• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Script] StringHash ASM dump

Status
Not open for further replies.

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
539
As the title says i would love if someone would dump the asm for the StringHash native as the behavior was changed. I'm not too versed in circumventing anti RE protection but i can wade through the asm. So if someone has the knowledge, please dump the asm.
 
Level 19
Joined
Jan 3, 2022
Messages
320
StringHash was added in 1.24a and multi-byte character (Unicode) hashing was changed in 1.30.x
JASS:
function testStringHash takes string description, string text returns nothing
    call DisplayTextToPlayer( Player(0), 0, 0, description + ": '" + text + "' is (" + I2S(StringHash(text)) + ")" )
endfunction

function Trig_StringHashTest_Actions takes nothing returns nothing
    // User-defined
    local string udg_pathFORWARDSLASHto = "path/to"
    local string udg_pathBACKSLASHto = "path\\to"
    local string udg_case_upper = "CASE"
    local string udg_case_lower = "case"
    local string udg_empty_string = ""
 
    local string udg_singlequote = "'"
    local string udg_doublequote = "\""
 
    local string udg_cyrillic_lower_ya = "я"
    local string udg_german_lower_a_umlaut = "ä"
 
    local string udg_chinese_earth = "地球"
 
    // THE NEXT LINE WAS EDITED IN A HEX-EDITOR TO
    // PRODUCE A REAL 8-bit ASCII CHARACTER, NOT UNICODE'S UTF-8!
    // If you resave the file in a regular editor, it'll surely encode everything
    // as UTF-8.
    // Here was supposed to be the literal 8-bit \xA9 copyright character
    local string ascii_dec_169_copyright =   ""    // padding.
 
    call DisplayTextToForce( GetPlayersAll(), "TRIGSTR_005" )
    call testStringHash("lower-case word", udg_case_lower)
    call testStringHash("upper-case word", udg_case_upper)
    call testStringHash("empty string", udg_empty_string)
    call testStringHash("backslash path", udg_pathBACKSLASHto)
    call testStringHash("forward-slash path", udg_pathFORWARDSLASHto)
 
    call testStringHash("single-quote", udg_singlequote)
    call testStringHash("double-quote", udg_doublequote)
 
    call DisplayTextToPlayer( Player(0), 0, 0, "(Luashine) I saved war3map.j file encoded as UTF-8, Unicode tests:" )
 
    call testStringHash("cyrillic ya, lower-case, utf-8", udg_cyrillic_lower_ya)
    call testStringHash("german a umlaut, lower-case, utf-8", udg_german_lower_a_umlaut)
    call testStringHash("chinese simpl word earth, utf-8", udg_chinese_earth)
 
    call testStringHash("0xA9 or dec 169 aka copyright-sign via hex editor", ascii_dec_169_copyright)
 
    // Success!
    call DisplayTextToForce( GetPlayersAll(), "TRIGSTR_006" )
endfunction

v1.29.2 (Chinese) & v1.27 (German) - text rendering depends on version​

