怎样实现读磁盘或硬盘的物理扇区?难道没有高手知道? (50分)

  • 主题发起人 主题发起人 kenwoo
  • 开始时间 开始时间
K

kenwoo

Unregistered / Unconfirmed
GUEST, unregistred user!
怎样实现读磁盘或硬盘的物理扇区?难道没有高手知道?
 
好象有这么一个程序源码,找找。
 
好像要用汇编,不太清楚,关注
 
请研究如下的源代码,本人在一个系统中修改在VC++编译成dll文件在delphi中调用,
有时会死机。

;* ; ; Windows 95加密软件核心模块之一--磁盘扇区大小修改程序以及V86 内存分 *
;* 配与释放函数。 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; *
;****************************************************************************

.386p

.model flat,stdcall

;修改的中断号,如果本中断号改成3则可以防止Soft-ICE跟踪!

HookExceptionNo EQU 05h

;****************************************************************************
;* cb_s结构说明(VMM.INC文件中有) ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;*
;* ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;*
;* cb_s ; ;struc ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;*
;* CB_VM_Status ; ; ; ;dd ; ? ;; VM status; see below ; ; ; ; ; ; ; ; ; ; ; *
;* CB_High_Linear ; ; ;dd ; ? ;; base linear address; see below ; ; ; ; ; ; *
;* CB_Client_Pointer ; dd ; ? ;; see below ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;*
;* CB_VMID ; ; ; ; ; ; dd ; ? ;; virtual machine ID ; ; ; ; ; ; ; ; ; ; ; ; *
;* CB_Signature ; ; ; ;dd ; ? ;; see below ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;*
;* cb_s ; ;ends ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; *
;****************************************************************************

.data
; ; ; ; IDTR_1 db 6 dup(0) ;保存中断描述符表寄存器
; ; ; ; OldExceptionHook dd 0 ;保存原先的中断入口地址

.code

;修改扇区大小过程

;VC原型:void _stdcall ChangeSectorSize(BYTE SectorSize);

ChangeSectorSize PROC SectorSize:BYTE
; ; ; ; push eax
; ; ; ; ;获取修改的中断的中断描述符(中断门)地址
; ; ; ; sidt IDTR_1
; ; ; ; mov eax,dword ptr IDTR_1+02h
; ; ; ; add eax,HookExceptionNo*08h+04h
; ; ; ; cli
; ; ; ; ;保存原先的中断入口地址
; ; ; ; push ecx
; ; ; ; mov ecx,dword ptr [eax]
; ; ; ; mov cx,word ptr [eax-04h]
; ; ; ; mov dword ptr OldExceptionHook,ecx
; ; ; ; pop ecx
; ; ; ; ;设置修改的中断入口地址为新的中断处理程序1 入口地址
; ; ; ; push ebx
; ; ; ; lea ebx,NewExceptionHook1
; ; ; ; mov word ptr [eax-04h],bx
; ; ; ; shr ebx,10h
; ; ; ; mov word ptr [eax+02h],bx
; ; ; ; pop ebx
; ; ; ; ;执行中断,转到Ring 0(与CIH 病毒原理相似!)
; ; ; ; push ebx
; ; ; ; mov bl,byte ptr SectorSize ;扇区大小保存在bl寄存器中
; ; ; ; int HookExceptionNo
; ; ; ; pop ebx
; ; ; ; ;恢复原先的中断入口地址
; ; ; ; push ecx
; ; ; ; mov ecx,dword ptr OldExceptionHook
; ; ; ; mov word ptr [eax-04h],cx
; ; ; ; shr ecx,10h
; ; ; ; mov word ptr [eax+02h],cx
; ; ; ; pop ecx
; ; ; ; ;修改扇区大小过程结束
; ; ; ; sti
; ; ; ; pop eax
; ; ; ; ret
ChangeSectorSize ENDP

;分配V86内存过程

;VC原型:DWORD _stdcall V86AllocBuffer(DWORD FarPtrMem,BYTE SectorSize);

