This is a module of EuroTool program EuroView.
EUROASM CPU=X64,AutoAlign=yes,DumpWidth=38,Unicode=no
viewmain PROGRAM Format=COFF,Width=64
%DROPMACRO *
INCLUDEHEAD argument.htm
INCLUDE1 memory64.htm, cpuext64.htm, cpuext.htm, sort64.htm, string64.htm, status32.htm, time.htm
EXTERN BufferCreate@RT
HEAD ; What will the listing line start with:
;Level0 = 0x0000_0000 ; |
Level1 = 0x1000_0000 ; |#
Level2 = 0x2000_0000 ; |##
Level3 = 0x3000_0000 ; |###
Level4 = 0x4000_0000 ; |####
VIEW_INDEX STRUC ; A structure which describes one viewed element.
.Rem D QWORD ; Pointer to the remark (in EuroView memory). It may contain !x variables.
.FA D DWORD ; FileAddress of the element.
.Size D DWORD ; Size of the element in bits 0..27 and level in bits 28..31.
ENDSTRUC VIEW_INDEX
LST_INDEX STRUC ; A structure which describes one line of the output (listing) file.
.FA D DWORD ; Offset of the line from OutputPtr.
.Size D DWORD ; Size of the line in bytes minus LF at the end.
ENDSTRUC LST_INDEX
ENDHEAD
[.rodata] ; Constant text data. EuroView:: DB "EuroView",0 Version:: DB " %^Date",0
[.data] FormatTable:: FF %FOR %FileFormats ; Enumeration %FileFormats is set inargument.htm. DQ Format%FF ; Address of the formating procedure. %ENDFOR FF FnTable: ; Functions used by ExpandRem. DQ Fn00$CoffMachine DQ Fn01$CoffCharacteristics DQ Fn02$CoffSectionName DQ Fn03$CoffSectionFlags DQ Fn04$CoffSymbolName DQ Fn05$CoffSymbolSection DQ Fn06$CoffSymbolType DQ Fn07$CoffSymbolIndexStore DQ Fn08$CoffSymbolByIndex DQ Fn09$CoffSectionIndexStore DQ Fn10$MajorMinorVersion1 DQ Fn11$MajorMinorVersion2 DQ Fn12$WinSubsystem DQ Fn13$DataDirName DQ Fn14$FileName DQ Fn15$SaveMemberSize DQ Fn16$DisplayName DQ Fn17$DisplaySymbolName DQ Fn18$MemberNumber DQ Fn19$OmfModuleName DQ Fn20$ElfSectionName DQ Fn21$ElfSymbolName DQ Fn22$ElfProgramSections DQ Fn23$GifColorTableSize DQ Fn24$FileSize MP3frame DD 0 MP3SamplerateTable: DD 44100, 48000, 32000 ; Used in FormatMP3. MP3BitrateTable: DW 0,32,40,48,56,64,80,96,112,128,160,192,224,256,320 ; Used in FormatMP3. MP3report: DB "MPEG1, Layer3, " MP3bitrate: DB "xxx000 bit/s, " MP3freq: DB "yyyyy Hz, " MP3channel: DB "joint stereo.",0 ElfSegmentTypes: DB "null",0,"progbits",0,"symtab",0,"strtab",0,"rela",0,"hash",0,"dynamic",0,"note",0, \ "nobits",0,"rel",0,"shlib",0,"dynsym",0 ElfDynamic: DB "NULL (ignored)",0,"NEEDED (required library)",0,"PLTRELSZ (size of PLT relocations)",0, \ "PLTGOT (PLT address)",0,"HASH (.hash address)",0,"STRTAB (.dynstr address)",0, \ "SYMTAB (.dynsym address)",0,"RELA (.rela.* address)",0,"RELASZ (.rela.* size)",0, \ "RELAENT (one RELA size)",0,"STRSZ (.strtab size)",0,"SYMENT (one symbol size)",0, \ "INIT (address of init function)",0,"FINI (address of termination function)",0, \ "SONAME (FA of this SO name)",0,"RPATH (offset of RPATH in .dynstr)",0, \ "SYMBOLIC",0,"REL (.rel.* address)",0,"RELSZ (.rel.* size)",0,"RELENT (one REL size)",0, \ "PLTREL (PLT relocation type)",0,"DEBUG",0,"TEXTREL (relocations for RO)",0, \ "JMPREL (.rela.plt address)",0,"BIND_NOW",0,"INIT_ARRAY (pointers to an array of pointers)",0, \ "FINI_ARRAY (pointers to an array of pointers)",0,"INIT_ARRAYSZ (size of the array)",0, \ "FINI_ARRAYSZ (size of the array)",0,"RUNPATH (offset of RUNPATH in .dynstr)",0,"FLAGS",0 DataDirNames: DB 'EXPORT',0 DB 'IMPORT',0 DB 'RESOURCE',0 DB 'EXCEPTION',0 DB 'CERTIFICATE',0 DB 'BASE_RELOC',0 DB 'DEBUG',0 DB 'ARCHITECTURE',0 DB 'GLOBAL_POINTER',0 DB 'TLS',0 DB 'LOAD_CONFIGURATION',0 DB 'BOUND_IMPORT',0 DB 'IAT',0 DB 'DELAY_IMPORT',0 DB 'CLI_HEADER',0 DB 'RESERVERD',0 [.bss] ; Working memory variables. ViewIndex:: DS VIEW_INDEX FileWriteOutputProc:: D QWORD ; Pointer to FileWrite in Windows or in Linux. FileIndexReopenProc:: D QWORD ; Pointer to FileClose and FileMapCreate in Windows or in Linux. InputPtr:: D QWORD ; Pointer to the contents of FileInput loaded in memory. InputSize:: D QWORD ; Input file size. InputEnd:: D QWORD ; Pointer to the end of contents of FileInput loaded in memory. OutputPtr:: D QWORD ; Pointer to the listing (in ASCII) in memory. OutputSize:: D QWORD ; Size of the listing. OutputEnd:: D QWORD ; Pointer to the end of listing in memory. IndexPtr:: D QWORD ; Pointer to the contents of FileIndex loaded in memory (1st VIEW_INDEX). IndexEnd:: D QWORD ; Pointer to the end contens of FileIndex loaded in memory. FormatNamePtr:: D QWORD ; Pointer to ASCIIZ string with uppercase format name. FormatProcPtr:: D QWORD ; Pointer to the file format function (FormatMZ, FormatCOFF32 etc) ArgNr:: D DWORD ; Binary number of the current cmd-line argument. ListingLines:: D DWORD ; Number of lines in FileOutput. Also Lines in viewwing.htm. AddressDigits:: D DWORD ; Number of address digits in listing (4..8). Level0Buffer:: D QWORD ; Pointer to BUFFER for Level0. Level1Buffer:: D QWORD ; Pointer to BUFFER for Level1. Level2Buffer:: D QWORD ; Pointer to BUFFER for Level2. Level3Buffer:: D QWORD ; Pointer to BUFFER for Level3. Level4Buffer:: D QWORD ; Pointer to BUFFER for Level4. FaOfArchiveStrings D DWORD FaOfDataDirs D DWORD FaOfDynamicEnd D DWORD FaOfElfProgramHeaders D DWORD FaOfElfSectionHeaders D DWORD FaOfHashEnd D DWORD FaOfMembersTable D DWORD FaOfNoteEnd D DWORD FaOfPeSignature D DWORD FaOfRelaEnd D DWORD FaOfRelEnd D DWORD FaOfRelocations D DWORD FaOfSectionHeaders D DWORD FaOfShstrtabData D DWORD FaOfStringTable D DWORD FaOfSymbolEnd D DWORD FaOfSymbolsEnd D DWORD FaOfSymbolTable D DWORD FaOfThisSectionHeader D DWORD FaOfSoundStart D DWORD FaOfSoundEnd D DWORD Fn13Index D DWORD LastOmfRecord D DWORD MemberNumber D DWORD MemberSize D DWORD MzBytesFileSize D DWORD MzHeaderSize D DWORD NrOfDataDirectories D DWORD NrOfElfProgramHeaders D DWORD NrOfElfSectionHeaders D DWORD NrOfRelocations D DWORD NrOfSections D DWORD NrOfSymbols D DWORD PaletteSize D DWORD RecordSize D DWORD SectionIndex D DWORD SectionNumber D DWORD SizeOfColorTable D DWORD SizeOfStringTable D DWORD ; Including DWORD size value. ID3size D DWORD ; Size of the entire ID3 tag in MP3 file, without 10 bytes. SymbolIndex D DWORD SymbolNumber D DWORD ACharacter D BYTE Number D 16*BYTE WorkMemory:: D 800*BYTE [.text]
AutodetectFileFormat:: PROC
FF %FOR %FileFormats
MOV RSI,[InputPtr::]
CALL Detect%FF ; Return CF=0 when %FF detected.
LEA RAX,[Format%FF:]
MOV ECX,ArgFileFormat%FF
JNC .Found
%ENDFOR FF
.Found:RET
ENDP AutodetectFileFormat
ByLevel:: PROC
MOV EAX,[RSI+VIEW_INDEX.FA]
MOV EDX,[RDI+VIEW_INDEX.FA]
CMP EDX,EAX
JB .SW:
JA .OK:
MOV EAX,[RSI+VIEW_INDEX.Size]
MOV EDX,[RDI+VIEW_INDEX.Size]
SHR EAX,28
SHR RDX,28
CMP EAX,EDX
JB .SW:
JA .OK:
MOV EAX,[RSI+VIEW_INDEX.Size]
MOV EDX,[RDI+VIEW_INDEX.Size]
CMP EDX,EAX
JNB .OK:
.SW:MOV RAX,[RSI+0]
MOV RDX,[RSI+8]
XCHG RAX,[RDI+0]
XCHG RDX,[RDI+8]
MOV [RSI+0],RAX
MOV [RSI+8],RDX
STC
.OK:RET
ENDP ByLevel
ExpandRem
[RBX+VIEW_INDEX.Rem] to RDI and expands escaped parameters.
Exclamation ! is the escape character. If a decimal number immediately follows the exclamation,
this many bytes will be used from the inspected file, otherwise VIEW_INDEX.Size bytes will be used.
Address of the inspected file is specified by the current FA in R14, the input file is mapped at R8.
The number R13=VIEW_INDEX.Size may be above 16, in this case each listing line
is max.16 dumped bytes long and it is repeated with file address R14=VIEW_INDEX.FA increased.
Table of escaped symbols: (n represents a decimal number)
| !n$ | Helper n-th function from FnTable::, e. g. Fn12WinSubsystem. |
|---|---|
| !1A | 1 Low nibble from 2nd character converted to '0'..'F'. |
| !2B | 2 2 bytes as a hexadecimal number in big endian. |
| !2b | 2 2 bytes as a decimal number in big endian. |
| !1C | 1 PNG color type. |
| !nD | n bytes as a decimal number. |
| !4d | 4 bytes as a decimal number in big endian. |
| !4E | 4 bytes from FA+0..FA+3 as ASCII (PNG chunk identifier). |
| !4F | 2+2 bytes as a hexadecimal segment:offset. |
| !2G | ELF file type. |
| !nH | n bytes as a hexadecimal number. |
| !4h | 4 bytes as a hexadecimal number in big endian. |
| !2I | Interpreted as import type in LIBCOF format. |
| !12L | 12 decimal digits interpreted as 1970 datetime (seconds since 1.1.1970). |
| !2M | ELF machine type. |
| !4N | ELF section name. |
| !1O | OMF record type. |
| !4P | ELF program type. |
| !4Q | ELF program flags. |
| !4q | ELF section flags. |
| !1R | ELF section number. |
| !1r | ELF symbol number. |
| !4S | ELF section type. |
| !1s | ELF symbol info. |
| !4T | Dword interpreted as 1970 datetime (seconds since 1.1.1970). |
| !2U | Symbol's section number|type. |
| !nX | n bytes as a text (ASCII characters 20..127 only, otherwise spaces). |
| !8y | ELF32 dynamic |
| !4Z | ELF relocation type. |
VIEW_INDEX.Rem).
time.htm.
ExpandRem:: PROC
MOV RSI,R12
TEST RSI
JZ .0x00:
.Dispatched: ; Return point from dispatching.
LODSB
CMP AL,0
JE .0x00: ; End of remark.
CMP AL,'!'
JE .20:
STOSB ; Copy nonescaped bytes from .Rem to RDI.
JMP .Dispatched:
.20: LodD RSI ; Load the decimal number following '!'.
JNC .30:
MOV ECX,R13D ; If it's missing, use R13 instead.
TEST ECX
JZ .0x00:
MOV EAX,ECX
.30: MOV ECX,EAX ; The number following !.
CMPB [RSI],'$' ; !n$ is not a number of expansion but a fn number.
JE .60: ; Do not load RAX when it's a function from FnTable.
CMP ECX,16 ; Do some preparation of registers before dispatching.
JBE .35:
MOV ECX,16
.35: MOV R11,RCX ; Temporary store RCX=R11 the number of loaded bytes from FA.
MOV EDX,R14D
XOR R9,R9 ; Load R9 from the data of viewed file.
JRCXZ .50:
ADD RDX,R8
.40: MOV AL,[RDX+RCX-1]
SHL R9,8
OR R9L,AL
LOOP .40:
.50: MOV RAX,R9 ; R9=RAX is 0..8 bytes loaded from FA mapped in memory.
MOV RCX,R11 ; Restore number of bytes loaded from FA or Fn number.
MOV EDX,R14D
.60: LODSB ; The next character after !n
PUSHQ .Dispatched: ; Where to continue after dispatching. This enables RET for return from dispatching.
Dispatch AL,'$','A','B','b','C','D','d','E','F','G','H','h','I','L','M','N','O','P','Q','q', \
'R','r','S','s','T','U','X','y','Z',0x00
STOSB ; Nonmatched character store as is.
JMP .Dispatched:
.X: JRCXZ .X9: ; Store the ECX (max.16) bytes of the text dump as ASCII characters.
PUSH R14 ; R14 is FA of the line.
.X1: MOV AL,[R14+R8]
CMP AL,0x7F
JA .X5:
CMP AL,0x20
JA .X6:
.X5: MOV AL,' '
.X6: STOSB
INC R14
LOOP .X1:
POP R14
.X9: RET
.A: MOV RAX,R9 ; Low nibble from 2nd character converted to '0'..'F'.
SHR EAX,8
AND AL,0x0F
OR AL,'0'
CMP AL,':'
JB .A5:
ADD AL,'A'-':'
.A5: STOSB
RET
.C: MOV RAX,R9 ; PNG color type.
PUSH RSI
Dispatch AL,0n0,0n2,0n3,0n4,0n6
StoD RDI
POP RSI
RET
.0n0: LEA RSI,[=B'grayscale']
JMP .M5:
.0n2: LEA RSI,[=B'truecolor']
JMP .M5:
.0n3: LEA RSI,[=B'indexed']
JMP .M5:
.0n4: LEA RSI,[=B'grayscale+aplha']
JMP .M5
.0n6: LEA RSI,[=B'truecolor+aplha']
JMP .M5
.b: MOVZXW EAX,R9W ; 2 bytes as a decimal number in big endian.
XCHG AH,AL
StoD RDI
RET
.B: MOVZXW EAX,R9W ; 2 bytes as a hexadecimal number in big endian.
XCHG AH,AL
StoH RDI,Size=4
RET
.D: MOV RAX,R9 ; Store RAX decimal.
StoD RDI
RET
.d: MOV RAX,R9 ; 4 bytes as a decimal number in big endian.
BSWAP EAX
StoD RDI
RET
.H: MOV RAX,R9 ; Store RAX hexadecimal.
ADD ECX,ECX
StoH RDI,Size=RCX
RET
.h: MOV RAX,R9 ; 4 bytes as a hexadecimal number in big endian.
ADD ECX,ECX
BSWAP EAX
StoH RDI,Size=RCX
RET
.E: PUSH RSI ; 4 bytes from FA+0..FA+3 as ASCII (PNG chunk identifier).
MOV EDX,[RBX+VIEW_INDEX.FA] ; Store four ASCII characters from FA+4...FA+7.
LEA RSI,[RDX+R8+4]
MOV ECX,4
.E1: LODSB
CMP AL,20
JB .E2:
CMP AL,128
JNA .E3:
.E2: MOV AL,' '
.E3: STOSB
LOOP .E1:
POP RSI
RET
.F: MOV RAX,R9 ; Store EAX as FAR pointer segment:offset hexadecimal.
StoH RDI,Size=8
SUB RDI,4
MOV ECX,[RDI]
MOV AL,':'
STOSB
MOV EAX,ECX
STOSD
.F9: RET
.N: MOV RAX,R9 ; Offset of the name in .shstrtab.
ADD EAX,[FaOfShstrtabData]
CMP RAX,[InputSize]
JNB .F9:
PUSH RSI
LEA RSI,[R8+RAX]
JMP .M5:
.R: MOV EAX,[SectionNumber] ; ELF section number.
StoD RDI
INCD [SectionNumber]
RET
.r: MOV EAX,[SymbolNumber] ; ELF symbol number.
StoD RDI
INCD [SymbolNumber]
RET
.G: MOV RAX,R9 ; ELF file type.
PUSH RSI
Dispatch AX,0N1,0N2,0N3
StoD RDI
JMP .M8:
.0N1: LEA RSI,[=B'relocatable, linkable']
JMP .M5:
.0N2: LEA RSI,[=B'executable']
JMP .M5:
.0N3: LEA RSI,[=B'shared object']
JMP .M5:
.U: MOV RAX,R9 ; Symbol's section number | type.
PUSH RSI
LEA RSI,[=B'absolute']
CMP AX,0xFFF1
JE .M5:
LEA RSI,[=B'common']
CMP AX,0xFFF2
JE .M5:
POP RSI
MOVB [RDI],'#'
INC RDI
StoD RDI
RET
.M: MOV RAX,R9 ; ELF machine type.
PUSH RSI
Dispatch AX,0n03,0n62
StoD RDI
JMP .M8:
.0n03:LEA RSI,[=B'I386']
JMP .M5:
.0n62:LEA RSI,[=B'AMD64']
.M5: LODSB
CMP AL,0
JE .M8:
STOSB
JMP .M5:
.M8: POP RSI
RET
.Z: PUSH RSI ; ELF relocation type.
MOV AL,R9L
Dispatch AL,00,01,02,05,06,07,08,10
PUSH RAX
MOV EAX,'Type'
STOSD
MOV AL,' '
STOSB
POP RAX
StoD
POP RSI
RET
.01: LEA RSI,[=B'Absolute QWORD']
JSt [Status::],ArgWidth64,.M5:
LEA RSI,[=B'Absolute DWORD']
JMP .M5:
.02: LEA RSI,[=B'Relative DWORD']
JMP .M5:
.08: LEA RSI,[=B'Relative QWORD']
JSt [Status::],ArgWidth64,.M5:
JMP .02:
.10: LEA RSI,[=B'Absolute DWORD']
JSt [Status::],ArgWidth64,.M5:
LEA RSI,[=B'GOTPC DWORD']
JMP .M5:
.00:
.05: LEA RSI,[=B'Copy']
JMP .M5:
.06:
.07: LEA RSI,[=B'JMP_SLOT']
JMP .M5:
.P: MOV RAX,R9 ; ELF "program" type.
PUSH RSI
Dispatch EAX,0d,1d,2d,3d,4d,6d
JMP .M8:
.0d: LEA RSI,[=B'null']
JMP .P5:
.1d: LEA RSI,[=B'load']
JMP .P5:
.2d: LEA RSI,[=B'dynamic']
JMP .P5:
.3d: LEA RSI,[=B'interpreter']
JMP .P5:
.4d: LEA RSI,[=B'note']
JMP .P5:
.6d: LEA RSI,[=B'program header']
;JMP .P5:
.P5: JMP .M5:
.S: PUSH RSI ; ELF section type.
PUSH RDI
LEA RDI,[ElfSegmentTypes]
XOR EAX,EAX
MOV ECX,-1
.S2: CMP R9L,0
JBE .S3:
DEC R9D
REPNE SCASB
JMP .S2:
.S3: MOV RSI,RDI
POP RDI
JMP .M5:
.s: PUSH RSI ; ELF symbol info.
MOV AL,R9L
SHR AL,4
LEA RSI,[=B'Global ']
CMP AL,1
JE .s2:
LEA RSI,[=B'Weak ']
CMP AL,2
JE .s2:
LEA RSI,[=B'Local ']
.s2: LODSB
CMP AL,0
JE .s3:
STOSB
JMP .s2:
.s3: MOV AL,R9L
AND AL,0x0F
LEA RSI,[=B'dataobject']
CMP AL,1
JE .M5:
LEA RSI,[=B'function']
CMP AL,2
JE .M5:
LEA RSI,[=B'section']
CMP AL,3
JE .M5:
LEA RSI,[=B'file']
CMP AL,4
JE .M5:
LEA RSI,[=B'pointer']
JMP .M5:
.Q: TEST R9L,4 ; ELF program flags.
JZ .Q2:
MOV EAX,'read'
STOSD
MOV AL,'|'
STOSB
.Q2: TEST R9L,2
JZ .Q3:
MOV EAX,'writ'
STOSD
MOV AX,'e|'
STOSW
.Q3: TEST R9L,1
JZ .Q4:
MOV EAX,'exec'
STOSD
MOV EAX,'ute|'
STOSD
.Q4: DEC RDI ; Rollback the final '|'.
RET
.q: CMP R9L,0 ; ELF section flags.
JNE .q1:
MOV EAX,'none'
STOSD
RET
.q1: TEST R9L,2
JZ .q2:
MOV EAX,'read'
STOSD
MOV AL,'|'
STOSB
.q2: TEST R9L,1
JZ .q3:
MOV EAX,'writ'
STOSD
MOV AX,'e|'
STOSW
.q3: TEST R9L,4
JZ .q4:
MOV EAX,'exec'
STOSD
MOV EAX,'ute|'
STOSD
.q4: DEC RDI
RET
.y: PUSH RSI ; ELF32 dynamic.
MOV EAX,R9D
CMP EAX,0x6FFF_FFFA
LEA RSI,[=B'RELCOUNT (number of REL)']
JE .y3:
CMP EAX,0x6FFF_FFF9
LEA RSI,[=B'RELACOUNT (number of RELA)']
JE .y3:
CMP EAX,0x6FFF_FFFB
LEA RSI,[=B'FLAGS_1']
JE .y3:
CMP EAX,0x6FFF_FEF5
LEA RSI,[=B'GNU_HASH']
JE .y3:
CMP EAX,31
JAE .y4:
MOV EDX,EAX
MOV RCX,-1
XOR EAX,EAX
PUSH RDI
LEA RDI,[ElfDynamic::]
.y1: TEST EDX
JZ .y2:
REPNE SCASB
DEC EDX
JMP .y1:
.y2: MOV RSI,RDI
POP RDI
.y3: LODSB
CMP AL,0
JE .y5:
STOSB
JMP .y3:
.y4: MOVD [RDI],'Tag '
ADD RDI,4
StoH RDI,Size=8
MOV AL,'h'
STOSB
.y5: MOV AX,': '
STOSW
JSt [Status::],ArgWidth64,.y6:
MOV RAX,R9
SHR RAX,32
StoH RDI,Size=8
JMP .y7:
.y6: MOV EDX,[RBX+VIEW_INDEX.FA]
MOV RAX,[R8+RDX+8]
StoH RDI,Size=16
.y7: MOV AX,'h='
STOSW
JSt [Status::],ArgWidth64,.y8:
MOV RAX,R9
SHR RAX,32
JMP .y9:
.y8: MOV EDX,[RBX+VIEW_INDEX.FA]
MOV RAX,[R8+RDX+8]
.y9: StoD
POP RSI
RET
.T: MOV RAX,R9 ; Store datetime as yyyy/mm/dd hh:mm:ss.
.T1: Time1970 RAX,RDI ; Use macro from time.htm.
ADD RDI,19
RET
.L: PUSH RSI
LEA RSI,[R8+RDX]
LodD
POP RSI
JMP .T1:
.I: MOV RAX,R9 ; LIBCOF import type.
SHR EAX,2
PUSH RSI
LEA RSI,[=B'BY_ORDINAL']
CMP AL,0
JE .I5:
LEA RSI,[=B'Import name=public name']
CMP AL,1
JE .I5:
LEA RSI,[=B'Import name=public name without prefix']
CMP AL,2
JE .I5:
LEA RSI,[=B'Import name=public name undecorated']
CMP AL,3
JNE .I8:
.I5: LODSB
CMP AL,0
JE .I8:
STOSB
JMP .I5:
.I8: POP RSI
RET
.O: PUSH RSI ; OMF record type.
MOV RAX,R9
Dispatch AL,0F0h,0F1h
SHR EAX,1
Dispatch AL,40h,41h,44h,45h,46h,47h,48h,4Ah,4Bh,4Ch,4Dh,4Eh, \
50h,51h,58h,59h,5Ah,5Bh,5Ch,5Eh,61h,62h,63h,64h,65h
MOVZXB EAX,R9L ; Restore AL with record name and
StoH,Size=2 ; display it as hexadecimal byte,
MOV AL,'h' ; when it was unrecognized.
STOSB
POP RSI
RET
.40h: LEA RSI,[=B'THEADR']
JMP .O2:
.41h: LEA RSI,[=B'LHEADR']
JMP .O2:
.44h: LEA RSI,[=B'COMENT']
JMP .O2:
.45h: LEA RSI,[=B'MODEND']
JMP .O2:
.46h: LEA RSI,[=B'EXTDEF']
JMP .O2:
.47h: LEA RSI,[=B'TYPDEF']
JMP .O2:
.48h: LEA RSI,[=B'PUBDEF']
JMP .O2:
.4Ah: LEA RSI,[=B'LINNUM']
JMP .O2:
.4Bh: LEA RSI,[=B'LNAMES']
JMP .O2:
.4Ch: LEA RSI,[=B'SEGDEF']
JMP .O2:
.4Dh: LEA RSI,[=B'GRPDEF']
JMP .O2:
.4Eh: LEA RSI,[=B'FIXUPP']
JMP .O2:
.50h: LEA RSI,[=B'LEDATA']
JMP .O2:
.51h: LEA RSI,[=B'LIDATA']
JMP .O2:
.58h: LEA RSI,[=B'COMDEF']
JMP .O2:
.59h: LEA RSI,[=B'BAKPAT']
JMP .O2:
.5Ah: LEA RSI,[=B'LEXTDEF']
JMP .O2:
.5Bh: LEA RSI,[=B'LPUBDEF']
JMP .O2:
.5Ch: LEA RSI,[=B'LCOMDEF']
JMP .O2:
.5Eh: LEA RSI,[=B'CEXTDEF']
JMP .O2:
.61h: LEA RSI,[=B'COMDAT']
JMP .O2:
.62h: LEA RSI,[=B'LINSYM']
JMP .O2:
.63h: LEA RSI,[=B'ALIAS']
JMP .O2:
.64h: LEA RSI,[=B'NBKPAT']
JMP .O2:
.65h: LEA RSI,[=B'LLNAMES']
JMP .O2:
.0F0h:LEA RSI,[=B'LIBHDR']
JMP .O2:
.0F1h:LEA RSI,[=B'LIBEND']
;JMP .O2:
.O2: LODSB
CMP AL,0
JE .O3:
STOSB
JMP .O2:
.O3: TEST R9L,1
JZ .O9:
MOV AX,'32'
STOSW
.O9: POP RSI
RET
.$: MOV RAX,[8*RCX+FnTable] ; Fn marker. Call a function from FnTable.
MOV RCX,R9
PUSH RSI
CALL RAX
POP RSI
RET
.0x00:MOV EAX,0x0A0D
STOSD
RET
ENDP ExpandRem
The input file loaded to memory and mapped between [InputPtr]..[InputEnd] is analyzed by one of
Format*** procedures (its address is stored in [FormatProcPtr]).
In Phase One this OS-independent procedure converts the input to VIEW_INDEX structures, which will be written to FileIndex using
CALL SaveViewIndex::.
SaveViewIndex:: is a global procedure defined in modules for
Windows or for
Linux.
In Phase Two the procedure ViewCreate uses the sorted indexes to generate an output listing.
Caller of this procedure then calls ViewEpilogue for Windows or Linux which should close+reopen IndexFile and OutputFile.
ViewCreate:: PROC
MOV EDX,[ArgFileFormat::] ; Nonzero ordinal.
ff %FOR %FileFormats ; Enumeration declared in argument.htm
.
LEA RAX,[Format%ff]
CMP EDX,ArgFileFormat%ff
JE .02:
%ENDFOR ff
LEA RAX,[FormatBIN]
.02:MOV [FormatProcPtr],RAX
LEA RBX,[ViewIndex] ; Working variable in the form VIEW_INDEX.
MOV R8,[InputPtr] ; Start of input file loaded in memory. Phase One begins.
CALL [FormatProcPtr] ; Call FormatMZ, FormatCOFF32 etc. to write the index file.
LEA RBX,[ViewIndex] ; Add padding at the end of VIEW_INDEX array.
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
MOV EAX,[InputSize]
MOV [RBX+VIEW_INDEX.FA],EAX
MOV [RBX+VIEW_INDEX.Size],0
CALL SaveViewIndex::
CALL [FileIndexReopenProc] ; From viewwing.htm
or from viewling.htm
. Returns the contents in RDI,RAX.
MOV [IndexPtr],RDI ; Beginning of array of indexes VIEW_INDEX.
LEA RCX,[RDI+RAX] ; End of the array.
MOV [IndexEnd],RCX
SHR EAX,4 ; SIZE# VIEW_INDEX=16. RAX is now the number of indexes.
ShellSort RDI,RAX,16,ByLevel
SAL RAX,4
LEA RBX,[RDI+RAX-2*16] ; RBX=the last but one VIEW_INDEX.
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[RBX+VIEW_INDEX.Size]
ADD EAX,EDX
MOV ECX,[InputSize]
SUB ECX,EAX
JZ .05:
ADD RBX,16 ; RBX=the last VIEW_INDEX.
MOV [RBX+VIEW_INDEX.FA],EAX
MOV [RBX+VIEW_INDEX.Size],ECX
.05:MOV RBX,RDI ; Pointer to an array of VIEW_INDEXes is now in RBX.
.10:; Phase Two. Convert each VIEW_INDEX record RBX to a listing line(s) and write it to the listing in FileOutput.
CMP RBX,[IndexEnd]
JNB .90: ; Jump when all VIEW_INDEX are converted.
; Look at the previous VIEW_INDEX if there's a gap.
LEA RDI,[RBX-SIZE# VIEW_INDEX] ; RDI=Previous index.
CMP RDI,[IndexPtr]
JNA .40:
MOV EDX,[RDI+VIEW_INDEX.Size]
ADD EDX,[RDI+VIEW_INDEX.FA] ; EDX=FA of the end of the previous object.
MOV ECX,[RBX+VIEW_INDEX.FA] ; ECX=FA of the beginning of this object.
SUB ECX,EDX
JBE .40:
; There is ECX bytes of unassigned alignment between objects. Create listing lines for them.
MOV R13,RCX ; Amount of alignment bytes (may be over 16).
MOV R14,RDX ; FA of alignment bytes mapped in memory.
.18:LEA RDI,[WorkMemory]
MOV AL,'|'
STOSB
MOV RAX,R14
StoH RDI,Size=R15
MOV AL,':'
STOSB
XOR EAX,EAX
XOR EDX,EDX
LEA RSI,[R8+R14]
MOV ECX,R13D
CMP ECX,16
JBE .20:
MOV ECX,16
.20:JRCXZ .30:
.24:TEST DL,0000_0011b
JNZ .28:
TEST EDX
JZ .28:
MOV AL,' '
STOSB
.28:LODSB
StoH RDI,Size=2
INC EDX
LOOP .24:
.30:LEA RCX,[WorkMemory+37] ; Fixed end of hexadecimal data.
ADD RCX,R15 ; Respect the variable number of address digits in R15.
SUB RCX,RDI
JNA .34:
MOV AL,' '
REP STOSB
.34:LEA RSI,[=B'| alignment']
MOV ECX,11
REP MOVSB
MOV EAX,0x0A0D
STOSD
LEA RSI,[WorkMemory]
GetLength$ RSI ; Get the size of the entire line to RCX.
CALL [FileWriteOutputProc] ; Call the procedure from viewwing.htm
or from viewling.htm
.
MOV ECX,R13D
CMP ECX,16
JBE .38:
MOV ECX,16
.38:ADD R14,RCX
SUB R13,RCX
JA .18:
.40:; There is no gap. Continue.
MOV R15D,[AddressDigits] ; 4..12 depending on the input file size.
MOV R14D,[RBX+VIEW_INDEX.FA]
MOV R13D,[RBX+VIEW_INDEX.Size]
MOV EDX,R13D
SHR EDX,28 ; EDX=level 0..4.
JZ .Level0:
; VIEW_INDEX at RBX represents a colourful LevelX line (X=1,2,3,4).
LEA RDI,[WorkMemory] ; Listing line will be constructed in WorkMemory.
MOV AL,'|' ; The first character in each listing line.
STOSB
MOV AL,'#' ; # is the level marker.
MOV ECX,EDX
REP STOSB
NEG RDX
LEA RCX,[RDX+13] ; Let ECX=number of separating spaces in the colourful listing line.
MOV AL,' '
REP STOSB
MOV EAX,R14D ; VIEW_INDEX.FA
StoH RDI,Size=R15 ; Store file-address range.
MOV AX,'..'
STOSW
MOV ECX,0x0FFF_FFFF ; VIEW_INDEX.Size mask.
AND ECX,R13D
LEA RAX,[R14+RCX-1]
StoH RDI,Size=R15
MOV AL,' '
STOSB
LEA RCX,[R15+WorkMemory+38] ; Fixed position in the line where the remark begins.
SUB RCX,RDI
JNA .47:
CMP ECX,64
JA .90:
MOV AL,'#'
REP STOSB ; Fill the gap with variable number of #.
MOV AL,' '
STOSB
MOV ESI,[RBX+VIEW_INDEX.Rem]
PUSH RSI,RDI ; A hack for ELF section contents.
LEA RDI,[=B'Contents of section #']
MOV ECX,21
REPE CMPSB
JNE .44:
MOVD [SymbolNumber::],0 ; Clear the symbol number counter when a new section begins.
.44:POP RDI,RSI
.47:MOV R12,[RBX+VIEW_INDEX.Rem]
CALL ExpandRem: ; Expand !x parameters, add CR+LF+NULL.
LEA RSI,[WorkMemory]
GetLength$ RSI
CALL [FileWriteOutputProc] ; Call the procedure from viewwing.htm
or from viewling.htm
.
ADD RBX,SIZE# VIEW_INDEX
JMP .10: ; The next listing line.
.Level0: ; VIEW_INDEX at RBX represents a gray Level0 line,
MOV R12,[RBX+VIEW_INDEX.Rem] ; or more Level0 lines when RBX+VIEW_INDEX.Size is above 16.
MOV R13D,[RBX+VIEW_INDEX.Size]
MOV R14D,[RBX+VIEW_INDEX.FA]
TEST R13
JZ .85:
.50:LEA RDI,[WorkMemory] ; Print |file_address: R14 at the beginning of WorkMemory.
MOV AL,'|'
STOSB
MOV RAX,R14
StoH RDI,Size=R15
MOV AL,':'
STOSB
XOR EAX,EAX
XOR EDX,EDX
LEA RSI,[R8+R14]
MOV ECX,R13D
CMP ECX,16
JBE .57:
MOV ECX,16
.57:JRCXZ .70:
.60:TEST DL,0000_0011b
JNZ .63:
TEST EDX
JZ .63:
MOV AL,' '
STOSB ; Insert a space after each four hexa bytes.
.63:LODSB
StoH RDI,Size=2
INC EDX
LOOP .60:
.70:LEA RCX,[WorkMemory+37] ; Fixed end of hexadecimal data.
ADD RCX,R15 ; Respect the variable number of address digits in R15.
SUB RCX,RDI
JNA .75:
MOV AL,' '
REP STOSB
.75:MOV AX,'| '
STOSW ; Terminate the dump column.
CALL ExpandRem ; Print the remark, if any, with expanded !variables.
LEA RSI,[WorkMemory]
GetLength$ RSI ; Get the size of the entire line to RCX.
CALL [FileWriteOutputProc] ; Call the procedure from viewwing.htm
or from viewling.htm
.
MOV ECX,R13D
CMP ECX,16
JBE .80:
MOV ECX,16
.80:ADD R14,RCX
SUB R13,RCX
JA .50:
.85:ADD RBX,SIZE# VIEW_INDEX
JMP .10:
.90:RET
ENDP ViewCreate
Undetected binary file format which EuroView does not know. It will be displayed as hexadecimal dump.
FormatBIN:: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format BIN "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
RET
ENDP FormatBIN
Image file format.
FormatBMP PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format BMP "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"BMP file header"
MOV [RBX+VIEW_INDEX.Size],14+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Signature !2X"
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Size of the file: !4Hh=!4D"
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Application specific data"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"FA of bitmap data: !4Hh=!4D"
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[R8+RDX]
SUB EAX,36h
JB .20:
MOV [PaletteSize],EAX
.20:CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"DIB header"
MOV [RBX+VIEW_INDEX.Size],4+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Size of DIB header:!4Hh=!4D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Width: !4Hh=!4D px"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Height: !4Hh=!4D px"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of color planes: !2D"
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of bits per pixel: !2D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Compression: !4D"
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Size of data: !4Hh=!4D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Horizontal print resolution: !4Hh=!4D px/m"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Vertical print resolution: !4Hh=!4D px/m"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of colors in the palette: !4D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Important colors (0=all): !4D"
CALL SaveViewIndex::
MOV ECX,[PaletteSize]
JRCXZ .50:
MOV [RBX+VIEW_INDEX.Rem],=B"Palette"
OR ECX,Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CALL SaveViewIndex::
.50:MOV [RBX+VIEW_INDEX.Rem],=B"Bitmap data"
MOV RCX,[InputSize::]
SUB ECX,[PaletteSize]
ADD ECX,Level1-36h
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CALL SaveViewIndex::
RET
ENDP FormatBMP
Cursor file format.
FormatCUR PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format CUR "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Icon directory"
MOV [RBX+VIEW_INDEX.Size],6+Level3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Cursor file signature"
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of images: !2D"
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW ECX,[R8+RDX]
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
TEST RCX
JZ .90:
.30:PUSH RCX
MOV [RBX+VIEW_INDEX.Rem],=B"Image #!18$"
MOV [RBX+VIEW_INDEX.Size],16+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image width: !1D"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image height: !1D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of colors in palette: !1D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Unused"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Horizontal position of hotspot: !1D"
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Vertical position of hotpost: !1D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image data size: !4Hh=!4D"
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"FA of image data: !4Hh=!4D"
CALL SaveViewIndex::
POP RCX
DEC RCX
JNZ .30:
MOV [RBX+VIEW_INDEX.Rem],=B"Data of images"
MOV RAX,[InputSize::]
MOV EDX,[RBX+VIEW_INDEX.FA]
SUB EAX,EDX
JNA .90:
OR EAX,Level1
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
CALL SaveViewIndex::
.90:RET
ENDP FormatCUR
16bit linkable file format.
FormatCOFF16: PROC
SetSt [Status::],ArgWidth16
JMP AnalyzeCOFF
ENDP FormatCOFF16
32bit linkable file format.
FormatCOFF32: PROC
SetSt [Status::],ArgWidth32
JMP AnalyzeCOFF
ENDP FormatCOFF32
64bit linkable file format.
FormatCOFF64 PROC
SetSt [Status::],ArgWidth64
JMP AnalyzeCOFF
ENDP FormatCOFF64
32bit dynamic library file format.
FormatDLL32 PROC
SetSt [Status::],ArgWidth32+ArgDynamicLibrary
JMP AnalyzePE
ENDP FormatDLL32
64bit dynamic library file format.
FormatDLL64 PROC
SetSt [Status::],ArgWidth64+ArgDynamicLibrary
JMP AnalyzePE
ENDP FormatDLL64
32bit linkable module format.
FormatELF32 PROC
SetSt [Status::],ArgWidth32
MOV [RBX+VIEW_INDEX.Rem],=B'Format ELF32 "!14$" size=!24$'
.Common:
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CALL AnalyzeElfFileHeader
MOV ECX,[NrOfElfProgramHeaders]
JRCXZ .20:
CMP ECX,32
JNBE .90:
MOV EAX,[FaOfElfProgramHeaders]
CMP RAX,[InputSize::]
JNB .90:
MOV [RBX+VIEW_INDEX.FA],EAX
.10:PUSH RCX
CALL AnalyzeElfProgramHeader
POP RCX
LOOP .10:
.20:MOV ECX,[NrOfElfSectionHeaders]
JRCXZ .90:
CMP ECX,64
JNB .90:
MOV EAX,[FaOfElfSectionHeaders]
CMP RAX,[InputSize::]
JNB .90:
MOV [RBX+VIEW_INDEX.FA],EAX
.30:PUSH RCX
JSt [Status::],ArgWidth64, .40:
CALL AnalyzeElfSectionHeader32
JMP .50:
.40: CALL AnalyzeElfSectionHeader64
.50:POP RCX
LOOP .30:
.90:RET
ENDP FormatELF32
64bit linkable module format.
FormatELF64 PROC
SetSt [Status::],ArgWidth64
MOV [RBX+VIEW_INDEX.Rem],=B'Format ELF64 "!14$" size=!24$'
JMP FormatELF32.Common:
ENDP FormatELF64
32bit shared object library format.
FormatELFSO32 PROC
SetSt [Status::],ArgWidth32+ArgDynamicLibrary
MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFSO32 "!14$" size=!24$'
JMP FormatELF32.Common:
ENDP FormatELFSO32
64bit shared object library format.
FormatELFSO64 PROC
SetSt [Status::],ArgWidth64+ArgDynamicLibrary
MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFSO64 "!14$" size=!24$'
JMP FormatELF32.Common:
ENDP FormatELFSO64
32bit executable file format.
FormatELFX32 PROC
SetSt [Status::],ArgWidth32
MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFX32 "!14$" size=!24$'
JMP FormatELF32.Common:
ENDP FormatELFX32
64bit executable file format.
FormatELFX64 PROC
SetSt [Status::],ArgWidth64
MOV [RBX+VIEW_INDEX.Rem],=B'Format ELFX64 "!14$" size=!24$'
JMP FormatELF32.Common:
ENDP FormatELFX64
Image file format.
FormatGIF PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format GIF "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"GIF Signature"
MOV [RBX+VIEW_INDEX.Size],6+Level3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"!6X"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Screen description"
MOV [RBX+VIEW_INDEX.Size],7+Level3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Screen width: !2D"
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Screen height: !2D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Global color table size: !23$"
MOV [RBX+VIEW_INDEX.Size],1
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV CL,[R8+RDX]
XOR EAX,EAX
TEST CL,0x80
JZ .20:
AND CL,0x07
INC CL
INC EAX
SHL EAX,CL
LEA EAX,[EAX+2*EAX]
.20:MOV [SizeOfColorTable],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Background color: !1Hh"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Pixel aspect ratio: !1D"
CALL SaveViewIndex::
MOV ECX,[SizeOfColorTable]
JRCXZ .30:
MOV [RBX+VIEW_INDEX.Rem],=B"Global color table RGB"
OR ECX,Level3
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CALL SaveViewIndex::
.30:MOV EDX,[RBX+VIEW_INDEX.FA]
MOV AX,[R8+RDX]
CMP AL,0x2C
JE .0x2C:
Dispatch AX,0xFF21,0xFE21,0xF921
JMP .80:
.0x2C:
MOV [RBX+VIEW_INDEX.Rem],=B"Image descriptor"
MOV [RBX+VIEW_INDEX.Size],1+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Descriptor identifier"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image left position: !2Hh=!2D"
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image top position: !2Hh=!2D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image width: !2Hh=!2D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image height: !2Hh=!2D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Color table size: !23$"
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV CL,[R8+RDX]
XOR EAX,EAX
TEST CL,0x80
JZ .35:
AND CL,0x07
INC CL
INC EAX
SHL EAX,CL
LEA EAX,[EAX+2*EAX]
.35:MOV [SizeOfColorTable],EAX
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV ECX,[SizeOfColorTable]
TEST ECX
JZ .30:
MOV [RBX+VIEW_INDEX.Rem],=B"Color table RGB"
OR ECX,Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CALL SaveViewIndex::
JMP .30:
.0xFF21:
MOV [RBX+VIEW_INDEX.Rem],=B"Application extension"
MOV [RBX+VIEW_INDEX.Size],2+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Extension identifier"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Application owner: !12X"
MOV [RBX+VIEW_INDEX.Size],12
CALL SaveViewIndex::
.40:MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB ECX,[R8+RDX] ; Data subblock size.
JRCXZ .45:
MOV [RBX+VIEW_INDEX.Rem],=B"Data block size: !1D"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Data block body"
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
JMP .40:
.45:MOV [RBX+VIEW_INDEX.Rem],=B"Data block terminator"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
JMP .30:
.0xF921:
MOV [RBX+VIEW_INDEX.Rem],=B"Graphic control extension"
MOV [RBX+VIEW_INDEX.Size],2+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Extension identifier"
CALL SaveViewIndex::
.50:MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB ECX,[R8+RDX] ; Data subblock size.
JRCXZ .55:
MOV [RBX+VIEW_INDEX.Rem],=B"Data block size: !1D"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Data block body"
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
JMP .50:
.55:MOV [RBX+VIEW_INDEX.Rem],=B"Data block terminator"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
JMP .30:
.0xFE21:
MOV [RBX+VIEW_INDEX.Rem],=B"Comment extension"
MOV [RBX+VIEW_INDEX.Size],2+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Extension identifier"
CALL SaveViewIndex::
.60:MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB ECX,[R8+RDX] ; Data subblock size.
JRCXZ .65:
MOV [RBX+VIEW_INDEX.Rem],=B"Data block size: !1D"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"!X"
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
JMP .60:
.65:MOV [RBX+VIEW_INDEX.Rem],=B"Data block terminator"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
JMP .30:
.80:MOV [RBX+VIEW_INDEX.Rem],=B"Image data"
MOV RCX,[InputSize::]
MOV EDX,[RBX+VIEW_INDEX.FA]
SUB ECX,EDX
OR ECX,Level1
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"!X"
CALL SaveViewIndex::
RET
ENDP FormatGIF
Image file format.
FormatICO PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format ICO "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Icon directory"
MOV [RBX+VIEW_INDEX.Size],6+Level3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Icon file signature"
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of images: !2D"
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW ECX,[R8+RDX]
; MOV [NrOfSections],ECX
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
TEST RCX
JZ .90:
.30:PUSH RCX
MOV [RBX+VIEW_INDEX.Rem],=B"Image #!18$"
MOV [RBX+VIEW_INDEX.Size],16+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image width: !1D"
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image height: !1D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of colors in palette: !1D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Unused"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Number of color planes: !1D"
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Bits per pixel: !1D"
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"Image data size: !4Hh=!4D"
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B"FA of image data: !4Hh=!4D"
CALL SaveViewIndex::
POP RCX
DEC RCX
JNZ .30:
MOV [RBX+VIEW_INDEX.Rem],=B"Data of images"
MOV RAX,[InputSize::]
MOV EDX,[RBX+VIEW_INDEX.FA]
SUB EAX,EDX
JNA .90:
OR EAX,Level1
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
CALL SaveViewIndex::
.90:RET
ENDP FormatICO
Image file format.
FormatJPG: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format JPG "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize]
MOV EDX,ECX
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Segment EOI: End of image'
SUB EDX,2
MOV [RBX+VIEW_INDEX.FA],EDX
MOV [RBX+VIEW_INDEX.Size],2+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.FA],0
.10:MOV EDX,[RBX+VIEW_INDEX.FA]
ADD RDX,R8
LEA RAX,[RDX+2]
CMP RAX,[InputEnd]
JNB .90:
MOVZXW EAX,[RDX] ; Load the marker.
CMP AL,0xFF
JE .20:
MOV [RBX+VIEW_INDEX.Rem],=B'!X' ; It was not a marker. Dump until EOI.
MOV RCX,[InputEnd]
SUB RCX,2
SUB RCX,RDX
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
JMP .90:
.20:MOVZX EDX,AH ; AL=0xFF, DL=marker identifier.
Dispatch DL,0xD8,0xD9 ; Markers FFD0..FFD9 are without payload. Their size is 0.
CMP DL,0xD0
JB .30:
CMP DL,0xD7
JA .30:
AND DL,0x07 ; Marker 0xFFDn - restart n
OR DL,'0'
MOV [ACharacter],DL
MOV [RBX+VIEW_INDEX.Rem],=B'Segment RST!1A: Restart'
MOV [RBX+VIEW_INDEX.Size],2+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
CALL SaveViewIndex::
JMP .10:
.0xD8:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOI: Start of image'
MOV [RBX+VIEW_INDEX.Size],2+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
CALL SaveViewIndex::
JMP .10:
.0xD9:MOV [RBX+VIEW_INDEX.Rem],=B'Segment EOI: End of image'
MOV [RBX+VIEW_INDEX.Size],2+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
CALL SaveViewIndex::
JMP .10:
.30: ; Other markers are followed by variable size in two big endian bytes. DL=marker identifier.
CMP DL,0xE0
JB .40:
CMP DL,0xEF
JA .40:
; FFE0..FFEF are application-specific segment markers.
MOV [RBX+VIEW_INDEX.Rem],=B'Segment APP!2A: Application-specific'
JMP .50:
.40:Dispatch DL,0xC0,0xC2,0xC4,0xDA,0xDB,0xDD,0xFE
MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
JMP .50:
.0xC0:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOF0: Start of frame baseline transform'
JMP .50:
.0xC2:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOF2: Start of frame progressive transform'
JMP .50:
.0xC4:MOV [RBX+VIEW_INDEX.Rem],=B'Segment DHT: Define Huffman tables'
JMP .50:
.0xDA:MOV [RBX+VIEW_INDEX.Rem],=B'Segment SOS: Start of scan'
JMP .50:
.0xDB:MOV [RBX+VIEW_INDEX.Rem],=B'Segment DQT: Define quantization tables'
JMP .50:
.0xDD:MOV [RBX+VIEW_INDEX.Rem],=B'Segment DRI: Define restart interval'
JMP .50:
.0xFE:MOV [RBX+VIEW_INDEX.Rem],=B'Segment COM: Comment'
;JMP .50:
.50:MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW ECX,[R8+RDX+2]
XCHG CH,CL
LEA EDX,[RCX-2] ; Keep netto size in EDX.
ADD ECX,2
OR ECX,Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Marker !2B'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size !2Bh=!2b'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
MOV [RBX+VIEW_INDEX.Size],EDX
CALL SaveViewIndex::
JMP .10:
.90:RET
ENDP FormatJPG
Library of COFF modules file format.
FormatLIBCOF: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format LIBCOF "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Archive signature !7X'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
CALL AnalyzeLibcofMemberHeader
MOV [RBX+VIEW_INDEX.Rem],=B'Linker 1st header'
MOV EAX,[MemberSize]
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
CALL AnalyzeLibcofMemberHeader
MOV [RBX+VIEW_INDEX.Rem],=B'Linker 2nd header'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[MemberSize]
MOV ECX,EAX
ADD ECX,EDX
MOV [FaOfSymbolEnd],ECX
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'File addresses of !4D members'
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOV EAX,[R8+RDX]
LEA EAX,[4*EAX+4+Level1]
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of members: !4D'
MOV [RBX+VIEW_INDEX.Size],4
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV [FaOfMembersTable],EDX
CMP RDX,[InputSize::]
JNB .90:
MOV ECX,[R8+RDX]
CALL SaveViewIndex::
CMP ECX,65000
JNB .90:
JRCXZ .30:
.20:MOV [RBX+VIEW_INDEX.Rem],=B'Member #!18$ at !4Hh: !16$'
CALL SaveViewIndex::
LOOP .20:
.30:MOV [RBX+VIEW_INDEX.Rem],=B'Indexes of !4D symbols'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[R8+RDX]
MOV ECX,EAX
LEA EAX,[2*EAX+4]
ADD EDX,EAX
MOV [FaOfArchiveStrings],EDX
ADD EAX,Level1
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of symbols: !4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
JRCXZ .50:
MOV [RBX+VIEW_INDEX.Size],2
.40:MOV [RBX+VIEW_INDEX.Rem],=B'Symbol in member #!2D: !17$' ; Fn17$DisplaySymbolName
CALL SaveViewIndex::
LOOP .40:
.50:MOV [RBX+VIEW_INDEX.Rem],=B'String table'
MOV EAX,[FaOfSymbolEnd]
SUB EAX,[RBX+VIEW_INDEX.FA]
OR EAX,Level1
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
CALL AnalyzeLibcofMemberHeader
MOV [RBX+VIEW_INDEX.Rem],=B'Longnames header'
MOV EAX,[MemberSize]
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
MOV EDX,[FaOfMembersTable]
LEA RSI,[R8+RDX]
LODSD ; Number of members.
MOV ECX,EAX
.60:PUSH RCX
LODSD
PUSH RSI
MOV [RBX+VIEW_INDEX.FA],EAX
LEA EDX,[EAX+60] ; FA of Short import header or COFF file header.
MOV EAX,[R8+RDX]
CMP EAX,0xFFFF_0000
JNE .70:
CALL AnalyzeLibcofMemberHeader
CALL AnalyzeLibcofFileHeader
MOV [RBX+VIEW_INDEX.Rem],=B'Short import body'
JMP .80:
.70: CALL AnalyzeLibcofMemberHeader
CALL AnalyzeCoffFileHeader
MOV [RBX+VIEW_INDEX.Rem],=B'COFF module body'
.80: MOV EAX,[MemberSize]
SUB EAX,20
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
POP RSI
POP RCX
LOOP .60:
.90:RET
ENDP FormatLIBCOF
LIBOMF module file format.
FormatLIBOMF: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format LIBOMF "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
.10:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize]
JNB .90:
CALL AnalyzeOmfRecord
JNZ .10:
; [LastOmfRecord]=LIBEND
MOV [RBX+VIEW_INDEX.Rem],=B'Hashed dictionary'
MOV RCX,[InputSize::]
SUB ECX,[RBX+VIEW_INDEX.FA]
OR ECX,Level3
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
.90:RET
ENDP FormatLIBOMF
Sound file format.
FormatMIDI:: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format MIDI" !14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'MIDI header MThd'
MOV [RBX+VIEW_INDEX.Size],14+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Header marker "!4X"'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Header size !4hh=!4d'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Format !2b'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of tracks !2b'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Ticks per quarter note !2b'
CALL SaveViewIndex::
.30:MOV EDX,[RBX+VIEW_INDEX.FA]
ADD RDX,R8
CMP RDX,[InputEnd]
JNB .90:
CMPD [RDX],'MTrk'
JNE .90:
MOV [RBX+VIEW_INDEX.Rem],=B'MIDI track MTrk'
MOV ECX,[RDX+4]
BSWAP ECX
MOV EDX,ECX
ADD ECX,8
OR ECX,Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Track marker "!4X"'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Track size !4hh=!4d'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'MIDI data'
MOV [RBX+VIEW_INDEX.Size],EDX
CALL SaveViewIndex::
JMP .30:
.90:RET
ENDP FormatMIDI
Sound file format.
FormatMP3:: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format MP3 "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize]
MOV [FaOfSoundEnd],ECX
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex:: ; The entire file.
CMPD [R8],0x03334449 ; ID3v2.
JNE .40: ; ID3 missing, assume sound frames only.
MOV [RBX+VIEW_INDEX.Rem],=B'ID3 TAG version 2'
XOR EDX,EDX ; Compute size of ID3 tag to EDX.
MOV ECX,4
LEA RSI,[R8+6] ; MSB digit of tag size (big endian).
.10:LODSB
SHL EDX,7
OR DL,AL
LOOP .10:
ADD EDX,10
MOV [ID3size],EDX
MOV [FaOfSoundStart],EDX
OR EDX,Level3
MOV [RBX+VIEW_INDEX.Size],EDX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!3X' ; ID3.
MOV [RBX+VIEW_INDEX.Size],10
CALL SaveViewIndex:: ; One ID3 header.
.20:MOV EDX,[RBX+VIEW_INDEX.FA]
MOV ECX,[R8+RDX+4] ; Size of one tag.
BSWAP ECX
TEST ECX
JZ .30:
ADD ECX,10+Level2
MOV [RBX+VIEW_INDEX.Size],ECX
MOV EAX,[R8+RDX+0] ; The tag (four letters).
PUSH .Dispatched: ; Convert the tag from EAX to human-readable at RSI.
Dispatch EAX,'TYER','TALB','TIT2','TPE1','TRCK','TENC','TCOP','TOPE','TCOM','TCON','COMM','WXXX'
LEA RSI,[=B(0)]
RET
.TYER:LEA RSI,[=B'Year']
RET
.TALB:LEA RSI,[=B'Album']
RET
.TIT2:LEA RSI,[=B'Song name']
RET
.TPE1:LEA RSI,[=B'Artist']
RET
.TRCK:LEA RSI,[=B'Track number']
RET
.TENC:LEA RSI,[=B'Encoded by']
RET
.TCOP:LEA RSI,[=B'Frame identifier']
RET
.TOPE:LEA RSI,[=B'Original artist']
RET
.TCOM:LEA RSI,[=B'Composer']
RET
.TCON:LEA RSI,[=B'Genre']
RET
.COMM:LEA RSI,[=B'Comments']
RET
.WXXX:LEA RSI,[=B'URL']
RET
.Dispatched:
MOV [RBX+VIEW_INDEX.Rem],RSI
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
MOV [RBX+VIEW_INDEX.Size],11
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X' ; Value of the tag.
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB ECX,[R8+RDX-4]
JRCXZ .25:
DEC ECX
.25:MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV EAX,[RBX+VIEW_INDEX.FA]
CMP EAX,[ID3size]
JB .20: ; The next ID3 tag.
.30:MOV [RBX+VIEW_INDEX.Rem],=B'Not used'
MOV ECX,[ID3size]
SUB ECX,[RBX+VIEW_INDEX.FA]
JB .90:
OR ECX,Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex:: ; Not used.
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex:: ; Unused bytes in ID3.
; ID3v2 tag is completed.
.40:; Try ID3v1 tag.
MOV RSI,[InputEnd]
SUB RSI,128
MOV EAX,[RSI]
AND EAX,0x00FFFFFF
CMP EAX,'TAG'
JNE .45:
SUB [FaOfSoundEnd],128 ; ID3v1 exists at the last 128 bytes of the file.
MOV [RBX+VIEW_INDEX.Rem],=B'ID3 TAG version 1'
MOV [RBX+VIEW_INDEX.Size],128+Level3
MOV RAX,RSI
SUB RAX,R8
MOV [RBX+VIEW_INDEX.FA],EAX
CALL SaveViewIndex:: ; ID3 TAG version 1, Level2
MOV [RBX+VIEW_INDEX.Rem],=B'TAG'
MOV [RBX+VIEW_INDEX.Size],3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Song name'
MOV [RBX+VIEW_INDEX.Size],30+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Artist'
MOV [RBX+VIEW_INDEX.Size],30+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Album'
MOV [RBX+VIEW_INDEX.Size],30+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Year'
MOV [RBX+VIEW_INDEX.Size],4+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Comment'
MOV [RBX+VIEW_INDEX.Size],30+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Genre'
MOV [RBX+VIEW_INDEX.Size],1+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
.45:MOV [RBX+VIEW_INDEX.Rem],=B'Entire sound content'
MOV ECX,[FaOfSoundEnd]
MOV EDX,[FaOfSoundStart]
MOV [RBX+VIEW_INDEX.FA],EDX
SUB ECX,EDX
OR ECX,Level3
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex:: ; Entire cound content. Level3.
AND ECX,0x0FFF_FFFF
LEA RDI,[R8+RDX]
.50:MOV AL,0xFF
REPNE SCASB
JNE .90:
LEA RDX,[RDI-1]
SUB RDX,R8
MOV [RBX+VIEW_INDEX.FA],EDX
MOV AL,[RDI]
AND AL,0xFA ; Accept frame header 0xFFFB or 0xFFFA.
CMP AL,0xFA
JNE .50:
LEA RDX,[RDI-1] ; RDX points to the start of frame 0xFFFBxxyy.
MOV EAX,[RDX]
MOV [MP3frame],EAX ; Store cache of the MP3 frame.
SUB RDX,R8
MOV [RBX+VIEW_INDEX.FA],EDX
.60:MOV [RBX+VIEW_INDEX.Rem],=B'Sound frame 26 ms'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB EAX,[R8+RDX+2] ; The byte which follows 0xFFFB.
MOV ECX,EAX
SHR EAX,4 ; Get bit rate.
JZ .90:
CMP AL,1111b
JE .90:
MOVZXW EDX,[2*EAX+MP3BitrateTable]
MOV EAX,EDX
LEA RDI,[MP3bitrate]
StoD RDI,Size=3
AND ECX,0000_1100b ; Get sample rate.
CMP CL,0000_1100b
JE .90:
MOV EAX,[RCX+MP3SamplerateTable]
MOV ECX,EAX
LEA RDI,[MP3freq]
StoD RDI,Size=5
MOV EAX,144_000 ; Calculate frame length * 1000.
MUL RDX ; 144 * Bitrate in kbps.
DIV RCX ; 144 * Bitrate / Samplerate
MOV EDI,[RBX+VIEW_INDEX.FA] ; FA of byte 0xFF.
BTD [R8+RDI+2],1 ; Query and add the padding bit.
ADC EAX,0
MOV R9D,EAX ; Remember the brutto size of one 26 ms sound frame in R9.
MOV AL,[R8+RDI+3] ; Continue with the construction of MP3report.
SHR AL,6
Dispatch AL,0d,1d,2d
LEA RSI,[=B'mono']
JMPS .70:
.0d:LEA RSI,[=B'stereo']
JMPS .70:
.1d:LEA RSI,[=B'joint stereo']
JMPS .70:
.2d:LEA RSI,[=B'dual sound']
.70:LEA RDI,[MP3channel]
.75:LODSB
STOSB
CMP AL,0
JNZ .75: ; MP3report is constructed.
; Sound frame brutto size is in R9. Look if the last frame is not shorter (if it ends at FaOfSoundEnd).
MOV EDX,[RBX+VIEW_INDEX.FA] ; EDX is FA of the end of frame.
ADD EDX,R9D
SUB EDX,[FaOfSoundEnd]
JBE .80: ; If below, the frame is not shorter. Its size is in R9.
SUB R9D,EDX ; Otherwise decrement the last frame size.
.80:MOV [RBX+VIEW_INDEX.Size],R9D
OR [RBX+VIEW_INDEX.Size],Level1
CALL SaveViewIndex:: ; Level1 Sound frame 26 ms.
LEA RSI,[MP3report]
MOV [RBX+VIEW_INDEX.Rem],RSI ; MP3report is used as remark.
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex:: ; MPEG1 Layer3 xxx bit/s, yyyy Hz, stereo.
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
SUB R9D,4
MOV [RBX+VIEW_INDEX.Size],R9D ; Netto size of this sound frame.
CALL SaveViewIndex:: ; Samples.
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV AX,[R8+RDX]
AND AH,0xFA
CMP AX,0xFAFF
JE .60:
.90:RET
ENDP FormatMP3
16bit DOS executable file format.
FormatMZ:: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format MZ "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CALL AnalyzeMzProgram
RET
ENDP FormatMZ
OMF module file format.
FormatOMF:: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format OMF "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
.10:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
CALL AnalyzeOmfRecord
JMP .10:
.90:RET
ENDP FormatOMF
32bit executable file format.
FormatPE32 PROC
SetSt [Status::],ArgWidth32
JMP AnalyzePE
ENDP FormatPE32
64bit executable file format.
FormatPE64 PROC
SetSt [Status::],ArgWidth64
JMP AnalyzePE
ENDP FormatPE64
Image file format.
FormatPNG: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format PNG "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'PNG signature'
MOV [RBX+VIEW_INDEX.Size],8+Level3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!8X'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
LEA RSI,[R8+RDX] ; A chunk is expected.
CMP RSI,[InputEnd]
JNB .90:
MOV EDI,[RSI] ; Chunk netto size (payload data only).
BSWAP EDI ; Convert BE to LE.
ADD EDI,4+4+4 ; Chunk brutto size (size+id+data+CRC).
CMP EDI,4+4+13+4
JNE .30:
CMPD [RSI+4],0x52444849 ; Chunk id="IHDR"?
JNE .30:
; Chunk is IHDR.
MOV [RBX+VIEW_INDEX.Rem],=B'Chunk !4E'
ADD EDI,Level2
MOV [RBX+VIEW_INDEX.Size],EDI
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Chunk netto size !4hh=!4d'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Chunk identifier "!4X"'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Image width !4hh=!4d'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Image height !4hh=!4d'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Bits per pixel !1D'
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Color type !1C'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Compression method !1D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Filter method !1D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Interlaced !1D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Size],4
MOV [RBX+VIEW_INDEX.Rem],=B'CRC !4hh'
CALL SaveViewIndex::
.30:; Chunk is not IHDR.
MOV EDX,[RBX+VIEW_INDEX.FA]
LEA RSI,[R8+RDX]
CMP RSI,[InputEnd]
JNB .90:
MOV EDI,[RSI]
BSWAP EDI
ADD EDI,4+4+4 ; Chunk brutto size (size+id+data+CRC).
MOV [RBX+VIEW_INDEX.Rem],=B'Chunk !4E'
ADD EDI,Level2
MOV [RBX+VIEW_INDEX.Size],EDI
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Chunk netto size !4hh=!4d'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Chunk identifier "!4X"'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV ECX,[R8+RDX] ; Chunk identifier.
CALL SaveViewIndex
OR ECX,0x20202020 ; Convert to lowercase.
CMP ECX,'text'
JE .70:
MOV [RBX+VIEW_INDEX.Rem],=B'Chunk data'
JMP .80:
.70:MOV [RBX+VIEW_INDEX.Rem],=B'!X'
.80:SUB EDI,4+4+4+Level2
MOV [RBX+VIEW_INDEX.Size],EDI
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'CRC !4hh'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex
LEA RDI,[R8+RDI+4]
CMP RDI,[InputEnd]
JB .30:
.90:RET
ENDP FormatPNG
Sound file format.
FormatWAV PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Format WAV "!14$" size=!24$'
MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Master chunk RIFF'
MOV [RBX+VIEW_INDEX.Size],12+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FileTypeBlocID "!4X"'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FileSize !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FileFormatID "!4X"'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Format chunk FMT'
MOV [RBX+VIEW_INDEX.Size],24+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FormatBlocID "!4X"'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'BlocSize !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'AudioFormat !2D'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'NbrChannels !2D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Frequency !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'BytePerSec !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'BytePerBloc !2D'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'BitsPerSample !2D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Samples chunk DATA'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV ECX,[R8+RDX+4]
MOV EDX,ECX
OR ECX,Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'DataBlocID "!4X"'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'DataSize !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
MOV [RBX+VIEW_INDEX.Size],EDX
CALL SaveViewIndex::
RET
ENDP FormatWAV
This procedure is the last in AutoDetectFileFormat, so it will always return the BIN format.
DetectBIN PROC
LEA RAX,[FormatBIN]
RET
ENDP DetectBIN
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectBMP: PROC
CMPW [RSI],'BM' ; Signature bitmap file?
JNE .No:
MOV EAX,[RSI+2]
CMP RAX,[InputSize:]
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectBMP
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectCOFF16 PROC
MOVZXW EAX,[RSI+16] ; Size of optional header.
TEST EAX
JNZ .No:
MOV AX,[RSI+0] ; COFF machine.
CMP AX,0x014C ; Machine I386?
JNE .No:
TESTW [RSI+18],0x0100 ; 32 bit machine?
JNZ .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectCOFF16
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectCOFF32 PROC
MOVZXW EAX,[RSI+16] ; Size of optional header.
TEST EAX
JNZ .No:
MOV AX,[RSI+0] ; COFF machine.
CMP AX,0x014C ; Machine I386?
JNE .No:
TESTW [RSI+18],0x0100 ; 32 bit machine?
JZ .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectCOFF32
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectCOFF64 PROC
MOVZXW EAX,[RSI+16] ; Size of optional header.
TEST EAX
JNZ .No:
MOV AX,[RSI+0] ; COFF machine.
CMP AX,0x8664 ; Machine AMD64?
JNE .No:
TESTW [RSI+18],0x0100 ; 32 bit machine?
JNZ .No:
CLC
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectCOFF64
Test if the file memory-mapped between [InputPtr::] and [OutputEnd::] is in this file format.
DetectCUR: PROC
CMPW [RSI+0],0
JNE .No:
CMPW [RSI+2],2
JNE .No:
CMPW [RSI+4],64
JA .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectCUR
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectDLL32 PROC
CMPW [RSI+0],'MZ' ; MZ signature?
JNE .No:
MOV EDX,[RSI+0x3C]
CMP RDX,[InputSize::]
JAE .No:
CMPD [RSI+RDX],0x00004550 ; PE signature?
JNE .No:
CMPW [RSI+RDX+4+0],0x014C ; MACHINE_I386?
JNE .No:
CMPW [RSI+RDX+4+16],0x00E0 ; Size of optional header.
JNE .No:
TESTW [RSI+RDX+4+18],0x2000 ; FILE_DLL?
JZ .No:
CLC
JMP .90:
.No:STC
.90:RET
ENDP DetectDLL32
Test if the file memory-mapped between [InputPtr::] and [OutputEnd::] is in this file format.
DetectDLL64: PROC
CMPW [RSI+0],'MZ' ; MZ signature?
JNE .No:
MOV EDX,[RSI+0x3C]
CMP RDX,[InputSize::]
JAE .No:
CMPD [RSI+RDX],0x00004550 ; PE signature?
JNE .No:
CMPW [RSI+RDX+4+0],0x8664 ; MACHINE_AMD64?
JNE .No:
CMPW [RSI+RDX+4+16],0x00F0 ; Size of optional header.
JNE .No:
TESTW [RSI+RDX+4+18],0x2000 ; FILE_DLL?
JZ .No:
CLC
JMP .90:
.No:STC
.90:RET
ENDP DetectDLL64
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectELF32: PROC
CMPD [RSI],0x464C457F ; Signature ELF?
JNE .No:
CMPB [RSI+4],1
JNE .No:
CMPB [RSI+16],1
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectELF32
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectELF64 PROC
CMPD [RSI],0x464C457F ; Signature ELF?
JNE .No:
CMPB [RSI+4],2
JNE .No:
CMPB [RSI+16],1
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectELF64
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectELFSO32 PROC
CMPD [RSI],0x464C457F ; Signature ELF?
JNE .No:
CMPB [RSI+4],1
JNE .No:
CMPB [RSI+16],3
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectELFSO32
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectELFSO64 PROC
CMPD [RSI],0x464C457F ; Signature ELF?
JNE .No:
CMPB [RSI+4],2
JNE .No:
CMPB [RSI+16],3
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectELFSO64
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectELFX32 PROC
CMPD [RSI],0x464C457F ; Signature ELF?
JNE .No:
CMPB [RSI+4],1
JNE .No:
CMPB [RSI+16],2
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectELFX32
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectELFX64 PROC
CMPD [RSI],0x464C457F ; Signature ELF?
JNE .No:
CMPB [RSI+4],2
JNE .No:
CMPB [RSI+16],2
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectELFX64
Test if the file memory-mapped between [InputPtr::] and [InputEnd::] is in this file format.
DetectGIF: PROC
CMPD [RSI+0],'GIF8'
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectGIF
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectICO: PROC
CMPW [RSI+0],0
JNE .No:
CMPW [RSI+2],1
JNE .No:
CMPW [RSI+4],64
JA .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectICO
Test if the file memory-mapped between [InputPtr::] and [InputEnd::] is in this file format.
DetectJPG: PROC
CMPW [RSI],0xD8FF
JNE .No:
MOV RDX,[InputEnd]
CMPW [RDX-2],0xD9FF
JE .90:
.No:STC
.90:RET
ENDP DetectJPG:
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectLIBCOF: PROC
CMPD [RSI+0],0x72613C21 ; !
JNE .No:
CMPD [RSI+4],0x0A3E6863
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectLIBCOF
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectLIBOMF: PROC
PUSH RSI
CMPB [RSI],0xF0 ; LIBHDR?
JNE .No:
MOVZXW ECX,[RSI+1]
ADD ECX,3
CMP RCX,[InputSize:]
JNB .No:
CMPB [RSI+RCX],0x82 ; LHEADR?
JNE .No:
ADD RSI,RCX
MOVZXW ECX,[RSI+1]
ADD ECX,3
XOR EDX,EDX
.10:LODSB
ADD DL,AL
LOOP .10:
TEST DL
JNZ .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:POP RSI
RET
ENDP DetectLIBOMF
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectMIDI: PROC
CMPD [RSI],'MThd'
JNE .No:
CMPD [RSI+4],0x06000000
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectMIDI
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectMP3: PROC
CMPW [RSI],0xFBFF ; MP3 frame?
JE .90:
CMPD [RSI],0x03334449 ; ID3?
JE .90:
STC ; Not detected.
.90:RET
ENDP DetectMP3
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectMZ PROC
CMPW [RSI+0],'MZ' ; Size of optional header.
JE .90:
STC ; Not detected.
.90: RET
ENDP DetectMZ
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectOMF: PROC
PUSH RSI
CMPB [RSI],0x80 ; THEADR
JNE .No:
MOVZXW ECX,[RSI+1]
ADD ECX,3
CMP RCX,[InputSize::]
JNB .No:
CMPB [RSI+RCX-1],0
JE .Yes:
XOR EDX,EDX
.10: LODSB
ADD DL,AL
LOOP .10:
TEST DL
JNZ .No:
.Yes:CLC ; Detected.
JMP .90:
.No: STC ; Not detected.
.90: POP RSI
RET
ENDP DetectOMF
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectPE32 PROC
CMPW [RSI+0],'MZ' ; MZ signature?
JNE .No:
MOV EDX,[RSI+0x3C]
CMP RDX,[InputSize::]
JAE .No:
CMPD [RSI+RDX],0x00004550 ; PE signature?
JNE .No:
CMPW [RSI+RDX+4+0],0x014C ; MACHINE_I386?
JNE .No:
CMPW [RSI+RDX+4+16],0x00E0 ; Size of optional header.
JNE .No:
TESTW [RSI+RDX+4+18],0x2000 ; FILE_DLL?
JNZ .No:
CLC
JMP .90:
.No:STC
.90:RET
ENDP DetectPE32
Test if the file memory-mapped between [InputPtr::] and [OutputEnd::] is in this file format.
DetectPE64: PROC
CMPW [RSI+0],'MZ' ; MZ signature?
JNE .No:
MOV EDX,[RSI+0x3C]
CMP RDX,[InputSize::]
JAE .No:
CMPD [RSI+RDX],0x00004550 ; PE signature?
JNE .No:
CMPW [RSI+RDX+4+0],0x8664 ; MACHINE_AMD64?
JNE .No:
CMPW [RSI+RDX+4+16],0x00F0 ; Size of optional header.
JNE .No:
TESTW [RSI+RDX+4+18],0x2000 ; FILE_DLL?
JNZ .No:
CLC
JMP .90:
.No:STC
.90:RET
ENDP DetectPE64
Test if the file memory-mapped between [InputPtr::] and [InputEnd::] is in this file format.
DetectPNG: PROC
LODSD
CMP AL,0x89
JNE .No:
SHR EAX,8
CMP EAX,'PNG'
JE .90:
.No:STC
.90:RET
ENDP DetectPNG:
Test if the file memory-mapped between [InputPtr:] and [OutputEnd:] is in this file format.
DetectWAV: PROC
CMPD [RSI],'RIFF'
JNE .No:
CMPD [RSI+8],'WAVE'
JNE .No:
CLC ; Detected.
JMP .90:
.No:STC ; Not detected.
.90:RET
ENDP DetectWAV
Linkable file format.
AnalyzeCOFF: PROC
XOR EAX,EAX
MOV [RBX+VIEW_INDEX.FA],EAX
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF64 "!14$" size=!24$'
JSt [Status::],ArgWidth64,.10:
MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF32 "!14$" size=!24$'
JSt [Status::],ArgWidth32,.10:
MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF16 "!14$" size=!24$'
JSt [Status::],ArgWidth16,.10:
MOV [RBX+VIEW_INDEX.Rem],=B'Format COFF "!14$" size=!24$'
.10:CALL SaveViewIndex::
MOV [FaOfSectionHeaders],20 ; Size of COFF file header.
CALL AnalyzeCoffFileHeader
MOV EAX,[NrOfSections]
LEA EAX,[EAX+4*EAX]
LEA EAX,[8*EAX] ; Multiply NrOfSections by section header size (40).
MOV [RBX+VIEW_INDEX.Rem],=B'COFF section headers'
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV ECX,[NrOfSymbols]
LEA EAX,[ECX+8*ECX]
LEA EDX,[2*EAX] ; Multiply NrOfSymbols by symbol size (18).
ADD EDX,[FaOfSymbolTable]
MOV [FaOfStringTable],EDX
MOV ECX,[NrOfSections]
JRCXZ .70:
.50:PUSH RCX
CALL AnalyzeCoffSectionHeader
POP RCX
LOOP .50:
.70:CALL AnalyzeCoffRawData
CALL AnalyzeCoffRelocations
CALL AnalyzeCoffSymbolTable
CALL AnalyzeCoffStringTable
RET
ENDP AnalyzeCOFF
Linkable file format.
AnalyzeCoffFileHeader PROC MOV [RBX+VIEW_INDEX.Rem],=B'COFF file header' MOV [RBX+VIEW_INDEX.Size],20+Level2 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Machine !2Hh: !0$' MOV [RBX+VIEW_INDEX.Size],2 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Number of sections: !2D' MOV EDX,[RBX+VIEW_INDEX.FA] CMP RDX,[InputSize::] JNB .90: MOVZXW EAX,[R8+RDX] MOV [NrOfSections],EAX CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Time&Date stamp: !4T UTC' MOV [RBX+VIEW_INDEX.Size],4 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'FA of symbol table: !4Hh' MOV EDX,[RBX+VIEW_INDEX.FA] MOV EAX,[R8+RDX] MOV [FaOfSymbolTable],EAX CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Number of symbols: !4Hh=!4D' MOV EDX,[RBX+VIEW_INDEX.FA] MOV EAX,[R8+RDX] MOV [NrOfSymbols],EAX CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Size of optional header: !2Hh=!2D' MOV [RBX+VIEW_INDEX.Size],2 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Characteristics !2Hh: !1$' CALL SaveViewIndex:: .90:RET ENDP AnalyzeCoffFileHeader
AnalyzeCoffRawData PROC
MOV ECX,[NrOfSections]
JRCXZ .90:
MOV EDX,[FaOfSectionHeaders] ;Size of COFF file header, FA of 1st section header.
.10:MOV [RBX+VIEW_INDEX.Rem],=B'Raw data|code of section !2$'
CMP EDX,[InputSize::]
JNB .90:
MOV EAX,[R8+RDX+8+4+4+4] ; FA of FA of raw data.
TEST EAX
JZ .80:
MOV [RBX+VIEW_INDEX.FA],EAX
MOV EAX,[R8+RDX+8+4+4] ; FA of FA of raw size.
TEST EAX
JZ .80:
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
.80:ADD EDX,40 ; Size of section header.
LOOP .10: ; The next section header.
.90:RET
ENDP AnalyzeCoffRawData
AnalyzeCoffRelocations PROC
MOV ECX,[NrOfSections]
TEST ECX
JZ .90:
MOV EDX,[FaOfSectionHeaders] ; Size of COFF file header, FA of 1st section header.
CMP RDX,[InputSize::]
JNB .90:
.10:MOV R11,RDX ; Temprary save FaOfSectionHeaders to R11.
MOV [SectionNumber],ECX ; NrOfSections, NrOfSections-1, NrOfSections-2, ,,,
MOV [RBX+VIEW_INDEX.Rem],=B'Relocations in section !2$'
MOV EAX,[R8+RDX+8+4+4+4+4] ; FA of FA of relocations.
TEST EAX
JZ .80: ; Skip if there are no relocations in this section.
MOV [RBX+VIEW_INDEX.FA],EAX
MOVZXW EAX,[R8+RDX+8+4+4+4+4+4+4] ; Number of relocations.
TEST EAX
JZ .80: ; Skip if there are no relocations in this section.
MOV ECX,EAX ; Number of relocations.
LEA EAX,[EAX+4*EAX]
ADD EAX,EAX ; Multiply the number by size of one relocation (10).
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex:: ; Level 2.
.50:MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !4Hh'
MOV [RBX+VIEW_INDEX.Size],10+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Relative VA: !4Hh'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!4D: !8$'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Size],2
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOVZXW EAX,[R8+RDX]
JSt [Status::],ArgWidth64,.55:
Dispatch AX,0x0006,0x0007,0x0014
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !2H'
JMP .60:
.0x0006:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD VA'
JMP .60:
.0x0007:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD RVA'
JMP .60:
.0x0014:MOV [RBX+VIEW_INDEX.Rem],=B'Relative DWORD'
JMP .60:
.55:Dispatch AX,0x0001,0x0002,0x0003,0x0004
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !2H'
JMP .60:
.0x0001:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute QWORD VA'
JMP .60:
.0x0002:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD VA'
JMP .60:
.0x0003:MOV [RBX+VIEW_INDEX.Rem],=B'Absolute DWORD RVA'
JMP .60:
.0x0004:MOV [RBX+VIEW_INDEX.Rem],=B'Relative DWORD'
;JMP .60:
.60:CALL SaveViewIndex::
DEC RCX
JNZ .50:
.80:MOV RDX,R11
ADD EDX,40 ; Size of the next section header.
MOV ECX,[SectionNumber]
DEC ECX
JNZ .10:
.90:RET
ENDP AnalyzeCoffRelocations
Linkable file format.
AnalyzeCoffSectionHeader: PROC
MOV [SectionIndex],1
MOV [RBX+VIEW_INDEX.Rem],=B'COFF Section header #!9$: !2$'
MOV [RBX+VIEW_INDEX.Size],40+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Section name: !2$'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Virtual size: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Virtual address: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of raw data: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FA of raw data: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FA of relocations: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FA of line numbers: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of relocations: !2D'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of line numbers: !2D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !3$'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
RET
ENDP AnalyzeCoffSectionHeader
AnalyzeCoffStringTable PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Table of strings'
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP EDX,[InputSize::]
JNB .90:
MOV EAX,[R8+RDX] ; Get string table size.
MOV [SizeOfStringTable],EAX
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of string table: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Body of string table'
MOV EAX,[SizeOfStringTable]
SUB EAX,4
OR EAX,Level1
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
.90: RET
ENDP AnalyzeCoffStringTable
AnalyzeCoffSymbolTable: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Table of symbols'
MOV ECX,[NrOfSymbols]
TEST ECX
JZ .90:
LEA EAX,[ECX+8*ECX]
ADD EAX,EAX ; Multiply by symbol size (18).
JZ .90:
MOV ECX,EAX ; Size of symbol table.
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
MOV EAX,[FaOfSymbolTable]
ADD ECX,EAX
MOV [FaOfStringTable],ECX
CMP RCX,[InputSize::]
JNB .90:
MOV [RBX+VIEW_INDEX.FA],EAX
CALL SaveViewIndex::
MOV ECX,[NrOfSymbols]
.20: MOV [SymbolNumber],ECX ; Total number of symbols.
MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!7$: !4$' ; Fn7$CoffSymbolIndexStore, Fn4$CoffIndexName
MOV [RBX+VIEW_INDEX.Size],18+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Name: !4$'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Value: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!5$' ; Section by Fn5$CoffSymbolSection
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!6$' ; Fn6$CoffSymbolType
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB ECX,[R8+RDX+17-18] ; Aux
JRCXZ .30:
.25: MOV [RBX+VIEW_INDEX.Rem],=B'!X' ; Auxilliary symbol(s).
MOV [RBX+VIEW_INDEX.Size],18
CALL SaveViewIndex::
DEC [SymbolNumber]
LOOP .25:
.30: MOV ECX,[SymbolNumber]
TEST ECX
JBE .90:
DEC ECX
JNZ .20:
.90: RET
ENDP AnalyzeCoffSymbolTable
AnalyzeElfDynamic: PROC
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF
ADD EAX,[RBX+VIEW_INDEX.FA]
MOV [FaOfDynamicEnd],EAX
JSt [Status::],ArgWidth64,.50:
.20:MOV [RBX+VIEW_INDEX.Rem],=B'!8y'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP EDX,[FaOfDynamicEnd]
JB .20:
JMP .90:
.50:MOV [RBX+VIEW_INDEX.Rem],=B'!16y'
MOV [RBX+VIEW_INDEX.Size],16
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP EDX,[FaOfDynamicEnd]
JB .50:
.90:RET
ENDP AnalyzeElfDynamic
AnalyzeElfHash: PROC
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF
MOV EDX,EAX
ADD EAX,[RBX+VIEW_INDEX.FA]
MOV [FaOfHashEnd],EAX
MOV [RBX+VIEW_INDEX.Rem],=B'Number of buckets: !4D'
MOV [RBX+VIEW_INDEX.Size],4
MOV EAX,[RBX+VIEW_INDEX.FA]
CMP RAX,[InputSize::]
JNB .90:
MOV ECX,[R8+RAX]
SHR EDX,2
CMP ECX,EDX
JB .10:
MOV ECX,EDX
.10:CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of symbols: !4D'
CALL SaveViewIndex::
CMP ECX,300
JNB .90:
.20:MOV [RBX+VIEW_INDEX.Rem],=B'Bucket !4D'
CALL SaveViewIndex::
LOOP .20:
.30:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP EDX,[FaOfHashEnd]
JNB .90:
MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!4D'
CALL SaveViewIndex::
JMP .30:
.90:RET
ENDP AnalyzeElfHash
32bit linkable module format.
AnalyzeElfFileHeader: PROC
JSt [Status::],ArgWidth64,.50:
MOV [RBX+VIEW_INDEX.Rem],=B'ELF32 file header'
MOV [RBX+VIEW_INDEX.Size],52+Level2
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Signature ELF32'
MOV [RBX+VIEW_INDEX.Size],16
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'File type !2G'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Machine type !2M'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Version !4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Entry: !4Hh=!4D'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'FA of program headers: !4Hh=!4D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[R8+RDX]
MOV [FaOfElfProgramHeaders],EAX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'FA of section headers: !4Hh=!4D'
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP EDX,[InputSize::]
JNB .90:
MOV EAX,[R8+RDX]
MOV [FaOfElfSectionHeaders],EAX
CMP RAX,[InputSize::]
JNB .90:
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'CPU flags: !4D'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Size of file header: !2Hh=!2D'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Size of program header: !2Hh=!2D'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Number of program headers: !2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
MOV [NrOfElfProgramHeaders],EAX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Size of section header: !2Hh=!2D'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Number of section headers: !2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
MOV [NrOfElfSectionHeaders],EAX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'String table section ordinal: !2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX] ; shstrndx.
MOV ECX,40 ; Size of 32bit section header.
MUL RCX
MOV EDX,[R8+20h] ; FA of section headers in 32bit file header.
LEA EAX,[EAX+EDX+10h] ; FA of 32bit section .shstrtab
CMP RAX,[InputSize::]
JNB .90
MOV ECX,[R8+RAX] ; FA of data in 32bit section .shstrtab.
MOV [FaOfShstrtabData],ECX
CALL SaveViewIndex
JMP .90:
.50:MOV [RBX+VIEW_INDEX.Rem],=B'ELF64 file header'
MOV [RBX+VIEW_INDEX.Size],64+Level2
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Signature ELF64'
MOV [RBX+VIEW_INDEX.Size],16
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'File type !2G'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Machine type !2M'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Version !4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Entry: !8Hh=!8D'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'FA of program headers: !8Hh=!8D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV RAX,[R8+RDX]
CMP RAX,[InputSize::]
JNB .90:
MOV [FaOfElfProgramHeaders],EAX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'FA of section headers: !8Hh=!8D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV RAX,[R8+RDX]
MOV [FaOfElfSectionHeaders],EAX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'CPU flags: !4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Size of file header: !2Hh=!2D'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Size of program header: !2Hh=!2D'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Number of program headers: !2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
MOV [NrOfElfProgramHeaders],EAX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Size of section header: !2Hh=!2D'
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'Number of section headers: !2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
MOV [NrOfElfSectionHeaders],EAX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'String table section ordinal: !2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX] ; shstrndx.
MOV ECX,64 ; Size of 64bit section header.
MUL RCX
MOV RDX,[R8+28h] ; FA of section headers in 64bit file header.
LEA EAX,[EAX+EDX+18h] ; FA of 64bit section .shstrtab data.
CMP RAX,[InputSize::]
JNB .90:
MOV ECX,[R8+RAX] ; FA of data in 64bit section .shstrtab.
MOV [FaOfShstrtabData],ECX
CALL SaveViewIndex
.90:RET
ENDP AnalyzeElfFileHeader
AnalyzeElfNote: PROC
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF
ADD EAX,[RBX+VIEW_INDEX.FA]
MOV [FaOfNoteEnd],EAX
MOV [RBX+VIEW_INDEX.Rem],=B'Vendor name size: !4D'
MOV [RBX+VIEW_INDEX.Size],4
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV ECX,[R8+RDX]
ADD ECX,7
AND ECX,0x0000_00F8 ; Round up vendor name size to 8.
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Data name size: !4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Data type: !4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Vendor: !X'
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV ECX,[FaOfNoteEnd]
SUB ECX,EDX
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
RET
ENDP AnalyzeElfNote
AnalyzeElfProgramHeader: PROC
JSt [Status::],ArgWidth64,.50:
MOV [RBX+VIEW_INDEX.Rem],=B'Program header of sections !22$'
MOV ECX,32+Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4P'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FA: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'PA: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size in file: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size in memory: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !4Q'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !4Hh=!4D'
CALL SaveViewIndex::
JMP .90:
.50:MOV [RBX+VIEW_INDEX.Rem],=B'Program header of sections !22$'
MOV ECX,56+Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4P'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !4Q'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Size],8
MOV [RBX+VIEW_INDEX.Rem],=B'FA: !8Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA: !8Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'PA: !8Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size in file: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size in memory: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !8Hh=!8D'
CALL SaveViewIndex::
.90:RET
ENDP AnalyzeElfProgramHeader
AnalyzeElfRel PROC
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF
ADD EAX,[RBX+VIEW_INDEX.FA]
MOV [FaOfRelEnd],EAX
JSt [Status::],ArgWidth64,.50:
.20:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
CMP EDX,[FaOfRelEnd]
JNB .90:
MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !4Hh'
MOV [RBX+VIEW_INDEX.Size],4+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!1Z'
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!3D'
MOV [RBX+VIEW_INDEX.Size],3
CALL SaveViewIndex::
JMP .20:
.50:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
CMP EDX,[FaOfRelEnd]
JB .90:
MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !8Hh'
MOV [RBX+VIEW_INDEX.Size],8+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!4Z'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!4D'
CALL SaveViewIndex::
JMP .50:
.90:RET
ENDP AnalyzeElfRel
AnalyzeElfRela PROC
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF
ADD EAX,[RBX+VIEW_INDEX.FA]
MOV [FaOfRelaEnd],EAX
JSt [Status::],ArgWidth64,.50:
.20:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
CMP EDX,[FaOfRelaEnd]
JNB .90:
MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !4Hh'
MOV [RBX+VIEW_INDEX.Size],4+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!1Z'
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!3D'
MOV [RBX+VIEW_INDEX.Size],3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Addend: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
JMP .20:
.50:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
CMP EDX,[FaOfRelaEnd]
JNB .90:
MOV [RBX+VIEW_INDEX.Rem],=B'Relocation at !8Hh'
MOV [RBX+VIEW_INDEX.Size],8+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA|offset: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!4Z'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'by symbol #!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Addend: !8Hh=!8D'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
JMP .50:
.90:RET
ENDP AnalyzeElfRela
AnalyzeElfSectionHeader32: PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV [FaOfThisSectionHeader],EDX
MOV [RBX+VIEW_INDEX.Rem],=B'Section header #!1R !4N'
MOV [RBX+VIEW_INDEX.Size],40+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Size],4
MOV [RBX+VIEW_INDEX.Rem],=B'Name: !4N'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4S'
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOV ECX,[R8+RDX] ; RCX=section type.
CMP ECX,256
JA .90:
CALL SaveViewIndex::
; Analyze of section will be temporary suspended
; and section types "progbits","strtab" etc analyzed now.
Dispatch CL,1d,3d,5d,2d,11d,6d,7d,4d,9d
JMP .40:
.1d: ; progbits
.2d: ; symtab
.3d: ; strtab
.4d: ; rela
.5d: ; hash
.6d: ; dynamic
.7d: ; note
.9d: ; rel
.11d: ; dynsym
PUSHQ [RBX+VIEW_INDEX.FA]; FA and Size which pointed to SHDR32.sh_flags
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOV EAX,[R8+RDX-8+10h] ; SHDR32.sh_offset.
CMP RAX,[InputSize::]
JNB .90:
MOV [RBX+VIEW_INDEX.FA],EAX
MOV EAX,[R8+RDX-8+14h] ; SHDR32.sh_size.
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
MOV [RBX+VIEW_INDEX.Rem],=B'Contents of section #!20$'
CALL SaveViewIndex::
Dispatch CL,1D,3D,5D,2D,11D,6D,4D,9D,7D
.1D: ; progbits
.3D: ; strtab
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
JMP .30:
.5D: ; hash
CALL AnalyzeElfHash
JMP .30:
.7D: CALL AnalyzeElfNote
JMP .30:
.4D: CALL AnalyzeElfRela
JMP .30:
.9D: CALL AnalyzeElfRel
JMP .30:
.2D: ; symtab
.11D: ; dynsym
CALL AnalyzeElfSymbols
JMP .30:
.6D: ; dynamic
MOV ECX,[RBX+VIEW_INDEX.Size]
AND ECX,0x0FFF_FFFF
ADD ECX,[RBX+VIEW_INDEX.FA]
MOV [FaOfDynamicEnd],ECX
MOV [RBX+VIEW_INDEX.Size],4+4
.20: MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
CMP EDX,[FaOfDynamicEnd]
JNB .30:
MOV [RBX+VIEW_INDEX.Rem],=B'!8y'
CALL SaveViewIndex::
JMP .20:
.30:POPQ [RBX+VIEW_INDEX.FA]
.40:MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !4q' ; Continue with analyzing section header.
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FA: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Section size: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Link to section: #!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Info of this section: !4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of one entry: !4D'
CALL SaveViewIndex::
.90:RET
ENDP AnalyzeElfSectionHeader32
AnalyzeElfSectionHeader64: PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV [FaOfThisSectionHeader],EDX
MOV [RBX+VIEW_INDEX.Rem],=B'Section header #!1R !4N'
MOV [RBX+VIEW_INDEX.Size],64+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Size],4
MOV [RBX+VIEW_INDEX.Rem],=B'Name: !4N'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !4S'
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOV ECX,[R8+RDX] ; RCX=section type.
CMP ECX,256
JA .90:
CALL SaveViewIndex::
; Analyze of section will be temporarily suspended
; and section types "progbits","strtab" etc analyzed now.
Dispatch CL,1d,2d,3d,4d,5d,6d,7d,9d,11d
JMP .40: ; Do nothing for sections 0="null", 8="nobits" etc.
.1d: ; progbits
.2d: ; symtab
.3d: ; strtab
.4d: ; rela
.5d: ; hash
.6d: ; dynamic
.7d: ; note
.9d: ; rel
.11d: ; dynsym
PUSHQ [RBX+VIEW_INDEX.FA]; .FA and .Size which pointed to SHDR32.sh_flags
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV RAX,[R8+RDX-4-4+18h]; SHDR64.sh_offset.
MOV [RBX+VIEW_INDEX.FA],EAX
MOV RAX,[R8+RDX-4-4+20h]; SHDR64.sh_size.
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
MOV [RBX+VIEW_INDEX.Rem],=B'Contents of section #!20$'
CALL SaveViewIndex::
Dispatch CL,1D,3D,5D,2D,11D,6D,4D,9D,7D
.1D: ; progbits
.3D: ; strtab
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
CALL SaveViewIndex::
JMP .30:
.2D: ; symtab
.11D: ; dynsym
CALL AnalyzeElfSymbols
JMP .30:
.5D: CALL AnalyzeElfHash
JMP .30:
.7D: CALL AnalyzeElfNote
JMP .30:
.4D: CALL AnalyzeElfRela
JMP .30:
.9D: CALL AnalyzeElfRel
JMP .30:
.6D: ; dynamic
MOV ECX,[RBX+VIEW_INDEX.Size]
AND ECX,0x0FFF_FFFF
ADD ECX,[RBX+VIEW_INDEX.FA]
MOV [FaOfDynamicEnd],ECX
MOV [RBX+VIEW_INDEX.Size],8+8
.20: MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
CMP EDX,[FaOfDynamicEnd]
JNB .30:
MOV [RBX+VIEW_INDEX.Rem],=B'!16y'
CALL SaveViewIndex::
JMP .20:
.30:POPQ [RBX+VIEW_INDEX.FA]
.40:MOV [RBX+VIEW_INDEX.Rem],=B'Flags: !8q'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'VA: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FA: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Section size: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Link to section: #!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Info of this section: !4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Alignment: !8Hh=!8D'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of one entry: !8D'
CALL SaveViewIndex::
.90:RET
ENDP AnalyzeElfSectionHeader64
AnalyzeElfSymbols: PROC
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF
ADD EAX,[RBX+VIEW_INDEX.FA]
MOV [FaOfSymbolsEnd],EAX
JSt [Status::],ArgWidth64,.50:
.20:MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!1r !21$'
MOV [RBX+VIEW_INDEX.Size],16+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Name: !21$'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Value: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !1s'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'In section !2U'
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP EDX,[FaOfSymbolsEnd]
JB .20:
JMP .90:
.50:MOV [RBX+VIEW_INDEX.Rem],=B'Symbol #!1r !21$'
MOV [RBX+VIEW_INDEX.Size],24+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Name: !21$'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Type: !1s'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'In section !2U'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Value: !8Hh=!8D'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size: !8Hh=!8D'
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP EDX,[FaOfSymbolsEnd]
JB .50:
.90:RET
ENDP AnalyzeElfSymbols
Linkable archive file format.
AnalyzeLibcofFileHeader PROC MOV [RBX+VIEW_INDEX.Rem],=B'Short import header' MOV [RBX+VIEW_INDEX.Size],20+Level2 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Import signature: !4Hh' MOV [RBX+VIEW_INDEX.Size],4 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Version: !2D' MOV [RBX+VIEW_INDEX.Size],2 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Machine: !2Hh: !0$' CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Time&Date stamp: !4T UTC' MOV [RBX+VIEW_INDEX.Size],4 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Size of data: !4Hh=!4D' CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Ordinal|hint: !2D' MOV [RBX+VIEW_INDEX.Size],2 CALL SaveViewIndex:: MOV [RBX+VIEW_INDEX.Rem],=B'Import type: !2I' CALL SaveViewIndex:: RET ENDP AnalyzeLibcofFileHeader
AnalyzeLibcofMemberHeader PROC
MOV [RBX+VIEW_INDEX.Rem],=B'Member header !16X'
MOV [RBX+VIEW_INDEX.Size],60+Level3
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Name: !16X'
MOV [RBX+VIEW_INDEX.Size],16
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Date: !12L'
MOV [RBX+VIEW_INDEX.Size],12
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'User: !6X'
MOV [RBX+VIEW_INDEX.Size],6
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Group: !6X'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Mode: !8X'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!15$Member size: !10X'
MOV [RBX+VIEW_INDEX.Size],10
MOV EDX,[RBX+VIEW_INDEX.FA]
LEA RSI,[R8+RDX]
LodD RSI
MOV [MemberSize],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Terminating signature: !2Hh'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
RET
ENDP AnalyzeLibcofMemberHeader
DOS executable file format.
AnalyzeMzProgram PROC
MOV [RBX+VIEW_INDEX.Rem],=B'MZ DOS Header'
MOV [RBX+VIEW_INDEX.Size],64+Level2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Signature !2X'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Bytes in the last page !2Hh=!2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW ECX,[R8+RDX]
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of 512-byte pages !2Hh=!2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOVZXW EAX,[R8+RDX]
JRCXZ .20:
DEC EAX
.20:SHL EAX,9
ADD EAX,ECX
MOV [MzBytesFileSize],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of relocations !2Hh=!2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
MOV [NrOfRelocations],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Header size in paragraphs incl.relocations !2Hh=!2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
SHL EAX,4 ; Convert paragraphs to bytes.
MOV [MzHeaderSize],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Min.paragraphs allocated above code !2Hh=!2D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Max.paragraphs allocatable !2Hh=!2D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'SS relative to the start of MZ !2Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'SP !2Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Checksum !2Hh=!2D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Entry IP !2Hh=!2D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'CS entry relative to the start of MZ !2Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'FA of relocation table !2Hh=!2D'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
MOV [FaOfRelocations],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Overlay !2Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Size],32
MOV [RBX+VIEW_INDEX.Rem],=B'Reserved'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Size],4
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[R8+RDX]
MOV [FaOfPeSignature],EAX
MOV [RBX+VIEW_INDEX.Rem],=B'FA of LE/NE/PE header = !4Hh=!4D'
CALL SaveViewIndex::
MOV ECX,[NrOfRelocations]
JRCXZ .50:
MOV [RBX+VIEW_INDEX.Rem],=B'Relocations'
MOV EDX,[FaOfRelocations]
CMP RDX,[InputSize::]
JNB .90:
MOV [RBX+VIEW_INDEX.FA],EDX
SHL ECX,2
ADD ECX,Level1
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.FA],EDX
MOV [RBX+VIEW_INDEX.Size],4
MOV ECX,[NrOfRelocations]
CMP ECX,65000
JNB .90:
.40:MOV [RBX+VIEW_INDEX.Rem],=B'Relocation !4Fh'
CALL SaveViewIndex
LOOP .40:
.50:MOV [RBX+VIEW_INDEX.Rem],=B'MZ program executable body'
MOV ECX,[MzHeaderSize]
MOV [RBX+VIEW_INDEX.FA],ECX
MOV EDX,[MzBytesFileSize]
MOV EAX,EDX
SUB EDX,ECX
CMP EAX,0x0490
JNE .60:
MOV EAX,[FaOfPeSignature]
CMPD [R8+RAX],'PE'
JNE .60:
MOV EDX,[FaOfPeSignature]
MOV ECX,[MzHeaderSize]
SUB EDX,ECX
.60:OR EDX,Level1
MOV [RBX+VIEW_INDEX.Size],EDX
CALL SaveViewIndex
MOV [RBX+VIEW_INDEX.Rem],=B'!X'
MOV [RBX+VIEW_INDEX.FA],ECX
CALL SaveViewIndex
.90:RET
ENDP AnalyzeMzProgram
Linkable object module.
AnalyzeOmfRecord: PROC
MOV [RBX+VIEW_INDEX.Rem],=B'OMF record !1O'
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB EAX,[R8+RDX+0]
MOV [LastOmfRecord],EAX
CMP AL,0x82 ; LHEADR?
JNE .05:
MOV [RBX+VIEW_INDEX.Rem],=B'Module !19$'
MOVZXW ECX,[R8+RDX+1]
OR ECX,Level3
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
.05:MOVZXW ECX,[R8+RDX+1]
MOV [RecordSize],ECX
ADD ECX,3+Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!1O'
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Record size: !2D'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
CMPB [R8+RDX-3],0x88 ; COMENT?
JNE .40:
MOV AL,[R8+RDX]
LEA RSI,[=B'No purge, list']
CMP AL,0x80
JE .10:
LEA RSI,[=B'Purge, no list']
CMP AL,0x40
JE .10:
LEA RSI,[=B'No purge, no list']
CMP AL,0xC0
JE .10:
LEA RSI,[=B'Purge, list']
.10:MOV [RBX+VIEW_INDEX.Rem],RSI
MOV [RBX+VIEW_INDEX.Size],1
CALL SaveViewIndex::
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV AL,[R8+RDX]
Dispatch AL,0x00,0x9D,0xA0,0xA8,0xA9,0xE9
LEA RSI,[=B'Comment class !1Hh']
JMP .20:
.0x00:LEA RSI,[=B'Class 00h: Translator']
JMP .20:
.0x9D:LEA RSI,[=B'Class 9Dh: CPU and memory model']
JMP .20:
.0xA0:LEA RSI,[=B'Class A0h: Import|export definition']
JMP .20:
.0xA8:LEA RSI,[=B'Class A8h: Weak extern definition']
JMP .20:
.0xA9:LEA RSI,[=B'Class A9h: Lazy extern definition']
JMP .20:
.0xE9:LEA RSI,[=B'Class E9h: File dependency']
;JMP .20:
.20:MOV [RBX+VIEW_INDEX.Rem],RSI
CALL SaveViewIndex::
SUB [RecordSize],2
.40:MOV [RBX+VIEW_INDEX.Rem],=B'!X'
MOV ECX,[RecordSize]
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CMPB [LastOmfRecord],0xF1
RET
ENDP AnalyzeOmfRecord
32bit executable file format component.
AnalyzeOptionalHeader PROC
MOV [RBX+VIEW_INDEX.Rem],=B'64bit optional header'
MOV ECX,240+Level2
JSt [Status::],ArgWidth64,.10:
MOV [RBX+VIEW_INDEX.Rem],=B'32bit optional header'
MOV ECX,224+Level2
.10:MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Magic !2Hh=!2D'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Linker version: !10$'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of code: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of initialized data: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of uninitialized data: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'RVA entry: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'RVA base code: !4Hh=!4D'
CALL SaveViewIndex::
JSt [Status::],ArgWidth64,.20:
MOV [RBX+VIEW_INDEX.Rem],=B'RVA base data: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Image base: !4Hh=!4D'
JMP .25:
.20:MOV [RBX+VIEW_INDEX.Rem],=B'Image base: !8Hh=!8D'
MOV [RBX+VIEW_INDEX.Size],8
.25:CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Section alignment: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'File alignment: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'OS version: !11$'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Image version: !11$'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Subsystem version: !11$'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Win32 version: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Image size: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Headers size: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Checksum: !4Hh'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Subsystem: !12$'
MOV [RBX+VIEW_INDEX.Size],2
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'DLL characteristics: !2Hh'
CALL SaveViewIndex::
JSt [Status::],ArgWidth64,.40:
MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack reserve: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack commit: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap reserve: !4Hh=!4D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap commit: !4Hh=!4D'
JMP .45
.40:MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack reserve: !8Hh=!8D'
MOV [RBX+VIEW_INDEX.Size],8
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of stack commit: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap reserve: !8Hh=!8D'
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size of heap commit: !8Hh=!8D'
.45:CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Loader flags: !4Hh'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Number of data directories: !4D'
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOV EAX,[R8+RDX]
MOV [NrOfDataDirectories],EAX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Data directories'
MOV EAX,[RBX+VIEW_INDEX.FA]
MOV [FaOfDataDirs],EAX
MOV ECX,[NrOfDataDirectories]
MOV EAX,4+4
MUL RCX
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
.70:MOV [RBX+VIEW_INDEX.Rem],=B'PE data directory !13$' ; Fn13$DataDirName
MOV [RBX+VIEW_INDEX.Size],8+Level1
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'RVA: !4Hh=!4D'
MOV [RBX+VIEW_INDEX.Size],4
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'Size: !4Hh=!4D'
CALL SaveViewIndex::
LOOP .70:
.90:RET
ENDP AnalyzeOptionalHeader
Portable executable file format.
AnalyzePE: PROC
JSt [Status::],ArgDynamicLibrary,.20:
JSt [Status::],ArgWidth64,.10:
MOV [RBX+VIEW_INDEX.Rem],=B'Format PE32 "!14$" size=!24$'
JMP .30:
.10:MOV [RBX+VIEW_INDEX.Rem],=B'Format PE64 "!14$" size=!24$'
JMP .30:
.20:JSt [Status::],ArgWidth64,.25:
MOV [RBX+VIEW_INDEX.Rem],=B'Format DLL32 "!14$" size=!24$'
JMP .30:
.25:MOV [RBX+VIEW_INDEX.Rem],=B'Format DLL64 "!14$" size=!24$'
.30:MOV [RBX+VIEW_INDEX.FA],0
MOV RCX,[InputSize::]
OR ECX,Level4
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
CALL AnalyzeMzProgram
MOV [RBX+VIEW_INDEX.Rem],=B'PE Headers'
MOV EAX,[FaOfPeSignature]
MOV [RBX+VIEW_INDEX.FA],EAX
JSt [Status::],ArgWidth64,.40:
MOV ECX,4+20+224+Level3
JMP .50:
.40:MOV ECX,4+20+240+Level3
.50:MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'PE signature'
MOV ECX,4+Level2
MOV [RBX+VIEW_INDEX.Size],ECX
CALL SaveViewIndex::
MOV [RBX+VIEW_INDEX.Rem],=B'!2X'
CALL SaveViewIndex::
CALL AnalyzeCoffFileHeader
CALL AnalyzeOptionalHeader
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV [FaOfSectionHeaders],EDX
MOV EAX,[NrOfSections]
LEA EAX,[EAX+4*EAX]
LEA EAX,[8*EAX] ; Multiply by section header size (40).
MOV [RBX+VIEW_INDEX.Rem],=B'COFF section headers'
OR EAX,Level2
MOV [RBX+VIEW_INDEX.Size],EAX
CALL SaveViewIndex::
MOV ECX,[NrOfSections]
JRCXZ .70:
CMP ECX,257
JNB .90:
.60:PUSH RCX
CALL AnalyzeCoffSectionHeader
POP RCX
LOOP .60:
.70:CALL AnalyzeCoffRawData
CALL AnalyzeCoffRelocations
CALL AnalyzeCoffSymbolTable
CALL AnalyzeCoffStringTable
.90:RET
ENDP AnalyzePE
Internal function trigerred by !0$ in VIEW_INDEX.Rem
Fn00$CoffMachine PROC
MOV CX,[R8+RDX]
Dispatch CX,0x0000,0x014C,0x0200,0x8664,0x01C0,0xAA64
JMP .90:
.0x0000:LEA RSI,[=B'UNKNOWN']
JMP .70:
.0x014C:LEA RSI,[=B'I386']
JMP .70:
.0x0200:LEA RSI,[=B'IA64']
JMP .70:
.0x8664:LEA RSI,[=B'AMD64']
JMP .70:
.0x01C0:LEA RSI,[=B'ARM']
JMP .70:
.0xAA64:LEA RSI,[=B'ARM64']
.70: LODSB
CMP AL,0
JE .90:
STOSB
JMP .70:
.90: RET
ENDP Fn00$CoffMachine
Internal function trigerred by !1$ in VIEW_INDEX.Rem
Fn01$CoffCharacteristics PROC ; Input:CX=COFF.Characteristics
MOV CX,[R8+RDX]
%bit %SETA 0x01
name %FOR RELOCS_STRIPPED, EXEC, LINE_NUMS_STRIPPED, SYM_S, AGGR, \
LARGE_ADDRESS_AWARE, NU, LE, 32BIT_MACHINE, DBG_S, RUN_SWAP, \
NRUN_SWAP, FS, FILE_DLL, UP_SYS, BE
TEST CX,%bit
JZ .No%name:
LEA RSI,[=B'%name']
CALL .70:
.No%name:
%bit %SETA %bit << 1 ; >>
%ENDFOR name
DEC RDI ; Remove the last '|'.
JMP .90:
.70:LODSB
CMP AL,0
JE .80:
STOSB
JMP .70:
.80:MOV AL,'|'
STOSB
.90:RET
ENDP Fn01$CoffCharacteristics
Internal function trigerred by !2$ in VIEW_INDEX.Rem
Fn02$CoffSectionName:: PROC ; Store section name to RDI. RBX is the first element of section header, raw data or relocations.
MOV EDX,[FaOfSectionHeaders] ; Try all section headers, they start at FA=20.
MOV ECX,[NrOfSections]
.10: ; EDX is FA of section header. EAX is the searched for FA of section header, raw data or relocations.
MOV EAX,[RBX+VIEW_INDEX.FA] ; The searched for FA of section header, raw data or relocation.
CMP EAX,EDX ; Pointers to .Name of section EDX header?
JE .30:
LEA RSI,[R8+RDX+8+4+4+4] ; Pointer to FA of raw data.
MOV EAX,[RSI]
CMP EAX,[RBX+VIEW_INDEX.FA]
JE .30:
LEA RSI,[R8+RDX+8+4+4+4+4]; Pointer to FA of relocations.
MOV EAX,[RSI]
CMP EAX,[RBX+VIEW_INDEX.FA]
JE .30
ADD EDX,40 ; Add section header size.
LOOP .10: ; EDX is not .FA of the corresponding header. Try the next one.
JMP .90:
.30:; EDX is FA of section header. Write section name to RDI.
MOV ESI,EDX
CALL FnStoreSectionName
.90:RET
ENDP Fn02$CoffSectionName
Internal function trigerred by !3$ in VIEW_INDEX.Rem
Fn03$CoffSectionFlags PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV ECX,[R8+RDX]
%bit %SETA 0x01
name %FOR ?,?,?,NO_PAD,?,CNT_CODE,INITIALIZED_DATA,UNINITIALIZED_DATA, \
?,LNK_INFO,?,LNK_REMOVE,LNK_COMDAT,?,?,GPREL, \
?,?,?,?,?,?,?,?, \
NRELOC_OVFL,DISCARDABLE,NOT_CACHED,NOT_PAGED,SHARED,EXECUTE,READ,WRITE
TEST ECX,%bit
JZ .No%.:
%IF "%name"!==="?"
LEA RSI,[=B'%name']
CALL .70:
%ENDIF
.No%.:
%bit %SETA %bit << 1 ; >>
%ENDFOR name
DEC RDI
SHR ECX,20
AND CX,0x000F
JZ .90:
DEC ECX
MOV EAX,1
SHL EAX,CL
LEA RSI,[=B'+ALIGN_']
MOV CL,7
REP MOVSB
StoD RDI
JMP .90:
.70: LODSB
CMP AL,0
JE .80:
STOSB
JMP .70:
.80: MOV AL,'|'
STOSB
.90: RET
ENDP Fn03$CoffSectionFlags
Internal function trigerred by !4$ in VIEW_INDEX.Rem
Fn04$CoffSymbolName PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV RAX,[R8+RDX]
TEST EAX
JZ .50: ; Jump on long name.
.20:CMP AL,0
JE .90:
STOSB
SHR RAX,8
JMP .20:
.50:SHR RAX,32 ; EAX is now index in string table.
ADD EAX,[FaOfStringTable]
LEA RSI,[R8+RAX]
.60:LODSB
CMP AL,0
JE .90:
STOSB
JMP .60:
.90:RET
ENDP Fn04$CoffSymbolName
Internal function trigerred by !5$ in VIEW_INDEX.Rem
Fn05$CoffSymbolSection PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
CMP AX,0xFFFF
LEA RSI,[=B'CONSTANT']
JE .50:
TEST AX,AX
LEA RSI,[=B'EXTERN']
JZ .50:
LEA RSI,[=B'DEBUG']
JS .50:
LEA RSI,[=B'Section #']
MOV ECX,9
REP MOVSB
MOV EDX,EAX ; Section #1,2,3,,,
StoD RDI
MOV AX,': '
STOSW
MOV EAX,40 ; Size of section header.
DEC EDX
MUL RDX
MOV ESI,[FaOfSectionHeaders]
ADD ESI,EAX
CALL FnStoreSectionName
JMP .90:
.50: LODSB
CMP AL,0
JE .90:
STOSB
JMP .50:
.90: RET
ENDP Fn05$CoffSymbolSection
Internal function trigerred by !6$ in VIEW_INDEX.Rem
Fn06$CoffSymbolType PROC ; Store Type, Class, Aux to RDI.
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV ECX,[R8+RDX]
CMP CH,1
LEA RSI,[=B'Pointer to ']
JE .20:
CMP CH,2
LEA RSI,[=B'Function ']
JE .20:
CMP CH,3
LEA RSI,[=B'Array ']
JNE .30:
.20: LODSB
CMP AL,0
JE .30:
STOSB
JMP .20:
.30:
%i %SETA 1
type %FOR VOID,CHAR,SHORT,INT,LONG,FLOAT,DOUBLE,STRUCT,UNION,ENUM,MOE,BYTE,WORD,UINT,DWORD
CMP CL,%i
JNE .No%type:
LEA RSI,[=B'%type ']
JMP .40:
.No%type:
%i %SETA %i+1
%ENDFOR type
JMP .50:
.40: LODSB
CMP AL,0
JE .50:
STOSB
JMP .40:
.50: SHR ECX,16
JZ .90:
CMP CL,2
LEA RSI,[=B'EXTERN']
JE .70:
CMP CL,3
LEA RSI,[=B'STATIC']
JE .70:
CMP CL,103
LEA RSI,[=B'FILE']
JE .70:
CMP CL,104
LEA RSI,[=B'SECTION']
JE .70:
CMP CL,105
LEA RSI,[=B'WEAK']
JNE .80:
.70: LODSB
CMP AL,0
JE .80:
STOSB
JMP .70:
.80: TEST CH,CH
JZ .90:
LEA RSI,[=B'+auxilliary']
.85: LODSB
CMP AL,0
JE .90:
STOSB
JMP .85:
.90: RET
ENDP Fn06$CoffSymbolType
Internal function trigerred by !07$ in VIEW_INDEX.Rem
Fn07$CoffSymbolIndexStore PROC ; Store and increment symbol index to RDI.
MOV EAX,[SymbolIndex]
PUSH RDI
LEA RDI,[Number]
MOV RSI,RDI
StoD RDI
SUB RDI,RSI
MOV ECX,EDI
POP RDI
REP MOVSB
INC [SymbolIndex]
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB ECX,[R8+RDX+17]
ADD [SymbolIndex],ECX
RET
ENDP Fn07$CoffSymbolIndexStore
Internal function trigerred by !8$ in VIEW_INDEX.Rem
Fn08$CoffSymbolByIndex PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[R8+RDX] ; Get symbol index.
LEA ECX,[EAX+8*EAX]
ADD ECX,ECX ; Multiply by symbol size (18).
ADD ECX,[FaOfSymbolTable]
MOV RAX,[R8+RCX]
TEST EAX
JZ .50: ; Jump on long name.
.20:CMP AL,0
JE .90:
STOSB
SHR RAX,8
JMP .20:
.50:SHR RAX,32 ; EAX is now index in string table.
ADD EAX,[FaOfStringTable]
LEA RSI,[R8+RAX]
.60:LODSB
CMP AL,0
JE .90:
STOSB
JMP .60:
.90:RET
ENDP Fn08$CoffSymbolByIndex
Internal function trigerred by !9$ in VIEW_INDEX.Rem
Fn09$CoffSectionIndexStore PROC ; Store and increment section index to RDI.
MOV EAX,[SectionIndex]
PUSH RDI
LEA RDI,[Number]
MOV RSI,RDI
StoD RDI
SUB RDI,RSI
MOV ECX,EDI
POP RDI
REP MOVSB
INC [SectionIndex]
RET
ENDP Fn09$CoffSectionIndexStore
Internal function trigerred by !10$ in VIEW_INDEX.Rem
Fn10$MajorMinorVersion1 PROC ; Interpret BYTE version as Major.Minor
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXB EAX,[R8+RDX+0] ; Get major version.
StoD RDI
MOV AL,'.'
STOSB
MOV AL,[R8+RDX+1] ; Get minor version.
StoD RDI
RET
ENDP Fn10$MajorMinorVersion1
Internal function trigerred by !11$ in VIEW_INDEX.Rem
Fn11$MajorMinorVersion2 PROC ; Interpret WORD version as Major.Minor
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX+0] ; Get major version.
StoD RDI
MOV AL,'.'
STOSB
MOV AX,[R8+RDX+2] ; Get minor version.
StoD RDI
RET
ENDP Fn11$MajorMinorVersion2
Internal function trigerred by !12$ in VIEW_INDEX.Rem
Fn12$WinSubsystem PROC ; Interpret WORD version as subsystem token.
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW EAX,[R8+RDX]
Dispatch AX,0x0002,0x0003,0x0001,0x0000
StoD RDI
JMP .90:
.0x0000:MOV RAX,'UNKNOWN'
JMP .70:
.0x0001:MOV RAX,'NATIVE'
JMP .70:
.0x0002:MOV EAX,'GUI'
JMP .70:
.0x0003:MOV EAX,'CON'
.70:CMP AL,0
JE .90:
STOSB
SHR RAX,8
JMP .70:
.90:RET
ENDP Fn12$WinSubsystem
Internal function trigerred by !13$ in VIEW_INDEX.Rem
Fn13$DataDirName PROC ; Write option header's data directoryname.
PUSH RCX,RDI
MOV EDX,[Fn13Index]
LEA RDI,[DataDirNames]
INC [Fn13Index]
TEST EDX
JZ .60:
MOV ECX,-1
XOR EAX,EAX
.20: REPNE SCASB
DEC EDX
JNZ .20:
.60: MOV RSI,RDI
POP RDI,RCX
.70:LODSB
CMP AL,0
JE .90:
STOSB
JMP .70:
.90:RET
ENDP Fn13$DataDirName
Internal function trigerred by !14$ in VIEW_INDEX.Rem
Fn14$FileName PROC ; Write input filename.
LEA RSI,[ArgInputFile::]
.10: LODSB
CMP AL,0
JE .90:
CMP AL,128
JB .50:
MOV AL,'~'
.50: STOSB
JMP .10:
.90: RET
ENDP Fn14$FileName
Internal function trigerred by !15$ in VIEW_INDEX.Rem
Fn15$SaveMemberSize:: PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
PUSH RSI
LEA RSI,[R8+RDX]
LodD RSI
POP RSI
MOV [MemberSize],EAX
RET
ENDP Fn15$SaveMemberSize
Internal function trigerred by !16$ in VIEW_INDEX.Rem
Fn16$DisplayName:: PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV EAX,[R8+RDX]
CMP RAX,[InputSize::]
JA .90:
LEA RSI,[R8+RAX]
.10:LODSB
CMP AL,' '
JBE .90:
CMP AL,128
JAE .90:
STOSB
JMP .10:
.90:RET
ENDP Fn16$DisplayName
Internal function trigerred by !17$ in VIEW_INDEX.Rem
Fn17$DisplaySymbolName:: PROC
MOV ESI,[FaOfArchiveStrings]
ADD RSI,R8
.10:LODSB
CMP AL,0
JE .20:
STOSB
JMP .10:
.20:SUB RSI,R8
MOV [FaOfArchiveStrings],RSI
RET
ENDP Fn17$DisplaySymbolName
Internal function trigerred by !18$ in VIEW_INDEX.Rem
Fn18$MemberNumber PROC
MOV EAX,[MemberNumber]
INC EAX
MOV [MemberNumber],EAX
StoD RDI
RET
ENDP Fn18$MemberNumber
Internal function trigerred by !19$ in VIEW_INDEX.Rem
Fn19$OmfModuleName PROC
MOV EDX,[RBX+VIEW_INDEX.FA]
MOVZXW ECX,[R8+RDX+1]
SUB ECX,2
JB .90:
AND ECX,0x000000EF
PUSH RSI
LEA RSI,[R8+RDX+4]
REP MOVSB
POP RSI
.90: RET
ENDP Fn19$OmfModuleName
Internal function trigerred by !20$ in VIEW_INDEX.Rem
Fn20$ElfSectionName:: PROC ; Find a section header with .sh_offset and .sh_size equal to .FA and .Size.
JSt [Status::],ArgWidth64,.50:
MOV ESI,[R8+20h] ; FA of section headers in the file header. 0-th section header SHDR32 offset by file header.
MOV EDX,[RBX+VIEW_INDEX.FA] ; RBX describes section data.
XOR ECX,ECX ; ECX=Section number #0, #1, #2...
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF ; Get rid of level.
.10:CMP EDX,[R8+RSI+10h] ; Does it correspond to SHDR32 data offset?
JNE .20:
CMP EAX,[R8+RSI+14h] ; Does it correspond to SHDR32 data size?
JE .30:
.20:ADD ESI,40 ; Try the next section header PHDR32.
INC ECX
CMP CX,[R8+30h] ; Number of section headers by file header.
JB .10:
JMP .90:
.30:; Found section header #ECX at RSI which corresponds with this data.
MOV EAX,ECX
StoD RDI ; Section number.
MOV AL,' '
STOSB
MOV EAX,[R8+RSI+0] ; Get section name (offset in .shstrtab).
ADD EAX,[FaOfShstrtabData]
LEA RSI,[R8+RAX]
.40:LODSB
CMP AL,0
JZ .90:
STOSB
JMP .40:
.50:MOV ESI,[R8+28h] ; FA of section headers in the file header. 0-th section header SHDR64 offset by file header.
MOV EDX,[RBX+VIEW_INDEX.FA]
XOR ECX,ECX ; ECX=Section number #0, #1, #2...
MOV EAX,[RBX+VIEW_INDEX.Size]
AND EAX,0x0FFF_FFFF ; Get rid of level.
.60:CMP RDX,[R8+RSI+18h] ; Does the FA correspond to SHDR64 data offset?
JNE .70:
CMP RAX,[R8+RSI+20h] ; Does the section contents .Size correspond to SHDR32 data size?
JE .80:
.70:ADD ESI,64 ; Try the next section header PHDR64.
INC ECX
CMP CX,[R8+3Ch] ; Number of section headers by file header.
JB .60:
JMP .90:
.80:; Found section header #ECX at RSI which corresponds with this data.
MOV EAX,ECX
StoD RDI ; Section number.
MOV AL,' '
STOSB
MOV EAX,[R8+RSI+0] ; Get section name (offset in .shstrtab).
ADD EAX,[FaOfShstrtabData]
LEA RSI,[R8+RAX]
.85:LODSB
CMP AL,0
JZ .90:
STOSB
JMP .85:
.90:RET
ENDP Fn20$ElfSectionName
Internal function trigerred by !21$ in VIEW_INDEX.Rem
Fn21$ElfSymbolName:: PROC ; Find the section which hosts symbol with [RBX+VIEW_INDEX.FA].
JSt [Status::],ArgWidth64,.50:
MOV ESI,[R8+20h] ; FA of 0-th section header SHDR64 by file header. RSI=FA of EHDR32.e_shoff.
XOR ECX,ECX
MOV EDX,[RBX+VIEW_INDEX.FA] ; EDX is FA of the symbol SYM32 (10h bytes). Find its section (.symtab).
.10: CMP EDX,[R8+RSI+10] ; Is symbol EDX within the range SHDR32.sh_offset..SHDR32.sh_offset+size
JB .20: ; of section header RSI?
MOV EAX,[R8+RSI+14h] ; SHDR32.sh_size
ADD EAX,[R8+RSI+10h] ; FA of end of SHDR32 data.
CMP EDX,EAX
JB .30: ; Jump if found .symtab or .dynsym section.
.20: ADD ESI,40 ; Try the next section header SHDR32.
INC ECX ; Section number.
CMP CX,[R8+30h] ; Number of section headers by file header.
JB .10: ; Exceeded this number of section headers (EHDR32.e_shnum)?
JMP .90:
.30: ; Found section header number ECX (.symtab or .dynsym section) at FA RSI which hosts this symbol.
MOV EAX,[R8+RSI+18h] ; SHDR32.sh_link - ordinal of section with .strtab (#0, #1, #2 etc).
MOV ECX,40 ; Size of SHDR32.
MUL RCX
ADD RAX,[R8+20h] ; FA of 0-th section header SHDR32 by file header.
MOV RCX,[R8+RAX+10h] ; FA of SHDR32.sh_offset of .strtab.
CMP RCX,[InputSize]
JNB .90:
ADD RCX,R8 ; RCX points to .strtab contents.
MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize]
JNB .90:
MOV EAX,[R8+RDX+0] ; SYM32.st_name (offset in string table).
LEA RSI,[RCX+RAX]
CMP RSI,[InputEnd]
JNB .90:
.40: LODSB
CMP AL,0
JZ .90:
STOSB
JMP .40:
.50: MOV RSI,[R8+28h] ; FA of 0-th section header SHDR64 by file header. RSI=FA of EHDR64.e_shoff.
XOR ECX,ECX
MOV EDX,[RBX+VIEW_INDEX.FA] ; EDX is FA of the symbol SYM64 (18h bytes). Find its section (.symtab).
.60: CMP RDX,[R8+RSI+18h] ; Is symbol EDX within the range SHDR64.sh_offset..SHDR64.sh_offset+size
JB .70: ; of section header RSI?
MOV RAX,[R8+RSI+20h] ; SHDR64.sh_size
ADD RAX,[R8+RSI+18h] ; FA of end of SHDR64 data.
CMP RDX,RAX
JB .80: ; Jump if found (.symtab or .dynsym section).
.70: ADD ESI,64 ; Otherwise try the next section header SHDR64.
INC ECX ; Section number.
CMP CX,[R8+3Ch] ; Exceeded this number of section headers (EDHR64.e_shnum)?
JB .60:
JMP .90:
.80: ; Found section header number ECX (.symtab or .dynsym) at FA RSI which hosts this symbol.
MOV EAX,[R8+RSI+28h] ; SHDR64.sh_link - ordinal of section with .strtab (#0, #1, #2 etc).
MOV ECX,64 ; Size of SHDR64.
MUL RCX
ADD RAX,[R8+28h] ; FA of 0-th section header SHDR64 by file header.
MOV RCX,[R8+RAX+18h] ; FA of SHDR64.sh_offset of .strtab.
CMP RCX,[InputSize]
JNB .90:
ADD RCX,R8 ; RCX points to .strtab contents.
MOV EDX,[RBX+VIEW_INDEX.FA] ; FA SYM64.
CMP RDX,[InputSize]
JNB .90:
MOV EAX,[R8+RDX+0] ; SYM64.st_name (offset in string table).
LEA RSI,[RCX+RAX]
CMP RSI,[InputEnd]
JNB .90:
.85: LODSB
CMP AL,0
JZ .90:
STOSB
JMP .85:
.90: RET
ENDP Fn21$ElfSymbolName
Internal function trigerred by !22$ in VIEW_INDEX.Rem
Fn22$ElfProgramSections:: PROC ; Number of sections which belong to the segment.
JSt [Status::],ArgWidth64,.50:
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV R12D,[R8+RDX+4+4] ; PHDR32.p_vaddr
MOV R11D,[R8+RDX+14h] ; PHDR32.p_memsz
ADD R11,R12 ; FA of end of program span.
MOV ESI,[R8+20h] ; EHDR32.e_shoff
XOR ECX,ECX ; Section counter.
.10:CMP CX,[R8+30h] ; EHDR32.e_shnum
JAE .90:
MOV EAX,[R8+RSI+0Ch] ; SHDR32.sh_addr
CMP EAX,R12D
JB .20:
CMP EAX,R11D
JA .20:
MOV AL,'#'
STOSB
MOV EAX,ECX
StoD RDI
MOV AL,' '
STOSB
.20:ADD ESI,40 ; Size of SHDR32
INC ECX
JMP .10:
.50:MOV EDX,[RBX+VIEW_INDEX.FA]
CMP RDX,[InputSize::]
JNB .90:
MOV R12,[R8+RDX+10h] ; PHDR64.p_vaddr
MOV R11,[R8+RDX+28h] ; PHDR64.p_memsz
ADD R11,R12 ; FA of end of program span.
MOV RSI,[R8+28h] ; EHDR64.e_shoff
CMP RSI,[InputSize::]
JNB .90:
XOR ECX,ECX ; Section counter.
.60:CMP CX,[R8+3Ch] ; EHDR64.e_shnum
JAE .90:
MOV RAX,[R8+RSI+10h] ; SHDR64.sh_addr
CMP RAX,R12
JB .70:
CMP RAX,R11
JA .70:
MOV AL,'#'
STOSB
MOV EAX,ECX
StoD RDI
MOV AL,' '
STOSB
.70:ADD ESI,64 ; Size of SHDR64
INC ECX
JMP .60:
.90: RET
ENDP Fn22$ElfProgramSections
Internal function trigerred by !23$ in VIEW_INDEX.Rem
Fn23$GifColorTableSize:: PROC ; Number of sections which belong to the segment.
MOV EDX,[RBX+VIEW_INDEX.FA]
MOV CL,[R8+RDX]
XOR EAX,EAX
TEST CL,0x80
JZ .80:
AND CL,0x07
INC CL
INC EAX
SHL EAX,CL
LEA EAX,[EAX+2*EAX]
MOV [SizeOfColorTable],EAX
.80:MOV ECX,EAX
StoH RDI,Size=3
MOV AX,'h='
STOSW
MOV EAX,ECX
StoD RDI
RET
ENDP Fn23$GifColorTableSize
Internal function trigerred by !24$ in VIEW_INDEX.Rem
Fn24$FileSize:: PROC ; Size of the input file hexadecimal and decimal.
MOV EAX,[InputSize]
StoH RDI,Size=8
MOV AX,'h='
STOSW
MOV EAX,[InputSize]
StoD RDI
RET
ENDP Fn24$FileSize
Internal function trigerred by !2$ and !5$ in VIEW_INDEX.Rem
FnStoreSectionName PROC ; ESI is FA of 8 byte section name. Store it to RDI. R8=InputPtr
ADD RSI,R8
LODSB
CMP AL,'/'
JNE .50
LodD RSI
MOV RSI,[FaOfStringTable]
ADD RSI,R8
ADD RSI,RAX
.20: LODSB
CMP AL,0
JE .90:
STOSB
JMP .20:
.50: MOV RAX,[RSI-1]
.60: CMP AL,0
JE .90:
STOSB
SHR RAX,8
JMP .60:
.90: RET
ENDP FnStoreSectionName
ENDPROGRAM viewmain