<逆向工程核心原理> 静态反调试技术总结
来源:互联网 发布:金字塔软件论坛 编辑:程序博客网 时间:2024/06/04 17:43
1.PEB
#include "stdio.h"#include "windows.h"#include "tchar.h"void PEB(){ HMODULE hMod = NULL; FARPROC pProc = NULL; LPBYTE pTEB = NULL; LPBYTE pPEB = NULL; BOOL bIsDebugging = FALSE; //<span style="color:#ff0000;">[pPEB+0x2]==0x1</span> // IsDebuggerPresent() bIsDebugging = IsDebuggerPresent(); printf("IsDebuggerPresent() = %d\n", bIsDebugging); if( bIsDebugging ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n"); // Ldr xp特有 pProc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCurrentTeb"); pTEB = (LPBYTE)(*pProc)(); // address of TEB pPEB = (LPBYTE)*(LPDWORD)(pTEB+0x30); // address of PEB printf("PEB.Ldr\n"); DWORD pLdrSig[4] = { 0xEEFEEEFE, 0xEEFEEEFE, 0xEEFEEEFE, 0xEEFEEEFE }; LPBYTE pLdr = (LPBYTE)*(LPDWORD)(<span style="color:#ff0000;">pPEB+0xC</span>); __try { while( TRUE ) { if( !memcmp(pLdr, pLdrSig, sizeof(pLdrSig)) ) { printf(" => Debugging!!!\n\n"); break; } pLdr++; } } __except (EXCEPTION_EXECUTE_HANDLER) { printf(" => Not debugging...\n\n"); } // Process Heap - Flags xp特有 bIsDebugging = FALSE; LPBYTE pHeap = (LPBYTE)*(LPDWORD)(<span style="color:#ff0000;">pPEB+0x18</span>); DWORD dwFlags = *(LPDWORD)(<span style="color:#ff0000;">pHeap+0xC</span>); printf("PEB.ProcessHeap.Flags = 0x%X\n", dwFlags); if( dwFlags != 0x2 ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n"); // Process Heap - ForceFlags xp特有 bIsDebugging = FALSE; DWORD dwForceFlags = *(LPDWORD)(<span style="color:#ff0000;">pHeap+0x10</span>); printf("PEB.ProcessHeap.ForceFlags = 0x%X\n", dwForceFlags); if( dwForceFlags != 0x0 ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n"); // NtGlobalFlag bIsDebugging = FALSE; DWORD dwNtGlobalFlag = *(LPDWORD)(<span style="color:#ff0000;">pPEB+0x68</span>); printf("PEB.NtGlobalFlag = 0x%X\n", dwNtGlobalFlag); if( (dwNtGlobalFlag & 0x70) == 0x70 ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ PEB(); printf("\npress any key to quit...\n"); _gettch(); return 0;}
strongOD->Options中的HidePEB可以绕过。
#include "stdio.h"#include "windows.h"#include "tchar.h"enum PROCESSINFOCLASS{ ProcessBasicInformation = 0, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort = 7, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDefaultHardErrorMode, ProcessIoPortHandlers, ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, MaxProcessInfoClass, ProcessWow64Information = 26, ProcessImageFileName = 27, ProcessDebugObjectHandle = 30, ProcessDebugFlags = 31, SystemKernelDebuggerInformation = 35};void MyNtQueryInformationProcess(){ typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONPROCESS)( HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength ); NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess = NULL; pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS) GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess"); // ProcessDebugPort (0x7) DWORD dwDebugPort = 0; pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort, &dwDebugPort, sizeof(dwDebugPort), NULL); printf("NtQueryInformationProcess(ProcessDebugPort) = 0x%X\n", dwDebugPort); if( dwDebugPort != 0x0 ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n"); // ProcessDebugObjectHandle (0x1E) HANDLE hDebugObject = NULL; pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject, sizeof(hDebugObject), NULL); printf("NtQueryInformationProcess(ProcessDebugObjectHandle) = 0x%X\n", hDebugObject); if( hDebugObject != 0x0 ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n"); // ProcessDebugFlags (0x1F) BOOL bDebugFlag = TRUE; pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &bDebugFlag, sizeof(bDebugFlag), NULL); printf("NtQueryInformationProcess(ProcessDebugFlags) = 0x%X\n", bDebugFlag); if( bDebugFlag == 0x0 ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ MyNtQueryInformationProcess(); printf("\npress any key to quit...\n"); _gettch(); return 0;}
strongOD->Options中的*KernelMode可以绕过。
3.NTQuerySystemInformation()
#include "stdio.h"#include "windows.h"#include "tchar.h"void MyNtQuerySystemInformation(){ //检测当前OS是否运行在调试模式下,WinDbg typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)( ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION { BOOLEAN DebuggerEnabled; BOOLEAN DebuggerNotPresent; } SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION; NTQUERYSYSTEMINFORMATION NtQuerySystemInformation; NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION) GetProcAddress(GetModuleHandle(L"ntdll"), "NtQuerySystemInformation"); ULONG SystemKernelDebuggerInformation = 0x23; ULONG ulReturnedLength = 0; SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo = {0,}; NtQuerySystemInformation(SystemKernelDebuggerInformation, (PVOID) &DebuggerInfo, sizeof(DebuggerInfo), // 2 bytes &ulReturnedLength); printf("NtQuerySystemInformation(SystemKernelDebuggerInformation) = 0x%X 0x%X\n", DebuggerInfo.DebuggerEnabled, DebuggerInfo.DebuggerNotPresent); if( DebuggerInfo.DebuggerEnabled ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ //基于调试环境检测反调试 // boot.ini /debug MyNtQuerySystemInformation(); printf("\npress any key to quit...\n"); _gettch(); return 0;}
4.NTQueryObject()
#include "stdio.h"#include "windows.h"#include "tchar.h"typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation, ObjectNameInformation, ObjectTypeInformation, <span style="color:#ff0000;"> ObjectAllTypesInformation,</span> ObjectHandleInformation} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;void MyNtQueryObject(){ //基于检测调试环境 //系统中的某个调试器调试进程时,会创建1个调试对象类型的内核对象。检测该对象 //是否存在即可判断是否有进程正在被调试(注意不是当前进程)。 typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; typedef NTSTATUS (WINAPI *NTQUERYOBJECT)( HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength ); #pragma pack(1) typedef struct _OBJECT_TYPE_INFORMATION { UNICODE_STRING TypeName; ULONG TotalNumberOfHandles; ULONG TotalNumberOfObjects; }OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; typedef struct _OBJECT_ALL_INFORMATION { ULONG NumberOfObjectsTypes; OBJECT_TYPE_INFORMATION ObjectTypeInformation[1]; } OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION; #pragma pack() POBJECT_ALL_INFORMATION pObjectAllInfo = NULL; void *pBuf = NULL; ULONG lSize = 0; BOOL bDebugging = FALSE; NTQUERYOBJECT pNtQueryObject = (NTQUERYOBJECT) GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryObject"); // Get the size of the list pNtQueryObject(NULL, ObjectAllTypesInformation, &lSize, sizeof(lSize), &lSize); // Allocate list buffer pBuf = VirtualAlloc(NULL, lSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // Get the actual list pNtQueryObject((HANDLE)0xFFFFFFFF, ObjectAllTypesInformation, pBuf, lSize, NULL); pObjectAllInfo = (POBJECT_ALL_INFORMATION)pBuf; UCHAR *pObjInfoLocation = (UCHAR *)pObjectAllInfo->ObjectTypeInformation; POBJECT_TYPE_INFORMATION pObjectTypeInfo = NULL; for( UINT i = 0; i < pObjectAllInfo->NumberOfObjectsTypes; i++ ) { pObjectTypeInfo = (POBJECT_TYPE_INFORMATION)pObjInfoLocation; <span style="color:#ff0000;"> if( wcscmp(L"DebugObject", pObjectTypeInfo->TypeName.Buffer) == 0 ) { bDebugging = (pObjectTypeInfo->TotalNumberOfObjects > 0) ? TRUE : FALSE; break; }</span> // calculate next struct pObjInfoLocation = (UCHAR*)pObjectTypeInfo->TypeName.Buffer; pObjInfoLocation += pObjectTypeInfo->TypeName.Length; pObjInfoLocation = (UCHAR*)(((ULONG)pObjInfoLocation & 0xFFFFFFFC) + sizeof(ULONG)); } if( pBuf ) VirtualFree(pBuf, 0, MEM_RELEASE); printf("NtQueryObject(ObjectAllTypesInformation)\n"); if( bDebugging ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ MyNtQueryObject(); printf("\npress any key to quit...\n"); _gettch(); return 0;}
strongOD->Options中的*KernelMode可以绕过。
5.ZwSetInformationThread()
#include "stdio.h"#include "windows.h"#include "tchar.h"void DetachDebugger(){ //强制分离被调试者和调试器的技术。调试器与被调试进程同时终止 typedef enum _THREAD_INFORMATION_CLASS { ThreadBasicInformation, ThreadTimes, ThreadPriority, ThreadBasePriority, ThreadAffinityMask, ThreadImpersonationToken, ThreadDescriptorTableEntry, ThreadEnableAlignmentFaultFixup, ThreadEventPair, ThreadQuerySetWin32StartAddress, ThreadZeroTlsCell, ThreadPerformanceCount, ThreadAmILastThread, ThreadIdealProcessor, ThreadPriorityBoost, ThreadSetTlsArrayAddress, ThreadIsIoPending, <span style="color:#ff0000;"> ThreadHideFromDebugger // 17 (0x11)</span> } THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS; typedef NTSTATUS (WINAPI* ZWSETINFORMATIONTHREAD)( HANDLE ThreadHandle, THREAD_INFORMATION_CLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength ); ZWSETINFORMATIONTHREAD pZwSetInformationThread = NULL; pZwSetInformationThread = (ZWSETINFORMATIONTHREAD) GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwSetInformationThread"); pZwSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0); printf("ZwSetInformationThread() -> Debugger detached!!!\n\n");}int _tmain(int argc, TCHAR* argv[]){ DetachDebugger(); printf("\npress any key to quit...\n"); _gettch(); return 0;}经过测试,此方法在XP可行,但在WIN7无效。
6.TLS回调函数
7.检测窗口 FindWindow,FindWindowEx 检测进程 CreateToolHelp32Snapshoot
#include "stdio.h"#include "windows.h"#include "tchar.h"void FindDebuggerWindow(){ BOOL bDebugging = FALSE; // using ClassName if( FindWindow(L"OllyDbg", NULL) || // OllyDbg FindWindow(L"TIdaWindow", NULL) || // IDA Pro FindWindow(L"WinDbgFrameClass", NULL) ) // Windbg bDebugging = TRUE; printf("FindWindow()\n"); if( bDebugging ) printf(" => Found a debugger window!!!\n\n"); else printf(" => Not found a debugger window...\n\n"); // using WindowName bDebugging = FALSE; TCHAR szWindow[MAX_PATH] = {0,}; HWND hWnd = GetDesktopWindow(); hWnd = GetWindow(hWnd, GW_CHILD); hWnd = GetWindow(hWnd, GW_HWNDFIRST); while( hWnd ) { if( GetWindowText(hWnd, szWindow, MAX_PATH) ) { if( _tcsstr(szWindow, L"IDA") || _tcsstr(szWindow, L"OllyDbg") || _tcsstr(szWindow, L"WinDbg") ) { bDebugging = TRUE; break; } } hWnd = GetWindow(hWnd, GW_HWNDNEXT); } printf("GetWindowText()\n"); if( bDebugging ) printf(" => Found a debugger window!!!\n\n"); else printf(" => Not found a debugger window...\n\n");}int _tmain(int argc, TCHAR* argv[]){ FindDebuggerWindow(); printf("\npress any key to quit...\n"); _gettch(); return 0;}
0 0
- <逆向工程核心原理> 静态反调试技术总结
- <逆向工程核心原理> 动态反调试技术总结
- 《逆向工程核心原理》》<07> 反调试技术
- 《逆向工程核心原理》》<06> 高级逆向分析技术
- 《逆向工程核心原理》
- 《逆向工程核心原理》
- 逆向工程核心原理
- 逆向工程核心原理学习笔记(七):总结
- 逆向工程核心原理学习笔记(七):总结
- 《逆向工程核心原理》学习总结(一)
- 《逆向工程核心原理》学习总结(二)
- 《逆向工程核心原理》学习总结(三)
- 《逆向工程核心原理》学习总结(四)
- 反调试技术总结.
- 反调试技术总结
- 171211 逆向-高级反调试技术
- 《逆向工程核心原理》相关说明
- 逆向工程核心原理读书笔记-代码注入
- selenium IDE 的安装
- 第三周 项目4-多文件组织
- Git 常用命令
- 0002cpp文件与h文件
- vi 基本用法
- <逆向工程核心原理> 静态反调试技术总结
- Java_语法基础_NaN
- 什么是启发式算法(转)
- Android 内容提供者、解释者和观察者学习笔记
- 构造函数 复制构造函数 类型转换构造函数 析构函数
- angular ngOptions的使用
- Android开发_SharePreferences
- AMD展示DirectX 12游戏优势和多项创新技术
- 编程之美——找符合条件的整数