Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Report 【error LNK2019: unresolved external symbol __EH_epilog3】 in build mode "Release x86". #3

Closed
Peter-Zheng-Sp opened this issue Apr 27, 2021 · 11 comments
Labels
bug Something isn't working

Comments

@Peter-Zheng-Sp
Copy link

Peter-Zheng-Sp commented Apr 27, 2021

OS: Windows 10 Enterprise LTSC (Build 17763.1809)
IDE: Visual Studio 2019
WDK: WDK10 (10.0.19041.0)
Build mode: Kernel, Release x86
Details: When I compile the driver with the already compiled ucxxrt.lib, the LNK2019 error is reported only when I set the compile mode to Release x86. And the project's UnitTest does not compile through in this mode either, with the same LNK2019 error.

image

@MiroKaku MiroKaku added the bug Something isn't working label Apr 29, 2021
@MiroKaku
Copy link
Owner

Yes, SAFESEH is not supported temporarily.
You can turn off SAFESEH first。
/SAFESEH:NO

@Peter-Zheng-Sp
Copy link
Author

Yes, SAFESEH is not supported temporarily.
You can turn off SAFESEH first。
/SAFESEH:NO

Hi, apparently I have closed SAFESEH, but the error still persists. The zip file of my Visual Studio project is provided below for reference.

Please click here to get project code: Visual Studio Project Demo

image

@Peter-Zheng-Sp
Copy link
Author

Peter-Zheng-Sp commented May 8, 2021

Hi,
I noticed that your exception type only support /EHsc, but not support /EHa, it will caused that if I define a class object in __try->__except, and then this class will not be destructed when exception be throwed in this block, reference to Structured Exception Handling (C/C++) ... Only use try->catch structure can avoid this question, but if not support /EHa, try->catch will not catch SEH exception, like ProbeForWrite. Please see example as below:

class A {
public:
  A() { DbgPrint("Construct \n");
  }
  ~A() { DbgPrint("Destruct \n");}
};

__try {
  A a;
  ProbeForWrite(0x00000000, 4, 4);
} __except (EXCEPTION_EXECUTE_HANDLER) {
  DbgPrint("Throw Exception !!!");
}

@MeeSong
Copy link

MeeSong commented May 17, 2021

Hi, SAFESEH is supported.

@Peter-Zheng-Sp
Copy link
Author

Hi, SAFESEH is supported.

Hi, when use dynamic initializer to initialize STL container in /EHsc or /EHa, it will cause compiler error, the error message as shown below.

error LNK2019: unresolved external symbol "void __stdcall `eh vector destructor iterator'(void *,unsigned int,unsigned int,void (__thiscall*)(void *))" (??_M@YGXPAXIIP6EX0@Z@Z) referenced in function "void __cdecl `dynamic initializer for 'global_api''(void)" (??__Eglobal_api@@YAXXZ)

Code demo:

std::map<std::string, ULONG_PTR> global_api = {
{"ZwMapViewOfSection", NULL},
{"ZwCreateFile", NULL}
}

@Peter-Zheng-Sp
Copy link
Author

Peter-Zheng-Sp commented May 18, 2021

Great! I think this should be a relatively complete C++ Runtime library 👍 . By the way, would you like to research about how to implement _set_se_translator? It is useful for helping us convert between c++ exception context and SEH exception context.

Code demo

#include <ntifs.h>
#include <eh.h>

class CSEHException
{
public :
    CSEHException(UINT code , PEXCEPTION_POINTERS pep) {
       m_exceptionCode      = code ;
       m_exceptionRecord   = *pep->ExceptionRecord ;
       m_context               = *pep->ContextRecord ;
}
operator unsigned int() { return m_exceptionCode ; }

UINT m_exceptionCode ;
EXCEPTION_RECORD   m_exceptionRecord ;
CONTEXT   m_context ;
} ;
 
// SEH translator function
void __cdecl TranslateSEHtoCE( UINT code , PEXCEPTION_POINTERS pep ) {
    throw CSEHException( code , pep ) ;
}
 
EXTERN_C 
NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath) {
    UNREFERENCE_PARAMETER(pDrvObj);
    UNREFERENCE_PARAMETER(pRegPath);
    
    //TODO: Init cpp runtime
    // xxxxxxx

    // Install SEH translator
    _set_se_translator(TranslateSEHtoCE) ;

    try {
        ProbeForWrite(0x00000000, 4, 4);
    } catch(const CSEHException& e) {
        printf("SEH exception code: %u \n", e.m_exceptionCode);
    }
    
    return STATUS_SUCCESS;
}

@MeeSong
Copy link

MeeSong commented May 21, 2021

Great! I think this should be a relatively complete C++ Runtime library 👍 . By the way, would you like to research about how to implement _set_se_translator? It is useful for helping us convert between c++ exception context and SEH exception context.

Code demo

#include <ntifs.h>
#include <eh.h>

class CSEHException
{
public :
    CSEHException(UINT code , PEXCEPTION_POINTERS pep) {
       m_exceptionCode      = code ;
       m_exceptionRecord   = *pep->ExceptionRecord ;
       m_context               = *pep->ContextRecord ;
}
operator unsigned int() { return m_exceptionCode ; }

UINT m_exceptionCode ;
EXCEPTION_RECORD   m_exceptionRecord ;
CONTEXT   m_context ;
} ;
 
// SEH translator function
void __cdecl TranslateSEHtoCE( UINT code , PEXCEPTION_POINTERS pep ) {
    throw CSEHException( code , pep ) ;
}
 
EXTERN_C 
NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath) {
    UNREFERENCE_PARAMETER(pDrvObj);
    UNREFERENCE_PARAMETER(pRegPath);
    
    //TODO: Init cpp runtime
    // xxxxxxx

    // Install SEH translator
    _set_se_translator(TranslateSEHtoCE) ;

    try {
        ProbeForWrite(0x00000000, 4, 4);
    } catch(const CSEHException& e) {
        printf("SEH exception code: %u \n", e.m_exceptionCode);
    }
    
    return STATUS_SUCCESS;
}

Don't support, The system won't call me.

@Peter-Zheng-Sp
Copy link
Author

Peter-Zheng-Sp commented May 21, 2021

Hi, in the newly refactored version of the code I found that it will cause BSOD on Windows7 x86 when I load driver of your code demo. Have you tested it, including loading and unloading drivers?

BSOD Info:

*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

UNEXPECTED_KERNEL_MODE_TRAP (7f)
This means a trap occurred in kernel mode, and it's a trap of a kind
that the kernel isn't allowed to have/catch (bound trap) or that
is always instant death (double fault).  The first number in the
bugcheck params is the number of the trap (8 = double fault, etc)
Consult an Intel x86 family manual to learn more about what these
traps are. Here is a *portion* of those codes:
If kv shows a taskGate
        use .tss on the part before the colon, then kv.
Else if kv shows a trapframe
        use .trap on that value
Else
        .trap on the appropriate frame will show where the trap was taken
        (on x86, this will be the ebp that goes with the procedure KiTrap)
Endif
kb will then show the corrected stack.
Arguments:
Arg1: 0000000d, EXCEPTION_GP_FAULT
Arg2: 00000000
Arg3: 00000000
Arg4: 00000000

Debugging Details:
------------------


KEY_VALUES_STRING: 1

    Key  : Analysis.CPU.Sec
    Value: 0

    Key  : Analysis.DebugAnalysisProvider.CPP
    Value: Create: 8007007e on MINERVASOWL

    Key  : Analysis.DebugData
    Value: CreateObject

    Key  : Analysis.DebugModel
    Value: CreateObject

    Key  : Analysis.Elapsed.Sec
    Value: 6

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 66

    Key  : Analysis.System
    Value: CreateObject


BUGCHECK_CODE:  7f

BUGCHECK_P1: d

BUGCHECK_P2: 0

BUGCHECK_P3: 0

BUGCHECK_P4: 0

