通过中间函数调用WriteConsole无法正常工作

时间:2015-12-04 14:35:57

标签: c++ c visual-studio assembly masm32

我正在尝试学习assembly,因此我手动CC++代码转换为assembly代码。

环境

  • 86

  • Visual Studio

目标

手动将以下C代码转换为assembly代码:

static HANDLE OUTPUT_HANDLE;

BOOL __stdcall InputConsole(const VOID *lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten)
{
    WriteConsoleA(OUTPUT_HANDLE, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, 0);
}

int main()
{
    DWORD charsWritten;
    OUTPUT_HANDLE = GetStdHandle(STD_OUTPUT_HANDLE);


    InputConsole("Hello World!\n", 13, &charsWritten);
}

尝试

.586
.model flat, stdcall
.stack 4096

EXTRN   ExitProcess@4       :   PROC
EXTRN   GetStdHandle@4      :   PROC
EXTRN   WriteConsoleA@20    :   PROC

.data
    STD_OUTPUT_HANDLE       DD  ?
    WRITE_CONSOLE_STRING    DB  "Hello World!", 10, 0
    CHARS_WRITTEN           DD  ?

.code

WriteConsole PROC   
    PUSH    0                   ; lpReserved

    MOV     EAX, [ESP + 16]     ; lpNumberOfCharsWritten
    PUSH    EAX

    MOV     EAX, [ESP + 16]     ; nNumberOfCharsToWrite
    PUSH    EAX

    MOV     EAX, [ESP + 16]     ; lpBuffer
    PUSH    EAX

    PUSH    STD_OUTPUT_HANDLE   ; hConsoleOutput

    CALL    WriteConsoleA@20

    ADD     ESP, 12             ; Restore stack

    RET
WriteConsole ENDP

main: NOP
    PUSH    -11
    CALL    GetStdHandle@4;
    MOV     STD_OUTPUT_HANDLE, EAX

    LEA     EAX, CHARS_WRITTEN
    PUSH    EAX

    PUSH    13

    LEA     EAX, WRITE_CONSOLE_STRING
    PUSH    EAX

    CALL    WriteConsole

    PUSH    0
    CALL    ExitProcess@4
END main

问题

截至目前,它确实会打印实际行,但Access Violation Exception会引发ADD ESP, 12。在仔细检查调试器之后,似乎我应该将16而不是12添加到ESP以恢复堆栈。在使用16之后,它仍然会在从procedure返回后冻结应用程序。

问题

  • 当我只在堆栈上推送三个4字节的参数时,为什么我需要添加16而不是12
  • 正确使用ESP + xx访问'输入参数'吗?
  • 为什么我的程序会冻结,即使我正在恢复堆栈并且实际上是在控制台上写了一些东西?
  • 是否有另一种方法可以在assembly中“通过引用传递参数”而不是使用全局.data地址?

旁注

我知道你可以在Visual Studio中设置一个过程的参数(这是我正在使用的IDE),但是我应该如何做到这一点,对吧?

1 个答案:

答案 0 :(得分:0)

add esp您不是ret 12那样做的。GREETING_KEYWORDS = ("hello", "hi", "greetings", "sup", "what's up",) GREETING_RESPONSES = ["'sup bro", "hey", "nods", "hey you get my snap?"] def check_for_greeting(sentence): for word in sentence.words: if word.lower() in GREETING_KEYWORDS: return random.choice(GREETING_RESPONSES)                      - 杰斯特