summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Input.h7
-rw-r--r--lib/Input.cc35
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)