capstone-engine / capstone

Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
http://www.capstone-engine.org
7.6k stars 1.56k forks source link

Disassembling backward #1294

Open yhs0602 opened 5 years ago

yhs0602 commented 5 years ago

Is there any effective way to disassemble the prior N instructions of CISC architectures?

E.g.

Assume I have ...48 8D 43 1C 74 91 C3 85 C0 EB 40 CC CD 12...

And I disassembled from the 85 C0, and I will get:

85 C0 test eax, eax EB 40 jmp near 40 CC int3 CD 12 int 12 Something like this.

I want to know how to get the prior 50 instructions from the 85 C0(TEST EAX, EAX). In RISC architectures, I can just subtract 200 bytes from the start offset of 85 C0 and call cs_disasm(handle,buffer+offset-200,...).

But how to do this on CISC architectures with variable instruction size?

yhs0602 commented 5 years ago

Sewms like there's no east way to do this.

keenk commented 5 years ago

You are correct. From an arbitrary point in the code there is no easy way (that I know of) to compute how many bytes backward you need to go to reach the n-th previous instruction.

If you are talking about just a small straight line section of code your best bet would probably be to do a forward disassembly starting from some previous known good location. Save the individual instruction results in a collection and then you can step over the collection from end to beginning.

If you are talking about a large section of code, or if you want the disassembly to be in reverse execution order (as opposed to linear reverse address order), it becomes way harder. Take for example that first 85 C0 instruction you mentioned. If we are talking about reverse execution order, that instruction could be the landing address of several other branches in the program. Those branch instructions could happen before or after the section of code you have there.

radare commented 5 years ago

Just use r2. Its implemented there on top of capstone and other disassembler libraries for all the supported archs. And no, you cant do this with just a disassembler, the alignment of the prev instruction require extra information