Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
PEBuilder.cs
Go to the documentation of this file.
5
7
8public abstract class PEBuilder
9{
10 protected readonly struct Section
11 {
12 public readonly string Name;
13
15
17 {
18 if (name == null)
19 {
20 Throw.ArgumentNull("name");
21 }
22 Name = name;
24 }
25 }
26
27 private readonly struct SerializedSection
28 {
29 public readonly BlobBuilder Builder;
30
31 public readonly string Name;
32
34
35 public readonly int RelativeVirtualAddress;
36
37 public readonly int SizeOfRawData;
38
39 public readonly int PointerToRawData;
40
41 public int VirtualSize => Builder.Count;
42
52 }
53
55
57
58 private static readonly byte[] s_dosHeader = new byte[128]
59 {
60 77, 90, 144, 0, 3, 0, 0, 0, 4, 0,
61 0, 0, 255, 255, 0, 0, 184, 0, 0, 0,
62 0, 0, 0, 0, 64, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 128, 0, 0, 0, 14, 31, 186, 14, 0, 180,
67 9, 205, 33, 184, 1, 76, 205, 33, 84, 104,
68 105, 115, 32, 112, 114, 111, 103, 114, 97, 109,
69 32, 99, 97, 110, 110, 111, 116, 32, 98, 101,
70 32, 114, 117, 110, 32, 105, 110, 32, 68, 79,
71 83, 32, 109, 111, 100, 101, 46, 13, 13, 10,
72 36, 0, 0, 0, 0, 0, 0, 0
73 };
74
75 internal static int DosHeaderSize = s_dosHeader.Length;
76
77 public PEHeaderBuilder Header { get; }
78
80
81 public bool IsDeterministic { get; }
82
94
96 {
98 if (value.IsDefault)
99 {
101 }
102 return value;
103 }
104
106
107 protected abstract BlobBuilder SerializeSection(string name, SectionLocation location);
108
109 protected internal abstract PEDirectoriesBuilder GetDirectories();
110
130
150
152 {
153 builder.WriteBytes(s_dosHeader);
154 builder.WriteUInt32(17744u);
155 }
156
158 {
159 builder.WriteUInt16((ushort)((Header.Machine == Machine.Unknown) ? Machine.I386 : Header.Machine));
160 builder.WriteUInt16((ushort)sections.Length);
161 stampFixup = builder.ReserveBytes(4);
162 builder.WriteUInt32(0u);
163 builder.WriteUInt32(0u);
164 builder.WriteUInt16((ushort)PEHeader.Size(Header.Is32Bit));
165 builder.WriteUInt16((ushort)Header.ImageCharacteristics);
166 }
167
169 {
170 builder.WriteUInt16((ushort)(Header.Is32Bit ? 267 : 523));
173 builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsCode));
174 builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsInitializedData));
175 builder.WriteUInt32((uint)SumRawDataSizes(sections, SectionCharacteristics.ContainsUninitializedData));
176 builder.WriteUInt32((uint)directories.AddressOfEntryPoint);
177 int num = IndexOfSection(sections, SectionCharacteristics.ContainsCode);
178 builder.WriteUInt32((num != -1) ? ((uint)sections[num].RelativeVirtualAddress) : 0u);
179 if (Header.Is32Bit)
180 {
181 int num2 = IndexOfSection(sections, SectionCharacteristics.ContainsInitializedData);
182 builder.WriteUInt32((num2 != -1) ? ((uint)sections[num2].RelativeVirtualAddress) : 0u);
183 builder.WriteUInt32((uint)Header.ImageBase);
184 }
185 else
186 {
187 builder.WriteUInt64(Header.ImageBase);
188 }
189 builder.WriteUInt32((uint)Header.SectionAlignment);
190 builder.WriteUInt32((uint)Header.FileAlignment);
193 builder.WriteUInt16(Header.MajorImageVersion);
194 builder.WriteUInt16(Header.MinorImageVersion);
197 builder.WriteUInt32(0u);
198 SerializedSection serializedSection = sections[sections.Length - 1];
199 builder.WriteUInt32((uint)BitArithmetic.Align(serializedSection.RelativeVirtualAddress + serializedSection.VirtualSize, Header.SectionAlignment));
201 _lazyChecksum = builder.ReserveBytes(4);
203 builder.WriteUInt16((ushort)Header.Subsystem);
204 builder.WriteUInt16((ushort)Header.DllCharacteristics);
205 if (Header.Is32Bit)
206 {
207 builder.WriteUInt32((uint)Header.SizeOfStackReserve);
208 builder.WriteUInt32((uint)Header.SizeOfStackCommit);
209 builder.WriteUInt32((uint)Header.SizeOfHeapReserve);
210 builder.WriteUInt32((uint)Header.SizeOfHeapCommit);
211 }
212 else
213 {
214 builder.WriteUInt64(Header.SizeOfStackReserve);
215 builder.WriteUInt64(Header.SizeOfStackCommit);
216 builder.WriteUInt64(Header.SizeOfHeapReserve);
217 builder.WriteUInt64(Header.SizeOfHeapCommit);
218 }
219 builder.WriteUInt32(0u);
220 builder.WriteUInt32(16u);
221 builder.WriteUInt32((uint)directories.ExportTable.RelativeVirtualAddress);
222 builder.WriteUInt32((uint)directories.ExportTable.Size);
223 builder.WriteUInt32((uint)directories.ImportTable.RelativeVirtualAddress);
224 builder.WriteUInt32((uint)directories.ImportTable.Size);
225 builder.WriteUInt32((uint)directories.ResourceTable.RelativeVirtualAddress);
226 builder.WriteUInt32((uint)directories.ResourceTable.Size);
227 builder.WriteUInt32((uint)directories.ExceptionTable.RelativeVirtualAddress);
228 builder.WriteUInt32((uint)directories.ExceptionTable.Size);
229 builder.WriteUInt32(0u);
230 builder.WriteUInt32(0u);
231 builder.WriteUInt32((uint)directories.BaseRelocationTable.RelativeVirtualAddress);
232 builder.WriteUInt32((uint)directories.BaseRelocationTable.Size);
233 builder.WriteUInt32((uint)directories.DebugTable.RelativeVirtualAddress);
234 builder.WriteUInt32((uint)directories.DebugTable.Size);
235 builder.WriteUInt32((uint)directories.CopyrightTable.RelativeVirtualAddress);
236 builder.WriteUInt32((uint)directories.CopyrightTable.Size);
237 builder.WriteUInt32((uint)directories.GlobalPointerTable.RelativeVirtualAddress);
238 builder.WriteUInt32((uint)directories.GlobalPointerTable.Size);
239 builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.RelativeVirtualAddress);
240 builder.WriteUInt32((uint)directories.ThreadLocalStorageTable.Size);
241 builder.WriteUInt32((uint)directories.LoadConfigTable.RelativeVirtualAddress);
242 builder.WriteUInt32((uint)directories.LoadConfigTable.Size);
243 builder.WriteUInt32((uint)directories.BoundImportTable.RelativeVirtualAddress);
244 builder.WriteUInt32((uint)directories.BoundImportTable.Size);
245 builder.WriteUInt32((uint)directories.ImportAddressTable.RelativeVirtualAddress);
246 builder.WriteUInt32((uint)directories.ImportAddressTable.Size);
247 builder.WriteUInt32((uint)directories.DelayImportTable.RelativeVirtualAddress);
248 builder.WriteUInt32((uint)directories.DelayImportTable.Size);
249 builder.WriteUInt32((uint)directories.CorHeaderTable.RelativeVirtualAddress);
250 builder.WriteUInt32((uint)directories.CorHeaderTable.Size);
251 builder.WriteUInt64(0uL);
252 }
253
263
265 {
266 if (serializedSection.VirtualSize == 0)
267 {
268 return;
269 }
270 int i = 0;
271 int length = serializedSection.Name.Length;
272 for (; i < 8; i++)
273 {
274 if (i < length)
275 {
276 builder.WriteByte((byte)serializedSection.Name[i]);
277 }
278 else
279 {
280 builder.WriteByte(0);
281 }
282 }
283 builder.WriteUInt32((uint)serializedSection.VirtualSize);
284 builder.WriteUInt32((uint)serializedSection.RelativeVirtualAddress);
285 builder.WriteUInt32((uint)serializedSection.SizeOfRawData);
286 builder.WriteUInt32((uint)serializedSection.PointerToRawData);
287 builder.WriteUInt32(0u);
288 builder.WriteUInt32(0u);
289 builder.WriteUInt16(0);
290 builder.WriteUInt16(0);
291 builder.WriteUInt32((uint)serializedSection.Characteristics);
292 }
293
295 {
296 for (int i = 0; i < sections.Length; i++)
297 {
299 {
300 return i;
301 }
302 }
303 return -1;
304 }
305
307 {
308 int num = 0;
309 for (int i = 0; i < sections.Length; i++)
310 {
312 {
313 num += sections[i].SizeOfRawData;
314 }
315 }
316 return num;
317 }
318
320 {
323 foreach (Blob blob in peImage.GetBlobs())
324 {
325 int blobStart = blob.Start;
326 int blobLength = blob.Length;
327 while (blobLength > 0)
328 {
329 if (remainingHeader > 0)
330 {
331 int length;
332 if (remainingHeaderToSign > 0)
333 {
335 yield return new Blob(blob.Buffer, blobStart, length);
337 }
338 else
339 {
341 }
343 blobStart += length;
345 continue;
346 }
347 if (blob.Buffer == strongNameSignatureFixup.Buffer)
348 {
351 }
352 else
353 {
354 yield return new Blob(blob.Buffer, blobStart, blobLength);
355 }
356 break;
357 }
358 }
359 }
360
361 internal static Blob GetPrefixBlob(Blob container, Blob blob)
362 {
363 return new Blob(container.Buffer, container.Start, blob.Start - container.Start);
364 }
365
366 internal static Blob GetSuffixBlob(Blob container, Blob blob)
367 {
368 return new Blob(container.Buffer, blob.Start + blob.Length, container.Start + container.Length - blob.Start - blob.Length);
369 }
370
372 {
373 foreach (Blob blob in peImage.GetBlobs())
374 {
375 if (blob.Buffer == checksumFixup.Buffer)
376 {
377 yield return GetPrefixBlob(blob, checksumFixup);
378 yield return GetSuffixBlob(blob, checksumFixup);
379 }
380 else
381 {
382 yield return blob;
383 }
384 }
385 }
386
399
404
405 private unsafe static uint CalculateChecksum(IEnumerable<Blob> blobs)
406 {
407 uint num = 0u;
408 int num2 = -1;
409 foreach (Blob blob in blobs)
410 {
412 fixed (byte* ptr = bytes.Array)
413 {
414 byte* ptr2 = ptr + bytes.Offset;
415 byte* ptr3 = ptr2 + bytes.Count;
416 if (num2 >= 0)
417 {
418 num = AggregateChecksum(num, (ushort)((*ptr2 << 8) | num2));
419 ptr2++;
420 }
421 if ((ptr3 - ptr2) % 2 != 0L)
422 {
423 ptr3--;
424 num2 = *ptr3;
425 }
426 else
427 {
428 num2 = -1;
429 }
430 for (; ptr2 < ptr3; ptr2 += 2)
431 {
432 num = AggregateChecksum(num, (ushort)((ptr2[1] << 8) | *ptr2));
433 }
434 }
435 }
436 if (num2 >= 0)
437 {
438 num = AggregateChecksum(num, (ushort)num2);
439 }
440 return num;
441 }
442
443 private static uint AggregateChecksum(uint checksum, ushort value)
444 {
445 uint num = checksum + value;
446 return (num >> 16) + (ushort)num;
447 }
448}
void Add(TKey key, TValue value)
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static uint Align(uint position, uint alignment)
static int SumRawDataSizes(ImmutableArray< SerializedSection > sections, SectionCharacteristics characteristics)
Definition PEBuilder.cs:306
static int IndexOfSection(ImmutableArray< SerializedSection > sections, SectionCharacteristics characteristics)
Definition PEBuilder.cs:294
BlobContentId Serialize(BlobBuilder builder)
Definition PEBuilder.cs:111
ImmutableArray< Section > CreateSections()
PEBuilder(PEHeaderBuilder header, Func< IEnumerable< Blob >, BlobContentId >? deterministicIdProvider)
Definition PEBuilder.cs:83
ImmutableArray< SerializedSection > SerializeSections()
Definition PEBuilder.cs:131
void WritePEHeader(BlobBuilder builder, PEDirectoriesBuilder directories, ImmutableArray< SerializedSection > sections)
Definition PEBuilder.cs:168
static unsafe uint CalculateChecksum(IEnumerable< Blob > blobs)
Definition PEBuilder.cs:405
void WriteCoffHeader(BlobBuilder builder, ImmutableArray< SerializedSection > sections, out Blob stampFixup)
Definition PEBuilder.cs:157
static IEnumerable< Blob > GetContentToChecksum(BlobBuilder peImage, Blob checksumFixup)
Definition PEBuilder.cs:371
BlobBuilder SerializeSection(string name, SectionLocation location)
void WriteSectionHeaders(BlobBuilder builder, ImmutableArray< SerializedSection > serializedSections)
Definition PEBuilder.cs:254
void Sign(BlobBuilder peImage, Blob strongNameSignatureFixup, Func< IEnumerable< Blob >, byte[]> signatureProvider)
Definition PEBuilder.cs:387
ImmutableArray< Section > GetSections()
Definition PEBuilder.cs:95
static void WriteSectionHeader(BlobBuilder builder, SerializedSection serializedSection)
Definition PEBuilder.cs:264
readonly Lazy< ImmutableArray< Section > > _lazySections
Definition PEBuilder.cs:54
static Blob GetPrefixBlob(Blob container, Blob blob)
Definition PEBuilder.cs:361
static uint AggregateChecksum(uint checksum, ushort value)
Definition PEBuilder.cs:443
Func< IEnumerable< Blob >, BlobContentId > IdProvider
Definition PEBuilder.cs:79
void WritePESignature(BlobBuilder builder)
Definition PEBuilder.cs:151
static uint CalculateChecksum(BlobBuilder peImage, Blob checksumFixup)
Definition PEBuilder.cs:400
static IEnumerable< Blob > GetContentToSign(BlobBuilder peImage, int peHeadersSize, int peHeaderAlignment, Blob strongNameSignatureFixup)
Definition PEBuilder.cs:319
static Blob GetSuffixBlob(Blob container, Blob blob)
Definition PEBuilder.cs:366
static void ArgumentNull(string parameterName)
Definition Throw.cs:110
static string MustNotReturnNull
Definition SR.cs:220
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string SignatureProviderReturnedInvalidSignature
Definition SR.cs:210
Definition SR.cs:7
static Func< IEnumerable< Blob >, BlobContentId > GetTimeBasedProvider()
unsafe void WriteBytes(byte value, int byteCount)
readonly byte[] Buffer
Definition Blob.cs:5
ArraySegment< byte > GetBytes()
Definition Blob.cs:20
readonly SectionCharacteristics Characteristics
Definition PEBuilder.cs:14
Section(string name, SectionCharacteristics characteristics)
Definition PEBuilder.cs:16
SerializedSection(BlobBuilder builder, string name, SectionCharacteristics characteristics, int relativeVirtualAddress, int sizeOfRawData, int pointerToRawData)
Definition PEBuilder.cs:43