注册表虚拟化

时间:2022-09-04 17:27:17

最近在研究chromium双核的功能, 想要IE控件的数据跟配置不去污染IE自身的配置好难啊。 


本以为通过虚拟化注册表可以解决配置,但是道高一尺, 魔高一丈啊。 IE的配置通过不仅保存在注册表, 还保存在共享内存了, 即使不去改变注册表, A进程里面的配置也会影响B进程。 只虚拟注册表不行了, 只能重定向缓存了


唯一留下的遗产就这个注册表的虚拟化


头文件。 

#include "base/basictypes.h"
#include "base/synchronization/lock.h"
#include <map>
#include <set>
#include <vector>

typedef std::string RegistryPath;
typedef std::string RegistryBuffer; 
typedef std::pair<DWORD, RegistryBuffer> RegistryValue;

namespace trident_glue{
  
class RegistryManager{
public:

  static RegistryManager* GetInstance();
  static void DestroyInstance();  
  static bool HasInstance();
  static RegistryBuffer MakeDwordBuffer(DWORD value);
  static RegistryBuffer MakeSzBuffer(const std::string& value);

  // reg_path sample: \REGISTRY\MACHINE\SOFTWARE\Wow6432Node\Microsoft
  // reg_path should consider wow64, pass a absolute path
  void AddHookValue(const RegistryPath& reg_path, const std::string& value_name, const RegistryValue& value);

  void AddHookValue(HKEY rootkey , const std::string& sub_key, const std::string& value_name, const RegistryValue& value);
  void RemoveHookValue(const RegistryPath& reg_path, const std::string& value_name);

public:
//   void RegOpenExA_After(LONG* ret_value, HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
//   void RegOpenExW_After(LONG* ret_value, HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
//   
  void RegClose_After(LONG* ret_value, HKEY hkey);
  
  bool RegQueryValueExW_Before(LONG* ret_value, HKEY hKey,LPCWSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData);
  void RegQueryValueExW_After(LONG* ret_value, HKEY hKey,LPCWSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData);
    
  bool RegQueryValueExA_Before(LONG* ret_value, HKEY hKey,LPCSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData);
  void RegQueryValueExA_After(LONG* ret_value, HKEY hKey,LPCSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData);

  bool RegSetValueExW_Before(LONG* ret_value, HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, 
    const BYTE *lpData,DWORD cbData);
  void RegSetValueExW_After(LONG* ret_value, HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, 
    const BYTE *lpData,DWORD cbData);

  bool RegSetValueExA_Before(LONG* ret_value, HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 
    const BYTE *lpData,DWORD cbData);
  void RegSetValueExA_After(LONG* ret_value, HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 
    const BYTE *lpData,DWORD cbData);
    
  bool RegEnumValueA_Before(LONG* ret_value, HKEY hKey, DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,
    LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
  void RegEnumValueA_After(LONG* ret_value, HKEY hKey, DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,
    LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);

private:
  static RegistryManager* instance_;
  RegistryManager();
  virtual ~RegistryManager();
  bool GetHandlePath(HKEY key, RegistryPath& path) ;
  //void PushNewHandle(HKEY key, const RegistryPath& path);
  void EraseHandle(HKEY key);

  bool GetHookValue(const RegistryPath& path, const std::string& value_name, RegistryValue& value);
  bool HasHookValue(const RegistryPath& path, const std::string& value_name);
  bool HasHookValue(const RegistryPath& path); 

  base::Lock handleMapPathLock_;
  std::map<HKEY, RegistryPath> handleMapPath_;

  base::Lock hookValueLock_;
  std::map<RegistryPath, std::map<std::string, RegistryValue>>  hookValue_;
  
  
};

}
 
cc实现
 
<pre name="code" class="cpp">#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "trident_glue/trident_hook/inline_hook/preamble_patcher.h"
#include <windows.h>

namespace {

