📄 shellinj.c
字号:
#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 + -