冰露㊣神 发表于 2020-2-16 22:13

逆向笔记之基础学习(一)

本帖最后由 冰露㊣神 于 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 |



## 总结

基础不扎实,感觉逆向起来特费劲,通过这个教程来巩固基础,将笔记进行整理分享

DumplingBoy 发表于 2020-2-19 11:11

新人重新捡起来C,然后看着汇编的大学教材开始学习,感谢楼主的笔记!其实汇编这种底层语言在分析的时候很有作用,而且还有单片机的应用实例,所以工控、物联网也很有前景。

静默森林 发表于 2020-2-16 22:29

新人前排顶楼主:lol

a838717128 发表于 2020-2-16 22:31

新人前排顶楼主

wuhao123 发表于 2020-2-16 22:56

楼主很强,这个有实战的例子不

iloveu5201314 发表于 2020-2-16 22:57

新人前排顶楼主

Swag-A 发表于 2020-2-16 22:59

感谢楼主分享

月清明月追风 发表于 2020-2-16 23:05

在线小学生 发表于 2020-2-16 23:07

收听了收听了~跟着楼主学习

上将无双 发表于 2020-2-16 23:09

正需要 感谢楼主分享!

y294945022 发表于 2020-2-16 23:16

这是什么编程语言上的吗?
页: [1] 2 3 4 5 6 7
查看完整版本: 逆向笔记之基础学习(一)