Господа! Как получить параметры с которыми была вызвана программа? ProcessExplorer как это делает? Я в мсдне не нашёл - может плохо искал? Направте! Спасибо.
хочу попутно задать вопрос: а как узнать, где в соседней программе находится PEB? А то очень интересует, как Олли затирает флаг отладки в отлаживаемом приложении
Спасибо. Одно НО - если GetCommandLine - для, своего а для другого процесса? я в инете встречал способ - типа инжект, а там уже GetCommandLine Насколько я понял стандартно нельзя, т.е. через АПИ. А тогда не подскажители описание структуры PEB, и как же её прочитать из чужого процесса. К тому же на всё это ругается фаервол ...
Код (Text): typedef struct _PEB { BYTE InheritedAddressSpace; BYTE ReadImageFileExecOptions; BYTE BeingDebugged; BYTE SpareBool; void* Mutant; void* ImageBaseAddress; struct _PEB_LDR_DATA* Ldr; struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; void* SubSystemData; void* ProcessHeap; void* FastPebLock; void* FastPebLockRoutine; void* FastPebUnlockRoutine; DWORD EnvironmentUpdateCount; void* KernelCallbackTable; DWORD SystemReserved[2]; struct _PEB_FREE_BLOCK* FreeList; DWORD TlsExpansionCounter; void* TlsBitmap; DWORD TlsBitmapBits[2]; void* ReadOnlySharedMemoryBase; void* ReadOnlySharedMemoryHeap; void** ReadOnlyStaticServerData; void* AnsiCodePageData; void* OemCodePageData; void* UnicodeCaseTableData; DWORD NumberOfProcessors; DWORD NtGlobalFlag; LARGE_INTEGER CriticalSectionTimeout; DWORD HeapSegmentReserve; DWORD HeapSegmentCommit; DWORD HeapDeCommitTotalFreeThreshold; DWORD HeapDeCommitFreeBlockThreshold; DWORD NumberOfHeaps; DWORD MaximumNumberOfHeaps; void** ProcessHeaps; void* GdiSharedHandleTable; void* ProcessStarterHelper; DWORD GdiDCAttributeList; void* LoaderLock; DWORD OSMajorVersion; DWORD OSMinorVersion; WORD OSBuildNumber; WORD OSCSDVersion; DWORD OSPlatformId; DWORD ImageSubsystem; DWORD ImageSubsystemMajorVersion; DWORD ImageSubsystemMinorVersion; DWORD ImageProcessAffinityMask; DWORD GdiHandleBuffer[34]; void* PostProcessInitRoutine; void* TlsExpansionBitmap; DWORD TlsExpansionBitmapBits[32]; DWORD SessionId; ULARGE_INTEGER AppCompatFlags; void* pShimData; void* AppCompatInfo; UNICODE_STRING CSDVersion; void* ActivationContextData; void* ProcessAssemblyStorageMap; void* SystemDefaultActivationContextData; void* SystemAssemblyStorageMap; DWORD MinimumStackCommit; } PEB; typedef struct _RTL_USER_PROCESS_PARAMETERS { ULONG AllocationSize; ULONG Size; ULONG Flags; ULONG DebugFlags; HANDLE hConsole; ULONG ProcessGroup; HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; UNICODE_STRING CurrentDirectoryName; HANDLE CurrentDirectoryHandle; UNICODE_STRING DllPath; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PWSTR Environment; ULONG dwX; ULONG dwY; ULONG dwXSize; ULONG dwYSize; ULONG dwXCountChars; ULONG dwYCountChars; ULONG dwFillAttribute; ULONG dwFlags; ULONG wShowWindow; UNICODE_STRING WindowTitle; UNICODE_STRING Desktop; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeInfo; RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
фаервол скорее всего аутпост и ругается он именно на внедрение в другой процесс а не обнаружение коммандной строки )
Нет у меня описания. По названиям параметров можно понять, что и где лежит. Получаешь указатель на EProcess через IoGetCurrentProcess(), далее из EProcess получаешь указатель на PEB, из которого получаешь указатель на RTL_USER_PROCESS_PARAMETERS, в котором сидит искомый CommandLine в виде UNICODE_STRING. Это из драйвера через IoGetCurrentProcess() получается EProcess. Как из юзера - не знаю, подозреваю, что никак не получается для чужого процесса (где-то читал такое). Для своего процесса указатель на PEB получается так: assume fs:nothing mov eax,FS:[00000030h]
GetThreadSelectorEntry - получаешь базу FS. (Селектор FS одинаковый у всех юзермодных прог). Далее берешь эту базу и делаeшь ReadProcessMemory / WriteProcessMemory. Структура PEB описана выше GetThreadSelectorEntry
Посмотри исходники EzProcess (EzProcess.v1.82_src) там ассемблер и все легко найти. Правда нужный тебе функционал в библиотеке ProcHlpr.lib, а исходников нет. Но дизассемблер в руки и все на ура найдешь. Функиция GetProcessEBDataA invoke GetProcessEBDataA,dProcessID,pBuffer,dBuffSize,PEB_GET_CMD_LINE Алгоритм: OpenProcess ZwQueryInformationProcess ReadProcessMemory
Для чужого процесса PEB можно получить из user mode вызовом NtQueryInformationProcess. Для этого нужен только дескриптор чужого процесса. Структура PEB (если я правильно понял Руссиновича&Соломона) находится в пользовательском адресном пространстве процесса. Далее ReadProcessMemory. В этом случае инжект не нужен. Но я могу ошибаться, потому как сам этого не делал. Но если мысль пригодится - пожалуйста.
Код (Text): program GetProcCmdLine; uses Windows; function NtQueryInformationProcess(hProcess: THandle; ProcessInfoClass: Integer; ProcessInfoBuffer: Pointer; ProcessInfoBufferLength: Cardinal; BytesReturned: PCardinal): integer; stdcall; external 'ntdll.dll'; 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; begin MessageBoxW(0, GetCommandLine(1028), 'Command line is:', 0); end.
Код (Text): const DWORD FS = 0x3B; DWORD ownerProcessId = 38056; // Open process HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ownerProcessId); if(!hProcess) return printf("Cannot open process\n"); // Find thread HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); THREADENTRY32 te = {sizeof(te)}; Thread32First(hSnapshot, &te); DWORD threadId = 0; do { if(te.th32OwnerProcessID == ownerProcessId) threadId = te.th32ThreadID; } while(Thread32Next(hSnapshot, &te)); if(!threadId) return printf("No threads for specified process id\n"); // Get FS base HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, threadId); if(!hThread) return printf("Cannot open thread\n"); LDT_ENTRY fs_entry; GetThreadSelectorEntry(hThread, FS, &fs_entry); DWORD fs_base = fs_entry.BaseLow | (fs_entry.HighWord.Bytes.BaseMid<<16) | (fs_entry.HighWord.Bytes.BaseHi<<24); // Read modules list TEB teb; DWORD read; if(!ReadProcessMemory(hProcess, (LPCVOID) fs_base, &teb, sizeof(teb), &read)) return printf("Can't read process memory for TEB, %d bytes read\n", read); PEB peb; if(!ReadProcessMemory(hProcess, (LPCVOID) teb.Peb, &peb, sizeof(peb), &read)) return printf("Can't read process memory for PEB, %d bytes read\n", read);