decomp2dbg icon indicating copy to clipboard operation
decomp2dbg copied to clipboard

Unable to decompile after rebasing addreses of PIE binary in Binja

Open owah opened this issue 1 year ago • 12 comments

Hi,

I wanted to play around with this plugin, but I can't seem to get it to work on windows, specifically within WSL. BinaryNinja and gdb (with gef script) are communicating with each other, because the plugin says that it is connected. I've tried turning off BN, but then the plugin also complains about not having a connection etc. So I assume everything is fine on that end.

Ultimately though, I don't get symbol or decompiled code. When I step through the instructions my terminal flashes for less than a second and I can only vaguely see something like: "int exceeds xml rpc limit".

I've setup a Debian VM, and within the VM everything works just as expected, so I am assuming that I am installing it correctly. Any idea how to fix this, or how I can log the specific issue for you?

owah avatar Mar 09 '23 22:03 owah

@owah would your binary happen to be PIE? You can check with the checksec command. It would also be useful if you could run vmmap for me and tell me what the starting address of the binary is in the debugger.

mahaloz avatar Mar 09 '23 22:03 mahaloz

@mahaloz Yep, it is PIE:

Canary                        : ✓ (value: 0x37bf007681b65a00)
NX                            : ✓ 
PIE                           : ✓ 
Fortify                       : ✘ 
RelRO                         : Full

vmmap says:

[ Legend:  Code | Heap | Stack ]
Start              End                Offset             Perm Path
0x00555555400000 0x00555555402000 0x00000000000000 r-x /home/owah/RE/nopeeking
0x00555555601000 0x00555555602000 0x00000000001000 r-- /home/owah/RE/nopeeking
0x00555555602000 0x00555555603000 0x00000000002000 rw- /home/owah/RE/nopeeking
0x007ffff7dc8000 0x007ffff7dcb000 0x00000000000000 rw- 
0x007ffff7dcb000 0x007ffff7df1000 0x00000000000000 r-- /usr/lib/x86_64-linux-gnu/libc.so.6
0x007ffff7df1000 0x007ffff7f46000 0x00000000026000 r-x /usr/lib/x86_64-linux-gnu/libc.so.6
0x007ffff7f46000 0x007ffff7f99000 0x0000000017b000 r-- /usr/lib/x86_64-linux-gnu/libc.so.6
0x007ffff7f99000 0x007ffff7f9d000 0x000000001ce000 r-- /usr/lib/x86_64-linux-gnu/libc.so.6
0x007ffff7f9d000 0x007ffff7f9f000 0x000000001d2000 rw- /usr/lib/x86_64-linux-gnu/libc.so.6
0x007ffff7f9f000 0x007ffff7fac000 0x00000000000000 rw- 
0x007ffff7fbe000 0x007ffff7fbf000 0x00000000000000 rw- /dev/zero (deleted)
0x007ffff7fbf000 0x007ffff7fc0000 0x00000000000000 rw- /dev/zero (deleted)
0x007ffff7fc0000 0x007ffff7fc1000 0x00000000000000 rw- /dev/zero (deleted)
0x007ffff7fc1000 0x007ffff7fc2000 0x00000000000000 rw- /dev/zero (deleted)
0x007ffff7fc2000 0x007ffff7fc3000 0x00000000000000 rw- /dev/zero (deleted)
0x007ffff7fc3000 0x007ffff7fc5000 0x00000000000000 rw- 
0x007ffff7fc5000 0x007ffff7fc9000 0x00000000000000 r-- [vvar]
0x007ffff7fc9000 0x007ffff7fcb000 0x00000000000000 r-x [vdso]
0x007ffff7fcb000 0x007ffff7fcc000 0x00000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x007ffff7fcc000 0x007ffff7ff1000 0x00000000001000 r-x /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x007ffff7ff1000 0x007ffff7ffb000 0x00000000026000 r-- /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x007ffff7ffb000 0x007ffff7ffd000 0x00000000030000 r-- /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x007ffff7ffd000 0x007ffff7fff000 0x00000000032000 rw- /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x007ffffffde000 0x007ffffffff000 0x00000000000000 rw- [stack]

owah avatar Mar 10 '23 01:03 owah

@owah I used to be able to trigger this bug with Non-PIE binaries. Would you be able to send me this binary and tell me steps to reproduce. I suspected your address damage was too big, which can be fixed in the xml implementation.

