从moectf2025-upx题目里入门链式加密
积累
【套路名称】
链式加密
【触发条件】
一项数据的生成是由其中另一些项决定的
点击展开查看详情
就像一个数列,从左往右依次更新,更新中又有左边或者右边的数据参与(此时就要考虑清楚数据是已处理或是没有被处理)
【操作链路】
从上往下依次分析代码作用(包括参数的理解)
之后从下往上,分析“等效”参数,简化理解
链式异或逆向:先定已知边界明文作锚点,再从最后一个密文往前逐位反推,每一步都依赖前一步已还原的明文。
写脚本
查错误
【我的卡壳点】
今天卡在:
fgets函数的理解,它收录了\n
数组元素数没看仔细,有一些没处理的项我直接扔了
例子
ida反编译结果
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
开始第一步上到下理解
找flag,buffer数组改名为flag数组,,第二个do while里面,v8和v7搞不懂意思导致模糊,v7其实就是从0开始一直到长度,那么v8就是对flag全部进行异或0x21,这个table_1是我改的名,他的用意是执行if语句,只要没到倒数第二个字符,v8同时异或0x21和flag的后一个字符,然后用v14逐个进行储存
全部执行完到下一个while,v5又是一个移位,v10数组是这些数据,E0,10,20,F0,D0,B0,00,C0的顺序,但是不知道具体怎么看这个数据
这个while是在比较v14的各项和v10的各项相不相等第二步下往上整合
那我逆向的想法就是
v14数组等效于v10数组
v7是len,然后dowhile那里从下往上写?table不要了,也是len,但是后面怎么处理呢,一开始是从左往右更新,现在要从右往左逆向,然后呢?或者进行爆破!弄个for从前往后顺没啥事别爆破,正常思路理算法
第三步写代码
1
2
3
4
5
6
7
8
9 unsigned char flag[35]; int len = 35; // 从最后一个字符开始逆推
for (int i = len - 1; i >= 0; i--)
{
if (i == len - 1)
{ // 最后一个字符:没有后继 flag[i+1],直接异或还原
flag[i] = target[i] ^ 0x21;
}
else { // 请根据正向公式
v14[i] = flag[i] ^ 0x21 ^ flag[i+1]写出来这一段,发现乱码
后面才了解是fgets以及数组元素处理的问题
正确代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using namespace std;
unsigned char target[35] = {
0x23, 0x2B, 0x27, 0x36, 0x33, 0x3C, 0x03, 0x48,
0x64, 0x0B, 0x1D, 0x76, 0x7B, 0x10, 0x0B, 0x3A,
0x3F, 0x65, 0x76, 0x29, 0x15, 0x37, 0x1C, 0x0A,
0x08, 0x21, 0x3E, 0x3C, 0x3D, 0x16, 0x0B, 0x24,
0x29, 0x24, 0x56
};
int main()
{
char flag[100]={0};
int len=35;
flag[35] = '\n'; // 起点单独放在这里,不放进target
for(int i=len-1;i>=0;i--)
{
flag[i] = target[i] ^ flag[i + 1] ^ 0x21;
}
cout << flag;
}
思考
当时第一次面对这个代码很难受,感觉这些参数都揉在一起,不想开始。
后面耐下性子认真读,发现并没有那么难。
相似题目
CTF2中的pyre
