編寫自定義PE結構的程式(如何手寫一個PE,高階編譯器都是編譯好的PE頭部,例如MASM,TASM等,NASM,FASM是低階編譯器.可以自定義結構)
阿新 • • 發佈:2019-01-02
正在學PE結構...感謝個位大哥的文章和資料...這裡先說聲謝謝
一般高階編譯器都是編譯好的PE頭部,例如MASM,TASM等
一直都說NASM,FASM是低階編譯器.可以自定義結構
但是苦於無人釋出相關文章說明..我這裡就簡單的用NASM寫一下
由於剛學PE結構許多東西都不太懂希望個位大俠指點
如何打造一個迷你的PE結構..我暫只只能作到617位元組
下面隨著學習的深入...還有更迷你的PE出現...
程式碼可以直接編譯..
編譯引數:nasmw -fbin MsgBoxA.asm -o MsgBoxA.exe
請下載最新的NASM for Win32編譯器
當前最新版本:NASM 0.98.39
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Small PE Header Demo For NASM ;Email:[email protected]
;
;程式碼說明:NASM 編寫迷你PE程式碼.(C) 2006.3.20
;1.自構造PE頭部
;2.自構造匯入表結構
;
;Thank:Vecna[29A],Nguga aka PedroGC Made NAGOA+.INC
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [BITS 32]
%define CODE_BASE 1000h ;程式碼基址
%define RVADIFF 1000h-200h ;計算記憶體資料與硬碟資料相對便宜
%define imagebase 00400000h ;程式碼基址
%define reloc RVADIFF+imagebase ;全域性偏移--一個很重要的引數
;DOS STUB頭部
MZ_Header:
.magic dw
"MZ"
;01 02----DOS STUB標識[關鍵資料]
.cblp dw 435Bh ;03 04--[非關鍵資料]
.
cp
dw 415Dh ;05 06--[非關鍵資料]
.crlc dw 736Eh ;07 08--這十個位元組我們可以寫一點自己的個人資訊[非關鍵資料]
.cparhdr dw 796Bh ;09 10--[非關鍵資料]
.minalloc dw 2161h ;11 12--[非關鍵資料]
PE_Header:
.Signature
dd
"PE"
;13 14 | 15 16----PE 頭部起始[關鍵資料]
.Machine dw 14Ch ;17 18----該檔案執行所要求的CPU:IMAGE_FILE_MACHINE_I386[關鍵資料]
.NumberOfSections dw 1 ;19 20----檔案節數量[關鍵資料]
.TimeDateStamp
dd
0h ;21 22 | 23 24----檔案建立日期和時間[非關鍵資料]
.PointerToSymbolTable
dd
0h ;25 26 | 27 28----除錯資訊-[非關鍵資料]
.NumberOfSymbols
dd
0h ;29 30 | 31 32----除錯資訊-[非關鍵資料]
.SizeOfOptionalHeader dw 0E0h ;33 34----OptionalHeader 結構大小[關鍵資料]
.Characteristics dw 103h ;35 36----檔案資訊的標記:比如檔案是exe還是dll[關鍵資料]
Optional_Header:
.Magic dw 10Bh ;37 38----[關鍵資料]
.MajorLinkerVersion db 0h ;39----[非關鍵資料]
.MinorLinkerVersion db 0h ;40----[非關鍵資料]
.SizeOfCode
dd
0h ;41 42 | 43 44----[非關鍵資料]
.SizeOfInitializedData
dd
0h ;45 46 | 47 48----[非關鍵資料]
.SizeOfUninitialzedData
dd
0h ;49 50 | 51 52----[非關鍵資料]
.AddressOfEntryPoint
dd
code+RVADIFF ;53 54 | 55 56----程式碼基址+RVA=此值---需要計算[關鍵資料]
.BaseOfCode
dd
0h ;57 58 | 59 60----程式碼基址[非關鍵資料]
;.BaseOfData
dd
DATA_BASE ;資料基址-被下面的.lfanew替換了~這個數值本身也沒有什麼用
.lfanew
dd
0Ch ;61 62 | 63 64----標識.PE頭部的起始位置這裡寫為C-看上面第13位元組
;DOS STUB部分的最後結尾部分---標識:PE頭部的起始位置~他的位置是固定的所以只能寫在最後了
;align 16, DB 0
.ImageBase
dd
imagebase;65 66 | 67 68----記憶體對映基址--預設為00400000h[關鍵資料]
.SectionAlignment
dd
01000h ;69 70 | 71 72----記憶體中節對齊--如果該值是1000h那麼每節的起始地址必須是4096的倍數,
.FileAlignment
dd
0200h ;73 74 | 75 76----檔案對齊[關鍵資料]..明白吧
.MajorOperSystemVersion dw 0h ;77 78--[非關鍵資料]
.MinorOperSystemVersion dw 0h ;79 80--[非關鍵資料]
.MajorImageVersion dw 0h ;81 82--win32子系統版本。若PE檔案是專門為Win32設計的[非關鍵資料]
.MinorImageVersion dw 0h ;83 84--該子系統版本必定是4.0否則對話方塊不會有3維立體感[非關鍵資料]
.MajorSubsystemVersion dw 4 ;85 86--[關鍵資料]
.MinorSubsystemVersion dw 0 ;87 88--[關鍵資料]
.Reserved1
dd
0 ;89 90 | 91 92----[非關鍵資料]
.SizeOfImage
dd
2000h ;93 94 | 95 96----記憶體中整個PE映像體的尺寸,它是所有頭和節經過節對齊處理後的大小[關鍵資料]
.SizeOfHeaders
dd
code ;97 98 | 99 100---所有頭+節表的大小,也就等於檔案尺寸減去檔案中所有節的尺寸,可以以此值作為PE檔案第一節的檔案偏移量[關鍵資料]
.CheckSum
dd
0h ;101 102 | 103 104----[非關鍵資料]
.Subsystem dw 2 ;105 106----PE檔案屬子系統,2=Win32 GUI,3=Win32 Console[關鍵資料]
.DllCharacteristics dw 0 ;107 108----[非關鍵資料]
.SizeOfStackReserve1
dd
100000h ;109 110 | 111 112----[關鍵資料]
.SizeOfStackCommit1
dd
2000h ;113 114 | 115 116----[關鍵資料]
.SizeOfStackReserve2
dd
100000h ;117 118 | 119 120----[關鍵資料]
.SizeOfStackCommit2
dd
2000h ;121 122 | 123 124----[關鍵資料]
.LoaderFlags
dd
0h ;125 126 | 127 128----[非關鍵資料]
.NumberOfRvaAndSizes
dd
10h ;129 130 | 131 132----[關鍵資料]
Data_Directories:
.ExportRva
dd
0h ;133 134 | 135 136----匯出表虛擬偏移[非關鍵資料]
.ExportSize
dd
0h ;137 138 | 139 140----匯入表長度[非關鍵資料]
.ImportRva
dd
import
+RVADIFF ;141 142 | 143 144----匯入表虛擬偏移[關鍵資料]
.ImportSize
dd
code_end-
import
;145 146 | 147 148----匯入表長度[關鍵資料]
;匯入表結構部分~這個地方需要仔細構造[尚未研究徹底]
;.misc_sectionz
times
28
dd
0 ;其他部分~對於我們完全沒用的
.ResourceRva
dd
0h ;資源表虛擬偏移[非關鍵資料]
.ResourceSize
dd
0h ;資源表長度[非關鍵資料]
.ExceptionRva
dd
0h ;沒玩過這東東[非關鍵資料]
.ExceptionSize
dd
0h ;沒玩過這東東[非關鍵資料]
.CertificateRva
dd
0h ;沒玩過這東東[非關鍵資料]
.CertificateSize
dd
0h ;沒玩過這東東[非關鍵資料]
.BaseRelocationRva
dd
0h ;基址重定位表虛擬偏移[非關鍵資料]
.BaseRelocationSize
dd
0h ;基址重定位表長度[非關鍵資料]
.DebugRva
dd
0h ;除錯資訊虛擬偏移[非關鍵資料]
.DebugSize
dd
0h ;除錯資訊長度[非關鍵資料]
.DescriptionRva
dd
0h ;沒玩過這東東[非關鍵資料]
.DescriptionSize
dd
0h ;沒玩過這東東[非關鍵資料]
.MachineRva
dd
0h ;沒玩過這東東[非關鍵資料]
.MachineSize
dd
0h ;沒玩過這東東[非關鍵資料]
.TLSRva
dd
0h ;執行緒處理資料[關鍵資料]
.TLSSize
dd
0h ;執行緒處理資料長度[關鍵資料]
.LoadConfigRva
dd
0h ;沒玩過這東東[關鍵資料]
.LoadConfigSize
dd
0h ;沒玩過這東東[關鍵資料]
.BoundImportRva
dd
0h ;繫結匯入表資料[關鍵資料]
.BoundImportSize
dd
0h ;繫結匯入表資料長度[關鍵資料]
.IATRva
dd
0h ;沒玩過這東東[關鍵資料]
.IATSize
dd
0h ;沒玩過這東東[關鍵資料]
.DelayImportDescriptor1
dd
0h ;沒玩過這東東[非關鍵資料]
.DelayImportDescriptor2
dd
0h ;沒玩過這東東[非關鍵資料]
.COMRuntimeHeader1
dd
0h ;COM+ 時間連線庫虛擬偏移地址[非關鍵資料]
.COMRuntimeHeader2
dd
0h ;COM+ 時間連線庫長度[非關鍵資料]
.Reserved1
dd
0h ;這東東就真的沒聽說過了[非關鍵資料]
.Reserved2
dd
0h ;這東東就真的沒聽說過了[非關鍵資料]
;以上乃~~PE結構頭部資訊~請按照說明進行修改---謝謝我自己
sections:
.SectionName db
".Anskya"
,0
.VirtualSize
dd
CODE_BASE ;虛擬體積
.VirtualAddress
dd
CODE_BASE ;虛擬地址
.SizeOfRawData
dd
code_end-code;資料體積
.PointerToRawData
dd
code ;資料偏移
.PointerToRelocations
dd
0
.PointerToLinenumbers
dd
0
.NumberOfRelocations dw 0
.NumberOfLinenumbers dw 0
.Characteristics
dd
0E0000060h ;段屬性...不用說了吧
align 200h, DB 0 ;對齊0x200
code:
pushad
sub eax,eax
push eax ;0
push 00400105h ;把節名稱壓入堆疊
push 00400002h ;把MZ後面的個人資訊壓入堆疊
push eax ;MB_OK
call [MessageBoxA] ;呼叫匯入表地址
popad
ret
align 16, DB 0
;以下匯入表部分....僅僅為了演示就沒有寫匯出表部分...具體參見<<軟體加密技術內幕>>
import
dd
0
dd
0
dd
-1
dd
dll001+RVADIFF
dd
api001+RVADIFF
times
5
dd
0 ;空處4*5個00的空位
dll001 db
'USER32.DLL'
,0 ;匯入DLL名稱
api001
dd
api101+RVADIFF ;計算匯入表的記憶體地址
dd
0
api101 dw 0
db
'MessageBoxA'
,0 ;匯入函式
MessageBoxA equ api001+reloc+4*0 ;函式地址宣告...如有多餘的函式請api00N+reloc+4*N
code_end:
|
相關程式碼見附件...
https://bbs.pediy.com/thread-28316.htm