瑞数vmp-代码格式化后无法正常运行原因分析

在逆向开发过程中,我们常常会修改网页源码来调试和跟踪数据流与运行流,那么首先要做的就是将源码格式化,但是当我们逆向瑞数加密的网站时,如果直接格式化源码,运行后就会陷入无限循环,代码不格式化非常影响我们做逆向工作,那么这里博主分析下原因即处理这个无法格式化的问题。

我们找到一个瑞数加密的网站,并获得入口js文件

然后使用浏览器替换,重新打开网站,程序进入无限循环,页面无法显示出来。

静态代码格式化

源码分析

通过比对动态生成的代码,可以确定格式化与否生成的动态代码一致。

既然动态代码一致,那是不是与window.$_ts变量有关呢,通过对比发现如果格式化后window.$_ts.jf的值是true,如果改成false则无限循环问题不会出现,因此可以确认代码格式化后无法运行的原因就是window.$_ts.jf的值导致的。

定位代码

通过插桩方式确认window.$ts.jf的赋值过程,找到正则匹配代码:_$ht.test(_$_q)

其中_$_q的值为"function _$dG(){return'\\x74\\x6f\\x53\\x74\\x72\\x69\\x6e\\x67';}",可以直接在js文件搜索到,搜索字符串:function _$dG(){return'\x74\x6f\x53\x74\x72\x69\x6e\x67';}

_$ht的值为/\S+\(\){\S+['|"].+['|"];}/

如果把源码格式化后_$_q的值为"function _$dG() {\n return '\\x74\\x6f\\x53\\x74\\x72\\x69\\x6e\\x67';\n }"

分析正则串

正则串/\S+\(\){\S+['|"].+['|"];}/的解释如下:

  1. /: 正则表达式的开始。
  2. \S+: 匹配一个或多个非空白字符。这部分表示一个函数名或标识符。
  3. \(: 匹配左括号(
  4. \): 匹配右括号)
  5. {: 匹配左花括号{
  6. \S+: 再次匹配一个或多个非空白字符。这部分可能表示函数体的起始部分。
  7. ['|"]: 匹配一个单引号'或双引号"
  8. .+: 匹配一个或多个任意字符。
  9. ['|"]: 再次匹配一个单引号' 或双引号"
  10. ;: 匹配分号;
  11. }: 匹配右花括号}
  12. /: 正则表达式的结束。

可以看到2和6都是匹配非空白字符,且){中间是没有空格的,因此只要格式化了就肯定过不了这个正则判断。

然后这个正则串可以在代码中找到:_$ht = new RegExp('\x5c\x53\x2b\x5c\x28\x5c\x29\x7b\x5c\x53\x2b\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x7d');'\x5c\x53\x2b\x5c\x28\x5c\x29\x7b\x5c\x53\x2b\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x7d'"\S+\(\){\S+['|"].+['|"];}"的ascii码的16进制显示

分析函数字符

函数字符比较简单,返回的字符串'\x74\x6f\x53\x74\x72\x69\x6e\x67'是16进制的ascii码值,解码后就是字符串toString,或者直接运行_$dG()也会返回toString这个字符串,为啥是这么字符串,博主盲猜应该是为了混淆逆向开发者,因为我们要把函数转换为字符串就可以运行代码$dG[$dG()](),这样看起来确实有点混淆的感觉,不管调试时鼠标滑在变量上或者运行代码返回的值都是一致的,哈哈哈

动态代码格式化

瑞数的核心代码是动态生成的,也是加入了格式化检测,如果做代码分析,代码格式化会减少我们的逆向复杂度,与外层代码格式化检测不同,动态代码格式化检测是检测的入口函数,入口函数长这样(由于代码是动态生成的,因此直接搜索这个方法是搜不到的);

function _$$I() {
  var _$$I, _$ft, _$_0, _$iv, _$j7, _$kb;
  if (_$f1._$gS) _$ft = _$bS._$et(), _$$I = _$bS._$et(), _$ft[1] = _$cR[1], _$ft[3] = _$cR[3];else {
    _$ft = [], _$$I = new _$at(_$f1._$ic), _$ft[1] = _$cR[1].concat([arguments]), _$ft[3] = _$cR[3].concat([_$$I]), _$_0 = _$f1._$j8;
    for (_$iv = 2; _$iv < _$_0.length; _$iv++) _$$I[_$iv] = _$_w(_$_0[_$iv], _$ft);
  }
  _$ft[0] = arguments, _$ft[2] = _$$I, _$$I[0] = this, _$$I[1] = arguments, _$f1._$$j.charCodeAt ? _$f1._$$j = _$eu(_$f1._$$j) : 0, _$bl(_$f1, 0, _$f1._$$j.length, _$ft), _$j7 = _$ft[4], _$kb = _$ft[5], _$f1._$gS ? (_$bS._$gt(_$ft), _$bS._$gt(_$$I)) : 0;
  if (_$j7 === 1) return _$kb;
}

然后通过正则语句/function \S+?\(\){\S+/.test(_$$I.toString())进行匹配,匹配结果为true则正常执行,为false则进入死循环。

这个正则语句匹配的函数代码前部分如:function _$$I(){var...

因此我们只要找到入口函数并将格式化的入口函数的函数头还原就可以通过格式化检测了

总结

最后总结下,对于外部代码,如果要格式化后代码能正常运行,那我们就要在格式化后搜索_$dG方法的代码,将这个方法还原成没有格式化的代码,即function _$dG(){return'\x74\x6f\x53\x74\x72\x69\x6e\x67';}

对于动态代码,首先要找到入口函数,再将入口函数的代码首部改成function 方法名(){代码

两处都修改完后就可以使用格式化后的代码调试开发了,关于格式化代码,中间操作不建议通过复制黏贴方式完成,可能会让二进制数据丢失或者二进制数据并被转化为字符串字面量造成程序运行异常,可以使用babel工具进行处理!

扩展

字符转16进制ascii码:'S'.charCodeAt().toString(16) === '53'

16进制ascii码转字符:String.fromCharCode(parseInt('53', 16)) === 'S'

爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取据并存储,以便后续分析或展示。爬虫通常由搜索引擎、据挖掘工具、监测系统等应用于网络据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标据,如文本、图片、链接等。 据存储: 爬虫将提取的据存储到据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型据库、NoSQL据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。
### VMP 功能、配置与使用方法 VMP(Virtual Machine Protection)是一种虚拟机保护技术,通常用于防止代码被逆向工程或篡改。它通过将关键逻辑封装在虚拟机中运行,使得攻击者难以理解或修改程序的行为。以下是关于 VMP 的功能、配置与使用方法的详细介绍。 #### 功能概述 VMP 的核心功能在于提供高级别的代码保护[^1]。其主要特点包括: - **代码虚拟化**:将敏感代码片段转换为专有的虚拟机指令集,从而避免直接暴露原始代码逻辑。 - **动态混淆**:对代码进行动态变换,每次运行时生成不同的字节码,增加逆向分析的难度[^3]。 - **完整性校验**:检测程序是否被非法修改或注入恶意代码,并在检测到异常时采取防护措施。 #### 配置指南 虽然 sdenv 项目未明确指出具体的配置文件名,但根据开源项目的常见实践, VMP 的配置可能位于以下位置[^1]: - **配置文件路径**:通常在项目的根目录下或特定子目录(如 `config/`),可能命名为 `config.ini` 或 `settings.yaml`。 - **环境变量**:某些情况下,VMP 的行为可以通过环境变量进行调整。例如,设置 `VMP_PROTECTION_LEVEL` 来控制保护强度。 - **默认参**:如果项目未提供预定义的配置文件,用户可以参考 `env_manager.py` 中的默认参来间接理解配置方式。 #### 使用方法 使用 VMP 通常需要以下几个步骤: 1. **安装依赖**:确保安装了必要的库和工具。例如,若项目基于 Python,可以使用 `pip` 安装相关依赖[^2]。 ```bash pip install sdenv ``` 2. **初始化环境**:激活虚拟环境并加载 VMP 模块。 ```python import sdenv sdenv.init_vmp() ``` 3. **配置保护规则**:根据需求自定义保护策略。例如,指定哪些函或模块需要进行虚拟化处理。 ```python vmp_config = { "protection_level": "high", "target_functions": ["process_data", "validate_user"] } sdenv.apply_vmp(vmp_config) ``` #### 注意事项 - **性能影响**:启用 VMP 可能会导致程序运行速度下降,因此需要在安全性与性能之间找到平衡点[^1]。 - **兼容性测试**:在实际部署前,建议对受保护的代码进行全面测试,以确保功能正常[^2]。 ```python # 示例:应用 VMP 并测试性能 import time import sdenv def process_data(): # 模拟据处理逻辑 return "Processed Data" vmp_config = {"protection_level": "medium"} sdenv.apply_vmp(vmp_config) start_time = time.time() result = process_data() end_time = time.time() print(f"Result: {result}, Time taken: {end_time - start_time:.4f} seconds") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值