Вызов FormatMessageA из 64-битной ассемблерной программы - PullRequest
0 голосов
/ 04 мая 2020

Я работал в течение нескольких дней над подпрограммой ассемблера для вызова Windows API-функции FormatMessageA, и я думаю, что у меня должно быть систематическое c недоразумение. Моя рутина показана ниже. Я проследил это в режиме отладки, и я знаю, что в то время, когда вызывается функция: rcx имеет шестнадцатеричный 1B00, который является значениями флага, которые я указал (dwFlags); rdx имеет шестнадцатеричное 33, которое является фиктивным начальным дескриптором, который я подключил, чтобы спровоцировать ошибку (lpSource); r8 имеет 6, что является номером сообщения об ошибке, которое было возвращено GetLastError, что соответствует ERROR_INVALID_HANDLE (dwMessageId); r9 имеет 0 для языка по умолчанию (dwLanguageId); rsp + 32 имеет адрес msgptrp, который является моей областью для получения адреса сообщения об ошибке, выделенного вызываемой функцией (lpBuffer); rsp + 40 имеет шестнадцатеричное 28 или десятичное 40, что является минимальным количеством символов, которое я произвольно указал для сообщения об ошибке (nSize); и rsp + 48 имеет адрес argmntsp, который в соответствии с документацией должен игнорироваться с указанными мною флагами (* Аргументы).

Если есть проблема и, очевидно, так как rax возвращается как ноль, Я подозреваю, что это связано с lpBuffer, который, как говорится в документации, имеет тип данных LPTSTR, что бы это ни было. Иногда я хочу крикнуть: «Хорошо, это то, что с точки зрения C ++, но что это такое действительно ? Я надеюсь, что кто-то может легко определить, где я сбежал с рельсов, потому что я в своем уме покончим с этим, и это то, что мне нужно, чтобы начать эффективную проверку ошибок для моих будущих начинаний.

goterr    PROC
;
.data 
; flag values used:
; hex 00000100 FORMAT_MESSAGE_ALLOCATE_BUFFER
; hex 00000200 FORMAT_MESSAGE_IGNORE_INSERTS
; hex 00000800 FORMAT_MESSAGE_FROM_HMODULE
; hex 00001000 FORMAT_MESSAGE_FROM_SYSTEM
flagsp    dd 00001B00h ; those flags combined  

saveinitp dq     ?
bmaskp    dq     0fffffffffffffff0h
savshadp  dq     ?
msgptrp   dq     ?
handlep   dd     ?
argmntsp  dd     ?
;
.code
          mov    saveinitp, rsp    ; save initial contents of stack pointer in this proc         
          sub    rsp, 56           ; shadow space (max of 7 parameters * 8)
          and    rsp, bmaskp       ; make sure it's 16 byte aligned
          mov    savshadp, rsp     ; save address of aligned shadow area for this proc
;
          mov    handlep, ecx      ; save passed I/O handle value locally
;
          call   GetLastError      ; get the specific error
;
          mov    rsp, savshadp     ; shadow area for this proc
          mov    ecx, flagsp       ; flags for Windows error routine
          mov    edx, handlep      ; handle passed from caller
          mov    r8d, eax          ; msg id from GetLastError in low order dword
          mov    r9, 0             ; default language id
          lea    rax, msgptrp      ; pointer to receive address of msg buffer
          mov    [rsp+32], rax     ; put it on the stack
          mov    rax, 40           ; set lower doubleword to minimum size for msg buffer 
          mov    [rsp+40], rax     ; put it on the stack
          lea    rax, argmntsp     ; variable arguments parameter (not used)
          mov    [rsp+48], rax     ; put it on the stack
          call   FormatMessageA    ; if rax eq 0 the called failed, otherwise rax is no chars.
          mov    rsp, saveinitp    ; restore initial SP for this proc
          ret
goterr    ENDP
...