吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7503|回复: 18
收起左侧

[.NET逆向] 基于JIT定位.Net软件的代码位置

  [复制链接]
吾爱破解1111 发表于 2021-2-18 23:03
本帖最后由 吾爱破解1111 于 2021-2-18 23:26 编辑

QQ图片20210218232454.png
## 普通的程序定位
界面如下
Image.png
代码如下图
Image [1].png
### VS中调试
在按钮点击事件处下断调试,查看堆栈
此时可以知道Button点击消息的传递过程
Image [2].png
堆栈如下
System.Windows.Forms.dll!System.Windows.Forms.Control.OnClick(System.EventArgs e)
System.Windows.Forms.dll!System.Windows.Forms.Button.OnClick(System.EventArgs e)
同时进去查看MessageBox.Show的代码定义
可以看到来自于System.Windows.Forms的MessageBox类
Image [3].png
此时针对该程序将有两种定位

### 通过按钮消息定位
首先找到System.Windows.Forms模块
Image [4].png
之后一层层往下找找到Button类的OnClick方法
Image [5].png
之后下断调试将会断下,调试时进入base.Onclick内
此时来到Control类的OnClick方法,继续步入到eventHandle函数内
Image [6].png
此时将来到我们自己写的函数了
Image [7].png
### 通过信息框定位
信息框可以去对应的类定位,同上,此处不赘述。
也可以使用"F12断点法"定位
弹出信息框以后,点击暂停,之后查看堆栈
Image [8].png
第三个就是我们写的函数,直接转过去即可
Image [9].png

## 通过JIT定位
### 前期铺垫
.Net的程序执行时每个方法需要经过JIT编译,且仅编译一次
可以理解成最初是下面的,均指向JIT内
| 函数  |地址  |
| --- ---| --- |
| 函数1 |JIT  |
| 函数2 | JIT |
函数1执行JIT,之后经过JIT编译成本地代码执行,同时表格内地址变更如下
| 函数   |地址  |
| --- ----| --- |
| 函数1 |0xXXXXXXXX|
| 函数2 | JIT |
后续函数1执行的时候就不经过JIT了,直接调用本地代码,IL代码也不需要二次JIT编译了

### 查看JIT代码
CLRJIT继承自ICorJitCompile
注意是stdcall调用约定,关注第二个参数与第四个参数第五个参数
Image [10].png
ICorJitCompile内如下,注意四个函数都是虚函数
Image [11].png

### 使用X64dbg调试
首先运行程序,先不要点击按钮,防止JIT编译
查看clrjit.dll,下载符号(**后面有不下载符号的方法**)
直接搜索compilemethod,下断。点击按钮将会断下
Image [12].png
如下图,因为是stdcall,所以堆栈中第三个参数CORINFO_METHOD_INFO*
第五个参数是返回的本地代码的二级指针
Image [13].png
查看该结构体定义,第三个参数执行了IL代码,第四个参数是IL代码的长度
Image [14].png
此时复制对应长度的ILCode的代码使用解码工具解码如下
Image [15].png
对比dnspy中显示的代码,确定了是按钮单击事件的
Image [16].png
#### clrjit模块无符号定位CompileMethod地址
因有些网络环境无法下载符号或有些公司不能连接外网(😭)

clrjit模块导出函数如下,没有符号的时候如何定位CompileMethod
Image [17].png
代码中查看getJit定义发现返回了ICorJitCompiler*
Image [18].png
查看getJit代码
Image [19].png
0x71373420存储ICorJitCompiler*
Image [20].png
0x7136A3FC存储ICorJitCompiler* 的虚表指针
Image [21].png
第一个函数就是CompileMethod的函数指针
Image [22].png
如果该地址被HOOK了,没有符号的时候可以下dll断点,这样dll刚加载就断下了,之后在getJit下断,可以提前知道CompileMethod的地址,防止启动后没符号不好找了
Image [23].png

## 基于JIT地址定位代码位置
场景:
有些软件很大,关注的功能不在按钮下。无法通过字符串,按钮消息,或者操作文件等"API"等直接定位代码。或者定位比较麻烦

使用条件,软件启动后该功能首次使用,被JIT后就不行了

由于被编译所以会提供IL代码,此时我们把IL代码复制出来去主模块搜索
Image [24].png
定位到位置了
Image [25].png
0x40206A该地址处有该段IL代码
模块基址是0x400000,RVA是0x206A
用CFF打开程序,可以发现button1_Click的RVA是2069,看起来差1字节
Image [26].png

.Net的方法体的前面有个方法头,分为tiny和fat,tiny是代码少于64字节,没有异常处理表,堆栈深度小于8的时候是tiny,tiny是方法体前面有一字节,所以该例子中相差一个字节。一般都是fat,fat前面多12字节

### 自动查找方法位置
上述Method中只有几个,所以知道是button1_Click方法

借助于Dnlib遍历所有的方法
[C#] 纯文本查看 复制代码
var filename = "Csharp.exe";
int RVA = 0x206A;
var mod = ModuleDefMD.Load(filename);

foreach (var type in mod.GetTypes()) 
{

        foreach (var method in type.Methods) 
        {
                if ((int)method.RVA + 1 == RVA || (int)method.RVA + 12 == RVA)
                {
                        Console.WriteLine("Type:{0}", type.FullName);
                        if (type.BaseType != null) 
                        {
                                Console.WriteLine("  Base type :{0}", type.BaseType.FullName);
                        }
                        Console.WriteLine(method.Name);
                }
        }
}

可以直接得到方法的名字与类,可以快速定位到代码
Image [27].png
### 全自动化
可以写X64dbg插件,Hook CompileMethod,之后获取到IL代码,进行特征查找,找到后通过dnlib代码输出函数地址和方法名

## 实战论坛的一个DNG软件爆破
软件地址
https://www.52pojie.cn/forum.php?mod=viewthread&tid=952601&highlight=dng

该软件有弹出信息框可以作为突破口,此处以JIT处入手进行演示
X64dbg调试
Image [28].png
通过getjit方法查看CompileMethod函数地址
Image [29].png
发现CompileMethod被Hook了,所以没有符号时需要用上述方法提前知道地址
此处做爆破所以需要找到本地代码的地址
留意返回地址这个参数
Image [30].png
之后转过去打个断点
Image [31].png
如下有个跳转,根据call的地址符号名判断是这里
Image [32].png
修改跳转后爆破
Image [33].png

### 关于自动化
这类软件有些只是简单的判断,跳过了跳转就爆破
1. 可以写dll导入表注入,HOOK 真实的CompileMethod,判断IL代码是这个函数的IL代码时,获取出返回的本地代码位置,之后根据偏移之类的动态修改机器码达到爆破目的
2. 将这个函数的本地代码做个特征码,每次打开软件先执行一次,提示错误后,此时代码已经Jit,根据特征码定位到位置,修改机器码破解,每次都需要点击两次才能进入,比较麻烦
基于JIT定位.Net软件的代码位置.zip (1.98 MB, 下载次数: 225)


免费评分

参与人数 14吾爱币 +16 热心值 +14 收起 理由
BestTime + 1 + 1 谢谢@Thanks!
PuddingKC + 1 + 1 热心回复!
andywu + 1 + 1 谢谢@Thanks!
langzi + 1 + 1 谢谢@Thanks!
jgs + 1 + 1 谢谢@Thanks!
qzhsjz + 2 + 1 用心讨论,共获提升!
zycode + 1 + 1 谢谢@Thanks!
无闻无问 + 2 + 1 谢谢@Thanks!
wekabc + 1 + 1 谢谢@Thanks!
jy04468108 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
FatPigs + 1 + 1 谢谢@Thanks!
a1100330 + 1 + 1 谢谢@Thanks!
Ravey + 1 + 1 谢谢@Thanks!
romobin + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

无闻无问 发表于 2021-2-19 15:26
本帖最后由 无闻无问 于 2021-2-19 15:34 编辑

暂停,回溯,即可解决…不过,原理性的爆破还是牛逼…

所以compilemethod为万能断点…加解密二者争夺之处…
romobin 发表于 2021-2-19 02:44
lyghost 发表于 2021-2-19 07:40
lx771602764 发表于 2021-2-19 07:42
学习到了
无闻无问 发表于 2021-2-19 08:10
lyghost 发表于 2021-2-19 07:40
为啥不直接用dnspy?

加壳的你用dnspy毛都看不到…
张海洋 发表于 2021-2-19 08:34
看起来好高端的亚子
羽刃 发表于 2021-2-19 11:30

好教程 非常感谢 学习了
woaipujie 发表于 2021-2-19 19:48
谢谢分享,学习到了。
whyou126 发表于 2021-2-19 22:57
感谢大佬分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 12:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表