📄 detours.cpp
字号:
}
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 + -