ByteCodeEncrypt icon indicating copy to clipboard operation
ByteCodeEncrypt copied to clipboard

java段怎么通过指定agentpath,调用dll,解密class

Open GitHubcaowei opened this issue 5 years ago • 30 comments

我们提供jar供第三方调用,但是不像让第三方看到jar的源码,所以我也采用dll完成此需求,但是我不知道在jar如何集成dll,这样让第三方无感调用jar。

GitHubcaowei avatar Mar 21 '19 14:03 GitHubcaowei

https://blog.csdn.net/wangyangzhizhou/article/details/75316826

sea-boat avatar Mar 21 '19 14:03 sea-boat

你好,我用您的方法,普通的java项目,这样做的确可以做到jar加密,十分感谢, 但是在做springboot项目 jar的加密时,在启动 jar,提示
image
我怀疑是springboot项目和普通java项目的jar结构不一样。
image
image
我也再尝试修改springboot项目的路径, (我是java开发师,c++不是很懂),
尝试着修改JarEncryptor的
image
尝试着修改C++的cpp源文件
image
也不知道是否正确,拜托您帮忙看一下,现在在cmd启动出现第一张图的错误。
我不是很了解c++,怀疑是这里的 if 中的strncmp(name, "BOOT-INF/classes/com/wyd/", 25)这行代码的问题(里面有大小写和符合 - ,与25是否匹配)。拜托您抽空看看。

wuyingdu avatar May 10 '19 12:05 wuyingdu

你尝试调试一下,把java层和c++层的name和加解密结果都打印出来看看,就知道是哪里的问题了

sea-boat avatar May 10 '19 15:05 sea-boat

你尝试调试一下,把java层和c++层的name和加解密结果都打印出来看看,就知道是哪里的问题了

