/* Read in an .exp. Produce a .def file like so: EXPORTS Foo = expFoo Bar = expBar PRIVATE Abc = ntdll.RtlAbc An .exp file is really just an .obj. We just read its symbols. */ #include "yvals.h" #pragma warning(disable:4100) #pragma warning(disable:4663) #pragma warning(disable:4511) #pragma warning(disable:4512) #pragma warning(disable:4127) #include #include #include #include #include #include #include #include #include "strtok_r.h" #include "windows.h" class Export_t { public: string ExternalName; string InternalName; string ForwarderDll; string ForwarderFunction; void Write(FILE *); }; class DefFile_t { public: vector Exports; void AddExport(const Export_t & e) { Exports.push_back(e); } void Read(const char *); void Write(const char *); }; class ObjFile_t { public: ObjFile_t() : File(NULL) { } ~ObjFile_t() { if (File != NULL) { fclose(File); } } void ReadHeader(const char *); void ReadSymbols(); bool AnySymbols() const; ULONG Machine() const; IMAGE_FILE_HEADER FileHeader; vector Symbols; FILE * File; }; class ExpFile_t : public ObjFile_t { public: ExpFile_t() { } }; class IoError_t { public: IoError_t() { } }; class StdIoError_t : public IoError_t { public: StdIoError_t(const char * function, int error) { } }; class StdioError_fread_t : public StdIoError_t { public: StdioError_fread_t(int error) { } }; class StdioError_fopen_t : public StdIoError_t { public: StdioError_fopen_t(const char * filename, const char * mode, int error) { } }; FILE * FileOpen(const char * filename, const char * mode) { FILE * file = fopen(filename, mode); if (file == NULL) throw StdioError_fopen_t(filename, mode, errno); return file; } void FileRead(FILE * File, void * Buffer, SIZE_T BytesToRead) { if (!fread(Buffer, 1, BytesToRead, File)) throw StdioError_fread_t(errno); } void FileSeek(FILE * File, long HowFar, int FromWhere) { fseek(File, HowFar, FromWhere); } void ObjFile_t::ReadHeader(const char * s) { File = FileOpen(s, "rb"); FileRead(File, &this->FileHeader, sizeof(this->FileHeader)); } bool ObjFile_t::AnySymbols() const { return (FileHeader.PointerToSymbolTable != 0 && FileHeader.NumberOfSymbols != 0); } ULONG ObjFile_t::Machine() const { return FileHeader.Machine; } unsigned long GetLittleEndianInteger(const unsigned char * Bytes, unsigned long Size) { unsigned long i = 0; For ( ; Size != 0 ; (--Size, ++Bytes)) { i <<= 8; i |= *Bytes; } return i; } class StringTable_t { public: unsigned long Size; const unsigned char * Base; StringTable_t() : Size(0), Base(0) { } void Attach(const unsigned char * s) { this->Base = s; this->Size = GetLittleEndianInteger(s, 4); } void RangeCheck(unsigned long Offset) const { if (Offset > this->Size) throw RangeError_t("StringTable"); } const unsigned char * GetAtOffset(unsigned long Offset) const { return reinterpret_cast(this->Base + Offset); } }; class RawSymbols_t { public: unsigned char Bytes[18]; string GetShortName() const { char ShortName[9]; memcpy(ShortName, Bytes, 8); ShortName[8] = 0; return ShortName; } bool IsShortName() const { return GetLittleEndianInteger(&this->Bytes[0], 4) == 0; } const char * GetLongName(StringTable_t * StringTable) const { unsigned long Offset = GetLittleEndiangInteger(&this->Bytes[4], 4); return StringTable->GetAtOffset(Offset); } ULONG GetValue() const { return GetLittleEndianInteger(&Bytes[8], 4); } LONG SectionNumber() const { return GetLittleEndianInteger(&Bytes[12], 2); } ULONG GetType() const { return GetLittleEndianInteger(&Bytes[14], 2); } LONG GetStorageClass() const { return GetLittleEndianInteger(&Bytes[16], 1); } ULONG NumberOfAuxSymbols() const { return GetLittleEndianInteger(&Bytes[17], 1); } }; void ObjFile_t::ReadSymbols() { FileSeek(File, FileHeader.PointerToSymbolsTable, SEEK_SET); } class ExpToDef_t { public: ExpFile_t InExpFile; DefFile_t OutDefFile; void Main(const char * in1, const char * in2, const char * out); }; void ExpToDef_t::Main(const char * in, const char * out) { this->InExpFile.Read(in); FILE * outfile = NULL; if (_stricmp(out, "-") == 0) outfile = stdout; else { outfile = fopen(out, "w"); if (outfile == NULL) { Error("fopen(%s)\n", out); return; } } this->OutDefFile.Write(outfile); } int main() { ExpToDef_t expToDef; expToDef.Main(); return 0; }