【发布时间】:2013-05-28 15:48:20
【问题描述】:
这行代码一直让我莫名其妙!
string s = Marshal.PtrToStringAnsi((IntPtr)((Int32)Buffer +
Marshal.SizeOf(typeof(Struct))));
这是函数的其余部分。
Api.LvItem lvItem = new Api.LvItem();
IntPtr lpLocalBuffer = Marshal.AllocHGlobal(1024);
uint pid;
uint thread = Api.GetWindowThreadProcessId(hWnd, out pid);
IntPtr hProcess = Api.OpenProcess(0x001f0fff, false, (int)pid);
IntPtr lpRemoteBuffer = Api.VirtualAllocEx(hProcess, IntPtr.Zero, 1024, 0x1000, 4);
lvItem.mask = 1;
lvItem.iItem = index;
lvItem.iSubItem = subitem;
lvItem.pszText = (IntPtr)((int)lpRemoteBuffer + Marshal.SizeOf(typeof(Api.LvItem)));
lvItem.cchTextMax = 50;
Api.WriteProcessMemory(hProcess, lpRemoteBuffer, ref lvItem, Marshal.SizeOf(typeof(Api.LvItem)), 0);
Api.SendMessage(hWnd, 0x1005, IntPtr.Zero, lpRemoteBuffer);
Api.ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, 1024, 0);
string ret = Marshal.PtrToStringAnsi((IntPtr)((int)lpLocalBuffer + Marshal.SizeOf(typeof(Api.LvItem))));
Marshal.FreeHGlobal((IntPtr)lpLocalBuffer);
Api.VirtualFreeEx(hProcess, lpRemoteBuffer, 0, 0x8000);
Api.CloseHandle(hProcess);
return ret;
此代码用于获取另一个进程的列表视图中每个项目的文本。我从这里跟踪代码(半):http://taylorza.blogspot.com/2009/08/archive-hacking-my-way-across-process.html
我很抱歉使用 0x1005。这是LV_GETITEM 消息的代码。
我已将其范围缩小到与平台相关。它适用于 x64 和 AnyCPU,但不适用于 x86。我将如何改变内存分配的大小差异等
在控制台应用程序中使用时,它会正确返回值。但是,当我在通过反射调用的 .DLL 中使用此代码(及其其余部分)时,该代码返回一个不正确的字符串。它看起来是空的,但实际上并不为空。也许只是空白......
有没有人对这种麻烦的编组有类似的经历?这让我困惑了整整三个小时......
非常感谢任何帮助或任何想法或任何东西!
【问题讨论】:
-
可能是 64 位指针截断,但这很可能会导致访问冲突。因此,结构末尾之外的内容可能确实是空的。为什么不给我们一个说明故障的完整程序。否则我们必须猜测。你有一个完整的程序。我们不这样做是不公平的
-
嗨,David,我已将其范围缩小到与平台相关。它适用于 x64 和 AnyCPU,但不适用于 x86。我想我现在可以从这里开始,但任何建议都是有帮助的。我正在运行 x64 位版本的 Windows。
-
另外,我将如何改变内存分配等的大小差异。
-
我不知道。您没有显示足够的代码。如果你坚持自己保密,我帮不了你。
-
这里是函数,太长了,无法评论。 pastebin.com/raw.php?i=793X6PS5
标签: c# pinvoke 32bit-64bit