00407C9C  /$  B8 AC7C4000   mov     eax, 00407CAC ;
00407CA1  |.  E8 F2FFFFFF   call    00407C98

本人是新手, 刚看到这两句真不知道是干什么的, 但是由于有些汇编和正向编程经验,所以
call 还是知道的, 步进了call 发现 将 eax传给了ebx, 后来又做了恢复。

可见eax 存储的应该是函数的参数, 但是由于汇编无类型,或者说大部分都是  几字节 双字
单字的, 这对于习惯高级语言的 实在痛苦。 

到这里基本上停顿了, 后来就干脆试试 为任意一个函数仅有一个参数的进行反汇编,
任意的改变类型。 于是就得到下面的一堆片段, 本来我是想 反过大部分情况后 比如 
Integer Boolean Char String PChar Real Single 等作为参数情况后然后再里面找的, 我还找了本官方的Object Pascal 来从头逐个对  各种  运算符 流程控制  函数  参数, 函数指针  类
集合  记录 等进行反 , 恩  忘了说, 我反的是Delphi写的。

00000000
..................
code.  jmp 行1985


题目: Delphi 7 的反汇编结果,  编译选项默认。

0.不同的subsystem, 子系统编译出来的反汇编头结果。
当子系统为控制台时也就是{APPTYPE  CONSOLE}时, 
004034F0 > $  55            push    ebp
004034F1   .  8BEC          mov     ebp, esp
004034F3   .  83C4 F0       add     esp, -10

004034F6   .  A1 A0404000   mov     eax, dword ptr [4040A0]
004034FB   .  C600 01       mov     byte ptr [eax], 1
004034FE   .  B8 B8344000   mov     eax, 004034B8
00403503   .  E8 DCFDFFFF   call    004032E4
00403508   .  E8 CBFEFFFF   call    004033D8 ; WinMain函数中转。名字无所谓。
0040350D   .  E8 EAF8FFFF   call    00402DFC

//begin相当于{  end 相当于}

当子系统为GUI时也就是{APPTYPE GUI}时,Delphi 7的入口为:
004034F0 > $  55            push    ebp
004034F1   .  8BEC          mov     ebp, esp
004034F3   .  83C4 F0       add     esp, -10
004034F6   .  B8 B8344000   mov     eax, 004034B8
004034FB   .  E8 E4FDFFFF   call    004032E4
00403500   .  E8 D3FEFFFF   call    004033D8; 
               这里利用另外一个函数中转,是procedure,表示无返回值。
00403505   .  E8 F2F8FFFF   call    00402DFC
0040350A   .  8BC0          mov     eax, eax

无论是用procedure还是function并不影响入口头的编译指令。
004034F4 > $  55            push    ebp
004034F5   .  8BEC          mov     ebp, esp
004034F7   .  83C4 F0       add     esp, -10
004034FA   .  B8 BC344000   mov     eax, 004034BC
004034FF   .  E8 E0FDFFFF   call    004032E4
00403504   .  E8 CFFEFFFF   call    004033D8
00403509   .  E8 EEF8FFFF   call    00402DFC


一、 函数, 函数参数, 指针类型, 类对象类型。
1. 对不同函数参数, 对不同Delphi过程的反汇编进行总结。
   首先按四个参数进行, 四个参数的类型上进行逐一对比。
   (1)四个参数全为Integer型
00403460  /$  6A 04         push    4
00403462  |.  B9 03000000   mov     ecx, 3
00403467  |.  BA 02000000   mov     edx, 2
0040346C  |.  B8 01000000   mov     eax, 1
00403471  |.  E8 A2FFFFFF   call    00403418

一个整型参数
0040345C  /$  B8 01000000   mov     eax, 1
00403461  |.  E8 B2FFFFFF   call    00403418

Cardinal类型时无变化, Cardinal是32位无符号整数
00403460  /$  6A 05         push    5
00403462  |.  B9 04000000   mov     ecx, 4
00403467  |.  BA 03000000   mov     edx, 3
0040346C  |.  B8 0C000000   mov     eax, 0C
00403471  |.  E8 A2FFFFFF   call    00403418

Shortint类型时,寄存使用8位的, 如 al dl
00403460  /$  6A 05         push    5
00403462  |.  B1 04         mov     cl, 4
00403464  |.  B2 03         mov     dl, 3
00403466  |.  B0 0C         mov     al, 0C
00403468  |.  E8 ABFFFFFF   call    00403418

Smallint类型时, 寄存器使用16位的, 如 ax, dx, 但是由于CPU默认一次传递最大是32位的,
所以不管处理什么最好默认类型都用32位的, 如果用小位的,则CPU要进行调整。
但是由于目前64位的CPU很多,当用64位操作系统时则最好使用64位的类型。
00403460  /$  6A 05         push    5
00403462  |.  66:B9 0400    mov     cx, 4
00403466  |.  66:BA 0300    mov     dx, 3
0040346A  |.  66:B8 0C00    mov     ax, 0C
0040346E  |.  E8 A5FFFFFF   call    00403418

Longint类型,为32位, 如eax, edx, ecx
00403460  /$  6A 05         push    5
00403462  |.  B9 04000000   mov     ecx, 4
00403467  |.  BA 03000000   mov     edx, 3
0040346C  |.  B8 0C000000   mov     eax, 0C
00403471  |.  E8 A2FFFFFF   call    00403418

使用64位Int64,则全变成了即时数,不再用寄存器中转
00403460  /$  6A 00         push    0
00403462  |.  6A 0C         push    0C
00403464  |.  6A 00         push    0
00403466  |.  6A 03         push    3
00403468  |.  6A 00         push    0
0040346A  |.  6A 04         push    4
0040346C  |.  6A 00         push    0
0040346E  |.  6A 05         push    5
00403470  |.  E8 A3FFFFFF   call    00403418

