zoukankan      html  css  js  c++  java
  • C语言之 Switch和?:运算符的反汇编

    Switch条件语句

    通过上面一篇了解了条件语句的使用,接下来就直接进行反汇编学习

    #include <stdio.h>
    
    void print()
    {
    	int b = 1;
    	switch (b)
    	{
    	case 1:
    		printf("当前是1");
    		break;
    	case 2:
    		printf("当前是2");
    		break;
    	default:
    		printf("unKnow");
    		break;
    	}
    }
    
    int main()
    {
    
    	print();
    	return 0;
    }
    

    先f2在print()下个断点,然后我们进入反汇编窗口

    然后我们再f11两下,跳两下,进入函数内部

    00873840  push        ebp  
    00873841  mov         ebp,esp  
    00873843  sub         esp,0D0h  
    00873849  push        ebx  
    0087384A  push        esi  
    0087384B  push        edi  
    0087384C  lea         edi,[ebp-0D0h]  
    00873852  mov         ecx,34h  
    00873857  mov         eax,0CCCCCCCCh  
    0087385C  rep stos    dword ptr es:[edi]  
    
    0087385E  mov         dword ptr [b],1  
    00873865  mov         eax,dword ptr [b]  
    00873868  mov         dword ptr [ebp-0D0h],eax  
    0087386E  cmp         dword ptr [ebp-0D0h],1  
    00873875  je          print+42h (0873882h)  
    00873877  cmp         dword ptr [ebp-0D0h],2  
    0087387E  je          print+51h (0873891h)  
    00873880  jmp         print+60h (08738A0h)  
    00873882  push        offset string "xb5xb1xc7xb0xcaxc71" (0876B94h)  
    00873887  call        _printf (08713B1h)  
    0087388C  add         esp,4  
    0087388F  jmp         print+6Dh (08738ADh)  
    00873891  push        offset string "xb5xb1xc7xb0xcaxc72" (0876BE4h)  
    00873896  call        _printf (08713B1h)  
    0087389B  add         esp,4  
    0087389E  jmp         print+6Dh (08738ADh)  
    008738A0  push        offset string "unKnow" (0876C0Ch)  
    008738A5  call        _printf (08713B1h)  
    008738AA  add         esp,4  
    
    008738AD  pop         edi  
    008738AE  pop         esi  
    008738AF  pop         ebx  
    008738B0  add         esp,0D0h  
    008738B6  cmp         ebp,esp  
    008738B8  call        __RTC_CheckEsp (087132Fh)  
    008738BD  mov         esp,ebp  
    008738BF  pop         ebp  
    008738C0  ret  
    

    我们的代码都是在缓冲区填充完数据之后的,才是真正的功能点

    0087385E  mov         dword ptr [b],1        //把1赋值给b
    00873865  mov         eax,dword ptr [b]      //把b给eax寄存器
    00873868  mov         dword ptr [ebp-0D0h],eax  //把eax的值给 ebp-0D0h 这个地址上
    

    接下来就开始进行比较了

    0087386E  cmp         dword ptr [ebp-0D0h],1  //对比两个值
    00873875  je          print+42h (0873882h)    //je是当两个数为相等的时候执行
    00873877  cmp         dword ptr [ebp-0D0h],2  
    0087387E  je          print+51h (0873891h)  
    00873880  jmp         print+60h (08738A0h)   //Jmp无条件跳转到 0x08738A0h 这个地址上
    

    由上得知 eax=1 == 1,所以会跳到 0x0873882h 这个地址上面

    00873882  push        offset string "xb5xb1xc7xb0xcaxc71" (0876B94h)  //把字符串压入栈中
    00873887  call        _printf (08713B1h)    //调用printf()函数打印出来
    0087388C  add         esp,4                 //栈顶提升4字节,也就是平栈
    0087388F  jmp         print+6Dh (08738ADh)  //直接跳到下面一段,完成功能执行
    ....
    ....
    008738AD  pop         edi         //恢复数据
    008738AE  pop         esi         //恢复数据
    008738AF  pop         ebx         //恢复数据
    008738B0  add         esp,0D0h    
    008738B6  cmp         ebp,esp  
    008738B8  call        __RTC_CheckEsp (087132Fh)  
    008738BD  mov         esp,ebp  
    008738BF  pop         ebp  
    008738C0  ret  
    

    ?:运算符

    #include <stdio.h>
    
    void print()
    {
    	int a = 10;
    	int c = a > 11 ? 10 : 11;
    }
    
    int main()
    {
    
    	print();
    	return 0;
    }
    
    00D43840  push        ebp  
    00D43841  mov         ebp,esp  
    00D43843  sub         esp,0DCh  
    00D43849  push        ebx  
    00D4384A  push        esi  
    00D4384B  push        edi  
    00D4384C  lea         edi,[ebp-0DCh]  
    00D43852  mov         ecx,37h  
    00D43857  mov         eax,0CCCCCCCCh  
    00D4385C  rep stos    dword ptr es:[edi]  
    	int a = 10;
    00D4385E  mov         dword ptr [a],0Ah  
    	int c = a > 11 ? 10 : 11;
    00D43865  cmp         dword ptr [a],0Bh  
    00D43869  jle         print+37h (0D43877h)  
    00D4386B  mov         dword ptr [ebp-0DCh],0Ah  
    00D43875  jmp         print+41h (0D43881h)  
    00D43877  mov         dword ptr [ebp-0DCh],0Bh  
    00D43881  mov         eax,dword ptr [ebp-0DCh]  
    00D43887  mov         dword ptr [c],eax  
    }
    00D4388A  pop         edi  
    00D4388B  pop         esi  
    00D4388C  pop         ebx  
    00D4388D  mov         esp,ebp  
    00D4388F  pop         ebp  
    00D43890  ret  
    

    和if语句没什么区别,就不写了,可以看看练习一下

  • 相关阅读:
    批量重命令文件名称的几种方式
    SecureCRT常用快捷键
    ipv4地址从最后一位按步长递增
    win32
    GDI根据位图和透明度创建蒙版
    git bash的一些使用
    win32
    win32
    win32
    QT
  • 原文地址:https://www.cnblogs.com/0x7e/p/13749614.html
Copyright © 2011-2022 走看看