高中物理课件是中学生学习物理之必备...
软件采用了次数限制使用超过三次,跳出提示注册的Nag并且打开官方网站要求注册,其次软件注册是计算一个本地机器码,根据本地机器码运算加密.
官方网站:http://www.flztgzsh.ys168.com/
高中物理课件全集(2005.08版),好像是在wwww.skycn.net或者是在华军下载的..
下边给出破解分析次数和Nag,还有注册分析流程...有错误之处谢谢指正.
1:罗列一下vb调用约定,有助于分析.2:分析VB调用一个SDK API(GetVolumeInformationA)过程来计算机器码和它的参数Unicode转变Ansi化,并且通MSVBVM60.DllFunctionCall调用SDK API. 3:分析破解次数流程和nag窗体,4:分析注册算法过程.

VB函数约定太杂乱没有统一性,自己分析了几个函数:有的用eax,edx约定,有的单个ecx约定,有的堆栈、寄存器一起用,有的象stdcall约定,有时候会跟虚拟机内部组件传地址引用.
先给出函数分析,下边分析汇编的时候,可以看这些函数,不是很全的且存在错误.仅仅供参考.大家可以一起补充.
-----------------------------------------------------------------
MSVBVM60.__vbaObjSet类似MSVBVM60.__vbanew2用来给对象赋值或者实例化
类似stdcall
push    eax----->类对象模版地址
lea     eax, [ebp-1C]
push    eax-------->欲要设置引用对象指针给eax
call    401048 ---> MSVBVM60.__vbaObjSet
--------------------------------------------------
在每个事件触发之前都要调用MSVBVM60.Zombie_AddRef来记数
事件引用的COM组件对象.约定eax,ecx
mov     eax, esi
and     eax, 1
mov     [ebp-4], eax
and     esi, FFFFFFFE------>经过这寻址正好是对象虚拟表指针
push    esi------>保存对象虚表指针esi
mov     [ebp+8], esi---->esi被局部变量保存[ebp+8]
mov     ecx, [esi]----->对象虚拟表地址给ecx
call    [ecx+4] ---------> MSVBVM60.Zombie_AddRef
--------------------------------------------------
在每个事件结束之后都后调用MSVBVM60.Zombie_Release来
释放事件引用的COM组件对象,约定eax.
MSVBVM60.Zombie_Release释放对象约定参数寄存器:eax
mov     eax, [ebp+8]
push    eax-----------对象地址eax
mov     edx, [eax]----->对象虚拟表地址给edx
call    [edx+8] ----->  MSVBVM60.Zombie_Release
-------------------------------------------------------------------

MSVBVM60.__vbaFreeObj释放对象约定寄存器:ecx
lea     ecx, [ebp-24]--->对象引用指针ecx
call     [401140] --->MSVBVM60.__vbaFreeObj
--------------------------------------------------
MSVBVM60.__vbaChkstk调整堆栈指针约定寄存器:eax
mov     eax, 10
call    004016C0---->MSVBVM60.__vbaChkstk--->这个函数返回的时候就是把esp+10
---------------------------------------------------
MSVBVM60.__vbaNew2类似C++/JAVA的new函数
push    0043E120--->对象地址
push    004031A4---------->类模版地址
call    4010E0 ---> MSVBVM60.__vbaNew2
----------------------------------------------------
MSVBVM60.__vbaStrMove 是寄存器约定 edx和ecx.
mov     edx, eax---->UNICODE字符串源地址:edx
lea     ecx, [ebp-24]---->UNICODE字符串目的地址:ecx
call    401120    ----> MSVBVM60.__vbaStrMove 
-----------------------------------------------------
MSVBVM60.__vbaStrCat 是stdcall约定
push    edx----->连接目的UNICODE字符串
push    00404230 ---->UNICODE字符串常量
call    401034 ---->MSVBVM60.__vbaStrCat
-----------------------------------------------------
MSVBVM60.__vbaFreeStr 约定寄存器:ecx
lea     ecx, [ebp-24]--->ecx传字符串引用
call    40113C----> MSVBVM60.__vbaFreeStr
-----------------------------------------------------
MSVBVM60.__vbaFreeStrList是可变参数Cdcall约定
lea     eax, [ebp-28]--->UNICODE字符串引用地址eax
push    eax
lea     ecx, [ebp-24]---->UNICODE字符串引用地址ecx
push    ecx
push    2------->释放2个UNICODE字符串
call   4010F0 ---> MSVBVM60.__vbaFreeStrList
add    esp, 0C 
-----------------------------------------------------
MSVBVM60.__vbaFileOpen是Cdcall约定
push    eax---->UNICODE文件字符串名称
push    1
push    -1
push    1
call    4010F0-----> MSVBVM60.__vbaFileOpen
add     esp, 0C
----------------------------------------------------

分析程序提取本地机器码

字符串常量: const string_00403FDC="c:\"
机器码全局变量 :int_[43E108] 保存机器码
004108FB   .  BA DC3F4000   mov     edx, 00403FDC----> UNICODE字符号常量 "c:\"
00410900   .  8D4D DC       lea     ecx, [ebp-24]
00410903   .  FF15 EC104000 call    [<&MSVBVM60.__vbaStrCopy>]--->见上边
00410909   .  8D55 DC       lea     edx, [ebp-24]
0041090C   .  52            push    edx------->UNICODE字符串参数="c:\"
0041090D   .  E8 AEF9FFFF   call    004102C0---------->关键Call:获取机器码函数
00410912   .  A3 08E14300   mov     [43E108], eax--->返回值通过eax给机器码全局变量

call    004102C0 (int edx)过程如下:
004102C0   $  55            push    ebp
004102C1   .  8BEC          mov     ebp, esp
004102C3   .  83EC 08       sub     esp, 8
004102C6   .  68 C6164000   push    <jmp.&MSVBVM60.__vbaExceptHandler>    
004102CB   .  64:A1 0000000>mov     eax, fs:[0]
004102D1   .  50            push    eax
004102D2   .  64:8925 00000>mov     fs:[0], esp
004102D9   .  83EC 40       sub     esp, 40
004102DC   .  53            push    ebx
004102DD   .  56            push    esi
004102DE   .  57            push    edi
004102DF   .  8965 F8       mov     [ebp-8], esp
004102E2   .  C745 FC 50114>mov     dword ptr [ebp-4], 00401150
004102E9   .  8B3D D0104000 mov     edi, [<&MSVBVM60.#537>] 
004102EF   .  33F6          xor     esi, esi
004102F1   .  56            push    esi
004102F2   .  8975 E8       mov     [ebp-18], esi   ----->[ebp-18]___[12FC54]===lpVolumeSerialNumber
004102F5   .  8975 E4       mov     [ebp-1C], esi                         ;  [12FC50]
004102F8   .  8975 E0       mov     [ebp-20], esi                         ;  [12FC4C]
004102FB   .  8975 D8       mov     [ebp-28], esi                         ;  [12FC44]
004102FE   .  8975 D4       mov     [ebp-2C], esi                         ;  [12FC40]
00410301   .  8975 D0       mov     [ebp-30], esi                         ;  [12FC3C]
00410304   .  8975 C0       mov     [ebp-40], esi                         ;  [12FC2C]
00410307   .  8975 BC       mov     [ebp-44], esi     ----->[Ebp-44]___[12FC28]====lpMaximumComponentLength参数
0041030A   .  8975 B8       mov     [ebp-48], esi    ----> [ebp-48]__[12FC24]====lpFileSystemFlags
0041030D   .  FFD7          call    edi                                  
0041030F   .  8B1D BC104000 mov     ebx, [<&MSVBVM60.#606>] -->  MSVBVM60.rtcStringBstr
00410315   .  8945 C8       mov     [ebp-38], eax --->  [ebp-38]=12FC34
00410318   .  8D45 C0       lea     eax, [ebp-40]-->[ebp-40] [12FC2C]
0041031B   .  C745 C0 08000>mov     dword ptr [ebp-40], 8
00410322   .  50            push    eax
00410323   .  68 FF000000   push    0FF
00410328   .  FFD3          call    ebx                                  
0041032A   .  8BD0          mov     edx, eax
0041032C   .  8D4D E4       lea     ecx, [ebp-1C]      ------->[ebp-1C]=[12FC50]
0041032F   .  FF15 20114000 call    [<&MSVBVM60.__vbaStrMove>]           
00410335   .  8D4D C0       lea     ecx, [ebp-40]           ------>[ebp-40] =[12FC2C]
00410338   .  FF15 10104000 call    [<&MSVBVM60.__vbaFreeVar>]        
0041033E   .  56            push    esi
0041033F   .  FFD7          call    edi
00410341   .  8D4D C0       lea     ecx, [ebp-40]              ----> [ebp-40]=[12FC2C]
00410344   .  8945 C8       mov     [ebp-38], eax  ---->eax=0014FAFC--->lpRootPathName
00410347   .  51            push    ecx
00410348   .  68 FF000000   push    0FF
0041034D   .  C745 C0 08000>mov     dword ptr [ebp-40], 8  ------->[ebp-40]=[12FC2C]
00410354   .  FFD3          call    ebx
00410356   .  8BD0          mov     edx, eax   ----->eax=0014FE74
00410358   .  8D4D E0       lea     ecx, [ebp-20]  ---->  [ebp-20]=[12FC4C]
0041035B   .  FF15 20114000 call    [<&MSVBVM60.__vbaStrMove>] ---> MSVBVM60.__vbaStrMove
00410361   .  8D4D C0       lea     ecx, [ebp-40]                         ;  0012FC2C
00410364   .  FF15 10104000 call    [<&MSVBVM60.__vbaFreeVar>] ---> MSVBVM60.__vbaFreeVar
0041036A   .  8B55 E0       mov     edx, [ebp-20]                         ;  [12FC4C]
0041036D   .  8B3D 1C104000 mov     edi, [<&MSVBVM60.__vbaLenBstr>] ----> MSVBVM60.__vbaLenBstr
00410373   .  52            push    edx
00410374   .  8975 B8       mov     [ebp-48], esi ---------->0012FC24_lpFileSystemFlags
00410377   .  8975 BC       mov     [ebp-44], esi    ------>0012FC28_lpMaximumComponentLength
0041037A   .  FFD7          call    edi                                   ;  <&MSVBVM60.__vbaLenBstr>
0041037C   .  8B35 10114000 mov     esi, [<&MSVBVM60.__vbaStrToAnsi>]--->MSVBVM60.__vbaStrToAnsi
00410382   .  50            push    eax--------------------------------->eax=FF=nFileSystemNameSize入栈
00410383   .  8B45 E0       mov     eax, [ebp-20]--->[ebp-20]=[12FC4C]
00410386   .  8D4D D0       lea     ecx, [ebp-30] --> [ebp-20]=[12FC3C]
00410389   .  50            push    eax
0041038A   .  51            push    ecx
0041038B   .  FFD6          call    esi ------><&MSVBVM60.__vbaStrToAnsi>
0041038D   .  50            push    eax------------------------->0015009C--->lpFileSystemNameBuffer入栈
0041038E   .  8D55 B8       lea     edx, [ebp-48]---------->edx=12FC24_lpFileSystemFlags
00410391   .  8D45 BC       lea     eax, [ebp-44]------>eax=0012FC28=lpMaximumComponentLength
00410394   .  52            push    edx       --------->edx=0012FC24=lpFileSystemFlags
00410395   .  8B55 E4       mov     edx, [ebp-1C]                         ;  12FC50
00410398   .  8D4D E8       lea     ecx, [ebp-18]--->ecx=12FC54_lpVolumeSerialNumber
0041039B   .  50            push    eax-------------------------->0012FC28=lpMaximumComponentLength入栈
0041039C   .  51            push    ecx------------------------------>0012FC54=lpVolumeSerialNumber入栈
0041039D   .  52            push    edx--------------------------------->0012FC24=lpFileSystemFlags入栈
0041039E   .  FFD7          call    edi--->------><&MSVBVM60.__vbaStrToAnsi>
004103A0   .  8BC8          mov     ecx, eax-->FF
004103A2   .  FF15 84104000 call    [<&MSVBVM60.__vbaI2I4>]       
004103A8   .  50            push    eax-----------------------------------> 000000FF=nVolumeNameSize入栈
004103A9   .  8B45 E4       mov     eax, [ebp-1C] ---> 12FC50
004103AC   .  8D4D D4       lea     ecx, [ebp-2C] ---> 12FC50
004103AF   .  50            push    eax
004103B0   .  51            push    ecx
004103B1   .  FFD6          call    esi ------><&MSVBVM60.__vbaStrToAnsi>
004103B3   .  8B7D 08       mov     edi, [ebp+8]--->12FC74
004103B6   .  50            push    eax--------------------------------->001501C4=lpVolumeNameBuffer入栈
004103B7   .  8D45 D8       lea     eax, [ebp-28]   --> [ebp-28]=12FC44
004103BA   .  8B17          mov     edx, [edi]  --->0012FD70
004103BC   .  52            push    edx  -->0014F92C C:\
004103BD   .  50            push    eax  -->0012FC44
004103BE   .  FFD6          call    esi ------><&MSVBVM60.__vbaStrToAnsi>
004103C0   .  50            push    eax------------------------------------>0014FAFC_lpRootPathName入栈
004103C1   .  E8 D23BFFFF   call    00403F98----------->关键call,虽然它参数全部Ansi化了,但还没有调用但还没有调用GetVolumeInformation请看下边分析
--------------------------------------------------------------------------------------------------------
stdcall方式,参数由Unicode转化为Ansi看堆栈:
0012FBF0   0014FAFC--->lpRootPathName
0012FBF4   001501C4--->lpVolumeNameBuffer
0012FBF8   000000FF--->nVolumeNameSize
0012FBFC   0012FC54---->lpVolumeSerialNumber
0012FC00   0012FC28---->lpMaximumComponentLength
0012FC04   0012FC24--->lpFileSystemFlags
0012FC08   0015009C--->lpFileSystemNameBuffer
0012FC0C   000000FF--->nFileSystemNameSize

继续分析从上边call  00403F9 进入

00403F98   $  A1 0CE54300   mov     eax, [43E50C]--->[43E50C]保存GetVolumeInformationA函数地址
00403F9D   .  0BC0          or      eax, eax--->地址为空就跳
00403F9F   .  74 02         je      short 00403FA3
00403FA1   .  FFE0          jmp     eax
00403FA3   >  68 803F4000   push    00403F80--->关键地址:00403F54数值地址看下边 
00403FA8   .  B8 50174000   mov     eax, 401750----->MSVBVM60.DllFunctionCall地址
00403FAD   .  FFD0          call    eax----->调用MSVBVM60.DllFunctionCall,返回值放到eax中.
00403FAF   .- FFE0          jmp     eax---->eax指向kernel32.GetVolumeInformationA地址

00403F54   .  6B 65 72 6E 6>ascii   "kernel32.dll",0
00403F61      00            db      00
00403F62      00            db      00
00403F63      00            db      00
00403F64      16            db      16
00403F65      00            db      00
00403F66      00            db      00
00403F67      00            db      00
00403F68   .  47 65 74 56 6>ascii   "GetVolumeInformA"
给出SDK Ansi kernel32.GetVolumeInformationA函数原形
kernel32.GetVolumeInformationA(
         string lpRootPathName,
         string lpVolumeNameBuffer,
         int nVolumeNameSize,
         ref int lpVolumeSerialNumber,
         int lpMaximumComponentLength,
         int lpFileSystemFlags,
         string lpFileSystemNameBuffer,
         int nFileSystemNameSize
         );
再看堆栈,:
0012FBEC   004103C6 --->GetVolumeInformationA的返回地址
0012FBF0   0014FAFC--->lpRootPathName
0012FBF4   001501C4--->lpVolumeNameBuffer
0012FBF8   000000FF--->nVolumeNameSize
0012FBFC   0012FC54---->lpVolumeSerialNumber
0012FC00   0012FC28---->lpMaximumComponentLength
0012FC04   0012FC24--->lpFileSystemFlags
0012FC08   0015009C--->lpFileSystemNameBuffer
0012FC0C   000000FF--->nFileSystemNameSize

看内存
00403F14                                      4D 6F 64 75              Modu
00403F24  6C 65 31 00 66 72 6D 4D 61 69 6E 00 66 72 6D 7A  le1.frmMain.frmz
00403F34  68 75 63 65 00 00 00 00 66 72 6D 41 62 6F 75 74  huce....frmAbout
00403F44  00 00 00 00 66 6C 61 73 68 00 00 00 0D 00 00 00  ....flash.......
00403F54  6B 65 72 6E 65 6C 33 32 2E 64 6C 6C 00 00 00 00  kernel32.dll....
00403F64  16 00 00 00 47 65 74 56 6F 6C 75 6D 65 49 6E 66  ...GetVolumeInf
00403F74  6F 72 6D 61 74 69 6F 6E 41 00 00 00              ormationA...

kernel32.GetVolumeInformationA是在Module1.frmMain.frmzhuce单元声明的,总结一下:VB调用动态连接库中
API可以通过VB虚拟机内置MSVBVM60.DllFunctionCall(类似SDK API:LoadLibrary和GetProcAddrees)调用,至于之前
那些冗余的步骤都是把Unicode参数序列化成Ansi版,关键之处还是MSVBVM60.DllFunctionCall起作用.


到这里注册用的本地机器码就是调用kernel32.GetVolumeInformationA得到C磁盘的卷标标识,只是VB调用一个SDK API圈圈多多而已.
好了继续.这个函数返回之后:
00410912   .  A3 08E14300   mov     [43E108], eax--->eax返回c:\磁盘的卷标给机器码全局变量[43E108]
00410917   .  8D4D DC       lea     ecx, [ebp-24]
0041091A   .  FF15 3C114000 call    [<&MSVBVM60.__vbaFreeStr>]  
00410920   .  C745 FC 0C000>mov     dword ptr [ebp-4], 0C----->状态标志
00410927   .  833D 08E14300>cmp     dword ptr [43E108], 0--->比较机器码全局变量[43E108]
0041092E   .  7D 13         jge     short 00410943--->小于0就跳
00410930   .  C745 FC 0D000>mov     dword ptr [ebp-4], 0D
00410937   .  A1 08E14300   mov     eax, [43E108]
0041093C   .  F7D8          neg     eax
0041093E   .  A3 08E14300   mov     [43E108], eax
00410943   >  C745 FC 0F000>mov     dword ptr [ebp-4], 0F----->状态标志
0041094A   .  8B0D 08E14300 mov     ecx, [43E108]
00410950   .  81F1 AFFA2D01 xor     ecx, 12DFAAF-------------->机器码全局变量[43E108]与常数12DFAAF相互异或
00410956   .  390D 0CE14300 cmp     [43E10C], ecx-------->[43E10C]关键全局变量存放正确的注册码
0041095C   .  75 15         jnz     short 00410973--------->关键部分
0041095E   .  C745 FC 10000>mov     dword ptr [ebp-4], 10
00410965   .  66:C705 14E04>mov     word ptr [43E014], 0FFFF----------->关键标志全局变量[43E014],
0041096E   .  E9 DD000000   jmp     00410A50

分析次数计算,经过分析程序把天数保存在\wzj\4\number.txt中了,而读出的时候程序把天数保存在0043E110全局变量中当使用次数超过了3次,就提示出注册Nag来
------------------------------------------------------------------------------------------------
0041098A   .  8B15 18E04300 mov     edx, [43E018]----------->D:\Program Files\gzwlqj\
00410990   .  52            push    edx
00410991   .  68 30424000   push    00404230  ----->UNICODE "wzj\4\"
00410996   .  FF15 34104000 call    [<&MSVBVM60.__vbaStrCat>]           
0041099C   .  8BD0          mov     edx, eax---------
0041099E   .  8D4D DC       lea     ecx, [ebp-24]
004109A1   .  FF15 20114000 call    [<&MSVBVM60.__vbaStrMove>]           
004109A7   .  50            push    eax
004109A8   .  68 E83F4000   push    00403FE8 ------------->UNICODE "number.txt"
004109AD   .  FF15 34104000 call    [<&MSVBVM60.__vbaStrCat>]             
004109B3   .  8BD0          mov     edx, eax
004109B5   .  8D4D D8       lea     ecx, [ebp-28]
004109B8   .  FF15 20114000 call    [<&MSVBVM60.__vbaStrMove>]          
004109BE   .  50            push    eax-------->D:\Program Files\gzwlqj\wzj\4\number.txt
004109BF   .  6A 01         push    1
004109C1   .  6A FF         push    -1
004109C3   .  6A 01         push    1
004109C5   .  FF15 DC104000 call    [<&MSVBVM60.__vbaFileOpen>]  --->打开wzj\4\number.txt文件
004109CB   .  8D45 D8       lea     eax, [ebp-28]
004109CE   .  50            push    eax
004109CF   .  8D4D DC       lea     ecx, [ebp-24]
004109D2   .  51            push    ecx
004109D3   .  6A 02         push    2
004109D5   .  FF15 F0104000 call    [<&MSVBVM60.__vbaFreeStrList>]--->释放局部变量
004109DB   .  83C4 0C       add     esp, 0C
004109DE   .  C745 FC 14000>mov     dword ptr [ebp-4], 14
004109E5   .  68 10E14300   push    0043E110--------------->0043E110全局变量保存天数
004109EA   .  6A 01         push    1---------->文件号
004109EC   .  68 04404000   push    00404004
004109F1   .  FF15 B8104000 call    [<&MSVBVM60.__vbaInputFile>]----->
004109F7   .  83C4 0C       add     esp, 0C
004109FA   .  C745 FC 15000>mov     dword ptr [ebp-4], 15
00410A01   .  6A 01         push    1----->文件号
00410A03   .  FF15 6C104000 call    [<&MSVBVM60.__vbaFileClose>]---->关闭文件
00410A09   .  C745 FC 16000>mov     dword ptr [ebp-4], 16
00410A10   .  66:833D 10E14>cmp     word ptr [43E110], 1 --->天数比较,是否等于1
00410A18   .  75 36         jnz     short 00410A50--->关键部分:当等于1的时候好象改变\number.txt文件属性为隐藏


到这里又出现比较使用次数:

00410CAE   .  66:833D 10E14>cmp     word ptr [43E110], 3---->当次数大于3的时候,
00410CB6      0F8E 04010000 jle     00410DC0--->关键部分:次数大于3的时候,就跳出Nag,之后调用MSVBVM60.rtcShell启动官方网站提示用户注册
使用次数Nag分析完毕了,鼠标指点一二,就over了.
========================================================================================================================================

               

之后再分析两个关键注册事件过程:
第一个是:点击"注册"菜单命令过程.如果没有注册或者是注册码不对,当点击"注册"菜单命令的时候它就跳出注册窗口来提示你注册.
如果你是注册用户,你点击"注册"菜单命令,它会提示你已经是是注册用户.
事件入口:
00417190   > \55            push    ebp
00417191   .  8BEC          mov     ebp, esp
00417193   .  83EC 0C       sub     esp, 0C
00417196   .  68 C6164000   push    <jmp.&MSVBVM60.__vbaExceptHandler>    
0041719B   .  64:A1 0000000>mov     eax, fs:[0]
004171A1   .  50            push    eax
004171A2   .  64:8925 00000>mov     fs:[0], esp-------->构造完毕SEH
004171A9   .  81EC 84000000 sub     esp, 84----------->分配局部变量
004171AF   .  53            push    ebx
004171B0   .  56            push    esi
004171B1   .  57            push    edi
004171B2   .  8965 F4       mov     [ebp-C], esp
004171B5   .  C745 F8 D8144>mov     dword ptr [ebp-8], 004014D8
004171BC   .  8B45 08       mov     eax, [ebp+8]
004171BF   .  8BC8          mov     ecx, eax
004171C1   .  83E1 01       and     ecx, 1
004171C4   .  894D FC       mov     [ebp-4], ecx
004171C7   .  24 FE         and     al, 0FE
004171C9   .  50            push    eax
004171CA   .  8945 08       mov     [ebp+8], eax
004171CD   .  8B10          mov     edx, [eax]------>eax是菜单组件对象地址,
004171CF   .  FF52 04       call    [edx+4] ---->MSVBVM60.Zombie_AddRef VB事件调用固定模式函数调用,引用虚拟机内的COM组件对象
004171D2   .  33FF          xor     edi, edi
004171D4   .  66:833D 14E04>cmp     word ptr [43E014], 0FFFF----->标志全局变量[43E014]在上边分析给出,0FFFF是注册成功的标志
004171DC   .  897D E8       mov     [ebp-18], edi
004171DF   .  897D D8       mov     [ebp-28], edi
004171E2   .  897D C8       mov     [ebp-38], edi
004171E5   .  897D B8       mov     [ebp-48], edi
004171E8   .  897D A8       mov     [ebp-58], edi
004171EB   .  897D 98       mov     [ebp-68], edi
004171EE   .  897D 88       mov     [ebp-78], edi
004171F1   .  0F85 9A000000 jnz     00417291------>关键跳:不相等就跳出注册窗口提示注册
第一个事件过程分析完毕:鼠标指点一二,就over了.

------------------------------------------------------------------------------------------------------------
第二是注册窗口的事件处理过程.当输入注册码,点击确认button然后进入注册算法中,如果输入超过三次就宣布game,over...
这里用到了几个浮点指令做比较,如果注册码正确就写入到隐藏文件config.txt中.
事件入口:
0043C4F0   > \55            push    ebp
0043C4F1   .  8BEC          mov     ebp, esp
0043C4F3   .  83EC 0C       sub     esp, 0C
0043C4F6   .  68 C6164000   push    <jmp.&MSVBVM60.__vbaExceptHandler>    
0043C4FB   .  64:A1 0000000>mov     eax, fs:[0]
0043C501   .  50            push    eax
0043C502   .  64:8925 00000>mov     fs:[0], esp
0043C509   .  81EC B0000000 sub     esp, 0B0

0043C533   .  8B15 08E14300 mov     edx, [43E108] ---->全局变量[43E108]存放本地机器码
0043C539   .  33DB          xor     ebx, ebx
0043C53B   .  81F2 AFFA2D01 xor     edx, 12DFAAF---->与12DFAAF异或保存在edx中.
0043C541   .  56            push    esi
0043C542   .  8915 0CE14300 mov     [43E10C], edx ---> [43EI0C]变量在上边出现一次,它正确的注册编码

0043C57E   .  8D45 E8       lea     eax, [ebp-18] --->[ebp-18]局部变量存取用户输入的注册码:qiweixue
0043C581   .  50            push    eax                                   
0043C582   .  57            push    edi
0043C583   .  8B17          mov     edx, [edi]--->Edit组件地址
0043C585   .  FF92 A0000000 call    [edx+A0] ---> 虚函数取Edit的用户输入内容
0043C58B   .  3BC3          cmp     eax, ebx---->
0043C58D   .  DBE2          fclex--->浮点指令清除异常
0043C58F   . /7D 12         jge     short 0043C5A3
0043C591   . |68 A0000000   push    0A0
0043C596   . |68 DC6E4000   push    00406EDC
0043C59B   . |57            push    edi
0043C59C   . |50            push    eax
0043C59D   . |FF15 3C104000 call    [<&MSVBVM60.__vbaHresultCheckObj>]    ;  MSVBVM60.__vbaHresultCheckObj
0043C5A3   > \8B4D E8       mov     ecx, [ebp-18]                         ;  存取用户编码的输入:qiweixue
0043C5A6   .  51            push    ecx
0043C5A7   .  FF15 48114000 call    [<&MSVBVM60.#581>]                    ;  MSVBVM60.rtcR8ValFromBstr
0043C5AD   .  FF15 60104000 call    [<&MSVBVM60.__vbaFpR8>]               ;  MSVBVM60.__vbaFpR8
0043C5B3   .  DB05 0CE14300 fild    dword ptr [43E10C]---> [43EI0C]压入浮点栈
0043C5B9   .  DD9D 3CFFFFFF fstp    qword ptr [ebp-C4]----->[ebp-C4]压入浮点栈
0043C5BF   .  DC9D 3CFFFFFF fcomp   qword ptr [ebp-C4]---------->浮点比较
0043C5C5   .  DFE0          fstsw   ax------------>比较状态给ax
0043C5C7   .  F6C4 40       test    ah, 40
0043C5CA   .  74 07         je      short 0043C5D3------------->不相等就over掉了.
0043C5CC   .  B8 01000000   mov     eax, 1--->正确标志true给eax
0043C5D1   .  EB 02         jmp     short 0043C5D5
0043C5D3   >  33C0          xor     eax, eax--->错误标志false给eax
0043C5D5   >  F7D8          neg     eax
0043C5D7   .  8D4D E8       lea     ecx, [ebp-18]                         ;  存取用户编码
0043C5DA   .  66:8BF8       mov     di, ax
0043C5DD   .  FF15 3C114000 call    [<&MSVBVM60.__vbaFreeStr>] --->析构字符串
0043C5E3   .  8D4D E0       lea     ecx, [ebp-20]
0043C5E6   .  FF15 40114000 call    [<&MSVBVM60.__vbaFreeObj>]  --->  析构对象        
0043C5EC   .  66:3BFB       cmp     di, bx
0043C5EF   .  0F84 86010000 je      0043C77B---->关键:如果相等就over了,然后在比较是否是第三次输入.如果不相等就注册正确,把注册码输入到config.txt中.                        

以上全部分析完毕,注册算法很简单,但是跟踪起来却相当不轻松.
第一调用VB约定太杂乱,没有统一性.第二调用本地SDK API,需要Unicode转化Ansi也相当烦琐.第三用到浮点指令判断.第四用户程序堆栈与虚拟机相互通讯传地址,经常eax寄存器out出来com组件地址引用,
一堆一堆接口指针却大多没有sig.
错误之处,多谢指教. 注册机C#源代码:
========================================================

using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Pediy
{
    class Pediy
    {
        [DllImport("kernel32.dll")]
         private static extern int GetVolumeInformation(
         string lpRootPathName,
         string lpVolumeNameBuffer,
         int nVolumeNameSize,
         ref int lpVolumeSerialNumber,
         int lpMaximumComponentLength,
         int lpFileSystemFlags,
         string lpFileSystemNameBuffer,
         int nFileSystemNameSize
         );
        public static int GetRootVolume(string RootID)
        {
            const int MAX_FILENAME_LEN = 256;
            int retVal = 0;
            int a = 0;
            int b = 0;
            string str1 = null;
            string str2 = null;


            int i = GetVolumeInformation(
             RootID,
             str1,
             MAX_FILENAME_LEN,
             ref retVal,
             a,
             b,
             str2,
             MAX_FILENAME_LEN
             );

            return retVal;
        }
        static void Main(string[] args)
        {
            int key;
            Pediy prg = new Pediy();
            key = Pediy.GetRootVolume(@"c:\");
            if(key>0)
            {
              System.Console.WriteLine(@"LocalKey:"+key);
              key=key ^ 0x12DFAAF;
              System.Console.WriteLine(@"RegisterKey:" +key);
            }
            else
            { 
              key=((~key)+0x1);
              System.Console.WriteLine(@"LocalKey:"+key);
              key=((~key)+0x1)^0x12DFAAF;
              System.Console.WriteLine(@"RegisterKey:" +key)
            }

            System.Console.ReadLine();
        }
    }
}

.NET sdk 2.0