//www.pudn.com > EVEmu-0.6.253.rar > sym_engine.cpp
/*
Copyright (c) 2001 - 2002
Author: Konstantin Boukreev
E-mail: konstantin@mail.primorye.ru
Created: 25.12.2001 19:41:07
Version: 1.0.2
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation. Konstantin Boukreev makes no representations
about the suitability of this software for any purpose.
It is provided "as is" without express or implied warranty.
*/
#if (_WIN32_WINNT < 0x0400)
#error This now requires an NT based system.
#endif
#ifndef _UNICODE
#define _T(x) x
#endif
#include "../common.h"
#include "sym_engine.h"
#include <CRTDBG.H>
#include <MALLOC.H>
#include <TLHELP32.H>
#pragma comment (lib, "dbghelp")
#ifdef VERIFY
#undef VERIFY
#endif // VERIFY
#ifdef _DEBUG
#define VERIFY(x) _ASSERTE(x)
#else
#define VERIFY(x) (x)
#endif //_DEBUG
#define WORK_AROUND_SRCLINE_BUG
#ifdef _DEBUG
//#if 1
// #define SYM_ENGINE_TRACE_SPIN_COUNT
#endif //_DEBUG
///////////////////////////////////////////////////////////////////////
/*static bool IsNT()
{
#if 1
OSVERSIONINFO vi = { sizeof(vi)};
::GetVersionEx(&vi);
return vi.dwPlatformId == VER_PLATFORM_WIN32_NT;
#else
return false;
#endif
}*/
HANDLE SymGetProcessHandle()
{
// if (IsNT())
// if (0)
return GetCurrentProcess();
// else
// return (HANDLE)GetCurrentProcessId();
}
BOOL __stdcall My_ReadProcessMemory (HANDLE, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead)
{
return ReadProcessMemory(GetCurrentProcess(), lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}
///////////////////////////////////////////////////////////////////////
sym_engine::sym_engine (unsigned address)
: m_address(address), m_ok(false), m_pframe(0)
{
}
sym_engine::~sym_engine()
{
// if (m_ok) guard::instance().clear();
delete m_pframe;
}
unsigned sym_engine::module(char * buf, unsigned len)
{
if (!len || !buf || IsBadWritePtr(buf, len))
return 0;
if (!check())
return 0;
HANDLE hProc = SymGetProcessHandle();
HMODULE hMod = (HMODULE)SymGetModuleBase (hProc, m_address);
if (!hMod) return 0;
return get_module_basename(hMod, buf, len);
}
unsigned sym_engine::symbol(char * buf, unsigned len, unsigned * pdisplacement)
{
if (!len || !buf ||
IsBadWritePtr(buf, len) ||
(pdisplacement && IsBadWritePtr(pdisplacement, sizeof(unsigned))))
return 0;
if (!check())
return 0;
BYTE symbol [ 512 ] ;
PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)&symbol;
memset(pSym, 0, sizeof(symbol)) ;
pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL) ;
pSym->MaxNameLength = sizeof(symbol) - sizeof(IMAGEHLP_SYMBOL);
HANDLE hProc = SymGetProcessHandle();
DWORD displacement = 0;
int r = SymGetSymFromAddr(hProc, m_address, &displacement, pSym);
if (!r) return 0;
if (pdisplacement)
*pdisplacement = displacement;
r = _snprintf(buf, len, "%s()", pSym->Name);
r = r == -1 ? len - 1 : r;
buf[r] = 0;
return r;
}
unsigned sym_engine::fileline (char * buf, unsigned len, unsigned * pline, unsigned * pdisplacement)
{
if (!len || !buf ||
IsBadWritePtr(buf, len) ||
(pline && IsBadWritePtr(pline, sizeof(unsigned))) ||
(pdisplacement && IsBadWritePtr(pdisplacement, sizeof(unsigned))))
return 0;
if (!check())
return 0;
IMAGEHLP_LINE img_line;
memset(&img_line, 0, sizeof(IMAGEHLP_LINE));
img_line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
HANDLE hProc = SymGetProcessHandle();
unsigned displacement = 0;
if (!get_line_from_addr(hProc, m_address, &displacement, &img_line))
return 0;
if (pdisplacement)
*pdisplacement = displacement;
if (pline)
*pline = img_line.LineNumber;
lstrcpynA(buf, img_line.FileName, len);
return lstrlenA(buf);
}
bool sym_engine::stack_first (CONTEXT* pctx)
{
if (!pctx || IsBadReadPtr(pctx, sizeof(CONTEXT)))
return false;
if (!check())
return false;
if (!m_pframe)
{
m_pframe = new STACKFRAME;
if (!m_pframe) return false;
}
memset(m_pframe, 0, sizeof(STACKFRAME));
#ifdef _X86_
m_pframe->AddrPC.Offset = pctx->Eip;
m_pframe->AddrPC.Mode = AddrModeFlat;
m_pframe->AddrStack.Offset = pctx->Esp;
m_pframe->AddrStack.Mode = AddrModeFlat;
m_pframe->AddrFrame.Offset = pctx->Ebp;
m_pframe->AddrFrame.Mode = AddrModeFlat;
#else
m_pframe->AddrPC.Offset = (DWORD)pctx->Fir;
m_pframe->AddrPC.Mode = AddrModeFlat;
m_pframe->AddrReturn.Offset = (DWORD)pctx->IntRa;
m_pframe->AddrReturn.Mode = AddrModeFlat;
m_pframe->AddrStack.Offset = (DWORD)pctx->IntSp;
m_pframe->AddrStack.Mode = AddrModeFlat;
m_pframe->AddrFrame.Offset = (DWORD)pctx->IntFp;
m_pframe->AddrFrame.Mode = AddrModeFlat;
#endif
m_pctx = pctx;
return stack_next();
}
bool sym_engine::stack_next ()
{
if (!m_pframe || !m_pctx)
{
_ASSERTE(0);
return false;
}
if (!m_ok)
{
_ASSERTE(0);
return false;
}
SetLastError(0);
HANDLE hProc = SymGetProcessHandle();
BOOL r = StackWalk (IMAGE_FILE_MACHINE_I386,
hProc,
GetCurrentThread(),
m_pframe,
m_pctx,
(PREAD_PROCESS_MEMORY_ROUTINE)My_ReadProcessMemory,
SymFunctionTableAccess,
SymGetModuleBase,
0);
if (!r ||
!m_pframe->AddrFrame.Offset)
{
return false;
}
// "Debugging Applications" John Robbins
// Before I get too carried away and start calculating
// everything, I need to double-check that the address returned
// by StackWalk really exists. I've seen cases in which
// StackWalk returns TRUE but the address doesn't belong to
// a module in the process.
DWORD dwModBase = SymGetModuleBase (hProc, m_pframe->AddrPC.Offset);
if (!dwModBase)
{
_ASSERTE(0);
return false;
}
address(m_pframe->AddrPC.Offset);
return true;
}
bool sym_engine::get_line_from_addr (HANDLE hProc, unsigned addr, unsigned * pdisplacement, IMAGEHLP_LINE * pLine)
{
#ifdef WORK_AROUND_SRCLINE_BUG
// "Debugging Applications" John Robbins
// The problem is that the symbol engine finds only those source
// line addresses (after the first lookup) that fall exactly on
// a zero displacement. I'll walk backward 100 bytes to
// find the line and return the proper displacement.
DWORD displacement = 0 ;
while (!SymGetLineFromAddr (hProc, addr - displacement, (DWORD*)pdisplacement, pLine))
{
if (100 == ++displacement)
return false;
}
C_Exception_Catch.rar_vc 异常_异常处理
版权申诉
165 浏览量
2022-09-23
09:35:16
上传
评论
收藏 31KB RAR 举报
寒泊
- 粉丝: 74
- 资源: 1万+
最新资源
- 基于51单片机的蓝牙避障小车源码.zip
- esp8266wifi模块教程: 《嵌入式编程与网络通信:C语言操作ESP8266 WiFi模块》-涵盖嵌入式系统、网络编程、
- 毕业设计基于SSM和SpringBoot的动态旅游网站.zip
- 基于51单片机的mp3播放器源码+原理图+参考资料.zip
- 随机森林回归预测模型的构建与应用.zip
- 《Python文本挖掘实战:词频统计高效教程》-计算机科学·Python编程·文本分析·数据预处理
- 基于51单片机的自动浇水器设计源码+原理图pcb+使用说明.zip
- 《机器学习评估:Python混淆矩阵实战》-涵盖模型评估、分类算法,助力精准度与召回率分析,适用于数据科学和人工智能领域
- 企业大数据治理管理平台解决方案.pptx
- 基于51单片机的矩阵键盘密码锁源码.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