首页
社区
课程
招聘
[求助]基于安卓8.1源码实现自定义Linker加载so,so中有try-catch调用时,catch会失效
发表于: 2024-5-30 14:40 2885

[求助]基于安卓8.1源码实现自定义Linker加载so,so中有try-catch调用时,catch会失效

2024-5-30 14:40
2885

so中抛出异常源代码内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//定义异常
class MyException : public std::exception {
public:
    const char* what() const noexcept override {
        return "error";
    }
};
//JNI_ONLOAD中抛出异常
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    __android_log_print(6, "sd", "JNI_OnLoad!");
    try
    {
        throw MyException();
    }
    catch(const std::exception& e)
    {
        __android_log_print(6, "sd", "catched %s",e.what());
    }
    return JNI_VERSION_1_6;
}

如果不使用自定义linker加载,能正常捕获到异常。使用自定义Linker加载时会崩溃:
图片描述
自定义linker在还原soinfo时没有还原ARM_exidx、ARM_exidx_count两个字段,不知道是否和这个有关。
soinfo替换代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
LOG_I("==================reset_soinfo===================");
    LOG_I("phdr_table_ old=%lx, new=%p",*(long*)((char*)mysoinfo),myso.phdr_table_);
    *(long*)((char*)mysoinfo) = reinterpret_cast<long>(myso.phdr_table_);
    LOG_I("phdr_num_ old=%ld, new=%ld",*(size_t*)((char*)mysoinfo+8),myso.phdr_num_);
    *(size_t*)((char*)mysoinfo+8) = myso.phdr_num_;
    LOG_I("load_start_ old=%lx, new=%lx",*(long *)((char *)mysoinfo+16),reinterpret_cast<long>(myso.load_start_));
    *(long *)((char *)mysoinfo+16) = reinterpret_cast<long>(myso.load_start_);
    LOG_I("load_size_ old=%ld, new=%ld",*(size_t*)((char*)mysoinfo+24),myso.load_size_);
    *(size_t*)((char*)mysoinfo+24) = myso.load_size_;
    LOG_I("dynamic_ old=%lx, new=%lx",*(long*)((char*)mysoinfo+32),(long)myso.dynamic_);
    *(long*)((char*)mysoinfo+32) = (long) myso.dynamic_;
    LOG_I("strtab_ old=%lx, new=%lx",*(long*)((char*)mysoinfo+56) ,(long)myso.strtab_);
    *(long*)((char*)mysoinfo+56) = reinterpret_cast<long>(myso.strtab_);
    LOG_I("sym_table_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+64) ,(long)myso.sym_table_);
    *(long *)((char*)mysoinfo+64) = reinterpret_cast<long>(myso.sym_table_);
 
    //DT_HASH
    *(size_t *)((char*)mysoinfo+72) = myso.nbucket_;
    *(size_t*)((char*)mysoinfo+80) = myso.nchain_;
    *(long*)((char*)mysoinfo+88) = reinterpret_cast<long>(myso.bucket_);
    *(long*)((char*)mysoinfo+96) = reinterpret_cast<long>(myso.chain_);
    LOG_I("plt_rela_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+104)  ,(long)myso.jum_rel_tab_);
    *(long *)((char*)mysoinfo+104) = reinterpret_cast<long>(myso.jum_rel_tab_);
    LOG_I("plt_rela_count_ old=%ld, new=%ld",*(size_t *)((char*)mysoinfo+112)  ,myso.plt_rela_count_);
    *(size_t *)((char*)mysoinfo+112) = myso.plt_rela_count_;
    LOG_I("rela_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+120)  ,(long)myso.rela_table_);
    *(long *)((char*)mysoinfo+120) = reinterpret_cast<long>(myso.rela_table_);
    LOG_I("rela_count_ old=%ld, new=%ld",*(size_t *)((char*)mysoinfo+128)  ,myso.rela_count_);
    *(size_t *)((char*)mysoinfo+128) = myso.rela_count_;
 
    LOG_E("preinit_array_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+136)  ,reinterpret_cast<long>(myso.preinit_array_));
    *(long *)((char*)mysoinfo+136) = reinterpret_cast<long>(myso.preinit_array_);
    LOG_I("preinit_array_count_ old=zu, new=%zu",*(size_t *)((char*)mysoinfo+144)  ,myso.preinit_array_count_);
    *(size_t *)((char*)mysoinfo+144) = myso.preinit_array_count_;
    LOG_I("init_array_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+152)  ,(long)myso.init_array_);
    *(long *)((char*)mysoinfo+152) = reinterpret_cast<long>(myso.init_array_);
    LOG_I("init_array_count_ old=%ld, new=%zu",*(size_t *)((char*)mysoinfo+160)  ,myso.init_array_count_);
    *(size_t *)((char*)mysoinfo+160) = myso.init_array_count_;
    LOG_I("fini_array_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+168)  ,(long)myso.fini_array_);
    *(long *)((char*)mysoinfo+168) = reinterpret_cast<long>(myso.fini_array_);
    LOG_I("fini_array_count_ old=%ld, new=%ld",*(size_t *)((char*)mysoinfo+176)  ,myso.fini_array_count_);
    *(size_t *)((char*)mysoinfo+176) = myso.fini_array_count_;
    LOG_I("init_func_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+184)  ,(long)myso.init_func_);
    *(long *)((char*)mysoinfo+184) =  reinterpret_cast<long>(myso.init_func_);
    LOG_I("fini_func_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+192)  ,(long)myso.fini_func_);
    *(long *)((char*)mysoinfo+192) =reinterpret_cast<long>(myso.fini_func_);
 
    LOG_I("load_bias_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+256)  ,(long)myso.load_bias_);
    *(size_t*)((char*)mysoinfo+256) = myso.load_bias_;
    LOG_I("strtab_size_ old=%ld, new=%ld",*(size_t *)((char*)mysoinfo+336),myso.strtab_size_);
    *(size_t *)((char*)mysoinfo+336) = myso.strtab_size_;
    //DT_GNU_HASH
    LOG_I("gnu_nbucket_ old=%ld, new=%ld",*(size_t *)((char*)mysoinfo+344),myso.gnu_nbucket_);
    *(size_t *)((char*)mysoinfo+344) = myso.gnu_nbucket_;
    LOG_I("gnu_bucket_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+352)  ,(long)myso.gnu_bucket_);
    *(long*)((char*)mysoinfo+352) = reinterpret_cast<long>(myso.gnu_bucket_);
    LOG_I("gnu_chain_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+360)  ,(long)myso.gnu_chain_);
    *(long*)((char*)mysoinfo+360) = reinterpret_cast<long>(myso.gnu_chain_);
    LOG_I("gnu_maskwords_ old=%u, new=%u",*(uint32_t *)((char*)mysoinfo+368),myso.gnu_maskwords_);
    *(uint32_t *)((char*)mysoinfo+368) = myso.gnu_maskwords_;
    LOG_I("gnu_shift2_ old=%u, new=%u",*(uint32_t *)((char*)mysoinfo+372),myso.gnu_shift2_);
    *(uint32_t *)((char*)mysoinfo+372) = myso.gnu_shift2_;
    LOG_I("gnu_bloom_filter_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+376)  ,(long)myso.gnu_bloom_filter_);
    *(long*)((char*)mysoinfo+376) = reinterpret_cast<long>(myso.gnu_bloom_filter_);
 
    LOG_I("android_relocs_ old=%u, new=%p",*(uint8_t*)((char*)mysoinfo+392),myso.android_relocs_);
    *(uint8_t*)((char*)mysoinfo+392) = reinterpret_cast<long>(myso.android_relocs_);
    LOG_I("android_relocs_size_ old=%zu, new=%zu",*(size_t *)((char*)mysoinfo+400),myso.android_relocs_size_);
    *(size_t *)((char*)mysoinfo+400) = myso.android_relocs_size_;
 
    LOG_I("versym_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+440)  ,(long)myso.versym_);
    *(long *)((char*)mysoinfo+440) = (long) myso.versym_;
    LOG_I("verdef_ptr_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+448)  ,(long)myso.verdef_ptr_);
    *(long *)((char*)mysoinfo+448) = (long)myso.verdef_ptr_;
    LOG_I("verdef_cnt_ old=%ld, new=%ld",*(size_t *)((char*)mysoinfo+456),myso.verdef_cnt_);
    *(size_t *)((char*)mysoinfo+456) = myso.verdef_cnt_;
    LOG_I("verneed_ptr_ old=%lx, new=%lx",*(long *)((char*)mysoinfo+464)  ,(long)myso.verneed_ptr_);
    *(long *)((char*)mysoinfo+464) = (long)myso.verneed_ptr_;
    LOG_I("verneed_cnt_ old=%ld, new=%ld",*(size_t *)((char*)mysoinfo+472),myso.verneed_cnt_);
    *(size_t *)((char*)mysoinfo+472) = myso.verneed_cnt_;

但是感觉和这两个字段没有关系,这两个字段的值来自于程序头表中的PT_ARM_EXIDX类型,但实际上我的so并没有这个类型的程序头表项

1
2
3
4
5
6
if(phdr->p_type == PT_ARM_EXIDX) {
    /* exidx entries (used for stack unwinding) are 8 bytes each.
     */
    si->ARM_exidx = (unsigned *)phdr->p_vaddr;
    si->ARM_exidx_count = phdr->p_memsz / 8;
}

我看节头表中有.gcc_except_table节,不知道是不是和这个有关。
还请大佬们不吝赐教!


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 2911
活跃值: (5500)
能力值: ( LV11,RANK:185 )
在线值:
发帖
回帖
粉丝
2
这要看你的自定义linker 实现到什么程度了,比如是否支持异常
2024-6-1 16:05
0
雪    币: 6506
活跃值: (4917)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
论坛里之前好像有人问过这个问题,是因为遗漏了两个字段
2024-6-2 14:20
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
简单的简单 论坛里之前好像有人问过这个问题,是因为遗漏了两个字段
还记得时哪个帖子吗,实在是没思路了
2024-6-3 12:00
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
Thehepta 这要看你的自定义linker 实现到什么程度了,比如是否支持异常

需要支持捕获异常,大佬可以指点一下吗

2024-6-3 12:01
0
雪    币: 2911
活跃值: (5500)
能力值: ( LV11,RANK:185 )
在线值:
发帖
回帖
粉丝
6
翻一翻系统的源码和文档,看看他们是怎么处理的,你有那些字段没有处理。另外,建议去抄系统源码,自己写,坑太多,很多东西不遇到问题根本不知道,当然你也可以去看看最新的so 相关的文档,照着写
2024-6-3 16:41
0
雪    币: 2911
活跃值: (5500)
能力值: ( LV11,RANK:185 )
在线值:
发帖
回帖
粉丝
7

我也写了一个linker,但是好像我也没有处理异常,对了,你试试源码系统本身是否支持异常,如果不支持,抄最新的

最后于 2024-6-3 16:47 被Thehepta编辑 ,原因:
2024-6-3 16:42
0
游客
登录 | 注册 方可回帖
返回
//