From b31c7bfce7aa52d00ca984431d155e0c44d962b8 Mon Sep 17 00:00:00 2001 From: xerox Date: Sat, 8 Aug 2020 16:52:01 -0700 Subject: [PATCH] sdk is working! test with ammo --- ligma-cheat/ligma-cheat/SDK/Il2Cpp/Il2Cpp.cpp | 11 +++- ligma-cheat/ligma-cheat/bypass/bypass.cpp | 60 +++++++++++++++++- ligma-cheat/ligma-cheat/bypass/bypass.h | 10 ++- ligma-cheat/ligma-cheat/hooks/got_hook.h | 46 -------------- ligma-cheat/ligma-cheat/hooks/xhook.h | 50 +++++++++++++++ ligma-cheat/ligma-cheat/libxhook.a | Bin 0 -> 54554 bytes ligma-cheat/ligma-cheat/ligma-cheat.vcxproj | 37 +++++++---- .../ligma-cheat/ligma-cheat.vcxproj.filters | 7 +- ligma-cheat/ligma-cheat/ligma.h | 1 - ligma-cheat/ligma-cheat/main.cpp | 37 ++++++----- ligma-cheat/ligma-cheat/utils/utils.cpp | 27 +++++--- ligma-cheat/ligma-cheat/utils/utils.h | 1 + 12 files changed, 192 insertions(+), 95 deletions(-) delete mode 100644 ligma-cheat/ligma-cheat/hooks/got_hook.h create mode 100644 ligma-cheat/ligma-cheat/hooks/xhook.h create mode 100644 ligma-cheat/ligma-cheat/libxhook.a diff --git a/ligma-cheat/ligma-cheat/SDK/Il2Cpp/Il2Cpp.cpp b/ligma-cheat/ligma-cheat/SDK/Il2Cpp/Il2Cpp.cpp index f33cf31dc..502546701 100644 --- a/ligma-cheat/ligma-cheat/SDK/Il2Cpp/Il2Cpp.cpp +++ b/ligma-cheat/ligma-cheat/SDK/Il2Cpp/Il2Cpp.cpp @@ -3,6 +3,8 @@ // #include "Il2Cpp.h" +#include "../../ligma.h" + // ========================================================================================================================================== // #define IL2CPP__TAG "Il2CppSdk" #define IL2CPP_LOGI(...) __android_log_print(ANDROID_LOG_INFO,IL2CPP__TAG,__VA_ARGS__) @@ -14,7 +16,7 @@ std::map m_cacheFields; std::map m_cacheMethods; std::map m_cacheClasses; // ========================================================================================================================================== // -namespace +namespace // all of this dog shit needs to be cleaned up... { const void *(*il2cpp_assembly_get_image)(const void *assembly); void *(*il2cpp_domain_get)(); @@ -66,10 +68,12 @@ void *get_export_function(const char *lib, const char *name) } // ========================================================================================================================================== // -#define GAME_LIB_ENGINE "libil2cpp.so" std::uintptr_t Il2CppBase() { - return reinterpret_cast(dlopen(GAME_LIB_ENGINE, RTLD_NOLOAD)); + static const auto module_base = + ligma::utils::get_module_base("libil2cpp.so"); + + return module_base; } // ========================================================================================================================================== // typedef unsigned short UTF16; @@ -194,6 +198,7 @@ bool Il2Cpp::Attach(const char *libname) if (!(il2cpp_string_new_utf16 = (Il2CppString * (*)(const wchar_t*, size_t)) get_export_function(libname, "il2cpp_string_new_utf16"))) return false; + return true; } // ========================================================================================================================================== // diff --git a/ligma-cheat/ligma-cheat/bypass/bypass.cpp b/ligma-cheat/ligma-cheat/bypass/bypass.cpp index 436a643e3..643cdf2cd 100644 --- a/ligma-cheat/ligma-cheat/bypass/bypass.cpp +++ b/ligma-cheat/ligma-cheat/bypass/bypass.cpp @@ -1,4 +1,6 @@ #include "bypass.h" +#include +#include namespace ligma { @@ -15,11 +17,34 @@ namespace ligma { LOGI("libxlua.so base = %p", module_base); ligma::hook::make_hook( - dlsym(reinterpret_cast(module_base), "luaL_loadbufferx"), + dlsym(dlopen("libxlua.so", RTLD_NOLOAD), "luaL_loadbufferx"), reinterpret_cast(&load_bufferx_hook) ); }); + ligma::utils::on_image_load("libtersafe.so", [&](const std::uintptr_t module_base) + { + LOGI("libtersafe.so = %p", module_base); + ligma::hook::make_hook( + reinterpret_cast(module_base + offset_ischeat_packet), + reinterpret_cast(&tss_sdk_ischeatpacket) + ); + ligma::hook::make_hook( + reinterpret_cast(module_base + offset_tencent_init), + reinterpret_cast(&Java_com_tencent_tp_TssSdk_init) + ); + }); + + // for some reason lubcubehawk.so is never loaded?? + ligma::utils::on_image_load("libcubehawk.so", [&](const auto module_base) + { + LOGI("libcubehawk.so = %p", module_base); + ligma::hook::make_hook( + dlsym(dlopen("libcubehawk.so", RTLD_NOLOAD), "Java_com_tencent_hawk_bridge_HawkNative_checkEmulator"), + reinterpret_cast(&Java_com_tencent_hawk_bridge_HawkNative_checkEmulator) + ); + }); + fopen_ptr = dlsym(dlopen("libc.so", RTLD_NOLOAD), "fopen"); dlopen_ptr = dlsym(dlopen("libdl.so", RTLD_NOLOAD), "dlopen"); system_prop_get = dlsym(dlopen("libc.so", RTLD_NOLOAD), "__system_property_get"); @@ -29,6 +54,37 @@ namespace ligma ligma::hook::make_hook(system_prop_get, reinterpret_cast(&system_property_hook)); } + int Java_com_tencent_hawk_bridge_HawkNative_checkEmulator(int a1, int a2, int a3, int a4) + { + LOGI("check emulator called! a1 = 0x%x, a2 = 0x%x, a3 = 0x%x, a4 = 0x%x", a1, a2, a3, a4); + static const auto check_emulator = + reinterpret_cast( + dlsym(dlopen("libcubehawk.so", RTLD_NOLOAD), "Java_com_tencent_hawk_bridge_HawkNative_checkEmulator")); + const auto result = check_emulator(a1, a2, a3, a4); + LOGI("check emulator result = 0x%x", result); + return result; + } + + int tss_sdk_ischeatpacket(int a1) + { + LOGI("-------------- is cheat packet called! a1 = 0x%x -----------------", a1); + const auto result = + reinterpret_cast( + dlsym(dlopen("libtersafe.so", RTLD_NOLOAD), "tss_sdk_ischeatpacket"))(a1); + LOGI("is cheat packet result = 0x%x", a1); + return result; + } + + int Java_com_tencent_tp_TssSdk_init(int a1, int a2, int a3) + { + LOGI("----------- Java_com_tencent_tp_TssSdk_init called! a1 = 0x%x, a2 = 0x%x, a3 = 0x%x --------------", a1, a2, a3); + const auto result = + reinterpret_cast( + dlsym(dlopen("libtersafe.so", RTLD_NOLOAD), "Java_com_tencent_tp_TssSdk_init"))(a1, a2, a3); + LOGI("result = 0x%x", result); + return result; + } + // // dont let a single lua script load! // @@ -79,7 +135,7 @@ namespace ligma if (strstr(filename, file_key.c_str())) { ligma::utils::get_callbacks()->erase(file_key); - callback(reinterpret_cast(result)); + callback(ligma::utils::get_module_base(file_key.c_str())); break; } } diff --git a/ligma-cheat/ligma-cheat/bypass/bypass.h b/ligma-cheat/ligma-cheat/bypass/bypass.h index d2606e6ef..5c6c242d9 100644 --- a/ligma-cheat/ligma-cheat/bypass/bypass.h +++ b/ligma-cheat/ligma-cheat/bypass/bypass.h @@ -1,15 +1,16 @@ #pragma once #include +#include #include #include #include #include "../ligma.h" #define HWID_VALUE "what do you call nuts on your chin? a dick down your throat you fucking retard!" -#define offset_emulator_check 0x000D7B4 -#define offset_ischeat_packet 0x00128E0 +#define offset_emulator_check 0x000D7B4 +#define offset_ischeat_packet 0x00128E0 #define offset_mshook_function 0x0010358 -#define offset_fopen_got 0x23ECC +#define offset_tencent_init 0x0021CAC namespace ligma { @@ -25,6 +26,9 @@ namespace ligma inline std::mutex dlopen_mutex; void init(const std::function& callback); + int tss_sdk_ischeatpacket(int a1); + int Java_com_tencent_hawk_bridge_HawkNative_checkEmulator(int a1, int a2, int a3, int a4); + int Java_com_tencent_tp_TssSdk_init(int a1, int a2, int a3); void* dlopen_hook(const char* filename, int flags); FILE* fopen_hook(const char* path, const char* mode); int system_property_hook(const char* name, char* value); diff --git a/ligma-cheat/ligma-cheat/hooks/got_hook.h b/ligma-cheat/ligma-cheat/hooks/got_hook.h deleted file mode 100644 index 215d709e7..000000000 --- a/ligma-cheat/ligma-cheat/hooks/got_hook.h +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include - -#define LOGI(...) ((void)__android_log_print(4, "ligma", __VA_ARGS__)) -#define LOGW(...) ((void)__android_log_print(5, "ligma", __VA_ARGS__)) - -namespace ligma -{ - namespace hook - { - // - // TODO this doesnt work yet, needs to be debugged! - // - inline void* got_hook(elf32_hdr* module_base, const std::pair& module_info, void* new_ptr) - { - if (!module_base || !module_info.first || !module_info.second || !new_ptr) - return {}; - - const auto orig_module_base = dlopen(module_info.first, RTLD_NOW); - const auto orig_ptr = dlsym(orig_module_base, module_info.second); - - const auto shstrtab_header_offset = module_base->e_shoff + module_base->e_shstrndx * sizeof(elf32_shdr); - const auto shstr_header = reinterpret_cast(reinterpret_cast(module_base) + shstrtab_header_offset); - - const auto shstr_section = reinterpret_cast(module_base) + shstr_header->sh_offset; - auto section_header = reinterpret_cast(reinterpret_cast(module_base) + module_base->e_shoff); - - for (auto idx = 0u; idx < module_base->e_shnum; ++idx) - { - if (strcmp(shstr_section + section_header->sh_name, ".got")) - { - for (auto section_value = reinterpret_cast(module_base) + section_header->sh_offset; - section_value < reinterpret_cast(module_base) + section_header->sh_size; section_value += 0x8) - if (*reinterpret_cast(section_value) == orig_ptr) - *reinterpret_cast(section_value) = new_ptr; - break; - } - section_header++; - } - return orig_ptr; - } - } -} \ No newline at end of file diff --git a/ligma-cheat/ligma-cheat/hooks/xhook.h b/ligma-cheat/ligma-cheat/hooks/xhook.h new file mode 100644 index 000000000..93dd5b4cd --- /dev/null +++ b/ligma-cheat/ligma-cheat/hooks/xhook.h @@ -0,0 +1,50 @@ +// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. +// +// 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. +// + +// Created by caikelun on 2018-04-11. + +#ifndef XHOOK_H +#define XHOOK_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#define XHOOK_EXPORT __attribute__((visibility("default"))) + +int xhook_register(const char *pathname_regex_str, const char *symbol, + void *new_func, void **old_func) XHOOK_EXPORT; + +int xhook_ignore(const char *pathname_regex_str, const char *symbol) XHOOK_EXPORT; + +int xhook_refresh(int async) XHOOK_EXPORT; + +void xhook_clear() XHOOK_EXPORT; + +void xhook_enable_debug(int flag) XHOOK_EXPORT; + +void xhook_enable_sigsegv_protection(int flag) XHOOK_EXPORT; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ligma-cheat/ligma-cheat/libxhook.a b/ligma-cheat/ligma-cheat/libxhook.a new file mode 100644 index 0000000000000000000000000000000000000000..3212303e4dd060234f10c67d821a09e5c79c9280 GIT binary patch literal 54554 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 CLUb - + + @@ -159,7 +160,8 @@ Enabled - %(AdditionalDependencies) + + adb logcat -c @@ -178,7 +180,8 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per Enabled - %(AdditionalDependencies) + + adb logcat -c @@ -197,7 +200,8 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per Enabled - %(AdditionalDependencies) + + adb logcat -c @@ -221,7 +225,8 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per Enabled - %(AdditionalDependencies) + + adb logcat -c @@ -245,7 +250,8 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per Enabled - %(AdditionalDependencies) + + adb logcat -c @@ -269,7 +275,8 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per Enabled - %(AdditionalDependencies) + + adb logcat -c @@ -292,9 +299,7 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per c++1z Enabled - - %(AdditionalDependencies) - + adb logcat -c @@ -308,6 +313,10 @@ start cmd /k "title 'all logs' & adb logcat" adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.PermissionGrantActivity + + + + @@ -316,9 +325,7 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per c++1z Enabled - - %(AdditionalDependencies) - + adb logcat -c @@ -332,6 +339,10 @@ start cmd /k "title 'all logs' & adb logcat" adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.PermissionGrantActivity + + + + diff --git a/ligma-cheat/ligma-cheat/ligma-cheat.vcxproj.filters b/ligma-cheat/ligma-cheat/ligma-cheat.vcxproj.filters index 23b0ca6b6..454aa792f 100644 --- a/ligma-cheat/ligma-cheat/ligma-cheat.vcxproj.filters +++ b/ligma-cheat/ligma-cheat/ligma-cheat.vcxproj.filters @@ -39,9 +39,6 @@ headers\bypass - - headers\hooks - headers\hooks @@ -51,6 +48,10 @@ headers + + headers\hooks + + diff --git a/ligma-cheat/ligma-cheat/ligma.h b/ligma-cheat/ligma-cheat/ligma.h index 1407d69e2..1d7fef398 100644 --- a/ligma-cheat/ligma-cheat/ligma.h +++ b/ligma-cheat/ligma-cheat/ligma.h @@ -2,7 +2,6 @@ #include #include "utils/utils.h" #include "hooks/shithook.h" -#include "hooks/got_hook.h" #define LOGI(...) ((void)__android_log_print(4, "ligma", __VA_ARGS__)) #define LOGW(...) ((void)__android_log_print(5, "ligma", __VA_ARGS__)) \ No newline at end of file diff --git a/ligma-cheat/ligma-cheat/main.cpp b/ligma-cheat/ligma-cheat/main.cpp index 9c825a5ae..b2bfc83cb 100644 --- a/ligma-cheat/ligma-cheat/main.cpp +++ b/ligma-cheat/ligma-cheat/main.cpp @@ -1,22 +1,26 @@ #include -#include "bypass/bypass.h" -#include "SDK/Il2Cpp/Il2Cpp.h" -#include "SDK/Assembly-CSharp.dll/GameEngine.h" #include "SDK/Assembly-CSharp.dll/GameBase.h" +#include "SDK/Assembly-CSharp.dll/GameEngine.h" +#include "bypass/bypass.h" -#include "SDK/UnityEngine.dll/Includes/UnityEngine/Component.h" -#include "SDK/UnityEngine.dll/Includes/UnityEngine/Transform.h" -#include "SDK/UnityEngine.dll/Includes/UnityEngine/Screen.h" -#include "SDK/UnityEngine.dll/Includes/UnityEngine/Camera.h" -#include "SDK/UnityEngine.dll/Includes/UnityEngine/Physics.h" -#include "SDK/UnityEngine.dll/Includes/UnityEngine/RaycastHit.h" -#include "SDK/UnityEngine.dll/Includes/UnityEngine/Object.h" - -// just an example that this never gets called, ever -int get_localplayer_hook() +void test() { - LOGI("=========== get local player called!!!! ==========="); - return NULL; + LOGI("sleeping 10 seconds...."); + sleep(10); + while (true) + { + const auto currentWeapon = GameEngine::GamePlay::get_CurrentWeapon(); + LOGI("current Weapon = %p", currentWeapon); + + if (currentWeapon) + { + currentWeapon->AddCurrentAmmo(0x100); + currentWeapon->AddCarriedAmmo(0x100); + currentWeapon->set_MaxAmmoCount(0x1000); + sleep(10); + } + sleep(1); + } } __attribute__((constructor)) @@ -25,6 +29,7 @@ void init() ligma::bypass::init([&](const std::uintptr_t il2cpp_base) { LOGI("il2cpp base address = %p", il2cpp_base); - ligma::hook::make_hook(reinterpret_cast(il2cpp_base + 0x36F2600), reinterpret_cast(&get_localplayer_hook)); + if (Il2Cpp::Attach()) + std::thread(&test).detach(); }); } \ No newline at end of file diff --git a/ligma-cheat/ligma-cheat/utils/utils.cpp b/ligma-cheat/ligma-cheat/utils/utils.cpp index 52abb1408..4f0e04de7 100644 --- a/ligma-cheat/ligma-cheat/utils/utils.cpp +++ b/ligma-cheat/ligma-cheat/utils/utils.cpp @@ -1,5 +1,5 @@ #include "utils.h" -#include +#include namespace ligma { @@ -18,15 +18,26 @@ namespace ligma void iterate_memory(const std::function&, const std::string& protection)>& callback) { - std::fstream maps("/proc/self/maps"); - std::pair memory_range; - std::string page_perms; - while (maps >> memory_range.first >> memory_range.second >> page_perms) + + } + + std::uintptr_t get_module_base(const char* module_name) + { + const auto maps_handle = fopen("/proc/self/maps", "r"); + char line[512]; + while (fgets(line, sizeof line, maps_handle)) { - maps.ignore(std::numeric_limits::max(), '\n'); // skip to next line :) - callback(memory_range, page_perms); + std::uintptr_t base; + char tmp[64]; + sscanf(line, "%" PRIXPTR "-%*" PRIXPTR " %*s %*s %*s %*s %s", &base, tmp); + if (strstr(tmp, module_name)) + { + fclose(maps_handle); + return base; + } } - maps.close(); + fclose(maps_handle); + return NULL; } } } \ No newline at end of file diff --git a/ligma-cheat/ligma-cheat/utils/utils.h b/ligma-cheat/ligma-cheat/utils/utils.h index 10f2a73eb..614b8c715 100644 --- a/ligma-cheat/ligma-cheat/utils/utils.h +++ b/ligma-cheat/ligma-cheat/utils/utils.h @@ -7,6 +7,7 @@ namespace ligma { namespace utils { + std::uintptr_t get_module_base(const char* module_name); auto get_callbacks() -> std::map>*; void iterate_memory(const std::function&, const std::string& protection)>& callback); void on_image_load(const std::string& module_name, const std::function& callback);