準備
工具:IDA、x32dbg、010Editor
環境:Windows10
開始
附件是exe可執行檔案,在cmd里執行后,發現是一個游戲

玩了一會后,發現規律大概是它出現什么字母,你就要根據下面的規則按下相應的鍵
's'-->' ' 'x'-->'x' 'm'-->'m'
一開始可能還可以,后來速度快就沒法玩,所以動態除錯
IDA靜態分析
先拖進IDA中,分析main函式
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // edi
unsigned int v4; // eax
int v5; // ecx
int v6; // ecx
int v7; // ecx
void (__stdcall *v8)(DWORD); // ebx
int v9; // esi
int v10; // esi
int v11; // esi
int v12; // esi
int v13; // esi
int i; // edi
int v15; // esi
unsigned __int8 *v16; // esi
int v17; // ebx
int v18; // esi
int v19; // esi
char v20; // cl
int v22; // [esp+10h] [ebp-20h]
int v23; // [esp+14h] [ebp-1Ch] BYREF
char v24; // [esp+1Bh] [ebp-15h]
_WORD v25[3]; // [esp+1Ch] [ebp-14h] BYREF
int v26; // [esp+22h] [ebp-Eh]
int v27; // [esp+26h] [ebp-Ah]
__int16 v28; // [esp+2Ah] [ebp-6h]
strcpy((char *)v25, " ");
v23 = 7630702;
*(_DWORD *)&v25[1] = 0;
v26 = 0;
v27 = 0;
v28 = 0;
v3 = 0;
v22 = 0;
sub_401A73((int)"\r\tZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG\n");
sub_401A73((int)"\tkey is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\r\tZOMGZOMG ZOMGZOMG\n");
sub_401A73((int)"\tkey is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\r\tZOMGZOMG TAP TAP REVOLUTION!!!!!!! ZOMGZOMG\n");
sub_401A73((int)"\tkey is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\r\tZOMGZOMG ZOMGZOMG\n");
sub_401A73((int)"\tkey is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\r\tZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG\n\n\n");
sub_401A73((int)"\tkey is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\r\t R U READDY?!\n\n\n");
sub_401A73((int)"\tkey is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\rThe game is starting in...\n");
v4 = _time64(0);
srand(v4);
sub_4012B2();
sub_4012D5(0xC8u);
if ( !(unsigned __int8)sub_401435(10, v5, v25, &v23) )
return 0;
if ( !(unsigned __int8)sub_401435(8, v6, v25, &v23) )
return 0;
if ( !(unsigned __int8)sub_401435(5, v7, v25, &v23) )
return 0;
sub_401A73((int)"key is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401A73((int)"\rTRAINING COMPLETE! \n");
v8 = Sleep;
v9 = 20;
do
{
Sleep(0xC8u);
sub_401A73((int)"\n");
--v9;
}
while ( v9 );
sub_401A73((int)"key is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401A73((int)"\rNow you know everything you need to know");
v10 = 4;
do
{
sub_401A73((int)".");
Sleep(0x3E8u);
--v10;
}
while ( v10 );
sub_401A73((int)"\n\n\nfor the rest of your life!\n");
v11 = 20;
do
{
Sleep(0xC8u);
sub_401A73((int)"\n");
--v11;
}
while ( v11 );
sub_401A73((int)"LETS PLAY !\n");
v12 = 20;
do
{
Sleep(0xC8u);
sub_401A73((int)"\n");
--v12;
}
while ( v12 );
sub_4012B2();
sub_4012D5(0x64u);
if ( !(unsigned __int8)sub_401507(0xC8u, (int)v25, (int)&v23) )
return 0;
if ( !(unsigned __int8)sub_401507(0xC8u, (int)v25, (int)v25) )
return 0;
if ( !(unsigned __int8)sub_401507(0xC8u, (int)v25, (int)v25) )
return 0;
sub_401A73((int)"key is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\rooooh, you fancy!!!\n");
if ( !(unsigned __int8)sub_401507(0xC8u, (int)v25, (int)&v23)
|| !(unsigned __int8)sub_401507(0xC8u, (int)v25, (int)&v23)
|| !(unsigned __int8)sub_401507(0xC8u, (int)v25, (int)&v23) )
{
return 0;
}
sub_401A73((int)"key is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401A73((int)"\b\b");
sub_401A73((int)"NIIICE JOB)!!!!\n");
v13 = 20;
do
{
Sleep(0x32u);
sub_401A73((int)"\n");
--v13;
}
while ( v13 );
v24 = 1;
do
{
if ( v3 % 3 == 1 )
{
sub_401A73((int)"key is %s (%s)", (const char *)&v23, (const char *)v25);
sub_401423();
sub_401A73((int)"\rTURBO TIME! \n");
for ( i = 0; i < 20; ++i )
{
v8(0x32u);
sub_401A73((int)"\n");
if ( i == 19 )
{
v15 = sub_40141D();
sub_401D02(v25, v15 - 5514);
dword_41A1F8 = (int)v25;
dword_41A1FC = v15 - 5498;
sub_401AA5();
sub_401CC9();
sub_401A73((int)"key is %s (%s)", byte_417D02, (const char *)&v23);
sub_401A73((int)"\b\b");
v16 = (unsigned __int8 *)v25;
v17 = 16;
do
{
sub_401A73((int)"%02x", *v16++);
--v17;
}
while ( v17 );
sub_401A73((int)")\n\n");
v8 = Sleep;
}
}
v18 = 0;
while ( 1 )
{
rand();
if ( !(unsigned __int8)sub_401507(0x64u, (int)v25, (int)&v23) )
break;
if ( ++v18 >= 10 )
goto LABEL_33;
}
v24 = 0;
LABEL_33:
v3 = v22;
}
v19 = 0;
while ( 1 )
{
rand();
v20 = v24;
if ( v24 )
break;
LABEL_38:
if ( ++v19 >= 10 )
goto LABEL_41;
}
if ( (unsigned __int8)sub_401507(0x64u, (int)v25, (int)&v23) )
{
v20 = v24;
goto LABEL_38;
}
v20 = 0;
v24 = 0;
LABEL_41:
if ( v3 == 1337 )
{
sub_4012F6();
v20 = v24;
}
v22 = ++v3;
}
while ( v20 );
return 0;
}
代碼很長,分析關鍵部分
第60行到第66行是教你怎么玩,函式是sub_401435()
char __usercall sub_401435@<al>(DWORD a1@<edx>, int a2@<ecx>, int a3, int a4, const char *a5, const char *a6)
{
int v8; // edi
sub_401A73((int)"key is %s (%s)", a6, a5);
sub_401423();
sub_401A73((int)"\rZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG\n");
if ( a2 == 32 )
sub_401A73((int)"\nWhen you see an 's', press the space bar\n\n");
else
sub_401A73((int)"\nWhen you see an '%c', press the '%c' key\n\n", a2, a2);
sub_401A73((int)"key is %s (%s)", a6, a5);
sub_401423();
sub_401A73((int)"\rZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG\n");
sub_4012D5(a1);
v8 = a3;
if ( a3 > 0 )
{
do
{
sub_401A73((int)".");
Sleep(0xC8u);
--v8;
}
while ( v8 );
}
if ( sub_401260(a2, 100000) ) //關鍵
return 1;
sub_401A73((int)"key is %s (%s)\r", a6, a5);
sub_401423();
sub_401A73((int)"\rUDDER FAILURE! http://imgur.com/4Ajx21P \n");
return 0;
}
從第98行開始就是自己玩,函式是sub_401507()
char __usercall sub_401507@<al>(int a1@<edx>, int a2@<ecx>, DWORD dwMilliseconds, int a4, int a5)
{
sub_401A73((int)"key is %s (%s)", (const char *)a5, (const char *)a4);
sub_401423();
sub_401A73((int)"\r \r");
if ( a1 > 0 )
{
do
{
sub_401A73((int)".");
Sleep(dwMilliseconds);
--a1;
}
while ( a1 );
}
if ( sub_401260(a2, 500 * dwMilliseconds) ) //關鍵
return 1;
sub_401A73((int)"key is %s (%s)\r", (const char *)a5, (const char *)a4);
sub_401A73((int)"UDDER FAILURE! http://imgur.com/4Ajx21P \n");
return 0;
}
可以看出游戲里面的關鍵函式都是sub401260(),只要它回傳值為1,游戲就會進行下去,否則就會輸出
sub_401A73((int)"UDDER FAILURE! http://imgur.com/4Ajx21P \n");
分別查看sub_401435()、sub_401507()兩個函式中呼叫sub401260()的位置
· sub_401435()

在004014D1處呼叫,在004014DB時判斷回傳結果
· sub_401507()

在00401559處呼叫,在00401563時判斷回傳結果
所以破解方案就是,在這兩處判斷的地方打上斷點,修改ZF標志位,使它原來的跳轉指令朝著相反的方向執行,(即不執行)
動態除錯
動態除錯之前,要使用010Editor關掉aslr,具體方法參照博客
[(30條訊息) 攻防世界 Windows_Reverse1_P_Bloomberg的博客-CSDN博客]的動態除錯部分,
修改之后
將檔案放入x32dbg中先按下F9開始,指令地址就會變得和IDA中相同
再在004014DB和00401563兩處打上斷點,


然后一直F9執行,執行到斷點處時,修改sub401260()的回傳結果

即修改EFLAGS中的ZF標志位,改成與原來相反的數即可

執行一段時間后,大概是在main函式的153行處,就會輸出完整的flag
運行程序:
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
ZOMGZOMG ZOMGZOMG
ZOMGZOMG TAP TAP REVOLUTION!!!!!!! ZOMGZOMG
ZOMGZOMG ZOMGZOMG
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
R U READDY?!
The game is starting in...
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
When you see an 's', press the space bar
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
..........s
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
When you see an 'x', press the 'x' key
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
........x
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
When you see an 'm', press the 'm' key
ZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMGZOMGZOMGOZMG
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
.....m
TRAINING COMPLETE!
Now you know everything you need to know....
for the rest of your life!
LETS PLAY !
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
Get ready to play
.....s
..x
.m
ooooh, you fancy!!!
.....m
..x
.s
key is not (NIIICE JOB)!!!!
....x
....x
.....m
.....m
....x
...s
...s
....x
.....m
....x
TURBO TIME!
key is (no5c30416d6cf52638460377995c6a8cf5)
flag:no5c30416d6cf52638460377995c6a8cf5
key is (no5c30416d6cf52638460377995c6a8cf5)
flag:`no5c30416d6cf52638460377995c6a8cf5`
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293104.html
標籤:其他
上一篇:【技術詳解】阿里云AIoT物模型支撐設備規模已超億級
下一篇:WEB安全_基礎入門_資料包拓展,安裝Burp Suite,練習來源頁偽造、瀏覽器資訊偽造、HTTP動作練習、投票系統程式設計缺陷分析
