技术分享图片
人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

技巧“c”

一、逻辑运算符

  1、或运算(c语言中的  ||  ) 

    条件真和假 : 

       非零为真,零为假

    ++为+(假假为假)

    截断原理  if(a || b) 判断前面是否为真,把认为可能行大的放在最前面

    c = i || j;

    if (c) {}

    以汇编指令去看

    /*

009E1014 |. C745 FC 330>mov [local.1],0x33
009E101B |. C745 F4 660>mov [local.3],0x66
009E1022 |. 837D FC 00 cmp [local.1],0x0
009E1026 |. 75 0F jnz short 汇编.009E1037    // jnz 不为0 跳转  因 local-1  与  0 比较 不为0 跳转 ,所以导致第二个参数不用判断,效率快

009E1028 |. 837D F4 00 cmp [local.3],0x0       // 如果为0不跳转, 则继续与第二个参数比较  (假假为假)

009E102C |. 75 09 jnz short 汇编.009E1037
009E102E |. C745 F0 000>mov [local.4],0x0
009E1035 |. EB 07 jmp short 汇编.009E103E
009E1037 |> C745 F0 010>mov [local.4],0x1
009E103E |> 8B45 F0 mov eax,[local.4] ; 汇编.envpcurity_cookie_complement
009E1041 |. 8945 F8 mov [local.2],eax
009E1044 |. 8BC0 mov eax,eax

     */

  

  2、按位或(c语言中的 |)  

      0x33 ==>>   00 11 00 11

    | 0x66         + 01 10 01 10

       =  0x77 ==>  = 01  11 01 11   (假假为假) 

    /*

009E1046 |. 8B4D FC mov ecx,[local.1] ; msvcr100.72AD266D
009E1049 |. 0B4D F4 or ecx,[local.3]
009E104C |. 894D F8 mov [local.2],ecx ; msvcr100.__initenv

    */

    汇编是使用 or 指令 

   3、与运算

    ==>>逻辑与(c语言中的 && )

        真真为真

      c = a && b    //  自己的代码  a 认为 是假 放在前面   。判断前面是否为假,把认为可能行大的放在最前面

      if ( c ){}

      截断原理

    ==>>按位与 (c语言中的 &)

      0x33 ==>>    00 11 00 11

    & 0x66         + 01 10 01 10

       =  0x22 ==>   =  00 10 0010  (真真为真) 

    /*

  4、非运算

    (1)逻辑取反(c语言中的 ! )

       假变真, 真变假

      sete(setz)       取ZF标志位的值保存

      setne(setnz)   将ZF标志位的值取反保存

      (2)  按位取反(c语言中的 ~ )

        

    c语言代码中的汇编指令

      #include <cstdio>
      int main(){
      printf("fsadfasd");
      int i, j;
      i = 0x7787;
      j =  !i ; // 0

      /*

      

      */

      __asm mov eax, eax
      j = ~i;

          

 

 

 


      return 0;

      }

       NOT 指令

 

   5、异或运算

     (1)按位异或(c语言中的^)

      1^1 = 0 , 0^0 = 0  ,相同为0

      0^1 = 1 , 1^0 = 1  ,   不同为1

      eg :   1101

          ^ 0110

         = 1011  

      

 

 

 

      经典练习题:

        (1)不借助第三个变量,将两个数交换(数值大的数会有问题,溢出)

            int a = 5, b = 7;

            a = a+b;   // a = 12

            b = a - b;  // b = 12 - 7 = 5

            a = a - b;  // a = 12 - 5 = 7

        (2)用异或计算高效

          

 

    逻辑运算指令总结:

       (1) or :  按位或运算,假假为假(有1为1,全0为0)

          如:101100

           |   110101

           =  111101

       (2)  and : 按位与运算,真真为真(有0为0,全1为1)

          如: 101100

           &   110101

           =   100100

       (3) Not: 取反运算

          如:not  1011

              =   0100

        (4)  xor : 异或运算(相同为0,不同为1)

          如 :   101100

            ^  110101

            =  011001

                  

二、字符操作相关指令

  1、字符串的比较函数 strcmp 反汇编分析:

  2、REPNE和SCASB指令

    (1)SCASB指令:

      SCASB编译后:

        SCASB  BTYP PTR ES:[EDI]  char   s1[0]   byte 1  

        //// SCASW WORD PTR [EDI]      short  s1[0]  word  2

        //// SCASD  DWORD PTR [EDI]   int      s1[0]   dword 4

      相当于

        cmp byte prt [edi], al

       对标志位的影响相当于SUB指令,同时还会修改寄存器EDI的值

        如果标志位DF为0, 则  inc  EDI

        否则,dec EDI

      

    (2)REPNE指令(连续执行)

        repnz scasb 编译后 :repne scas bype ptr es:[edi]

        当ecx != 0 并且 ZF = 0 时,重复执行后边的指令 scas bype ptr es:[edi]

        每执行一  次EDI的值加1,ECX的值减1

        

         //   此汇编代码 是 获取字符的长度  (主要是实现逻辑思想)

        repne 和 repnz 是同一条指令的不同助记符

  3、REPE/REPZ和CMPSB, CMPSW, CMPSD指令

    (1)CMPS

        cmps byte ptr [edi] , byte ptr [esi]

        cmps word ptr [edi] , byte ptr [esi]

        cmps dword ptr [edi] , byte ptr [esi]

        对标志位的影响相当于sub指令, 同时还会修改寄存器EDI和ESI的值

          如果标志DF为0, 则EDI, ESI按相对于大小(byte, word, dword) 递增

          如果标志DF为1, 则EDI, ESI按相对于大小(byte word dword) 递减

    (2)REPE/REPZ

        repe/repz cmpsb 当ecx!=0并且zf = 1时, 重复执行后面的指令

        每执行一次ecx的值减1

    (3)实例运用

        比较串是否相等

        

      (4)汇编编写字符串比较函数

         (1)asm_strcmp 函数

            _declspec(naked)  告诉编译器用纯汇编方式编译函数, 不自动添加

                      寄存器保护和堆栈平衡代码

         (2)STD/CLD指令(DF方向标志位相关)

            std   df = 1

            cld   df =  0

 三、串存储和串的加载指令

    (1)串存储指令STOSB、STOSW、STOSD

        STOSB  STOS BYTE PTR [EDI]

        STOSW  STOS WORD PTR [EDI]

        STOSD  STOS  DWORD PTR [EDI]

        相当于:

          mov byte    ptr [edi], al

          mov word   ptr [edi], ax

          mov dword ptr [edi], eax

          rep stosb    rep stos byte ptr [edi]

          用al 的值 填充byte ptr [edi],每次ecx值减1,edi加1

     定位main()函数位置的步骤:

      第一步:打开程序, 程序启动后停在这里,直接jmp跳转

      第二步:jmp跳转跟随之后, 找到call  dword ptr [<xxxxx.exit>]退出的代码的位置

      第三步:call dword ptr [<xxxxx.exit >] 前一个call就是main函数。

    (2) 串载入指令LODSB, LODSW,LODSD

      lodsb lods byte ptr [esi]

      lodsw lods woedptr [esi]

      lodsd lods dword ptr [esi]

      

     rep lodsb ==>> rep lods byte ptr [esi]

     用byte ptr [esi]  的值, 填充al, 每次ecx值减1 , esi的值加1

 

逆向实战练习

  一、游戏的call 

    1、调用MessageBoxA函数call示例

    2、分析MessageBoxA call 地址

    3、注入代码测试调用MessageBoxA call

  二、窗口菜单类CALL分析

    (1)windows菜单基本知识:菜单被点击的时候发送的是WM_COMMAND消息

    窗口出来函数:
      LRESULT CALLBACK WindowProc(
        __in HWND hwnd,

        __in UINT uMsg,

        __in WPARAM wParam,

        __in LPARAM lParam
      );

     当点击菜单的时候, windowsproc 会被系统调用

      uMsg     赋值为:WM_COMMAND

      wParam      赋值为:对应的菜单的ID(我们分析的数据就是这个)

    (2)用OD打开扫雷游戏程序, 定位到窗口处理函数地址

    (3)在扫雷游戏 Windowsproc函数处下条件断点

        条件是:uMsg  == WM_COMMAND

        如:edx == WM-COMMAND 的条件断点(S+F2)

    (4)分析出各项菜单被点击时, windowsproc 的4个参数的值

      如:wParam(菜单ID)参数

        初级菜单ID

        中级菜单ID

        高级菜单ID

     (5)注入代码调试

    

三、分析游戏基地址

  (1)基地址的概念

      全局变量、字符常量等的地址

  (2)查找和验证基地址

      1、使用CE内存查找工具查找数据地址

        1)首次先让要查找的数据稳定在某个范围(或者某个精确的值)

          使用CE的首次搜索功能

        2)改变要查找的数据,根据变化在选择出数据的地址

      2、在OD中验证是否就是基地址

        通过下内存断点的方式来验证

        add dword ptr [1005194],eax  这种立即数寻址基本就是基地址

      

 四、游戏菜单点击和读取基地址

 五、扫雷游戏的辅助编写

  1、雷区数据分析

    char a[24][32]   0 1 2 3 4  X X X   // ReadProcessMemory

    雷区数据基地址  0x1005361 0x8f

    雷区   宽基地址  0x1005334  

    雷区   高基地址  0x1005338

   2、分析数据意义

    0X8F   翻开是雷

      0x10    结束标示

 

    

      

           

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       

 

posted @ 2019-10-01 19:08  山海郡  阅读(271)  评论(0编辑  收藏  举报