Сейчас на форуме: vasilevradislav, tyns777, zombi-vadim (+3 невидимых)

 eXeL@B —› Программирование —› GetCommandLineA
Посл.ответ Сообщение


Ранг: 58.1 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 03 февраля 2008 17:49
· Личное сообщение · #1

Как получить параметры коммандной строки чужого процесса без использования CreateRemoteThread и без инжекта dll через установку хука на сообщения, через CreateRemoteThread ессно тоже нельзя инжект... обьясню почему...
есть вот такой код

program CmdLine;

{$APPTYPE CONSOLE}

uses
Windows, tlhelp32, Sysutils;

{function DebugSetProcessKillOnExit(KillOnExit:boolean):boolean;stdcall;external 'kernel32.dll';
function DebugActiveProcessStop(dwProcessId:cardinal):boolean;stdcall;external 'kernel32.dll';}
//Get module base in context of the owning process
function GetTrueModuleBase(PID:cardinal;ModuleName:string):Hmodule;
var
snap:cardinal;
modules:MODULEENTRY32;
begin
Result:=0;
snap:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,PID);
modules.dwSize:=sizeof(MODULEENTRY32);
if Module32First(snap,modules) then
repeat
if lowercase(modules.szModule)=lowercase(ModuleName) then
begin
Result:=Cardinal(modules.modBaseAddr);
break;
end;
until not Module32Next(snap,modules);
CloseHandle(snap);
end;
//---------

procedure ViewSysError(ErrCode:cardinal;func:string);
begin
Messagebox(0,pchar('error #'+inttostr(ErrCode)),pchar(func),MB_ICONERROR);
end;

var
hProcess,hRemoteThread,ThreadId,BR,PID,ptr:cardinal;
FuncPtr:Cardinal;
b:Byte;
cmd:string;
cb:dword;
hToken:THandle;
SeDebugNameValue:Int64;
tkp:TOKEN_PRIVILEGES;
begin
writeln('Write Process ID');
OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken);
LookupPrivilegeValue(nil,'SeDebugPrivilege',SeDebugNameValue);
tkp.PrivilegeCount:=1;
tkp.Privileges[0].Luid:=SeDebugNameValue;
tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,false,tkp,SizeOf(tkp),tkp,cb);
CloseHandle(htoken);
readln(PID);
hProcess:=OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_SET_QUOTA,false,PID);
ViewSysError(GetLastError,'OpenProcess');
FuncPtr:=Cardinal(GetProcAddress(GetModuleHandle('kernel32.dll'),'GetC ommandLineA'));
FuncPtr:=GetTrueModuleBase(PID,'kernel32.dll')+(FuncPtr-GetModuleHandl e('kernel32.dll'));
hRemoteThread:=CreateRemoteThread(hProcess,nil,1024,Pointer(FuncPtr),n il,0,ThreadId);
ViewSysError(GetLastError,'CreateRemoteThread');
WaitForSingleObject(hRemoteThread,INFINITE);
GetExitCodeThread(hRemoteThread,ptr);
CloseHandle(hRemoteThread);
cmd:='';
repeat
ReadProcessMemory(hProcess,pointer(ptr),pointer(@b),1,br);
cmd:=cmd+chr(b);
inc(ptr);
until b=0;
writeln('Command Line for this process:');
writeln(cmd);
CloseHandle(hProcess);
readln;
end.

в ХР всё работает... и у svchost.exe тоже получает комм. строку...
в Server 2008 RC0 и предположительно в висте не пашет. А вообще в мсдн написано типа что в процессе выполнящимся под аккаунтом другого пользователя то типа CreateRemoteThread не пашет... короче вот msdn2.microsoft.com/en-us/library/ms682437.aspx там написано. И возвращает код ошибки 8 после выполн. CreateRemoteThread.



Ранг: 23.2 (новичок), 8thx
Активность: 0.020
Статус: Участник

Создано: 03 февраля 2008 18:36
· Личное сообщение · #2

Нужная инфа есть в PEB

function GetCommandLine(pID: DWORD): PWChar;
label err;
var
pbi: array [0..5] of DWORD;
hProc: THandle;
pProcParams: DWORD;
wCmdLen: WORD;
pCmdLine: DWORD;
br: DWORD;
begin
result := nil;
hProc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, pID);
if NtQueryInformationProcess(hProc, 0, @pbi, $18, nil) <> 0 then goto err;
if not ReadProcessMemory(hProc, Pointer(pbi[1] + $10), @pProcParams, 4, br) then goto err;
if not ReadProcessMemory(hProc, Pointer(pProcParams + $40), @wCmdLen, 2, br) then goto err;
if not ReadProcessMemory(hProc, Pointer(pProcParams + $44), @pCmdLine, 4, br) then goto err;
result := GetMemory(wCmdLen);
if result = nil then goto err;
if not ReadProcessMemory(hProc, Pointer(pCmdLine), result, wCmdLen, br) then
begin
FreeMemory(result);
result := nil;
end;
err:
CloseHandle(hProc);
end;




Ранг: 58.1 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 03 февраля 2008 22:39
· Личное сообщение · #3

