From a9b580334fa85e7b023e5309d514badcaa723e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luiz=20Kr=C3=BCger?= <46863600+itisluiz@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:26:19 -0300 Subject: [PATCH] .def creation support Allows the use of the -d (--def) switch for generating a module definition file instead of a proxy header, along with many other tweaks: - Files now default to being generated with the same name as the input DLL instead of 'dllforward', along with the proper extension. - Show the current filename in the usage / help prompt. - Changes the format with which the export comments are generated in the header files, now displaying the ordinal, export name, and demangled export name. - Some other tiny formatting changes. - Added icon resource file configured to add icons to the output binaries when built. --- CMakeLists.txt | 9 +- include/builder.hh | 3 +- include/forwarder.hh | 3 +- .../bottom.inl | 0 .../top.inl | 2 +- include/parser.hh | 1 + res/app.ico | Bin 0 -> 101562 bytes res/app.rc | 1 + src/builder.cc | 26 ++++- src/forwarder.cc | 35 ++++++- src/main.cc | 99 ++++++++++-------- src/parser.cc | 18 +++- 12 files changed, 138 insertions(+), 59 deletions(-) rename include/{boilerplate => headerboilerplate}/bottom.inl (100%) rename include/{boilerplate => headerboilerplate}/top.inl (87%) create mode 100644 res/app.ico create mode 100644 res/app.rc diff --git a/CMakeLists.txt b/CMakeLists.txt index e094757..5fd02dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.21) -project("dllforward" VERSION 1.0 LANGUAGES CXX) +project("dllforward" VERSION 1.1 LANGUAGES CXX) ## QoL definitions add_compile_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}" -DBUILD_SHARED_LIBS=$) @@ -22,8 +22,11 @@ file(GLOB_RECURSE PROJECT_SOURCES "src/*.cpp" "src/*.cxx" "src/*.cc") list(FILTER PROJECT_SOURCES EXCLUDE REGEX "src/main.cc$") target_sources(${PROJECT_BASE} INTERFACE ${PROJECT_SOURCES}) +## Project's resource files +set(PROJECT_RESOURCES "res/app.rc" "res/app.ico") + ## Project output, end-product set(PROJECT_TARGET ${PROJECT_NAME}) -# add_library(${PROJECT_TARGET} "src/main.cc") -add_executable(${PROJECT_TARGET} "src/main.cc") +# add_library(${PROJECT_TARGET} "src/main.cc" ${PROJECT_RESOURCES}) +add_executable(${PROJECT_TARGET} "src/main.cc" ${PROJECT_RESOURCES}) target_link_libraries(${PROJECT_TARGET} PUBLIC ${PROJECT_BASE}) diff --git a/include/builder.hh b/include/builder.hh index 7f30847..9207115 100644 --- a/include/builder.hh +++ b/include/builder.hh @@ -4,4 +4,5 @@ namespace fs = std::filesystem; -void buildResult(const fs::path& dllPath, const fs::path& outFile, Architecture architecture, const std::vector& exports); +void buildResultHeader(const fs::path& dllPath, const fs::path& outFile, Architecture architecture, const std::vector& exports); +void buildResultDefinition(const fs::path& dllPath, const fs::path& outFile, const std::vector& exports); diff --git a/include/forwarder.hh b/include/forwarder.hh index cb24e78..c2f1d54 100644 --- a/include/forwarder.hh +++ b/include/forwarder.hh @@ -3,4 +3,5 @@ namespace fs = std::filesystem; -bool makeProxy(const fs::path& dllPath, const fs::path& outFile); +bool makeHeader(const fs::path& dllPath, const fs::path& outFile); +bool makeDefinition(const fs::path& dllPath, const fs::path& outFile); diff --git a/include/boilerplate/bottom.inl b/include/headerboilerplate/bottom.inl similarity index 100% rename from include/boilerplate/bottom.inl rename to include/headerboilerplate/bottom.inl diff --git a/include/boilerplate/top.inl b/include/headerboilerplate/top.inl similarity index 87% rename from include/boilerplate/top.inl rename to include/headerboilerplate/top.inl index e40d85e..43baebc 100644 --- a/include/boilerplate/top.inl +++ b/include/headerboilerplate/top.inl @@ -1,4 +1,4 @@ -"// DLL Forward by itisluiz v" PROJECT_VERSION R"( +"// DLLForward by itisluiz v" PROJECT_VERSION R"( #pragma once #include #include diff --git a/include/parser.hh b/include/parser.hh index 2357d4a..5d1e943 100644 --- a/include/parser.hh +++ b/include/parser.hh @@ -28,3 +28,4 @@ public: Architecture parseArchitecture(const fs::path& path); std::vector parseExports(const fs::path& path); +std::string parseMangled(const std::string& mangledName); diff --git a/res/app.ico b/res/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..0fa35f67c232830a995804daec50556370b45fb1 GIT binary patch literal 101562 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 c=c?kbb5-%zxvKc& exports) +void buildResultHeader(const fs::path& dllPath, const fs::path& outFile, Architecture architecture, const std::vector& exports) { std::ofstream file(outFile); file.exceptions(std::ifstream::failbit | std::ifstream::badbit); file << -#include +#include << '\n'; file << "// Proxy header generated for " << dllPath.filename().string() << " (" << (architecture == Architecture::kI386 ? "32" : "64") << " bit)" "\n"; @@ -23,7 +23,7 @@ void buildResult(const fs::path& dllPath, const fs::path& outFile, Architecture for (const Export& exportEntry : exports) { - file << "// " << exportEntry << '\n'; + file << "// #" << exportEntry.ordinal << ": " << exportEntry.name << " (" << parseMangled(exportEntry.name) << ")" "\n"; file << BUILD_EXPORT_DUMMY(exportEntry.name, exportEntry.ordinal); } @@ -38,7 +38,25 @@ void buildResult(const fs::path& dllPath, const fs::path& outFile, Architecture file << " };\n"; file << "}\n" -#include +#include ; } + +void buildResultDefinition(const fs::path& dllPath, const fs::path& outFile, const std::vector& exports) +{ + std::ofstream file(outFile); + file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + file << "; DLLForward by itisluiz v" PROJECT_VERSION << '\n'; + + file << "LIBRARY " << dllPath.filename().replace_extension().string() << '\n'; + file << "EXPORTS"; + + for (const Export& exportEntry : exports) + { + file << "\n" ";\t#" << exportEntry.ordinal << ": " << parseMangled(exportEntry.name) << '\n'; + file << '\t' << exportEntry.name << '\n'; + } + +} diff --git a/src/forwarder.cc b/src/forwarder.cc index 3fe4542..c254d66 100644 --- a/src/forwarder.cc +++ b/src/forwarder.cc @@ -4,7 +4,7 @@ #include #include -bool makeProxy(const fs::path& dllPath, const fs::path& outFile) +bool makeHeader(const fs::path& dllPath, const fs::path& outFile) { try { @@ -25,7 +25,7 @@ bool makeProxy(const fs::path& dllPath, const fs::path& outFile) std::cout << '\t' << exportEntry << '\n'; } - buildResult(dllPath, outFile, architecture, exports); + buildResultHeader(dllPath, outFile, architecture, exports); std::cout << "Generated output at \"" << fs::absolute(outFile).string() << "\"" "\n"; } catch (const std::system_error& e) @@ -41,3 +41,34 @@ bool makeProxy(const fs::path& dllPath, const fs::path& outFile) return true; } + +bool makeDefinition(const fs::path& dllPath, const fs::path& outFile) +{ + try + { + std::vector exports{ parseExports(dllPath) }; + + std::cout << "There are " << exports.size() << " exports:" "\n"; + + for (size_t hint{ 0 }; hint < exports.size(); ++hint) + { + const Export& exportEntry{ exports[hint] }; + std::cout << '\t' << exportEntry << '\n'; + } + + buildResultDefinition(dllPath, outFile, exports); + std::cout << "Generated output at \"" << fs::absolute(outFile).string() << "\"" "\n"; + } + catch (const std::system_error& e) + { + std::cerr << e.what() << " [" << e.code() << "]" "\n"; + return false; + } + catch (const std::runtime_error& e) + { + std::cerr << e.what() << '\n'; + return false; + } + + return true; +} diff --git a/src/main.cc b/src/main.cc index 5e2479d..e23a61d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -7,63 +7,70 @@ namespace fs = std::filesystem; struct ExitCodes { - enum - { - kSuccess = 0, - kFailed = 1, - kBadArgs = 2 - }; + enum + { + kSuccess = 0, + kFailed = 1, + kBadArgs = 2 + }; }; int main(int argc, char* argv[]) { - cxxopts::Options options("DLLForward", "Generate files for creating a DLL Proxy (Man in the middle) to any other DLL."); + cxxopts::Options options(fs::path(argv[0]).filename().string(), "Generate files for creating a DLL Proxy (Man in the middle) to any other DLL."); - options.add_options() - ("i,input", "Input DLL path", cxxopts::value(), "The DLL that will be proxied, be mindful of the DLL's architecture/bitness.") - ("o,output", "Output header file path", cxxopts::value()->default_value("./"), "Output path of the resulting header file used to build the proxy DLL.") - ("h,help", "Print usage"); + options.add_options() + ("i,input", "Input DLL path", cxxopts::value(), "The DLL that will be proxied, be mindful of the DLL's architecture/bitness.") + ("o,output", "Output header file path", cxxopts::value()->default_value("./"), "Output path of the resulting file generated from the input DLL.") + ("d,def", "Create a module definition (.def file) instead of a header for proxying.") + ("h,help", "Print usage"); - options.parse_positional({ "input", "output" }); - options.positional_help("input output"); - options.show_positional_help(); + options.parse_positional({ "input", "output" }); + options.positional_help("input output"); + options.show_positional_help(); - fs::path argInput,argOutput; - try - { - cxxopts::ParseResult result{ options.parse(argc, argv) }; + bool argDef; + fs::path argInput,argOutput; + try + { + cxxopts::ParseResult result{ options.parse(argc, argv) }; - if (result["help"].count()) - { - std::cout << options.help(); - return ExitCodes::kSuccess; - } + if (result["help"].count()) + { + std::cout << options.help(); + return ExitCodes::kSuccess; + } - argInput = result["input"].as(); - argOutput = result["output"].as(); - } - catch (const cxxopts::exceptions::exception& e) - { - std::cerr << options.help() << '\n' << e.what(); - return ExitCodes::kBadArgs; - } + argInput = result["input"].as(); + argOutput = result["output"].as(); + argDef = result["def"].count(); + } + catch (const cxxopts::exceptions::exception& e) + { + std::cerr << options.help() << '\n' << e.what(); + return ExitCodes::kBadArgs; + } - if (!fs::is_regular_file(argInput)) - { - std::cerr << "Invalid input DLL path " << argInput << '\n'; - return ExitCodes::kBadArgs; - } + if (!fs::is_regular_file(argInput)) + { + std::cerr << "Invalid input DLL path " << argInput << '\n'; + return ExitCodes::kBadArgs; + } - if (!fs::is_directory(argOutput.parent_path())) - { - std::cerr << "Invalid output path " << argOutput << '\n'; - return ExitCodes::kBadArgs; - } + if (!fs::is_directory(argOutput.parent_path())) + { + std::cerr << "Invalid output path " << argOutput << '\n'; + return ExitCodes::kBadArgs; + } - if (fs::is_directory(argOutput)) - argOutput /= "dllforwarder.h"; - else if (!argOutput.has_extension()) - argOutput.replace_extension(".h"); + if (fs::is_directory(argOutput)) + argOutput /= argInput.filename().replace_extension(); - return makeProxy(argInput, argOutput) ? ExitCodes::kSuccess : ExitCodes::kFailed; + if (!argOutput.has_extension()) + argOutput.replace_extension(argDef ? ".def" : ".h"); + + if (argDef) + return makeDefinition(argInput, argOutput) ? ExitCodes::kSuccess : ExitCodes::kFailed; + else + return makeHeader(argInput, argOutput) ? ExitCodes::kSuccess : ExitCodes::kFailed; } diff --git a/src/parser.cc b/src/parser.cc index cdbd8b9..7603c58 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -60,7 +60,7 @@ std::vector parseExports(const fs::path& path) char* exportName = reinterpret_cast( ImageRvaToVa(LoadedImage.FileHeader, LoadedImage.MappedAddress, dNameRVAs[i], nullptr)); - Export exportEntry{ exportName, dOrdinals[i] + 1, static_cast(dFunctions[dOrdinals[i]]) }; + Export exportEntry{ exportName, static_cast(dOrdinals[i] + 1), static_cast(dFunctions[dOrdinals[i]]) }; exportVector.push_back(exportEntry); } } @@ -68,3 +68,19 @@ std::vector parseExports(const fs::path& path) return exportVector; } + +std::string parseMangled(const std::string& mangledName) +{ + std::string unmangledName; + unmangledName.resize(512); + + DWORD writtenChars{ UnDecorateSymbolName(mangledName.c_str(), unmangledName.data(), static_cast(unmangledName.size()), UNDNAME_COMPLETE) }; + if (writtenChars) + { + unmangledName.resize(writtenChars); + unmangledName.shrink_to_fit(); + return unmangledName; + } + else + return mangledName; +}