Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 从程序集中的命令行获取完整路径_Assembly_Unicode_Command Line_Path_Nasm - Fatal编程技术网

Assembly 从程序集中的命令行获取完整路径

Assembly 从程序集中的命令行获取完整路径,assembly,unicode,command-line,path,nasm,Assembly,Unicode,Command Line,Path,Nasm,我已经为这个问题折磨了自己一个月了,我打算放弃。这是一个简单的程序,我就是不明白为什么不能正常工作。 因此,我试图创建一个简单的应用程序,它将解析命令行并显示第一个参数,这是可执行文件的完整路径。 我的代码是这样的: use32 [EXTERN GetStdHandle] [EXTERN GetCommandLineW] [EXTERN WriteConsoleW] [EXTERN ExitProcess] [section .bss] StdHandle resd 1 PathStart

我已经为这个问题折磨了自己一个月了,我打算放弃。这是一个简单的程序,我就是不明白为什么不能正常工作。 因此,我试图创建一个简单的应用程序,它将解析命令行并显示第一个参数,这是可执行文件的完整路径。 我的代码是这样的:

use32

[EXTERN GetStdHandle]
[EXTERN GetCommandLineW]
[EXTERN WriteConsoleW]
[EXTERN ExitProcess]

[section .bss]
StdHandle resd 1
PathStart resw 1
PathEnd resw 1
WrittenChars resw 1

[section .data]
message db __utf16__("Hello everybody"), 13, 10, 0

[section .text]
global start

start:
    call GetHandler
    call GetCommandLine
    end:
        mov eax, 0
        ret

    GetHandler:
        push -11
        call GetStdHandle
        cmp eax, 1
        push ebx
        mov ebx, 1
        jl CloseApp
        pop ebx
        mov dword[StdHandle], eax
        ret

    GetCommandLine:
        cld
        call GetCommandLineW ; UNICODE
        mov esi, eax
        mov bh, 0 ; here we save the argc
        mov ecx, eax ; here we save the pointer of the first arg

        Parse:
            lodsw
            cmp ax, __utf16__(' ')
            je NewArg
            jmp ContinueParsing

            NewArg:
                inc bh
                cmp bh, 1
                jne Parse
                ; if the first arg was just read save the 
                ; start from ecx and end from esi to the BSS variables
                mov dword[PathStart], ecx
                mov dword[PathEnd], esi
                jmp ShowPath

        ContinueParsing:
            cmp ax, 0
            jne Parse

        ShowPath:
            mov ecx, [PathEnd]
            mov ebx, [PathStart]
            sub ecx, ebx ; text size
            shr ecx, 1 ; is UNICODE
            push dword[PathStart]
            push dword[ecx]
            call ShowText
            ret

    ShowText:
        push ebp
        mov ebp, esp
        push 0
        push dword WrittenChars
        push dword [ebp+8]
        push dword [ebp+12]
        push dword [StdHandle]
        call WriteConsoleW
        pop ebp
        ret 8

    CloseApp:
        push ebx
        call ExitProcess
        pop ebx
        ret
嗯,我可能拼错了或遗漏了什么,但这不是问题所在。代码已成功编译和构建,但我看到的消息只是可执行文件的名称,而不是我期望的完整路径。如果完整路径为“D:\My Projects\NASM\Demo.exe”,则我只看到“Demo”。如果在调用
ShowText
之前,我准备了
message
变量的参数,它可以工作,并且我可以正确地看到文本,因此我认为问题在于正确获取完整路径的指针和长度。然而,在研究使用OllyDbg运行应用程序时,我可以看到正确的值存储在
BSS
部分。这是非常奇怪的,也许有人有更好的眼睛可以抓住它的原因。提前谢谢

更新 今天,我尝试以如下方式显示整个命令行:

GetCommandLine:
        cld
        call GetCommandLineW ; UNICODE
        mov esi, eax
        ; display it here
        push    dword       eax
        push    dword       128
        call    ShowText
我仍然看到奇怪的角色。我知道还有其他选择,但我只是想知道为什么这么简单的事情在第一眼就不起作用。我的意思是,计算机做事情不是随意的,没有解释的

jne解析;否则,继续解析

mov-dword[PathStart],ecx;保存路径字符串的开头

mov-dword[PathEnd],esi;保存路径字符串的结尾

继续讨论:

cmp-ax,0;如果这不是命令行的结尾

jne解析;返回分析

mov dword[PathEnd]之后,esi
您应该
jmp
ShowPath
。否则,您将检查ax==0——由于它包含一个空格字符,因此显然不会是这样——并且您将返回到
解析


mov-ecx,[PathStart];将路径字符串的开头保存在ECX中

mov-ebx[PathEnd];在EBX中保存路径字符串的结尾

子ecx、ebx;计算ECX中路径字符串的大小

您正在从
PathStart
中减去
PathEnd
。应该是相反的。在调用
WriteConsoleW
之前,还需要将长度除以2(即
shr ecx,1
),因为
WriteConsoleW
的第三个参数是要写入的字符数(而不是字节数)



GetFullPath
的开头添加
cld
指令也可能是一个好主意,以确保
lodsw
将地址移动到正确的方向。

什么的完整路径?您能给出一个示例命令行和预期的输出吗?该命令行包含可执行文件的路径以及用户指定的其他参数。示例:“C:\Program Files\MyApp\AppExe.exe”“arg1”“arg2”。在这里,我只想显示第一部分(可执行文件的完整路径),即“C:\Program Files\MyApp\AppExe.exe”。您正在测试的路径包含一个空格(在我的和项目之间)。您的解析代码无法正确处理此类情况。您可能需要研究调用。这将为您完成解析,正确处理引用参数中的空格、转义字符等。我可以使用它作为最后一个选项,但看到如此简单的东西不起作用,令人沮丧。即使它会在第一个空格处停止,至少在那之前我应该看到文本。奇怪的是,它仍然不起作用。仅显示“MyApp”。错误的开始,错误的长度这对我来说很有效(我使用masm32来确认我建议的更改给出了期望的结果)。