keystone-engine / keystone

Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
http://www.keystone-engine.org
GNU General Public License v2.0
2.3k stars 456 forks source link

ARM branch instruction sometimes not encoded properly #277

Open keyboardsmoke opened 7 years ago

keyboardsmoke commented 7 years ago
pi@raspberrypi:~/share/arm-hook $ ./ArmHook
ARM TARGET
Main!
Mode: 0
Instruction (push {fp, lr}) size: 0x4
Size To Save: 0x4
Page protections OK
Trampoline OK
Trampoline protections OK
Generating unconditional branch: b #0x5a1f0
b #0x5a1f0 = [ 07 00 00 ea ]
Generating unconditional branch: b #0x5a1d0
b #0x5a1d0 = [ 47 2c 6d ea ]
print_disasm (0): push {fp, lr} (4)
print_disasm (1): b #0x405a1d0 (4) // !!! THIS ONE !!!
Hooked main!
Segmentation fault

Sometimes when the branch instruction is encoded, it seems it is not the correct output. I am printing disasm with capstone.

I should note, many times this works perfectly

pi@raspberrypi:~/share/arm-hook $ ./ArmHook
ARM TARGET
Main!
Mode: 0
Instruction (push {fp, lr}) size: 0x4
Size To Save: 0x4
Page protections OK
Trampoline OK
Trampoline protections OK
Generating unconditional branch: b #0x5a1f0
b #0x5a1f0 = [ 07 00 00 ea ]
Generating unconditional branch: b #0x5a1d0
b #0x5a1d0 = [ 47 70 89 ea ]
print_disasm (0): push {fp, lr} (4)
print_disasm (1): b #0x5a1d0 (4)
Hooked main!
Main!

But every once in a while it is incorrect, seems to not encode the destination properly (despite same base address, allocated addresses for destinations, etc)

aquynh commented 7 years ago

will be great if you can reproduce this bug reliably.

can you post your script?

keyboardsmoke commented 7 years ago

Sure, I also have an update of sorts. I included my basic algorithm for encoding unconditional branch, and it produces the same erroneous result (sometimes), I believe this may have to do with where my trampoline for my detour function is allocated. I will try to print it and see if I notice anything.

detour.cpp https://gist.github.com/keyboardsmoke/2987cf3c16897525682e5fad3878c498

the main.cpp https://gist.github.com/keyboardsmoke/4d3dae3344c5e3e5b4fd155c3729f13c

Produces:

pi@raspberrypi:~/share/arm-hook $ ./ArmHook
ARM TARGET
Main!
Mode: 0
Instruction (push {fp, lr}) size: 0x4
Size To Save: 0x4
Page protections OK
Trampoline OK
Trampoline protections OK
Generating unconditional branch: b #0x5A228
b #0x5A228 = [ 07 00 00 ea ]
alternate encoder = [ 07 00 00 ea ]
Generating unconditional branch: b #0x5A208
b #0x5A208 = [ 7f cc 6a ea ]
alternate encoder = [ 7f cc 6a ea ]
print_disasm (0): push {fp, lr} (4)
print_disasm (1): b #0x405a208 (4)
Hooked main!
Segmentation fault
pi@raspberrypi:~/share/arm-hook $ ./ArmHook
ARM TARGET
Main!
Mode: 0
Instruction (push {fp, lr}) size: 0x4
Size To Save: 0x4
Page protections OK
Trampoline OK
Trampoline protections OK
Generating unconditional branch: b #0x5A228
b #0x5A228 = [ 07 00 00 ea ]
alternate encoder = [ 07 00 00 ea ]
Generating unconditional branch: b #0x5A208
b #0x5A208 = [ 7f 30 c0 ea ]
alternate encoder = [ 7f 30 c0 ea ]
print_disasm (0): push {fp, lr} (4)
print_disasm (1): b #0x5a208 (4)
Hooked main!
Main!
keyboardsmoke commented 7 years ago

Update number two, yes the allocation address seems to matter here

pi@raspberrypi:~/share/arm-hook $ ./ArmHook
ARM TARGET
Main!
Mode: 0
Instruction (push {fp, lr}) size: 0x4
Size To Save: 0x4
Page protections OK
Trampoline OK (0x1f400a8)
Trampoline protections OK
Generating unconditional branch: b #0x5A1F0
b #0x5A1F0 = [ 07 00 00 ea ]
alternate encoder = [ 07 00 00 ea ]
Generating unconditional branch: b #0x5A1D0
b #0x5A1D0 = [ 47 68 84 ea ]
alternate encoder = [ 47 68 84 ea ]
print_disasm (0): push {fp, lr} (4)
print_disasm (1): b #0x5a1d0 (4)
Hooked main!
Main!
pi@raspberrypi:~/share/arm-hook $ ./ArmHook
ARM TARGET
Main!
Mode: 0
Instruction (push {fp, lr}) size: 0x4
Size To Save: 0x4
Page protections OK
Trampoline OK (0x1c0a0a8)
Trampoline protections OK
Generating unconditional branch: b #0x5A1F0
b #0x5A1F0 = [ 07 00 00 ea ]
alternate encoder = [ 07 00 00 ea ]
Generating unconditional branch: b #0x5A1D0
b #0x5A1D0 = [ 47 40 91 ea ]
alternate encoder = [ 47 40 91 ea ]
print_disasm (0): push {fp, lr} (4)
print_disasm (1): b #0x5a1d0 (4)
Hooked main!
Main!
pi@raspberrypi:~/share/arm-hook $ ./ArmHook
ARM TARGET
Main!
Mode: 0
Instruction (push {fp, lr}) size: 0x4
Size To Save: 0x4
Page protections OK
Trampoline OK (0x206b0a8)
Trampoline protections OK
Generating unconditional branch: b #0x5A1F0
b #0x5A1F0 = [ 07 00 00 ea ]
alternate encoder = [ 07 00 00 ea ]
Generating unconditional branch: b #0x5A1D0
b #0x5A1D0 = [ 47 bc 7f ea ]
alternate encoder = [ 47 bc 7f ea ]
print_disasm (0): push {fp, lr} (4)
print_disasm (1): b #0x405a1d0 (4)
Hooked main!
Segmentation fault

Maybe the difference in distance from the destination is the issue