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

📄 image.cpp

📁 微软提供的截取Win32 API函数的开发包和例子detours-src-1.2.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	
	if (!SizeTo(m_cbData + cbAlloc + sizeof(DETOUR_SECTION_RECORD))) {
		return NULL;
	}
		
	PDETOUR_SECTION_RECORD pRecord = (PDETOUR_SECTION_RECORD)(m_pbData + m_cbData);
	pRecord->cbBytes = cbAlloc + sizeof(DETOUR_SECTION_RECORD);
	pRecord->nReserved = 0;
	pRecord->guid = rguid;
	
	PBYTE pbDest = (PBYTE)(pRecord + 1);
	if (pbData) {
		CopyMemory(pbDest, pbData, cbData);
		if (cbData < cbAlloc) {
			ZeroMemory(pbDest + cbData, cbAlloc - cbData);
		}
	}
	else {
		if (cbAlloc > 0) {
			ZeroMemory(pbDest, cbAlloc);
		}
	}
	
	m_cbData += cbAlloc + sizeof(DETOUR_SECTION_RECORD);

	IsValid();
	return pbDest;
}

//////////////////////////////////////////////////////////////////////////////
//
class CImageThunks 
{
private:
	CImage *			m_pImage;
	PIMAGE_THUNK_DATA	m_pThunks;
	DWORD				m_nThunks;
	DWORD				m_nThunksMax;
	DWORD				m_nThunkVirtAddr;
		
public:
	CImageThunks(CImage *pImage, DWORD nThunksMax, DWORD *pnAddr) 
	{
		m_pImage = pImage;
		m_nThunks = 0;
		m_nThunksMax = nThunksMax;
		m_pThunks = (PIMAGE_THUNK_DATA)
			m_pImage->AllocateOutput(sizeof(IMAGE_THUNK_DATA) * nThunksMax,
									 &m_nThunkVirtAddr);
		*pnAddr = m_nThunkVirtAddr;
	}
	
	PIMAGE_THUNK_DATA Current(DWORD *pnVirtAddr)
	{
		if (m_nThunksMax > 1) {
			*pnVirtAddr = m_nThunkVirtAddr;
			return m_pThunks;
		}
		*pnVirtAddr = 0;
		return NULL;
	}

	PIMAGE_THUNK_DATA Allocate(DWORD nData, DWORD *pnVirtAddr) 
	{
		if (m_nThunks < m_nThunksMax) {
			*pnVirtAddr = m_nThunkVirtAddr;
			
			m_nThunks++;
			m_nThunkVirtAddr += sizeof(IMAGE_THUNK_DATA);
			m_pThunks->u1.Ordinal = nData;
			return m_pThunks++;
		}
		*pnVirtAddr = 0;
		return NULL;
	}

	DWORD	Size()
	{
		return m_nThunksMax * sizeof(IMAGE_THUNK_DATA);
	}
};
	
//////////////////////////////////////////////////////////////////////////////
//
class CImageChars
{
private:
	CImage *		m_pImage;
	PCHAR			m_pChars;
	DWORD			m_nChars;
	DWORD			m_nCharsMax;
	DWORD			m_nCharVirtAddr;
		
public:
	CImageChars(CImage *pImage, DWORD nCharsMax, DWORD *pnAddr) 
	{
		m_pImage = pImage;
		m_nChars = 0;
		m_nCharsMax = nCharsMax;
		m_pChars = (PCHAR)m_pImage->AllocateOutput(nCharsMax, &m_nCharVirtAddr);
		*pnAddr = m_nCharVirtAddr;
	}

	PCHAR Allocate(PCHAR pszString, DWORD *pnVirtAddr) 
	{
		DWORD nLen = strlen(pszString) + 1;
		nLen += (nLen & 1);

		if (m_nChars + nLen > m_nCharsMax) {
			*pnVirtAddr = 0;
			return NULL;
		}

		*pnVirtAddr = m_nCharVirtAddr;
		strcpy(m_pChars, pszString);

		pszString = m_pChars;
			
		m_pChars += nLen;
		m_nChars += nLen;
		m_nCharVirtAddr += nLen;
			
		return pszString;
	}
		
	PCHAR Allocate(PCHAR pszString, DWORD nHint, DWORD *pnVirtAddr) 
	{
		DWORD nLen = strlen(pszString) + 1 + sizeof(USHORT);
		nLen += (nLen & 1);
			
		if (m_nChars + nLen > m_nCharsMax) {
			*pnVirtAddr = 0;
			return NULL;
		}

		*pnVirtAddr = m_nCharVirtAddr;
		*(USHORT *)m_pChars = (USHORT)nHint;
		strcpy(m_pChars + sizeof(USHORT), pszString);

		pszString = m_pChars + sizeof(USHORT);
		
		m_pChars += nLen;
		m_nChars += nLen;
		m_nCharVirtAddr += nLen;
			
		return pszString;
	}

