Coverage for /Syzygy/agent/common/process_utils.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
54.9%28510.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/agent/common/process_utils.h"
  16    :  
  17    :  #include <psapi.h>
  18    :  
  19    :  #include "base/logging.h"
  20    :  #include "base/win/pe_image.h"
  21    :  #include "syzygy/common/com_utils.h"
  22    :  #include "syzygy/common/path_util.h"
  23    :  #include "syzygy/trace/client/rpc_session.h"
  24    :  
  25    :  namespace agent {
  26    :  namespace common {
  27    :  
  28    :  namespace {
  29    :  
  30    :  // Accessing a module acquired from process iteration calls is inherently racy,
  31    :  // as we don't hold any kind of reference to the module, and so the module
  32    :  // could be unloaded while we're accessing it.
  33    :  bool CaptureModuleInformation(const base::win::PEImage& image,
  34    :                                size_t* module_base_size,
  35    :                                uint32* module_checksum,
  36  i :                                uint32* module_time_date_stamp) {
  37  i :    DCHECK(module_base_size != NULL);
  38  i :    DCHECK(module_checksum != NULL);
  39  i :    DCHECK(module_time_date_stamp != NULL);
  40    :  
  41  i :    __try {
  42  i :      const IMAGE_NT_HEADERS* nt_headers = image.GetNTHeaders();
  43  i :      *module_base_size = nt_headers->OptionalHeader.SizeOfImage;
  44  i :      *module_checksum = nt_headers->OptionalHeader.CheckSum;
  45  i :      *module_time_date_stamp = nt_headers->FileHeader.TimeDateStamp;
  46    :  
  47    :      // Make reasonably sure we're actually looking at a module.
  48  i :      if (!image.VerifyMagic())
  49  i :        return false;
  50  i :    } __except(EXCEPTION_EXECUTE_HANDLER) {
  51  i :      return false;
  52  i :    }
  53    :  
  54  i :    return true;
  55  i :  }
  56    :  
  57    :  }  // namespace
  58    :  
  59    :  bool LogModule(HMODULE module,
  60    :                 trace::client::RpcSession* session,
  61  E :                 trace::client::TraceFileSegment* segment) {
  62  E :    DCHECK(module != NULL);
  63  E :    DCHECK(session != NULL);
  64  E :    DCHECK(segment != NULL);
  65    :  
  66    :    // See whether we can acquire the module data.
  67  E :    base::win::PEImage image(module);
  68  E :    size_t module_base_size = 0;
  69  E :    uint32 module_checksum = 0;
  70  E :    uint32 module_time_date_stamp = 0;
  71    :    if (!CaptureModuleInformation(image,
  72    :                                  &module_base_size,
  73    :                                  &module_checksum,
  74  E :                                  &module_time_date_stamp)) {
  75  E :      LOG(ERROR) << "Failed to capture module information.";
  76  E :      return false;
  77    :    }
  78    :  
  79    :    // Make sure the event we're about to write will fit.
  80    :    if (!segment->CanAllocate(sizeof(TraceModuleData)) &&
  81  E :        !session->ExchangeBuffer(segment)) {
  82    :      // Failed to allocate a new segment.
  83  i :      LOG(ERROR) << "Failed to exchange buffer.";
  84  i :      return false;
  85    :    }
  86  E :    DCHECK(segment->CanAllocate(sizeof(TraceModuleData)));
  87    :  
  88    :    // Allocate a record in the log.
  89    :    TraceModuleData* module_event = reinterpret_cast<TraceModuleData*>(
  90    :        segment->AllocateTraceRecordImpl(
  91  E :            TRACE_PROCESS_ATTACH_EVENT, sizeof(TraceModuleData)));
  92  E :    DCHECK(module_event != NULL);
  93    :  
  94  E :    module_event->module_base_addr = module;
  95  E :    module_event->module_base_size = module_base_size;
  96  E :    module_event->module_checksum = module_checksum;
  97  E :    module_event->module_time_date_stamp = module_time_date_stamp;
  98    :  
  99  E :    wchar_t module_name[MAX_PATH] = { 0 };
 100    :    if (::GetMappedFileName(::GetCurrentProcess(), module,
 101  E :                            module_name, arraysize(module_name)) == 0) {
 102  i :      DWORD error = ::GetLastError();
 103  i :      LOG(ERROR) << "Failed to get module name: " << ::common::LogWe(error)
 104    :                 << ".";
 105  i :      return false;
 106    :    }
 107  E :    base::FilePath device_path(module_name);
 108  E :    base::FilePath drive_path;
 109  E :    if (!::common::ConvertDevicePathToDrivePath(device_path, &drive_path)) {
 110  i :      LOG(ERROR) << "ConvertDevicePathToDrivePath failed.";
 111  i :      return false;
 112    :    }
 113    :    ::wcsncpy(module_event->module_name, drive_path.value().c_str(),
 114  E :              arraysize(module_event->module_name));
 115    :  
 116  E :    module_event->module_exe[0] = L'\0';
 117    :  
 118  E :    return true;
 119  E :  }
 120    :  
 121    :  }  // namespace common
 122    :  }  // namespace agent

Coverage information generated Thu Jan 14 17:40:38 2016.