#!/bin/bash

if [ -z "$1" ]; then
    echo "Usage: $0 <fichier_binaire>"
    exit 1
fi

TARGET_FILE="$1"

# Sauvegarde de sécurité
cp "$TARGET_FILE" "${TARGET_FILE}.bak"

echo "[*] Recherche et application du second patch (BL dynamique)..."

python3 -c "
import sys
import struct

file_path = sys.argv[1]
with open(file_path, 'rb') as f:
    data = bytearray(f.read())

# --- 1er PATCH (Précédent) ---
patterns_p1 = [
    (b'\x30\x62\x00\x21\xF2\x6B\x07\x20', 'Pattern 1.1'),
    (b'\x20\x62\x00\x21\xE2\x6B\x07\x20', 'Pattern 1.2'),
]
for pattern, name in patterns_p1:
    offset = data.find(pattern)
    if offset != -1:
        data[offset:offset+2] = b'\x00\xBF'
        if offset + 14 <= len(data):
            data[offset+12:offset+14] = b'\x00\xBF'
            print(f'[+] {name} patché avec succès.')


# --- 2ème PATCH (Nouveau : BL 0xBC00 dynamique) ---
# Pattern recherché : 6B 46 10 68 51 68
# Attention : en binaire brut (Little Endian), '46 6B' devient \x6B\x46, '68 10' devient \x10\x68, etc.
pattern_p2 = b'\x6B\x46\x10\x68\x51\x68'
offset_p2 = data.find(pattern_p2)

if offset_p2 != -1:
    print(f'[+] Pattern 2 trouvé à l offset de base : 0x{offset_p2:X}')
    
    # L'adresse de l'instruction à remplacer (offset + 22 décimal)
    patch_address = offset_p2 + 22
    print(f'[+] Adresse de l instruction à remplacer (BL) : 0x{patch_address:X}')
    
    # Cible du branchement
    target_address = 0xBC00
    
    # En ARM, le PC a 4 octets d'avance pendant l'exécution de l'instruction
    pc_address = patch_address + 4
    
    # Calcul de la distance (offset de saut)
    jump_offset = target_address - pc_address
    
    # Encodage de l'instruction BL en Thumb-2 (saut sur 32-bits)
    # jump_offset doit être divisé par 2 car le bit de poids faible est omis (instructions alignées sur 2 octets)
    jump_val = jump_offset >> 1
    
    # Extraction des composants du signe et des bits J1, J2 (Spécification ARM)
    S = 1 if jump_val < 0 else 0
    if jump_val < 0:
        # Gestion du complément à 2 sur 25 bits pour les sauts négatifs si besoin
        jump_val = (1 << 24) + jump_val 
        
    I1 = (jump_val >> 22) & 1
    I2 = (jump_val >> 21) & 1
    
    J1 = int(not (I1 ^ S))
    J2 = int(not (I2 ^ S))
    
    imm10 = (jump_val >> 11) & 0x3FF
    imm11 = jump_val & 0x7FF
    
    # Reconstruction des deux demi-mots (16-bits chacun) du BL
    first_half = 0xF000 | (S << 10) | imm10
    second_half = 0xF800 | (J1 << 13) | (J2 << 11) | imm11
    
    # Conversion en octets Little Endian
    bl_bytes = struct.pack('<HH', first_half, second_half)
    
    # Application du patch
    if patch_address + 4 <= len(data):
        data[patch_address:patch_address+4] = bl_bytes
        # Affichage des octets générés en Hexa pour vérification (ex: 03 F0 97 FB)
        hex_bytes = ' '.join(f'{b:02X}' for b in bl_bytes)
        print(f'[+] BL encodé généré : {hex_bytes}')
        print(f'[+] Patch 2 appliqué à l offset 0x{patch_address:X}')
        
        # Sauvegarde du fichier modifié
        with open(file_path, 'wb') as f:
            f.write(data)
        print('[+] Fichier patché avec succès !')
    else:
        print('[-] Erreur : L offset de destination dépasse la taille du fichier.')
else:
    print('[-] Pattern 2 non trouvé dans le binaire.')
" "$TARGET_FILE"

# 3. Injection du code et des ressources (dd)
echo "[*] Injection du code et des ressources en 0xBC00+..."

if [ -f "main.bin" ] && [ -f "image.bin" ] && [ -f "about.bin" ]; then
    dd if=main.bin of="$TARGET_FILE" bs=1 seek=48128 conv=notrunc 2>/dev/null
    dd if=image.bin of="$TARGET_FILE" bs=1 seek=49344 conv=notrunc 2>/dev/null
    dd if=about.bin of="$TARGET_FILE" bs=1 seek=50992 conv=notrunc 2>/dev/null
    echo "[+] Code et ressources injectés avec succès !"
    python3 -c "
import sys
import struct

file_path = sys.argv[1]
with open(file_path, 'rb') as f:
    data = bytearray(f.read())

patterns_screen = [
    (b'\x08\xB5\x01\x22\x00\x21\x06\x48', 'Screen 115'),
    (b'\x08\xB5\x01\x22\x03\x21\x06\x48', 'Screen 120')
]

for pattern, name in patterns_screen:
    offset = data.find(pattern)
    print(name,offset)
    if offset!=-1 and name=='Screen 120':
        data[0xbc04:0xbc06] = b'\x00\xBF'
        data[0xbdfc] = (offset+1) % 256
        data[0xbdfd] = (offset//256) % 256
        print(f'[+] {name} patché avec succès.')
        # Sauvegarde du fichier modifié
        with open(file_path, 'wb') as f:
            f.write(data)

" "$TARGET_FILE"
else
    echo "[-] Erreur : L'un des fichiers requis (main.bin, image.bin, about.bin) est manquant dans le répertoire courant."
    exit 1
fi
