示例#1
0
int WRWinNTHeaderHasResourceTable( exe_pe_header *header )
{
    int                 num_tables;
    pe_hdr_table_entry  *table;

    if( IS_PE64( *header ) ) {
        num_tables = PE64( *header ).num_tables;
        table = PE64( *header ).table;
    } else {
        num_tables = PE32( *header ).num_tables;
        table = PE32( *header ).table;
    }
    return( num_tables > PE_TBL_RESOURCE && table[PE_TBL_RESOURCE].rva != 0 && table[PE_TBL_RESOURCE].size != 0 );
}
示例#2
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 );
}
示例#3
0
int WRCalcObjTableOffset( WResFileID file, exe_pe_header *hdr )
{
    uint_16  pe_offset;
    int      offset;
    bool     ok;

    ok = (ResSeek( file, PE_OFFSET, SEEK_SET ) != -1);

    if( ok ) {
        ResReadUint16( &pe_offset, file );
        ok = (pe_offset != 0);
    }

    if ( ok ) {
        if( IS_PE64( *hdr ) ) {
            offset = pe_offset + PE64( *hdr ).nt_hdr_size + offsetof( pe_header64, magic );
        } else {
            offset = pe_offset + PE32( *hdr ).nt_hdr_size + offsetof( pe_header, magic );
        }
    } else {
        offset = 0;
    }

    return( offset );
}
示例#4
0
long int WRReadWinNTExeHeader( WResFileID file_handle, exe_pe_header *header )
{
    long int    old_pos;
    uint_16     offset;
    bool        ok;

    old_pos = -1;

    ok = (file_handle != -1 && header != NULL);

    if( ok ) {
        ok = ((old_pos = ResSeek( file_handle, 0x18, SEEK_SET )) != -1);
    }

    /* check the reloc offset */
    if( ok ) {
        ResReadUint16( &offset, file_handle );
        ok = (offset >= 0x0040);
    }

    if( ok ) {
        ok = (ResSeek( file_handle, PE_OFFSET, SEEK_SET ) != -1);
    }

    /* check header offset */
    if( ok ) {
        ResReadUint16( &offset, file_handle );
        ok = (offset != 0x0000);
    }

    if( ok ) {
        ok = (ResSeek( file_handle, offset, SEEK_SET ) != -1);
    }

    if( ok ) {
        ok = (read( file_handle, &PE32( *header ), sizeof( pe_header ) ) == sizeof( pe_header ));
        if( ok && IS_PE64( *header ) ) {
            ok = (ResSeek( file_handle, offset, SEEK_SET ) != -1);
            if( ok ) {
                ok = (read( file_handle, &PE64( *header ), sizeof( pe_header64 ) ) == sizeof( pe_header64 ));
            }
        }
    }

    /* check for valid Win32 EXE */
    if( ok ) {
        ok = WRIsHeaderValidWINNT( header );
    }

    if( old_pos != -1 ) {
        ok = (ResSeek( file_handle, old_pos, SEEK_SET ) != -1 && ok);
    }

    if( !ok ) {
        WRDisplayErrorMsg( WR_INVALIDNTEXE );
        offset = 0;
    }

    return( offset );
}
示例#5
0
static bool IdentifyWinExeHeader( FILE *fh, bool win16 )
{
    os2_exe_header  os2_hdr;
    exe_pe_header   pe_hdr;
    uint_16         offset;
    bool            ok;

    ok = ( fh != NULL );

    if( ok ) {
        ok = ( fseek( fh, 0x18, SEEK_SET ) == 0 );
    }

    /* check the reloc offset */
    if( ok ) {
        ok = ( fread( &offset, 1, sizeof( offset ), fh ) == sizeof( offset ) && offset >= 0x0040 );
    }

    if( ok ) {
        ok = ( fseek( fh, NH_OFFSET, SEEK_SET ) == 0 );
    }

    /* check the header offset */
    if( ok ) {
        ok = ( fread( &offset, 1, sizeof( offset ), fh ) == sizeof( offset ) && offset != 0 );
    }

    /* seek to the header */
    if( ok ) {
        ok = ( fseek( fh, offset, SEEK_SET ) == 0 );
    }

    if( ok ) {
        if( win16 ) {
            ok = ( fread( &os2_hdr, 1, sizeof( os2_hdr ), fh ) == sizeof( os2_hdr ));
            /* check for valid Win16 EXE */
            if( ok ) {
                return( WRIsHeaderValidWIN16( &os2_hdr ) );
            }
        } else {
            ok = ( fread( &PE32( pe_hdr ), 1, sizeof( pe_header ), fh ) == sizeof( pe_header ) );
            if( ok && IS_PE64( pe_hdr ) ) {
                /* seek to the header again */
                ok = ( fseek( fh, offset, SEEK_SET ) == 0 );
                if( ok ) {
                    ok = ( fread( &PE64( pe_hdr ), 1, sizeof( pe_header64 ), fh ) == sizeof( pe_header64 ) );
                }
            }
            /* check for valid Win32 EXE */
            if( ok ) {
                return( WRIsHeaderValidWINNT( &pe_hdr ) );
            }
        }
    }

    return( false );
}
示例#6
0
int WRIsHeaderValidWINNT( exe_pe_header *header )
{
    /* at some point will we have to check the CPUTYPE ????!!!! */
    if( IS_PE64( *header ) ) {
        return( PE64( *header ).signature == PE_SIGNATURE );
    } else {
        return( PE32( *header ).signature == PE_SIGNATURE );
    }
}
示例#7
0
int WRReadNTObjectTable( WResFileID file, exe_pe_header *hdr, pe_object **ot )
{
    int size;
    int ot_offset;

    ot_offset = WRCalcObjTableOffset( file, hdr );
    if( ot_offset == 0 || ResSeek( file, ot_offset, SEEK_SET ) == -1 ) {
        return( FALSE );
    }
    if( IS_PE64( *hdr ) ) {
        size = sizeof( pe_object ) * PE64( *hdr ).num_objects;
    } else {
        size = sizeof( pe_object ) * PE32( *hdr ).num_objects;
    }
    *ot = (pe_object *)MemAlloc( size );
    if( *ot != NULL ) {
        if( read( file, *ot, size ) != size ) {
            MemFree( *ot );
            *ot = NULL;
        }
    }

    return( *ot != NULL );
}
示例#8
0
/*
 * AccLoadProg - create a new process for debugging
 */
