Skip to content

Commit

Permalink
* Remove redundant string_to_utf8() code
Browse files Browse the repository at this point in the history
* Place tests into another project
  • Loading branch information
BullyWiiPlaza committed Jun 26, 2021
1 parent 551e442 commit 0c84a1a
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,4 @@ ASALocalRun/
healthchecksdb
*.json

/Test Files
/DLL-Dependencies-Parser-Tests/Test Files
151 changes: 151 additions & 0 deletions DLL-Dependencies-Parser-Tests/DLL-Dependencies-Parser-Tests.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{28291861-3341-4a30-80d9-8a6843b3a86c}</ProjectGuid>
<RootNamespace>DLLDependenciesParserTests</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\CorrectCasingUtils.cpp" />
<ClCompile Include="..\DLLReferencesResolver.cpp" />
<ClCompile Include="Main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\DLLReferencesResolver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\CorrectCasingUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
#include <CLI/CLI.hpp>
#include <spdlog/spdlog.h>
#include "DLLReferencesResolver.hpp"

inline std::string bool_to_string(const bool value)
{
return value ? "true" : "false";
}

#define COMPILE_TESTS true

#if COMPILE_TESTS

#define BOOST_TEST_MODULE DLL References Resolver
#include <boost/test/included/unit_test.hpp>

#include "../DLLReferencesResolver.hpp"
#include <filesystem>

std::filesystem::path test_files_directory = "Test Files";

BOOST_AUTO_TEST_CASE(test_utf8_file_path)
Expand Down Expand Up @@ -46,13 +36,13 @@ BOOST_AUTO_TEST_CASE(test_parsing_with_system_libraries)
references_resolver.executable_file_path = test_files_directory / "Bot-Utilities.exe";
references_resolver.executable_file_path = absolute(references_resolver.executable_file_path);
references_resolver.skip_parsing_windows_dll_dependencies = false;

const auto [dll_load_failures, missing_dlls, referenced_dlls] = references_resolver.resolve_references();
BOOST_REQUIRE(dll_load_failures.size() == 1);
BOOST_REQUIRE(missing_dlls.size() == 11);
BOOST_REQUIRE(referenced_dlls.size() == 42);

// Make sure running this again yields the same results
// Make sure running this again yields the same results
const auto [dll_load_failures_2, missing_dlls_2, referenced_dlls_2] = references_resolver.resolve_references();
BOOST_REQUIRE(dll_load_failures_2.size() == 1);
BOOST_REQUIRE(missing_dlls_2.size() == 11);
Expand All @@ -69,53 +59,4 @@ BOOST_AUTO_TEST_CASE(test_jduel_links_bot_hooks_parsing)
BOOST_REQUIRE(dll_load_failures.empty());
BOOST_REQUIRE(missing_dlls.empty());
BOOST_REQUIRE(referenced_dlls.size() == 3);
}

#else

// TODO Boost Tests in a new project?
// TODO https://docs.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8?view=msvc-160 ?
int main(const int argument_count, char* arguments[])
{
try
{
#if _DEBUG
spdlog::set_level(spdlog::level::level_enum::debug);
#endif

spdlog::info("Referenced DLL Parser (C) 2021 BullyWiiPlaza Productions");

CLI::App application{"Referenced DLL Parser"};

std::filesystem::path executable_file_path;
application.add_option("--pe-file-path", executable_file_path, "The file path to the executable to analyze")
->required()
->check(CLI::ExistingFile);
auto skip_parsing_windows_dll_dependencies = default_skip_parsing_windows_dll_dependencies;
application.add_flag("--skip-parsing-windows-dll-dependencies", skip_parsing_windows_dll_dependencies, "Whether Windows DLLs will not be parsed to speed up analysis");
std::filesystem::path results_output_file_path;
application.add_option("--results-output-file-path", results_output_file_path, "The output file to write the results to");

CLI11_PARSE(application, argument_count, arguments)

spdlog::info("Executable file path: " + executable_file_path.string());
spdlog::info("Skip parsing Windows DLL dependencies: " + bool_to_string(skip_parsing_windows_dll_dependencies));
results_output_file_path = absolute(results_output_file_path);
spdlog::info("Results output file path: " + results_output_file_path.string());

dll_references_resolver references_resolver;
references_resolver.executable_file_path = executable_file_path;
references_resolver.skip_parsing_windows_dll_dependencies = skip_parsing_windows_dll_dependencies;
references_resolver.results_output_file_path = results_output_file_path;
references_resolver.resolve_references();

return EXIT_SUCCESS;
}
catch (std::exception &exception)
{
spdlog::error(exception.what());
return EXIT_FAILURE;
}
}

#endif
}
26 changes: 3 additions & 23 deletions DLLReferencesResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,26 +126,6 @@ inline auto write_to_file(const std::string& file_contents, const std::filesyste
file_writer << file_contents;
}

// https://stackoverflow.com/a/21575607/3764804
// Required due to "[json.exception.type_error.316] invalid UTF-8 byte at index"
inline auto string_to_utf8(const std::string& string)
{
const auto size = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, string.c_str(),
static_cast<int>(string.length()), nullptr, 0);
std::wstring utf16_string(size, '\0');
MultiByteToWideChar(CP_ACP, MB_COMPOSITE, string.c_str(),
static_cast<int>(string.length()), &utf16_string.at(0), size);

const auto utf8_size = WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(),
static_cast<int>(utf16_string.length()), nullptr, 0,
nullptr, nullptr);
std::string utf8_string(utf8_size, '\0');
WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(),
static_cast<int>(utf8_string.length()), &utf8_string.at(0), utf8_size,
nullptr, nullptr);
return utf8_string;
}

resolved_dll_dependencies dll_references_resolver::resolve_references()
{
parsed_module_file_paths_.clear();
Expand Down Expand Up @@ -228,7 +208,7 @@ resolved_dll_dependencies dll_references_resolver::resolve_references()
std::vector<std::string> missing_dlls_vector;
for (const auto& missing_dlls_file_name : missing_dlls_file_names)
{
const auto missing_dll_file_path = string_to_utf8(replace_user_profile_with_environment_variable(missing_dlls_file_name).string());
const auto missing_dll_file_path = replace_user_profile_with_environment_variable(missing_dlls_file_name).string();
missing_dlls_json.push_back(missing_dll_file_path);
missing_dlls_vector.push_back(missing_dll_file_path);
}
Expand All @@ -238,7 +218,7 @@ resolved_dll_dependencies dll_references_resolver::resolve_references()
std::vector<std::string> dll_load_failures_vector;
for (const auto& dll_load_failure : dll_load_failures)
{
const auto dll_load_failure_file_path = string_to_utf8(replace_user_profile_with_environment_variable(dll_load_failure).string());
const auto dll_load_failure_file_path = replace_user_profile_with_environment_variable(dll_load_failure).string();
dll_load_failures_json.push_back(dll_load_failure_file_path);
dll_load_failures_vector.push_back(dll_load_failure_file_path);
}
Expand All @@ -250,7 +230,7 @@ resolved_dll_dependencies dll_references_resolver::resolve_references()
module_file_paths.erase(executable_file_path);
for (const auto& module_file_path : module_file_paths)
{
const auto module_file_path_utf8 = string_to_utf8(replace_user_profile_with_environment_variable(module_file_path).string());
const auto module_file_path_utf8 = replace_user_profile_with_environment_variable(module_file_path).string();
referenced_dlls_json.push_back(module_file_path_utf8);
referenced_dlls_vector.push_back(module_file_path_utf8);
}
Expand Down
51 changes: 51 additions & 0 deletions Main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <CLI/CLI.hpp>
#include <spdlog/spdlog.h>
#include "DLLReferencesResolver.hpp"

inline std::string bool_to_string(const bool value)
{
return value ? "true" : "false";
}

int main(const int argument_count, char* arguments[])
{
try
{
#if _DEBUG
spdlog::set_level(spdlog::level::level_enum::debug);
#endif

spdlog::info("Referenced DLL Parser (C) 2021 BullyWiiPlaza Productions");

CLI::App application{"Referenced DLL Parser"};

std::filesystem::path executable_file_path;
application.add_option("--pe-file-path", executable_file_path, "The file path to the executable to analyze")
->required()
->check(CLI::ExistingFile);
auto skip_parsing_windows_dll_dependencies = default_skip_parsing_windows_dll_dependencies;
application.add_flag("--skip-parsing-windows-dll-dependencies", skip_parsing_windows_dll_dependencies, "Whether Windows DLLs will not be parsed to speed up analysis");
std::filesystem::path results_output_file_path;
application.add_option("--results-output-file-path", results_output_file_path, "The output file to write the results to");

CLI11_PARSE(application, argument_count, arguments)

spdlog::info("Executable file path: " + executable_file_path.string());
spdlog::info("Skip parsing Windows DLL dependencies: " + bool_to_string(skip_parsing_windows_dll_dependencies));
results_output_file_path = absolute(results_output_file_path);
spdlog::info("Results output file path: " + results_output_file_path.string());

dll_references_resolver references_resolver;
references_resolver.executable_file_path = executable_file_path;
references_resolver.skip_parsing_windows_dll_dependencies = skip_parsing_windows_dll_dependencies;
references_resolver.results_output_file_path = results_output_file_path;
references_resolver.resolve_references();

return EXIT_SUCCESS;
}
catch (std::exception &exception)
{
spdlog::error(exception.what());
return EXIT_FAILURE;
}
}
Loading

0 comments on commit 0c84a1a

Please sign in to comment.