軟件名稱:易觸得翻書系統v3.4.2
下載地址:http://www.crsky.com/soft/34451.html
主程序是Bookshow.exe,注冊碼是在BookSet.exe里面輸入,首先查殼兩個都是vb6無殼。
首先看BookSet.exe,
直接打開點注冊是這樣子,是重啟驗證
vb的程序用VB Decompiler 反編譯看一下,可以看到有MD5和AES算法
frmReg是程序注冊的窗口,但是啟動的時候就已經顯示了“您的軟件未注冊”幾個字,說明驗證是在啟動的時候,
所以從frmStart -> Form_Load_47D304里面找,
單純靜態分析逆算法不容易,我們用OD來調試,
vb PCODE的調試跟native的有些不一樣
47CBAB下內存訪問斷點(p-code只能下內存斷點,因為代碼是在vb虛擬機里運行的),,
按F9運行,斷在了47CBA9(ESI是實際運行的代碼)
大概猜測這里是從reg.db里面讀取了注冊碼并且用clsBlowfish.DecryptFileAsStr算法解密的,
繼續追蹤,在frmStart -> Form_Load_47D304里面可以找到
loc_47D127: Set var_210 = Nothing
loc_47D139: MemVar_4920E4 = Proc_19_1_467B14(0, 0) '計算硬盤序列號 modDiskInfo.Proc_467B14
loc_47D140: MemVar_4920E0 = MemVar_4920E4 '這里賦值
loc_47D15D: var_F4 = 16
從4920e0下硬件寫入斷點,F9 2次,直到4920e0的數據變化,可以看到MemVar_4920E所指向的數據,[[4920E0]]=[545D7C]="ST1000DM003-1ER162,W4Y5R3FH",這個是電腦的硬盤型號
斷在的地方ESI為47D144
然后再來看Bookshow.exe,同樣先反編譯
在frmStart.FormLoad里面可以找到
后面還有
可以知道有一些字符串運算,到底算的是什么,一一下斷點調試太費時,
我們可以用smart check軟件看一下比較方便,
可以看到是用|間隔的一串字符串,我們之前輸入的序列號就保存在其中,
這樣很快定位到了關鍵代碼
[Asm] 純文本查看 復制代碼
loc_43714B: MsgBox("找不到數據文件!", &H30, "提示", var_140, var_160)
loc_43715B: End
loc_43715D: Exit Sub
loc_43715E: End If
loc_43716D: MemVar_4450A0 = Proc_10_1_42F524(0, 0) '讀取硬盤序列號
loc_437174: MemVar_44509C = MemVar_4450A0
loc_437191: var_140 = 16
loc_43719C: Proc_12_14_43CBD8(var_160, Ucase(CVar(MemVar_4450A0 & MemVar_4450A8 & "eacde")), var_140) ’計算MD5(硬盤序列號EACDESOFT+"eacde") ST1000DM003-1ER162,W4Y5R3FHEACDESOFTEACDE 就是序列號+EACDESOFT+EACDE MD5為 57b1428ee2e49088
loc_4371A7: var_198 = Ucase(var_160) '轉化大寫 57B1428EE2E49088 這個是機器碼
loc_4371B0: MemVar_4450A0 = CStr(var_198)
loc_4371CF: var_164 = Proc_11_3_42DD78(MemVar_4450A0, MemVar_4450A4) ’ AES(機器碼,eacdesofttbk) 取32位 AES算法,MemVar_4450A4是key
|
0018F894 00548A9C UNICODE "eacdesofttbk" 密鑰
0018F894 00616AEC UNICODE "F008D7A07648EAB5F983F9151D843391" 這個是加密結果
MD5可以在線驗證,
手工驗證一下這個aes,有個網站
http://www.seacha.com/tools/aes.html
結果跟OD調試的結果F008D7A07648EAB5F983F9151D843391是一樣的
[Asm] 純文本查看 復制代碼
loc_4371E0: Proc_12_14_43CBD8(var_140, CVar(var_164), 32) //MD5 32位 MD532(ToUpper(AES(機器碼,eacdesofttbk)))
0018F67C 02D502BC UNICODE "0A516B737C3FBF185C1B1DA99F1D9CED"
MD5("F008D7A07648EAB5F983F9151D843391",32)=0a516b737c3fbf185c1b1da99f1d9ced
loc_4371E5: var_160 = 16
loc_4371F0: Proc_12_14_43CBD8(var_198, var_140, var_160) //MD5 16位 MD516(MD532(ToUpper(AES(機器碼,eacdesofttbk))))
MD5("0a516b737c3fbf185c1b1da99f1d9ced",16)=2a59468b454a2d05
loc_437226: var_120 = 32
loc_437238: Proc_12_14_43CBD8(var_140, CVar(CStr(Ucase(CStr(var_198))) & MemVar_4450A4), var_120)//再MD5 MD532(ToUpper(MD516(MD532(ToUpper(AES(機器碼,eacdesofttbk)))))+eacdesofttbk)
|
算法就逆出來了,
有點亂,先整理一下主要步驟,MD5有兩種,一種是16字節的,一種是32字節的,
步驟1 AES eacdesofttbk ToUpper
步驟2 MD532
步驟3 MD516 ToUpper
步驟4 MD532 eacdesofttbk
步驟5 MD516
0018F67C 02D502BC UNICODE "44CFDDA7226A8AF5227D0931817D399B"
0018F88C 00328A9C UNICODE "eacdesofttbk" MemVar_4450A4
MD5("2A59468B454A2D05"+eacdesofttbk,32)=44cfdda7226a8af5227d0931817d399b
[Asm] 純文本查看 復制代碼
loc_43724F: MemVar_4450B0 = 0
loc_437262: Proc_12_14_43CBD8(var_120, CStr(var_140), 16) 'MD516(MD532(ToUpper(MD516(MD532(ToUpper(AES(機器碼,eacdesofttbk)))))+eacdesofttbk))MD5("44cfdda7226a8af5227d0931817d399b",16)=baf849ceaffd1606 這個是序列號=MD516(MD532(MD5()+eacdesofttbk))
loc_437267: var_140 = 16
loc_437272: Proc_12_14_43CBD8(var_160, var_120, var_140) 'MD5(baf849ceaffd1606,16)=be555d3d4e16025c
loc_437287: Proc_12_14_43CBD8(var_208, MemVar_4450AC, 16)
0032FCA4 22222222222222222222 MemVar_4450AC
MD5(22222222222222222222 ,16)=8bbb9d0bcc5c0d0f
loc_437297: Proc_12_14_43CBD8(var_1C8, var_160, 32)
MD5(be555d3d4e16025c,32)=323279f73adb2c39cb6916e611d0c356
loc_4372AA: Proc_12_14_43CBD8(var_234, var_208, 32, var_1C8)
MD5(8bbb9d0bcc5c0d0f,32)= f12b3549ffe313a1f6aa0a14eb0791bf
loc_4372CB: If (MemVar_4450B0 = var_234) Then
loc_4372D0: MemVar_4450B0 = &HFF
loc_4372D6: MemVar_4450F4 = MemVar_4450EC
loc_4372DC: Else
loc_4372DE: MemVar_4450B0 = 0
loc_4372E4: MemVar_4450F4 = MemVar_4450E8
loc_4372E7: End If
loc_4372F3: Me.tm.Enabled = True
loc_4372FB: Exit Sub
loc_4372FC: ' Referenced from: 436514
loc_437304: Set var_88 = Err()
loc_43730A: Call {A4C466B8-499F-101B-BB7800AA00383CBB}.Method_arg_2C (var_164, MemVar_4450F4, MemVar_4450B0, MemVar_4450F4)
loc_43732F: MsgBox(CVar("系統啟動失敗!" & var_164), &H10, "錯誤", var_140, var_160)
loc_437345: End
|
注冊算法就分析完了
下面是修改資源,修改文字和圖片等資源不難,可是BookSet.exe修改后運行程序閃退,有校驗
一處是CRC
frmStart.FormLoad里面
[Asm] 純文本查看 復制代碼
loc_47C817: If (MemVar_492020 = Proc_2_18_4658D0(Proc_2_17_462E40(MemVar_4920F6, MemVar_492020))) Then
loc_47C81C: MemVar_4920F6 = 0
loc_47C822: Else
loc_47C824: MemVar_4920F6 = &HFF
loc_47C827: End If
|
47C82A的1C改成1D就過了CRC校驗,這里是判斷退出程序的地方
改完運行彈窗提示: 系統啟動失敗!Incorrect size descriptor in BFD
從FormLoad里面依次下斷點縮小范圍,看運行到哪里開始彈窗的
47CB84 大了
47CB7F 小了
最后定位到
[Asm] 純文本查看 復制代碼
loc_47CB58: Call frmStart.global_4289336Set(New clsBlowfish)
loc_47CBAB: var_D4 = Split(frmStart.global_4289336Get().DecryptFileAsStr(MemVar_492020 & MemVar_4920F8, MemVar_49210C), "|", -1, 0)
|
跟進去,在
clsBlowfish.DecryptFileAsStr
[Asm] 純文本查看 復制代碼
Public Function DecryptFileAsStr(SourceFile, Key) '462350
'Data Table: 4169E4
Dim var_8A As Integer
loc_462288: Call Proc_30_17_45CA68(SourceFile)
loc_462291: If Not(var_92) Then
loc_4622B2: Set var_118 = Err()
loc_4622B8: Call {A4C466B8-499F-101B-BB7800AA00383CBB}.Method_DecryptFileAsStr4 (-2147221504, var_B4, "Error in Skipjack EncryptFile procedure (Source file does not exist).")
loc_4622CB: DecryptFileAsStr = var_F4
loc_4622D1: End If
loc_4622D9: var_8A = FreeFile(var_B4)
loc_4622E7: Open SourceFile For Binary As var_8A Len = &HFF
loc_462301: ReDim var_90(0 To (LOF(var_8A) - 1))
loc_462311: Get var_8A, , var_90
loc_462318: Close var_8A
loc_462320: Call DecryptByte(var_90, Key) '在這一行彈窗出錯
loc_462343: var_88 = CStr(StrConv(var_90, &H40, 0))
loc_462349: DecryptFileAsStr = var_8A
End Function
|
跟進去clsBlowfish.DecryptByte
就是46A0E7處的IF語句判斷的,1C改成1D即可.
至于為什么是這么改,我們可以切換到Disassembler界面,BranchF就是1C,改成1D就是BranchT,就類似于我們win32下把jnz改成了jz
修改這個要用OD,在OD里面找到46A0E7的1C
然后改成1D,點右鍵-->復制到可執行文件-->所有修改
最后是注冊機算法,C#寫的
class Crypt
{
public static String bin2str(byte[] b, int length = -1)
{
var builder = new StringBuilder();
int len = (length == -1) ?16:b.Length;
for (int i = 0; i < len; i++)
{
builder.Append(b.ToString("x2"));
}
return builder.ToString();
}
public static byte[] encryptStringToBytes_AES(string plainText, byte[] Key)//, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the stream used to encrypt to an in memory
// array of bytes.
MemoryStream msEncrypt = null;
// Declare the RijndaelManaged object
// used to encrypt the data.
RijndaelManaged aesAlg = null;
try
{
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.KeySize = 128;
aesAlg.Key = Key;
aesAlg.Mode = CipherMode.ECB;
aesAlg.Padding = PaddingMode.Zeros;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
msEncrypt = new MemoryStream();
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
aesAlg.Clear();
}
// Return the encrypted bytes from the memory stream.
return msEncrypt.ToArray();
}
public static string MD532(string str)
{
byte[] buf=MD5.Create().ComputeHash(Encoding.Default.GetBytes(str));
return bin2str(buf, 32);
}
public static string MD516(string str)
{
byte[] buf = MD5.Create().ComputeHash(Encoding.Default.GetBytes(str));
return bin2str(buf, 32).Substring(8, 16);
}
public static string encrypt(string str)
{
string tmpstr;
byte[] key = { 0x65, 0x61, 0x63, 0x64, 0x65, 0x73, 0x6f, 0x66, 0x74, 0x74, 0x62, 0x6b, 0, 0, 0, 0 };
tmpstr=bin2str( encryptStringToBytes_AES(str, key)).ToUpper();
tmpstr=MD532(tmpstr);
tmpstr=MD516(tmpstr).ToUpper();
tmpstr=MD532(tmpstr+"eacdesofttbk");
tmpstr=MD516(tmpstr);
return tmpstr;
}
}
附上源碼vs工程文件和主程序的exe
翻書v3.4.2注冊機源碼.rar (125.53 KB, 下載次數: 103)
|