本帖最后由 kay2kay 于 2021-03-14 15:36 编辑
本文为本人的滴水逆向破解脱壳学习笔记之一,为本人对以往所学的回顾和总结,可能会有谬误之处,欢迎大家指出。 陆续将不断有笔记放出,希望能对想要入门的萌新有所帮助,一起进步 所有笔记链接:
大神论坛 逆向脱壳分析基础学习笔记一 进制篇 大神论坛 逆向脱壳分析基础学习笔记二 数据宽度和逻辑运算 大神论坛 逆向脱壳分析基础学习笔记三 通用寄存器和内存读写 大神论坛 逆向脱壳分析基础学习笔记四 堆栈篇 大神论坛 逆向脱壳分析基础学习笔记五 标志寄存器 大神论坛 逆向脱壳分析基础学习笔记六 汇编跳转和比较指令 大神论坛 逆向脱壳分析基础学习笔记七 堆栈图(重点)(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记八 反汇编分析C语言 大神论坛 逆向脱壳分析基础学习笔记九 C语言内联汇编和调用协定 大神论坛 逆向脱壳分析基础学习笔记十 汇编寻找C程序入口(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十一 汇编C语言基本类型 大神论坛 逆向脱壳分析基础学习笔记十二 汇编 全局和局部 变量(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十三 汇编C语言类型转换(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十四 汇编嵌套if else(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十五 汇编比较三种循环(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十六 汇编一维数组(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十七 汇编二维数组 位移 乘法(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十八 汇编 结构体和内存对齐(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记十九 汇编switch比较if else(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记二十 汇编 指针(一)(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记二十一 汇编 指针(二)(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记二十二 汇编 指针(三)(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记二十三 汇编 指针(四)(需登录才能访问) 大神论坛 逆向脱壳分析基础学习笔记二十四 汇编 指针(五) 系列完结(需登录才能访问) 更多逆向脱壳资源,请访问 大神论坛EFLAGS寄存器进位标志CF(Carry Flag)如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0 例子: MOV AL,0xFF
ADD AL,1
0x80+0x40 加黑的为最高位 0x80:0 1000 0000 0x40:0 0100 0000 结果为1100 0000 最高位并没有发生变化,于是CF位为0 0x80-0x40注意这里借位的位是1000 0000中的加黑部分 而非0 1000 0000这里的最高位 结果为0100 0000 最高位并没有发生变化,于是CF位为0 0x80-0x810x80:1000 0000 0x81:1000 0001 结果为1111 1111= -1,最高位被借位,于是CF位为1 奇偶标志PF(Parity Flag)奇偶标志PF用于反映运算结果中最低有效字节中“1”的个数的奇偶性 如果“1”的个数为偶数,则PF的值为1,否则其值为0。 指令 | 指令执行后AL的结果 | PF |
---|
MOV AL,3 | 0011 | 1 | ADD AL,3 | 0110 | 1 | ADD AL,2 | 1000 | 0 |
例: MOV AX,803 ADD AX,1
0x803: 0000 1000 0000 0011 执行结果 0x804: 0000 1000 0000 0100 总共2个1 ,PF应为1,但实际运行结果PF为0 因为PF是根据最低有效字节来看,即804后面04的这部分 04: 0000 0100 总共1个1,所以PF为0 辅助进位标志AF(Auxiliary Carry Flag)在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0: - 在字操作时,发生低字节向高字节进位或借位时
- 在字节操作时,发生低4位向高4位进位或借位时
AF与数据宽度相关 32位时 FFFF F FFF 16位时 FF F F 8位时 F F 加黑的字体为AF标志位判断的位置,如果该位置要向前进位则AF为1,否则为0,和CF相似,不过判断的位置不同 32位例: MOV EAX,55EEFFFF
ADD EAX,2
16位例: MOV AX,5EFE
ADD AX,2
8位例: MOV AL,4E
ADD AL,2
零标志ZF(Zero Flag)零标志ZF用来反映运算结果是否为0 如果运算结果为0,则其值为1,否则其值为0 作用:在判断运算结果是否为0时,可使用此标志位 例子: XOR EAX,EAX
通过xor将eax清零,会改变zf标志位为1 MOV EAX,0
通过MOV将EAX赋值为0,非运算,不改变zf标志位 符号标志SF(Sign Flag)符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同 例子: MOV AL,7F ADD AL,2
溢出标志OF(Overflow Flag)溢出标志OF用于反映有符号数加减运算所得结果是否溢出 注意与CF区分!!! 最高位进位与溢出的区别: 进位标志表示无符号数运算结果是否超出范围. 溢出标志表示有符号数运算结果是否超出范围. 溢出主要是给有符号运算使用的,在有符号的运算中,有如下的规律: - 正 + 正 = 正 如果结果是负数,则说明有溢出
- 负 + 负 = 负 如果结果是正数,则说明有溢出
- 正 + 负 永远都不会有溢出
无符号、有符号都不溢出例MOV AL,8 ADD AL,8
AL的数据宽度为8,即 无符号数范围为0~FF即0~255 8+8=16在0~255内 不溢出 有符号数的范围为 正数:0~7F 即0~127 负数:80~FF 即 -128~0 8+8=16 在0~127内 两正数相加结果仍为正数,不溢出 无符号溢出、有符号不溢出例MOV AL,0FF ADD AL,2
无符号数时 FF+2=255+2=257 在0~255外,溢出 有符号数时 FF+2=-1+2=1 正 + 负 永远都不会有溢出 无符号不溢出、有符号溢出例MOV AL,7F ADD AL,2
无符号数时 7F+2=127+2=129 在0~255内 不溢出 有符号数时 7F+2=0x81在80~FF (负数范围)内,两正数相加结果为负数,溢出 无符号、有符号都溢出MOV AL,0FE ADD AL,80
无符号数时 FE+2=254+2=256=0x100 在0~255外 溢出 有符号数时 FE+2=0x100在0~FF外,溢出 CPU如何计算OF位首先引入两个概念: 对于一个有符号数:如0x80和0xC0 符号位有进位 0x80:1 000 0000 0xC0:1 100 0000 最高有效数值位向符号位产生的进位 0x80:1 0 00 0000 0xC0:1 1 00 0000 接下来看一组汇编指令 MOV AL,80 ADD AL,0C0
就是运算0x80+0xc0 0x80:1 0 00 0000 0xC0:1 1 00 0000 符号位1+1有产生进位,于是符号位有进位为1 最高有效数值位向符号位产生的进位0+1没有产生进位,于是最高有效数值位向符号位产生的进位为0 OF = 符号位有进位 xor 最高有效数值位向符号位产生的进位 OF = 1 xor 0 = 1 所以此时OF=1 方向标志DF(Direction Flag)DF:方向标志位 DF=1时串操作为减地址方式 DF=0为增地址方式 下面的MOVS指令有说明DF的具体应用 相关汇编指令符号 | 含义 |
---|
r | 寄存器 | m | 内存 | imm | 立即数 | r8 | 8位通用寄存器 | m8 | 8位内存 | imm8 | 8位立即数 |
ADC指令:带进位加法格式:ADC R/M,R/M/IMM 两边不能同时为内存 数据宽度要一样 例: MOV AL,1 MOV CL,2 手动修改CF为1 ADC AL,CL
计算结果为4,原本1+2=3,但是现在变成了4,注意与ADD的区别就在于进位 SBB指令:带借位减法格式:SBB R/M,R/M/IMM 两边不能同时为内存 数据宽度要一样 MOV AL,4 MOV CL,2 手动修改CF为1 SBB AL,CL
计算结果为1,原本4-2=2,但是现在变成了1,注意与SUB的区别就在于进位 XCHG指令:交换数据格式:XCHG R/M,R/M 两边不能同时为内存 数据宽度要一样 XCHG AL,CL XCHG DWORD PTR DS:[12FFC4],EAX XCHG BYTE PTR DS:[12FFC4],AL
例: MOV AL,1 MOV CL,2 XCHG AL,CL
执行前:AL=1 CL=2 执行后:AL=2 CL=1 MOVS指令:移动数据 内存-内存BYTE/WORD/DWORD MOVS指令常用于复制字符串 MOVS BYTE PTR ES:[EDI],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内存里的值被修改为ESI内存里的值,且EDI和ESI各加4 为什么各加4? 和DOWRD数据宽度相关,如果为WORD 则各加2 为什么执行完是加而不是减? 由DF(Direction Flag)方向标志位决定,当DF位为1时为减,当DF位为0时,则为加 STOS指令将Al/AX/EAX的值存储到[EDI]指定的内存单元,和数据宽度相关 STOS BYTE PTR ES:[EDI] 将AL存储到[EDI] STOS WORD PTR ES:[EDI] 将AX存储到[EDI] STOS DWORD PTR ES:[EDI] 将EAX存储到[EDI]
注意这里使用的是ES: 之前写的都是DS: 当后面为[EDI]时要使用ES: 这和后面要学的段寄存器有关,先记住 存储完数据后EDI地址的变化方向也受DF标志控制,1减0增 REP指令按计数寄存器 (ECX) 中指定的次数重复执行指令 MOV ECX,10 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 也可以写成REP MOVSD
这里的10为十六进制,也就是0x10=16 代码将会重复执行16次,会不会往同一个地方覆盖? 不会,因为每执行一次EDI和ESI都会变化4,变化方向由DF决定
版权声明:本文由 lyl610abc 原创,欢迎分享本文,转载请保留出处
|