def test_complex1(self): patches = [] added_code = ''' mov x8, 0x40 mov x0, 0x1 ldr x1, =0x400648 mov x2, 2 svc 0 bl {added_function} mov x8, 0x5d mov x0, 0x34 svc 0 ''' patches.append(AddEntryPointPatch(added_code)) test_str = b"testtesttest\n\x00" added_code = ''' mov x8, 0x40 mov x0, 0x1 ldr x1, ={added_data} mov x2, %d svc 0 ret ''' % (len(test_str)) patches.append(AddCodePatch(added_code, "added_function")) patches.append(AddRODataPatch(test_str, "added_data")) self.run_test("printf_nopie", patches, expected_output=b'%s' + test_str, expected_returnCode=0x34)
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)
def test_complex1(self): patches = [] added_code = ''' mov eax, 4 mov ebx, 1 mov ecx, 0x080484f3 mov edx, 2 int 0x80 call {added_function} ''' patches.append(AddEntryPointPatch(added_code)) added_code = ''' mov eax, 1 mov ebx, 0x34 int 0x80 ''' patches.append(AddEntryPointPatch(added_code)) test_str = b"testtesttest\n\x00" added_code = ''' mov eax, 4 mov ebx, 1 mov ecx, {added_data} mov edx, %d int 0x80 ret ''' % (len(test_str)) patches.append(AddCodePatch(added_code, "added_function")) patches.append(AddRODataPatch(test_str, "added_data")) self.run_test("printf_nopie", patches, expected_output=b'%s' + test_str, expected_returnCode=0x34)
def test_complex1(self): patches = [] added_code = ''' dli $v0, 5001 dli $a0, 1 dla $a1, 0x120000cf8 dli $a2, 2 syscall jal {added_function} dli $v0, 5058 dli $a0, 0x34 syscall ''' patches.append(AddEntryPointPatch(added_code)) test_str = b"testtesttest\n\x00" added_code = ''' dli $v0, 5001 dli $a0, 1 dla $a1, {added_data} dli $a2, %d syscall jr $ra ''' % (len(test_str)) patches.append(AddCodePatch(added_code, "added_function")) patches.append(AddRODataPatch(test_str, "added_data")) self.run_test("printf_nopie", patches, expected_output=b'%s' + test_str, expected_returnCode=0x34)
def test_complex1(self): patches = [] added_code = ''' mov r7, 0x4 mov r0, 0x1 ldr r1, =0x10450 mov r2, 2 svc 0 bl {added_function} mov r7, 0x1 mov r0, 0x34 svc 0 ''' patches.append(AddEntryPointPatch(added_code)) test_str = b"testtesttest\n\x00" added_code = ''' mov r7, 0x4 mov r0, 0x1 ldr r1, ={added_data} mov r2, %d svc 0 bx lr ''' % (len(test_str)) patches.append( AddCodePatch(added_code, "added_function", is_thumb=True)) patches.append(AddRODataPatch(test_str, "added_data")) self.run_test("printf_nopie", patches, expected_output=b'%s' + test_str, expected_returnCode=0x34)
def test_complex1(self): patches = [] added_code = ''' li r0, 4 li r3, 1 lis r4, 0x10000758@h ori r4, r4, 0x10000758@l li r5, 2 sc bl {added_function} li r0, 1 li r3, 0x34 sc ''' patches.append(AddEntryPointPatch(added_code)) test_str = b"testtesttest\n\x00" added_code = ''' li r0, 4 li r3, 1 lis r4, {added_data}@h ori r4, r4, {added_data}@l li r5, %d sc blr ''' % (len(test_str)) patches.append(AddCodePatch(added_code, "added_function")) patches.append(AddRODataPatch(test_str, "added_data")) self.run_test("printf_nopie", patches, expected_output=b'%s' + test_str, expected_returnCode=0x34)
def test_add_code_patch(self): added_code = ''' li $v0, 4001 li $a0, 50 syscall ''' self.run_test("printf_nopie", [AddCodePatch(added_code, "added_code")], set_oep="added_code", expected_returnCode=0x32)
def test_add_code_patch(self): added_code = ''' mov x8, 0x5d mov x0, 0x32 svc 0 ''' self.run_test("printf_nopie", [AddCodePatch(added_code, "added_code")], set_oep="added_code", expected_returnCode=0x32)
def test_add_code_patch(self): added_code = ''' mov eax, 1 ;sys_exit mov ebx, 0x32 ;return code int 0x80 ''' self.run_test("printf_nopie", [AddCodePatch(added_code, "added_code")], set_oep="added_code", expected_returnCode=0x32)
def _get_logic(self, patch): """ Adds logic to check and update the countdown """ reg_a = "rax" if self.arch_bits == 64 else "eax" reg_b = "rbx" if self.arch_bits == 64 else "ebx" reg_sp = "rsp" if self.arch_bits == 64 else "esp" if self.patcher.project.loader.main_object.pic: l.debug( "Using `call {pie_thunk}`. This will clobber {rax, [rsp]} in order to return a pointer to the base of the binary" ) get_counter = ''' call {pie_thunk} add %s, {%s} ''' % (reg_a, self.count_var_name) else: get_counter = ''' mov %s, {%s} ''' % (reg_a, self.count_var_name) code = ''' ; update countdown push %s push %s push %s ; get address of count_var %s mov %s, [%s] ; check if we reached zero test ebx, ebx jle _zero_case ; decrement sub ebx, 1 mov [%s], %s ; call extra logic and jump to dst_active pop %s pop %s pop %s call {%s} jmp {%s} _zero_case: ; call extra logic and jump to dst_zero pop %s pop %s pop %s call {%s} jmp {%s} ''' % (reg_a, reg_b, reg_sp, get_counter, reg_b, reg_a, reg_a, reg_b, reg_sp, reg_b, reg_a, patch["extra_code_name"], patch["dst_active_name"], reg_sp, reg_b, reg_a, patch["extra_code_name"], patch["dst_zero_name"]) p1 = AddCodePatch(code, name=patch["countdown_logic_name"], compiler_flags=self.compiler_flags) return [p1]
def test_add_code_patch(self): added_code = ''' li r0, 1 li r3, 50 sc ''' self.run_test("printf_nopie", [AddCodePatch(added_code, "added_code")], set_oep="added_code", expected_returnCode=0x32)
def _get_extra_code(self, patch): if not patch["extra_is_c"]: # We called this code so the stack is shifted by 8. patch["extra_code"] = """ add rsp, 8 %s sub rsp, 8 ret """ % (patch['extra_code']) p1 = AddCodePatch(patch["extra_code"], name=patch["extra_code_name"], is_c=patch["extra_is_c"], compiler_flags=self.compiler_flags) return [p1]
def test_sample_pie(self): patches = [] transmit_code = ''' pop rsi pop rax push rsi sub rsi, rax sub rsi, 0xa add rsi, {transmitted_string} mov rax, 1 mov rdi, 1 syscall mov rbx, (rsp) add rsp, 8 pop r9 pop r8 pop r10 pop rdx pop rsi pop rdi pop rax mov (rsp), rbx ret ''' injected_code = ''' push rax push rdi push rsi push rdx push r10 push r8 push r9 mov rdx, 10 push $ call {transmit_function} ''' patches.append(AddCodePatch(transmit_code, name="transmit_function")) patches.append( AddRODataPatch(b"---HI---\x00", name="transmitted_string")) patches.append( InsertCodePatch(0x400665, injected_code, name="injected_code_after_receive")) self.run_test("sample_x86-64_pie", patches, expected_output=b'---HI---\x00\x00Purdue')
def _get_special_zero_targets(self): """ Adds code for special zero targets """ if self.has_ZERO_TARGET_EXIT: reg_a = "rax" if self.arch_bits == 64 else "eax" param_0 = "rdi" if self.arch_bits == 64 else "ebx" exit_num = 60 if self.arch_bits == 64 else 1 syscall = "syscall" if self.arch_bits == 64 else "int 0x80" code = """ xor %s, %s mov %s, %d %s """ % (param_0, param_0, reg_a, exit_num, syscall) p1 = AddCodePatch(code, name=self.ZERO_TARGET_EXIT_name, compiler_flags=self.compiler_flags) return [p1] return []
def test_c_compilation(self): added_code = ''' mov ecx, 0x4 %s mov ebx, 1 lea ecx, [0x080484f4] mov edx, 1 int 0x80 ''' % patcherex.utils.get_nasm_c_wrapper_code("c_function", get_return=True) self.run_test("printf_nopie", [ InsertCodePatch(0x8048457, added_code, name="p1", priority=1), AddCodePatch( "__attribute__((fastcall)) int func(int a){ return a; }", "c_function", is_c=True) ], expected_output=b"sHi", expected_returnCode=0x0)
def test_c_compilation(self): added_code = ''' dli $a0, 0 %s move $a0, $v0 dli $v0, 5001 dla $a1, 0x120000cf9 dli $a2, 1 syscall ''' % DetourBackendMips.get_c_function_wrapper_code("c_function") self.run_test("printf_nopie", [ InsertCodePatch(0x120000b20, added_code, name="p1", priority=1), AddCodePatch( "__attribute__((fastcall)) int func(int a){ return a + 1; }", "c_function", is_c=True, compiler_flags="") ], expected_output=b"sHi", expected_returnCode=0x0)
def test_c_compilation(self): added_code = ''' li r3, 0 %s li r0, 4 lis r4, 0x10000759@h ori r4, r4, 0x10000759@l li r5, 1 sc ''' % DetourBackendPpc.get_c_function_wrapper_code("c_function") self.run_test("printf_nopie", [ InsertCodePatch(0x100004f8, added_code, name="p1", priority=1), AddCodePatch( "__attribute__((fastcall)) int func(int a){ return a + 1; }", "c_function", is_c=True, compiler_flags="") ], expected_output=b"sHi", expected_returnCode=0x0)
def test_c_compilation(self): added_code = ''' mov r7, 0x4 mov r0, 0x0 %s ldr r1, =0x10451 mov r2, 1 svc 0 ''' % DetourBackendArm.get_c_function_wrapper_code("c_function") self.run_test("printf_nopie", [ InsertCodePatch(0x103ec, added_code, name="p1", priority=1), AddCodePatch( "__attribute__((fastcall)) int func(int a){ return a + 1; }", "c_function", is_c=True, compiler_flags="", is_thumb=True) ], expected_output=b"sHi", expected_returnCode=0x0)
def test_sample_no_pie(self): patches = [] transmit_code = ''' mov rax, 1 mov rdi, 1 syscall mov rbx, (rsp) add rsp, 8 pop r9 pop r8 pop r10 pop rdx pop rsi pop rdi pop rax mov (rsp), rbx ret ''' patches.append(AddCodePatch(transmit_code, name="transmit_function")) patches.append( AddRODataPatch(b"---HI---\x00", name="transmitted_string")) injected_code = ''' push rax push rdi push rsi push rdx push r10 push r8 push r9 mov rsi, {transmitted_string} mov rdx, 10 call {transmit_function} ''' patches.append( InsertCodePatch(0x400502, injected_code, name="injected_code_after_receive")) self.execute(patches, "sample_x86-64_no_pie", b'---HI---\x00\x00Purdue')
def test_c_compilation(self): added_code = ''' mov x8, 0x40 mov x0, 0x0 %s ldr x1, =0x400649 mov x2, 1 svc 0 ''' % DetourBackendAarch64.get_c_function_wrapper_code("c_function") self.run_test("printf_nopie", [InsertCodePatch(0x400580, added_code, name="p1", priority=1), AddCodePatch("__attribute__((fastcall)) int func(int a){ return a + 1; }", "c_function", is_c=True, compiler_flags="")], expected_output=b"sHi", expected_returnCode=0x0)