CFF Explorer:
Improved support for tiny PEs.
Fixed a bug in the Exception Directory which was due to the grid set up.
Task Explorer:
Fixed a minor bug on x64.
Added the Driver List tool.
CFF Explorer:
Improved support for tiny PEs.
Fixed a bug in the Exception Directory which was due to the grid set up.
Task Explorer:
Fixed a minor bug on x64.
Added the Driver List tool.
This week, after months of development of bigger projects, I found some time to windbg “ntoskrnl.exe” and write a utility. It is called Filter Monitor and shows some key filters installed by kernel mode components.
“As you probably all know the Service Descriptor Table has been a playground on x86 for all sorts of things: rootkits, anti-viruses, system monitors etc. On x64 modifying the Service Descriptor Table is no longer possible, at least not without subverting the Patch Guard technology.
Thus, programs have now to rely on the filtering/notification technologies provided by Microsoft. And that’s why I wrote this little utility which monitors some key filters.
Since I haven’t signed the driver of my utility, you have to press F8 at boot time and then select the “Disable Driver Signature Enforcement” option. If you have a multiple boot screen like myself, then you can take your time. Otherwise you have to press F8 frenetically to not miss right moment.
A disclaimer: the boot process can be a bit annoying, but the utility should be used on virtualized systems anyway, as I haven’t fully tested it yet. I doubt that it will crash your system, I guess the worst scenario is that it won’t list some filters. It should work on any Windows system starting from Vista RTM and I have provided an x86 version and an x64 version. But the truth is that I have tested only the x64 version on Windows 7 RTM. Last but not least, I can’t guarantee that this utility will work on future versions of Windows, it relies heavily on system internals.
Now, let’s run it. The supported filters/notifications at the time are these: Registry, Create Process, Create Thread and Load Image. “Registry” stands for CmRegisterCallback filters. “Create Process” for PsSetCreateProcessNotifyRoutine callbacks. “Create Thread” for PsSetCreateThreadNotifyRoutine callbacks. And “Load Image” for PsSetLoadImageNotifyRoutine callbacks.
The “Additional Info” in the list view provides internal information like the address of the callback function.
There are some default filters registered by system components, but, as you can notice, there are also Kaspersky components. That’s because some filters (like the registry filter) are not used by system components and I needed a tool which would make use of these filters for my little demonstration.
The version of Kaspersky I have installed is the latest one available on the internet which is: 9.0.0.463.
I created for this demonstration a little executable called “k-test” (what you see on the desktop are three copies of the same executable) which copies itself in a directory called “borda” in the “Roaming” directory of the operating system. It then creates a value in the Run key of the registry to execute itself at each start-up. Finally, it launches itself from the “Roaming” directory and ends.
This is a typical malware behavior. Beware that the signature of the application itself is not contained in the databases of Kaspersky as I have written it on the fly, but it detects the suspicious behavior, stops execution and deletes the file. And it does this every time I launch the test application.
Now let’s get to the part where I show an additional functionality of the Filter Monitor which is the ability to remove registered filters and see what happens if I remove the filters installed by klif.sys, which is the “Kaspersky Lab Interceptor and Filter” driver. As the name suggests, this driver intercepts and filters: it installs all four of typologies of filters listed by the Filter Monitor. On x86 instead of calling CmRegisterCallback it additionally hooks about 60 functions of the Service Descriptor Table (which is a lot), but that’s no longer possible on x64.
So, let’s remove the filters and re-launch k-test. It works now.
Final disclaimer: It is not my intent to comment on security features of anti-viruses, I just wanted to present my new tool and show its functionalities. I was already familiar with the internals of Kaspersky before writing this utility.
I hope you enjoyed the presentation.”
P.S. A huge thanks goes to Alessandro Gario for providing me with all the different versions of ntoskrnl.exe.
Fixed a bug reported by icy. It was causing crashes in executables without sections when calculating their PE size.
If you’re a Qt developer, you surely are aware of the fact that you can only display GUI elements and access them from the main thread. This limitation as far as I know is mostly bound to the limitations of X and it isn’t to exclude that multithreading support for GUIs will be added soon.
This limitation never caused me any trouble, since the signal & slots mechanism is thread-safe and communicating between threads and GUI elements can be achieved through it. However, yesterday I needed to show a messagebox in a method and, in case the code is not executing in the main thread, show a native win32 MessageBox instead of a QMessageBox (of course, only on Windows can I do that, on other platforms when I’m not in the main thread, I won’t show anything).
Anyway, here’s a simple method to establish if we’re running the GUI thread:
bool isGuiThread()
{
if (QCoreApplication::instance()->thread() == QThread::currentThread())
return true;
return false;
}
As you can see this is a pointer comparision, but can we rely on the value returned by currentThread? Yes, we can since the pointer is associated with the thread itself as we can see from the code of the method:
QThread *QThread::currentThread()
{
QThreadData *data = QThreadData::current();
Q_ASSERT(data != 0);
return data->thread;
}
// thread_win.cpp
QThreadData *QThreadData::current()
{
qt_create_tls();
QThreadData *threadData = reinterpret_cast(TlsGetValue(qt_current_thread_data_tls_index));
if (!threadData) {
QThread *adopted = 0;
if (QInternal::activateCallbacks(QInternal::AdoptCurrentThread, (void **) &adopted)) {
Q_ASSERT(adopted);
threadData = QThreadData::get2(adopted);
TlsSetValue(qt_current_thread_data_tls_index, threadData);
adopted->d_func()->running = true;
adopted->d_func()->finished = false;
static_cast(adopted)->init();
} else {
threadData = new QThreadData;
// This needs to be called prior to new AdoptedThread() to
// avoid recursion.
TlsSetValue(qt_current_thread_data_tls_index, threadData);
threadData->thread = new QAdoptedThread(threadData);
threadData->deref();
}
if (!QCoreApplicationPrivate::theMainThread) {
QCoreApplicationPrivate::theMainThread = threadData->thread;
} else {
HANDLE realHandle = INVALID_HANDLE_VALUE;
#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
&realHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
#else
realHandle = (HANDLE)GetCurrentThreadId();
#endif
qt_watch_adopted_thread(realHandle, threadData->thread);
}
}
return threadData;
}
qt_create_tls just calls once for every thread TlsAlloc and if the data for the current thread hasn’t been set yet, it is set with TlsSetValue. So, we can rely on a pointer comparision.
Today I received the following email from my hosting provider:
[…] Security is our highest priority and the last years we have taken dramatic measures to build the most secure hosting environment around.
Unfortunately we have however been affected by the Linux kernel vulnerability (CVE-2009-2692) for a 24 hour period. Due to our architecture this exploit did not compromise personal data and all customer records are safe.
After updating the kernel on our systems we scanned all customer accounts and found that your index was removed. Therefore we kindly ask you to check your webpage and reupload your index page if it is missing.
We sincerely apologize for this incident and will take measures to ensure to prevent such incidents in the future.
The index pages of both rcecafe and ntcore were missing in fact. For precaution I reuploaded both pages completely.