diff options
author | tkent@chromium.org <tkent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-08 05:34:25 +0000 |
---|---|---|
committer | tkent@chromium.org <tkent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-08 05:34:25 +0000 |
commit | 1cda29e91ff949440ee93675241ee8e1e9e8ab10 (patch) | |
tree | 05fa297fdc8717f746e54c383f47397b12c222d0 /sandbox/src | |
parent | 0174b6962c8c75e60218b1e38fd7cedac9f5bebc (diff) | |
download | chromium_src-1cda29e91ff949440ee93675241ee8e1e9e8ab10.zip chromium_src-1cda29e91ff949440ee93675241ee8e1e9e8ab10.tar.gz chromium_src-1cda29e91ff949440ee93675241ee8e1e9e8ab10.tar.bz2 |
Fix issue 8348: unfork pe_image.h / pe_image.cc
Moved versions of those files from sandbox/src/ to base/ (overwrite versions in
base/ to avoid 64-bit warning).
Removed 'sandbox' namespace, adapted other files as necessary.
BUG=8348
TEST=none
Original review URL: http://codereview.chromium.org/179039
Patch by rsteiner
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25611 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src')
-rw-r--r-- | sandbox/src/eat_resolver.cc | 2 | ||||
-rw-r--r-- | sandbox/src/interception.cc | 2 | ||||
-rw-r--r-- | sandbox/src/pe_image.cc | 543 | ||||
-rw-r--r-- | sandbox/src/pe_image.h | 261 | ||||
-rw-r--r-- | sandbox/src/pe_image_unittest.cc | 201 | ||||
-rw-r--r-- | sandbox/src/policy_broker.cc | 2 | ||||
-rw-r--r-- | sandbox/src/resolver.cc | 2 | ||||
-rw-r--r-- | sandbox/src/sandbox_nt_util.cc | 2 | ||||
-rw-r--r-- | sandbox/src/service_resolver.cc | 2 | ||||
-rw-r--r-- | sandbox/src/sidestep_resolver.cc | 2 | ||||
-rw-r--r-- | sandbox/src/target_process.cc | 4 |
11 files changed, 9 insertions, 1014 deletions
diff --git a/sandbox/src/eat_resolver.cc b/sandbox/src/eat_resolver.cc index acf4ce3..89d8c94 100644 --- a/sandbox/src/eat_resolver.cc +++ b/sandbox/src/eat_resolver.cc @@ -4,7 +4,7 @@ #include "sandbox/src/eat_resolver.h" -#include "sandbox/src/pe_image.h" +#include "base/pe_image.h" #include "sandbox/src/sandbox_nt_util.h" namespace sandbox { diff --git a/sandbox/src/interception.cc b/sandbox/src/interception.cc index fcb38ff..f75fa3a 100644 --- a/sandbox/src/interception.cc +++ b/sandbox/src/interception.cc @@ -10,9 +10,9 @@ #include "sandbox/src/interception.h" #include "base/logging.h" +#include "base/pe_image.h" #include "base/scoped_ptr.h" #include "sandbox/src/interception_internal.h" -#include "sandbox/src/pe_image.h" #include "sandbox/src/sandbox.h" #include "sandbox/src/sandbox_utils.h" #include "sandbox/src/service_resolver.h" diff --git a/sandbox/src/pe_image.cc b/sandbox/src/pe_image.cc deleted file mode 100644 index 75c22b9..0000000 --- a/sandbox/src/pe_image.cc +++ /dev/null @@ -1,543 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file implements PEImage, a generic class to manipulate PE files. -// This file was adapted from GreenBorder's Code. - -#include "sandbox/src/pe_image.h" - -namespace sandbox { - -// Structure to perform imports enumerations. -struct EnumAllImportsStorage { - sandbox::PEImage::EnumImportsFunction callback; - PVOID cookie; -}; - -// Callback used to enumerate imports. See EnumImportChunksFunction. -bool ProcessImportChunk(const PEImage &image, LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, PVOID cookie) { - EnumAllImportsStorage &storage = *reinterpret_cast<EnumAllImportsStorage*>( - cookie); - - return image.EnumOneImportChunk(storage.callback, module, name_table, iat, - storage.cookie); -} - -// Callback used to enumerate delay imports. See EnumDelayImportChunksFunction. -bool ProcessDelayImportChunk(const PEImage &image, - PImgDelayDescr delay_descriptor, - LPCSTR module, PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, PIMAGE_THUNK_DATA bound_iat, - PIMAGE_THUNK_DATA unload_iat, PVOID cookie) { - EnumAllImportsStorage &storage = *reinterpret_cast<EnumAllImportsStorage*>( - cookie); - - return image.EnumOneDelayImportChunk(storage.callback, delay_descriptor, - module, name_table, iat, bound_iat, - unload_iat, storage.cookie); -} - -} // namespace - -namespace sandbox { - -void PEImage::set_module(HMODULE module) { - module_ = module; -} - -PIMAGE_DOS_HEADER PEImage::GetDosHeader() const { - return reinterpret_cast<PIMAGE_DOS_HEADER>(module_); -} - -PIMAGE_NT_HEADERS PEImage::GetNTHeaders() const { - PIMAGE_DOS_HEADER dos_header = GetDosHeader(); - - return reinterpret_cast<PIMAGE_NT_HEADERS>( - reinterpret_cast<char*>(dos_header) + dos_header->e_lfanew); -} - -PIMAGE_SECTION_HEADER PEImage::GetSectionHeader(UINT section) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - PIMAGE_SECTION_HEADER first_section = IMAGE_FIRST_SECTION(nt_headers); - - if (section < nt_headers->FileHeader.NumberOfSections) - return first_section + section; - else - return NULL; -} - -WORD PEImage::GetNumSections() const { - return GetNTHeaders()->FileHeader.NumberOfSections; -} - -DWORD PEImage::GetImageDirectoryEntrySize(UINT directory) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - - return nt_headers->OptionalHeader.DataDirectory[directory].Size; -} - -PVOID PEImage::GetImageDirectoryEntryAddr(UINT directory) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - - return RVAToAddr( - nt_headers->OptionalHeader.DataDirectory[directory].VirtualAddress); -} - -PIMAGE_SECTION_HEADER PEImage::GetImageSectionFromAddr(PVOID address) const { - PBYTE target = reinterpret_cast<PBYTE>(address); - PIMAGE_SECTION_HEADER section; - - for (UINT i = 0; NULL != (section = GetSectionHeader(i)); i++) { - // Don't use the virtual RVAToAddr. - PBYTE start = reinterpret_cast<PBYTE>( - PEImage::RVAToAddr(section->VirtualAddress)); - - DWORD size = section->Misc.VirtualSize; - - if ((start <= target) && (start + size > target)) - return section; - } - - return NULL; -} - -PIMAGE_SECTION_HEADER PEImage::GetImageSectionHeaderByName( - LPCSTR section_name) const { - if (NULL == section_name) - return NULL; - - PIMAGE_SECTION_HEADER ret = NULL; - int num_sections = GetNumSections(); - - for (int i = 0; i < num_sections; i++) { - PIMAGE_SECTION_HEADER section = GetSectionHeader(i); - if (0 == _strnicmp(reinterpret_cast<LPCSTR>(section->Name), section_name, - sizeof(section->Name))) { - ret = section; - break; - } - } - - return ret; -} - -PDWORD PEImage::GetExportEntry(LPCSTR name) const { - PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); - - if (NULL == exports) - return NULL; - - WORD ordinal = 0; - if (!GetProcOrdinal(name, &ordinal)) - return NULL; - - PDWORD functions = reinterpret_cast<PDWORD>( - RVAToAddr(exports->AddressOfFunctions)); - - return functions + ordinal - exports->Base; -} - -FARPROC PEImage::GetProcAddress(LPCSTR function_name) const { - PDWORD export_entry = GetExportEntry(function_name); - if (NULL == export_entry) - return NULL; - - PBYTE function = reinterpret_cast<PBYTE>(RVAToAddr(*export_entry)); - - PBYTE exports = reinterpret_cast<PBYTE>( - GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT)); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_EXPORT); - - // Check for forwarded exports as a special case. - if (exports <= function && exports + size > function) -#pragma warning(push) -#pragma warning(disable: 4312) - // This cast generates a warning because it is 32 bit specific. - return reinterpret_cast<FARPROC>(0xFFFFFFFF); -#pragma warning(pop) - - return reinterpret_cast<FARPROC>(function); -} - -bool PEImage::GetProcOrdinal(LPCSTR function_name, WORD *ordinal) const { - if (NULL == ordinal) - return false; - - PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); - - if (NULL == exports) - return false; - - if (IsOrdinal(function_name)) { - *ordinal = ToOrdinal(function_name); - } else { - PDWORD names = reinterpret_cast<PDWORD>(RVAToAddr(exports->AddressOfNames)); - PDWORD lower = names; - PDWORD upper = names + exports->NumberOfNames; - int cmp = -1; - - // Binary Search for the name. - while (lower != upper) { - PDWORD middle = lower + (upper - lower) / 2; - LPCSTR name = reinterpret_cast<LPCSTR>(RVAToAddr(*middle)); - - cmp = strcmp(function_name, name); - - if (cmp == 0) { - lower = middle; - break; - } - - if (cmp > 0) - lower = middle + 1; - else - upper = middle; - } - - if (cmp != 0) - return false; - - - PWORD ordinals = reinterpret_cast<PWORD>( - RVAToAddr(exports->AddressOfNameOrdinals)); - - *ordinal = ordinals[lower - names] + static_cast<WORD>(exports->Base); - } - - return true; -} - -bool PEImage::EnumSections(EnumSectionsFunction callback, PVOID cookie) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - UINT num_sections = nt_headers->FileHeader.NumberOfSections; - PIMAGE_SECTION_HEADER section = GetSectionHeader(0); - - for (UINT i = 0; i < num_sections; i++, section++) { - PVOID section_start = RVAToAddr(section->VirtualAddress); - DWORD size = section->Misc.VirtualSize; - - if (!callback(*this, section, section_start, size, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumExports(EnumExportsFunction callback, PVOID cookie) const { - PVOID directory = GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_EXPORT); - - // Check if there are any exports at all. - if (NULL == directory || 0 == size) - return true; - - PIMAGE_EXPORT_DIRECTORY exports = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>( - directory); - UINT ordinal_base = exports->Base; - UINT num_funcs = exports->NumberOfFunctions; - UINT num_names = exports->NumberOfNames; - PDWORD functions = reinterpret_cast<PDWORD>(RVAToAddr( - exports->AddressOfFunctions)); - PDWORD names = reinterpret_cast<PDWORD>(RVAToAddr(exports->AddressOfNames)); - PWORD ordinals = reinterpret_cast<PWORD>(RVAToAddr( - exports->AddressOfNameOrdinals)); - - for (UINT count = 0; count < num_funcs; count++) { - PVOID func = RVAToAddr(functions[count]); - if (NULL == func) - continue; - - // Check for a name. - LPCSTR name = NULL; - UINT hint; - for (hint = 0; hint < num_names; hint++) { - if (ordinals[hint] == count) { - name = reinterpret_cast<LPCSTR>(RVAToAddr(names[hint])); - break; - } - } - - if (name == NULL) - hint = 0; - - // Check for forwarded exports. - LPCSTR forward = NULL; - if (reinterpret_cast<char*>(func) >= reinterpret_cast<char*>(directory) && - reinterpret_cast<char*>(func) <= reinterpret_cast<char*>(directory) + - size) { - forward = reinterpret_cast<LPCSTR>(func); - func = 0; - } - - if (!callback(*this, ordinal_base + count, hint, name, func, forward, - cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumRelocs(EnumRelocsFunction callback, PVOID cookie) const { - PVOID directory = GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_BASERELOC); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_BASERELOC); - PIMAGE_BASE_RELOCATION base = reinterpret_cast<PIMAGE_BASE_RELOCATION>( - directory); - - if (directory == NULL || size < sizeof(IMAGE_BASE_RELOCATION)) - return true; - - while (base->SizeOfBlock) { - PWORD reloc = reinterpret_cast<PWORD>(base + 1); - UINT num_relocs = (base->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / - sizeof(WORD); - - for (UINT i = 0; i < num_relocs; i++, reloc++) { - WORD type = *reloc >> 12; - PVOID address = RVAToAddr(base->VirtualAddress + (*reloc & 0x0FFF)); - - if (!callback(*this, type, address, cookie)) - return false; - } - - base = reinterpret_cast<PIMAGE_BASE_RELOCATION>( - reinterpret_cast<char*>(base) + base->SizeOfBlock); - } - - return true; -} - -bool PEImage::EnumImportChunks(EnumImportChunksFunction callback, - PVOID cookie) const { - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_IMPORT); - PIMAGE_IMPORT_DESCRIPTOR import = GetFirstImportChunk(); - - if (import == NULL || size < sizeof(IMAGE_IMPORT_DESCRIPTOR)) - return true; - - for (; import->FirstThunk; import++) { - LPCSTR module_name = reinterpret_cast<LPCSTR>(RVAToAddr(import->Name)); - PIMAGE_THUNK_DATA name_table = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(import->OriginalFirstThunk)); - PIMAGE_THUNK_DATA iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(import->FirstThunk)); - - if (!callback(*this, module_name, name_table, iat, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumOneImportChunk(EnumImportsFunction callback, - LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, PVOID cookie) const { - if (NULL == name_table) - return false; - - for (; name_table && name_table->u1.Ordinal; name_table++, iat++) { - LPCSTR name = NULL; - WORD ordinal = 0; - WORD hint = 0; - - if (IMAGE_SNAP_BY_ORDINAL(name_table->u1.Ordinal)) { - ordinal = static_cast<WORD>(IMAGE_ORDINAL32(name_table->u1.Ordinal)); - } else { - PIMAGE_IMPORT_BY_NAME import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>( - RVAToAddr(name_table->u1.ForwarderString)); - - hint = import->Hint; - name = reinterpret_cast<LPCSTR>(&import->Name); - } - - if (!callback(*this, module_name, ordinal, name, hint, iat, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumAllImports(EnumImportsFunction callback, PVOID cookie) const { - EnumAllImportsStorage temp = { callback, cookie }; - return EnumImportChunks(ProcessImportChunk, &temp); -} - -bool PEImage::EnumDelayImportChunks(EnumDelayImportChunksFunction callback, - PVOID cookie) const { - PVOID directory = GetImageDirectoryEntryAddr( - IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT); - PImgDelayDescr delay_descriptor = reinterpret_cast<PImgDelayDescr>(directory); - - if (directory == NULL || size == 0) - return true; - - for (; delay_descriptor->rvaHmod; delay_descriptor++) { - PIMAGE_THUNK_DATA name_table; - PIMAGE_THUNK_DATA iat; - PIMAGE_THUNK_DATA bound_iat; // address of the optional bound IAT - PIMAGE_THUNK_DATA unload_iat; // address of optional copy of original IAT - LPCSTR module_name; - - // check if VC7-style imports, using RVAs instead of - // VC6-style addresses. - bool rvas = (delay_descriptor->grAttrs & dlattrRva) != 0; - - if (rvas) { - module_name = reinterpret_cast<LPCSTR>( - RVAToAddr(delay_descriptor->rvaDLLName)); - name_table = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(delay_descriptor->rvaINT)); - iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(delay_descriptor->rvaIAT)); - bound_iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(delay_descriptor->rvaBoundIAT)); - unload_iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(delay_descriptor->rvaUnloadIAT)); - } else { -#pragma warning(push) -#pragma warning(disable: 4312) - // These casts generate warnings because they are 32 bit specific. - module_name = reinterpret_cast<LPCSTR>(delay_descriptor->rvaDLLName); - name_table = reinterpret_cast<PIMAGE_THUNK_DATA>( - delay_descriptor->rvaINT); - iat = reinterpret_cast<PIMAGE_THUNK_DATA>(delay_descriptor->rvaIAT); - bound_iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - delay_descriptor->rvaBoundIAT); - unload_iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - delay_descriptor->rvaUnloadIAT); -#pragma warning(pop) - } - - if (!callback(*this, delay_descriptor, module_name, name_table, iat, - bound_iat, unload_iat, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumOneDelayImportChunk(EnumImportsFunction callback, - PImgDelayDescr delay_descriptor, - LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PIMAGE_THUNK_DATA bound_iat, - PIMAGE_THUNK_DATA unload_iat, - PVOID cookie) const { - UNREFERENCED_PARAMETER(bound_iat); - UNREFERENCED_PARAMETER(unload_iat); - - for (; name_table->u1.Ordinal; name_table++, iat++) { - LPCSTR name = NULL; - WORD ordinal = 0; - WORD hint = 0; - - if (IMAGE_SNAP_BY_ORDINAL(name_table->u1.Ordinal)) { - ordinal = static_cast<WORD>(IMAGE_ORDINAL32(name_table->u1.Ordinal)); - } else { - PIMAGE_IMPORT_BY_NAME import; - bool rvas = (delay_descriptor->grAttrs & dlattrRva) != 0; - - if (rvas) { - import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>( - RVAToAddr(name_table->u1.ForwarderString)); - } else { -#pragma warning(push) -#pragma warning(disable: 4312) - // This cast generates a warning because it is 32 bit specific. - import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>( - name_table->u1.ForwarderString); -#pragma warning(pop) - } - - hint = import->Hint; - name = reinterpret_cast<LPCSTR>(&import->Name); - } - - if (!callback(*this, module_name, ordinal, name, hint, iat, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumAllDelayImports(EnumImportsFunction callback, - PVOID cookie) const { - EnumAllImportsStorage temp = { callback, cookie }; - return EnumDelayImportChunks(ProcessDelayImportChunk, &temp); -} - -bool PEImage::VerifyMagic() const { - PIMAGE_DOS_HEADER dos_header = GetDosHeader(); - - if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) - return false; - - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - - if (nt_headers->Signature != IMAGE_NT_SIGNATURE) - return false; - - if (nt_headers->FileHeader.SizeOfOptionalHeader != - sizeof(IMAGE_OPTIONAL_HEADER)) - return false; - - if (nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) - return false; - - return true; -} - -bool PEImage::ImageRVAToOnDiskOffset(DWORD rva, DWORD *on_disk_offset) const { - LPVOID address = RVAToAddr(rva); - return ImageAddrToOnDiskOffset(address, on_disk_offset); -} - -bool PEImage::ImageAddrToOnDiskOffset(LPVOID address, - DWORD *on_disk_offset) const { - if (NULL == address) - return false; - - // Get the section that this address belongs to. - PIMAGE_SECTION_HEADER section_header = GetImageSectionFromAddr(address); - if (NULL == section_header) - return false; - -#pragma warning(push) -#pragma warning(disable: 4311) - // These casts generate warnings because they are 32 bit specific. - // Don't follow the virtual RVAToAddr, use the one on the base. - DWORD offset_within_section = reinterpret_cast<DWORD>(address) - - reinterpret_cast<DWORD>(PEImage::RVAToAddr( - section_header->VirtualAddress)); -#pragma warning(pop) - - *on_disk_offset = section_header->PointerToRawData + offset_within_section; - return true; -} - -PVOID PEImage::RVAToAddr(DWORD rva) const { - if (rva == 0) - return NULL; - - return reinterpret_cast<char*>(module_) + rva; -} - -PVOID PEImageAsData::RVAToAddr(DWORD rva) const { - if (rva == 0) - return NULL; - - PVOID in_memory = PEImage::RVAToAddr(rva); - DWORD dummy; - - if (!ImageAddrToOnDiskOffset(in_memory, &dummy)) - return NULL; - - return in_memory; -} - -} // namespace sandbox diff --git a/sandbox/src/pe_image.h b/sandbox/src/pe_image.h deleted file mode 100644 index fd36578..0000000 --- a/sandbox/src/pe_image.h +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file was adapted from GreenBorder's Code. -// To understand what this class is about (for other than well known functions -// as GetProcAddress), a good starting point is "An In-Depth Look into the -// Win32 Portable Executable File Format" by Matt Pietrek: -// http://msdn.microsoft.com/msdnmag/issues/02/02/PE/default.aspx - -#ifndef SANDBOX_SRC_PE_IMAGE_H__ -#define SANDBOX_SRC_PE_IMAGE_H__ - -#include <windows.h> -#include <DelayIMP.h> - -namespace sandbox { - -// This class is a wrapper for the Portable Executable File Format (PE). -// It's main purpose is to provide an easy way to work with imports and exports -// from a file, mapped in memory as image. -class PEImage { - public: - // Callback to enumerate sections. - // cookie is the value passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumSectionsFunction)(const PEImage &image, - PIMAGE_SECTION_HEADER header, - PVOID section_start, DWORD section_size, - PVOID cookie); - - // Callback to enumerate exports. - // function is the actual address of the symbol. If forward is not null, it - // contains the dll and symbol to forward this export to. cookie is the value - // passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumExportsFunction)(const PEImage &image, DWORD ordinal, - DWORD hint, LPCSTR name, PVOID function, - LPCSTR forward, PVOID cookie); - - // Callback to enumerate import blocks. - // name_table and iat point to the imports name table and address table for - // this block. cookie is the value passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumImportChunksFunction)(const PEImage &image, LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, PVOID cookie); - - // Callback to enumerate imports. - // module is the dll that exports this symbol. cookie is the value passed to - // the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumImportsFunction)(const PEImage &image, LPCSTR module, - DWORD ordinal, LPCSTR name, DWORD hint, - PIMAGE_THUNK_DATA iat, PVOID cookie); - - // Callback to enumerate dalayed import blocks. - // module is the dll that exports this block of symbols. cookie is the value - // passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumDelayImportChunksFunction)(const PEImage &image, - PImgDelayDescr delay_descriptor, - LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PIMAGE_THUNK_DATA bound_iat, - PIMAGE_THUNK_DATA unload_iat, - PVOID cookie); - - // Callback to enumerate relocations. - // cookie is the value passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumRelocsFunction)(const PEImage &image, WORD type, - PVOID address, PVOID cookie); - - explicit PEImage(HMODULE module) : module_(module) {} - explicit PEImage(const void* module) { - module_ = reinterpret_cast<HMODULE>(const_cast<void*>(module)); - } - - // Gets the HMODULE for this object. - HMODULE module() const; - - // Sets this object's HMODULE. - void set_module(HMODULE module); - - // Checks if this symbol is actually an ordinal. - static bool IsOrdinal(LPCSTR name); - - // Converts a named symbol to the corresponding ordinal. - static WORD ToOrdinal(LPCSTR name); - - // Returns the DOS_HEADER for this PE. - PIMAGE_DOS_HEADER GetDosHeader() const; - - // Returns the NT_HEADER for this PE. - PIMAGE_NT_HEADERS GetNTHeaders() const; - - // Returns number of sections of this PE. - WORD GetNumSections() const; - - // Returns the header for a given section. - // returns NULL if there is no such section. - PIMAGE_SECTION_HEADER GetSectionHeader(UINT section) const; - - // Returns the size of a given directory entry. - DWORD GetImageDirectoryEntrySize(UINT directory) const; - - // Returns the address of a given directory entry. - PVOID GetImageDirectoryEntryAddr(UINT directory) const; - - // Returns the section header for a given address. - // Use: s = image.GetImageSectionFromAddr(a); - // Post: 's' is the section header of the section that contains 'a' - // or NULL if there is no such section. - PIMAGE_SECTION_HEADER GetImageSectionFromAddr(PVOID address) const; - - // Returns the section header for a given section. - PIMAGE_SECTION_HEADER GetImageSectionHeaderByName(LPCSTR section_name) const; - - // Returns the first block of imports. - PIMAGE_IMPORT_DESCRIPTOR GetFirstImportChunk() const; - - // Returns the exports directory. - PIMAGE_EXPORT_DIRECTORY GetExportDirectory() const; - - // Returns a given export entry. - // Use: e = image.GetExportEntry(f); - // Pre: 'f' is either a zero terminated string or ordinal - // Post: 'e' is a pointer to the export directory entry - // that contains 'f's export RVA, or NULL if 'f' - // is not exported from this image - PDWORD GetExportEntry(LPCSTR name) const; - - // Returns the address for a given exported symbol. - // Use: p = image.GetProcAddress(f); - // Pre: 'f' is either a zero terminated string or ordinal. - // Post: if 'f' is a non-forwarded export from image, 'p' is - // the exported function. If 'f' is a forwarded export - // then p is the special value 0xFFFFFFFF. In this case - // RVAToAddr(*GetExportEntry) can be used to resolve - // the string that describes the forward. - FARPROC GetProcAddress(LPCSTR function_name) const; - - // Retrieves the ordinal for a given exported symbol. - // Returns true if the symbol was found. - bool GetProcOrdinal(LPCSTR function_name, WORD *ordinal) const; - - // Enumerates PE sections. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumSections(EnumSectionsFunction callback, PVOID cookie) const; - - // Enumerates PE exports. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumExports(EnumExportsFunction callback, PVOID cookie) const; - - // Enumerates PE imports. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumAllImports(EnumImportsFunction callback, PVOID cookie) const; - - // Enumerates PE import blocks. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumImportChunks(EnumImportChunksFunction callback, PVOID cookie) const; - - // Enumerates the imports from a single PE import block. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumOneImportChunk(EnumImportsFunction callback, LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, PIMAGE_THUNK_DATA iat, - PVOID cookie) const; - - - // Enumerates PE delay imports. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumAllDelayImports(EnumImportsFunction callback, PVOID cookie) const; - - // Enumerates PE delay import blocks. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumDelayImportChunks(EnumDelayImportChunksFunction callback, - PVOID cookie) const; - - // Enumerates imports from a single PE delay import block. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumOneDelayImportChunk(EnumImportsFunction callback, - PImgDelayDescr delay_descriptor, - LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PIMAGE_THUNK_DATA bound_iat, - PIMAGE_THUNK_DATA unload_iat, - PVOID cookie) const; - - // Enumerates PE relocation entries. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumRelocs(EnumRelocsFunction callback, PVOID cookie) const; - - // Verifies the magic values on the PE file. - // Returns true if all values are correct. - bool VerifyMagic() const; - - // Converts an rva value to the appropriate address. - virtual PVOID RVAToAddr(DWORD rva) const; - - // Converts an rva value to an offset on disk. - // Returns true on success. - bool ImageRVAToOnDiskOffset(DWORD rva, DWORD *on_disk_offset) const; - - // Converts an address to an offset on disk. - // Returns true on success. - bool ImageAddrToOnDiskOffset(LPVOID address, DWORD *on_disk_offset) const; - - private: - HMODULE module_; -}; - -// This class is an extension to the PEImage class that allows working with PE -// files mapped as data instead of as image file. -class PEImageAsData : public PEImage { - public: - explicit PEImageAsData(HMODULE hModule) : PEImage(hModule) {} - - virtual PVOID RVAToAddr(DWORD rva) const; -}; - -inline bool PEImage::IsOrdinal(LPCSTR name) { -#pragma warning(push) -#pragma warning(disable: 4311) - // This cast generates a warning because it is 32 bit specific. - return reinterpret_cast<DWORD>(name) <= 0xFFFF; -#pragma warning(pop) -} - -inline WORD PEImage::ToOrdinal(LPCSTR name) { - return reinterpret_cast<WORD>(name); -} - -inline HMODULE PEImage::module() const { - return module_; -} - -inline PIMAGE_IMPORT_DESCRIPTOR PEImage::GetFirstImportChunk() const { - return reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>( - GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_IMPORT)); -} - -inline PIMAGE_EXPORT_DIRECTORY PEImage::GetExportDirectory() const { - return reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>( - GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT)); -} - -} // namespace sandbox - -#endif // SANDBOX_SRC_PE_IMAGE_H__ diff --git a/sandbox/src/pe_image_unittest.cc b/sandbox/src/pe_image_unittest.cc deleted file mode 100644 index 9f0ea09..0000000 --- a/sandbox/src/pe_image_unittest.cc +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains unit tests for PEImage. - -#include "testing/gtest/include/gtest/gtest.h" -#include "sandbox/src/pe_image.h" - -// Just counts the number of invocations. -bool ExportsCallback(const sandbox::PEImage &image, - DWORD ordinal, - DWORD hint, - LPCSTR name, - PVOID function, - LPCSTR forward, - PVOID cookie) { - int* count = reinterpret_cast<int*>(cookie); - (*count)++; - return true; -} - -// Just counts the number of invocations. -bool ImportsCallback(const sandbox::PEImage &image, - LPCSTR module, - DWORD ordinal, - LPCSTR name, - DWORD hint, - PIMAGE_THUNK_DATA iat, - PVOID cookie) { - int* count = reinterpret_cast<int*>(cookie); - (*count)++; - return true; -} - -// Just counts the number of invocations. -bool SectionsCallback(const sandbox::PEImage &image, - PIMAGE_SECTION_HEADER header, - PVOID section_start, - DWORD section_size, - PVOID cookie) { - int* count = reinterpret_cast<int*>(cookie); - (*count)++; - return true; -} - -// Just counts the number of invocations. -bool RelocsCallback(const sandbox::PEImage &image, - WORD type, - PVOID address, - PVOID cookie) { - int* count = reinterpret_cast<int*>(cookie); - (*count)++; - return true; -} - -// Just counts the number of invocations. -bool ImportChunksCallback(const sandbox::PEImage &image, - LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PVOID cookie) { - int* count = reinterpret_cast<int*>(cookie); - (*count)++; - return true; -} - -// Just counts the number of invocations. -bool DelayImportChunksCallback(const sandbox::PEImage &image, - PImgDelayDescr delay_descriptor, - LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PIMAGE_THUNK_DATA bound_iat, - PIMAGE_THUNK_DATA unload_iat, - PVOID cookie) { - int* count = reinterpret_cast<int*>(cookie); - (*count)++; - return true; -} - -// We'll be using some known values for the tests. -enum Value { - sections = 0, - imports_dlls, - delay_dlls, - exports, - imports, - delay_imports, - relocs -}; - -// Retrieves the expected value from advapi32.dll based on the OS. -int GetExpectedValue(Value value, DWORD os) { - const int xp_delay_dlls = 2; - const int xp_exports = 675; - const int xp_imports = 422; - const int xp_delay_imports = 8; - const int xp_relocs = 9180; - const int vista_delay_dlls = 4; - const int vista_exports = 799; - const int vista_imports = 476; - const int vista_delay_imports = 24; - const int vista_relocs = 10188; - const int w2k_delay_dlls = 0; - const int w2k_exports = 566; - const int w2k_imports = 357; - const int w2k_delay_imports = 0; - const int w2k_relocs = 7388; - - // Contains the expected value, for each enumerated property (Value), and the - // OS version: [Value][os_version] - const int expected[][3] = { - {4, 4, 4}, - {3, 3, 3}, - {w2k_delay_dlls, xp_delay_dlls, vista_delay_dlls}, - {w2k_exports, xp_exports, vista_exports}, - {w2k_imports, xp_imports, vista_imports}, - {w2k_delay_imports, xp_delay_imports, vista_delay_imports}, - {w2k_relocs, xp_relocs, vista_relocs} - }; - - if (value > relocs) - return 0; - if (50 == os) - os = 0; // 5.0 - else if (51 == os || 52 == os) - os = 1; - else if (os >= 60) - os = 2; // 6.x - else - return 0; - - return expected[value][os]; -} - -// Tests that we are able to enumerate stuff from a PE file, and that -// the actual number of items found is within the expected range. -TEST(PEImageTest, EnumeratesPE) { - HMODULE module = LoadLibrary(L"advapi32.dll"); - ASSERT_TRUE(NULL != module); - - sandbox::PEImage pe(module); - int count = 0; - EXPECT_TRUE(pe.VerifyMagic()); - - DWORD os = pe.GetNTHeaders()->OptionalHeader.MajorOperatingSystemVersion; - os = os * 10 + pe.GetNTHeaders()->OptionalHeader.MinorOperatingSystemVersion; - - pe.EnumSections(SectionsCallback, &count); - EXPECT_EQ(GetExpectedValue(sections, os), count); - - count = 0; - pe.EnumImportChunks(ImportChunksCallback, &count); - EXPECT_EQ(GetExpectedValue(imports_dlls, os), count); - - count = 0; - pe.EnumDelayImportChunks(DelayImportChunksCallback, &count); - EXPECT_EQ(GetExpectedValue(delay_dlls, os), count); - - count = 0; - pe.EnumExports(ExportsCallback, &count); - EXPECT_GT(count, GetExpectedValue(exports, os) - 20); - EXPECT_LT(count, GetExpectedValue(exports, os) + 100); - - count = 0; - pe.EnumAllImports(ImportsCallback, &count); - EXPECT_GT(count, GetExpectedValue(imports, os) - 20); - EXPECT_LT(count, GetExpectedValue(imports, os) + 100); - - count = 0; - pe.EnumAllDelayImports(ImportsCallback, &count); - EXPECT_GT(count, GetExpectedValue(delay_imports, os) - 2); - EXPECT_LT(count, GetExpectedValue(delay_imports, os) + 8); - - count = 0; - pe.EnumRelocs(RelocsCallback, &count); - EXPECT_GT(count, GetExpectedValue(relocs, os) - 150); - EXPECT_LT(count, GetExpectedValue(relocs, os) + 1500); - - FreeLibrary(module); -} - -// Tests that we can locate an specific exported symbol, by name and by ordinal. -TEST(PEImageTest, RetrievesExports) { - HMODULE module = LoadLibrary(L"advapi32.dll"); - ASSERT_TRUE(NULL != module); - - sandbox::PEImage pe(module); - WORD ordinal; - - EXPECT_TRUE(pe.GetProcOrdinal("RegEnumKeyExW", &ordinal)); - - FARPROC address1 = pe.GetProcAddress("RegEnumKeyExW"); - FARPROC address2 = pe.GetProcAddress(reinterpret_cast<char*>(ordinal)); - EXPECT_TRUE(address1 != NULL); - EXPECT_TRUE(address2 != NULL); - EXPECT_TRUE(address1 == address2); - - FreeLibrary(module); -} diff --git a/sandbox/src/policy_broker.cc b/sandbox/src/policy_broker.cc index 3ef65dd..e3b5023 100644 --- a/sandbox/src/policy_broker.cc +++ b/sandbox/src/policy_broker.cc @@ -7,9 +7,9 @@ #include "sandbox/src/policy_broker.h" #include "base/logging.h" +#include "base/pe_image.h" #include "base/win_util.h" #include "sandbox/src/interception.h" -#include "sandbox/src/pe_image.h" #include "sandbox/src/policy_target.h" #include "sandbox/src/process_thread_interception.h" #include "sandbox/src/sandbox.h" diff --git a/sandbox/src/resolver.cc b/sandbox/src/resolver.cc index ee8bd10..c2a8136 100644 --- a/sandbox/src/resolver.cc +++ b/sandbox/src/resolver.cc @@ -4,7 +4,7 @@ #include "sandbox/src/resolver.h" -#include "sandbox/src/pe_image.h" +#include "base/pe_image.h" #include "sandbox/src/sandbox_nt_util.h" namespace { diff --git a/sandbox/src/sandbox_nt_util.cc b/sandbox/src/sandbox_nt_util.cc index e8a56a7..188974e 100644 --- a/sandbox/src/sandbox_nt_util.cc +++ b/sandbox/src/sandbox_nt_util.cc @@ -4,7 +4,7 @@ #include "sandbox/src/sandbox_nt_util.h" -#include "sandbox/src/pe_image.h" +#include "base/pe_image.h" #include "sandbox/src/sandbox_factory.h" #include "sandbox/src/target_services.h" diff --git a/sandbox/src/service_resolver.cc b/sandbox/src/service_resolver.cc index 5b8683c..2fae55a 100644 --- a/sandbox/src/service_resolver.cc +++ b/sandbox/src/service_resolver.cc @@ -5,8 +5,8 @@ #include "sandbox/src/service_resolver.h" #include "base/logging.h" +#include "base/pe_image.h" #include "base/scoped_ptr.h" -#include "sandbox/src/pe_image.h" #include "sandbox/src/sandbox_types.h" #include "sandbox/src/sandbox_utils.h" diff --git a/sandbox/src/sidestep_resolver.cc b/sandbox/src/sidestep_resolver.cc index 4d14a51..74409a8 100644 --- a/sandbox/src/sidestep_resolver.cc +++ b/sandbox/src/sidestep_resolver.cc @@ -4,7 +4,7 @@ #include "sandbox/src/sidestep_resolver.h" -#include "sandbox/src/pe_image.h" +#include "base/pe_image.h" #include "sandbox/src/sandbox_nt_util.h" #include "sandbox/src/sidestep/preamble_patcher.h" diff --git a/sandbox/src/target_process.cc b/sandbox/src/target_process.cc index 5bd0a8c..d3ae80d 100644 --- a/sandbox/src/target_process.cc +++ b/sandbox/src/target_process.cc @@ -5,10 +5,10 @@ #include "sandbox/src/target_process.h" #include "base/basictypes.h" +#include "base/pe_image.h" #include "base/scoped_ptr.h" #include "sandbox/src/crosscall_server.h" #include "sandbox/src/crosscall_client.h" -#include "sandbox/src/pe_image.h" #include "sandbox/src/policy_low_level.h" #include "sandbox/src/sandbox_types.h" #include "sandbox/src/sharedmem_ipc_server.h" @@ -54,7 +54,7 @@ void* GetBaseAddress(const wchar_t* exe_name, void* entry_point) { if (NULL == exe) return exe; - sandbox::PEImage pe(exe); + PEImage pe(exe); if (!pe.VerifyMagic()) { ::FreeLibrary(exe); return exe; |