ldd: Handle executable relocation when setting breakpoint
set_entry_point_break() uses GetModuleInformation to fetch the address of the exe's entry point. However, just as with lpStartAddress from the CREATE_PROCESS_DEBUG_EVENT event, the returned address is only computed from the PE file header. It's not actually the entry point in memory, if the executable is relocated (ASLR). See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684229(v=vs.85).aspx Convert this to using the info from CREATE_PROCESS_DEBUG_EVENT combined with the offset from the PE file header's AddressOfEntryPoint to deal with relocation. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
9f54ceadae
commit
85db21730b
@ -212,25 +212,6 @@ start_process (const wchar_t *fn, bool& isdll)
|
||||
set_errno_and_return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
set_entry_point_break ()
|
||||
{
|
||||
HMODULE hm;
|
||||
DWORD cbe;
|
||||
SIZE_T cbw;
|
||||
if (!EnumProcessModules (hProcess, &hm, sizeof (hm), &cbe) || !cbe)
|
||||
set_errno_and_return (1);
|
||||
|
||||
MODULEINFO mi = {};
|
||||
if (!GetModuleInformation (hProcess, hm, &mi, sizeof (mi)) || !mi.EntryPoint)
|
||||
set_errno_and_return (1);
|
||||
|
||||
static const unsigned char int3 = 0xcc;
|
||||
if (!WriteProcessMemory (hProcess, mi.EntryPoint, &int3, 1, &cbw) || cbw != 1)
|
||||
set_errno_and_return (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dlls
|
||||
{
|
||||
LPVOID lpBaseOfDll;
|
||||
@ -318,8 +299,6 @@ report (const char *in_fn, bool multiple)
|
||||
|
||||
DEBUG_EVENT ev;
|
||||
|
||||
unsigned dll_count = 0;
|
||||
|
||||
dlls dll_list = {};
|
||||
dlls *dll_last = &dll_list;
|
||||
const wchar_t *process_fn = NULL;
|
||||
@ -331,9 +310,31 @@ report (const char *in_fn, bool multiple)
|
||||
break;
|
||||
switch (ev.dwDebugEventCode)
|
||||
{
|
||||
case CREATE_PROCESS_DEBUG_EVENT:
|
||||
if (!isdll)
|
||||
{
|
||||
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER) alloca (4096);
|
||||
PIMAGE_NT_HEADERS nt_header;
|
||||
PVOID entry_point;
|
||||
static const unsigned char int3 = 0xcc;
|
||||
SIZE_T bytes;
|
||||
|
||||
if (!ReadProcessMemory (hProcess,
|
||||
ev.u.CreateProcessInfo.lpBaseOfImage,
|
||||
dos_header, 4096, &bytes))
|
||||
print_errno_error_and_return (in_fn);
|
||||
|
||||
nt_header = PIMAGE_NT_HEADERS (PBYTE (dos_header)
|
||||
+ dos_header->e_lfanew);
|
||||
entry_point = (PVOID)
|
||||
((caddr_t) ev.u.CreateProcessInfo.lpBaseOfImage
|
||||
+ nt_header->OptionalHeader.AddressOfEntryPoint);
|
||||
|
||||
if (!WriteProcessMemory (hProcess, entry_point, &int3, 1, &bytes))
|
||||
print_errno_error_and_return (in_fn);
|
||||
}
|
||||
break;
|
||||
case LOAD_DLL_DEBUG_EVENT:
|
||||
if (!isdll && ++dll_count == 2)
|
||||
set_entry_point_break ();
|
||||
dll_last->next = (dlls *) malloc (sizeof (dlls));
|
||||
dll_last->next->lpBaseOfDll = ev.u.LoadDll.lpBaseOfDll;
|
||||
dll_last->next->next = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user