]> Projects - linux-game-trainer.git/commitdiff Test
Changes in trainer interface, bug fixes & helper scripts
authorOrfeas <redacted>
Sun, 21 Apr 2024 13:27:55 +0000 (16:27 +0300)
committerOrfeas <redacted>
Sun, 21 Apr 2024 13:32:47 +0000 (16:32 +0300)
run.sh [new file with mode: 0755]
scripts/read.sh [new file with mode: 0644]
scripts/scan.sh [new file with mode: 0644]
src/main.c
src/vm.c
src/vm.h

diff --git a/run.sh b/run.sh
new file mode 100755 (executable)
index 0000000..6de5897
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if [ "$#" -ne 1 ]
+then
+    printf "Usage: %s <tracee_pid>\n" "$0"
+    exit 1
+fi
+
+gnome-terminal -- bash ./scripts/scan.sh "$1"
+gnome-terminal -- bash ./scripts/read.sh "$1"
diff --git a/scripts/read.sh b/scripts/read.sh
new file mode 100644 (file)
index 0000000..38535e6
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+if [ "$#" -ne 1 ]
+then
+    printf "Usage: %s <tracee_pid>\n" "$0"
+    exit 1
+fi
+
+scanfile=${SCANFILE:-/tmp/scanfile}
+pid="$1"
+watch -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 (file)
index 0000000..c700011
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+if [ "$#" -ne 1 ]
+then
+    printf "Usage: %s <tracee_pid>\n" "$0"
+    exit 1
+fi
+
+echo '
+                                                       /$$      
+                                                      | $$      
+  /$$$$$$$  /$$$$$$$  /$$$$$$  /$$$$$$$       /$$$$$$$| $$$$$$$ 
+ /$$_____/ /$$_____/ |____  $$| $$__  $$     /$$_____/| $$__  $$
+|  $$$$$$ | $$        /$$$$$$$| $$  \ $$    |  $$$$$$ | $$  \ $$
+ \____  $$| $$       /$$__  $$| $$  | $$     \____  $$| $$  | $$
+ /$$$$$$$/|  $$$$$$$|  $$$$$$$| $$  | $$ /$$ /$$$$$$$/| $$  | $$
+|_______/  \_______/ \_______/|__/  |__/|__/|_______/ |__/  |__/
+'
+
+pid="$1"
+scanfile=${SCANFILE:-/tmp/scanfile}
+rm -f ${scanfile}
+
+while true
+do
+    read -p "Scan pattern (hex): " pattern
+    newscan=$(mktemp)
+    ./hack.out ${pid} scan ${pattern} > ${newscan} 2> /dev/null
+    if [ ! -f ${scanfile} ]
+    then
+       mv ${newscan} ${scanfile}
+    else
+       temp=$(mktemp)
+       cat ${newscan} ${scanfile} | sort | uniq -d > ${temp}
+       mv ${temp} ${scanfile}
+       rm ${newscan}
+    fi
+done
index 667ca4ca0f608dec50f79ec64c48c03070d4599c..623d767df36367dcf85450dc9c2f6a44f99e21c0 100644 (file)
@@ -1,5 +1,4 @@
 #include <string.h>
-#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/ptrace.h>
@@ -8,24 +7,94 @@
 #include "util.h"
 #include "vm.h"
 
-void hex2bytes(char *hex)
+Bytes hex2bytes(const char *hex)
 {
-  size_t len = strlen(hex);
-  char bytes[len + 1];
+  size_t hlen = strlen(hex);
+  Bytes bytes = {
+    .data = xmalloc(hlen / 2),
+    .len = hlen / 2,
+  };
 
-  for (size_t i = 0; i < len; ++i) {
+  for (size_t i = 0; i < hlen; ++i) {
     char hdig[3] = { hex[i*2], hex[i*2+1], '\0' };
-    sscanf(hdig, "%hhx", &bytes[i]);
+    sscanf(hdig, "%hhx", &bytes.data[i]);
   }
 
-  memcpy(hex, bytes, len);
-  hex[len] = '\0';
+  return bytes;
 }
 
-int main(int argc, char *argv[])
+void action_scan(int pid, int argc, const char *argv[])
 {
-  if (argc < 2) {
-    ERROR("Usage: %s <tracee_pid>\n", argv[0]);
+  if (argc == 0) {
+    ERROR("Scan: Missing argument <byte_sequence>\n");
+  }
+
+  Bytes aob = hex2bytes(argv[0]);
+  MemscanResult *results_head =  memscan(pid, aob);
+  MemscanResult *cur = results_head;
+  while (cur) {
+    void *address = cur->mapping->begin + cur->offset;
+    printf("%p\n", address);
+    cur = cur->next;
+  }
+}
+
+void action_read(int pid, int argc, const char *argv[])
+{
+  if (argc == 0) {
+    ERROR("Write: Missing argument <nbytes>\n");
+  }
+
+  if (argc == 1) {
+    ERROR("Read: Missing argument(s) [<address> ...]");
+  }
+
+  size_t nbytes = atol(argv[0]);
+  if (nbytes == 0) {
+    perror("atol");
+    exit(1);
+  }
+
+  void *address[argc-1];
+  for (size_t i = 0; i < argc-1; ++i) {
+    sscanf(argv[i+1], "%p", &address[i]);
+  }
+
+  for (size_t i = 0; i < argc-1; ++i) {
+    Bytes bytes = memread(pid, address[i], nbytes);
+    for (size_t j = 0; j < bytes.len; ++j) {
+      printf("%02hhx", bytes.data[j]);
+    }
+    printf("\n");
+  }
+}
+
+void action_write(int pid, int argc, const char *argv[])
+{
+  if (argc == 0) {
+    ERROR("Write: Missing argument <bytes>\n");
+  }
+
+  if (argc == 1) {
+    ERROR("Write: Missing argument [<address> ...]\n");
+  }
+
+  Bytes aob = hex2bytes(argv[0]);
+  printf("%s\n", aob.data);
+  void *address[argc-1];
+  for (size_t i = 0; i < argc-1; ++i) {
+    sscanf(argv[i+1], "%p", &address[i]);
+  }
+
+  for (size_t i = 0; i < argc-1; ++i) {
+    memwrite(pid, address[i], aob);
+  }
+}
+
+int main(int argc, const char *argv[])
+{
+  if (argc < 3) {
+    ERROR("Usage: %s <tracee_pid> (scan|read|write) [args ...]\n", argv[0]);
   }
 
   int pid;
@@ -37,32 +106,14 @@ int main(int argc, char *argv[])
   waitpid(pid, NULL, __WALL);
   LOG("Attached to process %d\n", pid);
 
-  char *byte_seq = "DEADBEEF";
-  size_t byte_seq_len = strlen(byte_seq);
-  MemscanResult *head = memscan(pid, (uint8_t*)byte_seq, byte_seq_len);
-  MemscanResult *cur = head;
-
-  printf("\n\n\nMemory scan results:\n");
-  printf("%-16s|%-16s|%-10s|%-s\n", "Address", "Base", "Offset", "Name");
-  puts("--------------------------------------------------");
-  while (cur) {
-    printf("%-16p|%-16p|%#-10lx|%-s\n",
-          cur->mapping->begin + cur->offset,
-          cur->mapping->begin,
-          cur->offset,
-          cur->mapping->name);
-    cur = cur->next;
-  }
-
-  printf("\n\n");
-
-  char *buf = "CAFEBABE";
-  size_t len = strlen(buf);
-  cur = head;
-  while (cur) {
-    void *address = cur->mapping->begin + cur->offset;
-    memwrite(pid, address, (uint8_t*)buf, len);
-    cur = cur->next;
+  if (strcmp(argv[2], "scan") == 0) {
+    action_scan(pid, argc-3, &argv[3]);
+  } else if (strcmp(argv[2], "read") == 0) {
+    action_read(pid, argc-3, &argv[3]);
+  } else if (strcmp(argv[2], "write") == 0) {
+    action_write(pid, argc-3, &argv[3]);
+  } else {
+    ERROR("Unknown option '%s'\n", argv[1]);
   }
 
   ptrace(PTRACE_DETACH, pid, NULL, NULL);
index b33a7bf8e5b18cdd12c0ed85a1f4588612bc297d..6e04bc855e53a7dea323655e0be2faba3c251e98 100644 (file)
--- 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,
   return hay_size;
 }
 
-MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
+MemscanResult* memscan(int pid, Bytes aob)
 {
   char fmem_path[1024] = {0};
   sprintf(fmem_path, "/proc/%d/mem", pid);
@@ -95,15 +95,15 @@ MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
     }
 
     size_t region_size = cur_vmmap->end - cur_vmmap->begin;
-    uint8_t region_data[region_size];
+    uint8_t *region_data = xmalloc(region_size);
     fseek(fmem, (off_t)cur_vmmap->begin, SEEK_SET);
     fread(region_data, 1, region_size, fmem);
 
     off_t offset = 0;
     while (offset += memfind(region_data + offset,
                             region_size - offset,
-                            byte_seq,
-                            byte_seq_len),
+                            aob.data,
+                            aob.len),
           offset < region_size) {
       LOG("Matched pattern at [%p]\n", cur_vmmap->begin + (off_t)offset);
       MemscanResult *new_result = xmalloc(sizeof(MemscanResult));
@@ -121,8 +121,9 @@ MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
        head = cur = new_result;
       }
 
-      offset += byte_seq_len;
+      offset += aob.len;
     }
+    free(region_data);
 
     cur_vmmap = cur_vmmap->next;
   }
@@ -131,15 +132,33 @@ MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len)
   return head;
 }
 
-void memwrite(int pid, void *address, uint8_t *data, size_t data_len)
+void memwrite(int pid, void *address, Bytes aob)
 {
   char fmem_path[1024] = {0};
   sprintf(fmem_path, "/proc/%d/mem", pid);
   FILE *fmem = fopen(fmem_path, "rb+");
 
   fseek(fmem, (off_t)address, SEEK_SET);
-  fwrite(data, 1, data_len, fmem);
+  fwrite(aob.data, 1, aob.len, fmem);
   fclose(fmem);
 
   LOG("Data written successfully at address %p\n", address);
 }
+
+Bytes memread(int pid, void *address, size_t nbytes)
+{
+  Bytes result = {
+    .data = xmalloc(nbytes),
+    .len = nbytes,
+  };
+
+  char fmem_path[1024] = {0};
+  sprintf(fmem_path, "/proc/%d/mem", pid);
+  FILE *fmem = fopen(fmem_path, "rb");
+
+  fseek(fmem, (off_t)address, SEEK_SET);
+  fread(result.data, 1, result.len, fmem);
+  fclose(fmem);
+
+  return result;
+}
index 3f3cc097960537851dcbfd36b9960af70b15f8b9..9164c577c6b82c5afbb487acbf91147629822c3a 100644 (file)
--- a/src/vm.h
+++ b/src/vm.h
@@ -21,9 +21,17 @@ typedef struct MemscanResult {
   struct MemscanResult *next;
 } MemscanResult;
 
+typedef struct Bytes {
+  uint8_t *data;
+  size_t len;
+} Bytes;
+
 VMMapping* parse_vmmap (int pid);
 
-MemscanResult* memscan(int pid, uint8_t *byte_seq, uint64_t byte_seq_len);
+MemscanResult* memscan(int pid, Bytes aob);
+
+void memwrite(int pid, void *address, Bytes aob);
+
+Bytes memread(int pid, void *address, size_t nbytes);
 
-void memwrite(int pid, void *address, uint8_t *data, size_t data_len);
 #endif // _VM_H_