lunixbochs / patchkit

binary patching from Python
Other
631 stars 85 forks source link

The patched binary differs when switching to another computer #30

Closed Ver0n1ca closed 5 years ago

Ver0n1ca commented 5 years ago

Hi, I used exactly same version of patchkit, same patchfiles and same binary on two Ubuntu 16.04 computers. The output of patching is the same and without any errors but the patched binary is different. One works well but the other has segmentation fault. I found that the jump address of the patch position is different:

//No.1
.text:0000000000400629                 jmp     near ptr 80104Bh
//No.2
.text:0000000000400629                 jmp     near ptr 8392779h

And I found that hex(8392779)=0x80104B

The output of ./patch:

[*] 0x400629.py
 [+] patch()
  [INJECT] @0x801483-0x8014a0
  [INJECT] @0x8014a0-0x8014c7
  [INJECT] @0x8014df-0x801506
  [INJECT] @0x801506-0x801528
  [PATCH] @0x8014c7-0x8014d3 | "hook stage 1"
  [PATCH] @0x8014d3-0x8014df | "hook stage 2"
  [PATCH] @0x400629-0x400635 | "hook entry point"

I don't know what's happening, please give me I clue :(

lunixbochs commented 5 years ago

Add -v flag to patch

Ver0n1ca commented 5 years ago

Hi, this is the output of adding -v on my 'segmentation fault' computer:

$ ./patch -v simple test_patch.py
[*] test_patch.py
 [+] patch()
  [INJECT] @0x801000-0x80100c
  68656c6c6f20776f726c640a
  [INJECT] @0x80100c-0x801033
  0x80100c: 50             push rax
  0x80100d: 57             push rdi
  0x80100e: 56             push rsi
  0x80100f: 52             push rdx
  0x801010: 48c7c001000000 mov rax, 1
  0x801017: 48c7c701000000 mov rdi, 1
  0x80101e: 48c7c600108000 mov rsi, 0x801000
  0x801025: 48c7c20c000000 mov rdx, 0xc
  0x80102c: 0f05           syscall 
  0x80102e: 5a             pop rdx
  0x80102f: 5e             pop rsi
  0x801030: 5f             pop rdi
  0x801031: 58             pop rax
  0x801032: c3             ret 
  [HOOK] @0x400629 -> 0x80100c
  [!] Segment made writable: 0x400000-0x40082c
  [INJECT] @0x80104b-0x801072
  0x80104b: e8c616b907     call 0x8392716
  0x801050: 57             push rdi
  0x801051: 56             push rsi
  0x801052: 51             push rcx
  0x801053: 488d3d5997e6fb lea rdi, [rip - 0x41968a7]
  0x80105a: 488d35d8ffffff lea rsi, [rip - 0x28]
  0x801061: 48c7c112000000 mov rcx, 0x12
  0x801068: f3a4           rep movsb byte ptr [rdi], byte ptr [rsi]
  0x80106a: 59             pop rcx
  0x80106b: 5e             pop rsi
  0x80106c: 5f             pop rdi
  0x80106d: e90f489903     jmp 0x4195881
  [INJECT] @0x801072-0x801094
  0x801072: 57             push rdi
  0x801073: 56             push rsi
  0x801074: 51             push rcx
  0x801075: 488d3dbf96e6fb lea rdi, [rip - 0x4196941]
  0x80107c: 488d358cffffff lea rsi, [rip - 0x74]
  0x801083: 48c7c112000000 mov rcx, 0x12
  0x80108a: f3a4           rep movsb byte ptr [rdi], byte ptr [rsi]
  0x80108c: 59             pop rcx
  0x80108d: 5e             pop rsi
  0x80108e: 5f             pop rdi
  0x80108f: e9f4479903     jmp 0x4195888
  [PATCH] @0x801033-0x80103f | "hook stage 1"
  - 000000000000000000000000
  + 0x801033: e94b21f907 jmp 0x8793183
  + 0x801038: 9090       nop (x2)
  + 0x80103a: b800000000 mov eax, 0
  [PATCH] @0x80103f-0x80104b | "hook stage 2"
  - 000000000000000000000000
  + 0x80103f: 7e11       jle 0x801052
  + 0x801041: bff7064000 mov edi, 0x4006f7
  + 0x801046: e9e321f907 jmp 0x879322e
  [PATCH] @0x400629-0x400635 | "hook entry point"
  - 0x400629: 7e11       jle 0x40063c
  - 0x40062b: bff7064000 mov edi, 0x4006f7
  - 0x400630: b800000000 mov eax, 0
  + 0x400629: e94b21f907 jmp 0x8392779
  + 0x40062e: 9090       nop (x2)
  + 0x400630: b800000000 mov eax, 0

[+] Saving binary to: /home/ver0n1ca/Desktop/patchkit/simple.patched

I'm still not sure about how to fix this... Thanks.

lunixbochs commented 5 years ago

What’s the output on the computer that works?

Ver0n1ca commented 5 years ago

The output on the computer that works:

$ ./patch -v test/simple test_patch.py
[*] test_patch.py
 [+] patch()
  [INJECT] @0x801000-0x80100c
  68656c6c6f20776f726c640a
  [INJECT] @0x80100c-0x801033
  0x80100c: 50             push rax
  0x80100d: 57             push rdi
  0x80100e: 56             push rsi
  0x80100f: 52             push rdx
  0x801010: 48c7c001000000 mov rax, 1
  0x801017: 48c7c701000000 mov rdi, 1
  0x80101e: 48c7c600108000 mov rsi, 0x801000
  0x801025: 48c7c20c000000 mov rdx, 0xc
  0x80102c: 0f05           syscall 
  0x80102e: 5a             pop rdx
  0x80102f: 5e             pop rsi
  0x801030: 5f             pop rdi
  0x801031: 58             pop rax
  0x801032: c3             ret 
  [HOOK] @0x400629 -> 0x80100c
  [!] Segment made writable: 0x400000-0x40082c
  [INJECT] @0x80104b-0x801072
  0x80104b: e8bcffffff     call 0x80100c
  0x801050: 57             push rdi
  0x801051: 56             push rsi
  0x801052: 51             push rcx
  0x801053: 488d3dcff5bfff lea rdi, [rip - 0x400a31]
  0x80105a: 488d35deffffff lea rsi, [rip - 0x22]
  0x801061: 48c7c10c000000 mov rcx, 0xc
  0x801068: f3a4           rep movsb byte ptr [rdi], byte ptr [rsi]
  0x80106a: 59             pop rcx
  0x80106b: 5e             pop rsi
  0x80106c: 5f             pop rdi
  0x80106d: e9b7f5bfff     jmp 0x400629
  [INJECT] @0x801072-0x801094
  0x801072: 57             push rdi
  0x801073: 56             push rsi
  0x801074: 51             push rcx
  0x801075: 488d3dadf5bfff lea rdi, [rip - 0x400a53]
  0x80107c: 488d35b0ffffff lea rsi, [rip - 0x50]
  0x801083: 48c7c10c000000 mov rcx, 0xc
  0x80108a: f3a4           rep movsb byte ptr [rdi], byte ptr [rsi]
  0x80108c: 59             pop rcx
  0x80108d: 5e             pop rsi
  0x80108e: 5f             pop rdi
  0x80108f: e99cf5bfff     jmp 0x400630
  [PATCH] @0x801033-0x80103f | "hook stage 1"
  - 000000000000000000000000
  + 0x801033: e91d0a4000 jmp 0xc01a55
  + 0x801038: 9090       nop (x2)
  + 0x80103a: b800000000 mov eax, 0
  [PATCH] @0x80103f-0x80104b | "hook stage 2"
  - 000000000000000000000000
  + 0x80103f: 7e11       jle 0x801052
  + 0x801041: bff7064000 mov edi, 0x4006f7
  + 0x801046: e93d0a4000 jmp 0xc01a88
  [PATCH] @0x400629-0x400635 | "hook entry point"
  - 0x400629: 7e11       jle 0x40063c
  - 0x40062b: bff7064000 mov edi, 0x4006f7
  - 0x400630: b800000000 mov eax, 0
  + 0x400629: e91d0a4000 jmp 0x80104b
  + 0x40062e: 9090       nop (x2)
  + 0x400630: b800000000 mov eax, 0

[+] Saving binary to: /home/ver0n1ca/Desktop/patchkit-master/test/simple.patched

Thanks!

lunixbochs commented 5 years ago

What's your patch script?

Ver0n1ca commented 5 years ago

My patch script:

def patch(pt):
    hello, size = pt.inject(raw='hello world\n', size=True)

    addr = pt.inject(asm=r'''
    push rax
    push rdi
    push rsi
    push rdx
    mov rax, 1  # SYS_write
    mov rdi, 1  # fd
    mov rsi, %d # buf
    mov rdx, %d # size
    syscall
    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret
    ''' % (hello, size))
    pt.hook(0x400629, addr)

Thanks a lot.

Ver0n1ca commented 5 years ago

This problem is solved in the latest dyn branch. Thanks!