新160個(gè)CrackMe分析-第6組:51-60(上)

作者:selph
??051-Keygenning4newbies1
??052-tc.22
??053-devilz KeyGen me#33
??054-vcrkme014
??055-BCG Crackme5
??056-diablo2oo2's Crackme 016
??057-bbbs-crackme047
??058-CZG-crackme18
??059-Dope2112.19
??060-snake10
1.??????051-Keygenning4newbies
???????????算法難度:??
???????????爆破難度:?
????????????信息收集
????????????運(yùn)行情況:

??????????
查殼與脫殼:
??無(wú)殼

調(diào)試分析
?C++窗口程序:
首先跟進(jìn)窗口函數(shù)
???

???????
然后是一段switch-case分支,或者是if-esle分支:根據(jù)消息碼進(jìn)入對(duì)應(yīng)的處理,按鈕的處理消息是WM_COMMAND,對(duì)應(yīng)的值就是0x111
?

?????????
然后wParam是控件的id號(hào),這里通過(guò)xspy發(fā)現(xiàn)驗(yàn)證按鈕的id號(hào)是0x69,跟進(jìn)這個(gè)0x69的跳轉(zhuǎn)

??????????
這里調(diào)用了一個(gè)call就跳出了:
????????

??
這個(gè)call?應(yīng)該就是驗(yàn)證處理,前面初始化局部變量和獲取控件值就不看了
這里兩個(gè)紅圈就是注冊(cè)碼生成邏輯,用Name計(jì)算一個(gè)值,然后變成十六進(jìn)制字符串形式

??????????
?注冊(cè)機(jī)
注冊(cè)碼生成算法:(CSharp)
?????string? Name = Console.ReadLine();
if(Name!=null && Name.Length is > 3 and < 32)
{
??? int ebx=0;
??? int eax=0;
??? for (int i = 0; i < Name.Length; )
??? {
??????? eax = (int)Name[i++];
??????? eax ^= i;
??????? ebx += eax;
??? }
??? eax *= 6;
??? ebx <<= 7;
??? eax += ebx;
??? Console.WriteLine(string.Format("{0:X}", eax));
}
效果:

??????????
2.??????052-tc.2
???????????算法難度:????
???????????爆破難度:???
信息收集
運(yùn)行情況:

??????????
查殼與脫殼:
??????????

調(diào)試分析
老版本delphi看著就煩
構(gòu)造正確的keyfile
首先是打開(kāi)文件,讀取其中的內(nèi)容,對(duì)比內(nèi)容是否為這個(gè)固定值
??

????????
然后判斷內(nèi)容的長(zhǎng)度,內(nèi)容的長(zhǎng)度為固定值0x17字節(jié)

??????????
條件滿(mǎn)足了就會(huì)啟用編輯框和注冊(cè)按鈕:

??????????
校驗(yàn)算法分析
這個(gè)call里有一堆代碼不知道在干嘛,可能是編譯器自動(dòng)生成的吧,這里就挑有用的看
首先是這里,這里是個(gè)循環(huán),這個(gè)ReadChar函數(shù)盲猜是讀取Name的一個(gè)字節(jié),然后保存到局部變量ebp-0D里
然后取出讀取的這一個(gè)字節(jié),和初值是0的bl進(jìn)行一系列計(jì)算,得到一個(gè)值,將這個(gè)值累加到si里,對(duì)于每個(gè)字符都這么操作
最后判斷si的值是否大于一個(gè)固定值,否則就加上一個(gè)固定值

??????????
再往后就是生成真碼和比較的過(guò)程了:
首先將計(jì)算出來(lái)的累加值si轉(zhuǎn)字符串,然后往第3和第5個(gè)字符處插入-符號(hào),然后就是比對(duì)和輸入是否相同,不同就跳轉(zhuǎn),相同就提示成功

??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:(CSharp)
?????string? name = Console.ReadLine();
byte bl = 0;
var si = 0;
for(byte i = 1; i <= name.Length; i++)
{
??? byte tmp = (byte)name[i-1];
??? bl -= tmp;
??? bl += i;
??? si += bl;
}
while (si < 0x438D) si += 0x45e6;
var serial = string.Format("{0:D}", si);
serial = serial.Insert(2, "-");
serial = serial.Insert(4, "-");
Console.WriteLine(serial);
效果:

? ? ? ? ??
總結(jié)
分析無(wú)意義的代碼真是浪費(fèi)時(shí)間!應(yīng)該從判斷條件開(kāi)始自下往上去分析!
3.??????053-devilz KeyGen me#3
???????????算法難度:??
???????????爆破難度:?
?信息收集
運(yùn)行情況:

??????????
查殼與脫殼:
有殼!Petite殼,第一次見(jiàn),試著脫一下

