I’m trying to write a program that uses CreateRemoteThread
to inject a dll.
The problem is that CreateRemoteThread is refusing to work. GetLastError() is returning 5 which is ERROR_ACCESS_DENIED. I cant figure why!
I am working from this video http://www.youtube.com/watch?v=H3O3hmXkt1I .
#include <iostream>
#include <direct.h>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;
char* GetCurrentDir()
{
char* szRet = (char*)malloc(MAX_PATH);
_getcwd(szRet, MAX_PATH);
return szRet;
}
LPCTSTR SzToLPCTSTR(char* szString)
{
LPTSTR lpszRet;
size_t size = strlen(szString)+1;
lpszRet = (LPTSTR)malloc(MAX_PATH);
mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
return lpszRet;
}
void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDelay)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
BOOL bAppeared = FALSE;
while(!bAppeared)
{
if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnap, &peProc))
while(Process32Next(hSnap, &peProc) && !bAppeared)
if(!lstrcmp(lpcszProc, peProc.szExeFile))
bAppeared = TRUE;
}
CloseHandle(hSnap);
Sleep(dwDelay);
}
}
DWORD GetProcessIdByName(LPCTSTR lpcszProc)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
DWORD dwRet = -1;
if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnap, &peProc))
while(Process32Next(hSnap, &peProc))
if(!lstrcmp(lpcszProc, peProc.szExeFile))
dwRet = peProc.th32ProcessID;
}
CloseHandle(hSnap);
return dwRet;
}
BOOL InjectDll(DWORD dwPid, char* szDllPath)
{
DWORD dwMemSize;
HANDLE hProc;
LPVOID lpRemoteMem, lpLoadLibrary;
BOOL bRet = FALSE;
if((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) != NULL)
{
dwMemSize = strlen(szDllPath);
if((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
if(WriteProcessMemory(hProc, lpRemoteMem, szDllPath, dwMemSize, NULL))
{
lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if(CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
{
bRet = TRUE;
}
cout << GetLastError();
}
}
CloseHandle(hProc);
return bRet;
}
int main()
{
char szProc[MAX_PATH], szDll[MAX_PATH];
char* szDllPath = (char*)malloc(MAX_PATH);
LPTSTR lpszProc = NULL;
for(;;)
{
cout << "Process: ";
cin >> szProc;
cout << "DLL: ";
cin >> szDll;
szDllPath = GetCurrentDir();
strcat_s(szDllPath, MAX_PATH, "\");
strcat_s(szDllPath, MAX_PATH, szDll);
cout << "Waiting for process.. ." << szDllPath << " " << szDll << endl;
WaitForProcessToAppear(SzToLPCTSTR(szProc), 100);
if(InjectDll(GetProcessIdByName(SzToLPCTSTR(szProc)), szDllPath))
cout << "Injection Succeeded!" << endl;
else
cout << "Injection Failed!" << endl;
cout << "n";
}
return 0;
After a fair amount of googling I cant find a reason why this should not be working.
Does CreateRemoteThread not work under Windows 7 ?
If it does, have I made any obvious mistakes ?
CreateRemoteThread — ERROR_ACCESS_DENIED
I think my code is finally working now. Only problem is that for some reason, even though I’ve opened the process with PROCESS_ALL_ACCESS, CreateRemoteThread throws back an error: ERROR_ACCESS_DENIED.
The error was retrieved with GetLastError() and it spit out ‘5’, which translates to ERROR_ACCESS_DENIED.
|
|
Last edited on
Last edited on
Hello,
First thing I would like to check is are you running your test program (the program you have made to use CreateRemoteThread) as Administrator?
If you cannot do this for whatever, you can attempt to modify the tokens of your process to make your process have SE_DEBUG_NAME privileges.
To do this, you can use the OpenProcessToken and SetPrivilege functions.
The second thing I would like to mention is if you changed the process target to «calc.exe» just to post this thread (for example, if you were really trying to inject into security software), the chances are it would be a protected process, hence this would not work. To interact with protected processes (security software protect their processes), you would require a kernel-mode driver.
Maybe you were not, just thought I’d mention it say on case!
Lastly, I have compiled the source code successfully and tested it. The code works, the injection succeeds for me. Want to know why? It’s because you must make the architecture of the build the same as the target process to be injected. For example, if your program is x86 and your process is x64, it will not work. (as @modoran mentioned).
Thanks. Maybe my little comments above will be helpful though, or to someone else in the future anyway.
Topic archived. No new replies allowed.
I have a code which injects a dll to a process. The process which executes the injection function is always in the same architecture (x86 or x64) as the injected process. But for some reason, the CreateRemoteThread function call fails on Win7 64 bit OS, when
the injecting and injected processes are of x86 architecture. Surprisingly, when the OS is Win10 64bit. 32 bit processes work fine. The code also works well for Win7 64 bit with 64 bit processes, and for Win7 32 bit with 32 bit processes.
I’ve looked over the internet for a possible cause and all I could find is that in Win7 there are sometimes issues with process sessions. I don’t think this is the case since both the injecting and injected processes are «user» sessions.
When running GetLastError() I get 5 (ERROR_ACCESS_DENIED)
This is my injection function:
DWORD Inject(DWORD PID, const char *dllname)
{
HANDLE hThread = NULL;
BOOL writeSucceed = false;
int cch = 0;
cout << «Injector.dll : Injecting » << dllname << » to » << PID << endl;
DWORD hLibModule;
HMODULE hKernel32 = GetModuleHandle (TEXT («Kernel32»));
void *hProcess = OpenProcess (PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE, false, PID);
cch = strlen (dllname) + 1;
void *pLibRemote = VirtualAllocEx (hProcess, NULL, cch, MEM_COMMIT,
PAGE_READWRITE);
writeSucceed = WriteProcessMemory (hProcess, pLibRemote, (void *) dllname, cch, NULL);
hThread = CreateRemoteThread (hProcess, NULL, 0,
(PTHREAD_START_ROUTINE)
GetProcAddress (hKernel32,
«LoadLibraryA»),
pLibRemote, 0, NULL);
WaitForSingleObject (hThread, INFINITE);
GetExitCodeThread( hThread, &hLibModule );
CloseHandle (hThread);
VirtualFreeEx (hProcess, pLibRemote, sizeof (dllname), MEM_RELEASE);
hThread = CreateRemoteThread (hProcess, NULL, 0,
(PTHREAD_START_ROUTINE) GetProcAddress (hKernel32,
«FreeLibrary»),
(void *) hLibModule, 0, NULL);
WaitForSingleObject (hThread, INFINITE);
CloseHandle (hThread);
return 0;
}
Maybe CreateRemoteThread is just not supported in Win7 64bit for 32bit applications?
Страница 1 из 2
-
lobzik
New Member
- Публикаций:
-
0
- Регистрация:
- 9 апр 2009
- Сообщения:
- 34
Всем привет.
В общем сразу скажу гуглил-шмуглил, ничего не нагуглил.
Есть ф-ия, которая должна загружать dll в адресное пространство другого процесса.-
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
-
HANDLE hProcess = NULL, hThread = NULL;
-
PWSTR pszLibFileRemote = NULL;
-
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, dwProcessId);
-
int cb = (1 + lstrlenW(pszLibFile)) * sizeof(WCHAR);
-
pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
-
if (pszLibFileRemote == NULL)
-
if ( !WriteProcessMemory(hProcess, pszLibFileRemote, pszLibFile, cb, NULL) )
-
LPTHREAD_START_ROUTINE pfnThreadRtn = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT(«Kernel32»)), «LoadLibraryW»);
-
if (pfnThreadRtn == NULL)
-
hThread = CreateRemoteThread(hProcess, NULL, NULL, pfnThreadRtn, pszLibFileRemote, 0, NULL);
-
printf(«Error = %in», GetLastError());
-
WaitForSingleObject(hThread, INFINITE);
-
if (pszLibFileRemote != NULL)
-
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
Она работает на ХР 32, но отказывается на 7 х64. Проблема в CreateRemoteThread, ошибка ERROR_ACCESS_DENIED, пробовал с PROCESS_ALL_ACCESS — тоже самое, пробовал DEP отрубать — ничего не изменилось… в общем я склоняюсь к тому, что какая-то служба мешает… или какая-то фишка… помогите плз )
OS: Win 7 6.1.7600
-
Rel
Well-Known Member
- Публикаций:
-
2
- Регистрация:
- 11 дек 2008
- Сообщения:
- 4.896
для начала ответьте на вопросы: из какого процесса в какой? из x86 в x64 или из x64 в х64? не имеют ли процессы разный integrity level? установлены ли на машине какие-нить средства безопасности?
-
lobzik
New Member
- Публикаций:
-
0
- Регистрация:
- 9 апр 2009
- Сообщения:
- 34
Стоит КИС 2010, отрубал, так же.
У блокнота и инжектора «Обязательная меткаВысокий обязательный уровень» выставлен в integrity.
x86 -> x64 (если блокнот x64), да и из х86 -> х86 тоже не пашет (Где-то на XX странице гугла прочитал, что адрес ф-ии в моём и чужом пространстве может отличатся (http://www.gamedev.net/community/forums/topic.asp?topic_id=432792&whichpage=1�)
-
int (*load)(LPCWSTR lpLibFileName);
-
(FARPROC&) load = GetProcAddress(GetModuleHandle(TEXT(«Kernel32»)), «LoadLibraryW»);
-
pszLibFileRemote = (LPTHREAD_START_ROUTINE)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-
if ( !WriteProcessMemory(hProcess, pszLibFileRemote, InjectCode, 0x20, NULL) )
0х20 — под отладкой посмотрел, в любом случае код должен выполнятся и заканчиватся ошибкой в случае обрезки ф-ии. Но этого непроисходит — все та же ошибка ERROR_ACCESS_DENIED.
-
gorodon
New Member
- Публикаций:
-
0
- Регистрация:
- 19 окт 2009
- Сообщения:
- 301
Позволю себе процитировать (http://lhc645.wordpress.com/)
«Краткая справка. Механизм ASLR – Address Space Layout Randomization (случайное расположение в адресном пространстве) появился впервые в XP и затрагивал PEB и TEB only. Начиная с Vista сабж уже стал применяться к базам загрузки исполняемых файлов и длл (в частности системных ntdll, kernel32 etc), а также к стеку и куче.»
Вам надо определить расположение (базовый адрес загрузки) Kernel32 в целевом процессе, используя связку Module32First — Module32Next. -
Rel
Well-Known Member
- Публикаций:
-
2
- Регистрация:
- 11 дек 2008
- Сообщения:
- 4.896
можно ещё найти через PEB базовый адрес kernel32 и прибавить смещение функции от базового адреса (смещение найти в своем процессе)…
-
lhc645
New Member
- Публикаций:
-
0
- Регистрация:
- 9 авг 2009
- Сообщения:
- 106
Ага, учитывая, что в 32-битном процессе одна kernel32.dll (wow), а в 64-битном другая.
-
lobzik
New Member
- Публикаций:
-
0
- Регистрация:
- 9 апр 2009
- Сообщения:
- 34
Про ALSR слышал, посмотрите код, что выше, он должен ведь выполнятся в целевом процессе, вызывается GetProcAddress(), а потом LoadLibrary(), только стринги надо еще копировать ), а так код должен работать поидее, и не надо высчитывать разные смещения… или я что-то не так понял.
Но проблема немного в другом, проблема в том что CreateRemoteThread возвращает ERROR_ACCESS_DENIED, а CreateRemoteThreadEx которая появилась в 7-ке использовать не охото..
-
leo
Active Member
- Публикаций:
-
0
- Регистрация:
- 4 авг 2004
- Сообщения:
- 2.542
- Адрес:
- Russia
Применяться-то он стал, но только именно к (первой) загрузке dll в память, а не к маппингу уже загруженных dll в разные процессы по разным адресам (см.Inside… Руссиновича. Соотв-но базовые адреса сис. dll м.б. различны в разных сессиях, но в пределах одной сессии для всех процессов они по прежнему одинаковы (иначе бы это был пипец производительности из-за постоянных релоков).
Поэтому нельзя жестко прошивать адреса ф-й в проге, а определять их в своем процессе и юзать в другом — можно, пока…
PS:Да и потом, стоит ли «растекаться мыслью по древу», если в данном случае CreateRemoteThread валится с конкретной ошибкой ACCESS_DENIED, что недвысмысленно указывает на недостаток правпривелегий. Может для начала все необходимые права задать в OpenProcess, перечисленные в msdn для CreateRemoteThread ?
-
+Установка привилегии SeDebugPrivilege
-
Вот рабочий код:
-
#define _WIN32_WINNT 0x500
-
BOOL AdjustDebugPrivilege(void)
-
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
-
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
-
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
-
tp.Privileges[0].Luid = luid;
-
if (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL)
-
&& GetLastError() != ERROR_NOT_ALL_ASSIGNED)
-
DWORD GetProcessIdByName(LPCTSTR lpszProcessName)
-
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
-
PROCESSENTRY32 pe = {sizeof(PROCESSENTRY32)};
-
if (Process32First(hSnapshot, &pe))
-
if (_tcscmp(pe.szExeFile, lpszProcessName) == 0)
-
dwProcessId = pe.th32ProcessID;
-
} while (Process32Next(hSnapshot, &pe));
-
HMODULE RemoteLoadLibrary(DWORD dwProcessId, LPCTSTR lpszLibName)
-
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
-
LPVOID lpszRemoteLibName;
-
dwBytesToWrite = (_tcslen(lpszLibName)+1)*sizeof(TCHAR);
-
lpszRemoteLibName = VirtualAllocEx(hProcess, NULL, dwBytesToWrite, MEM_COMMIT, PAGE_READWRITE);
-
if (WriteProcessMemory(hProcess, lpszRemoteLibName, lpszLibName, dwBytesToWrite, &dwBytesWritten)
-
&& dwBytesWritten == dwBytesToWrite)
-
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, lpszRemoteLibName, 0, NULL);
-
if (WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0)
-
GetExitCodeThread(hThread, (LPDWORD)&hLib);
-
VirtualFreeEx(hProcess, lpszRemoteLibName, 0, MEM_RELEASE);
-
BOOL RemoteFreeLibrary(DWORD dwProcessId, HMODULE hLib)
-
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
-
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, hLib, 0, NULL);
-
if (WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0)
-
GetExitCodeThread(hThread, (LPDWORD)&bRet);
-
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpszCmdLine, int nCmdShow)
-
TCHAR szLibName[MAX_PATH];
-
dwProcessId = GetProcessIdByName(TEXT(«explorer.exe»));
-
GetModuleFileName(NULL, szLibName, MAX_PATH);
-
*_tcsrchr(szLibName, ‘\’) = »;
-
_tcscat_s(szLibName, MAX_PATH, __T(«\Hook.dll»));
-
hLib = RemoteLoadLibrary(dwProcessId, szLibName);
-
RemoteFreeLibrary(dwProcessId, hLib);
-
-
lobzik
New Member
- Публикаций:
-
0
- Регистрация:
- 9 апр 2009
- Сообщения:
- 34
KeSqueer, спасибо за код, но ошибка осталась(, у Вас на 7ке х64 работает ? какая сборка ?
-
lobzik
New Member
- Публикаций:
-
0
- Регистрация:
- 9 апр 2009
- Сообщения:
- 34
Запускаю от Админа само собой.
-
lobzik
На семерке не пробовал, на висте x64 работало, сейчас не могу проверить, т.к. вернул 32хбитную. -
lobzik
New Member
- Публикаций:
-
0
- Регистрация:
- 9 апр 2009
- Сообщения:
- 34
Все права и привилегии есть.
Ну не может же быть такого, что бы в 7ке CreateRemouteThread не работал совсем, как же тогда совместимость (которую я тоже кстати тыкал, эффекта не дало).
-
lobzik
Ваша функа это не чёрный ящик. Что в ней возвращает ошибку ?
Сервис какой и какой статус ?
Уже стопяцот раз говорил за неделю чтобы не юзали винапишные коды ошибок. Если у вас стек не выравнен, то я уж и не знаю тогда что сказать.. -
Clerk
Да вроде на С человек пишет, вряд ли.
ЗЫ
Почему бы не собрать статьи в пачку и не выложить на wasm.ru? Сложно искать их по всему форуму, indy-vx.narod.ru как там и написано, лог, а не сайт. -
KeSqueer
Так мб в 7’ке ссылка на TID не опциональный параметр. -
freeq
New Member
- Публикаций:
-
0
- Регистрация:
- 2 дек 2008
- Сообщения:
- 47
а вы уверены что процесс в который вы делайте инжект запущен в той же сессии что и вы?
нужно сравнивать еще и sessionid процесса со своим если юзайте такой инжект. -
Это очень вряд ли, как сказал Билли, обратная совместимость превыше всего.
Косяки в моем коде могуть быть с GetExitCodeThread который возвращает DWORD, а на x64 HMODULE — 64битная величина(?), но до этого момента всё вроде должно быть нормально… -
lobzik
New Member
- Публикаций:
-
0
- Регистрация:
- 9 апр 2009
- Сообщения:
- 34
Страница 1 из 2
CreateRemoteThread: access denied (w. debug privileges+PROCESS_ALL_ACCESS)
hi,
i’m currently trying to write a manual mapper using the windows api and CreateRemoteThread keeps failing even though accessing the remote process works for VirtualAllocEx/RPM/WPM …
i’m not too win api-experienced so i guess i’ve done some stupid beginner’s mistakes but can’t seem to find any of them myself right now …
here’s what i do in detail:
first getting debug privileges for my application (returns without errors):
Code:
bool acquireDebugPrivileges() { bool success = false; HANDLE hToken; TOKEN_PRIVILEGES tokenPriv; LUID luidDebug; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { if(LookupPrivilegeValue(L"", SE_DEBUG_NAME, &luidDebug)) { tokenPriv.PrivilegeCount = 1; tokenPriv.Privileges[0].Luid = luidDebug; tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL) == 0) { // error msg } else { success = true; } } else { error msg } } else { // error msg } return success; }
then getting the pid and opening the process (also returns non-NULL)
Code:
m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_pid);
// EDIT: the problem also persists when i’m using (PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | SYNCHRONIZE) instead of just PROCESS_ALL_ACCESS …
now VirtualAllocEx/VirtualFreeEx and RPM/WPM do work without errors (i’m always checking GetLastError()).
but when i execute
Code:
hThread = CreateRemoteThread(m_hProcess, NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(pThreadFunc), reinterpret_cast<LPVOID>(optParam), 0, NULL);
hThread is NULL and GetLasError() says «access denied».
did i make any obvious mistakes i don’t see right now? i feel pretty stupid with this …
thanks in advance for any advices!
I’m trying to write a program that uses CreateRemoteThread
to inject a dll.
The problem is that CreateRemoteThread is refusing to work. GetLastError() is returning 5 which is ERROR_ACCESS_DENIED. I cant figure why!
I am working from this video http://www.youtube.com/watch?v=H3O3hmXkt1I .
#include <iostream>
#include <direct.h>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;
char* GetCurrentDir()
{
char* szRet = (char*)malloc(MAX_PATH);
_getcwd(szRet, MAX_PATH);
return szRet;
}
LPCTSTR SzToLPCTSTR(char* szString)
{
LPTSTR lpszRet;
size_t size = strlen(szString)+1;
lpszRet = (LPTSTR)malloc(MAX_PATH);
mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE);
return lpszRet;
}
void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDelay)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
BOOL bAppeared = FALSE;
while(!bAppeared)
{
if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnap, &peProc))
while(Process32Next(hSnap, &peProc) && !bAppeared)
if(!lstrcmp(lpcszProc, peProc.szExeFile))
bAppeared = TRUE;
}
CloseHandle(hSnap);
Sleep(dwDelay);
}
}
DWORD GetProcessIdByName(LPCTSTR lpcszProc)
{
HANDLE hSnap;
PROCESSENTRY32 peProc;
DWORD dwRet = -1;
if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
peProc.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnap, &peProc))
while(Process32Next(hSnap, &peProc))
if(!lstrcmp(lpcszProc, peProc.szExeFile))
dwRet = peProc.th32ProcessID;
}
CloseHandle(hSnap);
return dwRet;
}
BOOL InjectDll(DWORD dwPid, char* szDllPath)
{
DWORD dwMemSize;
HANDLE hProc;
LPVOID lpRemoteMem, lpLoadLibrary;
BOOL bRet = FALSE;
if((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) != NULL)
{
dwMemSize = strlen(szDllPath);
if((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL)
if(WriteProcessMemory(hProc, lpRemoteMem, szDllPath, dwMemSize, NULL))
{
lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if(CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL)
{
bRet = TRUE;
}
cout << GetLastError();
}
}
CloseHandle(hProc);
return bRet;
}
int main()
{
char szProc[MAX_PATH], szDll[MAX_PATH];
char* szDllPath = (char*)malloc(MAX_PATH);
LPTSTR lpszProc = NULL;
for(;;)
{
cout << "Process: ";
cin >> szProc;
cout << "DLL: ";
cin >> szDll;
szDllPath = GetCurrentDir();
strcat_s(szDllPath, MAX_PATH, "\");
strcat_s(szDllPath, MAX_PATH, szDll);
cout << "Waiting for process.. ." << szDllPath << " " << szDll << endl;
WaitForProcessToAppear(SzToLPCTSTR(szProc), 100);
if(InjectDll(GetProcessIdByName(SzToLPCTSTR(szProc)), szDllPath))
cout << "Injection Succeeded!" << endl;
else
cout << "Injection Failed!" << endl;
cout << "n";
}
return 0;
After a fair amount of googling I cant find a reason why this should not be working.
Does CreateRemoteThread not work under Windows 7 ?
If it does, have I made any obvious mistakes ?
-
07-01-2015
#1
CreateRemoteThread — ERROR_ACCESS_DENIED
I think my code is finally working now. Only problem is that for some reason, even though I’ve opened the process with PROCESS_ALL_ACCESS, CreateRemoteThread throws back an error: ERROR_ACCESS_DENIED.
The error was retrieved with GetLastError() and it spit out ‘5’, which translates to ERROR_ACCESS_DENIED.
Code:
#include <iostream> #include <windows.h> #include <TlHelp32.h> char* dllPath = "C:\Users\Kalist\Desktop\Projects\DLL\bin\Debug\DLL.dll"; char* ProcToInject = "calc.exe"; int main(){ PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); HANDLE procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(procSnap == INVALID_HANDLE_VALUE){ std::cout << "Snapshot function failed" << std::endl; } DWORD procID = 0; if(Process32First(procSnap, &pe32)){ do{ if(!strcmp(pe32.szExeFile, ProcToInject)){ procID = pe32.th32ProcessID; break; } }while(Process32Next(procSnap, &pe32)); } CloseHandle(procSnap); if(procID != 0){ HANDLE procAccess = OpenProcess(PROCESS_ALL_ACCESS, false, procID); if(procAccess == NULL){ std::cout << "OpenProcess error: " << GetLastError() << std::endl; } LPVOID remoteString = (LPVOID)VirtualAllocEx(procAccess, NULL, strlen(dllPath)+1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if(remoteString == NULL){ std::cout << "VirtualAllocEx error: " << GetLastError() << std::endl; } bool memoryWritten = WriteProcessMemory(procAccess, (LPVOID)remoteString, dllPath, strlen(dllPath)+1, NULL); if(memoryWritten == 0){ std::cout << "WriteProcessMemory error: " << GetLastError() << std::endl; } LPVOID getLibAdd = (LPVOID)GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA"); if(getLibAdd == NULL){ std::cout << "GetProcAddress error: " << GetLastError() << std::endl; } HANDLE remoteThread = CreateRemoteThread(procAccess, NULL, 0, (LPTHREAD_START_ROUTINE)getLibAdd, (LPVOID)remoteString, 0, NULL); if(remoteThread == NULL){ std::cout << "CreateRemoteThread error: " << GetLastError() << std::endl; } CloseHandle(procAccess); }else{ std::cout << "Failed to retrieve procID" << std::endl; } }
-
07-01-2015
#2
It doesn’t work because your code is for x86 while by calculator (calc.exe) is x86_64 by default. Try it on some other process that has a *32 in task manager (x86 program) and it should work. Some evidence:
This is my code (thanks to Darawk) but before you try my code try yours on an x86 program:
Code:
#include <cstdio> #include <Windows.h> #include <TlHelp32.h> #include <string> using std::string; using std::wstring; #define PROCESS_NAME L"Swag.exe" #define MODULE_NAME "C:\Users\Swag\Desktop\Dll.dll" int wmain() { // Get a snapshot and then filter for getting // the Id of the process we want HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hSnapshot == INVALID_HANDLE_VALUE) { printf_s("Error: Could not get snapshot (Code: %i)n", GetLastError()); return S_FALSE; } // Iterate 'snapshotted' processes for the one // we want PROCESSENTRY32 pe32 = { }; pe32.dwSize = sizeof(PROCESSENTRY32); if(!Process32First(hSnapshot, &pe32)) { printf_s("Error: Process32First returned false (Code: %i)n", GetLastError()); CloseHandle(hSnapshot); return S_FALSE; } bool foundProcess = false; do { if(std::wstring(pe32.szExeFile) == PROCESS_NAME) { foundProcess = true; break; // Found the process we want } } while(Process32Next(hSnapshot, &pe32)); if(!foundProcess) { printf_s("Error: Failed to find process (Code: %i)n", GetLastError()); CloseHandle(hSnapshot); return S_FALSE; } // Get the Id of the process and use it // to inject the module into the process DWORD procId = pe32.th32ProcessID; HANDLE hProcess = OpenProcess(((PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)), FALSE, procId); if(hProcess == NULL) { printf_s("Error: Failed to open process (Code: %i)n", GetLastError()); CloseHandle(hSnapshot); return S_FALSE; } auto addrOfLoadLibrary = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA"); auto remoteAlloc = VirtualAllocEx(hProcess, NULL, strlen(MODULE_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if(WriteProcessMemory(hProcess, remoteAlloc, MODULE_NAME, strlen(MODULE_NAME), NULL) == 0) { printf_s("Error: Failed to write to process' memory (Code: %i)n", GetLastError()); CloseHandle(hProcess); CloseHandle(hSnapshot); return S_FALSE; } if(CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE) addrOfLoadLibrary, remoteAlloc, NULL, NULL) == NULL) { printf_s("Error: Failed to create remote thread (Code: %i)n", GetLastError()); CloseHandle(hProcess); CloseHandle(hSnapshot); return S_FALSE; } printf_s("Finished Successfully!n"); // Clean up a bit CloseHandle(hSnapshot); CloseHandle(hProcess); return S_OK; }
-
07-01-2015
#3
Try running as an administrator, or use RtlAdjustPrivilege and SeDebugPrivilege (this allows your process to even interfere with system’s process e.g csrss.exe)
Code:
NTSTATUS NTAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); //This is the prototype of the RtlAdjustPrivilege function. RtlAdjustPrivilege(20,TRUE,FALSE,&bl); //20 is the value of SeDebugPrivilege
LINK WITH NTDLL.LIB !
-
07-01-2015
#4
殺す必要がある唯一のものは殺されるために準備され人 々である。
Originally Posted by ZER0MEM0RY
Try running as an administrator, or use RtlAdjustPrivilege and SeDebugPrivilege (this allows your process to even interfere with system’s process e.g csrss.exe)
Code:
NTSTATUS NTAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); //This is the prototype of the RtlAdjustPrivilege function. RtlAdjustPrivilege(20,TRUE,FALSE,&bl); //20 is the value of SeDebugPrivilege
LINK WITH NTDLL.LIB !
Still won’t allow you to bypass the WoW64 barrier implemented in the system.
-
07-02-2015
#5
It works like a charm, I simply downloaded the MinGW64 compiler and implemented it into CodeBlocks. Now I can inject both 32bit and 64bit as I see fit.
-
07-02-2015
#6
Originally Posted by Kalist
It works like a charm, I simply downloaded the MinGW64 compiler and implemented it into CodeBlocks. Now I can inject both 32bit and 64bit as I see fit.
Were you using MSVC before? Try compiling again with MSVC but in 64-bit and try again.
Как я могу решить эту проблему? код работает нормально, так как я тестировал его на 32-битном компьютере, но мой 64-битный компьютер возвращает эту ошибку с помощью getlasterror ();
что я могу сделать, чтобы это исправить?
0
Решение
Частичная информация:
Когда я работал с CreateRemoteThread
на Win2000 все работало нормально, за исключением случаев, когда я запускал удаленные потоки в процессах, которые принадлежали к различным сеансам терминального сервера. На Win2003 (и вкл.) Все системные процессы работают в сеансе TS 0, который отличается от интерактивного сеанса, в который вы в данный момент вошли. В то время мне не удалось решить проблему границы сеанса TS. Это то, что вам может понадобиться проверить в первую очередь.
Скорее всего, это не проблема 32/64 бит, а какая-то проблема безопасности, требующая специальных привилегий и / или разрешений.
0
Другие решения
Я собираюсь предположить, что ваш целевой процесс — это управляемый исполняемый файл, скомпилированный для «Любого процессора» …
Если так, то когда вы запускаете этот exe-файл в 64-битной Windows, он JIT компилируется в 64-битный код и, таким образом, становится 64-битным процессом.
Затем вы не можете вызвать CreateRemoteThread для него из 32-разрядного процесса.
Тот же Managed exe, запущенный на 32-битной Windows, будет JIT к 32-битному коду, и, следовательно, будет работать.
Если это так, и вы являетесь автором рассматриваемого Managed exe, перестройте его для x86.
0