找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3622|回复: 2

吾偶得一好文,不忍独享Stealing Program's Memory

[复制链接]

307

主题

228

回帖

7343

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5593 个
贡献
253 次
宅之契约
0 份
在线时间
948 小时
注册时间
2014-1-25
发表于 2015-1-7 23:35:37 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 元始天尊 于 2015-1-8 00:09 编辑

今日偶得一文甚好,随分享出来,愿好事者翻译^_^
Stealing Program's Memory
http://www.codeproject.com/Artic ... ng-Program-s-Memory


An advanced article on allocating and using memory in another process using the Win32 API.

Introduction

I was recently trying to steal strings from another program's listview control. You need to pass a pointer so it knows where to put the string. Normally this wouldn't be a problem, but because Windows uses virtual memory pointers are not valid across programs.

Virtual memory is how Windows deals out memory to all it's programs. It makes programs think they have 2 Gb of memory to use. It also protects programs from using each other's memory so if one program crashes it doesn't take down the whole system with it.

So after coding a fair bit, I realized my pointers were all invalid and it wouldn't work. A few hours of digging through MSDN brought me to the functions VirtualAllocEx(), VirtualFreeEx(), WriteProcessMemory() and ReadProcessMemory(). Armed with this new information, I set out to modify my code. Here is what I had so far:

Collapse | Copy Code
  1. #define WIN32_LEAN_AND_MEAN
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <commctrl.h>

  5. int main(void) {
  6. /* Run through the windows until we find our listview. */
  7. HWND hwnd=FindWindow(NULL, "Stealing Program's Memory: ListView");
  8. HWND listview=FindWindowEx(hwnd, NULL, "SysListView32", NULL);

  9. int count=(int)SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);
  10. int i;

  11. char item[512], subitem[512];

  12. /* Shove all items of listview into item and subitem
  13.     and print out one by one. */

  14. LVITEM lvi;
  15. lvi.cchTextMax=512;

  16. for(i=0; i<count; i++) {
  17.   lvi.iSubItem=0;
  18.   lvi.pszText=item;
  19.   SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)&lvi);

  20.   lvi.iSubItem=1;
  21.   lvi.pszText=subitem;
  22.   SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)&lvi);

  23.   printf("%s - %s\n", item, subitem);
  24. }
  25. return 0;
  26. }
复制代码



As I said before, this won't work. The pointers to lvi, item, and subitem all get screwed when they go across process. The solution? Use WriteProcessMemory() and ReadProcessMemory() to use the other programs memory, perform LVM_GETITEMTEXT on it, and read it back. Hackish yes, but then again reading items from another program's listview control is one giant hack.

First, we get the process of the listview like this:

Collapse | Copy Code
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(listview, &pid);
process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|
                    PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);


Next We create three pointers, LVITEM *_lvi, char *_item, and char *_subitem and allocate them in the other program's virtual memory space with VirtualAllocEx():

Collapse | Copy Code
LVITEM *_lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM),
                                     MEM_COMMIT, PAGE_READWRITE);
char *_item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
                                  PAGE_READWRITE);
char *_subitem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
                                     PAGE_READWRITE);

Now we point lvi.pszText to _item, and copy it's memory to _lvi using WriteMemoryProcess():

Collapse | Copy Code
lvi.pszText=_item;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);

Now that we have an LVITEM pointer that is valid in the other programs virtual memory, we can shoot off LVM_GETITEMTEXT to listview and copy _item's text into item so we can read it in our program:

Collapse | Copy Code
SendMessage(hwnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
ReadProcessMemory(process, _item, item, max, NULL);

Repeat that for subitem, then free the memory we used in the other program's memory:

Collapse | Copy Code
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);

Yay, all done. In case that didn't make too much sense to you, here is our new code, all fixed up:

Collapse | Copy Code
  1. #define WIN32_LEAN_AND_MEAN
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <commctrl.h>

  5. int main(void) {
  6. HWND hwnd=FindWindow(NULL, "Stealing Program's Memory: ListView");
  7. HWND listview=FindWindowEx(hwnd, NULL, "SysListView32", NULL);

  8. int count=(int)SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);
  9. int i;

  10. LVITEM lvi, *_lvi;
  11. char item[512], subitem[512];
  12. char *_item, *_subitem;
  13. unsigned long pid;
  14. HANDLE process;

  15. GetWindowThreadProcessId(listview, &pid);
  16. process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|
  17.                      PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);

  18. _lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM),
  19.                               MEM_COMMIT, PAGE_READWRITE);
  20. _item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
  21.                              PAGE_READWRITE);
  22. _subitem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT,
  23.                                 PAGE_READWRITE);

  24. lvi.cchTextMax=512;

  25. for(i=0; i<count; i++) {
  26.   lvi.iSubItem=0;
  27.   lvi.pszText=_item;
  28.   WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
  29.   SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);

  30.   lvi.iSubItem=1;
  31.   lvi.pszText=_subitem;
  32.   WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
  33.   SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);

  34.   ReadProcessMemory(process, _item, item, 512, NULL);
  35.   ReadProcessMemory(process, _subitem, subitem, 512, NULL);

  36.   printf("%s - %s\n", item, subitem);
  37. }

  38. VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
  39. VirtualFreeEx(process, _item, 0, MEM_RELEASE);
  40. VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);

  41. return 0;
  42. }
复制代码


If you're looking to use a program's memory for another reason, or have had a similar problem to mine, adapting this should be fairly easy.
回复

使用道具 举报

3

主题

42

回帖

156

积分

用户组: 小·技术宅

UID
70
精华
0
威望
1 点
宅币
109 个
贡献
0 次
宅之契约
0 份
在线时间
6 小时
注册时间
2014-2-20
发表于 2015-1-9 22:42:29 | 显示全部楼层
好评ww!
回复

使用道具 举报

1

主题

60

回帖

201

积分

用户组: 中·技术宅

UID
4683
精华
0
威望
0 点
宅币
140 个
贡献
0 次
宅之契约
0 份
在线时间
31 小时
注册时间
2019-2-11
发表于 2019-5-10 21:01:30 | 显示全部楼层
点进来却看不懂,悻悻离开。
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-4-26 15:21 , Processed in 0.035942 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表