• PC逆向之代码还原技术,第四讲汇编中减法的代码还原


    PC逆向之代码还原技术,第四讲汇编中减法的代码还原

    一丶汇编简介

    在讲解减法的代码还原之前.我们首先要知道. 减法在汇编中对应的指令是什么.
    Sub 汇编指令. Sub x,y 将x的值 加上y 并且重新赋值给x

    二丶高级代码对应汇编观看.

    观看如下代码

    int main(int argc, char* argv[])
    {
    	int nValue = 10 - 2;  		//常量 - 常量 给变量
    	int nVar = nValue - 10; 	//变量 - 常量
    	int nVar3 = nValue - nVar;  //变量 - 变量
    	nVar3 = nValue - -5;    	//变量 - 负数常量
    
    	return 0;
    }
    

    有四种方式
    第一种 常量 - 常量
    第二种 变量 - 常量
    第三种 变量 - 变量
    第四种 变量 + 负数常量

    1.代码还原解析:

    代码还原解析需要了解的知识:

    reg: 代表任意通用寄存器
    imm: 立即数,可以看做常量
    ? : 代表任意数值.可以 [ebp -?]可以确定那个变量,变量是在栈中存放的.

    • 第一种方式 常量 - 常量
      常量-常量 在编译器编译的时候. 优化的时候直接就已经计算出来了. 所以常量- 常量就是固定的值了.
      如果给变量则会使用mov指令将常量赋值给变量.

    • 第二种方式 变量 -常量
      变量 - 常量 .我们首先要知道.变量在汇编的角度来说.就是在栈中内存存储的. 而栈 - imm(立即数)
      在湖边中没有这种指令
      例如:
      sub [ebp - ?],10
      所以只要操作变量必然会操作一个寄存器进行操作.
      所以会产生以下代码定式:

    mov reg,[ebp - ?]  获得变量值
    sub reg,imm        用寄存器相减
    mov [ebp - ?],reg  重新将寄存器的值赋值给某变量.
    
    • 第三种方式 变量 - 变量
      变量- 变量 我们通过第二种方式可以得知.操作变量的时候必然会使用寄存器.此时有两个变量.
      那么会不会操作两个寄存器?
      答: 不会操作两个寄存器. 汇编中支持 寄存器的值 跟 栈中内存的值 互相操作.

    产生的代码定式:

    mov reg,[ebp - 4]  获得第一个变量的值
    sub reg,[ebp - 8]  reg - 第二个变量的值. 结果给reg存储
    mov [ebp - c[,reg  将结果利用mov赋值指令赋值给变量三.
    
    • 第四种方式 变量 - 负数
      首先操作了变量.那么肯定会操作寄存器. 而 - 负数 在数学中 负负得正. 所以负数在汇编中会被加上
      所以产生代码定式:
    mov reg,[ebp - 4];
    add reg,|负数|        |负数|  这个代表负数的绝对值
    mov [ebp - 8], reg
    

    三丶根据高级代码IDA反汇编的完整代码

    
    .text:00401250 _main_0         proc near               ; CODE XREF: _main↑j
    .text:00401250
    .text:00401250 var_4C          = byte ptr -4Ch
    .text:00401250 var_C           = dword ptr -0Ch
    .text:00401250 var_8           = dword ptr -8
    .text:00401250 var_4           = dword ptr -4
    .text:00401250
    .text:00401250                 push    ebp                     保存栈低
    .text:00401251                 mov     ebp, esp                指向新栈
    .text:00401253                 sub     esp, 4Ch                开辟局部变量空间
    .text:00401256                 push    ebx
    .text:00401257                 push    esi
    .text:00401258                 push    edi                     保存寄存器环境
    .text:00401259                 lea     edi, [ebp+var_4C]       获得局部变量空间首地址
    .text:0040125C                 mov     ecx, 13h
    .text:00401261                 mov     eax, 0CCCCCCCCh
    .text:00401266                 rep stosd                       利用rep 加串操作指令 stosd 按照4个字节.从 eax中取出cc值. 存放到 edi中. 循环次数 ecx控制.
    
    
    .text:00401268                 mov     [ebp+var_4], 8          常量赋值给变量
    
    .text:0040126F                 mov     eax, [ebp+var_4]
    .text:00401272                 sub     eax, 0Ah              var_8 = var_4 - 0xA 
    .text:00401275                 mov     [ebp+var_8], eax
    
    .text:00401278                 mov     ecx, [ebp+var_4]
    .text:0040127B                 sub     ecx, [ebp+var_8]
    .text:0040127E                 mov     [ebp+var_C], ecx      var_c = var4 - var_8;
    
    .text:00401281                 mov     edx, [ebp+var_4]
    .text:00401284                 add     edx, 5                var_c = var_4 + 5;   上方是 var_4  - -5 ,因为负负得正.所以汇编中使用加法了.
    .text:00401287                 mov     [ebp+var_C], edx
    
    .text:0040128A                 xor     eax, eax
    .text:0040128C                 pop     edi
    .text:0040128D                 pop     esi
    .text:0040128E                 pop     ebx
    .text:0040128F                 mov     esp, ebp
    .text:00401291                 pop     ebp
    .text:00401292                 retn
    .text:00401292 _main_0         endp
    

    可以根据自己需求,将上面的代码进行还原. 当然还原出的高级代码可能跟我写的高级代码不一样.这是正常的.
    但是如果还原正确.那么在IDA中.二进制十一摸一样的. 也就是汇编. 此时就算还原正确.

    四丶知识总结

    总体来讲. 如果是常量进行操作.则在编译期间直接运算完毕了. 如果操作变量则会操作通用寄存器.
    使用通用寄存器进行计算.
    最重要的一点: 计算机不会做加法.所以 我们的做减法运算的时候. 其实是按照补码存放的. 使用补码去操作的.
    例如:
    11 - 3 我们可以看做 11 + 3(补码)

    可以参考本人编写的详细博客: 博客链接

  • 相关阅读:
    JVM工作原理--垃圾收集
    并发编程之单例模式
    设计模式之动态代理
    UML类图基础
    CAP理论的理解
    Dubbo RPC调用参数校验---错误message自动返回
    ELK日志分析系统搭建
    Kafka原理及应用(一)
    HTTPS的原理
    Maven 生命周期的概念(指令默认顺序执行)
  • 原文地址:https://www.cnblogs.com/iBinary/p/9966486.html
Copyright © 2020-2023  润新知