首 页详细分类去玩游戏网络学院千一MTV软件下载音乐无极无极天下社区繁體中文
iczelionpetutcn5 设为首页
加入收藏
联系我们
学院: 站长学堂 | 网站开发 | 设计学院 | 软件教程 | 数据库类 | 编程经验 | 服务器类 | 网络技术 | 黑客破解 | 维修中心 | [更多]
源码: ASP 源码 | PHP 源码 | JSP 源码 | CGI 源码 | .NET源码 | FLA 源码 | JAVA源码 |Delphi源码| PB 源码 | VC/C++源码 | 其 它
软件: 系统工具 | 网络工具 | 多媒体类 | 图形图像 | 应用软件 | 行业软件 | 教育教学 | 安全相关 | 联络聊天 | 电子书籍 | [更多]
视频: 网络技术 | 图像动画 | 程序设计 | 机械电子 | 外语学习 | 手机: 手机软件 | 手机游戏手机电影手机维修手机铃声
电驴: 电驴电影 | 电驴游戏电驴音乐电驴软件电驴动漫 | 电驴剧集电驴资料电驴综艺电驴杂志 | [更多电驴共享]
您当前的位置:itlove -> 编程经验 -> 汇编语言 -> iczelionpetutcn5 退出登录 用户管理
推荐精品
热门下载
数据载入中...
热门技术文章
  • ·MDAC2.8下载!
  • ·Sun公司的操作系统:Solaris简介
  • ·RM转VCD/SVCD/DVD/WMV/AVI/MPEG4的终极高手--超级…...
  • ·笔记本电脑解密方法大全
  • ·C#介绍
  • ·win2k NTLDR丢失故障的解决
  • ·教你用PHOTOSHOP制作一寸照片
  • ·JBoss及Lomboz的下载与安装
  • ·PHP入门速成
  • ·入侵六合彩--- 1次入侵的扩散性思维的利用
  • ·SQL Server 服务器安装剖析
  • ·MySQL的JDBC驱动程序下载地址
  • 相关技术文章
  • ·iczelionpetutcn5
  • ·iczelionpetutcn6
  • ·iczelionpetutcn7
  • ·iczelionVxdtut1
  • ·iczelionVxdtut2
  • ·iczelionVxdtut3
  • ·iczelionVxdtut4
  • ·iczelionVxdtut5
  • ·iczelionVxdtut6
  • ·iczelionVxdtut7
  • ·iczelionVxdtut8
  • ·iczelionVxdtut9
  • iczelionpetutcn5
    作者:Ahaoz.CoM  来源:本站整理  发布时间:2005-11-21 0:40:59  发布人:admin


    PE教程5: Section Table(节表)

    理论:

    到本课为止,我们已经学了许多关于 DOS header PE header 的知识。接下来就该轮到 section table(节表)了。节表其实就是紧挨着 PE header 的一结构数组。该数组成员的数目由 file header (IMAGE_FILE_HEADER) 结构NumberOfSections 域的域值来决定。节表结构又命名为 IMAGE_SECTION_HEADER

    IMAGE_SIZEOF_SHORT_NAME equ 8

    IMAGE_SECTION_HEADER STRUCT
       Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?)
       union Misc
          PhysicalAddress dd ?
          VirtualSize dd ?
       ends
       VirtualAddress dd ?
       SizeOfRawData dd ?
       PointerToRawData dd ?
       PointerToRelocations dd ?
       PointerToLinenumbers dd ?

       NumberOfRelocations dw ?
       NumberOfLinenumbers dw ?
       Characteristics dd ?
    IMAGE_SECTION_HEADER ENDS

    同样,不是所有成员都是很有用的,我们只关心那些真正重要的。

    FieldMeanings
    Name1事实上本域的名称是"name",只是"name"已被MASM用作关键字,所以我们只能用"Name1"代替。这儿的节名长不超过8字节。记住节名仅仅是个标记而已,我们选择任何名字甚至空着也行,注意这里不用null结束。命名不是一个ASCIIZ字符串,所以不用null结尾。
    VirtualAddress本节的RVA(相对虚拟地址)。PE装载器将节映射至内存时会读取本值,因此如果域值是1000h,而PE文件装在地址400000h处,那么本节就被载到401000h
    SizeOfRawData经过文件对齐处理后节尺寸,PE装载器提取本域值了解需映射入内存的节字节数。(译者注: 假设一个文件的文件对齐尺寸是0x200,如果前面的 VirtualSize域指示本节长度是0x388字节,则本域值为0x400,表示本节是0x400字节长)。
    PointerToRawData这是节基于文件的偏移量,PE装载器通过本域值找到节数据在文件中的位置。
    Characteristics包含标记以指示节属性,比如节是否含有可执行代码、初始化数据、未初始数据,是否可写、可读等。

    现在我们已知晓 IMAGE_SECTION_HEADER 结构,再来模拟一下 PE装载器的工作吧:

    1. 读取 IMAGE_FILE_HEADER NumberOfSections域,知道文件的节数目。
    2. SizeOfHeaders 域值作为节表的文件偏移量,并以此定位节表。
    3. 遍历整个结构数组检查各成员值。
    4. 对于每个结构,我们读取PointerToRawData域值并定位到该文件偏移量。然后再读取SizeOfRawData域值来决定映射内存的字节数。将VirtualAddress域值加上ImageBase域值等于节起始的虚拟地址。然后就准备把节映射进内存,并根据Characteristics域值设置属性。
    5. 遍历整个数组,直至所有节都已处理完毕。

    注意我们并没有使用节名: 这其实并不重要。

    示例:

    本例程打开一PE文件遍历其节表,并在列表框控件显示各节的信息。

    .386
    .model flat,stdcall
    option casemap:none
    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\comdlg32.inc
    include \masm32\include\user32.inc
    include \masm32\include\comctl32.inc
    includelib \masm32\lib\comctl32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\comdlg32.lib

    IDD_SECTIONTABLE equ 104
    IDC_SECTIONLIST equ 1001

    SEH struct


    PrevLink dd ? ; the address of the previous seh structure
    CurrentHandler dd ? ; the address of the new exception handler
    SafeOffset dd ? ; The offset where it's safe to continue execution
    PrevEsp dd ? ; the old value in esp
    PrevEbp dd ? ; The old value in ebp
    SEH ends

    .data
    AppName db "PE tutorial no.5",0
    ofn OPENFILENAME <>
    FilterString db "Executable Files (*.exe, *.dll)",0,"*.exe;*.dll",0
                 db "All Files",0,"*.*",0,0
    FileOpenError db "Cannot open the file for reading",0
    FileOpenMappingError db "Cannot open the file for memory mapping",0
    FileMappingError db "Cannot map the file into memory",0
    FileInValidPE db "This file is not a valid PE",0
    template db "%08lx",0
    SectionName db "Section",0
    VirtualSize db "V.Size",0
    VirtualAddress db "V.Address",0
    SizeOfRawData db "Raw Size",0
    RawOffset db "Raw Offset",0
    Characteristics db "Characteristics",0

    .data?
    hInstance dd ?
    buffer db 512 dup(?)
    hFile dd ?
    hMapping dd ?
    pMapping dd ?
    ValidPE dd ?
    NumberOfSections dd ?

    .code
    start proc
    LOCAL seh:SEH
       invoke GetModuleHandle,NULL
       mov hInstance,eax
       mov ofn.lStructSize,SIZEOF ofn
       mov ofn.lpstrFilter, OFFSET FilterString
       mov ofn.lpstrFile, OFFSET buffer
       mov ofn.nMaxFile,512
       mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY
       invoke GetOpenFileName, ADDR ofn
       .if eax==TRUE
          invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
          .if eax!=INVALID_HANDLE_VALUE
             mov hFile, eax
             invoke CreateFileMapping, hFile, NULL, PAGE_READONLY,0,0,0
             .if eax!=NULL
                mov hMapping, eax
                invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0
                .if eax!=NULL
                   mov pMapping,eax
                   assume fs:nothing
                   push fs:[0]
                   pop seh.PrevLink
                   mov seh.CurrentHandler,offset SEHHandler
                   mov seh.SafeOffset,offset FinalExit
                   lea eax,seh
                   mov fs:[0], eax
                   mov seh.PrevEsp,esp
                   mov seh.PrevEbp,ebp
                   mov edi, pMapping
                   assume edi:ptr IMAGE_DOS_HEADER
                   .if [edi].e_magic==IMAGE_DOS_SIGNATURE
                      add edi, [edi].e_lfanew
                      assume edi:ptr IMAGE_NT_HEADERS
                      .if [edi].Signature==IMAGE_NT_SIGNATURE
                         mov ValidPE, TRUE
                      .else
                         mov ValidPE, FALSE
                      .endif
                   .else
                      mov ValidPE,FALSE
                   .endif
    FinalExit:
                   push seh.PrevLink
                   pop fs:[0]
                   .if ValidPE==TRUE
                      call ShowSectionInfo
                   .else
                      invoke MessageBox, 0, addr FileInValidPE, addr AppName, MB_OK+MB_ICONINFORMATION
                   .endif
                   invoke UnmapViewOfFile, pMapping
               .else
                   invoke MessageBox, 0, addr FileMappingError, addr AppName, MB_OK+MB_ICONERROR
              .endif
              invoke CloseHandle,hMapping
           .else
              invoke MessageBox, 0, addr FileOpenMappingError, addr AppName, MB_OK+MB_ICONERROR
           .endif
           invoke CloseHandle, hFile
        .else
           invoke MessageBox, 0, addr FileOpenError, addr AppName, MB_OK+MB_ICONERROR
        .endif
      .endif
      invoke ExitProcess, 0
      invoke InitCommonControls
    start endp

    SEHHandler proc uses edx pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
       mov edx,pFrame
       assume edx:ptr SEH
       mov eax,pContext
       assume eax:ptr CONTEXT
       push [edx].SafeOffset
       pop [eax].regEip
       push [edx].PrevEsp
       pop [eax].regEsp
       push [edx].PrevEbp
       pop [eax].regEbp
       mov ValidPE, FALSE
       mov eax,ExceptionContinueExecution
       ret
    SEHHandler endp

    DlgProc proc uses edi esi hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
       LOCAL lvc:LV_COLUMN
       LOCAL lvi:LV_ITEM
       .if uMsg==WM_INITDIALOG
          mov esi, lParam
          mov lvc.imask,LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
          mov lvc.fmt,LVCFMT_LEFT
          mov lvc.lx,80
          mov lvc.iSubItem,0
          mov lvc.pszText,offset SectionName
          invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTCOLUMN,0,addr lvc inc lvc.iSubItem
          mov lvc.fmt,LVCFMT_RIGHT
          mov lvc.pszText,offset VirtualSize
          invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTCOLUMN,1,addr lvc
          inc lvc.iSubItem
          mov lvc.pszText,offset VirtualAddress
          invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTCOLUMN,2,addr lvc
          inc lvc.iSubItem
          mov lvc.pszText,offset SizeOfRawData
          invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTCOLUMN,3,addr lvc
          inc lvc.iSubItem
          mov lvc.pszText,offset RawOffset
          invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTCOLUMN,4,addr lvc
          inc lvc.iSubItem
          mov lvc.pszText,offset Characteristics
          invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTCOLUMN,5,addr lvc
          mov ax, NumberOfSections
          movzx eax,ax
          mov edi,eax      
          mov lvi.imask,LVIF_TEXT
          mov lvi.iItem,0
          assume esi:ptr IMAGE_SECTION_HEADER
          .while edi>0
             mov lvi.iSubItem,0
             invoke RtlZeroMemory,addr buffer,9
             invoke lstrcpyn,addr buffer,addr [esi].Name1,8
             lea eax,buffer
             mov lvi.pszText,eax
             invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTITEM,0,addr lvi
             invoke wsprintf,addr buffer,addr template,[esi].Misc.VirtualSize
             lea eax,buffer
             mov lvi.pszText,eax
             inc lvi.iSubItem
             invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi
             invoke wsprintf,addr buffer,addr template,[esi].VirtualAddress
             lea eax,buffer
             mov lvi.pszText,eax
             inc lvi.iSubItem
             invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi
             invoke wsprintf,addr buffer,addr template,[esi].SizeOfRawData
             lea eax,buffer
             mov lvi.pszText,eax
             inc lvi.iSubItem
             invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi
             invoke wsprintf,addr buffer,addr template,[esi].PointerToRawData
             lea eax,buffer
             mov lvi.pszText,eax
             inc lvi.iSubItem
             invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi
             invoke wsprintf,addr buffer,addr template,[esi].Characteristics
             lea eax,buffer
             mov lvi.pszText,eax
             inc lvi.iSubItem
             invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_SETITEM,0,addr lvi
             inc lvi.iItem
             dec edi
             add esi, sizeof IMAGE_SECTION_HEADER
          .endw
       .elseif
          uMsg==WM_CLOSE
             invoke EndDialog,hDlg,NULL
       .else
          mov eax,FALSE
          ret
       .endif
       mov eax,TRUE
       ret
    DlgProc endp

    ShowSectionInfo proc uses edi
       mov edi, pMapping
       assume edi:ptr IMAGE_DOS_HEADER
       add edi, [edi].e_lfanew
       assume edi:ptr IMAGE_NT_HEADERS
       mov ax,[edi].FileHeader.NumberOfSections
       movzx eax,ax
       mov NumberOfSections,eax
       add edi,sizeof IMAGE_NT_HEADERS
       invoke DialogBoxParam, hInstance, IDD_SECTIONTABLE,NULL, addr DlgProc, edi
       ret
    ShowSectionInfo endp
    end start

    分析:

    本例重用了PE教程2代码,校验PE文件的有效性后,继续调用函数ShowSectionInfo显示各节信息。

    ShowSectionInfo proc uses edi
       mov edi, pMapping
       assume edi:ptr IMAGE_DOS_HEADER
       add edi, [edi].e_lfanew
       assume edi:ptr IMAGE_NT_HEADERS

    我们将edi用作指向PE文件数据的指针。首先,将指向DOS header地址的pMapping赋给edi,再加上e_lfanew域值等于PE header的地址。

       mov ax,[edi].FileHeader.NumberOfSections
       mov NumberOfSections,ax

    因为我们要遍历节表,所以必须先获取文件的节数目。这就得靠file header里的NumberOfSections域了,切记这是个word域。

       add edi,sizeof IMAGE_NT_HEADERS

    现在edi正指向PE header的起始地址,加上PE header结构大小后恰好指向节表了。

       invoke DialogBoxParam, hInstance, IDD_SECTIONTABLE,NULL, addr DlgProc, edi

    调用 DialogBoxParam 显示列表对话框,注意我们已将节表地址作为最后一个参数传递过去了,该值可从WM_INITDIALOG 消息的lParam参数中提取。

    在对话框过程里我们响应WM_INITDIALOG消息,将lParam(节表地址)存入esi,节数目赋给edi并设置列表控件。万事俱备后,进入循环将各节信息插入到列表控件中,这部分相当简单。

          .while edi>0
             mov lvi.iSubItem,0

    字符串置入第一列。

             invoke RtlZeroMemory,addr buffer,9
             invoke lstrcpyn,addr buffer,addr [esi].Name1,8
             lea eax,buffer
             mov lvi.pszText,eax

    要显示节名,当然要将其转换为ASCIIZ字符串先。

             invoke SendDlgItemMessage,hDlg,IDC_SECTIONLIST,LVM_INSERTITEM,0,addr lvi

    然后显示第一列。
    继续我们伟大的工程,显示完本节中最后一个欲呈现的值后,立马下一个结构。

             dec edi
             add esi, sizeof IMAGE_SECTION_HEADER
          .endw

    每处理完一节就递减edi,然后将esi加上IMAGE_SECTION_HEADER 结构大小,使其指向下一个IMAGE_SECTION_HEADER 结构。

    遍历节表的步骤:

    1. PE文件有效性校验。
    2. 定位到 PE header 的起始地址。
    3. file header NumberOfSections域获取节数。
    4. 通过两种方法定位节表: ImageBase+SizeOfHeaders 或者 PE header的起始地址+ PE header结构大小。 (节表紧随 PE header)。如果不是使用文件映射的方法,可以用SetFilePointer 直接将文件指针定位到节表。节表的文件偏移量存放在 SizeOfHeaders域里。(SizeOfHeaders IMAGE_OPTIONAL_HEADER 的结构成员)
    5. 处理每个 IMAGE_SECTION_HEADER 结构。

    翻译:iamgufeng [Iczelion's Win32 Assembly Homepage][LuoYunBin's Win32 ASM Page]

     



       
    [数据载入中...] [返回上一页] [打 印] [收 藏]
    上一篇技术文章:iczelionpetutcn6
     
    相关技术文章 搜索
  • ★ 在迅雷中搜索更多iczelionpetutcn5相关内容
  • ★ 在百度中搜索更多iczelionpetutcn5相关内容
  • ★ 在GOOGLE中搜索更多iczelionpetutcn5相关内容
  • ★ 在SOGOU中搜索更多iczelionpetutcn5相关内容
  • ★ 在雅虎中搜索更多iczelionpetutcn5相关内容
  • ★ 在腾讯SoSo中搜索更多iczelionpetutcn5相关内容
  • ★ 在中国搜索中搜索更多iczelionpetutcn5相关内容
  •  
    相关技术文章评论    (评论内容只代表网友观点,与本站立场无关!) [更多评论...]

    用户名
    分 值 100分 85分 70分 55分 40分 25分 10分 0分
    说 明
      (注“”为必填内容。)
     
    关于本站 - 网站帮助 - 广告合作 - 下载声明 - 网站地图
    本页主要内容:iczelionpetutcn5
    Copyright © 2002-2008 itlove.net. All Rights Reserved .  苏ICP备05061636号