/**
** tishion#163.com
** 2016-01-28 18:52:34
**/
PLDR_DATA_TABLE_ENTRY GetModuleEntryInLoadOrderModuleList(HMODULE hMod)
{
PPEB pPeb = NULL;
// Get the base address of PEB struct
__asm
{
push eax
mov eax, fs:[0x30]
mov pPeb, eax
pop eax
}
// Get pointer value of PEB_LDR_DATA
PPEB_LDR_DATA pLdr = pPeb->Ldr;
// And get header of the InLoadOrderModuleList
PLIST_ENTRY pHeaderOfModuleList = &(pLdr->InLoadOrderModuleList);
if (pHeaderOfModuleList->Flink == pHeaderOfModuleList)
{
// Something was wrong
return NULL;
}
PLDR_DATA_TABLE_ENTRY pEntry = NULL;
PLIST_ENTRY pCur = pHeaderOfModuleList->Flink;
// Find Entry of the fake module
do
{
pEntry = CONTAINING_RECORD(pCur, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
// Ok, got it
if (pEntry->BaseAddress == hMod)
{
break;
}
pEntry = NULL;
pCur = pCur->Flink;
} while (pCur != pHeaderOfModuleList);
return pEntry;
}
/**
** Replace the return value of LoadLibrary
**
**/
BOOL LoadFogModule(HMODULE hModule, LPCTSTR pOrigiModPath)
{
// First, we must get the Entry of the fake module
PLDR_DATA_TABLE_ENTRY pEntryOfFakeMod = GetModuleEntryInLoadOrderModuleList(hModule);
// Then, load the original module
HMODULE hOrigiMod = ::LoadLibrary(pOrigiModPath);
if (NULL != pEntryOfFakeMod && NULL != hOrigiMod)
{
// Now we need to find the Entry of the original module
PLDR_DATA_TABLE_ENTRY pEntryOfOrigiMod = GetModuleEntryInLoadOrderModuleList(hOrigiMod);
/*
* Tish is the key statement which will replace the return value of LoadLibrary.
* At the end of LoadLibrary, it will return the base address which get from the entry of fake module.
* And then the process will import all the functions and variables it needs according to the base address.
* Because we have replaced the address with the base address of real original module,
* so it will work well, that is to say the process can get all valid imported functions and variables
* from the original module.
*/
pEntryOfFakeMod->BaseAddress = pEntryOfOrigiMod->BaseAddress;
// Then we must remove the fake module entry from all the module list, or it will lead the process crash
// remove it from InLoadOrderModuleList
pEntryOfFakeMod->InLoadOrderModuleList.Blink->Flink = pEntryOfFakeMod->InLoadOrderModuleList.Flink;
pEntryOfFakeMod->InLoadOrderModuleList.Flink->Blink = pEntryOfFakeMod->InLoadOrderModuleList.Blink;
// remove it from InInitializationOrderModuleList
pEntryOfFakeMod->InInitializationOrderModuleList.Blink->Flink = pEntryOfFakeMod->InInitializationOrderModuleList.Flink;
pEntryOfFakeMod->InInitializationOrderModuleList.Flink->Blink = pEntryOfFakeMod->InInitializationOrderModuleList.Blink;
// remove it from InMemoryOrderModuleList
pEntryOfFakeMod->InMemoryOrderModuleList.Blink->Flink = pEntryOfFakeMod->InMemoryOrderModuleList.Flink;
pEntryOfFakeMod->InMemoryOrderModuleList.Flink->Blink = pEntryOfFakeMod->InMemoryOrderModuleList.Blink;
return TRUE;
}
return FALSE;