6

Is there some tool to disassemble a raw hex into assembly instructions? for example: lets say we have \xeb\x1d that disassemble into jmp 0x1f according to this online disassembler. So is there some offline tool? I have tried ndisasm its not giving me the right output.

ndisam -b32 foo gives me:

OUTPUT:

00000000  5C                pop esp<br>
00000001  7833              js 0x36<br>
00000003  315C7865          xor [eax+edi*2+0x65],ebx<br>
00000007  620A              bound ecx,[edx]

It should be jmp 0x1f. I have also tried objdump like:

objdump -D -b binary -mi386 -M intel foo

OUTPUT:

00000000 <.data>:<br>
   0:   5c                      pop    esp <br>
   1:   78 33                   js     0x36 <br>
   3:   31 5c 78 65             xor    DWORD PTR [eax+edi*2+0x65],ebx<br>
   7:   62 0a                   bound  ecx,QWORD PTR [edx]<br>

SO can you tell me some tool that will disassemble raw hex codes into assembly language.

I have also tried gdb but I want something more flexible.

Michael Petch
  • 42,023
  • 8
  • 87
  • 158
Rishi Bhatt
  • 81
  • 1
  • 3
  • The bytes 5c 78 65 5c 78 31 64 0a are the representation of the string `\xeb\x1d` (terminated with a newline) which is what you get when you type `echo '\xeb\x1d' >foo`. You want to disassemble the bytes eb 1d, seems like you misunderstood what `"\xeb\x1d"` means. – fuz Jun 27 '17 at 13:48
  • Additionally, note that `eb 1d` is `jmp .+0x1f`, i.e. the address jumped to is relative to the address where the jump instruction is. Depending on where this instruction is disassembled, the absolute jump target changes! – fuz Jun 27 '17 at 13:53
  • You're wrong and the tools are working fine. That disassembly is correct. You're disassembling 5C7833315C7865620A, not EB1D. – m0skit0 Jun 27 '17 at 13:55
  • disassembly of machine code has never been possible - its a misnomer. What these tools *(disassemblers)* actually do is INTERPRETING machine language and GUESSING about possible source-variants – specializt Jun 27 '17 at 13:55
  • 1
    @specializt That is exactly what disassembling means! Translating machine code back into mnemonics. The only guesswork involved is where instructions begin (in case the ISA doesn't make this clear) and for some ISAs, which instruction set is being used. – fuz Jun 27 '17 at 13:59
  • @specializt You are talking about something that is clearly way out of your depth. Machine code has a 1-to-1 relationship with assembly language. Assembly mnemonics are translated by an assembler into machine code, and a disassembler just does the reverse, translating those machine code bytes back into assembly mnemonics. It is *extremely* easy to disassemble machine code into assembly language. No fancy tool is required. What you are probably thinking of is disassemblers that try to turn machine code into *high-level language* code, like C. And you're right: *those* are mostly guesswork. – Cody Gray Jun 27 '17 at 14:12
  • again with the insults which make no sense - please read [the wikipedia article](https://en.wikipedia.org/wiki/Disassembler) - ASM and machine code have no 1:1 relationship, they never had, AFAIK. Because its impossible ... well ... it COULD be possible on platforms and architectures unknown to me but at least x86 and AVR do not include such a relationship - it currently is an *"unsolvable problem"* for these architectures and languages. – specializt Jun 27 '17 at 14:29
  • 2
    The Wikipedia article is simultaneously trying to go into too much depth *and* grossly oversimplifying. This line: *"For example, an x86 assembler takes an arbitrary choice between two binary codes for something as simple as MOV AX,BX. If the original code uses the other choice, the original code simply cannot be reproduced at any given point in time."* is absurd. If there are two possible encodings for `MOV AX, BX`, then no matter which one is found in the hex dump, it would be disassembled to `MOV AX, BX`, *which is the original instruction*! – Cody Gray Jun 27 '17 at 14:32
  • And while yes, disassembling an *entire application* is a non-trivial exercise, in part because of data being mixed in with code, and in part because of the halting problem, it is nowhere near that difficult to disassemble a series of instructions as might make up a function or group of functions. No halting problem needs to be solved. The variable-length instruction format on x86 makes it slightly challenging, but it is nevertheless a solved problem. – Cody Gray Jun 27 '17 at 14:34
  • 1
    @CodyGray That Wikipedia article needs some serious work. They have actually over complicated the article to the point that it actually doesn't make much sense. Even the disassembly example of relative/absolute jump makes no sense. Whether it is absolute or relative is part of the encoding. Almost like someone who doesn't know x86 tried to write that. – Michael Petch Jun 27 '17 at 15:43

1 Answers1

11

As the comments have suggested, your issue is that you have output the string \xeb\x1d as ASCII into the file you are trying to disassemble. You may have done something like:

echo '\xeb\x1d' >foo

You can do this but you will want to tell echo to interpret the escape character \. This can be done with the -e option.

You'll want it to not append a newline on the end using the -n option. This is documented in the ECHO manual page:

  -n     do not output the trailing newline
  -e     enable interpretation of backslash escapes

This may work:

echo -ne '\xeb\x1d' >foo

Using NDISASM to disassemble the bytes:

ndisasm -b32 foo

Should now produce:

00000000  EB1D              jmp short 0x1f

Without using an intermediate file (like foo) you can pipe ECHO output into NDISASM and disassemble it that way. This line would take a shell code string and output the disassembly as well:

echo -ne '\xeb\x1d' | ndisasm -b32 -

The - on the end is needed to tell NDISASM to disassemble input from standard input rather than an explicit file.

We have now revolutionized the IT industry! ;-)

Michael Petch
  • 42,023
  • 8
  • 87
  • 158
  • Oh i see,Thank you. – Rishi Bhatt Jun 27 '17 at 19:50
  • Another much more convenient way is to declare two global symbols at the beginning and end of your shellcode- call them PIC_START and PIC_END. Compile the assembly using gcc -c shellcode.s. Do NOT have a main() or _start() symbol. Then, write a simple c program with extern unsigned char *PIC_START; unsigned char *PIC_END, call it main.c and give it a main with an unsigned char *ptr that starts at PIC_START and iterates over your shellcode, one byte at a time (or however you want to do it) and use a print statement like printf("\\x%.02x", *ptr); – adam Jul 01 '17 at 00:10
  • can you make this interactive? – AK_ Jan 08 '18 at 21:32