从Qt应用程序获取原始数据包数据
Get raw packet data from Qt application
我正在寻找一种方法来访问和篡改Qt应用程序发送和接收的原始数据包数据,但找不到任何东西。有什么方法吗?或者,如果不是应用程序,则至少是一种从QWebView访问数据包数据的方法。
有没有方法可以实现上述两种中的任何一种?
对不起,山姆,我无法让它工作。我一直在尝试我能想象的一切,但没有像它想要的那样进行。
让我们列出一个简短的选项列表,以及可以做什么和不能做什么:
-
您可以通过获取
webView->page()->currentFrame()
QWebFrame
,然后访问setContents()
、setHtml()
、toHtml()
或toPlainText()
等方法访问检索到的网页。您可以通过这些功能动态更改小部件中显示的网页。 -
您可以通过
replyFinished()
槽中reply->readAll()
的方法访问为每个请求接收的原始响应(作为字节数组)。 -
可以通过在您自己的网络访问管理器中重写
QNetworkAccessManager::createRequest()
方法来截获请求。在那里,您可以访问请求中发送的 URL 和标头,并更改它们或取消请求。
但。。。您希望访问每个请求的请求和已回复的数据。
访问请求很容易,已经通过在自定义QNetworkAccessManager
中覆盖createRequest()
方法来解释。但是让我们谈谈另一部分:
-
对于我所看到的,从请求中获得的回复是只读的,无法更改,因为它在源代码中硬编码
QNetworkReply
。 -
你不能使用
QNetworkReply
的writeData()
函数,因为它是硬编码的,可以简单地做return -1
!!! -
您可以尝试对自己的
QNetworkReply
进行子类化,并在自定义QNetworkAccessManager
的createRequest()
方法中返回它。必须覆盖函数readAll()
、bytesAvailable()
和abort()
。奇怪的是,此方法仅在向非 HTTP 目标发出请求时才有效。我认为QNetworkAccessManager
的内部结构会根据所使用的协议(HTTP,FTP等)调用QNetworkReply
的不同实现。所以这在某种意义上是有效的,但不是以我们想要的方式。例如,此方法可用于在特定条件下返回预定义的网页。 -
考虑到
QNetworkAccessManager::createRequest()
必须返回一个QNetworkReply
对象的事实,我看不到允许篡改回复字节数组的任何子类组合。它得到了很好的保护,您必须在这些类上重新实现所有内容才能实现您的目标。几乎复制粘贴所有QtNetwork
部分的源代码类并进行自己的实现。
所以我认为答案是:"不,似乎不能完全按照你的要求去做;只是部分"。
不好意思。
中服务器发送/接收的数据的正确方法是通过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()
方法获取该对象。您可以通过QWebView::page()
从QWebView
获取QWebPage
。
编辑
要操作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);
// ...
从现在开始,所有请求都将使用该对象发出。
此方法允许完全控制导航器发出的请求:过滤和访问请求数据(标头、get 和 post 值等)。您可以记录请求,分析请求及其POST/GET字段等。
希望最终有所帮助!
看起来你想要Wireshark http://www.wireshark.org/或Fiddler http://www.fiddler2.com/fiddler2/,甚至可能是Charles http://www.charlesproxy.com/。
这些工具与Qt没有任何关系,可用于检查和拦截各种程序的网络流量。
...那么代理服务器呢?一夜好眠让我想到了这种可能性。
您可以按照环回示例和 torrent 客户端示例等制作一个。因此,您可以捕获和篡改请求和回复。
您可以使用 webView->page()->networkAccessManager()->setProxy()
在客户端QWebView
上配置代理。
这涉及构建一个进程,该进程侦听所需的端口(例如 8080)并侦听本地主机上的连接。
您必须通过以下方式实现代理协议:
- 分析 GET 和 POST 操作,
- 以二进制传输的形式接收整个请求,
- 篡改请求,
- 将连接中获取的请求发送到目标 IP,
- 然后你可以捕获回复,
- 篡改收到的回复,以及
- 将生成的响应发送到客户端 Web 视图。
在这里我没有经验,但道路似乎很清楚。这将是很多编码,但我认为如果不是唯一的选择,这确实是一个不错的选择。
更重要的是:这是可以做到的!
- 如何在 XML 中正确存储原始字节数据并恢复它?
- 如何查看async_accept故障的原始 tcp 数据?
- 读取C++的原始字节数据
- 如何从C++中的原始指针数据构造张量流::张量
- 从数据库中以 blob 数据类型形式存储的原始图像数据中检索 CImage 对象
- 如何使用 C/C++获取原始相机数据
- 在 C++ 中使用 libsndfile 从 WAV 文件中提取原始音频数据
- 使用 ADO 将原始文件数据插入访问表的 BLOB("OLE 对象")字段
- Qt/C++-转换原始二进制数据并将其显示为图像(即QImage)
- 为什么我必须将原始图像数据的宽度除以3
- 在Windows中更改原始波形数据的音高
- 使用FAAC编码到m4a的原始PCM数据是不可识别的
- 如何使用boost::asio发送原始二进制数据
- 用OpenGL在Qt中显示DirectShow的原始图像数据
- 通过原始缓冲区数据缩放和旋转纹理到另一个纹理上
- 从原始缓冲区数据创建Mat图像
- 将原始mono8数据转换为PNG时,加快PNG++的速度
- 转储原始图像数据
- 如何正确接收和发送原始红外数据从Arduino
- 如何将原始图像数据保存为png图像