aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOrfeas <38209077+0xfea5@users.noreply.github.com>2024-04-16 03:33:40 +0300
committerOrfeas <38209077+0xfea5@users.noreply.github.com>2024-04-16 04:09:21 +0300
commit7de6d2226b9746e2a2d90a00aa130282cb23605d (patch)
treed98fd7dbdc816ced520e92a3be202d0ce0b32bbd
parentParse /proc/pid/maps (diff)
downloadlinux-game-trainer-7de6d2226b9746e2a2d90a00aa130282cb23605d.tar.gz
linux-game-trainer-7de6d2226b9746e2a2d90a00aa130282cb23605d.zip
Memory scanning to find byte patterns
-rw-r--r--src/main.c18
-rw-r--r--src/vm.c69
-rw-r--r--src/vm.h12
3 files changed, 92 insertions, 7 deletions
diff --git a/src/main.c b/src/main.c
index e255ec5..ee33aac 100644
--- a/src/main.c
+++ b/src/main.c
@@ -23,9 +23,23 @@ int main(int argc, char *argv[])
23 waitpid(pid, NULL, __WALL); 23 waitpid(pid, NULL, __WALL);
24 LOG("Attached to process %d\n", pid); 24 LOG("Attached to process %d\n", pid);
25 25
26 /* Do stuff ... */ 26 char *byte_seq = "secret text";
27 parse_vmmap(pid); 27 size_t byte_seq_len = strlen(byte_seq);
28 MemscanResult *head = memscan(pid, (uint8_t*)byte_seq, byte_seq_len);
29 MemscanResult *cur = head;
28 30
31 printf("\n\n\nMemory scan results:\n");
32 printf("%-16s|%-16s|%-10s|%-s\n", "Address", "Base", "Offset", "Name");
33 puts("--------------------------------------------------");
34 while (cur) {
35 printf("%-16p|%-16p|%#-10lx|%-s\n",
36 cur->mapping->begin + cur->offset,
37 cur->mapping->begin,
38 cur->offset,
39 cur->mapping->name);
40 cur = cur->next;
41 }
42 printf("\n\n");
29 ptrace(PTRACE_DETACH, pid, NULL, NULL); 43 ptrace(PTRACE_DETACH, pid, NULL, NULL);
30 LOG("Detached from process %d\n", pid); 44 LOG("Detached from process %d\n", pid);
31 45
diff --git a/src/vm.c b/src/vm.c
index 8e62426..82f67fd 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -3,6 +3,7 @@
3#include <string.h> 3#include <string.h>
4#include <ctype.h> 4#include <ctype.h>
5#include <stdint.h> 5#include <stdint.h>
6#include <sys/mman.h>
6#include "vm.h" 7#include "vm.h"
7#include "util.h" 8#include "util.h"
8 9
@@ -45,8 +46,8 @@ VMMapping* parse_vmmap (int pid)
45 46
46 VMMapping *new_mapping = xmalloc(sizeof(VMMapping)); 47 VMMapping *new_mapping = xmalloc(sizeof(VMMapping));
47 *new_mapping = (VMMapping) { 48 *new_mapping = (VMMapping) {
48 .begin = begin, 49 .begin = (void*)begin,
49 .end = end, 50 .end = (void*)end,
50 .r = perms[0] == 'r', 51 .r = perms[0] == 'r',
51 .w = perms[1] == 'w', 52 .w = perms[1] == 'w',
52 .x = perms[2] == 'x', 53 .x = perms[2] == 'x',
@@ -63,7 +64,7 @@ VMMapping* parse_vmmap (int pid)
63 head = cur = new_mapping; 64 head = cur = new_mapping;
64 } 65 }
65 66
66 LOG("%lx-%lx %c%c%c%c %s\n", 67 LOG("%p-%p %c%c%c%c %s\n",
67 cur->begin, 68 cur->begin,
68 cur->end, 69 cur->end,
69 cur->r ? 'r' : '-', 70 cur->r ? 'r' : '-',
@@ -75,3 +76,65 @@ VMMapping* parse_vmmap (int pid)
75 76
76 return head; 77 return head;
77} 78}
79
80static off_t memfind(const uint8_t *hay, size_t hay_size, const uint8_t *needle, size_t needle_size)
81{
82 for (off_t i = 0 ; i < hay_size - needle_size; ++i) {
83 if (memcmp(&hay[i], needle, needle_size) == 0) {
84 return i;
85 }
86 }
87 return hay_size;
88}
89
90MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
91{
92 char fmem_path[1024] = {0};
93 sprintf(fmem_path, "/proc/%d/mem", pid);
94 FILE *fmem = fopen(fmem_path, "rb+");
95 VMMapping *vmmaps_head = parse_vmmap(pid);
96 VMMapping *cur_vmmap = vmmaps_head;
97 MemscanResult *cur = NULL, *head = NULL;
98
99 while (cur_vmmap) {
100 if (!cur_vmmap->r) {
101 cur_vmmap = cur_vmmap->next;
102 continue;
103 }
104 LOG("Scanning [%p]\n", cur_vmmap->begin);
105
106 size_t region_size = cur_vmmap->end - cur_vmmap->begin;
107 uint8_t region_data[region_size];
108 fseek(fmem, (off_t)cur_vmmap->begin, SEEK_SET);
109 fread(region_data, 1, region_size, fmem);
110
111 off_t offset = 0;
112 while (offset += memfind(region_data + offset,
113 region_size - offset,
114 byte_seq,
115 byte_seq_len),
116 offset < region_size) {
117 LOG("Matched pattern at [%p]\n", cur_vmmap->begin + (off_t)offset);
118 MemscanResult *new_result = xmalloc(sizeof(MemscanResult));
119 *new_result = (MemscanResult) {
120 .mapping = cur_vmmap,
121 .offset = offset,
122 .next = NULL,
123 };
124
125 if (head) {
126 cur->next = new_result;
127 cur = new_result;
128 }
129 else {
130 head = cur = new_result;
131 }
132
133 offset += byte_seq_len;
134 }
135
136 cur_vmmap = cur_vmmap->next;
137 }
138
139 return head;
140}
diff --git a/src/vm.h b/src/vm.h
index 25849e7..4a994f9 100644
--- a/src/vm.h
+++ b/src/vm.h
@@ -3,8 +3,8 @@
3#include <stdint.h> 3#include <stdint.h>
4 4
5typedef struct VMMapping { 5typedef struct VMMapping {
6 uint64_t begin; 6 void *begin;
7 uint64_t end; 7 void *end;
8 uint8_t r:1; 8 uint8_t r:1;
9 uint8_t w:1; 9 uint8_t w:1;
10 uint8_t x:1; 10 uint8_t x:1;
@@ -14,6 +14,14 @@ typedef struct VMMapping {
14 struct VMMapping *next; 14 struct VMMapping *next;
15} VMMapping; 15} VMMapping;
16 16
17typedef struct MemscanResult {
18 VMMapping *mapping;
19 off_t offset;
20 struct MemscanResult *next;
21} MemscanResult;
22
17VMMapping* parse_vmmap (int pid); 23VMMapping* parse_vmmap (int pid);
18 24
25MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len);
26
19#endif // _VM_H_ 27#endif // _VM_H_