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

提取符号偏移地址

使用DIA接口获取符号的偏移地址


#include <windows.h>// DIA headers must come after windows headers.
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#endif
#include <dia2.h>
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#include <diacreate.h>//
#include <wrl/client.h>#include <iostream>#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/types/expected.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_com_initializer.h"namespace switches {
constexpr char kSymbolName[] = "symbol";
constexpr char kSymbolServer[] = "srv";
constexpr char kPdb[] = "pdb";
constexpr char kImage[] = "image";
}  // namespace switchesnamespace {
// clang-format off
constexpr wchar_t kDefaultSymbolSearchPath[] =L"SRV*D:\\SYMBOL.NT*https://msdl.microsoft.com/download/symbols"L";SRV*D:\\SYMBOL.NT*https://chromium-browser-symsrv.commondatastorage.googleapis.com";
// clang-format onconst std::wstring& SymbolServer() {static base::NoDestructor<std::wstring> srv([]{base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();if (command_line->HasSwitch(switches::kSymbolServer)) {return std::wstring(command_line->GetSwitchValueNative(switches::kSymbolServer));}return std::wstring(kDefaultSymbolSearchPath);}());return *srv;
}HRESULT CreateDiaSessionFromPdb(const std::wstring& pdb_path,IDiaSession** dia_session) {Microsoft::WRL::ComPtr<IDiaDataSource> dia_data_source;HRESULT hr = ::NoRegCoCreate(L"msdia140.dll", __uuidof(DiaSource),IID_PPV_ARGS(&dia_data_source));if (FAILED(hr)) {return hr;}hr = dia_data_source->loadDataFromPdb(pdb_path.c_str());if (FAILED(hr)) {return hr;}hr = dia_data_source->openSession(dia_session);if (FAILED(hr)) {return hr;}return S_OK;
}HRESULT CreateDiaSessionForImage(const std::wstring& image_path,IDiaSession** dia_session) {Microsoft::WRL::ComPtr<IDiaDataSource> dia_data_source;HRESULT hr = ::NoRegCoCreate(L"msdia140.dll", __uuidof(DiaSource),IID_PPV_ARGS(&dia_data_source));if (FAILED(hr)) {return hr;}hr = dia_data_source->loadDataForExe(image_path.c_str(),SymbolServer().c_str(), nullptr);if (FAILED(hr)) {return hr;}hr = dia_data_source->openSession(dia_session);if (FAILED(hr)) {return hr;}return S_OK;
}struct RAVResult {RAVResult(ULONGLONG rav, std::vector<std::string> lines): rav(rav), lines(std::move(lines)) {}RAVResult(const RAVResult&) = default;RAVResult& operator=(const RAVResult&) = default;~RAVResult() = default;ULONGLONG rav;std::vector<std::string> lines;
};base::expected<std::vector<std::string>, HRESULT> GetSymbolLocation(IDiaSession* session,IDiaSymbol* symbol) {DWORD rva = 0;HRESULT hr = symbol->get_relativeVirtualAddress(&rva);if (FAILED(hr)) {return base::unexpected(hr);}Microsoft::WRL::ComPtr<IDiaEnumLineNumbers> lines;ULONGLONG length = 0;hr = symbol->get_length(&length);if (FAILED(hr)) {return base::unexpected(hr);}hr = session->findLinesByRVA(rva, (DWORD)length, &lines);if (FAILED(hr)) {return base::unexpected(hr);}std::vector<std::string> result;ULONG c = 0;Microsoft::WRL::ComPtr<IDiaLineNumber> line;while (SUCCEEDED(lines->Next(1, line.ReleaseAndGetAddressOf(), &c)) &&c == 1) {DWORD line_number;base::win::ScopedBstr filename;if (FAILED(line->get_lineNumber(&line_number))) {continue;}Microsoft::WRL::ComPtr<IDiaSourceFile> source_file;if (FAILED(line->get_sourceFile(source_file.ReleaseAndGetAddressOf()))) {continue;}if (FAILED(source_file->get_fileName(filename.Receive()))) {continue;}if (filename.Get()) {result.push_back(base::StringPrintf("%s(%d)", base::SysWideToUTF8(filename.Get()).c_str(), line_number));}}return base::ok(std::move(result));
}base::expected<std::vector<RAVResult>, HRESULT> GetRAVForSymbol(IDiaSession* session,const std::wstring& symbol) {Microsoft::WRL::ComPtr<IDiaSymbol> global_symbol;HRESULT hr = session->get_globalScope(global_symbol.GetAddressOf());if (FAILED(hr)) {return base::unexpected(hr);}Microsoft::WRL::ComPtr<IDiaEnumSymbols> dia_enum_symbols;hr = global_symbol->findChildrenEx(SymTagFunction, symbol.c_str(), nsNone,dia_enum_symbols.GetAddressOf());if (FAILED(hr)) {return base::unexpected(hr);}std::vector<RAVResult> results;ULONG celt = 0;Microsoft::WRL::ComPtr<IDiaSymbol> dia_symbol;while (SUCCEEDED(dia_enum_symbols->Next(1, dia_symbol.ReleaseAndGetAddressOf(), &celt)) &&celt == 1) {ULONGLONG rav;dia_symbol->get_virtualAddress(&rav);auto lines = GetSymbolLocation(session, dia_symbol.Get());results.emplace_back(rav, lines.has_value() ? std::move(lines.value()): std::vector<std::string>{});}return base::ok(std::move(results));
}void PrintUseage() {}
}int main(int argc, char** argv) {base::AtExitManager at_exit;base::CommandLine::Init(0, nullptr);base::win::ScopedCOMInitializer scoped_com_initializer;base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();Microsoft::WRL::ComPtr<IDiaSession> dia_session;if (command_line->HasSwitch(switches::kPdb)) {if (FAILED(CreateDiaSessionFromPdb(command_line->GetSwitchValueNative(switches::kPdb),dia_session.ReleaseAndGetAddressOf()))) {return -1;}} else {if (!command_line->HasSwitch(switches::kImage)) {PrintUseage();return -1;}if (FAILED(CreateDiaSessionForImage(command_line->GetSwitchValueNative(switches::kImage),dia_session.ReleaseAndGetAddressOf()))) {return -1;}}CHECK(dia_session);if (!command_line->HasSwitch(switches::kSymbolName)) {PrintUseage();return -1;}auto result = GetRAVForSymbol(dia_session.Get(),command_line->GetSwitchValueNative(switches::kSymbolName));if (result.has_value()) {for (const auto& rav : result.value()) {std::cout << "RAV: " << rav.rav;if (!rav.lines.empty()) {std::cout << "\n\t" << rav.lines[0];}std::cout<< std::endl;}} else {return result.error();}return 0;
}
http://www.gsyq.cn/news/229.html

