• 标 题:POPMAN时常管家2003版--简单算法分析
  • 作 者:xbb-NCG
  • 时 间:2003年12月17日 09:51
  • 链 接:http://bbs.pediy.com

POPMAN时常管家2003版



【软件简介】:此软件可用电脑帮你打点日常数据库。主要有名片盒、财产表、支出表、收入表、成长录、区邮码、营养表等功能。用它来进行家庭理财非常错。如果你经营有个小店面的话,用它来记录每天的财目是非常方便的。软件的设计十分人性化。
  

【声    明】:破解旨在学习技术,无其它目的。失误之处敬请诸位大侠赐教!

【程 序 名】:popman.exe
【版    本】:2003
【大    小】:796KB
【语    言】:Microsoft Visual C++ 6.0
【运行平台】:W9x/NT/W2K/WXP
【保护方式】:注册码(现在的国内的软件不加壳的可真是希奇啊!)
【分析方式】:追注册码及注册码算法
【难    度】:简单
【工    具】:PEiD/Filemon5.0/W32Dasm8.93+/TRW2000 v1.23
【程序下载】:http://www.sunguns.com/

【作    者】:xbb[DFCG]

【分    析】:

    运行软件后提示注册,我的机器码为624955638624955602。填入假注册码123456789,点击注册,提示“密码不正确”。
    从提示框来看我猜软件用的是messagebox,帮用TRW下断messagebox果然断下了:
    
.............

* Possible StringData Ref from Data Obj ->"密码不正确"
                                  |
:00411B59 68F89C4500              push 00459CF8        
:00411B5E 8BCB                    mov ecxebx

* Reference To: MFC42.Ordinal:1080, Ord:1080h
                                  |
:00411B60 E8F77A0300              Call 0044965C        <-我们断在这里
:00411B65 EB2B                    jmp 00411B92

............

可我要找的是注册算法,所以这不是我们要的。不过我们知道了出错的代码也行,我们记下411B60这个地址。然后用PEiD查看软件是否加壳,还好,没壳。再用W32Dasm8.93+反汇编。反汇编后我们我们Goto Code Location处输入411B60确定,我们来到下面的代码:

* Reference To: MFC42.Ordinal:0C17, Ord:0C17h
                                  |
:00411B4C E8917C0300              Call 004497E2   经典     <-字符转换CALL
:00411B51 3BC6                    cmp eaxesi   | 比对     <-比较真假注册码
:00411B53 7412                    je 00411B67   /  代码     <-相等则跳到INI文件处理处写注册信息
:00411B55 6A00                    push 00000000
:00411B57 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"密码不正确"       <-这个字串和提示信息一样。
                                  |
:00411B59 68F89C4500              push 00459CF8        
:00411B5E 8BCB                    mov ecxebx

* Reference To: MFC42.Ordinal:1080, Ord:1080h
                                  |
:00411B60 E8F77A0300              Call 0044965C        <-我们输入的地址
:00411B65 EB2B                    jmp 00411B92


上面是对一个软件的注册比对核心部分的确定的常用方法,希望新手们能看得懂。

下面是我对注册码计算与比对部分的注释,由于本人汇编不是很好,有错误的地方请大家指出。


.....................

:004119B0 6AFF                    push FFFFFFFF
:004119B2 68E0B24400              push 0044B2E0
:004119B7 64A100000000            mov eaxdword ptr fs:[00000000]
:004119BD 50                      push eax
:004119BE 64892500000000          mov dword ptr fs:[00000000], esp
:004119C5 83EC5C                  sub esp, 0000005C
:004119C8 53                      push ebx
:004119C9 55                      push ebp
:004119CA 8BD9                    mov ebxecx
:004119CC 56                      push esi
:004119CD 57                      push edi
:004119CE 8D4C2414                lea ecxdword ptr [esp+14]

* Reference To: MFC42.Ordinal:021C, Ord:021Ch
                                  |
