当前位置: 首页 > article >正文

Windows逆向工程入门之堆栈回溯

  • 公开视频 -> 链接点击跳转公开课程
  • 博客首页 -> ​​​链接点击跳转博客主页

目录

堆栈回溯

效果

代码

符号解析

符号信息

示例代码

DBG

IDA


堆栈回溯

效果

代码

#include <iostream>
#include <iomanip>


void PrintCallBack()
{
	// 栈帧结构
	int StackFrameCount = 0;

	// 栈帧获取
	int* varEbp = 0;
	__asm
	{
		mov[varEbp], ebp
	}

	// 堆栈回溯
	while (varEbp)
	{

		/*
			PrintCallBack
				[EBP + 0] -> FUN3.EBP
				[EBP + 4] -> FUN3.RETADDR

			FUN3
				[EBP + 0] -> FUN2.EBP
				[EBP + 4] -> FUN2.RETADDR



		*/

		// 返回地址
		int varRetAddr = varEbp[1];
		if (!varRetAddr) return;

		std::cout << "StackFrameCount -> " << std::setw(2) << std::setfill('0') << std::dec << StackFrameCount << "\t";
		std::cout << "RetAddr -> " << std::showbase << std::hex << varRetAddr << std::endl;

		varEbp = (int*)varEbp[0];

		StackFrameCount++;
	}

}

void Fun3()
{
	//[EBP + 0] -> FUN2.EBP
	//[EBP + 4] -> FUN2.RETADDR
	PrintCallBack();
}

void Fun2()
{
	//[EBP + 0] -> FUN1.EBP
	//[EBP + 4] -> FUN1.RETADDR
	Fun3();
}

void Fun1()
{
	//[EBP + 0] -> MAIN.EBP
	//[EBP + 4] -> MAIN.RETADDR
	Fun2();
}

int main()
{
	Fun1();

	return 0;
}

符号解析

符号信息

示例代码

#include <iostream>
#include <Windows.h>
#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")

void PrintCallBack()
{
	WORD wFrameCount = 0;
	HANDLE hProcess = NULL;
	PVOID pStack[100] = { 0 };
	SYMBOL_INFO* symInfo = NULL;

	hProcess = GetCurrentProcess();

	// 符号解析
	if (SymInitialize(hProcess, NULL, TRUE) == FALSE) return;

	// 获取栈帧
	wFrameCount = RtlCaptureStackBackTrace(1, 100, pStack, NULL);

	// 符号信息
	symInfo = (SYMBOL_INFO*)malloc(sizeof(SYMBOL_INFO) + MAX_PATH);
	memset(symInfo, 0, sizeof(SYMBOL_INFO) + MAX_PATH);
	symInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
	symInfo->MaxNameLen = 255;


	// 回溯信息
	for (size_t i = 0; i < wFrameCount; i++)
	{
		CHAR strModule[MAX_PATH] = { 0 };
		DWORD dwModuleBase = NULL;
		SymFromAddr(hProcess, (DWORD64)pStack[i], 0, symInfo);
		dwModuleBase = SymGetModuleBase(hProcess, (DWORD64)pStack[i]);
		GetModuleFileNameA((HMODULE)dwModuleBase, strModule, MAX_PATH);
		if (dwModuleBase)
		{
			std::cout << "---------------------------------------" << std::endl;
			std::cout << "ModuleName -> " << strModule << std::endl;
			std::cout << "FunctnName -> " << symInfo->Name << std::endl;
			std::cout << "FunStrAddr -> " << "0x" << std::hex << symInfo->Address << std::endl;
			std::cout << "FunRetAddr -> " << "0x" << std::hex << (DWORD)pStack[i] << std::endl;
			std::cout << "ModuleAddr -> " << "0x" << std::hex << dwModuleBase << std::endl;

		}

	}

}

void Fun3()
{
	PrintCallBack();
}

void Fun2()
{
	Fun3();
}

void Fun1()
{
	Fun2();
}

int main()
{
	Fun1();

	return 0;
}

DBG

  • visual studio中设置工程项目属性

    • 随机基址 - 否

    • 固定基址 - 是

  • F11运行工程项目转到反汇编查看MAIN函数地址
  • DBG启动调试程序
  • CTRL + G 转到指定MAIN函数地址
  • 通过函数头部下断方式查看栈顶数据返回地址进行堆栈回溯

IDA

  • 加载指定PE文件
  • Function窗口中搜索MAIN
  • 选中函数过程名点击X展开交叉引用窗口

 


http://www.kler.cn/a/552995.html

相关文章:

  • 关于uniApp的面试题及其答案解析
  • Python在网络安全中的应用 python与网络安全
  • 萌新学 Python 之 for 循环语句
  • 设置SCP无需输入密码
  • Linux下ioctl的应用
  • 极限网关可视化——Elasticsearch 请求流量分析实战
  • docker安装kafka,并通过springboot快速集成kafka
  • 每日一题之喜糖摆放
  • 图片粘贴上传实现
  • 深入探讨优先队列:原理、实现与应用
  • 4.6 模型训练基类Trainer:Hugging Face工业级训练引擎深度剖析
  • 【0407】Postgres内核 Condition variables (ConditionVariable)设计机制 ①
  • Linux基础25-C语言之分支结构Ⅱ【入门级】
  • matplotlib 如何是的横坐标纵向显示
  • 实战开发coze应用-姓氏头像生成器(下)
  • 【开源免费】基于SpringBoot+Vue.JS医疗挂号管理系统(JAVA毕业设计)
  • python绘图之箱型图
  • 如何通过Bigemap Pro实现面合并和相交
  • 【大模型】DeepSeek 的人工智能发展之路
  • 前端对话框项目 react如何实时接收,Node.js 服务端转发Coze API响应结果详解