滴水逆向初级-汇编(一)

1.1.进制

进制的定义:
八进制的定义:由八个符号组成,分别是01234567逢八进一。
十进制的定义:由十个符号组成,分别是0123456789逢十进一。
N进制的定义:由N个符号组成,逢N进一。shell

1.二、进制的运算

八进制运算数据结构

2+3=5
2*3=6
4+5=11
4*5=24
277+333= 632
276*54= 162
237-54= 20250
234/4= 47

#八进制:0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27

八进制加法表函数

2+3=5
2*3=6
4+5=11
4*5=24
277+333= 632
276*54= 162
237-54= 20250
234/4= 47

#八进制:0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27

八进制加法表
image
八进制乘法表
image工具

1.3.二进制简写形式

计算机为何使用二进制
计算机是须要用电的,电路只有两种状态: 1真(通电) 0假(未通电)
计算机中存储的任何文件、接收的任何指令都是由0和1组成的编码

二进制与十六进制操作系统

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
 0	  1	   2	3	  4   5	   6	7	  8	  9	   A	 B	  C	   D   E    F

1.4.数据宽度

数据宽度
数学上的数字,是没有大小限制的,能够无限的大。但在计算机中,因为受硬件的制约,数据都是有长度限制的(咱们称为数据宽度),超过最大宽度的数据会被丢弃。debug

计算机中常见的数据宽度:3d

1)位(BIT) 1位
2)字节(Byte) 8位
3)字(Word) 16位
4)双字(Doubleword) 32位指针

存储范围:
字节(Byte): 0 ~ 0xFF
字(Word): 0 ~ 0xFFFF
双字:0~ 0xFFFFFFFF
若是要存储的数据超过最大宽度,那么多余的数据将被丢弃!code

1.5.无符号数有符号数

无符号数的编码规则

10011010
十六进制:0x9A
十进制:154

有符号数的编码规则

正数编码规则(第一位是0),若是是正数就和无符号数编码规则同样
00011010

负数编码规则(第一位是1)
10011010

1.6.原码反码补码

有符号数的编码规则
原码:最高位为符号位,其他各位为数值自己的绝对值
反码:
正数:反码与原码相同
负数:符号位为1,其他位对原码取反
补码:
正数:补码与原码相同
负数:符号位为1,其他位对原码取反加1

-1
原码:10000001
反码:11111110
补码:11111111     (负数在计算机里面是采用补码的形势存储的)

-7
原码:10000111
反码:11111000
补码:11111001     (负数在计算机里面是采用补码的形势存储的)

1.7.计算机不会作加法

image
image
image
image
image
image

1.8.位运算之加减乘除

4+5=的运算过程
image
4-5=?的运算过程
image

1.9.汇编环境安装

下载DTdebug工具,打开后设置UDD和plugin的路劲。Options-->Appearance
image
image

1.10.通用寄存器

1寄存器
存储数据:
CPU>内存>硬盘
32位CPU: 8 16 32
64位CPU: 8 16 32 64

二、通用寄存器
32位通用寄存器:
EAX
ESP
ECX
EBP
EDX
ESI
EBX
EDI

三、MOV指令
<1> 当即数到内存
<2>寄存器到内存
<3>内存到寄存器

按F8单步运行
image
4.通用寄存器
image

1.11.内存

image
二、内存地址
<1>内存太大无法起名字,因此只能用编号。当咱们想向内存中存储数据,或者从内存中读取数据时,必须用到这个编号,就像写信必需要写收信人地址同样。
<2>这个编号又称为内存地址(32位,前面0能够省略)。

三、往内存中写入值

MOV DWORD PTR DS:[19FF90],12345678

# DWORD表示四个字节长度
#PTR DS:[19FF90]表示内存地址

1.12.内存地址的五种形式

一、形式一: [当即数]
读取内存的值:
MOV EAX,DWORD PTR DS:[Ox13FFC4]
向内存中写入数据:
MOV DWORD PTR DS:[0x13FFC4],EAX

二、形式二: [reg] reg表明寄存器能够是8个通用寄存器中的任意一个
读取内存的值:
MOV ECX,0x13FFD0
MOV EAX,DWORD PTR DS:[ECX]
向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX],0x87654321

三、形式三: [reg+当即数]
读取内存的值:
MOV ECX,0x1 3FFD0
MOV EAX,DWORD PTR DS:[ECX+4]
向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX+0xC],0x87654321

四、形式四: [reg+reg*{1,2,4,8}]
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX4]
向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX
4],87654321

五、形式五: [reg+reg*{1 ,2,4,8}+当即数]
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX4+4]
向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX
4+4],87654321

