代码混淆导致 [java.lang.VerifyError Bad type on operand stack]
场景
在项目开发中为了源代码的安全问题,有时候会把代码混淆,让人无法通过反编译Java的class文件得到源码,但是在代码混淆之后可能会出现一些问题。
问题描述
我新建了一个类
public class TKScheduledTaskServiceDataOperationUpload {
public Object exeAction(HashMap<String, Object> result) {
try{
//code
} catch (ParseException | IOException e) {
e.printStackTrace();
return null;
}
return null;
}
}
编译完成之后得到jar
包,通过 allatori
混淆代码,上传到服务器,在启动项目的时候出现了如下的异常日志:
Caused by: java.lang.VerifyError Bad type on operand stack
Exception Details:
Location:
com/css/tk/tka/core/common/log/TKScheduledTaskServiceDataOperationUpload.exeAction(Ljava/util/HashMap;)Ljava/lang/Object; @831: invokevirtual
Reason:
Type 'java/lang/Object' (current frame, stack[2]) is not assignable to 'java/lang/Throwable'
Current Frame:
bci: @831
flags: { }
locals: { 'java/lang/Object', 'java/util/List', 'com/css/tk/tka/core/common/log/TKScheduledTaskServiceDataOperationUpload', 'java/lang/Object', 'java/lang/String', 'java/lang/Object', 'java/util/HashMap' }
stack: { 'com/css/sword/kernel/utils/SwordLogUtils', 'java/lang/String', 'java/lang/Object' }
Bytecode:
0x0000000: 2a4d b200 3812 b0b8 003f b600 452b b800
0x0000010: b699 0011 b200 3812 b8b8 003f b600 4501
0x0000020: b0bf 12ba b800 3fb6 0095 04bd 00bc 0459
0x0000030: 5859 0312 be53 b800 c4c0 00c6 594b b800
0x0000040: b69a 0032 2a12 c8b8 003f b900 cb02 00c0
0x0000050: 0092 594e b800 ce9a 001c 2a12 c8b8 003f
0x0000060: b900 cb02 00c0 0092 12d0 b800 3fb6 00d3
0x0000070: 9900 1fb2 0038 05bd 00bc 0459 5859 0312
0x0000080: d5b8 003f 5359 042a 53b6 00d8 01b0 bfbb
0x0000090: 0086 59b7 008a 032d b600 9012 dab8 003f
0x00000a0: b600 99b6 009c 4b2b 12dc b800 3fb6 00df
0x00000b0: c000 e159 4eb6 00e4 3a04 2b12 e6b8 003f
0x00000c0: b600 dfc0 00e8 4cb2 0038 05bd 00bc 0459
0x00000d0: 5859 0312 eab8 003f 5359 0419 0453 b600
0x00000e0: d8bb 0086 59b7 008a 0312 8cb6 0090 1904
0x00000f0: b600 95b6 0099 b600 9c2b b600 eeb8 00f2
0x0000100: 594c b800 f599 0010 b200 3812 f7b8 003f
0x0000110: b600 4501 b02b ba00 fd00 00b9 00fe 0200
0x0000120: bb00 de59 b700 ff59 3a05 1301 0110 20b8
0x0000130: 0105 b601 0919 0513 010b bb00 de59 b700
0x0000140: ffb6 0109 bb00 de59 b700 ff59 3a06 1301
0x0000150: 0db8 003f 2db6 0110 b601 0919 0613 0112
0x0000160: b800 3f2b b601 0919 0513 0114 1906 b601
0x0000170: 0919 05b8 011a 4eb2 0038 1301 1cb8 003f
0x0000180: b600 4557 5858 b200 3805 bd00 bc04 5958
0x0000190: 5903 1301 1eb8 003f 5359 042a 53b6 00d8
0x00001a0: 2d2a 03b8 0124 b801 2a2c 2b19 04ba 0133
0x00001b0: 0000 b801 374b b200 3805 bd00 bc04 5958
0x00001c0: 5903 1301 39b8 003f 5359 042a 53b6 00d8
0x00001d0: 12a4 2ab6 013c 9a01 a22a b801 42c0 00c6
0x00001e0: 1301 14b9 00cb 0200 c000 c659 4eb8 00b6
0x00001f0: 9a00 172d 1301 14b9 00cb 0200 c000 c659
0x0000200: 4eb8 00b6 9900 72b2 0038 05bd 00bc 0459
0x0000210: 5859 0313 0144 b800 3f53 5904 2a53 b600
0x0000220: d82b b900 5301 002c 1904 ba01 4800 00b9
0x0000230: 0068 0200 2c2b b900 5301 00ba 014c 0000
0x0000240: b900 7602 00b8 007c b900 8002 00c0 0026
0x0000250: 1904 b600 843a 05bb 0086 59b7 008a 0312
0x0000260: 8cb6 0090 1904 b600 95b6 0099 b600 9c19
0x0000270: 05b8 00a2 01b0 1301 4eb8 003f 2d13 0150
0x0000280: b800 3fb9 00cb 0200 b601 3c99 00ed b200
0x0000290: 3813 0152 b800 3fb6 0045 2d13 0154 b800
0x00002a0: 3fb9 00cb 0200 c000 263a 052b b900 5301
0x00002b0: 002c 1904 ba01 5b00 00b9 0076 0200 1905
0x00002c0: ba01 6500 00b9 0169 0200 b800 7cb9 0080
0x00002d0: 0200 c000 264e 2c2d 1904 b600 843a 05bb
0x00002e0: 0086 59b7 008a 0312 8cb6 0090 1904 b600
0x00002f0: 95b6 0099 b600 9c19 05b8 00a2 b200 3805
0x0000300: bd00 bc04 5958 5903 1301 6bb8 003f 5359
0x0000310: 042d 53b6 00d8 b200 3805 bd00 bc04 5958
0x0000320: 5903 1301 6db8 003f 5359 0419 0553 b600
0x0000330: d8a7 0047 4bb2 0038 1301 6fb8 003f 2ab6
0x0000340: 004f 012a b601 72b0 4bbb 0086 59b7 008a
0x0000350: 0312 8cb6 0090 1904 b600 95b6 0099 b600
0x0000360: 9c2b b800 a2b2 0038 1301 74b8 003f 2ab6
0x0000370: 004f 012a b601 72b0 01b0
Exception Handler Table:
bci [390, 629] => handler: 820
bci [390, 629] => handler: 820
bci [630, 817] => handler: 820
bci [630, 817] => handler: 820
bci [390, 629] => handler: 840
bci [630, 817] => handler: 840
Stackmap Table:
full_frame(@33,{},{Object[#375]})
append_frame(@34,Object[#2],Object[#222],Object[#2])
full_frame(@115,{Object[#198],Object[#222],Object[#2]},{})
full_frame(@142,{},{Object[#375]})
full_frame(@143,{Object[#198],Object[#222],Object[#2],Object[#146]},{})
full_frame(@277,{Object[#146],Object[#38],Object[#2],Object[#225],Object[#146]},{})
full_frame(@519,{Object[#146],Object[#38],Object[#2],Object[#198],Object[#146],Object[#222],Object[#222]},{})
same_frame_extended(@630)
full_frame(@820,{Object[#146],Object[#38],Object[#2],Object[#188],Object[#146],Object[#188],Object[#222]},{Object[#188]})
same_locals_1_stack_item_frame(@840,Object[#174])
same_frame(@888)
at java.lang.Class.getDeclaredMethods0(Class.java:-2)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetPublicMethods(Class.java:2902)
at java.lang.Class.getMethods(Class.java:1615)
找了很久的错误原因,一开始以为没有扫描到这个类,最后在这篇博客上proguard代码混淆问题 上找到了错误原因。查看源码根本原因是在使用代码混淆的时候有一些特殊的代码混淆会出现问题。在这个问题中特殊的代码就是
try{
//code
} catch (ParseException | IOException e) {
e.printStackTrace();
return null;
}
这里使用了Java
的一些便捷语法。导致了代码混淆之后出现了错误。把这里的代码写成原来的方式:
try{
//code
} catch (IOException e) {
e.printStackTrace();
return null;
} catch(ParseException e) {
e.printStackTrace();
return null;
}
重新打包编译就没有错误。
总结
1.在使用代码混淆工具的时候一定要注意一些特殊的代码打包是否会出现问题
2.同样的在使用新的语法的时候要特别的注意使用的一些限制,避免出现问题
3.我们在排错的时候,如果把所有可能的情况都排除了,那么就需要转换思维,是否是我们自己主动原因导致的,有时候也可以适当的把重点放在客观因素上。