Ragekill3377 / Titanox

A hooking framework, symbol rebinder and memory-manager for jailed IOS, All-In-One.
8 stars 0 forks source link

Example #1

Closed Quangcha closed 4 weeks ago

Quangcha commented 1 month ago

Can u give some examples how to use it in imgui? Thank you so much

Quangcha commented 1 month ago

My error when i add [TitanoxHook initializeMemoryEngine]; rootfs/private/var/mobile/Containers/Shared/AppGroup/.jbroot-25394E379BEB7A6F/var/mobile/theos/LQ5/Cheat/Patches.h:18:2: error: missing '[' at start of message send expression [TitanoxHook initializeMemoryEngine]; ^ [ /rootfs/private/var/mobile/Containers/Shared/AppGroup/.jbroot-25394E379BEB7A6F/var/mobile/theos/LQ5/Cheat/Patches.h:18:37: error: expected ']' [TitanoxHook initializeMemoryEngine]; ^ /rootfs/private/var/mobile/Containers/Shared/AppGroup/.jbroot-25394E379BEB7A6F/var/mobile/theos/LQ5/Cheat/Patches.h:18:1: note: to match this '[' [TitanoxHook initializeMemoryEngine]; ^ /rootfs/private/var/mobile/Containers/Shared/AppGroup/.jbroot-25394E379BEB7A6F/var/mobile/theos/LQ5/Cheat/Patches.h:18:1: error: expected unqualified-id [TitanoxHook initializeMemoryEngine]; ^ 3 errors generated.

Ragekill3377 commented 1 month ago

This is not an error with Titanox. This is a syntax error in your own code. Why is this in Patches.h? What template are you using?

The memory engine is automatically initialised in the functions which use memory. Check the source code in libtitanox/main.mm you will see that the memory engine is already initialized. if you want to implement your own functions based on the APIs, you can do that aswell. I have to update the memory engine aswell as the developer of it has recently made a new update for it, so titanox will be updated accordingly.

For example in the inline hooking:


+ (void)hookFunctionByName:(const char *)symbol inLibrary:(const char *)libName withReplacement:(void *)replacement outOldFunction:(void **)oldFunction {
    NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
    NSString *libPath = [bundlePath stringByAppendingPathComponent:[NSString stringWithUTF8String:libName]];
    void *handle = dlopen([libPath UTF8String], RTLD_NOW | RTLD_NOLOAD);

    if (!handle) {
        NSLog(@"Failed to open library: %s", libName);
        return;
    }

    void *originalFunction = dlsym(handle, symbol);
    if (!originalFunction) {
        NSLog(@"Failed to find symbol: %s", symbol);
        dlclose(handle);
        return;
    }

    if ([self isFunctionHooked:symbol withOriginal:originalFunction inLibrary:libName]) {
        NSLog(@"Warning: Function %s is already hooked.", symbol);
        dlclose(handle);
        return;
    }

    *oldFunction = originalFunction;

    // init mem-engine if not done yet.
    [self initializeMemoryEngine];

    // mem-write
    if (memoryEngine) {
        memoryEngine->CGPWriteMemory((long)originalFunction, &replacement, sizeof(replacement));
    }

    dlclose(handle);
    NSLog(@"Successfully hooked %s in library %s", symbol, libName);
}

you can see that the memory engine is already initialized. So no need to init it in the functions because it’s automatically done. If you would want to use the engine globally though, THEN you’d do that. simply, just an error in your own code. Example usage is above. Thanks.

Ragekill3377 commented 1 month ago

Closed as: Syntax error, Titanox has no issues currently,

Quangcha commented 1 month ago

I'm currently working on hooking the following class and function:

public class LVActorLinker : LActorComponent // TypeDefIndex: 13365
{
    // ...................
    // RVA: 0x53319F0 Offset: 0x53319F0 VA: 0x53319F0
    public bool SetVisible(COM_PLAYERCAMP camp, bool bVisible, bool forceSync = false) { }
    // ...................
}

I’m using an ImGui template and trying to hook this method into UnityFramework. Below is my attempt:

// original function pointer
bool (*SetVisible)(void *instance, void* camp, bool bVisible, bool forceSync);
// new hooked function
bool _SetVisible(void *instance, void* camp, bool bVisible, bool forceSync)
{
    if(map) // Assuming 'map' is a global variable or condition
    {
        bVisible = true; // Force visibility to true if condition is met
    }
    return SetVisible(instance, camp, bVisible, forceSync); // Call original function
}

I want to hook this function properly. Can you help with any suggestions or improvements for hooking this method into UnityFramework?

Ragekill3377 commented 1 month ago

I'm currently working on hooking the following class and function:

public class LVActorLinker : LActorComponent // TypeDefIndex: 13365
{
    // ...................
    // RVA: 0x53319F0 Offset: 0x53319F0 VA: 0x53319F0
    public bool SetVisible(COM_PLAYERCAMP camp, bool bVisible, bool forceSync = false) { }
    // ...................
}

I’m using an ImGui template and trying to hook this method into UnityFramework. Below is my attempt:

// original function pointer
bool (*SetVisible)(void *instance, void* camp, bool bVisible, bool forceSync);
// new hooked function
bool _SetVisible(void *instance, void* camp, bool bVisible, bool forceSync)
{
    if(map) // Assuming 'map' is a global variable or condition
    {
        bVisible = true; // Force visibility to true if condition is met
    }
    return SetVisible(instance, camp, bVisible, forceSync); // Call original function
}

I want to hook this function properly. Can you help with any suggestions or improvements for hooking this method into UnityFramework?


void invis()
{
[Titanox hookStaticFunction:"_ZN13LVActorLinker11SetVisibleE6COM_PLAYERCAMPbbb" // Replace with the actual symbol name. From a decompiler or something. You can also use LHHookFunction
            withReplacement:(void *)&_SetVisible
            outOldFunction:(void **)&originalSetVisible];

}


This is just an example, you can try out different things.
also, is the attempt you did AI generated? It seems so.
just hook the function with fishhook (static func hooking) or LHHookFunction in Titanox.
Quangcha commented 1 month ago

Thank you for your response. I use AI for translation because my English is not good.

So, if I have a similar code:

Copy code
public class GameSettings // TypeDefIndex: 21563 
{
// RVA: 0x5E3AD60 Offset: 0x5E3AD60 VA: 0x5E3AD60
    public static bool IsIPadDevice() { }
}

Then the hookStaticFunction would be: _ZN12GameSettings13IsIPadDeviceEb, right?

Thank you very much.

Ragekill3377 commented 1 month ago

Thank you for your response. I use AI for translation because my English is not good.

So, if I have a similar code:

Copy code
public class GameSettings // TypeDefIndex: 21563 
{
// RVA: 0x5E3AD60 Offset: 0x5E3AD60 VA: 0x5E3AD60
    public static bool IsIPadDevice() { }
}

Then the hookStaticFunction would be: _ZN12GameSettings13IsIPadDeviceEb, right?

Thank you very much.

Yes, I’d say so. You can double check this in a decompiler aswell. Just curious, what game is this? you can also directly use fishhook or CGuardMemory to hook this aswell, CGuardMemory will be updated today with inbuilt hooks.

just make sure the mangled symbol is correct. As I said double-check this in a decompiler like Ghidra.

Quangcha commented 1 month ago

Thank you for your response. I use AI for translation because my English is not good. So, if I have a similar code:

Copy code
public class GameSettings // TypeDefIndex: 21563 
{
// RVA: 0x5E3AD60 Offset: 0x5E3AD60 VA: 0x5E3AD60
    public static bool IsIPadDevice() { }
}

Then the hookStaticFunction would be: _ZN12GameSettings13IsIPadDeviceEb, right? Thank you very much.

Yes, I’d say so. You can double check this in a decompiler aswell. Just curious, what game is this? you can also directly use fishhook or CGuardMemory to hook this aswell, CGuardMemory will be updated today with inbuilt hooks.

The game is Arena of Valor. I used Il2CppDumper to dump the file. I have the dump.cs file but don’t know where to find the mangling symbols. Sorry, I’m new to this. Could you help me please?

Ragekill3377 commented 1 month ago

Thank you for your response. I use AI for translation because my English is not good. So, if I have a similar code:

Copy code
public class GameSettings // TypeDefIndex: 21563 
{
// RVA: 0x5E3AD60 Offset: 0x5E3AD60 VA: 0x5E3AD60
    public static bool IsIPadDevice() { }
}

Then the hookStaticFunction would be: _ZN12GameSettings13IsIPadDeviceEb, right? Thank you very much.

Yes, I’d say so. You can double check this in a decompiler aswell. Just curious, what game is this? you can also directly use fishhook or CGuardMemory to hook this aswell, CGuardMemory will be updated today with inbuilt hooks.

The game is Arena of Valor. I used Il2CppDumper to dump the file. I have the dump.cs file but don’t know where to find the mangling symbols. Sorry, I’m new to this. Could you help me please?

The symbols are mangled for cpp functions. You can put the executable/library of your target game (decrypted) in a decompile such as Ghidra, analyse the binary using the analysis feature in it, then search for the symbol names.

Quangcha commented 1 month ago

Thank you for your response. I use AI for translation because my English is not good. So, if I have a similar code:

Copy code
public class GameSettings // TypeDefIndex: 21563 
{
// RVA: 0x5E3AD60 Offset: 0x5E3AD60 VA: 0x5E3AD60
    public static bool IsIPadDevice() { }
}

Then the hookStaticFunction would be: _ZN12GameSettings13IsIPadDeviceEb, right? Thank you very much.

Yes, I’d say so. You can double check this in a decompiler aswell. Just curious, what game is this? you can also directly use fishhook or CGuardMemory to hook this aswell, CGuardMemory will be updated today with inbuilt hooks.

The game is Arena of Valor. I used Il2CppDumper to dump the file. I have the dump.cs file but don’t know where to find the mangling symbols. Sorry, I’m new to this. Could you help me please?

The symbols are mangled for cpp functions. You can put the executable/library of your target game (decrypted) in a decompile such as Ghidra, analyse the binary using the analysis feature in it, then search for the symbol names.

I have Ida Pro, I searched symbol name, but it don't have anything like _ZN13LVActorLinker............... Is there any way to use the class + function name + parameter instead of the mangled symbol?

Ragekill3377 commented 1 month ago

Thank you for your response. I use AI for translation because my English is not good. So, if I have a similar code:

Copy code
public class GameSettings // TypeDefIndex: 21563 
{
// RVA: 0x5E3AD60 Offset: 0x5E3AD60 VA: 0x5E3AD60
    public static bool IsIPadDevice() { }
}

Then the hookStaticFunction would be: _ZN12GameSettings13IsIPadDeviceEb, right? Thank you very much.

Yes, I’d say so. You can double check this in a decompiler aswell. Just curious, what game is this? you can also directly use fishhook or CGuardMemory to hook this aswell, CGuardMemory will be updated today with inbuilt hooks.

The game is Arena of Valor. I used Il2CppDumper to dump the file. I have the dump.cs file but don’t know where to find the mangling symbols. Sorry, I’m new to this. Could you help me please?

The symbols are mangled for cpp functions. You can put the executable/library of your target game (decrypted) in a decompile such as Ghidra, analyse the binary using the analysis feature in it, then search for the symbol names.

I have Ida Pro, I searched symbol name, but it don't have anything like _ZN13LVActorLinker............... Is there any way to use the class + function name + parameter instead of the mangled symbol?

Just search isIpadDevice and see if it comes up, or use another decompiler like Ghidra. in the implementation of the game the function would be GameSettings::IsIpadDevice

this is a cpp func, and the name is indeed mangled, so you would require the mangled symbol.

make sure the binary is decrypted whilst analysing aswell.

Ragekill3377 commented 1 month ago

If you REALLY need to get the mangled symbols, I can make a tool for that.

Quangcha commented 1 month ago

If you REALLY need to get the mangled symbols, I can make a tool for that.

I really need it. Thank you so much. i used Ghidra. And i searched. 2 function:


                         *                          FUNCTION                          *
                         **************************************************************
                         undefined NucleusDrive.Logic.LVActorLinker$$SetVisible()
         undefined         w0:1           <RETURN>
                         NucleusDrive.Logic.LVActorLinker$$SetVisible    XREF[1]:     0924e699(*)  
    053319f0 f8              ??         F8h

and


                         *                          FUNCTION                          *
                         **************************************************************
                         undefined Assets.Scripts.Framework.GameSettings$$IsIPadD
         undefined         w0:1           <RETURN>
                         Assets.Scripts.Framework.GameSettings$$IsIPadD  XREF[1]:     0925f08c(*)  
    05e3ad60 ff              ??         FFh

How can i use it? I'm trying with Unityframework - game : Arena of valor

Ragekill3377 commented 4 weeks ago

Here is the code for my demangler: In main.mm:

#import <substrate.h>
#import <Foundation/Foundation.h>
#import <dlfcn.h>
#import <mach-o/dyld.h>
#import <mach-o/getsect.h>
#include <sys/stat.h>
#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

bool isJailbroken() {
    return ([[NSFileManager defaultManager] fileExistsAtPath:@"/usr/lib/TweakInject"] ||
            [[NSFileManager defaultManager] fileExistsAtPath:@"/var/jb"]);
}

const char* getTargetArchitecture(uint32_t magic) {
    switch (magic) {
        case MH_MAGIC_64:
            return "arm64";
        case MH_MAGIC:
            return "arm64e";
        default:
            return "unknown";
    }
}

size_t getFileSize(const char* path) {
    struct stat st;
    if (stat(path, &st) == 0) {
        return st.st_size;
    }
    return 0;
}

void startRetrieving() {

    const char *mainBinaryPath = _dyld_get_image_name(0);
    void *handle = dlopen(mainBinaryPath, RTLD_NOW | RTLD_NOLOAD);
    if (!handle) {
        cerr << "Failed to open main binary: " << dlerror() << endl;
        return;
    }

    struct mach_header_64 *header = (struct mach_header_64*)_dyld_get_image_header(0);
    struct symtab_command *symtab = nullptr;

    struct load_command *loadCmd = (struct load_command*)((char*)header + sizeof(struct mach_header_64));
    for (uint32_t i = 0; i < header->ncmds; i++) {
        if (loadCmd->cmd == LC_SYMTAB) {
            symtab = (struct symtab_command *)loadCmd;
            break;
        }
        loadCmd = (struct load_command *)((char*)loadCmd + loadCmd->cmdsize);
    }

    if (!symtab) {
        cerr << "Symbol table not found." << endl;
        dlclose(handle);
        return;
    }

    struct nlist_64 *symbolTable = (struct nlist_64 *)((char*)header + symtab->symoff);
    const char *stringTable = (const char*)header + symtab->stroff;

    vector<string> mangledSymbols;

    for (uint32_t i = 0; i < symtab->nsyms; i++) {
        const char *symbolName = &stringTable[symbolTable[i].n_un.n_strx];

        // mangled cpp funcs being with '_Z'
        if (strncmp(symbolName, "_Z", 2) == 0) {
            mangledSymbols.push_back(symbolName);
        }
    }

    dlclose(handle);

    const char* arch = getTargetArchitecture(header->magic);
    bool jailbroken = isJailbroken();
    size_t fileSize = getFileSize(mainBinaryPath);
    size_t totalExports = mangledSymbols.size();

    NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = paths[0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"MangledFunctions.hpp"];
    ofstream outFile([filePath UTF8String]);

    outFile << "#pragma once\n";
    outFile << "/*\n";
    outFile << " * imangle V1.0\n";
    outFile << " * Target Architecture: " << arch << "\n";
    outFile << " * Jailbroken: " << (jailbroken ? "YES" : "NO") << "\n";
    outFile << " * Size: " << fileSize << " bytes\n";
    outFile << " * Total Exported Mangled Symbols: " << totalExports << "\n";
    outFile << " */\n\n";

    for (size_t i = 0; i < mangledSymbols.size(); ++i) {
        outFile << "#define mangledfunc" << (i + 1) << " " << mangledSymbols[i] << "\n";
    }
    outFile.close();

    cout << "Destination: " << [filePath UTF8String] << endl;
}

int main() {
    @autoreleasepool {
        startRetrieving();
    }
    return 0;
}

Or, you could just copy this and the includes in your main source file, and call it in an ImGui::Button As:

        if (ImGui::Button("Dump Demangled names")) {
            startRetrieving();
            return;
        }

I've compiled it already in an imgui menu I made, so you can use the file attached: P.S: It is in a .zip format. extract it to get the devtool.dylib, and inject that into your game aswell as libsubstrate.dylib if not already. I've had to zip it because github won't let me upload it as a .deb or .dylib.

devtool.dylib.zip

libsubstrate.dylib.zip

libsubstrate.dylib to be injected, as it relies on that to load in. If its already present, then no need.

Ragekill3377 commented 4 weeks ago

Also, please send the .hpp once done. I also want to check it out :p I WILL be closing this issue aswell, please contact me on discord since this is getting off-topic.

ragekill_3377

This is my discord username. Send me a friend request and I'll accept.