admin管理员组文章数量:1530864
2024年7月14日发(作者:)
维普资讯
* … — …… - … 0’… ~ * |^-… … 】
实用第--/智慧密集
… … …… … ~… … … 一…… … …
Win
张镄
摘要 介绍了用Win32汇编对PE格式EXE文件进行口令加密的基本原理和方法,并给
出了实用的加密代码,对研究文件的加密很有参考价值。
关键词 Win32汇编,PE格式文件,口令加密
一
般程序员开发的软件并不希望别人随便使用,为了防止
就是采用此法,但要求文件头部有足够的空隙来构建节表等。
别人的非法使用,一般是通过加密的方法对软件进行保护,口
第三种方法是把附加代码附在目标文件的尾部,构成一个新代
令加密只是加密方式中的一种。虽然加密的方法对解密高手而 码节,这种方法的优点是附加代码的长度不受限制,但文件的
言,并不能百分之百的保护,但对一般的使用者来说,加密保 长度会增加,另外,要求文件头有一定的空隙来构建节表。本
护软件的方法,仍是有效的。 文采用第一种和第三种方法,目的是提高加密的成功率。
Win32环境下PE格式的文件形式有EXE、DLL、OCX、 要对PE文件进行口令加密,首先要对PE文件的结构有
SCR等 其中常用的可执行文件是EXE文件,对PE格式的 所了解,下图就是PE文件的基本结构,从这个PE文件的结
EXE文件进行口令加密,就是在目标EXE文件上附加一段代
构中,可以看到PE文件是由DOS头、PE文件头、节表和节
码,通过附加代码中的对话框获取口令,并与附加代码里留存
等组成,每一个节表对应一个节,节表的排列顺序,也就是节
的口令进行比较,当口令一致时,表示用户是合法的,否则是
的排列顺序 PE装载器就是根据PE文件头结构和节表结构中
非法用户。
的相应字段将有关的节装入内存中,当然有些节如重定位节
本口令加密软件分为三个模块。模块1的功能是生成对话
( reloc节)是不必装入内存的。将加密代码附在日标PE文
框,选择目标文件,输人口令及校核口令的正确性;模块2的 件后面,就是将加密代码做成一个代码节附在PE文件的后
功能是判断目标文件是否是PE格式的EXE文件,是否已口令
面,为了使PE装载器正确地加载附加的加密代码节,必须构
加密,留存口令,修改目标文件头里的有关结构中的相关字
建一个新节表使其指向加密代码节,而新添加的节表须位于原
段,并把加密代码附在目标文件上;模块3的功能是重定位, PE文件节表的末尾,这就要求文件头中的空隙要≥40B(因为
搜索加密代码中所要用到的API函数的地址,以便使用这些
节表结构的长度为28H),满足这个条件才能建立一个新的节
API函数生成对话框,并由对话框接收口令,校核口令的正确
表。而将加密代码插入节的空隙中,不用构建新节表。
性,口令正确运行目标文件,口令错误则退出。由于模块1较
▲
10s头 m能GE—c》0s.1H队DER
简单,本文主要说明模块2和模块3的功能与作用。
.. D0S Stub
▲
志 PEO0”
一
、
在目标文件上附加口令加密代码
pE
E文件头 IMAGE
FILE
....
HEADER
● lMAGE_OP11ONA _HEADER32
在对PE格式的EXE文件上附加代码的的方法常用的有三
▲
IMAGE SEC11ONHEADER —
_
种方法。第一种方法是将附加代码插入在目标文件的代码节或
_襄 rMAGE SECTION_HEADER —
其他节(如数据节)的空隙中,一般文件中节对齐在文件中的
nT曲1e、 IMAGE
SECTION_MEADER —
_
最大长度是512B(200H),如ML汇编器生成的文件默认文
I ̄GE_SEC11ON_HEADER 一
件对齐参数为512B,而代码至少要占用1B,所以最大空隙长
文件头中的空隙
度不超过51 1B。但也有一部分文件,如VC++编译器生成的
▲
t瞰节 .-
I
文件其默认文件中节对齐的最大长度为4KB(1000H),因
枯 蛐节 ●
此,即使是加密代码较长,只要小于4KB,也完全可以插入其
;c矗iOn .rs 节 ■}—一
节中空隙。第二种方法是将附加代码分段插入文件中的不同节
oc节 ・●—一
的空隙中,这种方法的优点是不会增加文件的长度,CIH病毒
●
PE文件的基本结构图
2008
电麓确程 冀|技巧冀壤护 _l
维普资讯
……
C0啊PUTER PR0GR^啊啊lHG MAINTENANCE……… ……… …… ………… ………… … ……………
Characteristics dd 7l j 节的属性
IMAGE._SECTION
HEADER ENDS
_
在口令加密中我们要用到文件头中的以下结构及相应
段:
1.DOS头结构:
IMAGE
DOS,HEADER STRUCT
_
本IJ令加密算法采用将代码插入节中优先,这样可保证文
件的长度不变;当节空隙不够时,再采用构建一新代码节。在
目标PE文件中附加口令加密代码的主要过程如下:
e_magic WORD? ;DOS头标志,“MZ”
e/fanew DWORD 7 ;指向PE文件头(或文件头偏移
003ch) ,
IMAGE DOS HEADER ENDS
(1)判断是否是PE格式的EXE文件,不是则退出;
(2)判断该PE格式EXE文件是否已加密,加密标志设为
“
zz”
,
已加密则退出;
(3)循环检查节的空隙是否足够,如空隙足够则将加密代
码插入对应节空隙中,修改对应节表中的相应字段Virtual—
Size、Characteristics,修改文件的入 1:3地址Ac]dressOfEntry—
2.PE文件头(NT映像头)结构
IMAGE_NT_HEADERS STRUCT
Signature DWORD
_
;.PE文件头标志,“PE00” Point,指向加密代码的开始执行点,将修改后的文件头写入目
FileHeader IMAGE
FILE EADER<>
OptionaIHeader IMAGE_OPTIONAL HEADER32<>
IMAGE NT HEADERS ENDS
标PE文件的头部,将返回地址和口令写入加密代码中,加密
完成后退出。
(4)当节的空隙不够时,判断文件头是否有足够的空隙容
3.映像文件头(FileHeader)结构
IMAGE_FILE_HEADER STRUCT
纳新的节表(节表长度28H),不足退出,放弃口令加密;
(5)有新的节表空隙,修改NT映像头中的相关字段;
由于新建了一个节(节表),所以要节数+1,即Num—
berOfSections+1,并修改SizeOfCode和SizeOflmage;另外,要
NumberOfSections WORD
IMAGE_FILE EADER ENDS
;节表(节)的数量
修改文件的入口地址AddressOfEntryPoint,使其指向加密代码
的开始执行点;
,
4.可选映像头(0pti0nalHeader)结构
lMAGE OPTIONAL HEADER32 STRUCT
(6)在文件头中的空隙处建立一新节表,并为新节表的相
关字段赋值,使其指向新建的加密代码节;
有Name 1、VitrualSize、VitrualAddress、SizeOfRawData、
PointerToRawData、Characteristics。
SizeOfCode DWORD 7 :所有含代码的节的总长度
.
AddressOfEntryPoint DW0RD 7
.:程序开始执行的入口地址RVA ,
SectionAlignment DWORD 内存中节对齐的粒度
FileAlignment DWORD 7 ;文件中节对齐的粒度
SizeOfImage DWORD 7
其中新代码节的VitrualAddress:末节的VitrualAddress+末
节的VitrualSize并按secti0nAlignment对齐,新代码节的Size—
j内存中整个PE文件映像的大JJ、
SizeOfHeaders DWORD 7
OfRawData=加密代码的长度按FileAlignment对齐,新代码节
的PointerToRawData=末节l ̄JPointerToRawData+末节的Size一
0fRawData:
;DOS头+PE文件头+节表的大小
DataDirectory IMAGE_DATA_DIRECTORY 6dup(《>)
(7)将修改后的文件头写入目标PE文件的头部;
(8)将口令加密代码作为一新建代码节附加在目标PE文
件的尾部;
;数据目录结构数组
IMAGE OPTIONAL_HEADER32 ENDS
5.节表结构
IMAGE SECTION HEADER STRUCT
(9)将返回地址写入加密代码中;
(10)将口令写入加密代码中。
下面是附加口令加密代码的主要过程源程序,为了方便阅
Namel db IMAGE_SIZEOF_SHORT_NAME dup《 )
;
节的名称,长度8字节
读加了必要的注释;另一点要注意的是PE文件的头部在磁盘
文件里和在内存映射中是完全一致的,所以我们另外申请了一
内存块把它装在内存中来修改又快又方便,然后将其重新写入
Unl on}Misc
VirtualSize dd?;节的实际大JJ、
ends
目标文件的头部来完成对文件头的修改。实现代码如下:
handlePeFile proc
VirtuaIAddress dd i节装入内存后的偏移地址RVA
SizeOfRawData dd?
定 过程骶要禺 禺 变量
节在文件中按FileAlignment对齐后的大JJ、
PPointerToRawData'dd 7;节在文件中的偏移地址
Qca\@:hFiie;@hMapFi!e,@、p emo @IpAI10c @
dvvRet;@SizeOfHeader
\oca\@ @dwPENeader_off,@RieAiign,@See-
维普资讯
实用第一 智慧密集
tionAlign.@SectionNum
local@NewSection
off.@AppC囱eSize,@AddCodeVirt,@
Tip,MB OK
jmp_ErrFormat:不是PE格式文件,退出
endif
AddCodeFile
pushad
:‘zz’已加密标志,判断是否已加密,用于防止重复加密
ifwordptr【ebx+1 ah】
tionTip,MB OK
:创建处理异常的SHE结构
assume fs:nothing
push
push
push
ebp
offset ErrFormat
offset Handler
= zz
invoke MessageBox,NULL,addr szCodeText,addr szCap—
jmp E rrFormat:已加密退出
.
endif
push fs:【O】
push【ebx】.0pt;ona1Header.FileAlignment
movfs:【O】,esp
:将后面要用的参数赋给局部变量
pop@FileAlign
:取目标PE文件的扩展名,判断是否是.exe
invoke Istrlen,addr szFileName
lea ecx,szFileName
push【ebx】.0ptionalHeader.SectionAlignment
pop@SectionAlign
movedx,dword ptr【ecx+eax一4】 push【ebx】 0ptionalHeader.SizeOfHeaders
pop@Size0fHeader
or edx,20202020h :将大写字符转换为小写
ifedx!= exe. :不是.exe则退出
.
push【ebx】.0ptionalHeader.AddressOfEntryPoint
pop@dwEntry invoke MessageBox,NULL,addr szTexttip,addr szCaption—
Tip,MB OK
movzxeax,【ebx】.FileHeader.NumberOfSections
deceax
imp_Ret
endif
mov@SectionNum eax
movecx sizeof lMAGE SECTION HEADER
mulecx .
:以可读、可写方式打开已存在的目标PE文件,如打开只读
文件或不存在的文件会报错
invoke CreateFile,addr SzFileName.GENERlC READ or
GENERlC WRITE FILE SHARE READ or\
FlLE SHARE WRITE,NULL,OPEN EXISTING,
FlLE ATTRfBUTE ARCHlVE NULL
ifeax f=fNVALfD HANDLE VALUE
add eax.@dwPE Header off
add eax.sizeof lMAGE NT HEADERS
addeax.sizeoffMAGE SECTION HEADER
mov@NewSection pff eax
:申请一块内存,长度为Size0fHeaders,用于文件头的修改
invoke GlobalAIIoc,GPTR,【ebx】
OptionalHeader.SizeOfHeaders
mov@hFile eax
:创建内存映射对象
invoke CreateFileMapping,@hFile,NULL,
PAGE
READWRITE,0,0,NULL
mov@IpAlloc eax
movedi,eax
.
feax
mov@hMapFile eax
:将打开的内存映射文件的头部,长度为Size0fHeaders,传
:送到申请的内存块里
invoke RtlMoveMemory,edi,@IpMemory,f ebx】
OptionalHeader.SizeOfHeaders
:创建内存映射文件
invoke MapViewOfFile,eax,FILE MAP READ or
FILE
MAP_WRITE,0,0,0
invoke UnmapViewOfFile @IpMemOrv
.
ifeax
:关闭内存映射文件,后面不用了。
mOv@IpMemory eax
invoke CloseHandle,@hMapFile
movebx,eax
assumeebx:ptrlMAGE D0S HEADER
.
:关闭内存映射对象,后面不用了。
addedi,dword ptr【edi 4-3ch】 :edi一一>丰旨向PE文件头
assumeedi:ptrIMAGE NT HEADERS
movesi,edi
ifwordptr【ebx】!= ZM
判断D0S头标记, ‘MZ’
invoke MessageBox,NULL,addr szE rror,addr szCaption—
Tip,MB OK
add esi.sizeof fMAGE NT HEADERS
assumeesi:ptrlMAGE_SECTION HEADER
jmp_ErrFormat :不是PE格式文件,退出
endif
mov ecx,offset APPEND CODE END—offset
APPEND CODE
pushecx
moveax febx】.eJfanew
mov@dwPE/-Ieader
off,eax
Pop@AppCodeSize;加密代码的长度
xorebx ebx
addebx,【ebx】eJfanew :ebx一一>丰旨向PE文件头
assumeebx:ptrlMAGE NT HEADERS
;循环检查每个节中是否有足够的空隙来插入代码
.
ifword ptr【ebx】!= EP
repeat
:判断PE文件头标记,‘PE
invoke MessageBox,N ULL,addr szError,addr szCaption一
mov edx,【esi】.SizeOfRawData
.
_fl edx :判断SizeOfRawData是否为0,为0表示该
84_电 与雏
维普资讯
……
COMPUT矾PROGB删MING啊^l町E帅脯CE…………… …一…………………………………………………
PEND_CODE
mov[ebx]i Misc,\,i髓ualsize;ecx
__
:节是未初始化数据的节,跳过
incebx
add esi,sizeof I MAGESECTION
HEADER
continue
endif
sub edx,\esi]. isc.VirtualSize
:如果[esil.SizeOfRawData<【esil-M;se.VitrualSize,
:则Cf=。1, 过o.
.
ifCARRY
、 incebx
addesi,sizeofIMAGE SECTION EADER
.
continue
endif .
ifedx>=ecx
:节中空隙足够,则将加密代码插入节的空隙中。
\mp insert_code
.
endif
addesi|sizeofIMAGE_SECTION_HEADER
incebx’
.
Until ebx>@SectionNum
:当各节空隙都不够插入加密代码时,添加新节(表)。
movedi @IpAIIoc
movebx e
add ebx,@NewSection
off
_
:ebx—一一>丰旨向最后一个节表的尾部(新节表的头部)
pushad
:检查文件头是否有足够空隙构建新节表
movledi,ex
moval,0
mov。ecxf sizeof IMAGE
SECTION_HEADER
_
cld
repe scasb
popadI
ifIZEROl7
invoke Me ssage Box NULL add{szNoRoom,addr szCap-
tionTip,MB_OK
NoRoomRe弋
t
invoke Globa^Free,@IpAIIoc
._
.
i文件头没有足够空隙构建节表 退出司令加密
endif
mov edx,ebx"
|一Subedx,sizeofIMAGE_SECTION_HEADER _
ledx一一一 抬 最黾一令 轰 头部
AGE.SECT IO EA DE R
|
| |I I
assume ebx:ptr IMAGE_S ECTIONJ-IEADER,edx:ptr IM-
一ll|。
addedi,dwordptr[勖文4-3ch、
一
|。j始 PE文侮头
|一- 羹 。assumeedi 州MAGE_NT HEADERS
inc[edi、 ̄FileHeader.NumberOfSections 数
m州eax,[edx].PointerToRawData 。
|。 0|addeax,[。edx],SizeOfRawData | ll l 。
| |I| | mov[ebx].PointerToRawData,eax 薯| l |一
…
’I mov ecX ;of肆se静tA锵PPEN|D
_
CQDEI
|
j
叠
|乏
|
-
i
l
off
s
et
A P
 ̄N D  ̄
维普资讯
… ……一… ……… … …… …… … ………
实用第一 智慧密集
… ………… ……… … ………一…………………
,
;关闭内存映射文件
endif
mov eax,{esi】VirtualAddress
aa—aeax
,
【esi】.Misc VirtualSize
‘
mov@AddCodeV{ft,eax
ql'10V IeCX,【esi l 】PointerToRawData
,
,
invoke CIoseHandle,@hMapFile:关闭内存映射对象
endif
.
aa~a ecx
,
【esi】 Misc.VirtualSize
NoRoom Ret:invoke CloseHandle-,@hFile
ql"lOV@AddCOdeFiIe.ecx
:关闭打开的目标PE文件
else
mov eax.@ApPCodeSize
aa—a【esi】.Misc.VirtualSize,eax;修改节的实际大小
invoke MessageBox,NULL,8a。a。r szErrCreate,addr szCap-
mlovwora。l0tr【edi+1 ah】, ZZ ;设置力13密标志为 zz
;以下是二种附加加密代码的公用程序部分,这样设计是
:为了减小程序的长度
:修改目标PE文件的入IZl地址,使其指向口令加密代码的
:开始执行处
append‘
coa。e:mov eax
_
,
@AddCodeVirt
aa—a eax
,
(offset ewEntry—offsetAPPEND C0DE)
mov【edi】.0pt{onaIHeader.AddressOfEnt广yPoint,
eaX
;nvoke SetFilePointer,@hF_Ie.0,NULL,FILE BEGIeN
:将修改后的文件头写入目标PE文件的头部
invoke WriteFile,@hFile,@IpAIIoc,@SizeOfHeacl。一
er,\
addr@dwRet.NULL
mov eax,@AddCodeVirt
aa—a eax
,
(offsetRetOldEntrv—offset
APPEND CODE+4)
sub@dwEntry.eax
:@dwEntry一加密代码执行完后,返回原程序执行的地址
mov ecx,@AddCodeFile
add ecx ,(offset RetOIdEntry—offset
APPEND CODE)
invoke SetFjIePOinter,@hFile,ecx,NU LL,
FfLE BEGfN
将返回地址写在加密代码中0e9h(’imp机器码,1I的后面
invoke WriteFile。@hFile,aadr@dwEntry,4 addr@
dwRet NULL ‘
mov ecx,@AddCodeFile
aa~a ecx
,
(offset APPEND_PASSWD_c0DE—offset
APPEND CODE)
invoke SetFiIePOinter,@hFiIe,ecx,NULL,FILE。一
BEGfN
将校核后的口令(最大长度为3O个字符) 写入附加的加密
:代码留存口令处
invoke WriteFile,@hFile,offset szPwdBuffer2,30,
addr@dwRet,INULL ,
invoke GlobalFree,@IpAlloc:关闭申请的内存块
invoke CloseHandle.@hFile
;关闭打开的目标文件
assume edi:nothing esi:nothing
ervoke MessageBox,NULL,addr szOkCode,addr szCap-
tionTip,MBOK
jmp et
_ErrFormat:
assume ebx:nothing
invoke Unma pViewOfFile,@fpMemory
电 螭雅
tionTip,MB OK
.
endif
et:
popfs:10】
addeso。0chI
popaa。
ret
lhandlePeFile ena。p
二、口令加密的主要功能
1.重定位
由于加密代码是在编译、连接之后附加在目标PE文件的
尾部或节的空隙中,而各个目标文件的长度又是可变的,导致
附加代码中的变量或过程名偏移地址在装入内存后发生变化,
使之在目标文件中运行时寻址错误,为了使附加代码中的变量
地址正确,必须进行重定位。其重定位的标准格式如下:
call@F
@@:
pIop ebx
:这个寄存器不一定非用ebx,也可使用其他不常用的寄存器
sub ebx,offset@B
2.动态获取API函数地址
由于加密代码是附在各种目标文件的尾部或节的空隙中,
所需要的API函数地址,各个目标PE文件不可能为你准备
好,因此,加密代码必须自己想法解决。这就是要用LoadLi—
brarT函数来动态装入某个DLI 模块,然后再用GetProcAddress
函数从装入的DLL模块中获取所需要的AP[函数的人口地
址。但是这二个函数都位于Kernel32.dll中,注意到当Ker.
ne132.dll把目标程序装入内存后,堆栈的顶部存放有程序的返
回地址,而这个返回地址正好位于Kernel32.dll中;因此,加
密代码一开始执行,就从堆栈中取出该地址【esp](如果程序一
开始就压栈后再取出返回地址,那应是此形式【esp+XXXX]7,
搜索Kernel32.dll的基地址,然后再搜索GetProcAddress的人
口地址,获得GetProcAddress的人口地址后,再调用GetPro—
cAddress函数获取LoadLibrary函数的人口地址,有了这二个函
数后加密代码所需要的AP1就可以轻松获得。
3.在加密代码中生成对话框
对于普通的对话框程序来说生成对话榧较简单,只要在
Link的时候把程序的目标文件.o 和资源文件.res连接起来
就可实现。而对于加密代码而言,生成对话框就不那么简单
维普资讯
……
C0啊PUTEB PROMAMMING MAINTENANCE……………………………………………………………………
了,不单是需要API函数,而且还需要资源文件,对话框能否
一
实现是口令加密的关键问题也是最难的问题,因为加密代码需
要用对话框来接收输入的口令。当然用命令行输人口令也可
ey
...
woRD 曩;JX、cy控件的宽和高 j一。 j 毫
Q D 1 0 \D | j|j
|
以。好在Win32汇编提供了对话框模板结构,使我们的问题得
以解决。无论是模态对话框还是非模态对话框,其建立的过程
都会用到模板,而模板就是具有相对固定格式的内存块,其中
的数据用以建立对话框的资源和控件,如菜单、子窗口控件、
标题栏等,专供代码调用。
对话框模板主要由二部分组成:模板头和模板控件。
(1)模板头
模板头定义对话框的大小、样式、菜单、CLASS、标题名
d
DLG iTEMTEMP ̄TE ENDS
称等。模板头开始的结构如下:
DLGTEMPLATE STRUCT
style DWORD 7:对话框样式,如WS APTl0N、
WS_SYSMENU等
dwExtendedStyIeDWORD 7:扩展样式,对话框不使用
cdit
X
WORD ?:对话框中控件韵数目
WORD ?
Y
lx
WORD 7;x、Y对话框的屏幕坐标
WORD 7
f
ly WORD ?;Ix、ly对话框的宽和高
紧跟DLGTEMPLATE结构后面的是菜单、CLASS和对话框
DLGTEMPLATE ENDS
标题等组成的三种可变数组。
菜单数组:数组元素都是字,数组边界须字对齐。若数组
第一个元素为0,则该对话框不带菜单,并且数组只有一个元
紊;若数组第一个元素为Offfh,则第二个元素为菜单资源的序
数值,接着就是Unicode字符集的菜单资源的字符串名。
CLASS数组:数组元素都是字,数组边界须字对齐。若数
组的第一个元素为0,则为标准控件或通用控件类,并且数组只
有一个元素;若数组第一个元素为0ffffh,则第二个元素为系统
预定义窗口类的序数值,接着是Unicode字符集的窗口类的字符
串名。
标题数组:紧跟在CLASS数组后的是Unicode字符集的标
题栏名(以0结束),如果都是0则对话框无标题栏。注意,如
果对话框指定了样式为Ds ETFONT,则紧跟在标题栏后的字指
定字体的点阵大小,后面跟着Unicode字符集的字体名字符串。
(2)模板控件
模板控件定义控件的大小、样式、CLASS、控件标题、成形
数据等。模板控件的开始结构如下:
DLGITEMTEMPLATE STRUCT
style
dwExtendedStyle
DWORD 7:控件样式
DWORD 7
× WORD 7
维普资讯
……… … ………… … … …一一 一… …… ………
实用第一 智慧密集
rotoDialogBoxlndirectParam
_
Ioca}@count
mov@count,0
pushad
cId
ApiGIobalFreetypedef ptr rotoGIobalFree
piEndDialog typedef ptr_ProtoEndDialog.
piGetDIgltemTexttypedef ptr_ProtoGetDIgltemText
=ApiSetWindowText typedef ptr rotoSetWindowText
ApiSendDIgltemMessage typedef ptr
mov esi,_dwarg
@@:lodsb
inc@count
cmpal 0
__ProtoSendDigItemMessage
:附加到目标PE文件上的口令加密代码从这里开始
APPEND
C:ODE equ this byte
_
jz exit
jmp@b
exit:
popad
include zz
GetKerne1.asm
_
hDIIKerne132 dd 7
hDIIUser32 dd 7
—
GetProcAddress piGetProcAddress 7
MessageBox ApiMessageBox 7
moveax.@count
ret
上oadLibrary ApiLoadLibrary 7
szLoadLibrary
szUser32 db
strlen ene。o
db LoadLibraryA ,0
:口令核对过程
ChkEnterpswd proc
lDushad
szGetPrOcAddress db GetProcAddress ,O
user32 .O
MessageBOxA ,O szMessageBox db
call@f
@@:
Popebx
:定义指向对话框函数的指针变量及常量的定义
etModuleHandle ApiGetModuleHandle 7
IobalAIIoc ApiGIobalAIIoc 7
MuItiByteToWideChar
ApiMultiByteToWideChar 7
subebx,offset@b
Iea Ieax,【ebx+PswdText】
invoke strlen,eax
一DialogBoxlndirectParam piDialogBoxlndirectParam 7
_j3IobalFree piGIobalFree?
_EndDialog ApiEndDialog 7
GetDIgItemText ApiGetDIgltemText?
SetWindowText ApiSetWindowText?
SendDIgltemMessage ApiSendDlgltemMessage 7
Imov【ebx-i-@strlen1 1】,eax
lea eax,【ebx-i-OldPswdText】
invoke strl。en,eax
mov【ebx-i-@strlen22】,eax
Imovecx,febx-i-@strlen1 1】
moveax,febx+@strlen22 J
.
szGetModuleHandle db GetModuleHandleA .O
szGIobalAIloc db GlobalAIloc .O
szMull[iByteToWideChardb MultiByteToWideChar .O
szDialogBoxIndirectParamdb DialogBox!ndirectParamA
0
szGIobatFree db GIobalFree .O
,
Ifecx<eax
xchg eax,ecx
.
endif :
1eaesi.【ebx--iOIdPswdText:1
szEndDialog db EndDialog 10
leaed 【ebx-i-PswdText】
cld
repe cmpsb
.
szGetDIgItemText db GetDIgltemTextA ,0
szSetWindowText db SetWindowTextA ,0
szSendDIgltemMessage db SendDigItemMessageA O
APPEND
PASSWD_!=ODE equ this byte
_
ifZERO7
popad
OIdPswdText db30dup《O) 加密后留存的口令
PswdText db30dup《0) :对话框输入的验证口令
TitleName db Enter PassWord .O
moveax,TRUE
ret
.
etse
ButtonName db 确定 ,O
FontName db Times NewRoman .0
lD.PSWDequ 1O1
lD
EXITequ 202
_
popad
moveax.FALSE
ret:
.
endif
ID CAPTIONequ 1 1O1 1
ChkEnterpswd endP
szCaIption db 问题提示: ,0
TitleTextdb 请输入口令: ,0
ErrPasswddb 口令错误{ ,0
hlnstance1 dd 7
@strlen11 dd 7
@strlen22dd 7 ’
.
:对话框过程
DIgProc Proc hWnd:dword,uMsg:dword
wParam:dword
IParam:dvvrord
,
call@f
@@:
pOPebx
:取字符串长度过程
strlen proc-dwarg
subebx..offset@b
.
if uMsg==WM OMMAND
电蘑鳙程技巧与维护 -与 辫赫
维普资讯
……
CO啊PUTE矗PROG肌啊啊IHG眦INTEH^一CE… …………… …………………………………………………
invoke【ebx+_GetProcAddress】.【ebx+hD Kerne132],eax
m 、ebx 4-_MuItiByteToWideChar、I eax-一、
mov eax.wParam
.
If ax= lD pswD
Iea edx,【ebx 4-PswdText】
invoke【ebx 4- etDIgltemText】,hWnd,lD_PSWD,edx,30
elseifax::lD_EXIT
.
lea eax,【ebx+szGIobalFreel :获取GlobalFree入日地址
invoke【ebx -4 etP『_0cAddress】J【ebx -4hDIIKernel32】 eax
mov、ebx_、_ IobaIFree、I eax
invoke【ebx 4-_EndDialog】,hWnd,NULL
.
endif
_
:获取D_alogBoxlndirectParam入口地址 .
lea eax,【ebx -4szDialogBoxln rectParam l
“
。 。
.
elseif uMsg:=WM
INITDIALOG
invoke【ebx+ etProcAddress] 【ebx+h DllUser32 eaX
Jea ecx,f ebx 4-TitleText】
invoke【ebx 4-_setWindowText】,hWnd,ecx
mov f ebx+_Dia,log BoxlndirectPaFam】 eax
e8 eax,【ebx -4szEndD_al0g】 :获取EndDialog入口地址
invoke I ebx -_4GetProcAddress】,febx -4hDIIUser32】J eax
mov、ebx+王ndDl\a\o eax
lea eax,【ebx 4-szGetDigltemText】 ‘
}nvoke【ebx -4_sendDIgItemMessage】.hWnd 1D_PSWD,
EM_LlMlTTEXT,1 8,NULL
invoke【ebx -4_sendDlgltemMessage】,hWnd,ID_PSWD,
EM_sETPASSWORDCHAR,42,NULL
eIse
:获取GetDigltemText入IZ!地址
;nvoke【ebx 4- etProcAddress 【ebx 4-hDIlUser32】.eax.
moveax,FALSE
ret
.
m刚、ebx+ etDigItemText、l eax
lea e8x,【ebx 4-szSetWindowText】
’
I
- -
endif
●
获取SetWindowText入 地
invoke【ebx+_』3etProcAddress】J【ebx+hDlIUser32],eax
mov、ebx -4 etWindowText、1 eax
lea—eax,【ebx+szSenaDIgltemMessage】
mov eax TRUE
ret
DlgProc endp
:口令加密代码的入口
_NewEntry:
1获取SendDIgltemMessage入I:q地址
invoke【ebx+_GetProcAddress】,[ebx 4-lhDIIUser3 2】 ̄eax
:重定位
call@F
。
mov、ebx -4_SendDIg\temMessage、I eax
@@:
pop ebx
sub ebx.offset@B
lea eax, ebx -SZMessageBox、 4
I获取MessageBox入I:q地垃
eax
一 。。。
invoke 【ebx+_GetProcAddress] 【ebx+hDIIUser32],
mov【ebx+—MessageBox】,eax
invoke GetKernelBase,I esp】
pushad
:获取Kernel32.dll基地址
rnov【ebx 4-hDIIKerne132 eax
invoke ebx 4- etModuleHandIe、.NULL
I获 模块 甸柄
|
lea eax.【ebx 4-szGetProcAddress】
mov[ebx -hi4nstanoel、I eax
:获取GetProcAddress入口地址
invoke
_
GetApi,【ebx+hDllKernel32】I eax
对话框模板申请长度为4K,用O初始化,地址固定的内存
块 甩千建立对话框模摄。
invoke、ebx 4- IobaIAIloc] GMEM_FIXED or
GMEM ZEROlNIT,1024 4 -
mov【ebx 4-.j3etProcAddress】,eax
lea eax,【ebx 4-szLoadLibrary】
。。。
:获取LoadLibrary入IZ!地址
invoke
ne132】,ea×
【ebx+ etProcAddress】.【ebx+hDllKer-
。 mov【ebx+_LoadLlbrary eax
lea eax,、ebx 4-szUser32、 一
movwordptr、e 4-8 2 控悻数目
,
一 ||
:获取User32.d¨基地址
invoke【ebx 4-_LoadLibrary】,eax
mov【ebx -hDI4IUser32lI eax
lea eax;【ebx+szGIobalAIIoc]
I 话框 屏幕坚标 200,180)
movword edi 4、. 10
| ll?
j||
:获取GIobal Al10c入口地址
invoke【lebx 4-GetProcAddress 【ebX+hDI1Keme132】,eax
d邸\ed、+、
菜单2字 、
、ea
|
! 话 大j\\、、Qx ≯|l
l I |||
j薯 : …0
mov【ebx+ IobalAIloc】,eax
lea eaX。I ebx十szeetModuleHand Je】
2字 ,共221}
me、 宅 +弋
:获取GetModuleHand!e入口地址
}nvoke【lebx -4J3etProcAddress I ebx+hDIIKerne132】.ea×
moV【ebX+ etModuleHandle】.eax
rn ecx
eax
No e +
蝇 0
| l |l|i | |t | |
、l cPAcP蕾i|| I i薯誊。
C |邑心f |l j |薯
获取 UltiByteToWideChar入 地
1ea eax;【ebx -szMul4tiByteToWideCha rl
1
e弋 l、de
J f\D
维普资讯
…一… ~……一… …… … … …… ……… 一…
实用第一 智慧密集
popecx
moveax.ecx
序数值0081 h代表Edit类
addedi.22
shleax,1
lea edx.【ebx+PswdText】
invoke strlen,edX
addedi,eax
movwordptr【edi】.9
added .2
;字体点阵大小
movecx,eax
DuSh‘ecx
.
lea edx,【ebx+FontName】
invoke strlen.edx
movecx,eax
invoke【ebx+ ultiByteToWideChar】,CP_ACP.
MB_PRECOMPOSED,edx,一1,edi,eax
DODecx
..
pushecx
moveax,ecx
invoke【ebx+ u t ByteToWideChar】I CP_ACP,
shleax,1
addedi,eax
MB PREC0MPOSED.edx.一1,edi.eax
popecx
moveax,ecx
add edi,3
shredi,2
shl edi,2
shleax,1
addedi.eax
addedi.3
shredi,2
lea ecx,【ebx+DIgProc】
创建模态对话框
invoke 【ebx十一pialogBoxlndirectParam】, 【ebx+hln—
stance1 1,esi,NULL.ecx,NULL
.
shl edi,2 :起始地址双字对齐
:按钮控件
movdword ptr【edi】,ws_vISIBLEorWS_CHILD:按钮样式
movwordptr【edi+81,3O
movWOrdptr【edi+10】.27
:对话框关闭后释放申请的内存块
invoke【ebx十一j3IobalFFee】J esi
oo
oad
..
invokeChkEnter
oswd
.
.
按钮在对话框中的坐标(30,27)
movwordptr【edi+12】,40
:校对用户输入的口令的正确性
If】eax:口令错误,则退出。
lea ecx,【ebx+ErrPasswd】
lea eax,【ebx+SZCaotion】
’invo。Ke【ebx+ essageBox】,NULL,ecx,eax.MB K
ret
,
movword ptr【edi+14】,1 2 按钮的大小4O×1 2
movword ptr【edi+16】,lD_EXIT:按钮标识
movword ptr【edi+18】,Offffh
movwordptr【edi+20】,O080h
endif
序数值O080h代表Button类
addedi,22
口令正确,执行原来的目标尸E文件
dbOe9h :Oe9h是jmpXXXXXXXX的机器码
RetOldEntw:
lea edx,【ebx+ButtonName】
invoke strlen,edx
movecx.eax 。
dd 7:用来填写返回到目标PE文件的入口地址
APPEND
CODE
END equ this byte
pushecx
invoke【ebx+ ultiByteToWideChar】,CP_ACP,
MB_PRECOMPOSED,edx,一1,edi,eax
popecx
moveax,ecx
三、结语
本文在WindowsXP中文版下对多个PE文件进行测试,效
果良好。还有可以改进的地方,如埘输入的}]令进 加密,增
加防静态分析和反动态跟踪的功能,使加密软件更加安全可
靠。另外,有兴趣的读者可以在此加密原 的基础上,开发出
・
shleax.1
addedi,eax
addedi,3
对应的解密程序(或防病毒免疫程序),以更加方便实用。
shredi,2
shl edi,2 :起始地址双字对齐
编辑控件
mov dword ptr【edi】,WS ISIBLE or ws cHILD or
WS
TABSTOP orws 8ORDER:编辑框样式
_
参考文献
l罗云彬编著.Windows环境下32化 :编 言程序设计(第2
版).北京:电子工业出版社,2006.
movword ptr【edi+8】.13
movwordptr【e +10】,10
(1 3 X 10)
编辑框在对话框中的坐标
.
2吴中平编著.Windows汇编语言程序设计.北京:清华大学
出版社,2004.
movword ptr【edi+1 2】,8O
3严义,包健等编著.Win32汇编语占’程序设计教程.北京:
机械工业出版社,2004.
(收稿日期:2008年1月17日)
movword ptr【edi+14】,1 2 编辑框的大小80 X 1 2
movwordptr【edi+16】,ID_PSWD 编辑框标识
movword ptr【edi+18】,0ffffh
movword ptr【edi+2O】,0081h
‘
, ‘
柏
版权声明:本文标题:用Win32汇编语言对PE格式的EXE文件进行口令加密 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1720916333a850043.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论