我想从ntdll.dll调用一些Nt函数,我就是这样做的。
对于调用:NtTestAlert(),您需要典型的ntcall内核例程,可通过int 2Eh访问。 (从这里我得到了Nt函数http://undocumented.ntinternals.net/)
代码也未完成,我得到了:
*错误C2664:' _ ntcall' :无法从' int'转换参数1到' 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;
}
答案 0 :(得分:8)
您只需调用您检索指针的函数即可。 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关于这个主题的书。