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 ecx, ebx
* 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 eax, esi | 比对 <-比较真假注册码
: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 ecx, ebx
* 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 eax, dword 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 ebx, ecx
:004119CC 56 push esi
:004119CD 57 push edi
:004119CE 8D4C2414 lea ecx, dword ptr [esp+14]
* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:004119D2 E8A9790300 Call 00449380
:004119D7 33F6 xor esi, esi <-ESI清零
* Possible StringData Ref from Data Obj ->"01234567"
|
:004119D9 68049D4500 push 00459D04 <-“01234567”入栈
:004119DE 8D4C2414 lea ecx, dword 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 eax, dword ptr [esp+14]
:004119EF 8BCB mov ecx, ebx
: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 edi, dword ptr [esp+24] <-EDI=6FF674(字符表首位地址各人电脑中不同)
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411AAA(C)
|
:00411A88 8B0F mov ecx, dword ptr [edi] <-ECX=8
:00411A8A 8B542414 mov edx, dword ptr [esp+14] <-机器码
:00411A8E 8A0411 mov al, byte ptr [ecx+edx] <-取机器第9位(这里按0-8计数)
:00411A91 88442418 mov byte ptr [esp+18], al <-AL=38 此处ESP+18=1250000+AL=1250038
:00411A95 8B4C2418 mov ecx, dword ptr [esp+18] <-ECX=1250038 |411A88-411AAA是循环处理
:00411A99 51 push ecx <-ECX入栈 |将机器码按字符表前取字符
:00411A9A 56 push esi <-ESI入栈 |并从左至右遂位替换字符
:00411A9B 8D4C2418 lea ecx, dword 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 esi, ebp <-比较 |
:00411AAA 7CDC jl 00411A88 <-小于则跳 |与注册码有关的第一位数
:00411AAC 8B542410 mov edx, dword ptr [esp+10] <-EDX=83652246
* Reference To: MSVCRT.atoi, Ord:023Dh
|
:00411AB0 8B2D58EA4400 mov ebp, dword 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 esi, esi <-ESI清零
:00411AC2 8D7C2444 lea edi, dword ptr [esp+44]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411AE9(C)
|
:00411AC6 8B07 mov eax, dword ptr [edi]---
:00411AC8 8B4C2414 mov ecx, dword ptr [esp+14]
:00411ACC 8A1408 mov dl, byte ptr [eax+ecx]
:00411ACF 8D4C2410 lea ecx, dword ptr [esp+10]
:00411AD3 88542418 mov byte ptr [esp+18], dl |与注册码有关的第二位数
:00411AD7 8B442418 mov eax, dword 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 ecx, dword 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 esi, esi
:00411AFB 8D7C244C lea edi, dword ptr [esp+4C]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411B22(C)
|
:00411AFF 8B17 mov edx, dword ptr [edi]---
:00411B01 8B442414 mov eax, dword ptr [esp+14]
:00411B05 8A0C10 mov cl, byte ptr [eax+edx]
:00411B08 884C2418 mov byte ptr [esp+18], cl 与注册码有关的第三位数
:00411B0C 8D4C2410 lea ecx, dword ptr [esp+10]
:00411B10 8B542418 mov edx, dword 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 eax, dword ptr [esp+10] <-EAX=98255945
:00411B28 50 push eax
:00411B29 FFD5 call ebp <-转换5DB4449----第三位数
:00411B2B 8B4C2420 mov ecx, dword ptr [esp+20] <-ECX=4FC6E96----第一位数
:00411B2F 8B542424 mov edx, dword ptr [esp+24] <-EDX=3EED05F----第二位数
:00411B33 83C404 add esp, 00000004
:00411B36 8D3409 lea esi, dword ptr [ecx+ecx] <-ESI=4FC6E96+4FC6E96=9F8DD2C
:00411B39 2BF2 sub esi, edx <-ESI=9F8DD2C-3EED05F=60A0CCD
:00411B3B 03F0 add esi, eax <-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 ecx, ebx
* Reference To: MFC42.Ordinal:0C17, Ord:0C17h
|
:00411B4C E8917C0300 Call 004497E2 <-字符转换CALL,假注册码转为16进制
:00411B51 3BC6 cmp eax, esi <-比较真假注册码
: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 ecx, ebx
* 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 edi, dword 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 ecx, edi
* Reference To: MFC42.Ordinal:1902, Ord:1902h
|
:00411B7C E85B7C0300 Call 004497DC
:00411B81 8BCB mov ecx, ebx
: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 ecx, dword ptr [esp+10] |
:00411B96 C644247400 mov [esp+74], 00 |
|
* Reference To: MFC42.Ordinal:0320, Ord:0320h |
| |
:00411B9B E8C8770300 Call 00449368 |
:00411BA0 8D4C2414 lea ecx, dword ptr [esp+14] |
:00411BA4 C7442474FFFFFFFF mov [esp+74], FFFFFFFF |
|
* Reference To: MFC42.Ordinal:0320, Ord:0320h |
| |
:00411BAC E8B7770300 Call 00449368 /
:00411BB1 8B4C246C mov ecx, dword 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