А отличаються ли эти структуры в разных билдах Nt? ну например в 2k/2003/XP/Vista/Longhorn ? можно ли смело юзать и не задумываться где будет выполнена программа?



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 04 февраля 2008 07:43
· Личное сообщение · #4

multiarc пишет:
А отличаються ли эти структуры в разных билдах Nt? ну например в 2k/2003/XP/Vista/Longhorn ?

Угу. Отличаются, но командная строка пока на месте.
На x86 в 2k/2003/XP/Vista, если я не путаю, можно юзать статичное смещение 20000h (указатель на RTL_USER_PROCESS_PARAMETERS). В CreateProcess оно забито и пока вроде не меняется.
Хотя, в любом случае, всё это на свой страх и риск.

-----
Всем привет, я вернулся





Ранг: 58.1 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 04 февраля 2008 17:32
· Личное сообщение · #5

Спасибо! тема исчерпана...
Вот код который в итоге получился.
program CmdLine;

{$APPTYPE CONSOLE}

uses
Windows;

var
NtQueryInformationProcess: function(ProcessHandle:cardinal;ProcessInformationClass:cardinal;Proce ssInformation:pointer;ProcessInformationLength:cardinal;ReturnLength:P ointer):cardinal;stdcall=nil;
RtlNtStatusToDosError: function(Status:integer):cardinal;stdcall=nil;

type
_RTL_USER_PROCESS_PARAMETERS=record
Reserved1:array [0..15] of byte;
Reserved2:array [0..9] of pointer;
Reserved3:Word;
ImageNameLen:Word;
ImageName:PWCHAR;
Reserved4:Word;
CommandLineLen:Word;
CommandLine:PWCHAR;
end;

_PEB=record
Reserved1:array [0..1] of byte;
BeingDebugged:boolean;
Reserved2:byte;
Reserved3:array [0..1] of Pointer;
LoaderData:Pointer;
ProcessParameters:Pointer;
Reserved4:array [0..103] of byte;
Reserved5:array [0..51] of Pointer;
PostProcessInitRoutine:Pointer;
Reserved6:array [0..127] of byte;
Reserved7:Pointer;
SessionId:Cardinal;
end;

_PROCESS_BASIC_INFORMATION=record
Reserved1:Pointer;
PebBaseAddress:Pointer;
Reserved2:array [0..1] of Pointer;
UniqueProcessId:PCardinal;
Reserved3:Pointer;
end;

procedure ViewSysError(ErrCode:cardinal;func:string);
var str:pointer;
s:pointer;
begin
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER,
nil,ErrCode,LANG_USER_DEFAULT,@str,0,nil);
writeln('Error in function ',func);
getmem(s,lstrlen(str)+1);
AnsiToOem(str,s);
writeln(pansichar(s));
freemem(s);
LocalFree(Cardinal(str));
end;

function GetCommandLine_(pID: DWORD): PWChar;
var
pbi:_PROCESS_BASIC_INFORMATION;
peb:_PEB;
rupp:_RTL_USER_PROCESS_PARAMETERS;
hProc: THandle;
br: DWORD;
begin
hProc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, pID);
if hproc=0 then
ViewSysError(GetLastError,'OpenProcess');
br:=NtQueryInformationProcess(hProc, 0, @pbi, sizeof(pbi), nil);
if br<>0 then
ViewSysError(RtlNtStatusToDosError(br),'NtQueryInformationProcess');
ReadProcessMemory(hproc,pbi.PebBaseAddress,@peb,sizeof(peb),br);
ReadProcessMemory(hproc,peb.ProcessParameters,@rupp,sizeof(rupp),br);
GetMem(result,rupp.CommandLineLen);
ReadProcessMemory(hproc,rupp.CommandLine,result,rupp.CommandLineLen,br );
CloseHandle(hProc);
end;

var
PID:cardinal;
cmd:PwChar;
cb:dword;
hToken:THandle;
SeDebugNameValue:Int64;
tkp:TOKEN_PRIVILEGES;
begin
writeln('Write Process ID');
NtQueryInformationProcess := GetProcAddress(GetModuleHandle('ntdll.dll'),'NtQueryInformationProcess ');
RtlNtStatusToDosError := GetProcAddress(GetModuleHandle('ntdll.dll'),'RtlNtStatusToDosError');
OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken);
LookupPrivilegeValue(nil,'SeDebugPrivilege',SeDebugNameValue);
tkp.PrivilegeCount:=1;
tkp.Privileges[0].Luid:=SeDebugNameValue;
tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,false,tkp,SizeOf(tkp),tkp,cb);
CloseHandle(htoken);
readln(PID);
cmd:=GetCommandLine_(Pid);
writeln(WideCharToString(cmd));
if cmd<>nil then
FreeMem(cmd);
readln;
end.





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 04 февраля 2008 23:02
· Личное сообщение · #6

Раз исчерпана-закрывай, чтоб флуда не было. Шпунька такая Закрыть тему под кнопкой Отправить сообщение.


 eXeL@B —› Программирование —› GetCommandLineA
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати