aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOrfeas <38209077+0xfea5@users.noreply.github.com>2024-04-21 16:27:55 +0300
committerOrfeas <38209077+0xfea5@users.noreply.github.com>2024-04-21 16:32:47 +0300
commitc79bbdb0448501987c0c16c2877c780143156d1e (patch)
treeff518148959a27e0efa655b3e40c4efea074a383
parentWrite other process' memory (diff)
downloadlinux-game-trainer-c79bbdb0448501987c0c16c2877c780143156d1e.tar.gz
linux-game-trainer-c79bbdb0448501987c0c16c2877c780143156d1e.zip
Changes in trainer interface, bug fixes & helper scripts
-rwxr-xr-xrun.sh10
-rw-r--r--scripts/read.sh11
-rw-r--r--scripts/scan.sh38
-rw-r--r--src/main.c125
-rw-r--r--src/vm.c33
-rw-r--r--src/vm.h12
6 files changed, 183 insertions, 46 deletions
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..6de5897
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,10 @@
1#!/bin/bash
2
3if [ "$#" -ne 1 ]
4then
5 printf "Usage: %s <tracee_pid>\n" "$0"
6 exit 1
7fi
8
9gnome-terminal -- bash ./scripts/scan.sh "$1"
10gnome-terminal -- bash ./scripts/read.sh "$1"
diff --git a/scripts/read.sh b/scripts/read.sh
new file mode 100644
index 0000000..38535e6
--- /dev/null
+++ b/scripts/read.sh
@@ -0,0 +1,11 @@
1#!/bin/bash
2
3if [ "$#" -ne 1 ]
4then
5 printf "Usage: %s <tracee_pid>\n" "$0"
6 exit 1
7fi
8
9scanfile=${SCANFILE:-/tmp/scanfile}
10pid="$1"
11watch -d -n 1 "xargs -r -a ${scanfile} ./hack.out ${pid} read 8 > /tmp/out 2> /dev/null && pr -t -m ${scanfile} /tmp/out"
diff --git a/scripts/scan.sh b/scripts/scan.sh
new file mode 100644
index 0000000..c700011
--- /dev/null
+++ b/scripts/scan.sh
@@ -0,0 +1,38 @@
1#!/bin/bash
2
3if [ "$#" -ne 1 ]
4then
5 printf "Usage: %s <tracee_pid>\n" "$0"
6 exit 1
7fi
8
9echo '
10 /$$
11 | $$
12 /$$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$$| $$$$$$$
13 /$$_____/ /$$_____/ |____ $$| $$__ $$ /$$_____/| $$__ $$
14| $$$$$$ | $$ /$$$$$$$| $$ \ $$ | $$$$$$ | $$ \ $$
15 \____ $$| $$ /$$__ $$| $$ | $$ \____ $$| $$ | $$
16 /$$$$$$$/| $$$$$$$| $$$$$$$| $$ | $$ /$$ /$$$$$$$/| $$ | $$
17|_______/ \_______/ \_______/|__/ |__/|__/|_______/ |__/ |__/
18'
19
20pid="$1"
21scanfile=${SCANFILE:-/tmp/scanfile}
22rm -f ${scanfile}
23
24while true
25do
26 read -p "Scan pattern (hex): " pattern
27 newscan=$(mktemp)
28 ./hack.out ${pid} scan ${pattern} > ${newscan} 2> /dev/null
29 if [ ! -f ${scanfile} ]
30 then
31 mv ${newscan} ${scanfile}
32 else
33 temp=$(mktemp)
34 cat ${newscan} ${scanfile} | sort | uniq -d > ${temp}
35 mv ${temp} ${scanfile}
36 rm ${newscan}
37 fi
38done
diff --git a/src/main.c b/src/main.c
index 667ca4c..623d767 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,5 +1,4 @@
1#include <string.h> 1#include <string.h>
2#include <stdint.h>
3#include <stdlib.h> 2#include <stdlib.h>
4#include <stdio.h> 3#include <stdio.h>
5#include <sys/ptrace.h> 4#include <sys/ptrace.h>
@@ -8,24 +7,94 @@
8#include "util.h" 7#include "util.h"
9#include "vm.h" 8#include "vm.h"
10 9
11void hex2bytes(char *hex) 10Bytes hex2bytes(const char *hex)
12{ 11{
13 size_t len = strlen(hex); 12 size_t hlen = strlen(hex);
14 char bytes[len + 1]; 13 Bytes bytes = {
14 .data = xmalloc(hlen / 2),
15 .len = hlen / 2,
16 };
15 17
16 for (size_t i = 0; i < len; ++i) { 18 for (size_t i = 0; i < hlen; ++i) {
17 char hdig[3] = { hex[i*2], hex[i*2+1], '\0' }; 19 char hdig[3] = { hex[i*2], hex[i*2+1], '\0' };
18 sscanf(hdig, "%hhx", &bytes[i]); 20 sscanf(hdig, "%hhx", &bytes.data[i]);
19 } 21 }
20 22
21 memcpy(hex, bytes, len); 23 return bytes;
22 hex[len] = '\0';
23} 24}
24 25
25int main(int argc, char *argv[]) 26void action_scan(int pid, int argc, const char *argv[])
26{ 27{
27 if (argc < 2) { 28 if (argc == 0) {
28 ERROR("Usage: %s <tracee_pid>\n", argv[0]); 29 ERROR("Scan: Missing argument <byte_sequence>\n");
30 }
31
32 Bytes aob = hex2bytes(argv[0]);
33 MemscanResult *results_head = memscan(pid, aob);
34 MemscanResult *cur = results_head;
35 while (cur) {
36 void *address = cur->mapping->begin + cur->offset;
37 printf("%p\n", address);
38 cur = cur->next;
39 }
40}
41
42void action_read(int pid, int argc, const char *argv[])
43{
44 if (argc == 0) {
45 ERROR("Write: Missing argument <nbytes>\n");
46 }
47
48 if (argc == 1) {
49 ERROR("Read: Missing argument(s) [<address> ...]");
50 }
51
52 size_t nbytes = atol(argv[0]);
53 if (nbytes == 0) {
54 perror("atol");
55 exit(1);
56 }
57
58 void *address[argc-1];
59 for (size_t i = 0; i < argc-1; ++i) {
60 sscanf(argv[i+1], "%p", &address[i]);
61 }
62
63 for (size_t i = 0; i < argc-1; ++i) {
64 Bytes bytes = memread(pid, address[i], nbytes);
65 for (size_t j = 0; j < bytes.len; ++j) {
66 printf("%02hhx", bytes.data[j]);
67 }
68 printf("\n");
69 }
70}
71
72void action_write(int pid, int argc, const char *argv[])
73{
74 if (argc == 0) {
75 ERROR("Write: Missing argument <bytes>\n");
76 }
77
78 if (argc == 1) {
79 ERROR("Write: Missing argument [<address> ...]\n");
80 }
81
82 Bytes aob = hex2bytes(argv[0]);
83 printf("%s\n", aob.data);
84 void *address[argc-1];
85 for (size_t i = 0; i < argc-1; ++i) {
86 sscanf(argv[i+1], "%p", &address[i]);
87 }
88
89 for (size_t i = 0; i < argc-1; ++i) {
90 memwrite(pid, address[i], aob);
91 }
92}
93
94int main(int argc, const char *argv[])
95{
96 if (argc < 3) {
97 ERROR("Usage: %s <tracee_pid> (scan|read|write) [args ...]\n", argv[0]);
29 } 98 }
30 99
31 int pid; 100 int pid;
@@ -37,32 +106,14 @@ int main(int argc, char *argv[])
37 waitpid(pid, NULL, __WALL); 106 waitpid(pid, NULL, __WALL);
38 LOG("Attached to process %d\n", pid); 107 LOG("Attached to process %d\n", pid);
39 108
40 char *byte_seq = "DEADBEEF"; 109 if (strcmp(argv[2], "scan") == 0) {
41 size_t byte_seq_len = strlen(byte_seq); 110 action_scan(pid, argc-3, &argv[3]);
42 MemscanResult *head = memscan(pid, (uint8_t*)byte_seq, byte_seq_len); 111 } else if (strcmp(argv[2], "read") == 0) {
43 MemscanResult *cur = head; 112 action_read(pid, argc-3, &argv[3]);
44 113 } else if (strcmp(argv[2], "write") == 0) {
45 printf("\n\n\nMemory scan results:\n"); 114 action_write(pid, argc-3, &argv[3]);
46 printf("%-16s|%-16s|%-10s|%-s\n", "Address", "Base", "Offset", "Name"); 115 } else {
47 puts("--------------------------------------------------"); 116 ERROR("Unknown option '%s'\n", argv[1]);
48 while (cur) {
49 printf("%-16p|%-16p|%#-10lx|%-s\n",
50 cur->mapping->begin + cur->offset,
51 cur->mapping->begin,
52 cur->offset,
53 cur->mapping->name);
54 cur = cur->next;
55 }
56
57 printf("\n\n");
58
59 char *buf = "CAFEBABE";
60 size_t len = strlen(buf);
61 cur = head;
62 while (cur) {
63 void *address = cur->mapping->begin + cur->offset;
64 memwrite(pid, address, (uint8_t*)buf, len);
65 cur = cur->next;
66 } 117 }
67 118
68 ptrace(PTRACE_DETACH, pid, NULL, NULL); 119 ptrace(PTRACE_DETACH, pid, NULL, NULL);
diff --git a/src/vm.c b/src/vm.c
index b33a7bf..6e04bc8 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -79,7 +79,7 @@ static off_t memfind(const uint8_t *hay, size_t hay_size, const uint8_t *needle,
79 return hay_size; 79 return hay_size;
80} 80}
81 81
82MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len) 82MemscanResult* memscan(int pid, Bytes aob)
83{ 83{
84 char fmem_path[1024] = {0}; 84 char fmem_path[1024] = {0};
85 sprintf(fmem_path, "/proc/%d/mem", pid); 85 sprintf(fmem_path, "/proc/%d/mem", pid);
@@ -95,15 +95,15 @@ MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
95 } 95 }
96 96
97 size_t region_size = cur_vmmap->end - cur_vmmap->begin; 97 size_t region_size = cur_vmmap->end - cur_vmmap->begin;
98 uint8_t region_data[region_size]; 98 uint8_t *region_data = xmalloc(region_size);
99 fseek(fmem, (off_t)cur_vmmap->begin, SEEK_SET); 99 fseek(fmem, (off_t)cur_vmmap->begin, SEEK_SET);
100 fread(region_data, 1, region_size, fmem); 100 fread(region_data, 1, region_size, fmem);
101 101
102 off_t offset = 0; 102 off_t offset = 0;
103 while (offset += memfind(region_data + offset, 103 while (offset += memfind(region_data + offset,
104 region_size - offset, 104 region_size - offset,
105 byte_seq, 105 aob.data,
106 byte_seq_len), 106 aob.len),
107 offset < region_size) { 107 offset < region_size) {
108 LOG("Matched pattern at [%p]\n", cur_vmmap->begin + (off_t)offset); 108 LOG("Matched pattern at [%p]\n", cur_vmmap->begin + (off_t)offset);
109 MemscanResult *new_result = xmalloc(sizeof(MemscanResult)); 109 MemscanResult *new_result = xmalloc(sizeof(MemscanResult));
@@ -121,8 +121,9 @@ MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
121 head = cur = new_result; 121 head = cur = new_result;
122 } 122 }
123 123
124 offset += byte_seq_len; 124 offset += aob.len;
125 } 125 }
126 free(region_data);
126 127
127 cur_vmmap = cur_vmmap->next; 128 cur_vmmap = cur_vmmap->next;
128 } 129 }
@@ -131,15 +132,33 @@ MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
131 return head; 132 return head;
132} 133}
133 134
134void memwrite(int pid, void *address, uint8_t *data, size_t data_len) 135void memwrite(int pid, void *address, Bytes aob)
135{ 136{
136 char fmem_path[1024] = {0}; 137 char fmem_path[1024] = {0};
137 sprintf(fmem_path, "/proc/%d/mem", pid); 138 sprintf(fmem_path, "/proc/%d/mem", pid);
138 FILE *fmem = fopen(fmem_path, "rb+"); 139 FILE *fmem = fopen(fmem_path, "rb+");
139 140
140 fseek(fmem, (off_t)address, SEEK_SET); 141 fseek(fmem, (off_t)address, SEEK_SET);
141 fwrite(data, 1, data_len, fmem); 142 fwrite(aob.data, 1, aob.len, fmem);
142 fclose(fmem); 143 fclose(fmem);
143 144
144 LOG("Data written successfully at address %p\n", address); 145 LOG("Data written successfully at address %p\n", address);
145} 146}
147
148Bytes memread(int pid, void *address, size_t nbytes)
149{
150 Bytes result = {
151 .data = xmalloc(nbytes),
152 .len = nbytes,
153 };
154
155 char fmem_path[1024] = {0};
156 sprintf(fmem_path, "/proc/%d/mem", pid);
157 FILE *fmem = fopen(fmem_path, "rb");
158
159 fseek(fmem, (off_t)address, SEEK_SET);
160 fread(result.data, 1, result.len, fmem);
161 fclose(fmem);
162
163 return result;
164}
diff --git a/src/vm.h b/src/vm.h
index 3f3cc09..9164c57 100644
--- a/src/vm.h
+++ b/src/vm.h
@@ -21,9 +21,17 @@ typedef struct MemscanResult {
21 struct MemscanResult *next; 21 struct MemscanResult *next;
22} MemscanResult; 22} MemscanResult;
23 23
24typedef struct Bytes {
25 uint8_t *data;
26 size_t len;
27} Bytes;
28
24VMMapping* parse_vmmap (int pid); 29VMMapping* parse_vmmap (int pid);
25 30
26MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len); 31MemscanResult* memscan(int pid, Bytes aob);
32
33void memwrite(int pid, void *address, Bytes aob);
34
35Bytes memread(int pid, void *address, size_t nbytes);
27 36
28void memwrite(int pid, void *address, uint8_t *data, size_t data_len);
29#endif // _VM_H_ 37#endif // _VM_H_