����frida ̽������ģ������arm so����
�����Ƕ���ģ�����µ�arm�µ�so�ļ����еķ���̽����ʵ���϶�����Щ��֪ʶ�ϣ����ص������Ǻ��ٵģ�����Ҳ���Ƕ���ģ�������о��ͷ�����
�������
����ʹ�õ���mumuģ�������е�frida����ģ����arm��so�ļ��ع���
��װmumuģ������MuMuģ��������_��12ģ����_��������ģ����
֮ͬǰ��������һ�������ƶ��˰�װ�϶�Ӧ��frida-server���Լ���Ӧ��PC�˰�װfrida��������֮ǰ��ʵ�Ǵ������
frida��14.2.18����
������PC�˵�����frida��14.2.18�汾�ģ�������һ��ʼ���Ե������ض�Ӧ��14.2.18�汾��frida-server��x86_64�ġ�
����
������ģ�����н���������ʱ�����ǻ��б����ģ����ǻ��ǻ�����frida-server�ķ����ģ����Ի���ȥ���Թ�ֱ��ע��frida�����dz����Ῠס��
ͨ��deepseek���鿴�����ؿ��ܳ��ֵ�����
�ڱ�����ģ������frida�Լ�frida-serverƥ����14.2.18�汾���ǻ����ּ��������ģ���������ȥ����ȥʵ�ָ�������frida�汾��frida-server�汾�IJ�����
frida��16.0.11
���ض�
pip install --upgrade frida==16.0.11
ͬʱ����frida-tools
pip install --upgrade frida-tools
�����
���ض�Ӧ��frida-server�汾
���ﲻ֪���Dz���ģ�������ص㣬���Ƕ�����mumuģ�����ģ���Ҫ��frida-server������Ӧ��Ŀ¼��û���Թ����Ż���ʲô���⣩
Ȼ�����dz����IJ����ˣ�����server����
adb push frida-server /data/local/tmp/
adb shell
su
chmod 777 /data/local/tmp/frida-server-16.0.11-android-x86_64
./data/local/tmp/frida-server-16.0.11-android-x86_64
������������֮����û���ٽ��б��������ˣ�ͬʱ����������fridaע��������������û������
��������Ϊ����spwned������bվ������frida�����ģ����Գ��������ˣ������ܹ�ʵ��ע��
��������̽��
�������Լ�����������ҵ��Ҫ������Ҫ��ȥ̽��android������ģ������so��ִ������֮���IJ�����
��������
����ȥ������HOOK��bվ��dlopen����������ִ�еõ���so�ļ���ʲô
function hook_dlopen() {
var interceptor = Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
{
onEnter: function (args) {
var pathptr = args[0];
if (pathptr !== undefined && pathptr != null) {
var path = ptr(pathptr).readCString();
console.log("[LOAD]", path)
}
}
}
)
return interceptor
}
setImmediate(hook_dlopen)
������ʵ������������frida������so��λ���ˣ����Է��ֵ��ǣ������ܹ�ȥ����dlopenȥʵ�ֶ��ڼ��ص�so�ļ����д�ӡ
�������
����ģ������X86_64�Ĺ���ģ����android����ʵ�ֵĶ��ڳ�����ִ�У�����ʹ�ò�ͬ�� dlopen ��������������so�ļ�������HOOK����Ҳ���Ľ�������
function hook_dlopen() {
// Hook ���п��ܵ� dlopen ����
const dlopenFuncs = [
'android_dlopen_ext',
'dlopen',
'__loader_dlopen'
];
let interceptors = [];
dlopenFuncs.forEach(funcName => {
let funcPtr = Module.findExportByName(null, funcName);
if (funcPtr) {
let interceptor = Interceptor.attach(funcPtr, {
onEnter: function(args) {
var pathptr = args[0];
if (pathptr && !pathptr.isNull()) {
var path = ptr(pathptr).readCString();
console.log("[LOAD]", path);
// �����Ƿ��ǿ��ɵļ�����
if (path && (path.includes("libtt") || path.includes("libbili") ||
path.includes("security") || path.includes("protect"))) {
console.warn("!!! Possible Frida detection library loaded:", path);
// ��ӡ����ջ��������λ˭������������
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n') + '\n');
}
}
}
});
interceptors.push(interceptor);
console.log(`Hooked ${funcName} at ${funcPtr}`);
}
});
// ���������������Ա���������
return interceptors;
}
// �ӳ�ִ���Ա����������ڼ��صĿ�
setImmediate(hook_dlopen);
�ԱȽ���������˼��������
��ʵ�ǿ��Է���ģ����Ҳ�ǹҵ��ˣ���������������˼������Ϊʲô�������������µ�HOOK��dlopen���غ����õ���so�ļ�����ģ������HOOK�õ���so�ļ�һ�㲻һ��
����bվ�İ汾��7.76.0�İ汾���������汾��������д�����ص�һ���ƹ�frida���������ӵģ�����frida������so��libmsaoaidsec.so��������ģ����������so������û�б� 'android_dlopen_ext', 'dlopen','__loader_dlopen'
�⼸��HOOK������û�н�����libmsaoaidsec.so������ô���ܻ�ȥ����ִ�����̵����⡣
�ܹ�֮���ļ�������
������ʵ��һ��ʼ����ģ�������о����٣����Ի�ȥ���ǵ���Ϊʲô����X86������X86_64�ļܹ���ģ��������ȥʵ��ARM�ܹ���ָ���
ͨ���������Ե�֪����Ҫ������ ��̬�����Ʒ��� �� ϵͳ���ļ��ݲ㼼��
��̬�����Ʒ��루Dynamic Binary Translation, DBT��
- ������ʵʱ�� ARM ָ�����鷭��Ϊ x86_64 ָ�
- ������
- ���� ARM ������ָ������
- ��ÿ�� ARM ָ���Ϊ��Ч�� x86_64 ָ�
- ���淭�����Ĵ��룬����ִ��ֱ�ӵ��û��档
ϵͳ����ת��
����������˼��֮������deepseek�õ��Ľ�����
��������
����������ʵ���ڰ������е�VMP�����ˣ��Զ����ܹ�ȥ�����Լ��ļ��ܺ�����ʵ�ְ��ղ�ͬ�IJ��������Ӽ��˳���λ������Щ����
ͬʱҲ������Ϊʲô��android���������������ֻ�����Ҫ�����ˣ���̬�����Ʒ����������������ֵ�˼·��ʵ����HOOKÿһ��ָ�Ȼ���Ĵ��룬��ARMתΪx86_64��ʵ��һ���ܹ���ת�䡣
ͬʱ��Ҳ�ǵ��������ϵ���������ʼ���ź��о�AOSPԴ���Ķ���ģ������ִ�����̴�����
AOSPԴ���еĶ���ģ������ִ�����̴���
����ǰ������Android�����˵�so�ļ�����ʵ��ִ�����̵�
�������ѡ�Android SO�ļ����ع���̽�� - �ᰮ�ƽ� - 52pojie.cn
������ƪ����ֻ�Ǿ������˶���android����Ҳ����arm�Ĵ�������û�ж���������ʵ�����µ�ģ��������so����ִ�����̷���������������������mumuģ�������������ڲ�ͬ�ܹ��µĴ�����
Android Native Bridge ����
����������Ҫ�˽����Android Native Bridge �������� MuMu ģ������ִ�� ARM �ܹ��� SO �ļ������������� �����Ʒ��� �� Android Native Bridge �������������Ͱ���������֮ǰ��˵����̬�����Ʒ������Ӷ�ʵ��֧�ֿ��ܹ����е�һ�����̡�
���������µ�ִ������
����������ͨ��System.load()
����
@CallerSensitive
public static void load(String filename) {
Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
}
�˷������յ��� Runtime.load0()
��Ȼ������ nativeLoad()
������
Runtime_nativeLoad
�� vm->LoadNativeLibrary
������֮��������OpenNaitveLibrary
���� JavaVMExt::LoadNativeLibrary
�����������ջ����� dlopen
���������� SO �ļ����ء�
vm->LoadNativeLibrary(env, filename.c_str(), javaLoader, caller, &error_msg);
�� Android 12 �����ϰ汾�������� android_dlopen_ext
���� __loader_android_dlopen_ext
��
void* __loader_android_dlopen_ext(const char* filename,
int flags,
const android_dlextinfo* extinfo,
const void* caller_addr) {
return dlopen_ext(filename, flags, extinfo, caller_addr);
}
�÷������յ��� dlopen_ext()
��
static void* dlopen_ext(const char* filename,
int flags,
const android_dlextinfo* extinfo,
const void* caller_addr) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
void* result = do_dlopen(filename, flags, extinfo, caller_addr);
return result;
}
do_dlopen(filename, flags, extinfo, caller_addr)
�� do_dlopen()
�������� find_library()
���� SO �ļ����������ء�
soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
�����Ƕ���soinfo�ĸ�ֵ��ͬʱ�����↑ʼ����so��.init_proc���������ŵ���.init_array�еĺ�������������JNI_OnLoad����������find_libraries ִ�������Ĵ�����
���ܼ���
ͬʱ��find_library��λ�ã������ֶ���ELF�ļ�ͷ��ȡ���ֶΣ�ͨ������ SO �ļ��� ELF ͷ��e_machine
�ֶΣ��жϼܹ��Ƿ�ƥ�䡣��ȷ�����ڹ��ܵļ���
��ʼ��Native Bridge
�������˶�Ӧ�ļܹ�������ARM����Ҫ����Native Bridgeת��ʱ����ô�ͻ�ʵ�ֳ�ʼ��Native Bridge
Native Bridge ����
��OpenNaitveLibrary�����У���ȥ�ж��Ƿ����ڴ���Native Bridge
���ľ��ߵ���ѡ��ԭ�� dlopen �� Native Bridge ����
ͨ������������Native Bridge���Ƿ���Ŀ�� SO ���� Native Bridge
���жϵ��ܹ�����ƥ����ʱ����Ҫȥ����Native Bridge ת���ܹ�ʵ�ֿ��ܹ�ִ�в�������ô�Ͳ�������dlopen�ĺ��������ǽ���NativeBridgeLoadLibrary
����ͼ
���˶���ģ��������so�Ĺ��̵����⣺
�µ�����
��ģ�����У����ܹ��� SO ���ػ�ͨ�� NativeBridgeLoadLibrary
���������DZ� dlopen
������
��������ͼ�Ƕ���ģ����ִ��so�ļ���������һ���˽⣬����������Ҫ��ʵ��HOOK����ô����������������������ȥHOOK dlopen�������ܹ�ȥ�õ�dlopen�IJ����Ӷ��õ����ص�so�ļ�����
��ô�Ƿ������ܹ�ȥHOOK NativeBridgeLoadLibrary
�����أ�NativeBridgeLoadLibrary����Native Bridge �������ĺ�����ͬʱҲ��AOSPԴ���еĺ����������ܷ�ȥ��λ������so�ļ��أ�
���������ʣ��Լ���һЩ�²⣬ȷʵ����ȥ����һ��
������Ϊ��ȥȷ��NativeBridgeLoadLibrary
�����������������Ĵ���
Java.perform(() => {
// ���� Native Bridge ��
const libnb = Module.load("libhoudini.so");
// ��ȡ NativeBridgeLoadLibrary ������ַ
const NBLoadLib = Module.getExportByName("libhoudini.so", "NativeBridgeLoadLibrary");
// Hook ����
Interceptor.attach(NBLoadLib, {
onEnter(args) {
const libpath = args[0].readCString(); // ��һ�������� SO ·��
const flag = args[1]; // �ڶ��������DZ�־λ (int)
console.log(`[NB] ���ؿ�: ${libpath}, flags=${flag}`);
// ��ѡ���۸ļ���·�������ض��������� SO��
if (libpath.includes("target.so")) {
args[0].writeUtf8String("/data/local/tmp/fake.so");
console.log("���ض��� SO ·����");
}
},
onLeave(retval) {
console.log(`[NB] ���ؾ���: ${retval}`);
}
});
});
����ʵ������û������������
ȥ�鿴�˶�Ӧ��libhoudini.so�ļ�������ʵ���ϵ����к������ţ����Dz�û��NativeBridgeLoadLibrary����
Java.perform(() => {
let libnb = Module.enumerateExportsSync("libhoudini.so");
libnb.forEach(exp => console.log(exp.name));
});
��ӡ��һ�·���
NativeBridgeItf
��NativeBridgeItf�� Native Bridge �ĺ��Ľӿڱ���ͨ������ loadLibrary�����Dz�֪������loadLibrary���������ṹ���е�ƫ��λ�á�
�����ҵ��뷨�ǣ���֪��ƫ�Ƶ�ַ�ͽ��б���HOOK�������п���loadLibrary������NativeBridgeItf�Ľṹ����ƫ�ƶ�����hook
Java.perform(() => {
const NativeBridgeItf = Module.findExportByName("libhoudini.so", "NativeBridgeItf");
const callbacks = NativeBridgeItf.readPointer();
// ���� 0x0 ~ 0x50 ��ƫ��
for (let offset = 0; offset < 0x50; offset += Process.pointerSize) {
const func = callbacks.add(offset).readPointer();
Interceptor.attach(func, {
onEnter(args) {
console.log(`[����] ƫ�� ${offset.toString(16)} �����ã�����: ${args[0]}`);
}
});
}
});
���������������ڴ汨��
���↑ʼȥ�˽��˶�������NativeBridgeItf �ṹ����ϸ�����ݣ�ʵ�����Ǵ��ڰ汾�����ġ�
1. �Ͱ汾��Android 5.0~7.0��
���ĺ���������ƫ�� 0x0 ~ 0x28
struct NativeBridgeItf {
// �����ֶ�
uint32_t version; // �汾�� (e.g., 1)
uint32_t padding; // �������� (64λ�¿��ܲ�����)
// ����ָ����
bool (*initialize)(const struct NativeBridgeRuntimeCallbacks* runtime_cbs); // 0x8 (64λ)
void* (*loadLibrary)(const char* libpath, int flag); // 0x10 (64λ)
void* (*getTrampoline)(void* handle, const char* name, const char* shorty); // 0x18 (64λ)
bool (*isCompatibleWith)(uint32_t bridge_version); // 0x20 (64λ)
void* (*getNativeAddress)(void* arm_address); // 0x28 (64λ)
// ... ������չ����
};
�ṹ���еĺ���ָ����ͨ��Ϊ loadLibrary
����Ӧƫ�ƹ̶����� 64 λ������ƫ�� 0x10
��
2.�߰汾��Android 8.0+��
struct NativeBridgeItf {
uint32_t version; // �汾�� (e.g., 2 �� 3)
uint32_t padding;
// �������������Ͱ汾��ͬ��
bool (*initialize)(...); // 0x8
void* (*loadLibrary)(...); // 0x10
// ��չ������������
void* (*loadLibraryExt)(const char* libpath, int flag, void* extinfo); // 0x18
void* (*getTrampolineExt)(...); // 0x20
void* (*createNamespace)(...); // 0x28
// ... ������չ����
};
������չ�ӿ� loadLibraryExt
������������ loadLibrary
��ƫ�ƿ��ܺ��ƣ��� 0x18
��
�ڹ̶���һ��NativeBridgeItf �ṹ��ƫ��֮�µ�����loadLibraryҲ�ǹ̶��ģ���ô������ʵ����ȥ���ǵõ������ṹ���ڶ�Ӧƫ�Ƶ�λ��ȥ�õ���Ӧ�ĵ�ַ
�����ܹ�����mumuģ����ģ������android12�汾�ģ����Զ�Ӧ������NativeBridgeItfҲ�Ƕ�Ӧ�ĸ߰汾�ϵĽ����塣
����ʵ����һֱ�ڱ��������յľ����ڴ�����֮������Ϣ�������һ��Ǵ���ȥ����ʵʵ����Դ��
IDA�����ṹ��
����������Щ����������ʵʵ������ʲô����
���Աȶ�������IDA�õ��Ľṹ���Ľṹȥ����AOSPԴ��
���Կ��������ǹ̶��ģ���ô���Ǿ�ȥ�Ҷ�Ӧ�ṹ�����Գ�Ա����һ�����ݵĴ�ӡ
��ԭ��ʵ��NativeBridgeItf�ṹ������
�����ȶ��˶��ڰ�12�Լ�IDAԴ�룬ֱ��ȥadd���ڵij�Ա����ƫ�����õ���Ӧ�Ľṹ����ֵ
Java.perform(() => {
console.log("\n====== ������Ϣ ======");
console.log(` ���̼ܹ�: ${Process.arch}`);
console.log(` ��ǰ�߳�ID: ${Process.getCurrentThreadId()}`);
const Build = Java.use("android.os.Build");
console.log("\n====== ģ����Ϣ ======");
const libhoudini = Module.findBaseAddress("libhoudini.so");
if (!libhoudini) {
console.error("[!] libhoudini.so ���");
return;
}
console.log(` libhoudini.so ��ַ: ${libhoudini}`);
console.log("\n====== NativeBridgeItf ������Ϣ ======");
const NativeBridgeItf = Module.findExportByName("libhoudini.so", "NativeBridgeItf");
if (!NativeBridgeItf) {
console.error("[!] �Ҳ��� NativeBridgeItf ����");
return;
}
console.log(` NativeBridgeItf ���ŵ�ַ: ${NativeBridgeItf}`);
console.log(` NativeBridgeItf ���ŵ�ַ ƫ��Ѱַ : ${libhoudini.add(0x0701D00)}`);
console.log("\n====== �ṹ��ָ����Ϣ ======");
const callbacks = NativeBridgeItf.readInt();
console.log(` version: ${callbacks}`);
const padding = NativeBridgeItf.add(0x4).readInt();
console.log(` padding: ${padding}`);
const initialize = NativeBridgeItf.add(0x8).readPointer();
console.log(` initialize addr: ${initialize}`);
const loadLibrary = NativeBridgeItf.add(0x10).readPointer();
console.log(` loadLibrary addr: ${loadLibrary}`);
const getTrampoline = NativeBridgeItf.add(0x18).readPointer();
console.log(` getTrampoline addr: ${getTrampoline}`);
const isSupported = NativeBridgeItf.add(0x20).readPointer();
console.log(` isSupported addr: ${isSupported}`);
const getAppEnv = NativeBridgeItf.add(0x28).readPointer();
console.log(` getAppEnv addr: ${getAppEnv}`);
const isCompatibleWith = NativeBridgeItf.add(0x30).readPointer();
console.log(` isCompatibleWith addr: ${isCompatibleWith}`);
const getSignalHandler = NativeBridgeItf.add(0x38).readPointer();
console.log(` getSignalHandler addr: ${getSignalHandler}`);
const unloadLibrary = NativeBridgeItf.add(0x40).readPointer();
console.log(` unloadLibrary addr: ${unloadLibrary}`);
const getError = NativeBridgeItf.add(0x48).readPointer();
console.log(` getError addr: ${getError}`);
const isPathSupported = NativeBridgeItf.add(0x50).readPointer();
console.log(` isPathSupported addr: ${isPathSupported}`);
const unused_initAnonymousNamespace = NativeBridgeItf.add(0x58).readPointer();
console.log(` unused_initAnonymousNamespace addr: ${unused_initAnonymousNamespace}`);
const createNamespace = NativeBridgeItf.add(0x60).readPointer();
console.log(` createNamespace addr: ${createNamespace}`);
const linkNamespaces = NativeBridgeItf.add(0x68).readPointer();
console.log(` linkNamespaces addr: ${linkNamespaces}`);
const loadLibraryExt = NativeBridgeItf.add(0x70).readPointer();
console.log(` loadLibraryExt addr: ${loadLibraryExt}`);
const getVendorNamespace = NativeBridgeItf.add(0x78).readPointer();
console.log(` getVendorNamespace addr: ${getVendorNamespace}`);
const getExportedNamespace = NativeBridgeItf.add(0x80).readPointer();
console.log(` getExportedNamespace addr: ${getExportedNamespace}`);
const preZygoteFork = NativeBridgeItf.add(0x88).readPointer();
console.log(` preZygoteFork addr: ${preZygoteFork}`);
});
�ܹ�������������Ҳ�ǰѶ�Ӧ�ij�Ա���Ե�ֵ����ӡ������
������Ȼ�������ォ��Щ���ݶ�����ӡ�����ˣ�����������ʵʵ������Ҫ�IJ�������loadLibrary��������Ϊ����һֱϣ���ɵ���������HOOK loadLibrary������������HOOK dlopen
Java.perform(() => {
console.log("\n====== ������Ϣ ======");
console.log(` ���̼ܹ�: ${Process.arch}`);
console.log(` ��ǰ�߳�ID: ${Process.getCurrentThreadId()}`);
const Build = Java.use("android.os.Build");
console.log("\n====== ģ����Ϣ ======");
const libhoudini = Module.findBaseAddress("libhoudini.so");
if (!libhoudini) {
console.error("[!] libhoudini.so ���");
return;
}
console.log(` libhoudini.so ��ַ: ${libhoudini}`);
console.log("\n====== NativeBridgeItf ������Ϣ ======");
const NativeBridgeItf = Module.findExportByName("libhoudini.so", "NativeBridgeItf");
if (!NativeBridgeItf) {
console.error("[!] �Ҳ��� NativeBridgeItf ����");
return;
}
console.log(` NativeBridgeItf ���ŵ�ַ: ${NativeBridgeItf}`);
console.log(` NativeBridgeItf ���ŵ�ַ ƫ��Ѱַ : ${libhoudini.add(0x0701D00)}`);
console.log("\n====== �ṹ��ָ����Ϣ ======");
const callbacks = NativeBridgeItf.readInt();
console.log(` version: ${callbacks}`);
const padding = NativeBridgeItf.add(0x4).readInt();
console.log(` padding: ${padding}`);
const initialize = NativeBridgeItf.add(0x8).readPointer();
console.log(` initialize addr: ${initialize}`);
const loadLibrary = NativeBridgeItf.add(0x10).readPointer();
console.log(` loadLibrary addr: ${loadLibrary}`);
const getTrampoline = NativeBridgeItf.add(0x18).readPointer();
console.log(` getTrampoline addr: ${getTrampoline}`);
const isSupported = NativeBridgeItf.add(0x20).readPointer();
console.log(` isSupported addr: ${isSupported}`);
const getAppEnv = NativeBridgeItf.add(0x28).readPointer();
console.log(` getAppEnv addr: ${getAppEnv}`);
const isCompatibleWith = NativeBridgeItf.add(0x30).readPointer();
console.log(` isCompatibleWith addr: ${isCompatibleWith}`);
const getSignalHandler = NativeBridgeItf.add(0x38).readPointer();
console.log(` getSignalHandler addr: ${getSignalHandler}`);
const unloadLibrary = NativeBridgeItf.add(0x40).readPointer();
console.log(` unloadLibrary addr: ${unloadLibrary}`);
const getError = NativeBridgeItf.add(0x48).readPointer();
console.log(` getError addr: ${getError}`);
const isPathSupported = NativeBridgeItf.add(0x50).readPointer();
console.log(` isPathSupported addr: ${isPathSupported}`);
const unused_initAnonymousNamespace = NativeBridgeItf.add(0x58).readPointer();
console.log(` unused_initAnonymousNamespace addr: ${unused_initAnonymousNamespace}`);
const createNamespace = NativeBridgeItf.add(0x60).readPointer();
console.log(` createNamespace addr: ${createNamespace}`);
const linkNamespaces = NativeBridgeItf.add(0x68).readPointer();
console.log(` linkNamespaces addr: ${linkNamespaces}`);
const loadLibraryExt = NativeBridgeItf.add(0x70).readPointer();
console.log(` loadLibraryExt addr: ${loadLibraryExt}`);
const getVendorNamespace = NativeBridgeItf.add(0x78).readPointer();
console.log(` getVendorNamespace addr: ${getVendorNamespace}`);
const getExportedNamespace = NativeBridgeItf.add(0x80).readPointer();
console.log(` getExportedNamespace addr: ${getExportedNamespace}`);
const preZygoteFork = NativeBridgeItf.add(0x88).readPointer();
console.log(` preZygoteFork addr: ${preZygoteFork}`);
Interceptor.attach(loadLibraryExt, {
onEnter: function(args) {
// ����ʵ�ʺ���ԭ���жϲ���������������һ������ΪҪ���صĿ�·��
var libName = Memory.readCString(args[0]);
console.log(" loadLibraryExt called with library name: " + libName);
},
onLeave: function(retval) {
console.log(" loadLibraryExt returned: " + retval);
}
});
});
HOOK loadLibraryExt
���˵�ַȥֱ��HOOK������HOOK loadLibraryExtȥʵ�ֵõ���ģ�����м��ع���so�ļ�
���������ǵõ������յĽ����ˣ�Ҳ������������HOOK dlopenһ���ˣ�����ȥHOOK ��loadLibraryExt�õ��˺��ֻ���һ���Ľ��������������յ�libmsaoaidsec.so�����Ƕ��ڼ��ع���so�ļ�������������
�ƹ�frida����
�������ѡ�bilibili XHS frida���������ƹ� - �ᰮ�ƽ� - 52pojie.cn
����ѡ����APP�� ����������7.76.0��������һ��ԭ��������֮ǰд��һƪ���������汾��frida�����ƹ����������Ѿ����ֻ���һ�����ܹ�ȥ��λfrida������so�ļ��ˡ�
- frida��patch������JNI_Onload֮ǰ��init֮���ġ�
- ������patch������__system_property_get("ro.build.version.sdk")��ʱ��
- HOOK��pthread_create������������libmsaoaidsec.so���濪���������߳�
- �ƹ��IJ�������ֱ��patch���������߳��ƹ���
Java.perform(() => {
console.log("\n====== ������Ϣ ======");
console.log(` ���̼ܹ�: ${Process.arch}`);
console.log(` ��ǰ�߳�ID: ${Process.getCurrentThreadId()}`);
const libhoudini = Module.findBaseAddress("libhoudini.so");
if (!libhoudini) {
console.error("[!] libhoudini.so ���");
return;
}
console.log(` libhoudini.so ��ַ: ${libhoudini}`);
const NativeBridgeItf = Module.findExportByName("libhoudini.so", "NativeBridgeItf");
if (!NativeBridgeItf) {
console.error("[!] �Ҳ��� NativeBridgeItf ����");
return;
}
console.log(` NativeBridgeItf ���ŵ�ַ: ${NativeBridgeItf}`);
// �����ṹ��ָ��
console.log("\n====== �ṹ��ָ����Ϣ ======");
const offsets = {
version: 0x0, padding: 0x4, initialize: 0x8, loadLibrary: 0x10,
getTrampoline: 0x18, isSupported: 0x20, getAppEnv: 0x28,
isCompatibleWith: 0x30, getSignalHandler: 0x38, unloadLibrary: 0x40,
getError: 0x48, isPathSupported: 0x50, unused_initAnonymousNamespace: 0x58,
createNamespace: 0x60, linkNamespaces: 0x68, loadLibraryExt: 0x70,
getVendorNamespace: 0x78, getExportedNamespace: 0x80, preZygoteFork: 0x88
};
Object.keys(offsets).forEach(name => {
console.log(` ${name} addr: ${NativeBridgeItf.add(offsets[name]).readPointer()}`);
});
// Hook loadLibraryExt
Interceptor.attach(NativeBridgeItf.add(offsets.loadLibraryExt).readPointer(), {
onEnter: function(args) {
var libName = Memory.readCString(args[0]);
console.log(` loadLibraryExt called with: ${libName}`);
if (libName.includes("libmsaoaidsec.so")) {
console.log("hooking libmsaoaidsec.so");
hook_system_property_get();
}
},
onLeave: function(retval) {
console.log(` loadLibraryExt returned: ${retval}`);
}
});
});
function hook_system_property_get() {
var addr = Module.findExportByName(null, "__system_property_get");
if (!addr) {
console.log("__system_property_get not found");
return;
}
console.log("hooking __system_property_get");
Interceptor.attach(addr, {
onEnter: function(args) {
var name = ptr(args[0]).readCString();
if (name.includes("ro.build.version.sdk")) {
console.log("Found ro.build.version.sdk, patching...");
setTimeout(hook_pthread_create, 100);
}
}
});
}
function call_function(){
console.log("alearly patch frida");
}
function hook_pthread_create() {
var pthread_create = Module.findExportByName("libc.so", "pthread_create");
if (!pthread_create) {
console.log("pthread_create not found");
return;
}
var libmsaoaidsec = Process.findModuleByName("libmsaoaidsec.so");
if (!libmsaoaidsec) {
console.log("libmsaoaidsec.so not found");
return;
}
console.log(`libmsaoaidsec.so base: ${libmsaoaidsec.base}`);
Interceptor.attach(pthread_create, {
onEnter: function(args) {
var thread_ptr = args[2];
if (thread_ptr.compare(libmsaoaidsec.base) < 0 ||
thread_ptr.compare(libmsaoaidsec.base.add(libmsaoaidsec.size)) >= 0) {
console.log(`pthread_create other thread: ${thread_ptr}`);
} else {
console.log(`pthread_create libmsaoaidsec.so thread: ${thread_ptr}, offset: ${thread_ptr.sub(libmsaoaidsec.base)}`);
[0x1c544, 0x1b8d4, 0x26e5c].forEach(offset => {
Interceptor.replace(libmsaoaidsec.base.add(offset),
new NativeCallback(() => console.log(`Interceptor.replace: 0x${offset.toString(16)}`), "void", [])
);
});
}
}
});
}
�����ƹ���frida���⣬������call_function��������ӡ��һ���ַ���
�ܽ
����ֻ�Ƕ�����ģ����������ʵ�ֿ��ܹ�����so���ص�̽�����̣�����ʱ���е��̣����кܶ���ϸ��û��ϸ�µ��о���ֻ�Ƕ�������ģ����so������������һ��СС���жϡ�
��������hook dlopen�ķ�����ȥHOOK NativeBridgeLoadLibrary ��ȥ�õ���Ӧ��frida������so�ļ�������ȥ��ԭ��NativeBridgeItf�����ṹ�壬Ҳ������ȥ�õ���loadLibraryExt������ַ��������HOOK loadLibraryExt��Ҳ�ǵõ��˺�֮ǰ�ֻ���һ���Ľ�����
֮��Ҳ�Ǹ������Լ����ֻ��˵��ƹ�frida���⣬Ҳ�dzɹ��ƹ���
����ȷʵ����һЩ����android�����������⣬�������ֿ��ܹ��Ĺ��̣��ñ����������а�ÿһ��ָ����������Ȼ���ö�Ӧ�ļܹ�����ȥ���ͣ�Ȼ��ʵ�����Լ��ļܹ����������������أ�ȷʵ���ڰ�����������һЩ��ʶ��