アセンブリ命令と機械語の相互変換

アセンブリ命令(asm)と機械語(opcode)を相互に変換する方法のメモ。

GNU Binutilsを使う

asmからopcodeに変換するには、asコマンドを使う。

$ echo jmp esp | as -msyntax=intel -mnaked-reg -aln -o /dev/null
   1 0000 FFE4          jmp esp

ここで、-msyntax=intel -mnaked-regアセンブリコード中の.intel_syntax noprefixと同じ意味であり、intel構文を使用、かつレジスタ%espではなくespで記述するオプションである。 次のように、端末を標準入力にすることもできる。

$ as -msyntax=intel -mnaked-reg -aln -o /dev/null
jmp esp
call esp
push esp
ret
[CTRL+D]
   1 0000 FFE4          jmp esp
   2 0002 FFD4          call esp
   3 0004 54            push esp
   4 0005 C3            ret

opcodeからasmに変換するには、objdumpコマンドを使う。

$ echo -en "\xff\xe4" >hoge && objdump -M intel -D -b binary -m i386 hoge

hoge:     file format binary


Disassembly of section .data:

00000000 <.data>:
   0:   ff e4                   jmp    esp

-b binary -m i386はファイルを単純な機械語列とみなし、i386アーキテクチャにおける機械語としてディスアセンブルするオプションである。 また、-M intelアセンブリコードをintel形式で出力するオプションである。

NASMを使う

asmからopcodeに変換するには、nasmコマンドを使う。

$ echo jmp esp >hoge && nasm -f elf -o /dev/null -l /dev/stdout hoge
     1 00000000 FFE4                    jmp esp

デフォルトでは16bitモードでアセンブルされるため、32bitモードでアセンブルするためには-f elfオプションなどを指定する必要がある。

opcodeからasmに変換するには、ndisasmコマンドを使う。

$ echo -en "\xff\xe4" | ndisasm -u -
00000000  FFE4              jmp esp

ndisasmもデフォルトでは16bitモードでディスアセンブルするため、32bitモードでディスアセンブルするためには-uまたは-b32オプションを指定する必要がある。

NASMとnasm_shell.rbを使う

Metasploitに含まれるnasm_shell.rbを使えば、NASMを使って対話的にasmからopcodeに変換することもできる。

$ /opt/metasploit/apps/pro/msf3/tools/nasm_shell.rb
nasm > jmp esp
00000000  FFE4              jmp esp
nasm > call esp
00000000  FFD4              call esp
nasm >

なお、nasm_shell.rbでopcodeからasmへの変換はできない。

rasm2を使う

radare2に含まれるrasm2を使うと、asmとopcodeを相互に変換することができる。 Ubuntu 12.04以降であれば、radare2はaptからインストールできる

$ rasm2 "jmp esp"
ffe4

$ rasm2 -d "ff e4"
jmp esp

rasm2はx86以外のアーキテクチャにも対応している。

$ rasm2 -L
ad  arm       ARM disassembly plugin
ad  armthumb  ARM THUMB disassembly plugin
_d  avr       AVR Atmel disassembler
ad  bf        Brainfuck disassembly plugin
_d  csr       CSR disassembly plugin
ad  dalvik    Dalvik (Android VM) disassembly plugin
ad  java      Java CLASS assembler/disassembler
_d  mips      MIPS disassembly plugin
_d  msil      MSIL disassembly plugin
_d  ppc       PPC disassembly plugin
_d  sh        SH-4 disassembly plugin
_d  sparc     SPARC disassembly plugin
_d  x86       udis86 disassembly plugin
a_  x86.nz    x86 assembler with non-zeros
ad  x86.olly  X86 disassembly plugin (olly engine)

$ rasm2 -a arm "add r1,r2,r3"
031082e0

$ rasm2 -a arm -d "031082e0"
add r1, r2, r3

関連リンク