汇编笔记【滴水逆向】
第一课(课程概要)
1.高级语言—(高级语言编译器)—>汇编语言—(汇编语言编译器)—>机器语言
2.不是语言变得强大了,而是编译器变得强大了
3.c和c++的关系:对于c++来讲,编译器替我们做的事情更多了;学习C语言是学好c++的基础
4.程序员的鄙视链
5.学习汇编可以了解程序的本质,而不是用汇编去编程
第二课(进制的概念)
1.为什么要学习进制:计算机只认识二进制,也就是0和1,为了更好地学习计算机,我们首先要深入理解什么是进制
2.学习进制的障碍:总是以十进制为依托去考虑其他进制,需要运算时也总是先转换成十进制(仅仅是因为我们对十进制熟悉,所以才转换);每一种进制都是完美的,想学好进制首先要忘掉十进制
3.N进制的定义:由N个符号组成(通常是[0,N-1]),逢N进1
4.进制的书写方法:“查数”
5.进制的本质(可以用于加密)
第三课(进制运算)
1.八进制运算:
2+3=5
2*3=6
4+5=11
4*5=24
277+333=632
276*54=20250
八进制加法表:
八进制乘法表:
第四课(二进制简写形式)
1.进制总结:每种进制都是完美的,它自身就是一个完整的体系,可以直接做运算
2.计算机为什么使用二进制:计算机时需要电的,电路只有两种状态:1真(通电) 0假(未通电)
3.计算机中存储的任何文件、接收的指令都是由0和1组成的,例如我们可以查看一个【*.exe应用程序】:
4.16进制是二进制的简写形式:
第五课(数据宽度)
1. 1双字(DoubleWord)=2字(Word)=4字节(Byte)=32位(bit)
2.存储范围:
字节:0--0xFF
字:0--0xFFFF
双字:0--0xFFFFFFFF
如果要存储的数据超过最大宽度,那么多余的数据将被丢弃(高位丢弃)
第六课(无符号数和有符号数)
1.无符号数:不存在负数,直接二进制转十进制
2.有符号数:正数和无符号数编码规则一样,负数以补码的形式在计算机中存储
3.编码规则:不同的文件有不同的编码规则:例如给你一串二进制数,你首先要问这一串二进制数存储的是什么(数字、文本、图像、音频、视频、还是应用程序?),如果是数字,再问是有符号还是无符号
第七课(原码反码和补码)
1.原码:最高位为符号位,其余各位为其数值本身的绝对值
2.反码:正数:反码与原码相同;负数:符号位为1,其余位对原码取反
3.补码:正数:反码与原码相同;负数:符号位为1,其余位对原码取反加1
4.“以什么方式去显示”
#include<stdio.h>
int main()
{
unsigned char x = 0x9A;
char y = 0x9A; //%u的输出格式是unsigned int,所以9A会扩展成FFFFFF9A
unsigned int z = 0xFFFFFF9A;
printf("%u\n%u\n%u\n", x, y, z);
return 0;
}
D:\software\DESKTOP\TEST\cmake-build-debug\test.exe
154
4294967194
4294967194
Process finished with exit code 0
5.编码规则
6.“砍一半”
第八课(位运算)
1.逻辑运算:
【与(and)】{1+1=1}
【或(or)】{1+0=1}
【非(not)】{~1=0}
【异或(xor)】{“两数不相同时”为1,“相同时”为0}
2.左移运算[shl]
3.右移[A:shr(>>)或B:sar(>>)]:各二进制位全部右移若干位,低位丢弃,高位A:(补零【逻辑右移】)或B:(补符号位【算术右移】)
第九课(计算机如何做运算)
1.计算机如何做加法:位运算(异或+与)
2.计算机如何做减法:减数以补码方式参与运算,变为加法
3.计算机如何做乘法:乘法的本质是加法
4.计算机如何做除法:除法的本质是减法
第十课(汇编环境搭建)
1.学汇编不是为了写代码,而是为了理解程序的本质
2.利用工具:OllyDbg或x64dbg
第十一、二课(通用寄存器)
1.存读数据速度:CPU>内存>硬盘
2.32位通用寄存器:EAX、EBX、ECX、EDX、ESP、EBP、ESI、EDI
3. ESP、EBP、EDI、ESI没有8位的
第十三、四课(内存)
PTR DS:[立即数]
PTR DS:[reg]
PTR DS:[立即数+reg]
PTR DS:[reg+reg*{1,2,4,8}]
PTR DS:[reg+reg*{1,2,4,8}+立即数]
第十五课(数据的存储模式)
第十六课(常用汇编指令)
EFL:标志寄存器:其中第十位(DF)为0时,ESI和EDI运算完成后加1/2/4;第十位(DF)为1时,ESI和EDI运算完成后减1/2/4;
第十七课(堆栈相关汇编指令)
1.什么是堆栈:就是一块内存,操作系统在程序启动的时候已经分配好的,供程序执行时使用;和数据结构中的堆栈无关
3.ESP:栈顶指针寄存器
第十八课(修改EIP)
2.RET指令:栈顶指针加4,把原来栈顶指针中的值取出来放到EIP中
第十九课(拓展篇:反调试之Fake8)
1.单步步入(F7)和单步步过(F8)
2.本质:修改ESP的值
第二十、二十一课(汇编中的函数)
1.函数就是一系列指令的集合,为了完成某个会重复使用的特定功能
2.如何执行一个函数:JMP 或 CALL
3.一般来讲,返回值存到EAX中
第二十二课(堆栈平衡)
2.如果通过堆栈传递参数了,那么在函数执行完毕后,要平衡参数变化导致的堆栈变化
3.内平栈(RETN XXX)和外平栈(add esp,XXX)
第二十三课(外挂的本质)
#include<stdio.h>
#include<windows.h>
void attack()
{
printf("attack\n");
}
int main()
{
getchar();
while (1)
{
attack();
Sleep(1000);
}
return 0;
}
//所谓外挂:修改Sleep()函数中的数值
第二十四课(ESP寻址)
1.使用寄存器传递参数
2.使用堆栈来传递参数
3.ESP寻址的缺点:程序执行过程中有通用寄存器或中间数据需要被压入栈中,ESP总是在变化
第二十五课(EBP寻址)
第二十六课(JCC指令)
标志寄存器:CF(无符号数是否溢出或借位)、PF(最低有效字节包含1的个数是偶数还是奇数)、ZF(运算结果是否为0)、SF(运算结果是正还是负)、OF(有符号数是否溢出或借位)、DF(方向)
1.LAHF(Load AH with flags)指令:LAHF(加载状态标志位到 AH)指令将 EFLAGS 寄存器的低字节复制到 AH。被复制的标志位包括:符号标志位、零标志位、辅助进位标志位、奇偶标志位和进位标志位。
2.SAHF(store AH into flags)指令:用于将 AH 寄存器中的值存储回标志寄存器中。这允许程序在 AH 寄存器中设置标志位的值,然后使用 SAHF 指令将这些值还原到标志寄存器,从而影响后续的条件分支和控制流操作。
3.PUSHF(push the flags)指令:PUSHF 指令用于将标志寄存器的值压入堆栈中。
4.POPF(pop the flags)指令:POPF 指令用于从堆栈中弹出标志寄存器的值,并将这些值加载到标志寄存器中。
因篇幅问题不能全部显示,请点此查看更多更全内容