|
|
Comments and Discussions
|
|
 |

|
Thanks a million. This is exactly what I needed!
|
|
|
|

|
Hi,
i want to get the Rectangle of each Item. Or better the Icon.
How can i get the icon? I can't get it...
Please help
|
|
|
|

|
Thank you! I needed a way to get the titles of column headers from list-controls in another process, and this was just what I needed.
|
|
|
|

|
I understand why calling things like GetItemText() or GetColumnTitle() won’t work for list-controls in other processes because you need to pass a pointer to a buffer to store the text in. What confuses me is why calling GetWindowText() does work for windows in other processes even though it too requires passing a pointer to a buffer to store the string.
--
Synetech
|
|
|
|

|
Hello
First; thank you very much for your code
Secondly, I want to ask: Is it possible to delete an item using your method (WriteProcessMemory and SendMessage)?
Thank you very much
Sincerely Yours
|
|
|
|

|
By the way great post mate.
I am trying to code this method into C# version but I know only C#. it is somewhat confusing me to convert from C++ version of this code into C#. Please let me know if you have C# version of code.
|
|
|
|
|
|

|
hello,i have a problem about List Control,can you help me?i creat two pages in a Tab Control,one is come from a dialog named RECORD,the other is come from a dialog named INFORMATION.there is a List Control in the RECORD,when i change to the INFORMATION page,why I can get List Control's Item in the RECORD?all of the List Control's functons just like DeleteAllItems()、InsertItem() can't work,the program crashed when use them.is the IList Control need to actived? how to active it?can you help me to resolve this problem?thank you very much.
|
|
|
|

|
Just what I was looking for. Works on XP
|
|
|
|

|
Hi All,
I am trying to read text from ListView of other application.
I have created a demo application which is working fine for all listview (FolderView/ Winzip Listview control and listview of some application), but it is not working for a particular Listview.
I am able to get the Row Counts/ Column Counts but I am not able to read text.
Below is my code which I am executing to get ListItem.
Private Const LVM_FIRST = &H1000
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Private Const LVM_GETITEM = (LVM_FIRST + 5)
Private Const LVM_GETSTRINGWIDTH = (LVM_FIRST + 17)
Private Const LVM_GETCOLUMN = (LVM_FIRST + 25)
Private Const LVM_GETITEMTEXT = (LVM_FIRST + 45)
‘LVMGETITEMTEXT
strLength = SendMessage(hWindow, LVM_GETITEMTEXT_ANSI, iItem, ByVal pMyItemMemory)
Above code is working fine for other listview, and strLength is returning currect length of text of the List item on 32 bit systems Win2K, XP. But it is not working properly on 64 Bit systems like Vista, Win2003 Server. I am getting Item count and column count using "LVM_GETITEMCOUNT"
I guess memory address for VISTA/Win2003 application is different.
Any suggestion please.
Regards
RushiJoshi
|
|
|
|

|
Hello all,
I tried this code for Windows Task Manager, it worked fine.
But when i tried it o listview of a third party application
it simply returns blanks.
i'm a novice to win api message handling,
however i tried to figure out that list veiw carries window style LVS_OWNERDRAWFIXED.
i'm not sure whether that is the problem or something else.
it returns the proper RecordCount but does not returns the data.
PLZ HELP !!!!
Thanks in Advance.
|
|
|
|

|
You seem to discover the wheel...
ReadProcessMemory() and so is used since... 1995 !
Just Laughable.
Search on Google Groups before posting noob code...
|
|
|
|

|
How to steal TStringGrid's Memory? Any idea?
|
|
|
|

|
Perfect solution. Good article. Short but to the point.
|
|
|
|

|
I Tried that with vista 64 (32 bit Compiler) but SendMessage(LVM_GETITEMTEXT...) returns empty item label strings. Does anyone havve a solution for that?
|
|
|
|

|
I don't know about all compilers (I don't know if this code would work differently on another compiler) but on Microsoft Visual VirtualAllocEx initializes the entire commited range with 0s.
-Cedar
|
|
|
|

|
Is it possible to get selected text? E.g. if user select some text from Word, Notepad, ... is it possible to retrieve that text? Loop trough top windows and see if there is some text that is selected and copy it for further analysis?
What message to send?
Thanks for help!
|
|
|
|

|
I have done . i was happy . my send message(a,b,n,&lvitem) was doing very fine but later when i uploaded this to final destination a i tried i got this error
Failled to alocate memmory in remote process
i am shoure i have alocated vmamory in and programe has accress to this new memory but i am still having this
Failled to alocate memmory in remote process
bug
may any body help me in this
Thank You
_______________
|
|
|
|

|
if user selfmade listview ,how can you get text and send message
|
|
|
|

|
FWIW, here is a clever utility that copies the text of another process's controls to the clipboard. The controls that are supported are Edit (including obscured password edits), Static, Headers, Listview, ComboBox and ListBox. Source code (GPL'd) is included:
"Control Content Saver" by Jacquelin Potier at http://jacquelin.potier.free.fr/controlcontentsaver/[^]
Jeffrey Richter, in his Win32 Q&A column from September 1997, explains the apparent contradiction of why, with some messages (like WM_GETTTEXT and LB_GETTEXT and EM_GETLINE), it's possible to copy data from another process even though you're using a pointer to memory in the local process, whereas for other messages (like LVM_GETITEMTEXT) it's not. See http://www.microsoft.com/msj/0997/win320997.aspx[^]. His solution for list view controls is similar to that proposed in this article.
Mike
|
|
|
|

|
Hi. I'm trying to convert to C# but I got a null buffer (all items are \0).
Please, can someone help me?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
IntPtr mainWindowHwnd;
IntPtr lvwHwnd = (IntPtr)0;
try
{
mainWindowHwnd = FindWindow(null, "Stealing Program's memory: ListView");
lvwHwnd = FindWindowEx(mainWindowHwnd, IntPtr.Zero, "SysListView32", IntPtr.Zero);
if (lvwHwnd == (IntPtr)0)
throw new Win32Exception();
}
catch(Exception ex)
{
MessageBox.Show("[" + Marshal.GetLastWin32Error().ToString() + "] - Não foi possível obter o handle do controle filho.\n\n" + ex.ToString(), "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
int lvwItem = 0;
IntPtr pid = (IntPtr)0;
GetWindowThreadProcessId(lvwHwnd, ref pid);
IntPtr _lvi;
IntPtr _subitem = IntPtr.Zero;
IntPtr process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, false, pid.ToInt32());
LVITEM lvi = new LVITEM();
//process = (IntPtr)(process.ToInt32() - 1);
_lvi = VirtualAllocEx(process, IntPtr.Zero, Marshal.SizeOf(typeof(LVITEM)), MEM_COMMIT, PAGE_READWRITE);
_subitem = VirtualAllocEx(process, IntPtr.Zero, 512, MEM_COMMIT, PAGE_READWRITE);
if(_lvi == IntPtr.Zero)
throw new SystemException("Failed to allocate memory in remote process");
bool bsuccess;
lvi.cchTextMax = 512;
lvi.iSubItem = 1;
lvi.pszText = _subitem;
bsuccess = WriteProcessMemory(process, _lvi, ref lvi, Marshal.SizeOf(typeof(LVITEM)), IntPtr.Zero);
SendMessage(lvwHwnd, LVM_GETITEMTEXT, lvwItem, _lvi);
IntPtr lpBuffer;
lpBuffer = Marshal.AllocHGlobal(512);
string sRet;
IntPtr bytesReaded;
byte[] buffer = new byte[512];
ReadProcessMemory(process, _subitem, buffer, 512, out bytesReaded);
//sRet = Marshal.PtrToStringAnsi(lpBuffer, 512);
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);
}
[DllImport("user32.dll",
CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parent /*HWND*/,
IntPtr next /*HWND*/,
string sClassName,
IntPtr sWindowTitle);
//'''''''''''''''''''''''''''''''''''''''''''''''
//' Used by the OpenProcess API call
private const long STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const long SYNCHRONIZE = 0x100000;
private const int PROCESS_TERMINATE = 0x1;
private const int PROCESS_CREATE_THREAD = 0x2;
private const int PROCESS_SET_SESSIONID = 0x4;
private const int PROCESS_VM_OPERATION = 0x8;
private const int PROCESS_VM_READ = 0x10;
private const int PROCESS_VM_WRITE = 0x20;
private const long PROCESS_DUP_HANDLE = 0x40;
private const long PROCESS_CREATE_PROCESS = 0x80;
private const long PROCESS_SET_QUOTA = 0x100;
private const long PROCESS_SET_INFORMATION = 0x200;
private const int PROCESS_QUERY_INFORMATION = 0x400;
private const long PROCESS_SUSPEND_RESUME = 0x800;
private const long PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF;
[DllImport("kernel32")]
public static extern IntPtr OpenProcess(int dwDesiredAccess,
bool bInheritHandle,
int dwProcessID);
//'''''''''''''''''''''''''''''''''''''''''''''''
const uint MEM_COMMIT = 0x1000;
const uint MEM_RELEASE = 0x8000;
const uint PAGE_READWRITE = 0x4;
[DllImport("kernel32")]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
int dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
ref LVITEM buffer, int dwSize, IntPtr lpNumberOfBytesWritten);
//Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal msg As Int32, ByVal wParam As IntPtr, ByRef lParam As IntPtr) As Boolean
[DllImport("user32.dll")]
static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
private const int LVM_FIRST = 0x1000;
private const long LVM_GETSELECTEDCOUNT = (LVM_FIRST + 50);
private const long LVM_GETITEMSTATE = (LVM_FIRST + 44);
public const int LVM_GETITEMTEXT = (LVM_FIRST + 45);
public const long LVM_GETITEMCOUNT = LVM_FIRST + 4;
private const long LVIF_TEXT = 0x1;
//'Public Const LVM_GETITEMA = (LVM_FIRST + 5)
//'Public Const LVM_GETITEMW = (LVM_FIRST + 75)
public const long LVM_GETITEM = (LVM_FIRST + 5);
[StructLayout(LayoutKind.Sequential)]
private struct LVITEM
{
public Int16 mask;
public Int16 iItem;
public Int16 iSubItem;
public Int16 state;
public Int16 stateMask;
public IntPtr pszText;
public Int16 cchTextMax;
public Int16 iImage;
}
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
//[In, Out] byte[] buffer,
IntPtr buffer,
UInt32 size,
out IntPtr lpNumberOfBytesRead
);
[DllImport("kernel32.dll")]
public static extern Int32 ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[In, Out] byte[] buffer,
UInt32 size,
out IntPtr lpNumberOfBytesRead
);
[DllImport("kernel32")]
static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize,
uint dwFreeType);
[DllImport("user32")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd,
ref IntPtr lpdwProcessId);
}
}
|
|
|
|

