WEB开发网      濠电姷鏁告繛鈧繛浣冲洤纾瑰┑鐘宠壘閻ょ偓銇勯幇鍫曟闁稿鍠愰妵鍕冀閵娧佲偓鎺楁⒒閸曨偄顏柡宀嬬畱铻e〒姘煎灡绗戦梻浣筋嚙濮橈箓顢氳濠€浣糕攽閻樿宸ュΔ鐘叉啞缁傚秹宕滆绾惧ジ寮堕崼娑樺缂佹宀搁弻鐔风暋閻楀牆娈楅梺璇″枓閺呯姴鐣疯ぐ鎺濇晝闁靛牆妫欓蹇旂節閻㈤潧浠﹂柛銊ョ埣楠炴劙骞橀鑲╋紱闂佽宕樼粔顔裤亹閹烘挸浜归梺缁樺灦閿曗晛螞閸曨垱鈷戦柟鑲╁仜婵″ジ鎮楀☉鎺撴珖缂侇喖顑呴鍏煎緞濡粯娅囬梻浣瑰缁诲倿寮绘繝鍥ㄦ櫇闁稿本绋撻崢鐢告煟鎼淬垻鈯曢柨姘舵煟韫囥儳绋荤紒缁樼箖缁绘繈宕橀妸褌绱濋梻浣筋嚃閸ㄤ即宕弶鎴犳殾闁绘梻鈷堥弫鍌炴煕閳锯偓閺呮瑧妲愬Ο琛℃斀闁绘劕妯婇崵鐔封攽椤旇棄鍔ら摶鐐烘煕閺囥劌澧柛娆忕箻閺屽秹宕崟顒€娅g紓浣插亾濠㈣泛顑囩粻楣冩煙鐎涙ḿ绠橀柨娑樼У椤ㄣ儵鎮欓鍕紙闂佽鍠栫紞濠傜暦閹偊妲诲┑鈩冨絻椤兘寮诲☉銏犖╅柕澶堝労閸斿绱撴担绋库偓鍝ョ矓瑜版帒鏋侀柟鍓х帛閺呮悂鏌ㄩ悤鍌涘 ---闂傚倸鍊烽悞锔锯偓绗涘厾娲煛閸涱厾顔嗛梺璺ㄥ櫐閹凤拷
开发学院网络安全黑客技术 压缩与脱壳-PE文件格式 四 阅读

压缩与脱壳-PE文件格式 四

 2007-01-12 20:12:08 来源:WEB开发网 闂傚倸鍊风欢姘缚瑜嶈灋闁圭虎鍠栫粻顖炴煥閻曞倹瀚�闂傚倸鍊风粈渚€骞夐敓鐘插瀭闁汇垹鐏氬畷鏌ユ煙閹殿喖顣奸柛搴$У閵囧嫰骞掗幋婵冨亾閻㈢ǹ纾婚柟鐐灱濡插牊绻涢崱妤冃℃繛宀婁簽缁辨捇宕掑鎵佹瀸闂佺懓鍤栭幏锟�濠电姷鏁告慨顓㈠箯閸愵喖宸濇い鎾寸箘閹规洟姊绘笟鈧ḿ褍煤閵堝悿娲Ω閳轰胶鍔﹀銈嗗笂閼冲爼鍩婇弴銏$厪闁搞儮鏅涙禒褏绱掓潏鈺佷槐闁轰焦鎹囬弫鎾绘晸閿燂拷闂傚倸鍊风欢姘缚瑜嶈灋闁圭虎鍠栫粻顖炴煥閻曞倹瀚�  闂傚倸鍊烽懗鑸电仚缂備胶绮〃鍛村煝瀹ュ鍗抽柕蹇曞У閻庮剟姊虹紒妯哄妞ゆ劗鍘ч埥澶娢熼柨瀣偓濠氭⒑瑜版帒浜伴柛鎾寸☉閳绘柨顫濋懜纰樻嫼闂佸憡绋戦オ鏉戔枔閺冣偓缁绘稓浠﹂崒姘瀳闂佸磭绮幑鍥嵁鐎n亖鏀介柟閭﹀墯椤斿倹淇婇悙顏勨偓鏍ь潖婵犳艾鍌ㄧ憸蹇涘箟閹绢喗鏅搁柨鐕傛嫹
核心提示: invoke AppendText,hDlg,addr NameHeader.while dword ptr [esi]!=0现在我们准备遍历 IMAGE_THUNK_DATAs 数组以查找该 DLL 引入的函数名,直到遇上全 0 项,压缩与脱壳-PE文件格式 四(4),test dwor
invoke AppendText,hDlg,addr NameHeader
.while dword ptr [esi]!=0

现在我们准备遍历 IMAGE_THUNK_DATAs 数组以查找该 DLL 引入的函数名,直到遇上全 0 项。

test dword ptr [esi],IMAGE_ORDINAL_FLAG32
jnz ImportByOrdinal

第一件事是校验 IMAGE_THUNK_DATA 是否含有 IMAGE_ORDINAL_FLAG32 标记。检查 IMAGE_THUNK_DATA 的 MSB 是否为 1 ,如果是 1 ,则函数是通过序数引出的,所以不需要更进一步处理了。直接从 IMAGE_THUNK_DATA 提取低字节获得序数,然后是下一个 IMAGE_THUNK_DATA 双字。

invoke RVAToOffset,pMapping,dword ptr [esi]
mov edx,eax
add edx,pMapping
assume edx:ptr IMAGE_IMPORT_BY_NAME

如果 IMAGE_THUNK_DATA 的 MSB 是 0 ,那么它包含了 IMAGE_IMPORT_BY_NAME 结构的 RVA 。需要先转换为虚拟地址。

mov cx, [edx].Hint
movzx ecx,cx
invoke wsprintf,addr temp,addr NameTemplate,ecx,addr [edx].Name1
jmp ShowTheText

Hint 是字类型,所以先转换为双字后再传递给 wsprintf ,然后我们将 hint 和函数名都显示到编辑控件中。

ImportByOrdinal:
mov edx,dword ptr [esi]
and edx,0FFFFh
invoke wsprintf,addr temp,addr OrdinalTemplate,edx

在仅用序数引出函数的情况中,先清空高字再显示序数。

ShowTheText:
invoke AppendText,hDlg,addr temp
add esi,4

在编辑控件中插入相应的函数名 / 序数后,跳转到下个 IMAGE_THUNK_DATA 。

.endw
add edi,sizeof IMAGE_IMPORT_DESCRIPTOR

处理完当前 IMAGE_THUNK_DATA 数组里的所有双字,跳转到下个 IMAGE_IMPORT_DESCRIPTOR 开始处理其他 DLLs 的引入函数了。

附录 :

让我们再来讨论一下 bound import 。当 PE 装载器装入 PE 文件时,检查引入表并将相关 DLLs 映射到进程地址空间。然后象我们这样遍历 IMAGE_THUNK_DATA 数组并用引入函数的真实地址替换 IMAGE_THUNK_DATAs 值。这一步需要很多时间。如果程序员能事先正确预测函数地址, PE 装载器就不用每次装入 PE 文件时都去修正 IMAGE_THUNK_DATAs 值了。 Bound import 就是这种思想的产物。

为了方便实现, Microsoft 出品的类似 Visual Studio 的编译器多提供了 bind.exe 这样的工具,由它检查 PE 文件的引入表并用引入函数的真实地址替换 IMAGE_THUNK_DATA 值。当文件装入时, PE 装载器必定检查地址的有效性,如果 DLL 版本不同于 PE 文件存放的相关信息,或则 DLLs 需要重定位,那么装载器认为原先计算的地址是无效的,它必定遍历 OriginalFirstThunk 指向的数组以获取引入函数新地址。

Bound import 在本课中并非很重要,我们确省就是用到了 OriginalFirstThunk 。要了解更多信息可参见 LUEVELSMEYER 的 pe.txt 。

上一页  1 2 3 4 

Tags:压缩 脱壳 PE

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接