c++detours

Access Violation when using struct


I'm trying to hook OpenSSL's int SSL_connect(SSL *s) method. OpenSSL 1.0.2l version.

Here's the source code:

SSL_connect

SSL structure

SSL_SESSION structure

GOAL:

Printing out any SSL_SESSION member (like ssl_version or master_key)

THE PROBLEM:

I get Access Violation Exception when trying to access the SSL *s parameter inside my hook method. Is there anything wrong with my structure? I don't think I must map all of the members of SSL and SSL_SESSION, because I found that SSLHook library doesn't do this - link

I'm able to inject the dll successfully, it does work when I'm not trying to access the parameter.

THE CODE:

typedef struct
{
    int ssl_version;
    unsigned char master_key[48];
} SSL_SESSION;

typedef struct
{
    SSL_SESSION* session;
} SSL;

typedef int(__cdecl* SSL_METHOD_TEMPLATE)(SSL* s);

SSL_METHOD_TEMPLATE Target_SSL_connect = (SSL_METHOD_TEMPLATE)0x14018c540;

int __cdecl Detour_SSL_connect(SSL* s) {
    int ssl_version = s->session->ssl_version;
    std::string message = "done. ssl_version: " + std::to_string(ssl_version);
    MessageBoxA(HWND_DESKTOP, message.c_str(), "title", MB_OK);
    return Target_SSL_connect(s);
}

VOID AfterAttach()
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)Target_SSL_connect, Detour_SSL_connect);

    long lError = DetourTransactionCommit();    
    if (lError != NO_ERROR) {
        MessageBoxA(HWND_DESKTOP, std::to_string(lError).c_str(), "err", MB_OK);
    }
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        AfterAttach();
    }
    return TRUE;
}

Solution

  • I don't think I must map all of the members of SSL and SSL_SESSION, because I found that SSLHook library doesn't do this

    If you take a closer look you see, that they do not map everything but they keep the member order and they duplicate all members up to the "point" in the struct that is relevant for them. Ignoring the original padding in struct injections is almost always very critical and in general undefined behavior I guess, so you can be lucky to obtain a quite deterministic crash here :) So you can either provide the full struct or at least a reduced struct with the according final padding "before" your session member pointer.