SkillAgentSearch skills...

Titanox

A hooking framework, symbol rebinder and memory-manager for jailed IOS, All-In-One.

Install / Use

/learn @Ragekill3377/Titanox
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Titanox

Donations

USDT-TRC20 address: TGtQav9ockH1gnb4oqpJLHZJgjv65aEsQj

BNB-BSC address: 0x6a42D5375e77FF896E5fDD5B494Df9f9cAA08D78

SOLANA/SOL: 3HQw2KHZDFL3nEpFxvN5YZGxCqjBsLK5jyhHLZoJsq2q

USDC/BSC: 0x6a42D5375e77FF896E5fDD5B494Df9f9cAA08D78

LITECOIN/LTC: LZr52LM5EaWv7RF8GJY635woqwpxZK3zMJ

TRON/TRX: TRRNssMpSvDkGYq7qPq22Ff6vgFT4dBNwu

  • Do not send NFTs to this/these address/addresses.

-> SEND SOLANA NFTs to:

3HQw2KHZDFL3nEpFxvN5YZGxCqjBsLK5jyhHLZoJsq2q

-> FOR ETHEREUM/ETH NFTs:

0x6a42D5375e77FF896E5fDD5B494Df9f9cAA08D78

PayPal: @HKTRC email: killrage441@gmail.com Name: Haroon Khan

Titanox is a hooking framework for iOS. It utilizes fishhook for symbol rebinding and MemX for memory related tasks. This library supports function hooking, method swizzling, memory patching etc. It does not have any external dependencies and can be used on non-jailbroken/non-rooted IOS devices with full functionailty!!!

Titanox Discord Server

Join for support!

experimental: This framework also uses breakpoint hooks. Inspired by The Ellekit Team.

Features

beta function: brk hooking.

  • Breakpoint hooks: Apply upto maximum 6 hooks via breakpoints at runtime. -> Undetected*

  • Static Inline Hook & Patch: -> Patch unlimited addresses UNDER MAINTENANCE -> Hook unlimited addresses -> Be able to call orig in hooks -> Unlimited -> Drawback: need to manually replace binary (From documents directory)

  • Function Hooking (by symbol): Hook functions and rebind symbols (fishhook). FUNCTIONS MUST BE EXPORTED!!!

  • Virtual Function hooking: You can hook any pure C++ class virtual function with this. A wrapper for @Aethereux 's MemX. -> Unlimited -> Must be virtual -> By address

  • Method Swizzling: Replace methods in Objective-C classes.

  • Memory Patching: Modify memory contents safely. -> Read -> Write -> Patch (Insipred from Dobby's CodePatch, made to work on stock IOS)

  • Bool-Hooking: Toggle bool values in memory, to the opposite of their original state. bool symbol must be exposed.

  • Is Hooked: Check if a function is already hooked. This is done automatically.

  • Base Address & VM Address Slide Get: Get BaseAddress i.e header of the target library and the vm addr slide.

LOGS ARE SAVED TO DOCUMENT'S DIRECTORY AS TITANOX_LOGS.TXT. NO NEED TO USE NSLog or Console app to view logs! You can take logging from utils/utils.mm.

APIs:~

  • fishhook: A library for symbol rebinding used by @facebook. fishhook

  • MemX: A memory management library by @Aethereux. (Modified) MemX-Jailed

Documentation:~

Usage:~

Static Inline Hook (NEW):

A bit complex to use ->

  • Patch

  • Get patched binary

  • Replaced original binary with patched one

  • re-inject titanox + your tweak/library in the target, but this time the target must be the patched one

Required!

StaticInlineHook *hooker = [[StaticInlineHook alloc] initWithMachOName:@"hello.dylib"]; // whatever is name of target binary

Patching address (Need to activate later)

NSString *originalBytes = [hooker applyPatchAtVaddr:0x100003f20 // vm addr stuff
patchBytes:@"00008052C0035FD6"]; // mov & ret asm

Hook Function

void *runthishook = [hooker hookFunctionAtVaddr:0x100004000 withReplacement:(void *)&orig_target];
// you can call orig in the hook func

Activate patch

BOOL qw = [hooker activatePatchAtVaddr:0x100003f20 patchBytes:@"00008052C0035FD6"]; // make sure its same as addr patch init
if (qw) {
    // worked
}

Deactivate patch

BOOL wq = [hooker deactivatePatchAtVaddr:0x100003f20 patchBytes:@"00008052C0035FD6"]; // must be same as init patch
if (wq) {
    // worked
}

VMT (Virtual) Hook usage and helpers (NEW)

class QAZ {
public:
    virtual int do_shit(int v) {
        printf("%d\n", v);
        return v;
    }
    virtual ~QAZ() = default;
};

int mt_do_shit(QAZ* s, int v) {
    printf("Hooked value -> %d\n", v);
    return 69420;
}

void messaround() {
    QAZ* obj = new QAZ();

    void* hook = [TitanoxHook vmthookCreateWithNewFunction:(void*)&my_do_shit index:0];
    if (!hook) {
        //Titanox will auto log what went wrong and where.
        delete obj;
        return;
    }

    [TitanoxHook vmthookSwap:hook instance:(void*)obj]; // THIS actually does the hook. swaps vtable

    int res1 = obj->do_shit(5); // try calling with any value, will return 69420.
     
    // reset to original vtable 
    [TitanoxHook vmthookReset:hook instance:(void*)obj];

    int res2 = obj->do_shit(5);
    NSLog(@"This should be 5 -> %d", res2);

    [TitanoxHook vmthookDestroy:hook];

    void* inv = [TitanoxHook vmtinvokerCreateWithInstance:(void*)obj index:0];
    if (!inv) {
        // again it will auto log.
        delete obj;
        return;
    }
    
    // Just cast invoker to func ptr with same signature e.g: int(*)(CPPClass*, int)

    typedef int (*fn_t)(QAZ*, int);
    fn_t func = *(fn_t*)&inv;

    int res3 = func(obj, 10);
    NSLog(@"direct invoker call: %d", res3);
    
    // get rid of the caller
    [TitanoxHook vmtinvokerDestroy:inv];

    delete obj;
}
// You can call orig and hook as many funcs as you want safely.
// However, they must be virtual. If they aren't, use brk hooks.
// I'd reccommend using brk hooks as a last resort though.
// prioritise this
// Example: Let's say you can't get a class instance for some reason
// You can use brk hooks to hook it, get instance, unhook, and use that to hook whatever target function you have (virtual)

BRK Hook (Aarch64/arm64) FOR C/C++ FUNCTIONS BY ADDRESS

static void (*original_exit)(int) = NULL;

void hooked_exit(int status) {
    NSLog(@"[HOOK] _exit called with status: %d", status);

    // a bit difficult to call orig with brk hooks
    // copy orig func data, strip PACs and use that (if it works)
    return;
}

void hook_exit() {
    original_exit = (void (*)(int)) dlsym(RTLD_DEFAULT, "_exit");

    if (!original_exit) {
        NSLog(@"[ERROR] Failed to find _exit symbol");
        return;
    }

    if ([TitanoxHook addBreakpointAtAddress:(void *)original_exit withHook:(void *)hooked_exit]) {
        NSLog(@"[HOOK] _exit hooked successfully");
    } else {
        NSLog(@"[ERROR] Failed to hook _exit");
    }
}

void unhook_exit() {
    if (!original_exit) {
        NSLog(@"[ERROR] Cannot unhook _exit: original_exit is NULL");
        return;
    }

    if ([TitanoxHook removeBreakpointAtAddress:(void *)original_exit]) {
        NSLog(@"[HOOK] _exit unhooked successfully");
    } else {
        NSLog(@"[ERROR] Failed to unhook _exit");
    }
}

HAS a limit to 6 hooks. Unhooking frees those slots.

Function Hooking by fishhook (static) C/C++ Functions by SYMBOL Hook a function by symbol using fishhook (Will hook in main task process):

[TitanoxHook hookStaticFunction:"_funcsym" withReplacement:newFunction outOldFunction:&oldFunction];

Hook a function in a specific library:(Will hook in target library/Binary specified in 'inLibrary'.) Full name is required. i.e extension if any e.g .dylib. It auto loads in the target if not loaded in! Can be the main executable or a loaded library in the application.**

[TitanoxHook hookFunctionByName:"_Zn5Get6Ten" inLibrary:"ShooterGame" withReplacement:newFunction outOldFunction:&oldFunction];

Method Swizzling Swizzle a method in an objc class:

[TitanoxHook swizzleMethod:@selector(originalMethod) withMethod:@selector(swizzledMethod) inClass:[TargetClass class]];

Method Overriding Over-ride a method in an objc class with a new implementation:

[TitanoxHook overrideMethodInClass:[TargetClass class]
                          selector:@selector(targetMethod)
                   withNewFunction:newFunction
                 oldFunctionPointer:&oldFunction];

Memory Modifications R/W memory at specified addresses.

mach_vm_address_t targetAddress = 0x102345678;
uint8_t buffer[16] = {0};
mach_vm_size_t size = sizeof(buffer);

if ([TitanoxHook readMemoryAt:targetAddress buffer:buffer size:size]) {
    NSLog(@"worked.");
} else {
    NSLog(@"failed to read.");
}

// OR

if ([TitanoxHook MemXreadMemory:targetAddress buffer:buffer length:size]) {
    NSLog(@"worked");
} else {
    NSLog(@"couldn't read.");
}

Read String


uintptr_t stringAddress = 0x102;
size_t maxLen = 64;

NSString *readString = [TitanoxHook MemXreadString:stringAddress maxLength:maxLen];

if (readString) {
    NSLog(@"read string: %@", readString);
} else {
    NSLog(@"failed to read string.");
}

Write

mach_vm_address_t targetAddress = 0x1000000000;
uint8_t data[] = {0xdead, 0xdead, 0xdead, 0xdead};
mach_vm_size_t size = sizeof(data);

if ([TitanoxHook writeMemoryAt:targetAddress data:data size:size]) {
    NSLog(@"worked.");
} else {
    NSLog(@"failed.");
}

// OR

NSNumber *value = @(12345);
NSString *type = @"int";  // type of data ("int", "long", "uintptr_t", etc.)

[TitanoxHook MemXwriteMemory:targetAddress value:value type:type];

Is Address Valid?

uintptr_t address = 0x100;

if ([TitanoxHook MemXisValidPointer:address]) {
    NSLog(@"ptr 0x%lx is valid.", address);
} else {
    NSLog(@"ptr 0x%lx is invalid.", address);
}

Change Memory protections with custom vm functions

mach_vm_address_t targetAddress = 0x449ef78;  
mach_vm_size_t size = 0x1000;  // this should be sizeof target addr but just an example here
vm_prot_t newProtection = VM_PROT_READ | VM_PROT_WRITE;
BOOL setMax = NO;  // depends on your usage case

kern_return_t result = [TitanoxHook protectMemoryAt:targetAddress s
View on GitHub
GitHub Stars120
CategoryDevelopment
Updated4d ago
Forks15

Languages

Objective-C++

Security Score

100/100

Audited on Mar 22, 2026

No findings