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

📄 detours.cpp

📁 微软提供的截取Win32 API函数的开发包和例子detours-src-1.2.rar
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
		
		if (s_pfSymInitialize) {
			(*s_pfSymInitialize)(s_hProcess, NULL, FALSE);
		}
		
		if (s_pfSymGetOptions && s_pfSymSetOptions) {
			DWORD dw = (*s_pfSymGetOptions)();
			dw &= (SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
			(*s_pfSymSetOptions)(dw);
		}
		
		return TRUE;
	}
	return FALSE;
}

//////////////////////////////////////////////////////////////////////////////
//
PBYTE WINAPI DetourFindFinalCode(PBYTE pbCode)
{
	if (pbCode == NULL)
		return NULL;
	
	PBYTE pbTemp = pbCode;
	if (pbCode[0] == OP_JMP) {							// Reference passed.
		pbCode = pbCode + SIZE_OF_JMP + *(LONG *)&pbCode[1];
	}
	else if (pbCode[0] == OP_PREFIX && pbCode[1] == OP_JMP_DS) {
		pbCode = *(PBYTE *)&pbCode[2];
		pbCode = *(PBYTE *)pbCode;
	}
	return pbCode;
}

PBYTE WINAPI DetourFindFunction(PCHAR pszModule, PCHAR pszFunction)
{
	/////////////////////////////////////////////// First, Try GetProcAddress.
	//
	HINSTANCE hInst = LoadLibraryA(pszModule);
	if (hInst == NULL) {
		return NULL;
	}

	PBYTE pbCode = (PBYTE)GetProcAddress(hInst, pszFunction);
	if (pbCode) {
		return pbCode;
	}

	////////////////////////////////////////////////////// Then Try ImageHelp.
	//
	if (!LoadImageHlp() || 
		s_pfSymLoadModule == NULL ||
		s_pfSymGetModuleInfo == NULL ||
		s_pfSymGetSymFromName == NULL) {

		return NULL;
	}
	
	(*s_pfSymLoadModule)(s_hProcess, NULL, pszModule, NULL, (DWORD)hInst, 0);

	IMAGEHLP_MODULE modinfo;
	ZeroMemory(&modinfo, sizeof(modinfo));
	if (!(*s_pfSymGetModuleInfo)(s_hProcess, (DWORD)hInst, &modinfo)) {
		return NULL;
	}

	CHAR szFullName[512];
	strcpy(szFullName, modinfo.ModuleName);
	strcat(szFullName, "!");
	strcat(szFullName, pszFunction);
	
	DWORD nDisplacement = 0;
	struct CFullSymbol : IMAGEHLP_SYMBOL {
		CHAR szRestOfName[512];
	} symbol;
	ZeroMemory(&symbol, sizeof(symbol));
	symbol.SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	symbol.MaxNameLength = sizeof(symbol.szRestOfName)/sizeof(0);

	if (!(*s_pfSymGetSymFromName)(s_hProcess, szFullName, &symbol)) {
		return NULL;
	}

	return (PBYTE)symbol.Address;
}

//////////////////////////////////////////////////// Instance Image Functions.
//
HINSTANCE WINAPI DetourEnumerateInstances(HINSTANCE hinstLast)
{
	PBYTE pbLast;
	
	if (hinstLast == NULL) {
		pbLast = (PBYTE)0x10000;
	}
	else {
		pbLast = (PBYTE)hinstLast + 0x10000;
	}

	MEMORY_BASIC_INFORMATION mbi;
	ZeroMemory(&mbi, sizeof(mbi));
	
	for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {
		if (VirtualQuery((PVOID)pbLast, &mbi, sizeof(mbi)) <= 0) {
			return NULL;
		}

		if (mbi.State != MEM_COMMIT)
			continue;
		
		__try {
			PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbLast;
			if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
				continue;
			}

			PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
															  pDosHeader->e_lfanew);
			if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
				continue;
			}

			return (HINSTANCE)pDosHeader;
		} __except(EXCEPTION_EXECUTE_HANDLER) {
			/* nothing. */
		}
	}
	return NULL;
}

PBYTE WINAPI DetourFindEntryPointForInstance(HINSTANCE hInst)
{
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hInst;
	if (hInst == NULL) {
		pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
	}
	
	__try {
		if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
			SetLastError(ERROR_BAD_EXE_FORMAT);
			return NULL;
		}
		
		PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
														  pDosHeader->e_lfanew);
		if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
			SetLastError(ERROR_INVALID_EXE_SIGNATURE);
			return NULL;
		}
		if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
			SetLastError(ERROR_EXE_MARKED_INVALID);
			return NULL;
		}
		return (PBYTE)pNtHeader->OptionalHeader.AddressOfEntryPoint +
			pNtHeader->OptionalHeader.ImageBase;
	} __except(EXCEPTION_EXECUTE_HANDLER) {
	}
	SetLastError(ERROR_EXE_MARKED_INVALID);
	
	return NULL;
}

static inline PBYTE RvaAdjust(HINSTANCE hInst, DWORD raddr)
{
	if (raddr != NULL) {
		return (PBYTE)hInst + raddr;
	}
	return NULL;
}

BOOL WINAPI DetourEnumerateExportsForInstance(HINSTANCE hInst,
											  PVOID pContext,
											  PF_DETOUR_BINARY_EXPORT_CALLBACK pfExport)
{
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hInst;
	if (hInst == NULL) {
		pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
	}
	
	__try {
		if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
			SetLastError(ERROR_BAD_EXE_FORMAT);
			return NULL;
		}
		
		PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
														  pDosHeader->e_lfanew);
		if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
			SetLastError(ERROR_INVALID_EXE_SIGNATURE);
			return FALSE;
		}
		if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
			SetLastError(ERROR_EXE_MARKED_INVALID);
			return FALSE;
		}

		PIMAGE_EXPORT_DIRECTORY pExportDir
			= (PIMAGE_EXPORT_DIRECTORY)
			RvaAdjust(hInst,
					  pNtHeader->OptionalHeader
					  .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
		ULONG cbExportDir = pNtHeader->OptionalHeader
			.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
		
		if (pExportDir == NULL) {
			SetLastError(ERROR_EXE_MARKED_INVALID);
			return FALSE;
		}

		PCHAR pszName = (PCHAR)RvaAdjust(hInst, pExportDir->Name);
		PDWORD pdwFunctions = (PDWORD)RvaAdjust(hInst, pExportDir->AddressOfFunctions);
		PDWORD pdwNames = (PDWORD)RvaAdjust(hInst, pExportDir->AddressOfNames);
		PWORD pwOrdinals = (PWORD)RvaAdjust(hInst, pExportDir->AddressOfNameOrdinals);

		for (DWORD nFunc = 0; nFunc < pExportDir->NumberOfFunctions; nFunc++) {
			PBYTE pbCode = (PBYTE)RvaAdjust(hInst, pdwFunctions[nFunc]);
			PCHAR pszName = (nFunc < pExportDir->NumberOfNames) ?
				(PCHAR)RvaAdjust(hInst, pdwNames[nFunc]) : NULL;
			ULONG nOrdinal = pExportDir->Base + pwOrdinals[nFunc];

			if (!(*pfExport)(pContext, nOrdinal, pszName, pbCode)) {
				break;
			}
		}
		SetLastError(NO_ERROR);
		return TRUE;
	} __except(EXCEPTION_EXECUTE_HANDLER) {
	}
	SetLastError(ERROR_EXE_MARKED_INVALID);
	return FALSE;
}

PDETOUR_LOADED_BINARY WINAPI DetourBinaryFromInstance(HINSTANCE hInst)
{
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hInst;
	if (hInst == NULL) {
		pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
	}
	
	__try {
		if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
			SetLastError(ERROR_BAD_EXE_FORMAT);
			return NULL;
		}
		
		PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
														  pDosHeader->e_lfanew);
		if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
			SetLastError(ERROR_INVALID_EXE_SIGNATURE);
			return NULL;
		}
		if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
			SetLastError(ERROR_EXE_MARKED_INVALID);
			return NULL;
		}
		
		PIMAGE_SECTION_HEADER pSectionHeaders
			= (PIMAGE_SECTION_HEADER)((PBYTE)pNtHeader
									  + sizeof(pNtHeader->Signature)
									  + sizeof(pNtHeader->FileHeader)
									  + pNtHeader->FileHeader.SizeOfOptionalHeader);

		for (DWORD n = 0; n < pNtHeader->FileHeader.NumberOfSections; n++) {
			if (strcmp((PCHAR)pSectionHeaders[n].Name, ".detour") == 0) {
				if (pSectionHeaders[n].VirtualAddress == 0 ||
					pSectionHeaders[n].SizeOfRawData == 0) {

					break;
				}
					
				PBYTE pbData = (PBYTE)pDosHeader + pSectionHeaders[n].VirtualAddress;
				DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pbData;
				if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
					pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
					
					break;
				}

				if (pHeader->nDataOffset == 0) {
					pHeader->nDataOffset = pHeader->cbHeaderSize;
				}
				return (PBYTE)pHeader;
			}
		}
	} __except(EXCEPTION_EXECUTE_HANDLER) {
	}
	SetLastError(ERROR_EXE_MARKED_INVALID);
	
	return NULL;
}

DWORD WINAPI DetourGetSizeOfBinary(PDETOUR_LOADED_BINARY pBinary)
{
	__try {
		DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
		if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
			pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
			
			SetLastError(ERROR_INVALID_HANDLE);
			return 0;
		}
		return pHeader->cbDataSize;
	} __except(EXCEPTION_EXECUTE_HANDLER) {
		SetLastError(ERROR_INVALID_HANDLE);
		return 0;
	}
	SetLastError(ERROR_INVALID_HANDLE);
	return 0;
}

PBYTE WINAPI DetourFindPayloadInBinary(PDETOUR_LOADED_BINARY pBinary,
									   REFGUID rguid,
									   DWORD * pcbData)
{
	PBYTE pbData = NULL;
	DWORD cbData = 0;
	if (pcbData) {
		*pcbData = 0;
	}

	if (pBinary == NULL) {
		pBinary = DetourBinaryFromInstance(NULL);
	}
	
	__try {
		DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
		if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
			pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {

			SetLastError(ERROR_INVALID_EXE_SIGNATURE);
			return NULL;
		}
		
		PBYTE pbBeg = ((PBYTE)pHeader) + pHeader->nDataOffset;
		PBYTE pbEnd = ((PBYTE)pHeader) + pHeader->cbDataSize;
		
		for (pbData = pbBeg; pbData < pbEnd;) {
			DETOUR_SECTION_RECORD *pSection = (DETOUR_SECTION_RECORD *)pbData;
			
			if (pSection->guid == rguid) {
				if (pcbData) {
					*pcbData = pSection->cbBytes - sizeof(*pSection);
					return (PBYTE)(pSection + 1);
				}
				
			}
			
			pbData = (PBYTE)pSection + pSection->cbBytes;
		}
	} __except(EXCEPTION_EXECUTE_HANDLER) {
		SetLastError(ERROR_INVALID_HANDLE);
		return NULL;
	}
	SetLastError(ERROR_INVALID_HANDLE);
	return NULL;
}

//////////////////////////////////////////////////////////////////////////////
//
BOOL WINAPI DetourBinaryBindA(PCHAR pszFile, PCHAR pszDll, PCHAR pszPath)
{
	if (!LoadImageHlp()) {
		SetLastError(ERROR_MOD_NOT_FOUND);
		return FALSE;
	}
	if (s_pfBindImage) {
		return (*s_pfBindImage)(pszFile, pszDll ? pszDll : ".", pszPath ? pszPath : ".");
	}
	SetLastError(ERROR_INVALID_FUNCTION);
	return FALSE;
}

static void UnicodeToOem(PWCHAR pwzIn, PCHAR pszOut, INT cbOut)
{
	cbOut = WideCharToMultiByte(CP_OEMCP, 0,
								pwzIn, wcslen(pwzIn),
								pszOut, cbOut-1,
								NULL, NULL);
	pszOut[cbOut] = '\0';
}

BOOL WINAPI DetourBinaryBindW(PWCHAR pwzFile, PWCHAR pwzDll, PWCHAR pwzPath)
{
	if (!LoadImageHlp()) {
		SetLastError(ERROR_MOD_NOT_FOUND);
		return FALSE;
	}
	
	CHAR szFile[MAX_PATH];
	CHAR szDll[MAX_PATH];
	CHAR szPath[MAX_PATH];

	UnicodeToOem(pwzFile, szFile, sizeof(szFile));
	UnicodeToOem(pwzDll, szDll, sizeof(szDll));
	UnicodeToOem(pwzPath, szPath, sizeof(szPath));

	if (s_pfBindImage) {
		return (s_pfBindImage)(szFile, szDll, szPath);
	}
	SetLastError(ERROR_INVALID_FUNCTION);
	return FALSE;
}

//  End of File

⌨️ 快捷键说明

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