I have written a filter driver firewall that takes its port lists from the registry.
Such as reg_sz values like
80;8080;1433;25
There are two strings that I need to process, one for inbound ports and one for outbound ports. I have successfully written C code in DEV C++ that parses the strings and loads an array of ints.
When I move this code into my Kernel Mode driver, it compiles but throws linker errors such as
cannot resolve external symbol _sscanf
cannot resolve external symbol _realloc
Some research suggests that crt api calls such as sscanf and realloc have no place in a Kernel mode driver.
I have been through the WDDK looking at the rtl and mm functions and am now at the point where I need a steer. You can presumably guess what I’m trying to do with sscanf and realloc, to basically take the string and populate two arrays of ints so that in the callout functions I can decide whether or not to allow the packet to pass, if origination or destination port is in the relevant list.
Ultimately I will load the firewall rules table into memory in user mode and pass it to the driver using an IOCTL, but that is way ahead. For simplicities sake, and to concentrate on the actual firewalling aspects I wanted to load the basic settings this way, but now this is proving more of a headache than actually writing the firewall logic itself!!
Any help would be appreciated.
Thanks in advance
There is no realloc you have to write your own. On the scanf you either can
do the arithmetic yourself or convert the string to UNICODE and use
RtlUnicodeStringToInteger and do your own parsing. Note there are
undocumented ways of getting to functions like scanf, but then you are
entering the gray area of drivers.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
wrote in message news:xxxxx@ntdev…
>I have written a filter driver firewall that takes its port lists from the
>registry.
> Such as reg_sz values like
>
> 80;8080;1433;25
>
> There are two strings that I need to process, one for inbound ports and
> one for outbound ports. I have successfully written C code in DEV C++ that
> parses the strings and loads an array of ints.
>
> When I move this code into my Kernel Mode driver, it compiles but throws
> linker errors such as
>
> cannot resolve external symbol _sscanf
> cannot resolve external symbol _realloc
>
> Some research suggests that crt api calls such as sscanf and realloc have
> no place in a Kernel mode driver.
>
> I have been through the WDDK looking at the rtl and mm functions and am
> now at the point where I need a steer. You can presumably guess what I’m
> trying to do with sscanf and realloc, to basically take the string and
> populate two arrays of ints so that in the callout functions I can decide
> whether or not to allow the packet to pass, if origination or destination
> port is in the relevant list.
>
> Ultimately I will load the firewall rules table into memory in user mode
> and pass it to the driver using an IOCTL, but that is way ahead. For
> simplicities sake, and to concentrate on the actual firewalling aspects I
> wanted to load the basic settings this way, but now this is proving more
> of a headache than actually writing the firewall logic itself!!
>
> Any help would be appreciated.
>
> Thanks in advance
>
Write another parser without a need for sscanf (which is dangerous
function). Be very careful about buffer overflow and presume registry
can contain intentionally broken data.
Alternatively, you can store the result of parsing as binary values in
registry instead of human readable strings. I presume an application
which is used to configure firewall writes these strings. It can write
parsed data as well. It is also necessary to be very careful as
firewalls and target of malware attacks. I’d probably use CRC to check
data validity and format straightforward enough to not crash the driver
in any case.
Best regards,
Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.co.uk
Sent: Wednesday, September 03, 2008 11:29 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] SSCANF and other CRT apis
I have written a filter driver firewall that takes its port
lists from the registry.
Such as reg_sz values like
80;8080;1433;25
There are two strings that I need to process, one for inbound
ports and one for outbound ports. I have successfully written
C code in DEV C++ that parses the strings and loads an array of ints.
When I move this code into my Kernel Mode driver, it compiles
but throws linker errors such as
cannot resolve external symbol _sscanf
cannot resolve external symbol _realloc
Some research suggests that crt api calls such as sscanf and
realloc have no place in a Kernel mode driver.
I have been through the WDDK looking at the rtl and mm
functions and am now at the point where I need a steer. You
can presumably guess what I’m trying to do with sscanf and
realloc, to basically take the string and populate two arrays
of ints so that in the callout functions I can decide whether
or not to allow the packet to pass, if origination or
destination port is in the relevant list.
Ultimately I will load the firewall rules table into memory
in user mode and pass it to the driver using an IOCTL, but
that is way ahead. For simplicities sake, and to concentrate
on the actual firewalling aspects I wanted to load the basic
settings this way, but now this is proving more of a headache
than actually writing the firewall logic itself!!
Any help would be appreciated.
Thanks in advance
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online
at http://www.osronline.com/page.cfm?name=ListServer
-
In my opinion, you either should do this in user mode and pass it or change the representation of the data to eliminate the
string parsing. Short of a compelling reason to do so, you don’t want to parse strings like this in the kernel, especially ones
that come from the registry, because the registry is notorious both for containing malformed data (in practice), and in particular
because REG_SZ read from the registry might not contain a terminating ‘\0,’ which will cause a function like sccanf to overflow.
Minimally, you should be sure to include a length in any %s specification, i. e. - %80s, not just %s - or (preferably) use the
kernel mode version of the safe string library, i. e. - sscanf_s, et. c. One good reason to handle this directly in a driver is so
that you don’t have to depend on a user mode application or service. If those registry settings are your own (you create them),
then I would just represent them differently to eliminate the parsing. If they are not your own, then the whole thing is on a shaky
foundation, in my opinion.
-
Most of the c functions supported by the kernel are contained in the import library LIBCNTPR.LIB, but I seriously doubt that
‘realloc’ is among them. You need to learn about kernel drivers in general and memory management in particular before proceeding
with this portion of your project, but in general, ExAllocatePool is the basic equivalent of malloc(), and the workhorse of kernel
memory management. If you wished, you could use the sequence ExAllocatePool(), RtlCopyMemory(), ExFreePool() to emulate relloc(),
but this is an expensive operation, so I would think twice about if you really need to do it all.
-
You’re going to need a control application - user mode application that communicates with your driver to anything at all, so I
would start there. It sounds like you’ve never written a kernel mode driver for Windows before, so I would recommend starting by
writing a simple console application that opens your driver (which does nothing but load and unload at this point), sends an IOCTL
in some way, shape or form, does anything else you wish like display the results from the IOCTL (submitted via DeviceIoControl()),
close your driver, and terminates. That’s it, and I would get that working before doing anything else. Look in the ‘src’ directory
in your wdk installation for possible samples to use as a starting point.
-
You need to decide what driver model you will use. These days, it will either be a legacy style (NT4) driver or a KMDF driver,
assuming that some form of user mode driver isn’t an option, which it maybe - I don’t know what the deal is with firewall drivers
these days. That is, whether you should use a KMDF driver or not. You need to decide this right now, and you need to get the
advice from someone who knows. No doubt Doron will be along shortly…
-
Which ever driver model you end up using, if you haven’t ever written a kernel mode driver before, I would personally recommend
that you consider just playing around with a simple sample like IOCTRL just to get an idea of what’s going on, how things work and
the fun that can be had with driver installation, for example. Assuming that sample, I would try adding you code to send (and
received) your IOCTL that handles those strings.
Good luck,
mm
xxxxx@yahoo.co.uk wrote:
I have written a filter driver firewall that takes its port lists from the registry.
Such as reg_sz values like
80;8080;1433;25
There are two strings that I need to process, one for inbound ports and one for outbound ports. I have successfully written C code in DEV C++ that parses the strings and loads an array of ints.
When I move this code into my Kernel Mode driver, it compiles but throws linker errors such as
cannot resolve external symbol _sscanf
cannot resolve external symbol _realloc
Some research suggests that crt api calls such as sscanf and realloc have no place in a Kernel mode driver.
I have been through the WDDK looking at the rtl and mm functions and am now at the point where I need a steer. You can presumably guess what I’m trying to do
with sscanf and realloc, to basically take the string and populate two arrays of ints so that in the callout functions I can decide
whether or not to allow
the packet to pass, if origination or destination port is in the relevant list.
Ultimately I will load the firewall rules table into memory in user mode and pass it to the driver using an IOCTL, but that is way ahead.
For simplicities sake, and to concentrate on the actual firewalling aspects I wanted to load the basic settings this way, but now
this is
proving more of a headache than actually writing the firewall logic itself!!
Any help would be appreciated.
Thanks in advance
Great feedback thanks! I was thinking one option was to parse the string and use RtlUnicodeStringToInteger. I stress this is entirely development and not production code so much tidier and malware resistent logic will be implemented, for now though I just want to test my firewall logic and need to get the port lists in as easy as possible. Storing the values in binary is not a realistic option as the code is a workaround until I can develop a front end which will then store the rules in a rijndael encrypted crc checked file, or some such.
So I guess what we’re saying here is the the kernel mode functions are all I got, and I just need to start focussing on that for practicalities sake. If anyone has a snippet of sscanf equivalent parsing a delimited string using only kernel mode apis then all my Christmases have come at once.
xxxxx@yahoo.co.uk wrote:
Great feedback thanks! I was thinking one option was to parse the string and use RtlUnicodeStringToInteger. I stress this is entirely development and not production code so much tidier and malware resistent logic will be implemented, for now though I just want to test my firewall logic and need to get the port lists in as easy as possible. Storing the values in binary is not a realistic option as the code is a workaround until I can develop a front end which will then store the rules in a rijndael encrypted crc checked file, or some such.
So I guess what we’re saying here is the the kernel mode functions are all I got, and I just need to start focussing on that for practicalities sake. If anyone has a snippet of sscanf equivalent parsing a delimited string using only kernel mode apis then all my Christmases have come at once.
For a quick start, parse the stuff in usermode (what you’ve already
done), write it as a binary blob into registry and read that in your
driver. Bingo, you’re done, until the ioctl interface is ready.
–PA
Sold on that last idea, very good indeed. All posts have given me lots to think about. Thanks to all.
Don Burn wrote:
There is no realloc you have to write your own. On the scanf you either can
do the arithmetic yourself or convert the string to UNICODE and use
RtlUnicodeStringToInteger and do your own parsing. Note there are
undocumented ways of getting to functions like scanf, but then you are
entering the gray area of drivers.
Are you suggesting that libcntpr.lib is somehow a “gray area”?
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Tim,
For some of my clients it is considered the gray area, since they
truly belive if a function is not in the WDK documentation it should not be
used. Note: in the past there was no reference to libcntpr.lib in the DDK
documentation, only a few samples. Now there are three references, two
involving you need to link this for a sample and one indicating it is
illegal to use with ScsiPort. So yes, to some degree it is gray, but an
extremely light gray 
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
“Tim Roberts” wrote in message news:xxxxx@ntdev…
> Don Burn wrote:
>> There is no realloc you have to write your own. On the scanf you either
>> can
>> do the arithmetic yourself or convert the string to UNICODE and use
>> RtlUnicodeStringToInteger and do your own parsing. Note there are
>> undocumented ways of getting to functions like scanf, but then you are
>> entering the gray area of drivers.
>>
>
> Are you suggesting that libcntpr.lib is somehow a “gray area”?
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>