标题:关于寄存器的运用问题。
只看楼主
tigerdown
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2017-8-21
结帖率:69.23%
已结贴  问题点数:20 回复次数:3 
关于寄存器的运用问题。
什么地方,什么时候用什么寄存器是一个令人头疼的问题。通过对书上一个程序研究和分析,来提出一些疑问。
这是一个展示PE文件信息的程序,主要部分在子程序_ProcesPeFile, 所以分析和研究主要在这方面展开的。由于篇幅较长,我把它放在两个帖子里。
先看一下程序:
<<_ProcesPeFile>>
1. ; Peinfo 例子的 PE文件处理模块
2. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
3. .const
4. szMsg        db    '文件名:%s',0dh,0ah
5. db    '----------------------------------------------------------',0dh,0ah
6. db    '运行平台:          0x%04X',0dh,0ah
7. db    '节区数量:          %d',0dh,0ah
8. db    '文件标记:          0x%04X',0dh,0ah
9. db    '建议装入地址:      0x%08X',0dh,0ah,0ah,0
10. szMsgSection    db    '----------------------------------------------------------',0dh,0ah
11. db    '节区名称  节区大小  虚拟地址  Raw_尺寸  Raw_偏移  节区属性',0dh,0ah
12. db    '----------------------------------------------------------',0dh,0ah,0
13. szFmtSection    db    '%s  %08X  %08X  %08X  %08X  %08X',0dh,0ah,0

14. .code
15. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
16. _ProcessPeFile    proc    _lpFile,_lpPeHead,_dwSize
17. local    @szBuffer[1024]:byte,@szSectionName[16]:byte

18. pushad
19. mov    edi,_lpPeHead
20. assume    edi:ptr IMAGE_NT_HEADERS
21. ;********************************************************************
22. ; 显示 PE 文件头中的一些信息
23. ;********************************************************************
24. movzx    ecx,[edi].FileHeader.Machine
25. movzx    edx,[edi].FileHeader.NumberOfSections
26. movzx    ebx,[edi].FileHeader.Characteristics
27. invoke    wsprintf,addr @szBuffer,addr szMsg,\
28. addr szFileName,ecx,edx,ebx,\
29. [edi].OptionalHeader.ImageBase
30. invoke    SetWindowText,hWinEdit,addr @szBuffer
31. ;********************************************************************
32. ; 循环显示每个节区的信息
33. ;********************************************************************
34. invoke    _AppendInfo,addr szMsgSection
35. movzx    ecx,[edi].FileHeader.NumberOfSections
36. add    edi,sizeof IMAGE_NT_HEADERS
37. assume    edi:ptr IMAGE_SECTION_HEADER
38. .repeat
39. push    ecx
40. ;********************************************************************
41. ; 节区名称
42. ;********************************************************************
43. invoke    RtlZeroMemory,addr @szSectionName,sizeof @szSectionName
44. push    esi
45. push    edi
46. mov    ecx,8
47. mov    esi,edi
48. lea    edi,@szSectionName
49. cld
50. @@:
51. lodsb
52. .if    ! al
53. mov    al,' '
54. .endif
55. stosb
56. loop    @B
57. pop    edi
58. pop    esi
59. ;********************************************************************
60. invoke    wsprintf,addr @szBuffer,addr szFmtSection,\
61. addr @szSectionName,[edi].Misc.VirtualSize,\
62. [edi].VirtualAddress,[edi].SizeOfRawData,\
63. [edi].PointerToRawData,[edi].Characteristics
64. invoke    _AppendInfo,addr @szBuffer
65. add    edi,sizeof IMAGE_SECTION_HEADER
66. ;********************************************************************
67. pop    ecx
68. .untilcxz
69. assume    edi:nothing
70. popad
71. ret

72. _ProcessPeFile    endp
73. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

<<Main File>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Main.asm
;     PE 文件操作演示的主程序,提供对话框界面和文件打开功能
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Main.asm
; rc Main.rc
; Link /subsystem:windows Main.obj Main.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .386
        .model flat, stdcall
        option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        windows.inc
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib
include        comdlg32.inc
includelib    comdlg32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN    equ    1000
DLG_MAIN    equ    1000
IDC_INFO    equ    1001
IDM_MAIN    equ    2000
IDM_OPEN    equ    2001
IDM_EXIT    equ    2002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data?
hInstance    dd    ?
hRichEdit    dd    ?
hWinMain    dd    ?
hWinEdit    dd    ?
szFileName    db    MAX_PATH dup (?)

        .const
szDllEdit    db    'RichEd20.dll',0
szClassEdit    db    'RichEdit20A',0
szFont        db    '宋体',0
szExtPe        db    'PE Files',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
        db    'All Files(*.*)',0,'*.*',0,0
