发新话题
打印

[转载]注册“美萍安全卫士 8.87 标准版”

[转载]注册“美萍安全卫士 8.87 标准版”

文章作者:qduwg

题目:注册“美萍安全卫士 ”
软件名称:美萍菜单安全卫士 8.87 标准版
文件大小:584 KB
使用平台:Win9x/NT/2000/XP
软件来源:电脑报2002合订本光盘
软件简介:
美萍电脑安全卫士是最实用的网吧,电脑屋,学校机房安全保护,计费管理软件,它利用许多先进的windows内核

技术,全真虚拟win9x桌面,实现了硬盘文件保护远程控制,会员远程登陆,限时,定时运行计算机,应用软件选

择运行,网站记录,黄色网站限制等多项功能。
工具:SOFTICE,CASPER,PEID,OD,UltraEDIT

引子:以前只是听说过这个软件,根本没有用过,今天尝试安装了一下,结果刚启动安装程序“咣当”一声,电脑

关机没商量:(,据说是对SOFTICE和TRW等设防了,我每次SOFTICE都是自动启动,所以关机是必然的了。我先用

PEID查看是否加壳,结果是被Aspack2.0加壳了,我尝试用AspackDIE脱壳,运行脱壳后的程序不成功!我用

Prodump也不成功,最后只好用Casper脱壳,运行一下,成功。但是用W32DASM反汇编不成功,用OD反汇编成功。

首先干掉关机的函数,用OD打开软件,搜索函数名,查看哪个函数关机,发现ExitWindowEx。再查看有几个地方调

用它,看到3个地方45AC32,4A1B01,4A1F3D,再看看是否上面能否跳过这个调用。下面挨个来解决吧。
0045AC18  /$ 53         PUSH EBX
*略去十来行
0045AC31  |. 57         PUSH EDI
0045AC32  |. E8 89B7FAFF   CALL <JMP.&user32.ExitWindowsEx> //就是这个函数关机。
0045AC37  |. 85C0        TEST EAX,EAX
0045AC39  |. 75 02       JNZ SHORT SMENU1.0045AC3D
*略去十来行
0045AC4F  |. 5B         POP EBX
0045AC50  \. C3         RETN
(1).先看第一个地址所在的函数如下,从45AC18开始到45AC50结束,右击第一行指令,然后选择“搜索选定指令

的引用”命令,发现有6个地方对此函数调用,看来软件作者非要你死机不可啦!!这六个地方是49683B,

496854,496893,49FC7F,49FC94,49FCC5.看来陷阱重重。下面看这六处如何解决:
(1)49683B,496854和496893所在的函数上下文
004967DA  |. 8B83 E4010000  MOV EAX,DWORD PTR DS:[EBX+1E4]
004967E0  |. 80B8 1D010000 >CMP BYTE PTR DS:[EAX+11D],0
004967E7  |. 74 70       JE SHORT SMENU1.00496859  //此处JE 改为JMP可跳过关机CALL,即75->eb  

(*)
004967E9  |. 8B15 58BE4A00  MOV EDX,DWORD PTR DS:[4ABE58]
004967EF  |. 8B12        MOV EDX,DWORD PTR DS:[EDX]
*略去10来行
0049681F  |. A1 E8BF4A00   MOV EAX,DWORD PTR DS:[4ABFE8]
00496824  |. 8338 01      CMP DWORD PTR DS:[EAX],1
00496827  |. 75 19       JNZ SHORT SMENU1.00496842 //如果(*)跳转NOP掉,此处改为跳到496898,

即EB 6F (**)
00496829  |. A1 30C04A00   MOV EAX,DWORD PTR DS:[4AC030]
0049682E  |. 8B00        MOV EAX,DWORD PTR DS:[EAX]
00496830  |. 8B80 14020000  MOV EAX,DWORD PTR DS:[EAX+214]
00496836  |. BA 09000000   MOV EDX,9
0049683B  |. E8 D843FCFF   CALL SMENU1.0045AC18    //调用关机函数
00496840  |. EB 17       JMP SHORT SMENU1.00496859
00496842  |> A1 30C04A00   MOV EAX,DWORD PTR DS:[4AC030]
00496847  |. 8B00        MOV EAX,DWORD PTR DS:[EAX]
00496849  |. 8B80 14020000  MOV EAX,DWORD PTR DS:[EAX+214]
0049684F  |. BA 05000000   MOV EDX,5
00496854  |. E8 BF43FCFF   CALL SMENU1.0045AC18    //调用关机函数
00496859  |> 8B83 E8010000  MOV EAX,DWORD PTR DS:[EBX+1E8]
0049685F  |. 80B8 1D010000 >CMP BYTE PTR DS:[EAX+11D],0
00496866  . 74 30       JE SHORT SMENU2.00496898  //如果(*)改为JMP,则这个也改为JMP,通往

光明。否则从(**)直接跳到目的地。
00496868  . 8D55 FC      LEA EDX,DWORD PTR SS:[EBP-4]
0049686B  |. A1 ACB84A00   MOV EAX,DWORD PTR DS:[4AB8AC]
00496870  |. E8 73CEFDFF   CALL SMENU1.004736E8
00496875  |. A1 30C04A00   MOV EAX,DWORD PTR DS:[4AC030]
0049687A  |. 8B00        MOV EAX,DWORD PTR DS:[EAX]
0049687C  |. E8 0794F9FF   CALL SMENU1.0042FC88
00496881  |. A1 30C04A00   MOV EAX,DWORD PTR DS:[4AC030]
00496886  |. 8B00        MOV EAX,DWORD PTR DS:[EAX]
00496888  |. 8B80 14020000  MOV EAX,DWORD PTR DS:[EAX+214]
0049688E  |. BA 06000000   MOV EDX,6
00496893  |. E8 8043FCFF   CALL SMENU1.0045AC18    //调用关机函数
00496898  |> 33C0        XOR EAX,EAX
0049689A  |. 5A         POP EDX
0049689B  |. 59         POP ECX
0049689C  |. 59         POP ECX
========================================================
(2)49FC7F,49FC94,49FCC5所在的上下文
0049FC68  . 833D 50BA4A00 >CMP DWORD PTR DS:[4ABA50],1
0049FC6F  . 75 15       JNZ SHORT SMENU1.0049FC86
0049FC71  . 8B45 FC      MOV EAX,DWORD PTR SS:[EBP-4]
0049FC74  . 8B80 14020000  MOV EAX,DWORD PTR DS:[EAX+214]
0049FC7A  . BA 09000000   MOV EDX,9
0049FC7F  . E8 94AFFBFF   CALL SMENU1.0045AC18    //调用关机函数,NOP掉
0049FC84  . EB 13       JMP SHORT SMENU1.0049FC99
0049FC86  > 8B45 FC      MOV EAX,DWORD PTR SS:[EBP-4]
0049FC89  . 8B80 14020000  MOV EAX,DWORD PTR DS:[EAX+214]
0049FC8F  . BA 05000000   MOV EDX,5
0049FC94  . E8 7FAFFBFF   CALL SMENU1.0045AC18    //调用关机函数,NOP掉
0049FC99  > 8B45 F8      MOV EAX,DWORD PTR SS:[EBP-8]
0049FC9C  . 8078 03 72    CMP BYTE PTR DS:[EAX+3],72
0049FCA0  . 75 28       JNZ SHORT SMENU1.0049FCCA
0049FCA2  . 833D 7CBA4A00 >CMP DWORD PTR DS:[4ABA7C],1
0049FCA9  . 75 0C       JNZ SHORT SMENU1.0049FCB7
0049FCAB  . A1 A4BD4A00   MOV EAX,DWORD PTR DS:[4ABDA4]
0049FCB0  . 8B00        MOV EAX,DWORD PTR DS:[EAX]
0049FCB2  . E8 D1FFF8FF   CALL SMENU1.0042FC88
0049FCB7  > 8B45 FC      MOV EAX,DWORD PTR SS:[EBP-4]
0049FCBA  . 8B80 14020000  MOV EAX,DWORD PTR DS:[EAX+214]
0049FCC0  . BA 06000000   MOV EDX,6
0049FCC5  . E8 4EAFFBFF   CALL SMENU1.0045AC18    //调用关机函数,NOP掉
0049FCCA  > 8B45 F8      MOV EAX,DWORD PTR SS:[EBP-8]
0049FCCD  . 8078 03 6D    CMP BYTE PTR DS:[EAX+3],6D
0049FCD1  . 0F85 8B000000  JNZ SMENU1.0049FD62
========================================================
(3)另外两处调用关机关机函数的地方4A1B01,4A1F3D
004A1AF4  > E8 7FFEFCFF   CALL SMENU1.00471978
004A1AF9  . 84C0        TEST AL,AL
004A1AFB    74 09       JE SHORT SMENU1.004A1B06    //JE改为JMP,即74->EB
004A1AFD  . 6A 00       PUSH 0
004A1AFF  . 6A 05       PUSH 5
004A1B01  . E8 BA48F6FF   CALL <JMP.&user32.ExitWindowsEx>  //调用关机函数
004A1B06  > 8D45 E0      LEA EAX,DWORD PTR SS:[EBP-20]
004A1B09  . BA E4104D00   MOV EDX,SMENU1.004D10E4
004A1B0E  . B9 00010000   MOV ECX,100
004A1B13  . E8 6421F6FF   CALL SMENU1.00403C7C
==================
004A1F30  . E8 43FAFCFF   CALL SMENU2.00471978
004A1F35  . 84C0        TEST AL,AL
004A1F37    74 09       JE SHORT SMENU1.004A1F42  //JE改为JMP,即74->EB
004A1F39  . 6A 00       PUSH 0
004A1F3B  . 6A 05       PUSH 5
004A1F3D  . E8 7E44F6FF   CALL SMENU2.004063C0         //调用关机函数
004A1F42  > B8 440E4D00   MOV EAX,SMENU2.004D0E44
还有一个地方就是4063C0 ,看看如下:
004063C0  $-FF25 74274D00  JMP DWORD PTR DS:[<&user32.ExitWindowsEx>]
这个JMP就是被上述各函数调用的跳转。现在已经没有函数调用它了。如果只把此处NOP是不可以的,道理很简单,

因为程序已经检测到SOFTICE等工具的存在,然后调用这个函数,这个如果不存在了,那程序不会正常运行,被挂

起来了。所以必须才根本上把调用这个函数的路线切断。
========================================================
(4)下面解决注册问题
这个软件在输入注册码后不立即校验,在重新启动时校验,所以肯定写在注册表或者什么地方了。安装这个软件之

前,用REGSNAP给系统留影,然后安装之后再次留影,比较两次结果,发现在注册表留下了踪迹:
H.L.M\Software\Mpsoft\Smenu\Reg等7个键在REG下面可以看到输入的假码。程序每次重新启动后才读取注册表

进行校验是否正确。所以我们下条件断点 bpx regqueryvalueExa if *(esp->8)= =&#39;RegN&#39; do "d esp->14"。

F5退出SICE,然后启动美萍,被断下,就停在这个系统函数这里,此刻不要用F10或者F12跟踪了,如果这样最后走

到系统的消息循环那儿就走不出来了,我折腾了半天也没有回到主程序去,如果用TRW的pmodule也不成功,一下子

就运行了 ,根本拦不住的。所以还是SICE好用,这里按一次F11键,然后用F10跟踪。以前我对这个键不明白,那

时刚刚开始学习破解,现在终于明白其意义重大了。这个键的功能就是“返回到刚刚调用了某个子函数的主函数的

后面一条指令位置。比如:
//下面是某个主函数体
00400188    mov eax,1
00400192    call  00400288 //发出对某个函数的调用
00400198    test eax,eax
// 下面是某个子函数体
00400288    push ebp     //在刚刚开始进入这个函数的位置,按F11键,立即执行这个函数并返回到主调

函数    0040028a    mov eax,ebx  //中发出调用的指令的后面一个指令处。比如返回到00400198处。
0040028c    call 400666
注意:在需要的时候,按一下该F11功能键就可以了,不要按多次。

美萍被断下后,按一下F11回到主程序,因为美萍调用了好几次regqueryvalueExa函数,所以注意观察在数据窗口

内读出的注册表键值,按一次F5就可以发现在数据窗口显示了Reg的键值,就是你的假码的16进制数了。当然这个

假码已经是解密了的,在注册表内是加密的。加密方法见下面。

00477694  /$ 53         PUSH EBX
00477695  |. A1 38C04A00   MOV EAX,DWORD PTR DS:[4AC038]
0047769A  |. 8338 00      CMP DWORD PTR DS:[EAX],0
0047769D  |. 75 2A       JNZ SHORT SMENU2.004776C9
0047769F  |. A1 D4BC4A00   MOV EAX,DWORD PTR DS:[4ABCD4]
004776A4  |. 8B00        MOV EAX,DWORD PTR DS:[EAX]
004776A6  |. E8 BDF4FFFF   CALL SMENU2.00476B68
004776AB  |. 8BD8        MOV EBX,EAX                    ;  

SMENU2.<ModuleEntryPoint>
004776AD  |. B8 54774700   MOV EAX,SMENU2.00477754            ;  ASCII "RegNum"
004776B2  |. E8 DDF6FFFF   CALL SMENU2.00476D94      //调用regqueryvalueExa函数
004776B7  |. 3BD8        CMP EBX,EAX                     //真假码进行对比,EBX为解

密后的真码,EAX解密后的假码
004776B9  |. 75 0A       JNZ SHORT SMENU2.004776C5  //不相同则Fail。直接修改为JZ实行爆破,可

以输入任意注册码了。
004776BB  |. B8 01000000   MOV EAX,1
004776C0  |. E9 83000000   JMP SMENU2.00477748
004776C5  |> 33C0        XOR EAX,EAX                    ;  

SMENU2.<ModuleEntryPoint>
004776C7  |. 5B         POP EBX                       ;  KERNEL32.BFF8B86C
004776C8  |. C3         RETN
========================================================
(5)跟踪注册码计算方法。只有在成功之前可以进行跟踪,如果注册成功了,那还跟踪干吗??:) 输入任意码,

