首页
社区
课程
招聘
[求助]请问如何在WM里取得电话通话界面以及里面按钮的句柄
发表于: 2009-4-2 16:14 13072

[求助]请问如何在WM里取得电话通话界面以及里面按钮的句柄

2009-4-2 16:14
13072

如果你是有一个818/828+手机的人,那么你一定会知道最近火爆的Cotulla WM6 ROM的事情,但是这个ROM里通话界面“打开扬声器”功能是没法用的,花了半天时间分析发现是WM6的cprog.exe只是简单的调用了一下ossvcs.dll的导出函数#218,然后跟到ossvcs.dll发现果然也是调用DeviceIoControl实现的功能,但是这个里面预置的代码跟能在818手机中工作的代码有很大区别,本来想给它做点修改的,后来发现这是ROM封装文件没法改,现在的思路是从外面挂一个后台exe或dll在电话界面中做处理。

但是基本没写过WM下的代码,也不方便调试,所以想问下WM下获得窗体名的是用FindWindow吗?有什么需要注意的地方?电话通话界面的类标识是什么?


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (27)
雪    币: 2604
活跃值: (64)
能力值: (RANK:510 )
在线值:
发帖
回帖
粉丝
2
一般桌面平台有的API在WM都有,找不到解决方法时可以尝试用桌面平台的解法试试。
前面我写程序的时候就是使用FindWindow来查找窗体句柄的。没有发现什么特别需要注意的地方。

VS2005/2008都有Visual Studio Remote Tools,其中有一个工具是“远程监视”可以连接设备,监视设备中的窗体信息。

我做过模拟器连接、监视的实验可以得到所有窗体信息。建议你把真机连上,打开AcitiveSync连接,用“远程监视”连接查看。看看能不能得到你需要的信息。

祝你成功!
2009-4-2 16:30
0
雪    币: 2604
活跃值: (64)
能力值: (RANK:510 )
在线值:
发帖
回帖
粉丝
3
这是连接模拟器上看到的截图。
上传的附件:
2009-4-2 16:43
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
谢谢版主了,晕死,在我这个WM6上连接不了。

另外我发现FindWindowEx在CE里没有的,那我用FindWindow("MSCprog",NULL)找到电话句柄后如何进一步去得到它里面各个按钮的Handle?谢谢
2009-4-2 18:14
0
雪    币: 2604
活跃值: (64)
能力值: (RANK:510 )
在线值:
发帖
回帖
粉丝
5
你说的WM6是真机?现在我这里没有真机不太清楚,是不是连接设置上有什么问题?
慢慢来不要着急。

你说的对。MSDN中没有看到WM平台FindWindowEx的介绍。可能WM不支持这个API。

对于你说的问题我估计有以下3种方法可能可以解决:

01、使用GetWindow()函数。
     通过循环可以查找子窗体或父窗体,从而找到你想要的按钮句柄。

02、使用WindowFromPoint()函数
     可以得到指定位置的窗体的句柄。

03、使用EnumWindows()函数。
     此函数可以枚举所有窗体,看能不能设置条件找到你需要的。

     这3个API都是WM支持的。感觉前两个比较容易成功。 加油。
2009-4-2 19:24
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
谢谢版主,等我写成功了,把源代码丢上来,也好让后面的人少走弯路,做做贡献

另外,是真机+WM6.1 ROM,通话界面里的免提功能无效,是它那个按钮呼叫的api在这个WM6上使用无效。
分析文在此:
http://bbs.pdafans.com/thread-720625-1-1.html

可能ROM比较特殊的原因,毕竟不是官方做的,是一个俄罗斯人自己弄出来的。
http://www.cotulla.pp.ru/Magician.html
2009-4-2 20:18
0
雪    币: 2604
活跃值: (64)
能力值: (RANK:510 )
在线值:
发帖
回帖
粉丝
7
好的!谢谢!
形成互动,大家的学习、研究、发布的热情都高了,进步就会很快!
2009-4-2 20:31
0
雪    币: 81
活跃值: (41)
能力值: (RANK:220 )
在线值:
发帖
回帖
粉丝
8
楼主,你好像给我来信过。CeleDial是这样实现的:
1. 把自己伪装成一个 Phone Canvas Skin 扩展,让cprog.exe装载自己。
2. 装载后转发所有的Skin API到原来的Skin扩展中(如果有)
3. 创建一个线程查找电话程序主窗口,SubClass它,这样就可以处理所有的消息了。

针对你的情况,你可以截获到打开扬声器的WM_COMMAND的wParam参数,然后然后用 HWND hWnd = FindWindow(TEXT("MSCProg"), NULL) 来查找更简单,找到后发送一个 WM_COMMAND消息即可。
2009-4-2 21:36
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
9
宇宙杰出青年来了……拜高人ing……
从早几年用Smartphone开始就在用你的CeleTask,后来用上了ppc就一直在用CeleDial,甚至818最初的汉化包也是靠CeleCmd来释放文件和改注册表的,我后来为818 WM6打造的定制工具里一键安装功能也是看了CeleCmd的脚本思路而想到的(当然我是自己实现的CreateProcess不是调用CeleCmd哈),激动得~~~~~~颤抖ing~~~抽搐中~~~



不过我又带着问题回来了-_-

我在一个SetTimer里用GetForegroundWindow获取最前面的窗口Handle,然后用FindWindow("MSCprog", NULL)取得电话托管程序的Handle。

我的思路是当两个Handle相同时,则认定用户当前的操作是在电话通话界面中。

理论上应该没问题吧……

但是实际测试了下发现问题来了,两个Handle始终不能一样,如图:


Window Handle是CProg.exe的Handle
Current Handle是用户切换当前窗体的Handle

2080842800是CProg的Handle
当Current Handle变成2080893856的时候,是我进入电话界面的时候。

这两个Handle为啥不同?我晕了
上传的附件:
2009-4-2 22:35
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
10
难道我得用查找窗体标题的方法来锁定电话界面?~~~>_<~~~但是有人把电话界面标题改了怎么办,例如那些CallerLoc啥的,或者……或者……为什么两个Handle不同呢~~~>_<~~~电话界面是一个类名CProg.exe又是另一个类名?

补充一下:我是想获得这个窗口的句柄,可能它不是CProg……


再次补充:
我用GetClassName抓到这家伙了,果然不是CProg!但是它的名字也平常的很……Dialog……这样的类名一抓就一大把……我尝试抓“电话”标题,但是失败了……
上传的附件:
2009-4-2 22:56
0
雪    币: 2604
活跃值: (64)
能力值: (RANK:510 )
在线值:
发帖
回帖
粉丝
11
Yonsm出手就是不一样!
2009-4-3 07:43
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
12
~~~~~~~~~~我抓不到我想要的电话窗口Handle :(
2009-4-3 09:08
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
13
我无奈了,用GetForegroundWindow+GetClassName+GetWindowText一起抓,结果发现我想要的界面和电话界面是两个不同的界面……

Current Text为空的就是我想要的“通话状态”窗口
Current Text为“电话”的是拨号界面窗口
上传的附件:
2009-4-3 10:14
0
雪    币: 81
活跃值: (41)
能力值: (RANK:220 )
在线值:
发帖
回帖
粉丝
14
既然这么多条件,建议你用TaskMgr分析一下电话程序的窗口,找个以比较完全的解决方案。

TaskMgr: http://www.yonsm.net/read.php?428

因为Dialog不能标识唯一,你可以找他的儿子嘛。举例说明:
你枚举一下所有顶级窗口,每个顶级窗口GetDlgItem(0x59DF)一下,如果有,查一下这个控件的ClassName,如果是MS_PHONE_ELAPSEDTIME,那就父窗口就是你要找的窗口中。
2009-4-3 19:52
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
15
谢谢宇宙青年,我去翻翻看。
2009-4-3 20:16
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
16
You make it!
成功了!
谢谢版主和宇宙青年!我可以继续下一步工作了!
(我写测试代码的时候习惯用VB.NET……)

    Private Function FindPhoneHandle() As Integer
        Dim lpForeground As Integer = 0
        Dim lpNextWindow As Integer = 0
        FindPhoneHandle = 0
        Dim lpClassName As New StringBuilder("", 50)
        lpForeground = GetForegroundWindow
        If lpForeground = 0 Then Return 0
        lpNextWindow = GetWindow(lpForeground, GW_CHILD)
        lpNextWindow = GetWindow(lpNextWindow, GW_HWNDFIRST)
        Do Until lpNextWindow = 0
            GetClassName(lpNextWindow, lpClassName, lpClassName.Capacity)
            If Trim(lpClassName.ToString.Replace(vbNullChar, "")) = "MS_PHONE_BRANDING" Then
                Return lpForeground
            End If
            lpNextWindow = GetWindow(lpNextWindow, GW_HWNDNEXT)
        Loop
    End Function
上传的附件:
2009-4-3 21:52
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
17
嘿嘿嘿嘿嘿嘿嘿……

HWND FindPhoneHandle(){
        HWND lpNextWindow = NULL;
        HWND lpForeground = NULL;
        TCHAR lpClassName[64];

        lpForeground =GetForegroundWindow();

        if(lpForeground==NULL) return 0;

        lpNextWindow = GetWindow(lpForeground, GW_CHILD);
        lpNextWindow = GetWindow(lpNextWindow, GW_HWNDFIRST);

        while(lpNextWindow!=0){
                GetClassName( lpNextWindow,lpClassName,64);
                _debug(L"Main Handle:%d,ClassName:%s",lpForeground,lpClassName);
                if(!_tcscmp(lpClassName,TEXT("MS_PHONE_BRANDING"))){
                        _debug(L"Main Handle:%d,ClassName:%s,Found!!!!",lpForeground,lpClassName);
                        return lpForeground;
                }
                lpNextWindow = GetWindow(lpNextWindow, GW_HWNDNEXT);
        }
        return 0;
}  

测试结果:
[22:59:52] msg.message:275
[22:59:52] Main Handle:2080989168,ClassName:ToolbarWindow32
[22:59:52] Main Handle:2080989168,ClassName:ATL:01F6B6C8
[22:59:52] Main Handle:2080989168,ClassName:static
[22:59:53] msg.message:275
[22:59:53] Main Handle:2080989168,ClassName:ToolbarWindow32
[22:59:53] Main Handle:2080989168,ClassName:ATL:01F6B6C8
[22:59:53] Main Handle:2080989168,ClassName:static
[22:59:54] msg.message:275
[22:59:54] Main Handle:2080855248,ClassName:SysListView32
[22:59:54] Main Handle:2080855248,ClassName:MS_PHONE_LAYOUTHELPER
[22:59:54] Main Handle:2080855248,ClassName:MS_PHONE_INVALIDPHONE
[22:59:54] Main Handle:2080855248,ClassName:MS_PHONE_BRANDING
[22:59:54] Main Handle:2080855248,ClassName:MS_PHONE_BRANDING,Found!!!!

[23: 0: 1] msg.message:275
[23: 0: 1] Main Handle:2080894096,ClassName:MS_PHONE_LAYOUTHELPER
[23: 0: 1] Main Handle:2080894096,ClassName:MS_PHONE_INVALIDPHONE
[23: 0: 1] Main Handle:2080894096,ClassName:MS_PHONE_BRANDING
[23: 0: 1] Main Handle:2080894096,ClassName:MS_PHONE_BRANDING,Found!!!!
[23: 0: 2] msg.message:275
[23: 0: 2] Main Handle:2080989168,ClassName:ToolbarWindow32
[23: 0: 2] Main Handle:2080989168,ClassName:ATL:01F6B6C8
[23: 0: 2] Main Handle:2080989168,ClassName:static
[23: 0: 3] msg.message:275
[23: 0: 3] Main Handle:2080989168,ClassName:ToolbarWindow32
[23: 0: 3] Main Handle:2080989168,ClassName:ATL:01F6B6C8
[23: 0: 3] Main Handle:2080989168,ClassName:static
2009-4-3 23:01
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
18
才留意到宇宙青年改了帖子。
GetDlgItem和getwindow哪个效率更高些?
改成MS_PHONE_ELAPSEDTIME也行,是不是为了更好的确定用户当前是在通话状态界面里?

[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_LAYOUTHELPER
[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_INVALIDPHONE
[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_BRANDING
[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_LAYOUTHELPER
[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_STATUSICONS
[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_CALLSTATE
[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_ELAPSEDTIME
[23:14:43] Main Handle:2080894096,ClassName:MS_PHONE_ELAPSEDTIME,Found!!!!
2009-4-3 23:16
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
19
我在程序里对抓到的电话界面做消息拦截,用了Hook,结果一开电话绿色拨号按键(硬件按键)就不起作用了,界面的绿色按键还能用,然后通话开始,电话死掉……真惨……Hook错了?

WNDPROC s_OldWndProc = NULL;
HWND lpGlobHookHwnd = NULL;

LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
        if(timerID!=0){
                KillTimer(NULL,timerID);
                timerID=0;
                _debug(L"Timer killed");
        }

        switch (uMsg)
        {
        case WM_KEYDOWN:
                {
                        _debug(L"WM_KEYDOWN:%d,%d:",(int)wParam,(int)lParam);
                        break;
                }
        case WM_DESTROY:
                {
                        /*if (s_hExit)
                        {
                        _debug(L"Posting exit msg...");
                        SetEvent(s_hExit);
                        }*/
                        SetWindowLong(lpGlobHookHwnd, GWL_WNDPROC, (DWORD)s_OldWndProc);
                        break;
                }
                return CallWindowProc(s_OldWndProc, hwnd, uMsg, wParam, lParam);
        }
        return 0;//DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int SetHook(HWND lpHookHwnd){
        //s_hExit = CreateEvent(NULL, FALSE, FALSE, NULL);

        if (lpHookHwnd!=NULL)
        {
                lpGlobHookHwnd=lpHookHwnd;
                //s_OldWndProc = (WNDPROC)GetWindowLong(lpHookHwnd, GWL_WNDPROC);
                s_OldWndProc = (WNDPROC)SetWindowLong(lpHookHwnd, GWL_WNDPROC, (DWORD)NewWndProc);
                _debug(L"Hooked");
                //WaitForSingleObject(s_hExit, INFINITE);
                //SetWindowLong(lpHookHwnd, GWL_WNDPROC, (DWORD)s_OldWndProc);
        }
        return 0;
}
2009-4-4 01:34
0
雪    币: 2604
活跃值: (64)
能力值: (RANK:510 )
在线值:
发帖
回帖
粉丝
20
恭喜,恭喜!谢谢分享,继续加油!
2009-4-4 08:57
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
21
~~~~~~>_<~~~~~~ 我hook不了那个句柄
2009-4-4 09:18
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
22
突然想到,在Win32编程下,要实现SetWindowLong配合GWL_WNDPROC做hook,必须用注入,让两个进程在同一个内存空间里执行,宇宙青年的CeleDial是写成DLL形式让cprog加载的,也就是默认就成为了cprog内存空间里的一个模块了,是不是因为这样才Hook成功的?CE平台里的内存保护机制也有这个限制吗?但是我有几次做记录文件的时候能发现hook到了WM_KEYDOWN消息?

初次接触CE平台就弄得太复杂了点……@#$#@%@#%@#^
2009-4-4 09:40
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
23
写了个TestHook代码抓我自己的NETCF程序发现也能把那程序给弄死了#$#@%@#%
发现问题根源了,CallWindowProc放错地方,我给return 0了:
default:
                return CallWindowProc(s_OldWndProc, hwnd, uMsg, wParam, lParam);
        }
        return CallWindowProc(s_OldWndProc, hwnd, uMsg, wParam, lParam);//DefWindowProc(hwnd, uMsg, wParam, lParam);
2009-4-4 10:59
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
24
~~~~>_<~~~~~~ 装了WM6 SDK和模拟器也仍然没法连接上……查看不了消息……目前只知道id被定义为23028的MS_PHONE_BUTTON类是“扬声器”按钮,但是没法拦截到用户点击界面上button的消息……WM_KEYDOWN、WM_COMMAND、WM_NOTIFY全用上了,一根鸟毛都没抓到……
2009-4-4 12:57
0
雪    币: 164
活跃值: (10)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
25
终于写出一个能用的DllInjector以及把我的注入代码测试通过了,不过怎么会有两次DLL_PROCESS_DETACH消息……

[10:24: 6] Speakphone Dll started
[10:24: 6] Speakphone Dll unloaded
[10:24: 6] Speakphone set func called
[10:24: 6] Speakphone Dll unloaded

不管了,应该能用,开始正式写实际工作的DLL……

http://bbs.pdafans.com/viewthread.php?tid=722223
2009-4-5 10:37
0
游客
登录 | 注册 方可回帖
返回
//