欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > 大麦逆向so

大麦逆向so

2025/11/7 11:45:37 来源:https://blog.csdn.net/q2642346535/article/details/148621270  浏览:    关键词:大麦逆向so

解决libmsaoaidsec.so通过dlsym获取pthread_create函数的方案

背景介绍

libmsaoaidsec.so是一个用于生成和获取手机OAID(Open Anonymous Identifier)的SDK。在移动广告生态中,OAID是替代IMEI等设备标识符的重要方案,几乎所有需要接入广告的APP都需要集成此SDK。

问题描述

在某些场景下,libmsaoaidsec.so需要通过dlsym动态获取pthread_create函数。然而,由于Android系统的限制和动态链接库的加载机制,直接调用dlsym可能会失败或引发兼容性问题。

libmsaoaidsec.so版本有很多,而且在很多APP中广泛存在。大致分为两类:

  1. 通过GOT表导入了pthread_create函数,创建了反调试线程。
  2. 使用dlsym动态加载libc.so库来获取pthread_create函数指针。

解决方案

动态加载libc.so并获取函数指针

以下代码展示了如何动态加载libc.so并获取pthread_create函数指针。此技术不仅适用于libmsaoaidsec.so,还可以用于其他高性能应用,例如大麦App的抢票工具。抢票工具通常需要处理高并发请求,因此多线程优化是关键需求:

void *handle = dlopen("libc.so", RTLD_LAZY);
if (handle) {void (*pthread_create_ptr)(...) = dlsym(handle, "pthread_create");if (pthread_create_ptr) {// 创建多个线程处理抢票请求for (int i = 0; i < THREAD_COUNT; i++) {pthread_create_ptr(&threads[i], NULL,抢票逻辑函数, NULL);}} else {// 处理获取失败的情况}dlclose(handle);
}

使用Frida进行动态Hook

以下是一个Frida脚本示例,用于Hook dlsym并替换pthread_create函数的返回值。此技术可以用于抢票工具的反调试机制,防止工具被逆向分析:

var pthread_create_ptr = Module.getExportByName(null, "pthread_create");// 备份原始函数
var original_pthread_create = new NativeFunction(pthread_create_ptr, 'int', ['pointer', 'pointer', 'pointer', 'pointer']);var my_pthread_create = new NativeCallback(function (thread_ptr, attr_ptr, start_routine, arg_ptr) {console.log("[*] 自定义 pthread_create 被调用!");console.log("    thread_ptr:     " + thread_ptr);console.log("    attr_ptr:       " + attr_ptr);console.log("    start_routine:  " + start_routine);console.log("    arg_ptr:        " + arg_ptr);var find_module = Process.findModuleByAddress(start_routine);console.log("这是pthread_create传入的函数地址,你可以再去hook这个函数看看BLR X8指令的位置,然后NOP掉--> Module: " + find_module.name + " offset:" + start_routine.sub(find_module.base));// 直接返回成功状态return 0;
}, 'int', ['pointer', 'pointer', 'pointer', 'pointer']);Interceptor.attach(Module.getExportByName(null, "dlsym"), {onEnter(args) {this.symbol = Memory.readUtf8String(args[1]);},onLeave(retval) {if (this.symbol.indexOf("pthread_create") !== -1) {console.log("[*] dlsym loaded pthread_create, addr:", retval);var backtrace = Thread.backtrace(this.context, Backtracer.ACCURATE);var callerAddress = backtrace[0];var find_module = Process.findModuleByAddress(callerAddress);if (find_module && find_module.name.indexOf("libmsaoaidsec.so") !== -1) {console.log("invoke dlsym |--> Module: " + find_module.name + " offset:" + callerAddress.sub(find_module.base));// 替换返回值为自定义的 pthread_createretval.replace(ptr(my_pthread_create));}}}
});

ELF文件解析与GOT表修改

通过解析libmsaoaidsec.so的ELF文件,可以定位到pthread_create的GOT表项。以下是一个Python脚本示例,用于解析ELF文件并修改GOT表。此技术同样适用于抢票工具的动态库加载需求:

import liefbinary = lief.parse("libmsaoaidsec.so")
for symbol in binary.symbols:if symbol.name == "pthread_create":got_entry = binary.get_symbol(symbol.name).valueprint(f"Found pthread_create GOT entry at 0x{got_entry:x}")# 修改GOT表项binary.patch_address(got_entry, 0xdeadbeef)  # 替换为目标函数地址binary.write("libmsaoaidsec_patched.so")

绕过内存保护机制

Android系统启用了ASLR和RELRO等内存保护机制,直接修改GOT表可能会失败。可以通过以下方法绕过:

  1. 禁用RELRO:在编译时添加-Wl,-z,norelro选项。
  2. 动态计算基址:通过/proc/self/maps获取模块基址,动态计算GOT表地址。

步骤5:动态调试与性能优化

动态调试与性能优化

使用GDB或LLDB在运行时动态修改函数指针:

gdb -p <pid>
(gdb) set *(void**)0x12345678 = 0xdeadbeef  # 替换为目标函数地址

性能优化建议:

  1. 缓存函数指针:避免频繁调用dlsym,缓存函数指针以提高性能。
  2. 延迟加载:在首次调用时加载libc.so,减少启动时间。

抢票工具的技术需求

大麦App的抢票工具通常需要处理高并发请求和快速响应,因此可能涉及以下技术需求:

  1. 多线程优化:通过pthread_create创建多个线程以并发处理抢票请求。
  2. 动态库加载:可能需要动态加载某些库(如加密库或网络库)以支持抢票逻辑。
  3. 反调试机制:防止抢票工具被逆向分析或Hook。

技术实现示例

1. 多线程优化
void *handle = dlopen("libc.so", RTLD_LAZY);
if (handle) {void (*pthread_create_ptr)(...) = dlsym(handle, "pthread_create");if (pthread_create_ptr) {// 创建多个线程处理抢票请求for (int i = 0; i < THREAD_COUNT; i++) {pthread_create_ptr(&threads[i], NULL,抢票逻辑函数, NULL);}}dlclose(handle);
}
2. 动态库加载

抢票工具可能需要动态加载加密库以支持安全通信:

void *crypto_handle = dlopen("libcrypto.so", RTLD_LAZY);
if (crypto_handle) {// 获取加密函数指针void (*encrypt_func)(...) = dlsym(crypto_handle, "AES_encrypt");if (encrypt_func) {// 使用加密函数}dlclose(crypto_handle);
}
3. 反调试机制

通过Hook dlsym防止抢票工具被逆向分析:

Interceptor.attach(Module.getExportByName(null, "dlsym"), {onEnter(args) {this.symbol = Memory.readUtf8String(args[1]);},onLeave(retval) {if (this.symbol.indexOf("ptrace") !== -1) {// 替换为无效函数指针retval.replace(ptr(0x0));}}
});

总结

通过动态加载libc.so并调用dlsym,可以安全地获取pthread_create函数指针。结合ELF文件解析、内存保护绕过和动态调试技巧,我们能够更深入地分析和控制libmsaoaidsec.so的行为。此方案不仅解决了libmsaoaidsec.so的需求,还为类似场景(如大麦App抢票工具的多线程优化和反调试机制)提供了参考。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com