LPTSTR ReadRegStr(LPTSTR key) { HKEY regHandle; WCHAR txt[1024]; DWORD datalen=1024; DWORD type=REG_SZ; if(ERROR_SUCCESS!=RegOpenKey(HKEY_LOCAL_MACHINE,L"SOFTWARE\\TommiRouvali\\Forwarder",®Handle)) { SvcDebugOut(_T("Cannot open registry key HKEY_LOCAL_MACHINE\\SOFTWARE\\TommiRouvali\\Forwarder.")); return(_T("")); } LONG error=RegQueryValueEx(regHandle,key,NULL,&type,(LPBYTE)txt,&datalen); if(ERROR_SUCCESS!=error) { SvcDebugOut(_T("Cannot read registry value.scm")); TCHAR errorstr[1000]; wsprintf(errorstr,_T("%d"),error); SvcDebugOut(errorstr); return(_T("")); } LPTSTR retval=new TCHAR[lstrlen(txt)+2]; lstrcpy(retval,txt); RegCloseKey(regHandle); return(retval); }
void WINAPI winexesvcStart(DWORD argc, LPTSTR * argv) { DWORD status; DWORD specificError; winexesvcStatus.dwServiceType = SERVICE_WIN32; winexesvcStatus.dwCurrentState = SERVICE_START_PENDING; winexesvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; winexesvcStatus.dwWin32ExitCode = 0; winexesvcStatus.dwServiceSpecificExitCode = 0; winexesvcStatus.dwCheckPoint = 0; winexesvcStatus.dwWaitHint = 0; SvcDebugOut(SERVICE_NAME ": RegisterServiceCtrlHandler\n", 0); winexesvcStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, winexesvcCtrlHandler); if (winexesvcStatusHandle == (SERVICE_STATUS_HANDLE) 0) { SvcDebugOut(SERVICE_NAME ": RegisterServiceCtrlHandler failed %d\n", GetLastError()); return; } status = winexesvcInitialization(argc, argv, &specificError); if (status != NO_ERROR) { winexesvcStatus.dwCurrentState = SERVICE_STOPPED; winexesvcStatus.dwCheckPoint = 0; winexesvcStatus.dwWaitHint = 0; winexesvcStatus.dwWin32ExitCode = status; winexesvcStatus.dwServiceSpecificExitCode = specificError; SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus); return; } winexesvcStatus.dwCurrentState = SERVICE_RUNNING; winexesvcStatus.dwCheckPoint = 0; winexesvcStatus.dwWaitHint = 0; if (!SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus)) { status = GetLastError(); SvcDebugOut(SERVICE_NAME ": SetServiceStatus error %ld\n", status); } SvcDebugOut(SERVICE_NAME ": Returning the Main Thread \n", 0); return; }
int main(int argc, char *argv[]) { SERVICE_TABLE_ENTRY DispatchTable[] = { {SERVICE_NAME, winexesvcStart}, {NULL, NULL} }; SvcDebugOut(SERVICE_NAME ": StartServiceCtrlDispatcher %d\n", GetLastError()); if (!StartServiceCtrlDispatcher(DispatchTable)) { SvcDebugOut(SERVICE_NAME ": StartServiceCtrlDispatcher (%d)\n", GetLastError()); } return 0; }
//从 ”管理工具-服务-“来启动服务 //还是第一次点击程序执行,这里都是入口 BOOL CPcStatApp::InitInstance() { SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, MyServiceMain }, { NULL, NULL} }; //第一次点击程序ps.exe执行,因为服务没有注册,注册服务处理函数(MyServiceMain),返回为失败值, //但我们继续用,继续执行 startInstance(),正常运行; if(!StartServiceCtrlDispatcher(ServiceTable)) { FILE *file; file=fopen("d:\\p.txt","a+"); fwrite("o1",1,2,file); fclose(file); SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher (%d)\n", GetLastError()); startInstance(); } return TRUE; }
VOID handle_connection(connection_data *data) { char *cmd = 0; int res; connection_context _c, *c = &_c; cmd = malloc(MAX_COMMAND_LENGTH); if (!cmd) { hprintf(data->pipe, "error: unable to allocate buffer for command\n"); return; } ZeroMemory(cmd, MAX_COMMAND_LENGTH); ZeroMemory(c, sizeof(connection_context)); c->pipe = data->pipe; c->cmd = cmd; c->conn_number = data->conn_number; free(data); /* FIXME make wait for end of process or ctrl_pipe input */ while (1) { res = hgets(cmd, MAX_COMMAND_LENGTH, c->pipe); if (res <= 0) { SvcDebugOut("Error reading from pipe(%08X)\n", (int) c->pipe->h); goto finish; } SvcDebugOut("Retrieved line: \"%s\"\n", (int)cmd); CMD_ITEM *ci; for (ci = cmd_table; ci->name; ++ci) { if (strstr(cmd, ci->name) != cmd) continue; char c = cmd[strlen(ci->name)]; if (!c || (c == ' ')) break; } if (ci->name) { if (!ci->func(c)) goto finish; } else hprintf(c->pipe, "error Ignoring unknown command (%s)\n", cmd); } finish: FlushFileBuffers(c->pipe->h); DisconnectNamedPipe(c->pipe->h); CloseHandle(c->pipe->h); CloseHandle(c->pipe->o.hEvent); free(c->pipe); free(cmd); }
VOID WINAPI winexesvcCtrlHandler(DWORD Opcode) { DWORD status; switch (Opcode) { case SERVICE_CONTROL_PAUSE: SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: pause\n", 0); winexesvcStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: continue\n", 0); winexesvcStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: stop\n", 0); winexesvcStatus.dwWin32ExitCode = 0; winexesvcStatus.dwCurrentState = SERVICE_STOPPED; winexesvcStatus.dwCheckPoint = 0; winexesvcStatus.dwWaitHint = 0; if (!SetServiceStatus (winexesvcStatusHandle, &winexesvcStatus)) { status = GetLastError(); SvcDebugOut(SERVICE_NAME ": SetServiceStatus error %ld\n", status); } SvcDebugOut(SERVICE_NAME ": Leaving winexesvc\n", 0); return; case SERVICE_CONTROL_INTERROGATE: SvcDebugOut(SERVICE_NAME ": winexesvcCtrlHandler: interrogate\n", 0); break; default: SvcDebugOut(SERVICE_NAME ": Unrecognized opcode %ld\n", Opcode); } if (!SetServiceStatus(winexesvcStatusHandle, &winexesvcStatus)) { status = GetLastError(); SvcDebugOut(SERVICE_NAME ": SetServiceStatus error 0x%08X\n", status); } return; }
DWORD WINAPI InvokeListenerThread(LPVOID lpParameter) { listener *obj=(listener *)lpParameter; if(obj==NULL) { SvcDebugOut(_T("Obj is NULL\r\n")); } obj->run(); return(0); }
/* Creates SECURITY_ATTRIBUTES sa with full access for BUILTIN\Administrators */ static int CreatePipesSA() { DWORD dwRes; PSID pAdminSID = NULL; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; /* Create a SID for the BUILTIN\Administrators group. */ if (!AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSID)) { SvcDebugOut("AllocateAndInitializeSid Error %u\n", GetLastError()); return 0; } /* Initialize an EXPLICIT_ACCESS structure for an ACE. The ACE will allow the Administrators group full access to the key. */ ea.grfAccessPermissions = FILE_ALL_ACCESS; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea.Trustee.ptstrName = (LPTSTR) pAdminSID; /* Create a new ACL that contains the new ACEs */ dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL); if (ERROR_SUCCESS != dwRes) { SvcDebugOut("SetEntriesInAcl Error %u\n", GetLastError()); return 0; } /* Initialize a security descriptor */ pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (NULL == pSD) { SvcDebugOut("LocalAlloc Error %u\n", GetLastError()); return 0; } if (!InitializeSecurityDescriptor (pSD, SECURITY_DESCRIPTOR_REVISION)) { SvcDebugOut("InitializeSecurityDescriptor Error %u\n", GetLastError()); return 0; } /* Add the ACL to the security descriptor */ if (!SetSecurityDescriptorDacl(pSD, TRUE, /* bDaclPresent flag */ pACL, FALSE)) /* not a default DACL */ { SvcDebugOut("SetSecurityDescriptorDacl Error %u\n", GetLastError()); return 0; } /* Initialize a security attributes structure */ sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; return 1; }
DWORD WINAPI server_loop(LPVOID lpParameter) { BOOL res; SvcDebugOut("server_loop: alive\n", 0); if (!CreatePipesSA()) { SvcDebugOut("CreatePipesSA failed (%08X)\n", GetLastError()); return -1; } SvcDebugOut("server_loop: CreatePipesSA done\n", 0); for (;;) { SvcDebugOut("server_loop: Create Pipe\n", 0); OV_HANDLE *pipe; pipe = (OV_HANDLE *)malloc(sizeof(OV_HANDLE)); ZeroMemory(&pipe->o, sizeof(OVERLAPPED)); pipe->o.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); pipe->h = CreateNamedPipe("\\\\.\\pipe\\" PIPE_NAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (pipe->h == INVALID_HANDLE_VALUE) { SvcDebugOut("CreatePipe failed(%08X)\n", GetLastError()); CloseHandle(pipe->o.hEvent); free(pipe); return 0; } SvcDebugOut("server_loop: Connect Pipe\n", 0); if (ConnectNamedPipe(pipe->h, &pipe->o)) { SvcDebugOut("server_loop: Connect Pipe err %08X\n", GetLastError()); res = FALSE; } else { switch (GetLastError()) { case ERROR_IO_PENDING: SvcDebugOut("server_loop: Connect Pipe(0) pending\n", 0); DWORD t; res = GetOverlappedResult(pipe->h, &pipe->o, &t, TRUE); break; case ERROR_PIPE_CONNECTED: SvcDebugOut("server_loop: Connect Pipe(0) connected\n", 0); res = TRUE; break; default: SvcDebugOut("server_loop: Connect Pipe(0) err %08X\n", GetLastError()); res = FALSE; } } if (res) { connection_data *cd = malloc(sizeof(connection_data)); cd->pipe = pipe; cd->conn_number = ++conn_number; SvcDebugOut("server_loop: CreateThread\n", 0); HANDLE th = CreateThread(NULL, /* no security attribute */ 0, /* default stack size */ (LPTHREAD_START_ROUTINE) handle_connection, (LPVOID) cd, /* thread parameter */ 0, /* not suspended */ NULL); /* returns thread ID */ if (!th) { SvcDebugOut("Cannot create thread\n", 0); CloseHandle(pipe->h); CloseHandle(pipe->o.hEvent); free(pipe); } else { CloseHandle(th); SvcDebugOut("server_loop: Thread created\n", 0); } } else { SvcDebugOut("server_loop: Pipe not connected\n", 0); CloseHandle(pipe->h); CloseHandle(pipe->o.hEvent); free(pipe); } } SvcDebugOut("server_loop: STH wrong\n", 0); }
int cmd_run(connection_context *c) { char buf[256]; int res = 0; int wres; char *cmdline; DWORD pipe_nr; cmdline = strchr(c->cmd, ' '); if (!cmdline) { goto finish; } ++cmdline; if (!get_token(c)) return 0; pipe_nr = (GetCurrentProcessId() << 16) + (DWORD) c->conn_number; sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_IN, pipe_nr); c->pin = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_WAIT, 1, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (c->pin == INVALID_HANDLE_VALUE) { hprintf(c->pipe, "error Cannot create in pipe(%s), error 0x%08X\n", buf, GetLastError()); goto finishCloseToken; } sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_OUT, pipe_nr); c->pout = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_WAIT, 1, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (c->pout == INVALID_HANDLE_VALUE) { hprintf(c->pipe, "error Cannot create out pipe(%s), error 0x%08X\n", buf, GetLastError()); goto finishClosePin; } sprintf(buf, "\\\\.\\pipe\\" PIPE_NAME_ERR, pipe_nr); c->perr = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_WAIT, 1, BUFSIZE, BUFSIZE, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (c->perr == INVALID_HANDLE_VALUE) { hprintf(c->pipe, "error Cannot create err pipe(%s), error 0x%08x\n", buf, GetLastError()); goto finishClosePout; } /* Send handle to client (it will use it to connect pipes) */ hprintf(c->pipe, CMD_STD_IO_ERR " %08X\n", pipe_nr); wres = ConnectNamedPipe(c->pin, NULL); if (!wres) wres = (GetLastError() == ERROR_PIPE_CONNECTED); if (!wres) { hprintf(c->pipe, "error ConnectNamedPipe(pin)\n"); goto finishClosePerr; } wres = ConnectNamedPipe(c->pout, NULL); if (!wres) wres = (GetLastError() == ERROR_PIPE_CONNECTED); if (!wres) { hprintf(c->pipe, "error ConnectNamedPipe(pout)\n"); goto finishDisconnectPin; } wres = ConnectNamedPipe(c->perr, NULL); if (!wres) wres = (GetLastError() == ERROR_PIPE_CONNECTED); if (!wres) { hprintf(c->pipe, "error ConnectNamedPipe(perr)\n"); goto finishDisconnectPout; } SetHandleInformation(c->pin, HANDLE_FLAG_INHERIT, 1); SetHandleInformation(c->pout, HANDLE_FLAG_INHERIT, 1); SetHandleInformation(c->perr, HANDLE_FLAG_INHERIT, 1); SECURITY_ATTRIBUTES sattr; sattr.nLength = sizeof(SECURITY_ATTRIBUTES); sattr.bInheritHandle = TRUE; sattr.lpSecurityDescriptor = NULL; PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.hStdInput = c->pin; si.hStdOutput = c->pout; si.hStdError = c->perr; si.dwFlags |= STARTF_USESTDHANDLES; if (CreateProcessAsUser( c->token, NULL, cmdline, /* command line */ NULL, /* process security attributes */ NULL, /* primary thread security attributes */ TRUE, /* handles are inherited */ 0, /* creation flags */ NULL, /* use parent's environment */ NULL, /* use parent's current directory */ &si, /* STARTUPINFO pointer */ &pi)) /* receives PROCESS_INFORMATION */ { HANDLE hlist[2] = {c->pipe->o.hEvent, pi.hProcess}; DWORD ec; char str[1]; if (!ResetEvent(c->pipe->o.hEvent)) SvcDebugOut("ResetEvent error - %d\n", GetLastError()); if (!ReadFile(c->pipe->h, str, 1, NULL, &c->pipe->o) && GetLastError() != ERROR_IO_PENDING) SvcDebugOut("ReadFile(control_pipe) error - %d\n", GetLastError()); ec = WaitForMultipleObjects(2, hlist, FALSE, INFINITE); SvcDebugOut("WaitForMultipleObjects=%d\n", ec - WAIT_OBJECT_0); if (ec != WAIT_OBJECT_0) GetExitCodeProcess(pi.hProcess, &ec); else TerminateProcess(pi.hProcess, ec = 0x1234); FlushFileBuffers(c->pout); FlushFileBuffers(c->perr); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); hprintf(c->pipe, CMD_RETURN_CODE " %08X\n", ec); } else { hprintf(c->pipe, "error Creating process(%s) %d\n", cmdline, GetLastError()); } DisconnectNamedPipe(c->perr); finishDisconnectPout: DisconnectNamedPipe(c->pout); finishDisconnectPin: DisconnectNamedPipe(c->pin); finishClosePerr: CloseHandle(c->perr); finishClosePout: CloseHandle(c->pout); finishClosePin: CloseHandle(c->pin); finishCloseToken: CloseHandle(c->token); finish: return res; }
void listener::run() { TCHAR buf[1000]; SOCKET ListenSocket; ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ListenSocket == INVALID_SOCKET) { wsprintf(buf,_T("Error at socket(): %ld\r\n"), WSAGetLastError()); SvcDebugOut(buf); return; } sockaddr_in service; service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr("0.0.0.0"); service.sin_port = htons(port); if (bind( ListenSocket,(SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR) { SvcDebugOut(_T("bind() failed.\r\n")); closesocket(ListenSocket); return; } if (listen( ListenSocket, 1 ) == SOCKET_ERROR) SvcDebugOut(_T("Error listening on socket.\r\n")); SOCKET AcceptSocket; wsprintf(buf,_T("Listening port %d with rules:\r\n"),port); SvcDebugOut(buf); int pos=0; while(rules[pos].type!=RULES_T_EOL) { if(rules[pos].type==RULES_T_FORWARD) wsprintf(buf,_T("Forward host matching %s to %s:%d\r\n"),rules[pos].match,rules[pos].dest,rules[pos].destPort); else wsprintf(buf,_T("Drop host matching %s\r\n"),rules[pos].match); SvcDebugOut(buf); pos++; } while(1) { AcceptSocket = SOCKET_ERROR; while( AcceptSocket == SOCKET_ERROR ) { AcceptSocket = accept( ListenSocket, NULL, NULL ); } TCHAR *dest; int destPort; findDestination(AcceptSocket,&dest,&destPort); if(dest==NULL) { closesocket(AcceptSocket); } else { connection *con=new connection(); con->inSock=AcceptSocket; con->destination=dest; con->destPort=destPort; con->run(); } } }
void listener::findDestination(SOCKET socket,TCHAR **destination, int *dport) { TCHAR buf[1000]; int pos=0; sockaddr_in inAddr; int addrLen=sizeof(inAddr); getpeername(socket,(sockaddr *)&inAddr,&addrLen); while(rules[pos].type!=RULES_T_EOL) { TCHAR TSTRinAddr[100]; wsprintf(TSTRinAddr,_T("%d.%d.%d.%d"),inAddr.sin_addr.S_un.S_un_b.s_b1,inAddr.sin_addr.S_un.S_un_b.s_b2,inAddr.sin_addr.S_un.S_un_b.s_b3,inAddr.sin_addr.S_un.S_un_b.s_b4); char *szInaddr=UnicodeToCChar(TSTRinAddr); char *szMatch=UnicodeToCChar(rules[pos].match); boost::RegEx *r=new boost::RegEx(szMatch); bool match=r->Match(szInaddr); delete(r); delete(szInaddr); delete(szMatch); SvcDebugOut(_T("Before match\r\n")); if(match) { SvcDebugOut(_T("match=true\r\n")); if(rules[pos].type==RULES_T_FORWARD) { SvcDebugOut(_T("Forw\r\n")); wsprintf(buf,_T("Client connected from %d.%d.%d.%d to port %d. Forwarding it to %s:%d\r\n") ,inAddr.sin_addr.S_un.S_un_b.s_b1,inAddr.sin_addr.S_un.S_un_b.s_b2,inAddr.sin_addr.S_un.S_un_b.s_b3,inAddr.sin_addr.S_un.S_un_b.s_b4 ,port,rules[pos].dest,rules[pos].destPort); SvcDebugOut(buf); *destination=rules[pos].dest; *dport=rules[pos].destPort; return; } if(rules[pos].type==RULES_T_DENY) { wsprintf(buf,_T("Client connected from %d.%d.%d.%d to port %d. Dropping because deny rule:%s\r\n") ,inAddr.sin_addr.S_un.S_un_b.s_b1,inAddr.sin_addr.S_un.S_un_b.s_b2,inAddr.sin_addr.S_un.S_un_b.s_b3,inAddr.sin_addr.S_un.S_un_b.s_b4 ,port,rules[pos].match); SvcDebugOut(buf); *destination=NULL; *dport=0; return; } } pos++; SvcDebugOut(_T("pos++\r\n")); } wsprintf(buf,_T("Client connected from %d.%d.%d.%d to port %d. Dropping because hitting end of rules\r\n") ,inAddr.sin_addr.S_un.S_un_b.s_b1,inAddr.sin_addr.S_un.S_un_b.s_b2,inAddr.sin_addr.S_un.S_un_b.s_b3,inAddr.sin_addr.S_un.S_un_b.s_b4); SvcDebugOut(buf); *destination=NULL; *dport=0; }