Я пытаюсь отменить обработку dll, введенного в процесс, который делает hook winsock send()
и отправляет данные по PipeStream
.
Это код С#, который считывает поток канала:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct PipeHeader
{
[MarshalAs(UnmanagedType.I1)]
public byte command;
[MarshalAs(UnmanagedType.I4)]
public int sockid;
public int datasize;
}
public static object RawDeserializeEx(byte[] rawdatas, Type anytype)
{
int rawsize = Marshal.SizeOf(anytype);
if (rawsize > rawdatas.Length)
return null;
GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
IntPtr buffer = handle.AddrOfPinnedObject();
object retobj = Marshal.PtrToStructure(buffer, anytype);
handle.Free();
return retobj;
}
private void PipeRead()
{
byte[] dbPipeMsgIn = new byte[9];
byte[] zero = new byte[] { 0 };
byte[] dbPipeMsgInData;
PipeLoop:
while (pipeIn.Read(dbPipeMsgIn, 0, 9) != 0)
{
strPipeMsgIn = (PipeHeader)RawDeserializeEx(dbPipeMsgIn, typeof(PipeHeader));
if (strPipeMsgIn.datasize != 0)
{
dbPipeMsgInData = new byte[strPipeMsgIn.datasize];
pipeIn.Read(dbPipeMsgInData, 0, dbPipeMsgInData.Length);
//do something with dbPipeMsgInData
}
}
if (pipeIn.IsConnected) goto PipeLoop;
}
До сих пор я подключил функцию send()
, подключил и отправил сообщения через трубу.
Проблема в том, что полученные данные - это не данные, которые я ожидаю, поэтому, вероятно, я сделал неправильный путь. Мне нужна помощь, потому что у меня очень мало знаний о С++.
Код С++:
#pragma pack(1)
typedef struct
{
byte command;
int sockid;
int datasize;
} PipeHeader;
#pragma pack(0)
int WINAPI MySend(SOCKET s, const char* buf, int len, int flags)
{
PipeHeader ph;
string p(buf);
if(p.find("<TalkMsg") == 0){
byte cmd = 0;
ph.command = cmd;
ph.sockid = s;
ph.datasize = len;
char buffer[sizeof(ph)];
memcpy(buffer, &ph, sizeof(ph));
if(SendPipeMessage(buffer, sizeof(buffer))){
if(SendPipeMessage(buf, sizeof(buf))){
MessageBox(NULL,"Message Sent", NULL, NULL);
}
}
fopen_s(&pSendLogFile, "C:\\SendLog.txt", "a+");
fprintf(pSendLogFile, "%s\n", buf);
fclose(pSendLogFile);
}
return pSend(s, buf, len, flags);
}
BOOL SendPipeMessage(LPCVOID lpvMessage, DWORD ctToWrite){
// Send a message to the pipe server.
cbToWrite = sizeof(lpvMessage);
fSuccess = WriteFile(
hPipe, // pipe handle
lpvMessage, // message
cbToWrite, // message length
&cbWritten, // bytes written
NULL); // not overlapped
if ( ! fSuccess)
{
return false;
}else return true;
}
Изменить, подробнее:
Цель состоит в том, чтобы отправить сообщение, содержащее длительность PipeHeader
Struct по 9 байтам по каналу, затем отправить другое сообщение, содержащее данные winsock send()
, (переменную buf
), прочитать трубу в приложении С# и проанализируйте первое сообщение, чтобы получить DataSize следующего входящего сообщения (что datasize
var of PipeHeader
), затем, используя datasize
, снова прочитайте трубку, чтобы получить буфер send().
Я думаю, что работаю именно так. Я не очень хорошо знаю, как работает Pipes.
В любом случае главная цель - отправить буфер send()
из С++ Dll в приложение С#.
Update:
Кажется, что я должен сначала сериализовать структуру PipeHeader
таким образом, чтобы я мог Deserialize с помощью RawDeserializeEx()
в коде С#.
Я пробовал:
char buffer[sizeof(ph)];
memcpy(buffer, &ph, sizeof(ph));
Проблема заключается в том, что в С++ sizeof(ph)
или sizeof(buffer)
возвращается 12 байтов.
Вместо этого в С# неуправляемый размер (Marshal.SizeOf()
) того же Struct, верните 9 байтов.
Обновление 2: Устранены различия в размерах, изменив структуру упаковки. Но я все еще не получаю правильные значения в С#. Обновлен код.