flat assembler
Message board for the users of flat assembler.
Index
> Windows > Command line differs in Command Prompt & PowerShell? |
Author |
|
revolution 30 May 2023, 23:19
I suggest two ways to solve this:
1) Print out the returned string from GetCommandLine in hex and look for differences. 2) Use a debugger and follow the code. |
|||
30 May 2023, 23:19 |
|
Flier-Mate 31 May 2023, 03:20
revolution wrote: I suggest two ways to solve this: I use the first method as it is easier, but I don't know how to interpret this result.... I use: "test2 test.asm > cmd.txt" at command prompt and ".\test2 test.asm > ps.txt" at PowerShell. Command-prompt: Code: 00000000 74 65 73 74 32 20 20 74 65 73 74 2E 61 73 6D 20 test2 test.asm 00000010 00 00 00 00 00 00 00 00 42 84 7C 12 68 7C 00 10 ........B.|.h|.. PowerShell: Code: 00000000 FF FE 22 00 43 00 3A 00 5C 00 55 00 73 00 65 00 ..".C.:.\.U.s.e. 00000010 72 00 73 00 5C 00 42 00 4F 00 4F 00 5C 00 70 00 r.s.\.B.O.O.\.p. 00000020 72 00 6F 00 6A 00 65 00 63 00 74 00 73 00 5C 00 r.o.j.e.c.t.s.\. 00000030 74 00 65 00 73 00 74 00 32 00 2E 00 65 00 78 00 t.e.s.t.2...e.x. 00000040 65 00 22 00 20 00 74 00 65 00 73 00 74 00 2E 00 e.". .t.e.s.t... 00000050 61 00 73 00 6D 00 00 00 00 00 00 00 00 00 00 00 a.s.m........... The command line string returned by PowerShell has BOM and is in Wide Char?? That one returned by command prompt has an extra white space (0x20) at the end of command line, and the one returned by PowerShell doesn't have two white space after the program name. This is how I print the string returned by GetCommandLine: Code: section '.data' readable writable _dummy dd ? _stdout dd ? section '.code' code readable executable start: invoke GetCommandLine push eax invoke GetStdHandle, -11 mov [_stdout], eax pop eax mov esi, eax mov edx, MAX_PATH call Print invoke ExitProcess,0 Print: ;invoke WriteConsole, dword [_stdout], esi, edx, _dummy, 0 invoke WriteFile, dword [_stdout], esi, edx, _dummy, 0 ret From visual inspection (screenshot attached), I think it is because Command Prompt inserts two white space between program name and input filename.....
|
||||||||||
31 May 2023, 03:20 |
|
bitRAKE 31 May 2023, 03:33
Reading the code we can see something peculiar:
First the length of the string is calculated with: Code: or ecx, -1 xor eax, eax repnz scasb ; Calculate total length of command line arguments not ecx dec ecx Then the distance of first argument with: Code: or ecx, -1 mov eax, 32 repnz scasb ; Calculate length of first command line argument (APPNAME) not ecx inc ecx So, these techniques have a difference of two. Why? If we wanted to skip the space character they should only differ by one. Although Powershell is a different command processor, I think the error is in your code - the INC ECX is probably not what you intend. _________________ ¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup |
|||
31 May 2023, 03:33 |
|
Flier-Mate 31 May 2023, 03:43
Thanks bitRAKE for your analysis, it is indeed true to skip the space character they should only differ by one.
If I comment the "inc ecx", the output in PowerShell is correct ("test.asm") but in command prompt is in error (" test.asm"). From my quick check, "dec ecx" is to remove the trailing space, and the "inc ecx" is to take command prompt special case into consideration (there are two white spaces between program name and input filename, not just one like in PowerShell). And thanks for your code (that one you quoted), I modified it to use in my program to extract command line string. |
|||
31 May 2023, 03:43 |
|
revolution 31 May 2023, 04:01
It should be indifferent to the number of spaces.
A user could type Code: C:\> test.exe arg0 arg1 "2 3" 4 "5 6 7" |
|||
31 May 2023, 04:01 |
|
bitRAKE 31 May 2023, 04:16
Your redirected output also confirms the double-space. Seems like more complex processing is needed. Could just use CommandLineToArgvW() and be done with it. (Of course, that has it's own caveats.)
Might be of interest: The wild west of Windows command line parsing. |
|||
31 May 2023, 04:16 |
|
Flier-Mate 31 May 2023, 05:03
Thank you revolution and bitRAKE for the feedback.
The "wild west of Windows command lien parsing" article has interesting point about undocumented offset in fs register to get the command line string. Wouldn't know that if I didn't read this article. Yes, more complex processing is needed, I will use CommandLineToArgvW() as last resort. Or use "Command line parameters" example found in FASM website. But.... I have an idea on how to solve the arbitrary white spaces, I will insert another routine to scan for white spaces until not found. Will start implement this in my future program. Thank you all once again! |
|||
31 May 2023, 05:03 |
|
Flier-Mate 07 Aug 2023, 06:56
I fixed the code, the following work in Command Prompt and PowerShell:
Code: call [GetCommandLine] push eax cld mov edi, eax or ecx, -1 xor eax, eax repnz scasb ; Calculate total length of command line arguments not ecx pop eax push eax mov dword [_fnlen], ecx mov edi, eax or ecx, -1 mov eax, 32 repnz scasb ; Find the first white space after first argument repz scasb ; Scan for extra white spacing between first argument and second argument not ecx mov dword [_dummy], ecx sub dword [_fnlen], ecx cmp dword [_fnlen], 0 ; Check if no argument is supplied js .err0 mov ecx, dword [_fnlen] pop eax add eax, dword [_dummy] dec eax mov esi, eax lea edi, [_filename] rep movsb First argument here refers to APPNAME, second argument is user's specified FILENAME. |
|||
07 Aug 2023, 06:56 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.