-
-
[原创]分享Unity游戏逆向的小工具
-
发表于:
2020-9-9 08:32
20749
-
使用 frida 的第n天
"真香 ~~~ "
今天的主题是用结合使用frida和Il2CppDumper对Unity游戏的批量断点
方便大家动态分析方法调用(指的libil2cpp.so)
欢迎Unity逆向玩家食用
Il2CppHookScripts
简单的介绍一下,主要是两个文件

这里举例的libmain.so,其他也一样,一般是断libil2cpp.so

以上为静态使用Il2CppDumperTool生成的数据来进行筛选搜索,来排查我们需要hook的函数位置,那又有小伙伴要说了,“你这玩意用起来太麻烦了,步骤好多,我们可以用贼香贼香的frida来实现动态hook吗?“
”答案当然是肯定可以的“
以下就简要的分析以下libil2cpp.so相关的东西,以目的为主,需要深入的玩家请看参考文章(参考:885K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6X3L8r3!0W2i4K6u0V1K9h3y4W2i4K6u0W2j5$3&6Q4x3V1k6S2M7X3y4Z5K9i4k6W2M7#2)9J5c8U0f1H3x3W2!0q4c8W2!0n7b7#2)9^5z5b7`.`.
调用链:
il2cpp_class_get_methods_0 -->SetupMethods--> SetupMethodsLocked
先在导出函数看看il2cpp_class_get_methods_0
参见函数原型,三个参数(IDA识别错误的两个参数)

这个函数的返回值就是一个MethodInfo结构体
1 2 3 4 5 6 7 8 9 10 | typedef struct MethodInfo
{
int32_t methodPointer;
int32_t invoker_method;
const char* name;
Il2CppClass *klass;
const void *return_type;
const void* parameters;
...
} MethodInfo;
|
这里会用到一个结构体Il2CppClass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | struct Il2CppClass
{
const Il2CppImage* image;
void* gc_desc;
const char* name;
const char* namespaze;
const Il2CppType* byval_arg;
const Il2CppType* this_arg;
Il2CppClass* element_class;
Il2CppClass* castClass;
Il2CppClass* declaringType;
Il2CppClass* parent;
Il2CppGenericClass *generic_class;
const Il2CppTypeDefinition* typeDefinition;
const Il2CppInteropData* interopData;
...
};
|
这两个结构体里面就包含了我们Hook需要的基本信息了
所以我们直接Hook
这张图是il2cpp_class_get_methods_0的返回值,结合上面的结构体去看

下面咋们就直接给出稍微整理后的Hook的结果

第一列是真实运行时候的地址,第二列是so里面的地址,还有就是函数名,这就相当于有了函数符号表了鸭,回到主题,hook位置我们可以在这个时候去筛选名称进行hook,这还是蛮方便的 ~
附上frida代码,可以自行尝试:
(ps:记得在hook dlopen判断so加载哦,第一时间hook)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function hook(){
var p_size = Process.pointerSize
var soAddr = Module.findBaseAddress("libil2cpp.so")
Interceptor.attach(Module.findExportByName("libil2cpp.so","il2cpp_class_get_methods"),{
onEnter:function(args){
},
onLeave:function(ret){
console.error("--------------------------------------------------------")
console.log(hexdump(ret,{length:16}))
console.log("methodPointer => \t"+ret.readPointer() +"\t ===> \t"+ret.readPointer().sub(soAddr))
console.log("invoker_method => \t"+ret.add(p_size*1).readPointer() +"\t ===> \t"+ret.add(p_size*1).readPointer().sub(soAddr))
console.log("MethodName => \t\t"+ret.add(p_size*2).readPointer().readCString())
var klass = ret.add(p_size*3).readPointer()
console.log("namespaze => \t\t"+klass.add(p_size*3).readPointer().readCString()+"."
+klass.add(p_size*2).readPointer().readCString())
}
})
}
|
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-5-31 17:28
被唱过阡陌编辑
,原因: