Beispiel #1
0
def test_jumpouts_and_indirectcalls():
    expected_jumpouts = [("KPRCA_00034", 0x08050140, [0x0805014f])]
    exptected_unresolved_calls = [("KPRCA_00025", 0x8048ECC)]

    cfg_cache = {}
    for binary, function_addr, jmps in expected_jumpouts:
        if binary in cfg_cache:
            cfg = cfg_cache["binary"]
        else:
            filepath = os.path.join(bin_location, binary)
            backend = DetourBackend(filepath)
            cfg = backend.cfg
            cfg_cache["binary"] = cfg

        ff = cfg.functions[function_addr]
        nose.tools.assert_equal([a.addr for a in ff.jumpout_sites], jmps)

    for binary, function_addr in exptected_unresolved_calls:
        if binary in cfg_cache:
            cfg = cfg_cache["binary"]
        else:
            filepath = os.path.join(bin_location, binary)
            backend = DetourBackend(filepath)
            cfg = backend.cfg
            cfg_cache["binary"] = cfg

        ff = cfg.functions[function_addr]
        nose.tools.assert_true(ff.has_unresolved_calls)
Beispiel #2
0
def test_detect_syscall_wrapper():
    filepath = os.path.join(bin_location, "CROMU_00071")
    backend = DetourBackend(filepath)
    cfg = backend.cfg
    legitimate_syscall_wrappers = set([(0x804d483, 1), (0x804d491, 2),
                                       (0x804d4b1, 3), (0x804d4d1, 4),
                                       (0x804d4f7, 5), (0x804d511, 6),
                                       (0x804d525, 7)])

    syscall_wrappers = set([(ff.addr,cfg_utils.detect_syscall_wrapper(backend,ff)) \
            for ff in cfg.functions.values() if cfg_utils.detect_syscall_wrapper(backend,ff)!=None])
    print "syscall wrappers in CROMU_00071:"
    print map(lambda x: (hex(x[0]), x[1]), syscall_wrappers)
    nose.tools.assert_equal(syscall_wrappers, legitimate_syscall_wrappers)

    filepath = os.path.join(bin_location, "CROMU_00070")
    backend = DetourBackend(filepath)
    cfg = backend.cfg
    legitimate_syscall_wrappers = set([(0x804d690, 5), (0x804d66a, 4),
                                       (0x804d6be, 7), (0x804d6aa, 6),
                                       (0x804d61c, 1), (0x804d64a, 3),
                                       (0x804d62a, 2)])

    syscall_wrappers = set([(ff.addr,cfg_utils.detect_syscall_wrapper(backend,ff)) \
            for ff in cfg.functions.values() if cfg_utils.detect_syscall_wrapper(backend,ff)!=None])
    print "syscall wrappers in CROMU_00070:"
    print map(lambda x: (hex(x[0]), x[1]), syscall_wrappers)
    nose.tools.assert_equal(syscall_wrappers, legitimate_syscall_wrappers)
Beispiel #3
0
    def test_conflicting_symbols(self):
        filepath = os.path.join(self.bin_location, "printf_nopie")

        patches = []
        backend = DetourBackend(filepath)
        patches.append(AddRODataPatch(b"0123456789abcdef", "aaa"))
        patches.append(AddRODataPatch(b"\n", "aaa"))
        exc = False
        try:
            backend.apply_patches(patches)
        except ValueError:
            exc = True
        self.assertTrue(exc)

        patches = []
        backend = DetourBackend(filepath)
        patches.append(AddRODataPatch(b"0123456789abcdef", "aaa"))
        added_code = '''
            nop
        '''
        patches.append(AddCodePatch(added_code, "aaa"))
        exc = False
        try:
            backend.apply_patches(patches)
        except ValueError:
            exc = True
        self.assertTrue(exc)
