- Implement more parts of the GPF Handler.

- Add support for lazy loading.
- QEMU + -kernel-qemu seems to work now.
- Hack away the Win32k bug that's been there for ages (copy to user-mode from kernel-mode failing due to probe due to incorrect previous mode). It's not the right fix, but nobody seems to be willing to fix it, and it doesn't make anything less stable, sicne the actually copy is in SEH anyway. It opens a security vuln. (wow, not like we have 15000) in exchange for fixing dozens of win32k bugs and failures.

svn path=/trunk/; revision=23832
This commit is contained in:
Alex Ionescu 2006-08-31 04:10:33 +00:00
parent e82f58c755
commit d2ba2fdc17
4 changed files with 64 additions and 71 deletions

View file

@ -1,61 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: zeromemory_asm.S
* PURPOSE: Memory functions
* PROGRAMMERS: Patrick Baggett (baggett.patrick@gmail.com)
* Alex Ionescu (alex@relsoft.net)
* Magnus Olsen (magnusolsen@greatlord.com)
*/
.intel_syntax noprefix
/* GLOBALS ****************************************************************/
.globl _RtlZeroMemory@8 // (no bug) (max optimze code)
/* FUNCTIONS ***************************************************************/
_RtlZeroMemory@8:
mov ecx,dword [esp + 8 ] // Length
cmp ecx,0// if (Length==0) goto .zero
je 3f
pushad // Save all register on the stack
mov edi, dword [esp + (4 + 32)] // Destination
xor eax,eax // ZeroFillByte = 0
// code for take four byte each time it loop
mov ebx,ecx // temp_Length = Length
shr ecx,2// Length = Length / sizeof(ULONG)
jz 1f // if (Length==0) goto .1byte
shl ecx,2// Length = Length * sizeof(ULONG)
sub ebx,ecx // temp_Length = temp_Length - Length//
jz 2f // if (temp_Length==0) goto .4byte
// move 4byte and 1byte
shr ecx,2// Length = Length / sizeof(ULONG)
cld // clear d flag
rep stosd// while (Length!=0) { (ULONG *) Destination[Length-1]=ZeroFillByte// Legnth = Legnth - 1 }
mov ecx,ebx // Length = temp_Length
rep stosb// while (Length!=0) { (UCHAR *) Destination[Length-1]=ZeroFillByte// Legnth = Legnth - 1 }
popad // restore register
ret 8 // return
// move 1byte
1:
mov ecx,dword [esp + (12 +32) ] // Length
cld // clear d flag
rep stosb// while (Length!=0) { (UCHAR *) Destination[Length-1]=ZeroFillByte// Legnth = Legnth - 1 }
popad // restore register
ret 8 // return
// move 4bytes
2:
shr ecx,2// Length = Length / sizeof(ULONG)
cld // clear d flag
rep stosd// while (Length!=0) { (ULONG *) Destination[Length-1]=ZeroFillByte// Legnth = Legnth - 1 }
popad // restore register
3:
ret 8 // return

View file

@ -28,7 +28,6 @@
// - Get rid of KiRosPrintAddress and use KiDumpParameterImages instead.
// - Sanitize some context fields during conversions.
// - Implement stack fault and segment fault handlers.
// - Implement kernel-mode GPF handler, possibly fixing below:
// - Figure out why ES/DS gets messed up in VMWare, when doing KiServiceExit only,
// and only when called from user-mode, and returning to user-mode.
// - Add DR macro/save and VM macro/save.

View file

@ -1215,7 +1215,6 @@ _KiTrap13:
/* Otherwise, something is very wrong, raise an exception */
sti
jmp $
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov esi, -1
mov eax, STATUS_ACCESS_VIOLATION
@ -1329,21 +1328,77 @@ NotCsGpf:
test dword ptr [edx+4], RPL_MASK
jz UserModeGpf
/* FIXME: Handle IRET back to user-mode */
/* Setup trap frame to copy */
mov ecx, (KTRAP_FRAME_LENGTH - 12) / 4
lea edx, [ebp+KTRAP_FRAME_ERROR_CODE]
TrapCopy:
/* Copy each field */
mov eax, [edx]
mov [edx+12], eax
sub edx, 4
loop TrapCopy
/* Enable interrupts and adjust stack */
sti
add esp, 12
add ebp, 12
/* Setup exception record */
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov esi, [ebp+KTRAP_FRAME_ERROR_CODE]
and esi, 0xFFFF
mov eax, STATUS_ACCESS_VIOLATION
jmp _DispatchTwoParam
MsrCheck:
/* FIXME: Handle RDMSR/WRMSR */
int 3
jmp $
NotIretGpf:
/* FIXME: Handle RDMSR/WRMSR and lazy load */
int 3
jmp $
/* Check if this was an MSR opcode */
cmp al, 0xF
jz MsrCheck
/* Check if DS is Ring 3 */
cmp word ptr [ebp+KTRAP_FRAME_DS], KGDT_R3_DATA + RPL_MASK
jz CheckEs
/* Otherwise, fix it up */
mov dword ptr [ebp+KTRAP_FRAME_DS], KGDT_R3_DATA + RPL_MASK
jmp ExitGpfTrap
CheckEs:
/* Check if ES is Ring 3 */
cmp word ptr [ebp+KTRAP_FRAME_ES], KGDT_R3_DATA + RPL_MASK
jz UserModeGpf
/* Otherwise, fix it up */
mov dword ptr [ebp+KTRAP_FRAME_ES], KGDT_R3_DATA + RPL_MASK
jmp ExitGpfTrap
SegPopGpf:
/* Handle segment POP fault */
/* Sanity check */
lea eax, [ebp+KTRAP_FRAME_ESP]
cmp edx, eax
jz HandleSegPop
int 3
jmp $
/* Handle segment POP fault by setting it to 0 */
HandleSegPop:
xor eax, eax
mov dword ptr [edx], eax
ExitGpfTrap:
/* Do a trap exit */
TRAP_EPILOG NotFromSystemCall, DoNotRestorePreviousMode, DoNotRestoreSegments, DoRestoreVolatiles, DoRestoreEverything
UserModeGpf:

View file

@ -4,7 +4,7 @@ NTSTATUS _MmCopyFromCaller( PVOID Target, PVOID Source, UINT Bytes ) {
NTSTATUS Status = STATUS_SUCCESS;
_SEH_TRY {
ProbeForRead(Source,Bytes,1);
//ProbeForRead(Source,Bytes,1);
RtlCopyMemory(Target,Source,Bytes);
} _SEH_HANDLE {
Status = _SEH_GetExceptionCode();
@ -17,7 +17,7 @@ NTSTATUS _MmCopyToCaller( PVOID Target, PVOID Source, UINT Bytes ) {
NTSTATUS Status = STATUS_SUCCESS;
_SEH_TRY {
ProbeForWrite(Target,Bytes,1);
//ProbeForWrite(Target,Bytes,1);
RtlCopyMemory(Target,Source,Bytes);
} _SEH_HANDLE {
Status = _SEH_GetExceptionCode();