diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..f39da7a0 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,11 @@ +Checks: '-*,bugprone-*,cert-dcl21-cpp,cert-dcl50-cpp,cert-env33-c,cert-err52-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,cppcoreguidelines-*,-cppcoreguidelines-macro-usage,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-vararg,google-build-using-namespace,google-explicit-constructor,google-global-names-in-headers,google-readability-casting,google-runtime-int,google-runtime-operator,hicpp-*,-hicpp-vararg,misc-*,modernize-*,performance-*,readability-*,-readability-named-parameter,-modernize-use-trailing-return-type,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-hicpp-signed-bitwise,-hicpp-uppercase-literal-suffix,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-named-parameter,-cppcoreguidelines-avoid-goto,-cppcoreguidelines-avoid-non-const-global-variables,-hicpp-avoid-goto,-cppcoreguidelines-owning-memory,-readability-uppercase-literal-suffix,-readability-implicit-bool-conversion,-hicpp-no-array-decay,-hicpp-no-malloc,-readability-use-anyofallof,-cppcoreguidelines-prefer-member-initializer,-performance-no-int-to-ptr,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-special-member-functions,-hicpp-special-member-functions,-bugprone-reserved-identifier,-bugprone-easily-swappable-parameters, -bugprone-implicit-widening-of-multiplication-result,-google-explicit-constructor,-bugprone-exception-escape,-hicpp-exception-baseclass,-cppcoreguidelines-prefer-member-initializer,-bugprone-macro-parentheses,-bugprone-suspicious-missing-comma,-bugprone-sizeof-expression,-bugprone-throw-keyword-missing,-cppcoreguidelines-no-malloc,-bugprone-branch-clone,-cppcoreguidelines-pro-bounds-constant-array-index,-hicpp-explicit-conversions,-cppcoreguidelines-pro-type-member-init,-hicpp-member-init,-bugprone-lambda-function-name,-readability-function-cognitive-complexity,-misc-no-recursion,-misc-throw-by-value-catch-by-reference,-readability-simplify-boolean-expr,-readability-identifier-length,-readability-container-data-pointer,-cppcoreguidelines-virtual-class-destructor,-misc-non-private-member-variables-in-classes,-modernize-use-default-member-init,-google-readability-casting,-bugprone-suspicious-memory-comparison,-modernize-use-nodiscard,-modernize-concat-nested-namespaces,-cppcoreguidelines-avoid-do-while,-modernize-macro-to-enum,-misc-const-correctness,-cppcoreguidelines-avoid-const-or-ref-data-members,-misc-use-anonymous-namespace,-misc-misplaced-const,-readability-redundant-member-init,-cppcoreguidelines-macro-to-enum,-misc-include-cleaner,-performance-enum-size,-bugprone-empty-catch,-readability-duplicate-include,-readability-avoid-unconditional-preprocessor-if,-cppcoreguidelines-rvalue-reference-param-not-moved,-cppcoreguidelines-missing-std-forward,-bugprone-casting-through-void,-cppcoreguidelines-non-private-member-variables-in-classes,-bugprone-multi-level-implicit-pointer-conversion,-bugprone-unchecked-optional-access' +CheckOptions: + - key: bugprone-argument-comment.StrictMode + value: 1 + - key: bugprone-exception-escape.FunctionsThatShouldNotThrow + value: WinMain,SDL_main + - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic + value: 1 +FormatStyle: 'file' +WarningsAsErrors: '*' +HeaderFilterRegex: '.*src.*\.hpp$' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b886ae55..d6099649 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,6 +24,42 @@ on: # cancel-in-progress: true jobs: + clang-tidy: + name: Run Clang Tidy + runs-on: ubuntu-24.04 + env: + LLVM_VERSION: 20 + steps: + - name: Checkout Source + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Ninja + uses: seanmiddleditch/gha-setup-ninja@v6 + + - name: Install Clang + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh ${{ env.LLVM_VERSION }} + sudo apt install -y clang-tidy-${{ env.LLVM_VERSION }} + sudo apt install -y clang-${{ env.LLVM_VERSION }} lld-${{ env.LLVM_VERSION }} + sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-${{ env.LLVM_VERSION }} 100 + sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-${{ env.LLVM_VERSION }} 100 + sudo update-alternatives --set cc /usr/bin/clang-${{ env.LLVM_VERSION }} + sudo update-alternatives --set c++ /usr/bin/clang++-${{ env.LLVM_VERSION }} + + - name: CMake Build + run: cmake --preset=${{matrix.preset}} -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/toolchain/android-ndk.cmake && cmake --build --preset=${{matrix.preset}} + if: ${{ startsWith(matrix.platform, 'Android') }} + env: + ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} + ANDROID_ABI: ${{matrix.abi}} + + - name: CMake Build + run: cmake --preset=release -DMOMO_ENABLE_CLANG_TIDY=On && cmake --build --preset=release + verify-formatting: name: Verify Formatting runs-on: ubuntu-24.04 @@ -349,7 +385,7 @@ jobs: summary: name: Pipeline Summary runs-on: ubuntu-24.04 - needs: [build-apiset-dumper, smoke-test-android, create-emulation-root, build, test, verify-formatting] + needs: [clang-tidy, build-apiset-dumper, smoke-test-android, create-emulation-root, build, test, verify-formatting] if: always() steps: - uses: geekyeggo/delete-artifact@v5 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c0b8964..cf72e772 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.26.4) ########################################## option(MOMO_ENABLE_SANITIZER "Enable sanitizer" OFF) +option(MOMO_ENABLE_CLANG_TIDY "Enable clang-tidy checks" OFF) option(MOMO_BUILD_AS_LIBRARY "Configure and Build the emulator as a shared library (without the samples and tests)" OFF) set(MOMO_REFLECTION_LEVEL "0" CACHE STRING "Reflection level for the build") @@ -62,3 +63,4 @@ momo_targets_disable_warnings(${EXTERNAL_TARGETS}) momo_targets_expose_includes(${OWN_TARGETS}) momo_targets_set_warnings_as_errors(${OWN_TARGETS}) +momo_targets_enable_clang_tidy(${OWN_TARGETS}) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 9c67459f..c1939de7 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -346,3 +346,22 @@ endfunction() macro(momo_assign_source_group) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${ARGN}) endmacro() + +########################################## + +function(momo_target_enable_clang_tidy target) + if(MOMO_ENABLE_CLANG_TIDY) + set(CLANG_TIDY_COMMAND "clang-tidy;--use-color;--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy") + + set_target_properties(${target} PROPERTIES C_CLANG_TIDY "${CLANG_TIDY_COMMAND}") + set_target_properties(${target} PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") + endif() +endfunction() + +########################################## + +function(momo_targets_enable_clang_tidy) + foreach(target ${ARGV}) + momo_target_enable_clang_tidy(${target}) + endforeach() +endfunction() diff --git a/src/analyzer/CMakeLists.txt b/src/analyzer/CMakeLists.txt index 2a550be4..51a4615e 100644 --- a/src/analyzer/CMakeLists.txt +++ b/src/analyzer/CMakeLists.txt @@ -10,7 +10,9 @@ add_executable(analyzer ${SRC_FILES}) momo_assign_source_group(${SRC_FILES}) -target_precompile_headers(analyzer PRIVATE std_include.hpp) +if(NOT MOMO_ENABLE_CLANG_TIDY) + target_precompile_headers(analyzer PRIVATE std_include.hpp) +endif() target_link_libraries(analyzer PRIVATE reflect diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index c6c001c9..fca08166 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -164,7 +164,9 @@ namespace static uint64_t count{0}; ++count; if (count > 100 && count % 10000 != 0) + { return; + } } win_emu.log.print(color::green, @@ -184,7 +186,9 @@ namespace static uint64_t count{0}; ++count; if (count > 100 && count % 10000 != 0) + { return; + } } win_emu.log.print(color::blue, "Writing to executable section %s at 0x%" PRIx64 " via 0x%" PRIx64 "\n", diff --git a/src/analyzer/std_include.hpp b/src/analyzer/std_include.hpp index 43df7c99..9719ff6b 100644 --- a/src/analyzer/std_include.hpp +++ b/src/analyzer/std_include.hpp @@ -27,4 +27,5 @@ #include +// NOLINTNEXTLINE(google-global-names-in-headers) using namespace std::literals; diff --git a/src/common/network/address.cpp b/src/common/network/address.cpp index 89068016..b80a8778 100644 --- a/src/common/network/address.cpp +++ b/src/common/network/address.cpp @@ -1,5 +1,6 @@ #include "address.hpp" +#include #include #include "../utils/finally.hpp" @@ -125,7 +126,7 @@ namespace network } } - void address::set_port(const unsigned short port) + void address::set_port(const uint16_t port) { switch (this->get_family()) { @@ -140,7 +141,7 @@ namespace network } } - unsigned short address::get_port() const + uint16_t address::get_port() const { switch (this->get_family()) { @@ -155,27 +156,27 @@ namespace network std::string address::to_string() const { - char buffer[1000] = {}; - std::string addr; + std::string addr{}; + std::array buffer{}; switch (this->get_family()) { case AF_INET: - inet_ntop(this->get_family(), &this->address4_.sin_addr, buffer, sizeof(buffer)); - addr = std::string(buffer); + inet_ntop(this->get_family(), &this->address4_.sin_addr, buffer.data(), buffer.size()); + addr = std::string(buffer.data()); break; case AF_INET6: - inet_ntop(this->get_family(), &this->address6_.sin6_addr, buffer, sizeof(buffer)); - addr = "[" + std::string(buffer) + "]"; + inet_ntop(this->get_family(), &this->address6_.sin6_addr, buffer.data(), buffer.size()); + addr = "[" + std::string(buffer.data()) + "]"; break; default: buffer[0] = '?'; buffer[1] = 0; - addr = std::string(buffer); + addr = std::string(buffer.data()); break; } - return addr + ":"s + std::to_string(this->get_port()); + return addr + ":" + std::to_string(this->get_port()); } bool address::is_local() const @@ -187,8 +188,8 @@ namespace network // According to: https://en.wikipedia.org/wiki/Private_network - uint8_t bytes[4]; - memcpy(bytes, &this->address4_.sin_addr.s_addr, sizeof(bytes)); + std::array bytes{}; + memcpy(bytes.data(), &this->address4_.sin_addr.s_addr, bytes.size()); // 10.X.X.X if (bytes[0] == 10) @@ -346,7 +347,7 @@ namespace network { address a{}; a.set_address(i->ai_addr, static_cast(i->ai_addrlen)); - results.emplace_back(std::move(a)); + results.emplace_back(a); } } } @@ -372,6 +373,8 @@ std::size_t std::hash::operator()(const network::address& a) c std::string_view{reinterpret_cast(a.get_in6_addr().sin6_addr.s6_addr), sizeof(a.get_in6_addr().sin6_addr.s6_addr)}); break; + default: + break; } return hash; diff --git a/src/common/network/address.hpp b/src/common/network/address.hpp index 52fe8018..df3d3e2c 100644 --- a/src/common/network/address.hpp +++ b/src/common/network/address.hpp @@ -63,8 +63,8 @@ namespace network void set_ipv6(const in6_addr& addr); void set_address(const sockaddr* addr, socklen_t length); - void set_port(unsigned short port); - [[nodiscard]] unsigned short get_port() const; + void set_port(uint16_t port); + [[nodiscard]] uint16_t get_port() const; sockaddr& get_addr(); sockaddr_in& get_in_addr(); diff --git a/src/common/network/socket.cpp b/src/common/network/socket.cpp index 1e057da7..cad5d0b1 100644 --- a/src/common/network/socket.cpp +++ b/src/common/network/socket.cpp @@ -71,11 +71,13 @@ namespace network } } + // NOLINTNEXTLINE(readability-make-member-function-const) bool socket::bind(const address& target) { return ::bind(this->socket_, &target.get_addr(), target.get_size()) == 0; } + // NOLINTNEXTLINE(readability-make-member-function-const) bool socket::set_blocking(const bool blocking) { return socket::set_blocking(this->socket_, blocking); @@ -89,7 +91,10 @@ namespace network #else int flags = fcntl(s, F_GETFL, 0); if (flags == -1) + { return false; + } + flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); return fcntl(s, F_SETFL, flags) == 0; #endif @@ -97,30 +102,6 @@ namespace network bool socket::sleep(const std::chrono::milliseconds timeout, const bool in_poll) const { - /*fd_set fdr; - FD_ZERO(&fdr); - FD_SET(this->socket_, &fdr); - - const auto msec = timeout.count(); - - timeval tv{}; - tv.tv_sec = static_cast(msec / 1000ll); - tv.tv_usec = static_cast((msec % 1000) * 1000); - - const auto retval = select(static_cast(this->socket_) + 1, &fdr, nullptr, nullptr, &tv); - if (retval == SOCKET_ERROR) - { - std::this_thread::sleep_for(1ms); - return socket_is_ready; - } - - if (retval > 0) - { - return socket_is_ready; - } - - return !socket_is_ready;*/ - std::vector sockets{}; sockets.push_back(this); diff --git a/src/common/network/tcp_client_socket.cpp b/src/common/network/tcp_client_socket.cpp index fc5921f1..5288b3d3 100644 --- a/src/common/network/tcp_client_socket.cpp +++ b/src/common/network/tcp_client_socket.cpp @@ -1,5 +1,6 @@ #include "tcp_client_socket.hpp" +#include #include namespace network @@ -58,13 +59,13 @@ namespace network std::optional tcp_client_socket::receive(const std::optional max_size) { - char buffer[0x2000]; - const auto size = std::min(sizeof(buffer), max_size.value_or(sizeof(buffer))); + std::array buffer{}; + const auto size = std::min(buffer.size(), max_size.value_or(buffer.size())); - const auto result = recv(this->get_socket(), buffer, static_cast(size), 0); + const auto result = recv(this->get_socket(), buffer.data(), static_cast(size), 0); if (result > 0) { - return std::string(buffer, result); + return std::string(buffer.data(), static_cast(result)); } if (result == 0 || (result < 0 && GET_SOCKET_ERROR() == SERR(ECONNRESET))) diff --git a/src/common/network/udp_socket.cpp b/src/common/network/udp_socket.cpp index 379ccbab..1f481bc6 100644 --- a/src/common/network/udp_socket.cpp +++ b/src/common/network/udp_socket.cpp @@ -1,4 +1,5 @@ #include "udp_socket.hpp" +#include namespace network { @@ -31,17 +32,17 @@ namespace network std::optional> udp_socket::receive() const { - char buffer[0x2000]; + std::array buffer{}; address source{}; auto len = source.get_max_size(); const auto result = - recvfrom(this->get_socket(), buffer, static_cast(sizeof(buffer)), 0, &source.get_addr(), &len); + recvfrom(this->get_socket(), buffer.data(), static_cast(buffer.size()), 0, &source.get_addr(), &len); if (result == SOCKET_ERROR) { return std::nullopt; } - return {{source, std::string(buffer, result)}}; + return {{source, std::string(buffer.data(), static_cast(result))}}; } } diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index 528965f5..bbef40df 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -1,5 +1,7 @@ #pragma once +// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + #define ACCESS_MASK DWORD #define DEVICE_TYPE DWORD @@ -408,3 +410,5 @@ typedef struct _REMOTE_PORT_VIEW64 EMULATOR_CAST(std::int64_t, SIZE_T) ViewSize; EmulatorTraits::PVOID ViewBase; } REMOTE_PORT_VIEW64, *PREMOTE_PORT_VIEW64; + +// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/common/platform/kernel_mapped.hpp b/src/common/platform/kernel_mapped.hpp index 2dae3215..83dd548e 100644 --- a/src/common/platform/kernel_mapped.hpp +++ b/src/common/platform/kernel_mapped.hpp @@ -2,6 +2,8 @@ #include +// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + #define PROCESSOR_FEATURE_MAX 64 #define GDI_HANDLE_BUFFER_SIZE64 60 #define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_RELEASE_ON_DEACTIVATION 0x00000001 @@ -388,10 +390,10 @@ typedef struct _GDI_TEB_BATCH64 #ifndef OS_WINDOWS typedef struct _GUID { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; } GUID; typedef struct _PROCESSOR_NUMBER @@ -913,3 +915,5 @@ struct PROCESS_TLS_INFO }; static_assert(sizeof(PROCESS_TLS_INFO) - sizeof(THREAD_TLS_INFO) == 0x10); + +// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/common/platform/memory.hpp b/src/common/platform/memory.hpp index 7d2dcbd0..13779235 100644 --- a/src/common/platform/memory.hpp +++ b/src/common/platform/memory.hpp @@ -1,5 +1,7 @@ #pragma once +// NOLINTBEGIN(modernize-use-using) + #define PAGE_EXECUTE 0x10 #define PAGE_EXECUTE_READ 0x20 #define PAGE_EXECUTE_READWRITE 0x40 @@ -127,3 +129,5 @@ typedef struct _MEMORY_REGION_INFORMATION DWORD64 PartitionId; // 19H1 DWORD64 NodePreference; // 20H1 } MEMORY_REGION_INFORMATION64, *PMEMORY_REGION_INFORMATION64; + +// NOLINTEND(modernize-use-using) diff --git a/src/common/platform/platform.hpp b/src/common/platform/platform.hpp index 91490952..f26dc677 100644 --- a/src/common/platform/platform.hpp +++ b/src/common/platform/platform.hpp @@ -4,7 +4,9 @@ #pragma warning(push) #pragma warning(disable : 4201) // nameless struct/union #pragma warning(disable : 4702) // unreachable code -#else +#endif + +#if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #endif @@ -24,8 +26,10 @@ #include "network.hpp" #include "threading.hpp" -#ifdef OS_WINDOWS -#pragma warning(pop) -#else +#if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif + +#ifdef OS_WINDOWS +#pragma warning(pop) +#endif diff --git a/src/common/platform/primitives.hpp b/src/common/platform/primitives.hpp index 9db43fb5..b30f7373 100644 --- a/src/common/platform/primitives.hpp +++ b/src/common/platform/primitives.hpp @@ -2,6 +2,8 @@ #include +// NOLINTBEGIN(modernize-use-using) + #ifdef OS_WINDOWS #define WIN32_LEAN_AND_MEAN @@ -51,10 +53,10 @@ using BYTE = std::uint8_t; using WORD = std::uint16_t; -#define UCHAR unsigned char +#define UCHAR uint8_t #define BOOLEAN UCHAR -using CSHORT = short; +using CSHORT = int16_t; using USHORT = WORD; #define DUMMYSTRUCTNAME @@ -63,3 +65,5 @@ using USHORT = WORD; #define TRUE 1 #define FALSE 0 #endif + +// NOLINTEND(modernize-use-using) diff --git a/src/common/platform/process.hpp b/src/common/platform/process.hpp index 8b989f65..88d4712c 100644 --- a/src/common/platform/process.hpp +++ b/src/common/platform/process.hpp @@ -1,5 +1,7 @@ #pragma once +// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + #define CONTEXT_X86_MAIN 0x00010000 #define CONTEXT_AMD64_MAIN 0x100000 #define CONTEXT_CONTROL_32 (CONTEXT_X86_MAIN | 0x1L) @@ -1005,3 +1007,5 @@ _Struct_size_bytes_(Size) struct EMU_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX64 EMU_GROUP_RELATIONSHIP64 Group; }; }; + +// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/common/platform/registry.hpp b/src/common/platform/registry.hpp index e2ec50cd..7f76d0ae 100644 --- a/src/common/platform/registry.hpp +++ b/src/common/platform/registry.hpp @@ -1,5 +1,7 @@ #pragma once +// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + typedef enum _KEY_INFORMATION_CLASS { KeyBasicInformation, // KEY_BASIC_INFORMATION @@ -77,3 +79,5 @@ struct KEY_VALUE_FULL_INFORMATION ULONG NameLength; char16_t Name[1]; }; + +// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/common/platform/synchronisation.hpp b/src/common/platform/synchronisation.hpp index a04037b0..bca5bf09 100644 --- a/src/common/platform/synchronisation.hpp +++ b/src/common/platform/synchronisation.hpp @@ -1,5 +1,7 @@ #pragma once +// NOLINTBEGIN(modernize-use-using) + typedef enum _EVENT_TYPE { NotificationEvent, @@ -14,3 +16,5 @@ typedef enum _WAIT_TYPE WaitDequeue, WaitDpc, } WAIT_TYPE; + +// NOLINTEND(modernize-use-using) diff --git a/src/common/platform/threading.hpp b/src/common/platform/threading.hpp index f3fe70fd..96e61816 100644 --- a/src/common/platform/threading.hpp +++ b/src/common/platform/threading.hpp @@ -1,5 +1,7 @@ #pragma once +// NOLINTBEGIN(modernize-use-using) + typedef enum _THREADINFOCLASS { ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION @@ -87,3 +89,5 @@ typedef struct _THREAD_TEB_INFORMATION ULONG TebOffset; // Offset in TEB to begin reading from. ULONG BytesToRead; // Number of bytes to read. } THREAD_TEB_INFORMATION, *PTHREAD_TEB_INFORMATION; + +// NOLINTEND(modernize-use-using) diff --git a/src/common/platform/unicode.hpp b/src/common/platform/unicode.hpp index e232958a..f76bac36 100644 --- a/src/common/platform/unicode.hpp +++ b/src/common/platform/unicode.hpp @@ -13,7 +13,7 @@ struct UNICODE_STRING inline std::u16string u8_to_u16(const std::string_view view) { - return std::u16string(view.begin(), view.end()); + return {view.begin(), view.end()}; } inline std::string u16_to_u8(const std::u16string_view u16_view) diff --git a/src/common/platform/win_pefile.hpp b/src/common/platform/win_pefile.hpp index 24acb4ab..d73222af 100644 --- a/src/common/platform/win_pefile.hpp +++ b/src/common/platform/win_pefile.hpp @@ -2,6 +2,8 @@ #include +// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory @@ -339,3 +341,5 @@ struct SECTION_IMAGE_INFORMATION ULONG ImageFileSize; ULONG CheckSum; }; + +// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/common/utils/compression.cpp b/src/common/utils/compression.cpp index acd710fb..aa4ab0be 100644 --- a/src/common/utils/compression.cpp +++ b/src/common/utils/compression.cpp @@ -1,6 +1,7 @@ #include "compression.hpp" #include +#include #include namespace utils::compression @@ -58,20 +59,20 @@ namespace utils::compression int ret{}; size_t offset = 0; - static thread_local uint8_t dest[ZCHUNK_SIZE] = {0}; + static thread_local std::array dest{}; auto& stream = stream_container.get(); do { - const auto input_size = std::min(sizeof(dest), data.size() - offset); + const auto input_size = std::min(dest.size(), data.size() - offset); stream.avail_in = static_cast(input_size); stream.next_in = reinterpret_cast(data.data()) + offset; offset += stream.avail_in; do { - stream.avail_out = sizeof(dest); - stream.next_out = dest; + stream.avail_out = static_cast(dest.size()); + stream.next_out = dest.data(); ret = inflate(&stream, Z_NO_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) @@ -79,7 +80,7 @@ namespace utils::compression return {}; } - buffer.insert(buffer.end(), dest, dest + sizeof(dest) - stream.avail_out); + buffer.insert(buffer.end(), dest.data(), dest.data() + dest.size() - stream.avail_out); } while (stream.avail_out == 0); } while (ret != Z_STREAM_END); @@ -102,4 +103,4 @@ namespace utils::compression return result; } } -} \ No newline at end of file +} diff --git a/src/common/utils/finally.hpp b/src/common/utils/finally.hpp index 65c74392..f4a68e44 100644 --- a/src/common/utils/finally.hpp +++ b/src/common/utils/finally.hpp @@ -13,7 +13,7 @@ namespace utils class final_action { public: - static_assert(!std::is_reference::value && !std::is_const::value && !std::is_volatile::value, + static_assert(!std::is_reference_v && !std::is_const_v && !std::is_volatile_v, "Final_action should store its callable by value"); explicit final_action(F f) noexcept @@ -33,14 +33,16 @@ namespace utils ~final_action() noexcept { - if (invoke_) - f_(); + if (this->invoke_) + { + this->f_(); + } } // Added by momo5502 void cancel() { - invoke_ = false; + this->invoke_ = false; } private: @@ -49,8 +51,8 @@ namespace utils }; template - final_action::type>::type> finally(F&& f) noexcept + final_action>> finally(F&& f) noexcept { - return final_action::type>::type>(std::forward(f)); + return final_action>>(std::forward(f)); } } diff --git a/src/common/utils/io.cpp b/src/common/utils/io.cpp index 06397a91..6c4899b5 100644 --- a/src/common/utils/io.cpp +++ b/src/common/utils/io.cpp @@ -51,12 +51,17 @@ namespace utils::io bool read_file(const std::filesystem::path& file, std::vector* data) { if (!data) + { return false; + } + data->clear(); std::ifstream stream(file, std::ios::binary); if (!stream) + { return false; + } *data = std::vector{(std::istreambuf_iterator(stream)), std::istreambuf_iterator()}; return true; @@ -108,14 +113,14 @@ namespace utils::io if (recursive) { - for (auto& file : std::filesystem::recursive_directory_iterator(directory, code)) + for (const auto& file : std::filesystem::recursive_directory_iterator(directory, code)) { files.push_back(file.path()); } } else { - for (auto& file : std::filesystem::directory_iterator(directory, code)) + for (const auto& file : std::filesystem::directory_iterator(directory, code)) { files.push_back(file.path()); } diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 401738b7..d52fb816 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -24,7 +24,7 @@ namespace utils::string inline wchar_t char_to_lower(const wchar_t val) { - return std::towlower(val); + return static_cast(std::towlower(val)); } template diff --git a/src/emulator/memory_permission.hpp b/src/emulator/memory_permission.hpp index 4c044563..00e7628b 100644 --- a/src/emulator/memory_permission.hpp +++ b/src/emulator/memory_permission.hpp @@ -15,22 +15,22 @@ enum class memory_permission : uint8_t * ****************************************************************************/ -inline constexpr memory_permission operator&(const memory_permission x, const memory_permission y) +constexpr memory_permission operator&(const memory_permission x, const memory_permission y) { return static_cast(static_cast(x) & static_cast(y)); } -inline constexpr memory_permission operator|(const memory_permission x, const memory_permission y) +constexpr memory_permission operator|(const memory_permission x, const memory_permission y) { return static_cast(static_cast(x) | static_cast(y)); } -inline constexpr memory_permission operator^(const memory_permission x, const memory_permission y) +constexpr memory_permission operator^(const memory_permission x, const memory_permission y) { return static_cast(static_cast(x) ^ static_cast(y)); } -inline constexpr memory_permission operator~(memory_permission x) +constexpr memory_permission operator~(memory_permission x) { return static_cast(~static_cast(x)); } diff --git a/src/emulator/serialization.hpp b/src/emulator/serialization.hpp index 4693ce3e..53fab16a 100644 --- a/src/emulator/serialization.hpp +++ b/src/emulator/serialization.hpp @@ -499,8 +499,8 @@ namespace utils std::optional get_diff(const buffer_serializer& other) const { - auto& b1 = this->get_buffer(); - auto& b2 = other.get_buffer(); + const auto& b1 = this->get_buffer(); + const auto& b2 = other.get_buffer(); const auto s1 = b1.size(); const auto s2 = b2.size(); diff --git a/src/fuzzer/CMakeLists.txt b/src/fuzzer/CMakeLists.txt index 8a7b600a..2ffc31a0 100644 --- a/src/fuzzer/CMakeLists.txt +++ b/src/fuzzer/CMakeLists.txt @@ -10,7 +10,9 @@ add_executable(fuzzer ${SRC_FILES}) momo_assign_source_group(${SRC_FILES}) -target_precompile_headers(fuzzer PRIVATE std_include.hpp) +if(NOT MOMO_ENABLE_CLANG_TIDY) + target_precompile_headers(fuzzer PRIVATE std_include.hpp) +endif() target_link_libraries(fuzzer PRIVATE fuzzing-engine diff --git a/src/fuzzer/std_include.hpp b/src/fuzzer/std_include.hpp index 43df7c99..9719ff6b 100644 --- a/src/fuzzer/std_include.hpp +++ b/src/fuzzer/std_include.hpp @@ -27,4 +27,5 @@ #include +// NOLINTNEXTLINE(google-global-names-in-headers) using namespace std::literals; diff --git a/src/gdb-stub/gdb_stub.cpp b/src/gdb-stub/gdb_stub.cpp index 81176e6a..5460fce2 100644 --- a/src/gdb-stub/gdb_stub.cpp +++ b/src/gdb-stub/gdb_stub.cpp @@ -64,7 +64,9 @@ namespace gdb_stub void send_xfer_data(connection_handler& connection, const std::string& args, const std::string_view data) { - size_t offset{}, length{}; + size_t offset{}; + size_t length{}; + rt_assert(sscanf_s(args.c_str(), "%zx,%zx", &offset, &length) == 2); if (offset >= data.size()) diff --git a/src/windows-emulator/CMakeLists.txt b/src/windows-emulator/CMakeLists.txt index a623de76..0da4f6e6 100644 --- a/src/windows-emulator/CMakeLists.txt +++ b/src/windows-emulator/CMakeLists.txt @@ -10,7 +10,9 @@ add_library(windows-emulator ${SRC_FILES}) momo_assign_source_group(${SRC_FILES}) -target_precompile_headers(windows-emulator PRIVATE std_include.hpp) +if(NOT MOMO_ENABLE_CLANG_TIDY) + target_precompile_headers(windows-emulator PRIVATE std_include.hpp) +endif() target_link_libraries(windows-emulator PRIVATE unicorn-emulator diff --git a/src/windows-emulator/apiset/apiset.cpp b/src/windows-emulator/apiset/apiset.cpp index 2031acae..6d6679b1 100644 --- a/src/windows-emulator/apiset/apiset.cpp +++ b/src/windows-emulator/apiset/apiset.cpp @@ -1,3 +1,5 @@ +#include "../std_include.hpp" + #include "apiset.hpp" #include "default_apiset.hpp" @@ -44,7 +46,10 @@ namespace apiset { auto buffer = utils::compression::zlib::decompress(apiset); if (buffer.empty()) + { throw std::runtime_error("Failed to decompress API-SET"); + } + return buffer; } @@ -66,7 +71,10 @@ namespace apiset case location::file: { const auto apiset = utils::io::read_file(root / "api-set.bin"); if (apiset.empty()) + { throw std::runtime_error("Failed to read file api-set.bin"); + } + return decompress_apiset(apiset); } case location::default_windows_10: { @@ -123,9 +131,9 @@ namespace apiset api_set.HashOffset = static_cast(hash_entries_obj.value() - api_set_map_obj.value()); }); - const auto orig_ns_entries = + const auto* orig_ns_entries = offset_pointer(&orig_api_set_map, orig_api_set_map.EntryOffset); - const auto orig_hash_entries = + const auto* orig_hash_entries = offset_pointer(&orig_api_set_map, orig_api_set_map.HashOffset); for (ULONG i = 0; i < orig_api_set_map.Count; ++i) @@ -142,7 +150,7 @@ namespace apiset } const auto values_obj = allocator.reserve(ns_entry.ValueCount); - const auto orig_values = offset_pointer(&orig_api_set_map, ns_entry.ValueOffset); + const auto* orig_values = offset_pointer(&orig_api_set_map, ns_entry.ValueOffset); ns_entry.ValueOffset = static_cast(values_obj.value() - api_set_map_obj.value()); diff --git a/src/windows-emulator/apiset/default_apiset.hpp b/src/windows-emulator/apiset/default_apiset.hpp index 8d86f98b..ebcaf38f 100644 --- a/src/windows-emulator/apiset/default_apiset.hpp +++ b/src/windows-emulator/apiset/default_apiset.hpp @@ -3,6 +3,8 @@ #include // Windows 11 - APISET-W11.24H2-26100.2605 + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) const uint8_t apiset_w11[] = { 0x78, 0xDA, 0xCD, 0x7D, 0x0F, 0x7C, 0xCD, 0xD5, 0xFF, 0xFF, 0x9D, 0x26, 0xCA, 0xD2, 0xAA, 0x29, 0xA2, 0x52, 0x11, 0x0A, 0x6D, 0xD7, 0xBF, 0x91, 0x24, 0xAD, 0xA2, 0x54, 0xF2, 0x2F, 0xB1, 0xD8, 0xFF, 0x3F, 0xDC, 0x6D, 0xD7, 0xBD, @@ -1369,6 +1371,8 @@ const uint8_t apiset_w11[] = { }; // Windows 10 - APISET-W10.22H2-19045.5247 + +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) const uint8_t apiset_w10[] = { 0x78, 0xDA, 0xCD, 0x7D, 0x0B, 0x5C, 0x94, 0x45, 0xF7, 0xFF, 0x62, 0x58, 0x98, 0x64, 0x64, 0x98, 0x9A, 0x98, 0x9A, 0x98, 0x5A, 0x6A, 0x88, 0x37, 0x2C, 0x53, 0xF2, 0x52, 0x5A, 0x54, 0xE6, 0x2D, 0x2F, 0xA4, 0xDC, 0x2F, 0xBA, 0x0B, diff --git a/src/windows-emulator/cpu_context.cpp b/src/windows-emulator/cpu_context.cpp index 5167bc46..3fd234ba 100644 --- a/src/windows-emulator/cpu_context.cpp +++ b/src/windows-emulator/cpu_context.cpp @@ -138,7 +138,7 @@ namespace cpu_context } } - if ((context.ContextFlags & CONTEXT_XSTATE_64) == CONTEXT_INTEGER_64) + if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64) { context.MxCsr = emu.reg(x64_register::mxcsr); for (int i = 0; i < 16; i++) diff --git a/src/windows-emulator/devices/afd_endpoint.cpp b/src/windows-emulator/devices/afd_endpoint.cpp index 33af053e..f2885659 100644 --- a/src/windows-emulator/devices/afd_endpoint.cpp +++ b/src/windows-emulator/devices/afd_endpoint.cpp @@ -1,3 +1,4 @@ +#include "../std_include.hpp" #include "afd_endpoint.hpp" #include "afd_types.hpp" @@ -11,6 +12,8 @@ namespace { + // NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + struct afd_creation_data { uint64_t unk1; @@ -45,6 +48,8 @@ namespace uint32_t sin6_scope_id; }; + // NOLINTEND(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + static_assert(sizeof(win_sockaddr) == 16); static_assert(sizeof(win_sockaddr_in) == 16); static_assert(sizeof(win_sockaddr_in6) == 28); @@ -77,7 +82,7 @@ namespace int16_t translate_host_to_win_address_family(const int host_af) { - for (auto& entry : address_family_map) + for (const auto& entry : address_family_map) { if (entry.second == host_af) { @@ -130,7 +135,7 @@ namespace win_addr.sin_port = htons(win_emu.get_emulator_port(a.get_port())); memcpy(&win_addr.sin_addr, &a.get_in_addr().sin_addr, sizeof(win_addr.sin_addr)); - const auto ptr = reinterpret_cast(&win_addr); + const auto* ptr = reinterpret_cast(&win_addr); return {ptr, ptr + sizeof(win_addr)}; } @@ -140,12 +145,12 @@ namespace win_addr.sin6_family = translate_host_to_win_address_family(a.get_family()); win_addr.sin6_port = htons(win_emu.get_emulator_port(a.get_port())); - auto& addr = a.get_in6_addr(); + const auto& addr = a.get_in6_addr(); memcpy(&win_addr.sin6_addr, &addr.sin6_addr, sizeof(win_addr.sin6_addr)); win_addr.sin6_flowinfo = addr.sin6_flowinfo; win_addr.sin6_scope_id = addr.sin6_scope_id; - const auto ptr = reinterpret_cast(&win_addr); + const auto* ptr = reinterpret_cast(&win_addr); return {ptr, ptr + sizeof(win_addr)}; } @@ -241,7 +246,7 @@ namespace handle_info.emplace_back(handle_info_obj.read(i)); } - return {std::move(poll_info), std::move(handle_info)}; + return {poll_info, std::move(handle_info)}; } int16_t map_afd_request_events_to_socket(const ULONG poll_events) @@ -317,7 +322,7 @@ namespace for (size_t i = 0; i < endpoints.size() && i < handles.size(); ++i) { auto& pfd = poll_data.at(i); - auto& handle = handles[i]; + const auto& handle = handles[i]; pfd.fd = endpoints[i]; pfd.events = map_afd_request_events_to_socket(handle.PollEvents); @@ -525,6 +530,11 @@ namespace NTSTATUS ioctl_bind(windows_emulator& win_emu, const io_device_context& c) const { + if (!this->s_) + { + throw std::runtime_error("Invalid AFD endpoint socket!"); + } + auto data = win_emu.emu().read_memory(c.input_buffer, c.input_buffer_length); constexpr auto address_offset = 4; @@ -561,9 +571,9 @@ namespace } const auto* endpoint = device->get_internal_device(); - if (!endpoint) + if (!endpoint || !endpoint->s_) { - throw std::runtime_error("Device is not an AFD endpoint!"); + throw std::runtime_error("Invalid AFD endpoint!"); } endpoints.push_back(*endpoint->s_); @@ -604,6 +614,11 @@ namespace NTSTATUS ioctl_receive_datagram(windows_emulator& win_emu, const io_device_context& c) { + if (!this->s_) + { + throw std::runtime_error("Invalid AFD endpoint socket!"); + } + auto& emu = win_emu.emu(); if (c.input_buffer_length < sizeof(AFD_RECV_DATAGRAM_INFO>)) @@ -668,6 +683,11 @@ namespace NTSTATUS ioctl_send_datagram(windows_emulator& win_emu, const io_device_context& c) { + if (!this->s_) + { + throw std::runtime_error("Invalid AFD endpoint socket!"); + } + const auto& emu = win_emu.emu(); if (c.input_buffer_length < sizeof(AFD_SEND_DATAGRAM_INFO>)) diff --git a/src/windows-emulator/devices/afd_types.hpp b/src/windows-emulator/devices/afd_types.hpp index dd0d106e..b05ed79e 100644 --- a/src/windows-emulator/devices/afd_types.hpp +++ b/src/windows-emulator/devices/afd_types.hpp @@ -2,6 +2,8 @@ #include "../std_include.hpp" +// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + typedef LONG TDI_STATUS; template @@ -171,3 +173,5 @@ struct AFD_POLL_INFO64 #define AFD_NO_OPERATION 39 #define AFD_VALIDATE_GROUP 40 #define AFD_GET_UNACCEPTED_CONNECT_DATA 41 + +// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/windows-emulator/devices/mount_point_manager.cpp b/src/windows-emulator/devices/mount_point_manager.cpp index 918ff081..c0f0f8b9 100644 --- a/src/windows-emulator/devices/mount_point_manager.cpp +++ b/src/windows-emulator/devices/mount_point_manager.cpp @@ -1,3 +1,4 @@ +#include "../std_include.hpp" #include "mount_point_manager.hpp" #include "../windows_emulator.hpp" diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index 2b3ca72c..d1fd7aec 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -1,3 +1,4 @@ +#include "std_include.hpp" #include "emulator_thread.hpp" #include "cpu_context.hpp" @@ -219,6 +220,11 @@ bool emulator_thread::is_thread_ready(process_context& process, utils::clock& cl void emulator_thread::setup_registers(x64_emulator& emu, const process_context& context) const { + if (!this->gs_segment) + { + throw std::runtime_error("Missing GS segment"); + } + setup_stack(emu, this->stack_base, this->stack_size); setup_gs_segment(emu, *this->gs_segment); diff --git a/src/windows-emulator/exception_dispatch.cpp b/src/windows-emulator/exception_dispatch.cpp index 1db01ee6..12a40452 100644 --- a/src/windows-emulator/exception_dispatch.cpp +++ b/src/windows-emulator/exception_dispatch.cpp @@ -1,9 +1,8 @@ +#include "std_include.hpp" #include "exception_dispatch.hpp" #include "process_context.hpp" #include "cpu_context.hpp" -#include - namespace { using exception_record = EMU_EXCEPTION_RECORD>; diff --git a/src/windows-emulator/file_system.hpp b/src/windows-emulator/file_system.hpp index ce2d33d0..e39fd320 100644 --- a/src/windows-emulator/file_system.hpp +++ b/src/windows-emulator/file_system.hpp @@ -43,8 +43,8 @@ class file_system } #endif - const char root_drive[2] = {win_path.get_drive().value_or('c'), 0}; - auto root = this->root_ / root_drive; + const std::array root_drive{win_path.get_drive().value_or('c'), 0}; + auto root = this->root_ / root_drive.data(); auto path = this->root_ / win_path.to_portable_path(); path = weakly_canonical(path); diff --git a/src/windows-emulator/io_device.cpp b/src/windows-emulator/io_device.cpp index e96329a0..93659d76 100644 --- a/src/windows-emulator/io_device.cpp +++ b/src/windows-emulator/io_device.cpp @@ -1,3 +1,4 @@ +#include "std_include.hpp" #include "io_device.hpp" #include "devices/afd_endpoint.hpp" #include "devices/mount_point_manager.hpp" diff --git a/src/windows-emulator/io_device.hpp b/src/windows-emulator/io_device.hpp index 43e8b1cf..b76ff6cc 100644 --- a/src/windows-emulator/io_device.hpp +++ b/src/windows-emulator/io_device.hpp @@ -151,7 +151,7 @@ class io_device_container : public io_device void work(windows_emulator& win_emu) override { this->assert_validity(); - return this->device_->work(win_emu); + this->device_->work(win_emu); } void serialize_object(utils::buffer_serializer& buffer) const override diff --git a/src/windows-emulator/kusd_mmio.cpp b/src/windows-emulator/kusd_mmio.cpp index 03fcd950..136ecbc7 100644 --- a/src/windows-emulator/kusd_mmio.cpp +++ b/src/windows-emulator/kusd_mmio.cpp @@ -1,3 +1,4 @@ +#include "std_include.hpp" #include "kusd_mmio.hpp" #include #include "windows_emulator.hpp" diff --git a/src/windows-emulator/logger.cpp b/src/windows-emulator/logger.cpp index 80c8247f..ea4dc2ee 100644 --- a/src/windows-emulator/logger.cpp +++ b/src/windows-emulator/logger.cpp @@ -73,17 +73,20 @@ namespace std::string_view format(va_list* ap, const char* message) { - thread_local char buffer[0x1000]; + thread_local std::array buffer{}; #ifdef _WIN32 - const int count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); + const int count = _vsnprintf_s(buffer.data(), buffer.size(), buffer.size(), message, *ap); #else - const int count = vsnprintf(buffer, sizeof(buffer), message, *ap); + const int count = vsnprintf(buffer.data(), buffer.size(), message, *ap); #endif if (count < 0) + { return {}; - return {buffer, static_cast(count)}; + } + + return {buffer.data(), static_cast(count)}; } #define format_to_string(msg, str) \ @@ -110,36 +113,42 @@ void logger::print(const color c, const std::string_view message) const print_colored(message, get_color_type(c)); } +// NOLINTNEXTLINE(cert-dcl50-cpp) void logger::print(const color c, const char* message, ...) const { format_to_string(message, data); this->print(c, data); } +// NOLINTNEXTLINE(cert-dcl50-cpp) void logger::info(const char* message, ...) const { format_to_string(message, data); this->print(color::cyan, data); } +// NOLINTNEXTLINE(cert-dcl50-cpp) void logger::warn(const char* message, ...) const { format_to_string(message, data); this->print(color::yellow, data); } +// NOLINTNEXTLINE(cert-dcl50-cpp) void logger::error(const char* message, ...) const { format_to_string(message, data); this->print(color::red, data); } +// NOLINTNEXTLINE(cert-dcl50-cpp) void logger::success(const char* message, ...) const { format_to_string(message, data); this->print(color::green, data); } +// NOLINTNEXTLINE(cert-dcl50-cpp) void logger::log(const char* message, ...) const { format_to_string(message, data); diff --git a/src/windows-emulator/memory_manager.cpp b/src/windows-emulator/memory_manager.cpp index 214cfaa2..a3f82563 100644 --- a/src/windows-emulator/memory_manager.cpp +++ b/src/windows-emulator/memory_manager.cpp @@ -1,3 +1,4 @@ +#include "std_include.hpp" #include "memory_manager.hpp" #include "memory_region.hpp" diff --git a/src/windows-emulator/module/mapped_module.hpp b/src/windows-emulator/module/mapped_module.hpp index b058a2b2..dfe2b268 100644 --- a/src/windows-emulator/module/mapped_module.hpp +++ b/src/windows-emulator/module/mapped_module.hpp @@ -41,7 +41,7 @@ struct mapped_module uint64_t find_export(const std::string_view export_name) const { - for (auto& symbol : this->exports) + for (const auto& symbol : this->exports) { if (symbol.name == export_name) { diff --git a/src/windows-emulator/module/module_mapping.cpp b/src/windows-emulator/module/module_mapping.cpp index a85f5ea0..17cc4857 100644 --- a/src/windows-emulator/module/module_mapping.cpp +++ b/src/windows-emulator/module/module_mapping.cpp @@ -9,11 +9,11 @@ namespace { uint64_t get_first_section_offset(const PENTHeaders_t& nt_headers, const uint64_t nt_headers_offset) { - const uint8_t* nt_headers_addr = reinterpret_cast(&nt_headers); + const auto* nt_headers_addr = reinterpret_cast(&nt_headers); size_t optional_header_offset = reinterpret_cast(&(nt_headers.OptionalHeader)) - reinterpret_cast(&nt_headers); size_t optional_header_size = nt_headers.FileHeader.SizeOfOptionalHeader; - const uint8_t* first_section_addr = nt_headers_addr + optional_header_offset + optional_header_size; + const auto* first_section_addr = nt_headers_addr + optional_header_offset + optional_header_size; const auto first_section_absolute = reinterpret_cast(first_section_addr); const auto absolute_base = reinterpret_cast(&nt_headers); @@ -32,7 +32,7 @@ namespace void collect_exports(mapped_module& binary, const utils::safe_buffer_accessor buffer, const PEOptionalHeader_t& optional_header) { - auto& export_directory_entry = optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + const auto& export_directory_entry = optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; if (export_directory_entry.VirtualAddress == 0 || export_directory_entry.Size == 0) { return; @@ -88,7 +88,7 @@ namespace return; } - const auto directory = &optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + const auto* directory = &optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; if (directory->Size == 0) { return; @@ -209,7 +209,7 @@ mapped_module map_module_from_data(memory_manager& memory, const std::span>(nt_headers_offset).get(); - auto& optional_header = nt_headers.OptionalHeader; + const auto& optional_header = nt_headers.OptionalHeader; if (nt_headers.FileHeader.Machine != PEMachineType::AMD64) { diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index 1ce0a315..947543bb 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -1,3 +1,4 @@ +#include "std_include.hpp" #include "process_context.hpp" #include "emulator_utils.hpp" @@ -15,6 +16,7 @@ namespace void setup_gdt(x64_emulator& emu, memory_manager& memory) { + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) constexpr uint64_t gdtr[4] = {0, GDT_ADDR, GDT_LIMIT, 0}; emu.write_register(x64_register::gdtr, &gdtr, sizeof(gdtr)); memory.allocate_memory(GDT_ADDR, GDT_LIMIT, memory_permission::read); diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index e0ae016b..2118c59c 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -50,8 +50,7 @@ struct process_context void setup(x64_emulator& emu, memory_manager& memory, const application_settings& app_settings, const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container); - handle create_thread(memory_manager& memory, const uint64_t start_address, const uint64_t argument, - const uint64_t stack_size); + handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size); void serialize(utils::buffer_serializer& buffer) const; void deserialize(utils::buffer_deserializer& buffer); diff --git a/src/windows-emulator/registry/hive_parser.cpp b/src/windows-emulator/registry/hive_parser.cpp index 68ecb9a3..c6892433 100644 --- a/src/windows-emulator/registry/hive_parser.cpp +++ b/src/windows-emulator/registry/hive_parser.cpp @@ -1,3 +1,4 @@ +#include "../std_include.hpp" #include "hive_parser.hpp" #include @@ -8,6 +9,8 @@ namespace constexpr uint64_t MAIN_ROOT_OFFSET = 0x1000; constexpr uint64_t MAIN_KEY_BLOCK_OFFSET = MAIN_ROOT_OFFSET + 0x20; + // NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + struct offset_entry_t { int32_t offset; @@ -52,6 +55,8 @@ namespace char name[255]; }; + // NOLINTEND(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + bool read_file_data_safe(std::ifstream& file, const uint64_t offset, void* buffer, const size_t size) { if (file.bad()) @@ -170,7 +175,7 @@ void hive_key::parse(std::ifstream& file) const auto offset = read_file_object(file, MAIN_ROOT_OFFSET + this->value_offsets_ + 4, i); const auto value = read_file_object(file, MAIN_ROOT_OFFSET + offset); - std::string value_name(value.name, std::min(value.name_len, static_cast(sizeof(value.name)))); + std::string value_name(value.name, std::min(value.name_len, static_cast(sizeof(value.name)))); raw_hive_value raw_value{}; raw_value.parsed = false; @@ -199,7 +204,7 @@ void hive_key::parse(std::ifstream& file) const auto entry_offsets = this->subkey_block_offset_ + offsetof(offsets_t, entries); - for (short i = 0; i < item.count; ++i) + for (int16_t i = 0; i < item.count; ++i) { const auto offset_entry = read_file_object(file, MAIN_ROOT_OFFSET + entry_offsets, i); diff --git a/src/windows-emulator/registry/hive_parser.hpp b/src/windows-emulator/registry/hive_parser.hpp index 249fb0f8..3677f821 100644 --- a/src/windows-emulator/registry/hive_parser.hpp +++ b/src/windows-emulator/registry/hive_parser.hpp @@ -42,7 +42,7 @@ class hive_key return &entry->second; } - const hive_value* get_value(std::ifstream& file, const std::string_view name); + const hive_value* get_value(std::ifstream& file, std::string_view name); private: struct raw_hive_value : hive_value diff --git a/src/windows-emulator/registry/registry_manager.cpp b/src/windows-emulator/registry/registry_manager.cpp index 7f64b1d1..9a822569 100644 --- a/src/windows-emulator/registry/registry_manager.cpp +++ b/src/windows-emulator/registry/registry_manager.cpp @@ -1,3 +1,4 @@ +#include "../std_include.hpp" #include "registry_manager.hpp" #include @@ -104,7 +105,7 @@ std::optional registry_manager::get_key(const utils::path_key& key return {std::move(reg_key)}; } - const auto entry = iterator->second->get_sub_key(reg_key.path.get()); + const auto* entry = iterator->second->get_sub_key(reg_key.path.get()); if (!entry) { return std::nullopt; @@ -123,7 +124,7 @@ std::optional registry_manager::get_value(const registry_key& ke return std::nullopt; } - auto* entry = iterator->second->get_value(key.path.get(), name); + const auto* entry = iterator->second->get_value(key.path.get(), name); if (!entry) { return std::nullopt; diff --git a/src/windows-emulator/std_include.hpp b/src/windows-emulator/std_include.hpp index 4a6c82b2..05cf0d0b 100644 --- a/src/windows-emulator/std_include.hpp +++ b/src/windows-emulator/std_include.hpp @@ -62,4 +62,5 @@ #include "platform/platform.hpp" +// NOLINTNEXTLINE(google-global-names-in-headers) using namespace std::literals; diff --git a/src/windows-emulator/syscall_dispatcher.cpp b/src/windows-emulator/syscall_dispatcher.cpp index 6b7c3c15..d93bcc7b 100644 --- a/src/windows-emulator/syscall_dispatcher.cpp +++ b/src/windows-emulator/syscall_dispatcher.cpp @@ -1,3 +1,4 @@ +#include "std_include.hpp" #include "syscall_dispatcher.hpp" #include "syscall_utils.hpp" diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index b2d0b71a..5bf51007 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -375,7 +375,7 @@ namespace NTSTATUS handle_NtSetEvent(const syscall_context& c, const uint64_t handle, const emulator_object previous_state) { - const auto entry = c.proc.events.get(handle); + auto* entry = c.proc.events.get(handle); if (!entry) { return STATUS_INVALID_HANDLE; @@ -427,7 +427,7 @@ namespace if (h.value.type == handle_types::thread) { - const auto t = c.proc.threads.get(h); + const auto* t = c.proc.threads.get(h); if (t == c.proc.active_thread && t->ref_count == 1) { // TODO: Better handle ref counting @@ -750,7 +750,7 @@ namespace return STATUS_SUCCESS; } - const auto section_entry = c.proc.sections.get(section_handle); + auto* section_entry = c.proc.sections.get(section_handle); if (!section_entry) { return STATUS_INVALID_HANDLE; @@ -758,7 +758,7 @@ namespace if (section_entry->is_image()) { - const auto binary = c.win_emu.mod_manager.map_module(section_entry->file_name, c.win_emu.log); + const auto* binary = c.win_emu.mod_manager.map_module(section_entry->file_name, c.win_emu.log); if (!binary) { return STATUS_FILE_INVALID; @@ -855,14 +855,14 @@ namespace const auto region_info = c.win_emu.memory.get_region_info(base_address); assert(!region_info.is_committed || region_info.is_reserved); - + const auto state = region_info.is_reserved ? MEM_RESERVE : MEM_FREE; + image_info.State = region_info.is_committed ? MEM_COMMIT : state; image_info.BaseAddress = reinterpret_cast(region_info.start); image_info.AllocationBase = reinterpret_cast(region_info.allocation_base); image_info.AllocationProtect = 0; image_info.PartitionId = 0; image_info.RegionSize = static_cast(region_info.length); - image_info.State = - region_info.is_committed ? MEM_COMMIT : (region_info.is_reserved ? MEM_RESERVE : MEM_FREE); + image_info.Protect = map_emulator_to_nt_protection(region_info.permissions); image_info.Type = MEM_PRIVATE; }); @@ -882,7 +882,7 @@ namespace return STATUS_BUFFER_OVERFLOW; } - const auto mod = c.win_emu.mod_manager.find_by_address(base_address); + const auto* mod = c.win_emu.mod_manager.find_by_address(base_address); if (!mod) { c.win_emu.log.error("Bad address for memory image request: 0x%" PRIx64 "\n", base_address); @@ -893,7 +893,7 @@ namespace info.access([&](MEMORY_IMAGE_INFORMATION64& image_info) { image_info.ImageBase = reinterpret_cast(mod->image_base); - image_info.SizeOfImage = mod->size_of_image; + image_info.SizeOfImage = static_cast(mod->size_of_image); image_info.ImageFlags = 0; }); @@ -1998,11 +1998,11 @@ namespace thread_iterator->second.teb->access([&](TEB64& teb) { entry.ThreadId = teb.ClientId.UniqueThread; - const auto tls_vector = teb.ThreadLocalStoragePointer; + auto* tls_vector = teb.ThreadLocalStoragePointer; if (tls_info.TlsRequest == ProcessTlsReplaceIndex) { - const auto tls_entry_ptr = tls_vector + tls_info.TlsIndex; + auto* tls_entry_ptr = tls_vector + tls_info.TlsIndex; const auto old_entry = c.emu.read_memory::PVOID>(tls_entry_ptr); c.emu.write_memory::PVOID>(tls_entry_ptr, entry.TlsModulePointer); @@ -2011,11 +2011,11 @@ namespace } else if (tls_info.TlsRequest == ProcessTlsReplaceVector) { - const auto new_tls_vector = entry.TlsVector; + auto* new_tls_vector = entry.TlsVector; for (uint32_t index = 0; index < tls_info.TlsVectorLength; ++index) { - const auto old_entry = c.emu.read_memory(tls_vector + index); + auto* old_entry = c.emu.read_memory(tls_vector + index); c.emu.write_memory(new_tls_vector + index, old_entry); } @@ -2270,7 +2270,7 @@ namespace const auto attributes = object_attributes.read(); if (attributes.ObjectName) { - const auto name = read_unicode_string( + auto name = read_unicode_string( c.emu, reinterpret_cast>*>(attributes.ObjectName)); c.win_emu.log.print(color::dark_gray, "--> Section with name %s\n", u16_to_u8(name).c_str()); s.name = std::move(name); @@ -2510,6 +2510,7 @@ namespace return STATUS_NOT_SUPPORTED; } + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) const uint8_t sid[] = { 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00, 0x84, 0x94, 0xD4, 0x04, 0x4B, 0x68, 0x42, 0x34, 0x23, 0xBE, 0x69, 0x4E, 0xE9, 0x03, 0x00, 0x00, @@ -3229,7 +3230,7 @@ namespace return STATUS_NOT_SUPPORTED; } - const auto file = c.proc.files.get(handle); + const auto* file = c.proc.files.get(handle); if (!file) { return STATUS_INVALID_HANDLE; diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 9d75ef33..0a58c31a 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -292,7 +292,7 @@ void windows_emulator::perform_thread_switch() bool windows_emulator::activate_thread(const uint32_t id) { - const auto thread = get_thread_by_id(this->process, id); + auto* thread = get_thread_by_id(this->process, id); if (!thread) { return false; @@ -576,6 +576,7 @@ void windows_emulator::deserialize(utils::buffer_deserializer& buffer) this->dispatcher.deserialize(buffer); } +// NOLINTNEXTLINE(readability-convert-member-functions-to-static) void windows_emulator::save_snapshot() { throw std::runtime_error("Not supported"); @@ -591,6 +592,7 @@ void windows_emulator::save_snapshot() // this->process_snapshot_ = this->process;*/ } +// NOLINTNEXTLINE(readability-convert-member-functions-to-static) void windows_emulator::restore_snapshot() { throw std::runtime_error("Not supported"); diff --git a/src/windows-emulator/windows_path.hpp b/src/windows-emulator/windows_path.hpp index d909aae3..8429c102 100644 --- a/src/windows-emulator/windows_path.hpp +++ b/src/windows-emulator/windows_path.hpp @@ -163,7 +163,7 @@ class windows_path throw std::runtime_error("Device path can not be computed for relative paths!"); } - const auto drive_index = *this->drive_ - 'a'; + const auto drive_index = this->drive_.value_or('a') - 'a'; const auto drive_number = std::to_string(drive_index + 1); const std::u16string number(drive_number.begin(), drive_number.end());