|
This save my time of searching solution. Before found this article I nearly go to the hooking that I'm not fully understand. This article explain clearly and easy to follow.
|
|
|
|

|
I use the code and change it a bit.
The code below retrieves text on statusbar "msctls_statusbar32".
I use SB_GETTEXT to send message and retrieves text.
But on statusbar "StatusBar20WndClass", i am getting null string.
I need help on this. Thank you for your suggestions.
Status Bar in a Dialog - Nish for CP - http://www.codeproject.com/statusbar/dlgstatbar01.asp[]
Code:
//HWND hwnd=FindWindow(NULL, "Status Bar in a Dialog - Nish for CP");
//HWND hStatusBar=FindWindowEx(hwnd, NULL, "msctls_statusbar32", NULL);
HWND hwnd=FindWindow(NULL, "TEST");
HWND hStatusBar=FindWindowEx(hwnd, NULL, "StatusBar20WndClass", NULL);
unsigned long pid;
HANDLE process;
char *_item;
char item[512];
GetWindowThreadProcessId(hStatusBar, &pid);
process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, FALSE, pid);
_item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
SendMessage(hStatusBar, SB_GETTEXT, (WPARAM)0, (LPARAM)_item);
ReadProcessMemory(process, _item, &item, 512, NULL);
printf("%s",item);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
return 0;
|
|
|
|

|
Great job with the code, I’ve got some information from Outlook’s Express List View thanks to it. Now I would like to do the same thing but with Microsoft Outlook’s SUPERGRID. I’ve done the same thing as before – Localized SUPERGRID with FindWindowEx(…) and then , because SUPERGRID (from what I know)is derived from CListCtrl which encapsulates the functionality of a "list view” control, I tried to send some LVM_.... messages with SendMessage(…) to get any kind of information. Of course it didn’t work …. any ideas?
|
|
|
|

|
Using similar code I can get a handle to the component but of course the messages do not work. I want to fetch the data from a TStringGrid belonging to a different application. Any ideas?
|
|
|
|

|
can we write some text to list view?
|
|
|
|

|
i think
CloseHandle(process);
is missing there somewhere
|
|
|
|

|
Hi, Very nice code - worked inside 5 minutes on ALL of my apps with any listviews in.
However the actual app I am interested in reading the list view from (a third party windows app with three listviews in) cannot access the list. The valid hadle (from Spy++) for the listview32 comes back with nothing at all count=0 even though I know the listview in question has items in!
Is there any way this code won't work on any windows app if it was written and obfruscated/secured?
Any help appreciated
Clive
|
|
|
|

|
Is there a way to select an item of a list or set text of a list? Basically the reverse of what was shown here?
|
|
|
|
|

|
Hi,
I'm working on a kind of macro-tool, and want to retrieve the Name of the selected object. But what's even more important: I want to be able to find the control back by this Name!
Is this possible in the way you do this to listviews?
|
|
|
|

|
I have been trying to access the text from a listview today and worked out this little work around.
//-----------------------------
//----------------------------
int index;
HWND ListViewhwnd,LVEditWnd;
TCHAR buf[512];
1.index = ListView_GetHotItem(ListViewhwnd) //returns index of currently selected iteam -1 if none selcted
2.LVEditWnd = ListView_EditLabel(listviewhwnd,index);//place selected item in edit mode which creates an edit control with the label
3.SendMessage(LVEditWnd,WM_GETTEXT,sizeof(buf)/sizeof(TCHAR),(LPARAM)(void*)buf);//get Edit controls text
4. ListView_EditLabel(listviewhwnd,-1);//sending -1 cancels edit mode
//-------------------------------
buf = text of selected item
this gets the text of the currently selected item "what i wanted and you if i read your article correctly" . You could call ListView_GetItemCount() and then loop through the indexs capturing the text in the same way without GetHotItem.
Any one any other ideas ?
|
|
|
|

|
Here's my Adaptation... it gets all of the columns in the ListView.
I'm primarily a VB programmer so please excuse any blatent errors. :]
I pass the function the handle to the ListView and it returns the data in a member variable (m_strTEXT).
Do you know how to do this with the TreeView?
I'm working on it but haven't gotten very far.
James
-------
void CTestDlg::GETLVTEXT(const HWND hWnd) {
int count=(int)::SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0);
int i, col=0;
LVITEM lvi, *_lvi;
TCHAR item[512], subitem[512], strTmp[1050];
TCHAR* _item, *_subitem;
unsigned long pid;
HANDLE process;
m_strTEXT.Empty();
GetWindowThreadProcessId(hWnd, &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=(TCHAR*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
_subitem=(TCHAR*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
lvi.cchTextMax=512;
for(i=0; i<count; i++) {
col=0;
lvi.iSubItem=col;
lvi.pszText=_item;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage(hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
ReadProcessMemory(process, _item, item, 512, NULL);
m_strTEXT += item;
do
{
col++;
lvi.iSubItem=col;
lvi.pszText=_subitem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage(hWnd, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
ReadProcessMemory(process, _subitem, subitem, 512, NULL);
if(_tcscmp(item,subitem) != 0) {
m_strTEXT += _T(",");
m_strTEXT += subitem;
} else {
col = 0;
}
} while(col != 0);
m_strTEXT += strTmp;
m_strTEXT += _T("\x0d\x0a");
}
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);
}
|
|
|
|

|
Thankyou very much,
Exactly what I needed and well described. Took me about 5 minutes to adapt to my needs
|
|
|
|

|
Just what I needed, thanks for the info.
- Fred
|
|
|
|

|
hy all
is is it possible to overwrite the memory of another process?
so allocate an existing part of memory, and then read/write to it.
don't realy know why to do it, but i just wondered if the memory of another process could be overwritten, and what would happen..
will the process just crash, or keep working?
|
|
|
|

|
This is a nice hack to get the data. I was just wondering if there happened to be 2 list controls in the window, how would we distinguish between them?
|
|
|
|

|
hi its a good thing.
i managed the same thing with hooks. and they gave me heck of a time, where were you 4 months back????
nice work!
|
|
|
|

|
Virtual memory is how Windows' deals out memory to all it's programs. It makes programs think they have 4GiB of memory to use.
Actually, the largest address space an application has is 2GB, or 3GB if running on Windows 2000 Advanced Server or Windows 2000 Datacenter Server and the /3GB switch was used.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|

|
It is difficult reading your article and having to keep moving the scrollbar back and forth.
You also stated this is for VC++ 6.
William
Fortes in fide et opere!
|
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
An advanced article on allocating and using memory in another process using the Win32 API.
| Type | Article |
| Licence | |
| First Posted | 2 Dec 2003 |
| Views | 211,503 |
| Bookmarked | 99 times |
|
|