使用windbg挖地雷直接取胜

12 篇文章 0 订阅
7 篇文章 0 订阅

使用windbg挖地雷直接取胜

前面一篇文章探讨了如何直接明挖地雷,通过windbg修改了雷区就可以了. 这次我们更直接,看看如何通过函数飞针直接取胜.
使用windbg直接打开winmine.exe
先运行起来:g   共99个雷.


先看如何把雷个数改为0,  break这个程序. 用x命令显示所有符号
0:005> x winmine!*
01001004 winmine!_imp__RegSetValueExW = <no type information>
0100511c winmine!yCur = <no type information>
01005b8c winmine!__onexitend = <no type information>
01001108 winmine!_imp__GetDlgItemTextW = <no type information>
010010cc winmine!_imp__RegisterClassW = <no type information>
010057a0 winmine!cBoxVisitMac = <no type information>
01001178 winmine!_imp____p__fmode = <no type information>
0100118c winmine!_imp____getmainargs = <no type information>
01005158 winmine!hGrayPen = <no type information>
01002eab winmine!ChangeBlk = <no type information>
01001baa winmine!DoDisplayBest = <no type information>
01002f3b winmine!CountBombs = <no type information>
01001950 winmine!AdjustWindow = <no type information>
01001090 winmine!_imp__GetStartupInfoA = <no type information>
0100518c winmine!pHtmlHelpW = <no type information>
......
no type information 表示我们没有微软私有符号,只有公开符号,不知道变量类型.

内容非常多,还是要过滤一下,看看有没有g开头的,g一般是全局变量的开头
0:005> x winmine!g*
01005950 winmine!g_hReg = <no type information>
0100347c winmine!GameOver = <no type information>
01003df6 winmine!GetDlgInt = <no type information>
看着都不像地雷个数. 再看看c开头的,c一般是整形数
0:005> x winmine!c*
010057a0 winmine!cBoxVisitMac = <no type information>
01002eab winmine!ChangeBlk = <no type information>
01002f3b winmine!CountBombs = <no type information>
010023f1 winmine!CbBitmap = <no type information>
01003119 winmine!CountMarks = <no type information>
010057a4 winmine!cBoxVisit = <no type information>
0100579c winmine!cSec = <no type information>
01005194 winmine!cBombLeft = <no type information>
01002ed5 winmine!ClearField = <no type information>
01003cc4 winmine!CheckEm = <no type information>
01005330 winmine!cBombStart = <no type information>
0100263c winmine!CleanUp = <no type information>

winmine!cBombLeft 像是剩余雷个数,需要验证一下. 先看看内容:
0:005> dd winmine!cBombLeft
01005194  00000063 00000000 00000000 00000000
010051a4  00000000 00000000 00000000 00000000
010051b4  00000000 00000000 00000000 00000000
010051c4  00000000 00000000 00000000 00000000
010051d4  00000000 00000000 00000000 00000000
010051e4  00000000 00000000 00000000 00000000
数值是63,这是16进制,转换10进制:
0:005> ? 63
Evaluate expression: 99 = 00000063
正好是99,猜测靠谱。 修改一下这个值,看看雷个数是否跟着修改了。
0:005> ed winmine!cBombLeft 0
g运行起来,看一下界面:

果然变成0了,猜测正确。
我们还可以通过硬件断点进一步加深理解。
0:003> ba r4 winmine!cBombLeft
ba: 硬件断点break access
r:代表读写的时候都停下来,注意不是只读
4:表示监视4字节
g起来看看何时命中。一刷新就直接命中了。看一下堆栈


0:003> g
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=00001b4c edx=00000000 esi=01010dee edi=00000000
eip=010027af esp=000cfc48 ebp=766de761 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
winmine!DrawBombCount+0x2a:
010027af 85c0            test    eax,eax
0:000> k
ChildEBP RetAddr  
000cfc54 01002ad4 winmine!DrawBombCount+0x2a
000cfc60 01001c51 winmine!DrawScreen+0x11
000cfcb8 7512630a winmine!MainWndProc+0x88
000cfce4 75127326 USER32!InternalCallWinProc+0x23
000cfd5c 75126df8 USER32!UserCallWinProcCheckWow+0xd8
000cfdb8 75126e54 USER32!DispatchClientMessage+0xd5
000cfdf4 76ef010a USER32!__fnDWORD+0x2b
000cfe08 010830f0 ntdll!KiUserCallbackDispatcher+0x2e
WARNING: Frame IP not in any known module. Following frames may be wrong.
000cfe70 7512789a 0x10830f0
000cfe80 010023a4 USER32!DispatchMessageW+0xf
000cfee4 01003f95 winmine!WinMain+0x1b4
000cff88 746c343d winmine!WinMainCRTStartup+0x174
000cff94 76f19812 kernel32!BaseThreadInitThunk+0xe
000cffd4 76f197e5 ntdll!__RtlUserThreadStart+0x70
000cffec 00000000 ntdll!_RtlUserThreadStart+0x1b

为何命中点没有在访问winmine!cBombLeft ? 原因是硬件断点的命中时事后的,访问完成了才命中。软件断点是事前的
可以向前反汇编看看,可以看到访问winmine!cBombLeft 
0:000> ub
winmine!DrawBombCount+0x15:
0100279a 8bd8            mov     ebx,eax
0100279c 895c2414        mov     dword ptr [esp+14h],ebx
010027a0 83e301          and     ebx,1
010027a3 7405            je      winmine!DrawBombCount+0x25 (010027aa)
010027a5 6a00            push    0
010027a7 56              push    esi
010027a8 ffd5            call    ebp
010027aa a194510001      mov     eax,dword ptr [winmine!cBombLeft (01005194)]

好了,我们删除这个断点然后继续研究:
0:000> bl
 0 e 01005194 r 4 0001 (0001)  0:**** winmine!cBombLeft
0:000> bc 0

雷个数已经是0了,但游戏并为结束,那是因为没有执行gameover的过程,我们找一下有没有相关函数。
0:000> x winmine!*gameover*
0100347c winmine!GameOver = <no type information>

需要找到窗口线程执行,win7后一般是0号线程,我们观察一下:
0:003> ~* k

   0  Id: 1b4c.580 Suspend: 1 Teb: 7efdd000 Unfrozen
ChildEBP RetAddr  
000cfe58 7512791d USER32!NtUserGetMessage+0x15
000cfe74 010023ad USER32!GetMessageW+0x33
000cfee4 01003f95 winmine!WinMain+0x1bd
000cff88 746c343d winmine!WinMainCRTStartup+0x174
000cff94 76f19812 kernel32!BaseThreadInitThunk+0xe
000cffd4 76f197e5 ntdll!__RtlUserThreadStart+0x70
000cffec 00000000 ntdll!_RtlUserThreadStart+0x1b

   1  Id: 1b4c.1e10 Suspend: 1 Teb: 7efda000 Unfrozen
ChildEBP RetAddr  
026ffd70 76541775 ntdll!NtWaitForMultipleObjects+0x15
026ffe0c 746c19fc KERNELBASE!WaitForMultipleObjectsEx+0x100
026ffe54 746c268c kernel32!WaitForMultipleObjectsExImplementation+0xe0
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SysWOW64\winhadnt.dll - 
026ffe70 711418c1 kernel32!WaitForMultipleObjects+0x18
WARNING: Stack unwind information not available. Following frames may be wrong.
026ffe94 7114280f winhadnt!DelPassthru+0xdf1
026fff88 746c343d winhadnt!DelPassthru+0x1d3f
026fff94 76f19812 kernel32!BaseThreadInitThunk+0xe
026fffd4 76f197e5 ntdll!__RtlUserThreadStart+0x70
026fffec 00000000 ntdll!_RtlUserThreadStart+0x1b

   2  Id: 1b4c.1e18 Suspend: 1 Teb: 7efd7000 Unfrozen
ChildEBP RetAddr  
025efdf4 76f2f68f ntdll!NtWaitForMultipleObjects+0x15
025eff88 746c343d ntdll!TppWaiterpThread+0x32e
025eff94 76f19812 kernel32!BaseThreadInitThunk+0xe
025effd4 76f197e5 ntdll!__RtlUserThreadStart+0x70
025effec 00000000 ntdll!_RtlUserThreadStart+0x1b

#  3  Id: 1b4c.1e04 Suspend: 1 Teb: 7ef9f000 Unfrozen
ChildEBP RetAddr  
0362ff58 76f7f3e6 ntdll!DbgBreakPoint
0362ff88 746c343d ntdll!DbgUiRemoteBreakin+0x3c
0362ff94 76f19812 kernel32!BaseThreadInitThunk+0xe
0362ffd4 76f197e5 ntdll!__RtlUserThreadStart+0x70
0362ffec 00000000 ntdll!_RtlUserThreadStart+0x1b

确实是0号线程,切换到0号线程,然后修改eip的值为gameover函数,然后g
0:003> ~0s
eax=00000001 ebx=00000001 ecx=00000000 edx=00000000 esi=000cfec0 edi=00000000
eip=751278e7 esp=000cfe58 ebp=000cfe74 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
USER32!NtUserGetMessage+0x15:
751278e7 83c404          add     esp,4

0:000> r eip=0100347c
然后g,结果:


看一下堆栈:
0:003> ~0s
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000102 edi=000cfda0
eip=7513352d esp=000cfd8c ebp=000cfdc8 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
USER32!NtUserWaitMessage+0x15:
7513352d 83c404          add     esp,4
0:000> k
ChildEBP RetAddr  
000cfd8c 75152139 USER32!NtUserWaitMessage+0x15
000cfdc8 7515234f USER32!DialogBox2+0x222
000cfdf4 7515227d USER32!InternalDialogBox+0xe5
000cfe14 751523fc USER32!DialogBoxIndirectParamAorW+0x37
000cfe38 01001b9f USER32!DialogBoxParamW+0x3f
000cfe50 0100350a winmine!DoEnterName+0x1e
000cfe58 7512791d winmine!GameOver+0x8e
000cfe74 010023ad USER32!GetMessageW+0x33
000cfee4 01003f95 winmine!WinMain+0x1bd
000cff88 746c343d winmine!WinMainCRTStartup+0x174
000cff94 76f19812 kernel32!BaseThreadInitThunk+0xe
000cffd4 76f197e5 ntdll!__RtlUserThreadStart+0x70
000cffec 00000000 ntdll!_RtlUserThreadStart+0x1b

确实在执行winmine!GameOver,游戏结束。获得最短时间取胜:


windbg真强大!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值