trap_retval ReqProg_load( void )
{
    char            *parm;
    char            *src;
    char            *dst;
    char            *endsrc;
    char            exe_name[PATH_MAX];
    char            ch;
    BOOL            rc;
    int             len;
    MYCONTEXT       con;
    thread_info     *ti;
    HANDLE          handle;
    prog_load_req   *acc;
    prog_load_ret   *ret;
    header_info     hi;
    WORD            stack;
    WORD            version;
    DWORD           pid;
    DWORD           pid_started;
    DWORD           cr_flags;
    char            *buff = NULL;
    size_t          nBuffRequired = 0;
    char            *dll_name;
    char            *service_name;
    char            *dll_destination;
    char            *service_parm;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    parm = GetInPtr( sizeof( *acc ) );

    /*
     * reset status variables
     */
    LastExceptionCode = -1;
    DebugString = NULL;
    DebugeeEnded = FALSE;
    RemoveAllThreads();
    FreeLibList();
    DidWaitForDebugEvent = FALSE;
    DebugeePid = 0;
    DebugeeTid = 0;
    SupportingExactBreakpoints = 0;

    /*
     * check if pid is specified
     */
    ParseServiceStuff( parm, &dll_name, &service_name, &dll_destination, &service_parm );
    pid = 0;
    src = parm;

    /*
    //  Just to be really safe!
    */
    nBuffRequired = GetTotalSize() + PATH_MAX + 16;
    if( NULL == ( buff = malloc( nBuffRequired ) ) ) {
        ret->err = ERROR_NOT_ENOUGH_MEMORY;
        return( sizeof( *ret ) );
    }

    if( *src == '#' ) {
        src++;
        pid = strtoul( src, &endsrc, 16 );
        if( pid == 0 ) {
            pid = -1;
        }
        strcpy( buff, endsrc );
    } else {
        while( isdigit( *src ) ) {
            src++;
        }
        if( *src == 0 && src != parm ) {
            pid = atoi( parm );
        }
    }

    /*
     * get program to debug.  If the user has specified a pid, then
     * skip directly to doing a DebugActiveProcess
     */
    IsWOW = FALSE;
#if !defined( MD_x64 )
    IsDOS = FALSE;
#endif
    if( pid == 0 ) {
        if( FindFilePath( parm, exe_name, ExtensionList ) != 0 ) {
            ret->err = ERROR_FILE_NOT_FOUND;
            goto error_exit;
        }

        /*
         * Get type of application
         */
        handle = CreateFile( (LPTSTR)exe_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
        if( handle == INVALID_HANDLE_VALUE ) {
            ret->err = GetLastError();
            goto error_exit;
        }
        GetFullPathName( exe_name, MAX_PATH, CurrEXEName, NULL );

        /*
         * get the parm list
         */
        if( strchr( CurrEXEName, ' ' ) != NULL ) {
            strcpy( buff, "\"" );
            strcat( buff, CurrEXEName );
            strcat( buff, "\"" );
        } else {
            strcpy( buff, CurrEXEName );
        }
        dst = &buff[strlen( buff )];
        src = parm;
        while( *src != 0 ) {
            ++src;
        }
        // parm layout
        // <--parameters-->0<--program_name-->0<--arguments-->0
        //
        for( len = GetTotalSize() - sizeof( *acc ) - (src - parm) - 1; len > 0; --len ) {
            ch = *src;
            if( ch == 0 ) {
                ch = ' ';
            }
            *dst = ch;
            ++dst;
            ++src;
        }
        *dst = 0;

        cr_flags = DEBUG_ONLY_THIS_PROCESS;

        if( !GetEXEHeader( handle, &hi, &stack ) ) {
            ret->err = GetLastError();
            CloseHandle( handle );
            goto error_exit;
        }
        if( hi.sig == EXE_PE ) {
            if( IS_PE64( hi.u.peh ) ) {
                DebugeeSubsystem = PE64( hi.u.peh ).subsystem;
            } else {
                DebugeeSubsystem = PE32( hi.u.peh ).subsystem;
#if defined( MD_x64 )
                IsWOW = TRUE;
#endif
            }
            if( DebugeeSubsystem == SS_WINDOWS_CHAR ) {
                cr_flags |= CREATE_NEW_CONSOLE;
            }
#if !defined( MD_x64 )
        } else if( hi.sig == EXE_NE ) {
            IsWOW = TRUE;
            /*
             * find out the pid of WOW, if it is already running.
             */
            pVDMEnumProcessWOW( EnumWOWProcessFunc, (LPARAM)&pid );
            if( pid != 0 ) {
                version = LOWORD( GetVersion() );
                if( LOBYTE( version ) == 3 && HIBYTE( version ) < 50 ) {
                    int kill = MessageBox( NULL, TRP_NT_wow_warning, TRP_The_WATCOM_Debugger, MB_APPLMODAL + MB_YESNO );
                    if( kill == IDYES ) {
                        DWORD axs = PROCESS_TERMINATE+STANDARD_RIGHTS_REQUIRED;
                        HANDLE hprocess = OpenProcess( axs, FALSE, pid );

                        if( hprocess != 0 && TerminateProcess( hprocess, 0 ) ) {
                            CloseHandle( hprocess );
                            pid = 0;
                        }
                    }
                } else {
                    cr_flags |= CREATE_SEPARATE_WOW_VDM;
                    pid = 0; // always start a new VDM.
                }
            }
            if( pid != 0 ) {
                ret->err = GetLastError();
                CloseHandle( handle );
                goto error_exit;
            }
        } else {
            IsDOS = TRUE;
#endif
        }
        CloseHandle( handle );
    }

    /*
     * start the debugee
     */
    pid_started = pid;
    if( *dll_name ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_DLLNAME );
        strcat( buff, dll_name );
    }
    if( *service_name ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_SERVICE );
        strcat( buff, service_name );
    }
    if( *dll_destination ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_COPYDIR );
        strcat( buff, dll_destination );
    }
    if( *service_parm ) {
        strcat( buff, LOAD_PROG_STR_DELIM );
        strcat( buff, LOAD_PROG_STR_SERVICEPARM );
        strcat( buff, service_parm );
    }
    ret->err = StartControlThread( buff, &pid_started, cr_flags );
    if( ret->err != 0 ) {
        goto error_exit;
    }
    /*
     * CREATE_PROCESS_DEBUG_EVENT will always be the first debug event.
     * If it is not, then something is horribly wrong.
     */
    rc = MyWaitForDebugEvent();
    if( !rc || ( DebugEvent.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT ) || ( DebugEvent.dwProcessId != pid_started ) ) {
        ret->err = GetLastError();
        goto error_exit;
    }
    ProcessInfo.pid = DebugEvent.dwProcessId;
    ProcessInfo.process_handle = DebugEvent.u.CreateProcessInfo.hProcess;
    ProcessInfo.base_addr = DebugEvent.u.CreateProcessInfo.lpBaseOfImage;
    AddProcess( &hi );
    AddThread( DebugEvent.dwThreadId, DebugEvent.u.CreateProcessInfo.hThread, DebugEvent.u.CreateProcessInfo.lpStartAddress );
    DebugeePid = DebugEvent.dwProcessId;
    DebugeeTid = DebugEvent.dwThreadId;
    LastDebugEventTid = DebugEvent.dwThreadId;

#if defined( MD_x86 )
#ifdef WOW
    if( IsWOW ) {
        ret->flags = LD_FLAG_IS_PROT;
        ret->err = 0;
        ret->task_id = DebugeePid;
        /*
         * we use our own CS and DS as the Flat CS and DS, for lack
         * of anything better
         */
        FlatDS = GetDS();
        FlatCS = GetCS();
        if( !executeUntilVDMStart() ) {
            ret->err = GetLastError();
            goto error_exit;
        }
        if( pid ) {
            addAllWOWModules();
        } else {
            addKERNEL();
        }
        /*
         * we save the starting CS:IP of the WOW app, since we will use
         * it to force execution of code later
         */
        ti = FindThread( DebugeeTid );
        MyGetThreadContext( ti, &con );
        WOWAppInfo.segment = ( WORD ) con.SegCs;
        WOWAppInfo.offset = ( WORD ) con.Eip;
        con.SegSs = con.SegDs; // Wow lies about the stack segment.  Reset it
        con.Esp = stack;
        MySetThreadContext( ti, &con );
    } else if( IsDOS ) {
        // TODO! Clean up this code
        ret->flags = 0; //LD_FLAG_IS_PROT;
        ret->err = 0;
        ret->task_id = DebugeePid;
        /*
         * we use our own CS and DS as the Flat CS and DS, for lack
         * of anything better
         */
        FlatDS = GetDS();
        FlatCS = GetCS();
        if( !executeUntilVDMStart() ) {
            ret->err = GetLastError();
            goto error_exit;
        }
#if 0
        if( pid ) {
            addAllWOWModules();
        } else {
            addKERNEL();
        }
#endif
        /*
         * we save the starting CS:IP of the WOW app, since we will use
         * it to force execution of code later
         */
        ti = FindThread( DebugeeTid );
        MyGetThreadContext( ti, &con );
        WOWAppInfo.segment = ( WORD )con.SegCs;
        WOWAppInfo.offset = ( WORD )con.Eip;
        con.SegSs = con.SegDs; // Wow lies about the stack segment.  Reset it
        con.Esp = stack;
        MySetThreadContext( ti, &con );
    } else {
#else
    {
#endif
#else
    {
#endif
        LPVOID base;

        if( pid == 0 ) {
            base = (LPVOID)DebugEvent.u.CreateProcessInfo.lpStartAddress;
        } else {
            base = 0;
        }

        ret->flags = LD_FLAG_IS_PROT;
        ret->err = 0;
        ret->task_id = DebugeePid;
        if( executeUntilStart( pid != 0 ) ) {
            LPVOID old;
            /*
             * make the application load our DLL, so that we can have it
             * run code out of it.  One small note: this will not work right
             * if the app does not load our DLL at the same address the
             * debugger loaded it at!!!
             */

            ti = FindThread( DebugeeTid );
            MyGetThreadContext( ti, &con );
            old = (LPVOID)AdjustIP( &con, 0 );
            if( base != 0 ) {
                SetIP( &con, base );
            }
            MySetThreadContext( ti, &con );
            SetIP( &con, old );
            MySetThreadContext( ti, &con );
        }
        ti = FindThread( DebugeeTid );
        MyGetThreadContext( ti, &con );
#if defined( MD_x86 )
        FlatCS = con.SegCs;
        FlatDS = con.SegDs;
#endif
        ret->flags |= LD_FLAG_IS_BIG;
    }
    ret->flags |= LD_FLAG_HAVE_RUNTIME_DLLS;
    if( pid != 0 ) {
        ret->flags |= LD_FLAG_IS_STARTED;
    }
    ret->mod_handle = 0;

error_exit:
    if( buff ) {
        free( buff );
        buff = NULL;
    }
    return( sizeof( *ret ) );

}

trap_retval ReqProg_kill( void )
{
    prog_kill_ret   *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    DelProcess( TRUE );
    StopControlThread();
    return( sizeof( *ret ) );
}
示例#9
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 );
}
示例#10
0
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 */
示例#11
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 */
示例#12
0
bool WRLoadWResDirFromWinNTEXE( WResFileID file_handle, WResDir *dir )
{
    exe_pe_header       nt_header;
    pe_object           *otable;
    uint_32             physical_size;
    uint_32             physical_offset;
    int                 i;
    bool                ok;
    unsigned_32         resource_rva;

    ok = (file_handle != -1);

    if( ok ) {
        ok = ((*dir = WResInitDir()) != NULL);
    }

    if( ok ) {
        ok = (WRReadWinNTExeHeader( file_handle, &nt_header ) != 0);
    }

    /* check if a resource table is present */
    if( ok ) {
        ok = WRWinNTHeaderHasResourceTable( &nt_header );
        if( !ok ) {
            WRDisplayErrorMsg( WR_EXENORES );
            return( TRUE );
        }
    }

    /* read NT object table */
    otable = NULL;
    if( ok ) {
        ok = WRReadNTObjectTable( file_handle, &nt_header, &otable );
    }

    /* find resource object in object table */
    resource_rva = 0;
    if( ok ) {
        int         num_objects;
        unsigned_32 file_align;

        physical_size = 0;
        physical_offset = 0;
        if( IS_PE64( nt_header ) ) {
            resource_rva = PE64( nt_header ).table[PE_TBL_RESOURCE].rva;
            num_objects = PE64( nt_header ).num_objects;
            file_align = PE64( nt_header ).file_align;
        } else {
            resource_rva = PE32( nt_header ).table[PE_TBL_RESOURCE].rva;
            num_objects = PE32( nt_header ).num_objects;
            file_align = PE32( nt_header ).file_align;
        }
        for( i = 0; i < num_objects; i++ ) {
            if( otable[i].rva == resource_rva ) {
                physical_size = otable[i].physical_size;
                physical_offset = otable[i].physical_offset;
                break;
            }
        }
        ok = (physical_size != 0 && physical_offset != 0 && physical_size % file_align == 0 && physical_offset % file_align == 0);
    }

    if( otable != NULL ) {
        MemFree( otable );
    }

    /* read the resource information */
    if( ok ) {
        res_offset = physical_offset;
        res_rva = resource_rva;
        ok = WRHandleWinNTTypeDir( file_handle, dir, physical_offset );
    }

    return( ok );
}