HybridCLR 从原理上来说并不复杂,主要是Runtime下进行元数据的初始化和解析,同时实现了一个解释器,由于是动态的进行解析,基于元数据的Dump自然就失效了得到的偏移地址完全指向了解释器的占位入口 比如一个静态函数 :
public static void Run(){} 指向的地址的符号表为 _ZL7__N2M_vPK10MethodInfo 这是因为在动态解析的过程中 生成的methodInfo最终需要解释器来执行,一些固定的函数自然需要固定的入口来进行跳转,HybridCLR 也是生成了非常多的符号表,对应各个类型函数的跳转;
// CS函数函数对应
// RVA: 0x52C7A0 VA: 0x6EDCF367A0
public void add(int a, int b) { }
export let TestJs={
test:function(){
//参数分别是 dllName namespace className methodName methodCount
HybridCLR.observe("HotUpdate.dll","HotUpdate","Hello",
"add",2,function (methodInfo,runtimeArgs){
console.log("args len "+runtimeArgs.length)
let a = runtimeArgs[1].readU32();
let b = runtimeArgs[2].readU32();
console.log("add call a = "+a +" b= "+b)
});
HybridCLR.attach();
}
}
test:function(){
HybridCLR.observe("HotUpdate.dll","HotUpdate","Hello",
"add",2,function (methodInfo,runtimeArgs){
console.log("args len "+runtimeArgs.length)
let a = runtimeArgs[1].readU32();
let b = runtimeArgs[2].readU32();
console.log("add call a = "+a +" b= "+b)
runtimeArgs[1].writeU32(100) //把a值修改为100
});
HybridCLR.attach();
}
// Image :0 mscorlib - 1282
// Image :1 System.Configuration - 10
// Image :2 Mono.Security - 5
// Image :3 System.Xml - 3
// Image :4 System - 119
// Image :5 System.Core - 8
// Image :6 UnityEngine.SharedInternalsModule - 26
// Image :7 UnityEngine.CoreModule - 434
// Image :8 UnityEngine.AndroidJNIModule - 24
// Image :9 UnityEngine.AudioModule - 14
// Image :10 UnityEngine.UnityAnalyticsModule - 11
// Image :11 UnityEngine.UnityWebRequestModule - 4
// Image :12 UnityEngine - 1
// Image :13 UnityHook - 27
// Image :14 Assembly-CSharp - 3
// Image :15 HotUpdate - 4---> HybridCLR Dll 此即代表该dll为热更dll
SymbolFinder.findEnterFrameFromInterpreter(function (address) {
HybridCLR.doAttach(address);
});