andfix 의 자바 hook 프로 세 스

5016 단어 androidndk자바
andfix 의 자바 hook 프로 세 스:
원 리 는 자바 함 수 를 native 함수 로 설명 한 다음 자바 함수 가 dvm 에 대응 하 는 method 구조 체 지침 을 가 져 와 구성원 데이터 의 지침 을 교체 하여 자바 hook 을 실현 하 는 것 입 니 다.
기본 방법:
setup  replaceMethod(src, dest); setFieldFlag
dalvik 모드 에서 자바 hook 1, libdvm. so 에서 dvmDecodeIndirectRef 함수 포인 터 를 동적 으로 가 져 오고 dvmThreadSelf 함수 포인 터 를 가 져 옵 니 다.
2. dest 의 Method. getDeclaringClass 방법 으로 method 의 클래스 대상 clazz 를 가 져 옵 니 다.
3. dvmDecodeIndirectRef 방법 을 호출 하여 clazz 의 ClassObject * 를 가 져 옵 니 다.
4. env -> FromReflected Method 를 통관 하 는 방법 으로 dest 의 Method 구조 체 함수 지침 가 져 오기
5. method 구조 체 의 구성원 데이터 교체
 method 구조 체 의 클래스 대상 포인터 clazz 교체
 method 구조 체 의 accessFlags 교체
 method 구조 체 의 방법 을 바 꾸 는 색인 methodIndex
 method 구조 체 의 캐 시 를 바 꾸 는 JNI 인자 jniArgInfo
 method 구조 체 를 교체 하 는 insSize
 method 구조 체 를 교체 하 는 방법 원형 설명 prototype
 method 구조 체 의 실제 코드 인 센 스 를 교체 합 니 다.
 method 구조 체 의 실제 함수 나 JNI 브리지 함수 교체
6. 구성원 도 메 인의 방문 표 지 를 설정 합 니 다.
Dalvik 모드 에서 자바 hook 완성
android 5.0 이상.
art 모드 에서 자바 훅
1. art 모드 에서 우 리 는 env -> FromReflected Method 를 통 해 ArtMethod 함수 지침 을 직접 얻 을 수 있 습 니 다.
2. 그리고 ArtMethod 구조 체 의 구성원 데이터 포인 터 를 직접 교체 합 니 다.
ArtMethod 의 class 교체로 더 포인터
ArtMethod 를 대체 하 는 clinitthread_id_포인터
ArtMethod 의 status 교체포인터
ArtMethod 의 declaring 바 꾸 기class_포인터
ArtMethod 의 access 교체flags_포인터
ArtMethod 를 대체 하 는 methodindex_포인터
ArtMethod 의 ptr 바 꾸 기sized_fields_포인터
3. 구성원 도 메 인의 방문 표 지 를 설정 합 니 다.
마지막 으로 아 트 모드 의 자바 훅 완성
/*
 *
 * Copyright (c) 2015, alipay.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * 	dalvik_method_replace.cpp
 *
 * @author : [email protected]
 *
 */
#include 
#include 
#include 
#include 

#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "dalvik.h"
#include "common.h"

static void* dvm_dlsym(void *hand, const char *name) {
	void* ret = dlsym(hand, name);
	char msg[1024] = { 0 };
	snprintf(msg, sizeof(msg) - 1, "0x%x", ret);
	LOGD("%s = %s
", name, msg); return ret; } extern jboolean __attribute__ ((visibility ("hidden"))) dalvik_setup( JNIEnv* env, int apilevel) { void* dvm_hand = dlopen("libdvm.so", RTLD_NOW); if (dvm_hand) { dvmDecodeIndirectRef_fnPtr = dvm_dlsym(dvm_hand, apilevel > 10 ? "_Z20dvmDecodeIndirectRefP6ThreadP8_jobject" : "dvmDecodeIndirectRef"); if (!dvmDecodeIndirectRef_fnPtr) { return JNI_FALSE; } dvmThreadSelf_fnPtr = dvm_dlsym(dvm_hand, apilevel > 10 ? "_Z13dvmThreadSelfv" : "dvmThreadSelf"); if (!dvmThreadSelf_fnPtr) { return JNI_FALSE; } jclass clazz = env->FindClass("java/lang/reflect/Method"); jClassMethod = env->GetMethodID(clazz, "getDeclaringClass", "()Ljava/lang/Class;"); return JNI_TRUE; } else { return JNI_FALSE; } } extern void __attribute__ ((visibility ("hidden"))) dalvik_replaceMethod( JNIEnv* env, jobject src, jobject dest) { jobject clazz = env->CallObjectMethod(dest, jClassMethod); ClassObject* clz = (ClassObject*) dvmDecodeIndirectRef_fnPtr( dvmThreadSelf_fnPtr(), clazz); clz->status = CLASS_INITIALIZED; Method* meth = (Method*) env->FromReflectedMethod(src); Method* target = (Method*) env->FromReflectedMethod(dest); LOGD("dalvikMethod: %s", meth->name); meth->clazz = target->clazz; meth->accessFlags |= ACC_PUBLIC; meth->methodIndex = target->methodIndex; meth->jniArgInfo = target->jniArgInfo; meth->registersSize = target->registersSize; meth->outsSize = target->outsSize; meth->insSize = target->insSize; meth->prototype = target->prototype; meth->insns = target->insns; meth->nativeFunc = target->nativeFunc; } extern void dalvik_setFieldFlag(JNIEnv* env, jobject field) { Field* dalvikField = (Field*) env->FromReflectedField(field); dalvikField->accessFlags = dalvikField->accessFlags & (~ACC_PRIVATE) | ACC_PUBLIC; LOGD("dalvik_setFieldFlag: %d ", dalvikField->accessFlags); }

좋은 웹페이지 즐겨찾기