不点 发表于 2018-2-11 22:30:36

搜到一篇好文,备忘(使用了未公开的功能,不具有通用性,但确实是一篇好文,从技术上来说):

Calling BIOS from Driver in Windows XP x64

http://x86asm.net/articles/calling-bios-from-driver-in-windows-xp-x64/

不点 发表于 2018-2-12 06:54:26

访问物理内存,找到如下代码,但不知这个代码能否在新版 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 07:35:33

本帖最后由 不点 于 2018-2-12 12:08 编辑

找到了一个闭源的查看物理内存的工具,德语的界面,可能不太方便:

https://kb.hilscher.com/display/CIFXDRV/Physical+Memory+Viewer+for+Windows

在 XP 和 Win7x64 试验了,能够查看物理内存的内容。

Win7x64 下还可以查看超过 4G 的高位内存。

谁能试试,看看在 XP (32 位)之下能否查看高于 4G 的物理内存地址的内容?

(点击上面的网址,下载原网站上的文件,不需要币值)

sp_star 发表于 2018-2-12 14:03:28

这个工具是.net的,没运行起来。可以试试读取0~1M的内存,看看grub4dos的信息能不能找到。
里面还有个physmem.sys驱动,好像签名齐全啊,只是不知道怎么用。

不点 发表于 2018-2-12 15:32:34

sp_star 发表于 2018-2-12 14:03
这个工具是.net的,没运行起来。可以试试读取0~1M的内存,看看grub4dos的信息能不能找到。
里面还有个phys ...

试验过了,完全能读出物理内存啊。

只需验证 XP 下能否读高位内存即可。Win7x64 已经验证成功。

sp_star 发表于 2018-2-12 16:31:18

不点 发表于 2018-2-12 15:32
试验过了,完全能读出物理内存啊。

只需验证 XP 下能否读高位内存即可。Win7x64 已经验证成功。

grub4dos的信息应该是在低位内存吧? 即使实际磁盘在高位内存,也要靠imdisk去处理。如果知道ramdisk在内存中的地址和大小,imdisk能直接映射吗?

不点 发表于 2018-2-12 17:02:51

sp_star 发表于 2018-2-12 16:31
grub4dos的信息应该是在低位内存吧? 即使实际磁盘在高位内存,也要靠imdisk去处理。如果知道ramdisk在内 ...

映射物理内存,我觉得不难,imdisk 应该可以做到。

已知 firadisk 和 winvblock 都能访问物理内存。

imdisk 至少能够访问线性地址。

不过,即使 imdisk 不能访问物理地址,也能够给它添加这个功能(从 firadisk 或 winvblock 复制代码即可)。



sp_star 发表于 2018-2-12 17:08:52

不点 发表于 2018-2-12 17:02
映射物理内存,我觉得不难,imdisk 应该可以做到。

已知 firadisk 和 winvblock 都能访问物理内存。


关键是改了驱动就没有签名了啊。
不然,直接修改firadisk 或 winvblock就可以了。当然这2个本来也没签名。

不点 发表于 2018-2-12 17:27:36

sp_star 发表于 2018-2-12 17:08
关键是改了驱动就没有签名了啊。
不然,直接修改firadisk 或 winvblock就可以了。当然这2个本来也没签名 ...

确实是个问题。可以提交给原作者进行签名。

再有就是,干脆就增强 firadisk 或 winvblock 也行。

哪个途径容易编译,就采用那个途径。具体编译的人,看情况决定。

我估计,firadisk 的功能最完善。

firadisk 支持高位内存,winvblock 不支持。
firadisk 和 winvblock 支持物理内存,而 imdisk (有可能)不支持。
winvblock 和 imdisk 支持纯扇区序列,而 firadisk 不支持。

总体感觉,firadisk 毛病不严重,其毛病容易解决。

不点 发表于 2018-2-12 18:45:44

我在 win7 下安装了 Visual Studio 2017,结果不能编译任何程序。它要求操作系统是 Win10。

难度太大,这个帖子的讨论,我就不再来了,抱歉。有兴趣者,你们可以继续。


chenall 发表于 2018-2-12 20:46:18

