逆向工程日记2--WINDOWS优化大师

来源:互联网 发布:硬盘检测软件 编辑:程序博客网 时间:2024/04/30 09:55

 

    前一段时间破解了WINDOWS优化大师,并写BLOG文在qq空间里。但是这篇文章总的来说算是暴力破解——修改原程序绕过序列号校验的代码,达到注册的目的。最近为了锻炼功力决定把它的注册算法逆向出来。说干就干。  我逆向的版本号是7.86.8.1105。
    WINDOWS优化大师是用DEPHI写的,用DEDE分析可以得到注册按钮的入口地址0062196C,在OD里下断点。结合DEDE进行分析一路跟踪到这里
00621C33   E8F077FAFF             call    005C9428
00621C38   3DB2000000             cmp     eax, $000000B2
这里调用一个函数,然后让EAX和0xB2进行比较,如果相等则注册成功。进入函数005C9428查看,DEDE的分析结果是:
005C9428   8BC8                   mov     ecx, eax
005C942A   B201                   mov     dl, $01
* Reference to class TBig5RegChkThread
|
005C942C   A1488F5C00             mov     eax, dword ptr [$005C8F48]
|
005C9431   E8C60A0000             call    005C9EFC
005C9436   8B15406F7500           mov     edx, [$00756F40]
005C943C   8B12                   mov     edx, [edx]
* Reference to field TBig5RegChkThread.OFFS_001C
|
005C943E   89501C                 mov     [eax+$1C], edx
* Reference to field TBig5RegChkThread.OFFS_0018
|
005C9441   C7401814EB6F00         mov     dword ptr [eax+$18], $006FEB14
005C9448   C605BCC2760001         mov     byte ptr [$0076C2BC], $01
* Reference to: Classes.TThread.Resume(TThread);
|
005C944F   E8E81AE6FF             call    0042AF3C
005C9454   B8E8030000             mov     eax, $000003E8
|
005C9459   E8EEA5E3FF             call    00403A4C
005C945E   A10C6F7500             mov     eax, dword ptr [$00756F0C]
005C9463   8B00                   mov     eax, [eax]
* Reference to: ActnMenus.TCustomActionMenuBar.ProcessMessages(TCustomActionMenuBar);
|           or: Forms.TApplication.ProcessMessages(TApplication);
|
005C9465   E88ECFECFF             call    004963F8
005C946A   803DBCC2760000         cmp     byte ptr [$0076C2BC], $00
005C9471   75E1                   jnz     005C9454
005C9473   A1C0C27600             mov     eax, dword ptr [$0076C2C0]
005C9478   C3                     ret
该函数启动一个线程计算注册码,然后把结果放在地址0076C2C0处,也就是说,如果最后的计算结果是0XB2的话,则注册成功。
    继续逆流而上。在0076C2C0下内存写入断点,竟然断不了?那就是注册不成功,则不执行对该地址的写入操作。想点别的办法。查找命令MOV DWORD PTR DS:[76C2C0],0B2, 找到下列地址中有该函数
5CA312
5CA383
5CA3F4
5CA474
5CA4F8
5CA544
(这里还有个小技巧,也不知道是我笨,还是OD的功能所限,查找MOV DWORD PTR DS:[76C2C0],0B2指令时,查找到的总是第一个指令,无法查找下一条指令, 没办法,只能先把找到的指令改成别的,比如MOV DWORD PTR DS:[76C2C0],0B1,然后继续查找,就会找到下一条MOV DWORD PTR DS:[76C2C0],0B2。)
发现它们统统在一个函数调用里面。那十之八九就是计算注册码的线程函数了。该函数的起始地址是5C9F88 , 用OD跟踪上几遍就会发现起运行步骤:
1. 这个函数是先把注册字符串转换成十六进制16字节,即取注册字符串的前32有效字符字符。(把非0-9,A-F的字符全部滤去)。
2. 通过一定的运算计算出16个字节的数据,再把该16字节数据转换成长度为32的字符串。
3. 取该字符串后16位与一个固定字符串进行比较,如果相等,则注册成功,否则注册失败。
    如果要用暴力破解的话,直接把判断是否注册成功的语句改掉就ok了。其实很简单。但我现在的目的是不改动原来的持续,而要把它正确的注册码算出来。接下来的关键就是看步骤2中的加密算法了。
