现学现用之windbg的高级玩法外篇一:获取某软件的聊天记录
不知道直接点名会不会请去喝茶,我不爱喝茶,所以就不直接点名了。 测试环境 某软件版本:2013 正式版sp2 在这里简称Tx 调试软件:windbg 6.12 逆向分析工具:ida 6.0 系统版本:xp sp3 其他工具:xuetr0.45
声明:本软件只是用来演示windbg的用法,本人是纯洁的。所以假设各位童鞋也和楼主一样,否则请自愿离开 本文只限于技术交流,如果有人根据本文做出非法用途的工具与楼主无关。
好,废话少说,开练。 首先,我通过xuetr看到有软件获取聊天内容的方法是Hook了KernelUtil!Util::Msg::SaveMsg194。 楼主是个懒人,不想再另辟新径去找其他方法了。咱们就通过KernelUtil!Util::Msg::SaveMsg194函数来分析怎么获取聊天内容吧。 把kernelUtil放到ida里看了一下,分析出函数定义: int __cdecl Util::Msg::SaveMsg194(wchar_t const *, unsigned long, unsigned long, unsigned long, struct ITXMsgPack *, struct ITXData *) 由于这次分析ida是配角,所以大部分分析的工作就交给windbg了。每个参数是干啥的,等会就能见分晓
开启某软件,然后用windbg附加调试。 查看KernelUtil!Util::Msg::SaveMsg194 发现有两处,不管了,都下上断点 继续执行 我在聊天窗口中发送了消息 ddlxtest2,并按回车,此时果然被断下了 果然那个XX软件没骗我,这个函数就是跟聊天内容相关啊,咱们看一下参数,刚惨咱们看到定义,共有6个参数。 //看一下栈转储 第一个参数是一个宽字符串 第二个参数是个ulong类型的数字 第三个参数是个ulong类型的数字 第四个参数是个ulong类型的数字 第五个参数是个struct ITXMsgPack *结构指针。 ITXMsgPack是干啥的?不知道,看名字定义是消息包,由名字推出聊天内容就应该在这个结构内 第六个参数是个struct ITXData *结构指针。 ITXData是干啥的?不知道,看名字像是一个存储数据的东东,内容也可能在这个结构里面 看了所有的参数,看来账号已经可以拿到了,但是没有一个显式存储聊天内容的。看来最头疼的就是怎么拿聊天内容了。 这一下犯难了,分析时最难的是出现数据结构,需要对数据结构进行分析,最头疼了。既然说要干沉他,那就不能就此罢休 先看一下后两个参数是什么 看一下第五个参数第一个数值:318f9fa8,看看他是一个什么地址: 看来第五个是一个类对象了,318f9fa8告诉我们是在一个模块内,由此可以猜出是个虚函数表。验证一下: 果然是虚函数表。咱们在看看第六个参数: 也是一个类实例。难道要让我分析他们的虚函数么?一个一个看这也太考验楼主耐心了。怎么办!突然灵感一现,为啥不直接搜内容字符串呢? 这个为啥搜unicode字符串而不是ascii字符串呢?这个,哈哈,根据我的经验,聊天软件为了支持其他语言,通常会使用unicode字符串。要不像日文这类就无法显示了 搜出来两条,这个比较乐观,只有两个,对于分析来说容易一些。那哪个才是给Util::Msg::SaveMsg194函数准备的呢? 那就看看这两个地址都在哪被引用了 没有结果,看来不乐观,这么看来,这两个地址都是一个结构内字符串数组,而不是一个指针。 没办法了么?这个时候只能靠猜了(其实调试的过程就是一个不断假设不断否定的过程),假设这两个地址一定会被访问。 那下个访问断点把 看能不能被断下,继续执行 竟然马上就断下来了,太好了,假设是正确的。 向上反汇编看看: 地址78145076就是读取字符串位置,刚才咱们下了两个访问断点,这个是哪个的?看一下esi就知道了 哈哈,看来是访问的第一个地址。似乎看到了曙光。 看一下调用栈(下面的分析都是基于此调用栈的分析) 通过看堆栈我们可以发现,当前调用栈还在KernelUtil!Util::Msg::SaveMsg194函数内部(栈帧编号09)。 有了这个我们应该怎么看呢?还记得断下的访问地址么?对就是0779c308。看看有没有函数的参数是0779c308。 果然有发现,栈帧01的第二个参数就是0779c308。 那咱们就从帧编号01处开始排查,这时楼主使用的是反向剥洋葱法,从内向外,一步一步剥光它,这个方法,在现实生活中,很难实施,有兴趣的欢迎体验 调用Common!Util::Extension::CreateExtensionSort+0x572b函数的指令地址是318e1b49上一条指令,咱们向上反汇编看一下第二个参数是从哪来的 此处汇编指出第二个参数是push eax(地址:318e1b41),eax是从[KernelUtil!ValidateBugReport+0xef2e]函数返回的返回值,并且上一条指令是add ecx,14h 由此可知,[KernelUtil!ValidateBugReport+0xef2e]函数是一个类成员函数,ecx+14h就是一个类对象了。并且这个对象是ecx类对象的内部成员变量。 看看[KernelUtil!ValidateBugReport+0xef2e]是个神马函数: 原来ecx+14h是一个CTXStringW类对象。 看看这个函数 看来,字符串就存储在第一个变量内,并且是一个指针。要想从CTXStringW中获取wchar_t const *字符串,只需poi(ecx)即可。 OK,现在咱们知道了ecx+14h是一个CTXStringW对象,聊天内容字符串就存在此对象中,那ecx所指向的对象是哪里来的呢? 继续看上面的反汇编,发现ecx最后一次被赋值是在 318e1b2c 8b4dec mov ecx,dword ptr [ebp-14h] ebp-14h中的值是哪里来的呢?继续向上反汇编 这个函数还挺长。看完后终于找到ebp-14h的来历: 原来就是KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7de7函数的类对象。看来只看此函数是不知道ecx是那冒出来的, 继续看下一个调用栈 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7de7函数是从318dda9c的上一条地址调用过来的,咱们对318dda9c向上反汇编看看ecx的来历 02 0012d958 318dda9c 019bc360 b2d95feb 05aa688c KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7e69 由此可知ecx是从 318dda93 8b4d08 mov ecx,dword ptr [ebp+8] 处被赋值的,下面就找找ebp+8的值哪里来的。为啥要从下向上看?就是要找到ecx寄存器最后一次被赋值的地方! 看了一遍之后,没找到给ebp+8赋值的地方。那说明ebp+8是参数传过来的。那是第几个参数呢?没看到push ebp ,mov ebp,esp啊,我看到此函数第三行有一个调用 318dda11 e8055f0000 call KernelUtil!CFileResumeInfoMgr::DeleteResumeFile+0x717 (318e391b) 分析了KernelUtil!CFileResumeInfoMgr::DeleteResumeFile+0x717函数知道ebp+8就是第一个参数。ecx=[ebp+8] 咱看一下第一个参数的值是多少 第一个参数是05847a70,也就是ecx=05847a70。聊天内容存储在ecx+14h的类变量里,取出聊天内容的方法为str=*(wchar**)(ecx+14h) 好。我们来验证一下是不是这样 哈哈,现在很是兴奋啊,离目标不远了。
继续看一下第一个参数是哪里来的 第一个参数是push esi得来的,esi是哪里来的呢? 是对esi进行赋值操作。 那函数KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x1698是干嘛的? 此函数的伪代码,大致是这样: eax = *(void**)(ecx+4) 根据上下文推出上面的代码相当于 esi = *(void**)(ebp-0Ch) //-10h+4h = -0Ch 找一下谁对ebp-0Ch进行的赋值 eax是怎么来的呢? 这么说,esi = *(void**)(ebp-0Ch)= *(void**)(ebp-14h) ebp-14中的值怎么来的? 找了一下没找到,但是看到一处函数调用 可能秘密在这里。 上面的函数的伪代码大致如下 class class0 { public: class0( void* p1, void* p2 ) { m_ptr1 = p2; m_ptr2 = p1; } private: void* m_ptr1; void* m_ptr2; } KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ca函数就是class0的构造函数 再根据上下文 可知 [ebp-18] = ecx+24h [ebp-14] = [ecx+24+4] 再加上 esi = *(void**)(ebp-0Ch) = *(void**)(ebp-14h) 现在可以确定esi与ecx之间的关系了 esi = *(void**)*(void**)(ecx+24+4)
这个函数是最难理解的了。 确定了esi与ecx的关系,那ecx是怎么来的呢? 看一下上层函数是谁 看完之后确定ecx 是通过第一个参数传递过来的,第一个参数是什么呢? 是05aa6868!!!!! 05aa6868是什么?就是KernelUtil!Util::Msg::SaveMsg194函数的第五个参数啊!!!功夫不负有心人,终于找到内容从哪个参数中取了。 慢着,通过第五个参数怎么获取内容呢?在绿一下 经过分析,struct ITXMsgPack大致长成这个样子: struct ITXMsgPack { char szUnknown[0x28]; UnknownSt1* pst1; ... } struct UnknownSt1 { UnknownSt2* pst2; } struct UnknownSt2 { char szUnknown[0x14]; wchar* pMsg; ... } 验证一下,没有验证就无法证明推理是正确的 到此分析完了。本来就要结束了,但是感觉需要再升华一下。
我打算用用windbg监控聊天信息,每次聊天都输出日志,日志信息包括自己的账号,对方的账号,以及聊天内容 //设置一个记录断点 本篇只分析了发送,接受消息不走3189bb3a函数。有兴趣的就分析一下接受消息。
多余的话 本次分析最大的难点在于怎么拿取聊天内容。 楼主通过反向剥洋葱分析法,通过对每层调用栈的刨析,最终找到通过ITXMsgPack拿取聊天内容的方法。 奉劝各位刚接触逆向的朋友,遇到问题不要着急,答案就在附近,仔细寻找就能找到他! 不管是用Od还是用Windbg,他们都是工具而已。 最终用来解决问题的是我们的大脑。所以不管使用什么工具,只要有思路就可以找到你想要的答案。 总之一句话,方法和技巧才是找到问题根源的最终武器。工具只是验证你的方法是否正确。
不知道直接点名会不会请去喝茶,我不爱喝茶,所以就不直接点名了。 测试环境 某软件版本:2013 正式版sp2 在这里简称Tx 调试软件:windbg 6.12 逆向分析工具:ida 6.0 系统版本:xp sp3 其他工具:xuetr0.45
声明:本软件只是用来演示windbg的用法,本人是纯洁的。所以假设各位童鞋也和楼主一样,否则请自愿离开 本文只限于技术交流,如果有人根据本文做出非法用途的工具与楼主无关。
好,废话少说,开练。 首先,我通过xuetr看到有软件获取聊天内容的方法是Hook了KernelUtil!Util::Msg::SaveMsg194。 楼主是个懒人,不想再另辟新径去找其他方法了。咱们就通过KernelUtil!Util::Msg::SaveMsg194函数来分析怎么获取聊天内容吧。 把kernelUtil放到ida里看了一下,分析出函数定义: int __cdecl Util::Msg::SaveMsg194(wchar_t const *, unsigned long, unsigned long, unsigned long, struct ITXMsgPack *, struct ITXData *) 由于这次分析ida是配角,所以大部分分析的工作就交给windbg了。每个参数是干啥的,等会就能见分晓
开启某软件,然后用windbg附加调试。 查看KernelUtil!Util::Msg::SaveMsg194
代码:
0:000> x KernelUtil!Util::Msg::SaveMsg194 3189b75a KernelUtil!Util::Msg::SaveMsg194 () 3189bb3a KernelUtil!Util::Msg::SaveMsg194 () [/cpp]
代码:
0:025> bm KernelUtil!Util::Msg::SaveMsg194 1: 3189b75a @!"KernelUtil!Util::Msg::SaveMsg194" 2: 3189bb3a @!"KernelUtil!Util::Msg::SaveMsg194" 0:025> bl 1 e 3189b75a 0001 (0001) 0:**** KernelUtil!Util::Msg::SaveMsg194 2 e 3189bb3a 0001 (0001) 0:**** KernelUtil!Util::Msg::SaveMsg194 [/cpp]
代码:
0:025> g [/cpp]
代码:
Breakpoint 2 hit eax=4c12fd1a ebx=00000000 ecx=31877650 edx=0012db48 esi=3016a33c edi=056c0864 eip=3189bb3a esp=0012db54 ebp=0012dfdc iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 KernelUtil!Util::Msg::SaveMsg194: 3189bb3a 6a2c push 2Ch [/cpp]
代码:
0:000> dd esp 0012db54 03409695 035c918c 5556ae** 4c12fd** 0012db64 5556ae** 05aa6868 059b3908 996b7eb3 0012db74 300b5467 300d64b9 056c0860 300a771a 0012db84 05929680 05929680 0012dba0 71a2265b 0012db94 00000020 01376978 059b3908 0012dc0c 0012dba4 07779a18 30820a35 035c918c 0012dbd0 0012dbb4 00000010 05aa6868 059b3908 00000020 0012dbc4 01376978 0012dc0c 0012dc38 0012dc10 [/cpp]
代码:
0:000> du poi(esp+4) 035c918c "buddy" //擦这个不是聊天内容 [/cpp]
代码:
0:000> ? poi(esp+8) Evaluate expression: 14317***** = 5556ae** //14317*****正是楼主发送的对方账号。账号做了打码处理 [/cpp]
代码:
0:000> ? poi(esp+c) Evaluate expression: 12763***** = 4c12fd** //127631****正是正在调试的账号 [/cpp]
代码:
0:000> ? poi(esp+10) Evaluate expression: 14317***** = 5556ae** [/cpp]
代码:
0:000> dd poi(esp+14) 05aa6868 318f9fa8 318f9f98 00000006 3016a23c 05aa6878 3016a22c 00000000 00040000 00000000 05aa6888 05ad35f8 05aa0000 059d8ec0 059d8ec4 05aa6898 059d8ec4 00000000 00080004 0408012c 05aa68a8 059d8db8 059d8db8 059d8db8 00000000 05aa68b8 700a0c76 00000101 00040002 040e0120 05aa68c8 05aa0000 003f0178 0002000f 04080122 05aa68d8 00008000 00000004 0000000d 0000000b [/cpp]
代码:
0:000> dd poi(esp+18) 059b3908 3016a270 3016a260 3016a24c 3016a23c 059b3918 3016a22c 00000001 00000000 00010000 059b3928 00016300 00000001 095af8f8 095afc40 059b3938 01896740 0000000f 0008000a 040c0110 059b3948 30168f40 00000001 059b3948 00000000 059b3958 c54dd1c9 4511ad06 d6749aa1 42b25ff5 059b3968 00000000 00000000 00000000 00000000 059b3978 00000000 3028475c 07777b70 059d8248 [/cpp]
代码:
0:000> !address 318f9fa8 Failed to map Heaps (error 80004005) Usage: Image Allocation Base: 31800000 Base Address: 318f3000 End Address: 31932000 Region Size: 0003f000 Type: 01000000 MEM_IMAGE State: 00001000 MEM_COMMIT Protect: 00000002 PAGE_READONLY More info: lmv m KernelUtil More info: !lmi KernelUtil More info: ln 0x318f9fa8 [/cpp]
代码:
0:000> dds 318f9fa8 l5 318f9fa8 31886259 KernelUtil!Util::Msg::ConvertCharFormatMsgPackToRichEdit+0xf18 318f9fac 318da1e0 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x500 318f9fb0 31884d3a KernelUtil!Util::Msg::SetMsgDB2StorageMode+0x98 318f9fb4 318dd504 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3824 318f9fb8 318dd516 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3836 [/cpp]
代码:
0:000> !address 3016a270 Usage: Image Allocation Base: 30000000 Base Address: 3014e000 End Address: 301c1000 Region Size: 00073000 Type: 01000000 MEM_IMAGE State: 00001000 MEM_COMMIT Protect: 00000002 PAGE_READONLY More info: lmv m Common More info: !lmi Common More info: ln 0x3016a270 [/cpp]
代码:
0:000> s -u 0 f000000 "ddlxtest2" 01475e98 0064 0064 006c 0078 0074 0065 0073 0074 d.d.l.x.t.e.s.t. 0779c308 0064 0064 006c 0078 0074 0065 0073 0074 d.d.l.x.t.e.s.t. [/cpp]
代码:
0:000> s -u 0 f000000 01475e98 0:000> s -u 0 f000000 0779c308 [/cpp]
代码:
0:000> ba r4 0779c308 0:000> ba r4 01475e98 [/cpp]
代码:
0:000> g [/cpp]
代码:
Breakpoint 0 hit eax=00000064 ebx=05acfc00 ecx=00000012 edx=00000002 esi=0779c308 edi=05acfc26 eip=78145078 esp=0012d8e8 ebp=0012d8f0 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 MSVCR80!LeadUpVec+0x3c: 78145078 8807 mov byte ptr [edi],al ds:0023:05acfc26=00 [/cpp]
代码:
0:000> ub MSVCR80!LeadUpVec+0x24 [F:\dd\vctools\crt_bld\SELF_X86\crt\src\intel\memcpy.asm @ 245]: 78145060 83c703 add edi,3 78145063 83f908 cmp ecx,8 78145066 72cc jb MSVCR80!memcpy+0x84 (78145034) 78145068 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] 7814506a ff249524511478 jmp dword ptr MSVCR80!TrailUpVec (78145124)[edx*4] 78145071 8d4900 lea ecx,[ecx] 78145074 23d1 and edx,ecx 78145076 8a06 mov al,byte ptr [esi] [/cpp]
代码:
0:000> r esi esi=0779c308 [/cpp]
代码:
0:000> kb n 10 # ChildEBP RetAddr Args to Child 00 0012d8f0 30030e71 05acfc26 0779c308 00000014 MSVCR80!LeadUpVec+0x3c [F:\dd\vctools\crt_bld\SELF_X86\crt\src\intel\memcpy.asm @ 259] WARNING: Stack unwind information not available. Following frames may be wrong. 01 0012d910 318e1b49 059bc360 0779c308 00000014 Common!Util::Extension::CreateExtensionSort+0x572b 02 0012d958 318dda9c 019bc360 b2d95feb 05aa688c KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7e69 03 0012d988 318dfedb 05847a70 059bc360 0012da4c KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3dbc 04 0012d9b8 318dff6b 0012d9ec b2d95f83 05aa6868 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x61fb 05 0012d9e0 0328d5e0 05aa6868 059bc360 996b7b57 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x628b 06 0012da38 0326ca46 01ab9aa4 062e2cb0 0770c4b8 IM!DllUnregisterServer+0x2a994 07 0012da98 3189b727 057a2310 05aa6868 01ab9aa4 IM!DllUnregisterServer+0x9dfa 08 0012daf4 3189beab 035c918c 07779a18 05aa6868 KernelUtil!Util::MsgImport::FindAutoQQMsgFileFullPath+0x4a6 09 0012db50 03409695 035c918c 5556ae** 4c12fd** KernelUtil!Util::Msg::SaveMsg194+0x371 0a 0012dfdc 033d52c0 035c918c 05aa6868 00000000 IM!DllUnregisterServer+0x1a6a49 0b 0012e07c 033d6f08 05aa6868 00000000 00000001 IM!DllUnregisterServer+0x172674 0c 0012e0a0 033d7125 05aa6868 00000000 05a56438 IM!DllUnregisterServer+0x1742bc 0d 0012e0d4 6629a5eb 056c0864 05aa6868 00000000 IM!DllUnregisterServer+0x1744d9 0e 0012e12c 64c20f8d 059d19a0 05aa6868 05599278 AppFramework!DllUnregisterServer+0x9851c 0f 0012e140 662903e9 05a560c8 05aa6868 05ae3f88 ChatFrameApp!DllUnregisterServer+0x1fb6a [/cpp]
代码:
01 0012d910 318e1b49 059bc360 0779c308 00000014 Common!Util::Extension::CreateExtensionSort+0x572b [/cpp]
代码:
0:000> ub 318e1b49 l10 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7e42: 318e1b22 8d4de8 lea ecx,[ebp-18h] 318e1b25 51 push ecx 318e1b26 56 push esi 318e1b27 ff5050 call dword ptr [eax+50h] 318e1b2a 8b06 mov eax,dword ptr [esi] 318e1b2c 8b4dec mov ecx,dword ptr [ebp-14h] 318e1b2f 8945e4 mov dword ptr [ebp-1Ch],eax 318e1b32 0fb745e8 movzx eax,word ptr [ebp-18h] 318e1b36 57 push edi 318e1b37 50 push eax 318e1b38 83c114 add ecx,14h 318e1b3b ff15f4348f31 call dword ptr [KernelUtil!ValidateBugReport+0xef2e (318f34f4)] 318e1b41 50 push eax 318e1b42 8b45e4 mov eax,dword ptr [ebp-1Ch] 318e1b45 56 push esi 318e1b46 ff5050 call dword ptr [eax+50h] [/cpp]
代码:
0:000> dds KernelUtil!ValidateBugReport+0xef2e l1 318f34f4 300d9ab1 Common!CTXStringW::operator wchar_t const * [/cpp]
代码:
0:000> uf 300d9ab1 Common!CTXStringW::GetString: 300d9162 56 push esi 300d9163 8bf1 mov esi,ecx 300d9165 e8dcfdffff call Common!CTXStringW::Refresh (300d8f46) 300d916a 8b06 mov eax,dword ptr [esi] 300d916c 5e pop esi 300d916d c3 ret [/cpp]
代码:
0:000> ub 318e1b22 l21 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7de4: 318e1ac4 c20400 ret 4 318e1ac7 6a14 push 14h 318e1ac9 b8fb148f31 mov eax,offset KernelUtil!ValidateBugReport+0xcf35 (318f14fb) 318e1ace e8481e0000 call KernelUtil!CFileResumeInfoMgr::DeleteResumeFile+0x717 (318e391b) 318e1ad3 894dec mov dword ptr [ebp-14h],ecx 318e1ad6 8b7508 mov esi,dword ptr [ebp+8] 318e1ad9 33ff xor edi,edi 318e1adb 3bf7 cmp esi,edi 318e1add 750a jne KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7e09 (318e1ae9) 318e1adf b805400080 mov eax,80004005h 318e1ae4 e9a9020000 jmp KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x80b2 (318e1d92) 318e1ae9 83c114 add ecx,14h 318e1aec ff15ec308f31 call dword ptr [KernelUtil!ValidateBugReport+0xeb26 (318f30ec)] 318e1af2 84c0 test al,al 318e1af4 8b1dd4308f31 mov ebx,dword ptr [KernelUtil!ValidateBugReport+0xeb0e (318f30d4)] 318e1afa 754d jne KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x7e69 (318e1b49) 318e1afc 8b4dec mov ecx,dword ptr [ebp-14h] 318e1aff 83c114 add ecx,14h 318e1b02 c6450b01 mov byte ptr [ebp+0Bh],1 318e1b06 ffd3 call ebx 318e1b08 03c0 add eax,eax 318e1b0a 57 push edi 318e1b0b 0fb7c0 movzx eax,ax 318e1b0e 6a01 push 1 318e1b10 8d4d0b lea ecx,[ebp+0Bh] 318e1b13 51 push ecx 318e1b14 8945e8 mov dword ptr [ebp-18h],eax 318e1b17 8b06 mov eax,dword ptr [esi] 318e1b19 56 push esi 318e1b1a ff5050 call dword ptr [eax+50h] 318e1b1d 8b06 mov eax,dword ptr [esi] 318e1b1f 57 push edi 318e1b20 6a02 push 2 [/cpp]
代码:
318e1ad3 894dec mov dword ptr [ebp-14h],ecx [/cpp]
代码:
0:000> ub 318dda9c l40 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3d1c: 318dd9fc 50 push eax 318dd9fd ff5108 call dword ptr [ecx+8] 318dda00 8bc3 mov eax,ebx 318dda02 e8ec5f0000 call KernelUtil!CFileResumeInfoMgr::DeleteResumeFile+0x7ef (318e39f3) 318dda07 c20800 ret 8 318dda0a 6a08 push 8 318dda0c b8d3178f31 mov eax,offset KernelUtil!ValidateBugReport+0xd20d (318f17d3) 318dda11 e8055f0000 call KernelUtil!CFileResumeInfoMgr::DeleteResumeFile+0x717 (318e391b) 318dda16 8b4d08 mov ecx,dword ptr [ebp+8] 318dda19 8b7904 mov edi,dword ptr [ecx+4] 318dda1c 8b750c mov esi,dword ptr [ebp+0Ch] 318dda1f 33db xor ebx,ebx 318dda21 3bfb cmp edi,ebx 318dda23 7471 je KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3db6 (318dda96) 318dda25 895df0 mov dword ptr [ebp-10h],ebx 318dda28 8d4df0 lea ecx,[ebp-10h] 318dda2b 895dfc mov dword ptr [ebp-4],ebx 318dda2e e86411f9ff call KernelUtil!CTXCCProtocolStrategy::GetUin+0x203 (3186eb97) 318dda33 8b0f mov ecx,dword ptr [edi] 318dda35 50 push eax 318dda36 57 push edi 318dda37 ff5160 call dword ptr [ecx+60h] 318dda3a 8b06 mov eax,dword ptr [esi] 318dda3c 53 push ebx 318dda3d 6a01 push 1 318dda3f 8d4d0f lea ecx,[ebp+0Fh] 318dda42 51 push ecx 318dda43 56 push esi 318dda44 885d0f mov byte ptr [ebp+0Fh],bl 318dda47 ff5050 call dword ptr [eax+50h] 318dda4a 8d4df0 lea ecx,[ebp-10h] 318dda4d e8a911f9ff call KernelUtil!CTXCCProtocolStrategy::GetUin+0x267 (3186ebfb) 318dda52 53 push ebx 318dda53 0fb7c0 movzx eax,ax 318dda56 6a02 push 2 318dda58 8d4dec lea ecx,[ebp-14h] 318dda5b 51 push ecx 318dda5c 8945ec mov dword ptr [ebp-14h],eax 318dda5f 8b06 mov eax,dword ptr [esi] 318dda61 56 push esi 318dda62 ff5050 call dword ptr [eax+50h] 318dda65 395df0 cmp dword ptr [ebp-10h],ebx 318dda68 750b jne KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3d95 (318dda75) 318dda6a 8d45f0 lea eax,[ebp-10h] 318dda6d 50 push eax 318dda6e ff1524358f31 call dword ptr [KernelUtil!ValidateBugReport+0xef5e (318f3524)] 318dda74 59 pop ecx 318dda75 8b06 mov eax,dword ptr [esi] 318dda77 53 push ebx 318dda78 ff75f0 push dword ptr [ebp-10h] 318dda7b 56 push esi 318dda7c ff5054 call dword ptr [eax+54h] 318dda7f 8b45f0 mov eax,dword ptr [ebp-10h] 318dda82 834dfcff or dword ptr [ebp-4],0FFFFFFFFh 318dda86 3bc3 cmp eax,ebx 318dda88 7409 je KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3db3 (318dda93) 318dda8a 8b08 mov ecx,dword ptr [eax] 318dda8c 50 push eax 318dda8d ff5108 call dword ptr [ecx+8] 318dda90 895df0 mov dword ptr [ebp-10h],ebx 318dda93 8b4d08 mov ecx,dword ptr [ebp+8] 318dda96 8b01 mov eax,dword ptr [ecx] 318dda98 56 push esi 318dda99 ff505c call dword ptr [eax+5Ch] [/cpp]
代码:
0:000> uf 318e391b KernelUtil!CFileResumeInfoMgr::DeleteResumeFile+0x717: 318e391b 50 push eax 318e391c 64ff3500000000 push dword ptr fs:[0] 318e3923 8d44240c lea eax,[esp+0Ch] //esp+c,这里为啥要加C呢,上两条指令已经加上返回地址,调用此函数到运行到这里,共压栈 //压栈3此,共计0xC个字节,esp+0Ch正好是调用此函数前的栈帧 318e3927 2b64240c sub esp,dword ptr [esp+0Ch] 318e392b 53 push ebx 318e392c 56 push esi 318e392d 57 push edi 318e392e 8928 mov dword ptr [eax],ebp 318e3930 8be8 mov ebp,eax //此处给ebp赋值,eax经过上面的分析可知。ebp此时的赋值,相当于在调用此函数前执行了mov ebp,esp //再加上,上一个函数执行了一条push 8,此时也就知道了上一个函数的ebp+8其实是指向的第一个参数 318e3932 a160419331 mov eax,dword ptr [KernelUtil!CppSQLite3DB::`vftable'+0x2c484 (31934160)] 318e3937 33c5 xor eax,ebp 318e3939 50 push eax 318e393a ff75fc push dword ptr [ebp-4] 318e393d c745fcffffffff mov dword ptr [ebp-4],0FFFFFFFFh 318e3944 8d45f4 lea eax,[ebp-0Ch] 318e3947 64a300000000 mov dword ptr fs:[00000000h],eax 318e394d c3 ret [/cpp]
代码:
03 0012d988 318dfedb 05847a70 059bc360 0012da4c KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3dbc [/cpp]
代码:
0:000> du poi(05847a70 +14) 0779c308 "ddlxtest2." [/cpp]
继续看一下第一个参数是哪里来的
代码:
03 0012d988 318dfedb 05847a70 059bc360 0012da4c KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3dbc [/cpp]
代码:
0:000> ub 318dfedb l10 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x61d7: 318dfeb7 4d dec ebp 318dfeb8 f8 clc 318dfeb9 51 push ecx 318dfeba 56 push esi 318dfebb ff5014 call dword ptr [eax+14h] 318dfebe 8b4d08 mov ecx,dword ptr [ebp+8] 318dfec1 6a02 push 2 318dfec3 8d45f8 lea eax,[ebp-8] 318dfec6 50 push eax 318dfec7 e80252faff call KernelUtil!Util::Msg::SetMsgDB2StorageMode+0x42c (318850ce) 318dfecc 8b4d08 mov ecx,dword ptr [ebp+8] 318dfecf e8afecf8ff call KernelUtil!CTXCCProtocolStrategy::GetUin+0x1ef (3186eb83) 318dfed4 8b0e mov ecx,dword ptr [esi] 318dfed6 50 push eax 318dfed7 56 push esi 318dfed8 ff5118 call dword ptr [ecx+18h] [/cpp]
代码:
0:000> ub 318dfedb l40-7 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x6167: 318dfe47 55 push ebp 318dfe48 8bec mov ebp,esp 318dfe4a 83ec18 sub esp,18h 318dfe4d 8365f800 and dword ptr [ebp-8],0 318dfe51 57 push edi 318dfe52 8d7924 lea edi,[ecx+24h] 318dfe55 57 push edi 318dfe56 ff7704 push dword ptr [edi+4] 318dfe59 8d4de8 lea ecx,[ebp-18h] 318dfe5c c645ff00 mov byte ptr [ebp-1],0 318dfe60 e83e1ff9ff call KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ca (31871da3) 318dfe65 8b45e8 mov eax,dword ptr [ebp-18h] 318dfe68 57 push edi 318dfe69 ff7708 push dword ptr [edi+8] 318dfe6c 8945f0 mov dword ptr [ebp-10h],eax 318dfe6f 8b45ec mov eax,dword ptr [ebp-14h] 318dfe72 8d4de8 lea ecx,[ebp-18h] 318dfe75 8945f4 mov dword ptr [ebp-0Ch],eax 318dfe78 e8261ff9ff call KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ca (31871da3) 318dfe7d 8d45e8 lea eax,[ebp-18h] 318dfe80 50 push eax 318dfe81 8d4df0 lea ecx,[ebp-10h] 318dfe84 e8d546fcff call KernelUtil!DllUnregisterServer+0x113c (318a455e) 318dfe89 84c0 test al,al 318dfe8b 7573 jne KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x6220 (318dff00) 318dfe8d 56 push esi 318dfe8e 8d4df0 lea ecx,[ebp-10h] 318dfe91 e8344afeff call KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x1698 (318c48ca) 318dfe96 8b30 mov esi,dword ptr [eax] //发现有个esi赋值操作 318dfe98 85f6 test esi,esi 318dfe9a 743f je KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x61fb (318dfedb) 318dfe9c 8b06 mov eax,dword ptr [esi] 318dfe9e 8d4dff lea ecx,[ebp-1] 318dfea1 51 push ecx 318dfea2 56 push esi 318dfea3 ff500c call dword ptr [eax+0Ch] 318dfea6 8b4d08 mov ecx,dword ptr [ebp+8] 318dfea9 6a01 push 1 318dfeab 8d45ff lea eax,[ebp-1] 318dfeae 50 push eax 318dfeaf e81a52faff call KernelUtil!Util::Msg::SetMsgDB2StorageMode+0x42c (318850ce) 318dfeb4 8b06 mov eax,dword ptr [esi] 318dfeb6 8d4df8 lea ecx,[ebp-8] 318dfeb9 51 push ecx 318dfeba 56 push esi 318dfebb ff5014 call dword ptr [eax+14h] 318dfebe 8b4d08 mov ecx,dword ptr [ebp+8] 318dfec1 6a02 push 2 318dfec3 8d45f8 lea eax,[ebp-8] 318dfec6 50 push eax 318dfec7 e80252faff call KernelUtil!Util::Msg::SetMsgDB2StorageMode+0x42c (318850ce) 318dfecc 8b4d08 mov ecx,dword ptr [ebp+8] 318dfecf e8afecf8ff call KernelUtil!CTXCCProtocolStrategy::GetUin+0x1ef (3186eb83) 318dfed4 8b0e mov ecx,dword ptr [esi] 318dfed6 50 push eax 318dfed7 56 push esi 318dfed8 ff5118 call dword ptr [ecx+18h] [/cpp]
代码:
318dfe91 e8344afeff call KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x1698 (318c48ca) 318dfe96 8b30 mov esi,dword ptr [eax] [/cpp]
代码:
0:000> uf KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x1698 KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x1698: 318c48ca 56 push esi 318c48cb 8bf1 mov esi,ecx 318c48cd 833e00 cmp dword ptr [esi],0 318c48d0 57 push edi 318c48d1 8b3dec378f31 mov edi,dword ptr [KernelUtil!ValidateBugReport+0xf226 (318f37ec)] 318c48d7 7502 jne KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x16a9 (318c48db)
KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x16a7: 318c48d9 ffd7 call edi
KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x16a9: 318c48db 8b06 mov eax,dword ptr [esi] 318c48dd 8b4e04 mov ecx,dword ptr [esi+4] 318c48e0 3b4808 cmp ecx,dword ptr [eax+8] 318c48e3 7202 jb KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x16b5 (318c48e7)
KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x16b3: 318c48e5 ffd7 call edi
KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x16b5: 318c48e7 8b4604 mov eax,dword ptr [esi+4] 318c48ea 5f pop edi 318c48eb 5e pop esi 318c48ec c3 ret [/cpp]
代码:
318dfe8e 8d4df0 lea ecx,[ebp-10h] 318dfe91 e8344afeff call KernelUtil!CDRStrCodecBaseHttp2Cs::CodeStr+0x1698 (318c48ca) 318dfe96 8b30 mov esi,dword ptr [eax] [/cpp]
代码:
318dfe75 8945f4 mov dword ptr [ebp-0Ch],eax [/cpp]
代码:
318dfe6f 8b45ec mov eax,dword ptr [ebp-14h] [/cpp]
代码:
318dfe60 e83e1ff9ff call KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ca (31871da3) [/cpp]
代码:
0:000> uf 31871da3 KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ca: 31871da3 55 push ebp 31871da4 8bec mov ebp,esp 31871da6 53 push ebx 31871da7 8b5d08 mov ebx,dword ptr [ebp+8] 31871daa 56 push esi 31871dab 57 push edi 31871dac 8b7d0c mov edi,dword ptr [ebp+0Ch] 31871daf 8bf1 mov esi,ecx 31871db1 832600 and dword ptr [esi],0 31871db4 85ff test edi,edi 31871db6 740a je KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7e9 (31871dc2)
KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7df: 31871db8 395f04 cmp dword ptr [edi+4],ebx 31871dbb 7705 ja KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7e9 (31871dc2)
KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7e4: 31871dbd 3b5f08 cmp ebx,dword ptr [edi+8] 31871dc0 7606 jbe KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ef (31871dc8)
KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7e9: 31871dc2 ff15ec378f31 call dword ptr [KernelUtil!ValidateBugReport+0xf226 (318f37ec)]
KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ef: 31871dc8 893e mov dword ptr [esi],edi 31871dca 5f pop edi 31871dcb 895e04 mov dword ptr [esi+4],ebx 31871dce 8bc6 mov eax,esi 31871dd0 5e pop esi 31871dd1 5b pop ebx 31871dd2 5d pop ebp 31871dd3 c20800 ret 8 [/cpp]
代码:
318dfe51 57 push edi 318dfe52 8d7924 lea edi,[ecx+24h] 318dfe55 57 push edi 318dfe56 ff7704 push dword ptr [edi+4] 318dfe59 8d4de8 lea ecx,[ebp-18h] 318dfe5c c645ff00 mov byte ptr [ebp-1],0 318dfe60 e83e1ff9ff call KernelUtil!CCcSeqManager::IsCmdSeqRecved+0x7ca (31871da3) 318dfe65 8b45e8 mov eax,dword ptr [ebp-18h] 318dfe68 57 push edi 318dfe69 ff7708 push dword ptr [edi+8] 318dfe6c 8945f0 mov dword ptr [ebp-10h],eax 318dfe6f 8b45ec mov eax,dword ptr [ebp-14h] 318dfe72 8d4de8 lea ecx,[ebp-18h] 318dfe75 8945f4 mov dword ptr [ebp-0Ch],eax [/cpp]
这个函数是最难理解的了。 确定了esi与ecx的关系,那ecx是怎么来的呢?
代码:
04 0012d9b8 318dff6b 0012d9ec b2d95f83 05aa6868 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x61fb [/cpp]
代码:
0:000> ub 318dff6b l25 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x6220: 318dff00 33c0 xor eax,eax 318dff02 40 inc eax 318dff03 5f pop edi 318dff04 c9 leave 318dff05 c20400 ret 4 318dff08 6a00 push 0 318dff0a b85aab8e31 mov eax,offset KernelUtil!ValidateBugReport+0x6594 (318eab5a) 318dff0f e8073a0000 call KernelUtil!CFileResumeInfoMgr::DeleteResumeFile+0x717 (318e391b) //此函数上面已经给出说明,此函数导致ebp+8指向第一个参数 318dff14 8b750c mov esi,dword ptr [ebp+0Ch] 318dff17 85f6 test esi,esi 318dff19 7507 jne KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x6242 (318dff22) 318dff1b b857000780 mov eax,80070057h 318dff20 eb7d jmp KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x62bf (318dff9f) 318dff22 83650c00 and dword ptr [ebp+0Ch],0 318dff26 8365fc00 and dword ptr [ebp-4],0 318dff2a 6800020000 push 200h 318dff2f 8d4d0c lea ecx,[ebp+0Ch] 318dff32 e889d8ffff call KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x3ae0 (318dd7c0) 318dff37 8b4d08 mov ecx,dword ptr [ebp+8] 318dff3a 8d450c lea eax,[ebp+0Ch] 318dff3d 50 push eax 318dff3e e829f0ffff call KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x528c (318def6c) 318dff43 85c0 test eax,eax 318dff45 7518 jne KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x627f (318dff5f) 318dff47 8b450c mov eax,dword ptr [ebp+0Ch] 318dff4a 834dfcff or dword ptr [ebp-4],0FFFFFFFFh 318dff4e 85c0 test eax,eax 318dff50 7406 je KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x6278 (318dff58) 318dff52 8b08 mov ecx,dword ptr [eax] 318dff54 50 push eax 318dff55 ff5108 call dword ptr [ecx+8] 318dff58 b805400080 mov eax,80004005h 318dff5d eb40 jmp KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x62bf (318dff9f) 318dff5f 8b4d08 mov ecx,dword ptr [ebp+8] //对ecx赋值, ebp+8就是第一个参数。 318dff62 8d450c lea eax,[ebp+0Ch] 318dff65 50 push eax 318dff66 e8dcfeffff call KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x6167 (318dfe47) [/cpp]
代码:
05 0012d9e0 0328d5e0 05aa6868 059bc360 996b7b57 KernelUtil!CDRStrCodecBaseHttp2Cs::AddRef+0x628b [/cpp]
代码:
0:000> du poi(poi(poi(05aa6868+0x28))+14) 0779c308 "ddlxtest2." [/cpp]
我打算用用windbg监控聊天信息,每次聊天都输出日志,日志信息包括自己的账号,对方的账号,以及聊天内容 //设置一个记录断点
代码:
0:012> bp 3189bb3a ".printf \"lcoalId:%u tergatId:%u msg:%mu\\n\" ,poi(esp+c),poi(esp+10),poi(poi(poi(poi(esp+14)+0x28))+14);gc;" breakpoint 0 redefined 0:012> bl 0 e 3189bb3a 0001 (0001) 0:**** KernelUtil!Util::Msg::SaveMsg194 ".printf \"lcoalId:%u tergatId:%u msg:%mu\\n\" ,poi(esp+c),poi(esp+10),poi(poi(poi(poi(esp+14)+0x28))+14);gc;" 0:012> g //下面是输出的记录信息 lcoalId:127631**** tergatId:143174**** msg:ddlxtest6 lcoalId:127631**** tergatId:143174**** msg:ddlxtest7 lcoalId:127631**** tergatId:183498**** msg:hello pediy [/cpp]
多余的话 本次分析最大的难点在于怎么拿取聊天内容。 楼主通过反向剥洋葱分析法,通过对每层调用栈的刨析,最终找到通过ITXMsgPack拿取聊天内容的方法。 奉劝各位刚接触逆向的朋友,遇到问题不要着急,答案就在附近,仔细寻找就能找到他! 不管是用Od还是用Windbg,他们都是工具而已。 最终用来解决问题的是我们的大脑。所以不管使用什么工具,只要有思路就可以找到你想要的答案。 总之一句话,方法和技巧才是找到问题根源的最终武器。工具只是验证你的方法是否正确。
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10722994
每日一句
All things in their being are good for something.
天生我材必有用。
天生我材必有用。
新会员