RtlInitUnicodeString 函数的原型是:
<pre name="code" class="cpp">VOID WINAPI RtlInitUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_opt_ PCWSTR SourceString
);
UnicodeString结构体:
<pre><span style="color:Blue;">typedef</span> <span style="color:Blue;">struct</span> _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
在windbg中输入:
kd> u RtlInitUnicodeString l 15
nt!RtlInitUnicodeString:
8052bd6c 57 push edi
8052bd6d 8b7c240c mov edi,dword ptr [esp+0Ch]//SourceString
8052bd71 8b542408 mov edx,dword ptr [esp+8]//DestinationString
8052bd75 c70200000000 mov dword ptr [edx],0//先将UnicodeString前2个成员置0
8052bd7b 897a04 mov dword ptr [edx+4],edi//将字符串地址存入UnicodeString中
8052bd7e 0bff or edi,edi//判断源字符串是否为空指针
8052bd80 7422 je nt!RtlInitUnicodeString+0x38 (8052bda4)
8052bd82 83c9ff or ecx,0FFFFFFFFh//将ecx每位置一,ecx代表串长度。
8052bd85 33c0 xor eax,eax//eax清零
8052bd87 f266af repne scas word ptr es:[edi]
8052bd8a f7d1 not ecx
8052bd8c d1e1 shl ecx,1//计算源字符串字节数
8052bd8e 81f9feff0000 cmp ecx,0FFFEh//判断是否超长
8052bd94 7605 jbe nt!RtlInitUnicodeString+0x2f (8052bd9b)
8052bd96 b9feff0000 mov ecx,0FFFEh//不知道为什么单步执行不出现这条语句
8052bd9b 66894a02 mov word ptr [edx+2],cx//保存缓存大小
8052bd9f 49 dec ecx
8052bda0 49 dec ecx
8052bda1 66890a mov word ptr [edx],cx//保存实际字符数,即缓存-2
8052bda4 5f pop edi
8052bda5 c20800 ret 8
因为该函数就收的源地址字符串都是以大小为2字节的NULL结尾,所以可用缓存大小都比实际字符数多2.
所以UnicodeString结构体的三个成员代表的内容就是:
实际字符数
可用缓存大小
缓存地址