Beispiel #4
0
def test_is_floatingpoint_function():
    filepath = os.path.join(bin_location, "CROMU_00071")
    backend = DetourBackend(filepath)
    cfg = backend.cfg
    floatingpoint_functions = [
        ff for ff in cfg.functions.values()
        if cfg_utils.is_floatingpoint_function(backend, ff)
    ]
    floatingpoint_functions = sorted(floatingpoint_functions,
                                     key=lambda f: f.addr)
    #print "floatingpoint_functions in CROMU_00071"
    #print "\n".join(map(lambda f:hex(f.addr),floatingpoint_functions))
    first = floatingpoint_functions[0].addr
    ff = floatingpoint_functions[-1]
    if ff.ret_sites == None:
        last = ff.addr
    else:
        if len(ff.ret_sites) == 0:
            last = ff.addr
        else:
            last = max([e.addr for e in ff.blocks])
    print hex(first), hex(last)
    real_start = 0x804d5c6
    real_end = 0x0804D78b
    nose.tools.assert_true(first == real_start)
    nose.tools.assert_true(last <= real_end)
    nose.tools.assert_true(last > real_end - 0x20)  #I allow some imprecision

    filepath = os.path.join(bin_location, "CROMU_00070")
    backend = DetourBackend(filepath)
    cfg = backend.cfg
    floatingpoint_functions = [
        ff for ff in cfg.functions.values()
        if cfg_utils.is_floatingpoint_function(backend, ff)
    ]
    floatingpoint_functions = sorted(floatingpoint_functions,
                                     key=lambda f: f.addr)
    #print "floatingpoint_functions in CROMU_00071"
    #print "\n".join(map(lambda f:hex(f.addr),floatingpoint_functions))
    first = floatingpoint_functions[0].addr
    ff = floatingpoint_functions[-1]
    if ff.ret_sites == None:
        last = ff.addr
    else:
        if len(ff.ret_sites) == 0:
            last = ff.addr
        else:
            last = max([e.addr for e in ff.blocks])
    print hex(first), hex(last)
    real_start = 0x0804D75f
    real_end = 0x0804D924
    nose.tools.assert_true(first == real_start)
    nose.tools.assert_true(last <= real_end)
    nose.tools.assert_true(last > real_end - 0x20)  #I allow some imprecision
Beispiel #5
0
    def run_test(self,
                 filename,
                 patches,
                 set_oep=None,
                 inputvalue=None,
                 expected_output=None,
                 expected_returnCode=None,
                 try_without_cfg=True):
        filepath = os.path.join(self.bin_location, filename)
        pipe = subprocess.PIPE

        with patcherex.utils.tempdir() as td:
            tmp_file = os.path.join(td, "patched")
            backend = DetourBackend(filepath, try_without_cfg=try_without_cfg)
            backend.apply_patches(patches)
            if set_oep:
                backend.set_oep(backend.name_map[set_oep])
            backend.save(tmp_file)
            p = subprocess.Popen([
                self.qemu_location, "-L", "/usr/mips64-linux-gnuabi64",
                tmp_file
            ],
                                 stdin=pipe,
                                 stdout=pipe,
                                 stderr=pipe)
            res = p.communicate(inputvalue)
            if expected_output:
                self.assertEqual(res[0], expected_output)
            if expected_returnCode:
                self.assertEqual(p.returncode, expected_returnCode)
            return backend
