1.故事前情
https://www.52pojie.cn/thread-1896656-1-1.html 节约时间可以只看提要:前情提要:处理一个APP,通过修改verifyUserLogin方法的判断跳转,成功做到打开软件即登录状态,实现了免登陆。点击部分按钮时,软件需要从服务器获取账号json信息,页面才能正常显示并使用,否则闪退。本以为通过正常登陆获取到账号json,对关键部分进行改编,再强制在返回值处写死就万事大吉了,结果软件一崩再崩,原因是到点击功能按钮这一步骤前,还需要点击获取城市列表按钮,点击选中城市确定按钮,每一步服务器都会返回一段json,每一步软件都会通过alibaba.fastjson处理后刷新给Model.smali,每一步功能按钮点击后软件都会从Model.smali重新获取返回值。因为自己手动写的json是写死了的,而且仅仅是账号信息的内容,没有城市列表、没有所在城市可使用功能等json信息,所以老是on a null object reference。对于一个外行小白来说,json的各种自动转换本身比较复杂,而且这个软件老是刷新不同的json,用写死返回值的方法可能行不通,所以想换个路径继续逆向。
2.问题详情
2.1通过改verifyUserLogin的判断跳转实现启动即登录,点击功能时出现闪退,logcat日志错误信息如下
[Java] 纯文本查看 复制代码
FATAL EXCEPTION: main
Process: com.huiyou.xiaoding, PID: 32729
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.huiyou.xiaoding/com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.huiyou.xiaoding.common.model.wallet.HYWallet.getGuid()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3307)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3446)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:7533)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:953)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.huiyou.xiaoding.common.model.wallet.HYWallet.getGuid()' on a null object reference
at com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.loadData(HYChooseDeviceActivity.java:253)
at com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.initUI(HYChooseDeviceActivity.java:130)
at com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.onCreate(HYChooseDeviceActivity.java:121)
at android.app.Activity.performCreate(Activity.java:7893)
at android.app.Activity.performCreate(Activity.java:7880)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3282)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3446)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:7533)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:953)
问题出在HYWallet,找到HYWallet.smali,查看代码
[Java] 纯文本查看 复制代码
# classes3.dex
.class public Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;
.super Lcom/huiyou/xiaoding/common/model/base/HYModel;
.source "HYWallet.java"
# instance fields
.field private alias:Ljava/lang/String;
.field private avatarUri:Ljava/lang/String;
.field private consumeEnterpriseAlias:Ljava/lang/String;
.field private consumeEnterpriseGuid:Ljava/lang/String;
.field private consumeEnterpriseName:Ljava/lang/String;
.field private countCredit:I
.field private createTime:Ljava/lang/String;
.field private creator:Ljava/lang/String;
.field private dummyMoney:D
.field private fullName:Ljava/lang/String;
.field private guid:Ljava/lang/String;
.field private isSystem:I
.field private modifier:Ljava/lang/String;
.field private modifyTime:Ljava/lang/String;
.field private money:D
.field private oldMoney:D
.field private payStatus:I
.field private phone:Ljava/lang/String;
.field private status:I
.field private studentNumber:Ljava/lang/String;
.field private userGuid:Ljava/lang/String;
.field private version:Ljava/lang/String;
.field private yesEnterprise:I
# direct methods
.method public constructor <init>()V
.registers 1
.line 5
invoke-direct {p0}, Lcom/huiyou/xiaoding/common/model/base/HYModel;-><init>()V
return-void
.end method
# virtual methods
.method public getAlias()Ljava/lang/String;
.registers 2
.line 33
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->alias:Ljava/lang/String;
return-object v0
.end method
.method public getAvatarUri()Ljava/lang/String;
.registers 2
.line 41
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->avatarUri:Ljava/lang/String;
return-object v0
.end method
.method public getConsumeEnterpriseAlias()Ljava/lang/String;
.registers 2
.line 201
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->consumeEnterpriseAlias:Ljava/lang/String;
return-object v0
.end method
.method public getConsumeEnterpriseGuid()Ljava/lang/String;
.registers 2
.line 185
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->consumeEnterpriseGuid:Ljava/lang/String;
return-object v0
.end method
.method public getConsumeEnterpriseName()Ljava/lang/String;
.registers 2
.line 193
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->consumeEnterpriseName:Ljava/lang/String;
return-object v0
.end method
.method public getCountCredit()I
.registers 2
.line 49
iget v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->countCredit:I
return v0
.end method
.method public getCreateTime()Ljava/lang/String;
.registers 2
.line 57
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->createTime:Ljava/lang/String;
return-object v0
.end method
.method public getCreator()Ljava/lang/String;
.registers 2
.line 65
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->creator:Ljava/lang/String;
return-object v0
.end method
.method public getDummyMoney()D
.registers 3
.line 73
iget-wide v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->dummyMoney:D
return-wide v0
.end method
.method public getFullName()Ljava/lang/String;
.registers 2
.line 81
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->fullName:Ljava/lang/String;
return-object v0
.end method
.method public getGuid()Ljava/lang/String;
.registers 2
.line 89
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->guid:Ljava/lang/String;
return-object v0
.end method
.method public getIsSystem()I
.registers 2
.line 97
iget v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->isSystem:I
return v0
.end method
.method public getModifier()Ljava/lang/String;
.registers 2
.line 105
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->modifier:Ljava/lang/String;
return-object v0
.end method
.method public getModifyTime()Ljava/lang/String;
.registers 2
.line 113
iget-object v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->modifyTime:Ljava/lang/String;
return-object v0
.end method
.method public getMoney()D
.registers 3
.line 121
iget-wide v0, p0, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->money:D
return-wide v0
.end method
.method public ge
将其中getGuid方法改为静态方法,并赋值
[Java] 纯文本查看 复制代码
.method public static getGuid()Ljava/lang/String;
.registers 2
const-string v0, "{\"guid\":\"abcdefghijklmnopqrstuvwxyz\"}"
return-object v0
.end method
保存运行,闪退,错误日志如下
[Java] 纯文本查看 复制代码
FATAL EXCEPTION: main
Process: com.huiyou.xiaoding, PID: 3589
java.lang.IncompatibleClassChangeError: The method 'java.lang.String com.huiyou.xiaoding.common.model.wallet.HYWallet.getGuid()' was expected to be of type virtual but instead was found to be of type static (declaration of 'com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity' appears in base.apk!classes3.dex)
at com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.loadData(HYChooseDeviceActivity.java:253)
at com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.initUI(HYChooseDeviceActivity.java:130)
at com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.onCreate(HYChooseDeviceActivity.java:121)
at android.app.Activity.performCreate(Activity.java:7893)
at android.app.Activity.performCreate(Activity.java:7880)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3282)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3446)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:7533)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:953)
HYChooseDeviceActivity调取getGuid方法时认为应该是virtual非私有的方法,而不是static静态方法,又打开HYChooseDeviceActivity.smali查看代码,调取了getGuid静态方法结果的是下面这个loadData方法
[Java] 纯文本查看 复制代码
.method private loadData()V .registers 6
.line 251
invoke-virtual {p0}, Lcom/huiyou/xiaoding/activity/device/HYChooseDeviceActivity;->HUDLoading()V
.line 252
invoke-static {}, Lcom/huiyou/xiaoding/core/HYCore;->sharedCore()Lcom/huiyou/xiaoding/core/HYCore;
move-result-object v0
invoke-virtual {v0}, Lcom/huiyou/xiaoding/core/HYCore;->getProject()Lcom/huiyou/xiaoding/common/model/project/HYProject;
move-result-object v0
invoke-virtual {v0}, Lcom/huiyou/xiaoding/common/model/project/HYProject;->getEnterpriseGuid()Ljava/lang/String;
move-result-object v0
.line 253
invoke-static {}, Lcom/huiyou/xiaoding/core/HYCore;->sharedCore()Lcom/huiyou/xiaoding/core/HYCore;
move-result-object v1
invoke-virtual {v1}, Lcom/huiyou/xiaoding/core/HYCore;->getWallet()Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;
move-result-object v1
invoke-virtual {v1}, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->getGuid()Ljava/lang/String;
move-result-object v1
.line 254
iget-object v2, p0, Lcom/huiyou/xiaoding/activity/device/HYChooseDeviceActivity;->deviceTypeCode:Ljava/lang/String;
iget-boolean v3, p0, Lcom/huiyou/xiaoding/activity/device/HYChooseDeviceActivity;->isDrinking:Z
new-instance v4, Lcom/huiyou/xiaoding/activity/device/HYChooseDeviceActivity$$ExternalSyntheticLambda0;
invoke-direct {v4, p0}, Lcom/huiyou/xiaoding/activity/device/HYChooseDeviceActivity$$ExternalSyntheticLambda0;-><init>(Lcom/huiyou/xiaoding/activity/device/HYChooseDeviceActivity;)V
invoke-static {v0, v1, v2, v3, v4}, Lcom/huiyou/xiaoding/http/HYHotWaterAction;->getHouseUse(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLcom/huiyou/xiaoding/common/model/http/HYHttpResponseHandler;)V
return-void
.end method
那我把invoke-virtual {v1}, Lcom/huiyou/xiaoding/common/model/wallet/HYWallet;->getGuid()Ljava/lang/String;
move-result-object v1之中的调取非私有实例方法invoke-virtual改为调取静态方法invoke-static,保存运行,又闪退崩溃,日志如下
[Java] 纯文本查看 复制代码
FATAL EXCEPTION: main
Process: com.huiyou.xiaoding, PID: 8459
java.lang.VerifyError: Verifier rejected class com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity: void com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.loadData() failed to verify: void com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity.loadData(): [0x17] Rejecting invocation, expected 1 argument registers, method signature has 0 (declaration of 'com.huiyou.xiaoding.activity.device.HYChooseDeviceActivity' appears in base.apk!classes3.dex)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at java.lang.Class.forName(Class.java:379)
at com.huiyou.xiaoding.core.HYCommandCore.pushActivity(HYCommandCore.java:372)
at com.huiyou.xiaoding.core.HYCommandCore.startActivity(HYCommandCore.java:321)
at com.huiyou.xiaoding.core.HYCommandCore.run(HYCommandCore.java:84)
at com.huiyou.xiaoding.fragment.home.cell.HYShortcutListCell.zb_didSelectRowAtIndexPath(HYShortcutListCell.java:169)
at com.huiyou.xiaoding.common.view.zbink.listview.ZBRecyclerView$ZBRecyclerViewAdapter$1.onClick(ZBRecyclerView.java:289)
at android.view.View.performClick(View.java:7161)
at android.view.View.performClickInternal(View.java:7138)
at android.view.View.access$3500(View.java:811)
at android.view.View$PerformClick.run(View.java:27419)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:227)
at android.app.ActivityThread.main(ActivityThread.java:7533)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:953)
loadData方法拒绝调用,因为预期1个参数寄存器,但是方法签名有0个,这该怎么办呢?.method private loadData()V下不是有一个register 6吗?怎么还是报错? |