Blocking an application using wfp in the kernel

What is the best way to block an application in the kernel ? I know I can use FWPM_CONDITION_ALE_APP_ID filter option but it uses FwpmGetAppIdFromFileName0 which is a usermode prototype. Are there any equivalent kernelmode functions ?

I found the following thread in msdn forums

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a98d58d8-3270-4490-91f5-212a18d8f977/start-service-faied-with-fwpmgetappidfromfilename0-function?forum=wfp

which assumes an alternative for the function but I get many syntax errors and undefined symbols. Has anybody dealt with this before?

I use the following code and I get ExAllocPoolWithTag undefined ?

UINT32 status = STATUS_SUCCESS;
HANDLE fileHandle = 0;
BYTE* pObjectInfo = 0;
UINT32 objLength = 0;
UINT16 appIdSize = 0;
//const UINT16 MAX_PATH = 256;
const UINT16 MY_TAG = (UINT32)‘raHD’;
const PWSTR pAppName = L"\DosDevice\C:\Program Files\Internet Explorer\IExplore.exe";
const UINT16 APP_LENGTH = 59 * sizeof(WCHAR);
PWSTR pApplicationId = 0;
OBJECT_ATTRIBUTES objAttributes;
IO_STATUS_BLOCK ioStatusBlock;
UNICODE_STRING unicodeString;

RtlZeroMemory(&objAttributes,
sizeof(OBJECT_ATTRIBUTES));

RtlZeroMemory(&ioStatusBlock,
sizeof(IO_STATUS_BLOCK));

RtlZeroMemory(&unicodeString,
sizeof(UNICODE_STRING));

pObjectInfo = ExAllocPoolWithTag(NonPagedPool, sizeof(BYTE) * MAX_PATH, MY_TAG);
if (pObjectInfo == 0)
goto ERROR_HANDLING;

unicodeString.Buffer = pAppName;
unicodeString.Length = APP_LENGTH;
unicodeString.MaximumLength = MAX_PATH;

InitializeObjectAttributes(&objAttributes,
&unicodeString,
OBJ_CASE_INSENSITIVE |
OBJ_KERNEL_HANDLE |
OBJ_FORCE_ACCESS_CHECK,
0,
0);

status = ZwOpenFile(&fileHandle,
GENERIC_READ,
&objAttributes,
&ioStatusBlock,
0,
FILE_NON_DIRECTORY_FILE);
if (status != STATUS_SUCCESS || fileHandle == 0)
goto ERROR_HANDLING;

status = ZwQueryObject(fileHandle, 1, pObjectInfo, MAX_PATH, (PULONG)&objLength);
if (status != STATUS_SUCCESS || objLength == 0)
goto ERROR_HANDLING;

appIdSize = (UINT16)((UNICODE_STRING*)pObjectInfo)->Length;

if (appIdSize != 0 &&
appIdSize < 256)
{
pApplicationId = ExAllocPoolWithTag(NonPagedPool, sizeof(WCHAR) * (appIdSize + 1), MY_TAG);
if (pApplicationId == 0)
goto ERROR_HANDLING;

for (UINT32 index = 0;
index < (appIdSize / sizeof(WCHAR));
index++)
{
((UNICODE_STRING*)pObjectInfo)->Buffer[index] = towlower(((UNICODE_STRING*)pObjectInfo)->Buffer[index]);
}

RtlCopyMemory(pApplicationId,
((UNICODE_STRING*)pObjectInfo)->Buffer,
appIdSize);
}

if (fileHandle)
{
ZwClose(fileHandle);

fileHandle = 0;
}

ExFreePoolWithTag((VOID*)pObjectInfo, MY_TAG);

It is ExAllocatePoolWithTag

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
xxxxx@lists.osr.com
Sent: Friday, July 14, 2017 10:13 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Blocking an application using wfp in the kernel

I use the following code and I get ExAllocPoolWithTag undefined ?

