自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

記一次 .NET某工控WPF程序被人惡搞的卡死分析

開發(fā) 前端
主線程通過 GetMessageW 從消息隊(duì)列中拿到了數(shù)據(jù),在處理時(shí)被 coreclr 押解到 WaitSuspendEventsHelper 處等待一個(gè)event事件,接下來看下這個(gè)方法的源碼到底是怎么寫的?

一、背景

1. 講故事

這一期程序故障除了做原理分析,還順帶吐槽一下,熟悉我的朋友都知道我分析dump是免費(fèi)的,但免費(fèi)不代表可以濫用我的寶貴時(shí)間,我不知道有些人故意惡搞卡死是想干嘛,不得而知,希望后面類似的事情越來越少吧!廢話不多說,我們來看看是如何被惡搞的。

二、WinDbg 分析

1. 程序是如何卡死的

既然是窗體程序自然就是看主線程,我們使用 k 命令即可。

0:000> k 
 # Child-SP          RetAddr               Call Site
00 00000036`e1f7da18 00007ffe`70bf30ce     ntdll!NtWaitForSingleObject+0x14
01 00000036`e1f7da20 00007ffd`eff74910     KERNELBASE!WaitForSingleObjectEx+0x8e
...
05 (Inline Function) --------`--------     coreclr!CLREventBase::Wait+0x12 [D:\a\_work\1\s\src\coreclr\vm\synch.cpp @ 412] 
06 00000036`e1f7db20 00007ffd`f00c9afa     coreclr!Thread::WaitSuspendEventsHelper+0xc8 [D:\a\_work\1\s\src\coreclr\vm\threadsuspend.cpp @ 4626] 
07 (Inline Function) --------`--------     coreclr!Thread::WaitSuspendEvents+0x8 [D:\a\_work\1\s\src\coreclr\vm\threadsuspend.cpp @ 4663] 
08 00000036`e1f7dbe0 00007ffd`f0009c80     coreclr!Thread::RareEnablePreemptiveGC+0x7d99a [D:\a\_work\1\s\src\coreclr\vm\threadsuspend.cpp @ 2414] 
09 (Inline Function) --------`--------     coreclr!Thread::EnablePreemptiveGC+0x16 [D:\a\_work\1\s\src\coreclr\vm\threads.h @ 2044] 
0a 00000036`e1f7dc20 00007ffd`f0075d10     coreclr!Thread::RareDisablePreemptiveGC+0xc8 [D:\a\_work\1\s\src\coreclr\vm\threadsuspend.cpp @ 2156] 
0b 00000036`e1f7dca0 00007ffd`f0096a5f     coreclr!JIT_ReversePInvokeEnterRare2+0x18 [D:\a\_work\1\s\src\coreclr\vm\jithelpers.cpp @ 5462] 
0c 00000036`e1f7dcd0 00007ffd`907afe09     coreclr!JIT_ReversePInvokeEnterTrackTransitions+0xaf [D:\a\_work\1\s\src\coreclr\vm\jithelpers.cpp @ 5509] 
0d 00000036`e1f7dd00 00007ffe`72e0e858     0x00007ffd`907afe09
0e 00000036`e1f7dd80 00007ffe`72e0e3dc     user32!UserCallWinProcCheckWow+0x2f8
0f 00000036`e1f7df10 00007ffe`72e20c93     user32!DispatchClientMessage+0x9c
10 00000036`e1f7df70 00007ffe`730f0e64     user32!_fnDWORD+0x33
11 00000036`e1f7dfd0 00007ffe`70b31104     ntdll!KiUserCallbackDispatcherContinue
12 00000036`e1f7e058 00007ffe`72e21c0e     win32u!NtUserGetMessage+0x14
13 00000036`e1f7e060 00007ffe`711e28f2     user32!GetMessageW+0x2e
...
1d 00000036`e1f7e460 00007ffd`f009ba53     xxx!xxx.App.Main+0x5e
...
2a 00000036`e1f7f140 00007ffe`4cd4e1e6     hostfxr!execute_app+0x2fa [D:\a\_work\1\s\src\native\corehost\fxr\fx_muxer.cpp @ 145] 
...
34 00000036`e1f7f890 00000000`00000000     ntdll!RtlUserThreadStart+0x21

從卦中的調(diào)用??梢钥吹?,主線程通過 GetMessageW 從消息隊(duì)列中拿到了數(shù)據(jù),在處理時(shí)被 coreclr 押解到 WaitSuspendEventsHelper 處等待一個(gè)event事件,接下來看下這個(gè)方法的源碼到底是怎么寫的?簡化后如下:

BOOL Thread::WaitSuspendEventsHelper(void)
{
    if (m_State & TS_DebugSuspendPending)
    {

        ThreadState oldState = m_State;

        while (oldState & TS_DebugSuspendPending)
        {

            ThreadState newState = (ThreadState)(oldState | TS_SyncSuspended);

            if (InterlockedCompareExchange((LONG*)&m_State, newState, oldState) == (LONG)oldState)
            {
                result = m_DebugSuspendEvent.Wait(INFINITE, FALSE);
                break;
            }

            oldState = m_State;
        }
    }
    return result != WAIT_OBJECT_0;
}

從上面的代碼可以明顯的看到當(dāng)前Thread 處于 TS_DebugSuspendPending 狀態(tài),從名字上看貌似和調(diào)試有關(guān),接下來查下這個(gè)枚舉的注解。

enum ThreadState
{
    TS_DebugSuspendPending = 0x00000008,    // Is the debugger suspending threads?
}

從注解看是因?yàn)檎{(diào)試器阻塞了這個(gè)線程,我去,哪里來的調(diào)試器呢?這引起了我的巨大興趣。。。

2. 哪里來的調(diào)試器

我剛開始是抱有巨大的善意,我以為他的程序被人惡意注入導(dǎo)致卡死,但分析下來我還是太單純了,繼續(xù)往下看吧,既然有調(diào)試器,一般來說PEB.BeingDebugged=Yes狀態(tài),命令的輸出結(jié)果也得到了證實(shí)。

0:000> !peb
PEB at 00000036e1c11000
    ...
    BeingDebugged:            Yes
    ...
                    Base TimeStamp                     Module
            7ff7f5230000 65310000 Oct 19 18:08:00 2023 G:\xxx\C#\Projects\NugetApplications\Applications\xxx\bin\Debug\net6.0-windows\xxx.exe
            ...

我以為到這里就可以告訴朋友答案,你的程序可能被人惡意注入了,但眼尖的我發(fā)現(xiàn)了一點(diǎn)異常,他的 xxx.exe 啟動(dòng)目錄怎么會(huì)有 \bin\Debug\net6.0-windows\ 呢?很明顯這是用 VS 直接跑起來的呀。。。。

3. 真的是 VS 跑起來的嗎

首先大家要知道 Visual Studio 是托管調(diào)試器,托管調(diào)試器在調(diào)試程序的時(shí)候會(huì)在 coreclr 層面設(shè)置一個(gè)全局變量 g_CORDebuggerControlFlags=0x0200,這也是 Debugger.IsAttached 的底層判斷依據(jù),不相信的朋友可以看下這個(gè)方法的底層實(shí)現(xiàn):

FCIMPL0(FC_BOOL_RET, DebugDebugger::IsDebuggerAttached)
{
    CORDebuggerAttached();
}

inline bool CORDebuggerAttached()
{
    return (g_CORDebuggerControlFlags & DBCF_ATTACHED);
}

enum DebuggerControlFlag
{
    DBCF_ATTACHED                   = 0x0200,
};

有了這些基礎(chǔ)知識(shí)之后,接下來就可以用 x 命令去驗(yàn)證下。

看到上面的答案基本就可以實(shí)錘了,有些朋友可能還是不大相信,我們可以這樣看,VisualStudio 是 WPF 寫的,如果用 VS 來調(diào)試,那么線程棧里面應(yīng)該會(huì)有很多類似的 VisualStudio 字符串。

從卦中看,你說正常發(fā)布的程序怎么可能會(huì)有 9 個(gè) Microsoft.VisualStudio.DesignTools 字符串呢?

4. 這個(gè)dump是如何生成的

這個(gè)問題我相信可能有一些朋友會(huì)比較疑惑,其實(shí)沒什么疑惑的,Visual Studio 有生成Dump的功能,操作步驟為:Debug -> Save Dump As... , 接下來通過一個(gè)小例子觀察一下。

internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"托管調(diào)試器:{Debugger.IsAttached}");
            Console.WriteLine($"非托管調(diào)試器:{IsDebuggerPresent()}");

            Console.ReadLine();
        }

        [DllImport("kernel32.dll")]
        static extern bool IsDebuggerPresent();
    }

