KeyFile的意思就是密钥文件,它主要呢存在于某些需要注册的软件中,就是说你用一款软件它需要注册并且购买它才可以解锁使用它,这个KeyFile呢就是软件的某个文件,每次软件启动都要从系统根目录或者软件目录中搜寻这个密钥文件,文件里面记录着你的注册信息和注册码以及一些数据,软件利用某种函数将这些数据转化为它可以识别的数据在判断注册的信息是否一致如果一致就进入购买后的版本如果不一致就进入一个试用期的版本。当然呢,还有一种情况是你当时下载的就是个未注册版本,当你注册之后软件向后台发送一些注册数据,然后作者将KeyFile文件发给你,让你放在某个目录下。
相关API函数
FindFirstFileA ;确定注册文件是否存在
CreateFileA、_Iopen ;确认文件是否存在;打开文件以获得其句柄
GetFileSize、GetFileSizeEx ;获得注册文件的大小
GetFileAttributesA、GetFileAttributesExA ; 获得注册文件的属性
SetFilePointer、SetFilePointerEx ;移动文件指针
ReadFile ;读取文件内容
拆解的一般思路:用Process Monitor 等工具监视软件对文件的操作,以找到KeyFile的文件名
伪造一个KeyFile文件用十六进制工具编辑和修改
在调试器里用CreateFileA函数设段,查看打开文件名的指针
用ReadFile设段,分析给ReadFile函数的文件句柄和缓冲区地址。
用CreateFileA函数设段举例子
下断点
004016D8 . 52 push edx ; |FileName = "j"
004016D9 . E8 1C010000 call <jmp.&KERNEL32.CreateFileA> ; \CreateFileA
004016DE . 83F8 FF cmp eax,-0x1
004016E1 . 74 64 je short PacMe.00401747
观察其FileNme
check之后
004016D9 . E8 1C010000 call <jmp.&KERNEL32.CreateFileA> ; \CreateFileA
004016DE . 83F8 FF cmp eax,-0x1
004016E1 . 74 64 je short PacMe.00401747
004016E3 . A3 44344000 mov dword ptr ds:[0x403444],eax
004016E8 . 6A 00 push 0x0 ; /pOverlapped = NULL
004016EA . 68 48344000 push PacMe.00403448 ; |pBytesRead = PacMe.00403448
004016EF . 6A 01 push 0x1 ; |BytesToRead = 0x1
004016F1 . 68 FA344000 push PacMe.004034FA ; |Buffer = PacMe.004034FA
004016F6 . FF35 44344000 push dword ptr ds:[0x403444] ; |hFile = NULL
004016FC . E8 11010000 call <jmp.&KERNEL32.ReadFile> ; \ReadFile
00401701 . 0FB605 FA344000 movzx eax,byte ptr ds:[0x4034FA]
00401708 . 85C0 test eax,eax
0040170A . 74 3B je short PacMe.00401747
0040170C . 6A 00 push 0x0 ; /pOverlapped = NULL
0040170E . 68 48344000 push PacMe.00403448 ; |pBytesRead = PacMe.00403448
00401713 . 50 push eax ; |BytesToRead = 0x0
00401714 . 68 88324000 push PacMe.00403288 ; |Buffer = PacMe.00403288
00401719 . FF35 44344000 push dword ptr ds:[0x403444] ; |hFile = NULL
0040171F . E8 EE000000 call <jmp.&KERNEL32.ReadFile> ; \ReadFile
00401724 . E8 D7F8FFFF call PacMe.00401000
00401729 . 6A 00 push 0x0 ; /pOverlapped = NULL
0040172B . 68 48344000 push PacMe.00403448 ; |pBytesRead = PacMe.00403448
00401730 . 6A 12 push 0x12 ; |BytesToRead = 12 (18.)
00401732 . 68 E8344000 push PacMe.004034E8 ; |Buffer = PacMe.004034E8
00401737 . FF35 44344000 push dword ptr ds:[0x403444] ; |hFile = NULL
0040173D . E8 D0000000 call <jmp.&KERNEL32.ReadFile> ; \ReadFile
00401742 . E8 82F9FFFF call PacMe.004010C9
00401747 > FF35 44344000 push dword ptr ds:[0x403444] ; /hObject = NULL
0040174D . E8 A2000000 call <jmp.&KERNEL32.CloseHandle> ; \CloseHandle
分有三次读取数据,第三次为核心数据 40173D
call 4010c9
004010C9 /$ 55 push ebp
004010CA |. 8BEC mov ebp,esp
004010CC |. 83C4 FC add esp,-0x4
004010CF |. 68 65334000 push PacMe.00403365 ;
****************
C*......*...****
.*.****...*....*
.*..**********.*
..*....*...*...*
*.****.*.*...***
*.*....*.*******
..*.***..*.....*
.*..***.**.***.*
...****....*X..*
****************
004010D4 |. 68 BC314000 push PacMe.004031BC ;
****************
C*......*...****
.*.****...*....*
.*..**********.*
..*....*...*...*
*.****.*.*...***
*.*....*.*******
..*.***..*.....*
.*..***.**.***.*
...****....*X..*
****************
004010D9 |. E8 3A070000 call <jmp.&KERNEL32.lstrcpyA> ; \lstrcpyA 为复制字串
吃豆子柚子 C吃家 X终点 *墙壁 。豆子
00401033 $ 55 push ebp
00401034 . 8BEC mov ebp,esp
00401036 . 83C4 F8 add esp,-0x8
00401039 . 8B15 84314000 mov edx,dword ptr ds:[0x403184] ; C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************
0040103F . 8955 FC mov dword ptr ss:[ebp-0x4],edx ; PacMe.00403192
00401042 . 0AC0 or al,al ; Switch (cases 0..2)
00401044 . 75 09 jnz short PacMe.0040104F ;向上移
00401046 . 832D 84314000 10 sub dword ptr ds:[0x403184],0x10 ; Case 0 of switch 00401042
0040104D . EB 1F jmp short PacMe.0040106E
0040104F > 3C 01 cmp al,0x1
00401051 . 75 08 jnz short PacMe.0040105B
00401053 . FF05 84314000 inc dword ptr ds:[0x403184] ; 向右移
00401059 . EB 13 jmp short PacMe.0040106E
0040105B > 3C 02 cmp al,0x2
0040105D . 75 09 jnz short PacMe.00401068
0040105F . 8305 84314000 10 add dword ptr ds:[0x403184],0x10 ; 向下移
00401066 . EB 06 jmp short PacMe.0040106E
00401068 > FF0D 84314000 dec dword ptr ds:[0x403184] ; 向左移
0040106E > 8B15 84314000 mov edx,dword ptr ds:[0x403184] ; C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************
00401074 . 8A02 mov al,byte ptr ds:[edx]
00401076 . 3C 2A cmp al,0x2A
00401078 . 75 06 jnz short PacMe.00401080
0040107A . 33C0 xor eax,eax
0040107C . C9 leave
0040107D . C3 retn
0040107E . /EB 33 jmp short PacMe.004010B3
00401080 > |3C 58 cmp al,0x58 ;检查最后是否为“X”
00401082 . |75 2F jnz short PacMe.004010B3
00401084 . |6A 00 push 0x0 ; /Style = MB_OK|MB_APPLMODAL
00401086 . |8D15 59334000 lea edx,dword ptr ds:[0x403359] ; |Success..
0040108C . |52 push edx ; |Title = "KwazyWeb.bit"
0040108D . |8D15 EC324000 lea edx,dword ptr ds:[0x4032EC] ; |Congratulations!\n\rMail me (KwazyWebbit@hotmail.com) how you did it.\n\rDont forget to include your keyfile! =]
00401093 . |52 push edx ; |Text = "KwazyWeb.bit"
00401094 . |6A 00 push 0x0 ; |hOwner = NULL
00401096 . |8D15 AC174000 lea edx,dword ptr ds:[0x4017AC] ; |
0040109C . |FFD2 call edx ; \MessageBoxA
0040109E . |8D15 7B324000 lea edx,dword ptr ds:[0x40327B] ; Cracked by :
004010A4 . |52 push edx ; /Text = "KwazyWeb.bit"
004010A5 . |FF35 20344000 push dword ptr ds:[0x403420] ; |hWnd = 00420D8E ('UNREGISTERED!',class='Edit',parent=00310DA8)
004010AB . |8D15 DC174000 lea edx,dword ptr ds:[0x4017DC] ; |
004010B1 . |FFD2 call edx ; \SetWindowTextA
004010B3 > \8B15 84314000 mov edx,dword ptr ds:[0x403184] ; C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************
004010B9 . C602 43 mov byte ptr ds:[edx],0x43 ;"C"的值为43
004010BC . 8B55 FC mov edx,dword ptr ss:[ebp-0x4]
004010BF . C602 20 mov byte ptr ds:[edx],0x20
004010C2 . B8 01000000 mov eax,0x1
004010C7 . C9 leave
004010C8 . C3 retn
可以看到 0 1 2 3 分别代表上右下左
004010F5 |> /C645 FF 08 /mov byte ptr ss:[ebp-0x1],0x8
004010F9 |> |806D FF 02 |/sub byte ptr ss:[ebp-0x1],0x2
004010FD |. |0FB64D FE ||movzx ecx,byte ptr ss:[ebp-0x2]
00401101 |. |81C1 E8344000 ||add ecx,PacMe.004034E8
00401107 |. |8A01 ||mov al,byte ptr ds:[ecx]
00401109 |. |8A4D FF ||mov cl,byte ptr ss:[ebp-0x1]
0040110C |. |D2E8 ||shr al,cl
0040110E |. |24 03 ||and al,0x3
00401110 |. |E8 1EFFFFFF ||call PacMe.00401033
00401115 |. 85C0 ||test eax,eax
00401117 |. 74 11 ||je short PacMe.0040112A
00401119 |. 0FB655 FF ||movzx edx,byte ptr ss:[ebp-0x1]
0040111D |. 85D2 ||test edx,edx ; PacMe.00403192
0040111F |.^ 75 D8 |\jnz short PacMe.004010F9 ;进行小循环 len=8 每次-6 则为4次
00401121 |. FE45 FE |inc byte ptr ss:[ebp-0x2]
00401124 |. 807D FE 12 |cmp byte ptr ss:[ebp-0x2],0x12 ;遍历12H字节
00401128 |.^ 75 CB \jnz short PacMe.004010F5 ;没有则继续
0040112A |> C9 leave
0040112B \. C3 retn
一共可以走18次 每次可以走4步
则为 2221 2223 2211 0100 1110 0333 0300 1111 1211 0112 1112 2332 3303 3222 3221 1100 1111 2233
四进制转十六进制
A9 AB A5 10 54 3F 30 55 65 16 56 BE F3 EA E9 50 55 AF
用pediy作为用户名可以推出Filekey
05 70 65 64 69 79 B2 B0 BE 0B 4F 24 2B 4E 7E 0D 4D A5 E8 F1 F2 4B 4E B4
05为姓名字符数 70-79为姓名ASCII 后面为数据
名字和取低8位 1Bh 依此与数据异或得到 B2 B0 BE 0B 4F 24 2B 4E 7E 0D 4D A5 E8 F1 F2 4B 4E B4
小总结:通过演示 可以得出keyfile会有几个组成部分· 名字字符 名字和 数据 (不过具体情况具体分析)
注意循环与大循环之间的代码·