lstrcat在MASM程序中无法正常工作

时间:2013-04-04 13:12:43

标签: winapi masm masm32

我有一个基本的C ++程序。其目标是显示特定文件夹中包含的文件名。 C ++代码如下:

#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>

int                     _tmain(int ac, TCHAR **av)
{
    HANDLE              hFile;
    WIN32_FIND_DATA     findFileData;
    BOOL                retFindNextFile;
    TCHAR               FilePathPattern[] = TEXT("C:\\Users\\Bloodsucker94\\Desktop\\TestASM\\*.txt");

    if ((hFile = FindFirstFile(FilePathPattern, &findFileData)) == INVALID_HANDLE_VALUE)
        _tprintf(TEXT("FindFirstFile() failed with code %d\n"), GetLastError());
    else {
        _tprintf(TEXT("hFile=%d, addr=0x%08X\n"), hFile, &findFileData);
        do {
            TCHAR       beginPath[] = TEXT("C:\\Users\\Bloodsucker94\\Desktop\\TestASM\\");

            lstrcat(beginPath, findFileData.cFileName);
            _tprintf(TEXT("%s\n"), beginPath);
            //printf("%s\n", beginPath);
            retFindNextFile = FindNextFile(hFile, &findFileData);

        } while (retFindNextFile == TRUE);
    }
    getchar();
    return (EXIT_SUCCESS);
}

我想使用MASM生成相同的程序:

.386
.model                          flat, stdcall
option                          casemap :none

include                         \masm32\include\windows.inc
include                         \masm32\include\kernel32.inc
include                         \masm32\include\masm32.inc
include                         \masm32\include\masm32rt.inc
includelib                      \masm32\lib\kernel32.lib
includelib                      \masm32\lib\masm32.lib
include                         \masm32\include\msvcrt.inc
includelib                      \masm32\lib\msvcrt.lib
includelib                      \masm32\lib\crtdll.lib

_tprintf PROTO C :VARARG

.data

FolderPath                      TCHAR                       "C:\Users\Bloodsucker94\Desktop\TestASM\*.txt", 0
BeginFolderPath                 TCHAR                       "C:\Users\Bloodsucker94\Desktop\TestASM\", 0
FileName                        TCHAR                       "ta_mere.txt", 0

LstrcatFailed                   BYTE                        "lstrcat failed", 0
FormatPrintString               BYTE                        "%s\n", 0

FindFirstFileError              BYTE                        "FindFirstFile() failed with code %d", 0
FindFirstFileSuccess            BYTE                        "First file found with success - hfile=%d", 0
PrintStructAddr                 BYTE                        "addr=Ox%08X", 0
PrintFileName                   BYTE                        "%s", 0

.data?

hFile                           HANDLE                      ?
findFileData                    WIN32_FIND_DATA             <>
retFindNextFile                 BOOL                        ?
ErrorCode                       DWORD                       ?
FinalFilePath                   LPTSTR                      ?

.code

start:

    ;--------------------------------------------------------

    invoke  FindFirstFile,      ADDR FolderPath,            \
                                ADDR findFileData

    mov     hFile,              eax

    .IF hFile == INVALID_HANDLE_VALUE
        invoke  GetLastError
        mov     ErrorCode,      eax
        printf("%d\n", ErrorCode)
        jmp                     _quit                                
    .ENDIF

    ;--------------------------------------------------------

_loop:
    invoke  lstrcat,            ADDR BeginFolderPath,
                                ADDR findFileData.cFileName

    mov     FinalFilePath,      eax

    .IF FinalFilePath == NULL
        invoke  MessageBox,     NULL,                       \
                                ADDR LstrcatFailed,         \
                                ADDR LstrcatFailed,         \
                                MB_OK 
    .endif      

    ;invoke crt_printf,         ADDR FormatPrintString,     \
    ;                           findFileData.cFileName

    invoke  MessageBox,         NULL,                       \
                                ADDR FinalFilePath,         \
                                ADDR FinalFilePath,         \
                                MB_OK 

    ;--------------------------------------------------------

    invoke  FindNextFile,       hFile,                      \
                                ADDR findFileData       

    .IF eax == NULL
        jmp                     _quit
    .ELSE
        jmp                     _loop                       
    .ENDIF

    ;--------------------------------------------------------

_quit:
    invoke  ExitProcess,        0

end start

编译工作完美。 lstrcat函数也不会失败。但在执行时,消息框显示字符串“-O @”。当我想用printf而不是_tprintf打印时,我注意到c ++程序中的行为相同(因为打印TCHAR Windows类型不适用于printf)。也许问题来自MessageBox函数或者TCHAR类型可能不是好的。只有c ++程序才有效。我输了。

有人可以帮助我吗?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

首先,您对lstrcat的调用将覆盖BeginFolderPath之后的内存。因此,FileName的值将会被覆盖,如果文件名很长,则无法确定该调用会破坏数据段的哪些部分。缓冲区溢出不是lstrcat唯一可能出现的问题。请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/ms647487(v=vs.85).aspx

上的文档

您可以考虑在调试器中运行它并在调用lstrcat后查看内存。

此外,您正在为您的字符串混合TCHARBYTE,这有点令人困惑。我不清楚你是否希望这个程序使用Unicode或ANSI字符串。正如它目前所写,这是不可能的。 TCHAR是这个程序中的一个字节,还是一个单词?如果这是一个单词,那么您需要调用MessageBoxW

设置输出汇编列表文件的编译器开关并编译C ++程序将具有指导意义。看一下生成的汇编代码。