Security Software and Undocumented API Usage

I’ve read many threads that have originated from this list regarding the usage of undocumented api calls and people’s opinions on whether they should be used or not. My question is, when you are building security software, what other choice do you have? To illustrate my point, I will draw attention to Symantec Endpoint Protection. As part of this software suite, they have a component called “Application and Device Control”. This component consists of a driver called sysplant.sys. This driver registers a create process notification callback and an image load notification callback during initialization. In the image load notification callback they do quite a few things that, based on my reading of this forum, the developers here would scream bloody murder at. The overall purpose of the callback is to inject a dll called sysfer.dll into user land processes. Inside the image load notification callback, they make use of KeInitializeApc and KeInsertQueueApc to accomplish the dll injection. Both of these are undocumented APIs that could change at any time. Now, I will say, this method of dll injection has been known for some time and they certainly aren’t the first to make use of it. But this is a very popular corporate security suite that is used in many enterprises. I’ve seen people like Don comment in response to people asking about doing the exact same thing (dll injection from kernel) that he wants them to tell him the name of their company and product so he can avoid their software and urge his customers to avoid their software as well. Does that apply to companies like Symantec as well? And finally, if you can’t use a technique like KeInitializeApc/KeInsertQueueApc to inject a dll into user land processes, what other option do you have if Microsoft does not provide a documented way to do that?

First as far as Symantec, they sued Microsoft to remove PatchGuard since it
broke their software, so I don’t think they are what you can call a great
example. There are documented ways of doing DLL injection from user space,
so the question becomes what advantage does the kernel bring you. I
haven’t heard a valid argument for what is better about doing this with an
undocumented (and not always safe) approach from the kernel so I still am
against it.

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@protonmail.com
Sent: Tuesday, October 18, 2016 8:56 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Security Software and Undocumented API Usage

I’ve read many threads that have originated from this list regarding the
usage of undocumented api calls and people’s opinions on whether they should
be used or not. My question is, when you are building security software,
what other choice do you have? To illustrate my point, I will draw attention
to Symantec Endpoint Protection. As part of this software suite, they have a
component called “Application and Device Control”. This component consists
of a driver called sysplant.sys. This driver registers a create process
notification callback and an image load notification callback during
initialization. In the image load notification callback they do quite a few
things that, based on my reading of this forum, the developers here would
scream bloody murder at. The overall purpose of the callback is to inject a
dll called sysfer.dll into user land processes. Inside the image load
notification callback, they make use of KeInitializeApc and KeInsertQueueApc
to accomplish the dll injection. Both of these are undocumented APIs that
could change at any time. Now, I will say, this method of dll injection has
been known for some time and they certainly aren’t the first to make use of
it. But this is a very popular corporate security suite that is used in many
enterprises. I’ve seen people like Don comment in response to people asking
about doing the exact same thing (dll injection from kernel) that he wants
them to tell him the name of their company and product so he can avoid their
software and urge his customers to avoid their software as well. Does that
apply to companies like Symantec as well? And finally, if you can’t use a
technique like KeInitializeApc/KeInsertQueueApc to inject a dll into user
land processes, what other option do you have if Microsoft does not provide
a documented way to do that?


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:>

If you are going to sell for enterprise you must address their needs. I regard Mr Burn as an expert in driver development area but it would be impossible to use such opinion for undocumented API to win a contract. You would not get a contract as your solution would not provide the same level of functionality as a software that uses undocumented API.

When I developed a similar solution I managed to avoid using KeInitializeApc/KeInsertQueueApc . I used a documented API that results in calling KeInsertQueueApc. I can’t elaborate more on this as this is a part of a commercial product. Anyway, this usage of the documented API relied on the “undocumented knowledge” about its implementation.

They have also done other dodgy things like implementing file unpacking in their drivers which resulted in critical exploitable vulnerabilities at the kernel, so I agree with you on that. That said, they have been around a LONG time and still have a very large user base. Regardless, other security companies implement similar features (dll injection from kernel).

I would assume because the dll they want to inject is involved in hooking system routines in libraries like ntdll.dll to spy on API calls made by user processes. Since I’m assuming they want to get their hook library loaded before the process has finished initializing, they use KeInsertQueueApc to queue an APC to the initial thread in the process while libraries are being loaded.

Is there a documented way to inject a dll into new processes as they are loading from user land? The only thing I can think of is to inject code into explorer, hook CreateProcessInternal and monitor for new process creation and inject at that point. Then that only covers user session processes and you might miss a few others. Likewise, using AppInit_DLLs would have the same problem, although I think Kaspersky uses that.

I would not say you could not win a contract, but a professional will do
full disclosure that they are stepping outside of documented usage, and why
they feel they need to do it. There are situations you have to step out of
the lines, but it needs to be well documented.

For example about 5 years ago, I developed a hooking driver even though I
had by that point been speaking out against it. The driver was only for
Windows XP 32-bit and the client needed to capture registry calls and the
CmRegisterCallback was inadequate, the driver was split into a library for
hooking, another library using CmRegisterCallbackEx and the code that did
the actual work. The customer understood the dangers, but really needed
CmRegisterCallbackEx capabilities on XP, which required the hooking.

You have to use judgement, the people I speak out against are the ones who
have a bad design, and are wedded to it when there are alternatives.

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@hotmail.com
Sent: Tuesday, October 18, 2016 10:50 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Security Software and Undocumented API Usage

If you are going to sell for enterprise you must address their needs. I
regard Mr Burn as an expert in driver development area but it would be
impossible to use such opinion for undocumented API to win a contract. You
would not get a contract as your solution would not provide the same level
of functionality as a software that uses undocumented API.



When I developed a similar solution I managed to avoid using
KeInitializeApc/KeInsertQueueApc . I used a documented API that results in
calling KeInsertQueueApc. I can’t elaborate more on this as this is a part
of a commercial product. Anyway, this usage of the documented API relied on
the “undocumented knowledge” about its implementation.


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:>

This isn’t really restricted to “building security software”. It’s a much more general question.

And the answer is that it’s a judgement call. Not all undocumented things are equal. If you know your way around the Windows OS pretty well, and understand its evolution, you’re probably in a good position to take what is at least a REASONABLE guess as WHY a given API set is undocumented. This should guide your actions. Calling KeInsertQueueApc isn’t really in the same class as NtQuerySystemInformation for a random class of information. And calling 0NtQuerySystemInformation isn’t the same as reaching into some structure at an arbitrary offset and running a list, or even calling a newly introduced API for some new OS feature that’s not likely to be stable.

If you don’t know your Windows well enough to make these calls, then the answer is simple: Don’t use undocumented stuff. Go hire somebody who has the necessary level of knowledge, can articulate the perceived level of risk, and can help you make the trade-offs.

Sometimes if you want to innovate, you NEED to do undocumented things. When you do these things, you need to be absolutely sure that you do them in an architecturally appropriate way and in a way that’s as sound as possible. And, finally, you need to be willing to live with the risk you’re introducing into the project. This might require a pro-active approach (like, being a closer partner with MSFT and testing your product on every new pre-release of Windows to be sure YOU – not your customers – are the first to know when your approach breaks).

It’s not a mystery. It’s the very essence of engineering.

Peter
OSR
@OSRDrivers

Do not do undocumented thing because you simply don’t want to break your customer’s machine, do you ?

You must be very careful about this. You don’t want to be sued and pay your customer big compensations.

Injection ? Why ? You are not supposed to execute code in the context of someone else process.

KeInsertQueueApc actually was documented long time ago. It fell out of favor since then, but it was documented.

In MSDN? By Microsoft? I don’t think so.

With all due respect, I have been asked (and answered) questions about this API and its use since “the beginning of time” – I do not ever remember this function being documented by MSFT.

Once documented by MSFT, functions ALMOST never get *undocumented*

Now, GIYF: You can find LOADS of docs on KeInsertQueueApc online. And some of the people who’ve done those write-ups even know what they’re talking about. But I don’t see anything by MSFT.

Peter
OSR
@OSRDrivers

Thanks for this advice, Peter. This pretty much addresses what I was thinking about when asking this question.

> I do not ever remember this function being documented by MSFT.

I think that the entire concept of APCs is supposed to be transparent to both KM and UM programmers - although you may be aware of them (and are even allowed to disable APC delivery to your thread by raising IRQL) you are not supposed to actually try making any use of them on your own initiative in either mode. IIRC, even “Windows Internals” does not provide any details in this respect

Anton Bassov