吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 14964|回复: 30
收起左侧

[调试逆向] 逆向基础之一

  [复制链接]
BeneficialWeb 发表于 2019-4-4 23:16
本帖最后由 BeneficialWeb 于 2019-7-7 09:23 编辑

1.    调试器是如何实现栈回溯的?
因为函数调用指令会将函数的返回地址记录在栈上,因此可以通过从栈顶向下遍历每个栈帧来追溯函数调用的过程。
知识背景
1.源代码级调试、栈回溯、按名称显示变量等功能的实现,都离不开调试符号。
2.调试符号是在编译器在将源文件编译为可执行程序的过程中,为支持调试而摘录的调试信息。调试信息包括变量,类型,函数名,源代码行等。
3.PDB,ProgramDataBase, 微软用于描述源程序的数据库。
4.可以通过DbgHelp函数库或者DIASDK两种方式来访问调试符号文件中的符号。
5.栈帧就是利用寄存器访问栈内局部变量、参数、函数返回地址等的手段。指向每个栈帧的指针被称为帧指针。遍历整个栈中的所有栈帧,便可以得到函数调用序列。
在通过DbgHelp函数库返回地址对应的符号,便可以得到栈回溯信息。
以下是我在文件夹中找到的dbghelp.dll的身影。

X64dbg
1.png

OllyDbg
2.png
接下来是我在其它地方学习来的的代码
[C++] 纯文本查看 复制代码
#include <windows.h>
#include <dbghelp.h>
#include <iostream>
#include<iomanip>
#include<vector>

#pragma comment(lib, "dbghelp.lib")

bool PrintCallStackBackTrace() 
{
        DWORD options = SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES;
        SymSetOptions(options);
        CONTEXT context = { 0 };
        RtlCaptureContext(&context);
        STACKFRAME64 stack = { 0 };
        stack.AddrPC.Offset = context.Eip;
        stack.AddrPC.Mode = AddrModeFlat;
        stack.AddrStack.Offset = context.Esp;
        stack.AddrStack.Mode = AddrModeFlat;
        stack.AddrFrame.Offset = context.Ebp;
        stack.AddrFrame.Mode = AddrModeFlat;
        std::vector<DWORD_PTR> backtrace;
        std::string path =
                R"(SRV*D:\symbols*https://msdl.microsoft.com/download/symbols)";
        BOOL result = SymInitialize(GetCurrentProcess(), path.c_str(), TRUE);
        if (!result) {
                DWORD error = GetLastError();
                std::cout << "SymInitialize returned error : " << error << std::endl;
        }
        while (StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(),
                GetCurrentThread(), &stack, &context, NULL,
                SymFunctionTableAccess64, SymGetModuleBase64, NULL)) 
        {
                backtrace.push_back(stack.AddrPC.Offset);
        }
        for (DWORD index = 0; index < backtrace.size(); index++) 
        {
                DWORD_PTR frame = backtrace[index];
                const int kMaxNameLength = 256;
                ULONG64 buffer[(sizeof(SYMBOL_INFO) + kMaxNameLength * sizeof(wchar_t) +
                        sizeof(ULONG64) - 1) /
                        sizeof(ULONG64)];
                memset(buffer, 0, sizeof(buffer));
                DWORD64 sym_displacement = 0;
                PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(&buffer[0]);
                symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
                symbol->MaxNameLen = kMaxNameLength - 1;
                BOOL has_symbol =
                        SymFromAddr(GetCurrentProcess(), frame, &sym_displacement, symbol);
                DWORD line_displacement = 0;
                IMAGEHLP_LINE64 line = {};
                line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
                BOOL has_line = SymGetLineFromAddr64(GetCurrentProcess(), frame,
                        &line_displacement, &line);
                std::cout <<"0x"<< std::left << std::hex << std::setw(12) << frame;
                if (has_symbol) {
                        std::cout <<std::setw(5)<< symbol->Name << "\t";
                }
                std::cout << std::endl;
        }
        result = SymCleanup(GetCurrentProcess());
        return true;
}
void f() 
{
        PrintCallStackBackTrace();
}
int main() 
{
        f();
        system("pause");
        return 0;
}



删除pdb之前的运行效果
b.png success.png

删除pdb之后的运行效果
a.png fail.png
这是我的学习笔记,如有错误的地方,望大佬们指出
最后我有一个疑问,为什么我用OD调试OD过程中,对SymFromAddr下断点,没有断下来???

免费评分

参与人数 12吾爱币 +14 热心值 +12 收起 理由
xmxZhang + 1 + 1 谢谢@Thanks!
bbn + 1 + 1 我很赞同!
zhongjiezhe + 1 + 1 我很赞同!
会喊⑥⑥的咸鱼 + 1 + 1 热心回复!
weiwei321 + 1 + 1 我很赞同!
nj001 + 1 + 1 我很赞同!
店小三丶 + 1 + 1 热心回复!
GGbond + 1 + 1 热心回复!
小俊 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wangxp + 1 + 1 谢谢@Thanks!
涛之雨 + 3 + 1 用心讨论,共获提升!
欲为大树。 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

涛之雨 发表于 2019-4-5 10:14
收藏收听慢慢看 ̄  ̄)σ
现在木有电脑
世不待 发表于 2019-4-5 07:26
头像被屏蔽
lane1234 发表于 2019-4-5 08:00
goldengod 发表于 2019-4-5 09:02
进来学习. 感谢分享

yaoyao7 发表于 2019-4-5 10:51
这是打算一直更新到10000吗?
冥界3大法王 发表于 2019-4-5 10:53
yaoyao7 发表于 2019-4-5 10:51
这是打算一直更新到10000吗?

到死也看不完啊。
ll5595936 发表于 2019-4-5 12:10

喜欢!谢谢分享!
dns2018 发表于 2019-4-5 12:22
学习快乐!多学学哈
wwdzwo 发表于 2019-4-5 17:41
进来学习. 感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 21:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表