|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionRmThread is a project that I made based on one of three ideas from the Robert Kuster article, "Three Ways to Inject Your Code into Another Process". However, I didn't use any code. I wanted to learn about it, searched over the net, and got influenced by the The project is useful for someone who need to run some code in a neighbor process, but doesn't want to worry about remote thread technique development. He wants just to write the code to run remotely. The demo project, RmThread.exe, works precisely to do the dirty thing. You say what process to run and the DLL to load, and it starts the process and loads the DLL in the process context. The rest remains in the DLL code. To write your DLL, there's a demo project that uses a technique that I created to run some code starting from the Using the codeThere're three useful functions that could be called from your program: /** Run process and get rights for running remote threads. */ HANDLE CreateAndGetProcessGodHandle(LPCTSTR lpApplicationName, LPTSTR lpCommandLine); /** Load DLL in another process. */ HMODULE RemoteLoadLibrary(HANDLE hProcess, LPCTSTR lpFileName); /** Free DLL in another process. */ BOOL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule); Here's a simplified main routine showing how simple it is to use the functions: //... // Start process and get handle with powers. hProc = CreateAndGetProcessGodHandle(tzProgPath, tzProgArgs); if( hProc != NULL ) { // Load DLL in the create process context. HMODULE hDll = RemoteLoadLibrary(hProc, tzDllPath); if( hDll != NULL ) RemoteFreeLibrary(hProc, hDll); CloseHandle(hProc); } //... The most complicated thing maybe what to do when your DLL is loaded. Considering that when it is called in your entry point, the DLL code has to follow some boring rules to avoid boring things like access violations (for more, read the BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call, LPVOID lpReserved) {
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
{
DWORD dwThrId;
// Fill global variable with handle copy of this thread.
BOOL bRes =
DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
&g_hThrDllMain,
0,
FALSE,
0);
if( bRes == FALSE ) break;
// Call function that do the useful stuff with its DLL handle.
CloseHandle(CreateThread(NULL,
0,
RmThread,
(LPVOID) LoadLibrary(g_tzModuleName),
0,
&dwThrId));
}
break;
//...
The tasks for our newly created thread, by its turn are, to wait for the /** * Sample function, called remotely for RmThread.exe. */ DWORD WINAPI RmThread(LPVOID lpParameter) { HMODULE hDll = (HMODULE) lpParameter; LPCTSTR ptzMsg = _T("Congratulations! Did you call RmThread.dll successfully!"); // Wait DllMain termination. WaitForSingleObject(g_hThrDllMain, INFINITE); //TODO: Put your remote code here. MessageBox(NULL, ptzMsg, g_tzModuleName, MB_OK | MB_ICONINFORMATION); // Do what the function name says. FreeLibraryAndExitThread(hDll, 0); } The TODO mark is where your code must be written (you can pull out the An interesting detail is the requirement to call Points of InterestA boring problem that you can find is: if the DLL couldn't be loaded successfully, how can I get the error code? Unfortunately, there's no trivial way to get the error code returned from History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||