Jump to content

Replace RtlInitUnicodeString with custom code


 Share

Recommended Posts

I am working with some native registry functions, and in order to handle invalid registry keys properly, I need to specify the keyname in hex. Note this is a must when invalid characters are in the middle of the key name, and not just appended to the end of name. So first the original code as I've used lately that uses RtlInitUnicodeString;

Global Const $tagOBJECTATTRIBUTES = "ulong Length;hwnd RootDirectory;ptr ObjectName;ulong Attributes;ptr SecurityDescriptor;ptr SecurityQualityOfService"
Global Const $tagUNICODESTRING = "ushort Length;ushort MaximumLength;ptr Buffer"

$objectname = "test"
$szName = DllStructCreate("wchar[260]")
$sUS = DllStructCreate($tagUNICODESTRING)
$sOA = DllStructCreate($tagOBJECTATTRIBUTES)
DllStructSetData($szName, 1, $objectname)
$ret = DllCall($hNTDLL, "none", "RtlInitUnicodeString", "ptr", DllStructGetPtr($sUS), "ptr", DllStructGetPtr($szName))
DllStructSetData($sOA, "Length", DllStructGetSize($sOA))
DllStructSetData($sOA, "RootDirectory", Chr(0))
DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS))
DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE)
DllStructSetData($sOA, "SecurityDescriptor", Chr(0))
DllStructSetData($sOA, "SecurityQualityOfService", Chr(0))

Now here's the attemped custom code that currently returns a 0xC0000033 (STATUS_OBJECT_NAME_INVALID);

Global Const $tagOBJECTATTRIBUTES = "ulong Length;hwnd RootDirectory;ptr ObjectName;ulong Attributes;ptr SecurityDescriptor;ptr SecurityQualityOfService"
Global Const $tagUNICODESTRING = "ushort Length;ushort MaximumLength;ptr Buffer"

$objectname = "7400650073007400"
$szName = DllStructCreate("wchar[260]")
$sUS = DllStructCreate($tagUNICODESTRING)
$sOA = DllStructCreate($tagOBJECTATTRIBUTES)
DllStructSetData($szName, 1, $objectname)
DllStructSetData($sUS,"Length",StringLen($ObjectName)/2)
DllStructSetData($sUS,"MaximumLength",StringLen($ObjectName)/2)
DllStructSetData($sUS,"Buffer",DllStructGetPtr($szName))
DllStructSetData($sOA, "Length", DllStructGetSize($sOA))
DllStructSetData($sOA, "RootDirectory", $handle)
DllStructSetData($sOA, "ObjectName", DllStructGetPtr($sUS))
DllStructSetData($sOA, "Attributes", $OBJ_CASE_INSENSITIVE)
DllStructSetData($sOA, "SecurityDescriptor", Chr(0))
DllStructSetData($sOA, "SecurityQualityOfService", Chr(0));Chr(0)

This is actually quite interesting because if we can manage to specify the name this way, we can also handle invalid key names much better than RegDelNull (which is crappy); http://technet.microsoft.com/en-us/sysinternals/bb897448. It already looks promising as I have a PoC identical to RegHide; http://technet.microsoft.com/en-us/sysinternals/dd581628.aspx and I can rename and/or delete invalid keynames (with nulls appended to end) entirely using native functions.

Edited by joakim
Link to comment
Share on other sites

Actually it was dividing by 2 that was correct, however the plus 2 in MaximumLength is crucial for the function to succeed. Beware that "7400" is 4 characters in non-binary, equivalent to "t", which is 2 bytes and not 4. I get back to it when the sample it finished.

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