Удаленный впрыск резьбы:
Вы используете удаленное внедрение потока, вызываете GetCommandLine()
, затем возвращаете результат IPC. Это может работать в большинстве случаев в Windows XP, но в Windows Vista и более поздних версиях не работает в системных и служебных процессах. Это связано с тем, что CreateRemoteThread
работает только с процессами с тем же идентификатором сеанса, что и у вызывающего - в Windows Vista службы и другие системные процессы выполняются в сеансе 0, а пользовательские программы - в сеансах более высокого уровня. Лучший и самый безопасный способ - прочитать структуру, присутствующую в каждом процессе Windows.
Структура PEB:
Блок среды процесса (PEB) обычно хранится в верхних областях памяти процесса, выше 0x7ff00000
. Эти регионы также содержат блоки среды потоков (TEB). Адрес PEB различен практически для каждого процесса, поэтому вы не можете просто использовать жестко закодированную константу.
#include <windows.h>
#include <stdio.h>
#include "Winternl.h"
typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
HANDLE ProcessHandle,
DWORD ProcessInformationClass,
PVOID ProcessInformation,
DWORD ProcessInformationLength,
PDWORD ReturnLength
);
PVOID GetPebAddress(HANDLE ProcessHandle)
{
_NtQueryInformationProcess NtQueryInformationProcess =
(_NtQueryInformationProcess)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
PROCESS_BASIC_INFORMATION pbi;
NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);
return pbi.PebBaseAddress;
}
int wmain(int argc, WCHAR *argv[])
{
int pid;
HANDLE processHandle;
PVOID pebAddress;
PVOID rtlUserProcParamsAddress;
UNICODE_STRING commandLine;
WCHAR *commandLineContents;
if (argc < 2)
{
printf("Usage: getprocesscommandline [pid]\n");
return 1;
}
pid = _wtoi(argv[1]);
if ((processHandle = OpenProcess(
PROCESS_QUERY_INFORMATION | /* required for NtQueryInformationProcess */
PROCESS_VM_READ, /* required for ReadProcessMemory */
FALSE, pid)) == 0)
{
printf("Could not open process!\n");
return GetLastError();
}
pebAddress = GetPebAddress(processHandle);
/* get the address of ProcessParameters */
if (!ReadProcessMemory(processHandle,
&(((_PEB*) pebAddress)->ProcessParameters),
&rtlUserProcParamsAddress,
sizeof(PVOID), NULL))
{
printf("Could not read the address of ProcessParameters!\n");
return GetLastError();
}
/* read the CommandLine UNICODE_STRING structure */
if (!ReadProcessMemory(processHandle,
&(((_RTL_USER_PROCESS_PARAMETERS*) rtlUserProcParamsAddress)->CommandLine),
&commandLine, sizeof(commandLine), NULL))
{
printf("Could not read CommandLine!\n");
return GetLastError();
}
/* allocate memory to hold the command line */
commandLineContents = (WCHAR *)malloc(commandLine.Length);
/* read the command line */
if (!ReadProcessMemory(processHandle, commandLine.Buffer,
commandLineContents, commandLine.Length, NULL))
{
printf("Could not read the command line string!\n");
return GetLastError();
}
/* print it */
/* the length specifier is in characters, but commandLine.Length is in bytes */
/* a WCHAR is 2 bytes */
printf("%.*S\n", commandLine.Length / 2, commandLineContents);
CloseHandle(processHandle);
free(commandLineContents);
return 0;
}
Для более подробной информации, пожалуйста, посмотрите Получить командную строку процесса
РЕДАКТИРОВАТЬ (Дополнительная информация):
Первый автор сказал:
CreateRemoteThread
работает только для процессов с тем же идентификатором сеанса, что и
вызывающая сторона - в Windows Vista запускаются сервисы и другие системные процессы
в сеансе 0, в то время как пользовательские программы работают в старших сеансах. Самый лучший и безопасный способ - прочитать структуру, присутствующую в каждом процессе Windows.
То же самое с OpenProcess , вы не можете открыть процесс, который является службой или процесс, открытый SYSTEM или LOCAL SERVICE NETWORK SERVICE , если ваша программа запускается пользователем (даже администратором).
Если ваша программа является службой, она, вероятно, уже запущена локальной системной учетной записью , так что никаких проблем.
Но если нет, решение состоит в том, чтобы запустить его с psexec :
- Загрузите PSEXEC и разархивируйте в какую-нибудь папку.
- Откройте привилегированное приглашение CMD от имени администратора.
- Перейдите в папку, в которую вы распаковали PSEXEC.EXE
- Прогон:
PSEXEC -i -s -d CMD
- Откроется новая подсказка CMD.
- Введите следующее в новом приглашении CMD, чтобы доказать, кто вы:
WHOAMI
Вы должны увидеть, что вы SYSTEM , теперь вы можете запустить свою программу и просмотреть командную строку для всех процессов.