【问题标题】:SEH with RtlAddFunctionTable in manually loaded DLL手动加载的 DLL 中带有 RtlAddFunctionTable 的 SEH
【发布时间】:2019-10-05 17:30:55
【问题描述】:

我正在手动将 dll 映射到使用 (/EHa) 编译的进程中。这可以捕获如下异常。问题是,由于我手动映射 dll,因此未注册异常/函数,一旦发生异常,就会导致程序崩溃。为了解决这个问题,我得出的结论是我需要使用这个函数“RtlAddFunctionTable(...)”。遗憾的是,我无法获取前两个参数(FunctionTable 和 EntryCount)来调用该函数。有人可以帮我告诉我如何获得前两个参数吗?

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    RUNTIME_FUNCTION runtimeFunction = ?;
    DWORD size = ?;

    RtlAddFunctionTable(&runtimeFunction, size, (DWORD64)hModule);

    try
    {
        int var = *reinterpret_cast<int*>(0xFFFF);
    }
    catch (...) 
    {
        cout << "Exception" << endl;
    }

    return TRUE;
}

编辑,我解决了:

bool EnableExceptions(DWORD64 moduleBase)
{
    PIMAGE_DOS_HEADER pDOSHeader;
    PIMAGE_NT_HEADERS pNTHeader;
    PIMAGE_OPTIONAL_HEADER pOptHeader;

    pDOSHeader = (PIMAGE_DOS_HEADER)moduleBase;
    if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
        return false;

    pNTHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDOSHeader + pDOSHeader->e_lfanew);
    if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
        return false;

    pOptHeader = (PIMAGE_OPTIONAL_HEADER)& pNTHeader->OptionalHeader;
    if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
        return false;

    PRUNTIME_FUNCTION pFunctionTable = (PRUNTIME_FUNCTION)((DWORD64)pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress + moduleBase);
    cout << "functionTable " << hex << functionTable << endl;

    DWORD sizeFunctionTable = (pOptHeader->DataDirectory[3].Size / (DWORD)sizeof(RUNTIME_FUNCTION));
    cout << "functionTableSize " << dec << functionTableSize << endl;

    BOOL success = RtlAddFunctionTable(pFunctionTable, sizeFunctionTable, moduleBase);
    cout << "RtlAddFunctionTable " << success << endl;

    return success;
}

【问题讨论】:

    标签: windows exception visual-c++ dll


    【解决方案1】:

    由于您正在构建启用 SEH 的 .DLL,因此您需要的信息应该已经在 PE 文件中。

    根据this blog post,PE 中的静态表优先于动态添加的表。

    如果您出于某种原因需要使用自定义表,那么您需要使用VirtualAlloc 为表和分配内存,因为地址是相对的 (RVA)。

    【讨论】:

    • 是的,信息应该在“.pdata”部分。所以我需要调用 RtlAddFunctionTable(pDataAdress, pDataArraySize, moduleBaseAddress) 因为“.pdata”部分是一个 RUNTIME_FUNCTION 的数组 - 但它似乎没有按预期工作,因为代码仍然崩溃并且没有触发异常。
    猜你喜欢
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多