能力值:
( LV3,RANK:20 )
|
-
-
6 楼
工具:winhex lordpe 例程:pe.exe 输入表实例分析
步骤一:用winhex打开pe.exe找到了2040h这个rva值
迷惑:用winhex看到的文件是磁盘文件还是映像文件?
如果是磁盘文件,2040这个值是winhex打开瞬间产生的,还是编译器产生的?
如果是映像文件.为什么直接用2040h找不到输入表的内容?
解:winhex打开的是磁盘文件[文件对齐存放] [注:磁盘文件的格式与用map这些API映射到内存里存放是一样的,没有用内存对齐的,里面的存放还是以文件对齐。,楼主指的映像应是指PE文件被PE装载器装载到内存中的存放文件吧,PE装载器装入PE文件到内存中的是以内存对齐存放的。所以这个要清楚]
我没看这章,所以我只以楼主的说明解释。
竟然2040这个是rva,rva是指这个值到映象基址的距离,即是当一个PE文件执行后他的装入点就是PE头里的imagebase这个值。所以真实的内存虚拟地址就是rva+imagebase
这里要说到文件偏移与rva了,比如用loadpe看文件.txet段偏移值是400,rva的值1000,那么在磁盘文件中即用winhex这个软件打开找到400处存的内存与当这个PE文件加载到内存后rva+1000处地方存的是一样的东东[可以用OD查看。]
楼主应是指2040这个rva处存的是输入表内容吧?那么,你要rva+imagebase这样才是内存中的虚拟地址。
步骤二:用lordpe打开了pe.exe文件,在目录表里找到了2040h,在区块表里找到.rdata的虚拟地址2000h和物理地址600h
迷惑: 在lordpe里看到的磁盘文件还是映像文件?
.rdata是只读区块而不是输入表区块对吗?
600h物理地址就是磁盘文件地址对吗?
如果不用lordpe怎么手动得到那个差值(K)?
lordpe应是把文件用映射API函数把他映射到内存中,从而读取PE格式里的各种值[这个有没有映射偶也没分析,也是不映射读了的。]。
.rdata这个东东可以随意命名,不过你说的那个PE文件我不清楚。
600h不叫物理地址,叫文件偏移。即是你找到文件在磁盘的某个地方,那么再加上600这个值就可以定位到600处的内容。同rva一样的。只是一个偏移值。
如果不用lordpe怎么手动得到那个差值(K)?什么差值?
三,IMAGE_THUNK_DATA STRUC
union u1
ForwarderString DWORD
Function DWORD
Ordinal DWORD
AddressOfData DWORD
ends
IMAGE_THUNK_DATA ENDS
这个结构体里的DWORD是不是要改成WROD,不然好像跟后面字节对不上号?
这个结构体是一个union结构,就是说某一个时刻只表示一个成员
新手问题较多,请高手耐心帮我解答一下,谢谢了
注。再努力学习下PE格式。。慢慢来。学了一下再自己写一下就清楚了。我看这个PE也看很久。。
我看的教材是罗大侠的。
以上不一定正确
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
搞明白了,找到的2040这个值是内存中的,.rdata的RVA是2000,对齐值是1000,所以2040在.rdata中,这也就是为什么用.rdata差值来计算的原因
总结一下,看这种书,还没熟练之前要一个字一个字的看过去,不能象学高级语言一样那么马虎
|
能力值:
( LV3,RANK:20 )
|
-
-
10 楼
你先理解。然后再写就行了。。。我学习时的练习程序。
;****************************************************************
;导入表对话框程序
;****************************************************************
_DlgImportProc proc uses esi edi ebx hDlg,uMsg,wParam,lParam
local @stLumm:LV_COLUMN,@stLumm1:LV_COLUMN
local @stLtiem:LV_ITEM,@stLtiem1:LV_ITEM
.if uMsg==WM_INITDIALOG
;*********************
invoke GetDlgItem,hDlg,IDC_LIST1
invoke SendMessage,eax,LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_GRIDLINES OR LVS_EX_FULLROWSELECT
invoke GetDlgItem,hDlg,IDC_LIST2
invoke SendMessage,eax,LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_GRIDLINES OR LVS_EX_FULLROWSELECT
;*********************
mov @stLumm.imask,LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
mov @stLumm.fmt,LVCFMT_CENTER
mov @stLumm.lx,90
mov @stLumm.iSubItem,0
mov @stLumm.pszText,offset szDllName
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_INSERTCOLUMN,0,addr @stLumm
inc @stLumm.iSubItem
mov @stLumm.pszText,offset szDllNameAddr
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_INSERTCOLUMN,1,addr @stLumm
inc @stLumm.iSubItem
mov @stLumm.pszText,offset szOriginalFirstThunk
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_INSERTCOLUMN,2,addr @stLumm
inc @stLumm.iSubItem
mov @stLumm.pszText,offset szFirstThunk
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_INSERTCOLUMN,3,addr @stLumm
;行
mov @stLtiem.imask,LVIF_TEXT
mov @stLtiem.iItem,0
;******************************************
mov esi,lpNtHeader
assume esi:ptr IMAGE_NT_HEADERS
mov ebx,[esi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress ;导入表RVA
invoke _RvaToOffset,lpNtHeader,ebx ;把RVA转为文件偏移,返回的eax的值就是文件偏移
add eax,lpMemory ;eax是导入表的文件偏移,所以加上lpMemory,那么现在eax就是指向导入表
mov esi,eax
mov lpImportFstruct,esi
assume esi:ptr IMAGE_IMPORT_DESCRIPTOR ;IMAGE_IMPORT_DESCRIPTOR最后一个是全0的结构
;***
.while [esi].OriginalFirstThunk || [esi].TimeDateStamp || [esi].ForwarderChain || [esi].FirstThunk || [esi].Name1
invoke _RvaToOffset,lpNtHeader,[esi].Name1 ;这个是一个RVA指向一个以0结尾的字符串
add eax,lpMemory
invoke wsprintf,addr szPeFmatBuffer,addr szFmatName,eax
;********
mov @stLtiem.iSubItem,0
mov @stLtiem.pszText,offset szPeFmatBuffer
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_INSERTITEM,0,addr @stLtiem
inc @stLtiem.iSubItem
invoke wsprintf,addr szPeFmatBuffer,addr szPeFmatNum,[esi].Name1
mov @stLtiem.pszText,offset szPeFmatBuffer
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_SETITEM,0,addr @stLtiem
inc @stLtiem.iSubItem
invoke wsprintf,addr szPeFmatBuffer,addr szPeFmatNum,[esi].OriginalFirstThunk
mov @stLtiem.pszText,offset szPeFmatBuffer
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_SETITEM,0,addr @stLtiem
inc @stLtiem.iSubItem
invoke wsprintf,addr szPeFmatBuffer,addr szPeFmatNum,[esi].FirstThunk
mov @stLtiem.pszText,offset szPeFmatBuffer
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_SETITEM,0,addr @stLtiem
inc @stLtiem.iItem
add esi,sizeof IMAGE_IMPORT_DESCRIPTOR
.endw ;全0时退出
;***
;******************************************
assume esi:nothing
;**********************
mov @stLumm1.imask,LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
mov @stLumm1.fmt,LVCFMT_CENTER
mov @stLumm1.lx,140
mov @stLumm1.iSubItem,0
mov @stLumm1.pszText,offset szFunctionName
invoke SendDlgItemMessage,hDlg,IDC_LIST2,LVM_INSERTCOLUMN,0,addr @stLumm1
inc @stLumm1.iSubItem
mov @stLumm1.pszText,offset szHint
invoke SendDlgItemMessage,hDlg,IDC_LIST2,LVM_INSERTCOLUMN,1,addr @stLumm1
;**********************
.elseif uMsg==WM_NOTIFY
mov eax,lParam
assume eax:ptr NMHDR
.if ([eax].idFrom==IDC_LIST1) && ([eax].code==LVN_ITEMCHANGED)
assume eax:nothing
invoke SendDlgItemMessage,hDlg,IDC_LIST2,LVM_DELETEALLITEMS,0,0 ;清空
invoke SendDlgItemMessage,hDlg,IDC_LIST1,LVM_GETNEXTITEM,-1,LVNI_SELECTED
.if eax!=-1
mov ebx,sizeof IMAGE_IMPORT_DESCRIPTOR
imul ebx ;eax*ebx
mov esi,lpImportFstruct ;这个是在内存中指向第一个IMAGE_IMPORT_DESCRIPTOR的值
add esi,eax
assume esi:ptr IMAGE_IMPORT_DESCRIPTOR
.if [esi].OriginalFirstThunk ;这个是指向IMAGE_THUNK_DATA结构数组的偏移地址
mov eax,[esi].OriginalFirstThunk ;因为有可能会把OriginalFirstThunk置0
.else
mov eax,[esi].FirstThunk;所以用这个 eax现在是RVA
.endif
assume esi:nothing
invoke _RvaToOffset,lpNtHeader,eax ;返回文件偏移
add eax,lpMemory ;内存映射文件之后这个IMAGE_THUNK_DATA结构的起始地址
mov esi,eax
; IMAGE_THUNK_DATA ;这个结构是一个双字DWORD型
mov @stLtiem1.imask,LVIF_TEXT
mov @stLtiem1.iItem,0
.while DWORD ptr [esi]!=0
.if DWORD ptr [esi] & 80000000h ;按位相与,若高位为1则是按序号导入[双字低位是序号]
mov eax,DWORD ptr [esi]
and eax,0FFFFh
invoke wsprintf,addr szPeFmatBuffer,addr szPeFmatNum,eax
mov @stLtiem1.iSubItem,0
mov @stLtiem1.pszText,offset szPeFmatBuffer
invoke SendDlgItemMessage,hDlg,IDC_LIST2,LVM_INSERTITEM,0,addr @stLtiem1
.else
invoke _RvaToOffset,lpNtHeader,DWORD ptr [esi] ;高位为0时则是一个RVA
add eax,lpMemory ;指向IMAGE_IMPORT_BY_NAME结构
assume eax:ptr IMAGE_IMPORT_BY_NAME
movzx ecx,[eax].Hint
invoke wsprintf,addr szPeFmatBuffer,addr szFmatName,addr [eax].Name1
mov @stLtiem1.iSubItem,0
mov @stLtiem1.pszText,offset szPeFmatBuffer
invoke SendDlgItemMessage,hDlg,IDC_LIST2,LVM_INSERTITEM,0,addr @stLtiem1
inc @stLtiem1.iSubItem
invoke wsprintf,addr szPeFmatBuffer,addr szPeFmatNum,ecx
mov @stLtiem1.pszText,offset szPeFmatBuffer
invoke SendDlgItemMessage,hDlg,IDC_LIST2,LVM_SETITEM,0,addr @stLtiem1
assume eax:nothing
.endif
inc @stLtiem1.iItem
add esi,sizeof IMAGE_THUNK_DATA
.endw
.endif
.endif
.elseif uMsg==WM_COMMAND
.elseif uMsg==WM_CLOSE
invoke EndDialog,hDlg,FALSE
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_DlgImportProc endp
;****************************************************************
;导入表对话框程序
;****************************************************************
|