news 2026/4/22 18:34:29

BUUCTF SimpleRev:逆向工程中的字符变换算法解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BUUCTF SimpleRev:逆向工程中的字符变换算法解析

1. 逆向分析入门:从SimpleRev看CTF题目设计

第一次接触BUUCTF的SimpleRev题目时,我完全被它精巧的设计吸引了。这道题表面看起来是个简单的字符处理程序,但深入分析后会发现其中蕴含着典型的CTF逆向工程考点。我们先来看看这个程序的基本行为:运行后会提示输入d/D开始或q/Q退出,选择开始后进入Decry函数,要求用户输入flag并进行验证。

逆向工程中最关键的是理解程序的数据流。在SimpleRev中,有几个关键变量需要注意:

  • key1和key3是硬编码在程序中的字符串
  • src和v9这两个变量需要特别注意字节序问题
  • text变量由key3和v9拼接而成
  • key变量由key1和src拼接而成

我在分析时犯过一个典型错误:直接看IDA反编译的伪代码,忽略了数据存储方式。src和v9在内存中是以整型形式存储的,需要右键转换为char数组才能看到实际字符串内容。更坑的是这里还涉及大小端问题,字符串需要手动反转才能得到正确值。比如src显示为'SLCDN',实际应该是'NDCLS'。

2. 深入解析字符变换算法

2.1 密钥预处理过程

程序首先会对key进行预处理,这个过程很有意思:

for ( i = 0; i < key_len; ++i ) { if ( key[key_p % key_len] > 64 && key[key_p % key_len] <= 90 ) { key[i] = key[key_p % key_len] + 32; } ++key_p; }

这段代码的作用是将key中的所有大写字母转换为小写。但实现方式很特别:它使用key_p % key_len来循环遍历key,而不是直接使用循环变量i。这种写法在CTF题目中很常见,目的是增加一点分析难度。

我实际调试时发现,经过预处理后,key从"ADSFKNDCLS"变成了"adsfkndcls"。这个细节很重要,因为后续的加密算法会用到处理后的key。

2.2 核心加密算法剖析

真正的加密逻辑在用户输入处理部分:

if ( input <= 96 || input > 122 ) { if ( input > 64 && input <= 90 ) { str2[input_not_return_cnt] = (input - 39 - key[key_p % key_len] + 97) % 26 + 97; ++key_p; } } else { str2[input_not_return_cnt] = (input - 39 - key[key_p % key_len] + 97) % 26 + 97; ++key_p; }

这个算法有几个特点:

  1. 同时处理大小写输入,但处理方式相同
  2. 使用key循环对输入字符进行变换
  3. 变换公式为:(input - 39 - key_char + 97) % 26 + 97
  4. 每处理一个非空格字符,key_p递增

我花了些时间推导这个公式的实际含义。经过多次测试发现,它本质上是一种基于字母表的位移加密,类似于凯撒密码但更复杂。公式中的-39和+97看似随意,实际上是为了将ASCII码调整到0-25范围内进行模运算。

3. 逆向破解实战:从静态分析到动态验证

3.1 关键数据提取

要破解这个加密,首先需要获取所有必要的数据:

  1. text = "killshadow"(这是目标输出)
  2. key = "adsfkndcls"(预处理后的密钥)
  3. 加密算法已知

在IDA中查找这些字符串时,要注意字符串可能被拆分成多个部分。比如key1是"ADSFK",key3是"kills",而v9是"hadow"(需要反转字节序)。

3.2 枚举破解的实现

由于加密算法是可逆的,我们可以尝试枚举所有可能的输入:

for (int i = 0; i < 10; i++) { for (int j = 0; j < 26; j++) { char put = 'A' + j; if (text[i] == (put - 39 - key[i % key_len] + 97) % 26 + 97) { cout << put; break; } } }

这个枚举算法尝试每个位置的大写字母(A-Z),检查加密后是否匹配目标text中的对应字符。我最初尝试同时枚举大小写,但发现只有大写字母能得到有意义的flag。

在实际测试中,我发现当输入为"KLDQCUDFZO"时,加密结果正好是"killshadow"。这就是我们要找的flag。有趣的是,如果尝试小写字母组合,虽然也能得到一些结果,但不符合题目要求。

4. 经验总结与技巧分享

逆向工程中最耗时的往往不是算法分析,而是数据提取和预处理。在SimpleRev这道题中,我踩过几个坑:

  1. 字节序问题:src和v9的整型表示需要转换为正确的字符串形式。我一开始忽略了这点,导致后续分析完全错误。

  2. 密钥预处理:没注意到程序会修改key的内容,直接用原始key进行解密尝试,自然得不到正确结果。

  3. 枚举范围:最初同时枚举大小写,导致结果不唯一。后来发现题目预期flag是全大写的,才缩小了枚举范围。

对于类似的题目,我建议:

  • 仔细检查所有数据提取是否正确
  • 动态调试验证静态分析结果
  • 注意题目给出的暗示(如flag格式要求)
  • 从简单情况开始测试(如不加空格)

逆向工程就像解谜,需要耐心和系统性的方法。SimpleRev虽然名字简单,但包含了许多典型的逆向考点,是非常好的练习题目。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 18:29:07

无监督学习:让AI自己发现“人以群分”的秘密

没有老师&#xff0c;机器怎么学&#xff1f; 监督学习像有标准答案的习题册&#xff0c;无监督学习则像一堆没整理的乐高零件——让AI自己找出结构、分组或规律。 &#x1f9e9; 生活类比&#xff1a; 你拿到一堆从未见过的水果&#xff08;形状、颜色、大小都不同&#xff0…

作者头像 李华
网站建设 2026/4/22 18:28:51

OSPFv3网络排错实战:当IPv6路由丢失时,如何用Intra-Area-Prefix LSA定位问题(附报文分析)

OSPFv3网络排错实战&#xff1a;当IPv6路由丢失时如何精准定位问题 凌晨三点&#xff0c;运维工程师小李被监控系统告警惊醒——核心网络的IPv6路由表出现异常缺失。这种问题在OSPFv3网络中并不罕见&#xff0c;但每次排查都像在黑暗森林中寻找隐藏的狙击手。本文将分享一套基于…

作者头像 李华
网站建设 2026/4/22 18:25:22

Onekey:3分钟完成Steam清单下载的终极自动化工具

Onekey&#xff1a;3分钟完成Steam清单下载的终极自动化工具 【免费下载链接】Onekey Onekey Steam Depot Manifest Downloader 项目地址: https://gitcode.com/gh_mirrors/one/Onekey 在Steam游戏生态中&#xff0c;获取和管理Depot清单文件是开发者、MOD创作者和技术爱…

作者头像 李华
网站建设 2026/4/22 18:22:27

如何让你的鼠标滚轮爽如触控板:Mos 终极平滑滚动解决方案

如何让你的鼠标滚轮爽如触控板&#xff1a;Mos 终极平滑滚动解决方案 【免费下载链接】Mos 一个用于在 macOS 上平滑你的鼠标滚动效果或单独设置滚动方向的小工具, 让你的滚轮爽如触控板 | A lightweight tool used to smooth scrolling and set scroll direction independentl…

作者头像 李华