IonicWind Software

IWBasic => General Questions => Topic started by: Andy on October 05, 2017, 04:01:23 AM

Title: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Andy on October 05, 2017, 04:01:23 AM
Not one to give up, I thought I'd have a look at the NtRenameKey function again.

And I declare it as:
declare extern NtRenameKey(hKey as uint,Name as wstring),Uint

Now I haven't really used Wstrings very much but when I pass hKey (a handle) and Name (a Wstring) to the NtRenameKey function it returns with the error STATUS_DATATYPE_MISALIGNMENT.

Sapero posted something about this here:

http://www.ionicwind.com/forums/index.php?topic=1693.msg15605#msg15605 and

http://www.ionicwind.com/forums/index.php?topic=1060.msg9818#msg9818

- but as most things with Sapero it just has me confused.

This what I'm trying (but you won't be able to compile it):


$include "registrylib.inc"

declare extern NtRenameKey(hKey as uint,Name as wstring),Uint

UINT hInst=LoadLibrary("ntdll.dll")
UINT proc = GetProcAddress(hInst,"NtRenameKey")

uint rHandle = 0
string dummy = ""
wstring w = s2w("ATEST\x00")

openconsole
print
print
print "  Library ntdll.dll handle ",hInst," is ok"
print "  NtRenameKey Proc handle ",proc," is ok"

rHandle = RegCreateKeyHandle("HKEY_CURRENT_USER\\Software\\Test")

print
print "  Handle to key I want to rename ",rHandle," is ok"
print
print "  Result ",!<NtRenameKey>proc(rHandle,w)," error! (STATUS_DATATYPE_MISALIGNMENT)"
print
print

'RegCloseKey(rHandle)
FreeLibrary(hInst)

do:until inkey$ <> ""
closeconsole
end


I'm trying to rename the key from "Test" to "ATEST".

Any ideas anyone?

Thanks.

Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Brian on October 05, 2017, 05:35:27 AM
Andy,

Doesn't S2W convert an ANSI string to wide string? You are already putting a
WSTRING in and asking to convert it to a WSTRING, as well. Maybe it should
just be STRING w=S2W

Brian
Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Andy on October 05, 2017, 05:46:02 AM
Brian,

Making "w" a string gives a compiler error.

The other thing that confuses me is that the help file says a wstring is 512 in length, but when I use the sizeof(w) command it returns 510?

Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Brian on October 05, 2017, 06:04:00 AM
Andy,

Have you looked at the UNICODE command in the Help File? It may do what you want

Brian
Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Andy on October 06, 2017, 03:29:18 AM
The unicode section of the help file tells me wstrings are automatically set to 255 characters so why it should double using sizeof(x) to 510 is a mystery.

I'm wondering if the declare line is correct?

declare extern NtRenameKey(hKey as uint,Name as Wstring),Uint

This is a link from ms showing the parameters of NtRenameKey function:

https://msdn.microsoft.com/en-us/library/cc512138(v=vs.85).aspx

Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: jalih on October 06, 2017, 07:13:27 AM
Quote from: Andy on October 06, 2017, 03:29:18 AM
The unicode section of the help file tells me wstrings are automatically set to 255 characters so why it should double using sizeof(x) to 510 is a mystery
255 characters, 2 bytes per character.
Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Andy on October 06, 2017, 09:07:17 AM
Thanks Jalih,

That answers that question, so the next question is:

Do we have to pad every normal string character to 2 bytes so that the string and wstring are aligned?

And isn't that what the S2W command is doing?

Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: fasecero on October 06, 2017, 05:33:56 PM
Hi Andy, I don't have much time to look at this right now but I think this will not be an easy task. Some hints:

NTSTATUS NtRenameKey(uint KeyHandle, POINTER NewName);

- Not sure if you can use a key from RegOpenKeyEx as KeyHandle in NtRenameKey. Maybe NtRenameKey param needs to be adquired by using NtOpenKey or NtOpenKeyEx, I have never use these. But I repeat, I am not sure about this.

- NewName is not a pointer to wstring, it's a pointer to UNICODE_STRING structure
https://msdn.microsoft.com/en-us/library/windows/hardware/ff564879(v=vs.85).aspx

