首页
社区
课程
招聘
[原创]内存解析libmono函数地址
发表于: 2021-2-2 18:12 10827

[原创]内存解析libmono函数地址

2021-2-2 18:12
10827

启动时候HookDlopen,并在加载libmono.so的时候对导出函数 mono_image_open_from_data_with_name 进行Hook 拿到加载进来的dll的image对象,返回值就是一个_MonoImage结构体指针


关注上图中的
*raw_data dll在内存中的起始地址
raw_data_len dll的长度
即可写出,记录下arr_imgs_addr 和 arr_imgs_name

以上为启动的时候就进行Hook可以拿到Image结构体,不在启动的时候Hook同样也可以拿到
使用导出函数中的 mono_image_loaded 即可

对于如何拿到method对象的话,我们还是冲导出函数入手,使用IDA查看一下导出函数,看看关键字method,可以看到这些函数,选几个长得像那么回事的函数去源码搜搜


搜了一下源码得到一下声明

第一个token我们不好找,放弃
第二个flags也不好找,放弃
第四个显然就是一个通过class来遍历method的方法,可用但是没必要

所以看参数我们要去找 MonoClass,那继续去找导出函数


于是找到了 mono_class_from_nam() 函数

由此我们需要的参数也都筹齐了,写出一下hook代码

运行见效果:

简单的看了一下导出函数,发现有一个 mono_runtime_invoke 传参就是 MonoMethod
于是可以尝试主动调用

这里选了一个get_identifier 来主动调用,可以发现没问题
(但是这里仅限于不带参数的Static方法)


看着这个mono_runtime_invoke(MonoMethod method, void obj, void **params,MonoObject **exc)的声明参数就不想看它了,有更简单的方法,这里就简述一下这个简单的方法
我们换一个思路,总所周知,dll是被加载进去内存在动态编译的,这里我们手动调用mono_compile_method来编译这个MonoMethod即可得到类似于il2cpp中的MethodInfo的函数指针,详见下图

/**
* 启动时候Hook mono_image_open_from_data_with_name 记录dll的起始位置,名称
*/
function HookMono() {
  //MonoImage *mono_image_open_from_data_with_name (char *data, uint32_t data_len, mono_bool need_copy,MonoImageOpenStatus *status, mono_bool refonly, const char *name);
  Interceptor.attach(Module.findExportByName(soName,"mono_image_open_from_data_with_name"), {
      onEnter: function (args) {
          this.name = args[5].readCString()
          this.size = args[1].toInt32()
      },
      onLeave: function (ret) {
          var t_ret = ret
          LOG("[*] "+t_ret + "\t"+this.name,LogColor.C36)
          var t_arr = this.name.split("/")
          var t_name = t_arr[(t_arr.length)-1].split(".dll")[0]
          arr_imgs_addr.push(String(t_ret))
          arr_imgs_name.push(t_name)
      }
  });
}
/**
* 启动时候Hook mono_image_open_from_data_with_name 记录dll的起始位置,名称
*/
function HookMono() {
  //MonoImage *mono_image_open_from_data_with_name (char *data, uint32_t data_len, mono_bool need_copy,MonoImageOpenStatus *status, mono_bool refonly, const char *name);
  Interceptor.attach(Module.findExportByName(soName,"mono_image_open_from_data_with_name"), {
      onEnter: function (args) {
          this.name = args[5].readCString()
          this.size = args[1].toInt32()
      },
      onLeave: function (ret) {
          var t_ret = ret
          LOG("[*] "+t_ret + "\t"+this.name,LogColor.C36)
          var t_arr = this.name.split("/")
          var t_name = t_arr[(t_arr.length)-1].split(".dll")[0]
          arr_imgs_addr.push(String(t_ret))
          arr_imgs_name.push(t_name)
      }
  });
}
MonoImage    *mono_image_loaded   (const char *name);
MonoImage    *mono_image_loaded   (const char *name);
MonoMethod *mono_get_method (MonoImage *image, uint32_t token, MonoClass *klass);
MonoMethod *mono_class_get_method_from_name (MonoClass *klass, const char *name, int param_count);
MonoMethod *mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int param_count, int flags);
MonoMethod *mono_class_get_methods       (MonoClass* klass, void **iter);
MonoMethod *mono_get_method (MonoImage *image, uint32_t token, MonoClass *klass);
MonoMethod *mono_class_get_method_from_name (MonoClass *klass, const char *name, int param_count);
MonoMethod *mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int param_count, int flags);
MonoMethod *mono_class_get_methods       (MonoClass* klass, void **iter);
//函数声明
MonoClass *mono_class_from_name       (MonoImage *image, const char* name_space, const char *name);
 
struct _MonoMethod {
    guint16 flags;  /* method flags */
    guint16 iflags; /* method implementation flags */
    guint32 token;
    MonoClass *klass; /* To what class does this method belong */
    MonoMethodSignature *signature;
    /* name is useful mostly for debugging */
    const char *name;
    .....
}
 
struct _MonoClass {
    MonoClass *element_class;
    MonoClass *cast_class;
    MonoClass **supertypes;
    guint16     idepth;
    guint8     rank;         
    int        instance_size;
    ......
    MonoImage *image;
    const char *name;
    const char *name_space;
    ......
}
 
struct _MonoMethodSignature {
    MonoType     *ret;
#ifdef MONO_SMALL_CONFIG
    guint8        param_count;
    gint8         sentinelpos;
    unsigned int  generic_param_count : 5;
#else
    guint16       param_count;
    gint16        sentinelpos;
    unsigned int  generic_param_count : 16;
#endif
    unsigned int  call_convention     : 6;
    unsigned int  hasthis             : 1;
    unsigned int  explicit_this       : 1;
    unsigned int  pinvoke             : 1;
    unsigned int  is_inflated         : 1;
    unsigned int  has_type_parameters : 1;
    MonoType     *params [MONO_ZERO_LEN_ARRAY];
};
//函数声明
MonoClass *mono_class_from_name       (MonoImage *image, const char* name_space, const char *name);
 
struct _MonoMethod {
    guint16 flags;  /* method flags */
    guint16 iflags; /* method implementation flags */
    guint32 token;
    MonoClass *klass; /* To what class does this method belong */
    MonoMethodSignature *signature;
    /* name is useful mostly for debugging */
    const char *name;
    .....
}
 
struct _MonoClass {
    MonoClass *element_class;
    MonoClass *cast_class;
    MonoClass **supertypes;
    guint16     idepth;
    guint8     rank;         
    int        instance_size;
    ......
    MonoImage *image;
    const char *name;
    const char *name_space;
    ......
}
 
struct _MonoMethodSignature {
    MonoType     *ret;
#ifdef MONO_SMALL_CONFIG
    guint8        param_count;
    gint8         sentinelpos;
    unsigned int  generic_param_count : 5;
#else
    guint16       param_count;
    gint16        sentinelpos;
    unsigned int  generic_param_count : 16;
#endif
    unsigned int  call_convention     : 6;
    unsigned int  hasthis             : 1;
    unsigned int  explicit_this       : 1;
    unsigned int  pinvoke             : 1;
    unsigned int  is_inflated         : 1;

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

最后于 2021-5-31 17:24 被唱过阡陌编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (3)
雪    币: 105
活跃值: (4422)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
nice 兄弟
2021-2-2 23:37
0
雪    币: 4005
活跃值: (2183)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
思路很清晰,支持一下
2021-2-3 15:34
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
如果是x86模拟器,运行arm架构,会找不到libil2cpp.so库,怎么解决
2022-10-25 16:14
0
游客
登录 | 注册 方可回帖
返回
//