#include "stdafx.h"
#define MAX_PROC_NAME_LEN 256
//
// Enable log event: for synchronization
//
static KEVENT gs_eventEnableKeLog;
static ULONG ProcessNameOffset = 0;
static ULONG GetProcessNameOffset(VOID)
{
PEPROCESS curproc;
int i;
curproc = PsGetCurrentProcess();
//
// Scan for 12KB, hopping the KPEB never grows that big!
//
for (i = 0; i < 3 * PAGE_SIZE; i++)
{
if (!strncmp("System", (PCHAR)curproc + i, strlen("System")))
{
return i;
}
}
//
// Name not found - oh, well
//
return 0;
}
//---------------------------------------------------------
//
// initialize the ProcessNameOffset when the driver is loading.
// (Call in DriverEntry())
//
NTSTATUS ProcessInfo_LoadInit()
{
ProcessNameOffset = GetProcessNameOffset();
return STATUS_SUCCESS;
}
//---------------------------------------------------------
//
// initialization interface
//
//---------------------------------------------------------
//
// initialize the global data structures, when the driver is loading.
// (Call in DriverEntry())
NTSTATUS Dbg_LoadInit()
{
// Initialize the event
KeInitializeEvent(&gs_eventEnableKeLog, SynchronizationEvent, TRUE);
ProcessInfo_LoadInit();
return STATUS_SUCCESS;
}
static void WaitForWriteMutex()
{
// Wait for enable log event
KeWaitForSingleObject(&gs_eventEnableKeLog, Executive, KernelMode, TRUE, 0);
KeClearEvent(&gs_eventEnableKeLog);
}
static void ReleaseWriteMutex()
{
// Set enable log event
KeSetEvent(&gs_eventEnableKeLog, 0, FALSE);
}
//----------------------------------------------------------------------
//
// GetCurrentTimeString
//
// Get current time string. (format: %d-%02d-%02d %02d:%02d:%02d)
//
//----------------------------------------------------------------------
static PCHAR GetCurrentTimeString()
{
static CHAR szTime[128];
LARGE_INTEGER SystemTime;
LARGE_INTEGER LocalTime;
TIME_FIELDS timeFiled;
KeQuerySystemTime(&SystemTime);
ExSystemTimeToLocalTime(&SystemTime, &LocalTime);
RtlTimeToTimeFields(&LocalTime, &timeFiled);
sprintf(szTime, "%d-%02d-%02d %02d:%02d:%02d", timeFiled.Year, timeFiled.Month, timeFiled.Day, timeFiled.Hour, timeFiled.Minute, timeFiled.Second);
return szTime;
}
//----------------------------------------------------------------------
//
// GetCurrentProcessName
//
// Uses undocumented data structure offsets to obtain the name of the
// currently executing process.
//
//----------------------------------------------------------------------
static PCHAR GetCurrentProcessName()
{
PEPROCESS curproc;
char *nameptr;
ULONG i;
static CHAR szName[MAX_PROC_NAME_LEN];
//
// We only try and get the name if we located the name offset
//
if (ProcessNameOffset)
{
//
// Get a pointer to the current process block
//
curproc = PsGetCurrentProcess();
//
// Dig into it to extract the name. Make sure to leave enough room
// in the buffer for the appended process ID.
//
nameptr = (PCHAR)curproc + ProcessNameOffset;
strncpy(szName, nameptr, MAX_PROC_NAME_LEN - 1);
szName[MAX_PROC_NAME_LEN - 1] = 0;
/* for 64 bit system
#if defined(_M_IA64)
sprintf( szName + strlen(szName), ":%I64d", PsGetCurrentProcessId());
#else
sprintf( szName + strlen(szName), ":%d", (ULONG) PsGetCurrentProcessId());
#endif
//*/
}
else
{
strcpy(szName, "???");
}
return szName;
}
//----------------------------------------------------------------------
//
// DbgKeLog
//
// Trace to file.
//
//----------------------------------------------------------------------
BOOLEAN DbgKeLog(const char *lpszLog, ...)
{
L_INFO("===========DbgKeLog=========%s\n",lpszLog);
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
{
KdPrint(("TKeHook: KeLog: IRQL too hight.../n"));
return FALSE;
}
WaitForWriteMutex();
__try
{
IO_STATUS_BLOCK IoStatus;
OBJECT_ATTRIBUTES objectAttributes;
NTSTATUS status;
HANDLE FileHandle;
UNICODE_STRING fileName;
static WCHAR s_szLogFile[] = L"\\??\\D:\\1.LOG";
LPCWSTR lpszLogFile = s_szLogFile;
PAGED_CODE();
if (lpszLogFile == NULL)
lpszLogFile = s_szLogFile;
//get a handle to the log file object
fileName.Buffer = NULL;
fileName.Length = 0;
fileName.MaximumLength = (wcslen(lpszLogFile) + 1) * sizeof(WCHAR);
fileName.Buffer = (PWCHAR)ExAllocatePool(PagedPool, fileName.MaximumLength);
if (!fileName.Buffer)
{
ReleaseWriteMutex();
KdPrint(("TKeHook: KeLog: ExAllocatePool Failed.../n"));
return FALSE;
}
RtlZeroMemory(fileName.Buffer, fileName.MaximumLength);
status = RtlAppendUnicodeToString(&fileName, (PWSTR)lpszLogFile);
InitializeObjectAttributes(&objectAttributes,
(PUNICODE_STRING)&fileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = ZwCreateFile(&FileHandle,
FILE_APPEND_DATA,
&objectAttributes,
&IoStatus,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(status))
{
static CHAR szBuffer[1024];
PCHAR pszBuffer = szBuffer;
ULONG ulBufSize;
int nSize;
va_list pArglist;
// add process name and time string
sprintf(szBuffer, "[%s][%16s:%d] ", GetCurrentTimeString(), GetCurrentProcessName(), (ULONG)PsGetCurrentProcessId());
pszBuffer = szBuffer + strlen(szBuffer);
va_start(pArglist, lpszLog);
// The last argument to wvsprintf points to the arguments
nSize = _vsnprintf(pszBuffer, 1024 - 32, lpszLog, pArglist);
// The va_end macro just zeroes out pArgList for no good reason
va_end(pArglist);
if (nSize > 0)
{
pszBuffer[nSize] = 0;
}
else
{
pszBuffer[0] = 0;
}
ulBufSize = strlen(szBuffer);
ZwWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatus,
szBuffer,
ulBufSize,
NULL,
NULL);
ZwClose(FileHandle);
}
if (fileName.Buffer)
ExFreePool(fileName.Buffer);
ReleaseWriteMutex();
return TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
ReleaseWriteMutex();
KdPrint(("TKeHook: DbgKeLog() except: %0xd !!/n", GetExceptionCode()));
return FALSE;
}
}
NTSTATUS
CreateFileTest(IN PUNICODE_STRING nFilePath)
{
HANDLE lhFile = NULL;
NTSTATUS lstatus;
IO_STATUS_BLOCK Io_Status_Block;
CHAR *Content;
//init filepath
OBJECT_ATTRIBUTES obj_attrib;
do
{
InitializeObjectAttributes(&obj_attrib,nFilePath,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
NULL,NULL);
//create file
lstatus = ZwCreateFile(&lhFile,GENERIC_ALL,&obj_attrib,&Io_Status_Block,NULL,
FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,
FILE_OPEN_IF,FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT,
NULL,0);
if (!NT_SUCCESS(lstatus))
{
L_INFO("ZwCreateFile faile \n");
lstatus = Io_Status_Block.Status;
break;
}
Content = "这是要写入的数据";
lstatus = ZwWriteFile( lhFile,
NULL,
NULL,
NULL,
&Io_Status_Block,
Content,
strlen(Content),
NULL,
NULL);
if( !NT_SUCCESS( lstatus ) )
{
L_INFO("ZwWriteFile faile \n");
lstatus = Io_Status_Block.Status;
}
lstatus = STATUS_SUCCESS;
} while (FALSE);
if (lhFile)
{
ZwClose(lhFile);
}
return lstatus;
}
void DbgTest()
{
NTSTATUS lstatus;
UNICODE_STRING lstrFilePath;
RtlInitUnicodeString(&lstrFilePath,L"\\??\\D:\\a.txt");
lstatus = CreateFileTest(&lstrFilePath);
if (NT_SUCCESS(lstatus))
{
KdPrint(("Createfile Success!\n"));
}
else
{
KdPrint((" Createfile Error(%08x)!\n",lstatus));
}
}