  typedef enum _KEY_INFORMATION_CLASS { 
    KeyBasicInformation           = 0,
    KeyNodeInformation            = 1,
    KeyFullInformation            = 2,
    KeyNameInformation            = 3,
    KeyCachedInformation          = 4,
    KeyFlagsInformation           = 5,
    KeyVirtualizationInformation  = 6,
    KeyHandleTagsInformation      = 7,
    MaxKeyInfoClass               = 8
  } KEY_INFORMATION_CLASS;

  typedef struct _KEY_NAME_INFORMATION {
    ULONG NameLength;
    WCHAR Name[1];
  } KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION;


  typedef LONG (WINAPI* FN_ZwQueryKey)(
    _In_       HANDLE KeyHandle,
    _In_       KEY_INFORMATION_CLASS KeyInformationClass,
    _Out_opt_  PVOID KeyInformation,
    _In_       ULONG Length,
    _Out_      PULONG ResultLength
    );

typedef LONG (WINAPI* FN_RegEnumValueA)(HKEY hKey, DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,
    LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
    
typedef LONG (WINAPI* FN_RegQueryValueExA) (HKEY hKey,LPCSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData);
    
typedef LONG (WINAPI* FN_RegQueryValueExW) (HKEY hKey,LPCWSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData);

typedef LONG (WINAPI* FN_RegSetValueExA)(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 
    const BYTE *lpData,DWORD cbData );    

typedef LONG (WINAPI* FN_RegSetValueExW)(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType,
   const BYTE *lpData,DWORD cbData );

    
typedef LONG (WINAPI* FN_RegCloseKey)(HKEY hKey);

// typedef LONG (WINAPI* FN_RegOpenKeyExA)(HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
// 
// typedef LONG (WINAPI* FN_RegOpenKeyExW)(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
// 
// 
bool IsPredefinedKey(HKEY key) {
  if(key == HKEY_CLASSES_ROOT ||
     key == HKEY_CURRENT_CONFIG ||
     key == HKEY_CURRENT_USER ||
     key == HKEY_LOCAL_MACHINE ||
     key == HKEY_USERS )
     return true;
  else
    return false;
}

//std::string GetNormalizedPath(const std::string& path) {
//  std::string ret_value = path;
//  const char kSperatro[] = { '\\'};
//  const char kReverseSepator[] = {'/'};
//  TrimWhitespace(ret_value, TRIM_ALL, &ret_value);
//  TrimString(ret_value, kSperatro, &ret_value);
//  StringToLowerASCII(&ret_value);
//  //ReplaceChars(ret_value, kReverseSepator, "\\", &ret_value);
//  return ret_value;
//}

//std::wstring GetNormalizedPath(const std::wstring& path) {
//  std::wstring ret_value = path;
//  const wchar_t kSperatro[] = { L'\\', L'/'};
//  const wchar_t kReverseSepator[] = {'/'};
//  TrimWhitespace(ret_value, TRIM_ALL, &ret_value);
//  TrimString(ret_value, kSperatro, &ret_value);
//  StringToLowerASCII(&ret_value);
//  ReplaceChars(ret_value, kReverseSepator, L"\\", &ret_value);
//  return ret_value;
//}

//std::string GetCompletePathStrA(const RegistryPath& path){
//  std::string ret_value;
//  if(path.first == HKEY_CLASSES_ROOT){
//    ret_value = "hkey_root\\";
//  } else  if(path.first == HKEY_CURRENT_USER){
//    ret_value = "hkey_curusr\\";
//  }  else  if(path.first == HKEY_LOCAL_MACHINE){
//    ret_value = "hkey_locmachine\\";
//  } else  if(path.first == HKEY_USERS){
//    ret_value = "hkey_user\\";
//  }
//  ret_value.append(path.second);
//  return ret_value;
//}

//std::wstring GetCompletePathStrW(const RegistryPath& path){
//  std::string ret_value = GetCompletePathStrA(path);
//  return base::SysNativeMBToWide(ret_value);
//}

char* InstallInlineHook(const wchar_t* dll_name, const char* function_name, void* new_function){
  char* origin_function_stub = NULL;
  void* orgin_fuction_address = ::GetProcAddress(
    ::GetModuleHandle(dll_name), function_name);

  if (orgin_fuction_address == NULL)
    return origin_function_stub;

  DWORD old_protect = 0;
  if (!::VirtualProtect(orgin_fuction_address, 5,
    PAGE_EXECUTE_READWRITE, &old_protect))
    return origin_function_stub;

  origin_function_stub = reinterpret_cast<char*>(VirtualAllocEx(
    ::GetCurrentProcess(), NULL, sidestep::kMaxPreambleStubSize,
    MEM_COMMIT, PAGE_EXECUTE_READWRITE));
  if (origin_function_stub == NULL)
    return origin_function_stub;

  sidestep::SideStepError patch_result =
    sidestep::PreamblePatcher::Patch(
    orgin_fuction_address, new_function,
    origin_function_stub, sidestep::kMaxPreambleStubSize);

  if (patch_result != sidestep::SIDESTEP_SUCCESS) {
    CHECK(::VirtualFreeEx(::GetCurrentProcess(), origin_function_stub,
      0, MEM_RELEASE));
    CHECK(::VirtualProtect(orgin_fuction_address, 5, old_protect,
      &old_protect));
    return origin_function_stub;
  }

  DWORD dummy = 0;
  CHECK(::VirtualProtect(orgin_fuction_address,
    5,
    old_protect,
    &dummy));
  CHECK(::VirtualProtect(origin_function_stub,
    sidestep::kMaxPreambleStubSize,
    old_protect,
    &old_protect));  
  return origin_function_stub;
}

std::string GetKeyPathFromHKEY(HKEY key)
{
  std::string keyPath;
  std::wstring keyPath_Unicode;

  HMODULE dll = LoadLibrary(L"ntdll.dll");
  if (dll == NULL) 
    return keyPath;

   FN_ZwQueryKey pfnZwQueryKey = reinterpret_cast<FN_ZwQueryKey>(::GetProcAddress(dll, "ZwQueryKey"));
   if(pfnZwQueryKey == NULL)
     return keyPath;

   ULONG result_length = 0;
   pfnZwQueryKey(key, KeyNameInformation, NULL, NULL, &result_length);
   if(result_length == 0)
     return keyPath;

   void* allocted_mem = malloc(result_length);
   ZeroMemory(allocted_mem, result_length);
   PKEY_NAME_INFORMATION pKeyNameInfo = (PKEY_NAME_INFORMATION)allocted_mem;
   if(0 == pfnZwQueryKey(key, KeyNameInformation, allocted_mem, result_length, &result_length)){
      keyPath_Unicode.append(pKeyNameInfo->Name, pKeyNameInfo->NameLength/2); 
      keyPath = base::SysWideToNativeMB(keyPath_Unicode);
   }
   free(allocted_mem);
  return keyPath;
}
}

namespace trident_glue{
  
FN_RegEnumValueA g_pfnRegEnumValue_Origin = NULL;
FN_RegQueryValueExA g_pfnRegQueryValueExA_Origin = NULL;
FN_RegQueryValueExW g_pfnRegQueryValueExW_Origin = NULL;
FN_RegSetValueExA g_pfnRegSetValueExA_Origin = NULL;
FN_RegSetValueExW g_pfnRegSetValueExW_Origin = NULL;
FN_RegCloseKey g_pfnRegCloseKey_Origin = NULL;
// FN_RegOpenKeyExA g_pfnRegOpenKeyExA_Origin = NULL;
// FN_RegOpenKeyExW g_pfnRegOpenKeyExW_Origin = NULL;
// 
LONG WINAPI RegEnumValueA_Hook(HKEY hKey, DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,
    LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData){
  if(!RegistryManager::HasInstance()) 
    return g_pfnRegEnumValue_Origin(hKey, dwIndex, lpValueName, 
      lpcchValueName, lpReserved, lpType, lpData, lpcbData);

  LONG ret_value = 0;
  bool call_origin = RegistryManager::GetInstance()->RegEnumValueA_Before(&ret_value, hKey, dwIndex, lpValueName, 
    lpcchValueName, lpReserved, lpType, lpData, lpcbData);
  if(call_origin) {
    ret_value = g_pfnRegEnumValue_Origin(hKey, dwIndex, lpValueName, 
      lpcchValueName, lpReserved, lpType, lpData, lpcbData);
  }
  RegistryManager::GetInstance()->RegEnumValueA_After(&ret_value, hKey, dwIndex, lpValueName, 
    lpcchValueName, lpReserved, lpType, lpData, lpcbData);
  return ret_value;
}
    
LONG WINAPI RegQueryValueExA_Hook(HKEY hKey,LPCSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData){
   if(!RegistryManager::HasInstance()) 
     return g_pfnRegQueryValueExA_Origin(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  LONG ret_value = 0;
  bool call_origin = RegistryManager::GetInstance()->RegQueryValueExA_Before(&ret_value, hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  if(call_origin) {
    ret_value = g_pfnRegQueryValueExA_Origin(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  }
  RegistryManager::GetInstance()->RegQueryValueExA_After(&ret_value, hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  return ret_value;
}
    
LONG WINAPI RegQueryValueExW_Hook(HKEY hKey,LPCWSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
    LPBYTE lpData, LPDWORD lpcbData){ 
   if(!RegistryManager::HasInstance()) 
     return   g_pfnRegQueryValueExW_Origin(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  LONG ret_value = 0;
  bool call_origin = RegistryManager::GetInstance()->RegQueryValueExW_Before(&ret_value, hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  if(call_origin) {
    ret_value = g_pfnRegQueryValueExW_Origin(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  }
  RegistryManager::GetInstance()->RegQueryValueExW_After(&ret_value, hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  return ret_value;
}

LONG WINAPI RegSetValueExA_Hook(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE *lpData,DWORD cbData ){
  if(!RegistryManager::HasInstance()) 
     return   g_pfnRegSetValueExA_Origin(hKey, lpValueName, Reserved, dwType, lpData, cbData);
  LONG ret_value = 0;
  bool call_origin = RegistryManager::GetInstance()->RegSetValueExA_Before(&ret_value, hKey, lpValueName, Reserved, dwType, lpData, cbData);
  if(call_origin) {
    ret_value = g_pfnRegSetValueExA_Origin(hKey, lpValueName, Reserved, dwType, lpData, cbData);
  }
  RegistryManager::GetInstance()->RegSetValueExA_After(&ret_value, hKey, lpValueName, Reserved, dwType, lpData, cbData);
  return ret_value;
}    

LONG WINAPI RegSetValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType,
  const BYTE *lpData,DWORD cbData ){
  if(!RegistryManager::HasInstance()) 
     return   g_pfnRegSetValueExW_Origin(hKey, lpValueName, Reserved, dwType, lpData, cbData);
  LONG ret_value = 0;
  bool call_origin = RegistryManager::GetInstance()->RegSetValueExW_Before(&ret_value, hKey, lpValueName, Reserved, dwType, lpData, cbData);
  if(call_origin) {
    ret_value = g_pfnRegSetValueExW_Origin(hKey, lpValueName, Reserved, dwType, lpData, cbData);
  }
  RegistryManager::GetInstance()->RegSetValueExW_After(&ret_value,hKey, lpValueName, Reserved, dwType, lpData, cbData);
  return ret_value;
}

LONG WINAPI RegCloseKey_Hook(HKEY hKey){ 
  if(!RegistryManager::HasInstance()) 
    return  g_pfnRegCloseKey_Origin(hKey);
  LONG ret_value = g_pfnRegCloseKey_Origin(hKey);
  RegistryManager::GetInstance()->RegClose_After(&ret_value, hKey);
  return ret_value;  
}

// LONG WINAPI RegOpenKeyExA_Hook(HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult){    
//   if(!RegistryManager::HasInstance()) 
//     return  g_pfnRegOpenKeyExA_Origin(hKey, lpSubKey, ulOptions, samDesired, phkResult);
//   LONG ret_value = g_pfnRegOpenKeyExA_Origin(hKey, lpSubKey, ulOptions, samDesired, phkResult);
//   RegistryManager::GetInstance()->RegOpenExA_After(&ret_value, hKey, lpSubKey, ulOptions, samDesired, phkResult);
//   return ret_value;   
// }
// 
// LONG WINAPI RegOpenKeyExW_Hook(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult){
// 
//   if(!RegistryManager::HasInstance()) 
//     return g_pfnRegOpenKeyExW_Origin(hKey, lpSubKey, ulOptions, samDesired, phkResult);
//   LONG ret_value = g_pfnRegOpenKeyExW_Origin(hKey, lpSubKey, ulOptions, samDesired, phkResult);
//   RegistryManager::GetInstance()->RegOpenExW_After(&ret_value, hKey, lpSubKey, ulOptions, samDesired, phkResult);
//   return ret_value;   
// }
// 
RegistryManager* RegistryManager::instance_ = NULL;


//static 
RegistryManager* RegistryManager::GetInstance() {
  if(!instance_){
    instance_ = new RegistryManager;
  }
  return instance_;
}

//static 
void RegistryManager::DestroyInstance() {
  if(instance_) {
    delete instance_;
    instance_ = NULL;
  }
}  

//static 
bool RegistryManager::HasInstance() {
  return instance_ != NULL;
}


//static 
RegistryBuffer RegistryManager::MakeDwordBuffer(DWORD value) {
  RegistryBuffer ret_value;
  ret_value.assign((char*)(&value), sizeof(DWORD));
  return ret_value;
}

//static 
RegistryBuffer RegistryManager::MakeSzBuffer(const std::string& value) {
  RegistryBuffer ret_value;
  ret_value.assign(value.c_str(), value.length() + 1);
  return ret_value;
}

void RegistryManager::AddHookValue(const RegistryPath& reg_path, const std::string& value_name, const RegistryValue& value) {
  base::AutoLock auto_lock(hookValueLock_);
  RegistryPath normal_reg_path = StringToLowerASCII(reg_path);
  hookValue_[normal_reg_path][StringToLowerASCII(value_name)] = value;
}

void RegistryManager::AddHookValue(HKEY rootkey , const std::string& sub_key, const std::string& value_name, const RegistryValue& value) {
   base::AutoLock auto_lock(hookValueLock_);
   HKEY subkey_handle = NULL;
   if( ERROR_SUCCESS != ::RegOpenKeyA(rootkey, sub_key.c_str(), &subkey_handle))
     return ;
   std::string reg_path = GetKeyPathFromHKEY(subkey_handle);
   ::RegCloseKey(subkey_handle);
   if(reg_path.empty())
     return ;
   RegistryPath normal_reg_path = StringToLowerASCII(reg_path);
   hookValue_[normal_reg_path][StringToLowerASCII(value_name)] = value;
}

void RegistryManager::RemoveHookValue(const RegistryPath& reg_path, const std::string& value_name) {
  base::AutoLock auto_lock(hookValueLock_);
  RegistryPath normal_reg_path = StringToLowerASCII(reg_path);
  hookValue_[normal_reg_path].erase(StringToLowerASCII(value_name));
}

RegistryManager::RegistryManager() {
  g_pfnRegEnumValue_Origin = (FN_RegEnumValueA)InstallInlineHook(L"Advapi32.dll", "RegEnumValueA", RegEnumValueA_Hook);  
  g_pfnRegQueryValueExA_Origin = (FN_RegQueryValueExA)InstallInlineHook(L"Advapi32.dll", "RegQueryValueExA", RegQueryValueExA_Hook);
  g_pfnRegQueryValueExW_Origin = (FN_RegQueryValueExW)InstallInlineHook(L"Advapi32.dll", "RegQueryValueExW", RegQueryValueExW_Hook);  
  g_pfnRegSetValueExA_Origin = (FN_RegSetValueExA)InstallInlineHook(L"Advapi32.dll", "RegSetValueExA", RegSetValueExA_Hook);
  g_pfnRegSetValueExW_Origin = (FN_RegSetValueExW)InstallInlineHook(L"Advapi32.dll", "RegSetValueExW", RegSetValueExW_Hook);
  g_pfnRegCloseKey_Origin = (FN_RegCloseKey)InstallInlineHook(L"Advapi32.dll", "RegCloseKey", RegCloseKey_Hook);  
}

RegistryManager::~RegistryManager(){
  FreeModule(GetModuleHandleA("wininet.dll"));
   InstallInlineHook(L"Advapi32.dll", "RegEnumValueA", g_pfnRegEnumValue_Origin); 
   g_pfnRegEnumValue_Origin = NULL;
   InstallInlineHook(L"Advapi32.dll", "RegQueryValueExA", g_pfnRegQueryValueExA_Origin);
   g_pfnRegQueryValueExA_Origin = NULL;
   InstallInlineHook(L"Advapi32.dll", "RegQueryValueExW", g_pfnRegQueryValueExW_Origin);
   g_pfnRegQueryValueExW_Origin = NULL;
   InstallInlineHook(L"Advapi32.dll", "RegSetValueExA", g_pfnRegSetValueExA_Origin);
   g_pfnRegSetValueExA_Origin = NULL;
   InstallInlineHook(L"Advapi32.dll", "RegSetValueExW", g_pfnRegSetValueExW_Origin);
   g_pfnRegSetValueExW_Origin = NULL;
   InstallInlineHook(L"Advapi32.dll", "RegCloseKey", g_pfnRegCloseKey_Origin);  
   g_pfnRegCloseKey_Origin = NULL;
}

bool RegistryManager::GetHandlePath(HKEY key, RegistryPath& path) {
  base::AutoLock auto_lock(handleMapPathLock_);
  std::map<HKEY, RegistryPath>::const_iterator iter = handleMapPath_.find(key);
  if(iter != handleMapPath_.end()) {
    path = iter->second;
    return true;
  } else{
    std::string key_path = GetKeyPathFromHKEY(key);
    if(!key_path.empty()){
      path = StringToLowerASCII(key_path);
      handleMapPath_[key] = path;  
      return true;
    }
  }
  return false;
}                 
                                                                                                                       
//void RegistryManager::PushNewHandle(HKEY key, const RegistryPath& path){
//  base::AutoLock auto_lock(handleMapPathLock_);
//  std::map<HKEY, RegistryPath>::const_iterator iter = handleMapPath_.find(key);
//  DCHECK(iter == handleMapPath_.end());
//  handleMapPath_[key] = path;
//}

void RegistryManager::EraseHandle(HKEY key){
  base::AutoLock auto_lock(handleMapPathLock_);
  handleMapPath_.erase(key);
}

bool RegistryManager::GetHookValue(const RegistryPath& path, const std::string& value_name, RegistryValue& value){
  base::AutoLock auto_lock(hookValueLock_);
  RegistryPath normal_reg_path( StringToLowerASCII(path));
  std::map<RegistryPath, std::map<std::string, RegistryValue>>::iterator iter = hookValue_.find(normal_reg_path);
  if(iter == hookValue_.end())
    return false;
  std::map<std::string, RegistryValue>::iterator iter_second = iter->second.find(StringToLowerASCII(value_name));
  if(iter_second == iter->second.end())
    return false;
  value = iter_second->second;
  return true;
}

bool RegistryManager::HasHookValue(const RegistryPath& path, const std::string& value_name){
  base::AutoLock auto_lock(hookValueLock_);
  RegistryPath normal_reg_path(StringToLowerASCII(path));
  std::map<RegistryPath, std::map<std::string, RegistryValue>>::iterator iter = hookValue_.find(normal_reg_path);
  if(iter == hookValue_.end())
    return false;
  std::map<std::string, RegistryValue>::iterator iter_second = iter->second.find(StringToLowerASCII(value_name));
  return (iter_second != iter->second.end());
}

bool RegistryManager::HasHookValue(const RegistryPath& path) {
  base::AutoLock auto_lock(hookValueLock_);
  RegistryPath normal_reg_path(StringToLowerASCII(path));
  std::map<RegistryPath, std::map<std::string, RegistryValue>>::iterator iter = hookValue_.find(normal_reg_path);
  return (iter != hookValue_.end() && !iter->second.empty());
}

// void RegistryManager::RegOpenExA_After(LONG* ret_value, HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult) {
//   if((*ret_value != ERROR_SUCCESS) || lpSubKey == NULL || (strcmp(lpSubKey, "") == 0))
//     return ;
//   std::pair<HKEY , std::string> parent_path;
//   std::pair<HKEY , std::string> path;
//   if(IsPredefinedKey(hKey)) {
//     path.first = hKey;
//     path.second = GetNormalizedPath(lpSubKey);
//     PushNewHandle(*phkResult, path);
//   }else {
//     if(!GetHandlePath(hKey, parent_path))
//       return ;
//     path.first = parent_path.first;
//     path.second = parent_path.second;
//     path.second.append("\\");
//     path.second.append(GetNormalizedPath(lpSubKey));
//     PushNewHandle(*phkResult, path);
//   }
// }
// 
// void RegistryManager::RegOpenExW_After(LONG* ret_value, HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult) {
//   if((*ret_value != ERROR_SUCCESS) || lpSubKey == NULL || (wcscmp(lpSubKey, L"") == 0))
//     return ;
//   std::pair<HKEY , std::string> parent_path;
//   std::pair<HKEY , std::string> path;
//   if(IsPredefinedKey(hKey)) {
//     path.first = hKey;
//     path.second = base::SysWideToNativeMB(GetNormalizedPath(lpSubKey));
//     PushNewHandle(*phkResult, path);
//   }else {
//     if(!GetHandlePath(hKey, parent_path))
//       return ;
//     path.first = parent_path.first;
//     path.second = parent_path.second;
//     path.second.append("\\");
//     path.second.append(base::SysWideToNativeMB(GetNormalizedPath(lpSubKey)));
//     PushNewHandle(*phkResult, path);
//   }
// }
// 
void RegistryManager::RegClose_After(LONG* ret_value, HKEY hkey) {
  if(*ret_value == ERROR_SUCCESS)
    EraseHandle(hkey);
}

bool RegistryManager::RegQueryValueExW_Before(LONG* ret_value, HKEY hKey,LPCWSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
  LPBYTE lpData, LPDWORD lpcbData) {

  RegistryPath path;
  if(!GetHandlePath(hKey, path)) {
    return true;
  }

 std::string strValueName = lpValueName?base::SysWideToNativeMB(lpValueName):"";
 RegistryValue value;
 if(!GetHookValue(path, strValueName, value))
   return true;

 if(value.first == REG_DWORD) {
   if(lpType)
     *lpType = REG_DWORD;
   *ret_value = ERROR_SUCCESS;
   *lpcbData = sizeof(DWORD);
   (*(DWORD*)(lpData)) = (*((DWORD*)value.second.c_str()));
   return false;
 }

 if(value.first == REG_SZ) {
   if(lpType)
     *lpType = REG_SZ;
   std::wstring strvalue = base::SysNativeMBToWide(value.second);
   DWORD bytes_need = (strvalue.length()*2); 
   if(*lpcbData < bytes_need){
     *lpcbData = bytes_need;
     *ret_value = ERROR_MORE_DATA;
   }else {
     memcpy(lpData, strvalue.c_str(), bytes_need);
     *lpcbData = bytes_need;
     *ret_value = ERROR_SUCCESS;
   }
   return false;
 }
  return true;
}

void RegistryManager::RegQueryValueExW_After(LONG* ret_value, HKEY hKey,LPCWSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
  LPBYTE lpData, LPDWORD lpcbData) {

}

bool RegistryManager::RegQueryValueExA_Before(LONG* ret_value, HKEY hKey,LPCSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
  LPBYTE lpData, LPDWORD lpcbData) {
  
  RegistryPath path;
  if(!GetHandlePath(hKey, path)) {
    return true;
  }   

 std::string strValueName = lpValueName?lpValueName:"";
 RegistryValue value;
 if(!GetHookValue(path, strValueName, value))
   return true;

 if(value.first == REG_DWORD) {
   if(lpType)
     *lpType = REG_DWORD;
   *ret_value = ERROR_SUCCESS;
   *lpcbData = sizeof(DWORD);
   (*(DWORD*)(lpData)) = (*((DWORD*)value.second.c_str()));
   return false;
 }

 if(value.first == REG_SZ) {
   if(lpType)
     *lpType = REG_SZ;
   std::string strvalue = value.second;
   DWORD bytes_need = (strvalue.length()); 
   if(*lpcbData < bytes_need){
     *lpcbData = bytes_need;
     *ret_value = ERROR_MORE_DATA;
   }else {
     memcpy(lpData, strvalue.c_str(), bytes_need);
     *lpcbData = bytes_need;
     *ret_value = ERROR_SUCCESS;
   }
   return false;
 }
  return true;
}

void RegistryManager::RegQueryValueExA_After(LONG* ret_value, HKEY hKey,LPCSTR lpValueName, LPDWORD lpReserved,LPDWORD lpType,
  LPBYTE lpData, LPDWORD lpcbData) {

}

bool RegistryManager::RegSetValueExW_Before(LONG* ret_value, HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, 
  const BYTE *lpData,DWORD cbData){
  RegistryPath path;
  if(!GetHandlePath(hKey, path)) {
    return true;
  }

 std::string strValueName = lpValueName?base::SysWideToNativeMB(lpValueName):"";
 RegistryValue value;
 if(GetHookValue(path, strValueName, value)){
   *ret_value = ERROR_SUCCESS;
   return false;
 }
 else
   return true;
}

void RegistryManager::RegSetValueExW_After(LONG* ret_value, HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType, 
  const BYTE *lpData,DWORD cbData){

}

bool RegistryManager::RegSetValueExA_Before(LONG* ret_value, HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 
  const BYTE *lpData,DWORD cbData){
    RegistryPath path;
  if(!GetHandlePath(hKey, path)) {
    return true;
  }

 std::string strValueName = lpValueName?lpValueName:"";
 RegistryValue value;
 if(GetHookValue(path, strValueName, value)){
   *ret_value = ERROR_SUCCESS;
   return false;
 }
 else
   return true;
}

void RegistryManager::RegSetValueExA_After(LONG* ret_value, HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 
  const BYTE *lpData,DWORD cbData){

}

bool RegistryManager::RegEnumValueA_Before(LONG* ret_value, HKEY hKey, DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,
  LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData) {
  return true;
}

void RegistryManager::RegEnumValueA_After(LONG* ret_value, HKEY hKey, DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,
  LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData) {
   
  RegistryPath path;
  if(!GetHandlePath(hKey, path)) {
    return ;
  }  

 std::string strValueName = lpValueName?lpValueName:"";
 RegistryValue value;
 if(!GetHookValue(path, strValueName, value))
   return ;

 if(lpType)
   *lpType = value.first;

 if(lpData ) {
   if(IsBadWritePtr(lpData, value.second.length())){
     *ret_value = ERROR_MORE_DATA;
     *lpcbData = value.second.length();
     return ;
   }
 }else {
   return ;
 }

 *ret_value = ERROR_SUCCESS;
 if(value.first == REG_DWORD) {
   *lpcbData = sizeof(DWORD);
   (*(DWORD*)(lpData)) = (*((DWORD*)value.second.c_str()));
   return ;
 }

 if(value.first == REG_SZ) {
   std::string strvalue = value.second;
   DWORD bytes_need = (strvalue.length()); 
   memcpy(lpData, strvalue.c_str(), bytes_need);
   *lpcbData = bytes_need;
   }
}

  
}