Contents

Practical Reverse Engineering Exercise Solutions: RtlValidateUnicodeString

Contents

This blog post contains my solution for the decompilation exercise of the RtlValidateUnicodeString function in the Windows Kernel. The following contains the disassembly without annotations:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
kd> uf rtlvalidateunicodestring
ntdll!RtlValidateUnicodeString:
77686f6c 8bff            mov     edi,edi
77686f6e 55              push    ebp
77686f6f 8bec            mov     ebp,esp
77686f71 837d0800        cmp     dword ptr [ebp+8],0
77686f75 0f85fc380300    jne     ntdll!RtlValidateUnicodeString+0xb (776ba877)

ntdll!RtlValidateUnicodeString+0x12:
77686f7b 6800010000      push    100h
77686f80 ff750c          push    dword ptr [ebp+0Ch]
77686f83 e809000000      call    ntdll!RtlUnicodeStringValidateEx (77686f91)

ntdll!RtlValidateUnicodeString+0x1f:
77686f88 5d              pop     ebp
77686f89 c20800          ret     8

ntdll!RtlValidateUnicodeString+0xb:
776ba877 b80d0000c0      mov     eax,0C000000Dh
776ba87c e907c7fcff      jmp     ntdll!RtlValidateUnicodeString+0x1f (77686f88)

The function prototype is given here:

1
NTSTATUS NTAPI RtlValidateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING UnicodeString);

Note that the function returns an NTSTATUS value, which is publicly documented by Microsoft at https://msdn.microsoft.com/en-us/library/cc704588.aspx.

Other relevant data structures are _unicode_string:

1
2
3
4
kd> dt nt!_unicode_string
   +0x000 Length           : Uint2B
   +0x002 MaximumLength    : Uint2B
   +0x004 Buffer           : Ptr32 Uint2B

The following listing gives the disassembly with my annotations / comments:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
kd> uf rtlvalidateunicodestring
ntdll!RtlValidateUnicodeString:
; hot-patch point
77686f6c 8bff            mov     edi,edi 

; function prologue
77686f6e 55              push    ebp
77686f6f 8bec            mov     ebp,esp

; check if Flags are set to zero
77686f71 837d0800        cmp     dword ptr [ebp+8],0
77686f75 0f85fc380300    jne     ntdll!RtlValidateUnicodeString+0xb (776ba877)

; Flags are set to  zero
ntdll!RtlValidateUnicodeString+0x12:

77686f7b 6800010000      push    100h
77686f80 ff750c          push    dword ptr [ebp+0Ch]
; call RtlUnicodeStringValidateEx(UnicodeString, 0x100)
77686f83 e809000000      call    ntdll!RtlUnicodeStringValidateEx (77686f91)

ntdll!RtlValidateUnicodeString+0x1f:
; function epilogue
77686f88 5d              pop     ebp
77686f89 c20800          ret     8


ntdll!RtlValidateUnicodeString+0xb:
; flags are not set to zero
776ba877 b80d0000c0      mov     eax,0C000000Dh
; Function return value is set to 0x0C000000D
776ba87c e907c7fcff      jmp     ntdll!RtlValidateUnicodeString+0x1f (77686f88)

Finally, the decompiled function is provided:

1
2
3
4
5
6
7
NTSTATUS NTAPI RtlValidateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING UnicodeString){
 if (Flags != 0) {
  return 0x0C000000D // corresponding NTSTATUS: STATUS_INVALID_PARAMETER
  }
 RtlUnicodeStringValidateEx(UnicodeString, 0x100);
 return
}