Calling the Nt function from ntdll.dll in Win32, C ++

I want to call some Nt function from ntdll.dll, I do it as shown above.

To call: NtTestAlert () you need a typical ntcall kernel routine, accessible via int 2Eh. (from here I got the Nt functions http://undocumented.ntinternals.net/ )

The code is also incomplete, I get:

* error C2664: '_ntcall': unable to convert parameter 1 from 'int' to 'MESS (_stdcall)'

#include <iostream>
#include <windows.h>
#include <Ntsecapi.h>

using namespace std;

typedef int(__stdcall MESS)(unsigned int);

void __ntcall(MESS *msg)
{
    __asm
    {
        int 2Eh;
    }
}

int main(void)
{
    MESS *me = 0;
    int result = 0;

    HINSTANCE__ *hModule= LoadLibrary(L"C:\\Windows\\System32\\ntdll.dll");

    if(hModule != 0)
    {
        me = (MESS*)GetProcAddress(hModule, "NtTestAlert");

        if(me != 0)
        {
            unsigned int type = 1;

            result = (__ntcall((*me)(type)));
        }
        else
        {
            cout << "Error Load function!" << endl;
        }

        FreeLibrary(hModule);
    }
    else
    {
        cout << "Error load Dll!" << endl;
    }

    return 0;
}

      

+3


source to share


1 answer


You just call the function, the pointer to which you retrieve. int 2Eh

is an old (and deprecated) SP2 that makes system calls. When you call (using normal means only) the NTDLL function that is located below it. You don't need this.

Side note: you seem to be confusing a few more concepts. NtTestAlert

does not take a parameter.

NTSYSAPI NTSTATUS NTAPI NtTestAlert();

      

so that it translates (your type MESS

):

typedef NTSTATUS(__stdcall *TFNNtTestAlert)();

      



An example based on yours:

#include <iostream>
#include <windows.h>
#include <tchar.h>
#include <Ntsecapi.h>

using namespace std;

typedef NTSTATUS (__stdcall *TFNNtTestAlert)();
// NTSTATUS is LONG, in case that isn't defined in the above headers

int main(void)
{
    HMODULE hModule=GetModuleHandle(TEXT("ntdll.dll"));

    if(hModule != 0)
    {
        TFNNtTestAlert pfnNtTestAlert = (TFNNtTestAlert)GetProcAddress(hModule, "NtTestAlert");

        if(pfnNtTestAlert != 0)
        {
            result = pfnNtTestAlert();
        }
        else
        {
            cout << "Error Load function!" << endl;
            return 1;
        }
    }
    else
    {
        cout << "Error load Dll!" << endl;
        return 2;
    }

    return 0;
}

      

System call mechanism:

the syscall mechanism in Windows used int 2Eh

at some point (and now sysenter

) to pass parameters on the user-mode stack, the syscall index and then call the dispatcher. It then puts the thread into kernel mode, where it checks the parameters from the user mode stack, and then processing continues. This is a very crude scheme. I suggest you read a book by Gary Nebbett on this topic.

+8


source







All Articles