summaryrefslogtreecommitdiff
path: root/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h')
-rwxr-xr-xutils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h1139
1 files changed, 1139 insertions, 0 deletions
diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h
new file mode 100755
index 0000000000..6578f0712a
--- /dev/null
+++ b/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h
@@ -0,0 +1,1139 @@
1/*
2* ImportDirectory.h - Part of the PeLib library.
3*
4* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
5* All rights reserved.
6*
7* This software is licensed under the zlib/libpng License.
8* For more details see http://www.opensource.org/licenses/zlib-license.php
9* or the license information file (license.htm) in the root directory
10* of PeLib.
11*/
12
13#ifndef IMPORTDIRECTORY_H
14#define IMPORTDIRECTORY_H
15
16#include "PeLibAux.h"
17#include "PeHeader.h"
18
19namespace PeLib
20{
21 /// Parameter for functions that can operate on the OLDDIR or new import directory.
22 enum currdir {OLDDIR = 1, NEWDIR};
23
24 class PeLibException;
25
26 /// Class that handles import directories.
27 /**
28 * This class can read import directories from existing PE files or start completely from scratch.
29 * Modifying import directories and writing them to files is also possible.
30 * It's worthy to note that many functions require an extra parameter of type currdir
31 * because the structure of import directories make it necessary that the OLDDIR import directory
32 * must be preserved. That's why some functions (like adding and removing) imported functions
33 * only exist for the new import directory, not for the one which is already written to the file.
34 * \todo Adding functions by ordinal doesn't work yet (rebuild needs to be changed).
35 * \todo Somehow store the rvas of the chunks in the file.
36 **/
37 template<int bits>
38 class ImportDirectory
39 {
40 typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::iterator ImpDirFileIterator;
41 typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::const_iterator ConstImpDirFileIterator;
42
43 private:
44 /// Stores information about already imported DLLs.
45 std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vOldiid;
46 /// Stores information about imported DLLs which will be added.
47 std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vNewiid;
48
49 // I can't convince Borland C++ to compile the function outside of the class declaration.
50 // That's why the function definition is here.
51 /// Tests if a certain function is imported.
52 template<typename T> bool hasFunction(std::string strFilename, T value, bool(PELIB_THUNK_DATA<bits>::* comp)(T) const) const
53 {
54 ConstImpDirFileIterator FileIter = m_vOldiid.begin();
55 ConstImpDirFileIterator EndIter = m_vOldiid.end();
56
57 for (int i=0;i<=1;i++) // Loop once for m_vOldiid and once for m_vNewiid
58 {
59 do
60 {
61 FileIter = std::find_if(FileIter, EndIter, std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
62
63 if (FileIter != EndIter)
64 {
65 typename std::vector<PELIB_THUNK_DATA<bits> >::const_iterator Iter = std::find_if(FileIter->originalfirstthunk.begin(), FileIter->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(comp), value));
66 if (Iter != FileIter->originalfirstthunk.end())
67 {
68 return true;
69 }
70 ++FileIter;
71 }
72 }
73 while (FileIter != EndIter);
74
75 FileIter = m_vNewiid.begin();
76 EndIter = m_vNewiid.end();
77 }
78
79 return false;
80 }
81
82
83 public:
84
85 /// Add a function to the import directory.
86 int addFunction(const std::string& strFilename, word wHint); // EXPORT _byHint
87 /// Add a function to the import directory.
88 int addFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName
89
90 /// Get the ID of a file through it's name.
91 unsigned int getFileIndex(const std::string& strFilename, currdir cdDir) const; // EXPORT
92 /// Get the ID of a function through it's name.
93 unsigned int getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const; // EXPORT
94
95 /// Get the name of an imported file.
96 std::string getFileName(dword dwFilenr, currdir cdDir) const; // EXPORT
97
98 void setFileName(dword filenr, currdir dir, const std::string& name); // EXPORT
99
100 /// Get the hint of an imported function.
101 word getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT
102 void setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value); // EXPORT
103 /// Get the name of an imported function.
104 std::string getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT
105 void setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName); // EXPORT
106 /// Get the number of files which are imported.
107 dword getNumberOfFiles(currdir cdDir) const; // EXPORT
108 /// Get the number of fucntions which are imported by a specific file.
109 dword getNumberOfFunctions(dword dwFilenr, currdir cdDir) const; // EXPORT
110 /// Read a file's import directory.
111 int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader); // EXPORT
112 /// Rebuild the import directory.
113 void rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries = true) const; // EXPORT
114 /// Remove a file from the import directory.
115 int removeFile(const std::string& strFilename); // EXPORT
116 /// Remove a function from the import directory.
117 int removeFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName
118 /// Remove a function from the import directory.
119 int removeFunction(const std::string& strFilename, word wHint); // EXPORT _byHint
120 /// Returns the size of the current import directory.
121 unsigned int size() const; // EXPORT
122 /// Writes the import directory to a file.
123 int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva); // EXPORT
124
125 /// Returns the FirstThunk value of a function.
126 dword getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber
127 void setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT _byNumber
128 /// Returns the OriginalFirstThunk value of a function.
129 dword getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber
130 void setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT
131
132// dword getFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException);
133// dword getOriginalFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException);
134
135 /// Returns the FirstThunk value of a file.
136 dword getFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
137 /// Returns the OriginalFirstThunk value of a file.
138 dword getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
139 /// Returns the ForwarderChain value of a file.
140 dword getForwarderChain(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
141 dword getRvaOfName(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
142 /// Returns the TimeDateStamp value of a file.
143 dword getTimeDateStamp(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName
144
145 /// Returns the FirstThunk value of a file.
146 dword getFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT
147 void setFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function
148 /// Returns the OriginalFirstThunk value of a file.
149 dword getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT
150 void setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function
151 /// Returns the ForwarderChain value of a file.
152 dword getForwarderChain(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber
153 void setForwarderChain(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function
154 dword getRvaOfName(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber
155 void setRvaOfName(dword dwFilenr, currdir cdDir, dword value); // EXPORT
156 /// Returns the TimeDateStamp value of a file.
157 dword getTimeDateStamp(dword dwFilenr, currdir cdDir) const; // EXPORT
158 void setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber
159
160// word getFunctionHint(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException);
161 };
162
163 /**
164 * Add another import (by Ordinal) to the current file. Note that the import table is not automatically updated.
165 * The new imported functions will be added when you recalculate the import table as it's necessary
166 * to specify the address the import table will have in the file.
167 * @param strFilename The name of a DLL.
168 * @param wHint The ordinal of the function in the DLL.
169 **/
170 template<int bits>
171 int ImportDirectory<bits>::addFunction(const std::string& strFilename, word wHint)
172 {
173 if (hasFunction(strFilename, wHint, &PELIB_THUNK_DATA<bits>::equalHint))
174 {
175 return ERROR_DUPLICATE_ENTRY;
176 }
177
178 // Find the imported file.
179 ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
180
181 PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid;
182 PELIB_THUNK_DATA<bits> td;
183 td.hint = wHint;
184 td.itd.Ordinal = wHint | PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG;
185 iid.name = strFilename;
186 if (FileIter == m_vNewiid.end())
187 {
188 iid.originalfirstthunk.push_back(td);
189 iid.firstthunk.push_back(td);
190 m_vNewiid.push_back(iid);
191 }
192 else
193 {
194 FileIter->originalfirstthunk.push_back(td);
195 FileIter->firstthunk.push_back(td);
196 }
197
198 return NO_ERROR;
199 }
200
201 /**
202 * Add a function to the Import Directory.
203 * @param strFilename Name of the file which will be imported
204 * @param strFuncname Name of the function which will be imported.
205 **/
206 template<int bits>
207 int ImportDirectory<bits>::addFunction(const std::string& strFilename, const std::string& strFuncname)
208 {
209 if (hasFunction(strFilename, strFuncname, &PELIB_THUNK_DATA<bits>::equalFunctionName))
210 {
211 return ERROR_DUPLICATE_ENTRY;
212 }
213
214 // Find the imported file.
215 ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
216
217 PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid;
218 PELIB_THUNK_DATA<bits> td;
219 td.fname = strFuncname;
220 iid.name = strFilename;
221 if (FileIter == m_vNewiid.end())
222 {
223 iid.originalfirstthunk.push_back(td);
224 iid.firstthunk.push_back(td);
225 m_vNewiid.push_back(iid);
226 }
227 else
228 {
229 FileIter->originalfirstthunk.push_back(td);
230 FileIter->firstthunk.push_back(td);
231 }
232
233 return NO_ERROR;
234 }
235
236 /**
237 * Searches through the import directory and returns the number of the import
238 * directory entry which belongs to the given filename.
239 * @param strFilename Name of the imported file.
240 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
241 * @return The ID of an imported file.
242 **/
243 template<int bits>
244 unsigned int ImportDirectory<bits>::getFileIndex(const std::string& strFilename, currdir cdDir) const
245 {
246 const std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >* currDir;
247
248 if (cdDir == OLDDIR)
249 {
250 currDir = &m_vOldiid;
251 }
252 else
253 {
254 currDir = &m_vNewiid;
255 }
256
257 ConstImpDirFileIterator FileIter = std::find_if(currDir->begin(), currDir->end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename));
258
259 if (FileIter != currDir->end())
260 {
261 return static_cast<unsigned int>(std::distance(currDir->begin(), FileIter));
262 }
263 else
264 {
265 return -1;
266 // throw Exceptions::InvalidName(ImportDirectoryId, __LINE__);
267 }
268
269 return NO_ERROR;
270 }
271
272 /**
273 * Searches through an imported file for a specific function.
274 * @param strFilename Name of the imported file.
275 * @param strFuncname Name of the imported function.
276 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
277 * @return ID of the imported function.
278 **/
279 template<int bits>
280 unsigned int ImportDirectory<bits>::getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const
281 {
282 unsigned int uiFile = getFileIndex(strFilename, cdDir);
283
284 for (unsigned int i=0;i<getNumberOfFunctions(uiFile, cdDir);i++)
285 {
286 if (getFunctionName(uiFile, i, cdDir) == strFuncname) return i;
287 }
288
289 return -1;
290 }
291
292 /**
293 * Get the name of an imported file.
294 * @param dwFilenr Identifies which file should be checked.
295 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
296 * @return Name of an imported file.
297 **/
298 template<int bits>
299 std::string ImportDirectory<bits>::getFileName(dword dwFilenr, currdir cdDir) const
300 {
301 if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].name;
302 else return m_vNewiid[dwFilenr].name;
303 }
304
305 template<int bits>
306 void ImportDirectory<bits>::setFileName(dword filenr, currdir dir, const std::string& name)
307 {
308 if (dir == OLDDIR) m_vOldiid[filenr].name = name;
309 else m_vNewiid[filenr].name = name;
310 }
311
312 /**
313 * Get the name of an imported function.
314 * @param dwFilenr Identifies which file should be checked.
315 * @param dwFuncnr Identifies which function should be checked.
316 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
317 * @return Name of an imported function.
318 * \todo Marked line is unsafe (function should be rewritten).
319 **/
320 template<int bits>
321 std::string ImportDirectory<bits>::getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
322 {
323 if (cdDir == OLDDIR)
324 {
325 // Unsafe
326 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
327 {
328 return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname;
329 }
330 else
331 {
332 return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname;
333 }
334 }
335 else
336 {
337 if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk)
338 {
339 return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname;
340 }
341 else
342 {
343 return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname;
344 }
345 }
346 }
347
348 template<int bits>
349 void ImportDirectory<bits>::setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName)
350 {
351 if (cdDir == OLDDIR)
352 {
353 // Unsafe
354 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
355 {
356 m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName;
357 }
358 else
359 {
360 m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName;
361 }
362 }
363 else
364 {
365 if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk)
366 {
367 m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName;
368 }
369 else
370 {
371 m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName;
372 }
373 }
374 }
375
376 /**
377 * Get the hint of an imported function.
378 * @param dwFilenr Identifies which file should be checked.
379 * @param dwFuncnr Identifies which function should be checked.
380 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
381 * @return Hint of an imported function.
382 **/
383 template<int bits>
384 word ImportDirectory<bits>::getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
385 {
386 if (cdDir == OLDDIR)
387 {
388 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
389 {
390 return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint;
391 }
392 else
393 {
394 return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint;
395 }
396 }
397 else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint;
398 }
399
400 template<int bits>
401 void ImportDirectory<bits>::setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value)
402 {
403 if (cdDir == OLDDIR)
404 {
405 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk)
406 {
407 m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value;
408 }
409 else
410 {
411 m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint = value;
412 }
413 }
414 else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value;
415 }
416
417 /**
418 * Get the number of files which are currently being imported.
419 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
420 * @return Number of files which are currently being imported.
421 **/
422 template<int bits>
423 dword ImportDirectory<bits>::getNumberOfFiles(currdir cdDir) const
424 {
425 if (cdDir == OLDDIR) return static_cast<dword>(m_vOldiid.size());
426 else return static_cast<dword>(m_vNewiid.size());
427 }
428
429 /**
430 * Get the number of functions which are currently being imported from a specific file.
431 * @param dwFilenr Identifies which file should be checked.
432 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
433 * @return Number of functions which are currently being imported from a specific file.
434 **/
435 template<int bits>
436 dword ImportDirectory<bits>::getNumberOfFunctions(dword dwFilenr, currdir cdDir) const
437 {
438 if (cdDir == OLDDIR) return static_cast<unsigned int>(m_vOldiid[dwFilenr].firstthunk.size());
439 else return static_cast<unsigned int>(m_vNewiid[dwFilenr].firstthunk.size());
440 }
441
442 /**
443 * Read an import directory from a file.
444 * \todo Check if streams failed.
445 * @param strFilename Name of the file which will be read.
446 * @param uiOffset Offset of the import directory (see #PeLib::PeHeader::getIDImportRVA).
447 * @param uiSize Size of the import directory (see #PeLib::PeHeader::getIDImportSize).
448 * @param pehHeader A valid PE header.
449 **/
450 template<int bits>
451 int ImportDirectory<bits>::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader)
452 {
453 std::ifstream ifFile(strFilename.c_str(), std::ios_base::binary);
454
455 if (!ifFile)
456 {
457 return ERROR_OPENING_FILE;
458 }
459
460 unsigned int uiFileSize = fileSize(ifFile);
461
462 if (uiFileSize < uiOffset + uiSize)
463 {
464 return ERROR_INVALID_FILE;
465 }
466
467 ifFile.seekg(uiOffset, std::ios_base::beg);
468
469 std::vector<unsigned char> vImportdirectory(uiSize);
470 ifFile.read(reinterpret_cast<char*>(&vImportdirectory[0]), uiSize);
471
472 PELIB_IMAGE_IMPORT_DIRECTORY<bits> iidCurr;
473 unsigned int uiDesccounter = 0;
474
475 InputBuffer inpBuffer(vImportdirectory);
476
477 std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > vOldIidCurr;
478
479 do // Read and store all descriptors
480 {
481 inpBuffer >> iidCurr.impdesc.OriginalFirstThunk;
482 inpBuffer >> iidCurr.impdesc.TimeDateStamp;
483 inpBuffer >> iidCurr.impdesc.ForwarderChain;
484 inpBuffer >> iidCurr.impdesc.Name;
485 inpBuffer >> iidCurr.impdesc.FirstThunk;
486
487 if (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 ||
488 iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0)
489 {
490 vOldIidCurr.push_back(iidCurr);
491 }
492
493 uiDesccounter++;
494
495 if (uiSize < (uiDesccounter + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) break;
496 } while (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 ||
497 iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0);
498
499 char namebuffer[2] = {0};
500
501 // Name
502 for (unsigned int i=0;i<vOldIidCurr.size();i++)
503 {
504 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].impdesc.Name)), std::ios_base::beg);
505
506 std::string dllname = "";
507
508 do
509 {
510 ifFile.read(namebuffer, 1);
511 if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte
512 dllname += namebuffer;
513 } while (true);
514
515 vOldIidCurr[i].name = dllname;
516
517 }
518
519 // OriginalFirstThunk
520 for (unsigned int i=0;i<vOldIidCurr.size();i++)
521 {
522 PELIB_THUNK_DATA<bits> tdCurr;
523 dword uiVaoft = vOldIidCurr[i].impdesc.OriginalFirstThunk;
524
525 if (!uiVaoft)
526 {
527 continue;
528 }
529
530 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg);
531
532 do
533 {
534 if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal))
535 {
536 return ERROR_INVALID_FILE;
537 }
538 uiVaoft += sizeof(tdCurr.itd.Ordinal);
539
540 ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal));
541 if (tdCurr.itd.Ordinal) vOldIidCurr[i].originalfirstthunk.push_back(tdCurr);
542 } while (tdCurr.itd.Ordinal);
543 }
544
545 // FirstThunk
546 for (unsigned int i=0;i<vOldIidCurr.size();i++)
547 {
548 dword uiVaoft = vOldIidCurr[i].impdesc.FirstThunk;
549 PELIB_THUNK_DATA<bits> tdCurr;
550
551 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg);
552
553 do
554 {
555 if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal))
556 {
557 return ERROR_INVALID_FILE;
558 }
559
560 uiVaoft += sizeof(tdCurr.itd.Ordinal);
561
562 ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal));
563 if (tdCurr.itd.Ordinal) vOldIidCurr[i].firstthunk.push_back(tdCurr);
564 } while (tdCurr.itd.Ordinal);
565 }
566
567 // Names
568 for (unsigned int i=0;i<vOldIidCurr.size();i++)
569 {
570 if (vOldIidCurr[i].impdesc.OriginalFirstThunk)
571 {
572 for (unsigned int j=0;j<vOldIidCurr[i].originalfirstthunk.size();j++)
573 {
574 if (vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG)
575 {
576 vOldIidCurr[i].originalfirstthunk[j].hint = 0;
577 continue;
578 }
579
580 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal)), std::ios_base::beg);
581
582 ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].originalfirstthunk[j].hint), sizeof(vOldIidCurr[i].originalfirstthunk[j].hint));
583
584 if (!ifFile)
585 return ERROR_INVALID_FILE;
586
587 std::string funcname = "";
588 do
589 {
590 ifFile.read(namebuffer, 1);
591 if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte
592 funcname += namebuffer;
593 } while (true);
594
595 vOldIidCurr[i].originalfirstthunk[j].fname = funcname;
596 }
597 }
598 else
599 {
600 for (unsigned int j=0;j<vOldIidCurr[i].firstthunk.size();j++)
601 {
602 if (vOldIidCurr[i].firstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG)
603 {
604 continue;
605 }
606
607 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].firstthunk[j].itd.Ordinal)), std::ios_base::beg);
608
609 ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].firstthunk[j].hint), sizeof(vOldIidCurr[i].firstthunk[j].hint));
610
611 if (!ifFile)
612 return ERROR_INVALID_FILE;
613
614 std::string funcname = "";
615 do
616 {
617 ifFile.read(namebuffer, 1);
618 if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte
619 funcname += namebuffer;
620 } while (true);
621
622 vOldIidCurr[i].firstthunk[j].fname = funcname;
623 }
624 }
625 }
626 std::swap(vOldIidCurr, m_vOldiid);
627 return NO_ERROR;
628 }
629
630 /**
631 * Rebuilds the import directory.
632 * @param vBuffer Buffer the rebuilt import directory will be written to.
633 * @param dwRva The RVA of the ImportDirectory in the file.
634 * \todo uiSizeoffuncnames is not used.
635 **/
636 template<int bits>
637 void ImportDirectory<bits>::rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries) const
638 {
639 unsigned int uiImprva = dwRva;
640 unsigned int uiSizeofdescriptors = (static_cast<unsigned int>(m_vNewiid.size() + m_vOldiid.size()) + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size();
641
642 unsigned int uiSizeofdllnames = 0, uiSizeoffuncnames = 0;
643 unsigned int uiSizeofoft = 0;
644
645 for (unsigned int i=0;i<m_vNewiid.size();i++)
646 {
647 uiSizeofdllnames += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1;
648 uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size();
649
650 for(unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++)
651 {
652 // +3 for hint (word) and 00-byte
653 uiSizeoffuncnames += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3);
654 }
655 }
656
657// for (unsigned int i=0;i<m_vNewiid.size();i++)
658// {
659// uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size();
660// }
661
662 OutputBuffer obBuffer(vBuffer);
663
664 // Rebuild IMAGE_IMPORT_DESCRIPTORS
665 for (unsigned int i=0;i<m_vOldiid.size();i++)
666 {
667 obBuffer << m_vOldiid[i].impdesc.OriginalFirstThunk;
668 obBuffer << m_vOldiid[i].impdesc.TimeDateStamp;
669 obBuffer << m_vOldiid[i].impdesc.ForwarderChain;
670 obBuffer << m_vOldiid[i].impdesc.Name;
671 obBuffer << m_vOldiid[i].impdesc.FirstThunk;
672 }
673
674 unsigned int dllsize = 0;
675
676 for (unsigned int i=0;i<m_vNewiid.size();i++)
677 {
678 dword dwPoft = uiSizeofdescriptors + uiImprva;
679
680 for (unsigned int j=1;j<=i;j++)
681 {
682 dwPoft += (static_cast<unsigned int>(m_vNewiid[j-1].originalfirstthunk.size()) + 1) * PELIB_IMAGE_THUNK_DATA<bits>::size();
683 }
684
685 obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.OriginalFirstThunk);
686 obBuffer << m_vNewiid[i].impdesc.TimeDateStamp;
687 obBuffer << m_vNewiid[i].impdesc.ForwarderChain;
688 dword dwPdll = uiSizeofdescriptors + uiSizeofoft + uiImprva + dllsize;
689 obBuffer << (fixEntries ? dwPdll : m_vNewiid[i].impdesc.Name);
690 obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.FirstThunk);
691
692 dllsize += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1;
693 }
694
695 obBuffer << (dword)0;
696 obBuffer << (dword)0;
697 obBuffer << (dword)0;
698 obBuffer << (dword)0;
699 obBuffer << (dword)0;
700
701 unsigned int uiPfunc = uiSizeofdescriptors + uiSizeofoft + uiSizeofdllnames + uiImprva;
702
703 // Rebuild original first thunk
704 for (unsigned int i=0;i<m_vNewiid.size();i++)
705 {
706 for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++)
707 {
708 if (m_vNewiid[i].originalfirstthunk[j].itd.Ordinal & PELIB_IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG
709 || fixEntries == false)
710 {
711 obBuffer << m_vNewiid[i].originalfirstthunk[j].itd.Ordinal;
712 }
713 else
714 {
715 obBuffer << uiPfunc;
716 }
717 uiPfunc += static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3;
718 }
719 obBuffer << (dword)0;
720 }
721
722 // Write dllnames into import directory
723 for (unsigned int i=0;i<m_vNewiid.size();i++)
724 {
725 obBuffer.add(m_vNewiid[i].name.c_str(), static_cast<unsigned int>(m_vNewiid[i].name.size())+1);
726 }
727
728 // Write function names into directory
729 for (unsigned int i=0;i<m_vNewiid.size();i++)
730 {
731 for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++)
732 {
733 obBuffer << m_vNewiid[i].originalfirstthunk[j].hint;
734 obBuffer.add(m_vNewiid[i].originalfirstthunk[j].fname.c_str(), static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 1);
735 }
736 }
737 }
738
739 /**
740 * Removes a specific file and all functions of it from the import directory.
741 * @param strFilename Name of the file which will be removed.
742 **/
743 template<int bits>
744 int ImportDirectory<bits>::removeFile(const std::string& strFilename)
745 {
746 unsigned int oldSize = static_cast<unsigned int>(m_vNewiid.size());
747
748 m_vNewiid.erase(std::remove_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)), m_vNewiid.end());
749
750 return oldSize == m_vNewiid.size() ? 1 : 0;
751 }
752
753 /**
754 * Removes a specific function from the import directory.
755 * @param strFilename Name of the file which exports the function.
756 * @param strFuncname Name of the imported function.
757 **/
758 template<int bits>
759 int ImportDirectory<bits>::removeFunction(const std::string& strFilename, const std::string& strFuncname)
760 {
761 ImpDirFileIterator viPos = m_vNewiid.begin();
762
763 int notFound = 1;
764
765 while (viPos != m_vNewiid.end())
766 {
767 if (isEqualNc(viPos->name, strFilename))
768 {
769 unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size());
770 viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalFunctionName), strFuncname)), viPos->originalfirstthunk.end());
771 //viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(CompPolicy<PELIB_THUNK_DATA, std::string>(), strFuncname)));
772 if (viPos->originalfirstthunk.size() != oldSize) notFound = 0;
773 }
774 ++viPos;
775 }
776
777 return notFound;
778 }
779
780 /**
781 * Removes a specific function from the import directory.
782 * @param strFilename Name of the file which exports the function.
783 * @param wHint The hint of the function.
784 **/
785 template<int bits>
786 int ImportDirectory<bits>::removeFunction(const std::string& strFilename, word wHint)
787 {
788 ImpDirFileIterator viPos = m_vNewiid.begin();
789 int notFound = 1;
790
791 while (viPos != m_vNewiid.end())
792 {
793 if (isEqualNc(viPos->name, strFilename))
794 {
795 unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size());
796 viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalHint), wHint)), viPos->originalfirstthunk.end());
797 unsigned int newPos = static_cast<unsigned int>(viPos->originalfirstthunk.size());
798 if (viPos->originalfirstthunk.size() != oldSize) notFound = 0;
799 }
800 ++viPos;
801 }
802
803 return notFound;
804 }
805
806 /**
807 * Writes the current import directory to a file.
808 * @param strFilename Name of the file.
809 * @param uiOffset File Offset of the new import directory.
810 * @param uiRva RVA which belongs to that file offset.
811 **/
812 template<int bits>
813 int ImportDirectory<bits>::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva)
814 {
815 std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
816
817 if (!ofFile)
818 {
819 ofFile.clear();
820 ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
821 }
822 else
823 {
824 ofFile.close();
825 ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
826 }
827
828 if (!ofFile)
829 {
830 return ERROR_OPENING_FILE;
831 }
832
833 ofFile.seekp(uiOffset, std::ios_base::beg);
834
835 std::vector<byte> vBuffer;
836
837 rebuild(vBuffer, uiRva);
838
839 ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), vBuffer.size());
840 ofFile.close();
841
842 std::copy(m_vNewiid.begin(), m_vNewiid.end(), std::back_inserter(m_vOldiid));
843 m_vNewiid.clear();
844
845 return NO_ERROR;
846 }
847
848 /**
849 * Returns the size of the import directory.
850 * @return Size of the import directory.
851 **/
852 template<int bits>
853 unsigned int ImportDirectory<bits>::size() const
854 {
855 // Only the descriptors of m_vOldiid must be rebuilt, not the data they point to.
856 return std::accumulate(m_vNewiid.begin(), m_vNewiid.end(), 0, accumulate<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >)
857 + (m_vOldiid.size() + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size();
858 }
859
860 /**
861 * @param strFilename Name of the imported file.
862 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
863 * @return FirstThunk value of an imported file.
864 **/
865 template<int bits>
866 dword ImportDirectory<bits>::getFirstThunk(const std::string& strFilename, currdir cdDir) const
867 {
868 if (cdDir == OLDDIR)
869 {
870 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk;
871 }
872 else
873 {
874 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk;
875 }
876 }
877
878 /**
879 * @param strFilename Name of the imported file.
880 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
881 * @return OriginalFirstThunk value of an imported file.
882 **/
883 template<int bits>
884 dword ImportDirectory<bits>::getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const
885 {
886 if (cdDir == OLDDIR)
887 {
888 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk;
889 }
890 else
891 {
892 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk;
893 }
894 }
895
896 /**
897 * @param strFilename Name of the imported file.
898 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
899 * @return ForwarderChain value of an imported file.
900 **/
901 template<int bits>
902 dword ImportDirectory<bits>::getForwarderChain(const std::string& strFilename, currdir cdDir) const
903 {
904 if (cdDir == OLDDIR)
905 {
906 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain;
907 }
908 else
909 {
910 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain;
911 }
912 }
913
914 /**
915 * @param strFilename Name of the imported file.
916 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
917 * @return TimeDateStamp value of an imported file.
918 **/
919 template<int bits>
920 dword ImportDirectory<bits>::getTimeDateStamp(const std::string& strFilename, currdir cdDir) const
921 {
922 if (cdDir == OLDDIR)
923 {
924 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp;
925 }
926 else
927 {
928 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp;
929 }
930 }
931
932 template<int bits>
933 dword ImportDirectory<bits>::getRvaOfName(const std::string& strFilename, currdir cdDir) const
934 {
935 if (cdDir == OLDDIR)
936 {
937 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.Name;
938 }
939 else
940 {
941 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.Name;
942 }
943 }
944
945 /**
946 * @param strFilename Name of the imported file.
947 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
948 * @return FirstThunk value of an imported file.
949 **/
950 template<int bits>
951 dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, currdir cdDir) const
952 {
953 if (cdDir == OLDDIR)
954 {
955 return m_vOldiid[dwFilenr].impdesc.FirstThunk;
956 }
957 else
958 {
959 return m_vNewiid[dwFilenr].impdesc.FirstThunk;
960 }
961 }
962
963 template<int bits>
964 void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, currdir cdDir, dword value)
965 {
966 if (cdDir == OLDDIR)
967 {
968 m_vOldiid[dwFilenr].impdesc.FirstThunk = value;
969 }
970 else
971 {
972 m_vNewiid[dwFilenr].impdesc.FirstThunk = value;
973 }
974 }
975
976 /**
977 * @param strFilename Name of the imported file.
978 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
979 * @return OriginalFirstThunk value of an imported file.
980 **/
981 template<int bits>
982 dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const
983 {
984 if (cdDir == OLDDIR)
985 {
986 return m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk;
987 }
988 else
989 {
990 return m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk;
991 }
992 }
993
994 template<int bits>
995 void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value)
996 {
997 if (cdDir == OLDDIR)
998 {
999 m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk = value;
1000 }
1001 else
1002 {
1003 m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk = value;
1004 }
1005 }
1006
1007 /**
1008 * @param strFilename Name of the imported file.
1009 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
1010 * @return ForwarderChain value of an imported file.
1011 **/
1012 template<int bits>
1013 dword ImportDirectory<bits>::getForwarderChain(dword dwFilenr, currdir cdDir) const
1014 {
1015 if (cdDir == OLDDIR)
1016 {
1017 return m_vOldiid[dwFilenr].impdesc.ForwarderChain;
1018 }
1019 else
1020 {
1021 return m_vNewiid[dwFilenr].impdesc.ForwarderChain;
1022 }
1023 }
1024
1025 template<int bits>
1026 void ImportDirectory<bits>::setForwarderChain(dword dwFilenr, currdir cdDir, dword value)
1027 {
1028 if (cdDir == OLDDIR)
1029 {
1030 m_vOldiid[dwFilenr].impdesc.ForwarderChain = value;
1031 }
1032 else
1033 {
1034 m_vNewiid[dwFilenr].impdesc.ForwarderChain = value;
1035 }
1036 }
1037
1038 /**
1039 * @param strFilename Name of the imported file.
1040 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
1041 * @return TimeDateStamp value of an imported file.
1042 **/
1043 template<int bits>
1044 dword ImportDirectory<bits>::getTimeDateStamp(dword dwFilenr, currdir cdDir) const
1045 {
1046 if (cdDir == OLDDIR)
1047 {
1048 return m_vOldiid[dwFilenr].impdesc.TimeDateStamp;
1049 }
1050 else
1051 {
1052 return m_vNewiid[dwFilenr].impdesc.TimeDateStamp;
1053 }
1054 }
1055
1056 template<int bits>
1057 void ImportDirectory<bits>::setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value)
1058 {
1059 if (cdDir == OLDDIR)
1060 {
1061 m_vOldiid[dwFilenr].impdesc.TimeDateStamp = value;
1062 }
1063 else
1064 {
1065 m_vNewiid[dwFilenr].impdesc.TimeDateStamp = value;
1066 }
1067 }
1068
1069 template<int bits>
1070 dword ImportDirectory<bits>::getRvaOfName(dword dwFilenr, currdir cdDir) const
1071 {
1072 if (cdDir == OLDDIR)
1073 {
1074 return m_vOldiid[dwFilenr].impdesc.Name;
1075 }
1076 else
1077 {
1078 return m_vNewiid[dwFilenr].impdesc.Name;
1079 }
1080 }
1081
1082 template<int bits>
1083 void ImportDirectory<bits>::setRvaOfName(dword dwFilenr, currdir cdDir, dword value)
1084 {
1085 if (cdDir == OLDDIR)
1086 {
1087 m_vOldiid[dwFilenr].impdesc.Name = value;
1088 }
1089 else
1090 {
1091 m_vNewiid[dwFilenr].impdesc.Name = value;
1092 }
1093 }
1094
1095 /**
1096 * @param dwFilenr ID of the imported file.
1097 * @param dwFuncnr ID of the imported function.
1098 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
1099 * @return FirstThunk value of an imported function.
1100 **/
1101 template<int bits>
1102 dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
1103 {
1104 if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal;
1105 else return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal;
1106 }
1107
1108 template<int bits>
1109 void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value)
1110 {
1111 if (cdDir == OLDDIR) m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value;
1112 else m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value;
1113 }
1114
1115 /**
1116 * @param dwFilenr ID of the imported file.
1117 * @param dwFuncnr ID of the imported function.
1118 * @param cdDir Flag to decide if the OLDDIR or new import directory is used.
1119 * @return OriginalFirstThunk value of an imported function.
1120 **/
1121 template<int bits>
1122 dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const
1123 {
1124 if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal;
1125 else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal;
1126 }
1127
1128 template<int bits>
1129 void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value)
1130 {
1131 if (cdDir == OLDDIR) m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value;
1132 else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value;
1133 }
1134
1135 typedef ImportDirectory<32> ImportDirectory32;
1136 typedef ImportDirectory<64> ImportDirectory64;
1137}
1138
1139#endif