【发布时间】:2015-07-15 22:34:32
【问题描述】:
我正在尝试对注入到进程中的 dll 进行逆向工程,它确实挂钩 winsock send() 并通过 PipeStream 发送数据。
这是读取管道流的 C# 代码:
[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() 函数,通过管道连接并发送消息。
问题是收到的数据不是我期望的数据,所以我可能以错误的方式发送。我需要帮助,因为我几乎没有 C++ 知识。
C++ 代码:
#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;
}
编辑,更多信息:
目标是通过管道发送一条包含 9 字节长的 PipeHeader 结构的消息,然后发送另一条包含 winsock send() 数据的消息(buf 变量),在 C# 应用程序上读取管道并解析第一条消息以获取下一条传入消息的DataSize(即PipeHeader 的datasize var),然后使用datasize 再次读取管道以获取send() 缓冲区。
我认为这是以这种方式工作的。我不太了解 Pipes 的工作原理。
无论如何,主要目标是将send() 缓冲区从 C++ Dll 发送到 C# 应用程序。
更新:
似乎我必须首先以某种方式序列化 PipeHeader 结构,以便我可以在 C# 代码中使用 RawDeserializeEx() 反序列化它。
我尝试这样做:
char buffer[sizeof(ph)];
memcpy(buffer, &ph, sizeof(ph));
问题在于,在 C++ 中 sizeof(ph) 或 sizeof(buffer) 返回 12 个字节。
而在 C# 中,相同 Struct 的非托管大小 (Marshal.SizeOf()) 返回 9 个字节。
更新 2: 通过更改结构包装解决了大小差异。 但我仍然没有在 C# 中得到正确的值。 代码已更新。
【问题讨论】:
-
请发布整个 C++ 代码。有许多变量未在您的代码中声明,例如
hPipe或cbWritten。pSend是什么?
标签: c# c++ named-pipes