V86AllocateBuffer PROC FarPtrMem:DWORD,SectorSize:BYTE
; ; ; ; push edi
; ; ; ; ;获取修改的中断的中断描述符(中断门)地址
; ; ; ; sidt IDTR_1
; ; ; ; mov eax,dword ptr IDTR_1+02h
; ; ; ; add eax,HookExceptionNo*08h+04h
; ; ; ; cli
; ; ; ; ;保存原先的中断入口地址
; ; ; ; push ecx
; ; ; ; mov ecx,dword ptr [eax]
; ; ; ; mov cx,word ptr [eax-04h]
; ; ; ; mov dword ptr OldExceptionHook,ecx
; ; ; ; pop ecx
; ; ; ; ;设置修改的中断入口地址为新的中断处理程序2 入口地址
; ; ; ; push ebx
; ; ; ; lea ebx,NewExceptionHook2
; ; ; ; mov word ptr [eax-04h],bx
; ; ; ; shr ebx,10h
; ; ; ; mov word ptr [eax+02h],bx
; ; ; ; pop ebx
; ; ; ; ;执行中断,转到Ring 0(与CIH 病毒原理相似!)
; ; ; ; push edx
; ; ; ; push esi
; ; ; ; push fs
; ; ; ; mov dx,ds
; ; ; ; mov fs,dx
; ; ; ; mov esi,dword ptr FarPtrMem ;内存指针保存在fs:esi寄存器中
; ; ; ; mov dl,byte ptr SectorSize ;扇区大小保存在dl寄存器中
; ; ; ; int HookExceptionNo
; ; ; ; pop fs
; ; ; ; pop esi
; ; ; ; pop edx
; ; ; ; ;恢复原先的中断入口地址
; ; ; ; push ecx
; ; ; ; mov ecx,dword ptr OldExceptionHook
; ; ; ; mov word ptr [eax-04h],cx
; ; ; ; shr ecx,10h
; ; ; ; mov word ptr [eax+02h],cx
; ; ; ; pop ecx
; ; ; ; ;分配V86内存过程结束
; ; ; ; sti
; ; ; ; mov eax,edi
; ; ; ; pop edi
; ; ; ; ret
V86AllocateBuffer ENDP

;释放V86内存过程

;VC原型:void _stdcall V86FreeBuffer(DWORD FarPtrMem,BYTE SectorSize);

V86FreeBuffer PROC FarPtrMem:DWORD,SectorSize:BYTE
; ; ; ; push eax
; ; ; ; ;获取修改的中断的中断描述符(中断门)地址
; ; ; ; sidt IDTR_1
; ; ; ; mov eax,dword ptr IDTR_1+02h
; ; ; ; add eax,HookExceptionNo*08h+04h
; ; ; ; cli
; ; ; ; ;保存原先的中断入口地址
; ; ; ; push ecx
; ; ; ; mov ecx,dword ptr [eax]
; ; ; ; mov cx,word ptr [eax-04h]
; ; ; ; mov dword ptr OldExceptionHook,ecx
; ; ; ; pop ecx
; ; ; ; ;设置修改的中断入口地址为新的中断处理程序3 入口地址
; ; ; ; push ebx
; ; ; ; lea ebx,NewExceptionHook3
; ; ; ; mov word ptr [eax-04h],bx
; ; ; ; shr ebx,10h
; ; ; ; mov word ptr [eax+02h],bx
; ; ; ; pop ebx
; ; ; ; ;执行中断,转到Ring 0(与CIH 病毒原理相似!)
; ; ; ; push edx
; ; ; ; push esi
; ; ; ; push fs
; ; ; ; mov dx,ds
; ; ; ; mov fs,dx
; ; ; ; mov esi,dword ptr FarPtrMem ;内存指针保存在fs:esi寄存器中
; ; ; ; mov dl,byte ptr SectorSize ;扇区大小保存在dl寄存器中
; ; ; ; int HookExceptionNo
; ; ; ; pop fs
; ; ; ; pop esi
; ; ; ; pop edx
; ; ; ; ;恢复原先的中断入口地址
; ; ; ; push ecx
; ; ; ; mov ecx,dword ptr OldExceptionHook
; ; ; ; mov word ptr [eax-04h],cx
; ; ; ; shr ecx,10h
; ; ; ; mov word ptr [eax+02h],cx
; ; ; ; pop ecx
; ; ; ; ;释放V86内存过程结束
; ; ; ; sti
; ; ; ; pop eax
; ; ; ; ret
V86FreeBuffer ENDP

;新的中断处理程序1

NewExceptionHook1 PROC
; ; ; ; push eax
; ; ; ; push ebx
; ; ; ; push ecx
; ; ; ; push edx
; ; ; ; push esi
; ; ; ; ;修改扇区大小
; ; ; ; push dword ptr 00000000h ;必须为0
; ; ; ; push dword ptr 00000001h ;字节数
; ; ; ; push dword ptr 00000525h ;物理地址0000:0525
; ; ; ; int 20h
; ; ; ; dd 0001006ch ;以上两条指令相当于 VMMCall _MapPhysToLinear
; ; ; ; pop esi
; ; ; ; pop esi
; ; ; ; pop esi
; ; ; ; mov byte ptr [eax],bl ;修改扇区大小
; ; ; ; ;中断处理程序结束
; ; ; ; pop esi
; ; ; ; pop edx
; ; ; ; pop ecx
; ; ; ; pop ebx
; ; ; ; pop eax
; ; ; ; iretd
NewExceptionHook1 ENDP

;新的中断处理程序2

NewExceptionHook2 PROC
; ; ; ; push eax
; ; ; ; push ebx
; ; ; ; push ecx
; ; ; ; push ebp
; ; ; ; ;获取当前VM句柄
; ; ; ; int 20h
; ; ; ; dd 00010001h ;以上两条指令相当于 VMMCall Get_Cur_VM_Handle
; ; ; ; ;获取Client_Reg_Struc结构地址
; ; ; ; mov ebp,dword ptr [ebx+08h]
; ; ; ; ;分配V86内存
; ; ; ; movzx eax,dl
; ; ; ; xor ecx,ecx
; ; ; ; bts ecx,eax
; ; ; ; shl ecx,7
; ; ; ; mov eax,ecx
; ; ; ; stc
; ; ; ; int 20h
; ; ; ; dd 00060008h ;以上两条指令相当于 VxDCall V86MMGR_Allocate_Buffer
; ; ; ; jc Error_Handler1
; ; ; ; cmp eax,ecx
; ; ; ; jnz Error_Handler2
; ; ; ; jmp ExceptionHook_End1
Error_Handler1:
; ; ; ; ;V86内存分配错误处理1(分配失败)
; ; ; ; xor edi,edi
; ; ; ; jmp ExceptionHook_End1
Error_Handler2:
; ; ; ; ;V86内存分配错误处理2(内存不够)
; ; ; ; clc
; ; ; ; int 20h
; ; ; ; dd 00060009h ;以上两条指令相当于 VxDCall V86MMGR_Free_Buffer
; ; ; ; xor edi,edi
ExceptionHook_End1:
; ; ; ; ;中断处理程序结束
; ; ; ; pop ebp
; ; ; ; pop ecx
; ; ; ; pop ebx
; ; ; ; pop eax
; ; ; ; iretd
NewExceptionHook2 ENDP

;新的中断处理程序3

NewExceptionHook3 PROC
; ; ; ; push eax
; ; ; ; push ebx
; ; ; ; push ecx
; ; ; ; push ebp
; ; ; ; ;获取当前VM句柄
; ; ; ; int 20h
; ; ; ; dd 00010001h ;以上两条指令相当于 VMMCall Get_Cur_VM_Handle
; ; ; ; ;获取Client_Reg_Struc结构地址
; ; ; ; mov ebp,dword ptr [ebx+08h]
; ; ; ; ;释放V86内存
; ; ; ; movzx eax,dl
; ; ; ; xor ecx,ecx
; ; ; ; bts ecx,eax
; ; ; ; shl ecx,7
; ; ; ; stc
; ; ; ; int 20h
; ; ; ; dd 00060009h ;以上两条指令相当于 VxDCall V86MMGR_Free_Buffer
; ; ; ; ;中断处理程序结束
; ; ; ; pop ebp
; ; ; ; pop ecx
; ; ; ; pop ebx
; ; ; ; pop eax
; ; ; ; iretd
NewExceptionHook3 ENDP

end

//获取KERNEL32.DLL引出函数指针(防止Microsoft Anti-Hacking代码)

#include <windows.h>
#include "getk32pa.h"