	DWORD Size()
	{
		return m_nChars;
	}
};

//////////////////////////////////////////////////////////////////////////////
//
CImage * CImage::IsValid(PDETOUR_BINARY pBinary)
{
	if (pBinary) {
		CImage *pImage = (CImage *)pBinary;

		if (pImage->m_dwValidSignature == DETOUR_IMAGE_VALID_SIGNATURE) {
			return pImage;
		}
	}
	SetLastError(ERROR_INVALID_HANDLE);
	return NULL;
}

CImage::CImage()
{
	m_dwValidSignature = DETOUR_IMAGE_VALID_SIGNATURE;

	m_hMap = NULL;
	m_pMap = NULL;
	
	m_nPeOffset = 0;
	m_nSectionsOffset = 0;

	m_pbOutputBuffer = NULL;
	m_cbOutputBuffer = 0;

	m_pImageData = NULL;

	m_pImportFiles = NULL;
	m_nImportFiles = 0;
}

CImage::~CImage()
{
	Close();
	m_dwValidSignature = 0;
}

BOOL CImage::Close()
{
	if (m_pImportFiles) {
		delete m_pImportFiles;
		m_pImportFiles = NULL;
		m_nImportFiles = 0;
	}
	
	if (m_pImageData) {
		delete m_pImageData;
		m_pImageData = NULL;
	}

	if (m_pMap != NULL) {
		UnmapViewOfFile(m_pMap);
		m_pMap = NULL;
	}
	
	if (m_hMap) {
		CloseHandle(m_hMap);
		m_hMap = NULL;
	}
	
	if (m_pbOutputBuffer) {
		delete[] m_pbOutputBuffer;
		m_pbOutputBuffer = NULL;
		m_cbOutputBuffer = 0;
	}
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////////
//
PBYTE CImage::DataEnum(GUID *pGuid, DWORD *pcbData, DWORD *pnIterator)
{
	if (m_pImageData == NULL) {
		return NULL;
	}
	return m_pImageData->Enumerate(pGuid, pcbData, pnIterator);
}

PBYTE CImage::DataFind(REFGUID rguid, DWORD *pcbData)
{
	if (m_pImageData == NULL) {
		return NULL;
	}
	return m_pImageData->Find(rguid, pcbData);
}

PBYTE CImage::DataSet(REFGUID rguid, PBYTE pbData, DWORD cbData)
{
	if (m_pImageData == NULL) {
		return NULL;
	}
	return m_pImageData->Set(rguid, pbData, cbData);
}

BOOL CImage::DataDelete(REFGUID rguid)
{
	if (m_pImageData == NULL) {
		return FALSE;
	}
	return m_pImageData->Delete(rguid);
}

BOOL CImage::DataPurge()
{
	if (m_pImageData == NULL) {
		return TRUE;
	}
	return m_pImageData->Purge();
}

//////////////////////////////////////////////////////////////////////////////
//
BOOL CImage::SizeOutputBuffer(DWORD cbData)
{
	if (m_cbOutputBuffer < cbData) {
		if (cbData < 1024)	//65536
			cbData = 1024;
		cbData = FileAlign(cbData);

		PBYTE pOutput = new BYTE [cbData];
		if (pOutput == NULL) {
			SetLastError(ERROR_OUTOFMEMORY);
			return FALSE;
		}

		if (m_pbOutputBuffer) {
			CopyMemory(pOutput, m_pbOutputBuffer, m_cbOutputBuffer);
			
			delete[] m_pbOutputBuffer;
			m_pbOutputBuffer = NULL;
		}

		ZeroMemory(pOutput + m_cbOutputBuffer, cbData - m_cbOutputBuffer), 
		
		m_pbOutputBuffer = pOutput;
		m_cbOutputBuffer = cbData;
	}
	return TRUE;
}

PBYTE CImage::AllocateOutput(DWORD cbData, DWORD *pnVirtAddr)
{
	cbData = QuadAlign(cbData);

	PBYTE pbData = m_pbOutputBuffer + m_nOutputVirtSize;

	*pnVirtAddr = m_nOutputVirtAddr + m_nOutputVirtSize;
	m_nOutputVirtSize += cbData;
	
	if (m_nOutputVirtSize > m_cbOutputBuffer) {
		SetLastError(ERROR_OUTOFMEMORY);
		return NULL;
	}

	ZeroMemory(pbData, cbData);
	
	return pbData;
}

//////////////////////////////////////////////////////////////////////////////
//
DWORD CImage::FileAlign(DWORD nAddr)
{
	return Align(nAddr, m_NtHeader.OptionalHeader.FileAlignment);
}

DWORD CImage::SectionAlign(DWORD nAddr)
{
	return Align(nAddr, m_NtHeader.OptionalHeader.SectionAlignment);
}

//////////////////////////////////////////////////////////////////////////////
//
PVOID CImage::RvaToVa(DWORD nRva)
{
	if (nRva == 0) {
		return NULL;
	}
	
	for (DWORD n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
		DWORD vaStart = m_SectionHeaders[n].VirtualAddress;
		DWORD vaEnd = vaStart + m_SectionHeaders[n].SizeOfRawData;

		if (nRva >= vaStart && nRva < vaEnd) {
			return (PBYTE)m_pMap
				+ m_SectionHeaders[n].PointerToRawData 
				+ nRva - m_SectionHeaders[n].VirtualAddress;
		}
	}
	return NULL;
}

DWORD CImage::RvaToFileOffset(DWORD nRva)
{
	DWORD n;
	for (n = 0; n < m_NtHeader.FileHeader.NumberOfSections; n++) {
		DWORD vaStart = m_SectionHeaders[n].VirtualAddress;
		DWORD vaEnd = vaStart + m_SectionHeaders[n].SizeOfRawData;
		
		if (nRva >= vaStart && nRva < vaEnd) {
			return m_SectionHeaders[n].PointerToRawData 
				+ nRva - m_SectionHeaders[n].VirtualAddress;
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////////
//
BOOL CImage::CopyFileData(HANDLE hFile, DWORD nOldPos, DWORD cbData)
{
	DWORD cbDone = 0;
	return WriteFile(hFile, m_pMap + nOldPos, cbData, &cbDone, NULL);
}

BOOL CImage::ZeroFileData(HANDLE hFile, DWORD cbData)
{
	if (!SizeOutputBuffer(4096)) {
		return FALSE;
	}
	
	ZeroMemory(m_pbOutputBuffer, 4096);
	
	for (DWORD cbLeft = cbData; cbLeft > 0;) {
		DWORD cbStep = cbLeft > sizeof(m_pbOutputBuffer)
			? sizeof(m_pbOutputBuffer) : cbLeft;
		DWORD cbDone = 0;
		
		if (!WriteFile(hFile, m_pbOutputBuffer, cbDone, &cbDone, NULL)) {
			return FALSE;
		}
		if (cbDone == 0)
			break;

		cbLeft -= cbDone;
	}
	return TRUE;
}

BOOL CImage::AlignFileData(HANDLE hFile)
{
	DWORD nLastFileAddr = m_nNextFileAddr;
	
	m_nNextFileAddr = FileAlign(m_nNextFileAddr);
	m_nNextVirtAddr = SectionAlign(m_nNextVirtAddr);

	if (hFile != INVALID_HANDLE_VALUE) {
		if (m_nNextFileAddr > nLastFileAddr) {
			if (SetFilePointer(hFile, nLastFileAddr, NULL, FILE_BEGIN) == ~0u) {
				return FALSE;
			}
			return ZeroFileData(hFile, m_nNextFileAddr - nLastFileAddr);
		}
	}
	return TRUE;
}

BOOL CImage::Read(HANDLE hFile)
{

	DWORD n;
	PBYTE pbData = NULL;
	DWORD cbData = 0;
	
	if (hFile == INVALID_HANDLE_VALUE) {
		SetLastError(ERROR_INVALID_HANDLE);
		return FALSE;
	}

	///////////////////////////////////////////////////////// Create mapping.
	//
	m_nFileSize = GetFileSize(hFile, NULL);
	if (m_nFileSize == (DWORD)-1) {
		return FALSE;
	}

	m_hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (m_hMap == NULL) {
		return FALSE;
	}

	m_pMap = (PBYTE)MapViewOfFile(m_hMap, FILE_MAP_COPY, 0, 0, 0);
	if (m_pMap == NULL) {
		return FALSE;
	}

	////////////////////////////////////////////////////// Process DOS Header.
	//
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)m_pMap;
	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
		SetLastError(ERROR_BAD_EXE_FORMAT);
		return FALSE;
	}
	m_nPeOffset = pDosHeader->e_lfanew;

	/////////////////////////////////////////////////////// Process PE Header.
	//
	CopyMemory(&m_NtHeader, m_pMap + m_nPeOffset, sizeof(m_NtHeader));
	if (m_NtHeader.Signature != IMAGE_NT_SIGNATURE) {
		SetLastError(ERROR_INVALID_EXE_SIGNATURE);
		return FALSE;
	}
	if (m_NtHeader.FileHeader.SizeOfOptionalHeader == 0) {
		SetLastError(ERROR_EXE_MARKED_INVALID);
		return FALSE;
	}
	m_nSectionsOffset = m_nPeOffset
		+ sizeof(m_NtHeader.Signature)
		+ sizeof(m_NtHeader.FileHeader)
		+ m_NtHeader.FileHeader.SizeOfOptionalHeader;

	///////////////////////////////////////////////// Process Section Headers.
	//
	if (m_NtHeader.FileHeader.NumberOfSections > (sizeof(m_SectionHeaders) /
												  sizeof(m_SectionHeaders[0]))) {

⌨️ 快捷键说明

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