首页 > 系统相关 >偷换windows窗口过程

偷换windows窗口过程

时间:2022-11-07 20:33:16浏览次数:35  
标签:WndProc 窗口 偷换 windows Button InternalCallWinProc 00000000 000 USER32


    ​​ Window user32子动态库控件封装和消息分发浅析​​  这篇文章提到窗口程序在分发消息时会依次调用:UserCallWinProcCheckWow--->_InternalCallWinProc-->各个窗口程序的WndProc。各类控件的窗口程序不同,比如Button控件用的是Button_WndProc,程序通过_InternalCallWinProc最终进入Button_WndProc对Button事件处理。受到这篇文章的启示,我尝试用windbg修改calc.exe的窗口程序,并记录于此。

    网上一些文章提及万能消息断点时,无不例外的都会带到_InternalCallWinProc这个函数,综合各家所言和自己调试的过程,我得到如下结论:

1._InternalCallWinProc的函数接口可能为:

_InternalCallWinProc(WndProc*,Hwnd,UINT,WPARAM,LPARAM);

参数1是程序在调用RegisterClass(Ex)时注册的窗口过程,参数2是接收消息的窗口的句柄,参数3是消息号。从参数2到参数5,类似于传递给WndProc接口的参数。

2.在_InternalCallWinProc函数中会以参数1传入的函数指针作为消息的窗口过程,将参数2-5压栈传给它并跳转到该窗口过程。可能的实现如下(xp):

_InternalCallWinProc()
{
(*WndProc)(Hwnd,UINT,WPARAM,LPARAM);
}

(win7)


_InternalCallWinProc()
{
push LPARAM
push WPARAM
push UINT
push Hwnd
jmp WndProc
}

    回到我的正题上,我要做的是偷换窗口过程。xp到win7都没有检测函数指针WndProc的合法性(至少在windbg中是这样),所以,我们可以把这个指针值偷换为其他代码(可以通过注入代码的形式实现)。作为演示的目的,我把calc.exe按键7的WndProc替换为ExitProcess函数,以下为实现步骤:

1.用spy++定位按键7的句柄:

偷换windows窗口过程_调试

2.windbg attach到calc.exe,设置符号并查找符号_InternalCallWinProc

0:001> x *!*internalcall* @查找符号InternalCallWinProc地址
77d1870c USER32!InternalCallWinProc = <no type information>
0:001> x *!Button_* @查找Button控件符号地址
771a7725 comctl32!Button_CalcRect = <no type information>
0:001> bp USER32!InternalCallWinProc
0:001> g
Breakpoint 0 hit
USER32!InternalCallWinProc:
77d1870c 55 push ebp
0:000> kb
ChildEBP RetAddr Args to Child
00>0007fd30 77d18816 7365912a 000101b2 00000219 USER32!InternalCallWinProc
01>0007fd98 77d189cd 00000000 7365912a 000101b2 USER32!UserCallWinProcCheckWow+0x150
02>0007fdf8 77d18a10 0007fee8 00000000 0007ff1c USER32!DispatchMessageWorker+0x306
03>0007fe08 010021a7 0007fee8 7c80b731 000a2348 USER32!DispatchMessageW+0xf
...
0007fff0 00000000 01012475 00000000 78746341 kernel32!BaseProcessStart+0x23
@栈回溯00>处的0x7365912a是计算机窗口过程的函数指针
0:000> ln 7365912a
(7365912a) msctfime!UIWndProc | (7365913a) msctfime!CtfImeDestroyInputContext
Exact matches:
msctfime!UIWndProc (<no parameter info>)
@查看地址0x7365912a附近的符号是msctfime!UIWndProc,有点像一个窗口过程

3.准备下条件断点。来分析一下断点要满足的需求:如果我们在Button控件(Button控件的窗口过程为comctl32!Button_CalcRect)"7"(spy++显示句柄值0x001016A判断)上按下左键(消息值为0x201)时,使windbg中断。把这段话转变为windbg能理解的命令:

0:000> bp comctl32!Button_WndProc ".if(dwo(esp+4)==0001016A&dwo(esp+8)==201){.echo Button7Down;}.else{gc;}"
0:000> g

其中dwo(esp+4)用于判断按键7的窗口句柄值,dwo(esp+8)用于判断消息值是否为左键按下。我们看下断点的效果:

偷换windows窗口过程_函数指针_02


    当我按下7,windbg在输出窗口输出"Button7Down",看来断点生效了~再来看下调用堆栈:

0:000> kb
ChildEBP RetAddr Args to Child
00> 0007fd04 77d18734 0001016a 00000201 00000001 comctl32!Button_WndProc
01> 0007fd30 77d18816 771a8eb4 0001016a 00000201 USER32!InternalCallWinProc+0x28
02> 0007fd98 77d189cd 00000000 771a8eb4 0001016a USER32!UserCallWinProcCheckWow+0x150
03> 0007fdf8 77d18a10 0007fee8 00000000 0007ff1c USER32!DispatchMessageWorker+0x306
04> 0007fe08 010021a7 0007fee8 7c80b731 000a2348 USER32!DispatchMessageW+0xf
...
0007ffc0 7c817067 00330039 00360037 7ffd3000 calc+0x125e9
0007fff0 00000000 01012475 00000000 78746341 kernel32!BaseProcessStart+0x23

按调用栈可以看到是USER32!InternalCallWinProc调用了comctl32!Button_WndProc,现在我们回过头来看下前面我得到的结论对不对----USER32!InternalCallWinProc的参数1存放了处理消息的窗口过程:

0:000> ln 771a8eb4 
(771a8eb4) comctl32!Button_WndProc | (771a99c9) comctl32!InitButtonClass
Exact matches:
comctl32!Button_WndProc = <no type information>

果不其然,0x771a8eb4是Button控件的消息处理函数!

    既然USER32!InternalCallWinProc对参数1传入的值不加甄别,我完全可以对USER32!InternalCallWinProc下同样的条件断点,触发断点后在函数入口处修改参数1的值,把他指向进程空间中其他一段可执行代码,那就ExitProcess了:

0:000> x *!*ExitProcess*
7c81cafa kernel32!ExitProcess = <no type information>
0:000> bp USER32!InternalCallWinProc ".if(dwo(esp+8)==0001016A&dwo(esp+c)==201){.echo Button7Down;}.else{gc;}"
0:000> g
Button7Down
eax=c0000000 ebx=00000000 ecx=40000000 edx=00000040 esi=771a8eb4 edi=0007fd6c
eip=77d1870c esp=0007fd34 ebp=0007fd98 iopl=0 ov up ei ng nz na pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000a87
USER32!InternalCallWinProc:
77d1870c 55 push ebp
0:000> kb
ChildEBP RetAddr Args to Child
0007fd30 77d18816 771a8eb4 0001016a 00000201 USER32!InternalCallWinProc
0007fd98 77d189cd 00000000 771a8eb4 0001016a USER32!UserCallWinProcCheckWow+0x150
@注意传入给InternalCallWinProc的函数指针位于参数2,所以要修改的是esp+8
0:000> ed 0007fd30+8 7c81cafa
0:000> g
eax=000000c0 ebx=00000102 ecx=77d2b401 edx=0007f720 esi=000000d4 edi=00000000
eip=7c92e4f4 esp=00bfff24 ebp=00bfff88 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet: <--------------进程退出
7c92e4f4 c3 ret

    修改参数2后,继续执行windbg马上就能看到进程退出,有意思吧?来看下任务栏的截图:

偷换windows窗口过程_控件_03


calc.exe已经不复存在,偷换成功~

本篇完~






标签:WndProc,窗口,偷换,windows,Button,InternalCallWinProc,00000000,000,USER32
From: https://blog.51cto.com/u_13927568/5831333

相关文章

  • windbg调试窗口过程WindowProc(winxp 32bit)
      ollydbg在调试窗口程序方面做得很便捷,虽然windbg在这方面不如od,但通过命令的组合也能达到类似的效果。我借winxp的calc.exe为例来谈谈如何用windbg调试窗口过程。 ......
  • Linux 挂载Windows共享文件夹和NAS存储
    summary:[Linux挂载共享存储]概述将Windows共享文件夹和NAS存储挂载至Linux。Linux系统环境:CentOS挂载共享存储查看外部主机共享了哪些目录smbclient-L//10.1......
  • windows防火墙支持FTP服务的设置方法
    2003server用于提供web和ftp服务,通过互联网用flashfxp实现远程上传网页。如果关闭防火墙,ftp上传下载正常,但启用windows防火墙后就不行,即使把web、ftp等服务列为例外也不行......
  • windows设备停用启动杂记
      公司(OEM厂商)的电脑升级到win10RS2RTM后,发现有部分MSinbox驱动在电源事件后会出现黄标的现象(ErrorCode=43--QueryRemove失败)甚至driverlost。MS虽然承认是他们......
  • 在Windows 2000 Server系统光盘中集成SP4更新程序
    Windows2000Server操作系统以其稳定的性能依然服役于很多作为服务器的计算机中,目前其最新版本已经集成了SP4累积更新程序。本教程将介绍在未集成任何ServicePack的Wind......
  • OpenStack的Windows镜像制作
    基础环境安装yumgroupinstallVirtualization"VirtualizationClient"yuminstalllibvirt启动服务systemctlenablelibvirtdsystemctlstartlibvirtdsystemctl......
  • Windows常用快捷键
    Windows常用快捷键01-Ctrl系列快捷键Ctrl+C:复制Ctrl+V:粘贴Ctrl+A:全选Ctrl+X:剪切Ctrl+Z:撤销Ctrl+S:保存Ctrl+N:快速创建同级界面Ctrl+W:关闭当前界面......
  • Windows 环境下 jfinal-undertow 启动脚本
    @echooffrem启动入口类setMAIN_CLASS=com.dsideal.StartremJava命令行参数,根据需要开启下面的配置,改成自己需要的,注意等号前后不能有空格remset"JAVA_OPTS......
  • windows平台下软件最小化后无法打开的解决方法
       今天打开电脑后,双击桌面软件图标,软件启动画面出现,等了几秒后直接最小化窗口,感觉有点奇怪。点击任务栏图标后没有反应,软件界面没出现。以为软件是不是安装破损什么......
  • Nginx(负载均衡Windows部署)
    目的:发布的Web接口,当大批量并发访问时,会出现响应慢问题;原理:当访问者大批量访问时,用五台服务器部署同样的接口程序,来分压,对于访问者来说只要访问Nginx,Ngin来根据配置,分配......