【破解作者】 海风月影[DFCG][NE365]
【作者邮箱】 Email to Me 
【使用工具】 od 1.10d ,Peid 
【破解平台】 Win9x/NT/2000/XP
【软件名称】 江苏省计算机等级考试全真模拟试卷(三级偏软)
【软件简介】 

  江苏省计算机等级考试全真模拟试卷题目
  (三级偏软)

【加壳方式】 无
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】


今天装了 江苏省计算机等级考试全真模拟试卷(三级偏软) 的配套光盘,结果运行时要放光盘才能运行.晕!这也太麻烦了
于是想把它的光盘检测去掉,看雪论坛上cd-check这方面文章不多,写一篇详细的文章给新手看看吧(我也是新手 :-) )

安装好后,用peid检测 笔试.exe ,无壳,delphi 6.0 - 7.0

用od载入,在命令行中输入 bp GetDriveTypeA 回车

(
这里是对GetDriveTypeA下断点,一般来说,cd-check 的保护都要用到这个函数,这个函数是用来判断一个磁盘驱动器的类型
如何调用就不用看了,重点看它的返回值

返回值含义如下
0 驱动器不能识别  
1 指定的目录不存在  
2 DriveRemoveable  
3 A Fixed Disk (HardDrive)  
4 Remote Drive(Network)  
5 Cd-Rom驱动器  
6 RamDisk  

重点的是  3 硬盘驱动器  和   5 光盘驱动器
一般的cd-check程序,调用了GetDriveTypeA后,立即就是判断是否为光驱,即 cmp al,5 (al是返回值),根据这个我们就可以做点文章了

)

也可以 按 ctrl+n ,查找GetDriveTypeA这个函数,然后下断点。但用命令行是断在kernel32.dll里,这样下断点是肯定能断下的而查找GetDriveTypeA这个函数有可能找不到,这个程序是能找到的

F9运行,断在kernel32.dll里,不要慌,f2取消断点,这时看堆栈

代码:
0012FD38     00491AB8   /CALL 到 GetDriveTypeA 来自 笔试.00491AB3 0012FD3C     009C21DC   \RootPathName = "a:\"



CALL 到 GetDriveTypeA 来自 笔试.00491AB3,看到了吗?是00491AB3这里调用的
按ctrl+F9,直接跳到ret,按f8,即来到00491AB3调用的后一句,即 00491AB8

代码:
00491AB2  |.  50            |push eax                          ; /RootPathName 00491AB3  |.  E8 5450F7FF   |call <jmp.&kernel32.GetDriveTypeA>; \GetDriveTypeA 00491AB8  |.  3C 05         |cmp al,5                          ;  5 指的是光盘,3指的是硬盘



很显然,后面一句就是cmp al,5,判断是否为光驱,把盘放进去,仔细跟踪一下它是如何检测的



代码:
00491AB3  |.  E8 5450F7FF   |call <jmp.&kernel32.GetDriveTypeA>; \GetDriveTypeA



这行下断点,看好堆栈,f9运行,直到出现光驱盘符停下来

代码:
0012FD3C     009C22BC   \RootPathName = "i:\"



我这里是i:。
f8单步跟踪

代码:
00491AA7  |.  8B85 E8FDFFFF  |mov eax,dword ptr ss:[ebp-218] 00491AAD  |.  E8 6231F7FF    |call 笔试.00404C14 00491AB2  |.  50             |push eax                                    ; /RootPathName 00491AB3  |.  E8 5450F7FF    |call <jmp.&kernel32.GetDriveTypeA>          ; \GetDriveTypeA 00491AB8  |.  3C 05          |cmp al,5                                    ;  5指的是光盘,3指的是硬盘 00491ABA  |.  75 74          |jnz short 笔试.00491B30        ; 不是光盘就跳走  ★ 00491ABC  |.  68 00010000    |push 100 00491AC1  |.  8D85 ECFDFFFF  |lea eax,dword ptr ss:[ebp-214] 00491AC7  |.  50             |push eax 00491AC8  |.  8D45 EC        |lea eax,dword ptr ss:[ebp-14] 00491ACB  |.  50             |push eax 00491ACC  |.  8D45 F0        |lea eax,dword ptr ss:[ebp-10] 00491ACF  |.  50             |push eax 00491AD0  |.  8D45 F4        |lea eax,dword ptr ss:[ebp-C] 00491AD3  |.  50             |push eax 00491AD4  |.  68 00010000    |push 100 00491AD9  |.  8D85 ECFEFFFF  |lea eax,dword ptr ss:[ebp-114] 00491ADF  |.  50             |push eax 00491AE0  |.  8D85 E4FDFFFF  |lea eax,dword ptr ss:[ebp-21C] 00491AE6  |.  B9 801B4900    |mov ecx,笔试.00491B80                         ;  ASCII ":\" 00491AEB  |.  8B55 F8        |mov edx,dword ptr ss:[ebp-8] 00491AEE  |.  E8 6D2FF7FF    |call 笔试.00404A60 00491AF3  |.  8B85 E4FDFFFF  |mov eax,dword ptr ss:[ebp-21C] 00491AF9  |.  E8 1631F7FF    |call 笔试.00404C14 00491AFE  |.  50             |push eax                                    ; |RootPathName 00491AFF  |.  E8 9050F7FF    |call <jmp.&kernel32.GetVolumeInformationA>  ; \GetVolumeInformationA 00491B04  |.  83F8 01        |cmp eax,1            ; 这里只判断调用是否成功,很弱 00491B07  |.  1BC0           |sbb eax,eax 00491B09  |.  40             |inc eax 00491B0A  |.  84C0           |test al,al 00491B0C  |.  74 22          |je short 笔试.00491B30 ★下面就开始检测光盘上的内容了 00491B0E  |.  8D85 E0FDFFFF  |lea eax,dword ptr ss:[ebp-220]              ;  指针地址 00491B14  |.  8B4D FC        |mov ecx,dword ptr ss:[ebp-4]                ;  路径+文件名 ★这里看下内存,字符是 :\江苏省计算机等级考试全真模拟试卷.exe 00491B17  |.  8B55 F8        |mov edx,dword ptr ss:[ebp-8]                ;  盘符i 00491B1A  |.  E8 412FF7FF    |call 笔试.00404A60                          ;  连接起来,放到指针地址中 00491B1F  |.  8B85 E0FDFFFF  |mov eax,dword ptr ss:[ebp-220]              ;  文件名指针 00491B25  |.  E8 4274F7FF    |call 笔试.00408F6C                          ;  判断文件是否存在 ★就是i:\江苏省计算机等级考试全真模拟试卷.exe 是否存在 00491B2A  |.  84C0           |test al,al 00491B2C  |.  74 02          |je short 笔试.00491B30                      ;  不存在就跳走 00491B2E  |.  B3 01          |mov bl,1                                    ;  这里是标志位,1则表示通过 ★注意这行 00491B30  |>  47             |inc edi 00491B31  |.  83FF 1A        |cmp edi,1A 00491B34  |.^ 0F85 3DFFFFFF  \jnz 笔试.00491A77



通过上面的分析,就知道了,原来程序判断光盘根目录下有没有"江苏省计算机等级考试全真模拟试卷.exe"这个文件有的话就成功通过检测,没有就提示插入光盘

这个过程的返回值是由eax返回的

