~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Writer/PEWriter.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2008 Jeroen Frijters
 
3
 
 
4
  This software is provided 'as-is', without any express or implied
 
5
  warranty.  In no event will the authors be held liable for any damages
 
6
  arising from the use of this software.
 
7
 
 
8
  Permission is granted to anyone to use this software for any purpose,
 
9
  including commercial applications, and to alter it and redistribute it
 
10
  freely, subject to the following restrictions:
 
11
 
 
12
  1. The origin of this software must not be misrepresented; you must not
 
13
     claim that you wrote the original software. If you use this software
 
14
     in a product, an acknowledgment in the product documentation would be
 
15
     appreciated but is not required.
 
16
  2. Altered source versions must be plainly marked as such, and must not be
 
17
     misrepresented as being the original software.
 
18
  3. This notice may not be removed or altered from any source distribution.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
  
 
23
*/
 
24
using System;
 
25
using System.IO;
 
26
using BYTE = System.Byte;
 
27
using WORD = System.UInt16;
 
28
using DWORD = System.UInt32;
 
29
using ULONGLONG = System.UInt64;
 
30
using IMAGE_DATA_DIRECTORY = IKVM.Reflection.Reader.IMAGE_DATA_DIRECTORY;
 
31
 
 
32
namespace IKVM.Reflection.Writer
 