1.13.存储模式

image
二、DTDEBUG内存窗口的使用
<1>分别以字节/字/双字形式来查看内存(db dw dd)
image
<2>向内存中写入四个字节的数据,并观察存储形式(大端存储/小端存储)
image

1.14.经常使用汇编指令

一、MOV指令
指令格式:
一、MOV r/m8,r8 r通用寄存器
二、MOV r/m16,r16 m表明内存
三、MOV r/m32,r32 ; imm表明当即数
四、MOVr8,r/m8 r8表明8位通用寄存器
五、MOV r16,r/m16 m8表明8位内存
六、MOV r32,r/m32 ; imm8表明8位当即数
七、MOV r8, imm8
八、MOV r16, imm16
九、MOV r32, imm32

二、ADD指令
指令格式:
ADD r/m8, imm8
ADD r/m16, imm16
ADD r/m32,imm32
ADD r/m16, imm8
ADD r/m32, imm8
ADD r/m8, r8
ADD r/m16, r16
ADD r/m32, r32
ADD r8, r/m8
ADD r16, r/m16
ADD r32, r/m32

三、SUB指令
指令格式:
SUB r/m8, imm8
SUB r/m1 6,imm16
SUB r/m32,imm32
SUB r/m16, imm8
SUB r/m32, imm8
SUB r/m8, r8
SUB r/m16, r16
SUB r/m32, r32
SUB r8, r/m8
SUB r16, r/m16
SUB r32, r/m32

四、AND指令
AND r/m8, imm8
AND r/m16,imm16
AND r/m32,imm32
AND r/m16, imm8
AND r/m32, imm8
AND r/m8, r8
AND r/m16, r16
AND r/m32, r32
AND r8, r/m8
AND r16, r/m16
AND r32, r/m32

五、OR指令
OR r/m8, imm8
OR r/m16 ,imm16
OR r/m32,imm32
OR r/m16, imm8
OR r/m32, imm8
OR r/m8, r8
OR r/m16, r16
OR r/m32, r32
OR r8, r/m8
OR r16, r/m16
OR r32, r/m32

六、XOR指令
XOR r/m8, imm8
XOR r/m16,imm16
XOR r/m32 ,imm32
XOR r/m16, imm8
XOR r/m32, imm8
XOR r/m8, r8
XOR r/m16, r16
XOR r/m32, r32
XOR r8, r/m8
XOR r16, r/m16
XOR r32, r/m32

七、NOT指令
NOT r/m8
NOT r/m16
NOT r/m32

1.15.内存复制指令

一、MOVS指令:移动数据内存-内存
BYTENWORD/DWORD
MOVS BYTE PTR ES:[EDJ,BYTE PTR DS:[ESI] 简写为: MOVSB
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] 简写为: MOVSW
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 简写为: MOVSD

例子: .
MOV EDI,12FFD8
MOV ESI,12FFD0
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
观察EDI的值
修改标志寄存器中D位的值,而后在执行下面的指令:
MOV EDI,12FFD8
MOV ESI,12FFD0MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]

二、STOS指令: 将AI/AX/EAX的值存储到[EDI]指定的内存单元
STOS BYTE PTR ES:[EDI] 简写为STOSB
STOS WORD PTR ES:[EDI] 简写为STOSW
STOS DWORD PTR ES:[EDI] 简写为STOSD

例子:

MOV EAX, 12345678 观察EDI的值
MOV EDI, 12FFC4
STOS BYTE PTR ES:[EDI]
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]
修改标志寄存器中D位的值,而后在执行下面的指令:
MOV EAX, 12345678 观察EDI的值
MOV EDI, 12FFC4
STOS BYTE PTR ES:[EDI]
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]

三、REP指令: 按计数寄存器(ECX)中指定的次数重复执行字符串指令
MOV ECX,10
REP MOVSD
REP STOSD

1.16.堆栈相关指令

一、什么是堆栈?
1)就是一块内存,操做系统在程序启动的时候已经分配好的,供程序执行时使用。
2)和数据结构的堆栈无关。
3)查看堆栈。

二、栈指针寄存器
ESP中存储了当前的堆栈用到哪里了

三、堆栈的使用
<1>存储数据
<2>修改栈顶指针

四、PUSH指令
<1>向堆栈中压人数据
<2>修改栈项指针ESP寄存器
指令格式:
一、PUSH r32
二、PUSH r16
三、PUSH m16
四、PUSH m32
五、PUSH imm8/imm1 6/imm32

五、POP指令:
<1>将栈顶数据存储到寄存器/内存
<2>修改栈项指针ESP寄存器
指令格式:|
一、POP r32
二、POPr16
三、POP m16
四、POP m32