您好,我尝试着修改了文件,并打印name。
image
image
image
image
[我是java开发师,对c++一点都不懂,十分抱歉再次打扰到你。
您若是有时间,帮我看看这个。谢谢
问题说明.zip

wuyingdu avatar May 13 '19 08:05 wuyingdu

没有加载的话直接配一下classpath,将你的目录添加进去即可。

sea-boat avatar May 13 '19 09:05 sea-boat

这个问题已经困扰我好几天了,我实在是看不懂c++的语法,您能帮我写稍微修改一下吗?我愿意请您喝杯咖啡,或者其它,来表示我对您帮助的一点谢意。

wuyingdu avatar May 13 '19 11:05 wuyingdu

我看了下,问题应该在springboot自己写了类加载器,那个boot-inf是他自己的类加载器加载的,它没有交给jvm的系统类加载器加载。现在如果要简单处理的话你可以把加密的类打包到正常的目录下,而不是boot-inf里面,你是用maven管理的吧,好像是有插件可以做这个事。另外一种方法就是要改springboot的类加载器,比较麻烦。

sea-boat avatar May 13 '19 15:05 sea-boat

还有,记得放到正常目录的类,里面不要用到第三方类,只能用由系统类加载器加载的类,比如java语言自带的类,不然会找不到类,因为不同类加载器加载。

sea-boat avatar May 13 '19 15:05 sea-boat

image 是这样理解的吗?这样的话,springboot项目因为它独特的类加载器,所以这种加密方式,无法使用。

wuyingdu avatar May 13 '19 15:05 wuyingdu

你理解的大致没问题,不过不是说无法使用,是因为springboot自定义的类加载器没有使用双亲委派机制,所以不会委派给系统类加载器来加载。需要改动到springboot将类交给系统类加载器加载或者把类放到你图中的java常规目录下。

sea-boat avatar May 14 '19 01:05 sea-boat

通过您提供的思路,今天尝试着将springboot jar 外层的BOOT-INF/classes尝试去除。
参考网上,使用maven的插件 maven-jar-plugin 将依赖包lib和配置文件config与源码进行分离,
成功的将springboot jar 去除外层的BOOT-INF/classes 还原成普通的 jar 项目,就是启动时,需要将lib和config与jar放在一起。
还有一个问题,加密springboot的启动类时,解密失败多次。
image
其余的controller层加解密无异常。
image
毕竟核心业务代码也都是在 controller,所以暂时不加密springboot启动类,换成controller层。这个需求暂时也算是过了。
我还想写篇博客,总结一下这次的经验,方便转载或者摘抄博客吗?会注明出处。
十分感谢您的帮助,方便告诉您的支付宝号或者收款码,请您喝杯咖啡聊表谢意。
如果觉得泄露隐私,可以留邮箱联系您。或者我的邮箱 [email protected]

wuyingdu avatar May 14 '19 11:05 wuyingdu

博客可以转载,注明出处即可。 多谢打赏。

TIM图片20190514230510

sea-boat avatar May 14 '19 15:05 sea-boat

image
image
加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢?

wuyingdu avatar May 24 '19 12:05 wuyingdu

看下是不是版本的问题。 https://stackoverflow.com/questions/22771826/beandefinitionstoreexception-failed-to-read-candidate-component-class

sea-boat avatar May 25 '19 02:05 sea-boat

你好我按情况编写了加密解密springboot 项目 但是 在启动是报错nested exception is org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet 而且也没有进去解密的类 我已经将springboot的jar弄成了一般的jar 请问有解决方案吗?非常感谢

NotHys avatar May 29 '19 10:05 NotHys

image

image

加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢?

我在windows下根本加载不了 不进去解密的jvmti写的Agent_OnLoad

NotHys avatar May 29 '19 10:05 NotHys

image

image

加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢? 你成功加密的demo 可以给一个吗 或者加个联系方式QQ 1304320858

NotHys avatar May 29 '19 10:05 NotHys

可以参考我写的博客:https://blog.csdn.net/weixin_39747279/article/details/90214044 博客仅实现了windows平台的springboot jar包的加密,linux版本的有异常,没有实现。 你刚才的异常,网上搜索了一下,是JDK和spring的版本冲突, jdk7对应的是spring 3.2, jdk8对应的是spring 4.2. 你可以排查一下这方面的。

------------------ 原始邮件 ------------------ 发件人: "yushuihong"[email protected]; 发送时间: 2019年5月29日(星期三) 晚上6:22 收件人: "sea-boat/ByteCodeEncrypt"[email protected]; 抄送: "娃哈哈矿泉水"[email protected];"Comment"[email protected]; 主题: Re: [sea-boat/ByteCodeEncrypt] java段怎么通过指定agentpath,调用dll,解密class (#1)

加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢? 你成功加密的demo 可以给一个吗 或者加个联系方式QQ 1304320858 — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

wuyingdu avatar May 29 '19 10:05 wuyingdu

可以参考我写的博客:https://blog.csdn.net/weixin_39747279/article/details/90214044 博客仅实现了windows平台的springboot jar包的加密,linux版本的有异常,没有实现。 你刚才的异常,网上搜索了一下,是JDK和spring的版本冲突, jdk7对应的是spring 3.2, jdk8对应的是spring 4.2. 你可以排查一下这方面的。 ------------------ 原始邮件 ------------------ 发件人: "yushuihong"[email protected]; 发送时间: 2019年5月29日(星期三) 晚上6:22 收件人: "sea-boat/ByteCodeEncrypt"[email protected]; 抄送: "娃哈哈矿泉水"<[email protected]>;"Comment"<[email protected]>; 主题: Re: [sea-boat/ByteCodeEncrypt] java段怎么通过指定agentpath,调用dll,解密class (#1) 加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢? 你成功加密的demo 可以给一个吗 或者加个联系方式QQ 1304320858 — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

我排除了是JDK和spring的版本冲突的问题的 你试一试把你的加密的那做的复杂一点 比如AES DES 简单的字符str[i] = str[i] + 4 这种 idea 瞬间反编译 其实 可以思考一下 字节码前8个 是魔数 如果魔数不对 是不会加载类的 jdk马上会返回错误,而简单的str[i] = str[i] + 4 还是能识别就证明 这种加密其实没有太大的作用jdk的类加载和springboot的类加载都能识别(我的猜测),需要把字节加密做的复杂而且前8个字节是不能加密的。 当你把字节加密做的复杂的时候 你就会发现springboot的不管是lib和config分离 还是不分离 都运行不起来,(已经做了测试)。总之 在springboot下简单的str[i] = str[i] + 4 能运行(可能是类加载可以处理这种简单的错误code) 复杂的加密运行不了。而且运行复杂的版本的时候 不会进入dll或so的解密算法(假设我的算法有错它也应该会进入解密流程再报错),所以我猜测还是被springboot类加载器加载了,springboot没有双亲委派所以不会进入自定义的jvmti实现中。

基于这个情况我将springboot的类加载器重写进行加密解密,然后将重写springboot类加载器的class通过这个方案加密,因为spring boot 类加载器的加载肯定是会被原始的类加载器加载的,这样算是解决了也正常运行了反编译也看不到了idea同样无法反编译。不知道是不是我弄的没对还是怎么。用你的方案复杂加密算法是无法运行的,你可以尝试一下 如果能运行麻烦告知一下谢谢!

NotHys avatar May 30 '19 01:05 NotHys

QQ联系详细聊吧

wuyingdu avatar May 30 '19 03:05 wuyingdu

https://github.com/sea-boat/ByteCodeEncrypt/issues/1#issuecomment-496877963

image image 加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢?

我在windows下根本加载不了 不进去解密的jvmti写的Agent_OnLoad

最近也在做对jar加密的事情,这边个人感觉是spring自己负责解析class文件,没有交给jvm进行解析(所以也没有进行回调ClassDecryptHook),在spring解析class文件时,由于是密文所以在解析时出现了异常(org.springframework.asm.ClassReader#ClassReader(byte[], int, int)); 试过:手动注册被加密后的class类,在BeanDefinitionBuilder.genericBeanDefinition(className) 会调用回调函数,进而解密加载被加密的class文件。 所以个人的判断是:spring项目无法使用jvmti进行加解密后运行。

xiaoheitalk avatar Jun 04 '19 11:06 xiaoheitalk

你好我按情况编写了加密解密springboot 项目 但是 在启动是报错nested exception is org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet 而且也没有进去解密的类 我已经将springboot的jar弄成了一般的jar 请问有解决方案吗?非常感谢

请问一下这个问题解决了吗?是什么思路,刚刚遇见相同的情况。

WheatMaThink avatar Aug 30 '19 05:08 WheatMaThink

jdk版本的问题,请查看spring版本对应的jdk版本。 jar包加密推荐参考:https://github.com/core-lib/xjar

------------------ 原始邮件 ------------------ 发件人: "wheatma38"[email protected]; 发送时间: 2019年8月30日(星期五) 中午1:12 收件人: "sea-boat/ByteCodeEncrypt"[email protected]; 抄送: "娃哈哈矿泉水"[email protected];"Comment"[email protected]; 主题: Re: [sea-boat/ByteCodeEncrypt] java段怎么通过指定agentpath,调用dll,解密class (#1)

你好我按情况编写了加密解密springboot 项目 但是 在启动是报错nested exception is org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet 而且也没有进去解密的类 我已经将springboot的jar弄成了一般的jar 请问有解决方案吗?非常感谢 请问一下这个问题解决了吗?是什么思路,刚刚遇见相同的情况。 — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

wuyingdu avatar Aug 30 '19 06:08 wuyingdu

可以参考我写的博客:https://blog.csdn.net/weixin_39747279/article/details/90214044 博客仅实现了windows平台的springboot jar包的加密,linux版本的有异常,没有实现。 你刚才的异常,网上搜索了一下,是JDK和spring的版本冲突, jdk7对应的是spring 3.2, jdk8对应的是spring 4.2. 你可以排查一下这方面的。 ------------------ 原始邮件 ------------------ 发件人: "yushuihong"[email protected]; 发送时间: 2019年5月29日(星期三) 晚上6:22 收件人: "sea-boat/ByteCodeEncrypt"[email protected]; 抄送: "娃哈哈矿泉水"<[email protected]>;"Comment"<[email protected]>; 主题: Re: [sea-boat/ByteCodeEncrypt] java段怎么通过指定agentpath,调用dll,解密class (#1) 加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢? 你成功加密的demo 可以给一个吗 或者加个联系方式QQ 1304320858 — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

我排除了是JDK和spring的版本冲突的问题的 你试一试把你的加密的那做的复杂一点 比如AES DES 简单的字符str[i] = str[i] + 4 这种 idea 瞬间反编译 其实 可以思考一下 字节码前8个 是魔数 如果魔数不对 是不会加载类的 jdk马上会返回错误,而简单的str[i] = str[i] + 4 还是能识别就证明 这种加密其实没有太大的作用jdk的类加载和springboot的类加载都能识别(我的猜测),需要把字节加密做的复杂而且前8个字节是不能加密的。 当你把字节加密做的复杂的时候 你就会发现springboot的不管是lib和config分离 还是不分离 都运行不起来,(已经做了测试)。总之 在springboot下简单的str[i] = str[i] + 4 能运行(可能是类加载可以处理这种简单的错误code) 复杂的加密运行不了。而且运行复杂的版本的时候 不会进入dll或so的解密算法(假设我的算法有错它也应该会进入解密流程再报错),所以我猜测还是被springboot类加载器加载了,springboot没有双亲委派所以不会进入自定义的jvmti实现中。

基于这个情况我将springboot的类加载器重写进行加密解密,然后将重写springboot类加载器的class通过这个方案加密,因为spring boot 类加载器的加载肯定是会被原始的类加载器加载的,这样算是解决了也正常运行了反编译也看不到了idea同样无法反编译。不知道是不是我弄的没对还是怎么。用你的方案复杂加密算法是无法运行的,你可以尝试一下 如果能运行麻烦告知一下谢谢!

可以分析出是解析org.springframework.asm.ClassReader#ClassReader(byte[], int, int) 出的问题,

springboot没有双亲委派所以不会进入自定义的jvmti实现中,请教一下这个是怎么实现的?

WheatMaThink avatar Sep 03 '19 10:09 WheatMaThink

我的博客第三点明确的说了,我在打包springboot项目时,将源码和依赖,配置文件进行拆分,去除 BOOT-INF那一层,恢复双亲委派机制,springboot项目打包成普通的jar包,来进行加解密支持。

------------------ 原始邮件 ------------------ 发件人: "wheatma38"[email protected]; 发送时间: 2019年9月3日(星期二) 晚上6:14 收件人: "sea-boat/ByteCodeEncrypt"[email protected]; 抄送: "娃哈哈矿泉水"[email protected];"Comment"[email protected]; 主题: Re: [sea-boat/ByteCodeEncrypt] java段怎么通过指定agentpath,调用dll,解密class (#1)

可以参考我写的博客:https://blog.csdn.net/weixin_39747279/article/details/90214044 博客仅实现了windows平台的springboot jar包的加密,linux版本的有异常,没有实现。 你刚才的异常,网上搜索了一下,是JDK和spring的版本冲突, jdk7对应的是spring 3.2, jdk8对应的是spring 4.2. 你可以排查一下这方面的。 … ------------------ 原始邮件 ------------------ 发件人: "yushuihong"[email protected]; 发送时间: 2019年5月29日(星期三) 晚上6:22 收件人: "sea-boat/ByteCodeEncrypt"[email protected]; 抄送: "娃哈哈矿泉水"[email protected];"Comment"[email protected]; 主题: Re: [sea-boat/ByteCodeEncrypt] java段怎么通过指定agentpath,调用dll,解密class (#1) 加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢? 你成功加密的demo 可以给一个吗 或者加个联系方式QQ 1304320858 — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread. 我排除了是JDK和spring的版本冲突的问题的 你试一试把你的加密的那做的复杂一点 比如AES DES 简单的字符str[i] = str[i] + 4 这种 idea 瞬间反编译 其实 可以思考一下 字节码前8个 是魔数 如果魔数不对 是不会加载类的 jdk马上会返回错误,而简单的str[i] = str[i] + 4 还是能识别就证明 这种加密其实没有太大的作用jdk的类加载和springboot的类加载都能识别(我的猜测),需要把字节加密做的复杂而且前8个字节是不能加密的。 当你把字节加密做的复杂的时候 你就会发现springboot的不管是lib和config分离 还是不分离 都运行不起来,(已经做了测试)。总之 在springboot下简单的str[i] = str[i] + 4 能运行(可能是类加载可以处理这种简单的错误code) 复杂的加密运行不了。而且运行复杂的版本的时候 不会进入dll或so的解密算法(假设我的算法有错它也应该会进入解密流程再报错),所以我猜测还是被springboot类加载器加载了,springboot没有双亲委派所以不会进入自定义的jvmti实现中。 基于这个情况我将springboot的类加载器重写进行加密解密,然后将重写springboot类加载器的class通过这个方案加密,因为spring boot 类加载器的加载肯定是会被原始的类加载器加载的,这样算是解决了也正常运行了反编译也看不到了idea同样无法反编译。不知道是不是我弄的没对还是怎么。用你的方案复杂加密算法是无法运行的,你可以尝试一下 如果能运行麻烦告知一下谢谢! 可以分析出是解析org.springframework.asm.ClassReader#ClassReader(byte[], int, int) 出的问题, — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

wuyingdu avatar Sep 03 '19 10:09 wuyingdu

image

image

加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢?

这个是spring-boot项目加密后启动报数组越界的错误。经排查是由于spring aop注解扫描的时候需要用asm框架去读取字节码数据,去获取注解信息,用于实例化对象,但是由于class文件已经被加密过,SimpleMetadataReader这个类去读取加密字节文件InputStream,然后在将输入流转换为字节数组去构建ClassReader,但是这个字节数组其实已经被c代码修改过了,因此会报数组越界异常。因此需要修改SimpleMetadataReader代码。 详细的原因参考这篇文章 image 由于牵扯到修改源码,有几种方式: 1.直接在项目里,建一个org.springframework.core.type.classreading包,将源码SimpleMetadataReadercopy出来做修改即可。这是最简单直接的方式。

2.第一种方式可能需要每个加密项目都要建相同的包路径和文件,不是很优雅,因此还有一个思路就是修改SimpleMetadataReader类后自己在重新构建spring源码,发布。

3.修改源码,重新构建,打包发布考虑到也比较麻烦,因此就考虑使用jvmti 的class onload回调函数里,拦截SimpleMetadataReader的加载数据,进行替换。 首先也是将SimpleMetadataReader源码copy出来进行相应的字节码解密修改,然后读取SimpleMetadataReader.class文件,转为byte[]数组,然后转为16进制字符串,将16进制字符串进行两位一组分组,分组后每个字符串前加0x前缀(16进制标识),组成四位一组的的字节码数组输出(因为jvmti的ClassFileLoadHook回调函数的unsigned char* class_data就是这种格式)。将输出的字节码数组复制到c代码里,作为一个常量字符数组,然后在ClassFileLoadHook函数里拦截org/springframework/core/type/classreading/SimpleMetadataReader这个类,使用常量替换即可。 注意new_class_data在替换的时候需要申请新的数组空间,否则会出现服务随机无法启动的问题。

superlee007 avatar Jan 07 '20 12:01 superlee007

image image 加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢?

这个是spring-boot项目加密后启动报数组越界的错误。经排查是由于spring aop注解扫描的时候需要用asm框架去读取字节码数据,去获取注解信息,用于实例化对象,但是由于class文件已经被加密过,SimpleMetadataReader这个类去读取加密字节文件InputStream,然后在将输入流转换为字节数组去构建ClassReader,但是这个字节数组其实已经被c代码修改过了,因此会报数组越界异常。因此需要修改SimpleMetadataReader代码。 详细的原因参考这篇文章 image 由于牵扯到修改源码,有几种方式: 1.直接在项目里,建一个org.springframework.core.type.classreading包,将源码SimpleMetadataReadercopy出来做修改即可。这是最简单直接的方式。

2.第一种方式可能需要每个加密项目都要建相同的包路径和文件,不是很优雅,因此还有一个思路就是修改SimpleMetadataReader类后自己在重新构建spring源码,发布。

3.修改源码,重新构建,打包发布考虑到也比较麻烦,因此就考虑使用jvmti 的class onload回调函数里,拦截SimpleMetadataReader的加载数据,进行替换。 首先也是将SimpleMetadataReader源码copy出来进行相应的字节码解密修改,然后读取SimpleMetadataReader.class文件,转为byte[]数组,然后转为16进制字符串,将16进制字符串进行两位一组分组,分组后每个字符串前加0x前缀(16进制标识),组成四位一组的的字节码数组输出(因为jvmti的ClassFileLoadHook回调函数的unsigned char* class_data就是这种格式)。将输出的字节码数组复制到c代码里,作为一个常量字符数组,然后在ClassFileLoadHook函数里拦截org/springframework/core/type/classreading/SimpleMetadataReader这个类,使用常量替换即可。 注意new_class_data在替换的时候需要申请新的数组空间,否则会出现服务随机无法启动的问题。

你好,SimpleMetadataReader要怎么修改,方案3有详细代码吗,方便的话,qq沟通一下:407072737,谢谢

yixianluo avatar Jan 22 '20 08:01 yixianluo

https://bce.gopiqiu.com/ 去这个网站看看,能解决上面提到的所有问题。

nobody19527 avatar Mar 09 '22 03:03 nobody19527

通过您提供的思路,今天尝试着将springboot jar 外层的BOOT-INF/classes尝试去除。 参考网上,使用maven的插件 maven-jar-plugin 将依赖包lib和配置文件config与源码进行分离, 成功的将springboot jar 去除外层的BOOT-INF/classes 还原成普通的 jar 项目,就是启动时,需要将lib和config与jar放在一起。 还有一个问题,加密springboot的启动类时,解密失败多次。 image 其余的controller层加解密无异常。 image 毕竟核心业务代码也都是在 controller,所以暂时不加密springboot启动类,换成controller层。这个需求暂时也算是过了。 我还想写篇博客,总结一下这次的经验,方便转载或者摘抄博客吗?会注明出处。 十分感谢您的帮助,方便告诉您的支付宝号或者收款码,请您喝杯咖啡聊表谢意。 如果觉得泄露隐私,可以留邮箱联系您。或者我的邮箱 [email protected]

https://bce.gopiqiu.com/ 去这个网站看看,能解决上面提到的所有问题。

nobody19527 avatar Mar 09 '22 03:03 nobody19527

image image 加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢?

这个是spring-boot项目加密后启动报数组越界的错误。经排查是由于spring aop注解扫描的时候需要用asm框架去读取字节码数据,去获取注解信息,用于实例化对象,但是由于class文件已经被加密过,SimpleMetadataReader这个类去读取加密字节文件InputStream,然后在将输入流转换为字节数组去构建ClassReader,但是这个字节数组其实已经被c代码修改过了,因此会报数组越界异常。因此需要修改SimpleMetadataReader代码。 详细的原因参考这篇文章 image 由于牵扯到修改源码,有几种方式: 1.直接在项目里,建一个org.springframework.core.type.classreading包,将源码SimpleMetadataReadercopy出来做修改即可。这是最简单直接的方式。 2.第一种方式可能需要每个加密项目都要建相同的包路径和文件,不是很优雅,因此还有一个思路就是修改SimpleMetadataReader类后自己在重新构建spring源码,发布。 3.修改源码,重新构建,打包发布考虑到也比较麻烦,因此就考虑使用jvmti 的class onload回调函数里,拦截SimpleMetadataReader的加载数据,进行替换。 首先也是将SimpleMetadataReader源码copy出来进行相应的字节码解密修改,然后读取SimpleMetadataReader.class文件,转为byte[]数组,然后转为16进制字符串,将16进制字符串进行两位一组分组,分组后每个字符串前加0x前缀(16进制标识),组成四位一组的的字节码数组输出(因为jvmti的ClassFileLoadHook回调函数的unsigned char* class_data就是这种格式)。将输出的字节码数组复制到c代码里,作为一个常量字符数组,然后在ClassFileLoadHook函数里拦截org/springframework/core/type/classreading/SimpleMetadataReader这个类,使用常量替换即可。 注意new_class_data在替换的时候需要申请新的数组空间,否则会出现服务随机无法启动的问题。

你好,SimpleMetadataReader要怎么修改,方案3有详细代码吗,方便的话,qq沟通一下:407072737,谢谢

https://bce.gopiqiu.com/ 去这个网站看看,能解决上面提到的所有问题。

image image 加解密的字符位置和之前windows一样。在if判断内的。这是什么原因呢?

这个是spring-boot项目加密后启动报数组越界的错误。经排查是由于spring aop注解扫描的时候需要用asm框架去读取字节码数据,去获取注解信息,用于实例化对象,但是由于class文件已经被加密过,SimpleMetadataReader这个类去读取加密字节文件InputStream,然后在将输入流转换为字节数组去构建ClassReader,但是这个字节数组其实已经被c代码修改过了,因此会报数组越界异常。因此需要修改SimpleMetadataReader代码。 详细的原因参考这篇文章 image 由于牵扯到修改源码,有几种方式: 1.直接在项目里,建一个org.springframework.core.type.classreading包,将源码SimpleMetadataReadercopy出来做修改即可。这是最简单直接的方式。 2.第一种方式可能需要每个加密项目都要建相同的包路径和文件,不是很优雅,因此还有一个思路就是修改SimpleMetadataReader类后自己在重新构建spring源码,发布。 3.修改源码,重新构建,打包发布考虑到也比较麻烦,因此就考虑使用jvmti 的class onload回调函数里,拦截SimpleMetadataReader的加载数据,进行替换。 首先也是将SimpleMetadataReader源码copy出来进行相应的字节码解密修改,然后读取SimpleMetadataReader.class文件,转为byte[]数组,然后转为16进制字符串,将16进制字符串进行两位一组分组,分组后每个字符串前加0x前缀(16进制标识),组成四位一组的的字节码数组输出(因为jvmti的ClassFileLoadHook回调函数的unsigned char* class_data就是这种格式)。将输出的字节码数组复制到c代码里,作为一个常量字符数组,然后在ClassFileLoadHook函数里拦截org/springframework/core/type/classreading/SimpleMetadataReader这个类,使用常量替换即可。 注意new_class_data在替换的时候需要申请新的数组空间,否则会出现服务随机无法启动的问题。

你好,SimpleMetadataReader要怎么修改,方案3有详细代码吗,方便的话,qq沟通一下:407072737,谢谢

https://bce.gopiqiu.com/ 去这个网站看看,能解决上面提到的所有问题。

nobody19527 avatar Mar 09 '22 03:03 nobody19527