修改远程窗口文本的动态连接库
常在所写的工具中用到这个功能,提取出来单独作为一个库。
2006-08-14

简易说明

远程更改文本作为常用的工具操作,包装成单独的小巧(毕竟需要挂到别的程序中)库以方便复用。
文件为源代码+编译参数,。

API:

LPCSTR __stdcall WGetRemoteTextA(HWND hWnd,LPCSTR sztext);
LPCSTR __stdcall WSetRemoteTextA(HWND hWnd,LPCSTR sztext);

源码

将以下源码保存成 WRT.BAT 放入安装了 masm32 的分区的任意目录中,双击编译。若存为其它名字,记得更改 %this% 变量。
  1 ;echo off
  2 ;cls
  3 ;goto make
  4 ;担心UNICODE有BUG。把原本定义UNICODE操作comment out了。
  5 MAXTEXTSIZE = 1000
  6 .386
  7 .model flat, stdcall
  8 option casemap :none
  9 
 10 include windows.inc
 11 include user32.inc
 12 include kernel32.inc
 13 
 14 includelib user32.lib
 15 includelib kernel32.lib
 16 
 17 .data
 18     bset            dd 0
 19 ;   bunicode        dd 0
 20     readflag        dd 0
 21     busying         dd 0    ;   another program calling this function will share the whole .data section.
 22                             ;   when the DLL is called simultaneously, this var is the semaphore.
 23     finished        dd 0    ;   if the title changed
 24     processid       dd 0    ;   the Target process id
 25     threadid        dd 0
 26     hhook           dd 0
 27     htarget         dd 0    ;   Target window :)
 28     targettext      db MAXTEXTSIZE+2 dup(?)
 29 .CODE
 30     hInstance dd 0
 31 LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD
 32     .if reason == DLL_PROCESS_ATTACH
 33         mov eax,hInstDLL
 34         mov hInstance,eax
 35     ;.elseif reason == DLL_PROCESS_DETACH
 36     ;.elseif reason == DLL_THREAD_ATTACH
 37     ;.elseif reason == DLL_THREAD_DETACH
 38     .endif
 39     mov eax,TRUE
 40     ret 12
 41 LibMain Endp
 42 WHookCall   proc ncode:DWORD,wParam:DWORD,lParam:DWORD
 43         mov eax,finished
 44         test eax,eax
 45         jnz hookignore
 46         invoke GetCurrentProcessId
 47         cmp eax,processid
 48         jne hookignore
 49         .if bset == 0
 50             invoke SendMessage,htarget,WM_GETTEXT,MAXTEXTSIZE,offset targettext
 51         .else
 52             invoke SendMessage,htarget,WM_SETTEXT,0,offset targettext
 53         .endif
 54         mov finished,1
 55 hookignore:;
 56     invoke CallNextHookEx,hhook,ncode,wParam,lParam
 57     ret 12
 58 WHookCall   endp
 59 WTextOperation  proc    hWnd:DWORD,sztext:DWORD
 60 wait0:
 61     mov eax,busying
 62     test eax,eax
 63     jne wait0
 64     invoke IsWindow,hWnd
 65     je invalidhwnd
 66     mov busying,1
 67     invoke GetWindowThreadProcessId,hWnd,offset processid
 68     mov threadid,eax
 69     invoke GetLastError
 70     test eax,eax
 71     jne Expection
 72 ;偷懒点,不去考虑当前进程的窗口了
 73 ;   invoke GetCurrentProcessId
 74 ;   .if processid == eax
 75 ;       .if bset == 0
 76 ;           invoke SendMessage,htarget,WM_GETTEXT,MAXTEXTSIZE,sztext
 77 ;       .else
 78 ;           invoke SendMessage,htarget,WM_SETTEXT,0,sztext
 79 ;       .endif
 80 ;       jmp Expection
 81 ;   .endif
 82     .if bset == 1
 83 ;       .if bunicode == 0
 84             invoke lstrcpynA,offset targettext,sztext,MAXTEXTSIZE
 85 ;       .else
 86 ;           invoke lstrcpynW,offset targettext,sztext,MAXTEXTSIZE/2
 87 ;       .endif
 88     .endif
 89     mov finished,0
 90     push hWnd
 91     pop htarget
 92     invoke SetWindowsHookEx,WH_CALLWNDPROC,offset WHookCall,hInstance,threadid
 93     mov hhook,eax
 94     invoke GetLastError
 95     test eax,eax
 96     jne Expection
 97     invoke SendMessage,hWnd,WM_GETTEXTLENGTH,0,0
 98     invoke GetLastError
 99     test eax,eax
100     jne Expection
101 notfinished:;
102     mov eax,finished
103     test eax,eax
104     je notfinished
105     invoke UnhookWindowsHookEx,hhook
106     mov hhook,0
107     .if bset==0
108 ;       .if bunicode == 0
109             invoke lstrcpynA,sztext,offset targettext,MAXTEXTSIZE
110 ;       .else
111 ;           invoke lstrcpynW,sztext,offset targettext,MAXTEXTSIZE/2
112 ;       .endif
113     .endif
114 invalidhwnd:;
115 Expection:;
116     mov busying,0
117     mov eax,sztext
118     ret 8
119 WTextOperation  endp
120 ;=================Unicode: ====================
121 ;WGetRemoteTextW    proc    hWnd:DWORD,sztext:DWORD
122 ;   mov bset,0
123 ;   mov bunicode,1
124 ;   invoke WTextOperation,hWnd,sztext
125 ;   ret 8
126 ;WGetRemoteTextW    endp
127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
128 ;WSetRemoteTextW    proc    hWnd:DWORD,sztext:DWORD
129 ;   mov bset,1
130 ;   mov bunicode,1
131 ;   invoke WTextOperation,hWnd,sztext
132 ;   ret 8
133 ;WSetRemoteTextW    endp
134 ;================Ansi: ========================
135 WGetRemoteTextA proc    hWnd:DWORD,sztext:DWORD
136     mov bset,0
137     ;mov bunicode,0
138     invoke WTextOperation,hWnd,sztext
139     ret 8
140 WGetRemoteTextA endp
141 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
142 WSetRemoteTextA proc    hWnd:DWORD,sztext:DWORD
143     mov bset,1
144     ;mov bunicode,0
145     invoke WTextOperation,hWnd,sztext
146     ret 8
147 WSetRemoteTextA endp
148 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
149 
150 End LibMain
151 
152 :make
153 set this=WRT
154 set include=%include%;\masm32\include
155 set lib=%lib%;\masm32\lib
156 \masm32\bin\ml /c /coff /nologo %this%.bat
157 rem link option
158 if exist %this%.bat \masm32\bin\link /SUBSYSTEM:WINDOWS /DLL /NOLOGO /merge:.rdata=.text /section:.text,RWE /section:.data,rws /EXPORT:WSetRemoteTextA /EXPORT:WGetRemoteTextA %this%.obj
159 del %this%.obj
160 pause