3

我需要从 win 计算器 (calc.exe) 中获取所有控件的列表,然后从我的应用程序中按下 calc 上的按钮。我尝试了代码注入,现在可以从 calc 应用程序执行我的代码。在示例中,它发送消息框:

#define PROC_NAME _T("calc.exe")
#define MAX_READ 128
#include <windows.h>
#include <tlhelp32.h>

#pragma comment(linker,"/BASE:0x13140000") 

//-------- My code, which will be executed  from the app-------

DWORD WINAPI func(LPVOID)
{
    LoadLibrary(_T("kernel32.dll")); 
    LoadLibrary(_T("user32.dll"));
    MessageBox(0,_T("Hello from addres area of calculator"),_T("title"),0);
    return true;
}

//-------- find process ---------

DWORD GetProcessID(LPCWSTR lpNameProcess) 
{
    HANDLE snap;
    PROCESSENTRY32 pentry32;
    snap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(snap==INVALID_HANDLE_VALUE) return 0;
    pentry32.dwSize=sizeof(PROCESSENTRY32);
    if(!Process32First(snap,&pentry32)) {CloseHandle(snap);return 0;}
    do
    {
        if(!lstrcmpi(lpNameProcess,&pentry32.szExeFile[0]))
        {
            CloseHandle(snap);
            return pentry32.th32ProcessID;
        }
    }
    while(Process32Next(snap,&pentry32));
    CloseHandle(snap);
    return 0;
}

//-------- injection to another process -------------------

BOOL Inject(HANDLE hProc,DWORD(WINAPI* func)(LPVOID))
{
    DWORD id;
    DWORD ByteOfWriten;
    HMODULE hModule = GetModuleHandle(NULL);
    DWORD size=((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE*)(hModule)+((PIMAGE_DOS_HEADER)(hModule))->e_lfanew+sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER))))->SizeOfImage;
    char* hNewModule = (char*)VirtualAllocEx(hProc,hModule,size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    if(hNewModule==NULL) return false;
    WriteProcessMemory(hProc,hNewModule,hModule,size,&ByteOfWriten);
    if(ByteOfWriten!=size){return false;}
    HANDLE hThread=CreateRemoteThread(hProc,NULL,0,func,(LPVOID)hNewModule,0,&id);
    if(hThread==0) return false;
    return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
    if(!Inject(OpenProcess(PROCESS_ALL_ACCESS,false,GetProcessID(PROC_NAME)),&func)) return false;
}

但是我怎样才能使按钮单击并从 calc 上的某些控件中获取文本?

我如何尝试枚举子窗口:

HWND hwnd, child;
    child = NULL;
    char buf[MAX_STR];          
    hwnd = getMyWnd();  // my own func, returns hwnd to main window 
    do 
    {
        //  here i tried to get child windows
        child = FindWindowExA(hwnd, child, NULL, NULL);
        GetWindowTextA( child, buf, MAX_STR - 1 );
        printf(buf); printf("\n");      
    } while (child != NULL);
4

2 回答 2

1

我假设您已经获得了所需的按钮句柄

如果是这样试试这个 - SendMessage(hButton, BN_CLICKED, 0, 0) 我不记得常量,你可能需要查找它们。

更新以获取按钮窗口句柄 - 1. 使用 EnumChildWindows() http://msdn.microsoft.com/en-us/library/ms633494(VS.85).aspx枚举计算器的子窗口

  1. 对于每个此类窗口,通过使用 GetWindowText http://msdn.microsoft.com/en-us/library/ms633520(VS.85).aspx检查其上的文本来查找其是否为按钮

  2. 制作一个所有按钮句柄的数组,然后点击它们,就像你的心内容一样:)

于 2011-03-08T16:52:29.280 回答
1

查看 MSDN 上的 MSAA 和 UIAutomation API - 它们旨在让一个应用程序获取有关另一个应用程序中的控件的信息,并且通常由自动化测试和可访问性工具和应用程序使用。

作为 Windows SDK 一部分的 inspect.exe 工具使用这些;您应该能够使用它来检查 calc 或其他各种应用程序中的按钮并与之交互。

Windows 中的所有系统控件都支持这些 API,许多其他应用程序(例如 IE、Firefox)也是如此;但它可能不适用于某些仅绘制自己的 UI 的 3rd 方应用程序。

于 2011-03-15T08:46:43.830 回答