Chrome 插件随机向我的 C++ 本机主机应用程序发送垃圾

2024-03-29

我正在尝试为我的大学项目编写一个简单的家长控制应用程序,但我是浏览器插件的新手。我想使用Chrome插件将用户实时查看的主机发送到Qt应用程序,Qt应用程序将分析用户行为。问题是,有时 chrome 发送正确的主机,有时它发送带有空字符串或非常长的消息的垃圾,这是我的 Qt 应用程序过滤的。但这些“错误”消息会无限循环地发送,为了使其再次工作,我必须重新启动扩展程序或 chrome 甚至整个电脑。

Chrome 插件清单:

{
    "name": "AM Chrome addon",
    "version": "0.7",
    "description": "Get your activity supervised!",
    "background": {
        "scripts": [
            "background.js"
        ],
        "persistent": false
    },
    "permissions": [
        "tabs",
        "nativeMessaging",
        "background"
    ],
    "manifest_version": 2
}

插件background.js文件:

var current = undefined;
var port = null;
tryConnectagain();

function tryConnectagain() {
    port = chrome.runtime.connectNative('<Native host app-name>');
    port.onDisconnect.addListener(onDisconnect);
}

function onDisconnect() {
    port = null;
        console.log("last error: ", chrome.runtime.lastError.message);
        setTimeout(tryConnectagain, 1000);
}

function sendMessageToNativeApp(message) {
    if (port != null) port.postMessage({ message: message });
}

function newUrl(u) {
    if (u != undefined && !u.includes(current) && !u.includes("chrome-extension://") && u.includes('.')) {
        var u = new URL(u);
        var domain = u.hostname.replace("www.", "");
        if (domain != current) {
            current = domain;
            sendMessageToNativeApp(current);
            console.log(current);
        }
    }
    else if (current != "NotURL") {
        current = "NotURL";
        sendMessageToNativeApp(current);
        console.log(current);
    }
}

// Here I'm trying to intercept all URL change situations

chrome.tabs.onActivated.addListener(function (activeInfo) {
    chrome.tabs.get(activeInfo.tabId, function (tab) {
        if (tab.active && tab.highlighted) newUrl(tab.url);
    });
});

chrome.tabs.onAttached.addListener(function (tabId, attachInfo) {
    chrome.tabs.get(tabId, function (tab) {
        if (tab.active && tab.highlighted) newUrl(tab.url);
    });
});

chrome.tabs.onReplaced.addListener(function (addedTabId, removedTabId) {
    chrome.tabs.get(addedTabId, function (tab) {
        if (tab.active && tab.highlighted) newUrl(tab.url);
    });
});

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
    if (changeInfo.url && tab.active && tab.highlighted) newUrl(changeInfo.url);
});

chrome.windows.onFocusChanged.addListener(function (windowId) {
    if (windowId > -1) {
        var getInfo = { populate: true, windowTypes: ['normal'] };
        chrome.windows.getLastFocused(getInfo, function (window) {
            for (var t = 0; t < window.tabs.length; t++) {
                if (window.tabs[t].active && window.tabs[t].highlighted) {
                    newUrl(window.tabs[t].url);
                    break;
                }
            }
        })
    }
});

本机主机应用程序清单:

{
  "name": "<Native host app-name>",
  "description": "Hostname Identifier",
  "path": "<Hostname app Path>",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://<extension-ID>/"
  ]
}

以及从插件接收数据的 C++ qt 代码片段: addonmessagereceiver.h:

#ifndef ADDONMESSAGERECEIVER_H
#define ADDONMESSAGERECEIVER_H

#include <qthread.h>
#include <QJsonDocument>
#include <QJsonObject>

#include <iostream>
#include <string>

class AddonMessageReceiver : public QThread
{
    Q_OBJECT
public:
    void run();
signals:
    void UpdateMessage(const QString &);
};

#endif // ADDONMESSAGERECEIVER_H

addonmessagereceiver.cpp:

#include "addonmessagereceiver.h"
#include <qdebug.h>
using namespace std;

void AddonMessageReceiver::run()
{
    do{
        char nextMessageLen[4];
        cin.read(nextMessageLen, 4);
        unsigned long int messageLength = *reinterpret_cast<unsigned long int *>(nextMessageLen);
        qDebug() << messageLength << static_cast<int>(nextMessageLen[0]) << static_cast<int>(nextMessageLen[1]) << static_cast<int>(nextMessageLen[2]) << static_cast<int>(nextMessageLen[3]);
        if(messageLength<1024 && messageLength>1)
        {
            char *incomingMessage = new char[messageLength+1];
            memset(incomingMessage,'\0',messageLength+1);
            cin.read(incomingMessage, messageLength);
            QString message = QString::fromLatin1(incomingMessage);
            delete[] incomingMessage;
            qDebug() << messageLength << message;
            if(message.length()>5)
            {
                QJsonDocument json = QJsonDocument::fromJson(message.toLatin1());
                QJsonObject obj = json.object();
                QString host = obj.value("message").toString();
                emit UpdateMessage(host);
            }
        }
        QThread::msleep(100);
    }while(true);
}

qDebug 循环中错误的 nextMessageLen 示例:

一个好的输入在循环中变成错误的例子:

您能告诉我该扩展程序或 chrome 发生了什么,或者我对本机应用程序有什么问题吗?谢谢您的回答。


基于这个答案 https://stackoverflow.com/a/36865680/6622587我构建了一个类来监视“stdin”,获取文本并使用 QFile 对其进行解码:

本地信使.h

#ifndef NATIVEMESSENGER_H
#define NATIVEMESSENGER_H

#include <QObject>
#include <QFile>

class NativeMessenger : public QObject
{
    Q_OBJECT
public:
    explicit NativeMessenger(QObject *parent = nullptr);
public Q_SLOTS:
    void sendMessage(const QByteArray & message);
Q_SIGNALS:
    void messageChanged(const QByteArray & message);
private Q_SLOTS:
    void readyRead();
private:
    QFile m_qin;
    QFile m_qout;
};

#endif // NATIVEMESSENGER_H

本地信使.cpp

#include "nativemessenger.h"

#include <QCoreApplication>
#ifdef Q_OS_WIN
#include <QWinEventNotifier>
#include <windows.h>
#else
#include <QSocketNotifier>
#endif
NativeMessenger::NativeMessenger(QObject *parent) : QObject(parent)
{
#ifdef Q_OS_WIN
    // https://developer.chrome.com/apps/nativeMessaging#native-messaging-debugging
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
#endif

    m_qin.open(stdin, QIODevice::ReadOnly | QIODevice::Unbuffered);
    m_qout.open(stdout, QIODevice::WriteOnly);

#ifdef Q_OS_WIN
    QWinEventNotifier *m_notifier = new QWinEventNotifier(GetStdHandle(STD_INPUT_HANDLE));
    connect(m_notifier, &QWinEventNotifier::activated, this, &NativeMessenger::readyRead);
#else
    QSocketNotifier *m_notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this);
    connect(m_notifier, &QSocketNotifier::activated, this, &NativeMessenger::readyRead);
#endif
}

void NativeMessenger::sendMessage(const QByteArray &message){
    quint32 len = message.length();
    m_qout.write(reinterpret_cast<char *>(&len), sizeof(len));
    m_qout.write(message);
    m_qout.flush();
}

void NativeMessenger::readyRead(){
    m_qin.startTransaction();
    quint32 length = 0;
    qint64 rc = m_qin.read(reinterpret_cast<char *>(&length), sizeof(quint32));
    if (rc == -1) {
        m_qin.rollbackTransaction();
        return;
    }
    QByteArray message = m_qin.read(length);
    if (message.length() != int(length)) {
        m_qin.rollbackTransaction();
        return;
    }
    if (message.isEmpty()) {
        m_qin.rollbackTransaction();
        return;
    }
    m_qin.commitTransaction();
    Q_EMIT messageChanged(message);
}

main.cpp

#include <QCoreApplication>
#include <QJsonDocument>
#include <QJsonObject>

#include <QDebug>

#include "nativemessenger.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    NativeMessenger listener;
    QObject::connect(&listener, &NativeMessenger::messageChanged,
                     [&listener]
                     (const QByteArray & message){
        // decode message 
        QJsonParseError error;
        QJsonDocument json = QJsonDocument::fromJson(message, &error);
        if(error.error != QJsonParseError::NoError){
            qDebug() << error.errorString();
        }
        // build response
        QJsonObject object
        {
            {"data", json.object()},
            {"name", QCoreApplication::applicationName()}
        };
        QByteArray response = QJsonDocument(object).toJson(QJsonDocument::Compact);
        // send response
        listener.sendMessage(response);
    });
    return a.exec();
}

A complete example can be found here https://github.com/eyllanesc/stackoverflow/tree/master/questions/59336957.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Chrome 插件随机向我的 C++ 本机主机应用程序发送垃圾 的相关文章

  • 如何在 Visual C++ 中创建 ActiveX DLL

    是否有在 Visual Studio 2008 C 中创建 ActiveX DLL 的教程 参考 我有一个使用 DLLRegisterServer UnregisterServer 构建的 DLL 并且已注册 但我在弄清楚使用什么名称来引用
  • 使用 mkl_malloc 进行内存对齐

    这个问题可能只是表明我还没有理解 C 中的一些重要内容 Intel Math Kernel 库提供了一种在分配内存时设置内存对齐的方法 另一方面 我只是通过引用将数组传递给 mkl lapack 例程 那么 lapack 例程如何知道数组的
  • PyQt5:如何将 QPushButton 连接到插槽?

    好吧 几乎所有教程 可理解的用人类语言编写的文档都是针对 PyQt4 的 但是 PyQt5 改变了整个 将按钮连接到插槽 的工作方式 但我仍然不知道如何做到这一点 我在 QtDesigner 中做了一个快速 gui 并且有一个 QPushB
  • 如何从 API 获取雅虎天气背景?

    我有一个天气小部件 我需要动态背景 雅虎有天气 API 但我无法找到与天气类型相关的背景图像 https weather yahoo com https weather yahoo com 这可能吗 var url http query y
  • 使用 jquery deferreds 处理可变数量的 ajax 请求

    当我有可变数量的 ajax 请求时 如何使用 deferreds 调用它们 我猜 qty of gets 3 function getHTML productID qty of gets var dfd Deferred i 0 c 0 t
  • 未初始化的枚举变量值

    我使用 enum 声明新类型 DAY 然后从中声明两个变量 day1 和 day2 然后当我使用未初始化的值时 我应该看到 0 到 6 之间的值 因为 enumlist 中的值介于 0 到 6 之间 但我收到了这些值改为 858993460
  • 使用 istream_iterator 范围构造时无法访问向量

    我尝试编译此代码片段 但出现编译器错误 使用 Visual Studio 2010 进行编译 include
  • 从 std::list 中删除具有特定值的元素

    我需要从 std list 中删除具有特定值的元素 随着list
  • BigInteger 乘以 Double

    我的物理老师给全班布置了一项艰巨的任务 我正在尝试创建一个程序来为我计算一些事情 在某个时刻 我需要将分子数量乘以百分比 Ulong 不能容纳大到 6022 10 19 的数字 所以我必须使用 net 4 0 中的 BigInteger 但
  • Array.filter 与 $filter('filter')

    我应该在 Angular 应用程序中使用哪一个 为什么 array filter o gt o name myName or filter filter array name myName true 关键的区别是快捷方式或语法糖由提供 fi
  • __syncthreads() 死锁

    如果只有部分线程执行 syncthreads 会导致死锁吗 我有一个这样的内核 global void Kernel int N int a if threadIdx x
  • screen.availHeight 和 window.height() 之间的区别

    我正在我的浏览器 Firefox 上执行以下 Javascript console debug 屏幕高度 屏幕可用高度 输出770 console debug 窗口高度 窗口 height 输出210 我也在使用 jQuery 两者有什么区
  • 现在的浏览器真的不隐藏javascript吗?

    这不是重复的这个问题 https stackoverflow com questions 822872 do web sites really need to cater for browsers that dont have javasc
  • 重载解析:这如何不含糊不清?

    假设我们有这段代码 是从一个单独的问题复制的 namespace x void f class C void f using x f f lt 名字f在指定的行上明确指的是x f 至少根据 gcc 和 clang 为什么是x f优先于x C
  • 在 angular2 中使用 routerLink 更新模板

    当我移动到另一个模板时 我遇到了模板未更新的问题store location 例如 默认值为Eastleigh如果我搬到USA它将更改为USA但当我去其他地方时它就粘住了USA 我必须刷新页面以便模板更新Collection Store 事
  • Eigen 如何沿特定维度连接矩阵?

    我有两个特征矩阵 我想将它们连接起来 就像在 matlab 中一样cat 0 A B eigen 有等价物吗 Thanks 您可以使用逗号初始值设定项语法 水平方向 MatrixXd C A rows A cols B cols C lt
  • Javascript/jQuery/等中测量经过时间/一段时间后触发事件的方法

    我正在尝试使用 HTML5 Javascript 制作一个简单的游戏 我想对活动施加时间限制 例如 当玩家进入一个屋顶正在向他们逼近的房间时 我想给他们一些时间来做出决定 然后自动发生其他事件 但是 如果他们做出决定 我根本不希望触发定时功
  • 无法使用 openxml 在 PPT 报告中生成第二个表

    我有这个代码 我能够完美地生成带有文本数据的 pptx 报告 我在这份报告中还有 4 个表格 其中包含动态数据 我可以在 PPT 中生成一张表格 但无法生成多个表格 Requirement On the right I have 4 tab
  • EF,Code First - 如何在插入时设置自定义 Guid 标识值

    在处理在数据库中插入新实体时 我面临以下问题Guid作为主键 代码优先的 EF 5方法 我知道有很多类似的主题 因为我为此问题运行了几个小时 但我找不到与此问题相关的主题 举个例子 我的 POCO 类是 public class Entit
  • 无法使用“in”运算符在中搜索“_id”

    我正在尝试使用 mongoose 和express 来获取现有的用户文档 但我只得到这个 webroot api domain com production node modules mongoose lib document js 162

随机推荐