Merge pull request #177 from wangxingsheng/main

--user=wxs 增加转发消息功能,可打包成jar直接运行,详情见README.md
This commit is contained in:
ttttupup 2023-06-07 17:11:40 +08:00 committed by GitHub
commit 66ea9d5428
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 217 additions and 35 deletions

29
weChatHook-java/README.md Normal file
View File

@ -0,0 +1,29 @@
#maven打包
```aidl
进入weChatHook-java项目根目录执行如下命令进行打包
mvn package
打包完成后在target目录下找到
weChatHook-java-1.0-jar-with-dependencies.jar
文件就可以直接启动了
```
#启动命令
####命令参数说明
###port:监听的端口 默认端口19077
###hookApi消息转发的接口 为空不转发
```aidl
java -jar .\weChatHook-java-1.0-jar-with-dependencies.jar --port=9999 --hookApi=http://localhost:29099/api/demo/msg
```
#java接收hook消息示例
```aidl
@RequestMapping("/api/demo")
public class DemoController {
@PostMapping("/msg")
public void getMsg(String msg){
JSONObject jsonObject = JSON.parseObject(msg);
jsonObject.forEach((k,v)->{
System.out.println(k+":"+v);
});
}
```

View File

@ -6,7 +6,7 @@
<groupId>org.example</groupId> <groupId>org.example</groupId>
<artifactId>weChatHook-java</artifactId> <artifactId>weChatHook-java</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0</version>
<properties> <properties>
<maven.compiler.source>8</maven.compiler.source> <maven.compiler.source>8</maven.compiler.source>
@ -38,5 +38,40 @@
<artifactId>netty-all</artifactId> <artifactId>netty-all</artifactId>
<version>4.1.51.Final</version> <version>4.1.51.Final</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.service.WeChatHookNettyServer</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -606,4 +606,14 @@ public class WeChatHookClient {
return JSON.parseObject(body); return JSON.parseObject(body);
} }
@SneakyThrows
public static JSONObject hook(String url, String json) {
String body = Jsoup.connect(url)
.data("msg",json)
.method(Connection.Method.POST)
.timeout(1000)
.execute().body();
return JSON.parseObject(body);
}
} }

View File

@ -17,11 +17,11 @@ import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.internal.StringUtil;
import java.io.BufferedReader; import java.io.*;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.*;
/** /**
* @PACKAGE_NAME: com.example.service * @PACKAGE_NAME: com.example.service
@ -34,33 +34,53 @@ public class WeChatHookNettyServer {
/** /**
* 直接启动main方法 * 直接启动main方法
*
* @param args * @param args
*/ */
public static void main(String[] args) { public static void main(String[] args) {
Integer hookPort = 19099;
Integer serverPort = 19077;
String hookApi = null;
for (String arg : args) {
System.out.println(arg);
if (arg.startsWith("--port")) {
serverPort = Integer.valueOf(arg.split("=")[1]);
}
if (arg.startsWith("--hookApi")) {
hookApi = arg.split("=")[1];
}
}
//1注入 //1注入
inject(); inject();
//2开启hook //2开启hook
try { try {
JSONObject result = WeChatHookClient.hook_msg("127.0.0.1", hookPort.toString()); JSONObject result = WeChatHookClient.hook_msg("127.0.0.1", serverPort.toString());
} catch (Exception e) { } catch (Exception e) {
System.out.println("hook 失败,请检查微信是否登录"); System.out.println("hook 失败,请检查微信是否登录");
return; return;
} }
//3启动服务 //3启动服务
start(hookPort); start(serverPort, hookApi);
} }
/** /**
* 执行注入命令 * 执行注入命令
*/ */
public static void inject() { public static void inject() {
ClassLoader classLoader = WeChatHookNettyServer.class.getClassLoader(); //
//获取ConsoleInject 文件路径 File consoleInjectTemp = null;
String ConsoleInject = classLoader.getResource("ConsoleInject.exe").getPath().replaceFirst("/", ""); File wxhelperTemp = null;
//获取 wxhelper.dll 文件路径 try {
String wxhelper = classLoader.getResource("wxhelper.dll").getPath().replaceFirst("/", ""); consoleInjectTemp = createTempFile("ConsoleInject", ".exe");
wxhelperTemp = createTempFile("wxhelper", ".dll");
String ConsoleInject = consoleInjectTemp.getAbsolutePath();
String wxhelper = wxhelperTemp.getAbsolutePath();
//ConsoleInject.exe -i WeChat.exe -p C:\Users\DELL\Desktop\injector\wxhelper.dll //ConsoleInject.exe -i WeChat.exe -p C:\Users\DELL\Desktop\injector\wxhelper.dll
String command = ConsoleInject + " -i WeChat.exe -p " + wxhelper; String command = ConsoleInject + " -i WeChat.exe -p " + wxhelper;
@ -78,12 +98,61 @@ public class WeChatHookNettyServer {
} }
} catch (Exception e) { } catch (Exception e) {
System.out.println(e.getMessage() + "请确认微信已登录"); System.out.println(e.getMessage() + "请确认微信已登录");
} }
//执行注入命令 //执行注入命令
excuteShell(command); excuteShell(command);
} while (retryCount > 0); } while (retryCount >= 0);
} catch (Exception e) {
e.printStackTrace();
return;
} finally {
////如果不为空删除临时文件
if (Objects.nonNull(consoleInjectTemp)) {
consoleInjectTemp.delete();
}
//如果不为空删除临时文件
if (Objects.nonNull(wxhelperTemp)) {
wxhelperTemp.delete();
}
}
}
/**
* 创建临时文件
*
* @param fileName
* @param suffix
* @return
*/
private static File createTempFile(String fileName, String suffix) {
InputStream inputStream = WeChatHookNettyServer.class.getResourceAsStream("/" + fileName + suffix);
FileOutputStream outputStream = null;
try {
File tempFile = File.createTempFile(fileName, suffix);
outputStream = new FileOutputStream(tempFile);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
return tempFile;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (Objects.nonNull(outputStream)) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
} }
/** /**
@ -91,7 +160,7 @@ public class WeChatHookNettyServer {
* *
* @param port * @param port
*/ */
public static void start(Integer port) { public static void start(Integer port, String hookApi) {
NioEventLoopGroup bossGroup = new NioEventLoopGroup(); NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup(); NioEventLoopGroup workerGroup = new NioEventLoopGroup();
try { try {
@ -102,10 +171,10 @@ public class WeChatHookNettyServer {
.childHandler(new ChannelInitializer<SocketChannel>() { .childHandler(new ChannelInitializer<SocketChannel>() {
@Override @Override
protected void initChannel(SocketChannel ch) { protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024 * 100, Delimiters.lineDelimiter()));
ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8)); ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8)); ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new ReceiveMsgHandler()); ch.pipeline().addLast(new ReceiveMsgHandler(hookApi));
} }
}) })
.option(ChannelOption.SO_BACKLOG, 128) .option(ChannelOption.SO_BACKLOG, 128)
@ -124,12 +193,52 @@ public class WeChatHookNettyServer {
private static class ReceiveMsgHandler extends SimpleChannelInboundHandler<String> { private static class ReceiveMsgHandler extends SimpleChannelInboundHandler<String> {
private String hookApi;
public ReceiveMsgHandler(String hookApi) {
this.hookApi = hookApi;
}
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) { protected void channelRead0(ChannelHandlerContext ctx, String msg) {
JSON.parseObject(msg).forEach((k, v) -> { JSONObject jsonObject = JSON.parseObject(msg);
jsonObject.forEach((k, v) -> {
System.out.println(k + " = " + v); System.out.println(k + " = " + v);
}); });
System.out.println("----------end----------");
String fromGroup = jsonObject.getString("fromGroup");
String fromUser = jsonObject.getString("fromUser");
String from;
if (fromGroup.equals(fromUser)) {
JSONObject fromGroupJson = WeChatHookClient.query_nickname(jsonObject.getString("fromGroup"));
String groupNname = fromGroupJson.getString("name");
from = "消息来自:" + groupNname;
jsonObject.put("fromUserName", groupNname);
} else {
JSONObject fromGroupJson = WeChatHookClient.query_nickname(jsonObject.getString("fromGroup"));
String groupNname = fromGroupJson.getString("name");
JSONObject fromUserJson = WeChatHookClient.query_nickname(jsonObject.getString("fromUser"));
String fromUserName = fromUserJson.getString("name");
jsonObject.put("fromUserName", fromUserName);
from = "消息来自:" + groupNname + "->" + fromUserName;
}
System.out.println("----------" + from + "----------");
//消息转发
if (StringUtil.isNullOrEmpty(hookApi)) {
return;
}
//检查api接口是否是通的
//转发消息
try {
WeChatHookClient.hook(hookApi, msg);
} catch (Exception e) {
//请检查hookApi服务是否正常
System.err.println("--》消息转发失败请检查hookApi服务是否正常");
}
} }
@Override @Override
@ -160,5 +269,4 @@ public class WeChatHookNettyServer {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }