📄 _vflat.asm
字号:
cprocstart InstallBankFunc ARG codeLen:UINT, bankFunc:DPTR enter_c mov esi,[bankFunc] ; Copy the code into buffer mov edi,offset BankFuncBuf mov ecx,[codeLen] rep movsb mov [BYTE edi],0C3h ; Terminate the function with a near ret leave_c retcprocend;----------------------------------------------------------------------------; int InitPaging(void);----------------------------------------------------------------------------; Initializes paging system. If paging is not enabled, builds a page table; directory and page tables for physical memory;; Exit: 0 - Successful; -1 - Couldn't initialize paging mechanism;----------------------------------------------------------------------------cprocstart InitPaging push ebx push ecx push edx push esi push edi; Are we running under CauseWay? mov ax,0FFF9h int 31h jc @@NotCauseway cmp ecx,"CAUS" jnz @@NotCauseway cmp edx,"EWAY" jnz @@NotCauseway mov [BOOL VF_haveCauseWay],1 mov [CauseWayDIRLinear],esi mov [CauseWay1stLinear],edi; Check for DPMI mov ax,0ff00h push es int 31h pop es shr edi,2 and edi,3 cmp edi,2 jz @@ErrExit ; Not supported under DPMI mov eax,[CauseWayDIRLinear] jmp @@CopyCR3@@NotCauseway: mov ax,cs test ax,3 ; Which ring are we running jnz @@ErrExit ; Needs zero ring to access ; page tables (CR3) mov eax,cr0 ; Load CR0 test eax,80000000h ; Is paging enabled? jz @@ErrExit ; No, we must have paging! mov eax,cr3 ; Load directory address and eax,0FFFFF000h@@CopyCR3: mov [PDBR],eax ; Save it mov esi,eax mov edi,offset pageDirectory mov ecx,1024 cld rep movsd ; Copy the original page table directory cmp [DWORD accessPageAddr],0; Check if we have allocated page jne @@HaveRealMem ; table already (we cant free it) mov eax,0100h ; DPMI DOS allocate mov ebx,8192/16 int 31h ; Allocate 8192 bytes and eax,0FFFFh shl eax,4 ; EAX points to newly allocated memory add eax,4095 and eax,0FFFFF000h ; Page align mov [accessPageAddr],eax@@HaveRealMem: mov eax,[accessPageAddr] ; EAX -> page table in 1st Mb shr eax,12 and eax,3FFh ; Page table offset shl eax,2 cmp [BOOL VF_haveCauseWay],0 jz @@NotCW0 mov ebx,[CauseWay1stLinear] jmp @@Put1st@@NotCW0: mov ebx,[PDBR] mov ebx,[ebx] and ebx,0FFFFF000h ; Page table for 1st megabyte@@Put1st: add eax,ebx mov [accessPageTable],eax sub eax,eax ; No error jmp @@Exit@@ErrExit: mov eax,-1@@Exit: pop edi pop esi pop edx pop ecx pop ebx retcprocend;----------------------------------------------------------------------------; void ClosePaging(void);----------------------------------------------------------------------------; Closes the paging system;----------------------------------------------------------------------------cprocstart ClosePaging push eax push ecx push edx push esi push edi mov eax,[accessPageAddr] call AccessPage ; Restore AccessPage mapping mov edi,[PDBR] mov esi,offset pageDirectory mov ecx,1024 cld rep movsd ; Restore the original page table directory@@Exit: pop edi pop esi pop edx pop ecx pop eax retcprocend;----------------------------------------------------------------------------; long AccessPage(long phys);----------------------------------------------------------------------------; Maps a known page to given physical memory; Entry: EAX - Physical memory; Exit: EAX - Linear memory address of mapped phys mem;----------------------------------------------------------------------------cprocstatic AccessPage push edx mov edx,[accessPageTable] or eax,7 mov [edx],eax mov eax,cr3 mov cr3,eax ; Update page table cache mov eax,[accessPageAddr] pop edx retcprocend;----------------------------------------------------------------------------; long GetPhysicalAddress(long linear);----------------------------------------------------------------------------; Returns the physical address of linear address; Entry: EAX - Linear address to convert; Exit: EAX - Physical address;----------------------------------------------------------------------------cprocstatic GetPhysicalAddress push ebx push edx mov edx,eax shr edx,22 ; EDX is the directory offset mov ebx,[PDBR] mov edx,[edx*4+ebx] ; Load page table address push eax mov eax,edx call AccessPage ; Access the page table mov edx,eax pop eax shr eax,12 and eax,03FFh ; EAX offset into page table mov eax,[edx+eax*4] ; Load physical address and eax,0FFFFF000h pop edx pop ebx retcprocend;----------------------------------------------------------------------------; void CreatePageTable(long pageDEntry);----------------------------------------------------------------------------; Creates a page table for specific address (4MB); Entry: EAX - Page directory entry (top 10-bits of address);----------------------------------------------------------------------------cprocstatic CreatePageTable push ebx push ecx push edx push edi mov ebx,eax ; Save address mov eax,8192 push eax call VF_malloc ; Allocate page table directory add esp,4 add eax,0FFFh and eax,0FFFFF000h ; Page align (4KB) mov edi,eax ; Save page table linear address sub eax,eax ; Fill with zero mov ecx,1024 cld rep stosd ; Clear page table sub edi,4096 mov eax,edi call GetPhysicalAddress mov edx,[PDBR] or eax,7 ; Present/write/user bit mov [edx+ebx*4],eax ; Save physical address into page directory mov eax,cr3 mov cr3,eax ; Update page table cache pop edi pop edx pop ecx pop ebx retcprocend;----------------------------------------------------------------------------; void MapPhysical2Linear(ulong pAddr, ulong lAddr, int pages, int flags);;----------------------------------------------------------------------------; Maps physical memory into linear memory; Entry: pAddr - Physical address; lAddr - Linear address; pages - Number of 4K pages to map; flags - Page flags; bit 0 = present; bit 1 = Read(0)/Write(1);----------------------------------------------------------------------------cprocstart MapPhysical2Linear ARG pAddr:ULONG, lAddr:ULONG, pages:UINT, pflags:UINT enter_c and [ULONG pAddr],0FFFFF000h; Page boundary and [ULONG lAddr],0FFFFF000h; Page boundary mov ecx,[pflags] and ecx,11b ; Just two bits or ecx,100b ; Supervisor bit mov [pflags],ecx mov edx,[lAddr] shr edx,22 ; EDX = Directory mov esi,[PDBR] mov edi,[pages] ; EDI page count mov ebx,[lAddr]@@CreateLoop: mov ecx,[esi+edx*4] ; Load page table address test ecx,1 ; Is it present? jnz @@TableOK mov eax,edx call CreatePageTable ; Create a page table@@TableOK: mov eax,ebx shr eax,12 and eax,3FFh sub eax,1024 neg eax ; EAX = page count in this table inc edx ; Next table mov ebx,0 ; Next time we'll map 1K pages sub edi,eax ; Subtract mapped pages from page count jns @@CreateLoop ; Create more tables if necessary mov ecx,[pages] ; ECX = Page count mov esi,[lAddr] shr esi,12 ; Offset part isn't needed mov edi,[pAddr]@@MappingLoop: mov eax,esi shr eax,10 ; EAX = offset to page directory mov ebx,[PDBR] mov eax,[eax*4+ebx] ; EAX = page table address call AccessPage mov ebx,esi and ebx,3FFh ; EBX = offset to page table mov edx,edi add edi,4096 ; Next physical address inc esi ; Next linear page or edx,[pflags] ; Update flags... mov [eax+ebx*4],edx ; Store page table entry loop @@MappingLoop mov eax,cr3 mov cr3,eax ; Update page table cache leave_c retcprocendendcodeseg _vflatendif END ; End of module
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -