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 ); }
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 ); }
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 ); }
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 ); }
void Retriever::ReadPage( const unsigned_32 offset ) /**************************************************/ { if ( ! _inputFile.eof() ) { SeekRead(_inputBuffer,_lfaBase+offset,DEF_BUF_SIZE); _pageStartOffset = offset; } }
/* * 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 */
// // 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); }
// 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; */ }
// // 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); }
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; }
/* * 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 }
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 ); }
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 */
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 */