我想从ntdll.dll调用一些Nt函数,我就是这样做的.
对于调用:NtTestAlert(),您需要典型的ntcall内核例程,可通过int 2Eh访问.
(从这里我得到Nt功能http://undocumented.ntinternals.net/)
代码也未完成,我得到:
*错误C2664:’_ callcall’:无法将参数1从’int’转换为’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;
}
解决方法:
您只需调用您检索其指针的函数. int 2Eh是一个旧的(并且自XP SP2过时)进行系统调用的方法.调用(仅通过正常方法)NTDLL函数,这是在下面发生的事情.你不必关心这一点.
旁注:你似乎混淆了一些概念. NtTestAlert不接受参数.
NTSYSAPI NTSTATUS NTAPI NtTestAlert();
所以这将转换为(你的MESS类型):
typedef NTSTATUS(__stdcall *TFNNtTestAlert)();
基于您的示例:
#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;
}
系统调用机制:
Windows中的syscall机制在某些时候使用int 2Eh(现在是sysenter)来传递用户模式堆栈上的参数,系统调用的索引然后调用调度程序.然后,这将线程转换为内核模式,其中检查来自用户模式堆栈的参数,然后继续处理.这是一个非常粗略的轮廓.我建议你阅读Gary Nebbett关于这个主题的书.