 . Any help is much appreciated. It has 2 parts: an injector (app) and a dll. The code is not big (~4 kb each).
. Any help is much appreciated. It has 2 parts: an injector (app) and a dll. The code is not big (~4 kb each). Oh, and what does "->" means in C++? I can't find any replacement in PB...
The injector
Code: Select all
#include <windows>
#include <stdlib>
#include <conio>
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;
}
Code: Select all
#include <stdio>
#include <imagehlp>
#include <stdlib>
HANDLE g_hModule = INVALID_HANDLE_VALUE;
PROC g_OriginalCopyFileW;
typedef BOOL WINAPI MyCopyFileW_t
(
	LPCWSTR lpExistingFileName,
	LPCWSTR lpNewFileName,
	BOOL bFailIfExists
);
BOOL WINAPI MyCopyFileW(LPCWSTR lpExistingFileName,	LPCWSTR lpNewFileName, BOOL bFailIfExists)
{
	BOOL ReturnValue;
	
	MyCopyFileW_t* fn = (MyCopyFileW_t*)g_OriginalCopyFileW;
	
	ReturnValue = (*fn)(lpExistingFileName, lpNewFileName, bFailIfExists);
	return ReturnValue;
}
void SetHook(HMODULE hModuleOfCaller, LPSTR LibraryName, PROC OldFunctionPointer, PROC NewFunctionPointer)
{
	if(hModuleOfCaller == g_hModule)
		return;
	if(hModuleOfCaller == 0)
		return;
	ULONG ulSize;
	// Get the address of the module’s import section
	PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData
	(
		hModuleOfCaller, 
		TRUE, 
		IMAGE_DIRECTORY_ENTRY_IMPORT, 
		&ulSize
	);
	// Does this module have an import section ?
	if (pImportDesc == NULL)
		return;
	// Loop through all descriptors and find the 
	// import descriptor containing references to callee’s functions
	while (pImportDesc->Name)
	{
		PSTR pszModName = (PSTR)((PBYTE) hModuleOfCaller + pImportDesc->Name);
		
		if (stricmp(pszModName, LibraryName) == 0) 
			break; // Found
		pImportDesc++;
	} // while
	if (pImportDesc->Name == 0)
		return;
	//Get caller’s IAT 
	PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)( (PBYTE) hModuleOfCaller + pImportDesc->FirstThunk );
	PROC pfnCurrent = OldFunctionPointer;
	// Replace current function address with new one
	while (pThunk->u1.Function)
	{
		// Get the address of the function address
		PROC* ppfn = (PROC*) &pThunk->u1.Function;
		// Is this the function we’re looking for?
		BOOL bFound = (*ppfn == pfnCurrent);
		if (bFound) 
		{
			MEMORY_BASIC_INFORMATION mbi;
			
			::VirtualQuery(ppfn, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
			// In order to provide writable access to this part of the 
			// memory we need to change the memory protection
			if (FALSE == ::VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_READWRITE,&mbi.Protect))
				return;
			*ppfn = *NewFunctionPointer;
			BOOL bResult = TRUE;
			// Restore the protection back
			DWORD dwOldProtect;
			::VirtualProtect(mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&dwOldProtect);
			
			break;
		} // if
		pThunk++;
	} // while
}
PROC EnumAndSetHooks(LPSTR BaseLibraryName, LPSTR BaseFunctionName, PROC NewFunctionPointer, bool UnHook, PROC Custom)
{
	HMODULE hMods[1024];
	DWORD cbNeeded;
	unsigned int i;
	typedef BOOL (WINAPI * PFNENUMPROCESSMODULES)
	(
		HANDLE hProcess,
		HMODULE *lphModule,
		DWORD cb,
		LPDWORD lpcbNeeded
	);
	HMODULE hBaseLib = LoadLibrary(BaseLibraryName);
	PROC hBaseProc;
	if(UnHook)
		hBaseProc = (PROC) Custom;
	else
		hBaseProc = GetProcAddress(hBaseLib, BaseFunctionName);
	PFNENUMPROCESSMODULES m_pfnEnumProcessModules;
	HMODULE m_hModPSAPI = ::LoadLibraryA("PSAPI.DLL");
	m_pfnEnumProcessModules = (PFNENUMPROCESSMODULES)::GetProcAddress(m_hModPSAPI, "EnumProcessModules");
	HANDLE hProcess = ::GetCurrentProcess();
	if( m_pfnEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
	{
		for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
		{
			SetHook(hMods[i], BaseLibraryName, hBaseProc, NewFunctionPointer); 
		}
	}
	return hBaseProc;
}
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			g_hModule = hModule;
			
			g_OriginalCopyFileW = EnumAndSetHooks("KERNEL32.DLL", "CopyFileW", (PROC) MyCopyFileW, false, 0);
				
			break;
		case DLL_PROCESS_DETACH:
			EnumAndSetHooks("KERNEL32.DLL", "CopyFileW", (PROC) GetProcAddress(LoadLibrary("KERNEL32"),"CopyFileW"), true, (PROC) MyCopyFileW);
			break;
	}
	return TRUE;
}

 . I didn't have any problems until now, and I hope I'll never have
. I didn't have any problems until now, and I hope I'll never have  . But a bugfix version would be cool (one with SendNetworkFile with callback and buffered transfer
. But a bugfix version would be cool (one with SendNetworkFile with callback and buffered transfer 

