kd> u RtlInitUnicodeString 8052cda8
VOID RtlInitUnicodeString(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
nt!RtlInitUnicodeString:
; edi压栈
8052cd6c 57 push edi
; edi=SourceString,注意这里,因为参数都是用指针传递的,这里是指向了参数指针的实际内容
8052cd6d 8b7c240c mov edi,dword ptr [esp+0Ch]
; edx=DestinationString,同上面的注意点,指向了参数指针的实际内容
8052cd71 8b542408 mov edx,dword ptr [esp+8]
; edx指向的内存第一个字节设置为0
8052cd75 c70200000000 mov dword ptr [edx],0
; edx+4个字节(就是UNICODE_STRING.Buffer成员)指向了edi
8052cd7b 897a04 mov dword ptr [edx+4],edi
; edi本身没有变化,只影响了标志为ZF,其实就是判断edi是否是0
8052cd7e 0bff or edi,edi
; edi是0,跳到8052cda4继续处理,就是结束
8052cd80 7422 je nt!RtlInitUnicodeString+0x38 (8052cda4)
; ecx设置了一个极大值0FFFFFFFFh,用作循环变量
8052cd82 83c9ff or ecx,0FFFFFFFFh
; eax=0
8052cd85 33c0 xor eax,eax
; scas word 串扫描指令,用ax-di,其实就是判断什么时候di的内容是0,用结果设置ZF标志位,
; 不知道为什么,这里没有cld,设置方向标志位为0,每次循环edi+sizeof(word)
; 非0,那么继续,一直到找到di为0的那一位为止,这时候ecx和0FFFFFFFFh的差就是edi指向的
; 字符串的字长度
8052cd87 f266af repne scas word ptr es:[edi]
; 取反的结果是把ecx中的几个F(not 1111 = 0000)位都去除,对剩下的再取反就是用F...去减,
; 得到字符串的长度
8052cd8a f7d1 not ecx
; 因为ecx是字长度,为了得到字节长度,就乘以2,也就是左移1位
8052cd8c d1e1 shl ecx,1
; 比较ecx(得到的字节长度)和某个固定值(0FFFEh=65534)
8052cd8e 81f9feff0000 cmp ecx,0FFFEh
; 带符号比较,小于等于8052cd9b,跳到继续处理
8052cd94 7605 jbe nt!RtlInitUnicodeString+0x2f (8052cd9b)
; 长度最多设置到65534,这2条指令就是判断长度是否小于65535
8052cd96 b9feff0000 mov ecx,0FFFEh
; 因为最多是65534(2个字节可以表达),所以用了cx寄存器,edx+2是MaximumLength成员
8052cd9b 66894a02 mov word ptr [edx+2],cx
; 减2后作为现在字符串的长度
8052cd9f 49 dec ecx
8052cda0 49 dec ecx
8052cda1 66890a mov word ptr [edx],cx
8052cda4 5f pop edi
8052cda5 c20800 ret 8
闲着无事3 RtlInitUnicodeString
最新推荐文章于 2023-04-09 23:33:38 发布