예제 #1
0
파일: NativeHook.cs 프로젝트: 5l1v3r1/Aphid
        public static bool Hook(ProcessMemory memory, IntPtr funcAddr, TrampolineHeap heap)
        {
            var objectCode      = _nops.ToArray();
            var trampolineAddr  = heap.Allocate((uint)objectCode.Length);
            var jmpToTrampoline = CreateJmpRel32((uint)funcAddr, (uint)trampolineAddr);
            var originalCode    = memory.ReadBytes(funcAddr, 0x100);
            var dasm            = IA32Disassembler.Disassemble(originalCode);

            var matches = dasm
                          .TakeWhile(x => ((Opcode[])Enum.GetValues(typeof(Opcode))).Contains(x.Opcode.Opcode))
                          .ToArray();

            var matchSum = matches.Sum(x => x.Size);
            var sum      = 0;

            dasm.TakeWhile(x => (sum += x.Size) < jmpToTrampoline.Length).ToArray();

            if (matchSum < sum)
            {
                return(false);
            }

            var originalCodeCopy = originalCode.ToArray();

            Array.Resize(ref originalCode, sum);
            originalCodeCopy = originalCodeCopy.Skip(originalCode.Length).ToArray();
            //0x10 8B 4C 24 14 8B 7C 24 0C 8B
            if (originalCodeCopy[0] == 0x10 &&
                originalCodeCopy[1] == 0x8B &&
                originalCodeCopy[2] == 0x4C &&
                originalCodeCopy[3] == 0x24 &&
                originalCodeCopy[4] == 0x14 &&
                originalCodeCopy[5] == 0x8B &&
                originalCodeCopy[6] == 0x7C &&
                originalCodeCopy[7] == 0x24 &&
                originalCodeCopy[8] == 0x0C &&
                originalCodeCopy[9] == 0x8B)
            {
                Console.WriteLine();
            }

            const int originalCodeOffset = 0x10;

            originalCode.CopyTo(objectCode, originalCodeOffset);
            var jmpToFuncOffset = (uint)originalCodeOffset + (uint)originalCode.Length + 0x4;
            //objectCode[(uint)originalCodeOffset + (uint)originalCode.Length + 1] = 0xCC;

            var jmpToFunc = CreateJmpRel32(
                (uint)trampolineAddr + jmpToFuncOffset,
                (uint)funcAddr + (uint)originalCode.Length);

            jmpToFunc.CopyTo(objectCode, jmpToFuncOffset);
            memory.Write(trampolineAddr, objectCode);
            memory.Write(funcAddr, jmpToTrampoline);

            return(true);
        }
예제 #2
0
 public BreakpointManager(ProcessMemory memory)
 {
     BreakpointTable = new Dictionary <IntPtr, byte>();
     HitTable        = new Dictionary <IntPtr, uint>();
     MaxHits         = 0x1;
     ThreadCache     = new Cache <uint, IntPtr>(x => Kernel32.OpenThread(
                                                    ThreadAccess.THREAD_GET_CONTEXT | ThreadAccess.THREAD_SET_CONTEXT,
                                                    false,
                                                    x));
     mem = memory;
 }
예제 #3
0
        public ProcessMemory GetMemory(IntPtr processHandle)
        {
            lock (_readers)
            {
                if (!_readers.TryGetValue(processHandle, out var mem))
                {
                    _readers.Add(processHandle, mem = new ProcessMemory(processHandle));
                }

                return(mem);
            }
        }
예제 #4
0
        public List <uint> GetFunctionPointers(int count)
        {
            var pointers = new List <uint>();
            var reader   = new ProcessMemory(Process);
            var context  = ProcessMemory.GetContext(ThreadId);

            //var pointers = new List<uint> { context.Eip };

            uint[] stack = null;
            var    ptr   = IntPtr.Zero;

            try
            {
                ptr = (IntPtr)context.Esp;
            }
            catch { }

            if (ptr != IntPtr.Zero)
            {
                stack = reader.ReadUInt32s(ptr, count / 4);
            }

            if (stack == null)
            {
                return(null);
            }

            foreach (var p in GetIntPtrs(stack))
            {
                var bytes = reader.ReadBytes(p, 0x20);

                if (bytes == null ||
                    //IsStackAddress(context, (uint)p) ||
                    !reader.IsExecutable(p))
                {
                    continue;
                }

                pointers.Add((uint)p);

                //var dasm = new DiStormWrapper().Disassemble(bytes);
            }

            return(pointers);
        }
예제 #5
0
        public DebuggerEventArgs(
            IntPtr processHandle,
            byte[] faultingInstructions,
            string instructionHash,
            DEBUG_EVENT debugEvent,
            ProcessMemory memory
#if FULL_DBG
            ,
            BreakpointManager breakpoints,
            HookManager hooks
#endif
            )
        {
            ProcessHandle        = processHandle;
            FaultingInstructions = faultingInstructions;
            InstructionHash      = instructionHash;
            DebugEvent           = debugEvent;
            Memory = memory;
#if FULL_DBG
            Breakpoints = breakpoints;
            Hooks       = hooks;
#endif
        }
