├── README.md ├── assets └── image.png ├── dllutils.cpp ├── dllutils.h ├── logger.cpp ├── logger.h └── main.cpp /README.md: -------------------------------------------------------------------------------- 1 | # DllDragon 🐉 2 | 3 | DllDragon is a utility for dynamically loading functions from Windows DLLs (Dynamic Link Libraries) at runtime. It allows you to load a DLL module and retrieve the address of a specific function within that module, without having to link the DLL statically or load it manually. 4 | 5 | ## Features 6 | 7 | - **Dynamic Library Loading**: Load a DLL module by specifying its file name (e.g., "mymodule.dll"). 8 | - **Function Resolution**: Retrieve the address of a specific function within a loaded DLL module by providing the function name (e.g., "MyFunction"). 9 | - **Resource Management**: Employs the RAII (Resource Acquisition Is Initialization) principle to ensure that loaded DLL modules are properly unloaded when they go out of scope, preventing resource leaks. 10 | - **Error Logging**: Logs errors using a custom logger class instead of throwing exceptions, providing better control over error handling and debugging. 11 | - **Thread Safety**: Designed to be thread-safe, with each thread having its own instance of the DLL wrapper class, avoiding potential race conditions and synchronization issues. 12 | - **Caching Mechanism**: Implements a caching mechanism to store loaded DLL modules and resolved function addresses, improving performance by avoiding redundant module loading and function resolution. 13 | - **Modular Design**: Separates the dynamic library loading and function resolution logic into a dedicated class (`DllUtils`), improving code organization and maintainability. 14 | - **Improved API**: Returns a `std::function` object instead of a raw function pointer, providing more flexibility and type safety. 15 | 16 | ## Usage 17 | 18 | To use the DllDragon utility, follow these steps: 19 | 20 | 1. Include the necessary header file: 21 | 22 | ```cpp 23 | #include "dllutils.h" 24 | ``` 25 | 26 | 2. Load a function from a DLL: 27 | 28 | ```cpp 29 | auto myFunction = DllUtils::loadFunction("mymodule.dll", "MyFunction"); 30 | if (myFunction) { 31 | myFunction(); // Invoke the loaded function 32 | } 33 | ``` 34 | 35 | The `loadFunction` method takes two arguments: 36 | - `moduleName`: The name of the DLL module to load (e.g., "mymodule.dll"). 37 | - `procName`: The name of the function to retrieve from the loaded module (e.g., "MyFunction"). 38 | 39 | If the function is successfully loaded, the `loadFunction` method returns a `std::function` object representing the loaded function. You can then invoke the function by calling the returned object. 40 | 41 | ## Examples 42 | 43 | Check out the `main.cpp` file for more examples of how to use the DllDragon utility, including loading multiple functions, loading functions with parameters, and more. 44 | 45 | ## Building and Running 46 | 47 | To build and run the DllDragon utility, follow these steps: 48 | 49 | 1. Clone the repository: 50 | 51 | ``` 52 | git clone https://github.com/your-repo/DllDragon.git 53 | ``` 54 | 55 | 2. Navigate to the project directory: 56 | 57 | ``` 58 | cd DllDragon 59 | ``` 60 | 61 | 3. Compile the source files: 62 | 63 | ``` 64 | g++ -o dlldragon main.cpp dllutils.cpp logger.cpp # On Unix-like systems 65 | cl /EHsc main.cpp dllutils.cpp logger.cpp # On Windows with Visual C++ 66 | ``` 67 | 68 | 4. Run the compiled executable: 69 | 70 | ``` 71 | ./dlldragon # On Unix-like systems 72 | dlldragon.exe # On Windows 73 | ``` 74 | 75 | ## Contributing 76 | 77 | Contributions to the DllDragon project are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request. 78 | 79 | ## License 80 | 81 | This project is licensed under the [MIT License](LICENSE). 82 | 83 | ```txt 84 | DllDragon/ 85 | ├── main.cpp 86 | ├── dllutils.h 87 | ├── dllutils.cpp 88 | ├── logger.h 89 | ├── logger.cpp 90 | └── LICENSE 91 | ``` 92 | -------------------------------------------------------------------------------- /assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a7t0fwa7/DllDragon/655118e6a6536a11a3eedf8cd6ed27ed4c8fba7f/assets/image.png -------------------------------------------------------------------------------- /dllutils.cpp: -------------------------------------------------------------------------------- 1 | #include "dllutils.h" 2 | #include 3 | 4 | std::unordered_map& DllUtils::getModuleCache() { 5 | static std::unordered_map moduleCache; 6 | return moduleCache; 7 | } 8 | 9 | std::unordered_map>& DllUtils::getFunctionCache() { 10 | static std::unordered_map> functionCache; 11 | return functionCache; 12 | } 13 | 14 | std::function DllUtils::loadFunction(const std::string& moduleName, const std::string& procName) { 15 | auto& moduleCache = getModuleCache(); 16 | auto& functionCache = getFunctionCache(); 17 | 18 | auto moduleIt = moduleCache.find(moduleName); 19 | if (moduleIt == moduleCache.end()) { 20 | HMODULE hModule = LoadLibraryA(moduleName.c_str()); 21 | if (!hModule) { 22 | std::cout << "Failed to load module: " << moduleName << std::endl; 23 | return nullptr; 24 | } 25 | moduleIt = moduleCache.emplace(moduleName, hModule).first; 26 | } 27 | 28 | auto& funcCache = functionCache[moduleName]; 29 | auto funcIt = funcCache.find(procName); 30 | if (funcIt == funcCache.end()) { 31 | FARPROC procAddr = GetProcAddress(moduleIt->second, procName.c_str()); 32 | if (!procAddr) { 33 | std::cout << "Failed to get address of function: " << procName << std::endl; 34 | return nullptr; 35 | } 36 | funcIt = funcCache.emplace(procName, procAddr).first; 37 | } 38 | 39 | return reinterpret_cast>(funcIt->second); 40 | } 41 | -------------------------------------------------------------------------------- /dllutils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class DllUtils { 9 | public: 10 | static std::function loadFunction(const std::string& moduleName, const std::string& procName); 11 | 12 | private: 13 | static std::unordered_map& getModuleCache(); 14 | static std::unordered_map>& getFunctionCache(); 15 | }; 16 | -------------------------------------------------------------------------------- /logger.cpp: -------------------------------------------------------------------------------- 1 | #include "logger.h" 2 | #include 3 | 4 | void Logger::log(const std::string& message) { 5 | std::cout << "Log: " << message << std::endl; 6 | } 7 | -------------------------------------------------------------------------------- /logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Logger { 6 | public: 7 | static void log(const std::string& message); 8 | }; 9 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "dllutils.h" 2 | 3 | int main() { 4 | // Example usage 5 | auto myFunction = DllUtils::loadFunction("mymodule.dll", "MyFunction"); 6 | if (myFunction) { 7 | myFunction(); // Invoke the loaded function 8 | } 9 | return 0; 10 | } 11 | --------------------------------------------------------------------------------