Beispiel #6
0
def test_fullcfg_properties():
    binaries = [ "KPRCA_00009","KPRCA_00025","NRFIN_00004","CROMU_00071", "CADET_00003",
                 # "CROMU_00070",
                 "EAGLE_00005",
                 # "KPRCA_00019"
                 ]

    # these are either "slides" into a call or jump to the beginning of a call
    # ("KPRCA_00025",0x804b041) is a very weird case, but Fish convinced me that it is correct
    legittimate_jumpouts = [("KPRCA_00025",0x80480bf),("KPRCA_00025",0x804b041),
            ("KPRCA_00025",0x804bd85),("KPRCA_00025",0x804c545),("KPRCA_00025",0x804c5b5), ("KPRCA_00025", 0x804c925),
            ("KPRCA_00019",0x8048326),
            ("KPRCA_00019",0x8048b41),("KPRCA_00019",0x804882e),("KPRCA_00019",0x8048cd1),
            ("KPRCA_00019",0x8048cca),("KPRCA_00019",0x8049408),
            ("KPRCA_00019", 0x8048846), ("KPRCA_00019", 0x804884b), ("KPRCA_00019", 0x804885f),
            ("KPRCA_00019", 0x804886f), ("KPRCA_00019", 0x8048877),
            ("CROMU_00071", 0x804d77d), ("CROMU_00071", 0x804d783),
                            ]

    for binary in binaries:
        print "testing",binary,"..."
        filepath = os.path.join(bin_location, binary)
        backend = DetourBackend(filepath)
        cfg = backend.cfg

        node_addrs_dict = defaultdict(set)
        for k,ff in cfg.functions.iteritems():
            for node_addr in ff.block_addrs_set:
                node_addrs_dict[node_addr].add(ff)
            # check that endpoints are the union of callouts, rets, and jumpouts
            endpoint_union = set(ff.callout_sites).union(set(ff.ret_sites).union(set(ff.jumpout_sites)))
            nose.tools.assert_equal(set(ff.endpoints),endpoint_union)

            # check that we do not encounter any unexpected jumpout
            if not ff.is_syscall and ff.returning and not ff.has_unresolved_calls and \
                    not ff.has_unresolved_jumps and ff.startpoint != None and ff.endpoints:
                if not cfg_utils.is_floatingpoint_function(backend,ff):
                    if len(ff.jumpout_sites) > 0:
                        unexpected_jumpout = [(binary,int(jo.addr)) for jo in ff.jumpout_sites \
                                if (binary,int(jo.addr)) not in legittimate_jumpouts]
                        if len(unexpected_jumpout)>0:
                            print "unexpected jumpouts in",binary,map(lambda x:hex(x[1]),unexpected_jumpout)
                        nose.tools.assert_equal(len(unexpected_jumpout),0)

        # check that every node only belongs to a single function
        for k,v in node_addrs_dict.iteritems():
            if len(v)>1:
                print "found node in multiple functions:",hex(k),repr(v)
            nose.tools.assert_equal(len(v),1)

        # check that every node only appears once in the cfg
        nn = set()
        instruction_set = set()
        for n in cfg.nodes():
            nose.tools.assert_true(n.addr not in nn)
            nn.add(n.addr)
            # check that every instruction appears only in one node
            for iaddr in n.instruction_addrs:
                nose.tools.assert_true(iaddr not in instruction_set)
                instruction_set.add(iaddr)
Beispiel #7
0
    def generate_medium_detour_binary(self, test_bin=True):
        try:
            nr = NetworkRules()
            backend = DetourBackend(self.infile)
            patches = []

            patches.extend(IndirectCFI(self.infile, backend).get_patches())
            patches.extend(
                TransmitProtection(self.infile, backend).get_patches())
            patches.extend(ShiftStack(self.infile, backend).get_patches())
            patches.extend(Adversarial(self.infile, backend).get_patches())
            patches.extend(Backdoor(self.infile, backend).get_patches())
            # patches.extend(NxStack(self.infile,backend).get_patches())
            patches.extend(
                MallocExtPatcher(self.infile, backend).get_patches())
            patches.extend(
                StackRetEncryption(self.infile, backend).get_patches())
            patches.extend(
                UninitializedPatcher(self.infile, backend).get_patches())
            patches.extend(
                NoFlagPrintfPatcher(self.infile, backend).get_patches())

            backend.apply_patches(patches)
            final_content = backend.get_final_content()
            if test_bin:
                test_bin_with_qemu(self.infile, final_content)
            res = (final_content, "")
        except PatcherexError, e:
            traceback.print_exc(e)
            res = (None, None)
