1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-12-21 05:35:54 +01:00
metasploit-payloads/c/meterpreter/source/client/module.c

164 lines
3.2 KiB
C

#include "metcli.h"
typedef struct _ClientModule
{
LPSTR name;
LPSTR path;
HMODULE handle;
struct _ClientModule *prev;
struct _ClientModule *next;
} ClientModule;
ClientModule *clientModules = NULL;
/*
* Load and initialize a client module
*/
DWORD module_load_client(Remote *remote, LPCSTR name, LPCSTR path)
{
ClientModule *current = NULL;
DWORD res = ERROR_SUCCESS;
DWORD (*init)(Remote *remote);
do
{
// Allocate storage for tracking the module
if (!(current = (ClientModule *)malloc(sizeof(ClientModule))))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Zero the buffer
memset(current, 0, sizeof(ClientModule));
current->name = _strdup(name);
current->path = _strdup(path);
// Duplication of name/path failed?
if ((!current->name) || (!current->path))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Try to load the library from the supplied path
if (!(current->handle = LoadLibrary(current->path)))
{
res = GetLastError();
break;
}
// Try to find the initialization entry point
if (!(init = (DWORD (*)(Remote *))GetProcAddress(current->handle,
"InitClientExtension")))
{
res = GetLastError();
break;
}
// Initialize the module
init(remote);
// Add the new module to the list
if (clientModules)
clientModules->prev = current;
current->next = clientModules;
clientModules = current;
} while (0);
// Clean up on failure
if (res != ERROR_SUCCESS)
{
if (current)
{
if (current->path)
free(current->path);
if (current->name)
free(current->name);
free(current);
}
}
return res;
}
/*
* Enumerate the list of modules, returning a pointer to the name at
* the given index in the output parameter
*/
DWORD module_enumerate_client(DWORD index, LPCSTR *name)
{
ClientModule *current;
DWORD cindex = 0;
DWORD res = ERROR_SUCCESS;
for (current = clientModules, cindex = 0;
cindex < index && current;
cindex++, current = current->next);
if (current)
*name = current->name;
else
res = ERROR_NOT_FOUND;
return res;
}
/*
* Unload a previously loaded module of a given name
*/
DWORD module_unload_client(Remote *remote, LPCSTR name)
{
ClientModule *current = NULL, *prev = NULL;
DWORD (*deinit)(Remote *remote);
DWORD res = ERROR_SUCCESS;
do
{
// Try to locate the module
for (current = clientModules;
current;
prev = current, current = current->next)
{
if (!strcmp(current->name, name))
break;
}
// Not located?
if (!current)
{
res = ERROR_NOT_FOUND;
break;
}
// Remove the module from the list
if (prev)
prev->next = current->next;
else
clientModules = current->next;
if (current->next)
current->next->prev = prev;
// Call the module's deinitialization routine if it exports one
if ((deinit = (DWORD (*)(Remote *))GetProcAddress(current->handle,
"DeinitClientExtension")))
deinit(remote);
// Deallocate & unload the module
FreeLibrary(current->handle);
free(current->path);
free(current->name);
free(current);
} while (0);
return res;
}