:004119D2 E8A9790300              Call 00449380
:004119D7 33F6                    xor esiesi                   <-ESI清零

* Possible StringData Ref from Data Obj ->"01234567"
                                  |
:004119D9 68049D4500              push 00459D04                  <-“01234567”入栈
:004119DE 8D4C2414                lea ecxdword ptr [esp+14]
:004119E2 89742478                mov dword ptr [esp+78], esi

* Reference To: MFC42.Ordinal:0219, Ord:0219h
                                  |
:004119E6 E8A57B0300              Call 00449590                  
:004119EB 8D442414                lea eaxdword ptr [esp+14]
:004119EF 8BCB                    mov ecxebx
:004119F1 50                      push eax

* Possible Reference to Dialog: DialogID_0067, CONTROL_ID:03E8, ""
                                  |
:004119F2 68E8030000              push 000003E8                  <-3E8=1000入栈
:004119F7 C644247C01              mov [esp+7C], 01

* Reference To: MFC42.Ordinal:0C19, Ord:0C19h
                                  |
:004119FC E87B7D0300              Call 0044977C                  <-取机器码

* Possible Reference to String Resource ID=00001: "㧏
齾莌"
                                  |
:00411A01 B801000000              mov eax, 00000001              <-EAX=1
:00411A06 BD08000000              mov ebp, 00000008              <-EBP=8
:00411A0B 89442434                mov dword ptr [esp+34], eax--
:00411A0F 89442438                mov dword ptr [esp+38], eax   
:00411A13 B805000000              mov eax, 00000005              
:00411A18 896C2424                mov dword ptr [esp+24], ebp     |
:00411A1C C744242807000000        mov [esp+28], 00000007          |
:00411A24 8974242C                mov dword ptr [esp+2C], esi     |
:00411A28 C744243004000000        mov [esp+30], 00000004          |
                                                                  |
* Possible Reference to String Resource ID=00002: "ub聀緉?       |
9M                                                                |此段代码是按机器码的位数(18位)在堆栈 Sp"                                                             |ESP+24至ESP+68以DWORD格式填入18个数用
                                  |                               |于后面代码中对3个与注册码有关的8位的计
:00411A30 C744243C02000000        mov [esp+3C], 00000002          |算。我称这18个数为字符表,字符表如下:
:00411A38 C744244009000000        mov [esp+40], 00000009          |      8  7  0  4
:00411A40 C744244406000000        mov [esp+44], 00000006          |      1  1  2  9
:00411A48 89442448                mov dword ptr [esp+48], eax     |      6  5  3  8
                                                                  |      A  E  D  C
* Possible Reference to String Resource ID=00003: "㧏吳臍*p"      |      B  5
                                  |                               |
:00411A4C C744244C03000000        mov [esp+4C], 00000003          |
:00411A54 896C2450                mov dword ptr [esp+50], ebp     |
:00411A58 C74424540A000000        mov [esp+54], 0000000A          |
:00411A60 C74424580E000000        mov [esp+58], 0000000E          |
:00411A68 C744245C0D000000        mov [esp+5C], 0000000D          |
:00411A70 C74424600C000000        mov [esp+60], 0000000C         /
:00411A78 C74424640B000000        mov [esp+64], 0000000B        /
:00411A80 89442468                mov dword ptr [esp+68], eax__/
:00411A84 8D7C2424                lea edidword ptr [esp+24]      <-EDI=6FF674(字符表首位地址各人电脑中不同)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411AAA(C)
|
:00411A88 8B0F                    mov ecxdword ptr [edi]         <-ECX=8
:00411A8A 8B542414                mov edxdword ptr [esp+14]      <-机器码
:00411A8E 8A0411                  mov albyte ptr [ecx+edx]       <-取机器第9位(这里按0-8计数)
:00411A91 88442418                mov byte ptr [esp+18], al        <-AL=38 此处ESP+18=1250000+AL=1250038
:00411A95 8B4C2418                mov ecxdword ptr [esp+18]      <-ECX=1250038 |411A88-411AAA是循环处理
:00411A99 51                      push ecx                         <-ECX入栈     |将机器码按字符表前取字符
:00411A9A 56                      push esi                         <-ESI入栈     |并从左至右遂位替换字符
:00411A9B 8D4C2418                lea ecxdword ptr [esp+18]      <-ECX=01234567|01234567,直至ESI>EBP则结束
                                                                                 |循环。
