diff options
| author | auth12 <[email protected]> | 2020-07-20 03:09:25 -0700 |
|---|---|---|
| committer | auth12 <[email protected]> | 2020-07-20 03:09:25 -0700 |
| commit | c9e48c5e9eddfe5b7a895fb3940c41ccf75d3e93 (patch) | |
| tree | 2b04471e76f7fb31aff0151b978ece9af4410a8b | |
| parent | Merge pull request #1 from auth12/windows (diff) | |
| download | loader-c9e48c5e9eddfe5b7a895fb3940c41ccf75d3e93.tar.xz loader-c9e48c5e9eddfe5b7a895fb3940c41ccf75d3e93.zip | |
Syscalls.
Removed asmjit submodule and embedded it instead.
Small PE wrapper.
| -rw-r--r-- | CMakeLists.txt | 5 | ||||
| -rw-r--r-- | client/client.vcxproj | 9 | ||||
| -rw-r--r-- | client/client.vcxproj.filters | 24 | ||||
| -rw-r--r-- | client/src/client/client.h | 9 | ||||
| -rw-r--r-- | client/src/include.h | 1 | ||||
| -rw-r--r-- | client/src/injection/mapper.h | 18 | ||||
| -rw-r--r-- | client/src/main.cpp | 64 | ||||
| -rw-r--r-- | client/src/util/native.h | 209 | ||||
| -rw-r--r-- | client/src/util/pe.h | 55 | ||||
| -rw-r--r-- | client/src/util/syscalls.cpp | 99 | ||||
| -rw-r--r-- | client/src/util/syscalls.h | 22 | ||||
| -rw-r--r-- | client/src/util/util.cpp | 52 | ||||
| -rw-r--r-- | client/src/util/util.h | 26 | ||||
| -rw-r--r-- | server/src/main.cpp | 8 |
14 files changed, 571 insertions, 30 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ec601bf..8643d4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,6 @@ cmake_minimum_required(VERSION 3.14) project(server-client) -find_package(LLVM REQUIRED CONFIG) - -message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") -message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") - if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() diff --git a/client/client.vcxproj b/client/client.vcxproj index 302f138..6e6b40c 100644 --- a/client/client.vcxproj +++ b/client/client.vcxproj @@ -143,7 +143,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalDependencies>wolfssl.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)lib\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> - <UACExecutionLevel>RequireAdministrator</UACExecutionLevel> + <UACExecutionLevel>AsInvoker</UACExecutionLevel> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -213,6 +213,7 @@ <ClInclude Include="asmjit\x86\x86opcode_p.h" /> <ClInclude Include="asmjit\x86\x86operand.h" /> <ClInclude Include="asmjit\x86\x86rapass_p.h" /> + <ClInclude Include="src\injection\mapper.h" /> <ClInclude Include="src\shellcode\shellcode.h" /> <ClInclude Include="src\client\client.h" /> <ClInclude Include="src\client\enc.h" /> @@ -220,6 +221,10 @@ <ClInclude Include="src\include.h" /> <ClInclude Include="src\util\events.h" /> <ClInclude Include="src\util\io.h" /> + <ClInclude Include="src\util\native.h" /> + <ClInclude Include="src\util\pe.h" /> + <ClInclude Include="src\util\syscalls.h" /> + <ClInclude Include="src\util\util.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="asmjit\core\arch.cpp" /> @@ -274,6 +279,8 @@ <ClCompile Include="src\client\enc.cpp" /> <ClCompile Include="src\main.cpp" /> <ClCompile Include="src\util\io.cpp" /> + <ClCompile Include="src\util\syscalls.cpp" /> + <ClCompile Include="src\util\util.cpp" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/client/client.vcxproj.filters b/client/client.vcxproj.filters index 5bef59c..cc039bb 100644 --- a/client/client.vcxproj.filters +++ b/client/client.vcxproj.filters @@ -22,6 +22,9 @@ <Filter Include="asmjit\core"> <UniqueIdentifier>{c2f81934-936b-47af-928c-3ef5c27a6429}</UniqueIdentifier> </Filter> + <Filter Include="src\injection"> + <UniqueIdentifier>{b42a963e-6a61-434d-a9e7-fcbdf8c0164e}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClInclude Include="src\include.h"> @@ -243,6 +246,21 @@ <ClInclude Include="asmjit\x86\x86rapass_p.h"> <Filter>asmjit\x86</Filter> </ClInclude> + <ClInclude Include="src\injection\mapper.h"> + <Filter>src\injection</Filter> + </ClInclude> + <ClInclude Include="src\util\util.h"> + <Filter>src\util</Filter> + </ClInclude> + <ClInclude Include="src\util\pe.h"> + <Filter>src\util</Filter> + </ClInclude> + <ClInclude Include="src\util\native.h"> + <Filter>src\util</Filter> + </ClInclude> + <ClInclude Include="src\util\syscalls.h"> + <Filter>src\util</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="src\main.cpp"> @@ -401,5 +419,11 @@ <ClCompile Include="asmjit\x86\x86rapass.cpp"> <Filter>asmjit\x86</Filter> </ClCompile> + <ClCompile Include="src\util\util.cpp"> + <Filter>src\util</Filter> + </ClCompile> + <ClCompile Include="src\util\syscalls.cpp"> + <Filter>src\util</Filter> + </ClCompile> </ItemGroup> </Project>
\ No newline at end of file diff --git a/client/src/client/client.h b/client/src/client/client.h index 3a888fb..8d5b80a 100644 --- a/client/src/client/client.h +++ b/client/src/client/client.h @@ -15,6 +15,12 @@ struct version_t { uint8_t patch; }; +struct game_data_t { + std::string name; + std::string version; + int id; +}; + enum client_state { idle = 0, logged_in, waiting }; @@ -36,7 +42,8 @@ class client { public: int state; - mmap::data mapper_data; + mmap::mapper_data_t mapper_data; + std::vector<game_data_t> games; std::string session_id; event<packet_t&> receive_event; diff --git a/client/src/include.h b/client/src/include.h index a810eed..4955913 100644 --- a/client/src/include.h +++ b/client/src/include.h @@ -6,6 +6,7 @@ #include <winsock2.h> #include <ws2tcpip.h> #include <iphlpapi.h> +#include <winternl.h> #include <algorithm> #include <array> diff --git a/client/src/injection/mapper.h b/client/src/injection/mapper.h index 27541c4..0d9026e 100644 --- a/client/src/injection/mapper.h +++ b/client/src/injection/mapper.h @@ -1,11 +1,13 @@ #pragma once - namespace mmap { - struct data { - size_t image_size; - uint32_t entry; - uint32_t base; - std::string imports; - }; -};
\ No newline at end of file + +struct mapper_data_t { + size_t image_size; + uint32_t entry; + uint32_t base; + std::string imports; + std::vector<char> image; +}; + +}; // namespace mmap
\ No newline at end of file diff --git a/client/src/main.cpp b/client/src/main.cpp index f67ecf1..65a29e3 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -1,11 +1,27 @@ #include "include.h" #include "util/io.h" +#include "util/util.h" +#include "util/syscalls.h" #include "client/client.h" #include "shellcode/shellcode.h" int main(int argc, char* argv[]) { io::init(); + if (!util::init()) { + return 0; + } + g_syscalls.init(); + + using NtClose_t = long(__stdcall*)(HANDLE); + + HANDLE h = INVALID_HANDLE_VALUE; + auto status = g_syscalls.get<NtClose_t>("NtClose")(h); + + io::logger->info("{:x}", status); + + std::cin.get(); + tcp::client client; std::thread t{tcp::client::monitor, std::ref(client)}; @@ -72,14 +88,24 @@ int main(int argc, char* argv[]) { } if (res == tcp::login_result::login_success) { - client.state = tcp::client_state::logged_in; + auto games = j["games"]; + for (auto&[key, value] : games.items()) { + std::string version = value["version"]; + int id = value["id"]; + + client.games.emplace_back(tcp::game_data_t{key, version, id}); + } io::logger->info("logged in."); + client.state = tcp::client_state::logged_in; } } if (id == tcp::packet_id::game_select) { /*auto pe = nlohmann::json::parse(message); + client.mapper_data.base = pe[0]; + client.mapper_data.entry = pe[1]; + client.mapper_data.image_size = pe[2]; client.read_stream(client.mapper_data.imports);*/ @@ -97,21 +123,37 @@ int main(int argc, char* argv[]) { }); while (client) { - std::string u; - getline(std::cin, u); + if (client.state == tcp::client_state::idle) { + std::string u; + getline(std::cin, u); + + std::string p; + getline(std::cin, p); + + auto l = fmt::format("{},{}", u, p); + + int ret = client.write(tcp::packet_t(l, tcp::packet_type::write, + client.session_id, + tcp::packet_id::login_req)); + + if (ret <= 0) { + break; + } + } + + if (client.state == tcp::client_state::logged_in) { + for (auto& dat : client.games) { + io::logger->info("[{}]{} : {}", dat.id, dat.name, dat.version); + } + io::logger->info("please select a game :"); - std::string p; - getline(std::cin, p); + int id; + std::cin >> id; - auto l = fmt::format("{},{}", u, p); - int ret = client.write(tcp::packet_t(l, tcp::packet_type::write, - client.session_id, - tcp::packet_id::login_req)); - if (ret <= 0) { - break; } + } std::cin.get(); diff --git a/client/src/util/native.h b/client/src/util/native.h new file mode 100644 index 0000000..623e577 --- /dev/null +++ b/client/src/util/native.h @@ -0,0 +1,209 @@ +#pragma once + +namespace native { + struct PEB_LDR_DATA { + uint32_t Length; + uint8_t Initialized; + uintptr_t SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + uintptr_t EntryInProgress; + uint8_t ShutdownInProgress; + uintptr_t ShutdownThreadId; + }; + + struct UNICODE_STRING { + uint16_t Length; + uint16_t MaximumLength; + wchar_t *Buffer; + }; + + struct STRING { + uint16_t Length; + uint16_t MaximumLength; + char *Buffer; + }; + + struct CURDIR { + UNICODE_STRING DosPath; + uintptr_t Handle; + }; + + struct RTL_DRIVE_LETTER_CURDIR { + uint16_t Flags; + uint16_t Length; + uint32_t TimeStamp; + STRING DosPath; + }; + + struct RTL_USER_PROCESS_PARAMETERS { + uint32_t MaximumLength; + uint32_t Length; + uint32_t Flags; + uint32_t DebugFlags; + uintptr_t ConsoleHandle; + uint32_t ConsoleFlags; + uintptr_t StandardInput; + uintptr_t StandardOutput; + uintptr_t StandardError; + CURDIR CurrentDirectory; + UNICODE_STRING DllPath; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; + uintptr_t Environment; + uint32_t StartingX; + uint32_t StartingY; + uint32_t CountX; + uint32_t CountY; + uint32_t CountCharsX; + uint32_t CountCharsY; + uint32_t FillAttribute; + uint32_t WindowFlags; + uint32_t ShowWindowFlags; + UNICODE_STRING WindowTitle; + UNICODE_STRING DesktopInfo; + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeData; + RTL_DRIVE_LETTER_CURDIR CurrentDirectores[ 32 ]; + uintptr_t EnvironmentSize; + uintptr_t EnvironmentVersion; + uintptr_t PackageDependencyData; + uint32_t ProcessGroupId; + uint32_t LoaderThreads; + }; + + struct RTL_BALANCED_NODE { + RTL_BALANCED_NODE *Children[ 2 ]; + RTL_BALANCED_NODE *Left; + RTL_BALANCED_NODE *Right; + uintptr_t ParentValue; + }; + + struct _PEB { + uint8_t InheritedAddressSpace; + uint8_t ReadImageFileExecOptions; + uint8_t BeingDebugged; + uint8_t BitField; + //uchar Padding0[ 4 ]; + uintptr_t Mutant; + uintptr_t ImageBaseAddress; + PEB_LDR_DATA *Ldr; + RTL_USER_PROCESS_PARAMETERS *ProcessParameters; + uintptr_t SubSystemData; + uintptr_t ProcessHeap; + RTL_CRITICAL_SECTION *FastPebLock; + uintptr_t AtlThunkSListPtr; + uintptr_t IFEOKey; + uint32_t CrossProcessFlags; + uint8_t Padding1[ 4 ]; + uintptr_t KernelCallbackTable; + uintptr_t UserSharedInfoPtr; + uint32_t SystemReserved[ 1 ]; + uint32_t AtlThunkSListPtr32; + uintptr_t ApiSetMap; + uint32_t TlsExpansionCounter; + uint8_t Padding2[ 4 ]; + uintptr_t TlsBitmap; + uint32_t TlsBitmapBits[ 2 ]; + uintptr_t ReadOnlySharedMemoryBase; + uintptr_t SparePvoid0; + uintptr_t ReadOnlyStaticServerData; + uintptr_t AnsiCodePageData; + uintptr_t OemCodePageData; + uintptr_t UnicodeCaseTableData; + uint32_t NumberOfProcessors; + uint32_t NtGlobalFlag; + LARGE_INTEGER CriticalSectionTimeout; + uintptr_t HeapSegmentReserve; + uintptr_t HeapSegmentCommit; + uintptr_t HeapDeCommitTotalFreeThreshold; + uintptr_t HeapDeCommitFreeBlockThreshold; + uint32_t NumberOfHeaps; + uint32_t MaximumNumberOfHeaps; + uintptr_t ProcessHeaps; + uintptr_t GdiSharedHandleTable; + uintptr_t ProcessStarterHelper; + uint32_t GdiDCAttributeList; + uint8_t Padding3[ 4 ]; + RTL_CRITICAL_SECTION *LoaderLock; + uint32_t OSMajorVersion; + uint32_t OSMinorVersion; + uint16_t OSBuildNumber; + uint16_t OSCSDVersion; + uint32_t OSPlatformId; + uint32_t ImageSubsystem; + uint32_t ImageSubsystemMajorVersion; + uint32_t ImageSubsystemMinorVersion; + uint8_t Padding4[ 4 ]; + uintptr_t ActiveProcessAffinityMask; +#ifdef _WIN32 + uint32_t GdiHandleBuffer[ 34 ]; +#else + uint32_t GdiHandleBuffer[ 60 ]; +#endif + uintptr_t PostProcessInitRoutine; + uintptr_t TlsExpansionBitmap; + uint32_t TlsExpansionBitmapBits[ 32 ]; + uint32_t SessionId; + uint8_t Padding5[ 4 ]; + ULARGE_INTEGER AppCompatFlags; + ULARGE_INTEGER AppCompatFlagsUser; + uintptr_t pShimData; + uintptr_t AppCompatInfo; + UNICODE_STRING CSDVersion; + uintptr_t ActivationContextData; + uintptr_t ProcessAssemblyStorageMap; + uintptr_t SystemDefaultActivationContextData; + uintptr_t SystemAssemblyStorageMap; + uintptr_t MinimumStackCommit; + uintptr_t FlsCallback; + LIST_ENTRY FlsListHead; + uintptr_t FlsBitmap; + uint32_t FlsBitmapBits[ 4 ]; + uint32_t FlsHighIndex; + uintptr_t WerRegistrationData; + uintptr_t WerShipAssertPtr; + uintptr_t pUnused; + uintptr_t pImageHeaderHash; + uint32_t TracingFlags; + uint8_t Padding6[ 4 ]; + uint64_t CsrServerReadOnlySharedMemoryBase; + uintptr_t TppWorkerpListLock; + LIST_ENTRY TppWorkerpList; + uintptr_t WaitOnAddressHashTable[ 128 ]; + }; + + struct LDR_DATA_TABLE_ENTRY { + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + uintptr_t DllBase; + uintptr_t EntryPoint; + uint32_t SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + uint8_t FlagGroup[ 4 ]; + uint32_t Flags; + uint16_t ObsoleteLoadCount; + uint16_t TlsIndex; + LIST_ENTRY HashLinks; + uint32_t TimeDateStamp; + uintptr_t EntryPointActivationContext; + uintptr_t Lock; + uintptr_t DdagNode; + LIST_ENTRY NodeModuleLink; + uintptr_t LoadContext; + uintptr_t ParentDllBase; + uintptr_t SwitchBackContext; + RTL_BALANCED_NODE BaseAddressIndexNode; + RTL_BALANCED_NODE MappingInfoIndexNode; + uintptr_t OriginalBase; + LARGE_INTEGER LoadTime; + uint32_t BaseNameHashValue; + uint32_t LoadReason; + uint32_t ImplicitPathOptions; + uint32_t ReferenceCount; + }; + +}; // namespace native
\ No newline at end of file diff --git a/client/src/util/pe.h b/client/src/util/pe.h new file mode 100644 index 0000000..a4d835d --- /dev/null +++ b/client/src/util/pe.h @@ -0,0 +1,55 @@ +#pragma once + +namespace pe { + +class image { + std::unordered_map<std::string, uintptr_t> m_exports; + + IMAGE_NT_HEADERS64 *m_nt; + uintptr_t m_base; + bool m_valid; + + public: + image(){}; + image(const uintptr_t base) : m_valid{false}, m_base{base}, m_nt{nullptr} { + auto dos = reinterpret_cast<IMAGE_DOS_HEADER *>(base); + if (!dos || dos->e_magic != IMAGE_DOS_SIGNATURE) { + return; + } + + m_nt = reinterpret_cast<IMAGE_NT_HEADERS64 *>(base + dos->e_lfanew); + if (m_nt->Signature != IMAGE_NT_SIGNATURE) { + return; + } + + m_valid = true; + } + + void parse_exports() { + auto dir = m_nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + auto exp = + reinterpret_cast<IMAGE_EXPORT_DIRECTORY *>(m_base + dir.VirtualAddress); + + if (exp->NumberOfFunctions == 0) return; + + auto names = reinterpret_cast<uint32_t *>(m_base + exp->AddressOfNames); + auto funcs = reinterpret_cast<uint32_t *>(m_base + exp->AddressOfFunctions); + auto ords = + reinterpret_cast<uint16_t *>(m_base + exp->AddressOfNameOrdinals); + + if (!names || !funcs || !ords) return; + + for (size_t i{}; i < exp->NumberOfFunctions; i++) { + uintptr_t va = m_base + funcs[ords[i]]; + std::string name = reinterpret_cast<const char *>(m_base + names[i]); + + m_exports[name] = va; + } + } + + auto &exports() { return m_exports; } + + operator bool() { return m_valid; } +}; + +}; // namespace pe
\ No newline at end of file diff --git a/client/src/util/syscalls.cpp b/client/src/util/syscalls.cpp new file mode 100644 index 0000000..624ce5a --- /dev/null +++ b/client/src/util/syscalls.cpp @@ -0,0 +1,99 @@ +#include "../include.h" +#include "io.h" +#include "util.h" +#include "syscalls.h" + +syscalls g_syscalls; + +syscalls::syscalls() { + m_call_table = VirtualAlloc(0, 0x100000, MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + std::memset(m_call_table, 0x90, 0x100000); +} + +syscalls::~syscalls() { + VirtualFree(m_call_table, 0, MEM_RELEASE); +} + +void syscalls::init() { + auto nt = util::ntdll(); + for (auto& exp : nt.exports()) { + auto addr = exp.second; + + uint16_t offset; + auto idx = get_index(addr, offset); + + if(!idx) continue; + + m_indexes[exp.first] = std::make_pair(idx, offset); + + if (m_stub.empty()) { + auto s = func_size(reinterpret_cast<uint8_t*>(addr)); + + m_stub.resize(s); + + std::memcpy(&m_stub[0], (void*)addr, s); + } + } + + io::logger->info("{:x}", uintptr_t(m_call_table)); + + for (auto& syscall : m_indexes) { + auto idx = syscall.second.first; + + auto addr = uintptr_t(m_call_table) + (idx * m_stub.size()); + std::memcpy(reinterpret_cast<void*>(addr), m_stub.data(), m_stub.size()); + + *reinterpret_cast<uint8_t*>(addr + m_stub.size() - 1) = 0xc3; + *reinterpret_cast<uint16_t*>(addr + syscall.second.second + 1) = idx; + } +} + +bool syscalls::valid(const uintptr_t addr, const size_t &size) { + auto func = reinterpret_cast<uint8_t*>(addr); + + // mov r10, rcx + uint32_t a = func[0] + func[1] + func[2]; + if (a != 0x1a8) { + return false; + } + + for (size_t i{}; i < size; i++) { + auto op = func[i]; + auto next = func[i + 1]; + + if (op == 0x0f && next == 0x05) { + return true; + } + } + + return false; +} + +uint16_t syscalls::get_index(const uintptr_t va, uint16_t &offset) { + auto func = reinterpret_cast<uint8_t*>(va); + auto size = func_size(reinterpret_cast<uint8_t*>(va)); + if (!valid(va, size)) { + return 0; + } + + for (size_t i{}; i < size; i++) { + auto op = func[i]; + if (op == 0xb8) { + offset = i; + + return *reinterpret_cast<uint16_t*>(va + i + 1); + } + } + return 0; +} + +size_t syscalls::func_size(const uint8_t* func) { + for (size_t i = 0; i < 64; i++) { + auto op = func[i]; + if (op == 0xc3 || op == 0xc2) { + return i + 1; + } + } + return 0; +} diff --git a/client/src/util/syscalls.h b/client/src/util/syscalls.h new file mode 100644 index 0000000..0d73e4e --- /dev/null +++ b/client/src/util/syscalls.h @@ -0,0 +1,22 @@ +#pragma once + +class syscalls { + std::unordered_map<std::string, std::pair<uint16_t, uint16_t>> m_indexes; + std::vector<char> m_stub; + + void *m_call_table; +public: + syscalls(); + ~syscalls(); + void init(); + bool valid(const uintptr_t func, const size_t &size); + uint16_t get_index(const uintptr_t va, uint16_t &offset); + size_t func_size(const uint8_t *func); + + template<class T> + T get(const std::string_view func) { + return reinterpret_cast<T>(uintptr_t(m_call_table) + (m_indexes[func.data()].first * m_stub.size())); + }; +}; + +extern syscalls g_syscalls;
\ No newline at end of file diff --git a/client/src/util/util.cpp b/client/src/util/util.cpp new file mode 100644 index 0000000..a23c03c --- /dev/null +++ b/client/src/util/util.cpp @@ -0,0 +1,52 @@ +#include "../include.h" +#include "io.h" +#include "util.h" + +std::unordered_map<std::string, pe::image> util::loaded_modules; + +std::string util::wide_to_multibyte(const std::wstring &str) { + std::string ret; + int32_t str_len; + + // check if not empty str + if (str.empty()) + return{}; + + // count size + str_len = WideCharToMultiByte(CP_UTF8, 0, &str[0], (int32_t) str.size(), 0, 0, 0, 0); + + // setup return value + ret = std::string(str_len, 0); + + // final conversion + WideCharToMultiByte(CP_UTF8, 0, &str[0], (int32_t) str.size(), &ret[0], str_len, 0, 0); + + return ret; +} + + +native::_PEB* util::get_peb() { + return reinterpret_cast<native::_PEB*>(__readgsqword(0x60)); +} + +bool util::init() { + auto peb = get_peb(); + if (!peb) return false; + + if (!peb->Ldr->InMemoryOrderModuleList.Flink) return false; + + auto* list = &peb->Ldr->InMemoryOrderModuleList; + + for (auto i = list->Flink; i != list; i = i->Flink) { + auto entry = CONTAINING_RECORD(i, native::LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + if (!entry) + continue; + + auto name = wide_to_multibyte(entry->BaseDllName.Buffer); + std::transform(name.begin(), name.end(), name.begin(), ::tolower); + + loaded_modules[name] = pe::image(entry->DllBase); + } + + return true; +} diff --git a/client/src/util/util.h b/client/src/util/util.h new file mode 100644 index 0000000..b4bf699 --- /dev/null +++ b/client/src/util/util.h @@ -0,0 +1,26 @@ +#pragma once + +#include "native.h" +#include "pe.h" + +namespace util { + +extern std::unordered_map<std::string, pe::image> loaded_modules; + +std::string wide_to_multibyte(const std::wstring &str); + +native::_PEB *get_peb(); + +bool init(); + +static pe::image& ntdll() { + static pe::image nt{}; + if (!nt) { + nt = loaded_modules["ntdll.dll"]; + nt.parse_exports(); + } + return nt; +} + +}; // namespace util + diff --git a/server/src/main.cpp b/server/src/main.cpp index df3f6e8..524954e 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -93,8 +93,8 @@ int main(int argc, char* argv[]) { io::logger->info("{} is trying to login from {}.", user, ip); - // int ret = forum_response::api_error; - int ret = client_server.forum().check_login(user, pass, data); + int ret = forum_response::api_success; + //int ret = client_server.forum().check_login(user, pass, data); if (ret == forum_response::api_success) { if (data.banned) { io::logger->warn("{} is forum banned, dropping...", user); @@ -137,8 +137,8 @@ int main(int argc, char* argv[]) { } json["result"] = tcp::client_response::login_success; - json["games"]["csgo"] = {{"version", 1.2}, {"id", 0}}; - json["games"]["csgo beta"] = {{"version", 1.2}, {"id", 1}}; + json["games"]["csgo"] = {{"version", "1.2"}, {"id", 0}}; + json["games"]["csgo beta"] = {{"version", "1.2"}, {"id", 1}}; client.write(tcp::packet_t(json.dump(), tcp::packet_type::write, session, tcp::packet_id::login_resp)); |