めいくりぷとのブログ

技術的なことやゲームのことやら・・・

マニュアルマッピングされたモジュールをマニュアルリンクする。

_Success_(return != NULL)
PTEB 
WINAPI 
GetThreadEnvironmentBlock(
	)
{
#ifdef _WIN64
	return reinterpret_cast<PTEB>(__readgsqword(0x00000030));
#else
	return reinterpret_cast<PTEB>(__readfsdword(0x00000018));
#endif
}

_Success_(return != NULL)
PPEB 
WINAPI 
GetProcessEnvironmentBlock(
	)
{
	PTEB pThreadEnvironmentBlock;

	pThreadEnvironmentBlock = GetThreadEnvironmentBlock();
	if (pThreadEnvironmentBlock)
		return pThreadEnvironmentBlock->ProcessEnvironmentBlock;

	return NULL;
}

_Success_(return != NULL)
PPEB_LDR_DATA 
WINAPI 
GetLoaderData(
	)
{
	PPEB pProcessEnvironmentBlock;
	PPEB_LDR_DATA pLdrData;

	pProcessEnvironmentBlock = GetProcessEnvironmentBlock();
	if (pProcessEnvironmentBlock != NULL)
	{
		pLdrData = pProcessEnvironmentBlock->Ldr;
		if (pLdrData != NULL)
		{
			return pLdrData;
		}
	}

	return NULL;
}

_Success_(return != FALSE)
BOOL 
WINAPI 
AddLoaderEntry(
	_In_ LPCWSTR lpcwszImageName, 
	_In_ LPVOID lpBaseAddress,
	_In_ SIZE_T uSizeOfImage
	)
{
	PLDR_DATA_TABLE_ENTRY pNewEntry;
	PLDR_DATA_TABLE_ENTRY pLastEntry;
	PPEB_LDR_DATA pLdrData;
	PLIST_ENTRY pBaseEntry;
	PIMAGE_NT_HEADERS pNtHeaders;

	pLdrData = GetLoaderData();
	if (!pLdrData)
		return FALSE;

	pLastEntry = reinterpret_cast<PLDR_DATA_TABLE_ENTRY>(pLdrData->InLoadOrderModuleList.Blink);
	if (!pLastEntry)
		return FALSE;

	pNtHeaders = ImageNtHeader(lpBaseAddress);
	if (!pNtHeaders)
		return FALSE;

	pNewEntry = new LDR_DATA_TABLE_ENTRY;
	pNewEntry->InLoadOrderModuleList.Flink = pLastEntry->InLoadOrderModuleList.Flink;
	pNewEntry->InLoadOrderModuleList.Blink = pLastEntry->InLoadOrderModuleList.Blink;
	pNewEntry->InMemoryOrderModuleList = pLastEntry->InMemoryOrderModuleList;
	pNewEntry->InInitializationOrderModuleList = pLastEntry->InInitializationOrderModuleList;
	pNewEntry->BaseAddress = lpBaseAddress;
	pNewEntry->SizeOfImage = uSizeOfImage;
	pNewEntry->EntryPoint = (PVOID)pNtHeaders->OptionalHeader.AddressOfEntryPoint;
	pNewEntry->Flags = pLastEntry->Flags;
	pNewEntry->LoadCount = pLastEntry->LoadCount;
	pNewEntry->TlsIndex = pLastEntry->TlsIndex;
	pNewEntry->HashTableEntry = pLastEntry->HashTableEntry;
	pNewEntry->CheckSum = pNtHeaders->OptionalHeader.CheckSum;
	pNewEntry->TimeDateStamp = pNtHeaders->FileHeader.TimeDateStamp;
	pNewEntry->EntryPointActivationContext = pLastEntry->EntryPointActivationContext;
	pNewEntry->PatchInformation = pLastEntry->PatchInformation;
	pNewEntry->ForwarderLinks = pLastEntry->ForwarderLinks;
	pNewEntry->ServiceTagLinks = pLastEntry->ServiceTagLinks;
	pNewEntry->StaticLinks = pLastEntry->StaticLinks;
	RtlInitUnicodeString(&pNewEntry->FullDllName, (L"C:\\" + std::wstring(lpcwszImageName)).c_str());
	RtlInitUnicodeString(&pNewEntry->BaseDllName, lpcwszImageName);

	pLastEntry->InLoadOrderModuleList.Flink = reinterpret_cast<PLIST_ENTRY>(pNewEntry);

	//Log(L"xmodule: %s, %08X, %08X\n", lpcwszImageName, lpBaseAddress, uSizeOfImage);

	return TRUE;
}