You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 10:35:24