首页
社区
课程
招聘
[求助][求助]基于Android7.0 Linker的SO加壳方法思路
发表于: 2017-6-13 17:43 8973

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

2017-6-13 17:43
8973

    本人由于工作与爱好,基于论坛各位前辈的资料以及安卓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, SoinfoListAllocator> soinfo_list_t;    // 请问该结构体 占内存空间吗?

  typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;   // 请问该结构体 占内存空间吗?

#if defined(__work_around_b_24465209__)

 private:

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

 ...

         }


关于 LinkedList的定义大概如下:

template<typename T, typename Allocator>

class LinkedList {

 public:

  typedef LinkedListIterator<T> 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<uintptr_t, soinfo*> g_soinfo_handles_map;

static soinfo* soinfo_from_handle(void* handle) {

  if ((reinterpret_cast<uintptr_t>(handle) & 1) != 0) {

    auto it = g_soinfo_handles_map.find(reinterpret_cast<uintptr_t>(handle));

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

      return nullptr;

    } else {

      return it->second;

    }

  }

  return static_cast<soinfo*>(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 这样。 希望后人别踩这个坑。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 2039
活跃值: (1468)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
2
1.  soinfo_list_t  和  android_namespace_list_t  不占内存,那是类型定义,不是变量定义
2.  建议你换个思路,其实还有别的办法。
2017-6-13 18:08
1
雪    币: 202
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
十八垧 1. soinfo_list_t 和 android_namespace_list_t 不占内存,那是类型定义,不是变量定义 2. 建议你换个思路,其实还有别的办法。
不占内存,应该soinfo结构体是兼容的。    思路的关键是找到soinfo的信息,这个也是难点。
2017-6-13 20:52
0
雪    币: 2039
活跃值: (1468)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
Giggle小鹿 不占内存,应该soinfo结构体是兼容的。 思路的关键是找到soinfo的信息,这个也是难点。
32bit的soinfo兼容问题不大,64bit系统的soinfo就要特别注意了。
2017-6-14 13:40
0
雪    币: 202
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
十八垧 32bit的soinfo兼容问题不大,64bit系统的soinfo就要特别注意了。
今天找到方法了,  的确像你说的  类型定义不占内存,  但是还在调试中。  很感谢!
2017-6-14 18:23
0
雪    币: 275
活跃值: (254)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
依赖soinfo结构就是给以后挖坑啊。
2017-6-15 12:14
0
雪    币: 202
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
wule 依赖soinfo结构就是给以后挖坑啊。
我也有点这种感觉,    不过都是向前兼容的,  已经实现64位的加壳了
2017-6-15 17:15
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
楼主分享一下获取  soinfo  的思路吧,Android  7.0  改了这个不好拿了
2017-7-18 18:38
0
雪    币: 202
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
Torch油 楼主分享一下获取 soinfo 的思路吧,Android 7.0 改了这个不好拿了
最近我也在找思路,  SDK24及以上    获取的是hash值,字典映射存储着soinfo
2017-8-15 18:27
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
楼主找到soinfo信息了吗
2017-9-26 17:47
0
雪    币: 4
活跃值: (137)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
获取soinfo的思路有了吗 楼主?
2018-7-5 15:14
0
雪    币: 107
活跃值: (1693)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
12
之前想过内存搜索linker里的全局std:: unordered_map变量,考虑到不同编译器,不同版本,存在兼容性问题,最后没有去尝试。
2019-8-13 15:01
0
雪    币: 109
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
有需要so非加壳代码保护的,可以私聊呀,比如Native代码层的保护等
2019-8-13 16:46
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
楼主能不能分享一下源码呢?
2021-4-27 16:47
0
游客
登录 | 注册 方可回帖
返回
//