怎么调用NTDLL.DLL中的函数ZwQueryDirectoryFile

hmugua 2008-10-07 03:16:53
extern NTSYSAPI NTSTATUS NTAPI ZwQueryDirectoryFile(
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
IN PVOID IoApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK pIoStatusBlock,
OUT PVOID FileInformationBuffer,
IN ULONG FileInformationBufferLength,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN bReturnOnlyOneEntry,
IN PUNICODE_STRING PathMask OPTIONAL,
IN BOOLEAN bRestartQuery);

然后调用该函数,编译后出现以下连接错误:
error LNK2001: unresolved external symbol "__declspec(dllimport) long __stdcall ZwQueryDirectoryFile(void *,void *,void (__stdcall*)(void *,struct _IO_STATUS_BLOCK *,unsigned long),void *,struct _IO_STATUS_BLOCK *,void *,unsigned long,enu
m _FILE_INFORMATION_CLASS,unsigned char,struct _UNICODE_STRING *,unsigned char)" (__imp_?ZwQueryDirectoryFile@@YGJPAX0P6GX0PAU_IO_STATUS_BLOCK@@K@Z010KW4_FILE_INFORMATION_CLASS@@EPAU_UNICODE_STRING@@E@Z)
.\objchk\i386\File.sys : fatal error LNK1120: 1 unresolved externals
这个问题其实已经有人问过了,人家告诉说:
1.到DDK中找到ntdll.lib
2.链接ntdll.lib
3.制作头文件,该头文件需要定义函数原型中需要的结构,可以从DDK中参考,
4.定义需要使用的函数的原型,声明 extern "C"或项目使用C语法编译。
我是一菜鸟。对于2、3、4步骤我实在不知道该怎么弄。 能请各位知道的说的详细一些吗?
期待着您能给我指点一下,qq:165389837.mail:consel@qq.com. PLEASE!!!
...全文
879 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hmugua 2008-10-09
  • 打赏
  • 举报
回复
搞定了。
代码没有问题。主要是配置文件除了问题。
谢谢各位的关注。
hmugua 2008-10-08
  • 打赏
  • 举报
回复
安装ddk了。winxp SP2 + W2K3DDK + vc6
zhoujianhei 2008-10-08
  • 打赏
  • 举报
回复
这个是驱动,需要安装DDK,在DDK环境中编译。

hmugua 2008-10-08
  • 打赏
  • 举报