Beispiel #8
0
    def run_test(self,
                 file,
                 patches,
                 set_oep=None,
                 inputs=None,
                 expected_output=None,
                 expected_returnCode=None):
        filepath = os.path.join(self.bin_location, file)
        pipe = subprocess.PIPE

        with patcherex.utils.tempdir() as td:
            tmp_file = os.path.join(td, "patched")
            backend = DetourBackend(filepath)
            backend.apply_patches(patches)
            if set_oep:
                backend.set_oep(backend.name_map[set_oep])
            backend.save(tmp_file)
            p = subprocess.Popen([tmp_file],
                                 stdin=pipe,
                                 stdout=pipe,
                                 stderr=pipe)
            res = p.communicate(inputs)
            if expected_output:
                self.assertEqual(res[0], expected_output)
            if expected_returnCode:
                self.assertEqual(p.returncode, expected_returnCode)
            return backend
Beispiel #9
0
def test_0b32aa01_01():
    print "Testing test_0b32aa01_01..."
    filepath = os.path.join(bin_location, "0b32aa01_01_2")
    backend = DetourBackend(filepath)
    cfg = backend.cfg

    legitimate_functions = set([
        0x80480a0, 0x8048230, 0x8048400, 0x80484f0, 0x80485fc, 0x8048607,
        0x8048615, 0x8048635, 0x80486c3, 0x80486a9L, 0x8048613L, 0x8048655L,
        0x804867bL, 0x80486deL, 0x8048695L
    ])

    non_syscall_functions = [
        v for k, v in cfg.functions.iteritems() if not v.is_syscall
    ]
    #check startpoints, I know that sometimes they could be None, but this should not happen in CADET_00003
    function_entrypoints = set(
        [f.startpoint.addr for f in non_syscall_functions])
    print "additional:", map(hex, function_entrypoints - legitimate_functions)
    print "skipped:", map(hex, legitimate_functions - function_entrypoints)
    nose.tools.assert_equal(function_entrypoints == legitimate_functions, True)

    sane_functions = [
        v for k, v in cfg.functions.iteritems() if is_sane_function(v)
    ]
    function_entrypoints = set([f.startpoint.addr for f in sane_functions])
    print "additional:", map(hex, function_entrypoints - legitimate_functions)
    print "skipped:", map(hex, legitimate_functions - function_entrypoints)
    nose.tools.assert_equal(function_entrypoints == legitimate_functions, True)

    #all sane functions ends with ret in CADET_00003
    for ff in sane_functions:
        node = cfg.get_any_node(ff.addr, is_syscall=False)
        nose.tools.assert_equal(node != None, True)
        nose.tools.assert_equal(len(node.instruction_addrs) > 0, True)
        node = cfg.get_any_node(ff.addr + 1, is_syscall=False, anyaddr=True)
        nose.tools.assert_equal(node != None, True)
        nose.tools.assert_equal(len(node.instruction_addrs) > 0, True)
        nose.tools.assert_equal(ff.startpoint != None, True)
        nose.tools.assert_equal(ff.ret_sites != None, True)
        if ff.addr == 0x080485FC or ff.addr == 0x8048607:
            nose.tools.assert_equal(ff.returning == False, True)
        if ff.returning:
            nose.tools.assert_equal(len(ff.ret_sites) > 0, True)
        for endpoint in ff.ret_sites:
            bb = backend.project.factory.block(endpoint.addr)
            last_instruction = bb.capstone.insns[-1]
            nose.tools.assert_equal(last_instruction.mnemonic == u"ret", True)

    syscalls = [v for k, v in cfg.functions.iteritems() if v.is_syscall]

    for ff in syscalls:
        bb1 = cfg.get_any_node(ff.addr)
        nose.tools.assert_equal(len(bb1.predecessors) >= 1, True)
        bb2 = bb1.predecessors[0]
        bb = backend.project.factory.block(bb2.addr)
        ii = bb.capstone.insns[-1]
        nose.tools.assert_equal(ii.mnemonic == u"int" and ii.op_str == u"0x80",
                                True)
Beispiel #10
0
 def generate_fidget_bitflip_binary(self):
     nr = NetworkRules()
     midfile = self.infile + '.fidget' + str(random.randrange(0, 1000))
     fidget_it(self.infile, midfile)
     backend = DetourBackend(midfile)
     cp = Bitflip(midfile, backend)
     patches1 = cp.get_patches()
     backend.apply_patches(patches1)
     return (backend.get_final_content(), nr.get_bitflip_rule())
Beispiel #11
0
 def execute(self, patches, binary, output_expected=None):
     with patcherex.utils.tempdir() as td:
         tmp_file = os.path.join(td, "patched")
         #backend operations
         backend = DetourBackend(self.binary_path + binary)
         backend.apply_patches(patches)
         backend.save(tmp_file)
         #run the patched binary
         pipe = subprocess.PIPE
         p = subprocess.Popen([tmp_file],
                              stdin=pipe,
                              stdout=pipe,
                              stderr=pipe)
         res = p.communicate()
         #check the results
         self.assertEqual(res[0], output_expected)
Beispiel #12
0
    def generate_medium_lief_detour_binary(self, test_bin=True):
        try:
            backend = DetourBackend(self.infile)
            patches = []

            patches.extend(
                StackRetEncryption(self.infile, backend).get_patches())

            backend.apply_patches(patches)
            final_content = backend.get_final_content()
            if test_bin:
                test_bin_with_qemu(self.infile, final_content)
            res = (final_content, "")
        except PatcherexError, e:
            traceback.print_exc(e)
            res = (None, None)
Beispiel #13
0
def test_setlongjmp_detection():
    solutions = [
            ("CADET_00003",0x80486c8,0x80486e3),
            ("CROMU_00008",0x804C3AC,0x804C3C7),
            ("Ofast/CROMU_00008",0x804ABD7,0x804ABF2),

    ]

    for tbin, setjmp, longjmp in solutions:
        filepath = os.path.join(bin_location, tbin)
        backend = DetourBackend(filepath)
        cfg = backend.cfg

        for k,ff in cfg.functions.items():
            msg = "detection failure in %s (%#x vs %#x)"
            if cfg_utils.is_setjmp(backend,ff):
                nose.tools.assert_equal(setjmp,ff.addr,"setjmp " + msg %(tbin,setjmp,ff.addr))
            elif cfg_utils.is_longjmp(backend,ff):
                nose.tools.assert_equal(longjmp,ff.addr,"longjmp " + msg %(tbin,setjmp,ff.addr))
Beispiel #14
0
def test_EAGLE_00005_bb():
    filepath = os.path.join(bin_location, "EAGLE_00005")
    backend = DetourBackend(filepath)
    cfg = backend.cfg
    # import IPython; IPython.embed()
    bbs = [(0x0804A73C,3),(0x0804BB3D,1),(0x0804A0E5,6),(0x0804A101,3),(0x0804B145,1),(0x0804BB42,2)]
    for addr,ni in bbs:
        n = cfg.model.get_any_node(addr)
        nose.tools.assert_true(n != None)
        nose.tools.assert_true(len(n.instruction_addrs) == ni)

    caller_map = [
        (0x8048D28,set([0x8048685,0x804877b])),
        (0x8048FEA,set([0x80483d2])),
    ]
    inv_callsites = map_callsites(cfg)
    for b,clist in caller_map:
        nose.tools.assert_true(is_last_returning_block(b,cfg,backend.project))
        node_addresses = set([n.addr for n in last_block_to_callers(b,cfg,inv_callsites)])
        print(hex(b), "<--", map(hex, node_addresses))
        nose.tools.assert_equal(clist,node_addresses)
Beispiel #15
0
parser = ArgumentParser()
parser.add_argument("original")
parser.add_argument("patched")
args = parser.parse_args()

try:
    os.unlink(args.patched)
except OSError:
    pass
try:
    os.unlink(args.patched + ".bin")
except OSError:
    pass

backend = DetourBackend(args.original, variant="stm32")
patches = []

