算法分析一道逆向CTF題
1.下載查殼,跑一遍


提示輸入,隨便輸入后結(jié)束程序
2.使用IDA靜態(tài)分析,拖進(jìn)去直接F5偽代碼分析

?v7 = strcmp(byte_40336C, aXircjR2twsv3pt);
??? if ( v7 )
????? v7 = v7 < 0 ? -1 : 1;
??? if ( !v7 )
??? {
????? sub_401020("right\n", Arglist[0]);
????? system("pause");
}
從偽代碼中可以看到關(guān)鍵字符"right\n",那這里可以直接看出這個sub_401020指定就是輸入正確后的提示函數(shù),但是要執(zhí)行sub_401020函數(shù)則需要v7是一個非零的數(shù),那么我們就跟蹤v7,可以從整個main函數(shù)中看到,對v7變量做出更改的只有一下兩個地方
v7 = strcmp(byte_40336C, aXircjR2twsv3pt);
if ( v7 )
????? v7 = v7 < 0 ? -1 : 1;
第一個地方v7是byte_40336C變量與aXircjR2twsv3pt變量strcmp的返回值,第二個地方v7無論怎么樣都是非零數(shù),所以第二個地方的v7就不影響提示輸入正確的函數(shù)sub_401020("right\n", Arglist[0]),那只有第一個地方的了,化簡后的對比代碼如下
?v7 = strcmp(byte_40336C, aXircjR2twsv3pt);
?if ( !v7 )
??? {
????? sub_401020("right\n", Arglist[0]);
????? system("pause");
??? }
也就是說,只要byte_40336C與aXircjR2twsv3pt相等就行了,相等v7就等于0,!v7就為真,那就執(zhí)行提示輸入正確的函數(shù),到這里根據(jù)以往的經(jīng)驗就可以有90%的信心確定這個byte_40336C就是最后一次flag的密文,我們只需推到出這個byte_40336C就應(yīng)該可以解決題目了
那好,接下來找出aXircjR2twsv3pt的具體值,雙擊aXircjR2twsv3pt進(jìn)入查看具體值

shift+e把a(bǔ)XircjR2twsv3pt提取出來先放好,繼續(xù)查看aXircjR2twsv3pt與byte_40336C存在的邏輯
for ( i = 0; i < 0x18; ++i )
????? byte_40336C[i] = (byte_40336C[i] + 1) ^ 6;
我們剛才得到最后的byte_40336C正確的滿足條件就是等于aXircjR2twsv3pt,那在上面的代碼中就只存在一個未知數(shù):每次循環(huán)前的byte_40336C,那我們先用剛才提取出的aXircjR2twsv3pt寫腳本推導(dǎo)出每次循環(huán)前的byte_40336C,代碼如下:
#include
#include
int main()
{
??? unsigned char aXircjR2twsv3pt[] =
??? {
??????? 0x78, 0x49, 0x72, 0x43, 0x6A, 0x7E, 0x3C, 0x72, 0x7C, 0x32,
??????? 0x74, 0x57, 0x73, 0x76, 0x33, 0x50, 0x74, 0x49, 0x7F, 0x7A,
??????? 0x6E, 0x64, 0x6B, 0x61, 0x00, 0x00, 0x00, 0x00
??? };
??? char get[24];
??? for (size_t i = 0; i < 0x18; i++)
??? {
??????? get[i] = (aXircjR2twsv3pt[i] ^ 6) - 1;
??? }
??? for (size_t i =0; i < 0x17; i++)
??? {
??????? printf("%c", get[i]);
??? }
??? system("pause");
}

到這里以后,我們繼續(xù)閱讀main函數(shù)代碼邏輯,發(fā)現(xiàn)在這個for循環(huán)之前只有一個地方操作了這個byte_40336C變量,但是即使再怎么操作byte_40336C變量的最后操作都是for循環(huán)結(jié)構(gòu)內(nèi),所以再for以前的代碼毫無意義了,那此時我們得到最后的條件就是上面輸出的“}NsDkw9sy3qPto4UqNx{galf”字符了,所以只能通過這個字符串來查找關(guān)鍵信息最快,咱們不如把“}NsDkw9sy3qPto4UqNx{galf”倒序看一下,是不是有flag{...}這味?那我們把for循環(huán)輸出從最后一位開始倒序

腳本如下:
#include
#include
int main()
{
???? char aXircjR2twsv3pt[] =
??? {
??????? 0x78, 0x49, 0x72, 0x43, 0x6A, 0x7E, 0x3C, 0x72, 0x7C, 0x32,
??????? 0x74, 0x57, 0x73, 0x76, 0x33, 0x50, 0x74, 0x49, 0x7F, 0x7A,
??????? 0x6E, 0x64, 0x6B, 0x61, 0x00, 0x00, 0x00, 0x00
??? };
??? char get[24];
? ??for (size_t i = 0; i < 0x18; i++)
??? {
??????? get[i] = (aXircjR2twsv3pt[i] ^ 6) - 1;
??? }
??? for (size_t i = 0x17; i >=0; i--)
??? {
??????? printf("%c", get[i]);
??? }
??? system("pause");
}
