我的PE程式加密核心程式碼(MASM 6.0) (9千字)

看雪資料發表於2015-11-15

;=======================我的加密程式 2.5版ASM源程式================
;本程式是將被加殼到被加密的程式中的主要部分
;2.5版的程式將處理原程式中的輸入表的修正工作
;==================================================================
;程式主要流程
;    1.進行反動態跟蹤,破壞INT1.檢測是否有跟蹤程式存在
;    2.修正原程式的輸入表
;    3.載入mkey.dll
;    4.在mkey.dll中查詢名為error 的過程
;    5.執行error過程
;    6.返回到原程式
;
;===================================================================

        
        .486
        .model flat, stdcall
        option casemap :none  ; case sensitive

INCLUDE        E:\masm32\INCLUDE\windows.inc
INCLUDE        E:\masm32\INCLUDE\kernel32.inc
INCLUDE        E:\masm32\INCLUDE\user32.inc
           
includelib     E:\masm32\lib\kernel32.lib
includelib        E:\masm32\lib\user32.lib
;==============================================================================
;自定義過程
RVAtoAddr proto  :DWORD ;將相對地址(RVA)轉化為記憶體實際地址
SetprocAddr proto :DWORD,:DWORD  ;取出每一個DLL中的涵數名,將正確地址寫入FirstThunk中





DEBUG=FALSE
;=============================================================================

.code     ;程式碼開始           
start:  ;--------------------------------------------------
;在以下段佔寫入程式的程式碼;           
            call      @1
           
data1:
            ver db        1    ;
            main_ver db        2
            sub_ver db        5
        impRVA dd 4a000h  ;輸入表地址,裝配時需修改
        impSize dd 1c14h ;輸入表的大小,裝配時需修改
        imagebase dd 60000h  ;被加入程式碼段的RVA,裝配時需修改

        
            call_ep dd        0c1e92h  ;被加殼程式的入口經計算後的值,裝配時需修改
            key dd        0b8420000h          ;加密的密碼經計算後的值,裝配時需修改
        diskey dd 0  ;是否用鑰匙盤的變數,為0時不用,1為A:,2為B:,裝配時需修改
            hdll dd        ?  ;儲存DLL控制程式碼的變數
        lpszfmt db "%s%s",0
            dll_name db        "mkey.dll",0
            error db        "錯誤",0
            caption1 db        "mkey.dll 沒有找到!",0
        lpszKNL db "KERNEL32.DLL",0
        lpszGetVer db "GetVersion",0
            call_name db        "Error",0
        lpszLoadError db "程式啟動時出錯!",0
        lpszError db "找不到所需的 .DLL 檔案 - ",0
        sint1 dd ?
            int1    dd        ?

IF DEBUG
        d_caption        db "測試",0
        d_sz        db "現在處於除錯狀態,請修改程式section(節表)的屬性(改為0XE0000020),不然就會出現非法操作",0
        d_sz1        db "現在開始修正輸入表",0
ENDIF
           
           
           
      @1:
            pop      EBX

IF DEBUG
        pusha
        push MB_OK
        lea eax,[offset d_caption-data1][ebx]
        push eax
        lea eax,[offset d_sz-data1][ebx]
        push eax
        push 0
        call MessageBox
        popa

ELSE


            call      anti_debug
ENDIF
        mov    eax,ebx
        mov edx,[offset imagebase-data1][ebx]
        sub eax,edx
        sub eax,5h
        mov [offset imagebase-data1][ebx],eax ;將計算後的載入基址存入變數imagebase中
        mov eax,[offset impRVA-data1][ebx]
        invoke RVAtoAddr,eax
        mov [offset impRVA-data1][ebx],eax
        call import ;修正原程式的輸入表

            lea      ECX,[OFFSET dll_name-data1][EBX]
            invoke LoadLibraryA,ecx ;載入mkey.dll
        .if eax==0      ;載入不成功
                  push      MB_OK
              LEa      EAX,[OFFSET error-data1][ebx]
            push      EAX
            lea      EAX,[OFFSET caption1-data1][ebx]
            push      EAX
            push      0 
            call MessageBoxA ;顯示錯誤資訊框
            push      0
            call    ExitProcess  ;退出
        .endif

IF DEBUG
ELSE
            call      deint
ENDIF
            mov      dword PTR[OFFSET hdll-data1][EBX],EAX           
            lea      ECX,[OFFSET call_name-data1][EBX]
            push      ECX
            push      EAX
                         
            call      GetProcAddress  ;取得DLL中顯示對話方塊的函式
            .if eax!=0
                    mov      EDX,[OFFSET key-data1][EBX]
            push      EDX
            mov edx,[offset diskey-data1][ebx]
            push edx
            call      EAX
        .endif           
freelibrary:
            mov      EAX,dword PTR[OFFSET hdll-data1][EBX]
            push      EAX
            call      FreeLibrary      ;解除安裝mkey.dll

            call      bw            ;防bw2000
IF DEBUG
ELSE
              mov      edx,[offset int1-data1][EBX]
          mov      ecx,[offset sint1-data1][ebx ]
              mov      [edx],ecx            ;修改INT1中斷門,破壞跟蹤環境
ENDIF
            mov      EAX,dword PTR[OFFSET call_ep-data1][EBX]
        xor    eax,80586h
        invoke RVAtoAddr,eax
        push      eax ;計算出原程式的入口值,壓入堆疊
           
            ret
           
;----------------------------------------------------------
;以下用於編寫一些反跟蹤的程式碼:
            anti_debug:
                call      trw
                
                ret           
;-----------------------------------------------------------
;防TRW,SOFTICE等的反跟蹤:
            trw:
                push      EdX
                sidt      [esp-2]
                pop      edx
                add      edx,8
        mov      dword PTR[OFFSET int1-data1][EBX],EdX                
            ret
;------------------------------------------------------------
;防bw2000找入口點:
              bw:
                lea edx, [OFFSET lpszKNL-data1][ebx]
        push edx
        call GetModuleHandle
                lea ecx,[offset lpszGetVer-data1][ebx]
        push ecx
        push eax
        call GetProcAddress
                cmp word ptr[eax],30cdh
                jnz nobw2000
        mov eax,0bff70451h
        jmp dword ptr[eax]
                    ;退出                             
                               
  nobw2000:
        ret
  deint: 
                  mov      edx,[offset int1-data1][EBX]
                    mov      ecx,[edx]
              mov      dword ptr[offset sint1-data1][ebx],ecx   
                  add      dword ptr[edx],2
              ret
           
  ;-----------------------------------------------------------------------------------------------------
  ;以下為過載原程式的輸入表內的涵數地址
  import proc uses eax ecx edi edx
IF DEBUG
        pusha
        push MB_OK
        lea eax,[offset d_caption-data1][ebx]
        push eax
        lea eax,[offset d_sz1-data1][ebx]
        push eax
        push 0
        call MessageBox
        popa
ENDIF
        
        mov edi,[offset impRVA-data1][ebx]
        mov ecx,[offset impSize-data1][ebx]
        xor edx,edx
        assume edi:ptr IMAGE_IMPORT_DESCRIPTOR   
        .while !([edi].OriginalFirstThunk==0 && [edi].TimeDateStamp==0 && [edi].ForwarderChain==0 && [edi].Name1==0 && [edi].FirstThunk==0)
            .if edx>=ecx
                jmp impend
            .endif
            mov eax,[edi].Name1
            invoke RVAtoAddr,eax
            mov esi,eax
            push edx
IF DEBUG
            pusha
            push MB_OK
            push eax
            lea eax,[offset d_sz1-data1][ebx]
            push eax
            push 0
            call MessageBox
            popa
ENDIF
            invoke GetModuleHandle,esi
            .if eax==0
                invoke LoadLibraryA,esi
                .if eax==0
                    push esi
                    lea eax,[offset lpszError-data1][ebx]
                    push eax
                    lea eax,[offset lpszfmt-data1][ebx]
                    push eax
                    lea eax,[offset dll_name-data1][ebx]
                    push eax
                    call wsprintf

                    push MB_ICONEXCLAMATION+MB_OK
                    mov eax,[offset lpszLoadError-data1][ebx]
                    push eax
                    mov eax,[offset dll_name-data1][ebx]
                    push eax
                    push NULL
                    call MessageBox
                    invoke ExitProcess,NULL

                .endif
            .endif
            mov dword ptr[esi],0
            mov [offset hdll-data1][ebx],eax
            mov eax,[edi].FirstThunk
            invoke RVAtoAddr,eax
            push eax                    ;FirstThunk的偏移量壓棧,
            .if [edi].OriginalFirstThunk!=0      ;有的聯結器會將OriginalFirstThunk的值置0,這時取FirstThunk所指的陣列的值指向涵數名
                mov eax,[edi].OriginalFirstThunk
                invoke RVAtoAddr,eax
                push eax                  ;OriginalFirstThunk的偏移量壓棧,這時eax所指陣列的值指向IMAGE_IMPORT_BY_NAME
            .else
                push eax    ;這時eax所指陣列的值指向IMAGE_IMPORT_BY_NAME
            .endif
            call SetprocAddr
            pop edx
            add edx,sizeof IMAGE_IMPORT_DESCRIPTOR
            add edi,sizeof IMAGE_IMPORT_DESCRIPTOR
        .endw
impend:

      ret
import endp

RVAtoAddr proc  RVA:DWORD
    mov eax,RVA
    ADD eax,DWORD PTR[offset imagebase-data1][ebx]
    ret
RVAtoAddr endp
           
SetprocAddr proc uses edi ecx esi edx naddr:DWORD ,faddr:DWORD

        mov edi,naddr
        mov esi,faddr
        .while DWORD PTR[edi]!=0
            .if dword ptr[edi]&80000000h ;判斷涵數是以序號方式引入,還是用名稱的方式引入。
                mov eax,dword ptr[edi]
                and eax,7fffffffh ;得到引入函式的序號
                push eax
            .else
                mov eax,DWORD PTR[edi]
                invoke RVAtoAddr,eax            
                assume eax:ptr IMAGE_IMPORT_BY_NAME

                IF DEBUG
                    pusha
                    push MB_OK
                    lea ecx,[offset d_sz1-data1][ebx]
                    push ecx
                    lea ecx,[eax].Name1
                    push ecx
                    push 0
                    call MessageBox
                    popa
                ENDIF

                lea ecx,[eax].Name1    
                push ecx
                push ecx
            .endif

                mov ecx,[offset hdll-data1][ebx]
                push ecx
            call GetProcAddress
            .if eax==0
                lea eax,[offset lpszLoadError-data1][ebx]
                push MB_ICONEXCLAMATION+MB_OK
                push eax
                push eax
                push 0
                call MessageBox
                invoke ExitProcess,0
            .endif
            .if !(dword ptr[edi] & 80000000h)
                pop ecx
                mov DWORD PTR[ecx-2],0
            .endif
            mov DWORD PTR[esi],eax
            add esi,sizeof IMAGE_THUNK_DATA
            add edi,sizeof IMAGE_THUNK_DATA
          .endw

        ret
SetprocAddr endp
           
           
;----------------------------------------------------------
           
        END    start

相關文章