public override void SetHook(HookInfo info) { if (HookInfos.Count > 0) { throw new InvalidOperationException("JumpHook can not mix with other hook"); } base.SetHook(info); HookAttribute hook = info.GetHookAttribute(); switch (hook.Type) { case HookType.SimpleJumpToRet: int address = (int)info.GetReturnValue(); Logger.Log("jump to address: 0x{0:X}", address); ASMWriter.WriteJump(new JumpStruct(hook.Address, address)); break; case HookType.DirectJumpToHook: int callable = (int)info.GetCallable(); Logger.Log("jump to callable: 0x{0:X}", callable); ASMWriter.WriteJump(new JumpStruct(hook.Address, callable)); break; default: Logger.LogError("found unkwnow jump hook: " + info.Member.Name); break; } }
public override void SetHook(HookInfo info) { base.SetHook(info); HookAttribute hook = MaxHookInfo.GetHookAttribute(); var callable = (int)MaxHookInfo.GetCallable(); Logger.Log("ares hook callable: 0x{0:X}", callable); int pMemory = (int)GetMemory(code_call.Length + hook.Size + ASM.Jmp.Length); Logger.Log("AresHookTransferStation alloc: 0x{0:X}", pMemory); if (pMemory != (int)IntPtr.Zero) { MemoryHelper.Write(pMemory, code_call, code_call.Length); MemoryHelper.Write(pMemory + 3, hook.Address); ASMWriter.WriteCall(new JumpStruct(pMemory + 0xF, callable)); var origin_code_offset = pMemory + code_call.Length; if (hook.Size > 0) { // write origin code MemoryHelper.Write(origin_code_offset, code_over, hook.Size); // protect relative jmp or call if (code_over[0] == ASM.Jmp[0] || code_over[0] == ASM.Call[0]) { int destination = 0; MemoryHelper.Read(hook.Address + 1, ref destination); destination = hook.Address + 5 + destination; MemoryHelper.Write(origin_code_offset + 1, new JumpStruct(origin_code_offset, destination).Offset); } } var jmp_back_offset = origin_code_offset + hook.Size; ASMWriter.WriteJump(new JumpStruct(jmp_back_offset, hook.Address + hook.Size)); ASMWriter.WriteJump(new JumpStruct(hook.Address, pMemory)); ASMWriter.FlushInstructionCache(pMemory, memoryHandle.Size); } }
public void ApplyHook(MemberInfo member) { HookAttribute[] hooks = HookInfo.GetHookAttributes(member); foreach (var hook in hooks) { var info = new HookInfo(member, hook); Logger.Log("appling {3} hook: {0:X}, {1}, {2:X}", hook.Address, member.Name, hook.Size, hook.Type); try { CheckHookRace(info); int key = hook.Address; HookTransferStation station = null; // use old station if exist if (transferStations.ContainsKey(key)) { station = transferStations[key]; if (station.Match(hook.Type)) { Logger.Log("insert hook to key '{0:X}'", key); station.SetHook(info); } else if (station.HookInfos.Count <= 0) { Logger.LogWarning("remove key '{0:X}' because of hook type mismatch. ", key); transferStations.Remove(key); station = null; } else { throw new InvalidOperationException("hook type mismatch."); } } // create new station if (station == null) { Logger.Log("add key '{0:X}'", key); switch (hook.Type) { case HookType.AresHook: station = new AresHookTransferStation(info); break; case HookType.SimpleJumpToRet: case HookType.DirectJumpToHook: station = new JumpHookTransferStation(info); break; case HookType.WriteBytesHook: station = new WriteBytesHookTransferStation(info); break; default: Logger.LogError("found unkwnow hook: " + member.Name); return; } transferStations.Add(key, station); } ASMWriter.FlushInstructionCache(hook.Address, Math.Max(hook.Size, ASM.Jmp.Length)); maxHookSize = Math.Max(hook.Size, maxHookSize); } catch (Exception e) { Logger.LogError("hook applied error!"); Logger.PrintException(e); } } }