unsafe void ApplyPatch(string[] list) { int baseAddr = (int)Process.GetCurrentProcess().MainModule.BaseAddress, codeInjAddr = baseAddr + codeInjOffset, mpqFuncAddr = baseAddr + mpqFuncOffset; if (!Check(codeInjAddr, mpqFuncAddr)) { Log.Error("LoadMPQ: Patch pattern mismatch (wrong game version?)"); return; } Log.Information("LoadMPQ: Injecting mpq archives"); int extSz = sizeof(JmpOp) + ((sizeof(JmpOp) + sizeof(MovEspDwordOp)) * list.Length) + sizeof(JmpOp), codeDestAddr = (int)Marshal.AllocHGlobal(extSz); VirtualProtect(codeInjAddr, sizeof(JmpOp), erwFlag, out outPtr); JmpOp.Write(codeInjAddr, codeDestAddr, false); VirtualProtect(codeDestAddr, extSz, erwFlag, out outPtr); var writeAddr = codeDestAddr; JmpOp.Write(writeAddr, mpqFuncAddr, true); writeAddr += sizeof(JmpOp); for (int i = 0; i < list.Length; i++) { MovEspDwordOp.Write(writeAddr, (int)Marshal.StringToHGlobalAnsi(list[i])); writeAddr += sizeof(MovEspDwordOp); JmpOp.Write(writeAddr, mpqFuncAddr, true); writeAddr += sizeof(JmpOp); } JmpOp.Write(writeAddr, codeInjAddr + sizeof(JmpOp), false); }
unsafe bool Check(int codeInjAddr, int mpqFuncAddr) { return(JmpOp.Compare(*(JmpOp *)codeInjAddr, new JmpOp(mpqFuncAddr - (codeInjAddr + sizeof(JmpOp)), true))); }
public static unsafe bool Compare(JmpOp opA, JmpOp opB) { return((opA.OpCode == opB.OpCode) && (opA.Offset == opB.Offset)); }