回复
编译能通过,可链接的时候出现了上述错误。我用的是vc6.请大家指点。期待!!
WinEggDrop 2008-10-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hmugua 的回复:]
不讲过时不过时,我只想知道怎么通过编译啊!;——(
[/Quote]

系统上装上DDK就能编译啦.
hmugua 2008-10-08
  • 打赏
  • 举报
回复
不讲过时不过时,我只想知道怎么通过编译啊!;——(
WinEggDrop 2008-10-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hmugua 的回复:]
我在网上搜索到一片“编写驱动拦截NT的API实现隐藏文件目录”的文章。我想试一下。我在代码里面添加:
HMODULE hModule = ::LoadLibrary("ntdll.dll");
ZwQueryDirectoryFile = (PFN_ZwQueryDirectoryFile)::GetProcAddress( hModule, "ZwQueryDirectoryFile");
可vc6说HMODULE为定义。包含#include <windows.h>,又报winbase.h里面错误,~~~~(>_ <)~~~~
代码如下:
#include <ntddk.h>

#define FILE_DEVICE_NTHIDE…
[/Quote]

估计N多防病毒的会叫.卡巴估计也叫了,瑞星那些不清楚,有可能会叫吧.SSDT Hook已经是过时技术,满大街反rootkit工具能查出来.现在连防病毒的都带反rootkit功能或相关工具了.
cnzdgs 2008-10-08
  • 打赏
  • 举报
回复
LZ是要做应用程序还是驱动程序,如果是应用程序按我前面说的来做,如果要做驱动程序,需要先找本书系统地学习一下,因为驱动程序与应用程序的概念完全不同。
cnzdgs 2008-10-07
  • 打赏
  • 举报
回复
做应用程序不要包含DDK的头文件,把#include <ntddk.h>去调,需要的定义自己复制过来。
hmugua 2008-10-07
  • 打赏
  • 举报
回复
我在网上搜索到一片“编写驱动拦截NT的API实现隐藏文件目录”的文章。我想试一下。我在代码里面添加:
HMODULE hModule = ::LoadLibrary("ntdll.dll");
ZwQueryDirectoryFile = (PFN_ZwQueryDirectoryFile)::GetProcAddress( hModule, "ZwQueryDirectoryFile");
可vc6说HMODULE为定义。包含#include <windows.h>,又报winbase.h里面错误,~~~~(>_<)~~~~
代码如下:
#include <ntddk.h>

#define FILE_DEVICE_NTHIDEFILES 0x8000
#define NTHIDEFILES_IOCTL_BASE 0x800

#define CTL_CODE_NTHIDEFILES(i) CTL_CODE(FILE_DEVICE_NTHIDEFILES, NTHIDEFILES_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_NTHIDEFILES_HELLO CTL_CODE_NTHIDEFILES(0)

#define NTHIDEFILES_DEVICE_NAME L"\\Device\\NtHideFiles"
#define NTHIDEFILES_DOS_DEVICE_NAME L"\\DosDevices\\NtHideFiles"
...
typedef struct _FILE_BOTH_DIR_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

#pragma pack(1)
typedef struct _SERVICE_DESCRIPTOR_ENTRY
{
unsigned int * ServiceTableBase;
unsigned int * ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char * ParamTableBase;
} SERVICE_DESCRIPTOR_ENTRY, *PSERVICE_DESCRIPTOR_ENTRY;
#pragma pack()

// ZwQueryDirectoryFile 的原型
typedef NTSTATUS (NTAPI *PFN_ZwQueryDirectoryFile)(
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
IN PVOID IoApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK pIoStatusBlock,
OUT PVOID FileInformationBuffer,
IN ULONG FileInformationBufferLength,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN bReturnOnlyOneEntry,
IN PUNICODE_STRING PathMask OPTIONAL,
IN BOOLEAN bRestartQuery);

NTSYSAPI
NTSTATUS
NTAPI
ZwQueryDirectoryFile(
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
IN PVOID IoApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK pIoStatusBlock,
OUT PVOID FileInformationBuffer,
IN ULONG FileInformationBufferLength,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN bReturnOnlyOneEntry,
IN PUNICODE_STRING PathMask OPTIONAL,
IN BOOLEAN bRestartQuery);

NTSTATUS HookZwQueryDirectoryFile(
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
IN PVOID IoApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK pIoStatusBlock,
OUT PVOID FileInformationBuffer,
IN ULONG FileInformationBufferLength,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN bReturnOnlyOneEntry,
IN PUNICODE_STRING PathMask OPTIONAL,
IN BOOLEAN bRestartQuery);

__declspec(dllimport) SERVICE_DESCRIPTOR_ENTRY KeServiceDescriptorTable;

// 保存原 ZwQueryDirectoryFile 函数指针
PFN_ZwQueryDirectoryFile OriginalZwQueryDirectoryFile = NULL;

PMDL g_pmdlSystemCall = NULL;
PVOID *MappedSystemCallTable = NULL;
BOOLEAN g_bHooked = FALSE;

#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function + 1)
#define SYSTEMSERVICE(_Function) KeServiceDescriptorTable.ServiceTableBase[SYSCALL_INDEX(_Function)]
#define HOOK_SYSCALL(_Function, _Hook, _Orig) _Orig = (PVOID)InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Hook)
#define UNHOOK_SYSCALL(_Function, _Orig) InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Orig)
...
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
...
// Map the memory into our domain to change the permissions on the MDL
g_pmdlSystemCall = IoAllocateMdl(KeServiceDescriptorTable.ServiceTableBase,
KeServiceDescriptorTable.NumberOfServices * 4,
FALSE, FALSE, NULL);

MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
// Change the flags of the MDL
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);

