Ejemplo n.º 1
0
 public void UnHook()
 {
     if (m_Hooked)
     {
         ProcessHandler curproc = ProcessHandler.CurrentProcess;
         StreamHandler  sh      = new StreamHandler(curproc);
         if (original_address == 0)
         {
             sh.Position = m_Address;
             sh.Write(copied_instructions, 0, copied_instructions.Length);
         }
         else if (m_VtblHook)
         {
             sh.Position = m_Address;
             sh.Write <uint>(original_address);
         }
         else
         {
             CallRelative cr = new CallRelative((int)original_address);
             cr.Write(sh, (int)m_Address);
         }
         m_Hooks.Remove(m_Address);
         m_Hooked = false;
     }
 }
Ejemplo n.º 2
0
        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);
        }