From fd510863952ce75c6e6d3822badae045f25c6fbe Mon Sep 17 00:00:00 2001 From: Jens Steube Date: Fri, 21 May 2021 12:46:14 +0200 Subject: [PATCH] RAR3 Plugins: Replaced naive with true UTF8 to UTF16 conversion in optimized and pure kernels --- OpenCL/m23700-optimized.cl | 45 ++++++++++++++++++++++----------- OpenCL/m23700-pure.cl | 48 ++++++++++-------------------------- OpenCL/m23800-optimized.cl | 30 ++++++++++++++-------- OpenCL/m23800-pure.cl | 48 ++++++++++-------------------------- docs/changes.txt | 2 +- src/modules/module_23700.c | 7 +++--- src/modules/module_23800.c | 7 +++--- tools/test_modules/m23700.pm | 2 +- 8 files changed, 86 insertions(+), 103 deletions(-) diff --git a/OpenCL/m23700-optimized.cl b/OpenCL/m23700-optimized.cl index f9b83e5b3..f496a32e2 100644 --- a/OpenCL/m23700-optimized.cl +++ b/OpenCL/m23700-optimized.cl @@ -161,15 +161,20 @@ KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) if (gid >= gid_max) return; - u32 pw_buf[5]; + u32 pw_buf[10]; pw_buf[0] = pws[gid].i[0]; pw_buf[1] = pws[gid].i[1]; pw_buf[2] = pws[gid].i[2]; pw_buf[3] = pws[gid].i[3]; pw_buf[4] = pws[gid].i[4]; + pw_buf[5] = pws[gid].i[5]; + pw_buf[6] = pws[gid].i[6]; + pw_buf[7] = pws[gid].i[7]; + pw_buf[8] = pws[gid].i[8]; + pw_buf[9] = pws[gid].i[9]; - const u32 pw_len = MIN (pws[gid].pw_len, 20); + const u32 pw_len = MIN (pws[gid].pw_len, 40); u32 salt_buf[2]; @@ -184,7 +189,7 @@ KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) u32 p = 0; - for (u32 j = 0; j < pw_len; j++, p += 2) + for (u32 j = 0; j < pw_len; j++, p += 1) { PUTCHAR_BE (cb, p, GETCHAR (pw_buf, j)); } @@ -194,8 +199,8 @@ KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) PUTCHAR_BE (cb, p, GETCHAR (salt_buf, j)); } - const u32 p2 = (pw_len * 2) + salt_len; - const u32 p3 = (pw_len * 2) + salt_len + 3; + const u32 p2 = pw_len + salt_len; + const u32 p3 = pw_len + salt_len + 3; const u32 init_pos = loop_pos / (ROUNDS / 16); @@ -491,15 +496,20 @@ KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) if (gid >= gid_max) return; - u32 pw_buf[5]; + u32 pw_buf[10]; pw_buf[0] = pws[gid].i[0]; pw_buf[1] = pws[gid].i[1]; pw_buf[2] = pws[gid].i[2]; pw_buf[3] = pws[gid].i[3]; pw_buf[4] = pws[gid].i[4]; + pw_buf[5] = pws[gid].i[5]; + pw_buf[6] = pws[gid].i[6]; + pw_buf[7] = pws[gid].i[7]; + pw_buf[8] = pws[gid].i[8]; + pw_buf[9] = pws[gid].i[9]; - const u32 pw_len = MIN (pws[gid].pw_len, 20); + const u32 pw_len = MIN (pws[gid].pw_len, 40); u32 salt_buf[2]; @@ -518,7 +528,7 @@ KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) for (u32 i = 0, p = 0; i < 64; i++) { - for (u32 j = 0; j < pw_len; j++, p += 2) + for (u32 j = 0; j < pw_len; j++, p += 1) { PUTCHAR_BE (largeblock, p, GETCHAR (pw_buf, j)); } @@ -533,9 +543,9 @@ KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) p += 3; } - const u32 p2 = (pw_len * 2) + salt_len; + const u32 p2 = pw_len + salt_len; - const u32 p3 = (pw_len * 2) + salt_len + 3; + const u32 p3 = pw_len + salt_len + 3; const u32 init_pos = loop_pos / (ROUNDS / 16); @@ -739,11 +749,11 @@ KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) * base */ - const u32 pw_len = MIN (pws[gid].pw_len, 20); + const u32 pw_len = MIN (pws[gid].pw_len, 40); const u32 salt_len = 8; - const u32 p3 = (pw_len * 2) + salt_len + 3; + const u32 p3 = pw_len + salt_len + 3; u32 w0[4]; u32 w1[4]; @@ -797,13 +807,18 @@ KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) for (int i = 0; i < 16; i++) { - u32 pw_buf[5]; + u32 pw_buf[10]; pw_buf[0] = pws[gid].i[0]; pw_buf[1] = pws[gid].i[1]; pw_buf[2] = pws[gid].i[2]; pw_buf[3] = pws[gid].i[3]; pw_buf[4] = pws[gid].i[4]; + pw_buf[5] = pws[gid].i[5]; + pw_buf[6] = pws[gid].i[6]; + pw_buf[7] = pws[gid].i[7]; + pw_buf[8] = pws[gid].i[8]; + pw_buf[9] = pws[gid].i[9]; //const u32 pw_len = pws[gid].pw_len; @@ -814,7 +829,7 @@ KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) //const u32 salt_len = 8; - //const u32 p3 = (pw_len * 2) + salt_len + 3; + //const u32 p3 = pw_len + salt_len + 3; u32 w[16]; @@ -837,7 +852,7 @@ KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) u32 p = 0; - for (u32 j = 0; j < pw_len; j++, p += 2) + for (u32 j = 0; j < pw_len; j++, p += 1) { PUTCHAR_BE (w, p, GETCHAR (pw_buf, j)); } diff --git a/OpenCL/m23700-pure.cl b/OpenCL/m23700-pure.cl index 48e7c61f6..ec62394a1 100644 --- a/OpenCL/m23700-pure.cl +++ b/OpenCL/m23700-pure.cl @@ -849,38 +849,17 @@ KERNEL_FQ void m23700_init (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) const u32 pw_len = pws[gid].pw_len; - // first set the utf16le pass: - u32 w[80] = { 0 }; - for (u32 i = 0, j = 0, k = 0; i < pw_len; i += 16, j += 4, k += 8) + for (int i = 0, j = 0; i < pw_len; i += 4, j += 1) { - u32 a[4]; - - a[0] = pws[gid].i[j + 0]; - a[1] = pws[gid].i[j + 1]; - a[2] = pws[gid].i[j + 2]; - a[3] = pws[gid].i[j + 3]; - - u32 b[4]; - u32 c[4]; - - make_utf16le (a, b, c); - - w[k + 0] = hc_swap32_S (b[0]); - w[k + 1] = hc_swap32_S (b[1]); - w[k + 2] = hc_swap32_S (b[2]); - w[k + 3] = hc_swap32_S (b[3]); - w[k + 4] = hc_swap32_S (c[0]); - w[k + 5] = hc_swap32_S (c[1]); - w[k + 6] = hc_swap32_S (c[2]); - w[k + 7] = hc_swap32_S (c[3]); + w[j] = hc_swap32_S (pws[gid].i[j]); } // append salt: - const u32 salt_idx = (pw_len * 2) / 4; - const u32 salt_off = (pw_len * 2) & 3; + const u32 salt_idx = pw_len / 4; + const u32 salt_off = pw_len & 3; u32 salt_buf[3]; @@ -897,10 +876,9 @@ KERNEL_FQ void m23700_init (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) salt_buf[0] = (salt_buf[0] >> 16); } - w[salt_idx] |= salt_buf[0]; - - w[salt_idx + 1] = salt_buf[1]; - w[salt_idx + 2] = salt_buf[2]; + w[salt_idx + 0] |= salt_buf[0]; + w[salt_idx + 1] = salt_buf[1]; + w[salt_idx + 2] = salt_buf[2]; // store initial w[] (pass and salt) in tmps: @@ -927,17 +905,17 @@ KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) * base */ - const u32 pw_len = pws[gid].pw_len; + const u32 pw_len = pws[gid].pw_len & 255; const u32 salt_len = 8; - const u32 pw_salt_len = (pw_len * 2) + salt_len; + const u32 pw_salt_len = pw_len + salt_len; const u32 p3 = pw_salt_len + 3; - u32 w[80] = { 0 }; // 64 byte aligned + u32 w[80] = { 0 }; - for (u32 i = 0; i < 66; i++) // unroll ? + for (u32 i = 0; i < 66; i++) { w[i] = tmps[gid].w[i]; } @@ -1101,11 +1079,11 @@ KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) * base */ - const u32 pw_len = pws[gid].pw_len; + const u32 pw_len = pws[gid].pw_len & 255; const u32 salt_len = 8; - const u32 pw_salt_len = (pw_len * 2) + salt_len; + const u32 pw_salt_len = pw_len + salt_len; const u32 p3 = pw_salt_len + 3; diff --git a/OpenCL/m23800-optimized.cl b/OpenCL/m23800-optimized.cl index 2d941e9a3..a26769e7b 100644 --- a/OpenCL/m23800-optimized.cl +++ b/OpenCL/m23800-optimized.cl @@ -71,15 +71,20 @@ KERNEL_FQ void m23800_loop (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, if (gid >= gid_max) return; - u32 pw_buf[5]; + u32 pw_buf[10]; pw_buf[0] = pws[gid].i[0]; pw_buf[1] = pws[gid].i[1]; pw_buf[2] = pws[gid].i[2]; pw_buf[3] = pws[gid].i[3]; pw_buf[4] = pws[gid].i[4]; + pw_buf[5] = pws[gid].i[5]; + pw_buf[6] = pws[gid].i[6]; + pw_buf[7] = pws[gid].i[7]; + pw_buf[8] = pws[gid].i[8]; + pw_buf[9] = pws[gid].i[9]; - const u32 pw_len = MIN (pws[gid].pw_len, 20); + const u32 pw_len = MIN (pws[gid].pw_len, 40); u32 salt_buf[2]; @@ -98,7 +103,7 @@ KERNEL_FQ void m23800_loop (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, for (u32 i = 0, p = 0; i < 64; i++) { - for (u32 j = 0; j < pw_len; j++, p += 2) + for (u32 j = 0; j < pw_len; j++, p += 1) { PUTCHAR_BE (largeblock, p, GETCHAR (pw_buf, j)); } @@ -113,9 +118,9 @@ KERNEL_FQ void m23800_loop (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, p += 3; } - const u32 p2 = (pw_len * 2) + salt_len; + const u32 p2 = pw_len + salt_len; - const u32 p3 = (pw_len * 2) + salt_len + 3; + const u32 p3 = pw_len + salt_len + 3; const u32 init_pos = loop_pos / (ROUNDS / 16); @@ -312,11 +317,11 @@ KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_ * base */ - const u32 pw_len = MIN (pws[gid].pw_len, 20); + const u32 pw_len = MIN (pws[gid].pw_len, 40); const u32 salt_len = 8; - const u32 p3 = (pw_len * 2) + salt_len + 3; + const u32 p3 = pw_len + salt_len + 3; u32 w0[4]; u32 w1[4]; @@ -359,13 +364,18 @@ KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_ for (int i = 0; i < 16; i++) { - u32 pw_buf[5]; + u32 pw_buf[10]; pw_buf[0] = pws[gid].i[0]; pw_buf[1] = pws[gid].i[1]; pw_buf[2] = pws[gid].i[2]; pw_buf[3] = pws[gid].i[3]; pw_buf[4] = pws[gid].i[4]; + pw_buf[5] = pws[gid].i[5]; + pw_buf[6] = pws[gid].i[6]; + pw_buf[7] = pws[gid].i[7]; + pw_buf[8] = pws[gid].i[8]; + pw_buf[9] = pws[gid].i[9]; //const u32 pw_len = pws[gid].pw_len; @@ -376,7 +386,7 @@ KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_ //const u32 salt_len = 8; - //const u32 p3 = (pw_len * 2) + salt_len + 3; + //const u32 p3 = pw_len + salt_len + 3; u32 w[16]; @@ -399,7 +409,7 @@ KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_ u32 p = 0; - for (u32 j = 0; j < pw_len; j++, p += 2) + for (u32 j = 0; j < pw_len; j++, p += 1) { PUTCHAR_BE (w, p, GETCHAR (pw_buf, j)); } diff --git a/OpenCL/m23800-pure.cl b/OpenCL/m23800-pure.cl index 788c8b558..1629433c0 100644 --- a/OpenCL/m23800-pure.cl +++ b/OpenCL/m23800-pure.cl @@ -760,38 +760,17 @@ KERNEL_FQ void m23800_init (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, const u32 pw_len = pws[gid].pw_len; - // first set the utf16le pass: - u32 w[80] = { 0 }; - for (u32 i = 0, j = 0, k = 0; i < pw_len; i += 16, j += 4, k += 8) + for (int i = 0, j = 0; i < pw_len; i += 4, j += 1) { - u32 a[4]; - - a[0] = pws[gid].i[j + 0]; - a[1] = pws[gid].i[j + 1]; - a[2] = pws[gid].i[j + 2]; - a[3] = pws[gid].i[j + 3]; - - u32 b[4]; - u32 c[4]; - - make_utf16le (a, b, c); - - w[k + 0] = hc_swap32_S (b[0]); - w[k + 1] = hc_swap32_S (b[1]); - w[k + 2] = hc_swap32_S (b[2]); - w[k + 3] = hc_swap32_S (b[3]); - w[k + 4] = hc_swap32_S (c[0]); - w[k + 5] = hc_swap32_S (c[1]); - w[k + 6] = hc_swap32_S (c[2]); - w[k + 7] = hc_swap32_S (c[3]); + w[j] = hc_swap32_S (pws[gid].i[j]); } // append salt: - const u32 salt_idx = (pw_len * 2) / 4; - const u32 salt_off = (pw_len * 2) & 3; + const u32 salt_idx = pw_len / 4; + const u32 salt_off = pw_len & 3; u32 salt_buf[3]; @@ -808,10 +787,9 @@ KERNEL_FQ void m23800_init (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, salt_buf[0] = (salt_buf[0] >> 16); } - w[salt_idx] |= salt_buf[0]; - - w[salt_idx + 1] = salt_buf[1]; - w[salt_idx + 2] = salt_buf[2]; + w[salt_idx + 0] |= salt_buf[0]; + w[salt_idx + 1] = salt_buf[1]; + w[salt_idx + 2] = salt_buf[2]; // store initial w[] (pass and salt) in tmps: @@ -838,17 +816,17 @@ KERNEL_FQ void m23800_loop (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, * base */ - const u32 pw_len = pws[gid].pw_len; + const u32 pw_len = pws[gid].pw_len & 255; const u32 salt_len = 8; - const u32 pw_salt_len = (pw_len * 2) + salt_len; + const u32 pw_salt_len = pw_len + salt_len; const u32 p3 = pw_salt_len + 3; - u32 w[80] = { 0 }; // 64 byte aligned + u32 w[80] = { 0 }; - for (u32 i = 0; i < 66; i++) // unroll ? + for (u32 i = 0; i < 66; i++) { w[i] = tmps[gid].w[i]; } @@ -1005,11 +983,11 @@ KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_ * base */ - const u32 pw_len = pws[gid].pw_len; + const u32 pw_len = pws[gid].pw_len & 255; const u32 salt_len = 8; - const u32 pw_salt_len = (pw_len * 2) + salt_len; + const u32 pw_salt_len = pw_len + salt_len; const u32 p3 = pw_salt_len + 3; diff --git a/docs/changes.txt b/docs/changes.txt index 3f56c22d2..876799588 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -16,7 +16,7 @@ - CUDA Backend: Do not warn about missing CUDA SDK installation if --stdout is used - Performance Monitor: Add -S as a user suggestion to improve cracking performance in specific attack configurations - Status Screen: Show currently running kernel type (pure, optimized) and generator type (host, device) -- RAR3-hp Plugin: Replaced naive with true UTF8 to UTF16 conversion in optimized and pure kernel +- RAR3 Plugins: Replaced naive with true UTF8 to UTF16 conversion in optimized and pure kernels ## ## Technical diff --git a/src/modules/module_23700.c b/src/modules/module_23700.c index c315214ca..1d1f84a74 100644 --- a/src/modules/module_23700.c +++ b/src/modules/module_23700.c @@ -21,7 +21,8 @@ static const u32 HASH_CATEGORY = HASH_CATEGORY_ARCHIVE; static const char *HASH_NAME = "RAR3-p (Uncompressed)"; static const u64 KERN_TYPE = 23700; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; -static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE; +static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_POST_AMP_UTF16LE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "$RAR3$*1*e54a73729887cb53*49b0a846*16*14*1*34620bcca8176642a210b1051901921e*30"; @@ -117,7 +118,7 @@ u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED con { const bool optimized_kernel = (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL); - u32 pw_max = 127; + u32 pw_max = 64; if (optimized_kernel == true) { @@ -129,7 +130,7 @@ u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED con const char *module_benchmark_mask (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { - const char *mask = "?b?b?b?b?b"; + const char *mask = "?l?l?l?l?l"; return mask; } diff --git a/src/modules/module_23800.c b/src/modules/module_23800.c index 9b0a6eb2d..1a9a551e1 100644 --- a/src/modules/module_23800.c +++ b/src/modules/module_23800.c @@ -22,7 +22,8 @@ static const char *HASH_NAME = "RAR3-p (Compressed)"; static const u64 KERN_TYPE = 23800; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE - | OPTS_TYPE_HOOK23; + | OPTS_TYPE_HOOK23 + | OPTS_TYPE_POST_AMP_UTF16LE; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const char *ST_PASS = "hashcat"; static const char *ST_HASH = "$RAR3$*1*ad56eb40219c9da2*834064ce*32*13*1*eb47b1abe17a1a75bce6c92ab1cef3f4126035ea95deaf08b3f32a0c7b8078e1*33"; @@ -400,7 +401,7 @@ u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED con { const bool optimized_kernel = (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL); - u32 pw_max = 127; + u32 pw_max = 64; if (optimized_kernel == true) { @@ -412,7 +413,7 @@ u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED con const char *module_benchmark_mask (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { - const char *mask = "?b?b?b?b?b"; + const char *mask = "?l?l?l?l?l"; return mask; } diff --git a/tools/test_modules/m23700.pm b/tools/test_modules/m23700.pm index ed4191ba5..eb0b4dbd2 100644 --- a/tools/test_modules/m23700.pm +++ b/tools/test_modules/m23700.pm @@ -13,7 +13,7 @@ use Crypt::CBC; use Encode; use Digest::CRC qw (crc32); -sub module_constraints { [[0, 127], [8, 8], [0, 20], [8, 8], [-1, -1]] } +sub module_constraints { [[0, 64], [8, 8], [0, 20], [8, 8], [-1, -1]] } my $ITERATIONS = 0x40000;