使用8位的Byte, 则还为8位的al 
00403460  /$  6A 05         push    5
00403462  |.  B1 04         mov     cl, 4
00403464  |.  B2 03         mov     dl, 3
00403466  |.  B0 0C         mov     al, 0C
00403468  |.  E8 ABFFFFFF   call    00403418

使用16位的Word, 则为16位的ax
00403460  /$  6A 05         push    5
00403462  |.  66:B9 0400    mov     cx, 4
00403466  |.  66:BA 0300    mov     dx, 3
0040346A  |.  66:B8 0C00    mov     ax, 0C
0040346E  |.  E8 A5FFFFFF   call    00403418

使用32位的Longword, 则为32位的eax
00403460  /$  6A 05         push    5
00403462  |.  B9 04000000   mov     ecx, 4
00403467  |.  BA 03000000   mov     edx, 3
0040346C  |.  B8 0C000000   mov     eax, 0C
00403471  |.  E8 A2FFFFFF   call    00403418


[结论] 四个参数大部分使用寄存器转参数

(2)四个参数全为字符型Char, 由于单个字符是8位,所以寄存器使用al dl cl作中转。
00403460  /$  6A 33         push    33
00403462  |.  B1 33         mov     cl, 33
00403464  |.  B2 32         mov     dl, 32
00403466  |.  B0 31         mov     al, 31
00403468  |.  E8 ABFFFFFF   call    00403418
[结论] 四个参数大部分使用寄存器转参数, 不push, 或不每个参数都push.

(3)四个参数全为布尔值时, 序列为 True, False, True, False
00403460  /$  6A 00         push    0
00403462  |.  B1 01         mov     cl, 1
00403464  |.  33D2          xor     edx, edx
00403466  |.  B0 01         mov     al, 1
00403468  |.  E8 ABFFFFFF   call    00403418
序列为 True, True, True, True
00403460  /$  6A 01         push    1
00403462  |.  B1 01         mov     cl, 1
00403464  |.  B2 01         mov     dl, 1
00403466  |.  B0 01         mov     al, 1
序列为 False, False, False, False时
00403460  /$  6A 00         push    0
00403462  |.  33C9          xor     ecx, ecx
00403464  |.  33D2          xor     edx, edx
00403466  |.  33C0          xor     eax, eax
00403468  |.  E8 ABFFFFFF   call    00403418,   由于 xor指令对相同则 = 0, 不同则为1。和
and指令相反, and 是 1 and 1 = 1 1 and 0 = 0, 0 and 1 = 0 0 and 0 = 0.
序列为 True, True, False, False时
00403460  /$  6A 00         push    0
00403462  |.  33C9          xor     ecx, ecx
00403464  |.  B2 01         mov     dl, 1
00403466  |.  B0 01         mov     al, 1
00403468  |.  E8 ABFFFFFF   call    00403418
序列为 False, False, True, True时
00403460  /$  6A 01         push    1
00403462  |.  B1 01         mov     cl, 1
00403464  |.  33D2          xor     edx, edx = 0
00403466  |.  33C0          xor     eax, eax = 0
00403468  |.  E8 ABFFFFFF   call    00403418

(4)四个参数全为Real48的实数类型时, 全利用push 压入
0040343C  /$  68 852B0000   push    2B85
00403441  |.  68 8152B81E   push    1EB85281(每个立即数占用48位)
00403446  |.  68 1E250000   push    251E
0040344B  |.  68 81EC51B8   push    B851EC81
00403450  |.  68 707D0000   push    7D70
00403455  |.  68 810AD7A3   push    A3D70A81
0040345A  |.  68 D7630000   push    63D7
0040345F  |.  68 81713D0A   push    0A3D7181
00403464  |.  E8 8BFFFFFF   call    004033F4
(5)四个参数全为Single的实数类型时, 仍然是全利用 push压入
0040343C  /$  68 1F85AB3F   push    3FAB851F(每个占用32位)
00403441  |.  68 B81EA53F   push    3FA51EB8
00403446  |.  68 A470FD3F   push    3FFD70A4
0040344B  |.  68 0AD7E33F   push    3FE3D70A
00403450  |.  E8 9FFFFFFF   call    004033F4
(6)四个参数全为Double的实数类型时, Double是64位的,所以没个立即数占64位。
0040343C  /$  68 A370F53F   push    3FF570A3
00403441  |.  68 713D0AD7   push    D70A3D71
00403446  |.  68 D7A3F43F   push    3FF4A3D7
0040344B  |.  68 A4703D0A   push    0A3D70A4
00403450  |.  68 14AEFF3F   push    3FFFAE14
00403455  |.  68 AE47E17A   push    7AE147AE
0040345A  |.  68 E17AFC3F   push    3FFC7AE1
0040345F  |.  68 7B14AE47   push    47AE147B
00403464  |.  E8 8BFFFFFF   call    004033F4
(7)四个参数全为Extended的实数类型时,  Extended是80位, 即立即数占80位。
0040343C  /$  68 FF3F0000   push    3FFF
00403441  |.  68 B81E85AB   push    AB851EB8
00403446  |.  68 1F85EB51   push    51EB851F

0040344B  |.  68 FF3F0000   push    3FFF
00403450  |.  68 51B81EA5   push    A51EB851
00403455  |.  68 B81E85EB   push    EB851EB8

0040345A  |.  68 FF3F0000   push    3FFF
0040345F  |.  68 D7A370FD   push    FD70A3D7
00403464  |.  68 A4703D0A   push    0A3D70A4

00403469  |.  68 FF3F0000   push    3FFF
0040346E  |.  68 3D0AD7E3   push    E3D70A3D
00403473  |.  68 0AD7A370   push    70A3D70A
00403478  |.  E8 77FFFFFF   call    004033F4
(8)四个全为Comp
0040343C  /$  6A 00         push    0
0040343E  |.  6A 01         push    1

