这是我的问题。我绕开了“ScriptTextOut”功能,我试图找到它的来源。这是我的dll(我使用Microsoft Detour):
#pragma comment(lib, "detours.lib")
#include <Windows.h>
#include <detours.h>
#include <tchar.h>
#include <string>
#include <iostream>
#include <Usp10.h>
#include <Dbghelp.h>
HRESULT (WINAPI * Real_ScriptTextOut)(const HDC hdc, SCRIPT_CACHE *psc, int x, int y, UINT fuOptions, const RECT *lprc, const SCRIPT_ANALYSIS *psa, const WCHAR *pwcReserved, int iReserved,
const WORD *pwGlyphs, int cGlyphs, const int *piAdvance, const int *piJustify, const GOFFSET *pGoffset) = ScriptTextOut;
// function used to back trace where the function was called from
void printStack()
{
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
for( i = 0; i < frames; i++ )
{
SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
printf( "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address );
}
free( symbol );
}
// My ScriptTextOut function
HRESULT WINAPI Mine_ScriptTextOut(const HDC hdc, SCRIPT_CACHE *psc, int x, int y, UINT fuOptions, const RECT *lprc, const SCRIPT_ANALYSIS *psa, const WCHAR *pwcReserved, int iReserved,
const WORD *pwGlyphs, int cGlyphs, const int *piAdvance, const int *piJustify, const GOFFSET *pGoffset)
{
printStack();
return Real_ScriptTextOut(hdc, psc, x, y, fuOptions, lprc, psa, pwcReserved, iReserved, pwGlyphs, cGlyphs, piAdvance, piJustify, pGoffset);
}
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
AllocConsole();
freopen("CONOUT$", "w", stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_ScriptTextOut, Mine_ScriptTextOut);
DetourTransactionCommit();
break;
case DLL_PROCESS_DETACH:
FreeConsole();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_ScriptTextOut, Mine_ScriptTextOut);
DetourTransactionCommit();
break;
}
return TRUE;
}
所以绕行功能按预期工作,但printStack()函数打印出一些奇怪的结果......在这里,看看:
为什么它很奇怪,你可能会问?好吧,我希望找到调用ScriptTextOut的函数,但是“Mine_ScriptTextOut”之前的函数是“ScriptApplyDigitSubstitution”,虽然这两个明显相关,但是没有调用另一个......
在注入的dll之外测试我的PrintStack功能时,一切都很顺利:
#include <Windows.h>
#include <Dbghelp.h>
#include <cstdio>
void printStack()
{
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
for( i = 0; i < frames; i++ )
{
SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
printf( "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address );
}
free( symbol );
}
void dontprint()
{
}
void foo()
{
printStack();
}
void test()
{
dontprint();
foo();
}
int main()
{
dontprint();
test();
return 0;
}
这是正确的输出:
知道发生了什么事吗?