Run as Windows service

This commit is contained in:
lufog 2024-04-23 15:48:37 +03:00
parent bd290b1b5f
commit c3ccd45426
8 changed files with 144 additions and 2 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.vscode
ciadpi.exe

View File

@ -2,12 +2,13 @@ TARGET = ciadpi
CC ?= gcc CC ?= gcc
CFLAGS += -std=c99 -O2 -D_XOPEN_SOURCE=500 CFLAGS += -std=c99 -O2 -D_XOPEN_SOURCE=500
SOURCES = packets.c main.c conev.c proxy.c desync.c mpool.c extend.c SOURCES = packets.c main.c conev.c proxy.c desync.c mpool.c extend.c
WIN_SOURCES = win_service.c
all: all:
$(CC) $(CFLAGS) $(SOURCES) -I . -o $(TARGET) $(CC) $(CFLAGS) $(SOURCES) -I . -o $(TARGET)
windows: windows:
$(CC) $(CFLAGS) $(SOURCES) -I . -lws2_32 -lmswsock -o $(TARGET).exe $(CC) $(CFLAGS) $(SOURCES) $(WIN_SOURCES) -I . -lws2_32 -lmswsock -o $(TARGET).exe
clean: clean:
rm -f $(TARGET) *.o rm -f $(TARGET) *.o

4
dist/windows/byedpi.bat vendored Normal file
View File

@ -0,0 +1,4 @@
@echo off
title ByeDPI
ciadpi.exe --split 1+s --disorder 3+s --mod-http=h,d --auto --tlsrec 1+s

13
dist/windows/service_delete.bat vendored Normal file
View File

@ -0,0 +1,13 @@
@echo off
title ByeDPI - Delete Service
echo This script should be run with administrator privileges.
echo Right click - run as administrator.
echo Press any key if you're running it as administrator.
pause
set svc_name="ByeDPI"
sc stop %svc_name%
sc delete %svc_name%
pause

24
dist/windows/service_install.bat vendored Normal file
View File

@ -0,0 +1,24 @@
@echo off
title ByeDPI - Install Service
pushd "%~dp0"
echo This script should be run with administrator privileges.
echo Right click - run as administrator.
echo Press any key if you're running it as administrator.
pause
set svc_name="ByeDPI"
set svc_desc="Local SOCKS proxy server to bypass DPI (Deep Packet Inspection)."
:: Set up launch args (bypass methods) here. The "--service" arg is required;
:: without it, the program will not register itself as a Windows service!
set svc_bin="\"%cd%\ciadpi.exe\" --service --split 1+s --disorder 3+s --mod-http=h,d --auto --tlsrec 1+s"
sc stop %svc_name%
sc delete %svc_name%
sc create %svc_name% binPath= %svc_bin% start= "auto"
sc description %svc_name% %svc_desc%
sc start %svc_name%
popd
pause

20
main.c
View File

@ -20,6 +20,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#else #else
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include "win_service.h"
#define close(fd) closesocket(fd) #define close(fd) closesocket(fd)
#endif #endif
@ -139,6 +140,9 @@ const struct option options[] = {
#ifdef __linux__ #ifdef __linux__
{"md5sig", 0, 0, 'S'}, {"md5sig", 0, 0, 'S'},
#endif #endif
#ifdef _WIN32
{"service", 0, 0, 'B'},
#endif
{"fake-data", 1, 0, 'l'}, {"fake-data", 1, 0, 'l'},
{"tls-sni", 1, 0, 'n'}, {"tls-sni", 1, 0, 'n'},
#endif #endif
@ -433,6 +437,8 @@ int main(int argc, char **argv)
uniperror("WSAStartup"); uniperror("WSAStartup");
return -1; return -1;
} }
int as_winsvc = 0;
#endif #endif
struct sockaddr_ina s = { struct sockaddr_ina s = {
.in = { .in = {
@ -459,7 +465,7 @@ int main(int argc, char **argv)
int rez; int rez;
int invalid = 0; int invalid = 0;
long val = 0; ssize_t val = 0;
char *end = 0; char *end = 0;
uint16_t port = htons(1080); uint16_t port = htons(1080);
@ -475,6 +481,12 @@ int main(int argc, char **argv)
argc, argv, opt, options, 0)) != -1) { argc, argv, opt, options, 0)) != -1) {
switch (rez) { switch (rez) {
#ifdef _WIN32
case 'B':
as_winsvc = 1;
break;
#endif
case 'N': case 'N':
params.resolve = 0; params.resolve = 0;
break; break;
@ -803,6 +815,12 @@ int main(int argc, char **argv)
return -1; return -1;
} }
} }
#ifdef _WIN32
if (as_winsvc && register_winsvc(argc, argv))
return 0;
#endif
if (invalid) { if (invalid) {
fprintf(stderr, "invalid value: -%c %s\n", rez, optarg); fprintf(stderr, "invalid value: -%c %s\n", rez, optarg);
clear_params(); clear_params();

79
win_service.c Normal file
View File

@ -0,0 +1,79 @@
#include "win_service.h"
#include <minwindef.h>
#include <winsvc.h>
#define SERVICE_NAME "ByeDPI"
static SERVICE_STATUS ServiceStatus;
static SERVICE_STATUS_HANDLE hStatus;
static int svc_argc = 0;
static char **svc_argv = NULL;
int main(int argc, char *argv[]);
void service_ctrl_handler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
default:
break;
}
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
void service_main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
{
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 1;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(SERVICE_NAME, (LPHANDLER_FUNCTION)service_ctrl_handler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
SetServiceStatus(hStatus, &ServiceStatus);
// Calling main with saved argc & argv
ServiceStatus.dwWin32ExitCode = (DWORD)main(svc_argc, svc_argv);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
int register_winsvc(int argc, char *argv[])
{
SERVICE_TABLE_ENTRY ServiceTable[] = {
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main},
{NULL, NULL}
};
// Save args passed to the program to use instead of the service args.
if (!svc_argc && !svc_argv) {
svc_argc = argc;
svc_argv = calloc((size_t)(argc + 1), sizeof(void*));
for (int i = 0; i < argc; i++)
svc_argv[i] = strdup(argv[i]);
}
int result = StartServiceCtrlDispatcher(ServiceTable);
if (svc_argc && svc_argv) {
for (int i = 0; i < svc_argc; i++)
free(svc_argv[i]);
free(svc_argv);
}
return result;
}

1
win_service.h Normal file
View File

@ -0,0 +1 @@
int register_winsvc(int argc, char *argv[]);