谁有办法通过一个HIMAGELIST句柄,取得其它进程中的TImageList的图标列表(相应的HICON)? ( 积分: 200 )

  • 主题发起人 主题发起人 YuZi
  • 开始时间 开始时间
Y

YuZi

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,包括C做出来的程序,注意是其它进程中的窗口中的ImageList.<br>我知道一个ImageList句柄,但用ImageList_GetIcon()无法取得其相应的HICON,用ImageList_GetImageCount()也始终返回0,但我另一个程序中的TImageList却是确实有图标的,句柄也确是有效的。<br>哪个大侠出手帮我一把呀?
 
如题,包括C做出来的程序,注意是其它进程中的窗口中的ImageList.<br>我知道一个ImageList句柄,但用ImageList_GetIcon()无法取得其相应的HICON,用ImageList_GetImageCount()也始终返回0,但我另一个程序中的TImageList却是确实有图标的,句柄也确是有效的。<br>哪个大侠出手帮我一把呀?
 
如果是另外的进程,建议做一个dll注入进程,在dll中调用ImageList_GetIcon。<br>注入进程的方法很多,建议采用hook注入。
 
在9X下这种方法可能实现起来更为困难(我所需的就是在9X下取图标列表),而且我不想用DLL。。。<br>看了一些C类的线程注入的方法,感觉CreateRemoteThread 和 WriteProcessmemory的方法可以实现,但有点晕。。。。<br>我是想能不能根据HIMAGELIST句柄,按照IMageList存储结构,用ReadProcessMemory直接把那个进程内存中的图标读出来,但又无从知道ImageList的存储结构。。。。
 
高手在哪里呀?
 
高手在家数钞票
 
9X下CreateRemoteThread没有实现,只能通过钩子(Hook)注入DLL。
 
你们都确信ImageList_GetIcon等函数一定要在那个程序的进程空间内执行才有效吗?
 
这个操作我想你是必须把你的代码植入到目标线程。RemoteThread/HOOK都是手段。
 
to zjan521:<br>我不能用Dll,您能给段将代码植入其它进程,并执行得到所需值的演示代码,代码注入的例子我没见过,9X下怎么做呢?还有在其它进程中申请所需空间大小怎么算?执行了注入的代码后,返回值和善后问题是不是很麻烦呢?
 
Win98下主要问题是没有VirtualAllocEx,因此比较麻烦.不过解决方法很多.比如利用WriteProcessMemory改写对方窗体的消息处理函数,利用DebugAPI暂停/修改代码/执行/复原代码.等等.不过我并没有实践过代码.如果你不使用DLL,本身就是会很麻烦,权利与责任并存
 
只有利用DLL注入其他进程,你才可以得到它们的ImageList中的图标(当然你用资源提取工具例外了),但在运行期除此外应该没有别的办法了。至于你说不愿意使用DLL那就没有办法了^_^,而且98系统只有使用HOOK方法,道理嘛,可以看看《Window核心编程》,里面讲的很清楚!
 
我想,HIMAGELIST句柄应该是一个进程相关的结构地址吧,如你所言,如果知道其数据结构,用<br>ReadProcessMemory应该可以读出来的吧,可惜ImageList控件不是窗口, 否则可以在其进程<br>分配一块空间,然后发个消息就好了,比如这个读取TreeView控件的小函数:<br><br> &nbsp;// 扩展的TreeView_GetItem (取得TreeView指定子项目)<br>function TreeView_GetItem_Ex(hwndTV: HWND; var TVItem: TTVItem): Bool;<br>var<br> &nbsp;ProcessID, ProcessHD, Temp: DWORD;<br> &nbsp;pszText, MemPoint: Pointer;<br>begin<br> &nbsp;Result := FALSE;<br><br> &nbsp;GetWindowThreadProcessId(hwndTV, ProcessID);<br><br> &nbsp;ProcessHD := OpenProcess(<br> &nbsp; &nbsp;PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, FALSE, ProcessID);<br> &nbsp;if (ProcessHD = 0) then Exit;<br><br> &nbsp;MemPoint := VirtualAllocEx(ProcessHD, nil,<br> &nbsp; &nbsp;SizeOf(TTVItem) + TVItem.cchTextMax + 1,<br> &nbsp; &nbsp;MEM_COMMIT, PAGE_READWRITE);<br> &nbsp;if (MemPoint = nil) then Exit;<br><br> &nbsp;pszText := TVItem.pszText; // 保存本进程地址<br> &nbsp;PChar(pszText)^ := #0;<br> &nbsp;TVItem.pszText := PChar(Integer(MemPoint) + SizeOf(TTVItem));<br> &nbsp;if (WriteProcessMemory(ProcessHD, MemPoint, @TVItem, SizeOf(TVItem), Temp) = FALSE) then Exit;<br> &nbsp;if (WriteProcessMemory(ProcessHD, TVItem.pszText, pszText, 1, Temp) = FALSE) then Exit;<br><br> &nbsp;Result := (SendMessage(hwndTV, TVM_GETITEM, 0, LongInt(MemPoint)) &lt;&gt; 0);<br><br> &nbsp;if (ReadProcessMemory(ProcessHD, TVItem.pszText, pszText, TVItem.cchTextMax + 1, Temp) = FALSE) then<br> &nbsp;begin<br> &nbsp; &nbsp;Result := FALSE;<br> &nbsp; &nbsp;Exit;<br> &nbsp;end;<br> &nbsp;TVItem.pszText := pszText; // 恢复本进程地址<br><br> &nbsp;VirtualFreeEx(ProcessHD, MemPoint, SizeOf(TTVItem) + TVItem.cchTextMax + 1, MEM_DECOMMIT);<br> &nbsp;VirtualFreeEx(ProcessHD, MemPoint, 0, MEM_RELEASE);<br>end;<br><br> &nbsp;// 取指定TreeView子项目文字<br>function TreeView_GetItem_Text(hwndTV: HWND; hitem: HTreeItem): string;<br>var<br> &nbsp;Buffer: array[0..50] of Char;<br> &nbsp;TVItem: TTVItem;<br>begin<br> &nbsp;TVItem.hItem := hitem;<br> &nbsp;TVItem.mask := TVIF_TEXT;<br> &nbsp;TVItem.pszText := @Buffer[0];<br> &nbsp;TVItem.cchTextMax := 50;<br><br> &nbsp;if TreeView_GetItem_Ex(hwndTV, TVItem) then<br> &nbsp; &nbsp;Result := Buffer<br> &nbsp;else<br> &nbsp; &nbsp;Result := '';<br>end;<br><br>但是这个函数有一个小问题,就是Window 9x不支持远程内存分配,解决方法呢,<br>可以用消息钩子,将我们的DLL注入目标进程, 随后DLL中的代码直接操作即可, <br>我想ImageList也可以用这样的方法搞定(DLL中直接调用ImageList_GetIcon)
 
谢谢几位大侠朋友,看来我的要求和我的问题本身都的确叫人郁闷,<br>还是结贴吧,贴子没了结就好像欠人东西一样,呵呵,<br>我以后还会继续思考这个问题的,遇到困难再开贴请教吧,<br>谢谢几位!
 
后退
顶部