使用WINAPI(如CaptureStackBackTrace()或StackWalk64())遍历调用堆栈 [英] walking the call stack using WINAPI like CaptureStackBackTrace() or StackWalk64()
问题描述
大家好,如果已经在论坛上提出要求,我很抱歉。我想在我的一个项目中浏览堆栈。我认为CaptureStackBackTrace()很容易使用,所以我从那开始。我在这里发布我的代码。
Hi All, I am sorry if its already been asked on the forum. I want to walk through the stack for one of my projects. I got the perception that CaptureStackBackTrace() is quite easy to use so I started with that. I am posting my code here.
// TestingWINAPI.cpp:定义控制台应用程序的入口点。
// TestingWINAPI.cpp : Defines the entry point for the console application.
#include" stdafx.h"
#include "stdafx.h"
#include" StackWalker.h"
#include "StackWalker.h"
#include< windows.h>
#include <windows.h>
#include< winbase.h>
#include <winbase.h>
#include< Dbghelp。 h>
#include <Dbghelp.h>
#include< stdlib.h>
#include <stdlib.h>
#include< stdio.h>
#include <stdio.h>
bool checkAPI()
bool checkAPI()
{
PVOID * stackStart = NULL;
PVOID *stackStart = NULL;
USHORT frames = CaptureStackBackTrace((ULONG)0,(ULONG)10,stackStart,NULL);
USHORT frames = CaptureStackBackTrace((ULONG)0, (ULONG)10, stackStart, NULL);
printf("找不到帧数%d \ n",帧数);
printf ("No of frames found %d\n",frames);
typedef BOOL(WINAPI * StackWalk64Type)(__ in DWORD,__在HANDLE,__ in HANDLE,__ INout LPSTACKFRAME64,__ inout PVOID,__ in_opt PREAD_PROCESS_MEMORY_ROUTINE64,__ in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64,__ in_opt PGET_MODULE_BASE_ROUTINE64,
__in_opt PTRANSLATE_ADDRESS_ROUTINE64);
typedef BOOL (WINAPI *StackWalk64Type)(__in DWORD, __in HANDLE, __in HANDLE, __inout LPSTACKFRAME64, __inout PVOID, __in_opt PREAD_PROCESS_MEMORY_ROUTINE64, __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64, __in_opt PGET_MODULE_BASE_ROUTINE64, __in_opt PTRANSLATE_ADDRESS_ROUTINE64);
跨度> StackWalk64Type FUNC1 =(StackWalk64Type)(GetProcAddress的(的LoadLibrary(QUOT; dbghelp.dll")," StackWalk64"));
StackWalk64Type func1 = (StackWalk64Type)(GetProcAddress(LoadLibrary("dbghelp.dll"), "StackWalk64"));
&NBSP;
HANDLE hProc = GetCurrentProcess();
HANDLE hProc = GetCurrentProcess();
HANDLE hThread = GetCurrentThread();
HANDLE hThread = GetCurrentThread();
STACKFRAME64 stackframe;
STACKFRAME64 stackframe;
CONTEXT context;
CONTEXT context;
memset(& context,0,sizeof(context));
memset (&context, 0, sizeof(context));
//从寄存器初始化当前上下文:
// Initialise hte current context from registers:
__ asm pop eax
__asm pop eax
__ asm mov context.Eip,eax
__asm mov context.Eip, eax
__ asm mov context.Ebp,ebp
__asm mov context.Ebp, ebp
__ asm mov context.Esp,esp
__asm mov context.Esp, esp
context.ContextFlags = CONTEXT_FULL;
context.ContextFlags = CONTEXT_FULL;
// GetThreadContext(hThread,& context);
//GetThreadContext(hThread, &context);
memset(& stackframe,0,sizeof (stackframe));
memset (&stackframe, 0, sizeof(stackframe));
stackframe.AddrPC.Offset &NBSP; &NBSP; &NBSP; = context.Eip;
stackframe.AddrPC.Offset = context.Eip;
stackframe.AddrPC.Mode &NBSP; &NBSP; &NBSP; &NBSP; = AddrModeFlat;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrStack.Offset &NBSP; = context.Esp;
stackframe.AddrStack.Offset = context.Esp;
stackframe.AddrStack.Mode &NBSP; &NBSP; = AddrModeFlat;
stackframe.AddrStack.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset &NBSP; = context.Ebp;
stackframe.AddrFrame.Offset = context.Ebp;
stackframe.AddrFrame.Mode &NBSP; &NBSP; = AddrModeFlat;
stackframe.AddrFrame.Mode = AddrModeFlat;
/ *
if(
func1(0x014c,hProc,hThread,& stackframe,& context,NULL,NULL,NULL,NULL)
)
printf(" working");
printf("working ");
else
printf("不工作");
printf("not working");
* /
返回true;
}
bool a()
{
checkAPI();
checkAPI();
返回true;
}
void b()
{
a();
}
void c()
{
b();
}
int _tmain(int argc,_TCHAR * argv [])
int _tmain(int argc, _TCHAR* argv[])
{
c();
返回0;
}
当我获得大部分代码时正在通过论坛进行搜索。如果我做错了,我很抱歉。如果我在某处错了,请你查一下这段代码。问题是CaptureStackBackTrace总是返回0.我不知道为什么它无法捕获
堆栈帧。
I got most of the code when I was seraching through forums. I am sorry if I am doing something wrong. could you please check this code, if I am wrong somewhere. The issue is CaptureStackBackTrace always returns 0. I dont why is it not able to capture the stack frames.
Stack步行64打印工作一次然后它只是中止说:
Stack walk 64 prints working once and then it just aborts saying:
运行时间检查faliure#0 - 在函数调用中没有正确保存ESP的值。这通常是调用使用一个调用约定声明的函数的结果,函数指针使用不同的调用约定声明。
Run Time check faliure #0 - The value of ESP was not prperly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
可能请问有什么问题?
谢谢
ARB
推荐答案
你好a_arb,
Hello a_arb,
的签名> CaptureStackBackTrace 函数 是:
USHORT WINAPI CaptureStackBackTrace(
__in ULONG FramesToSkip,
__in ULONG FramesToCapture,
__out PVOID *BackTrace
,
__out_opt PULONG BackTraceHash
);
但你在BackTrace参数上传递了NULL:
but you passed NULL on BackTrace parameter:
PVOID * stackStart = NULL;
USHORT frames = CaptureStackBackTrace((ULONG)0,(ULONG)10,stackStart,NULL);
但必须是这样的:
PVOID stackStart = NULL ;
USHORT frames = CaptureStackBackTrace((ULONG)0,(ULONG)10,
& stackStart,NULL);
USHORT frames = CaptureStackBackTrace((ULONG)0, (ULONG)10, & stackStart, NULL);
谢谢,
彼得
这篇关于使用WINAPI(如CaptureStackBackTrace()或StackWalk64())遍历调用堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!