我已经单独编写了该程序,它可以正常工作,但是当将其作为头文件导入Qt项目时,它会以其他方式起作用的代码引发错误。错误:
这是头文件
#include <iostream>
#include <string>
#include <sstream>
//global vars
FILE *pFile;
char * buffer;
long lSize;
std::basic_stringstream<char> e_lfanew() {
pFile = fopen("hello.exe", "r");
//get file size
fseek(pFile, 0, SEEK_END);
long lSize = ftell(pFile);
rewind(pFile);
//alloc memory
buffer = (char *) malloc(sizeof(char) * lSize);
//read file to memory
auto result = fread(buffer, 1, lSize, pFile);
auto e_lfanew = (unsigned char *) malloc(4);
fseek(pFile, 0x3c, SEEK_SET);
fread(e_lfanew, 0x1, 0x4, pFile);
std::stringstream pe_offset;
for(size_t i=0; i<4; i++){
std::cout << std::hex << (int)e_lfanew[i];
pe_offset << std::hex << (int)e_lfanew[i];
}
std::cout << pe_offset.rdbuf();
return pe_offset;
}
这是qt mainwindow.c文件(具有导致错误的按钮按下功能的文件)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "e_lfanew.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow(){
delete ui;
}
void MainWindow::on_pushButton_clicked(){
QString e_lfanew_value = QString::fromStdString(e_lfanew().str());
ui->label_2->setText(e_lfanew_value);
}
您的程序不会从Qt
二进制文件中引发错误,但会从minkernel/crts/ucrt/src/appcrt/stdio/fseek.cpp
中引发错误。因此,我认为问题出在您尝试fseek
时。您的代码有一些问题,最大的问题是在使用它之前,请不要检查文件描述符是否不为null。
从fopen()
文档中可以阅读。
如果文件成功打开,该函数将返回指向
FILE
对象的指针,该指针可用于在以后的操作中标识流。否则,将返回空指针。在大多数库实现中,errno
变量也会在失败时设置为特定于系统的错误代码。
这意味着打开文件后,您可能会在pFile
变量中获得空指针。尝试添加以下行。
std::basic_stringstream<char> e_lfanew() {
pFile = fopen("hello.exe", "r");
if (pFile == nullptr) // or simply if (!pFile)
// Cannot open file. Handle the situation
fseek(pFile, 0, SEEK_END);
long lSize = ftell(pFile);
rewind(pFile);
正如注释中提到的@ Scheff,在MS Windows上,应始终明确地读取二进制文件:fopen(file_name, "rb") (or std::ifstream(file_name, std::ios::binary))
。否则,您可能无法获得文件中所包含的内容。