Trao đổi với tôi

http://www.buidao.com

1/4/10

[MASM] Cavity search engine of 29A

Cavity search engine of 29A

Author: Benina REA

Bài viết này chỉ đơn giản là nghiên cứu thuật tóan tìm một “hẫm code” (cavity code) (một lõm code trống) của một file.

Mục đích tìm hẫm code là để inject code tầm bậy tầm bạ vào file.

Bài này tôi dựa vào thuật tóan của Benny and Darkman of 29A.

Đầu tiên chúng ta tham khảo một cấu trúc định nghĩa trước hay dùng của các coder viruz:

Khi đầu một thủ tục hay một hàm, chúng ta bảo lưu các thanh ghi để sau này phục hồi, ta hay dùng lệnh pushad.

Vậy khi pushad thì các thanh ghi push vào stack theo thứ tự như thế nào. Đây là cấu trúc đó:

Pushad_struc struc

Pushad_edi dd ? ;esp+00h

Pushad_esi dd ? ;esp+04h

Pushad_ebp dd ? ;esp+08h

Pushad_esp dd ? ;esp+0ch

Pushad_ebx dd ? ;esp+10h

Pushad_edx dd ? ;esp+14h

Pushad_ecx dd ? ;esp+18h

Pushad_eax dd ? ;esp+1ah

Pushad_struc ends

Mục đích chính dùng cấu trúc này là khi trả về “giá trị trả về” của một thủ tục vào một thanh ghi nào đó mà chúng ta muốn.

Đây là thủ tục chính tìm cavity code :

;-----------------------------------------------------------------------------

; Cavity search engine Benny and Darkman of 29A

;

; Calling parameters:

; ECX = size of search area

; ESI = pointer to search area

; EDI = required size

;

; Return parameters:

; ESI = pointer to cave

;

; Changed registers:

; EAX, EBX, ECX, EDX, ESI, EDI

CSE: pushad

lodsb ; AL = byte within search area

reset_cavity_loop:

xchg eax,ebx ; BL = " " " "

xor edx,edx ; Zero EDX

dec ecx ; Decrease counter

jecxz no_cave_found ; Zero ECX? Jump to no_cave_found

find_cave_loop:

lodsb ; AL = byte within search area

cmp al,bl ; Current byte equal to previous byte?

jne reset_cavity_loop ; Not equal? Jump to reset_cavity_loop

inc edx ; Increase number of bytes found in

; cave

cmp edx,edi ; Found a cave large enough?

jne find_cave_loop ; Not equal? Jump to find_cave_loop

sub esi,edi ; ESI = pointer to cave

mov [esp+04h],esi

no_cave_found:

popad

ret

Chú giải:

-Tham số truyền vào hàm:

ecx : là size của vùng nhớ mà ta muốn search.

esi : Là con trỏ trỏ đến vùng nhớ để search.

edi : là size vùng cave yêu cầu

-Thuật tóan :

Lệnh lodsb là load một byte từ vùng nhớ trỏ đến bởi esi vào eax và esi sẽ tự động tăng lên

Biến ebx chứa tạm byte trước đó loaded để so sánh với byte load sau trong eax.

Chú ý lệnh xchg để hóan đổi byte loaded trong eax qua ebx

Nếu bằng nhau thì có nghĩa là có lõm code.

edx là biến đếm số bytes của lõm code.

Nếu có lõm code tức là al=bl thì so sánh với size yêu cầu (edi).

Nếu tìm thấy thì giá trị trả về trong thanh gi esi.

-Kết quả trả về.

Nếu không tìm thấy thì esi ko đổi

Nếu tìm thấy cave thì addr chứa trong esi

Sau đây là thủ tục trong masm :

peCaveSearchEngine proc

;-----------------------------------------------------------------------------

; Cavity search engine Benny and Darkman of 29A

;

; Calling parameters:

; ECX = size of search area

; ESI = pointer to search area

; EDI = required size

;

; Return parameters:

; ESI = pointer to cave

;

; Changed registers:

; EAX, EBX, ECX, EDX, ESI, EDI

;------------------------------------------------------------------------------

CSE: pushad

;mov al,byte ptr [esi]

;inc esi

lodsb ; AL = byte within search area

reset_cavity_loop:

xchg eax,ebx ; BL = " " " "

xor edx,edx ; Zero EDX

dec ecx ; Decrease counter

jecxz no_cave_found ; Zero ECX? Jump to no_cave_found

find_cave_loop:

;mov al,byte ptr [esi]

;inc esi

lodsb ; AL = byte within search area

cmp al,bl ; Current byte equal to previous byte?

jne reset_cavity_loop ; Not equal? Jump to reset_cavity_loop

inc edx ; Increase number of bytes found in

; cave

cmp edx,edi ; Found a cave large enough?

jne find_cave_loop ; Not equal? Jump to find_cave_loop

sub esi,edi ; ESI = pointer to cave

;assume esp : ptr Pushad_struc

mov [esp+04h],esi

;assume esp: nothing

no_cave_found:

popad

ret

peCaveSearchEngine endp