-
Notifications
You must be signed in to change notification settings - Fork 3
/
OnInjection.c
121 lines (103 loc) · 3.55 KB
/
OnInjection.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "OnInjection.h"
#include <windows.h>
#include <stdio.h>
#include "UAC.h"
#include "Client.h"
#include "ClientList.h"
//#include "COMBase.h"
#include "COMInjector.h"
//The onInjection function below is exported and used as entrypoint after injection on a remote process
volatile unsigned int initialized=0;
HHOOK hMsgHook=0;
IUnknown * clientlist_object=0;
LRESULT CALLBACK MsgHook(int code, WPARAM wParam, LPARAM lParam)
{
MSG * pMsg;
COMClass * clientclass;
DISPPARAMS * pars;
pMsg=(MSG *)lParam;
switch(pMsg->message)
{
case WM_QUIT:
if((clientclass=FindClass((GUID *)&CLSID_Client))&&(clientclass->activeobject!=0))
{
//invoke onClose event
pars=DispStack(1);
DispPush(pars, VObject(clientclass->activeobject));
InvokeEvent((COMObject *)(clientclass->activeobject), 1, pars, 0);
//get client list, unregister self
if(clientlist_object)
{
//Invoke ClientList->UnregisterClient(...)
pars=DispStack(1);
DispPush(pars, VObject((IUnknown *)clientclass->activeobject));
DoInvoke(clientlist_object, 3, pars, 0);
//release ClientList
clientlist_object->lpVtbl->Release(clientlist_object);
clientlist_object=0;
}
}
break;
default:
break;
}
return CallNextHookEx(0, code, wParam, lParam);
}
//Entry Point after injection of this dll into a client's process:
// - we need to setup the Client's COM interface
// - callibration is done remotely, and passed through the parametr of this function
// - the Client interface is to be an active object (we don't want multiple instances, we are on one specific client process at the moment)
// - we need to register that interface with the client list, so we obtain the client list object (which is a remote one, on a surrogate process)
// -
void OnInjection(OnInjectionParameters * parameters)
{
COMClass * clientclass;
Client * clientobject;
DISPPARAMS * pars;
HRESULT hr;
if(InterlockedCompareExchange(&initialized, 1, 0)==0)
{
//initialize COM
if(InitializeCOM())
{
//#if 0
//debug version : open a console and print the parameters
if(AllocConsole())
{
freopen("CONIN$","rb",stdin);
freopen("CONOUT$","wb",stdout);
freopen("CONOUT$","wb",stderr);
}
//#endif
if(clientclass=FindClass((GUID *)&CLSID_Client))
{
SetCallibrations(&(parameters->callibrations));
//setup injected client COM object
clientobject=(Client *)ConstructObject(clientclass);
SetActiveObject(clientclass, (IUnknown *)clientobject);
DefaultRelease((COMObject *)clientobject);//as activeobject it is kept alive
//get clientlist, register self, note that if the app accessing the client is running as admin, we need to confirm the admin rights here (can be annoying)
if((parameters->requireadminrights)&&(IsUserAdmin()==0))
hr=CoCreateInstanceAsAdmin(&CLSID_ClientList, &IID_IUnknown, (void **)&clientlist_object);
else
hr=CoCreateInstance(&CLSID_ClientList, 0, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void **)&clientlist_object);
if(hr==S_OK)
{
//invoke ClientList->RegisterClient(...)
pars=DispStack(1);
DispPush(pars, VObject((IUnknown *)clientobject));
DoInvoke(clientlist_object, 2, pars, 0);
}
else
printf("clientlist could not be obtained!\n");
//need msg-hook (for WM_CLOSE)
hMsgHook=SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MsgHook, 0, parameters->tid);
}
}
else
printf("COM initialization failure!\n");
}
else
printf("duplicate injection\n");
return;
}