| 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 |