Link to home
Start Free TrialLog in
Avatar of Mortaza Doulaty
Mortaza DoulatyFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Kernel Mode Driver and Registry Access

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
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Mortaza Doulaty

ASKER

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) {
Seems that the definition of DWORD is missing - are you using the appropriate header file?
I'm including ntddk.h library.
Are you also includeing 'wtypes.h'? A simple test should help, just add

typedef unsigned long DWORD;

at the top of the file.
I'm not including 'wtypes.h' in include section, but
typedef unsigned long DWORD;
compiled successfully.
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.
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>you should link with 'msvcrt.lib'
How can this be done?
Try to add

TARGETLIBS=$(DDK_LIB_PATH)\msvcrt.lib

to your 'sources'
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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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));

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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?
Well, what error(s) do you get?
Oh, and be sure that the registry key exists ;o)
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.
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?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
There should be some problem with DrvLoad() too.

It always returns f9e47438.
You mean the DWORD value or the return value?
The value of pdwVal after DrvLoad() completes.
(I mean the DWORD value)
Just to mention, DrvLoad() returns FALSE.
Well, when that function returns FALSE, something went wrong - probably 'DrvOpenKey()'. Can you check the values of 'ntStatus' after the 'Zw*()' calls?
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.
OK, let me double chekc that...
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial