We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

Kernel Mode Driver and Registry Access

Mortaza Doulaty
on
Medium Priority
3,442 Views
Last Modified: 2012-05-06
I've an existing kernel mode driver. I want to count the number of times it is being loaded and save it some where in the registry.

I've already read many pages from the DDK's help about using ZwXXX and RtlXXX functions, but as my background knowledge is very poor about kernel mode drivers, and I need to do this as soon as possible, I need two things:

1) A piece of code to help me solve this problem.
2) A good book to start learning about kernel mode drivers. (Assume that I know nothing!)

Any help would be highly appreciated.k
Comment
Watch Question

CERTIFIED EXPERT
Top Expert 2012
Commented:
Basically, you could do it using the following:
HANDLE
DrvOpenKey () const {
 
	NTSTATUS ntStatus;
 
	WCHAR awcBaseKey [] = L"\\Registry\\Machine\\SOFTWARE\\Company\\Product";
	WCHAR awcKey []	= L"LoadCounter";
	UNICODE_STRING KeyName;
	HANDLE hBaseKey = NULL;
	HANDLE hKey = NULL;
 
	OBJECT_ATTRIBUTES oa;
	ULONG ulDisposition;
 
	KeyName.Buffer = awcBaseKey;
	KeyName.Length = (USHORT) wcslen (awcBaseKey) * sizeof (WCHAR);
 
	InitializeObjectAttributes(&oa, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
 
	ntStatus = ZwCreateKey(&hBaseKey, KEY_ALL_ACCESS, &oa, 0,  NULL, REG_OPTION_NON_VOLATILE, &ulDisposition);
 
	if(!NT_SUCCESS (ntStatus )) {
 
		return NULL;
	}
 
	return hKey;
}
 
BOOL
DrvLoad (DWORD* pdwVal) {
 
	BOOL bRet = FALSE;
 
	WCHAR awcValue[]	= L"LoadCount";
	UNICODE_STRING ValueName;
	HANDLE hKey = NULL;
	NTSTATUS ntStatus;
 
	KEY_VALUE_PARTIAL_INFORMATION* pkvi = NULL;
 
	if (!(hKey = DrvOpenKey ())) return FALSE;
 
	__try {
 
		//
		// Create the storage value
		//
		ValueName.Buffer = awcValue;
		ValueName.Length = (USHORT) (wcslen (awcValue) + 1) * sizeof (WCHAR);
		ULONG ulNeeded;
 
		size_t szkvi = sizeof (KEY_VALUE_PARTIAL_INFORMATION);
		pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) new BYTE [ szkvi];
 
		ZeroMemory (pkvi, sizeof (KEY_VALUE_PARTIAL_INFORMATION));
		pkvi->Type = REG_DWORD;
 
		// Query necessary size first
		ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
		//
		//	Has not been saved yet
		//
		if (STATUS_OBJECT_NAME_NOT_FOUND == ntStatus) {
 
			__leave;
		}
 
		if (ntStatus != STATUS_BUFFER_TOO_SMALL && ntStatus != STATUS_BUFFER_OVERFLOW) {
 
			__leave;
		}
 
		delete [] pkvi;
		szkvi = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + ulNeeded;
		pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) new BYTE [ szkvi];
		ZeroMemory (pkvi, szkvi);
		pkvi->Type = REG_DWORD;
 
		// Finally, read value
		ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
		if(!NT_SUCCESS (ntStatus )) {
 
 
			__leave;
		}
 
		*pdwVal = (DWORD) pkvi->Data;
 
	} __finally {
 
		delete [] pkvi;
 
		ZwClose (hKey);
	}
 
	return bRet;
}
 
BOOL
DrvSave (DWORD dwVal) {
 
        BOOL bRet = FALSE;
 
	WCHAR awcValue []	= L"LoadCount";
	UNICODE_STRING ValueName;
	HANDLE hKey = NULL;
	NTSTATUS ntStatus;
 
	if (!(hKey = DrvOpenKey ())) return FALSE;
 
	__try {
 
		// Create the storage value
		ValueName.Buffer = awcValue;
		ValueName.Length = (USHORT) (wcslen (awcValue)) * sizeof(WCHAR);
 
		ntStatus = ZwSetValueKey (hKey, &ValueName, 0, REG_DWORD, (LPBYTE) &dwVal, sizeof (DWORD));
 
		if(!NT_SUCCESS (ntStatus )) {
 
			__leave;
		}
 
                bRet = TRUE;
 
	} __finally {
 
		ZwClose (hKey);
	}
 
	return bRet;
}

Open in new window

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
BTW, regarding books - I'd rather not recommend a single book, but point you to one IMO more valuable resource: http://www.osronline.com/index.cfm

Author

Commented:
Thanks for your comment.
About the code, when I compiling it with WDK 6000, this error message is displayed:

Compiling - hello.c
errors in directory d:\drivers
d:\drivers\hello.c(131) : error C2143: syntax error : missing ')' before '*'
d:\drivers\hello.c(131) : error C2143: syntax error : missing '{' before '*'
d:\drivers\hello.c(131) : error C2059: syntax error : ')'
d:\drivers\hello.c(131) : error C2054: expected '(' to follow 'pdwVal'
d:\drivers\hello.c(203) : error C2146: syntax error : missing ')' before identif
ier 'dwVal'
d:\drivers\hello.c(203) : error C2061: syntax error : identifier 'dwVal'
d:\drivers\hello.c(203) : error C2059: syntax error : ';'
d:\drivers\hello.c(203) : error C2059: syntax error : ')'
d:\drivers\hello.c(203) : error C2449: found '{' at file scope (missing function
 header?)
d:\drivers\hello.c(235) : error C2059: syntax error : '}'
Linking Executable - objchk_wxp_x86\i386\hello.sys
link : error LNK1181: cannot open input file 'objchk_wxp_x86\i386\hello.obj'
BUILD: Finish time: Sun Feb 15 09:36:35 2009
BUILD: Done

    3 files compiled - 10 Errors
    1 executable built - 1 Error

*******************************************************************

Line 131 is: BOOL DrvLoad (DWORD* pdwVal) {
and line 203 is: BOOL DrvSave (DWORD dwVal) {
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Seems that the definition of DWORD is missing - are you using the appropriate header file?

Author

Commented:
I'm including ntddk.h library.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Are you also includeing 'wtypes.h'? A simple test should help, just add

typedef unsigned long DWORD;

at the top of the file.

Author

Commented:
I'm not including 'wtypes.h' in include section, but
typedef unsigned long DWORD;
compiled successfully.

Author

Commented:
When compiling, there are some errors:

errors in directory d:\driver2
d:\driver2\drv.c(7) : error C2143: syntax error : missing '{' before '<cv-qualif
er>'
d:\driver2\drv.c(7) : error C2059: syntax error : '<Unknown>'
d:\driver2\drv.c(36) : error C2061: syntax error : identifier 'DrvLoad'
d:\driver2\drv.c(36) : error C2059: syntax error : ';'
d:\driver2\drv.c(36) : error C2059: syntax error : 'type'
d:\driver2\drv.c(108) : error C2061: syntax error : identifier 'DrvSave'
d:\driver2\drv.c(108) : error C2059: syntax error : ';'
d:\driver2\drv.c(108) : error C2059: syntax error : 'type'
Linking Executable - objchk_wxp_x86\i386\hello.sys
link : error LNK1181: cannot open input file 'objchk_wxp_x86\i386\drv.obj'

Where line 7,36,108 are the functions declaration.

Author

Commented:
This is my complete code file.
Including "makefile" and "sources" files.

#include <ntddk.h>
//#include <wtypes.h>
 
typedef unsigned long DWORD;
 
HANDLE
DrvOpenKey () const {
 
        NTSTATUS ntStatus;
 
        WCHAR awcBaseKey [] = L"\\Registry\\Machine\\SOFTWARE\\Company\\Product";
        WCHAR awcKey [] = L"LoadCounter";
        UNICODE_STRING KeyName;
        HANDLE hBaseKey = NULL;
        HANDLE hKey = NULL;
 
        OBJECT_ATTRIBUTES oa;
        ULONG ulDisposition;
 
        KeyName.Buffer = awcBaseKey;
        KeyName.Length = (USHORT) wcslen (awcBaseKey) * sizeof (WCHAR);
 
        InitializeObjectAttributes(&oa, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
 
        ntStatus = ZwCreateKey(&hBaseKey, KEY_ALL_ACCESS, &oa, 0,  NULL, REG_OPTION_NON_VOLATILE, &ulDisposition);
 
        if(!NT_SUCCESS (ntStatus )) {
 
                return NULL;
        }
 
        return hKey;
}
 
BOOL
DrvLoad (DWORD* pdwVal) {
 
        BOOL bRet = FALSE;
 
        WCHAR awcValue[]        = L"LoadCount";
        UNICODE_STRING ValueName;
        HANDLE hKey = NULL;
        NTSTATUS ntStatus;
 
        KEY_VALUE_PARTIAL_INFORMATION* pkvi = NULL;
 
        if (!(hKey = DrvOpenKey ())) return FALSE;
 
        __try {
 
                //
                // Create the storage value
                //
                ValueName.Buffer = awcValue;
                ValueName.Length = (USHORT) (wcslen (awcValue) + 1) * sizeof (WCHAR);
                ULONG ulNeeded;
 
                size_t szkvi = sizeof (KEY_VALUE_PARTIAL_INFORMATION);
                pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) new BYTE [ szkvi];
 
                ZeroMemory (pkvi, sizeof (KEY_VALUE_PARTIAL_INFORMATION));
                pkvi->Type = REG_DWORD;
 
                // Query necessary size first
                ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
                //
                //      Has not been saved yet
                //
                if (STATUS_OBJECT_NAME_NOT_FOUND == ntStatus) {
 
                        __leave;
                }
 
                if (ntStatus != STATUS_BUFFER_TOO_SMALL && ntStatus != STATUS_BUFFER_OVERFLOW) {
 
                        __leave;
                }
 
                delete [] pkvi;
                szkvi = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + ulNeeded;
                pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) new BYTE [ szkvi];
                ZeroMemory (pkvi, szkvi);
                pkvi->Type = REG_DWORD;
 
                // Finally, read value
                ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
                if(!NT_SUCCESS (ntStatus )) {
 
 
                        __leave;
                }
 
                *pdwVal = (DWORD) pkvi->Data;
 
        } __finally {
 
                delete [] pkvi;
 
                ZwClose (hKey);
        }
 
        return bRet;
}
 
BOOL
DrvSave (DWORD dwVal) {
 
        BOOL bRet = FALSE;
 
        WCHAR awcValue []       = L"LoadCount";
        UNICODE_STRING ValueName;
        HANDLE hKey = NULL;
        NTSTATUS ntStatus;
 
        if (!(hKey = DrvOpenKey ())) return FALSE;
 
        __try {
 
                // Create the storage value
                ValueName.Buffer = awcValue;
                ValueName.Length = (USHORT) (wcslen (awcValue)) * sizeof(WCHAR);
 
                ntStatus = ZwSetValueKey (hKey, &ValueName, 0, REG_DWORD, (LPBYTE) &dwVal, sizeof (DWORD));
 
                if(!NT_SUCCESS (ntStatus )) {
 
                        __leave;
                }
 
                bRet = TRUE;
 
        } __finally {
 
                ZwClose (hKey);
        }
 
        return bRet;
}
 
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, 
					  IN PUNICODE_STRING theRegistryPath )
{
 
 
 
 
	return STATUS_SUCCESS;
 
}

Open in new window

makefile
sources
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
Hmm, seems that both HANDLE and BOOL are still undefined... try

typedef int BOOL;
typedef void *HANDLE;

Author

Commented:
Sorry for my late reply, still have problems:

Compiling - drv.c
errors in directory d:\driver2
d:\driver2\drv.c(9) : error C2143: syntax error : missing '{' before '<cv-qualif
er>'
d:\driver2\drv.c(9) : error C2059: syntax error : '<Unknown>'
d:\driver2\drv.c(49) : error C4013: 'DrvOpenKey' undefined; assuming extern retu
rning int
d:\driver2\drv.c(58) : error C2275: 'ULONG' : illegal use of this type as an exp
ression
d:\driver2\drv.c(58) : error C2146: syntax error : missing ';' before identifier
 'ulNeeded'
d:\driver2\drv.c(58) : error C2065: 'ulNeeded' : undeclared identifier
d:\driver2\drv.c(60) : error C2275: 'size_t' : illegal use of this type as an ex
pression
d:\driver2\drv.c(60) : error C2146: syntax error : missing ';' before identifier
 'szkvi'
d:\driver2\drv.c(60) : error C2065: 'szkvi' : undeclared identifier
d:\driver2\drv.c(61) : error C2065: 'new' : undeclared identifier
d:\driver2\drv.c(61) : error C2146: syntax error : missing ';' before identifier
 'BYTE'
