19 Desember 2016 - 23:16:54 - Read: 394

Melihat Kode Disassembled Binary "Hello World!" 32-bit dan 64-bit

Yarp, pada artikel sebelumnya di Assembly First Code, Hello World! kita sudah berhasil membuat 2 buah file binary elf dan elf64 dengan kode yang sama. Perbedaannya adalah pada saat kita akan meng-assemble kode tersebut.

32-bit

$ nasm -f elf hello.asm
$ ld -m elf_i386 -s -o hello hello.o

64-bit

$ nasm -f elf64 hello-64.asm
$ ld -s -o hello-64 hello-64.o

 parameter -f pada nasm adalah format file output hasil assemble. elf untuk membuat file binary 32-bit dan elf64 untuk membuat file binary 64bit. Format lain yang bisa kita assemble menggunakan nasm adalah sebagai berikut:

valid output formats for -f are (`*' denotes default):
  * bin       flat-form binary files (e.g. DOS .COM, .SYS)
    ith       Intel hex
    srec      Motorola S-records
    aout      Linux a.out object files
    aoutb     NetBSD/FreeBSD a.out object files
    coff      COFF (i386) object files (e.g. DJGPP for DOS)
    elf32     ELF32 (i386) object files (e.g. Linux)
    elf64     ELF64 (x86_64) object files (e.g. Linux)
    elfx32    ELFX32 (x86_64) object files (e.g. Linux)
    as86      Linux as86 (bin86 version 0.3) object files
    obj       MS-DOS 16-bit/32-bit OMF object files
    win32     Microsoft Win32 (i386) object files
    win64     Microsoft Win64 (x86-64) object files
    rdf       Relocatable Dynamic Object File Format v2.0
    ieee      IEEE-695 (LADsoft variant) object file format
    macho32   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
    macho64   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
    dbg       Trace of all info passed to output stage
    elf       ELF (short name for ELF32)
    macho     MACHO (short name for MACHO32)
    win       WIN (short name for WIN32)

Mungkin pada kasus-kasus tertentu kita akan menggunakan format lainnya diatas.

Berikutnya mari kita lihat perbedaan file binary "Hello World!" pada 32-bit dan 64-bit yang sudah kita compile sebelumnya. Tools yang akan kita gunakan disini adalah Radare 2.

Binary 32-bit

$ r2 ./hello
Warning: Cannot initialize dynamic strings
 -- nothing personal, just bitness
[0x08048080]> aa
[x] Analyze all flags starting with sym. and entry0 (aa)
[0x08048080]> pdf
            ;-- section..text:
/ (fcn) entry0 41
|   entry0 ();
|           0x08048080      ba0e000000     mov edx, 0xe                ; [1] va=0x08048080 pa=0x00000080 sz=29 vsz=29 rwx=--r-x .text
|           0x08048085      b9a0900408     mov ecx, str.Hello__world__n ; "Hello, world!." @ 0x80490a0
|           0x0804808a      bb01000000     mov ebx, 1
|           0x0804808f      b804000000     mov eax, 4
|           0x08048094      cd80           int 0x80
|           0x08048096      b801000000     mov eax, 1
|           0x0804809b      cd80           int 0x80
|           ;-- section_end..text:
|           ;-- section_end.LOAD0:
|           0x0804809d      0000           add byte [eax], al
|           0x0804809f      004865         add byte [eax + 0x65], cl
|           0x080480a2      6c             insb byte es:[edi], dx
|           0x080480a3      6c             insb byte es:[edi], dx
|           0x080480a4      6f             outsd dx, dword [esi]
|           0x080480a5      2c20           sub al, 0x20
\       ,=< 0x080480a7      776f           ja 0x8048118
[0x08048080]> 

Binary 64-bit

$ r2 ./hello-64
Warning: Cannot initialize dynamic strings
 -- Hang in there, Baby!
[0x004000b0]> aa
[x] Analyze all flags starting with sym. and entry0 (aa)
[0x004000b0]> pdf
            ;-- section..text:
/ (fcn) entry0 41
|   entry0 ();
|           0x004000b0      ba0e000000     mov edx, 0xe                ; [1] va=0x004000b0 pa=0x000000b0 sz=29 vsz=29 rwx=--r-x .text
|           0x004000b5      b9d0006000     mov ecx, str.Hello__world__n ; "Hello, world!." @ 0x6000d0
|           0x004000ba      bb01000000     mov ebx, 1
|           0x004000bf      b804000000     mov eax, 4
|           0x004000c4      cd80           int 0x80
|           0x004000c6      b801000000     mov eax, 1
|           0x004000cb      cd80           int 0x80
|           ;-- section_end..text:
|           ;-- section_end.LOAD0:
|           0x004000cd      0000           add byte [rax], al
|           0x004000cf      004865         add byte [rax + 0x65], cl
|           0x004000d2      6c             insb byte [rdi], dx
|           0x004000d3      6c             insb byte [rdi], dx
|           0x004000d4      6f             outsd dx, dword [rsi]
|           0x004000d5      2c20           sub al, 0x20
\       ,=< 0x004000d7      776f           ja 0x400148
[0x004000b0]> 

Jika kita perhatikan antara kedua code diatas dengan kode asli yang kita buat sebelumnya, pada section section .text atau pada output radar adalah entry0 (); , kode tidak ada yang berubah. Kode mulai berubah pada section .data.

Penamaan Register pada 32-bit eXX berubah menjadi rXX pada 64-bit. Perhatikan pada baris

add byte [eax], al dengan add byte [rax], al
atau pada
insb byte es:[edi], dx dengan insb byte [rdi], dx

Merujuk pada artikel https://wiki.cdot.senecacollege.ca/wiki/X86_64_Register_and_Instruction_Quick_Start

General-Purpose Registers

The 64-bit versions of the 'original' x86 registers are named:

  • rax - register a extended
  • rbx - register b extended
  • rcx - register c extended
  • rdx - register d extended
  • rbp - register base pointer (start of stack)
  • rsp - register stack pointer (current location in stack, growing downwards)
  • rsi - register source index (source for data copies)
  • rdi - register destination index (destination for data copies)

These may be accessed as:

  • 64-bit registers using the 'r' prefix: rax, r15
  • 32-bit registers using the 'e' prefix (original registers: e_x) or 'd' suffix (added registers: r__d): eax, r15d
  • 16-bit registers using no prefix (original registers: _x) or a 'w' suffix (added registers: r__w): ax, r15w
  • 8-bit registers using 'h' ("high byte" of 16 bits) suffix (original registers - bits 8-15: _h): ah, bh
  • 8-bit registers using 'l' ("low byte" of 16 bits) suffix (original registers - bits 0-7: _l) or 'b' suffix (added registers: r__b): al, bl, r15b

Gak perlu pusing dulu melihat informasi-informasi gak familiar diatas. :p

Paling gak, hari ini kita sudah mendapatkan sebuah pelajaran cara membedakan binary 32-bit dan 64-bit berdasarkan penamaan alamat register-nya. Walapun gak ngerti, itu yang lain apaan? :D