如何用Frida挂钩布尔函数并修改返回值?遇空指针异常求助
问题:Frida修改App类I()方法返回值时触发空指针异常
问题描述
我是Frida新手,尝试多种方法均未成功。我试图将布尔类型函数I()的返回值修改为false,但持续出现以下错误:Process crashed: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.cgflauowyeim.pxhvwigtoc.App.I()' on a null object reference
我已通过修改smali代码绕过虚拟机检测,但希望用Frida实现同样效果。尝试枚举重载方法但未找到,仍出现相同空指针异常。
目标类代码
public class App extends Application { private static App M; public libInterface f = null; public int g = 0; /* renamed from: K reason: collision with other method in class */ public boolean m42K() { return false; } public boolean I() { try { if (!Build.FINGERPRINT.startsWith(v.K((Object) "\u000fQ\u0006Q\u001a]\u000b"))) { if (!m42K()) { if (Build.FINGERPRINT.startsWith(u.K("&a&e?d")) || Build.MODEL.contains(v.K((Object) "S\u0007[\u000fX\rk\u001bP\u0003")) || Build.MODEL.contains(u.K("\rg=f)~'x")) || Build.MODEL.contains(v.K((Object) "/w-\u0014\u0010\f^\u0014\u0018\\\u0007Z\r")) || Build.MODEL.contains(u.K("Y<k&n)x,*\u0018I")) || Build.MODEL.contains(v.K((Object) ")Z\fF\u0007]\f\u0014;p#")) || Build.MODEL.contains(u.K(";n#U/z e&o")) || Build.MODEL.contains(v.K((Object) "u'g8")) || Build.MODEL.contains(u.K("\u00102pz:e")) || Build.MODEL.contains(v.K((Object) ">]\u001a@\u001dU\u0004")) || Build.MODEL.contains(u.K("\u001eG?k:o")) || Build.MANUFACTURER.contains(v.K((Object) "$}%}<q,")) || Build.MANUFACTURER.contains(u.K("\u0005E\nC\u0004O")) || Build.MANUFACTURER.contains(v.K((Object) "b%C\tF\r")) || Build.MANUFACTURER.contains(u.K("\\!x<)f")) || Build.MANUFACTURER.contains(v.K((Object) "e-y=")) || Build.MANUFACTURER.contains(u.K("&a&e?d")) || Build.MANUFACTURER.contains(v.K((Object) "s\rZ\u0011Y\u0007V\u0001X\r")) || Build.MANUFACTURER.contains(u.K("\u000fo&s%e<c'd")) || ((Build.BRAND.startsWith(v.K((Object) "\u000fQ\u0006Q\u001a]\u000b")) && Build.DEVICE.startsWith(u.K("m-d-x!i"))) || v.K((Object) "S\u0007[\u000fX\rk\u001bP\u0003").equals(Build.PRODUCT))) { return true; } return false; } } } catch (Exception unused) { } return true; } public void onCreate() { super.onCreate(); if (!I()) { try { if (M == null) { K(this); } Thread.setDefaultUncaughtExceptionHandler(new u()); o.K().m50K(); v.K().m55K((Context) this); aa.K().I(); l.K().I(this); startForegroundService(new Intent(this, ServiceHandler.class)); I(); } catch (Exception unused) { } } } private static synchronized /* synthetic */ void K(App app) { synchronized (App.class) { M = app; } } /* renamed from: K reason: collision with other method in class */ public void m41K() { try { System.exit(0); } catch (Exception unused) { } } public static App K() { return M; } }
编写的Frida脚本
Java.perform(function() { var App = Java.use('com.cgflauowyeim.pxhvwigtoc.App'); App.I.implementation = function() { console.log('I method called, returning false'); return false; }; // Register a hook that is executed before the onCreate method is called App.onCreate.before(function() { console.log('onCreate method called, replacing I method'); App.I.implementation = function() { console.log('I method called, returning false'); return false; }; }); });
解决方案
问题根源
空指针异常是因为I()方法可能在App实例初始化完成前就被调用了:比如其他代码通过静态方法App.K()获取实例,此时M还未被onCreate里的K(this)赋值,拿到null后调用I()就会触发异常。
修正后的Frida脚本方案
方案1:先保证静态方法返回有效实例,再hook I()
Java.perform(function() { var App = Java.use('com.cgflauowyeim.pxhvwigtoc.App'); var appInstance = null; // Hook静态K()方法,确保返回的实例不为null App.K.implementation = function() { if (!appInstance) { // 调用原方法获取系统初始化的实例 appInstance = this.K.call(this); } return appInstance; }; // Hook I()方法,固定返回false App.I.implementation = function() { console.log('I() called, returning false'); return false; }; });
方案2:主动捕获已加载的App实例,针对性hook
Java.perform(function() { var AppCls = Java.use('com.cgflauowyeim.pxhvwigtoc.App'); // 主动搜索已初始化的App实例,找到后hook其I()方法 Java.choose('com.cgflauowyeim.pxhvwigtoc.App', { onMatch: function(instance) { console.log('Found App instance:', instance); instance.I.implementation = function() { console.log('I() called on instance, returning false'); return false; }; }, onComplete: function() { console.log('App instance search finished'); } }); // 同时hook静态方法,防止后续获取null实例 AppCls.K.implementation = function() { var origInstance = this.K.call(this); return origInstance || null; }; });
额外说明
当I()返回false时,onCreate里的分支会正常执行,M会被赋值为当前App实例,后续调用App.K()就不会返回null了。核心是要拦截实例初始化前的I()调用请求,避免null对象调用方法。
内容的提问来源于stack exchange,提问作者balbavik
相关产品推荐
相关产品推荐

