我正在寻找一种方法来访问&篡改Qt应用程序发送和接收的原始数据包数据,但找不到任何内容。有什么方法吗? 或者如果不是应用程序,至少是从QWebView访问分组数据的方法。
有没有方法可以实现上述两种方法中的任何一种?
答案 0 :(得分:3)
篡改与网络连接中的服务器之间发送/接收的数据的正确方法是QNetworkAccessManager
。
此类允许您向服务器发送请求(可能带有标题)并获取响应(也包含标题)。
您可以访问相应QNetworkReply
对象上收到的数据。响应的标题:
{
...
QNetworkAccessManager *qnam = new QNetworkAccessManager(this);
connect(qnam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
QNetworkRequest request;
request.setUrl(QUrl("http://stackoverflow.com"));
request.setRawHeader("User-Agent", "Foo browser");
qnam->get(QNetworkRequest(request));
...
}
然后定义插槽:
void MyWidget::replyFinished(QNetworkReply *reply)
{
QByteArray response = reply->readAll();
QString mime = reply->header(QNetworkRequest::ContentTypeHeader).toString();
...
}
实际上,QWebView
有一个QNetworkAccessManager
对象来执行请求和管理回复。您可以通过QWebPage::networkAccessManager()
方法获取该对象。您可以通过QWebPage
从QWebView
获取QWebView::page()
。
修改强>
要操纵QWebView
显示的网页,您可以通过webView->setHtml(QString html)
直接设置新的HTML内容。
您还可以通过QWebFrame
类的方法直接访问HTML。
要获得此类对象,您必须执行以下操作:
QWebFrame *wb = webView->page()->currentFrame();
方法是:
void QWebFrame::setContent ( const QByteArray & data, const QString & mimeType = QString(), const QUrl & baseUrl = QUrl() )
用于在字节数组中设置新文档。
void QWebFrame::setHtml ( const QString & html, const QUrl & baseUrl = QUrl() )
也会这样做,但会考虑HTML文档的内容。
QString QWebFrame::toHtml () const
将内容作为HTML文档获取。
QString QWebFrame::toPlainText () const
与上述相同,为纯文本。
查看这些功能的文档。
编辑2:
最后,如果您想访问或过滤QWebView
本身发出的请求,我只能看到一种方法:从QNetworkAccessManager
派生一个类并覆盖用于发出请求的方法和收到答案。
然后,将该类的实例设置为QWebView使用的QNetworkAccessManager。
让我用骨架澄清:
class MyNAM : public QNetworkAccessManager
{
// ...
MyNAM(QObject *parent = 0) : QNetworkAccessManager(parent) { }
// ...
virtual QNetworkReply * createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0) {
// e.g. logging of the request
// e.g. decide if the request must be made
if (some_bool_deciding) {
QNetworkAccessManager::createRequest(op, req, outgoingData);
}
else {
// or faked...
}
// etc.
}
// ...
};
在您的主要应用程序中,您必须:
// ...
MyNAM *nam = new MyNAM();
webview->page()->setNetworkAccessManager(nam);
// ...
从现在开始,所有请求都将使用该对象进行。
此方法允许完全控制导航器发出的请求:过滤和访问请求数据(标题,获取和发布值等)。您可以记录请求,分析请求及其POST / GET字段等。
希望终于有所帮助!
答案 1 :(得分:3)
对不起,山姆,我做不到。我一直在尝试我能想象到的一切,但没有任何事情可以实现。
让我们列出一个简短的选项列表,以及可以做什么和不可以做什么:
您可以通过QWebFrame
获取webView->page()->currentFrame()
,然后访问setContents()
,setHtml()
,{{1}等方法来访问检索到的网页}或toHtml()
。您可以通过这些功能动态更改窗口小部件中显示的网页。
您可以通过toPlainText()
广告位中的方法reply->readAll()
访问为每个请求收到的原始响应(作为字节数组)。
可以通过覆盖您自己的网络访问管理器中的replyFinished()
方法来拦截请求。在那里,您可以访问请求中发送的URL和标题,并更改它们或取消请求。
但是......您想要访问每个请求的请求和回复数据。
访问请求很简单,已经通过覆盖自定义QNetworkAccessManager::createRequest()
中的createRequest()
方法来解释。但是让我们谈谈另一部分:
对于我所看到的,从请求获得的回复是只读且 IT无法更改,因为它是硬编码的在QNetworkAccessManager
的源代码中。
您无法使用 QNetworkReply
writeData()
的{{1}}功能,因为它只是简单地执行QNetworkReply
!!!
您可以尝试继承自己的return -1
并将其返回到自定义QNetworkReply
的{{1}}方法中。您必须覆盖功能createRequest()
,QNetworkAccessManager
和readAll()
。奇怪的是,此方法仅在请求发送到非HTTP目标时才有效。我认为bytesAvailable()
的内部调用abort()
的不同实现,具体取决于所使用的协议(HTTP,FTP,...)。所以这在某种意义上起作用,但不是我们想要的方式。例如,此方法可用于在特定条件下返回预定义的网页。
考虑到QNetworkAccessManager
必须返回QNetworkReply
对象这一事实,我看不到任何允许在回复的字节数组中进行篡改的子类组合。它确实受到很好的保护,你必须重新实现这些课程上的所有内容才能实现你的目标。几乎复制粘贴所有QNetworkAccessManager::createRequest()
部分的源类并进行自己的实现。
所以我认为答案是:“不,似乎不能完全按照你的要求完成;只是部分”。
对不起。
答案 2 :(得分:0)
看起来你想要Wireshark http://www.wireshark.org/或Fiddler http://www.fiddler2.com/fiddler2/,或者甚至是Charles http://www.charlesproxy.com/。
这些工具与Qt无关,可用于检查和拦截各种程序的网络流量。
答案 3 :(得分:0)
......那代理服务器怎么样?一夜好眠让我想到了这种可能性。
您可以在loopback example和torrent client example之后制作一个。因此,您可以捕获并篡改请求 AND 回复。
您可以使用QWebView
在客户端webView->page()->networkAccessManager()->setProxy()
上配置代理。
这涉及构建一个侦听所需端口(例如8080)并侦听本地主机上的连接的进程。
您必须通过以下方式实施代理协议:
这里我没有经验,但路径似乎很清楚。这将是一个很多编码,但我认为这是一个很好的选择如果不是唯一的选择。
更重要的是:可以做到!