zl程序教程

您现在的位置是:首页 >  IT要闻

当前栏目

C/C++ 计算文件ROF再计算VAOF

2023-02-18 16:46:19 时间

功能代码:

int get_PE_feature_rof(string path_r,int codeArr[],int codeCtrl[],int len){
	
	// 打开文件
	ifstream in = ifstream(path_r, ios::binary);
	if (!in.is_open()){
		cout << "文件打开失败:" << GetLastError() << endl;
		in.close();
		return 0;
	}

	// 获取文件大小、文件名
	long long Beg = in.tellg();
	in.seekg(0, ios::end);
	long long End = in.tellg();
	long long fileSize = End - Beg;
	in.seekg(0, ios::beg);

	// 读文件(每次循环读取 1 字节)
	int byteBeenRead = 0;				// 已经读取的字节数
	unsigned char temp;					// 存放读取内容的缓冲区				
	int rof_feature = 0;				// 特征 ROF
	int codeArrSub = 0;					// 要对比的 codeArr[] 下标
	BOOL isFound = FALSE;				// 是否找到特征
	int cmpAllReady = 0;				// 已经对比特征的次数
	while (in.read((char*)&temp, 1)/* && isFound == FALSE*/){
		byteBeenRead++;
		// 读 1 字节
		int hex = (unsigned)temp;

		// 控制码为0 则比较下一个
		if(codeCtrl[codeArrSub] == 0){
			codeArrSub++;
			// 是否比较完毕
			if(codeArrSub == len){
				cout << "find rof" << endl;
				rof_feature = byteBeenRead - len;
				isFound = TRUE;
				break;
			}
			continue;
		}
		// 匹配到一个特征
		if(hex == codeArr[codeArrSub]){
			codeArrSub++;
			// 是否比较完毕
			if(codeArrSub == len){
				cout << "find rof" << endl;
				rof_feature = byteBeenRead - len;
				isFound = TRUE;
				break;
			}
			continue;
		}
		// 匹配失败
		else{
			codeArrSub=0;
			continue;
		}
	}
	//cout << "rof_feature = " << hex << rof_feature << endl;
	in.close();
	return rof_feature;
}

调用例子

int codeArr_lea_win7[] = {
	0x48,0x8d,0x0d,0x37,0x41,0xdc,0xff,
	0x45,0x33,0xc0,
	0x48,0x8b,0xd7,
	0x48,0x8d,0x0c,0xd9,
	0xe8,0x98,0x54,0xf7,0xff,
	0x84,0xc0,
	0x75,0x11,
	0xff,0xc3,
	0x83,0xfb,0x40,
	0x72,0xdf,
	0x48,0x8b,0xcf,
	0xe8,0x65,0xd8,0xf7,0xff,
	0xeb,0xcc
};
int codeCtrl_lea_win7[] = {
	1,1,1,0,0,0,0,
	1,1,1,
	1,1,1,
	1,1,1,1,
	1,0,0,0,0,
	1,1,
	1,1,
	1,1,
	1,1,1,
	1,1,
	1,1,1,
	1,0,0,0,0,
	1,1
};

int rof_lea =  get_PE_feature_rof("C:\\Windows\\SysNative\\ntoskrnl.exe",codeArr_lea_win7,codeCtrl_lea_win7,43);

延申,根据 rof 计算 vaof 假设我们已经拿到了 ROF = 0x3d3f60 观察区段表:

0x46ec00 所以处于 PAGE 区段 根据公式 vaof = 我们的rof - 所属区段rof + 所属区段va

在这里也就是:

vaof = 0x3d3f60 - 0x235000 + 0x2be000;

拿到 vaof 后,再加上驱动基地址就能得到对应未公开 API 再内核中的内存地址