首页
社区
课程
招聘
[原创]uia的c++教程,轻松控制别的程序
发表于: 2012-4-6 23:35 15931

[原创]uia的c++教程,轻松控制别的程序

2012-4-6 23:35
15931
UIA是UI Automation,是微软提供的一套自动化接口。具体是什么意思。通俗的将,就是微软的标准控件都实现一个接口,使使用UIA编程的程序可以控制这个控件。如果是自绘的控件实现相应接口也可以让UIA的程序控制。
举例来说。
你写个mfc程序,有个button,内容是弹一个MessageBox。你想领写个程序去间接调用这个button。学外挂的熟悉,就是注入找call。但我们使用UIA可以很轻松实现。
UIA编程msdn上也很详细,不过大部分都是.net,c++例子很少,而且是英文。我这里就简单实现个例子。
这次例子是调用这个Button。
UIA把所有可调用控件元素都是一个树形式保存的,具体可以以用Inspect.exe查看,这个sdk带的小软件。你打开后把鼠标移到相应位置可以得到该控件相应信息。如果不是微软标准控件而且没有实现他的接口就没办法了。如图就是,我们要调用button4按钮。



第一步 需要 实现IUIAutomation 接口
他可以用于以下
1,注册事件
2,建立条件,使减少搜索控件元素范围。
3,直接从root节点获得控件元素。
4,建立元素 树遍历
5,转换数据类型
代码
CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER,
                                IID_PPV_ARGS(&g_pIUAutomation));
这个接口是老大。IUIAutomation一些方法可以直接获得控件元素
 IUIAutomation::GetFocusedElement , IUIAutomation::GetRootElement
然后可以用IUIAutomationElement::FindFirst 和FindAll. 搜索自控件。

第二步 实现IUIAutomationElement,
可以理解为每个控件都可以是IUIAutomationElement。我们调用button就用他的ivoke方法
IUIAutomationCondition 是条件搜索。控件一大堆,想搜到我们想要的靠他。
#include "stdafx.h"
#include <uiautomation.h>
IUIAutomation *g_pIUAutomation=NULL;


//我们button 的名字 可以通过inspect找到
WCHAR wcButtonName1[]=L"Button4";	
HWND g_hwd=NULL;
int _tmain(int argc, _TCHAR* argv[])
{
     //因为是com所以你懂的
	HRESULT hr=CoInitialize(NULL);
	if(SUCCEEDED(hr))
	{	
		IUIAutomationElement* pRoot = NULL;
		IUIAutomationElement* pFound = NULL;
		IUIAutomationCondition* pCondition=NULL;
	    IUIAutomationInvokePattern *pPattern = NULL;
		do 
		{
		
			
			//初始化IUAutomation实例

			hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER, 
				IID_PPV_ARGS(&g_pIUAutomation));
			if(FAILED(hr))
			{
				printf("create IUAutomation instance failed ");
				break;
			}
			
			//创建条件搜索
			VARIANT varName;
			varName.vt=VT_BSTR;
			varName.bstrVal=SysAllocString(wcButtonName1);

			//这个是根据句柄获得该 句柄下所有的元素,我注释掉了
		//	hr=g_pIUAutomation->ElementFromHandle(g_hwd,&pRoot);
                       //获得根目录下,就是从开始 下所有控件元素
			hr=g_pIUAutomation->GetRootElement(&pRoot);
			 if (FAILED(hr) || pRoot == NULL)
			 {
				 printf("get root element failed/n");
				 break;
			 }
			 //创建条件搜索,根据我们button名字搜索
			 hr = g_pIUAutomation->CreatePropertyCondition(UIA_NamePropertyId, varName, &pCondition);
			 if(FAILED(hr))
			 {
				 printf("create condition  failed/n");
				 break;
			 }
			
				 pRoot->FindFirst(TreeScope_Subtree, pCondition, &pFound);

			 // pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);


		
			  //调用invoke
			 
			  hr = pFound->GetCurrentPatternAs(UIA_InvokePatternId, IID_PPV_ARGS(&pPattern));
			  hr = pPattern->Invoke();

		} while (FALSE);
		if(g_pIUAutomation!=NULL)
		{
			g_pIUAutomation->Release();
			g_pIUAutomation=NULL;
		}
		if(pRoot!=NULL)
		{
			pRoot->Release();
			pRoot=NULL;
		}
		if(pFound!=NULL)
		{
			pFound->Release();
			pFound=NULL;
		}
		if(pCondition!=NULL)
		{
			pCondition->Release();
			pCondition=NULL;
		}
		if(pPattern!=NULL)
		{
			pPattern->Release();
			pPattern=NULL;
		}
		
		 CoUninitialize();
	}
	else
	{
		printf("initialize com failed/n");
	}
	return 0;
}


uia的功能远远不只这些,还可以操纵list 等复杂控件,特别操作网页元素。当然前提是ie内核下的。Google浏览器是不行的。可以实现自动网页上的很多功能。比如订票的自动化了。总之这是套很好玩的接口。

[课程]Android-CTF解题方法汇总!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (14)
雪    币: 826
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
代码?想看,能贴上来,学习下
2012-4-6 23:43
0
雪    币: 3
活跃值: (118)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
我这能看见==!在贴一次

#include "stdafx.h"
#include <uiautomation.h>
IUIAutomation *g_pIUAutomation=NULL;

//我们button 的名字 可以通过inspect找到
WCHAR wcButtonName1[]=L"Button4";  
HWND g_hwd=NULL;
int _tmain(int argc, _TCHAR* argv[])
{
     //因为是com所以你懂的
  HRESULT hr=CoInitialize(NULL);
  if(SUCCEEDED(hr))
  {  
    IUIAutomationElement* pRoot = NULL;
    IUIAutomationElement* pFound = NULL;
    IUIAutomationCondition* pCondition=NULL;
      IUIAutomationInvokePattern *pPattern = NULL;
    do
    {
   
      
      //初始化IUAutomation实例

      hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&g_pIUAutomation));
      if(FAILED(hr))
      {
        printf("create IUAutomation instance failed ");
        break;
      }
      
      //创建条件搜索
      VARIANT varName;
      varName.vt=VT_BSTR;
      varName.bstrVal=SysAllocString(wcButtonName1);

      //这个是根据句柄获得该 句柄下所有的元素,我注释掉了
    //  hr=g_pIUAutomation->ElementFromHandle(g_hwd,&pRoot);
                       //获得根目录下,就是从开始 下所有控件元素
      hr=g_pIUAutomation->GetRootElement(&pRoot);
       if (FAILED(hr) || pRoot == NULL)
       {
         printf("get root element failed/n");
         break;
       }
       //创建条件搜索,根据我们button名字搜索
       hr = g_pIUAutomation->CreatePropertyCondition(UIA_NamePropertyId, varName, &pCondition);
       if(FAILED(hr))
       {
         printf("create condition  failed/n");
         break;
       }
      
         pRoot->FindFirst(TreeScope_Subtree, pCondition, &pFound);

       // pRoot->FindFirst(TreeScope_Children, pCondition, &pFound);

   
        //调用invoke
      
        hr = pFound->GetCurrentPatternAs(UIA_InvokePatternId, IID_PPV_ARGS(&pPattern));
        hr = pPattern->Invoke();

    } while (FALSE);
    if(g_pIUAutomation!=NULL)
    {
      g_pIUAutomation->Release();
      g_pIUAutomation=NULL;
    }
    if(pRoot!=NULL)
    {
      pRoot->Release();
      pRoot=NULL;
    }
    if(pFound!=NULL)
    {
      pFound->Release();
      pFound=NULL;
    }
    if(pCondition!=NULL)
    {
      pCondition->Release();
      pCondition=NULL;
    }
    if(pPattern!=NULL)
    {
      pPattern->Release();
      pPattern=NULL;
    }
   
     CoUninitialize();
  }
  else
  {
    printf("initialize com failed/n");
  }
  return 0;
}
2012-4-6 23:45
0
雪    币: 506
活跃值: (65)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习了。
长知识。
2012-4-7 07:41
0
雪    币: 93
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习了感谢分享
2012-4-7 07:47
0
雪    币: 576
活跃值: (1500)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
用这个东西要求你的对话框上面的 文字和控件ID 是唯一的,如果有重叠的情况,他是分辨不了的。个人感觉AutoIt3这个更好。
2012-4-7 08:15
0
雪    币: 3
活跃值: (118)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
这个是最简单的demo。创建条件搜索可以解决的。
比如hr=g_pIUAutomation->ElementFromHandle(g_hwd,&pRoot);
获得这个窗口下的元素,就可以解决和其他程序控件名字冲突。
用好IUIAutomationCondition这个接口可以解决很多问题
2012-4-7 10:07
0
雪    币: 49
活跃值: (33)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
不错 学习了
2012-4-7 14:43
0
雪    币: 20557
活跃值: (3780)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
Thank you very much
2012-4-7 14:49
0
雪    币: 259
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢楼主提供的例仔~~~
2012-4-21 23:02
0
雪    币: 259
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
楼主有这个库吗?。。。。。能发一下吗。。。。。
2012-4-21 23:33
0
雪    币: 1149
活跃值: (833)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
12
autoit3   better
2012-4-22 00:28
0
雪    币: 259
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
better now...........
2012-4-23 21:58
0
雪    币: 50
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
谢谢楼主分享经验
2012-4-23 22:58
0
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
都还行 呵呵
2012-4-23 23:44
0
游客
登录 | 注册 方可回帖
返回
//