Commit 48d2de7e authored by Alex Brainman's avatar Alex Brainman Committed by Russ Cox

8l: pe changes

Dll names and function names padded to even size.
Refactoring of imports writing code.

R=rsc
CC=golang-dev
https://golang.org/cl/3804042
parent ff25900b
...@@ -48,21 +48,20 @@ static IMAGE_SECTION_HEADER sh[16]; ...@@ -48,21 +48,20 @@ static IMAGE_SECTION_HEADER sh[16];
typedef struct Imp Imp; typedef struct Imp Imp;
struct Imp { struct Imp {
Sym* s; Sym* s;
long va; uvlong off;
long vb;
Imp* next; Imp* next;
}; };
typedef struct Dll Dll; typedef struct Dll Dll;
struct Dll { struct Dll {
char* name; char* name;
int count; uvlong nameoff;
uvlong thunkoff;
Imp* ms; Imp* ms;
Dll* next; Dll* next;
}; };
static Dll* dr; static Dll* dr;
static int ndll, nimp, nsize;
static IMAGE_SECTION_HEADER* static IMAGE_SECTION_HEADER*
addpesection(char *name, int sectsize, int filesize, Segment *s) addpesection(char *name, int sectsize, int filesize, Segment *s)
...@@ -136,9 +135,15 @@ pewrite(void) ...@@ -136,9 +135,15 @@ pewrite(void)
static void static void
strput(char *s) strput(char *s)
{ {
while(*s) int n;
for(n=0; *s; n++)
cput(*s++); cput(*s++);
cput('\0'); cput('\0');
n++;
// string must be padded to even size
if(n%2)
cput('\0');
} }
static Dll* static Dll*
...@@ -146,50 +151,33 @@ initdynimport(void) ...@@ -146,50 +151,33 @@ initdynimport(void)
{ {
Imp *m; Imp *m;
Dll *d; Dll *d;
Sym *s; Sym *s, *dynamic;
int i; int i;
Sym *dynamic;
dr = nil; dr = nil;
ndll = 0;
nimp = 0;
nsize = 0;
for(i=0; i<NHASH; i++) for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->hash) { for(s = hash[i]; s != S; s = s->hash) {
if(!s->reachable || !s->dynimpname) if(!s->reachable || !s->dynimpname)
continue; continue;
nimp++;
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
if(strcmp(d->name,s->dynimplib) == 0) { if(strcmp(d->name,s->dynimplib) == 0) {
m = mal(sizeof *m); m = mal(sizeof *m);
m->s = s;
m->next = d->ms;
d->ms = m;
d->count++;
nsize += strlen(s->dynimpname)+2+1;
break; break;
} }
} }
if(d == nil) { if(d == nil) {
d = mal(sizeof *d); d = mal(sizeof *d);
d->name = s->dynimplib; d->name = s->dynimplib;
d->count = 1;
d->next = dr; d->next = dr;
dr = d; dr = d;
m = mal(sizeof *m); m = mal(sizeof *m);
m->s = s;
m->next = 0;
d->ms = m;
ndll++;
nsize += strlen(s->dynimpname)+2+1;
nsize += strlen(s->dynimplib)+1;
} }
m->s = s;
m->next = d->ms;
d->ms = m;
} }
nsize += 20*ndll + 20;
nsize += 4*nimp + 4*ndll;
dynamic = lookup(".windynamic", 0); dynamic = lookup(".windynamic", 0);
dynamic->reachable = 1; dynamic->reachable = 1;
dynamic->type = SWINDOWS; dynamic->type = SWINDOWS;
...@@ -211,83 +199,84 @@ static void ...@@ -211,83 +199,84 @@ static void
addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect) addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
{ {
IMAGE_SECTION_HEADER *isect; IMAGE_SECTION_HEADER *isect;
uint32 va; uvlong n, oftbase, ftbase;
int noff, aoff, o, last_fn, last_name_off, iat_off;
Imp *m; Imp *m;
Dll *d; Dll *d;
Sym* dynamic; Sym* dynamic;
isect = addpesection(".idata", nsize, nsize, 0);
isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
va = isect->VirtualAddress;
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = va;
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
seek(cout, fileoff, 0);
dynamic = lookup(".windynamic", 0); dynamic = lookup(".windynamic", 0);
iat_off = dynamic->value - PEBASE; // FirstThunk allocated in .data
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = iat_off;
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
noff = va + 20*ndll + 20; // skip import descriptor table (will write it later)
aoff = noff + 4*nimp + 4*ndll; n = 0;
last_fn = 0; for(d = dr; d != nil; d = d->next)
last_name_off = aoff; n++;
seek(cout, fileoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1), 0);
// write dll names
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
lputl(noff); d->nameoff = cpos() - fileoff;
lputl(0); strput(d->name);
lputl(0);
lputl(last_name_off);
lputl(iat_off);
last_fn = d->count;
noff += 4*last_fn + 4;
aoff += 4*last_fn + 4;
iat_off += 4*last_fn + 4;
last_name_off += strlen(d->name)+1;
} }
lputl(0); //end
lputl(0); // write function names
lputl(0);
lputl(0);
lputl(0);
// put OriginalFirstThunk
o = last_name_off;
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
for(m = d->ms; m != nil; m = m->next) { for(m = d->ms; m != nil; m = m->next) {
lputl(o); m->off = nextsectoff + cpos() - fileoff;
o += 2 + strlen(m->s->dynimpname) + 1; wputl(0); // hint
strput(m->s->dynimpname);
} }
lputl(0);
} }
// put names
// write OriginalFirstThunks
oftbase = cpos() - fileoff;
n = cpos();
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
strput(d->name); d->thunkoff = cpos() - n;
for(m = d->ms; m != nil; m = m->next)
lputl(m->off);
lputl(0);
} }
// put hint+name
// add pe section and pad it at the end
n = cpos() - fileoff;
isect = addpesection(".idata", n, n, 0);
isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
strnput("", isect->SizeOfRawData - n);
cflush();
// write FirstThunks (allocated in .data section)
ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
seek(cout, datsect->PointerToRawData + ftbase, 0);
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
for(m = d->ms; m != nil; m = m->next) { for(m = d->ms; m != nil; m = m->next)
wputl(0); lputl(m->off);
strput(m->s->dynimpname); lputl(0);
}
} }
strnput("", isect->SizeOfRawData - nsize);
cflush(); cflush();
// put FirstThunk // finally write import descriptor table
o = last_name_off; seek(cout, fileoff, 0);
seek(cout, datsect->PointerToRawData + dynamic->value - PEBASE - datsect->VirtualAddress, 0);
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
for(m = d->ms; m != nil; m = m->next) { lputl(isect->VirtualAddress + oftbase + d->thunkoff);
lputl(o); lputl(0);
o += 2 + strlen(m->s->dynimpname) + 1;
}
lputl(0); lputl(0);
lputl(isect->VirtualAddress + d->nameoff);
lputl(datsect->VirtualAddress + ftbase + d->thunkoff);
} }
lputl(0); //end
lputl(0);
lputl(0);
lputl(0);
lputl(0);
cflush(); cflush();
// update data directory
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress;
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
seek(cout, 0, 2); seek(cout, 0, 2);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment