Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crossin的编程教室
ComWeChatRobot
提交
f68111cf
C
ComWeChatRobot
项目概览
Crossin的编程教室
/
ComWeChatRobot
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ComWeChatRobot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
f68111cf
编写于
8月 25, 2022
作者:
J
Jack Li
提交者:
GitHub
8月 25, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #94 from ljc545w/add/msg-extrabuf
修改接收消息格式,消息内容添加扩展信息
上级
42a1466d
9a91f78a
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
288 addition
and
382 deletion
+288
-382
.pre-commit-config.yaml
.pre-commit-config.yaml
+2
-1
DWeChatRobot/ReceiveMessage.cpp
DWeChatRobot/ReceiveMessage.cpp
+46
-98
DWeChatRobot/SearchContactByCache.cpp
DWeChatRobot/SearchContactByCache.cpp
+24
-42
DWeChatRobot/SelfInfo.cpp
DWeChatRobot/SelfInfo.cpp
+128
-142
DWeChatRobot/base64/base64.cpp
DWeChatRobot/base64/base64.cpp
+3
-3
DWeChatRobot/pch.cpp
DWeChatRobot/pch.cpp
+17
-0
DWeChatRobot/pch.h
DWeChatRobot/pch.h
+1
-0
DWeChatRobot/wxapi.h
DWeChatRobot/wxapi.h
+1
-0
DWeChatRobot/wxdata.h
DWeChatRobot/wxdata.h
+1
-0
DWeChatRobot/wxsocket.cpp
DWeChatRobot/wxsocket.cpp
+17
-7
DWeChatRobot/wxsocketapi.h
DWeChatRobot/wxsocketapi.h
+0
-1
Python/test.py
Python/test.py
+1
-1
Python/wxRobot.py
Python/wxRobot.py
+25
-50
README.md
README.md
+11
-9
Release/DWeChatRobot.dll
Release/DWeChatRobot.dll
+0
-0
Release/socket/SWeChatRobot.dll
Release/socket/SWeChatRobot.dll
+0
-0
Release/socket/wxDriver.py
Release/socket/wxDriver.py
+11
-28
未找到文件。
.pre-commit-config.yaml
浏览文件 @
f68111cf
...
...
@@ -24,5 +24,6 @@ repos:
exclude
:
|
(?x)^(
.*?_i\.h|
.*?_p\.c
.*?_p\.c|
.*?\.md
)
DWeChatRobot/ReceiveMessage.cpp
浏览文件 @
f68111cf
...
...
@@ -3,6 +3,8 @@
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <map>
#include "json/json.hpp"
using
namespace
nlohmann
;
#pragma comment(lib, "ws2_32.lib")
...
...
@@ -24,19 +26,6 @@ using namespace std;
static
int
SRVPORT
=
0
;
struct
ScoketMsgStruct
{
DWORD
pid
;
int
messagetype
;
BOOL
isSendMessage
;
unsigned
long
long
msgid
;
wchar_t
sender
[
80
];
wchar_t
wxid
[
80
];
wchar_t
message
[
0x1000B
];
wchar_t
filepath
[
MAX_PATH
];
wchar_t
time
[
30
];
};
// 是否开启接收消息HOOK标志
BOOL
ReceiveMessageHooked
=
false
;
// 保存HOOK前的字节码,用于恢复
...
...
@@ -56,10 +45,23 @@ static DWORD SendMessageNextCall = WeChatWinBase + SendMessageNextCallOffset;
// 发送HOOK的跳转地址
static
DWORD
SendMessageJmpBackAddress
=
SendMessageHookAddress
+
0x5
;
struct
SocketMessageStruct
{
char
*
buffer
;
int
length
;
~
SocketMessageStruct
()
{
if
(
this
->
buffer
!=
NULL
)
{
delete
[]
this
->
buffer
;
this
->
buffer
=
NULL
;
}
}
};
// 通过socket将消息发送给服务端
BOOL
SendSocketMessage
(
ReceiveMsgStruct
*
ms
)
BOOL
SendSocketMessage
(
const
char
*
buffer
,
size_t
len
)
{
shared_ptr
<
ReceiveMsgStruct
>
shared_ms
(
ms
);
if
(
SRVPORT
==
0
)
{
return
false
;
...
...
@@ -89,21 +91,7 @@ BOOL SendSocketMessage(ReceiveMsgStruct *ms)
return
false
;
}
char
recvbuf
[
1024
]
=
{
0
};
auto
sms
=
std
::
make_shared
<
ScoketMsgStruct
>
();
ZeroMemory
(
sms
.
get
(),
sizeof
(
ScoketMsgStruct
));
sms
->
pid
=
shared_ms
->
pid
;
sms
->
messagetype
=
shared_ms
->
messagetype
;
sms
->
isSendMessage
=
shared_ms
->
isSendMessage
;
sms
->
msgid
=
shared_ms
->
msgid
;
memcpy
(
sms
->
wxid
,
shared_ms
->
wxid
.
c_str
(),
shared_ms
->
wxid
.
length
()
*
2
);
memcpy
(
sms
->
sender
,
shared_ms
->
sender
.
c_str
(),
shared_ms
->
sender
.
length
()
*
2
);
memcpy
(
sms
->
message
,
shared_ms
->
message
.
c_str
(),
shared_ms
->
message
.
length
()
*
2
);
memcpy
(
sms
->
filepath
,
shared_ms
->
filepath
.
c_str
(),
shared_ms
->
filepath
.
length
()
*
2
);
memcpy
(
sms
->
time
,
shared_ms
->
time
.
c_str
(),
shared_ms
->
time
.
length
()
*
2
);
#ifdef _DEBUG
wcout
<<
sms
->
time
<<
endl
;
#endif
int
ret
=
send
(
clientsocket
,
(
char
*
)
sms
.
get
(),
sizeof
(
ScoketMsgStruct
),
0
);
int
ret
=
send
(
clientsocket
,
buffer
,
len
,
0
);
if
(
ret
==
-
1
||
ret
==
0
)
{
#ifdef _DEBUG
...
...
@@ -126,83 +114,43 @@ BOOL SendSocketMessage(ReceiveMsgStruct *ms)
return
true
;
}
// 创建广播消息数组
#ifndef USE_SOCKET
static
SAFEARRAY
*
CreateMessageArray
(
map
<
wstring
,
_variant_t
>
msg
)
void
SendSocketMessageInThread
(
SocketMessageStruct
*
param
)
{
HRESULT
hr
=
S_OK
;
SAFEARRAY
*
psaValue
;
vector
<
wstring
>
MessageInfoKey
=
{
L"pid"
,
L"type"
,
L"isSendMessage"
,
L"msgid"
,
msg
[
L"isSendMessage"
].
boolVal
?
L"sendto"
:
L"from"
,
L"wxid"
,
L"message"
,
L"filepath"
,
L"time"
};
SAFEARRAYBOUND
rgsaBound
[
2
]
=
{{
MessageInfoKey
.
size
(),
0
},
{
2
,
0
}};
psaValue
=
SafeArrayCreate
(
VT_VARIANT
,
2
,
rgsaBound
);
long
keyIndex
[
2
]
=
{
0
,
0
};
keyIndex
[
0
]
=
0
;
keyIndex
[
1
]
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
MessageInfoKey
.
size
();
i
++
)
{
keyIndex
[
0
]
=
i
;
keyIndex
[
1
]
=
0
;
_variant_t
key
=
MessageInfoKey
[
i
].
c_str
();
hr
=
SafeArrayPutElement
(
psaValue
,
keyIndex
,
&
key
);
keyIndex
[
0
]
=
i
;
keyIndex
[
1
]
=
1
;
hr
=
SafeArrayPutElement
(
psaValue
,
keyIndex
,
&
msg
[
MessageInfoKey
[
i
]]);
}
return
psaValue
;
if
(
param
==
NULL
)
return
;
unique_ptr
<
SocketMessageStruct
>
sms
(
param
);
string
jstr
(
param
->
buffer
,
param
->
length
);
SendSocketMessage
(
jstr
.
c_str
(),
jstr
.
size
());
}
#endif
static
void
dealMessage
(
DWORD
messageAddr
)
{
BOOL
isSendMessage
=
*
(
BOOL
*
)(
messageAddr
+
0x3C
);
ReceiveMsgStruct
*
message
=
new
ReceiveMsgStruct
;
ZeroMemory
(
message
,
sizeof
(
ReceiveMsgStruct
));
message
->
pid
=
GetCurrentProcessId
();
message
->
isSendMessage
=
isSendMessage
;
message
->
time
=
GetTimeW
(
*
(
DWORD
*
)(
messageAddr
+
0x44
));
message
->
messagetype
=
*
(
DWORD
*
)(
messageAddr
+
0x38
);
message
->
msgid
=
*
(
unsigned
long
long
*
)(
messageAddr
+
0x30
);
message
->
sender
=
READ_WSTRING
(
messageAddr
,
0x48
);
json
jMsg
;
unsigned
long
long
msgid
=
*
(
unsigned
long
long
*
)(
messageAddr
+
0x30
);
jMsg
[
"pid"
]
=
GetCurrentProcessId
();
jMsg
[
"type"
]
=
*
(
DWORD
*
)(
messageAddr
+
0x38
);
jMsg
[
"isSendMsg"
]
=
*
(
BOOL
*
)(
messageAddr
+
0x3C
);
jMsg
[
"msgid"
]
=
msgid
;
jMsg
[
"sender"
]
=
unicode_to_utf8
((
wchar_t
*
)
READ_WSTRING
(
messageAddr
,
0x48
).
c_str
());
int
length
=
*
(
DWORD
*
)(
messageAddr
+
0x170
+
0x4
);
if
(
length
==
0
)
{
message
->
wxid
=
message
->
sender
;
}
else
{
message
->
wxid
=
READ_WSTRING
(
messageAddr
,
0x170
);
}
message
->
message
=
READ_WSTRING
(
messageAddr
,
0x70
);
message
->
filepath
=
READ_WSTRING
(
messageAddr
,
0x1AC
);
jMsg
[
"wxid"
]
=
length
==
0
?
jMsg
[
"sender"
].
get
<
std
::
string
>
()
:
unicode_to_utf8
((
wchar_t
*
)
READ_WSTRING
(
messageAddr
,
0x170
).
c_str
());
jMsg
[
"message"
]
=
unicode_to_utf8
((
wchar_t
*
)
READ_WSTRING
(
messageAddr
,
0x70
).
c_str
());
jMsg
[
"filepath"
]
=
unicode_to_utf8
((
wchar_t
*
)
READ_WSTRING
(
messageAddr
,
0x1AC
).
c_str
());
string
extrabuf
=
base64_encode
((
BYTE
*
)(
*
(
DWORD
*
)(
messageAddr
+
0x8C
)),
*
(
DWORD
*
)(
messageAddr
+
0x8C
+
0x4
));
jMsg
[
"extrainfo"
]
=
extrabuf
;
jMsg
[
"time"
]
=
unicode_to_utf8
((
wchar_t
*
)
GetTimeW
(
*
(
DWORD
*
)(
messageAddr
+
0x44
)).
c_str
());
string
jstr
=
jMsg
.
dump
()
+
'\n'
;
#ifdef USE_COM
// 通过连接点,将消息广播给客户端
map
<
wstring
,
_variant_t
>
msg_map
;
msg_map
[
L"pid"
]
=
message
->
pid
;
msg_map
[
L"isSendMessage"
]
=
isSendMessage
;
msg_map
[
L"time"
]
=
message
->
time
.
c_str
();
msg_map
[
L"type"
]
=
message
->
messagetype
;
msg_map
[
L"msgid"
]
=
message
->
msgid
;
msg_map
[
L"sendto"
]
=
message
->
sender
.
c_str
();
msg_map
[
L"from"
]
=
message
->
sender
.
c_str
();
msg_map
[
L"wxid"
]
=
message
->
wxid
.
c_str
();
msg_map
[
L"message"
]
=
message
->
message
.
c_str
();
msg_map
[
L"filepath"
]
=
message
->
filepath
.
c_str
();
SAFEARRAY
*
psaValue
=
CreateMessageArray
(
msg_map
);
VARIANT
vsaValue
;
vsaValue
.
vt
=
VT_ARRAY
|
VT_VARIANT
;
V_ARRAY
(
&
vsaValue
)
=
psaValue
;
PostComMessage
(
message
->
pid
,
WX_MESSAGE
,
message
->
msgid
,
&
vsaValue
);
VARIANT
vsaValue
=
(
_variant_t
)
jstr
.
c_str
();
PostComMessage
(
jMsg
[
"pid"
].
get
<
int
>
(),
WX_MESSAGE
,
msgid
,
&
vsaValue
);
#endif
HANDLE
hThread
=
CreateThread
(
NULL
,
0
,
(
LPTHREAD_START_ROUTINE
)
SendSocketMessage
,
message
,
NULL
,
0
);
// 为保证线程安全,需要手动管理内存
SocketMessageStruct
*
sms
=
new
SocketMessageStruct
;
sms
->
buffer
=
new
char
[
jstr
.
size
()
+
1
];
memcpy
(
sms
->
buffer
,
jstr
.
c_str
(),
jstr
.
size
()
+
1
);
sms
->
length
=
jstr
.
size
();
HANDLE
hThread
=
CreateThread
(
NULL
,
0
,
(
LPTHREAD_START_ROUTINE
)
SendSocketMessageInThread
,
sms
,
NULL
,
0
);
if
(
hThread
)
{
CloseHandle
(
hThread
);
...
...
DWeChatRobot/SearchContactByCache.cpp
浏览文件 @
f68111cf
...
...
@@ -2,6 +2,9 @@
#include <typeinfo>
#include <string>
#include <vector>
#include <map>
#include "json/json.hpp"
using
namespace
nlohmann
;
// 获取好友信息CALL1偏移
#define GetUserInfoCall1Offset 0x100BD5C0 - 0x10000000
...
...
@@ -34,50 +37,29 @@ struct GetUserInfoStruct
*/
static
wstring
WxUserInfo
(
DWORD
address
)
{
wstring
wUserInfo
=
L""
;
vector
<
DWORD
>
InfoType
{
address
+
0x10
,
address
+
0x24
,
address
+
0x38
,
address
+
0x58
,
address
+
0x6C
,
address
+
0xFC
,
address
+
0x110
,
address
+
0x19C
,
address
+
0x1B0
,
address
+
0x1C4
,
address
+
0x1D8
,
address
+
0x27C
};
vector
<
wchar_t
*>
InfoTypeName
{
(
WCHAR
*
)
L"
\"
wxId
\"
"
,
(
WCHAR
*
)
L"
\"
wxNumber
\"
"
,
(
WCHAR
*
)
L"
\"
wxV3
\"
"
,
(
WCHAR
*
)
L"
\"
wxRemark
\"
"
,
(
WCHAR
*
)
L"
\"
wxNickName
\"
"
,
(
WCHAR
*
)
L"
\"
wxBigAvatar
\"
"
,
(
WCHAR
*
)
L"
\"
wxSmallAvatar
\"
"
,
(
WCHAR
*
)
L"
\"
wxSignature
\"
"
,
(
WCHAR
*
)
L"
\"
wxNation
\"
"
,
(
WCHAR
*
)
L"
\"
wxProvince
\"
"
,
(
WCHAR
*
)
L"
\"
wxCity
\"
"
,
(
WCHAR
*
)
L"
\"
wxBackground
\"
"
,
};
wUserInfo
+=
L"{"
;
for
(
unsigned
int
i
=
0
;
i
<
InfoType
.
size
();
i
++
)
json
jData
;
map
<
string
,
DWORD
>
key_addr_map
;
key_addr_map
[
"wxId"
]
=
address
+
0x10
;
key_addr_map
[
"wxNumber"
]
=
address
+
0x24
;
key_addr_map
[
"wxV3"
]
=
address
+
0x38
;
key_addr_map
[
"wxRemark"
]
=
address
+
0x58
;
key_addr_map
[
"wxNickName"
]
=
address
+
0x6C
;
key_addr_map
[
"wxBigAvatar"
]
=
address
+
0xFC
;
key_addr_map
[
"wxSmallAvatar"
]
=
address
+
0x110
;
key_addr_map
[
"wxSignature"
]
=
address
+
0x19C
;
key_addr_map
[
"wxNation"
]
=
address
+
0x1B0
;
key_addr_map
[
"wxProvince"
]
=
address
+
0x1C4
;
key_addr_map
[
"wxCity"
]
=
address
+
0x1D8
;
key_addr_map
[
"wxBackground"
]
=
address
+
0x27C
;
for
(
auto
it
=
key_addr_map
.
begin
();
it
!=
key_addr_map
.
end
();
it
++
)
{
wchar_t
*
wstemp
=
((
*
((
DWORD
*
)
InfoType
[
i
]))
!=
0
)
?
(
WCHAR
*
)(
*
((
LPVOID
*
)
InfoType
[
i
]))
:
(
WCHAR
*
)
L"null"
;
wstring
wsrtemp
=
wreplace
(
wstemp
,
L'\"'
,
L"
\\\"
"
);
wUserInfo
=
wUserInfo
+
InfoTypeName
[
i
]
+
L":
\"
"
+
wsrtemp
+
L"
\"
"
;
if
(
i
!=
InfoType
.
size
()
-
1
)
{
wUserInfo
+=
L","
;
}
string
key
=
it
->
first
;
DWORD
addr
=
it
->
second
;
wstring
wstemp
=
((
*
((
DWORD
*
)
addr
))
!=
0
)
?
(
wstring
)(
WCHAR
*
)(
*
((
LPVOID
*
)
addr
))
:
L"null"
;
string
value
=
unicode_to_utf8
((
wchar_t
*
)
wstemp
.
c_str
());
jData
[
key
]
=
value
;
}
wUserInfo
+=
L"}"
;
#ifdef _DEBUG
wcout
.
imbue
(
locale
(
"chs"
));
wcout
<<
wUserInfo
.
c_str
()
<<
endl
;
#endif
wstring
wUserInfo
=
utf8_to_unicode
(
jData
.
dump
().
c_str
());
return
wUserInfo
;
}
...
...
DWeChatRobot/SelfInfo.cpp
浏览文件 @
f68111cf
#include "pch.h"
#include <vector>
#include "json/json.hpp"
#include <map>
using
namespace
nlohmann
;
#define CheckLoginOffset 0x2366538
// 个人WXID偏移
...
...
@@ -11,159 +13,141 @@
* length:selfinfo字符串长度
*/
#ifndef USE_SOCKET
struct
SelfInfoStruct
{
DWORD
message
;
DWORD
length
;
struct
SelfInfoStruct
{
DWORD
message
;
DWORD
length
;
}
ret
;
#endif // !USE_SOCKET
/*
* 供外部调用的获取个人信息接口
* return:DWORD,ret的首地址
*/
#ifndef USE_SOCKET
DWORD
GetSelfInfoRemote
()
{
ZeroMemory
(
&
ret
,
sizeof
(
SelfInfoStruct
));
wstring
selfinfo
=
GetSelfInfo
();
wchar_t
*
message
=
new
wchar_t
[
selfinfo
.
length
()
+
1
];
memcpy
(
message
,
selfinfo
.
c_str
(),(
selfinfo
.
length
()
+
1
)
*
2
);
ret
.
message
=
(
DWORD
)
message
;
ret
.
length
=
selfinfo
.
length
();
return
(
DWORD
)
&
ret
;
DWORD
GetSelfInfoRemote
()
{
ZeroMemory
(
&
ret
,
sizeof
(
SelfInfoStruct
));
wstring
selfinfo
=
GetSelfInfo
();
wchar_t
*
message
=
new
wchar_t
[
selfinfo
.
length
()
+
1
];
memcpy
(
message
,
selfinfo
.
c_str
(),
(
selfinfo
.
length
()
+
1
)
*
2
);
ret
.
message
=
(
DWORD
)
message
;
ret
.
length
=
selfinfo
.
length
();
return
(
DWORD
)
&
ret
;
}
#endif
wstring
GetSelfWxid
()
{
DWORD
baseAddr
=
GetWeChatWinBase
()
+
SelfWxidAddrOffset
;
char
wxidbuffer
[
0x100
]
=
{
0
};
DWORD
SelfWxIdAddr
=
0x0
;
sprintf_s
(
wxidbuffer
,
"%s"
,
(
char
*
)
baseAddr
);
if
(
strlen
(
wxidbuffer
)
<
0x6
||
strlen
(
wxidbuffer
)
>
0x14
)
{
SelfWxIdAddr
=
*
(
DWORD
*
)
baseAddr
;
}
else
{
SelfWxIdAddr
=
baseAddr
;
}
if
(
SelfWxIdAddr
==
0
)
{
return
L""
;
}
char
*
sselfwxid
=
(
char
*
)
SelfWxIdAddr
;
wchar_t
*
wselfwxid
=
new
wchar_t
[
strlen
(
sselfwxid
)
+
1
];
MultiByteToWideChar
(
CP_ACP
,
0
,
sselfwxid
,
-
1
,
wselfwxid
,
strlen
(
sselfwxid
)
+
1
);
wstring
wxid
(
wselfwxid
);
delete
[]
wselfwxid
;
return
wxid
;
wstring
GetSelfWxid
()
{
DWORD
baseAddr
=
GetWeChatWinBase
()
+
SelfWxidAddrOffset
;
char
wxidbuffer
[
0x100
]
=
{
0
};
DWORD
SelfWxIdAddr
=
0x0
;
sprintf_s
(
wxidbuffer
,
"%s"
,
(
char
*
)
baseAddr
);
if
(
strlen
(
wxidbuffer
)
<
0x6
||
strlen
(
wxidbuffer
)
>
0x14
)
{
SelfWxIdAddr
=
*
(
DWORD
*
)
baseAddr
;
}
else
{
SelfWxIdAddr
=
baseAddr
;
}
if
(
SelfWxIdAddr
==
0
)
{
return
L""
;
}
char
*
sselfwxid
=
(
char
*
)
SelfWxIdAddr
;
wchar_t
*
wselfwxid
=
new
wchar_t
[
strlen
(
sselfwxid
)
+
1
];
MultiByteToWideChar
(
CP_ACP
,
0
,
sselfwxid
,
-
1
,
wselfwxid
,
strlen
(
sselfwxid
)
+
1
);
wstring
wxid
(
wselfwxid
);
delete
[]
wselfwxid
;
return
wxid
;
}
/*
* 获取个人信息
*/
wstring
GetSelfInfo
()
{
wstring
selfinfo
=
L""
;
DWORD
WeChatWinBase
=
GetWeChatWinBase
();
vector
<
DWORD
>
SelfInfoAddr
=
{
WeChatWinBase
+
0x236607C
,
WeChatWinBase
+
0x2366548
,
WeChatWinBase
+
0x23660F4
,
WeChatWinBase
+
0x23661F8
,
*
(
DWORD
*
)(
WeChatWinBase
+
0x236622C
),
*
(
DWORD
*
)(
WeChatWinBase
+
0x23A111C
),
*
(
DWORD
*
)(
WeChatWinBase
+
0x23663D4
),
WeChatWinBase
+
0x23662E8
,
WeChatWinBase
+
0x23661FC
,
WeChatWinBase
+
0x2366214
,
WeChatWinBase
+
0x2366128
};
vector
<
wstring
>
SelfInfoKey
=
{
L"
\"
wxId
\"
"
,
L"
\"
wxNumber
\"
"
,
L"
\"
wxNickName
\"
"
,
L"
\"
Sex
\"
"
,
L"
\"
wxSignature
\"
"
,
L"
\"
wxBigAvatar
\"
"
,
L"
\"
wxSmallAvatar
\"
"
,
L"
\"
wxNation
\"
"
,
L"
\"
wxProvince
\"
"
,
L"
\"
wxCity
\"
"
,
L"
\"
PhoneNumber
\"
"
};
selfinfo
=
selfinfo
+
L"{"
;
for
(
unsigned
int
i
=
0
;
i
<
SelfInfoAddr
.
size
();
i
++
)
{
selfinfo
=
selfinfo
+
SelfInfoKey
[
i
]
+
L":"
;
selfinfo
=
selfinfo
+
L"
\"
"
;
char
*
temp
=
NULL
;
if
(
!
SelfInfoKey
[
i
].
compare
(
L"
\"
wxNickName
\"
"
))
{
if
(
*
(
DWORD
*
)(
SelfInfoAddr
[
i
]
+
0x14
)
==
0xF
)
{
temp
=
(
*
((
DWORD
*
)
SelfInfoAddr
[
i
])
!=
0
)
?
(
char
*
)
SelfInfoAddr
[
i
]
:
(
char
*
)
"null"
;
}
else
{
temp
=
(
*
((
DWORD
*
)
SelfInfoAddr
[
i
])
!=
0
)
?
(
char
*
)(
*
(
DWORD
*
)
SelfInfoAddr
[
i
])
:
(
char
*
)
"null"
;
}
}
else
if
(
!
SelfInfoKey
[
i
].
compare
(
L"
\"
wxId
\"
"
))
{
char
wxidbuffer
[
0x100
]
=
{
0
};
sprintf_s
(
wxidbuffer
,
"%s"
,
(
char
*
)
SelfInfoAddr
[
i
]);
if
(
strlen
(
wxidbuffer
)
<
0x6
||
strlen
(
wxidbuffer
)
>
0x14
)
{
//新的微信号 微信ID用地址保存
temp
=
(
char
*
)(
*
(
DWORD
*
)
SelfInfoAddr
[
i
]);
}
else
{
temp
=
(
char
*
)
SelfInfoAddr
[
i
];
}
}
else
if
(
!
SelfInfoKey
[
i
].
compare
(
L"
\"
Sex
\"
"
))
{
int
sex
=
*
(
int
*
)
SelfInfoAddr
[
i
];
switch
(
sex
)
{
case
1
:
{
selfinfo
=
selfinfo
+
L"男
\"
,"
;
break
;
}
case
2
:
{
selfinfo
=
selfinfo
+
L"女
\"
,"
;
break
;
}
default:
{
selfinfo
=
selfinfo
+
L"未知
\"
,"
;
break
;
}
}
continue
;
}
else
{
temp
=
(
char
*
)
SelfInfoAddr
[
i
];
if
(
temp
==
NULL
||
strlen
(
temp
)
==
0
)
{
temp
=
(
char
*
)
"null"
;
}
}
wchar_t
*
wtemp
=
new
wchar_t
[
strlen
(
temp
)
+
1
];
ZeroMemory
(
wtemp
,
(
strlen
(
temp
)
+
1
)
*
2
);
MultiByteToWideChar
(
CP_UTF8
,
0
,
temp
,
-
1
,
wtemp
,
strlen
(
temp
)
+
1
);
wstring
wrtemp
=
wreplace
(
wtemp
,
L'\"'
,
L"
\\\"
"
);
selfinfo
=
selfinfo
+
wrtemp
;
selfinfo
=
selfinfo
+
L"
\"
"
;
if
(
i
!=
SelfInfoAddr
.
size
()
-
1
)
selfinfo
=
selfinfo
+
L","
;
delete
[]
wtemp
;
wtemp
=
NULL
;
}
selfinfo
=
selfinfo
+
L"}"
;
#ifdef _DEBUG
wcout
.
imbue
(
locale
(
"chs"
));
wcout
<<
selfinfo
<<
endl
;
#endif
return
selfinfo
;
wstring
GetSelfInfo
()
{
json
jData
;
map
<
string
,
DWORD
>
self_info_addr
;
DWORD
WeChatWinBase
=
GetWeChatWinBase
();
self_info_addr
[
"wxId"
]
=
WeChatWinBase
+
0x236607C
;
self_info_addr
[
"wxNumber"
]
=
WeChatWinBase
+
0x2366548
;
self_info_addr
[
"wxNickName"
]
=
WeChatWinBase
+
0x23660F4
;
self_info_addr
[
"Sex"
]
=
WeChatWinBase
+
0x23661F8
;
self_info_addr
[
"wxSignature"
]
=
*
(
DWORD
*
)(
WeChatWinBase
+
0x236622C
);
self_info_addr
[
"wxBigAvatar"
]
=
*
(
DWORD
*
)(
WeChatWinBase
+
0x23A111C
);
self_info_addr
[
"wxSmallAvatar"
]
=
*
(
DWORD
*
)(
WeChatWinBase
+
0x23663D4
);
self_info_addr
[
"wxNation"
]
=
WeChatWinBase
+
0x23662E8
;
self_info_addr
[
"wxProvince"
]
=
WeChatWinBase
+
0x23661FC
;
self_info_addr
[
"wxCity"
]
=
WeChatWinBase
+
0x2366214
;
self_info_addr
[
"PhoneNumber"
]
=
WeChatWinBase
+
0x2366128
;
for
(
auto
it
=
self_info_addr
.
begin
();
it
!=
self_info_addr
.
end
();
it
++
)
{
string
key
=
it
->
first
;
DWORD
addr
=
it
->
second
;
string
temp
;
if
(
!
key
.
compare
(
"wxNickName"
))
{
if
(
*
(
DWORD
*
)(
addr
+
0x14
)
==
0xF
)
{
temp
=
(
*
((
DWORD
*
)
addr
)
!=
0
)
?
string
((
char
*
)
addr
)
:
gb2312_to_utf8
(
"null"
);
}
else
{
temp
=
(
*
((
DWORD
*
)
addr
)
!=
0
)
?
string
((
char
*
)(
*
(
DWORD
*
)
addr
))
:
gb2312_to_utf8
(
"null"
);
}
}
else
if
(
!
key
.
compare
(
"wxId"
))
{
char
wxidbuffer
[
0x100
]
=
{
0
};
sprintf_s
(
wxidbuffer
,
"%s"
,
(
char
*
)
addr
);
if
(
strlen
(
wxidbuffer
)
<
0x6
||
strlen
(
wxidbuffer
)
>
0x14
)
{
//新的微信号 微信ID用地址保存
temp
=
string
((
char
*
)(
*
(
DWORD
*
)
addr
));
}
else
{
temp
=
string
((
char
*
)
addr
);
}
}
else
if
(
!
key
.
compare
(
"Sex"
))
{
int
sex
=
*
(
int
*
)
addr
;
switch
(
sex
)
{
case
1
:
{
temp
=
gb2312_to_utf8
(
"男"
);
break
;
}
case
2
:
{
temp
=
gb2312_to_utf8
(
"女"
);
break
;
}
default:
{
temp
=
gb2312_to_utf8
(
"未知"
);
break
;
}
}
}
else
{
temp
=
addr
!=
0
?
string
((
char
*
)
addr
)
:
gb2312_to_utf8
(
"null"
);
}
jData
[
key
]
=
temp
.
c_str
();
}
wstring
selfinfo
=
utf8_to_unicode
(
jData
.
dump
().
c_str
());
return
selfinfo
;
}
BOOL
isWxLogin
()
{
DWORD
CheckLoginAddr
=
GetWeChatWinBase
()
+
CheckLoginOffset
;
return
*
(
BOOL
*
)
CheckLoginAddr
;
BOOL
isWxLogin
()
{
DWORD
CheckLoginAddr
=
GetWeChatWinBase
()
+
CheckLoginOffset
;
return
*
(
BOOL
*
)
CheckLoginAddr
;
}
/*
...
...
@@ -171,10 +155,12 @@ BOOL isWxLogin() {
* return:void
*/
#ifndef USE_SOCKET
VOID
DeleteSelfInfoCacheRemote
()
{
if
(
ret
.
length
)
{
delete
[]
(
wchar_t
*
)
ret
.
message
;
ZeroMemory
(
&
ret
,
sizeof
(
SelfInfoStruct
));
}
VOID
DeleteSelfInfoCacheRemote
()
{
if
(
ret
.
length
)
{
delete
[](
wchar_t
*
)
ret
.
message
;
ZeroMemory
(
&
ret
,
sizeof
(
SelfInfoStruct
));
}
}
#endif
\ No newline at end of file
#endif
DWeChatRobot/base64/base64.cpp
浏览文件 @
f68111cf
...
...
@@ -8,7 +8,7 @@
Version: 2.rc.08 (release candidate)
Copyright (C) 2004-2017, 2020, 2021 Ren
é
Nyffenegger
Copyright (C) 2004-2017, 2020, 2021 Ren
¨¦
Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
...
...
@@ -28,7 +28,7 @@
3. This notice may not be removed or altered from any source distribution.
Ren
é
Nyffenegger rene.nyffenegger@adp-gmbh.ch
Ren
¨¦
Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
...
...
@@ -182,7 +182,7 @@ template <typename String>
static
std
::
string
decode
(
String
encoded_string
,
bool
remove_linebreaks
)
{
//
// decode(
…)
is templated so that it can be used with String = const std::string&
// decode(
¡
) is templated so that it can be used with String = const std::string&
// or std::string_view (requires at least C++17)
//
...
...
DWeChatRobot/pch.cpp
浏览文件 @
f68111cf
...
...
@@ -87,6 +87,23 @@ string utf8_to_gb2312(const char *strUTF8)
return
strTemp
;
}
string
gb2312_to_utf8
(
const
char
*
strGB2312
)
{
int
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
strGB2312
,
-
1
,
NULL
,
0
);
wchar_t
*
wszGBK
=
new
wchar_t
[
len
+
1
];
memset
(
wszGBK
,
0
,
len
*
2
+
2
);
MultiByteToWideChar
(
CP_ACP
,
0
,
strGB2312
,
-
1
,
wszGBK
,
len
);
len
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
wszGBK
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
char
*
szGBK
=
new
char
[
len
+
1
];
memset
(
szGBK
,
0
,
len
+
1
);
WideCharToMultiByte
(
CP_UTF8
,
0
,
wszGBK
,
-
1
,
szGBK
,
len
,
NULL
,
NULL
);
string
strTemp
(
szGBK
);
delete
[]
szGBK
;
delete
[]
wszGBK
;
return
strTemp
;
}
/*
* 将UTF8编码数据转换为GBK编码
*/
...
...
DWeChatRobot/pch.h
浏览文件 @
f68111cf
...
...
@@ -15,6 +15,7 @@
#include <string>
#include "wxdata.h"
#include "wxapi.h"
#include "base64/base64.h"
#endif //PCH_H
#ifdef USE_SOCKET
...
...
DWeChatRobot/wxapi.h
浏览文件 @
f68111cf
...
...
@@ -39,6 +39,7 @@ BOOL CreateConsole(void);
DWORD
GetWeChatWinBase
();
string
unicode_to_gb2312
(
wchar_t
*
wchar
);
string
utf8_to_gb2312
(
const
char
*
strUTF8
);
string
gb2312_to_utf8
(
const
char
*
strGB2312
);
string
unicode_to_utf8
(
wchar_t
*
wstr
);
wstring
utf8_to_unicode
(
const
char
*
buffer
);
void
HookAnyAddress
(
DWORD
dwHookAddr
,
LPVOID
dwJmpAddress
,
char
*
originalRecieveCode
);
...
...
DWeChatRobot/wxdata.h
浏览文件 @
f68111cf
...
...
@@ -65,6 +65,7 @@ struct ReceiveMsgStruct
wstring
message
;
wstring
filepath
;
wstring
time
;
wstring
extrainfo
;
~
ReceiveMsgStruct
()
{
}
...
...
DWeChatRobot/wxsocket.cpp
浏览文件 @
f68111cf
...
...
@@ -28,7 +28,7 @@ json methods = {{"GET", HTTP_METHOD_GET}, {"POST", HTTP_METHOD_POST}};
#endif
#define STOI_S(str) (is_digit_number(str) ? stoi(str) : 0)
#define POST_PARAM(jData, key) utf8_to_unicode(
string(jData[key]
).c_str())
#define POST_PARAM(jData, key) utf8_to_unicode(
jData[key].get<string>(
).c_str())
#define GET_PARAM(hm, name) getMgVarW(hm, name)
bool
is_digit_number
(
string
str
)
...
...
@@ -94,11 +94,11 @@ static int get_http_param_int(mg_http_message *hm, json jData, string key, int m
{
try
{
result
=
jData
[
key
];
result
=
jData
[
key
]
.
get
<
int
>
()
;
}
catch
(
json
::
exception
)
{
result
=
STOI_S
(
(
string
)
jData
[
key
]
);
result
=
STOI_S
(
jData
[
key
].
get
<
string
>
()
);
}
break
;
}
...
...
@@ -153,8 +153,13 @@ void request_event(mg_http_message *hm, string &ret)
}
case
WECHAT_GET_SELF_INFO
:
{
wstring
self_info
=
GetSelfInfo
();
json
ret_data
=
{{
"self_info"
,
unicode_to_utf8
(
WS2LW
(
self_info
))},
{
"result"
,
"OK"
}};
json
ret_data
;
string
self_info
=
unicode_to_utf8
(
WS2LW
(
GetSelfInfo
()));
json
j_info
=
json
::
parse
(
self_info
.
c_str
(),
self_info
.
c_str
()
+
self_info
.
size
(),
nullptr
,
false
);
if
(
j_info
.
is_discarded
()
!=
true
)
ret_data
=
{{
"data"
,
j_info
},
{
"result"
,
"OK"
}};
else
ret_data
=
{{
"data"
,
self_info
},
{
"result"
,
"OK"
}};
ret
=
ret_data
.
dump
();
break
;
}
...
...
@@ -308,8 +313,13 @@ void request_event(mg_http_message *hm, string &ret)
case
WECHAT_CONTACT_SEARCH_BY_CACHE
:
{
wstring
wxid
=
get_http_param_str
(
hm
,
jData
,
"wxid"
,
method
);
wstring
userinfo
=
GetUserInfoByWxId
(
wxid
);
json
ret_data
=
{{
"userinfo"
,
unicode_to_utf8
(
WS2LW
(
userinfo
))},
{
"result"
,
"OK"
}};
string
userinfo
=
unicode_to_utf8
(
WS2LW
(
GetUserInfoByWxId
(
wxid
)));
json
ret_data
;
json
j_info
=
json
::
parse
(
userinfo
.
c_str
(),
userinfo
.
c_str
()
+
userinfo
.
size
(),
nullptr
,
false
);
if
(
j_info
.
is_discarded
()
!=
true
)
ret_data
=
{{
"data"
,
j_info
},
{
"result"
,
"OK"
}};
else
ret_data
=
{{
"data"
,
userinfo
},
{
"result"
,
"OK"
}};
ret
=
ret_data
.
dump
();
break
;
}
...
...
DWeChatRobot/wxsocketapi.h
浏览文件 @
f68111cf
...
...
@@ -3,7 +3,6 @@
#include <signal.h>
// mongoose: https://github.com/cesanta/mongoose
#include "mongoose/mongoose.h"
#include "base64/base64.h"
#pragma comment(lib, "ws2_32.lib")
extern
"C"
__declspec
(
dllexport
)
void
http_start
(
int
port
);
extern
"C"
__declspec
(
dllexport
)
int
http_close
();
...
...
Python/test.py
浏览文件 @
f68111cf
...
...
@@ -88,5 +88,5 @@ if __name__ == '__main__':
wx
=
WeChatRobot
(
pid_list
[
0
])
wx
.
StartService
()
wx
.
StartReceiveMessage
()
wxRobot
.
start_socket_server
(
)
wxRobot
.
register_msg_event
(
pid_list
[
0
]
)
wx
.
StopService
()
Python/wxRobot.py
浏览文件 @
f68111cf
...
...
@@ -6,9 +6,10 @@ Created on Thu Feb 24 16:19:48 2022
"""
# Before use,execute `CWeChatRobot.exe /regserver` in cmd by admin user
import
ast
import
os
import
ctypes
import
json
import
base64
import
ctypes.wintypes
import
socketserver
import
threading
...
...
@@ -51,6 +52,8 @@ class WeChatEventSink:
"""
def
OnGetMessageEvent
(
self
,
msg
):
msg
=
json
.
loads
(
msg
)
msg
[
'extrainfo'
]
=
base64
.
b64decode
(
msg
[
'extrainfo'
])
print
(
msg
)
...
...
@@ -58,65 +61,41 @@ class ReceiveMsgBaseServer(socketserver.BaseRequestHandler):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
class
ReceiveMsgStruct
(
ctypes
.
Structure
):
_fields_
=
[(
"pid"
,
ctypes
.
wintypes
.
DWORD
),
(
"type"
,
ctypes
.
wintypes
.
DWORD
),
(
"isSendMsg"
,
ctypes
.
wintypes
.
DWORD
),
(
"msgid"
,
ctypes
.
c_ulonglong
),
(
"sender"
,
ctypes
.
c_wchar
*
80
),
(
"wxid"
,
ctypes
.
c_wchar
*
80
),
(
"message"
,
ctypes
.
c_wchar
*
0x1000B
),
(
"filepath"
,
ctypes
.
c_wchar
*
260
),
(
"time"
,
ctypes
.
c_wchar
*
30
)
]
def
handle
(
self
):
conn
=
self
.
request
comtypes
.
CoInitialize
()
while
True
:
try
:
ptr_data
=
conn
.
recv
(
1024
)
try
:
if
ptr_data
.
decode
()
==
'bye'
:
break
except
UnicodeDecodeError
:
pass
while
len
(
ptr_data
)
<
ctypes
.
sizeof
(
self
.
ReceiveMsgStruct
):
ptr_data
=
b
""
while
True
:
data
=
conn
.
recv
(
1024
)
if
len
(
data
)
==
0
:
break
ptr_data
+=
data
if
ptr_data
:
ptr_receive_msg
=
ctypes
.
cast
(
ptr_data
,
ctypes
.
POINTER
(
self
.
ReceiveMsgStruct
))
ReceiveMsgBaseServer
.
msg_callback
(
ptr_receive_msg
.
contents
)
response
=
"200 OK"
conn
.
sendall
(
response
.
encode
())
if
len
(
data
)
==
0
or
data
[
-
1
]
==
0xA
:
break
msg
=
json
.
loads
(
ptr_data
.
decode
(
'utf-8'
))
ReceiveMsgBaseServer
.
msg_callback
(
msg
)
except
OSError
:
break
except
Exception
as
e
:
p
rint
(
e
)
conn
.
sendall
(
"200 OK"
.
encode
())
except
json
.
JSONDecodeError
:
p
ass
conn
.
sendall
(
"200 OK"
.
encode
())
conn
.
close
()
comtypes
.
CoUninitialize
()
@
staticmethod
def
msg_callback
(
data
):
def
msg_callback
(
msg
):
msg
[
'extrainfo'
]
=
base64
.
b64decode
(
msg
[
'extrainfo'
])
# 主线程中已经注入,此处禁止调用StartService和StopService
msg
=
{
'pid'
:
data
.
pid
,
'time'
:
data
.
time
,
'type'
:
data
.
type
,
'isSendMsg'
:
data
.
isSendMsg
,
'msgid'
:
data
.
msgid
,
'wxid'
:
data
.
wxid
,
'sendto'
if
data
.
isSendMsg
else
'from'
:
data
.
sender
,
'message'
:
data
.
message
}
robot
=
comtypes
.
client
.
CreateObject
(
"WeChatRobot.CWeChatRobot"
)
event
=
comtypes
.
client
.
CreateObject
(
"WeChatRobot.RobotEvent"
)
wx
=
WeChatRobot
(
data
.
pid
,
robot
,
event
)
userinfo
=
wx
.
GetWxUserInfo
(
data
.
wxid
)
wx
=
WeChatRobot
(
msg
[
'pid'
]
,
robot
,
event
)
userinfo
=
wx
.
GetWxUserInfo
(
msg
[
'wxid'
]
)
msg
[
'alias'
]
=
userinfo
[
'wxNumber'
]
if
data
.
isSendMsg
==
0
:
if
'@chatroom'
in
data
.
sender
:
chatroom_info
=
wx
.
GetWxUserInfo
(
data
.
sender
)
if
msg
[
'isSendMsg'
]
==
0
:
if
'@chatroom'
in
msg
[
'sender'
]
:
chatroom_info
=
wx
.
GetWxUserInfo
(
msg
[
'sender'
]
)
msg
[
'chatroom_name'
]
=
chatroom_info
[
'wxNickName'
]
msg
[
'nickname'
]
=
wx
.
GetChatRoomMemberNickname
(
data
.
sender
,
data
.
wxid
)
msg
[
'nickname'
]
=
wx
.
GetChatRoomMemberNickname
(
msg
[
'sender'
],
msg
[
'wxid'
]
)
else
:
msg
[
'nickname'
]
=
userinfo
[
'wxNickName'
]
# TODO: 在这里写额外的消息处理逻辑
...
...
@@ -330,12 +309,8 @@ class WeChatRobot:
调用成功返回个人信息,否则返回空字典.
"""
self_info
=
self
.
robot
.
CGetSelfInfo
(
self
.
pid
).
replace
(
'
\n
'
,
'
\\
n'
)
try
:
self_info
=
ast
.
literal_eval
(
self_info
)
except
SyntaxError
:
return
{}
return
self_info
self_info
=
self
.
robot
.
CGetSelfInfo
(
self
.
pid
)
return
json
.
loads
(
self_info
)
def
StopService
(
self
)
->
int
:
"""
...
...
@@ -519,8 +494,8 @@ class WeChatRobot:
联系人信息.
"""
userinfo
=
self
.
robot
.
CGetWxUserInfo
(
self
.
pid
,
wxid
)
.
replace
(
'
\n
'
,
'
\\
n'
)
return
ast
.
literal_eval
(
userinfo
)
userinfo
=
self
.
robot
.
CGetWxUserInfo
(
self
.
pid
,
wxid
)
return
json
.
loads
(
userinfo
)
def
GetChatRoomMembers
(
self
,
chatroom_id
:
str
)
->
dict
or
None
:
"""
...
...
README.md
浏览文件 @
f68111cf
...
...
@@ -49,11 +49,11 @@ CWeChatRobot.exe /unregserver
```
# 调用
**Python:**
参考
[
wxRobot.py
](
/Python/wxRobot.py
)
**C#:**
参考
[
ComWechatRobotCsharp
](
https://github.com/RingoStudio/ComWechatRobotCsharp
)
,感谢@RingoStudio 的贡献
**易语言:**
参考
[
ESDK
](
/ESDK
)
,感谢@lovezm 的贡献
参考
[
wxRobot.py
](
/Python/wxRobot.py
)
**C#:**
参考
[
ComWechatRobotCsharp
](
https://github.com/RingoStudio/ComWechatRobotCsharp
)
,感谢@RingoStudio 的贡献
**易语言:**
参考
[
ESDK
](
/ESDK
)
,感谢@lovezm 的贡献
# 更多功能
1.
尝试添加issue中的功能
...
...
@@ -119,11 +119,13 @@ CWeChatRobot.exe /unregserver
## 2022.08.13
1.
现在消息HOOK内容包含消息ID
2.
完成发送消息的http接口,可参考
[
wxDriver.py
](
/Release/socket/wxDriver.py
)
,其他接口还需要一点时间
3.
新增项目配置文件,感谢@amchii 提供的方法
3.
新增项目配置文件,感谢@amchii 提供的方法
## 2022.08.21
1.
所有功能http接口封装完成,可接受get、post请求
2.
提供http接口调用示例,参考
[
wxDriver.py
](
/Release/socket/wxDriver.py
)
1.
所有功能http接口封装完成,可接受get、post请求
2.
提供http接口调用示例,参考
[
wxDriver.py
](
/Release/socket/wxDriver.py
)
## 2022.08.25
1.
接收消息格式修改为json,现在也可以获取到扩展信息,可从扩展信息中获取到文件保存路径或被艾特人wxid
2.
优化获取个人信息,获取好友信息接口
# 打赏作者
请给作者一个star,感谢感谢
...
...
Release/DWeChatRobot.dll
浏览文件 @
f68111cf
无法预览此类型文件
Release/socket/SWeChatRobot.dll
浏览文件 @
f68111cf
无法预览此类型文件
Release/socket/wxDriver.py
浏览文件 @
f68111cf
...
...
@@ -3,6 +3,7 @@ import json
import
copy
import
threading
import
requests
import
base64
import
socketserver
if
ctypes
.
sizeof
(
ctypes
.
c_void_p
)
==
ctypes
.
sizeof
(
ctypes
.
c_ulonglong
):
...
...
@@ -190,47 +191,29 @@ class ReceiveMsgSocketServer(socketserver.BaseRequestHandler):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
class
ReceiveMsgStruct
(
ctypes
.
Structure
):
_fields_
=
[(
"pid"
,
ctypes
.
wintypes
.
DWORD
),
(
"type"
,
ctypes
.
wintypes
.
DWORD
),
(
"isSendMsg"
,
ctypes
.
wintypes
.
DWORD
),
(
"msgid"
,
ctypes
.
c_ulonglong
),
(
"sender"
,
ctypes
.
c_wchar
*
80
),
(
"wxid"
,
ctypes
.
c_wchar
*
80
),
(
"message"
,
ctypes
.
c_wchar
*
0x1000B
),
(
"filepath"
,
ctypes
.
c_wchar
*
260
),
(
"time"
,
ctypes
.
c_wchar
*
30
)
]
def
handle
(
self
):
conn
=
self
.
request
while
True
:
try
:
ptr_data
=
conn
.
recv
(
1024
)
try
:
if
ptr_data
.
decode
()
==
'bye'
:
break
except
UnicodeDecodeError
:
pass
while
len
(
ptr_data
)
<
ctypes
.
sizeof
(
self
.
ReceiveMsgStruct
):
ptr_data
=
b
""
while
True
:
data
=
conn
.
recv
(
1024
)
if
len
(
data
)
==
0
:
break
ptr_data
+=
data
if
ptr_data
:
ptr_receive_msg
=
ctypes
.
cast
(
ptr_data
,
ctypes
.
POINTER
(
self
.
ReceiveMsgStruct
))
ReceiveMsgSocketServer
.
msg_callback
(
ptr_receive_msg
.
contents
)
if
len
(
data
)
==
0
or
data
[
-
1
]
==
0xA
:
break
msg
=
json
.
loads
(
ptr_data
.
decode
(
'utf-8'
))
ReceiveMsgSocketServer
.
msg_callback
(
msg
)
except
OSError
:
break
except
:
except
json
.
JSONDecodeError
:
pass
conn
.
sendall
(
"200 OK"
.
encode
())
conn
.
close
()
@
staticmethod
def
msg_callback
(
data
):
msg
=
{
'pid'
:
data
.
pid
,
'time'
:
data
.
time
,
'type'
:
data
.
type
,
'isSendMsg'
:
data
.
isSendMsg
,
'msgid'
:
data
.
msgid
,
'wxid'
:
data
.
wxid
,
'message'
:
data
.
message
,
'sendto'
if
data
.
isSendMsg
else
'from'
:
data
.
sender
}
def
msg_callback
(
msg
):
# 附加信息是protobuf格式,需要自行处理
msg
[
'extrainfo'
]
=
base64
.
b64decode
(
msg
[
'extrainfo'
])
# TODO: 在这里写额外的消息处理逻辑
print
(
msg
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录