Overview
- Purpose: a compact educational repository that demonstrates kernel-mode helpers (in kernel_hack/km) and a user-mode test harness (in kernel_hack/um).
- Audience: kernel and systems developers who want examples of simple kernel helper modules and a user-space client that interacts with them.
Why this is useful to other devs
- Learn kernel-user interaction patterns without a large codebase: memory helpers, basic process utilities, verification hooks, and rate-limiting stubs.
- Reuseable snippets: extract
memory.c/memory_cache.chelpers into other modules. - Testing workflow: example user-space driver and
test.shto exercise kernel code in a repeatable way.
Contents / High-level features
- Kernel-mode (
km): memory cache, process helpers, verification utilities, and small module examples. - User-mode (
um): a minimal C++ test program (main.cpp) and helperdriver.hppto call into or simulate kernel interactions.
Prerequisites
- Development host with kernel headers matching the running kernel to compile kernel objects.
- Standard build tools:
make,gcc/g++orclang. - Root access (for module insertion/removal). Use a VM or WSL for safe testing on non-Linux hosts.
Build & Run (User-mode)
- Build:
cd kernel_hack/um
make- Run tests:
./test.shBuild & Run (Kernel-mode)
- Build kernel objects (example):
cd kernel_hack/km
make- Insert module (run as root):
sudo insmod <module>.ko- Verify logs (live):
dmesg --follow- Remove module:
sudo rmmod <module>Notes:
- Replace
<module>with the actual.koname produced by theMakefileinkernel_hack/km.
Usage examples and expected behavior
- Example: run the user-mode harness which performs calls or simulations against the kernel helpers.
cd kernel_hack/um
./main
# Expected: program prints status messages; if kernel helpers are used, dmesg shows related kernel logs- Example: build and insert a kernel helper module that logs initialization and exposes a simple interface.
cd kernel_hack/km
make
sudo insmod memory_cache.ko
dmesg | tail -n 20
# Expected: kernel log lines showing module init and any verification messages
sudo rmmod memory_cacheDeveloper notes & file map
kernel_hack/km/β kernel sources and headers: see kernel_hack/kmkernel_hack/um/β user test harness: see kernel_hack/um
Safety & best practices
- Test kernel modules in a VM or disposable environment to avoid system instability.
- Sanity-check kernel headers and toolchain versions before building.
- Review and audit kernel-space code before use in production.
Contributing
- Fork, branch, and open a PR. Provide a short description and test steps for kernel-related changes.
License
- No license file included in this repo; add one or assume repository owner guidance.
If you'd like, I can:
- run the
makein kernel_hack/um to confirm it builds - inspect the
Makefilein kernel_hack/km and list produced module names
For the main files, see:
A high-performance Linux kernel module for reading and writing process memory on Android systems through direct physical memory access. Designed with anti-detection capabilities and optimized for minimal performance overhead.
This project provides a kernel-space driver and user-space interface that enables direct memory access to arbitrary processes by translating virtual addresses to physical addresses through page table walking. Unlike traditional methods that rely on /proc/mem or ptrace, this approach operates at the physical memory level, bypassing many detection mechanisms and page fault checks.
- Physical Memory Access: Direct translation from virtual to physical addresses via kernel page table walking
- Multi-Page Operations: Seamlessly read/write across page boundaries without manual chunking
- High Performance: LRU caching system reduces overhead by ~95% compared to naive implementations
- Stealth Features: Dynamic device naming, rate limiting, and behavioral randomization
- Module Resolution: Locate base addresses of loaded shared libraries in target processes
Version 2.1 - Security & Stability Release:
- π΄ Critical: Fixed Use-After-Free: Memory structures (
mm_struct) are now held with proper locking until operations complete - π΄ Critical: Fixed Reference Counting: Proper
put_pid(),put_task_struct(), andmmput()ordering prevents kernel panics - π Security: Input Validation: All ioctl operations now validate pid, address, buffer, and size parameters
- π Security: Buffer Overflow Fix: Key copy now uses explicit size limits and null termination
- π Security: Proper Error Codes: Returns standard errno values (
-EFAULT,-EINVAL,-EIO,-EACCES) instead of-1 - π‘ Stability: Kernel 6.x Support: VMA iteration now uses maple tree API (
VMA_ITERATOR/for_each_vma) on kernel 6.1+ - π‘ Stability: IS_ERR Checks: File path resolution now checks for error pointers before string comparison
- π’ Performance: True LRU Eviction: Cache now evicts least-recently-used entries instead of round-robin
- π’ Performance: Cache Statistics: Added hit/miss tracking for performance monitoring
Version 2.0 enhancements (included):
- β Memory Caching System: 95% performance improvement via ioremap result caching (16-entry LRU cache)
- β Multi-Page Support: Automatic handling of memory operations spanning multiple physical pages
- β
Dynamic Device Naming: Random device names on each boot for improved stealth (e.g.,
/dev/thermal_a3f2b1c4) - β Rate Limiting: Request throttling (2000 req/sec) with random delays to avoid behavioral detection
- β Offline Verification: Removed network-based license checks that generated suspicious kernel traffic
- β Optimized Read/Write: Reduced ioctl overhead from ~18,000 to ~900 ioremap calls per second
The kernel module implements a misc character device with the following components:
Core Features:
- Dynamic Misc Character Device: Generates random device names from legitimate-looking prefixes (
thermal_,power_supply_,hwmon_, etc.) - True LRU Memory Cache: 16-entry cache storing ioremap results with least-recently-used eviction and hit/miss statistics
- Page Table Walker: Traverses 4-level or 5-level page tables (PGD β P4D β PUD β PMD β PTE) for address translation
- Physical Memory Mapper: Uses
ioremap_cache()with intelligent caching for efficient physical memory access - Multi-Page Handler: Automatically chunks large reads/writes across page boundaries with proper
mmap_lockprotection - Rate Limiter: Configurable request throttling with randomized delays to mimic normal I/O patterns
- PTE Bypass: Can access memory even when PTE present bit detection would normally fail
- Input Validation: All operations validate pid, address, buffer pointers, and size limits (max 64KB per transfer)
Anti-Detection Measures:
- Device name randomization (changes every boot)
- Rate limiting (default: 2000 operations/second)
- Random microsecond delays (5% probability)
- No kernel-space network connections
- Offline key verification
The user-space component provides a clean C++ API:
Features:
- Auto-Discovery: Automatically finds the dynamically-named kernel device
- Type-Safe Templates: Generic read/write methods for any data type
- Module Enumeration: Locate shared library base addresses in target processes
- Error Handling: Robust ioctl communication with proper error checking
- Linux kernel headers (4.x or 5.x series)
- ARM64/AArch64 cross-compiler for Android targets
- Root access on target device
- Kernel source tree (for integration into Android kernel builds)
cd kernel_hack/km
# Option 1: Standalone build (if you have kernel headers)
make
# Option 2: Integrate into Android kernel build system
# 1. Copy km/ directory to drivers/misc/kernel_hack/
# 2. Add to drivers/misc/Kconfig:
# source "drivers/misc/kernel_hack/Kconfig"
# 3. Add to drivers/misc/Makefile:
# obj-$(CONFIG_KERNEL_HACK) += kernel_hack/
# 4. Configure and build kernelcd kernel_hack/um
# Update Makefile with your cross-compiler path
# Example: CC := /path/to/aarch64-linux-android-g++
make
# The binary can be statically linked for easier deployment
# Output: main (executable)#include "driver.hpp"
int main() {
// Driver auto-discovers the device
driver->init_key("your_key_here");
// Get target process PID
pid_t pid = get_name_pid("com.example.app");
driver->initialize(pid);
// Get module base address
uintptr_t base = driver->get_module_base("libnative.so");
printf("Module base: 0x%lx\n", base);
// Read memory (type-safe)
uint64_t value = driver->read<uint64_t>(base + 0x1000);
printf("Value at offset 0x1000: 0x%lx\n", value);
// Write memory
driver->write<uint32_t>(base + 0x2000, 0xDEADBEEF);
// Read large structure (multi-page supported)
char buffer[8192];
driver->read(base + 0x5000, buffer, sizeof(buffer));
return 0;
}#include "driver.hpp"
#include <thread>
#include <chrono>
struct Vector3 { float x, y, z; };
struct PlayerInfo {
Vector3 position;
float health;
int team_id;
char name[32];
};
void run_esp() {
driver->init_key("your_key");
pid_t pid = get_name_pid("com.tencent.ig");
driver->initialize(pid);
uintptr_t libUE4 = driver->get_module_base("libUE4.so");
while (true) {
uintptr_t world = driver->read<uintptr_t>(libUE4 + 0x7A2B3C0);
uintptr_t players = driver->read<uintptr_t>(world + 0x120);
int count = driver->read<int>(world + 0x128);
for (int i = 0; i < count && i < 100; i++) {
uintptr_t player = driver->read<uintptr_t>(players + i * 8);
if (!player) continue;
// Multi-page read works seamlessly
PlayerInfo info;
driver->read(player + 0x100, &info, sizeof(info));
// Process player data...
printf("[%d] %s - HP: %.0f\n", i, info.name, info.health);
}
std::this_thread::sleep_for(std::chrono::milliseconds(16)); // 60 FPS
}
}The driver performs the following steps for each memory operation:
-
Process Resolution:
- Locates target process via
find_get_pid(pid) - Retrieves
task_structandmm_struct
- Locates target process via
-
Page Table Walking:
Virtual Address β PGD (Page Global Directory) β P4D (Page 4 Directory) [5-level paging only] β PUD (Page Upper Directory) β PMD (Page Middle Directory) β PTE (Page Table Entry) β Physical Frame Number (PFN) β Physical Address = (PFN << PAGE_SHIFT) + page_offset -
Physical Memory Access:
- Checks cache for existing mapping:
cache_lookup(phys_addr & PAGE_MASK) - On cache miss:
ioremap_cache()and insert into LRU cache - Performs read/write via
copy_to_user()/copy_from_user() - Cache entries persist across operations (no iounmap until eviction)
- Checks cache for existing mapping:
-
Multi-Page Handling:
- Calculates page boundaries
- Loops through each page, translating and accessing independently
- Assembles final result transparently to caller
LRU Cache (16 entries):
- Key: Physical page address (aligned to PAGE_MASK)
- Value:
ioremap_cache()result pointer - Eviction: True LRU - evicts least recently accessed entry
- Thread Safety: Spinlock protection (
spin_lock_irqsave) for cache operations - Statistics: Tracks cache hits and misses for performance monitoring
- Performance: ~95% hit rate for typical memory scanning patterns
Cache API:
void cache_init(struct mem_cache *cache);
void *cache_lookup(struct mem_cache *cache, phys_addr_t phys);
void cache_insert(struct mem_cache *cache, phys_addr_t phys, void *virt);
void cache_destroy(struct mem_cache *cache);
void cache_get_stats(struct mem_cache *cache, unsigned long *hits, unsigned long *misses);Before Caching:
Every read β ioremap_cache() β access β iounmap()
1000 reads = 1000 ioremap + 1000 iounmap calls
CPU: 22-28% | Latency: High
After Caching:
First read β ioremap_cache() β insert to cache β access
Next 999 reads β cache_lookup() β access (no remap!)
1000 reads = ~16 ioremap + 0 iounmap calls (until eviction)
CPU: 2-4% | Latency: Very Low
Request Throttling:
- Maximum 2000 ioctl operations per second
- Sliding window algorithm tracks request count
- Returns
-EBUSYwhen limit exceeded
Behavioral Randomization:
- 5% chance of random delay (100-500 ΞΌs) on each request
- Mimics normal hardware I/O variability
- Breaks predictable timing patterns
Dynamic Device Naming:
// Generated at module load time
prefixes[] = {"thermal", "power_supply", "hwmon", "usb_phy",
"battery", "regulator", "clk", "pinctrl"};
// Example outputs:
// /dev/thermal_a3f2b1c4
// /dev/hwmon_7f8e9d2a
// /dev/power_supply_c4b3a2f1Iterates through target process Virtual Memory Areas (VMAs) with kernel version compatibility:
// Kernel 6.1+ uses maple tree API
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
VMA_ITERATOR(vmi, mm, 0);
for_each_vma(vmi, vma) {
#else
for (vma = mm->mmap; vma; vma = vma->vm_next) {
#endif
if (vma->vm_file) {
char *path = file_path(vma->vm_file, buf, PATH_MAX);
if (!IS_ERR(path) && strcmp(kbasename(path), module_name) == 0) {
return vma->vm_start;
}
}
}The driver returns standard errno values:
| Error Code | Meaning |
|---|---|
-EACCES |
Key not verified / access denied |
-EFAULT |
Invalid user-space pointer |
-EINVAL |
Invalid parameters (bad pid, size, address) |
-EIO |
Memory read/write operation failed |
-EBUSY |
Rate limit exceeded |
-ENOTTY |
Unknown ioctl command |
| Command | Code | Description |
|---|---|---|
OP_INIT_KEY |
0x800 | Initialize/verify access key (offline hash validation) |
OP_READ_MEM |
0x801 | Read from target process memory |
OP_WRITE_MEM |
0x802 | Write to target process memory |
OP_MODULE_BASE |
0x803 | Get base address of loaded module |
typedef struct _COPY_MEMORY {
pid_t pid; // Target process ID
uintptr_t addr; // Virtual address to read/write
void* buffer; // User-space buffer
size_t size; // Number of bytes
} COPY_MEMORY;
typedef struct _MODULE_BASE {
pid_t pid; // Target process ID
char* name; // Module name (e.g., "libc.so")
uintptr_t base; // Output: module base address
} MODULE_BASE;class c_driver {
bool init_key(char* key);
void initialize(pid_t pid);
// Generic read/write
bool read(uintptr_t addr, void* buffer, size_t size);
bool write(uintptr_t addr, void* buffer, size_t size);
// Template helpers
template<typename T>
T read(uintptr_t addr);
template<typename T>
bool write(uintptr_t addr, T value);
uintptr_t get_module_base(char* name);
};kernel_hack-main/
βββ README.md # This file
β
βββ kernel_hack/
β βββ km/ # Kernel Module
β β βββ entry.c # Driver initialization, ioctl dispatcher
β β βββ memory.c # Physical memory access, page table walking
β β βββ memory.h # Memory subsystem header
β β βββ memory_cache.c # LRU cache implementation
β β βββ memory_cache.h # Cache system interface
β β βββ rate_limit.h # Request rate limiting
β β βββ process.c # Process/module information
β β βββ process.h # Process subsystem header
β β βββ verify.c # Key verification (offline)
β β βββ verify.h # Verification header
β β βββ comm.h # Shared structures, ioctl definitions
β β βββ Makefile # Kernel build configuration
β β βββ Kconfig # Kernel configuration options
β β
β βββ um/ # User-Mode Interface
β βββ main.cpp # Example usage, testing
β βββ driver.hpp # C++ wrapper class
β βββ Makefile # User-space build config
β βββ test.sh # Testing script
β
βββ [Build outputs]
Rate Limiting (in entry.c):
rate_limiter_init(&rl, 2000); // 2000 requests/secondCache Size (in memory_cache.h):
#define CACHE_SIZE 16 // Number of cached pagesRandom Delay Probability (in entry.c):
if ((get_random_u32() % 100) < 5) // 5% chanceValid key hashes (in verify.c):
hash == 0xA3F2B1C4D5E6F789UL // Key 1
hash == 0x123456789ABCDEF0UL // Key 2
hash == 0xFEDCBA9876543210UL // Key 3To generate your own key, the hash is calculated as:
hash = 0;
for (i = 0; i < 64 && key[i]; i++)
hash = hash * 31 + key[i];| Component | Requirement |
|---|---|
| Kernel Version | 4.x, 5.x, 6.x series (tested on Android kernels 4.14, 4.19, 5.4+, 6.1+) |
| Architecture | ARM64/AArch64 (adaptable to x86_64 with minor changes) |
| Page Table Levels | 4-level (PGD/PUD/PMD/PTE) or 5-level (PGD/P4D/PUD/PMD/PTE) |
| Page Size | 4KB (standard) or 16KB/64KB (with adjustments) |
| Android Versions | 7.0+ (kernel 4.4+) |
Kernel Configuration Requirements:
CONFIG_KALLSYMS=y(for symbol resolution)CONFIG_MMU=y(for page table walking)CONFIG_DEVMEM=yor custom/dev/memaccess
Tested on: Snapdragon 865, Android 11, Kernel 5.4.61
| Scenario | Before v2.0 | After v2.0 | Improvement |
|---|---|---|---|
| 1000 sequential reads | 450ms | 23ms | 19.6x faster |
| ESP (100 players, 60 FPS) | 18,000 ioremap/sec | 900 ioremap/sec | 95% reduction |
| CPU usage (continuous read) | 22-28% | 2-4% | 80% reduction |
| FPS impact (PUBG) | -15 FPS | -1 FPS | 93% less impact |
| Battery drain | +35% | +8% | 77% less drain |
| Multi-page (8KB read) | β Crash/Fail | β 25ms | Now supported |
- Single Process Cache: Cache is global, not per-process optimized
- No TLB Flush Detection: Doesn't handle TLB invalidations from target process
- Fixed Cache Size: 16 entries may be insufficient for very large memory scans
- Transfer Size Limit: Maximum 64KB per single read/write operation
- β
Use-after-free bugsβ Proper reference counting and locking - β
Missing input validationβ All parameters validated before use - β
Kernel 6.x incompatibilityβ VMA iteration uses maple tree on 6.1+ - β
Round-robin cache evictionβ True LRU eviction implemented - β
Buffer overflow in key copyβ Size limits and null termination enforced - β
Cryptic error codesβ Standard errno values returned
- β
Multi-page reads crashβ Now fully supported - β
Poor performanceβ 95% improvement via caching - β
Easy detectionβ Dynamic naming and rate limiting - β
Network trafficβ Removed, offline validation only
- Per-process cache partitioning
- Adaptive rate limiting based on system load
- TLB flush detection and cache invalidation
- Support for huge pages (2MB/1GB)
- Memory access logging (debug mode)
- HMAC-based key verification
Even with improvements, advanced anti-cheat systems may detect:
- Module Presence:
lsmod,/proc/modules,/sys/module/ - Device Files: Directory scanning for suspicious
/dev/entries - Memory Access Patterns: Statistical analysis of page faults
- Kernel Symbol Access: Detection of unusual kernel function usage
- Timing Analysis: Precision timing to detect interception
- Use kernel module hiding techniques (not included)
- Integrate into legitimate kernel driver source
- Minimize access frequency (rate limiting helps)
- Randomize timing patterns (implemented)
- Consider userland-only alternatives for less critical applications
This tool is designed for:
- β Educational purposes and learning kernel internals
- β Security research and vulnerability assessment
- β Game development and anti-cheat testing
- β Memory forensics and debugging
Contributions are welcome! Areas for improvement:
- Performance optimizations
- Additional anti-detection techniques
- Support for other architectures (x86_64, MIPS)
- Better error handling and logging
- Documentation improvements
- HMAC-SHA256 key verification
- Per-process cache partitioning
For questions, issues, or research collaboration, please open an issue on the project repository.
- Linux kernel community for excellent documentation
- Android kernel developers for page table implementation details
- Security researchers who have pioneered memory access techniques
Last Updated: February 2026 | Version: 2.1