.Net JIT二进制骚操DHVM破解篇

news2024/10/7 18:25:43

前言

经研究,号称最强.Net加密软件DNGuard HVM(以下简称DHVM),五行代码基本上可以优雅的破解它,本篇看下。友情提示,以下全是二进制汇编骚操,慎入。原文:.Net JIT二进制骚操DHVM破解篇

概括

示例:

非常简单的示例

static void ABC()
{
   Console.WriteLine("Call ABC");
}
static void DEF()
{
   Console.WriteLine("Call DEF");
}
static void Main(string[] args)
{
   Console.WriteLine("Call Main");
   ABC();
   DEF();
   Console.ReadLine();
}

修改调用ABC函数的逻辑为调用DEF函数,Main函数的MSIL二进制代码如下:

00 72 25 00 00 70 28 0e 00 00 0a 00 28 06 00 00 06 00 28 07 00 00 06 00 28 0f 00 00 0a 26 2a

这里的MSIL二进制代码可以参考:罕见的技术:MSIL的机器码简析

1.难点
因为Hook JIT,简单的MSIL修改已经不起作用。DHVM的各种反调试,比如VS调试器无法进入某些内存地址。一进入就会报异常。它静态地址在运行的时候动态偏移,它进行了PE的IAT(导入表)的Name字段验证,当IAT的Name不为0的时候,就会报异常等。这些东西叠加在一起,无法调试,无法通过输入表注入DLL等。

2.蛛丝马迹
避开这些反调试手段,魔高一尺道高一丈嘛,蛛丝马迹即是破绽。
当我们通过一些可以调试的地址进入发现一些有趣的东西,比如以下代码:

0000000180497AB2: E9 A1 73 00 00 jmp  0000000180497AB8
0000000180497AB7: F8             clc
0000000180497AB8: 4C 89 5F 10    mov  qword ptr [rdi+10h],r11

这一段汇编代码是关键点,它通过jmp指令跳到地址0000000180497AB8。然后执行指令

mov  qword ptr [rdi+10h],r11

这里的r11寄存器保存的是通过DHVM加密后的托管DLL的真实的MSIL二进制代码。rdi寄存器是DHVM Hook的JIT的函数invokeCompileMethod的参数methodInfo地址,rdi+0x10即是methodInfo的成员变量IL_Code地址。这个IL_Code里面的值会被JIT编译器编译成机器码,然后运行。

那么这段指令的意思很明显,也就是说把DHVM加密后把保存的托管DLL的真实MSIL二进制代码赋值给IL_Code。它这么做的目的就是屏蔽掉原有托管DLL里面的MSIL,而用DHVM自己加密之后保存的MSIL。无论你怎么修改原有的托管DLL,都不会影响JIT的执行。

3.预破
既然探查到了以上蛛丝马迹,下面着手解决掉DHVM。这里的思路是,因为jmp是个跳转指令,所以可以让它跳转到自己的地址。这个自己的地址因为无法通过IAT注入DLL构建,上面说了DHVM会搜寻IAT的Name字段是否为0。因为Win11超强的PatchGuard,所以这里不考虑DLL注入了。直接在HVMRun64.dll内部构建。通过dumpbin,把HVMRun64.dll的汇编代码导出到记事本。HVMRun64.dll的最后的汇编地址如下:

000000018049EE53: 00 74 56 01  add byte ptr [rsi+rdx*2+1],dh
000000018049EE57: 00

它这个地址对应的是把HVMRun64二进制的地址如下:

00499253:00 74 56 01 00

从00499258地址开始后面全都是0,类似如下:

00499258:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
          00 00 00 00 00 00 00 00 00

可以从这里为零的数据开始构建。在构建数据之前还需要做一件事情,我们上面蛛丝马迹里面jmp指令

0000000180497AB2: E9 A1 01 00 00 jmp  0000000180497AB8

需要让它跳转到00499258这个地址来,然后在这个为零地址里面做自己想要做的事情。如何跳转呢?可以把jmp地址改成如下:

//jmp跳转地址减去jmp所在地址减去5等E9后面的数值,E9是jmp机器码
0000000180497AB2: E9 A1 73 00 00  jmp  000000018049EE58

这里的000000018049EE58地址指向的即是00499258所在全部是零的地址处。当它跳转到0区之后如下代码:

首先在00499258地址处写入二进制代码:4D 89 DF,
这三个十六进制代表的汇编是mov  r15,r11,上面说了r11
保存的是MSIL需要编译的二进制代码,通过跟踪发现如果
直接更改r11寄存器,则会导致异常。跟踪也发现r15寄存器
为零,所以这里把r11赋值给r15。然后把蛛丝马迹里面的代码

0000000180497AB8: 4C 89 5F 10    mov  qword ptr [rdi+10h],r11
也就是这里的r11替换成r15,让它称为最后编译的MSIL

我们需要做的就是在r15里面修改MSIL二进制即可。

如何把r11替换成r15呢?看它的代码:

0000000180497AB8: 4C 89 5F 10  mov  qword ptr [rdi+10h],r11

修改成如下:

0000000180497AB8 4C 89 7F 10   mov  qword ptr [rdi+10h],r15 

把机器码5F改成7F即可。以上所有准备好了,我们开始替换MSIL代码,也即是r15寄存器修改。

4.破解
上面把十六进制的4D 89 DF写入了00499258地址,也即是000000018049EE58所指向的地址。

因为4D89DF

占3个字节,所以下面的地址

0x000000018049EE58+0x3==000000018049EE5B.

000000018049EE5B这个地址写入如下:

0049925B:49 C6 47 0D 07
转换成汇编也即是如下:
000000018049EE5B 49 C6 47 0D 07  mov ptr byte [r15+D],07

这里是把07这个数值赋值给r15偏移的0xD的位置处。这里修改r15偏移的0xD位置的数值,实际上是把示例里面的调用的ABC函数修改成调用DEF函数,也就是改变函数逻辑。示例的结果是:

Call Main
Call ABC
Call DEF

我们通过hook DHVM之后的结果是

Call Main
Call DEF
Call DEF

示例里面的MSIL二进制代码是:

00 72 25 00 00 70 28 0e 00 00 0a 00 28 06 00 00 06 00 28 07 00 00 06

调用ABC函数的MSIL二进制代码是:

28 06 00 00 06

调用DEF函数的二进制代码是:

28 07 00 00 06

可以看到ABC和DEF函数的MSIL二进制代码,只是基本上相同,上面偏移的0x1的位置一个是06,一个是07。如果想要把调用ABC改成调用DEF,这里只需要把06改成07即可,也就是这段汇编代码的意义

000000018049EE5B 49 C6 47 0D 07  mov ptr byte [r15+D],07

这里改了之后,还得跳回去,因为上面的汇编占了五个字节,所以这里下一个地址是:

0x000000018049EE5B+0x5==0x000000018049EE60

在地址0x000000018049EE60里面跳转到原来的jmp需要跳转的地址也即是

00499260:E9 53 8C FF FF
000000018049EE60 E9 53 8C FF FF jmp 0000000180497AB8

这样就完成了整个闭环的操作,在Hook DHVM里面这里只是简单的修改了一个字节数值,当然可以修改更多以满足自己的需求。

本篇用的是:.Net JIT的骚操作DNGuard HVM原理简析。里面提到的第二种方法也即是破二。第一种方法也可,而且能够做的更多。但是规模和成本上去了。个人比较喜欢简洁,所以选择了第二种。

5.整体
那么整体的代码是:

DHVM跳转代码和r11替换成r15
0000000180497AB2: E9 A1 73 00 00  jmp  000000018049EE58
0000000180497AB8 4C 89 7F 10      mov  qword ptr [rdi+10h],r15

hook代码:
000000018049EE58 4D 89 DF        mov   r15,r11
000000018049EE5B 49 C6 47 0D 07  mov   ptr byte [r15+D],07
000000018049EE60 E9 53 8C FF FF  jmp   0000000180497AB8

可以看到,真正的代码,也就那么几行。甚至只修改一个字节即可,所谓返璞归真,即是这个道理。

以上DHVM的整体过程,仅用于学习用途。

结尾

作者:江湖评谈,公众号:(jianghupt),欢迎关注,一起学习好玩的技术。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt打包工具windeployqt自动打包exe程序

Qt打包工具windeployqt自动打包exe程序 一、Qt打包工具windeployqt自动打包exe程序1.问题所在2. 如何使用3. 注意点3.1 第一点3.2 第二点3.3 更直接的解决方法(不是最优的办法,但是方便好用) 二、应用程序的发布 一、Qt打包工具windeployqt自…

Android 之 Compose 开发基础

1、中文官网地址: https://developer.android.google.cn/courses/android-basics-compose/course?hlzh-cn 2、首个Android应用 2、构建应用界面

2023年9月软考中级系统集成项目管理工程师报名来这里

系统集成项目管理工程师是全国计算机技术与软件专业技术资格(水平)考试(简称软考)项目之一,是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试,既属于国家职业资格考试,又是职…

正点原子逻辑分析仪DL16

最近购买了正点原子的逻辑分析仪,现在记录下此逻辑分析仪的用法。 逻辑分析仪不到半个巴掌大小。 安装下上位机软件,一路点击是即可。 用zadig安装下ATK-Logic的驱动。 安装完驱动后,此时将逻辑分析仪插上电脑后,指示灯变为绿色…

SpringBoot2.0(过滤器,监听器,拦截器)

目录 一,过滤器1.1,自定义Filter1.2,启动类代码1.2,创建filter类和LoginFilter包1.2.1,编写loginFilter类 过滤器代码1.2.2,创建二个Controller类 二,监听器2.1,自定义监听器2.2&…

基于虚拟仿真技术的汽车燃油泵控制

在当前激烈的竞争环境下,汽车行业正在加速产业和技术更迭,整车厂对大型ECU嵌入式控制系统和软件的需求迫在眉睫。 然而,复杂而庞大的汽车系统往往由多个物理系统组成,系统所对应的模型都需要在不同的领域实现:发动机、…

Leetcode算法入门与数组丨1. 数据结构与算法简介

文章目录 前言1 数据结构与算法1.1 数据结构1.2 算法 2 算法复杂度2.1 算法复杂度简介2.2 时间复杂度2.3 空间复杂度 3 总结 前言 Datawhale组队学习丨9月Leetcode算法入门与数组丨打卡笔记 这篇博客以及接下来几篇将会是一个 入门型 的文章,主要是自己学习的一个…

Leaflet入门,原生html网页如何使用Leaflet地图

前言 本章讲解如何不使用vue或react的情况下,在原生html网页中使用Leaflet地图加载地图的功能。 以高德地图xyz瓦片地图为例。 示例演示效果 vue如何使用Leaflet vue2如何使用:《Leaflet入门,如何使用vue2-leaflet实现vue2双向绑定式的使用Leaflet地图,以及初始化后拿到…

【直接运行TS文件的三种方法】

直接运行TS文件的三种方法 文章目录 直接运行TS文件的三种方法法一:将 ts 编译成 js,然后运行 js 文件法二:用 ts-node 直接运行 ts法三:webstorm中直接运行ts(TypeScript) 法一:将 ts 编译成 js,然后运行 …

SpringBoot项目--电脑商城【显示购物车列表】

1.持久层 1.1规划需要执行的SQL语句 这里需要将商品表和购物车表进行连表查询 显示某用户的购物车列表数据的SQL语句大致是 多表查询如果字段不重复则不需要显示的表面表名 selectcid, #日后勾选购物车商品模块需要用到cid来确定勾选的是购物车表的哪一条数据uid, #感觉没必要…

教你如何利用人工智能技术提升气象、海洋、水文领域工作学习效率

查看原文>>>基于Python机器学习、深度学习提升气象、海洋、水文领域实践应用能力 Python是功能强大、免费、开源,实现面向对象的编程语言,能够在不同操作系统和平台使用,简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库…

小程序 navigateBack 携带参数返回的三种方式(详细)

如果觉着主图好看,点个赞,你早晚也会看到这么好看的景色! 第一种方式 getCurrentPages 获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。不要尝试修改页面栈,会导致路由以及页面状态错误。不要在 App.onLaunch 的时候调用 getCurrentPages(),此时 page …

选择什么电容笔比较好?主动式电容笔推荐

随着科学技术的飞速发展,越来越多人把纸质转换为电子版了,许多小伙伴会入手电容笔来提高自己的生产效率。无论是写作还是绘画。都在使用电容笔。apple pencil的昂贵众所周知,而现在线上的电容笔多得让我们眼花缭乱,再从众多品牌中…

测试平台部署三——Nginx

测试平台部署——Nginx 一、nginx部署1、nginx的作用:2、案例1二、django静态文件配置和部署1、nginx工作原理2、反向代理一、nginx部署 1、nginx的作用: 静态文件服务器和反向代理django服务 进入nginx容器中 sudo docker run --rm -it nginx:alpine /bin/sh

VPN都容易受到泄露流量的TunnelCrack攻击

导读研究人员近日发现,影响市面上大多数VPN产品的几个漏洞可以被攻击者用来读取用户流量、窃取用户信息,甚至攻击用户设备。 我们实施的攻击从计算上来说开销并不大,这意味着任何拥有适当网络访问权限的人都可以执行攻击,而且攻击…

Seekbar细节

Seekbar可以自定义thumb图标,但是有时候发现thumb没有展示完全,或者图标周围显示的是背景色,此时就需要设置一些属性 android:background"null" android:thumbOffset"0dp" android:splitTrack"false" 设置an…

WSL Ubuntu设置中文语言环境

问题现象:终端、Edge、VScode等软件乱码 在这里插入图片描述 解决方法 ① 安装中文语言包 sudo apt-get install language-pack-zh-han*② 运行语言支持检查 sudo apt install $(check-language-support)③ 修改相关配置文件 sudo gedit /etc/default/locale替…

2023年9月DAMA-CDGA/CDGP数据治理认证报名到这错不了

DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业…

如何利用Python中实现高效的网络爬虫

各位大佬们!今天我要和大家分享一个有关Python的技巧,让你轻松实现高效的网络爬虫!网络爬虫是在互联网时代数据获取的一项关键技能,而Python作为一门强大的编程语言,为我们提供了许多方便而高效的工具和库。让我们一起…

XSC63-300-S-CB、XSC80-400-S-CA、XSC100-700-S-LB方型气缸

XQVB40-16、XQ-VB63-16、XQ-VB100-16倍压增压阀 QCK2400、QCK2400A、QCK2422、QCK2422A磁性开关 AL-07R、AL-30R、KT-50R、AL-03R、AL-20R、AL-72R磁性开关 XSC32-40-S-LB、XSC40-100-S-FA、XSC50-200-S-FB、XSC63-300-S-CB、XSC80-400-S-CA、XSC100-700-S-LB方型气缸 QSC3…