Посл.ответ |
Сообщение |
 Ранг: 58.1 (постоянный) Активность: 0.03↘0 Статус: Участник
|
Создано: 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.02↘0 Статус: Участник
|
Создано: 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.03↘0 Статус: Участник
|
Создано: 03 февраля 2008 22:39 · Личное сообщение · #3
А отличаються ли эти структуры в разных билдах Nt? ну например в 2k/2003/XP/Vista/Longhorn ? можно ли смело юзать и не задумываться где будет выполнена программа?
| Сообщение посчитали полезным: |
Ранг: 495.3 (мудрец) Активность: 0.3↘0 Статус: Участник
|
Создано: 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.03↘0 Статус: Участник
|
Создано: 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.34↘0.25 Статус: Модератор retired
|
Создано: 04 февраля 2008 23:02 · Личное сообщение · #6
Раз исчерпана-закрывай, чтоб флуда не было. Шпунька такая Закрыть тему под кнопкой Отправить сообщение.
| Сообщение посчитали полезным: |