概述
PEB相关
bool PEB_BeingDebugged()
{
bool BeingDebugged = false;
_asm
{
mov eax, dword ptr fs : [0x30];//dt _PEB
mov al, byte ptr ds : [eax + 0x02];//BeingDebugged
mov BeingDebugged, al;
}
return BeingDebugged;
}
int main()
{
bool bDebug = false;
bDebug = PEB_BeingDebugged();//等价于IsDebuggerPresent()
printf("%dn", bDebug);
system("pause");
return 0;
}
- ProcessHeap的Flags与ForceFlags正常情况下为2与0,处于调试态会发生改变,此方法在NT 5.x版本以上无效。
bool PEB_ProcessHeap()
{
int nFlags = 0;
int nForceFlags = 0;
_asm
{
PUSHAD;
mov eax, dword ptr FS : [0x30];
mov eax, dword ptr ds : [eax + 0x18];
mov ebx, dword ptr ds : [eax + 0x0c];
mov ecx, dword ptr ds : [eax + 0x10];
mov nFlags, ebx;
mov nForceFlags, ecx;
POPAD;
}
return (nFlags == 2 && nForceFlags == 0) ? false : true;
}
int main()
{
bool bDebug = false;
bDebug = PEB_ProcessHeap();
printf("%dn", bDebug);
system("pause");
return 0;
}
- NtGlobalFlag在当前进程处于调试状态时的值为0x70
bool PEB_NtGlobalFlag()
{
int nNtGlobalFlag = 0;
_asm
{
mov eax, dword ptr fs:[0x30];
mov eax, dword ptr ds : [eax + 0x68];
mov nNtGlobalFlag, eax;
}
return (nNtGlobalFlag != 0x70) ? false : true;
}
int main()
{
bool bDebug = false;
bDebug = PEB_NtGlobalFlag();
printf("%dn", bDebug);
system("pause");
return 0;
}
- NtQueryInformationProcess-ProcessDebugPort,如果目标进程处于未调试状态,端口为0,否则为0xFFFFFFFF
bool NQIP_ProcessDebug()
{
int nDebugPort = 0;
NtQueryInformationProcess(
GetCurrentProcess(),
ProcessDebugPort,
&nDebugPort,
sizeof(nDebugPort),
NULL);
return nDebugPort == 0xFFFFFFFF ? true : false;
}
int main()
{
bool nDebug = false;
nDebug = NQIP_ProcessDebug();
printf("%dn", nDebug);
system("pause");
return 0;
}
- ProcessDebugObjectHandle可以获取目标进程的调试对象句柄,如果未处于调试状态,则获取的值为NULL
bool NQIP_ProcessDebugObjectHandle()
{
HANDLE hDebug = NULL;
NtQueryInformationProcess(
GetCurrentProcess(),
(PROCESSINFOCLASS)0x1E,
&hDebug,
sizeof(hDebug),
NULL);
return hDebug? true : false;
}
int main()
{
bool nDebug = false;
nDebug = NQIP_ProcessDebugObjectHandle();
printf("%dn", nDebug);
system("pause");
return 0;
}
- ProcessDebugFlag可获取目标进程的调试标记,若处于调试状态值为0,否则为1
bool NQIP_ProcessDebugFlag()
{
BOOL bDebugFlag = FALSE;
NtQueryInformationProcess(
GetCurrentProcess(),
(PROCESSINFOCLASS)0x1F,
&bDebugFlag,
sizeof(bDebugFlag),
NULL);
return bDebugFlag ? false : true;
}
int main()
{
bool nDebug = false;
nDebug = NQIP_ProcessDebugFlag();
printf("%dn", nDebug);
system("pause");
return 0;
}
- 可获取指定进程的父进程PID,将其与Explorer.exe的PID对比,不匹配则不是被双击运行的。
bool NQIP_CheckParentProcess()
{
struct PROCESS_BASIC_INFORMATION
{
ULONG ExitStatus;//进程返回码
PPEB PebBaseAddress;//PEB地址
ULONG AffinityMask;//CPU亲和性掩码
LONG BasePriority;//基本优先级
ULONG UniqueProcessId;//本进程PID
ULONG InheritedFromUniqueProcessId;//父进程PID
}stcProcInfo;
NtQueryInformationProcess(
GetCurrentProcess(),
ProcessBasicInformation,
&stcProcInfo,
sizeof(stcProcInfo),
NULL);
DWORD dwExplorerPID = 0;
DWORD dwCurrentPID = stcProcInfo.InheritedFromUniqueProcessId;
GetWindowThreadProcessId(FindWindow("explorer.exe", NULL), &dwExplorerPID);
return dwExplorerPID == dwCurrentPID ? false : true;
}
int main()
{
bool nDebug = false;
nDebug = NQIP_CheckParentProcess();
printf("%dn", nDebug);
system("pause");
return 0;
}
- NtQuerySystemInformation()可获取当前系统是否开启调试模式
bool NQSI_SystemKernelDebuggerInformation()
{
struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
{
BOOLEAN DebuggerEnabled;
BOOLEAN DebuggerNotPresent;
}DebuggerInfo = {0};
NtQuerySystemInformation(
(SYSTEM_INFORMATION_CLASS)0x23,
&DebuggerInfo,
sizeof(DebuggerInfo),
NULL);
return DebuggerInfo.DebuggerEnabled;
}
int main()
{
BOOLEAN bDebug = FALSE;
bDebug = NQSI_SystemKernelDebuggerInformation();
printf("%dn", bDebug);
system("pause");
return 0;
}
- NtQueryObject
bool NQO_NtQueryObject()
{
typedef struct _OBJECT_TYPE_INFORMATION
{
UNICODE_STRING TypeName;
ULONG TotalNumberOfHandlers;
ULONG TotalNumberOfObjects;
}OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
typedef struct _OBJECT_ALL_INFORMATION
{
ULONG NumberOfObjectTypes;
OBJECT_TYPE_INFORMATION ObjTypeInfo[1];
}OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION;
ULONG uSize = 0;
NtQueryObject(NULL, (OBJECT_INFORMATION_CLASS)0x03, &uSize, sizeof(uSize), &uSize);
POBJECT_ALL_INFORMATION pObj = (POBJECT_ALL_INFORMATION)new BYTE[uSize];
NtQueryObject(NULL, (OBJECT_INFORMATION_CLASS)0x03, pObj, uSize, &uSize);
POBJECT_TYPE_INFORMATION pObjTypeInfo = pObj->ObjTypeInfo;
for (int i = 0; i < pObj->NumberOfObjectTypes; ++i)
{
if (!wcscmp(L"DebugObject", pObjTypeInfo->TypeName.Buffer))return true;
//获取对象名占用空间大小
ULONG uNameLength = pObjTypeInfo->TypeName.Length;
ULONG uDataLength = uNameLength - uNameLength % sizeof(ULONG) + sizeof(ULONG);
//指向下一个对象
pObjTypeInfo = (POBJECT_TYPE_INFORMATION)pObjTypeInfo->TypeName.Buffer;
pObjTypeInfo = (POBJECT_TYPE_INFORMATION)((PBYTE)pObjTypeInfo + uDataLength);
}
delete[] pObj;
return false;
}
int main()
{
bool bDebug = false;
bDebug = NQO_NtQueryObject();
printf("%dn", bDebug);
system("pause");
return 0;
}
- ZwSetInformationThread,此函数可以主动脱离调试器,这个碉堡了。
typedef enum THREAD_INFO_CLASS
{ ThreadHideFromDebugger = 17 };
typedef NTSTATUS(NTAPI *ZW_SET_INFORMATION_THREAD)
(
_In_ HANDLE ThreadHandle,
_In_ THREAD_INFO_CLASS ThreadInformationClass,
_In_ PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength
);
void ZSIT_DetachDebug()
{
ZW_SET_INFORMATION_THREAD Func;
Func = (ZW_SET_INFORMATION_THREAD)GetProcAddress(LoadLibrary("ntdll.dll"), "ZwSetInformationThread");
Func(GetCurrentThread(), ThreadHideFromDebugger, NULL, NULL);
}
int main()
{
ZSIT_DetachDebug();
return 0;
}
最后
以上就是积极背包为你收集整理的与调试相关的系统级函数的全部内容,希望文章能够帮你解决与调试相关的系统级函数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复