def is_debugger_present():
kernel32 = ctypes.windll.kernel32
ntdll = ctypes.windll.ntdll
if kernel32.IsDebuggerPresent():
return True
is_remote_present = ctypes.c_bool(False)
kernel32.CheckRemoteDebuggerPresent(kernel32.GetCurrentProcess(), ctypes.byref(is_remote_present))
if is_remote_present.value:
return True
class PROCESS_BASIC_INFORMATION(ctypes.Structure):
_fields_ = [
("ExitStatus", ctypes.c_ulong),
("PebBaseAddress", ctypes.c_void_p),
("AffinityMask", ctypes.c_ulonglong),
("BasePriority", ctypes.c_long),
("UniqueProcessId", ctypes.c_ulonglong),
("InheritedFromUniqueProcessId", ctypes.c_ulonglong),
]
pbi = PROCESS_BASIC_INFORMATION()
size = ctypes.c_ulong()
status = ntdll.NtQueryInformationProcess(
kernel32.GetCurrentProcess(),
0, # ProcessBasicInformation
ctypes.byref(pbi),
ctypes.sizeof(pbi),
ctypes.byref(size)
)
if status != 0:
return False
peb_address = pbi.PebBaseAddress
if not peb_address:
return False
debug_flag = ctypes.c_byte()
bytes_read = ctypes.c_size_t()
read_success = kernel32.ReadProcessMemory(
kernel32.GetCurrentProcess(),
ctypes.c_void_p(peb_address + 2),
ctypes.byref(debug_flag),
1,
ctypes.byref(bytes_read)
)
if read_success and debug_flag.value != 0:
return True
return False