600
|
1 |
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
2 |
// All rights reserved.
|
|
3 |
// This component and the accompanying materials are made available
|
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
|
5 |
// which accompanies this distribution, and is available
|
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
7 |
//
|
|
8 |
// Initial Contributors:
|
|
9 |
// Nokia Corporation - initial contribution.
|
|
10 |
//
|
|
11 |
// Contributors:
|
|
12 |
//
|
|
13 |
// Description:
|
|
14 |
//
|
|
15 |
|
|
16 |
#include <stdlib.h>
|
|
17 |
#include <string.h>
|
|
18 |
#include <e32std.h>
|
|
19 |
#include <e32std_private.h>
|
|
20 |
#include "h_utl.h"
|
|
21 |
#include "pe_file.h"
|
|
22 |
|
|
23 |
TInt E32ImageFile_PE::CopyImportAddrTable(char *aPtr, PEFile &aPeFile)
|
|
24 |
//
|
|
25 |
// Copy the import address table entries
|
|
26 |
//
|
|
27 |
{
|
|
28 |
|
|
29 |
TUint *ptr=(TUint *)aPtr;
|
|
30 |
char *importsection=aPeFile.iSectionData[KImportSection];
|
|
31 |
TUint *src=(TUint *)importsection;
|
|
32 |
while (*src)
|
|
33 |
{
|
|
34 |
TUint vaoffset=src[4];
|
|
35 |
if (!gLittleEndian) ByteSwap(vaoffset);
|
|
36 |
TUint offset=vaoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress; // find the offset into the section of import addr table
|
|
37 |
vaoffset=src[3];
|
|
38 |
if (!gLittleEndian) ByteSwap(vaoffset);
|
|
39 |
TUint exportername=vaoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress;
|
|
40 |
TUint *p=(TUint *)(importsection+offset);
|
|
41 |
while (*p)
|
|
42 |
{
|
|
43 |
if ((*p&0x80000000)==0)
|
|
44 |
{
|
|
45 |
Print(EError, "%s exporting symbol by name\n", importsection+exportername);
|
|
46 |
return KErrGeneral;
|
|
47 |
}
|
|
48 |
*ptr++=(*p++)&0x7fffffff; // mask out the high bit (- indicates export by ordinal)
|
|
49 |
}
|
|
50 |
src+=5;
|
|
51 |
}
|
|
52 |
*ptr++=0;
|
|
53 |
return KErrNone;
|
|
54 |
}
|
|
55 |
|
|
56 |
extern char* gX86imp;
|
|
57 |
extern int gX86num_imports;
|
|
58 |
extern int gX86num_imp_dlls;
|
|
59 |
extern int gX86imp_size;
|
|
60 |
int* gX86imp_relocs=NULL;
|
|
61 |
|
|
62 |
TInt CrunchImportSection(TAny* aSection, TInt aNumImpDlls, TInt aNumImports)
|
|
63 |
{
|
|
64 |
// Remove lists of ordinals from import section
|
|
65 |
TInt* d = (TInt*)aSection;
|
|
66 |
TInt orig_size = *d;
|
|
67 |
TInt offset_correction = aNumImports*sizeof(TUint);
|
|
68 |
*d -= offset_correction; // reduce total section size
|
|
69 |
TInt *dd = d+1;
|
|
70 |
TInt *ss = d+1;
|
|
71 |
|
|
72 |
TInt i;
|
|
73 |
for (i=0; i<aNumImpDlls; ++i)
|
|
74 |
{
|
|
75 |
*dd++ = *ss++ - offset_correction; // copy name offset and reduce it appropriately
|
|
76 |
TInt nimp = *ss++; // number of imports from this DLL
|
|
77 |
*dd++ = nimp; // copy it
|
|
78 |
ss += nimp; // skip the ordinals in the original list
|
|
79 |
}
|
|
80 |
TInt used_size = (ss - d) * sizeof(TInt);
|
|
81 |
memcpy(dd, ss, orig_size - used_size); // copy name strings
|
|
82 |
|
|
83 |
return *d; // return new total section size
|
|
84 |
}
|
|
85 |
|
|
86 |
char *E32ImageFile_PE::CreateImportSection(const PEFile &aPeFile, TInt &aSize)
|
|
87 |
//
|
|
88 |
// Create a new format import section
|
|
89 |
//
|
|
90 |
{
|
|
91 |
|
|
92 |
int total_imports = 0;
|
|
93 |
if (gX86imp)
|
|
94 |
{
|
|
95 |
TUint *rdata=(TUint*)aPeFile.iSectionData[KConstSection];
|
|
96 |
TInt bytecount=gX86imp_size;
|
|
97 |
char* section=new char[bytecount];
|
|
98 |
memcpy(section,gX86imp,bytecount);
|
|
99 |
int i;
|
|
100 |
int j=0;
|
|
101 |
int* s=(int*)section;
|
|
102 |
s++;
|
|
103 |
gX86imp_relocs=new int[gX86num_imports+gX86num_imp_dlls];
|
|
104 |
for (i=0; i<gX86num_imp_dlls; ++i)
|
|
105 |
{
|
|
106 |
++s;
|
|
107 |
int n=*s++;
|
|
108 |
total_imports += n;
|
|
109 |
while (n--)
|
|
110 |
{
|
|
111 |
int rdata_int_offset=*s>>2;
|
|
112 |
*s=rdata[rdata_int_offset]&0x7fffffffu; // rdata offset to ordinal
|
|
113 |
gX86imp_relocs[rdata_int_offset]=j<<2;
|
|
114 |
++j;
|
|
115 |
++s;
|
|
116 |
}
|
|
117 |
}
|
|
118 |
*(TInt*)section = bytecount;
|
|
119 |
aSize = CrunchImportSection(section, gX86num_imp_dlls, total_imports);
|
|
120 |
return section;
|
|
121 |
}
|
|
122 |
PIMAGE_SECTION_HEADER aHeader=aPeFile.iSectionHeader[KImportSection];
|
|
123 |
TUint *aSrc=(TUint *)aPeFile.iSectionData[KImportSection];
|
|
124 |
|
|
125 |
TInt nimportdlls=aPeFile.NumberOfImportDlls();
|
|
126 |
if (nimportdlls==0)
|
|
127 |
{
|
|
128 |
aSize=0;
|
|
129 |
return NULL;
|
|
130 |
}
|
|
131 |
E32ImportBlock *block=new E32ImportBlock [nimportdlls];
|
|
132 |
char **name=new char* [nimportdlls];
|
|
133 |
TUint **import=new TUint* [nimportdlls];
|
|
134 |
|
|
135 |
TInt bytecount=sizeof(E32ImportSection)+sizeof(E32ImportBlock)*nimportdlls;
|
|
136 |
TUint *src=aSrc;
|
|
137 |
TInt i;
|
|
138 |
for (i=0; i<nimportdlls; i++)
|
|
139 |
{
|
|
140 |
TUint vaoffset=src[4];
|
|
141 |
if (!gLittleEndian) ByteSwap(vaoffset);
|
|
142 |
TUint offset=vaoffset-aHeader->VirtualAddress; // find the offset into the section of import addr table
|
|
143 |
TUint *p=aSrc+offset/4;
|
|
144 |
block[i].iNumberOfImports=0;
|
|
145 |
while (*p++)
|
|
146 |
block[i].iNumberOfImports++;
|
|
147 |
total_imports += block[i].iNumberOfImports;
|
|
148 |
import[i]=new TUint [block[i].iNumberOfImports];
|
|
149 |
TInt j;
|
|
150 |
p=aSrc+offset/4;
|
|
151 |
for (j=0; j<block[i].iNumberOfImports; j++)
|
|
152 |
{
|
|
153 |
import[i][j]=(*p++)&0x7fffffffu;
|
|
154 |
bytecount+=4;
|
|
155 |
}
|
|
156 |
// name
|
|
157 |
vaoffset=src[3];
|
|
158 |
if (!gLittleEndian) ByteSwap(vaoffset);
|
|
159 |
offset=vaoffset-aHeader->VirtualAddress;
|
|
160 |
name[i]=((char *)aSrc)+offset;
|
|
161 |
bytecount+=strlen(name[i])+1;
|
|
162 |
src+=5;
|
|
163 |
}
|
|
164 |
|
|
165 |
bytecount=ALIGN4(bytecount);
|
|
166 |
char *section=new char [bytecount];
|
|
167 |
char *s=section+sizeof(E32ImportSection);
|
|
168 |
for (i=0; i<nimportdlls; i++)
|
|
169 |
{
|
|
170 |
memcpy(s, (char *)&block[i], sizeof(E32ImportBlock));
|
|
171 |
s+=sizeof(E32ImportBlock);
|
|
172 |
memcpy(s, (char *)import[i], block[i].iNumberOfImports*4);
|
|
173 |
s+=block[i].iNumberOfImports*4;
|
|
174 |
}
|
|
175 |
char *t=section+sizeof(E32ImportSection);
|
|
176 |
for (i=0; i<nimportdlls; i++)
|
|
177 |
{
|
|
178 |
((E32ImportBlock *)t)->iOffsetOfDllName=s-section;
|
|
179 |
strcpy(s, name[i]);
|
|
180 |
s+=strlen(name[i])+1;
|
|
181 |
t += ((E32ImportBlock *)t)->iNumberOfImports * sizeof(TUint) + sizeof(E32ImportBlock);
|
|
182 |
}
|
|
183 |
while ((s-section)<bytecount)
|
|
184 |
*s++=0;
|
|
185 |
|
|
186 |
// free mem
|
|
187 |
for (i=0; i<nimportdlls; i++)
|
|
188 |
delete import[i];
|
|
189 |
delete block;
|
|
190 |
delete import;
|
|
191 |
delete name;
|
|
192 |
|
|
193 |
*(TInt*)section = bytecount;
|
|
194 |
aSize = CrunchImportSection(section, nimportdlls, total_imports);
|
|
195 |
return section;
|
|
196 |
}
|
|
197 |
|
|
198 |
TUint E32ImageFile_PE::FixImportThunk(PEFile &aPeFile, TUint va)
|
|
199 |
//
|
|
200 |
// Fix an access to the import address table
|
|
201 |
//
|
|
202 |
{
|
|
203 |
|
|
204 |
TUint *imports=(TUint *)aPeFile.iSectionData[KImportSection];
|
|
205 |
TUint n=0;
|
|
206 |
TUint importoffset=imports[4];
|
|
207 |
if (!gLittleEndian) ByteSwap(importoffset);
|
|
208 |
TUint iat=importoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress;
|
|
209 |
|
|
210 |
while (iat<va)
|
|
211 |
{
|
|
212 |
if (*((TUint *)(aPeFile.iSectionData[KImportSection]+iat))==0)
|
|
213 |
{
|
|
214 |
imports+=5;
|
|
215 |
importoffset=imports[4];
|
|
216 |
if (!gLittleEndian) ByteSwap(importoffset);
|
|
217 |
iat=importoffset-aPeFile.iSectionHeader[KImportSection]->VirtualAddress;
|
|
218 |
}
|
|
219 |
else
|
|
220 |
{
|
|
221 |
n++;
|
|
222 |
iat+=4;
|
|
223 |
}
|
|
224 |
}
|
|
225 |
|
|
226 |
// Flag errors brought about by a corrupt input binary
|
|
227 |
if (iat>va)
|
|
228 |
{
|
|
229 |
Print(EError, "%s is corrupt - problem processing import address table.\n", this->iFileName);
|
|
230 |
return (TUint)KErrGeneral;
|
|
231 |
}
|
|
232 |
|
|
233 |
return iHdr->iTextSize+n*sizeof(TUint);
|
|
234 |
}
|
|
235 |
|