Jump to content

Propar syntax for DllCall and RtlHashUnicodeString in ntdll.dll


ilko
 Share

Recommended Posts

Hi,

Input string-

"USBSTOR\Disk&Ven_LEXAR&Prod_JD_LIGHTNING_II&Rev_1100\AA04015900000158&0"
. This has to be capitalized and converted to Windows unicode, maybe using RtlAnsiStringToUnicodeString if cannot be done easily in AutoIt, then a hash of the unicode converted string calculated by using RtlHashUnicodeString. Need as output the hash of that string.

Those are in ntdll.dll, but I've had no luck so far finding the proper syntax in AutoIt

$hwid = "USBSTOR\Disk&Ven_LEXAR&Prod_JD_LIGHTNING_II&Rev_1100\AA04015900000158&0"
$result = DllCall("ntdll.dll", "str", "RtlHashUnicodeString", "wstr", $hwid, "int", 0, "str", "HASH_STRING_ALGORITHM_DEFAULT", "str", $out)
This and similar attempts fail with AutoIt crash, assuming wrong parameters are passed to ntdll.dll...

I am quite new to all this, please bear with me :)

Thanks in advance

Link to comment
Share on other sites

See if this works:

ConsoleWrite(_RtlHashUnicodeString("ilko") & @CRLF)


Func _RtlHashUnicodeString($sString) ;SDBM-32

    Local $iStringLen = StringLen($sString)

    Local $tString = DllStructCreate("wchar[" & ($iStringLen + 1) & "]")
    DllStructSetData($tString, 1, $sString)

    Local $tLSA_UNICODE_STRING = DllStructCreate("align 2;ushort Length;" & _
            "ushort MaximumLength;" & _
            "ptr Buffer")

    DllStructSetData($tLSA_UNICODE_STRING, "Length", 2 * $iStringLen)
    DllStructSetData($tLSA_UNICODE_STRING, "MaximumLength", 2 * $iStringLen)
    DllStructSetData($tLSA_UNICODE_STRING, "Buffer", DllStructGetPtr($tString))

    Local $aCall = DllCall("ntdll.dll", "int", "RtlHashUnicodeString", _
            "ptr", DllStructGetPtr($tLSA_UNICODE_STRING), _
            "int", 0, _ ; CaseSensitive
            "dword", 1, _ ; HASH_STRING_ALGORITHM_X65599
            "dword*", 0)

    If @error Or $aCall[0] Then
        Return SetError(1, 0, "")
    EndIf

    Return Hex($aCall[4])

EndFunc   ;==>_RtlHashUnicodeString
Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

That works, thanks a lot, wouldn't have done it :)

Unfortunately the result is not what I hoped for- the same result as from HASH_UNICODE_STRING:

http://bbs.driverdevelop.com/htm_data/16/0508/96099.html

#define HASH_UNICODE_STRING( _pustr, _phash ) {                             \
    PWCHAR _p = (_pustr)->Buffer;                                           \
    PWCHAR _ep = _p + ((_pustr)->Length/sizeof(WCHAR));                     \
    ULONG _chHolder =0;                                                     \
                                                                            \
    while( _p < _ep ) {                                                     \
        _chHolder = 37 * _chHolder + (unsigned int) (*_p++);                \
    }                                                                       \
                                                                            \
    *(_phash) = abs(314159269 * _chHolder) % 1000000007;                    \
}
which I hardly can interpret correctly and redo in AutoIt :)

With input

USBSTOR\Disk&Ven_LEXAR&Prod_JD_LIGHTNING_II&Rev_1100\AA04015900000158&0
capitalized and converted to unicode, expected result is "16f722a4".
Link to comment
Share on other sites

That works, thanks a lot, wouldn't have done it :)

Unfortunately the result is not what I hoped for- the same result as from HASH_UNICODE_STRING:

http://bbs.driverdevelop.com/htm_data/16/0508/96099.html

#define HASH_UNICODE_STRING( _pustr, _phash ) {                             \
    PWCHAR _p = (_pustr)->Buffer;                                           \
    PWCHAR _ep = _p + ((_pustr)->Length/sizeof(WCHAR));                     \
    ULONG _chHolder =0;                                                     \
                                                                            \
    while( _p < _ep ) {                                                     \
        _chHolder = 37 * _chHolder + (unsigned int) (*_p++);                \
    }                                                                       \
                                                                            \
    *(_phash) = abs(314159269 * _chHolder) % 1000000007;                    \
}
which I hardly can interpret correctly and redo in AutoIt :)

With input

USBSTOR\Disk&Ven_LEXAR&Prod_JD_LIGHTNING_II&Rev_1100\AA04015900000158&0
capitalized and converted to unicode, expected result is "16f722a4".

That's not algorithm used for RtlHashUnicodeString function obviously.

RtlHashUnicodeString uses 'sdbm'. Translated to AutoIt it would be:

Func _SDBM32($sString)

    Local $aArray = StringToASCIIArray($sString)
    Local $iHash = 0

    For $i = 0 To UBound($aArray) - 1
        $iHash = $aArray[$i] + BitShift($iHash, -6) + BitShift($iHash, -16) - $iHash
    Next

    Return Hex($iHash)

EndFunc

Or if you are interested why Microsoft calls it HASH_STRING_ALGORITHM_X65599:

Func _SDBM32($sString)

    Local $aArray = StringToASCIIArray($sString)
    Local $iHash = 0

    For $i = 0 To UBound($aArray) - 1
        $iHash = $iHash * 65599 + $aArray[$i]
    Next

    Return Hex($iHash)

EndFunc

You can derive code for your needs from that last example.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

  • 2 weeks later...

Hmm, what am I doing wrong again?

#include <String.au3>
$sString='USBSTOR\Disk&Ven_LEXAR&Prod_JD_LIGHTNING_II&Rev_1100\AA04015900000158&0'
MsgBox(0,"",_HASH_UNI(StringUpper($sString)))


Func _HASH_UNI($sString)

    Local $aArray = StringToASCIIArray($sString)
    Local $bArray[UBound($aArray)*2]
    For $i = 0 To UBound($aArray) - 1
        $j = $i * 2
        $bArray[$j] = $aArray[$i]
        $bArray[$j+1] = 0
    Next
    Local $iHash = 0

    For $i = 0 To UBound($bArray) - 1
        $iHash = 37 * $iHash + $bArray[$i]
    Next
    $out = mod(abs(314159269 * $iHash),1000000007)
    Return Hex($out)

EndFunc

Playing with StringToASCIIArray options or inserting 0s in the array to get close to MS unicode representation, as I understand it, does not bring me close to the expected result "16f722a4". :)

Link to comment
Share on other sites

It's because of the int value roll so it can be:

Func _HASH_UNI($sString)

    Local $aArray = StringToASCIIArray($sString)
    Local $iHash = 0
    Local $tHash = DllStructCreate("uint")

    For $i = 0 To UBound($aArray) - 1
        DllStructSetData($tHash, 1, 37 * DllStructGetData($tHash, 1) + $aArray[$i])
    Next
    Local $tInt = DllStructCreate("int")
    DllStructSetData($tInt, 1, 314159269 * DllStructGetData($tHash, 1))
    
    $out = mod(abs(DllStructGetData($tInt, 1)),1000000007)
    Return Hex($out)

EndFunc

..just to illustrate. You can come up without all this DllStruct stuff.

Link to comment
Share on other sites

You need to post the hash for some other string(s) for me (for example) to eliminate you as a possible bug element.

Am I clear enough? :)

With the attached file you can create as many as you like, use "Uppercase.." checked and Win2k button. PD level is not relevant, as it only adds it at the front of the generated prefix, i.e. string="arfgaqf" , PD level=6

ParentIDPrefix would be 6&hash_of_string.

@ Authenticity

Thanks, this works just as expected ;)

ParentIDGen.zip

Edited by ilko
Link to comment
Share on other sites

Small glitch-

$sString = 'USBSTOR\DISK&VEN_KINGSTON&PROD_DATATRAVELER_120&REV_1.00\00137297175CF971862F0A39&0'

_HASH_UNI output- 0d825748

HASH_UNICODE_STRING output- d825748

Is it Windows omitting the 0 at front, e.g. 0Axxxx--> Axxxx ?

Link to comment
Share on other sites

The Hex() function does not return the hex value but it's string representation with length of the second parameter (8 by default). It's similar to:

Local $iValue = 305419896
ConsoleWrite(StringFormat("%08X", $iValue) & @CRLF)

$iValue = 0xFF
ConsoleWrite(StringFormat("%08X", $iValue) & @CRLF)

You should not use the returned string representation as a value in computation or other int/double/uint/etc.. context, it's just a string.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...