使用WINAPI(如CaptureStackBackTrace()或StackWalk64())遍历调用堆栈 [英] walking the call stack using WINAPI like CaptureStackBackTrace() or StackWalk64()

查看:361
本文介绍了使用WINAPI(如CaptureStackBackTrace()或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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