How to disassemble a shellcode into assembly instruction? [duplicate]
Asked Answered
F

1

7

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.

Fleck answered 27/6, 2017 at 13:41 Comment(10)
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.Rendezvous
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!Rendezvous
You're wrong and the tools are working fine. That disassembly is correct. You're disassembling 5C7833315C7865620A, not EB1D.Lariat
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-variantsFionnula
@Fionnula 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.Rendezvous
@Fionnula 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.Bonnette
again with the insults which make no sense - please read the wikipedia article - 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.Fionnula
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!Bonnette
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.Bonnette
@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.Sechrist
S
12

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! ;-)

Sechrist answered 27/6, 2017 at 13:41 Comment(3)
Oh i see,Thank you.Fleck
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);Outclass
can you make this interactive?Wintry

© 2022 - 2024 — McMap. All rights reserved.