typedef = '''
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
'''
transmit_code = '''
void rx_brake_routine( unsigned char buff[], void *bumper ){
	uint16_t speed_value;  
	uint8_t brake_switch;
	speed_value  = (buff[3] << 8) + buff[2];
	brake_switch = (buff[4] & 0b00001100) >> 2;
	((unsigned char*)bumper)[13] = (brake_switch) ? 1 : 0;

	if ( ((unsigned char*)bumper)[13] ) {
Beispiel #16
0
from argparse import ArgumentParser
from patcherex.backends.detourbackend import DetourBackend
from patcherex.patches import *

parser = ArgumentParser()
parser.add_argument("original")
parser.add_argument("patched")
args = parser.parse_args()

backend = DetourBackend(args.original)
patches = []

typedef = '''
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
'''
transmit_code = '''
void rx_brake_routine( uint8_t buff[], void *bumper ){
	uint16_t speed_value;  
	uint8_t brake_switch;

	speed_value  = (buff[3] << 8) + buff[2];
	brake_switch = (buff[4] & 0b00001100) >> 2;
	((uint8_t*)bumper)[5] = (brake_switch) ? 1 : 0;

	if ( ((uint8_t*)bumper)[5] ) {
		if ((speed_value > 0) && ( !((uint8_t*)bumper)[4]) ){ 
			((uint8_t*)bumper)[6] = 1;
		}
	}
	else {
Beispiel #17
0
from argparse import ArgumentParser
from patcherex.backends.detourbackend import DetourBackend
from patcherex.patches import *

parser = ArgumentParser()
parser.add_argument("original")
parser.add_argument("patched")
args = parser.parse_args()

backend = DetourBackend(args.original, replace_note_segment=True)
patches = []

# regenerate cfg with specified main function address
backend.cfg = backend.project.analyses.CFGFast(normalize=True, data_references=True, force_complete_scan=False, function_starts={0x11169, })
backend.ordered_nodes = backend._get_ordered_nodes(backend.cfg)

################################################################
#  - Patch encrypt(0x1254C) and decrypt(0x125B8)
#     12c12
#     < #include "EVP_des_ede3_cbc.h"
#     ---
#     > #include "EVP_aes_256_cbc.h"
################################################################

EVP_aes_256_cbc_addr = hex(0x47f90)

# 0x12564: "bl EVP_des_ede3_cbc" in encrypt()
patches.append(InlinePatch(0x12564, "bl " + EVP_aes_256_cbc_addr))
# 0x125D0: "bl EVP_des_ede3_cbc" in decrypt()
patches.append(InlinePatch(0x125D0, "bl " + EVP_aes_256_cbc_addr))
Beispiel #18
0
def test_CADET_00003():
    print "Testing test_CADET_00003..."
    filepath = os.path.join(bin_location, "CADET_00003")
    backend = DetourBackend(filepath)
    cfg = backend.cfg

    #how to get the list of functions from the IDA list:
    #print "["+",\n".join(map(hex,hex,[int(l.split()[2],16) for l in a.split("\n") if l.strip()]))+"]"
    legitimate_functions = set([
        0x80480a0, 0x8048230, 0x8048400, 0x80484f0, 0x80485fc, 0x804860c,
        0x804861a, 0x804863a, 0x8048705, 0x8048735, 0x8048680L, 0x80486e3L,
        0x80486c8L, 0x80486aeL, 0x8048618L, 0x804865aL, 0x804869aL
    ])

    non_syscall_functions = [
        v for k, v in cfg.functions.iteritems() if not v.is_syscall
    ]
    #check startpoints, I know that sometimes they could be None, but this should not happen in CADET_00003
    function_entrypoints = set(
        [f.startpoint.addr for f in non_syscall_functions])
    print "additional:", map(hex, function_entrypoints - legitimate_functions)
    print "skipped:", map(hex, legitimate_functions - function_entrypoints)
    nose.tools.assert_equal(function_entrypoints == legitimate_functions, True)

    sane_functions = [
        v for k, v in cfg.functions.iteritems() if is_sane_function(v)
    ]
    function_entrypoints = set([f.startpoint.addr for f in sane_functions])
    print "additional:", map(hex, function_entrypoints - legitimate_functions)
    print "skipped:", map(hex, legitimate_functions - function_entrypoints)
    nose.tools.assert_equal(function_entrypoints == legitimate_functions, True)

    #something which was wrong in the past
    n = cfg.get_any_node(0x80485EC)
    nose.tools.assert_true(len(n.instruction_addrs) == 1)
    nose.tools.assert_true(n.instruction_addrs[0] == 0x80485EC)

    #all sane functions ends with ret in CADET_00003
    for ff in sane_functions:
        node = cfg.get_any_node(ff.addr, is_syscall=False)
        nose.tools.assert_equal(node != None, True)
        nose.tools.assert_equal(len(node.instruction_addrs) > 0, True)
        node = cfg.get_any_node(ff.addr + 1, is_syscall=False, anyaddr=True)
        nose.tools.assert_equal(node != None, True)
        nose.tools.assert_equal(len(node.instruction_addrs) > 0, True)
        nose.tools.assert_equal(ff.startpoint != None, True)
        nose.tools.assert_equal(ff.ret_sites != None, True)
        if ff.addr == 0x080485FC or ff.addr == 0x804860C:
            nose.tools.assert_equal(ff.returning == False, True)
        if ff.returning:
            nose.tools.assert_equal(len(ff.ret_sites) > 0, True)
        for endpoint in ff.ret_sites:
            bb = backend.project.factory.block(endpoint.addr)
            last_instruction = bb.capstone.insns[-1]
            nose.tools.assert_equal(last_instruction.mnemonic == u"ret", True)

    syscalls = [v for k, v in cfg.functions.iteritems() if v.is_syscall]

    for ff in syscalls:
        bb1 = cfg.get_any_node(ff.addr)
        nose.tools.assert_equal(len(bb1.predecessors) >= 1, True)
        bb2 = bb1.predecessors[0]
        bb = backend.project.factory.block(bb2.addr)
        ii = bb.capstone.insns[-1]
        nose.tools.assert_equal(ii.mnemonic == u"int" and ii.op_str == u"0x80",
                                True)

    endpoint_set = set(
        map(lambda x: (x.addr, x.size), cfg.functions[0x08048230].endpoints))
    nose.tools.assert_equal(set([(0x080483F4, 12), (0x080483D5, 20)]),
                            endpoint_set)
    ret_set = set(
        map(lambda x: (x.addr, x.size), cfg.functions[0x08048230].ret_sites))
    nose.tools.assert_equal(set([(0x080483F4, 12)]), ret_set)

    # the following is a case of a bb that should be split by normalization
    # because the bb is split by a "subsequent" jump
    bb = cfg.get_any_node(0x804824F)
    nose.tools.assert_equal(bb != None, True)
    nose.tools.assert_equal(bb.size == 13, True)
    bb = cfg.get_any_node(0x08048230)
    nose.tools.assert_equal(bb != None, True)
    nose.tools.assert_equal(bb.size == 31, True)
Beispiel #19
0
# parse command line arguments
parser = ArgumentParser()
parser.add_argument("original")
parser.add_argument("patched")
parser.add_argument("patchinfo", nargs="?")
args = parser.parse_args()

# setup logging options
logging.getLogger("angr").propagate = False
logging.getLogger("cle").propagate = False
logging.getLogger("pyvex").propagate = False
logging.getLogger("patcherex").setLevel(logging.DEBUG)

# initialize backend
backend = DetourBackend(args.original,
                        replace_note_segment=True,
                        try_reuse_unused_space=True)
patches = []

# replace the original hash function (using CRC-32) with a modified version of it (using SHA-256)
digest_message = '''
#include <stdlib.h>
typedef void EVP_MD_CTX;
void digest_message(const unsigned char *message, size_t message_len, unsigned char **digest, unsigned int *digest_len)
{
	EVP_MD_CTX *mdctx;

	if((mdctx = EVP_MD_CTX_new()) == NULL)
		handleErrors();

	if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL))