5,317,180 members and growing! (21,447 online)
Email Password   helpLost your password?
General Programming » Threads, Processes & IPC » General     Advanced

Stealing Program's Memory

By Cory Nelson

An advanced article on allocating and using memory in another process using the Win32 API.
VC7.1, C++Windows, Win2K, WinXP, Win2003VS.NET2003, Visual Studio, Dev

Posted: 2 Dec 2003
Updated: 2 Dec 2003
Views: 105,881
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
48 votes for this Article.
Popularity: 6.84 Rating: 4.07 out of 5
2 votes, 4.2%
1
2 votes, 4.2%
2
4 votes, 8.3%
3
8 votes, 16.7%
4
32 votes, 66.7%
5

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:

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>

#include <windows.h>

#include <commctrl.h>


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

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

 char item[512], subitem[512];

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

 LVITEM lvi;
 lvi.cchTextMax=512;

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

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

  printf("%s - %s\n", item, subitem);
 }
 return 0;
}

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:

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():

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():

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:

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:

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:

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>

#include <windows.h>

#include <commctrl.h>


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

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

 LVITEM lvi, *_lvi;
 char item[512], subitem[512];
 char *_item, *_subitem;
 unsigned long pid;
 HANDLE process;

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

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

 lvi.cchTextMax=512;

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

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

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

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

 VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
 VirtualFreeEx(process, _item, 0, MEM_RELEASE);
 VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);

 return 0;
}

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.

This article was originally written for int64.org

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Cory Nelson



Occupation: Web Developer
Location: United States United States

Other popular Threads, Processes & IPC articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 43 (Total in Forum: 43) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralDoesn't work in Vista 64memberblurmotion3:18 17 May '08  
AnswerRe: Doesn't work in Vista 64memberblurmotion0:03 18 May '08  
GeneralVirtualAllocEx problemsmemberCedar825:45 17 Nov '07  
GeneralStatic Textmemberjosip cagalj2:14 23 Aug '07  
QuestionGetting list vew Data with sendmessage(xxxxx)memberXzion22:40 28 Mar '07  
Generalwhat if not window default controlmember9999kkk1:04 25 Nov '06  
GeneralA Clever Utility, and an Explanation of Cross-Process Copying of DatamemberMike O'Neill17:14 6 Sep '06  
GeneralC# VersionmemberMarco225016:57 28 Aug '06  
GeneralRe: C# VersionmemberKarlheinz Godo9:40 15 Feb '07  
GeneralCleaner C# Functionmemberdfhgesart17:10 7 Jul '07  
JokeThanks a lot! This is exactly what I'm looking for.membersongkiet9:58 9 Aug '06  
Questionretrieve text on statusbarmemberdoenoe23:22 31 Jul '06  
AnswerRe: retrieve text on statusbarmemberandy6665:19 11 Nov '06  
QuestionGet strings from Microsoft Outlook SUPERGRIDmemberkopyt3:13 19 Jul '06  
GeneralPossible to do same for delphi TStringGrid?memberAbsorbant Pad1:10 13 Jun '06  
Generalcan we write text?memberaldo hexosa3:47 4 Mar '06  
Generalleak?member[cs2]8:11 27 Jan '06  
GeneralProblem with one Appmemberclivet1:50 18 Sep '05  
GeneralRe: Problem with one Appmember___Charles___18:45 26 Jan '07  
GeneralSelect and SetTextmemberJ3ff11:30 28 Jul '05  
GeneralasussAnonymous10:57 9 Dec '04  
GeneralbsussAnonymous1:39 10 May '05  
GeneralcmemberZaibot4:52 17 Dec '06  
Generaldmembergames guru14:13 1 Aug '07  
GeneralControl Propterties?memberriezebosch5:39 19 Oct '04  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 2 Dec 2003
Editor: Nishant Sivakumar
Copyright 2003 by Cory Nelson
Everything else Copyright © CodeProject, 1999-2008
Web10 | Advertise on the Code Project