有這麼一道題,它檢驗輸入,並把輸入裡的空白刪掉後取 md5 作為 flag。它的輸入非常神奇,用 scanf 讀入一堆整數。放進陣列裡後要經過兩個函數的檢驗。
(下面請 ghidra 發言)
int check1(int *nums)
{
int j;
int s;
int i;
int res;
res = 0;
i = 0;
while( true ) {
if (0x400 < i) {
return res;
}
if (nums[i] == 0) break;
s = 0;
for (j = 0; j <= res; j = j + 1) {
s = s + nums[i + j];
}
if (1 << ((byte)res & 0x1f) != s) {
return -1;
}
i = ((res + 2) * (res + 1)) / 2;
res = res + 1;
}
return res;
}
//param_20傳入的是check1的返回值(楊輝三角形層數,main裡檢測了它是否等於20)
int check2(int *nums,int param_20)
{
int j;
int s;
int i;
int i0;
i0 = 0;
i = 1;
while( true ) {
if (para_20 <= i) {
return 1;
}
s = 0;
j = i + -1;
if (nums[i] == 0) break;
for (; j < para_20 + -1; j = j + 1) {
s = s + nums[i0 + ((j + 1) * j) / 2];
}
if (nums[i + ((j + 1) * j) / 2] != s) {
return 0;
}
i0 = i0 + 1;
i = i + 1;
}
return 0;
}
看 writeup 後:
check1 中,res 是層數,i = (res + 2) * (res + 1) / 2,是每層開始的下標。check1 是在檢驗第 res 層的和是不是 i 的 res 次方。(成功被 res&0x1f 搞蒙了。。效果是取 res 末五位,可能是防越界?好像不是。組合語言裡是 SHL EBX,CL ,EBX 裡是 1,太怪了)
check2 檢測的是 “斜線上數字的和等於其向左(從左上方到右下方的斜線)或向右拐彎(從右上方到左下方的斜線),拐角上的數字。” 意會一下。
所以最後提交的是 RCTF {20 層去皮楊輝三角形的 md5}