// HOOK ZwQueryDirectoryFile 并保存原 ZwQueryDirectoryFile 函数地址
HOOK_SYSCALL(ZwQueryDirectoryFile, HookZwQueryDirectoryFile, OriginalZwQueryDirectoryFile);
....
}



NTSTATUS HookZwQueryDirectoryFile(
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
IN PVOID IoApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK pIoStatusBlock,
OUT PVOID FileInformationBuffer,
IN ULONG FileInformationBufferLength,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN bReturnOnlyOneEntry,
IN PUNICODE_STRING PathMask OPTIONAL,
IN BOOLEAN bRestartQuery)
{
NTSTATUS rc = STATUS_SUCCESS;
ANSI_STRING ansiFileName, ansiDirName, HideDirFile;
UNICODE_STRING uniFileName;
PCWSTR pProcPath = NULL;

// 初始化要过虑的文件名,大写形式
RtlInitAnsiString(&HideDirFile, "WAR3.EXE");

pProcPath = GetProcessFullName();
DbgPrint("[NtHideFiles] GetProcessFullName: %ws\n", pProcPath == NULL ? L"<null>" : pProcPath);

// 执行真正的 ZwQueryDirectoryFile 函数
rc = OriginalZwQueryDirectoryFile(
hFile,
hEvent,
IoApcRoutine,
IoApcContext,
pIoStatusBlock,
FileInformationBuffer,
FileInformationBufferLength,
FileInfoClass,
bReturnOnlyOneEntry,
PathMask,
bRestartQuery);

// 如果执行成功,而且 FILE_INFORMATION_CLASS 的值为 FileBothDirectoryInformation,我们就进行处理,过滤
if (NT_SUCCESS(rc) && FileInfoClass == FileBothDirectoryInformation)
{
// 把执行结果赋给 pFileInfo
PFILE_BOTH_DIR_INFORMATION pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer;
PFILE_BOTH_DIR_INFORMATION pLastFileInfo = NULL;
BOOLEAN bLastOne = FALSE;

// 循环检查
do
{
bLastOne = !pFileInfo->NextEntryOffset;
RtlInitUnicodeString(&uniFileName, pFileInfo->FileName);
RtlUnicodeStringToAnsiString(&ansiFileName, &uniFileName, TRUE);
RtlUnicodeStringToAnsiString(&ansiDirName, &uniFileName, TRUE);
RtlUpperString(&ansiFileName, &ansiDirName);

// 打印结果,用 debugview 可以查看打印结果
//dprintf("ansiFileName :%s\n", ansiFileName.Buffer);
//dprintf("HideDirFile :%s\n", HideDirFile.Buffer);

// 开始进行比较,如果找到了就隐藏这个文件或者目录
if (RtlCompareMemory(ansiFileName.Buffer, HideDirFile.Buffer, HideDirFile.Length) == HideDirFile.Length)
{
dprintf("This is HideDirFile!\n");

if (bLastOne)
{
if (pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)
rc = STATUS_NO_MORE_FILES; // 隐藏文件或者目录;
else
pLastFileInfo->NextEntryOffset = 0;

break;
}
else // 指针往后移动
{
int iPos = (ULONG)pFileInfo - (ULONG)FileInformationBuffer;
int iLeft = (ULONG)FileInformationBufferLength - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory((PVOID)pFileInfo, (PVOID)((PCHAR)pFileInfo + pFileInfo->NextEntryOffset), (ULONG)iLeft);
continue;
}
}

pLastFileInfo = pFileInfo;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)pFileInfo + pFileInfo->NextEntryOffset);
} while (!bLastOne);

RtlFreeAnsiString(&ansiDirName);
RtlFreeAnsiString(&ansiFileName);
}

return rc;
}

多谢各位了!!
cnzdgs 2008-10-07
  • 打赏
  • 举报
回复
自己定义函数类型,然后用LoadLibrary、GetProcAddress获取函数指针,再调用。

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