簡體   English   中英

C#-無法將IntPtr編組為正確的字符串

[英]C# - Cannot Marshal IntPtr To String Correctly

這行代碼讓我感到困惑!

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中使用此代碼(及其其余部分)時,該代碼返回的字符串不正確。 它顯示為空,但實際上不為空。 也許只是空白...

有沒有人遇到過類似的麻煩編組經驗? 現在已經困擾了我三個小時了...

任何幫助或任何想法或任何東西都將不勝感激!

看來您正在嘗試讀取另一個進程的內存。 您正在將LV_GETITEM消息發送到列表視圖控件。 這要求您在該其他進程的虛擬地址空間中分配內存。 您對VirtualAllocEx的調用做了什么。

到目前為止,一切都很好,但這是關鍵。 您需要分配的結構才能成為目標進程的正確布局。 現在,讓我們假設目標進程是一個64位進程。 在這種情況下,該結構包含64位指針。 當您的進程也是64位時,則您定義的結構將具有64位指針。 但是,當您的進程是32位時,該結構中的任何指針都將是32位。

因此,現在我們遇到一種情況,您的流程中的結構與目標流程中的結構具有不同的布局。 這種不匹配足以使所有這些努力失敗。 為了有機會進行這項工作,您需要聲明結構,以使其布局與64位布局匹配。 假設您只訪問少數幾個字段,那么分配一個適當大小的內存塊(也許是字節數組)並手動讀取/寫入字段可能會更簡單。 並避免結構編組。

即使那樣,我仍然懷疑32位進程是否能夠以這種方式戳入64位進程。 您可以從64位處理到32位處理的另一方向進行操作。 但是我已經嘗試過並且從未成功地朝着您嘗試的方向發展。

所有跡象表明,您應該堅持執行此任務的64位進程。 或者,找到一種官方支持的方式來做您正在做的事情。 例如,如果您只想閱讀資源管理器視圖的內容,則有一個Shell API。


另外,請停止使用魔術常數而不是消息標識符名稱。 沒有人喜歡嘗試理解0x1005含義。 聲明一個名為LV_GETITEM的常量。 您似乎也根本不執行任何錯誤檢查。 這也將使您的生活艱難。 如果其中一個API調用失敗,您將如何找到呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM