[hgame 2023]vm

news/2024/12/24 11:35:19/文章来源:https://www.cnblogs.com/connu/p/18531328

--这是我的第一个博客--如有错误希望大佬能指出---

 

进来之后看到第8行和第12行有不知道的函数,分别是sub_140001000,sub_1400010B0。

进入第8行的sub_140001000看看。

 

再进入sub_140001060。

 

会发现初始化了一些以a1为基地址的数据。

vm逆向,即虚拟机逆向。这里的虚拟机类似java虚拟机,python虚拟机,能够解释一系列自研的指令。

而这里对a1的初始化,很可能是对自研的指令系统的寄存器初始化。

建一个结构体方便下面的分析。

 

在Structure窗口右键,点击add struct type或者按快捷键insert可以新建一个结构体。

我命名为了VM。

 

在ends处点击d可以新建结构体成员。

根据上上上个图,会发现也许可以这样建结构体。

 

不过这个题有提示怎么建结构体。

 

右键想转为结构体的变量可以转为指定结构体,这里转a1。

 

会发现这个函数需要返回0才算成功。

然后进入这个函数看看。

 

这也是a1,把它转成结构体。

 

会发现如果这个数组指定下标的值如果不是255,就执行下面的函数。返回值是zzz。那么zzz必须是0。

byte_140005360数组里也许就是这道题的加密过程的指令了。进入sub_140001940函数看看。

 

又有a1,把a1转成结构体。

 

看到很多case。这个数组也是上面说到的数组,进去看看。

 

果然是一堆。那么可以把数组重命名为opcode。

回到之前的函数,每个case下面的函数就是根据不同指令 [opcode数组] 做出的不同处理。

并且数组的下标是结构体a1的成员xxx,那么xxx就是指令寄存器ip。

把每个case里面的函数的a1都转成结构体。

 

进入case 0,发现根据opcode的ip的下一个数据执行不同赋值操作。

如果在main函数里重命名了,会发现数组dword_140005040就是存放用户输入的flag的数组。

下面是重命名后的。

 

会发现里面涉及到opcode[ip~ip+3],一共4字节的数据。函数的后面ip也进行了+4。

 

看外层函数的case 1,会发现把寄存器的值复制到了一个什么数组。

 

再看外层函数的case 2,把同样的数组的值赋给寄存器。

这个函数代表内存区域的那部分呢?我们会发现yyy进行了自增自减。可以猜测是栈。而yyy代表sp。

那么这两个函数分别是入栈和出栈。

 

看这个函数,会发现是一些有关寄存器的运算。

 

在这个函数,会发现zzz代表reg[0]和reg[1]相不相等。相等则是0。相当于汇编语言的cmp,比较之后给zzz赋值。

 

这个函数相当于jmp ip+1即jmp opcode[ip+1]。

 

这个函数即je opcode[ip+1]。

 

这个函数即jne opcode[ip+1]。

 

