예제 #1
0
static void GetObjectInfo( ULONG mte )
{
    HFILE               hdl;
    ULONG               new_head;
    USHORT              type;
    unsigned_32         objoff;
    unsigned_32         numobjs;

    char                buff[CCHMAXPATH];

    if( mte == LastMTE ) {
        return;
    }
    memset( ObjInfo, 0, sizeof( ObjInfo ) );
    DosQueryModuleName( mte, sizeof( buff ), buff );
    NumObjects = 0;
    if( !FindNewHeader( buff, &hdl, &new_head, &type ) ) {
        return;
    }
    if( type != EXE_LE && type != EXE_LX ) {
        DosClose( hdl );
        return;
    }
    SeekRead( hdl, new_head + 0x40, &objoff, sizeof( objoff ) );
    SeekRead( hdl, new_head + 0x44, &numobjs, sizeof( numobjs ) );
    if( numobjs <= MAX_OBJECTS ) {
        SeekRead( hdl, new_head + objoff, ObjInfo, numobjs * sizeof( ObjInfo[0] ) );
        NumObjects = numobjs;
    }
    LastMTE = mte;
    DosClose( hdl );
}
예제 #2
0
static bool readObjectAndPageTable( ExeFileInfo *exe )
/****************************************************/
{
    RcStatus    ret;
    size_t      table_size;

    table_size = exe->u.LXInfo.OS2Head.num_objects * sizeof( object_record );
    exe->u.LXInfo.Objects = RESALLOC( table_size );
    ret = SeekRead( exe->fid,
                exe->WinHeadOffset + exe->u.LXInfo.OS2Head.objtab_off,
                exe->u.LXInfo.Objects, table_size );

    if( ret == RS_OK ) {
        table_size = exe->u.LXInfo.OS2Head.num_pages * sizeof( lx_map_entry );
        exe->u.LXInfo.Pages = RESALLOC( table_size );
        ret = SeekRead( exe->fid,
                    exe->WinHeadOffset + exe->u.LXInfo.OS2Head.objmap_off,
                    exe->u.LXInfo.Pages, table_size );
    }
    switch( ret ) {
    case RS_OK:
        break;
    case RS_READ_ERROR:
        RcError( ERR_READING_EXE, exe->name, strerror( errno ) );
        break;
    case RS_READ_INCMPLT:
        RcError( ERR_UNEXPECTED_EOF, exe->name );
        break;
    default:
        RcError( ERR_INTERNAL, INTERR_UNKNOWN_RCSTATUS );
        break;
    }
    CheckDebugOffset( exe );
    return( ret != RS_OK );
}
예제 #3
0
static RcStatus readObjectTable( ExeFileInfo *exe )
/*************************************************/
{
    RcStatus        ret;
    unsigned        objects_size;
    long            file_offset;
    exe_pe_header   *pehdr;

    pehdr = exe->u.PEInfo.WinHead;
    if( IS_PE64( *pehdr ) ) {
        objects_size = PE64( *pehdr ).num_objects * sizeof( pe_object );
        file_offset = exe->WinHeadOffset + sizeof( pe_header64 );
    } else {
        objects_size = PE32( *pehdr ).num_objects * sizeof( pe_object );
        file_offset = exe->WinHeadOffset + sizeof( pe_header );
    }
    exe->u.PEInfo.Objects = RESALLOC( objects_size );
    ret = SeekRead( exe->fid, file_offset, exe->u.PEInfo.Objects, objects_size );
    switch( ret ) {
    case RS_OK:
        break;
    case RS_READ_ERROR:
        RcError( ERR_READING_EXE, exe->name, strerror( errno ) );
        break;
    case RS_READ_INCMPLT:
        RcError( ERR_UNEXPECTED_EOF, exe->name );
        break;
    default:
        RcError( ERR_INTERNAL, INTERR_UNKNOWN_RCSTATUS );
        break;
    }
    CheckDebugOffset( exe );
    return( ret );
}
예제 #4
0
static int readObjectTable( ExeFileInfo * exe )
/*********************************************/
{
    RcStatus    error;

    exe->u.PEInfo.Objects = RcMemMalloc( exe->u.PEInfo.WinHead->num_objects
                                * sizeof(pe_object) );
    error = SeekRead( exe->Handle, exe->WinHeadOffset + sizeof(pe_header),
                exe->u.PEInfo.Objects,
                exe->u.PEInfo.WinHead->num_objects * sizeof(pe_object) );
    switch( error ) {
    case RS_OK:
        break;
    case RS_READ_ERROR:
        RcError( ERR_READING_EXE, exe->name, strerror( errno ) );
        break;
    case RS_READ_INCMPLT:
        RcError( ERR_UNEXPECTED_EOF, exe->name );
        break;
    default:
        RcError( ERR_INTERNAL, INTERR_UNKNOWN_RCSTATUS );
        break;
    }
    CheckDebugOffset( exe );
    return( error != RS_OK );
}
예제 #5
0
void Retriever::ReadPage( const unsigned_32 offset )
/**************************************************/
{
    if ( ! _inputFile.eof() ) {
        SeekRead(_inputBuffer,_lfaBase+offset,DEF_BUF_SIZE);
        _pageStartOffset = offset;
    }
}
예제 #6
0
/*
 * FindNewHeader - get a pointer to the new exe header
 */
