You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
5.0 KiB
232 lines
5.0 KiB
/*
|
|
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 <vector>
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <map>
|
|
#include <string.h>
|
|
#include <set>
|
|
#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<Export_t> 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<string> 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<const char*>(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;
|
|
}
|