Kleine Erklärung dazu: die VirtualSize, ImageSize und RawSize Größen werden von fast allen
Linkern auf bestimmte Werte getrimmt. Heißt - sie sind ein Vielfaches von bestimmten Angaben (gleich mehr dazu). Wenn man die letzte Seciton fixt, muss man sich zwar nicht daran halten, aber dann "fällt" halt die Exe auf, weil sie z.B wie VB-Exe ausschaut, aber "komische" Werte hat.
Zu den Trimmwerten:
das sind SectionAlignment und FileAlignment.
Schau mal bei dir die Definition des IMAGE_OPTIONAL_HEADERS an:
Code:
Private Type IMAGE_OPTIONAL_HEADER
..
ImageBase As Long
SectionAlignment As Long
FileAlignment As Long
Zitat aus MS Doku:
SizeOfImage The size (in bytes) of the image, including all headers, as the image is loaded in memory. It must be a multiple of SectionAlignment.
SectionAlignment The alignment (in bytes) of sections when they are loaded into memory. It must be greater than or equal to FileAlignment. The default is the page size for the architecture.
FileAlignment The alignment factor (in bytes) that is used to align the raw data of sections in the image file. The value should be a power of 2 between 512 and 64 K, inclusive. The default is 512. If the SectionAlignment is less than the architecture’s page size, then FileAlignment must match SectionAlignment.
Das heißt im Klartext soviel:
SectionAlignment ist für alle "Virtual" Werte verantwortlich. Sagen wir mal, es ist meistens = 1000h oder dezimal 4096. Dann sollten alle VirtualSize Angaben ein Vielfaches davon sein oder eben auf das Vielfache aufgerundet werden (auf, nicht ab!).
Vielfaches: heißt einfach "restlos durch die Zahl teilbar"
Bsp: alte VirtualSize+EOFSize=4300
der Wert ist nicht restlos durch 4096 teilbar,
dann musst du halt auf die nächste passende Größe aufrunden: 8196
Oder: EOF+VirtualSize=12030
muss man auf 12288 (hex: 3000) aufrunden.
wie man Aufrundet: angenommen, du hast EOF größe und VirtualSize der letzen Section ermittelt. Nun brauchst du noch den SectionAlignment.
Jetzt kann man mit Modulo erstmal berechnen, wieviel einem bis zum "runden" Wert fehlt:
AktVSize=EOF+VirtualSize
Rest=AktVSize MOD SectionAlignment
D.h Rest ist gleich den "überflüssigen" Bytes, also wieviele Bytes man "drüber" ist.
jetzt berechnet man noch die differenz:
Differenz=SectionAlignment-Rest.
AlignedVSize=AktVSize+Differenz
AlignedSize ist damit die endgültige, aufgerundete Größe.
Bsprechnung:
AktVSize=10000+2030=12030
Rest=12030 MOD 4096=3838
Differenz=4096-3838=258
AlignedVSize=12030+258=12288
So, dasselbe muss man nun auch mit RawSize durchführen, nur dass man hier FileAlignment nimmt:
AktRawSize=EOF+RawSize
Rest=AktRawSize MOD FileAlignment
Differenz=fileAlignment-Rest.
AlignedRawSize=AktRawSize+Differenz
allerdings gibt RawSize ja die Dateigröße an. D.h da man diesen Wert jetzt noch vergörßert, sollte man auch ans Ende der Datei genausoviele Bytes anhängen (da können 00 stehen oder auch Zufallsbytes).
Als letztes machst du noch die Anpassung des SizeOfImage:
ImageSize=ImageSize+Differenz (aus der ersten Rechnung, also Differenz, die für AlginedVSize Rechnung benutzt wurde)
oder:
ImageSize=lastSectionVirtualAdress+AlignedVSize.
So sollte es das machen, was der PEfixer macht.