比如78787878,唤出SICE下断点bpx hmemcpy,F5退出SICE,点击“注册”按钮,被拦住。7次F12来到如下代码处

,开始分析:
00477F37  E8 809EFAFF    CALL SMENU3.00421DBC
00477F3C  837D FC 00     CMP DWORD PTR SS:[EBP-4],0  //在这里停住
00477F40  74 65        JE SHORT SMENU3.00477FA7   
00477F42  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-4]
00477F45  8B83 F4010000   MOV EAX,DWORD PTR DS:[EBX+1F4]
00477F4B  E8 6C9EFAFF    CALL SMENU3.00421DBC
00477F50  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
00477F53  E8 A4F9F8FF    CALL SMENU3.004078FC      //这个CALL关键,F8跟入
00477F58  8BD0         MOV EDX,EAX                    ;

SMENU3.<ModuleEntryPoint>
00477F5A  B8 D07F4700    MOV EAX,SMENU3.00477FD0            ; ASCII "RegNum"
00477F5F  E8 F4EEFFFF    CALL SMENU3.00476E58      //这个CALL 也关键,F8跟入

先看第一个477F53处的CALL:
*略去多行
00407916  64:8920       MOV DWORD PTR FS:[EAX],ESP
00407919  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-4]
0040791C  8BC3         MOV EAX,EBX
0040791E  E8 E5B2FFFF    CALL SMENU3.00402C08  //这个CALL关键,F8跟入
00407923  8BF0         MOV ESI,EAX                    ;

SMENU3.<ModuleEntryPoint>
00407925  837D FC 00     CMP DWORD PTR SS:[EBP-4],0
00407929  74 23        JE SHORT SMENU3.0040794E
下面是跟入的代码:
00402C08  53          PUSH EBX
*略去多行
00402C16  BF CCCCCC0C    MOV EDI,0CCCCCCC  //EDI赋值一个常量
00402C1B  8A1E         /MOV BL,BYTE PTR DS:[ESI]  // 这个小循环判断每位注册码是否空格.
00402C1D  46          |INC ESI
00402C1E  80FB 20       |CMP BL,20
00402C21  ^74 F8        \JE SHORT SMENU3.00402C1B
00402C23  B5 00        MOV CH,0
00402C25  80FB 2D       CMP BL,2D       //判断第一位是否是短杠"-",是则错。
00402C28  74 45        JE SHORT SMENU3.00402C6F
00402C2A  80FB 2B       CMP BL,2B       //判断第一位是否是加号"+",是则错。
00402C2D  74 42        JE SHORT SMENU3.00402C71
00402C2F  80FB 24       CMP BL,24       //判断第一位是否是"$",是则错。
00402C32  74 42        JE SHORT SMENU3.00402C76
00402C34  84DB         TEST BL,BL      
00402C36  74 32        JE SHORT SMENU3.00402C6A
00402C38  80EB 30       /SUB BL,30      //下面的循环把输入注册码的每位变成16进制数,累加起