下面是我的代码。

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]
ip = 0
while opcode[ip] != 255:print(f"{str(ip)+':':<8}",end='')match opcode[ip]:case 0:match opcode[ip+1]:case 0:print("mov    reg[0] input[reg[2]]")case 1:print("mov    input[reg[2]] reg[0]")case 2:print(f"mov    reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 3:print(f"mov    reg[{opcode[ip+2]}] {opcode[ip+3]}")ip+=4case 1:match opcode[ip+1]:case 0:print("push   reg[0]")case 1:print("push   reg[0]")case 2:print("push   reg[2]")case 3:print("push   reg[3]")ip+=2case 2:match opcode[ip+1]:case 0:print("pop    reg[0]")case 1:print("pop    reg[1]")case 2:print("pop    reg[2]")case 3:print("pop    reg[3]")ip+=2case 3:match opcode[ip+1]:case 0:print(f"add    reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 1:print(f"sub    reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 2:print(f"mul    reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 3:print(f"xor    reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 4:print(f"shl    reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")# print(f"        and    reg[{opcode[ip+2]}] 0xFF00")case 5:print(f"shr    reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")ip+=4case 4:print("cmp    reg[0] reg[1]")ip+=1case 5:print(f"jmp    {opcode[ip+1]}")ip+=2case 6:print(f"je     {opcode[ip+1]}")ip+=2case 7:print(f"jne    {opcode[ip+1]}")ip+=2

 

下面是得出的结果。

伪汇编代码
 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]and    reg[1] 0xFF00
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

然后不会了呢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/827967.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【windows应用】命令行禁用、启用Windows系统代理

原创 hyang0 生有可恋Windows 系统代理可以通过窗口鼠标点击开关进行配置,当需要频繁切换代理和非代理状态时命令行操作会更方便。系统代理是通过注册表进行控制的,可以通过操作注册表项来控制系统代理的禁用或启用: # 禁用: reg add "HKEY_CURRENT_USER\SOFTWARE\Mic…

【红队】dump RDP凭据

免责声明: 由于传播、利用本公众号文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责管理员通常使用远程桌面协议 (RDP) 来远程管理 Windows 环境。在充当跳板机以使用户能够访问其他网络的系统中启用它也是典型的 RDP。然而,虽然这个协议在大多数…

【免杀】DLL 侧载

一、什么是 DLL?二、什么是 DLL 劫持?三、DLL 路径搜索顺序四、DLL 劫持原理五、DLL Sideloading六、什么是 DLL 代理?七、执行 DLL 代理八、武器化 DLL 代理案例1:Teams案例2:Obsidian九、结论原创 独眼情报哎,犯病了,又整这种没人看的技术长文!但是看到很好的技术文章…

【web应用】中间件汇总

原创 boo 学而嘉一、HTTP服务 1.Apache HTTP Server主要用于静态内容服务 最新版本 2.4.592.Nginx主要用于静态内容服务和代理服务器 最新版本1.26.2主要功能: 1.HTTP 服务器(动静分离)nginx + tomcat中,可以将动态资源交给tomcat,而静态资源则交给Nginx,这样可以减轻tom…

c++中的try-catch及throw

C++ 使用 try-catch 语句来捕获和处理异常。try 块包含可能发生错误的代码,而 catch 块则用来捕获并处理错误。 try-catch 语句的基本结构 try {// 可能抛出异常的代码 } catch (exception_type1 e1) {// 处理异常类型 1 } catch (exception_type2 e2) {// 处理异常类型 2 } c…

【windows应用】windows系统怎么查看密钥

原创 L.w IT小农工大家都知道,安装Win10/11系统之后需要密钥才能使用所有的功能,网上提供的激活方法有很多,那我们要怎么知道自己的密钥呢? Windows 产品密钥是由 25 个字符组成的代码,用于激活 Windows。其格式如下所示: 产品密钥:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX 操作过…

【 js编程】原型和原型链

原创 mike Web全栈开发者驿站原型和原型链在 js中起着至关重要的作用。它们使得 js 能够以一种独特的方式实现面向对象编程,虽然与传统的面向对象编程语言有所不同,但却提供了很大的灵活性和强大的功能。然而,原型链也有一些缺点,如属性查找的性能问题、继承的脆弱性以及隐…

全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML\YAML\JSON格式这种序列化Web对象。这种序列化Web对象容易与其他程序设计语言交互,可读性强,容易被传递给其它系统或客户端。全网最适合入门的面向对象编程教程:58 Python 字符串与序列化-序…

开源低代码平台-Microi吾码-源码本地运行-后端

开源低代码平台-Microi吾码-简介技术框架:.NET8 + Redis + MySql/SqlServer/Oracle + Vue2/3 + Element-UI/Element-Plus 平台始于2014年(基于Avalon.js),2018年使用Vue重构,于2024年10月29日开源 试用地址:https://microi.net Gitee开源地址:https://gitee.com/ITdos/m…

CAPL基础

CAPL基础 1.CAPL如何生效 CAPL通过在Simulation Setup窗口设置CAPL节点,并加载对应的CAPL文件使CAPL生效。 2.Event驱动 CAPL语言的运行逻辑是事件触发,当满足条件时执行对应的代码 如下图所示有启动触发、停止触发、发送报文触发、定时器触发和按键触发等3.报文发送 1.自定义…

开源 - Ideal库 - 常用时间转换扩展方法(一)

分享《开源-Ideal库》系列文章,含公共、文档等库封装,首篇介绍时间转换封装,包括日期时间、时间戳与字符串间转换方法,后续上传至Nuget,测试代码已上传至代码库。从事软件开发这么多年,平时也积累了一些方便自己快速开发的帮助类,一直在想着以什么方式分享出来,因此有了…

excel排序

目录Excel成绩排名的两种方法方法一:先排序,再填排名 Excel成绩排名的两种方法 方法一:先排序,再填排名 具体步骤如下:先左键选中要排序的区域,如下图右键,然后选择排序->自定义排序选择要排序的区域(注意勾选数据包含标题)​ 数据包含标题的意思就是,上面的姓名、…