static BOOL FindNewHeader( char *name, HFILE *hdl,
                        ULONG *new_head, USHORT *id  )
{
    long        open_rc;
    HFILE       h;
    BOOL        rc;
    USHORT      data;

    open_rc = OpenFile( name, 0, OPEN_PRIVATE );
    if( open_rc < 0 ) {
        return( FALSE );
    }
    h = open_rc;
    rc = FALSE;
    while( 1 ) {
        if( !SeekRead( h, 0x00, &data, sizeof( data ) ) ) {
            break;
        }
        if( data != 0x5a4d )    /* MZ */
            break;

        if( !SeekRead( h, 0x18, &data, sizeof( data ) ) ) {
            break;
        }
        if( data < 0x40 )       /* offset of relocation header */
            break;

        if( !SeekRead( h, 0x3c, new_head, sizeof( ULONG ) ) ) {
            break;
        }

        if( !SeekRead( h, *new_head, id, sizeof( USHORT ) ) ) {
            break;
        }
        rc = TRUE;
        break;
    }
    if( !rc ) {
        DosClose( h );
    }
    *hdl = h;
    return( rc );

} /* FindNewHeader */
예제 #7
0
//
// Retriever::GetDirPos().
// Returns the address of the directory informations.
//
streampos Retriever::GetDirPos()
/******************************/
{
    unsigned_32 lfoDir;

    if ( ! SeekRead(&lfoDir, _lfaBase + LONG_WORD, LONG_WORD) ) {
        throw DebugInfoError();
    }
    return (_lfaBase+lfoDir);
}
예제 #8
0
// The read subsection routine is most efficient when debugging info emitted
// by the linker are in the order that cvpack reads.
bool Retriever::ReadSubsection( char*&       buffer,
                                unsigned_32& length,
                                const sst    subsection,
                                const module mod )
/******************************************************/
{
    if (_heapBuffer) {
    delete [] _heapBuffer;
        _heapBuffer=NULL;
    }
    dir_info di;
    if ( !_aDirectory.GetDirInfo(di,subsection,mod) ) {
        return FALSE;
    }
    length = di.length;
    if ( length == 0 ) {
        return FALSE;
    }
/*
    cerr << "Will read subsection ";
    cerr << subsection;
    cerr << " of length ";
    cerr << length;
    cerr << " now\n";
    cerr.flush();
*/
//  if ( 1 ) {
    //if ( _missRate > DEF_MISS_THRESHOLD ) {
        _heapBuffer = buffer = new char [di.length];
        if ( SeekRead( buffer, _lfaBase+di.offset, di.length ) != di.length ) {
            if (_heapBuffer) {
            delete [] _heapBuffer;
                _heapBuffer=NULL;
            }
            return FALSE;
        }
        return TRUE;
//    }
/*
    // if the request read is not in current page, readin the request
    // page.
    if ( ! IsInCurrentPage(di.offset) ) {
        ++_missRate;
        buffer = Read(di);
        return ( buffer ? TRUE : FALSE );
    }
    if ( IsCrossPage(di) ) {
        buffer = Read(di);
        return ( buffer ? TRUE : FALSE );
    }
    buffer = _inputBuffer + LocalPageOff(di.offset);
    return TRUE;
*/
}
예제 #9
0
//
// Retriever::GetPEDebugDirCVEntryPos().
// Returns the address of the PE debug dir entry for our
// CodeView data section.
// This works only with a modified linker.
// Similar to Retriever::GetBasePos()
//
streampos Retriever::GetPEDebugDirCVEntryPos()
/******************************/
{
    unsigned_32 addr;

    if (_lfaBase < LONG_WORD) return 0;
    if ( ! SeekRead(&addr, _lfaBase - LONG_WORD, LONG_WORD) ) {
        throw DebugInfoError();
    }
    if (addr >= _lfaBase) return 0;
    return (addr);
}
예제 #10
0
char* Retriever::Read( const dir_info& di )
/*****************************************/
{
    // if length larger than one page, then do a direct read and read in
    // the subsequent page onto input buffer.
    if ( di.length > DEF_BUF_SIZE ) {
        if (_heapBuffer) {
            delete [] _heapBuffer;
            _heapBuffer=NULL;
        }
        _heapBuffer = new char [di.length];
        if ( SeekRead(_heapBuffer, _lfaBase+di.offset, di.length) != di.length ) {
            delete [] _heapBuffer;
            _heapBuffer=NULL;
            return NULL;
        }
        ReadPage(di.offset+di.length);
        return _heapBuffer;
    }
    ReadPage(di.offset);
    return _inputBuffer;
}
예제 #11
0
/*
 * GetEXEHeader - get type of EXE
 */
int GetEXEHeader( HANDLE handle, header_info *hi, WORD *stack )
{
    WORD    data;
    WORD    sig;
    DWORD   nh_offset;

    if( !SeekRead( handle, 0x00, &data, sizeof( data ) ) ) {
        return( FALSE );
    }
    if( data != EXE_MZ ) {
        return( FALSE );
    }

    //    if( !SeekRead( handle, 0x18, &data, sizeof( data ) ) ) {
    //      return( FALSE );
    //    }
    //    if( data < 0x40 ) {
    //      return( FALSE );
    //    }

    if( !SeekRead( handle, 0x3c, &nh_offset, sizeof( unsigned_32 ) ) ) {
        return( FALSE );
    }

    if( !SeekRead( handle, nh_offset, &sig, sizeof( sig ) ) ) {
        sig = 0;
    }
    hi->sig = sig;
    if( sig == EXE_PE ) {
        return( SeekRead( handle, nh_offset, &hi->u.peh, sizeof( exe_pe_header ) ) );
    }
#if defined( MD_x86 )
    if( sig == EXE_NE ) {
        if( !SeekRead( handle, nh_offset, &hi->u.neh, sizeof( os2_exe_header ) ) )
        {
            return( FALSE );
        }
        if( hi->u.neh.target == TARGET_WINDOWS ) {
            DWORD       off;
            int         len;
            DWORD       bytes;
            DWORD       pos;

            off = nh_offset + hi->u.neh.resident_off;
            if( SetFilePointer( handle, off, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER ) {
                return( FALSE );
            }
            if( !ReadFile( handle, &len, sizeof( len ), &bytes, NULL ) ) {
                return( FALSE );
            }
            if( len > sizeof( hi->modname ) - 1 ) {
                len = sizeof( hi->modname ) - 1;
            }
            if( !ReadFile( handle, hi->modname, len, &bytes, NULL ) ) {
                return( FALSE );
            }
            hi->modname[len] = 0;
            pos = nh_offset + hi->u.neh.segment_off +
                ( hi->u.neh.adsegnum - 1 ) * sizeof( segment_record ) +
                offsetof( segment_record, min );
            if( !SeekRead( handle, pos, stack, sizeof( *stack ) ) ) {
                return( FALSE );
            }
            *stack += hi->u.neh.stack;
            return( TRUE );
        }
        return( FALSE );
    }
    hi->sig = EXE_MZ;
    return( TRUE );
#elif defined( MD_x64 )
    return( FALSE );
#elif defined( MD_axp ) || defined( MD_ppc )
    return( FALSE );
#else
    #error GetEXEHeader not configured
#endif
}
예제 #12
0
int GetModuleName( HANDLE fhdl, char *name )
{
    header_info         hi;
    pe_object           obj;
    pe_export_directory expdir;
    DWORD               lenread;
    DWORD               export_rva;
    DWORD               i;
    char                buf[_MAX_PATH];
    WORD                stack;
    int                 num_objects;
    DWORD               seek_offset;

    if( !GetEXEHeader( fhdl, &hi, &stack ) ) {
        return( FALSE );
    }
    if( hi.sig != EXE_PE ) {
        return( FALSE );
    }
    seek_offset = SetFilePointer( fhdl, 0, NULL, FILE_CURRENT );
    if( seek_offset == INVALID_SET_FILE_POINTER ) {
        return( FALSE );
    }
    if( IS_PE64( hi.u.peh ) ) {
        export_rva = PE64( hi.u.peh ).table[PE_TBL_EXPORT].rva;
        num_objects = PE64( hi.u.peh ).num_objects;
        seek_offset += PE64( hi.u.peh ).nt_hdr_size + offsetof( pe_header64, magic ) - sizeof( exe_pe_header );
    } else {
        export_rva = PE32( hi.u.peh ).table[PE_TBL_EXPORT].rva;
        num_objects = PE32( hi.u.peh ).num_objects;
        seek_offset += PE32( hi.u.peh ).nt_hdr_size + offsetof( pe_header, magic ) - sizeof( exe_pe_header );
    }
    if( num_objects == 0 ) {
        return( FALSE );
    }
    /* position to begining of object table */
    if( SetFilePointer( fhdl, seek_offset, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER ) {
        return( FALSE );
    }
    for( i = 0; i < num_objects; i++ ) {
        if( !ReadFile( fhdl, &obj, sizeof( obj ), &lenread, NULL ) || lenread != sizeof( obj ) ) {
            return( FALSE );
        }
        if( export_rva >= obj.rva && export_rva < obj.rva + obj.physical_size ) {
            break;
        }
    }
    if( i == num_objects ) {
        return( FALSE );
    }
    if( !SeekRead( fhdl, obj.physical_offset + export_rva - obj.rva, &expdir, sizeof( expdir ) ) ) {
        return( FALSE );
    }
    if( !SeekRead( fhdl, obj.physical_offset + expdir.name_rva - obj.rva, buf, _MAX_PATH ) ) {
        return( FALSE );
    }
    if( SetFilePointer( fhdl, obj.physical_offset + expdir.name_rva - obj.rva, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER ) {
        return( FALSE );
    }
    if( !ReadFile( fhdl, buf, _MAX_PATH, &lenread, NULL ) ) {
        return( FALSE );
    }
    memcpy( name, buf, lenread );
    name[lenread] = '\0';
    return( TRUE );
}
예제 #13
0
파일: rcio.c 프로젝트: jossk/open-watcom-v2
static int openExeFileInfoRO( char *filename, ExeFileInfo *info )
/***************************************************************/
{
    RcStatus        status;
    exe_pe_header   *pehdr;

    info->Handle = RcOpen( filename, O_RDONLY|O_BINARY );
    if( info->Handle == NIL_HANDLE ) {
        RcError( ERR_CANT_OPEN_FILE, filename, strerror( errno ) );
        return( FALSE );
    }
    info->IsOpen = TRUE;
    info->Type = FindNEPELXHeader( info->Handle, &info->WinHeadOffset );
    info->name = filename;
    switch( info->Type ) {
    case EXE_TYPE_NE_WIN:
    case EXE_TYPE_NE_OS2:
        status = SeekRead( info->Handle, info->WinHeadOffset, &info->u.NEInfo.WinHead, sizeof( os2_exe_header ) );
        if( status != RS_OK ) {
            RcError( ERR_NOT_VALID_EXE, filename );
            return( FALSE );
        } else {
            info->DebugOffset = info->WinHeadOffset + sizeof( os2_exe_header );
        }
        break;
    case EXE_TYPE_PE:
        pehdr = &info->u.PEInfo.WinHeadData;
        info->u.PEInfo.WinHead = pehdr;
        status = SeekRead( info->Handle, info->WinHeadOffset, &PE32( *pehdr ), sizeof( pe_header ) );
        if( status != RS_OK ) {
            RcError( ERR_NOT_VALID_EXE, filename );
            return( FALSE );
        }
        if( IS_PE64( *pehdr ) ) {
            status = SeekRead( info->Handle, info->WinHeadOffset, &PE64( *pehdr ), sizeof( pe_header64 ) );
            if( status != RS_OK ) {
                RcError( ERR_NOT_VALID_EXE, filename );
                return( FALSE );
            }
            info->DebugOffset = info->WinHeadOffset + sizeof( pe_header64 );
        } else {
            info->DebugOffset = info->WinHeadOffset + sizeof( pe_header );
        }
        break;
    case EXE_TYPE_LX:
        status = SeekRead( info->Handle, info->WinHeadOffset, &info->u.LXInfo.OS2Head, sizeof( os2_flat_header ) );
        if( status != RS_OK ) {
            RcError( ERR_NOT_VALID_EXE, filename );
            return( FALSE );
        } else {
            info->DebugOffset = info->WinHeadOffset + sizeof( os2_flat_header );
        }
        break;
    default:
        RcError( ERR_NOT_VALID_EXE, filename );
        return( FALSE );
        break;
    }

    RcSeek( info->Handle, 0, SEEK_SET );
    return( TRUE );
} /* openExeFileInfoRO */
예제 #14
0
static bool openExeFileInfoRO( const char *filename, ExeFileInfo *info )
/**********************************************************************/
{
    RcStatus        status;
    exe_pe_header   *pehdr;

    info->fp = ResOpenFileRO( filename );
    if( info->fp == NULL ) {
        RcError( ERR_CANT_OPEN_FILE, filename, strerror( errno ) );
        return( false );
    }
    info->IsOpen = true;
    info->Type = FindNEPELXHeader( info->fp, &info->WinHeadOffset );
    info->name = filename;
    switch( info->Type ) {
    case EXE_TYPE_NE_WIN:
    case EXE_TYPE_NE_OS2:
        status = SeekRead( info->fp, info->WinHeadOffset, &info->u.NEInfo.WinHead, sizeof( os2_exe_header ) );
        if( status != RS_OK ) {
            RcError( ERR_NOT_VALID_EXE, filename );
            return( false );
        } else {
            info->DebugOffset = info->WinHeadOffset + sizeof( os2_exe_header );
        }
        break;
    case EXE_TYPE_PE:
        pehdr = &info->u.PEInfo.WinHeadData;
        info->u.PEInfo.WinHead = pehdr;
        status = SeekRead( info->fp, info->WinHeadOffset, &PE32( *pehdr ), sizeof( pe_header ) );
        if( status != RS_OK ) {
            RcError( ERR_NOT_VALID_EXE, filename );
            return( false );
        }
        if( IS_PE64( *pehdr ) ) {
            status = SeekRead( info->fp, info->WinHeadOffset, &PE64( *pehdr ), sizeof( pe_header64 ) );
            if( status != RS_OK ) {
                RcError( ERR_NOT_VALID_EXE, filename );
                return( false );
            }
            info->DebugOffset = info->WinHeadOffset + sizeof( pe_header64 );
        } else {
            info->DebugOffset = info->WinHeadOffset + sizeof( pe_header );
        }
        break;
    case EXE_TYPE_LX:
        status = SeekRead( info->fp, info->WinHeadOffset, &info->u.LXInfo.OS2Head, sizeof( os2_flat_header ) );
        if( status != RS_OK ) {
            RcError( ERR_NOT_VALID_EXE, filename );
            return( false );
        } else {
            info->DebugOffset = info->WinHeadOffset + sizeof( os2_flat_header );
        }
        break;
    default:
        RcError( ERR_NOT_VALID_EXE, filename );
        return( false );
        break;
    }

    return( !RESSEEK( info->fp, 0, SEEK_SET ) );
} /* openExeFileInfoRO */