Code:
lower-case word: 'case' is (1865766789)
upper-case word: 'CASE' is (1865766789)
empty string: '' is (0)
backslash path: 'path\to' is (-1197512958)
forward-slash path: 'path/to' is (-1197512958)
single-quote: ''' is (-1415544861)
double-quote: '"' is (633424007)
-- ^ same for all ^ --

-- v different since 1.30.x v --
cyrillic ya, lower-case, utf-8: 'я' is (-1696602527)
german a umlaut, lower-case, utf-8: 'ä' is (1899444195)
chinese simpl word earth, utf-8: '地球' is (835900716)
0xA9 or dec 169 aka copyright-sign via hex editor: '\xA9' is (970678903)

v1.30.1 (Russian)​

Code:
cyrillic ya, lower-case, utf-8: 'я' is (-1527763325)
german a umlaut, lower-case, utf-8: 'ä' is (159638553)
chinese simpl word earth, utf-8: '地球' is (-1659141555)
0xA9 or dec 169 aka copyright-sign via hex editor: '\xA9' is (970678903)

I don't have 1.30.0 (anyone?) and I don't have enough time to test if the StringHash output is dependant on Windows' OS settings. All these links describe the same setting:
 
Last edited:
This is the dump from 1.33.

C++:
__int64 __fastcall sub_2DE270(_BYTE *a1)
{
  unsigned int v1; // edi
  unsigned __int8 *i; // rbx
  unsigned int v3; // eax
  unsigned int v5; // [rsp+20h] [rbp-438h] BYREF
  _BYTE *v6; // [rsp+28h] [rbp-430h] BYREF
  int v7[4]; // [rsp+30h] [rbp-428h] BYREF
  unsigned __int8 v8[1024]; // [rsp+40h] [rbp-418h] BYREF

  v1 = 0;
  v6 = a1;
  for ( i = v8; *v6; v5 = 0 )
  {
    if ( v1 >= 0x3FC )
      break;
    sub_2DD690(&v6, v7, (int *)&v5);
    v3 = v5;
    if ( v5 == 47 )
      v3 = 92;
    do
    {
      *i = v3;
      ++v1;
      ++i;
      v3 >>= 8;
    }
    while ( v3 );
  }
  *i = 0;
  return sub_2DF5E0(v8, v1, 0);
}
C++:
__int64 __fastcall sub_2DD690(_QWORD *a1, int *a2, int *a3)
{
  __int64 v5; // r11
  int v6; // ecx
  int v7; // er8
  int v8; // ecx
  int v9; // er8
  int v10; // ecx
  int v11; // er8
  int v12; // ecx
  int v13; // er8
  int v14; // ecx
  int v15; // er8
  __int64 result; // rax
  int v17; // ecx
  int v18; // ecx
  bool v19; // cc

  v5 = byte_214BA00[*(unsigned __int8 *)*a1];
  *a2 = 0;
  *a3 = 0;
  switch ( (int)v5 )
  {
    case 1:
      goto LABEL_13;
    case 2:
      goto LABEL_10;
    case 3:
      goto LABEL_8;
    case 4:
      goto LABEL_6;
    case 5:
      goto LABEL_4;
    case 6:
      v6 = *(unsigned __int8 *)(*a1)++;
      v7 = v6 + *a2;
      *a2 = v7;
      if ( !*(_BYTE *)*a1 )
        return 0i64;
      *a2 = v7 << 6;
LABEL_4:
      v8 = *(unsigned __int8 *)(*a1)++;
      v9 = v8 + *a2;
      *a2 = v9;
      if ( !*(_BYTE *)*a1 )
        return 0i64;
      *a2 = v9 << 6;
LABEL_6:
      v10 = *(unsigned __int8 *)(*a1)++;
      v11 = v10 + *a2;
      *a2 = v11;
      if ( !*(_BYTE *)*a1 )
        return 0i64;
      *a2 = v11 << 6;
LABEL_8:
      v12 = *(unsigned __int8 *)(*a1)++;
      v13 = v12 + *a2;
      *a2 = v13;
      if ( !*(_BYTE *)*a1 )
        return 0i64;
      *a2 = v13 << 6;
LABEL_10:
      v14 = *(unsigned __int8 *)(*a1)++;
      v15 = v14 + *a2;
      *a2 = v15;
      if ( !*(_BYTE *)*a1 )
        return 0i64;
      *a2 = v15 << 6;
LABEL_13:
      v17 = *(unsigned __int8 *)(*a1)++;
      *a2 += v17;
LABEL_14:
      *a2 -= dword_214B9E0[v5];
      v18 = *a2;
      if ( (unsigned int)*a2 > 0xFFFF )
      {
        v18 = 65533;
        *a2 = 65533;
      }
      if ( (_DWORD)v5 == 1 )
      {
        v19 = (unsigned int)(v18 - 97) <= 0x19;
      }
      else
      {
        if ( (_DWORD)v5 != 2 )
          goto LABEL_27;
        if ( (unsigned int)(v18 - 224) <= 0x1E )
          goto LABEL_26;
        if ( v18 == 339 )
        {
          result = (unsigned int)v5;
          *a3 = 338;
          return result;
        }
        if ( v18 == 1105 )
        {
          result = (unsigned int)v5;
          *a3 = 1025;
          return result;
        }
        v19 = (unsigned int)(v18 - 1072) <= 0x1F;
      }
      if ( !v19 )
        goto LABEL_27;
LABEL_26:
      v18 -= 32;
LABEL_27:
      *a3 = v18;
      return (unsigned int)v5;
    default:
      goto LABEL_14;
  }
}
C++:
__int64 __fastcall sub_2DF5E0(unsigned __int8 *a1, unsigned int a2, int a3)
{
  unsigned int v3; // er9
  unsigned int v4; // ebx
  int v5; // er10
  unsigned int v7; // edi
  __int64 v8; // rdx
  int v9; // er9
  unsigned int v10; // er8
  int v11; // eax
  int v12; // ecx
  int v13; // er10
  unsigned int v14; // er9
  unsigned int v15; // er8
  int v16; // er10
  unsigned int v17; // er9
  unsigned int v18; // er8
  unsigned int v19; // er8
  int v20; // er10
  unsigned int v21; // er9
  unsigned int v22; // er8
  int v23; // er10
  unsigned int v24; // er9
  unsigned int v25; // er8
  int v26; // er10

  v3 = -1640531527;
  v4 = a2;
  v5 = -1640531527;
  v7 = a2;
  if ( a2 >= 0xC )
  {
    v8 = a2 / 0xC;
    do
    {
      v7 -= 12;
      v9 = ((a1[5] + ((a1[6] + (a1[7] << 8)) << 8)) << 8) + a1[4] + v3;
      v10 = ((a1[9] + ((a1[10] + (a1[11] << 8)) << 8)) << 8) + a1[8] + a3;
      v11 = *a1;
      v12 = (a1[1] + ((a1[2] + (a1[3] << 8)) << 8)) << 8;
      a1 += 12;
      v13 = (v10 >> 13) ^ (v11 + v12 - v10 - v9 + v5);
      v14 = (v13 << 8) ^ (v9 - v10 - v13);
      v15 = (v14 >> 13) ^ (v10 - v14 - v13);
      v16 = (v15 >> 12) ^ (v13 - v15 - v14);
      v17 = (v16 << 16) ^ (v14 - v15 - v16);
      v18 = (v17 >> 5) ^ (v15 - v17 - v16);
      v5 = (v18 >> 3) ^ (v16 - v18 - v17);
      v3 = (v5 << 10) ^ (v17 - v18 - v5);
      a3 = (v3 >> 15) ^ (v18 - v3 - v5);
      --v8;
    }
    while ( v8 );
  }
  v19 = v4 + a3;
  switch ( v7 )
  {
    case 1u:
      goto LABEL_15;
    case 2u:
      goto LABEL_14;
    case 3u:
      goto LABEL_13;
    case 4u:
      goto LABEL_12;
    case 5u:
      goto LABEL_11;
    case 6u:
      goto LABEL_10;
    case 7u:
      goto LABEL_9;
    case 8u:
      goto LABEL_8;
    case 9u:
      goto LABEL_7;
    case 0xAu:
      goto LABEL_6;
    case 0xBu:
      v19 += a1[10] << 24;
LABEL_6:
      v19 += a1[9] << 16;
LABEL_7:
      v19 += a1[8] << 8;
LABEL_8:
      v3 += a1[7] << 24;
LABEL_9:
      v3 += a1[6] << 16;
LABEL_10:
      v3 += a1[5] << 8;
LABEL_11:
      v3 += a1[4];
LABEL_12:
      v5 += a1[3] << 24;
LABEL_13:
      v5 += a1[2] << 16;
LABEL_14:
      v5 += a1[1] << 8;
LABEL_15:
      v5 += *a1;
      break;
    default:
      break;
  }
  v20 = (v19 >> 13) ^ (v5 - v19 - v3);
  v21 = (v20 << 8) ^ (v3 - v19 - v20);
  v22 = (v21 >> 13) ^ (v19 - v21 - v20);
  v23 = (v22 >> 12) ^ (v20 - v22 - v21);
  v24 = (v23 << 16) ^ (v21 - v22 - v23);
  v25 = (v24 >> 5) ^ (v22 - v24 - v23);
  v26 = (v25 >> 3) ^ (v23 - v25 - v24);
  return (((v26 << 10) ^ (v24 - v25 - v26)) >> 15) ^ (v25 - ((v26 << 10) ^ (v24 - v25 - v26)) - v26);
}
 
Status
Not open for further replies.
Top