首页
社区
课程
招聘
[原创]sys里https(只支持tls1.2 tls1.3)通讯的bin
发表于: 1天前 531

[原创]sys里https(只支持tls1.2 tls1.3)通讯的bin

1天前
531

例子代码:

#include "DriverEntry.h"
#include "..\libssl\libssl.h"


_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;
// #pragma INITCODE
// #pragma alloc_text(INIT, 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期)!

上传的附件:
收藏
免费 1
打赏
分享
最新回复 (1)
雪    币: 1187
活跃值: (3831)
能力值: ( LV12,RANK:385 )
在线值:
发帖
回帖
粉丝
2
libssl.h和libssl.lib暂不公开。
1天前
0
游客
登录 | 注册 方可回帖
返回