来。
00402C3B  80FB 09       |CMP BL,9
00402C3E  77 2A        |JA SHORT SMENU3.00402C6A
00402C40  39F8         |CMP EAX,EDI    //不超过那个EDI内的常数则OK。
00402C42  77 26        |JA SHORT SMENU3.00402C6A
00402C44  8D0480        |LEA EAX,DWORD PTR DS:[EAX+EAX*4]  //EAX=5*EAX
00402C47  01C0         |ADD EAX,EAX      //EAX=2*EAX
00402C49  01D8         |ADD EAX,EBX      // //EAX=EAX+EBX(下一位)
00402C4B  8A1E         |MOV BL,BYTE PTR DS:[ESI]  //取下位注册码到BL。
00402C4D  46          |INC ESI
00402C4E  84DB         |TEST BL,BL
00402C50  ^75 E6        \JNZ SHORT SMENU3.00402C38  //继续循环累加。
00402C52  FECD         DEC CH
00402C54  74 10        JE SHORT SMENU3.00402C66
00402C56  85C0         TEST EAX,EAX                    ;

SMENU3.<ModuleEntryPoint>
00402C58  7C 10        JL SHORT SMENU3.00402C6A
========================================================
再看第二个477F5F处的CALL :
00476E58  55          PUSH EBP
00476E59  8BEC         MOV EBP,ESP
*略去多行
00476E96  BA F06E4700    MOV EDX,SMENU3.00476EF0            ; ASCII

"SOFTWARE\Mpsoft\Smenu\Reg"
00476E9B  8BC7         MOV EAX,EDI
00476E9D  E8 22C0FBFF    CALL SMENU3.00432EC4  //往注册表写入键。
00476EA2  8BCE         MOV ECX,ESI
00476EA4  81F1 45160100   XOR ECX,11645       //注册码与11645h异或运算,就是它的加密算法。写

入注册表的值就是异或后的值。比如78787878变成十六进制后是4B23526h,4B23526h xor 11645h=4B32363h。
00476EAA  8B55 FC       MOV EDX,DWORD PTR SS:[EBP-4]
*略去多行
========================================================
最后,得到我们的注册码,在004776B7  CMP EBX,EAX  那里看到的EBX内的值为解密后的真码8C2Eh,8C2Eh变为

10进制数为35886,这就是你的注册码了。但在注册表内的值19A6Bh是与1164h进行异或后得到的。比如8C2Eh  

xor 11645h =19A6Bh。

后记:

在学习看雪精华3的是时候偶尔看到这个破文,不过那里都写的比较精练,我按照其中一个下注册表断点失败,而

且有的用“天意”破解的,还有一篇是静态分析出来的,我还是结合动态和静态分析自己的吧,自己实践了一把,

感谢看雪精华的文章作者,我也把破解过程和心得奉献出来,希望菜鸟受益是最终目的。

体会:
软件破解的过程中,如果使用条件断点效率就比较高了,当然需要对函数的参数使用比较明确,函数调用后,参数

在堆栈的什么位置上是关键。比如下条件断点 bpx regqueryvalueExa if *(esp->8)= =&#39;RegN&#39; do "d esp-

>14"。其中esp->8是键名地址*(esp->8)表示该地址指向的键名串。 esp->14则是读取的键值所在的地址。这里给

菜鸟说明一下这个语法:这个形式(esp->8)跟(esp+8)是一样的,就是esp内容加8得到一个新堆栈地址,比如当前

esp=402000,esp+8=402008。如果前面带了*号,则表示间接寻址的意思,要拿出402008处的4个字节作为地址使

用,去存取目标对象。说白了,esp->8是指针变量,里面保存了一个地址,如果是 *(esp->8),则表示指针变量

(值)所指向的内容。不知菜鸟能否明白我的 罗嗦??:)希望阅读愉快,学习进步!

感谢看雪对我们的成长与进步所起的巨大作用!


QduWg

qduwg@163.com

TOP

发新话题