代码:
00491B0C  |. /74 22          |je short 笔试.00491B30 00491B0E  |. |8D85 E0FDFFFF  |lea eax,dword ptr ss:[ebp-220]              ;  指针地址 00491B14  |. |8B4D FC        |mov ecx,dword ptr ss:[ebp-4]                ;  路径+文件名 00491B17  |. |8B55 F8        |mov edx,dword ptr ss:[ebp-8]                ;  盘符 00491B1A  |. |E8 412FF7FF    |call 笔试.00404A60                          ;  连接起来,放到指针地址中 00491B1F  |. |8B85 E0FDFFFF  |mov eax,dword ptr ss:[ebp-220]              ;  文件名指针 00491B25  |. |E8 4274F7FF    |call 笔试.00408F6C                          ;  判断文件是否存在 00491B2A  |. |84C0           |test al,al 00491B2C  |. |74 02          |je short 笔试.00491B30                      ;  不存在就跳走 00491B2E  |. |B3 01          |mov bl,1                                    ;  这里是标志位,1则表示通过 ★注意这行 00491B30  |> \47             |inc edi 00491B31  |.  83FF 1A        |cmp edi,1A 00491B34  |.^ 0F85 3DFFFFFF  \jnz 笔试.00491A77 00491B3A  |.  33C0           xor eax,eax 00491B3C  |.  5A             pop edx 00491B3D  |.  59             pop ecx 00491B3E  |.  59             pop ecx 00491B3F  |.  64:8910        mov dword ptr fs:[eax],edx 00491B42  |.  68 6C1B4900    push 笔试.00491B6C 00491B47  |>  8D85 E0FDFFFF  lea eax,dword ptr ss:[ebp-220] 00491B4D  |.  BA 03000000    mov edx,3 00491B52  |.  E8 212CF7FF    call 笔试.00404778 00491B57  |.  8D45 F8        lea eax,dword ptr ss:[ebp-8] 00491B5A  |.  BA 02000000    mov edx,2 00491B5F  |.  E8 142CF7FF    call 笔试.00404778 00491B64  \.  C3             retn 00491B65   .^ E9 EE25F7FF    jmp 笔试.00404158 00491B6A   .^ EB DB          jmp short 笔试.00491B47 00491B6C   .  8BC3           mov eax,ebx                                   ★ eax为标志位,返回值为1则通过,返回值为0则不通过检测 00491B6E   .  5F             pop edi 00491B6F   .  5E             pop esi 00491B70   .  5B             pop ebx 00491B71   .  8BE5           mov esp,ebp 00491B73   .  5D             pop ebp 00491B74   .  C3             retn



--------------------------------------------------------------------------------
【破解总结】


既然程序已经分析完了,就可以破解了,下面给出三种方法

一、虚拟光驱法

  这是最直接的方法,既然它检测光盘,那就虚拟一个,欺骗程序。根据分析,程序只检测光盘根目录下有没有"江苏省计算机等级考试全真模拟试卷.exe"这个文件,所以可以只在虚拟光碟你加入这个文件即可,可以减少虚拟光碟文件的大小,也就是通常说的最小光盘镜像
  
二、以硬盘代替光盘

  注意这几行

代码:
00491AB3  |.  E8 5450F7FF    |call <jmp.&kernel32.GetDriveTypeA>          ; \GetDriveTypeA 00491AB8  |.  3C 05          |cmp al,5                                    ;  5指的是光盘,3指的是硬盘 00491ABA  |.  75 74          |jnz short 笔试.00491B30        ; 不是光盘就跳走  ★


  
  判断返回值是否为光盘,如果改为 cmp al,3 即判断是否为硬盘,这样把文件考到硬盘上,连虚拟光驱都可以省了。程序就直接检测硬盘上的文件了

三、爆破法

  这个过程返回值是eax,为1则通过检测,为0则不通过检测,那么,不管前面检测光盘如何,检测文件如何,只要返回值为1就通过了。没有空间,不能打补丁修改eax的值,仔细分析一下程序,看到这行

代码:
00491B2C  |. |74 02          |je short 笔试.00491B30                      ;  不存在就跳走 00491B2E  |. |B3 01          |mov bl,1                                    ;  这里是标志位,1则表示通过 ★注意这行 00491B30  |> \47             |inc edi 在过程中以bl做标志位,这里可以将 00491ABA  |.  75 74          |jnz short 笔试.00491B30        ; 不是光盘就跳走  ★ 这个跳转改一下,直接跳到 00491B2E  |. |B3 01          |mov bl,1                                    ;  这里是标志位,1则表示通过 这行,改为 00491ABA     /75 72          |jnz short 笔试.00491B2E



呵呵,这样就只要有光盘以外的盘都能通过检测了,只改了一个字节,算是最简单的了。
关键是这个程序的检测比较简单,适合新手练习,呵呵

--------------------------------------------------------------------------------
【爆破地址】


代码:
00491ABA  |.  75 74          |jnz short 笔试.00491B30 这行,改为 00491ABA     /75 72          |jnz short 笔试.00491B2E



--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢! 

感谢你把这篇文章看完^_^