将WCHAR类型转换为char类型

chenhao1988 2009-05-20 03:33:39

内核开发中我使用PCWSTR GetCurrentProcessFileName()
{
DWORD dwAddress = (DWORD)PsGetCurrentProcess();
if(dwAddress == 0 || dwAddress == 0xFFFFFFFF)
return NULL;
dwAddress += 0x1B0;
if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
dwAddress += 0x10;
if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
dwAddress += 0x3C;
if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
KdPrint(("Current Process Full Path Name: %ws\n", (PCWSTR)dwAddress));
return (PCWSTR)dwAddress;
} 得到了当前进程的路径,我现在要将该路径转换成char类型的字符串,我用了下面这个函数:
int ConvertFileNameWCHARToCHAR(PWCHAR pWChar, PCHAR pChar)
{
UNICODE_STRING usFileName;
ANSI_STRING asFileName;

RtlInitUnicodeString(&usFileName, pWChar);

asFileName.Length = 0;
asFileName.MaximumLength = 256;
asFileName.Buffer = pChar;

RtlUnicodeStringToAnsiString(&asFileName, &usFileName, FALSE);
pChar[asFileName.Length] = 0;
return asFileName.Length;
}
调用语句如下(调用语句在我的HookZwOpenFile中):
char aProcessName[MAXPATHLEN];
ZeroMemory(aProcessName,MAXPATHLEN); //将该空间清零
ConvertFileNameWCHARToCHAR(GetCurrentProcessFileName(),aProcessName);
加载了这个驱动以后,能够正常得到进程的路径,但是只要我一打开文件,如打开1111.txt,立即蓝屏,这是什么原因???不调用ConvertFileNameWCHARToCHAR是没有任何问题的。



我的Hook函数如下:
NTSTATUS
HookZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
)
{
NTSTATUS rc = 0;
char aProcessName[MAXPATHLEN];
ZeroMemory(aProcessName,MAXPATHLEN);
ConvertFileNameWCHARToCHAR(GetCurrentProcessFileName(),aProcessName);
if(ObjectAttributes->ObjectName->Length>=11)
{
if(!memcmp(ObjectAttributes->ObjectName->Buffer, L"\\??\\C:\\cccc",22 ))
{
DbgPrint("ZwOpenFile ObjectAttributes->ObjectName=%ws\n",ObjectAttributes->ObjectName->Buffer);
//return STATUS_UNSUCCESSFUL;
}
}

//调用原函数
rc=(NTSTATUS)RealZwOpenFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
ShareAccess,
OpenOptions
);
return rc;
}
...全文
623 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenhao1988 2009-05-26
  • 打赏
  • 举报
回复
谢谢9楼,问题已经解决了,我是调试的时候发现的。
jackyjkchen 2009-05-24
  • 打赏
  • 举报
回复
CStringA最简单,前提得加mfc库
cnzdgs 2009-05-24
  • 打赏
  • 举报
回复
这种方法只能在固定的系统环境中用,换个环境就很可能会出问题,如果你只在自己的系统中使用就没关系。
问题看起来是访问了无效的内存地址,既然确定打开1111.txt会出问题,只要设置断点调试一下就能查出问题了,先确定是哪行代码有问题,再检查是哪个地址无效,估计就是GetCurrentProcessFileName所取得的进程名地址不对。
chenhao1988 2009-05-24
  • 打赏
  • 举报
回复
感谢7楼的答复。
GetCurrentProcessFileName确实是网上Copy的,但是这个应该没有问题吧,XP不是不出补丁了嘛。我的机器上确实能够使用这个方法来取进程路径!
cnzdgs 2009-05-23
  • 打赏
  • 举报
回复
GetCurrentProcessFileName是从网上Copy来的吧?这种Undocumented的方法是不能用的。MS没有开放内核模式下获取进程名的方法,建议你用进程ID来识别进程,可以与应用程序通讯,由应用程序负责将进程ID与进程名称对应起来。
chenhao1988 2009-05-23
  • 打赏
  • 举报
回复
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING nameString, linkString;
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
WCHAR wBuffer[200];


nameString.Buffer = wBuffer;
nameString.MaximumLength = 200;

DriverObject->DriverUnload = DriverUnload;

RtlInitUnicodeString(&nameString, L"\\Device\\MyDriver");

// 创建设备
status = IoCreateDevice(
DriverObject,
0,
&nameString,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&deviceObject );

if (!NT_SUCCESS( status ))
return status;


deviceObject->Flags |= DO_BUFFERED_IO;


RtlInitUnicodeString(&linkString, L"\\??\\MyDriver");
//创建符号链接
status = IoCreateSymbolicLink (&linkString, &nameString);

if (!NT_SUCCESS( status ))
{
IoDeleteDevice (DriverObject->DeviceObject);
return status;
}

DriverObject->MajorFunction[IRP_MJ_CREATE] = MydrvDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MydrvDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MydrvDispatchIoctl;

__asm{
mov eax, cr0
mov CR0VALUE, eax
and eax, 0fffeffffh //DisableWriteProtect
mov cr0, eax
}


//HOOK
RealZwOpenFile = (REALZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile));
(REALZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile))= HookZwOpenFile;

//EnableWriteProtect
__asm
{
mov eax, CR0VALUE
mov cr0, eax
}
return STATUS_SUCCESS;
}

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irpSp;

UNREFERENCED_PARAMETER(DeviceObject);
irpSp = IoGetCurrentIrpStackLocation( Irp );

switch (irpSp->MajorFunction)
{
case IRP_MJ_CREATE:
DbgPrint("IRP_MJ_CREATE\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;

break;

case IRP_MJ_CLOSE:
DbgPrint("IRP_MJ_CLOSE\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;

break;
}
IoCompleteRequest(Irp, 0);
return STATUS_SUCCESS;
}

static NTSTATUS MydrvDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
NTSTATUS status;
ULONG ControlCode;
ULONG InputLength,OutputLength;
TCHAR OutMsg[] = "Message send by driver";
PVOID buffer;
IrpStack = IoGetCurrentIrpStackLocation(Irp); ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

buffer = Irp->AssociatedIrp.SystemBuffer;

switch (ControlCode)
{
case IOCTL_EVENT_MSG:
break;
}
status = Irp->IoStatus.Status;

IoCompleteRequest(Irp, 0);
return status;
}

VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING nameString;

RtlInitUnicodeString(&nameString, L"\\??\\MyDriver");
IoDeleteSymbolicLink(&nameString);
IoDeleteDevice(pDriverObject->DeviceObject);
//UnHook
__asm{
mov eax, cr0
mov CR0VALUE, eax
and eax, 0fffeffffh //DisableWriteProtect
mov cr0, eax
}
(REALZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile))= RealZwOpenFile;
__asm
{
mov eax, CR0VALUE
mov cr0, eax
}

return;
}

//钩子函数

NTSTATUS
HookZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
)
{
NTSTATUS rc = 0;
char aProcessName[MAXPATHLEN];
ZeroMemory(aProcessName,MAXPATHLEN);
do
{
if(GetProcessName2(aProcessName)==FALSE) break;
if(ObjectAttributes->ObjectName->Length>=11)
{
if(!memcmp(ObjectAttributes->ObjectName->Buffer, L"\\??\\C:\\cccc",22))
{
DbgPrint("Current Process Full Path Name: %s\n",aProcessName);
DbgPrint("ZwOpenFile ObjectAttributes->ObjectName=%ws\n",ObjectAttributes->ObjectName->Buffer);
return STATUS_UNSUCCESSFUL;
}
}
}while(0);

//调用原函数
rc=(NTSTATUS)RealZwOpenFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
ShareAccess,
OpenOptions
);
return rc;
}
chenhao1988 2009-05-23
  • 打赏
  • 举报
回复
我把程序贴出来,希望能有人帮忙解决一下,非常感谢!!!
#include <ntddk.h>
#include <string.h>
#include <ntstrsafe.h>
#include <wchar.h>
#define IOCTL_EVENT_MSG (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x927, METHOD_BUFFERED , FILE_ANY_ACCESS)
#define MAXPATHLEN 260
ULONG CR0VALUE;
#pragma pack(1)
typedef struct _ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
#pragma pack()
_declspec(dllimport) ServiceDescriptorTableEntry KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
//
typedef enum WIN_VER_DETAIL {
WINDOWS_VERSION_NONE, // 0
WINDOWS_VERSION_2K,
WINDOWS_VERSION_XP, //我自己的电脑类型
WINDOWS_VERSION_2K3,
WINDOWS_VERSION_2K3_SP1_SP2,
WINDOWS_VERSION_VISTA,
} WIN_VER_DETAIL;

WIN_VER_DETAIL yourWinVer;
typedef NTSTATUS (NTAPI * PFN_RtlGetVersion)(OUT PRTL_OSVERSIONINFOW lpVersionInformation);

void ZeroMemory(PCHAR theName,ULONG Name_SIZE)
{
ULONG i;
for (i = 0; i < Name_SIZE; i++)
{
theName[i]=0x00;
}
}