예제 #6
0
        public void ProcessDebugEvents()
        {
            IsStarted = true;
            var debugEvent = new DEBUG_EVENT();

            while (!_killProcesses && IsStarted && Processes.Count != 0)
            {
                if (!Kernel32.WaitForDebugEvent(ref debugEvent, 200))
                {
                    var error = Marshal.GetLastWin32Error();

                    //if (error == 121 || _killProcesses)

                    /*if (_killProcesses)
                     * {
                     *  KillCore();
                     *  break;
                     * }
                     * else */if (error != 121)
                    {
                        throw new Win32Exception(error);
                    }

                    if (Timeout > 0 &&
                        (DateTime.Now - StartTime).TotalMilliseconds > Timeout)
                    {
                        Kill();

                        return;
                    }

                    continue;
                }

                Process p = null;

                LockProcesses(() =>
                {
                    if (_processTable.ContainsKey(debugEvent.dwProcessId))
                    {
                        p = _processTable[debugEvent.dwProcessId];
                    }
                });

                byte[] buffer = null;
                var    hash   = "[NO HASH]";

                switch (debugEvent.dwDebugEventCode)
                {
                case DebugEventType.CREATE_PROCESS_DEBUG_EVENT:
                    if (p != null)
                    {
                        var mem = new ProcessMemory(p.Handle);
                        lock (_readers)
                        {
                            _readers.Add(p.Handle, mem);
                        }

#if FULL_DBG
                        if (!_hookManagers.ContainsKey(p.Handle))
                        {
                            _hookManagers.Add(p.Handle, new HookManager(mem));
                            _breakpointManagers.Add(p.Handle, new BreakpointManager(mem));
                        }
#endif
                    }
                    lock (_loaderBreakpointTable)
                    {
                        if (!_loaderBreakpointTable.ContainsKey(debugEvent.dwProcessId))
                        {
                            _loaderBreakpointTable.Add(debugEvent.dwProcessId, false);
                        }
                    }
                    LockProcesses(() =>
                    {
                        AddProcess(debugEvent.dwProcessId);
                        p = _processTable[debugEvent.dwProcessId];
                    });
                    Kernel32.CloseHandle(debugEvent.CreateProcessInfo.hFile);
                    break;

                case DebugEventType.EXIT_PROCESS_DEBUG_EVENT:
                    lock (_loaderBreakpointTable)
                    {
                        if (_loaderBreakpointTable.ContainsKey(debugEvent.dwProcessId))
                        {
                            _loaderBreakpointTable.Remove(debugEvent.dwProcessId);
                        }
                    }

                    LockProcesses(() => RemoveProcess(debugEvent.dwProcessId));

                    if (p != null)
                    {
                        lock (_readers)
                        {
                            try
                            {
                                // Swallow exceptions caused by accessing Process.Handle after
                                // process has exited.
                                _readers.Remove(p.Handle);
                            }
                            catch { }
                        }
                    }
                    break;

                case DebugEventType.LOAD_DLL_DEBUG_EVENT:
                    Kernel32.CloseHandle(debugEvent.LoadDll.hFile);
                    break;

                case DebugEventType.EXCEPTION_DEBUG_EVENT:
                    lock (_loaderBreakpointTable)
                    {
                        if (debugEvent.Exception.ExceptionRecord.ExceptionCode == ExceptionCode.EXCEPTION_BREAKPOINT)
                        {
                            if (!_loaderBreakpointTable.ContainsKey(debugEvent.dwProcessId))
                            {
                                _loaderBreakpointTable.Add(debugEvent.dwProcessId, false);
                            }

                            if (!_loaderBreakpointTable[debugEvent.dwProcessId])
                            {
                                _loaderBreakpointTable[debugEvent.dwProcessId] = true;

                                debugEvent.ContinueUnhandled();
                                continue;
                            }
                        }
                    }

                    if (p != null)
                    {
                        if (HashException)
                        {
                            hash = GetExceptionHash(p, debugEvent);
                        }

                        if (ReadFaultingInstructions)
                        {
                            buffer = new byte[32];
                            var exPtr = IntPtr.Zero;

                            try
                            {
                                exPtr = (IntPtr)debugEvent.Exception.ExceptionRecord.ExceptionAddress;
                            }
                            catch (OverflowException)
                            {
                            }

                            if (Kernel32.ReadProcessMemory(
                                    p.Handle,
                                    exPtr,
                                    buffer,
                                    new IntPtr(buffer.Length),
                                    out var bytesRead))
                            {
                                if (bytesRead < buffer.Length)
                                {
                                    Array.Resize(ref buffer, bytesRead);
                                }
                            }
                            else
                            {
                                buffer = null;
                            }

                            //hash = CreateInstructionHash(buffer.Take(HashSize));
                        }
                    }
                    //elser
                    //{
                    //    throw new InvalidOperationException();
                    //}

                    break;
                }

                if (DebugEventReceived != null)
                {
                    IntPtr handle;
                    try
                    {
                        handle = p != null ? p.Handle : IntPtr.Zero;
                    }
                    catch
                    {
                        handle = IntPtr.Zero;
                    }

#if FULL_DBG
                    if (!_breakpointManagers.TryGetValue(handle, out var breakpoints))
                    {
                        _breakpointManagers.Add(handle, breakpoints = new BreakpointManager(GetMemory(handle)));
                    }

                    if (!_hookManagers.TryGetValue(handle, out var hooks))
                    {
                        _hookManagers.Add(handle, hooks = new HookManager(GetMemory(handle)));
                    }
#endif
                    DebugEventReceived(this,
                                       new DebuggerEventArgs(
                                           handle,
                                           buffer,
                                           hash,
                                           debugEvent,
                                           GetMemory(handle)
#if FULL_DBG
                                           ,
                                           breakpoints,
                                           hooks
#endif
                                           ));
                }

                if (Timeout > 0 &&
                    (DateTime.Now - StartTime).TotalMilliseconds > Timeout)
                {
                    Kill();

                    return;
                }
            }

            //KillCore();
        }
예제 #7
0
 public HookManager(ProcessMemory memory) => _heap = new TrampolineHeap(_memory = memory);
예제 #8
0
 public TrampolineHeap(ProcessMemory memory)
 {
     BlockSize = 0x1000;
     _memory   = memory;
 }