Skip to content

Commit 4c80e69

Browse files
feat: Add option to kill running process
1 parent 380dedf commit 4c80e69

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Options:
2121
-d run as a daemon
2222
-h <hostname> hostname for obfuscation (required)
2323
-i <interface> network interface name (required)
24+
-k kill the running process
2425
-m <mark> fwmark for bypassing the queue
2526
-n <number> netfilter queue number
2627
-r <repeat> duplicate generated packets for <repeat> times

src/fakehttp.c

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#define _GNU_SOURCE
21+
#include <dirent.h>
2122
#include <errno.h>
2223
#include <fcntl.h>
2324
#include <inttypes.h>
@@ -54,6 +55,7 @@ static int g_sockfd = 0;
5455
static int g_exit = 0;
5556
static int g_daemon = 0;
5657
static int g_silent = 0;
58+
static int g_killproc = 0;
5759
static int g_repeat = 3;
5860
static uint32_t g_fwmark = 0x8000;
5961
static uint32_t g_fwmask = 0;
@@ -71,6 +73,7 @@ static void print_usage(const char *name)
7173
" -d run as a daemon\n"
7274
" -h <hostname> hostname for obfuscation (required)\n"
7375
" -i <interface> network interface name (required)\n"
76+
" -k kill the running process\n"
7477
" -m <mark> fwmark for bypassing the queue\n"
7578
" -n <number> netfilter queue number\n"
7679
" -r <repeat> duplicate generated packets for <repeat> "
@@ -174,6 +177,76 @@ static int signal_setup(void)
174177
}
175178

176179

180+
static int kill_running(int signal)
181+
{
182+
int res, matched, err;
183+
ssize_t len;
184+
DIR *procfs;
185+
struct dirent *entry;
186+
pid_t pid, self_pid;
187+
char self_path[PATH_MAX], proc_path[PATH_MAX], exe_path[PATH_MAX];
188+
189+
self_pid = getpid();
190+
191+
len = readlink("/proc/self/exe", self_path, sizeof(self_path));
192+
if (len < 0 || (size_t) len >= sizeof(self_path)) {
193+
E("ERROR: readlink(): /proc/self/exe: %s", strerror(errno));
194+
return -1;
195+
}
196+
self_path[len] = 0;
197+
198+
procfs = opendir("/proc");
199+
if (!procfs) {
200+
E("ERROR: opendir(): /proc: %s", strerror(errno));
201+
return -1;
202+
}
203+
204+
matched = err = 0;
205+
while ((entry = readdir(procfs))) {
206+
pid = strtoull(entry->d_name, NULL, 0);
207+
if (pid <= 1 || pid == self_pid) {
208+
continue;
209+
}
210+
211+
res = snprintf(exe_path, sizeof(exe_path), "/proc/%s/exe",
212+
entry->d_name);
213+
if (res < 0 || (size_t) res >= sizeof(exe_path)) {
214+
continue;
215+
}
216+
217+
len = readlink(exe_path, proc_path, sizeof(proc_path));
218+
if (len < 0 || (size_t) len >= sizeof(self_path)) {
219+
continue;
220+
}
221+
proc_path[len] = 0;
222+
223+
if (strcmp(self_path, proc_path) == 0) {
224+
matched = 1;
225+
226+
if (signal) {
227+
res = kill(pid, signal);
228+
if (res < 0) {
229+
E("ERROR: kill(): %llu: %s", pid, strerror(errno));
230+
err = 1;
231+
}
232+
}
233+
}
234+
}
235+
236+
res = closedir(procfs);
237+
if (res < 0) {
238+
E("ERROR: closedir(): %s", strerror(errno));
239+
err = 1;
240+
}
241+
242+
if (matched && !err) {
243+
return 0;
244+
}
245+
246+
return -1;
247+
}
248+
249+
177250
static int execute_command(char **argv, int silent)
178251
{
179252
int res, status, fd, i;
@@ -714,7 +787,7 @@ int main(int argc, char *argv[])
714787
return EXIT_FAILURE;
715788
}
716789

717-
while ((opt = getopt(argc, argv, "dh:i:m:n:r:st:w:x:")) != -1) {
790+
while ((opt = getopt(argc, argv, "dh:i:km:n:r:st:w:x:")) != -1) {
718791
switch (opt) {
719792
case 'd':
720793
g_daemon = 1;
@@ -736,6 +809,9 @@ int main(int argc, char *argv[])
736809
return EXIT_FAILURE;
737810
}
738811
break;
812+
case 'k':
813+
g_killproc = 1;
814+
break;
739815
case 'm':
740816
tmp = strtoull(optarg, NULL, 0);
741817
if (!tmp || tmp > UINT32_MAX) {
@@ -799,6 +875,11 @@ int main(int argc, char *argv[])
799875
}
800876
}
801877

878+
if (g_killproc) {
879+
res = kill_running(SIGTERM);
880+
return res ? EXIT_FAILURE : EXIT_SUCCESS;
881+
}
882+
802883
if (!g_fwmask) {
803884
g_fwmask = g_fwmark;
804885
} else if ((g_fwmark & g_fwmask) != g_fwmark) {
@@ -909,7 +990,13 @@ int main(int argc, char *argv[])
909990
if (!qh) {
910991
switch (errno) {
911992
case EPERM:
912-
err_hint = " (Another process is running / Are you root?)";
993+
res = kill_running(0);
994+
errno = EPERM;
995+
if (res) {
996+
err_hint = " (Another process is running / Are you root?)";
997+
} else {
998+
err_hint = " (Another process is running)";
999+
}
9131000
break;
9141001
case EINVAL:
9151002
err_hint = " (Missing kernel module?)";

0 commit comments

Comments
 (0)