diff --git a/3rdparty/CMakelists.txt b/3rdparty/CMakelists.txt new file mode 100644 index 00000000..c3ed36d6 --- /dev/null +++ b/3rdparty/CMakelists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 3.30) +project(Detours LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(libname lib_detours) +set(DETOURS_SOURCE Detours) + +add_library(${libname} STATIC) +target_include_directories(${libname} PRIVATE ${DETOURS_SOURCE}) +target_sources(${libname} PRIVATE + ${DETOURS_SOURCE}/creatwth.cpp + ${DETOURS_SOURCE}/detours.cpp + ${DETOURS_SOURCE}/disasm.cpp + ${DETOURS_SOURCE}/disolarm.cpp + ${DETOURS_SOURCE}/disolarm64.cpp + ${DETOURS_SOURCE}/disolia64.cpp + ${DETOURS_SOURCE}/disolx64.cpp + ${DETOURS_SOURCE}/disolx86.cpp + ${DETOURS_SOURCE}/image.cpp + ${DETOURS_SOURCE}/modules.cpp + ${DETOURS_SOURCE}/uimports.cpp + ${DETOURS_SOURCE}/detours.h + ${DETOURS_SOURCE}/detver.h +) + +# This file is included and not compiled on its own +set_property ( + SOURCE ${DETOURS_SOURCE}/uimports.cpp + APPEND PROPERTY HEADER_FILE_ONLY true) + +# Install libraries and public headers +install(TARGETS ${libname} + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + FILE_SET HEADERS DESTINATION include +) + +# Install export file +install(EXPORT ${PROJECT_NAME}Targets + FILE ${PROJECT_NAME}Targets.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION lib/cmake/${PROJECT_NAME} +) + +# Generate and install CMake config file +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION 1.0.0 + COMPATIBILITY SameMajorVersion +) + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + @ONLY +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION lib/cmake/${PROJECT_NAME} +) + +# CPack configuration for packaging +set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") +set(CPACK_PACKAGE_VERSION "1.0.0") +set(CPACK_PACKAGE_DESCRIPTION "A custom MemoryModulePP implementation") +set(CPACK_PACKAGE_VENDOR "xAI") +set(CPACK_GENERATOR "ZIP;TGZ") +include(CPack) diff --git a/3rdparty/DetoursConfig.cmake.in b/3rdparty/DetoursConfig.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/3rdparty/DetoursConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..718b9351 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.27) +project(MemoryModulePP LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# add _d to debug targets +SET(CMAKE_DEBUG_POSTFIX _d) + +# build spec done in subdirectories +add_subdirectory(3rdparty) +add_subdirectory(a) +add_subdirectory(MemoryModule) +add_subdirectory(test) diff --git a/MemoryModule/CMakeLists.txt b/MemoryModule/CMakeLists.txt new file mode 100644 index 00000000..b3833f32 --- /dev/null +++ b/MemoryModule/CMakeLists.txt @@ -0,0 +1,157 @@ +cmake_minimum_required(VERSION 3.30) +project(MemoryModulePP LANGUAGES CXX) + +# Define static library target +set(static_libname "MemoryModulePP-static") +add_library(${static_libname} STATIC) + +# Define shared library target +set(shared_libname "MemoryModulePP-shared") +add_library(${shared_libname} SHARED) + +# turn on "reflection" +target_compile_definitions(${shared_libname} PRIVATE _USRDLL) + +# link libraries for DLL +target_link_libraries(${shared_libname} PRIVATE lib_detours) + +# Common sources and headers for both libraries +set(common_sources + BaseAddressIndex.cpp + ImportTable.cpp + Initialize.cpp + InvertedFunctionTable.cpp + LdrEntry.cpp + LoadDllMemoryApi.cpp + Loader.cpp + MemoryModule.cpp + MmpDotNet.cpp + MmpLdrpTls.cpp + MmpTls.cpp + MmpTlsFiber.cpp + Utils.cpp + + # exports + MemoryModulePP.def +) + +set(common_public_headers + BaseAddressIndex.h + ImportTable.h + Initialize.h + InvertedFunctionTable.h + LdrEntry.h + LoadDllMemoryApi.h + Loader.h + MemoryModule.h + MmpGlobalData.h + MmpDotNet.h + MmpTls.h + Utils.h +) + +set(common_private_headers + LoaderPrivate.h + MmpTlsFiber.h + MmpTlsp.h + ReflectiveDLLInjection.h + ReflectiveLoader.h +) + +# Specify sources and headers for static library +target_sources(${static_libname} + PRIVATE + ${common_sources} + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${common_public_headers} + PRIVATE + FILE_SET private_headers + TYPE HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${common_private_headers} +) + +# Specify sources and headers for shared library +target_sources(${shared_libname} + PRIVATE + ${common_sources} + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${common_public_headers} + PRIVATE + FILE_SET private_headers + TYPE HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${common_private_headers} +) + +# Set include directories for libraries +foreach(libname ${static_libname} ${shared_libname}) + target_include_directories(${libname} + PUBLIC + $ + $ + $ + ) + + # Ensure C++ standard + target_compile_features(${libname} PRIVATE cxx_std_23) + + # key definitions + target_compile_definitions(${libname} PRIVATE + _MEMORY_MODULE + _HAS_AUTO_INITIALIZE + MMPP_USE_TLS=1 + ) +endforeach() + +# Install libraries and public headers +install(TARGETS ${static_libname} ${shared_libname} + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + FILE_SET HEADERS DESTINATION include +) + +# Install export file +install(EXPORT ${PROJECT_NAME}Targets + FILE ${PROJECT_NAME}Targets.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION lib/cmake/${PROJECT_NAME} +) + +# Generate and install CMake config file +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION 1.0.0 + COMPATIBILITY SameMajorVersion +) + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/../${PROJECT_NAME}Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + @ONLY +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION lib/cmake/${PROJECT_NAME} +) + +# CPack configuration for packaging +set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") +set(CPACK_PACKAGE_VERSION "1.0.0") +set(CPACK_PACKAGE_DESCRIPTION "A custom MemoryModulePP implementation") +set(CPACK_PACKAGE_VENDOR "xAI") +set(CPACK_GENERATOR "ZIP;TGZ") +include(CPack) diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index aa023c8e..1142c340 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -5,6 +5,12 @@ PMMP_GLOBAL_DATA MmpGlobalDataPtr; +// DLL compliant access +extern "C" PMMP_GLOBAL_DATA NTAPI GetMmpGlobalDataPtr() +{ + return MmpGlobalDataPtr; +} + #if MEMORY_MODULE_IS_PREVIEW(MEMORY_MODULE_MINOR_VERSION) #pragma message("WARNING: You are using a preview version of MemoryModulePP.") #endif @@ -621,6 +627,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser } #else #ifdef _HAS_AUTO_INITIALIZE -const NTSTATUS Initializer = MmInitialize(); +static const NTSTATUS Initializer = MmInitialize(); #endif #endif diff --git a/MemoryModule/LoadDllMemoryApi.cpp b/MemoryModule/LoadDllMemoryApi.cpp index 01aaeb65..8bf30901 100644 --- a/MemoryModule/LoadDllMemoryApi.cpp +++ b/MemoryModule/LoadDllMemoryApi.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include -HMEMORYMODULE WINAPI LoadLibraryMemoryExW( +extern "C" HMEMORYMODULE WINAPI LoadLibraryMemoryExW( _In_ PVOID BufferAddress, _In_ size_t Reserved, _In_opt_ LPCWSTR DllBaseName, @@ -15,7 +15,7 @@ HMEMORYMODULE WINAPI LoadLibraryMemoryExW( return hMemoryModule; } -HMEMORYMODULE WINAPI LoadLibraryMemoryExA( +extern "C" HMEMORYMODULE WINAPI LoadLibraryMemoryExA( _In_ PVOID BufferAddress, _In_ size_t Reserved, _In_opt_ LPCSTR DllBaseName, @@ -59,11 +59,11 @@ HMEMORYMODULE WINAPI LoadLibraryMemoryExA( return result; } -HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress) { +extern "C" HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress) { return LoadLibraryMemoryExW(BufferAddress, 0, nullptr, nullptr, 0); } -BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule) { +extern "C" BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule) { NTSTATUS status = LdrUnloadDllMemory(hMemoryModule); if (!NT_SUCCESS(status)) { SetLastError(RtlNtStatusToDosError(status)); diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index 846ad818..80c74e8d 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -44,7 +44,7 @@ NTSTATUS NTAPI LdrMapDllMemory( return STATUS_SUCCESS; } -NTSTATUS NTAPI LdrLoadDllMemoryExW( +extern "C" NTSTATUS NTAPI LdrLoadDllMemoryExW( _Out_ HMEMORYMODULE* BaseAddress, _Out_opt_ PVOID* LdrEntry, _In_ DWORD dwFlags, @@ -96,12 +96,8 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( auto dist = (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - length; bool equal = false; - if (dist == 0 || dist == 4) { - equal = !_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, length); - } - else { - continue; - } + if (!(dist == 0 || dist == 4)) continue; + equal = !_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, length); /* Check if name matches */ if (equal) { @@ -221,7 +217,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( return status; } -NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { +extern "C" NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { PLDR_DATA_TABLE_ENTRY CurEntry; ULONG count = 0; NTSTATUS status = STATUS_SUCCESS; @@ -292,13 +288,14 @@ NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { return status; } +extern "C" DECLSPEC_NORETURN VOID NTAPI LdrUnloadDllMemoryAndExitThread(_In_ HMEMORYMODULE BaseAddress, _In_ DWORD dwExitCode) { LdrUnloadDllMemory(BaseAddress); RtlExitUserThread(dwExitCode); } -NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures) { +extern "C" NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures) { NTSTATUS status = STATUS_SUCCESS; __try { *pFeatures = MmpGlobalDataPtr->MmpFeatures; diff --git a/MemoryModule/MemoryModulePP.def b/MemoryModule/MemoryModulePP.def index fcbae96d..7120e75c 100644 --- a/MemoryModule/MemoryModulePP.def +++ b/MemoryModule/MemoryModulePP.def @@ -15,3 +15,4 @@ LdrUnloadDllMemoryAndExitThread LdrQuerySystemMemoryModuleFeatures MmpGlobalDataPtr +GetMmpGlobalDataPtr diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index 2a986b0e..989c59f3 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -153,3 +153,4 @@ typedef struct _MMP_GLOBAL_DATA { ) extern PMMP_GLOBAL_DATA MmpGlobalDataPtr; +extern "C" PMMP_GLOBAL_DATA NTAPI GetMmpGlobalDataPtr() ; diff --git a/MemoryModule/MmpLdrpTls.cpp b/MemoryModule/MmpLdrpTls.cpp index 286ddd51..8d64e374 100644 --- a/MemoryModule/MmpLdrpTls.cpp +++ b/MemoryModule/MmpLdrpTls.cpp @@ -141,12 +141,9 @@ static NTSTATUS NTAPI RtlFindLdrpHandleTlsData10() { } static NTSTATUS NTAPI RtlFindLdrpHandleTlsData() { - if (MmpGlobalDataPtr->NtVersions.MajorVersion >= 10) { - return RtlFindLdrpHandleTlsData10(); - } - else { - return RtlFindLdrpHandleTlsDataOld(); - } + return MmpGlobalDataPtr->NtVersions.MajorVersion >= 10 + ? RtlFindLdrpHandleTlsData10() + : RtlFindLdrpHandleTlsDataOld(); } static NTSTATUS NTAPI RtlFindLdrpReleaseTlsEntry() { diff --git a/MemoryModule/Utils.cpp b/MemoryModule/Utils.cpp index 3e4e4dac..cae8bdff 100644 --- a/MemoryModule/Utils.cpp +++ b/MemoryModule/Utils.cpp @@ -393,9 +393,9 @@ BOOL NTAPI RtlIsWindowsVersionOrGreater( ) { if (MmpGlobalDataPtr->NtVersions.MajorVersion == MajorVersion) { if (MmpGlobalDataPtr->NtVersions.MinorVersion == MinorVersion) return MmpGlobalDataPtr->NtVersions.BuildNumber >= BuildNumber; - else return (MmpGlobalDataPtr->NtVersions.MinorVersion > MinorVersion); + return (MmpGlobalDataPtr->NtVersions.MinorVersion > MinorVersion); } - else return MmpGlobalDataPtr->NtVersions.MajorVersion > MajorVersion; + return MmpGlobalDataPtr->NtVersions.MajorVersion > MajorVersion; } BOOL NTAPI RtlIsWindowsVersionInScope( diff --git a/MemoryModulePPConfig.cmake.in b/MemoryModulePPConfig.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/MemoryModulePPConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/a/CMakeLists.txt b/a/CMakeLists.txt new file mode 100644 index 00000000..c54b9686 --- /dev/null +++ b/a/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.30) +project(a-sample LANGUAGES CXX) + +set(libname "a") + +add_library(${libname} SHARED) +target_link_libraries(${libname} PRIVATE lib_detours) +target_sources(${libname} PRIVATE + # sources + dllmain.cpp + exception.cpp + gdiplus.cpp + thread.cpp + + # exports + m.def + + # resources + a.rc + resource.h +) + +# put dll in local install dir +set( INSTALL_DIR "${CMAKE_BINARY_DIR}/install") +install(TARGETS ${libname} + LIBRARY DESTINATION ${INSTALL_DIR} + ARCHIVE DESTINATION ${INSTALL_DIR} + RUNTIME DESTINATION ${INSTALL_DIR} +) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..6ad5671e --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.27) +project(mmtest LANGUAGES CXX) + +# Define executable targets +set(static_exename "mmtest-static") +add_executable(${static_exename}) +target_link_libraries(${static_exename} PRIVATE + MemoryModulePP-static + lib_detours +) + +set(shared_exename "mmtest-shared") +add_executable(${shared_exename}) +target_link_libraries(${shared_exename} PRIVATE + MemoryModulePP-shared +) + +# use install directory under build to assemble tests +set( INSTALL_DIR "${CMAKE_BINARY_DIR}/install") + +foreach(exename ${static_exename} ${shared_exename}) + + # common sources and libs + target_sources(${exename} PRIVATE test.cpp) + + # copy exes into install dir + install(TARGETS ${exename} RUNTIME DESTINATION ${INSTALL_DIR}) + + # add shared lib to PATH + file(TO_NATIVE_PATH "$" MMSHARED_TARGET) + string(REGEX REPLACE "/" "\\\\" MMSHARED_PATH ${MMSHARED_TARGET}) + set_target_properties(${exename} PROPERTIES + VS_DEBUGGER_ENVIRONMENT + "PATH=${MMSHARED_PATH};%PATH%" + ) + + # pass path to target a_d.dll in VS debugger + file(TO_NATIVE_PATH "$" A_DLL) + set_target_properties(${exename} PROPERTIES + "VS_DEBUGGER_COMMAND_ARGUMENTS" + "${A_DLL}" + ) +endforeach() diff --git a/test/test.cpp b/test/test.cpp index e5c964af..56d7d921 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,9 +1,15 @@ #include "../MemoryModule/stdafx.h" #include "../MemoryModule/LoadDllMemoryApi.h" #include +#include #pragma comment(lib,"ntdll.lib") -static void DisplayStatus() { +static int DisplayStatus() { + const auto gdp = GetMmpGlobalDataPtr(); + if ( !gdp ) { + printf("failed GetMmpGlobalDataPtr().\n"); + return -1 ; + } printf( "\ MemoryModulePP [Version %d.%d%s]\n\n\t\ @@ -15,24 +21,25 @@ RtlRbRemoveNode = %p\n\n\t\ LdrpInvertedFunctionTable = %p\n\n\t\ LdrpHashTable = %p\n\n\ ", - MmpGlobalDataPtr->MajorVersion, - MEMORY_MODULE_GET_MINOR_VERSION(MmpGlobalDataPtr->MinorVersion), - MEMORY_MODULE_IS_PREVIEW(MmpGlobalDataPtr->MinorVersion) ? " Preview" : "", - MmpGlobalDataPtr->MmpFeatures, - MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex, - MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry, - MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx, - MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode, - MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable, - MmpGlobalDataPtr->MmpLdrEntry->LdrpHashTable + gdp->MajorVersion, + MEMORY_MODULE_GET_MINOR_VERSION(gdp->MinorVersion), + MEMORY_MODULE_IS_PREVIEW(gdp->MinorVersion) ? " Preview" : "", + gdp->MmpFeatures, + (PVOID)gdp->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex, + (PVOID)gdp->MmpBaseAddressIndex->NtdllLdrEntry, + gdp->MmpBaseAddressIndex->_RtlRbInsertNodeEx, + gdp->MmpBaseAddressIndex->_RtlRbRemoveNode, + gdp->MmpInvertedFunctionTable->LdrpInvertedFunctionTable, + (PVOID)gdp->MmpLdrEntry->LdrpHashTable ); + return 0 ; } -static PVOID ReadDllFile(LPCSTR FileName) { +static PVOID ReadDllFile(const std::string& FilePath) { LPVOID buffer; size_t size; FILE* f; - fopen_s(&f, FileName, "rb"); + fopen_s(&f, FilePath.c_str(), "rb"); if (!f)return 0; _fseeki64(f, 0, SEEK_END); if (!(size = _ftelli64(f))) { @@ -48,24 +55,24 @@ static PVOID ReadDllFile(LPCSTR FileName) { return buffer; } -PVOID ReadDllFile2(LPCSTR FileName) { +static std::string ResolveWithModulePath(const std::string& dll_path) +{ + std::string rc(dll_path) ; + + // expect default dll in module directory CHAR path[MAX_PATH + 4]; - DWORD len = GetModuleFileNameA(nullptr, path, sizeof(path)); + const auto len = GetModuleFileNameA(nullptr, path, sizeof(path)); if (len) { - while (len && path[len] != '\\') --len; - - if (len) { - strcpy_s(&path[len + 1], sizeof(path) - len - 1, FileName); - return ReadDllFile(path); - } + const std::string mod_path(path); + const auto last_slash = mod_path.find_last_of("/\\") ; + rc = mod_path.substr(0, last_slash + 1) + dll_path; } - return nullptr; + return rc ; } -int test() { - LPVOID buffer = ReadDllFile2("a.dll"); +int test(const std::string& dll_path) { HMODULE hModule = nullptr; FARPROC pfn = nullptr; @@ -77,7 +84,17 @@ int test() { HGLOBAL gRes; char str[10]; - if (!NT_SUCCESS(LdrLoadDllMemoryExW(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; + LPVOID buffer = ReadDllFile(dll_path); + if ( !buffer ) { + printf("failed to find %s.\n", dll_path.c_str()); + goto end; + } + printf("%s read into memory.\n", dll_path.c_str()); + + if (!NT_SUCCESS(LdrLoadDllMemoryExW(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) { + printf("LdrLoadDllMemoryExW failed.\n"); + goto end; + } //forward export pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW @@ -128,11 +145,17 @@ int test() { return 0; } -int main() { +int main(int argc, char* argv[]) { + + // check MemoryModulePP initialization + if ( DisplayStatus() ) { + return -1 ; + } - DisplayStatus(); + std::string dll_path("a.dll"); // default + dll_path = argc > 1 ? argv[1] : ResolveWithModulePath(dll_path); - test(); + test(dll_path); return 0; }