diff --git a/weChatHook-java/.idea/.gitignore b/weChatHook-java/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/weChatHook-java/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/weChatHook-java/.idea/compiler.xml b/weChatHook-java/.idea/compiler.xml new file mode 100644 index 0000000..0264bce --- /dev/null +++ b/weChatHook-java/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/weChatHook-java/.idea/inspectionProfiles/Project_Default.xml b/weChatHook-java/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..6560a98 --- /dev/null +++ b/weChatHook-java/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,36 @@ + + + + \ No newline at end of file diff --git a/weChatHook-java/.idea/jarRepositories.xml b/weChatHook-java/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/weChatHook-java/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/weChatHook-java/.idea/misc.xml b/weChatHook-java/.idea/misc.xml new file mode 100644 index 0000000..132404b --- /dev/null +++ b/weChatHook-java/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/weChatHook-java/pom.xml b/weChatHook-java/pom.xml new file mode 100644 index 0000000..abda013 --- /dev/null +++ b/weChatHook-java/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + org.example + weChatHook-java + 1.0-SNAPSHOT + + + 8 + 8 + + + + + org.jsoup + jsoup + 1.14.3 + + + + com.alibaba + fastjson + 1.2.83 + + + + org.projectlombok + lombok + 1.18.24 + + + + + io.netty + netty-all + 4.1.51.Final + + + \ No newline at end of file diff --git a/weChatHook-java/src/main/java/com/example/client/WeChatHookClient.java b/weChatHook-java/src/main/java/com/example/client/WeChatHookClient.java new file mode 100644 index 0000000..dc187d7 --- /dev/null +++ b/weChatHook-java/src/main/java/com/example/client/WeChatHookClient.java @@ -0,0 +1,609 @@ +package com.example.client; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.SneakyThrows; +import org.jsoup.Connection; +import org.jsoup.Jsoup; + +import java.util.HashMap; +import java.util.Map; + +/** + * @PACKAGE_NAME: com.example.client + * @NAME: WeChatHookClient + * @AUTHOR: wxs + * @DATE: 2023/5/31 15:08 + * @PROJECT_NAME: WeChatHook-java + **/ +public class WeChatHookClient { + + private static final String apiPath = "http://127.0.0.1:19088/api/"; + + public static void main(String[] args) { + System.out.println(check_login()); + } + + /** + * 检查是否登录 + * + * @return + */ + public static JSONObject check_login() { + String url = apiPath + "?type=0"; + JSONObject response = post(url, null); + return response; + } + + /** + * 登录用户信息 + * + * @return + */ + public static JSONObject user_info() { + String url = apiPath + "?type=8"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 发送文本 + * + * @param wxid + * @param msg + * @return + */ + public static JSONObject send_text(String wxid, String msg) { + String url = apiPath + "?type=2"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + map.put("msg", msg); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 发送@消息 + * + * @param chatRoomId + * @param wxids notify@all + * @param msg + * @return + */ + public static JSONObject send_at(String chatRoomId, String wxids, String msg) { + String url = apiPath + "?type=3"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("wxids", wxids); + map.put("msg", msg); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 发送图片 + * + * @param wxid + * @param imagePath C:/Users/ww/Downloads/素材图片 (4).jpg + * @return + */ + public static JSONObject send_img(String wxid, String imagePath) { + String url = apiPath + "?type=5"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + map.put("imagePath", imagePath); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 发送文件 + * + * @param wxid + * @param filePath C:/test.txt + * @return + */ + public static JSONObject send_file(String wxid, String filePath) { + String url = apiPath + "?type=6"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + map.put("filePath", filePath); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * hook 消息 + * + * @param ip + * @param port + * @return + */ + public static JSONObject hook_msg(String ip, String port) { + String url = apiPath + "?type=9"; + Map map = new HashMap<>(); + map.put("ip", ip); + map.put("port", port); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 取消消息hook + * + * @return + */ + public static JSONObject unhook_msg() { + String url = apiPath + "?type=10"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * hook 图片 + * + * @return + */ + public static JSONObject hook_img(String imgDir) { + String url = apiPath + "?type=11"; + Map map = new HashMap<>(); + map.put("imgDir", imgDir); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 取消hook 图片 + * + * @param imgDir C:\img + * @return + */ + public static JSONObject unhook_img(String imgDir) { + String url = apiPath + "?type=12"; + Map map = new HashMap<>(); + map.put("imgDir", imgDir); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * hook 语音 + * + * @return + */ + public static JSONObject hook_voice(Long msgId) { + String url = apiPath + "?type=56"; + Map map = new HashMap<>(); + map.put("msgId", msgId); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 取消hook 语音 + * + * @return + */ + public static JSONObject unhook_voice() { + String url = apiPath + "?type=14"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 删除好友 + * + * @param wxid + * @return + */ + public static JSONObject del_friend(String wxid) { + String url = apiPath + "?type=17"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 网络搜素用户 + * + * @return + */ + public static JSONObject search_friend(String keyword) { + String url = apiPath + "?type=19"; + Map map = new HashMap<>(); + map.put("keyword", keyword); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 添加好友 + * + * @param wxid + * @return + */ + public static JSONObject add_friend(String wxid) { + String url = apiPath + "?type=20"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 群成员 + * + * @param chatRoomId + * @return + */ + public static JSONObject fetch_chat_room_members(String chatRoomId) { + String url = apiPath + "?type=25"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 群成员昵称 + * + * @param chatRoomId + * @param memberId + * @return + */ + public static JSONObject get_member_nickname(String chatRoomId, String memberId) { + String url = apiPath + "?type=26"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("memberId", memberId); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 删除群成员 + * + * @param chatRoomId + * @param memberIds + * @return + */ + public static JSONObject del_member(String chatRoomId, String memberIds) { + String url = apiPath + "?type=27"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("memberIds", memberIds); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 增加群成员 + * + * @param chatRoomId + * @param memberIds + * @return + */ + public static JSONObject add_member(String chatRoomId, String memberIds) { + String url = apiPath + "?type=28"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("memberIds", memberIds); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 修改群昵称 + * + * @param chatRoomId + * @param wxid + * @param nickName + * @return + */ + public static JSONObject modify_room_name(String chatRoomId, String wxid, String nickName) { + String url = apiPath + "?type=31"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("wxid", wxid); + map.put("nickName", nickName); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 获取sqlite3的操作句柄 + * + * @return + */ + public static JSONObject get_db_handlers() { + String url = apiPath + "?type=32"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 查询数据库 + * + * @param dbHandle + * @param sql + * @return + */ + public static JSONObject query_db_by_sql(String dbHandle, String sql) { + String url = apiPath + "?type=34"; + Map map = new HashMap<>(); + map.put("dbHandle", dbHandle); + map.put("sql", sql); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * hook 日志 + * + * @return + */ + public static JSONObject hook_log() { + String url = apiPath + "?type=36"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 取消hook日志 + * + * @return + */ + public static JSONObject unhook_log() { + String url = apiPath + "?type=37"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 转发消息 + * + * @param wxid + * @param msgid + * @return + */ + public static JSONObject forward(String wxid, String msgid) { + String url = apiPath + "?type=40"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + map.put("msgid", msgid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 退出登录 + * + * @return + */ + public static JSONObject logout() { + String url = apiPath + "?type=44"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 确认收款 + * + * @param wxid + * @param transcationId + * @param transferId + * @return + */ + public static JSONObject confirm_receipt(String wxid, String transcationId, String transferId) { + String url = apiPath + "?type=45"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + map.put("transcationId", transcationId); + map.put("transferId", transferId); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 好友列表 + * + * @return + */ + public static JSONObject contact_list() { + String url = apiPath + "?type=46"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 群详情 + * + * @param chatRoomId + * @return + */ + public static JSONObject room_detail(String chatRoomId) { + String url = apiPath + "?type=47"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * ocr提取文字 + * + * @param imagePath + * @return + */ + public static JSONObject ocr(String imagePath) { + String url = apiPath + "?type=49"; + Map map = new HashMap<>(); + map.put("imagePath", imagePath); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 拍一拍 + * + * @param chatRoomId + * @param wxid + * @return + */ + public static JSONObject pat(String chatRoomId, String wxid) { + String url = apiPath + "?type=50"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("wxid", wxid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 消息置顶 + * + * @param chatRoomId + * @param msgid + * @return + */ + public static JSONObject top_msg(String chatRoomId, Long msgid) { + String url = apiPath + "?type=51"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("msgid", msgid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 取消置顶 + * + * @param chatRoomId + * @param msgid + * @return + */ + public static JSONObject close_top_msg(String chatRoomId, Long msgid) { + String url = apiPath + "?type=52"; + Map map = new HashMap<>(); + map.put("chatRoomId", chatRoomId); + map.put("msgid", msgid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 朋友圈首页 + * + * @return + */ + public static JSONObject sns_first() { + String url = apiPath + "?type=53"; + JSONObject response = post(url, null); + System.out.println(response); + return response; + } + + /** + * 朋友圈下一页 + * + * @param snsId + * @return + */ + public static JSONObject sns_next(String snsId) { + String url = apiPath + "?type=54"; + Map map = new HashMap<>(); + map.put("snsId", snsId); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 查询联系人或群名称 + * + * @param wxid 微信id + * @return + */ + public static JSONObject query_nickname(String wxid) { + String url = apiPath + "?type=55"; + Map map = new HashMap<>(); + map.put("id", wxid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 下载消息附件 + * + * @param msgId + * @return + */ + public static JSONObject download_msg_attach(Long msgId) { + String url = apiPath + "?type=56"; + Map map = new HashMap<>(); + map.put("msgId", msgId); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + /** + * 获取群/群成员信息 + * + * @param wxid + * @return + */ + public static JSONObject get_member_info(String wxid) { + String url = apiPath + "?type=57"; + Map map = new HashMap<>(); + map.put("wxid", wxid); + JSONObject response = post(url, JSON.toJSONString(map)); + System.out.println(response); + return response; + } + + @SneakyThrows + public static JSONObject post(String url, String json) { + String body = Jsoup.connect(url) + .method(Connection.Method.POST) + .header("Content-Type", "application/json") + .requestBody(json) + .execute().body(); + return JSON.parseObject(body); + } + +} diff --git a/weChatHook-java/src/main/java/com/example/service/WeChatHookNettyServer.java b/weChatHook-java/src/main/java/com/example/service/WeChatHookNettyServer.java new file mode 100644 index 0000000..00e1459 --- /dev/null +++ b/weChatHook-java/src/main/java/com/example/service/WeChatHookNettyServer.java @@ -0,0 +1,164 @@ +package com.example.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.example.client.WeChatHookClient; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.DelimiterBasedFrameDecoder; +import io.netty.handler.codec.Delimiters; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import io.netty.util.CharsetUtil; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; + +/** + * @PACKAGE_NAME: com.example.service + * @NAME: WeChatHookNettyServer + * @AUTHOR: wxs + * @DATE: 2023/5/31 15:07 + * @PROJECT_NAME: WeChatHook-java + **/ +public class WeChatHookNettyServer { + + /** + * 直接启动main方法 + * @param args + */ + public static void main(String[] args) { + Integer hookPort = 19099; + //1、注入 + inject(); + + //2、开启hook + try { + JSONObject result = WeChatHookClient.hook_msg("127.0.0.1", hookPort.toString()); + } catch (Exception e) { + System.out.println("hook 失败,请检查微信是否登录"); + return; + } + //3、启动服务 + start(hookPort); + } + + /** + * 执行注入命令 + */ + public static void inject() { + ClassLoader classLoader = WeChatHookNettyServer.class.getClassLoader(); + //获取ConsoleInject 文件路径 + String ConsoleInject = classLoader.getResource("ConsoleInject.exe").getPath().replaceFirst("/", ""); + //获取 wxhelper.dll 文件路径 + String wxhelper = classLoader.getResource("wxhelper.dll").getPath().replaceFirst("/", ""); + + //ConsoleInject.exe -i WeChat.exe -p C:\Users\DELL\Desktop\injector\wxhelper.dll + String command = ConsoleInject + " -i WeChat.exe -p " + wxhelper; + + //重试3次 + int retryCount = 3; + do { + retryCount--; + try { + //检查登录状态 + JSONObject jsonObject = WeChatHookClient.check_login(); + //如果已登录不需要注入 + if (jsonObject.getInteger("code").equals(1)) { + return; + } + } catch (Exception e) { + System.out.println(e.getMessage() + "请确认微信已登录"); + + } + //执行注入命令 + excuteShell(command); + + } while (retryCount > 0); + } + + /** + * 启动服务 + * + * @param port + */ + public static void start(Integer port) { + NioEventLoopGroup bossGroup = new NioEventLoopGroup(); + NioEventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap serverBootstrap = new ServerBootstrap(); + serverBootstrap.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .localAddress(new InetSocketAddress(port)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) { + ch.pipeline().addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); + ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8)); + ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8)); + ch.pipeline().addLast(new ReceiveMsgHandler()); + } + }) + .option(ChannelOption.SO_BACKLOG, 128) + .childOption(ChannelOption.SO_KEEPALIVE, true); + + Channel channel = serverBootstrap.bind().sync().channel(); + System.out.println("服务启动成功 端口号 " + port); + channel.closeFuture().sync(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + } + + private static class ReceiveMsgHandler extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext ctx, String msg) { + JSON.parseObject(msg).forEach((k, v) -> { + System.out.println(k + " = " + v); + }); + System.out.println("----------end----------"); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + ctx.close(); + } + + } + + /** + * 执行shell 命令 + * + * @param command + */ + public static void excuteShell(String command) { + try { + Process process = Runtime.getRuntime().exec(command); + + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + int exitCode = process.waitFor(); + System.out.println("Exit Code: " + exitCode); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/weChatHook-java/src/main/resources/ConsoleInject.exe b/weChatHook-java/src/main/resources/ConsoleInject.exe new file mode 100644 index 0000000..ed0fe3f Binary files /dev/null and b/weChatHook-java/src/main/resources/ConsoleInject.exe differ diff --git a/weChatHook-java/src/main/resources/injector.dll b/weChatHook-java/src/main/resources/injector.dll new file mode 100644 index 0000000..eb61d1c Binary files /dev/null and b/weChatHook-java/src/main/resources/injector.dll differ diff --git a/weChatHook-java/src/main/resources/wxhelper.dll b/weChatHook-java/src/main/resources/wxhelper.dll new file mode 100644 index 0000000..49439ae Binary files /dev/null and b/weChatHook-java/src/main/resources/wxhelper.dll differ