Iceman 发表于 2006-2-9 05:48:42

与keyfile第一次近距离接触

【破文标题】与keyfile第一次近距离接触
【破文作者】Iceman
【作者邮箱】[email protected]
【破解工具】OD、PEID
【破解平台】XP sp2
----------------------------------------------------------------------

--
记得几个月前,刚学破解,第一次遇到keyfile时,用FileMon找出文件名后,什么也不懂了。经过一段时间的学习,重新试下keyfile的保护方式。这篇文章,是我学习《加密与解密实战攻略》第十四章后的学习笔记(14.1的内容和一点整理),希望能帮助到初次接触keyfile的新手。


CreateFile函数原型:

HANDLE CreateFile(

   LPCTSTR lpFileName,                                             //要打开的文件名指针
   DWORD dwDesiredAccess,                                    //存取(读-写)模式
   DWORD dwShareMode                                          //共享模式
   LPSECURITY_ATTRIBUTES lpSecurityAttributes,    //SECURITY_ATTRIUTES 结构指针
   DWORD dwCreationDistribution,                           //打开方式
   DWORD dwFlagsAndAttributes,                              //文件属性
   HANDLE hTemplateFile                                             //GENERIC_READ 方式存取的临时文件句柄
   );


ReadFile函数原型:

BOOL ReadFile(

   HADNLE hFile,                                                      //要读取的文件句柄
   LPVOID lpBuffer,                                                //存放读出数据的缓冲区地址
   DWORD nNumberOfBytesToRead,                      //要读取的字节数
   LPWORD lpNumberOfBytesRead,                        //指向读取字节数的地址
   LPOVERLAPPED lpOverlapped                              //OVERLAPPED 结构的地址
   );



载入OD,bp CreateFileA,运行。追出KEY文件名

7C801A24 >8BFF            mov edi,edi                     //停在这,ALT+F9
7C801A26    55                push ebp
7C801A27    8BEC            mov ebp,esp
7C801A29    FF75 08         push dword ptr ss:
7C801A2C    E8 73C80000       call kernel32.7C80E2A4
7C801A31    85C0            test eax,eax

堆栈信息:
0012FC84   004010B4/CALL 到 CreateFileA 来自 aa.004010AF
0012FC88   004020E5|FileName = ".Key"                     //从这里知道,建立的文件名
0012FC8C   C0000000|Access = GENERIC_READ|GENERIC_WRITE
0012FC90   00000003|ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
0012FC94   00000000|pSecurity = NULL
0012FC98   00000003|Mode = OPEN_EXISTING
0012FC9C   004020EF|Attributes =

READONLY|HIDDEN|SYSTEM|ARCHIVE|NORMAL|402048
0012FCA0   00000000\hTemplateFile = NULL


返回到:
00401098   > \6A 00         push 0                               ; /hTemplateFile = NULL
0040109A   .68 EF204000   push aa.004020EF       ; |Attributes = READONLY|HIDDEN|SYSTEM|ARCHIVE|NORMAL|402048
0040109F   .6A 03         push 3                               ; |Mode = OPEN_EXISTING
004010A1   .6A 00         push 0                               ; |pSecurity = NULL
004010A3   .6A 03         push 3                               ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
004010A5   .68 000000C0   push C0000000                        ; |Access = GENERIC_READ|GENERIC_WRITE
004010AA   .68 E5204000   push aa.004020E5                     ; |FileName = ".Key"
004010AF   .E8 DE000000   call <jmp.&kernel32.CreateFileA>   ; \CreateFileA
004010B4   .A3 00204000   mov dword ptr ds:,eax            //停在这。EAX为建立的文件的Handle
004010B9   .833D 00204000 F>cmp dword ptr ds:,-1            //文件建立成功时为文件Handle,否则为FFFFFFFF(-1)
004010C0   .0F84 92000000   je aa.00401158                            //建立成功,不跳



用WINHEX建个.Key文件,重新运行

清除CreateFileA断点,BP ReadFile,运行

堆栈信息:
0012FC8C   004010DF/CALL 到 ReadFile 来自 aa.004010DA
0012FC90   00000078|hFile = 00000078 (window)            //存放读

出数据的缓冲区地址
0012FC94   004020F3|Buffer = aa.004020F3
0012FC98   0000000A|BytesToRead = A (10.)               //读10字节
0012FC9C   00402107|pBytesRead = aa.00402107
0012FCA0   00000000\pOverlapped = NULL

ALT+F9

返回到:
004010C6   .6A 00         push 0                               ; /pOverlapped = NULL
004010C8   .68 07214000   push aa.00402107                     ; |pBytesRead = aa.00402107
004010CD   .6A 0A         push 0A                              ; |BytesToRead = A (10.)
004010CF   .68 F3204000   push aa.004020F3                     ; |Buffer = aa.004020F3
004010D4   .FF35 00204000   push dword ptr ds:         ; |hFile = 00000078 (window)
004010DA   .E8 C5000000   call <jmp.&kernel32.ReadFile>      ; \ReadFile
004010DF   .85C0            test eax,eax
004010E1   . /74 75         je short aa.00401158               ;//读取不成功,跳
004010E3   .6A 00         push 0                               ; /pOverlapped = NULL
004010E5   .68 07214000   push aa.00402107                     ; |pBytesRead = aa.00402107
004010EA   .6A 0A         push 0A                              ; |BytesToRead = A (10.)
004010EC   .68 FD204000   push aa.004020FD                     ; |Buffer = aa.004020FD
004010F1   .FF35 00204000   push dword ptr ds:         ; |hFile = 00000078 (window)
004010F7   .E8 A8000000   call <jmp.&kernel32.ReadFile>      ; \ReadFile
004010FC   .85C0            test eax,eax
004010FE   .74 58         je short aa.00401158                  //读取成功,不跳
00401100   .FF35 00204000   push dword ptr ds:         ; /hObject = 00000078 (window)
00401106   .E8 93000000   call <jmp.&kernel32.CloseHandle>   ; //关闭Handle
0040110B   .33C0            xor eax,eax
0040110D   .EB 04         jmp short aa.00401113
0040110F   .C9            leave
00401110   .C2 1000         retn 10
00401113   >80B0 F3204000 5>xor byte ptr ds:,58
0040111A   .40            inc eax
0040111B   .80B8 F3204000 0>cmp byte ptr ds:,0
00401122   .^ 75 EF         jnz short aa.00401113
00401124   .68 F3204000   push aa.004020F3                     ; /String2 = "aaaaaaaaaa"
00401129   .68 FD204000   push aa.004020FD                     ; |String1 = ""
0040112E   .E8 77000000   call <jmp.&kernel32.lstrcmp>         ;//比较String2和String1,相等,注册验证成功
00401133   .83F8 00         cmp eax,0                        // 只要xor byte ptr ds:,58结果为0,就注册验证成功
00401136   .74 06         je short aa.0040113E
00401138   .EB 1E         jmp short aa.00401158
0040113A   .C9            leave
0040113B   .C2 1000         retn 10
0040113E   >68 00100000   push 1000                            ; /Style = MB_OK|MB_SYSTEMMODAL
00401143   .68 26204000   push aa.00402026                     ; |Title = "OfficialCrackme"
00401148   .68 BF204000   push aa.004020BF                     ; |Text = "注册验证成功,恭喜您成功破解了这个程序"
0040114D   .6A 00         push 0                               ; |hOwner = NULL
0040114F   .E8 5C000000   call <jmp.&user32.MessageBoxA>       ; \MessageBoxA
00401154   .C9            leave
00401155   .C2 1000         retn 10
00401158   >68 00100000   push 1000                            ; /Style = MB_OK|MB_SYSTEMMODAL
0040115D   .68 26204000   push aa.00402026                     ; |Title = "OfficialCrackme"
00401162   .68 83204000   push aa.00402083                     ; |Text = "革命尚未成功,破解者仍需努力阿。^_^ GOOD LUCK!"
00401167   .6A 00         push 0                               ; |hOwner = NULL
00401169   .E8 42000000   call <jmp.&user32.MessageBoxA>       ; \MessageBoxA
0040116E   .C9            leave


经过学习,知道对附keyfile保护方式的,要用到两个函数CreateFileA,ReadFile。首先找出KEY的文件名,接着追出KEY的文件长度、文件内容。我觉得这个过程,就像破解一个软件,也涉及到很多方面的知识。



----------------------------------------------------------------------

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

xingbing 发表于 2006-2-10 01:38:57

学习中...

underghost 发表于 2006-2-14 21:01:33

谢谢兄弟~~~~~~~~~·

zhengsifeng 发表于 2006-2-15 10:08:25

谢谢提供这些代码。

yefei 发表于 2006-7-7 11:37:14

不错,学习了,还没遇到过这种的呢

dryzh 发表于 2006-7-9 05:21:02

偶也来玩玩!

bfqyygy 发表于 2006-7-14 20:46:01

学习了.收藏一下!!

网游难民 发表于 2006-7-29 10:52:14

怎样用WINHEX建***.Key文件:L
偶没有用过~~


希望能做个演示

[ 本帖最后由 网游难民 于 2006-7-29 12:16 编辑 ]
页: [1]
查看完整版本: 与keyfile第一次近距离接触