005CA219   > /8D4D C0       LEA ECX,DWORD PTR SS:[EBP-40]
005CA21C   .  8D55 D0       LEA EDX,DWORD PTR SS:[EBP-30]
005CA21F   .  8D85 F0FEFFFF LEA EAX,DWORD PTR SS:[EBP-110]
005CA225   .  E8 3ED9FCFF   CALL WoptiUti.00597B68
在此调用了该加密算法,即函数00597B68。ECX是输入参数,EDX是输出参数,EAX可以认为是加密密钥,每次都是不变。进入函数体内,可以看到
00597B68  /$  53            PUSH EBX
00597B69  |.  56            PUSH ESI
00597B6A  |.  57            PUSH EDI
00597B6B  |.  55            PUSH EBP
00597B6C  |.  83C4 EC       ADD ESP,-14
00597B6F  |.  890C24        MOV DWORD PTR SS:[ESP],ECX
00597B72  |.  8BDA          MOV EBX,EDX
00597B74  |.  8BF8          MOV EDI,EAX
00597B76  |.  8D5424 04     LEA EDX,DWORD PTR SS:[ESP+4]
00597B7A  |.  8BC3          MOV EAX,EBX
00597B7C  |.  B9 04000000   MOV ECX,4
00597B81  |.  E8 C6B5E6FF   CALL WoptiUti.0040314C
00597B86  |.  8D5424 08     LEA EDX,DWORD PTR SS:[ESP+8]
00597B8A  |.  8BF3          MOV ESI,EBX
00597B8C  |.  8BC6          MOV EAX,ESI
00597B8E  |.  83C0 04       ADD EAX,4
00597B91  |.  B9 04000000   MOV ECX,4
00597B96  |.  E8 B1B5E6FF   CALL WoptiUti.0040314C
00597B9B  |.  8D5424 0C     LEA EDX,DWORD PTR SS:[ESP+C]
00597B9F  |.  8BC6          MOV EAX,ESI
00597BA1  |.  83C0 08       ADD EAX,8
00597BA4  |.  B9 04000000   MOV ECX,4
00597BA9  |.  E8 9EB5E6FF   CALL WoptiUti.0040314C
00597BAE  |.  8D5424 10     LEA EDX,DWORD PTR SS:[ESP+10]
00597BB2  |.  8BC6          MOV EAX,ESI
00597BB4  |.  83C0 0C       ADD EAX,0C
00597BB7  |.  B9 04000000   MOV ECX,4
00597BBC  |.  E8 8BB5E6FF   CALL WoptiUti.0040314C
00597BC1  |.  8B87 CC000000 MOV EAX,DWORD PTR DS:[EDI+CC]
00597BC7  |.  294424 0C     SUB DWORD PTR SS:[ESP+C],EAX
00597BCB  |.  8B87 C8000000 MOV EAX,DWORD PTR DS:[EDI+C8]
00597BD1  |.  294424 04     SUB DWORD PTR SS:[ESP+4],EAX
00597BD5  |.  BE 14000000   MOV ESI,14
00597BDA  |>  8B5C24 04     /MOV EBX,DWORD PTR SS:[ESP+4]
00597BDE  |.  8B4424 10     |MOV EAX,DWORD PTR SS:[ESP+10]
00597BE2  |.  894424 04     |MOV DWORD PTR SS:[ESP+4],EAX
00597BE6  |.  8B4424 0C     |MOV EAX,DWORD PTR SS:[ESP+C]
00597BEA  |.  894424 10     |MOV DWORD PTR SS:[ESP+10],EAX
00597BEE  |.  8B4424 08     |MOV EAX,DWORD PTR SS:[ESP+8]
00597BF2  |.  894424 0C     |MOV DWORD PTR SS:[ESP+C],EAX
00597BF6  |.  895C24 08     |MOV DWORD PTR SS:[ESP+8],EBX
00597BFA  |.  8B4424 10     |MOV EAX,DWORD PTR SS:[ESP+10]
00597BFE  |.  03C0          |ADD EAX,EAX
00597C00  |.  40            |INC EAX
00597C01  |.  F76C24 10     |IMUL DWORD PTR SS:[ESP+10]
00597C05  |.  BA 05000000   |MOV EDX,5
00597C0A  |.  E8 D5FBFFFF   |CALL WoptiUti.005977E4
00597C0F  |.  8BE8          |MOV EBP,EAX
00597C11  |.  8B4424 08     |MOV EAX,DWORD PTR SS:[ESP+8]
00597C15  |.  03C0          |ADD EAX,EAX
00597C17  |.  40            |INC EAX
00597C18  |.  F76C24 08     |IMUL DWORD PTR SS:[ESP+8]
00597C1C  |.  BA 05000000   |MOV EDX,5
00597C21  |.  E8 BEFBFFFF   |CALL WoptiUti.005977E4
00597C26  |.  8BD8          |MOV EBX,EAX
00597C28  |.  8BC6          |MOV EAX,ESI
00597C2A  |.  03C0          |ADD EAX,EAX
00597C2C  |.  FF7487 24     |PUSH DWORD PTR DS:[EDI+EAX*4+24]
00597C30  |.  8B4424 10     |MOV EAX,DWORD PTR SS:[ESP+10]
00597C34  |.  5A            |POP EDX
00597C35  |.  2BC2          |SUB EAX,EDX
00597C37  |.  8BD3          |MOV EDX,EBX
00597C39  |.  E8 BAFBFFFF   |CALL WoptiUti.005977F8
00597C3E  |.  33C5          |XOR EAX,EBP
00597C40  |.  894424 0C     |MOV DWORD PTR SS:[ESP+C],EAX
00597C44  |.  8BC6          |MOV EAX,ESI
00597C46  |.  03C0          |ADD EAX,EAX
00597C48  |.  FF7487 20     |PUSH DWORD PTR DS:[EDI+EAX*4+20]
00597C4C  |.  8B4424 08     |MOV EAX,DWORD PTR SS:[ESP+8]
00597C50  |.  5A            |POP EDX
00597C51  |.  2BC2          |SUB EAX,EDX
00597C53  |.  8BD5          |MOV EDX,EBP
00597C55  |.  E8 9EFBFFFF   |CALL WoptiUti.005977F8
00597C5A  |.  33D8          |XOR EBX,EAX
00597C5C  |.  895C24 04     |MOV DWORD PTR SS:[ESP+4],EBX
00597C60  |.  4E            |DEC ESI
00597C61  |.  85F6          |TEST ESI,ESI
00597C63  |.^ 0F85 71FFFFFF /JNZ WoptiUti.00597BDA
00597C69  |.  8B47 24       MOV EAX,DWORD PTR DS:[EDI+24]
00597C6C  |.  294424 10     SUB DWORD PTR SS:[ESP+10],EAX
00597C70  |.  8B47 20       MOV EAX,DWORD PTR DS:[EDI+20]
00597C73  |.  294424 08     SUB DWORD PTR SS:[ESP+8],EAX
00597C77  |.  8B1424        MOV EDX,DWORD PTR SS:[ESP]
00597C7A  |.  8D4424 04     LEA EAX,DWORD PTR SS:[ESP+4]
00597C7E  |.  B9 04000000   MOV ECX,4
00597C83  |.  E8 C4B4E6FF   CALL WoptiUti.0040314C
00597C88  |.  8B1C24        MOV EBX,DWORD PTR SS:[ESP]
00597C8B  |.  8BD3          MOV EDX,EBX
00597C8D  |.  83C2 04       ADD EDX,4
00597C90  |.  8D4424 08     LEA EAX,DWORD PTR SS:[ESP+8]
00597C94  |.  B9 04000000   MOV ECX,4
00597C99  |.  E8 AEB4E6FF   CALL WoptiUti.0040314C
00597C9E  |.  8BD3          MOV EDX,EBX
00597CA0  |.  83C2 08       ADD EDX,8
00597CA3  |.  8D4424 0C     LEA EAX,DWORD PTR SS:[ESP+C]
00597CA7  |.  B9 04000000   MOV ECX,4
00597CAC  |.  E8 9BB4E6FF   CALL WoptiUti.0040314C
00597CB1  |.  8BD3          MOV EDX,EBX
00597CB3  |.  83C2 0C       ADD EDX,0C
00597CB6  |.  8D4424 10     LEA EAX,DWORD PTR SS:[ESP+10]
00597CBA  |.  B9 04000000   MOV ECX,4
00597CBF  |.  E8 88B4E6FF   CALL WoptiUti.0040314C
00597CC4  |.  83C4 14       ADD ESP,14
00597CC7  |.  5D            POP EBP
00597CC8  |.  5F            POP EDI
00597CC9  |.  5E            POP ESI
00597CCA  |.  5B            POP EBX
00597CCB  /.  C3            RETN
这就是WINDOWS优化大师核心的注册算法。其中里面调用了一些函数,点进去看看,其实很简单。
CALL 0040314C是内存copy函数。
CALL 005977E4是循环左移位,完全可以用ROL指令替换。
CALL 005977F8是循环右移位,完全可以用ROR指令替换。
OK,用OD把上面函数的反汇编结果转换成汇编代码并把用到的内存数据copy出来,经过调试就是得到一段内嵌汇编的c代码(一开始还想用高级语言重写一下的,后来一想还是直接来汇编的方便。)
运行一下,再和OD中的加密算法出来的结果对比,一样样的,OK。下面开始写逆运算,为了验证逆运算的有效性,我把逆向运算的代码写在注册运算代码之后,也就是说运行完注册算法后立刻运行逆注册运算,看结果和注册之前一样不一样。记过了几番调试,最终的代码如下:
int PassWord[4]  = {0x78563412, 0xEFCDAB90, 0x78563412, 0xEFCDAB90};
BYTE data[] =
{
0xA9, 0x8E, 0xA2, 0x84, 0x5B, 0x08, 0x78, 0x5F, 0xE6, 0xD9, 0x9E, 0x1A, 0x69, 0xD0, 0xBC, 0x4D,
0xCE, 0xEA, 0xA1, 0xD3, 0xEF, 0x63, 0x2D, 0x4A, 0x20, 0x0A, 0x4E, 0xCF, 0xAF, 0xFC, 0xB2, 0xA6,
0x88, 0xA1, 0xB0, 0xC9, 0xA3, 0xB9, 0xC3, 0xE1, 0x7B, 0xBB, 0x96, 0x8B, 0x2F, 0x4F, 0xC4, 0xE6,
0x60, 0x7B, 0xCE, 0x8A, 0x11, 0xB4, 0x11, 0x4F, 0xC3, 0xB8, 0x26, 0x72, 0x25, 0x06, 0x35, 0xB1,
0x33, 0x61, 0x41, 0x00, 0x64, 0xD4, 0x4E, 0xD5, 0x9A, 0x42, 0x43, 0xDD, 0x7B, 0xD3, 0x25, 0xF7,
0x8F, 0x38, 0x85, 0x67, 0xDA, 0x41, 0xFB, 0x84, 0xA7, 0x15, 0x5A, 0x62, 0x7A, 0x6F, 0x14, 0x99,
0x36, 0x46, 0x90, 0x90, 0x23, 0xAC, 0x1C, 0x1B, 0x46, 0x81, 0x22, 0xC6, 0x7D, 0xE9, 0x0B, 0x6B,
0x37, 0x67, 0x5B, 0x4B, 0x4C, 0x69, 0xC1, 0x7D, 0xD4, 0x2C, 0x34, 0x1B, 0x6E, 0xC3, 0x17, 0xFD,
0xEF, 0x04, 0x55, 0x86, 0x6C, 0x31, 0xE5, 0x36, 0x3A, 0xA5, 0x63, 0x62, 0x13, 0xA3, 0xDE, 0x73,
0xFA, 0x9A, 0x6E, 0x28, 0x77, 0xF2, 0x69, 0xD3, 0x5C, 0x0E, 0xA4, 0x8D, 0x33, 0xE9, 0x9F, 0xEE,
0xB1, 0xEB, 0xA7, 0xC6, 0xE9, 0x2C, 0x91, 0x30, 0x14, 0xD8, 0xC6, 0x7F, 0x29, 0xE1, 0xD7, 0xB1,
};
void main()
{
__asm
{
      push ebp
   sub  esp, 20
   mov  edi, offset data
   mov     eax, 0x78563412
   mov  [esp+4], eax
   mov     eax, 0xEFCDAB90
   mov  [esp+8], eax
   mov     eax, 0x78563412
   mov  [esp+0xc], eax
   mov     eax, 0xEFCDAB90
   mov  [esp+0x10], eax
  
   mov     eax, 0xB1D7E129
   sub     dword ptr [esp+0xc], eax
   mov     eax, 0x7FC6D814;
   sub     dword ptr [esp+4], eax
   mov     esi, 0x14
L005:
   mov     ebx, dword ptr [esp+4]
   mov     eax, dword ptr [esp+0x10]
   mov     dword ptr [esp+4], eax
   mov     eax, dword ptr [esp+0xc]
   mov     dword ptr [esp+0x10], eax
   mov     eax, dword ptr [esp+8]
   mov     dword ptr [esp+0xc], eax
   mov     dword ptr [esp+8], ebx
   mov     eax, dword ptr [esp+0x10]
   add     eax, eax
   inc     eax
   imul    dword ptr [esp+0x10]
   mov     edx, 5
   mov  ecx, edx
   rol     eax, cl
   mov     ebp, eax
   mov     eax, dword ptr [esp+8]
   add     eax, eax
   inc     eax
   imul    dword ptr [esp+8]
   mov     edx, 5
   mov  ecx, edx
   rol     eax, cl
   mov     ebx, eax
   mov     eax, esi
   add     eax, eax
   push    dword ptr [edi+eax*4+0x4]
   mov     eax, dword ptr [esp+0x10]
   pop     edx
   sub     eax, edx
   mov     edx, ebx
   mov  ecx, edx
   ror     eax, cl
   xor     eax, ebp
   mov     dword ptr [esp+0xc], eax
   mov     eax, esi
   add     eax, eax
   push    dword ptr [edi+eax*4]
   mov     eax, dword ptr [esp+8]
   pop     edx
   sub     eax, edx
   mov     edx, ebp
   mov  ecx, edx
   ror     eax, cl
   xor     ebx, eax
   mov     dword ptr [esp+4], ebx
   dec     esi
   test    esi, esi
   jnz L005
   mov eax, dword ptr[edi + 4]
   sub dword ptr[esp + 0x10], eax
   mov eax, dword ptr[edi]
   sub dword ptr[esp + 8], eax
   ;reverse
   mov eax, dword ptr[edi]
   add dword ptr[esp + 8], eax
   mov eax, dword ptr[edi + 4]
   add dword ptr[esp + 0x10], eax
   mov esi, 0
L006:
   inc esi
   mov     eax, dword ptr [esp+0x10]
   add     eax, eax
   inc     eax
   imul    dword ptr [esp+0x10]
   mov     edx, 5
   mov  ecx, edx
   rol     eax, cl
   mov     ebp, eax
   mov     eax, dword ptr [esp+8]
   add     eax, eax
   inc     eax
   imul    dword ptr [esp+8]
   mov     edx, 5
   mov  ecx, edx
   rol     eax, cl
   mov     ebx, eax
-
   mov     eax, dword ptr [esp+0xc]
   xor     eax, ebp
   mov     edx, ebx
   mov  ecx, edx
   rol     eax, cl
   push     eax
   mov     eax, esi
   add     eax, eax
   push    dword ptr [edi+eax*4+0x4]
   pop     edx
   pop     eax
   add     eax, edx
   mov     dword ptr [esp+0xc], eax
   mov     eax, dword ptr [esp+4]
   xor     eax, ebx
   mov     edx, ebp
   mov  ecx, edx
   rol     eax, cl
   push    eax
   mov     eax, esi
   add     eax, eax
   push    dword ptr [edi+eax*4]
   pop     edx
   pop     eax
   add     eax, edx
   mov     dword ptr [esp+4], eax
   mov     ebx, dword ptr [esp+4]
   mov  eax, dword ptr [esp+8]
   mov  dword ptr [esp+4], eax
   mov eax, dword ptr [esp+0x0c]
   mov dword ptr [esp+8], eax
   mov eax, dword ptr [esp+0x10]
   mov dword ptr [esp+0xc], eax
   mov dword ptr [esp+0x10], ebx
   cmp esi, 0x14
   jnz L006
   mov     eax, 0xB1D7E129
   add     dword ptr [esp+0xc], eax
   mov     eax, 0x7FC6D814;
   add     dword ptr [esp+4], eax
   mov eax, dword ptr [esp+4]
   mov PassWord[0], eax
   mov eax, dword ptr [esp+8]
   mov PassWord[0] + 4, eax
  
   mov eax, dword ptr [esp+0x0c]
   mov PassWord[0] + 8, eax
  
   mov eax, dword ptr [esp+0x10]
   mov PassWord[0] + 0x0c, eax
   add esp, 20
   pop ebp
  }
}
;reverse 之后的即为逆向算法,最终的注册机代码如下:
int PassWord[4]  = {0};
BYTE data[] =
{
0xA9, 0x8E, 0xA2, 0x84, 0x5B, 0x08, 0x78, 0x5F, 0xE6, 0xD9, 0x9E, 0x1A, 0x69, 0xD0, 0xBC, 0x4D,
0xCE, 0xEA, 0xA1, 0xD3, 0xEF, 0x63, 0x2D, 0x4A, 0x20, 0x0A, 0x4E, 0xCF, 0xAF, 0xFC, 0xB2, 0xA6,
0x88, 0xA1, 0xB0, 0xC9, 0xA3, 0xB9, 0xC3, 0xE1, 0x7B, 0xBB, 0x96, 0x8B, 0x2F, 0x4F, 0xC4, 0xE6,
0x60, 0x7B, 0xCE, 0x8A, 0x11, 0xB4, 0x11, 0x4F, 0xC3, 0xB8, 0x26, 0x72, 0x25, 0x06, 0x35, 0xB1,
0x33, 0x61, 0x41, 0x00, 0x64, 0xD4, 0x4E, 0xD5, 0x9A, 0x42, 0x43, 0xDD, 0x7B, 0xD3, 0x25, 0xF7,
0x8F, 0x38, 0x85, 0x67, 0xDA, 0x41, 0xFB, 0x84, 0xA7, 0x15, 0x5A, 0x62, 0x7A, 0x6F, 0x14, 0x99,
0x36, 0x46, 0x90, 0x90, 0x23, 0xAC, 0x1C, 0x1B, 0x46, 0x81, 0x22, 0xC6, 0x7D, 0xE9, 0x0B, 0x6B,
0x37, 0x67, 0x5B, 0x4B, 0x4C, 0x69, 0xC1, 0x7D, 0xD4, 0x2C, 0x34, 0x1B, 0x6E, 0xC3, 0x17, 0xFD,
0xEF, 0x04, 0x55, 0x86, 0x6C, 0x31, 0xE5, 0x36, 0x3A, 0xA5, 0x63, 0x62, 0x13, 0xA3, 0xDE, 0x73,
0xFA, 0x9A, 0x6E, 0x28, 0x77, 0xF2, 0x69, 0xD3, 0x5C, 0x0E, 0xA4, 0x8D, 0x33, 0xE9, 0x9F, 0xEE,
0xB1, 0xEB, 0xA7, 0xC6, 0xE9, 0x2C, 0x91, 0x30, 0x14, 0xD8, 0xC6, 0x7F, 0x29, 0xE1, 0xD7, 0xB1,
};
void main()
{
__asm
{
      push ebp
   sub  esp, 20
   mov  edi, offset data
   mov  dword ptr[esp+4], 0x78563412   ;这个值可以随便填
   mov  dword ptr[esp+8], 0xEFCDAB90   ;这个值ye  可以随便填
   mov  dword ptr[esp+0x0c], 0x12d762c3
   mov  dword ptr[esp+0x010], 0x35a6b629
   ;reverse
   mov eax, dword ptr[edi]
   add dword ptr[esp + 8], eax
   mov eax, dword ptr[edi + 4]
   add dword ptr[esp + 0x10], eax
   mov esi, 0
L006:
   inc esi
   mov     eax, dword ptr [esp+0x10]
   add     eax, eax
   inc     eax
   imul    dword ptr [esp+0x10]
   mov     edx, 5
   mov  ecx, edx
   rol     eax, cl
   mov     ebp, eax
   mov     eax, dword ptr [esp+8]
   add     eax, eax
   inc     eax
   imul    dword ptr [esp+8]
   mov     edx, 5
   mov  ecx, edx
   rol     eax, cl
   mov     ebx, eax
   mov     eax, dword ptr [esp+0xc]
   xor     eax, ebp
   mov     edx, ebx
   mov  ecx, edx
   rol     eax, cl
   push     eax
   mov     eax, esi
   add     eax, eax
   push    dword ptr [edi+eax*4+0x4]
   pop     edx
   pop     eax
   add     eax, edx
   mov     dword ptr [esp+0xc], eax
   mov     eax, dword ptr [esp+4]
   xor     eax, ebx
   mov     edx, ebp
   mov  ecx, edx
   rol     eax, cl
   push    eax
   mov     eax, esi
   add     eax, eax
   push    dword ptr [edi+eax*4]
   pop     edx
   pop     eax
   add     eax, edx
   mov     dword ptr [esp+4], eax
   mov     ebx, dword ptr [esp+4]
   mov  eax, dword ptr [esp+8]
   mov  dword ptr [esp+4], eax
   mov eax, dword ptr [esp+0x0c]
   mov dword ptr [esp+8], eax
   mov eax, dword ptr [esp+0x10]
   mov dword ptr [esp+0xc], eax
   mov dword ptr [esp+0x10], ebx
   cmp esi, 0x14
   jnz L006
   mov     eax, 0xB1D7E129
   add     dword ptr [esp+0xc], eax
   mov     eax, 0x7FC6D814;
   add     dword ptr [esp+4], eax
   mov eax, dword ptr [esp+4]
   mov PassWord[0], eax
   mov eax, dword ptr [esp+8]
   mov PassWord[0] + 4, eax
  
   mov eax, dword ptr [esp+0x0c]
   mov PassWord[0] + 8, eax
  
   mov eax, dword ptr [esp+0x10]
   mov PassWord[0] + 0x0c, eax
   add esp, 20
   pop ebp
  
  }
  //运算得到的注册码为A282E03E56BB032CC418D93126F525C9
}
后记:前一段时间把优化大师暴力破解出来后,总觉得应该把它逆向出来才算是真本事。终于下定决心搞一把。每天利用下班吃完饭以后的时间搞,其实每天可能也就一两个小时的时间,第二天再接着搞,周末的时间多一些。有两天(不是连续的两天)发狠了,搞到快半夜两点了。第二天白天感觉还好,就是晚上就巨困,挺早就休息了。不过总体感觉是半夜的时候周遭比较安静,心可以静下来想问题。困难在于第二天要7点多起来上班,所以不能总这样。