Billy Belceb 病毒編寫教程for Win32 ----PE檔案頭

看雪資料發表於2015-11-15

標 題: Billy Belceb 病毒編寫教程for Win32 ----PE檔案頭

發信人:onlyu 

時 間:2004-05-28,12:32

詳細資訊: 



【PE檔案頭】
 ~~~~~~~~~~
    這是這篇檔案的最重要的一章。仔細讀!

%介紹%
~~~~~~
    對PE頭的結構很清晰在寫我們的Windows病毒很重要。下面我將給出我認為重要的東西,但是並不是關於PE檔案的所有的資訊,想要知道更多的東西,看看我在上面關於PE檔案推薦的資料,在"有用的東西..."這一章。
 _______________________________
|                               |<-----OFFSET=00000000h
|          DOS stub             |
|_______________________________|
|                               |<-----OFFSET=[DOS Stub+3Ch]
|          PE stuff             |
|_______________________________|

    讓我們對這兩大部分進行深入的分析,讓我們看看Micheal J. O'Leary的示意圖:

 __________________________________
|                                  |<----Base of Image Header
|    DOS compatible EXE header     |--|
|__________________________________|  |
|                                  |  |
|             Unused               |  |
|__________________________________|  |
|                                  |  |
|         OEM identifier           |  |
|__________________________________|  |
|                                  |  |
|            OEM info              |  |-->Uninteresting(DOS Compatibility)
|__________________________________|  |
|                                  |  |
|        Offset to PE Header       |----->Very interesting
|__________________________________|  |
|                                  |  |
| DOS Stub program and reloc table |  |
|__________________________________|  |
|                                  |  |
|              Unused              |__|
|__________________________________|
|                                  |
|   PE header(IMAGE_FILE_HEADER)   |--|
|__________________________________|  |
|                                  |  |
| PE header(IMAGE_OPTIONAL_HEADER) |  |
|__________________________________|  |-->Very very interesting :)
|                                  |  |
|          Section Table           |  |
|__________________________________|  |
|                                  |  |
|            Sections              |__|
|__________________________________|

    現在你已經對PE檔案頭已經有了一個大體的瞭解,確實很新奇(但也很複雜),我們的新目標。Ok,ok,你對那些東西有了一個"大體"的瞭解,但是,你仍然需要知道PE檔案頭中IMAGE_FILE_HEADER本身的內部結構。勒緊你的褲腰帶!

IMAGE_FILE_HEADER
^^^^^^^^^^^^^^^^^
 ________________________________
|            "PE\0\0"            |<----+00000000h
|________________________________|       Size:1 DWORD
|            Machine             |<----+00000004h
|________________________________|       Size:1 WORD
|       Number Of Section        |<----+00000006h
|________________________________|       Size:1 WORD
|        Time Date Stamp         |<----+00000008h
|________________________________|       Size:1 DWORD
|    pointer To Symbol Table     |<----+0000000Ch
|________________________________|       Size:1 DWORD
|       Number Of Symbols        |<----+00000010h
|________________________________|       Size:1 DWORD
|    Size Of Optional Header     |<----+000000014h
|________________________________|       Size:1 WORD
|        Characteristics         |<----+000000016h
|________________________________|       Size:1 WORD
                                  Total Size:18h BYTES
    我將繼續對IMAGE_FILE_HEADER的各個域給出簡要的描述。

    PE\0\0:

    它是每個PE檔案都有的標誌,只要在編寫你的感染程式的時候檢查它是否存在。如果它在那兒,它就不是一個PE檔案,ok?

    Machine:

    因為我們所使用的計算機的理想可以是一個非PC相容的(NT對這些東西有一個開放等級,你知道的),又因為PE檔案是普遍的,在這個域中是這個應用程式所編寫的程式碼的機器型別,可以為下面的值:

 IMAGE_FILE_MACHINE_I386    equ  14Ch    ; Intel 386.
 IMAGE_FILE_MACHINE_R3000   equ  162h    ; MIPS little-endian,160h big-endian
 IMAGE_FILE_MACHINE_R4000   equ  166h    ; MIPS little-endian
 IMAGE_FILE_MACHINE_R10000  equ  168h    ; MIPS little-endian
 IMAGE_FILE_MACHINE_ALPHA   equ  184h    ; Alpha_AXP
 IMAGE_FILE_MACHINE_POWERPC equ  1F0h    ; IBM PowerPC Little-Endian

    Number Of Sections:

    我們的感染程式的非常重要的域,它告訴我們這個檔案的節(section)的個數。

    Time Date Stamp:

    儲存了從1969.10.31 4:00到檔案連結時所過的秒數。

    Pointer To Symbol Table:

    沒意思,因為它僅僅被OBJ檔案使用。

    Number Of Symbols:

    沒意思,因為它僅僅被OBJ檔案使用。

    Size Of Optional header:

    儲存了IMAGE_OPTIONAL_HEADER域的位元組數(看下面IMAGE_OPTIONAL_HEADER的描述)。

    Characteristics:

    這些標誌給了我們關於這個檔案的更多資訊,對於我們所有人都沒意思。

IMAGE_OPTIONAL_HEADER
^^^^^^^^^^^^^^^^^^^^^
 ________________________________
|             Magic              |<----+00000018h
|________________________________|        Size:1 WORD
|      Major Linker Version      |<----+0000001Ah
|________________________________|        Size:1 BYTE
|      Minor Linker Version      |<----+0000001Bh
|________________________________|        Size:1 BYTE
|          Size Of Code          |<----+0000001Ch
|________________________________|        Size:1 DWORD
|    Size Of Initialized Data    |<----+00000020h
|________________________________|        Size:1 DWORD
|   Size of UnInitialized Data   |<----+00000024h
|________________________________|        Size:1 DWORD
|     Address Of Entry Point     |<----+00000028h
|________________________________|        Size:1 DWORD
|         Base Of Code           |<----+0000002Ch
|________________________________|        Size:1 DWORD
|         Base Of Data           |<----+00000030h
|________________________________|        Size:1 DWORD
|          Image Base            |<----+00000034h
|________________________________|        Size:1 DWORD
|      Section ALignment         |<----+00000038h
|________________________________|        Size:1 DWORD
|        File Alignment          |<----+0000003Ch
|________________________________|        Size:1 DWORD
| Major Operating System Version |<----+00000040h
|________________________________|        Size:1 WORD
| Minor Operating System Version |<----+00000042h
|________________________________|        Size:1 WORD
|      Major Image Version       |<----+00000044h
|________________________________|        Size:1 WORD
|      Minor Image Version       |<----+00000046h
|________________________________|        Size:1 WORD
|    Major Subsystem Version     |<----+00000048h
|________________________________|        Size:1 WORD
|    Minor Subsystem Version     |<----+0000004Ah
|________________________________|        Size:1 WORD
|           Reserved1            |<----+0000004Ch
|________________________________|        Size:1 DWORD
|        Size Of Headers         |<----+00000050h
|________________________________|        Size:1 DWORD
|            CheckSum            |<----+00000054h
|________________________________|        Size:1 DWORD
|            SubSystem           |<----+00000058h
|________________________________|        Size:1 DWORD
|       Dll Characteristics      |<----+0000005Eh
|________________________________|        Size:1 WORD
|      Size Of Stack Reserve     |<----+00000060h
|________________________________|        Size:1 DWORD
|      Size Of Stack Commit      |<----+00000064h
|________________________________|        Size:1 DWORD
|      Size OF Heap Reserve      |<----+00000068h
|________________________________|        Size:1 DWORD
|      Size Of Heap Commit       |<----+0000006Ch
|________________________________|        Size:1 DWORD
|          Loader Flags          |<----+00000070h
|________________________________|        Size:1 DWORD
|    Number Of Rva And Sizes     |<----+00000074h
|________________________________|        Size:1 DWORD
                                  Total Size:78h BYTES
                      (加上IMAGE_FILE_HEADER ^^^^^^^^^)

   Magic:

   看起來總為010Bh,實際上會使我們認為它是一種簽名,沒有意思。

   Major Linker Version and Minor Linker Version:

   產生這個檔案的連結器的版本,沒有意思。

   Size of Code:

   它是所有包含可執行程式碼的段的總位元組數。

   Size of Initialized Data:

   它是所有包含初始資料的段的總大小。

   Size of Uninitialized data

   未初始資料不佔磁碟空間,但是當系統裝載這個檔案的時候,它會分配一些記憶體(實際上是虛擬記憶體)。

   Address of EntryPoint:

   是裝載器開始執行程式碼的地方。它是一個RVA,當系統裝載這個檔案的時候和image base相關。非常有意思。

   Base Of Code:

   是檔案的code段開始的RVA。code段在記憶體中通常在data段之前,在PE檔案頭之後。這個RVA在用Microsoft連結器產生的EXE檔案中通常為0x1000。Borland的TLINK32看起來把image base加到了第一個code段的RVA處,並把結果儲存在這個域中。

   Base Of Data:

   是檔案的data段開始的RVA,data段通常在記憶體中處於最後,在PE檔案頭和code段之後。

   Image Base(基址):

   當連結器創造一個可執行檔案的時候,它會假定將會記憶體對映到記憶體的某個地址當中。這個地址被儲存在這個域中,假定的一個裝載地址來允許連結器進行最佳化。如果這個檔案確實被裝載器記憶體對映到那個地址,在它可以執行之前程式碼就不需要任何補丁了。在為Windows NT產生的可執行檔案中,預設的Image Base為0x10000。對DLL來說,預設的為0x400000。在Win9X中,地址0x10000不能被用來裝載EXE檔案因為它在被所有程式的共享地址中。因為這個,Microsoft就把Win32的預設Image Base改為0x400000。老的以基址0x10000進行連結而成的可執行檔案在Win9x下裝載將會花費更長的時間,因為裝載器需要進行基址重定位。

   Section Alignment:

   當對映到記憶體中的時候,每一節要保證是這個值的一個倍數的虛擬地址作為開始地址。對於按頁的時候,預設的節對齊方式是0x1000。

   File Alingnment:

   在PE檔案中,構成每一節的原始資料要保證從這個值的倍數開始。預設的值為0x200位元組,可能是為了保證各節總是以磁碟節(disk sector,它的長度也為0x200)的開始作為開始。這個域在NE檔案中等價於segment/resource alignment。和NE檔案不同的是,PE檔案通常不會有成百個節,所以由於對齊檔案的節而浪費的空間幾乎很少。

   Major Operating System Version and Minor Operating System Version:

   使用這種型別的可執行檔案的作業系統的最低版本號。既然subsystem fields目的看起來和它相類似,這個域有點摸稜兩可。這個域在所有的Win32 EXE檔案中預設為1.0。

   Major Image Version and Minor Image Version:
 
   是一個使用者可定義的域,它允許你可以有不同版本的EXE或DLL。你可以透過連結器的/VERSION開關來設定這個域。如:"LINK /VERSION:2.0 muobj.obj"。

   Major Subsystem Version and Minor Subsystem Version:

   包含了執行這個可執行檔案所需要的最小子系統版本。這個域的一個經典值為3.10(意思為Windows NT 3.1)。

   Reserved1:

   看起來總為0(最為感染標誌太完美了)。

   Size Of Headers:

   PE檔案頭的大小和節(物件)表。這些節的原始資料就從這些所有檔案頭元件之後開始。

   Checksum:

   為這個檔案的CRC校驗值。正如在其它的Microsoft可執行檔案格式中,這個域是忽略的並總設為0,這個規則的例外是這些EXE檔案必須有合法的校驗值。

   SubSystem:

   這些可執行檔案的子系統的型別被它用來使用者介面。WINNT.h定義了下面的值:

 NATIVE         1       Doesn't require a subsystem (such as a device driver)
 WINDOWS_GUI    2       Runs in the Windows GUI subsystem
 WINDOWS_CUI    3       Runs in the Windows character subsystem (console app)
 OS2_CUI        5       Runs in the OS/2 character subsystem (OS/2 1.x  only)
 POSIX_CUI      7       Runs in the Posix character subsystem

     一個標誌集表明了在什麼環境下一個DLL的初始函式(如DLLMain)將會呼叫。這個值看起來總是設定為0,然而作業系統仍然對所有四個事件呼叫DLL初始函式。下面是定義的值:

1     當DLL第一次裝載到一個程式的地址空間中時呼叫
2     當一個執行緒終止時呼叫
3     當一個執行緒開始時呼叫
4     當DLL已經存在時呼叫

   Size Of Stack Reserve: 

   為初始執行緒的堆疊而保留的虛擬記憶體數量,然而並不是所有的記憶體都可以做(看下一個域)。這個域的預設值為0x100000(1MB)。如果你用CreateThread把0作為堆疊的大小,那麼建立出來的堆疊就會有相同的大小。

   Size Of Stack Commit:

   保證初始執行緒的堆疊時的記憶體數量。對於Microsoft的連結器這個域的初始值為0x1000位元組(1頁)而TLINK32為2頁。

   Size Of Heap Reserve:

   用來保留給初始程式堆時的虛擬記憶體,這個堆的控制程式碼可以透過呼叫GetProcessHeap函式來獲得。並不能保證所有記憶體(看下一個域)。

   Size Of Heap Commit:

   在程式堆中初始時的記憶體數量。預設值為1頁。
 
   Loader Flags:

   從WINNT.h來看,這個域和除錯支援相關。我還沒有看到任何一個這些位都有效的可執行檔案,也沒有看到這些位都清空的。怎麼用連結器設定它們呢,下面是定義的值:
1   在開始程式前喚醒一個斷點指令
2  當程式已經載入後喚醒一個偵錯程式

   Number Of Rva and Sizes:

   DataDirectory 陣列(下面)的入口個數,這個值用當前的工具總是設定為16。

IMAGE_SECTION_HEADER
^^^^^^^^^^^^^^^^^^^^
 _____________________________
|       Section Name          |<-----Begin of section header
|_____________________________|        Size:8 BYTES
|       Virtual Size          |<-----+00000008h
|_____________________________|        Size:1 DWORD
|      Virtual Address        |<-----+0000000Ch
|_____________________________|        Size:1 DWORD
|      Size Of Raw Data       |<-----+00000010h
|_____________________________|        Size:1 DWORD
|    Pointer To Raw Data      |<-----+00000014h
|_____________________________|        Size:1 DWORD
|   Pointer To Relocations    |<-----+00000018h
|_____________________________|        Size:1 DWORD
|   Pointer To Line Numbers   |<-----+0000001Ch
|_____________________________|        Size:1 DWORD
|    Number Of Relocations    |<-----+00000020h
|_____________________________|        Size:1 WORD
|   Number Of Line Numbers    |<-----+00000022h
|_____________________________|        Size:1 WORD
|      Characteristics        |<-----+00000024h
|_____________________________|        Size:1 DWORD
                                Total Size: 28h BYTES

Section Name:

    命名節用的是一個8-byte的ANSI名字(非UNICODE),大多數的節的名字以一個.(如".text")作為開始,但是這不是必須的,你可以在一些關於PE的文章裡驗證這一點。你可以直接用匯編語言來命名你的節,或者在Microsoft C/C++編譯器下用"#pragma data_seg"和"pragma code_seg"。注意節名是否佔了滿滿8個位元組很重要,沒有NULL終止符。如果你是一個printf的熱愛者,你可以使用%.8s來避免把名字字串複製到另外一個你可以用NULL來終止的緩衝區裡面。

Virtual Size:

    這個域在EXE或者OBJ中有不同的意思。在一個EXE中,它儲存程式碼或者資料的實際大小。這個大小是在把檔案湊整到檔案對齊大小的倍數之前的大小。後面的SizeOfRawData域(看起來有點用詞不當)儲存的是湊整之後的值。Borland的聯結器把這兩個域的意思顛倒過來了,看起來是正確的。對於OBJ檔案,這個域表示節的實體地址。第一個節是從地址0開始的。為了尋找在一個OBJ檔案中的下一個節的實體地址,把當前節的實體地址加上SizeOfRawData值就可以了。

Virtual Address:
 
   在EXE中,這個域指裝載器應該對節進行對映的RVA。為了計算一個給定的節在記憶體中的真正起始地址,把映象的基址加上儲存在這個域中的VirtualAddress就可以了。利用Microsoft的工具,第一個節的預設的RVA為0x1000。在OBJ檔案中,這個域是沒有意義的並設定成0。

Size Of Raw Data:

     在EXE中,這個域包含了節在按檔案對齊大小湊整之後的大小。例如,假設一個檔案的對齊大小為0x200,如果上述的VirtualSize域的節的長度為0x35A,這個域就會以0x400作為節長。在OBJ檔案中,這個域包含了由編譯器或彙編程式所設定的精確大小。也就是說,對於OBJ檔案來說,它等於EXE中的VirtualSize域的值。

Pointer To Raw Data:

    這是節基於檔案的偏移量,原始資料是由編譯器或彙編器設定的。如果你的程式記憶體對映了一個PE檔案或者COFF檔案本身(而不是由作業系統來裝載它),這個域比VirtualAddress域重要。在這種情況下,你將會擁有完全的線形檔案對映,所以你將會發現在這個偏移地址出的節的資料,而不是在VirtualAddress處的特定RVA。

Pointer To Relocations

    在OBJ檔案中這個是節基於檔案的偏移量的重定位資訊,對於每一個節的重定位資訊直接跟在那個節的原始資料後面。在EXE檔案中這個域(和子域)是沒有意義的並設定成0。當聯結器產生EXE檔案的時候,它解決了大多數的修正問題,只剩基址重定位和輸入函式。關於基址重定位和輸入函式的資訊是儲存在它們自己的節中,所以沒有必要使一個EXE檔案的每一個節的重定位資料在原始節資料後面。

Pointer To Line Numbers:

      這是基於檔案的行號表的偏移量,一個行號表使原始檔的行號和一個給定的行所產生的程式碼地址相關聯。在現代的除錯格式如CodeView格式中,行號資訊是作為除錯資訊的一部分儲存的。在COFF除錯格式中,然而,行號資訊是和符號名/符號型別分開儲存的。通常,只有code節(如.text)有行號。在EXE檔案中,行號是在節的raw data(原始資料)之後向檔案尾累加的。在OBJ檔案中,一個節的行號表是在原始節資料和這個節的重定位表之後開始的。

