想一想,如果你要寫一個加密程序,或者病毒程序,都需要對文件進行修改(寫操作)。在dos下,系統提供有相應的功能調用來完成這樣的操作,如:“打開文件\移動指針\讀文件\寫文件\關閉文件”,在windows下,系統也提供有相應的Api函數。如“CreateFile\SetFilePointer\ReadFile\WriteFile\SetEndOfFile\CloseHandle”等,利用這些編程和dos下沒什麼兩樣,這裡就不再多說啦!咱們今天要用的是利用“內存映射文件”來操作。簡單的說就是把文件內容映射到一個內存塊,改變這塊內存的內容就是改變文件的內容,系統可提供的這塊內存巨大、平坦,操作起來真是方便!
這種方法要用到“CreateFile/CreatFileMapping/MapViewOfFile/UnmapViewOfFile/CloseHandle”,具體使用參考“Win32 Developer's References”。俺也是剛看,不敢亂說,嘿嘿嘿。
--------------------------------------------------------------
;例:打開一個已存在的文件並修改,建議文件具有一定的大小,比如80H字節。
;文件名:12.asm
.386
.Model Flat, StdCall
Option Casemap :None
;---------------------------------------------------------
Include windows.inc
Include kernel32.inc
IncludeLib kernel32.lib
ModifyFile PROTO :LPSTR
.data
MyFile db 'd:\masm7\MyTest',0 ;文件MyTest必須存在,若不存在,程序將什麼也不做
M1 db 'Good morning',0 ;將寫到文件中的字符串
M2 db 'Good afternoon',0
M3 db 'Good evening',0
;---------------------------------------------------------
.data?
hFile dd ?
hMap dd ?
pMapAddr dd ?
;---------------------------------------------------------
.code
START:
invoke CreateFile, \ ;打開文件,該函數具有多種功能
ADDR MyFile,\ ;指向要打開的文件名字符串
GENERIC_READ or GENERIC_WRITE ,\ ;打開的文件具有讀寫的權限
FILE_SHARE_READ or FILE_SHARE_WRITE,\ ;別人也可讀寫此文件
NULL, \ ;95下不用
OPEN_EXISTING, \ ;要打開的文件必須存在
FILE_ATTRIBUTE_NORMAL,\ ;文件的屬性
NULL ;95下必須是NULL
.if eax!=INVALID_HANDLE_VALUE ;判斷文件是否已正常打開
mov hFile, eax ;保存文件句柄
invoke CreateFileMapping, \ ;creates file-mapping object for the specified file.
hFile, \ ;Identifies the file from which to create a mapping object
NULL, \ ;ignored
PAGE_READWRITE, \ ;access
0, \ ;high-order 32 bits of the maximum size
0, \ ;low-order 32 bits of the maximum size
NULL ;the mapping object is created without a name
.if eax!=NULL ;
mov hMap,eax ;the return value is a handle to the file-mapping object
invoke MapViewOfFile,hMap,FILE_MAP_WRITE,0,0,NULL ;映射文件到內存
.if eax!=NULL
mov pMapAddr,eax ;保存返回的內存塊首地址
invoke ModifyFile,pMapAddr ;修改內存塊內容
invoke UnmapViewOfFile,pMapAddr ;解除文件映射
.endif
invoke CloseHandle,hMap ;關閉內存映射文件
.endif
invoke CloseHandle, hFile ;關閉文件
.endif
invoke ExitProcess,0 ;結束程序
;修改內存塊的內容,就相當於修改文件的內容
ModifyFileproc uses ebx esi edi,lpBufferAddress:LPSTR
mov edi,lpBufferAddress ;取內存塊地址
invoke lstrcpy,edi,addr M1 ;修改內存塊內容
add edi,40h ;調整地址(隨意)
invoke lstrcpy,edi,addr M2 ;修改
add edi,240h
invoke lstrcpy,edi,addr M3
ret
ModifyFileendp
END START
----------------------------------------------------------------------
注意:
0、程序運行後無任何提示,只可從被修改的文件上看變化
1、第39、40行的值都是0,這樣,內存映射文件的大小就正好取文件的實際大小
2、可以看到,第62、63行的修改並沒起作用,因為文件沒有這樣大。
3、將40行的數據改為100H,可看到運行後原文件的大小將變為100H
4、將40行的數據改為200H,47行的指令屏蔽掉不執行,程序運行後可看到文件的大小將成200H
5、此時將40行的數據改為80H,運行程序,文件不會變小
6、恢復47行指令,運行後文件亦不能減小
7、真想減少文件尺寸,可在52行前多執行兩條指令:①SetFilePointer②SetEndOfFile
8、其他的沒測試,自己琢磨吧!