Calling BIOS from Driver in Windows XP x64
http://x86asm.net/articles/calling-bios-from-driver-in-windows-xp-x64/
访问物理内存,找到如下代码,但不知这个代码能否在新版 Windows 下工作:
http://nah6.com/~itsme/cvs-xdadevtools/itsutils/src/sysint-physmem.cpp
//========================================================
//
// Physmem
//
// Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//
// This program demonstrates how you can open and
// map physical memory. This is essentially the NT
// equivalent of the \dev\kmem device in UNIX.
//
//========================================================
#include <util/wintypes.h>
#include "debug.h"
//#include <stdio.h>
//#include "native.h"
//========================================================
//
// Native.h
//
// Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//
// This file contains tyepdefs and defines from NTDDK.H.
// They are included here so that we don't have to
// include NTDDK.H and get all the other stuff that
// we don't really need or want.
//
//========================================================
#define PAGE_NOACCESS 0x01 // winnt
#define PAGE_READONLY 0x02 // winnt
#define PAGE_READWRITE 0x04 // winnt
#define PAGE_WRITECOPY 0x08 // winnt
#define PAGE_EXECUTE 0x10 // winnt
#define PAGE_EXECUTE_READ 0x20 // winnt
#define PAGE_EXECUTE_READWRITE 0x40 // winnt
#define PAGE_EXECUTE_WRITECOPY 0x80 // winnt
#define PAGE_GUARD 0x100 // winnt
#define PAGE_NOCACHE 0x200 // winnt
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; // windbgkd
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
#ifdef MIDL_PASS
USHORT * Buffer;
#else // MIDL_PASS
PWSTRBuffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef enum _SECTION_INHERIT {
ViewShare = 1,
ViewUnmap = 2
} SECTION_INHERIT;
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_VALID_ATTRIBUTES 0x000001F2L
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService;// Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
//
// Functions in NTDLL that we dynamically locate
//
typedef NTSTATUS (__stdcall *PFN_NtUnmapViewOfSection)(
IN HANDLEProcessHandle,
IN PVOIDBaseAddress
);
typedef NTSTATUS (__stdcall *PFN_NtOpenSection)(
OUT PHANDLESectionHandle,
IN ACCESS_MASKDesiredAccess,
IN POBJECT_ATTRIBUTESObjectAttributes
);
typedef NTSTATUS (__stdcall *PFN_NtMapViewOfSection)(
IN HANDLESectionHandle,
IN HANDLEProcessHandle,
IN OUT PVOID*BaseAddress,
IN ULONGZeroBits,
IN ULONGCommitSize,
IN OUT PLARGE_INTEGERSectionOffset, /* optional */
IN OUT PULONGViewSize,
IN SECTION_INHERITInheritDisposition,
IN ULONGAllocationType,
IN ULONGProtect
);
typedef VOID (__stdcall *PFN_RtlInitUnicodeString)(
IN OUT PUNICODE_STRINGDestinationString,
IN PCWSTRSourceString
);
typedef ULONG (__stdcall *PFN_RtlNtStatusToDosError) (
IN NTSTATUS Status
);
PFN_NtUnmapViewOfSection NtUnmapViewOfSection;
PFN_NtOpenSection NtOpenSection;
PFN_NtMapViewOfSection NtMapViewOfSection;
PFN_RtlInitUnicodeString RtlInitUnicodeString;
PFN_RtlNtStatusToDosError RtlNtStatusToDosError;
//--------------------------------------------------------
//
// UnmapPhysicalMemory
//
// Maps a view of a section.
//
//--------------------------------------------------------
VOID UnmapPhysicalMemory( DWORD Address )
{
NTSTATUS status;
status = NtUnmapViewOfSection( (HANDLE) -1, (PVOID) Address );
if( !NT_SUCCESS(status)) {
error(status, "Unable to unmap view");
}
}
//--------------------------------------------------------
//
// MapPhysicalMemory
//
// Maps a view of a section.
//
//--------------------------------------------------------
BOOLEAN MapPhysicalMemory( HANDLE PhysicalMemory,
PDWORD Address, PDWORD Length,
PDWORD VirtualAddress )
{
NTSTATUS ntStatus;
PHYSICAL_ADDRESS viewBase;
*VirtualAddress = 0;
viewBase.QuadPart = (ULONGLONG) (*Address);
ntStatus = NtMapViewOfSection (PhysicalMemory,
(HANDLE) -1,
(PVOID*) VirtualAddress,
0L,
*Length,
&viewBase,
Length,
ViewShare,
0,
PAGE_READONLY );
if( !NT_SUCCESS( ntStatus )) {
//error( ntStatus, "Could not map view of %X length %X", *Address, *Length );
return FALSE;
}
*Address = viewBase.LowPart;
return TRUE;
}
//--------------------------------------------------------
//
// OpensPhysicalMemory
//
// This function opens the physical memory device. It
// uses the native API since
//
//--------------------------------------------------------
HANDLE OpenPhysicalMemory()
{
NTSTATUS status;
HANDLE physmem;
UNICODE_STRING physmemString;
OBJECT_ATTRIBUTES attributes;
WCHAR physmemName[] = L"\\device\\physicalmemory";
RtlInitUnicodeString( &physmemString, physmemName );
InitializeObjectAttributes( &attributes, &physmemString,
OBJ_CASE_INSENSITIVE, NULL, NULL );
status = NtOpenSection( &physmem, SECTION_MAP_READ, &attributes );
if( !NT_SUCCESS( status )) {
error(status, "Could not open \\device\\physicalmemory");
return NULL;
}
return physmem;
}
//--------------------------------------------------------
//
// LocateNtdllEntryPoints
//
// Finds the entry points for all the functions we
// need within NTDLL.DLL.
//
//--------------------------------------------------------
BOOLEAN LocateNtdllEntryPoints()
{
if( !(RtlInitUnicodeString = (PFN_RtlInitUnicodeString) GetProcAddress( GetModuleHandle("ntdll.dll"),
"RtlInitUnicodeString" )) ) {
return FALSE;
}
if( !(NtUnmapViewOfSection = (PFN_NtUnmapViewOfSection) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtUnmapViewOfSection" )) ) {
return FALSE;
}
if( !(NtOpenSection = (PFN_NtOpenSection) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtOpenSection" )) ) {
return FALSE;
}
if( !(NtMapViewOfSection = (PFN_NtMapViewOfSection) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtMapViewOfSection" )) ) {
return FALSE;
}
if( !(RtlNtStatusToDosError = (PFN_RtlNtStatusToDosError) GetProcAddress( GetModuleHandle("ntdll.dll"),
"RtlNtStatusToDosError" )) ) {
return FALSE;
}
return TRUE;
}
#if 0
//--------------------------------------------------------
//
// Main
//
// This program drives the command loop
//
//--------------------------------------------------------
int main( int argc, char *argv[] )
{
HANDLE physmem;
DWORD vaddress, paddress, length;
char input;
DWORD lines;
char ch;
DWORD i, j;
printf("\nPhysmem v1.0: physical memory viewer\n"
"By Mark Russinovich\n"
"Systems Internals - http://www.sysinternals.com\n\n");
//
// Load NTDLL entry points
//
if( !LocateNtdllEntryPoints() ) {
printf("Unable to locate NTDLL entry points.\n\n");
return -1;
}
//
// Open physical memory
//
if( !(physmem = OpenPhysicalMemory())) {
return -1;
}
//
// Enter the command loop
//
printf("Enter values in hexadecimal. Enter 'q' to quit.\n");
while( 1 ) {
printf("\nAddress: " ); fflush( stdout );
gets( input );
if( input == 'q' || input == 'Q' ) break;
sscanf( input, "%x", &paddress );
printf("Bytes: "); fflush( stdout );
gets( input );
if( input == 'q' || input == 'Q' ) break;
sscanf( input, "%x", &length );
//
// Map it
//
if( !MapPhysicalMemory( physmem, &paddress, &length,
&vaddress ))
continue;
//
// Dump it
//
lines = 0;
for( i = 0; i < length; i += BYTESPERLINE ) {
printf("%08X: ", paddress + i );
for( j = 0; j < BYTESPERLINE; j++ ) {
if( i+j == length ) break;
if( j == BYTESPERLINE/2 ) printf("-" );
printf("%02X ", *(PUCHAR) (vaddress + i +j ));
}
for( j = 0; j < BYTESPERLINE; j++ ) {
if( i+j == length ) break;
ch = *(PUCHAR) (vaddress + i +j );
if( __iscsym( ch ) ||
isalnum( ch ) ||
ch == ' ') {
printf("%c", ch);
} else {
printf("." );
}
}
printf("\n");
if( lines++ == LINESPERSCREEN ) {
printf("-- more -- ('q' to abort)" ); fflush(stdout);
ch = getchar();
if( ch == 'q' || ch == 'Q' ) {
fflush( stdin );
break;
}
lines = 0;
}
}
//
// Unmap the view
//
UnmapPhysicalMemory( vaddress );
}
//
// Close physical memory section
//
CloseHandle( physmem );
return 0;
}
#endif 本帖最后由 不点 于 2018-2-12 12:08 编辑
找到了一个闭源的查看物理内存的工具,德语的界面,可能不太方便:
https://kb.hilscher.com/display/CIFXDRV/Physical+Memory+Viewer+for+Windows
在 XP 和 Win7x64 试验了,能够查看物理内存的内容。
Win7x64 下还可以查看超过 4G 的高位内存。
谁能试试,看看在 XP (32 位)之下能否查看高于 4G 的物理内存地址的内容?
(点击上面的网址,下载原网站上的文件,不需要币值)
这个工具是.net的,没运行起来。可以试试读取0~1M的内存,看看grub4dos的信息能不能找到。
里面还有个physmem.sys驱动,好像签名齐全啊,只是不知道怎么用。 sp_star 发表于 2018-2-12 14:03
这个工具是.net的,没运行起来。可以试试读取0~1M的内存,看看grub4dos的信息能不能找到。
里面还有个phys ...
试验过了,完全能读出物理内存啊。
只需验证 XP 下能否读高位内存即可。Win7x64 已经验证成功。 不点 发表于 2018-2-12 15:32
试验过了,完全能读出物理内存啊。
只需验证 XP 下能否读高位内存即可。Win7x64 已经验证成功。
grub4dos的信息应该是在低位内存吧? 即使实际磁盘在高位内存,也要靠imdisk去处理。如果知道ramdisk在内存中的地址和大小,imdisk能直接映射吗? sp_star 发表于 2018-2-12 16:31
grub4dos的信息应该是在低位内存吧? 即使实际磁盘在高位内存,也要靠imdisk去处理。如果知道ramdisk在内 ...
映射物理内存,我觉得不难,imdisk 应该可以做到。
已知 firadisk 和 winvblock 都能访问物理内存。
imdisk 至少能够访问线性地址。
不过,即使 imdisk 不能访问物理地址,也能够给它添加这个功能(从 firadisk 或 winvblock 复制代码即可)。
不点 发表于 2018-2-12 17:02
映射物理内存,我觉得不难,imdisk 应该可以做到。
已知 firadisk 和 winvblock 都能访问物理内存。
关键是改了驱动就没有签名了啊。
不然,直接修改firadisk 或 winvblock就可以了。当然这2个本来也没签名。 sp_star 发表于 2018-2-12 17:08
关键是改了驱动就没有签名了啊。
不然,直接修改firadisk 或 winvblock就可以了。当然这2个本来也没签名 ...
确实是个问题。可以提交给原作者进行签名。
再有就是,干脆就增强 firadisk 或 winvblock 也行。
哪个途径容易编译,就采用那个途径。具体编译的人,看情况决定。
我估计,firadisk 的功能最完善。
firadisk 支持高位内存,winvblock 不支持。
firadisk 和 winvblock 支持物理内存,而 imdisk (有可能)不支持。
winvblock 和 imdisk 支持纯扇区序列,而 firadisk 不支持。
总体感觉,firadisk 毛病不严重,其毛病容易解决。
我在 win7 下安装了 Visual Studio 2017,结果不能编译任何程序。它要求操作系统是 Win10。
难度太大,这个帖子的讨论,我就不再来了,抱歉。有兴趣者,你们可以继续。
本帖最后由 chenall 于 2018-2-12 20:47 编辑
我也是用windows 7的安装了vs 2017可以正常使用呀,编译驱动还需要安装winddk.我之前有测试编译imdisk,编译没有通过,应该还需要做一些设置.
没有编译过驱动,搞不懂如何编译,我看了imdisk的源码介绍,应该是可以直接用nmake编译的,不过还是失败了.有一些报错.
也许你可以把这些需求到reboot回复给作者看看他能不能直接加上.毕竟我们如果自己要编译的话那个签名就是一个大麻烦. chenall 发表于 2018-2-12 20:46
我也是用windows 7的安装了vs 2017可以正常使用呀,编译驱动还需要安装winddk.我之前有测试编译imdisk,编 ...
能力有限,精力、时间、身体都不允许。放弃。也不会再去英文论坛给别人解释什么了,我的英文太 poor,费劲。
有难度的事情,我一下子都失去信心了。
顺其自然,谁愿意干啥就干啥。不勉强自己,也不勉强别人。
一切皆缘分,没办法。有缘和没缘。最后还是得老老实实在 Linux 下捣鼓。
本帖最后由 不点 于 2018-2-12 22:58 编辑
谁能编译这一句,就算成功:
MmMapIoSpace(0, 0, 0);
firadisk 和 winvblock 都使用了这个 API。如果编译成功,修改一下,就能把物理内存 dump 出来。
只要能 dump 出物理内存,事情就简单了。我们现在就卡在不能访问物理内存上了。
前面的那个闭源软件能够访问物理内存,可惜是闭源的。
在网上搜了许多天,也见不到一个能够在(新近的) Windows 下 dump 物理内存的开源工具。前面介绍的那个开源的工具只能在 xp 上运行。
dos时代菜鸟 发表于 2018-1-28 09:38
vbs脚本
谢谢分享好东西! chenall 发表于 2018-2-12 20:46
我也是用windows 7的安装了vs 2017可以正常使用呀,编译驱动还需要安装winddk.我之前有测试编译imdisk,编 ...
我以前编译成功过,记得是用WDK 7.1.0,貌似不用改什么东西啊。
一个小工具,在windows下读GRUB4DOS map的磁盘信息。
sp_star 发表于 2018-2-25 11:03
一个小工具,在windows下读GRUB4DOS map的磁盘信息。
前面有个闭源的工具可以显示出物理内存。
既然你能读 map 信息,想必你一定也能 cat 出物理内存。你能否写个工具,显示物理内存的内容呢?命令行工具即可,不需要图形界面。最好能 open source。
不点 发表于 2018-2-25 11:42
前面有个闭源的工具可以显示出物理内存。
既然你能读 map 信息,想必你一定也能 cat 出物理内存。你能 ...
还是使用的Winio驱动,64位时有签名问题。既然有兴趣,自己改改就可以了。
sp_star 发表于 2018-2-25 12:04
还是使用的Winio驱动,64位时有签名问题。既然有兴趣,自己改改就可以了。
我的 Windows 编译环境建立不起来,没有缘分,已经放弃。目前我的兴趣已经彻底转到 Linux 下了。在 Linux 下可做的事多着呢,根本忙不过来,恐怕以后再也没有机会回到 Windows 下编程了。
我把你提供的代码贴出来,方便有兴趣者查看。
// mdisk.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <shellapi.h>
//#include <winable.h>
typedef BOOL(WINAPI *INITIALIZEWINTO)(void);
typedef BOOL(WINAPI *SHUTDOWNWINIO)(void);
typedef BOOL(WINAPI *GETPORTVAL)(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);
typedef BOOL(WINAPI *SETPORTVAL)(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);
typedef PBYTE(_stdcall *MAPPHYSTOLIN)(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle);
typedef BOOL(_stdcall *UNMAPPHYSICALMEMORY)(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr);
typedef BOOL(WINAPI *GETPHYSLONG)(PBYTE pbPhysAddr, PDWORD pdwPhysVal);
typedef BOOL(WINAPI *SETPHYSLONG)(PBYTE pbPhysAddr, DWORD dwPhysVal);
//typedef BOOL(WINAPI *INSTALLWINIODRIVER)(PWSTR pszWinIoDriverPath, bool IsDemandLoaded = false);
//typedef BOOL(WINAPI *REMOVEWINIODRIVER)();
INITIALIZEWINTO InitializeWinIo = NULL;
SHUTDOWNWINIO ShutdownWinIo = NULL;
GETPORTVALGetPortVal = NULL;
SETPORTVALSetPortVal = NULL;
MAPPHYSTOLIN MapPhysToLin = NULL;
UNMAPPHYSICALMEMORY UnmapPhysicalMemory = NULL;
GETPHYSLONG GetPhysLong = NULL;
SETPHYSLONG SetPhysLong = NULL;
//INSTALLWINIODRIVER InstallWinIoDriver = NULL;
//REMOVEWINIODRIVER RemoveWinIoDriver = NULL;
BOOL InitFuncs(void)
{
HMODULE hMod = LoadLibrary(_T("WinIo32.dll"));
InitializeWinIo= (INITIALIZEWINTO)GetProcAddress(hMod,"InitializeWinIo");
ShutdownWinIo= (SHUTDOWNWINIO)GetProcAddress(hMod,"ShutdownWinIo");
GetPortVal= (GETPORTVAL)GetProcAddress(hMod,"GetPortVal");
SetPortVal= (SETPORTVAL)GetProcAddress(hMod,"SetPortVal");
MapPhysToLin=(MAPPHYSTOLIN)GetProcAddress(hMod,"MapPhysToLin");
UnmapPhysicalMemory=(UNMAPPHYSICALMEMORY)GetProcAddress(hMod,"UnmapPhysicalMemory");
GetPhysLong=(GETPHYSLONG)GetProcAddress(hMod,"GetPhysLong");
SetPhysLong=(SETPHYSLONG)GetProcAddress(hMod,"SetPhysLong");
//InstallWinIoDriver=(INSTALLWINIODRIVER)GetProcAddress(hMod,"InstallWinIoDriver");
//RemoveWinIoDriver=(REMOVEWINIODRIVER)GetProcAddress(hMod,"RemoveWinIoDriver");
if(InitializeWinIo==NULL) return FALSE;
if(ShutdownWinIo==NULL) return FALSE;
if(GetPortVal==NULL) return FALSE;
if(SetPortVal==NULL) return FALSE;
if(MapPhysToLin==NULL) return FALSE;
if(UnmapPhysicalMemory==NULL) return FALSE;
if(GetPhysLong==NULL) return FALSE;
if(SetPhysLong==NULL) return FALSE;
//if(InstallWinIoDriver==NULL) return FALSE;
//if(RemoveWinIoDriver==NULL) return FALSE;
return TRUE;
}
BOOL ReadPhysicalMemory(unsigned int phyAddr, DWORD phySize, unsigned char *buf)
{
unsigned int addr;
unsigned long data;
unsigned long *p=(unsigned long *)buf;
for(unsigned int i=0;i<phySize;i+=4)
{
addr=phyAddr+i;
GetPhysLong((PBYTE)addr,&data);
*p=data;
p++;
}
return TRUE;
}
void print_buf(unsigned char *p)
{
for(int k=0;k<200;k++)
{
printf("%c",*(p+k));
}
printf("\n");
}
void find_g4d_drive(unsigned char* buf, int bufLen);
int _tmain(int argc, _TCHAR* argv[])
{
if(InitFuncs()!=TRUE)
{
printf("Load WinIo.dll failed!\n");
return 0;
}
if(InitializeWinIo()!=TRUE)
{
printf("InitializeWinIo failed!\n");
return 0;
}
printf("InitializeWinIo OK!\n");
printf("\n");
//printf("DWORD length=%d\n",sizeof(DWORD));
#if 0
HANDLE hPhyMem;
PBYTE pbLinAddr;
//下面的语句让 0xf0000 地址的 65536 个字节可直接读写
pbLinAddr = MapPhysToLin((unsigned char *)0xf0000,65536,&hPhyMem);
printf("pbLinAddr=%x\n",pbLinAddr);
DWORD ttmp;
BOOL rtv;
rtv=GetPhysLong((PBYTE)0xf0000,&ttmp);
printf("rtv=%d, ttmp=%x\n",rtv, ttmp);
#endif
// real-mode RAM range 0-640KB
const int nBytes=0xA0000;
unsigned char buf;
memset(buf,0,nBytes);
ReadPhysicalMemory(0,nBytes,buf);
//print_buf(buf);
find_g4d_drive(buf,nBytes);
ShutdownWinIo();
printf("Done!\n");
return 0;
}
typedef struct _INTRVECT {
UINT16 offset;
UINT16 segment;
} INTRVECT, *PINTRVECT;
typedef struct _GRUB4DOS_DRIVE_MAP_SLOT {
unsigned char from_drive;
unsigned char to_drive; // 0xFF indicates a memdrive
unsigned char max_head;
unsigned char max_sector:6,
disable_lba:1, // bit 6: disable lba
read_only:1; // bit 7: read only
unsigned short to_cylinder:13, // max cylinder of the TO drive
from_cdrom:1, // bit 13: FROM drive is CDROM(with big 2048-byte sector)
to_cdrom:1, // bit 14:TOdrive is CDROM(with big 2048-byte sector)
to_support_lba:1; // bit 15:TOdrive support LBA
unsigned char to_head; // max head of the TO drive
unsigned char to_sector:6, // max sector of the TO drive
fake_write:1, // bit 6: fake-write or safe-boot
in_situ:1; // bit 7: in-situ
UINT64 start_sector;
UINT64 sector_count;
} GRUB4DOS_DRIVE_MAP_SLOT, *PGRUB4DOS_DRIVE_MAP_SLOT;
void print_drv_map(PGRUB4DOS_DRIVE_MAP_SLOT slot)
{
int dataLen=sizeof(GRUB4DOS_DRIVE_MAP_SLOT);
printf("DATA: ");
for(int k=0;k<dataLen;k++)
{
printf("%.2X ", *((unsigned char *)slot+k) );
}
printf("\n");
UINT64 drvlen=slot->sector_count<<9;
UINT64 address=slot->start_sector<<9;
printf("Detected GRUB4DOS disk offset=0x%I64x bytes, len=%I64d KB\n",address, drvlen>>10);
printf(" GRUB4DOS SourceDrive: 0x%02x\n", slot->from_drive);
printf(" GRUB4DOS DestDrive: 0x%02x\n", slot->to_drive);
printf(" GRUB4DOS MaxHead: %d\n", slot->max_head);
printf(" GRUB4DOS MaxSector: %d\n", slot->max_sector);
printf(" GRUB4DOS DestMaxCylinder: %d\n", slot->to_cylinder);
printf(" GRUB4DOS DestMaxHead: %d\n", slot->to_head);
printf(" GRUB4DOS DestMaxSector: %d\n", slot->to_sector);
printf(" GRUB4DOS SectorStart: 0x%08x\n", slot->start_sector);
printf(" GRUB4DOS SectorCount: %d\n", slot->sector_count);
printf("\n");
printf(" GRUB4DOS disable_lba=%d\n", slot->disable_lba);
printf(" GRUB4DOS read_only=%d\n", slot->read_only);
printf(" GRUB4DOS from_cdrom=%d\n", slot->from_cdrom);
printf(" GRUB4DOS to_cdrom=%d\n", slot->to_cdrom);
printf(" GRUB4DOS to_support_lba=%d\n", slot->to_support_lba);
printf(" GRUB4DOS fake_write=%d\n", slot->fake_write);
printf(" GRUB4DOS in_situ=%d\n", slot->in_situ);
}
void print_vector(INTRVECT * pvec)
{
printf("offset=0x%.4x", pvec->offset);
printf("segment=0x%.4x", pvec->segment);
printf("\n");
}
void print_string(unsigned char *buf,UINT32 int13entry)
{
unsigned char tmp_str;
memset(tmp_str,0,9);
memcpy(tmp_str,buf+int13entry+3,8);
printf("%s",tmp_str);
memset(tmp_str,0,9);
memcpy(tmp_str,buf+int13entry+3+8,8);
printf("%s\n",tmp_str);
}
int check_string(unsigned char *buf,UINT32 int13entry)
{
int cmp=-1;
unsigned char tmp_str;
memset(tmp_str,0,9);
memcpy(tmp_str,buf+int13entry+3,8);
cmp = strcmp((char *)tmp_str,"$INT13SF");
if(cmp!=0) return 0;
memset(tmp_str,0,9);
memcpy(tmp_str,buf+int13entry+3+8,8);
cmp = strcmp((char *)tmp_str,"GRUB4DOS");
if(cmp==0)
{
//printf("Found GRUB4DOS\n");
return 1;
}
return 0;
}
void find_g4d_drive(unsigned char* buf, int bufLen)
{
//bufLen=0xA0000;//640K
INTRVECT int13vector;
UINT32 int13entry;
int found=0;
/*for(int kk=0;kk<0x40;kk++)
{
int13vector = ((PINTRVECT)buf);
int13entry = (((UINT32)int13vector.segment << 4) + int13vector.offset);
printf("int13entry=0x%lX [%.4X:%.4X]\n",int13entry,int13vector.segment,int13vector.offset);
}
printf("\n");
return;
*/
int13vector = ((PINTRVECT)buf);
int13entry = (((UINT32)int13vector.segment << 4) + int13vector.offset);
while(int13entry<0xA0000-27)
{
//if(int13entry==0) continue;
printf("int13entry=0x%lX [%.4X:%.4X]\n",int13entry,int13vector.segment,int13vector.offset);
found=check_string(buf,int13entry);
if(found==1)
{
PGRUB4DOS_DRIVE_MAP_SLOT pdrvmap;
//drive map slot starts at offset 0x20 of the same segment as int13 entry
pdrvmap = (PGRUB4DOS_DRIVE_MAP_SLOT)(buf+(((UINT32)int13vector.segment << 4) + 0x20));
printf("Found GRUBDOS drive at offset 0x%lX [%.4X:%.4X], data length=%d bytes\n",
(unsigned char *)pdrvmap-buf,int13vector.segment,0x20,
sizeof(GRUB4DOS_DRIVE_MAP_SLOT) );
printf("\n");
print_drv_map(pdrvmap);
printf("\n");
}
int13vector = *((UNALIGNED INTRVECT *)(buf+int13entry+3+8+8));
int13entry = (((UINT32)int13vector.segment << 4) + int13vector.offset);
//printf("==>int13entry=0x%lX [%.4X:%.4X]\n",int13entry,int13vector.segment,int13vector.offset);
}
} 本帖最后由 不点 于 2018-2-25 14:28 编辑
sp_star 发表于 2018-2-25 11:03
一个小工具,在windows下读GRUB4DOS map的磁盘信息。
Win7x64 下运行失败。出错信息:InitializeWinIo failed!
是必须签名的原因吗?
我没有 32 位 Win7 环境,现在无法测试。但稍后可以试试 XP。
【更新】
XP 下报错:对话框 “g4d.exe 不是有效的 Win32 应用程序。”
有个“确定”按钮。
点击 “确定” 按钮后,DOS 框里显示 “拒绝访问。”
回到命令提示符。
D:\G4D>dir
驱动器 D 中的卷没有标签。
卷的序列号是 0000-4823
D:\G4D 的目录
2018/02/2513:31 <DIR> .
2018/02/2513:31 <DIR> ..
2018/02/2510:10 161,280 g4d.exe
2010/05/1523:56 45,568 WinIo32.dll
2010/05/0823:16 6,656 WinIo32.sys
2010/05/1523:56 44,544 WinIo64.dll
2010/05/0823:46 10,920 WinIo64.sys
5 个文件 268,968 字节
2 个目录 263,994,019,840 可用字节
D:\G4D>g4d
InitializeWinIo failed!
D:\G4D>
不点 发表于 2018-2-25 13:39
Win7x64 下运行失败。出错信息:InitializeWinIo failed!
是必须签名的原因吗?
我没有 32 位 Win7...
64位应该是签名的原因。
由于编译环境,可能不支持xp,我在win10 x86下试过。你可以试试在xp下自己再编译一下。 sp_star 发表于 2018-2-25 14:47
64位应该是签名的原因。
由于编译环境,可能不支持xp,我在win10 x86下试过。你可以试试在xp下自己再编 ...
在 Windows 下我没有编译环境,就不试了。
页:
1
[2]