[Release] Fixing Bad Image error on Windows 11

Results 1 to 2 of 2
  1. #1
    Newbie shailist is offline
    MemberRank
    Nov 2022 Join Date
    2Posts

    [Release] Fixing Bad Image error on Windows 11

    Hello :)

    I've seen a lot of people having trouble running some maple versions on Windows 11.
    The affected versions I've seen seem to be 32bit versions above v176, but more versions could be affected.

    I ran into the same problem when trying to run v207.

    The Problem

    Some time after launching the game, I get the following error:


    It took some research, but what seems to happen is that maple is copying DLLs into a temp path and then loads them from there.
    The code that does that is virtualized so I didn't bother trying to understand it.
    What seems to happen is that in some cases, the game tries to load the copied DLL before the copying process finishes (how do you even code something this garbage?? wth nexon).

    The Fix

    If maple is copying the DLLs and then loading them, lets just make it load the original DLL.

    1. The first step is to keep track of files that are being copied:
    PHP Code:
    std::mutex coped_files_mutex;
    std::unordered_map<std::wstringstd::wstringcopied_files;

    WINBASEAPI
    BOOL
    WINAPI
    BasepCopyFileExW
    (
        
    IN LPCWSTR lpExistingFileName,
        
    IN LPCWSTR lpNewFileName,
        ...
    );

    void BasepCopyFileExW_hook_impl(LPCWSTR lpExistingFileNameLPCWSTR lpNewFileName)
    {
        if ((
    nullptr != lpExistingFileName) && (nullptr != lpNewFileName))
        {
            
    std::unique_lock copied_dlls_lock(coped_files_mutex);
            
    copied_files[lpNewFileName] = lpExistingFileName;
        }
    }

    __declspec(naked)
    BOOL
    WINAPI
    BasepCopyFileExW_hook
    (
        
    IN LPCWSTR lpExistingFileName,
        
    IN LPCWSTR lpNewFileName,
        ...
    )
    {
        
    BasepCopyFileExW_hook_impl(lpExistingFileNamelpNewFileName);

        
    __asm {
            
    jmp original_BasepCopyFileExW
        
    }


    (Don't mind the shitty BasepCopyFileExW signature and jmp to the original function, I can't seem to get the function signature right )

    2. The second step is to make every try of loading a copied DLL load the original one:
    PHP Code:
    NTSTATUS
    NTAPI
    LdrLoadDll_hook
    (
        
    PWSTR search_path OPTIONAL,    PULONG dll_characteristics OPTIONAL,    PUNICODE_STRING dll_name,
        
    PVOIDbase_address
    )
    {
        if ((
    nullptr != dll_name) && (nullptr != dll_name->Buffer))
        {
            
    autobegin dll_name->Buffer;
            
    autoend reinterpret_cast<PWSTR>(reinterpret_cast<PBYTE>(begin) + dll_name->Length);
            
    std::wstring dll_path(beginend);

            
    std::wstring original_dll;
            {
                
    std::unique_lock copied_dlls_lock(coped_files_mutex);
                
    original_dll copied_files[dll_path];
            }

            if (!
    original_dll.empty())
            {
                *
    base_address LoadLibraryW(original_dll.c_str());
                return 
    STATUS_SUCCESS;
            }
        }

        return 
    original_LdrLoadDll(search_pathdll_characteristicsdll_namebase_address);

    Hope this helps someone :)
    Last edited by shailist; 4 Weeks Ago at 11:46 PM.


  2. #2
    Sorcerer Supreme Spiderman is offline
    Member +Rank
    Feb 2010 Join Date
    420Posts
    nice.



Advertisement