⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shellinj.c

📁 这是一本学习 window编程的很好的参考教材
💻 C
📖 第 1 页 / 共 2 页
字号:
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <objbase.h> /* included for decl. of COM types */
#include <shlobj.h>  /* included for decl. of SHLoadInProc */
#include <assert.h>  /* included for assert(), a debugging tool */
#include "shellinj.h"


/****** function prototypes ******/
STDAPI DllCanUnloadNow( void );
STDAPI DllGetClassObject(REFCLSID, REFIID, void**);
STDAPI DllRegisterServer( void );
STDAPI DllUnregisterServer( void );


/****** globals and constants ******/

HMODULE g_hModule = NULL;

const char szFriendlyName[] = "Shell-Injected COM Object";

#ifdef __cplusplus
extern "C"
#endif
           const CLSID CLSID_ShellInjector =
       { 0x6CEF2AA0, 0x4AE3, 0x11D1,
       { 0xAA, 0x87, 0x00, 0x20, 0xAF, 0x46, 0x1E, 0x3C} };


/****** Shared Memory-Map Functions ******/
/*  These utility functions are called internally by both
    processes. They maintain a synchronized memory block
    shared between the shell's address space and the user's. */

#define MAX_SHELLINJ_CLIENTS  64 /* this is an arbitrary # */

typedef struct tag_SharedMemory
{
    HWND hShellHookCatcher; //handle of subclassed shell win
    int nUsers;    //# of apps that called SIStartup()
    int nClientWnds;//nWnds added with SIAddClientWindow()
    RECT rMinRect; //used while processing shell msg
    HWND hClientWnds[MAX_SHELLINJ_CLIENTS];
    UINT wmClientMsgs[MAX_SHELLINJ_CLIENTS];
} SharedMemory;


/* shared-mem-map variables (each process has a copy) */
static HANDLE hMemMapMutex;
static HANDLE hMemMap;
static void *pMemMapView;
static int LocalRecurseCount; /* an anti-bugging tool */


SharedMemory *GetSharedMemPtr( void )
{
    LocalRecurseCount++;
    if (LocalRecurseCount == 1)
        WaitForSingleObject(hMemMapMutex, INFINITE);
    assert(pMemMapView != NULL);
    return (SharedMemory*)pMemMapView;
}


void ReleaseSharedMemPtr( void )
{
    LocalRecurseCount--;
    if (LocalRecurseCount == 0)
      ReleaseMutex(hMemMapMutex);
}


void SetupSharedMemMap( void )
{
    BOOL bExists;
    hMemMapMutex = CreateMutex(NULL, FALSE, "SI_Mutex");
    hMemMap = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
        PAGE_READWRITE, 0, sizeof(SharedMemory), "SI_MemMap");
    bExists = (GetLastError() == ERROR_ALREADY_EXISTS);
    pMemMapView = MapViewOfFile(hMemMap, FILE_MAP_ALL_ACCESS,
                              0, 0, sizeof(SharedMemory));
    LocalRecurseCount = 0;
    if (!bExists) //init shared memory to all 0's
    {
        SharedMemory* pInfo = GetSharedMemPtr();
        ZeroMemory(pInfo, sizeof(SharedMemory));
        ReleaseSharedMemPtr();
    }
}


void ShutdownSharedMemMap( void )
{
    assert(LocalRecurseCount == 0);
    UnmapViewOfFile(pMemMapView);
    CloseHandle(hMemMap);
    CloseHandle(hMemMapMutex);
}


/****** API Functions ******/

#ifdef __cplusplus
#  define REFERENCE(n)  n
#else
#  define REFERENCE(n)  &n
#endif

/*  These functions implement the external API. They are never
    called from within the shell's process, only the user's. */


STDAPI_(BOOL) SIStartup()
{
    HRESULT hres;
    DllRegisterServer();
    hres = SHLoadInProc( REFERENCE(CLSID_ShellInjector) );
    if (hres == CLASS_E_CLASSNOTAVAILABLE)  {
        SharedMemory *pMem;
        SetupSharedMemMap();
        pMem = GetSharedMemPtr();
        pMem->nUsers++;
        ReleaseSharedMemPtr();
        return TRUE;
    }
    else
        return FALSE;
}


STDAPI_(void) SIShutdown()
{
    /*send the subclassed shell window a message. it means "a
      client has ended, consider un-subclassing the shell" */
    UINT wmDecCount = RegisterWindowMessage("SI_DEC");
    SharedMemory *pMem = GetSharedMemPtr();
    HWND h = pMem->hShellHookCatcher;
    pMem->nUsers--;
    ReleaseSharedMemPtr();
    ShutdownSharedMemMap();
    PostMessage(h, wmDecCount, 0, 0);
}


STDAPI_(BOOL) SIAddClientWindow(HWND hWnd, UINT wmMsg)
{
    BOOL bAddedWndToList = FALSE;
    SharedMemory* pInfo = GetSharedMemPtr();
    if (pInfo->nClientWnds < MAX_SHELLINJ_CLIENTS)  {
        pInfo->hClientWnds[pInfo->nClientWnds] = hWnd;
        pInfo->wmClientMsgs[pInfo->nClientWnds++] = wmMsg;
        bAddedWndToList = TRUE;
    }
    ReleaseSharedMemPtr();
    return bAddedWndToList;
}


STDAPI_(BOOL) SIRemoveClientWindow(HWND hWnd)
{
    int loop;
    BOOL bFoundWndInList = FALSE;
    SharedMemory* pInfo = GetSharedMemPtr();
    for (loop = 0; loop < pInfo->nClientWnds; loop++)
        if (pInfo->hClientWnds[loop] == hWnd)  {
            pInfo->hClientWnds[loop] =
                 pInfo->hClientWnds[pInfo->nClientWnds-1];
            pInfo->wmClientMsgs[loop] =
                 pInfo->wmClientMsgs[pInfo->nClientWnds-1];
            pInfo->nClientWnds--;
            bFoundWndInList = TRUE;
            break;
        }
    ReleaseSharedMemPtr();
    return bFoundWndInList;
}


STDAPI_(void) SIGetMinRect(RECT *pRect)
{
    SharedMemory *pMem = GetSharedMemPtr();
    *pRect = pMem->rMinRect;
    ReleaseSharedMemPtr();
}


/****** Shell-Manipulation Code ******/
/*  The code in this section is called from within the shell's
    address space. */


/*  GetShellWnd: a utility function that finds shell windows
    by examining their class names. It takes a string of
    semicolon-separated class names; it searches for an HWND
    that has the first name, then it searches that window's
    children for an HWND with the 2nd name in the list, etc. */
HWND GetShellWnd(const char *pClasses)
{
    HWND h = NULL;

    while (*pClasses)  {
        char Buffer[512], *pBuffer = Buffer;
        while (*pClasses && (*pClasses != ';'))
            *pBuffer++ = *pClasses++;
        *pBuffer = '\0';
        if (*pClasses == ';')
            pClasses++;

        h = FindWindowEx(h, NULL, Buffer, NULL);
        if (h == NULL)
            return NULL;
    }
    return h;
}


/* shell-subclassing variables */
static LONG g_OrgShellWndProc = 0;
static BOOL g_bShellSubclassed = FALSE;
static UINT wm_ShellHook, wm_DecCount;


void UnsubclassShell( void ); /*function prototype */


/*the "new" wndproc for the subclassed shell window */
LRESULT CALLBACK ShellHookCatcher(HWND hWnd, UINT Msg,
                          WPARAM wParam, LPARAM lParam)
{
    int loop;
    if (Msg == WM_DESTROY) /* forcibly un-subclass window */
        UnsubclassShell();

    if (Msg == wm_ShellHook)  {
        /* make a local copy of the SharedMemory struct */
        SharedMemory *pGlobalCopy = GetSharedMemPtr();
        SharedMemory MyCopy = *pGlobalCopy;
        ReleaseSharedMemPtr();

        /* special case: if processing HSHELL_GETMINRECT,
           need to find out where the shell will end up
           placing the rect. So call shell's proc FIRST. */
        if (wParam == HSHELL_GETMINRECT)  {
            LRESULT BaseClassResult = CallWindowProc(
                           (WNDPROC)g_OrgShellWndProc, hWnd,
                           Msg, wParam, lParam);
            /* this message is unique in that lParam is a ptr
               to a structure. */
            typedef struct tagInternalShellStruct
            {
                HWND hWin;
                SMALL_RECT MinRect;
            } InternalShellStruct;
            InternalShellStruct *p = (InternalShellStruct*)lParam;

            SharedMemory *pGlobalCopy = GetSharedMemPtr();
            /* Note that shell-procs really use a SMALL_RECT
               for this param, not a RECT (as the docs say).
               This window also receives a SMALL_RECT. But
               I manually put the SMALL_RECT into a RECT,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -