Files
2025-09-29 00:52:08 +02:00

159 lines
6.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;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
//Portions taken from http://csharptest.net/1051/managed-anti-debugging-how-to-prevent-users-from-attaching-a-debugger/
namespace guardPoke
{
class Mebugger
{
public Mebugger(int ipid)
{
pid = ipid;
}
//DebuggerWatcher dbgWatch = new DebuggerWatcher();
//Thread watchThread;
private int pid;
private volatile bool _shouldStop = false;
private const int DBG_CONTINUE = 0x00010002;
private const int DBG_EXCEPTION_NOT_HANDLED = unchecked((int)0x80010001);
private enum DebugEventType : int
{
CREATE_PROCESS_DEBUG_EVENT = 3, //Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure.
CREATE_THREAD_DEBUG_EVENT = 2, //Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure.
EXCEPTION_DEBUG_EVENT = 1, //Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure.
EXIT_PROCESS_DEBUG_EVENT = 5, //Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure.
EXIT_THREAD_DEBUG_EVENT = 4, //Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure.
LOAD_DLL_DEBUG_EVENT = 6, //Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure.
OUTPUT_DEBUG_STRING_EVENT = 8, //Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure.
RIP_EVENT = 9, //Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure.
UNLOAD_DLL_DEBUG_EVENT = 7, //Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure.
}
[StructLayout(LayoutKind.Sequential)]
private struct DEBUG_EVENT
{
[MarshalAs(UnmanagedType.I4)]
public DebugEventType dwDebugEventCode;
public int dwProcessId;
public int dwThreadId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public byte[] bytes;
}
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern bool DebugActiveProcess(int dwProcessId);
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern bool WaitForDebugEvent([Out] out DEBUG_EVENT lpDebugEvent, int dwMilliseconds);
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern bool ContinueDebugEvent(int dwProcessId, int dwThreadId, int dwContinueStatus);
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern bool IsDebuggerPresent();
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern ulong GetLastError();
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern bool DebugActiveProcessStop(int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
// Debugging thread main loop
public void debugTarget(object pidObj)
{
int pid = (int)pidObj;
Process.EnterDebugMode();
DEBUG_EVENT evt = new DEBUG_EVENT();
evt.bytes = new byte[1024];
if (!DebugActiveProcess(pid))
return;// Marshal.GetLastWin32Error();
while (true)
{
// wait for a debug event
if (!WaitForDebugEvent(out evt, -1))
return;// Marshal.GetLastWin32Error();
// return DBG_CONTINUE for all events but the exception type
int continueFlag = DBG_CONTINUE;
if (evt.dwDebugEventCode == DebugEventType.EXCEPTION_DEBUG_EVENT)
continueFlag = DBG_EXCEPTION_NOT_HANDLED;
// continue running the debugee
ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueFlag);
while (!_shouldStop)
{
while (WaitForDebugEvent(out evt, 100))
{
ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueFlag);
}
ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueFlag);
}
DebugActiveProcessStop(pid);
//watchThread = new Thread(dbgWatch.handleEvents);
//watchThread.Start();
//while (!watchThread.IsAlive) ;
//Thread.Sleep(1);
//while (WaitForDebugEvent(out evt, 100))
//{
// ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueFlag);
//}
//ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueFlag);
return;// 0;
}
}
public void RequestStop()
{
_shouldStop = true;
}
}
public class DebuggerWatcher
{
Mebugger dbg;
Thread watchThread;
public int debugTarget(int pid)
{
dbg = new Mebugger(pid);
//int ret = dbg.debugTarget(pid);
//if (ret != 0)
// return ret;
watchThread = new Thread(dbg.debugTarget);
watchThread.Start((object)pid);
while (!watchThread.IsAlive) ;
Thread.Sleep(1);
return 0;
}
public void stopDebug()
{
dbg.RequestStop();
watchThread.Join();
}
}
}