一段写只读内存的代码
逆向一个驱动程序时发现了一段写只读内存的代码,这个代码实际是Mark Russinovich 很早写的一段代码。如下:WriteReadOnlyMemory proc near ; CODE XREF: sub_108CC+D4 p
; sub_10A06+D4 p ...
BaseAddress = dword ptr -4 ; 保存映射的内存地址
SpinLock = dword ptr 8
arg_4 = dword ptr 0Ch
Length = dword ptr 10h
mov edi, edi
push ebp
mov ebp, esp
push ecx
push ebx
push esi
xor esi, esi
push esi
push esi
push esi
push [ebp+Length]
push [ebp+SpinLock]
call ds:IoAllocateMdl
mov ebx, eax
cmp ebx, esi
jnz short loc_105C6
mov eax, 0C0000001h
jmp short loc_1063F
; ---------------------------------------------------------------------------
loc_105C6: ; CODE XREF: WriteReadOnlyMemory+1D j
push edi
push ebx
call ds:MmBuildMdlForNonPagedPool
push 1
push esi
push ebx
call ds:MmProbeAndLockPages
push esi
push ebx
call ds:MmMapLockedPages
mov edi, eax
cmp edi, esi
mov [ebp+BaseAddress], edi
jnz short loc_105F0
mov esi, 0C0000001h
jmp short loc_1062E
; ---------------------------------------------------------------------------
loc_105F0: ; CODE XREF: WriteReadOnlyMemory+47 j
lea eax, [ebp+SpinLock]
push eax
call ds:KeInitializeSpinLock
lea ecx, [ebp+SpinLock]
call ds:KfAcquireSpinLock
mov ecx, [ebp+Length]
mov esi, [ebp+arg_4]
mov edx, ecx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
mov dl, al
lea ecx, [ebp+SpinLock]
call ds:KfReleaseSpinLock
push ebx
push [ebp+BaseAddress]
call ds:MmUnmapLockedPages
xor esi, esi
loc_1062E: ; CODE XREF: WriteReadOnlyMemory+4E j
push ebx
call ds:MmUnlockPages
push ebx
call ds:IoFreeMdl
mov eax, esi
pop edi
loc_1063F: ; CODE XREF: WriteReadOnlyMemory+24 j
pop esi
pop ebx
leave
retn 0Ch
WriteReadOnlyMemory endp
下面是Mark Russinovich 很早写的一段代码,目的是写只读内存。
NTSTATUS WriteReadOnlyMemory (char *dest, char *source, int length)
{
KSPIN_LOCK tempSpinLock;
KIRQL oldirql;
PMDL mdl;
PVOID writableAddress;
mdl = IoAllocateMdl((PVOID) dest, length, FALSE, FALSE, NULL);
if (mdl == NULL)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(mdl);
MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
writableAddress = MmMapLockedPages(mdl, KernelMode);
if (writableAddress == NULL) {
MmUnlockPages(mdl);
IoFreeMdl(mdl);
return STATUS_UNSUCCESSFUL;
}
KeInitializeSpinLock(&tempSpinLock);
KeAcquireSpinLock(&tempSpinLock, &oldirql);
RtlCopyMemory(writableAddress, source, length);
KeReleaseSpinLock(&tempSpinLock, oldirql);
MmUnmapLockedPages(writableAddress, mdl);
MmUnlockPages(mdl);
IoFreeMdl(mdl);
return STATUS_SUCCESS;