]> Cypherpunks repositories - gostls13.git/commitdiff
8l: pe executable building code changed to include import table for kernel32.dll...
authorAlex Brainman <alex.brainman@gmail.com>
Wed, 10 Feb 2010 08:47:52 +0000 (00:47 -0800)
committerRuss Cox <rsc@golang.org>
Wed, 10 Feb 2010 08:47:52 +0000 (00:47 -0800)
Fixes #586.

R=rsc
CC=golang-dev
https://golang.org/cl/203060

src/cmd/ld/pe.c
src/cmd/ld/pe.h

index 3a3099d044626e88b21a58f69378c56a662f7de4..15bd7b70d617581509f3d96729b68d56410531ef 100644 (file)
@@ -95,6 +95,78 @@ dope(void)
                IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
 }
 
+static void
+strput(char *s)
+{
+       while(*s)
+               cput(*s++);
+       cput('\0');
+}
+
+static void
+add_import_table(void)
+{
+       IMAGE_IMPORT_DESCRIPTOR ds[2], *d;
+       char *dllname = "kernel32.dll";
+       struct {
+               char *name;
+               uint32 thunk;
+       } *f, fs[] = {
+               { "GetProcAddress", 0 },
+               { "LoadLibraryExA", 0 },
+               { 0, 0 }
+       };
+
+       uint32 size = 0;
+       memset(ds, 0, sizeof(ds));
+       size += sizeof(ds);
+       ds[0].Name = size;
+       size += strlen(dllname) + 1;
+       for(f=fs; f->name; f++) {
+               f->thunk = size;
+               size += sizeof(uint16) + strlen(f->name) + 1;
+       }
+       ds[0].FirstThunk = size;
+       for(f=fs; f->name; f++)
+               size += sizeof(fs[0].thunk);
+
+       IMAGE_SECTION_HEADER *isect;
+       isect = new_section(".idata", size, 0);
+       isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
+               IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
+       
+       uint32 va = isect->VirtualAddress;
+       oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = va;
+       oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
+
+       ds[0].Name += va;
+       ds[0].FirstThunk += va;
+       for(f=fs; f->name; f++)
+               f->thunk += va;
+
+       vlong off = seek(cout, 0, 1);
+       seek(cout, 0, 2);
+       for(d=ds; ; d++) {
+               lputl(d->OriginalFirstThunk);
+               lputl(d->TimeDateStamp);
+               lputl(d->ForwarderChain);
+               lputl(d->Name);
+               lputl(d->FirstThunk);
+               if(!d->Name) 
+                       break;
+       }
+       strput(dllname);
+       for(f=fs; f->name; f++) {
+               wputl(0);
+               strput(f->name);
+       }
+       for(f=fs; f->name; f++)
+               lputl(f->thunk);
+       strnput("", isect->SizeOfRawData - size);
+       cflush();
+       seek(cout, off, 0);
+}
+
 void
 asmbpe(void)
 {
@@ -117,6 +189,8 @@ asmbpe(void)
                        IMAGE_SCN_CNT_INITIALIZED_DATA;
        }
 
+       add_import_table();
+
        fh.NumberOfSections = nsect;
        fh.TimeDateStamp = time(0);
        fh.SizeOfOptionalHeader = sizeof(oh);
index e7e2f9f08bb97d2f78f5f019e2e63eb4cfe86c68..b64dd97c07f8f964a8bc04b64ed826f7a0f861df 100644 (file)
@@ -64,6 +64,14 @@ typedef struct {
        uint32 Characteristics;
 } IMAGE_SECTION_HEADER;
 
+typedef struct {
+       uint32 OriginalFirstThunk;
+       uint32 TimeDateStamp;
+       uint32 ForwarderChain;
+       uint32 Name;
+       uint32 FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR;
+
 #define PERESERVE      0x400
 #define PEALIGN                0x200
 #define PEBASE         0x00400000
@@ -84,6 +92,23 @@ enum {
        IMAGE_SCN_MEM_EXECUTE = 0x20000000,
        IMAGE_SCN_MEM_READ = 0x40000000,
        IMAGE_SCN_MEM_WRITE = 0x80000000,
+
+       IMAGE_DIRECTORY_ENTRY_EXPORT = 0,
+       IMAGE_DIRECTORY_ENTRY_IMPORT = 1,
+       IMAGE_DIRECTORY_ENTRY_RESOURCE = 2,
+       IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3,
+       IMAGE_DIRECTORY_ENTRY_SECURITY = 4,
+       IMAGE_DIRECTORY_ENTRY_BASERELOC = 5,
+       IMAGE_DIRECTORY_ENTRY_DEBUG = 6,
+       IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7,
+       IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7,
+       IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8,
+       IMAGE_DIRECTORY_ENTRY_TLS = 9,
+       IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10,
+       IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11,
+       IMAGE_DIRECTORY_ENTRY_IAT = 12,
+       IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13,
+       IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14,
 };
 
 void peinit(void);