首页
社区
课程
招聘
[原创]win10 1909逆向(ALPC通信原理浅析)
发表于: 2021-6-25 14:48 23971

[原创]win10 1909逆向(ALPC通信原理浅析)

2021-6-25 14:48
23971


       参考书籍《深入解析 Windows 操作系统》第六版,网上资料少且部分错误,另外很多内核书籍是以 WRK的LPC 原型来讲解,但 Vista 后LPC代码被移除,仅保留 LPC 的接 口,参考意义不大。


       逆向ALPC通信原理仅作为我入职公司的压力测试,所以逆向时间有限,由于 ALPC 设计较复杂,目前仅以 ALPC 简单的通信为基础逆向得到下面的观点,如果有错误,那我也没有法子,哇哈哈。

      Windows 需要一种机制来安全的在一个或多个进程之间传输数据,或者允许内核中的服务 和用户模式下的客户之间传输数据,从而实现了一种称为高级本地过程调用(advanced local procedure callALPC 的内部 IPC 机制,这是一种高速的、可伸缩的、安全的消息传递 设施,可用于传递任意大小的消息。

         ALPC 是一种内部机制,所以第三方开发人员无法使用,但应用于 windows 的各个部分,例 如本地模式 RPC 和内核模式 RPC 都是调用的 ALPC。 

         ALPC_PORT 端口可以代表四种意思(索引有相应的意义):

    端口主要分两类:连接端口和通信端口。 

          0。未连接通信端口:这是一个未命名的端口,自己和自己通信。

         1。服务器连接端口:这是一个命名的端口,也是服务器的连接请求点。客户通过此端口连接到服务器。

         2。客户端通信端口:这是一个未命名的端口,客户线程利用这个端口与一个特定的服务器进行通信。

         3。服务器通信端口:这是一个未命名的端口,服务器利用此端口与一个特定的客户进行通信,针对每个活动的客户,服务器都有一个这样的端口。 

    初始化 PortObject AlpcpInitializePort(PortObject, Type, 0)这里进行了设置,里面这里的 INDEX 会是对应的 TYPE,内部会根据这个进行大量的判断


数据传输内部实现: 

1.0~512 字节以内:直接放入 Port_Message 结构体的末尾。 

2.512 字节~64K 以内: 512 字节以内,直接放在 Port_Message 结构体的末尾, 512 字节 ~64K 字节,申请一块 Datalen-0x200 的空间放入 Message->ExtensionBuffer 里。 

3.64K 以上:返回 Port_Message->Reserve。【未触发,暂未逆】 

消息队列:(红色部分是根据自己逆向推测

MainQueue:主队列,消息已经被发送,客户正在出来该消息。

PendingQueue:待处理消息,消息已经被发送,调用者正在等待应答,但是应答尚未被发 出,会从 WaitQueue 里的线程池里选择一条线程来执行。

LargeMessageQueue:大消息队列,消息已经被发送,但是调用者的缓冲区太小因而不能接 受该消息。调用者获得另一次机会来申请一个更大的缓冲区,并再次请求该消息的负荷数据。

CanceledQueue:已取消的队列,原本发送给该端口对象的消息,但是此后已被取消。 

WaitQueue:等待队列,它并没有把消息链接起来,相反,它把所有正在等待某个消息的线 程链接起来。 

DirectQueue:直接队列。由某个具体工作线程的处理的。


目前 ALPC 所使用的 BLOB 类型 + 资源类型: 

连接 BLOBAlpcConnectionType _ALPC_COMMUNICATION_INFO

区域 BLOBAlpcRegionType _KALPC_REGION 

视图 BLOBAlpcViewType _KALPC_VIEW

安全 BLOBAlpcSecurityType _KALPC_SECURITY_DATA 

内存 BLOBAlpcSectionType _KALPC_SECTION 消息 

BLOBAlpcMessageType _KALPC_MESSAGE 

保留 BLOBAlpcReserveType _KALPC_RESERVE 

句柄 BLOBAlpcHandleDataType _KALPC_HANDLE_DATA


通过全局变量 AlpcpRegisteredTypes,可以知道总共注册了多少个 ALPC 类型

AlpcConnectionType 这些属于 BLOB_TYPE 类型:

例如: 

CommResources=AlpcpAllocateBlob(&AlpcConnectionType, 0x48, 1) 

根据 BlobType 用不同的方 法创建 BLOB0x48 就是_ALPC_COMMUNICATION_INFO 的长度。 

最后形成的结构体类似句柄+资源: 

typedef struct _COMMBLOB

     _BLOB blob; _

    ALPC_COMMUNICATION_INFO alpcCommInfo; 

}COMMBLOB,*PCOMMBLOB


BLOB 结构体:

ResourceId =BLOB_ID

--------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------

例如:这里是创建了连接 

BLOB NewAlpcCommunicationInfo=AlpcpAllocateBlob(&AlpcConnectionType, 0x48, 1) 

AlpcConnectionType=BLOB_TYPE NewAlpcCommunicationInfo=_ALPC_COMMUNICATION_INFO

windows 在启动阶段调用 LpcInitSystem()来初始化 ALPC 里面主要实现三个功能:

 

1windows vista 后移除了所有的 LPC,但为了兼容性的问题,LPC 包装了 ALPC 的调用。


2. 通过 AlpcpInitSystem,创建_ALPC_PORT 的对象类型并加入到 ObTypeIndexTable 表中。

3.通过 AlpcpInitSystem,创建Alpc 全局消息句柄表。Windows 会根据消息数量动态的创建 AlpcpSecondaryMessageTables 数组,数组里面都是 HANDLE_TABLE 

【在插入消息时,句柄 ID>=0x4000000 时就会进入 AlpcpSecondaryMessageTables 数组 Windows 句柄表是三层结构:512*512*256=0x4000000,这就是由来。 

而私有句柄表和全局句柄表是 OBJECT+权限,所以是 512*512*256,而消息句柄表没有权 限,但也沿用了前者的模式】


原型: 

NTSYSCALLAPI NTSTATUS NTAPI NtAlpcCreatePort( 

_Out_ PHANDLE PortHandle, 

_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 

_In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes

);

NtAlpcCreatePort-->AlpcpCreateConnectionPort 

1.AlpcpCreateConnectionPort->AlpcpCreatePort 来创建一个命名的服务端连接端口,让客户端可以通过这个连接。 

    AlpcpCreatePort(ObjectAttributes, PreviousMode, &ServerConnectObject)

2.AlpcpCreateConnectionPort->AlpcpInitializePort 来初始化Object 结构体。 

AlpcpInitializePort(pServerConnectObject, 2, SynchronizationType) 

初始化各个链表: 

MainQueue:主队列,消息已经被发送,客户正在处理该消息。 

PendingQueue:待处理消息,消息已经被发送,调用者正在等待应答,但是应答尚未被发 出。

LargeMessageQueue:大消息队列,消息已经被发送,但是调用者的缓冲区太小因而不能接 受该消息。调用者获得另一次机会来申请一个更大的缓冲区,并再次请求该消息的负荷数 据。

CanceledQueue:已取消的队列,原本发送给该端口对象的消息,但是此后已被取消。 

WaitQueue:等待队列,它并没有把消息链接起来,相反,它把所有正在等待某个消息的线程链接起来。 

DirectQueue:直接队列。 

初始化事件或者信号量:

将当前的ALPC_PORT 加入全局的AlpcpPortList 链表 

3.创建连接 BLOB 和连接消息

ServerAlpcConnectCommInfo = AlpcpAllocateBlob(&AlpcConnectionType, 0x48, 1) 注 意 : ConnectionType 内部是调用 ExallocatePoolWithTag 来申请内存 

pServerConnectObject->CommunicationInfo = ServerAlpcConnectCommInfo 

pServerConnectObject->CommunicationInfo->ConnectionPort = pServerConnectObject;

pServerConnectObject->CommunicationInfo->ServerCommunicationPort = 0; 

pServerConnectObject->CommunicationInfo->CloseMessage = 0; 

ServerAlpcConnectCommInfo->ClientCommunicationPort = 0;

InitializeListHead(&ServerAlpcCommInfo->CommunicationList) 

AlpcInitializeHandleTable(&ServerAlpcConnectCommInfo->HandleTable); //初始化句柄表

ObInsertObjectEx(pServerConnectObject, 0, 0x1F0001u, 0, 0, 0, &Handle); //将当前 object 对象插入到Server 端的私有句柄表里。



[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 15
支持
分享
最新回复 (12)
雪    币: 1420
活跃值: (2151)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
豆总  yyds
2021-6-25 14:50
0
雪    币: 1290
活跃值: (2332)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
牛皮!
2021-6-25 14:53
0
雪    币: 889
活跃值: (4118)
能力值: ( LV6,RANK:98 )
在线值:
发帖
回帖
粉丝
4
牛皮!
2021-6-25 15:02
0
雪    币: 12848
活跃值: (9142)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
5
好耶
2021-6-25 15:22
0
雪    币: 198
活跃值: (8548)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
6
hzqst 好耶
2021-6-25 16:54
0
雪    币: 1290
活跃值: (2332)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
7
hzqst 好耶
我看到什么
2021-6-29 00:29
0
雪    币: 201
活跃值: (689)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
yyds
2021-7-20 14:12
0
雪    币: 189
活跃值: (154)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢!
2021-9-17 15:18
0
雪    币: 775
活跃值: (2338)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
牛批
2021-9-17 16:08
0
雪    币: 1821
活跃值: (1913)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
感谢分享
2022-2-15 11:28
0
雪    币: 12016
活跃值: (10399)
能力值: ( LV13,RANK:660 )
在线值:
发帖
回帖
粉丝
12
我有一个初级的问题,文章里面IDA截图 分析的文件是什么啊?
2022-6-15 11:30
2
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
感谢   分享
2024-4-15 20:35
0
游客
登录 | 注册 方可回帖
返回
//