c - 使用 Windows 套接字的 WriteFile 返回无效参数错误

标签 c windows sockets writefile

我已经在 Windows 套接字上苦苦挣扎了两天,无法像在 Linux 中那样只使用写入套接字。我想编写自己的 shellcode,并且正在研究如何将 stdout、stdin 重定向到套接字句柄(这就是我的演奏的来源)。如果有必要,我使用 Windows 7 x64,内部版本 7601。这是我的代码

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main (int argc,char ** argv)
{   
    // boring code starts
    if (argc < 2)
    {
        printf("Usage getstdhandle <ip> <port> ");
    }

    WSADATA wsadata;
    int result = WSAStartup (MAKEWORD(2,2),&wsadata);
    if (result != NO_ERROR)
    {
        printf("error with wsastartup");
    }

    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons (atoi(argv[2]));
    server.sin_addr.s_addr = inet_addr (argv[1]);

    SOCKET soc = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (soc == INVALID_SOCKET)
    {
        printf("Error with creating socket");
    }

    if (connect(soc,(struct sockaddr *)&server,sizeof(server)) == SOCKET_ERROR)
    {
        printf("Problem with connecting");
    }

     // boring code ends

    const char * buf = "Tekscik \n"; // know it's not really good in new C standards
    const char buf[] = "Test\n";  // not working also, shouldn't have any influence

    bool isSent = WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10,NULL,NULL);
    DWORD ret = GetLastError();
    printf("%.08x",ret);

    closesocket(soc);
    WSACleanup();
    return 0;
}

这就是我运行程序的方式

C:\Users\Domin568\Desktop>getstdhandle 192.168.56.1 5555
Tekscik
00000057     <---- Error code in hex

在我的第二台机器上,我只是运行 nc 来监听这些数据,如下所示:

15:14|domin568[21] ~ $ nc -l -v -p 5555
Connection from 192.168.56.101:50328
15:15|domin568[22] ~ $ 

我收到错误代码 0x57,它是:

ERROR_INVALID_PARAMETER 87 (0x57) The parameter is incorrect.

Local network traffic (发送的任何数据,纯连接握手和FIN)

这可能是什么原因?我知道这不是发送数据的好方法,但 MSDN 说这应该是可能的。

最佳答案

来自WriteFile文档

lpOverlapped [in, out, optional]

A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL.

但是是 socket函数使用 FILE_FLAG_OVERLAPPED 创建文件(套接字,这是文件句柄,它指向 FILE_OBJECT 结构)?这是没有记录的,你无法控制它。所以你需要使用OVERLAPPED作为 WriteFile 的参数.

如果使用WSASocket我们这里已经有dwFlags选项,可以设置或不设置WSA_FLAG_OVERLAPPED(相当于FILE_FLAG_OVERLAPPED CreateFile)

为什么 OVERLAPPED当我们使用以 FILE_FLAG_OVERLAPPED 标志打开的 hFile 时,结构是必需的(FILE_OBJECT 中没有 FO_SYNCHRONOUS_IO 标志) )

WriteFile调用ZwWriteFile

寻找

ZwWriteFile

PLARGE_INTEGER ByteOffset [in,可选] 参数- 但仅当我们以同步方式打开文件时它才是可选的。如果文件以异步 I/O 模式打开 - 此参数是强制

来自wrk源代码

if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
}
else if (!ARGUMENT_PRESENT( ByteOffset ) && !(fileObject->Flags & (FO_NAMED_PIPE | FO_MAILSLOT))) {

        //
        // The file is not open for synchronous I/O operations, but the
        // caller did not specify a ByteOffset parameter.  This is an error
        // situation, so cleanup and return with the appropriate status.
        //

        if (eventObject) {
            ObDereferenceObject( eventObject );
        }
        ObDereferenceObject( fileObject );
        return STATUS_INVALID_PARAMETER;

    }

这正是您调用时的情况

WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10,NULL,NULL);

NtWriteFile 返回给您STATUS_INVALID_PARAMETER,它转换为 win32 错误ERROR_INVALID_PARAMETER

但接下来的代码将正常工作。

OVERLAPPED ov = {};
BOOL isSent = WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10, 0, &ov);

因为在这种情况下ByteOffset将指向&ov.Offset

但是,为了更好地向套接字发送数据,请使用 WSASend

关于c - 使用 Windows 套接字的 WriteFile 返回无效参数错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43939424/

相关文章:

python - 如何在python中声明变量类型,C风格

c - 为什么 odd * even 在 C 中不返回精确值?

c - 如何使用命令行选项覆盖 __TIME__ 和 __DATE__ 宏的值?

asp.net - Windows Azure 启动任务未触发

c - TCP 客户端不处理损坏的服务器在 C 中正确连接

android - InetAddress.getLocalHost().getHostAddress() 在 Android 中返回 127.0.0.1

iphone - 在 UITableView 中插入新单元格时表格未向上移动

windows - 如何更新日期和时间控制面板以匹配 W32Time 服务配置?

windows - 如何让 jenkins 在 windows 上运行 `bash` 命令?

sockets - 如何路由QEMU内部的TCP端口/套接字?