[
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n**/Properties/launchSettings.json\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk \n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output \nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder \n.mfractor/\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"libcapcom\"]\n\tpath = libcapcom\n\turl = https://github.com/notscimmy/libcapcom.git\n"
  },
  {
    "path": "README.md",
    "content": "# libelevate - Bypass ObRegisterCallbacks via elevation\n\n## ObRegisterCallbacks\nOne of the goals of antivirus and anticheat software is to block malicious programs from reading and writing memory of other processes. Before more advanced enhancements to **PatchGuard**, anticheat and antivirus software were notorious for hooking the kernel, via an SSDT (System Service Dispatch Table) hook or straight up byte-patching, in order to monitor API calls from user-mode. **ObRegisterCallbacks** is Microsoft's official and supported method to intercept API calls that grant access rights of a process to another process. A very nice article that explains the internals of it can be found here: https://douggemhax.wordpress.com/2015/05/27/obregistercallbacks-and-countermeasures/.\n\n## Reversing OpenProcess\nBy design, a modern operating system implements **virtual memory** and **process isolation**, meaning that an arbitrary process X cannot reference memory in another arbitrary process Y.  ```OpenProcess``` is a powerful WinAPI function that allows a user-mode process to gain access rights to other processes by asking for permission granted by the kernel. This access right is the entrypoint to enable many other powerful functions that manipulate other processes such as ```ReadProcessMemory```, ```WriteProcessMemory```, and ```VirtualAllocEx```.\n\n```OpenProcess``` is an API that exported by **kernel32.dll**, which is part of the Windows subsystem that links against **ntdll.dll**, the library that contains all of the syscall stubs that will eventually call into the code in **ntoskrnl.exe** which does most of the work when it comes to implementing the higher level WinAPI functions.  \n\nLet's talk about the flow of code that gets executed when someone links against the Window SDK and calls ```OpenProcess```. The first thing that happens is that ```NtOpenProcess```, the underlying **ntdll.dll** API, gets called. Then, a syscall instruction gets executed with the index that maps to the equivalent to ```NtOpenProcess``` on the syscall table. At this point, execution is transferred to the kernel, where the actual implementation lives. Finally, an internal and undocumented function inside **ntoskrnl.exe**, ```PsOpenProcess``` gets called, and the result of that function is returned. \n\nHere's a diagram that is basically a tl;dr.\n![alt text](https://i.imgur.com/NqWD34r.png)\n\n## Registering Callbacks\n```ObRegisterCallbacks``` is a pretty well documented API on MSDN that clearly defines all the structures and parameters. Each callback you want to register is defined by the following structure and function prototypes:\n```cpp\nOB_PREOP_CALLBACK_STATUS PobPreOperationCallback(\n  PVOID RegistrationContext,\n  POB_PRE_OPERATION_INFORMATION OperationInformation\n);\n\nvoid PobPostOperationCallback(\n  PVOID RegistrationContext,\n  POB_POST_OPERATION_INFORMATION OperationInformation\n);\n\ntypedef struct _OB_OPERATION_REGISTRATION {\n  POBJECT_TYPE                *ObjectType;\n  OB_OPERATION                Operations;\n  POB_PRE_OPERATION_CALLBACK  PreOperation;\n  POB_POST_OPERATION_CALLBACK PostOperation;\n} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;\n```\n\nExample code for how to properly register callbacks can be found here: https://github.com/Microsoft/Windows-driver-samples/blob/master/general/obcallback/driver/callback.c\n\n## Intercepting an OpenProcess Call\nSo the next logical question at this point would be: where do these callbacks actually get called? Recall the diagram for the flow of execution for ```OpenProcess``` and all the steps that are taken to transition from user mode to kernel mode. It makes sense that somewhere along that path of code execution, the callback registered via ```ObRegisterCallbacks``` will be called, and it makes sense that this gets called in the kernel. Let's take a look at the disassembly starting from the implementation of ```NtOpenProcess``` inside **ntoskrnl.exe**.\n\nDisassembly from IDA shows us the following code:\n```nasm \nPAGE:0000000140583180 NtOpenProcess   proc near               ; CODE XREF: PfpSourceGetPrefetchSupport+A5↓p\nPAGE:0000000140583180                                         ; DATA XREF: .pdata:0000000140423B20↑o\nPAGE:0000000140583180\nPAGE:0000000140583180 var_18          = byte ptr -18h\nPAGE:0000000140583180 var_10          = byte ptr -10h\nPAGE:0000000140583180\nPAGE:0000000140583180                 sub     rsp, 38h\nPAGE:0000000140583184                 mov     rax, gs:188h\nPAGE:000000014058318D                 mov     r10b, [rax+232h]\nPAGE:0000000140583194                 mov     [rsp+38h+var_10], r10b\nPAGE:0000000140583199                 mov     [rsp+38h+var_18], r10b\nPAGE:000000014058319E                 call    PsOpenProcess\nPAGE:00000001405831A3                 add     rsp, 38h\nPAGE:00000001405831A7                 retn\nPAGE:00000001405831A7 NtOpenProcess   endp\n```\nCool, we don't see anything regarding ```ObRegisterCallbacks```, but we do see a call to ```PsOpenProcess```. Unfortunately, this function is extremely involved, so it doesn't make sense to paste an entire snippet here. Instead, let's look at a portion that may be related to ```ObRegisterCallbacks```.\n\n```nasm\nPAGE:00000001405836E0 PsOpenProcess   proc near               ; CODE XREF: NtAlpcOpenSenderProcess+194↑p\nPAGE:00000001405836E0                                         ; NtOpenProcess+1E↑p\nPAGE:00000001405836E0                                         ; DATA XREF: ...\nPAGE:0000000140583950 loc_140583950:                          ; CODE XREF: PsOpenProcess+411↓j\nPAGE:0000000140583950                 lea     rax, [rsp+2D8h+var_248]\nPAGE:0000000140583958                 mov     qword ptr [rsp+2D8h+var_2A8], rax ; int\nPAGE:000000014058395D                 mov     [rsp+2D8h+var_2B0], dil ; char\nPAGE:0000000140583962                 mov     rax, cs:PsProcessType\nPAGE:0000000140583969                 mov     [rsp+2D8h+var_2B8], rax ; __int64\nPAGE:000000014058396E                 xor     r9d, r9d\nPAGE:0000000140583971                 lea     r8, [rsp+2D8h+var_1E8]\nPAGE:0000000140583979                 mov     edx, [rsp+2D8h+var_294]\nPAGE:000000014058397D                 mov     rdi, [rsp+2D8h+BugCheckParameter2]\nPAGE:0000000140583985                 mov     rcx, rdi        ; BugCheckParameter2\nPAGE:0000000140583988                 call    ObOpenObjectByPointer\nPAGE:000000014058398D                 mov     ebx, eax\nPAGE:000000014058398F                 lea     rcx, [rsp+2D8h+var_1E8]\nPAGE:0000000140583997                 call    SepDeleteAccessState\nPAGE:000000014058399C                 lea     rcx, [rsp+2D8h+var_1C8]\nPAGE:00000001405839A4                 call    SeReleaseSubjectContext\nPAGE:00000001405839A9                 mov     eax, [rdi+2E0h]\nPAGE:00000001405839AF                 mov     [rsp+2D8h+var_288], eax\nPAGE:00000001405839B3                 mov     edx, 746C6644h\nPAGE:00000001405839B8                 mov     rcx, rdi        ; BugCheckParameter2\nPAGE:00000001405839BB                 call    ObfDereferenceObjectWithTag\nPAGE:00000001405839C0                 test    ebx, ebx\nPAGE:00000001405839C2                 js      short loc_1405839D8\n```\n\nWe see a function call to ```ObOpenObjectByPointer```. Symbols in the kernel are generally prefixed with an identifier that describes what type of data it manipulates. As seen here ```ObOpenObjectByPointer``` and ```ObRegisterCallbacks``` are both prefixed with ```Ob```, which would be the **Object Manager**. \n\n```nasm\nPAGE:00000001405831B0 ObOpenObjectByPointer proc near         ; CODE XREF: PspCreateObjectHandle+38↑p\nPAGE:00000001405831B0                                         ; NtQueryInformationProcess+35F0↑p ...\nPAGE:000000014058323F loc_14058323F:                          ; CODE XREF: ObOpenObjectByPointer+16E↓j\nPAGE:000000014058323F                 mov     [rsp+258h+var_208], r14\nPAGE:0000000140583244                 xor     r8d, r8d\nPAGE:0000000140583247                 mov     [rsp+258h+var_210], r13\nPAGE:000000014058324C                 mov     r9, rbx\nPAGE:000000014058324F                 mov     [rsp+258h+var_218], r13d\nPAGE:0000000140583254                 mov     rdx, rsi\nPAGE:0000000140583257                 mov     [rsp+258h+var_220], r13\nPAGE:000000014058325C                 mov     byte ptr [rsp+258h+var_228], r15b\nPAGE:0000000140583261                 lea     ecx, [r8+1]\nPAGE:0000000140583265                 mov     [rsp+258h+var_230], ebp\nPAGE:0000000140583269                 mov     dword ptr [rsp+258h+var_238], r13d\nPAGE:000000014058326E                 call    ObpCreateHandle\nPAGE:0000000140583273                 mov     edi, eax\nPAGE:0000000140583275                 test    eax, eax\nPAGE:0000000140583277                 js      loc_14058334F\n```\n\nInside ```ObOpenObjectByPointer```, we see another call to an **Object Manager** related function, ```ObpCreateHandle```.\n\n```nasm\nPAGE:00000001404DBEB0 ObpCreateHandle proc near               ; CODE XREF: ObInsertObjectEx+109↑p\nPAGE:00000001404DBEB0                                         ; ObInsertObjectEx+397↑p ...\nPAGE:00000001404DC7C1 loc_1404DC7C1:                          ; CODE XREF: ObpCreateHandle+324↑j\nPAGE:00000001404DC84A                 xor     eax, eax\nPAGE:00000001404DC84C                 mov     [rbp+110h+var_88], rax\nPAGE:00000001404DC853                 mov     [rbp+110h+Dst], 1\nPAGE:00000001404DC85A                 mov     [rbp+110h+var_90], rbx\nPAGE:00000001404DC861                 mov     dword ptr [rbp+110h+var_C8+4], edi\nPAGE:00000001404DC864                 mov     dword ptr [rbp+110h+var_C8], edi\nPAGE:00000001404DC867                 call    ObpCallPreOperationCallbacks\nPAGE:00000001404DC86C                 mov     ebx, eax\nPAGE:00000001404DC86E                 test    eax, eax\nPAGE:00000001404DC870                 js      loc_1406796F5\n```\n\nAnd finally, we find what we're looking for. ```ObpCallPreOperationCallbacks``` is the function that ultimately calls the ```POB_PRE_OPERATION_CALLBACK PreOperation``` function defined in the ```_OB_OPERATION_REGISTRATION``` structure initially passed into ```ObRegisterCallbacks```. In summary, this function loops over all of the ```_OB_OPERATION_REGISTRATION``` structures that are registered, and then sequentially calls each **PreOperation** function defined by a kernel mode driver.\n\n## Bypassing ObRegisterCallbacks\nDouggem's article details a method of bypassing these callbacks by using DKOM (Direct Kernel Object Manipulation) in order to locate the callbacks in kernel memory, and then remove them so that ```ObpCallPreOperationCallbacks``` has nothing to call. This method, though effective, has a few drawbacks.  \n1. Using undocumented structures could be dangerous due to Windows updates\n2. Forcibly removing callbacks means that the driver that registered them can execute sanity checks\n3. PatchGuard may someday decide to check for tampering of these kernel structures\n\n**libelevate** takes a different approach. Instead of directly touching callbacks to prevent stripping of access rights, why not elevate those rights after the fact that they have been stripped? \n\n### Locating a HANDLE in the kernel\nAn exported, but undocumented function ```ExEnumHandleTable``` does exactly what we want: execute a driver-defined function for every handle table entry in the handle table. Let's take a look at the disassembly:\n\n```nasm\nPAGE:000000014050E4C0 ExEnumHandleTable proc near             ; CODE XREF: IoRevokeHandlesForProcess+11E↑p\nPAGE:000000014050E4C0                                         ; NtQueryInformationProcess+29DE↑p ...\nPAGE:000000014050E5AF loc_14050E5AF:                          ; CODE XREF: ExEnumHandleTable+7A↑j\nPAGE:000000014050E5AF                                         ; DATA XREF: .pdata:000000014041EA38↑o ...\nPAGE:000000014050E5AF                 add     r9, 4\nPAGE:000000014050E5B3                 mov     rcx, rbp\nPAGE:000000014050E5B6                 mov     rdx, r9\nPAGE:000000014050E5B9                 call    ExpLookupHandleTableEntry\nPAGE:000000014050E5BE                 mov     rdi, rax\nPAGE:000000014050E5C1                 jmp     loc_14050E540\n```\n\nSweet, ```ExpLookupHandleTableEntry``` looks like a function that does what we actually want. This undocumented function takes in a **pointer to the object table**, found in the ```EPROCESS``` structure for a process, and the ```HANDLE``` value to look for. What this returns is a pointer to a ```_HANDLE_TABLE_ENTRY``` structure, which looks like this:\n```C\ntypedef struct _HANDLE_TABLE_ENTRY\n{\n     union\n     {\n          PVOID Object;\n          ULONG ObAttributes;\n          PHANDLE_TABLE_ENTRY_INFO InfoTable;\n          ULONG Value;\n     };\n     union\n     {\n          ULONG GrantedAccess;\n          struct\n          {\n               WORD GrantedAccessIndex;\n               WORD CreatorBackTraceIndex;\n          };\n          LONG NextFreeTableEntry;\n     };\n} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;\n```\n\n### Leveraging libcapcom\nImplementing the handle elevation technique is quite simple given all the information above. The flow of execution is the following:\n1. Open a handle with your desired access rights using ```OpenProcess```\n2. Antivirus/anticheat driver's callback strips your handle access rights\n3. In the context of the kernel:\n    * Find the ```HANDLE_TABLE_ENTRY``` that maps to the initial handle from step 1. \n    * Set the ```GrantedAccess``` member to your desired access rights\n4. Do whatever you want in user mode with your newly elevated handle\n\n### Caveats\n1. I have basically copy-pasted decompiled code for ```ExpLookupHandleTableEntry``` to be called in the context of the kernel. I can either do that, or implement a signature scan for the function, and call it directly. Either way, it is still Windows update dependent.\n2. Antivirus/anticheat drivers can still strip handles by **manually iterating the handle table** and stripping unauthorized handles. If I am able to elevate handles, then they can strip them after ```ObRegisterCallbacks``` too.\n\n## How to use this library\n1. Build the project\n2. Link against **libelevate.lib**\n3. Include **libelevate.h**\n4. Call ```OpenProcess```\n5. Call ```grant_access(HANDLE, ACCESS_MASK)``` with the returned ```HANDLE``` and your desired access rights\n\nAn example of the list above can be found in the **testlibelevate** project.\n![alt text](https://puu.sh/BxY5s/b1b4c4d15b.png)"
  },
  {
    "path": "libelevate/kerneloffsets.cpp",
    "content": "#include \"kerneloffsets.h\"\n\nwindows_version kernel_offsets::version;\nuint64_t kernel_offsets::name;\nuint64_t kernel_offsets::pid;\nuint64_t kernel_offsets::base;\nuint64_t kernel_offsets::link;\nuint64_t kernel_offsets::protection;\nuint64_t kernel_offsets::flags2;\nuint64_t kernel_offsets::objecttable;\nuint64_t kernel_offsets::vadroot;\n\nwindows_version get_windows_version()\n{\n\tstd::wstring wskernel32 = L\"\\\\kernel32.dll\";\n\n\twchar_t *path = NULL;\n\tvoid *ver = NULL, *block;\n\twindows_version version;\n\tUINT n;\n\tBOOL r;\n\tDWORD versz, blocksz;\n\tVS_FIXEDFILEINFO *vinfo;\n\n\tpath = (wchar_t*)malloc(sizeof(*path) * MAX_PATH);\n\tif (!path)\n\t\tabort();\n\n\tn = GetSystemDirectoryW(path, MAX_PATH);\n\tif (n >= MAX_PATH || n == 0 ||\n\t\tn > MAX_PATH - wskernel32.length())\n\t\tabort();\n\tmemcpy(path + n, wskernel32.c_str(), wskernel32.length() * sizeof(wchar_t) + 2);\n\n\tversz = GetFileVersionInfoSizeW(path, NULL);\n\tif (versz == 0)\n\t\tabort();\n\tver = malloc(versz);\n\tif (!ver)\n\t\tabort();\n\tr = GetFileVersionInfoW(path, 0, versz, ver);\n\tif (!r)\n\t\tabort();\n\tr = VerQueryValueA(ver, \"\\\\\", &block, (PUINT)&blocksz);\n\tif (!r || blocksz < sizeof(VS_FIXEDFILEINFO))\n\t\tabort();\n\tvinfo = (VS_FIXEDFILEINFO *)block;\n\tif ((int)HIWORD(vinfo->dwProductVersionMS) == 10)\n\t\tversion = WINDOWS10;\n\telse if ((int)HIWORD(vinfo->dwProductVersionMS) == 6)\n\t{\n\t\tswitch ((int)LOWORD(vinfo->dwProductVersionMS))\n\t\t{\n\t\tcase 0:\n\t\t\tversion = UNSUPPORTED;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tversion = WINDOWS7;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tversion = WINDOWS8;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tversion = WINDOWS81;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tversion = UNSUPPORTED;\n\t\t}\n\t}\n\telse\n\t\tversion = UNSUPPORTED;\n\n\tfree(path);\n\tfree(ver);\n\treturn version;\n}"
  },
  {
    "path": "libelevate/kerneloffsets.h",
    "content": "#pragma once\n\n#include <string>\n#include <Windows.h>\n\nenum windows_version\n{\n\tWINDOWS7,\n\tWINDOWS8,\n\tWINDOWS81,\n\tWINDOWS10,\n\tUNSUPPORTED\n};\n\nextern windows_version get_windows_version();\n\nextern \"C\" NTSTATUS RtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation);\n\nclass kernel_offsets\n{\npublic:\n\tstatic windows_version version;\n\n\t// Eprocess Offsets\n\tstatic uint64_t name;\n\tstatic uint64_t pid;\n\tstatic uint64_t base;\n\tstatic uint64_t link;\n\tstatic uint64_t protection;\n\tstatic uint64_t flags2;\n\tstatic uint64_t objecttable;\n\tstatic uint64_t vadroot;\n\n\tstatic void init()\n\t{\n\t\twindows_version win_ver = get_windows_version();\n\n\t\tversion = win_ver;\n\t\tswitch (win_ver)\n\t\t{\n\t\tcase WINDOWS7:\n\t\t\tinit_win7();\n\t\t\tbreak;\n\t\tcase WINDOWS8:\n\t\t\tinit_win8();\n\t\t\tbreak;\n\t\tcase WINDOWS81:\n\t\t\tinit_win81();\n\t\t\tbreak;\n\t\tcase WINDOWS10:\n\t\t\tinit_win10();\n\t\t\tbreak;\n\t\t}\n\t}\n\nprivate:\n\tstatic void init_win7()\n\t{\n\t\tname = 0x2D8;\n\t\tpid = 0x180;\n\t\tbase = 0x270;\n\t\tlink = 0x188;\n\t\tprotection = 0x43C;\n\t\tflags2 = 0;\n\t\tobjecttable = 0x200;\n\t\tvadroot = 0x448;\n\t}\n\n\tstatic void init_win8()\n\t{\n\t\tname = 0x438;\n\t\tpid = 0x2E0;\n\t\tbase = 0x3B0;\n\t\tlink = 0x2E8;\n\t\tprotection = 0x648;\n\t\tflags2 = 0;\n\t\tobjecttable = 0x408;\n\t\tvadroot = 0x590;\n\t}\n\n\tstatic void init_win81()\n\t{\n\t\tname = 0x438;\n\t\tpid = 0x2E0;\n\t\tbase = 0x3B0;\n\t\tlink = 0x2E8;\n\t\tprotection = 0x67A;\n\t\tflags2 = 0x2F8;\n\t\tobjecttable = 0x408;\n\t\tvadroot = 0x5D8;\n\t}\n\n\tstatic void init_win10()\n\t{\n\t\tname = 0x450;\n\t\tpid = 0x2E0;\n\t\tbase = 0x3C0;\n\t\tlink = 0x2E8;\n\t\tprotection = 0x6B2;\n\t\tflags2 = 0x300;\n\t\tobjecttable = 0x418;\n\t\tvadroot = 0x610;\n\n\t\tRTL_OSVERSIONINFOW osVersion;\n\t\tRtlGetVersion(&osVersion);\n\t\tif (osVersion.dwBuildNumber == 10586)\n\t\t{\n\t\t\tprotection = 0x6B2;\n\t\t\tflags2 = 0x300;\n\t\t\tobjecttable = 0x418;\n\t\t\tvadroot = 0x610;\n\t\t}\n\t\telse if (osVersion.dwBuildNumber == 14393)\n\t\t{\n\t\t\tprotection = 0x6C2;\n\t\t\tflags2 = 0x300;\n\t\t\tobjecttable = 0x418;\n\t\t\tvadroot = 0x620;\n\t\t}\n\t\telse if (osVersion.dwBuildNumber == 15063)\n\t\t{\n\t\t\tprotection = 0x6CA;\n\t\t\tflags2 = 0x300;\n\t\t\tobjecttable = 0x418;\n\t\t\tvadroot = 0x628;\n\t\t}\n\t\telse if (osVersion.dwBuildNumber == 16299)\n\t\t{\n\t\t\tprotection = 0x6CA;\n\t\t\tflags2 = 0x828;\n\t\t\tobjecttable = 0x418;\n\t\t\tvadroot = 0x628;\n\t\t}\n\t\telse if (osVersion.dwBuildNumber == 17134)\n\t\t{\n\t\t\tprotection = 0x6CA;\n\t\t\tflags2 = 0x828;\n\t\t\tobjecttable = 0x418;\n\t\t\tvadroot = 0x628;\n\t\t}\n\t}\n};"
  },
  {
    "path": "libelevate/libelevate.cpp",
    "content": "#include \"structs.h\"\n#include \"kerneloffsets.h\"\n#include \"libcapcom.h\"\n\nusing namespace native::structs;\n\nPHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry(PHANDLE_TABLE pHandleTable, HANDLE handle)\n{\n\tunsigned __int64 v2; // rdx\n\t__int64 v3; // r8\n\tsigned __int64 v4; // rax\n\t__int64 v5; // rax\n\n\tv2 = (__int64)handle & 0xFFFFFFFFFFFFFFFCui64;\n\tif (v2 >= *(DWORD*)pHandleTable)\n\t\treturn 0i64;\n\tv3 = *((uintptr_t*)pHandleTable + 1);\n\tv4 = *((uintptr_t *)pHandleTable + 1) & 3i64;\n\tif ((uint32_t)v4 == 1)\n\t{\n\t\tv5 = *(uintptr_t*)(v3 + 8 * (v2 >> 10) - 1);\n\t\treturn (PHANDLE_TABLE_ENTRY)(v5 + 4 * (v2 & 0x3FF));\n\t}\n\tif ((uint32_t)v4)\n\t{\n\t\tv5 = *(uintptr_t*)(*(uintptr_t *)(v3 + 8 * (v2 >> 19) - 2) + 8 * ((v2 >> 10) & 0x1FF));\n\t\treturn (PHANDLE_TABLE_ENTRY)(v5 + 4 * (v2 & 0x3FF));\n\t}\n\treturn (PHANDLE_TABLE_ENTRY)(v3 + 4 * v2);\n}\n\nbool grant_access(HANDLE handle, ACCESS_MASK access)\n{\n\tif (!init_exploit()) return false;\n\n\tkernel_offsets::init();\n\n\texecute_in_kernel([&handle, &access](MmGetSystemRoutineAddress_t _MmGetSystemRoutineAddress)\n\t{\n\t\tUNICODE_STRING DbgPrintExName = { 0 };\n\t\tRtlInitUnicodeString(&DbgPrintExName, L\"DbgPrintEx\");\n\n\t\tUNICODE_STRING PsGetCurrentProcessName = { 0 };\n\t\tRtlInitUnicodeString(&PsGetCurrentProcessName, L\"PsGetCurrentProcess\");\n\n\t\tDbgPrintEx_t _DbgPrintEx = (DbgPrintEx_t)_MmGetSystemRoutineAddress(&DbgPrintExName);\n\t\tPsGetCurrentProcess_t _PsGetCurrentProcess = (PsGetCurrentProcess_t)_MmGetSystemRoutineAddress(&PsGetCurrentProcessName);\n\n\t\tvoid* pEProcess = _PsGetCurrentProcess();\n\t\tPHANDLE_TABLE pHandleTable = *(PHANDLE_TABLE*)((unsigned char*)pEProcess + kernel_offsets::objecttable);\n\n\t\tPHANDLE_TABLE_ENTRY pEntry = ExpLookupHandleTableEntry(pHandleTable, handle);\n\t\tACCESS_MASK oldAccess = pEntry->GrantedAccess;\n\t\tpEntry->GrantedAccess = access;\n\n\t\t_DbgPrintEx(77, 0, \"Old: 0x%llx -> New: 0x%llx\", oldAccess, pEntry->GrantedAccess);\n\t});\n\n\treturn cleanup_exploit();\n}"
  },
  {
    "path": "libelevate/libelevate.h",
    "content": "#pragma once\n\n#include <Windows.h>\n\n/*\n\tGrants the given `handle` the access rights defined by `access`\n\n\t@param handle a handle that is created by a call to OpenProcess or\n\tOpenThread \n\t@param access a 32-bit mask that defines the access rights that a\n\thandle grants. More information can be found on MSDN:\n\thttps://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-security-and-access-rights\n\n\t@return true if the exploit was loaded, executed, and unloaded properly\n*/\nextern bool grant_access(HANDLE handle, ACCESS_MASK access);"
  },
  {
    "path": "libelevate/libelevate.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.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    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</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    <VCProjectVersion>15.0</VCProjectVersion>\n    <ProjectGuid>{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}</ProjectGuid>\n    <RootNamespace>libelevate</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>\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>v141</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>v141</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v141</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=\"Shared\">\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  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\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|x64'\">\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)'=='Release|x64'\">\n    <IncludePath>$(SolutionDir)libcapcom\\libcapcom;$(IncludePath)</IncludePath>\n    <LibraryPath>$(SolutionDir)x64\\Release;$(LibraryPath)</LibraryPath>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\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      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\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      <ConformanceMode>true</ConformanceMode>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <AdditionalDependencies>libcapcom.lib</AdditionalDependencies>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"kerneloffsets.cpp\" />\n    <ClCompile Include=\"libelevate.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"kerneloffsets.h\" />\n    <ClInclude Include=\"libelevate.h\" />\n    <ClInclude Include=\"structs.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "libelevate/libelevate.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;ipp;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    <ClCompile Include=\"libelevate.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"kerneloffsets.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"libelevate.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"kerneloffsets.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"structs.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "libelevate/structs.h",
    "content": "#pragma once\n#define WIN32_NO_STATUS\n#include <Windows.h>\n#include <Winternl.h>\n#undef WIN32_NO_STATUS\n#include <ntstatus.h>\n\nnamespace native::structs\n{\n\ttypedef struct _HANDLE_TABLE_ENTRY\n\t{\n\t\tunion\n\t\t{\n\t\t\tPVOID Object;\n\t\t\tULONG ObAttributes;\n\t\t};\n\t\tunion\n\t\t{\n\t\t\tunion\n\t\t\t{\n\t\t\t\tACCESS_MASK GrantedAccess;\n\t\t\t\tstruct\n\t\t\t\t{\n\t\t\t\t\tUSHORT GrantedAccessIndex;\n\t\t\t\t\tUSHORT CreatorBackTraceIndex;\n\t\t\t\t};\n\t\t\t};\n\t\t\tLONG NextFreeTableEntry;\n\t\t};\n\t} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;\n\n\ttypedef struct _HANDLE_TABLE\n\t{\n\t\tchar padding[100]; // we don't care about this actual structure\n\t} HANDLE_TABLE, *PHANDLE_TABLE;\n\n\ttypedef BOOLEAN(*EX_ENUMERATE_HANDLE_ROUTINE)(IN PHANDLE_TABLE_ENTRY, IN HANDLE, IN PVOID);\n\n\ttypedef CLIENT_ID* PCLIENT_ID;\n\ttypedef ULONG(*DbgPrintEx_t)(_In_ ULONG, _In_ ULONG, _In_ PCSTR, ...);\n\ttypedef PVOID(*PsGetCurrentProcess_t)();\n\ttypedef VOID(*RtlInitUnicodeString_t)(PUNICODE_STRING, PCWSTR);\n\ttypedef PVOID(NTAPI* MmGetSystemRoutineAddress_t)(PUNICODE_STRING);\n}\n"
  },
  {
    "path": "libelevate.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.28010.2016\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"libelevate\", \"libelevate\\libelevate.vcxproj\", \"{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206} = {AE5BAFC9-E4BA-4786-96E4-A564B113B206}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"libcapcom\", \"..\\libcapcom\\libcapcom\\libcapcom.vcxproj\", \"{AE5BAFC9-E4BA-4786-96E4-A564B113B206}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"testlibelevate\", \"testlibelevate\\testlibelevate.vcxproj\", \"{D5D362C4-C5E5-4567-91C1-9563A83423E4}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E} = {5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Debug|x64.Build.0 = Debug|x64\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Debug|x86.Build.0 = Debug|Win32\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Release|x64.ActiveCfg = Release|x64\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Release|x64.Build.0 = Release|x64\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Release|x86.ActiveCfg = Release|Win32\n\t\t{5BBDF4C8-27BC-488C-8D19-B3C345CA1F0E}.Release|x86.Build.0 = Release|Win32\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Debug|x64.Build.0 = Debug|x64\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Debug|x86.Build.0 = Debug|Win32\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Release|x64.ActiveCfg = Release|x64\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Release|x64.Build.0 = Release|x64\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Release|x86.ActiveCfg = Release|Win32\n\t\t{AE5BAFC9-E4BA-4786-96E4-A564B113B206}.Release|x86.Build.0 = Release|Win32\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Debug|x64.Build.0 = Debug|x64\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Debug|x86.Build.0 = Debug|Win32\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Release|x64.ActiveCfg = Release|x64\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Release|x64.Build.0 = Release|x64\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Release|x86.ActiveCfg = Release|Win32\n\t\t{D5D362C4-C5E5-4567-91C1-9563A83423E4}.Release|x86.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {A8666E26-937D-424D-B5B3-63D9FCD96291}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "testlibelevate/main.cpp",
    "content": "#include <stdio.h>\n#include <Windows.h>\n#include <tlhelp32.h>\n#include <map>\n#include <string>\n\n#include \"libelevate.h\"\n\nstd::map<std::string, DWORD> GetProcessList()\n{\n\tstd::map<std::string, DWORD> processList;\n\tPROCESSENTRY32 pe32;\n\tHANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n\tif (hSnapshot == INVALID_HANDLE_VALUE || hSnapshot == 0)\n\t\treturn processList;\n\n\tpe32.dwSize = sizeof(PROCESSENTRY32);\n\tif (!Process32First(hSnapshot, &pe32))\n\t{\n\t\tCloseHandle(hSnapshot);\n\t\treturn processList;\n\t}\n\n\tdo\n\t{\n\t\tprocessList[pe32.szExeFile] = pe32.th32ProcessID;\n\t} while (Process32Next(hSnapshot, &pe32));\n\n\tCloseHandle(hSnapshot);\n\treturn processList;\n}\n\nint main()\n{\n\tDWORD notepadPID = GetProcessList()[\"notepad.exe\"];\n\tHANDLE notepadHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, notepadPID);\n\tprintf(\"Elevating handle 0x%llx for PID %i from %s to %s\\n\", notepadHandle, notepadPID, \"PROCESS_QUERY_LIMITED INFORMATION\", \"PROCESS_ALL_ACCESS\");\n\tgrant_access(notepadHandle, PROCESS_ALL_ACCESS);\n\tsystem(\"pause\");\n\treturn 0;\n}"
  },
  {
    "path": "testlibelevate/testlibelevate.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.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    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</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    <VCProjectVersion>15.0</VCProjectVersion>\n    <ProjectGuid>{D5D362C4-C5E5-4567-91C1-9563A83423E4}</ProjectGuid>\n    <RootNamespace>testlibelevate</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>\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>v141</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>v141</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>MultiByte</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v141</PlatformToolset>\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>v141</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=\"Shared\">\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  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\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|x64'\">\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)'=='Release|x64'\">\n    <IncludePath>$(SolutionDir)libelevate\\;$(IncludePath)</IncludePath>\n    <LibraryPath>$(SolutionDir)x64\\Release;$(LibraryPath)</LibraryPath>\n  </PropertyGroup>\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      <ConformanceMode>true</ConformanceMode>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>libelevate.lib;Version.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <UACExecutionLevel>RequireAdministrator</UACExecutionLevel>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <SDLCheck>true</SDLCheck>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\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      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"main.cpp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "testlibelevate/testlibelevate.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;ipp;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    <ClCompile Include=\"main.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  }
]