⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pe_module.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * File pe_module.c - handle PE module information
 *
 * Copyright (C) 1996,      Eric Youngdale.
 * Copyright (C) 1999-2000, Ulrich Weigand.
 * Copyright (C) 2004,      Eric Pouech.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "dbghelp_private.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);

/******************************************************************
 *		pe_load_stabs
 *
 * look for stabs information in PE header (it's how the mingw compiler provides 
 * its debugging information)
 */
static BOOL pe_load_stabs(const struct process* pcs, struct module* module, 
                          const void* mapping, IMAGE_NT_HEADERS* nth)
{
    IMAGE_SECTION_HEADER*       section;
    int                         i, stabsize = 0, stabstrsize = 0;
    unsigned int                stabs = 0, stabstr = 0;
    BOOL                        ret = FALSE;

    section = (IMAGE_SECTION_HEADER*)
        ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
    for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
    {
        if (!strcasecmp(section->Name, ".stab"))
        {
            stabs = section->VirtualAddress;
            stabsize = section->SizeOfRawData;
        }
        else if (!strncasecmp(section->Name, ".stabstr", 8))
        {
            stabstr = section->VirtualAddress;
            stabstrsize = section->SizeOfRawData;
        }
    }

    if (stabstrsize && stabsize)
    {
        ret = stabs_parse(module, 
                          module->module.BaseOfImage - nth->OptionalHeader.ImageBase, 
                          RtlImageRvaToVa(nth, (void*)mapping, stabs, NULL),
                          stabsize,
                          RtlImageRvaToVa(nth, (void*)mapping, stabstr, NULL),
                          stabstrsize);
    }
    return ret;
}

static BOOL CALLBACK dbg_match(char* file, void* user)
{
    /* accept first file */
    return FALSE;
}

/******************************************************************
 *		pe_load_dbg_file
 *
 * loads a .dbg file
 */
static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
                             const char* dbg_name, DWORD timestamp)
{
    char                                tmp[MAX_PATH];
    HANDLE                              hFile = INVALID_HANDLE_VALUE, hMap = 0;
    const BYTE*                         dbg_mapping = NULL;
    const IMAGE_SEPARATE_DEBUG_HEADER*  hdr;
    const IMAGE_DEBUG_DIRECTORY*        dbg;
    BOOL                                ret = FALSE;

    WINE_TRACE("Processing DBG file %s\n", dbg_name);

    if (SymFindFileInPath(pcs->handle, NULL, (char*)dbg_name, 
                          NULL, 0, 0, 0,
                          tmp, dbg_match, NULL) &&
        (hFile = CreateFileA(tmp, GENERIC_READ, FILE_SHARE_READ, NULL, 
                             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE &&
        ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) &&
        ((dbg_mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL))
    {
        hdr = (const IMAGE_SEPARATE_DEBUG_HEADER*)dbg_mapping;
        if (hdr->TimeDateStamp != timestamp)
        {
            WINE_ERR("Warning - %s has incorrect internal timestamp\n",
                     dbg_name);
            /*
             * Well, sometimes this happens to DBG files which ARE REALLY the
             * right .DBG files but nonetheless this check fails. Anyway,
             * WINDBG (debugger for Windows by Microsoft) loads debug symbols
             * which have incorrect timestamps.
             */
        }
        if (hdr->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
        {
            /* section headers come immediately after debug header */
            const IMAGE_SECTION_HEADER *sectp =
                (const IMAGE_SECTION_HEADER*)(hdr + 1);
            /* and after that and the exported names comes the debug directory */
            dbg = (const IMAGE_DEBUG_DIRECTORY*) 
                (dbg_mapping + sizeof(*hdr) + 
                 hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
                 hdr->ExportedNamesSize);


            ret = pe_load_debug_directory(pcs, module, dbg_mapping, sectp,
                                          hdr->NumberOfSections, dbg,
                                          hdr->DebugDirectorySize / sizeof(*dbg));
        }
        else
            ERR("Wrong signature in .DBG file %s\n", debugstr_a(tmp));
    }
    else
        WINE_ERR("-Unable to peruse .DBG file %s (%s)\n", dbg_name, debugstr_a(tmp));

    if (dbg_mapping) UnmapViewOfFile((void*)dbg_mapping);
    if (hMap) CloseHandle(hMap);
    if (hFile != NULL) CloseHandle(hFile);
    return ret;
}

/******************************************************************
 *		pe_load_msc_debug_info
 *
 * Process MSC debug information in PE file.
 */
static BOOL pe_load_msc_debug_info(const struct process* pcs, 
                                   struct module* module,
                                   const void* mapping, IMAGE_NT_HEADERS* nth)
{
    BOOL                        ret = FALSE;
    const IMAGE_DATA_DIRECTORY* dir;
    const IMAGE_DEBUG_DIRECTORY*dbg = NULL;
    int                         nDbg;

    /* Read in debug directory */
    dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
    nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
    if (!nDbg) return FALSE;

    dbg = RtlImageRvaToVa(nth, (void*)mapping, dir->VirtualAddress, NULL);

    /* Parse debug directory */
    if (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED)
    {
        /* Debug info is stripped to .DBG file */
        const IMAGE_DEBUG_MISC* misc = (const IMAGE_DEBUG_MISC*)
            ((const char*)mapping + dbg->PointerToRawData);

        if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC ||
            misc->DataType != IMAGE_DEBUG_MISC_EXENAME)
        {
            WINE_ERR("-Debug info stripped, but no .DBG file in module %s\n",
                     module->module.ModuleName);
        }
        else
        {
            ret = pe_load_dbg_file(pcs, module, misc->Data, nth->FileHeader.TimeDateStamp);
        }
    }
    else
    {
        const IMAGE_SECTION_HEADER *sectp = (const IMAGE_SECTION_HEADER*)((const char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
        /* Debug info is embedded into PE module */
        ret = pe_load_debug_directory(pcs, module, mapping, sectp,
            nth->FileHeader.NumberOfSections, dbg, nDbg);
    }

    return ret;
}

/***********************************************************************
 *			pe_load_export_debug_info
 */
static BOOL pe_load_export_debug_info(const struct process* pcs, 
                                      struct module* module, 
                                      const void* mapping, IMAGE_NT_HEADERS* nth)
{
    unsigned int 		        i;
    const IMAGE_EXPORT_DIRECTORY* 	exports;
    DWORD			        base = module->module.BaseOfImage;
    DWORD                               size;

    if (dbghelp_options & SYMOPT_NO_PUBLICS) return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -