Пример #1
0
NFCallStackImp::callstack_ptr NFCallStackImp::generate(const void* pContext)
{
    if (!m_bInitialized)
    {
        _initialize();
    }

    CONTEXT Context;

    if (pContext != NULL)
    {
        ::memcpy_s(&Context, sizeof(CONTEXT), pContext, sizeof(CONTEXT));
    }
    else
    {
        ::ZeroMemory(&Context, sizeof(Context));
        Context.ContextFlags = CONTEXT_FULL;

        __asm
        {
            call FakeFuncCall
            FakeFuncCall:

            pop eax
            mov Context.Eip, eax
            mov Context.Ebp, ebp
            mov Context.Esp, esp
        }
    }

    static const int gc_iMaxStackDepth = 512;
    QWORD aryStack[gc_iMaxStackDepth] = {0};

    // 由于_stackwalk内部使用SEH 因此不能在其内部使用C++类
    _stackwalk(aryStack, gc_iMaxStackDepth, &Context);

    callstack_ptr spCallStack(new NFCallStack());

    for (int i = 0; i < gc_iMaxStackDepth && aryStack[i] != 0; ++i)
    {
        func_name name = _getfuncname(aryStack[i]);
        spCallStack->mspImp->m_lstFunc.push_back(name);
    }

    return spCallStack;
}
Пример #2
0
list<stack_line_info> get_stack_list(size_t maxDepth, size_t offset, bool module, bool symbolName)
{
	assert(maxDepth <= 32);

	QWORD trace[33];
	CONTEXT context;

	::ZeroMemory(&context, sizeof(context));
	context.ContextFlags = CONTEXT_FULL;
#ifdef _WIN64
	get_bp_sp_ip((void**)&context.Rbp, (void**)&context.Rsp, (void**)&context.Rip);
#else
	get_bp_sp_ip((void**)&context.Ebp, (void**)&context.Esp, (void**)&context.Eip);
#endif
	size_t depths = _stackwalk(trace, maxDepth+1, &context);

	list<stack_line_info> imageList;
	HANDLE hProcess = ::GetCurrentProcess();
	for (size_t i = 1 + offset; i < depths; i++)
	{
		stack_line_info stackResult;

		{
			DWORD symbolDisplacement = 0;
			IMAGEHLP_LINE64 imageHelpLine;
			imageHelpLine.SizeOfStruct = sizeof(imageHelpLine);

			if (::SymGetLineFromAddr64(hProcess, trace[i], &symbolDisplacement, &imageHelpLine))
			{
				stackResult.file = string(imageHelpLine.FileName, check_file_name(imageHelpLine.FileName));
				memset(imageHelpLine.FileName, 0, stackResult.file.size() + 1);
				stackResult.line = (int)imageHelpLine.LineNumber;
			}
			else
			{
				stackResult.line = -1;
			}
		}
		if (symbolName)
		{
			static const int maxNameLength = 1024;
			char symbolBf[sizeof(IMAGEHLP_SYMBOL64)+maxNameLength] = { 0 };
			PIMAGEHLP_SYMBOL64 symbol;
			DWORD64 symbolDisplacement64 = 0;

			symbol = (PIMAGEHLP_SYMBOL64)symbolBf;
			symbol->SizeOfStruct = sizeof(symbolBf);
			symbol->MaxNameLength = maxNameLength;

			if (::SymGetSymFromAddr64(
				hProcess,
				trace[i],
				&symbolDisplacement64,
				symbol)
				)
			{
				stackResult.symbolName = symbol->Name;
			}
			else
			{
				stackResult.symbolName = "unknow...";
			}
		}
		if (module)
		{
			IMAGEHLP_MODULE64 imageHelpModule;
			imageHelpModule.SizeOfStruct = sizeof(imageHelpModule);

			if (::SymGetModuleInfo64(hProcess, trace[i], &imageHelpModule))
			{
				stackResult.module = string(imageHelpModule.ImageName, check_file_name(imageHelpModule.ImageName));
				memset(imageHelpModule.ImageName, 0, stackResult.module.size() + 1);
			}
		}
		imageList.push_back(std::move(stackResult));
	}
	return std::move(imageList);
}