janeyjhon 发表于 2017-7-13 15:22:05

fs:[0]表示什么

.386
.model flat,stdcall
option casemap:none

include    windows.inc
include    user32.inc
includelib user32.lib
include    kernel32.inc
includelib kernel32.lib
include    comdlg32.inc
includelib comdlg32.lib


ICO_MAIN equ 1000
DLG_MAIN equ 1000
IDC_INFO equ 1001
IDM_MAIN equ 2000
IDM_OPEN equ 2001
IDM_EXIT equ 2002
IDM_1    equ 4000
IDM_2    equ 4001
IDM_3    equ 4002

.data
hInstance   dd ?   ; 进程句柄
hRichEdit   dd ?
hWinMain    dd ?   ; 弹出窗口句柄
hWinEdit    dd ?   ; 富文本框句柄
totalSize   dd ?   ; 文件大小
lpMemory    dd ?   ; 内存映像文件在内存的起始位置
szFileNamedb MAX_PATH dup(?)               ;要打开的文件路径及名称名

lpServicesBuffer         db 100 dup(0)   ;所有内容
bufDisplay               db 50 dup(0)      ;第三列ASCII码字符显示
szBuffer               db 200 dup(0)       ;临时缓冲区
lpszFilterFmt4         db'%08x',0
lpszManyBlanks         db'',0
lpszBlank                db' ',0
lpszSplit                db'-',0
lpszScanFmt            db'%02x',0
lpszHexArr               db'0123456789ABCDEF',0
lpszReturn               db0dh,0ah,0
lpszDoubleReturn         db0dh,0ah,0dh,0ah,0
lpszOut1               db'文件大小:%d',0
dwStop                   dd0
.const
szDllEdit   db 'RichEd20.dll',0
szClassEdit db 'RichEdit20A',0
szFont      db '宋体',0
szExtPe   db 'PE File',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
            db 'All Files(*.*)',0,'*.*',0,0
szErr       db '文件格式错误!',0
szErrFormat db '操作文件时出现错误!',0


.code

;----------------
;初始化窗口程序
;----------------
_init proc
local @stCf:CHARFORMAT

invoke GetDlgItem,hWinMain,IDC_INFO
mov hWinEdit,eax
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWinMain,WM_SETICON,ICON_BIG,eax       ;为窗口设置图标
invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0 ;设置编辑控件
invoke RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.yHeight,14*1440/96
mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
invoke lstrcpy,addr @stCf.szFaceName,addr szFont
invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret
_init endp

;------------------
; 错误Handler
;------------------
_Handler proc _lpExceptionRecord,_lpSEH,\
            _lpContext,_lpDispathcerContext

pushad
mov esi,_lpExceptionRecord
mov edi,_lpContext
assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
mov eax,_lpSEH
push
pop .regEbp
push
pop .regEip
push eax
pop .regEsp
assume esi:nothing,edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_Handler endp

;---------------------
; 往文本框中追加文本
;---------------------
_appendInfo proc _lpsz
local @stCR:CHARRANGE

pushad
invoke GetWindowTextLength,hWinEdit
mov @stCR.cpMin,eax;将插入点移动到最后
mov @stCR.cpMax,eax
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stCR
invoke SendMessage,hWinEdit,EM_REPLACESEL,FALSE,_lpsz
popad
ret
_appendInfo endp


;--------------------
; 打开PE文件并处理
;--------------------
_openFile proc
local @stOF:OPENFILENAME
local @hFile,@hMapFile
local @bufTemp1   ; 十六进制字节码
local @bufTemp2   ; 第一列
local @dwCount    ; 计数,逢16则重新计
local @dwCount1   ; 地址顺号
local @dwBlanks   ; 最后一行空格数

invoke RtlZeroMemory,addr @stOF,sizeof @stOF ;addr @stOF表示指向这个结构体的地址,sizeof @stOF结构体的长度,用零填充
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szExtPe
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
invoke GetOpenFileName,addr @stOF;让用户选择打开的文件
.if !eax
    jmp @F
