逆向筆記之基礎學習(一)
博客已搬家,新博客地址
本文筆記均來自於對滴水逆向教程的學習,通過學習教程記錄的筆記,個人所見所得。
我感覺滴水課程原理性的講的蠻好,通過這個來夯實基礎。
大綱:
-
進制學習
-
數據寬度
-
二進制的邏輯運算
-
通用寄存器
-
常見彙編指令
-
內存
-
標誌寄存器
-
堆棧
-
jcc
進制
學習大綱:
- 進制的實質就是查表
- 熟悉2進制跟16進制的轉換
- 熟悉進製表的製作以及計算進制之間的加減乘除
進制練習
- 通過編寫7進制加法表,乘法表,並計算
- 23456+54356 = ?
- 5621 - 654 = ?
- 234 * 65 = ?
- 2+3 = 1?可能嘛
- 16進制與二進制的映射
- 自行編寫進制加密
練習1解答
首先編寫1-100的7進制數據
一 | 二 | 三 | 四 | 五 | 六 | 七 |
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
30 | 31 | 32 | 33 | 34 | 35 | 36 |
40 | 41 | 42 | 43 | 44 | 45 | 46 |
50 | 51 | 52 | 53 | 54 | 55 | 56 |
60 | 61 | 62 | 63 | 64 | 65 | 66 |
編寫7進制加法表
一 | 二 | 三 | 四 | 五 | 六 |
---|---|---|---|---|---|
1+1=2 | |||||
1+2=3 | 2+2=4 | ||||
1+3=4 | 2+3=5 | 3+3=6 | |||
1+4=5 | 2+4=6 | 3+4=10 | 4+4=11 | ||
1+5=6 | 2+5=10 | 3+5=11 | 4+5=12 | 5+5=13 | |
1+6=7 | 2+6=11 | 3+6=12 | 4+6=13 | 5+6=14 | 6+6=15 |
編寫7進制乘法表
一 | 二 | 三 | 四 | 五 | 六 |
---|---|---|---|---|---|
1*1=1 | |||||
1*2=2 | 2*2=4 | ||||
1*3=3 | 2*3=6 | 3*3=12 | |||
1*4=4 | 2*4=11 | 3*4=14 | 4*4=22 | ||
1*5=5 | 2*5=13 | 3*5=21 | 4*5=26 | 5*5=34 | |
1*6=6 | 2*6=15 | 3*6=24 | 4*6=33 | 5*6=42 | 6*6=51 |
計算結果:
計算過程:
- 6+6 查表是15,進一位,留5
- 5+5 查表是13, 13 + 1,3+1查表爲4,爲14,進一位,留4
- 4+3 查表是10, 10 + 1,11,進一位,留1
- 3+4 查表是10, 10+1 = 11,進一位,留1
- 2+5 查表是10, 10+1 = 11,進一位,留1
結果爲:111145
計算過程:
- 1不夠減,借一位,爲11,11-4=?,查表可得爲4,
- 2-1 = 1,1-5不夠,借一位,11-5=3
- 5-6不夠,15-6=6
- 4
結果爲:4634
計算過程:
- 4*5 = 26,留6 進2
- 3*5 = 21, 21+2, 23,留3 進2
- 2*5 = 13 13+2=15 留5,進1
- 1536
- 4*6 = 33, 留3 進3
- 3*6 = 24, 24+3,4+3 == 10,留0,進3
- 2*6 = 15, 15+3, 5+3=11,進2,留1
- 2103
結果爲:22536
練習2解答
可能,當定義如下的10進制時便可,0,2,3,1,5,6,7,8,9,4
練習3解答
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
練習4解答
定義如下的7進制,4,5,6,1,2,3,0
試着計算上題中的計算題目
先編寫進制對應
一 | 二 | 三 | 四 | 五 | 六 | 七 |
---|---|---|---|---|---|---|
4 | 5 | 6 | 1 | 2 | 3 | 0 |
54 | 55 | 56 | 51 | 52 | 53 | 50 |
64 | 65 | 66 | 61 | 62 | 63 | 60 |
14 | 15 | 16 | 11 | 12 | 13 | 10 |
24 | 25 | 26 | 21 | 22 | 23 | 20 |
34 | 35 | 36 | 31 | 32 | 33 | 30 |
04 | 05 | 06 | 01 | 02 | 03 | 00 |
編寫7進制加法表
一 | 二 | 三 | 四 | 五 | 六 |
---|---|---|---|---|---|
5+5=6 | |||||
5+6=1 | 6+6=2 | ||||
5+1=2 | 6+1=3 | 1+1=0 | |||
5+2=3 | 6+2=0 | 1+2=54 | 2+2=55 | ||
5+3=0 | 6+3=54 | 1+3=55 | 2+3=56 | 3+3=51 | |
5+0=54 | 6+0=55 | 1+0=56 | 2+0=51 | 3+0=52 | 0+0=53 |
編寫7進制乘法表
一 | 二 | 三 | 四 | 五 | 六 |
---|---|---|---|---|---|
5*5=5 | |||||
5*6=6 | 6*6=2 | ||||
5*1=1 | 6*1=0 | 1*1=56 | |||
5*2=2 | 6*2=55 | 1*2=53 | 2*2=66 | ||
5*3=3 | 6*3=51 | 1*3=65 | 2*3=60 | 3*3=12 | |
5*0=0 | 6*0=53 | 1*0=62 | 2*0=11 | 3*0=26 | 0*0=35 |
計算
計算過程:
- 6+6 = 2 留2
- 5+5 = 6 留6
- 4+3 = 3 留3
- 3+4 = 3 留3
- 2+5 = 3 留3
結果:33362
計算過程:
- 1-4 = 1
- 2-5 = 1
- 6-6 = 0
- 5
結果:5011
計算過程:
- 4*5 = 4
- 3*5 = 3
- 2*5 = 2
- 234
- 4*6 = 4
- 3*6 = 51 留1 進5
- 2*6 = 55 55 + 5 , 5+5=6, 55+5=56,留6,進5
- 5614
結果:51434
數據寬度
記住圓圈,
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ME3Xakvd-1581900451300)(https://raw.githubusercontent.com/NoOne-hub/picture/master/img/20200121215830.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0sbVoK1r-1581900451302)(https://raw.githubusercontent.com/NoOne-hub/picture/master/img/20200121215855.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-8HbYzzTG-1581900451303)(https://raw.githubusercontent.com/NoOne-hub/picture/master/img/20200121215916.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-C6zcCH4M-1581900451304)(https://raw.githubusercontent.com/NoOne-hub/picture/master/img/20200121215934.png)]
數據類型 | 單位(bit) |
---|---|
byte 字節 | 8 |
word 字 | 16 |
dword 雙字 | 32 |
qword 四字 | 64 |
內存中只存0和1,沒有正負數只分,正負數是人爲分開的,通過圓圈
二進制邏輯運算
- 與(and &)
- 或(or |)
- 異或(xor ^)
- 非(not !)
具體應用
- CPU如何計算2+3=?
X:0010
Y:0011
其實很好理解,xor是取出不需要進位的,而&是取出要進位的,
X&Y=0010
X^Y=0001
所以x+y的時候需要第二位進第三位,所以左移一位
0100 在將不需要進位的搞回去
0100 ^ 0001 = 0101
- 獲取某個值的第N位的值是多少?
與第n位就行
- 簡單加密算法
xor加密,然後xor還可以解密
通用寄存器
寄存器 | (編號)二進制 | (編號)十六進制 | ||
---|---|---|---|---|
32位 | 16位 | 8位 | ||
eax | ax | al | 000 | 0 |
ecx | cx | cl | 001 | 1 |
edx | dx | dl | 010 | 2 |
ebx | bx | bl | 011 | 3 |
esp | sp | ah | 100 | 4 |
ebp | bp | ch | 101 | 5 |
esi | si | dh | 110 | 6 |
edi | di | bh | 111 | 7 |
r通用寄存器
m代表內存
imm代表立即數
r8代表8位通用寄存器
imm8代表8位立即數
m8代表8位內存
小結
-
32位通用寄存器,
位通用寄存器,8位寄存器
EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI -
寄存器eax-ax-ah-al的關係
EAX > ax > ah=al
子集關係
常見彙編
mov指令
mov 目標操作數,源操作數
- 源操作數可以是立即數,通用寄存器,段寄存器,內存單元
- 源操作數和目標操作數不能同時爲內存單元
- 操作數寬度必須一樣
- mov r/m8, r8
- mov r/m16, r16
- mov r/m32, r32
- mov r8, r/m8
- mov r16, r/m16
- mov r32, r/m32
- mov r8, imm8
- mov r16, imm16
- mov r32, imm32
add指令
同理,替換掉mov指令成add指令,上述也是成立的
sub指令
同理,替換掉mov指令成sub指令,上述也是成立的
and指令
同理,替換掉mov指令成sub指令,上述也是成立的
or指令
同理,替換掉mov指令成sub指令,上述也是成立的
xor指令
同理,替換掉mov指令成sub指令,上述也是成立的
not指令
not r/m8
not r/m16
not r/m32
ADC指令帶進位加法
ADC R/M,R/M/IMM 兩邊不能同時爲內存,寬度要一樣
SBB帶借位減法
SBB R/M,R/M/IMM 兩邊不能同時爲內存,寬度要一樣
XCHG 交換數據
XCHG R/M, R/M 不能爲立即數啊,想想變量a跟1交換是什麼鬼
MOVS 移動數據 內存-內存
都是內存
只有edi跟esi能用
movs byte ptr es:[edi],byte ptr ds:[esi]
簡寫
- movsb byte
- movsw word
- movsd dword
D標誌爲1,esi跟edi減,D標誌爲0,+
STOS 將AL/AX/EAX的值存儲到[edi]指定的內存單元
stos byte ptr es:[edi]
簡寫
- stosb
- stosw
- stosd
方向由D位決定
REP 按ecx指定的次數重複執行
mov ecx,10
rep movsd
就是重複movsd 16次
內存
寄存器與內存的區別
- 寄存器位於CPU內部,執行速度塊,但比較貴
- 內存速度相對較慢,成本較低,可以做的很大
- 計算機中幾個常用計量單位: byte, word, dword, qword
byte 字節 = 8bit
word 字 = 16bit
dword 雙字 = 32bit
qword 四字 = 64bit
1kb = 1024 byte
1mb = 1024kb
1gb = 1024mb
1024 = 2的10次方
-
32位計算機是因爲地址總線總共有32條,最大尋址範圍是0-0xFFFFFFFF, 內存中最多能存儲信息0+0xFFFFFFFF = 100000000即4g
-
32位尋址最多識別內存爲4g對嗎?
通常情況下是4g
不對,可以通過打補丁
內存與立即數區別
內存:[編號]
立即數: 數值
內存讀寫
涉及內存讀寫要指定數據寬度,也就是word,dword指定
mov word ptr ds:[0x12345678],0xffff
mov dword ptr ds[0x12345678],0xffff
從高位往低寫,比如寫word,小端存儲的話,是高位存高位,低位存低位
尋址公式
立即數尋址
mov eax,dword ptr ds:[0x13ffc4]
獲取內存編號
lea eax,dword ptr ds:[0x13ffc4]
lea還可以用來計算
寄存器尋址
mov ecx,12ffc4
mov eax,dword ptr ds:[ecx]
lea eax,dword ptr ds:[ecx]
寄存器+立即數尋址
mov eax,dword ptr ds:[ecx+4]
lea eax,dword ptr ds:[ecx+8]
[reg+reg*{1,2,4,8}]
mov eax,13ffc4
mov ecx,2
mov edx,dword ptr ds:[eax+ecx*4]
[reg+reg*{1,2,4,8}+立即數]
mov eax,13ffc4
mov ecx,2
mov edx,dword ptr ds:[eax+ecx*4+4]
標誌寄存器
- 進位標誌CF(carry flag) 最高位產生進位或者借位,
- 奇偶標誌位PF(Parity flag) 結果中1的個數,偶數PF=1,奇數PF=0
- 輔助進位標誌AF(Auxiliary Carry flag)
- 零標誌位ZF(zero flag) 用來反映結果是否是0
- 符號標誌位SF(signed flag) 運算結果的符號位
- 溢出標誌位OF(overflow flag)
自己學會拆EFL
進位標誌CF(Carry Flag)
如果運算結果的最高位產生了一個進位或借位,要確定數據寬度,比如add al,1 只要al進位了,就會改變標誌位
無符號關注CF位
奇偶標誌位PF(Parity Flag)
奇偶標誌位PF用於反映運算結果中’1’的個數的奇偶性,如果爲偶數,則爲1, 反之爲0
mov al,3 011
add al,3 110 #P爲1
add al,2 1000 #P爲0
輔助進位標誌AF(Auxiliary Carry Flag)
以下情況,AF爲1,否則爲0
- 在字操作時,發生低字節向高字節進位或借位時
- 在字節操作時,發生低4位向高四位進位或借位時
mov eax,55eeffff
add eax,2
低四位+2進位了,所以AF爲1
mov ax,5efe
add ax,2
就看fe進位沒,進位了,所以AF爲1
注意這裏要看bit
零標誌位ZF(Zero Flag)
零標誌ZF用來反映運算結果是否爲0
xor eax,eax 清0同時還會影響標誌位
mov eax,0 清0 不影響標誌位
符號標誌SF(Sign Flag)
運算結果的符號位,與運算結果最高位相同
mov al,7f
add al,2
溢出標誌OF(Overflow Flag)
進位標誌表示無符號數運算結果是否超出範圍
溢出主要是給有符號運算使用
- 正+正=正 如果結果是負數,則說明溢出了
- 負+負=負 如果結果是整數,則說明溢出了
- 正+負 永遠不會溢出
理解那個圈,那個圈挺有用的
1. 無符號,有符號都不溢出
mov al,8
add al,8
2. 無符號溢出,有符號不溢出
mov al,0ff
add al,2
無符號超過了,溢出,有符號,-1+2 = 1肯定不溢出
3. 無符號不溢出,有符號溢出
mov al,7f
add al,2
有符號,7f和2都是正數,+過後變成負數了,所以溢出了
4. 無符號,有符號都溢出
mov al,0fe
add al,80
fe負數,80負數 加起來是正數,
無符號,也溢出了,超過最大的ff了
方向標誌DF(Direction Flag)
edi跟esi的方向
堆棧
EBP跟ESP,
EBP棧底
ESP棧頂
push 一次 esp-4
pop 一次 esp+4
push
push r32
push r16
push m32
push m16
push imm8,imm16,imm32
pop
pop r32
pop r16
pop m16
pop m32
pushad
pushad將通用寄存器全部push進去,按照寄存器順序,eax,ecx,edx,ebx,esp,ebp,esi,edi,8個通用寄存器8*4=32個字節,所以是sub esp,0x20
popad
恢復全部通用寄存器
練習
- push 後,esp改動的一定是按機器字長來的嗎?
練習解答
不一定,可以push 16位的二進制數,esp-2,不可以弄8進制的數
32位:
-
push dword ptr ds:[0x1234] esp = esp - 4
-
push eax
-
push ax
-
push al X
-
push word ptr ds:[0x1234] esp = esp - 2
-
pop ax esp = esp + 2
-
pop eax
pushad popad
jcc
修改eip
jmp 影響eip的值 jmp reg/imm
call 也影響eip的值 call imm/reg
push 當前指令地址+指令長度地址,mov eip,imm/reg
retn 相當於pop eip
cmp指令
cmp只修改標誌寄存器,相當於sub,
作用比較大小,看sf
是否等於0,看zf
test指令
test R/M,R/M/IMM
實質是&
test eax,eax 判斷eax是不是0
jcc跳轉
jcc指令 | 說明 | 條件 |
---|---|---|
JE, JZ | 結果爲零則跳轉(相等時跳轉) | ZF=1 |
JNE, JNZ | 結果不爲零則跳轉(不相等時跳轉) | ZF=0 |
JS | 結果爲負則跳轉 | SF=1 |
JNS | 結果爲非負則跳轉 | SF=0 |
JP, JPE | 結果中1的個數爲偶數則跳轉 | PF=1 |
JNP, JPO | 結果中1的個數爲偶數則跳轉 | PF=0 |
JO | 結果溢出了則跳轉 | OF=1 |
JNO | 結果沒有溢出則跳轉 | OF=0 |
JB, JNAE | 小於則跳轉 (無符號數) | CF=1 |
JNB, JAE | 大於等於則跳轉 (無符號數) | CF=0 |
JBE, JNA | 小於等於則跳轉 (無符號數) | CF=1 or ZF=1 |
JNBE, JA | 大於則跳轉(無符號數) | CF=0 and ZF=0 |
JL, JNGE | 小於則跳轉 (有符號數) | SF≠ OF |
JNL, JGE | 大於等於則跳轉 (有符號數) | SF=OF |
JLE, JNG | 小於等於則跳轉 (有符號數) | ZF=1 or SF≠ OF |
JNLE, JG | 大於則跳轉(有符號數) | ZF=0 and SF=OF |
總結
基礎不紮實,感覺逆向起來特費勁,通過這個教程來鞏固基礎,將筆記進行整理分享