原文防盜鏈地址:http://www.cnblogs.com/aj3423/p/3477042.html
xuetr 介紹:http://www.epoolsoft.com/forum.php?mod=viewthread&tid=18&extra=page%3D1
xuetr pro 下載地址:http://down.epoolsoft.com/pchunter/PCHunter_pro.zip
key file 下載: http://files.cnblogs.com/aj3423/pchunter.ek.rar
pro版 介紹上說會讀取 pchunter.ek 這個keyfile,所以od載入,bp CreateFileA, bp CreateFileW
會斷兩次,都是斷在同一個函數,稍微跟幾步會檢查文件大小是不是256字節,不是就over,
打開 pchunter.ek,我開始是填入 12345678901234 ... 123456 共256字節, 填什麼都行,後來發覺填寫 00~FF更方便定位(下面代碼就是這樣)
往下走,來到算法部分,首先是
3個參數的函數 (??, "ShouJiErShiSiShi", 16), 預測是給算法準備key,因爲好多算法都是這樣,先set_key,然後再調用encrypt/decrypt,
緊接着下一行
4個參數的函數 (??, output buffer, key_file內容, 128), 一看就是解密keyfile了,到這還不知道是什麼算法,猜測出aes_decrypt有幾點:
1. 第一個圖的 aes_set_key 裏,用 ida 分析 41FB90,可以看到有 switch( case 16: ... case 24: ... case 32: ), aes中 16,24,32 分別對應密鑰長度是 128, 192, 256 bit,調試時的值是 16, 和上面的key "ShouJiErShiSiShi" 長度是 16 對應
2. 算法有個特徵是異或 0x1B,往上搜了下,aes 中有用到
3. 輸入和輸出有固定模式,因爲輸入是1234567890..這樣,所以圖上5行是一個循環, 而輸出也是5行一個循環,
aes的ecb模式就是,google下可以搜到:
4. 作者肯定是自己encrypt,然後在程序裏在decrypt
簡單寫了個測試,確認是 aes_ecb_decrypt,接着往下
來到一堆獲取時間的函數,但確定不了 是從128字節的哪部分讀取的,所以重新填充key file,這次用 00 ~ FF 填充, 發覺是從偏移 80 和 88 分別讀取了兩個 FILETIME 結構體,作爲starttime 和 endtime
最後,寫段代碼生成 keyfile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
#include
<windows.h> #include
<string> #include
<iostream> #include
<fstream> using namespace std; #include
"crypto/aes.h" // 用到了cryptopp 庫 #include
"crypto/modes.h" #include
"crypto/filters.h" using namespace CryptoPP; template < class ByteT> string
hex2str(ByteT* hex, int len,
const string&
delim= "
" )
{ if (len
== 0) return "" ; string
s; char x[4]; for ( int i=0;
i<len; i++) { sprintf_s(x,
4, "%02X" ,
((unsigned char *)hex)[i]); s
+= x; if (i
!= len-1) s += delim; //
append delim if not the last char } return s; } string
hex2str( const string&
hex, const string&
delim= "
" )
{ return hex2str(hex.c_str(),
hex.length(), delim); } string
aes_encrypt(string& plain, string& key) { ECB_Mode<
AES >::Encryption e((byte*)key.c_str(), key.length()); string
cipher; StringSource
ss(plain, true ,
new StreamTransformationFilter(
e, new StringSink(
cipher ), StreamTransformationFilter::NO_PADDING)
); return cipher; } #pragma
pack(push, 1) struct reg
{ byte
unknown_1[80]; FILETIME
ft_beg; FILETIME
ft_end; byte
unknown[32]; }; #pragma
pack(pop) int main()
{ string
key = "ShouJiErShiSiShi" ; reg
r; byte*
p = (byte*)&r; for (unsigned
int i=0;
i< sizeof (reg);
i++) { //
填充 00 ~ FF p[i]
= i; } SYSTEMTIME
st; GetSystemTime(&st);
//
得到當前時間 -> start time SYSTEMTIME
st_new = st; st_new.wYear
+= 10; //
當前時間+10年 -> end time SystemTimeToFileTime(&st,
&r.ft_beg); //
轉成8字節的 FILETIME,xuetr用的這個 SystemTimeToFileTime(&st_new,
&r.ft_end); string
plain; plain.assign(( const char *)&r,
sizeof (r)); cout
<< "raw:" <<
endl << hex2str(plain) << endl; string
encrypted = aes_encrypt(plain, key); //
加密 //
cout << "encrypted:" << endl << hex2str(encrypted) << endl; ofstream
ofs( "e:/pchunter.ek" ,
ios::binary); //
寫到 key file ofs
<< hex2str(encrypted, "" ); ofs.close(); } |
128 字節的 keyfile,裏面只用到了16字節的兩個 FILETIME 時間? 還是我漏了什麼?