這道題做出來的時候還是非常激動的,不枉費本菜雞從中午肝到半夜/(ㄒoㄒ)/~~
這道題的殼是出題方自己寫的,強度其實是非常不錯的,這裡我投機取巧了,直接dump記憶體後轉靜態分析,這殼子直接木大
後面的哥隆尺演算法卡了我好久,最後只能去找金牌爺了= =
下面是照搬的發在看雪的writeup:
肝了個一血出來哈哈哈
直接執行,然後x32dbg附加,注意開啟sharpod的anti anti attach,然後ollydumpex,點search image,選擇module、binary(virtual),dump下來,用ida開啟,定位到sub_2f12b0函式
int
sub_2f12b0()
while
(*v2 );}
sub_2f5d70
(v0,
0x3138b0
,strlen((
const
char*)
&unk_3138b0)+1
);// correct
v45 =
0x9091948a
; v46 =
0x9681b7c4
; v3 =
(unsigned __int8 *
)&v44;
v47 =
0xde88858d
; v4 =
0xadu
; v48 =
0xee;do
while
(*v3 )
;// input serial:\n
v36 =**
(_dword **)
(*(_dword *)(
*(_dword *
)&unk_314478 +
0x3c)+
*(_dword *
)&unk_314478 +
0x28);
printf
(&v44)
;memset
(v39,0,
400)
;memset
(dest,0,
200)
;memset
(flag,
255,
400)
;memset
(table,
255,
256)
; v5 =0;
dowhile
( v5 <=9)
; v6 =0;
dowhile
( v6 <=5)
; input =0;
length =0;
scanf
(0x310cdc
,&input,1)
;// %c
v8 = input;
if( input !=10)
flag[length++
]= v9;
scanf
(0x310cdc
,&input,1)
;// %c
v8 = input;
if( input ==
'\n'
)goto label_14;
}label_32:
printf
(0x310c6c);
printf
(0x310c70);
// \f換頁
return0;
}label_14:
v10 =0;
if( length >0)
goto label_32;
}label_20:
v16 =0;
half_len = length >>2;
v18 =0;
v33 =0;
if( half_len <=0)
goto label_57;
v19 =0;
v32 =0;
dowhile
( v20 )
;sub_2f6305
(v34)
; v21 =
0x65;do
while
( v21 )
; v22 =(*
(int
(__stdcall **)
(_dword)
)&unk_30b144)(0
);// getactivewindow(0)
if( v22 )
v24 = dest[v32]
;// v32是滿足條件v31的輸入的index
if( v31 == v24 )
else
if( v35 != v24 )
v16 = v33+++1
; v19 =
(unsigned __int16)v33;
v32 =
(unsigned __int16)v33;
}while((
unsigned __int16)v33 < half_len );if
( v18 <12)
if( v39[1]
- v39[0]
>*(
&v37 + v18)-*
(&v36 + v18)
)memset
(v43,0,
100)
; v25 =0;
if( v18 -
1<=0)
v26 = v36;
while(1
) v27 = v25 +1;
if( v25 +
1< v18 )
break
;label_48:if(
++v25 >= v18 -1)
goto label_49;
} v28 = v39[v25]
;while(1
)label_51:
printf
(0x310c6c);
printf
(0x310cc0);
// 有人說這題根本無解,你信嗎
return0;
}
遇到30***x的位址,從x32dbg裡檢視到底是啥內容
解密指令碼:
int gl;
intsub_2f62e4()
void
sub_2f6305
(int a1)
intmain()
; __int16 v16, v31, v35;
unsigned __int16 v34;
int v18, v19, v20, v21, v32;
int n =85;
v16 =0;
v19 =0;
v32 =0;
dowhile
(v20)
;sub_2f6305
(v34)
; v21 =
0x65;do
while
(v21)
;bool isin =
false
;for
(size_t i =
0; i <
12; i++)}
if(isin)
else
v16++
; v19++
; v32++;}
while
(n--);
return0;
}
list中的值要滿足的條件是:從[0,89]中選擇12個互不相同的數,使它們任意兩個數之差都不相同,這裡我問了4位acm金牌爺,2個多小時後有人把結果弄出來了
程式執行的思路就是,讀入至多360個字元,只能0-9、a-f,把每4個輸入組合成乙個類似0x1234這樣的short,如果與v31一樣,則把下標加入v39佇列,如果與v35一樣,則繼續,如果都不一樣,則結束程式。如果v39的元素小於12則結束程式。之後會判斷v39裡面的數(也就是滿足v31的輸入的下標)是否兩兩之差唯一,是的話就輸出correct。
生成v31和v35的演算法是可以本地寫**跑出來的,只要輸入的滿足「下標不在list裡的輸入等於v35,否則等於v31」的就是flag
補充金牌爺演算法:
#include
int c[
100]
;int a[
100]
;int
abs(
int x)
void
work
(int x,
int n,
int k)
intcheck
(int x,
int n)
return1;
}void
dfs(
int now,
int n)
printf
("\n");
}if(90
-now <
12-n)
return
;for
(int i=now;i<=
89;i++)}
}int
main()
注意,這段**能跑出多組解,但是其餘解不滿足程式的要求,會輸出「穿越蟲洞要講究順序」,因此上面那組解應該是唯一滿足題目限制的 2020KCTF秋季賽簽到題
比賽平台 例行檢查,64位程式,無殼 試執行一下,看看大概的情況 64位ida載入,根據執行時候看到的字串找到關鍵函式 這邊推薦用ida7.5,當時用ida7.0 的時候f5後是下圖的介面,沒搞懂byte1和byte2是個什麼意思,而且陣列需要手動命名 54 59行是對v19陣列進行了操作得到了2 ...
PAT(甲級)2023年秋季考試
題意 n 只熊貓排成一排喝奶。每只熊貓至少分配 200ml 的牛奶,如果乙個熊貓比它旁邊的熊貓重,那麼就需要比旁邊的熊貓至少多喝 100ml 的牛奶。如果體重相同,分配的牛奶要相同。問最少需要分配多少的牛奶,才能滿足要求 思路 從左往右掃一遍,每只熊貓都和左邊的比。然後從右往左掃一遍,每只熊貓都和右...
PAT(乙級)2023年秋季考試
模擬。include using namespace std int sum string s int main else 模擬。include using namespace std int func int n int res 0 while mul return res int main in...