diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c984ef1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 xerox
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 0480eee..362b273 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
# nasa-injector
-inserts a PML4E where a prior PML4E is set to not present, pointing at the PDPT that contains the dll.
\ No newline at end of file
+- 0 bytes allocated in the kernel.
+- 0 bytes allocated in the process.
+- 0 VAD entries created inside of the game.
+
+
\ No newline at end of file
diff --git a/injector.sln b/injector.sln
new file mode 100644
index 0000000..3a01a6d
--- /dev/null
+++ b/injector.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29613.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "injector", "injector\injector.vcxproj", "{CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Debug|x64.ActiveCfg = Debug|x64
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Debug|x64.Build.0 = Debug|x64
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Debug|x86.ActiveCfg = Debug|Win32
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Debug|x86.Build.0 = Debug|Win32
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Release|x64.ActiveCfg = Release|x64
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Release|x64.Build.0 = Release|x64
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Release|x86.ActiveCfg = Release|Win32
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {46DAEC7A-391F-4347-8C20-E11B52609A1B}
+ EndGlobalSection
+EndGlobal
diff --git a/injector/direct.h b/injector/direct.h
new file mode 100644
index 0000000..763f831
--- /dev/null
+++ b/injector/direct.h
@@ -0,0 +1,91 @@
+#pragma once
+#include
+#include
+#include
+
+extern "C" NTSTATUS __protect_virtual_memory(
+ HANDLE p_handle,
+ void** base_addr,
+ std::size_t* bytes_to_protect,
+ std::uint32_t new_protect,
+ std::uint32_t* old_protect
+);
+
+extern "C" NTSTATUS __write_virtual_memory(
+ HANDLE p_handle,
+ void* base_addr,
+ void* buffer,
+ std::size_t size,
+ std::size_t* bytes_written
+);
+
+extern "C" NTSTATUS __read_virtual_memory(
+ HANDLE p_handle,
+ void* base_addr,
+ void* buffer,
+ std::size_t size,
+ std::size_t* bytes_written
+);
+
+extern "C" NTSTATUS __alloc_virtual_memory(
+ HANDLE p_handle,
+ void** base_addr,
+ std::uint32_t zero_bits,
+ std::size_t* size,
+ std::uint32_t alloc_type,
+ std::uint32_t protect
+);
+
+namespace direct
+{
+ __forceinline bool protect_virtual_memory(
+ HANDLE p_handle,
+ void* base_addr,
+ std::size_t size,
+ std::uint32_t protect,
+ std::uint32_t* old_protect
+ )
+ {
+ return ERROR_SUCCESS == ::__protect_virtual_memory(p_handle, &base_addr, &size, protect, old_protect);
+ }
+
+ __forceinline bool write_virtual_memory(
+ HANDLE p_handle,
+ void* base_addr,
+ void* buffer,
+ std::size_t size
+ )
+ {
+ std::size_t bytes_written;
+ return ERROR_SUCCESS == __write_virtual_memory(p_handle, base_addr, buffer, size, &bytes_written);
+ }
+
+ __forceinline bool read_virtual_memory(
+ HANDLE p_handle,
+ void* addr,
+ void* buffer,
+ std::size_t size
+ )
+ {
+ std::size_t bytes_written;
+ return ERROR_SUCCESS == ::__read_virtual_memory(p_handle, addr, buffer, size, &bytes_written);
+ }
+
+ __forceinline void* alloc_virtual_memory(
+ HANDLE p_handle,
+ std::size_t size,
+ std::uint32_t protect
+ )
+ {
+ void* base_addr = NULL;
+ ::__alloc_virtual_memory(
+ p_handle,
+ &base_addr,
+ NULL,
+ &size,
+ MEM_COMMIT | MEM_RESERVE,
+ protect
+ );
+ return base_addr;
+ }
+}
\ No newline at end of file
diff --git a/injector/direct.lib b/injector/direct.lib
new file mode 100644
index 0000000..690bb6a
Binary files /dev/null and b/injector/direct.lib differ
diff --git a/injector/injector.cpp b/injector/injector.cpp
new file mode 100644
index 0000000..45fcd0c
--- /dev/null
+++ b/injector/injector.cpp
@@ -0,0 +1,93 @@
+#include
+#include "kernel_ctx/kernel_ctx.h"
+#include "mem_ctx/mem_ctx.hpp"
+#include "injector_ctx/injector_ctx.hpp"
+#include "util/util.hpp"
+
+int __cdecl main(int argc, char** argv)
+{
+ if (argc < 2)
+ {
+ MessageBoxA(NULL, "ERROR", "please provide dll", NULL);
+ return -1;
+ }
+ std::vector raw_image;
+ util::open_binary_file(argv[1], raw_image);
+
+ nasa::load_drv();
+ nasa::kernel_ctx kernel_ctx;
+ nasa::mem_ctx syscall_fix(kernel_ctx, GetCurrentProcessId());
+ kernel_ctx.fix_syscall(syscall_fix);
+
+ //
+ // shoot the tires off piddb cache entry.
+ //
+ {
+ const auto drv_timestamp = util::get_file_header((void*)raw_driver)->TimeDateStamp;
+ printf("[+] clearing piddb cache for driver: %s, with timestamp 0x%x\n", nasa::drv_key.c_str(), drv_timestamp);
+
+ if (!kernel_ctx.clear_piddb_cache(nasa::drv_key, drv_timestamp))
+ {
+ // this is because the signature might be broken on these versions of windows.
+ perror("[-] failed to clear PiDDBCacheTable.\n");
+ return -1;
+ }
+ printf("[+] cleared piddb cache...\n");
+ }
+ nasa::unload_drv();
+
+ //
+ // load the dll but dont actually call dll main
+ //
+ auto temp_module_base = LoadLibraryEx(argv[1], NULL, DONT_RESOLVE_DLL_REFERENCES);
+ std::cout << "[+] temp_module_base: " << temp_module_base << std::endl;
+ if (!temp_module_base)
+ return -1;
+
+ //
+ // get dll export RVA's
+ //
+ auto present_rva = (uint64_t)GetProcAddress(temp_module_base, "?event_handler@@YAKPEAXPEAW4event_type@@IPEAPEAPEAUIDXGISwapChain@@@Z") - (uint64_t)temp_module_base;
+ std::cout << "[+] present_rva: " << present_rva << std::endl;
+
+ if (!present_rva)
+ return -1;
+
+ auto pid = util::get_pid("RainbowSix.exe");
+ auto base_addr = util::get_module_base(pid, "RainbowSix.exe");
+ std::cout << "[+] pid: " << pid << " base address: " << base_addr << std::endl;
+
+ if (!pid || !base_addr)
+ return -1;
+
+ //
+ // create memory contexts for the game and this process
+ //
+ nasa::mem_ctx explorer(kernel_ctx, util::get_pid("explorer.exe"));
+ nasa::mem_ctx r6(kernel_ctx, pid);
+
+ //
+ // inject into the game
+ //
+ nasa::injector_ctx inject(r6, explorer);
+ const auto [inject_addr, inject_from_addr] = inject.inject(raw_image);
+
+ std::cout << "[+] injected into address: " << inject_addr << std::endl;
+ std::cout << "[+] (module base inside of injector) inject_from_addr: " << inject_from_addr << std::endl;
+ std::cin.get();
+
+ //
+ // install hooks on the game
+ //
+ auto result = inject.hook(
+ (void*)(((uint64_t)inject_addr) + present_rva)
+ );
+
+ std::cout << "[+] hook result: " << result << std::endl;
+ std::cin.get();
+
+ explorer.~mem_ctx();
+ r6.~mem_ctx();
+ syscall_fix.~mem_ctx();
+}
+
\ No newline at end of file
diff --git a/injector/injector.vcxproj b/injector/injector.vcxproj
new file mode 100644
index 0000000..cab906b
--- /dev/null
+++ b/injector/injector.vcxproj
@@ -0,0 +1,187 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {CAF2DBF5-95EA-49ED-95C8-43F7550E6B70}
+ Win32Proj
+ injector
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ MultiByte
+ false
+
+
+ Application
+ false
+ v142
+ true
+ MultiByte
+ false
+
+
+ Application
+ true
+ v142
+ MultiByte
+ false
+
+
+ Application
+ false
+ v142
+ true
+ MultiByte
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS
+ true
+ stdcpp17
+ false
+
+
+ Console
+ true
+
+
+
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS
+ true
+ stdcpp17
+ false
+
+
+ Console
+ true
+
+
+
+
+
+
+ Level3
+ true
+ false
+ true
+ _CRT_SECURE_NO_WARNINGS
+ true
+ stdcpp17
+ Disabled
+ false
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+ Level3
+ true
+ false
+ true
+ _CRT_SECURE_NO_WARNINGS
+ true
+ stdcpp17
+ Disabled
+ false
+
+
+ Console
+ true
+ true
+ true
+ direct.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/injector/injector.vcxproj.filters b/injector/injector.vcxproj.filters
new file mode 100644
index 0000000..002e436
--- /dev/null
+++ b/injector/injector.vcxproj.filters
@@ -0,0 +1,92 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {1ac5eac2-540f-4299-b247-6e474f0663c5}
+
+
+ {c8a6138a-6610-4ee7-b784-31950a4b2510}
+
+
+ {8f28f4f1-a8df-4c81-b593-10894d062d77}
+
+
+ {59ffe31b-8d86-44de-b8b8-d9e625fcf14d}
+
+
+ {adc0b7b7-1d99-4ac9-a713-e60536555241}
+
+
+ {afd76729-9a8c-4513-aa69-4128b87324b7}
+
+
+ {76959bd1-9765-439c-8c3e-92a8147e8345}
+
+
+ {18c7fd24-0e1f-4dd5-96c8-c1173a7f1981}
+
+
+ {ec029218-ad17-41b5-995a-7422a1c9a7d5}
+
+
+
+
+ Source Files
+
+
+ Source Files\kernel_ctx
+
+
+ Source Files\pe_image
+
+
+ Source Files\mem_ctx
+
+
+ Source Files\injector_ctx
+
+
+
+
+ Header Files\physmeme
+
+
+ Header Files\util
+
+
+ Header Files\util
+
+
+ Header Files\util
+
+
+ Source Files\pe_image
+
+
+ Header Files\mem_ctx
+
+
+ Header Files\kernel_ctx
+
+
+ Header Files\injector_ctx
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/injector/injector.vcxproj.user b/injector/injector.vcxproj.user
new file mode 100644
index 0000000..c8702e5
--- /dev/null
+++ b/injector/injector.vcxproj.user
@@ -0,0 +1,6 @@
+
+
+
+ WindowsLocalDebugger
+
+
\ No newline at end of file
diff --git a/injector/injector_ctx/injector_ctx.cpp b/injector/injector_ctx/injector_ctx.cpp
new file mode 100644
index 0000000..c37ef25
--- /dev/null
+++ b/injector/injector_ctx/injector_ctx.cpp
@@ -0,0 +1,124 @@
+#include "injector_ctx.hpp"
+#include "../direct.h"
+#include
+
+namespace nasa
+{
+ injector_ctx::injector_ctx(
+ mem_ctx& inject_into,
+ mem_ctx& inject_from
+ )
+ :
+ inject_into(inject_into),
+ inject_from(inject_from)
+ {}
+
+ std::pair injector_ctx::inject(
+ std::vector& raw_image,
+ const unsigned pml4_index
+ )
+ {
+ nasa::pe_image image(raw_image);
+ const auto p_handle = OpenProcess(
+ PROCESS_ALL_ACCESS,
+ FALSE,
+ inject_from.get_pid()
+ );
+
+ //
+ // allocate rwx memory for dll inside of explorer.exe
+ //
+ const auto module_base = direct::alloc_virtual_memory(
+ p_handle,
+ image.size() + 0x1000 * 512, //image size + 2mb (creates a new pde/pt)
+ PAGE_EXECUTE_READWRITE
+ );
+
+ image.fix_imports(NULL, NULL); // no imports
+ image.map();
+ image.relocate(reinterpret_cast(module_base));
+
+ //
+ // write dll into explorer.exe
+ //
+ auto result = direct::write_virtual_memory(
+ p_handle,
+ module_base,
+ image.data(),
+ image.size()
+ );
+
+ if (!result)
+ return {};
+
+ const auto [ppml4e, pml4e] = inject_from.get_pml4e(module_base);
+ if (!ppml4e || !pml4e.value)
+ return {};
+
+ const auto inject_into_dirbase = reinterpret_cast<::ppml4e>(inject_into.get_dirbase());
+ if (!inject_into_dirbase)
+ return {};
+
+ //
+ // write in pml4e containing dll at desired index
+ //
+ inject_into.write_phys<::pml4e>(
+ inject_into_dirbase + pml4_index,
+ pml4e
+ );
+
+ CloseHandle(p_handle);
+ virt_addr_t new_addr{ module_base };
+ new_addr.pml4_index = pml4_index;
+ return { new_addr.value, module_base };
+ }
+
+ bool injector_ctx::hook(void* present_hook)
+ {
+ if (!present_hook)
+ return false;
+
+ //
+ // get dxgi.dll base address
+ //
+ const auto dxgi = (std::uintptr_t)util::get_module_base(
+ inject_into.get_pid(),
+ "dxgi.dll"
+ );
+
+ std::cout << "[+] dxgi.dll base address: " << std::hex << dxgi << std::endl;
+ std::cin.get();
+
+ //
+ // IAT hook EtwEventWrite to our function
+ //
+ inject_into.write_virtual(
+ reinterpret_cast(dxgi + 0x9F000),
+ present_hook
+ );
+
+ std::cout << "[+] iat hooked: " << std::hex << dxgi + 0x9F000 << " to: " << present_hook << std::endl;
+ std::cin.get();
+
+ //
+ // enable EtwEventWrite to be called
+ //
+ {
+ inject_into.write_virtual(
+ reinterpret_cast(dxgi + 0xCB024),
+ 1
+ );
+
+ inject_into.write_virtual(
+ reinterpret_cast(dxgi + 0xCB010),
+ 0xFFFFFFFFFFFFFFFF
+ );
+
+ inject_into.write_virtual(
+ reinterpret_cast(dxgi + 0xCB018),
+ 0x4000000000000000
+ );
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/injector/injector_ctx/injector_ctx.hpp b/injector/injector_ctx/injector_ctx.hpp
new file mode 100644
index 0000000..2936f74
--- /dev/null
+++ b/injector/injector_ctx/injector_ctx.hpp
@@ -0,0 +1,21 @@
+#include