Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
01dacec
Delete code/api_proxy.h
vesirvit Jan 18, 2026
29afe3e
Delete code directory
vesirvit Jan 18, 2026
2408db6
Add object file definition in Makefile
vesirvit Jan 18, 2026
a458a1f
Create aurora.h
vesirvit Jan 18, 2026
54772d0
Add misc device driver with open, close, and ioctl
vesirvit Jan 18, 2026
acd20c5
Update Makefile
vesirvit Jan 18, 2026
3e57f60
Enhance aurora.h with new includes and device name
vesirvit Jan 18, 2026
3a30e2b
Update aurora.c
vesirvit Jan 18, 2026
742a5ba
Add files via upload
vesirvit Jan 23, 2026
66a7aae
Add files via upload
vesirvit Jan 23, 2026
c1e70a1
Delete README_zh.md
vesirvit Jan 23, 2026
55efe86
Update README.md
vesirvit Jan 23, 2026
49c3589
Delete code/aurora.c
vesirvit Jan 27, 2026
82be5d4
Delete code/aurora.h
vesirvit Jan 27, 2026
f4cf154
Add files via upload
vesirvit Jan 27, 2026
db700af
Delete code/hwBreakpointProc_module.c
vesirvit Jan 28, 2026
1d9e12b
Delete code/hwBreakpointProc_module.h
vesirvit Jan 28, 2026
db48fc8
Add files via upload
vesirvit Jan 28, 2026
51820a0
Delete code/arm64_hw_bp.c
vesirvit Jan 29, 2026
08b4fb1
Delete code/arm64_hw_bp.h
vesirvit Jan 29, 2026
ac9deb0
Add files via upload
vesirvit Jan 29, 2026
6d067a6
Delete code directory
vesirvit Jan 30, 2026
a842e04
Create Makefile
vesirvit Jan 30, 2026
a0f3669
Add files via upload
vesirvit Jan 30, 2026
a5bf323
Update aurora.c
vesirvit Jan 30, 2026
546f17e
Delete code/aurora.c
vesirvit Jan 30, 2026
30767a0
Delete code/aurora.h
vesirvit Jan 30, 2026
01ddfeb
Add files via upload
vesirvit Jan 30, 2026
897a0c8
Delete code directory
vesirvit Feb 3, 2026
c07d026
Create Makefile
vesirvit Feb 3, 2026
8d3f836
Add files via upload
vesirvit Feb 3, 2026
2c4405e
Add files via upload
vesirvit Feb 3, 2026
ab0e52b
Update ver_control.h
vesirvit Feb 3, 2026
a8ee2c3
Enable debug print mode in ver_control.h
vesirvit Feb 3, 2026
55b56b4
Add files via upload
vesirvit Feb 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 2 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,2 @@
**Read this in other languages: [English](README.md), [中文](README_zh.md).**
# Automated Kernel Driver Builder

This GitHub Action automates the process of building Android kernel drivers in the cloud, eliminating the need for local compilation environments. It solves common issues like accessing Google's source repositories and reduces compilation time to under 30min.

## Key Features

- ✅ **Cloud-based compilation** - No local setup required
- ✅ **Automatic source handling** - Fetches official Android kernel sources
- ✅ **Version-aware building** - Automatically selects correct build system
- ✅ **Parameterized inputs** - Customize builds via workflow inputs
- ✅ **Artifact packaging** - Downloads compiled drivers and kernel images

## Usage Guide

### 1. Repository Setup
1. Create a `code` directory in your repository
2. Place these files in the `code` directory:
- Driver source files (`.c` and `.h`)
- `Makefile` for your driver
- Any additional dependencies

### 2. Running the Workflow
1. Go to your GitHub repository's **Actions** tab
2. Select **Android Kernel Driver Builder**
3. Click **Run workflow**
4. Provide these parameters:
- `android_version`: Your Android version (Kernel) (e.g., `14`)
- `kernel_version`: Kernel version (e.g., `6.1`)
- `driver_name`: Your driver filename (e.g., `mydriver.ko`)
- `target_arch`: Device architecture (default: `aarch64`)

### 3. Retrieving Results
After successful compilation (30minutes):
1. Go to the completed workflow run
2. Download the `kernel-driver-<arch>` artifact
3. Extract to find:
- Compiled driver (`.ko` file)
- Kernel images (`boot.img`)
- Build logs

## Configuration Reference

### Input Parameters

| Parameter | Description | Example |
|-----------|-------------|---------|
| `android_version` | Android OS version | `11`, `12`, `13`, `14` |
| `kernel_version` | Linux kernel version | `5.10`, `5.15`, `6.1` |
| `driver_name` | Output driver filename | `custom_driver.ko` |
| `target_arch` | Device CPU architecture | `aarch64`, `x86_64` |

### Technical Notes

1. **Build System Selection**:
- Android 11 and earlier: Legacy `build.sh` system
- Android 12 and later: Modern Bazel build system

2. **Source Management**:
- Automatically fetches kernel sources from Google's repositories
- Uses parallel downloading for faster sync

3. **Driver Integration**:
- Automatically adds driver to kernel build system
- Registers driver as GKI module
- Handles Makefile modifications

## Troubleshooting

**Q: Build fails with "repo sync" errors**
A: Retry the workflow. Google's servers can occasionally timeout.

**Q: Driver not found in output artifacts**
A: Verify:
- Correct `driver_name` parameter (must match Makefile)
- Source files are in `/code` directory
- Makefile produces expected `.ko` filename

**Q: "Kernel configuration not found" error**
A: Confirm your kernel_version matches existing branches at [Android Kernel Sources](https://android.googlesource.com/kernel/manifest/)

## Support

For issues and feature requests:
- [Open an Issue](https://github.com/systemnb/compile_android_driver/issues)
- Provide workflow logs and input parameters
陈依涵的内核驱动项目,采用systemnb的Action编译。
由于本人还是初学者,所以会不定期学习新内容并更新
85 changes: 0 additions & 85 deletions README_zh.md

This file was deleted.

2 changes: 1 addition & 1 deletion code/Makefile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
obj-m += rwProcMem_module.o
obj-m += hwBreakpointProc_module.o
146 changes: 146 additions & 0 deletions code/anti_ptrace_detection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#ifndef _ANTI_PTRACE_DETECTION_H_
#define _ANTI_PTRACE_DETECTION_H_
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/hw_breakpoint.h>
#include <linux/kprobes.h>

#define PTRACE_GETREGSET 0x4204
#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */

struct hook_ptrace_data {
struct iovec iov;
};

static struct mutex *g_p_hwbp_handle_info_mutex = NULL;
static cvector *g_p_hwbp_handle_info_arr = NULL;

static bool is_my_hwbp_handle_addr(size_t addr) {
citerator iter;
bool found = false;
if(addr == 0) {
return found;
}
mutex_lock(g_p_hwbp_handle_info_mutex);
for (iter = cvector_begin(*g_p_hwbp_handle_info_arr); iter != cvector_end(*g_p_hwbp_handle_info_arr); iter = cvector_next(*g_p_hwbp_handle_info_arr, iter)) {
struct HWBP_HANDLE_INFO * hwbp_handle_info = (struct HWBP_HANDLE_INFO *)iter;
if(hwbp_handle_info->original_attr.bp_addr == addr) {
found = true;
break;
}
}
mutex_unlock(g_p_hwbp_handle_info_mutex);
return found;
}

static int entry_ptrace_handler(struct kretprobe_instance *ri, struct pt_regs *regs) {
long request = regs->regs[1];
unsigned long addr = (unsigned long)regs->regs[2];
struct hook_ptrace_data *data = (struct hook_ptrace_data *)ri->data;
data->iov.iov_base = 0;
data->iov.iov_len = 0;
printk_debug(KERN_INFO "entry_ptrace_handler called with request: %lx, addr: %lx\n", request, addr);
if (request == PTRACE_GETREGSET && (addr == NT_ARM_HW_WATCH || addr == NT_ARM_HW_BREAK)) {
unsigned long iov_user_ptr = regs->regs[3];
printk_debug(KERN_INFO "entry_ptrace_handler called with request: %lx, addr: %lx, iov_user_ptr: %lx\n", request, addr, iov_user_ptr);
if(!iov_user_ptr) {
return 0;
}
if (x_copy_from_user(&data->iov, (struct iovec __user *)iov_user_ptr, sizeof(struct iovec)) != 0) {
printk_debug(KERN_INFO "Failed to copy iovec from user space\n");
return 0;
}
printk_debug(KERN_INFO "entry_ptrace_handler iov_base: %lx, iov_len %ld\n", data->iov.iov_base, data->iov.iov_len);
}
return 0;
}
static int ret_ptrace_handler(struct kretprobe_instance *ri, struct pt_regs *regs) {
unsigned long retval = regs_return_value(regs);
struct hook_ptrace_data *data = (struct hook_ptrace_data *)ri->data;
struct user_hwdebug_state old_hw_state;
struct user_hwdebug_state new_hw_state;
size_t copy_size;
int i = 0, y = 0;
printk_debug(KERN_INFO "ret_ptrace_handler called with retval: %lx, iov_base: %lx, iov_len %ld\n", retval, data->iov.iov_base, data->iov.iov_len);
if (!data->iov.iov_base || !data->iov.iov_len) {
return 0;
}

// Check if the buffer of the IoV is readable and writable
if (!access_ok((void __user *)data->iov.iov_base, data->iov.iov_len)) {
printk_debug(KERN_INFO "User buffer is not accessible\n");
return 0;
}
copy_size = min(data->iov.iov_len, sizeof(struct user_hwdebug_state));
if (x_copy_from_user(&old_hw_state, (void __user *)data->iov.iov_base, copy_size) != 0) {
printk_debug(KERN_INFO "Failed to copy old_hw_state from user buffer\n");
return 0;
}
// After x_copy_from_user
printk_debug(KERN_INFO "Original old_hw_state.dbg_info: %u, size %ld\n", old_hw_state.dbg_info, copy_size);
for (i = 0; i < 16; i++) {
printk_debug(KERN_INFO "Reg %d: addr=%llu, ctrl=%u\n", i, old_hw_state.dbg_regs[i].addr, old_hw_state.dbg_regs[i].ctrl);
}
// Clear the dbd_regs array
memcpy(&new_hw_state, &old_hw_state, sizeof(new_hw_state));
memset(new_hw_state.dbg_regs, 0x00, sizeof(new_hw_state.dbg_regs));

printk_debug(KERN_INFO "After memset:\n");
for (i = 0; i < sizeof(old_hw_state.dbg_regs) / sizeof(old_hw_state.dbg_regs[0]); i++) {
if(!is_my_hwbp_handle_addr(old_hw_state.dbg_regs[i].addr)) {
memcpy(&new_hw_state.dbg_regs[y++], &old_hw_state.dbg_regs[i], sizeof(old_hw_state.dbg_regs[i]));
}
}

printk_debug(KERN_INFO "After memset:\n");
for (i = 0; i < 16; i++) {
printk_debug(KERN_INFO "Reg %d: addr=%llu, ctrl=%u\n", i, new_hw_state.dbg_regs[i].addr, new_hw_state.dbg_regs[i].ctrl);
}

// Copy the modified hw_ste back to the buffer in user space
if (x_copy_to_user((void __user *)data->iov.iov_base, &new_hw_state, copy_size) != 0) {
printk_debug(KERN_INFO "Failed to copy modified new_hw_state back to user buffer\n");
} else {
printk_debug(KERN_INFO "Successfully cleared dbg_regs in user_hwdebug_state\n");
}
return 0;
}


static struct kretprobe kretp_ptrace = {
.kp.symbol_name = "arch_ptrace",
.data_size = sizeof(struct hook_ptrace_data),
.entry_handler = entry_ptrace_handler,
.handler = ret_ptrace_handler,
.maxactive = 20,
};

static bool start_anti_ptrace_detection(struct mutex *p_hwbp_handle_info_mutex, cvector *p_hwbp_handle_info_arr) {
int ret = 0;
g_p_hwbp_handle_info_mutex = p_hwbp_handle_info_mutex;
g_p_hwbp_handle_info_arr = p_hwbp_handle_info_arr;
if(!g_p_hwbp_handle_info_mutex || !g_p_hwbp_handle_info_arr) {
printk_debug(KERN_INFO "start_anti_ptrace_detection param error\n");
return false;
}
ret = register_kretprobe(&kretp_ptrace);
if (ret < 0) {
printk_debug(KERN_INFO "register_kretprobe failed, returned %d\n", ret);
return false;
}
printk_debug(KERN_INFO "kretprobe at %s registered, addr: %lx\n", kretp_ptrace.kp.symbol_name, kretp_ptrace.kp.addr);
return true;
}


static void stop_anti_ptrace_detection(void) {
if(kretp_ptrace.kp.addr) {
unregister_kretprobe(&kretp_ptrace);
printk_debug(KERN_INFO "kretprobe unregistered\n");
}
}

#endif
Loading