OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file implements PEImage, a generic class to manipulate PE files. | 5 // This file implements PEImage, a generic class to manipulate PE files. |
6 // This file was adapted from GreenBorder's Code. | 6 // This file was adapted from GreenBorder's Code. |
7 | 7 |
8 #include "base/win/pe_image.h" | 8 #include "base/win/pe_image.h" |
9 | 9 |
10 namespace base { | 10 namespace base { |
11 namespace win { | 11 namespace win { |
12 | 12 |
13 // TODO(jschuh): crbug.com/167707 Make sure this code works on 64-bit. | 13 // TODO(jschuh): crbug.com/167707 Make sure this code works on 64-bit. |
14 | 14 |
15 // Structure to perform imports enumerations. | 15 // Structure to perform imports enumerations. |
16 struct EnumAllImportsStorage { | 16 struct EnumAllImportsStorage { |
17 PEImage::EnumImportsFunction callback; | 17 PEImage::EnumImportsFunction callback; |
18 PVOID cookie; | 18 PVOID cookie; |
19 }; | 19 }; |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
| 23 // PdbInfo Signature |
| 24 const DWORD kPdbInfoSignature = 'SDSR'; |
| 25 |
23 // Compare two strings byte by byte on an unsigned basis. | 26 // Compare two strings byte by byte on an unsigned basis. |
24 // if s1 == s2, return 0 | 27 // if s1 == s2, return 0 |
25 // if s1 < s2, return negative | 28 // if s1 < s2, return negative |
26 // if s1 > s2, return positive | 29 // if s1 > s2, return positive |
27 // Exception if inputs are invalid. | 30 // Exception if inputs are invalid. |
28 int StrCmpByByte(LPCSTR s1, LPCSTR s2) { | 31 int StrCmpByByte(LPCSTR s1, LPCSTR s2) { |
29 while (*s1 != '\0' && *s1 == *s2) { | 32 while (*s1 != '\0' && *s1 == *s2) { |
30 ++s1; | 33 ++s1; |
31 ++s2; | 34 ++s2; |
32 } | 35 } |
33 | 36 |
34 return (*reinterpret_cast<const unsigned char*>(s1) - | 37 return (*reinterpret_cast<const unsigned char*>(s1) - |
35 *reinterpret_cast<const unsigned char*>(s2)); | 38 *reinterpret_cast<const unsigned char*>(s2)); |
36 } | 39 } |
37 | 40 |
| 41 struct PdbInfo { |
| 42 DWORD Signature; |
| 43 GUID Guid; |
| 44 DWORD Age; |
| 45 char PdbFileName[1]; |
| 46 }; |
38 } // namespace | 47 } // namespace |
39 | 48 |
40 // Callback used to enumerate imports. See EnumImportChunksFunction. | 49 // Callback used to enumerate imports. See EnumImportChunksFunction. |
41 bool ProcessImportChunk(const PEImage &image, LPCSTR module, | 50 bool ProcessImportChunk(const PEImage &image, LPCSTR module, |
42 PIMAGE_THUNK_DATA name_table, | 51 PIMAGE_THUNK_DATA name_table, |
43 PIMAGE_THUNK_DATA iat, PVOID cookie) { | 52 PIMAGE_THUNK_DATA iat, PVOID cookie) { |
44 EnumAllImportsStorage &storage = *reinterpret_cast<EnumAllImportsStorage*>( | 53 EnumAllImportsStorage &storage = *reinterpret_cast<EnumAllImportsStorage*>( |
45 cookie); | 54 cookie); |
46 | 55 |
47 return image.EnumOneImportChunk(storage.callback, module, name_table, iat, | 56 return image.EnumOneImportChunk(storage.callback, module, name_table, iat, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 if (0 == _strnicmp(reinterpret_cast<LPCSTR>(section->Name), section_name, | 144 if (0 == _strnicmp(reinterpret_cast<LPCSTR>(section->Name), section_name, |
136 sizeof(section->Name))) { | 145 sizeof(section->Name))) { |
137 ret = section; | 146 ret = section; |
138 break; | 147 break; |
139 } | 148 } |
140 } | 149 } |
141 | 150 |
142 return ret; | 151 return ret; |
143 } | 152 } |
144 | 153 |
| 154 bool PEImage::GetDebugId(LPGUID guid, LPDWORD age) const { |
| 155 if (NULL == guid || NULL == age) { |
| 156 return false; |
| 157 } |
| 158 |
| 159 DWORD debug_directory_size = |
| 160 GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_DEBUG); |
| 161 PIMAGE_DEBUG_DIRECTORY debug_directory = |
| 162 reinterpret_cast<PIMAGE_DEBUG_DIRECTORY>( |
| 163 GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_DEBUG)); |
| 164 |
| 165 size_t directory_count = |
| 166 debug_directory_size / sizeof(IMAGE_DEBUG_DIRECTORY); |
| 167 |
| 168 for (size_t index = 0; index < directory_count; ++index) { |
| 169 if (debug_directory[index].Type == IMAGE_DEBUG_TYPE_CODEVIEW) { |
| 170 PdbInfo* pdb_info = reinterpret_cast<PdbInfo*>( |
| 171 RVAToAddr(debug_directory[index].AddressOfRawData)); |
| 172 if (pdb_info->Signature != kPdbInfoSignature) { |
| 173 // Unsupported PdbInfo signature |
| 174 return false; |
| 175 } |
| 176 *guid = pdb_info->Guid; |
| 177 *age = pdb_info->Age; |
| 178 return true; |
| 179 } |
| 180 } |
| 181 return false; |
| 182 } |
| 183 |
145 PDWORD PEImage::GetExportEntry(LPCSTR name) const { | 184 PDWORD PEImage::GetExportEntry(LPCSTR name) const { |
146 PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); | 185 PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); |
147 | 186 |
148 if (NULL == exports) | 187 if (NULL == exports) |
149 return NULL; | 188 return NULL; |
150 | 189 |
151 WORD ordinal = 0; | 190 WORD ordinal = 0; |
152 if (!GetProcOrdinal(name, &ordinal)) | 191 if (!GetProcOrdinal(name, &ordinal)) |
153 return NULL; | 192 return NULL; |
154 | 193 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 DWORD disk_offset; | 596 DWORD disk_offset; |
558 | 597 |
559 if (!ImageAddrToOnDiskOffset(in_memory, &disk_offset)) | 598 if (!ImageAddrToOnDiskOffset(in_memory, &disk_offset)) |
560 return NULL; | 599 return NULL; |
561 | 600 |
562 return PEImage::RVAToAddr(disk_offset); | 601 return PEImage::RVAToAddr(disk_offset); |
563 } | 602 } |
564 | 603 |
565 } // namespace win | 604 } // namespace win |
566 } // namespace base | 605 } // namespace base |
OLD | NEW |