IDA逆向工程:fgets关卡三重检查的突破方案问询
逆向工程关卡突破分析
关卡核心逻辑
关卡通过三层嵌套while循环要求输入依次通过三项检查,核心反编译代码如下:
while ( 1 ) { while ( 1 ) { while ( 1 ) { memset(Buffer, 0, sizeof(Buffer)); stream = _acrt_iob_func(0); fgets(Buffer, 1020, stream); if ( strlen(Buffer) >= 0x1E ) break; } if ( first_check_string(Buffer) ) break; } if ( second_check_string(Buffer) ) break; } return printf(aWellDone, Buffer[0]);
检查函数分析
第一项检查:first_check_string
该函数验证输入字符是否符合特定小写字母范围:
int __cdecl first_check_string(_BYTE *str_addr) { while ( *str_addr ) { if ( (char)*str_addr < 97 || (char)*str_addr > 122 ) return 0; if ( ((char)*str_addr - 97) % 3 ) return 0; ++str_addr; } return 1; }
第二项检查:second_check_string
该函数验证输入长度的整除性及4字节分组异或结果:
BOOL __cdecl second_check_string(char *Str) { int v2; // [esp+4h] [ebp-8h] char *i; // [esp+8h] [ebp-4h] if ( strlen(Str) % 4 ) return 0; v2 = 0; for ( i = Str; *(_DWORD *)i; i += 4 ) v2 ^= *(_DWORD *)i; return v2 == 1970760046; }
检查要求与矛盾点
三项检查的具体规则:
- 输入长度需≥0x1E(十进制30)
- 仅可使用ASCII码减97后能被3整除的小写字母(a、d、g、j、m、p、s、v、y),且输入至少1019个字符,否则
fgets会读取换行符0x0A导致检查失败 - 字符串长度需能被4整除,且按4字节分组异或的结果等于1970760046
矛盾点:1019无法被4整除,输入更少字符则会引入换行符,导致检查失败。
解决方案
通过文件重定向绕过输入限制,执行命令:
prog.exe < file
将程序标准输入替换为文件后,可在文件中写入任意字节(包括NUL 0x00),无需担心换行符问题。可通过编程语言生成符合要求的字节序列,或使用十六进制编辑器(如010 Editor)直接编辑文件内容。
内容的提问来源于stack exchange,提问作者nortain32
相关产品推荐
相关产品推荐

