「C ++を逆アセンブル、逆解析の秘密」 - データ型

 

  • 浮動小数点型
  所定のベース2は、符号ビットSは、0と1の正および負で表されることをロジックから数Nを表すためにトリプレット{S、E、M}を使用してIEEE規格は、仮数Mは元のコード、注文コードで表されます。 Eは、フレームシフトを表しています。この方法は、正規化浮動小数点数に応じて、仮数フィールドの最上位ビットは、標準的な慣習は、この1つは保存されませんが、それは、小数点の左側に隠され、従って、仮数フィールドの値が1で表現されることにより、常に1であります.M(実際に格納さがMである)は、仮数は、実際のメモリより複数の範囲を表す与えます。通常フレームシフト方法を表す負の屈折率、注文コードEを表すために、指数eのデータは、固定数の指数としてのオフセットを加えた後、これは負のインデックスを回避することができ、そしてあなたは、データの元の順序は、比較演算を行い維持することができます。
  倍精度を拡張単精度(32ビット)、倍精度(64ビット)、(ほとんど使用されない43ビット以上)単精度の拡張(79ビット:IEEE 754浮動小数点数は、4つの方法は、値を指定表します上記のように、典型的には)80に実装。唯一の32ビットモードは、他のものは任意であり、必須です。ほとんどのプログラミング言語は、IEEE浮動小数点演算フォーマットを提供してきたが、一部は非必須として表示されます。例えば、IEEE演算を含むC言語の出現前にIEEE 754、しかしのために必須ではないがある(Cフロートは、一般的にIEEE単精度、倍精度を意味し、二重度を意味します)。
全体的にプレゼンテーション
  バイナリ浮動小数点形式は、シンボル値がメソッドを表す格納されている - 最上位ビットは符号ビット(符号ビット)として指定され、「インデックス部分」、すなわち、Eの次の最上位ビット、指数部を格納し、最後に残っfは(0法令デフォルトの非整数部分の形態で、他のすべての場合デフォルト)小数部のビットストレージ「有効数」(仮)の上位ビットを下げます。
インデックスは、オフセット  
  指数は、値(指数バイアス)オフセット浮動小数点表記に加えて、固定値で符号化された指数部の指数値の実際の値を参照し、IEEE 754規格に指定された固定値すなわち  、前記 
これは、ビット長のインデックスが格納されます。
単精度浮動小数点の指数フィールドは、固定されたオフセット値は8ビットであるように 
この実施形態は、符号付き数、実際の値の指数部が-127から128までの単精度浮動小数点であるです。例えば、実際の値インデックス
、指数フィールドは、単精度浮動小数点で符号化されます
その 
指数実際の値を加えた固定オフセット値は、浮動小数点指数を表す接近、利点は、2つの浮動小数点指数の大きさになる長さのすべてのインデックスを表すビットの符号なし整数値を、電子でき比較的容易に、実際には、辞書順に係る2つの浮動小数点表現のサイズを比較することができます。これは、指数として中国で知られているシフトインデックス部分を表しています。

 単一の浮動小数点であります:

    25フロート fFloat0 = 12.25f 
0130723E F3 0F 10  05 CC 2E 3A 01 movss XMM0、DWORD PTR [__real @ 4144万(013A2ECCh)]  
 01307246 F3 0F 11  45 F8 movss DWORD PTR [fFloat0]、XMM0

 

 

負の単浮動小数点:

 

  無限バイナリ変換:

 

 倍精度浮動小数点数:

フロートを使用します。

54:     // 浮点数使用
    55:      float fFloat = (float)argc;
01307272 F3 0F 2A 45 08       cvtsi2ss    xmm0,dword ptr [argc]  
01307277 F3 0F 11 45 C4       movss       dword ptr [fFloat],xmm0  //movss 保存单浮点数
    56:      printf("%f", fFloat);//单浮点数作为参数时,需要先转换为双浮点数。
0130727C F3 0F 5A 45 C4       cvtss2sd    xmm0,dword ptr [fFloat] //cvtsi2ss 单浮点数-->双浮点数 
01307281 83 EC 08             sub         esp,8  //开辟8字节,以保存转换结果
01307284 F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0  //movsd 保存双浮点数
01307289 68 50 2E 3A 01       push        offset string "%f" (013A2E50h)  
0130728E E8 32 A1 FF FF       call        _printf (013013C5h)  
01307293 83 C4 0C             add         esp,0Ch  
    57:      argc = (int)fFloat;
01307296 F3 0F 2C 45 C4       cvttss2si   eax,dword ptr [fFloat]  //cvttss2si 单浮点数-->整形
    57:      argc = (int)fFloat;
0130729B 89 45 08             mov         dword ptr [argc],eax  
    58:      printf("%d", argc);
0130729E 8B 45 08             mov         eax,dword ptr [argc]  
013072A1 50                   push        eax  
013072A2 68 54 2E 3A 01       push        offset string "%d" (013A2E54h)  
013072A7 E8 19 A1 FF FF       call        _printf (013013C5h)  
013072AC 83 C4 08             add         esp,8  
    59: 
    60:      fFloat = GetFloat();
013072AF E8 77 C2 FF FF       call        GetFloat (0130352Bh)  
013072B4 D9 5D C4             fstp        dword ptr [fFloat]  //ST(0)出栈,存入[fFloat]
    61:      printf("%f", fFloat);
013072B7 F3 0F 5A 45 C4       cvtss2sd    xmm0,dword ptr [fFloat]  //单浮点数作为参数,转换为双浮点数
013072BC 83 EC 08             sub         esp,8  
013072BF F2 0F 11 04 24       movsd       mmword ptr [esp],xmm0  
    61:      printf("%f", fFloat);
013072C4 68 50 2E 3A 01       push        offset string "%f" (013A2E50h)  
013072C9 E8 F7 A0 FF FF       call        _printf (013013C5h)  
013072CE 83 C4 0C             add         esp,0Ch  

GetFloat():

6: float GetFloat()
     7: {
01307130 55                   push        ebp  
01307131 8B EC                mov         ebp,esp  
01307133 81 EC C0 00 00 00    sub         esp,0C0h  
01307139 53                   push        ebx  
0130713A 56                   push        esi  
0130713B 57                   push        edi  
0130713C 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
01307142 B9 30 00 00 00       mov         ecx,30h  
     1: // DataType.cpp : Defines the entry point for the console application.
     2: //
     3: 
     4: #include "stdafx.h"
     5: #include <stdio.h>
     6: float GetFloat()
     7: {
01307147 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0130714C F3 AB                rep stos    dword ptr es:[edi]  
     8:     return 12.25f;
0130714E D9 05 CC 2E 3A 01    fld         dword ptr [__real@41440000 (013A2ECCh)]  //关键就这一句,将浮点数存入ST(0)
     9: }
01307154 5F                   pop         edi  
01307155 5E                   pop         esi  
01307156 5B                   pop         ebx  
01307157 8B E5                mov         esp,ebp  
01307159 5D                   pop         ebp  
0130715A C3                   ret  
  • 字符与字符串

 

 

 

 

 


 

  • 布尔类型
71:      // 布尔类型
    72:      bool bBool;
    73:      if (argc > 0)
013072ED 83 7D 08 00          cmp         dword ptr [argc],0  
013072F1 7E 06                jle         main+0D9h (013072F9h)  
    74:      {
    75:          bBool = true;
013072F3 C6 45 A3 01          mov         byte ptr [bBool],1  //bool类型占用1字节,true 1;false 0;
    76:      }
    77:      else
013072F7 EB 04                jmp         main+0DDh (013072FDh)  
    78:      {
    79:          bBool = false;
013072F9 C6 45 A3 00          mov         byte ptr [bBool],0  
    80:      }
    81:      
    82:      
    83:      if (bBool == false)
013072FD 0F B6 45 A3          movzx       eax,byte ptr [bBool]  
    80:      }
    81:      
    82:      
    83:      if (bBool == false)
01307301 85 C0                test        eax,eax  
01307303 75 0D                jne         main+0F2h (01307312h)  
    84:      {
    85:          printf("布尔类型\r\n");
01307305 68 A0 2E 3A 01       push        offset string "\xb2\xbc\xb6\xfb\xc0\xe0\xd0\xcd\r\n" (013A2EA0h)  
0130730A E8 B6 A0 FF FF       call        _printf (013013C5h)  
0130730F 83 C4 04             add         esp,4  
    86:     }

  • 地址、指针和引用
对指针取内容:
    89: 
    90:     // 对指针取内容
    91:      int nVar = 0x12345678;
00E6723E C7 45 F8 78 56 34 12 mov         dword ptr [nVar],12345678h  
    92:      int *pnVar = &nVar;
00E67245 8D 45 F8             lea         eax,[nVar]  //引用-- 取地址
00E67248 89 45 EC             mov         dword ptr [pnVar],eax  //指针变量保存地址
    93:      char *pcVar = (char*)&nVar;
00E6724B 8D 45 F8             lea         eax,[nVar]  
00E6724E 89 45 E0             mov         dword ptr [pcVar],eax  
    94:      short *psnVar = (short*)&nVar;
00E67251 8D 45 F8             lea         eax,[nVar]  
00E67254 89 45 D4             mov         dword ptr [psnVar],eax  
    95:      printf("%08x \r\n", *pnVar);
00E67257 8B 45 EC             mov         eax,dword ptr [pnVar]  
00E6725A 8B 08                mov         ecx,dword ptr [eax]  //*pnVar  取4字节类型变量
00E6725C 51                   push        ecx  
00E6725D 68 50 2E F0 00       push        offset string "%08x \r\n" (0F02E50h)  
00E67262 E8 5E A1 FF FF       call        _printf (0E613C5h)  
00E67267 83 C4 08             add         esp,8  
    96:      printf("%08x \r\n", *pcVar);
00E6726A 8B 45 E0             mov         eax,dword ptr [pcVar]  
00E6726D 0F BE 08             movsx       ecx,byte ptr [eax]  //1字节类型变量
00E67270 51                   push        ecx  
00E67271 68 50 2E F0 00       push        offset string "%08x \r\n" (0F02E50h)  
00E67276 E8 4A A1 FF FF       call        _printf (0E613C5h)  
00E6727B 83 C4 08             add         esp,8  
    97:      printf("%08x \r\n", *psnVar);
00E6727E 8B 45 D4             mov         eax,dword ptr [psnVar]  
00E67281 0F BF 08             movsx       ecx,word ptr [eax]  //2字节类型变量
00E67284 51                   push        ecx  
00E67285 68 50 2E F0 00       push        offset string "%08x \r\n" (0F02E50h)  
00E6728A E8 36 A1 FF FF       call        _printf (0E613C5h)  
00E6728F 83 C4 08             add         esp,8  

指针偏移:
 //指针偏移
   100:      char cVar[5] = {0x01, 0x23, 0x45, 0x67, 0x89}; 
00217238 C6 45 F0 01          mov         byte ptr [cVar],1  
0021723C C6 45 F1 23          mov         byte ptr [ebp-0Fh],23h  
00217240 C6 45 F2 45          mov         byte ptr [ebp-0Eh],45h  
00217244 C6 45 F3 67          mov         byte ptr [ebp-0Dh],67h  
00217248 C6 45 F4 89          mov         byte ptr [ebp-0Ch],89h  
   101:  
   102:      int *pnVar = (int*)cVar;
0021724C 8D 45 F0             lea         eax,[cVar]  
0021724F 89 45 E4             mov         dword ptr [pnVar],eax  
   103:      char *pcVar = (char*)cVar;
00217252 8D 45 F0             lea         eax,[cVar]  
00217255 89 45 D8             mov         dword ptr [pcVar],eax  
   104:      short *psnVar = (short*)cVar;
00217258 8D 45 F0             lea         eax,[cVar]  
   104:      short *psnVar = (short*)cVar;
0021725B 89 45 CC             mov         dword ptr [psnVar],eax  
   105:  //x86 下指针变量都占4字节
   106:      pnVar += 1;
0021725E 8B 45 E4             mov         eax,dword ptr [pnVar]  
00217261 83 C0 04             add         eax,4  //int指针指向的变量类型大小为4字节
00217264 89 45 E4             mov         dword ptr [pnVar],eax  //相当于指向cVar[4],
   107:      pcVar += 1;
00217267 8B 45 D8             mov         eax,dword ptr [pcVar]  
0021726A 83 C0 01             add         eax,1  //char指针指向的变量类型大小为1字节
0021726D 89 45 D8             mov         dword ptr [pcVar],eax  //指向元素cVar[1] 
   108:      psnVar += 1;
00217270 8B 45 CC             mov         eax,dword ptr [psnVar]  
00217273 83 C0 02             add         eax,2  
00217276 89 45 CC             mov         dword ptr [psnVar],eax  //指向元素cVar[2]
   109:  
   110:      printf("%08x \r\n", *pnVar);
00217279 8B 45 E4             mov         eax,dword ptr [pnVar]  
   109:  
   110:      printf("%08x \r\n", *pnVar);
0021727C 8B 08                mov         ecx,dword ptr [eax]  
0021727E 51                   push        ecx  
0021727F 68 50 2E 2B 00       push        offset string "%08x \r\n" (02B2E50h)  
00217284 E8 3C A1 FF FF       call        _printf (02113C5h)  
00217289 83 C4 08             add         esp,8  
   111:      printf("%08x \r\n", *pcVar);
0021728C 8B 45 D8             mov         eax,dword ptr [pcVar]  
0021728F 0F BE 08             movsx       ecx,byte ptr [eax]  
00217292 51                   push        ecx  
00217293 68 50 2E 2B 00       push        offset string "%08x \r\n" (02B2E50h)  
00217298 E8 28 A1 FF FF       call        _printf (02113C5h)  
0021729D 83 C4 08             add         esp,8  
   112:      printf("%08x \r\n", *psnVar);
002172A0 8B 45 CC             mov         eax,dword ptr [psnVar]  
002172A3 0F BF 08             movsx       ecx,word ptr [eax]  
002172A6 51                   push        ecx  
002172A7 68 50 2E 2B 00       push        offset string "%08x \r\n" (02B2E50h)  
002172AC E8 14 A1 FF FF       call        _printf (02113C5h)  
002172B1 83 C4 08             add         esp,8  

 

 

引用类型:
 //引用类型
   115:     int nVar = 0x12345678;
0086717E C7 45 F8 78 56 34 12 mov         dword ptr [nVar],12345678h  
   116:      //引用类型定义
   117:     int &nVarTpye = nVar;
00867185 8D 45 F8             lea         eax,[nVar]  
00867188 89 45 EC             mov         dword ptr [nVarTpye],eax  
   118:      //调用函数,参数为引用类型
   119:     Add(nVar);
0086718B 8D 45 F8             lea         eax,[nVar]  
0086718E 50                   push        eax  
0086718F E8 AF A6 FF FF       call        Add (0861843h)  
00867194 83 C4 04             add         esp,4  

add():

11: void Add(int &nVar)
    12: {
008670E0 55                   push        ebp  
008670E1 8B EC                mov         ebp,esp  
008670E3 81 EC C0 00 00 00    sub         esp,0C0h  
008670E9 53                   push        ebx  
008670EA 56                   push        esi  
008670EB 57                   push        edi  
008670EC 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
008670F2 B9 30 00 00 00       mov         ecx,30h  
008670F7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
008670FC F3 AB                rep stos    dword ptr es:[edi]  
    13:     nVar++;
008670FE 8B 45 08             mov         eax,dword ptr [nVar]  
00867101 8B 08                mov         ecx,dword ptr [eax]  
00867103 83 C1 01             add         ecx,1  
00867106 8B 55 08             mov         edx,dword ptr [nVar]  
00867109 89 0A                mov         dword ptr [edx],ecx  
    14: }
0086710B 5F                   pop         edi  
0086710C 5E                   pop         esi  
0086710D 5B                   pop         ebx  
0086710E 8B E5                mov         esp,ebp  
00867110 5D                   pop         ebp  
00867111 C3                   ret  

 

  • 常量
 //const常量修改
   132: 
   133:      const int nConst = 5;
00867197 C7 45 E0 05 00 00 00 mov         dword ptr [nConst],5  
   134:      int *pConst = (int*)&nConst;
0086719E 8D 45 E0             lea         eax,[nConst]  
008671A1 89 45 D4             mov         dword ptr [pConst],eax  
   135:      *pConst = 6;
008671A4 8B 45 D4             mov         eax,dword ptr [pConst]  
008671A7 C7 00 06 00 00 00    mov         dword ptr [eax],6  
   136:     int nVar1 = nConst;
008671AD C7 45 C8 05 00 00 00 mov         dword ptr [nVar1],5  //由于const修饰的变量nConst被赋值一个数字常量5,
//编译器在编译过程中发现nConst的初值是可知的,并且被修饰为const。之后所有使用nConst的地方都以这个可预知值替换,
//故int nVar=nConst;对应的汇编代码没有将nConst赋值给nVar,而是用常量值5代替。如果nConst的值为一个未知值,那么编译器将不会做此优化。

 

 

 

  #define是一个真常量,而const却是由编译器判断实现的常量,是一个假常量。在实际中,使用const定义的变量,最终还是一个变量,只是在编译器内进行了检查,发现有修改则报错。
由于编译器在编译期间对const变量进行检查,因此被const修饰过的变量是可以修改的。利用指针获取到const修饰过的变量地址,强制将指针的const修饰去掉,就可以修改对应的数据内容

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

おすすめ

転載: www.cnblogs.com/DirWang/p/12126547.html