-
-
[原创]IL2cpp 无导出 il2cpp_image_get_class 和 il2cpp_image_get_class _count函数的解决方法
-
发表于:
2021-9-28 18:22
9630
-
[原创]IL2cpp 无导出 il2cpp_image_get_class 和 il2cpp_image_get_class _count函数的解决方法
前言:
第一次发帖,请多多指教。
问题背景:
在分析il2cpp游戏过程中,通过用frida脚本去hook游戏中的所有函数来观察程序的调用过程,进而快速确定目标调用的位置所在。由于一些游戏的il2cpp中的il2cpp_image_get_class 和 il2cpp_image_get_class _count函数未导出,使得通过获取导出函数来实现上述功能就不能实现,因为无法获取类信息,就得不到方法信息,也就谈不上对所有方法进行hook了。
问题分析和解决
没有导出函数,但是可以通过获取偏移去得到这个函数的指针,
如何获取函数偏移,废话不多说直接上结论。
先获取源码,源码就在unity引擎安装目录下的il2cpp文件夹中,可以自己到引擎目录中搜索。
1--分析 il2cpp_image_get_class _count
1--查看源码,通过查看源码发现 il2cpp_image_get_class _count的实现其实就是这个样子的,
1 2 3 4 | size_t Image::GetNumTypes(const Il2CppImage* image)
{
return image->typeCount;
}
|
很容易发现,这个仅仅是读取了Il2CppImage结构体中的typeCount这个字段,
因此通过查看Il2CppImage的结构体获取typeCount在结构体中的偏移,就可以直接写出代码
1 2 3 4 5 | function temp(imageAddr)
{
return imageAddr.add(p_size * 4).readPointer();
}
il2cpp_image_get_class_count = temp;
|
2--分析 il2cpp_image_get_class
根据源码发现这个函数并不是仅仅是偏移就可以模仿的,源码中函数大概如下
1 2 3 4 5 6 7 | // 通过分析发现, GetTypeInfoFromTypeDefinitionIndex
const Il2CppClass* Image::GetType(const Il2CppImage* image, size_t index)
{
size_t typeDefinitionIndex = image->typeStart + index;
IL2CPP_ASSERT(typeDefinitionIndex <= static_cast<size_t>(std::numeric_limits<TypeDefinitionIndex>::max()));
return MetadataCache::GetTypeInfoFromTypeDefinitionIndex(static_cast<TypeDefinitionIndex>(typeDefinitionIndex));
}
|
分析可知最关键的是GetTypeInfoFromTypeDefinitionIndex 函数,只需要定位到这个函数是在ida中被调用的位置,即可得到函数偏移,进而模拟出il2cpp_image_get_class 这个函数,(因为是自己用所以没去判断类的数量范围)
接着我们只需要查找下GetTypeInfoFromTypeDefinitionIndex在源码中还被哪些函数调用。
查找发现,最可能的函数是ClassFromName
1 2 3 4 5 6 7 8 9 10 | Il2CppClass* Image::ClassFromName(const Il2CppImage* image, const char* namespaze, const char *name)
{
//
Il2CppNameToTypeDefinitionIndexHashTable::const_iterator iter = image->nameToClassHashTable->find(std::make_pair(namespaze, name));
if (iter != image->nameToClassHashTable->end())
return MetadataCache::GetTypeInfoFromTypeDefinitionIndex(iter->second);
return NULL;
}
|
这时候就要根据经验了,自然就想到了这个il2cpp函数 il2cpp_class_from_name
很幸运的是确定这个函数在ida中确实有导出,这样就直接到ida中定位到函数位置,观察函数的流程,就可以轻松确定出GetTypeInfoFromTypeDefinitionIndex函数在ida中的位置
1 2 3 4 5 6 7 | // 这个是截取ida中ClassFromName的部分代码,可以发现
sub_D6EC58(&v16);
if ( v12 == v17 )
result = 0;
else
result = sub_D35254(*(_DWORD *)(v12 + 12));
return result;
|
最终确定 sub_D35254 函数便是我们要找的GetTypeInfoFromTypeDefinitionIndex函数,到此就全部确定完成了。
最终的代码如下,注意这里没判断类的数量范围,自己用要判断不判断都可以
1 2 3 4 5 6 7 8 9 10 11 12 | var func_offset = 0xD35254;
var func = n_addr_so.add(func_offset);
var getclass = new NativeFunction(func, 'pointer', ['int']);
LOG(`getclass :${getclass} `,LogColor.C93);
function tempgetclass(image,id)
{
// 源码中是有判断id的范围的,这里不判断,目前没影响
var idtype = image.add(p_size * 3).readPointer().toInt32()+id;
return getclass(idtype);
}
// 最后把函数 赋值给il2cpp_image_get_class , 后面就是正常调用这个函数就行了
il2cpp_image_get_class = tempgetclass;
|
目前这个就ok了,要是有的游戏的目标函数偏移不同就根据这个文章教程自己修改下,很简单的。
要是有帮助到各位,那就可以了。
[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!