相关文章:

  • nvm管理node
  • LG10641
  • LG11068
  • scp拷贝文件报错
  • 11.1 定义类和对象
  • C++小白修仙记_LeetCode刷题_队列
  • Fastjson 1.2.47 远程代码执行
  • MySQL事务
  • Python面向对象
  • buntu22.04 LTS安装docker以及docker-compose实践
  • 20分钟快速入门Docker
  • K8S的基础概念
  • 如何搭建K8S集群
  • 解决 .NET 7 在 Linux 上获取程序集的问题
  • MyBatis-Plus 实现PostgreSQL数据库jsonb类型的保存与查询
  • katalon常用定位元素Xpath合集
  • (期望)名字(name)
  • MathType7下载安装2025最新下载+安装+教程(附安装包)
  • 模板 AE PR 达芬奇 剪影
  • 如何自动删除重复执行的任务?
  • 开始更新第一篇
  • springboot~SpringData自定义Repository的正确方式
  • Linux之进程状态
  • 2. O(NlogN)的排序
  • React-手写支持多文件、并行上传、串行上传、分片上传、单文件上传、失败自动重试、自动上传/手动按钮上传切换
  • postcss-px-to-viewport-8-plugin无法转换tailwindcss样式问题
  • 82、SpringMVC 参数传递,浏览器和服务器之间的数据传输
  • 问卷调查数据库设计
  • Linux 系统调用详解与工作机制
  • The 2025 Sichuan Provincial Collegiate Programming Contest