Kamis, 26 Januari 2012

Membuat Virus Detector dengan Assembly.

Sebenarnya ada banyak cara antivirus untuk mendeteksi virus, tapi kali ini saya hanya akan memberi contoh
sedikit cara membuat program virus detector sederhana, dan bisa dikembangkan menjadi Anti Virus yang handal.

Nah, untuk contoh virusnya saya ambil dari si brontok yang lagi kondang katanya. brontok yang mana?, varian A,B,C... atau Z ?,
yah karena saking banyaknya varian jadi bingung deh, ya udah aku ambil semuanya, lo kok semua?
Sebenarnya ada rahasia yang unik pada virus brontok ini, eh tapi bukan rahasia ding, cause semua pasti sudah tahu
ciri khas brontok, apa tuh?

Ternyata semua varian dari virus brontok memiliki kesamaan yang tak pernah berubah sampai saat ini, dan ini yang saya
ambil sebagai identitas brontok dalam program virus detector sederhana yang akan kita buat. persamaan itu adalah :
sebaru-barunya varian terbaru dari brontok pasti akan tetap ber ikon folder, nah inilah yang akan kita jadikan handle virusnya.
lo nanti kalo ada applikasi walaupun bukan virus kalo ber-ikon folder akan dideteksi sebagai brontok?,
ya, memang, karena ikon folder merupakan ikon yang tidak wajar untuk sebuah applikasi. dan ini terbukti belum pernah
ada applikasi yang berikon folder murni. Dan hanya dengan cara inilah kita bisa mendeteksi berbagai macam virus brontok
yang terkenal cepat dalam perkembangannya, dari A sampe Z dari Z kembali lagi ke A, bahkan untuk brontok yang akan datang sekalipun!.
Inilah mimpi buruk bagi pembuat brontok. (ganti dong ikonnya....)
kita juga bisa menghandle ikon-ikon tidak wajar lainnya seperti ikon dokumen word, ikon notepad dll.

Lalu programnya mau kita buat pake apa?. pake VB!. bodoh brontok terbaru sudah dilengkapi anti VB man!,
pake C++. sama dengan brontok dong!. Oke kita pake Assembly Win32bit!. sulit nih!. Gampang kok baca aja buku
Pemrograman Bahasa Assembly oleh S'to di www.ilmukomputer.com.

terus kapan kita mulai ?
Oke kita mulai sekarang.

----[ CUT HERE ]-------------------------------------------------------------------------------------------------------------------
;-----------------------------------------------------------------------------------)
;         SIMPLE  VIRUS DETECTOR
;              BY:[4NV|e]
;        +=+=+=+=+=+=+=+=+=+=+=+=+
;     
;       Bisa dikompil menggunakan:
;       Macro Assembly Win32 (MASM32) 
;       Turbo Assembly Win32 (TASM32)
;-----------------------------------------------------------------------------------)

    .386                                ;<--Untuk prosesor 32 bit
    .model flat, stdcall                ;<--Memori 32 bit
    option casemap :none                ;<--case sensitive
     
    include user32.inc        ;------|
    include kernel32.inc            ;|--Komponen wajib hanya butuh kernel32.dll dan user32.dll
    includelib user32.lib           ;|  berbahagialah, karena tidak butuh MSVBVM60.dll
    includelib kernel32.lib   ;------|  dan MSVCP60.dll dan dll-dll yang lain/dlllllll.

    .data
        hInst               dd 0            ;<--Buffer-buffer
        gBuff1              dd 260 dup(0)
        CommandLine         dd 0
       
        AppName             db "Simple Virus Detector by:4NV|e",0
        FileTarget          db 260 dup(0)        ;<----------260 = MAX_PATH
        nOffset             dd 0
        FileReadError       db "File gak bisa dibuka/dibaca. Tambahkan parameter yang menunjuk pada file.",0
        MemoryError         db "Alokasi Memori Error.",0
        strIniBrontok       db "File %s",13,10,"Adalah virus Brontok.",13,10
                            db "Berhati-hatilah!!.",0
        strBukanBrontok     db "File ini bukan Brontok",0
        strMasukkanCMDL     db "Tambahkan parameter yang berisi alamat file.",0


        Virus_DB            db "Brontok",0,008H,025H,000h,000h,0 ;<-- 7 byte Nama virus, 4 byte offset awal
                                                                 ;    2 byte pemisah, 12 byte virus sign dan
                                                                 ;    2 byte tanda akhir. jadi setiap 1 data berjumlah 27 byte

                       ;Signatur virus milik brontok Varian A-Z. 4 byte x 3 = 12 byte + 2 = 14 byte
                               ;______________________________|_______________________________
                              ;|                                                             |
                            db 09FH,0CFH,0ECH,0F9H,0FEH,0CCH,0FCH,0FFH,0BCH,0FEH,0FFH,0B5H,0,0


         
    .code

start:
    push    0
    call    GetModuleHandle     ;<--Ambil handle untuk proses kita (App Instance)
    mov     hInst, eax          ;   dan simpan pada memory

    call    GetCommandLine      ;<--Ambil letak offset Command Line (exe parameter)
    mov     CommandLine, eax    ;   yang akan kita gunakan untuk menunjuka pd file
                                ;   yang akan kita periksa
    push    CommandLine        
    push    offset gBuff1       ;<--Copykan ke dalam buffer
    call    lstrcpy             ;   kita gunakan lstrcpy
                                ;   (perintah dari kernel32.dll
                                ;   yang dikenal baik dikalangan CRACKER)
    ;--------------------
    ; karena format string yang telah kita dapatkan dalam buffer
    ; adalah : |"exe file" + parameter| dan yang kita butuhkan
    ; hanyalah parameternya maka kita akan melakukan langkah2 berikut
    ;--------------------
    lea     esi, gBuff1         ;<--Ambil alamat efektif dari buffer
                                ;   yang telah berisi string exefile+parameter
    mov     ecx, esi ;<--gunakan register ecx untuk counter
    add     esi, 260  ;MAX_PATH  <tambahkan register esi dengan 260

    ;mulai looping
cari_lagi:
    dec     esi                  ;<--kurangi esi dengan 1 (dec = decrement)
    cmp     esi, ecx             ;<--apakah buffer sudah habis dibaca?
    jbe     udeh_lah             ;   jika udah lompat ke udeh_lah
    cmp     byte ptr [esi], 022H ;   apakah offset esi menunjuk pada karakter (") ?
    jne     cari_lagi            ;<--kalo ga balik ke cari_lagi
    add     esi, 3 ;<--esi=offset->"X:\xxxxx
    cmp     byte ptr [esi], 022H
    je      nullkan
    jmp     udeh_lah
                            ; sebenarnya kita bisa pake "repne scasb",
                            ; tapi dengan cara diatas akan lebih mudah dicerna.
nullkan:    ;jika terdapat karakter '"' Nullkan!
    inc     esi
    mov     edi, esi
    inc     ecx
    mov     al, 022H
    cld     ;<--Clear Direction Flag
    repne   scasb       ;<--aku terpaksa pake ini biar gak kelamaan
    mov     byte ptr [edi-1],0
    jmp     udeh_lah
udeh_lah:  

    cmp     byte ptr [esi], 03AH
    jne     path_oke
    dec     esi
   
path_oke:
    push    esi                 ;<--sekarang esi berisi offet dari parameter
    push    offset FileTarget   ;<--kita kopikan lagi ke buffer yang berbeda
    call    lstrcpy

    push    offset FileTarget   ;<--Apakah commandline berisi?
    call    lstrlen             ;   atau sama dengan perintah VB if len(FileTarget) = 0 then  goto commandline_kosong
    test    eax, eax            ;   jika tidak goto commandline_kosong
    jz      commandline_kosong


    push    offset FileTarget   ;<--panggil prosedur pemeriksaan file
    call    CheckThisFile       ;   jika virus terdeteksi maka register EAX akan bernilai 2
    test    eax, eax            ;   jika file gak bisa dibuka maka EAX bernilai 1
    jz      bukan_virus         ;   jika bukan virus maka EAX bernilai 0
                                ;<--Jika Bukan Virus goto bukan_virus

    cmp     eax, 1
    je      TAMAT

    push    offset FileTarget   ;<--buatkan format string untuk ditampilkan ke msgbox
    push    offset strIniBrontok
    push    offset gBuff1       ;<--hasil masuk ke gBuff1
    call    wsprintfA

    push    030H                ;<--030H = MB_ICONEXCLAMATION/vbExclamation
    push    offset AppName     
    push    offset gBuff1       
    push    0
    call    MessageBoxA          ;<--Tampilkan Message Box!
    jmp     TAMAT ;<--Selesai goto TAMAT
bukan_virus:
    push    0
    push    offset AppName
    push    offset strBukanBrontok
    push    0
    call    MessageBoxA          ;<--Tampilkan Message Box!
    jmp     TAMAT
commandline_kosong:
    push    0
    push    offset AppName
    push    offset strMasukkanCMDL
    push    0
    call    MessageBoxA
TAMAT:
    push    hInst
    call    ExitProcess         ;<--Akhiri Proses


;==============================[ PROSEDUR PEMERIKSAAN ]==========================)
CheckThisFile proc  tFile:DWORD
    LOCAL   lBuff[260]:BYTE     ;--------|
    LOCAL   fHandle:DWORD               ;|
    LOCAL   fSize:DWORD                 ;|
    LOCAL   memptr:DWORD                ;|
    LOCAL   bread:DWORD                 ;|--definisikan variabel lokal
    LOCAL   ccnt:DWORD                  ;|
    LOCAL   SizeToCheck:DWORD           ;|
    LOCAL   EndOffset:DWORD             ;|
    LOCAL   VirusName:DWORD             ;|
    LOCAL   VIDB:DWORD                  ;|
    LOCAL   UdahKetemu:DWORD  ;----------|

    push    00000004H         ;<--PAGE_READWRITE
    lea     eax, bread
    push    eax
    push    tFile
    call    OpenFile          ;<--Buka file
    mov     fHandle, eax      ;<--Ambil handle file yang terbuka
    inc     eax            
    jnz     file_ada          ;<--Apakah berhasil, jika ya goto label file_ada
    push    0                 ;   Tidak ?   sampaikan pesan kesalahan
    push    offset AppName
    push    offset FileReadError
    push    0
    call    MessageBoxA
    mov     eax, 1            ;<--set return value = 1 (file not found/access denied)
    ret
file_ada:
    push    0
    push    fHandle
    call    GetFileSize       ;<--Ambil ukuran file  
    mov     fSize, eax        ;   simpan di memori

    ; nggak make file mapping?
    ; aku gunakan VirtualAlloc untuk membaca file

    push    00000004H
    push    00001000H         ;<--MEM_COMMIT
    push    fSize             ;<--ukuran file
    push    0                  
    call    VirtualAlloc      ;<--Alokasikan memori untuk tempat dari isi file
    mov     memptr, eax       ;<--Pointer simpan dalam memori
    test    eax, eax          ;<--Berhasil?
    jnz     mem_oke           ;   YA. goto mem_oke
    push    0                 ;   TIDAK. tampilkan pesan kesalahan
    push    offset AppName
    push    offset MemoryError
    push    0
    call    MessageBox
    jmp     e_close_file     
mem_oke:
    push    0               ;--------|
    lea     eax, bread              ;|
    push    eax                     ;|
    push    fSize                   ;|--Masukkan isi dari file kedalam memori yang
    push    memptr                  ;|  telah kita alokasikan untuk diperiksa
    push    fHandle                 ;|
    call    ReadFile                ;|
    test    eax, eax                ;| 
    jnz     read_ok                 ;|
    jmp     e_free_ch       ;--------|
read_ok:
    lea     esi, Virus_DB
    xor     eax, eax        ; EAX = 0
    mov     UdahKetemu, eax ; set local flag
ps_loop_3:
    mov     VirusName, esi  ;--------|ESI menunjuk ke offset Virus_DB
    mov     eax, esi                ;|karena nama virus maximal kita set 7 byte
    add     eax, 8                  ;|maka EAX ditambah dengan 8 (+1 byte=pembatas=0)
    xor     ebx, ebx                ;|byte ke 1-7 berisi nama virus, byte ke 8 = 0
    mov     ebx, dword ptr [eax]    ;|byte ke 9-12 berisi offset awal yang harus dibaca, byte ke 13 = 0
    mov     nOffset, ebx            ;|byte ke 14-25 berisi Virus_sign/ID
    add     esi, 13                 ;|
    mov     VIDB, esi       ;--------|
       
    mov     esi, memptr     ;<--esi menunjuk pada awal offset dari file
    mov     ecx, fSize     
    cmp     ecx, nOffset    ;<--Apakah file target lebih kecil dari awal offset untuk dibaca?
    jbe     pake_DB_lain    ;   jika ya coba data virus selanjutnya
    add     esi, nOffset    ;   kamu bisa nambahin data virus sendiri, untuk contoh aku cuma pake virus brontok.
    mov     eax, memptr    
    add     eax, fSize
    mov     EndOffset, eax  ;<--Akhir dari offset
   
    xor     eax, eax
    mov     ccnt, eax
    mov     eax, EndOffset
    sub     eax, esi
    mov     SizeToCheck, eax    ;<--banyaknya pengulangan yang akan dilakukan
ps_loop_1:
    inc     esi
    mov     edi, VIDB
    xor     ebx, ebx
ps_loop:                ;----------------| 
    cmp     ebx, 2                      ;|--Rutin untuk memeriksa file
    jae     ps_loop_end                 ;|  apakah sudah berputar sebanyak 3x? (ingat Virus ID berisi 3 dword/12 byte)
    mov     eax, dword ptr [esi+ebx*4]  ;|  lo, kok ebx,2 ?, ya. karena ebx = 0 dan diset akhir
    mov     edx, dword ptr [edi+ebx*4]  ;|
    inc     ebx                         ;|
    cmp     eax, edx                    ;|
    je      ps_loop     ;----------------|
ps_loop_end:
    cmp     ebx, 2      ;<--Apakah pemeriksaan menuai hasil?
    je      virus_nih   ;   jika ya goto _virus_nih
    inc     ccnt
    mov     ecx, ccnt
    add     ecx, 10     ;<--Harus begini atau akan terjadi error
    cmp     ecx, SizeToCheck
    jae     pake_DB_lain
    jmp     ps_loop_1
virus_nih:
    mov     eax, 2          ;<--EAX = 2 (Virus ditemukan)
    mov     UdahKetemu, eax ;<--set local flag
pake_DB_lain:
    mov     eax, UdahKetemu
    test    eax, eax
    jnz     e_free_ch
    mov     esi, VirusName
    add     esi, 25
    inc     esi
    cmp     byte ptr[esi],0   ;apakah virus databasenya masih?
    jne     ps_loop_3         ;jika masih lompat ke ps_loop_3
e_free_ch:
    push    00004000H         ; = MEM_DECOMMIT
    push    fSize
    push    memptr
    call    VirtualFree       ;<--Bebaskan memori
e_close_file:
    push    fHandle
    call    CloseHandle       ;<--Tutup file
the_end:
    mov     eax, UdahKetemu   ;<--set return value
    ret
CheckThisFile endp   

end start

----[ END OF FILE  ]-------------------------------------------------------------------------------------------------------------------

Agak panjang ya... tapi kalo udah dikompil akan didapatkan file executable dengan ukuran file kira-kira 4.5 KB,
4.5 KB!!!, ya begitulah Assembly, terus kalo dipak make UPX jadi berapa ya?. oh ya,  4.5 KB itu belum make ikon/resource lo.

Setelah dikompil coba jalankan filenya dengan menambahkan parameter yang menunjuk pada file yang akan kita periksa
contoh :
            "cekvirus.exe C:\windows\eksplorasi.exe"
Tanpa tanda petik, dan diketik pada jendela explorer atau jendela konsol, file harus ada/eksis.

Jika source code diatas dimodifikasi menjadi virus maka akan menjadi virus yang mengerikan.
Jika source code diatas ditambah listing membaca proses pada memory (EnumProcesses) , mangaksesnya  (OpenProcess),
mencari file (FindFirstFile) dan dikembangkan lebih baik lagi, maka akan menjadi anti brontok yang dahsyat.
dan bahkan masuknya virus brontok kedalam system komputer menjadi hal yang tidak mungkin.

Siapa aja yang pengen nyoba, nih link untuk download kompilernya.

www.masm32.com
www.tasm32.com

Dan ini contoh file yang udah di kompil.
www.ansui.cjb.net\ansui\simple_vd.exe

Tidak ada komentar:

Posting Komentar