nccstf_string

nccstf_string 老样子下载查壳64位IDA打开f5查看伪代码伪码分析一、整体流程这个 main 函数只是一层输入输出外壳本身不包含任何加密校验逻辑。所有核心的 flag 验证算法都封装在 flag() 函数里。完整执行流程初始化栈保护机制打印提示语读取用户输入的字符串将输入传入 flag() 函数执行校验程序返回点击flag函数函数代码分析DWORD 全称 Double Word双字是 Windows C 开发体系里的经典数据类型IDA 反编译时沿用了这个命名前面加下划线写作 _DWORD。大小4 字节32 位对应 C 标准里的 unsigned int是无符号 32 位整数。命名由来1 个 Word字是 2 字节16 位双字就是两个 Word共 4 字节。这是一道入门逆向题的核心函数整体逻辑分为长度校验和flag 生成输出两部分。输入字符串的内容不参与校验只有长度会决定是否能触发 flag 输出。逐段逻辑拆解前半段大段代码快速计算字符串长度你看到的大量位运算、循环跳转本质是编译器内联优化的 strlen字符串长度计算实现是标准的快速长度计算算法先检查指针对齐状态未对齐时先逐个字节遍历到对齐位置对齐后按 4 字节32 位批量检测通过经典位运算公式 ((i - 0x01010101) ~i 0x80808080) 快速判断 4 个字节中是否包含结束符 \0大幅提升长字符串的计算效率最后处理剩余不足 4 字节的部分逐个字节定位结束符位置。最终 v6 会指向字符串末尾的 \0v6 - 起始地址 就是输入字符串的总长度。注伪代码里大量 (_DWORD)指针、1 偏移是 IDA 反编译的类型推断瑕疵把指针运算错误转成了整数运算不影响核心逻辑判断。核心代码puts(“The length of flag is 13”);//输出语句The length of flag is 13srand(seed);printf(“NSSCTF{”);for ( m 0; m 13; m ){v4 rand();printf(“%d”, (unsigned int)(v4 % 8 1));}putchar(125);说明flag长度是13生成一个随机数C语言的随机数是伪随机同一个种子生成的随机数是一样的所以种子相当于密钥先获取到种子双击seed说明种子是0x2766,写解题脚本#includestdio.h#includestdlib.h#includestring.hintmain(){srand(0x2766);intm;printf(NSSCTF{);for(m0;m13;m){intv4rand();printf(%d,(unsignedint)(v4%81));}putchar(125);return0;}得到flag