//encryption patch public static void PatchEncryption() { ProcessHandler us = ProcessHandler.CurrentProcess; int curtarget; JmpRelative jrel; asmInstruction curins; us.Position = UOCallibration.Callibrations[(uint)UOCallibration.CallibratedFeatures.sendcryptpatchpos]; curins = disassembler.disassemble(us); curtarget = (int)curins.ReadAddressOperand(); jrel = new JmpRelative(curtarget); jrel.Write(us, (int)curins.Address); us.Position = UOCallibration.Callibrations[(uint)UOCallibration.CallibratedFeatures.recvcryptpatchpos]; curins = disassembler.disassemble(us); curtarget = (int)curins.ReadAddressOperand(); jrel = new JmpRelative(curtarget); jrel.Write(us, (int)curins.Address); us.Position = (int)UOCallibration.Callibrations[(uint)UOCallibration.CallibratedFeatures.SendCryptPatchPos2]; curins = disassembler.disassemble(us); curtarget = (int)curins.ReadAddressOperand(); jrel = new JmpRelative(curtarget); jrel.Write(us, (int)curins.Address); }
private LocalHook(uint address, ushort stack_cleanup_size, bool IsVtblEntry) { uint skip_call_address; asmInstruction curinsn = null; ProcessHandler curprocess = ProcessHandler.CurrentProcess; StreamHandler sh = new StreamHandler(curprocess); CallRelative crel; JmpRelative jrel; int readsize = 0; m_Address = address; m_VtblHook = IsVtblEntry; //read original target address curprocess.Position = address; if (IsVtblEntry) { original_address = sh.Read <uint>(); } else { curinsn = disassembler.disassemble(curprocess); if (curinsn.Instruction.type == x86_insn_type.insn_call) { original_address = (uint)curinsn.ReadAddressOperand(); } else { original_address = 0;//not hooking a call readsize = curinsn.Instruction.size; while (readsize < 5) { curinsn = disassembler.disassemble(curprocess); readsize += curinsn.Instruction.size; } copied_instructions = new byte[readsize]; curprocess.Position = address; curprocess.Read(copied_instructions, 0, readsize); } } //allocate required space (60 bytes) m_HookMemory = Allocator.AllocateBuffer((uint)(46 + 32 + readsize)); m_EspBackup = Allocator.AllocateBuffer(4); skip_call_address = (uint)(m_HookMemory.Address.ToInt32() + 35 + readsize); //build unmanaged function pointer m_Delegate = new InternalHookDelegate(ActualHook); m_LateDelegate = new InternalHookDelegate(ActualLateHook); IntPtr unmanaged_hook_pointer = Marshal.GetFunctionPointerForDelegate(m_Delegate); IntPtr unmanaged_hook_pointerb = Marshal.GetFunctionPointerForDelegate(m_LateDelegate); //build hook code AsmBuilder hookcode = new AsmBuilder(); hookcode.Instructions.Add(new PushAll()); hookcode.Instructions.Add(new BackupEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PushImmediate(address)); hookcode.Instructions.Add(new CallRelative(unmanaged_hook_pointer.ToInt32())); hookcode.Instructions.Add(new TestEaxEax()); hookcode.Instructions.Add(new JzRelativeShort((int)skip_call_address)); hookcode.Instructions.Add(new RestoreEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PopAll()); //switch vtbl: return, non-call : jmp address+readsize, call, jmp original hookcode.Write(curprocess, m_HookMemory.Address.ToInt32()); if (original_address == 0) { curprocess.Position = m_HookMemory.Address.ToInt32() + 30; curprocess.Write(copied_instructions, 0, readsize); hookcode = new AsmBuilder(); hookcode.Instructions.Add(new JmpRelative((int)address + readsize)); } else { hookcode = new AsmBuilder(); hookcode.Instructions.Add(new JmpRelative((int)original_address)); } //end_code hookcode.Instructions.Add(new RestoreEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PopAll()); if (stack_cleanup_size == 0) { hookcode.Instructions.Add(new Rtn()); } else { hookcode.Instructions.Add(new RtnStackSize(stack_cleanup_size)); } hookcode.Write(curprocess, (int)m_HookMemory.Address.ToInt32() + 30 + readsize); hookcode = new AsmBuilder(); hookcode.Instructions.Add(new PushImmediate(0)); hookcode.Instructions.Add(new PushAll()); hookcode.Instructions.Add(new BackupEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PushImmediate(address)); hookcode.Instructions.Add(new CallRelative(unmanaged_hook_pointerb.ToInt32())); hookcode.Instructions.Add(new RestoreEsp((uint)m_EspBackup.Address.ToInt32())); hookcode.Instructions.Add(new PopAll()); hookcode.Instructions.Add(new Rtn()); hookcode.Write(curprocess, (int)m_HookMemory.Address.ToInt32() + 46 + readsize); m_LateHookAddress = (uint)(m_HookMemory.Address.ToInt32() + 46 + readsize); //install hook if (original_address != 0) { if (IsVtblEntry) { //vtbl_hook sh.Position = address; sh.Write <int>(m_HookMemory.Address.ToInt32()); } else { crel = new CallRelative((int)m_HookMemory.Address.ToInt32()); if (crel.Size != curinsn.Instruction.size) { throw new Exception("Can only hook call instructions with size equal to " + crel.Size.ToString()); } crel.Write(curprocess, (int)address); curprocess.Position = address + crel.Size; } } else { //random hook jrel = new JmpRelative((int)m_HookMemory.Address.ToInt32()); jrel.Write(curprocess, (int)address); curprocess.Position = address + jrel.Size; for (uint i = 0; i < (readsize - jrel.Size); i++) { curprocess.WriteByte(0x90);//NOP } } m_Hooks.Add(address, this); }