* Reference To: MFC42.Ordinal:16E0, Ord:16E0h                                    |字符表用到的字符
                                  |                                              |      8  7  0  4
:00411A9F E8587B0300              Call 004495FC                    <-EAX=81234567|      1  1  2  9
:00411AA4 46                      inc esi                          <-计数器      |最后结果:83652246
:00411AA5 83C704                  add edi, 00000004                <-字符表地址+4|
:00411AA8 3BF5                    cmp esiebp                     <-比较        |
:00411AAA 7CDC                    jl 00411A88                      <-小于则跳    |与注册码有关的第一位数
:00411AAC 8B542410                mov edxdword ptr [esp+10]      <-EDX=83652246 

* Reference To: MSVCRT.atoi, Ord:023Dh
                                  |
:00411AB0 8B2D58EA4400            mov ebpdword ptr [0044EA58]    <-EBP=7800C283
:00411AB6 52                      push edx                         <-83652246入栈
:00411AB7 FFD5                    call ebp                         <-将83652246转换为4FC6E96
:00411AB9 83C404                  add esp, 00000004                <-字符表地址加4
:00411ABC 8944241C                mov dword ptr [esp+1C], eax      <-ESP+1C=4FC6E96
:00411AC0 33F6                    xor esiesi                     <-ESI清零
:00411AC2 8D7C2444                lea edidword ptr [esp+44]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411AE9(C)
|
:00411AC6 8B07                    mov eaxdword ptr [edi]---     
:00411AC8 8B4C2414                mov ecxdword ptr [esp+14] 
:00411ACC 8A1408                  mov dlbyte ptr [eax+ecx]     
:00411ACF 8D4C2410                lea ecxdword ptr [esp+10]          
:00411AD3 88542418                mov byte ptr [esp+18], dl      |与注册码有关的第二位数     
:00411AD7 8B442418                mov eaxdword ptr [esp+18]    |
:00411ADB 50                      push eax                       |字符表用到的字符:
:00411ADC 56                      push esi                       |      6  5  3  8
                                                                 |      A  E  D  C
* Reference To: MFC42.Ordinal:16E0, Ord:16E0h                    |
                                  |                              |
:00411ADD E81A7B0300              Call 004495FC                  |最后结果为:65982559
:00411AE2 46                      inc esi           <-计数器    /
:00411AE3 83C704                  add edi, 00000004            / 
:00411AE6 83FE08                  cmp esi, 00000008           /  
:00411AE9 7CDB                    jl 00411AC6________________/
:00411AEB 8B4C2410                mov ecxdword ptr [esp+10]      <-ECX=65982559
:00411AEF 51                      push ecx
:00411AF0 FFD5                    call ebp                         <-65982559转换为3EED05F
:00411AF2 83C404                  add esp, 00000004
:00411AF5 89442420                mov dword ptr [esp+20], eax      <-ESP+20=3EED05F
:00411AF9 33F6                    xor esiesi
:00411AFB 8D7C244C                lea edidword ptr [esp+4C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411B22(C)
|
:00411AFF 8B17                    mov edxdword ptr [edi]---
:00411B01 8B442414                mov eaxdword ptr [esp+14] 
:00411B05 8A0C10                  mov clbyte ptr [eax+edx]   
:00411B08 884C2418                mov byte ptr [esp+18], cl       与注册码有关的第三位数
:00411B0C 8D4C2410                lea ecxdword ptr [esp+10]    
:00411B10 8B542418                mov edxdword ptr [esp+18]     |字符表用到的字符:
:00411B14 52                      push edx                        |      3  8  A  E
:00411B15 56                      push esi                        |      D  C  B  5
                                                                  |
* Reference To: MFC42.Ordinal:16E0, Ord:16E0h                     |最后结果为:98255945
                                  |                              /
:00411B16 E8E17A0300              Call 004495FC                 / 
:00411B1B 46                      inc esi         <-计数器     /  
:00411B1C 83C704                  add edi, 00000004           /   
:00411B1F 83FE08                  cmp esi, 00000008          /
:00411B22 7CDB                    jl 00411AFF_______________/                
:00411B24 8B442410                mov eaxdword ptr [esp+10]     <-EAX=98255945
:00411B28 50                      push eax
:00411B29 FFD5                    call ebp                        <-转换5DB4449----第三位数
:00411B2B 8B4C2420                mov ecxdword ptr [esp+20]     <-ECX=4FC6E96----第一位数
:00411B2F 8B542424                mov edxdword ptr [esp+24]     <-EDX=3EED05F----第二位数
:00411B33 83C404                  add esp, 00000004
:00411B36 8D3409                  lea esidword ptr [ecx+ecx]    <-ESI=4FC6E96+4FC6E96=9F8DD2C
:00411B39 2BF2                    sub esiedx                    <-ESI=9F8DD2C-3EED05F=60A0CCD
:00411B3B 03F0                    add esieax                    <-ESI=60A0CCD+5DB4449=BE55116(注册码)
:00411B3D 7902                    jns 00411B41                    <-跳到注册码计算部份
:00411B3F F7DE                    neg esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411B3D(C)
|

* Possible Reference to String Resource ID=00001: "㧏
齾莌"
                                  |
:00411B41 6A01                    push 00000001
:00411B43 6A00                    push 00000000

* Possible Reference to Dialog: DialogID_0069, CONTROL_ID:03EC, ""
                                  |
:00411B45 68EC030000              push 000003EC
:00411B4A 8BCB                    mov ecxebx

* Reference To: MFC42.Ordinal:0C17, Ord:0C17h
                                  |
:00411B4C E8917C0300              Call 004497E2        <-字符转换CALL,假注册码转为16进制
:00411B51 3BC6                    cmp eaxesi         <-比较真假注册码
:00411B53 7412                    je 00411B67          <-相等则跳到INI文件处理处写注册信息
:00411B55 6A00                    push 00000000
:00411B57 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"密码不正确"
                                  |
:00411B59 68F89C4500              push 00459CF8        
:00411B5E 8BCB                    mov ecxebx

* Reference To: MFC42.Ordinal:1080, Ord:1080h
                                  |
:00411B60 E8F77A0300              Call 0044965C        <-出错提示
:00411B65 EB2B                    jmp 00411B92

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411B53(C)
|

* Reference To: MFC42.Ordinal:0490, Ord:0490h
                                  |
:00411B67 E8E8790300              Call 00449554        <-注册码正确就跳来此处
:00411B6C 8B7804                  mov edidword ptr [eax+04]
:00411B6F 56                      push esi

* Possible StringData Ref from Data Obj ->"MIMI"------------
                                  |                          
:00411B70 68F09C4500              push 00459CF0               
                                                               
* Possible StringData Ref from Data Obj ->"REGISTE"             
                                  |                              
:00411B75 68E89C4500              push 00459CE8                   
:00411B7A 8BCF                    mov ecxedi                     
                                                                    
* Reference To: MFC42.Ordinal:1902, Ord:1902h                        
                                  |                                   
:00411B7C E85B7C0300              Call 004497DC                        
:00411B81 8BCB                    mov ecxebx                          
:00411B83 C787CC00000000000000    mov dword ptr [edi+000000CC], 00000000 |
                                                                         |此处代码在c:
* Reference To: MFC42.Ordinal:12F5, Ord:12F5h                            |windowspopman.ini
                                  |                                      |文件中[REGISTE]写
:00411B8D E86C7B0300              Call 004496FE                          |入"MIMI=注册码"的
                                                                         |信息,未注册时MIMI
* Referenced by a (U)nconditional or (C)onditional Jump at Address:      |的值随启动次而增加。
|:00411B65(U)                                                            |
|                                                                        |
:00411B92 8D4C2410                lea ecxdword ptr [esp+10]            |
:00411B96 C644247400              mov [esp+74], 00                       |
                                                                         |
* Reference To: MFC42.Ordinal:0320, Ord:0320h                            |
                                  |                                      |
:00411B9B E8C8770300              Call 00449368                          |
:00411BA0 8D4C2414                lea ecxdword ptr [esp+14]            |
:00411BA4 C7442474FFFFFFFF        mov [esp+74], FFFFFFFF                 |
                                                                         |
* Reference To: MFC42.Ordinal:0320, Ord:0320h                            |
                                  |                                      |
:00411BAC E8B7770300              Call 00449368                          /
:00411BB1 8B4C246C                mov ecxdword ptr [esp+6C]           /
:00411BB5 5F                      pop edi                              /
:00411BB6 5E                      pop esi                             /
:00411BB7 5D                      pop ebp                            /
:00411BB8 5B                      pop ebx                           /
:00411BB9 64890D00000000          mov dword ptr fs:[00000000], ecx /
:00411BC0 83C468                  add esp, 00000068               /
:00411BC3 C3                      ret____________________________/


**************************************************************************************

【算法总结】:
          
     软件的注册码与假注册码无关。真注册码通过机器码计算。先给出一个字符表,然后按字符表分别取出三个8位数(16进制)。
     注册码=第一位数*2-第二位数+第三位数

**************************************************************************************

【爆    破】:

    将411B53 7412   je 00411B67 处的7412改为EB12即可。

**************************************************************************************

【注册信息】:

    软件的注册信息我们可以用REGmon或者FILEMON这两个软件来监测软件的动作,前者针对注册表,后者针对文件。我用FILEMON进行监测后发现软件读写了c:windowspopman.ini这个文件,如下:
......
185  14:04:34  Popman  Attributes  C:WINDOWSPOPMAN.INI  SUCCESS  GetAttributes  
186  14:04:34  Popman  Open  C:WINDOWSPOPMAN.INI  SUCCESS  OPENEXISTING READWRITE DENYWRITE   
187  14:04:34  Popman  Ioctl  C:  SUCCESS  Subfunction: 08h  
188  14:04:34  Popman  Attributes  C:WINDOWSPOPMAN.INI  SUCCESS  Get Modify  
189  14:04:34  Popman  Seek  C:WINDOWSPOPMAN.INI  SUCCESS  End Offset: 0  
190  14:04:34  Popman  Seek  C:WINDOWSPOPMAN.INI  SUCCESS  Beginning Offset: 0  
191  14:04:34  Popman  Read  C:WINDOWSPOPMAN.INI  SUCCESS  Offset: 0 Length: 340  
192  14:04:34  Popman  Close  C:WINDOWSPOPMAN.INI  SUCCESS  CLOSE_FINAL  
......

如果想重新回到未注册版只需把DEL处的注册码删除即可。
[INFORMATION]
UNIT=NCG      |----此部分是在软件安装时要求输入的。
NAME=xbb_NCG /

[REGISTE]
MIMI=199577878        <------DEL
SKIN=22

**************************************************************************************

【注 册 机】:

    我很想编出注册机,想像中这个应该很简单,可我的编程太差,唉。。。。。
    谁要是编出来了,请贴出来让我学习一下。谢谢!


xbb[DFCG]
            
                                   2003.12.10