28 #define WM_PH_SELECT_OFFSET (WM_APP + 300)
30 typedef struct _MEMORY_EDITOR_CONTEXT
52 BOOLEAN LoadCompleted;
68 static RECT MinimumSize = { -1, -1, -1, -1 };
72 _In_ PVOID BaseAddress,
73 _In_ SIZE_T RegionSize,
74 _In_ ULONG SelectOffset,
75 _In_ ULONG SelectLength,
85 lookupContext.BaseAddress = BaseAddress;
86 lookupContext.RegionSize = RegionSize;
96 context->BaseAddress = BaseAddress;
97 context->RegionSize = RegionSize;
98 context->SelectOffset = SelectOffset;
100 context->Flags = Flags;
102 context->WindowHandle = CreateDialogParam(
110 if (!context->LoadCompleted)
112 DestroyWindow(context->WindowHandle);
116 if (SelectOffset != -1)
122 ShowWindow(context->WindowHandle, SW_SHOW);
128 if (IsIconic(context->WindowHandle))
129 ShowWindow(context->WindowHandle, SW_RESTORE);
131 SetForegroundWindow(context->WindowHandle);
133 if (SelectOffset != -1)
150 return memcmp(context1->Key, context2->Key,
sizeof(context1->Key));
162 if (uMsg != WM_INITDIALOG)
183 SetWindowText(hwndDlg, context->Title->Buffer);
193 context->BaseAddress, (ULONG_PTR)context->BaseAddress + context->RegionSize)->
Buffer);
200 if (context->RegionSize > 1024 * 1024 * 1024)
202 PhShowError(NULL, L
"Unable to edit the memory region because it is too large.");
207 &context->ProcessHandle,
213 &context->ProcessHandle,
218 PhShowStatus(NULL, L
"Unable to open the process", status, 0);
225 if (!context->Buffer)
227 PhShowError(NULL, L
"Unable to allocate memory for the buffer.");
232 context->ProcessHandle,
233 context->BaseAddress,
243 PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL,
256 if (MinimumSize.left == -1)
264 MapDialogRect(hwndDlg, &rect);
266 MinimumSize.left = 0;
269 context->HexEditHandle = GetDlgItem(hwndDlg,
IDC_MEMORY);
271 HexEdit_SetBuffer(context->HexEditHandle, context->Buffer, (ULONG)context->RegionSize);
280 MoveWindow(hwndDlg, windowRectangle.
Left, windowRectangle.
Top,
284 windowRectangle.
Left += 20;
285 windowRectangle.
Top += 20;
292 PWSTR bytesPerRowStrings[7];
296 for (i = 0; i <
sizeof(bytesPerRowStrings) /
sizeof(PWSTR); i++)
297 bytesPerRowStrings[i] =
PhaFormatString(L
"%u bytes per row", 1 << (2 + i))->Buffer;
300 bytesPerRowStrings,
sizeof(bytesPerRowStrings) /
sizeof(PWSTR));
304 if (bytesPerRow >= 4)
312 context->LoadCompleted =
TRUE;
317 if (context->LoadCompleted)
328 if (context->Buffer)
PhFreePage(context->Buffer);
329 if (context->ProcessHandle) NtClose(context->ProcessHandle);
340 SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle,
TRUE);
345 switch (LOWORD(wParam))
349 DestroyWindow(hwndDlg);
355 { L
"Binary files (*.bin)", L
"*.bin" },
356 { L
"All files (*.*)", L
"*.*" }
369 context->BaseAddress, context->RegionSize)->
Buffer);
400 PhShowStatus(hwndDlg, L
"Unable to create the file", status, 0);
420 L
"MemEditGotoChoices"
425 if (selectedChoice->
Length == 0)
430 if (offset >= context->RegionSize)
436 SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle,
TRUE);
448 context->ProcessHandle,
449 context->BaseAddress,
455 PhShowStatus(hwndDlg, L
"Unable to write memory", status, 0);
464 context->ProcessHandle,
465 context->BaseAddress,
471 PhShowStatus(hwndDlg, L
"Unable to read memory", status, 0);
474 InvalidateRect(context->HexEditHandle, NULL,
TRUE);
478 if (HIWORD(wParam) == CBN_SELCHANGE)
483 ULONG64 bytesPerRow64;
491 SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle,
TRUE);
512 HexEdit_SetSel(context->HexEditHandle, (ULONG)wParam, (ULONG)wParam + (ULONG)lParam);