逆向分析windows使用者層異常分發源碼

來源:互聯網
上載者:User

標籤:win

#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 *//* * 使用者層的異常派發源頭 */VOID KiUserExceptionDispatcher(__in PCONTEXT ContextRecord, __in PEXCEPTION_RECORD ExceptionRecord) { NTSTATUS Status; // 調用RtlDispatchException函數去派發異常. if (RtlDispatchException(ContextRecord, ExceptionRecord)) { /* 7C90E48E modify the execution context of the current thread to whatever the chosen exception handler gives us */ // 結束異常分發 Status = ZwContinue(ContextRecord, 0); } else { /* 7C90E49A no exception handler found so re-raise the exception for a debugger or the NT exception handler */ // 在此觸發一個異常, 並觸發時最後一個參數傳FALSE,表明這是一個第二次觸發的異常. Status = ZwRaiseException(ExceptionRecord, ContextRecord, FALSE); } /* 7C90E4A5 build an exception record with 20 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 如果異常被處理返回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; // 先將異常交給VEH處理. 如果能夠處理,則結束異常分發 if (RtlCallVectoredExceptionHandlers(ExceptionRecord, ContextRecord)) { /* 7C95010A */ ret = 1; } else { /* 否則交給SEH處理 */ /* 7C92A991 */ RtlpGetStackLimits(&StackLimit, &StackBase); // 擷取SEH鏈表前端節點 /* 7C92A99F */ head = (PEXCEPTION_REGISTRATION)RtlpGetRegistrationHead(); highest = 0; while (head != (PEXCEPTION_REGISTRATION) -1) { // 判斷擷取出來的節點的地址是否正確 if (head < StackLimit || head + sizeof(EXCEPTION_REGISTRATION) > StackBase || head & 3) { ExceptionRecord->ExceptionFlags |= EH_STACK_INVALID; goto exit; } // 判斷異常處理函數的地址是否正確 if (head->handler >= StackLimit && head->handler < StackBase) { ExceptionRecord->ExceptionFlags |= EH_STACK_INVALID; goto exit; } // 判斷異常處理函數是否為有效處理函數 if (!RtlIsValidHandler(head->handler)) { /* 7C92A336 */ ExceptionRecord->ExceptionFlags |= EH_STACK_INVALID; goto exit; } else if (LogExceptions) { /* 7C950113 */ RtlpLogExceptionHandler(ContextRecord, ExceptionRecord, 0, head, 0x10); } // 執行SEH的 _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 */ RtlpLogLastExceptionDisposition(highest, hret); } /* 7C92AA1E */ if (head == NULL) { ExceptionRecord->ExceptionFlags &= ~EH_NESTED_CALL; } /* 7C92AA27 */ if (hret == DISPOSITION_DISMISS) { if (ExceptionRecord->ExceptionFlags & EH_NONCONTINUABLE) { /* 7C950181 */ exRec.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; exRec.ExceptionFlags = EH_NONCONTINUABLE; exRec.ExceptionRecord = ExceptionRecord; exRec.NumberParameters = 0; RtlRaiseException(&exRec); /* 7C92A31C a little fudging with this block */ if (ExceptionRecord->ExceptionFlags & EH_STACK_INVALID) { goto exit; } } else { /* 77EDBD64 */ ret = 1; break; } } // 如果SEH過濾函數返回的是搜尋其它過濾函數處理 else if (hret == DISPOSITION_CONTINUE_SEARCH) { /* 7C92A31C a little fudging with 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.ExceptionRecord = ExceptionRecord; exRec.NumberParameters = 0; RtlRaiseException(&exRec); } /* 7C92A326 */ head = head->pNext; } }exit: /* 7C92AA43 */ return ret;}/* 7C92A934 */// 調用VEH函數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; // 進入臨界區 RtlEnterCriticalSection(&RtlpCalloutEntryLock); // 開始遍曆VEH的雙向鏈表 for (veh = (PVECTORED_EXCEPTION_NODE) RtlpCalloutEntryList.Flink); veh != (PVECTORED_EXCEPTION_NODE) RtlpCalloutEntryList; veh = (PVECTORED_EXCEPTION_NODE) veh->ListEntry.Flink) { // 解密處理函數地址 handler = RtlDecodePointer(veh->handler); // 調用處理函數 disposition = handler(&Rec); // 判斷處理函數是否處理了異常.如果是則結束迴圈. // 如果沒有,則繼續找到下一個處理函數. if (disposition == EXCEPTION_CONTINUE_EXECUTION) { // 將傳回值設定為TRUE. ret = 1; break; } } // 離開臨界區 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, &base_addr, &table_sz); if (safeseh_table == NULL || table_sz == 0) { /* 7C9500D1 ProcessExecuteFlags*/ if (ZwQueryInformationProcess(INVALID_HANDLE_VALUE, 22, &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, &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) { RtlInvalidHandlerDetected(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, safeseh_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 = MemoryBasicVlmInformation */ if (NtQueryVirtualMemory((HANDLE) -1, handler, 3, &mbi, sizeof(MEMORY_BASIC_INFORMATION), NULL) < 0) { return 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->Ldr != 0 && node != NULL) { while (node != &_PEB->Ldr->InLoadOrderModuleList) { /* 7C92AB00 */ if (handler < node->BaseAddr) { node = node->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 (header > base && header < base + ((PIMAGE_NT_HEADER) base)->OptionalHeaders.SizeOfImage) { /* 7C950D7D */ RtlCaptureImageExceptionValues(base, &safeseh_table, table_sz); } } break; } } } /* 7C92AB2C */ if (LdrpInLdrInit) { RtlLeaveCriticalSection(&LdrpLoaderLock); } } *base_addr = base; return safeseh_table;}

逆向分析windows使用者層異常分發源碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.