[newlib-cygwin] ldd: Handle executable relocation when setting breakpoint

Corinna Vinschen corinna@sourceware.org
Sat Jul 2 10:36:00 GMT 2016


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=85db21730beb3bb40723fa9b9f2dea5016fc4b4c

commit 85db21730beb3bb40723fa9b9f2dea5016fc4b4c
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Sat Jul 2 12:36:05 2016 +0200

    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>

Diff:
---
 winsup/utils/ldd.cc | 47 ++++++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/winsup/utils/ldd.cc b/winsup/utils/ldd.cc
index 8a33984..8e891d8 100644
--- a/winsup/utils/ldd.cc
+++ b/winsup/utils/ldd.cc
@@ -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;



More information about the Cygwin-cvs mailing list