user277465
user277465

Reputation:

easy way to get opcodes

I know how to get the opcodes and the corresponding assembly syntax from an executable; however is there an easy way to get the opcodes of a particular assembly instruction alone, without writing a program using the same and then, manually linking and loading it and doing an objdump on the executable?

Is there a simple way to find the corresponding opcodes of a particular instruction?

Upvotes: 6

Views: 18043

Answers (5)

Stefan Steiger
Stefan Steiger

Reputation: 82186

You can use gdb's (GNU Debugger's) x/bx command.

I made a tutorial here:
http://aimbots.net/tutorials/9276-how-get-op-codes.html
http://aimbots.net/threads/9276-How-to-get-OP-codes

https://web.archive.org/web/20180814185730/http://aimbots.net/threads/9276-How-to-get-OP-codes


TL;DR;404

Assuming you need an OP-code for a specific assembler instruction (for example an x64 instruction, to overwrite C-Code.)

One way to find the OP-code is to read the Intel Developer's manual. Unfortunately, this takes very long, and almost never leads to the right finding.

So here is the fast way, the gdb way.

Let's assume we want the OP code for jmp rel32, and for call

The way to do this is to write a tiny assembler program.

.section .data
text: .ascii "hello\n"
.section .text
.globl _start
_start:
    jmp 10000000
    call 7500000
    movl $4, %eax
    movl $1, %ebx
    movl $text, %ecx
    movl $6, %edx
    int $0x80
exit:
    movl $1, %eax
    movl $0, %ebx
    int $0x80 #linux equivalent to int 21h

save as lookup.gas

Compile:

as lookup.gas -o lookup.o
ld -o lookup lookup.o

Now, open it in gdb:
gdb lookup

gdb lookup
GNU gdb 6.8-debian
Copyright © 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(no debugging symbols found)
(gdb) disas _start
Dump of assembler code for function _start:
0x08048074 <_start+0>: jmp 0x989680
0x08048079 <_start+5>: call 0x7270e0
0x0804807e <_start+10>: mov $0x4,%eax
0x08048083 <_start+15>: mov $0x1,%ebx
0x08048088 <_start+20>: mov $0x80490a0,%ecx
0x0804808d <_start+25>: mov $0x6,%edx
0x08048092 <_start+30>: int $0x80
End of assembler dump.
(gdb) x/bx _start+0
0x8048074 <_start>: 0xe9
(gdb) x/bx _start+5
0x8048079 <_start+5>: 0xe8
(gdb) q

--> JMP REL32 = 0xE9y
--> CALL = 0xE8

Since gdb & GAS are available on Windoze, too, you can also do it there...

PS: If you don't like AT&T assembler syntax:

; yasm -f elf32 jmprel32.nasm -o jmprel32.o
; ld -o jmprel32 jmprel32.o

; or

; nasm -f elf jmprel32.nasm
; ld -s -o jmprel32 jmprel32.o


section .data

section .text
    global _start

_start:
    jmp exit
    jmp 1234567890
    call 1234567890
exit:
    mov eax,1           ; The system call for exit (sys_exit)
    xor ebx,ebx         ; Exit with return code of 0 (no error)
    int 80h

And so

GNU gdb 6.8-debian
Copyright © 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(no debugging symbols found)
(gdb) disas _start
Dump of assembler code for function _start:
0x08048060 <_start+0>: jmp 0x804806c <_start+12>
0x08048062 <_start+2>: jmp 0x519a8334
0x08048067 <_start+7>: call 0x519a8339
0x0804806c <_start+12>: mov $0x1,%eax
0x08048071 <_start+17>: xor %ebx,%ebx
0x08048073 <_start+19>: int $0x80
End of assembler dump.
(gdb) x/bx _start+2
0x8048062 <_start+2>: 0xe9
(gdb) x/bx _start+7
0x8048067 <_start+7>: 0xe8
(gdb) x/bx _start+0
0x8048060 <_start>: 0xeb
(gdb) q

Or you can

objdump -drwC -Mintel lookup.o 

to get disassembly with hex machine code for the whole instruction, with bytes space-separated.

Upvotes: 6

sillyMunky
sillyMunky

Reputation: 1278

I'm not sure why you want opcodes. But if its for exploit development you probably already have metasploit which comes with a really useful ruby script called nasm_shell.rb (in the tools directory).

Each line you type comes out as an ascii hex representation of the correct opcodes.

If its for some other purpose or you don't want some heavyweight toolkit like metasploit hanging around for whatever reason, you can just pull out the script and install its dependencies. It uses Rex and assumes nasm is installed.

If you want to adapt it the actual code you need is just a few lines in the function shell.run

Upvotes: 1

X86 Opcode and Instruction Reference contains a bunch of reference tables of instructions and their corresponding opcodes on both 32-bit and 64-bit x86 processors.

Upvotes: 3

Sparky
Sparky

Reputation: 14057

I asked a similar question a while back (DOS debug like program for 32-bit x86 assembly).

Someone was kind enough to provide me with an automated script to do this. You can follow the link to question, or refer to the script they provided to me below ...

opcode() {
  echo $* > tmp.S && nasm tmp.S -o tmp.o && od -x tmp.o
  rm -f tmp.o tmp.S
}

Hope this helps.

Upvotes: 4

phihag
phihag

Reputation: 287835

For x86, you can just look them up in the Intel Manual (Part 1 (A-M), Part 2 (N-Z)). And no, I don't know why the manual is split in 2 parts.

Upvotes: 4

Related Questions