如何破解加密狗

来源:百度文库 编辑:神马文学网 时间:2024/04/29 14:09:25
hasp 系列加密狗破解有的朋友认为很难,其实不然,只要有足够的耐心和技术基础。是没有问题的。--------------------------------------------------------------------------------------------------------004015FF   |.   8D95 ACFBFFFF         lea edx,[local.277]00401605   |.   52                             push edx00401606   |.   8B85 F8FBFFFF         mov eax,[local.258]0040160C   |.   50                             push eax0040160D   |.   8B8D A8FBFFFF         mov ecx,[local.278]00401613   |.   51                             push ecx00401614   |.   68 D4E54000             push APP.0040E5D4                               ;   ASCII "EN"00401619   |.   8B55 E8                     mov edx,[local.6]0040161C   |.   52                               push edx0040161D   |.   E8 8E230000           call                ;这个CALL只要一执行,就死掉,所以必须跟进00401622   |.   8945 EC               mov [local.5],eax00401625   |.   8B45 EC               mov eax,[local.5]00401628   |>   8B4D F4               mov ecx,[local.3]0040162B   |.   64:890D 00000000       mov fs:[0],ecx00401632   |.   8B4D E4               mov ecx,[local.7]00401635   |.   E8 C72D0000           call APP.004044010040163A   |.   8BE5                   mov esp,ebp0040163C   |.   5D                     pop ebp0040163D   \.   C3                     retn--------------------------------------------------------------------------------------------------------6、跟进后出现一下代码,看第一行,就是0040161D 处调用的函数,再看右面的注释,心跳加快,InitSystem,从名字上你都能猜想它会干什么,对,读狗的相关代码就应该在这儿初始化(当然还要初始化其他信息),继续跟进--------------------------------------------------------------------------------------------------------004039B0   $- FF25 C8554000         jmp ds:[<&user_In>]             ;   InitSystem004039B6   $- FF25 C4554000         jmp ds:[<&user_Star>]         ;   StartProgram004039BC   $- FF25 C0554000         jmp ds:[<&user_Mai>]004039C2   $- FF25 AC544000         jmp ds:[<&XXX_DLL.#3>]004039C8   $- FF25 A8544000         jmp ds:[<&XXX_DLL.#47>]--------------------------------------------------------------------------------------------------------7、跟进后,代码是一系列的IsBadReadPtr,由此判断该处是初始化内存工作,离读狗还用有一段距离。部分代码如下,还有更多的IsBadReadPtr,没必要就不贴了,贴一点提示思路即可。一直按F8,痛苦的是这段代码中有个循环,要循环20多次,稍不留神就结束循环,立刻进入另一个关键CALL,程序又死掉。所以在这儿又费了我很多时间。--------------------------------------------------------------------------------------------------------00EF5940 >   55                       push ebp       ;InitSystem函数00EF5941     8BEC                     mov ebp,esp00EF5943     81EC 280C0000           sub esp,0C2800EF5949     A1 6C2EF100             mov eax,ds:[F12E6C]00EF594E     8945 E0                 mov ss:[ebp-20],eax00EF5951     57                       push edi00EF5952     8B45 0C                 mov eax,ss:[ebp+C]00EF5955     50                       push eax00EF5956     68 6848F100             push user_dll.00F1486800EF595B     E8 34F70000             call 00EF5960     83C4 08                 add esp,800EF5963     B9 583AF100             mov ecx,user_dll.00F13A5800EF5968     85C9                     test ecx,ecx00EF596A     74 46                   je short user_dll.00EF59B200EF596C     6A 01                   push 100EF596E     68 583AF100             push user_dll.00F13A5800EF5973     FF15 1072F000           call ds:[<&KERNEL32.IsBadWritePtr>]             ; kernel32.IsBadWritePtr00EF5979     85C0                     test eax,eax00EF597B     75 35                   jnz short user_dll.00EF59B200EF597D     837D 10 00               cmp dword ptr ss:[ebp+10],000EF5981     74 26                   je short user_dll.00EF59A900EF5983     6A 01                   push 100EF5985     8B55 10                 mov edx,ss:[ebp+10]00EF5988     52                       push edx00EF5989     FF15 1472F000           call ds:[<&KERNEL32.IsBadReadPtr>]             ; kernel32.IsBadReadPtr00EF598F     85C0                     test eax,eax00EF5991     75 16                   jnz short user_dll.00EF59A900EF5993     68 04010000             push 10400EF5998     8B45 10                 mov eax,ss:[ebp+10]00EF599B     50                       push eax00EF599C     68 583AF100             push user_dll.00F13A5800EF59A1     FF15 1872F000           call ds:[<&KERNEL32.lstrcpynW>]                 ; kernel32.lstrcpynW--------------------------------------------------------------------------------------------------------8、上面代码执行结束后迅速来到下面代码,注释处的CALL执行就死,跟进--------------------------------------------------------------------------------------------------------00EF5D8A     6A 03                   push 300EF5D8C     68 10000100             push 1001000EF5D91     8B15 9C3EF100           mov edx,ds:[F13E9C]00EF5D97     83C2 12                 add edx,1200EF5D9A     52                       push edx00EF5D9B     68 D80CF100             push user_dll.00F10CD800EF5DA0     A1 9C3EF100             mov eax,ds:[F13E9C]00EF5DA5     8B88 2C0F0000           mov ecx,ds:[eax+F2C]00EF5DAB     51                       push ecx00EF5DAC     E8 45E70000             call 00EF5DB1     EB 15                   jmp short user_dll.00EF5DC800EF5DB3     E8 580B0000             call user_dll.00EF6910       ;该CALL执行就死掉,读狗函数在这里00EF5DB8     85C0                     test eax,eax00EF5DBA     74 0C                   je short user_dll.00EF5DC8--------------------------------------------------------------------------------------------------------9、跟进后一直按F8,遇到CALL user_dll.00XXXXXX字样的要格外小心,果然执行到某个CALL的时候死掉,只好记住地址,重设断点,重新来,继续跟进死掉的CALL。由于这儿一直是寻找读狗函数,所以不再贴代码了,大家只看思路,无用代码太多,会扰乱思路.10、不厌其烦的重复上述过程突然发现下面代码,相信仅仅函数名足以让你兴奋-------------------------------------------------------------------------------------------------------00EF6EB8     51                       push ecx00EF6EB9     68 680AF100             push user_dll.00F10A6800EF6EBE     8B15 9C3EF100           mov edx,ds:[F13E9C]00EF6EC4     83C2 12                 add edx,1200EF6EC7     52                       push edx00EF6EC8     E8 85D70000             call    ;LogIn,登录狗00EF6ECD     85C0                     test eax,eax         ;判断返回值,如是000EF6ECF     0F84 B2000000           je user_dll.00EF6F87       ;跳走,死掉00EF6ED5     C705 6C3EF100 01000000   mov dword ptr ds:[F13E6C],100EF6EDF     E8 5CD70000             call      ;读另一个数据,为ReadDong做准备,虽然00EF6EE4     85C0                     test eax,eax         ;不知道读什么,但返回值如是000EF6EE6     0F84 9B000000           je user_dll.00EF6F87       ;跳走,死掉00EF6EEC     8D85 5CFFFFFF           lea eax,ss:[ebp-A4]00EF6EF2     50                       push eax00EF6EF3     E8 54D70000             call    ;再读00EF6EF8     85C0                     test eax,eax         ;判断返回值,如是000EF6EFA     0F84 87000000           je user_dll.00EF6F87       ;OVER00EF6F00     B9 2848F100             mov ecx,user_dll.00F14828       ;判断ECX是否为0,跟踪发现该值是狗的编号00EF6F05     85C9                     test ecx,ecx         ;是0与否,不影响程序运行00EF6F07     74 2B                   je short user_dll.00EF6F3400EF6F09     8D55 98                 lea edx,ss:[ebp-68]         ;该地址存放狗的编号00EF6F0C     85D2                     test edx,edx00EF6F0E     74 16                   je short user_dll.00EF6F2600EF6F10     6A 06                   push 600EF6F12     8D45 98                 lea eax,ss:[ebp-68]00EF6F15     50                       push eax00EF6F16     68 2848F100             push user_dll.00F1482800EF6F1B     FF15 E875F000           call ds:[<&MSVCR71.strncpy>]                 ; MSVCR71.strncpy--------------------------------------------------------------------------------------------------------11、聪明的你肯定知道该做什么了,对,只要把00EF6ECF、00EF6EE6、00EF6EFA三处的je改为jne即可跳过狗的检查。我毫不犹豫的就改了,运行,然而并没有出现预想的兴奋的事情。出现一个错误提示“没有发现可选文件”。12、“可选文件”是什么意思,到软件安装目录查看,有个OPTION文件夹,里面有很多文件,用UltraEdit打开,看不懂呵呵13、将改文件夹中的文件所有文件删除,带狗运行,出现和11步同样的提示;恢复文件,运行正常。由此可见,解密那些文件需要狗中的数据,大家知道HASP狗用的是AES,难道狗中存放着AES密码??带着这样的疑问跟踪程序,来到下面代码--------------------------------------------------------------------------------------------------------00EF723F     8B8D 68F6FFFF           mov ecx,ss:[ebp-998]   ;压入的三个参数意义就不说明了,因为没必要00EF7245     51                       push ecx00EF7246     8D95 64F8FFFF           lea edx,ss:[ebp-79C]00EF724C     52                       push edx00EF724D     8D85 BCFAFFFF           lea eax,ss:[ebp-544]00EF7253     50                       push eax00EF7254     E8 47180000             call user_dll.00EF8AA0       ;该函数执行完后,EDX会出现一些明码,明码信息大概为APPLICAITON=XXX;OPTION=XXX.....是不是很像文件启动需要检查的选项?所以要弄懂解密算法,必须跟进--------------------------------------------------------------------------------------------------------14、跟进后,部分代码如下,这部分代码很关键,所以贴的比较多。但是有很多是内核函数,很容易读懂。--------------------------------------------------------------------------------------------------------00EF8B30     8D8D 68FDFFFF           lea ecx,ss:[ebp-298]00EF8B36     51                       push ecx00EF8B37     8B55 0C                 mov edx,ss:[ebp+C]00EF8B3A     83C2 2C                 add edx,2C00EF8B3D     52                       push edx00EF8B3E     68 5038F100             push user_dll.00F1385000EF8B43     E8 14BD0000             call    ; 获取文件完整路径00EF8B48     6A 00                   push 000EF8B4A     8D85 70FFFFFF           lea eax,ss:[ebp-90]00EF8B50     50                       push eax00EF8B51     8D8D 68FDFFFF           lea ecx,ss:[ebp-298]00EF8B57     51                       push ecx00EF8B58     E8 63BC0000             call 00EF8B5D     50                       push eax00EF8B5E     FF15 0872F000           call ds:[<&KERNEL32.OpenFile>]                 ; 打开文件00EF8B64     8985 54FDFFFF           mov ss:[ebp-2AC],eax00EF8B6A     83BD 54FDFFFF FF         cmp dword ptr ss:[ebp-2AC],-100EF8B71     74 55                   je short user_dll.00EF8BC800EF8B73     8B95 50FDFFFF           mov edx,ss:[ebp-2B0]00EF8B79     52                       push edx00EF8B7A     8B85 60FDFFFF           mov eax,ss:[ebp-2A0]         ;存放读入数据的缓冲区,关键(后面破解用上)00EF8B80     50                       push eax00EF8B81     8B8D 54FDFFFF           mov ecx,ss:[ebp-2AC]00EF8B87     51                       push ecx00EF8B88     FF15 F071F000           call ds:[<&KERNEL32._hread>]                   ; 读文件,ebp-2A0为存放读入数据的缓冲区00EF8B8E     3B85 50FDFFFF           cmp eax,ss:[ebp-2B0]00EF8B94     75 19                   jnz short user_dll.00EF8BAF00EF8B96     8B55 10                 mov edx,ss:[ebp+10]00EF8B99     52                       push edx00EF8B9A     8B85 64FDFFFF           mov eax,ss:[ebp-29C]00EF8BA0     50                       push eax00EF8BA1     8B8D 60FDFFFF           mov ecx,ss:[ebp-2A0]         ;存放解密后的数据,和读入缓冲区地址相同00EF8BA7     51                       push ecx00EF8BA8     E8 B1BA0000             call        ;对读入的数据进行解密,须弄懂算法00EF8BAD     EB 0A                   jmp short user_dll.00EF8BB900EF8BAF     C785 64FDFFFF 00000000   mov dword ptr ss:[ebp-29C],000EF8BB9     8B95 54FDFFFF           mov edx,ss:[ebp-2AC]00EF8BBF     52                       push edx00EF8BC0     FF15 F471F000           call ds:[<&KERNEL32._lclose>]                   ; 关闭文件00EF8BC6     EB 0A                   jmp short user_dll.00EF8BD200EF8BC8     C785 64FDFFFF 00000000   mov dword ptr ss:[ebp-29C],0       ;后面的函数不做解释了,只需知道解密后的00EF8BD2     8B85 60FDFFFF           mov eax,ss:[ebp-2A0]         ;数据存放在ebp-2A000EF8BD8     0385 64FDFFFF           add eax,ss:[ebp-29C]00EF8BDE     C600 00                 mov byte ptr ds:[eax],000EF8BE1     8B4D 08                 mov ecx,ss:[ebp+8]00EF8BE4     8B95 60FDFFFF           mov edx,ss:[ebp-2A0]00EF8BEA     8911                     mov ds:[ecx],edx00EF8BEC     8B85 64FDFFFF           mov eax,ss:[ebp-29C]00EF8BF2     8B4D FC                 mov ecx,ss:[ebp-4]00EF8BF5     E8 E8C30000             call user_dll.00F04FE200EF8BFA     8BE5                     mov esp,ebp00EF8BFC     5D                       pop ebp00EF8BFD     C3                       retn--------------------------------------------------------------------------------------------------------15、为了得到解密后的数据,跟进00EF8BA8处的call ,看看到底是什么算法。可是乐观的情绪又受打击,该函数有大量的花指令,菜鸟阶段,不懂如何去除花指令,研究肯定不是一天两天的事。所以不能在一棵树上吊死,换个思维,为什么不能用程序本身的代码进行解密呢!!!对,就让程序自身帮我们干活!说干就干,在步骤13的00EF723F处设断,反复运行程序,每执行一次查看ebp-2A0处的值,并dump出来,另存为16进制文件,这些文件就是解密过的文件,将其覆盖原来的加密文件。剩下要做的就是跳过上面代码中的解密模块(_hlk_Crypt)。这个很简单,来到00EF8B8E 处,即程序刚进行完_hread之后,将该处的代码cmp eax,ss:[ebp-2B0]改为jmp 00EF8BB9然后汇编。由于_hread函数和_hlk_Crypt函数用的是同一个缓冲区,所以_hread函数执行完毕后,ebp-2A0处的已解密数据就可顺利为后续程序使用了。16、经过上面修改后,F9,程序顺利启动!!!!【继续完善】17、程序运行一段时间后,弹出对话框,通知确定狗的存在!!看来程序启动中还是要定时检查的。第一个念头:查找SetTimer函数,果然找到,且只有一次调用,心想就是这个函数在作怪了,该函数的uElapsed值为1秒,我将其该为9A7EC800,即30天。运行,可是仍然定时检查狗的存在第二个念头:查找其他有关时间的函数,但感觉有点费劲,进而转第三个念头第三个念头:以其他的函数设断点,如大家常用的CreateFile、DeviceIoControl等,但没用过,感觉肯定不是跟踪一两句代码就可搞定的事情,进而转第四个念头第四个念头:一劳永逸的想法,从源头解决问题。为什么不直接修改读狗函数的返回值?这样程序无论何时检查狗都无所谓。重新跟进hlk_LogIn、hlk_Avail、hlk_ReadDong三个函数,发现这三个函数返回前都有共同的代码:--------------------------------------------------------------------------------------------------------00B5126C     837D FC 00               cmp dword ptr ss:[ebp-4],0     ;看ebp-4是否为000B51270     0F94C0                   sete al         ;是,则eax=1,有狗00B51273     8B4D F4                 mov ecx,ss:[ebp-C]00B51276     E8 C6640400             call HLK_dll.00B97741     ;该CALL并不是真正函数,经验证不影响上面的EAX值00B5127B     8BE5                     mov esp,ebp00B5127D     5D                       pop ebp00B5127E     C2 0C00                 retn 0C-----------------------------------------------------------------------------------------------------不插狗的情况下[ebp-4] = 9,因此eax = 0,无狗,因此只需将 sete al改为 setne al,汇编,即可。至此,打狗结束,程序非常正常。将修改后的文件另存到可执行文件,做为补丁,覆盖原文件,狗解除。