??????????
首先跑到當(dāng)前的OEP:
很明顯這里有一個(gè)注冊(cè)SEH異常處理程序的,然后就是保存當(dāng)前寄存器環(huán)境,等殼解壓解密完再恢復(fù)用
這里等pushf指令執(zhí)行之后,對(duì)esp的地址下硬件訪問(wèn)斷點(diǎn)

??????????
因?yàn)檫@里用到了異常,所以這里在x86dbg設(shè)置里把異常處理設(shè)置成由debugee處理
然后跑起來(lái),遇到異常了直接接著跑,跑到硬件斷點(diǎn)處:
很顯然,這可能應(yīng)該就是真正的OEP了
??????????
跟進(jìn)查看:
這就是一個(gè)注冊(cè)窗口的函數(shù)和退出進(jìn)程的函數(shù),確定了,這就是真正的OEP,接下來(lái)用插件脫殼即可
??????????
調(diào)試分析
ida打開(kāi)繼續(xù)分析:

??????????
跟進(jìn)DialogFunc,找到nMsg = 111,且arg_8 = 0x12c的分支(Unlock按鈕ID)繼續(xù)跟進(jìn):
顯示判斷輸入是否為空,有些函數(shù)沒(méi)識(shí)別全,應(yīng)該是導(dǎo)入表沒(méi)修復(fù)好
??????????
接下來(lái)是對(duì)Name的處理:
反轉(zhuǎn)字符串,然后對(duì)每個(gè)字符進(jìn)行異或0x30
??????????
然后是對(duì)UnlockCode的處理:
遍歷每個(gè)字符,對(duì)每個(gè)字符異或0x20,最后和各個(gè)處理過(guò)的Name進(jìn)行比對(duì),相同即可
??????????
?注冊(cè)機(jī)
注冊(cè)碼生成算法:(CSharp)
?????string? name = Console.ReadLine();
char[] UnlockCode = name.ToCharArray();
Array.Reverse(UnlockCode);
for (int i = 0; i < UnlockCode.Length; i++)
{
??? UnlockCode[i] = (char)(UnlockCode[i] ^ 0x30);
??? UnlockCode[i] = (char)(UnlockCode[i] ^ 0x20);
}
Console.WriteLine(UnlockCode);
???????????效果:
??????????
4.??????054-vcrkme01
???????????算法難度:??
???????????爆破難度:?
信息收集
運(yùn)行情況:
??????????
查殼與脫殼:
無(wú)殼:
??????????
調(diào)試分析
直接拖IDA:
一開(kāi)始就看到創(chuàng)建窗口的函數(shù)
??????????
?接下來(lái)直接跟進(jìn)DialogFunc找nMsg=0x111,arg_8=3eb的分支:
獲取用戶(hù)輸入的兩個(gè)值,調(diào)用了一個(gè)call,然后根據(jù)返回結(jié)果是否為1進(jìn)行彈框
?
?????????
跟進(jìn)這個(gè)call看看:
由于庫(kù)函數(shù)的內(nèi)聯(lián)匯編看得頭疼,直接F5看吧:
??????????
注冊(cè)機(jī)
注冊(cè)碼生成算法:(CSharp)
?????string? name = Console.ReadLine();
int sum = 0;
for (int i = 0; i < name.Length; i++) sum += name[i];
sum += 0x6064;
string? Buffer = string.Format("{0:D}", sum);
char[] code = new char[1024];
code[0] = name[0];
code[1] = '-';
code[2] = char.ToUpper(name[name.Length - 1]);
var code_s = new string(code);
code_s += Buffer;
code_s += '-';
code_s += string.Format("{0:D}", sum += 0x6064);
Console.WriteLine(code_s);
效果:
??????????
5.??????055-BCG Crackme
???????????算法難度:??
???????????爆破難度:?
信息收集
運(yùn)行情況:
意思是不能爆破,不能修改內(nèi)存,并完成破解,意思就是通過(guò)給出正確的key文件唄
??????????
查殼與脫殼:
ASPack殼,ESP定律即可

??????????
調(diào)試分析
不管是窗口啟動(dòng)還是點(diǎn)擊注冊(cè)按鈕,都會(huì)跳轉(zhuǎn)到同一段代碼上
這里是個(gè)文件驗(yàn)證:打開(kāi)文件[BCG].Key,然后讀取前10個(gè)字節(jié),和緊接著10個(gè)字節(jié)

??????????
讀取成功后,往下走:
這里是處理前10個(gè)字節(jié),每個(gè)字節(jié)異或一下0x58,直到遇到0為止
這意味著,我們構(gòu)造的文件里需要出現(xiàn)00截?cái)?/p>

??????????
???????????Key文件

??????????
???????????效果:
