Trao đổi với tôi

http://www.buidao.com

7/28/09

[MASM]*** Self Modifying Code ***

*** 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.