1、今天拿到一个比较有意思的dmp,分析之余觉得有趣,撰文以分享。
2、分析过程
2.1、step1:Windbg打开,.exr -1看了下异常记录里所呈现的信息,如下:
ExceptionAddress: 5d38a57f ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000008 Parameter[1]: 5d38a57f Attemptto execute non-executable address 5d38a57f
上边标红的两行,第一行的意思是说“访问异常”,基本就是访问了不该访问的内存,比如处于Free状态的内存;或者是该内存是只读的,却往里边写数据了;第二行的意思是说,代码执行了不可执行的部分,换句话说就是EIP跑飞了;当然这个第二行的提示文本是Windbg善解人意的自动推导出来辅助你分析的,可能对也可能不对;且看下边继续分析;
2.2、step2:看一下5d38a57f附近的代码:
0: 045> u 5d38a57f 5d38a57f ?? ??? ^ Memory access error in ‘u 5d38a57f’
咋回事,咋都是些’??’,嗯,正常的,一种情况是这块内存没有被dmp下来,所以Windbg去反汇编这块内存的时候,找不到数据;另一种情况是这块内存本身就是Free的;来看下这块内存的属性如下:
0: 045> !address 5d38a57f Usage: Free BaseAddress: 5d0a6000 EndAddress: 62670000 RegionSize: 055ca000 ( 85.789 MB) State: 00010000 MEM_FREE Protect: 00000001 PAGE_NOACCESS Type: <info not present at the target>
看来是第二种情况了;线索断了,不急再看看其他的地方,说不定山重水复疑无路,柳暗花明又一村嘞;
2.3、step3:下面就是将上下文恢复到出现问题[异常]时的那会了;执行.ecxr即可;
0:045> .ecxr eax=00001000 ebx=04f015a8 ecx=9a27e8a0 edx=00000000 esi=04f015c6 edi=04f015b0 eip=5d38a57f esp=18a3fe1c ebp=18a3fe64 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202 5d38a57f ?? ???
简单分析下上边所给出的信息;触发异常的显然就是这句汇编代码了,触发的原因也自然是5d38a57f这块内存是PAGE_NOACCESS,而你却Execute了,不挂才怪?这块内存属于谁?看下内存分布,如下:
5c8d00005c8e8000 dxva2 (deferred) 5d0a00005d0a6000 d3d8thk (deferred) 62670000626b7000 Qt5OpenGL (deferred) 641500006458e000 Qt5Widgets (deferred) 68bb000068bc4000 msacm32_68bb0000 (deferred) 6a6900006a697000 midimap (deferred) 6a6a00006a6a8000 msacm32 (deferred) 6bbc00006bbf1000 EhStorShell (deferred)
上图标蓝的两行最接近5d38a57f了,接近归接近,终究还是不属于任何模块,这就奇怪了。好好的EIP咋就跑的乱七八糟的了。看下调用栈吧,如下:
0: 045> k # ChildEBP RetAddr 0018a3fe18 013e5c4e 0x5d38a57f 0118a3fe64 013e5d5b aaaa!bbbb::waveOut+0x1fe 0218a3fe6c 74bb343d aaaa!bbbb::waveOutRoutine+0xb 0318a3fe78 77179812 kernel32!BaseThreadInitThunk+0xe 0418a3feb8 771797e5 ntdll!__RtlUserThreadStart+0x70 0518a3fed0 00000000 ntdll!_RtlUserThreadStart+0x1b
0: 045> ub 013e5c4eaaaa!bbbb: :waveOut+0x1e1013e5c31ff30 push dword ptr [eax]013e5c33ffb3a4000000 push dword ptr [ebx+0A4h]013e5c39e8d2020000 call start_for_wegame!fifo_read (013e5f10)013e5c3e83c410 add esp,10h013e5c416a20 push 20h013e5c43ff75f8 push dword ptr [ebp-8]013e5c46ff37 push dword ptr [edi]013e5c48ff15fc914101 call dword ptr [aaaa!_imp__waveOutWrite (014191fc)]
逻辑很清晰,是我们的exe调用了waveOutWrite;这个API是 Winmm.dll中的,是系统的API,难道这个系统的API不够健壮,有bug?传入的错误的参数,其又没有很严格的校验?确实有这可能,但可能性微乎其微,你要学会相信微软啊;好了来看下传入的参数都是啥:
0018a3fe18 013e5c4e 0bd84180 04f015e6 000000200x5d38a57f0118a3fe64 013e5d5b 18a3fe78 74bb343d 0bd83ed0 aaaa!bbbb::waveOut+ 0x1fe 0218a3fe6c 74bb343d 0bd83ed0 18a3feb8 77179812aaaa!bbbb::waveOutRoutine+ 0xb
0: 045> dd 04f015e6 04f015e6 04808e8800001000000000000000000004f015f6 0000000300000000000000000000007b
整理如下:
typedefstruct wavehdr_tag{LPSTRlpData; 04808e88DWORDdwBufferLength; 00001000DWORDdwBytesRecorded; 00000000DWORD_PTRdwUser; 00000000DWORDdwFlags; 00000003 #define WHDR_DONE | WHDR_PREPAREDDWORDdwLoops; 00000000structwavehdr_tag *lpNext; 00000000DWORD_PTRreserved; 0000007b}WAVEHDR, *LPWAVEHDR;
参数都很正常,那咋回事呢?不妨到这个API里边去看下,看看总归还是可以的;
2.4、step4:核心分析
0: 045> u Winmm!waveOutWritewinmm!waveOutWrite: 70ad4f7be990d5c892 jmp SBH+0x2510 (03762510)70ad4f8056 push esi70ad4f818b750c mov esi,dword ptr [ebp+0Ch]70ad4f846a01 push 170ad4f86ff7510 push dword ptr [ebp+10h]70ad4f8956 push esi70ad4f8ae8c2f9ffff call winmm!ValidateHeader (70ad4951)70ad4f8f85c0 test eax,eax
有意思了,很有意思;正常的API的开头几个字节的反汇编代码通常是:
movedi,edi ;hot patch会用到
而这里居然是一个jmp指令,那就说明这里有鬼了,根据给出的跳转目的地址可知,是跑到SBH这个模块里去了;不妨看一下跳转的那块内存的汇编代码,简单看下他在干啥:
0: 045> u 03762510SBH+ 0x2510: 03762510?? ??? ^ Memory access error in‘u 03762510’
没有数据,这是个minidmp,里边的数据有限;那没办法了,只能归因于该crash是由于第三方软件的bug导致的了;但是,我们还有另一条路可走,来看看这个模块是啥,有哪些信息可获取到,如下:
0 :045> lmvmSBHstartendmodulename03760000 0379 d000SBHT( nosymbols) Loadedsymbolimagefile: SBH.dllImagepath: E:迅雷下载 LetasoftSoundBoosterSBH.dllImagename: SBH.dllBrowseallglobalsymbolsfunctionsdataTimestamp: FriOct19 00 :43:472012 (508031 C3) CheckSum: 0004 A8A2ImageSize: 0003 D000Fileversion: 1 .1.0.88Productversion: 1 .1.0.88Fileflags: 0 ( Mask3 F) FileOS: 40004 NTWin32Filetype: 2 .0DllFiledate: 00000000 .00000000Translations: 0000 .04b00000 .04e40409 .04b00409 .04e4Informationfromresourcetables:
比较有用的信息,已经标红示出;根据经验,软件安装时,安装的目录名都一定程度上代表了这个软件自身的功能或者软件的名字;那从路径中提取出来的文件名就差不多是”Letasoft Sound Booster”,此外,还可以获取到该模块的创建时间戳为”2012-10-19 00:43:47”,下边百度下该软件的名字,看看能捞到哪些信息,如下,这个软件还是个正规的软件,官 为 https://www.letasoft.com/;从搜索到的
信息来看,这个软件的功能是增大音量的,其与dmp中所牵扯进来的waveOutWrite也是对的上的,该软件还有官 ,说明该软件确实是正规软件。要再继续往下边查原因的话,就需要去下载这个版本的,做下逆向分析了,但所得并不会太多,因为既然是正规软件且还是收费的,值来应该是可靠的,这里导致的crash,可能是极端情况下的某个bug,也必然不太容易复线。
3.dmp分析之外的探究
dmp分析之外的探究—SBH.dll是怎么注入到进程里去的?
通常Ring3的注入方法无怪乎以下几种,
导入表注入:直接修改 PE头,手动构造一项 IAT表; 挂起线程注入:修改 CONTEXT.Eip; 挂起进程注入:分为 ShellCode法和 Shim法,其中 Shim法不太稳定,严重依赖系统版本; 注册表注入: AppInit_DLLs键值 钩子注入:利用 SetWindowsHookEx拦截消息进行注入 APC注入:往用户态 Apc队列中丢一项; 远程线程注入: CreateRemoteThread即可 输入法注入:构造自己的 Ime文件 DLL劫持:利用 Dll搜索的路径顺序加载我们自己构造好的 Dll,然后再转发至真正的 Dll;
但考虑到,这个软件是正规军,不可能用一些“猥琐的”跨平台特性较差的方法来进行SBH.dll的注入;猜测它用到的方法大概率为:
SetWindowsHookEx > CreateRemoteThread>其他
为了研究这个问题,我下载了一个下来测试下,下载的版本如下:
运行起来之后,是上边右图所示。此时我可怜的QQMusic已经被注入了该Dll;一点点防备都没有;
来吧,开始干吧,祭出我们的核武器——Windbg;一顿操作之后挂到SoundBooster.exe上;继而操作如下:
0: 008> x User32!SetWindowsHookEx*76a6f190USER32!SetWindowsHookExA (<no parameter info>)76a7f8e0USER32!SetWindowsHookExAW (<no parameter info>)76a7b610USER32!SetWindowsHookExW (<no parameter info>)
0: 009> bm User32!SetWindowsHookEx*1: 76a6f190 @!”USER32!SetWindowsHookExA”2: 76a7f8e0 @!”USER32!SetWindowsHookExAW”3: 76a7b610 @!”USER32!SetWindowsHookExW”
0: 009> bl1e Disable Clear 76a6f190 0001 (0001) 0:**** USER32!SetWindowsHookExA2e Disable Clear 76a7f8e0 0001 (0001) 0:**** USER32!SetWindowsHookExAW3e Disable Clear 76a7b610 0001 (0001) 0:**** USER32!SetWindowsHookExW
顷刻之间,相干API都已经被我们安插了眼线,然后选中”启用”复选框;一切如所料,命中了,如下:
0: 009> g Breakpoint 1hit eax= 00000000ebx= 00000001ecx= 10000000edx= 10007be0 esi= 10072be8 edi= 010a0000 eip= 76a6f190 esp= 0019ef0c ebp= 0019f1b0 iopl= 0nv up ei pl zr na pe nc cs= 0023ss= 002b ds= 002b es= 002b fs= 0053gs= 002b efl= 00200246USER32!SetWindowsHookExA:76a6f190 8bff mov edi,edi 0: 000> k # ChildEBP RetAddr000019ef08 100073e2USER32!SetWindowsHookExA WARNING: Stack unwind information not available. Following frames may be wrong.010019f1b0 0048d1f5 SBH+ 0x73e2020019f1e0 0048c7b3 SoundBooster+ 0x8d1f5 030019f204 00492f71 SoundBooster+ 0x8c7b3040019f254 00493985SoundBooster+ 0x92f71 050019f2f0 0049034e SoundBooster+ 0x93985060019f310 0049243dSoundBooster+ 0x9034e070019f378 004924ca SoundBooster+ 0x9243d080019f398 76a7bafb SoundBooster+ 0x924ca090019f3c4 76a77e7a USER32!_InternalCallWinProc+ 0x2b0a 0019f4ac 76a5c21a USER32!UserCallWinProcCheckWow+ 0x3aa0b 0019f518 76a5bfa7 USER32!SendMessageWorker+ 0x20a0c 0019f558 7163e96fUSER32!SendMessageW+ 0x1370d0019f578 7163e92fCOMCTL32!Button_NotifyParent+ 0x390e 0019f590 716697f1 COMCTL32!Button_ReleaseCapture+ 0x880f0019f5e4 76a7bafb COMCTL32!Button_WndProc+ 0x3b1100019f610 76a77e7a USER32!_InternalCallWinProc+ 0x2b110019f6f8 76a57e4d USER32!UserCallWinProcCheckWow+ 0x3aa120019f734 00490254USER32!CallWindowProcW+ 0x8d130019f754 00490365SoundBooster+ 0x90254140019f770 0049243dSoundBooster+ 0x90365150019f7d8 004924ca SoundBooster+ 0x9243d160019f7f8 76a7bafb SoundBooster+ 0x924ca170019f824 76a77e7a USER32!_InternalCallWinProc+ 0x2b180019f90c 76a7772e USER32!UserCallWinProcCheckWow+ 0x3aa190019f988 76a5a613 USER32!DispatchMessageWorker+ 0x20e1a 0019f9c8 004906d2 USER32!IsDialogMessageW+ 0x1031b 0019fac8 00000000SoundBooster+ 0x906d2 SetWindowsHookExA的原型以及传入的参数如下:
0: 000> dd 0019ef08+ 8l4 0019ef10 00000003100073501000000000000000
HHOOKSetWindowsHookExA(intidHook, 00000003 —-> WH_GETMESSAGEHOOKPROClpfn, 10007350HINSTANCEhmod, 10000000 —->SBH.dllDWORDdwThreadId 00000000 —->全局钩子);
0: 000> !inmodule 100000000x10000000: SBH
那基本实锤了,这个软件就是通过的消息钩子安装的全局钩子注入到其他进程的;钩子的过程为0x10007350;看下反汇编代码,简单分析下:
SBH+0x7350: 1000735056 push esi100073518b742408 mov esi,dword ptr [esp+8] ;code1000735585f6 test esi,esi1000735757 push edi100073588b7c2414 mov edi,dword ptr [esp+14h] ;PMGS1000735c7516 jne SBH+0x7374 (10007374)1000735e803df84a071000 cmp byte ptr [SBH!KLHGetManager+0x6d078 (10074af8)],010007365750d jne SBH+0x7374 (10007374)100073678b07 mov eax,dword ptr [edi]1000736950 push eax ;hwnd1000736ab9dc450710 mov ecx,offset SBH!KLHGetManager+0x6cb5c (100745dc)1000736fe8bcf8ffff call SBH+0x6c30 (10006c30)100073748b4c2410 mov ecx,dword ptr [esp+10h]100073788b152c430710 mov edx,dword ptr [SBH!KLHGetManager+0x6c8ac (1007432c)]1000737e8b4218 mov eax,dword ptr [edx+18h]1000738157 push edi1000738251 push ecx1000738356 push esi1000738450 push eax10007385ff1518120410 call dword ptr [SBH!KLHGetManager+0x39798 (10041218)];USER32!CallNextHookEx1000738b5f pop edi1000738c5e pop esi1000738dc20c00 ret 0Ch
0: 000> ln poi(10041218)(76a7a470)USER32!CallNextHookEx | (76a7a530) USER32!GetThreadDpiAwarenessContextExactmatches:USER32!CallNextHookEx(void)
适可而止吧,再分析下去就是逆向这个软件的具体行为了,那就侵权了。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!