.endif
invoke CreateFile,addr szFileName,GENERIC_READ,\
         FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,\
         OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax!=INVALID_HANDLE_VALUE
    mov @hFile,eax
    invoke GetFileSize,eax,NULL   ;获取文件大小
    mov totalSize,eax

    .if eax
      invoke CreateFileMapping,@hFile,\;内存映射文件
             NULL,PAGE_READONLY,0,0,NULL
      .if eax
      mov @hMapFile,eax
      invoke MapViewOfFile,eax,\
               FILE_MAP_READ,0,0,0
      .if eax
          mov lpMemory,eax            ;获得文件在内存的映象起始位置
          assume fs:nothing
          push ebp
          push offset _ErrFormat
          push offset _Handler
          push fs:
          mov fs:,esp

          ;开始处理文件

          ;缓冲区初始化
          invoke RtlZeroMemory,addr @bufTemp1,10
          invoke RtlZeroMemory,addr @bufTemp2,20
          invoke RtlZeroMemory,addr lpServicesBuffer,100
          invoke RtlZeroMemory,addr bufDisplay,50

          mov @dwCount,1
          mov esi,lpMemory
          mov edi,offset bufDisplay

          ; 将第一列写入lpServicesBuffer
          mov @dwCount1,0
          invoke wsprintf,addr @bufTemp2,addr lpszFilterFmt4,@dwCount1
          invoke lstrcat,addr lpServicesBuffer,addr @bufTemp2

          ;求最后一行的空格数(16-长度%16)*3
          xor edx,edx
          mov eax,totalSize
          mov ecx,16
          div ecx
          mov eax,16
          sub eax,edx
          xor edx,edx
          mov ecx,3
          mul ecx
          mov @dwBlanks,eax

          ;invoke wsprintf,addr szBuffer,addr lpszOut1,totalSize
          ;invoke MessageBox,NULL,addr szBuffer,NULL,MB_OK

          .while TRUE
             .if totalSize==0;最后一行
                ;填充空格
               .while TRUE
                     .break .if @dwBlanks==0
                     invoke lstrcat,addr lpServicesBuffer,addr lpszBlank
                     dec @dwBlanks
               .endw
               ;第二列与第三列中间的空格
               invoke lstrcat,addr lpServicesBuffer,addr lpszManyBlanks
               ;第三列内容
               invoke lstrcat,addr lpServicesBuffer,addr bufDisplay
               ;回车换行符号
               invoke lstrcat,addr lpServicesBuffer,addr lpszReturn
               .break
             .endif
             ;将al翻译成可以显示的ascii码字符,注意不能破坏al的值
             mov al,byte ptr
             .if al>20h && al<7eh
                mov ah,al
             .else      ;如果不是ASCII码值,则显示“.”
                mov ah,2Eh
             .endif
             ;写入第三列的值
             mov byte ptr ,ah

            ;win2k不支持al字节级别,经常导致程序无故结束,
            ;因此用以下方法替代
            ;invoke wsprintf,addr @bufTemp1,addr lpszFilterFmt3,al
                        
             mov bl,al
             xor edx,edx
             xor eax,eax
             mov al,bl
             mov cx,16
             div cx   ;结果高位在al中,余数在dl中

             ;组合字节的十六进制字符串到@bufTemp1中,类似于:“7F \0”
             push edi
             xor bx,bx
             mov bl,al
             movzx edi,bx
             mov bl,byte ptr lpszHexArr
             mov byte ptr @bufTemp1,bl

             xor bx,bx
             mov bl,dl
             movzx edi,bx
             mov bl,byte ptr lpszHexArr
             mov byte ptr @bufTemp1,bl
             mov bl,20h
             mov byte ptr @bufTemp1,bl
             mov bl,0
             mov byte ptr @bufTemp1,bl
             pop edi

             ; 将第二列写入lpServicesBuffer
             invoke lstrcat,addr lpServicesBuffer,addr @bufTemp1

             .if @dwCount==16   ;已到16个字节,
                ;第二列与第三列中间的空格
                invoke lstrcat,addr lpServicesBuffer,addr lpszManyBlanks
                ;显示第三列字符
                invoke lstrcat,addr lpServicesBuffer,addr bufDisplay      
                ;回车换行
                invoke lstrcat,addr lpServicesBuffer,addr lpszReturn

                ;写入内容
                invoke _appendInfo,addr lpServicesBuffer
                invoke RtlZeroMemory,addr lpServicesBuffer,100         

                .break .if dwStop==1

                ;显示下一行的地址
                inc @dwCount1
                invoke wsprintf,addr @bufTemp2,addr lpszFilterFmt4,\
                                                            @dwCount1
                invoke lstrcat,addr lpServicesBuffer,addr @bufTemp2
                dec @dwCount1

                mov @dwCount,0
                invoke RtlZeroMemory,addr bufDisplay,50
                mov edi,offset bufDisplay
                ;为了能和后面的inc edi配合使edi正确定位到bufDisplay处
                dec edi
             .endif

             dec totalSize
             inc @dwCount
             inc esi
             inc edi
             inc @dwCount1
          .endw

          ;添加最后一行
          invoke _appendInfo,addr lpServicesBuffer

         
          ;处理文件结束

          jmp _ErrorExit

_ErrFormat:
          invoke MessageBox,hWinMain,offset szErrFormat,NULL,MB_OK
_ErrorExit:
          pop fs:
          add esp,0ch
          invoke UnmapViewOfFile,lpMemory
      .endif
      invoke CloseHandle,@hMapFile
      .endif
      invoke CloseHandle,@hFile
    .endif
.endif
@@:      
ret
_openFile endp
;-------------------
; 窗口程序
;-------------------
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @sClient

mov eax,wMsg
.if eax==WM_CLOSE
    invoke EndDialog,hWnd,NULL
.elseif eax==WM_INITDIALOG;初始化
    push hWnd
    pop hWinMain
    call _init
.elseif eax==WM_COMMAND;菜单
    mov eax,wParam
    .if eax==IDM_EXIT       ;退出
      invoke EndDialog,hWnd,NULL
    .elseif eax==IDM_OPEN   ;打开文件
      mov dwStop,0
      invoke CreateThread,NULL,0,addr _openFile,addr @sClient,0,NULL
      ;invoke _openFile
    .elseif eax==IDM_1
      mov dwStop,1
    .elseif eax==IDM_2
    .elseif eax==IDM_3
    .endif
.else
    mov eax,FALSE
    ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp

start:
invoke LoadLibrary,offset szDllEdit
mov hRichEdit,eax
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,\
         DLG_MAIN,NULL,offset _ProcDlgMain,NULL;offset是编译器通过,addr则要通过内存
invoke FreeLibrary,hRichEdit
invoke ExitProcess,NULL
end start


这段代码中
push fs:
mov fs:,esp
为什么要push fs:,fs:又表示什么

云野 发表于 2017-7-13 17:43:07

FS是附加数据段寄存器、从386开始才有的

janeyjhon 发表于 2017-7-13 17:48:02

为什么要push fs:里,而不压在别的寄存器里

erh 发表于 2017-7-13 22:19:42

push fs:
是将fs:的内容压入栈保存,跟后面pop fs:恢复是对应的
页: [1]
查看完整版本: fs:[0]表示什么