第一篇写技术的文章哦,以前好少写文章,我的文字表达很差劲,大家不要笑哦.
前几天仙剑4通关了,感觉好惆怅,什么都不想去做.今天看了一下书发现一篇比较好玩的文章,于是自己静静地实践一番.文章是<基于硬盘保留扇区的软件保护方法(作者:熊志勇)>,内容是介绍了怎么读写硬盘保留扇区.以下是我的学习日记.

这里是摘自文章里的一个表:硬盘的总体结构
***********************************************************************
编号       名称                                     备注
1          主引导扇区(含硬盘分区表)            占用一个扇区空间(一个扇区空间为512字节)
2          保留扇区(操作系统不使用的扇区)    占用62个扇区空间
3          第一个分区                              C:盘
4          扩展主引导扇区(含扩展分区表)       一个扇区空间(只有存在扩展分区是才存在)
5          保留扇区                                占用62个扇区空间
6          第2个分区                               D:盘
7          下一个扩展主引导扇区                 只有分区链没结束才存在
8          ......                                    ......
***********************************************************************

通常的软件保护都会向编号为2的保留扇区写一些软件注册信息呀,等等的东西.
而要读写这个没被操作系统利用的部分作者已经给出了代码(幸福呀,不用自己找).

//以下是已经做好的一个函数

BOOL ReadPhysicalSector(unsigned long SectorStart, unsigned long SectorCount, unsigned char *p)

{

unsigned long BytesPerSector = 512;

unsigned long nBytes;

char Drive[] = "////.//PHYSICALDRIVE0";

BOOL result = FALSE;

HANDLE hDeviceHandle = CreateFile(Drive,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,0);

if(hDeviceHandle)

{

long pointer;

long phigh;

pointer = SectorStart;

pointer = pointer*BytesPerSector;

phigh = pointer>>32;

SetFilePointer(hDeviceHandle,(unsigned long)pointer,&phigh,FILE_BEGIN);

if(ReadFile(hDeviceHandle,p,SectorCount*BytesPerSector,&nBytes,NULL))

result = TRUE;

CloseHandle(hDeviceHandle);

}

return result;

}

//调用就这样

int main(int argc, char* argv[])

{

unsigned long SectorStart = 0;//比如我要读的是编号为的那个扇区开始的数据,这里写

//如果读的是从第扇区开始后的数据这里就写

unsigned long SectorCount = 1;//读多少个扇区,这里是个

unsigned char p[512];//一个扇区数据量是字节呀

ReadPhysicalSector(SectorStart, SectorCount, p);

for(int i=0;i<512;i++)//输出的

{

printf("%02X ",p[i]);

if(i%26==0)

printf(" ");

}

return 0;

}

以上的代码都是读的,那如果要写就把ReadFile改成WriteFile呀.要注意的是别乱写了分区表了,很难恢复的.小心用WriteFile呀.

以上的我就实现了,其实也是抄人家的代码,5555555没意思,突然间想把这些功能用驱动来实现.
想就快呀,第一时间上网找ZwWriteFile,ZwReadFile的使用啦,想不到在baidu搜的都是怎么hook ZwWriteFile,ZwReadFile他们的文章,555555那个简单啦,不就改改SSDT然后自己定义函数嘛.
但是......ZwWriteFile,ZwReadFile怎么用的文章几乎没有的.天呀!好惨!

接着我看好久的DDK文档,看了很久ZwWriteFile,ZwReadFile的函数原型,就一步步写出以下的代码出来,经过了n的n次方次的失败后终于......成功读取了第一个扇区的数据了.

#include<ntddk.h>

//--------------------------------------------------------------------

VOID ReadPhysicalSector(unsigned long SectorCount, unsigned char *p)

