⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.cpp

📁 微软提供的截取Win32 API函数的开发包和例子detours-src-1.2.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	//
	if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == ~0u) {
		return FALSE;
	}
	if (!CopyFileData(hFile, 0, m_NtHeader.OptionalHeader.SizeOfHeaders)) {
		return FALSE;
	}

	m_nNextFileAddr = m_NtHeader.OptionalHeader.SizeOfHeaders;
	m_nNextVirtAddr = 0;
	if (!AlignFileData(hFile)) {
		return FALSE;
	}
	
	/////////////////////////////////////////////////////////// Copy Sections.
	//
	for (DWORD n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
		if (m_SectionHeaders[n].SizeOfRawData) {
			if (SetFilePointer(hFile,
							   m_SectionHeaders[n].PointerToRawData,
							   NULL, FILE_BEGIN) == ~0u) {
				return FALSE;
			}
			if (!CopyFileData(hFile,
							  m_SectionHeaders[n].PointerToRawData,
							  m_SectionHeaders[n].SizeOfRawData)) {
				return FALSE;
			}
		}
		m_nNextFileAddr = Max(m_SectionHeaders[n].PointerToRawData +
							  m_SectionHeaders[n].SizeOfRawData,
							  m_nNextFileAddr);
		m_nNextVirtAddr = Max(m_SectionHeaders[n].VirtualAddress +
							  m_SectionHeaders[n].Misc.VirtualSize,
							  m_nNextVirtAddr);
		m_nExtraOffset = Max(m_nNextFileAddr, m_nExtraOffset);
		
		if (!AlignFileData(hFile)) {
			return FALSE;
		}
	}

	/////////////////////////////////////////////////////////////// Old WriteSection
	BOOLEAN bNeedDetourSection;
	DWORD cbDone;

	DWORD nTables = 0;
	DWORD nThunks = 0;
	DWORD nChars = 0;
	bNeedDetourSection = CheckImportsNeeded(&nTables, &nThunks, &nChars);
	
	if (bNeedDetourSection || !m_pImageData->IsEmpty()) {
		/////////////////////////////////////////////////// Insert .detour Section.
		//
		DWORD nSection = m_NtHeader.FileHeader.NumberOfSections++;
		DETOUR_SECTION_HEADER dh;

		ZeroMemory(&dh, sizeof(dh));
		ZeroMemory(&m_SectionHeaders[nSection], sizeof(m_SectionHeaders[nSection]));

		dh.cbHeaderSize = sizeof(DETOUR_SECTION_HEADER);
		dh.nSignature = DETOUR_SECTION_HEADER_SIGNATURE;
	
		dh.nOriginalImportVirtualAddress = m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
		dh.nOriginalImportSize = m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
		
		dh.nOriginalBoundImportVirtualAddress
			= m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress;
		dh.nOriginalBoundImportSize = m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size;
	
		dh.nOriginalIatVirtualAddress = m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
		dh.nOriginalIatSize = m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
	
		dh.nOriginalSizeOfImage = m_NtHeader.OptionalHeader.SizeOfImage;
	
		strcpy((PCHAR)m_SectionHeaders[nSection].Name, ".detour");
		m_SectionHeaders[nSection].Characteristics
			= IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;

		m_nOutputVirtAddr = m_nNextVirtAddr;
		m_nOutputVirtSize = 0;
		m_nOutputFileAddr = m_nNextFileAddr;

		dh.nDataOffset = 0;						// pbData
		dh.cbDataSize = m_pImageData->m_cbData;

		//////////////////////////////////////////////////////////////////////////
		//
		
		DWORD rvaImportTable = 0;
		DWORD rvaLookupTable = 0;
		DWORD rvaBoundTable = 0;
		DWORD rvaNameTable = 0;
		DWORD nImportTableSize = nTables * sizeof(IMAGE_IMPORT_DESCRIPTOR);
	
		if (!SizeOutputBuffer(QuadAlign(sizeof(dh))
							 + QuadAlign(m_pImageData->m_cbData)
							 + QuadAlign(sizeof(IMAGE_THUNK_DATA) * nThunks)
							 + QuadAlign(sizeof(IMAGE_THUNK_DATA) * nThunks)
							 + QuadAlign(nChars)
							 + QuadAlign(nImportTableSize))) {
			return FALSE;
		}

		DWORD vaHead = 0;
		PBYTE pbHead = NULL;
		DWORD vaData = 0;
		PBYTE pbData = NULL;

		if ((pbHead = AllocateOutput(sizeof(dh), &vaHead)) == NULL) {
			return FALSE;
		}
		
		CImageThunks lookupTable(this, nThunks, &rvaLookupTable);
		CImageThunks boundTable(this, nThunks, &rvaBoundTable);
		CImageChars nameTable(this, nChars, &rvaNameTable);
			
		if ((pbData = AllocateOutput(m_pImageData->m_cbData, &vaData)) == NULL) {
			return FALSE;
		}
		
		dh.nDataOffset = vaData - vaHead;
		dh.cbDataSize = dh.nDataOffset + m_pImageData->m_cbData;
		CopyMemory(pbHead, &dh, sizeof(dh));
		CopyMemory(pbData, m_pImageData->m_pbData, m_pImageData->m_cbData);
	
		PIMAGE_IMPORT_DESCRIPTOR piidDst = (PIMAGE_IMPORT_DESCRIPTOR)
			AllocateOutput(nImportTableSize, &rvaImportTable);
		if (piidDst == NULL) {
			return FALSE;
		}

		//////////////////////////////////////////////// Step Through Imports.
		//
		for (CImageImportFile *pImportFile = m_pImportFiles;
			 pImportFile != NULL; pImportFile = pImportFile->m_pNextFile) {

			ZeroMemory(piidDst, sizeof(piidDst));
			nameTable.Allocate(pImportFile->m_pszName, (DWORD *)&piidDst->Name);
			piidDst->TimeDateStamp = 0;
			piidDst->ForwarderChain = pImportFile->m_nForwarderChain;
			
			if (pImportFile->m_bByway) {
				ULONG rvaIgnored;
				
				lookupTable.Allocate(IMAGE_ORDINAL_FLAG+1,
									 (DWORD *)&piidDst->OriginalFirstThunk);
				boundTable.Allocate(IMAGE_ORDINAL_FLAG+1,
									(DWORD *)&piidDst->FirstThunk);
				
				lookupTable.Allocate(0, &rvaIgnored);
				boundTable.Allocate(0, &rvaIgnored);
			}
			else {
				ULONG rvaIgnored;

				piidDst->FirstThunk = (ULONG)pImportFile->m_rvaFirstThunk;
				lookupTable.Current((DWORD *)&piidDst->OriginalFirstThunk);
				
				for (DWORD n = 0; n < pImportFile->m_nImportNames; n++) {
					CImageImportName *pImportName = &pImportFile->m_pImportNames[n];

					if (pImportName->m_pszName) {
						ULONG nDstName = 0;
						
						nameTable.Allocate(pImportName->m_pszName,
										   pImportName->m_nHint,
										   &nDstName);
						lookupTable.Allocate(nDstName, &rvaIgnored);
					}
					else {
						lookupTable.Allocate(IMAGE_ORDINAL_FLAG+pImportName->m_nOrdinal,
											 &rvaIgnored);
					}
				}
				lookupTable.Allocate(0, &rvaIgnored);
			}
			piidDst++;
		}
		ZeroMemory(piidDst, sizeof(piidDst));
		
		//////////////////////////////////////////////////////////////////////////
		//
		m_nNextVirtAddr += m_nOutputVirtSize;
		m_nNextFileAddr += FileAlign(m_nOutputVirtSize);
	
		if (!AlignFileData(hFile)) {
			return FALSE;
		}
	
		//////////////////////////////////////////////////////////////////////////
		//
		m_SectionHeaders[nSection].VirtualAddress = m_nOutputVirtAddr;
		m_SectionHeaders[nSection].Misc.VirtualSize = m_nOutputVirtSize;
		m_SectionHeaders[nSection].PointerToRawData = m_nOutputFileAddr;
		m_SectionHeaders[nSection].SizeOfRawData = FileAlign(m_nOutputVirtSize);
	
		m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
			= rvaImportTable;
		m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
			= nImportTableSize;

		m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
		m_NtHeader.OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;

		//////////////////////////////////////////////////////////////////////////
		//
		if (SetFilePointer(hFile, m_SectionHeaders[nSection].PointerToRawData,
						   NULL, FILE_BEGIN) == ~0u) {
			return FALSE;
		}
		if (!WriteFile(hFile, m_pbOutputBuffer, m_SectionHeaders[nSection].SizeOfRawData,
					   &cbDone, NULL)) {
			return FALSE;
		}
	}
	
	///////////////////////////////////////////////////// Adjust Extra Data.
	//
	LONG nExtraAdjust = m_nNextFileAddr - m_nExtraOffset;
	for (n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
		if (m_SectionHeaders[n].PointerToRawData > m_nExtraOffset)
			m_SectionHeaders[n].PointerToRawData += nExtraAdjust;
		if (m_SectionHeaders[n].PointerToRelocations > m_nExtraOffset)
			m_SectionHeaders[n].PointerToRelocations += nExtraAdjust;
		if (m_SectionHeaders[n].PointerToLinenumbers > m_nExtraOffset)
			m_SectionHeaders[n].PointerToLinenumbers += nExtraAdjust;
	}
	if (m_NtHeader.FileHeader.PointerToSymbolTable > m_nExtraOffset)
		m_NtHeader.FileHeader.PointerToSymbolTable += nExtraAdjust;
		
	m_NtHeader.OptionalHeader.CheckSum = 0;
	m_NtHeader.OptionalHeader.SizeOfImage = m_nNextVirtAddr;
	
	////////////////////////////////////////////////// Adjust Debug Directory.
	//
	DWORD debugAddr = m_NtHeader.OptionalHeader
		.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
	DWORD debugSize = m_NtHeader.OptionalHeader
		.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
	if (debugAddr && debugSize) {
		PIMAGE_DEBUG_DIRECTORY pDir = (PIMAGE_DEBUG_DIRECTORY)RvaToVa(debugAddr);
		if (pDir == NULL) {
			return FALSE;
		}
		DWORD nEntries = debugSize / sizeof(*pDir);
		
		for (DWORD n = 0; n < nEntries; n++) {
			pDir[n].PointerToRawData += nExtraAdjust;
		}

		DWORD nFileOffset = RvaToFileOffset(debugAddr);
		if (SetFilePointer(hFile, nFileOffset, NULL, FILE_BEGIN) == ~0u) {
			return FALSE;
		}
		if (!WriteFile(hFile, pDir, debugSize, &cbDone, NULL)) {
			return FALSE;
		}
	}
	
	///////////////////////////////////////////////// Copy Left-over Data.
	//
	if (m_nFileSize > m_nExtraOffset) {
		if (SetFilePointer(hFile, m_nNextFileAddr, NULL, FILE_BEGIN) == ~0u) {
			return FALSE;
		}
		if (!CopyFileData(hFile, m_nExtraOffset, m_nFileSize - m_nExtraOffset)) {
			return FALSE;
		}
	}

	//////////////////////////////////////////////////// Finalize Headers.
	//

	if (SetFilePointer(hFile, m_nPeOffset, NULL, FILE_BEGIN) == ~0u) {
		return FALSE;
	}
	if (!WriteFile(hFile, &m_NtHeader, sizeof(m_NtHeader), &cbDone, NULL)) {
		return FALSE;
	}
	
	if (SetFilePointer(hFile, m_nSectionsOffset, NULL, FILE_BEGIN) == ~0u) {
		return FALSE;
	}
	if (!WriteFile(hFile, &m_SectionHeaders,
				   sizeof(m_SectionHeaders[0])
				   * m_NtHeader.FileHeader.NumberOfSections,
				   &cbDone, NULL)) {
		return FALSE;
	}
	return TRUE;
}

};														// namespace Detour


//////////////////////////////////////////////////////////////////////////////
//
static BOOL CALLBACK ResetBywayCallback(PVOID pContext,
										PCHAR pszFile,
										PCHAR *ppszOutFile)
{
	*ppszOutFile = NULL;
	return TRUE;
}

static BOOL CALLBACK ResetFileCallback(PVOID pContext,
									   PCHAR pszOrigFile,
									   PCHAR pszFile,
									   PCHAR *ppszOutFile)
{
	*ppszOutFile = pszOrigFile;
	return TRUE;
}

static BOOL CALLBACK ResetSymbolCallback(PVOID pContext,
										 DWORD nOrdinal,
										 PCHAR pszOrigSymbol,
										 PCHAR pszSymbol,
										 PCHAR *ppszOutSymbol)
{
	*ppszOutSymbol = pszOrigSymbol;
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////////
//
PDETOUR_BINARY WINAPI DetourBinaryOpen(HANDLE hFile)
{
	Detour::CImage *pImage = new Detour::CImage;
	if (pImage == NULL) {
		SetLastError(ERROR_OUTOFMEMORY);
		return FALSE;
	}

	if (!pImage->Read(hFile)) {
		delete pImage;
		return FALSE;
	}

	return (PDETOUR_BINARY)pImage;
}

BOOL WINAPI DetourBinaryWrite(PDETOUR_BINARY pdi, HANDLE hFile)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->Write(hFile);
}

PBYTE WINAPI DetourBinaryEnumeratePayloads(PDETOUR_BINARY pdi,
										   GUID *pGuid,
										   DWORD *pcbData,
										   DWORD *pnIterator)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->DataEnum(pGuid, pcbData, pnIterator);
}

PBYTE WINAPI DetourBinaryFindPayload(PDETOUR_BINARY pdi,
									 REFGUID rguid,
									 DWORD *pcbData)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->DataFind(rguid, pcbData);
}

PBYTE WINAPI DetourBinarySetPayload(PDETOUR_BINARY pdi,
									REFGUID rguid,
									PBYTE pbData,
									DWORD cbData)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->DataSet(rguid, pbData, cbData);
}

BOOL WINAPI DetourBinaryDeletePayload(PDETOUR_BINARY pdi,
									 REFGUID rguid)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->DataDelete(rguid);
}

BOOL WINAPI DetourBinaryPurgePayload(PDETOUR_BINARY pdi)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->DataPurge();
}

BOOL WINAPI DetourBinaryResetImports(PDETOUR_BINARY pdi)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->EditImports(NULL,
							   ResetBywayCallback,
							   ResetFileCallback,
							   ResetSymbolCallback,
							   NULL);
}

BOOL WINAPI DetourBinaryEditImports(PDETOUR_BINARY pdi,
									PVOID pContext,
									PF_DETOUR_BINARY_BYWAY_CALLBACK pfBywayCallback,
									PF_DETOUR_BINARY_FILE_CALLBACK pfFileCallback,
									PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbolCallback,
									PF_DETOUR_BINARY_FINAL_CALLBACK pfFinalCallback)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	return pImage->EditImports(pContext,
							   pfBywayCallback,
							   pfFileCallback,
							   pfSymbolCallback,
							   pfFinalCallback);
}

BOOL WINAPI DetourBinaryClose(PDETOUR_BINARY pdi)
{
	Detour::CImage *pImage = Detour::CImage::IsValid(pdi);
	if (pImage == NULL) {
		return FALSE;
	}

	BOOL bSuccess = pImage->Close();
	delete pImage;
	pImage = NULL;

	return bSuccess;
}
//
///////////////////////////////////////////////////////////////// End of File.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -