已閱讀5頁,還剩8頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
前幾天和朋友交流技術(shù),提到手工打造微型PE文件,他說現(xiàn)在網(wǎng)上流傳的大部分版本在XP SP3下都不能運行,于是心血來潮,拍著胸脯說:“你放心,忙完了幫你做一個。”后來花了半天時間,終于打造出一個XP下可運行的微型PE,彈出一個對話框,292字節(jié),當(dāng)然這離極限也許還差得遠(yuǎn),不過自己做了一次,還是有些心得,貼出來和大家分享一下。本文介紹的這個MiniPE可以在下載:/source/774041第一步 準(zhǔn)備PE文件先創(chuàng)建一個PE文件,為了盡可能地小,我們用匯編語言來編寫。代碼如下:.386.model flat,stdcalloption casemap:none.databyData db 90h.codestart:end代碼什么也沒做,運行就報錯(因為PE文件的EntryPoint實際上指向了不存在的區(qū)域),代碼我們到后面再來填充它,這個PE文件只包含一個數(shù)據(jù)節(jié)。在Windows XP下,PE文件必須包含至少一個節(jié),否則無法運行,這正是我們?yōu)槭裁匆xbyData這個數(shù)據(jù)的原因。為了讓生成出的PE文件盡可能小,在鏈接的時候,我們使用/align:4這個選項,指定文件和節(jié)為4字節(jié)對齊(高版本的Microsoft增量鏈接器可能不支持4字節(jié)對齊,比如我測試的8.0版本,要求至少16字節(jié)對齊。所以使用這個選項,應(yīng)該用低版本的鏈接器,我用的是MASM32V9自帶的鏈接器,版本是5.12。)這樣生成出來的PE文件只有460字節(jié),這是一個很好的開始,因為大部分極其簡單的匯編程序生成出來都會在1.5K左右,如果是高級語言編寫的,將會更高。文件的內(nèi)容如下:00000000h: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 ; MZ?. .00000010h: B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ; ?.00000020h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 A8 00 00 00 ; .?.00000040h: 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ; .?.?L?Th00000050h: 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F ; is program canno00000060h: 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 ; t be run in DOS00000070h: 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 ; mode.$.00000080h: 5D 17 1D DB 19 76 73 88 19 76 73 88 19 76 73 88 ; .?vs?vs?vs?00000090h: E5 56 61 88 18 76 73 88 52 69 63 68 19 76 73 88 ; 錠a?vs圧ich.vs?000000a0h: 00 00 00 00 00 00 00 00 50 45 00 00 4C 01 01 00 ; .PE.L.000000b0h: 77 B8 1A 49 00 00 00 00 00 00 00 00 E0 00 0F 01 ; w?I.?.000000c0h: 0B 01 05 0C 00 00 00 00 04 00 00 00 00 00 00 00 ; .000000d0h: C8 01 00 00 C8 01 00 00 C8 01 00 00 00 00 40 00 ; ?.?.?.000000e0h: 04 00 00 00 04 00 00 00 04 00 00 00 00 00 00 00 ; .000000f0h: 04 00 00 00 00 00 00 00 CC 01 00 00 C8 01 00 00 ; .?.?.00000100h: 00 00 00 00 02 00 00 00 00 00 10 00 00 10 00 00 ; .00000110h: 00 00 10 00 00 10 00 00 00 00 00 00 10 00 00 00 ; .00000120h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000130h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000140h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000150h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000160h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000170h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000180h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000190h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000001a0h: 2E 64 61 74 61 00 00 00 01 00 00 00 C8 01 00 00 ; .data.?.000001b0h: 04 00 00 00 C8 01 00 00 00 00 00 00 00 00 00 00 ; .?.000001c0h: 00 00 00 00 40 00 00 C0 90 00 00 00 ; .缾.第二步 去掉數(shù)據(jù)節(jié)內(nèi)容看到文件的最后4字節(jié),90 00 00 00,這正是我們定義的byData(鏈接器使用4字節(jié)對起,后面3字節(jié)填0),這當(dāng)然不是我們需要的東西,我們定義byData,只是為了讓鏈接器生成PE文件時能至少有一個節(jié)。所以我們先把它拿掉,在UltraEdit中直接刪除最后4個字節(jié),把000001a8處Section的Virtual Size改為0,這樣,文件又少了4個字節(jié)。第三步 去掉DOS Stub我們的目標(biāo)是在Windows XP下運行,DOS Stub自然是多余的,可是鏈接器并沒有選項來去掉DOS Stub,只好手工來做這個工作,文件偏移0x3C處(IMAGE_DOS_HEADER的e_lfanew)指定了PE文件頭位置,這里是0x000000A8,直接將文件偏移0x3C到0xA8間的數(shù)據(jù)刪除,把后面的數(shù)據(jù)往前移,再將一些數(shù)據(jù)適當(dāng)修正,比如e_lfanew修正為0x40。這里DOS Stub的大小為0xA8-0x40=0x68,拿掉它,我們的文件又小了104字節(jié),內(nèi)容如下:00000000h: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 ; MZ?. .00000010h: B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ; ?.00000020h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 ; .00000040h: 50 45 00 00 4C 01 01 00 77 B8 1A 49 00 00 00 00 ; PE.L.w?I.00000050h: 00 00 00 00 E0 00 0F 01 0B 01 05 0C 00 00 00 00 ; .?.00000060h: 09 00 00 00 00 00 00 00 60 01 00 00 60 01 00 00 ; .00000070h: 60 01 00 00 00 00 40 00 04 00 00 00 04 00 00 00 ; .00000080h: 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ; .00000090h: 64 01 00 00 60 01 00 00 00 00 00 00 02 00 00 00 ; d.000000a0h: 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 ; .000000b0h: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 ; .000000c0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000d0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000e0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000f0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000100h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000110h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000120h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000130h: 00 00 00 00 00 00 00 00 2E 64 61 74 61 00 00 00 ; .data.00000140h: 00 00 00 00 60 01 00 00 00 00 00 00 60 01 00 00 ; .00000150h: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 ; .第四步 重疊DOS文件頭和PE文件頭在Windows下,PE裝載器只關(guān)心DOS文件頭的e_magic和e_lfanew,有這么多無用的項目,何不把PE文件頭往前挪挪,大家擠一擠,再謄點空間出來。當(dāng)然,PE文件頭的長度超過了DOS文件頭,往前移動,肯定是會覆蓋到e_lfanew的。e_lfanew是不能隨便亂填的,怎么辦?我們把PE文件頭移動到文件偏移0x04的位置,再把e_lfanew修改為0x04,現(xiàn)在PE裝載器可以正確從e_lfanew找到PE文件頭的位置了,我們在來看看PE文件頭,在PE文件頭偏移0x3C-0x4=0x38的位置,剛好是IMAGE_OPETION_HEADER的SectionAlignment節(jié)對齊值,剛剛好,我們的節(jié)對齊也是4,講到這里,如果你鏈接PE文件時,用的對齊值不是4那么就得修改為4咯。這一步也很簡單,直接把剛才文件偏移0x40的數(shù)據(jù)拷貝到0x04處,這時候,我們的PE文件總大小為292字節(jié):sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)+4。文件內(nèi)容如下:00000000h: 4D 5A 90 00 50 45 00 00 4C 01 01 00 77 B8 1A 49 ; MZ?PE.L.w?I00000010h: 00 00 00 00 00 00 00 00 E0 00 0F 01 0B 01 05 0C ; .?.00000020h: 00 00 00 00 09 00 00 00 00 00 00 00 60 01 00 00 ; .00000030h: 60 01 00 00 60 01 00 00 00 00 40 00 04 00 00 00 ; .00000040h: 04 00 00 00 04 00 00 00 00 00 00 00 04 00 00 00 ; .00000050h: 00 00 00 00 64 01 00 00 60 01 00 00 00 00 00 00 ; .d.00000060h: 02 00 00 00 00 00 10 00 00 10 00 00 00 00 10 00 ; .00000070h: 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ; .00000080h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000090h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000a0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000b0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000c0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000d0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000e0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .000000f0h: 00 00 00 00 00 00 00 00 00 00 00 00 2E 64 61 74 ; .dat00000100h: 61 00 00 00 00 00 00 00 60 01 00 00 00 00 00 00 ; a.00000110h: 60 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .00000120h: 40 00 00 C0 ; .第五步 添加代碼這一步很有意思,我們的PE文件沒有代碼節(jié),也沒有導(dǎo)入表,怎么讓他調(diào)用MessageBoxA呢?第一個問題很好解決,PE文件頭的EntryPoint不一定要指向代碼節(jié),例如很多加殼軟件都會修改EntryPoint,讓它指向自己的地址。極端一點,EntryPoint甚至可以指向PE文件的任意位置。我們來看一下,實際上對于PE文件頭,PE裝載器有很多字段也不會解釋,這里把這些字段列出來,其中帶“*”的字段表示值不能隨便填,能隨便填的值后面是其相對于我們這個PE文件的文件偏移:IMAGE_FILE_HEADER STRUCTMachine *NumberOfSections *TimeDateStampPointerToSymbolTable 0x0CNumberOfSymbols 0x10SizeOfOptionalHeader *Characteristics *IMAGE_FILE_HEADER ENDSIMAGE_FILE_HEADER ENDSIMAGE_OPTIONAL_HEADER32 STRUCTMagic *MajorLinkerVersion 0x1EMinorLinkerVersion 0x1FSizeOfCode 0x20SizeOfInitializedData 0x24SizeOfUninitializedData 0x28AddressOfEntryPoint *BaseOfCode 0x30BaseOfData 0x34ImageBase *SectionAlignment *FileAlignment *MajorOperatingSystemVersion *MinorOperatingSystemVersion *MajorImageVersion *MinorImageVersion *MajorSubsystemVersion *MinorSubsystemVersion *Win32VersionValue *SizeOfImage *SizeOfHeaders *CheckSum 0x5CSubsystem *DllCharacteristics *SizeOfStackReserve *SizeOfStackCommit *SizeOfHeapReserve *SizeOfHeapCommit *LoaderFlags 0x74NumberOfRvaAndSizes *DataDirectory *IMAGE_OPTIONAL_HEADER32 ENDS另外對于DataDirectories,都指定了Virtual Address和Size,一個結(jié)構(gòu)16字節(jié),實際上只要我們把它的任意一個字段填0,另外一個字段就可以挪作它用了(TLS除外,兩個字段必須都為0),有些DataDirectories甚至可以兩個字段都任意填寫,比如Exception Table,Seccrity Table,Base Relocation Table,Copyright Data Table,Global Ptr,再加上后面那個數(shù)據(jù)節(jié)的節(jié)表,除了VirtualSize,RAV/Offset和Pointer To Raw Data外,其他的都能隨意填充。這樣算下來,只要我們的代碼足夠小,還是有足夠的空間容納的?,F(xiàn)在讓我們來寫代碼。一個沒有導(dǎo)入表的程序,如何才能動態(tài)裝載User32.dll并調(diào)用其中的MessageBoxA呢?我們來看看下面的代碼:.386.model flat,stdcalloption casemap:noneinclude windows.inc.dataszUser32 db user32.dll,0szMsg db Hello World!,0szTitle db MiniPE,0.codeGetApi proc hModule,nIndexmov esi,hModulemov edx,nIndexadd esi,(IMAGE_DOS_HEADER ptr esi).e_lfanewassume esi:ptr IMAGE_NT_HEADERSmov esi,esi.OptionalHeader.DataDirectory.VirtualAddressadd esi,eaxassume esi:ptr IMAGE_EXPORT_DIRECTORYsub edx,esi.nBaserol edx,2mov edi,esi.AddressOfFunctionsadd edi,eaxadd edi,edxmov edx,dword ptr ediadd eax,edxretGetApi endpWinMain proclocal hModuleassume fs:nothingmov eax,fs:30hmov eax,eax+0Chmov eax,eax+0Chmov eax,eaxmov eax,eaxmov eax,eax+18hmov hModule,eaxinvoke GetApi,hModule,245h.if eaxpush offset szUser32call eax.if eaxmov hModule,eaxinvoke GetApi,hModule,1DDh.if eaxpush MB_OKpush offset szTitlepush offset szMsgpush 0call eax.endif.endif.endifretWinMain endpend WinMain上面的代碼并沒有顯示調(diào)用任何API,但是在Windows XP下,你嘗試編譯并運行它,你會發(fā)現(xiàn)他竟然能彈出一個對話框來。看看代碼的入口:首先加載fs:30h到eax,如果你研究過SHE的,一定對fs段寄存器很熟悉。在基于NT的操作系統(tǒng)中,fs寄存器用于訪問線程本地信息(TEB)。我們來看看TEB到0x30處的定義:0x00 NtTib :_NT_TIB0x1C EnvironmentPointer :Ptr32 Void0x20 ClientId :_CLIENT_ID0x28 ActiveRpcHandle :Ptr32 Void0x2C ThreadLocalStoragePointer :Ptr32 Void0x30 ProcessEnvironmentBlock :Ptr32 _PEB很顯然,這里是通過TEB來訪問進程環(huán)境塊(PEB),后面的代碼又將PEB的0x0C的數(shù)據(jù)加載到eax,我們來看PEB到0x0C的定義:0x00 InheritedAddressSpace :UChar0x01 ReadImageFileExecOptions :UChar0x02 BeginDebugged :UChar0x03 SpareBool :UChar0x04 Mutant :Ptr32 Void0x08 ImageBaseAddress :Ptr32 Void0x0C Ldr :Ptr _PEB_LDR_DATA可見,偏移0x0C出是_PEB_LDR_DATA,加載程序信息,后面的代碼又訪問了這個結(jié)構(gòu)0x0C處的數(shù)據(jù),我們再來看看_PEB_LDR_DATA到0x0C的定義:0x00 Length :Uint4B0x04 Initialized :UChar0x08 SsHandle :Ptr32 Void0x0C InLoadOrderModuleList :_LIST_ENTRY實際上_PEB_LDR_DATA+0x0C處的InLoadOrderModuleList正是LDR_DATA_TABLE_ENTRY結(jié)構(gòu),讓我們來看看它:0x00 InLoadOrderLinks :_LIST_ENTRY0x08 InMemoryOrderLinks :_LIST_ENTRY0x10 InInitializationOrderLinks :_LIST_ENTRY0x18 DllBase :Ptr32 Void0x1C EntryPoint :Ptr32 Voi我們的程序首先讀取了其偏移0處的數(shù)據(jù),它正是_LIST_ENTRY的Flink字段前向鏈接,mov eax,eax這段代碼直接跳過這個結(jié)構(gòu),把下一個_PEB_LDR_DATA結(jié)構(gòu)加載到eax,重復(fù)兩次,在讀0x18處的內(nèi)容模塊基地址。這是為什么呢?因為在Windows XP下,任何進程都必須含有至少3個模塊:自身、ntdll.dll、kernel32.dll,其加載順序也是自身、ntdll.dll、kernel32.dll。我們跳過前兩個模塊,把第三個模塊kernel32.dll的基地址加載到eax寄存器。上面的結(jié)構(gòu)看上去很復(fù)雜,要得到這些結(jié)構(gòu)的詳細(xì)信息,可以在WindDbg中使用“DT ModuleName!*”命令來列出模塊所有名字列表,然后再用“DT ModuleName!StructName”來列出結(jié)構(gòu)的詳細(xì)定義。得到了kernel32.dll的基地址,后面的代碼就很容易理解了,通過導(dǎo)出序號0x245從kernel32.dll的導(dǎo)出表中查找導(dǎo)出函數(shù)(0x245對應(yīng)的正是LoadLibraryA),得到LoadLibraryA的地址再通過調(diào)用它來加載user32.dll,再用同樣的方法用序號0x1DD從user32.dll導(dǎo)出表中查找MessageBoxA的地址。當(dāng)然,這里我們也可以使用函數(shù)名從模塊中查找導(dǎo)出函數(shù),不過為了盡量把代碼寫得短小,這里用了序號。羅云彬的Windows環(huán)境下32位匯編語言程序設(shè)計中對這兩種方法都作了說明,有興趣可以參考一下。解決了無導(dǎo)入表調(diào)用MessageBoxA的問題,我們還要想辦法把我們的代碼優(yōu)化得盡可能短,再回憶我們前面講的,我們要利用PE文件頭的空余字段,這些字段看上去沒有一塊足夠大的連續(xù)空間可以容納我們的整個代碼,所以我們還希望我們的代碼每條指令的機器碼盡量短,以便我們可以通過插入JZ/JNZ這樣的指令來靈活地利用空余的空間。在高級語言中,有_falstcall這樣的調(diào)用約定,我們借鑒一下,通過寄存器來傳遞調(diào)用函數(shù)的參數(shù),最終優(yōu)化出來,我的代碼如下:.386.model flat,stdcalloption casemap:noneinclude windows.inc.codeWinMain procassume fs:nothingmov ebx,offset GetApimov eax,fs:30hmov eax,eax+0Chmov eax,eax+0Chmov eax,eaxmov eax,eaxmov eax,eax+18hmov edx,245hcall ebxpush 00400000hcall eaxmov edx,1DDhcall ebxpush MB_OKpush 00400000hpush 00400000hpush 0call eaxretWinMain endpGetApi procmov esi,eaxadd esi,(IMAGE_DOS_HEADER ptr esi).e_lfanewassume esi:ptr IMAGE_NT_HEADERSmov esi,esi.OptionalHeader.DataDirectory.VirtualAddressadd esi,eaxassume esi:ptr IMAGE_EXPORT_DIRECTORYsub edx,esi.nBaserol edx,2mov edi,esi.AddressOfFunctionsadd edi,eaxadd edi,edxmov edx,dword ptr ediadd eax,edxretGetApi endpend WinMain在上面的代碼中,對于GetApi的調(diào)用,我們使用eax來傳遞hModule,因為無論是通過訪問TEB還是LoadLibraryA,模塊地址都已經(jīng)在eax中了,無須再用其他指令調(diào)整,edx來傳遞導(dǎo)出序號。上面的被調(diào)函數(shù)并沒有保護寄存器,是因為我們的代碼可以完全掌握所有的寄存器,確保關(guān)鍵寄存器不會被被調(diào)用函數(shù)覆蓋。代碼中有三個push 00400000h將字符串地址壓棧,可以肯定,我們最終會把user32.dll,Hello!,MiniPE這些字符串找個合適的空隙存放起來,地址暫時不能確定,先空起來,最后再填。代碼編譯出來:004001E0 /$ BB 1E024000 MOV EBX,ASMTest.0040021E004001E5 |. 64:A1 3000000MOV EAX,DWORD PTR FS:30004001EB |. 8B40 0C MOV EAX,DWORD PTR DS:EAX+C004001EE |. 8B40 0C MOV EAX,DWORD PTR DS:EAX+C004001F1 |. 8B00 MOV EAX,DWORD PTR DS:EAX004001F3 |. 8B00 MOV EAX,DWORD PTR DS:EAX004001F5 |. 8B40 18 MOV EAX,DWORD PTR DS:EAX+18004001F8 |. BA 45020000 MOV EDX,245004001FD |. FFD3 CALL EBX004001FF |. 68 02004000 PUSH ASMTest.0040000200400204 |. FFD0 CALL EAX00400206 |. BA DD010000 MOV EDX,1DD0040020B |. FFD3 CALL EBX0040020D |. 6A 00 PUSH 00040020F |. 68 1A004000 PUSH ASMTest.0040001A00400214 |. 68 0D004000 PUSH ASMTest.0040000D00400219 |. 6A 00 PUSH 00040021B |. FFD0 CALL EAX0040021D . C3 RETN0040021E . 8BF0 MOV ESI,EAX00400220 . 0376 3C ADD ESI,DWORD PTR DS:ESI+3C00400223 . 8B76 78 MOV ESI,DWORD PTR DS:ESI+7800400226 . 03F0 ADD ESI,EAX00400228 . 2B56 10 SUB EDX,DWORD PTR DS:ESI+100040022B . C1C2 02 ROL EDX,20040022E . 8B7E 1C MOV EDI,DWORD PTR DS:ESI+1C00400231 . 03F8 ADD EDI,EAX00400233 . 03FA ADD EDI,EDX00400235 . 8B17 MOV EDX,DWORD PTR DS:EDI00400237 . 03C2 ADD EAX,EDX00400239 . C3 RETN有90字節(jié),看樣子空隙足矣。主函數(shù)的代碼規(guī)模比較大,盡量找個連續(xù)的位置,看一下,文件偏移0x94這個位置比較合適(DataDirectories的Exception Table Address處),把剛才編譯好的Shellcode拷貝進去。到文件偏移0xB0這個位置,注意,不能填了,那么在偏移0xAC這個位置我們安排兩條指令來跳過它,直接跳到0xB4,JE 004000B4 JNE 004000B4,Shellcode剛好4字節(jié)。這樣按順序往下填寫,遇到需要跳過的地方就在它前面四字節(jié)位置用JE/JNE,到最后,從0x11E還空了些字段出來。然后是GetApi這個函數(shù),雖然才28字節(jié)。可是難阿,連連續(xù)28字節(jié)的位置都找不出來了。起始地址我們放在文件偏移0x0C處(PE文件頭的Time/Date Stamp字段),和前面一樣,遇到不能覆蓋的位置就在它前面四字節(jié)用JE/JNE跳過。但是代碼填到文件偏移0x25處為難了,0x2A是不能覆蓋的,那是PE文件頭的EntryPoint阿,看看這里的指令,ADD ESI,EAX SUB EDX,DWORD PTR ESI+10h,兩條算術(shù)指令,那么我們就用JNZ來跳過。我們可以肯定地知道,這兩條算術(shù)指令的運算結(jié)果不可能是0,否則,我們的程序也就出錯了。依次類推,后面遇到為難的而剛好又是算術(shù)指令的地方就用JNZ來跳過,才兩字節(jié)阿,又節(jié)省了寶貴的資源。這樣跳來跳去,到文件偏移0x8C的地方,GetApi的代碼也填完了。再回頭來看看主函數(shù)的第一條代碼,將GetApi的地址存入ebx,現(xiàn)在我們確定了GetApi的位置,那么就把0040000C填進去吧。然后是三個字符串,分別是“user32”(全名應(yīng)該是“user32.dll”,但實在找不出位置了,就用“user32”吧),“Hello!”,“MiniPE”。剛才說了,在文件偏移0x11E處還有空位呢,“user32”就填這里吧?!癏ello!”放在文件偏移0xD8處,“MiniPE”放在文件偏移0xE0處。最后別忘了修正004001FF |. 68 02004000 PUSH ASMTest.004000020040020F |. 68 1A004000 PUSH ASMTest.0040001A00400214 |. 68 0D004000 PUSH ASMTest.0040000D這三條指令后面字符串和PE文件頭EntryPoint的地址,EntryPoint修正為0x00000094。到此為止,292字節(jié)的微型PE打造成功了,最終的文件內(nèi)容如下:00000000h: 4D 5A 90 00 50 45 00 00 4C 01 01 00 8B F0 03 76 ; MZ?PE.L.嬸.v00000010h: 3C 8B 76 78 74 0D 75 0B E0 00 0F 01 0B 01 03 F0 ; 媣xt.u.?.?00000020h: 2B 56 10 03 F0 2B 56 10 75 06 00 00 94
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國輕巧型吸塵器數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年中國色拉匙數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年中國單相平底電磁灶數(shù)據(jù)監(jiān)測研究報告
- 2025年中國拉絲羊皮燈市場調(diào)查研究報告
- 2025年中國冰葡萄酒市場調(diào)查研究報告
- 臨時展覽場地租賃協(xié)議樣本版
- 二零二五年度特種涂料分包工程協(xié)議
- 二零二五年度車間租賃安全協(xié)議書(含智能化升級)
- 二零二五年度退休人員返聘文化傳播協(xié)議
- 二零二五年度酒店大堂豪華門簾訂購協(xié)議
- 垃圾處理廠工程施工組織設(shè)計
- 天皰瘡患者護理
- 機電一體化系統(tǒng)設(shè)計-第5章-特性分析
- 2025年高考物理復(fù)習(xí)壓軸題:電磁感應(yīng)綜合問題(原卷版)
- 2025年蛇年新年金蛇賀歲金蛇狂舞春添彩玉樹臨風(fēng)福滿門模板
- 《建筑制圖及陰影透視(第2版)》課件 4-直線的投影
- 2024-2030年中國IVD(體外診斷)測試行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略分析報告
- 碎紙機設(shè)計說明書
- 湖南省長沙市青竹湖湘一外國語學(xué)校2021-2022學(xué)年八年級下學(xué)期期中語文試題
- 2024年股權(quán)代持協(xié)議經(jīng)典版(3篇)
- 四川省成都市青羊區(qū)石室聯(lián)中學(xué)2024年八年級下冊物理期末學(xué)業(yè)水平測試試題含解析
評論
0/150
提交評論