WriteFile with Windows Sockets returns invalid parameter 错误
WriteFile with Windows Sockets returns invalid parameter error
我已经为 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 说它应该是可能的。
MSDN 说应该可以。
是真的吗? socket handles documentation states:
A socket handle can optionally be a file handle in Windows Sockets 2.
A socket handle from a Winsock provider can be used with other
non-Winsock functions such as ReadFile, WriteFile, ReadFileEx, and
WriteFileEx.
注意单词 "optionally"。
WriteFile with SocketHandle Fails
...
Not sure how you can read that page and think that it is a good idea
to use a socket handle with ReadFile et al.
Let's start with this sentence "A socket handle can optionally be a
file handle in Windows Sockets 2". That can be read two different
ways:
You can optionally use any socket handle as a file handle for ReadFile and friends
A socket provider can optionally provide dual-use sockets that work with ReadFile as well as the socket functions.
Unfortunately there is not enough information in that article to
conclusively decide whether #1 or #2 is correct. However the fact
that ReadFile returns ERROR_INVALID_PARAMETER (per Mike Danes'
comment) I am going to assume that #2 is the correct interpretation
and your network socket is not also a file handle. (Note that
frequently the MSDN documentation is written more from the perspective
of the team that implemented API than from a consumer of the API. If
you look at it in that light, #2 is the more likely interpretation --
I will agree that it is annoying because a consumer of the API is more
likely to understand the sentence as #1)
来自 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_OBJECT
结构 ) 和 FILE_FLAG_OVERLAPPED
?这是未记录的,您无法控制。所以你需要使用 OVERLAPPED
作为 WriteFile
.
的参数
if use WSASocket
我们这里已经有 dwFlags 选项并且可以设置或不设置 WSA_FLAG_OVERLAPPED
(这相当于 FILE_FLAG_OVERLAPPED
for CreateFile
)
为什么 OVERLAPPED
structure is required when we use hFile opened with FILE_FLAG_OVERLAPPED
flag (no FO_SYNCHRONOUS_IO
flag in FILE_OBJECT
) ?
寻找
PLARGE_INTEGER ByteOffset [in, optional]
ZwWriteFile
的参数 - 但仅当我们以同步方式打开文件时才可选。如果文件以异步 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
return 给你STATUS_INVALID_PARAMETER
里面转换成win32报错ERROR_INVALID_PARAMETER
但下一个代码将正常工作。
OVERLAPPED ov = {};
BOOL isSent = WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10, 0, &ov);
因为在这种情况下 ByteOffset
将指向 &ov.Offset
然而,为了将数据发送到套接字,更好地使用 WSASend
我已经为 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 说它应该是可能的。
MSDN 说应该可以。
是真的吗? socket handles documentation states:
A socket handle can optionally be a file handle in Windows Sockets 2. A socket handle from a Winsock provider can be used with other non-Winsock functions such as ReadFile, WriteFile, ReadFileEx, and WriteFileEx.
注意单词 "optionally"。
WriteFile with SocketHandle Fails
...
Not sure how you can read that page and think that it is a good idea to use a socket handle with ReadFile et al.
Let's start with this sentence "A socket handle can optionally be a file handle in Windows Sockets 2". That can be read two different ways:
You can optionally use any socket handle as a file handle for ReadFile and friends
A socket provider can optionally provide dual-use sockets that work with ReadFile as well as the socket functions.
Unfortunately there is not enough information in that article to conclusively decide whether #1 or #2 is correct. However the fact that ReadFile returns ERROR_INVALID_PARAMETER (per Mike Danes' comment) I am going to assume that #2 is the correct interpretation and your network socket is not also a file handle. (Note that frequently the MSDN documentation is written more from the perspective of the team that implemented API than from a consumer of the API. If you look at it in that light, #2 is the more likely interpretation -- I will agree that it is annoying because a consumer of the API is more likely to understand the sentence as #1)
来自 WriteFile
文档
lpOverlapped [in, out, optional]
A pointer to an
OVERLAPPED
structure is required if the hFile parameter was opened withFILE_FLAG_OVERLAPPED
, otherwise this parameter can be NULL.
但是是socket
函数创建文件(套接字这是文件句柄,它指向FILE_OBJECT
结构 ) 和 FILE_FLAG_OVERLAPPED
?这是未记录的,您无法控制。所以你需要使用 OVERLAPPED
作为 WriteFile
.
if use WSASocket
我们这里已经有 dwFlags 选项并且可以设置或不设置 WSA_FLAG_OVERLAPPED
(这相当于 FILE_FLAG_OVERLAPPED
for CreateFile
)
为什么 OVERLAPPED
structure is required when we use hFile opened with FILE_FLAG_OVERLAPPED
flag (no FO_SYNCHRONOUS_IO
flag in FILE_OBJECT
) ?
寻找
PLARGE_INTEGER ByteOffset [in, optional]
ZwWriteFile
的参数 - 但仅当我们以同步方式打开文件时才可选。如果文件以异步 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
return 给你STATUS_INVALID_PARAMETER
里面转换成win32报错ERROR_INVALID_PARAMETER
但下一个代码将正常工作。
OVERLAPPED ov = {};
BOOL isSent = WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10, 0, &ov);
因为在这种情况下 ByteOffset
将指向 &ov.Offset
然而,为了将数据发送到套接字,更好地使用 WSASend