linux so 加壳,[求助][求助]基于Android7.0 Linker的SO加壳方法思路

本人由于工作与爱好,基于论坛各位前辈的资料以及安卓5.10 linker源码实现了Arm32位的加壳加密, 由于最近7.0源码支持Arm64,对于soinfo结构体进行了很大的变动,原先通过 void* handle = dlopen("libxxx.so",RTLD_NOW); 将 Loader_soinfo = (soinfo*)(handle), 可以获取到需要获取处理的so库的soinfo信息,并通过该结构体进行替换相关 .nbucket, .nchain, .bucket, .chain, .strtab, .symtab, .load_bias, .base, .size等系统维护的soinfo_list维护的字段,可以实现壳的实现。

由于linker7.0是基于c++14写的,引入了lambda表达式等, 对于结构体soinfo:

struct soinfo {

public:

typedef LinkedList soinfo_list_t;    // 请问该结构体 占内存空间吗?

typedef LinkedList android_namespace_list_t;   // 请问该结构体 占内存空间吗?

#if defined(__work_around_b_24465209__)

private:

char old_name_[SOINFO_NAME_LEN];   // 该处为兼容Arm32位版本的  起始偏移地址

...

}

关于 LinkedList的定义大概如下:

template

class LinkedList {

public:

typedef LinkedListIterator iterator;

typedef T* value_type;

LinkedList() : head_(nullptr), tail_(nullptr) {}

~LinkedList() {

clear();

}

LinkedList(LinkedList&& that) {

this->head_ = that.head_;

this->tail_ = that.tail_;

that.head_ = that.tail_ = nullptr;

}

.........

}

另外, 通过dlsym函数查看源码,发现:

static std::unordered_map g_soinfo_handles_map;

static soinfo* soinfo_from_handle(void* handle) {

if ((reinterpret_cast(handle) & 1) != 0) {

auto it = g_soinfo_handles_map.find(reinterpret_cast(handle));

if (it == g_soinfo_handles_map.end()) {

return nullptr;

} else {

return it->second;

}

}

return static_cast(handle);

}

应该是通过系统维护的g_soinfo_handles_map里, 映射着对应的handle与soinfo*信息吧,请问如果是这样,如何在外部获取系统维护的g_soinfo_handles_map信息, 用于获取已经打开的so的soinfo*获取,并修改替换以完成壳的功能, 即如何找到想要打开的so的soinfo信息,且和原先版本的变量偏移有区别吗?

经过翻阅源码与多次实验,发现soinfo结构是向前兼容的,因此32位的方法同样适用于64位Arm,不过需要注意的是64位机子的指针为64位,还有重定位时,Rela与Rela.plt多了一个r_addend字段, relative重定位时不是自增加,而是 so->load_bias+rela.r_addend 这样。 希望后人别踩这个坑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值