Number Of Relocations:

    在節的行號表中的行號的數值(上面的PointerToLinenumbers域)。

Characteristics:

    大多數程式設計師叫做標誌(flag),在COFF/PE格式中叫做特徵(characterstic)。這個域是一些表面節屬性(如程式碼/資料,可讀,或可寫)的標誌。要看所有可能的節屬性的列表,看看定義在WINNT.H中的IMAGE_SCN_XXX_XXX。下面給出一些比較重要的標誌:

0x00000020 這個節包含程式碼。通常和可執行標誌(0x80000000)聯合設定。

0x00000040 這個節包含了初始化了的資料(initialized data)。除了可執行和.bss節之外幾乎所有的節都有這個標誌。

0x00000080 這個節包含了未初始化的資料(uninitialized data),如.bss節。

0x00000200 這個節包含了一些註釋或者一些其它型別的資訊。這個節的一個典型利用是由編譯器所設定的.drectve節,這個節包含了聯結器的命令。

0x00000800 這個節的內容是不應該放在最終的EXE檔案中的。這些節被編譯器/彙編器用來傳遞資訊給聯結器。

0x02000000 在它被裝載之後,程式就不再需要它了,這個節就可以被丟棄。最普通的可丟棄的節是基址重定位節(.reloc)。

0x10000000 這個節是可共享的。當使用一個DLL時,這個節中的資料將會透過DLL來給所有的程式共享。資料節的預設是不共享的。用更專業的術語,一個共享節告訴記憶體管理器設定這個節的頁對映使得所有使用這個DLL的程式指向記憶體中的同一個物理頁。要使一個節可共享的,在連線的時候使用共享(SHARED)屬性。如:

LINK /SECTION:MYDATA,RWS...

就告訴了聯結器一個叫做MYDA他的節是可讀的,可寫的,而且是共享的。

0x20000000 這個節是可執行的。這個標誌通常在"包含程式碼"的標誌(0x00000020)被設定後設定。

0x40000000 這個節是可讀的。這個標誌幾乎在EXE檔案的所有節中都被設定。

0x80000000 這個節是可寫的。如果這個標誌在一個EXE檔案的節中沒有被設定,裝載器就會標誌記憶體對映頁為只讀的或只能執行的。有這個屬性的典型的節是.data和.bss。有趣的是,.idata節也設定了這個屬性。

%要改變的東西%
~~~~~~~~~~~~~~
    下面,我將介紹在編寫一個普通的PE病毒時的一些改變。假設你要編寫一個會增加PE檔案的最後一個節內容的病毒,這個在我們看來更容易成功的技術,然而新增一個節更容易。讓我們看看一個病毒是怎麼來改變一個可執行檔案的頭。我使用了Lord Julus[SLAM]的INFO-PE程式。

 -------- DOS INFORMATION ---------------------------------------------------

 Analyzed File: GOAT002.EXE

 DOS Reports: 
              ?File Size  - 2000H      (08192d)
              ?File Time  - 17:19:46   (hh:mm:ss)
              ?File Date  - 11/06/1999 (dd/mm/yy)
              ?Attributes : Archive 

 [...]

 -------- PE Header ----------------------------------------------------------
 
  ---------------
 ‖O_DOS |O_PE  ‖(Offset from Dos Header / PE Header
 ‖------|------‖
 |0100H  |0000H | PE Header Signature - PE/0/0
 |0104H  |0004H | The machine for this EXE is Intel 386 (value = 014CH)
 |0106H  |0006H | Number of sections in the file - 0004H
 |0108H  |0008H | File was linked at : 23/03/2049
 |010CH  |000CH | Pointer to Symbol Table : 00000000H
 |0110H  |0010H | Number of Symbols : 00000000H
 |0114H  |0014H | Size of the Optional Header : 00E0H
 |       |      |
 |0116H  |0016H | File Characteristics - 818EH : 
 |       |      | ?File is executable
 |       |      | ?Line numbers stripped from file
 |       |      | ?Local symbols stripped from file
 |       |      | ?Bytes of machine word are reversed
 |       |      | ?32 bit word machine
 |       |      | ?Bytes of machine word are reversed
 ‖_______|_____‖
 
 
-------- PE Optional Header -----------------------------------
 
  ---------------
 ‖O_DOS |O_PE  ‖(Offset from Dos Header / PE Header
 ‖------|------‖
 |0118H  |0018H | Magic Value                : 010BH (`Θ`)
 |011AH  |001AH | Major Linker Version       : 2
 |011BH  |001BH | Minor Linker Version       : 25
 |       |      | Linker Version             : 2.25
 |011CH  |001CH | Size of Code               : 00001200H
 |0120H  |0020H | Size of Initialized Data   : 00000600H
 |0124H  |0024H | Size of Uninitialized Data : 00000000H
 |0128H  |0028H | Address of Entry Point     : 00001000H
 |012CH  |002CH | Base of Code (.text ofs.)  : 00001000H
 |0130H  |0030H | Base of Data (.bss ofs.)   : 00003000H
 |0134H  |0034H | Image Base                 : 00400000H
 |0138H  |0038H | Section Alignment          : 00001000H
 |013CH  |003CH | File Alignment             : 00000200H
 |0140H  |0040H | Major Operating System Version : 1
 |0142H  |0042H | Minor Operating System Version : 0
 |0144H  |0044H | Major Image Version        : 0
 |0146H  |0046H | Minor Image Version        : 0
 |0148H  |0048H | Major SubSystem Version    : 3
 |014AH  |004AH | Minor SubSystem Version    : 10
 |014CH  |004CH | Reserved Long              : 00000000H
 |0150H  |0050H | Size of Image              : 00006000H
 |0154H  |0054H | Size of Headers            : 00000400H
 |0158H  |0058H | File Checksum              : 00000000H
 |015CH  |005CH | SubSystem                  : 2
 |       |      |  Image runs in the Windows GUI subsystem
 |015EH  |005EH | DLL Characteristics        : 0000H
 |0160H  |0060H | Size of Stack Reserve      : 00100000H
 |0164H  |0064H | Size of Stack Commit       : 00002000H
 |0168H  |0068H | Size of Heap Reserve       : 00100000H
 |016CH  |006CH | Size of Heap Commit        : 00001000H
 |0170H  |0070H | Loader Flags               : 00000000H
 |0174H  |0074H | Number Directories         : 00000010H
 
 [...]
 
------- PE Section Headers ---------------------------------

  ---------------------------
 ‖O_DOS |O_PE  ‖(Offset from Dos Header / PE Header
 ‖------|------‖[...]
 |0270H  |0170H | Section name            : .reloc
 |0278H  |0178H | Physical Address        : 00001000H
 |027CH  |017CH | Virtual Address         : 00005000H
 |0280H  |0180H | Size of RAW data        : 00000200H
 |0284H  |0184H | Pointer to RAW data     : 00001C00H
 |0288H  |0188H | Pointer to relocations  : 00000000H
 |028CH  |018CH | Pointer to line numbers : 00000000H
 |0290H  |0190H | Number of Relocations   : 0000H
 |0292H  |0192H | Number of line numbers  : 0000H
 |0294H  |0194H | Characteristics         : 50000040H
 |       |      | ?Section contains initialized data.
 |       |      | ?Section is shareable.
 |       |      | ?Section is readable.
 |       |      |
 ‖______|______‖
 
    這是一個正常檔案,沒有被感染。下面是同一個檔案,但是被我的Aztec病毒(一個Ring-3病毒例子,看下面的)感染了。

------------ DOS INFORMATION ----------------------------------------------------------------- 

 Analyzed File: GOAT002.EXE

 DOS Reports: 
             ?File Size  - 2600H      (09728d)
             ?File Time  - 23:20:58   (hh:mm:ss)
             ?File Date  - 22/06/1999 (dd/mm/yy)
             ?Attributes : Archive 

 [...]

 -------------- PE Header -----------------------------------------------------------------

 --------------- 
‖O_DOS |O_PE  ‖(Offset from Dos Header / PE Header
‖------|------‖[...]
 |0100H |0000H  | PE Header Signature - PE/0/0
 |0104H |0004H  | The machine for this EXE is Intel 386 (value = 014CH)
 |0106H |0006H  | Number of sections in the file - 0004H
 |0108H |0008H  | File was linked at : 23/03/2049
 |010CH |000CH  | Pointer to Symbol Table : 00000000H
 |0110H |0010H  | Number of Symbols : 00000000H
 |0114H |0014H  | Size of the Optional Header : 00E0H
 |      |       |
 |0116H |0016H  | File Characteristics - 818EH : 
 |      |       | ?File is executable
 |      |       | ?Line numbers stripped from file
 |      |       | ?Local symbols stripped from file
 |      |       | ?Bytes of machine word are reversed
 |      |       | ?32 bit word machine
 |      |       | ?Bytes of machine word are reversed
 ‖_____|_______‖


 --------- PE Optional Header ------------------------------------------------------

 ---------------
‖O_DOS |O_PE  ‖(Offset from Dos Header / PE Header
‖------|------‖
 |0118H |0018H | Magic Value                : 010BH
 |      |      |
 |011AH |001AH | Major Linker Version       : 2
 |011BH |001BH | Minor Linker Version       : 25
 |      |      | Linker Version             : 2.25
 |011CH |001CH | Size of Code               : 00001200H
 |0120H |0020H | Size of Initialized Data   : 00000600H
 |0124H |0024H | Size of Uninitialized Data : 00000000H
 |0128H |0028H | Address of Entry Point     : 00005200H
 |012CH |002CH | Base of Code (.text ofs.)  : 00001000H
 |0130H |0030H | Base of Data (.bss ofs.)   : 00003000H
 |0134H |0034H | Image Base                 : 00400000H
 |0138H |0038H | Section Alignment          : 00001000H
 |013CH |003CH | File Alignment             : 00000200H
 |0140H |0040H | Major Operating System Version : 1
 |0142H |0042H | Minor Operating System Version : 0
 |0144H |0044H | Major Image Version        : 0
 |0146H |0046H | Minor Image Version        : 0
 |0148H |0048H | Major SubSystem Version    : 3
 |014AH |004AH | Minor SubSystem Version    : 10
 |014CH |004CH | Reserved Long              : 43545A41H
 |0150H |0050H | Size of Image              : 00006600H
 |0154H |0054H | Size of Headers            : 00000400H
 |0158H |0058H | File Checksum              : 00000000H
 |015CH |005CH | SubSystem                  : 2
 |      |      |     -Image runs in the Windows GUI subsystem
 |15EH  |005E  | DLL Characteristics        : 0000H
 |160H  |0060H | Size of Stack Reserve      : 00100000H
 |0164H |0064H | Size of Stack Commit       : 00002000H
 |0168H |0068H | Size of Heap Reserve       : 00100000H
 |016CH |006CH | Size of Heap Commit        : 00001000H
 |0170H |0070H | Loader Flags               : 00000000H
 |0174H |0074H | Number Directories         : 00000010H
 ‖___________‖
 
 [...]

 ---------PE Section Headers------------------------------------------

 ----------------
 ‖O_DOS |O_PE  ‖(Offset from Dos Header / PE Header
 ‖------|------‖[...] 
 |0270H  |0170H | Section name            : .reloc
 |0278H  |0178H | Physical Address        : 00001600H
 |027CH  |017CH | Virtual Address         : 00005000H
 |0280H  |0180H | Size of RAW data        : 00001600H
 |0284H  |0184H | Pointer to RAW data     : 00001C00H
 |0288H  |0188H | Pointer to relocations  : 00000000H
 |028CH  |018CH | Pointer to line numbers : 00000000H
 |0290H  |0190H | Number of Relocations   : 0000H
 |0292H  |0192H | Number of line numbers  : 0000H
 |0294H  |0194H | Characteristics         : F0000060H
 |       |      |  -Section contains code.
 |       |      | -Section contains initialized data.
 |       |      | -Section is shareable.
 |       |      | -Section is executable.
 |       |      | -Section is readable.
 |       |      | -Section is writeable.
 |       |      |
 |_______|______|

    那一個正常的檔案,沒有被感染。下面給出的是同一個檔案,但是被我的Aztec(Ring-3例子病毒,看下文)感染了。


 ---------------------------------------------------------------------------------------------------

-------DOS INFORMATION ------------------------------------------------- 

 Analyzed File: GOAT002.EXE

 DOS Reports: 
             ?File Size  - 2600H      (09728d)
             ?File Time  - 23:20:58   (hh:mm:ss)
             ?File Date  - 22/06/1999 (dd/mm/yy)
             ?Attributes : Archive 

 [...]

 -------PE Header-------------------------------------------------------

 ----------------
‖O_DOS |O_PE   ‖(Offset from Dos Header / PE Header
‖------|-------‖
 |0100H |0000H  | PE Header Signature - PE/0/0
 |0104H |0004H  | The machine for this EXE is Intel 386 (value = 014CH)
 |0106H |0006H  | Number of sections in the file - 0004H
 |0108H |0008H  | File was linked at : 23/03/2049
 |010CH |000CH  | Pointer to Symbol Table : 00000000H
 |0110H |0010H  | Number of Symbols : 00000000H
 |0114H |0014H  | Size of the Optional Header : 00E0H
 |      |       | 
 |0116H |0016H  | File Characteristics - 818EH : 
 |      |       | -File is executable
 |      |       | -Line numbers stripped from file
 |      |       | -Local symbols stripped from file
 |      |       | -Bytes of machine word are reversed
 |      |       | -32 bit word machine
 |      |       | -Bytes of machine word are reversed
 |______|_______|


 ---------PE Optional Header---------------------------------------

 -----------------
‖O_DOS  |O_PE   ‖(Offset from Dos Header / PE Header
‖-------|-------‖
 |0118H  |0018H  | Magic Value                : 010BH 
 |011AH  |001AH  | Major Linker Version       : 2
 |011BH  |001BH  | Minor Linker Version       : 25
 |       |       | Linker Version             : 2.25
 |011CH  |001CH  | Size of Code               : 00001200H
 |0120H  |0020H  | Size of Initialized Data   : 00000600H
 |0124H  |0024H  | Size of Uninitialized Data : 00000000H
 |0128H  |0028H  | Address of Entry Point     : 00005200H
 |012CH  |002CH  | Base of Code (.text ofs.)  : 00001000H
 |0130H  |0030H  | Base of Data (.bss ofs.)   : 00003000H
 |0134H  |0034H  | Image Base                 : 00400000H
 |0138H  |0038H  | Section Alignment          : 00001000H
 |013CH  |003CH  | File Alignment             : 00000200H
 |0140H  |0040H  | Major Operating System Version : 1
 |0142H  |0042H  | Minor Operating System Version : 0
 |0144H  |0044H  | Major Image Version        : 0
 |0146H  |0046H  | Minor Image Version        : 0
 |0148H  |0048H  | Major SubSystem Version    : 3
 |014AH  |004AH  | Minor SubSystem Version    : 10
 |014CH  |004CH  | Reserved Long              : 43545A41H
 |0150H  |0050H  | Size of Image              : 00006600H
 |0154H  |0054H  | Size of Headers            : 00000400H
 |0158H  |0058H  | File Checksum              : 00000000H
 |015CH  |005CH  | SubSystem                  : 2
 |       |       |     -Image runs in the Windows GUI subsystem
 |015EH  |005EH  | DLL Characteristics        : 0000H
 |0160H  |0060H  | Size of Stack Reserve      : 00100000H
 |0164H  |0064H  | Size of Stack Commit       : 00002000H
 |0168H  |0068H  | Size of Heap Reserve       : 00100000H
 |016CH  |006CH  | Size of Heap Commit        : 00001000H
 |0170H  |0070H  | Loader Flags               : 00000000H
 |0174H  |0074H  | Number Directories         : 00000010H
 |_______|_______|
 
 [...]

 ----------PE Section Headers---------------------------------------

 -----------------
‖O_DOS  | O_PE  ‖(Offset from Dos Header / PE Header
‖-------|-------‖[...] 
 |0270H  | 0170H | Section name            : .reloc
 |0278H  | 0178H | Physical Address        : 00001600H
 |027CH  | 017CH | Virtual Address         : 00005000H
 |0280H  | 0180H | Size of RAW data        : 00001600H
 |0284H  | 0184H | Pointer to RAW data     : 00001C00H
 |0288H  | 0188H | Pointer to relocations  : 00000000H
 |028CH  | 018CH | Pointer to line numbers : 00000000H
 |0290H  | 0190H | Number of Relocations   : 0000H
 |0292H  | 0192H | Number of line numbers  : 0000H
 |0294H  | 0194H | Characteristics         : F0000060H
 |       |       | -Section contains code.
 |       |       | -Section contains initialized data.
 |       |       | -Section is shareable.
 |       |       | -Section is executable.
 |       |       | -Section is readable.
 |       |       | -Section is writeable.
 |       |       |
 |_______|_______|
 --------------------------------------------------------------------------------

     好了,我希望這已經幫助你更理解在透過增加它的最後一節來感染PE檔案的時候,做了些什麼。為了避免你在比較這些每一個表時花更多的精力,我給出了一個列表:


  ==============================================================
  |  Values to change     |Before    |After     |Location      |
  ==============================================================
  |Address Of Entrypoint |00001000h |00005200h |Image File Hdr |
  --------------------------------------------------------------
  |Reserved1 (inf. mark) |00000000h |43545A41h |Image File Hdr |
  --------------------------------------------------------------
  |Virtual Size          |00001000h |00001600h |Section header |
  --------------------------------------------------------------
  |Size Of Raw Data      |00000200h |00001600h |Section header |
  --------------------------------------------------------------
  |Characteristics       |50000040h |F0000060h |Section header |
  --------------------------------------------------------------

    實現這個的程式碼非常簡單。對於那些沒有看到程式碼還沒有理解的人,可以看看Win32.Aztec,在下一章將詳細描述。

相關文章