Click here to Skip to main content
Click here to Skip to main content

Easy API hooking in Windows CE

By , 13 Nov 2010
Rate this:
Please Sign up or sign in to vote.
I won't go into all the interesting things you can do with API hooking as there are lots of articles on CodeProject already about that. But, here's a quick and easy way to do it under Windows CE / Windows Mobile.
 
You need platform builder for pkfuncs.h and psyscall.h and access to the private sources for kernel.h. Fortunately for the rest of you, however, all these things can be found by some quick Internet searches, too.
 
This example will subvert the GetTickCount() API to print 12345 and then restore it to its original state.
 
#include <psyscall.h>
#include <pkfuncs.h>
#include <kernel.h>

DWORD WINAPI Hook_GetTickCount( VOID )
{
    return 12345;
}
 
/// swap two function pointers
void SwapPFN( PFNVOID* a, PFNVOID* b )
{
    PFNVOID temp = *a;
    *a = *b;
    *b = temp;
}
 
int _tmain( int argc, _TCHAR* argv[] )
{
    // Give ourselves phenomenal cosmic powers
    DWORD old_permissions = ::SetProcPermissions( 0xFFFFFFFF );
    ::SetKMode( TRUE );
 
    // get access to the kernel data page and the WIN32 API pointers
    CINFO** api_sets = ( CINFO** )( UserKInfo[ KINX_APISETS ] );
    CINFO* win32_api = api_sets[ SH_WIN32 ];
 
    PFNVOID pfnHook_GetTickCount = ( PFNVOID )Hook_GetTickCount;
 
    // swap the usual GetTickCount() with our Hook_GetTickCount()
    SwapPFN( &win32_api->m_ppMethods[ W32_GetTickCount ], &pfnHook_GetTickCount );
    NKDbgPrintfW( L"Hooked: %d\r\n", ::GetTickCount() );
 
    // restore the original GetTickCount()
    SwapPFN( &win32_api->m_ppMethods[ W32_GetTickCount ], &pfnHook_GetTickCount );
    NKDbgPrintfW( L"Unhooked: %d\r\n", ::GetTickCount() );
 
    // restore our original permissions
    ::SetProcPermissions( old_permissions );
    ::SetKMode( FALSE );
    return 0;
}
 
For me, this prints:
 
Hooked: 12345
Unhooked: 2596716
 
Unfortunately, the reason this is easy is because it's incomplete. While this will work for your process, any other process that tries to call GetTickCount() while you've hooked it will crash and burn. Why? Because the function pointer address we put in the kernel API table is local to our process. Other processes can't access memory in our process.
 
The solution to that little conundrum will be posted soon!
 
Enjoy!
PaulH

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Paul Heil
Software Developer (Senior) An engineering firm in Cedar Rapids, Iowa
United States United States
I'm also on the MSDN forums
http://social.msdn.microsoft.com/profile/paulh79

Comments and Discussions

 
Generalnice... Pinmemberalexquisi25-Nov-10 3:17 
GeneralRe: nice... PinmemberPaul Heil3-Dec-10 5:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 13 Nov 2010
Article Copyright 2010 by Paul Heil
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid