android签名检测和绕过

发布时间 2023-09-27 17:24:17作者: 怎么可以吃突突

PackageManagerService获取签名

正常APP中获取PackageInfo中的签名信息是通过Binder通讯向PackageManagerService发送TRANSACTION_getPackageInfo请求,同时设置请求的参数的flag为GET_SIGNATURES。当PackageManagerService判断是TRANSACTION_getPackageInfo请求后会去调用PackageManagerService.getPackageInfo

PackageManagerService.getPackageInfo 会进一步调用PackageManagerService.getPackageInfoInternal

PackageManagerService.getPackageInfoInternal会进行一些权限校验和匹配,最后调用PackageManagerService.generatePackageInfo

PackageManagerService.generatePackageInfo获取到包名对应的PackageParser.Package,然后调用PackageParser.generatePackageInfo

PackageParser.generatePackageInfo就是取出PackageParser.Package对象中的成员mSigningDetails.pastsigningcertificates[0] / mSigningDetails.signatures的值,此值就是apk对应的签名信息。

而每个apk包对应的PackageParser.Package保存在PackageManagerServicemPackages成员中。这是一个map表,键是包名,值就是PackageParser.Package,而apk的签名信息就保存在PackageParser.Package对象中的成员mSigningDetails.pastsigningcertificates[0] / mSigningDetails.signatures中。在apk安装的时候,会将解析的apk签名保存(put)在mPackages中。

总结:APK进程中获取自身签名实际就是获取PackageManagerServicemPackages成员中包名对应的PackageParser.Package.mSigningDetails.pastsigningcertificates[0] / mSigningDetails.signatures

PackageManagerService获取签名绕过

  1. APP进程直接通过getApplicationContext().getPackageManager().getPackageInfo(packagename, PackageManager.GET_SIGNATURES)获取签名信息
  2. APP进程利用Binder通讯直接向PackageManagerService发送TRANSACTION_getPackageInfo请求获取签名信息
  3. 将1和2java层的操作拿到native层利用反射执行同样的操作。
    以上获取签名的方式本质上都是获取PackageManagerServicemPackages成员中包名对应的PackageParser.Package.mSigningDetails.pastsigningcertificates[0] / mSigningDetails.signatures,只要在整个通讯的中间的任意一个位置进行hook就可以将签名信息进行替换,获取直接修改PackageManagerServicemPackages成员中包名对应的PackageParser.Package.mSigningDetails.pastsigningcertificates[0] / mSigningDetails.signatures值为指定签名就可以绕过上面的签名检测。