2 IMAGE_FILE_MACHINE_UNKNOWN = 0x0
\r
3 IMAGE_FILE_MACHINE_AM33 = 0x1D3
\r
4 IMAGE_FILE_MACHINE_AMD64 = 0x8664
\r
5 IMAGE_FILE_MACHINE_ARM = 0x1C0
\r
6 IMAGE_FILE_MACHINE_ARMNT = 0x1C4
\r
7 IMAGE_FILE_MACHINE_ARM64 = 0xAA64
\r
8 IMAGE_FILE_MACHINE_EBC = 0xEBC
\r
9 IMAGE_FILE_MACHINE_I386 = 0x14C
\r
10 IMAGE_FILE_MACHINE_IA64 = 0x200
\r
11 IMAGE_FILE_MACHINE_M32R = 0x9041
\r
12 IMAGE_FILE_MACHINE_MIPS16 = 0x266
\r
13 IMAGE_FILE_MACHINE_MIPSFPU = 0x366
\r
14 IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466
\r
15 IMAGE_FILE_MACHINE_POWERPC = 0x1F0
\r
16 IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1
\r
17 IMAGE_FILE_MACHINE_R4000 = 0x166
\r
18 IMAGE_FILE_MACHINE_SH3 = 0x1A2
\r
19 IMAGE_FILE_MACHINE_SH3DSP = 0x1A3
\r
20 IMAGE_FILE_MACHINE_SH4 = 0x1A6
\r
21 IMAGE_FILE_MACHINE_SH5 = 0x1A8
\r
22 IMAGE_FILE_MACHINE_THUMB = 0x1C2
\r
23 IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
\r
25 IMAGE_FILE_RELOCS_STRIPPED = 0x0001
\r
26 IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002
\r
27 IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004
\r
28 IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008
\r
29 IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010
\r
30 IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020
\r
31 IMAGE_FILE_BYTES_REVERSED_LO = 0x0080
\r
32 IMAGE_FILE_32BIT_MACHINE = 0x0100
\r
33 IMAGE_FILE_DEBUG_STRIPPED = 0x0200
\r
34 IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400
\r
35 IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800
\r
36 IMAGE_FILE_SYSTEM = 0x1000
\r
37 IMAGE_FILE_DLL = 0x2000
\r
38 IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000
\r
39 IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
\r
41 IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020
\r
42 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040
\r
43 IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080
\r
44 IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100
\r
45 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200
\r
46 IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400
\r
47 IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800
\r
48 IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000
\r
49 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000
\r
50 IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000
\r
51 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
\r
53 IMAGE_SUBSYSTEM_UNKNOWN = 0
\r
54 IMAGE_SUBSYSTEM_NATIVE = 1
\r
55 IMAGE_SUBSYSTEM_WINDOWS_GUI = 2
\r
56 IMAGE_SUBSYSTEM_WINDOWS_CUI = 3
\r
57 IMAGE_SUBSYSTEM_POSIX_CUI = 7
\r
58 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9
\r
59 IMAGE_SUBSYSTEM_EFI_APPLICATION = 10
\r
60 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11
\r
61 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12
\r
62 IMAGE_SUBSYSTEM_EFI_ROM = 13
\r
63 IMAGE_SUBSYSTEM_XBOX = 14
\r
65 IMAGE_SCN_TYPE_NO_PAD = 0x00000008
\r
66 IMAGE_SCN_CNT_CODE = 0x00000020
\r
67 IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040
\r
68 IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
\r
69 IMAGE_SCN_LNK_OTHER = 0x00000100
\r
70 IMAGE_SCN_LNK_INFO = 0x00000200
\r
71 IMAGE_SCN_LNK_REMOVE = 0x00000800
\r
72 IMAGE_SCN_LNK_COMDAT = 0x00001000
\r
73 IMAGE_SCN_GPREL = 0x00008000
\r
74 IMAGE_SCN_MEM_PURGEABLE = 0x00020000
\r
75 IMAGE_SCN_MEM_16BIT = 0x00020000
\r
76 IMAGE_SCN_MEM_LOCKED = 0x00040000
\r
77 IMAGE_SCN_MEM_PRELOAD = 0x00080000
\r
78 IMAGE_SCN_ALIGN_1BYTES = 0x00100000
\r
79 IMAGE_SCN_ALIGN_2BYTES = 0x00200000
\r
80 IMAGE_SCN_ALIGN_4BYTES = 0x00300000
\r
81 IMAGE_SCN_ALIGN_8BYTES = 0x00400000
\r
82 IMAGE_SCN_ALIGN_16BYTES = 0x00500000
\r
83 IMAGE_SCN_ALIGN_32BYTES = 0x00600000
\r
84 IMAGE_SCN_ALIGN_64BYTES = 0x00700000
\r
85 IMAGE_SCN_ALIGN_128BYTES = 0x00800000
\r
86 IMAGE_SCN_ALIGN_256BYTES = 0x00900000
\r
87 IMAGE_SCN_ALIGN_512BYTES = 0x00A00000
\r
88 IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000
\r
89 IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000
\r
90 IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000
\r
91 IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000
\r
92 IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000
\r
93 IMAGE_SCN_MEM_DISCARDABLE = 0x02000000
\r
94 IMAGE_SCN_MEM_NOT_CACHED = 0x04000000
\r
95 IMAGE_SCN_MEM_NOT_PAGED = 0x08000000
\r
96 IMAGE_SCN_MEM_SHARED = 0x10000000
\r
97 IMAGE_SCN_MEM_EXECUTE = 0x20000000
\r
98 IMAGE_SCN_MEM_READ = 0x40000000
\r
99 IMAGE_SCN_MEM_WRITE = 0x80000000
\r
101 IMAGE_REL_BASED_ABSOLUTE = 0
\r
102 IMAGE_REL_BASED_HIGH = 1
\r
103 IMAGE_REL_BASED_LOW = 2
\r
104 IMAGE_REL_BASED_HIGHLOW = 3
\r
105 IMAGE_REL_BASED_HIGHADJ = 4
\r
106 IMAGE_REL_BASED_DIR64 = 10
\r
108 calminstruction align? boundary,value:?
\r
109 check $ relativeto 0 | ( $ relativeto PE.RELOCATION & PE.SECTION_ALIGNMENT mod boundary = 0 )
\r
111 arrange value, =err 'section not aligned enough'
\r
115 compute boundary, (boundary-1)-((0 scaleof $)+boundary-1) mod boundary
\r
116 arrange value, =db boundary =dup value
\r
118 end calminstruction
\r
124 if defined Settings.Magic
\r
125 MAGIC = Settings.Magic
\r
130 if defined Settings.Machine
\r
131 MACHINE = Settings.Machine
\r
133 MACHINE = IMAGE_FILE_MACHINE_I386
\r
136 if defined Settings.Characteristics
\r
137 CHARACTERISTICS = Settings.Characteristics
\r
139 CHARACTERISTICS = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE
\r
142 if defined Settings.DllCharacteristics
\r
143 DLL_CHARACTERISTICS = Settings.DllCharacteristics
\r
145 DLL_CHARACTERISTICS = 0
\r
148 if defined Settings.Subsystem
\r
149 SUBSYSTEM = Settings.Subsystem
\r
151 SUBSYSTEM = IMAGE_SUBSYSTEM_WINDOWS_CUI
\r
154 if defined Settings.MajorSubsystemVersion
\r
155 MAJOR_SUBSYSTEM_VERSION = Settings.MajorSubsystemVersion
\r
157 MAJOR_SUBSYSTEM_VERSION = 3
\r
160 if defined Settings.MinorSubsystemVersion
\r
161 MINOR_SUBSYSTEM_VERSION = Settings.MinorSubsystemVersion
\r
163 MINOR_SUBSYSTEM_VERSION = 10
\r
168 DLL_CHARACTERISTICS = DLL_CHARACTERISTICS or IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
\r
171 CHARACTERISTICS = CHARACTERISTICS or IMAGE_FILE_RELOCS_STRIPPED
\r
174 if defined Settings.ImageBase
\r
175 IMAGE_BASE := RELOCATION + Settings.ImageBase
\r
177 IMAGE_BASE := RELOCATION + 400000h
\r
180 if defined Settings.SectionAlignment
\r
181 SECTION_ALIGNMENT := Settings.SectionAlignment
\r
183 SECTION_ALIGNMENT := 1000h
\r
186 if defined Settings.FileAlignment
\r
187 FILE_ALIGNMENT := Settings.FileAlignment
\r
189 FILE_ALIGNMENT := 512
\r
192 if defined Settings.LegacyHeaders
\r
193 LEGACY_HEADERS := Settings.LegacyHeaders
\r
195 LEGACY_HEADERS := 1
\r
198 NUMBER_OF_DIRECTORIES := 16
\r
200 if defined Settings.Stub
\r
205 load SIGNATURE : word from 0
\r
206 if SIGNATURE = "MZ" | SIGNATURE = "ZM"
\r
212 if defined StubTemplate
\r
214 load .BYTES_IN_LAST_PAGE : word from StubTemplate:2
\r
215 load .NUMBER_OF_PAGES : word from StubTemplate:4
\r
216 .TEMPLATE_LENGTH = .NUMBER_OF_PAGES shl 9 - (-.BYTES_IN_LAST_PAGE) and 1FFh
\r
218 load .RELOCATIONS_OFFSET : word from StubTemplate:18h
\r
219 if .RELOCATIONS_OFFSET >= 40h
\r
220 file Settings.Stub,.TEMPLATE_LENGTH
\r
222 load .NUMBER_OF_RELOCATIONS : word from StubTemplate:6
\r
223 .RELOCATIONS_LENGTH = .NUMBER_OF_RELOCATIONS shl 2
\r
224 load .NUMBER_OF_HEADER_PARAGRAPHS : word from StubTemplate:8
\r
225 .TEMPLATE_HEADER_LENGTH = .NUMBER_OF_HEADER_PARAGRAPHS shl 4
\r
227 file Settings.Stub,1Ch
\r
229 file Settings.Stub:.RELOCATIONS_OFFSET,.RELOCATIONS_LENGTH
\r
232 file Settings.Stub:.TEMPLATE_HEADER_LENGTH,.TEMPLATE_LENGTH-.TEMPLATE_HEADER_LENGTH
\r
235 store 40h : word at 18h
\r
236 store .HEADER_LENGTH shr 4 : word at 8
\r
237 store .LENGTH and 1FFh : word at 2
\r
238 store (.LENGTH-1) shr 9 + 1 : word at 4
\r
241 store Header : dword at 3Ch
\r
247 .bytes_in_last_page dw .LENGTH and 1FFh
\r
248 .number_of_pages dw (.LENGTH-1) shr 9 + 1
\r
249 .number_of_relocations dw 0
\r
250 .number_of_header_paragraphs dw .HEADER_LENGTH shr 4
\r
251 .minimum_heap dw (10000h - (.LENGTH-.HEADER_LENGTH)) shr 4
\r
252 .maximum_heap dw 0FFFFh
\r
253 .initial_ss dw (-100h) shr 4
\r
254 .initial_sp dw 0FFFEh
\r
256 .initial_ip dw 100h
\r
257 .initial_cs dw (-100h) shr 4
\r
258 .relocations_offset dw 40h
\r
259 .overlay_number dw 0
\r
261 .new_header_offset dd Header
\r
275 .bytes_in_last_page dw .LENGTH and 1FFh
\r
276 .number_of_pages dw (.LENGTH-1) shr 9 + 1
\r
277 .number_of_relocations dw 0
\r
278 .number_of_header_paragraphs dw .HEADER_LENGTH shr 4
\r
279 .minimum_heap dw .STACK_LENGTH shr 4
\r
280 .maximum_heap dw 0FFFFh
\r
282 .initial_sp dw .LENGTH - .HEADER_LENGTH + .STACK_LENGTH
\r
286 .relocations_offset dw 40h
\r
287 .overlay_number dw 0
\r
289 .new_header_offset dd Header
\r
292 .STACK_LENGTH = 100h
\r
296 include '../8086.inc'
\r
301 mov dx,message - start
\r
307 message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
\r
317 if defined Settings.Stamp
\r
318 TIMESTAMP := Settings.Stamp
\r
320 TIMESTAMP := __TIME__
\r
326 .Signature dw "PE",0
\r
327 .Machine dw MACHINE
\r
328 .NumberOfSections dw NUMBER_OF_SECTIONS
\r
329 .TimeDateStamp dd TIMESTAMP
\r
330 .PointerToSymbolTable dd 0
\r
331 .NumberOfSymbols dd 0
\r
332 .SizeOfOptionalHeader dw SectionTable - OptionalHeader
\r
333 .Characteristics dw CHARACTERISTICS
\r
337 .MajorLinkerVersion db 0
\r
338 .MinorLinkerVersion db 0
\r
340 .SizeOfInitializedData dd 0
\r
341 .SizeOfUninitializedData dd 0
\r
342 .AddressOfEntryPoint dd 0
\r
346 .ImageBase dd IMAGE_BASE - RELOCATION
\r
348 .ImageBase dq IMAGE_BASE - RELOCATION
\r
350 .SectionAlignment dd SECTION_ALIGNMENT
\r
351 .FileAlignment dd FILE_ALIGNMENT
\r
352 .MajorOperatingSystemVersion dw 1
\r
353 .MinorOperatingSystemVersion dw 0
\r
354 .MajorImageVersion dw 0
\r
355 .MinorImageVersion dw 0
\r
356 .MajorSubsystemVersion dw MAJOR_SUBSYSTEM_VERSION
\r
357 .MinorSubsystemVersion dw MINOR_SUBSYSTEM_VERSION
\r
358 .Win32VersionValue dd 0
\r
359 .SizeOfImage dd SIZE_OF_IMAGE
\r
360 .SizeOfHeaders dd SIZE_OF_HEADERS
\r
362 .Subsystem dw SUBSYSTEM
\r
363 .DllCharacteristics dw DLL_CHARACTERISTICS
\r
365 .SizeOfStackReserve dd 1000h
\r
366 .SizeOfStackCommit dd 1000h
\r
367 .SizeOfHeapReserve dd 10000h
\r
368 .SizeOfHeapCommit dd 0
\r
370 .SizeOfStackReserve dq 1000h
\r
371 .SizeOfStackCommit dq 1000h
\r
372 .SizeOfHeapReserve dq 10000h
\r
373 .SizeOfHeapCommit dq 0
\r
376 .NumberOfRvaAndSizes dd NUMBER_OF_DIRECTORIES
\r
380 .ENTRY_LENGTH = $ - RvaAndSizes
\r
381 db (NUMBER_OF_DIRECTORIES-1)*RvaAndSizes.ENTRY_LENGTH dup 0
\r
385 .VirtualAddress dd 0
\r
386 .SizeOfRawData dd 0
\r
387 .PointerToRawData dd 0
\r
388 .PointerToRelocations dd 0
\r
389 .PointerToLineNumbers dd 0
\r
390 .NumberOfRelocations dw 0
\r
391 .NumberOfLineNumbers dw 0
\r
392 .Characteristics dd IMAGE_SCN_MEM_EXECUTE + IMAGE_SCN_MEM_READ + IMAGE_SCN_MEM_WRITE
\r
393 .ENTRY_LENGTH = $ - SectionTable
\r
394 db (NUMBER_OF_SECTIONS-1)*SectionTable.ENTRY_LENGTH dup 0
\r
397 define CheckSumBlocks PE,0,HeadersEnd
\r
400 RELOCATION_INDEX = 0
\r
401 DEFINED_SECTION = 0
\r
402 SECTION_DIRECTORIES = 0
\r
403 align SECTION_ALIGNMENT
\r
406 align FILE_ALIGNMENT,0
\r
407 SIZE_OF_HEADERS = $%
\r
409 SECTION_BASE = IMAGE_BASE + FIRST_SECTION_RVA
\r
412 store SECTION_BASE-IMAGE_BASE at PE:OptionalHeader.AddressOfEntryPoint
\r
413 store SECTION_BASE-IMAGE_BASE at PE:SectionTable.VirtualAddress
\r
414 store FILE_OFFSET at PE:SectionTable.PointerToRawData
\r
417 relocated_addresses:: rd NUMBER_OF_RELOCATIONS
\r
421 relocation_types:: rw NUMBER_OF_RELOCATIONS
\r
426 RVA? equ -PE.IMAGE_BASE +
\r
428 macro entry? address*
\r
430 store address-IMAGE_BASE at PE:OptionalHeader.AddressOfEntryPoint
\r
434 macro stack? reserve*,commit:1000h
\r
436 store reserve at PE:OptionalHeader.SizeOfStackReserve
\r
437 store commit at PE:OptionalHeader.SizeOfStackCommit
\r
441 macro heap? reserve*,commit:0
\r
443 store reserve at PE:OptionalHeader.SizeOfHeapReserve
\r
444 store commit at PE:OptionalHeader.SizeOfHeapCommit
\r
448 calminstruction calminstruction?.init? var*, val:0
\r
451 end calminstruction
\r
453 calminstruction calminstruction?.initsym? var*, val&
\r
455 end calminstruction
\r
457 calminstruction calminstruction?.unique? name
\r
458 local counter, buffer
\r
460 compute counter, counter + 1
\r
461 arrange buffer, name#counter
\r
462 publish name, buffer
\r
463 end calminstruction
\r
465 calminstruction calminstruction?.asm? line&
\r
466 local tmp, ln, buffer
\r
467 initsym tmp, unique ln
\r
470 arrange buffer, =assemble ln
\r
472 end calminstruction
\r
477 repeat SECTION_DIRECTORIES
\r
481 local AREA,DATA_START,DATA_END
\r
484 DATA_END = $-($%-$%%)
\r
485 CheckSumBlocks reequ CheckSumBlocks,AREA,DATA_START,DATA_END
\r
487 SECTION_SIZE = $ - SECTION_BASE
\r
488 store SECTION_SIZE at PE:SectionTable.VirtualSize+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
489 align SECTION_ALIGNMENT
\r
492 align FILE_ALIGNMENT,0
\r
493 RAW_DATA_SIZE = $% - FILE_OFFSET
\r
494 store RAW_DATA_SIZE at PE:SectionTable.SizeOfRawData+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
498 load SECTION_CHARACTERISTICS from PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
499 if SECTION_SIZE > 0 & RAW_DATA_SIZE = 0
\r
500 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_UNINITIALIZED_DATA
\r
501 store SECTION_CHARACTERISTICS at PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
505 if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_CODE & RAW_DATA_SIZE > 0
\r
506 load CODE_SIZE from PE:OptionalHeader.SizeOfCode
\r
508 load CODE_BASE from PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
509 store CODE_BASE at PE:OptionalHeader.BaseOfCode
\r
511 CODE_SIZE = CODE_SIZE + RAW_DATA_SIZE
\r
512 store CODE_SIZE at PE:OptionalHeader.SizeOfCode
\r
514 if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_INITIALIZED_DATA & RAW_DATA_SIZE > 0
\r
515 load DATA_SIZE from PE:OptionalHeader.SizeOfInitializedData
\r
516 if DATA_SIZE = 0 & MAGIC <> 0x20B
\r
517 load DATA_BASE from PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
518 store DATA_BASE at PE:OptionalHeader.BaseOfData
\r
520 DATA_SIZE = DATA_SIZE + RAW_DATA_SIZE
\r
521 store DATA_SIZE at PE:OptionalHeader.SizeOfInitializedData
\r
523 if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_UNINITIALIZED_DATA
\r
524 load BSS_SIZE from PE:OptionalHeader.SizeOfUninitializedData
\r
525 BSS_SIZE = BSS_SIZE + SECTION_SIZE
\r
526 store BSS_SIZE at PE:OptionalHeader.SizeOfUninitializedData
\r
530 if DEFINED_SECTION | SECTION_SIZE > 0
\r
531 SECTION_INDEX = SECTION_INDEX + 1
\r
537 macro section? declaration*
\r
542 DEFINED_SECTION = 1
\r
544 store SECTION_BASE-IMAGE_BASE at PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
545 store FILE_OFFSET at PE:SectionTable.PointerToRawData+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
547 SECTION_DIRECTORIES = 0
\r
549 match name attributes, declaration
\r
551 store name:qword at PE:SectionTable.Name+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
553 SECTION_CHARACTERISTICS = 0
\r
556 define seq attributes:
\r
560 else match =readable? tail, seq
\r
562 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_READ
\r
563 else match =writeable? tail, seq
\r
565 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_WRITE
\r
566 else match =writable? tail, seq
\r
568 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_WRITE
\r
569 else match =executable? tail, seq
\r
571 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_EXECUTE
\r
572 else match =discardable? tail, seq
\r
574 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_DISCARDABLE
\r
575 else match =shareable? tail, seq
\r
577 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_SHARED
\r
578 else match =import? tail, seq
\r
580 SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
\r
582 else match =export? tail, seq
\r
584 SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
\r
586 else match =resource? =from? path tail, seq
\r
588 SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
\r
589 data resource from path
\r
590 else match =resource? tail, seq
\r
592 SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
\r
594 else match =fixups? tail, seq
\r
596 SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
\r
598 else match =code? tail, seq
\r
600 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_CODE
\r
601 else match =data? tail, seq
\r
603 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_INITIALIZED_DATA
\r
604 else match =udata? tail, seq
\r
606 SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_UNINITIALIZED_DATA
\r
607 else match attribute tail, seq
\r
608 err 'unknown attribute "',`attribute,'"'
\r
613 store SECTION_CHARACTERISTICS at PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
616 store declaration:qword at PE:SectionTable.Name+SECTION_INDEX*SectionTable.ENTRY_LENGTH
\r
625 local number,content
\r
627 match =export?, type
\r
629 else match =import?, type
\r
631 else match =resource? =from? path, type
\r
633 define content resource_from path
\r
634 else match =resource?, type
\r
636 else match =fixups?, type
\r
638 define content fixups
\r
642 define DATA_DIRECTORY number
\r
643 load DATA_BASE:dword from PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
\r
645 store $-IMAGE_BASE:dword at PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
\r
646 match instruction, content
\r
650 err 'data already defined'
\r
657 load DATA_BASE:dword from PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
\r
658 store $-IMAGE_BASE-DATA_BASE:dword at PE:RvaAndSizes.Size+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
\r
659 restore DATA_DIRECTORY
\r
663 macro PE.resource_directory?
\r
665 Resource: rb RESOURCE_HEADERS_LENGTH
\r
666 Resource.counter = 0
\r
667 define RESOURCE_DIRECTORIES_LIST Resource_root
\r
668 Resource_root.counter = 0
\r
672 macro PE.resource_data? type*,id*,lang*,codepage:0
\r
674 local _type,_id,_lang
\r
679 _type = _type shl 32
\r
685 _lang = lang shl 32
\r
687 repeat 1, %type:_type, %id:_id, %lang:_lang
\r
688 if ~ defined Resource_#%type#_#%id.counter
\r
689 if ~ defined Resource_#%type.counter
\r
690 repeat 1, i:Resource_root.counter
\r
691 Resource_root.entry#i = type
\r
692 Resource_root.offset#i = (Resource_#%type - Resource) or 80000000h
\r
694 Resource_root.counter = Resource_root.counter + 1
\r
695 match list, RESOURCE_DIRECTORIES_LIST
\r
696 define RESOURCE_DIRECTORIES_LIST list,Resource_#%type
\r
698 Resource_#%type.counter = 0
\r
700 repeat 1, i:Resource_#%type.counter
\r
701 Resource_#%type.entry#i = id
\r
702 Resource_#%type.offset#i = (Resource_#%type#_#%id - Resource) or 80000000h
\r
704 Resource_#%type.counter = Resource_#%type.counter + 1
\r
706 match list, RESOURCE_DIRECTORIES_LIST
\r
707 define RESOURCE_DIRECTORIES_LIST list,Resource_#%type#_#%id
\r
709 Resource_#%type#_#%id.counter = 0
\r
711 repeat 1, i:Resource_#%type#_#%id.counter
\r
712 Resource_#%type#_#%id.entry#i = lang
\r
713 Resource_#%type#_#%id.offset#i = Resource_#%type#_#%id#_#%lang - Resource
\r
715 Resource_#%type#_#%id.counter = Resource_#%type#_#%id.counter + 1
\r
716 repeat 1, i:Resource.counter
\r
717 Resource_#%type#_#%id#_#%lang := Resource.entry#i
\r
718 Resource.cp#i := codepage
\r
725 macro PE.end_resource_data?
\r
727 repeat 1, i:Resource.counter
\r
728 Resource.size#i := $ - Resource.data#i
\r
730 Resource.counter = Resource.counter + 1
\r
735 macro PE.end_resource_directory?
\r
737 RESOURCE_HEADERS_POINTER = 0
\r
739 match list, RESOURCE_DIRECTORIES_LIST
\r
741 dir := Resource + RESOURCE_HEADERS_POINTER
\r
742 RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 16 + dir.counter * 8
\r
744 x = dir.counter shr 1
\r
747 while y < dir.counter
\r
750 repeat 1, i:z, j:z-x
\r
751 if dir.entry#i eqtype 0
\r
752 if ~ dir.entry#j eqtype 0 | dir.entry#i >= dir.entry#j
\r
755 else if ~ dir.entry#j eqtype 0
\r
756 a = dir.entry#i bswap lengthof dir.entry#i
\r
757 b = dir.entry#j bswap lengthof dir.entry#j
\r
758 if ( lengthof a >= lengthof b & a shr ((lengthof a - lengthof b)*8) >= b ) | ( lengthof a < lengthof b & a > b shr ((lengthof b - lengthof a)*8) )
\r
765 dir.entry#i = dir.entry#j
\r
766 dir.offset#i = dir.offset#j
\r
779 store __TIME__ : 4 at dir + 4
\r
780 dir.names_counter = 0
\r
781 repeat dir.counter, i:0
\r
782 if dir.entry#i eqtype 0
\r
783 store dir.entry#i : 4 at dir + 16 + i * 8
\r
785 dir.names_counter = dir.names_counter + 1
\r
786 repeat 1, %id:dir.entry#i
\r
787 if ~ defined Resource_string#%id
\r
788 restore Resource_string#%id
\r
789 Resource_string#%id = Resource + RESOURCE_HEADERS_POINTER
\r
790 if lengthof dir.entry#i and 1
\r
791 err 'a word-aligned string is expected as a name'
\r
793 RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + lengthof dir.entry#i + 2
\r
794 store (lengthof dir.entry#i)/2 : 2 at Resource_string#%id
\r
795 store dir.entry#i : lengthof dir.entry#i at Resource_string#%id + 2
\r
797 store (Resource_string#%id - Resource) or 80000000h : 4 at dir + 16 + i * 8
\r
800 store dir.offset#i : 4 at dir + 16 + i * 8 + 4
\r
802 store dir.names_counter : 2 at dir + 12
\r
803 store dir.counter - dir.names_counter : 2 at dir + 14
\r
807 if RESOURCE_HEADERS_POINTER and 11b
\r
808 RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 4 - RESOURCE_HEADERS_POINTER and 11b
\r
811 repeat Resource.counter, i:0
\r
812 Resource.entry#i := Resource + RESOURCE_HEADERS_POINTER
\r
813 RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 16
\r
814 store RVA(Resource.data#i) : 4 at Resource.entry#i
\r
815 store Resource.size#i : 4 at Resource.entry#i + 4
\r
816 store Resource.cp#i : 4 at Resource.entry#i + 8
\r
819 RESOURCE_HEADERS_LENGTH = RESOURCE_HEADERS_POINTER
\r
823 macro PE.resource_from path*
\r
825 local res_file,res_size,res_header_size,res_data_size,res_data
\r
826 local offset,char,type,id,lang
\r
829 res_file:: file path
\r
833 PE.resource_directory
\r
836 while offset < res_size
\r
837 load res_header_size : 4 from res_file : offset + 4
\r
838 load res_data_size : 4 from res_file : offset + 0
\r
840 if res_data_size > 0
\r
842 offset =: offset + 8
\r
843 load char : 2 from res_file : offset
\r
845 load char : 2 from res_file : offset + 2
\r
847 offset = offset + 4
\r
851 load type : (%-1)*2 from res_file : offset
\r
852 offset = offset + (% + % and 1)*2
\r
855 load char : 2 from res_file : offset + %*2
\r
858 load char : 2 from res_file : offset
\r
860 load char : 2 from res_file : offset + 2
\r
862 offset = offset + 4
\r
866 load id : (%-1)*2 from res_file : offset
\r
867 offset = offset + (% + % and 1)*2
\r
870 load char : 2 from res_file : offset + %*2
\r
873 load char : 2 from res_file : offset + 6
\r
878 PE.resource_data type,id,lang
\r
879 load res_data : res_data_size from res_file : offset + res_header_size
\r
881 PE.end_resource_data
\r
885 offset = offset + res_header_size + res_data_size
\r
887 offset = offset + 4 - offset and 11b
\r
891 PE.end_resource_directory
\r
898 calminstruction BuildFixups
\r
899 local PAGE_RVA, BLOCK_HEADER, BLOCK_SIZE
\r
900 local INDEX, ADDRESS, TYPE, FIXUP
\r
901 compute PAGE_RVA, -1
\r
902 compute BLOCK_HEADER, 0
\r
903 compute BLOCK_SIZE, 0
\r
906 check INDEX = NUMBER_OF_RELOCATIONS
\r
908 asm load ADDRESS:4 from relocated_addresses:INDEX shl 2
\r
909 check PAGE_RVA >= 0 & ADDRESS and not 0FFFh = PAGE_RVA
\r
910 jyes append_to_block
\r
913 jno start_new_block
\r
914 check BLOCK_SIZE and 11b
\r
917 compute BLOCK_SIZE, BLOCK_SIZE + 2
\r
919 asm store BLOCK_SIZE:4 at BLOCK_HEADER+4
\r
921 check INDEX = NUMBER_OF_RELOCATIONS
\r
923 compute PAGE_RVA, ADDRESS and not 0FFFh
\r
924 compute BLOCK_HEADER, $
\r
926 compute BLOCK_SIZE, 8
\r
928 asm load TYPE:2 from relocation_types:INDEX shl 1
\r
929 compute FIXUP, (ADDRESS and 0FFFh) or (TYPE shl 12)
\r
931 compute BLOCK_SIZE, BLOCK_SIZE + 2
\r
932 compute INDEX, INDEX + 1
\r
935 end calminstruction
\r
940 if defined PE.Fixups
\r
942 calminstruction dword? value
\r
943 compute value, value
\r
944 check value relativeto 0 | ~ value relativeto PE.RELOCATION
\r
948 asm emit 4: value - PE.RELOCATION
\r
951 asm store $-4-PE.IMAGE_BASE:4 at PE.relocated_addresses:PE.RELOCATION_INDEX shl 2
\r
952 asm store IMAGE_REL_BASED_HIGHLOW:2 at PE.relocation_types:PE.RELOCATION_INDEX shl 1
\r
953 compute PE.RELOCATION_INDEX, PE.RELOCATION_INDEX + 1
\r
958 end calminstruction
\r
960 calminstruction qword? value
\r
961 compute value, value
\r
962 check value relativeto 0 | ~ value relativeto PE.RELOCATION
\r
966 asm emit 8: value - PE.RELOCATION
\r
969 asm store $-8-PE.IMAGE_BASE:4 at PE.relocated_addresses:PE.RELOCATION_INDEX shl 2
\r
970 asm store IMAGE_REL_BASED_DIR64:2 at PE.relocation_types:PE.RELOCATION_INDEX shl 1
\r
971 compute PE.RELOCATION_INDEX, PE.RELOCATION_INDEX + 1
\r
976 end calminstruction
\r
978 iterate <dd,dword>, dd,dword, dq,qword
\r
980 calminstruction dd? definitions&
\r
983 match value=,definitions, definitions, ()
\r
985 match value, definitions
\r
986 arrange definitions,
\r
988 match n =dup? value, value, ()
\r
992 arrange value, =dword value
\r
995 match , definitions
\r
998 take definitions, definitions
\r
1002 arrange value, =dd ?
\r
1006 match (value), value
\r
1010 take definitions, value
\r
1011 arrange value, definitions
\r
1014 end calminstruction
\r
1016 calminstruction (label) dd? definitions&
\r
1018 arrange cmd, =label label : =dword
\r
1020 arrange cmd, =dd definitions
\r
1022 end calminstruction
\r
1032 SIZE_OF_IMAGE := SECTION_BASE - IMAGE_BASE
\r
1033 NUMBER_OF_SECTIONS := SECTION_INDEX
\r
1034 NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
\r
1042 calminstruction CheckSum
\r
1043 local AREA, DATA_START, DATA_END, POS, H
\r
1045 match AREA=,DATA_START=,DATA_END=,CheckSumBlocks, CheckSumBlocks
\r
1047 match AREA=,DATA_START=,DATA_END, CheckSumBlocks
\r
1051 arrange CheckSumBlocks,
\r
1053 compute POS, DATA_START
\r
1055 check POS + 2 <= DATA_END
\r
1057 asm load H:2 from AREA:POS
\r
1058 compute CHECKSUM, CHECKSUM + H
\r
1059 compute POS, POS + 2
\r
1060 jump process_block
\r
1062 check POS + 1 = DATA_END
\r
1063 jno reduce_checksum
\r
1064 asm load H:1 from AREA:POS
\r
1065 compute CHECKSUM, CHECKSUM + H
\r
1067 check CHECKSUM shr 16
\r
1069 compute CHECKSUM, CHECKSUM shr 16 + CHECKSUM and 0FFFFh
\r
1070 jump reduce_checksum
\r
1072 end calminstruction
\r
1075 CHECKSUM = CHECKSUM + $%
\r
1076 store CHECKSUM at PE:OptionalHeader.CheckSum
\r