안 드 로 이 드 가 블랙리스트 반사 하 는 방법
구 글 은 안 드 로 이 드 P 부터 비공개 API 에 대한 규 제 를 도입 했다.이 는 네 이 티 브 와 관련 된 소스 코드 에서 규제 의 원 리 를 찾 아 해결 방법 을 찾 을 수 있 지만 불필요 한 이유 로 이러한 규제 에 도전 하 는 것 을 권장 하지 않 는 다.후속 버 전에 서 제한 이 있 을 지 모 르 기 때문에 유지 하기 가 매우 번거롭다.
Native 층 에 몇 개의 접근 단계 가 있 습 니 다.
class HiddenApiAccessFlags {
  public:
  enum ApiList {
    kWhitelist = 0,
    kLightGreylist,
    kDarkGreylist,
    kBlacklist,
  };
}
enum Action {
  kAllow,     //  
  kAllowButWarn, //  ,     
  kAllowButWarnAndToast, //  ,        
  kDeny  //    
};시스템 클래스 위장
블랙리스트 시스템 에 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.invokeAPI 호출 을 숨 기 는 것 은'면제'조건 이 있 습 니 다.즉,면제 되 는 것 이 라면 블랙리스트 에 있 더 라 도 방 행 됩 니 다.이러한 방식 은 자바 층 에 노출 되 었 기 때문에 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"});
  }
}이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.