Внедрил свою ДЛЛ в другой процесс. Имеем код (ДЛЛ): Код (Text): BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID _Reserved) { switch(dwReason) { case DLL_PROCESS_ATTACH:{ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ServerThread, NULL, 0, &st_id); return true; } case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; }//end switch(dwReason) return true; } Процесс 100% аттаччится. Т.к. если во входной в ДЛЛ ф-ции прописать скажем MessageBox(...), то он запускается от имени процесса в который внедрились. Внимание вопрос: почему я не могу создать дочерний поток (CreateThread(...))? Ошибок никаких нет, но поток не запускается! Помогите плз найти решение проблемы. Благодарен! --zeromemory
Приведи код потока, а то картина не полная. Ты уверен что поток 100% не создается? Попробуй вставить в код потока мессадж бокс, проверь код возврата CreateThread!
2 liss Да, уверен. Вставлял МессаджБакс в код потока - не выполняется. CreateThread возвращает корректное значение (т.е. не NULL). Код потока: Код (Text): DWORD WINAPI ServerThread(PVOID param){ SOCKET hServerSocket, hClientSocket; struct sockaddr_in serv_sin; //DWORD dwCliThreadId; WORD port; Sleep(10); port = 9876; MessageBox(0, "in the server thread", "", MB_OK); // create TCP socket hServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (hServerSocket == INVALID_SOCKET){ CreateThread(NULL, 0, ServerThread, NULL, 0, &st_id); TerminateThread(GetCurrentThread(), 0); } // fill out local addr struct serv_sin.sin_family = AF_INET; serv_sin.sin_port = htons(port); serv_sin.sin_addr.s_addr = htonl(INADDR_ANY); __memset(&serv_sin.sin_zero, 0, sizeof(serv_sin.sin_zero)); // bind local addr and listen for connections if (bind(hServerSocket, (struct sockaddr*)&serv_sin, sizeof(serv_sin)) == SOCKET_ERROR){ CreateThread(NULL, 0, ServerThread, NULL, 0, &st_id); TerminateThread(GetCurrentThread(), 0); } if (listen(hServerSocket, SOMAXCONN) == SOCKET_ERROR){ CreateThread(NULL, 0, ServerThread, NULL, 0, &st_id); TerminateThread(GetCurrentThread(), 0); } CreateThread(NULL, 0, StatsThread, (PVOID)port, 0, &st_id); // wait for connection from anybody while (1){ hClientSocket = accept(hServerSocket, NULL, NULL); if (hClientSocket == INVALID_SOCKET){ Sleep(1000); continue; }else{ CreateThread(NULL, 0, ClientThread, (PVOID)hClientSocket, 0, &st_id); } } return 0; }
Если даже локально не запускает тред, то проблема 100% не в моем коде внедрения в процесс! Что же это может быть и как этот трабл решить? Если " entry-point function should perform only simple initialization" не позволяет стартануть тред, то как запустить тред вне входной ф-ции? Помогите плз - крайне важно!
Ok. Понял что нельзя вызывать CreateThread в инициализаторе... В таком случае откуда я должен вызвать ее? Необходимо создавать потоки, и я не верю что это вообще невозможно в ДЛЛ! Возникла мысль с инициализатора послать мое сообщение оконной ф-ции, и перехаватить его в ней же.. И уже оттуда вызвать CreateThread.. Но это как-то не красиво, по ламерски.. Да и возможно работать не будет.. Может кто-нить занет более красивый способ запуска дочерних потоков из ДЛЛ? Спасибо.
Фуфффф.... Пробела решена!! Геморр еще тот - но все заставил работать!! Заюзал WaitForSingleObject(). Всем спасибо!
ZeroMemory У меня нормально Thread создаётся и MessageBox показывается. Код (Text): .486 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc includelib kernel32.lib includelib user32.lib ThreadProc PROTO :DWORD .DATA szOk db "Ok",0 .DATA? ThreadID dd ? .CODE ALIGN DWORD DllEntry proc hInst:DWORD, reason:DWORD, reserved1:DWORD .IF reason == DLL_PROCESS_ATTACH ; When the dll is loaded invoke CreateThread, NULL, 0, OFFSET ThreadProc, NULL, 0, OFFSET ThreadID invoke CloseHandle, eax .ENDIF xor eax, eax inc eax ret DllEntry Endp ThreadProc proc Param:DWORD invoke MessageBox, 0, OFFSET szOk, 0, MB_OK or MB_ICONERROR ret ThreadProc endp End DllEntry
а как DLL грузится в процесс ? если внедряется код-агент, который уже загружает DLL штатным способом, то можно в этом коде вызывать отдельную ф-цию для иинциализации DLL.
Все таки как была решена эта проблема? У меня аналогичная! Function L: DWord; Begin MessageBoxA(0, 'bla bla', '23', 0); end; Case Reason Of DLL_PROCESS_ATTACH: begin hThread := CreateThread(nil, 0, @L, nil, 0, lpThreadId); If (hThread <> 0) Then WaitForSingleObject(hThread,INFINITE); Мессадж не показывается!!!
Дык тред не создается в ф-ции инициализации (во всяком случае в среде VC++6)! Делай так: Код (Text): DWORD WINAPI BeginThread(LPVOID lpParameter) { MSG msg; WSADATA wsa; HMODULE hDll = (HMODULE) lpParameter; WaitForSingleObject(g_hThrDllMain, INFINITE); // begin my stuff // вот тут уже можем запускать потоки CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ServerThread, NULL, 0, &st_id); while (GetMessage(&msg, NULL, 0, 0)){ TranslateMessage(&msg); DispatchMessage(&msg); } WSACleanup(); // Do what the function name says. FreeLibraryAndExitThread(hDll, 0); return 0; } BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID _Reserved) { switch(dwReason) { case DLL_PROCESS_ATTACH:{ DWORD dwThrId; BOOL bRes = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &g_hThrDllMain, 0, FALSE, 0); if( bRes == FALSE ) break; CloseHandle(CreateThread(NULL, 0, BeginThread, (LPVOID) LoadLibrary(g_tzModuleName), 0, &dwThrId)); return true; } case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; }//end switch(dwReason) return true; } --zeromemory
to ZeroMemory Если тред не создается в функции инициализации, то как выше приведенный код будет работать? Ведь функция BeginThread никогда не запуститься, т.к. тред не создался.
Обрати внимание на ф-цию DuplicateHandle(). И если не веришь - просто скомпиль этот код и увидешь что все работает на ура. А если сразу CreateThread() - то ничего не прокатит...
Я верю что все работает. На моей памяти небыло еще такого чтобы треды при инициализации DLL не создавались. Вот такой код у меня работает. DWORD ThreadId; HANDLE hThread; int ThreadProc(int Param); BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { if(ul_reason_for_call==DLL_PROCESS_ATTACH){ hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,0,&ThreadId); }; return TRUE; }; int ThreadProc(int Param){ MessageBox(0,"Hey man I'm sarted","New thread",MB_OK); return 0; };