Use VirtualProtect for PC WriteCodeBlocks
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
.meta visibility="all"
|
.meta visibility="all"
|
||||||
.meta name="PC data noop"
|
.meta name="PC text noop"
|
||||||
.meta description="PC-only test.\nWrites zeros over\nwritable data."
|
.meta description="PC-only test.\nWrites NOPs over\nexisting code NOPs."
|
||||||
|
|
||||||
entry_ptr:
|
entry_ptr:
|
||||||
reloc0:
|
reloc0:
|
||||||
@@ -12,9 +12,10 @@ start:
|
|||||||
|
|
||||||
.versions 2OJW
|
.versions 2OJW
|
||||||
|
|
||||||
.data 0x0068854E
|
.data 0x004E03DE
|
||||||
.data 2
|
.data 2
|
||||||
add [eax], al
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,109 @@ first_patch_header:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
.versions 2OJW 2OJZ 50YJ 59NJ 59NL
|
.versions 2OJW
|
||||||
|
|
||||||
|
start:
|
||||||
|
push ebx
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
sub esp, 8 # [esp] = oldProtect, [esp + 4] = tempProtect
|
||||||
|
jmp get_patch_data_ptr
|
||||||
|
get_patch_data_ptr_ret:
|
||||||
|
pop ebx # ebx = patch header
|
||||||
|
|
||||||
|
# Resolve kernel32!VirtualProtect using pso.exe's 2OJW IAT:
|
||||||
|
# GetModuleHandleA = 0x0064D114
|
||||||
|
# GetProcAddress = 0x0064D128
|
||||||
|
#
|
||||||
|
# Build "KERNEL32.dll\0" on stack.
|
||||||
|
sub esp, 16
|
||||||
|
mov dword [esp], 0x4E52454B # "KERN"
|
||||||
|
mov dword [esp + 4], 0x32334C45 # "EL32"
|
||||||
|
mov dword [esp + 8], 0x6C6C642E # ".dll"
|
||||||
|
mov dword [esp + 12], 0
|
||||||
|
push esp
|
||||||
|
call [0x0064D114] # GetModuleHandleA
|
||||||
|
add esp, 16
|
||||||
|
test eax, eax
|
||||||
|
jz fail
|
||||||
|
|
||||||
|
mov esi, eax # esi = kernel32 module handle
|
||||||
|
|
||||||
|
# Build "VirtualProtect\0" on stack.
|
||||||
|
sub esp, 16
|
||||||
|
mov dword [esp], 0x74726956 # "Virt"
|
||||||
|
mov dword [esp + 4], 0x506C6175 # "ualP"
|
||||||
|
mov dword [esp + 8], 0x65746F72 # "rote"
|
||||||
|
mov dword [esp + 12], 0x00007463 # "ct\0\0"
|
||||||
|
push esp
|
||||||
|
push esi
|
||||||
|
call [0x0064D128] # GetProcAddress
|
||||||
|
add esp, 16
|
||||||
|
test eax, eax
|
||||||
|
jz fail
|
||||||
|
|
||||||
|
mov edi, eax # edi = VirtualProtect
|
||||||
|
|
||||||
|
apply_next_patch:
|
||||||
|
cmp dword [ebx + 4], 0
|
||||||
|
jne copy_code_and_apply_again
|
||||||
|
|
||||||
|
add esp, 8
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebx
|
||||||
|
mov eax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
copy_code_and_apply_again:
|
||||||
|
# VirtualProtect(dest, size, PAGE_EXECUTE_READWRITE, &oldProtect)
|
||||||
|
lea eax, [esp]
|
||||||
|
push eax
|
||||||
|
push 0x40
|
||||||
|
push dword [ebx + 4]
|
||||||
|
push dword [ebx]
|
||||||
|
call edi
|
||||||
|
test eax, eax
|
||||||
|
jz fail
|
||||||
|
|
||||||
|
xor ecx, ecx # ecx = offset
|
||||||
|
mov edx, [ebx] # edx = dest addr
|
||||||
|
copy_next_byte:
|
||||||
|
mov al, [ebx + ecx + 8] # copy one byte to dest
|
||||||
|
mov [edx + ecx], al
|
||||||
|
inc ecx # offset++
|
||||||
|
cmp [ebx + 4], ecx # check if all bytes have been copied
|
||||||
|
jne copy_next_byte
|
||||||
|
|
||||||
|
# VirtualProtect(dest, size, oldProtect, &tempProtect)
|
||||||
|
mov esi, [ebx + 4] # esi = size; VirtualProtect preserves esi
|
||||||
|
mov edx, [esp] # edx = oldProtect
|
||||||
|
lea eax, [esp + 4]
|
||||||
|
push eax
|
||||||
|
push edx
|
||||||
|
push esi
|
||||||
|
push dword [ebx]
|
||||||
|
call edi
|
||||||
|
|
||||||
|
lea ebx, [ebx + esi + 8] # advance to next block
|
||||||
|
jmp apply_next_patch
|
||||||
|
|
||||||
|
fail:
|
||||||
|
add esp, 8
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebx
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
get_patch_data_ptr:
|
||||||
|
call get_patch_data_ptr_ret
|
||||||
|
first_patch_header:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.versions 2OJZ 50YJ 59NJ 59NL
|
||||||
|
|
||||||
start:
|
start:
|
||||||
push ebx
|
push ebx
|
||||||
|
|||||||
Reference in New Issue
Block a user