szErr        db    '文件格式错误!',0
szErrFormat    db    '这个文件不是PE格式的文件!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

        .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        _ProcessPeFile.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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,9 * 20
        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,_lpDispatcherContext

        pushad
        mov    esi,_lpExceptionRecord
        mov    edi,_lpContext
        assume    esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
        mov    eax,_lpSEH
        push    [eax + 0ch]
        pop    [edi].regEbp
        push    [eax + 8]
        pop    [edi].regEip
        push    eax
        pop    [edi].regEsp
        assume    esi:nothing,edi:nothing
        popad
        mov    eax,ExceptionContinueExecution
        ret

_Handler    endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_OpenFile    proc
        local    @stOF:OPENFILENAME
        local    @hFile,@dwFileSize,@hMapFile,@lpMemory

        invoke    RtlZeroMemory,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
;********************************************************************
; 打开文件并建立文件 Mapping
;********************************************************************
        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    @dwFileSize,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
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
                        assume    fs:nothing
                        push    ebp
                        push    offset _ErrFormat
                        push    offset _Handler
                        push    fs:[0]
                        mov    fs:[0],esp
;********************************************************************
; 检测 PE 文件是否有效
;********************************************************************
                        mov    esi,@lpMemory
                        assume    esi:ptr IMAGE_DOS_HEADER
                        .if    [esi].e_magic != IMAGE_DOS_SIGNATURE
                            jmp    _ErrFormat
                        .endif
                        add    esi,[esi].e_lfanew
                        assume    esi:ptr IMAGE_NT_HEADERS
                        .if    [esi].Signature != IMAGE_NT_SIGNATURE
                            jmp    _ErrFormat
                        .endif
                        invoke    _ProcessPeFile,@lpMemory,esi,@dwFileSize
                        jmp    _ErrorExit
_ErrFormat:
                        invoke    MessageBox,hWinMain,addr szErrFormat,NULL,MB_OK
_ErrorExit:
                        pop    fs:[0]
                        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

        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    ax ==    IDM_OPEN
                call    _OpenFile
            .elseif    ax ==    IDM_EXIT
                invoke    EndDialog,hWnd,NULL
            .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
        invoke    FreeLibrary,hRichEdit
        invoke    ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        end    start




搜索更多相关主题的帖子: mov addr invoke db 文件 
2021-12-07 10:24
tigerdown
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2017-8-21
得分:0 
对某个PE文件运行的结果:


请注意这二个指令,第25行 - movzx    edx,[edi].FileHeader.NumberOfSections
                  第35行 - movzx    ecx,[edi].FileHeader.NumberOfSections
为什么第二次把它放在ecx,是因为要计数(.repeat, untilcxz), 但是,为什么不一开始就把它赋值给ecx?
我把第25行的寄存器改成ecx,运行结果只能得到第一行节的信息,为什么会这样?是因为一定要把它放在第30行(invoke    SetWindowText,hWinEdit,addr @szBuffer)指令后,这是什么情况?





另外,第16行 - _ProcessPeFile    proc    _lpFile,_lpPeHead,_dwSize
 _lpFile传递参数在程序中并没有用到(可能是笔误),这参数是一个PE文件在磁盘上起始的映像地址(0x01810000),请注意,这个地址是不同于第29行([edi].OptionalHeader.ImageBase)的地址,这是一个建议装入内存的映像基址(0x00400000).

这程序摘自<<Windows环境下32位汇编语言程序设计>>之书,这是一本经典之作,作者罗云彬曾获得国家科技进步二等奖,本人从这本书中学到许多知识,受益匪浅,对其作者也充满敬意,之所以对这段程序展开仔细研究和分析,是为下一步编程工作打好扎实基础,并不是有意对其吹毛求疵。当然喽,如果这本书再编得严谨些,对源码标注再详细具体些,那将是一部完美之作

[此贴子已经被作者于2021-12-7 10:38编辑过]

2021-12-07 10:34
Valenciax
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:11
帖 子:337
专家分:2462
注 册:2016-5-15
得分:20 
窗口函式的输入或输出对暂存器有哪些不同要求(或无指定),视具体情况使用。
再看楼主的问题,可以用追踪程序(如OllyDbg)运行一下,单步看看暂存器的进出,理解其逻辑。
2021-12-13 04:26
tigerdown
Rank: 1
等 级:新手上路
帖 子:63
专家分:3
注 册:2017-8-21
得分:0 
回复 3楼 Valenciax
SetWindowText是个问题,估计原作者已意识到了,所以前后二次赋值给不同的寄存器。
另外求助你帮我一下,我想下载点东西,但人在外面,百度盘上不去,我需要巜window PE权威指南》的附书源码,如果你能帮忙的话,我将不胜感激!!!
2021-12-13 13:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-507787-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015368 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved