New version of wow64ext library is available for download:
http://rewolf.pl/stuff/rewolf.wow64ext.v1.0.0.7.zip
Changelog
- All 64bit APIs are now properly setting last Win32 error, thanks goes to Dreg (http://www.fr33project.org/) who implemented this feature.
This is actually unexpected benefit from hosting wow64ext on github (google code is dead, long live github), so if some of you want to add something to this library do not hesitate to do pull requests. I can’t promise that I’ll accept everything, but at least you may try :) Here is the address:
https://github.com/rwfpl/rewolf-wow64ext
There is an error in VirtualQueryEx64, sometimes returns 0 depending on the number of variables previously declared. I think it should be a problem in the stack, it is curious that when you declare a variable type BOOL, is sufficient for VirtualQueryEx64 fail.
Regards.
Hi, thanks for the report. Can you send me some simple code snippet, so I can reproduce this issue ?
OK. This is an example of code that fails
The compiler is BCB5 over Win10
Similar code in delphi7 also fail.
Regards.
I think that I know what is the issue here. MEMORY_BASIC_INFORMATION64 mbi64 has address aligned to 4 instead of 8 and x64 version of NT API refuse to work (it probably returns STATUS_DATATYPE_MISALIGNMENT 0x80000002). To prove that I’m right, you can printf address of mbi64 before VirtualQueryEx64 call:
I’ve no idea if BCB5/Delphi7 has any directive to force alignment of the local variable, but if it has, then address of mbi64 should be aligned to 8. I wasn’t able to trigger this problem with Visual Studio as it seems it always properly align this structure on the stack. I assume that it might be because of the way how it is declared:
Lo siento las etiquetas de código han borrado
#include
#include
y han deshecho la indentación.
Gracias
I tried to force alignment MEMORY_BASIC_INFORMATION64 to 8 and the error persists. MEMORY_BASIC_INFORMATION64 size is 48 and its direction is 0x0019FDCC
Cheers
#pragma pack won’t help as it only affects the internal layout of the structure, not the stack allocation address. In VC there is __declspec(align(n)) (DECLSPEC_ALIGN macro) and it guarantee that the address of the structure on the stack will be aligned to n (in our case it is 16). Your address 0x0019FDCC is obviously aligned to 4, that’s why it’s not working.
Ok, that’s the problem, but I can´t configure the compiler to align to 8.
I have located a pointer to VirtualAlloc, instead of declaring a variable in the stack MEMORY_BASIC_INFORMATION64 and with this works fine. I dont know if VirtualAlloc always performs an alignment to 8 or 16, you who you think?
VirtualAlloc allocates always at the page boundary so it is aligned not only to 8 and 16 but even to 0x1000. It will work, however I think that it is not necessary. You can try below code:
ALIGNUP macro simply adjusts pointer, so it is aligned to requested value (in this case 16), I’ve taken it from http://www.catch22.net/tuts/c-c-tricks
mbi64_buf is simple buffer, size of this buffer should be bigger than sizeof(MEMORY_BASIC_INFORMATION64). Adding alignment value to the size is sufficient, so it will always have enough memory for the structure. Then you can put mbi64_buf to ALIGNUP macro and cast it to MEMORY_BASIC_INFORMATION64 reference or pointer (whatever you prefer most). This will reduce overhead of VirtualAlloc and it should work fine.
@ReWolf
Very good trick, in fact I was thinking of doing something similar. Both VirtualAlloc, as ALIGNUP, works fine.
Thank you very much, you’ve done a good job with your wow64ext library
I’m glad that it works :) Thanks for the kind words!
Hi Rewolf,
I found an error when use: GetProcAddress64(GetModuleHandle64(L”wow64cpu.dll”),”X86SwitchTo64BitMode”)
please help to confirm this error.
thanks!
I guess you’re trying it on Windows 10. It won’t work on Windows 10, because Microsoft removed wow64cpu!X86SwitchTo64BitMode export. Far jump to wow64cpu!CpupReturnFromSimulatedCode is placed inside wow64 NTDLL in not exported Wow64SystemServiceCall function. You can find address of this function by simply disassembling any NT api:
@ReWolf
OS: Windows Server 2008 R2 Enterprise.
Ok, in this case I would like to ask you to send me wow64cpu.dll (you can put it on some shared hosting). You can also print the results of GetModuleHandle64(L”wow64cpu.dll”);
@ReWolf
Hi Rewolf,
wow64cpu.dll download link:
http://pan.baidu.com/s/1bnsPyKB
It works to get the handle by GetModuleHandle64(L”wow64cpu.dll”)
also works on your sample:
GetProcAddress64(GetModuleHandle64(L”wow64cpu.dll”),”TurboDispatchJumpAddressStart”)
I can’t download this file, try to send it to my email: rewolf [] rewolf.pl
Failed to send mail.
please try new link:
http://www.sisolver.com/temp/wow64cpu.zip
Thanks!
Well, it seems that this DLL doesn’t contain X86SwitchTo64BitMode export and it’s quite fresh: 0x562593AB (GMT: Tue Oct 20 01:06:51 2015). They probably changed something with the recent update.
Alright, I was a bit mistaken in my previous comments. Obviously, you can’t use GetProcAddress64 to obtain address of X86SwitchTo64BitMode, because it was NEVER exported :), so they didn’t change anything. I thought that it was exported in the past, but apparently not. It’s as simple as that.
Do you think you can port rewolf-wow64ext to be complied in MSVC? I’ve tried to compile it in a project of mine in MSVC2005 and I couldn’t :(
It should compile with VS2010 and newer, VS2005 is kind of ancient compiler nowadays.
@ReWolf
Regarding VirtualQueryEx64 I’ve changed the size parameter as you told me, so now it works, here is the informations about the process that can’t be read via ReadProcessMemory64 completely :
C:\Users\Mike\robot\La2Robot.exe (0x0000000000010000)
B[0x0000000000010000] AB[0x0000000000010000] MB[0x0000000000010000] S[319488] RS[4096] ST[0x00001000] AP[0x00000080] P[0x00000002] T[0x01000000] C[0] R/FAIL x86_64[299]
I think for the main process, I must use the base address provided by VirtualQueryEx64 instead ? Because probably the one returned by PEB/LDR (for .net executables) is being fooled by windows ? :D
@ReWolf
Hm my last question didn’t made sense lol, the base address is the same everywhere even when returned by VirtualQueryEx, just that I can’t read it :P
The report by VirtualQueryEx says it is a valid allocation with read access, who knows what’s up :P
Sorry for late answer, there is a possibility that the image memory is not continuous, in that case you need to read process memory in chunks. Information about each chunk can be obtained by consecutive calls to VirtualQueryEx.
How we can call methods such as EnumProcessModulesEx via rewolf ? (In 64-bit mode ?)
@Mark
Seems like we must call it from psapi.dll, but I can’t get the address the same way that is done with ntdll.dll (the dll is not found in 64-bit address space), any clue if this could be done ?
@Mark
The purpose here is that I want to enumerate the process modules in a 64 bit process, from a 32 bit process (But currently now, there is no “official way” to do this hehehe).
You need to use NtQuerySystemInformation with the SystemProcessInformation class.
@ReWolf
Oh, ok, so we must be doing it all by ntdll.dll, another question can we do it via PEB/TEB of the open process handle too ?
Alright, I misread your earlier comment and I thought that you want to enum processes :) As for the process modules, yes, you can use modules list from PEB.
@ReWolf
Actually I need to do both things ! :D
However it seems windows already provides the module handle, just that you can’t enumerate modules or anything because it is a 64-bit process.
@ReWolf
But the question is, how one would get PEB/TEB of a process handle ? Your example shows how to do it in the current process, but in this case I’ll have a process Handle for the process I want to access it.
You can call NtQueryInformationProcess with ProcessBasicInformation, check out MSDN for further details as this particular case is documented. I’m not sure at this moment if you can call standard NtQueryInformationProcess or you have to call it through wow64ext, but I’m sure you’ll figure it out.
@Mark
Hm, I’m having lots of troubles, isn’t there any way to call EnumProcessModulesEx but in 64-bit mode ? So this way it could read the proper informations and fill the output buffers ? It is all I want, so I can read the memory of the process and its modules using the ReadProcessMemory64 you’ve implemented :O
There is no way to load 64bit psapi.dll (and 64bit kernelbase.dll as well) into 32bit process.EnumProcessModulesEx internally calls NtQueryInformationProcess with ProcessBasicInformation and then it uses ReadProcessMemory to read PEB and other data from the target process. If you want the same behavior then you have to emulate it on your own.
@Mark
Ok, is there an alternative to OpenProcess in ntdll ? Because it seems the handle I’m passing to NtqueryInformationProcess in wow64 doesn’t work (probably because it is open in the 32 bit space).
Standard OpenProcess should work fine, look at the sample directory in wow64ext project (alternative would be NtOpenProcess, but it isn’t necessary).
@ReWolf
Ok, but when I try to useNtQueryInformationProccess in 32 bit environment (not via wow64) it returns this value : FFFFFFFFC0000004
And when I try it via wow64, I get :
FFFFFFFFC0000005
In any case, no clue why but I can’t get PEB through it :(
0xC0000004 – STATUS_INFO_LENGTH_MISMATCH, so you’re probably passing wrong arguments
0xC0000005 – STATUS_ACCESS_VIOLATION, no idea what can cause it atm
If you want, you can send me your code by e-mail and I’ll look at it when I’ll have some spare time.
@ReWolf
I had to call : NtWow64QueryInformationProcess64, now it worked and I get a valid PEB Address, now I’ll need to use ReadProcessMemory64 all the way It seems. (At least in every pointer I want to access stuff :P)
@ReWolf
Ok, that’s it, almost 100% working (I’ve used the iteration method you’ve used to GetProcAddress however, using ReadProcessMemory between the pointers, so I could “navigate” through PEB/Lists, however, how we can get the Image Size for the modules now ? Any ideas ?
@Mark
Found it too (Ldr Entry) ;), all sorted, thanks for the help on all questions.
@Mark
One last question actually, regarding x64 .net processes :
C:\Users\Fred\Downloads\TRENDNET\robot\La2Robot.exe (0x0000000000360000)
READ ERROR 1 – x86_64
C:\WINDOWS\SYSTEM32\ntdll.dll (0x00007FFA42A60000)
Success, Bytes Read (x86_64) : 1839104 – 1839104
C:\WINDOWS\SYSTEM32\MSCOREE.DLL (0x00007FFA33710000)
Success, Bytes Read (x86_64) : 425984 – 425984
C:\WINDOWS\system32\KERNEL32.dll (0x00007FFA409D0000)
Success, Bytes Read (x86_64) : 708608 – 708608
I can read basically all the modules loaded by it, but the main process does not allow me to be reading it, what could be causing it ? For native processes it works nicely, just .net ones aren’t good.
Try using VirtualQueryEx64 on that address and check the access rights and real size of the region.
@ReWolf
Hi, I forget to ask, but should the wowext64 work in any x86_64 version of windows ? Such as : xp sp3 / vista / w7 / 8 / 8.1 and 10 ? Or is this specific only to certain builds of windows ?
I’m not sure about xp64, but it should definitely work on Vista+ (up to Win10 TH2, tested).
@ReWolf
Ok great, I have asked because I’ll deploy it in production ;)
Cool :) Can you share (privately) some details about your project ? I’m always curious about the projects that uses wow64ext.
@ReWolf
It is a small antihack for a gameserver :), btw I’m having issues with ReadProcessMemory64 in AMD CPU, the same code works 100% stable in Intel, however any PC with AMD CPU is causing an access violation, trying to discover what could be the problem right now.
@ReWolf
VirtualQueryEx64 returns error 299 (partial copy) for that particular process. (It doesn’t completes properly).
@ReWolf
BEGIN
READ NAME
READ NAME – OK
QUERY
Name: c:\windows\system32\actxprxy.dll
Base: 0x00007FFED3D30000 (PEB/Module Base)
Alloc Address: 0x00007FFEDBF90000
Base: 0x00007FFEDBF90000 (Base reported by VirtualQuery)
Size:2813952 – 4096
State: 0x00001000
Protect: 0x00000080 – 0x00000002
Type: 0x01000000
QUERY-OK
READ (It stops here, it doesn’t even return it crashes calling ReadProcessMemory64)
Here is some data, of the location I’m trying to read :)
@ReWolf
Indeed, not sure why but all users with AMD x86_64 CPU cannot run the code properly, eventually it will crash somewhere hehe, probably something different with these CPUs.
@ReWolf
Here is the code sample:
It is quite simple, I provide the process handle with all the necessary permissions and loop through the modules, eventually it crashes, it is not related to ReadProcessMemory64 or VirtualQueryEx64 seems like to be something “generic” causing the problem I guess…
I’ve no idea what might be causing the crashes on AMD, but I see one problem in your usage of VirtualQueryEx, fourth argument should be sizeof(_mbi):
Regarding the crash, do you use the latest wow64ext sources/dll ?
@ReWolf
Yes, I’m using the latest one from GitHub, seems like some stack corruption or something like that, because the crash happens randomly, literally. (Even if you remove VirtualQueryEx out of the code, and just keep the PEB/LDR looping it will crash eventually (by just using ReadProcessMemory64).
I thought it was something wrong, but then when all AMD users complaint about not being able to keep the game running (because it was closing itself) then I figured something was a bit crazy hehehe. Then I made the test with only the loop, without anything else inside, but the problem persisted as well.
Yup, I’ve reproduced it on some amd machine, I’m already looking at the crashdumps, so hopefully I’ll be able to fix it :)
@ReWolf
Oh very nice :D
@ReWolf
Hi, looks like this one is a bit complex, having lucky ?
I’ve tried to contact you by e-mail, but maybe it went to spam :) I’ve possible fix, please send me an e-mail to rewolf [] rewolf.pl and hopefully you’ll be able to receive my reply (or check your spam folder :) )
@Mark
Oh, lol, that’s because this box is spammed as hell as I use it only for posting everywhere, but not to anything else (so not checking it frequently), but now I’ve checked it :D
@ReWolf
Right now the code is being used by 200+ users simultaneously in Intel CPU, just not in AMD. So the code seems to be working, at least for these users.