你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 计算机安全与维护
6.17 用Win32汇编语言对PE格式的EXE文件进行口令加密(下)
 

szUser32    db  'user32',0

szMessageBox    db  'MessageBoxA',0

;定义指向对话框函数的指针变量及常量的定义

_GetModuleHandle _ApiGetModuleHandle ?  

_GlobalAlloc _ApiGlobalAlloc ?      

_MultiByteToWideChar _ApiMultiByteToWideChar ?

_DialogBoxIndirectParam _ApiDialogBoxIndirectParam ?

_GlobalFree _ApiGlobalFree ?       

_EndDialog _ApiEndDialog ?        

_GetDlgItemText _ApiGetDlgItemText ?   

_SetWindowText _ApiSetWindowText ?    

_SendDlgItemMessage _ApiSendDlgItemMessage ?

szGetModuleHandle db 'GetModuleHandleA',0

szGlobalAlloc db 'GlobalAlloc',0

szMultiByteToWideChar db 'MultiByteToWideChar',0

szDialogBoxIndirectParam db 'DialogBoxIndirectParamA',0

szGlobalFree db 'GlobalFree',0

szEndDialog db 'EndDialog',0

szGetDlgItemText db 'GetDlgItemTextA',0

szSetWindowText db 'SetWindowTextA',0

szSendDlgItemMessage db 'SendDlgItemMessageA',0

APPEND_PASSWD_CODE equ  this byte

OldPswdText   db 30 dup(0)          ;加密后留存的口令

PswdText       db 30 dup(0)         ;对话框输入的验证口令

TitleName      db 'Enter PassWord',0

ButtonName   db '确定',0

FontName      db 'Times New Roman',0

ID_PSWD equ  101

ID_EXIT equ  202

ID_CAPTION equ 11011

szCaption db "问题提示:",0

TitleText db "请输入口令:",0

ErrPasswd db "口令错误!",0

hInstance1 dd ?

@strlen11 dd ?

@strlen22 dd ?

;取字符串长度过程

strlen  proc    _dwarg

        local   @count

        mov @count,0

        pushad

        cld

        mov esi,_dwarg

@@:     lodsb

        inc @count

        cmp al,0

        jz  exit

        jmp @b

exit:  

        popad

        mov eax,@count

        ret

strlen  endp

;口令核对过程

ChkEnterpswd   proc

        pushad

        call @f

        @@:

        pop ebx

        sub ebx,offset @b

        lea eax,[ebx+PswdText]

        invoke strlen,eax

        mov [ebx+@strlen11],eax

        lea eax,[ebx+OldPswdText]

        invoke strlen,eax

        mov [ebx+@strlen22],eax

        mov ecx,[ebx+@strlen11]

        mov eax,[ebx+@strlen22]

        .if ecx < eax

         xchg eax,ecx

        .endif

        lea esi,[ebx+OldPswdText]

        lea edi,[ebx+PswdText]

        cld

        repe cmpsb

        .if ZERO?

        popad

        mov eax,TRUE

        ret

        .else

        popad

        mov eax,FALSE

        ret

        .endif    

ChkEnterpswd   endp

;对话框过程

DlgProc proc hWnd:dword,uMsg:dword,wParam:dword,lParam:dword

      call @f

      @@:

      pop ebx

      sub ebx,offset @b     

      .if uMsg==WM_COMMAND

         mov eax,wParam

         .if  ax==ID_PSWD

         lea edx,[ebx+PswdText]

         invoke [ebx+_GetDlgItemText],hWnd,ID_PSWD,edx,30

         .elseif ax==ID_EXIT

         invoke [ebx+_EndDialog],hWnd,NULL

         .endif

     .elseif uMsg==WM_INITDIALOG

        lea ecx,[ebx+TitleText]

        invoke [ebx+_SetWindowText],hWnd,ecx

        invoke  [ebx+_SendDlgItemMessage],hWnd,ID_PSWD,EM_LIMITTEXT,18,NULL

        invoke  [ebx+_SendDlgItemMessage],hWnd,ID_PSWD,EM_SETPASSWORDCHAR,42,NULL

     .else

     mov eax,FALSE

     ret

     .endif

     mov eax,TRUE

     ret

DlgProc endp

;口令加密代码的入口

_NewEntry:

;重定位

        call    @F

        @@:

        pop ebx

        sub ebx,offset @B

 

        invoke  _GetKernelBase,[esp]       ;获取Kernel32.dll基地址

        mov [ebx+hDllKernel32],eax 

        lea eax,[ebx+szGetProcAddress]     ;获取GetProcAddress入口地址

        invoke  _GetApi,[ebx+hDllKernel32],eax

        mov [ebx+_GetProcAddress],eax

        lea eax,[ebx+szLoadLibrary]        ;获取LoadLibrary入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllKernel32],eax

        mov [ebx+_LoadLibrary],eax

        lea eax,[ebx+szUser32]              ;获取User32.dll基地址

        invoke  [ebx+_LoadLibrary],eax

        mov [ebx+hDllUser32],eax

        lea   eax,[ebx+szGlobalAlloc]       ;获取GlobalAlloc入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllKernel32],eax

        mov   [ebx+_GlobalAlloc],eax

        lea   eax,[ebx+szGetModuleHandle]    ;获取GetModuleHandle入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllKernel32],eax

        mov [ebx+_GetModuleHandle],eax

        ;获取MultiByteToWideChar入口地

lea  eax,[ebx+szMultiByteToWideChar]

        invoke  [ebx+_GetProcAddress],[ebx+hDllKernel32],eax

        mov   [ebx+_MultiByteToWideChar],eax

     

        lea   eax,[ebx+szGlobalFree]         ;获取GlobalFree入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllKernel32],eax

        mov   [ebx+_GlobalFree],eax

        ;获取DialogBoxIndirectParam入口地址

        lea   eax,[ebx+szDialogBoxIndirectParam]

        invoke  [ebx+_GetProcAddress],[ebx+hDllUser32],eax

        mov   [ebx+_DialogBoxIndirectParam],eax

        lea   eax,[ebx+szEndDialog]          ;获取EndDialog入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllUser32],eax

        mov   [ebx+_EndDialog],eax

        lea   eax,[ebx+szGetDlgItemText]     ;获取GetDlgItemText入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllUser32],eax

        mov   [ebx+_GetDlgItemText],eax

        lea   eax,[ebx+szSetWindowText]      ;获取SetWindowText入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllUser32],eax

        mov   [ebx+_SetWindowText],eax

        lea   eax,[ebx+szSendDlgItemMessage] ;获取SendDlgItemMessage入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllUser32],eax

        mov   [ebx+_SendDlgItemMessage],eax

        lea eax,[ebx+szMessageBox]           ;获取MessageBox入口地址

        invoke  [ebx+_GetProcAddress],[ebx+hDllUser32],eax

        mov [ebx+_MessageBox],eax

        pushad

   invoke [ebx+_GetModuleHandle],NULL        ;获取本模块的句柄

   mov [ebx+hInstance1],eax

   ;对话框模板

   ;申请长度为4K,用0初始化,地址固定的内存块,用于建立对话框模板。

   invoke [ebx+_GlobalAlloc],GMEM_FIXED or GMEM_ZEROINIT,1024*4

   mov esi,eax

   mov edi,eax

   mov dword ptr  [edi],DS_SETFONT or WS_SYSMENU or WS_OVERLAPPED  ;对话框样式

   mov word ptr    [edi+8],2                 ;控件数目

   mov word ptr    [edi+10],200

   mov word ptr    [edi+12],180              ;对话框的屏幕坐标(200,180)

   mov word ptr    [edi+14],110

   mov word ptr    [edi+16],60              ;对话框的大小110×60

   add edi,22                                ;菜单2字节、CLASS 2字节,共22字节

   lea edx,[ebx+TitleName]

   invoke strlen,edx

   mov ecx,eax

   push ecx

   invoke [ebx+_MultiByteToWideChar],CP_ACP,MB_PRECOMPOSED,edx,ID_CAPTION,edi,eax

   pop ecx

   mov eax,ecx

   shl eax,1

   add edi,eax

   mov word ptr [edi],9                       ;字体点阵大小

   add edi,2

   lea edx,[ebx+FontName]

   invoke strlen,edx

   mov ecx,eax

   push ecx

   invoke [ebx+_MultiByteToWideChar],CP_ACP,MB_PRECOMPOSED,edx,-1,edi,eax

   pop ecx

   mov eax,ecx

   shl eax,1

   add edi,eax

   add edi,3

   shr edi,2

   shl  edi,2                                    ;起始地址双字对齐

;按钮控件

   mov dword ptr [edi],WS_VISIBLE or WS_CHILD    ;按钮样式

   mov word ptr [edi+8],30

   mov word ptr [edi+10],27                      ;按钮在对话框中的坐标(30,27)

   mov word ptr [edi+12],40

   mov word ptr [edi+14],12                      ;按钮的大小40×12

   mov word ptr [edi+16],ID_EXIT                 ;按钮标识

   mov word ptr [edi+18],0ffffh

   mov word ptr [edi+20],0080h                   ;序数值0080h代表Button

   add edi,22

   lea edx,[ebx+ButtonName]

   invoke strlen,edx

   mov ecx,eax

   push ecx

   invoke [ebx+_MultiByteToWideChar],CP_ACP,MB_PRECOMPOSED,edx,-1,edi,eax

   pop ecx

   mov eax,ecx

   shl eax,1

   add edi,eax

   add edi,3

   shr edi,2

   shl  edi,2                                     ;起始地址双字对齐

;编辑控件

   mov dword ptr [edi],WS_VISIBLE or WS_CHILD or WS_TABSTOP or WS_BORDER  ;编辑框样式

   mov word ptr [edi+8],13

   mov word ptr [edi+10],10                       ;编辑框在对话框中的坐标(13×10)

   mov word ptr [edi+12],80

   mov word ptr [edi+14],12                       ;编辑框的大小80×12

   mov word ptr [edi+16],ID_PSWD                  ;编辑框标识

   mov word ptr [edi+18],0ffffh

   mov word ptr [edi+20],0081h                    ;序数值0081h代表Edit

   add edi,22

   lea edx,[ebx+PswdText]

   invoke strlen,edx

   mov ecx,eax

   push ecx

   invoke [ebx+_MultiByteToWideChar],CP_ACP,MB_PRECOMPOSED,edx,-1,edi,eax

   pop ecx

   mov eax,ecx

   shl eax,1

   add edi,eax

   add edi,3

   shr edi,2

   shl  edi,2

   lea ecx,[ebx + DlgProc]

   ;创建模态对话框

   invoke [ebx + _DialogBoxIndirectParam],[ebx+hInstance1],esi,NULL,ecx,NULL

   ;对话框关闭后释放申请的内存块

   invoke [ebx + _GlobalFree],esi

   popad

   invoke ChkEnterpswd               ;校对用户输入的口令的正确性

   .if !eax                         ;口令错误,则退出。

   lea ecx,[ebx+ErrPasswd]

   lea eax,[ebx+szCaption]

   invoke [ebx+_MessageBox],NULL,ecx,eax,MB_OK

   ret

   .endif

;口令正确,执行原来的目标PE文件

    db 0e9h       ;0e9hjmp xxxxxxxx的机器码

RetOldEntry: 

               dd     ?   ;用来填写返回到目标PE文件的入口地址

APPEND_CODE_END equ this byte

三、结语

   本文在Windows XP中文版下对多个PE文件进行测试,效果良好。还有可以改进的地方,如对输入的口令进行加密,增加防静态分析和反动态跟踪的功能,使加密软件更加安全可靠。另外,有兴趣的读者可以在此加密原理的基础上,开发出对应的解密程序(或防病毒免疫程序),以更加方便实用。

 

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089