精确逆向未公开的windows内部函数RtlpGetAssemblyStorageMapRootLocation的源代码。截止2022年5月30日,该函数没有在网络上找到任何有效的公开信息。
从函数名称推测,函数的功能是获取程序集存储映射的根位置。 借助IDA Pro,分析该函数的参数、局部变量和相关调用。详细IDA Pro反汇编代码请访问 https://gitee.com/asminlife/rtlp-get-assembly-storage-map-root-location-reversing/blob/master/%E5%8F%8D%E6%B1%87%E7%BC%96%E4%BB%A3%E7%A0%81.asm
函数的相关调用
这些错误信息表明,函数可能通过查询注册表键值来获得程序集的位置信息。
第一个参数先被放在eax中,随后 arg_0 的值给了RootDirectory ,根据_OBJECT_ATTRIBUTES结构的定义,可以确定arg_0是HANDLE类型,它是一个根对象目录句柄。
第二个参数移动到ecx,随后它被保存在局部变量var_224,最后var_224的地址传递给了ObjectAttributes.ObjectName所以第二个参数是对象名称,根据 _OBJECT_ATTRIBUTES结构的定义,它是PUNICODE_STRING类型
观察这些指令对第三个参数arg_8的操作,表明它是一个32位指针,暂时不明确类型。
初步判断,函数应该是通过传递根对象目录句柄、对象名称和一个未知指针参数来获取程序集的位置。
这段代码主要是初始化一些局部变量,把对象名称存储到var_224,然后开始检查参数。 任意一个参数为0,则函数退出,并返回一个错误代码。以下是代码还原:
这段代码主要是对ObjectAttributes结构的成员进行初始化,用第一个参数作为对象目录句柄,第二个参数作为对象名称。随后调用ZwOpenKey函数打开对象arg_4的注册表项,以下是代码还原:
这段代码调用ZwQueryValueKey函数,以下是MSDN上的函数说明
调用ZwQueryValueKey函数时,第三个参数是一个枚举变量,它在KEY_VALUE_INFORMATION_CLASS中定义。它确定了第四个参数 KeyValueInformation 缓冲区中返回的信息的类型。 调用时向KeyValueInformationClass传递的实际参数为数值2,所以我们可以确定第四个参数KeyValueInformation指向一个KEY_VALUE_PARTIAL_INFORMATION结构体变量。 此外,stru_7DF1C658被发现是一个在函数外部定义的LSA_UNICODE_STRING结构体变量,里面保存的是注册表的键"Location", 现在我们可以确认之前的猜测,函数确实是通过查询注册表键值来获得程序集的位置信息。 根据ZwQueryValueKey的最后一个参数信息,修改局部变量ResultLength的类型为ULONG。 以下是代码还原:
如果调用ZwOpenKey失败,则跳转到.text:7DF1C534 ,如果调用ZwQueryValueKey失败则跳转到.text:7DF1C56E,两个代码段处理的目的都是为了打印错误消息,并跳转到程序结尾loc_7DF1C631。这里列出代码详细逻辑:
在前面调用ZwQueryValueKey的第三个参数(KeyValueInformationClass)时我们看到,它指出了KeyValueInformation的类型信息, KeyValueInformationClass的实际参数的值为2。根据函数ZwQueryValueKey的说明,这个值是枚举类型KEY_VALUE_INFORMATION_CLASS定义的, 参考定义我们得出KEY_VALUE_INFORMATION_CLASS的值2对应的项为为KEY_VALUE_PARTIAL_INFORMATION。也就是说,KeyValueInformation指向一个 KEY_VALUE_PARTIAL_INFORMATION结构体变量。到这里,我们已经可以完全的推断出KeyValueInformation附近几个局部变量的数据类型和含义了。
回顾IDA Pro给出的局部变量分析:
结合KEY_VALUE_PARTIAL_INFORMATION结构体的定义,我们可以得出
KeyValueInformation中保存着键值和相关信息,是本函数的关键数据结构。
指令比较了KeyValueInformation->Type值和1是否相等,根据winnt.h中对KeyValueInformation->Type值的宏定义, 指令的意图在于测试获得的键值是否为unicode空终止字符串。如果不是,则调用DbgPrintEx输出错误信息。(错误信息aSxsAssemblySto_1的内容也印证了这个推断) 至此,代码还原如下:
如果键值是unicode空终止字符串,则程序跳转到loc_7DF1C59B。这段代码检查了Size也就是KeyValueInformation->DataLength的值,DataLength描述的是以字节为单位的数据长度。指令使用了al和1进行测试, 实际上是对比了DataLength的最低位是否为1,如果为1,则表明它是一个单数。而微软保存unicode字符的类型是一个16位utf-16的类型。 也就是说,无论保存的键值长度是多少,它的字节数都为偶数。在这里测试最低位是否为单数,再根据错误消息aSxsAssemblySto_3[] = "SXS: Assembly storage root location value has non-even size"的定义,编写者似乎在确认键值的unicode规范性。 代码还原如下:
如果键值的unicode规范性OK,则程序跳转到loc_7DF1C5BC。这里首先分析数据的类型,因为这段代码的指令对数据的操作让人感到很疑惑。
指令明确的告诉我们,arg_8(ESI)指向的是一个2字节的数据,考虑到之后的比较指令 是jbe,则arg_8指向的可能是一个2字节的unsigned short int变量,因为被比较的数是ULONG类型。
指令告诉我们,arg_8+2指向的也是一个2字节的,它也可能是unsigned short int的变量。
再分析这段代码的逻辑结构:
这里的esi是参数arg_8,代码把arg_8+2处的2个字节扩展并传送到ecx 接下来的一条指令
,这里的eax是KeyValueInformation.DataLength(ULONG类型) 代码编写者试图对比两个变量的大小。如果DataLength更大,则将DataLength和0FFFEh进行对比,如果它仍然大于0FFFEh,则打印错误消息 并返回错误代码。考虑到windows径的最大长度为MAX_PATH,定义为 260 个字符,除去驱动器标识x:\和空结尾,则最大长度为0xFFFE,代码应该 在测试路径是否越过最大的长度。根据错误消息aSxsAssemblySto_0的提示,也可以确认这一点。
如果DataLength比arg_8+2更小或相等,则程序会跳转到loc_7DF1C60B,调用memcpy函数把键值拷贝 到arg_8+4指向的指针(arg_8指向的是一个重要的数据结构),随后代码将DataLength的低16位拷贝到 arg_8, 并返回0表示函数成功。
如果DataLength比arg_8+2更大,但小于等于0xFFFE,则程序跳转到loc_7DF1C5E9,将DataLength的低16位拷贝到arg_8+2。 随后调用未公开的函数RtlpAllocateEnvBlock 分配DataLength低16位的数量的线程环境块TEB,由于RtlpAllocateEnvBlock没有公开信息,目前只是对函数功能的推测。最后,代码 检查RtlpAllocateEnvBlock是否调用成功,如果成功则程序跳转到loc_7DF1C60B,调用memcpy函数把键值拷贝 到arg_8+4指向的指针(进一步确认了arg_8指向的是一个重要数据结构),随后代码将DataLength的低16位拷贝到 arg_8, 并返回0表示函数成功。
至此,整个函数逆向分析工作已经全部完成,函数通过打开对象的注册表项,查询注册表键Location的值来获取程序集的路径。在获取路径之后,对路径字符串进行了一系列的unicode检查。如果路径字符串合规,则将键值DataLength和参数arg_8指向的前4个字节进行一系列对比,并根据对比结果进行相关数据操作。最终,程序集的路径字符串被拷贝到arg_8+4指向的地址,函数返回0。其中,RtlpAllocateEnvBlock函数的功能仍然是一个迷,arg_8指向的详细数据结构也仍然是一个迷。但是,目前不再深究这些谜题的答案。完整的还原代码请访问https://gitee.com/asminlife/rtlp-get-assembly-storage-map-root-location-reversing/blob/master/%E8%BF%98%E5%8E%9F%E4%BB%A3%E7%A0%81.c
ObjectAttributes
=
_OBJECT_ATTRIBUTES ptr
-
240h
ResultLength
=
dword ptr
-
228h
var_224
=
dword ptr
-
224h
KeyHandle
=
dword ptr
-
220h
KeyValueInformation
=
byte ptr
-
21Ch
var_218
=
dword ptr
-
218h
Size
=
dword ptr
-
214h
Src
=
byte ptr
-
210h
var_4
=
dword ptr
-
4
arg_0
=
dword ptr
8
arg_4
=
dword ptr
0Ch
arg_8
=
dword ptr
10h
ObjectAttributes
=
_OBJECT_ATTRIBUTES ptr
-
240h
ResultLength
=
dword ptr
-
228h
var_224
=
dword ptr
-
224h
KeyHandle
=
dword ptr
-
220h
KeyValueInformation
=
byte ptr
-
21Ch
var_218
=
dword ptr
-
218h
Size
=
dword ptr
-
214h
Src
=
byte ptr
-
210h
var_4
=
dword ptr
-
4
arg_0
=
dword ptr
8
arg_4
=
dword ptr
0Ch
arg_8
=
dword ptr
10h
.text:
7DF1C529
call _ZwOpenKey@
12
; ZwOpenKey(x,x,x)
.text:
7DF1C563
call _ZwQueryValueKey@
24
; ZwQueryValueKey(x,x,x,x,x,x)
.text:
7DF1C57E
call _DbgPrintEx
.text:
7DF1C5AD
call _DbgPrintEx
.text:
7DF1C5DA
call _DbgPrintEx
.text:
7DF1C5F1
call ds:_RtlAllocateStringRoutine; RtlpAllocateEnvBlock(x)
.text:
7DF1C616
call _memcpy
.text:
7DF1C63F
call _NtClose@
4
; NtClose(x)
.text:
7DF1C64E
call @__security_check_cookie@
4
; __security_check_cookie(x)
.text:
7DF1C529
call _ZwOpenKey@
12
; ZwOpenKey(x,x,x)
.text:
7DF1C563
call _ZwQueryValueKey@
24
; ZwQueryValueKey(x,x,x,x,x,x)
.text:
7DF1C57E
call _DbgPrintEx
.text:
7DF1C5AD
call _DbgPrintEx
.text:
7DF1C5DA
call _DbgPrintEx
.text:
7DF1C5F1
call ds:_RtlAllocateStringRoutine; RtlpAllocateEnvBlock(x)
.text:
7DF1C616
call _memcpy
.text:
7DF1C63F
call _NtClose@
4
; NtClose(x)
.text:
7DF1C64E
call @__security_check_cookie@
4
; __security_check_cookie(x)
'SXS: Unable to open storage root subkey %wZ; Status = 0x%08lx'
,
0Ah
'SXS: Unabel to query location from storage root subkey %wZ; Statu'
/
/
微软工程师把Unable写成了Unabel
'SXS: Assembly storage root location value type is not REG_SZ'
,
0Ah
'SXS: Assembly storage root location for %wZ does not fit in a UNICODE STRING'
'SXS: Assembly storage root location value has non-even size'
,
0Ah
,
0
'SXS: Unable to open storage root subkey %wZ; Status = 0x%08lx'
,
0Ah
'SXS: Unabel to query location from storage root subkey %wZ; Statu'
/
/
微软工程师把Unable写成了Unabel
'SXS: Assembly storage root location value type is not REG_SZ'
,
0Ah
'SXS: Assembly storage root location for %wZ does not fit in a UNICODE STRING'
'SXS: Assembly storage root location value has non-even size'
,
0Ah
,
0
.text:
7DF1C4AF
mov eax, [ebp
+
arg_0]
.text:
7DF1C4E7
mov [ebp
+
ObjectAttributes.RootDirectory], eax
.text:
7DF1C4AF
mov eax, [ebp
+
arg_0]
.text:
7DF1C4E7
mov [ebp
+
ObjectAttributes.RootDirectory], eax
.text:
7DF1C4B2
mov ecx, [ebp
+
arg_4]
.text:
7DF1C4BD
mov [ebp
+
var_224], ecx
.text:
7DF1C4ED
lea eax, [ebp
+
var_224]
.text:
7DF1C4F3
mov [ebp
+
ObjectAttributes.ObjectName], eax
.text:
7DF1C4B2
mov ecx, [ebp
+
arg_4]
.text:
7DF1C4BD
mov [ebp
+
var_224], ecx
.text:
7DF1C4ED
lea eax, [ebp
+
var_224]
.text:
7DF1C4F3
mov [ebp
+
ObjectAttributes.ObjectName], eax
.text:
7DF1C4B9
mov esi, [ebp
+
arg_8]
.text:
7DF1C5BC
movzx ecx, word ptr [esi
+
2
]
.text:
7DF1C5E9
mov [esi
+
2
], ax
.text:
7DF1C5F7
mov [esi
+
4
], eax
.text:
7DF1C4B9
mov esi, [ebp
+
arg_8]
.text:
7DF1C5BC
movzx ecx, word ptr [esi
+
2
]
.text:
7DF1C5E9
mov [esi
+
2
], ax
.text:
7DF1C5F7
mov [esi
+
4
], eax
HANDLE arg_0,
/
/
根对象目录句柄
PUNICODE_STRING arg_4,
/
/
对象名称
ptr_32 arg_8;
/
/
未知指针
HANDLE arg_0,
/
/
根对象目录句柄
PUNICODE_STRING arg_4,
/
/
对象名称
ptr_32 arg_8;
/
/
未知指针
.text:
7DF1C49A
; __stdcall RtlpGetAssemblyStorageMapRootLocation(x, x, x)
.text:
7DF1C49A
_RtlpGetAssemblyStorageMapRootLocation@
12
proc near
.text:
7DF1C49A
; CODE XREF: RtlpAssemblyStorageMapResolutionDefaultCallback(x,x,x)
+
2D255
↑p
.text:
7DF1C49A
.text:
7DF1C49A
ObjectAttributes
=
_OBJECT_ATTRIBUTES ptr
-
240h
.text:
7DF1C49A
ResultLength
=
dword ptr
-
228h
.text:
7DF1C49A
var_224
=
dword ptr
-
224h
.text:
7DF1C49A
KeyHandle
=
dword ptr
-
220h
.text:
7DF1C49A
KeyValueInformation
=
byte ptr
-
21Ch
.text:
7DF1C49A
var_218
=
dword ptr
-
218h
.text:
7DF1C49A
Size
=
dword ptr
-
214h
.text:
7DF1C49A
Src
=
byte ptr
-
210h
.text:
7DF1C49A
var_4
=
dword ptr
-
4
.text:
7DF1C49A
arg_0
=
dword ptr
8
.text:
7DF1C49A
arg_4
=
dword ptr
0Ch
.text:
7DF1C49A
arg_8
=
dword ptr
10h
.text:
7DF1C49A
.text:
7DF1C49A
mov edi, edi
.text:
7DF1C49C
push ebp
.text:
7DF1C49D
mov ebp, esp
.text:
7DF1C49F
sub esp,
240h
.text:
7DF1C4A5
mov eax, ___security_cookie
.text:
7DF1C4AA
xor eax, ebp
.text:
7DF1C4AC
mov [ebp
+
security_cookie], eax ;var_4
.text:
7DF1C4AF
mov eax, [ebp
+
arg_0] ; eax
=
arg_0 , HANDLE
.text:
7DF1C4B2
mov ecx, [ebp
+
arg_4] ; ecx
=
arg_4 ,对象名称
.text:
7DF1C4B5
push ebx
.text:
7DF1C4B6
xor ebx, ebx ; ebx
=
0
.text:
7DF1C4B8
push esi
.text:
7DF1C4B9
mov esi, [ebp
+
arg_8] ; esi
=
arg_8 ,指针
.text:
7DF1C4BC
push edi
.text:
7DF1C4BD
mov [ebp
+
var_224], ecx
.text:
7DF1C4C3
mov [ebp
+
KeyHandle], ebx
.text:
7DF1C4C9
mov [ebp
+
ResultLength], ebx
.text:
7DF1C4CF
cmp
eax, ebx
.text:
7DF1C4D1
jz loc_7DF1C62C
.text:
7DF1C4D7
cmp
ecx, ebx
.text:
7DF1C4D9
jz loc_7DF1C62C
.text:
7DF1C4DF
cmp
esi, ebx
.text:
7DF1C4E1
jz loc_7DF1C62C
.text:
7DF1C49A
; __stdcall RtlpGetAssemblyStorageMapRootLocation(x, x, x)
.text:
7DF1C49A
_RtlpGetAssemblyStorageMapRootLocation@
12
proc near
.text:
7DF1C49A
; CODE XREF: RtlpAssemblyStorageMapResolutionDefaultCallback(x,x,x)
+
2D255
↑p
.text:
7DF1C49A
.text:
7DF1C49A
ObjectAttributes
=
_OBJECT_ATTRIBUTES ptr
-
240h
.text:
7DF1C49A
ResultLength
=
dword ptr
-
228h
.text:
7DF1C49A
var_224
=
dword ptr
-
224h
.text:
7DF1C49A
KeyHandle
=
dword ptr
-
220h
.text:
7DF1C49A
KeyValueInformation
=
byte ptr
-
21Ch
.text:
7DF1C49A
var_218
=
dword ptr
-
218h
.text:
7DF1C49A
Size
=
dword ptr
-
214h
.text:
7DF1C49A
Src
=
byte ptr
-
210h
.text:
7DF1C49A
var_4
=
dword ptr
-
4
.text:
7DF1C49A
arg_0
=
dword ptr
8
.text:
7DF1C49A
arg_4
=
dword ptr
0Ch
.text:
7DF1C49A
arg_8
=
dword ptr
10h
.text:
7DF1C49A
.text:
7DF1C49A
mov edi, edi
.text:
7DF1C49C
push ebp
.text:
7DF1C49D
mov ebp, esp
.text:
7DF1C49F
sub esp,
240h
.text:
7DF1C4A5
mov eax, ___security_cookie
.text:
7DF1C4AA
xor eax, ebp
.text:
7DF1C4AC
mov [ebp
+
security_cookie], eax ;var_4
.text:
7DF1C4AF
mov eax, [ebp
+
arg_0] ; eax
=
arg_0 , HANDLE
.text:
7DF1C4B2
mov ecx, [ebp
+
arg_4] ; ecx
=
arg_4 ,对象名称
.text:
7DF1C4B5
push ebx
.text:
7DF1C4B6
xor ebx, ebx ; ebx
=
0
.text:
7DF1C4B8
push esi
.text:
7DF1C4B9
mov esi, [ebp
+
arg_8] ; esi
=
arg_8 ,指针
.text:
7DF1C4BC
push edi
.text:
7DF1C4BD
mov [ebp
+
var_224], ecx
.text:
7DF1C4C3
mov [ebp
+
KeyHandle], ebx
.text:
7DF1C4C9
mov [ebp
+
ResultLength], ebx
.text:
7DF1C4CF
cmp
eax, ebx
.text:
7DF1C4D1
jz loc_7DF1C62C
.text:
7DF1C4D7
cmp
ecx, ebx
.text:
7DF1C4D9
jz loc_7DF1C62C
.text:
7DF1C4DF
cmp
esi, ebx
.text:
7DF1C4E1
jz loc_7DF1C62C
extern dword security_cookie
=
0BB40E64Eh
;
/
/
var_4,在外部定义的未知类型变量,大小为dword
/
/
返回值是某种错误代码类型,大小为dword
dword RtlpGetAssemblyStorageMapRootLocation(HANDLE arg_0, PUNICODE_STRING arg_4, ptr_32 arg_8)
{
PUNICODE_STRING temp_arg_4
=
arg_4;
HANDLE KeyHandle
=
0
;
PULONG ResultLength
=
0
;
if
(arg_0
=
=
0
|| arg_4
=
=
0
|| arg_8
=
=
0
) {
/
/
任意参数为空则函数退出,并跳转到loc_7DF1C62C
if
(KeyHandle !
=
0
)
NtClose(KeyHandle);
__security_check_cookie(security_cookie);
return
0C000000Dh
;
}
}
extern dword security_cookie
=
0BB40E64Eh
;
/
/
var_4,在外部定义的未知类型变量,大小为dword
/
/
返回值是某种错误代码类型,大小为dword
dword RtlpGetAssemblyStorageMapRootLocation(HANDLE arg_0, PUNICODE_STRING arg_4, ptr_32 arg_8)
{
PUNICODE_STRING temp_arg_4
=
arg_4;
HANDLE KeyHandle
=
0
;
PULONG ResultLength
=
0
;
if
(arg_0
=
=
0
|| arg_4
=
=
0
|| arg_8
=
=
0
) {
/
/
任意参数为空则函数退出,并跳转到loc_7DF1C62C
if
(KeyHandle !
=
0
)
NtClose(KeyHandle);
__security_check_cookie(security_cookie);
return
0C000000Dh
;
}
}
.text:
7DF1C4E7
mov [ebp
+
ObjectAttributes.RootDirectory], eax
.text:
7DF1C4ED
lea eax, [ebp
+
var_224]
.text:
7DF1C4F3
mov [ebp
+
ObjectAttributes.ObjectName], eax
.text:
7DF1C4F9
lea eax, [ebp
+
ObjectAttributes]
.text:
7DF1C4FF
push eax ; ObjectAttributes
.text:
7DF1C500
push
1
; DesiredAccess
.text:
7DF1C502
lea eax, [ebp
+
KeyHandle]
.text:
7DF1C508
push eax ; KeyHandle
.text:
7DF1C509
mov [ebp
+
ObjectAttributes.Length],
18h
.text:
7DF1C513
mov [ebp
+
ObjectAttributes.Attributes],
40h
;
'@'
.text:
7DF1C51D
mov [ebp
+
ObjectAttributes.SecurityDescriptor], ebx
.text:
7DF1C523
mov [ebp
+
ObjectAttributes.SecurityQualityOfService], ebx
.text:
7DF1C529
call _ZwOpenKey@
12
; ZwOpenKey(x,x,x)
.text:
7DF1C52E
mov edi, eax
.text:
7DF1C530
cmp
edi, ebx
.text:
7DF1C532
jge short loc_7DF1C543
.text:
7DF1C4E7
mov [ebp
+
ObjectAttributes.RootDirectory], eax
.text:
7DF1C4ED
lea eax, [ebp
+
var_224]
.text:
7DF1C4F3
mov [ebp
+
ObjectAttributes.ObjectName], eax
.text:
7DF1C4F9
lea eax, [ebp
+
ObjectAttributes]
.text:
7DF1C4FF
push eax ; ObjectAttributes
.text:
7DF1C500
push
1
; DesiredAccess
.text:
7DF1C502
lea eax, [ebp
+
KeyHandle]
.text:
7DF1C508
push eax ; KeyHandle
.text:
7DF1C509
mov [ebp
+
ObjectAttributes.Length],
18h
.text:
7DF1C513
mov [ebp
+
ObjectAttributes.Attributes],
40h
;
'@'
.text:
7DF1C51D
mov [ebp
+
ObjectAttributes.SecurityDescriptor], ebx
.text:
7DF1C523
mov [ebp
+
ObjectAttributes.SecurityQualityOfService], ebx
.text:
7DF1C529
call _ZwOpenKey@
12
; ZwOpenKey(x,x,x)
.text:
7DF1C52E
mov edi, eax
.text:
7DF1C530
cmp
edi, ebx
.text:
7DF1C532
jge short loc_7DF1C543
OBJECT_ATTRIBUTES ObjectAttributes;
ObjectAttributes.RootDirectory
=
arg_0;
/
/
根对象目录句柄
ObjectAttributes.ObjectName
=
&temp_arg_4;
/
/
对象名称,arg_4
ObjectAttributes.Length
=
0x18
;
ObjectAttributes.Attributes
=
0x40
;
/
/
使用不区分大小写的方式比较对象名称
ObjectAttributes.SecurityDescriptor
=
0
;
ObjectAttributes.SecurityQualityOfService
=
0
;
if
(ZwOpenKey(&KeyHandle,
1
, ObjectAttributes) >
=
0
) {
/
/
打开注册表项
/
/
跳转到loc_7DF1C543
}
OBJECT_ATTRIBUTES ObjectAttributes;
ObjectAttributes.RootDirectory
=
arg_0;
/
/
根对象目录句柄
ObjectAttributes.ObjectName
=
&temp_arg_4;
/
/
对象名称,arg_4
ObjectAttributes.Length
=
0x18
;
ObjectAttributes.Attributes
=
0x40
;
/
/
使用不区分大小写的方式比较对象名称
ObjectAttributes.SecurityDescriptor
=
0
;
ObjectAttributes.SecurityQualityOfService
=
0
;
if
(ZwOpenKey(&KeyHandle,
1
, ObjectAttributes) >
=
0
) {
/
/
打开注册表项
/
/
跳转到loc_7DF1C543
}
.text:
7DF1C543
loc_7DF1C543:
.text:
7DF1C543
lea eax, [ebp
+
ResultLength]
.text:
7DF1C549
push eax ; ResultLength
.text:
7DF1C54A
push
218h
; Length
.text:
7DF1C54F
lea eax, [ebp
+
KeyValueInformation]
.text:
7DF1C555
push eax ; KeyValueInformation
.text:
7DF1C556
push
2
; KeyValueInformationClass
.text:
7DF1C558
push offset stru_7DF1C658 ; ValueName
.text:
7DF1C55D
push [ebp
+
KeyHandle] ; KeyHandle
.text:
7DF1C563
call _ZwQueryValueKey@
24
; ZwQueryValueKey(x,x,x,x,x,x)
.text:
7DF1C568
mov edi, eax
.text:
7DF1C56A
cmp
edi, ebx
.text:
7DF1C56C
jge short loc_7DF1C58B
.text:
7DF1C543
loc_7DF1C543:
.text:
7DF1C543
lea eax, [ebp
+
ResultLength]
.text:
7DF1C549
push eax ; ResultLength
.text:
7DF1C54A
push
218h
; Length
.text:
7DF1C54F
lea eax, [ebp
+
KeyValueInformation]
.text:
7DF1C555
push eax ; KeyValueInformation
.text:
7DF1C556
push
2
; KeyValueInformationClass
.text:
7DF1C558
push offset stru_7DF1C658 ; ValueName
.text:
7DF1C55D
push [ebp
+
KeyHandle] ; KeyHandle
.text:
7DF1C563
call _ZwQueryValueKey@
24
; ZwQueryValueKey(x,x,x,x,x,x)
.text:
7DF1C568
mov edi, eax
.text:
7DF1C56A
cmp
edi, ebx
.text:
7DF1C56C
jge short loc_7DF1C58B
NTSYSAPI NTSTATUS ZwQueryValueKey(
[
in
] HANDLE KeyHandle,
/
/
键句柄
[
in
] PUNICODE_STRING ValueName,
/
/
键值名称
[
in
] KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
/
/
确定 KeyValueInformation 缓冲区中返回的信息的类型
[out, optional] PVOID KeyValueInformation,
/
/
接收请求信息的指针
[
in
] ULONG Length,
/
/
指定 KeyValueInformation 缓冲区的大小(以字节为单位)
[out] PULONG ResultLength
);
NTSYSAPI NTSTATUS ZwQueryValueKey(
[
in
] HANDLE KeyHandle,
/
/
键句柄
[
in
] PUNICODE_STRING ValueName,
/
/
键值名称
[
in
] KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
/
/
确定 KeyValueInformation 缓冲区中返回的信息的类型
[out, optional] PVOID KeyValueInformation,
/
/
接收请求信息的指针
[
in
] ULONG Length,
/
/
指定 KeyValueInformation 缓冲区的大小(以字节为单位)
[out] PULONG ResultLength
);
extern LSA_UNICODE_STRING stru_7DF1C658
=
{
0x10
,
0x12
, L
"Location"
};
PUNICODE_STRING temp_arg_4
=
arg_4;
/
/
保存对象名称
HANDLE KeyHandle
=
0
;
ULONG ResultLength
=
0
;
PVOID KeyValueInformation;
/
/
返回注册表键Location的值
/
/
KeyValueInformation返回一个KEY_VALUE_PARTIAL_INFORMATION结构的指针,就是location信息
if
(ZwQueryValueKey(KeyHandle, stru_7DF1C658,
2
, &KeyValueInformation,
0x218
, &ResultLength) >
=
0
) {
/
/
跳转到loc_7DF1C58B
}
extern LSA_UNICODE_STRING stru_7DF1C658
=
{
0x10
,
0x12
, L
"Location"
};
PUNICODE_STRING temp_arg_4
=
arg_4;
/
/
保存对象名称
HANDLE KeyHandle
=
0
;
ULONG ResultLength
=
0
;
PVOID KeyValueInformation;
/
/
返回注册表键Location的值
/
/
KeyValueInformation返回一个KEY_VALUE_PARTIAL_INFORMATION结构的指针,就是location信息
if
(ZwQueryValueKey(KeyHandle, stru_7DF1C658,
2
, &KeyValueInformation,
0x218
, &ResultLength) >
=
0
) {
/
/
跳转到loc_7DF1C58B
}
.text:
7DF1C534
push edi
.text:
7DF1C535
lea eax, [ebp
+
var_224]
.text:
7DF1C53B
push eax
.text:
7DF1C53C
push offset aSxsUnableToOpe ;
"SXS: Unable to open storage root subkey"
...
.text:
7DF1C541
jmp short loc_7DF1C57B
.text:
7DF1C534
push edi
.text:
7DF1C535
lea eax, [ebp
+
var_224]
.text:
7DF1C53B
push eax
.text:
7DF1C53C
push offset aSxsUnableToOpe ;
"SXS: Unable to open storage root subkey"
...
.text:
7DF1C541
jmp short loc_7DF1C57B
.text:
7DF1C56E
push edi
.text:
7DF1C56F
lea eax, [ebp
+
var_224]
.text:
7DF1C575
push eax
.text:
7DF1C576
push offset aSxsUnabelToQue ;
"SXS: Unabel to query location from stor"
...
.text:
7DF1C56E
push edi
.text:
7DF1C56F
lea eax, [ebp
+
var_224]
.text:
7DF1C575
push eax
.text:
7DF1C576
push offset aSxsUnabelToQue ;
"SXS: Unabel to query location from stor"
...
.text:
7DF1C57B
loc_7DF1C57B: ; CODE XREF: RtlpGetAssemblyStorageMapRootLocation(x,x,x)
+
A7↑j
.text:
7DF1C57B
push ebx ; Level
.text:
7DF1C57C
push
33h
;
'3'
; ComponentId
.text:
7DF1C57E
call _DbgPrintEx
.text:
7DF1C583
add esp,
14h
.text:
7DF1C586
jmp loc_7DF1C631
.text:
7DF1C57B
loc_7DF1C57B: ; CODE XREF: RtlpGetAssemblyStorageMapRootLocation(x,x,x)
+
A7↑j
.text:
7DF1C57B
push ebx ; Level
.text:
7DF1C57C
push
33h
;
'3'
; ComponentId
.text:
7DF1C57E
call _DbgPrintEx
.text:
7DF1C583
add esp,
14h
.text:
7DF1C586
jmp loc_7DF1C631
extern dword security_cookie
=
0xBB40E64E
;
/
/
var_4,值来自在外部定义的未知类型变量___security_cookie
extern LSA_UNICODE_STRING stru_7DF1C658
=
{
0x10
,
0x12
, L
"Location"
};
extern const char aSxsUnableToOpe[]
=
"SXS: Unable to open storage root subkey %wZ; Status = 0x%08lx\n"
;
extern const char aSxsUnabelToQue[]
=
"SXS: Unabel to query location from storage root subkey %wZ; Statu"
;
/
/
返回值是某种错误代码类型,大小为dword
dword RtlpGetAssemblyStorageMapRootLocation(HANDLE arg_0,
/
/
根对象目录句柄
PUNICODE_STRING arg_4,
/
/
对象名称
ptr_32 arg_8)
/
/
未知指针
{
dword return_code
=
0
;
/
/
函数返回代码
PUNICODE_STRING temp_arg_4
=
arg_4;
/
/
对象名称
HANDLE KeyHandle
=
0
;
ULONG ResultLength
=
0
;
PVOID KeyValueInformation
=
NULL;
/
/
指向注册表键值信息
OBJECT_ATTRIBUTES ObjectAttributes;
ObjectAttributes.RootDirectory
=
arg_0;
/
/
根对象目录句柄
ObjectAttributes.ObjectName
=
&temp_arg_4;
/
/
对象名称,arg_4
ObjectAttributes.Length
=
0x18
;
ObjectAttributes.Attributes
=
0x40
;
/
/
使用不区分大小写的方式比较对象名称
ObjectAttributes.SecurityDescriptor
=
0
;
ObjectAttributes.SecurityQualityOfService
=
0
;
if
(arg_0 !
=
0
&& arg_4 !
=
0
&& arg_8 !
=
0
) {
/
/
参数检查
return_code
=
ZwOpenKey(&KeyHandle,
1
, ObjectAttributes);
/
/
打开注册表项
if
(return_code <
0
)
DbgPrintEx(
0x33
,
0
, aSxsUnableToOpe, &temp_arg_4, return_code);
/
/
打开注册表项失败,打印错误消息
else
{
/
/
成功打开,获取注册表键Location的值
return_code
=
ZwQueryValueKey(KeyHandle, stru_7DF1C658,
2
, &KeyValueInformation,
0x218
, &ResultLength);
if
(return_code <
0
)
DbgPrintEx(
0x33
,
0
, aSxsUnabelToQue, &temp_arg_4, return_code);
/
/
查询键值失败,打印错误消息
else
{
/
/
跳转到loc_7DF1C58B
}
}
}
else
return_code
=
0xC000000D
;
if
(KeyHandle !
=
0
)
/
/
程序退出,loc_7DF1C631
NtClose(KeyHandle);
__security_check_cookie(security_cookie);
return
return_code;
}
extern dword security_cookie
=
0xBB40E64E
;
/
/
var_4,值来自在外部定义的未知类型变量___security_cookie
extern LSA_UNICODE_STRING stru_7DF1C658
=
{
0x10
,
0x12
, L
"Location"
};
extern const char aSxsUnableToOpe[]
=
"SXS: Unable to open storage root subkey %wZ; Status = 0x%08lx\n"
;
extern const char aSxsUnabelToQue[]
=
"SXS: Unabel to query location from storage root subkey %wZ; Statu"
;
/
/
返回值是某种错误代码类型,大小为dword
dword RtlpGetAssemblyStorageMapRootLocation(HANDLE arg_0,
/
/
根对象目录句柄
PUNICODE_STRING arg_4,
/
/
对象名称
ptr_32 arg_8)
/
/
未知指针
{
dword return_code
=
0
;
/
/
函数返回代码
PUNICODE_STRING temp_arg_4
=
arg_4;
/
/
对象名称
HANDLE KeyHandle
=
0
;
ULONG ResultLength
=
0
;
PVOID KeyValueInformation
=
NULL;
/
/
指向注册表键值信息
OBJECT_ATTRIBUTES ObjectAttributes;
ObjectAttributes.RootDirectory
=
arg_0;
/
/
根对象目录句柄
ObjectAttributes.ObjectName
=
&temp_arg_4;
/
/
对象名称,arg_4
ObjectAttributes.Length
=
0x18
;
ObjectAttributes.Attributes
=
0x40
;
/
/
使用不区分大小写的方式比较对象名称
ObjectAttributes.SecurityDescriptor
=
0
;
ObjectAttributes.SecurityQualityOfService
=
0
;
if
(arg_0 !
=
0
&& arg_4 !
=
0
&& arg_8 !
=
0
) {
/
/
参数检查
return_code
=
ZwOpenKey(&KeyHandle,
1
, ObjectAttributes);
/
/
打开注册表项
if
(return_code <
0
)
DbgPrintEx(
0x33
,
0
, aSxsUnableToOpe, &temp_arg_4, return_code);
/
/
打开注册表项失败,打印错误消息
else
{
/
/
成功打开,获取注册表键Location的值
return_code
=
ZwQueryValueKey(KeyHandle, stru_7DF1C658,
2
, &KeyValueInformation,
0x218
, &ResultLength);
if
(return_code <
0
)
DbgPrintEx(
0x33
,
0
, aSxsUnabelToQue, &temp_arg_4, return_code);
/
/
查询键值失败,打印错误消息
else
{
/
/
跳转到loc_7DF1C58B
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-6-7 18:59
被mb_yx编辑
,原因: 修正参数检查的逻辑错误