{

unsigned long BytesPerSector = 512;

WCHAR* name = L"//??//PHYSICALDRIVE0";//这个找了好久呀,原来要这样写的

NTSTATUS ntStatus;

HANDLE hDeviceHandle;

IO_STATUS_BLOCK IoStatusBlock;

IO_STATUS_BLOCK IoStatusBlockR;

OBJECT_ATTRIBUTES ObjectAttributesL;

UNICODE_STRING UniFileNameL;

LARGE_INTEGER ByteOffset;

RtlInitUnicodeString(&UniFileNameL,name);

InitializeObjectAttributes( &ObjectAttributesL,

&UniFileNameL,

OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,

NULL,

NULL);

ntStatus = ZwCreateFile(&hDeviceHandle,

GENERIC_READ,

&ObjectAttributesL,

&IoStatusBlock,

NULL,

0,

FILE_SHARE_READ,

FILE_OPEN,

FILE_SYNCHRONOUS_IO_ALERT,

NULL,

0);

if( NT_SUCCESS(ntStatus) )

{

DbgPrint("Open Success");

ByteOffset.LowPart = FILE_USE_FILE_POINTER_POSITION;

ByteOffset.HighPart = -1;

ntStatus = ZwReadFile(  hDeviceHandle,

NULL,

NULL,

NULL,

&IoStatusBlockR,

p,

SectorCount*BytesPerSector,

&ByteOffset,

NULL);

if( NT_SUCCESS(ntStatus) )

{

DbgPrint("Read Success");

}

}

ZwClose(hDeviceHandle);

}

//--------------------------------------------------------------------

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)

{

DbgPrint("     88  ");

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)

{

unsigned long SectorCount = 1;

unsigned char p[512];

int i;

DriverObject->DriverUnload = OnUnload;

DbgPrint("Hi");

ReadPhysicalSector(SectorCount, p);

for(i=0;i<512;i++)

DbgPrint("%02X ",p[i]);

return STATUS_SUCCESS;

}

终于读取成功了,写就Read改成Write呀,哎....其实我都是刚刚学什么都不会,看了好久DDK文档才挤出上面几行代码.....但是现在我最不明白的就是ZwReadFile中怎么定位指针的位置呢,比如我想在第2个扇区开始读应该怎么写呢?55555555不想啦,很烦啊.....有高手路过就批一下啦,最好教一下我.

好啦今天一起床,想了想,又看了看DDK终于将以上的问题解决了,可以任意读取某一个扇区了~~~~~~~~~~~心情当然非常激动啦~~~啦~~~啦~

原来错误就在这两句里面,DDK误导人的,还是我的英文差呢~~~~~~好啦~~~其实DDK是这么说的:

ByteOffset

Pointer to a variable that specifies the starting byte offset in the file where the read operation will begin. If an attempt is made to read beyond the end of the file, ZwReadFile returns an error.

If the call to ZwCreateFile set either of the CreateOptions flags FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT, the I/O Manager maintains the current file position. If so, the caller ofZwReadFile can specify that the current file position offset be used instead of an explicit ByteOffset value. This specification can be made by using one of the following methods:

● Specify a pointer to a LARGE_INTEGER value with the HighPart member set to -1 and the LowPartmember set to the system-defined value FILE_USE_FILE_POINTER_POSITION.

● Pass a NULL pointer for ByteOffset.

ZwReadFile updates the current file position by adding the number of bytes read when it completes the read operation, if it is using the current file position maintained by the I/O Manager.

Even when the I/O Manager is maintaining the current file position, the caller can reset this position by passing an explicit ByteOffset value to ZwReadFile. Doing this automatically changes the current file position to that ByteOffset value, performs the read operation, and then updates the position according to the number of bytes actually read. This technique gives the caller atomic seek-and-read service.

//今天不按照它说的来做,

ByteOffset.LowPart = FILE_USE_FILE_POINTER_POSITION;

ByteOffset.HighPart = -1;

//改成:

ByteOffset.QuadPart = //第几个字节;

//终于成功了:

代码如下:

#include<ntddk.h>

//--------------------------------------------------------------------

VOID ReadPhysicalSector(unsigned long SectorStart,unsigned long SectorCount,unsigned char *p)

{

unsigned long BytesPerSector = 512;

WCHAR* name = L"//??//PHYSICALDRIVE0";//这个找了好久呀,原来要这样写的

NTSTATUS ntStatus;

HANDLE hDeviceHandle;

IO_STATUS_BLOCK IoStatusBlock;

IO_STATUS_BLOCK IoStatusBlockR;

OBJECT_ATTRIBUTES ObjectAttributesL;

UNICODE_STRING UniFileNameL;

LARGE_INTEGER ByteOffset;

RtlInitUnicodeString(&UniFileNameL,name);

InitializeObjectAttributes( &ObjectAttributesL,

&UniFileNameL,

OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,

NULL,

NULL);

ntStatus = ZwCreateFile(&hDeviceHandle,

GENERIC_READ,

&ObjectAttributesL,

&IoStatusBlock,

NULL,

0,

FILE_SHARE_READ,

FILE_OPEN,

FILE_SYNCHRONOUS_IO_ALERT,

NULL,

0);

if( NT_SUCCESS(ntStatus) )

{

DbgPrint("Open Success");

//      ByteOffset.LowPart = FILE_USE_FILE_POINTER_POSITION;

//      ByteOffset.HighPart = -1;不要用这两句换成下面一句,DDK误导人啊~~~~~

ByteOffset.QuadPart = SectorStart*BytesPerSector;//是这句了

ntStatus = ZwReadFile(  hDeviceHandle,

NULL,

NULL,

NULL,

&IoStatusBlockR,

p,

SectorCount*BytesPerSector,

&ByteOffset,

NULL);

if( NT_SUCCESS(ntStatus) )

{

DbgPrint("Read Success");

}

}

ZwClose(hDeviceHandle);

}

//--------------------------------------------------------------------

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)

{

DbgPrint("     88  ");

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)

{

unsigned long SectorStart = 63;//现在是读扇区啦

unsigned long SectorCount = 1;

unsigned char p[512];

int i;

DriverObject->DriverUnload = OnUnload;

DbgPrint("Hi");

ReadPhysicalSector(SectorStart ,SectorCount, p);

for(i=0;i<512;i++)

DbgPrint("%02X ",p[i]);

return STATUS_SUCCESS;

}

http://blog.csdn.net/cooblily/article/details/1737703

WIN32和Kernel)直接读写硬盘扇区的更多相关文章

  1. linux2.6硬盘扇区直接读写程序

    下面的程序可以在linux2.6内核直接读写硬盘的指定扇区,也是根据网上一个朋友的做法做了修改的: 有两个不是很明白的地方就是:1.bd_claim函数的使用,这个是个递归函数,像是匹配内存指针和设备 ...

  2. [转]Linux中如何读写硬盘上指定物理扇区

    读指定物理扇区: dd  if=<源设备>  of=<输出设备或文件>   skip=<指定扇区值>  bs=512 count=1 写指定物理扇区: dd   i ...

  3. cpu指令如何读写硬盘

    我们提到cpu的主要作用之一就是控制设备之间的数据交互.这其中自然也包括了硬盘.系统的所有数据基本都在硬盘中,所以知道怎么读写硬盘,对程序来说非常重要,所以我们先来探索下传说中的pio模式. cpu要 ...

  4. Android 怎样在linux kernel 中读写文件

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  5. 分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)

    分配粒度和内存页面大小 x86处理器平台的分配粒度是64K,32位CPU的内存页面大小是4K,64位是8K,保留内存地址空间总是要和分配粒度对齐.一个分配粒度里包含16个内存页面. 这是个概念,具体不 ...

  6. 使用CreateFile, ReadFile, WriteFile在Windows NT/2000/XP下读写绝对扇区的方法

    也就是在CreateFile的时候打开文件名指定: "\\.\Device"就可以了. 因为代码比较短, 所以我不做注释, 相信大家看代码就能明白意思了. 另外这里读写的都是软盘A ...

  7. 使用Python学习win32库进行内存读写

    前言: 上一周,在52的精华帖中,看到有位大佬用Python制作了鬼泣5的修改器,看完才知道,原来Python也可以对内存进行操作,出于对技术的好奇,看完以后,决定自己也尝试一下. 要用到的工具: C ...

  8. 不同WINDOWS平台下磁盘逻辑扇区的直接读写

    不同WINDOWS平台下磁盘逻辑扇区的直接读写 关键字:VWIN32.中断.DeviceIoControl 一.概述 在DOS操作系统下,通过BIOS的INT13.DOS的INT25(绝对读).INT ...

  9. Linux中硬盘物理扇区与文件系统文件对应关系(转)

    1               概述 系统读写文件过程中,如下面内核打印信息,报告读写某个扇区错误.那么我们如何能够通过sector找到读写哪个文件错误? kernel: end_request: I ...

随机推荐

  1. <转载>解决div里面img的缝隙问题

    转载自:http://blog.sina.com.cn/s/blog_9fd5b6df01013mld.html   练习切图时发现img和父级div之间总是有2px空隙(chrome),上网搜索解决 ...

  2. 关于U3D画面出现卡顿的问题

    在U3D中,曾近遇到过卡顿的问题,下面说明解决方法 一:在关于相机移动的函数中,移动的函数不应该放在Update里面应该放到LateUpdate 二:如果最开始建立项目的时候选择的时候是3D游戏,如果 ...

  3. 使用T4模板为EF框架添加实体根据数据库自动生成字段注释的功能

    转自http://jeffblog.sinaapp.com/archives/501 首先我们先下载一个文件GetSummery,这里我提供了,大家可以直接下载:下载 我们在数据库建立一个表,并给表中 ...

  4. android实现倒计时

    前言  在打开爱奇艺等app的欢迎界面的时候,右上角有一个倒计时的控件.倒计时完了以后进入主界面.现在我们来实现这个功能. 方法一 利用java的类Timer,TimerTask还有android的H ...

  5. DLL中导出STL模板类的问题

    接上一篇. 上一篇的dll在编译过程中一直有一个警告warning C4251: ‘CLASS_TEST::m_structs’ : class ‘std::vector<_Ty>’ ne ...

  6. 搭建Spring、Spring MVC、Mybatis和Freemarker

    搭建Spring.Spring MVC.Mybatis和Freemarker 1.pom文件 <project xmlns="http://maven.apache.org/POM/4 ...

  7. 三、使用Maven构建简单的java项目

    前边,我刚搭建了Maven环境,还有给大家推荐了学习资源,这个小节,我们来就来,,简单的玩玩maven. 1.所需工具: 1.Eclipse     2.apache-maven-3.3.9   3. ...

  8. C#下如何用NPlot绘制期货股票K线图(3):设计要显示的股票价格图表窗口并定义相应类的成员及函数

    [内容简介] 上一篇介绍了要显示K线图所需要的数据结构,及要动态显示K线图,需要动态读取数据文件必需的几个功能函数.本篇介绍要显示蜡烛图所用到的窗口界面设计及对应类定义.下面分述如下: [窗口界面] ...

  9. java之内存管理

    对于JVM的垃圾回收机制来说,是否回收一个对象的标准在于:是否还有引用变量引用该对象,只要有引用变量引用该对象,垃圾回收机制就不会回收它. 强引用:创建一个对象,并把这个对象赋给一个引用变量.这种引用 ...

  10. 关于C++对汉字拼音的处理(2)

    对于前面获取字符串汉字全拼音的功能,大家应该有个了解了.现在我又综合广大网友流传的获取字符串汉字拼音首字母的功能进行了整理.介绍如下 这个功能写的稍微有点复杂 使用3个函数解决了获取字符串汉字首拼音串 ...