7

I learned the disassembly challenges from this link. The following six challenges are listed in that article:

  1. Data embedded in the code regions
  2. Variable instruction size
  3. Indirect branch instructions
  4. Functions without explicit CALL sites within the executable's code segment
  5. Position independent code (PIC) sequences
  6. Hand crafted assembly code.

However, I am thinking about the following disassembly method which seems to solve the above challenges. Assuming we have an executable to be disassembled, an input set that can has 100% coverage of the code, and an emulator (e.g. QEMU). Then, we can instrument the emulator to output each instruction executed by the emulated CPU and the corresponding memory address. After that, we can translate each instruction to assembly instruction, and the whole program is now disassembled.

Could you please tell me why this idea will not/will work?

4 Answers 4

10

an input set that can has 100% coverage of the code

This may be very difficult to achieve, especially if the code behavior depends on something that you don't directly control (time, memory, OS version/environment, random number generator etc.). Additional observations:

  1. actually executing all that code may take more time than you can afford
  2. executing some parts of the code may require conditions you cannot satisfy (e.g. a specific hardware peripheral)
  3. you will miss code which is present in binary but never executes (dead code). In some cases such code can reveal additional information about the binary
  4. your approach may discover all code, but it will likely miss a lot of data.

However, it does not mean that the approach is completely useless. In fact there's already been some work in this area. For example, check out the S2E (Selective Symbolic Execution) project:

https://sites.google.com/site/dslabepfl/proj/s2e

Conceptually, S2E is an automated path explorer with modular path analyzers: the explorer drives the target system down all execution paths of interest, while analyzers check properties of each such path (e.g., to look for bugs) or simply collect information (e.g., count page faults). Desired paths can be specified in multiple ways, and one can either combine existing analyzers to build a custom analysis tool, or write new analyzers using the S2E API.

S2E helps make analyses based on symbolic execution practical for large software that runs in real environments, without requiring explicit modeling of these environments.

5

Can we use dynamic analysis (or just emulator) to achieve 100% code coverage?

No, if I was right, it equals to Turing Halting problem.

emulator based disassemble approach

I am afraid this may not be a very new idea, and code coverage is a big issue.

But it is always possible that you find a different angle and make some contributions in related area.

An interesting paper in last year's tier-one security conference CCS 2013 Obfuscation Resilient Binary Code Reuse through even push related ideas future.

It leverages an emulator to disassemble code, dynamic taint analysis to lift concrete value into symbols, and somehow re-use the disassembled asm code (embedded in C code.)

I wish it could be helpful

0
2

If you want a simple answer. Code coverage. If you only trace called/executed code, how do you know you found all the code.

Emulation is good to understand code when it has memory altering behavior or to understand code. Like in one of my projects I knew I had some double math functions implemented in software. So running an emu to see the results was useful to see the results to identify division verse addition functions. But the emu if started from the entry point would get into an infinite loop as the external Interrupts did not fire at the expected times.

3
  • Thanks! For the code coverage, many programs are shipped with a test suite. And we could assume that they can cover most of the code.
    – ZillGate
    Jul 10, 2014 at 4:04
  • @zillgate That would be a very flawed assumption Jul 10, 2014 at 4:06
  • 2
    In practice, test suites often cover a very small percentage of the basic blocks. Much smaller than one would hope.
    – broadway
    Jul 10, 2014 at 16:38
1

Dis-assembly as a technique isn't a problem As long as you know the boundaries of your binary file (where the data/code starts) and you know the Instrustion Set.

If you know you have UNIX ELF file on x86, you can just run objdump on it to get disassembled output:

objdump -d <file>

Their research was on security. They wanted to read the code boundaries, understand what certain sections of code do and then overwrite some of them. It's much harder problem (e.g.: when do you know the fragment being overwritten isn't actually supposed to be there?)

6
  • Thank you! But if disassembly as a technique isn't a problem, then why the article in the question mentioned those challenges? And based on that article, there must be some binary cases that objdump cannot correctly disassemble, right?
    – ZillGate
    Jul 10, 2014 at 3:32
  • 3
    "As long as you know the boundaries of your binary file (where the data/code starts)" - that's exactly the problem that is difficult to solve when you only have the raw binary
    – Igor Skochinsky
    Jul 10, 2014 at 10:21
  • @IgorSkochinsky By "only have the raw binary", do you mean the binary cannot be executed? If so, then the emulator idea won't work, and we need to use linear sweeping or recursive traversal...
    – ZillGate
    Jul 10, 2014 at 12:30
  • 1
    @ZillGate: no, I mean we have an executable but we don't know the boundaries where exactly is data and where's code (besides the entrypoints). E.g. objdump suggested by Wojciech has issues when you have jumptables intermixed with code.
    – Igor Skochinsky
    Jul 10, 2014 at 13:15
  • 2
    @ZillGate You'll get overall understanding of what program is doing that way, but since the program doesn't execute all its code always, you won't be able to fully reconstruct (its source code). Direction which you're thinking about is right, but it's hard to make it work well. For example: QEMU accepts disk images or ELF files.If you have an ELF file it means you can use better tools than QEMU for binary analysis. Disk image assumes you're running without an OS.. Jul 10, 2014 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.