Ja-netfilter(idea破解)分析
简介
ja-netfilter
是一款可以破解jetbrains
IDE系列的javaagentjar
包。
原理简介
- 通过
javaagent
创造修改字节码的时机。 - 通过
asm
修改相关类,达到hook特定方法的作用。 - 主要依赖power(rsa方法hook),url(拦截网络验证码校验),dns(拦截特定域名请求)插件。
原理分析
首先先简单了解下整理流程,后面详细讲解每个步骤。
正常启动idea流程
- 点击idea快捷方式,或者idea.bat / idea.sh启动。
- 根据环境变量加载对应vm参数。也就是
vmoptions
文件,vm中的内容会作为jvm启动参数添加到启动命令中。 - 本地校验激活码
- rpc接口校验激活码
使用ja-netfilter流程
- 运行install脚本(通过环境变量指定启动vm参数文件地址),也就是jar包目录下的
vmoptions
目录。 - 启动idea。
- 加载ja-netfilter
vm
参数(在ja-netfilter的vm参数中添加了asm支持以及javaagent参数,并指定当前jar包)。 - 运行javaagent,及
ja-netfilter.jar
的permain方法。 1. 加载ja-netfilter定义的插件,也即plugins目录下的jar包。2. 初始化插件,载入配置,也即config目录下的jar包。3. 通过javaagent提供的类转换能力转换插件hook的类。 - 本地校验激活码
- 网络rpc校验激活码
ja-netfilter代码分析
- 我这里直接调试idea,通过idea.bat启动。启动后在通过agent技术嵌入到idea目录虚拟机中,已达到调试idea的目录。
- com.janetfilter.core.Launcher是主启动类,定义了permain已经agentmain方法。同时在
manifest
指定了Premain-Class。
- 使用idea.bat启动idea
- 使用javaagent嵌入到目标虚拟机。
- 进入javaagner(ja-netfiler)定义的permain方法,开始执行ja-netfiler逻辑。
- 确定插件目录以及配置目录
- 加载插件,加载配置并初始化
ja-netfiler插件介绍
- ja-netfiler的插件结构大致可以分为三类 - 插件入口类(例如:
DNSFilterPlugin
),用来注册对应的类转换器。- Transformer类(例如:InetAddressTransformer
),用来定义需要hook的类名,以及hook方法的逻辑。- 过滤器业务逻辑类(例如:DNSFilter
),类转换之后被hook会真正调用到的类,一般用于拦截或者替换。
dns插件
- DNSFilterPlugin- 初始化转换类并注册
- InetAddressTransformer- hook了
java/net/InetAddress
类的getAllByName
方法以及isReachable
方法。- 修改之后的InetAddress代码大致如下:publicclassInetAddress{publicstaticInetAddress[]getAllByName(String hostName)throwsUnknownHostException{returnDNSFilter.testQuery(hostName)==null?newInetAddress[0]:super.getAllByName(hostName);}publicbooleanisReachable(NetworkInterface netif,int timeout,int ttl)throwsSocketException{InetAddress reachableAddress =DNSFilter.testReachable(this);if(reachableAddress !=null){returntrue;}else{returnfalse;}// ... }}
- DNSFilter
总结
- dns插件hook了InetAddress类的getAllByName方法,如何匹配配置的域名,则抛出UnknownHostException异常。以及isReachable方法,如何匹配规则则返回false。
- dns对应配置
[DNS]EQUAL,jetbrains.comEQUAL,plugin.obroom.com
- 也就是访问jetbrains.com以及plugin.obroom.com都是失败的。
power插件
总结
- power插件hook了
BigInteger
的oddModPow
方法,这个方法是用来对一个数模取幂运算的,及x.oddModPow(y,z) = x^y % z
。RSA非对称加密底层会使用到当前方法。 - 可以简单理解为在oddModPow函数前加了一段逻辑,就是如果入参x,y,z匹配配置的规则,那么就返回规则配置的结果。
publicclassBigInteger{publicstaticBigIntegeroddModPow(BigInteger x,BigInteger y,BigInteger mod){BigInteger result =ResultFilter.testFilter(x, y, mod);if(result !=null){return result;}// ...}}
url插件
总结
- url插件hook了
HttpClient
的openServer
方法。在执行逻辑之前调用testUrl方法。publicclassHttpClient{publicvoidopenServer(){URLFilter.testURL(url);// ...}}
- testUrl方法中的逻辑为如果匹配了规则中设置的url,那么就抛出SocketTimeoutException异常,也即不能访问指定url。
publicstaticURLtestURL(URL url)throwsIOException{if(null== url ||null== ruleList){returnnull;}for(FilterRule rule : ruleList){if(!rule.test(url.toString())){continue;}DebugInfo.output("Reject url: "+ url +", rule: "+ rule);thrownewSocketTimeoutException("connect timed out");}return url;}
- 对应规则为
[URL]PREFIX,https://account.jetbrains.com/lservice/rpc/validateKey.action
- 那么这里就是只要前缀匹配了当前地址,也即是rpc校验激活码的地址,那么就会抛出异常,自然也就无法网络校验了。
Idea调试
- 可以看到,在输入验证码之后,会调用
RAS
相关方法来校验激活码,这里就会调用到ja-netfiler
插件power
的方法。如果匹配了对应的配置,就会给出一个结果来替换oddModPow的结果。 - 校验验证码成功,激活成功
- 点击继续,关闭弹窗,idea会调用rpc接口校验验证码,
url
插件匹配规则,抛出异常。
参考
本文转载自: https://blog.csdn.net/yangfeng20/article/details/137565926
版权归原作者 闭关修炼啊哈 所有, 如有侵权,请联系我们删除。
版权归原作者 闭关修炼啊哈 所有, 如有侵权,请联系我们删除。