Ошибки встроенной сборки VC++

Я искал вокруг некоторое время, и не мог, кажется, найти ответ на мой вопрос. Я пытаюсь закодировать некоторые функции, чтобы определить, отлаживается ли исполняемый файл, и я использую для него некоторую встроенную сборку (с тегом __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 ответ

  1. сначала не 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;
    }