admin管理员组

文章数量:1532463

2024年7月14日发(作者:)

用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] ;获取基地址

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] ;获取基地址

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,e

ax

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 ;0e9h是jmp xxxxxxxx的机器码

RetOldEntry:

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

APPEND_CODE_END equ this byte

三、结语

本文在Windows XP中文版下对多个PE文件进行测试,效果良好。还有

可以改进的地方,如对输入的口令进行加密,增加防静态分析和反动态跟踪的功

能,使加密软件更加安全可靠。另外,有兴趣的读者可以在此加密原理的基础上,

开发出对应的解密程序(或防病毒免疫程序),以更加方便实用。

本文标签: 口令对话框加密文件