1.17.修改EIP的指令

一、JMP指令:
MOV EIP,寄存器/当即数/内存 简写为 JMP寄存器/当即数/内存

二、CALL指令:
PUSH下一行地址
MOV EIP,当即数/寄存器/内存 简写为: CALL当即数/寄存器/内存
与JMP惟--的区别:
在堆栈中存储Call指令下一-行地址

三、RET指令:
ADD ESP,4
MOV EIP,[ESP-4]

简写为: RET

1.18.汇编眼中的函数

一、什么是函数
函数就是一系列指令的集合,为了完成某个会重复使用的特定功能。
例子:向寄存器中赋值

二、如何执行一个函数?即函数调用
<1>用JMP来执行函数
<2> 用CALL来执行函数

三、 什么是参数?什么是返回值?
例子:编写一个函数,可以获得任意2个整数的值。

1.19.堆栈平衡

什么是堆栈平衡?
1)若是要返回父程序,则当咱们在堆栈中进行堆栈的操做的时候,必定要保证在RET这条指令以前,ESP指向的是咱们压入栈中的地址。
2)若是经过堆栈传递参数了,那么在函数执行完毕后,要平衡参数致使的堆栈变化。

1.20.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
七、J0 结果溢出了则跳转 0F=1
八、JNO 结果没有溢出则跳转 0F=0

九、JB, JNAE 小于则跳转(无符号数) CF=1
十、JNB, JAE 大于等于则跳转(无符号数) CF=0
十一、JBE, JNA 小于等于则跳转(无符号数) CF=1 or ZF=1
十二、JNBE, JA 太于则跣转(无符号数) CF=0 and ZF=0中
1三、JL, JNGE 小于则跳转(有符号数) SF≠OF

1四、JN, JGE 大于等于则跳转(有符号数) SF=OF
1五、JLE, JNG 小于等于则跳转(有符号数) ZF=1 or SF≠0F
1六、JNLE, JG 因于则来转(有符号数) ZF=0 and SF=OF

一、标志寄存器:EFLAGS
image
二、CF (bit 0) [Carry fiag]
若算术操做产生的结果在最高有效位(most-significant bit)发生进位或借位则将其置1,反之清零。
这个标志一般用来指示无符号整型运算的溢出状态。

例:
MOV AL,0xFE MOV AL,0x7F
ADD AL,2 或者 SUB AL ,0xFF

三、PF(bit 2) [Parity flag]
若是结果的最低有效字节(least-significant byte)包含偶数个1位则该位置1,不然清零。

利用PF可进行奇偶校验检查:
须要传输"11001110",数据中含5个"1", 因此其奇校验位为"0",同时把"110011100"传输给接收方,接收方收到数据后再- - 次计算奇偶性,"110011100"中仍然含有5个"1",因此接收方计算出的奇校验位仍是"0",与发送方一致,表示在这次传输过程当中未发生错误

例子:
MOV AL,OCE
ADDAL,0

四、AF(bit 4) [Adjust Flag]
若是算术操做在结果的第3位发生进位或借位则将该标志置1,不然清零。
这个标志在BCD(binary-code decimal)算术运算中被使用。

五、ZF(bit 6) [Zero flag]
若结果为0则将其置1,反之清零。
常常与CMP或者TEST等指令-起使用:

例1:判断2个值是否相等

MOV EAX, 100
MOV ECX, 100
CMP EAX, ECX
(CMP指令至关干SUB指令.可是相减的结果并不保存到第一个操做数中)

例2:判断某个值是否为0
TEST EAX,EAX
(TEST指令至关于AND指令,可是与的结果并不保存到第-一个操做数中)

六、SF(bit 7) [Sign flag]
该标志被设置为有符号整型的最高有效位。
(0指示结果为正,反之则为负)
例子:
MOV AL ,0x7F MOV AL ,0xFE
ADD AL,2 ADDAL,2

七、OF(bit 11) [Overflow flag]
溢出标志OF用于反映有符号数加减运算所得结果是否溢出。

能够这样理解:
若是是无符号数运算,是否溢出看CF位。
若是是有符号数运算,是否溢出看OF位。
例子:
MOV AL ,0x7F
ADD AL,2

八、DF(bit 10) [Direction Flag] 这个方向标志控制串指令(MOVS, CMPS, SCAS, LODS以及STOS)。设置DF 标志使得串指令自动递减(从高地址向低地址方向处理字符串),清除该标志则使 得串指令自动递增。 STD以及CLD指令分别用于设置以及清除DF标志。

相关文章
相关标签/搜索