News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

where is the address of the command line string?

Started by zermelo, October 27, 2008, 02:13:15 PM

Previous topic - Next topic

zermelo

Hi,
in the old Dos, the command line string was stored at address 81h, but in win32 where is it? I really know that GetCommandLine can tell me that, but my question is about the process images of win32. Thanks

drizz

it's a lot more complex than DOS thats for sure, probably because it's undocumented :)

assume fs:nothing
mov eax,fs:[TEB.Peb]
mov eax,[eax].PEB.ProcessParameters
mov eax,[eax].RTL_USER_PROCESS_PARAMETERS.CommandLine.UNICODE_STRING.Buffer
;; here EAX points to Unicode string of the command line

You can find all this structures in KMDKit by Four-F.
The truth cannot be learned ... it can only be recognized.

Mark Jones

"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Vortex

drizz,

Is your method portable across different Windows versions? MS can modify this structure in the future.

Vortex

Is your method portable across different Windows versions? MS can modify the structure TEB in the future.

drizz

Of course it's not, it only works on W2K, XP, 2K3 & later maybe? GetCommandLine is the proper way.
The truth cannot be learned ... it can only be recognized.

donkey

Well, the offset 10h in the PEB structure is not likely to change since it points to the RTL_USER_PROCESS_PARAMETERS structure that contains the address of the command line. However "not likely" does not mean "will not" so you have to use it at your own risk...

RTL_USER_PROCESS_PARAMETERS STRUCT
  Reserved1 DB 16 DUP (?)
  Reserved2 DD 10 DUP (?)
  ImagePathName DD ? // UNICODE STRING
  CommandLine DD ? // UNICODE STRING
ENDS


[EDIT]Sorry just looked over Drizz's example code and aside it does exactly what I was thinking.[/EDIT]
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

minor28

In spite of the matter is most likely settled, why not use ordinary APIs. In this way you will have
pointers to each argument in the commandline. Here is my example

.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include windows.inc
include kernel32.inc
include user32.inc
include shell32.inc

includelib kernel32.lib
includelib user32.lib
includelib shell32.lib

.data
szAppName db "Commandline arguments",0
szNewLine db 13,10,0

.data?
hInstance dd ?
pCommandline dd ?
pNumArgs dd ?

buffer db 256 DUP(?)
buffer1 db 256 DUP(?)

.code
start:

invoke GetModuleHandle,NULL
mov hInstance,eax

invoke GetCommandLineW
mov pCommandline,eax

invoke CommandLineToArgvW,pCommandline,offset pNumArgs
mov ebx,eax
;Path to application
invoke WideCharToMultiByte,CP_ACP,0,dword ptr [ebx],-1,\
             offset buffer,sizeof buffer,0,0
mov ecx,2
.while ecx<=pNumArgs
push ecx
push ecx
invoke lstrcat,addr buffer,offset szNewLine
;Commandline arguments
pop eax
sub eax,1
mov edx,4
mul edx
invoke WideCharToMultiByte,CP_ACP,0,dword ptr [ebx + eax],-1,\
                     offset buffer1,sizeof buffer1,0,0
invoke lstrcat,addr buffer,offset buffer1
pop ecx
inc ecx
.endw

invoke MessageBox,0,offset buffer,offset szAppName,MB_OK

invoke ExitProcess,0

end start


Edit: I didn't read the first guestion properly so disregard this post.