Sign in to follow this  
Followers 0

Propar syntax for DllCall and RtlHashUnicodeString in ntdll.dll

12 posts in this topic

Posted

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

Share this post


Link to post
Share on other sites



Posted (edited)

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

Share this post


Link to post
Share on other sites

Posted

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".

Share this post


Link to post
Share on other sites

Posted

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.

Share this post


Link to post
Share on other sites

Posted

Thanks a lot, much appreciated. Now have something to play with :)

Share this post


Link to post
Share on other sites

Posted

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". :)

Share this post


Link to post
Share on other sites

Posted

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? :)

Share this post


Link to post
Share on other sites

Posted

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.

Share this post


Link to post
Share on other sites

Posted (edited)

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

Share this post


Link to post
Share on other sites

Posted

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 ?

Share this post


Link to post
Share on other sites

Posted

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.

Share this post


Link to post
Share on other sites

Posted

Got it, thanks :)

Share this post


Link to post
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
Sign in to follow this  
Followers 0