what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Backward Disassembler For ROP Exploitation

Backward Disassembler For ROP Exploitation
Posted Sep 29, 2010
Authored by Adrian Furtuna

bdasm is a PyCommand written for Immunity Debugger version 1.73. It searches the address space of a process for a certain opcode/instruction and dissasembles backwards and forwards for a specified number of instructions.

tags | tool
systems | unix
SHA-256 | fe58521b41a518098ea9ad9c6287a48a3d89eba28efa2473fd7c45ffe68eb19c

Backward Disassembler For ROP Exploitation

Change Mirror Download
#!/usr/bin/env python
"""
(c) Adrian Furtuna
seastorm44@yahoo.com
"""

__VERSION__ = '0.1'
import immlib
from immutils import *
import getopt

# Globals
imm = immlib.Debugger()
maxBack = 5
maxFw = 5
moduleFilter = ""
filterRet = 0
filterExec = 0

def banner():
imm.Log("", address = 0)
imm.Log("", address = 0)
imm.Log("========================================", address = 0)
imm.Log("= BDASM - a backward disassembler =", address = 0)
imm.Log("= by Adrian Furtuna =", address = 0)
imm.Log("= http://stormsecurity.wordpress.com =", address = 0)
imm.Log("========================================", address = 0)
imm.Log("", address = 0)
imm.updateLog()


def usage():
banner()
imm.Log("Usage:", address = 0)
imm.Log("", address = 0)
imm.Log("!bdasm <operation> [<options>]", address = 0)
imm.Log(" Operations:", address = 0)
imm.Log(" -a <address> Disassemble around <address>", address = 0)
imm.Log(" -i <instruction> Find all occurences of <instruction> and disassemble around", address = 0)
imm.Log(" -o <opcode> Find all occurences of <opcode> and disassemble around", address = 0)
imm.Log(" Options:", address = 0)
imm.Log(" -b <num> Disassemble maximum <num> instructions backward (default = 5)", address = 0)
imm.Log(" -f <num> Disassemble maximum <num> instructions forward (default = 5)", address = 0)
imm.Log(" -m <module> Show results only from <module>", address = 0)
imm.Log(" -r Show results only if forward instructions contain RET", address = 0)
imm.Log(" -e Show results only if memory page is executable", address = 0)
imm.Log("", address = 0)

def printInstruction(opcode, emph):
if emph == 0:
spaceBack = " " * 18
else:
spaceBack = " " * 14
spaceBack = spaceBack + "*** "
spaceFw = " " * (40 - len(opcode.getDisasm()))
logString = spaceBack + "%s" + spaceFw + "%s"
imm.Log(logString % (opcode.getDisasm(), opcode.getDump()), address = opcode.getAddress())


def disasmAtAddress(address):
try:
page = imm.getMemoryPagebyAddress( address )
access = page.getAccess( human = True )
if filterExec == 1 and not "EXEC" in access:
#imm.Log("Memory page at address %08x is not executable. Skip" % address, address = 0)
return
except:
imm.Log("Exception at getting access rights for address %08x" % address, address=0)
return

module = imm.findModule(address)
if module:
module = module[0].lower()
else:
module = "None"

# Filter result by module name
if len(moduleFilter) > 0 and module.find(moduleFilter) < 0:
return

nextAddress = address + imm.Disasm(address).getOpSize()

# Searching for opcodes forward
opcFw = []
good = 0
opcFw.append(imm.Disasm(address))
for i in range(0,maxFw):
disasm = imm.Disasm(nextAddress)
nextAddress = nextAddress + disasm.getOpSize()
opcFw.append(disasm)
if disasm.isRet():
good = 1

if filterRet == 1 and good == 0:
#imm.Log("Instructions forward do not contain RET. Skip", address = 0)
return
else:
disasm = imm.Disasm(address)
disasmStr = disasm.getDisasm()
imm.Log("Found instruction %s [opcode: %s] at address %08x %s %s" %
(disasmStr, disasm.getDump(), address, access, module), address = address)
imm.Log("", address=0)

#Searching for opcodes before
opcBack = []
disasmBack(address, 0, maxBack, opcBack, opcFw)
imm.Log("", address=0)


def findOpcode(opcode):
results = imm.Search(opcode)
for address in results:
disasmAtAddress(address)

def findInstruction(instr):
opcode = imm.Assemble(instr)
if len(opcode) == 0:
imm.Log("Cannot assemble instruction %s" % instr)
return
findOpcode(opcode)


def printList(list, size, list2):
revList = list[0:size]
revList.reverse()
for i in range(0, size):
disasm = revList[i]
printInstruction(disasm, 0)

if len(list2) > 0:
disasm = list2[0]
printInstruction(disasm, 1)
for i in range(1,len(list2)):
disasm = list2[i]
printInstruction(disasm, 0)

def disasmBack(address, instrCrt, instrPrev, list, list2):
#imm.Log("Dissassembling at %08x instrCrt=%i" % (address, instrCrt), address = address)
if instrCrt >= instrPrev:
#imm.Log("Max instr reached", address=0)
printList(list, instrCrt, list2)
imm.Log("", address = 0)
return
found = 0
for numBytes in range (1,10):
searchAddress = address - numBytes
disasm = imm.Disasm(searchAddress)
#imm.Log("try: %s %s [%i -- %i] instrCrt=%i" %
# (disasm.getDisasm(), disasm.getDump(), disasm.getOpSize(), numBytes, instrCrt), address = searchAddress)
if disasm.getOpSize() == numBytes:
#imm.Log("ok: %s %s" % (disasm.getDisasm(), disasm.getDump()), address = searchAddress)
found = 1
list.insert(instrCrt, disasm)
#imm.Log("inserting at pos %i" % instrCrt)
disasmBack(searchAddress, instrCrt+1, instrPrev, list, list2)

