FlareOn入门逆向复盘:反调试与输入校验实战

发布时间:2026/10/19 13:48:04
FlareOn入门逆向复盘:反调试与输入校验实战 CTF圈子里的逆向题老玩家基本绕不开FlareOn这道菜。由安全厂商组织的年度逆向挑战赛题目路子野、脑洞大但又有实战题的实在感尤其适合磨炼基本功。今天想复盘的是里面两个入门关卡[FlareOn2]very_success和[FlareOn3]Challenge1。这两题难度都不算高但特别典型一个用来练反调试和字符串定位一个用来练最朴素的输入校验逻辑分析。把这两题啃下来后面再碰加壳、混淆、虚拟化保护心态会稳很多。先说结论如果你刚接触逆向又刷过一些CTF题但看到Windows GUI程序还是不知道怎么下手那这两题是很好的“破冰”素材。very_success是一个带对话框的MFC程序考验你能否在一个典型的Windows图形程序里快速定位关键校验逻辑Challenge1则是一个控制台交互程序输入key判断对错考验最基础的代码分析和静态提取能力。两者都不需要你懂高深的算法也不需要破解什么复杂保护但做完之后你对“逆向一个程序到底从哪开始”这件事会有非常具体的体感。1. 两道赛题的整体思路拆解1.1 题目定位为什么说它们适合做入门训练FlareOn赛事的题目往往沿着“真实场景”展开不会像传统CTF那样塞一大堆刻意到不自然的脑洞。但它的入门题依然保持了一个很好的梯度不以难倒你为目标而是逼你学会用工具、看汇编、找逻辑。very_success在FlareOn2里的位置比较靠后但难度放在今天的标准来看就是入门偏中等。它的障碍点主要在于程序带有一个反调试检测如果你直接用调试器加载程序会发现并给出一个误导性信息。这时候你不能停在“程序坏了”的误解里而要从汇编层面理解反调试的逻辑再决定是绕过还是patch。Challenge1则是FlareOn3的第一题非常直接。程序运行后在控制台里要你输入一个key输入正确的值才会出现成功提示。没有壳没有混淆没有反调试就是一个朴素的逐字节比较。这就很适合练习“从输入到比较再到结果”的完整逆向链路。我自己的建议是两道题都别急着看WriteUp而是按顺序走一遍先确认程序类型再静态分析找到关键函数再动态调试观察数据变化。哪怕最后没做出来这个过程也比直接抄答案有效得多。1.2 环境与工具链准备做这两道题最合适的平台是Windows系统。我在实际复现时用的是以下几套工具全部免费而且到现在也能稳定运行工具用途版本建议CFF Explorer查看PE结构、导入表、区段信息用经典版或修改版均可IDA Pro / Ghidra静态反汇编、F5伪代码分析IDA 7.x以上或Ghidra 10.xx64dbg动态调试、下断点、单步跟踪保持最新版HxD / 010 Editor十六进制查看、从数据区提取字节任意版本用着顺手就行Detect It Easy快速识别编译器和加壳情况社区版即可这里有个小经验老题经常被Windows 10/11系统兼容性坑我遇到过好几次明明逻辑很简单但程序一运行就崩的情况。排查下来大多是旧版OllyDbg在Win10以上系统不稳定导致的崩溃。所以动态调试优先用x64dbg同一个功能比OllyDbg省心得多。另外这两道题都是32位程序所以即使系统是64位也不影响运行。加载到IDA时默认选择32位反汇编地址范围在0x400000附近别选错。2. very_success解题过程实录2.1 先看文件再跑一次拿到very_success的exe我习惯先用Detect It Easy扫一下结果显示是Microsoft Visual C编写的MFC程序没有加壳。这是好消息意味着可以正常静态分析不需要先考虑脱壳。接下来在Windows里直接双击运行。屏幕上会弹出一个标准的MFC对话框里面有一行文字我记得大致是“You are a success now, keep going on”之类的提示还有一个按钮。我框选、复制对话框标题和内容文本把字符串记下来。这一步很简单但非常关键因为Flag往往就藏在提示文字附近或者提示文字本身就会暗示你下一步该做什么。当时我点按钮没有任何反应说明这个程序的核心逻辑不在按钮的交互上而更像是在窗口初始化的过程中就已经完成了判断。这就引导我去关注程序入口和对话框初始化函数。2.2 导入表里的反调试信号打开CFF Explorer切换到Import Table页我习惯先扫一眼程序导入了哪些系统API。对于MFC程序来说常见导入多数是user32.dll的窗口相关函数比如MessageBoxA、DialogBoxParam。但我在导入表里看到了一个很扎眼的APIIsDebuggerPresent。这个名字的意思很直白检查当前进程是否处于调试状态。如果你用调试器附加或加载运行这个函数会返回非零值程序就可以借此改变执行流程。很多正规软件也会用这个功能做反调试但CTF题里出现它基本就是在明说你要处理掉这个检测才能继续往下走。按照理想化的解题流程有两条路可选。第一条是在动态调试时绕过检测比如在调用IsDebuggerPresent之后把ZF标志位改掉让程序走正常分支。第二条是在静态分析时直接修改跳转指令把原本“检测到调试器就退出/弹错误提示”的跳转改成永远不跳转。更简单的做法是把IsDebuggerPresent的返回值直接置零常见手段是在导入表里把该函数改为返回零的自定义函数或者干脆patch调用点。我采用的方式是直接上x64dbg加载程序后在GetModuleHandleA和IsDebuggerPresent上先下一组断点。程序走到IsDebuggerPresent的调用处时单步越过这个Call紧接着查看返回值寄存器EAX。如果是1说明反调试触发我直接修改它的值为0然后再继续运行。2.3 单步跟踪到关键分支绕过反调试后程序继续执行很快会到达一个比较跳转的分支。这里典型的汇编形式是这样call IsDebuggerPresent test eax, eax jz short loc_401xxxjz的意思是“如果ZF1则跳转”。如果test eax,eax后EAX为0ZF会置1程序会跳到正常流程如果EAX非0ZF为0程序会进入另一个分支。所以在这个点上有两种patch思路改EAX为0或者把jz改成jmp。逻辑不同效果一致。在实际调试时我用x64dbg在test指令上按F8单步看到ZF状态然后右键选择“Edit flags”把ZF置1再F8继续。这一步之后我看到了窗口弹出显示的内容和双击运行时完全不一样——它会直接展示Flag字符串。这里有一个新手容易踩的坑很多人一上来就在消息框API上找Flag因为在正常运行时窗口里确实显示了Flag。但如果你没有先处理反调试根本走不到那条消息框调用。所以顺序很重要先看分支再找输出点。2.4 定位Flag字符串并验证当正确的消息框弹出时程序调用的是MessageBoxW或者MessageBoxA。在x64dbg里看到了调用点之后可以把断点下在MessageBoxW入口看栈上的参数hWnd、lpText、lpCaption、uType。lpText里就是完整的显示文本。我顺手在x64dbg的“字符串参考”里搜了一下发现Flag并不是简单明文放在数据段里而是拼接出来的。确切说它分成几段在不同位置存放最终通过某种方式组装成完整字符串。但在实际调试时你不一定需要理解它的拼接算法直接从MessageBoxW的参数里提取最终结果即可。最终拿到的Flag就是那一串完整文本格式一眼就能认出来。我把它复制下来到程序的消息框里手动验证确认无误。这种“先反调试再提取字符串”的组合套路在后续很多Windows逆向题里都非常常见。3. Challenge1的完整分析流程3.1 运行现象与程序行为Challenge1是一个典型的控制台程序运行后会先输出一段提示要求你输入key。输入之后程序会做判断如果正确则输出一段祝贺信息如果错误则输出提示并要求重试。从表现来看这就是一个最简单的“密码校验”逻辑。我先在命令行里跑了两次一次输入随意字符串一次输入空回车观察输出差异。然后把程序放进IDA Pro找到入口函数。因为程序没有加壳且没有反调试所以静态分析非常顺畅整个代码量也很小属于看一眼就能明白逻辑的级别。3.2 主逻辑与逐字节比较在IDA里定位到main或WinMain之后F5切换到伪代码视图可以看到大概这样的结构程序先调用某个输入函数读取键盘输入把读到的字符串保存到缓冲区然后进入一个循环或者直接调用一个子函数对输入的每个字符和某个预置的数组逐字节比较。这道题的做法在于找到那个预置数组。因为它是编译进程序数据段的常量不管你对它做什么变换原始字节就躺在那里。所以核心任务是在数据区找到这个数组然后把它还原成字符串。这里我用了一个比较直接的方法在IDA中定位到比较指令比如下面的模式movzx eax, byte ptr [ediecx] movzx edx, byte ptr [esiecx] cmp eax, edx jne short loc_wrong当看到“程序读入的某地址”和“全局地址0x403000附近”在做比较时就可以确认0x403000就是关键数组的起始位置。在IDA里跳到这个地址按D键把数据切换成字符形式就能直接看到一串可读文本。得到结果后我先手动在程序里输入程序给出了成功提示。这一步没有任何意外逻辑就是逐字节比对没有加密、没有变换、没有二次校验。3.3 为什么说这题是“教科书级”样例Challenge1的经典之处在于它把大部分CTF逆向题的核心过程压缩到了一个极小的范围内找到输入入口找到比较函数提取预置数据。整个过程不需要你处理壳、花指令、混淆甚至不需要复杂的动态调试只要静态分析功底过关几分钟就能解决。但真正有价值的是流程本身。很多更复杂的题目会在比较之前增加各种变换比如异或、base64编码、倒序处理、CRC校验但万变不离其宗——最终一定有一个“和某个已知数据比较”的动作。你只要能找到那个动作就能沿着代码往前回溯整理出输入数据需要满足的条件。所以说这题适合作为“逆向入门第一题”。它能把你对逆向的恐惧感降下来让你意识到很多CTF逆向题并没有想象中那么难缺的只是你的耐心和正确的分析路径。4. 实操中的常见坑与排查技巧4.1 动态调试时程序直接退出的问题这样的反调试题目很多人在x64dbg里按F9跑起来结果是程序直接退出或者弹一个错误窗口。问题原因未必是你做错了什么而是IsDebuggerPresent在以调试模式加载时几乎必然返回非零值。我的处理习惯是加载程序后先把断点下到程序的EP代码开头处不要在系统DLL里乱跳然后按F8单步直到看见调用IsDebuggerPresent或类似函数。如果你用的是x64dbg还可以直接在“符号表”里导入ntdll模块找到IsDebuggerPresent后下断点但要注意它在不同Windows版本里可能走不同的内部封装。另一个小技巧如果你只想快速拿到Flag不在乎正经绕过反调试可以直接在IDA里把关键跳转指令patch成EBjmp或者把调用IsDebuggerPresent的代码改成33 C0xor eax,eax。这里的核心思路是打破“检测到调试器就走错误路径”的逻辑让程序强制走正常流程。提示patch文件之前先备份这样如果你在调试过程中改坏了还能恢复原文件重新来。4.2 MFC程序里字符串找不到的困惑MFC程序里很多字符串不是普通ASCII而是UTF-16的宽字符串。你在IDA的字符串列表里搜关键字时可能搜不到明文或者搜到的是看起来像“乱码”的数据。这是因为IDA默认字符串类型可能没设置成Unicode或者程序使用了MessageBoxW显示的是宽字符。我用IDA时如果发现某个字符串没有在Strings窗口中出现会先尝试在输出区域右键切换到“Unicode”模式或者在Options里调整Strings窗口的字符集设置。多数字符串定位问题都能通过这个办法解决。CFF Explorer里也能在资源段看到MFC对话框模板和默认文本但要注意区分资源里的提示语和真正的Flag数据。4.3 动态与静态分析的结果对不上偶尔会遇到一种情况静态分析时看到跳转逻辑很清晰Flag字符串就在某个地址但动态调试时点击按钮或者运行程序显示出来的内容却不一样。这时候可以先考虑程序的运行路径是否不止一条比如它在窗口初始化和按钮点击里各自做了一次判断。我当初复盘这两道题的时候就发现very_success的提示文本在不同状态下会有不同版本。调试器未附加的情况下显示的是错误提示绕过反调试后显示的是正确Flag。如果你看到的结果和我描述的不一致优先检查你是不是没有处理反调试而不是先去怀疑静态分析错了。4.4 工具链版本带来的额外麻烦老题配上新工具偶尔会有些不兼容。我遇到过IDA 7.5加载某样本后函数识别异常F5不出伪代码也遇到过x64dbg调试某些旧MFC程序时在系统断点处卡住。这类问题通常很好解决把系统断点设置关掉直接运行到入口或者换一个版本的IDA又或者先用CFF Explorer重建PE后重新加载。另外如果你在主流的64位Windows上跑老版OllyDbg会发现附加进程很慢而且断点经常失效。这不是你的问题是OllyDbg对现代Windows支持不好。别在工具上死磕换x64dbg往往立刻就好了。5. 从两题延伸到更难的逆向题两道题都做完之后值得花几分钟复盘一下它们的共性。very_success考验的是“识别反调试并绕过”的意识Challenge1考验的是“从比较逻辑还原输入”的基本功。这两点几乎可以在任何Windows平台CTF逆向题里看到。再往后走你会碰到的常见变体包括但不限于变体方向典型特征应对思路加壳导入表被隐藏入口点异常先用工具识别壳类型再决定脱壳或动态转储花指令反汇编出现大量无效指令用“写代码模式”手动修复或用插件自动去花多级校验输入先过第一层再过第二层不要只看一个比较点要画全流程数据流反调试升级不止IsDebuggerPresent还有时间检测、NtQueryInformationProcess等先识别API再决定hook方案加密比较输入被加密/编码后参与比较关键在于找到解密后的目标数组而不是输入原值这些方向说起来复杂但解题思路的核心始终没变找到程序对输入数据的处理路径找到最终校验点再反推输入内容。你在这两道基础题里建立的流程就是解决这些变体问题的底层框架。就我个人经验而言做这一行最怕的不是题难而是手里有一堆工具却不知道第一步该干什么。这两道题的价值正在于把“第一步该干什么”训练成肌肉记忆先看文件类型再跑一遍程序感知行为然后用静态分析定位关键函数最后用动态调试验证路径。整个过程走完你对Windows程序的逆向分析就有了一个可复用的起点。以后不管遇到MFC弹窗、控制台校验还是某个看着很唬人的图形程序你都能从这套流程里找到一个切入的立足点。这比单独记住两道题的答案有意义得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询