吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15790|回复: 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++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#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, 2025-4-6 04:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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