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