if found == 0: # No instruction found backward and instrCrt < instrPrev
#imm.Log("No more instr backw", address = 0)
printList(list, instrCrt, list2)
imm.Log("", address = 0)

def hexToByte(hexStr):
bytes = []
for i in range(0, len(hexStr), 2):
bytes.append(chr(int(hexStr[i:i+2], 16)))
return ''.join( bytes )



# #########################################################
# MAIN
# #########################################################
def main(args):
global maxBack
global maxFw
global moduleFilter
global filterRet
global filterExec

if len(args) == 0:
usage()
return "Please see usage instructions"

banner()

try:
opts, xxx = getopt.getopt(args, "a:i:o:b:f:m:er")
except getopt.GetoptError:
return "Wrong arguments (Check usage on the Log window)"

# Check first the optional arguments
for opt, val in opts:
if opt == '-b':
try:
maxBack = int( val )
except ValueError:
usage()
return "Wrong argument (%s) % " % val
elif opt == '-f':
try:
maxFw = int( val )
except ValueError:
usage()
return "Wrong argument (%s) % " % val
elif opt == '-m':
imm.Log(" Filter MODULE on", address = 0)
moduleFilter = val.lower()
elif opt == '-r':
imm.Log(" Filter RET on", address = 0)
filterRet = 1
elif opt == '-e':
imm.Log(" Filter EXEC on", address = 0)
filterExec = 1
imm.Log("", address = 0)

# Iterate through input arguments and do the desired operation
for opt, val in opts:
if opt == '-a':
try:
address = int( val, 16 )
except ValueError:
usage()
return "Wrong address (%s) " % val

imm.Log("Disassembling at address %08x ..." % address, address = address)
disasmAtAddress(address)
break

elif opt == '-i':
instr = val.replace('_', ' ')
imm.Log("Searching for instruction: %s ..." % instr, address = 0)
findInstruction(instr)
break

elif opt == '-o':
if len(val) < 2 or len(val) % 2 != 0:
usage()
return "Wrong opcode (%s)" % val
opcode = hexToByte(val)
imm.Log("Searching for opcode: %s ..." % val, address = 0)
findOpcode(hexToByte(val))
break

imm.Log("Finished", address = 0)
return "See results in Log window"

#findOpcode("\x81\xc4", 5, 5) #add esp, xxxx
#findOpcode("\x81\xd4", 5, 5) #adc esp, xxxx
#findOpcode("\x83\xc4", 10, 10) #add esp, xx
#findOpcode("\x83\xd4", 10, 10) #adc esp, xx
#findOpcode("\x81\xc5", 5, 5) #add ebp, xxxx
#findOpcode("\x83\xc5", 5, 5) #add ebp, xx
#opcode1 = "\x8b\xe0"; #mov esp,eax
#findInstruction("add esp, dword ptr[ebp]", 5, 5)
#findInstruction("mov esp,eax", 5, 5)
#findInstruction("mov esp,ebx", 5, 5)
#findInstruction("mov esp,ecx")
#findInstruction("mov esp,edx")
#findInstruction("pop esp", 5, 5)
#findInstruction("popa", 5, 5)
#findInstruction("xchg eax,esp", 5, 5)
#findInstruction("xchg ecx,esp", 5, 5)
#printAssembled("call dword [esp + 400]");
#findOpcode("\xff\x94\x24") #7c90122d ff942400050000 call dword ptr [esp+500h]
#findOpcode("\xff\x95") #7c90123a ff9500050000 call dword ptr [ebp+500h]
#findOpcode("\x05\x00", 1, 10) #7c901240 0500030000 add eax,300h
#printAssembled("mov esp,eax")

Login or Register to add favorites

File Archive:

March 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    16 Files
  • 2
    Mar 2nd
    0 Files
  • 3
    Mar 3rd
    0 Files
  • 4
    Mar 4th
    32 Files
  • 5
    Mar 5th
    28 Files
  • 6
    Mar 6th
    42 Files
  • 7
    Mar 7th
    17 Files
  • 8
    Mar 8th
    13 Files
  • 9
    Mar 9th
    0 Files
  • 10
    Mar 10th
    0 Files
  • 11
    Mar 11th
    15 Files
  • 12
    Mar 12th
    19 Files
  • 13
    Mar 13th
    21 Files
  • 14
    Mar 14th
    38 Files
  • 15
    Mar 15th
    15 Files
  • 16
    Mar 16th
    0 Files
  • 17
    Mar 17th
    0 Files
  • 18
    Mar 18th
    10 Files
  • 19
    Mar 19th
    32 Files
  • 20
    Mar 20th
    46 Files
  • 21
    Mar 21st
    16 Files
  • 22
    Mar 22nd
    13 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    12 Files
  • 26
    Mar 26th
    31 Files
  • 27
    Mar 27th
    19 Files
  • 28
    Mar 28th
    42 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close