【学习】汇编中vb调用约定01

6 篇文章 0 订阅
标 题: [原创]高中物理课件破解次数、Nag算法分析和注册机
作 者: qiweixue
时 间: 2006-09-23,19:48
链 接: http://bbs.pediy.com/showthread.php?t=32356

高中物理课件是中学生学习物理之必备...
软件采用了次数限制使用超过三次,跳出提示注册的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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值