Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Kernel Mode Driver and Registry Access

Posted on 2009-02-14
34
Medium Priority
?
3,295 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
0
Comment
Question by:Mortaza Doulaty
  • 17
  • 17
34 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 23641437
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

0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 23641447
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
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23643789
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) {
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 23645958
Seems that the definition of DWORD is missing - are you using the appropriate header file?
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23648338
I'm including ntddk.h library.
0
 
LVL 86

Expert Comment

by:jkr
ID: 23651713
Are you also includeing 'wtypes.h'? A simple test should help, just add

typedef unsigned long DWORD;

at the top of the file.
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23656930
I'm not including 'wtypes.h' in include section, but
typedef unsigned long DWORD;
compiled successfully.
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23656964
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.
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23656975
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
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 23660677
Hmm, seems that both HANDLE and BOOL are still undefined... try

typedef int BOOL;
typedef void *HANDLE;
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23704152
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
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 23724316
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

0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23828502
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
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 23839515
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

0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23844964
>>you should link with 'msvcrt.lib'
How can this be done?
0
 
LVL 86

Expert Comment

by:jkr
ID: 23850435
Try to add

TARGETLIBS=$(DDK_LIB_PATH)\msvcrt.lib

to your 'sources'
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23854246
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
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 23862024
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

0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23865173
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));

0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 23874743
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

0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23896542
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?
0
 
LVL 86

Expert Comment

by:jkr
ID: 23902971
Well, what error(s) do you get?
0
 
LVL 86

Expert Comment

by:jkr
ID: 23902978
Oh, and be sure that the registry key exists ;o)
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23905003
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.
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23905013
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?
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 23932655
>>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

0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 23977690
There should be some problem with DrvLoad() too.

It always returns f9e47438.
0
 
LVL 86

Expert Comment

by:jkr
ID: 23995053
You mean the DWORD value or the return value?
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 24007635
The value of pdwVal after DrvLoad() completes.
(I mean the DWORD value)
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 24007665
Just to mention, DrvLoad() returns FALSE.
0
 
LVL 86

Expert Comment

by:jkr
ID: 24034021
Well, when that function returns FALSE, something went wrong - probably 'DrvOpenKey()'. Can you check the values of 'ntStatus' after the 'Zw*()' calls?
0
 
LVL 12

Author Comment

by:Mortaza Doulaty
ID: 24036661
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.
0
 
LVL 86

Expert Comment

by:jkr
ID: 24082028
OK, let me double chekc that...
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 2000 total points
ID: 24111731
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

0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

576 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question