Reverse analysis of Windows user layer exception distribution source code

Source: Internet
Author: User

#define DISPOSITION_DISMISS 0#define disposition_continue_search 1#define disposition_nested_exception 2#define Disposition_collided_unwind 3#define eh_noncontinuable 0x01#define eh_unwinding 0x02#define EH_EXIT_UNWIND 0x04# Define Eh_stack_invalid 0x08#define eh_nested_call 0x10#define status_noncontinuable_exception 0xC0000025#define Status_invalid_disposition 0xc0000026#define exception_continue_execution-1#define PAGE_EXEC_MASK (PAGE_EXECUTE| page_execute_read| page_execute_readwrite| page_execute_writecopy) typedef struct _EXCEPTION_RECORD {DWORD exceptioncode; DWORD ExceptionFlags; struct _exception_record *exceptionrecord; VAR_CW PVOID exceptionaddress; DWORD numberparameters; Ulong_ptr exceptioninformation[15];} Exception_record, *pexception_record;typedef struct _exception_registration{struct _exception_registration* pNext; Pexception_handler HANDLER;} Exception_registration, *pexception_registration;typedef struct _vectored_exception_node {LIST_ENTRY ListEntry; Pvectored_exCeption_handler HANDLER;} Vectored_exception_node, *pvectored_exception_node;typedef enum _exception_disposition {ExceptionContinueExecution , Exceptioncontinuesearch, Exceptionnestedexception, exceptioncollidedunwind} exception_disposition;/* 7C97E3FA * * UCHAR logexceptions = 0;/* 7c97e3c0 */list_entry rtlpcalloutentrylist;/* 7c9805e0 */rtl_critical_section Rtlpcalloutentrylock; Rtl_critical_section ldrploaderlock;/* 7c90e47c *//* * User Layer exception Dispatch source */void Kiuserexceptiondispatcher (__in PCONTEXT Contextrecord, __in Pexception_record exceptionrecord) {NTSTATUS Status;//Call the Rtldispatchexception function to distribute the exception. if ( Rtldispatchexception (Contextrecord, ExceptionRecord)) {/* 7c90e48e modify the execution context of the current thread to Whatever the chosen exception handler gives us *//End exception Distribution Status = Zwcontinue (Contextrecord, 0); } else {/* 7c90e49a no exception handler found so re-raise the exception for a debugger or the NT exception handler *// This triggers an exception, and when the last argument is triggered, it passes false, indicating that this is a second triggered exception. Status= Zwraiseexception (ExceptionRecord, Contextrecord, FALSE); }/* 7c90e4a5 build a exception record with bytes on the stack, second chance exception? */Pexception_record exception = (Pexception_record) alloca (0x14); Exception->exceptioncode = Status; Exception->exceptionflags = 1; Exception->exceptionrecord = Contextrecord; Exception->numberparameters = 1; return Rtlraiseexception (exception);} LPVOID Rtlpgetregistrationhead () {_asm mov eax, fs:[0] _asm ret}/* 7c92a970 If the exception is handled returns True */boolean rtldispatchexception ( PCONTEXT Contextrecord, Pexception_record exceptionrecord) {BOOLEAN ret = 0; LPVOID StackBase, Stacklimit; Pexception_registration Head; DWORD Kprocess_flags; DWORD Dispatch, highest; Exception_record Exrec; The exception is first given to veh processing. If able to handle, end exception distribution if (Rtlcallvectoredexceptionhandlers (ExceptionRecord, Contextrecord)) {/* 7c95010a */ret = 1;} else {/* Otherwise hand over to SEH processing */* 7c92a991 */rtlpgetstacklimits (&stacklimit, &stackbase); Get the Seh Link header node/* 7c92a99f */head = (Pexception_registration) Rtlpgetregistrationhead (); highest = 0; while (head! = (pexception_registration)-1) {//determines if the address of the obtained node is correct if (Head < Stacklimit | | head + sizeof (Exception_reg istration) > StackBase | | Head & 3) {exceptionrecord->exceptionflags |= eh_stack_invalid; goto exit;}//Determine if the address of the exception handler is correct if (Head->handl Er >= stacklimit && head->handler < stackbase) {exceptionrecord->exceptionflags |= EH_STACK_INVALID ; Goto exit; }//To determine if the exception handler is a valid handling function if (! Rtlisvalidhandler (Head->handler)) {/* 7c92a336 */exceptionrecord->exceptionflags |= EH_STACK_INVALID; Goto exit ; } else if (logexceptions) {/* 7c950113 */Rtlplogexceptionhandler (Contextrecord, ExceptionRecord, 0, head, 0x10);}//Execute Seh's _except_handler4 () Hret = Rtlpexecutehandlerforexception (Contextrecord, head, ExceptionRecord, &dispatch, Head->handler); if (logexceptions) {/* 7c950129 there is a second parameter to this function that I don ' t understand yet */Rtlploglastex CeptIondisposition (highest, Hret); }/* 7C92AA1E */if (head = = NULL) {exceptionrecord->exceptionflags &= ~eh_nested_call;}/* 7C92AA27 * * if (hret = = Disposition_dismiss) {if (Exceptionrecord->exceptionflags & eh_noncontinuable) {/* 7c950181 */ExRec.Exceptio NCode = status_noncontinuable_exception; Exrec.exceptionflags = eh_noncontinuable; Exrec.exceptionrecord = ExceptionRecord; exrec.numberparameters = 0; Rtlraiseexception (&AMP;EXREC); /* 7c92a31c a little fudging with this block */if (Exceptionrecord->exceptionflags & eh_stack_invalid) {goto exit ; }} else {/* 77EDBD64 */ret = 1; break;}} If the SEH filter function returns a search for other filtering functions to process the else if (Hret = = Disposition_continue_search) {/* 7c92a31c a little fudging with the this block */ if (Exceptionrecord->exceptionflags & eh_stack_invalid) {goto exit;}} else if (Hret = = disposition_nested_exception) {/* 7c950169 */exceptionrecord->exceptionflags |= EH_NESTED_CALL; if ( Dispatch > Highest) {highest = dispatch;}} else {/* 7c950147 */exrec.exceptioncode = status_invalid_disposition; exrec.exceptionflags = eh_noncontinuable; ExRec.E Xceptionrecord = ExceptionRecord; exrec.numberparameters = 0; Rtlraiseexception (&AMP;EXREC); }/* 7c92a326 */head = head->pnext; }}exit:/* 7c92aa43 */return ret; /* 7c92a934 *///call Veh function Boolean rtlcallvectoredexceptionhandlers (Pexception_record ExceptionRecord, PCONTEXT Contextrecord) {BOOLEAN ret = FALSE; struct {Pexception_record erec; PCONTEXT CRec; } Rec; Pvectored_exception_node Veh; Pvectored_exception_handler HANDLER; DWORD disposition if (Rtlpcalloutentrylist.flink = = &rtlpcalloutentrylist) {return FALSE;} Erec = ExceptionRecord; CRec = ExceptionRecord; Enter the critical Zone rtlentercriticalsection (&rtlpcalloutentrylock); Start traversing Veh's doubly linked list for (Veh = (pvectored_exception_node) rtlpcalloutentrylist.flink); Veh! = (pvectored_exception_node) rtlpcalloutentrylist; Veh = (pvectored_exception_node) veh->listentry.flink) {//decryption handler Address handler = Rtldecodepointer (Veh->handler); Call handler function disposition = handler (&AMP;REC); Determines whether the handler handles the exception. If yes, the loop ends. If not, continue to find the next handler function. if (disposition = = exception_continue_execution) {//sets the return value to true. ret = 1; break;}} Leaving the critical section rtlleavecriticalsection (&rtlpcalloutentrylock); return ret;} /* 7C9033DC */void rtlpgetstacklimits (lpvoid **stacklimit, lpvoid **stackbase) {pteb teb = _teb;//fs:18h *StackLimit = teb->nttib->stacklimit; *stackbase = teb->nttib->stackbase; return;} /* 7c92aa50 */boolean Rtlisvalidhandler (Pexception_handler HANDLER) {DWORD TABLE_SZ; LPVOID safeseh_table, base_addr; DWORD ret, Result_len, exec_flags, High, low; Memory_basic_information MBI; safeseh_table = rtllookupfunctiontable (Handler, &AMP;BASE_ADDR, &AMP;TABLE_SZ); if (safeseh_table = = NULL | | table_sz = = 0) {/* 7c9500d1 processexecuteflags*/if (zwqueryinformationprocess (INVALID_HAND Le_value, &exec_flags, 4, NULL) >= 0) {/* 7c92cf94 0x10 = executedispatchenable */if (! ( Exec_flags & 0x10)) { return 1; }}/* 7c935e8e * * if (ntqueryvirtualmemory (Invalid_handle_value, Handler, NULL, &mbi, sizeof (memory_basic_ Information), &result_len) < 0) {return 1;}/* 7C935EA9 */if (!) ( MBi. Protect & Page_exec_mask) {rtlinvalidhandlerdetected (handler,-1,-1); return 0;} else if (MBI. Type! = sec_image) {return 1;} Rtlcaptureimageexceptionvalues (MBI. Allocationbase, &safeseh_table, &AMP;TABLE_SZ); /* 7C935ED0 */if (var_10 = = NULL | | table_sz = = 0) {return 1;} return 0; } else if (safeseh_table = = (LPVOID)-1 && TABLE_SZ = = 1) {return 0;}/* 7C9500A6 */if (TABLE_SZ < 0) {RTL Invalidhandlerdetected (Handler, safeseh_table, TABLE_SZ); return 0; } rel_addr = handler-base_addr; High = TABLE_SZ; Low = 0; /* 7c9500b1 binary search through SafeSEH table */do {idx = (high + low)/2; if (Rel_addr < Safeseh_table[idx]) {if (idx = = 0) {rtlinvalidhandlerdetected (handler, safeseh_table, TABLE_SZ); return 0;} High = idx-1; if (High < low) {RTLINVAlidhandlerdetected (Handler, safeseh_table, TABLE_SZ); return 0; }} else if (Rel_addr > Safeseh_table[idx]) {low = idx + 1; if (High < low) {rtlinvalidhandlerdetected (handler, SA Feseh_table, TABLE_SZ); return 0; }} else {break;}} while (1); return 1;} /* 7C92AAA4 */lpvoid rtllookupfunctiontable (Pexception_handler HANDLER, DWORD *base_addr, DWORD *TABLE_SZ) {MEMORY_ Basic_information MBI; LPVOID Safeseh_table, Base; if (Ldrpinldrinit && rtltryentercriticalsection (&ldrploaderlock) = = 0) {/* 7c92dd29 3 = Memorybasicvlminform ation */if (Ntqueryvirtualmemory ((HANDLE)-1, Handler, 3, &mbi, sizeof (memory_basic_information), NULL) < 0) {RET Urn NULL; } else if (MBI. Type! = sec_image) {return NULL;} base = MBi. baseaddress; /* 7C92DD51 */rtlcaptureimageexceptionvalues (base, &safeseh_table, TABLE_SZ); } else {if (_teb! = NULL) {/* 7c92aad9 * * Pldr_module node = _peb->ldr->inloadordermodulelist.flink if (_peb->l Dr! = 0 && Node! = NULL) {WHIle (Node! = &_peb->ldr->inloadordermodulelist) {/* 7C92AB00 */if (handler < NODE-&GT;BASEADDR) {node = no de->inloadordermodulelist.flink; Continue } if (handler >= node->baseaddr + node->sizeofimage) {node = node->inloadordermodulelist.flink; continue;}/ * 7C92AB14 */base = node->baseaddr; Rtlcaptureimageexceptionvalues (base, &safeseh_table, TABLE_SZ); if (safeseh_table = = NULL && ntdllbase! = null && (base = Rtlntimageheader (ntdllbase)) = null) {if (head Er > Base && Header < base + ((Pimage_nt_header) base)->optionalheaders.sizeofimage) {/* 7c950d7d */RTL Captureimageexceptionvalues (base, &safeseh_table, TABLE_SZ); }} break; }}}/* 7C92AB2C */if (ldrpinldrinit) {rtlleavecriticalsection (&ldrploaderlock);}} *base_addr = base; return safeseh_table;}

Reverse analysis of Windows user layer exception distribution source code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.