CTF-Reverse---VM虚拟机逆向[HGAME 2023 week4]vm题目复现【详解】

news/2024/5/19 20:53:24 标签: CTF, Reverse, 网络安全, 学习, python

文章目录

  • 前言
  • 0x1[HGAME 2023 week4]vm
    • 提取汇编指令
      • mov指令
      • push指令&pop指令
      • 运算操作
      • cmp指令
      • jmp指令
      • je 和 jne
    • exp

前言

没有前言。终于搞定第二题了。费劲是真的费。
题目在nssctf上有。
这一题写完才看到有提示,是关于构建结构体的,下次试试。


0x1[HGAME 2023 week4]vm

在这里插入图片描述
在这里插入图片描述

这里有几个技巧:

  • 将__int64 a1 改为 _DWORD *a1
  • a1 可以 改名为 reg
  • 函数返回值改为void

这样方便观看,还有其他一些函数的名称,不一一做解释。

sub_1400010B0 点进来,一个里面放着字节码改为opcode,一个是调度器。 当opcode当前的索引的值不为255的时候就一直读取下去。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里是做过修过后的,可以看到特别的简洁明了。下面具体分析一下,汇编的实现过程。先给出完整的。

提取汇编指令

python">opcode = [0x00, 0x03, 0x02, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x03, 0x02, 0x32,
          0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
          0x01, 0x00, 0x00, 0x03, 0x02, 0x64, 0x03, 0x00, 0x02, 0x03,
          0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x01, 0x00, 0x00, 0x03,
          0x00, 0x08, 0x00, 0x02, 0x02, 0x01, 0x03, 0x04, 0x01, 0x00,
          0x03, 0x05, 0x02, 0x00, 0x03, 0x00, 0x01, 0x02, 0x00, 0x02,
          0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00, 0x01, 0x03, 0x00,
          0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x01, 0x28,
          0x04, 0x06, 0x5F, 0x05, 0x00, 0x00, 0x03, 0x03, 0x00, 0x02,
          0x01, 0x00, 0x03, 0x02, 0x96, 0x03, 0x00, 0x02, 0x03, 0x00,
          0x00, 0x00, 0x00, 0x04, 0x07, 0x88, 0x00, 0x03, 0x00, 0x01,
          0x03, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03,
          0x01, 0x28, 0x04, 0x07, 0x63, 0xFF, 0xFF]
input1 = []
i = 0
while opcode[i] != 0xFF:
    match opcode[i]:
        case 0x00:
            print(f'{i}', end=' ')
            o = i + 1
            if opcode[o]:
                match opcode[o]:
                    case 0x01:
                        print("mov input[reg[2]], reg[0]")
                    case 0x02:
                        print("mov reg[%d], reg[%d]" % (opcode[i+2],opcode[i+3]))
                    case 0x03:
                        print("mov reg[%d], %d" % (opcode[i+2], opcode[i+3]))
            else:
                print("mov reg[0], input[reg[2]]")
            i += 4
        case 0x01:
            print(f'{i}', end=' ')
            o = i + 1
            if opcode[o]:
                match opcode[o]:
                    case 0x01:
                        print("push reg[0]")
                    case 0x02:
                        print("push reg[2]")
                    case 0x03:
                        print("push reg[3]")
            else:
                print("push reg[0]")
            i += 2
        case 0x02:
            print(f'{i}', end=' ')
            o = i + 1
            if opcode[o]:
                match opcode[o]:
                    case 0x01:
                        print("pop reg[1]")
                    case 0x02:
                        print("pop reg[2]")
                    case 0x03:
                        print("pop reg[3]")
            else:
                print("pop reg[0]")
            i += 2
        case 0x03:
            print(f'{i}', end=' ')
            o = i + 1
            match opcode[o]:
                case 0:
                    print("add reg[%d],reg[%d]" % (opcode[i + 2], opcode[i + 3]))
                case 1:
                    print("sup reg[%d],reg[%d]" % (opcode[i + 2], opcode[i + 3]))
                case 2:
                    print("mul reg[%d],reg[%d]" % (opcode[i + 2], opcode[i + 3]))
                case 3:
                    print("xor reg[%d],reg[%d]" % (opcode[i + 2], opcode[i + 3]))
                case 4:
                    print("shl reg[%d],reg[%d]" % (opcode[i + 2], opcode[i + 3]))
                case 5:
                    print("shr reg[%d],reg[%d]" % (opcode[i + 2], opcode[i + 3]))
            i += 4
        case 0x04:
            print(f'{i} cmp reg[0], reg[1]')
            i += 1
        case 0x05:
            print(f'{i} jmp %d ' % (opcode[i+1]))
            i += 2
        case 0x06:
            print(f'{i} je %d ' % (opcode[i+1]))
            i += 2
        case 0x07:
            print(f'{i} jne %d ' % (opcode[i+1]))
            i += 2

