例子代码:
_Function_class_(DRIVER_UNLOAD)
_IRQL_requires_(PASSIVE_LEVEL)
_IRQL_requires_same_
VOID Unload(_In_ struct _DRIVER_OBJECT * DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
PAGED_CODE();
}
NTSTATUS TestGetHttps()
/*
在 HTTP/1.1 中 Host 是必须的,否则服务器通常会返回 400 Bad Request。
添加 Connection: close 以便在接收完数据后服务器主动断开连接,避免 Recv 超时阻塞。
针对 0xC000042A (STATUS_REQUEST_OUT_OF_SEQUENCE) 错误,这通常表示 TLS 协议状态机在处理接收数据时遇到了意外的报文序列。
在 HTTPS 通信中,这最常见的原因是接收缓冲区过小,无法容纳完整的 TLS 记录(TLS Record)。
TLS 记录最大可达 16KB 加上少量头部开销。如果缓冲区不足以存放一个完整的记录,底层解密函数(如 DecryptMessage)可能会返回SEC_E_INCOMPLETE_MESSAGE,
而驱动层并未正确处理分片读取,导致状态错误或直接返回序列错误。
*/
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
KPH_TLS_HANDLE Tls = nullptr;
PADDRINFOEXW AddressInfo{};
KPH_SOCKET_HANDLE Socket{};
PCHAR Buffer{};
const ULONG BufferSize = 0x5000; // 20KB
Status = KphInitializeSocket();
if (!NT_SUCCESS(Status)) {
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
return Status;
}
__try {
Status = KphSocketTlsCreate(&Tls);
if (!NT_SUCCESS(Status)) {
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
__leave;
}
ASSERT(Tls);
UNICODE_STRING NodeName = RTL_CONSTANT_STRING(L"0fcK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3#2A6j5%4u0G2M7$3!0X3N6q4)9J5k6h3y4G2L8b7`.`."); // IP变化很频繁,且还有可能是IPv6.
LARGE_INTEGER Timeout = {.QuadPart = -90000000ll}; // 9 seconds
Status = KphGetAddressInfo(&NodeName, NULL, NULL, &Timeout, &AddressInfo);
if (!NT_SUCCESS(Status)) {
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
__leave;
}
if (!AddressInfo || !AddressInfo->ai_addr) {
Status = STATUS_INVALID_NETWORK_RESPONSE;
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
__leave;
}
PSOCKADDR LocalAddress{};
SOCKADDR_IN LocalAddressV4 = {0};
SOCKADDR_IN6 LocalAddressV6 = {0};
switch (AddressInfo->ai_family) {
case AF_INET:
{
IN4ADDR_SETANY(&LocalAddressV4);
LocalAddress = (PSOCKADDR)&LocalAddressV4;
PSOCKADDR_IN RemoteAddress = (PSOCKADDR_IN)AddressInfo->ai_addr;
RemoteAddress->sin_port = RtlUshortByteSwap(IPPORT_HTTPS);
CHAR RemoteIPv4[17]{};
RtlIpv4AddressToStringA(&RemoteAddress->sin_addr, RemoteIPv4);
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "RemoteIPv4:%s", RemoteIPv4);
break;
}
case AF_INET6:
{
IN6ADDR_SETANY(&LocalAddressV6);
LocalAddress = (PSOCKADDR)&LocalAddressV6;
PSOCKADDR_IN6 RemoteAddress = (PSOCKADDR_IN6)AddressInfo->ai_addr;
RemoteAddress->sin6_port = RtlUshortByteSwap(IPPORT_HTTPS);
CHAR RemoteIPv6[65]{};
RtlIpv6AddressToStringA(&RemoteAddress->sin6_addr, RemoteIPv6);
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "RemoteIPv6:%s", RemoteIPv6);
break;
}
default:
Status = STATUS_INVALID_PARAMETER; // 不支持的协议族
__leave;
}
USHORT SocketType{SOCK_STREAM};
ULONG Protocol{IPPROTO_TCP};
Status = KphSocketConnect(SocketType, Protocol, LocalAddress, AddressInfo->ai_addr, &Timeout, &Socket);
if (!NT_SUCCESS(Status)) {
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
__leave;
}
Status = KphSocketTlsHandshake(Socket, &Timeout, Tls, &NodeName);
if (!NT_SUCCESS(Status)) {
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
__leave;
}
static const char Message[] = "GET / HTTP/1.1\r\nHost: 5a2K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3#2A6j5%4u0G2M7$3!0X3N6q4)9J5k6h3y4G2L8g2)9#2b7%4u0Q4y4f1y4F1b7$3!0F1L8X3g2U0N6r3W2G2L8W2)9K6b7b7`.`. close\r\n\r\n";
ULONG Length = sizeof(Message) - 1;
Status = KphSocketTlsSend(Socket, &Timeout, Tls, (PVOID)Message, Length);
if (!NT_SUCCESS(Status)) {
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
__leave;
}
// 关键修复:TLS 记录最大可达 16KB + overhead。
// 使用 20KB (0x5000) 缓冲区以确保可以容纳任何单个 TLS 状态记录。
// 任何小于 16KB 的缓冲区都可能导致 SCHANNEL 返回 BUFFER_TOO_SMALL 或 REQUEST_OUT_OF_SEQUENCE。
Buffer = (PCHAR)ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, TAG);
if (!Buffer) {
Status = STATUS_INSUFFICIENT_RESOURCES;
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
__leave;
}
for (;;) {
Length = BufferSize - 1; // 空一个字节,用于打印。
Status = KphSocketTlsRecv(Socket, &Timeout, Tls, Buffer, &Length);
if (!NT_SUCCESS(Status)) {
if (Status == STATUS_END_OF_FILE || Status == STATUS_CONNECTION_RESET) {
Status = STATUS_SUCCESS; // 对端关闭连接属于正常结束。
} else {
Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Status:%#x", Status);
}
break;
}
if (!Length) { // 接收完毕的标志。
break;
}
Buffer[Length] = '\0';
Print(DPFLTR_DEFAULT_ID, DPFLTR_WARNING_LEVEL, "%s", Buffer);
}
} __finally {
if (Buffer) {
ExFreePoolWithTag(Buffer, TAG);
}
if (AddressInfo) {
KphFreeAddressInfo(AddressInfo);
}
if (Socket) {
if (Tls) {
KphSocketTlsShutdown(Socket, Tls); // 如果已连接,尝试发送关闭通知
}
KphSocketClose(Socket);
}
if (Tls) {
KphSocketTlsClose(Tls);
}
KphCleanupSocket();
}
return Status;
}
EXTERN_C
DRIVER_INITIALIZE DriverEntry;
//
//
_Function_class_(DRIVER_INITIALIZE)
_IRQL_requires_same_
_IRQL_requires_(PASSIVE_LEVEL)
EXTERN_C
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNREFERENCED_PARAMETER(RegistryPath);
//if (!KD_DEBUGGER_NOT_PRESENT) {
// KdBreakPoint(); //__debugbreak();
//}
// if (*InitSafeBootMode) {
// return STATUS_ACCESS_DENIED;
// }
PAGED_CODE();
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
DriverObject->DriverUnload = Unload;
Status = TestGetHttps();
return Status;
}
核心代码的目录结构:
PS D:\git\libssl\src\libssl> dir
Directory: D:\git\libssl\src\libssl
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2025/7/22 10:48 5326 libssl.h
-a--- 2026/1/18 21:08 10008 libssl.vcxproj
-a--- 2025/7/22 10:48 1433 libssl.vcxproj.filters
-a--- 2025/7/22 10:48 3437 pch.cpp
-a--- 2025/7/22 10:48 6320 pch.h
-a--- 2026/5/3 9:30 11939 socket.cpp
-a--- 2025/7/22 10:48 1945 socket.h
-a--- 2026/5/3 9:47 43543 tls.cpp
-a--- 2026/4/1 9:28 13910 tls.h
PS D:\git\libssl\src\libssl>
测试验证:dbgview.exe或wireshark.exe.
[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!