Przykład samo-wymazującego się kodu (x64)
15.03.2022 Dawid Farbaniec

/* Dawid grzebie w swoich archiwach. */
Możliwe, że w jakimś programie trzeba będzie skasować pewne dane lub nawet kod. Chociaż technika wymazywania kodu z pamięci może niektórym czytelnikom wydawać się podejrzana (zachowanie wirusowe! o_O).
Zastanówmy się bez narzekania, czy technika ta zostanie wykorzystana do wykasowania shellcode w teście penetracyjnym, czy w innym celu. Wymazywanie kodu z pamięci jest nieco bardziej skomplikowane niż wymazywanie danych (zmienna).
Przykład w Asemblerze MASM x64 pokazano poniżej. Wypełnienie ciała procedury instrukcjami
Czekaj na więcej treści dotyczących cyberbezpieczeństwa! 🦠☣️💉🧪🛡️.
Możliwe, że w jakimś programie trzeba będzie skasować pewne dane lub nawet kod. Chociaż technika wymazywania kodu z pamięci może niektórym czytelnikom wydawać się podejrzana (zachowanie wirusowe! o_O).
Zastanówmy się bez narzekania, czy technika ta zostanie wykorzystana do wykasowania shellcode w teście penetracyjnym, czy w innym celu. Wymazywanie kodu z pamięci jest nieco bardziej skomplikowane niż wymazywanie danych (zmienna).
Przykład w Asemblerze MASM x64 pokazano poniżej. Wypełnienie ciała procedury instrukcjami
NOP
(ang. no operation) jest możliwe poprzez pobranie początku i końca bloku kodu za pomocą etykiet i rozmiaru kodu w bajtach. Dostęp do zapisu w sekcji kodu jest uzyskiwany przez funkcję VirtualProtect
.
;+---------------------------------------+
;| Erase procedure body code in MASM x64 |
;| Code example by Dawid Farbaniec |
;+---------------------------------------+
extrn MessageBoxA : proc
extrn VirtualProtect : proc
.const
PAGE_EXECUTE_READWRITE equ 040h
ProcInfo struct
bodyStart dq 0
bodyEnd dq 0
bodySize dq 0
ProcInfo ends
.data
szCaption db "ethical.blue", 0
szText db "This is sample procedure call.", 0
oldProtect dd 0
procInfo1 ProcInfo <0,0,0>
.code
MyProc1 proc
mov rax, offset _ERASE_START
mov [procInfo1.bodyStart], rax
push rbp
mov rbp, rsp
_ERASE_START:
sub rsp, 30h
xor r9, r9
lea r8, szCaption
lea rdx, szText
xor rcx, rcx
call MessageBoxA
add rsp, 30h
_ERASE_END:
leave
mov rcx, offset _ERASE_END
dec rcx
mov [procInfo1.bodyEnd], rcx
sub rcx, qword ptr [procInfo1.bodyStart]
mov [procInfo1.bodySize], rcx
ret
MyProc1 endp
Main proc
;sample procedure call
sub rsp, 28h
call MyProc1
add rsp, 28h
;get write access to code block
sub rsp, 28h
mov r9, offset oldProtect
mov r8, PAGE_EXECUTE_READWRITE
mov rdx, [procInfo1.bodySize]
mov rcx, qword ptr [procInfo1.bodyStart]
call VirtualProtect
add rsp, 28h
;erase procedure body (fill with NOPs)
mov rdx, [procInfo1.bodyStart]
xor rcx, rcx
_loop1:
mov byte ptr [rdx + rcx * sizeof byte], 90h
inc rcx
cmp rcx, [procInfo1.bodySize]
jle _loop1
;sample procedure call (after erasing)
sub rsp, 28h
call MyProc1
add rsp, 28h
ret
Main endp
end
Czekaj na więcej treści dotyczących cyberbezpieczeństwa! 🦠☣️💉🧪🛡️.