예제 #1
0
파일: minidump.c 프로젝트: howard5888/wineT
/******************************************************************
 *		fetch_pe_module_info_cb
 *
 * Callback for accumulating in dump_context a PE modules set
 */
static BOOL WINAPI fetch_pe_module_info_cb(char* name, DWORD base, DWORD size,
                                           void* user)
{
    struct dump_context*        dc = (struct dump_context*)user;
    IMAGE_NT_HEADERS            nth;

    if (pe_load_nt_header(dc->hProcess, base, &nth))
        add_module((struct dump_context*)user, name, base, size, 
                   nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum,
                   FALSE);
    return TRUE;
}
예제 #2
0
/******************************************************************
 *		fetch_pe_module_info_cb
 *
 * Callback for accumulating in dump_context a PE modules set
 */
static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size,
                                           PVOID user)
{
    struct dump_context*        dc = user;
    IMAGE_NT_HEADERS            nth;

    if (!validate_addr64(base)) return FALSE;

    if (pe_load_nt_header(dc->hProcess, base, &nth))
        add_module(user, name, base, size,
                   nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum,
                   FALSE);
    return TRUE;
}
예제 #3
0
/******************************************************************
 *		pe_load_builtin_module
 *
 */
struct module* pe_load_builtin_module(struct process* pcs, const WCHAR* name,
                                      DWORD64 base, DWORD64 size)
{
    struct module*      module = NULL;

    if (base && pcs->dbg_hdr_addr)
    {
        IMAGE_NT_HEADERS    nth;

        if (pe_load_nt_header(pcs->handle, base, &nth))
        {
            if (!size) size = nth.OptionalHeader.SizeOfImage;
            module = module_new(pcs, name, DMT_PE, FALSE, base, size,
                                nth.FileHeader.TimeDateStamp,
                                nth.OptionalHeader.CheckSum);
        }
    }
    return module;
}
예제 #4
0
/* machLoadDebugInfo(): attempts to load the debug information for the module identified by 
     <module>.  If <map> is NULL, the dylib name is generated from the image name stored 
     in <module> and the file's header and debug information is read into <map> if found.
     If <map> is non-NULL, it is assumed that the debug information has already been read
     into it, and parses from that instead.  Returns TRUE if the file was found, successfully 
     opened, and had its debug information parsed.  Returns FALSE on failure. */
BOOL machLoadDebugInfo(struct process *pcs, struct module *module, MachMap *map){
    MachMap _map;
    BOOL    opened = FALSE;
    BOOL    ret = FALSE;
    int     i;
    DWORD64 loadOffset = 0;


    TRACE("loading the debug information for %s {module = %p, map = %p}\n", debugstr_w(module->module.LoadedImageName), module, map);

    /* the file has not been mapped yet => map it now */
    if (map == NULL){
        /* this isn't a mach file or it couldn't be loaded => fail */
        if (!machIsMachFile(module->module.LoadedImageName, NULL, &_map)){
            ERR("could not map the image file %s into memory\n", debugstr_w(module->module.LoadedImageName));

            return FALSE;
        }

        map = &_map;
        opened = TRUE;
    }


    /* try to retrieve the load offset from the NT header.  The module base address that is passed
       into machLoadModule() and that is stored in 'module->module.BaseOfImage' is not entirely the
       correct address.  The symbol addresses stored in the debug information are relative to the
       start of the mach module itself, and that always seems to load at an address 0x2000 bytes
       below the module's base address.  Unfortunately, all the addresses that get passed to the
       SymFromAddr() function are relative to the address stored in 'module->module.BaseOfImage.
       Happily, the offset between these two addresses is stored in the module's header for the
       text section (IMAGE_SECTION_HEADER).  We'll attempt to grab the offset from there instead
       of hardcoding it.  The load offset will be applied to all the symbol addresses as they are
       parsed. */
    if (module->module.BaseOfImage){
        IMAGE_NT_HEADERS nt;


        /* read the NT header => attempt to grab a section header and extract the load offset */
        if (pe_load_nt_header(pcs->handle, module->module.BaseOfImage, &nt)){
            IMAGE_SECTION_HEADER    sec;
            int                     i;


            for (i = 0; i < nt.FileHeader.NumberOfSections; i++){
                if (pe_load_nt_sect_header(pcs->handle, module->module.BaseOfImage, i, &nt, &sec)){
                    if (!strcmp((char *)sec.Name, ".text")){
                        loadOffset = (DWORD64)(signed)sec.VirtualAddress;

                        break;
                    }
                }
            }

            if (loadOffset == 0)
                WARN("could not find a valid text section header.  Assuming a load offset of 0.  Symbol lookups will fail in this module\n");
        }

        else{
            /* HACK!!!  This value seems to be the correct offset for our modules, but we
                        couldn't calculate it because this module isn't currently loaded.
                        Setting this offset here allows symbols from non-resident modules
                        to still be looked up by address (assuming the base address was
                        correctly specified as well). */
            loadOffset = -0x2000ll;
            FIXME("module could not be read from.  Assuming a load offset of 0x%08llx\n", loadOffset);
        }
    }

    else
        ERR("no module base specified or found.  Symbol lookups in this module will fail!\n");



    for (i = 0; i < map->numLoadCmds; i++){
        switch (map->loadCmds[i].header->cmd){
            case LC_SYMTAB:
                TRACE("parsing the STABS debug information {BaseOfImage = 0x%08llx, loadOffset = 0x%08llx}\n", 
                        module->module.BaseOfImage,
                        loadOffset);

                ret = stabs_parse(  module,
                                    module->module.BaseOfImage + loadOffset,
                                    map->loadCmds[i].data.stabs.stab,
                                    map->loadCmds[i].data.stabs.stabSize,
                                    (const char *)map->loadCmds[i].data.stabs.strings,
                                    map->loadCmds[i].data.stabs.stringsSize);

                TRACE("%s the STABS debug information\n", ret ? "SUCCESSFULLY loaded" : "FAILED to load");
                break;

            case LC_DYSYMTAB:
                /* FIXME!! figure out if we need to load or fixup anything from this table */
                FIXME("figure out if we need to load or fixup anything from the dynamic symbol table\n");
                break;

            default:
                continue;
        }
    }


    TRACE("done loading debug information for %s\n", debugstr_w(module->module.LoadedImageName));

    if (opened)
        machUnmapFile(map);

    return ret;
}