00403440  |.  6A 00         push    0
00403442  |.  6A 01         push    1

00403444  |.  6A 00         push    0
00403446  |.  6A 02         push    2

00403448  |.  6A 00         push    0
0040344A  |.  6A 02         push    2
0040344C  |.  E8 A3FFFFFF   call    004033F4
(9)四个全为Currency类型的实数
0040343C  /$  6A 00         push    0
0040343E  |.  68 58340000   push    3458
00403443  |.  6A 00         push    0
00403445  |.  68 64320000   push    3264
0040344A  |.  6A 00         push    0
0040344C  |.  68 584D0000   push    4D58
00403451  |.  6A 00         push    0
00403453  |.  68 88450000   push    4588
00403458  |.  E8 97FFFFFF   call    004033F4
(10)四个全为String字符串时的
0040345C  /$  68 80344000   push    00403480                         ;  ASCII "Hello"
00403461  |.  B9 80344000   mov     ecx, 00403480                    ;  ASCII "Hello"
00403466  |.  BA 80344000   mov     edx, 00403480                    ;  ASCII "Hello"
0040346B  |.  B8 80344000   mov     eax, 00403480                    ;  ASCII "Hello"
00403470  |.  E8 8FFFFFFF   call    00403404
仍然是用寄存器传递
(11)四个全为WideString字符串时
0040349C  /$  68 BC344000   push    004034BC                         ;  UNICODE "Hello"
004034A1  |.  B9 BC344000   mov     ecx, 004034BC                    ;  UNICODE "Hello"
004034A6  |.  BA BC344000   mov     edx, 004034BC                    ;  UNICODE "Hello"
004034AB  |.  B8 BC344000   mov     eax, 004034BC                    ;  UNICODE "Hello"
004034B0  |.  E8 8FFFFFFF   call    00403444
(12)四个全为PChar时
0040343C  /$  68 58344000   push    00403458                         ;  ASCII "Hello"
00403441  |.  B9 58344000   mov     ecx, 00403458                    ;  ASCII "Hello"
00403446  |.  BA 58344000   mov     edx, 00403458                    ;  ASCII "Hello"
0040344B  |.  B8 58344000   mov     eax, 00403458                    ;  ASCII "Hello"
00403450  |.  E8 9FFFFFFF   call    004033F4

二、 赋值情况, 算术, 过程, 函数, 流程控制, 循环, 其他语句,数组。
1. 当给一个字符串string类型在函数过程中赋值时, 
004033DF  |.  A1 A0404000   mov     eax, dword ptr [4040A0]
004033E4  |.  E8 9BFBFFFF   call    00402F84                  //赋值我们很理解,
                                                              //但是加一个处理就很纳闷了,可能是Delphi特有的,但是这样我们就可以知道,究竟哪里是Delphi多出的部分了。

b := 90;
       a := IntToStr(12);
       MessageBox(0, PChar(a), PChar(a), 0);
对上面进行反汇编, 产生熟悉的情形, 增加了push ebp, 保存基地址。
其中 00402F84步入后呈现为: 
00402F84  /$  85C0          test    eax, eax                         ;  heloMain.004033D0
00402F86  |.  74 02         je      short 00402F8A
00402F88  |.  C3            retn

返回值不同类型的状态
(1)返回值为Integer时
00407C74  /$  33C0          xor     eax, eax
00407C76  \.  C3            retn

当使用Writeln(100)时
004081B8  |.  A1 04934000   mov     eax, dword ptr [409304]    
004081BD  |.  BA 64000000   mov     edx, 64                    //edx = 100
004081C2  |.  E8 0DABFFFF   call    00402CD4
004081C7  |.  E8 38ABFFFF   call    00402D04
004081CC  |.  E8 5BA4FFFF   call    0040262C

全局变量赋值 , 整数。
00407C68  |.  C705 94824000>mov     dword ptr [408294], 0C8
局部变量是在变量被引用的时候才赋值,不引用则不赋值。
004081B0  /$  53            push    ebx

004081B9  |.  BB AA000000   mov     ebx, 0AA  ;单个一个Integer时就使用个寄存器
                                              ;所以要push ebx一下以ret后恢复
004081BE  |.  A1 04934000   mov     eax, dword ptr [409304]
004081C3  |.  8BD3          mov     edx, ebx
004081C5  |.  E8 0AABFFFF   call    00402CD4
004081CA  |.  E8 35ABFFFF   call    00402D04
004081CF  |.  E8 58A4FFFF   call    0040262C

//当要输出的数是一个变量时。
004081B8  |.  A1 08934000   mov     eax, dword ptr [409308]
004081BD  |.  8B15 98924000 mov     edx, dword ptr [409298]
004081C3  |.  E8 0CABFFFF   call    00402CD4
004081C8  |.  E8 37ABFFFF   call    00402D04
004081CD  |.  E8 5AA4FFFF   call    0040262C

当两个Writeln(<变量>)时候
004081B9  |.  BB AA000000   mov     ebx, 0AA
004081BE  |.  A1 08934000   mov     eax, dword ptr [409308]
004081C3  |.  8BD3          mov     edx, ebx
004081C5  |.  E8 0AABFFFF   call    00402CD4
004081CA  |.  E8 35ABFFFF   call    00402D04
004081CF  |.  E8 58A4FFFF   call    0040262C
004081D4  |.  A1 08934000   mov     eax, dword ptr [409308]
004081D9  |.  8B15 98924000 mov     edx, dword ptr [409298]
004081DF  |.  E8 F0AAFFFF   call    00402CD4
004081E4  |.  E8 1BABFFFF   call    00402D04
004081E9  |.  E8 3EA4FFFF   call    0040262C

