<逆向工程核心原理> 静态反调试技术总结
2015-03-23 16:34
537 查看
1.PEB
strongOD->Options中的HidePEB可以绕过。
2.ntdll.dll的NtQueryInformationProcess()
strongOD->Options中的*KernelMode可以绕过。
3.NTQuerySystemInformation()
4.NTQueryObject()
strongOD->Options中的*KernelMode可以绕过。
5.ZwSetInformationThread()
6.TLS回调函数
7.检测窗口 FindWindow,FindWindowEx 检测进程 CreateToolHelp32Snapshoot
#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可以绕过。
2.ntdll.dll的NtQueryInformationProcess()
#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; }
相关文章推荐
- <逆向工程核心原理> 动态反调试技术总结
- <iOS>iphone技术总结,整合一下
- 推荐书籍<大型网站技术架构-核心原理与案例分析>--结合内容思考产品架构
- <iOS>iphone技术总结, 在网上找到比较有用的东东,整合一下
- Android中常常使用shape来定义控件的一些显示属性,今天看了一些shape的使用,对shape有了大体的了解,稍作总结: 先看下面的代码: <shape>
- <杂谈1002>HTML作为GUI前段,Java/NDK作为业务后端开发方式总结
- MFC中的 Document / View 结构的使用 <转载+自己总结,MFC中的MVC>
- &lt;展现C#&gt;第二章NGWSRuntime技术基础
- 欢迎来到火龙菌的技术博客~ >_<
- <转载>在Eclipse中用JDBC连接Sql Server 2005总结
- 在eclipse中运行工程时 出现<ConnectionProperties> <PropertyCategory name="Connection/Authentication">的解决方法
- <<展现C#>> 第二章 NGWS Runtime 技术基础(修订)
- ssh错误总结1.1----关与struts2中极为恶心的<s:action>标签问题
- <无线局域网媒体访问控制和物理层规范:汇聚无线控制技术规范>学习总结
- <深入浅出通信原理>参考书籍及资料
- asp.net的<% %>总结
- jstl标签====核心标签<c: >
- linux-kernel调试技术大全<一>上海嵌入式索漫科技培训教材
- <备份>9月19日简单总结
- << Oracle高可用>>部分书面作业 - 第二课 RAC-原理和安装