EN | ZH

## 例题¶

.rodata:0000000000400A53 00000006 C KEY:
.rodata:0000000000400A5F 0000001F C OK YOU WIN. HERE'S YOUR FLAG:


int __cdecl main(int argc, const char **argv, const char **envp)
{
qmemcpy(v23, &unk_400A7E, sizeof(v23));
v3 = v22;
for ( i = 9LL; i; --i )
{
*(_DWORD *)v3 = 0;
v3 += 4;
}
v20 = 0x31337;
v21 = time(0LL);
do
{
v11 = 0LL;
do
{
v5 = 0LL;
v6 = time(0LL);
srand(233811181 - v21 + v6); // 初始化随机数种子
v7 = v22[v11];
v22[v11] = rand() ^ v7;   // 伪随机数
v8 = (&funny)[8 * v11];
while ( v5 < strlen(v8) )
{
v9 = v8[v5];
if ( (_BYTE)v9 == 105 )
{
v24[(signed int)v5] = 105;
}
else
{
if ( (_DWORD)v5 && v8[v5 - 1] != 32 )
v10 = __ctype_toupper_loc();    // 大写
else
v10 = __ctype_tolower_loc();    // 小写
v24[(signed int)v5] = (*v10)[v9];
}
++v5;
}
v24[(signed int)v5] = 0;
++v11;
__printf_chk(1LL, " 鈾%80s 鈾玕n", v24); // 乱码的其实是一个音符
sleep(1u);
}
while ( v11 != 36 );
--v20;
}
while ( v20 );
v13 = v22;    // key存储在v22数组内
__printf_chk(1LL, "KEY: ", v12);
do
{
v14 = (unsigned __int8)*v13++;
__printf_chk(1LL, "%02x ", v14); // 输出key
}
while ( v13 != v23 );
v15 = 0LL;
putchar(10);
__printf_chk(1LL, "OK YOU WIN. HERE'S YOUR FLAG: ", v16);
do
{
v17 = v23[v15] ^ v22[v15];  // 跟key的值有异或
++v15;
putchar(v17);   // 输出flag
}
while ( v15 != 36 );
putchar(10);      // 输出换行
result = 0;
return result;
}


.text:00000000004007B7                 call    ___printf_chk
.text:00000000004007BC                 xor     eax, eax


4007B74007BD之间的汇编代码全部修改为nop即可. 然后选择菜单Edit->Patch Program->Apply patches to input file. 当然最好做一个备份(即勾选Create a backup), 然后点击OK即可(我重命名为了patched.elf, 下载链接: patched.elf).

static int t = 0x31337;

void sleep(int sec) {
t += sec;
}

int time() {
return t;
}