最近在帮朋友解决一些任务时,有些比较复杂的任务需要批量使用模拟器,但是模拟器存在一个缺点,就是缺少很多物理功能,比如说陀螺仪、温度传感器和生物识别模块等等,但是有些任务是需要这些功能的。没有办法,只能自己去想办法解决这些先天缺陷。
由于模拟器本身不存在指纹,因此我们在询问android
系统时,对应的系统方法是这个:
package android.hardware.biometrics;public class BiometricManager {@Deprecated@RequiresPermission(USE_BIOMETRIC)@BiometricErrorpublic int canAuthenticate() {@BiometricError final int result = canAuthenticate(mContext.getUserId(),Authenticators.BIOMETRIC_WEAK);FrameworkStatsLog.write(FrameworkStatsLog.AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED,false /* isAllowedAuthenticatorsSet */, Authenticators.EMPTY_SET, result);FrameworkStatsLog.write(FrameworkStatsLog.AUTH_DEPRECATED_API_USED,AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_BIOMETRIC_MANAGER_CAN_AUTHENTICATE,mContext.getApplicationInfo().uid,mContext.getApplicationInfo().targetSdkVersion);return result;}}
如果能 hook 这个方法,返回 success
标志,替代系统告诉使用者,我假装可以进行生物识别(生物识别包含指纹识别和人脸识别),解决完这个问题之后,我们再次需要进入生物验证方法:
@RequiresPermission(USE_BIOMETRIC)public void authenticate(@NonNull CryptoObject crypto,@NonNull CancellationSignal cancel,@NonNull @CallbackExecutor Executor executor,@NonNull AuthenticationCallback callback) {FrameworkStatsLog.write(FrameworkStatsLog.AUTH_PROMPT_AUTHENTICATE_INVOKED,true /* isCrypto */,mPromptInfo.isConfirmationRequested(),mPromptInfo.isDeviceCredentialAllowed(),mPromptInfo.getAuthenticators() != Authenticators.EMPTY_SET,mPromptInfo.getAuthenticators());// Disallow explicitly setting any non-Strong biometric authenticator types.@Authenticators.Types int authenticators = mPromptInfo.getAuthenticators();if (authenticators == Authenticators.EMPTY_SET) {authenticators = Authenticators.BIOMETRIC_STRONG;}final int biometricStrength = authenticators & Authenticators.BIOMETRIC_WEAK;if ((biometricStrength & ~Authenticators.BIOMETRIC_STRONG) != 0) {throw new IllegalArgumentException("Only Strong biometrics supported with crypto");}authenticateInternal(crypto, cancel, executor, callback, mContext.getUserId());}
这个authenticate
方法中存在四个参数,其实我们只需要关注AuthenticationCallback
这个抽象类,可以查看一下这个抽象类:
public abstract static class AuthenticationCallback extendsBiometricAuthenticator.AuthenticationCallback {// 验证失败时执行@Overridepublic void onAuthenticationError(int errorCode, CharSequence errString) {}// 验证成功时执行public void onAuthenticationSucceeded(AuthenticationResult result) {}}
那么只需要 hook 这个方法,直接使得AuthenticationCallback
调用onAuthenticationSucceeded
方法即可。
找到了系统需要 hook 的点,那么就可以请出我们的终极武器frida
框架了,这里不说明frida
框架的入门了,大家可以找找其他参考教程。
我们直接启动frida-server
,然后通过frida
注入js hook 代码,覆盖掉系统的返回,即可得到我们的答案。比如可以看到结论图:
当然,这只是我的思路,如果有更好的想法和方案,我们可以共同交流,wx:javainstalling, 暗号:指纹。