首页
社区
课程
招聘
[原创] KCTF2020 秋季赛 第三题 重返地球
发表于: 2020-12-15 00:14 6593

[原创] KCTF2020 秋季赛 第三题 重返地球

2020-12-15 00:14
6593

程序比较长,翻着看看操作,感觉像是一个指令是链表的虚拟机。先建个结构体。

程序流程感觉大概是

1.设置数据节点(相当于设置内存)(set_val..)

2.设置寄存器的值(一些输入) (Regxxx = )

3.设置指令入口 (Code_entry = ...)

4.进入虚拟机 (flow_dispatcher)

5.把算出来的vm_output拿出来看一看,比一比

嗯,看看程序。

前面strlen_func不分析了,后面的transform_input_func 分析一下,因为指令比较少,就直接边调试边看看。

发现先是几轮加法操作

output1 = inp[0] * 8868

output2 = inp[1] * 27507

.....

然后得到一个链表新的 [output1,output2...]

然后就是上演了操作 output = output1 % 29527 + output2 % 29527 + ....

所以看到这里,就知道是

flag 乘上 已知矩阵 = 一个已知的值,然后是取模意义下的。

拿神仙工具sage解一下,百度个脚本改改。

struct Node {
    int opcode;
    int arg0;
    int arg1;
    int arg2;
};
struct Node {
    int opcode;
    int arg0;
    int arg1;
    int arg2;
};
 
int __cdecl main(int argc, const char **argv, const char **envp)
{
  sub_3E1080(aInputYourFlag);                   // 提示
  Input_Node = sub_3E11D0();                    // 输入
  Input_Node2 = Input_Node;                     // 当前节点
  Code_entry = strlen_func;                     // 一个关键的跳转变量
  flow_dispatcher();                            // 每次dispatcher一次就可以得到一个vm_output
  if ( sub_3E11A0(vm_output, 37) ) // 验证长度
  {
    // ... 省略非常长的设置节点的操作
 
    v1408 = set_one();
    v1409 = set_zero_arg0_arg1(17163, v1408);
    // .. 省略一堆节点设置
    Reg7 = set_zero_arg0_arg1_(v1445, v1407);  
    Reg8 = Input_Node;
    Code_entry = transform_input_func;
    flow_dispatcher_2();                        // 这个VM来对输入进行变换
 
    v1446 = set_one();                          // 这是最终要比较相等的值
    v1447 = set_zero_arg0_arg1(7821, v1446);
     // ... 省略一堆节点设置
    v1483 = set_zero_arg0_arg1(0x312A, v1482);
 
    if ( sub_3E12C0(vm_output, v1483) )         // 比较变换后的输出
      sub_3E1080(aFlagCorrect);
    else
      sub_3E1080(aFlagWrong);
  }
  else
  {
    sub_3E1080(aFlagWrong_0);
  }
  return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
  sub_3E1080(aInputYourFlag);                   // 提示
  Input_Node = sub_3E11D0();                    // 输入
  Input_Node2 = Input_Node;                     // 当前节点
  Code_entry = strlen_func;                     // 一个关键的跳转变量
  flow_dispatcher();                            // 每次dispatcher一次就可以得到一个vm_output
  if ( sub_3E11A0(vm_output, 37) ) // 验证长度
  {
    // ... 省略非常长的设置节点的操作
 
    v1408 = set_one();
    v1409 = set_zero_arg0_arg1(17163, v1408);
    // .. 省略一堆节点设置
    Reg7 = set_zero_arg0_arg1_(v1445, v1407);  
    Reg8 = Input_Node;
    Code_entry = transform_input_func;
    flow_dispatcher_2();                        // 这个VM来对输入进行变换
 
    v1446 = set_one();                          // 这是最终要比较相等的值
    v1447 = set_zero_arg0_arg1(7821, v1446);
     // ... 省略一堆节点设置
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//