逆向笔记之基础学习(一)
本帖最后由 冰露㊣神 于 2020-2-17 20:36 编辑# 逆向笔记之基础学习(一)
本文笔记均来自于对滴水逆向教程的学习,通过学习教程记录的笔记,个人所见所得。
我感觉滴水课程原理性的讲的蛮好,通过这个来夯实基础。
大纲:
1. 进制学习
2. 数据宽度
3. 二进制的逻辑运算
4. 通用寄存器
5. 常见汇编指令
6. 内存
7. 标志寄存器
8. 堆栈
9. jcc
## 进制
学习大纲:
1. 进制的实质就是查表
2. 熟悉2进制跟16进制的转换
3. 熟悉进制表的制作以及计算进制之间的加减乘除
### 进制练习
1. 通过编写7进制加法表,乘法表,并计算
- 23456+54356 = ?
- 5621 - 654 = ?
- 234 * 65 = ?
2. 2+3 = 1?可能嘛
3. 16进制与二进制的映射
4. 自行编写进制加密
#### 练习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=10 | 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 |
计算结果:
$23456 + 54356 = ?$
计算过程:
1. 6+6 查表是15,进一位,留5
2. 5+5 查表是13, 13 + 1,3+1查表为4,为14,进一位,留4
3. 4+3 查表是10, 10 + 1,11,进一位,留1
4. 3+4 查表是10, 10+1 = 11,进一位,留1
5. 2+5 查表是10, 10+1 = 11,进一位,留1
结果为:111145
$5621 - 654 = ?$
计算过程:
1. 1不够减,借一位,为11,11-4=?,查表可得为4,
2. 2-1 = 1,1-5不够,借一位,11-5=3
3. 5-6不够,15-6=6
4. 4
结果为:4634
$234 * 65 = ?$
计算过程:
1. 4*5 = 26,留6 进2
2. 3*5 = 21, 21+2, 23,留3 进2
3. 2*5 = 13 13+2=15 留5,进1
4. 1536
5. 4*6 = 33, 留3 进3
6. 3*6 = 24, 24+3,4+3 == 10,留0,进3
7. 2*6 = 15, 15+3, 5+3=11,进2,留1
8. 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 |
计算
$23456+54356=?$
计算过程:
1. 6+6 = 2 留2
2. 5+5 = 6 留6
3. 4+3 = 3 留3
4. 3+4 = 3 留3
5. 2+5 = 3 留3
结果:33362
$5621-654=?$
计算过程:
1. 1-4 = 1
2. 2-5 = 1
3. 6-6 = 0
4. 5
结果:5011
$234*65=?$
计算过程:
1. 4*5 = 4
2. 3*5 = 3
3. 2*5 = 2
4. 234
5. 4*6 = 4
6. 3*6 = 51 留1 进5
7. 2*6 = 55 55 + 5 , 5+5=6, 55+5=56,留6,进5
8. 5614
结果:51434
## 数据宽度
记住圆圈,
![](https://raw.githubusercontent.com/NoOne-hub/picture/master/img/20200121215830.png)
![](https://raw.githubusercontent.com/NoOne-hub/picture/master/img/20200121215855.png)
![](https://raw.githubusercontent.com/NoOne-hub/picture/master/img/20200121215916.png)
![](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 !)
### 具体应用
1. CPU如何计算2+3=?
X:0010
Y:0011
其实很好理解,xor是取出不需要进位的,而&是取出要进位的,
X&Y=0010
X^Y=0001
所以x+y的时候需要第二位进第三位,所以左移一位
0100 在将不需要进位的搞回去
0100 ^ 0001 = 0101
2. 获取某个值的第N位的值是多少?
与第n位就行
3. 简单加密算法
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位内存
### 小结
1. 32位通用寄存器,
位通用寄存器,8位寄存器
EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
2. 寄存器eax-ax-ah-al的关系
EAX > ax > ah=al
子集关系
## 常见汇编
### mov指令
mov 目标操作数,源操作数
- 源操作数可以是立即数,通用寄存器,段寄存器,内存单元
- 源操作数和目标操作数不能同时为内存单元
- 操作数宽度必须一样
1. mov r/m8, r8
2. mov r/m16, r16
3. mov r/m32, r32
4. mov r8, r/m8
5. mov r16, r/m16
6. mov r32, r/m32
7. mov r8, imm8
8. mov r16, imm16
9. 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:,byte ptr ds:
简写
- movsb byte
- movsw word
- movsd dword
D标志为1,esi跟edi减,D标志为0,+
### STOS 将AL/AX/EAX的值存储到指定的内存单元
stos byte ptr es:
简写
- stosb
- stosw
- stosd
方向由D位决定
### REP 按ecx指定的次数重复执行
mov ecx,10
rep movsd
就是重复movsd 16次
## 内存
寄存器与内存的区别
1. 寄存器位于CPU内部,执行速度块,但比较贵
2. 内存速度相对较慢,成本较低,可以做的很大
3. 计算机中几个常用计量单位: byte, word, dword, qword
byte 字节 = 8bit
word 字= 16bit
dword 双字 = 32bit
qword 四字 = 64bit
1kb = 1024 byte
1mb = 1024kb
1gb = 1024mb
1024 = 2的10次方
4. 32位计算机是因为地址总线总共有32条,最大寻址范围是0-0xFFFFFFFF, 内存中最多能存储信息0+0xFFFFFFFF = 100000000即4g
5. 32位寻址最多识别内存为4g对吗?
通常情况下是4g
不对,可以通过打补丁
### 内存与立即数区别
内存:[编号]
立即数: 数值
### 内存读写
涉及内存读写要指定数据宽度,也就是word,dword指定
mov word ptr ds:,0xffff
mov dword ptr ds,0xffff
从高位往低写,比如写word,小端存储的话,是高位存高位,低位存低位
### 寻址公式
#### 立即数寻址
mov eax,dword ptr ds:
获取内存编号
lea eax,dword ptr ds:
lea还可以用来计算
#### 寄存器寻址
mov ecx,12ffc4
mov eax,dword ptr ds:
lea eax,dword ptr ds:
#### 寄存器+立即数寻址
mov eax,dword ptr ds:
lea eax,dword ptr ds:
####
mov eax,13ffc4
mov ecx,2
mov edx,dword ptr ds:
####
mov eax,13ffc4
mov ecx,2
mov edx,dword ptr ds:
## 标志寄存器
1. 进位标志CF(carry flag) 最高位产生进位或者借位,
2. 奇偶标志位PF(Parity flag) 结果中1的个数,偶数PF=1,奇数PF=0
3. 辅助进位标志AF(Auxiliary Carry flag)
4. 零标志位ZF(zero flag) 用来反映结果是否是0
5. 符号标志位SF(signed flag) 运算结果的符号位
6. 溢出标志位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
1) 在字操作时,发生低字节向高字节进位或借位时
2) 在字节操作时,发生低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
恢复全部通用寄存器
### 练习
1. push 后,esp改动的一定是按机器字长来的吗?
#### 练习解答
不一定,可以push 16位的二进制数,esp-2,不可以弄8进制的数
32位:
+ push dword ptr ds: esp = esp - 4
+ push eax
+ push ax
+ push al X
+ push word ptr ds: 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 |
## 总结
基础不扎实,感觉逆向起来特费劲,通过这个教程来巩固基础,将笔记进行整理分享 新人重新捡起来C,然后看着汇编的大学教材开始学习,感谢楼主的笔记!其实汇编这种底层语言在分析的时候很有作用,而且还有单片机的应用实例,所以工控、物联网也很有前景。 新人前排顶楼主:lol 新人前排顶楼主 楼主很强,这个有实战的例子不 新人前排顶楼主 感谢楼主分享 收听了收听了~跟着楼主学习 正需要 感谢楼主分享! 这是什么编程语言上的吗?