summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheron Spiegl <tspiegl@gmail.com>2020-06-28 13:15:32 -0500
committerGitHub <noreply@github.com>2020-06-28 13:15:32 -0500
commita0d66f6e862d38dcd064693f19e5d0e0b922b2c1 (patch)
tree4ef39812048df923e38d759570ae7e174085b67b
parent9abd805b7b6e097e7492fac0ba90026c92927b95 (diff)
parent3a609585bc94c1b9385927374f1b28e63f5d6546 (diff)
Merge pull request #9 from spieglt/ARM
Arm
-rw-r--r--Makefile9
-rw-r--r--src/arm32/registers.c120
-rw-r--r--src/attach.c4
-rw-r--r--src/utilities.c6
-rw-r--r--src/whatfiles.c115
-rw-r--r--src/whatfiles.h12
-rw-r--r--src/x86_64/registers.c119
-rw-r--r--whatfiles.geany57
8 files changed, 320 insertions, 122 deletions
diff --git a/Makefile b/Makefile
index 92cc0c2..2f05bbb 100644
--- a/Makefile
+++ b/Makefile
@@ -2,10 +2,17 @@ CC = gcc
CFLAGS = -Wall
SOURCES = $(addprefix src/, whatfiles.c attach.c utilities.c hashmap.c strings.c)
+ARCH = $(shell uname -m)
+ifeq ($(findstring arm,$(ARCH)), arm)
+ ARCH_DIR = arm32
+else
+ ARCH_DIR = x86_64
+endif
+
all: bin/whatfiles
bin/whatfiles: $(SOURCES)
- $(CC) $(CFLAGS) -o $@ $(SOURCES)
+ $(CC) $(CFLAGS) -o $@ $(SOURCES) src/$(ARCH_DIR)/registers.c
# utils
diff --git a/src/arm32/registers.c b/src/arm32/registers.c
new file mode 100644
index 0000000..cc3cdf5
--- /dev/null
+++ b/src/arm32/registers.c
@@ -0,0 +1,120 @@
+
+#include <sys/ptrace.h>
+#include <linux/ptrace.h>
+
+#include <sys/user.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+
+#include "../hashmap.h"
+#include "../whatfiles.h"
+
+void check_syscall(pid_t current_pid, void *registers, HashMap map)
+{
+ struct pt_regs *regs = (struct pt_regs*)registers;
+ struct String filename = {0};
+ struct String output = {0};
+ init_string(&filename, 64);
+ init_string(&output, 64);
+ char mode[MODE_LEN] = {0};
+
+ pid_t parent_tid, child_tid;
+ unsigned long flags;
+ unsigned long newsp;
+
+ size_t index;
+ HashError err = find_index(current_pid, map, &index);
+ if (err) DEBUG("unknown pid %d, syscall %ld\n", current_pid, regs->ARM_r7);
+
+ switch (regs->ARM_r7)
+ {
+ case SYS_execve:
+ DEBUG("PID %d exec'd. orig_rax: %ld\n", current_pid, regs->ARM_r7);
+ if (peek_filename(current_pid, regs->ARM_ORIG_r0, &filename)) {
+ DEBUG("associated process %d with name \"%s\"\n", current_pid, filename.data);
+ set_name(current_pid, filename.data, map);
+ }
+ break;
+ case SYS_fork:
+ DEBUG("PID %d forked. orig_rax: %ld\n", current_pid, regs->ARM_r7);
+ break;
+ case SYS_clone:
+ flags = regs->ARM_ORIG_r0;
+ newsp = regs->ARM_r1;
+ parent_tid = ptrace(PTRACE_PEEKDATA, current_pid, (void*)regs->ARM_r2, 0);
+ child_tid = ptrace(PTRACE_PEEKDATA, current_pid, (void*)regs->ARM_r4, 0);
+ DEBUG("PID %d cloned. orig_rax: %ld, flags: 0x%ld, newsp: 0x%ld, parent pid: %d, child pid: %d\n",
+ current_pid, regs->ARM_r7, flags, newsp, parent_tid, child_tid);
+ break;
+ case SYS_creat:
+ peek_filename(current_pid, regs->ARM_ORIG_r0, &filename);
+ get_mode(regs->ARM_r1, mode);
+ build_output(mode, "creat()", regs->ARM_r1, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_open:
+ peek_filename(current_pid, regs->ARM_ORIG_r0, &filename);
+ get_mode(regs->ARM_r2, mode);
+ build_output(mode, "open()", regs->ARM_r2, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_openat:
+ peek_filename(current_pid, regs->ARM_r1, &filename);
+ get_mode(regs->ARM_r3, mode);
+ build_output(mode, "openat()", regs->ARM_r3, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_unlink:
+ peek_filename(current_pid, regs->ARM_ORIG_r0, &filename);
+ build_output("delete", "unlink()", 0, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_unlinkat:
+ peek_filename(current_pid, regs->ARM_r1, &filename);
+ build_output("delete", "unlinkat()", 0, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ default:
+ // DEBUG("syscall: %lld, pid: %d, %s\n", regs->orig_rax, current_pid, proc_name);
+ break;
+ }
+ free(filename.data);
+ free(output.data);
+}
+
+
+bool step_syscall(pid_t current_pid, int proc_status, HashMap map)
+{
+ long res;
+ struct pt_regs regs;
+ bool could_read = false;
+ // get current register values
+ // TODO: make this fault tolerant to a dead PID
+ res = ptrace(PTRACE_GETREGS, current_pid, &regs, &regs);
+ if (res == -1L) {
+ DEBUG("CURRENT PID: %d, failed to get registers\n", current_pid);
+ }
+
+ // can't get some registers for some reason
+ if (regs.ARM_ORIG_r0 != -1) {
+ could_read = true;
+ // If it's the same PID performing the same syscall (has same orig_rax) as last time, we don't care. Just means it's exiting the syscall.
+ // Might want to keep for debug mode? This might result in missing some output, in the case where two threads of the same process enter the same syscall before either exits,
+ // because they will both return the same PID to wait() when given SIGTRAP as part of the syscall-enter-exit loop. Might also result in double-printing,
+ // because if two threads (that report the same PID) enter two different syscalls before either exits, the "last" syscall for the PID won't be the entry by that thread.
+ if (!is_exiting(current_pid, regs.ARM_ORIG_r0) /*|| Debug*/) {
+ check_syscall(current_pid, (void*)&regs, map);
+ }
+ LastSyscall.pid = current_pid;
+ LastSyscall.syscall = regs.ARM_ORIG_r0;
+ check_ptrace_event(current_pid, proc_status, map);
+ // continue, catching next entry or exit from syscall
+ res = ptrace(PTRACE_SYSCALL, current_pid, 0, 0);
+ if (res == -1L) DEBUG("ptrace() failed to resume");
+ } else {
+ DEBUG("can't get registers, detaching from %d\n", current_pid);
+ res = ptrace(PTRACE_DETACH, current_pid, 0, 0); // "Under Linux, a tracee can be detached in this way regardless of which method was used to initiate tracing."
+ if (res == -1L) DEBUG("ptrace() failed to detach from %d\n", current_pid);
+ }
+ return could_read;
+}
diff --git a/src/attach.c b/src/attach.c
index b40739d..7aad391 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -16,9 +16,9 @@
void read_file(struct String *str, size_t size, FILE *file)
{
- char c;
+ int c;
for (size_t read = 0; read < size && (c = fgetc(file)) != EOF; read++) {
- append_char(c, str);
+ append_char((char)c, str);
}
}
diff --git a/src/utilities.c b/src/utilities.c
index 9bfecba..c8b08b9 100644
--- a/src/utilities.c
+++ b/src/utilities.c
@@ -12,7 +12,7 @@ char *FLAGS = "ado:p:s";
void build_output(
char *mode,
char *syscall_name,
- unsigned long long reg,
+ unsigned long reg,
pid_t pid,
struct String *filename,
struct String *result,
@@ -25,7 +25,7 @@ void build_output(
char mode_str[MODE_LEN] = {0};
// grab detected mode or the raw number
- *mode ? sprintf(mode_str, "%5s", mode) : sprintf(mode_str, "0x%llX", reg);
+ *mode ? sprintf(mode_str, "%5s", mode) : sprintf(mode_str, "0x%lX", reg);
append_str("mode: ", strlen("mode: "), result);
append_str(mode_str, strlen(mode_str), result);
@@ -72,7 +72,7 @@ void get_command(pid_t current_pid, char *command, size_t len)
}
}
-bool peek_filename(pid_t pid, unsigned long long p_reg, struct String *str)
+bool peek_filename(pid_t pid, unsigned long p_reg, struct String *str)
{
char get_next_word = 1;
long *addr = (long*)p_reg;
diff --git a/src/whatfiles.c b/src/whatfiles.c
index 67d4e92..fb9f291 100644
--- a/src/whatfiles.c
+++ b/src/whatfiles.c
@@ -6,7 +6,6 @@
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
-#include <sys/user.h>
#include <sys/wait.h>
#include "whatfiles.h"
@@ -18,83 +17,6 @@ int Debug = 0;
LastSyscall_t LastSyscall;
DebugStats_t DebugStats;
-// looks at the current syscall and outputs its information if it's one we're interested in
-void check_syscall(pid_t current_pid, struct user_regs_struct regs, HashMap map)
-{
- struct String filename = {0};
- struct String output = {0};
- init_string(&filename, 64);
- init_string(&output, 64);
- char mode[MODE_LEN] = {0};
-
- pid_t parent_tid, child_tid;
- unsigned long flags;
- unsigned long newsp;
-
- size_t index;
- HashError err = find_index(current_pid, map, &index);
- if (err) DEBUG("unknown pid %d, syscall %lld\n", current_pid, regs.orig_rax);
- // struct String *proc_string = err ? NULL : &map->names[index];
- // char *proc_name = proc_string && proc_string->data && *proc_string->data
- // ? proc_string->data
- // : "[unknown]";
-
- switch (regs.orig_rax)
- {
- case SYS_execve:
- DEBUG("PID %d exec'd. orig_rax: %lld, rax: %lld\n", current_pid, regs.orig_rax, regs.rax);
- if (peek_filename(current_pid, regs.rdi, &filename)) {
- DEBUG("associated process %d with name \"%s\"\n", current_pid, filename.data);
- set_name(current_pid, filename.data, map);
- }
- break;
- case SYS_fork:
- DEBUG("PID %d forked. orig_rax: %lld, rax: %lld\n", current_pid, regs.orig_rax, regs.rax);
- break;
- case SYS_clone:
- flags = regs.rdi;
- newsp = regs.rsi;
- parent_tid = ptrace(PTRACE_PEEKDATA, current_pid, (void*)regs.rdx, 0);
- child_tid = ptrace(PTRACE_PEEKDATA, current_pid, (void*)regs.r10, 0);
- DEBUG("PID %d cloned. orig_rax: %lld, rax: %lld, flags: 0x%ld, newsp: 0x%ld, parent pid: %d, child pid: %d\n",
- current_pid, regs.orig_rax, regs.rax, flags, newsp, parent_tid, child_tid);
- break;
- case SYS_creat:
- peek_filename(current_pid, regs.rdi, &filename);
- get_mode(regs.rsi, mode);
- build_output(mode, "creat()", regs.rsi, current_pid, &filename, &output, map);
- OUTPUT("%s", output.data);
- break;
- case SYS_open:
- peek_filename(current_pid, regs.rdi, &filename);
- get_mode(regs.rdx, mode);
- build_output(mode, "open()", regs.rdx, current_pid, &filename, &output, map);
- OUTPUT("%s", output.data);
- break;
- case SYS_openat:
- peek_filename(current_pid, regs.rsi, &filename);
- get_mode(regs.r10, mode);
- build_output(mode, "openat()", regs.r10, current_pid, &filename, &output, map);
- OUTPUT("%s", output.data);
- break;
- case SYS_unlink:
- peek_filename(current_pid, regs.rdi, &filename);
- build_output("delete", "unlink()", 0, current_pid, &filename, &output, map);
- OUTPUT("%s", output.data);
- break;
- case SYS_unlinkat:
- peek_filename(current_pid, regs.rsi, &filename);
- build_output("delete", "unlinkat()", 0, current_pid, &filename, &output, map);
- OUTPUT("%s", output.data);
- break;
- default:
- // DEBUG("syscall: %lld, pid: %d, %s\n", regs.orig_rax, current_pid, proc_name);
- break;
- }
- free(filename.data);
- free(output.data);
-}
-
// responsible for seeing new processes and threads created by forks, clones, or vforks, and inserting them into the hashmap
void check_ptrace_event(pid_t current_pid, int proc_status, HashMap map)
{
@@ -158,42 +80,6 @@ void check_ptrace_event(pid_t current_pid, int proc_status, HashMap map)
free(new_proc.data);
}
-bool step_syscall(pid_t current_pid, int proc_status, HashMap map)
-{
- long res;
- struct user_regs_struct regs;
- bool could_read = false;
- // get current register values
- // TODO: make this fault tolerant to a dead PID
- res = ptrace(PTRACE_GETREGS, current_pid, &regs, &regs);
- if (res == -1L) {
- DEBUG("CURRENT PID: %d, failed to get registers\n", current_pid);
- }
-
- // can't get some registers for some reason
- if (regs.orig_rax != -1) {
- could_read = true;
- // If it's the same PID performing the same syscall (has same orig_rax) as last time, we don't care. Just means it's exiting the syscall.
- // Might want to keep for debug mode? This might result in missing some output, in the case where two threads of the same process enter the same syscall before either exits,
- // because they will both return the same PID to wait() when given SIGTRAP as part of the syscall-enter-exit loop. Might also result in double-printing,
- // because if two threads (that report the same PID) enter two different syscalls before either exits, the "last" syscall for the PID won't be the entry by that thread.
- if (!is_exiting(current_pid, regs.orig_rax) /*|| Debug*/) {
- check_syscall(current_pid, regs, map);
- }
- LastSyscall.pid = current_pid;
- LastSyscall.syscall = regs.orig_rax;
- check_ptrace_event(current_pid, proc_status, map);
- // continue, catching next entry or exit from syscall
- res = ptrace(PTRACE_SYSCALL, current_pid, 0, 0);
- if (res == -1L) DEBUG("ptrace() failed to resume");
- } else {
- DEBUG("can't get registers, detaching from %d\n", current_pid);
- res = ptrace(PTRACE_DETACH, current_pid, 0, 0); // "Under Linux, a tracee can be detached in this way regardless of which method was used to initiate tracing."
- if (res == -1L) DEBUG("ptrace() failed to detach from %d\n", current_pid);
- }
- return could_read;
-}
-
int main(int argc, char* argv[])
{
int pid, status;
@@ -331,6 +217,7 @@ int main(int argc, char* argv[])
/*
TODO:
+confirm process exists for -p flag
debug flag for use by hashdriver
more hashmap tests?
better allocator/destructor for String
diff --git a/src/whatfiles.h b/src/whatfiles.h
index 1738010..4561c11 100644
--- a/src/whatfiles.h
+++ b/src/whatfiles.h
@@ -30,11 +30,14 @@ typedef struct {
extern LastSyscall_t LastSyscall;
+// whatfiles.c
+void check_ptrace_event(pid_t current_pid, int proc_status, HashMap map);
+
// utilities.c
void build_output(
char *mode,
char *syscall_name,
- unsigned long long reg,
+ unsigned long reg,
pid_t pid,
struct String *filename,
struct String *result,
@@ -42,7 +45,7 @@ void build_output(
);
void get_mode(unsigned long long m, char *mode);
void get_command(pid_t current_pid, char *command, size_t len);
-bool peek_filename(pid_t pid, unsigned long long p_reg, struct String *str);
+bool peek_filename(pid_t pid, unsigned long p_reg, struct String *str);
// void toggle_status(pid_t current_pid, HashMap map);
bool is_exiting(pid_t pid, unsigned long long syscall);
char *parse_flags(int argc, char *argv[], pid_t *pid, bool *stdout_override, bool *attach);
@@ -58,4 +61,9 @@ void read_file(struct String *str, size_t size, FILE *file);
char read_status(pid_t pid);
bool read_task(pid_t tid, struct String *str);
+// architecture-specific, registers.c
+void check_syscall(pid_t current_pid, void *registers, HashMap map);
+bool step_syscall(pid_t current_pid, int proc_status, HashMap map);
+
+
#endif /* !WHATFILES_H */
diff --git a/src/x86_64/registers.c b/src/x86_64/registers.c
new file mode 100644
index 0000000..badc0c1
--- /dev/null
+++ b/src/x86_64/registers.c
@@ -0,0 +1,119 @@
+
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+
+#include "../hashmap.h"
+#include "../whatfiles.h"
+
+// looks at the current syscall and outputs its information if it's one we're interested in
+void check_syscall(pid_t current_pid, void *registers, HashMap map)
+{
+ struct user_regs_struct *regs = (struct user_regs_struct*)registers;
+ struct String filename = {0};
+ struct String output = {0};
+ init_string(&filename, 64);
+ init_string(&output, 64);
+ char mode[MODE_LEN] = {0};
+
+ pid_t parent_tid, child_tid;
+ unsigned long flags;
+ unsigned long newsp;
+
+ size_t index;
+ HashError err = find_index(current_pid, map, &index);
+ if (err) DEBUG("unknown pid %d, syscall %lld\n", current_pid, regs->orig_rax);
+
+ switch (regs->orig_rax)
+ {
+ case SYS_execve:
+ DEBUG("PID %d exec'd. orig_rax: %lld, rax: %lld\n", current_pid, regs->orig_rax, regs->rax);
+ if (peek_filename(current_pid, regs->rdi, &filename)) {
+ DEBUG("associated process %d with name \"%s\"\n", current_pid, filename.data);
+ set_name(current_pid, filename.data, map);
+ }
+ break;
+ case SYS_fork:
+ DEBUG("PID %d forked. orig_rax: %lld, rax: %lld\n", current_pid, regs->orig_rax, regs->rax);
+ break;
+ case SYS_clone:
+ flags = regs->rdi;
+ newsp = regs->rsi;
+ parent_tid = ptrace(PTRACE_PEEKDATA, current_pid, (void*)regs->rdx, 0);
+ child_tid = ptrace(PTRACE_PEEKDATA, current_pid, (void*)regs->r10, 0);
+ DEBUG("PID %d cloned. orig_rax: %lld, rax: %lld, flags: 0x%ld, newsp: 0x%ld, parent pid: %d, child pid: %d\n",
+ current_pid, regs->orig_rax, regs->rax, flags, newsp, parent_tid, child_tid);
+ break;
+ case SYS_creat:
+ peek_filename(current_pid, regs->rdi, &filename);
+ get_mode(regs->rsi, mode);
+ build_output(mode, "creat()", regs->rsi, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_open:
+ peek_filename(current_pid, regs->rdi, &filename);
+ get_mode(regs->rdx, mode);
+ build_output(mode, "open()", regs->rdx, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_openat:
+ peek_filename(current_pid, regs->rsi, &filename);
+ get_mode(regs->r10, mode);
+ build_output(mode, "openat()", regs->r10, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_unlink:
+ peek_filename(current_pid, regs->rdi, &filename);
+ build_output("delete", "unlink()", 0, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ case SYS_unlinkat:
+ peek_filename(current_pid, regs->rsi, &filename);
+ build_output("delete", "unlinkat()", 0, current_pid, &filename, &output, map);
+ OUTPUT("%s", output.data);
+ break;
+ default:
+ // DEBUG("syscall: %lld, pid: %d, %s\n", regs->orig_rax, current_pid, proc_name);
+ break;
+ }
+ free(filename.data);
+ free(output.data);
+}
+
+
+bool step_syscall(pid_t current_pid, int proc_status, HashMap map)
+{
+ long res;
+ struct user_regs_struct regs;
+ bool could_read = false;
+ // get current register values
+ // TODO: make this fault tolerant to a dead PID
+ res = ptrace(PTRACE_GETREGS, current_pid, &regs, &regs);
+ if (res == -1L) {
+ DEBUG("CURRENT PID: %d, failed to get registers\n", current_pid);
+ }
+
+ // can't get some registers for some reason
+ if (regs.orig_rax != -1) {
+ could_read = true;
+ // If it's the same PID performing the same syscall (has same orig_rax) as last time, we don't care. Just means it's exiting the syscall.
+ // Might want to keep for debug mode? This might result in missing some output, in the case where two threads of the same process enter the same syscall before either exits,
+ // because they will both return the same PID to wait() when given SIGTRAP as part of the syscall-enter-exit loop. Might also result in double-printing,
+ // because if two threads (that report the same PID) enter two different syscalls before either exits, the "last" syscall for the PID won't be the entry by that thread.
+ if (!is_exiting(current_pid, regs.orig_rax) /*|| Debug*/) {
+ check_syscall(current_pid, (void*)&regs, map);
+ }
+ LastSyscall.pid = current_pid;
+ LastSyscall.syscall = regs.orig_rax;
+ check_ptrace_event(current_pid, proc_status, map);
+ // continue, catching next entry or exit from syscall
+ res = ptrace(PTRACE_SYSCALL, current_pid, 0, 0);
+ if (res == -1L) DEBUG("ptrace() failed to resume");
+ } else {
+ DEBUG("can't get registers, detaching from %d\n", current_pid);
+ res = ptrace(PTRACE_DETACH, current_pid, 0, 0); // "Under Linux, a tracee can be detached in this way regardless of which method was used to initiate tracing."
+ if (res == -1L) DEBUG("ptrace() failed to detach from %d\n", current_pid);
+ }
+ return could_read;
+}
diff --git a/whatfiles.geany b/whatfiles.geany
new file mode 100644
index 0000000..4219693
--- /dev/null
+++ b/whatfiles.geany
@@ -0,0 +1,57 @@
+[editor]
+line_wrapping=false
+line_break_column=72
+auto_continue_multiline=true
+
+[file_prefs]
+final_new_line=true
+ensure_convert_new_lines=false
+strip_trailing_spaces=false
+replace_tabs=false
+
+[indentation]
+indent_width=4
+indent_type=1
+indent_hard_tab_width=8
+detect_indent=true
+detect_indent_width=true
+indent_mode=2
+
+[project]
+name=whatfiles
+base_path=/home/pi/projects/whatfiles/
+description=
+file_patterns=
+
+[long line marker]
+long_line_behaviour=1
+long_line_column=72
+
+[files]
+current_page=1
+FILE_NAME_0=697;C;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Farmv7l%2Fregisters.c;0;4
+FILE_NAME_1=567;C;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fattach.c;0;4
+FILE_NAME_2=0;C;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fhashmap.c;0;4
+FILE_NAME_3=0;C++;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fhashmap.h;0;4
+FILE_NAME_4=888;C;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fstrings.c;0;4
+FILE_NAME_5=0;C++;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fstrings.h;0;4
+FILE_NAME_6=166;C;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fwhatfiles.c;0;4
+FILE_NAME_7=1087;C++;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fwhatfiles.h;0;4
+FILE_NAME_8=0;C++;0;EUTF-8;1;1;0;%2Fusr%2Finclude%2Farm-linux-gnueabihf%2Fasm%2Fptrace.h;0;4
+FILE_NAME_9=0;C++;0;EUTF-8;0;1;0;%2Fusr%2Finclude%2Farm-linux-gnueabihf%2Fsys%2Fptrace.h;0;2
+FILE_NAME_10=0;C++;0;EUTF-8;1;1;0;%2Fusr%2Finclude%2Flinux%2Fptrace.h;0;4
+FILE_NAME_11=1732;C++;0;EUTF-8;0;1;0;%2Fusr%2Finclude%2Farm-linux-gnueabihf%2Fsys%2Fuser.h;0;2
+FILE_NAME_12=683;C;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Futilities.c;0;4
+FILE_NAME_13=783;C;0;EUTF-8;0;1;0;%2Fhome%2Fpi%2Fwhatfiles%2Fsrc%2Fx86_64%2Fregisters.c;0;4
+
+[VTE]
+last_dir=/home/pi/whatfiles
+
+[build-menu]
+NF_00_LB=_Make
+NF_00_CM=make
+NF_00_WD=/home/pi/whatfiles
+CFT_00_LB=_Compile
+CFT_00_CM=gcc -Wall -c "%f"
+CFT_00_WD=
+filetypes=C;