You need to declare a UNICODE_STRING, use RtlZeroMemory on it and then you can initialize it with RtlUnicodeStringInit  :P
Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: fasecero on October 07, 2017, 08:36:17 PM
Well, I did check these ideas... RegOpenKeyEx works just fine, there's no RtlUnicodeStringInit at Sapero's includes so I just hard code the UNICODE struct. The example rename "HKEY_CURRENT_USER\Software\temp" to "HKEY_CURRENT_USER\Software\TEST_RENAMED"


$INCLUDE "windowssdk.inc"
$INCLUDE "Ntddk.inc"

DECLARE NtRenameKey(UINT hKey, pointer newName), UINT

' -------

UINT hKey = 0
UINT result = 0

IF RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Test", 0, KEY_ALL_ACCESS, hKey) = 0 THEN
result = RenameKey(hKey, L"TEST_RENAMED")
RegCloseKey(hKey)

PRINT GetResultMessage(result)

ENDIF

DO:UNTIL INKEY$ <> ""

' -------

SUB RenameKey(UINT hKey, pointer newName), UINT
UINT result = 0

UINT hInst=LoadLibrary("ntdll.dll")

IF hInst THEN
UINT proc = GetProcAddress(hInst,"NtRenameKey")

IF proc THEN
UNICODE_STRING ReplacementName
RtlZeroMemory(&ReplacementName, LEN(ReplacementName))

WCHAR temp = 0
ReplacementName.Buffer = newName
ReplacementName.Length = wcslen(newName) * LEN(temp)
ReplacementName.MaximumLength = LEN(newName)

result = !<NtRenameKey>proc(hKey, &ReplacementName)
ENDIF

FreeLibrary(hInst)
ENDIF

RETURN result
ENDSUB

SUB GetResultMessage(uint _Erro), STRING
STRING message = ""

uint nSize = 0
uint Arguments = 0
POINTER ErMes = 0

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0,_Erro,0, &ErMes,nSize,Arguments)
message = *<string>ErMes
LocalFree(ErMes)

RETURN message
ENDSUB

Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Andy on October 09, 2017, 01:41:35 AM
Fasecero,

Yes that really works, and it's fast, just one little thing, I had to amend the ntdef.inc file from:

$ifndef __IWBIDE__
typedef BYTE Schar


To:

$ifndef __IWBIDE__
'typedef BYTE Schar


So I've made a copy with the amendment and I'm using that include file instead.

But thanks again for solving this one!
Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: fasecero on October 09, 2017, 02:02:13 PM
Aw, just remove temp variable completely and replace the code below so there's no need to modify that file

ReplacementName.Buffer = newName
ReplacementName.Length =  2 * wcslen(newName)
ReplacementName.MaximumLength = LEN(newName)
Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Andy on October 11, 2017, 04:55:34 AM
Been delayed a couple of days so I've only just got back to this.

I tried that, it didn't work then it dawned on me it won't because it's actually a definition in ntdef.inc which is included at compile time.

So the only way around it is to comment out the line in ntdef.inc:

'typedef BYTE schar

and save it as something like ntdef2.inc - and include this in any code.

$INCLUDE "windowssdk.inc"
$INCLUDE "Ntdef2.inc"



Title: Re: Wstrings and STATUS_DATATYPE_MISALIGNMENT
Post by: Andy on October 12, 2017, 12:10:09 AM
Thanks everybody for helping with this topic.

For me it was about two things:

1. How to overcome / use unicode strings, that is how to pass a normal string to a unicode string and avoid "data misalignment" (something I'd never heard of before) at compile time.

2. Using a native Ntdll function to see if it any quicker than an api call - which it is.  After testing both NtRenameKey (ntdll) and RegCopyTree plus RegDeleteKey (Advapi32) I found that NtRenameKey was twice as fast.

NtRenameKey returns after around 15 milliseconds, where the Advapi32 functions return after around 31 milliseconds.

Although as a human, the difference of around 15 / 16 milliseconds makes no noticeable difference in performance / response to me (although it might on a very large registry key).

Should I replace RegCopyTree plus RegDeleteKey (Advapi32) with NtRenameKey (ntdll)? I will think on that one.....

Once again guys, Thanks!!!