BUUCTF_reverse_[MRCTF2020]Transform

一、查壳

1、使用工具

2、检查结果

这表明程序​​未加壳​​,我们可以直接进行下一步的代码分析。

二、分析代码

1、静态分析

用IDA Pro打开程序,等待自动分析完成。

F5反汇编得到

cs 复制代码
// local variable allocation has failed, the output may be wrong!
int __fastcall main(int argc, const char **argv, const char **envp)
{
  char input[104]; // [rsp+20h] [rbp-70h] BYREF
  int i; // [rsp+88h] [rbp-8h]
  int j; // [rsp+8Ch] [rbp-4h]
 
  // 调用子函数sub_402230,参数包括argc、argv和envp
  sub_402230(*(_QWORD *)&argc, argv, envp);
  // 提示用户输入代码
  printf("Give me your code:\n");
  // 从标准输入读取字符串到input数组
  scanf("%s", input);
  // 检查输入字符串长度是否为33个字符,如果不是则输出错误信息并退出程序
  if ( strlen(input) != 33 )                    // 33个字符
  {
    printf("Wrong!\n");
    system("pause");
    exit(0);
  }
  // 遍历输入字符串的每个字符,进行特定的字符操作
  for ( j = 0; j <= 32; ++j )                   // 遍历数组
  {
    a[j] = input[b[j]];
    a[j] ^= LOBYTE(b[j]);                       
  }
  // 再次遍历数组,检查a数组和c数组对应位置的字符是否相同,如果不同则输出错误信息并退出程序
  for ( i = 0; i <= 32; ++i )
  {
    if ( c[i] != a[i] )                         // a==c
    {
      printf("Wrong!\n");
      system("pause");
      exit(0);
    }
  }
  // 如果所有检查都通过,则输出成功信息和flag
  printf("Right!Good Job!\n");
  printf("Here is your flag: %s\n", input);
  system("pause");
  return 0;
}

先来看大概的过程,输入33个字符的input

接下来是核心的加密方法:遍历数组input将input[b[j]]的元素赋值给a数组,然后a数组异或LOBYTE(b[j])

最后将a与c数组进行对照,如果不一样就输出错误,反之得到a==c得到正确

其中疑点在b数组的内容,c数组的内容

双击b数组可以看到

我们需要提取具体内容,选中需要提取的内容,点击上方导航栏的edit

b数组就是这样了

复制代码
b=[9,   0,   0,   0,  10,   0,   0,   0,  15,   0,
    0,   0,  23,   0,   0,   0,   7,   0,   0,   0,
   24,   0,   0,   0,  12,   0,   0,   0,   6,   0,
    0,   0,   1,   0,   0,   0,  16,   0,   0,   0,
    3,   0,   0,   0,  17,   0,   0,   0,  32,   0,
    0,   0,  29,   0,   0,   0,  11,   0,   0,   0,
   30,   0,   0,   0,  27,   0,   0,   0,  22,   0,
    0,   0,   4,   0,   0,   0,  13,   0,   0,   0,
   19,   0,   0,   0,  20,   0,   0,   0,  21,   0,
    0,   0,   2,   0,   0,   0,  25,   0,   0,   0,
    5,   0,   0,   0,  31,   0,   0,   0,   8,   0,
    0,   0,  18,   0,   0,   0,  26,   0,   0,   0,
   28,   0,   0,   0,  14,   0,   0,   0,0,0,0,0]

同理可以得到c数组的内容

复制代码
c=[103, 121, 123, 127, 117,  43,  60,  82,  83, 121,
   87,  94,  93,  66, 123,  45,  42, 102,  66, 126,
   76,  87, 121,  65, 107, 126, 101,  60,  92,  69,
  111,  98,  77]

还有一点关于LOBYTE[b[j]]

在C语言中,lobyte ​ 通常指一个多字节数据(如int, short)中的低字节(Low Byte),即最低有效字节。

它不是一个标准C语言关键字或函数,而是一个在底层编程、硬件交互或数据协议处理中常用的概念操作

核心概念

对于一个多字节整数(例如 uint16_t, int),它在内存中由多个连续字节存储。lobyte指的是这个值中权重最低的那个字节。

示例:一个32位整数 0x12345678
在小端系统中,内存布局为:
地址0: 0x78 ← 这就是 **lobyte** (最低8位/低字节)
地址1: 0x56 ← 次低字节
地址2: 0x34 ← 次高字节
地址3: 0x12 ← 最高字节

都搞清楚了,接下来就是破解了

三、破解方法

python 复制代码
c = [103, 121, 123, 127, 117, 43, 60, 82, 83, 121, 87, 94, 93, 66, 123, 45, 42, 102, 66, 126, 76, 87, 121, 65, 107, 126, 101, 60, 92, 69, 111, 98, 77]
b = [9, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 23, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 0, 32, 0, 0, 0, 29, 0, 0, 0, 11, 0, 0, 0, 30, 0, 0, 0, 27, 0, 0, 0, 22, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 31, 0, 0, 0, 8, 0, 0, 0, 18, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0]

# 提取 b 中的索引(每4字节的低字节)
newb = b[::4]  # 长度33,为0-32的排列

# 初始化 flag 字符数组
flag = [''] * 33

# 根据映射计算每个位置字符
for j in range(33):
    idx = newb[j]          # input 中的位置
    flag[idx] = chr(c[j] ^ newb[j])

# 合并为字符串
flag_str = ''.join(flag)
print("Flag:", flag_str)

解密的过程有点饶,我们要先异或因为异或过程是可逆的,然后把重排的顺序还原,这个我觉得很绕我举个例子吧

input="ABCD"

0 1 2 3

b=[2,0,3,1]

可以得到

a[0]=input[2]='C'

a[1]=input[0]='A'

a[2]=input[3]='D'

a[3]=input[1]='B'

反过来推

flag[2]='C'=a[0]

flag[0]='A'=a[1]

flag[3]='D'=a[2]

flag[1]='B'=a[3]

Flag: MRCTF{Tr4nsp0sltiON_Clph3r_1s_3z}

四、最终flag

flag{Tr4nsp0sltiON_Clph3r_1s_3z}

相关推荐
zhangfeng1133几秒前
unsloth 安装在google colab
pytorch·python·深度学习
8Qi82 分钟前
LeetCode61. 旋转链表
c语言·数据结构·c++·算法·leetcode·链表·力扣
Nuopiane3 分钟前
MyPal3(7)
java·开发语言
被AI抢饭碗的人3 分钟前
高并发内存池实现
开发语言·c++
不光头强4 分钟前
object所有方法及知识点
java·开发语言·jvm
眼眸流转5 分钟前
LeetCode热题100(一)
算法·leetcode
渡过晚枫6 分钟前
[第十六届蓝桥杯/java/算法]1.偏蓝
java·算法·蓝桥杯
.小小陈.8 分钟前
C++进阶7:深入理解哈希表,从原理到 C++ 实践
开发语言·c++·学习·哈希算法
码云数智-大飞9 分钟前
排序算法的终极博弈:从复杂度推导到工程选型实战
开发语言
2501_9403152611 分钟前
【无标题】1302 层数最深叶子节点的和
java·数据结构·算法