C++ 当试图在注入的dll中回溯跟踪时,会出现Wierd结果

C++ 当试图在注入的dll中回溯跟踪时,会出现Wierd结果,c++,winapi,dll,stack-trace,C++,Winapi,Dll,Stack Trace,这是我的问题。我绕过了“ScriptTextOut”函数,并试图找到它的调用来源。这是我的dll(我使用Microsoft Detour): #pragma注释(lib,“detours.lib”) #包括 #包括 #包括 #包括 #包括 #包括 #包括 HRESULT(WINAPI*Real\u ScriptTextOut)(常量HDC HDC、脚本缓存*psc、int x、int y、UINT fuOptions、常量RECT*lprc、常量脚本分析*psa、常量WCHAR*pwcReser

这是我的问题。我绕过了“ScriptTextOut”函数,并试图找到它的调用来源。这是我的dll(我使用Microsoft Detour):

#pragma注释(lib,“detours.lib”)
#包括
#包括
#包括
#包括
#包括
#包括
#包括
HRESULT(WINAPI*Real\u ScriptTextOut)(常量HDC HDC、脚本缓存*psc、int x、int y、UINT fuOptions、常量RECT*lprc、常量脚本分析*psa、常量WCHAR*pwcReserved、int iReserved、,
const WORD*pGlyphs,int cGlyphs,const int*piAdvance,const int*piJustify,const GOFFSET*pGoffset)=脚本文本输出;
//函数用于回溯从何处调用函数
void printStack()
{
无符号整数i;
void*stack[100];
无符号短帧;
符号信息*符号;
处理过程;
process=GetCurrentProcess();
SymInitialize(进程,NULL,TRUE);
frames=capturestacktrace(0,100,stack,NULL);
symbol=(symbol_INFO*)calloc(sizeof(symbol_INFO)+256*sizeof(char),1);
symbol->MaxNameLen=255;
symbol->SizeOfStruct=sizeof(symbol\U信息);
对于(i=0;i名称,符号->地址);
}
免费(符号);
}
//我的ScriptTextOut函数
HRESULT WINAPI Mine_ScriptTextOut(常量HDC HDC、脚本缓存*psc、int x、int y、UINT fuOptions、常量RECT*lprc、常量脚本分析*psa、常量WCHAR*pwcReserved、int iReserved、,
常量字*pGlyphs,int cGlyphs,常量int*piAdvance,常量int*piJustify,常量GOFFSET*pGoffset)
{
printStack();
返回Real_ScriptTextOut(hdc、psc、x、y、fuOptions、lprc、psa、pwcReserved、iReserved、pwGlyphs、cGlyphs、piAdvance、piJustify、pGoffset);
}
BOOL APIENTRY DllMain(句柄模块、DWORD ul_原因、LPVOID LPREFERED)
{
开关(ul\u呼叫原因\u)
{
案例DLL\u进程\u附加:
allocsole();
freopen(“CONOUT$”、“w”、stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
迂回附加(&(PVOID&)Real_ScriptTextOut,Mine_ScriptTextOut);
DetourTransactionCommit();
打破
案例DLL\u进程\u分离:
FreeConsole();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_ScriptTextOut,Mine_ScriptTextOut);
DetourTransactionCommit();
打破
}
返回TRUE;
}
因此,detour函数按预期工作,但printStack()函数会打印一些wierd结果。。。在这里,看一看:

你可能会问,为什么会这样?嗯,我希望找到调用ScriptTextOut的函数,但是“Mine_ScriptTextOut”之前的函数是“ScriptApplyDigitsSubstitution”,虽然这两个函数明显相关,但一个函数不调用另一个函数

在注入的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;
}
#包括
#包括
#包括
void printStack()
{
无符号整数i;
void*stack[100];
无符号短帧;
符号信息*符号;
处理过程;
process=GetCurrentProcess();
SymInitialize(进程,NULL,TRUE);
frames=capturestacktrace(0,100,stack,NULL);
symbol=(symbol_INFO*)calloc(sizeof(symbol_INFO)+256*sizeof(char),1);
symbol->MaxNameLen=255;
symbol->SizeOfStruct=sizeof(symbol\U信息);
对于(i=0;i名称,符号->地址);
}
免费(符号);
}
void dontprint()
{
}
void foo()
{
printStack();
}
无效测试()
{
dontprint();
foo();
}
int main()
{
dontprint();
test();
返回0;
}
以下是正确的输出:


知道发生了什么吗?

如果使用帧指针省略进行编译,堆栈跟踪可能不会100%准确。我不会使用帧指针省略进行编译,因此我认为这不是问题所在……更重要的是,如果您注入的程序(或由此调用的库)使用帧指针省略进行编译,您将遇到您描述的类型的问题。因此,要获得准确的堆栈跟踪,我真的无能为力?@Noob程序员如果您有这些库的源代码,您可以重新编译。否则,它们会忽略帧指针,仅此而已。
#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;
}