Code:
//======================native.c v2====================================
/*****************What it can do and cannot ****************************
1. It fails to set the system time to new time with NtSetSystemTime().
2. It creates c:\time.txt but fails to write the old time with NtWriteFile().
Tested: It can be successfully compiled using
Windows Server 2003 SP1 DDK on WINDOWS XP SP3>>
Build Environments >> Win XP Checked (free) Build Environment
***********************************************************************/
#include "ntddk.h"
#include "stdio.h"
NTSTATUS NTAPI NtDisplayString(PUNICODE_STRING String);
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus);
// SystemTime [out]: A pointer to a LARGE_INTEGER structure
// that receives the system time.
// This value means number of 100-nanosecond units since 1600, 1 January.
// Time is incremented 10.000.000 times per second.,i.e 1s=10.000.000
NTSTATUS NTAPI NtQuerySystemTime(
OUT PLARGE_INTEGER SystemTime);
/* NtSetSystemTime() is similar to NtQuerySystemTime()
STATUS_SUCCESS is returned if the service is successfully executed.
STATUS_PRIVILEGE_NOT_HELD is returned if the caller does not have the privilege
to set the system time.
STATUS_ACCESS_VIOLATION is returned if the input parameter for the system time
cannot be read or the output parameter for the system time cannot be written.
STATUS_INVALID_PARAMETER is returned if the input system time is negative.
SeSystemtimePrivilege is required to set the system time!!!
*/
NTSTATUS NTAPI NtSetSystemTime(
IN PLARGE_INTEGER SystemTime,
OUT PLARGE_INTEGER PreviousTime);
// converts 64-bit time to user-readable structure TIME_FIELDS.
NTSYSAPI VOID NTAPI RtlTimeToTimeFields(
IN PLARGE_INTEGER Time,
OUT PTIME_FIELDS TimeFields);
// converts user-readable structure TIME_FIELDS to 64-bit integer
NTSYSAPI BOOLEAN NTAPI RtlTimeFieldsToTime(
IN PTIME_FIELDS TimeFields,
OUT PLARGE_INTEGER Time);
NTSTATUS NTAPI NtCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer,
IN ULONG EaLength);
NTSTATUS NTAPI NtWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine,
IN PVOID ApcContext,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset,
IN PULONG Key);
NTSYSAPI NTSTATUS NTAPI NtClose(
IN HANDLE Handle);
// Store the current time
LARGE_INTEGER MySystemTime;
// The time to be set
LARGE_INTEGER MySystemTimeNew;
// The time (=MySystemTime) before being set to MySystemTimeNew
LARGE_INTEGER MySystemTimeOld;
//
TIME_FIELDS TimeFields;
TIME_FIELDS MyTimeFields;
TIME_FIELDS MyTimeFieldsOld;
/* when included, error "'struct' type redefinition"
typedef struct _TIME_FIELDS {
USHORT Year;
USHORT Month;
USHORT Day;
USHORT Hour;
USHORT Minute;
USHORT Second;
USHORT Milliseconds;
USHORT Weekday;
} TIME_FIELDS, *PTIME_FIELDS;
*/
UNICODE_STRING wszPath;
UNICODE_STRING ErrorMonitor;
NTSTATUS Status;
HANDLE hFile;
OBJECT_ATTRIBUTES objAttr;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER FilePos;
CHAR *strMessage=NULL;
void NtProcessStartup(PPEB ppeb)
{
//get the current system time
Status = NtQuerySystemTime(&MySystemTime);
if (!NT_SUCCESS(Status)) // not succesful
{
//just to check if NtQuerySystemTime() worked.
RtlInitUnicodeString(&ErrorMonitor,L"Failed to get system time!\n");
NtDisplayString(&ErrorMonitor);
}
else // succesful
{
//just to show something on the screen. these two lines can be removed.
RtlInitUnicodeString(&ErrorMonitor,L"Got system time successfully!\n");
NtDisplayString(&ErrorMonitor);
// converts 64-bit time to user-readable structure TIME_FIELDS.
RtlTimeToTimeFields(&MySystemTime,&MyTimeFields);
// *************The time (31/12/2009) to be set***************
// better to take Argument like "native.exe 31/12/2009"
// but I do not know how to do it. So I use this way:
MyTimeFields.Year=2009;
MyTimeFields.Month=12;
MyTimeFields.Day=31;
//converts user-readable structure TIME_FIELDS to 64-bit integer
RtlTimeFieldsToTime(&MyTimeFields,&MySystemTimeNew);
// set new time and the old time is in MySystemTimeOld
// but testing showed the time was not set to 31/12/2009!!!
//NtSetSystemTime(&MySystemTimeNew,NULL);
Status = NtSetSystemTime(&MySystemTimeNew,&MySystemTimeOld);
if (!NT_SUCCESS(Status)) // not succesful
{
//just to check if NtSetSystemTime() worked.
RtlInitUnicodeString(&ErrorMonitor,L"Failed to set system time!\n");
NtDisplayString(&ErrorMonitor);
}
else // succesful
{
//just to check if NtSetSystemTime() worked.
RtlInitUnicodeString(&ErrorMonitor,L"System time has been set successfully!\n");
NtDisplayString(&ErrorMonitor);
// converts 64-bit time to user-readable structure TIME_FIELDS.
RtlTimeToTimeFields(&MySystemTimeOld,&MyTimeFieldsOld);
// The old time in MyTimeFieldsOld is written into c:\time.txt
RtlInitUnicodeString(&wszPath, L"\\??\\c:\\Time.txt");
InitializeObjectAttributes(&objAttr, &wszPath, OBJ_OPENIF, NULL, NULL);
NtCreateFile(&hFile, FILE_GENERIC_WRITE, &objAttr, &IoStatusBlock,0,
FILE_ATTRIBUTE_NORMAL,FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
FILE_RANDOM_ACCESS|FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0);
/* The following was modified from codes found
@ http://software.itags.org/software-application/4470/
it means to formt strMessage from MyTimeFieldsOld,
but ExAllocatePool (or ExAllocatePoolWithTag) returned an error
NtQuerySystemTime(&MySystemTime);
RtlTimeToTimeFields(&MySystemTime,&TimeFields);
strMessage = (CHAR *)ExAllocatePoolWithTag( NonPagedPool, 99 * sizeof(CHAR),'1gaT');
RtlZeroMemory( strMessage, 99 * sizeof(CHAR));
sprintf(strMessage, "%4d-%02d-%02d %02d:%02d:%02d\t%s\r\n",
TimeFields.Year,
TimeFields.Month,
TimeFields.Day,
TimeFields.Hour,
TimeFields.Minute,
TimeFields.Second,
"0123456789"
);
*/
//use this to test NtWriteFile()
strMessage = "Testing string for NtWriteFile";
// write the old time into the Time.txt file.
// but testing showed nothing was written to the file !!!!
NtWriteFile(hFile, NULL, NULL, NULL, &IoStatusBlock,
strMessage,strlen(strMessage), &FilePos, NULL);
//just to show something on the screen. these two lines can be removed.
//RtlInitUnicodeString(&helloWorld,L"Hello World!\n");
//NtDisplayString(&helloWorld);
}
}
NtClose(&hFile);
//Terminate
NtTerminateProcess( NtCurrentProcess(), 0 );
}
//===========================end======================================