Заметил любопытную вещь - при создании потока в удалённом процессе и внедрении в него кода сам процес приостанавливается и ждёт завершения работы вновь созданного потока. Почему так происходит ведь это должен быть отдельный поток? Как это можно обойти?
C чего это ты взял, что он останавливается? Если ты сам не остановишь все треды, то они будут работать, но при создании нового в планирование будет включен ещё один поток.
Это может произойти тока если ты открываешь процесс отладчиком... А простой VirtualAllocEx, WriteProcessMemory, CreateRemoteThread такого эффекта не дают.
Угу... я тоже так думаю (код чуть ли не по Рихтеру весь)... но получилось всё несколько иначе Во внедряемой dll в функции DllMain стоит просто запуск ShowMessage c одной кнопкой OK. При внедрении в процес Explorer'а несмотря на установленный низкий приоритет вновь создаваемого потока, пока не нажмёшь на кнопку ОК Explorer просто подвисает.
Вот код DLL: Код (Text): #include <vcl.h> #include <windows.h> #include "psapi.h" #pragma hdrstop #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) {char s[40]; char szProcessName[MAX_PATH] = "unknown"; int res = 0; if(reason == DLL_THREAD_ATTACH) {// Get a handle to the process. HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); // Get the process name. if (NULL != hProcess ) { HMODULE hMod; DWORD cbNeeded; if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); } else return 0; } else return 0; CloseHandle( hProcess ); strcpy(s, "Ïðîèçâåäåíà èíêàïñóëÿöèÿ â ïðîöåññ "); strcat(s, szProcessName); MessageBox(NULL, s, "Èíêàïñóëÿöèÿ", MB_OK); } return 1; } Инжекция по Рихтеру. Сам никак понять не могу в чём дело.
Дело не в CreateRemoteThread, а в LoadLibrary. Например, пока она работает, GetModuleHandle, вызванная в другом потоке, будет висеть и ждать её завершения.
Ты прав, конечно, но при чем тут весь процесс процесс??? Просто LoadLibrary не вернется, пока DllMain не вернет что-нибудь. А т.к. она вызывается в отдельном треде, то зависнуть должен только тред, а не весь процесс. Кроме того даже в этом случае зависание имхо должно произойти только при первом вызове DllMain, т.е. когда reason = DLL_PROCESS_ATTACH, а код обрабатывает DLL_THREAD_ATTACH. Осталось посмотреть, не подвели ли звезды А если серъезно, отладчик в зубы и веперед - больше ниче не могу посоветовать. Посмотри, может где-то рекурсия вызывается, может ты какие-то не те параметры где-то передаешь. Попробуй внедрить код в другой процес...
А весь процесс и не виснет. Виснут только те потоки, которые ждут окончания LoadLibrary, ну и те, которые ждут тех, которые повисли ). А THREAD_ или PROSESS_ATTACH влияет только на то, когда зависнет: сразу при подгрузке длл или при создании очередного потока.
2MSoft Пробовал внедрять в другие процессы - результат тот же. Попробовал переиграть ситуацию следующим образом: Код (Text): #include <vcl.h> #include <windows.h> #include "psapi.h" #pragma hdrstop #pragma argsused VOID CALLBACK _export TimerProc( HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime // current system time ) { char s[40]; char szProcessName[MAX_PATH] = "unknown"; int res = 0; KillTimer(NULL, idEvent); HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); // Get the process name. if (NULL != hProcess ) { HMODULE hMod; DWORD cbNeeded; if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); } else return; } else return; CloseHandle( hProcess ); strcpy(s, "Ïðîèçâåäåíà èíêàïñóëÿöèÿ â ïðîöåññ "); strcat(s, szProcessName); MessageBox(NULL, s, "Èíêàïñóëÿöèÿ", MB_OK); } int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { if(reason == DLL_PROCESS_ATTACH)//(reason == DLL_THREAD_ATTACH) { if(!SetTimer(NULL, 0, 10000, (TIMERPROC)TimerProc)) MessageBox(NULL, "Íå ìîãó ñîçäàòü òàéìåð.", "Èíêàïñóëÿöèÿ", MB_OK); MessageBox(NULL, "DLL_PROCESS_ATTACH", "Èíêàïñóëÿöèÿ", MB_OK); } return 1; } результат тотже, правда не понятно почему функция таймера вызывается только в том случае, если DllMain ещё не завершилась (специально туда MessageBox сунул)... иначе ничего не происходит. Каким образом можно ещё переиграть? Может имеет смысл попытаться после загрузки Dll через CreateRemoteThread вызвать через него же нужную функцию в этой dll? Правда тогда надо будет каким-то образом вычислить её адрес в новом процессе. Если да, то как?
запиши в память машинные коды вызова LoadLibrary, и создавай поток на них а после вызова поставь джамп на нужную функцию, ее адрес заполнишь прямо их DllMain единственный вопрос - как в DllMain узнать, где находится твой код
Aivengo Создай в DllMain свои потоки, которые будут делать, что нужно. Они выполнятся после выхода из DllMain. типа такого: Код (Text): #include "stdafx.h" #include <windows.h> #include "psapi.h" DWORD WINAPI thread_proc(LPVOID x) { char s[40]; char szProcessName[MAX_PATH] = "unknown"; int res = 0; HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); // Get the process name. if (NULL != hProcess ) { HMODULE hMod; DWORD cbNeeded; if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); } else return 1; } else return 1; CloseHandle( hProcess ); strcpy(s, "opened process "); strcat(s, szProcessName); MessageBox(NULL, s, "Messagebox", MB_OK); return 0; } int WINAPI DllMain(HINSTANCE hinst, unsigned long reason, void* lpReserved) { if(reason == DLL_PROCESS_ATTACH) { // Get a handle to the process. DWORD tid; HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_proc, NULL,0,&tid); if (hThread == NULL) return 0; CloseHandle (hThread); } return 1; }
MSoft А что значит "процесс приостанавливается"? Это значит, приостанавливаются его потоки. Либо все, либо те, которые создают видимость его работы. Если все потоки друг с другом как-то синхронизируются, то при зависании одного потока запросто может повиснуть и другой, и т.д. Вот пример процесса с 2-мя потоками. Внедрите в него длл с масаджбоксом в DllMain на PROCESS_ATTACH, и посмотрите, что будет Код (Text): #include <windows.h> #include <stdio.h> DWORD WINAPI thr1(LPVOID x) { int i=0; while (i<100) { Sleep(2000); GetModuleHandle("kernel32.dll"); printf("Thread1: Got module handle %X\n",i); i++; } return 0; } DWORD WINAPI thr2(LPVOID x) { int i=0; while (i<100) { Sleep(2000); printf("Thread2: Got module handle %X\n",i); i++; } return 0; } int main(int argc, char* argv[]) { DWORD tid1,tid2; HANDLE hThr1, hThr2; hThr1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thr1, 0, 0, &tid1); hThr2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thr2, 0, 0, &tid2); WaitForSingleObject(hThr1,500000); WaitForSingleObject(hThr2,500000); return 0; } Можно и не внедрять, а просто дописать создание третьего потока, в котором сделать LoadLibrary дллки с месаджбоксом. CreateRemoteThread тут ни при чём.
Думаю, было бы криво, если бы она работала не так Просто нечего в DllMain 2 часа просто так висеть при загрузке либы )