讯飞星火GPT接入微信

之前为了搞微信机器人我造了个双开工具,这个双开工具就是基于LSPosed框架开发的,LSPosed框架本身就是兼容支持XPosed接口的开发的模块。于是微信机器人模块,我也是基于Xposed框架开发的,因为这样更方便一些。

原理:通过LSPosed 提供的Hook能力,Hook了微信代码里,接收消息的函数,和发送消息的函数。当收到消息时,将消息内容,通过封装的讯飞星火GPT接口发送给讯飞GPT,等到接口回调回来内容,则将内容通过发射调用微信发送代码,将消息发送出去。

基础知识:

1.Android Apk基础逆向知识。

2.Android及Websocket开发知识。

工具:

1.jadx反编译工具。

2.AndroidStudio。

组件:

1.XposedAPI java包,用于Hook微信代码里的接收消息。

2.OKHttp框架,用于和讯飞GPT通信,因为讯飞给的SDK里包含Native代码,但是Xposed模块不支持native开发,所以需要自己写一个。

XPosed工程配置

配置好XPosed开发工程,这里就不展开了,了解点逆向的人都知道。

https://blog.csdn.net/moon_nife/article/details/91346067?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170627179016800227453985%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=170627179016800227453985&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-91346067-null-null.142v99pc_search_result_base6&utm_term=Xposed%E6%A8%A1%E5%9D%97%E5%BC%80%E5%8F%91&spm=1018.2226.3001.4187

可以根据这篇文章进行配置。

讯飞GPT库搭建

由于Xposed框架不支持lib库的加载,但是讯飞的Android版本API包是将网络请求部分封装到Native层,无法直接调用,所以我就基于OKHttp框架,实现一个简单的Java Websocket功能,用来和讯飞GPT交互。

发送消息函数

    private void sendWebSocket(String msg) {
        try {
            JSONObject requestJson = new JSONObject();

            JSONObject header = new JSONObject();  // header参数
            header.put("app_id", appid);
            header.put("uid", userId);

            JSONObject parameter = new JSONObject(); // parameter参数
            JSONObject chat = new JSONObject();
            chat.put("domain", "generalv3");
            chat.put("temperature", 0.5);
            chat.put("max_tokens", 4096);
            parameter.put("chat", chat);

            JSONObject payload = new JSONObject(); // payload参数
            JSONObject message = new JSONObject();
            JSONArray text = new JSONArray();
            List<RoleContent> historyList = getHistoryList(userId);
            // 历史问题获取
            if (historyList.size() > 0) {
                for (RoleContent tempRoleContent : historyList) {
                    text.add(JSON.toJSON(tempRoleContent));
                }
            }

            // 最新问题
            RoleContent roleContent = new RoleContent();
            roleContent.role = "user";
            roleContent.content = msg;
            text.add(JSON.toJSON(roleContent));
            historyList.add(roleContent);

            message.put("text", text);
            payload.put("message", message);
            requestJson.put("header", header);
            requestJson.put("parameter", parameter);
            requestJson.put("payload", payload);
            // System.err.println(requestJson); // 可以打印看每次的传参明细
            webSocket.send(requestJson.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

接收消息解析函数

public void onMessage(WebSocket webSocket, String text) {
//        Log.e("SparkChat", userId + "用来区分那个用户的结果" + text);
        JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
        if (myJsonParse.header.code != 0) {
            Log.e("SparkChat","发生错误,错误码为:" + myJsonParse.header.code);
            Log.e("SparkChat","本次请求的sid为:" + myJsonParse.header.sid);
            webSocket.close(1000, "");
        }
        Log.d("SparkChat","*************************************************************************************");
        List<Text> textList = myJsonParse.payload.choices.text;
        for (Text temp : textList) {
            Log.d("SparkChatx", temp.content);
            totalAnswer=totalAnswer+temp.content;
        }
        Log.d("SparkChat","*************************************************************************************");
        if (myJsonParse.header.status == 2) {
            // 可以关闭连接,释放资源
            List<RoleContent> historyList = getHistoryList(userId);
            if(canAddHistory(userId)){
                RoleContent roleContent=new RoleContent();
                roleContent.setRole("assistant");
                roleContent.setContent(totalAnswer);
                historyList.add(roleContent);
            }else{
                historyList.remove(0);
                RoleContent roleContent=new RoleContent();
                roleContent.setRole("assistant");
                roleContent.setContent(totalAnswer);
                historyList.add(roleContent);
            }
            totalFlag = true;
            webSocket.close(1000, null);
        }
    }

WX接收Hook和发送代码

//                    Log.e("SparkChat","t11.c hook");
                    Method getMsgIdMethod = ReflectUtils.getDeclaredMethod(param.args[1], "getMsgId");
                    long MsgId = (long) getMsgIdMethod.invoke(param.args[1]);
                    String strMsgId = String.valueOf(MsgId);
                    Log.d("SparkChat","receiver msg id " + strMsgId);

                    Method getContentMethod =  ReflectUtils.getDeclaredMethod(param.args[1], "getContent");
                    String content = (String) getContentMethod.invoke(param.args[1]);
                    Log.d("SparkChat","receiver content " + content);
//                    sendMsg();
                    UHandler.getHandler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                BigModelNew talkerModel;
                                if (talkerModels.containsKey(strMsgId)) {
                                    talkerModel = talkerModels.get(strMsgId);
                                } else {
                                    talkerModel = new BigModelNew();
                                    talkerModel.init(strMsgId, new BigModelNew.IMessageCallback() {
                                        @Override
                                        public void onMessage(String msg) {
                                            UHandler.getHandler().postDelayed(new Runnable() {
                                                @Override
                                                public void run() {
                                                    try {
                                                        Log.d("SparkChat","UI show result text");
                                                        Method method = ReflectUtils.getDeclaredMethod(r1Obj, "c", String.class);
                                                        method.invoke(r1Obj, msg);
                                                    } catch (Throwable e) {
                                                        e.printStackTrace();
                                                    }
                                                }
                                            }, 3000);
                                        }
                                    });
                                    talkerModels.put(strMsgId, talkerModel);
                                }
                                Log.d("SparkChat","tos Send msg to GPT");
                                talkerModel.sendMsg(content);
                            } catch (Throwable e) {
                                e.printStackTrace();
                            }
                        }
                    }, 3000);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        });

上面代码中,通过Java Hook,hook 微信Java代码的"t11.c" 类的z1方法,这个方法是收到消息时的分发函数。通过解析参数,就可以获得发送的消息内容,基于微信8.0.43版本。

我也是逆向小白,分享些基础的内容,详细可以去https://github.com/ziyunzhifeng/WeChatGPT 下载Demo源码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值