Skip to content

hexpatch struggles with patching properties in /dev/__properties__ #8315

@0x11DFE

Description

@0x11DFE

The magiskboot hexpatch command seems to have difficulties consistently patching property names within the /dev/__properties__/ files, which are memory-mapped representations of system properties.

Problem

  • When attempting to patch the entire hex representation of a property name, hexpatch often fails to find the pattern, even if the property is clearly present in the file. This might be due to the binary nature of these files and the potential fragmentation of property data within them.
  • Partially patching or randomizing specific parts of the property name also seems unreliable, as the exact offset of the target string within the file might not be easily determined.

Demo Code

Here are two functions demonstrating the attempted patching approaches:

    local search_string="$1"      # The string to search for in property names
    local search_hex=$(echo -n "$search_string" | xxd -p | tr '[:lower:]' '[:upper:]')  # Hex representation in uppercase

    # Path to magiskboot
    local magiskboot_path="/data/adb/magisk/magiskboot"

    # Find the property file name using resetprop -Z
    prop_file_name=$(resetprop -Z "$search_string" | cut -d' ' -f2) 

    if [ -n "$prop_file_name" ]; then
        # Extract the relevant part of the file name (remove SELinux context)
        prop_file_name=$(echo "$prop_file_name" | cut -d':' -f3)

        # Use find to locate the actual property file (potentially in a subdirectory)
        # and iterate directly over the found paths
        find /dev/__properties__/ -name "*$prop_file_name*" | while read -r prop_file; do 

            # Generate a random LOWERCASE alphanumeric string of the same length as the search string, but only using 0-9 and a-f
            local replacement_string=$(cat /dev/urandom | tr -dc '0-9a-f' | fold -w ${#search_string} | head -n 1)

            # Convert the full replacement string to hex (once, at the top scope) and ensure it's in uppercase
            local replacement_hex=$(echo -n "$replacement_string" | xxd -p | tr '[:lower:]' '[:upper:]')

            echo "Patching $prop_file: $search_hex -> $replacement_hex"
            if "$magiskboot_path" hexpatch "$prop_file" "$search_hex" "$replacement_hex" >/dev/null 2>&1; then
                echo "Successfully patched $prop_file (replaced '$search_string' with '$replacement_string')"
            # else  # No need to print "not found" for every file, it might be too verbose
            fi 
        done
    else
        echo "Property '$search_string' not found."
    fi
}


hexpatch_partial_deleteprop() {
    local search_string="$1"  # The string to search for in property names
    local search_hex=$(echo -n "$search_string" | xxd -p | tr '[:lower:]' '[:upper:]')  # Hex representation in uppercase

    # Path to magiskboot
    local magiskboot_path="/data/adb/magisk/magiskboot"

    # Find the property file name using resetprop -Z
    prop_file_name=$(resetprop -Z "$search_string" | cut -d' ' -f2) 

    if [ -n "$prop_file_name" ]; then
        # Extract the relevant part of the file name (remove SELinux context)
        prop_file_name=$(echo "$prop_file_name" | cut -d':' -f3)

        # Use find to locate the actual property file (potentially in a subdirectory)
        # and iterate directly over the found paths
        find /dev/__properties__/ -name "*$prop_file_name*" | while read -r prop_file; do 

            # Generate a random LOWERCASE alphanumeric string of the same length as the search string, but only using 0-9 and a-f
            local replacement_hex=$(cat /dev/urandom | tr -dc '0-9a-f' | fold -w ${#search_hex} | head -n 1 | tr '[:lower:]' '[:upper:]')

            echo "Patching $prop_file: $search_hex -> $replacement_hex"
            "$magiskboot_path" hexpatch "$prop_file" "$search_hex" "$replacement_hex" >/dev/null 2>&1

            # Check if the patch was successfully applied
            if [ $? -eq 0 ]; then
                echo "Successfully patched $prop_file (replaced part of '$search_string')"
            else
                echo "Failed to patch $prop_file (replacing part of '$search_string')."
            fi
        done
    else
        echo "Property '$search_string' not found."
    fi
}

Explanation of the functions

  • hexpatch_deleteprop: Replaces the entire occurrence of the search_string with the provided replacement_hex.
  • hexpatch_partial_deleteprop: Replaces only the part of the property name that matches the search_string with a random hex string of the same length.
    Partial vs. Full-Length Property Patching
  • Partial patching aims to modify only a specific portion of the property name, typically the part that matches the provided search_string. The rest of the property name remains unchanged.
  • Full-length patching replaces the entire property name with a new string, usually a randomly generated one, while optionally preserving a prefix (the part before the first dot).
    Advantages of Editing Full-Length Props
    While partial patching might seem safer as it minimizes the risk of corrupting surrounding binary data, editing full-length properties can offer certain advantages:
  • Stronger Obfuscation: Completely replacing the property name with a random string can make it significantly harder for root detection apps or other tools to identify the original property, potentially improving the effectiveness of the obfuscation.
  • Flexibility: Full-length patching provides more flexibility in customizing the replacement strings. You can generate completely random names, use specific patterns, or even incorporate other techniques to make the patched properties even less recognizable.
  • Consistency: In some cases, it might be desirable to have all patched properties follow a consistent naming convention, which can be easily achieved with full-length replacement.

Suggested Improvements/Considerations

  • Enhanced hexpatch search algorithm:
    • magiskboot hexpatch could potentially benefit from a more robust search algorithm that can handle fragmented or non-contiguous hex patterns within binary files.
    • This could involve:
      • Smarter pattern matching that allows for some tolerance in the hex sequence (e.g., ignoring certain byte values between the target hex characters)
      • Support for specifying a range of offsets or a search window within the file
  • Alternative patching mechanisms:
    • If direct hex patching proves to be unreliable for memory-mapped property files, consider exploring alternative approaches within magiskboot, such as:
      • Modifying the property values directly in memory using appropriate system calls or kernel interfaces
      • Providing a way to temporarily remount the property partition as read-write to allow for safer modifications

Additional Information

Device: Surya
Android version: 14
Magisk version name: 0495468-alpha:MAGISK:R
Magisk version code: 27006

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions