我一直在寻找一段时间,似乎找不到我的问题的答案。我试图编写一些函数来检测可执行文件是否正在调试,并且我使用了一些内联汇编(使用__asm标记)。它不断抛出两个错误,其余的代码似乎编译得很好。这是函数
int peb_detect() {
__asm {
ASSUME FS : NOTHING
MOV EAX, DWORD PTR FS : [18]
MOV EAX, DBYTE PTR DS : [EAX + 30]
MOVZX EAX, BYTE PTR DS : [EAX + 2]
RET
}
}
我不断收到错误
warning C4405: 'FS': identifier is reserved word
warning C2400: inline assembler syntax error in 'opcode'; found 'FS'
warning C2408: illegal type on PTR operator in 'second operand'
我似乎无法弄明白。如果有人可以提供帮助,我会非常感激。谢谢!
答案 0 :(得分:0)
首先不是18而是0x18而不是30但是0x30
C_ASSERT(FIELD_OFFSET(NT_TIB, Self) == 0x18);
C_ASSERT(FIELD_OFFSET(TEB, ProcessEnvironmentBlock) == 0x30);
需要使用非硬编码常量。特别错。
如果您使用int peb_detect()
指令,在第二个__declspec(naked)
必须为RET
。所以代码看起来像这样:
#include <winternl.h>
#include <intrin.h>
__declspec(naked) BOOLEAN peb_detect() {
__asm {
MOV EAX, FS:[NT_TIB.Self]
MOV EAX, [EAX + TEB.ProcessEnvironmentBlock]
MOV AL, [EAX + PEB.BeingDebugged]
RET
}
}
但我们可以使用更短的变体
__declspec(naked) BOOLEAN peb_detect2() {
__asm {
MOV EAX, FS:[TEB.ProcessEnvironmentBlock]
MOV AL, [EAX]PEB.BeingDebugged
RET
}
}
对于实现IsDebuggerPresent
,我们根本不能使用内联汇编程序。这也适用于x64
__forceinline BOOLEAN peb_detect3()
{
return ((PEB*)
#ifdef _WIN64
__readgsqword
#else
__readfsdword
#endif
(FIELD_OFFSET(_TEB, ProcessEnvironmentBlock)))->BeingDebugged;
}