| 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 | |
| 26 // Compare two strings byte by byte on an unsigned basis. | 23 // Compare two strings byte by byte on an unsigned basis. |
| 27 // if s1 == s2, return 0 | 24 // if s1 == s2, return 0 |
| 28 // if s1 < s2, return negative | 25 // if s1 < s2, return negative |
| 29 // if s1 > s2, return positive | 26 // if s1 > s2, return positive |
| 30 // Exception if inputs are invalid. | 27 // Exception if inputs are invalid. |
| 31 int StrCmpByByte(LPCSTR s1, LPCSTR s2) { | 28 int StrCmpByByte(LPCSTR s1, LPCSTR s2) { |
| 32 while (*s1 != '\0' && *s1 == *s2) { | 29 while (*s1 != '\0' && *s1 == *s2) { |
| 33 ++s1; | 30 ++s1; |
| 34 ++s2; | 31 ++s2; |
| 35 } | 32 } |
| 36 | 33 |
| 37 return (*reinterpret_cast<const unsigned char*>(s1) - | 34 return (*reinterpret_cast<const unsigned char*>(s1) - |
| 38 *reinterpret_cast<const unsigned char*>(s2)); | 35 *reinterpret_cast<const unsigned char*>(s2)); |
| 39 } | 36 } |
| 40 | 37 |
| 41 struct PdbInfo { | |
| 42 DWORD Signature; | |
| 43 GUID Guid; | |
| 44 DWORD Age; | |
| 45 char PdbFileName[1]; | |
| 46 }; | |
| 47 } // namespace | 38 } // namespace |
| 48 | 39 |
| 49 // Callback used to enumerate imports. See EnumImportChunksFunction. | 40 // Callback used to enumerate imports. See EnumImportChunksFunction. |
| 50 bool ProcessImportChunk(const PEImage &image, LPCSTR module, | 41 bool ProcessImportChunk(const PEImage &image, LPCSTR module, |
| 51 PIMAGE_THUNK_DATA name_table, | 42 PIMAGE_THUNK_DATA name_table, |
| 52 PIMAGE_THUNK_DATA iat, PVOID cookie) { | 43 PIMAGE_THUNK_DATA iat, PVOID cookie) { |
| 53 EnumAllImportsStorage &storage = *reinterpret_cast<EnumAllImportsStorage*>( | 44 EnumAllImportsStorage &storage = *reinterpret_cast<EnumAllImportsStorage*>( |
| 54 cookie); | 45 cookie); |
| 55 | 46 |
| 56 return image.EnumOneImportChunk(storage.callback, module, name_table, iat, | 47 return image.EnumOneImportChunk(storage.callback, module, name_table, iat, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 if (0 == _strnicmp(reinterpret_cast<LPCSTR>(section->Name), section_name, | 135 if (0 == _strnicmp(reinterpret_cast<LPCSTR>(section->Name), section_name, |
| 145 sizeof(section->Name))) { | 136 sizeof(section->Name))) { |
| 146 ret = section; | 137 ret = section; |
| 147 break; | 138 break; |
| 148 } | 139 } |
| 149 } | 140 } |
| 150 | 141 |
| 151 return ret; | 142 return ret; |
| 152 } | 143 } |
| 153 | 144 |
| 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 | |
| 184 PDWORD PEImage::GetExportEntry(LPCSTR name) const { | 145 PDWORD PEImage::GetExportEntry(LPCSTR name) const { |
| 185 PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); | 146 PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); |
| 186 | 147 |
| 187 if (NULL == exports) | 148 if (NULL == exports) |
| 188 return NULL; | 149 return NULL; |
| 189 | 150 |
| 190 WORD ordinal = 0; | 151 WORD ordinal = 0; |
| 191 if (!GetProcOrdinal(name, &ordinal)) | 152 if (!GetProcOrdinal(name, &ordinal)) |
| 192 return NULL; | 153 return NULL; |
| 193 | 154 |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 DWORD disk_offset; | 557 DWORD disk_offset; |
| 597 | 558 |
| 598 if (!ImageAddrToOnDiskOffset(in_memory, &disk_offset)) | 559 if (!ImageAddrToOnDiskOffset(in_memory, &disk_offset)) |
| 599 return NULL; | 560 return NULL; |
| 600 | 561 |
| 601 return PEImage::RVAToAddr(disk_offset); | 562 return PEImage::RVAToAddr(disk_offset); |
| 602 } | 563 } |
| 603 | 564 |
| 604 } // namespace win | 565 } // namespace win |
| 605 } // namespace base | 566 } // namespace base |
| OLD | NEW |