diff --git a/badeye/badeye.sln b/badeye/badeye.sln new file mode 100644 index 0000000..ef004d0 --- /dev/null +++ b/badeye/badeye.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30406.217 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "badeye", "badeye\badeye.vcxproj", "{FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inside", "inside\inside.vcxproj", "{F449B39D-4975-4478-B873-2747CC3DD7EF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Debug|x64.ActiveCfg = Debug|x64 + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Debug|x64.Build.0 = Debug|x64 + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Debug|x86.ActiveCfg = Debug|Win32 + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Debug|x86.Build.0 = Debug|Win32 + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Release|x64.ActiveCfg = Release|x64 + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Release|x64.Build.0 = Release|x64 + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Release|x86.ActiveCfg = Release|Win32 + {FAADD55D-E2C8-4E6D-BE7E-6D8B5209F4F0}.Release|x86.Build.0 = Release|Win32 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Debug|x64.ActiveCfg = Debug|x64 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Debug|x64.Build.0 = Debug|x64 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Debug|x86.ActiveCfg = Debug|Win32 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Debug|x86.Build.0 = Debug|Win32 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Release|x64.ActiveCfg = Release|x64 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Release|x64.Build.0 = Release|x64 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Release|x86.ActiveCfg = Release|Win32 + {F449B39D-4975-4478-B873-2747CC3DD7EF}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {140A6DB5-034F-43AF-9D44-4D6FEBDFADD1} + EndGlobalSection +EndGlobal diff --git a/badeye/badeye/badeye.vcxproj b/badeye/badeye/badeye.vcxproj new file mode 100644 index 0000000..1ef8ad8 --- /dev/null +++ b/badeye/badeye/badeye.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {faadd55d-e2c8-4e6d-be7e-6d8b5209f4f0} + badeye + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + + + Console + true + true + true + ntdll.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + \ No newline at end of file diff --git a/badeye/badeye/badeye.vcxproj.filters b/badeye/badeye/badeye.vcxproj.filters new file mode 100644 index 0000000..02a3f13 --- /dev/null +++ b/badeye/badeye/badeye.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/badeye/badeye/badeye.vcxproj.user b/badeye/badeye/badeye.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/badeye/badeye/badeye.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/badeye/badeye/main.cpp b/badeye/badeye/main.cpp new file mode 100644 index 0000000..bb83b4f --- /dev/null +++ b/badeye/badeye/main.cpp @@ -0,0 +1,20 @@ +#include "nozzle.hpp" + +int main(const int argc, const char** argv) +{ + if (argc < 2) + { + std::perror("[-] please provide a dll path..."); + return -1; + } + + const auto lsass_pid = util::get_process_id(L"lsass.exe"); + std::printf("[+] lsass_pid => %p\n", lsass_pid); + + nozzle::injector inject(argv[1], lsass_pid); + const auto module_base = inject.inject(); + inject.hook_entry(); + + std::printf("[+] module base => %p\n", module_base); + std::getchar(); +} \ No newline at end of file diff --git a/badeye/badeye/nozzle.hpp b/badeye/badeye/nozzle.hpp new file mode 100644 index 0000000..74facec --- /dev/null +++ b/badeye/badeye/nozzle.hpp @@ -0,0 +1,511 @@ +/* + 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 +#include +#include +#include +#include +#include + +#pragma comment(lib, "Dbghelp.lib") +#define FIND_NT_HEADER(x) reinterpret_cast( uint64_t(x) + reinterpret_cast(x)->e_lfanew ) +#define RET_CHK(x)\ +if (!x)\ +{\ +LOG_LAST_ERROR();\ +return false;\ +}\ + +// +// coded by paracord. +// see: https://github.com/haram/splendid_implanter/blob/master/splendid_implanter/win_utils.hpp +// +namespace util +{ + using uq_handle = std::unique_ptr; + inline void open_binary_file(const std::string& file, std::vector& data) + { + std::ifstream fstr(file, std::ios::binary); + fstr.unsetf(std::ios::skipws); + fstr.seekg(0, std::ios::end); + + const auto file_size = fstr.tellg(); + + fstr.seekg(NULL, std::ios::beg); + data.reserve(static_cast(file_size)); + data.insert(data.begin(), std::istream_iterator(fstr), std::istream_iterator()); + } + + inline uint32_t get_process_id(const std::wstring_view process_name) + { + // open a system snapshot of all loaded processes + uq_handle snap_shot{ CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0), &CloseHandle }; + + if (snap_shot.get() == INVALID_HANDLE_VALUE) + return NULL; + + PROCESSENTRY32W process_entry{ sizeof(PROCESSENTRY32W) }; + + // enumerate through processes + for (Process32FirstW(snap_shot.get(), &process_entry); Process32NextW(snap_shot.get(), &process_entry); ) + if (std::wcscmp(process_name.data(), process_entry.szExeFile) == NULL) + return process_entry.th32ProcessID; + + return NULL; + } + + inline std::pair get_module_data(HANDLE process_handle, const std::wstring_view module_name) + { + auto loaded_modules = std::make_unique(64); + DWORD loaded_module_sz = 0; + + // enumerate all modules by handle, using size of 512 since the required size is in bytes, and an HMODULE is 8 bytes large. + if (!EnumProcessModules(process_handle, loaded_modules.get(), 512, &loaded_module_sz)) + return {}; + + for (auto i = 0u; i < loaded_module_sz / 8u; i++) + { + wchar_t file_name[MAX_PATH] = L""; + + // get the full working path for the current module + if (!GetModuleFileNameExW(process_handle, loaded_modules.get()[i], file_name, _countof(file_name))) + continue; + + // module name returned will be a full path, check only for file name sub string. + if (std::wcsstr(file_name, module_name.data()) != nullptr) + return { loaded_modules.get()[i], file_name }; + } + + return {}; + } + + inline std::vector get_file_data(const HANDLE file_handle, const std::wstring_view file_path) + { + const auto file_size = std::filesystem::file_size(file_path); + std::vector file_bytes{}; + file_bytes.resize(file_size); + + DWORD bytes_read = 0; + if (!ReadFile(file_handle, file_bytes.data(), static_cast(file_size), &bytes_read, nullptr)) + return {}; + + return file_bytes; + } + + inline bool enable_privilege(const std::wstring_view 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; + } +} + +namespace nozzle +{ + // + // class programmed by wlan + // link: https://github.com/not-wlan/drvmap/blob/master/drvmap/drv_image.hpp + // + class pe_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: + pe_image() {}; + pe_image(std::uint8_t* image, std::size_t size); + pe_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(uintptr_t 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(); + }; + + pe_image::pe_image(std::uint8_t* image, std::size_t size) + { + m_image = std::vector(image, image + size); + m_dos_header = reinterpret_cast(image); + 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); + } + + pe_image::pe_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 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: + { + throw std::runtime_error("gay relocation!"); + 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; + + 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) + 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 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_base, 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; + } + + class injector + { + public: + injector() {}; + injector(void* pe_image, std::size_t size, unsigned pid); + injector(std::vector image_buffer, unsigned pid); + injector(const char* path, unsigned pid); + + void* inject(); + void hook_entry(); + void set_target(unsigned pid); + void set_target(std::wstring proc_name); + + void* get_pe_image() const; + void* get_allocated_base() const; + unsigned get_target() const; + private: + pe_image image; + unsigned target_pid; + std::vector image_buffer; + HANDLE target_handle; + void* alloc_base; + + void write(void* addr, void* buffer, std::size_t size); + void read(void* addr, void* buffer, std::size_t size); + + template + T read(void* addr) + { + if (!addr) + return {}; + T buffer; + read(addr, &buffer, sizeof(T)); + return buffer; + } + + template + void write(void* addr, const T& data) + { + if (!addr) + return; + write(addr, (void*)&data, sizeof(T)); + } + }; + + injector::injector(void* pe_image, std::size_t size, unsigned pid) + : + target_pid(pid), + target_handle(::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid)) + {} + + injector::injector(const char* path, unsigned pid) + : + target_pid(pid) + { + std::vector image_buffer; + util::open_binary_file(path, image_buffer); + this->image_buffer = image_buffer; + std::printf("[+] enabled debug priv => %d\n", util::enable_privilege(L"SeDebugPrivilege")); + this->target_handle = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + std::printf("[+] target handle => %p\n", target_handle); + } + + injector::injector(std::vector image_buffer, unsigned pid) + : + image_buffer(image_buffer), + target_pid(pid), + target_handle(::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid)) + {} + + void* injector::inject() + { + image = pe_image(image_buffer); + + // + // only resolves globally mapped dll imports. + // + static const auto _get_module = [](std::string_view module_name) -> std::uintptr_t + { + return reinterpret_cast(LoadLibraryA(module_name.data())); + }; + + // + // only resolves ntdll.dll, kernel32.dll, and user32.dll imports + // + static const auto _get_function = [](std::uintptr_t module_base, const char* module_name) -> std::uintptr_t + { + return reinterpret_cast(GetProcAddress(reinterpret_cast(module_base), module_name)); + }; + + alloc_base = VirtualAllocEx( + target_handle, + NULL, + image.size(), + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE + ); + + if (!alloc_base) + return NULL; + + image.fix_imports(_get_module, _get_function); + image.map(); + image.relocate(reinterpret_cast(alloc_base)); + write(alloc_base, image.data(), image.size()); + return alloc_base; + } + + void injector::hook_entry() + { + // jmp [rip] + // 0xaddress of entry... + std::uint8_t jmp_rip[14] = { 0xff, 0x25, 0x0, 0x0, 0x0, 0x0 }; + *reinterpret_cast(jmp_rip + 6) = reinterpret_cast(alloc_base) + image.entry_point(); + static const auto rtl_alloc_heap = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtClose"); + write(rtl_alloc_heap, jmp_rip, sizeof(jmp_rip)); + } + + void* injector::get_allocated_base() const + { + return alloc_base; + } + + void injector::set_target(unsigned pid) + { + target_pid = pid; + } + + void injector::set_target(std::wstring proc_name) + { + target_pid = util::get_process_id(proc_name); + } + + void* injector::get_pe_image() const + { + return (void*)image_buffer.data(); + } + + unsigned injector::get_target() const + { + return target_pid; + } + + void injector::write(void* addr, void* buffer, std::size_t size) + { + SIZE_T bytes_written; + ::WriteProcessMemory( + target_handle, + addr, + buffer, + size, + &bytes_written + ); + } + + void injector::read(void* addr, void* buffer, std::size_t size) + { + SIZE_T bytes_read; + ::ReadProcessMemory( + target_handle, + addr, + buffer, + size, + &bytes_read + ); + } +} \ No newline at end of file diff --git a/badeye/inside/dllmain.cpp b/badeye/inside/dllmain.cpp new file mode 100644 index 0000000..90ae9b0 --- /dev/null +++ b/badeye/inside/dllmain.cpp @@ -0,0 +1,129 @@ +#include +#include +#include + +// would use std::pair but that requires #include which causes unresolved externals... +using ioctl_data = struct { HANDLE drv_handle; void* return_addr; }; +#define READ_IOCTL 0x0222000 +#define WRITE_IOCTL 0x0222004 + +namespace bedaisy +{ + struct beioctl + { + void* ret_addr; + void* handle; + std::uintptr_t base_addr; + void* buffer; + size_t buffer_size; + size_t* bytes_read; + }; + + inline ioctl_data get_ioctl_data() + { + const auto wpm = + reinterpret_cast( + GetProcAddress(GetModuleHandleA("ntdll.dll"), + "NtWriteVirtualMemory")); + + // ensure inline jump is installed... + if (*reinterpret_cast(wpm) == 0xFF) + { + const auto shellcode_ptr = *reinterpret_cast(wpm + 6); + const auto ioctl_handle = *reinterpret_cast(shellcode_ptr + 0x50); + + const auto lsasrv = + reinterpret_cast( + GetModuleHandleA("lsasrv.dll")); + + // 0f 1f 44 00 ? 8b f0 48 8b 0d ? ? ? ? 49 3b cd (proper return) + return { ioctl_handle, reinterpret_cast(lsasrv + 0x36E3B) }; + } + return { {}, {} }; + } + + template + inline T read(HANDLE proc_handle, std::uintptr_t addr) + { + if (!addr || !proc_handle) + return {}; + + T buffer; + const auto [daisy_handle, return_addr] = get_ioctl_data(); + const beioctl ioctl_data + { + return_addr, + proc_handle, + addr, + &buffer, + sizeof(T), + nullptr + }; + + DWORD bytes_read; + DeviceIoControl + ( + daisy_handle, + READ_IOCTL, + (void*)&ioctl_data, + sizeof ioctl_data, + nullptr, + NULL, + &bytes_read, + nullptr + ); + return buffer; + } + + template + inline void write(HANDLE proc_handle, std::uintptr_t addr, const T& data) + { + if (!proc_handle || !addr) + return; + + const auto [daisy_handle, return_addr] = get_ioctl_data(); + const beioctl ioctl_data + { + return_addr, + proc_handle, + addr, + (void*)&data, + sizeof(T), + nullptr + }; + + DWORD bytes_read; + DeviceIoControl + ( + daisy_handle, + WRITE_IOCTL, + (void*)&ioctl_data, + sizeof ioctl_data, + nullptr, + NULL, + &bytes_read, + nullptr + ); + } +} + +void runner() +{ + OutputDebugStringA("[lsass] main thread created!"); + const auto r6 = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, 11108); + if(bedaisy::read(r6, 0x7ff7f2c90000) == 0x5A4D) + OutputDebugStringA("[lsass] read MZ!"); + else + OutputDebugStringA("[lsass] didnt read MZ!"); +} + +std::atomic init = false; +extern "C" NTSTATUS nt_close(void* handle) +{ + if (!init.exchange(true)) + { + OutputDebugStringA("[lsass] creating thread!"); + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)&runner, NULL, NULL, NULL); + } + return NULL; +} \ No newline at end of file diff --git a/badeye/inside/inside.vcxproj b/badeye/inside/inside.vcxproj new file mode 100644 index 0000000..5e638ff --- /dev/null +++ b/badeye/inside/inside.vcxproj @@ -0,0 +1,170 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {f449b39d-4975-4478-b873-2747cc3dd7ef} + helloworld + 10.0 + inside + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;HELLOWORLD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;HELLOWORLD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;HELLOWORLD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;HELLOWORLD_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + stdcpp17 + MultiThreaded + false + false + + + Windows + true + true + true + false + nt_close + false + %(AdditionalDependencies) + true + + + + + + + + + + \ No newline at end of file diff --git a/badeye/inside/inside.vcxproj.filters b/badeye/inside/inside.vcxproj.filters new file mode 100644 index 0000000..c728d06 --- /dev/null +++ b/badeye/inside/inside.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/badeye/inside/inside.vcxproj.user b/badeye/inside/inside.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/badeye/inside/inside.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/battleye.8.17.2020/BELauncher.exe b/battleye.8.17.2020/BELauncher.exe new file mode 100644 index 0000000..71b58a5 Binary files /dev/null and b/battleye.8.17.2020/BELauncher.exe differ diff --git a/battleye.8.17.2020/BattlEye/BELauncher.ini b/battleye.8.17.2020/BattlEye/BELauncher.ini new file mode 100644 index 0000000..d4d8bc9 Binary files /dev/null and b/battleye.8.17.2020/BattlEye/BELauncher.ini differ diff --git a/battleye.8.17.2020/BattlEye/BEService_x64.exe b/battleye.8.17.2020/BattlEye/BEService_x64.exe new file mode 100644 index 0000000..2056969 Binary files /dev/null and b/battleye.8.17.2020/BattlEye/BEService_x64.exe differ diff --git a/battleye.8.17.2020/powershell.exe b/battleye.8.17.2020/powershell.exe new file mode 100644 index 0000000..fedcea1 Binary files /dev/null and b/battleye.8.17.2020/powershell.exe differ