UINT32 status = STATUS_SUCCESS;
HANDLE fileHandle = 0;
BYTE* pObjectInfo = 0;
UINT32 objLength = 0;
UINT16 appIdSize = 0;
//const UINT16 MAX_PATH = 256;
const UINT16 MY_TAG = (UINT32)‘raHD’;
const PWSTR pAppName = L"\DosDevice\C:\Program
Files\Internet Explorer\IExplore.exe";
const UINT16 APP_LENGTH = 59 * sizeof(WCHAR);
PWSTR pApplicationId = 0;
OBJECT_ATTRIBUTES objAttributes;
IO_STATUS_BLOCK ioStatusBlock;
UNICODE_STRING unicodeString;

RtlZeroMemory(&objAttributes,
sizeof(OBJECT_ATTRIBUTES));

RtlZeroMemory(&ioStatusBlock,
sizeof(IO_STATUS_BLOCK));

RtlZeroMemory(&unicodeString,
sizeof(UNICODE_STRING));

pObjectInfo = ExAllocPoolWithTag(NonPagedPool, sizeof(BYTE)
MAX_PATH, MY_TAG);
if (pObjectInfo == 0)
goto ERROR_HANDLING;

unicodeString.Buffer = pAppName;
unicodeString.Length = APP_LENGTH;
unicodeString.MaximumLength = MAX_PATH;

InitializeObjectAttributes(&objAttributes,
&unicodeString,
OBJ_CASE_INSENSITIVE |
OBJ_KERNEL_HANDLE |
OBJ_FORCE_ACCESS_CHECK,
0,
0);

status = ZwOpenFile(&fileHandle,
GENERIC_READ,
&objAttributes,
&ioStatusBlock,
0,
FILE_NON_DIRECTORY_FILE);
if (status != STATUS_SUCCESS || fileHandle == 0)
goto ERROR_HANDLING;

status = ZwQueryObject(fileHandle, 1, pObjectInfo, MAX_PATH,
(PULONG)&objLength);
if (status != STATUS_SUCCESS || objLength == 0)
goto ERROR_HANDLING;

appIdSize = (UINT16)((UNICODE_STRING
)pObjectInfo)->Length;

if (appIdSize != 0 &&
appIdSize < 256)
{
pApplicationId = ExAllocPoolWithTag(NonPagedPool,
sizeof(WCHAR) * (appIdSize + 1), MY_TAG);
if (pApplicationId == 0)
goto ERROR_HANDLING;

for (UINT32 index = 0;
index < (appIdSize / sizeof(WCHAR));
index++)
{
((UNICODE_STRING*)pObjectInfo)->Buffer[index] =
towlower(((UNICODE_STRING*)pObjectInfo)->Buffer[index]);
}

RtlCopyMemory(pApplicationId,
((UNICODE_STRING*)pObjectInfo)->Buffer,
appIdSize);
}

if (fileHandle)
{
ZwClose(fileHandle);

fileHandle = 0;
}

ExFreePoolWithTag((VOID*)pObjectInfo, MY_TAG);


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

Thanks Don, it compiles well now but I get a run time error as ZwOpenFile fails with error code c0000033 ! Any ideas ?

That is STATUS_OBJECT_NAME_INVALID, you have a problem with your pathname to
the file.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
xxxxx@lists.osr.com
Sent: Friday, July 14, 2017 7:47 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Blocking an application using wfp in the kernel

Thanks Don, it compiles well now but I get a run time error as ZwOpenFile
fails with error code c0000033 ! Any ideas ?


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

The path is
const PWSTR pAppName = L"\DosDevice\C:\Program Files\Internet Explorer\IExplore.exe";
which surely exists on the test machine. Could the error be caused by another issue ?

On Sat, 15 Jul 2017, xxxxx@gmail.com wrote:

The path is
const PWSTR pAppName = L"\DosDevice\C:\Program Files\Internet Explorer\IExplore.exe";
which surely exists on the test machine. Could the error be caused by another issue ?

There is an “s” missing in “DosDevices”.

