安卓逆向SO库去签名校验

Title
安卓逆向SO库去签名校验
Date
May 14, 2023

apk签名校验:

某些安卓程序为了防止被破解,而在程序中加入了签名校验,这样在apk被重新打包之后,会出现签名不一直的问题,apk运行之后就会检测到,这样apk就会运行出现问题。

apk去除签名校验:

去除签名校验的方法也很简单,只要在apk校验签名的地方给破解掉即可。

apk签名校验的常用方法:

getPackageManager()
getPackageInfo(getPackageName(), 64)
signatures
hashCode()
使用packageManager获取apk packageinfo然后使用signatures方法之后,在算出哈希值和原本的签名哈希值进行对比,一般的签名校验都是这个流程。

实例一:bug磁力搜索器:

android killer 反编译之后,搜索getPackageManager,就在入口界面找到了qian()方法,看到这就明白了,这拼音命名法可正是666。
 
notion image
直接去掉219行的跳转,或者直接去掉,再干脆一点,直接清空这个函数都可以。
.method public qian(I)V .locals 3 .annotation system Ldalvik/annotation/Signature; value = { "(I)V" } .end annotation .prologue .line 215 :try_start_0 invoke-virtual {p0}, Lcom/bug/bt/MainActivity;->getPackageManager()Landroid/content/pm/PackageManager; move-result-object v0 invoke-virtual {p0}, Lcom/bug/bt/MainActivity;->getPackageName()Ljava/lang/String; move-result-object v1 const/16 v2, 0x40 invoke-virtual {v0, v1, v2}, Landroid/content/pm/PackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo; move-result-object v0 .line 216 iget-object v0, v0, Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature; .line 217 const/4 v1, 0x0 aget-object v0, v0, v1 .line 218 invoke-virtual {v0}, Landroid/content/pm/Signature;->hashCode()I move-result v0 .line 219 if-eq v0, p1, :cond_0 #去掉这里的跳转,或者直接删除即可 .line 221 const/4 v0, 0x1 const/4 v1, 0x1 invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast; move-result-object v0 invoke-virtual {v0}, Landroid/widget/Toast;->show()V :try_end_0 .catch Landroid/content/pm/PackageManager$NameNotFoundException; {:try_start_0 .. :try_end_0} :catch_0 .line 222 :cond_0 :goto_0 return-void :catch_0 move-exception v0 goto :goto_0 .end method
以为这样就可以了,但是我还是too yang,too simple,应用还是照样闪退,翻看日志,找到了一点端倪,看到了qian()方法,打印出的日志,然后还调用了libbug.so文件。
notion image
notion image
IDA打开libbug.so文件:
这里调用了getsignhashcode函数,而这就是校验签名的函数:
notion image
getsignhashcode函数也是大致的校验流程,如果签名不一致,就会直接exit(0)退出,本想在这个函数里修改,但是有些麻烦,所以直接在调用这个函数的地方,直接nop掉,就可以了
notion image
 
notion image
notion image
在这里直接用两个两字节的thumb指令填充即可,arm hex指令四字节的nop指令,ida不识别,只能用00 BF 00 BF 直接代替即可,用ida改有时候会改变其他的指令,可以用其他的十六进制编辑器编辑。
notion image
编辑示意图:
notion image
notion image
notion image
notion image
改成BNE之后:
notion image
notion image
编辑完之后保存,替换libbug.so文件,然后重新打包运行:
不再闪退了:
notion image

案例二:书旗小说:

为了不走上次的弯路,我这次直接从日志入手:
notion image
关键方法就在ShuqiApplication$3.handleTokernf,这就是签名方法:
notion image
.method public handleToken(II)Z .locals 3 .prologue .line 351 iget-object v0, p0, Lcom/shuqi/app/ShuqiApplication$3;->val$context:Landroid/content/Context; invoke-virtual {v0}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager; move-result-object v0 .line 353 :try_start_0 iget-object v1, p0, Lcom/shuqi/app/ShuqiApplication$3;->val$context:Landroid/content/Context; .line 354 invoke-virtual {v1}, Landroid/content/Context;->getPackageName()Ljava/lang/String; move-result-object v1 const/16 v2, 0x40 invoke-virtual {v0, v1, v2}, Landroid/content/pm/PackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo; move-result-object v0 .line 355 iget-object v0, v0, Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature; .line 356 const/4 v1, 0x0 aget-object v0, v0, v1 invoke-virtual {v0}, Landroid/content/pm/Signature;->hashCode()I move-result v0 .line 357 .line 363 :cond_0 :goto_0 const/4 v0, 0x1 return v0 .end method
直接清空就好了,然后再次运行,又发现在libAppRuntime_V1_3.so里还有一个checkSignature函数,
notion image
notion image
notion image
notion image
 
notion image
在jni_load函数时,就已经调用了校验签名方法:
notion image
notion image
替换so文件,重新打包就可以运行了。

总结:

校验签名的方法可能有时候不止在java层,也可能在so层,或者两者都会有。
Built with Potion.so