学习资料来自滴水逆向,标题同理,若无内容则无必要笔记
0-汇编语言
1 课程概要
2 进制
3 数据宽度
字(Word)16位,2个字节
4 无符号数、有符号数
无符号数存储在计算机内就是其本身的值
5 原码、反码、补码
6 计算机不会做加法
not(~)shl(<<)shr/sar(>>)
7 位运算加减乘除
加法计算:异或,与并左移一位(重复)
8 汇编学习环境搭建
9 通用寄存器
计算机在CPU > 内存 > 硬盘存储数据
一个32位的CPU能提供8、16、32位的寄存器
通用寄存器的通用性指可以往里面存储任意数据和值
32位 | 16位 | 8位 |
---|---|---|
EAX | AX | AL、AH |
ECX | CX | CL、CH |
EDX | DX | DL、DH |
EBX | BX | BL、BH |
ESP | SP | |
EBP | BP | |
ESI | SI | |
EDI | DI |
AX、AL、AH分别表示EAX中的2个低位字节、1个低位字节和1个高位字节
10 内存
每个应用程序都会有自己的独立4GB内存空间
MOV DOWRD PTR DS:[内存地址], 立即数 MOV DOWRD PTR DS:[内存地址], 32位通用寄存器
存储的数据需要与DOWRD数据宽度一致
11 内存地址的5种形式
12 存储模式(大、小端)
绝大部分应用数据存储在x86上采用小端模式,在ARM上采用大端模式
13 常用汇编指令
r 代表通用寄存器,m 代表内存,imm 代表立即数,r8 代表8位通用寄存器,以此类推
13.8 MOVS指令
MOVS与MOV不同于可以将内存的数据传送到内存;使用MOVS指令时,默认使用的就是ESI和EDI寄存器;MOVS指令执行完成后ESI、EDI寄存器的值会自增或自减(取决于DF位和传送数据的数据宽);按照数据宽度简写为MOVSB,MOVSW,MOVSD
13.9 STOS指令
STOS将AL/AX/EAX的值储存到EDI指定的内存地址(与MOVS指令一样自增或自减);按照数据宽度简写为STOSB,STOSW,STOSD
13.10 REP指令
REP MOVS指令/STOS指令
循环执行MOVS指令或STOS指令,循次数取决于ECX寄存器中的值
13.11 堆栈相关指令
在DTDebug的内存窗口输入dd 7FFDF000即可看到堆栈的地址范围
ESP、EBP分别表示栈顶指针和栈底指针
14 修改EIP的指令
EIP不叫通用寄存器,它存放的值是CPU下次要执行的指令地址,当我们想去修改它的值时需要修改其特有的指令
14.2 CALL指令
表示跳转,跟JMP指令一样可以修改EIP的值,不同的是执行后会将其下一条指令地址压入堆栈,
ESP栈顶指针的值减4
14.3 RET指令
表示返回,将当前栈顶指针的值赋给EIP,然后让栈顶指针加4
15 汇编眼中的函数
16 堆栈传参
17 堆栈平衡
平衡堆栈有两种情况三个方法:1.使用完堆栈后,POP释放数据;2.外平栈:使用ADD指令;3.内平栈:使用RET指令
18 ESP寻址
MOV EAX, DWORD PTR SS:[ESP+4]
19 EBP寻址
先把EBP的值保存起来,然后将EBP指向ESP的位置,接着在原来的堆栈基础上将ESP上移,重新变成一块新的堆栈;之后新的程序再使用堆栈的时候,只影响ESP但不会影响EBP,那我们寻址的时候使用EBP去寻址,EBP的位置相对固定,程序不管如何操作ESP都会不停浮动,EBP相对稳定
20 标志寄存器
条件标志位
进位标志CF:运算结果的最高有效位有进位(加法)或者借位(减法)。用于表示两个无符号数高低
零标志ZF:如果运算结果位0,则ZF=1
溢出标志位OF:当将操作数作为有符号数的时候,使用该标志位判断运算结果是否溢出。加法时若相同符号数相加,结果的符号与之相反则OF=1,否则OF=0。减法时若被减数与减数符号不相同,而结果的符号与减数相同则OF=1,否则OF=0发生溢出,说明运算的结果已经不可信
标志符号SF:运算结果最高位为1,SF=1,否则SF=0。有符号数用最高有效位表示数据的符号,最高有效位是标志符号的状态
奇偶标志位PF:当运算结果(指的是低8位)中1的个数为偶数时,PF=1,否则PF=0。该标志位主要用于检测数据在传输过程中是否出错
辅助进位标志位AF:一个字节运算的时候低4位向高4位的进位和错位
如何操作标志寄存器
LAHF(Load AH with flags)指令:用于将标志寄存器的低八位送入AH,即将标志寄存器FLAGS中的SF、ZF、AF、PF、CF五个标志位分别传送到AH的对应位(八位中有三位是无效的)
SAHF(store AH into flags)指令:用于将AH寄存器送入标志寄存器
PUSHF(push the flags)指令:用于将标志寄存器送入栈 → push eflags
POPF(pop the flags)指令:用于将标志寄存器送出栈 → pop eflags