日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

PE学习(六)第六章 栈与重定位表 实例栈溢出、模拟加载器加载DLL、遍历重定位表

發(fā)布時(shí)間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PE学习(六)第六章 栈与重定位表 实例栈溢出、模拟加载器加载DLL、遍历重定位表 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第六章 棧與重定位表
16bit OS?存在長(zhǎng)調(diào)用 lcall push cs,ip??? 相應(yīng)的iret pop ip, cs? 而call/ret only focus ip register
32bit OS 因?yàn)?2寄存器可以訪問(wèn)4G空間,可以長(zhǎng)短調(diào)用被忽略,只關(guān)注eip

實(shí)模式:段地址+程序偏移地址??SS::SP= SS<<16+SP
保護(hù)模式:段選擇子+程序偏移地址?原來(lái)的段寄存器稱為段選擇子,指向是 GDT/LDT(全局描述符表/局部描述符表)

call?0xXXXXXXXX???;//push 后面的返回地址? 再 jump 0xXXXXXXXX

push ebp
mov ebp,esp??;//這兩句是masm32中偽關(guān)鍵字proc,和C中的函數(shù)一樣,翻譯為匯編時(shí)自動(dòng)會(huì)加上這兩行還有l(wèi)eave
...
leave?等價(jià) mov esp,ebp?pop ebp
上面這3行是 編譯器為proc做的

ret??;//pop eip

//當(dāng)只有一個(gè)要訪問(wèn).text段中的數(shù)據(jù)時(shí),需要設(shè)置段屬性
C:\testmasm\example\666>ml /coff HelloWorld1.asm /link -subsystem:windows -section:.text,ERW

window加載器發(fā)現(xiàn)IMAGE_OPTIONAL_HEADER32.ImageBase被占用時(shí),會(huì)根據(jù)重定位表修改所有的重定位信息

//棧溢出導(dǎo)致部分代碼未執(zhí)行.386.model flat,stdcalloption casemap:noneinclude windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib;數(shù)據(jù)段.data szTextHelloWord db 'HelloWorld',0 szTextOverData db 'Test overwrite ret address to simulate stack overflow!',0 szShellCode db 'oneArg',0;代碼段.code _overWrite proc _lpSrc;_lpSrc,retAddress,ebppushadmov [ebp+4],offset someAddresspopadret _overWrite endpstart:invoke _overWrite,addr szShellCodeinvoke MessageBox,NULL,offset szTextHelloWord,NULL,MB_OK someAddress:invoke MessageBox,NULL,offset szTextOverData,NULL,MB_OKinvoke ExitProcess,NULL end start


?

