最近需要在内核中获取远程名称管道的源地址
所以首先逆向了r3的GetNamedPipeClientComputerNameW,该函数在kernelbase.dll中实现,为了更好的分析函数需要下载符号,使用下面的命令
symchk /r D:\rpc\kernelbasex32 /s SRV*D:\rpc\kernelbasex32\*http://msdl.microsoft.com/download/symbols
有了符号分析起来的简单了,最后将该函数所做的事情写成c代码如下:
ULONG AltGetNamedPipeClientComputerName(HANDLE Pipe, PWSTR ClientComputerName, ULONG ClientComputerNameLength)
{
static const char AttributeName[] = "ClientComputerName";
if (HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL))
{
IO_STATUS_BLOCK iosb = {0};
NTSTATUS status = NtFsControlFile(Pipe,
NULL,
NULL,
NULL,
&iosb,
FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE,
(void*)AttributeName,
strlen(AttributeName)+1,
ClientComputerName,
ClientComputerNameLength*sizeof(WCHAR));
if (NT_SUCCESS(status ))
{
//xxx
}
}
}
这里有三个传入参数,第一个是名称管道的句柄,第二个是传出的参数,第三个是大小,第一个比较好找,那么第二个和第三个怎么确定?由于通常名称管道是在rpc中使用所以在rpcrt4.dll中找到NMP_ConnectionQueryClientAddress分析以下可知大小取的就是MAX_PATH
最后就是在内核中使用NtFsControlFile发送IOCTL就能获取到IP。
但是如果使用NtFsControlFile返回的错误码是0xc0000005,之后查了一下msdn发现NtFsControlFile说的是在用户层需要使用Nt的,在内核中使用ZW的https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntfscontrolfile
最后修改代码为ZwFsControlFile成功获取到源地址IP