159 lines
6.5 KiB
C#
Executable File
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();
|
|
}
|
|
}
|
|
|
|
} |