diff options
| author | Hunter Kvalevog <hunter@kvog.sh> | 2026-06-27 10:22:20 -0500 |
|---|---|---|
| committer | Hunter Kvalevog <hunter@kvog.sh> | 2026-06-27 10:22:20 -0500 |
| commit | 8311d0d8c42ca3972ebb7055994a8dae448ee932 (patch) | |
| tree | bb2ab66551f57308bfd1ea17a2a078067446f1ce | |
| parent | f5f267418f27c26e87074ba2ab74d2913932c67f (diff) | |
| -rw-r--r-- | README | 1 | ||||
| -rwxr-xr-x | mempoke/build.sh | 4 | ||||
| -rw-r--r-- | mempoke/mempoke-injector.c | 153 | ||||
| -rw-r--r-- | mempoke/mempoke-target.c | 67 |
4 files changed, 0 insertions, 225 deletions
@@ -10,7 +10,6 @@ guaranteed to be correct, performant, safe, or (generally speaking) good. aarch64 AArch64 assembly experiments
ffmpeg-shadertoy Basic offline Shadertoy renderer
-mempoke Read/write to another process's memory
vk-cube Spinning cube Vulkan demo
win-resize-mt Drawing while resizing on Windows (multi threaded)
win-resize-st Drawing while resizing on Windows (single threaded)
diff --git a/mempoke/build.sh b/mempoke/build.sh deleted file mode 100755 index ed4c5a8..0000000 --- a/mempoke/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -mkdir -p bin -cc -o bin/mempoke-target -Wall -Wextra -Wpedantic -O0 -g ./mempoke-target.c -cc -o bin/mempoke-injector -Wall -Wextra -Wpedantic -O0 -g ./mempoke-injector.c diff --git a/mempoke/mempoke-injector.c b/mempoke/mempoke-injector.c deleted file mode 100644 index 2d1c4a9..0000000 --- a/mempoke/mempoke-injector.c +++ /dev/null @@ -1,153 +0,0 @@ -// ================================================================================================ -// Example showing how to read/write process memory remotely. -// -// License: -// Copyright (c) 2026 Hunter Kvalevog -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE. -// ================================================================================================ - -#define _GNU_SOURCE - -#ifdef _WIN32 -# include <windows.h> -# include <psapi.h> -# include <tlhelp32.h> -#endif - -#ifdef __linux__ -# include <dirent.h> -# include <sys/uio.h> -#endif - -#include <assert.h> -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -typedef struct ProcessHandle ProcessHandle; -struct ProcessHandle -{ - int pid; - uintptr_t base; -#ifdef _WIN32 - HANDLE handle; -#endif -}; - -static inline void open_target_process(ProcessHandle *p) -{ -#ifdef _WIN32 - // ref: https://docs.microsoft.com/en-us/windows/win32/toolhelp/taking-a-snapshot-and-viewing-processes - HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - assert(snap != INVALID_HANDLE_VALUE); - - PROCESSENTRY32 pe = { .dwSize = sizeof(PROCESSENTRY32) }; - Process32First(snap, &pe); - - do { - if (!strcmp(pe.szExeFile, "mempoke-target.exe")) { - p->pid = pe.th32ProcessID; - p->handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, p->pid); - assert(p->handle && "failed to open process"); - - // First module is always the exe itself - HMODULE exe = 0; - DWORD needed = 0; - if (!EnumProcessModules(p->handle, &exe, sizeof(exe), &needed)) { - assert(0 && "EnumProcessModules failed"); - } - p->base = (uintptr_t)exe; - - return; - } - } while (Process32Next(snap, &pe)); -#endif -#ifdef __linux__ - DIR *proc = opendir("/proc"); - - struct dirent *d; - while ((d = readdir(proc))) { - pid_t pid = (pid_t)atoi(d->d_name); - if (pid <= 0) - continue; - - char comm[256]; - snprintf(comm, sizeof(comm), "/proc/%d/comm", pid); - - FILE *f = fopen(comm, "r"); - if (!f) - continue; - - if (fgets(comm, sizeof(comm), f) && !strncmp(comm, "mempoke-target", 14)) { - p->pid = pid; - - char maps_path[64]; - snprintf(maps_path, sizeof(maps_path), "/proc/%d/maps", p->pid); - - FILE *maps = fopen(maps_path, "r"); - fscanf(maps, "%" SCNxPTR "-", &p->base); - fclose(maps); - fclose(f); - return; - } - - fclose(f); - } -#endif - assert(0 && "couldn't find process"); -} - -int main(int argc, const char **argv) -{ - const uintptr_t offset = (argc > 1) ? strtoull(argv[1], 0, 0) : 0; - if (!offset) { - printf("Usage: %s <offset>\n example: %s 0x1234\n", argv[0], argv[0]); - return 1; - } - - ProcessHandle p; - open_target_process(&p); - - printf("target process: pid=%d base=0x%" PRIxPTR "\n", p.pid, p.base); - - int num = 0; - uintptr_t tgt = p.base + offset; - -#ifdef _WIN32 - if (!ReadProcessMemory(p.handle, (LPCVOID)tgt, &num, sizeof(num), 0)) { - assert(0 && "ReadProcessMemory failed"); - } -#endif -#ifdef __linux__ - struct iovec iov_rsrc = { .iov_base = (void *)tgt, .iov_len = sizeof(num) }; - struct iovec iov_rdst = { .iov_base = &num, .iov_len = sizeof(num) }; - if (process_vm_readv(p.pid, &iov_rdst, 1, &iov_rsrc, 1, 0) != sizeof(num)) { - assert(0 && "process_vm_readv failed"); - } -#endif - - printf("tgtnum = %d\n", num); - - num += 1; - -#ifdef _WIN32 - if (!WriteProcessMemory(p.handle, (LPVOID)tgt, &num, sizeof(num), 0)) { - assert(0 && "WriteProcessMemory failed"); - } -#endif -#ifdef __linux__ - struct iovec iov_wsrc = { .iov_base = &num, .iov_len = sizeof(num) }; - struct iovec iov_wdst = { .iov_base = (void *)tgt, .iov_len = sizeof(num) }; - if (process_vm_writev(p.pid, &iov_wsrc, 1, &iov_wdst, 1, 0) != sizeof(num)) { - assert(0 && "process_vm_writev failed"); - } -#endif -} - diff --git a/mempoke/mempoke-target.c b/mempoke/mempoke-target.c deleted file mode 100644 index 2c34780..0000000 --- a/mempoke/mempoke-target.c +++ /dev/null @@ -1,67 +0,0 @@ -// ================================================================================================ -// Example showing how to read/write process memory remotely. -// -// License: -// Copyright (c) 2026 Hunter Kvalevog -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE. -// ================================================================================================ - -#ifdef _WIN32 -# include <windows.h> -#endif - -#ifdef __linux__ -# include <unistd.h> -#endif - -#include <assert.h> -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> - -int tgtnum = 1; - -static inline uintptr_t get_process_base_address(void) -{ - uintptr_t base = 0; -#ifdef _WIN32 - base = (uintptr_t)GetModuleHandleW(0); -#endif -#ifdef __linux__ - FILE *maps = fopen("/proc/self/maps", "r"); - fscanf(maps, "%" SCNxPTR "-", &base); - fclose(maps); -#endif - assert(base); - return base; -} - -static inline void sleep_ms(unsigned ms) -{ -#ifdef _WIN32 - Sleep(ms); -#endif -#ifdef __linux__ - usleep(ms * 1000); -#endif -} - -int main(int argc, const char **argv) -{ - (void)argc; - (void)argv; - - printf("offset: 0x%" PRIxPTR "\n", (uintptr_t)&tgtnum - get_process_base_address()); - sleep_ms(3000); - - while (1) { - sleep_ms(1000); - printf("tgtnum: %d\n", tgtnum); - } -} - |