#include <windows.h>
#include <stdlib.h>
#include <conio.h>
int DoHook(int pid, bool UnHook, HMODULE hFreeModule)
{
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, // Specifies all possible access flags
FALSE,
pid);
if (hProcess == NULL)
return 0;
char szLibFile[MAX_PATH] = "C:\\work\\vc6\\SharedModule\\Debug\\sharedmodule.dll";
int cch = 1 + strlen(szLibFile);
PSTR pszLibFileRemote = (PSTR)::VirtualAllocEx(hProcess, NULL, cch, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL)
{
printf("pszLibFileRemote was NULL");
return 0;
}
if (!::WriteProcessMemory(hProcess, (PVOID)pszLibFileRemote, (PVOID)szLibFile, cch, NULL))
{
printf("\nWriteProcessMemory Failed");
return 0;
}
PTHREAD_START_ROUTINE pfnThreadRtn = NULL;
if(UnHook)
pfnThreadRtn = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle("Kernel32"), "FreeLibrary");
else
pfnThreadRtn = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle("Kernel32"), "LoadLibraryA");
if (pfnThreadRtn == NULL)
{
printf("\nGetProcAddress Failed");
return 0;
}
HANDLE hThread;
if(UnHook)
hThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, (HMODULE)hFreeModule, 0, NULL);
else
hThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, (PVOID)pszLibFileRemote, 0, NULL);
if (hThread == NULL)
{
printf("\nCreateRemoteThread Failed");
return 0;
}
::WaitForSingleObject(hThread, INFINITE);
if (pszLibFileRemote != NULL)
::VirtualFreeEx(hProcess, (PVOID)pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
::CloseHandle(hThread);
if (hProcess != NULL)
::CloseHandle(hProcess);
return 1;
}
// We will require this function to get a module handle of our
// original module
HMODULE EnumModules(int pid, char szLibFile[MAX_PATH])
{
HMODULE hMods[1024];
DWORD cbNeeded;
unsigned int i;
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, // Specifies all possible access flags
FALSE,
pid);
if (hProcess == NULL)
return 0;
HMODULE m_hModPSAPI = ::LoadLibraryA("PSAPI.DLL");
typedef BOOL (WINAPI * PFNENUMPROCESSMODULES)
(
HANDLE hProcess,
HMODULE *lphModule,
DWORD cb,
LPDWORD lpcbNeeded
);
typedef DWORD (WINAPI * PFNGETMODULEFILENAMEEXA)
(
HANDLE hProcess,
HMODULE hModule,
LPSTR lpFilename,
DWORD nSize
);
PFNENUMPROCESSMODULES m_pfnEnumProcessModules;
PFNGETMODULEFILENAMEEXA m_pfnGetModuleFileNameExA;
m_pfnEnumProcessModules = (PFNENUMPROCESSMODULES)::GetProcAddress(m_hModPSAPI, "EnumProcessModules");
m_pfnGetModuleFileNameExA = (PFNGETMODULEFILENAMEEXA)::GetProcAddress(m_hModPSAPI, "GetModuleFileNameExA");
if( m_pfnEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
char szModName[MAX_PATH];
// Get the full path to the module's file.
if ( m_pfnGetModuleFileNameExA( hProcess, hMods[i], szModName, sizeof(szModName)))
{
// Print the module name and handle value.
printf("\t%s (0x%08X)\n", szModName, hMods[i] );
if(strcmp(szModName, szLibFile) == 0)
{
::FreeLibrary(m_hModPSAPI);
return hMods[i];
}
}
}
}
if (hProcess != NULL)
::CloseHandle(hProcess);
return 0;
}
int main(int argc, char* argv[])
{
int pid = atol(argv[1]);
HMODULE hModule;
DoHook(pid, false, 0);
hModule = EnumModules(pid,"C:\\work\\vc6\\SharedModule\\Debug\\sharedmodule.dll");
getch();
if(0 != hModule)
DoHook(pid, true, hModule);
printf("\n");
EnumModules(pid,"C:\\Parag\\pidwatcher\\Debug\\sharedmodule.dll");
return 0;
}