可见, Writeln(是靠 mov edx, ebx来控制, 而 mov eax, dword ptr [409308]总是存在
三次call是必须的。

当为Writeln(#89)时
0040808C  |.  A1 04934000   mov     eax, dword ptr [409304]
00408091  |.  B2 59         mov     dl, 59
00408093  |.  E8 04ABFFFF   call    00402B9C
00408098  |.  E8 3BABFFFF   call    00402BD8
0040809D  |.  E8 8AA5FFFF   call    0040262C

单个一个变量赋值  Size :=  400; ,变量为全局
00407C68  |.  C705 94824000>mov     dword ptr [408294], 190

单个一个指针类型的变量 根据 立即数可以发现 00408294是个地址。所以还是有区别的。
nSize := @Size;
00407C68  |.  C705 9C974000>mov     dword ptr [40979C], 00408294

两个整数变量相加  rel := Size + pSize;
00407C68  |.  A1 94824000   mov     eax, dword ptr [408294], [408294]存储器操作数,
00407C6D  |.  0305 98824000 add     eax, dword ptr [408298]
00407C73  |.  A3 9C824000   mov     dword ptr [40829C], eax
除了特殊情况, 对一个变量的操作基本上都是存储器操作数。

两个整数变量相乘  rel := Size * pSize;
00407C68  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6D  |.  F72D 98824000 imul    dword ptr [408298]
00407C73  |.  A3 9C824000   mov     dword ptr [40829C], eax

对一个整数变量进行取反, 是先取到一个eax里, 然后对eax取反。
00407C68  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6D  |.  F7D0          not     eax
00407C6F  |.  A3 98824000   mov     dword ptr [408298], eax

对一个Boolean的进行not,  tBool := not tBool;
00407C68  |.  A0 94824000   mov     al, byte ptr [408294]
00407C6D  |.  34 01         xor     al, 1
00407C6F  |.  A2 94824000   mov     byte ptr [408294], al

两个整数相减, sub指令。
00407C68  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6D  |.  2B05 98824000 sub     eax, dword ptr [408298]
00407C73  |.  A3 9C824000   mov     dword ptr [40829C], eax

两个浮点数进行相加  
       tReal := 12.2;
       bReal := tReal + 0.5;
       tReal := tReal + bReal;
00407C68  |.  C705 9C974000>mov     dword ptr [40979C], 66666666
00407C72  |.  C705 A0974000>mov     dword ptr [4097A0], 40286666
00407C7C  |.  DD05 9C974000 fld     qword ptr [40979C]
00407C82  |.  D805 B07C4000 fadd    dword ptr [407CB0]
00407C88  |.  DD1D A4974000 fstp    qword ptr [4097A4]
00407C8E  |.  9B            wait
00407C8F  |.  DD05 9C974000 fld     qword ptr [40979C]
00407C95  |.  DC05 A4974000 fadd    qword ptr [4097A4]
00407C9B  |.  DD1D 9C974000 fstp    qword ptr [40979C]
00407CA1  |.  9B            wait

两个浮点进行相除
00407C68  |.  DB05 94824000 fild    dword ptr [408294]
00407C6E  |.  DB05 98824000 fild    dword ptr [408298]
00407C74  |.  DEF9          fdivp   st(1), st
00407C76  |.  DD1D 9C974000 fstp    qword ptr [40979C]
00407C7C  |.  9B            wait

两个浮点进行整除 tReal := Size div pSize; 取整。
00407C69  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6E  |.  99            cdq
00407C6F  |.  F73D 98824000 idiv    dword ptr [408298]
00407C75  |.  890424        mov     dword ptr [esp], eax //eax存储商
00407C78  |.  DB0424        fild    dword ptr [esp]          //装入整数
00407C7B  |.  DD1D 9C974000 fstp    qword ptr [40979C]
00407C81  |.  9B            wait

两个浮点进行取余 
00407C69  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6E  |.  99            cdq
00407C6F  |.  F73D 98824000 idiv    dword ptr [408298]
00407C75  |.  891424        mov     dword ptr [esp], edx // edx存储余数
00407C78  |.  DB0424        fild    dword ptr [esp]
00407C7B  |.  DD1D 9C974000 fstp    qword ptr [40979C]
00407C81  |.  9B            wait

对一个整数进行取反
00407C68  |.  F71D 94824000 neg     dword ptr [408294]  

对两个Boolean进行逻辑与 and
00407C68  |.  803D 94824000>cmp     byte ptr [408294], 0
00407C6F  |.  74 09         je      short 00407C7A
00407C71  |.  803D 98824000>cmp     byte ptr [408298], 0
00407C78  |.  75 04         jnz     short 00407C7E
00407C7A  |>  33C0          xor     eax, eax
00407C7C  |.  EB 02         jmp     short 00407C80
00407C7E  |>  B0 01         mov     al, 1
00407C80  |>  A2 94824000   mov     byte ptr [408294], al

为两Boolean赋真值和假值
00407C68  |.  C605 94824000>mov     byte ptr [408294], 1 , 真
00407C6F  |.  C605 98824000>mov     byte ptr [408298], 0 , 假

进行逻辑与后再存储在Boolean变量中
00407C68  |.  C605 94824000>mov     byte ptr [408294], 1
00407C6F  |.  C605 98824000>mov     byte ptr [408298], 0

00407C76  |.  803D 94824000>cmp     byte ptr [408294], 0
00407C7D  |.  74 09         je      short 00407C88
00407C7F  |.  803D 98824000>cmp     byte ptr [408298], 0
00407C86  |.  75 04         jnz     short 00407C8C
00407C88  |>  33C0          xor     eax, eax
00407C8A  |.  EB 02         jmp     short 00407C8E
00407C8C  |>  B0 01         mov     al, 1
00407C8E  |>  A2 9C974000   mov     byte ptr [40979C], al

进行逻辑或
00407C68  |.  C605 94824000>mov     byte ptr [408294], 1
00407C6F  |.  C605 98824000>mov     byte ptr [408298], 0
00407C76  |.  803D 94824000>cmp     byte ptr [408294], 0
00407C7D  |.  75 0D         jnz     short 00407C8C
00407C7F  |.  803D 98824000>cmp     byte ptr [408298], 0
00407C86  |.  75 04         jnz     short 00407C8C
00407C88  |.  33C0          xor     eax, eax
00407C8A  |.  EB 02         jmp     short 00407C8E
00407C8C  |>  B0 01         mov     al, 1
00407C8E  |>  A2 9C974000   mov     byte ptr [40979C], al

进行逻辑异或
00407C68  |.  C605 94824000>mov     byte ptr [408294], 1
00407C6F  |.  C605 98824000>mov     byte ptr [408298], 0
00407C76  |.  A0 94824000   mov     al, byte ptr [408294]  只对是真的进行处理,另外逻辑运算都进行转换到Byte - 8bit
00407C7B  |.  3205 98824000 xor     al, byte ptr [408298]
00407C81  |.  A2 9C974000   mov     byte ptr [40979C], al

对整数则为位运算,这容易让人混淆。Size := not Size;
00407C68  |.  F715 94824000 not     dword ptr [408294]

对整数进行位运算与
00407C68  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6D  |.  2305 98824000 and     eax, dword ptr [408298]
00407C73  |.  A3 9C824000   mov     dword ptr [40829C], eax
00407C78  |.  89C0          mov     eax, eax

对整数进行位运算或
00407C68  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6D  |.  0B05 98824000 or      eax, dword ptr [408298]  //整数的比Boolean的容易看,
                           //使用与或非 异或指令很明显。
00407C73  |.  A3 9C824000   mov     dword ptr [40829C], eax

对整数进行位运算异或
00407C68  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C6D  |.  3305 98824000 xor     eax, dword ptr [408298]
00407C73  |.  A3 9C824000   mov     dword ptr [40829C], eax

对整数进行位运算左移位 shl
00407C68  |.  8B0D 98824000 mov     ecx, dword ptr [408298]
00407C6E  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C73  |.  D3E0          shl     eax, cl
00407C75  |.  A3 9C824000   mov     dword ptr [40829C], eax

对整数进行位运算右移位 shr
00407C68  |.  8B0D 98824000 mov     ecx, dword ptr [408298]
00407C6E  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C73  |.  D3E8          shr     eax, cl
00407C75  |.  A3 9C824000   mov     dword ptr [40829C], eax

进行条件判断 = 时
[源]
if Size = 100 then
           Writeln('Hello World');
004080F4  |.  833D 98924000>cmp     dword ptr [409298], 64
004080FB  |.  75 19         jnz     short 00408116
004080FD  |.  A1 08934000   mov     eax, dword ptr [409308]
00408102  |.  BA 2C814000   mov     edx, 0040812C                    ;  ASCII "Hello World"

关系运算符 <> 时
if Size <> 100 then
       begin
           Writeln('Hello World');
       end;
004080F4  |.  833D 98924000>cmp     dword ptr [409298], 64
004080FB  |.  74 19         je      short 00408116            (ZF = 1)时
004080FD  |.  A1 08934000   mov     eax, dword ptr [409308]
00408102  |.  BA 2C814000   mov     edx, 0040812C                    ;  ASCII "Hello World"
00408107  |.  E8 48BDFFFF   call    00403E54
0040810C  |.  E8 07ABFFFF   call    00402C18
00408111  |.  E8 16A5FFFF   call    0040262C

关系运算 < 时
if Size < 100 then
       begin
           Writeln('Hello World');
       end;
004080F4  |.  833D 98924000>cmp     dword ptr [409298], 64
004080FB  |.  7D 19         jge     short 00408116
004080FD  |.  A1 08934000   mov     eax, dword ptr [409308]
00408102  |.  BA 2C814000   mov     edx, 0040812C                    ;  ASCII "Hello World"
00408107  |.  E8 48BDFFFF   call    00403E54
0040810C  |.  E8 07ABFFFF   call    00402C18
00408111  |.  E8 16A5FFFF   call    0040262C

关系运算 > 时
if Size > 100 then
       begin
           Writeln('Hello World');
       end;

004080F4  |.  833D 98924000>cmp     dword ptr [409298], 64
004080FB  |.  7E 19         jle     short 00408116
004080FD  |.  A1 08934000   mov     eax, dword ptr [409308]
00408102  |.  BA 2C814000   mov     edx, 0040812C                    ;  ASCII "Hello World"
00408107  |.  E8 48BDFFFF   call    00403E54
0040810C  |.  E8 07ABFFFF   call    00402C18
00408111  |.  E8 16A5FFFF   call    0040262C

关系运算 <= 时
004080F4  |.  833D 98924000>cmp     dword ptr [409298], 64
004080FB  |.  7F 19         jg      short 00408116
004080FD  |.  A1 08934000   mov     eax, dword ptr [409308]
00408102  |.  BA 2C814000   mov     edx, 0040812C                    ;  ASCII "Hello World"
00408107  |.  E8 48BDFFFF   call    00403E54
0040810C  |.  E8 07ABFFFF   call    00402C18
00408111  |.  E8 16A5FFFF   call    0040262C

[源]
if Size <= 100 then
       begin
           Writeln('Hello World');
       end;

关系运算 >= 时
004080F4  |.  833D 98924000>cmp     dword ptr [409298], 64
004080FB  |.  7C 19         jl      short 00408116
004080FD  |.  A1 08934000   mov     eax, dword ptr [409308]
00408102  |.  BA 2C814000   mov     edx, 0040812C                    ;  ASCII "Hello World"
00408107  |.  E8 48BDFFFF   call    00403E54
0040810C  |.  E8 07ABFFFF   call    00402C18
00408111  |.  E8 16A5FFFF   call    0040262C

[源]
if Size >= 100 then
       begin
           Writeln('Hello World');
       end;

对单个字符取地址,并递增
00407C68  |.  C705 9C974000>mov     dword ptr [40979C], 00408294
00407C72  |.  FF05 9C974000 inc     dword ptr [40979C]
[源]
szcChar := @ccc;
szcChar := szcChar + 1;  

取回原指针指向的内容
00407C68  |.  C705 9C974000>mov     dword ptr [40979C], 00408294
00407C72  |.  A1 9C974000   mov     eax, dword ptr [40979C]
00407C77  |.  A3 9C974000   mov     dword ptr [40979C], eax

00407C7C  |.  A1 9C974000   mov     eax, dword ptr [40979C]
00407C81  |.  8A00          mov     al, byte ptr [eax]   //由于是字符指针,所以是byte(8)
00407C83  |.  A2 98824000   mov     byte ptr [408298], al
[源]
szcChar := @ccc;
szcChar := szcChar;    
ccb := szcChar^;  //取内容   

不同赋值类型的反汇编。
整数
00407C68  |.  C705 94824000>mov     dword ptr [408294], 11D7

[源]
rel := 4567;  

字符, 布尔, 浮点, 
00407C68  |.  C605 94824000>mov     byte ptr [408294], 1
00407C6F  |.  C605 98824000>mov     byte ptr [408298], 34
00407C76  |.  C705 9C974000>mov     dword ptr [40979C], CCCCCCCD  //0.
00407C80  |.  C705 A0974000>mov     dword ptr [4097A0], 3FDCCCCC  //45
[源]
 tBool:= True;
 ccc  := '4';
 tReal:= 0.45;   

为一个字符串赋值
00407C68  |.  B8 9C974000   mov     eax, 0040979C
00407C6D  |.  BA 8C7C4000   mov     edx, 00407C8C                    ;  ASCII "Hello World"
00407C72  |.  E8 D1B9FFFF   call    00403648//调用此函数是在为字符传赋值.
为字符传赋值要使用两个地址。

批量对string进行赋值并没有变化指令
00407C8C  |.  B8 94824000   mov     eax, 00408294                    ;要填充的字符串变量地址
00407C91  |.  BA CC7C4000   mov     edx, 00407CCC                    ;  ASCII "Hello World"
00407C96  |.  E8 ADB9FFFF   call    00403648
00407C9B  |.  B8 98824000   mov     eax, 00408298
00407CA0  |.  BA E07C4000   mov     edx, 00407CE0                    ;  ASCII "Beijing"
00407CA5  |.  E8 9EB9FFFF   call    00403648
00407CAA  |.  B8 9C824000   mov     eax, 0040829C
00407CAF  |.  BA F07C4000   mov     edx, 00407CF0                    ;  ASCII "GuNiang"
00407CB4  |.  E8 8FB9FFFF   call    00403648
[源]
szStrN := 'Hello World';
       szStrA := 'Beijing';
       szStrZ := 'GuNiang';

拼接两个字符串
00407D00  |.  B8 94824000   mov     eax, 00408294
00407D05  |.  BA 487D4000   mov     edx, 00407D48                    ;  ASCII "Hello World"
00407D0A  |.  E8 39B9FFFF   call    00403648
00407D0F  |.  B8 98824000   mov     eax, 00408298
00407D14  |.  BA 5C7D4000   mov     edx, 00407D5C                    ;  ASCII "Beijing"
00407D19  |.  E8 2AB9FFFF   call    00403648
00407D1E  |.  B8 9C824000   mov     eax, 0040829C
00407D23  |.  8B0D 98824000 mov     ecx, dword ptr [408298]          ;  heloMain.00407CE8
00407D29  |.  8B15 94824000 mov     edx, dword ptr [408294]          ;  heloMain.00407CDC
00407D2F  |.  E8 80BBFFFF   call    004038B4

[源]
szStrN := 'Hello World';
       szStrA := 'Beijing';
       szStrZ :=  szStrN + szStrA;

(2)二 第二部分 流程控制, 循环, 对象, 类型, 结构等。
条件分支语句, if .... then 
00408118  |.  833D 98924000>cmp     dword ptr [409298], 0
0040811F  |.  74 19         je      short 0040813A
00408121  |.  A1 14934000   mov     eax, dword ptr [409314]
00408126  |.  BA 50814000   mov     edx, 00408150                    ;  ASCII "Hello World"
0040812B  |.  E8 24BDFFFF   call    00403E54
00408130  |.  E8 E3AAFFFF   call    00402C18
00408135  |.  E8 F2A4FFFF   call    0040262C
[源]
if rel <> 0 then
       begin
          Writeln('Hello World');
       end;

条件分支语句, if ... then ... else
00408118  |.  833D 98924000>cmp     dword ptr [409298], 0
0040811F  |.  74 1B         je      short 0040813C
00408121  |.  A1 14934000   mov     eax, dword ptr [409314]
00408126  |.  BA 68814000   mov     edx, 00408168                    ;  ASCII "Hello World"
0040812B  |.  E8 24BDFFFF   call    00403E54
00408130  |.  E8 E3AAFFFF   call    00402C18
00408135  |.  E8 F2A4FFFF   call    0040262C
0040813A  |.  EB 19         jmp     short 00408155
0040813C  |>  A1 14934000   mov     eax, dword ptr [409314]
00408141  |.  BA 68814000   mov     edx, 00408168                    ;  ASCII "Hello World"
00408146  |.  E8 09BDFFFF   call    00403E54
0040814B  |.  E8 C8AAFFFF   call    00402C18
00408150  |.  E8 D7A4FFFF   call    0040262C
[源]
if rel <> 0 then
       begin
          Writeln('Hello World');
       end
       else
       begin
          Writeln('Hello World');
       end;

条件分支语句 if ... then ...  else if     then  .... else
00408118  |.  833D 98924000>cmp     dword ptr [409298], 0
0040811F  |.  74 1B         je      short 0040813C
00408121  |.  A1 14934000   mov     eax, dword ptr [409314]
00408126  |.  BA 8C814000   mov     edx, 0040818C                    ;  ASCII "Hello World"
0040812B  |.  E8 24BDFFFF   call    00403E54
00408130  |.  E8 E3AAFFFF   call    00402C18
00408135  |.  E8 F2A4FFFF   call    0040262C
0040813A  |.  EB 3D         jmp     short 00408179

0040813C  |>  833D 98924000>cmp     dword ptr [409298], 0
00408143  |.  75 1B         jnz     short 00408160
00408145  |.  A1 14934000   mov     eax, dword ptr [409314]
0040814A  |.  BA 8C814000   mov     edx, 0040818C                    ;  ASCII "Hello World"
0040814F  |.  E8 00BDFFFF   call    00403E54
00408154  |.  E8 BFAAFFFF   call    00402C18
00408159  |.  E8 CEA4FFFF   call    0040262C
0040815E  |.  EB 19         jmp     short 00408179

00408160  |>  A1 14934000   mov     eax, dword ptr [409314]
00408165  |.  BA 8C814000   mov     edx, 0040818C                    ;  ASCII "Hello World"
0040816A  |.  E8 E5BCFFFF   call    00403E54
0040816F  |.  E8 A4AAFFFF   call    00402C18
00408174  |.  E8 B3A4FFFF   call    0040262C

[源]
if rel <> 0 then
       begin
          Writeln('Hello World');
       end
       else if rel = 0 then
       begin
          Writeln('Hello World');
       end
       else
       begin
          Writeln('Hello World');
       end;

多分支语句 case ....  of  .... end;
00407C8C  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C91  |.  83E8 01       sub     eax, 1                           ;  Switch (cases 0..1)
00407C94  |.  72 04         jb      short 00407C9A
00407C96  |.  74 17         je      short 00407CAF
00407C98  |.  EB 28         jmp     short 00407CC2
00407C9A  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Case 0 of switch 00407C91
00407C9C  |.  68 D07C4000   push    00407CD0                         ; |Title = "ggg"
00407CA1  |.  68 D47C4000   push    00407CD4                         ; |Text = "0000"
00407CA6  |.  6A 00         push    0                                ; |hOwner = NULL
00407CA8  |.  E8 BBC8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00407CAD  |.  EB 13         jmp     short 00407CC2
00407CAF  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Case 1 of switch 00407C91
00407CB1  |.  68 D07C4000   push    00407CD0                         ; |Title = "ggg"
00407CB6  |.  68 DC7C4000   push    00407CDC                         ; |Text = "8899"
00407CBB  |.  6A 00         push    0                                ; |hOwner = NULL
00407CBD  |.  E8 A6C8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA

[源]


       case Size of
          0: 
            MessageBox(0, '0000', 'ggg', 0);
          1:
            MessageBox(0, '8899', 'ggg', 0);
       end;

对多分支加了一个else
00407C8C  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C91  |.  83E8 01       sub     eax, 1                           ;  Switch (cases 0..1)
00407C94  |.  72 04         jb      short 00407C9A
00407C96  |.  74 17         je      short 00407CAF
00407C98  |.  EB 2A         jmp     short 00407CC4
00407C9A  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Case 0 of switch 00407C91
00407C9C  |.  68 E47C4000   push    00407CE4                         ; |Title = "ggg"
00407CA1  |.  68 E87C4000   push    00407CE8                         ; |Text = "0000"
00407CA6  |.  6A 00         push    0                                ; |hOwner = NULL
00407CA8  |.  E8 BBC8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00407CAD  |.  EB 28         jmp     short 00407CD7
00407CAF  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Case 1 of switch 00407C91
00407CB1  |.  68 E47C4000   push    00407CE4                         ; |Title = "ggg"
00407CB6  |.  68 F07C4000   push    00407CF0                         ; |Text = "8899"
00407CBB  |.  6A 00         push    0                                ; |hOwner = NULL
00407CBD  |.  E8 A6C8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00407CC2  |.  EB 13         jmp     short 00407CD7
00407CC4  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Default case of switch 00407C91
00407CC6  |.  68 E47C4000   push    00407CE4                         ; |Title = "ggg"
00407CCB  |.  68 F87C4000   push    00407CF8                         ; |Text = "78No"
00407CD0  |.  6A 00         push    0                                ; |hOwner = NULL
00407CD2  |.  E8 91C8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA

[源]
case Size of
          0: 
            MessageBox(0, '0000', 'ggg', 0);
          1:
            MessageBox(0, '8899', 'ggg', 0);
       else
            MessageBox(0, '78No', 'ggg', 0);
       end;

多分支加了 case = 2
00407C8C  |.  A1 94824000   mov     eax, dword ptr [408294]
00407C91  |.  83E8 01       sub     eax, 1                           ;  Switch (cases 0..2)
00407C94  |.  72 07         jb      short 00407C9D
00407C96  |.  74 1A         je      short 00407CB2
00407C98  |.  48            dec     eax
00407C99  |.  74 2C         je      short 00407CC7
00407C9B  |.  EB 3F         jmp     short 00407CDC
00407C9D  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Case 0 of switch 00407C91
00407C9F  |.  68 FC7C4000   push    00407CFC                         ; |Title = "ggg"
00407CA4  |.  68 007D4000   push    00407D00                         ; |Text = "0000"
00407CA9  |.  6A 00         push    0                                ; |hOwner = NULL
00407CAB  |.  E8 B8C8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00407CB0  |.  EB 3D         jmp     short 00407CEF
00407CB2  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Case 1 of switch 00407C91
00407CB4  |.  68 FC7C4000   push    00407CFC                         ; |Title = "ggg"
00407CB9  |.  68 087D4000   push    00407D08                         ; |Text = "8899"
00407CBE  |.  6A 00         push    0                                ; |hOwner = NULL
00407CC0  |.  E8 A3C8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00407CC5  |.  EB 28         jmp     short 00407CEF
00407CC7  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Case 2 of switch 00407C91
00407CC9  |.  68 FC7C4000   push    00407CFC                         ; |Title = "ggg"
00407CCE  |.  68 107D4000   push    00407D10                         ; |Text = "2222"
00407CD3  |.  6A 00         push    0                                ; |hOwner = NULL
00407CD5  |.  E8 8EC8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00407CDA  |.  EB 13         jmp     short 00407CEF
00407CDC  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL; Default case of switch 00407C91
00407CDE  |.  68 FC7C4000   push    00407CFC                         ; |Title = "ggg"
00407CE3  |.  68 187D4000   push    00407D18                         ; |Text = "78No"
00407CE8  |.  6A 00         push    0                                ; |hOwner = NULL
00407CEA  |.  E8 79C8FFFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA


//函数参数传递字符串问题, 这种形态对我来说, 逆向很是恼火。
直接填充函数参数一个串则为这种情形
00407C9C  /$  B8 AC7C4000   mov     eax, 00407CAC ;只通过一个eax, 得到一个临时变量区的地址来传递
00407CA1  |.  E8 F2FFFFFF   call    00407C98
[源]
test('6'); 
//而利用全局变量(存储器)进行中转的则为这种形态
00407C94  |.  A1 A0824000   mov     eax, dword ptr [4082A0]
00407C99  |.  E8 EAFFFFFF   call    00407C88
[源]
Init_funcStr(b);              
//其中函数Init_funcStr和test的参数都是一个PChar类型, 并且没有加var, 因为加了var表示是一个引用,在内部就可以修改外部了。
//当反汇编看到
00407C9C  /$  B8 AC7C4000   mov     eax, 00407CAC ;只通过一个eax, 得到一个临时变量区的地址来传递
00407CA1  |.  E8 F2FFFFFF   call    00407C98
这种情形时就一定要想到 字符串一定是直接在实参部分写的, 而不是通过全局变量, 或局变量中转的。
//在局部变量(存储器)进行中转为
00407C90  |.  B8 A87C4000   mov     eax, 00407CA8                    ;  ASCII "0 :"
00407C95  |.  E8 EAFFFFFF   call    00407C84
[源]
szaBuf := '0 :';     
Init_funcStr(szaBuf);        


问题出现了, 利用局部变量和直接在函数实参数写为什么一样呢? 因为 都是利用堆栈临时填充的,也就是把串是存放在栈内。
00407C90  |.  B8 A87C4000   mov     eax, 00407CA8                    ;  ASCII "0 :"
00407C95  |.  E8 EAFFFFFF   call    00407C84
//看, 在同一个函数内, 直接在实参写串, 和利用临时变量转产生的是一样的。而
00407C9C  /$  B8 AC7C4000   mov     eax, 00407CAC ;只通过一个eax, 得到一个临时变量区的地址来传递
00407CA1  |.  E8 F2FFFFFF   call    00407C98  //这个之所以和上面的不一样是因为在不同的程序,不同的函数名编译的结果。
但是这里我们只关注 mov eax, <xxxxxx>  右操作数的形态, 不是存储器操作数就好, 要一个立即数的地址。

现在才刚刚开始, 更多逆向还在后面。

三、 高级情形, RTTI, 其他情形。

行1985:  #########################################

上面大部分就是我反的并记录的笔记。

可是后来当试到PChar时, 发现和
00407C9C  /$  B8 AC7C4000   mov     eax, 00407CAC ;
00407CA1  |.  E8 F2FFFFFF   call    00407C98
这两句很类似了, 只不过我反出来的形态是这样的。
00407C94  |.  A1 A0824000   mov     eax, dword ptr [4082A0]
00407C99  |.  E8 EAFFFFFF   call    00407C88
也就是eax, 这行的操作数不对, 用过汇编的知道,很明显 dword ptr [4082A0]是个存储器操作数。
也就是说这个操作数是个变量。 而我要反的是个立即数,根据一些反汇编的经验,可以推测
这个立即数就是个地址。

于是我就想不是PChar类型的吧, 得到

00407C94  |.  A1 A0824000   mov     eax, dword ptr [4082A0]
00407C99  |.  E8 EAFFFFFF   call    00407C88
我是类似这么写的

var szBuf : PChar = '0 :';

function NewTestFunc(a : PChar):Integer;
begin
       result := 0;       
end;

funciton WinMain();stdcall;
begin
      NewTestFunc(szBuf);      
      result := 0;
end;

这句 NewTestFunc(szBuf);       反出来就是
00407C94  |.  A1 A0824000   mov     eax, dword ptr [4082A0]
00407C99  |.  E8 EAFFFFFF   call    00407C88    相似的。
于是我又换成string类型的, 但是反出来还是不对。 

后来还是试PChar, 因为我感觉就是操作数问题, 就是可能要变化变化。
于是不知怎么的, 我把调用方式改变了一下。 从NewTestFunc(szBuf)
改为 NewTestFunc('0 ');, 于是形态就正确了。

于是才联想起来由于直接写的 变量要放在堆栈内,所以只需要个地址就可以了。
而我再单独申请个局部变量然后在赋值后, 和直接写实参也一样, 好就到这, 这么反出来
工作量大些毕竟没多少经验, 但是逆出来两句也很高兴。