33
{
 
34
        sealed class PEWriter
 
35
        {
 
36
                private readonly BinaryWriter bw;
 
37
                private readonly IMAGE_NT_HEADERS hdr = new IMAGE_NT_HEADERS();
 
38
 
 
39
                internal PEWriter(Stream stream)
 
40
                {
 
41
                        bw = new BinaryWriter(stream);
 
42
                        WriteMSDOSHeader();
 
43
                }
 
44
 
 
45
                public IMAGE_NT_HEADERS Headers
 
46
                {
 
47
                        get { return hdr; }
 
48
                }
 
49
 
 
50
                public uint HeaderSize
 
51
                {
 
52
                        get
 
53
                        {
 
54
                                return (uint)
 
55
                                        ((8 * 16) +     // MSDOS header
 
56
                                        4 +                             // signature
 
57
                                        20 +                    // IMAGE_FILE_HEADER
 
58
                                        hdr.FileHeader.SizeOfOptionalHeader +
 
59
                                        hdr.FileHeader.NumberOfSections * 40);
 
60
                        }
 
61
                }
 
62
 
 
63
                private void WriteMSDOSHeader()
 
64
                {
 
65
                        bw.Write(new byte[] {
 
66
                                0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
 
67
                                0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
 
68
                                0xB8, 0x00, 0x00, 0x00, 0x00, 0x00,     0x00, 0x00,
 
69
                                0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
70
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
71
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
72
                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
73
                                0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
 
74
                                0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD,
 
75
                                0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68,
 
76
                                0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72,
 
77
                                0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F,
 
78
                                0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E,
 
79
                                0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20,
 
80
                                0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A,
 
81
                                0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 
82
                        });
 
83
                }
 
84
 
 
85
                internal void WritePEHeaders()
 
86
                {
 
87
                        bw.Write(hdr.Signature);
 
88
 
 
89
                        // IMAGE_FILE_HEADER
 
90
                        bw.Write(hdr.FileHeader.Machine);
 
91
                        bw.Write(hdr.FileHeader.NumberOfSections);
 
92
                        bw.Write(hdr.FileHeader.TimeDateStamp);
 
93
                        bw.Write(hdr.FileHeader.PointerToSymbolTable);
 
94
                        bw.Write(hdr.FileHeader.NumberOfSymbols);
 
95
                        bw.Write(hdr.FileHeader.SizeOfOptionalHeader);
 
96
                        bw.Write(hdr.FileHeader.Characteristics);
 
97
 
 
98
                        // IMAGE_OPTIONAL_HEADER
 
99
                        hdr.OptionalHeader.Write(bw);
 
100
                }
 
101
 
 
102
                internal void WriteSectionHeader(SectionHeader sectionHeader)
 
103
                {
 
104
                        byte[] name = new byte[8];
 
105
                        System.Text.Encoding.UTF8.GetBytes(sectionHeader.Name, 0, sectionHeader.Name.Length, name, 0);
 
106
                        bw.Write(name);
 
107
                        bw.Write(sectionHeader.VirtualSize);
 
108
                        bw.Write(sectionHeader.VirtualAddress);
 
109
                        bw.Write(sectionHeader.SizeOfRawData);
 
110
                        bw.Write(sectionHeader.PointerToRawData);
 
111
                        bw.Write(sectionHeader.PointerToRelocations);
 
112
                        bw.Write(sectionHeader.PointerToLinenumbers);
 
113
                        bw.Write(sectionHeader.NumberOfRelocations);
 
114
                        bw.Write(sectionHeader.NumberOfLinenumbers);
 
115
                        bw.Write(sectionHeader.Characteristics);
 
116
                }
 
117
 
 
118
                internal uint ToFileAlignment(uint p)
 
119
                {
 
120
                        return (p + (Headers.OptionalHeader.FileAlignment - 1)) & ~(Headers.OptionalHeader.FileAlignment - 1);
 
121
                }
 
122
 
 
123
                internal uint ToSectionAlignment(uint p)
 
124
                {
 
125
                        return (p + (Headers.OptionalHeader.SectionAlignment - 1)) & ~(Headers.OptionalHeader.SectionAlignment - 1);
 
126
                }
 
127
        }
 
128
 
 
129
        sealed class IMAGE_NT_HEADERS
 
130
        {
 
131
                public DWORD Signature = 0x00004550;    // "PE\0\0"
 
132
                public IMAGE_FILE_HEADER FileHeader = new IMAGE_FILE_HEADER();
 
133
                public IMAGE_OPTIONAL_HEADER OptionalHeader = new IMAGE_OPTIONAL_HEADER();
 
134
        }
 
135
 
 
136
        sealed class IMAGE_FILE_HEADER
 
137
        {
 
138
                public const WORD IMAGE_FILE_MACHINE_I386 = 0x014c;
 
139
                public const WORD IMAGE_FILE_MACHINE_ARM = 0x01c4;
 
140
                public const WORD IMAGE_FILE_MACHINE_IA64 = 0x0200;
 
141
                public const WORD IMAGE_FILE_MACHINE_AMD64 = 0x8664;
 
142
 
 
143
                public const WORD IMAGE_FILE_32BIT_MACHINE = 0x0100;
 
144
                public const WORD IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002;
 
145
                public const WORD IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020;
 
146
                public const WORD IMAGE_FILE_DLL = 0x2000;
 
147
 
 
148
                public WORD Machine;
 
149
                public WORD NumberOfSections;
 
150
                public DWORD TimeDateStamp = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
 
151
                public DWORD PointerToSymbolTable = 0;
 
152
                public DWORD NumberOfSymbols = 0;
 
153
                public WORD SizeOfOptionalHeader = 0xE0;
 
154
                public WORD Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
 
155
        }
 
156
 
 
157
        sealed class IMAGE_OPTIONAL_HEADER
 
158
        {
 
159
                public const WORD IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;
 
160
                public const WORD IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b;
 
161
 
 
162
                public const WORD IMAGE_SUBSYSTEM_WINDOWS_GUI = 2;
 
163
                public const WORD IMAGE_SUBSYSTEM_WINDOWS_CUI = 3;
 
164
 
 
165
                public WORD Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
 
166
                public BYTE MajorLinkerVersion = 8;
 
167
                public BYTE MinorLinkerVersion = 0;
 
168
                public DWORD SizeOfCode;
 
169
                public DWORD SizeOfInitializedData;
 
170
                public DWORD SizeOfUninitializedData;
 
171
                public DWORD AddressOfEntryPoint;
 
172
                public DWORD BaseOfCode;
 
173
                public DWORD BaseOfData;
 
174
                public ULONGLONG ImageBase;
 
175
                public DWORD SectionAlignment = 0x2000;
 
176
                public DWORD FileAlignment;
 
177
                public WORD MajorOperatingSystemVersion = 4;
 
178
                public WORD MinorOperatingSystemVersion = 0;
 
179
                public WORD MajorImageVersion = 0;
 
180
                public WORD MinorImageVersion = 0;
 
181
                public WORD MajorSubsystemVersion = 4;
 
182
                public WORD MinorSubsystemVersion = 0;
 
183
                public DWORD Win32VersionValue = 0;
 
184
                public DWORD SizeOfImage;
 
185
                public DWORD SizeOfHeaders;
 
186
                public DWORD CheckSum = 0;
 
187
                public WORD Subsystem;
 
188
                public WORD DllCharacteristics;
 
189
                public ULONGLONG SizeOfStackReserve;
 
190
                public ULONGLONG SizeOfStackCommit = 0x1000;
 
191
                public ULONGLONG SizeOfHeapReserve = 0x100000;
 
192
                public ULONGLONG SizeOfHeapCommit = 0x1000;
 
193
                public DWORD LoaderFlags = 0;
 
194
                public DWORD NumberOfRvaAndSizes = 16;
 
195
                public IMAGE_DATA_DIRECTORY[] DataDirectory = new IMAGE_DATA_DIRECTORY[16];
 
196
 
 
197
                internal void Write(BinaryWriter bw)
 
198
                {
 
199
                        bw.Write(Magic);
 
200
                        bw.Write(MajorLinkerVersion);
 
201
                        bw.Write(MinorLinkerVersion);
 
202
                        bw.Write(SizeOfCode);
 
203
                        bw.Write(SizeOfInitializedData);
 
204
                        bw.Write(SizeOfUninitializedData);
 
205
                        bw.Write(AddressOfEntryPoint);
 
206
                        bw.Write(BaseOfCode);
 
207
                        if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
 
208
                        {
 
209
                                bw.Write(BaseOfData);
 
210
                                bw.Write((DWORD)ImageBase);
 
211
                        }
 
212
                        else
 
213
                        {
 
214
                                bw.Write(ImageBase);
 
215
                        }
 
216
                        bw.Write(SectionAlignment);
 
217
                        bw.Write(FileAlignment);
 
218
                        bw.Write(MajorOperatingSystemVersion);
 
219
                        bw.Write(MinorOperatingSystemVersion);
 
220
                        bw.Write(MajorImageVersion);
 
221
                        bw.Write(MinorImageVersion);
 
222
                        bw.Write(MajorSubsystemVersion);
 
223
                        bw.Write(MinorSubsystemVersion);
 
224
                        bw.Write(Win32VersionValue);
 
225
                        bw.Write(SizeOfImage);
 
226
                        bw.Write(SizeOfHeaders);
 
227
                        bw.Write(CheckSum);
 
228
                        bw.Write(Subsystem);
 
229
                        bw.Write(DllCharacteristics);
 
230
                        if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
 
231
                        {
 
232
                                bw.Write((DWORD)SizeOfStackReserve);
 
233
                        }
 
234
                        else
 
235
                        {
 
236
                                bw.Write(SizeOfStackReserve);
 
237
                        }
 
238
                        if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
 
239
                        {
 
240
                                bw.Write((DWORD)SizeOfStackCommit);
 
241
                        }
 
242
                        else
 
243
                        {
 
244
                                bw.Write(SizeOfStackCommit);
 
245
                        }
 
246
                        if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
 
247
                        {
 
248
                                bw.Write((DWORD)SizeOfHeapReserve);
 
249
                        }
 
250
                        else
 
251
                        {
 
252
                                bw.Write(SizeOfHeapReserve);
 
253
                        }
 
254
                        if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
 
255
                        {
 
256
                                bw.Write((DWORD)SizeOfHeapCommit);
 
257
                        }
 
258
                        else
 
259
                        {
 
260
                                bw.Write(SizeOfHeapCommit);
 
261
                        }
 
262
                        bw.Write(LoaderFlags);
 
263
                        bw.Write(NumberOfRvaAndSizes);
 
264
                        for (int i = 0; i < DataDirectory.Length; i++)
 
265
                        {
 
266
                                bw.Write(DataDirectory[i].VirtualAddress);
 
267
                                bw.Write(DataDirectory[i].Size);
 
268
                        }
 
269
                }
 
270
        }
 
271
 
 
272
        class SectionHeader
 
273
        {
 
274
                public const DWORD IMAGE_SCN_CNT_CODE = 0x00000020;
 
275
                public const DWORD IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040;
 
276
                public const DWORD IMAGE_SCN_MEM_DISCARDABLE = 0x02000000;
 
277
                public const DWORD IMAGE_SCN_MEM_EXECUTE = 0x20000000;
 
278
                public const DWORD IMAGE_SCN_MEM_READ = 0x40000000;
 
279
                public const DWORD IMAGE_SCN_MEM_WRITE = 0x80000000;
 
280
 
 
281
                public string Name;             // 8 byte UTF8 encoded 0-padded
 
282
                public DWORD VirtualSize;
 
283
                public DWORD VirtualAddress;
 
284
                public DWORD SizeOfRawData;
 
285
                public DWORD PointerToRawData;
 
286
#pragma warning disable 649 // the follow fields are never assigned to
 
287
                public DWORD PointerToRelocations;
 
288
                public DWORD PointerToLinenumbers;
 
289
                public WORD NumberOfRelocations;
 
290
                public WORD NumberOfLinenumbers;
 
291
#pragma warning restore 649
 
292
                public DWORD Characteristics;
 
293
        }
 
294
}