Thanks Branten, I don’t get that error now but the system crashes and I get the blue screen. It seems the error happens when adding the filter conditions because running it without them doesn’t cause any error. How do I know what caused the error ?

HANDLE fileHandle = 0;
BYTE* pObjectInfo = 0;
UINT32 objLength = 0;
UINT16 appIdSize = 0;
const UINT16 MAX_PATH1 = 256;
const UINT16 MY_TAG = (UINT32)‘raHD’;
const PWSTR pAppName = L"\DosDevices\C:\Program Files\Internet Explorer\iexplore.exe";
const UINT16 APP_LENGTH = 59 * sizeof(WCHAR);
PWSTR pApplicationId = 0;
OBJECT_ATTRIBUTES objAttributes;
IO_STATUS_BLOCK ioStatusBlock;
UNICODE_STRING unicodeString;

RtlZeroMemory(&objAttributes,
sizeof(OBJECT_ATTRIBUTES));

RtlZeroMemory(&ioStatusBlock,
sizeof(IO_STATUS_BLOCK));

RtlZeroMemory(&unicodeString,
sizeof(UNICODE_STRING));

pObjectInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(BYTE) * MAX_PATH1, MY_TAG);
if (pObjectInfo == 0)
DbgPrint(“Error in allocating pool!”);

unicodeString.Buffer = pAppName;
unicodeString.Length = APP_LENGTH;
unicodeString.MaximumLength = MAX_PATH1;

InitializeObjectAttributes(&objAttributes,
&unicodeString,
OBJ_CASE_INSENSITIVE |
OBJ_KERNEL_HANDLE |
OBJ_FORCE_ACCESS_CHECK,
0,
0);

DbgPrint(“Trying to open !!”);
status = ZwOpenFile(&fileHandle,
GENERIC_READ,
&objAttributes,
&ioStatusBlock,
0,
FILE_NON_DIRECTORY_FILE);
if (status != STATUS_SUCCESS || fileHandle == 0)
DbgPrint(“Error in opening the file %X” , status);

status = ZwQueryObject(fileHandle, 1, pObjectInfo, MAX_PATH1, (PULONG)&objLength);
if (status != STATUS_SUCCESS || objLength == 0)
DbgPrint(“Error in quering the object %X” , status);

appIdSize = (UINT16)((UNICODE_STRING*)pObjectInfo)->Length;

if (appIdSize != 0 &&
appIdSize < 256)
{
pApplicationId = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * (appIdSize + 1), MY_TAG);
if (pApplicationId == 0)
DbgPrint(“Error in allocaing the pool”);

for (UINT32 index = 0;
index < (appIdSize / sizeof(WCHAR));
index++)
{
((UNICODE_STRING*)pObjectInfo)->Buffer[index] = towlower(((UNICODE_STRING*)pObjectInfo)->Buffer[index]);
}

RtlCopyMemory(pApplicationId,
((UNICODE_STRING*)pObjectInfo)->Buffer,
appIdSize);
}

if (fileHandle)
{
ZwClose(fileHandle);

fileHandle = 0;
}

ExFreePoolWithTag((VOID*)pObjectInfo, MY_TAG);
filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_ALE_APP_ID;
filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;
filterConditions[conditionIndex].conditionValue.type = FWP_BYTE_BLOB_TYPE;
filterConditions[conditionIndex].conditionValue.byteBlob = pApplicationId;
conditionIndex++;

you need to learn how to debug your own code. Using this list as a debugger
is the wrong way to do it.

Mark Roddy

On Sun, Jul 16, 2017 at 3:28 PM, xxxxx@gmail.com
wrote:

> Thanks Branten, I don’t get that error now but the system crashes and I
> get the blue screen. It seems the error happens when adding the filter
> conditions because running it without them doesn’t cause any error. How do
> I know what caused the error ?
>
> HANDLE fileHandle = 0;
> BYTE* pObjectInfo = 0;
> UINT32 objLength = 0;
> UINT16 appIdSize = 0;
> const UINT16 MAX_PATH1 = 256;
> const UINT16 MY_TAG = (UINT32)‘raHD’;
> const PWSTR pAppName = L"\DosDevices\C:\Program
> Files\Internet Explorer\iexplore.exe";
> const UINT16 APP_LENGTH = 59 * sizeof(WCHAR);
> PWSTR pApplicationId = 0;
> OBJECT_ATTRIBUTES objAttributes;
> IO_STATUS_BLOCK ioStatusBlock;
> UNICODE_STRING unicodeString;
>
> RtlZeroMemory(&objAttributes,
> sizeof(OBJECT_ATTRIBUTES));
>
> RtlZeroMemory(&ioStatusBlock,
> sizeof(IO_STATUS_BLOCK));
>
> RtlZeroMemory(&unicodeString,
> sizeof(UNICODE_STRING));
>
> pObjectInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(BYTE)
> MAX_PATH1, MY_TAG);
> if (pObjectInfo == 0)
> DbgPrint(“Error in allocating pool!”);
>
> unicodeString.Buffer = pAppName;
> unicodeString.Length = APP_LENGTH;
> unicodeString.MaximumLength = MAX_PATH1;
>
> InitializeObjectAttributes(&objAttributes,
> &unicodeString,
> OBJ_CASE_INSENSITIVE |
> OBJ_KERNEL_HANDLE |
> OBJ_FORCE_ACCESS_CHECK,
> 0,
> 0);
>
> DbgPrint(“Trying to open !!”);
> status = ZwOpenFile(&fileHandle,
> GENERIC_READ,
> &objAttributes,
> &ioStatusBlock,
> 0,
> FILE_NON_DIRECTORY_FILE);
> if (status != STATUS_SUCCESS || fileHandle == 0)
> DbgPrint(“Error in opening the file %X” , status);
>
> status = ZwQueryObject(fileHandle, 1, pObjectInfo, MAX_PATH1,
> (PULONG)&objLength);
> if (status != STATUS_SUCCESS || objLength == 0)
> DbgPrint(“Error in quering the object %X” , status);
>
> appIdSize = (UINT16)((UNICODE_STRING
)pObjectInfo)->Length;
>
> if (appIdSize != 0 &&
> appIdSize < 256)
> {
> pApplicationId = ExAllocatePoolWithTag(NonPagedPool,
> sizeof(WCHAR) * (appIdSize + 1), MY_TAG);
> if (pApplicationId == 0)
> DbgPrint(“Error in allocaing the pool”);
>
> for (UINT32 index = 0;
> index < (appIdSize / sizeof(WCHAR));
> index++)
> {
> ((UNICODE_STRING*)pObjectInfo)->Buffer[index] =
> towlower(((UNICODE_STRING*)pObjectInfo)->Buffer[index]);
> }
>
> RtlCopyMemory(pApplicationId,
> ((UNICODE_STRING*)pObjectInfo)->Buffer,
> appIdSize);
> }
>
> if (fileHandle)
> {
> ZwClose(fileHandle);
>
> fileHandle = 0;
> }
>
> ExFreePoolWithTag((VOID*)pObjectInfo, MY_TAG);
> filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_ALE_APP_ID;
> filterConditions[conditionIndex].matchType = FWP_MATCH_EQUAL;
> filterConditions[conditionIndex].conditionValue.type =
> FWP_BYTE_BLOB_TYPE;
> filterConditions[conditionIndex].conditionValue.byteBlob =
> pApplicationId;
> conditionIndex++;
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

On Jul 16, 2017, at 12:28 PM, xxxxx@gmail.com xxxxx@lists.osr.com wrote:

Thanks Branten, I don’t get that error now but the system crashes and I get the blue screen. It seems the error happens when adding the filter conditions because running it without them doesn’t cause any error. How do I know what caused the error ?

In every one of your error conditions, you print a debug string, but then you just continue on as if the call had succeeded. That’s a recipe for disaster.

sizeof(BYTE) is 1, by definition.

const UINT16 MY_TAG = (UINT32)‘raHD’;

What do you think that’s going to do? How do you store a 32-bit tag in a UINT16?

unicodeString.Buffer = pAppName;
unicodeString.Length = APP_LENGTH;
unicodeString.MaximumLength = MAX_PATH1;

The MaximumLength of this buffer is APP_LENGTH. There’s no room to expand it.

pObjectInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(BYTE) * MAX_PATH1, MY_TAG);
if (pObjectInfo == 0)
DbgPrint(“Error in allocating pool!”);

Why allocate this as MAX_PATH1 bytes, when you know you’re fetching a UNICODE_STRING? Why not just define

UNICODE_STRING pObjectInfo;

and pass its address to ZwQueryObject?

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hey Tim, I really appreciate your comment. Actually I copied the code from

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a98d58d8-3270-4490-91f5-
212a18d8f977/start-service-faied-with-fwpmgetappidfromfilename0-function?forum=wf
p

I am not sure if it is correct as I am new to this. Are the filterconditions correct or do I need to change them ? Can a PWSTR type be applied to a byte array for the condition ?

filterConditions[conditionIndex].conditionValue.byteBlob = pApplicationId;

On Jul 17, 2017, at 1:57 PM, xxxxx@gmail.com xxxxx@lists.osr.com wrote:

Hey Tim, I really appreciate your comment. Actually I copied the code from

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a98d58d8-3270-4490-91f5-
212a18d8f977/start-service-faied-with-fwpmgetappidfromfilename0-function?forum=wf
p

It is very, very, very dangerous to take code you do not understand from a web site and shove it into the kernel.

I am not sure if it is correct as I am new to this. Are the filterconditions correct or do I need to change them ? Can a PWSTR type be applied to a byte array for the condition ?

filterConditions[conditionIndex].conditionValue.byteBlob = pApplicationId;

Absolutely not. Did you read ANY of the documentation for the functions you are calling here? If you had, you would have learned that the app ID is an integer. You have to call another function to convert your path name into an integer app ID. The thread you quoted above even told you which API to use to do that mapping.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I am still quite lost here. Tried for the previous three days and nowhere to go. What I understand is that I have to pass FWP_BYTE_BLOB to

filterConditions[conditionIndex].conditionValue.byteBlob

You said I have to pass an integer? Furthermore, in the link it says I have to use ZwQueryObject to retrieve the app id but as used the pObjectInfo variable contains the path name when I print it. What I am missing here ? How to get the appid ?

xxxxx@gmail.com xxxxx@lists.osr.com wrote:

I am still quite lost here. Tried for the previous three days and nowhere to go. What I understand is that I have to pass FWP_BYTE_BLOB to

filterConditions[conditionIndex].conditionValue.byteBlob

You said I have to pass an integer? Furthermore, in the link it says I have to use ZwQueryObject to retrieve the app id but as used the pObjectInfo variable contains the path name when I print it. What I am missing here ? How to get the appid ?

Well, it appears that I either misread or was misled by some sample code
on the web. The documentation does clearly state that the
FWPM_CONDITION_ALE_APP_ID value must be a pathname string.

However, it has to be a fully qualified path name starting at the
\Devices tree. I believe you need to use FwpmGetAppIdFromFileName0 to
convert a user-type path to a fully-qualified path to pass to the
filter. Note that the output type here is a pointer to pointer to
FWP_BYTE_BLOB, which should be familiar. The doc page for that function
shows an example.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

“However, it has to be a fully qualified path name starting at the
\Devices tree. I believe you need to use FwpmGetAppIdFromFileName0 to
convert a user-type path to a fully-qualified path to pass to the
filter. Note that the output type here is a pointer to pointer to
FWP_BYTE_BLOB, which should be familiar. The doc page for that function
shows an example.”

But using that we are back to square one because I cannot use this function in the kernel. The link I provided was suggesting to use that code as an alternative for the function but I am not sure how is that a solution and how to use it?