wow64ext v1.0.0.6

New version of wow64ext library is available for download:
http://rewolf.pl/stuff/rewolf.wow64ext.v1.0.0.6.zip

Changelog

  • Bugfix for improperly aligned stack. It was aligned to 8, and it was failing when some x64 SSE code was executed as it needs 0x10 alignment. Thanks goes to Vlad, who pointed it out in some recent comment under previous release: http://blog.rewolf.pl/blog/?p=1097#comment-51893. This bug was present since the first version of the library, thankfully now it’s gone.

11 Comments

  1. Hey Rewolf, would you happen to know a way to allocate memory past 0x7FFFFFFF in a WoW64 processs. I’ve tried NtAllocateVirtualMemory with specific BaseAddress values but it keeps returning 0xC0000018 (STATUS_CONFLICTING_ADDRESS) most likely because the regions above 0x7FFFFFFF are already reserved by the system as private memory.

    Reply

    1. As for the region between 0x80000000 and 0xFFFFFFFF, You can do it without wow64ext library, just link the executable with /LARGEADDRESSAWARE switch (IMAGE_FILE_LARGE_ADDRESS_AWARE). On 64bit Windows, this enables You to use whole 4GB address space. Allocating memory above those limits is not possible – at least, not on Win7 and Vista. I’m not sure about Win8, as x64 NTDLL is allocated above those limits, but it can be handled as a special case. I don’t have access to Win8 x64 at this moment, so I can’t help You in this particular case.

      Reply

  2. Hi Rewolf. There are another strange issue i’ve found. Some API calls still not work properly for me. For simple example, MessageBoxA:

    DWORD64 user32 = LoadLibrary64(L"user32.dll");
    DWORD64 mb = GetProcAddress64(user32,"MessageBoxA");
    __declspec(align(16)) char t1[32] = "hello";
    __declspec(align(16)) char t2[32] = "title";
     
    X64Call(mb, 4, (DWORD64)0, (DWORD64)t1, (DWORD64)t2, (DWORD64)MB_OK);

    I see messagebox, with ‘title’ displayed correctly in title of message box window, but ‘hello’ are not displayed, and ok button doesn’t have ‘ok’ label on it. Some other api’s also not working in different ways.

    I’ve checked in windbg, user32.dll are loaded correctly and dllmain are executed (i’ve got user32.dll loading code from w64owow64 by George Nicolaou). Also i’ve checked that MessageBoxA correctly receives “hello” and “title” strings, that are aligned on 16-byte border.

    Reply

    1. From what I remember, loading x64 versions of user32 and kernel32 libraries was rather problematic. The current state of wow64ex library doesn’t support calling any other libraries except NTDLL. I’ve looked at mentioned method (w64owow64) and I’m not fully convinced that it will always work (as we can see, probably it doesn’t). I’m not exactly sure what’s happening there and I’m not willing to debug that issue at this moment :) Maybe You can try asking George Nicolaou, as described problem is on his side.

      Reply

  3. I found a bug in win10 (Buildnumber: 9879), when i invoke _LdrGetProcedureAddress to get the export funtion address, the r10 register will be modified in ms code, so when the wow64 return to x64, it crashed, because the code return to x64 is — jmp r10

    Reply

  4. Nice library. Noticed a small mistake in your variable naming convention, not really a bug but for the sake of code uniformity I am mentioning it. Keep up the good work

    It appears that you copied the NtReadVirtualMemory() code to create the same function for NtWriteProcessMemory() but left the function VA variable name the same as NtReadVirtualMemory

    static DWORD64 "nrvm" = 0;
        if (0 == "nrvm")
        {
            "nrvm" = GetProcAddress64(getNTDLL64(), "NtWriteVirtualMemory");
            if (0 == "nrvm")
                return 0;
        }
        DWORD64 numOfBytes = lpNumberOfBytesWritten ? *lpNumberOfBytesWritten : 0;
        DWORD64 ret = X64Call("nrvm", 5, (DWORD64)hProcess, lpBaseAddress, (DWORD64)lpBuffer, (DWORD64)nSize, (DWORD64)&numOfBytes);

    Reply

    1. Thanks for the feedback, I see that the same inconsistency appears in Set/GetThreadContext. I’ll change it with the next update.

      Reply

  5. Really useful library , great job. However i tried to implement NtUnMapViewOfSection but it doesn’t seem to work , it returns me 0xc000045 , a protection error but it doesn’t seem to be the real error .
    How i implemented it :

    NTSTATUS x64Func::x64NtMapViewOfSection (
        IN HANDLE SectionHandle,
        IN HANDLE ProcessHandle,
        IN OUT PDWORD64* BaseAddress,
        IN ULONG ZeroBits,
        IN ULONG CommitSize,
        IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
        IN OUT PULONG_PTR ViewSize,
        IN SECTION_INHERIT InheritDisposition,
        IN ULONG AllocationType,
        IN ULONG Protect
        )
    {
    	static DWORD64 _NtMapViewOfSection = 0;
    	if(!_NtMapViewOfSection)
    	{
    		_NtMapViewOfSection  = GetProcAddress64((PVOID)getNTDLL64(),"NtMapViewOfSection");
    		if(!_NtMapViewOfSection){
    			return 0;
    		}
    	}
     
    	return (NTSTATUS)x64Func::X64Call(_NtMapViewOfSection,10,
    	(DWORD64)SectionHandle,(DWORD64)ProcessHandle,(DWORD64)BaseAddress, (DWORD64)ZeroBits,(DWORD64)CommitSize,
    	(DWORD64)&SectionOffset,(DWORD64)ViewSize, InheritDisposition,(DWORD64) AllocationType,(DWORD64)Protect);
    }

    And how i’am using it :

    	HANDLE hSec = NULL;
    	LARGE_INTEGER a;
    	SIZE_T s = NULL;
    	PDWORD64 pBaseAddress = NULL;
    	s = dwImageSize;
    	a.HighPart = 0;
    	a.LowPart = s;
     
     
    res = x64Func::x64NtMapViewOfSection(hSec,hProcess,pBaseAddress,NULL,NULL,NULL,&s,ViewUnmap,NULL,PAGE_EXECUTE_READWRITE);

    Reply

    1. Try this: http://pastebin.com/xHXDyUft

      I haven’t tested it, but I tried to fix all obvious problems:

      • – BaseAddress should be declared as DWORD64, not PDWORD64, as PDWORD64 would be 32 bits (and it should be 64, as you’re passing address of this variable to the function).
      • – s should be declared as DWORD64, not SIZE_T. SIZE_T is 32bit on x86, and 64bit on x64, similar problem as with BaseAddress.
      • – You are passing &SectionOffset to the X64Call, this is definitely wrong.
      • – Casting result of getNTDLL64() to PVOID will not work on Windows 8, as NTDLL64 is loaded above 4GB on this plaform.
      • – You missed DWORD64 cast for InheritDisposition in X64Call

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *