Fwd: [Question] Backwards disassembly

188 views
Skip to first unread message

Duncan Ogilvie

unread,
Nov 7, 2017, 8:16:19 AM11/7/17
to x64dbg
This was an interesting question that I think is worth sharing.

---------- Forwarded message ---------
From: Duncan Ogilvie <mr.exod...@gmail.com>
Date: Mon, 6 Nov 2017 at 21:52
Subject: Re: [Question] Backwards disassembly
To: Rafael Elias <rel...@gmail.com>


Hey,

If there is junk code inserted that interrupts the instruction flow you can change the type of those bytes to byte. For example EB 01 FF 55 90 would look like:

 

If you select the instruction with FF and press B (Right click -> analysis -> treat from selection as -> byte) and set the size to 1 it will instead look like this:


The difference between x64dbg and IDA in this regard is that everything is assumed to be code in the disassembler so you'll have to do the opposite. If the instructions inserted are just junk you should also check out the graph view. Usually this clarifies quite a lot!

The documentation on this front is not great, so an addition to http://help.x64dbg.com or http://blog.x64dbg.com would be much appreciated!

Duncan 

On Mon, 6 Nov 2017 at 21:30 Rafael Elias <rel...@gmail.com> wrote:

Awesome! Thank you!

The only issue that I’ve had with x64dbg’s disassembler is against obfuscated code, but I believe there isn’t much that you can do about it.

For example, when 55 - push ebp is in the middle of another valid instruction:

.text:00D2950E 1F                                            pop     ds
.text:00D2950F
.text:00D2950F                               loc_D2950F:                             ; CODE XREF: .text:00D29445 j
.text:00D2950F 00 74 D2 33                                   add     [edx+edx*8+33h], dh
.text:00D29513
.text:00D29513                               loc_D29513:                             ; CODE XREF: .text:00D29439 j
.text:00D29513                                                                       ; sub_D27B10+CE6 p
.text:00D29513 C0 8B E5 5D C3 55 8B                          ror     byte ptr [ebx+55C35DE5h], 8Bh
.text:00D2951A EC                                            in      al, dx
.text:00D2951B 83 EC 30                                      sub     esp, 30h
.text:00D2951E C6 45 FF 46                                   mov     byte ptr [ebp-1], 46h

In x64dbg, if you go to 0xD29518, then it will display push ebp correctly, but as soon as you scroll up, it disassembles incorrectly because of the obfuscation done way up these addresses. These cases are more complicated… Maybe there could be a way to tell x64dbg that some address is a valid instruction so the decompiler could try to include it when disassembling back. If it isn’t able to find an instruction flow for it, then place a bunch of ?? - invalid opcodes, but without changing the main valid instruction.

In IDA, you can "fix" this by undefining the code and then manually placing the cursor at 55 and pressing C:

image.png

It would be nice to have in x64dbg this manual option for these exceptional cases.

Anyways, thanks once again for the inputs!

On Sun, Nov 5, 2017 at 8:22 PM, Duncan Ogilvie <mr.exod...@gmail.com> wrote:
Hey,

The relevant code can be found here: https://github.com/x64dbg/x64dbg/blob/development/src/gui/Src/Disassembler/QBeaEngine.cpp#L31 Basically the algorithm I use it slightly tweaked from OllyDbg and the idea is to start disasembling backwards like 100 bytes and try to find an instruction flow that disassembles with your current instruction in it. It doesn't work flawlessly (as you can see), but with an interactive tool like x64dbg this isn't really an issue.

Duncan
On Sun, 5 Nov 2017 at 21:34 Rafael Elias <rel...@gmail.com> wrote:

Hey Duncan,

Just a quick question: how backwards disassembly is implemented in x64dbg?

I basically need to implement a function that prints the assembly of the EIP, the next 5 instructions and the 5 previous instructions. Getting the 5 next instructions is trivial, but the 5 previous ones got me questioning about how it should be implemented.

Take this piece of code for example:

.text:00A8FA58 84 C0                                         test    al, al
.text:00A8FA5A 75 1A                                         jnz     short loc_A8FA76
.text:00A8FA5C 8B 8F 5C 01 00 00                             mov     ecx, [edi+15Ch]
.text:00A8FA62 BE 11 21 10 00                                mov     esi, 102111h
.text:00A8FA67 E8 AE 09 FB FF                                call    sub_A4041A
.text:00A8FA6C 84 C0                                         test    al, al
.text:00A8FA6E B9 10 21 00 00                                mov     ecx, 2110h
.text:00A8FA73 0F 45 F1                                      cmovnz  esi, ecx

In x64dbg, if you go to 0xA8FA59, this happens:

image.png

But as soon as you scroll up, it disassembles everything correctly. If you go to 0xA8FA5A and scroll up, the debugger moves to 0xA8FA58 and disassembles the test instruction correctly.

I tried to follow the implementation on x64dbg’s source code, but I couldn’t find exactly where this issue is handled. My idea to solve this problem is to decrement the EIP (-1) until you have 5 successful decodings, but I have the “feeling” that I will run into some false positives.

Could you please give me some insights on how I could implement this? If you prefer, you can just point out the line/file in x64dbg’s source code and I will check it out. I’m also using Zydis and I saw that you guys recently started using it instead of Capstone, but I’m not sure if this migration is finished yet.

Thanks for your attention!

Reply all
Reply to author
Forward
0 new messages