0

私が取り組んでいるゲームの ddraw.dll をプロキシしようとしています (チート目的ではありません)。メイン ゲームを開始するために、2 つの関数が呼び出されます。

DirectDrawEnumerateExA

DirectDrawCreateEx

これらの両方を C++ プロジェクトに追加し、オンラインで数え切れないほどの調査を行いましたが、これまでのところどこにもありません。さまざまなチュートリアルや、.def ファイルの使用などのさまざまな方法を試しましたが、何が間違っているかを理解する。

ゲームを起動すると、「プロシージャ エントリ ポイント DirectDrawEnumerateExA がダイナミック リンク ライブラリ DDRAW.dll に見つかりませんでした」というメッセージが表示されます。

現在使用しているコードベースは次のとおりです。

#include <windows.h>
#include <ddraw.h>

typedef HRESULT (WINAPI* DirectDrawEnumerateExA_td)(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
typedef HRESULT (WINAPI* DirectDrawCreateEx_td)(GUID FAR *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkouter);

static struct
{
    HMODULE hGameDLL;
    char* pGameDLL;

    // entry points
    DirectDrawEnumerateExA_td OldDirectDrawEnumerateExA;
    DirectDrawCreateEx_td OldDirectDrawCreateEx;

} g_state;

extern "C" HRESULT __declspec(dllexport) OldDirectDrawEnumerateExA(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
{
    return g_state.OldDirectDrawEnumerateExA(lpCallback, lpContext, dwFlags);
}

extern "C" HRESULT __declspec(dllexport) WINAPI OldDirectDrawCreateEx(GUID FAR *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkouter)
{
    return g_state.OldDirectDrawCreateEx(lpGuid, lplpDD, iid, pUnkouter);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if(fdwReason == DLL_PROCESS_ATTACH)
    {
            char infoBuf[MAX_PATH];
            GetSystemDirectory(infoBuf, MAX_PATH);
            strcat_s(infoBuf, MAX_PATH, "\\ddraw.dll");

            g_state.hGameDLL = LoadLibrary(infoBuf); 
            g_state.pGameDLL = (char*)g_state.hGameDLL;

            if(!g_state.hGameDLL)
            {
                MessageBox(NULL, "Unable to load ddraw.dll", "Error", MB_OK | MB_ICONEXCLAMATION);
                ExitProcess(0);
            }

            g_state.OldDirectDrawEnumerateExA = (DirectDrawEnumerateExA_td)GetProcAddress(g_state.hGameDLL, "DirectDrawEnumerateExA");

            if(!g_state.OldDirectDrawEnumerateExA)
            {
                MessageBox(NULL, "Unable to find entry point: DirectDrawEnumerateExA", "Error", MB_OK | MB_ICONEXCLAMATION);
                ExitProcess(0);
            }

            g_state.OldDirectDrawCreateEx = (DirectDrawCreateEx_td)GetProcAddress(g_state.hGameDLL, "DirectDrawCreateEx");

            if(!g_state.OldDirectDrawCreateEx)
            {
                MessageBox(NULL, "Unable to find entry point: DirectDrawCreateEX", "Error", MB_OK | MB_ICONEXCLAMATION);
            }

            MessageBox(NULL, "Test.", "Test Box", MB_OK | MB_ICONEXCLAMATION);
    }
    else if(fdwReason == DLL_PROCESS_DETACH)
    {
        if (g_state.hGameDLL)
        {
            FreeLibrary(g_state.hGameDLL);
        }
    }

    return TRUE;
}
4

1 に答える 1

0

大きな問題の 1 つは、DLL_PROCESS_ATTACH が行われているときの LoaLibrary の呼び出しです。そんなことは絶対にしないでください!代わりに、DLL を作成するためのベスト プラクティスを参照して、これを修正してください。実験中の失敗は、Loader がプロセスへの DLL のアタッチをまだ完了していないときに LoadLibrary を呼び出すことの副作用に関係しています。

于 2012-06-13T06:44:35.467 に答える