sRDI icon indicating copy to clipboard operation
sRDI copied to clipboard

convert user32.dll to shellcode and load it into memory failed

Open rainkin1993 opened this issue 6 years ago • 5 comments

Environment: Win10 1709 DLL: C:\Windows\SysWOW64\user32.dll

  1. I firstly use command python Python\ConvertToShellcode.py user32.dll convert user32.dll to user32.bin.
  2. Then I change the code in Native\Loader.cpp to call API MessageBoxA after loading the user32.dll and compile the Native project using Visual Studio 2015 Debug x86.
	// Only set the first page to RWX
	// This is should sufficiently cover the sRDI shellcode up top
	if (VirtualProtect(finalShellcode, sysInfo.dwPageSize, PAGE_EXECUTE_READWRITE, &dwOldProtect1)) {
		RDI rdi = (RDI)(finalShellcode);

		printf("[+] Executing RDI\n");
 		UINT_PTR hLoadedDLL = rdi(); // Excute DLL

		free(finalShellcode); // Free the RDI blob. We no longer need it.

		/*Function exportedFunction = (Function)GetProcAddressR(hLoadedDLL, "SayGoodbye");
		if (exportedFunction) {
			printf("[+] Calling exported functon\n");
			exportedFunction();
		}*/
		MyMessageBoxA exportedFunction = (MyMessageBoxA)GetProcAddressR(hLoadedDLL, "MessageBoxA");
		if (exportedFunction) {
			printf("[+] Calling exported functon\n");
			exportedFunction(0, "Hello", "user32.dll message", 1);
		}
	}


----

typedef int (WINAPI *MyMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
  1. Then use command Native.exe user32.bin to load the shellcode. The exe crashed and report a error :

0x7774CCC5 (ntdll.dll) (located at Native.exe) Exception: 0xC0000005: Access violation reading location 0x00000008.

I ensure that the GetProcAddressR return the correct address of MessageBoxA.

I found that the 0x7774CCC5 belongs to ntdll.dll!RtlAllocateHeap function: image

Do you have comments that which possible cause this problem? My conclusion is that reflective loading a DLL written by ourselves works fine but loading a system dll(ntdll, user32..) will not work. It seems that there is something the loader doesn't handle when load the system dll into memory.

rainkin1993 avatar Jul 05 '18 15:07 rainkin1993

Have you ever load a system dll(user32.dll, ntdll.dll) succeed?

rainkin1993 avatar Jul 06 '18 05:07 rainkin1993

I have played with this as well, but had similar results.

I can try to find some time to take a look, I agree with your setiment that some part of the loading process is obviously being missed.

You could try loading with the MemoryModule project and see if you have better luck. Their code does a much better job of handling edge cases in the unpacking process. Off the top of my head, delayed imports and TLS call backs are still missing from sRDI

monoxgas avatar Jul 06 '18 14:07 monoxgas

AH, I firstly try MemoryModule but also failed with another error messages

  1. When loading user32.dll using MemoryModule in Win10, the DLLMain was invoked and I get an error code 14: ERROR_OUTOFMEMORY
  2. For urlmon.dll, the DLL was successfully loaded, but when I invoke the URLDownloadToFileA API, the program crashed as well.

It seems that totally simulating the process of loading system DLLs is very difficult.

rainkin1993 avatar Jul 09 '18 14:07 rainkin1993

Interesting results. I might assume there is a class of core system DLLs (kernel32, user32, ntdll, etc.) which have special handling to deny loading multiple instances in one process.

Other Microsoft DLLs like urlmon, gdi, etc. might not have this special handling and therefore might give better results. Going to do some digging to try and find out more.

The PE load process is well documented, but I can't shake the feeling that Microsoft has some special handling that doesn't conform to well-known standards.

monoxgas avatar Jul 23 '18 03:07 monoxgas

Adding an interesting note here, kernel32.dll appears to load and run fine for those wondering.

I can validate the failure of user32 and the crash from urlmon. Looking through ReactOS and online material, my guess for the user32 failure is the relation to GDI. Potentially something about GDI heaps being allocated and mapped in the PEB.

monoxgas avatar Jul 26 '18 15:07 monoxgas