質問編集履歴
1
構造体を32bit用に変更、読み書きできるメモリの確保コードの追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -124,17 +124,130 @@
|
|
124
124
|
public int iGroup;
|
125
125
|
}
|
126
126
|
|
127
|
+
```
|
127
128
|
|
128
|
-
|
129
|
+
###9/16修正後
|
130
|
+
ソフトが落ちることはなくなりましたが、textの中身は””状態で取得することができませんでした。。
|
131
|
+
構造体はすべてintに変更しています
|
132
|
+
〇主コード抜粋
|
133
|
+
```
|
134
|
+
//listViewのプロセスIDを取得する
|
129
135
|
|
136
|
+
int dwProcessId;
|
130
137
|
|
138
|
+
GetWindowThreadProcessId(hWnd, out dwProcessId);
|
131
139
|
|
140
|
+
// 取得したプロセスIDをオープンする
|
132
141
|
|
142
|
+
IntPtr hProcess;
|
133
143
|
|
144
|
+
hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, (uint)dwProcessId);
|
134
145
|
|
146
|
+
//必要なリストビューアイテムのテキストを格納するために、文字列にバッファを割り当て
|
147
|
+
|
148
|
+
var textBufferPtr = VirtualAllocEx(hProcess, IntPtr.Zero,MAX_LVMSTRING,AllocationType.Commit, MemoryProtection.ReadWrite);
|
149
|
+
|
150
|
+
|
151
|
+
//listViewの行数
|
152
|
+
|
153
|
+
int itemId = 2;
|
154
|
+
|
155
|
+
//listViewの列数
|
156
|
+
|
157
|
+
int subItemId = 2;
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
//構造体のnew
|
162
|
+
|
163
|
+
tagLVITEMA lvItem = new tagLVITEMA();
|
164
|
+
|
165
|
+
lvItem.mask = LVIF_TEXT;
|
166
|
+
|
167
|
+
lvItem.cchTextMax = (int)MAX_LVMSTRING;
|
168
|
+
|
169
|
+
lvItem.iItem = itemId;
|
170
|
+
|
171
|
+
lvItem.iSubItem = subItemId;
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
//リモートプロセスでLVITEM構造にメモリを割り当て
|
176
|
+
|
177
|
+
int lvItemSize = Marshal.SizeOf(lvItem);
|
178
|
+
|
179
|
+
var lvItemBufferPtr = VirtualAllocEx(hProcess, IntPtr.Zero,(uint)lvItemSize,AllocationType.Commit,MemoryProtection.ReadWrite);
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
// LVITEM構造体を挿入するには、ポインターからポインターへのコピーを実行するWriteProcessMemoryAPIを使用する必要があります。したがって、マネージLVITEM構造をアンマネージLVITEMポインターに変換する必要があります
|
184
|
+
|
185
|
+
//最初にアンマネージメモリの一部を割り当てます。
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
var lvItemLocalPtr = Marshal.AllocHGlobal(lvItemSize);
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
//管理対象オブジェクトを管理対象外メモリにコピーします
|
194
|
+
|
195
|
+
Marshal.StructureToPtr(lvItem, lvItemLocalPtr, false);
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
int NumberOfBytesRead = 0;
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
//リモートプロセスのメモリに書き込みます
|
204
|
+
|
205
|
+
WriteProcessMemory(hProcess, lvItemBufferPtr,lvItemLocalPtr,(uint)lvItemSize,out NumberOfBytesRead) ;
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
//リストビューに、必要なテキストを入力するように指示します
|
210
|
+
|
211
|
+
SendMessage(hWnd, LVM_GETITEMTEXT, itemId, lvItemBufferPtr);
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
//テキストを読む。 CLRはポインタとバイト配列の間でマーシャリングする方法を知っているため、
|
216
|
+
|
217
|
+
//AllocHGlobalの代わりに、取得したテキストを格納するためにマネージバイト配列を割り当てます。
|
218
|
+
|
219
|
+
var localTextBuffer = new byte[MAX_GETITEMTEXT_LENGTH];
|
220
|
+
|
221
|
+
IntPtr ptrNumberOfBytesRead = IntPtr.Zero;
|
222
|
+
|
223
|
+
ReadProcessMemory(hProcess,textBufferPtr,localTextBuffer,(int)MAX_LVMSTRING, out ptrNumberOfBytesRead);
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
//バイト配列を文字列に変換します。リモートプロセスがUnicodeを使用すると仮定します
|
228
|
+
|
229
|
+
var text = Encoding.Unicode.GetString(localTextBuffer);
|
230
|
+
|
231
|
+
//末尾のゼロは自動的にクリアされません
|
232
|
+
|
233
|
+
text = text.Substring(0, text.IndexOf('\0'));
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
//最後に、割り当てたすべてのメモリを解放し、開いたプロセスハンドルを閉じます
|
238
|
+
|
239
|
+
VirtualFreeEx(hProcess, textBufferPtr, 0, AllocationType.Release);
|
240
|
+
|
241
|
+
VirtualFreeEx(hProcess, lvItemBufferPtr, 0, AllocationType.Release);
|
242
|
+
|
243
|
+
Marshal.FreeHGlobal(lvItemLocalPtr);
|
244
|
+
|
245
|
+
|
135
246
|
```
|
136
247
|
|
137
248
|
|
249
|
+
|
250
|
+
|
138
251
|
### 試したこと
|
139
252
|
|
140
253
|
SendMessageの第4引数をIntPtr型や構造体そのものを入れてみたりしましたが、どれも同じく相手側が落ちてしまうという結果になりました。
|