I'm recently doing some research on private APIs. I tried to call functions such as NtOpenFile
in ntdll.dll with LoadLibrary
and GetProcAddress
at runtime. Luckly, it succeed. This morning I performed a file search on my computer and find ntdll.lib
in my C drive. As far as I know of, such .lib file should contain stubs for dll exports available for linking. So, I tried to link my application to that lib but I'm constantly getting unresolved external symbol
errors. However, a dumpbin /EXPORTS
shows that ntdll.lib clearly has NtOpenFile exported. How could I resolve this error?
相关问题
- Multiple sockets for clients to connect to
- How to know full paths to DLL's from .csproj f
- Importing NuGet references through a local project
- What is the best way to do a search in a large fil
- Visual Studio 2019 - error MSB8020: The build tool
The problem is the name of the function as recorded in the library and as it is generated from compiler.
dumpbin
just shows you the base exported symbolNtOpenFile
(the undecorated one), but there is also a import symbol__imp_NtOpenFile
. Now if you try to link staticallyNtOpenFile
declaring it as:The compiler will generate, for a
__stdcall
function under 32bits, the symbol_NtOpenFile@24
, if I'm not wrong counting the bytes size of call arguments, that obviously is not in the library. This is due to the fact that ntdll.lib is intended to be used under DDK for drivers development, where the compiler generates undecorated symbols.To clarify the concept open the ntdll.lib file with a binary editor and look for
NtOpenFile
, you will see only it and the import version__imp_NtOpenFile
. Now open a standar library as gdi32.lib, just to name one, and search forCreateDIBSection
you'll find a_CreateDIBSection@24
and also__imp__CreateDIBSection@24
.So what's going on? Simple dumpbin shows always the undecorated names, but the compiler generates decorated ones, result: the linker fails. It is said that names use
PASCAL
convention, that is the same as__stdcall
, but doesn't decorate symbols (i.e. read this https://msdn.microsoft.com/en-us/library/aa235591(v=vs.60).aspx).There is a way to solve the problem? Yes you have to create your own import library assigning an alias to the wanted function having the correct decorations. Start reading this https://msdn.microsoft.com/en-us/library/0b9xe492.aspx.
No longer the case, you can find ntdll.lib import library and NT headers as I write this in 2019.
It's a lot of extra code to do it the GetProcAddress() way. Certainly direct imports is cleaner and is the pattern we're used to for C/C++ desktop applications.
I used to make my own "ntdll.lib" import library by creating a simple Windows DLL project with a .def file, etc. Adding each ntdll API function one at the time as I needed them as a stub and for a header file. Throwing away the .dll, just using the .lib from it.
But at least since MSVC 2017 it includes user mode (for desktop applications) ntdll.lib libraries for x86 and ARM in both 32bit and 64bit varieties. This might require the Windows 10 WDK to be installed. Just search your "C:\Program Files (x86)" for "ntdll.lib" and you should find them.
Then on the header front, a lot of the ntdll prototypes and definitions are in "winternl.h" but unfortunately many parts are missing and/or there are only simplified versions of structures, etc. To solve this you can use the fantastic NT header set from the "Process Hacker" project: https://github.com/processhacker/processhacker The headers are in "phnt".
Instead of the typical "windows.h" and "winternl.h" combo, you will use:
And then to specificity Windows 10 as a target for example (default is Windows 7) you would follow that with:
Note "phnt_windows.h" already includes "windows.h" for you. So you should be able to follow it with any other Windows, stdlib, stl, etc., headers after; not much different then the typical desktop build environment.
Or some others to use:
https://github.com/Fyyre/ntdll
Also includes libs:
https://github.com/x64dbg/ScyllaHide/tree/master/3rdparty/ntdll
Yet another with ntdll libraries too:
https://github.com/odzhan/injection/tree/master/ntlib