typedef struct {
DWORD Signature;
//IMAGE_FILE_HEADER FileHeader;
WORD ; ;Machine;
WORD ; ;NumberOfSections;
DWORD ; TimeDateStamp;
DWORD ; PointerToSymbolTable;
DWORD ; NumberOfSymbols;
WORD ; ;SizeOfOptionalHeader;
WORD ; ;Characteristics;
//IMAGE_OPTIONAL_HEADER OptionalHeader;
WORD ; ;Magic;
BYTE ; ;MajorLinkerVersion;
BYTE ; ;MinorLinkerVersion;
DWORD ; SizeOfCode;
DWORD ; SizeOfInitializedData;
DWORD ; SizeOfUninitializedData;
DWORD ; AddressOfEntryPoint;
DWORD ; BaseOfCode;
DWORD ; BaseOfData;
DWORD ; ImageBase;
DWORD ; SectionAlignment;
DWORD ; FileAlignment;
WORD ; ;MajorOperatingSystemVersion;
WORD ; ;MinorOperatingSystemVersion;
WORD ; ;MajorImageVersion;
WORD ; ;MinorImageVersion;
WORD ; ;MajorSubsystemVersion;
WORD ; ;MinorSubsystemVersion;
DWORD ; Win32VersionValue;
DWORD ; SizeOfImage;
DWORD ; SizeOfHeaders;
DWORD ; CheckSum;
WORD ; ;Subsystem;
WORD ; ;DllCharacteristics;
DWORD ; SizeOfStackReserve;
DWORD ; SizeOfStackCommit;
DWORD ; SizeOfHeapReserve;
DWORD ; SizeOfHeapCommit;
DWORD ; LoaderFlags;
DWORD ; NumberOfRvaAndSizes;
//IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
DWORD ; EXPORT_VirtualAddress;
DWORD ; EXPORT_Size;
DWORD ; IMPORT_VirtualAddress;
DWORD ; IMPORT_Size;
DWORD ; RESORC_VirtualAddress;
DWORD ; RESORC_Size;
DWORD ; EXCEPT_VirtualAddress;
DWORD ; EXCEPT_Size;
DWORD ; SECURT_VirtualAddress;
DWORD ; SECURT_Size;
} PE;

FARPROC GetKernel32ProcAddress(DWORD OrdValue)
{
DWORD hModule;
PE *Hdr;
IMAGE_EXPORT_DIRECTORY *Exp;
PDWORD AddrFunc;
hModule=(DWORD)GetModuleHandle("KERNEL32");
Hdr=(PE *)(hModule+(*(PWORD)(hModule+0x3c)));
if(*(PDWORD)(Hdr)!=0x4550) return NULL;
Exp=(IMAGE_EXPORT_DIRECTORY *)(hModule+Hdr->EXPORT_VirtualAddress);
AddrFunc=(PDWORD)(hModule+(DWORD)Exp->AddressOfFunctions);
OrdValue--;
if(OrdValue<Exp->NumberOfFunctions)
return (FARPROC)(hModule+AddrFunc[OrdValue]);
else
return NULL;
}

//获取KERNEL32.DLL引出函数指针(防止Microsoft Anti-Hacking代码)

#ifdef __cplusplus

extern "C"
{
FARPROC GetKernel32ProcAddress(DWORD OrdValue);
}

#else

FARPROC GetKernel32ProcAddress(DWORD OrdValue);

#endif

/**********************************************************/
/* ; ; Windows 95加密软件核心模块之二——密钥判读程序 ; ; */
/**********************************************************/

#include <windows.h>
#include "w95enc.h"
#include "getk32pa.h"

//W95ENC.ASM汇编模块过程在VC中的函数原型

void _stdcall ChangeSectorSize(BYTE SectorSize);
DWORD _stdcall V86AllocateBuffer(DWORD FarPtrMem,BYTE SectorSize);
void _stdcall V86FreeBuffer(DWORD FarPtrMem,BYTE SectorSize);

static FARPROC VxDCall;

//实模式寄存器结构

typedef struct {
DWORD Reg_EDI;
DWORD Reg_ESI;
DWORD Reg_EBP;
DWORD Reserve;
DWORD Reg_EBX;
DWORD Reg_EDX;
DWORD Reg_ECX;
DWORD Reg_EAX;
WORD Reg_Flags;
WORD Reg_ES;
WORD Reg_DS;
WORD Reg_FS;
WORD Reg_GS;
WORD Reg_IP;
WORD Reg_CS;
WORD Reg_SP;
WORD Reg_SS;
} REAL_MODE_REGS;

DWORD Win95DiskEncryption(BYTE Head,BYTE Track,BYTE Sector,BYTE SectorSize,void *Buffer)
{
REAL_MODE_REGS Reg1;
DWORD V86Ptr1;
DWORD RegPtr1;
int BufSize;
int Sch1,Sch2;
//获取未公开API函数VxDCall的入口地址
if(!(VxDCall=GetKernel32ProcAddress(1))) return 0;
//缓冲区初始化
BufSize=(1<<(7+SectorSize));
for(Sch1=0;Sch1<BufSize;Sch1++) *((BYTE *)Buffer+Sch1)=0;
//分配V86 内存
if(!(V86Ptr1=V86AllocateBuffer((DWORD)Buffer,SectorSize))) return 0;
for(Sch2=0;Sch2<3;Sch2++)
{
Reg1.Reg_EAX=0x0201;
Reg1.Reg_EBX=(DWORD)LOWORD(V86Ptr1);
Reg1.Reg_ECX=(DWORD)MAKEWORD(Sector,Track);
Reg1.Reg_EDX=(DWORD)MAKEWORD(0,Head);
Reg1.Reg_ES=HIWORD(V86Ptr1);
RegPtr1=(DWORD)&Reg1;
//修改加密扇区大小
ChangeSectorSize(SectorSize);
_asm
{
mov bx,0013h
mov edi,RegPtr1
}
//调用DPMI功能,模拟INT 13H。
VxDCall(0x002a0029,0x0300,0);
//恢复加密扇区大小
ChangeSectorSize(2);
}
//释放V86 内存
V86FreeBuffer((DWORD)Buffer,SectorSize);
//返回EAX 寄存器的值
return Reg1.Reg_EAX;
}

#ifdef __cplusplus

extern "C"
{
DWORD Win95DiskEncryption(BYTE Head,BYTE Track,BYTE Sector,BYTE SectorSize,void *Buffer);
}

#else

DWORD Win95DiskEncryption(BYTE Head,BYTE Track,BYTE Sector,BYTE SectorSize,void *Buffer);

#endif

//Windows 95加密软件测试程序

#include <windows.h>
#include "tchar.h"
#include "w95enc.h"

static TCHAR szAppName[]=_T("ENTEST");

LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam);
BOOL DiskEncryptionTest(void); //加密磁盘测试函数

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wcex;
MSG Msg;
//本程序不能在Windows NT中运行
if(GetVersion()<0x80000000)
{
MessageBox(NULL,_T("本程序不能在Windows NT中运行!"),_T("Windows 95加密软件测试程序"),MB_ICONINFORMATION|MB_OK);
return FALSE;
}
//加密磁盘测试
if(!DiskEncryptionTest())
{
MessageBox(NULL,_T("非法拷贝!程序不能运行!"),_T("Windows 95加密软件测试程序"),MB_ICONINFORMATION|MB_OK);
return FALSE;
}
if(!hPrevInstance)
{
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW|CS_VREDRAW;
wcex.lpfnWndProc=WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=NULL;
wcex.lpszClassName=szAppName;
wcex.hIconSm=LoadIcon(hInstance,IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) return FALSE;
}
hWnd=CreateWindow(szAppName,_T("Windows 95加密软件测试程序"),WS_OVERLAPPEDWINDOW,
;CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
;0,0,hInstance,NULL);
if(!hWnd) return FALSE;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&Msg,0,0,0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
switch(Message)
{
case WM_PAINT:
hDC=BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,Message,wParam,lParam);
}
return 0;
}

BOOL DiskEncryptionTest(void)
{
//该函数中有部分注释掉的调试程序
BYTE KeyData[1024];
DWORD Result1;
int Sch1;
int KeySum;
//TCHAR szBuf1[256],szBuf2[256];
//读取0面79磁道18扇区,扇区大小为3(1024字节)
Result1=Win95DiskEncryption(0,79,18,3,KeyData);
//wsprintf(szBuf1,"EAX=%xH",Result1);
//MessageBox(NULL,szBuf1,_T("Windows 95加密软件测试程序"),MB_ICONINFORMATION|MB_OK);
//计算密钥数据校验和
KeySum=0;
for(Sch1=0;Sch1<1024;Sch1++) KeySum=KeySum+KeyData[Sch1];
//wsprintf(szBuf2,"Key data SUM=%d",KeySum);
//MessageBox(NULL,szBuf2,_T("Windows 95加密软件测试程序"),MB_ICONINFORMATION|MB_OK);
//该校验和值与加密磁盘有关,27152是全国计算机等级考试练习盘的校验和。
if(KeySum==27152) return TRUE; else return FALSE;
}
 
接受答案了.
 
后退
顶部