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