*** Self Modifying Code ***
Benina (tranz in 2008)
Source:
http://www.mediafire.com/download.php?myjwzul4dun
Tut này để thực hành nếu bạn quan tâm đến việc thay đổi chính code của chương trình (self modifying code). Tôi sẽ chỉ giải thích căn bản và phần còn lại là do bạn tửơng tượng.
Tools chúng ta cần cho tut này:
- MASM32 compiller
- Có lẻ vài chất gây nghiện cho hướng thú (xanax, bromazepam, diazepam or any other good benzodiazepine)
Ok, Ý tưởng cơ bản là gì?. Chúng ta cần một vài đọan trong section .code mà nó “trống” (free) để dùng cho việc viết đè data (dữ liệu) lên đó , đọan code trống đó giống như các dòng lệnh chỉ thị NOP. Những thứ khác bạn cần là code mà chúng ta muốn thay đổi. Trong ví dụ của tôi, tôi sẽ chỉ dùng hàm gọi API MessageBox. Quan trọng là có bao nhiêu bytes trống data code mà chúng ta cần.
Chúng ta bắt đầu với phần khảo sát sau:
MessageBox calling code là:
push MB_OK ;push MB_OK as type of our msgbox
push offset szCap ;push the offset of our caption
push offset szText ;push the offset of our text
push NULL ;push NULL as parent handle (no parent)
lea eax, MessageBox ;loads the effective address of MessageBox API function in EAX
;this is important 'cause when we copy this code to
;some other place the offset will change if we
;call directly the MessageBox API because of the
;segmenting
call eax ;and call eax
Hex of code này là như sau (chú ý các addresses sẽ khác):
6A00 = PUSH 0
6823304000 = PUSH 403023
6800304000 = PUSH 403000
6A00 = PUSH 0
8D05EC104000 = LEA EAX, DWORD PTR DS:[4010EC]
FFD0 = CALL NEAR EAX
Nói cách khác chúng ta có:
6A 00 68 23 30 40 00 68 00 30 40 00 6A 00 8D 05 EC 10 40 00 FF D0 = 22 bytes of code
Ok, bây giờ chúng ta có vài thứ để bắt đầu rồi. Chúng ta cần add 22 dòng chỉ thị NOPs nơi nào đó trong code của chúng ta mà ở đó chúng ta muốn gọi hàm MessageBox API. Và sau đây sẽ là ví dụ code:
jmp _decrypt ;jumps to the decrypt part
EncryptedOffset: ;this we use to name an offset
nop ;our free code starts here
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop ;and ends here
jmp _continue ;jump to the end
_decrypt: ;this is the decryption part
mov edx,offset EncryptedOffset ;edx = our free data [it's not encrypted but this doesn't metter :)]
invoke VirtualProtect,edx,22,PAGE_EXECUTE_READWRITE,addr oldProt ;we invoke VirtualProtect to get
;write access to the free .code segment
mov esi, offset EncryptedOffset ;esi = our free code offset
mov edi, offset DecryptionData ;edi = our executable code
mov ecx, 22 ;ecx hods how many times to loop the loop
xor eax, eax ;we clear eax (eax = 0)
lp1: ;our loop label
mov al, byte ptr [edi] ;al = current byte pointed by edi
mov byte ptr [esi], al ;copy this byte to the offset pointed by esi
inc esi ;esi + 1
inc edi ;edi + 1
loop lp1 ;jumps to lp1 label while ecx > 0
jmp EncryptedOffset ;when the loop ends we jump to the code we just copyed
DecryptionData: ;our offset with important data :)
push MB_OK ;the code of the data :)
push offset szCap ;...
push offset szText ;...
push NULL ;...
lea eax, MessageBox ;...
call eax ;...
_continue: ;we reach here when everything is done
Đây là tất cả những gì cần làm. Nhưng cho phép tôi nói vài lời, đây là một phương án rất tệ về self modifying code.
Nếu tôi cần làm self mod code thì Tôi chưa bao giờ làm nó như cách này. Bạn có thể khai báo executable code của bạn
trong vài biến , encrypt nó etc. Đây chỉ là một ví dụ đơn giản Tôi đã làm nó trong vài phút. Tôi đã nói gì cho những người
mới bắt đầu với tut này, là dùng trí tưởng tượng của bạn. Bạn có thể sử dụng proc khác để đặt free code tránh việc labelling, sau đó chỉ thay thế replace lea
Sorry about bad english, good luck.