[adeliktas] add older kernel compatibility, cleaned code and file structure
improved base and added PP defines KERNEL_UPSTREAM TESTING DEBUG
This commit was merged in pull request #1.
This commit is contained in:
15
.gitignore
vendored
15
.gitignore
vendored
@@ -1,8 +1,11 @@
|
|||||||
*.order
|
|
||||||
*.symvers
|
|
||||||
Revird
|
|
||||||
*.ko
|
|
||||||
TaxiDriver.mod.c
|
|
||||||
imgui.ini
|
|
||||||
*.o
|
*.o
|
||||||
*.cmd
|
*.cmd
|
||||||
|
*.symvers
|
||||||
|
*.ko
|
||||||
|
*.mod*
|
||||||
|
*.order
|
||||||
|
km/build/*
|
||||||
|
um/main
|
||||||
|
um/test/test_app
|
||||||
|
um/test/libmath_module.so
|
||||||
|
imgui.ini
|
||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,6 +0,0 @@
|
|||||||
[submodule "imgui"]
|
|
||||||
path = imgui
|
|
||||||
url = https://github.com/ocornut/imgui/
|
|
||||||
[submodule "src/client/imgui"]
|
|
||||||
path = src/client/imgui
|
|
||||||
url = https://github.com/ocornut/imgui/
|
|
||||||
36
Makefile
36
Makefile
@@ -1,36 +0,0 @@
|
|||||||
# Makefile for Linux Kernel Driver
|
|
||||||
CONFIG_MODULE_SIG=n
|
|
||||||
|
|
||||||
# Source files and object files
|
|
||||||
SRC_DIR := src
|
|
||||||
SOURCE_FILES := $(wildcard $(SRC_DIR)/*.c)
|
|
||||||
OBJ_FILES := src/TaxiDriver.o
|
|
||||||
obj-m := $(OBJ_FILES)
|
|
||||||
# KERNELDIR ?= /home/maxime/Downloads/linux-6.5.7-arch1/
|
|
||||||
KERNELDIR ?= /lib/modules/6.5.8-arch1-1/build/
|
|
||||||
# Kernel module name
|
|
||||||
MODULE_NAME := TaxiDriver
|
|
||||||
|
|
||||||
all: default
|
|
||||||
|
|
||||||
default:
|
|
||||||
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
|
|
||||||
mv src/$(MODULE_NAME).ko .
|
|
||||||
$(MAKE) clean
|
|
||||||
cd src/client && $(MAKE)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
find src/ -maxdepth 1 -type f ! -name "*.h" ! -name "*.c" -exec rm {} \;
|
|
||||||
|
|
||||||
fclean: clean
|
|
||||||
find . -maxdepth 1 -type f ! -name "Makefile" -exec rm {} \;
|
|
||||||
|
|
||||||
load:
|
|
||||||
sudo insmod $(MODULE_NAME).ko
|
|
||||||
sudo mknod /dev/$(MODULE_NAME) c 511 0
|
|
||||||
|
|
||||||
unload:
|
|
||||||
sudo rmmod $(MODULE_NAME)
|
|
||||||
sudo rm /dev/$(MODULE_NAME)
|
|
||||||
|
|
||||||
.PHONY: all clean fclean load unload
|
|
||||||
87
README.md
87
README.md
@@ -1,53 +1,78 @@
|
|||||||
# TaxiDriver
|
# TaxiDriver
|
||||||
W/RPM Driver and usermode for Linux.<br>
|
Linux Kernel Module for RPM/WPM and usermode driver with examples.
|
||||||
Some things in the client are still not finished :
|
|
||||||
* X11 overlay
|
|
||||||
|
|
||||||
# Features
|
## Features
|
||||||
* Get the base address of any process/loaded .so file
|
* Get the base address of any process/loaded .so file
|
||||||
* RPM
|
* RPM
|
||||||
* WPM
|
* WPM
|
||||||
|
|
||||||
# Compiling
|
## Compiling
|
||||||
To compile the driver you'll need to be at least on kernel version v6.5.8 (i used the [arch kernel](https://github.com/archlinux/linux/releases/tag/v6.5.8-arch1)).<br>
|
### Prerequises :
|
||||||
|
|
||||||
## Prerequises :
|
|
||||||
You'll need git, linux-headers, SDL3 and OpenGL :
|
|
||||||
```
|
```
|
||||||
sudo pacman -S git linux-headers OpenGL
|
sudo pacman -S git linux-headers OpenGL cmake
|
||||||
yay -S sdl3-git
|
yay -S sdl3-git
|
||||||
```
|
```
|
||||||
|
### Upstream Linux Kernel
|
||||||
|
To compile the driver you'll need to be at least on kernel version v6.5 (i used the [arch kernel](https://github.com/archlinux/linux/releases/tag/v6.5.8-arch1)).<br>
|
||||||
|
### legacy Linux Kernel
|
||||||
|
To build for an older Linux Kernel ex. 5.15 change KERNEL_UPSTREAM preprocessor definition
|
||||||
|
in TaxiDriver.h:
|
||||||
|
`#define KERNEL_UPSTREAM 0`
|
||||||
|
or if you use cmake only change required in CmakeLists.txt:
|
||||||
|
`add_compile_definitions(TaxiDriver PRIVATE KERNEL_UPSTREAM=0)`
|
||||||
|
|
||||||
## Compiling and running :
|
### Compiling and running :
|
||||||
Clone the repo, prepare imgui (still in active dev) :
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/ALittlePatate/TaxiDriver --recursive
|
git clone --recursive https://github.com/ALittlePatate/TaxiDriver
|
||||||
chmod +x prepare_imgui.sh
|
|
||||||
./prepare_imgui.sh
|
|
||||||
```
|
```
|
||||||
Compile :
|
#### Kernel Module
|
||||||
|
choose and write a MAJOR number ex. 506 in install.sh and validate for uniqueness `grep "506" /proc/devices`
|
||||||
```
|
```
|
||||||
make
|
# sudo mknod /dev/TaxiDriver c <choose Major Number> 0
|
||||||
|
# cmake is still incomplete
|
||||||
|
cd km && ./install.sh
|
||||||
```
|
```
|
||||||
Run the driver :
|
system might still choose to set a different one, so read the number that is in use, after TaxiDriver is loaded,
|
||||||
|
with `grep "TaxiDriver" /proc/devices` and adjust in mknod and reload TaxiDriver.
|
||||||
|
After loading the Driver, you should find a line saying that TaxiDriver was loaded with X major code.
|
||||||
```
|
```
|
||||||
sudo make load
|
|
||||||
sudo dmesg | grep TaxiDriver
|
sudo dmesg | grep TaxiDriver
|
||||||
```
|
```
|
||||||
You should find a line saying that TaxiDriver was loaded with X major code.
|
|
||||||
```
|
|
||||||
sudo mknod /dev/TaxiDriver c X 0
|
|
||||||
```
|
|
||||||
replace X with your major code.<br>
|
|
||||||
Run the client :
|
|
||||||
```
|
|
||||||
sudo ./Revird
|
|
||||||
```
|
|
||||||
Unload the driver :
|
Unload the driver :
|
||||||
```
|
```
|
||||||
sudo make unload
|
# sudo make unload
|
||||||
|
sudo rmmod TaxiDriver
|
||||||
|
sudo rm /dev/TaxiDriver
|
||||||
```
|
```
|
||||||
|
|
||||||
# Contact
|
#### Usermode Target/Test Application
|
||||||
|
```
|
||||||
|
cd um/test && make
|
||||||
|
./test_app
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Usermode Driver Application
|
||||||
|
```
|
||||||
|
cd um && make
|
||||||
|
./main
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
- Fails to open device:
|
||||||
|
MAJOR number has to match in mknod to open device! Check with `grep "TaxiDriver" /proc/devices`
|
||||||
|
|
||||||
|
If you find anything not listed above. Please open up Issues on the Repo
|
||||||
|
and provide the build log showing the issue with `LANG=C make` with all of your steps and envoirment info to reproduce.
|
||||||
|
|
||||||
|
### Missing Features in development
|
||||||
|
- ImGui Overlay
|
||||||
|
- expand km mem functions
|
||||||
|
- expand um driver example and test_app
|
||||||
|
- Findpattern
|
||||||
|
- write/inject shellcode with asm mid function hook
|
||||||
|
- X11 Input Event Handling
|
||||||
|
|
||||||
|
## Contact
|
||||||
If you have a problem regarding the code, open an issue or make a pull request, i'll be happy to add your contribution !<br>
|
If you have a problem regarding the code, open an issue or make a pull request, i'll be happy to add your contribution !<br>
|
||||||
If you need to contact me for any other reasons, message me at @_.patate on discord.
|
If you need to contact me for any other reasons, message me at `_.patate` on discord.
|
||||||
|
|||||||
30
km/CMakeLists.txt
Normal file
30
km/CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
project(TaxiDriverModule)
|
||||||
|
|
||||||
|
# Set the source files for your module
|
||||||
|
set(SRC ${CMAKE_SOURCE_DIR}/TaxiDriver.c)
|
||||||
|
|
||||||
|
# Locate the kernel build directory
|
||||||
|
execute_process(
|
||||||
|
COMMAND uname -r
|
||||||
|
OUTPUT_VARIABLE KERNEL_RELEASE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
set(KERNEL_BUILD_DIR /lib/modules/${KERNEL_RELEASE}/build)
|
||||||
|
|
||||||
|
# Define the target
|
||||||
|
add_custom_target(TaxiDriverModule ALL
|
||||||
|
COMMAND ${CMAKE_MAKE_PROGRAM} -C ${KERNEL_BUILD_DIR} M=${CMAKE_BINARY_DIR} modules
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Building TaxiDriver module"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Define the clean target
|
||||||
|
add_custom_target(clean_TaxiDriverModule
|
||||||
|
COMMAND ${CMAKE_MAKE_PROGRAM} -C ${KERNEL_BUILD_DIR} M=${CMAKE_BINARY_DIR} clean
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Cleaning TaxiDriver module"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Specify the files to be cleaned
|
||||||
|
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_BINARY_DIR}/*.ko")
|
||||||
7
km/Makefile
Normal file
7
km/Makefile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
obj-m += TaxiDriver.o
|
||||||
|
|
||||||
|
all:
|
||||||
|
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
||||||
|
|
||||||
|
clean:
|
||||||
|
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
|
||||||
394
km/TaxiDriver.c
Normal file
394
km/TaxiDriver.c
Normal file
@@ -0,0 +1,394 @@
|
|||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/sched/signal.h>
|
||||||
|
#include <linux/string.h> // Add this header for basename function
|
||||||
|
|
||||||
|
#define KERNEL_UPSTREAM 0
|
||||||
|
#define TESTING 0
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM==1
|
||||||
|
#include <linux/maple_tree.h>
|
||||||
|
#else
|
||||||
|
#include <linux/sched/mm.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DRIVER_NAME "TaxiDriver"
|
||||||
|
#define DRIVER
|
||||||
|
#include "../um/communication_struct.h"
|
||||||
|
|
||||||
|
static int major_number;
|
||||||
|
static struct task_struct *task;
|
||||||
|
|
||||||
|
static int device_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int device_release(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TESTING == 1
|
||||||
|
static unsigned long translate_physical_to_virtual(unsigned long paddr) {
|
||||||
|
unsigned long vaddr = 0xffff888000000000 | (paddr & (PAGE_SIZE - 1));
|
||||||
|
return vaddr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TESTING == 1
|
||||||
|
static unsigned long translate_virtual_to_physical(struct mm_struct *mm, unsigned long vaddr) {
|
||||||
|
pgd_t *pgd;
|
||||||
|
p4d_t *p4d;
|
||||||
|
pud_t *pud;
|
||||||
|
pmd_t *pmd;
|
||||||
|
pte_t *pte;
|
||||||
|
unsigned long pfn;
|
||||||
|
unsigned long paddr = 0;
|
||||||
|
|
||||||
|
if (!mm)
|
||||||
|
return 0; // Handle invalid mm_struct
|
||||||
|
|
||||||
|
pgd = pgd_offset(mm, vaddr);
|
||||||
|
if (!pgd_present(*pgd))
|
||||||
|
return 0; // Handle invalid pgd
|
||||||
|
|
||||||
|
p4d = p4d_offset(pgd, vaddr);
|
||||||
|
if (!p4d_present(*p4d))
|
||||||
|
return 0; // Handle invalid p4d
|
||||||
|
|
||||||
|
pud = pud_offset(p4d, vaddr);
|
||||||
|
if (!pud_present(*pud))
|
||||||
|
return 0; // Handle invalid pud
|
||||||
|
|
||||||
|
pmd = pmd_offset(pud, vaddr);
|
||||||
|
if (!pmd_present(*pmd))
|
||||||
|
return 0; // Handle invalid pmd
|
||||||
|
|
||||||
|
pte = pte_offset_map(pmd, vaddr);
|
||||||
|
if (!pte_present(*pte))
|
||||||
|
return 0; // Handle invalid pte
|
||||||
|
|
||||||
|
pfn = page_to_pfn(pte_page(*pte));
|
||||||
|
paddr = (pfn << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
|
||||||
|
pte_unmap(pte);
|
||||||
|
|
||||||
|
return paddr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int RPM(t_RPM args) {
|
||||||
|
struct mm_struct *mm;
|
||||||
|
unsigned long value = 0;
|
||||||
|
|
||||||
|
printk(KERN_INFO "TaxiDriver: RPM --> addr : 0x%lx, size : %ld\n", args.addr, args.size);
|
||||||
|
if (!args.addr)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!task) {
|
||||||
|
return -EINVAL; // Invalid argument
|
||||||
|
}
|
||||||
|
mm = get_task_mm(task);
|
||||||
|
if (mm) {
|
||||||
|
if (access_process_vm(task, args.addr, &value, args.size, 0) == args.size) {
|
||||||
|
printk(KERN_INFO "TaxiDriver: Value at 0x%lx: %lu\n", args.addr, value);
|
||||||
|
mmput(mm);
|
||||||
|
} else {
|
||||||
|
printk(KERN_ALERT "TaxiDriver: Failed to read value at 0x%lx\n", args.addr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (int)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WPM(t_WPM args) {
|
||||||
|
struct mm_struct *mm;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
printk(KERN_INFO "TaxiDriver: WPM --> addr : 0x%lx, size : %ld, value : %ld\n",
|
||||||
|
args.addr, args.size, args.value);
|
||||||
|
if (!args.addr)
|
||||||
|
return -1;
|
||||||
|
if (!task) {
|
||||||
|
return -EINVAL; // Invalid argument
|
||||||
|
}
|
||||||
|
mm = get_task_mm(task);
|
||||||
|
if (mm) {
|
||||||
|
if (access_process_vm(task, args.addr, &args.value, args.size, 1) == args.size) {
|
||||||
|
printk(KERN_INFO "TaxiDriver: Successfully wrote value %lu to 0x%lx\n", args.value, args.addr);
|
||||||
|
mmput(mm);
|
||||||
|
} else {
|
||||||
|
printk(KERN_ALERT "TaxiDriver: Failed to write value at 0x%lx\n", args.addr);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uintptr_t list_process_modules(const char *mod) {
|
||||||
|
struct vm_area_struct *vma;
|
||||||
|
#if KERNEL_UPSTREAM == 1
|
||||||
|
struct mm_struct *mm = task->mm;
|
||||||
|
VMA_ITERATOR(vmi, mm, 0);
|
||||||
|
|
||||||
|
for_each_vma(vmi, vma) {
|
||||||
|
if (vma->vm_file) {
|
||||||
|
struct file *file = vma->vm_file;
|
||||||
|
printk(KERN_INFO "TaxiDriver: Shared Library: %s start: 0x%lx end: 0x%lx\n",
|
||||||
|
file->f_path.dentry->d_name.name, vma->vm_start, vma->vm_end);
|
||||||
|
if (strcmp(file->f_path.dentry->d_name.name, mod) == 0)
|
||||||
|
return (uintptr_t)vma->vm_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
struct task_struct *task;
|
||||||
|
struct mm_struct *mm;
|
||||||
|
|
||||||
|
for_each_process(task) {
|
||||||
|
mm = get_task_mm(task);
|
||||||
|
|
||||||
|
if (mm) {
|
||||||
|
printk(KERN_INFO "\nTaxiDriver: PARENT PID: %d PROCESS: %s", task->pid, task->comm);
|
||||||
|
down_read(&mm->mmap_lock);
|
||||||
|
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
||||||
|
printk(KERN_INFO "TaxiDriver: Address Range: 0x%lx - 0x%lx", vma->vm_start, vma->vm_end);
|
||||||
|
|
||||||
|
if (vma->vm_file) {
|
||||||
|
char buf[256];
|
||||||
|
char *file_name = d_path(&vma->vm_file->f_path, buf, sizeof(buf));
|
||||||
|
//const char *base_name = kbasename(file_name); // Extract the base name
|
||||||
|
printk(KERN_INFO "TaxiDriver: Mapped File: %s", file_name);
|
||||||
|
//printk(KERN_INFO "TaxiDriver: Mapped File: %s", base_name);
|
||||||
|
if (strcmp(file_name, mod) == 0)
|
||||||
|
//if (strcmp(base_name, mod) == 0) // Compare with the base name
|
||||||
|
//printk(KERN_INFO "TaxiDriver: Mapped File %s found at 0x%lx - 0x%lx", base_name, vma->vm_start, vma->vm_end);
|
||||||
|
return (uintptr_t)vma->vm_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
up_read(&mm->mmap_lock);
|
||||||
|
mmput(mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//only checked for KERNEL_UPSTREAM == 0
|
||||||
|
#if KERNEL_UPSTREAM == 0
|
||||||
|
static unsigned long long list_pid_mod(t_PM args) {
|
||||||
|
printk(KERN_INFO "\nTaxiDriver list_pid_mod:%s", args.mod);
|
||||||
|
struct task_struct *task;
|
||||||
|
struct mm_struct *mm;
|
||||||
|
struct vm_area_struct *vma;
|
||||||
|
|
||||||
|
for_each_process(task) {
|
||||||
|
mm = get_task_mm(task);
|
||||||
|
|
||||||
|
if (mm) {
|
||||||
|
if(task->pid == args.pid)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO "\nTaxiDriver: PARENT PID: %d PROCESS: %s", task->pid, task->comm);
|
||||||
|
}
|
||||||
|
down_read(&mm->mmap_lock);
|
||||||
|
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
||||||
|
//printk(KERN_INFO "TaxiDriver: Address Range: 0x%lx - 0x%lx", vma->vm_start, vma->vm_end);
|
||||||
|
if (vma->vm_file) {
|
||||||
|
char buf[256];
|
||||||
|
char *file_name = d_path(&vma->vm_file->f_path, buf, sizeof(buf));
|
||||||
|
const char *base_name = kbasename(file_name);
|
||||||
|
if (strcmp(base_name, args.mod) == 0)
|
||||||
|
{
|
||||||
|
unsigned long long vmstartaddr = (unsigned long long)vma->vm_start;
|
||||||
|
if(vmstartaddr>0)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO "TaxiDriver: Mapped File %s found at 0x%lx - 0x%lx", base_name, vma->vm_start, vma->vm_end);
|
||||||
|
return vmstartaddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
up_read(&mm->mmap_lock);
|
||||||
|
mmput(mm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int init_process_by_pid(int target_pid) {
|
||||||
|
printk(KERN_INFO "TaxiDriver: Accessing process with PID: %d\n", target_pid);
|
||||||
|
|
||||||
|
struct pid *pid_struct;
|
||||||
|
pid_struct = find_get_pid(target_pid);
|
||||||
|
if (pid_struct) {
|
||||||
|
task = get_pid_task(pid_struct, PIDTYPE_PID);
|
||||||
|
if (task) {
|
||||||
|
const char *process_name = task->comm;
|
||||||
|
printk(KERN_INFO "TaxiDriver: Process with PID %d has name: %s\n", target_pid, process_name);
|
||||||
|
put_task_struct(task);
|
||||||
|
} else {
|
||||||
|
printk(KERN_INFO "TaxiDriver: Process with PID %d not found\n", target_pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
put_pid(pid_struct);
|
||||||
|
} else {
|
||||||
|
printk(KERN_INFO "TaxiDriver: Process with PID %d not found\n", target_pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; // A successful module initialization
|
||||||
|
}
|
||||||
|
|
||||||
|
static long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long arg)
|
||||||
|
{
|
||||||
|
struct s_WPM wpm_args;
|
||||||
|
struct s_RPM rpm_args;
|
||||||
|
#if KERNEL_UPSTREAM == 0
|
||||||
|
struct s_PM pm_args;
|
||||||
|
#endif
|
||||||
|
const char *mod = kmalloc(sizeof(char) * 256, GFP_KERNEL);
|
||||||
|
if (!mod)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uintptr_t addr = 0;
|
||||||
|
int pid;
|
||||||
|
long return_value = 0;
|
||||||
|
|
||||||
|
switch (ioctl_num) {
|
||||||
|
case IOCTL_GETMODULE:
|
||||||
|
if (copy_from_user((void *)mod, (int *)arg, sizeof(char *)))
|
||||||
|
return -EFAULT;
|
||||||
|
return_value = list_process_modules(mod);
|
||||||
|
addr = return_value;
|
||||||
|
kfree(mod);
|
||||||
|
break;
|
||||||
|
#if KERNEL_UPSTREAM == 0
|
||||||
|
case IOCTL_GETPIDMODULE:
|
||||||
|
if (copy_from_user(&pm_args, (int *)arg, sizeof(t_PM)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (copy_from_user(mod, pm_args.mod, 256)) // ptr/data Userspace to Kernel else perms/page fault
|
||||||
|
{
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
pm_args.mod = mod;
|
||||||
|
|
||||||
|
return_value = list_pid_mod(pm_args);
|
||||||
|
addr = return_value;
|
||||||
|
kfree(mod);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case IOCTL_OPENPROC:
|
||||||
|
if (copy_from_user(&pid, (int *)arg, sizeof(int)))
|
||||||
|
return -EFAULT;
|
||||||
|
return_value = init_process_by_pid(pid);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOCTL_RPM:
|
||||||
|
if (copy_from_user(&rpm_args, (int *)arg, sizeof(t_RPM)))
|
||||||
|
return -EFAULT;
|
||||||
|
if (rpm_args.addr == 0x69420) {
|
||||||
|
put_user(addr, rpm_args.out_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return_value = RPM(rpm_args);
|
||||||
|
put_user(return_value, rpm_args.out_addr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOCTL_WPM:
|
||||||
|
if (copy_from_user(&wpm_args, (int *)arg, sizeof(t_WPM)))
|
||||||
|
return -EFAULT;
|
||||||
|
return_value = WPM(wpm_args);
|
||||||
|
break;
|
||||||
|
#if KERNEL_UPSTREAM == 0 && TESTING==1
|
||||||
|
case IOCTL_VIRT_TO_PHYS:
|
||||||
|
{
|
||||||
|
struct mm_struct *mm = current->mm; // Get the current process's mm_struct
|
||||||
|
unsigned long vaddr;
|
||||||
|
unsigned long paddr;
|
||||||
|
|
||||||
|
if (copy_from_user(&vaddr, (unsigned long *)arg, sizeof(unsigned long))) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddr = translate_virtual_to_physical(mm, vaddr);
|
||||||
|
return_value = paddr;
|
||||||
|
if (copy_to_user((unsigned long *)arg, &return_value, sizeof(unsigned long))) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM == 0 && TESTING==1
|
||||||
|
case IOCTL_PHYS_TO_VIRT:
|
||||||
|
{
|
||||||
|
unsigned long paddr;
|
||||||
|
unsigned long vaddr;
|
||||||
|
|
||||||
|
if (copy_from_user(&paddr, (unsigned long *)arg, sizeof(unsigned long))) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
vaddr = translate_physical_to_virtual(paddr);
|
||||||
|
if (copy_to_user((unsigned long *)arg, &vaddr, sizeof(unsigned long))) {
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -ENOTTY;
|
||||||
|
}
|
||||||
|
#if KERNEL_UPSTREAM == 0 && TESTING==1
|
||||||
|
printk(KERN_INFO "return_value=0x%llx\n", (unsigned long long)return_value);
|
||||||
|
#endif
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct file_operations fops = {
|
||||||
|
.unlocked_ioctl = device_ioctl,
|
||||||
|
.open = device_open,
|
||||||
|
.release = device_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init driver_init(void)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO "TaxiDriver: Loaded\n");
|
||||||
|
|
||||||
|
// Dynamically allocate the major number
|
||||||
|
major_number = register_chrdev(0, DRIVER_NAME, &fops);
|
||||||
|
|
||||||
|
if (major_number < 0) {
|
||||||
|
printk(KERN_ALERT "TaxiDriver: Failed to register the driver.\n");
|
||||||
|
return major_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(KERN_INFO "TaxiDriver: Registered %s with major number %d\n", DRIVER_NAME, major_number);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit driver_exit(void)
|
||||||
|
{
|
||||||
|
unregister_chrdev(major_number, DRIVER_NAME);
|
||||||
|
printk(KERN_INFO "TaxiDriver: Unloaded\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(driver_init);
|
||||||
|
module_exit(driver_exit);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
12
km/install.sh
Executable file
12
km/install.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
sudo rmmod TaxiDriver
|
||||||
|
sudo rm /dev/TaxiDriver
|
||||||
|
# choose a unique MAJOR number; read out the used number and adjust in mknod for next use.
|
||||||
|
# MAJOR number has to match mknod to open device!
|
||||||
|
# 511, 250, 505
|
||||||
|
sudo mknod /dev/TaxiDriver c 506 0
|
||||||
|
sudo chmod 666 /dev/TaxiDriver
|
||||||
|
sudo insmod TaxiDriver.ko
|
||||||
|
cat /proc/devices | grep -i "TaxiDriver"
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cd src/client/imgui/backends
|
|
||||||
mv imgui_impl_opengl3* ..
|
|
||||||
mv imgui_impl_sdl3* ..
|
|
||||||
199
src/TaxiDriver.c
199
src/TaxiDriver.c
@@ -1,199 +0,0 @@
|
|||||||
#include <linux/init.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <linux/sched/signal.h>
|
|
||||||
#include <linux/maple_tree.h>
|
|
||||||
|
|
||||||
#define DRIVER_NAME "TaxiDriver"
|
|
||||||
#define DRIVER
|
|
||||||
#include "client/communication_struct.h"
|
|
||||||
|
|
||||||
static int major_number;
|
|
||||||
static struct task_struct *task;
|
|
||||||
|
|
||||||
static int device_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int device_release(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RPM(t_RPM args) {
|
|
||||||
struct mm_struct *mm;
|
|
||||||
unsigned long value = 0;
|
|
||||||
|
|
||||||
printk(KERN_INFO "TaxiDriver: RPM --> addr : 0x%lx, size : %ld\n", args.addr, args.size);
|
|
||||||
if (args.addr == 0)
|
|
||||||
return -1;
|
|
||||||
if (task == NULL) {
|
|
||||||
return -EINVAL; // Invalid argument
|
|
||||||
}
|
|
||||||
mm = get_task_mm(task);
|
|
||||||
if (mm != NULL) {
|
|
||||||
if (access_process_vm(task, args.addr, &value, args.size, 0) == args.size) {
|
|
||||||
printk(KERN_INFO "TaxiDriver: Value at 0x%lx: %lu\n", args.addr, value);
|
|
||||||
mmput(mm);
|
|
||||||
} else {
|
|
||||||
printk(KERN_ALERT "TaxiDriver: Failed to read value at 0x%lx\n", args.addr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (int)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WPM(t_WPM args) {
|
|
||||||
struct mm_struct *mm;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
printk(KERN_INFO "TaxiDriver: WPM --> addr : 0x%lx, size : %ld, value : %ld\n",
|
|
||||||
args.addr, args.size, args.value);
|
|
||||||
if (args.addr == 0)
|
|
||||||
return -1;
|
|
||||||
if (task == NULL) {
|
|
||||||
return -EINVAL; // Invalid argument
|
|
||||||
}
|
|
||||||
mm = get_task_mm(task);
|
|
||||||
if (mm != NULL) {
|
|
||||||
if (access_process_vm(task, args.addr, &args.value, args.size, 1) == args.size) {
|
|
||||||
printk(KERN_INFO "TaxiDriver: Successfully wrote value %lu to 0x%lx\n", args.value, args.addr);
|
|
||||||
mmput(mm);
|
|
||||||
} else {
|
|
||||||
printk(KERN_ALERT "TaxiDriver: Failed to write value at 0x%lx\n", args.addr);
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = -EINVAL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uintptr_t list_process_modules(const char *mod) {
|
|
||||||
struct mm_struct *mm = task->mm;
|
|
||||||
struct vm_area_struct *vma;
|
|
||||||
VMA_ITERATOR(vmi, mm, 0);
|
|
||||||
|
|
||||||
for_each_vma(vmi, vma) {
|
|
||||||
if (vma->vm_file) {
|
|
||||||
struct file *file = vma->vm_file;
|
|
||||||
printk(KERN_INFO "TaxiDriver: Shared Library: %s start: 0x%lx end: 0x%lx\n",
|
|
||||||
file->f_path.dentry->d_name.name, vma->vm_start, vma->vm_end);
|
|
||||||
if (strcmp(file->f_path.dentry->d_name.name, mod) == 0)
|
|
||||||
return (uintptr_t)vma->vm_start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int init_process_by_pid(int target_pid) {
|
|
||||||
printk(KERN_INFO "TaxiDriver: Accessing process with PID: %d\n", target_pid);
|
|
||||||
|
|
||||||
struct pid *pid_struct;
|
|
||||||
pid_struct = find_get_pid(target_pid);
|
|
||||||
if (pid_struct != NULL) {
|
|
||||||
task = get_pid_task(pid_struct, PIDTYPE_PID);
|
|
||||||
if (task != NULL) {
|
|
||||||
const char *process_name = task->comm;
|
|
||||||
printk(KERN_INFO "TaxiDriver: Process with PID %d has name: %s\n", target_pid, process_name);
|
|
||||||
put_task_struct(task);
|
|
||||||
} else {
|
|
||||||
printk(KERN_INFO "TaxiDriver: Process with PID %d not found\n", target_pid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
put_pid(pid_struct);
|
|
||||||
} else {
|
|
||||||
printk(KERN_INFO "TaxiDriver: Process with PID %d not found\n", target_pid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1; // A successful module initialization
|
|
||||||
}
|
|
||||||
|
|
||||||
static long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long arg)
|
|
||||||
{
|
|
||||||
struct s_WPM wpm_args;
|
|
||||||
struct s_RPM rpm_args;
|
|
||||||
const char *mod = kmalloc(sizeof(char) * 256, GFP_KERNEL);
|
|
||||||
if (!mod)
|
|
||||||
return -ENOMEM;
|
|
||||||
static uintptr_t addr = 0;
|
|
||||||
int pid;
|
|
||||||
long return_value = 0;
|
|
||||||
|
|
||||||
switch (ioctl_num) {
|
|
||||||
case IOCTL_GETMODULE:
|
|
||||||
if (copy_from_user((void *)mod, (int *)arg, sizeof(char *)))
|
|
||||||
return -EFAULT;
|
|
||||||
return_value = list_process_modules(mod);
|
|
||||||
addr = return_value;
|
|
||||||
kfree(mod);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IOCTL_OPENPROC:
|
|
||||||
if (copy_from_user(&pid, (int *)arg, sizeof(int)))
|
|
||||||
return -EFAULT;
|
|
||||||
return_value = init_process_by_pid(pid);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IOCTL_RPM:
|
|
||||||
if (copy_from_user(&rpm_args, (int *)arg, sizeof(t_RPM)))
|
|
||||||
return -EFAULT;
|
|
||||||
if (rpm_args.addr == 0x69420) {
|
|
||||||
put_user(addr, rpm_args.out_addr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return_value = RPM(rpm_args);
|
|
||||||
put_user(return_value, rpm_args.out_addr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IOCTL_WPM:
|
|
||||||
if (copy_from_user(&wpm_args, (int *)arg, sizeof(t_WPM)))
|
|
||||||
return -EFAULT;
|
|
||||||
return_value = WPM(wpm_args);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -ENOTTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct file_operations fops = {
|
|
||||||
.unlocked_ioctl = device_ioctl,
|
|
||||||
.open = device_open,
|
|
||||||
.release = device_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init driver_init(void)
|
|
||||||
{
|
|
||||||
printk(KERN_INFO "TaxiDriver: Loaded\n");
|
|
||||||
|
|
||||||
// Dynamically allocate the major number
|
|
||||||
major_number = register_chrdev(0, DRIVER_NAME, &fops);
|
|
||||||
|
|
||||||
if (major_number < 0) {
|
|
||||||
printk(KERN_ALERT "TaxiDriver: Failed to register the driver.\n");
|
|
||||||
return major_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
printk(KERN_INFO "TaxiDriver: Registered %s with major number %d\n", DRIVER_NAME, major_number);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit driver_exit(void)
|
|
||||||
{
|
|
||||||
unregister_chrdev(major_number, DRIVER_NAME);
|
|
||||||
printk(KERN_INFO "TaxiDriver: Unloaded\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(driver_init);
|
|
||||||
module_exit(driver_exit);
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
SRC = main.cpp \
|
|
||||||
memory.cpp \
|
|
||||||
overlay.cpp \
|
|
||||||
imgui/*.cpp
|
|
||||||
OBJ = $(SRC:.cpp=.o)
|
|
||||||
NAME = Revird
|
|
||||||
INC = -Iimgui/
|
|
||||||
CFLAGS = -Wall -Wextra -Wpedantic -lSDL3 -lOpenGL
|
|
||||||
|
|
||||||
all: $(NAME)
|
|
||||||
|
|
||||||
$(NAME): $(OBJ)
|
|
||||||
g++ $(SRC) $(CFLAGS) $(INC) -o $(NAME)
|
|
||||||
mv $(NAME) ../../.
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJ)
|
|
||||||
|
|
||||||
fclean: clean
|
|
||||||
rm -f $(NAME)
|
|
||||||
|
|
||||||
re: fclean all
|
|
||||||
|
|
||||||
.PHONY : all $(NAME) clean fclean re
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef DRIVER
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IOCTL_OPENPROC _IOW('k', 1, int)
|
|
||||||
#define IOCTL_GETMODULE _IOW('k', 2, const char*)
|
|
||||||
#define IOCTL_RPM _IOW('k', 3, t_RPM)
|
|
||||||
#define IOCTL_WPM _IOW('k', 4, t_WPM)
|
|
||||||
|
|
||||||
typedef struct s_RPM
|
|
||||||
{
|
|
||||||
uintptr_t addr;
|
|
||||||
ssize_t size;
|
|
||||||
uintptr_t out;
|
|
||||||
uintptr_t *out_addr;
|
|
||||||
} t_RPM;
|
|
||||||
|
|
||||||
typedef struct s_WPM
|
|
||||||
{
|
|
||||||
uintptr_t addr;
|
|
||||||
ssize_t size;
|
|
||||||
uintptr_t value;
|
|
||||||
} t_WPM;
|
|
||||||
Submodule src/client/imgui deleted from 313676d200
@@ -1,23 +0,0 @@
|
|||||||
#include "memory.hpp"
|
|
||||||
#include "overlay.hpp"
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
//run_overlay();
|
|
||||||
if (!open_device())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int pid = get_pid("nsnake");
|
|
||||||
if (!open_process(pid))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uintptr_t addr = get_module("nsnake");
|
|
||||||
printf("module : 0x%lx\n", addr);
|
|
||||||
WPM<int>(addr + 0x1d71510, 1337);
|
|
||||||
|
|
||||||
int out = RPM<int>(addr + 0x1d71510);
|
|
||||||
printf("Value from RPM: %d\n", out);
|
|
||||||
|
|
||||||
close_device();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
#include "overlay.hpp"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "imgui/imgui.h"
|
|
||||||
#include "imgui/imgui_impl_sdl3.h"
|
|
||||||
#include "imgui/imgui_impl_opengl3.h"
|
|
||||||
#include <SDL3/SDL.h>
|
|
||||||
#include <SDL3/SDL_opengl.h>
|
|
||||||
|
|
||||||
int run_overlay(void)
|
|
||||||
{
|
|
||||||
// Setup SDL
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0)
|
|
||||||
{
|
|
||||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* glsl_version = "#version 130";
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
|
||||||
|
|
||||||
// Enable native IME.
|
|
||||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
|
||||||
|
|
||||||
// Create window with graphics context
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_UTILITY);
|
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", 1280, 720, window_flags);
|
|
||||||
if (window == nullptr)
|
|
||||||
{
|
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
|
||||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
|
||||||
SDL_GL_MakeCurrent(window, gl_context);
|
|
||||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
|
||||||
SDL_ShowWindow(window);
|
|
||||||
|
|
||||||
// Setup Dear ImGui context
|
|
||||||
IMGUI_CHECKVERSION();
|
|
||||||
ImGui::CreateContext();
|
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
|
||||||
ImGui::StyleColorsDark();
|
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
|
||||||
ImGui_ImplSDL3_InitForOpenGL(window, gl_context);
|
|
||||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
|
||||||
|
|
||||||
// Main loop
|
|
||||||
bool done = false;
|
|
||||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
|
||||||
while (!done)
|
|
||||||
{
|
|
||||||
SDL_Event event;
|
|
||||||
while (SDL_PollEvent(&event))
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
|
||||||
if (event.type == SDL_EVENT_QUIT)
|
|
||||||
done = true;
|
|
||||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the Dear ImGui frame
|
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
|
||||||
ImGui_ImplSDL3_NewFrame();
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
ImGui::ShowDemoWindow();
|
|
||||||
|
|
||||||
// Rendering
|
|
||||||
ImGui::Render();
|
|
||||||
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
|
||||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
||||||
SDL_GL_SwapWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
ImGui_ImplOpenGL3_Shutdown();
|
|
||||||
ImGui_ImplSDL3_Shutdown();
|
|
||||||
ImGui::DestroyContext();
|
|
||||||
|
|
||||||
SDL_GL_DeleteContext(gl_context);
|
|
||||||
SDL_DestroyWindow(window);
|
|
||||||
SDL_Quit();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
int run_overlay(void);
|
|
||||||
19
um/Makefile
Normal file
19
um/Makefile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
APP_NAME = main
|
||||||
|
APP_SRCS = main.cpp memory.cpp
|
||||||
|
APP_OBJS = $(APP_SRCS:.cpp=.o)
|
||||||
|
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -Wall -Werror
|
||||||
|
|
||||||
|
all: $(APP_NAME)
|
||||||
|
|
||||||
|
$(APP_NAME): $(APP_OBJS)
|
||||||
|
$(CXX) $(CXXFLAGS) -o $@ $(APP_OBJS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(APP_NAME) $(APP_OBJS)
|
||||||
|
|
||||||
|
$(APP_OBJS): %.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
41
um/communication_struct.h
Normal file
41
um/communication_struct.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef DRIVER
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IOCTL_OPENPROC _IOW('k', 1, int)
|
||||||
|
#define IOCTL_GETMODULE _IOW('k', 2, const char*)
|
||||||
|
#define IOCTL_RPM _IOW('k', 3, t_RPM)
|
||||||
|
#define IOCTL_WPM _IOW('k', 4, t_WPM)
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM == 0
|
||||||
|
#define IOCTL_GETPIDMODULE _IOWR('k', 5, t_PM)
|
||||||
|
#if TESTING == 1
|
||||||
|
#define IOCTL_VIRT_TO_PHYS _IOWR('k', 6, unsigned long)
|
||||||
|
#define IOCTL_PHYS_TO_VIRT _IOWR('k', 7, unsigned long)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct s_RPM
|
||||||
|
{
|
||||||
|
uintptr_t addr;
|
||||||
|
ssize_t size;
|
||||||
|
uintptr_t out;
|
||||||
|
uintptr_t *out_addr;
|
||||||
|
} t_RPM;
|
||||||
|
|
||||||
|
typedef struct s_WPM
|
||||||
|
{
|
||||||
|
uintptr_t addr;
|
||||||
|
ssize_t size;
|
||||||
|
uintptr_t value;
|
||||||
|
} t_WPM;
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM == 0
|
||||||
|
typedef struct s_PM {
|
||||||
|
int pid;
|
||||||
|
const char *mod;
|
||||||
|
} t_PM;
|
||||||
|
#endif
|
||||||
67
um/main.cpp
Normal file
67
um/main.cpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include "memory.hpp"
|
||||||
|
|
||||||
|
std::string target_proc_name{"test_app"};
|
||||||
|
std::string target_mod_name{"libmath_module.so"};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
//run_overlay();
|
||||||
|
if (!open_device())
|
||||||
|
return -1;
|
||||||
|
std::cout << "[Main]device opened" << std::endl;
|
||||||
|
|
||||||
|
int pid = get_pid(target_proc_name.c_str());
|
||||||
|
std::cout << "pid of " << target_proc_name << "=" << std::dec << pid << std::endl;
|
||||||
|
if (!open_process(pid))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint64_t addr;
|
||||||
|
std::ifstream inFile("test/addr.txt");
|
||||||
|
if (!inFile.is_open()) {
|
||||||
|
std::cerr << "Error: Could not open the file for reading." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
inFile >> std::hex;
|
||||||
|
if (inFile >> addr) {
|
||||||
|
std::cout << "Read from file var_virtaddr=" << std::hex << addr << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Error: Failed to read value from file." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
inFile.close();
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM==1
|
||||||
|
uint64_t mod_primary_addr = get_module(target_proc_name.c_str());
|
||||||
|
#else
|
||||||
|
uint64_t mod_primary_addr = get_pid_module(pid, target_proc_name.c_str());
|
||||||
|
#endif
|
||||||
|
std::cout << "module of " << target_proc_name << "=" << std::hex << mod_primary_addr << std::endl;
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM==1
|
||||||
|
uint64_t modaddr_libmath_addr = get_module(target_mod_name.c_str());
|
||||||
|
#else
|
||||||
|
uint64_t modaddr_libmath_addr = get_pid_module(pid, target_mod_name.c_str());
|
||||||
|
#endif
|
||||||
|
std::cout << "module of " << target_mod_name << "=" << std::hex << modaddr_libmath_addr << std::endl;
|
||||||
|
|
||||||
|
//mod_primary_addr = 0; // primary_module not required
|
||||||
|
int value_read = RPM<int>(0 + addr);
|
||||||
|
std::cout << "Value before write=" << std::dec << value_read << std::endl;
|
||||||
|
|
||||||
|
WPM<int>(0 + addr, 1337);
|
||||||
|
value_read = RPM<int>(0 + addr);
|
||||||
|
std::cout << "Value after write=" << std::dec << value_read << std::endl;
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM==0 && TESTING==1
|
||||||
|
uint64_t physaddr = VIRT_TO_PHYS(0x7fff2a2cb7a4);
|
||||||
|
std::cout << "phys addr=" << std::hex << physaddr << std::endl;
|
||||||
|
uint64_t phys2virtaddr = PHYS_TO_VIRT(0x7fff2a2cb7a4);
|
||||||
|
std::cout << "phys2virtaddr=" << std::hex << phys2virtaddr << std::endl;
|
||||||
|
|
||||||
|
//attempt to read relative to proc primary module
|
||||||
|
int value_read_primarymod = RPM<int>(mod_primary_addr + 0x2A917D6757A4);
|
||||||
|
std::cout << "value_read_primarymod=" << std::dec << value_read_primarymod << std::endl;
|
||||||
|
#endif
|
||||||
|
close_device();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//pmap -x $(pidof test_app)
|
||||||
@@ -1,12 +1,4 @@
|
|||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
#include "communication_struct.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define DEVICE_FILE "/dev/TaxiDriver"
|
|
||||||
|
|
||||||
int file_desc = 0;
|
int file_desc = 0;
|
||||||
int open_device(void)
|
int open_device(void)
|
||||||
@@ -35,7 +27,7 @@ int get_pid(const char *program_name) {
|
|||||||
|
|
||||||
// Open a pipe to execute the command and read the output
|
// Open a pipe to execute the command and read the output
|
||||||
fp = popen(command, "r");
|
fp = popen(command, "r");
|
||||||
if (fp == NULL) {
|
if (!fp) {
|
||||||
perror("popen");
|
perror("popen");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -58,9 +50,7 @@ int get_pid(const char *program_name) {
|
|||||||
|
|
||||||
int open_process(int pid)
|
int open_process(int pid)
|
||||||
{
|
{
|
||||||
int ret;
|
uint64_t ret = ioctl(file_desc, IOCTL_OPENPROC, &pid);
|
||||||
|
|
||||||
ret = ioctl(file_desc, IOCTL_OPENPROC, &pid);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Revird: openprocess failed.");
|
perror("Revird: openprocess failed.");
|
||||||
close(file_desc);
|
close(file_desc);
|
||||||
@@ -71,7 +61,7 @@ int open_process(int pid)
|
|||||||
|
|
||||||
uintptr_t get_module(const char *mod)
|
uintptr_t get_module(const char *mod)
|
||||||
{
|
{
|
||||||
int ret = ioctl(file_desc, IOCTL_GETMODULE, mod);
|
uint64_t ret = ioctl(file_desc, IOCTL_GETMODULE, mod);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Revird: getmodule failed.");
|
perror("Revird: getmodule failed.");
|
||||||
close(file_desc);
|
close(file_desc);
|
||||||
@@ -81,3 +71,46 @@ uintptr_t get_module(const char *mod)
|
|||||||
uintptr_t addr = RPM<uintptr_t>(0x69420);
|
uintptr_t addr = RPM<uintptr_t>(0x69420);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM == 0
|
||||||
|
uintptr_t get_pid_module(int pid, const char *mod) {
|
||||||
|
struct s_PM pma;
|
||||||
|
pma.pid = pid;
|
||||||
|
pma.mod = mod;
|
||||||
|
|
||||||
|
uint64_t ret = ioctl(file_desc, IOCTL_GETPIDMODULE, &pma);
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("Revird: get_pid_module failed.");
|
||||||
|
close(file_desc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t addr = RPM<uintptr_t>(0x69420);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM == 0 && TESTING==1
|
||||||
|
uintptr_t VIRT_TO_PHYS(uintptr_t vaddr) {
|
||||||
|
uint64_t ret = ioctl(file_desc, IOCTL_VIRT_TO_PHYS, vaddr);
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("VIRT_TO_PHYS failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// At this point, 'vaddr' contains the physical address.
|
||||||
|
return vaddr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KERNEL_UPSTREAM == 0 && TESTING==1
|
||||||
|
uintptr_t PHYS_TO_VIRT(uintptr_t paddr) {
|
||||||
|
uint64_t ret = ioctl(file_desc, IOCTL_PHYS_TO_VIRT, &paddr);
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("PHYS_TO_VIRT failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, 'paddr' contains the virtual address.
|
||||||
|
return paddr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -4,7 +4,12 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
//#include "overlay.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <cstdint>
|
||||||
#include "communication_struct.h"
|
#include "communication_struct.h"
|
||||||
|
#define DEVICE_FILE "/dev/TaxiDriver"
|
||||||
|
|
||||||
extern int file_desc;
|
extern int file_desc;
|
||||||
int open_device(void);
|
int open_device(void);
|
||||||
@@ -20,7 +25,7 @@ T RPM(uintptr_t address)
|
|||||||
args.out = 0;
|
args.out = 0;
|
||||||
args.out_addr = &args.out;
|
args.out_addr = &args.out;
|
||||||
|
|
||||||
int ret = ioctl(file_desc, IOCTL_RPM, &args);
|
uint64_t ret = ioctl(file_desc, IOCTL_RPM, &args);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Revird: RPM failed.");
|
perror("Revird: RPM failed.");
|
||||||
close(file_desc);
|
close(file_desc);
|
||||||
@@ -36,9 +41,7 @@ void WPM(uintptr_t address, T value)
|
|||||||
args_wpm.addr = address;
|
args_wpm.addr = address;
|
||||||
args_wpm.size = sizeof(T);
|
args_wpm.size = sizeof(T);
|
||||||
args_wpm.value = value;
|
args_wpm.value = value;
|
||||||
int ret;
|
uint64_t ret = ioctl(file_desc, IOCTL_WPM, &args_wpm);
|
||||||
|
|
||||||
ret = ioctl(file_desc, IOCTL_WPM, &args_wpm);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Revird: WPM failed.");
|
perror("Revird: WPM failed.");
|
||||||
close(file_desc);
|
close(file_desc);
|
||||||
@@ -50,3 +53,10 @@ void WPM(uintptr_t address, T value)
|
|||||||
void WPM(uintptr_t addr, uintptr_t value, ssize_t size);
|
void WPM(uintptr_t addr, uintptr_t value, ssize_t size);
|
||||||
int open_process(int pid);
|
int open_process(int pid);
|
||||||
uintptr_t get_module(const char *mod);
|
uintptr_t get_module(const char *mod);
|
||||||
|
#if KERNEL_UPSTREAM == 0
|
||||||
|
uintptr_t get_pid_module(int pid, const char *mod);
|
||||||
|
#if TESTING==1
|
||||||
|
uintptr_t VIRT_TO_PHYS(uintptr_t vaddr);
|
||||||
|
uintptr_t PHYS_TO_VIRT(uintptr_t paddr);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
35
um/test/Makefile
Normal file
35
um/test/Makefile
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Define the name of your application
|
||||||
|
APP_NAME = test_app
|
||||||
|
|
||||||
|
# Source files for your application
|
||||||
|
APP_SRCS = main.cpp
|
||||||
|
APP_OBJS = $(APP_SRCS:.cpp=.o)
|
||||||
|
|
||||||
|
# Compiler and compiler flags
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -Wall -Werror -fexceptions
|
||||||
|
|
||||||
|
# Library name and source files
|
||||||
|
LIB_NAME = libmath_module.so
|
||||||
|
LIB_SRCS = math_module.cpp
|
||||||
|
LIB_OBJS = $(LIB_SRCS:.cpp=.o)
|
||||||
|
|
||||||
|
# Additional flags for creating PIC code
|
||||||
|
PICFLAGS = -fPIC
|
||||||
|
|
||||||
|
# The default target is 'all', which builds your application
|
||||||
|
all: $(APP_NAME) $(LIB_NAME)
|
||||||
|
|
||||||
|
$(APP_NAME): $(APP_OBJS) $(LIB_NAME)
|
||||||
|
$(CXX) $(CXXFLAGS) -o $@ $(APP_OBJS) -L. -lmath_module -Wl,-rpath,'$$ORIGIN'
|
||||||
|
|
||||||
|
$(LIB_NAME): $(LIB_OBJS)
|
||||||
|
$(CXX) -shared -o $@ $(LIB_OBJS) $(CXXFLAGS)
|
||||||
|
|
||||||
|
# Compile source files to object files
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $(PICFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Clean rule to remove the executable, object files, and library
|
||||||
|
clean:
|
||||||
|
rm -f $(APP_NAME) $(APP_OBJS) $(LIB_NAME) $(LIB_OBJS)
|
||||||
1
um/test/addr.txt
Normal file
1
um/test/addr.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0x7fff7203ed94
|
||||||
44
um/test/main.cpp
Normal file
44
um/test/main.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "math_module.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
MathModule math;
|
||||||
|
|
||||||
|
int result = math.add(10, 5);
|
||||||
|
std::cout << "10 + 5 = " << result << std::endl;
|
||||||
|
|
||||||
|
result = math.subtract(10, 5);
|
||||||
|
std::cout << "10 - 5 = " << result << std::endl;
|
||||||
|
|
||||||
|
result = math.multiply(10, 5);
|
||||||
|
std::cout << "10 * 5 = " << result << std::endl;
|
||||||
|
|
||||||
|
double divisionResult = math.divide(10.0, 5.0);
|
||||||
|
std::cout << "10 / 5 = " << divisionResult << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
int var = 0;
|
||||||
|
uint64_t* var_virtaddr = reinterpret_cast<uint64_t*>(&var);
|
||||||
|
std::ofstream outFile("addr.txt");
|
||||||
|
if (!outFile.is_open()) {
|
||||||
|
std::cerr << "Error: Could not open the file for writing." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
outFile << var_virtaddr;
|
||||||
|
outFile.close();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int random_increment = std::rand() % 100; // Generate a random number between 0 and 99
|
||||||
|
std::cout << "before inc value=" << std::dec << var << "@" << std::hex << var_virtaddr << std::endl;
|
||||||
|
var += random_increment;
|
||||||
|
std::cout << "after inc value=" << std::dec << var << "@" << std::hex << var_virtaddr << std::endl;
|
||||||
|
std::cin.get(); // Wait for Enter key press
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
|
||||||
24
um/test/math_module.cpp
Normal file
24
um/test/math_module.cpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "math_module.h"
|
||||||
|
|
||||||
|
MathModule::MathModule() {
|
||||||
|
// Constructor, if any initialization is needed
|
||||||
|
}
|
||||||
|
|
||||||
|
int MathModule::add(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MathModule::subtract(int a, int b) {
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MathModule::multiply(int a, int b) {
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double MathModule::divide(double a, double b) {
|
||||||
|
if (b == 0) {
|
||||||
|
throw "Division by zero is not allowed.";
|
||||||
|
}
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
14
um/test/math_module.h
Normal file
14
um/test/math_module.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef MATH_MODULE_H
|
||||||
|
#define MATH_MODULE_H
|
||||||
|
|
||||||
|
class MathModule {
|
||||||
|
public:
|
||||||
|
MathModule(); // Constructor
|
||||||
|
|
||||||
|
int add(int a, int b);
|
||||||
|
int subtract(int a, int b);
|
||||||
|
int multiply(int a, int b);
|
||||||
|
double divide(double a, double b);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user