Try   HackMD

ISIP SummerCamp Day1 Reverse

Keynote Link
Write-up Link

Basic Tools

Static Analysis

file

To determine a file's type

https://linux.die.net/man/1/file

  • syntax
file [option] [file]
  • example
    we have a file name hexedit, we can use file to determine this file
file hexedit

option refrence

strings

print the strings of printable characters in files.

https://linux.die.net/man/1/strings

  • syntax
strings [options] [file]

預設輸出字串長度為4個以上的連續可顯示字元

  • example
    we have a file name hexable, we can use strings to see the visible character in file
strings hexable

nm

list symbols from object files

https://linux.die.net/man/1/nm

如果是執行檔

  • syntax
nm [options] [file]
  • example
    we write a c code first,and compile it, use nm to see the symbols of file
#include<stdio.h> void owo(){ printf("owo") } int main(){ printf("Hello\n"); return 0; }


we can find owo in symbol T

nm symbols

B , b => .bss
T , t => .text
D , d => .data
G , g => global int variable array
r => read only data section
? => unknown symbol type

readelf

Displays information about ELF files.

https://linux.die.net/man/1/readelf

  • syntax
readelf [options] [file]
  • example
    we have a ELF file name hexedit, we can use readelf to see more information
readelf -a hexedit

objdump 看組合語言

display information from object files.

  • 一般都會看-M intel格式

https://linux.die.net/man/1/objdump

  • syntax
objdump [options] [file]
  • example
    we have a binary file name hexable, we can use objdump to see the assembly code in intel format
objdump -M intel -d hexable

Dynamic Analysis

strace

trace system calls and signals

  • 跟系統有關

https://linux.die.net/man/1/strace

  • syntax
strace [options] [file]
  • example
    we have a binary file name a.out, we can use strace to see what system calls the file call
strace ./a.out     

The default maximum output is 32 consecutive characters

ltrace

A library call tracer

https://linux.die.net/man/1/ltrace

  • 印出程式實際用到的function

  • syntax

ltrace [options] [file]
  • example
    we have a file name a.out, we can use ltrace to see what library call the file call
ltrace ./a.out

gdb

The GNU Debugger

https://linux.die.net/man/1/gdb

  • installation
git clone https://github.com/longld/peda.git ~/peda
git clone https://github.com/scwuaptx/Pwngdb.git ~/Pwngdb
cp ~/Pwngdb/.gdbinit ~/
  • syntax
gdb [options] [file]
  • example
    we have a binary name hexedit, we can use gdb to see more info in the file
gdb ./hexedit
  • commands
    • attach <pid>
    • break <point addr>
      設定斷點
    • delete breakpoints [id]
      刪除斷點
    • run
      執行程式
    • step
      執行下一個指令(會進入function)
    • stepi
      執行下一個組語指令(會進入function)
    • next
      執行下一個指令(不會進入function)
    • nexti
      執行下一個組語指令(不會進入function)
    • continue
      繼續執行
    • finish
      執行至function結束
    • jump <address>
      跳轉至指定記憶體位置
    • print $<register>
      印出指定暫存器的值
    • print <address>
      印出指定記憶體位置的值
    • set $<register>
      設定指定暫存器的值
    • set <address>
      設定指定記憶體位置的值
    • info break
      查看斷點狀態
    • info register
      查看暫存器狀態

x86-64 Assembly

rsp ..stack的頂端
rbp ..stack的底端

instruction

  • mov
    • stntax
    ​​​​mov dst, src
    
    • example
    ​​​​■ mov rax, rbx // rax = rbx
    ​​​​■ mov rax, [rbp - 4] // rax = *(rbp - 4)
    ​​​​■ mov [rax], rbx // *rax = rbx
    
  • add/sub/imul/idiv/and/or/xor
    • syntax
    ​​​​add/sub/imul/idiv/and/or/xor dst, src
    
    • example
    ​​​​■ sub rbx, [rbp - 4] // rbx = rbx - *(rbp - 4)
    ​​​​■ mul rcx, 2 // rcx = rcx * 2
    ​​​​■ xor [rsp], rax // *rsp = (*rsp) ^ rax
    
  • inc/dec/neg/not
    • syntax
    ​​​​inc/dec/neg/not dst
    
    • example
    ​​​​■ dec rbx // rbx -= 1
    ​​​​■ neg rcx // rcx = -rcx
    ​​​​■ not byte [rsp] // convert [rsp] to byte *rsp = ~(*rsp)
    
  • cmp
    • syntax
    ​​​​cmp val1, val2
    
    • example
    ​​​​■ cmp rax, 5 // compare the values and set the flag
    ​​​​■ cmp rbx, rcx
    ​​​​■ cmp word [rsp], 0x1234
    
  • jmp
    • syntax
    ​​​​jmp label
    
    • example
    ​​​​■ loop: // set a label
    ​​​​■ ; do something
    ​​​​■ jmp loop // jump to loop label
    
  • ja/jb/jna/jbe/je/jne/jz
    • syntax
    ​​​​ja/jb/jna/jbe/je/jne/jz label
    
    -example
    ​​​​■ cmp rax, 10 // compare the values and set flag
    ​​​​■ je quit // check flag if equal jump to quit
    
  • nop
    • syntax
    ​​​​nop
    
  • syscall
    • syntax
    ​​​​syscall
    

Practice

try to output hello world by using assembly code

global _start section .data msg db "Hello, world!", 0xa len equ $ - msg section .text _start: mov rax, 1 ; write syscall number mov rdi, 1 ; 1 for stdout mov rsi, msg ; buf address mov rdx, len ; output length syscall mov rax, 60 ; exit syscall number mov rdi, 0 syscall

解說
Line 9: 輸出檔案需要使用write這個syscall方法,參考資料可以知道sys_writerax是1

Line 10: 這邊要選擇輸出的位置,可以參考資料得知rdi是1

Line 11: 這邊要指定輸出的內容,在Line4已經將Hello, world!存入magrsi這邊指定是msg即可

Line 12: 這邊要指定輸出的總長度,在Line5已經將長度存在len中,rdx這邊指定len即可

compile assembly code to binary

nasm -f elf64 <asm file>
ld -m elf_x86_64 -o <out file> <.o file>

nasm ..把組合語言編譯為物件檔
ld .. 連結

function call

stack

rsp store the top address of stack frame
rbp store the bottom address of stack frame

in stack

push rbp mov rbp, rsp sub rsp, N

解說
Line1: 將舊rbp位置推入stack頂端
Line2: 調整rbprsp的位置
Line3: 調整rsp位置,開出stack frame大小為N

out stack

mov rsp, rbp pop rbp ret

解說
Line1: 調整rsprbp的位置
Line2: 將rbp調整回舊rbp的位置
Line3: 結束

C++



可以發現到C++的asembly code命名很複雜,可以透過demangle改善

c++filt <mangling name>
objdump -C <C++ binary>

in gdb

set print asm-demangle on

Reverse Engineering Tips

Patch Binary

hook
先確定file有動態連結

tags: ISIP SummerCamp 2020