I am trying to disassemble the 64-bit ntdll.dll using IDA. From my understand, this DLL is located in C:\Windows\System32 on a Windows 64-bit OS. When I disassemble this DLL, it shows 32-bit addresses and a 32-bit instruction set. However, in the debugger, when I load this library into a process from the same directory, it has a 64-bit instruction set during runtime.
How can I disassemble the 64-bit ntdll?
Please check whether IDA is a 32 bit application in Task Manager (on the Processes page 32 bit processes should have the suffix (32 bit). If you switch to the Details page in Task Manager perform a right click on the column header and choose Select columns from the context menu. Select Platform to display the bit-ness of a process and close the dialog. 32 bit processes are listed as 32 bit in the Platform column.
If IDA is a 32 bit application, use the path c:\windows\sysnative\ntdll.dll to open the DLL. If you specify sysnative instead of System32, Windows uses the SYSTEM32 directory instead of the SysWOW64 for 32 bit apps.
Related
I'm trying to debug a 32 bit program on 64 bit Windows 7.
So I use gflags to set the debugger for that app. I fill in the path of the application, and the one of the debugger. But when I start the application, WinDBG doesn't run.
The same configuration works on 32 bit Windows 7.
So, is it impossible to debug a 32 bit application on 64 bit environment?
For me this has always worked, even if I use the "wrong" architecture gflags.
However Windbg must be in the PATH, or you must include path when you specify the debugger to gflags.
UPDATE
This is an old question. Older versions of gflags used to store the settings in one of the locations:
HTML\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
or
HTML\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
Depending on which architecture you pick for gflags.exe, it will affect either 64 bit or 32 bit processes.
Apparently at some point (thanks, #Thomas Weller to point it out), Microsoft changed gflags behavior and now (November 2016) current version of gflags.exe writes to both 32-bit and 64-bit registry locations, irrespective of the architecture.
This is a bit of a problem, because I used to use to attach 32-bit debugger to 32-bit processes and 64-bit debugger to 64 bit processes with the same process name. Now I cannot use gflags for this. However the workaround is to directly modify registry keys under Image File Execution Options.
Old Answer
Processor architecture of gflags.exe actually matters. If you use 64-bit version of Windows Debugging tools and launch gflags.exe from there, it will affect behavior of 64-bit applications. Similarly, if you use 32-bit version of Windows Debugging Tools and launch gflags.exe, it will affect 32-bit applications.
32-bit and 64-bit versions could be installed side-by-side. Pay close attention on bitness of application you are debugging and use the same architecture of the debugger/tools.
I am currently trying to get a list of all autoruns, but I am struggling on a 64-bit system. When I use:
My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", False)
It shows me entries from:
My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run", False)
Anyone know why and/or how to fix this?
I should also state that the items in HKLM\..\Run are different to those in HKLM\..\Wow6432Node..\Run.
Your process is a 32 bit process and so, on a 64 bit OS, the registry redirector comes into play. The HKLM\Software key is redirected and there are two views of it, a 32 bit view that your process is finding, and a 64 bit view.
It is true that if you run a 64 bit process, you will see the 64 bit view of the registry. However, that is not the full story. Windows processes CurrentVersion\Run entries from both 32 and 64 bit views of the registry. So, if you just switched to an x64 or AnyCPU process you would then be missing the autoruns stored in the 32 bit registry view.
So, since your goal is to list all the autoruns, you will need to read both 32 and 64 bit views of the registry. You can do that using the RegistryView enumeration that was introduced in .net 4. This allows a 32 bit process to access the 64 bit view of the registry. And indeed it allows a 64 bit process to access the 32 bit view of the registry.
If you want a process that runs on both 32 bit and 64 bit systems you will need to target either x86 or AnyCPU. And then use RegistryView to read both views of the registry if you detect that you are running on a 64 bit system.
That's happen because your application is compiled for x86 platform and running on a 64bit operating system. There is a comprensive article on Registry Redirection on MSDN
The registry redirector isolates 32-bit and 64-bit applications by
providing separate logical views of certain portions of the registry
on WOW64. The registry redirector intercepts 32-bit and 64-bit
registry calls to their respective logical registry views and maps
them to the corresponding physical registry location. The redirection
process is transparent to the application. Therefore, a 32-bit
application can access registry data as if it were running on 32-bit
Windows even if the data is stored in a different location on 64-bit
Windows
You could fix the problem compiling your application for AnyCPU platform
Apart from the MSDN reference, I want to know what these keys do? Does KEY_WOW64_32KEY means that a 32-bit app on x64 OS will access the WOW64 Registry Tree ? And does KEY_WOW64_64KEY means that a 32-bit app on x64 OS will access the normal Registry Tree and not the WOW64 Registry Tree ? What if I have to access some keys which I do not know whether lies in the WOW64 or normal Registry Tree ?
KEY_WOW64_64KEY on a 64-bit OS means that the registry access, no matter if it's a 32 or 64 bit process, will access the 64 bit registry view.
KEY_WOW64_32KEY on a 64-bit OS means that the registry access, no matter if it's a 32 or 64 bit process, will access the 32 bit registry view.
Neither of them have any effect on a 32-bit OS.
Leaving the flag out (the default) on a 64-bit OS will send registry accesses from 32-bit processes to the 32 bit registry view, and accesses from 64-bit processes to the 64 bit registry view.
For more info, this reference page at Microsoft should tell the whole tale.
From the linked reference:
For more information, see Accessing an Alternate Registry View.
Which says:
KEY_WOW64_64KEY: Access a 64-bit key from either a 32-bit or 64-bit application.
KEY_WOW64_32KEY: Access a 32-bit key from either a 32-bit or 64-bit application.
Attempting to call SetupDiCallClassInstaller from a program compiled in 32 bit mode fails on 64 bit Windows.
Apparently this is by design, but I'd like to know the reason.
According to MSDN:
Device Installations on 64-Bit Systems:
The 32-bit version of the application must check the value returned by UpdateDriverForPlugAndPlayDevices. If the return value is ERROR_IN_WOW64, the 32-bit application is executing on a 64-bit platform and cannot update inbox drivers. Instead, it must call CreateProcess (described in the Windows SDK documentation) to start the 64-bit version of the application. The 64-bit version can then call UpdateDriverForPlugAndPlayDevices, specifying a FullInfPath parameter that identifies the location of the 64-bit versions of all files.
So it looks like any API that is designed to report ERROR_IN_WOW64 is specifically intended NOT to work in WOW64, a 32bit process has to invoke a 64bit process to call the API.
If you are making that call from a 32bit process on a 64bit OS, it fails because it has to modify some registry keys in the 64bit portion of the registry. Where else if you were to make that call from a 64bit process on a 64bit OS, it would succeed likewise with 32bit process on a 32bit OS.
I was looking at some libraries with dumpbin and I noticed that all the 64-bit versions were linked to KERNEL32. Is there no KERNEL64 on 64-bit Windows? If not, why?
All my operating systems are 32-bit so I can't just look. A google search brings up nothing worthwhile so I suspect that there is no KERNEL64 but I'm still curious as to why this is.
EDIT: I found this later which is pretty useful. MSDN guide to x64
It's always called kernel32.dll, even on 64-bit windows. This is for the same compatibility reasons that system32 contains 64-bit binaries, while syswow64 contains 32-bit binaries.
On the 64-bit versions of Windows one of the "kernel32.dll"s contains 64-bit code but is still called kernel32.dll. This is at least misleading
Hope the following links will give the solution for this
http://www.howzatt.demon.co.uk/articles/DebuggingInWin64.html
http://www.viva64.com/en/l/0002/
http://blogs.msdn.com/b/aaron_margosis/archive/2012/12/10/using-ntfs-junctions-to-fix-application-compatibility-issues-on-64-bit-editions-of-windows.aspx
64-bit Windows provides such an environment "out of the box" and supports 32-bit applications using the 'Windows on Windows 64' subsystem, abbreviated to WOW64, which runs in user mode and maps the 32-bit calls to the operating system kernel into an equivalent 64-bit call. This is normally almost invisible to the calling program.Windows provides a set of 64-bit DLLs in %windir%\system32 and an equivalent set of 32-bit DLLs in %windir%\syswow64. In fact the bulk of the binary images in this directory are identical to the same files in the system32 directory on a 32-bit Windows installation. (It seems to me an unfortunate naming issue that the 64-bit DLLs live in system32 and the 32-bit ones live in syswow64, but there it is)