Introduction
This is an introductory article to a series that I am going to publish at CodeProject about Detours.
Throughout the series we will focus on how to leverage the power of Detours to our advantage without going into the intricacies of the technology itself.
The discerning reader is advised to go through the excellent presentations prepared by Galen Hunt, as well as the documentation provided with the Detours package itself.
In this article we shall understand what Detours is and what it can do. Then, we shall follow up with a set of samples outlining the material.
Background
It is often that a legacy application needs to be extended, but the source is not readily available. Or maybe you find out that it would have been great if you had used CToolBar::CreateEx()
with the TBSTYLE_FLAT
flag instead of simple Create()
to make your toolbars look more snazzy..
These are the times when toiling thorough the source tends to put one off - after all, why sweat just to make you app look a bit more nicer ;)
In such cases, a Detour based solution comes very handy. In fact, after using it, you will wonder what you were doing without it since '99.
In short, what Detours really does, is just detour calls to a function(s) to another (user supplied) one, but obviously, their signatures should match.
Detours in a line
It is a library for
intercepting arbitrary Win32 binary functions on x86 machines.
Using Detours
Detours is a Microsoft Research project, and till date a pre-release package. As a result, you are requested to obtain the Detours package (~627KB) yourself from the Microsoft Research site. Typically, all that we will be needing is the detours.lib
and the detours.h
files to compile the samples which I have provided here .
It is to be noted that you MUST first read and agree to the EULA provided with Detours in order to use parts which belong to it (which includes detours.lib, detours.h
), in conjunction with this article.
Basic framework code for projects using Detours
First timers may find Detours a little intimidating, so besides the suggestion that Galen Hunt has put out in his publication, I myself make another one.
The framework give below however is for static trampolines which are extremely easy to use when the target function(s) are available as link symbol(s). In the scope of this article, we will be content with Win32 APIs which are usually available for linking.
However, very little modification is required for supporting dynamic trampolines. So here goes...
#include <windows.h>
#include "detours.h"
#pragma warning(disable:4100)
#pragma comment(lib,"detours.lib")
DETOUR_TRAMPOLINE(HANDLE WINAPI Real_CreateFile(LPCTSTR lpFileName,
DWORD dwDesiredAccess,DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile),CreateFile);
BOOL WINAPI DetourWriteFile(HANDLE hFile,LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped)
{
BOOL bRet=Real_WriteFile(hFile,lpBuffer,
nNumberOfBytesToWrite,lpNumberOfBytesWritten,lpOverlapped);
if(*(const char*)lpBuffer)
{
DWORD dwBytesWrote;
Real_WriteFile(hOutFile,(LPCTSTR)lpBuffer,lstrlen(
(const char*)lpBuffer),&dwBytesWrote,NULL);
}
return bRet;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
DetourFunctionWithTrampoline((PBYTE)Real_CreateFile,
(PBYTE)DetourCreateFile);
}
else if (ul_reason_for_call == DLL_PROCESS_DETACH)
{
DetourRemove((PBYTE)Real_CreateFile, (PBYTE)DetourCreateFile);
}
return TRUE;
}
Putting what we learnt to use : Making Windows programs disobedient
Many a time I have received cries for help from people who locked themselves out after
experimenting with Group Policies.
Sometimes I can figure out it's just a kid trying to get around the restrictions set by his parents, and sometimes it's a genuine request.
Group policies are mostly maintained thorough the omnipresent registry. Each setting has a corresponding registry setting which is evaluated by the concerned components during execution.
For demonstration purposes, we will consider the following :
- DisableCMD - HKCU\Software\Policies\Microsoft\Windows\System.
This determines whether the current user can run the command prompt - Cmd.exe, and determines if batch files can be executed while this user is logged on.
- DisableTaskMgr - HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System.
A value of '1' will prevent the user from starting Task Manager - Taskmgr.exe.
- DisableRegistryTools - HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System.
A value of '1' will disable the Windows registry editors, Regedt32.exe and Regedit.exe.
Our samples will allow us to circumvent these policies even when they are in effect.
You are requested to use the Group Policy editor to put these policies in effect and verify that the samples indeed circumvent the security settings.
What did we do ?
Well, to put to simply, we "detoured" the
RegQueryValueEx
(
RegQueryValueExW
to be precise..) which is called by the afore mentioned tools to find out if the group policy allows them to run or not, to go though our modified 'DetourRegQueryValueEx' function which checks if the above keys are being checked for. If they are, we make the function return a value which it otherwise would have returned if the restriction had not been there ! This
fools the concerned programs into believing that the restrictions actually do not exist (even when they really do).
Well, so much for Group Policies...
History
- 20040414 - Formatting changes
- 20040329 - Initial draft
Send in your feedback
Please send in feedback as to if this article came to use to you. This will help me gauge the acceptance of such material, and will affect further submitting of my articles regarding Detours.
I have kept a brief plan of the articles that I wish to write at http://www.geocities.com/kbshankar2000/ArticleSchedule.html. You may go through it and suggest your choice of precedence.