日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

記一次 .NET某防偽驗證系統崩潰分析

來源: 責編: 時間:2024-03-28 17:49:15 204觀看
導讀一、背景1. 講故事昨晚給訓練營里面的一位朋友分析了一個程序崩潰的故障,因為看小伙子昨天在群里問了一天也沒搞定,干脆自己親自上陣吧,抓取的dump也是我極力推薦的用 procdump 注冊 AEDebug 的方式,省去了很多溝通成本。

一、背景

1. 講故事

昨晚給訓練營里面的一位朋友分析了一個程序崩潰的故障,因為看小伙子昨天在群里問了一天也沒搞定,干脆自己親自上陣吧,抓取的dump也是我極力推薦的用 procdump 注冊 AEDebug 的方式,省去了很多溝通成本。L6228資訊網——每日最新資訊28at.com

二、WinDbg分析

1. 為什么會崩潰

windbg有一個非常強大的點就是當你雙擊打開后,會自動幫你切換到崩潰的線程以及崩潰處的匯編代碼,省去了 !analyze -v 命令的龜速輸出,參考信息如下:L6228資訊網——每日最新資訊28at.com

...................................................................................................................This dump file has an exception of interest stored in it.The stored exception information can be accessed via .ecxr.(10f4.f58): Access violation - code c0000005 (first/second chance not available)For analysis of this file, run !analyze -veax=00000000 ebx=00000000 ecx=00000040 edx=00000000 esi=004c1b98 edi=07a8ed4ceip=7008508f esp=07a8ec74 ebp=07a8ec80 iopl=0         nv up ei pl zr na pe nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246clr!Thread::GetSafelyRedirectableThreadContext+0x7c:7008508f 8038eb          cmp     byte ptr [eax],0EBh        ds:002b:00000000=??...

從卦中可以看到,當前崩潰是因為 eax=0 導致的,那為什么 eax 等于 0 呢?要想尋找這個答案,需要觀察崩潰前的線程棧上下文,可以使用命令 .ecxr;k 9 即可。L6228資訊網——每日最新資訊28at.com

0:009> .ecxr;k 9eax=00000000 ebx=00000000 ecx=00000040 edx=00000000 esi=004c1b98 edi=07a8ed4ceip=7008508f esp=07a8ec74 ebp=07a8ec80 iopl=0         nv up ei pl zr na pe nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246clr!Thread::GetSafelyRedirectableThreadContext+0x7c:7008508f 8038eb          cmp     byte ptr [eax],0EBh        ds:002b:00000000=?? # ChildEBP RetAddr      00 07a8ec80 6fe7f6cd     clr!Thread::GetSafelyRedirectableThreadContext+0x7c01 07a8f030 6fe7f2f3     clr!Thread::HandledJITCase+0x3102 07a8f0a4 6fee23da     clr!Thread::SuspendRuntime+0x26003 07a8f184 6fedf72d     clr!WKS::GCHeap::SuspendEE+0x1fe04 07a8f1b0 6fe309ca     clr!WKS::GCHeap::GarbageCollectGeneration+0x16805 07a8f1c0 6fe30a2e     clr!WKS::GCHeap::GarbageCollectTry+0x5606 07a8f1e4 6fe30a90     clr!WKS::GCHeap::GarbageCollect+0xa507 07a8f230 6f058b01     clr!GCInterface::Collect+0x5d08 07a8f26c 055fa4b1     mscorlib_ni+0x3b8b01

從卦中信息看,尼瑪,真無語了 GCInterface::Collect 說明有人用 GC.Collect() 手工觸發GC,不知道為什么要這么做來污染GC內部的統計信息,不管怎么說這個肯定不是崩潰的原因。L6228資訊網——每日最新資訊28at.com

2. GC正在干什么

我們繼續觀察線程棧,可以看到它的邏輯大概是這樣的,通過 SuspendRuntime 把所有的托管線程進行邏輯上暫停,在暫停其中的一個線程時拋出了異常。L6228資訊網——每日最新資訊28at.com

稍微提醒一下,這個 HandledJITCase 方法是用 ip 劫持技術將代碼引入到 coreclr 中進行 GC完成等待,這種神操作有些殺毒軟件會認為是病毒!!!L6228資訊網——每日最新資訊28at.com

有些朋友肯定會說,有沒有代碼支撐。。。這里我就找一下 coreclr 的源碼貼一下吧。L6228資訊網——每日最新資訊28at.com

void ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason){ while ((thread = ThreadStore::GetThreadList(thread)) != NULL) {  ...  if (workingOnThreadContext.Acquired() && thread->HandledJITCase())  {   ...  }  ... }}

結合源碼分析思路就非常清晰了,這里的 thread->HandledJITCase() 中的 thread 到底是哪一個線程?可以觀察 kb 輸出然后用 !t 去做比對。L6228資訊網——每日最新資訊28at.com

圖片圖片L6228資訊網——每日最新資訊28at.com

從卦中看,當前 GC 正在 Suspend 主線程,并且還看到了主線程有一個 System.AccessViolationException 異常,無語了。。。L6228資訊網——每日最新資訊28at.com

3. 主線程到底怎么了

主線程進入到視野之后,那就重點關注一下它,可以用 k 看一下輸出。L6228資訊網——每日最新資訊28at.com

0:009> ~0seax=00000000 ebx=0029ea50 ecx=0029ea90 edx=00000000 esi=7efdb800 edi=000d0000eip=00000000 esp=0029ea4c ebp=75146381 iopl=0         nv up ei pl nz na po nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=0021020200000000 ??              ???0:000> k00 75146381 7efdb800     0x001 75146381 7517fa04     0x7efdb80002 0029ea80 7736013a     user32!__fnHkINLPKBDLLHOOKSTRUCT+0x2803 0029eae4 7514908d     ntdll!KiUserCallbackDispatcher+0x2e04 0029eae4 076e3912     user32!CallNextHookEx+0x8405 0029eb28 076e3064     0x76e391206 0029eb5c 0011d48f     xxx!xxx.ScanerHook.KeyboardHookProc+0xe407 0029eb8c 75146381     0x11d48f08 0029eba8 7517fa04     user32!DispatchHookW+0x3809 0029ebd8 7736013a     user32!__fnHkINLPKBDLLHOOKSTRUCT+0x280a 0029ec3c 751406eb     ntdll!KiUserCallbackDispatcher+0x2e0b 0029ec3c 75140751     user32!_PeekMessage+0x880c 0029ec68 6d8af3bf     user32!PeekMessageW+0x108...

從卦象看,這卦非常奇怪,有如下兩點信息:L6228資訊網——每日最新資訊28at.com

  • eip=00000000,這個很無語,線程已經瘋了
  • KeyboardHookProc ,居然有鍵盤鉤子

熟悉 eip 的朋友應該知道,它相當于一輛車的方向盤,一輛高速行駛的車突然沒了方向盤,真的太可怕了,最后必然車毀人亡。L6228資訊網——每日最新資訊28at.com

4. 是 eip=0 導致的崩潰嗎

在匯編中是因為eax=0導致,而這里eip恰好也等于0,仿佛冥冥之中自有牽連,帶著強烈的好奇心我們來反匯編下 GetSafelyRedirectableThreadContext 方法邏輯,簡化后如下:L6228資訊網——每日最新資訊28at.com

0:000> uf 7008508fclr!Thread::GetSafelyRedirectableThreadContext:6fe7f60e 55              push    ebp6fe7f60f 8bec            mov     ebp,esp6fe7f611 53              push    ebx6fe7f612 56              push    esi6fe7f613 57              push    edi6fe7f614 8bf1            mov     esi,ecx...7008506d ffe9            jmp     rcx7008506f fd              std70085070 c1daff          rcr     edx,0FFh70085073 f6450801        test    byte ptr [ebp+8],170085077 0f84efa5dfff    je      clr!Thread::GetSafelyRedirectableThreadContext+0xcc (6fe7f66c)7008507d 8b8604010000    mov     eax,dword ptr [esi+104h]70085083 3987b8000000    cmp     dword ptr [edi+0B8h],eax70085089 0f85dda5dfff    jne     clr!Thread::GetSafelyRedirectableThreadContext+0xcc (6fe7f66c)7008508f 8038eb          cmp     byte ptr [eax],0EBh

從上面的匯編代碼看eax的取值鏈條是: eax <- esi+104h <- ecx ,很顯然這里的 ecx 是 thiscall 協議中的 Thread=004c1b98 參數,可以用 dp 驗證下。L6228資訊網——每日最新資訊28at.com

0:000> dp 004c1b98+0x104 L1004c1c9c  00000000

從卦中看果然是 0,有些朋友好奇這個 104 偏移到底是個什么東西,參考 coreclr 源碼其實就是 m_LastRedirectIP 字段,參考如下:L6228資訊網——每日最新資訊28at.com

BOOL Thread::GetSafelyRedirectableThreadContext(DWORD dwOptions, CONTEXT* pCtx, REGDISPLAY* pRD){    if (!EEGetThreadContext(this, pCtx))    {        return FALSE;    }    ...  if (GetIP(pCtx) == m_LastRedirectIP) {  const BYTE short_jmp = 0xeb;  const BYTE self = 0xfe;  BYTE* ip = (BYTE*)m_LastRedirectIP;  if (ip[0] == short_jmp && ip[1] == self)   m_LastRedirectIP = 0;  return FALSE; }}

結合匯編代碼其實我們崩潰在 ip[0] == short_jmp 這一句上,仔細分析上面的C++代碼會發現一個很奇怪的信息,那就是為什么 GetIP(pCtx)= 0,接下來用 dt 觀察下寄存器上下文。L6228資訊網——每日最新資訊28at.com

