currently not working... moved some stuff from bypass.cpp to

utils.h/.cpp and to shithook.h, this will allow for more modular code...
master
xerox 4 years ago
parent 167107fd95
commit bf63bdab4f

Binary file not shown.

Binary file not shown.

@ -173,6 +173,12 @@ public:
template <typename T = std::uintptr_t> T& m_weaponfiresound() { template <typename T = std::uintptr_t> T& m_weaponfiresound() {
return *(T*)((std::uintptr_t)this + 0x11C); return *(T*)((std::uintptr_t)this + 0x11C);
} }
void set_firespeed(float speed)
{
*(float*)((std::uintptr_t)this + 0x120) = speed;
}
template <typename T = float> T& m_firespeed() { template <typename T = float> T& m_firespeed() {
return *(T*)((std::uintptr_t)this + 0x120); return *(T*)((std::uintptr_t)this + 0x120);
} }

@ -1,6 +1,4 @@
#include "bypass.h" #include "bypass.h"
#include <link.h>
#include <dlfcn.h>
namespace ligma namespace ligma
{ {
@ -26,100 +24,16 @@ namespace ligma
ligma::utils::on_image_load("libtersafe.so", [&](const std::uintptr_t module_base) ligma::utils::on_image_load("libtersafe.so", [&](const std::uintptr_t module_base)
{ {
LOGI("libtersafe.so = %p", module_base); LOGI("libtersafe.so = %p", module_base);
ligma::hook::make_hook( LOGI("libtersafe.so handle = %p", dlopen("libtersafe.so", RTLD_NOLOAD));
reinterpret_cast<void*>(module_base + offset_ischeat_packet),
reinterpret_cast<void*>(&tss_sdk_ischeatpacket)
);
ligma::hook::make_hook(
reinterpret_cast<void*>(module_base + offset_tencent_init),
reinterpret_cast<void*>(&Java_com_tencent_tp_TssSdk_init)
);
/*ligma::hook::make_hook(
reinterpret_cast<void*>(module_base + 0x0013F3C),
reinterpret_cast<void*>(&tp2_sdk_ioctl)
);
ligma::hook::make_hook(
reinterpret_cast<void*>(module_base + 0x0014178),
reinterpret_cast<void*>(&tp2_sdk_init)
);
ligma::hook::make_hook(
reinterpret_cast<void*>(module_base + 0x0013ECC),
reinterpret_cast<void*>(&tss_sdk_regist_tss_info_receiver)
);*/
LOGI("installed libtersafe.so hooks!");
});
// 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<void*>(&Java_com_tencent_hawk_bridge_HawkNative_checkEmulator)
);
}); });
fopen_ptr = dlsym(dlopen("libc.so", RTLD_NOLOAD), "fopen"); 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"); system_prop_get = dlsym(dlopen("libc.so", RTLD_NOLOAD), "__system_property_get");
ligma::hook::make_hook(dlopen_ptr, reinterpret_cast<void*>(&dlopen_hook));
ligma::hook::make_hook(fopen_ptr, reinterpret_cast<void*>(&fopen_hook)); ligma::hook::make_hook(fopen_ptr, reinterpret_cast<void*>(&fopen_hook));
ligma::hook::make_hook(system_prop_get, reinterpret_cast<void*>(&system_property_hook)); ligma::hook::make_hook(system_prop_get, reinterpret_cast<void*>(&system_property_hook));
} }
void tss_sdk_regist_tss_info_receiver(int a1)
{
LOGI("tss_sdk_regist_tss_info_receiver called!! a1 = %p", a1);
}
int tp2_sdk_init(int a1)
{
LOGI("tp2 sdk init called! a1 = %p", a1);
return NULL;
}
int tp2_sdk_ioctl(int a1, int a2)
{
LOGI("tp2_sdk_ioctl called! a1 = %p, a2 = %p", a1, a2);
return NULL;
}
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<decltype(&Java_com_tencent_hawk_bridge_HawkNative_checkEmulator)>(
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<decltype(&tss_sdk_ischeatpacket)>(
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<decltype(&Java_com_tencent_tp_TssSdk_init)>(
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! // dont let a single lua script load!
// //
@ -149,34 +63,6 @@ namespace ligma
return result; return result;
} }
//
// this is used to gain code execution exactly when a module is loaded (for the first time)
//
__attribute__((noinline))
void* dlopen_hook(const char* filename, int flags)
{
dlopen_mutex.lock();
ligma::hook::disable(dlopen_ptr);
const auto result = dlopen(filename, reinterpret_cast<int>(RTLD_NEXT));
if(ligma::utils::get_callbacks()->size())
ligma::hook::enable(dlopen_ptr);
dlopen_mutex.unlock();
//
// if there is a callback for this module, call it and then remove it.
//
for (const auto& [file_key, callback] : *ligma::utils::get_callbacks())
{
if (strstr(filename, file_key.c_str()))
{
ligma::utils::get_callbacks()->erase(file_key);
callback(ligma::utils::get_module_base(file_key.c_str()));
break;
}
}
return result;
}
// //
// spoof all hwids to "what do you call nuts on your chin? a dick down your throat you fucking retard!" // spoof all hwids to "what do you call nuts on your chin? a dick down your throat you fucking retard!"
// //

@ -6,11 +6,7 @@
#include <sys/system_properties.h> #include <sys/system_properties.h>
#include "../ligma.h" #include "../ligma.h"
#define HWID_VALUE "what do you call nuts on your chin? a dick down your throat you fucking retard!" #define HWID_VALUE "NA"
#define offset_emulator_check 0x000D7B4
#define offset_ischeat_packet 0x00128E0
#define offset_mshook_function 0x0010358
#define offset_tencent_init 0x0021CAC
namespace ligma namespace ligma
{ {
@ -18,21 +14,11 @@ namespace ligma
{ {
inline void* fopen_ptr = nullptr; inline void* fopen_ptr = nullptr;
inline void* system_prop_get = nullptr; inline void* system_prop_get = nullptr;
inline void* dlopen_ptr = nullptr;
// every shithook you make you will need a mutex.
inline std::mutex fopen_mutex; inline std::mutex fopen_mutex;
inline std::mutex system_prop_mutex; inline std::mutex system_prop_mutex;
inline std::mutex dlopen_mutex;
void init(const std::function<void(std::uintptr_t)>& callback); void init(const std::function<void(std::uintptr_t)>& callback);
int tp2_sdk_ioctl(int a1, int a2);
int tp2_sdk_init(int a1);
void tss_sdk_regist_tss_info_receiver(int a1);
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); FILE* fopen_hook(const char* path, const char* mode);
int system_property_hook(const char* name, char* value); int system_property_hook(const char* name, char* value);
int load_bufferx_hook(void* L, const char* buff, size_t sz, const char* name, const char* mode); int load_bufferx_hook(void* L, const char* buff, size_t sz, const char* name, const char* mode);

@ -28,6 +28,8 @@
#include <memory> #include <memory>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <mutex>
#include <string.h>
#define PAGE_START(ptr) reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(ptr) >> 12 << 12) #define PAGE_START(ptr) reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(ptr) >> 12 << 12)
#define ARM_JMP_CODE 0xE51FF004 #define ARM_JMP_CODE 0xE51FF004
@ -91,10 +93,15 @@ namespace ligma
std::uint8_t org_bytes[sizeof(jmp_code)]; std::uint8_t org_bytes[sizeof(jmp_code)];
}; };
// this is jank, but needed because the OS isnt initalizing statics/inlined globals... :|
inline std::map<void*, std::unique_ptr<detour>>* get_hooks() inline std::map<void*, std::unique_ptr<detour>>* get_hooks()
{ {
static std::map<void*, std::unique_ptr<detour>> hooks{}; static std::map<void*, std::unique_ptr<detour>> hooks;
return &hooks;
}
inline std::map<std::pair<const std::string, const std::string>, void*>* get_dlsym_hook()
{
static std::map<std::pair<const std::string, const std::string>, void*> hooks{};
return &hooks; return &hooks;
} }
@ -133,5 +140,57 @@ namespace ligma
return; return;
get_hooks()->erase(addr); get_hooks()->erase(addr);
} }
inline std::mutex dlsym_mutex;
inline void* dlsym_ptr = nullptr;
__attribute__((noinline))
void* dlsym_bypass(void* handle, const char* symbol)
{
dlsym_mutex.lock();
ligma::hook::disable(dlsym_ptr);
const auto result =
reinterpret_cast<decltype(&dlsym_bypass)>(dlsym_ptr)(handle, symbol);
ligma::hook::enable(dlsym_ptr);
dlsym_mutex.unlock();
return result;
}
__attribute__((noinline))
void* dlsym_handler(void* handle, const char* symbol)
{
for (const auto& [so_data, hook_ptr] : *get_dlsym_hook())
if (strcmp(so_data.second.c_str(), symbol))
if (dlopen(so_data.first.c_str(), RTLD_NOLOAD) == handle)
return hook_ptr;
dlsym_mutex.lock();
ligma::hook::disable(dlsym_ptr);
const auto result = dlsym(handle, symbol);
ligma::hook::enable(dlsym_ptr);
dlsym_mutex.unlock();
return result;
}
void dlsym_hook(std::pair<const std::string&, const std::string&> symbol_data, void* function_ptr)
{
static std::once_flag once;
std::call_once(once, [&]()
{
make_hook(
dlsym(dlopen("libdl.so", RTLD_NOLOAD), "dlsym"),
reinterpret_cast<void*>(&dlsym_handler)
);
//
// this allows us to use "dlsym" anywhere in the code :)
//
make_hook(
reinterpret_cast<void*>(&dlsym),
reinterpret_cast<void*>(&dlsym_bypass)
);
});
get_dlsym_hook()->insert({ symbol_data, function_ptr });
}
} }
} }

@ -1,50 +0,0 @@
// 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

@ -37,16 +37,12 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="bypass\bypass.cpp" /> <ClCompile Include="bypass\bypass.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="SDK\il2cpp\il2cpp.cpp" />
<ClCompile Include="utils\utils.cpp" /> <ClCompile Include="utils\utils.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="bypass\bypass.h" /> <ClInclude Include="bypass\bypass.h" />
<ClInclude Include="hooks\shithook.h" /> <ClInclude Include="hooks\shithook.h" />
<ClInclude Include="hooks\xhook.h" />
<ClInclude Include="ligma.h" /> <ClInclude Include="ligma.h" />
<ClInclude Include="SDK\il2cpp\il2cpp.h" />
<ClInclude Include="SDK\il2cpp\il2cpp_type.h" />
<ClInclude Include="utils\utils.h" /> <ClInclude Include="utils\utils.h" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
@ -297,6 +293,8 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CppLanguageStandard>c++1z</CppLanguageStandard> <CppLanguageStandard>c++1z</CppLanguageStandard>
<ExceptionHandling>Enabled</ExceptionHandling> <ExceptionHandling>Enabled</ExceptionHandling>
<CLanguageStandard>gnu11</CLanguageStandard>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link /> <Link />
<PostBuildEvent> <PostBuildEvent>
@ -323,6 +321,8 @@ adb shell am start -n com.activision.callofduty.shooter/com.tencent.tmgp.cod.Per
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CppLanguageStandard>c++1z</CppLanguageStandard> <CppLanguageStandard>c++1z</CppLanguageStandard>
<ExceptionHandling>Enabled</ExceptionHandling> <ExceptionHandling>Enabled</ExceptionHandling>
<CLanguageStandard>gnu11</CLanguageStandard>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile> </ClCompile>
<Link /> <Link />
<PostBuildEvent> <PostBuildEvent>

@ -33,7 +33,6 @@
<ClCompile Include="utils\utils.cpp"> <ClCompile Include="utils\utils.cpp">
<Filter>source\utils</Filter> <Filter>source\utils</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="SDK\il2cpp\il2cpp.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="bypass\bypass.h"> <ClInclude Include="bypass\bypass.h">
@ -48,10 +47,5 @@
<ClInclude Include="ligma.h"> <ClInclude Include="ligma.h">
<Filter>headers</Filter> <Filter>headers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="hooks\xhook.h">
<Filter>headers\hooks</Filter>
</ClInclude>
<ClInclude Include="SDK\il2cpp\il2cpp.h" />
<ClInclude Include="SDK\il2cpp\il2cpp_type.h" />
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ShowAllFiles>true</ShowAllFiles> <ShowAllFiles>false</ShowAllFiles>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

@ -4,77 +4,11 @@
#include <assembly-csharp.dll/gameengine.h> #include <assembly-csharp.dll/gameengine.h>
#include "bypass/bypass.h" #include "bypass/bypass.h"
//
// ALL OF THIS CODE STINKS! THIS CODE IS JUST TEST CODE AND PROBABLY WILL NOT WORK! YOU NEED TO GET GAME STATE/ROUND STATE/ROUND CHANGE IN ORDER NOT TO CRASH!
//
namespace dogshit
{
bool is_pointer_valid(void* p) {
/* get the page size */
size_t page_size = sysconf(_SC_PAGESIZE);
/* find the address of the page that contains p */
void* base = (void*)((((size_t)p) / page_size) * page_size);
/* call msync, if it returns non-zero, return false */
return msync(base, page_size, MS_ASYNC) == 0;
}
using namespace std::chrono_literals;
void test()
{
LOGI("sleeping 10 seconds....");
sleep(10);
std::atomic<bool> is_in_game;
while (true)
{
const auto game_base = gameengine::gameplay::get_game<gamebase::basegame*>();
const auto local_pawn = gameengine::gameplay::get_localpawn<gamebase::pawn*>();
LOGI("local_pawn = %p, game_base = %p", local_pawn, game_base);
if (is_pointer_valid(local_pawn) && is_pointer_valid(game_base))
{
if (!is_in_game.exchange(true))
{
sleep(10);
LOGI("sleeping 10 seconds....");
}
const auto enemy_pawns = game_base->enemypawns<il2cpp_list<gamebase::pawn*>*>();
if (is_pointer_valid(enemy_pawns))
{
LOGI("enemy_pawns = %p", enemy_pawns);
const auto pawns = enemy_pawns->get_items();
if (is_pointer_valid(pawns))
{
LOGI("pawns = %p", pawns);
for (auto idx = 0u; idx < enemy_pawns->get_size(); ++idx)
{
if (!is_pointer_valid(enemy_pawns) || !is_pointer_valid(pawns))
break;
const auto target = pawns[idx];
if (is_pointer_valid(target) && is_pointer_valid(local_pawn))
{
LOGI("target = %p", target);
local_pawn->set_location(target->get_headposition());
}
}
}
}
}
else
is_in_game.exchange(false);
std::this_thread::sleep_for(0.1s);
}
}
}
__attribute__((constructor)) __attribute__((constructor))
void init() void init()
{ {
ligma::bypass::init([&](const std::uintptr_t il2cpp_base) ligma::bypass::init([&](const std::uintptr_t il2cpp_base)
{ {
LOGI("il2cpp base address = %p", il2cpp_base); LOGI("il2cpp base address = %p", il2cpp_base);
if (il2cpp::attach())
std::thread(&dogshit::test).detach();
}); });
} }

@ -1,5 +1,4 @@
#include "utils.h" #include "utils.h"
#include <inttypes.h>
namespace ligma namespace ligma
{ {
@ -7,6 +6,13 @@ namespace ligma
{ {
void on_image_load(const std::string& module_name, const std::function<void(const std::uintptr_t)>& callback) void on_image_load(const std::string& module_name, const std::function<void(const std::uintptr_t)>& callback)
{ {
static std::once_flag once;
std::call_once(once, [&]() {
ligma::hook::make_hook(
dlsym(dlopen("libdl.so", RTLD_NOLOAD), "dlopen"),
reinterpret_cast<void*>(&dlopen_handler)
);
});
get_callbacks()->insert({ module_name, callback }); get_callbacks()->insert({ module_name, callback });
} }
@ -16,11 +22,6 @@ namespace ligma
return &callback_map; return &callback_map;
} }
void iterate_memory(const std::function<void(const std::pair<std::uintptr_t, std::uintptr_t>&, const std::string& protection)>& callback)
{
}
std::uintptr_t get_module_base(const char* module_name) std::uintptr_t get_module_base(const char* module_name)
{ {
const auto maps_handle = fopen("/proc/self/maps", "r"); const auto maps_handle = fopen("/proc/self/maps", "r");
@ -39,5 +40,30 @@ namespace ligma
fclose(maps_handle); fclose(maps_handle);
return NULL; return NULL;
} }
__attribute__((noinline))
void* dlopen_handler(const char* filename, int flags)
{
dlopen_hook.second.lock();
ligma::hook::disable(dlopen_hook.first);
const auto result = dlopen(filename, reinterpret_cast<int>(RTLD_NEXT));
if (ligma::utils::get_callbacks()->size())
ligma::hook::enable(dlopen_hook.first);
dlopen_hook.second.unlock();
//
// if there is a callback for this module, call it and then remove it.
//
for (const auto& [file_key, callback] : *ligma::utils::get_callbacks())
{
if (strstr(filename, file_key.c_str()))
{
ligma::utils::get_callbacks()->erase(file_key);
callback(ligma::utils::get_module_base(file_key.c_str()));
break;
}
}
return result;
}
} }
} }

@ -2,14 +2,19 @@
#include <functional> #include <functional>
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <inttypes.h>
#include <dlfcn.h>
#include "../hooks/shithook.h"
namespace ligma namespace ligma
{ {
namespace utils namespace utils
{ {
inline std::pair<void*, std::mutex> dlopen_hook;
std::uintptr_t get_module_base(const char* module_name); std::uintptr_t get_module_base(const char* module_name);
auto get_callbacks() -> std::map<std::string, std::function<void(const std::uintptr_t)>>*; auto get_callbacks() -> std::map<std::string, std::function<void(const std::uintptr_t)>>*;
void iterate_memory(const std::function<void(const std::pair<std::uintptr_t, std::uintptr_t>&, const std::string& protection)>& callback);
void on_image_load(const std::string& module_name, const std::function<void(const std::uintptr_t)>& callback); void on_image_load(const std::string& module_name, const std::function<void(const std::uintptr_t)>& callback);
void dlsym_hook(const std::string& symbol_name, void* function_ptr);
void* dlopen_handler(const char* filename, int flags);
} }
} }
Loading…
Cancel
Save