Author Topic: Get full path from the command line  (Read 7483 times)

Offline alexbnc

  • Jr. Member
  • *
  • Posts: 6
Get full path from the command line
« on: July 29, 2013, 06:02:26 PM »
I've been torturing myself with this issue for a month and I'm about to give up. It is a simple program and I just can't see why is not working properly.
So, what I am trying to do create is a simple application that will parse the command line and display the first argument, which is the full path to the executable.
This is how my code looks like:

Code: [Select]

[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

    call GetHandler
    call GetCommandLine
        mov eax, e

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

        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

            cmp ax, __utf16__(' ')
            je NewArg
            jmp ContinueParsing

                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

            cmp ax, 0
            jne Parse

            mov ecx, [PathEnd]
            mov ebx, [PathStart]
            sub ecx, ebx ; text size
            shr ecx, 1 ; is UNICODE
            push dword[PathStart]
            push dword[ecx]
            call ShowText
        push ebp
        mov ebp, esp
        push 0
        push dword WrittenChars
        push dword [ebp+8]
        push dword [ebp+12]
        push dword [StdHandle]
        call WriteConsoleW
        ret 8

        push ebx
        call ExitProcess
        pop ebx

Well, I might have misspelled or missed something but that is not the problem. The code is compiled and built successfully but the message that I see is only the name of the executable, not the full path that I expect. If the full path is "D:\My Projects\NASM\Demo.exe" I only see "Demo". If before calling ShowText I prepare the arguments for the message variable it works and I can see the text correctly, so I think the problem lies in getting the pointer and length of the full path correctly. Yet, when studying the running of the application with OllyDbg I can see that correct values are stored in the BSS section. This is very weird and maybe somebody with a better eye can catch the cause of it. Thanks in advance

Offline Gunner

  • Jr. Member
  • *
  • Posts: 74
  • Country: us
    • Gunners Software
Re: Get full path from the command line
« Reply #1 on: July 30, 2013, 03:32:38 AM »
To make life easier, you could use CommandLineToArgvW which will return the count of args.  To simplify, I used printf:

Code: [Select]
%define     STD_OUTPUT_HANDLE -11

; Shell32.dll
extern  CommandLineToArgvW

; Kernel32.dll
extern ExitProcess, WriteConsoleW, LocalFree
extern GetStdHandle, GetCommandLineW
%define GetCommandLine GetCommandLineW

;  msvcrt.dll
extern _printf

section .bss
stdout          resd 1
szArglist       resd 1
nArgs           resd 1

section .data
fmtst     db  "%ws", 13, 10, 0

section .text
global start

    call    GetStdHandle
    mov     dword [stdout], eax

    call    GetCommandLine
    push    nArgs
    push    eax
    call    CommandLineToArgvW
    mov     dword [szArglist], eax
    mov     esi, eax
    xor     ebx, ebx
    sub     dword [nArgs], 1
    push    dword [esi + 4 * ebx]
    push    fmtst
    call    _printf
    add     esp, 4 * 2
    inc     ebx
    cmp     ebx, dword [nArgs]
    jle     .DisplayArgs
    push    dword [szArglist]
    call    LocalFree
    push    0
    call    ExitProcess


Offline alexbnc

  • Jr. Member
  • *
  • Posts: 6
Re: Get full path from the command line
« Reply #2 on: July 30, 2013, 11:15:00 AM »
Thanks for that solution. It is a good alternative yet I would really like to understand what is the problem in my case. It is frustrating to see that something that is supposed to work just doesn't. Computers don't do things at random and without explanation. Today I tried this
Code: [Select]
            call GetCommandLineW ; UNICODE
            mov esi, eax
            ; display it here
            push    dword       eax
            push    dword       128
            call    ShowText
I am trying to get the entire, or at least the first 128 characters of the full command line. I still get weird characters, so I am really really lost right now. So, if I have my executable in "D:\Project\My Demo\Test.exe", I add this to Path and I execute "Test --firstarg" in the cmd what I get is
Test  --firstarg Test  --firstarg Winsta0\Default =::=:: \=C:=C:\Users\Alex =D:=D:\Project\MyDemo\ ALLUSERSPROFILE