android 通过hook linker得到所有加载的so信息

通过分析dlopen的加载流程,do_dlopen会调用find_library来加载so,并且把该so的信息加载进并且返回一个soinfo结构体

soinfo结构体里面包含了so的所有信息,比如符号等等信息,

然后位于/bionic/linker/linker_main.cpp全局有几个变量,其中的solist是一个链表,指向已加载的共享库链表的头部,它是一个指向 soinfo 结构体的指针,表示链表的起始点,所以,可以通过这个solist拿到通过正常linker加载的所有so的信息

somain:指的是linker.so的soinfo的结构体指针linker.so 是一个特殊的共享库

sonext:每当使用 dlopen 加载一个共享库时,动态链接器会创建一个新的 soinfo 结构体,并通过 sonext 变量将这个结构体链接到共享库链表中。这样就形成了一个链表,其中包含了已加载的所有共享库的信息,每次调用dlopen加载so的时候,都会做这种操作,形成一个链表

newinfo->next = sonext;

sonext = newinfo;

刚好,在/bionic/linker/linker_main.cpp下就有一个方法,叫solist_get_head会返回这个solist,所以,只需要使用hook来hooklinker.so的__dl__Z15solist_get_headv这个符号即可得到这个方法的地址他是编译后的符号,调用它即可拿到该solist,因为是链表,每调用一次next指向的就是下一个soinfo的指针。

以下代码是一个,拿到soinfo后,遍历其中符号的示例:

void process_exported_symbols(soinfo* si) {
    // 获取动态段的地址
    ElfW(Dyn)* dynamic = si->dynamic;

    // 遍历动态段,查找动态符号表的地址和大小
    for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
        if (d->d_tag == DT_SYMTAB) {
            // d->d_un.d_ptr 是动态符号表的地址
            ElfW(Sym)* symtab = reinterpret_cast<ElfW(Sym)*>(d->d_un.d_ptr);

            // 获取符号表中的符号数量
            size_t num_symbols = ...;  // 计算符号数量的方法取决于符号表的结构

            // 遍历动态符号表,处理每个符号
            for (size_t i = 0; i < num_symbols; ++i) {
                // 处理符号信息
                ElfW(Sym)* symbol = &symtab[i];
                const char* symbol_name = si->strtab + symbol->st_name;
                // 处理符号名称、值等信息
                // ...
            }
        }
    }
}

// 调用上述函数
soinfo* my_so = ...;  // 你的 soinfo 指针
process_exported_symbols(my_so);

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值