mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-04 13:52:40 +00:00
1178 lines
40 KiB
C
1178 lines
40 KiB
C
/**
|
|
* Author......: See docs/credits.txt
|
|
* License.....: MIT
|
|
*/
|
|
|
|
#include "common.h"
|
|
#include "types.h"
|
|
#include "bridges.h"
|
|
#include "memory.h"
|
|
#include "shared.h"
|
|
#include "dynloader.h"
|
|
|
|
#if defined (_WIN)
|
|
#include "processenv.h"
|
|
#endif
|
|
|
|
// python interpreter
|
|
|
|
#define PY_SSIZE_T_CLEAN
|
|
|
|
#undef _GNU_SOURCE
|
|
#include <Python.h>
|
|
|
|
#define PYTHON_API_CALL
|
|
|
|
typedef void (PYTHON_API_CALL *PY_INITIALIZE) ();
|
|
typedef void (PYTHON_API_CALL *PY_FINALIZE) ();
|
|
typedef void (PYTHON_API_CALL *PY_DECREF) (PyObject *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYBOOL_FROMLONG) (long);
|
|
typedef PyObject *(PYTHON_API_CALL *PYBYTES_FROMSTRINGANDSIZE) (const char *, Py_ssize_t);
|
|
typedef int (PYTHON_API_CALL *PYDICT_DELITEMSTRING) (PyObject *, const char *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYDICT_GETITEMSTRING) (PyObject *, const char *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYDICT_NEW) ();
|
|
typedef int (PYTHON_API_CALL *PYDICT_SETITEMSTRING) (PyObject *, const char *, PyObject *);
|
|
typedef void (PYTHON_API_CALL *PYERR_PRINT) ();
|
|
typedef PyObject *(PYTHON_API_CALL *PYIMPORT_IMPORTMODULE) (const char *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYIMPORT_IMPORT) (PyObject *);
|
|
typedef int (PYTHON_API_CALL *PYLIST_APPEND) (PyObject *, PyObject *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYLIST_GETITEM) (PyObject *, Py_ssize_t);
|
|
typedef PyObject *(PYTHON_API_CALL *PYLIST_NEW) (Py_ssize_t);
|
|
typedef int (PYTHON_API_CALL *PYLIST_SETITEM) (PyObject *, Py_ssize_t, PyObject *);
|
|
typedef Py_ssize_t (PYTHON_API_CALL *PYLIST_SIZE) (PyObject *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYLONG_FROMLONG) (long);
|
|
typedef PyObject *(PYTHON_API_CALL *PYOBJECT_CALLOBJECT) (PyObject *, PyObject *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYOBJECT_GETATTRSTRING) (PyObject *, const char *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYTUPLE_NEW) (Py_ssize_t);
|
|
typedef int (PYTHON_API_CALL *PYTUPLE_SETITEM) (PyObject *, Py_ssize_t, PyObject *);
|
|
typedef const char *(PYTHON_API_CALL *PYUNICODE_ASUTF8) (PyObject *);
|
|
typedef const char *(PYTHON_API_CALL *PYUNICODE_ASUTF8ANDSIZE) (PyObject *, Py_ssize_t *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYUNICODE_DECODEFSDEFAULTANDSIZE) (const char *, Py_ssize_t);
|
|
typedef PyObject *(PYTHON_API_CALL *PYUNICODE_DECODEFSDEFAULT) (const char *);
|
|
typedef PyObject *(PYTHON_API_CALL *PYUNICODE_FROMSTRINGANDSIZE) (const char *, Py_ssize_t);
|
|
typedef PyObject *(PYTHON_API_CALL *PYUNICODE_FROMSTRING) (const char *);
|
|
typedef void (PYTHON_API_CALL *PYEVAL_ACQUIRELOCK) (void);
|
|
typedef void (PYTHON_API_CALL *PYEVAL_RELEASELOCK) (void);
|
|
typedef PyThreadState *(PYTHON_API_CALL *PYTHREADSTATE_SWAP) (PyThreadState *);
|
|
typedef PyThreadState *(PYTHON_API_CALL *PYNEWINTERPRETER) (void);
|
|
typedef void (PYTHON_API_CALL *PYENDINTERPRETER) (PyThreadState *);
|
|
typedef PyGILState_STATE (PYTHON_API_CALL *PYGILSTATE_ENSURE) (void);
|
|
typedef void (PYTHON_API_CALL *PYGILSTATE_RELEASE) (PyGILState_STATE);
|
|
typedef void (PYTHON_API_CALL *PYEVAL_ACQUIRETHREAD) (PyThreadState *);
|
|
typedef void (PYTHON_API_CALL *PYEVAL_RELEASETHREAD) (PyThreadState *);
|
|
typedef void (PYTHON_API_CALL *PYTHREADSTATE_CLEAR) (PyThreadState *);
|
|
typedef void (PYTHON_API_CALL *PYTHREADSTATE_DELETE) (PyThreadState *);
|
|
typedef PyThreadState *(PYTHON_API_CALL *PYTHREADSTATE_NEW) (PyInterpreterState *);
|
|
typedef PyInterpreterState *(PYTHON_API_CALL *PYINTERPRETERSTATE_MAIN) (void);
|
|
typedef void (PYTHON_API_CALL *PYEVAL_INITTHREADS) (void);
|
|
typedef PyThreadState *(PYTHON_API_CALL *PYEVAL_SAVETHREAD) (void);
|
|
typedef PyStatus (PYTHON_API_CALL *PYNEWINTERPRETERFROMCONFIG) (PyThreadState **, const PyInterpreterConfig *);
|
|
typedef void (PYTHON_API_CALL *PYEXITSTATUSEXCEPTION) (PyStatus);
|
|
typedef PyStatus (PYTHON_API_CALL *PYINITIALIZEFROMCONFIG) (const PyConfig *);
|
|
typedef void (PYTHON_API_CALL *PYEVAL_RESTORETHREAD) (PyThreadState *);
|
|
typedef const char *(PYTHON_API_CALL *PYGETVERSION) (void);
|
|
|
|
typedef struct hc_python_lib
|
|
{
|
|
hc_dynlib_t lib;
|
|
|
|
PY_INITIALIZE Py_Initialize;
|
|
PY_FINALIZE Py_Finalize;
|
|
PY_DECREF Py_DecRef;
|
|
PYBOOL_FROMLONG PyBool_FromLong;
|
|
PYBYTES_FROMSTRINGANDSIZE PyBytes_FromStringAndSize;
|
|
PYDICT_DELITEMSTRING PyDict_DelItemString;
|
|
PYDICT_GETITEMSTRING PyDict_GetItemString;
|
|
PYDICT_NEW PyDict_New;
|
|
PYDICT_SETITEMSTRING PyDict_SetItemString;
|
|
PYERR_PRINT PyErr_Print;
|
|
PYIMPORT_IMPORTMODULE PyImport_ImportModule;
|
|
PYIMPORT_IMPORT PyImport_Import;
|
|
PYLIST_APPEND PyList_Append;
|
|
PYLIST_GETITEM PyList_GetItem;
|
|
PYLIST_NEW PyList_New;
|
|
PYLIST_SETITEM PyList_SetItem;
|
|
PYLIST_SIZE PyList_Size;
|
|
PYLONG_FROMLONG PyLong_FromLong;
|
|
PYOBJECT_CALLOBJECT PyObject_CallObject;
|
|
PYOBJECT_GETATTRSTRING PyObject_GetAttrString;
|
|
PYTUPLE_NEW PyTuple_New;
|
|
PYTUPLE_SETITEM PyTuple_SetItem;
|
|
PYUNICODE_ASUTF8 PyUnicode_AsUTF8;
|
|
PYUNICODE_ASUTF8ANDSIZE PyUnicode_AsUTF8AndSize;
|
|
PYUNICODE_DECODEFSDEFAULTANDSIZE PyUnicode_DecodeFSDefaultAndSize;
|
|
PYUNICODE_DECODEFSDEFAULT PyUnicode_DecodeFSDefault;
|
|
PYUNICODE_FROMSTRINGANDSIZE PyUnicode_FromStringAndSize;
|
|
PYUNICODE_FROMSTRING PyUnicode_FromString;
|
|
PYEVAL_ACQUIRELOCK PyEval_AcquireLock;
|
|
PYEVAL_RELEASELOCK PyEval_ReleaseLock;
|
|
PYTHREADSTATE_SWAP PyThreadState_Swap;
|
|
PYNEWINTERPRETER Py_NewInterpreter;
|
|
PYENDINTERPRETER Py_EndInterpreter;
|
|
PYGILSTATE_ENSURE PyGILState_Ensure;
|
|
PYGILSTATE_RELEASE PyGILState_Release;
|
|
PYEVAL_ACQUIRETHREAD PyEval_AcquireThread;
|
|
PYEVAL_RELEASETHREAD PyEval_ReleaseThread;
|
|
PYTHREADSTATE_CLEAR PyThreadState_Clear;
|
|
PYTHREADSTATE_DELETE PyThreadState_Delete;
|
|
PYTHREADSTATE_NEW PyThreadState_New;
|
|
PYINTERPRETERSTATE_MAIN PyInterpreterState_Main;
|
|
PYEVAL_INITTHREADS PyEval_InitThreads;
|
|
PYEVAL_SAVETHREAD PyEval_SaveThread;
|
|
PYNEWINTERPRETERFROMCONFIG Py_NewInterpreterFromConfig;
|
|
PYEXITSTATUSEXCEPTION Py_ExitStatusException;
|
|
PYINITIALIZEFROMCONFIG Py_InitializeFromConfig;
|
|
PYEVAL_RESTORETHREAD PyEval_RestoreThread;
|
|
PYGETVERSION Py_GetVersion;
|
|
|
|
} hc_python_lib_t;
|
|
|
|
// good: we can use this multiplier do reduce copy overhead to increase the guessing speed,
|
|
// bad: but we also increase the password candidate batch size.
|
|
// slow hashes which make use of this bridge probably are used with smaller wordlists,
|
|
// and therefore it's easier for hashcat to parallelize if this multiplier is low.
|
|
// in the end, it's a trade-off.
|
|
|
|
#define N_ACCEL 8
|
|
|
|
typedef struct
|
|
{
|
|
// input
|
|
|
|
u32 pw_buf[64];
|
|
u32 pw_len;
|
|
|
|
// output
|
|
|
|
u32 out_buf[64];
|
|
u32 out_len;
|
|
|
|
} generic_io_tmp_t;
|
|
|
|
typedef struct
|
|
{
|
|
// template
|
|
|
|
char unit_info_buf[1024];
|
|
int unit_info_len;
|
|
|
|
u64 workitem_count;
|
|
size_t workitem_size;
|
|
|
|
// implementation specific
|
|
|
|
PyThreadState *tstate;
|
|
|
|
PyObject *pArgs;
|
|
PyObject *pContext;
|
|
PyObject *pModule;
|
|
PyObject *pFunc_Init;
|
|
PyObject *pFunc_Term;
|
|
PyObject *pFunc_kernel_loop;
|
|
|
|
} unit_t;
|
|
|
|
typedef struct
|
|
{
|
|
unit_t *units_buf;
|
|
int units_cnt;
|
|
|
|
hc_python_lib_t *python;
|
|
|
|
PyThreadState *thread_state;
|
|
|
|
char *source_filename;
|
|
|
|
} python_interpreter_t;
|
|
|
|
static char *DEFAULT_SOURCE_FILENAME = "generic_hash_sp";
|
|
|
|
#if defined (_WIN)
|
|
#define DEVNULL "NUL"
|
|
#else
|
|
#define DEVNULL "/dev/null"
|
|
#endif
|
|
|
|
static int suppress_stderr (void)
|
|
{
|
|
int null_fd = open (DEVNULL, O_WRONLY);
|
|
|
|
if (null_fd < 0) return -1;
|
|
|
|
int saved_fd = dup (fileno (stderr));
|
|
|
|
if (saved_fd < 0)
|
|
{
|
|
close (null_fd);
|
|
|
|
return -1;
|
|
}
|
|
|
|
dup2 (null_fd, fileno (stderr));
|
|
|
|
close (null_fd);
|
|
|
|
return saved_fd;
|
|
}
|
|
|
|
static void restore_stderr (int saved_fd)
|
|
{
|
|
if (saved_fd < 0) return;
|
|
|
|
dup2 (saved_fd, fileno (stderr));
|
|
|
|
close (saved_fd);
|
|
}
|
|
|
|
static char *expand_pyenv_libpath (const char *prefix, const int maj, const int min)
|
|
{
|
|
char *out = NULL;
|
|
|
|
#if defined (_WIN)
|
|
const int len = asprintf (&out, "%s/python%d%dt.dll", prefix, maj, min); //untested
|
|
#elif defined (__MSYS__)
|
|
const int len = asprintf (&out, "%s/msys-python%d.%dt.dll", prefix, maj, min); //untested could be wrong
|
|
#elif defined (__APPLE__)
|
|
const int len = asprintf (&out, "%s/lib/libpython%d.%dt.dylib", prefix, maj, min); //untested
|
|
#elif defined (__CYGWIN__)
|
|
const int len = asprintf (&out, "%s/lib/python%d%dt.dll", prefix, maj, min); //untested
|
|
#else
|
|
const int len = asprintf (&out, "%s/lib/libpython%d.%dt.so", prefix, maj, min);
|
|
#endif
|
|
|
|
if (len == -1) return NULL;
|
|
|
|
struct stat st;
|
|
|
|
if (stat (out, &st) != 0)
|
|
{
|
|
free (out);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
static int resolve_pyenv_libpath (char *out_buf, const size_t out_sz)
|
|
{
|
|
// prefix
|
|
|
|
FILE *fp1 = popen ("pyenv prefix", "r");
|
|
|
|
if (fp1 == NULL) return -1;
|
|
|
|
char prefix_path[PATH_MAX];
|
|
|
|
if (fgets (prefix_path, sizeof (prefix_path), fp1) == NULL)
|
|
{
|
|
pclose (fp1);
|
|
|
|
return -1;
|
|
}
|
|
|
|
pclose (fp1);
|
|
|
|
superchop_with_length (prefix_path, strlen (prefix_path));
|
|
|
|
int maj = 0;
|
|
int min = 0;
|
|
|
|
// local
|
|
|
|
FILE *fp2 = popen ("pyenv local", "r");
|
|
|
|
if (fp2 == NULL) return -1;
|
|
|
|
if (fscanf (fp2, "%d.%d", &maj, &min) == 2)
|
|
{
|
|
pclose (fp2);
|
|
|
|
char *pyenv_libpath = expand_pyenv_libpath (prefix_path, maj, min);
|
|
|
|
if (pyenv_libpath != NULL)
|
|
{
|
|
strncpy (out_buf, pyenv_libpath, out_sz - 1);
|
|
|
|
free (pyenv_libpath);
|
|
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
pclose (fp2);
|
|
|
|
// global
|
|
|
|
FILE *fp3 = popen ("pyenv global", "r");
|
|
|
|
if (fp3 == NULL) return -1;
|
|
|
|
if (fscanf (fp3, "%d.%d", &maj, &min) == 2)
|
|
{
|
|
pclose (fp3);
|
|
|
|
char *pyenv_libpath = expand_pyenv_libpath (prefix_path, maj, min);
|
|
|
|
if (pyenv_libpath != NULL)
|
|
{
|
|
strncpy (out_buf, pyenv_libpath, out_sz - 1);
|
|
|
|
free (pyenv_libpath);
|
|
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
pclose (fp3);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static bool init_python (hc_python_lib_t *python)
|
|
{
|
|
char pythondll_path[PATH_MAX];
|
|
|
|
python->lib = NULL;
|
|
|
|
if (getenv ("PYTHON_GIL") == NULL)
|
|
putenv ((char *) "PYTHON_GIL=0");
|
|
|
|
// let's see if we have pyenv, that will save us a lot of guessing...
|
|
|
|
int saved_stderr = suppress_stderr ();
|
|
|
|
const int pyenv_rc = resolve_pyenv_libpath (pythondll_path, sizeof (pythondll_path));
|
|
|
|
restore_stderr (saved_stderr);
|
|
|
|
if (pyenv_rc == 0)
|
|
{
|
|
#if defined (_WIN)
|
|
python->lib = hc_dlopen (pythondll_path);
|
|
#elif defined (__MSYS__)
|
|
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
|
#elif defined (__APPLE__)
|
|
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
|
#elif defined (__CYGWIN__)
|
|
python->lib = hc_dlopen (pythondll_path);
|
|
#else
|
|
python->lib = dlopen (pythondll_path, RTLD_NOW | RTLD_GLOBAL);
|
|
#endif
|
|
}
|
|
|
|
#define MIN_MAJ 3
|
|
#define MAX_MAJ 8
|
|
|
|
#define MIN_MIN 0
|
|
#define MAX_MIN 50
|
|
|
|
for (int maj = MAX_MAJ; maj >= MIN_MAJ; --maj)
|
|
{
|
|
if (python->lib != NULL) break;
|
|
|
|
for (int min = MAX_MIN; min >= MIN_MIN; --min)
|
|
{
|
|
#if defined (_WIN)
|
|
|
|
// first try %LocalAppData% default path
|
|
char expandedPath[MAX_PATH - 1];
|
|
|
|
char *libpython_namelocal = NULL;
|
|
|
|
hc_asprintf (&libpython_namelocal, "%%LocalAppData%%\\Programs\\Python\\Python%d%d\\python%d%dt.dll", maj, min, maj, min);
|
|
|
|
DWORD len = ExpandEnvironmentStringsA (libpython_namelocal, expandedPath, sizeof (expandedPath));
|
|
|
|
if (len)
|
|
{
|
|
python->lib = hc_dlopen (expandedPath);
|
|
|
|
if (python->lib != NULL)
|
|
{
|
|
strncpy (pythondll_path, expandedPath, sizeof (pythondll_path) - 1);
|
|
|
|
hcfree (libpython_namelocal);
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
hcfree (libpython_namelocal);
|
|
};
|
|
}
|
|
|
|
// use %PATH%
|
|
char *libpython_namepath = NULL;
|
|
|
|
hc_asprintf (&libpython_namepath, "python%d%dt.dll", maj, min);
|
|
|
|
python->lib = hc_dlopen (libpython_namepath);
|
|
|
|
if (python->lib != NULL)
|
|
{
|
|
strncpy (pythondll_path, libpython_namepath, sizeof (pythondll_path) - 1);
|
|
|
|
hcfree (libpython_namepath);
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
hcfree (libpython_namepath);
|
|
};
|
|
|
|
#elif defined (__MSYS__)
|
|
|
|
char *libpython_name = NULL;
|
|
|
|
hc_asprintf (&libpython_name, "msys-python%d.%dt.dll", maj, min);
|
|
|
|
python->lib = dlopen (libpython_name, RTLD_NOW | RTLD_GLOBAL);
|
|
|
|
if (python->lib != NULL)
|
|
{
|
|
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
|
|
|
hcfree (libpython_name);
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
hcfree (libpython_name);
|
|
};
|
|
|
|
#elif defined (__APPLE__)
|
|
|
|
char *libpython_name = NULL;
|
|
|
|
hc_asprintf (&libpython_name, "libpython%d.%dt.dylib", maj, min);
|
|
|
|
python->lib = dlopen (libpython_name, RTLD_NOW | RTLD_GLOBAL);
|
|
|
|
if (python->lib != NULL)
|
|
{
|
|
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
|
|
|
hcfree (libpython_name);
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
hcfree (libpython_name);
|
|
};
|
|
|
|
#elif defined (__CYGWIN__)
|
|
|
|
char *libpython_name = NULL;
|
|
|
|
hc_asprintf (&libpython_name, "python%d%dt.dll", maj, min);
|
|
|
|
python->lib = hc_dlopen (libpython_name);
|
|
|
|
if (python->lib != NULL)
|
|
{
|
|
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
|
|
|
hcfree (libpython_name);
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
hcfree (libpython_name);
|
|
};
|
|
|
|
#else
|
|
|
|
char *libpython_name = NULL;
|
|
|
|
hc_asprintf (&libpython_name, "libpython%d.%dt.so", maj, min);
|
|
|
|
python->lib = dlopen (libpython_name, RTLD_NOW | RTLD_GLOBAL);
|
|
|
|
if (python->lib != NULL)
|
|
{
|
|
strncpy (pythondll_path, libpython_name, sizeof (pythondll_path) - 1);
|
|
|
|
hcfree (libpython_name);
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
hcfree (libpython_name);
|
|
};
|
|
|
|
#endif
|
|
|
|
if (python->lib != NULL) break;
|
|
}
|
|
|
|
if (python->lib != NULL) break;
|
|
}
|
|
|
|
if (python->lib == NULL)
|
|
{
|
|
fprintf (stderr, "Unable to find suitable Python library for -m 72000.\n\n");
|
|
fprintf (stderr, "Most users who encounter this error are just missing the so called 'free-threaded' library support.\n");
|
|
fprintf (stderr, "* On Windows, during install, there's an option 'free-threaded' that you need to click, it's just disabled by default.\n");
|
|
fprintf (stderr, "* On Linux, use `pyenv` and select a version that ends with a `t` (for instance `3.13t`).\n");
|
|
fprintf (stderr, " However, on Linux it's better to use -m 73000 instead. So you probably want to ignore this.\n");
|
|
fprintf (stderr, "\n");
|
|
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
printf ("Loaded python library from: %s\n\n", pythondll_path);
|
|
}
|
|
|
|
#if defined (_WIN)
|
|
|
|
#else
|
|
fprintf (stderr, "Attention!!! The 'free-threaded' python library has some major downsides.\n");
|
|
fprintf (stderr, " The main purpose of this module is to give windows users a multithreading option.\n");
|
|
fprintf (stderr, " It seems to be a lot slower, and relevant modules such as cffi are incompatibile.\n");
|
|
fprintf (stderr, " Since your are on Linux/MacOS we highly recommend to stick to multiprocessing module.\n");
|
|
fprintf (stderr, " Maybe 'free-threaded' mode will become more mature in the future.\n");
|
|
fprintf (stderr, " For now, we high recommend to stick to -m 73000 instead.\n\n");
|
|
#endif
|
|
|
|
#define HC_LOAD_FUNC_PYTHON(ptr,name,pythonname,type,libname,noerr) \
|
|
do { \
|
|
ptr->name = (type) hc_dlsym ((ptr)->lib, #pythonname); \
|
|
if ((noerr) != -1) { \
|
|
if (!(ptr)->name) { \
|
|
if ((noerr) == 1) { \
|
|
fprintf (stderr, "%s is missing from %s shared library.", #name, #libname); \
|
|
return false; \
|
|
} \
|
|
if ((noerr) != 1) { \
|
|
fprintf (stderr, "%s is missing from %s shared library.", #name, #libname); \
|
|
return true; \
|
|
} \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
HC_LOAD_FUNC_PYTHON (python, Py_GetVersion, Py_GetVersion, PYGETVERSION, PYTHON, 1);
|
|
|
|
const char *version_str = python->Py_GetVersion ();
|
|
|
|
int major = 0;
|
|
int minor = 0;
|
|
|
|
if (sscanf (version_str, "%d.%d", &major, &minor) != 2)
|
|
{
|
|
fprintf (stderr, "Python version string is not valid: %s\n", version_str);
|
|
|
|
return false;
|
|
}
|
|
|
|
if ((major < 3) || (major == 3 && minor < 13))
|
|
{
|
|
fprintf (stderr, "Python version mismatch: Need at least v3.13\n");
|
|
|
|
return false;
|
|
}
|
|
|
|
HC_LOAD_FUNC_PYTHON (python, Py_Initialize, Py_Initialize, PY_INITIALIZE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, Py_Finalize, Py_Finalize, PY_FINALIZE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, Py_DecRef, Py_DecRef, PY_DECREF, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyBool_FromLong, PyBool_FromLong, PYBOOL_FROMLONG, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyBytes_FromStringAndSize, PyBytes_FromStringAndSize, PYBYTES_FROMSTRINGANDSIZE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyDict_DelItemString, PyDict_DelItemString, PYDICT_DELITEMSTRING, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyDict_GetItemString, PyDict_GetItemString, PYDICT_GETITEMSTRING, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyDict_New, PyDict_New, PYDICT_NEW, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyDict_SetItemString, PyDict_SetItemString, PYDICT_SETITEMSTRING, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyErr_Print, PyErr_Print, PYERR_PRINT, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyImport_ImportModule, PyImport_ImportModule, PYIMPORT_IMPORTMODULE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyImport_Import, PyImport_Import, PYIMPORT_IMPORT, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyList_Append, PyList_Append, PYLIST_APPEND, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyList_GetItem, PyList_GetItem, PYLIST_GETITEM, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyList_New, PyList_New, PYLIST_NEW, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyList_SetItem, PyList_SetItem, PYLIST_SETITEM, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyList_Size, PyList_Size, PYLIST_SIZE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyLong_FromLong, PyLong_FromLong, PYLONG_FROMLONG, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyObject_CallObject, PyObject_CallObject, PYOBJECT_CALLOBJECT, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyObject_GetAttrString, PyObject_GetAttrString, PYOBJECT_GETATTRSTRING, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyTuple_New, PyTuple_New, PYTUPLE_NEW, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyTuple_SetItem, PyTuple_SetItem, PYTUPLE_SETITEM, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyUnicode_AsUTF8, PyUnicode_AsUTF8, PYUNICODE_ASUTF8, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyUnicode_AsUTF8AndSize, PyUnicode_AsUTF8AndSize, PYUNICODE_ASUTF8ANDSIZE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyUnicode_DecodeFSDefaultAndSize, PyUnicode_DecodeFSDefaultAndSize, PYUNICODE_DECODEFSDEFAULTANDSIZE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyUnicode_DecodeFSDefault, PyUnicode_DecodeFSDefault, PYUNICODE_DECODEFSDEFAULT, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyUnicode_FromStringAndSize, PyUnicode_FromStringAndSize, PYUNICODE_FROMSTRINGANDSIZE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyUnicode_FromString, PyUnicode_FromString, PYUNICODE_FROMSTRING, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyEval_AcquireLock, PyEval_AcquireLock, PYEVAL_ACQUIRELOCK, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyEval_ReleaseLock, PyEval_ReleaseLock, PYEVAL_RELEASELOCK, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyThreadState_Swap, PyThreadState_Swap, PYTHREADSTATE_SWAP, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, Py_NewInterpreter, Py_NewInterpreter, PYNEWINTERPRETER, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, Py_EndInterpreter, Py_EndInterpreter, PYENDINTERPRETER, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyGILState_Ensure, PyGILState_Ensure, PYGILSTATE_ENSURE, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyGILState_Release, PyGILState_Release, PYGILSTATE_RELEASE, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyEval_AcquireThread, PyEval_AcquireThread, PYEVAL_ACQUIRETHREAD, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyEval_ReleaseThread, PyEval_ReleaseThread, PYEVAL_RELEASETHREAD, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyThreadState_Clear, PyThreadState_Clear, PYTHREADSTATE_CLEAR, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyThreadState_Delete, PyThreadState_Delete, PYTHREADSTATE_DELETE, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyThreadState_New, PyThreadState_New, PYTHREADSTATE_NEW, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyInterpreterState_Main, PyInterpreterState_Main, PYINTERPRETERSTATE_MAIN, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, PyEval_InitThreads, PyEval_InitThreads, PYEVAL_INITTHREADS, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyEval_SaveThread, PyEval_SaveThread, PYEVAL_SAVETHREAD, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, Py_NewInterpreterFromConfig, Py_NewInterpreterFromConfig, PYNEWINTERPRETERFROMCONFIG, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, Py_ExitStatusException, Py_ExitStatusException, PYEXITSTATUSEXCEPTION, PYTHON, 1);
|
|
//HC_LOAD_FUNC_PYTHON (python, Py_InitializeFromConfig, Py_InitializeFromConfig, PYINITIALIZEFROMCONFIG, PYTHON, 1);
|
|
HC_LOAD_FUNC_PYTHON (python, PyEval_RestoreThread, PyEval_RestoreThread, PYEVAL_RESTORETHREAD, PYTHON, 1);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool units_init (python_interpreter_t *python_interpreter)
|
|
{
|
|
#if defined (_WIN)
|
|
|
|
SYSTEM_INFO sysinfo;
|
|
|
|
GetSystemInfo (&sysinfo);
|
|
|
|
int num_devices = sysinfo.dwNumberOfProcessors;
|
|
|
|
#else
|
|
|
|
int num_devices = sysconf (_SC_NPROCESSORS_ONLN);
|
|
|
|
#endif
|
|
|
|
unit_t *units_buf = (unit_t *) hccalloc (num_devices, sizeof (unit_t));
|
|
|
|
int units_cnt = 0;
|
|
|
|
for (int i = 0; i < num_devices; i++)
|
|
{
|
|
unit_t *unit_buf = &units_buf[i];
|
|
|
|
hc_python_lib_t *python = python_interpreter->python;
|
|
|
|
unit_buf->unit_info_len = snprintf (unit_buf->unit_info_buf, sizeof (unit_buf->unit_info_buf) - 1, "Python Interpreter (%s)", python->Py_GetVersion ());
|
|
|
|
unit_buf->unit_info_buf[unit_buf->unit_info_len] = 0;
|
|
|
|
unit_buf->workitem_count = N_ACCEL;
|
|
|
|
units_cnt++;
|
|
}
|
|
|
|
python_interpreter->units_buf = units_buf;
|
|
python_interpreter->units_cnt = units_cnt;
|
|
|
|
return true;
|
|
}
|
|
|
|
static void units_term (python_interpreter_t *python_interpreter)
|
|
{
|
|
unit_t *units_buf = python_interpreter->units_buf;
|
|
|
|
if (units_buf)
|
|
{
|
|
hcfree (python_interpreter->units_buf);
|
|
}
|
|
}
|
|
|
|
void *platform_init (user_options_t *user_options)
|
|
{
|
|
python_interpreter_t *python_interpreter = (python_interpreter_t *) hcmalloc (sizeof (python_interpreter_t));
|
|
|
|
hc_python_lib_t *python = (hc_python_lib_t *) hcmalloc (sizeof (hc_python_lib_t));
|
|
|
|
python_interpreter->python = python;
|
|
|
|
if (init_python (python) == false) return NULL;
|
|
|
|
python->Py_Initialize ();
|
|
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
python_interpreter->source_filename = (user_options->bridge_parameter1) ? user_options->bridge_parameter1 : DEFAULT_SOURCE_FILENAME;
|
|
|
|
if (units_init (python_interpreter) == false)
|
|
{
|
|
hcfree (python_interpreter);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
return python_interpreter;
|
|
}
|
|
|
|
void platform_term (void *platform_context)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
if (python_interpreter == NULL) return;
|
|
|
|
hc_python_lib_t *python = python_interpreter->python;
|
|
|
|
// python->PyGILState_Ensure ();
|
|
|
|
python->PyEval_RestoreThread (python_interpreter->thread_state);
|
|
|
|
python->Py_Finalize ();
|
|
|
|
units_term (python_interpreter);
|
|
|
|
hcfree (python_interpreter);
|
|
}
|
|
|
|
bool thread_init (MAYBE_UNUSED void *platform_context, MAYBE_UNUSED hc_device_param_t *device_param, MAYBE_UNUSED hashconfig_t *hashconfig, MAYBE_UNUSED hashes_t *hashes)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
const int unit_idx = device_param->bridge_link_device;
|
|
|
|
unit_t *unit_buf = &python_interpreter->units_buf[unit_idx];
|
|
|
|
hc_python_lib_t *python = python_interpreter->python;
|
|
|
|
PyInterpreterConfig config =
|
|
{
|
|
.use_main_obmalloc = 0,
|
|
.allow_fork = 1,
|
|
.allow_exec = 1,
|
|
.allow_threads = 1,
|
|
.allow_daemon_threads = 0,
|
|
.check_multi_interp_extensions = 1,
|
|
.gil = PyInterpreterConfig_OWN_GIL
|
|
};
|
|
|
|
unit_buf->tstate = NULL;
|
|
|
|
PyStatus status = python->Py_NewInterpreterFromConfig (&unit_buf->tstate, &config);
|
|
|
|
if (status.exitcode)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
PyObject *sys = python->PyImport_ImportModule ("sys");
|
|
PyObject *path = python->PyObject_GetAttrString (sys, "path");
|
|
python->PyList_Append (path, python->PyUnicode_FromString ("./Python"));
|
|
//python->Py_DecRef (path);
|
|
//python->Py_DecRef (sys);
|
|
|
|
PyObject *pName = python->PyUnicode_DecodeFSDefault (python_interpreter->source_filename);
|
|
|
|
if (pName == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
unit_buf->pModule = python->PyImport_Import (pName);
|
|
|
|
if (unit_buf->pModule == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
//python->Py_DecRef (pName);
|
|
|
|
unit_buf->pFunc_Init = python->PyObject_GetAttrString (unit_buf->pModule, "init");
|
|
|
|
if (unit_buf->pFunc_Init == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
unit_buf->pFunc_Term = python->PyObject_GetAttrString (unit_buf->pModule, "term");
|
|
|
|
if (unit_buf->pFunc_Term == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
unit_buf->pFunc_kernel_loop = python->PyObject_GetAttrString (unit_buf->pModule, "kernel_loop");
|
|
|
|
if (unit_buf->pFunc_kernel_loop == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
// Initialize Context (which also means copy salts because they are part of the context)
|
|
|
|
unit_buf->pContext = python->PyDict_New ();
|
|
|
|
if (unit_buf->pContext == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
int rc = 0;
|
|
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "salts_cnt", python->PyLong_FromLong (hashes->salts_cnt));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "salts_size", python->PyLong_FromLong (sizeof (salt_t)));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "salts_buf", python->PyBytes_FromStringAndSize ((const char *) hashes->salts_buf, sizeof (salt_t) * hashes->salts_cnt));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "esalts_cnt", python->PyLong_FromLong (hashes->digests_cnt));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "esalts_size", python->PyLong_FromLong (hashconfig->esalt_size));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "esalts_buf", python->PyBytes_FromStringAndSize ((const char *) hashes->esalts_buf, hashconfig->esalt_size * hashes->digests_cnt));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "st_salts_cnt", python->PyLong_FromLong (1));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "st_salts_size", python->PyLong_FromLong (sizeof (salt_t)));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "st_salts_buf", python->PyBytes_FromStringAndSize ((const char *) hashes->st_salts_buf, sizeof (salt_t) * 1));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "st_esalts_cnt", python->PyLong_FromLong (1));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "st_esalts_size", python->PyLong_FromLong (hashconfig->esalt_size));
|
|
rc |= python->PyDict_SetItemString (unit_buf->pContext, "st_esalts_buf", python->PyBytes_FromStringAndSize ((const char *) hashes->st_esalts_buf, hashconfig->esalt_size * 1));
|
|
|
|
if (rc != 0)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
PyObject *pArgs = python->PyTuple_New (1);
|
|
|
|
if (pArgs == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
python->PyTuple_SetItem (pArgs, 0, unit_buf->pContext);
|
|
|
|
python->PyObject_CallObject (unit_buf->pFunc_Init, pArgs);
|
|
|
|
// for later calls
|
|
|
|
unit_buf->pArgs = python->PyTuple_New (4);
|
|
|
|
if (unit_buf->pArgs == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
python->PyTuple_SetItem (unit_buf->pArgs, 0, unit_buf->pContext);
|
|
python->PyTuple_SetItem (unit_buf->pArgs, 2, python->PyLong_FromLong (0));
|
|
python->PyTuple_SetItem (unit_buf->pArgs, 3, python->PyBool_FromLong (false));
|
|
|
|
return true;
|
|
}
|
|
|
|
void thread_term (MAYBE_UNUSED void *platform_context, MAYBE_UNUSED hc_device_param_t *device_param, MAYBE_UNUSED hashconfig_t *hashconfig, MAYBE_UNUSED hashes_t *hashes)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
const int unit_idx = device_param->bridge_link_device;
|
|
|
|
unit_t *unit_buf = &python_interpreter->units_buf[unit_idx];
|
|
|
|
hc_python_lib_t *python = python_interpreter->python;
|
|
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "salts_cnt"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "salts_size"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "salts_buf"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "esalts_cnt"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "esalts_size"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "esalts_buf"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "st_salts_cnt"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "st_salts_size"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "st_salts_buf"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "st_esalts_cnt"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "st_esalts_size"));
|
|
//python->Py_DecRef (python->PyDict_GetItemString (unit_buf->pContext, "st_esalts_buf"));
|
|
|
|
python->PyDict_DelItemString (unit_buf->pContext, "salts_cnt");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "salts_size");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "salts_buf");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "esalts_cnt");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "esalts_size");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "esalts_buf");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "st_salts_cnt");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "st_salts_size");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "st_salts_buf");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "st_esalts_cnt");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "st_esalts_size");
|
|
python->PyDict_DelItemString (unit_buf->pContext, "st_esalts_buf");
|
|
|
|
PyObject *pArgs = python->PyTuple_New (1);
|
|
|
|
if (pArgs == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return;
|
|
}
|
|
|
|
python->PyTuple_SetItem (pArgs, 0, unit_buf->pContext);
|
|
|
|
python->PyObject_CallObject (unit_buf->pFunc_Term, pArgs);
|
|
|
|
//python->Py_DecRef (pArgs);
|
|
//python->Py_DecRef (unit_buf->pFunc_kernel_loop);
|
|
//python->Py_DecRef (unit_buf->pFunc_Term);
|
|
//python->Py_DecRef (unit_buf->pFunc_Init);
|
|
//python->Py_DecRef (unit_buf->pModule);
|
|
//python->Py_DecRef (unit_buf->pContext);
|
|
//python->Py_DecRef (unit_buf->pArgs);
|
|
|
|
python->Py_EndInterpreter (unit_buf->tstate);
|
|
}
|
|
|
|
int get_unit_count (void *platform_context)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
return python_interpreter->units_cnt;
|
|
}
|
|
|
|
// we support units of mixed speed, that's why the workitem count is unit specific
|
|
|
|
int get_workitem_count (void *platform_context, const int unit_idx)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
unit_t *unit_buf = &python_interpreter->units_buf[unit_idx];
|
|
|
|
return unit_buf->workitem_count;
|
|
}
|
|
|
|
char *get_unit_info (void *platform_context, const int unit_idx)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
unit_t *unit_buf = &python_interpreter->units_buf[unit_idx];
|
|
|
|
return unit_buf->unit_info_buf;
|
|
}
|
|
|
|
bool launch_loop (MAYBE_UNUSED void *platform_context, MAYBE_UNUSED hc_device_param_t *device_param, MAYBE_UNUSED hashconfig_t *hashconfig, MAYBE_UNUSED hashes_t *hashes, MAYBE_UNUSED const u32 salt_pos, MAYBE_UNUSED const u64 pws_cnt)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
const int unit_idx = device_param->bridge_link_device;
|
|
|
|
unit_t *unit_buf = &python_interpreter->units_buf[unit_idx];
|
|
|
|
hc_python_lib_t *python = python_interpreter->python;
|
|
|
|
generic_io_tmp_t *generic_io_tmp = (generic_io_tmp_t *) device_param->h_tmps;
|
|
|
|
PyObject *pws = python->PyList_New (pws_cnt);
|
|
|
|
if (pws == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
for (u64 i = 0; i < pws_cnt; i++)
|
|
{
|
|
PyObject *pw = python->PyBytes_FromStringAndSize ((char *) generic_io_tmp->pw_buf, generic_io_tmp->pw_len);
|
|
|
|
if (pw == NULL) return false;
|
|
|
|
python->PyList_SetItem (pws, i, pw);
|
|
|
|
generic_io_tmp++;
|
|
}
|
|
|
|
python->PyTuple_SetItem (unit_buf->pArgs, 1, pws);
|
|
python->PyTuple_SetItem (unit_buf->pArgs, 2, python->PyLong_FromLong (salt_pos));
|
|
|
|
if (hashes->salts_buf == hashes->st_salts_buf)
|
|
{
|
|
python->PyTuple_SetItem (unit_buf->pArgs, 3, python->PyBool_FromLong (true));
|
|
}
|
|
else
|
|
{
|
|
python->PyTuple_SetItem (unit_buf->pArgs, 3, python->PyBool_FromLong (false));
|
|
}
|
|
|
|
PyObject *pReturn = python->PyObject_CallObject (unit_buf->pFunc_kernel_loop, unit_buf->pArgs);
|
|
|
|
if (pReturn == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
return false;
|
|
}
|
|
|
|
//python->Py_DecRef (pws);
|
|
|
|
Py_ssize_t retsz = python->PyList_Size (pReturn);
|
|
|
|
if (retsz != (Py_ssize_t) pws_cnt) return false;
|
|
|
|
generic_io_tmp = (generic_io_tmp_t *) device_param->h_tmps;
|
|
|
|
for (Py_ssize_t i = 0; i < retsz; i++)
|
|
{
|
|
PyObject *hash = python->PyList_GetItem (pReturn, i);
|
|
|
|
Py_ssize_t len;
|
|
|
|
const char *s = python->PyUnicode_AsUTF8AndSize (hash, &len);
|
|
|
|
if (s)
|
|
{
|
|
memcpy (generic_io_tmp->out_buf, s, len);
|
|
|
|
generic_io_tmp->out_len = len;
|
|
}
|
|
|
|
//python->Py_DecRef (hash);
|
|
|
|
generic_io_tmp++;
|
|
}
|
|
|
|
//python->Py_DecRef (pReturn);
|
|
|
|
return true;
|
|
}
|
|
|
|
const char *st_update_hash (MAYBE_UNUSED void *platform_context)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
hc_python_lib_t *python = python_interpreter->python;
|
|
|
|
python->PyEval_RestoreThread (python_interpreter->thread_state);
|
|
|
|
PyObject *sys = python->PyImport_ImportModule ("sys");
|
|
PyObject *path = python->PyObject_GetAttrString (sys, "path");
|
|
python->PyList_Append (path, python->PyUnicode_FromString ("./Python"));
|
|
//python->Py_DecRef (path);
|
|
//python->Py_DecRef (sys);
|
|
|
|
PyObject *pName = python->PyUnicode_DecodeFSDefault (python_interpreter->source_filename);
|
|
|
|
if (pName == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return false;
|
|
}
|
|
|
|
PyObject *pModule = python->PyImport_Import (pName);
|
|
|
|
if (pModule == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return false;
|
|
}
|
|
|
|
PyObject *constant = python->PyObject_GetAttrString (pModule, "ST_HASH");
|
|
|
|
if (constant == NULL)
|
|
{
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char *s = python->PyUnicode_AsUTF8 (constant);
|
|
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return s;
|
|
}
|
|
|
|
const char *st_update_pass (MAYBE_UNUSED void *platform_context)
|
|
{
|
|
python_interpreter_t *python_interpreter = platform_context;
|
|
|
|
hc_python_lib_t *python = python_interpreter->python;
|
|
|
|
python->PyEval_RestoreThread (python_interpreter->thread_state);
|
|
|
|
PyObject *sys = python->PyImport_ImportModule ("sys");
|
|
PyObject *path = python->PyObject_GetAttrString (sys, "path");
|
|
python->PyList_Append (path, python->PyUnicode_FromString ("./Python"));
|
|
//python->Py_DecRef (path);
|
|
//python->Py_DecRef (sys);
|
|
|
|
PyObject *pName = python->PyUnicode_DecodeFSDefault (python_interpreter->source_filename);
|
|
|
|
if (pName == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return false;
|
|
}
|
|
|
|
PyObject *pModule = python->PyImport_Import (pName);
|
|
|
|
if (pModule == NULL)
|
|
{
|
|
python->PyErr_Print ();
|
|
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return false;
|
|
}
|
|
|
|
PyObject *constant = python->PyObject_GetAttrString (pModule, "ST_PASS");
|
|
|
|
if (constant == NULL)
|
|
{
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char *s = python->PyUnicode_AsUTF8 (constant);
|
|
|
|
python_interpreter->thread_state = python->PyEval_SaveThread ();
|
|
|
|
return s;
|
|
}
|
|
|
|
void bridge_init (bridge_ctx_t *bridge_ctx)
|
|
{
|
|
bridge_ctx->bridge_context_size = BRIDGE_CONTEXT_SIZE_CURRENT;
|
|
bridge_ctx->bridge_interface_version = BRIDGE_INTERFACE_VERSION_CURRENT;
|
|
|
|
bridge_ctx->platform_init = platform_init;
|
|
bridge_ctx->platform_term = platform_term;
|
|
bridge_ctx->get_unit_count = get_unit_count;
|
|
bridge_ctx->get_unit_info = get_unit_info;
|
|
bridge_ctx->get_workitem_count = get_workitem_count;
|
|
bridge_ctx->thread_init = thread_init;
|
|
bridge_ctx->thread_term = thread_term;
|
|
bridge_ctx->salt_prepare = BRIDGE_DEFAULT;
|
|
bridge_ctx->salt_destroy = BRIDGE_DEFAULT;
|
|
bridge_ctx->launch_loop = launch_loop;
|
|
bridge_ctx->launch_loop2 = BRIDGE_DEFAULT;
|
|
bridge_ctx->st_update_hash = st_update_hash;
|
|
bridge_ctx->st_update_pass = st_update_pass;
|
|
}
|