├── .github └── FUNDING.yml ├── AndroidDriveSignity.py ├── LICENSE └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [gmh5225] 2 | -------------------------------------------------------------------------------- /AndroidDriveSignity.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | 4 | # Dictionary to hold symbol addresses and names 5 | symbols_dict = {} 6 | 7 | def parse_kallsyms(file_path): 8 | # Parse the kallsyms file to populate the symbols dictionary 9 | global symbols_dict 10 | with open(file_path, 'r') as file: 11 | for line in file: 12 | parts = line.strip().split(' ') 13 | if len(parts) == 3: 14 | address, symbol_type, symbol_name = parts 15 | symbols_dict[address] = symbol_name 16 | 17 | def check_original_instruction(kernel_data, patch_offset): 18 | # Check if the original instruction at the given offset is PACIASP 19 | return kernel_data[patch_offset:patch_offset + 4] == bytearray.fromhex("3F 23 03 D5") 20 | 21 | def prepare_patch_data(original_patch_data_hex, has_paciasp): 22 | # Prepare the patch data, adding PACIASP and AUTIASP instructions if necessary 23 | if has_paciasp: 24 | return bytearray.fromhex("3F 23 03 D5") + bytearray.fromhex(original_patch_data_hex)[:4] + bytearray.fromhex("BF 23 03 D5") + bytearray.fromhex(original_patch_data_hex)[4:] 25 | else: 26 | return bytearray.fromhex(original_patch_data_hex) 27 | 28 | def patch_symbol(kernel_data, symbol_name, base_address, original_patch_data_hex): 29 | # Patch the symbol in the kernel data with the given patch data 30 | symbol_address = None 31 | for address, name in symbols_dict.items(): 32 | if name == symbol_name: 33 | symbol_address = int(address, 16) 34 | break 35 | 36 | if symbol_address is None: 37 | print(f"Error: {symbol_name} symbol not found.") 38 | return False 39 | 40 | relative_address = symbol_address - base_address 41 | patch_offset = relative_address 42 | 43 | # Check if the original instruction is PACIASP and prepare the patch data accordingly 44 | has_paciasp = check_original_instruction(kernel_data, patch_offset) 45 | if has_paciasp: 46 | print(f"Symbol {symbol_name} Offset 0x{patch_offset:X} has PACIASP enabled.") 47 | else: 48 | print(f"Symbol {symbol_name} Offset 0x{patch_offset:X} has PACIASP disabled.") 49 | patch_data = prepare_patch_data(original_patch_data_hex, has_paciasp) 50 | 51 | kernel_data[patch_offset:patch_offset + len(patch_data)] = patch_data 52 | return True 53 | 54 | def patch_kernel_file(kernel_file_path, kallsyms_file_path, output_file_path): 55 | # Main function to patch the kernel file based on the provided kallsyms file 56 | parse_kallsyms(kallsyms_file_path) 57 | 58 | base_address = int(list(symbols_dict.keys())[0], 16) 59 | 60 | with open(kernel_file_path, 'rb') as kernel_file: 61 | kernel_data = bytearray(kernel_file.read()) 62 | 63 | # Apply patches to specified symbols 64 | patch_symbol(kernel_data, "check_modinfo", base_address, "00 00 80 52 C0 03 5F D6") 65 | patch_symbol(kernel_data, "check_version", base_address, "20 00 80 52 C0 03 5F D6") 66 | # The GKI kernel may not have this function 67 | patch_symbol(kernel_data, "module_sig_check", base_address, "00 00 80 52 C0 03 5F D6") 68 | 69 | # Save the patched kernel data to the output file 70 | with open(output_file_path, 'wb') as output_file: 71 | output_file.write(kernel_data) 72 | 73 | print(f"Kernel file patched and saved to {output_file_path}") 74 | 75 | if __name__ == "__main__": 76 | # Command line argument parsing 77 | parser = argparse.ArgumentParser(description="Patch kernel file with provided symbol modifications.") 78 | parser.add_argument("kernel_file_path", type=str, help="Path to the binary kernel file.") 79 | parser.add_argument("kallsyms_file_path", type=str, help="Path to the kallsyms symbol file.") 80 | parser.add_argument("output_file_path", type=str, help="Path where the patched kernel file will be saved.") 81 | 82 | args = parser.parse_args() 83 | 84 | # Execute the patching process with provided arguments 85 | patch_kernel_file(args.kernel_file_path, args.kallsyms_file_path, args.output_file_path) 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 gmh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `AndroidDriveSignity` 2 | 3 | AndroidDriveSignity is a Python script designed for patching Android kernel``(ARMv8.3)`` files, enabling the loading of drivers without being subject to various verification checks, specifically signature verifications. This tool aims to facilitate the development and testing process by allowing developers to bypass the kernel's built-in security measures that prevent unofficial or modified drivers from being loaded. 4 | 5 | ### Features 6 | 7 | - **Targeted Symbol Patching:** Modifies specific symbols within the kernel (`check_modinfo`, `check_version`, and `module_sig_check`) to circumvent driver signature verification mechanisms. 8 | - **Intelligent Patching:** Dynamically adjusts patching based on the presence of the PACIASP instruction, ensuring compatibility across different kernel configurations. 9 | - **User-Friendly CLI:** Provides a straightforward command-line interface for specifying the kernel binary, the kallsyms symbol table, and the output file paths. 10 | 11 | ### Requirements 12 | 13 | - Rooted Android devices``(ARMv8.3)`` with [Magisk](https://github.com/topjohnwu/Magisk) or [KernelSU](https://github.com/tiann/KernelSU) 14 | - Python 3.x 15 | - ADB 16 | 17 | ### Usage 18 | 19 | 1. **Prepare the Necessary Files:** Ensure you have the kernel binary file (`kernel_file_path`), the kallsyms symbol table file (`kallsyms_file_path`), and a destination for the patched kernel (`output_file_path`). 20 | 21 | 2. **Execute AndroidDriveSignity:** Navigate to the script's directory in your terminal or command prompt and run: 22 | 23 | ```bash 24 | python AndroidDriveSignity.py 25 | 26 | ### How to get your kallsyms? 27 | ``` 28 | adb shell 29 | su 30 | echo 0 > /proc/sys/kernel/kptr_restrict 31 | exit 32 | exit 33 | adb shell su -c "cat /proc/kallsyms > /data/local/tmp/kallsyms" 34 | adb pull /data/local/tmp/kallsyms 35 | ``` 36 | 37 | ### How to extract your kernel file? 38 | If there are two partitions, prioritize trying "boot_a": 39 | ``` 40 | adb shell su -c "dd if=$(readlink /dev/block/by-name/boot_a) of=/data/local/tmp/boot.img" 41 | ``` 42 | If there is only one partition, then it is "boot.img": 43 | ``` 44 | adb shell su -c "dd if=$(readlink /dev/block/by-name/boot) of=/data/local/tmp/boot.img" 45 | ``` 46 | Then, pull the boot image to your local machine: 47 | ``` 48 | adb pull /data/local/tmp/boot.img 49 | ``` 50 | 51 | Finally, use [magiskboot](https://github.com/svoboda18/magiskboot/releases) to extract the kernel file from boot.img. 52 | ``` 53 | magiskboot --unpack boot.img 54 | ``` 55 | You will obtain two files: one is the ``kernel``(your kernel file), and the other is ``ramdisk.cpio``. 56 | 57 | ### Testing on android12-5.10 58 | ``` 59 | python AndroidDriveSignity.py kernel kallsyms new-kernel 60 | move/mv new-kernel kernel 61 | magiskboot --repack boot.img 62 | adb reboot bootloader 63 | fastboot flash boot new-boot.img 64 | fastboot reboot 65 | adb push demo.ko /data/local/tmp 66 | adb shell su -c insmod /data/local/tmp/demo.ko 67 | adb shell su -c "lsmod |grep demo" 68 | adb shell su -c rmmod /data/local/tmp/demo.ko 69 | ``` 70 | You can obtain an example of the Android driver [here](https://github.com/gmh5225/android-kernel-driver-template/releases) 71 | 72 | ## Credits 73 | - ``Linux`` 74 | - ``Android`` 75 | - Some anonymous people 76 | 77 | --------------------------------------------------------------------------------