From: Willy Denoyette [MVP] on 5 Nov 2006 05:31 "SQACSharp" <lsdisciples(a)hotmail.com> wrote in message news:1162691474.481310.78130(a)h54g2000cwb.googlegroups.com... | Your help is really appreciated Willy since i'm trying to do this since | almost a week :( | | Ok i try to understand how to use the openProcess, VirtualAllocEx, | ReadProcessMemory and VirtualFreeEx to solve my problem but i'm not | sure exactly how i'm suppose to use the ReadProcessMemory to retreive | the controlname returned by my sendmessage API call..This is what it | look like after spending 3-4 more hours on that : | | System.Diagnostics.Process.Start("\"C:\\MyApplication.exe\"", ""); | int hwnd = 0; | IntPtr hwndChild = IntPtr.Zero; | hwnd = FindWindow(null, "Login"); | hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "TEdit", ""); | SetControlText((int)hwndChild, WM_SETTEXT, 0, "MyPassword!"); | | // The following is my nightmare to get the controlname....still not | working :( | System.Diagnostics.Process[] processes; | processes = System.Diagnostics.Process.GetProcesses(); | uint ProcessId; | IntPtr hProcess = IntPtr.Zero; | const uint PROCESS_ALL_ACCESS = (uint)(0x000F0000L | 0x00100000L | | 0xFFF); | foreach (System.Diagnostics.Process instance in processes) | { | if (instance.ProcessName == "MyApplication") | { | ProcessId = (uint)instance.Id; | hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, | (uint)instance.Id); | } | } | if (hProcess == IntPtr.Zero) | throw new ApplicationException("Failed to access process"); | const int dwBufferSize = 1024; | const uint MEM_COMMIT = 0x1000; | const uint MEM_RELEASE = 0x8000; | const uint PAGE_READWRITE = 0x04; | IntPtr lpRemoteBuffer = IntPtr.Zero; | IntPtr lpLocalBuffer = IntPtr.Zero; | IntPtr threadId = IntPtr.Zero; | lpLocalBuffer = Marshal.AllocHGlobal(dwBufferSize); | lpRemoteBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, dwBufferSize, | MEM_COMMIT, PAGE_READWRITE); | if (lpRemoteBuffer == IntPtr.Zero) | throw new SystemException("Failed to allocate memory in remote | process"); | Int32 SendMsg; | SendMsg = RegisterWindowMessage("WM_GETCONTROLNAME"); | long ReturnMsg; | IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr))); | Marshal.WriteIntPtr(ptr, IntPtr.Zero); | MessageBox.Show(SendMsg.ToString()); | ReturnMsg = SendMessage((int)hwndChild, SendMsg, 65536, | lpRemoteBuffer); | bool bSuccess; | bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, | dwBufferSize,IntPtr.Zero); | if (!bSuccess) | throw new SystemException("Failed to read from process memory"); | string retval; | retval = Marshal.PtrToStringAnsi(lpRemoteBuffer); | MessageBox.Show(retval); //This is not working....how I'm suppose to | read the string value returned by my sendmessage??? | | -OpenProcess should not expect to have PROCESS_ALL_ACCESS access privs. (you shouldn't even expect to have any privilege at all), specify only the minimum required which is PROCESS_VM_OPERATION, PROCESS_VM_REA and PROCESS_VM_WRITE. const short PROCESS_VM_OPERATION = 0x8; const short PROCESS_VM_READ = 0x10; const short PROCESS_VM_WRITE = 0x20; - VirtualAllocEx must allocate the same buffer size as passed with SendMessage, that is - 65536, which is the minimum that should be allocated. - You don't need a native heap allocated local buffer (lpLocalBuffer ), point is that you allocate memory in the target process and read from there using ReadProcessMemory specifying a (local) byte[] as destination. ... uint bufferSize = 65536; byte[] bytearray = new byte[buffSize]; ... ReadProcessMemory(...., lpRemoteBuffer, bytearray, bufferSize,...); - The byte[] can be converted to a string using the appropriate GetString method of the Encoding class. Note that using VirtualAllocEx requires a Unicode based Windows OS (NT4 and higher), so you can use something like: string s = Encoding.Default.GetString(bytearray).TrimEnd('0'); to convert the byte[] to string. As a genera remark, you should take care passing machine independent IntPtr arguments in SendMessage. That means tha you should declare the size argument as an IntPtr and pass it "new IntPtr(65536)" as value. The same is valid for the handle argument. So your declarartion should look something like: ... SendMessage(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); or better use a SafeHandle for your handle parameters... Same remark for your other API declarations. And finally, don't forget to call VirtualFreeEx and to check the return values !!!! Willy.
From: SQACSharp on 5 Nov 2006 13:05 OK, I modify the code according to all your comments. Now I have a compiling error that prevent me to try the code with the modification : Error 1 - The best overloaded method match for 'TestWinAPI.MainForm.ReadProcessMemory(System.IntPtr, System.IntPtr, System.IntPtr, int, System.IntPtr)' has some invalid Error 2 - Argument '3': cannot convert from 'byte[]' to 'System.IntPtr' Here is line of the error :: bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, ***ERROR*** bytearray, (int)bufferSize, NumRead); Here is the code that use the bytearray : //-------------------------- const int dwBufferSize = 65536; uint bufferSize = 65536; byte[] bytearray = new byte[bufferSize]; //....blablabla IntPtr lpRemoteBuffer = IntPtr.Zero; lpRemoteBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, dwBufferSize, MEM_COMMIT, PAGE_READWRITE); //....blablabla ReturnMsg = SendMessage((IntPtr)hwndChild, SendMsg, SizePtr, NumRead); bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, bytearray, (int)bufferSize, NumRead); //-------------------------- Any idea about how to convert from 'byte[]' to 'System.IntPtr ???? Thanks again for your time Michel
From: Willy Denoyette [MVP] on 5 Nov 2006 13:42 See inline... Willy. "SQACSharp" <lsdisciples(a)hotmail.com> wrote in message news:1162749951.848994.55550(a)b28g2000cwb.googlegroups.com... | OK, I modify the code according to all your comments. | | Now I have a compiling error that prevent me to try the code with the | modification : | | Error 1 - The best overloaded method match for | 'TestWinAPI.MainForm.ReadProcessMemory(System.IntPtr, System.IntPtr, | System.IntPtr, int, System.IntPtr)' has some invalid | | Error 2 - Argument '3': cannot convert from 'byte[]' to 'System.IntPtr' | | You need to declare the argument as a byte[] not an IntPtr, something like this: static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte [] lpBuffer, UIntPtr nSize, IntPtr lpNumberOfBytesRead); | Here is line of the error :: | | bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, ***ERROR*** | bytearray, (int)bufferSize, NumRead); | | Here is the code that use the bytearray : | //-------------------------- | const int dwBufferSize = 65536; | uint bufferSize = 65536; | byte[] bytearray = new byte[bufferSize]; | No need to define the size a second time. const int dwBufferSize = 65536; byte[] bytearray = new byte[dwBufferSize ]; | //....blablabla | | IntPtr lpRemoteBuffer = IntPtr.Zero; | lpRemoteBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, dwBufferSize, | MEM_COMMIT, PAGE_READWRITE); | | //....blablabla | | ReturnMsg = SendMessage((IntPtr)hwndChild, SendMsg, SizePtr, NumRead); | | bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, bytearray, | (int)bufferSize, NumRead); | //-------------------------- | | | Any idea about how to convert from 'byte[]' to 'System.IntPtr ???? | | Thanks again for your time | | Michel |
From: SQACSharp on 5 Nov 2006 20:41 I change ReturnMsg to a IntPointer IntPtr ReturnMsg = IntPtr.Zero; Here is the missing declaration for SendMessage : [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr handle, uint msg, IntPtr wParam, IntPtr lParam); But it still return 0 for and 0 bytes read.... Michel
From: SQACSharp on 5 Nov 2006 21:06 the function RegisterWindowMessage("WM_GETCONTROLNAME"); return 49589..... If I call RegisterWindowMessage("WM_BLABLABLA"); it also return 49589 ?????? Is this return value is a kind of non found return value???? Are you sure I can use registerWindowMessage to get the int value of const "WM_GETCONTROLNAME" ??? System.UInt32 SendMsg; SendMsg = RegisterWindowMessage("WM_GETCONTROLNAME"); MessageBox.Show(SendMsg.ToString());
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: How to get any upload using WUA API ? Next: microsoft.common.target |