http://ucooper.com 7. PEB.NtGlobalFlag , Heap.HeapFlags, Heap.ForceFlags
(1)通常程序没有被调试时,PEB另一个成员NtGlobalFlag(偏移0x68)值为0,如果进程被调试通常值为0x70(代表下述标志被设置): FLG_HEAP_ENABLE_TAIL_CHECK(0X10) FLG_HEAP_ENABLE_FREE_CHECK(0X20) FLG_HEAP_VALIDATE_PARAMETERS(0X40)
这些标志是在ntdll!LdrpInitializeExecutionOptions()里设置的。请注意PEB.NtGlobalFlag的默认值可以通过gflags.exe工具或者在注册表以下位置创建条目来修改:
HKLM\\Software\\Microsoft\\Windows Nt\\CurrentVersion\\Image File Execution Options
assume fs:nothing
mov eax,fs:[30h] mov eax,[eax+68h] and eax,70h
(2)由于NtGlobalFlag标志的设置,堆也会打开几个标志,这个变化可以在ntdll!RtlCreateHeap()里观测到。正常情况下系统为进程创建第一个堆时会将Flags和ForceFlags分别设为2(HEAP_GROWABLE)和0 。当进程被调试时,这两个标志通常被设为50000062(取决于NtGlobalFlag)和0x40000060(等于Flags AND 0x6001007D)。
assume fs:nothing
mov ebx,fs:[30h] ;ebx指向PEB mov eax,[ebx+18h] ;PEB.ProcessHeap
cmp dword ptr [eax+0ch],2 ;PEB.ProcessHeap.Flags jne debugger_found cmp dword ptr [eax+10h],0 ;PEB.ProcessHeap.ForceFlags jne debugger_found
这些标志位都是因为BeingDebugged引起的。系统创建进程的时候设置BeingDebugged=TRUE,后来NtGlobalFlag根据这个标记设置FLG_VALIDATE_PARAMETERS等标记。在为进程创建堆时,又由于NtGlobalFlag的作用,堆的Flags被设置了一些标记,这个Flags随即被填充到ProcessHeap的Flags和ForceFlags中,同时堆中被填充了很多BAADF00D之类的东西(HeapMagic,也可用来检测调试)。 一次性解决这些状态见加密解密P413
//********************************************** typedef ULONG NTSTATUS; typedef ULONG PPEB; typedef ULONG KAFFINITY; typedef ULONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION { // Information Class 0 NTSTATUS ExitStatus; PPEB PebBaseAddress; KAFFINITY AffinityMask; KPRIORITY BasePriority; ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等
http://ucooper.com } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
typedef enum _PROCESSINFOCLASS { ProcessBasicInformation, // 0 Y N ProcessQuotaLimits, // 1 Y Y ProcessIoCounters, // 2 Y N ProcessVmCounters, // 3 Y N ProcessTimes, // 4 Y N ProcessBasePriority, // 5 N Y ProcessRaisePriority, // 6 N Y ProcessDebugPort, // 7 Y Y ProcessExceptionPort, // 8 N Y ProcessAccessToken, // 9 N Y ProcessLdtInformation, // 10 Y Y ProcessLdtSize, // 11 N Y
ProcessDefaultHardErrorMode, // 12 Y Y ProcessIoPortHandlers, // 13 N Y ProcessPooledUsageAndLimits, // 14 Y N ProcessWorkingSetWatch, // 15 Y Y ProcessUserModeIOPL, // 16 N Y
ProcessEnableAlignmentFaultFixup, // 17 N Y ProcessPriorityClass, // 18 N Y ProcessWx86Information, // 19 Y N ProcessHandleCount, // 20 Y N ProcessAffinityMask, // 21 N Y ProcessPriorityBoost, // 22 Y Y ProcessDeviceMap,// 23 Y Y ProcessSessionInformation, // 24 Y Y ProcessForegroundInformation, // 25 N Y ProcessWow64Information // 26 Y N } PROCESSINFOCLASS;
typedef NTSTATUS (_stdcall *ZwQueryInformationProcess)( HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength ); //定义函数指针
void CDetectODDlg::OnPebflags() {
// TODO: Add your control notification handler code here
//定义函数指针变量
写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等
http://ucooper.com
ZwQueryInformationProcess MyZwQueryInformationProcess;
HANDLE hProcess = NULL;
PROCESS_BASIC_INFORMATION pbi = {0};
ULONG peb = 0; ULONG cnt = 0;
ULONG PebBase = 0; ULONG AddrBase; BOOL bFoundOD=FALSE; WORD flag; DWORD dwFlag; DWORD bytesrw;
DWORD ProcessId=GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessId);
if (hProcess != NULL) {
MyZwQueryInformationProcess=(ZwQueryInformationProcess)GetProcAddress(LoadLibrary(\wQueryInformationProcess\ //函数指针变量调用
if (MyZwQueryInformationProcess( {
AddrBase=PebBase; if
(ReadProcessMemory(hProcess,(LPCVOID)(PebBase+0x68),&flag,2,&bytesrw)
&&
ProcessBasicInformation, &pbi,
sizeof(PROCESS_BASIC_INFORMATION), &cnt) == 0)
hProcess,
//函数指针变量赋值
PebBase = (ULONG)pbi.PebBaseAddress; //获取PEB地址
bytesrw==2) //读内存地址
{ //PEB.NtGlobalFlag } if { } if
(ReadProcessMemory(hProcess,(LPCVOID)(AddrBase+0x0c),&flag,2,&bytesrw)
&&
AddrBase=dwFlag;
(ReadProcessMemory(hProcess,(LPCVOID)(PebBase+0x18),&dwFlag,4,&bytesrw)
&&
if(0x70==flag){ }
bFoundOD=TRUE;
bytesrw==4)
bytesrw==2)
写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等
http://ucooper.com
{//PEB.ProcessHeap.Flags } if
(ReadProcessMemory(hProcess,(LPCVOID)(AddrBase+0x10),&flag,2,&bytesrw)
&&
if(2!=flag){ }
bFoundOD=TRUE;
bytesrw==2)
{//PEB.ProcessHeap.ForceFlags }
if(bFoundOD==FALSE) { } else { }
AfxMessageBox(\发现OD\AfxMessageBox(\没有OD\if(0!=flag){ }
bFoundOD=TRUE;
}
CloseHandle(hProcess); } }
8. DebugPort: CheckRemoteDebuggerPresent()/NtQueryInformationProcess()
Kernel32!CheckRemoteDebuggerPresent()是用于确定是否有调试器被附加到进程。 BOOL CheckRemoteDebuggerPresent( HANDLE hProcess,
PBOOL pbDebuggerPresent )
Kernel32!CheckRemoteDebuggerPresent()接受2个参数,第1个参数是进程句柄,第2个参数是一个指向boolean变量的指针,如果进程被调试,该变量将包含TRUE返回值。 这个API内部调用了ntdll!NtQueryInformationProcess(),由它完成检测工作。
typedef BOOL (WINAPI *CHECK_REMOTE_DEBUGGER_PRESENT)(HANDLE, PBOOL); //定义函数指针
void CDetectODDlg::OnCheckremotedebuggerpresent() {
// TODO: Add your control notification handler code here HANDLE hProcess;
HINSTANCE hModule;
BOOL bDebuggerPresent = FALSE;
CHECK_REMOTE_DEBUGGER_PRESENT CheckRemoteDebuggerPresent; //建立函数指针变量 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等