summaryrefslogtreecommitdiff
path: root/detect/gdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'detect/gdb.c')
-rw-r--r--detect/gdb.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/detect/gdb.c b/detect/gdb.c
new file mode 100644
index 0000000..53a0311
--- /dev/null
+++ b/detect/gdb.c
@@ -0,0 +1,99 @@
1/*
2 * Various tricks to detect GDB or any related GNU tools
3 *
4 */
5
6
7#include <signal.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/ptrace.h>
12
13
14#define check_strings(str_buff) (strstr(str_buff, "gdb") || strstr(str_buff, "ltrace") || strstr(str_buff, "strace"))
15
16/*
17 * This is an old well known bug (#7912)
18 *
19 * GDB leaks 2 file descriptors when it opens a program to be debugged.
20 * Both file descriptors are pointing to the file being debugged.
21 */
22int dbg_file_descriptor(){
23 FILE* fd = fopen("/", "r");
24 int nb_fd = fileno(fd);
25 fclose(fd);
26
27 return (nb_fd > 3);
28}
29
30/*
31 * Detect GDB by the mean of /proc/$PID/cmdline, which should no be "gdb"
32 */
33int dbg_cmdline(){
34 char buff [24], tmp [16];
35 FILE* f;
36
37 snprintf(buff, 24, "/proc/%d/cmdline", getppid());
38 f = fopen(buff, "r");
39 fgets(tmp, 16, f);
40 fclose(f);
41
42 return check_strings(tmp);
43}
44
45/*
46 * Classic self ptrace trick: a program can only be ptraced by ONE other.
47 */
48int dbg_ptrace(){
49 if(ptrace(PTRACE_TRACEME, 0, 0, 0) == -1)
50 return 1;
51 //TODO : detach ptrace
52 return 0;
53}
54
55/*
56 * GDB handle SIGTRAP, if we raise one under GDB, it will not reach our handler.
57 * FIXME
58 */
59unsigned int no_dbg = 1;
60static void handler(int signum){no_dbg = 0;}
61int dbg_sigtrap(){
62 no_dbg = 1;
63 signal(SIGTRAP, handler);
64 raise(SIGTRAP);
65 signal(SIGTRAP, SIG_IGN);
66 return no_dbg;
67}
68
69/*
70 * Scan memory for breakpoints
71 * TODO
72 */
73int dbg_check_bp(){
74 unsigned char* start;
75 size_t size;
76 size_t i;
77
78 for(i = 0; i < size; i++){
79 if(start[i] == 0xCC || start[i] == 0xCD)
80 return 1;
81 }
82 return 0;
83}
84
85/*
86 * Check the parent's name
87 */
88int dbg_getppid_name(){
89 char buff1[24], buff2[16];
90 FILE* f;
91
92 snprintf(buff1, 24, "/proc/%d/status", getppid());
93 f = fopen(buff1, "r");
94 fgets(buff2, 16, f);
95 fclose(f);
96
97 return check_strings(buff2);
98}
99