WIN_VER_DETAIL GetWindowsVersion()
{
UNICODE_STRING ustrFuncName = { 0 };
RTL_OSVERSIONINFOEXW osverinfo = { sizeof(osverinfo) };
PFN_RtlGetVersion pfnRtlGetVersion = NULL;

RtlInitUnicodeString(&ustrFuncName, L"RtlGetVersion");
pfnRtlGetVersion = MmGetSystemRoutineAddress(&ustrFuncName);

if (pfnRtlGetVersion)
{
pfnRtlGetVersion((PRTL_OSVERSIONINFOW)&osverinfo);
}
else
{
PsGetVersion(&osverinfo.dwMajorVersion, &osverinfo.dwMinorVersion, &osverinfo.dwBuildNumber, NULL);
}

if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0) {
return WINDOWS_VERSION_2K;
} else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1) {
return WINDOWS_VERSION_XP;
} else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2) {
if (osverinfo.wServicePackMajor==0) {
return WINDOWS_VERSION_2K3;
} else {
return WINDOWS_VERSION_2K3_SP1_SP2;
}
} else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0) {
return WINDOWS_VERSION_VISTA;
}

return WINDOWS_VERSION_NONE;
}

int ConvertFileNameWCHARToCHAR(PWCHAR pWChar, PCHAR pChar)
{
UNICODE_STRING usFileName;
ANSI_STRING asFileName;

RtlInitUnicodeString(&usFileName, pWChar);

asFileName.Length = 0;
asFileName.MaximumLength = 260;
asFileName.Buffer = pChar;

RtlUnicodeStringToAnsiString(&asFileName, &usFileName, FALSE);
pChar[asFileName.Length] = 0x00;
return asFileName.Length;
}
//取当前进程路径
LONG GetProcessName2( PCHAR theName )
{
ULONG i;
ULONG dwAddress = (ULONG)PsGetCurrentProcess();

if(dwAddress == 0 || dwAddress == 0xFFFFFFFF)
return FALSE;

if (yourWinVer==WINDOWS_VERSION_2K3)
{
dwAddress += 0x190;
}
else
{
if (yourWinVer==WINDOWS_VERSION_2K3_SP1_SP2)
{
dwAddress += 0x1A0;
}
else
{
if (yourWinVer==WINDOWS_VERSION_VISTA)
{
dwAddress += 0x188;
}
else
{
dwAddress += 0x1B0;
}
}
}
if((dwAddress = *(ULONG*)dwAddress) == 0) return FALSE;
dwAddress += 0x10;
if((dwAddress = *(ULONG*)dwAddress) == 0) return FALSE;
dwAddress += 0x3C;
if((dwAddress = *(ULONG*)dwAddress) == 0) return FALSE;
ConvertFileNameWCHARToCHAR((PWCHAR)dwAddress,theName);
return TRUE;
}
//函数原型的声明
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
);
//声明函数指针类型
typedef NTSTATUS (*REALZWOPENFILE)
(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
);
NTSTATUS
HookZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
);
REALZWOPENFILE RealZwOpenFile;

NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
static NTSTATUS MydrvDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);



chenhao1988 2009-05-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 Purpleendurer 的回复:]
asFileName.MaximumLength = 256;

char aProcessName[MAXPATHLEN];

如果MAXPATHLEN=256的话,最好再加大一些,比如


asFileName.MaximumLength = MAXPATHLEN * 2;

char aProcessName[MAXPATHLEN * 2];
[/Quote]
谢谢三楼!
改了长度,但是不管用,应该不是字符串长度的问题,又发现了一些的问题:同一路径下,打开文件夹偶尔没有问题,打开具体的文件就肯定出蓝屏。


只调用GetCurrentProcessFileName(),不会发生任何问题。
紫郢剑侠 2009-05-21
  • 打赏
  • 举报
回复
asFileName.MaximumLength = 256;

char aProcessName[MAXPATHLEN];

如果MAXPATHLEN=256的话,最好再加大一些,比如



asFileName.MaximumLength = MAXPATHLEN * 2;

char aProcessName[MAXPATHLEN * 2];
fiveofhearts 2009-05-21
  • 打赏
  • 举报
回复
我的一个转换函数,你自己改改。

int UnicodeStringToPChar(UNICODE_STRING UnicodeString, char* PChar)
{
ANSI_STRING akeyname;
int nLen = 0;

RtlUnicodeStringToAnsiString( &akeyname, &UnicodeString, TRUE );
if(akeyname.Length < 260)
{
memcpy(PChar,akeyname.Buffer,akeyname.Length);
PChar[akeyname.Length]=0x00;
nLen = akeyname.Length;
}
else
{
memcpy(PChar,akeyname.Buffer,260);
PChar[260-1]=0x00;
nLen = 260-1;
}
RtlFreeAnsiString( &akeyname );
return nLen;
}
supercow 2009-05-21
  • 打赏
  • 举报
回复
你看起来 不像好人.

9,506

社区成员

发帖
与我相关
我的任务
社区描述
Windows专区 安全技术/病毒
社区管理员
  • 安全技术/病毒社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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