0:009> kb 2 # ChildEBP RetAddr      Args to Child              00 07a8ec80 6fe7f6cd     00000003 07a8ed4c 07a8ecf0 clr!Thread::GetSafelyRedirectableThreadContext+0x7c01 07a8f030 6fe7f2f3     004c1b98 0b367326 76a016a1 clr!Thread::HandledJITCase+0x310:009> dt _CONTEXT 07a8ed4cntdll!_CONTEXT   +0x000 ContextFlags     : 0x10007   ...   +0x01c FloatSave        : _FLOATING_SAVE_AREA   +0x08c SegGs            : 0x2b   +0x090 SegFs            : 0x53   +0x094 SegEs            : 0x2b   +0x098 SegDs            : 0x2b   +0x09c Edi              : 0xd0000   +0x0a0 Esi              : 0x7efdb800   +0x0a4 Ebx              : 0x29ea50   +0x0a8 Edx              : 0   +0x0ac Ecx              : 0x29ea90   +0x0b0 Eax              : 0   +0x0b4 Ebp              : 0x75146381   +0x0b8 Eip              : 0   +0x0bc SegCs            : 0x23   +0x0c0 EFlags           : 0x210202   +0x0c4 Esp              : 0x29ea4c   ...

從卦中看果然 eip=0,這是一個非常錯誤的信息,還有一點就是 m_LastRedirectIP 字段一般用來處理一些比較詭異的兼容性問題,所以這里兩個字段都是 0 導致崩潰的產生。L6228資訊網——每日最新資訊28at.com

有了上面的信息,我們就知道了前因后果,原來是主線程車毀人亡(eip=0),導致GC無法暫停它,在內部拋出了代碼異常,你可以說是 CLR 的bug,也可以說是主線程的Bug,所以給到的解決方案就是:L6228資訊網——每日最新資訊28at.com

  1. 屏蔽掉 鍵盤鉤子 的業務邏輯,肯定是它造成的。
  2. 不去掉的話,要重點觀察 鍵盤盤子 ,是否是代碼改動引發的。

三、總結

說實話要想解釋這個程序為什么會崩潰,需要分析者對GC的SuspendRuntime運作邏輯有一定的了解,否則真抓瞎了,所以.NET調試訓練營中的GC理論知識一定是分析這些 dump 的基石。L6228資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-80192-0.html記一次 .NET某防偽驗證系統崩潰分析

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 負載均衡原理最全詳解

下一篇: vivo 消息中間件測試環境項目多版本實踐

標簽:
  • 熱門焦點
  • 官方承諾:K60至尊版將會首批升級MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版將會搭載天璣9200+處理器和獨顯芯片X7的同時,Redmi給出了官方承諾,K60至尊重大更新首批升級,會首批推送MIUI 15。也就是說雖然
  • 小米官宣:2023年上半年出貨量中國第一!

    今日早間,小米電視官方微博帶來消息,稱2023年小米電視上半年出貨量達到了中國第一,同時還表示小米電視的巨屏風暴即將開始。“公布一個好消息2023年#小米電視上半年出貨量中國
  • 學習JavaScript的10個理由...

    作者 | Simplilearn編譯 | 王瑞平當你決心學習一門語言的時候,很難選擇到底應該學習哪一門,常用的語言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • Python異步IO編程的進程/線程通信實現

    這篇文章再講3種方式,同時講4中進程間通信的方式一、 Python 中線程間通信的實現方式共享變量共享變量是多個線程可以共同訪問的變量。在Python中,可以使用threading模塊中的L
  • ESG的面子與里子

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之三伏大幕拉起,各地高溫預警不絕,但處于厄爾尼諾大&ldquo;烤&rdquo;之下的除了眾生,還有各大企業發布的ESG報告。ESG是&ldquo;環境保
  • 華為Mate60標準版細節曝光:經典星環相機模組回歸

    這段時間以來,關于華為新旗艦的爆料日漸密集。據此前多方爆料,今年華為將開始恢復一年雙旗艦戰略,除上半年推出的P60系列外,往年下半年的Mate系列也將
  • 2299元起!iQOO Pad明晚首銷:性能最強天璣平板

    5月23日,iQOO如期舉行了新品發布會,除了首發安卓最強旗艦處理器的iQOO Neo8系列新機外,還在發布會上推出了旗下首款平板電腦——iQOO Pad,其最大的賣點
  • OPPO Reno10 Pro英雄聯盟定制禮盒公布:薩勒芬妮同款配色夢幻十足

    5月24日,OPPO推出了全新的OPPO Reno 10系列,包含OPPO Reno10、OPPO Reno10 Pro和OPPO Reno10 Pro+三款新機,全系標配了超光影長焦鏡頭,是迄今為止拍照
Top 主站蜘蛛池模板: 海口市| 浦城县| 广灵县| 西乌珠穆沁旗| 兴隆县| 平陆县| 涿鹿县| 冕宁县| 阿坝| 法库县| 临西县| 崇信县| 彝良县| 盘山县| 张家口市| 永胜县| 马关县| 房产| 神农架林区| 新乡县| 板桥市| 富川| 集安市| 龙井市| 湛江市| 仪陇县| 伊通| 景洪市| 遂溪县| 包头市| 鄂托克前旗| 江川县| 随州市| 奉新县| 长治市| 梧州市| 女性| 钦州市| 定日县| 溧阳市| 夏河县|