Home | History | Annotate | Download | only in chrome_elf
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdint.h>
      6 #include <windows.h>
      7 
      8 #include "chrome_elf/ntdll_cache.h"
      9 
     10 FunctionLookupTable g_ntdll_lookup;
     11 
     12 void InitCache() {
     13   HMODULE ntdll_handle = ::GetModuleHandle(L"ntdll.dll");
     14 
     15   // To find the Export Address Table address, we start from the DOS header.
     16   // The module handle is actually the address of the header.
     17   IMAGE_DOS_HEADER* dos_header =
     18       reinterpret_cast<IMAGE_DOS_HEADER*>(ntdll_handle);
     19   // The e_lfanew is an offset from the DOS header to the NT header. It should
     20   // never be 0.
     21   IMAGE_NT_HEADERS* nt_headers = reinterpret_cast<IMAGE_NT_HEADERS*>(
     22       ntdll_handle + dos_header->e_lfanew / sizeof(uint32_t));
     23   // For modules that have an import address table, its offset from the
     24   // DOS header is stored in the second data directory's VirtualAddress.
     25   if (!nt_headers->OptionalHeader.DataDirectory[0].VirtualAddress)
     26     return;
     27 
     28   BYTE* base_addr = reinterpret_cast<BYTE*>(ntdll_handle);
     29 
     30   IMAGE_DATA_DIRECTORY* exports_data_dir =
     31       &nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
     32 
     33   IMAGE_EXPORT_DIRECTORY* exports = reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(
     34       base_addr + exports_data_dir->VirtualAddress);
     35 
     36   WORD* ordinals = reinterpret_cast<WORD*>(
     37       base_addr + exports->AddressOfNameOrdinals);
     38   DWORD* names = reinterpret_cast<DWORD*>(
     39       base_addr + exports->AddressOfNames);
     40   DWORD* funcs = reinterpret_cast<DWORD*>(
     41       base_addr + exports->AddressOfFunctions);
     42   int num_entries = exports->NumberOfNames;
     43 
     44   for (int i = 0; i < num_entries; i++) {
     45     char* name = reinterpret_cast<char*>(base_addr + names[i]);
     46     WORD ord =  ordinals[i];
     47     DWORD func = funcs[ord];
     48     FARPROC func_addr = reinterpret_cast<FARPROC>(func + base_addr);
     49     g_ntdll_lookup[std::string(name)] = func_addr;
     50   }
     51 }
     52