調(diào)試起來后,截圖如下:

最后打開生成好的 Dump 文件,使用 kc 觀察主線程的輸出:

0:000> kc
 # Call Site
00 ntdll!NtWaitForSingleObject
01 KERNELBASE!WaitForSingleObjectEx
02 coreclr!CLREventWaitHelper2
03 coreclr!CLREventWaitHelper
04 coreclr!CLREventBase::WaitEx
05 coreclr!CLREventBase::Wait
06 coreclr!Thread::WaitSuspendEventsHelper
07 coreclr!Thread::WaitSuspendEvents
08 coreclr!Thread::RareEnablePreemptiveGC
09 coreclr!Thread::EnablePreemptiveGC
0a coreclr!Thread::RareDisablePreemptiveGC
0b coreclr!Thread::DisablePreemptiveGC
...
19 ConsoleApp4!ConsoleApp4.Program.Main
...
30 ntdll!RtlUserThreadStart

從卦中看,正是停留在 WaitSuspendEventsHelper 函數(shù)里,一摸一樣,徹底被360°無死角的證實(shí)......

三、總結(jié)

這是一次人為的故意惡搞,大概率就是想看下我到底是騾子是馬。我分析的結(jié)果對(duì)他和他所在的公司來說沒有任何價(jià)值,只能白白的浪費(fèi)我的時(shí)間,真是分析多了,什么樣的人都能遇到,謹(jǐn)以此文告知后來者,免費(fèi)但請(qǐng)不要濫用!

責(zé)任編輯:武曉燕 來源: 一線碼農(nóng)聊技術(shù)
相關(guān)推薦

2023-09-27 07:23:10

.NET監(jiān)控軟件

2024-06-06 10:51:15

自動(dòng)化系統(tǒng)推測(cè)

2024-09-14 10:28:56

.NET卡死程序

2024-05-20 09:39:02

.NETurl線程池

2022-10-13 18:40:05

.NETOA后端

2024-07-01 13:00:24

.NET網(wǎng)絡(luò)邊緣計(jì)算

2022-01-17 21:28:36

管理系統(tǒng).NET

2023-05-15 11:15:50

.NET門診語句

2024-11-29 10:06:59

2022-10-09 10:47:37

NET視覺軟件

2024-07-12 11:20:34

.NET崩潰視覺程序

2022-10-25 14:17:01

.NET代碼程序

2023-06-26 00:12:46

2024-12-27 13:31:18

.NETdump調(diào)試

2024-03-28 12:56:36

2023-04-06 10:52:18

2023-03-26 20:24:50

ERP網(wǎng)站系統(tǒng)

2023-07-06 10:11:38

.NET模式dump

2024-03-26 00:44:53

.NETCIM系統(tǒng)

2021-10-27 07:30:32

.NETCPU論壇
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)