d:\driver2\drv.c(61) : error C2065: 'BYTE' : undeclared identifier
d:\driver2\drv.c(61) : error C2109: subscript requires array or pointer type
d:\driver2\drv.c(63) : error C4013: 'ZeroMemory' undefined; assuming extern retu
rning int
d:\driver2\drv.c(82) : error C2065: 'delete' : undeclared identifier
d:\driver2\drv.c(82) : error C2059: syntax error : ']'
d:\driver2\drv.c(84) : error C2146: syntax error : missing ';' before identifier
 'BYTE'
d:\driver2\drv.c(84) : error C2109: subscript requires array or pointer type
d:\driver2\drv.c(101) : error C2059: syntax error : ']'
d:\driver2\drv.c(127) : error C2065: 'LPBYTE' : undeclared identifier
Linking Executable - objchk_wxp_x86\i386\hello.sys
link : error LNK1181: cannot open input file 'objchk_wxp_x86\i386\drv.obj'
BUILD: Finish time: Sun Feb 22 13:58:05 2009
BUILD: Done

    3 files compiled - 3 Warnings - 20 Errors
    1 executable built - 1 Error
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
Argh, sorry - remove the 'const' from the function, i.e.
HANDLE
DrvOpenKey () {
 
        NTSTATUS ntStatus;
 
        WCHAR awcBaseKey [] = L"\\Registry\\Machine\\SOFTWARE\\Company\\Product";
        WCHAR awcKey [] = L"LoadCounter";
        UNICODE_STRING KeyName;
        HANDLE hBaseKey = NULL;
        HANDLE hKey = NULL;
 
        OBJECT_ATTRIBUTES oa;
        ULONG ulDisposition;
 
        KeyName.Buffer = awcBaseKey;
        KeyName.Length = (USHORT) wcslen (awcBaseKey) * sizeof (WCHAR);
 
        InitializeObjectAttributes(&oa, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
 
        ntStatus = ZwCreateKey(&hBaseKey, KEY_ALL_ACCESS, &oa, 0,  NULL, REG_OPTION_NON_VOLATILE, &ulDisposition);
 
        if(!NT_SUCCESS (ntStatus )) {
 
                return NULL;
        }
 
        return hKey;
}

Open in new window

Author

Commented:
Hi,

I tried, still some problems:

errors in directory d:\driver
d:\driver\mrt.cpp(67) : error C3861: 'ZeroMemory': identifier not found
d:\driver\mrt.cpp(89) : error C3861: 'ZeroMemory': identifier not found
Linking Executable - objchk_wxp_x86\i386\mrt.sys
link : error LNK1181: cannot open input file 'objchk_wxp_x86\i386\mrt.obj'

I changed ZeroMemory to RtlZeroMemory, and new errors:

errors in directory d:\driver
d:\driver\mrt.obj : error LNK2019: unresolved external symbol "void __cdecl oper
ator delete(void *)" (??3@YAXPAX@Z) referenced in function "int __stdcall DrvLoa
d(unsigned long *)" (?DrvLoad@@YGHPAK@Z)
d:\driver\mrt.obj : error LNK2019: unresolved external symbol "void * __cdecl op
erator new(unsigned int)" (??2@YAPAXI@Z) referenced in function "int __stdcall D
rvLoad(unsigned long *)" (?DrvLoad@@YGHPAK@Z)
d:\driver\bufferoverflowk.lib(gs_support.obj) : error LNK2019: unresolved extern
al symbol _DriverEntry@8 referenced in function _GsDriverEntry@8
d:\driver\objchk_wxp_x86\i386\mrt.sys : error LNK1120: 3 unresolved externals
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
Hm, OK, try th efollowing. Regarding the linker errors, you should link with 'msvcrt.lib' (or msvcrtd.lib when compiling a debug build)
#include <ntddk.h>
//#include <wtypes.h>
 
typedef unsigned long DWORD;
typedef int BOOL;
typedef void *HANDLE;
 
HANDLE
DrvOpenKey () {
 
        NTSTATUS ntStatus;
 
        WCHAR awcBaseKey [] = L"\\Registry\\Machine\\SOFTWARE\\Company\\Product";
        WCHAR awcKey [] = L"LoadCounter";
        UNICODE_STRING KeyName;
        HANDLE hBaseKey = NULL;
        HANDLE hKey = NULL;
 
        OBJECT_ATTRIBUTES oa;
        ULONG ulDisposition;
 
        KeyName.Buffer = awcBaseKey;
        KeyName.Length = (USHORT) wcslen (awcBaseKey) * sizeof (WCHAR);
 
        InitializeObjectAttributes(&oa, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
 
        ntStatus = ZwCreateKey(&hBaseKey, KEY_ALL_ACCESS, &oa, 0,  NULL, REG_OPTION_NON_VOLATILE, &ulDisposition);
 
        if(!NT_SUCCESS (ntStatus )) {
 
                return NULL;
        }
 
        return hKey;
}
 
BOOL
DrvLoad (DWORD* pdwVal) {
 
        BOOL bRet = FALSE;
 
        WCHAR awcValue[]        = L"LoadCount";
        UNICODE_STRING ValueName;
        HANDLE hKey = NULL;
        NTSTATUS ntStatus;
 
        KEY_VALUE_PARTIAL_INFORMATION* pkvi = NULL;
 
        if (!(hKey = DrvOpenKey ())) return FALSE;
 
        __try {
 
                //
                // Create the storage value
                //
                ValueName.Buffer = awcValue;
                ValueName.Length = (USHORT) (wcslen (awcValue) + 1) * sizeof (WCHAR);
                ULONG ulNeeded;
 
                size_t szkvi = sizeof (KEY_VALUE_PARTIAL_INFORMATION);
                pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) new BYTE [ szkvi];
 
                RtlZeroMemory (pkvi, sizeof (KEY_VALUE_PARTIAL_INFORMATION));
                pkvi->Type = REG_DWORD;
 
                // Query necessary size first
                ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
                //
                //      Has not been saved yet
                //
                if (STATUS_OBJECT_NAME_NOT_FOUND == ntStatus) {
 
                        __leave;
                }
 
                if (ntStatus != STATUS_BUFFER_TOO_SMALL && ntStatus != STATUS_BUFFER_OVERFLOW) {
 
                        __leave;
                }
 
                delete [] pkvi;
                szkvi = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + ulNeeded;
                pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) new BYTE [ szkvi];
                RtlZeroMemory (pkvi, szkvi);
                pkvi->Type = REG_DWORD;
 
                // Finally, read value
                ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
                if(!NT_SUCCESS (ntStatus )) {
 
 
                        __leave;
                }
 
                *pdwVal = (DWORD) pkvi->Data;
 
        } __finally {
 
                delete [] pkvi;
 
                ZwClose (hKey);
        }
 
        return bRet;
}
 
