#!/usr/bin/env python3
"""
TS3Hook Pattern Finder for TeamSpeak 3.6.2-3.6.3
This script finds the exact byte patterns needed for hooking in your ts3client_win64.exe
"""

import sys
import os

def find_pattern(data, pattern, mask):
    """Find a byte pattern in binary data with a mask."""
    pattern_bytes = pattern
    mask_bytes = mask

    matches = []
    data_len = len(data)
    pattern_len = len(pattern_bytes)

    for i in range(data_len - pattern_len):
        found = True
        for j in range(pattern_len):
            if mask_bytes[j] != ord('?') and data[i + j] != pattern_bytes[j]:
                found = False
                break
        if found:
            matches.append(i)

    return matches

def bytes_from_pattern_string(pattern_str):
    """Convert pattern string to bytes."""
    return bytes([int(pattern_str[i:i+2], 16) for i in range(0, len(pattern_str), 2)])

def main():
    if len(sys.argv) != 2:
        print("Usage: python pattern_finder.py <path_to_ts3client_win64.exe>")
        sys.exit(1)

    binary_path = sys.argv[1]

    if not os.path.exists(binary_path):
        print(f"Error: File not found: {binary_path}")
        sys.exit(1)

    print(f"Analyzing: {binary_path}")
    print(f"File size: {os.path.getsize(binary_path)} bytes\n")

    with open(binary_path, 'rb') as f:
        data = f.read()

    # Known patterns from different TS3 versions (x64 only)
    patterns = {
        "IN_HOOK_1_OLD": {
            "pattern": "498B4E50488B01C64424200x004D8B4E584D8BC6488BD3FF5020EB",
            "mask": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
            "desc": "Packet IN Hook 1 (TS3 3.1.x - 3.5.x)"
        },
        "IN_HOOK_2_OLD": {
            "pattern": "498B4F50488B01C64424200x004D8B4F584D8BC7488BD3FF502041",
            "mask": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
            "desc": "Packet IN Hook 2 (TS3 3.1.x - 3.5.x)"
        },
        "IN_HOOK_1_NEW": {
            "pattern": "498B4E50488B014533C088442420004D8B4E584D8BC6488BD3FF5020",
            "mask": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "desc": "Packet IN Hook 1 (TS3 3.6.x - XOR variant)"
        },
        "IN_HOOK_2_NEW": {
            "pattern": "498B4F50488B014533C088442420004D8B4F584D8BC7488BD3FF5020",
            "mask": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "desc": "Packet IN Hook 2 (TS3 3.6.x - XOR variant)"
        },
        "OUT_HOOK_1_OLD": {
            "pattern": "89450083F8010F94C1884C24448007C2440",
            "mask": "xxxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 1 (TS3 3.1.x - 3.5.x)"
        },
        "OUT_HOOK_2_OLD": {
            "pattern": "8945E083F8010F94C1884C24508007C2440",
            "mask": "xxxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 2 (TS3 3.1.x - 3.5.x)"
        },
        "OUT_HOOK_3_OLD": {
            "pattern": "488B10488954245048895424784889580808",
            "mask": "xxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 3 (TS3 3.1.x - 3.5.x)"
        },
        "OUT_HOOK_4_OLD": {
            "pattern": "8985E009000041003BC6410F94C4807C244000",
            "mask": "xxxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 4 (TS3 3.1.x - 3.5.x)"
        },
        "OUT_HOOK_1_NEW": {
            "pattern": "89450083F8010F94C1884C24488007C2440",
            "mask": "xxxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 1 (TS3 3.6.x - offset variant)"
        },
        "OUT_HOOK_2_NEW": {
            "pattern": "8945D883F8010F94C1884C24508007C2440",
            "mask": "xxxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 2 (TS3 3.6.x - offset variant)"
        },
        "OUT_HOOK_3_NEW": {
            "pattern": "488B10488954245848895424804889580808",
            "mask": "xxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 3 (TS3 3.6.x - offset variant)"
        },
        "OUT_HOOK_4_NEW": {
            "pattern": "8985D009000041003BC6410F94C4807C244000",
            "mask": "xxxxxxxxxxxxxxxxxx",
            "desc": "Packet OUT Hook 4 (TS3 3.6.x - offset variant)"
        },
    }

    print("=" * 80)
    print("SCANNING FOR PATTERNS...")
    print("=" * 80)

    found_patterns = {}

    for name, info in patterns.items():
        pattern_hex = info["pattern"].replace("0x00", "00")
        pattern_bytes = bytes.fromhex(pattern_hex)
        mask_bytes = info["mask"].encode()

        matches = find_pattern(data, pattern_bytes, mask_bytes)

        if matches:
            print(f"\n[FOUND] {info['desc']}")
            print(f"  Pattern: {name}")
            print(f"  Offset(s): {', '.join(f'0x{m:X}' for m in matches)}")
            found_patterns[name] = matches
        else:
            print(f"\n[NOT FOUND] {info['desc']}")

    print("\n" + "=" * 80)
    print("SUMMARY")
    print("=" * 80)

    if found_patterns:
        print(f"\nFound {len(found_patterns)} pattern(s) in the binary.\n")

        # Determine version based on found patterns
        has_old = any("OLD" in k for k in found_patterns.keys())
        has_new = any("NEW" in k for k in found_patterns.keys())

        if has_new and not has_old:
            print("✓ This appears to be TeamSpeak 3.6.x (new patterns found)")
        elif has_old and not has_new:
            print("✓ This appears to be TeamSpeak 3.1.x - 3.5.x (old patterns found)")
        elif has_old and has_new:
            print("⚠ Both old and new patterns found - unusual")

        print("\nNext steps:")
        print("1. Copy the found pattern offsets")
        print("2. Update the IN_HOOKS[] and OUT_HOOKS[] arrays in dllmain.cpp")
        print("3. Recompile TS3Hook with the correct patterns for your version")
    else:
        print("\n✗ No known patterns found in this binary.")
        print("\nThis could mean:")
        print("  - This is a newer TS3 version with different patterns")
        print("  - The binary is packed or modified")
        print("  - You need to use a disassembler (x64dbg/IDA) to find new patterns")
        print("\nRecommended: Use x64dbg to find the packet dispatch functions manually")

    print("\n" + "=" * 80)

if __name__ == "__main__":
    main()

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: