Created
July 1, 2023 07:44
-
-
Save Mufanc/7b0d7bfdcf1bc31534dc7089f7a9bf28 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdlib> | |
#include <iostream> | |
#include <sys/inotify.h> | |
#include <sys/mman.h> | |
#include <sys/mount.h> | |
#include <sys/stat.h> | |
#include <sys/unistd.h> | |
#define TMP_FILE "/tmp/fake.brightness" | |
#define HIJACK_FILE "/sys/class/backlight/intel_backlight/brightness" | |
#define CHECK_ERR(func, ...) ({ \ | |
auto result = func(__VA_ARGS__); \ | |
if (result == -1) { \ | |
std::perror(#func); \ | |
std::exit(EXIT_FAILURE); \ | |
} \ | |
result; \ | |
}) | |
#define PRINT_LOG(pattern, ...) printf(("[*] " pattern "\n"), ##__VA_ARGS__) | |
int open_overlay() { | |
int fd; | |
if (access(TMP_FILE, F_OK) == 0) { | |
CHECK_ERR(chown, TMP_FILE, 0, 0); | |
CHECK_ERR(chmod, TMP_FILE, 0644); | |
fd = CHECK_ERR(open, TMP_FILE, O_RDONLY); | |
} else { | |
fd = CHECK_ERR(open, TMP_FILE, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | |
} | |
return fd; | |
} | |
int init_inotify() { | |
int inotify_fd = CHECK_ERR(inotify_init); | |
CHECK_ERR(inotify_add_watch, inotify_fd, TMP_FILE, IN_CLOSE_WRITE); | |
return inotify_fd; | |
} | |
int mount_overlay() { | |
struct stat buf_overlay { }, buf_hijack { }; | |
CHECK_ERR(stat, TMP_FILE, &buf_overlay); | |
CHECK_ERR(stat, HIJACK_FILE, &buf_hijack); | |
if (buf_overlay.st_dev == buf_hijack.st_dev && buf_overlay.st_ino == buf_hijack.st_ino) { | |
PRINT_LOG("brightness hijack detected, umount old file first!"); | |
CHECK_ERR(umount, HIJACK_FILE); | |
} | |
int original_fd = open(HIJACK_FILE, O_WRONLY); | |
CHECK_ERR(mount, TMP_FILE, HIJACK_FILE, "none", MS_BIND, nullptr); | |
PRINT_LOG("bind mount: " TMP_FILE " -> " HIJACK_FILE); | |
return original_fd; | |
} | |
int main() { | |
if (geteuid() != 0) { | |
PRINT_LOG("Please run as root!\n"); | |
return EXIT_FAILURE; | |
} | |
PRINT_LOG("current pid: %d", getpid()); | |
const int page_size = getpagesize(); | |
int overlay_fd = open_overlay(); | |
int inotify_fd = init_inotify(); | |
int original_fd = mount_overlay(); | |
void *addr = mmap(nullptr, page_size, PROT_READ, MAP_SHARED, overlay_fd, 0); | |
close(overlay_fd); | |
char buffer[4096] __attribute__((aligned(__alignof__(struct inotify_event)))); | |
for (;;) { | |
ssize_t count = read(inotify_fd, buffer, sizeof(buffer)); | |
if (count == 0) { | |
perror("inotify"); | |
break; | |
} | |
const inotify_event *event; | |
for (char *ptr = buffer; ptr < buffer + count; ptr += sizeof(inotify_event) + event->len) { | |
event = reinterpret_cast<const inotify_event *>(ptr); | |
long level = std::strtol(static_cast<const char *>(addr), nullptr, 10); | |
printf("brightness level: %ld\r", level); | |
fflush(stdout); | |
CHECK_ERR(lseek, original_fd, 0, SEEK_SET); | |
CHECK_ERR(write, original_fd, addr, page_size); | |
} | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment