静态反调试技术(2)
文章目录
- NtQueryInformationProcess()
- `ProcessDebugPort`(0x7)
- CheckRemoteDebuggerPresent()
- ProcessDebugObjectHandle(0x1E)
- ProcessDebugFlags(0x1F)
- 调试程序代码
- NtQuerySystemInformation()
- `SystemKernelDebuggerInformation`(`0x23`)
- 破解之法
- NTQueryObject()
- 破解之法
- 反调试技术系列:
NtQueryInformationProcess()
下面介绍一种利用NtQuertInformationProcess()API探测调试器的技术。通过NtQuertInformationProcess()API可以获取各种与进程相关的信息。函数定义如下
NtQueryInformationProcess (
IN HANDLE ProcessHandle, // 进程句柄
IN PROCESSINFOCLASS InformationClass, // 信息类型
OUT PVOID ProcessInformation, // 缓冲指针
IN ULONG ProcessInformationLength, // 以字节为单位的缓冲大小
OUT PULONG ReturnLength OPTIONAL // 写入缓冲的字节数
);
第一个参数是希望操作的进程句柄,这个句柄必须以PROCESS_QUERY_INFORMATION
模式存取。为了取得一个句柄,我们必须用OpenProcess
函数:
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwProcessID);
第二个参数是请求信息的类型,这个参数可以有许多个值,为这个参数指定特定值并去调用函数,相关信息就会设置到第三个参数PVOID ProcessInformation
。
因此,如果第二个参数是ProcessBasicInformation
的话,则第三个参数必须为一个指针指向结构PROCESS_BASIC_INFORMATION
。
typedef struct
{ DWORD ExitStatus; // 接收进程终止状态 DWORD PebBaseAddress; // 接收进程环境块地址 DWORD AffinityMask; // 接收进程关联掩码 DWORD BasePriority; // 接收进程的优先级类 ULONG UniqueProcessId; // 接收进程ID ULONG InheritedFromUniqueProcessId; //接收父进程ID
} PROCESS_BASIC_INFORMATION;
PROCESSINFOCLASS
是枚举类型,拥有的值如下所示:
enum PROCESSINFOCLASS
{ProcessBasicInformation = 0,ProcessQuotaLimits,ProcessIoCounters,ProcessVmCounters,ProcessTimes,ProcessBasePriority,ProcessRaisePriority,ProcessDebugPort = 7, //0x7ProcessExceptionPort,ProcessAccessToken,ProcessLdtInformation,ProcessLdtSize,ProcessDefaultHardErrorMode,ProcessIoPortHandlers,ProcessPooledUsageAndLimits,ProcessWorkingSetWatch,ProcessUserModeIOPL,ProcessEnableAlignmentFaultFixup,ProcessPriorityClass,ProcessWx86Information,ProcessHandleCount,ProcessAffinityMask,ProcessPriorityBoost,MaxProcessInfoClass,ProcessWow64Information = 26,ProcessImageFileName = 27,ProcessDebugObjectHandle = 30, //0x1EProcessDebugFlags = 31, //0x1FSystemKernelDebuggerInformation = 35
};
以上代码中与调试器探测相关的成员为ProcessDebugPort
(0x7),ProcessDebugObjectHandle
(0x1E),ProcessDebugFlags
(0x1F)
ProcessDebugPort
(0x7)
进程处于调试状态时,系统就会为它分配一个调试端口(Debug Port)。PROCESSINFOCLASS
参数的值设置为 ProcessDebugPort
(0x7)时,调用NtQueryInformationProcess()
函数就能获取调试端口。若进程处于非调试状态,则变量 ProcessDebugPort
的值设置为0;若进程处于调试状态,则变量 ProcessDebugPort
的值设置为0xFFFFFFFF
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");
CheckRemoteDebuggerPresent()
CheckRemoteDebuggerPresent()
API与IsdebuggerPresent()
API类似,用来检测进程是否处于调试状态。CheckRemoteDebuggerPresent()
函数不仅可以用来检测当前进程,还可以用来检测其它进程是否处于被调试状态。
CheckRemoteDebuggerPresent()
内部代码如下:
这个参数7即 ProcessDebugPort
ProcessDebugObjectHandle(0x1E)
调试进程时会生成调试对象(Debug Object)。函数的第二个参数值为 ProcessDebugObjectHandle
(0x1E)时,调用函数后通过第三个参数就能获取调用对象句柄。进程属于调试状态时,调试对象句柄就存在;若进程处于非调试状态,则调试对象句柄值为NULL
。
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)
检测Debug Flags(调试标志)的值也可以判断进程是否处于被调试状态,函数的第二个参数设置为ProcessDebugFlags
(0x1F)时,调用函数后通过第三个参数即可获取调试标志的值:若为,则进程处于被调试状态;若为1,则进程处于非调试状态。
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");
}
调试程序代码
#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可以绕过。
NtQuerySystemInformation()
这是基于调试环境检测的反调试技术。
注意:
前面所介绍的反调试技术,我们通过探测调试器来判断自己的进程是否处于被调试状态,这是一种非常直接的调试器探测方法。除此之外,还有间接探测调试器的方法,借助该方法可以检测调试环境,若显露出调试器的端倪,则立刻停止执行程序。
运用这种反调试技术可以检测当前OS是否在调试模式下运行。
OS的调试模式:
为了使用winDbg工具调试系统内核(Kernel Debugging),需要先准备2个系统(Host Target)并连接(Serial,1394,USB,Direct Cable)。其中,Target的OS以调试模式运行,连接到Host系统的WinDbg上台后即可调试。
设置调试模式方法:
windows XP:编辑"C:\boot.ini"
windows 7:使用bcdedit.exe实用程序
ntdll!NtQuerySystemInformation()
API是一个系统函数,用来获取当前运行的多种OS信息。
typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION)
(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,IN OUT PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength OPTIONAL);NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
第一个参数是dwRecordType,这个参数指定了我们所查询的系统信息类型,为了查询系统HANDLE列表,我们定义一个常量#define NT_HANDLE_LIST 16(这个数值我是查资料得到的,如果谁有更详细的资料,也请让我共享一下)。
第二个参数是一个指针,这个指针用来返回系统句柄列表,在调用NtQuerySystemInformation函数之前,必须为这个指针分配足够的内存空间,否则函数调用会出错。
第三个参数是指定你为HandleList所分配的内存空间大小,单位是byte。
第四个参数是NtQuerySystemInformation返回的HandleList的大小;如果NtQuerySystemInformation函数调用成功,返回值将是0,否则可以使用GetLastError()获得详细的错误代码。
SYSTEM_INFORMATION_CLASS 是枚举类型,拥有的值如下:
typedef enum _SYSTEM_INFORMATION_CLASS {SystemBasicInformation,// 0 Y N
SystemProcessorInformation,// 1 Y N
SystemPerformanceInformation,// 2 Y N
SystemTimeOfDayInformation,// 3 Y N
SystemNotImplemented1,// 4 Y N // SystemPathInformation
SystemProcessesAndThreadsInformation,// 5 Y N
SystemCallCounts,// 6 Y N
SystemConfigurationInformation,// 7 Y N
SystemProcessorTimes,// 8 Y N
SystemGlobalFlag,// 9 Y Y
SystemNotImplemented2,// 10 YN // SystemCallTimeInformation
SystemModuleInformation,// 11 YN
SystemLockInformation,// 12 YN
SystemNotImplemented3,// 13 YN // SystemStackTraceInformation
SystemNotImplemented4,// 14 YN // SystemPagedPoolInformation
SystemNotImplemented5,// 15 YN // SystemNonPagedPoolInformation
SystemHandleInformation,// 16 YN
SystemObjectInformation,// 17 YN
SystemPagefileInformation,// 18 YN
SystemInstructionEmulationCounts,// 19 YN
SystemInvalidInfoClass1,// 20
SystemCacheInformation,// 21 YY
SystemPoolTagInformation,// 22 YN
SystemProcessorStatistics,// 23 YN
SystemDpcInformation,// 24 YY
SystemNotImplemented6,// 25 YN // SystemFullMemoryInformation
SystemLoadImage,// 26 NY // SystemLoadGdiDriverInformation
SystemUnloadImage,// 27 NY
SystemTimeAdjustment,// 28 YY
SystemNotImplemented7,// 29 YN // SystemSummaryMemoryInformation
SystemNotImplemented8,// 30 YN // SystemNextEventIdInformation
SystemNotImplemented9,// 31 YN // SystemEventIdsInformation
SystemCrashDumpInformation,// 32 YN
SystemExceptionInformation,// 33 YN
SystemCrashDumpStateInformation,// 34 YY/N
SystemKernelDebuggerInformation,// 35 YN //0x23
SystemContextSwitchInformation,// 36 YN
SystemRegistryQuotaInformation,// 37 YY
SystemLoadAndCallImage,// 38 NY // SystemExtendServiceTableInformation
SystemPrioritySeparation,// 39 NY
SystemNotImplemented10,// 40 YN // SystemPlugPlayBusInformation
SystemNotImplemented11,// 41 YN // SystemDockInformation
SystemInvalidInfoClass2,// 42 // SystemPowerInformation
SystemInvalidInfoClass3,// 43 // SystemProcessorSpeedInformation
SystemTimeZoneInformation,// 44 YN
SystemLookasideInformation,// 45 YN
SystemSetTimeSlipEvent,// 46 NY
SystemCreateSession,// 47 NY
SystemDeleteSession,// 48 NY
SystemInvalidInfoClass4,// 49
SystemRangeStartInformation,// 50 YN
SystemVerifierInformation,// 51 YY
SystemAddVerifier,// 52 NY
SystemSessionProcessesInformation// 53 YN
} SYSTEM_INFORMATION_CLASS;
向SystemInformationClass
参数传入SystemKernelDebuggerInformation
值(0x23
)即可判断当前OS在调试模式下运行
SystemKernelDebuggerInformation
(0x23
)
void MyNtQuerySystemInformation()
{//检测当前OS是否运行在调试模式下,WinDbgtypedef 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");
}
在上述代码中调用NtQuerySystemInformation()
API时,第一个参数(SystemInformaticationClass)的值设置为SystemKernelDebuggerInformation(0x23),第二个参数(SystemInformation)为SYSTEM_KERNEL_DEBUGGER_INFORMATION结构体的地址。当API返回时,若系统处在调试模式下,则SYSTEM_KERNEL_DEBUGGER_INFORMATION.DebuggerEnable的值设置为1(SYSTEM_KERNEL_DEBUGGER_INFORMATION.DebuggerEnable的值恒为1)
破解之法
在Windows XP 系统中编辑boot.ini文件,删除“/debugport=coml /baudrate=115200 /debug”值。在windows 7系统的命令行窗口中执行“bcdedit /debug off”命令即可。并且,若重启系统则要以正常模式启动。
NTQueryObject()
系统中的某个调试器调试进程时,会创建1个调试对象类型的内核对象。检测该对象是否存在即可判断是否有进程正在被调试。
ntdll!NTQueryObject()
API用来获取系统各种内核对象的信息,NTQueryObject()函数的定义如下
NTSTATUS NtQueryObject(_In_opt_ HANDLE Handle,_In_ OBJECT_INFORMATION_CLASS objectInformationClass,_Out_opt_ PVOID ObjectInformation,_In_ ULONG ObjectInformationLength,_Out_opt_ PULONG ReturnLength);
调用NTQueryObject()
函数前,先向第二个参数 OBJECT_INFORMATION_CLASS objectInformationClass
赋于某个特定的值,调用API后,包含相关信息的结构指针就被返回到第三个参数PVOID ObjectInformation
。
typedef enum _OBJECT_INFORMATION_CLASS {ObjectBasicInformation,ObjectNameInformation,ObjectTypeInformation,ObjectAllInformation,//3ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
首先使用ObjectAllTypeInformation
值获取系统所有对象的信息,然后从中检测是否存在调试对象。NtQueryObject()
API使用方法复杂。
1.获取内核对象信息链表的大小
ULONG lSize = 0;
pNtQueryObject(NULL, ObjectAllTypesInformation, &lSize, sizeof(lSize), &lSize);
2.分配内存
void *pBuf = NULL;
pBuf = VirtualAlloc(NULL, lSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
3.获取内核对象信息链表
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;pNtQueryObject((HANDLE)0xFFFFFFFF, ObjectAllTypesInformation, pBuf, lSize, NULL);POBJECT_ALL_INFORMATION pObjectAllInfo = (POBJECT_ALL_INFORMATION)pBuf;
调用NtQueryObject()
函数后,系统的所有对象的信息代码就被存入pBuf
,然后将pBuf
转换(casing
)为POBJECT_ALL_INFORMATION
类型。POBJECT_ALL_INFORMATION
结构体_OBJECT_TYPE_INFORMATION
结构体数组构成。实际内核对象类型的信息就被存储在_OBJECT_TYPE_INFORMATION
结构体数组中,然后通过循环检索即可查看是否存在“调试对象”对象类型。
完整代码:
#include "stdio.h"
#include "windows.h"
#include "tchar.h"typedef enum _OBJECT_INFORMATION_CLASS {ObjectBasicInformation,ObjectNameInformation,ObjectTypeInformation,ObjectAllTypesInformation,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 listpNtQueryObject(NULL, ObjectAllTypesInformation, &lSize, sizeof(lSize), &lSize);// Allocate list bufferpBuf = VirtualAlloc(NULL, lSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);// Get the actual listpNtQueryObject((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;if( wcscmp(L"DebugObject", pObjectTypeInfo->TypeName.Buffer) == 0 ){bDebugging = (pObjectTypeInfo->TotalNumberOfObjects > 0) ? TRUE : FALSE;break;}// calculate next structpObjInfoLocation = (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可以绕过。
破解之法
位于0xCB184A
地址处的call dword ptr ss:[ebp-0x3C]
指令是用来调用ntdll.ZwQueryObject()
API的,
此时查看栈可以发现,第二个参数值为ObjectAllTypesInformation(3)
,将该值修改为0后再执行0xCB184A
地址处的指令,这样就无法探测到调试器的存在了
或者直接把这个API给勾取,输入ObjectAllTypesInformation(3)
值或者直接操作结果值,也不会被探测到
反调试技术系列:
静态反调试技术(1)https://blog.csdn.net/CSNN2019/article/details/113105292
静态反调试技术(2)https://blog.csdn.net/CSNN2019/article/details/113147820
静态反调试技术(3)https://blog.csdn.net/CSNN2019/article/details/113178232
动态反调试技术 https://blog.csdn.net/CSNN2019/article/details/113181558
高级反调试技术 https://blog.csdn.net/CSNN2019/article/details/113263215
静态反调试技术(2)相关推荐
- 静态反调试技术(1)
文章目录 声明 静态反调试目的 注意 PEB https://blog.csdn.net/CSNN2019/article/details/113113347 BeingDebugged(+0x2) ...
- 静态反调试技术(3)
文章目录 ZwSetInformationThread 破解方法 **调试程序代码**: 利用TLS回调函数(详情通过以下链接查看) ETC 破解之法 **调试程序代码**: 篇章大总结: 反调试技术 ...
- 详解反调试技术(转)
反调试技术,恶意代码用它识别是否被调试,或者让调试器失效.恶意代码编写者意识到分析人员经常使用调试器来观察恶意代码的操作,因此他们使用反调试技术尽可能地延长恶意代码的分析时间.为了阻止调试器的分析,当 ...
- 反调试技术揭秘(转)
在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编之类的方法破解自己.为了了解如何破解反调试技术, ...
- windows平台下的反调试技术
在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...
- Windows反调试技术全攻略
在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...
- 如何绕过反调试技术——PhantOM插件总结
PhantOM是OllyDbg的一款插件,可以用来绕过大多数的反调试技术,功能十分强大,所以单独对这个插件进行使用总结.(Ps:现在似乎不怎么常用,在64位下的兼容性比较差,现在比较常用的是sharp ...
- 恶意软件反检测技术简介:反调试技术解析
本文中,我们将向读者介绍恶意软件用以阻碍对其进行逆向工程的各种反调试技术,以帮助读者很好的理解这些技术,从而能够更有效地对恶意软件进行动态检测和分析. 一.反调试技术 反调试技术是一种常见的反检测技术 ...
- 180306 逆向-反调试技术(1)BeingDebugged
1625-5 王子昂 总结<2018年3月6日> [连续第521天总结] A. 反调试技术(1) B. BeingDebugged Win32API为程序提供了IsDebuggerPres ...
最新文章
- 一.Timesten安装
- Cylinder3D :3D环境下的Lidar 点云分割
- python复制sheet_python excel sheet复制
- 科大奥锐实验报告霍尔效应_大学物理实验报告系列之霍尔效应
- OllyDBG 入门系列(三)-函数
- 前端—每天5道面试题(十三)
- azure centos 7安装mariadb
- 建立.NET Core控制台应用程序以输出EXE?
- dalvik虚拟内存管理之二——垃圾收集
- 版式设计中要注意的三点问题
- MDT实现windows系统批量部署
- 虚拟机镜像文件高速下载方法之一
- 知了课堂 flask 笔记总结
- 初级Java程序员如何快速提升自己的能力?
- CAD椭圆怎么画?CAD椭圆绘制步骤
- 【5G RRU专题】什么是PA非线性失真?
- 罗振宇4小时跨年演讲精华版:大环境里的7个行动策略
- 测试架构师需要具备哪些能力?
- 恶意代码分析-静态分析基础
- QuickTime Player 键盘快捷键和手势大全
热门文章
- 不确定大小的数组_原来数组是容器喔
- python在开头声明全局变量_全局变量声明Python
- 成功解决AttributeError: module tensorflow.compat has no attribute v1
- 成功解决PackagesNotFoundError: The following packages are not available from current channels: tensorflo
- 成功解决sklearn\ensemble\weight_boosting.py:29: DeprecationWarning: numpy.core.umath_tests is an interna
- ML之SVM(三种):基于三种SVM(linearSVR、polySVR、RBFSVR)对Boston(波士顿房价)数据集(506,13+1)进行价格回归预测并对比各自性能
- 成功解决Scrapy框架的问题ModuleNotFoundError: No module named 'win32api'
- JAVA_OA(五):SpringMVC接受传入页面的参数值
- selenium V1.0和V2.0差别对比
- 10.原码 反码 补码