-
Notifications
You must be signed in to change notification settings - Fork 6
/
detectgdb.cpp
150 lines (123 loc) · 3.35 KB
/
detectgdb.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "detectgdb.h"
#ifndef _MSC_VER
#include <sys/types.h>
#ifndef DARWIN_NO_CARBON // skip for ios
#include <sys/ptrace.h>
#endif
#include <sys/wait.h>
#else
#include <Windows.h> // IsDebuggerPresent
#endif
#ifndef PTRACE_ATTACH
#define PTRACE_ATTACH PT_ATTACH
#define PTRACE_CONT PT_CONTINUE
#define PTRACE_DETACH PT_DETACH
#endif
#include <stdio.h>
#include <errno.h>
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
#if defined(__GNUC__)
#include <unistd.h>
#else
#define fileno _fileno
#endif
static bool was_started_through_gdb_ = DetectGdb::is_running_through_gdb ();
#ifndef _MSC_VER
// http://stackoverflow.com/a/10973747/1513411
// gdb apparently opens FD(s) 3,4,5 (whereas a typical program uses only stdin=0, stdout=1, stderr=2)
bool is_running_through_gdb_xorl()
{
bool gdb = false;
FILE *fd = fopen("/tmp", "r");
if (fileno(fd) >= 5)
{
gdb = true;
}
fclose(fd);
return gdb;
}
// http://stackoverflow.com/a/3599394/1513411
bool is_running_through_gdb_terminus()
{
int pid = fork();
int status = 0;
int res;
if (pid == -1)
{
printf("Fork failed!\n");
perror("fork");
return 1;
}
if (pid == 0)
{
/* Child fork */
int ppid = getppid();
if (ptrace(PTRACE_ATTACH, ppid, nullptr, 0) == 0)
{
/* Wait for the parent to stop and continue it */
waitpid(ppid, nullptr, 0);
ptrace(PTRACE_CONT, ppid, nullptr, 0);
/* Detach */
ptrace(PTRACE_DETACH, ppid, nullptr, 0);
/* We were the tracers, so gdb is not present */
res = 0;
}
else
{
/* Trace failed so gdb is present */
res = 1;
}
_exit(res);
}
else
{
pid_t w = 0;
do
{
// the first signal might be an unblocked signal, skip it
w = waitpid(pid, &status, 0);
}
while (w < 0 && errno == EINTR);
// fall-back to return "true" if the fork failed for whatever reason
res = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
//std::cout << "WIFCONTINUED(status)="<< WIFCONTINUED(status)
// << ", WSTOPSIG(status)=" << WSTOPSIG(status) << std::endl;
//std::cout << "WIFSTOPPED(status)="<< WIFSTOPPED(status)
// << ", WSTOPSIG(status)=" << WSTOPSIG(status) << std::endl;
//std::cout << "WIFSIGNALED(status)="<< WIFSIGNALED(status)
// << ", WTERMSIG(status)=" << WTERMSIG(status) << std::endl;
//std::cout << "WIFEXITED(status)="<< WIFEXITED(status)
// << ", WEXITSTATUS(status)=" << WEXITSTATUS(status) << std::endl;
}
return res;
}
bool DetectGdb::
is_running_through_gdb()
{
#if defined(__APPLE_CPP__) && (TARGET_OS_IPHONE==0)
// No implementation for detecting IOS debugger
#ifdef _DEBUG
return false;
#else
return true;
#endif
#else
bool is_attached_in_qt_creator = is_running_through_gdb_xorl();
bool is_attached_by_system_debugger = is_running_through_gdb_terminus();
return is_attached_in_qt_creator || is_attached_by_system_debugger;
#endif
}
#else
bool DetectGdb::
is_running_through_gdb()
{
return TRUE == IsDebuggerPresent();
}
#endif
bool DetectGdb::
was_started_through_gdb()
{
return was_started_through_gdb_;
}