https://developer.android.com/google/play/integrity/standard?hl=zh-cn#overview 官方文档

https://stackoverflow.com/questions/72395653/how-to-call-decodeintegritytoken-api

https://stackoverflow.com/questions/72193058/google-playintegrity-api-a-nightmare 搭建指导

搭建使用的代码

        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());


        // Create an instance of a manager.
        StandardIntegrityManager standardIntegrityManager =
                IntegrityManagerFactory.createStandard(this.getApplicationContext());

        long cloudProjectNumber = 0L; // project number

        // Prepare integrity token. Can be called once in a while to keep internal
        // state fresh.
        standardIntegrityManager.prepareIntegrityToken(
                        StandardIntegrityManager.PrepareIntegrityTokenRequest.builder()
                                .setCloudProjectNumber(cloudProjectNumber)
                                .build())
                .addOnSuccessListener(
                    tokenProvider -> {
                        Log.e("TAG","provider");
                        integrityTokenProvider = tokenProvider;
                        String requestHash = "2cp24zlkjlkjlklklk";
                        Task<StandardIntegrityToken> integrityTokenResponse =
                                integrityTokenProvider.request(
                                        StandardIntegrityManager.StandardIntegrityTokenRequest.builder()
                                                .setRequestHash(requestHash)
                                                .build());
                        integrityTokenResponse
                                .addOnSuccessListener(
                                        new OnSuccessListener<StandardIntegrityToken>() {
                                            @Override
                                            public void onSuccess(StandardIntegrityToken standardIntegrityToken) {
                                                Log.e("TAG","standardIntegrityToken onSuccess");
                                                String token = standardIntegrityToken.token();
                                                DecodeIntegrityTokenRequest requestObj = new DecodeIntegrityTokenRequest();
                                                requestObj.setIntegrityToken(token);
                                                //Configure your credentials from the downloaded Json file from the resource
                                                GoogleCredentials credentials = null;
                                                try {
                                                    credentials = GoogleCredentials.fromStream(Objects.requireNonNull(getClass().getClassLoader()).getResourceAsStream("credentials.json"));
                                                } catch (IOException e) {
                                                    Log.e("TAG","standardIntegrityToken error");
                                                    throw new RuntimeException(e);
                                                }
                                                HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);

                                                HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
                                                JsonFactory JSON_FACTORY  = new JacksonFactory();
                                                GoogleClientRequestInitializer initializer = new PlayIntegrityRequestInitializer();

                                                PlayIntegrity.Builder playIntegrity = new PlayIntegrity.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).setApplicationName("com.example.myapplication")
                                                        .setGoogleClientRequestInitializer(initializer);
                                                PlayIntegrity play  = playIntegrity.build();

                                                Thread thread = new Thread(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        try  {
                                                            DecodeIntegrityTokenResponse response = play.v1().decodeIntegrityToken("com.example.myapplication", requestObj).execute();
                                                            Log.d("TAG" ,"licensingVerdict\t" +  response.getTokenPayloadExternal().getDeviceIntegrity().toString());                                                            String licensingVerdict = response.getTokenPayloadExternal().getAccountDetails().getAppLicensingVerdict();
                                                            Log.d("TAG" ,"licensingVerdict\t" +licensingVerdict );
                                                            if (licensingVerdict.equalsIgnoreCase("LICENSED")) {
                                                                Log.d("TAG" ,"LICENSED APP");
                                                                // Looks good! LICENSED app
                                                            } else {
                                                                Log.d("TAG" ,"LICENSED not APP");
                                                                // LICENSE NOT OK
                                                            }
                                                        } catch (Exception e) {
                                                            Log.d("TAG" ,"LICENSED error "+  e.getMessage());
                                                            //  LICENSE error
                                                        }
                                                    }
                                                });
                                                thread.start();

                                            }
                                        }
//                                        (response) -> {
//                                            Log.e("TAG" , response.token());
//                                        }
                                )
                                .addOnFailureListener((param1)->{
                                    Log.e("TAG","error2");
                                });

                    }
                )
                .addOnFailureListener((param1)->{
                    Log.e("TAG","error " + param1.getMessage());
                });




//                .addOnFailureListener(exception -> handleError(exception));

        TextView tv = binding.sampleText;
        tv.setText(stringFromJNI());

高度依赖google play 商城,未安装google play商城 或者版本过低,都不能给出判断结果;

未安装google play

模拟器 提示google play 版本过低

magisk 设备 划为不可信设备

deviceIntegrity 值为空

经过反复刷机验证,控制单一变量,刷入原厂的镜像时 ,flash为lock 或 unlock , play integrity 判定为正常 或异常设备。

对比lock 和 unlock前后的系统属性,取其中关键的属性;

  1. ro.boot.vbmeta.device_state
  2. ro.boot.verifiedbootstate
  3. ro.boot.veritymode
  4. ro.boot.flash.locked

将属性设置成locked时的属性. 仍不能饶过 Play integrity。

研究PlayIntegrityFix 插件:

核心的两个功能

  • 伪造设备信息,如图,但是实际上,我就自己的设备信息,然后把FIRST_API_LEVEL改为23,配合第二个功能,也能饶过
  • UnsupportedOperationException ,检测到DroidGuard时抛出异常。

https://github.com/chiteroman/PlayIntegrityFix magisk 绕过插件

分类: 安卓

pareto

未来什么方向不管,先做自己喜欢做的事情。

0 条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注