mahaloz avatar Mar 10 '23 15:03 mahaloz

Certainly, the file is a challenge from Hack The Box:

https://app.hackthebox.com/challenges/ptracenopeeking you can get it there if you have an account. If you don't want to, I have also uploaded the file for you here: https://surfdrive.surf.nl/files/index.php/s/W1T1ve4bkRPX8B9

the unpack password is: "hackthebox"

Reproduction steps: Install latest version of BN in WSL2, install GEF for GDB and finally install decomp2dbg. I start the server within BN and when I connect through gdb (decompiler connect binja) it seems fine at first, but as soon as you start stepping you notice you don't see any decompilation.

Doing the same steps in a proper Debian VM works, which leads me to believe that this is WSL related.

owah avatar Mar 10 '23 16:03 owah

@owah ty! To follow up, when you say step, can you be specific on what commands you did? Like did you do entry-break, then step?

mahaloz avatar Mar 10 '23 16:03 mahaloz

I am a novice, so my workflow so far is: Check if the binary memory addresses in the debugger are the same as in my decompiler, if not I rebase the image in BN or IDA.

Then I usually use starti in GDB to get a 'foothold' so that I can check things like the memory mapping or what not. If there aren't any symbols, I look for the proper address to break on in my rebased binary.

I mostly only use si, ni and finish and continue.

Does that answer your question?

owah avatar Mar 10 '23 16:03 owah

Check if the binary memory addresses in the debugger are the same as in my decompiler, if not I rebase the image in BN or IDA.

Ah, this is most likely the cause of the crash. I think most people just use offsets instead of rebasing their decompiler (since the debugger can change addresses every run). So in this case, you rebased to 0x00555555400000?

mahaloz avatar Mar 10 '23 17:03 mahaloz

Uploading referenced binary here: nopeeking.zip

mahaloz avatar Mar 10 '23 17:03 mahaloz

Check if the binary memory addresses in the debugger are the same as in my decompiler, if not I rebase the image in BN or IDA.

Ah, this is most likely the cause of the crash. I think most people just use offsets instead of rebasing their decompiler (since the debugger can change addresses every run). So in this case, you rebased to 0x00555555400000?

Yep, to me it seemed like the easiest solution, because I read somewhere that when you open a binary in gdb, it will basically turn off the address randomisation, so all my GDB runs will just use the same addresses.

And having the same memory addresses everywhere feels like you can concentrate on other things, instead of calculating offsets.

owah avatar Mar 10 '23 17:03 owah

@owah Ok so I think there are two problems here. The first issue is use outside of what is assumed by d2d, and the second is a real bug I can work to make a more robust handling system for it.

So I took the binary you gave me and tested it in the normal way I've seen others debug with:

  1. Open the binary in gdb and binja
  2. Start the Binja d2d server
  3. In gdb do: entry-break (you could do starti too, it just stops you at a starting place)
  4. decompiler connect ... your decompiler now
  5. ni (you will have decompilation)
  6. b main (you can break at symbols)

This causes the intended behavior of d2d.

mahaloz avatar Mar 10 '23 17:03 mahaloz

Rebasing causes the debugger to tell the decompiler that it's PIE, which means that it needs to rebase everything. But then the decompiler has essentially turned the binary into a Non-PIE address layout, which conflicts with what the debugger is telling the decompiler. This causes both to send massive addresses (the ones seen inside the debugger), which both causes a mismatch and a number too large to send on XML.

I can look into a solution to detect this type of mismatch but it will be tricky since the user can mess with addresses which essentially throws everything off.

mahaloz avatar Mar 10 '23 17:03 mahaloz

@owah Ok so I think there are two problems here. The first issue is use outside of what is assumed by d2d, and the second is a real bug I can work to make a more robust handling system for it.

So I took the binary you gave me and tested it in the normal way I've seen others debug with:

1. Open the binary in gdb and binja

2. Start the Binja d2d server

3. In gdb do: `entry-break` (you could do starti too, it just stops you at a starting place)

4. `decompiler connect ...` your decompiler now

5. `ni` (you will have decompilation)

6. `b main` (you can break at symbols)

This causes the intended behavior of d2d.

I've just tested this under WSL without rebasing, and it works too, really great, thanks!

owah avatar Mar 10 '23 19:03 owah

I believe this was resolved. Feel free to reopen if it was not :).

mahaloz avatar Jul 18 '24 17:07 mahaloz