262 lines
9.5 KiB
C#
Executable File
262 lines
9.5 KiB
C#
Executable File
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;
|
|
}
|
|
}
|
|
|
|
}
|