retdec
TlsDirectory.h
Go to the documentation of this file.
1 /*
2 * TlsDirectory.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 RETDEC_PELIB_TLSDIRECTORY_H
14 #define RETDEC_PELIB_TLSDIRECTORY_H
15 
17 
18 namespace PeLib
19 {
21 
25  {
26  private:
28  std::vector<uint64_t> m_Callbacks;
29  std::size_t pointerSize;
30 
31  public:
33  int read(ImageLoader & imageLoader); // EXPORT
35  void rebuild(std::vector<std::uint8_t>& vBuffer) const; // EXPORT
37  unsigned int size() const; // EXPORT
39  int write(const std::string& strFilename, unsigned int dwOffset) const; // EXPORT
40 
42  const std::vector<std::uint64_t> & getCallbacks() const;
44  std::uint64_t getStartAddressOfRawData() const; // EXPORT
46  std::uint64_t getEndAddressOfRawData() const; // EXPORT
48  std::uint64_t getAddressOfIndex() const; // EXPORT
50  std::uint64_t getAddressOfCallBacks() const; // EXPORT
52  std::uint32_t getSizeOfZeroFill() const; // EXPORT
54  std::uint32_t getCharacteristics() const; // EXPORT
55 
57  void setStartAddressOfRawData(std::uint64_t value); // EXPORT
59  void setEndAddressOfRawData(std::uint64_t value); // EXPORT
61  void setAddressOfIndex(std::uint64_t value); // EXPORT
63  void setAddressOfCallBacks(std::uint64_t value); // EXPORT
65  void setSizeOfZeroFill(std::uint32_t dwValue); // EXPORT
67  void setCharacteristics(std::uint32_t dwValue); // EXPORT
68  };
69 
74  inline
75  int TlsDirectory::read(ImageLoader & imageLoader)
76  {
77  std::uint64_t imageBase = imageLoader.getImageBase();
78  std::uint32_t rva = imageLoader.getDataDirRva(PELIB_IMAGE_DIRECTORY_ENTRY_TLS);
79  std::uint32_t size = imageLoader.getDataDirSize(PELIB_IMAGE_DIRECTORY_ENTRY_TLS);
80  std::uint32_t sizeOfImage = imageLoader.getSizeOfImage();
81  std::uint32_t bytesRead;
82 
83  if((rva + size) >= sizeOfImage)
84  return ERROR_INVALID_FILE;
85 
86  // Remember the pointer size
87  pointerSize = imageLoader.getPointerSize();
88 
89  // Read the TLS directory from the image. Differentiate between 32-bit and 64-bit
90  if(imageLoader.getImageBitability() == 32)
91  {
92  PELIB_IMAGE_TLS_DIRECTORY32 TlsDirectory32;
93 
94  // Read the 32-bit TLS directory structure
95  bytesRead = imageLoader.readImage(&TlsDirectory32, rva, sizeof(PELIB_IMAGE_TLS_DIRECTORY32));
96  if(bytesRead != sizeof(PELIB_IMAGE_TLS_DIRECTORY32))
97  return ERROR_INVALID_FILE;
98 
99  // Convert to 64-bit structure
102  m_tls.AddressOfIndex = TlsDirectory32.AddressOfIndex;
104  m_tls.SizeOfZeroFill = TlsDirectory32.SizeOfZeroFill;
105  m_tls.Characteristics = TlsDirectory32.Characteristics;
106  }
107  else
108  {
109  // Read the 32-bit TLS directory structure
110  bytesRead = imageLoader.readImage(&m_tls, rva, sizeof(PELIB_IMAGE_TLS_DIRECTORY));
111  if(bytesRead != sizeof(PELIB_IMAGE_TLS_DIRECTORY))
112  return ERROR_INVALID_FILE;
113  }
114 
115  // If there is non-zero address of callbacks, we try to read at least one pointer to know
116  // if there are TLS callbacks
117  if(imageBase < m_tls.AddressOfCallBacks && m_tls.AddressOfCallBacks < (imageBase + sizeOfImage))
118  {
119  std::uint32_t rva = (std::uint32_t)(m_tls.AddressOfCallBacks - imageBase);
120 
121  for(std::uint32_t i = 0; i < PELIB_MAX_TLS_CALLBACKS; i++)
122  {
123  std::uint64_t AddressOfCallBack = 0;
124 
125  if(imageLoader.readPointer(rva, AddressOfCallBack) == 0)
126  break;
127  if(AddressOfCallBack == 0)
128  break;
129 
130  m_Callbacks.push_back(AddressOfCallBack);
131  rva += pointerSize;
132  }
133  }
134 
135  return ERROR_NONE;
136  }
137 
142  inline
143  void TlsDirectory::rebuild(std::vector<std::uint8_t>& vBuffer) const
144  {
145  if(pointerSize == 32)
146  {
147  PELIB_IMAGE_TLS_DIRECTORY32 TlsDirectory32;
148 
149  TlsDirectory32.StartAddressOfRawData = (std::uint32_t)m_tls.StartAddressOfRawData;
150  TlsDirectory32.EndAddressOfRawData = (std::uint32_t)m_tls.EndAddressOfRawData;
151  TlsDirectory32.AddressOfIndex = (std::uint32_t)m_tls.AddressOfIndex;
152  TlsDirectory32.AddressOfCallBacks = (std::uint32_t)m_tls.AddressOfCallBacks;
153  TlsDirectory32.SizeOfZeroFill = m_tls.SizeOfZeroFill;
154  TlsDirectory32.Characteristics = m_tls.Characteristics;
155 
156  vBuffer.resize(sizeof(PELIB_IMAGE_TLS_DIRECTORY32));
157  memcpy(vBuffer.data(), &TlsDirectory32, sizeof(PELIB_IMAGE_TLS_DIRECTORY32));
158  }
159  else
160  {
161  vBuffer.resize(sizeof(PELIB_IMAGE_TLS_DIRECTORY));
162  memcpy(vBuffer.data(), &m_tls, sizeof(PELIB_IMAGE_TLS_DIRECTORY));
163  }
164  }
165 
171  inline
172  unsigned int TlsDirectory::size() const
173  {
174  return (pointerSize == 32) ? sizeof(PELIB_IMAGE_TLS_DIRECTORY32) : sizeof(PELIB_IMAGE_TLS_DIRECTORY);
175  }
176 
181  inline
182  int TlsDirectory::write(const std::string& strFilename, unsigned int dwOffset) const
183  {
184  std::fstream ofFile(strFilename.c_str(), std::ios_base::in);
185 
186  if (!ofFile)
187  {
188  ofFile.clear();
189  ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary);
190  }
191  else
192  {
193  ofFile.close();
194  ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
195  }
196 
197  if (!ofFile)
198  {
199  return ERROR_OPENING_FILE;
200  }
201 
202  ofFile.seekp(dwOffset, std::ios::beg);
203 
204  std::vector<unsigned char> vBuffer;
205  rebuild(vBuffer);
206 
207  ofFile.write(reinterpret_cast<const char*>(vBuffer.data()), vBuffer.size());
208 
209  ofFile.close();
210 
211  return ERROR_NONE;
212  }
213 
217  inline
218  const std::vector<std::uint64_t> & TlsDirectory::getCallbacks() const
219  {
220  return m_Callbacks;
221  }
222 
226  inline
228  {
230  }
231 
235  inline
237  {
238  return m_tls.EndAddressOfRawData;
239  }
240 
244  inline
245  std::uint64_t TlsDirectory::getAddressOfIndex() const
246  {
247  return m_tls.AddressOfIndex;
248  }
249 
253  inline
255  {
256  return m_tls.AddressOfCallBacks;
257  }
258 
262  inline
263  std::uint32_t TlsDirectory::getSizeOfZeroFill() const
264  {
265  return m_tls.SizeOfZeroFill;
266  }
267 
271  inline
272  std::uint32_t TlsDirectory::getCharacteristics() const
273  {
274  return m_tls.Characteristics;
275  }
276 
280  inline
281  void TlsDirectory::setStartAddressOfRawData(std::uint64_t value)
282  {
284  }
285 
289  inline
290  void TlsDirectory::setEndAddressOfRawData(std::uint64_t value)
291  {
292  m_tls.EndAddressOfRawData = value;
293  }
294 
298  inline
299  void TlsDirectory::setAddressOfIndex(std::uint64_t value)
300  {
301  m_tls.AddressOfIndex = value;
302  }
303 
307  inline
308  void TlsDirectory::setAddressOfCallBacks(std::uint64_t value)
309  {
310  m_tls.AddressOfCallBacks = value;
311  }
312 
316  inline
317  void TlsDirectory::setSizeOfZeroFill(std::uint32_t dwValue)
318  {
319  m_tls.SizeOfZeroFill = dwValue;
320  }
321 
325  inline
326  void TlsDirectory::setCharacteristics(std::uint32_t dwValue)
327  {
328  m_tls.Characteristics = dwValue;
329  }
330 
331 }
332 #endif
Definition: ImageLoader.h:138
std::uint32_t readPointer(std::uint32_t rva, std::uint64_t &pointerValue)
Definition: ImageLoader.cpp:291
std::uint32_t getDataDirSize(std::size_t dataDirIndex) const
Definition: ImageLoader.h:321
std::uint32_t getDataDirRva(std::size_t dataDirIndex) const
Definition: ImageLoader.h:315
std::uint32_t getImageBitability() const
Definition: ImageLoader.cpp:432
std::uint64_t getImageBase() const
Definition: ImageLoader.h:265
std::uint32_t readImage(void *buffer, std::uint32_t rva, std::uint32_t bytesToRead)
Definition: ImageLoader.cpp:171
std::uint32_t getSizeOfImage() const
Definition: ImageLoader.h:280
std::uint32_t getPointerSize() const
Definition: ImageLoader.cpp:322
Class that handles the TLS directory.
Definition: TlsDirectory.h:25
PELIB_IMAGE_TLS_DIRECTORY m_tls
Structure that holds all information about the directory.
Definition: TlsDirectory.h:27
void setCharacteristics(std::uint32_t dwValue)
Sets the Characteristics value of the TLS header.
Definition: TlsDirectory.h:326
std::vector< uint64_t > m_Callbacks
Definition: TlsDirectory.h:28
std::uint64_t getEndAddressOfRawData() const
Returns the EndAddressOfRawData value of the TLS header.
Definition: TlsDirectory.h:236
unsigned int size() const
Returns the size of the TLS Directory.
Definition: TlsDirectory.h:172
std::uint64_t getStartAddressOfRawData() const
Returns the StartAddressOfRawData value of the TLS header.
Definition: TlsDirectory.h:227
std::uint64_t getAddressOfCallBacks() const
Returns the AddressOfCallBacks value of the TLS header.
Definition: TlsDirectory.h:254
std::size_t pointerSize
Definition: TlsDirectory.h:29
std::uint64_t getAddressOfIndex() const
Returns the AddressOfIndex value of the TLS header.
Definition: TlsDirectory.h:245
int read(ImageLoader &imageLoader)
Reads a file's TLS directory.
Definition: TlsDirectory.h:75
void rebuild(std::vector< std::uint8_t > &vBuffer) const
Rebuilds the TLS directory.
Definition: TlsDirectory.h:143
void setStartAddressOfRawData(std::uint64_t value)
Sets the StartAddressOfRawData value of the TLS header.
Definition: TlsDirectory.h:281
void setEndAddressOfRawData(std::uint64_t value)
Sets the EndAddressOfRawData value of the TLS header.
Definition: TlsDirectory.h:290
std::uint32_t getSizeOfZeroFill() const
Returns the SizeOfZeroFill value of the TLS header.
Definition: TlsDirectory.h:263
std::uint32_t getCharacteristics() const
Returns the Characteristics value of the TLS header.
Definition: TlsDirectory.h:272
void setSizeOfZeroFill(std::uint32_t dwValue)
Sets the SizeOfZeroFill value of the TLS header.
Definition: TlsDirectory.h:317
int write(const std::string &strFilename, unsigned int dwOffset) const
Writes the TLS directory to a file.
Definition: TlsDirectory.h:182
void setAddressOfIndex(std::uint64_t value)
Sets the AddressOfIndex value of the TLS header.
Definition: TlsDirectory.h:299
void setAddressOfCallBacks(std::uint64_t value)
Sets the AddressOfCallBacks value of the TLS header.
Definition: TlsDirectory.h:308
const std::vector< std::uint64_t > & getCallbacks() const
Returns vector of TLS callbacks.
Definition: TlsDirectory.h:218
Definition: BoundImportDirectory.h:21
@ PELIB_IMAGE_DIRECTORY_ENTRY_TLS
Definition: PeLibAux.h:178
const std::uint32_t PELIB_MAX_TLS_CALLBACKS
Definition: PeLibAux.h:151
@ ERROR_NONE
Definition: PeLibAux.h:33
@ ERROR_OPENING_FILE
Definition: PeLibAux.h:34
@ ERROR_INVALID_FILE
Definition: PeLibAux.h:35
Definition: PeLibAux.h:1180
std::uint32_t StartAddressOfRawData
Definition: PeLibAux.h:1181
std::uint32_t Characteristics
Definition: PeLibAux.h:1186
std::uint32_t SizeOfZeroFill
Definition: PeLibAux.h:1185
std::uint32_t AddressOfIndex
Definition: PeLibAux.h:1183
std::uint32_t EndAddressOfRawData
Definition: PeLibAux.h:1182
std::uint32_t AddressOfCallBacks
Definition: PeLibAux.h:1184
Definition: PeLibAux.h:1190
std::uint64_t StartAddressOfRawData
Definition: PeLibAux.h:1191
std::uint32_t SizeOfZeroFill
Definition: PeLibAux.h:1195
std::uint32_t Characteristics
Definition: PeLibAux.h:1196
std::uint64_t AddressOfIndex
Definition: PeLibAux.h:1193
std::uint64_t EndAddressOfRawData
Definition: PeLibAux.h:1192
std::uint64_t AddressOfCallBacks
Definition: PeLibAux.h:1194