BOOL __declspec(dllexport) RemoteFreeLibraryNT(DWORD dwTargetProcessID, HMODULE hModule) { if (!IsWindowsNT()) { ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } LPTHREAD_START_ROUTINE lpfn = (LPTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "FreeLibrary"); if (lpfn == NULL) return FALSE; HANDLE hRemoteProc = OpenProcessForRemoteExecute(dwTargetProcessID); if (hRemoteProc == NULL) return FALSE; DWORD dwExitCode = 0; DWORD dwErrorCode = ERROR_SUCCESS; BOOL bOK = RemoteExecute(hRemoteProc, lpfn, (LPVOID)hModule, dwExitCode, dwErrorCode); ::CloseHandle(hRemoteProc); if (!bOK) { ::SetLastError(dwErrorCode); return FALSE; } if (dwExitCode == 0) { ::SetLastError(ERROR_MOD_NOT_FOUND); return FALSE; } return TRUE; }
HMODULE __declspec(dllexport) RemoteLoadLibraryNTA(DWORD dwTargetProcessID, LPCSTR lpszDllPath) { if (lpszDllPath == NULL || lpszDllPath[0] == 0) { ::SetLastError(ERROR_MOD_NOT_FOUND); return NULL; } if (!IsWindowsNT()) { ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return NULL; } LPTHREAD_START_ROUTINE lpfn = (LPTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); if (lpfn == NULL) return NULL; DWORD dwExitCode = 0; DWORD dwErrorCode = ERROR_SUCCESS; BOOL bOK = RemoteExecute(dwTargetProcessID, lpfn, (LPCVOID)lpszDllPath, (::strlen(lpszDllPath) + 1) * sizeof(char), dwExitCode, dwErrorCode); if (!bOK) { ::SetLastError(dwErrorCode); return NULL; } if (dwExitCode == 0) { ::SetLastError(ERROR_FILE_NOT_FOUND); return NULL; } return (HMODULE)dwExitCode; }
// this function can give us the command line of any specified 32bit process void GetProcessCmdLine(HANDLE hProcess, LPTSTR pBuffer) { DWORD dummy; // we simply execute "GetCmdLineThread" in the context of the target process // if it succeeds, "pBuffer" will contain the command line if (!RemoteExecute(hProcess, (PREMOTE_EXECUTE_ROUTINE) &RemoteGetCmdLine, &dummy, pBuffer, MAX_PATH)) // if it didn't work we clean the result string pBuffer[0] = 0; }
BOOL RemoteExecute(DWORD dwRemoteProcID, LPTHREAD_START_ROUTINE lpfn, LPCVOID lpszParamString, DWORD dwLen, DWORD& rExitCode, DWORD& rErrorCode) { rExitCode = 0; rErrorCode = ERROR_SUCCESS; if (lpfn == NULL) { rErrorCode = ERROR_INVALID_PARAMETER; return FALSE; } HANDLE hRemoteProc = OpenProcessForRemoteExecute(dwRemoteProcID); if (hRemoteProc == NULL) { rErrorCode = ::GetLastError(); return FALSE; } BOOL bOK = TRUE; LPVOID lpParam = NULL; if (lpszParamString && dwLen) { lpParam = ::VirtualAllocEx(hRemoteProc, NULL, dwLen, MEM_COMMIT, PAGE_READWRITE); if (lpParam == NULL) { rErrorCode = ::GetLastError(); ::CloseHandle(hRemoteProc); return FALSE; } bOK = WriteProcessBytes(hRemoteProc, lpParam, lpszParamString, dwLen); } if (bOK) bOK = RemoteExecute(hRemoteProc, lpfn, lpParam, rExitCode, rErrorCode); else rErrorCode = ::GetLastError(); if (lpszParamString) { ::VirtualFreeEx(hRemoteProc, lpParam, 0, MEM_RELEASE); ::CloseHandle(hRemoteProc); } return bOK; }
HMODULE __declspec(dllexport) RemoteGetModuleHandleNTW(DWORD dwTargetProcessID, LPCWSTR lpszDllPath) { if (g_kernel32.GetModuleHandleW == NULL) { ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return NULL; } if (lpszDllPath && lpszDllPath[0] == 0) { ::SetLastError(ERROR_MOD_NOT_FOUND); return NULL; } if (!IsWindowsNT()) { ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return NULL; } DWORD dwExitCode = 0; DWORD dwErrorCode = ERROR_SUCCESS; BOOL bOK = RemoteExecute(dwTargetProcessID, (LPTHREAD_START_ROUTINE)g_kernel32.GetModuleHandleW, (LPCVOID)lpszDllPath, lpszDllPath ? (::wcslen(lpszDllPath) + 1) * sizeof(wchar_t) : 0, dwExitCode, dwErrorCode); if (!bOK) { ::SetLastError(dwErrorCode); return NULL; } if (dwExitCode == 0) { ::SetLastError(ERROR_FILE_NOT_FOUND); return NULL; } return (HMODULE)dwExitCode; }