我第一次写,没有区分函数,最好可以写成 def mov(): 这样的形式。

mov指令

在这里插入图片描述

其实我也不太理解,为什么是reg[6](a1[6])这样子, 最后也只理解了它 等同于 i 索引值。

这里经过修改,还是蛮清楚的,reg是寄存器,reg[6] 当做是 i;这里例如case 1:可以理解为将reg[0] 的东西放入 input[reg[2]]里下面也是类似的。case2 是俩个寄存器,case 3就是将opcode[reg[3]]的数据放入寄存器。注意的是最后有个 i += 4 。

其实 i 可以理解为 rip。也就是读取指令的位置。

push指令&pop指令

在这里插入图片描述
栈 + 1,然后 将 reg[0] 的值放进去 ,就是push 指令 ,最后有 i += 2

pop指令同理,寄存器取了栈当前位置的值,然后栈再-1,

运算操作

在这里插入图片描述

这里其实蛮清楚的,就是寄存器之间的加减之类的运算。

cmp指令

在这里插入图片描述
比较函数,返回 0 或者 1;

jmp指令

在这里插入图片描述
改完后简单明了,就是 i = 下一个位置

je 和 jne

一个是不为 0 跳转 一个 是为零 跳转。
在这里插入图片描述
在这里插入图片描述

这里就分析完了。运行一开始的exp

得到近似的汇编

0 mov reg[2], 0
4 add reg[2],reg[3]
8 mov reg[0], input[reg[2]]
12 mov reg[1], reg[0]
16 mov reg[2], 50
20 add reg[2],reg[3]
24 mov reg[0], input[reg[2]]
28 add reg[1],reg[0]
32 mov reg[2], 100
36 add reg[2],reg[3]
40 mov reg[0], input[reg[2]]
44 xor reg[1],reg[0]
48 mov reg[0], 8
52 mov reg[2], reg[1]
56 shl reg[1],reg[0]
60 shr reg[2],reg[0]
64 add reg[1],reg[2]
68 mov reg[0], reg[1]
72 push reg[0]
74 mov reg[0], 1
78 add reg[3],reg[0]
82 mov reg[0], reg[3]
86 mov reg[1], 40
90 cmp reg[0], reg[1]
91 je 95 
93 jmp 0 
95 mov reg[3], 0
99 pop reg[1]
101 mov reg[2], 150
105 add reg[2],reg[3]
109 mov reg[0], input[reg[2]]
113 cmp reg[0], reg[1]
114 jne 136 
116 mov reg[0], 1
120 add reg[3],reg[0]
124 mov reg[0], reg[3]
128 mov reg[1], 40
132 cmp reg[0], reg[1]
133 jne 99 

分析后大概就是这样
在这里插入图片描述

  • a1 是 input[50 + i]
  • a2 是 input[100 + i]
  • a3 是 input[150 + i]

就是,取 input[50 + i]开始的值 和我们输入的flag 相加,然后和input[100+i]的值异或 。将异或后的值再做俩个移位处理相加起来,得到的值等于 input[150+i]的值。

将值都取出来,写个exp

exp

python">a1 = [155, 168, 2, 188, 172, 156, 206, 250, 2, 185, 255, 58, 116, 72, 25, 105, 232, 3, 203, 201,
      255, 252, 128, 214, 141, 215, 114, 0, 167, 29, 61, 153, 136, 153, 191, 232, 150, 46, 93, 87]
a2 = [201, 169, 189, 139, 23, 194, 110, 248, 245, 110, 99, 99, 213, 70, 93, 22, 152, 56, 48, 115, 56,
      193, 94, 237, 176, 41, 90, 24, 64, 167, 253, 10, 30, 120, 139, 98, 219, 15, 143, 156]
a3 = [18432, 61696, 16384, 8448, 13569, 25600, 30721, 63744, 6145, 20992, 9472, 23809, 18176, 64768, 26881, 23552,
      44801, 45568, 60417,
      20993, 20225, 6657, 20480, 34049, 52480, 8960, 63488, 3072, 52992, 15617, 17665, 33280, 53761, 10497, 54529, 1537,
      41473, 56832, 42497, 51713]
a4 = a3[::-1]
# a4 = [51713, 42497, 56832, 41473, 1537, 54529, 10497, 53761, 33280, 17665, 15617, 52992, 3072, 63488, 8960, 52480, 34049, 20480, 6657, 20225, 20993, 60417, 45568, 44801, 23552, 26881, 64768, 18176, 23809, 9472, 20992, 6145, 63744, 30721, 25600, 13569, 8448, 16384, 61696, 18432]
flag = [0] * 40
for i in range(40):
    flag[i] = ((a4[i] >> 8) & 0xff + (a4[i] << 8))
    flag[i] ^= a2[i]
    flag[i] -= a1[i]
print("".join([chr(a&0xff) for a in flag]))

# hgame{y0ur_rever5e_sk1ll_i5_very_g0od!!}

http://www.niftyadmin.cn/n/5144165.html

相关文章

山西电力市场日前价格预测【2023-11-03】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-03&#xff09;山西电力市场全天平均日前电价为277.41元/MWh。其中&#xff0c;最高日前电价为355.83元/MWh&#xff0c;预计出现在18:15。最低日前电价为0.00元/MWh&#xff0c;预计出…

Linux 之搭建 arm 的 qemu 模拟器

目录 1. Linux 之搭建 arm 的 qemu 模拟器 1. Linux 之搭建 arm 的 qemu 模拟器 OS: kali 1. 安装交叉编译工具、GDB 和 QEMU # sudo apt-get install qemu debootstrap qemu-user-static # sudo apt-get install qemu-system-arm # sudo apt-get install gdb-multiarch //支持…

Spring AOP基于XML方式笔记整理

XML AOP 加载流程 ClassPathXmlApplicationContext#refreshAbstractApplicationContext#obtainFreshBeanFactoryAbstractRefreshableApplicationContext#refreshBeanFactory创建DefaultListableBeanFactoryAbstractApplicationContext#loadBeanDefinitions(beanFactory)创建Xm…

TODOTODOTODOTODOTODOTODOTODOTODO

TODOTODOTODOTODOTODOTODOTODOTODO

ORAM文献笔记

Deterministic, stash-free write-only oram Roche D S, Aviv A, Choi S G, et al. Deterministic, stash-free write-only oram[C]//Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security. ACM, 2017: 507-521. 确定性的、无堆栈的只写O…

分布式ID系统设计(3)

分布式ID系统设计第三集 id-service-SnowFlake方案 第二集说了id-service-Segment-DB可以生成趋势递增的ID,但是ID号是可以计算的。不太适用于一些订单ID生成的场景。因为存在数据暴露的风险 比如我可以对比两天的订单ID号来大致计算出公司一天的订单量。这个有点危险。 所以…

C++11 auto限制

限制&#xff1a; auto 不能用于函数参数auto 不能用于非静态成员变量auto 无法定义数组auto 无法推导出模板参数 推荐一个零声学院项目课&#xff0c;个人觉得老师讲得不错&#xff0c;分享给大家&#xff1a; 零声白金学习卡&#xff08;含基础架构/高性能存储/golang云原生…

【Unity】【VR开发疑难】Unity运行就报无法启动XR Plugin

【现象】 连接Link后运行Unity的VR项目Link也无反映&#xff0c;Unity控制台报&#xff1a;无法启动XR Plugin&#xff0c;并说是由于Oculus头盔未连接导致。 【分析】 打开Oculus PC客户端&#xff0c;发现状态是连接正常。重启机器后&#xff0c;提示Oculus没有出于RunTim…