123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- typedef struct cmANON_OBJECT_HEADER_BIGOBJ
- {
-
- WORD Sig1;
- WORD Sig2;
- WORD Version;
- WORD Machine;
- DWORD TimeDateStamp;
- CLSID ClassID;
- DWORD SizeOfData;
- DWORD Flags;
- DWORD MetaDataSize;
- DWORD MetaDataOffset;
-
- DWORD NumberOfSections;
- DWORD PointerToSymbolTable;
- DWORD NumberOfSymbols;
- } cmANON_OBJECT_HEADER_BIGOBJ;
- typedef struct _cmIMAGE_SYMBOL_EX
- {
- union
- {
- BYTE ShortName[8];
- struct
- {
- DWORD Short;
- DWORD Long;
- } Name;
- DWORD LongName[2];
- } N;
- DWORD Value;
- LONG SectionNumber;
- WORD Type;
- BYTE StorageClass;
- BYTE NumberOfAuxSymbols;
- } cmIMAGE_SYMBOL_EX;
- typedef cmIMAGE_SYMBOL_EX UNALIGNED* cmPIMAGE_SYMBOL_EX;
- PIMAGE_SECTION_HEADER GetSectionHeaderOffset(
- PIMAGE_FILE_HEADER pImageFileHeader)
- {
- return (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageFileHeader +
- IMAGE_SIZEOF_FILE_HEADER +
- pImageFileHeader->SizeOfOptionalHeader);
- }
- PIMAGE_SECTION_HEADER GetSectionHeaderOffset(
- cmANON_OBJECT_HEADER_BIGOBJ* pImageFileHeader)
- {
- return (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageFileHeader +
- sizeof(cmANON_OBJECT_HEADER_BIGOBJ));
- }
- const char* StrNStr(const char* start, const char* find, size_t& size)
- {
- size_t len;
- const char* hint;
- if (!start || !find || !size) {
- size = 0;
- return 0;
- }
- len = strlen(find);
- while ((hint = (const char*)memchr(start, find[0], size - len + 1))) {
- size -= (hint - start);
- if (!strncmp(hint, find, len))
- return hint;
- start = hint + 1;
- }
- size = 0;
- return 0;
- }
- template <
-
- class ObjectHeaderType,
- // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL
- class SymbolTableType>
- class DumpSymbols
- {
- public:
-
- DumpSymbols(ObjectHeaderType* ih, std::set<std::string>& symbols,
- std::set<std::string>& dataSymbols, bool isI386)
- : Symbols(symbols)
- , DataSymbols(dataSymbols)
- {
- this->ObjectImageHeader = ih;
- this->SymbolTable =
- (SymbolTableType*)((DWORD_PTR) this->ObjectImageHeader +
- this->ObjectImageHeader->PointerToSymbolTable);
- this->SectionHeaders = GetSectionHeaderOffset(this->ObjectImageHeader);
- this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols;
- this->IsI386 = isI386;
- }
-
- void DumpObjFile() { this->DumpExternalsObjects(); }
-
- void DumpExternalsObjects()
- {
- unsigned i;
- PSTR stringTable;
- std::string symbol;
- DWORD SectChar;
-
- stringTable = (PSTR) & this->SymbolTable[this->SymbolCount];
- SymbolTableType* pSymbolTable = this->SymbolTable;
- for (i = 0; i < this->SymbolCount; i++) {
- if (pSymbolTable->SectionNumber > 0 &&
- (pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
- if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
-
- if (pSymbolTable->N.Name.Short != 0) {
- symbol.clear();
- symbol.insert(0, (const char*)pSymbolTable->N.ShortName, 8);
- } else {
- symbol = stringTable + pSymbolTable->N.Name.Long;
- }
-
- while (isspace(symbol[0]))
- symbol.erase(0, 1);
-
-
- if (symbol[0] == '_') {
- std::string::size_type posAt = symbol.find('@');
- if (posAt != std::string::npos) {
- symbol.erase(posAt);
- }
- }
-
- if (this->IsI386 && symbol[0] == '_') {
- symbol.erase(0, 1);
- }
-
-
-
-
- const char* scalarPrefix = "??_G";
- const char* vectorPrefix = "??_E";
-
-
-
- if (symbol.compare(0, 4, scalarPrefix) &&
- symbol.compare(0, 4, vectorPrefix)) {
- SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1]
- .Characteristics;
-
- if (symbol.find('.') == std::string::npos) {
- if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
-
- this->DataSymbols.insert(symbol);
- } else {
- if (pSymbolTable->Type || !(SectChar & IMAGE_SCN_MEM_READ) ||
- (SectChar & IMAGE_SCN_MEM_EXECUTE)) {
- this->Symbols.insert(symbol);
- }
- }
- }
- }
- }
- }
-
- i += pSymbolTable->NumberOfAuxSymbols;
- pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
- pSymbolTable++;
- }
- }
- private:
- std::set<std::string>& Symbols;
- std::set<std::string>& DataSymbols;
- DWORD_PTR SymbolCount;
- PIMAGE_SECTION_HEADER SectionHeaders;
- ObjectHeaderType* ObjectImageHeader;
- SymbolTableType* SymbolTable;
- bool IsI386;
- };
- bool DumpFile(const char* filename, std::set<std::string>& symbols,
- std::set<std::string>& dataSymbols)
- {
- HANDLE hFile;
- HANDLE hFileMapping;
- LPVOID lpFileBase;
- hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(), GENERIC_READ,
- FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, 0);
- if (hFile == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename);
- return false;
- }
- hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
- if (hFileMapping == 0) {
- CloseHandle(hFile);
- fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
- return false;
- }
- lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
- if (lpFileBase == 0) {
- CloseHandle(hFileMapping);
- CloseHandle(hFile);
- fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
- return false;
- }
- const PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
- if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
- fprintf(stderr, "File is an executable. I don't dump those.\n");
- return false;
- } else {
- const PIMAGE_FILE_HEADER imageHeader = (PIMAGE_FILE_HEADER)lpFileBase;
-
- if (((imageHeader->Machine == IMAGE_FILE_MACHINE_I386) ||
- (imageHeader->Machine == IMAGE_FILE_MACHINE_AMD64) ||
- (imageHeader->Machine == IMAGE_FILE_MACHINE_ARM) ||
- (imageHeader->Machine == IMAGE_FILE_MACHINE_ARMNT) ||
- (imageHeader->Machine == IMAGE_FILE_MACHINE_ARM64)) &&
- (imageHeader->Characteristics == 0)) {
-
- DumpSymbols<IMAGE_FILE_HEADER, IMAGE_SYMBOL> symbolDumper(
- (PIMAGE_FILE_HEADER)lpFileBase, symbols, dataSymbols,
- (imageHeader->Machine == IMAGE_FILE_MACHINE_I386));
- symbolDumper.DumpObjFile();
- } else {
-
- cmANON_OBJECT_HEADER_BIGOBJ* h =
- (cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase;
- if (h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
- DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX>
- symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase, symbols,
- dataSymbols, (h->Machine == IMAGE_FILE_MACHINE_I386));
- symbolDumper.DumpObjFile();
- } else {
- printf("unrecognized file format in '%s'\n", filename);
- return false;
- }
- }
- }
- UnmapViewOfFile(lpFileBase);
- CloseHandle(hFileMapping);
- CloseHandle(hFile);
- return true;
- }
- bool bindexplib::AddObjectFile(const char* filename)
- {
- return DumpFile(filename, this->Symbols, this->DataSymbols);
- }
- bool bindexplib::AddDefinitionFile(const char* filename)
- {
- cmsys::ifstream infile(filename);
- if (!infile) {
- fprintf(stderr, "Couldn't open definition file '%s'\n", filename);
- return false;
- }
- std::string str;
- while (std::getline(infile, str)) {
-
- if ((str.compare(0, 7, "LIBRARY") == 0) ||
- (str.compare(0, 7, "EXPORTS") == 0)) {
- continue;
- }
-
- str.erase(0, str.find_first_not_of(" \t"));
- std::size_t found = str.find(" \t DATA");
- if (found != std::string::npos) {
- str.erase(found, std::string::npos);
- this->DataSymbols.insert(str);
- } else {
- this->Symbols.insert(str);
- }
- }
- infile.close();
- return true;
- }
- void bindexplib::WriteFile(FILE* file)
- {
- fprintf(file, "EXPORTS \n");
- for (std::string const& ds : this->DataSymbols) {
- fprintf(file, "\t%s \t DATA\n", ds.c_str());
- }
- for (std::string const& s : this->Symbols) {
- fprintf(file, "\t%s\n", s.c_str());
- }
- }
|