C++ 逆向辅助学习----汇编基础 OD调试教程 快捷键 8

61 篇文章 2 订阅
17 篇文章 2 订阅

WIN32汇编与反汇编
环境:VS2010 + WIN7 64
       
一、全局变量赋值的汇编形式       
    1.OllyDbg简介
       是汇编级的调试器,我们用的VS是源码级的。
 
       反汇编窗口:显示被调试程序的反汇编代码(地址栏、HEX数据栏、汇编指令栏、注释栏)
       寄存器窗口:显示当前所选线程的CPU寄存器的内容
       信息窗口:  显示反汇编窗口中选中的第一个命令的参数及一些跳转目标地址、字符串等
       数据窗口:  显示内存或文件的内容。
       堆栈窗口:  显示当前线程的堆栈
       
    2.调试方式   
       方式1:用OD调试器直接打开
       方式2:附加到已经打开进程
       
    3. 定位地址
        Ctrl + G 输入WIN32 API函数名(如:MessageBoxW,MessageBoxA)    
       
    4. 断点
        方式1:直接在选中的行上按下 F2这样就在当前指令所在地址下一个断点    
        方式2:bp  指令地址(如果地址是一条指令的中间,那么会出错)
       
    5.PDB文件
        全称为"程序数据库"文件。存储了被编译文件的调试信息,大多数场景是调试应用程序
        OllyDbg调试器可以读取.pdb文件        
       
    6.调试中我们经常要用到的快捷键:
       F2:设置断点
       F8: 单步步过
       F7: 单步步入
       F4: 运行到选定位置
       F9: 运行
       CTRL + F9 执行到返回
       ALT  + F9 执行到用户代码       
       
    7.C++代码内嵌汇编
         内嵌汇编: __asm mov aaa,0x778899    
       
       
       
二、函数调用的反汇编形式       
    1、函数与CALL(OD分析代码将函数(子程序)分块)   
         C/C++函数调用翻译成汇编相当于call(子程序调用)
       
       
    2、关闭C/C++优化   
         项目属性配置 -> C/C++ ->优化 -> 禁用/Od
       
       int add (int a, int b)
       {
         return a+b;
       }
       优化的:
       0134100E      C705 18303401 3300000 mov     dword ptr [aaa], 33

       未被优化的:
       01271021  |.  6A 22                 push    22                                      ; /b = 34.
       01271023  |.  6A 11                 push    11                                      ; |a = 17.
       01271025  |.  E8 D6FFFFFF           call    add                                     ; \add

          
       add函数
        00381000  /$  55                    push    ebp                                    
        00381001  |.  8BEC                  mov     ebp, esp
        00381003  |.  8B45 08               mov     eax, dword ptr [a]
        00381006  |.  0345 0C               add     eax, dword ptr [b]
        00381009  |.  5D                    pop     ebp
        0038100A  \.  C3                    ret

    3、单步步入:(进入call)   
       F7(单步步入):按下后执行下一条指令。如果有call则进入call执行
       
    4、单步步过:(不进入call)
       F8(单步步过):按下后执行下一条指令。不会进入子函数call里面,
       子函数call也被当成一条指令执行       
       
       
三、加法预算反汇编       
       分析见代码
012D1012  |.  C745 FC 00000000      mov     dword ptr [local.1], 0                  ; int i = 0;
012D1019  |.  8B45 FC               mov     eax, dword ptr [local.1]                ; eax=i=0
012D101C  |.  83C0 64               add     eax, 64                                 ; eax=eax+100=0+100=100=0x64
012D101F  |.  8945 FC               mov     dword ptr [local.1], eax                ; i=eax=100=0x64
012D1022  |.  8B4D FC               mov     ecx, dword ptr [local.1]                ; ecx=i=100=0x64
012D1025  |.  81C1 22020000         add     ecx, 222                                ; ecx=ecx+0x222=0x64+0x222=0x286
012D102B  |.  894D FC               mov     dword ptr [local.1], ecx                ; i=ecx=0x286


四、进制与内存单元长度修饰
       add [ebx],0x333       01251046  |.  8003 33               add     byte ptr [ebx], 33  
       
    1.十六进制   
       十六进制同我们日常的十进制表示法不一样。它由0-9,A-F组成。
       与十进制的对应关系是:0-9对应0-9; A-F对应10-15   
       
       十进制元素(0,1,2,3,4,5,6,7,8,9)
       十六进制元素(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)
       
       9 + 1 = 10;   //十进制
       F + 1 = 10;   //十六进制
       99 + 1 = 100; //十进制 0x64
       FF + 1 = 100; //十六进制 1*16^2 + 0*16^1 + 0*16^0 = 256  //0xBDA = 11*16^2 + 13*16 + 10*16^0
       
       十六进制一般会加上前缀0x,汇编中也可以加上h后缀  
    
     2、字节,字,双字
        字节   (1字节): BYTE类型    (unsigned char)  0-255         表示成十六进制0-0xFF
        字     (2字节): WORD类型  (unsigned short) 0-65535       表示成十六进制0-0xFFFF
        双字    (4字节) : DWORD类型 (unsigned int)  0-4294967295  表示成十六进制0-0xFFFFFFFF
       
五、32位通用寄存器
     EAX AX AH AL       
     32  16 8  8  
       
     同样的还有:
     EBX BX BH BL    
     ECX CX CH CL    
     EDX DX DH DL        
    
     OD命令行看内存:  dd (data dword)  dw(data word) db(data byte)    
     OD命令行看寄存器:? eax / ? ax  / ? al   
       
六、MOVSX和MOVZX
     MOVSX    符号扩展传送
     MOVZX    零扩展传送    
       
    1、MOVSX与MOVZX  
        MOVSX  操作数A,操作数B
        MOVZX  操作数A,操作数B

       相同点:操作数B所在空间必须小于操作数A        
       
       (1)格式与MOV基本相同
       (2)能完成小存储单元向大的存储单元的数据传送
            比如:movsx eax,bx  movzx ebx,ax    movsx eax,bx
            
    2.MOVSX,MOVZX与MOV指令区别:
       (1)MOVSX,MOVZX的操作数B所占空间必须小于操作数A
       (2)MOV指令是原值传送,不会改动。而MOVSX和MOVZX有可能会改动

    3.MOVSX与MOVZX区别:
       (1)MOVSX将用操作数B的符号位扩展填充操作数A的余下空间:
          - 如果是负数则符号位为1
          - 如果是正数则符号位为0,和MOVZX功能相同
          
       (2)MOVZX将用0来扩展填充操作数A的余下空间
           操作数A   —— —— —— ——
           操作数B   0  0  —— ——           
    
    4.十六进制的正数负数
       BYTE(char)   0 - 0xFF         0xFF/2=7F              大于0x7F为负数                    
       WORD(short)  0 - 0xFFFF       0xFFFF/2=7FFF          大于0x7FFF为负数  
       DOWRD(int)   0 - 0xFFFFFFFF  0xFFFFFFFF/2=7FFFFFFF   大于0x7FFFFFFF为负数
       
               
七、LEA指令
    1.LEA指令格式
       有效的地址传送指令LEA    
       格式:LEA   操作数A , 操作数B
       功能:将操作数B的有效地址传送到指定的某个寄存器,操作数A必须是寄存器
             (32位系统上就是32位寄存器)


八、OD使用小结
    1.OD调试
      重新开始:Ctrl + F2
      转到地址:Ctrl + G
      断点切换: F2
      断点窗口:Alt + B
      运行:    F9
      暂停:    F12
      单步步过: F8遇到call跳过
      单步步入: F7遇到call进入
      运行到选定位置:F4
      反汇编窗口中跟随: 回车键enter
      跟随:回车键enter 进入某个地址
      
    2.右键菜单 - goto
      +号:转到下一步
      -号:转到上一步
      *号:转到当前指令地址

    3.命令栏指令
       bp  下断点
       bc  清除断点
       dd 以双字方式显示数据
       dw 以字方式显示数据
       db 以字节方式显示数据
       dc 以字符方式显示数据     
       ? 计算表达式的值
    
    4.OD修改汇编代码
      选中汇编指令,按下空格后 直接输入汇编代码    

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值