VC ++内联汇编错误

时间:2017-01-16 01:07:31

标签: visual-studio visual-c++ assembly x86 inline-assembly

我一直在寻找一段时间,似乎找不到我的问题的答案。我试图编写一些函数来检测可执行文件是否正在调试,并且我使用了一些内联汇编(使用__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'

我似乎无法弄明白。如果有人可以提供帮助,我会非常感激。谢谢!

1 个答案:

答案 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;
}