안 드 로 이 드 가 블랙리스트 반사 하 는 방법

제한 원리
구 글 은 안 드 로 이 드 P 부터 비공개 API 에 대한 규 제 를 도입 했다.이 는 네 이 티 브 와 관련 된 소스 코드 에서 규제 의 원 리 를 찾 아 해결 방법 을 찾 을 수 있 지만 불필요 한 이유 로 이러한 규제 에 도전 하 는 것 을 권장 하지 않 는 다.후속 버 전에 서 제한 이 있 을 지 모 르 기 때문에 유지 하기 가 매우 번거롭다.
Native 층 에 몇 개의 접근 단계 가 있 습 니 다.

class HiddenApiAccessFlags {
  public:
  enum ApiList {
    kWhitelist = 0,
    kLightGreylist,
    kDarkGreylist,
    kBlacklist,
  };
}
그리고 대응 하 는 응답 단계 가 몇 개 더 있 습 니 다.

enum Action {
  kAllow,     //  
  kAllowButWarn, //  ,     
  kAllowButWarnAndToast, //  ,        
  kDeny  //    
};
여기 서 인터넷 의 해결 방식 을 소개 합 니 다.그 밖 에 우리 가 반사 방법 을 호출 한 클래스 의 로 더 를 시스템 클래스 로 설정 하면 Native 층 의 제한 을 돌아 갈 수 있 습 니 다.
시스템 클래스 위장
블랙리스트 시스템 에 fncaller_is_trusted 의 조건:호출 자가 시스템 클래스 라면 호출 을 허용 합 니 다.즉,우리 가 시스템 류 의 신분 으로 반사 할 수 있다 면 막힘 이 없 을 것 이다.
4.567917.먼저 반사 API 를 통 해 getDeclared Method 방법 을 얻 을 수 있 습 니 다.getDeclared Method 는 Public 입 니 다.문제 가 없습니다.이것 은 반 사 를 통 해 얻 은 방법 을 인터넷 에서 원 반사 방법 이 라 고 부른다4.567917.그리고 방금 원 반사 방법 을 통 해 getDeclard Method 를 반사 적 으로 호출 합 니 다.여기 서 우 리 는 시스템 신분 으로 반사 하 는 목적 을 실현 했다.반사 와 관련 된 API 는 모두 시스템 류 이기 때문에 우리 의 메타 반사 방법 도 시스템 류 에 의 해 로드 되 는 방법 이다.그래서 우리 의 메타 반사 방법 이 호출 된 getDeclard Method 는 시스템 호출 으로 여 겨 지고 임의의 방법 을 반사 할 수 있 습 니 다의사 코드 는 다음 과 같 습 니 다:

//   API,   
Method metaGetDeclaredMethod = Class.class.getDeclaredMethod("getDeclardMethod");
//             API,      。
Method hiddenMethod = metaGetDeclaredMethod.invoke(hiddenClass, "hiddenMethod", "hiddenMethod    ");
//      Method       
hiddenMethod.invoke
면제 조건
API 호출 을 숨 기 는 것 은'면제'조건 이 있 습 니 다.즉,면제 되 는 것 이 라면 블랙리스트 에 있 더 라 도 방 행 됩 니 다.이러한 방식 은 자바 층 에 노출 되 었 기 때문에 VMRuntime.setHiddenapiExemptions 방법 을 통 해 이 루어 질 수 있다.위의 이 방법 을 결합 하면 우 리 는'원 반사'를 통 해 VMRuntime.setHiddenapiExemptions 를 반사 적 으로 호출 하면 우리 가 사용 하고 자 하 는 숨겨 진 API 를 모두 면제 할 수 있 습 니 다.또한 시스템 은 면 제 를 검사 할 때 방법 서명 을 통 해 접두사 가 일치 하고 자바 방법 서명 은 L 로 시작 하기 때문에 우 리 는 직접 L 을 전송 할 수 있 습 니 다.그러면 모든 숨겨 진 API 가 사면 되 었 습 니 다!
소스 코드 는 인터넷 대기업 의 오픈 소스 프로젝트 를 직접 참고 한다FreeReflection

public final class BootstrapClass {

  private static final String TAG = "BootstrapClass";

  private static Object sVmRuntime;
  private static Method setHiddenApiExemptions;

  static {
    if (SDK_INT >= Build.VERSION_CODES.P) {
      try {
        Method forName = Class.class.getDeclaredMethod("forName", String.class);
        Method getDeclaredMethod = Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class);

        Class<?> vmRuntimeClass = (Class<?>) forName.invoke(null, "dalvik.system.VMRuntime");
        Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "getRuntime", null);
        setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "setHiddenApiExemptions", new Class[]{String[].class});
        sVmRuntime = getRuntime.invoke(null);
      } catch (Throwable e) {
        Log.w(TAG, "reflect bootstrap failed:", e);
      }
    }
  }

  /**
   * make the method exempted from hidden API check.
   *
   * @param method the method signature prefix.
   * @return true if success.
   */
  public static boolean exempt(String method) {
    return exempt(new String[]{method});
  }

  /**
   * make specific methods exempted from hidden API check.
   *
   * @param methods the method signature prefix, such as "Ldalvik/system", "Landroid" or even "L"
   * @return true if success
   */
  public static boolean exempt(String... methods) {
    if (sVmRuntime == null || setHiddenApiExemptions == null) {
      return false;
    }

    try {
      setHiddenApiExemptions.invoke(sVmRuntime, new Object[]{methods});
      return true;
    } catch (Throwable e) {
      return false;
    }
  }

  /**
   * Make all hidden API exempted.
   *
   * @return true if success.
   */
  public static boolean exemptAll() {
    return exempt(new String[]{"L"});
  }
}
이상 은 안 드 로 이 드 가 블랙 리스트 를 반사 하 는 방법 에 대한 상세 한 내용 입 니 다.안 드 로 이 드 가 블랙 리스트 를 반사 하 는 방법 에 대한 자 료 는 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기