diff options
-rw-r--r-- | include/Input.h | 7 | ||||
-rw-r--r-- | lib/Input.cc | 35 |
2 files changed, 39 insertions, 3 deletions
diff --git a/include/Input.h b/include/Input.h index 181bf21..18173d2 100644 --- a/include/Input.h +++ b/include/Input.h @@ -7,7 +7,8 @@ #include <Handle.h> enum ArchiveType { - ARCHIVE_BUILTIN = 0 + ARCHIVE_BUILTIN = 0, + ARCHIVE_EXECUTABLE }; class Input : public Handle { @@ -54,8 +55,8 @@ extern Stdin_t Stdin; class Archive : public Base { public: - Archive(const String &, int = 0); - Archive(Handle *, int = 0); + Archive(const String &, int = ARCHIVE_BUILTIN); + Archive(Handle *, int = ARCHIVE_BUILTIN); virtual ~Archive(); protected: static bool inarchive(const String &); diff --git a/lib/Input.cc b/lib/Input.cc index 4f87599..6c7815f 100644 --- a/lib/Input.cc +++ b/lib/Input.cc @@ -203,14 +203,49 @@ Archive::Archive(Handle * hand, int atype) : create(); } +#pragma pack(1) + +struct PEsection_t { + char name[8]; + Uint32 VSize, VAdd, SizeOf, Pointer, PTRelocs, PTLNs; + Uint16 NR, NLN; + Uint32 Chars; +}; + void Archive::create() throw (GeneralException) { char buffer[1024]; int len; + Uint32 sig, ptr, maxptr = 0, startptr; + Uint16 sections; + PEsection_t PEsection; size_t size; FileTree * p = &filetree, * t; String ifname; + int i; switch(type) { + case ARCHIVE_EXECUTABLE: + startptr = archive->tell(); + sig = archive->readU32(); + if ((sig & 0xffff) == 0x5a4d) { /* MZ */ + archive->seek(56, SEEK_CUR); + sig = archive->readU32(); + archive->seek(sig - 64, SEEK_CUR); + sig = archive->readU32(); + if (sig != 0x4550) + throw GeneralException(_("Archive: file is not a PE.")); + archive->seek(2, SEEK_CUR); + sections = archive->readU16(); + archive->seek(240, SEEK_CUR); + for (i = 0; i < sections; i++) { + archive->read(&PEsection, sizeof(PEsection)); + printm(M_INFO, "Section: %s\n", PEsection.name); + ptr = PEsection.Pointer + PEsection.SizeOf; + if (ptr > maxptr) + maxptr = ptr; + } + archive->seek(startptr - archive->tell() + maxptr, SEEK_CUR); + } case ARCHIVE_BUILTIN: archive->read(buffer, 4); if (*((Uint32 *)buffer) != BUILTIN_SIG) |