private void updateContext(int threadId)
        {
            IntPtr hThread = getThreadHandle(threadId);

            Win64.CONTEXT ctx = Context;
            Win64.SetThreadContext(hThread, ref ctx);
        }
        /// <summary>
        /// Allocates memory in the debugged process.
        /// </summary>
        /// <param name="size">The number of bytes to allocate.</param>
        /// <param name="address">The output variable containing the address of the allocated memory.</param>
        /// <returns></returns>
        public NIDebugger64 AllocateMemory(uint size, out ulong address)
        {
            IntPtr memLocation = Win64.VirtualAllocEx((IntPtr)debuggedProcessInfo.hProcess, new IntPtr(), size, (uint)Win64.StateEnum.MEM_RESERVE | (uint)Win64.StateEnum.MEM_COMMIT, (uint)Win64.AllocationProtectEnum.PAGE_EXECUTE_READWRITE);

            address = (ulong)memLocation;
            return(this);
        }
        public NIDebugger64 Execute(NIStartupOptions opts)
        {
            Win64.SECURITY_ATTRIBUTES sa1 = new Win64.SECURITY_ATTRIBUTES();
            sa1.nLength = Marshal.SizeOf(sa1);
            Win64.SECURITY_ATTRIBUTES sa2 = new Win64.SECURITY_ATTRIBUTES();
            sa2.nLength = Marshal.SizeOf(sa2);
            Win64.STARTUPINFO si = new Win64.STARTUPINFO();
            debuggedProcessInfo = new Win64.PROCESS_INFORMATION();
            int ret = Win64.CreateProcess(opts.executable, opts.commandLine, ref sa1, ref sa2, 0, 0x00000200 | Win64.CREATE_SUSPENDED, 0, null, ref si, ref debuggedProcessInfo);

            debuggedProcess = Process.GetProcessById(debuggedProcessInfo.dwProcessId);
            threadHandles.Add(debuggedProcessInfo.dwThreadId, debuggedProcessInfo.hThread);

            if (opts.resumeOnCreate)
            {
                Win64.ResumeThread((IntPtr)debuggedProcessInfo.hThread);
            }
            else
            {
                Context = getContext(getCurrentThreadId());

                ulong OEP = Context.Rcx;

                SetBreakpoint(OEP);
                Continue();
                ClearBreakpoint(OEP);

                Console.WriteLine("We should be at OEP");
            }



            return(this);
        }
 private void pauseAllThreads()
 {
     foreach (ProcessThread t in debuggedProcess.Threads)
     {
         IntPtr hThread = getThreadHandle(t.Id);
         Win64.SuspendThread(hThread);
     }
 }
        /// <summary>
        /// Reads binary data from the debugged process, starting at a given address and reading a given amount of bytes.
        /// </summary>
        /// <param name="address">The address to begin reading.</param>
        /// <param name="length">The number of bytes to read.</param>
        /// <param name="output">The output variable that will contain the read data.</param>
        /// <returns></returns>
        public NIDebugger64 ReadData(ulong address, int length, out byte[] output)
        {
            ulong numRead = 0;

            byte[] data = new byte[length];
            Win64.ReadProcessMemory((ulong)debuggedProcessInfo.hProcess, address, data, length, ref numRead);

            output = data;

            return(this);
        }
        private Win64.CONTEXT getContext(int threadId)
        {
            IntPtr hThread = getThreadHandle(threadId);

            Win64.CONTEXT ctx = new Win64.CONTEXT();
            ctx.ContextFlags = (uint)Win64.CONTEXT_FLAGS.CONTEXT_ALL;
            Win64.GetThreadContext(hThread, ref ctx);
            int foo = Marshal.SizeOf(ctx);

            Context = ctx;
            return(ctx);
        }
 private void resumeAllThreads()
 {
     foreach (ProcessThread t in debuggedProcess.Threads)
     {
         IntPtr hThread = getThreadHandle(t.Id);
         int    result  = Win64.ResumeThread(hThread);
         while (result > 1)
         {
             result = Win64.ResumeThread(hThread);
         }
     }
 }
        public NIDebugger64 WriteData(ulong address, byte[] data)
        {
            Win64.MEMORY_BASIC_INFORMATION mbi = new Win64.MEMORY_BASIC_INFORMATION();

            Win64.VirtualQueryEx((ulong)debuggedProcessInfo.hProcess, address, out mbi, (uint)Marshal.SizeOf(mbi));
            uint oldProtect = 0;

            Win64.VirtualProtectEx((IntPtr)debuggedProcessInfo.hProcess, (IntPtr)mbi.BaseAddress, (UIntPtr)mbi.RegionSize, (uint)Win64.AllocationProtectEnum.PAGE_EXECUTE_READWRITE, out oldProtect);

            ulong numWritten = 0;

            Win64.WriteProcessMemory((ulong)debuggedProcessInfo.hProcess, address, data, data.Length, ref numWritten);

            Win64.VirtualProtectEx((IntPtr)debuggedProcessInfo.hProcess, (IntPtr)mbi.BaseAddress, (UIntPtr)mbi.RegionSize, oldProtect, out oldProtect);

            return(this);
        }
        private Win64.MODULEENTRY32 getModule(String modName)
        {
            IntPtr hSnap = Win64.CreateToolhelp32Snapshot(Win64.SnapshotFlags.NoHeaps | Win64.SnapshotFlags.Module, (uint)debuggedProcessInfo.dwProcessId);

            Win64.MODULEENTRY32 module = new Win64.MODULEENTRY32();
            module.dwSize = (uint)Marshal.SizeOf(module);
            Win64.Module32First(hSnap, ref module);

            if (module.szModule.Equals(modName, StringComparison.CurrentCultureIgnoreCase))
            {
                return(module);
            }

            while (Win64.Module32Next(hSnap, ref module))
            {
                if (module.szModule.Equals(modName, StringComparison.CurrentCultureIgnoreCase))
                {
                    return(module);
                }
            }
            module = new Win64.MODULEENTRY32();
            Win64.CloseHandle(hSnap);
            return(module);
        }