//no_exist_import_realloc_data.asm ;------------------------ ; 無(wú)導(dǎo)入表、無(wú)數(shù)據(jù)段、無(wú)重定位信息的HelloWorld ; 戚利 ; 2010.6.27 ;------------------------.386.model flat,stdcalloption casemap:noneinclude windows.inc;聲明函數(shù) _QLGetProcAddress typedef proto :dword,:dword ;聲明函數(shù)引用 _ApiGetProcAddress typedef ptr _QLGetProcAddress _QLLoadLib typedef proto :dword _ApiLoadLib typedef ptr _QLLoadLib_QLMessageBoxA typedef proto :dword,:dword,:dword,:dword _ApiMessageBoxA typedef ptr _QLMessageBoxA;代碼段.codeszText db 'HelloWorldPE',0 szGetProcAddr db 'GetProcAddress',0 szLoadLib db 'LoadLibraryA',0 szMessageBox db 'MessageBoxA',0user32_DLL db 'user32.dll',0,0;定義函數(shù) _getProcAddress _ApiGetProcAddress ? _loadLibrary _ApiLoadLib ? _messageBox _ApiMessageBoxA ?hKernel32Base dd ? hUser32Base dd ? lpGetProcAddr dd ? lpLoadLib dd ?;------------------------------------ ; 根據(jù)kernel32.dll中的一個(gè)地址獲取它的基地址 ;------------------------------------ _getKernelBase proc _dwKernelRetAddresslocal @dwRetpushadmov @dwRet,0mov edi,_dwKernelRetAddressand edi,0ffff0000h ;查找指令所在頁(yè)的邊界,以1000h對(duì)齊.repeat;找到kernel32.dll的dos頭.if word ptr [edi]==IMAGE_DOS_SIGNATURE mov esi,ediadd esi,[esi+003ch];找到kernel32.dll的PE頭標(biāo)識(shí).if word ptr [esi]==IMAGE_NT_SIGNATURE mov @dwRet,edi.break.endif.endifsub edi,010000h.break .if edi<070000000h.until FALSEpopadmov eax,@dwRetret _getKernelBase endp ;------------------------------- ; 獲取指定字符串的API函數(shù)的調(diào)用地址 ; 入口參數(shù):_hModule為動(dòng)態(tài)鏈接庫(kù)的基址 ; _lpApi為API函數(shù)名的首址 ; 出口參數(shù):eax為函數(shù)在虛擬地址空間中的真實(shí)地址 ;------------------------------- _getApi proc _hModule,_lpApilocal @retlocal @dwLenpushadmov @ret,0;計(jì)算API字符串的長(zhǎng)度,含最后的零mov edi,_lpApimov ecx,-1xor al,alcldrepnz scasbmov ecx,edisub ecx,_lpApimov @dwLen,ecx;從pe文件頭的數(shù)據(jù)目錄獲取導(dǎo)出表地址mov esi,_hModuleadd esi,[esi+3ch]assume esi:ptr IMAGE_NT_HEADERSmov esi,[esi].OptionalHeader.DataDirectory.VirtualAddressadd esi,_hModuleassume esi:ptr IMAGE_EXPORT_DIRECTORY;查找符合名稱的導(dǎo)出函數(shù)名mov ebx,[esi].AddressOfNamesadd ebx,_hModulexor edx,edx.repeatpush esimov edi,[ebx]add edi,_hModulemov esi,_lpApimov ecx,@dwLenrepz cmpsb.if ZERO?pop esijmp @F.endifpop esiadd ebx,4inc edx.until edx>=[esi].NumberOfNamesjmp _ret @@:;通過(guò)API名稱索引獲取序號(hào)索引再獲取地址索引sub ebx,[esi].AddressOfNamessub ebx,_hModuleshr ebx,1add ebx,[esi].AddressOfNameOrdinalsadd ebx,_hModulemovzx eax,word ptr [ebx]shl eax,2add eax,[esi].AddressOfFunctionsadd eax,_hModule;從地址表得到導(dǎo)出函數(shù)的地址mov eax,[eax]add eax,_hModulemov @ret,eax_ret:assume esi:nothingpopadmov eax,@retret _getApi endpstart:;取當(dāng)前函數(shù)的堆棧棧頂值mov eax,dword ptr [esp]push eaxcall @F ; 免去重定位 @@:pop ebxsub ebx,offset @Bpop eax;獲取kernel32.dll的基地址invoke _getKernelBase,eaxmov [ebx+offset hKernel32Base],eax;從基地址出發(fā)搜索GetProcAddress函數(shù)的首址mov eax,offset szGetProcAddradd eax,ebxmov edi,offset hKernel32Basemov ecx,[ebx+edi]invoke _getApi,ecx,eaxmov [ebx+offset lpGetProcAddr],eax;為函數(shù)引用賦值 GetProcAddressmov [ebx+offset _getProcAddress],eax ;使用GetProcAddress函數(shù)的首址;傳入兩個(gè)參數(shù)調(diào)用GetProcAddress函數(shù),獲得LoadLibraryA的首址mov eax,offset szLoadLibadd eax,ebxmov edi,offset hKernel32Basemov ecx,[ebx+edi]mov edx,offset _getProcAddressadd edx,ebx;模仿調(diào)用 invoke GetProcAddress,hKernel32Base,addr szLoadLibpush eaxpush ecxcall dword ptr [edx] mov [ebx+offset _loadLibrary],eax;使用LoadLibrary獲取user32.dll的基地址mov eax,offset user32_DLLadd eax,ebxmov edi,offset _loadLibrarymov edx,[ebx+edi]push eaxcall edx ; invoke LoadLibraryA,addr _loadLibrarymov [ebx+offset hUser32Base],eax;使用GetProcAddress函數(shù)的首址,獲得函數(shù)MessageBoxA的首址mov eax,offset szMessageBoxadd eax,ebxmov edi,offset hUser32Basemov ecx,[ebx+edi]mov edx,offset _getProcAddressadd edx,ebx;模仿調(diào)用 invoke GetProcAddress,hUser32Base,addr szMessageBoxpush eaxpush ecxcall dword ptr [edx] mov [ebx+offset _messageBox],eax;調(diào)用函數(shù)MessageBoxAmov eax,offset szTextadd eax,ebxmov edx,offset _messageBoxadd edx,ebx;模仿調(diào)用 invoke MessageBoxA,NULL,addr szText,NULL,MB_OK push MB_OKpush NULLpush eaxpush NULLcall dword ptr [edx] retend start


