using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Runtime.InteropServices; using System.Diagnostics; namespace guardPoke { //Code portions taken from https://github.com/ZenLulz/MemorySharp/ class MemoryTickler { [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr OpenProcess(int dwDesiredAccess,bool bInheritHandle, uint dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] static extern bool WriteProcessMemory(int hProcess, ulong lpBaseAddress,byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten); [DllImport("kernel32.dll", SetLastError = true)] static extern bool ReadProcessMemory(int hProcess, ulong lpBaseAddress,byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten); [DllImport("kernel32.dll", SetLastError = true)] static extern bool VirtualProtectEx(int hProcess, ulong lpAddress, int dwSize, uint flNewProtect, ref uint lpflOldProtect); [DllImport("kernel32.dll")] static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, int dwThreadId); [DllImport("kernel32.dll")] static extern uint SuspendThread(IntPtr hThread); [DllImport("kernel32.dll")] static extern int ResumeThread(IntPtr hThread); [DllImport("kernel32.dll")] static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext); [DllImport("kernel32.dll", SetLastError = true)] static extern bool CloseHandle(IntPtr hObject); const uint PAGE_EXECUTE_READWRITE = 0x40; const int PROCESS_ALL_ACCESS = 0x1FFFFF; const uint GET_CONTEXT = 0x08; public enum CONTEXT_FLAGS : uint { CONTEXT_i386 = 0x10000, CONTEXT_i486 = 0x10000, // same as i386 CONTEXT_CONTROL = CONTEXT_i386 | 0x01, // SS:SP, CS:IP, FLAGS, BP CONTEXT_INTEGER = CONTEXT_i386 | 0x02, // AX, BX, CX, DX, SI, DI CONTEXT_SEGMENTS = CONTEXT_i386 | 0x04, // DS, ES, FS, GS CONTEXT_FLOATING_POINT = CONTEXT_i386 | 0x08, // 387 state CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | 0x10, // DB 0-3,6,7 CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | 0x20, // cpu specific extensions CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS, CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS } [StructLayout(LayoutKind.Sequential)] public struct FLOATING_SAVE_AREA { public uint ControlWord; public uint StatusWord; public uint TagWord; public uint ErrorOffset; public uint ErrorSelector; public uint DataOffset; public uint DataSelector; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] RegisterArea; public uint Cr0NpxState; } [StructLayout(LayoutKind.Sequential)] public struct CONTEXT { public ulong ContextFlags; //set this to an appropriate value // Retrieved by CONTEXT_DEBUG_REGISTERS public ulong Dr0; public ulong Dr1; public ulong Dr2; public ulong Dr3; public ulong Dr6; public ulong Dr7; // Retrieved by CONTEXT_FLOATING_POINT public FLOATING_SAVE_AREA FloatSave; // Retrieved by CONTEXT_SEGMENTS public ulong SegGs; public ulong SegFs; public ulong SegEs; public ulong SegDs; // Retrieved by CONTEXT_INTEGER public ulong Edi; public ulong Esi; public ulong Ebx; public ulong Edx; public ulong Ecx; public ulong Eax; // Retrieved by CONTEXT_CONTROL public ulong Ebp; public ulong Eip; public ulong SegCs; public ulong EFlags; public ulong Esp; public ulong SegSs; // Retrieved by CONTEXT_EXTENDED_REGISTERS [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] ExtendedRegisters; } public int readVA(int pid,String modName,ulong va,out byte[] buffer,int length,bool abs) { Process.EnterDebugMode(); Process proc = Process.GetProcessById(pid); IntPtr procHandle = OpenProcess(PROCESS_ALL_ACCESS, false, (uint)proc.Id); uint stuff = 0; int num = 0; uint prot = 0; byte[] buff = new byte[length]; buffer = new byte[length]; if (!abs) { ulong ba = findBaseAddress(proc, modName); if (ba > 0) va = va + ba; else { buffer = null; CloseHandle(procHandle); return -2; } } bool ret = VirtualProtectEx((int)procHandle, va, length, PAGE_EXECUTE_READWRITE, ref prot); int err = Marshal.GetLastWin32Error(); ret = ReadProcessMemory((int)procHandle, va,buff, length, ref num); if (!ret) { err = Marshal.GetLastWin32Error(); buffer = null; CloseHandle(procHandle); return err; } ret = VirtualProtectEx((int)procHandle, va, length, prot, ref stuff); if (num != buff.Length) { buffer = null; CloseHandle(procHandle); return -1; } Array.Copy(buff, buffer,length); CloseHandle(procHandle); return 0; } public int tickleVA(int pid,String modName,ulong va,bool abs) { Process.EnterDebugMode(); //Process proc = Process.GetProcessesByName("notepad")[0]; Process proc = Process.GetProcessById(pid); IntPtr procHandle = OpenProcess(PROCESS_ALL_ACCESS, false, (uint)proc.Id); byte[] buffer = {0xBE,0xEF}; int buffLen = buffer.Length; uint stuff = 0; int num = 0; uint prot = 0; if (!abs) { //Find binary base address ulong ba = findBaseAddress(proc, modName); if (ba > 0) va = va + ba; else { CloseHandle(procHandle); return -2; } } bool ret = VirtualProtectEx((int)procHandle, va, buffer.Length, PAGE_EXECUTE_READWRITE, ref prot); int err = Marshal.GetLastWin32Error(); ret = WriteProcessMemory((int)procHandle, va, buffer, buffer.Length, ref num); if (!ret) { err = Marshal.GetLastWin32Error(); CloseHandle(procHandle); return err; } ret = VirtualProtectEx((int)procHandle, va, buffer.Length, prot, ref stuff); if (num != buffLen) { CloseHandle(procHandle); return -1; } CloseHandle(procHandle); return 0; } public int setBreakpoints(int pid,String modName,ulong va,bool abs) { Process.EnterDebugMode(); Process proc = Process.GetProcessById(pid); IntPtr procHandle = OpenProcess(PROCESS_ALL_ACCESS, false, (uint)pid); int tid = proc.Threads[0].Id; CONTEXT cxt = new CONTEXT(); cxt.ContextFlags = (uint)CONTEXT_FLAGS.CONTEXT_CONTROL; IntPtr hThread = OpenThread(GET_CONTEXT,false,tid); if (GetThreadContext(hThread, ref cxt)) { if (!abs) { //Find binary base address ulong ba = findBaseAddress(proc, modName); if (ba > 0) va = va + ba; else { CloseHandle(procHandle); return -2; } } //DR0 = va cxt.Dr0 = va; //DR7 = ((Length*4 + BP_type) shl (X*4 + 16)) + (1 shl (X*2)) //DR7 = ((0*4 + 11b) shl (0*4 + 16)) + (1 shl (0*2)) ulong i = Convert.ToUInt64("00110000000000000001",2); cxt.Dr7 = i; CloseHandle(procHandle); CloseHandle(hThread); return 0; } CloseHandle(hThread); CloseHandle(procHandle); return -1; } private ulong findBaseAddress(Process proc,String modName) { ProcessModuleCollection modCollect = proc.Modules; foreach (ProcessModule pm in modCollect) { if (pm.ModuleName.Contains(modName)) { return (ulong)pm.BaseAddress; } } return 0; } } }