1700449277
1700449278
public Throwable(){
1700449279
1700449280
//记录栈帧
1700449281
1700449282
fllInStackTrace();
1700449283
1700449284
}
1700449285
1700449286
//本地方法,抓取执行时的栈信息
1700449287
1700449288
public synchronized native Throwable fillInStackTrace();
1700449289
1700449290
}
1700449291
1700449292
在出现异常时(或主动声明一个Throwable对象时),JVM会通过fillInStackTrace方法记录下栈帧信息,然后生成一个Throwable对象,这样我们就可以知道类间的调用顺序、方法名称及当前行号等了。
1700449293
1700449294
获得栈信息可以对调用者进行判断,然后决定不同的输出,比如我们的m1和m2方法,同样是输入参数,同样的调用方法,但是输出却不同,这看起来很像是一个Bug:方法m1调用m方法是正常显示,而方法m2调用却会返回“错误”数据。因此我们虽然可以依据调用者不同产生不同的逻辑,但这仅局限在对此方法的广泛认知上。更多的时候我们使用m方法的变形体,代码如下:
1700449295
1700449296
class Foo{
1700449297
1700449298
public static boolean m(){
1700449299
1700449300
//取得当前栈信息
1700449301
1700449302
StackTraceElement[]sts=new Throwable().getStackTrace();
1700449303
1700449304
//检查是否是m1方法调用
1700449305
1700449306
for(StackTraceElement st:sts){
1700449307
1700449308
if(st.getMethodName().equals(“m1”)){
1700449309
1700449310
return true;
1700449311
1700449312
}
1700449313
1700449314
}
1700449315
1700449316
throw new RuntimeException(“除m1方法外,该方法不允许其他方法调用”);
1700449317
1700449318
}
1700449319
1700449320
}
1700449321
1700449322
只是把“return false”替换成一个运行期异常,除了m1方法外,其他方法调用都会产生异常,该方法常用作离线注册码校验,当破解者试图暴力破解时,由于主执行者不是期望的值,因此会返回一个经过包装和混淆的异常信息,大大增加了破解的难度。
1700449323
1700449324
1700449325
1700449326
[
上一页 ]
[ :1.700449277e+09 ]
[
下一页 ]