代碼可以直接編譯..
編譯參數:nasmw -fbin MsgBoxA.asm -o MsgBoxA.exe
請下載最新的NASM for Win32編譯器
當前最新版本:NASM 0.98.39
代碼:--------------------------------------------------------------------------------
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Small PE Header Demo For NASM
;Email:Anskya@Gmail.com
;
;代碼說明: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: