C++ to PB. Headaches, white nights, etc..
Posted: Mon Jul 10, 2006 1:47 pm
Hi! I found this code that help creating global API hooks without entering ring0 with a vxd and it seems pretty cool. Unfortunately it is in C++ and I can't manage to translate it
. 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
DLL module:
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;
}