BOOL
DrvSave (DWORD dwVal) {
 
        BOOL bRet = FALSE;
 
        WCHAR awcValue []       = L"LoadCount";
        UNICODE_STRING ValueName;
        HANDLE hKey = NULL;
        NTSTATUS ntStatus;
 
        if (!(hKey = DrvOpenKey ())) return FALSE;
 
        __try {
 
                // Create the storage value
                ValueName.Buffer = awcValue;
                ValueName.Length = (USHORT) (wcslen (awcValue)) * sizeof(WCHAR);
 
                ntStatus = ZwSetValueKey (hKey, &ValueName, 0, REG_DWORD, (LPBYTE) &dwVal, sizeof (DWORD));
 
                if(!NT_SUCCESS (ntStatus )) {
 
                        __leave;
                }
 
                bRet = TRUE;
 
        } __finally {
 
                ZwClose (hKey);
        }
 
        return bRet;
}
 
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, 
					  IN PUNICODE_STRING theRegistryPath )
{
 
 
 
 
	return STATUS_SUCCESS;
 
}

Open in new window

Author

Commented:
>>you should link with 'msvcrt.lib'
How can this be done?
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Try to add

TARGETLIBS=$(DDK_LIB_PATH)\msvcrt.lib

to your 'sources'

Author

Commented:
Still some errors:

errors in directory d:\driver
NMAKE : fatal error U1073: don't know how to make 'c:\winddk\6000\lib\wxp\i386\m
svcrt.lib'
nmake.exe /nologo BUILDMSG=Stop. -i BUILD_PASS=PASS2 LINKONLY=1 NOPASS0=1 MAKEDI
R_RELATIVE_TO_BASEDIR= MAKEDIR_LOWERCASE=d:\driver failed - rc = 2
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
OK, let's try to get rid of that in this case:
#include <ntddk.h>
//#include <wtypes.h>
 
typedef unsigned long DWORD;
typedef int BOOL;
typedef void *HANDLE;
 
HANDLE
DrvOpenKey () {
 
        NTSTATUS ntStatus;
 
        WCHAR awcBaseKey [] = L"\\Registry\\Machine\\SOFTWARE\\Company\\Product";
        WCHAR awcKey [] = L"LoadCounter";
        UNICODE_STRING KeyName;
        HANDLE hBaseKey = NULL;
        HANDLE hKey = NULL;
 
        OBJECT_ATTRIBUTES oa;
        ULONG ulDisposition;
 
        KeyName.Buffer = awcBaseKey;
        KeyName.Length = (USHORT) wcslen (awcBaseKey) * sizeof (WCHAR);
 
        InitializeObjectAttributes(&oa, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
 
        ntStatus = ZwCreateKey(&hBaseKey, KEY_ALL_ACCESS, &oa, 0,  NULL, REG_OPTION_NON_VOLATILE, &ulDisposition);
 
        if(!NT_SUCCESS (ntStatus )) {
 
                return NULL;
        }
 
        return hKey;
}
 
BOOL
DrvLoad (DWORD* pdwVal) {
 
        BOOL bRet = FALSE;
 
        WCHAR awcValue[]        = L"LoadCount";
        UNICODE_STRING ValueName;
        HANDLE hKey = NULL;
        NTSTATUS ntStatus;
        char buf[2048];
 
        KEY_VALUE_PARTIAL_INFORMATION* pkvi = NULL;
 
        if (!(hKey = DrvOpenKey ())) return FALSE;
 
        __try {
 
                //
                // Create the storage value
                //
                ValueName.Buffer = awcValue;
                ValueName.Length = (USHORT) (wcslen (awcValue) + 1) * sizeof (WCHAR);
                ULONG ulNeeded;
 
                size_t szkvi = sizeof (buf);
                pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) buf;
 
                RtlZeroMemory (pkvi, sizeof (buf));
                pkvi->Type = REG_DWORD;
 
 
                // Finally, read value
                ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
                if(!NT_SUCCESS (ntStatus )) {
 
 
                        __leave;
                }
 
                *pdwVal = (DWORD) pkvi->Data;
 
        } __finally {
 
 
                ZwClose (hKey);
        }
 
        return bRet;
}
 
BOOL
DrvSave (DWORD dwVal) {
 
        BOOL bRet = FALSE;
 
        WCHAR awcValue []       = L"LoadCount";
        UNICODE_STRING ValueName;
        HANDLE hKey = NULL;
        NTSTATUS ntStatus;
 
        if (!(hKey = DrvOpenKey ())) return FALSE;
 
        __try {
 
                // Create the storage value
                ValueName.Buffer = awcValue;
                ValueName.Length = (USHORT) (wcslen (awcValue)) * sizeof(WCHAR);
 
                ntStatus = ZwSetValueKey (hKey, &ValueName, 0, REG_DWORD, (LPBYTE) &dwVal, sizeof (DWORD));
 
                if(!NT_SUCCESS (ntStatus )) {
 
                        __leave;
                }
 
                bRet = TRUE;
 
        } __finally {
 
                ZwClose (hKey);
        }
 
        return bRet;
}
 
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, 
					  IN PUNICODE_STRING theRegistryPath )
{
 
 
 
 
	return STATUS_SUCCESS;
 
}

Open in new window

Author

Commented:
Still having errors:

errors in directory d:\driver
d:\driver\bufferoverflowk.lib(gs_support.obj) : error LNK2019: unresolved extern
al symbol _DriverEntry@8 referenced in function _GsDriverEntry@8
d:\driver\objchk_wxp_x86\i386\mrt.sys : error LNK1120: 1 unresolved externals



(Notice that in line 106, I changed LPBYTE to PVOID)

ntStatus = ZwSetValueKey (hKey, &ValueName, 0, REG_DWORD, (PVOID) &dwVal, sizeof (DWORD));

jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
Hm, you have a 'DriverEntry()' function - does your file have a .cpp suffix? If so, try
exteren "C" 
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, 
					  IN PUNICODE_STRING theRegistryPath )
{
 
 
 
 
	return STATUS_SUCCESS;
 
}

Open in new window

Author

Commented:
The file's extension was CPP, I added
extern "C"
it compiled.

This is my DriverEntry() function,

    DWORD mrt;
    mrt=0;
    DrvLoad (&mrt);
    mrt++;
    DrvSave(mrt);

This should do what I desired, but it is not working.

What could be the problem?
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Well, what error(s) do you get?
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Oh, and be sure that the registry key exists ;o)

Author

Commented:
I've already created a DWORD type named: LoadCounter in HKEY_LOCAL_MACHINE\SOFTWARE\Company\Product

But it's value is not changing when I load the driver.

Author

Commented:
Have a look at
DrvOpenKey()
It returns a HANDLE, named hKey. hKey is initialized with NULL value and never assigned any other value to it not used in other function, and just returned the NULL value, is this the problem with your code?
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
>>hKey is initialized with NULL value and never assigned any other value

Aaah, good eye - probably an editing error on my side (had to modify that from an existing project, try
HANDLE
DrvOpenKey () {
 
        NTSTATUS ntStatus;
 
        WCHAR awcKey [] = L"\\Registry\\Machine\\SOFTWARE\\Company\\Product";
        UNICODE_STRING KeyName;
        HANDLE hKey = NULL;
 
        OBJECT_ATTRIBUTES oa;
        ULONG ulDisposition;
 
        KeyName.Buffer = awcKey;
        KeyName.Length = (USHORT) wcslen (awcKey) * sizeof (WCHAR);
 
        InitializeObjectAttributes(&oa, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
 
        ntStatus = ZwCreateKey(&hKey, KEY_ALL_ACCESS, &oa, 0,  NULL, REG_OPTION_NON_VOLATILE, &ulDisposition); // <---------
 
        if(!NT_SUCCESS (ntStatus )) {
 
                return NULL;
        }
 
        return hKey;
}

Open in new window

Author

Commented:
There should be some problem with DrvLoad() too.

It always returns f9e47438.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
You mean the DWORD value or the return value?

Author

Commented:
The value of pdwVal after DrvLoad() completes.
(I mean the DWORD value)

Author

Commented:
Just to mention, DrvLoad() returns FALSE.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Well, when that function returns FALSE, something went wrong - probably 'DrvOpenKey()'. Can you check the values of 'ntStatus' after the 'Zw*()' calls?

Author

Commented:
If you have a look at DrvLoad(), the return value, bRet first initialized with FALSE, then never assigned a new value. So it always returns FALSE.
This is one problem with that function, there should be some other problems too. (after *pdwVal = (DWORD) pkvi->Data;
I put bRet = TRUE.
The DWORD value is not correct.

About DrvOpenKey() it works well,  used it with DrvSaveKey(), it worked and saved any value I passed to it.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
OK, let me double chekc that...
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
Ah, I think I got it, the problem seems to be

                ValueName.Length = (USHORT) (wcslen (awcValue) + 1) * sizeof (WCHAR);

which should be

                ValueName.Length = (USHORT) wcslen (awcValue)  * sizeof (WCHAR);

Try th efollowing
BOOL
DrvLoad (DWORD* pdwVal) {
 
        BOOL bRet = FALSE;
 
        WCHAR awcValue[]        = L"LoadCount";
        UNICODE_STRING ValueName;
        HANDLE hKey = NULL;
        NTSTATUS ntStatus;
        char buf[2048];
 
        KEY_VALUE_PARTIAL_INFORMATION* pkvi = NULL;
 
        if (!(hKey = DrvOpenKey ())) return FALSE;
 
        __try {
 
                //
                // Create the storage value
                //
                ValueName.Buffer = awcValue;
                ValueName.Length = (USHORT) wcslen (awcValue) * sizeof (WCHAR);
                ULONG ulNeeded;
 
                size_t szkvi = sizeof (buf);
                pkvi = (KEY_VALUE_PARTIAL_INFORMATION*) buf;
 
                RtlZeroMemory (pkvi, sizeof (buf));
                pkvi->Type = REG_DWORD;
 
 
                // Finally, read value
                ntStatus = ZwQueryValueKey (hKey, &ValueName, KeyValuePartialInformation, pkvi, (ULONG) szkvi, &ulNeeded);
 
                if(!NT_SUCCESS (ntStatus )) {
 
 
                        __leave;
                }
 
                *pdwVal = (DWORD) pkvi->Data;
 
                bRet = TRUE;
 
        } __finally {
 
 
                ZwClose (hKey);
        }
 
        return bRet;
}

Open in new window

Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.