• 标 题:转贴一篇文章 作者的功力绝对不亚于任何高手 (37千字)
  • 作 者:娃娃[CCG]
  • 时 间:2001-11-19 17:37:40
  • 链 接:http://bbs.pediy.com

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);

    }