Я заинтересован в том, чтобы вставлять библиотеки DLL в процессы, принадлежащие SYSTEM, на моей машине Vista. Я собираюсь об этом, используя традиционный метод VirtualAllocEx, WriteProcessMemory и CreateRemoteThread. Однако, поскольку это будет работать в процессах SYSTEM, я включаю SeDebugPivilege в процессе внедрения, прежде чем открывать целевой процесс.
int EnableDebugPriv(LPCTSTR name) {
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),
/*TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY*/
TOKEN_ALL_ACCESS,
&hToken))
return 0;
if(!LookupPrivilegeValue(NULL,name,&luid))
return 0;
tkp.PrivilegeCount=1;
tkp.Privileges[0].Luid=luid;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,false,&tkp,sizeof(tkp),NULL,NULL))
{
printf("!AdjustTokenPrivileges - %d\n",GetLastError());
return 0;
}
if(GetLastError()==ERROR_NOT_ALL_ASSIGNED)
{
return 0;
}
CloseHandle(hToken);
return 1;
}
Где константа SE_DEBUG_NAME
передается как имя.
После включения SeDebugPrivilege я прохожу процесс открытия целевого процесса, поиска LoadLibrary, выделения пространства, записи пути DLL в память и создания потока (проверяя все возвращаемые значения по пути):
if(NULL==(p=OpenProcess(PROCESS_ALL_ACCESS,FALSE,(DWORD)pid)))
...
if(NULL==(loadLib=(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"),
"LoadLibraryA")))
...
if(NULL==(dllBuff=(LPVOID)VirtualAllocEx(p,
NULL,
strlen(dllPath)+1,
MEM_RESERVE|MEM_COMMIT,
PAGE_READWRITE)))
...
if(NULL==WriteProcessMemory(p,
(LPVOID)dllBuff,
dllPath,
strlen(dllPath),
&written))
...
if(!CreateRemoteThread(p,
NULL,
NULL,
(LPTHREAD_START_ROUTINE)loadLib,
(LPVOID)dllBuff,
NULL,
NULL))
...
dllPath
- это символ * пути DLL (очевидно), а pid
- это PID целевого процесса. Оба эти значения принимаются через командную строку и проверяются перед использованием.
Проблема, с которой я столкнулся, заключается в том, что ничего не возвращает ошибки до CreateRemoteThread, который возвращает 8 («Недостаточно памяти»). ОДНАКО WriteProcessMemory НЕ записывает байты в процесс. После вызова записываемая переменная всегда равна 0. Байт не записывается, но функция не дает сбоя. Я не уверен, почему это происходит. Я посмотрел на другие привилегии, такие как SeRestorePrivilege, который обещает доступ на запись ко всем процессам, но ничего не работает.
Я запускаю эту программу с правами администратора.
Примечание: эта проблема WriteProcessMemory и CreateRemoteThread возникает только тогда, когда я запускаю эту программу для пользователей с более высокими привилегиями (SYSTEM, LOCAL SERVICE и т. Д. ...). Он отлично работает против программы, принадлежащей мне (те же привилегии).
Редактировать: вот ссылка на весь источник. http://pastebin.com/m77110d8e Там нет ничего другого, кроме базовой проверки ошибок, но, может быть, это поможет?