How to generate SEH code

I am developing a Windows driver and need some SEH code.
These codes are implemented in C as follows:

do {
	__try {
		ProbeForWrite(address, length, 1);
	} __except (1) {
		if (GetExceptionCode() == STATUS_GUARD_PAGE_VIOLATION) {
		return false;
} while (true);

return true;

Compile this C code with the Microsoft compiler

.text:00407700 ; __unwind { // __except_handler4
.text:00407700                 push    ebp
.text:00407701                 mov     ebp, esp
.text:00407703                 push    0FFFFFFFEh
.text:00407705                 push    offset stru_422C70
.text:0040770A                 push    offset __except_handler4
.text:0040770F                 mov     eax, large fs:0
.text:00407715                 push    eax
.text:00407716                 add     esp, 0FFFFFFF0h
.text:00407719                 push    ebx
.text:0040771A                 push    esi
.text:0040771B                 push    edi
.text:0040771C                 mov     eax, ___security_cookie
.text:00407721                 xor     [ebp+ms_exc.registration.ScopeTable], eax
.text:00407724                 xor     eax, ebp
.text:00407726                 push    eax
.text:00407727                 lea     eax, [ebp+ms_exc.registration]
.text:0040772A                 mov     large fs:0, eax
.text:00407730                 mov     [ebp+ms_exc.old_esp], esp
.text:00407733 loc_407733:                             ; CODE XREF: validate_writable_user_addr(x,x)+A2↓j
.text:00407733 ;   __try { // __except at $LN10_1
.text:00407733                 mov     [ebp+ms_exc.registration.TryLevel], 0
.text:0040773A                 push    1               ; Alignment
.text:0040773C                 mov     eax, [ebp+length]
.text:0040773F                 push    eax             ; Length
.text:00407740                 mov     ecx, [ebp+address]
.text:00407743                 push    ecx             ; Address
.text:00407744                 call    ds:__imp__ProbeForWrite@12 ; ProbeForWrite(x,x,x)
.text:00407744 ;   } // starts at 407733
.text:0040774A                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00407751                 jmp     short loc_4077A4
.text:00407753 ; ---------------------------------------------------------------------------
.text:00407753                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:0040775A                 jmp     short loc_40779B
.text:0040775C ; ---------------------------------------------------------------------------
.text:0040775C $LN9_1:                                 ; DATA XREF: .rdata:stru_422C70↓o
.text:0040775C ;   __except filter // owned by 407733
.text:0040775C                 mov     edx, [ebp+ms_exc.exc_ptr]
.text:0040775F                 mov     eax, [edx]
.text:00407761                 mov     ecx, [eax]
.text:00407763                 mov     [ebp+var_1C], ecx
.text:00407766                 mov     eax, 1
.text:0040776B $LN11_2:
.text:0040776B                 retn
.text:0040776C ; ---------------------------------------------------------------------------
.text:0040776C $LN10_1:                                ; DATA XREF: .rdata:stru_422C70↓o
.text:0040776C ;   __except($LN9_1) // owned by 407733
.text:0040776C                 mov     esp, [ebp+ms_exc.old_esp]
.text:0040776F                 cmp     [ebp+var_1C], 80000001h
.text:00407776                 jnz     short loc_407781
.text:00407778                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:0040777F                 jmp     short loc_40779B
.text:00407781 ; ---------------------------------------------------------------------------
.text:00407781 loc_407781:                             ; CODE XREF: validate_writable_user_addr(x,x)+76↑j
.text:00407781                 mov     [ebp+var_20], 0
.text:00407788                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:0040778F                 mov     eax, [ebp+var_20]
.text:00407792                 jmp     short loc_4077A9
.text:00407794 ; ---------------------------------------------------------------------------
.text:00407794                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:0040779B loc_40779B:                             ; CODE XREF:         validate_writable_user_addr(x,x)+5A↑j
.text:0040779B                                         ; validate_writable_user_addr(x,x)+7F↑j
.text:0040779B                 mov     edx, 1
.text:004077A0                 test    edx, edx
.text:004077A2                 jnz     short loc_407733
.text:004077A4 loc_4077A4:                             ; CODE XREF: validate_writable_user_addr(x,x)+51↑j
.text:004077A4                 mov     eax, 1
.text:004077A9 loc_4077A9:                             ; CODE XREF: validate_writable_user_addr(x,x)+92↑j
.text:004077A9                 mov     ecx, [ebp+ms_exc.registration.Next]
.text:004077AC                 mov     large fs:0, ecx
.text:004077B3                 pop     ecx
.text:004077B4                 pop     edi
.text:004077B5                 pop     esi
.text:004077B6                 pop     ebx
.text:004077B7                 mov     esp, ebp
.text:004077B9                 pop     ebp
.text:004077BA                 retn    8
.text:004077BA ; } // starts at 407700

I am now going to use rust instead of C to write windows drivers.
How should I generate similar code with rust?


Rust does not currently support the SEH exception handling mechanism. However, I'd love to have that in Rust and hopefully someone will actually have the motivation to finally write an RFC for it.

1 Like

It sounds like you will have to put the SEH code in a custom C file and call that from Rust.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.