本帖最后由 chenall 于 2018-2-12 20:47 编辑

我也是用windows 7的安装了vs 2017可以正常使用呀,编译驱动还需要安装winddk.我之前有测试编译imdisk,编译没有通过,应该还需要做一些设置.

没有编译过驱动,搞不懂如何编译,我看了imdisk的源码介绍,应该是可以直接用nmake编译的,不过还是失败了.有一些报错.


也许你可以把这些需求到reboot回复给作者看看他能不能直接加上.毕竟我们如果自己要编译的话那个签名就是一个大麻烦.

不点 发表于 2018-2-12 22:33:50

chenall 发表于 2018-2-12 20:46
我也是用windows 7的安装了vs 2017可以正常使用呀,编译驱动还需要安装winddk.我之前有测试编译imdisk,编 ...

能力有限,精力、时间、身体都不允许。放弃。也不会再去英文论坛给别人解释什么了,我的英文太 poor,费劲。

有难度的事情,我一下子都失去信心了。

顺其自然,谁愿意干啥就干啥。不勉强自己,也不勉强别人。

一切皆缘分,没办法。有缘和没缘。最后还是得老老实实在 Linux 下捣鼓。


不点 发表于 2018-2-12 22:56:54

本帖最后由 不点 于 2018-2-12 22:58 编辑

谁能编译这一句,就算成功:

MmMapIoSpace(0, 0, 0);

firadisk 和 winvblock 都使用了这个 API。如果编译成功,修改一下,就能把物理内存 dump 出来。

只要能 dump 出物理内存,事情就简单了。我们现在就卡在不能访问物理内存上了。

前面的那个闭源软件能够访问物理内存,可惜是闭源的。

在网上搜了许多天,也见不到一个能够在(新近的) Windows 下 dump 物理内存的开源工具。前面介绍的那个开源的工具只能在 xp 上运行。

苏州本是 发表于 2018-2-12 23:44:17

dos时代菜鸟 发表于 2018-1-28 09:38
vbs脚本

谢谢分享好东西!

527104427 发表于 2018-2-13 00:04:17

chenall 发表于 2018-2-12 20:46
我也是用windows 7的安装了vs 2017可以正常使用呀,编译驱动还需要安装winddk.我之前有测试编译imdisk,编 ...




我以前编译成功过,记得是用WDK 7.1.0,貌似不用改什么东西啊。






sp_star 发表于 2018-2-25 11:03:13

一个小工具,在windows下读GRUB4DOS map的磁盘信息。

不点 发表于 2018-2-25 11:42:43

sp_star 发表于 2018-2-25 11:03
一个小工具,在windows下读GRUB4DOS map的磁盘信息。

前面有个闭源的工具可以显示出物理内存。

既然你能读 map 信息,想必你一定也能 cat 出物理内存。你能否写个工具,显示物理内存的内容呢?命令行工具即可,不需要图形界面。最好能 open source。

sp_star 发表于 2018-2-25 12:04:04

不点 发表于 2018-2-25 11:42
前面有个闭源的工具可以显示出物理内存。

既然你能读 map 信息,想必你一定也能 cat 出物理内存。你能 ...

还是使用的Winio驱动,64位时有签名问题。既然有兴趣,自己改改就可以了。

不点 发表于 2018-2-25 13:20:09

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 13:39:35

本帖最后由 不点 于 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>

sp_star 发表于 2018-2-25 14:47:04

不点 发表于 2018-2-25 13:39
Win7x64 下运行失败。出错信息:InitializeWinIo failed!
是必须签名的原因吗?
我没有 32 位 Win7...

64位应该是签名的原因。
由于编译环境,可能不支持xp,我在win10 x86下试过。你可以试试在xp下自己再编译一下。

不点 发表于 2018-2-25 15:34:22

sp_star 发表于 2018-2-25 14:47
64位应该是签名的原因。
由于编译环境,可能不支持xp,我在win10 x86下试过。你可以试试在xp下自己再编 ...

在 Windows 下我没有编译环境,就不试了。
页: 1 [2]
查看完整版本: imdisk支持sector map扇区映射