diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9c60f6d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 nasa-tech
+
+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 14b4af3..7044789 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,14 @@
-# luna-1
+# Old code from 6/xx/2020.
+### luna-1 (AMD)
+
+Driver gets allocated inside of the kernel using a normal pool. The Nt headers of the driver are zero'ed. Communication with this driver happens via a process specific
+syscall hook (meaning the hook cannot be seen in any other context). Detected on EAC, should be fine for BattlEye.
+
+
+### luna-1 (INTEL)
+
+Driver gets allocated inside of the current process (not the kernel itself) and makes a process specific syscall hook to communicate (just like the AMD one). The AMD luna-1
+also works for intel. This project is using a super old version of PSKDM which is not stable, its also using an old version of PTM and its using physmeme instead of VDM.
+
+Not sure if EAC is enumorating all processes PML4's yet, when they do this will be detected. Should be fine for BattlEye.
-old project from 6/xx/2020
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1 (AMD).sln b/luna-1 (AMD)/luna-1 (AMD).sln
new file mode 100644
index 0000000..61a8ad4
--- /dev/null
+++ b/luna-1 (AMD)/luna-1 (AMD).sln
@@ -0,0 +1,79 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30114.105
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "luna-1", "luna-1\luna-1.vcxproj", "{334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "luna-1(km)", "luna-1(km)\luna-1(km).vcxproj", "{D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "luna-1(example)", "luna-1(example)\luna-1(example).vcxproj", "{14450AD4-F983-46E9-B7A8-F1B6313BFF6D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Debug|ARM.ActiveCfg = Debug|Win32
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Debug|x64.ActiveCfg = Debug|x64
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Debug|x64.Build.0 = Debug|x64
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Debug|x86.ActiveCfg = Debug|Win32
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Debug|x86.Build.0 = Debug|Win32
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Release|ARM.ActiveCfg = Release|Win32
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Release|ARM64.ActiveCfg = Release|Win32
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Release|x64.ActiveCfg = Release|x64
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Release|x64.Build.0 = Release|x64
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Release|x86.ActiveCfg = Release|Win32
+ {334EDBD9-6A7C-4F6A-8EEC-022F8C2C04C3}.Release|x86.Build.0 = Release|Win32
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|ARM.ActiveCfg = Debug|ARM
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|ARM.Build.0 = Debug|ARM
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|ARM.Deploy.0 = Debug|ARM
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|ARM64.Build.0 = Debug|ARM64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|x64.ActiveCfg = Debug|x64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|x64.Build.0 = Debug|x64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|x64.Deploy.0 = Debug|x64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|x86.ActiveCfg = Debug|Win32
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|x86.Build.0 = Debug|Win32
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Debug|x86.Deploy.0 = Debug|Win32
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|ARM.ActiveCfg = Release|ARM
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|ARM.Build.0 = Release|ARM
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|ARM.Deploy.0 = Release|ARM
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|ARM64.ActiveCfg = Release|ARM64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|ARM64.Build.0 = Release|ARM64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|ARM64.Deploy.0 = Release|ARM64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|x64.ActiveCfg = Release|x64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|x64.Build.0 = Release|x64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|x64.Deploy.0 = Release|x64
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|x86.ActiveCfg = Release|Win32
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|x86.Build.0 = Release|Win32
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}.Release|x86.Deploy.0 = Release|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Debug|ARM.ActiveCfg = Debug|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Debug|x64.ActiveCfg = Debug|x64
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Debug|x64.Build.0 = Debug|x64
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Debug|x86.ActiveCfg = Debug|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Debug|x86.Build.0 = Debug|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Release|ARM.ActiveCfg = Release|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Release|ARM64.ActiveCfg = Release|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Release|x64.ActiveCfg = Release|x64
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Release|x64.Build.0 = Release|x64
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Release|x86.ActiveCfg = Release|Win32
+ {14450AD4-F983-46E9-B7A8-F1B6313BFF6D}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F503F818-2E0C-43DD-B842-3E2B8BE82E44}
+ EndGlobalSection
+EndGlobal
diff --git a/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj b/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj
new file mode 100644
index 0000000..30eda68
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj
@@ -0,0 +1,157 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {14450ad4-f983-46e9-b7a8-f1b6313bff6d}
+ luna1example
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ MultiByte
+
+
+ Application
+ false
+ v142
+ true
+ MultiByte
+
+
+ Application
+ true
+ v142
+ MultiByte
+ false
+
+
+ Application
+ false
+ v142
+ true
+ MultiByte
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ luna-1.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+ luna-1.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ luna-1.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+
+
+ Console
+ true
+ true
+ true
+ luna-1.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj.filters b/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj.filters
new file mode 100644
index 0000000..6ef8153
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj.filters
@@ -0,0 +1,23 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj.user b/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(example)/luna-1(example).vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(example)/luna-1.hpp b/luna-1 (AMD)/luna-1(example)/luna-1.hpp
new file mode 100644
index 0000000..7d0b3c5
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(example)/luna-1.hpp
@@ -0,0 +1,66 @@
+#pragma once
+#include
+#include
+
+namespace i6
+{
+ //
+ // please call this before making any other calls!
+ //
+ bool begin();
+
+ //
+ // get process id of process.
+ //
+ unsigned get_pid(const char* proc_name);
+
+ //
+ // get process base address.
+ //
+ std::uintptr_t get_process_base(unsigned pid);
+
+ //
+ // get module base
+ //
+ std::uintptr_t get_module_base(unsigned pid, const wchar_t* module_name);
+
+ //
+ // read/write to specific process
+ //
+ bool read(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size);
+ bool write(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size);
+
+ //
+ // read/write kernel memory (you can write to readonly with this)
+ //
+ bool rkm(std::uintptr_t addr, void* buffer, std::size_t size);
+ bool wkm(std::uintptr_t addr, void* buffer, std::size_t size);
+
+ template
+ T rkm(std::uintptr_t addr)
+ {
+ T buffer{};
+ rkm(addr, (void*)&buffer, sizeof(T));
+ return buffer;
+ }
+
+ template
+ bool wkm(std::uintptr_t addr, const T& data)
+ {
+ return wkm(addr, (void*)&data, sizeof(T));
+ }
+
+ template
+ T read(unsigned pid, std::uintptr_t addr)
+ {
+ T buffer{};
+ read(pid, addr, (void*)&buffer, sizeof(T));
+ return buffer;
+ }
+
+ template
+ bool write(unsigned pid, std::uintptr_t addr, const T& data)
+ {
+ return write(pid, addr, (void*)&data, sizeof(T));
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(example)/luna-1.lib b/luna-1 (AMD)/luna-1(example)/luna-1.lib
new file mode 100644
index 0000000..528465e
Binary files /dev/null and b/luna-1 (AMD)/luna-1(example)/luna-1.lib differ
diff --git a/luna-1 (AMD)/luna-1(example)/main.cpp b/luna-1 (AMD)/luna-1(example)/main.cpp
new file mode 100644
index 0000000..3c9d3aa
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(example)/main.cpp
@@ -0,0 +1,24 @@
+#include
+#include "luna-1.hpp"
+
+int main()
+{
+ if (!i6::begin()) // call this before anything else.
+ {
+ std::cout << "[!] failed to init..." << std::endl;
+ std::cin.get();
+ return -1;
+ }
+ else
+ {
+ auto notepad_pid = i6::get_pid("notepad.exe");
+ auto notepad_base = i6::get_process_base(notepad_pid);
+
+ std::cout << "[+] notepad pid: " << notepad_pid << std::endl;
+ std::cout << "[+] notepad base address: " << notepad_base << std::endl;
+ std::cin.get();
+
+ while (true)
+ std::cout << "[+] notepad MZ: " << std::hex << i6::read(notepad_pid, notepad_base) << std::endl;
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/com_functions.cpp b/luna-1 (AMD)/luna-1(km)/com_functions.cpp
new file mode 100644
index 0000000..03b8e2d
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/com_functions.cpp
@@ -0,0 +1,158 @@
+#include "com_functions.h"
+#include "memory.h"
+
+namespace i6
+{
+ namespace com
+ {
+ void get_process_base(const pcom_struct com_data)
+ {
+ if (!com_data || !com_data->pid)
+ return;
+
+ PEPROCESS peproc;
+ if (PsLookupProcessByProcessId((HANDLE)com_data->pid, &peproc) != STATUS_SUCCESS)
+ return;
+
+ com_data->data_from = PsGetProcessSectionBaseAddress(peproc);
+ ObDereferenceObject(peproc);
+ }
+
+ void get_module_base(const pcom_struct com_data)
+ {
+ if (!com_data || !com_data->pid || !com_data->data_to)
+ return;
+
+ PEPROCESS peproc;
+ if (PsLookupProcessByProcessId((HANDLE)com_data->pid, &peproc) != STATUS_SUCCESS)
+ return;
+
+ auto ppeb = PsGetProcessPeb(peproc);
+ ObDereferenceObject(peproc);
+ if (!ppeb)
+ return;
+
+ PEB peb;
+ i6::memory::read(
+ ppeb,
+ &peb,
+ sizeof(peb),
+ com_data->pid
+ );
+
+ if (!peb.Ldr)
+ return;
+
+ PEB_LDR_DATA module_list_entry;
+ i6::memory::read(
+ peb.Ldr,
+ &module_list_entry,
+ sizeof(module_list_entry),
+ com_data->pid
+ );
+
+ auto first_entry = (void*)module_list_entry.InMemoryOrderModuleList.Flink;
+ unsigned char* current_entry;
+ i6::memory::read(
+ first_entry,
+ ¤t_entry,
+ sizeof(current_entry),
+ com_data->pid
+ );
+
+ WCHAR full_file_name[MAX_PATH];
+ ULONGLONG module_base;
+ ULONGLONG file_name_ptr;
+
+ while (current_entry != first_entry)
+ {
+ i6::memory::read(
+ (unsigned char*)(current_entry)+0x40,
+ &file_name_ptr,
+ sizeof(file_name_ptr),
+ com_data->pid
+ ); // read full module unicode_string structure.
+
+ i6::memory::read(
+ (void*)file_name_ptr,
+ full_file_name,
+ MAX_PATH,
+ com_data->pid
+ ); // read full file path.
+
+ i6::memory::read(
+ (unsigned char*)(current_entry)+0x20,
+ &module_base,
+ sizeof(module_base),
+ com_data->pid
+ );
+
+ if (wcsstr(full_file_name, (wchar_t*)com_data->data_to))
+ {
+ com_data->data_from = reinterpret_cast(module_base);
+ return;
+ }
+
+ i6::memory::read(
+ current_entry,
+ ¤t_entry,
+ sizeof(current_entry),
+ com_data->pid
+ );
+ }
+ }
+
+ void read_process_memory(const pcom_struct com_data)
+ {
+ if (!com_data || !com_data->pid || !com_data->data_from || !com_data->data_to || !com_data->size)
+ return;
+
+ i6::memory::read(
+ com_data->data_from,
+ com_data->data_to,
+ com_data->size,
+ com_data->pid
+ );
+ }
+
+ void write_process_memory(const pcom_struct com_data)
+ {
+ if (!com_data || !com_data->pid || !com_data->data_from || !com_data->data_to || !com_data->size)
+ return;
+
+ i6::memory::write
+ (
+ com_data->data_to,
+ com_data->data_from,
+ com_data->size,
+ com_data->pid
+ );
+ }
+
+ void read_kernel_memory(const pcom_struct com_data)
+ {
+ if (!com_data || !com_data->data_from || !com_data->data_to)
+ return;
+
+ memcpy
+ (
+ com_data->data_to,
+ com_data->data_from,
+ com_data->size
+ );
+ }
+
+ void write_kernel_memory(const pcom_struct com_data)
+ {
+ if (!com_data || !com_data->data_from || !com_data->data_to)
+ return;
+
+ memcpy
+ (
+ com_data->data_to,
+ com_data->data_from,
+ com_data->size
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/com_functions.h b/luna-1 (AMD)/luna-1(km)/com_functions.h
new file mode 100644
index 0000000..efb5bef
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/com_functions.h
@@ -0,0 +1,15 @@
+#pragma once
+#include "types.h"
+
+namespace i6
+{
+ namespace com
+ {
+ void get_process_base(const pcom_struct com_data);
+ void get_module_base(const pcom_struct com_data);
+ void read_process_memory(const pcom_struct com_data);
+ void write_process_memory(const pcom_struct com_data);
+ void read_kernel_memory(const pcom_struct com_data);
+ void write_kernel_memory(const pcom_struct com_data);
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/hook_handler.cpp b/luna-1 (AMD)/luna-1(km)/hook_handler.cpp
new file mode 100644
index 0000000..3a4cd51
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/hook_handler.cpp
@@ -0,0 +1,37 @@
+#include "com_functions.h"
+
+void hook_handler(pcom_struct com_data)
+{
+ if (!com_data)
+ return;
+
+ switch (com_data->type)
+ {
+ case READ:
+ i6::com::read_process_memory(com_data);
+ break;
+ case WRITE:
+ i6::com::write_process_memory(com_data);
+ break;
+ case WRITE_KERNEL_MEMORY:
+ i6::com::write_kernel_memory(com_data);
+ break;
+ case READ_KERNEL_MEMORY:
+ i6::com::read_kernel_memory(com_data);
+ break;
+ case GET_PROCESS_BASE:
+ i6::com::get_process_base(com_data);
+ break;
+ case GET_MODULE_BASE:
+ i6::com::get_module_base(com_data);
+ break;
+ default:
+ break;
+ }
+}
+
+NTSTATUS driver_entry(void** data_ptr)
+{
+ *data_ptr = &hook_handler;
+ return STATUS_SUCCESS;
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/luna-1(km).inf b/luna-1 (AMD)/luna-1(km)/luna-1(km).inf
new file mode 100644
index 0000000..ce3ca62
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/luna-1(km).inf
@@ -0,0 +1,87 @@
+;
+; luna-1(km).inf
+;
+
+[Version]
+Signature="$WINDOWS NT$"
+Class=Sample ; TODO: edit Class
+ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid
+Provider=%ManufacturerName%
+CatalogFile=luna-1(km).cat
+DriverVer= ; TODO: set DriverVer in stampinf property pages
+PnpLockDown=1
+
+[DestinationDirs]
+DefaultDestDir = 12
+luna-1(km)_Device_CoInstaller_CopyFiles = 11
+
+; ================= Class section =====================
+
+[ClassInstall32]
+Addreg=SampleClassReg
+
+[SampleClassReg]
+HKR,,,0,%ClassName%
+HKR,,Icon,,-5
+
+[SourceDisksNames]
+1 = %DiskName%,,,""
+
+[SourceDisksFiles]
+luna-1(km).sys = 1,,
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames
+
+;*****************************************
+; Install Section
+;*****************************************
+
+[Manufacturer]
+%ManufacturerName%=Standard,NT$ARCH$
+
+[Standard.NT$ARCH$]
+%luna-1(km).DeviceDesc%=luna-1(km)_Device, Root\luna-1(km) ; TODO: edit hw-id
+
+[luna-1(km)_Device.NT]
+CopyFiles=Drivers_Dir
+
+[Drivers_Dir]
+luna-1(km).sys
+
+;-------------- Service installation
+[luna-1(km)_Device.NT.Services]
+AddService = luna-1(km),%SPSVCINST_ASSOCSERVICE%, luna-1(km)_Service_Inst
+
+; -------------- luna-1(km) driver install sections
+[luna-1(km)_Service_Inst]
+DisplayName = %luna-1(km).SVCDESC%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %12%\luna-1(km).sys
+
+;
+;--- luna-1(km)_Device Coinstaller installation ------
+;
+
+[luna-1(km)_Device.NT.CoInstallers]
+AddReg=luna-1(km)_Device_CoInstaller_AddReg
+CopyFiles=luna-1(km)_Device_CoInstaller_CopyFiles
+
+[luna-1(km)_Device_CoInstaller_AddReg]
+HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
+
+[luna-1(km)_Device_CoInstaller_CopyFiles]
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
+
+[luna-1(km)_Device.NT.Wdf]
+KmdfService = luna-1(km), luna-1(km)_wdfsect
+[luna-1(km)_wdfsect]
+KmdfLibraryVersion = $KMDFVERSION$
+
+[Strings]
+SPSVCINST_ASSOCSERVICE= 0x00000002
+ManufacturerName="" ;TODO: Replace with your manufacturer name
+ClassName="Samples" ; TODO: edit ClassName
+DiskName = "luna-1(km) Installation Disk"
+luna-1(km).DeviceDesc = "luna-1(km) Device"
+luna-1(km).SVCDESC = "luna-1(km) Service"
diff --git a/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj b/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj
new file mode 100644
index 0000000..254976d
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj
@@ -0,0 +1,173 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM
+
+
+ Release
+ ARM
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {D8ED4627-18E7-4E6F-8C20-8809EB66B6D6}
+ {1bc93793-694f-48fe-9372-81e2b05556fd}
+ v4.5
+ 12.0
+ Debug
+ Win32
+ luna_1_km_
+ $(LatestTargetPlatformVersion)
+
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+ false
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+ false
+ false
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ KMDF
+ Universal
+
+
+
+
+
+
+
+
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+
+ false
+ stdcpp17
+ false
+
+
+ driver_entry
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj.filters b/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj.filters
new file mode 100644
index 0000000..0d713df
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj.user b/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/luna-1(km).vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/memory.cpp b/luna-1 (AMD)/luna-1(km)/memory.cpp
new file mode 100644
index 0000000..4d582ab
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/memory.cpp
@@ -0,0 +1,70 @@
+#include "memory.h"
+
+namespace i6
+{
+ namespace memory
+ {
+ void read(void* addr, void* buffer, size_t size, unsigned pid)
+ {
+ if (!addr || !buffer || !size)
+ return;
+
+ char memcpy_buffer[0x1000];
+ memset(memcpy_buffer, NULL, sizeof(memcpy_buffer));
+
+ KAPC_STATE state;
+ PEPROCESS peproc;
+ if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)pid, &peproc)) && peproc)
+ {
+ KeStackAttachProcess(peproc, &state);
+ if (MmIsAddressValid(addr))
+ memcpy(memcpy_buffer, addr, size);
+
+ KeUnstackDetachProcess(&state);
+ if(MmIsAddressValid(buffer))
+ memcpy(buffer, memcpy_buffer, size);
+ ObDereferenceObject(peproc);
+ }
+ }
+
+ void write(void* addr, void* buffer, size_t size, unsigned pid)
+ {
+ if (!addr || !buffer || !size)
+ return;
+
+ char memcpy_buffer[0x1000];
+ memset(memcpy_buffer, NULL, sizeof(memcpy_buffer));
+
+ if (MmIsAddressValid(buffer))
+ memcpy(memcpy_buffer, buffer, size);
+
+ KAPC_STATE state;
+ PEPROCESS peproc;
+ if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)pid, &peproc)) && peproc)
+ {
+ KeStackAttachProcess(peproc, &state);
+ if (MmIsAddressValid(addr))
+ memcpy(addr, memcpy_buffer, size);
+
+ KeUnstackDetachProcess(&state);
+ ObDereferenceObject(peproc);
+ }
+ }
+
+ void disable_wp()
+ {
+ _disable();
+ auto cr0 = __readcr0();
+ cr0 &= 0xfffffffffffeffff;
+ __writecr0(cr0);
+ }
+
+ void enable_wp()
+ {
+ auto cr0 = __readcr0();
+ cr0 |= 0x10000;
+ __writecr0(cr0);
+ _enable();
+ }
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/memory.h b/luna-1 (AMD)/luna-1(km)/memory.h
new file mode 100644
index 0000000..52d558d
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/memory.h
@@ -0,0 +1,15 @@
+#pragma once
+#include
+#include "types.h"
+
+namespace i6
+{
+ namespace memory
+ {
+ void disable_wp();
+ void enable_wp();
+
+ void read(void* addr, void* buffer, size_t size, unsigned pid);
+ void write(void* addr, void* buffer, size_t size, unsigned pid);
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1(km)/types.h b/luna-1 (AMD)/luna-1(km)/types.h
new file mode 100644
index 0000000..3555013
--- /dev/null
+++ b/luna-1 (AMD)/luna-1(km)/types.h
@@ -0,0 +1,101 @@
+#pragma once
+#include
+#include
+
+enum com_type
+{
+ READ,
+ WRITE,
+ READ_KERNEL_MEMORY,
+ WRITE_KERNEL_MEMORY,
+ GET_PROCESS_BASE,
+ GET_MODULE_BASE
+};
+
+typedef struct _com_struct
+{
+ com_type type;
+ unsigned pid;
+ unsigned size;
+ void* data_from;
+ void* data_to;
+} com_struct, * pcom_struct;
+
+extern "C" PVOID PsGetProcessSectionBaseAddress(
+ __in PEPROCESS Process
+);
+
+extern "C" PPEB PsGetProcessPeb(PEPROCESS process);
+
+extern "C" NTSTATUS MmCopyVirtualMemory(
+ _In_ PEPROCESS FromProcess,
+ _In_ CONST VOID* FromAddress,
+ _In_ PEPROCESS ToProcess,
+ _Out_opt_ PVOID ToAddress,
+ _In_ SIZE_T BufferSize,
+ _In_ KPROCESSOR_MODE PreviousMode,
+ _Out_ PSIZE_T NumberOfBytesCopied
+);
+
+typedef struct _PEB_LDR_DATA
+{
+ BYTE Reserved1[8];
+ PVOID Reserved2[3];
+ LIST_ENTRY InMemoryOrderModuleList;
+} PEB_LDR_DATA, * PPEB_LDR_DATA;
+
+typedef struct _LDR_DATA_TABLE_ENTRY
+{
+ PVOID Reserved1[2];
+ LIST_ENTRY InMemoryOrderLinks;
+ PVOID Reserved2[2];
+ PVOID DllBase;
+ PVOID Reserved3[2];
+ UNICODE_STRING FullDllName;
+ BYTE Reserved4[8];
+ PVOID Reserved5[3];
+#pragma warning(push)
+#pragma warning(disable: 4201) // we'll always use the Microsoft compiler
+ union
+ {
+ ULONG CheckSum;
+ PVOID Reserved6;
+ } DUMMYUNIONNAME;
+#pragma warning(pop)
+ ULONG TimeDateStamp;
+} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
+
+typedef struct _RTL_USER_PROCESS_PARAMETERS {
+ BYTE Reserved1[16];
+ PVOID Reserved2[10];
+ UNICODE_STRING ImagePathName;
+ UNICODE_STRING CommandLine;
+} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
+
+typedef
+VOID
+(NTAPI* PPS_POST_PROCESS_INIT_ROUTINE) (
+ VOID
+);
+
+typedef struct _PEB {
+ BYTE Reserved1[2];
+ BYTE BeingDebugged;
+ BYTE Reserved2[1];
+ PVOID Reserved3[2];
+ PPEB_LDR_DATA Ldr;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+ PVOID Reserved4[3];
+ PVOID AtlThunkSListPtr;
+ PVOID Reserved5;
+ ULONG Reserved6;
+ PVOID Reserved7;
+ ULONG Reserved8;
+ ULONG AtlThunkSListPtr32;
+ PVOID Reserved9[45];
+ BYTE Reserved10[96];
+ PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
+ BYTE Reserved11[128];
+ PVOID Reserved12[1];
+ ULONG SessionId;
+} PEB, * PPEB;
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/direct.asm b/luna-1 (AMD)/luna-1/direct.asm
new file mode 100644
index 0000000..0988870
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/direct.asm
@@ -0,0 +1,30 @@
+_TEXT SEGMENT
+ __protect_virtual_memory proc
+ mov r10, rcx
+ mov eax, 050h
+ syscall
+ ret
+ __protect_virtual_memory endp
+
+ __write_virtual_memory proc
+ mov r10, rcx
+ mov eax, 03Ah
+ syscall
+ ret
+ __write_virtual_memory endp
+
+ __read_virtual_memory proc
+ mov r10, rcx
+ mov eax, 03Fh
+ syscall
+ ret
+ __read_virtual_memory endp
+
+ __alloc_virtual_memory proc
+ mov r10, rcx
+ mov eax, 018h
+ syscall
+ ret
+ __alloc_virtual_memory endp
+_TEXT ENDS
+end
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/direct.h b/luna-1 (AMD)/luna-1/direct.h
new file mode 100644
index 0000000..763f831
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/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/luna-1 (AMD)/luna-1/drv_image/drv_image.cpp b/luna-1 (AMD)/luna-1/drv_image/drv_image.cpp
new file mode 100644
index 0000000..0f3a8ae
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/drv_image/drv_image.cpp
@@ -0,0 +1,196 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to
+
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!! This code was created by not-wlan (wlan). all credit for this header and source file goes to him !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+*/
+
+#include
+#include "../drv_image/drv_image.h"
+
+namespace nasa
+{
+ drv_image::drv_image(std::vector image) : m_image(std::move(image))
+ {
+ m_dos_header = reinterpret_cast(m_image.data());
+ m_nt_headers = reinterpret_cast((uintptr_t)m_dos_header + m_dos_header->e_lfanew);
+ m_section_header = reinterpret_cast((uintptr_t)(&m_nt_headers->OptionalHeader) + m_nt_headers->FileHeader.SizeOfOptionalHeader);
+ }
+
+ size_t drv_image::size() const
+ {
+ return m_nt_headers->OptionalHeader.SizeOfImage;
+ }
+
+ uintptr_t drv_image::entry_point() const
+ {
+ return m_nt_headers->OptionalHeader.AddressOfEntryPoint;
+ }
+
+ void drv_image::map()
+ {
+ m_image_mapped.clear();
+ m_image_mapped.resize(m_nt_headers->OptionalHeader.SizeOfImage);
+ std::copy_n(m_image.begin(), m_nt_headers->OptionalHeader.SizeOfHeaders, m_image_mapped.begin());
+
+ for (size_t i = 0; i < m_nt_headers->FileHeader.NumberOfSections; ++i)
+ {
+ const auto& section = m_section_header[i];
+ const auto target = (uintptr_t)m_image_mapped.data() + section.VirtualAddress;
+ const auto source = (uintptr_t)m_dos_header + section.PointerToRawData;
+ std::copy_n(m_image.begin() + section.PointerToRawData, section.SizeOfRawData, m_image_mapped.begin() + section.VirtualAddress);
+ }
+ }
+
+ bool drv_image::process_relocation(uintptr_t image_base_delta, uint16_t data, uint8_t* relocation_base)
+ {
+#define IMR_RELOFFSET(x) (x & 0xFFF)
+
+ switch (data >> 12 & 0xF)
+ {
+ case IMAGE_REL_BASED_HIGH:
+ {
+ const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += static_cast(HIWORD(image_base_delta));
+ break;
+ }
+ case IMAGE_REL_BASED_LOW:
+ {
+ const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += static_cast(LOWORD(image_base_delta));
+ break;
+ }
+ case IMAGE_REL_BASED_HIGHLOW:
+ {
+ const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += static_cast(image_base_delta);
+ break;
+ }
+ case IMAGE_REL_BASED_DIR64:
+ {
+ auto UNALIGNED raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += image_base_delta;
+ break;
+ }
+ case IMAGE_REL_BASED_ABSOLUTE: // No action required
+ case IMAGE_REL_BASED_HIGHADJ: // no action required
+ {
+ break;
+ }
+ default:
+ {
+ return false;
+ }
+
+ }
+#undef IMR_RELOFFSET
+
+ return true;
+ }
+
+
+ void drv_image::relocate(void* base) const
+ {
+ if (m_nt_headers->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
+ return;
+
+ ULONG total_count_bytes;
+ const auto nt_headers = ImageNtHeader((void*)m_image_mapped.data());
+ auto relocation_directory = (PIMAGE_BASE_RELOCATION)::ImageDirectoryEntryToData(nt_headers, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &total_count_bytes);
+ auto image_base_delta = static_cast(reinterpret_cast(base) - (nt_headers->OptionalHeader.ImageBase));
+ auto relocation_size = total_count_bytes;
+
+ // This should check (DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) too but lots of drivers do not have it set due to WDK defaults
+ const bool do_reloc = image_base_delta != 0 && relocation_size > 0;
+ if (!do_reloc)
+ return;
+
+ void* relocation_end = reinterpret_cast(relocation_directory) + relocation_size;
+ while (relocation_directory < relocation_end)
+ {
+ auto relocation_base = ::ImageRvaToVa(nt_headers, (void*)m_image_mapped.data(), relocation_directory->VirtualAddress, nullptr);
+ auto num_relocs = (relocation_directory->SizeOfBlock - 8) >> 1;
+ auto relocation_data = reinterpret_cast(relocation_directory + 1);
+
+ for (unsigned long i = 0; i < num_relocs; ++i, ++relocation_data)
+ if (process_relocation(image_base_delta, *relocation_data, (uint8_t*)relocation_base) == FALSE)
+ return;
+
+ relocation_directory = reinterpret_cast(relocation_data);
+ }
+
+ }
+
+ template
+ __forceinline T* ptr_add(void* base, uintptr_t offset)
+ {
+ return (T*)(uintptr_t)base + offset;
+ }
+
+ void drv_image::fix_imports(const std::function get_module, const std::function get_function)
+ {
+ ULONG size;
+ auto import_descriptors = static_cast(::ImageDirectoryEntryToData(m_image.data(), FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size));
+
+ if (import_descriptors == nullptr)
+ return;
+
+ for (; import_descriptors->Name; import_descriptors++)
+ {
+ IMAGE_THUNK_DATA* image_thunk_data;
+
+ const auto module_name = get_rva(import_descriptors->Name);
+ const auto module_base = get_module(module_name);
+
+ if (import_descriptors->OriginalFirstThunk)
+ image_thunk_data = get_rva(import_descriptors->OriginalFirstThunk);
+ else
+ image_thunk_data = get_rva(import_descriptors->FirstThunk);
+ auto image_func_data = get_rva(import_descriptors->FirstThunk);
+;
+
+ for (; image_thunk_data->u1.AddressOfData; image_thunk_data++, image_func_data++)
+ {
+ uintptr_t function_address;
+ const auto ordinal = (image_thunk_data->u1.Ordinal & IMAGE_ORDINAL_FLAG64) != 0;
+ const auto image_import_by_name = get_rva(*(DWORD*)image_thunk_data);
+ const auto name_of_import = static_cast(image_import_by_name->Name);
+ function_address = get_function(module_name, name_of_import);
+ image_func_data->u1.Function = function_address;
+ }
+ }
+ }
+
+ void* drv_image::data()
+ {
+ return m_image_mapped.data();
+ }
+
+ size_t drv_image::header_size()
+ {
+ return m_nt_headers->OptionalHeader.SizeOfHeaders;
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/drv_image/drv_image.h b/luna-1 (AMD)/luna-1/drv_image/drv_image.h
new file mode 100644
index 0000000..e8cda94
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/drv_image/drv_image.h
@@ -0,0 +1,77 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to
+
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!! This code was created by not-wlan (wlan). all credit for this header and source file goes to him !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+*/
+
+
+#pragma once
+#include
+#define WIN32_NO_STATUS
+#include
+#include
+#undef WIN32_NO_STATUS
+#include
+
+#include
+#include
+#include
+#include "../util/nt.hpp"
+
+#pragma comment(lib, "Dbghelp.lib")
+namespace nasa
+{
+ class drv_image
+ {
+ std::vector m_image;
+ std::vector m_image_mapped;
+ PIMAGE_DOS_HEADER m_dos_header = nullptr;
+ PIMAGE_NT_HEADERS64 m_nt_headers = nullptr;
+ PIMAGE_SECTION_HEADER m_section_header = nullptr;
+
+ public:
+ explicit drv_image(std::vector image);
+ size_t size() const;
+ uintptr_t entry_point() const;
+ void map();
+ static bool process_relocation(size_t image_base_delta, uint16_t data, uint8_t* relocation_base);
+ void relocate(void* base) const;
+
+ template
+ __forceinline T* get_rva(const unsigned long offset)
+ {
+ return (T*)::ImageRvaToVa(m_nt_headers, m_image.data(), offset, nullptr);
+ }
+
+ void fix_imports(
+ const std::function get_module,
+ const std::function get_function
+ );
+ void* data();
+ size_t header_size();
+ };
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/kernel_ctx/kernel_ctx.cpp b/luna-1 (AMD)/luna-1/kernel_ctx/kernel_ctx.cpp
new file mode 100644
index 0000000..ac7cf08
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/kernel_ctx/kernel_ctx.cpp
@@ -0,0 +1,374 @@
+#include "kernel_ctx.h"
+#include "../mem_ctx/mem_ctx.hpp"
+
+namespace nasa
+{
+ kernel_ctx::kernel_ctx()
+ {
+ if (psyscall_func.load() || nt_page_offset || ntoskrnl_buffer)
+ return;
+
+ nt_rva = reinterpret_cast(
+ util::get_module_export(
+ "ntoskrnl.exe",
+ syscall_hook.first.data(),
+ true
+ ));
+
+ nt_page_offset = nt_rva % PAGE_SIZE;
+ ntoskrnl_buffer = reinterpret_cast(LoadLibraryExA("ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES));
+
+ std::vector search_threads;
+ //--- for each physical memory range, make a thread to search it
+ for (auto ranges : util::pmem_ranges)
+ search_threads.emplace_back(std::thread(
+ &kernel_ctx::map_syscall,
+ this,
+ ranges.first,
+ ranges.second
+ ));
+
+ for (std::thread& search_thread : search_threads)
+ search_thread.join();
+ }
+
+ void kernel_ctx::map_syscall(std::uintptr_t begin, std::uintptr_t end) const
+ {
+ //if the physical memory range is less then or equal to 2mb
+ if (begin + end <= 0x1000 * 512)
+ {
+ auto page_va = nasa::map_phys(begin + nt_page_offset, end);
+ if (page_va)
+ {
+ // scan every page of the physical memory range
+ for (auto page = page_va; page < page_va + end; page += 0x1000)
+ if (!is_page_found.load()) // keep scanning until its found
+ if (!memcmp(reinterpret_cast(page), ntoskrnl_buffer + nt_rva, 32))
+ {
+ //
+ // this checks to ensure that the syscall does indeed work. if it doesnt, we keep looking!
+ //
+ psyscall_func.store((void*)page);
+ auto my_proc_base = reinterpret_cast(GetModuleHandleA(NULL));
+ auto my_proc_base_from_syscall = reinterpret_cast(get_proc_base(GetCurrentProcessId()));
+
+ if (my_proc_base != my_proc_base_from_syscall)
+ continue;
+
+ is_page_found.store(true);
+ return;
+ }
+ nasa::unmap_phys(page_va, end);
+ }
+ }
+ else // else the range is bigger then 2mb
+ {
+ auto remainder = (begin + end) % (0x1000 * 512);
+
+ // loop over 2m chunks
+ for (auto range = begin; range < begin + end; range += 0x1000 * 512)
+ {
+ auto page_va = nasa::map_phys(range + nt_page_offset, 0x1000 * 512);
+ if (page_va)
+ {
+ // loop every page of 2mbs (512)
+ for (auto page = page_va; page < page_va + 0x1000 * 512; page += 0x1000)
+ {
+ if (!is_page_found.load())
+ {
+ if (!memcmp(reinterpret_cast(page), ntoskrnl_buffer + nt_rva, 32))
+ {
+ //
+ // this checks to ensure that the syscall does indeed work. if it doesnt, we keep looking!
+ //
+ psyscall_func.store((void*)page);
+ auto my_proc_base = reinterpret_cast(GetModuleHandle(NULL));
+ auto my_proc_base_from_syscall = reinterpret_cast(get_proc_base(GetCurrentProcessId()));
+
+ if (my_proc_base != my_proc_base_from_syscall)
+ continue;
+
+ is_page_found.store(true);
+ return;
+ }
+ }
+ }
+ nasa::unmap_phys(page_va, 0x1000 * 512);
+ }
+ }
+
+ // map the remainder and check each page of it
+ auto page_va = nasa::map_phys(begin + end - remainder + nt_page_offset, remainder);
+ if (page_va)
+ {
+ for (auto page = page_va; page < page_va + remainder; page += 0x1000)
+ {
+ if (!is_page_found.load())
+ {
+ if (!memcmp(reinterpret_cast(page), ntoskrnl_buffer + nt_rva, 32))
+ {
+ //
+ // this checks to ensure that the syscall does indeed work. if it doesnt, we keep looking!
+ //
+ psyscall_func.store((void*)page);
+ auto my_proc_base = reinterpret_cast(GetModuleHandle(NULL));
+ auto my_proc_base_from_syscall = reinterpret_cast(get_proc_base(GetCurrentProcessId()));
+
+ if (my_proc_base != my_proc_base_from_syscall)
+ continue;
+
+ is_page_found.store(true);
+ return;
+ }
+ }
+ }
+ nasa::unmap_phys(page_va, remainder);
+ }
+ }
+ }
+
+ PEPROCESS kernel_ctx::get_peprocess(unsigned pid) const
+ {
+ if (!pid)
+ return NULL;
+
+ PEPROCESS proc;
+ static auto get_peprocess_from_pid =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "PsLookupProcessByProcessId"
+ );
+
+ const auto status = syscall(
+ get_peprocess_from_pid,
+ (HANDLE)pid,
+ &proc
+ );
+ return proc;
+ }
+
+ void* kernel_ctx::get_proc_base(unsigned pid) const
+ {
+ if (!pid)
+ return {};
+
+ const auto peproc = get_peprocess(pid);
+
+ if (!peproc)
+ return {};
+
+ static auto get_section_base =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "PsGetProcessSectionBaseAddress"
+ );
+
+ return syscall(
+ get_section_base,
+ peproc
+ );
+ }
+
+ void kernel_ctx::rkm(void* buffer, void* address, std::size_t size)
+ {
+ if (!buffer || !address || !size)
+ return;
+
+ size_t amount_copied;
+ static auto mm_copy_memory =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "memcpy"
+ );
+
+ if (mm_copy_memory)
+ syscall(
+ mm_copy_memory,
+ buffer,
+ address,
+ size
+ );
+ }
+
+ void kernel_ctx::wkm(void* buffer, void* address, std::size_t size)
+ {
+ if (!buffer || !address || !size)
+ return;
+
+ static auto mm_copy_memory =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "memcpy"
+ );
+
+ if (mm_copy_memory)
+ syscall(
+ mm_copy_memory,
+ address,
+ buffer,
+ size
+ );
+ }
+
+ void* kernel_ctx::get_physical(void* virt_addr)
+ {
+ if (!virt_addr)
+ return NULL;
+
+ static auto mm_get_physical =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "MmGetPhysicalAddress"
+ );
+
+ return syscall(
+ mm_get_physical,
+ virt_addr
+ );
+ }
+
+ void* kernel_ctx::get_virtual(void* addr)
+ {
+ if (!addr)
+ return NULL;
+
+ static auto mm_get_virtual =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "MmGetVirtualForPhysical"
+ );
+
+ PHYSICAL_ADDRESS phys_addr;
+ memcpy(&phys_addr, &addr, sizeof(addr));
+ return syscall(
+ mm_get_virtual,
+ phys_addr
+ );
+ }
+
+ void* kernel_ctx::allocate_pool(std::size_t size, POOL_TYPE pool_type)
+ {
+ static const auto ex_alloc_pool =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "ExAllocatePool"
+ );
+
+ return syscall(
+ ex_alloc_pool,
+ pool_type,
+ size
+ );
+ }
+
+ void kernel_ctx::zero_kernel_memory(void* addr, std::size_t size)
+ {
+ static const auto rtl_zero_memory =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "RtlZeroMemory"
+ );
+
+ syscall(
+ rtl_zero_memory,
+ addr,
+ size
+ );
+ }
+
+ bool kernel_ctx::clear_piddb_cache(const std::string& file_name, const std::uint32_t timestamp)
+ {
+ static const auto piddb_lock =
+ util::memory::get_piddb_lock();
+
+ static const auto piddb_table =
+ util::memory::get_piddb_table();
+
+ if (!piddb_lock || !piddb_table)
+ return false;
+
+ static const auto ex_acquire_resource =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "ExAcquireResourceExclusiveLite"
+ );
+
+ static const auto lookup_element_table =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "RtlLookupElementGenericTableAvl"
+ );
+
+ static const auto release_resource =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "ExReleaseResourceLite"
+ );
+
+ static const auto delete_table_entry =
+ util::get_module_export(
+ "ntoskrnl.exe",
+ "RtlDeleteElementGenericTableAvl"
+ );
+
+ if (!ex_acquire_resource || !lookup_element_table || !release_resource)
+ return false;
+
+ PiDDBCacheEntry cache_entry;
+ const auto drv_name = std::wstring(file_name.begin(), file_name.end());
+ cache_entry.time_stamp = timestamp;
+ RtlInitUnicodeString(&cache_entry.driver_name, drv_name.data());
+
+ //
+ // ExAcquireResourceExclusiveLite
+ //
+ if (!syscall(ex_acquire_resource, piddb_lock, true))
+ return false;
+
+ //
+ // RtlLookupElementGenericTableAvl
+ //
+ PIDCacheobj* found_entry_ptr =
+ syscall(
+ lookup_element_table,
+ piddb_table,
+ reinterpret_cast(&cache_entry)
+ );
+
+ if (found_entry_ptr)
+ {
+
+ //
+ // unlink entry.
+ //
+ PIDCacheobj found_entry = rkm(found_entry_ptr);
+ LIST_ENTRY NextEntry = rkm(found_entry.list.Flink);
+ LIST_ENTRY PrevEntry = rkm(found_entry.list.Blink);
+
+ PrevEntry.Flink = found_entry.list.Flink;
+ NextEntry.Blink = found_entry.list.Blink;
+
+ wkm(found_entry.list.Blink, PrevEntry);
+ wkm(found_entry.list.Flink, NextEntry);
+
+ //
+ // delete entry.
+ //
+ syscall(delete_table_entry, piddb_table, found_entry_ptr);
+
+ //
+ // ensure the entry is 0
+ //
+ auto result = syscall(
+ lookup_element_table,
+ piddb_table,
+ reinterpret_cast(&cache_entry)
+ );
+
+ syscall(release_resource, piddb_lock);
+ return !result;
+ }
+ syscall(release_resource, piddb_lock);
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/kernel_ctx/kernel_ctx.h b/luna-1 (AMD)/luna-1/kernel_ctx/kernel_ctx.h
new file mode 100644
index 0000000..41cac90
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/kernel_ctx/kernel_ctx.h
@@ -0,0 +1,124 @@
+#pragma once
+#include "../util/util.hpp"
+#include "../physmeme/physmeme.hpp"
+#include "../util/hook.hpp"
+
+namespace nasa
+{
+ //
+ // offset of function into a physical page
+ // used for comparing bytes when searching
+ //
+ inline std::uint16_t nt_page_offset{};
+
+ //
+ // rva of nt function we are going to hook
+ //
+ inline std::uint32_t nt_rva{};
+
+ //
+ // base address of ntoskrnl (inside of this process)
+ //
+ inline const std::uint8_t* ntoskrnl_buffer{};
+
+ //
+ // has the page been found yet?
+ //
+ inline std::atomic is_page_found = false;
+
+ //
+ // mapping of a syscalls physical memory (for installing hooks)
+ //
+ inline std::atomic psyscall_func{};
+
+ //
+ // you can edit this how you choose, im hooking NtShutdownSystem.
+ //
+ inline const std::pair syscall_hook = { "NtShutdownSystem", "ntdll.dll" };
+
+ class kernel_ctx
+ {
+ friend class mem_ctx;
+ public:
+ kernel_ctx();
+
+ //
+ // read kernel memory into buffer
+ //
+ void rkm(void* buffer, void* address, std::size_t size);
+
+ //
+ // write kernel memory from buffer
+ //
+ void wkm(void* buffer, void* address, std::size_t size);
+
+ template
+ T rkm(void* addr)
+ {
+ if (!addr)
+ return {};
+ T buffer;
+ rkm((void*)&buffer, addr, sizeof(T));
+ return buffer;
+ }
+
+ template
+ void wkm(void* addr, const T& data)
+ {
+ if (!addr)
+ return;
+ wkm((void*)&data, addr, sizeof(T));
+ }
+
+ //
+ // gets physical address from virtual
+ //
+ void* get_physical(void* virt_addr);
+
+ //
+ // uses the pfn database to get the virtual address
+ //
+ void* get_virtual(void* virt_addr);
+
+ //
+ // use this to call any function in the kernel
+ //
+ template
+ std::invoke_result_t syscall(void* addr, Ts ... args) const
+ {
+ static const auto proc =
+ GetProcAddress(
+ GetModuleHandleA(syscall_hook.second.data()),
+ syscall_hook.first.data()
+ );
+
+ hook::make_hook(psyscall_func, addr);
+ auto result = reinterpret_cast(proc)(args ...);
+ hook::remove(psyscall_func);
+ return result;
+ }
+
+ //
+ // clear piddb cache of specific process.
+ //
+ bool clear_piddb_cache(const std::string& drv_name, const std::uint32_t epoch_time);
+
+ //
+ // get a pointer to an eprocess given process id.
+ //
+ PEPROCESS get_peprocess(unsigned pid) const;
+
+ //
+ // get base address of process (used to compare and ensure we find the right page).
+ //
+ void* get_proc_base(unsigned pid) const;
+ void* allocate_pool(std::size_t size, POOL_TYPE pool_type);
+ void zero_kernel_memory(void* addr, std::size_t size);
+ private:
+
+ //
+ // find and map the physical page of a syscall into this process
+ //
+ void map_syscall(std::uintptr_t begin, std::uintptr_t end) const;
+ };
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/loadup.hpp b/luna-1 (AMD)/luna-1/loadup.hpp
new file mode 100644
index 0000000..7966b2b
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/loadup.hpp
@@ -0,0 +1,298 @@
+/*
+ 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.
+*/
+
+
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+
+#pragma comment(lib, "ntdll.lib")
+using nt_load_driver_t = NTSTATUS(__fastcall*)(PUNICODE_STRING);
+using nt_unload_driver_t = NTSTATUS(__fastcall*)(PUNICODE_STRING);
+
+namespace driver
+{
+ namespace util
+ {
+ inline bool delete_service_entry(const std::string& service_name)
+ {
+ HKEY reg_handle;
+ static const std::string reg_key("System\\CurrentControlSet\\Services\\");
+
+ auto result = RegOpenKeyA(
+ HKEY_LOCAL_MACHINE,
+ reg_key.c_str(),
+ ®_handle
+ );
+
+ return ERROR_SUCCESS == RegDeleteKeyA(reg_handle, service_name.data()) && ERROR_SUCCESS == RegCloseKey(reg_handle);
+ }
+
+ inline bool create_service_entry(const std::string& drv_path, const std::string& service_name)
+ {
+ HKEY reg_handle;
+ std::string reg_key("System\\CurrentControlSet\\Services\\");
+ reg_key += service_name;
+
+ auto result = RegCreateKeyA(
+ HKEY_LOCAL_MACHINE,
+ reg_key.c_str(),
+ ®_handle
+ );
+
+ if (result != ERROR_SUCCESS)
+ return false;
+
+ //
+ // set type to 1 (kernel)
+ //
+ constexpr std::uint8_t type_value = 1;
+ result = RegSetValueExA(
+ reg_handle,
+ "Type",
+ NULL,
+ REG_DWORD,
+ &type_value,
+ 4u
+ );
+
+ if (result != ERROR_SUCCESS)
+ return false;
+
+ //
+ // set error control to 3
+ //
+ constexpr std::uint8_t error_control_value = 3;
+ result = RegSetValueExA(
+ reg_handle,
+ "ErrorControl",
+ NULL,
+ REG_DWORD,
+ &error_control_value,
+ 4u
+ );
+
+ if (result != ERROR_SUCCESS)
+ return false;
+
+ //
+ // set start to 3
+ //
+ constexpr std::uint8_t start_value = 3;
+ result = RegSetValueExA(
+ reg_handle,
+ "Start",
+ NULL,
+ REG_DWORD,
+ &start_value,
+ 4u
+ );
+
+ if (result != ERROR_SUCCESS)
+ return false;
+
+ //
+ // set image path to the driver on disk
+ //
+ result = RegSetValueExA(
+ reg_handle,
+ "ImagePath",
+ NULL,
+ REG_SZ,
+ (std::uint8_t*) drv_path.c_str(),
+ drv_path.size()
+ );
+
+ if (result != ERROR_SUCCESS)
+ return false;
+
+ return ERROR_SUCCESS == RegCloseKey(reg_handle);
+ }
+
+ // this function was coded by paracord: https://githacks.org/snippets/4#L94
+ inline bool enable_privilege(const std::wstring& privilege_name)
+ {
+ HANDLE token_handle = nullptr;
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token_handle))
+ return false;
+
+ LUID luid{};
+ if (!LookupPrivilegeValueW(nullptr, privilege_name.data(), &luid))
+ return false;
+
+ TOKEN_PRIVILEGES token_state{};
+ token_state.PrivilegeCount = 1;
+ token_state.Privileges[0].Luid = luid;
+ token_state.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!AdjustTokenPrivileges(token_handle, FALSE, &token_state, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))
+ return false;
+
+ CloseHandle(token_handle);
+ return true;
+ }
+
+ inline std::string get_service_image_path(const std::string& service_name)
+ {
+ HKEY reg_handle;
+ DWORD bytes_read;
+ char image_path[0xFF];
+ static const std::string reg_key("System\\CurrentControlSet\\Services\\");
+
+ auto result = RegOpenKeyA(
+ HKEY_LOCAL_MACHINE,
+ reg_key.c_str(),
+ ®_handle
+ );
+
+ result = RegGetValueA(
+ reg_handle,
+ service_name.c_str(),
+ "ImagePath",
+ REG_SZ,
+ NULL,
+ image_path,
+ &bytes_read
+ );
+
+ RegCloseKey(reg_handle);
+ return std::string(image_path);
+ }
+ }
+
+ inline bool load(const std::string& drv_path, const std::string& service_name)
+ {
+ if (!util::enable_privilege(L"SeLoadDriverPrivilege"))
+ return false;
+
+ if (!util::create_service_entry("\\??\\" + std::filesystem::absolute(std::filesystem::path(drv_path)).string(), service_name))
+ return false;
+
+ std::string reg_path("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+ reg_path += service_name;
+
+ static const auto lp_nt_load_drv =
+ ::GetProcAddress(
+ GetModuleHandleA("ntdll.dll"),
+ "NtLoadDriver"
+ );
+
+ if (lp_nt_load_drv)
+ {
+ ANSI_STRING driver_rep_path_cstr;
+ UNICODE_STRING driver_reg_path_unicode;
+
+ RtlInitAnsiString(&driver_rep_path_cstr, reg_path.c_str());
+ RtlAnsiStringToUnicodeString(&driver_reg_path_unicode, &driver_rep_path_cstr, true);
+ return ERROR_SUCCESS == reinterpret_cast(lp_nt_load_drv)(&driver_reg_path_unicode);
+ }
+ return false;
+ }
+
+ inline std::tuple load(const std::vector& drv_buffer)
+ {
+ static const auto random_file_name = [](std::size_t length) -> std::string
+ {
+ static const auto randchar = []() -> char
+ {
+ const char charset[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ const std::size_t max_index = (sizeof(charset) - 1);
+ return charset[rand() % max_index];
+ };
+ std::string str(length, 0);
+ std::generate_n(str.begin(), length, randchar);
+ return str;
+ };
+
+ const auto service_name = random_file_name(16);
+ const auto file_path = std::filesystem::temp_directory_path().string() + service_name;
+
+ const auto h_file = CreateFileA(
+ file_path.data(),
+ GENERIC_ALL,
+ NULL, NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+
+ DWORD bytes_written;
+ WriteFile(
+ h_file,
+ drv_buffer.data(),
+ drv_buffer.size(),
+ &bytes_written,
+ NULL
+ );
+
+ CloseHandle(h_file);
+ return { load(file_path, service_name), service_name };
+ }
+
+ inline std::tuple load(const std::uint8_t* buffer, const std::size_t size)
+ {
+ std::vector image(buffer, buffer + size);
+ return load(image);
+ }
+
+ inline bool unload(const std::string& service_name)
+ {
+ std::string reg_path("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+ reg_path += service_name;
+
+ static const auto lp_nt_unload_drv =
+ ::GetProcAddress(
+ GetModuleHandleA("ntdll.dll"),
+ "NtUnloadDriver"
+ );
+
+ if (lp_nt_unload_drv)
+ {
+ ANSI_STRING driver_rep_path_cstr;
+ UNICODE_STRING driver_reg_path_unicode;
+
+ RtlInitAnsiString(&driver_rep_path_cstr, reg_path.c_str());
+ RtlAnsiStringToUnicodeString(&driver_reg_path_unicode, &driver_rep_path_cstr, true);
+
+ const bool unload_drv = !reinterpret_cast(lp_nt_unload_drv)(&driver_reg_path_unicode);
+ const auto image_path = std::filesystem::temp_directory_path().string() + service_name;
+ const bool delete_reg = util::delete_service_entry(service_name);
+ try
+ {
+ const bool delete_drv = std::filesystem::remove(image_path);
+ }
+ catch (std::exception& e) {}
+ return unload_drv && delete_reg;
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/luna-1.cpp b/luna-1 (AMD)/luna-1/luna-1.cpp
new file mode 100644
index 0000000..0bea1b7
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/luna-1.cpp
@@ -0,0 +1,233 @@
+#include "luna-1.hpp"
+#include "raw_driver.hpp"
+#include "patch_ctx/patch_ctx.hpp"
+#include "map_driver.hpp"
+
+namespace i6
+{
+ inline nasa::kernel_ctx* kernel_ctx;
+ inline nasa::mem_ctx* mem_ctx;
+ inline nasa::patch_ctx* kernel_patch;
+ inline hook::detour* win32kbase_detour;
+
+ inline std::mutex syscall_lock;
+ inline void* kernel_hook_handler = nullptr;
+ inline void* win32u_handler = nullptr;
+ inline void* win32kbase_handler = nullptr;
+ inline void* patch_address = nullptr;
+
+ enum com_type
+ {
+ READ,
+ WRITE,
+ READ_KERNEL_MEMORY,
+ WRITE_KERNEL_MEMORY,
+ GET_PROCESS_BASE,
+ GET_MODULE_BASE
+ };
+
+ typedef struct _com_struct
+ {
+ com_type type;
+ unsigned pid;
+ unsigned size;
+ void* data_from;
+ void* data_to;
+ } com_struct, * pcom_struct;
+
+ bool begin()
+ {
+ //
+ // make kernel_ctx and fix syscall page so there is no physical memory mapped into this process!
+ //
+ if (!nasa::load_drv())
+ return false;
+
+ //
+ // make driver and get the address of hook handler.
+ //
+ const auto result =
+ nasa::map_driver(
+ i6::luna_1,
+ sizeof(i6::luna_1),
+ &kernel_hook_handler
+ );
+
+ if (!result)
+ goto exit;
+
+ kernel_ctx = new nasa::kernel_ctx();
+ mem_ctx = new nasa::mem_ctx(*kernel_ctx, GetCurrentProcessId());
+ if (!kernel_ctx->clear_piddb_cache(nasa::drv_key, util::get_file_header((void*)raw_driver)->TimeDateStamp))
+ goto exit;
+
+ memset(i6::luna_1, NULL, sizeof(i6::luna_1));
+ win32kbase_handler =
+ util::get_module_export(
+ "win32kbase.sys",
+ "NtDCompositionBeginFrame"
+ );
+
+ if (!win32kbase_handler)
+ goto exit;
+
+ //
+ // needed for syscall
+ //
+ LoadLibrary("user32.dll");
+ win32u_handler =
+ ::GetProcAddress(
+ LoadLibraryA("win32u.dll"),
+ "NtDCompositionBeginFrame"
+ );
+
+ if (!win32u_handler)
+ goto exit;
+
+ kernel_patch = new nasa::patch_ctx(mem_ctx);
+ patch_address = kernel_patch->patch(win32kbase_handler);
+ win32kbase_detour = new hook::detour(patch_address, kernel_hook_handler, false);
+
+ //
+ // enable patch and flush tlb!
+ //
+ kernel_patch->enable();
+ FLUSH_TLB;
+
+ exit:
+ if (mem_ctx) delete mem_ctx;
+ if (kernel_patch) delete kernel_patch;
+ if (kernel_ctx) delete kernel_ctx;
+
+ nasa::unmap_all();
+ if (!nasa::unload_drv())
+ return false;
+ return true;
+ }
+
+ void syscall(const pcom_struct com_data)
+ {
+ syscall_lock.lock();
+ win32kbase_detour->install();
+ reinterpret_cast(win32u_handler)(com_data);
+ win32kbase_detour->uninstall();
+ syscall_lock.unlock();
+ }
+
+ std::uintptr_t get_process_base(unsigned pid)
+ {
+ if (!pid)
+ return {};
+
+ com_struct com_data;
+ com_data.type = GET_PROCESS_BASE;
+ com_data.pid = pid;
+ syscall(&com_data);
+ return reinterpret_cast(com_data.data_from);
+ }
+
+ std::uintptr_t get_module_base(unsigned pid, const wchar_t* module_name)
+ {
+ if (!pid || !module_name)
+ return {};
+
+ com_struct com_data;
+ com_data.type = GET_MODULE_BASE;
+ com_data.data_to = (void*)module_name;
+ com_data.pid = pid;
+ syscall(&com_data);
+ return reinterpret_cast(com_data.data_from);
+ }
+
+ bool read(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size)
+ {
+ if (!pid || !addr || !buffer || !size)
+ return false;
+
+ com_struct com_data;
+ com_data.type = READ;
+ com_data.pid = pid;
+ com_data.data_from = reinterpret_cast(addr);
+ com_data.data_to = buffer;
+ com_data.size = size;
+ syscall(&com_data);
+ return true;
+ }
+
+ bool write(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size)
+ {
+ if (!pid || !addr || !buffer || !size)
+ return false;
+
+ com_struct com_data;
+ com_data.type = WRITE;
+ com_data.pid = pid;
+ com_data.data_from = buffer;
+ com_data.data_to = reinterpret_cast(addr);
+ com_data.size = size;
+ syscall(&com_data);
+ return true;
+ }
+
+ bool rkm(std::uintptr_t addr, void* buffer, std::size_t size)
+ {
+ if (!addr || !buffer || !size)
+ return false;
+
+ com_struct com_data;
+ com_data.type = READ_KERNEL_MEMORY;
+ com_data.data_from = reinterpret_cast(addr);
+ com_data.data_to = buffer;
+ com_data.size = size;
+ syscall(&com_data);
+ return true;
+ }
+
+ bool wkm(std::uintptr_t addr, void* buffer, std::size_t size)
+ {
+ if (!addr || !buffer || !size)
+ return false;
+
+ com_struct com_data;
+ com_data.type = WRITE_KERNEL_MEMORY;
+ com_data.data_from = buffer;
+ com_data.data_to = reinterpret_cast(addr);
+ com_data.size = size;
+ syscall(&com_data);
+ return true;
+ }
+
+ unsigned get_pid(const char* proc_name)
+ {
+ PROCESSENTRY32 proc_info;
+ proc_info.dwSize = sizeof(proc_info);
+
+ const auto proc_snapshot =
+ CreateToolhelp32Snapshot(
+ TH32CS_SNAPPROCESS,
+ NULL
+ );
+
+ if (proc_snapshot == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ Process32First(proc_snapshot, &proc_info);
+ if (!strcmp(proc_info.szExeFile, proc_name))
+ {
+ CloseHandle(proc_snapshot);
+ return proc_info.th32ProcessID;
+ }
+
+ while (Process32Next(proc_snapshot, &proc_info))
+ {
+ if (!strcmp(proc_info.szExeFile, proc_name))
+ {
+ CloseHandle(proc_snapshot);
+ return proc_info.th32ProcessID;
+ }
+ }
+
+ CloseHandle(proc_snapshot);
+ return {};
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/luna-1.hpp b/luna-1 (AMD)/luna-1/luna-1.hpp
new file mode 100644
index 0000000..7d0b3c5
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/luna-1.hpp
@@ -0,0 +1,66 @@
+#pragma once
+#include
+#include
+
+namespace i6
+{
+ //
+ // please call this before making any other calls!
+ //
+ bool begin();
+
+ //
+ // get process id of process.
+ //
+ unsigned get_pid(const char* proc_name);
+
+ //
+ // get process base address.
+ //
+ std::uintptr_t get_process_base(unsigned pid);
+
+ //
+ // get module base
+ //
+ std::uintptr_t get_module_base(unsigned pid, const wchar_t* module_name);
+
+ //
+ // read/write to specific process
+ //
+ bool read(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size);
+ bool write(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size);
+
+ //
+ // read/write kernel memory (you can write to readonly with this)
+ //
+ bool rkm(std::uintptr_t addr, void* buffer, std::size_t size);
+ bool wkm(std::uintptr_t addr, void* buffer, std::size_t size);
+
+ template
+ T rkm(std::uintptr_t addr)
+ {
+ T buffer{};
+ rkm(addr, (void*)&buffer, sizeof(T));
+ return buffer;
+ }
+
+ template
+ bool wkm(std::uintptr_t addr, const T& data)
+ {
+ return wkm(addr, (void*)&data, sizeof(T));
+ }
+
+ template
+ T read(unsigned pid, std::uintptr_t addr)
+ {
+ T buffer{};
+ read(pid, addr, (void*)&buffer, sizeof(T));
+ return buffer;
+ }
+
+ template
+ bool write(unsigned pid, std::uintptr_t addr, const T& data)
+ {
+ return write(pid, addr, (void*)&data, sizeof(T));
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/luna-1.vcxproj b/luna-1 (AMD)/luna-1/luna-1.vcxproj
new file mode 100644
index 0000000..dbe586b
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/luna-1.vcxproj
@@ -0,0 +1,202 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {334edbd9-6a7c-4f6a-8eec-022f8c2c04c3}
+ luna1
+ 10.0
+
+
+
+ StaticLibrary
+ true
+ v142
+ MultiByte
+
+
+ StaticLibrary
+ false
+ v142
+ true
+ MultiByte
+
+
+ StaticLibrary
+ true
+ v142
+ MultiByte
+ false
+
+
+ StaticLibrary
+ false
+ v142
+ true
+ MultiByte
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+ MultiThreaded
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+ false
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+ MultiThreaded
+
+
+ Console
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+ Level3
+ true
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+ Disabled
+ false
+ MultiThreadedDLL
+
+
+ Console
+ true
+ true
+ true
+ mapper.lib;%(AdditionalDependencies)
+
+
+ %(AdditionalDependencies)
+ false
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/luna-1.vcxproj.filters b/luna-1 (AMD)/luna-1/luna-1.vcxproj.filters
new file mode 100644
index 0000000..d3252a2
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/luna-1.vcxproj.filters
@@ -0,0 +1,109 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {dd3f6067-3dff-478f-9d68-b96fc0e5456c}
+
+
+ {9d152069-464d-4ad4-ae2e-df0337a07cbb}
+
+
+ {4177fe47-d484-4b01-99ae-696601214b53}
+
+
+ {6eccd581-20cb-465a-9a1c-d9c8eb3fc399}
+
+
+ {c6462452-fbac-45ba-a0c8-597a3dfa2935}
+
+
+ {dabb66f8-2a8f-482d-a8e1-a309bbdc6421}
+
+
+ {2620ff7a-5d75-49c6-b340-6e0855fb9192}
+
+
+ {25436615-f282-4963-8800-e3bd482e6fb2}
+
+
+ {9313adec-bfa8-4399-82f6-22840f247382}
+
+
+ {db98d7be-fa02-45f7-9d32-2f2e79f72de7}
+
+
+
+
+ Source Files\kernel_ctx
+
+
+ Source Files\mem_ctx
+
+
+ Source Files\patch_ctx
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files\drv_image
+
+
+
+
+ Header Files
+
+
+ Header Files\kernel_ctx
+
+
+ Header Files\mem_ctx
+
+
+ Header Files\patch_ctx
+
+
+ Header Files
+
+
+ Header Files\physmeme
+
+
+ Header Files\util
+
+
+ Header Files\util
+
+
+ Header Files\util
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files\drv_image
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/luna-1.vcxproj.user b/luna-1 (AMD)/luna-1/luna-1.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/luna-1.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/map_driver.cpp b/luna-1 (AMD)/luna-1/map_driver.cpp
new file mode 100644
index 0000000..95790a9
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/map_driver.cpp
@@ -0,0 +1,78 @@
+#include
+#include
+#include
+
+#include "kernel_ctx/kernel_ctx.h"
+#include "drv_image/drv_image.h"
+
+namespace nasa
+{
+ bool __cdecl map_driver(std::vector& raw_driver, void** hook_handler)
+ {
+ nasa::drv_image image(raw_driver);
+ nasa::kernel_ctx ctx;
+
+ //
+ // lambdas used for fixing driver image
+ //
+ const auto _get_module = [&](std::string_view name)
+ {
+ return util::get_module_base(name.data());
+ };
+
+ const auto _get_export_name = [&](const char* base, const char* name)
+ {
+ return reinterpret_cast(util::get_module_export(base, name));
+ };
+
+ //
+ // fix the driver image
+ //
+ image.fix_imports(_get_module, _get_export_name);
+ image.map();
+
+ //
+ // allocate memory in the kernel for the driver
+ //
+ const auto pool_base =
+ ctx.allocate_pool(
+ image.size(),
+ NonPagedPool
+ );
+
+ if (!pool_base)
+ return -1;
+
+ image.relocate(pool_base);
+
+ //
+ // copy driver into the kernel
+ //
+ ctx.wkm(image.data(), pool_base, image.size());
+
+ //
+ // driver entry
+ //
+ auto entry_point = reinterpret_cast(pool_base) + image.entry_point();
+
+ //
+ // call driver entry
+ //
+ auto result = ctx.syscall(
+ reinterpret_cast(entry_point),
+ hook_handler
+ );
+
+ //
+ // zero driver headers
+ //
+ ctx.zero_kernel_memory(pool_base, image.header_size());
+ return !result; // 0x0 means STATUS_SUCCESS
+ }
+
+ bool __cdecl map_driver(std::uint8_t *image, std::size_t size, void** hook_handler)
+ {
+ auto data = std::vector(image, image + size);
+ return map_driver(data, hook_handler);
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/map_driver.hpp b/luna-1 (AMD)/luna-1/map_driver.hpp
new file mode 100644
index 0000000..bdf3087
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/map_driver.hpp
@@ -0,0 +1,8 @@
+#pragma once
+#include
+
+namespace nasa
+{
+ bool __cdecl map_driver(std::vector& raw_driver, void** hook_handler);
+ bool __cdecl map_driver(std::uint8_t* image, std::size_t size, void** hook_handler);
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/mem_ctx/mem_ctx.cpp b/luna-1 (AMD)/luna-1/mem_ctx/mem_ctx.cpp
new file mode 100644
index 0000000..5eb7c8d
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/mem_ctx/mem_ctx.cpp
@@ -0,0 +1,466 @@
+#include "mem_ctx.hpp"
+#include
+
+namespace nasa
+{
+ mem_ctx::mem_ctx(kernel_ctx& krnl_ctx, DWORD pid)
+ :
+ k_ctx(&krnl_ctx),
+ dirbase(get_dirbase(krnl_ctx, pid)),
+ pid(pid)
+ {
+ genesis_page.first = VirtualAlloc(
+ NULL,
+ PAGE_SIZE,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE
+ );
+
+ //
+ // page in the page, do not remove this makes the entries.
+ //
+ *(std::uintptr_t*)genesis_page.first = 0xC0FFEE;
+
+ //
+ // flush tlb since we just accessed the page
+ //
+ page_accessed();
+
+ //
+ // get the ppte and pte of the page we allocated
+ //
+ auto [page_ppte, page_pte] = get_pte(genesis_page.first, true);
+ genesis_page.second = page_pte;
+
+ //
+ // allocate a page that will get the mapping of the first pages PT
+ //
+ genesis_cursor.first = reinterpret_cast<::ppte>(
+ VirtualAlloc(
+ NULL,
+ 0x1000,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE
+ ));
+
+ //
+ // page it in
+ //
+ *(std::uintptr_t*)genesis_cursor.first = 0xC0FFEE;
+
+ //
+ // flush tlb since we just accessed the page
+ //
+ page_accessed();
+
+ //
+ // get ppte and pte of the cursor page.
+ //
+ auto [cursor_ppte, cursor_pte] = get_pte(genesis_cursor.first, true);
+ genesis_cursor.second = cursor_pte;
+
+ //
+ // change the page to the PT of the first page we allocated.
+ //
+ cursor_pte.pfn = reinterpret_cast(page_ppte) >> 12;
+ set_pte(genesis_cursor.first, cursor_pte, true);
+
+ //
+ // change the offset of genesis cursor page to genesis pages pt_index since the page is now a PT
+ // WARNING: pointer arithmetic, do not add pt_index * 8
+ //
+ genesis_cursor.first += +virt_addr_t{ genesis_page.first }.pt_index;
+
+ //
+ // since the page has been accessed we need to reset this bit in the PTE.
+ //
+ page_accessed();
+ }
+
+ mem_ctx::~mem_ctx()
+ {
+ set_pte(genesis_page.first, genesis_page.second, true);
+ set_pte(genesis_cursor.first, genesis_cursor.second, true);
+ }
+
+ void* mem_ctx::set_page(void* addr)
+ {
+ page_offset = virt_addr_t{ addr }.offset;
+ genesis_cursor.first->pfn = reinterpret_cast(addr) >> 12;
+ page_accessed();
+ return get_page();
+ }
+
+ void* mem_ctx::get_page() const
+ {
+ return reinterpret_cast((reinterpret_cast(genesis_page.first)) + page_offset);
+ }
+
+ void mem_ctx::page_accessed() const
+ {
+ Sleep(5);
+ }
+
+ void* mem_ctx::get_dirbase(kernel_ctx& k_ctx, DWORD pid)
+ {
+ if (!pid)
+ return NULL;
+
+ const auto peproc =
+ reinterpret_cast(k_ctx.get_peprocess(pid));
+
+ if (!peproc)
+ return NULL;
+
+ pte dirbase = k_ctx.rkm(
+ reinterpret_cast(peproc + 0x28)
+ );
+
+ return reinterpret_cast(dirbase.pfn << 12);
+ }
+
+ void mem_ctx::set_dirbase(void* dirbase)
+ {
+ this->dirbase = dirbase;
+ }
+
+ bool mem_ctx::hyperspace_entries(pt_entries& entries, void* addr)
+ {
+ if (!addr || !dirbase)
+ return false;
+
+ virt_addr_t virt_addr{ addr };
+ entries.pml4.first = reinterpret_cast(dirbase) + virt_addr.pml4_index;
+ entries.pml4.second = k_ctx->rkm(
+ k_ctx->get_virtual(entries.pml4.first));
+
+ if (!entries.pml4.second.value)
+ return false;
+
+ entries.pdpt.first = reinterpret_cast(entries.pml4.second.pfn << 12) + virt_addr.pdpt_index;
+ entries.pdpt.second = k_ctx->rkm(
+ k_ctx->get_virtual(entries.pdpt.first));
+
+ if (!entries.pdpt.second.value)
+ return false;
+
+ entries.pd.first = reinterpret_cast(entries.pdpt.second.pfn << 12) + virt_addr.pd_index;
+ entries.pd.second = k_ctx->rkm(
+ k_ctx->get_virtual(entries.pd.first));
+
+ // if its a 2mb page
+ if (entries.pd.second.page_size)
+ {
+ memcpy(
+ &entries.pt.second,
+ &entries.pd.second,
+ sizeof(pte)
+ );
+
+ entries.pt.first = reinterpret_cast(entries.pd.second.value);
+ return true;
+ }
+
+ entries.pt.first = reinterpret_cast(entries.pd.second.pfn << 12) + virt_addr.pt_index;
+ entries.pt.second = k_ctx->rkm(
+ k_ctx->get_virtual(entries.pt.first));
+
+ if (!entries.pt.second.value)
+ return false;
+
+ return true;
+ }
+
+ std::pair mem_ctx::get_pte(void* addr, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return {};
+
+ pt_entries entries;
+ if (use_hyperspace ? hyperspace_entries(entries, addr) : virt_to_phys(entries, addr))
+ {
+ ::pte pte;
+ memcpy(&pte, &entries.pt.second, sizeof(pte));
+ return { entries.pt.first, pte };
+ }
+ return {};
+ }
+
+ void mem_ctx::set_pte(void* addr, const ::pte& pte, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return;
+
+ pt_entries entries;
+ if (use_hyperspace)
+ if (hyperspace_entries(entries, addr))
+ k_ctx->wkm(
+ k_ctx->get_virtual(entries.pt.first),
+ pte
+ );
+ else
+ if (virt_to_phys(entries, addr))
+ write_phys(entries.pt.first, pte);
+ }
+
+ std::pair mem_ctx::get_pde(void* addr, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return {};
+
+ pt_entries entries;
+ if (use_hyperspace ? hyperspace_entries(entries, addr) : virt_to_phys(entries, addr))
+ {
+ ::pde pde;
+ memcpy(
+ &pde,
+ &entries.pd.second,
+ sizeof(pde)
+ );
+ return { entries.pd.first, pde };
+ }
+ return {};
+ }
+
+ void mem_ctx::set_pde(void* addr, const ::pde& pde, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return;
+
+ pt_entries entries;
+ if (use_hyperspace)
+ if (hyperspace_entries(entries, addr))
+ k_ctx->wkm(
+ k_ctx->get_virtual(entries.pd.first),
+ pde
+ );
+ else
+ if (virt_to_phys(entries, addr))
+ write_phys(entries.pd.first, pde);
+ }
+
+ std::pair mem_ctx::get_pdpte(void* addr, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return {};
+
+ pt_entries entries;
+ if (use_hyperspace ? hyperspace_entries(entries, addr) : virt_to_phys(entries, addr))
+ {
+ ::pdpte pdpte;
+ memcpy(
+ &pdpte,
+ &entries.pdpt.second,
+ sizeof(pdpte)
+ );
+ return { entries.pdpt.first, pdpte };
+ }
+ return {};
+ }
+
+ void mem_ctx::set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return;
+
+ pt_entries entries;
+ if (use_hyperspace)
+ if (hyperspace_entries(entries, addr))
+ k_ctx->wkm(
+ k_ctx->get_virtual(entries.pdpt.first),
+ pdpte
+ );
+ else
+ if (virt_to_phys(entries, addr))
+ write_phys(entries.pdpt.first, pdpte);
+ }
+
+ std::pair mem_ctx::get_pml4e(void* addr, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return {};
+
+ pt_entries entries;
+ if (use_hyperspace ? hyperspace_entries(entries, addr) : virt_to_phys(entries, addr))
+ {
+ ::pml4e pml4e;
+ memcpy(
+ &pml4e,
+ &entries.pml4.second,
+ sizeof(pml4e)
+ );
+ return { entries.pml4.first, pml4e };
+ }
+ return {};
+ }
+
+ void mem_ctx::set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace)
+ {
+ if (!dirbase || !addr)
+ return;
+
+ pt_entries entries;
+ if (use_hyperspace)
+ if (hyperspace_entries(entries, addr))
+ k_ctx->wkm(
+ k_ctx->get_virtual(entries.pml4.first),
+ pml4e
+ );
+ else
+ if (virt_to_phys(entries, addr))
+ write_phys(entries.pml4.first, pml4e);
+ }
+
+ std::pair mem_ctx::read_virtual(void* buffer, void* addr, std::size_t size)
+ {
+ if (!buffer || !addr || !size || !dirbase)
+ return {};
+
+ virt_addr_t virt_addr{ addr };
+ if (size <= PAGE_SIZE - virt_addr.offset)
+ {
+ pt_entries entries;
+ read_phys(
+ buffer,
+ virt_to_phys(entries, addr),
+ size
+ );
+ return {
+ reinterpret_cast(reinterpret_cast(buffer) + size),
+ reinterpret_cast(reinterpret_cast(addr) + size)
+ };
+ }
+ else
+ {
+ // cut remainder
+ const auto [new_buffer_addr, new_addr] = read_virtual(
+ buffer,
+ addr,
+ PAGE_SIZE - virt_addr.offset
+ );
+ // forward work load
+ return read_virtual(
+ new_buffer_addr,
+ new_addr,
+ size - (PAGE_SIZE - virt_addr.offset)
+ );
+ }
+ }
+
+ std::pair mem_ctx::write_virtual(void* buffer, void* addr, std::size_t size)
+ {
+ if (!buffer || !addr || !size || !dirbase)
+ return {};
+
+ virt_addr_t virt_addr{ addr };
+ if (size <= PAGE_SIZE - virt_addr.offset)
+ {
+ pt_entries entries;
+ write_phys(
+ buffer,
+ virt_to_phys(entries, addr),
+ size
+ );
+
+ return {
+ reinterpret_cast(reinterpret_cast(buffer) + size),
+ reinterpret_cast(reinterpret_cast(addr) + size)
+ };
+ }
+ else
+ {
+ // cut remainder
+ const auto [new_buffer_addr, new_addr] = write_virtual(
+ buffer,
+ addr,
+ PAGE_SIZE - virt_addr.offset
+ );
+
+ // forward work load
+ return write_virtual(
+ new_buffer_addr,
+ new_addr,
+ size - (PAGE_SIZE - virt_addr.offset)
+ );
+ }
+ }
+
+ void mem_ctx::read_phys(void* buffer, void* addr, std::size_t size)
+ {
+ if (!buffer || !addr || !size)
+ return;
+
+ auto temp_page = set_page(addr);
+ if (temp_page)
+ memcpy(buffer, temp_page, size);
+ }
+
+ void mem_ctx::write_phys(void* buffer, void* addr, std::size_t size)
+ {
+ if (!buffer || !addr || !size)
+ return;
+
+ auto temp_page = set_page(addr);
+ if (temp_page)
+ memcpy(temp_page, buffer, size);
+ }
+
+ void* mem_ctx::virt_to_phys(pt_entries& entries, void* addr)
+ {
+ if (!addr || !dirbase)
+ return {};
+
+ virt_addr_t virt_addr{ addr };
+
+ //
+ // traverse paging tables
+ //
+ auto pml4e = read_phys<::pml4e>(
+ reinterpret_cast(dirbase) + virt_addr.pml4_index);
+
+ entries.pml4.first = reinterpret_cast(dirbase) + virt_addr.pml4_index;
+ entries.pml4.second = pml4e;
+
+ if (!pml4e.value)
+ return NULL;
+
+ auto pdpte = read_phys<::pdpte>(
+ reinterpret_cast(pml4e.pfn << 12) + virt_addr.pdpt_index);
+
+ entries.pdpt.first = reinterpret_cast(pml4e.pfn << 12) + virt_addr.pdpt_index;
+ entries.pdpt.second = pdpte;
+
+ if (!pdpte.value)
+ return NULL;
+
+ auto pde = read_phys<::pde>(
+ reinterpret_cast(pdpte.pfn << 12) + virt_addr.pd_index);
+
+ entries.pd.first = reinterpret_cast(pdpte.pfn << 12) + virt_addr.pd_index;
+ entries.pd.second = pde;
+
+ if (!pde.value)
+ return NULL;
+
+ auto pte = read_phys<::pte>(
+ reinterpret_cast(pde.pfn << 12) + virt_addr.pt_index);
+
+ entries.pt.first = reinterpret_cast(pde.pfn << 12) + virt_addr.pt_index;
+ entries.pt.second = pte;
+
+ if (!pte.value)
+ return NULL;
+
+ return reinterpret_cast((pte.pfn << 12) + virt_addr.offset);
+ }
+
+ unsigned mem_ctx::get_pid() const
+ {
+ return pid;
+ }
+
+ void* mem_ctx::get_dirbase() const
+ {
+ return dirbase;
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/mem_ctx/mem_ctx.hpp b/luna-1 (AMD)/luna-1/mem_ctx/mem_ctx.hpp
new file mode 100644
index 0000000..7ef2ec4
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/mem_ctx/mem_ctx.hpp
@@ -0,0 +1,133 @@
+#pragma once
+#include "../util/nt.hpp"
+#include "../kernel_ctx/kernel_ctx.h"
+
+#define FLUSH_TLB Sleep(10)
+
+struct pt_entries
+{
+ std::pair pml4;
+ std::pair pdpt;
+ std::pair pd;
+ std::pair pt;
+};
+
+namespace nasa
+{
+ class mem_ctx
+ {
+ public:
+ explicit mem_ctx(kernel_ctx& k_ctx, DWORD pid);
+ ~mem_ctx();
+
+ //
+ // PTE manipulation
+ //
+ std::pair get_pte(void* addr, bool use_hyperspace = false);
+ void set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false);
+
+ //
+ // PDE manipulation
+ //
+ std::pair get_pde(void* addr, bool use_hyperspace = false);
+ void set_pde(void* addr, const ::pde& pde, bool use_hyperspace = false);
+
+ //
+ // PDPTE manipulation
+ //
+ std::pair get_pdpte(void* addr, bool use_hyperspace = false);
+ void set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace = false);
+
+ //
+ // PML4E manipulation
+ //
+ std::pair get_pml4e(void* addr, bool use_hyperspace = false);
+ void set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace = false);
+
+ //
+ // gets dirbase (not the PTE or PFN but actual physical address)
+ //
+ void* get_dirbase() const;
+ static void* get_dirbase(kernel_ctx& k_ctx, DWORD pid);
+
+ void read_phys(void* buffer, void* addr, std::size_t size);
+ void write_phys(void* buffer, void* addr, std::size_t size);
+
+ template
+ T read_phys(void* addr)
+ {
+ if (!addr)
+ return {};
+ T buffer;
+ read_phys((void*)&buffer, addr, sizeof(T));
+ return buffer;
+ }
+
+ template
+ void write_phys(void* addr, const T& data)
+ {
+ if (!addr)
+ return;
+ write_phys((void*)&data, addr, sizeof(T));
+ }
+
+ std::pair read_virtual(void* buffer, void* addr, std::size_t size);
+ std::pair write_virtual(void* buffer, void* addr, std::size_t size);
+
+ template
+ T read_virtual(void* addr)
+ {
+ if (!addr)
+ return {};
+ T buffer;
+ read_virtual((void*)&buffer, addr, sizeof(T));
+ return buffer;
+ }
+
+ template
+ void write_virtual(void* addr, const T& data)
+ {
+ write_virtual((void*)&data, addr, sizeof(T));
+ }
+
+ //
+ // linear address translation (not done by hyperspace mappings)
+ //
+ void* virt_to_phys(pt_entries& entries, void* addr);
+
+ //
+ // given an address fill pt entries with physical addresses and entry values.
+ //
+ bool hyperspace_entries(pt_entries& entries, void* addr);
+
+ //
+ // these are used for the pfn backdoor, this will be removed soon
+ //
+ void* set_page(void* addr);
+
+ //
+ // get current page mem_ctx is set to.
+ //
+ void* get_page() const;
+
+ //
+ // invalidate TLB
+ //
+ void page_accessed() const;
+ unsigned get_pid() const;
+
+ //
+ // set dirbase.
+ //
+ void set_dirbase(void* dirbase);
+
+ kernel_ctx* k_ctx;
+ private:
+ std::pair genesis_page;
+ std::pair genesis_cursor;
+ void* dirbase;
+
+ unsigned pid;
+ unsigned short page_offset;
+ };
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/patch_ctx/patch_ctx.cpp b/luna-1 (AMD)/luna-1/patch_ctx/patch_ctx.cpp
new file mode 100644
index 0000000..f6b46ab
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/patch_ctx/patch_ctx.cpp
@@ -0,0 +1,249 @@
+#include "patch_ctx.hpp"
+
+namespace nasa
+{
+ patch_ctx::patch_ctx(nasa::mem_ctx* mem_ctx)
+ :
+ mem_ctx(mem_ctx)
+ {}
+
+ void* patch_ctx::patch(void* kernel_addr)
+ {
+ if (!kernel_addr)
+ return {};
+
+ virt_addr_t kernel_addr_t{ kernel_addr };
+ pt_entries kernel_entries;
+ if (!mem_ctx->hyperspace_entries(kernel_entries, kernel_addr))
+ return {};
+
+ const auto [new_pdpt_phys, new_pdpt_virt] = make_pdpt(kernel_entries, kernel_addr);
+ const auto [new_pd_phys, new_pd_virt] = make_pd(kernel_entries, kernel_addr);
+ const auto [new_pt_phys, new_pt_virt] = make_pt(kernel_entries, kernel_addr);
+ const auto [new_page_phys, new_page_virt] = make_page(kernel_entries, kernel_addr);
+
+ // link pdpte to pd
+ (reinterpret_cast(new_pdpt_virt) + kernel_addr_t.pdpt_index)->pfn = reinterpret_cast(new_pd_phys) >> 12;
+ if (kernel_entries.pd.second.page_size)
+ // link pde to new page if its 2mb
+ (reinterpret_cast(new_pd_virt) + kernel_addr_t.pd_index)->pfn = reinterpret_cast(new_page_phys) >> 12;
+ else
+ {
+ // link pde to pt
+ (reinterpret_cast(new_pd_virt) + kernel_addr_t.pd_index)->pfn = reinterpret_cast(new_pt_phys) >> 12;
+ // link pte to page (1kb)
+ (reinterpret_cast(new_pt_virt) + kernel_addr_t.pt_index)->pfn = reinterpret_cast(new_page_phys) >> 12;
+ }
+
+ mapped_pml4e =
+ reinterpret_cast(
+ mem_ctx->set_page(
+ kernel_entries.pml4.first));
+
+ new_pml4e = kernel_entries.pml4.second;
+ new_pml4e.pfn = reinterpret_cast(new_pdpt_phys) >> 12;
+ old_pml4e = kernel_entries.pml4.second;
+ return reinterpret_cast((std::uintptr_t)new_page_virt + kernel_addr_t.offset);
+ }
+
+ std::pair patch_ctx::make_pdpt(const pt_entries& kernel_entries, void* kernel_addr)
+ {
+ if (!kernel_addr)
+ return {};
+
+ virt_addr_t kernel_addr_t{ kernel_addr };
+ const auto pdpt = reinterpret_cast(
+ mem_ctx->set_page(reinterpret_cast(
+ kernel_entries.pml4.second.pfn << 12)));
+
+ const auto new_pdpt =
+ reinterpret_cast(VirtualAlloc(
+ NULL,
+ 0x1000,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE
+ ));
+
+ //
+ // zero pdpt and lock it.
+ //
+ memset(new_pdpt, NULL, 0x1000);
+ if (!VirtualLock(new_pdpt, 0x1000))
+ return {};
+
+
+ //
+ // copy over pdpte's
+ //
+ for (auto idx = 0u; idx < 512; ++idx)
+ *(pdpte*)(new_pdpt + idx) = *(pdpte*)(pdpt + idx);
+
+ //
+ // get physical address of new pdpt
+ //
+ pt_entries new_pdpt_entries;
+ const auto physical_addr =
+ mem_ctx->virt_to_phys(
+ new_pdpt_entries,
+ new_pdpt
+ );
+
+ return { physical_addr, new_pdpt };
+ }
+
+ std::pair patch_ctx::make_pd(const pt_entries& kernel_entries, void* kernel_addr)
+ {
+ if (!kernel_addr)
+ return {};
+
+ virt_addr_t kernel_addr_t{ kernel_addr };
+ const auto new_pd = reinterpret_cast(
+ VirtualAlloc(
+ NULL,
+ 0x1000,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE
+ ));
+
+ //
+ // zero page and lock it.
+ //
+ memset(new_pd, NULL, 0x1000);
+ if (!VirtualLock(new_pd, 0x1000))
+ return {};
+
+ const auto pd = reinterpret_cast(
+ mem_ctx->set_page(
+ reinterpret_cast(
+ kernel_entries.pdpt.second.pfn << 12)));
+
+ //
+ // copy over pde's
+ //
+ for (auto idx = 0u; idx < 512; ++idx)
+ *(::pde*)(new_pd + idx) = *(::pde*)(pd + idx);
+
+ //
+ // get physical address of new pd
+ //
+ pt_entries pd_entries;
+ const auto physical_addr =
+ mem_ctx->virt_to_phys(
+ pd_entries,
+ new_pd
+ );
+
+ return { physical_addr, new_pd };
+ }
+
+ std::pair patch_ctx::make_pt(const pt_entries& kernel_entries, void* kernel_addr)
+ {
+ if (!kernel_addr || kernel_entries.pd.second.page_size) // if this address is a 2mb mapping.
+ return {};
+
+ virt_addr_t kernel_addr_t{ kernel_addr };
+ const auto new_pt = reinterpret_cast(
+ VirtualAlloc(
+ NULL,
+ 0x1000,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE
+ ));
+
+ //
+ // zero pt and lock it.
+ //
+ memset(new_pt, NULL, 0x1000);
+ if (!VirtualLock(new_pt, 0x1000))
+ return {};
+
+ const auto pt = reinterpret_cast(
+ mem_ctx->set_page(
+ reinterpret_cast(
+ kernel_entries.pd.second.pfn << 12)));
+
+ //
+ // copy over pte's
+ //
+ for (auto idx = 0u; idx < 512; ++idx)
+ *(::pde*)(new_pt + idx) = *(::pde*)(pt + idx);
+
+ //
+ // get physical address of new pt
+ //
+ pt_entries entries;
+ const auto physical_addr =
+ mem_ctx->virt_to_phys(
+ entries,
+ new_pt
+ );
+
+ return { physical_addr, new_pt };
+ }
+
+ std::pair patch_ctx::make_page(const pt_entries& kernel_entries, void* kernel_addr)
+ {
+ if (!kernel_addr)
+ return {};
+
+ virt_addr_t kernel_addr_t{ kernel_addr };
+
+ //
+ // if its a 2mb page
+ //
+ if (kernel_entries.pd.second.page_size)
+ {
+ const auto new_page = VirtualAlloc(
+ NULL,
+ 0x1000 * 512 * 2, // 4mb
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE
+ );
+ memset(new_page, NULL, 512 * 0x1000); // zero 2mb
+
+ //
+ // copy 2mb one page at a time.
+ //
+ for (auto idx = 0u; idx < 512; ++idx)
+ {
+ const auto old_page = mem_ctx->set_page(reinterpret_cast((kernel_entries.pt.second.pfn << 12) + (idx * 0x1000)));
+ memcpy((void*)((std::uintptr_t)new_page + (idx * 0x1000)), old_page, 0x1000);
+ }
+
+ pt_entries new_page_entries;
+ const auto new_page_phys = mem_ctx->virt_to_phys(new_page_entries, new_page);
+ return { new_page_phys, new_page };
+ }
+ else // 1kb
+ {
+ const auto new_page = VirtualAlloc(
+ NULL,
+ 0x1000,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_READWRITE
+ );
+
+ //
+ // zero and lock new page.
+ //
+ memset(new_page, NULL, 0x1000);
+ if (!VirtualLock(new_page, 0x1000))
+ return {};
+
+ const auto old_page =
+ mem_ctx->set_page(
+ reinterpret_cast(
+ kernel_entries.pt.second.pfn << 12));
+ memcpy(new_page, old_page, 0x1000);
+
+ pt_entries new_page_entries;
+ const auto new_page_phys =
+ mem_ctx->virt_to_phys(
+ new_page_entries,
+ new_page
+ );
+
+ return { new_page_phys, new_page };
+ }
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/patch_ctx/patch_ctx.hpp b/luna-1 (AMD)/luna-1/patch_ctx/patch_ctx.hpp
new file mode 100644
index 0000000..0657484
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/patch_ctx/patch_ctx.hpp
@@ -0,0 +1,61 @@
+#pragma once
+#include "../mem_ctx/mem_ctx.hpp"
+
+namespace nasa
+{
+ class patch_ctx
+ {
+ public:
+ explicit patch_ctx(mem_ctx* mem_ctx);
+
+ //
+ // returns a virtual address mapping of the newly patched page(s).
+ //
+ void* patch(void* kernel_addr);
+ __forceinline void enable()
+ {
+ mapped_pml4e->pfn = new_pml4e.pfn;
+ }
+
+ __forceinline void disable()
+ {
+ mapped_pml4e->pfn = old_pml4e.pfn;
+ }
+ private:
+
+ //
+ // std::pair< physical page, virtual address >
+ //
+ std::pair make_pdpt(const pt_entries& kernel_entries, void* kernel_addr);
+ std::pair make_pd(const pt_entries& kernel_entries, void* kernel_addr);
+ std::pair make_pt(const pt_entries& kernel_entries, void* kernel_addr);
+ std::pair make_page(const pt_entries& kernel_entries, void* kernel_addr);
+
+ //
+ // context of the current process you want to patch.
+ //
+ mem_ctx* mem_ctx;
+
+ //
+ // newly created table entries and table pointers (pdpte, pde, pte)
+ //
+ pt_entries new_entries;
+
+ //
+ // old and new pml4e
+ //
+ pml4e new_pml4e;
+ pml4e old_pml4e;
+
+ //
+ // kernel address of the patch.
+ //
+ void* kernel_addr;
+
+ //
+ // pointer to the mapped pml4e
+ // used for enable/disable patch...
+ //
+ ppml4e mapped_pml4e;
+ };
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/pe_image/pe_image.cpp b/luna-1 (AMD)/luna-1/pe_image/pe_image.cpp
new file mode 100644
index 0000000..8c39064
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/pe_image/pe_image.cpp
@@ -0,0 +1,196 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to
+
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!! This code was created by not-wlan (wlan). all credit for this header and source file goes to him !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+*/
+
+#include "pe_image.h"
+
+namespace nasa
+{
+ pe_image::pe_image(std::vector& image) : m_image(image)
+ {
+ m_dos_header = reinterpret_cast(m_image.data());
+ m_nt_headers = reinterpret_cast((uintptr_t)m_dos_header + m_dos_header->e_lfanew);
+ m_section_header = reinterpret_cast((uintptr_t)(&m_nt_headers->OptionalHeader) + m_nt_headers->FileHeader.SizeOfOptionalHeader);
+ }
+
+ size_t pe_image::size() const
+ {
+ return m_nt_headers->OptionalHeader.SizeOfImage;
+ }
+
+ uintptr_t pe_image::entry_point() const
+ {
+ return m_nt_headers->OptionalHeader.AddressOfEntryPoint;
+ }
+
+ void pe_image::map()
+ {
+ m_image_mapped.clear();
+ m_image_mapped.resize(m_nt_headers->OptionalHeader.SizeOfImage);
+ std::copy_n(m_image.begin(), m_nt_headers->OptionalHeader.SizeOfHeaders, m_image_mapped.begin());
+
+ for (size_t i = 0; i < m_nt_headers->FileHeader.NumberOfSections; ++i)
+ {
+ const auto& section = m_section_header[i];
+ const auto target = (uintptr_t)m_image_mapped.data() + section.VirtualAddress;
+ const auto source = (uintptr_t)m_dos_header + section.PointerToRawData;
+ std::copy_n(m_image.begin() + section.PointerToRawData, section.SizeOfRawData, m_image_mapped.begin() + section.VirtualAddress);
+ }
+ }
+
+ bool pe_image::process_relocation(uintptr_t image_base_delta, uint16_t data, uint8_t* relocation_base)
+ {
+#define IMR_RELOFFSET(x) (x & 0xFFF)
+
+ switch (data >> 12 & 0xF)
+ {
+ case IMAGE_REL_BASED_HIGH:
+ {
+ const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += static_cast(HIWORD(image_base_delta));
+ break;
+ }
+ case IMAGE_REL_BASED_LOW:
+ {
+ const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += static_cast(LOWORD(image_base_delta));
+ break;
+ }
+ case IMAGE_REL_BASED_HIGHLOW:
+ {
+ const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += static_cast(image_base_delta);
+ break;
+ }
+ case IMAGE_REL_BASED_DIR64:
+ {
+ auto UNALIGNED raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data));
+ *raw_address += image_base_delta;
+ break;
+ }
+ case IMAGE_REL_BASED_ABSOLUTE: // No action required
+ case IMAGE_REL_BASED_HIGHADJ: // no action required
+ {
+ break;
+ }
+ default:
+ {
+ return false;
+ }
+
+ }
+#undef IMR_RELOFFSET
+
+ return true;
+ }
+
+
+ void pe_image::relocate(uintptr_t base) const
+ {
+ if (m_nt_headers->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
+ return;
+
+ ULONG total_count_bytes;
+ const auto nt_headers = ImageNtHeader((void*)m_image_mapped.data());
+ auto relocation_directory = (PIMAGE_BASE_RELOCATION)::ImageDirectoryEntryToData(nt_headers, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &total_count_bytes);
+ auto image_base_delta = static_cast(static_cast(base) - (nt_headers->OptionalHeader.ImageBase));
+ auto relocation_size = total_count_bytes;
+
+ // This should check (DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) too but lots of drivers do not have it set due to WDK defaults
+ const bool doRelocations = image_base_delta != 0 && relocation_size > 0;
+
+ if (!doRelocations)
+ return;
+
+ void* relocation_end = reinterpret_cast(relocation_directory) + relocation_size;
+
+ while (relocation_directory < relocation_end)
+ {
+ auto relocation_base = ::ImageRvaToVa(nt_headers, (void*)m_image_mapped.data(), relocation_directory->VirtualAddress, nullptr);
+
+ auto num_relocs = (relocation_directory->SizeOfBlock - 8) >> 1;
+
+ auto relocation_data = reinterpret_cast(relocation_directory + 1);
+
+ for (unsigned long i = 0; i < num_relocs; ++i, ++relocation_data)
+ if (process_relocation(image_base_delta, *relocation_data, (uint8_t*)relocation_base) == FALSE)
+ return;
+
+ relocation_directory = reinterpret_cast(relocation_data);
+ }
+
+ }
+
+ template
+ __forceinline T* ptr_add(void* base, uintptr_t offset)
+ {
+ return (T*)(uintptr_t)base + offset;
+ }
+
+ void pe_image::fix_imports(const std::function get_module, const std::function get_function)
+ {
+ ULONG size;
+ auto import_descriptors = static_cast(::ImageDirectoryEntryToData(m_image.data(), FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size));
+
+ if (import_descriptors == nullptr)
+ return;
+
+ for (; import_descriptors->Name; import_descriptors++)
+ {
+ IMAGE_THUNK_DATA* image_thunk_data;
+
+ const auto module_name = get_rva(import_descriptors->Name);
+ const auto module_base = get_module(module_name);
+ if (import_descriptors->OriginalFirstThunk)
+ image_thunk_data = get_rva(import_descriptors->OriginalFirstThunk);
+ else
+ image_thunk_data = get_rva(import_descriptors->FirstThunk);
+ auto image_func_data = get_rva(import_descriptors->FirstThunk);
+ for (; image_thunk_data->u1.AddressOfData; image_thunk_data++, image_func_data++)
+ {
+ uintptr_t function_address;
+ const auto ordinal = (image_thunk_data->u1.Ordinal & IMAGE_ORDINAL_FLAG64) != 0;
+ const auto image_import_by_name = get_rva(*(DWORD*)image_thunk_data);
+ const auto name_of_import = static_cast(image_import_by_name->Name);
+ function_address = get_function(module_name, name_of_import);
+ image_func_data->u1.Function = function_address;
+ }
+ }
+ }
+
+ void* pe_image::data()
+ {
+ return m_image_mapped.data();
+ }
+
+ size_t pe_image::header_size()
+ {
+ return m_nt_headers->OptionalHeader.SizeOfHeaders;
+ }
+}
\ No newline at end of file
diff --git a/luna-1 (AMD)/luna-1/pe_image/pe_image.h b/luna-1 (AMD)/luna-1/pe_image/pe_image.h
new file mode 100644
index 0000000..e7acc9a
--- /dev/null
+++ b/luna-1 (AMD)/luna-1/pe_image/pe_image.h
@@ -0,0 +1,73 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to
+
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!! This code was created by not-wlan (wlan). all credit for this header and source file goes to him !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+*/
+
+
+#pragma once
+#include
+#define WIN32_NO_STATUS
+#include
+#include
+#undef WIN32_NO_STATUS
+#include
+
+#include