PROCESS_NAME:  System

STACK_TEXT:  
8d33452c 82ae6083 00000003 7ff70bde 00000065 nt!RtlpBreakWithStatusInstruction
8d33457c 82ae6b81 00000003 961ae01b 8708e2f8 nt!KiBugCheckDebugBreak+0x1c
8d334940 82a48d0b 0000007f 0000000d 00000000 nt!KeBugCheck2+0x68b
8d334940 961ae01b 0000007f 0000000d 00000000 nt!KiSystemFatalException+0xf
8d3349d0 960f60aa 8d334bbc 82bcb2e6 8708e2f8 unittest!__security_init_cookie+0x1b [minkernel\tools\gs_support\kmodefastfail\gs_support.c @ 46] 
8d3349d8 82bcb2e6 8708e2f8 87369000 00000000 unittest!FxDriverEntry+0xa [minkernel\wdf\framework\kmdf\src\dynamic\stub\stub.cpp @ 238] 
8d334bbc 82bced98 00000001 00000000 8d334be4 nt!IopLoadDriver+0x7ed
8d334c00 82a84aab 935aabd0 00000000 85240a70 nt!IopLoadUnloadDriver+0x70
8d334c50 82c10f5e 00000001 7ff70232 00000000 nt!ExpWorkerThread+0x10d
8d334c90 82ab8219 82a8499e 00000001 00000000 nt!PspSystemThreadStartup+0x9e
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x19


FAULTING_SOURCE_LINE:  minkernel\tools\gs_support\kmodefastfail\gs_support.c

FAULTING_SOURCE_FILE:  minkernel\tools\gs_support\kmodefastfail\gs_support.c

FAULTING_SOURCE_LINE_NUMBER:  46

SYMBOL_NAME:  unittest!__security_init_cookie+1b

MODULE_NAME: unittest

IMAGE_NAME:  unittest.sys

STACK_COMMAND:  .thread ; .cxr ; kb

FAILURE_BUCKET_ID:  0x7f_d_unittest!__security_init_cookie+1b

OS_VERSION:  7.1.7601.17514

BUILDLAB_STR:  win7sp1_rtm

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 7

FAILURE_ID_HASH:  {4029ef85-7b0c-0f11-f610-4ffdef762b6d}

Followup:     MachineOwner

Code

#ifdef __KERNEL_MODE
#include <ntddk.h>
#include <wdm.h>
#else
#include <windows.h>
#include <assert.h>
#endif

#include <ucxxrt.h>

#include <string>
#include <random>
#include <vector>
#include <functional>
#include <unordered_map>


#ifdef _KERNEL_MODE
#define LOG(_0, _1, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__)
#else
#define LOG(_0, _1, ...) printf(__VA_ARGS__)
#endif

#ifdef _KERNEL_MODE
EXTERN_C NTSTATUS DriverMain(PDRIVER_OBJECT aDriverObject, PUNICODE_STRING /*aRegistry*/)
#else
EXTERN_C int main()
#endif
{

#ifdef _KERNEL_MODE
  aDriverObject->DriverUnload = [](PDRIVER_OBJECT)
  {
    LOG(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Exit ucxxrt-test.\n");
  };
#endif

  return 0;
}

@MeeSong
Copy link

MeeSong commented May 21, 2021

You need set: unittest - Properties - Driver Settings - Target OS Version - Windows 7

@MeeSong
Copy link

MeeSong commented May 21, 2021

And, I don't plan to support Windows 7 😄

@Peter-Zheng-Sp
Copy link
Author

Peter-Zheng-Sp commented May 21, 2021

Alright, thanks.

MiroKaku added a commit that referenced this issue Jun 16, 2022
fix: issues #11

feat: #3 _set_se_translator

feat: ARM/ARM64 (experimental)

feat: /EHa
MiroKaku added a commit that referenced this issue Dec 25, 2023
fix: issues #11

feat: #3 _set_se_translator

feat: ARM/ARM64 (experimental)

feat: /EHa
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants