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