mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-28 17:38:43 +00:00
277 lines
8.6 KiB
C
277 lines
8.6 KiB
C
/**
|
|
* Author......: See docs/credits.txt
|
|
* License.....: MIT
|
|
*/
|
|
|
|
#include "common.h"
|
|
#include "types.h"
|
|
#include "memory.h"
|
|
#include "event.h"
|
|
#include "shared.h"
|
|
#include "modules.h"
|
|
#include "backend.h"
|
|
#include "dynloader.h"
|
|
#include "bridges.h"
|
|
#include "interface.h"
|
|
|
|
/**
|
|
* parsing
|
|
*/
|
|
|
|
int bridge_filename (const folder_config_t *folder_config, const char *bridge_name, char *out_buf, const size_t out_size)
|
|
{
|
|
// native compiled
|
|
#if defined (_WIN) || defined (__CYGWIN__)
|
|
return snprintf (out_buf, out_size, "%s/bridges/bridge_%s.dll", folder_config->shared_dir, bridge_name);
|
|
#else
|
|
return snprintf (out_buf, out_size, "%s/bridges/bridge_%s.so", folder_config->shared_dir, bridge_name);
|
|
#endif
|
|
}
|
|
|
|
bool bridge_load (hashcat_ctx_t *hashcat_ctx, bridge_ctx_t *bridge_ctx, const char *bridge_name)
|
|
{
|
|
const folder_config_t *folder_config = hashcat_ctx->folder_config;
|
|
|
|
char *bridge_file = (char *) hcmalloc (HCBUFSIZ_TINY);
|
|
|
|
bridge_filename (folder_config, bridge_name, bridge_file, HCBUFSIZ_TINY);
|
|
|
|
struct stat s;
|
|
|
|
memset (&s, 0, sizeof (struct stat));
|
|
|
|
if (stat (bridge_file, &s) == -1)
|
|
{
|
|
event_log_warning (hashcat_ctx, "The bridge plugin '%s' couldn't be found.", bridge_file);
|
|
event_log_warning (hashcat_ctx, NULL);
|
|
}
|
|
|
|
bridge_ctx->bridge_handle = hc_dlopen (bridge_file);
|
|
|
|
if (bridge_ctx->bridge_handle == NULL)
|
|
{
|
|
#if defined (_WIN)
|
|
event_log_error (hashcat_ctx, "Cannot load bridge %s", bridge_file); // todo: maybe there's a dlerror () equivalent
|
|
#else
|
|
event_log_error (hashcat_ctx, "%s", dlerror ());
|
|
#endif
|
|
|
|
return false;
|
|
}
|
|
|
|
bridge_ctx->bridge_init = (BRIDGE_INIT) hc_dlsym (bridge_ctx->bridge_handle, "bridge_init");
|
|
|
|
if (bridge_ctx->bridge_init == NULL)
|
|
{
|
|
event_log_error (hashcat_ctx, "Cannot load symbol 'bridge_init' in bridge %s", bridge_file);
|
|
|
|
return false;
|
|
}
|
|
|
|
hcfree (bridge_file);
|
|
|
|
return true;
|
|
}
|
|
|
|
void bridge_unload (bridge_ctx_t *bridge_ctx)
|
|
{
|
|
if (bridge_ctx->bridge_handle)
|
|
{
|
|
hc_dlclose (bridge_ctx->bridge_handle);
|
|
}
|
|
}
|
|
|
|
bool bridges_init (hashcat_ctx_t *hashcat_ctx)
|
|
{
|
|
bridge_ctx_t *bridge_ctx = hashcat_ctx->bridge_ctx;
|
|
user_options_t *user_options = hashcat_ctx->user_options;
|
|
hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
|
|
|
|
if (user_options->backend_info > 0) return true;
|
|
if (user_options->hash_info > 0) return true;
|
|
if (user_options->usage > 0) return true;
|
|
if (user_options->left == true) return true;
|
|
if (user_options->show == true) return true;
|
|
if (user_options->version == true) return true;
|
|
|
|
// There is a problem here. At this point, hashconfig is not yet initialized.
|
|
// This is because initializing hashconfig requires the module to be loaded,
|
|
// but in order to load the module, we need to know the backend devices.
|
|
// However, the backend devices are also not yet initialized, because
|
|
// they require the virtualization count, which we only determine here.
|
|
// To break this chicken-and-egg problem, we cheat by quick-loading the module
|
|
// and unloading it afterwards, so it can be properly initialized later.
|
|
|
|
const int hashconfig_init_rc = hashconfig_init (hashcat_ctx);
|
|
|
|
if (hashconfig_init_rc == -1) return false;
|
|
|
|
// ok, we can start
|
|
|
|
if (hashconfig->bridge_type == BRIDGE_TYPE_NONE)
|
|
{
|
|
hashconfig_destroy (hashcat_ctx);
|
|
|
|
return true;
|
|
}
|
|
|
|
bridge_ctx->enabled = true;
|
|
|
|
// finally, the real stuff
|
|
|
|
const bool rc_load = bridge_load (hashcat_ctx, bridge_ctx, hashconfig->bridge_name);
|
|
|
|
if (rc_load == false) return false;
|
|
|
|
bridge_ctx->bridge_init (bridge_ctx);
|
|
|
|
if (bridge_ctx->bridge_context_size != BRIDGE_CONTEXT_SIZE_CURRENT)
|
|
{
|
|
event_log_error (hashcat_ctx, "bridge context size is invalid. Old template?");
|
|
|
|
return false;
|
|
}
|
|
|
|
if (bridge_ctx->bridge_interface_version < BRIDGE_INTERFACE_VERSION_MINIMUM)
|
|
{
|
|
event_log_error (hashcat_ctx, "bridge interface version is outdated, please compile");
|
|
|
|
return false;
|
|
}
|
|
|
|
// check for missing pointer assignements
|
|
|
|
#define CHECK_DEFINED(func) \
|
|
if ((func) == NULL) \
|
|
{ \
|
|
event_log_error (hashcat_ctx, "Missing symbol definitions in bridge '%s'. Old template?", hashconfig->bridge_name); \
|
|
\
|
|
return false; \
|
|
}
|
|
|
|
CHECK_DEFINED (bridge_ctx->platform_init);
|
|
CHECK_DEFINED (bridge_ctx->platform_term);
|
|
CHECK_DEFINED (bridge_ctx->get_unit_count);
|
|
CHECK_DEFINED (bridge_ctx->get_unit_info);
|
|
CHECK_DEFINED (bridge_ctx->get_workitem_count);
|
|
CHECK_DEFINED (bridge_ctx->thread_init);
|
|
CHECK_DEFINED (bridge_ctx->thread_term);
|
|
CHECK_DEFINED (bridge_ctx->salt_prepare);
|
|
CHECK_DEFINED (bridge_ctx->salt_destroy);
|
|
CHECK_DEFINED (bridge_ctx->launch_loop);
|
|
CHECK_DEFINED (bridge_ctx->launch_loop2);
|
|
CHECK_DEFINED (bridge_ctx->st_update_hash);
|
|
CHECK_DEFINED (bridge_ctx->st_update_pass);
|
|
|
|
#undef CHECK_DEFINED
|
|
|
|
// mandatory functions check
|
|
|
|
#define CHECK_MANDATORY(func) \
|
|
if ((func) == MODULE_DEFAULT) \
|
|
{ \
|
|
event_log_error (hashcat_ctx, "Missing mandatory symbol definitions"); \
|
|
\
|
|
return false; \
|
|
}
|
|
|
|
CHECK_MANDATORY (bridge_ctx->platform_init);
|
|
CHECK_MANDATORY (bridge_ctx->platform_term);
|
|
CHECK_MANDATORY (bridge_ctx->get_unit_count);
|
|
CHECK_MANDATORY (bridge_ctx->get_unit_info);
|
|
CHECK_MANDATORY (bridge_ctx->get_workitem_count);
|
|
|
|
if (hashconfig->bridge_type & BRIDGE_TYPE_REPLACE_LOOP) CHECK_MANDATORY (bridge_ctx->launch_loop);
|
|
if (hashconfig->bridge_type & BRIDGE_TYPE_REPLACE_LOOP2) CHECK_MANDATORY (bridge_ctx->launch_loop2);
|
|
if (hashconfig->bridge_type & BRIDGE_TYPE_LAUNCH_LOOP) CHECK_MANDATORY (bridge_ctx->launch_loop);
|
|
if (hashconfig->bridge_type & BRIDGE_TYPE_LAUNCH_LOOP2) CHECK_MANDATORY (bridge_ctx->launch_loop2);
|
|
|
|
#undef CHECK_MANDATORY
|
|
|
|
bridge_ctx->platform_context = bridge_ctx->platform_init (user_options);
|
|
|
|
if (bridge_ctx->platform_context == NULL)
|
|
{
|
|
event_log_error (hashcat_ctx, "Platform initialization failed");
|
|
|
|
return false;
|
|
}
|
|
|
|
// auto adjust workitem counts
|
|
|
|
if (hashconfig->bridge_type & BRIDGE_TYPE_MATCH_TUNINGS)
|
|
{
|
|
if ((hashconfig->opts_type & OPTS_TYPE_NATIVE_THREADS) == 0)
|
|
{
|
|
event_log_error (hashcat_ctx, "BRIDGE_TYPE_MATCH_TUNINGS requires OPTS_TYPE_NATIVE_THREADS");
|
|
|
|
return false;
|
|
}
|
|
|
|
if ((hashconfig->opts_type & OPTS_TYPE_MP_MULTI_DISABLE) == 0)
|
|
{
|
|
event_log_error (hashcat_ctx, "BRIDGE_TYPE_MATCH_TUNINGS requires OPTS_TYPE_MP_MULTI_DISABLE");
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// clean up
|
|
|
|
hashconfig_destroy (hashcat_ctx);
|
|
|
|
return true;
|
|
}
|
|
|
|
void bridges_destroy (hashcat_ctx_t *hashcat_ctx)
|
|
{
|
|
bridge_ctx_t *bridge_ctx = hashcat_ctx->bridge_ctx;
|
|
|
|
if (bridge_ctx->enabled == false) return;
|
|
|
|
bridge_ctx->platform_term (bridge_ctx->platform_context);
|
|
|
|
bridge_unload (bridge_ctx);
|
|
}
|
|
|
|
bool bridges_salt_prepare (hashcat_ctx_t *hashcat_ctx)
|
|
{
|
|
bridge_ctx_t *bridge_ctx = hashcat_ctx->bridge_ctx;
|
|
hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
|
|
hashes_t *hashes = hashcat_ctx->hashes;
|
|
user_options_t *user_options = hashcat_ctx->user_options;
|
|
|
|
if (user_options->backend_info > 0) return true;
|
|
if (user_options->hash_info > 0) return true;
|
|
if (user_options->usage > 0) return true;
|
|
if (user_options->left == true) return true;
|
|
if (user_options->show == true) return true;
|
|
if (user_options->version == true) return true;
|
|
|
|
if (bridge_ctx->enabled == false) return true;
|
|
|
|
if (bridge_ctx->salt_prepare == MODULE_DEFAULT) return true;
|
|
|
|
if (bridge_ctx->salt_prepare (bridge_ctx->platform_context, hashconfig, hashes) == false)
|
|
{
|
|
event_log_error (hashcat_ctx, "Couldn't prepare salt specific data in bridge");
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void bridges_salt_destroy (hashcat_ctx_t *hashcat_ctx)
|
|
{
|
|
bridge_ctx_t *bridge_ctx = hashcat_ctx->bridge_ctx;
|
|
hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
|
|
hashes_t *hashes = hashcat_ctx->hashes;
|
|
|
|
if (bridge_ctx->enabled == false) return;
|
|
|
|
if (bridge_ctx->salt_destroy == MODULE_DEFAULT) return;
|
|
|
|
bridge_ctx->salt_destroy (bridge_ctx->platform_context, hashconfig, hashes);
|
|
}
|