主要的思路是,输入一个对象,那么使用反射的GetType, 然后使用type的GetFields, 拿到Field的列表,然后遍历field列表。
需要配合il2cpp原来程序里的一些json序列化的工具来进行,一般都可以找到,如下面的。MiniJSON.Json,像这个 Serialize到运行时对象就不行了。
// Namespace: MiniJSON
public static class Json // TypeDefIndex: 13713
{
// Methods
// RVA: 0x151A02C Offset: 0x151A02C VA: 0x151A02C
public static object Deserialize(string json) { }
// RVA: 0x151A1D4 Offset: 0x151A1D4 VA: 0x151A1D4
public static string Serialize(object obj) { }
}
Field是一个抽象类的,这里我使用 RuntimeFieldInfo : RtFieldInfo里面的函数来实现。代码如下。
function dumpCsObject(base_addr , obj,MiniJsonSerialize)
{
var GetType = new NativeFunction(ptr(base_addr).add(0x26433E8), "pointer", ["pointer"]);
var GetFields = new NativeFunction(ptr(base_addr).add(0x261D450), "pointer", ["pointer"]);
var t = GetType(obj);
var fields = GetFields(t);
var num = fields.add(0x18).readU64();
var szRet = "{";
for(var i=0;i<num;i++)
{
var FieldInfo = ptr(fields).add(0x20+i*8).readPointer();
var GetValue = new NativeFunction(ptr(base_addr).add(0x25603F8), "pointer", ["pointer","pointer"]);
var val = GetValue(FieldInfo,obj);
var pVal= MiniJsonSerialize(val);
var szJson = ptr(pVal).add(0x14).readUtf16String();
var fn = FieldInfo.add(0x20).readPointer().add(0x14).readUtf16String();
szRet = szRet + fn + ":" + szJson;
if(num-1!=i)
{
szRet = szRet + ",";
}
}
szRet = szRet + "}"
return szRet;
}