天天看點

iOS逆向之彙編基礎知識(二)

#本人有若幹成套學習視訊, 可試看! 可試看! 可試看, 重要的事情說三遍 包含

Java

,

資料結構與算法

,

iOS

,

安卓

,

python

,

flutter

等等, 如有需要, 聯系微信

tsaievan

.

####(一)程式的本質

讓我們來看一副圖, 看看程式的本質是什麼:

iOS逆向之彙編基礎知識(二)

#####通常,

CPU

會先将記憶體中的資料存儲到寄存器中, 然後再對寄存器中的資料進行運算

#####假設記憶體中有塊紅色記憶體空間的值是

3

, 現在想把它的值加

1

, 并将結果存儲到藍色記憶體空間

  • CPU

    首先會将紅色記憶體空間的值放到rax寄存器中:

    movq 紅色記憶體空間, %rax

  • 然後讓rax寄存器與1相加:

    addq $0x1, %rax

  • 最後将值指派給記憶體空間:

    movq %rax, 藍色記憶體空間

如下圖所示:

iOS逆向之彙編基礎知識(二)

####(二)程式設計語言的發展

  • 機器語言

    1

    組成
  • 彙編語言(

    Assembly Language

    )

    用符号代替了

    1

    , 比機器語言便于閱讀和記憶
  • 進階語言

    C/C++/Java/JS/Python

    等, 更接近人類自然語言
  • 操作

    機器語言:

    1000100111011000

    彙編語言:

    movw %bx, %ax

    進階語言:

    ax = bx

iOS逆向之彙編基礎知識(二)
  • 彙編語言與機器語言一一對應, 每一條機器指令都有與之對應的彙編指令
  • 彙編語言可以通過編譯得到機器語言, 機器語言可以通過反彙編得到彙編語言
  • 進階語言可以通過編譯得到彙編語言/機器語言, 但彙編語言/機器語言幾乎不可能還原成進階語言

####(三)彙編語言的種類

  • 彙編語言的種類

    8086

    彙編(

    16bit

    )

    x86

    彙編(

    32bit

    )

    x64

    彙編(

    64bit

    )

    ARM

    彙編(嵌入式, 移動裝置)
  • x86, x64彙編根據編譯器的不同, 有2種書寫格式

    Intel: Windows派系

    AT&T: Unix派系

  • 作為iOS開發工程師, 最主要的彙編語言是:

    AT&T彙編 ->iOS模拟器

    ARM彙編 ->iOS真機裝置

####(四)常見彙編指令

  • 寄存器命名:

    AT&T:

    %rax

    Intel:

    rax

  • 操作數順序: 将

    rax

    的值指派給

    rdx

    AT&T:

    movq %rax, %rdx

    Intel:

    mov rdx, rax

  • 常數, 立即數: 将

    3

    指派給

    rax

    , 将

    0x10

    指派給

    rax

    AT&T:

    movq $3, %rax

    movq $0x10, %rax

    Intel:

    mov rax, 3

    mov rax, 0x10

  • 記憶體指派: 将

    0xa

    指派給位址為

    rip+0x1ff7

    的記憶體空間

    AT&T:

    movq $0xa, 0x1ff7(%rip)

    Intel:

    mov qword ptr [rip+0x1ff7], 0xa

  • 取記憶體位址: 将

    rbp-0x18

    這個位址指派給

    rax

    AT&T:

    leaq -0x18(%rbp), %rax

    Intel:

    lea rax, [rbp - 0x18]

  • jump

    指令:

    call

    jump

    寫法類似

    AT&T:

    jump *%rdx

    jump 0x4001002

    jump *(%rax)

    Intel:

    jmp rdx

    jmp 0x4001002

    jmp [rax]

  • 操作數長度:
b = byte(8-bit)
s = short(16-bit integer or 32-bit floating point)
w = word(16-bit)
l = long(32-bit integer or 64-bit floating point)
q = quad(64bit)
t = ten bytes(80-bit floating point)
           

AT&T:

movl %eax, %edx

movb $0x10, %al

leaw 0x10(%dx), %ax

Intel:

mov edx, eax

mov al, 0x10

lea ax [dx + 0x10]

####(五)寄存器

  • 有16個常用寄存器

    rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,

    r8, r9, r10, r11, r12, r13, r14, r15

  • 寄存器的具體用途

    rax, rdx

    常作為函數傳回值使用

    rdi, rsi, rdx, rcx, r8, r9

    等寄存器常用于存放函數參數

    rsp, rbp

    用于棧操作

    rip

    作為指令指針

    存儲着

    CPU

    下一條要執行的指令的位址

    一旦

    CPU

    讀取一條指令,

    rip

    會自動指向下一條指令(存儲下一條指令的位址)

####(六)

lldb

常用指令

  • 讀取寄存器的值

    register read/格式

    register read/x

  • 修改寄存器的值

    register write 寄存器名稱 數值

    register write rax 0

  • 讀取記憶體中的值

    x/數量-格式-位元組大小 記憶體位址

    x/3xw 0x0000010

  • 修改記憶體中的值

    memory write記憶體位址 數值

    memory write 0x0000010 10

  • 格式

    x

    是16進制,

    f

    是浮點,

    d

    是十進制
  • 位元組大小

    b -byte

    1位元組

    h -half word

    2位元組

    w -word

    4位元組

    g -giant word

    8位元組
  • expression 表達式

    可以簡寫:

    expr 表達式

    expression $rax

    expression $rax = 1

  • po 表達式

  • print 表達式

    po/x $rax

    po (int) $rax

  • thread step-over, next, n

    單步運作, 把子函數當做整體一步執行(源碼級别)

-

thread step-in, step, s

單步運作, 遇到子函數會進入子函數(源碼級别)

  • thread step-inst-over, nexti, ni

    單步運作, 把子函數當做整體一步執行(彙編級别)
  • thread step-inst, stepi, si

    單步運作, 遇到子函數就會進入子函數(彙編級别)
  • thread step-out finish

    直接執行完目前函數的所有代碼, 傳回到上一個函數(遇到斷點會卡住)

####(七)規律

  • 記憶體位址格式為:

    0x4bdc(%rip)

    , 一般是全局變量, 全局區(資料段)
  • 記憶體位址格式為:

    -0x78(%rbp)

    , 一般是局部變量, 棧空間
  • 記憶體位址格式為:

    0x10(%rax)

    , 一般是堆空間

#本文資料來源于小碼哥

#非商業用途,如有侵權,請告知我,我會删除