【破文作者】 hbqjxhw[pyg]
【文章题目】 [破]Prof. DrAcULA presents, Cryptok KeyfileMe {4}
【下载地址】 http://www.crackmes.de/users/profdracula/cryptok_keyfileme_4/
----------------------------------------------------------------------------------------------
【破解工具】 OD
【破解平台】 WinXP SP2
----------------------------------------------------------------------------------------------
【软件简介】
Prof. DrAcULA presents, Cryptok KeyfileMe {4}
============================================
It is the 4th crackme in the Cryptok-series.
Hope you enjoy this!
You have to:
1. Code a keyfile-maker(inline-keygen is not allowed).
Solution for this KeyfileMe means;
1. Tutorial explaining how it works.
2. No patching, no self-keygenning.
3. A working keyfile-maker, with source.
Protection Level : For you to rate it
See u with next Cryptok Relaese.
----------------------------------------------------------------------------------------------
【破解过程】
春节即将到了,特地再发一篇与大家学习,特借贵坛祝大家新年快乐!恭喜发财!
用OD载入程序之后,搜索当前模块中的名称,发现一个可疑的函数CreateFileA,所以下断bp CreateFileA,运行软件
7C801A24 > 8BFF MOV EDI,EDI---------------->停在这里,看堆栈
7C801A26 55 PUSH EBP
7C801A27 8BEC MOV EBP,ESP
7C801A29 FF75 08 PUSH DWORD PTR SS:[EBP+8]
7C801A2C E8 43C60000 CALL kernel32.7C80E074
7C801A31 85C0 TEST EAX,EAX
7C801A33 74 1E JE SHORT kernel32.7C801A53
7C801A35 FF75 20 PUSH DWORD PTR SS:[EBP+20]
7C801A38 FF75 1C PUSH DWORD PTR SS:[EBP+1C]
7C801A3B FF75 18 PUSH DWORD PTR SS:[EBP+18]
7C801A3E FF75 14 PUSH DWORD PTR SS:[EBP+14]
7C801A41 FF75 10 PUSH DWORD PTR SS:[EBP+10]
7C801A44 FF75 0C PUSH DWORD PTR SS:[EBP+C]
7C801A47 FF70 04 PUSH DWORD PTR DS:[EAX+4]
7C801A4A E8 11ED0000 CALL kernel32.CreateFileW
7C801A4F 5D POP EBP
7C801A50 C2 1C00 RETN 1C
0012FC4C 0040175A /CALL 到 CreateFileA 来自 Cryptok_.00401755
0012FC50 00401735 |FileName = "keyfile.ctk"---------------------》这个就是我们要在其目录下建立的文件了。
0012FC54 80000000 |Access = GENERIC_READ
0012FC58 00000000 |ShareMode = 0
0012FC5C 00000000 |pSecurity = NULL
0012FC60 00000003 |Mode = OPEN_EXISTING
0012FC64 00000080 |Attributes = NORMAL
0012FC68 00000000 \hTemplateFile = NULL
在其目录下建立了keyfile.ctk文件之后。ALT+F9
00401755 E8 B6010000 CALL <JMP.&kernel32.CreateFileA>
0040175A 83F8 FF CMP EAX,-1------------------------>返回到这里
0040175D 0F84 54010000 JE Cryptok_.004018B7
00401763 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00401766 6A 00 PUSH 0
00401768 FF75 FC PUSH DWORD PTR SS:[EBP-4]
0040176B E8 CA010000 CALL <JMP.&kernel32.GetFileSize>
00401770 83F8 05 CMP EAX,5
00401773 73 0D JNB SHORT Cryptok_.00401782
00401775 FF75 FC PUSH DWORD PTR SS:[EBP-4]
00401778 E8 87010000 CALL <JMP.&kernel32.CloseHandle>
0040177D E9 35010000 JMP Cryptok_.004018B7
00401782 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
00401785 6A 00 PUSH 0
00401787 68 53314000 PUSH Cryptok_.00403153
0040178C 6A 03 PUSH 3
0040178E 68 70354000 PUSH Cryptok_.00403570 ; ASCII "WWW.PEDIY.COM"
00401793 FF75 FC PUSH DWORD PTR SS:[EBP-4]
00401796 E8 BD010000 CALL <JMP.&kernel32.ReadFile> ; 读取文件的前3个字符(前3位就是我们的注册标志)
0040179B 0BC0 OR EAX,EAX
0040179D 75 0D JNZ SHORT Cryptok_.004017AC
0040179F FF75 FC PUSH DWORD PTR SS:[EBP-4]
004017A2 E8 5D010000 CALL <JMP.&kernel32.CloseHandle>
004017A7 E9 0B010000 JMP Cryptok_.004018B7
004017AC 33C0 XOR EAX,EAX
004017AE BB 50000000 MOV EBX,50 ; 0x50给EBX
004017B3 3098 70354000 XOR BYTE PTR DS:[EAX+403570],BL ; BL与读取文件的前3个字符异或
004017B9 43 INC EBX ; EBX加1
004017BA 40 INC EAX ; EAX加1
004017BB 83F8 03 CMP EAX,3 ; 判断是否计算完
004017BE ^ 75 F3 JNZ SHORT Cryptok_.004017B3
004017C0 C605 73354000 0>MOV BYTE PTR DS:[403573],0
004017C7 68 70354000 PUSH Cryptok_.00403570 ; ASCII "WWW.PEDIY.COM"
004017CC 6A 03 PUSH 3
004017CE E8 2DF8FFFF CALL Cryptok_.00401000 ; 异或后的3个字符作CRC32计算
004017D3 35 4973AA4D XOR EAX,4DAA7349 ; 计算的结果是否等于0X4DAA7349
004017D8 0BC0 OR EAX,EAX
004017DA 74 0D JE SHORT Cryptok_.004017E9 ; 如果不等于则OVER
004017DC FF75 FC PUSH DWORD PTR SS:[EBP-4]
004017DF E8 20010000 CALL <JMP.&kernel32.CloseHandle>
004017E4 E9 CE000000 JMP Cryptok_.004018B7
004017E9 6A 64 PUSH 64
004017EB 68 70354000 PUSH Cryptok_.00403570 ; ASCII "WWW.PEDIY.COM"
004017F0 E8 69010000 CALL <JMP.&kernel32.RtlZeroMemory>
004017F5 6A 00 PUSH 0
004017F7 6A 00 PUSH 0
004017F9 6A 03 PUSH 3
004017FB FF75 FC PUSH DWORD PTR SS:[EBP-4]
004017FE E8 61010000 CALL <JMP.&kernel32.SetFilePointer>
00401803 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00401806 83E8 03 SUB EAX,3 ; 文件位数减去前面取了的3位
00401809 6A 00 PUSH 0
0040180B 68 53314000 PUSH Cryptok_.00403153
00401810 50 PUSH EAX
00401811 68 70354000 PUSH Cryptok_.00403570 ; ASCII "WWW.PEDIY.COM"
00401816 FF75 FC PUSH DWORD PTR SS:[EBP-4]
00401819 E8 3A010000 CALL <JMP.&kernel32.ReadFile> ; 从第4个字符读取文件
0040181E 0BC0 OR EAX,EAX
00401820 75 0D JNZ SHORT Cryptok_.0040182F
00401822 FF75 FC PUSH DWORD PTR SS:[EBP-4]
00401825 E8 DA000000 CALL <JMP.&kernel32.CloseHandle>
0040182A E9 88000000 JMP Cryptok_.004018B7
0040182F 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8]
00401832 83EA 04 SUB EDX,4 ; 文件位数减去4位(从第4位到倒数第2位就是我们的Name)
00401835 33C0 XOR EAX,EAX
00401837 BB 44000000 MOV EBX,44 ; 0x44给EBX
0040183C 3098 70354000 XOR BYTE PTR DS:[EAX+403570],BL ; BL与文件的第3个以后的字符异或(不包括最后一位)
00401842 43 INC EBX ; EBX加1
00401843 40 INC EAX ; EAX加1
00401844 3BC2 CMP EAX,EDX ; 判断是否计算完
00401846 ^ 75 F4 JNZ SHORT Cryptok_.0040183C
00401848 8A90 70354000 MOV DL,BYTE PTR DS:[EAX+403570]
0040184E 8855 F7 MOV BYTE PTR SS:[EBP-9],DL ; 文件的最后一位给SS[EBP-9]后面比较将用到
00401851 C680 70354000 0>MOV BYTE PTR DS:[EAX+403570],0
00401858 68 D4354000 PUSH Cryptok_.004035D4 ; ASCII "WWW.PEDIY.COM"
0040185D 68 70354000 PUSH Cryptok_.00403570 ; ASCII "WWW.PEDIY.COM"
00401862 E8 49010000 CALL Cryptok_.004019B0
00401867 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
0040186A 83E8 04 SUB EAX,4
0040186D 68 70354000 PUSH Cryptok_.00403570 ; ASCII "WWW.PEDIY.COM"
00401872 50 PUSH EAX
00401873 E8 88F7FFFF CALL Cryptok_.00401000 ; 异或后的字符作CRC32计算
00401878 0FC8 BSWAP EAX ; 交换EAX寄存器里字节的顺序
0040187A 32C4 XOR AL,AH ; EAX的AH高位与AL低位异或
0040187C 3A45 F7 CMP AL,BYTE PTR SS:[EBP-9] ; 异或的结果是否等于文件的最后一位
0040187F 74 0A JE SHORT Cryptok_.0040188B ; 如果不是则OVER
00401881 FF75 FC PUSH DWORD PTR SS:[EBP-4]
00401884 E8 7B000000 CALL <JMP.&kernel32.CloseHandle>
00401889 EB 2C JMP SHORT Cryptok_.004018B7
0040188B E8 04000000 CALL Cryptok_.00401894
00401890 59 POP ECX
00401891 65:73 00 JNB SHORT Cryptok_.00401894 ; 多余前缀
00401894 58 POP EAX
00401895 50 PUSH EAX
00401896 6A 69 PUSH 69
00401898 FF75 08 PUSH DWORD PTR SS:[EBP+8]
0040189B E8 52000000 CALL <JMP.&user32.SetDlgItemTextA>
004018A0 68 D4354000 PUSH Cryptok_.004035D4 ; ASCII "WWW.PEDIY.COM"
004018A5 6A 6A PUSH 6A
004018A7 FF75 08 PUSH DWORD PTR SS:[EBP+8]
004018AA E8 43000000 CALL <JMP.&user32.SetDlgItemTextA>
004018AF FF75 FC PUSH DWORD PTR SS:[EBP-4]
004018B2 E8 4D000000 CALL <JMP.&kernel32.CloseHandle>
004018B7 61 POPAD
004018B8 C9 LEAVE
004018B9 C2 0400 RETN 4
----------------------------------------------------------------------------------------------
【要点总结】
XOR EAX,4DAA7349要点应该是这个,CRC32的逆向是强行跳过之后,根据它弹出的对话框才看到Yes的,所以根据经验猜到了CRC32(Yes)=0x4daa7349
(不知哪位有CRC32的逆向穷举代码或程序,还请上传一封与大家分享*_*)
【文件生成注册机】
#include "stdio.h"
#include "string.h"
unsigned long crc_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
0x2d02ef8d
};
unsigned long crc32(unsigned long crc, unsigned char buf)
{
crc = crc ^ 0xffffffff;
crc = crc_table[((int)crc ^ buf) & 0xff]^(crc >> 8);
return crc^ 0xffffffff;
}
void main(){
FILE *fp;
int i;
unsigned long crc=0;
char name[20],str[]="Yes";
printf("Enter your name:");
gets(name);
int len=strlen(name);
fp=fopen("keyfile.ctk","wb+");
for (i=0;i<3;i++)
fprintf(fp,"%c",str[i]^(0x50+i));
for(i=0;i<len;i++)
fprintf(fp,"%c",name[i]^(0x44+i));
for(i=0;i<len;i++)
crc = crc32(crc, name[i]);
crc=(crc>>0x18)^(crc>>0x10&0xff);
fprintf(fp,"%c",crc);
fclose(fp);
}
----------------------------------------------------------------------------------------------
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
----------------------------------------------------------------------------------------------
文章写于2007-2-16 23:08:45
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)