?

//遍歷重定位表 ;-------------------- ; 獲取PE文件的重定位信息 ;-------------------- _getRelocInfo proc _lpFile,_lpPeHead,_dwSizelocal @szBuffer[1024]:bytelocal @szSectionName[16]:bytepushadmov esi,_lpPeHeadassume esi:ptr IMAGE_NT_HEADERSmov eax,[esi].OptionalHeader.DataDirectory[8*5].VirtualAddress.if !eaxinvoke _appendInfo,addr szMsgReloc4jmp _ret.endifpush eaxinvoke _RVAToOffset,_lpFile,eaxadd eax,_lpFilemov esi,eaxpop eaxinvoke _getRVASectionName,_lpFile,eaxinvoke wsprintf,addr @szBuffer,addr szMsgReloc1,eaxinvoke _appendInfo,addr @szBufferassume esi:ptr IMAGE_BASE_RELOCATION;循環(huán)處理每個(gè)重定位塊.while [esi].VirtualAddresscld ;//set DF=0 向高地址步增lodsd ;eax=[esi].VirtualAddressmov ebx,eaxlodsd ;eax=[esi].SizeofBlocksub eax,sizeof IMAGE_BASE_RELOCATION ;塊總長(zhǎng)度-兩個(gè)ddshr eax,1 ;然后除以2,得到重定位項(xiàng)數(shù)量;除以2是因?yàn)橹囟ㄎ豁?xiàng)是wordpush eaxinvoke wsprintf,addr @szBuffer,addr szMsgReloc2,ebx,eaxinvoke _appendInfo,addr @szBufferpop ecx ;重定位項(xiàng)數(shù)量xor edi,edi.repeatpush ecxlodswmov cx,axand cx,0f000h ;得到高四位.if cx==03000h ;重定位地址指向的雙字的32位都需要休正and ax,0fffhmovzx eax,axadd eax,ebx ;得到修正以前的偏移,該偏移加上裝入時(shí)的基址就是絕對(duì)地址.else ;該重定位項(xiàng)無(wú)意義,僅用來(lái)作為對(duì)齊mov eax,-1.endifinvoke wsprintf,addr @szBuffer,addr szMsgReloc3,eaxinc edi.if edi==8 ;每顯示8個(gè)項(xiàng)目換行invoke lstrcat,addr @szBuffer,addr szCrLfxor edi,edi.endifinvoke _appendInfo,addr @szBufferpop ecx.untilcxz.if ediinvoke _appendInfo,addr szCrLf.endif.endw _ret:assume esi:nothingpopadret _getRelocInfo endp


?

總結(jié)

以上是生活随笔為你收集整理的PE学习(六)第六章 栈与重定位表 实例栈溢出、模拟加载器加载DLL、遍历重定位表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。