/*! * @brief Load any stageless extensions that might be present in the current payload. * @param remote Pointer to the remote instance. * @param fd The socket descriptor passed to metsrv during intialisation. */ VOID load_stageless_extensions(Remote* remote, MetsrvExtension* stagelessExtensions) { while (stagelessExtensions->size > 0) { dprintf("[SERVER] Extension located at 0x%p: %u bytes", stagelessExtensions->dll, stagelessExtensions->size); HMODULE hLibrary = LoadLibraryR(stagelessExtensions->dll, stagelessExtensions->size); load_extension(hLibrary, TRUE, remote, NULL, extensionCommands); stagelessExtensions = (MetsrvExtension*)((LPBYTE)stagelessExtensions->dll + stagelessExtensions->size); } dprintf("[SERVER] All stageless extensions loaded"); // once we have reached the end, we may have extension initializers LPBYTE initData = (LPBYTE)(&stagelessExtensions->size) + sizeof(stagelessExtensions->size); while (initData != NULL && *initData != '\0') { const char* extensionName = (const char*)initData; LPBYTE data = initData + strlen(extensionName) + 1 + sizeof(DWORD); DWORD dataSize = *(DWORD*)(data - sizeof(DWORD)); dprintf("[STAGELESS] init data at %p, name %s, size is %d", extensionName, extensionName, dataSize); stagelessinit_extension(extensionName, data, dataSize); initData = data + dataSize; } dprintf("[SERVER] All stageless extensions initialised"); }
struct xtables_target * xtables_find_target(const char *name, enum xtables_tryload tryload) { struct xtables_target **dptr; struct xtables_target *ptr; /* Standard target? */ if (strcmp(name, "") == 0 || strcmp(name, XTC_LABEL_ACCEPT) == 0 || strcmp(name, XTC_LABEL_DROP) == 0 || strcmp(name, XTC_LABEL_QUEUE) == 0 || strcmp(name, XTC_LABEL_RETURN) == 0) name = "standard"; /* Trigger delayed initialization */ for (dptr = &xtables_pending_targets; *dptr; ) { if (strcmp(name, (*dptr)->name) == 0) { ptr = *dptr; *dptr = (*dptr)->next; ptr->next = NULL; xtables_fully_register_pending_target(ptr); } else { dptr = &((*dptr)->next); } } for (ptr = xtables_targets; ptr; ptr = ptr->next) { if (strcmp(name, ptr->name) == 0) break; } #ifndef NO_SHARED_LIBS if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { ptr = load_extension(xtables_libdir, afinfo->libprefix, name, true); if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't load target `%s':%s\n", name, strerror(errno)); } #else if (ptr && !ptr->loaded) { if (tryload != XTF_DONT_LOAD) ptr->loaded = 1; else ptr = NULL; } if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) { xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't find target `%s'\n", name); } #endif if (ptr) ptr->used = 1; return ptr; }
struct xtables_match * xtables_find_match(const char *name, enum xtables_tryload tryload, struct xtables_rule_match **matches) { struct xtables_match **dptr; struct xtables_match *ptr; const char *icmp6 = "icmp6"; if (strlen(name) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid match name \"%s\" (%u chars max)", name, XT_EXTENSION_MAXNAMELEN - 1); /* This is ugly as hell. Nonetheless, there is no way of changing * this without hurting backwards compatibility */ if ( (strcmp(name,"icmpv6") == 0) || (strcmp(name,"ipv6-icmp") == 0) || (strcmp(name,"icmp6") == 0) ) name = icmp6; /* Trigger delayed initialization */ for (dptr = &xtables_pending_matches; *dptr; ) { if (strcmp(name, (*dptr)->name) == 0) { ptr = *dptr; *dptr = (*dptr)->next; ptr->next = NULL; xtables_fully_register_pending_match(ptr); } else { dptr = &((*dptr)->next); } } for (ptr = xtables_matches; ptr; ptr = ptr->next) { if (strcmp(name, ptr->name) == 0) { struct xtables_match *clone; /* First match of this type: */ if (ptr->m == NULL) break; /* Second and subsequent clones */ clone = xtables_malloc(sizeof(struct xtables_match)); memcpy(clone, ptr, sizeof(struct xtables_match)); clone->udata = NULL; clone->mflags = 0; /* This is a clone: */ clone->next = clone; ptr = clone; break; } } #ifndef NO_SHARED_LIBS if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { ptr = load_extension(xtables_libdir, afinfo->libprefix, name, false); if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't load match `%s':%s\n", name, strerror(errno)); } #else if (ptr && !ptr->loaded) { if (tryload != XTF_DONT_LOAD) ptr->loaded = 1; else ptr = NULL; } if(!ptr && (tryload == XTF_LOAD_MUST_SUCCEED)) { xt_params->exit_err(PARAMETER_PROBLEM, "Couldn't find match `%s'\n", name); } #endif if (ptr && matches) { struct xtables_rule_match **i; struct xtables_rule_match *newentry; newentry = xtables_malloc(sizeof(struct xtables_rule_match)); for (i = matches; *i; i = &(*i)->next) { if (strcmp(name, (*i)->match->name) == 0) (*i)->completed = true; } newentry->match = ptr; newentry->completed = false; newentry->next = NULL; *i = newentry; } return ptr; }
/* * core_loadlib * ------------ * * Load a library into the address space of the executing process. * * TLVs: * * req: TLV_TYPE_LIBRARY_PATH -- The path of the library to load. * req: TLV_TYPE_FLAGS -- Library loading flags. * opt: TLV_TYPE_TARGET_PATH -- The contents of the library if uploading. * opt: TLV_TYPE_DATA -- The contents of the library if uploading. * * TODO: * * - Implement in-memory library loading */ DWORD request_core_loadlib(Remote *pRemote, Packet *pPacket) { Packet *response = packet_create_response(pPacket); DWORD res = ERROR_SUCCESS; HMODULE library; PCHAR libraryPath; DWORD flags = 0; BOOL bLibLoadedReflectivly = FALSE; Command *first = extensionCommands; do { libraryPath = packet_get_tlv_value_string(pPacket, TLV_TYPE_LIBRARY_PATH); flags = packet_get_tlv_value_uint(pPacket, 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(pPacket, TLV_TYPE_DATA, &dataTlv) != ERROR_SUCCESS) || (!(targetPath = packet_get_tlv_value_string(pPacket, 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 = LoadLibraryA(libraryPath))) { res = GetLastError(); } // If this library is supposed to be an extension library, try to // call its Init routine if ((flags & LOAD_LIBRARY_FLAG_EXTENSION) && library) { res = load_extension(library, bLibLoadedReflectivly, pRemote, response, first); } } while (0); if (response) { packet_transmit_response(res, pRemote, response); } return res; }
void scm_c_load_extension (const char *lib, const char *init) { load_extension (scm_from_locale_string (lib), scm_from_locale_string (init)); }