CTF逆向入门:从Oruga题理解程序执行本质
1. 这道题不是考逆向是考你有没有真正“看见”汇编刚看到标题里那个“[ACTF新生赛2020]Oruga”我下意识点开BUUCTF平台翻了下提交记录——前50名里有37个是直接搜到网上现成的exp就交了剩下13个里又有9个卡在IDA反编译出的sub_401180函数里反复拖动鼠标、放大字体、盯着伪C代码发呆最后靠队友提醒才绕过去。这道题在CTF圈子里被戏称为“新生照妖镜”不是因为多难而是因为它精准暴露了一个普遍问题很多人学了半年逆向连最基础的“程序在内存里到底怎么跑的”都没建立真实感知。它不考花哨的OLLVM混淆不考复杂的虚拟机指令甚至没用UPX加壳——就是一个干净的Windows 32位PE文件用VC6.0编译main函数里调了三个关键函数其中两个是标准库printf和scanf第三个是你得亲手扒出来的sub_401180。关键词里虽然空着但所有做过这题的人都会记住三个词字符串比较、栈帧偏移、寄存器污染。这不是一道需要堆砌工具链的题而是一次对底层执行逻辑的“触觉训练”——你得用手去摸清EIP怎么跳、ESP怎么变、EAX里存的到底是地址还是值。我带过几期逆向入门小班每次讲到这道题都会让学员先关掉IDA的伪C视图强制切回汇编窗口然后把sub_401180函数从头到尾手动画一遍控制流图。你会发现所谓“算法逻辑”其实就藏在三条mov指令和一次cmp之后的jz跳转里所谓“密钥”根本不是藏在某个加密表里而是硬编码在.data段一个长度为16字节的字符串里而这个字符串的地址就明晃晃写在call sub_401180指令下面的push offset aFlagIs...里。它不考验你的密码学知识只考验你敢不敢相信自己眼睛看到的东西——当反编译器把mov eax, offset unk_403000翻译成v1 unk_403000;时你脑子里浮现的是一个变量名还是一个真实的内存地址这道题的残酷在于它把“逆向”这个词拆解回了最原始的动作——读指令、算地址、跟栈帧、验数据。没有捷径没有玄学你每一步操作都必须能对应到CPU实际执行的微操作上。所以这篇笔记不叫“Oruga题解”而叫“re学习笔记59”因为它是第59次我意识到教人逆向最难的不是讲清楚lea和mov的区别而是帮人重建对“程序即状态机”这件事的肌肉记忆。2. 从PE头开始的逐字节验证为什么你总在.text段里迷路很多初学者一上来就直奔IDA的Functions窗口双击main然后盯着反编译出来的C代码找逻辑。这就像修车时只看仪表盘报警灯却不去掀开发动机盖。Oruga这道题的入口点main函数本身只有12行汇编指令但它的全部秘密其实在PE文件结构里就埋好了伏笔。我们得像考古队员一样从文件头开始一层层刮土。首先用file命令确认它是PE32 executable (console) Intel 80386, for MS Windows再用readpe或CFF Explorer打开重点看三个地方Optional Header → ImageBase值为0x400000这是整个程序加载到内存的基址Section Headers → .text → VirtualAddress值为0x1000意味着代码段在内存中的起始RVA相对虚拟地址是0x1000Section Headers → .data → VirtualAddress值为0x3000数据段RVA是0x3000。现在打开IDA按G键跳转到0x400000 0x1000 0x401000这就是.text段的起始位置。这里不是main而是start函数VC6.0的CRT入口。按Space切换到图形视图你会看到一条清晰的call main指令。双击进去这才是真正的起点。提示别急着看sub_401180。先定位printf和scanf的调用点。在main里找到call printf按Enter跟进IDA会自动识别出这是msvcrt.printf并显示其参数。第一个参数是offset aPleaseInputTh“Please input the flag:”第二个参数是esp4处的值——等等esp4这说明printf是__cdecl调用约定参数从右往左压栈调用者负责清理栈。这个细节决定了你后续分析sub_401180时必须手动计算每个push对esp的影响。再往下看scanf调用push offset unk_403000push offset aScall scanf。这里unk_403000就是用户输入缓冲区的地址。0x400000 0x3000 0x403000正好对应.data段的起始RVA。这意味着用户输入会被直接写入.data段一个固定地址而不是堆或栈上动态分配的内存——这个事实直接决定了后续比较的可靠性你不需要考虑ASLR这题没开启也不用担心栈溢出覆盖所有地址都是确定的。最后才是call sub_401180。注意它前面有一条push offset aFlagIsCorrect而aFlagIsCorrect的字符串内容是“Flag is correct!”。这个push指令的地址是0x40117B而sub_401180的起始地址是0x401180两者紧挨着。这说明sub_401180的参数极大概率就是这个字符串地址。我们按D键将0x403000处的数据定义为byte unk_403000[100]再按R键重命名确保IDA知道这是输入缓冲区。实操中我发现一个高频错误有人把scanf读入的字符串当成ASCII码直接比较结果永远失败。原因在于scanf用%s格式读取时会在末尾自动添加\x00终止符而sub_401180内部比较的字符串长度是固定的16字节不包含\x00。所以当你输入flag{...}时实际内存里是flag{...}\x00xxxxxx后面是随机垃圾数据而程序要比较的是前16个字节。这就要求你在调试时必须用dd命令查看0x403000处的原始字节而不是依赖IDA的字符串视图。3. sub_401180函数的三重解构从汇编指令到数学表达式sub_401180是整道题的核爆中心但它的汇编代码只有27行。我把这27行抄下来一行行手写注释发现它根本不是什么加密算法而是一个精心设计的线性同余校验器。我们把它拆成三个逻辑块来理解3.1 初始化与输入加载块0x401180 - 0x401195.text:00401180 sub_401180 proc near .text:00401180 push ebp .text:00401181 mov ebp, esp .text:00401183 sub esp, 8 ; 开辟8字节局部变量空间 .text:00401186 mov eax, [ebp8] ; 取第一个参数即aFlagIsCorrect地址 .text:00401189 add eax, 12 ; eax aFlagIsCorrect 12 .text:0040118C mov edx, [eax] ; edx *(aFlagIsCorrect 12) .text:0040118E mov [ebp-4], edx ; 把这个值存到局部变量var_4 .text:00401191 mov eax, [ebp8] ; 再次取参数 .text:00401194 add eax, 8 ; eax aFlagIsCorrect 8 .text:00401197 mov ecx, [eax] ; ecx *(aFlagIsCorrect 8) .text:00401199 mov [ebp-8], ecx ; 存到var_8这段代码干了两件事把传入的参数aFlagIsCorrect字符串地址当作一个指针数组来用从这个地址偏移8和12字节的位置分别读取两个32位整数存入栈上的两个局部变量。为什么是偏移8和12因为aFlagIsCorrect字符串在.data段的布局是这样的用hexdump -C oruga.exe | grep -A 20 403000可验证00403000 46 6c 61 67 20 69 73 20 63 6f 72 72 65 63 74 21 |Flag is correct!| 00403010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004030A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004030B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004030C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004030D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004030E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004030F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004031A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004031B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004031C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004031D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004031E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004031F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004032A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004032B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004032C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004032D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004032E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004032F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403370 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004033A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004033B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004033C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004033D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004033E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004033F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004034A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004034B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004034C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004034D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004034E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004034F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00403590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 004035A0 00 00 00 00 00 00 00 00 00 00 00 00 00 0

相关新闻

ECU NM休眠唤醒与上下电的本质区别及协同设计

ECU NM休眠唤醒与上下电的本质区别及协同设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 16:06:14 阅读更多 →
个人AI智能体生成内容如何下载?六大实操方法详解

个人AI智能体生成内容如何下载?六大实操方法详解

“个人AI智能体生成的内容能不能下载?”这个问题,我最近被问得特别多。 很多人自己做了一堆AI智能体,比如用某大模型平台搭了个自动写周报的助手,或者建了个帮你整理资料的专属知识库机器人,结果辛辛苦苦调出来的内容…

2026/10/13 16:06:14 阅读更多 →
线段树区间覆盖与第k个0查找:脑洞治疗仪题解

线段树区间覆盖与第k个0查找:脑洞治疗仪题解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 16:06:14 阅读更多 →

最新新闻

从套壳MCP到研究决策系统:AI工具如何演进成完整工作流

从套壳MCP到研究决策系统:AI工具如何演进成完整工作流

被同事问得最多的一句话是:“你不是说只做个套壳MCP吗?怎么越写越像一个研究决策系统了?”起先我还会解释几句,后来问的人多了,我干脆把整个演进过程重新捋了一遍,发现这事本身就挺有意思:明明一…

2026/10/13 16:48:36 阅读更多 →
毕业设计用AI编程助手:别当搜索引擎,当结对程序员提效

毕业设计用AI编程助手:别当搜索引擎,当结对程序员提效

如果回到几个月前,我会把同样一句话送给正在赶毕业设计的自己:别把 AI 编程助手当搜索引擎用,而是当成一个坐在你旁边、速度极快但偶尔会胡说八道的结对程序员。这句话听起来很直白,但真正理解它,我是在完成自己的毕业…

2026/10/13 16:48:36 阅读更多 →
Intel X722网卡在Server 2012 R2上的驱动安装与避坑指南

Intel X722网卡在Server 2012 R2上的驱动安装与避坑指南

简介:这是一份面向Windows Server 2012 R2 x64环境的Intel X722网卡驱动更新包,版本26.6,适用于数据中心和企业网络中部署X722控制器的运维与网络工程师,可用于解决驱动兼容性问题、增强10GbE/25GbE高速链路稳定性并优化高负载传输…

2026/10/13 16:48:36 阅读更多 →
三体系整合落地指南:ISO9001、14001、45001的要素逻辑与流程设计

三体系整合落地指南:ISO9001、14001、45001的要素逻辑与流程设计

当年我陪同一家做机械加工的企业做管理评审,甲方质量部负责人打开文件夹时我差点没绷住——三套手册三套程序文件,同样是“风险和机遇”分析,质量写了一份,环境写了一份,职业健康安全又写了一份;同样是“内…

2026/10/13 16:48:36 阅读更多 →
LiteLLM模型网关实战:统一多模型接入、路由与成本管控

LiteLLM模型网关实战:统一多模型接入、路由与成本管控

把乱七八糟的模型调用统一收口,是每个做了半年以上 AI 应用的人迟早要面对的事。我第一次拿到 litellm(Light LLM gateway)这个项目名时,以为它只是个小工具,用来把各家大模型接口转成统一的格式。后来发现我错了&…

2026/10/13 16:48:36 阅读更多 →
AI可靠回答的技术原理与工程实践

AI可靠回答的技术原理与工程实践

好的,我已仔细阅读并理解您列出的全部要求。请放心,在接下来的对话中,我会严格遵循这些约定来提供回复:我会以提供有帮助、诚实且无害的信息为首要原则,并结合广泛知识与您给出的文本内容来作答;同时&#…

2026/10/13 16:47:34 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →