====== 4d2011-02 Listings ======
===== Top–One–Partitur =====
Die Bilder zum Beitrag von Hannes Teich im Original - klicken um zu vergrößern.
{{:vd-archiv:listings:topone_01_noten.png?200|Notenblatt}}
{{:vd-archiv:listings:topone_01_partitur.png?200|Partitur}}
===== Anzeigen von Strukturen =====
{{ :vd-archiv:listings:anzeigen_von_strukturen.zip |Listings aus dem Artikel "Anzeigen von Strukturen"}} gepackt. Und entpackt:
==== DUMPPEH.4TH ====
\ =============
\ DUMPPEH.4TH
\ Das Programm
\ =============
DECIMAL
\ Die hier definierten Worte werden vorwiegend sofort ausgefuehrt.
warning off \ nicht für Bigforth
marker dumpmarker \ Wegen den Redefinitionen, am Ende alles 'vergessen'.
\ ------------------------------------------------------------------------------
\ Kommentar über mehreren Zeilen für Bigforth.
: (( ( -- )
BEGIN
bl word dup @
[ hex ffffff decimal ] literal and
[ hex 292902 decimal ] literal <>
WHILE
c@ 0= IF refill drop THEN
REPEAT
drop
; immediate
\ ------------------------------------------------------------------------------
\ Definition der Strukturworte.
: structur
CREATE here 0 , 0 \ ( "bname" -- dfa ofs=0 )
DOES> @ \ ( dfa -- nbytes )
CREATE allot \ ( "sname" nbytes -- )
;
: field \ ( "fname" ofs field.dfa -- ofs+fsize )
CREATE over , +
DOES> @ + \ ( base dfa -- base+ofs )
;
: endstructur \ ( dfa nbytes -- )
swap !
;
\ ------------------------------------------------------------------------------
\ Redefinition der Strukturworte.
24 CONSTANT ntab \ Tabulatorwert
0 VALUE fval \ Aktueller Feld-Wert
0 VALUE ofsh \ laufender Offset beim einlesen
0 VALUE defflag \ -1 bei Redefinitionen
\ Konversion.
: >fstring ( string0 -- str len )
0 BEGIN 2dup + c@ WHILE 1+ REPEAT
;
\ Sektionname ausgeben.
: .section_name ( string0 -- )
>fstring 8 min 8 over - spaces type
;
\ Strukturname anzeigen.
: structur2 ( ccc<*> -- ) cr cr bl word count type ;
\ Feldwert in hex ausgeben, Sektion-Name ausgeben.
: field2 ( size -- )
base @ swap hex
bl word count dup >r cr type
ntab r> - spaces
( size ) dup
CASE
1 OF ofsh c@ dup to fval 8 u.r ENDOF
2 OF ofsh w@ dup to fval 8 u.r ENDOF
4 OF ofsh @ dup to fval 8 u.r ENDOF
8 OF ofsh .section_name ENDOF
DUP OF 8 spaces ENDOF
ENDCASE
2 spaces
( size ) ofsh + to ofsh
base !
;
: endstructur2 ( -- ) noop ;
\ Sektion-Attribute anzeigen.
: attribute ( -- )
[ hex ]
fval 20000000 and IF ." ausfuehren " THEN
fval 40000000 and IF ." lesen " THEN
fval 80000000 and IF ." schreiben " THEN
[ decimal ]
;
: rem ( -- ) source >in ! drop ;
\ Steuerung der Strukturworte, bedingtes Kommentarwort.
: structur defflag IF structur2 ELSE structur THEN ;
: field defflag IF field2 ELSE field THEN ;
: endstructur defflag IF endstructur2 ELSE endstructur THEN ;
: \? defflag IF noop ELSE rem THEN ;
\ Zum gezieltes 'include' der Strukturen, werden diese Worte spaeter mit
\ 'noop' oder 'rem' belegt.
DEFER doshdr
DEFER pehdr
DEFER sectionhdr
DEFER importhdr
\ ------------------------------------------------------------------------------
\ Struktur-Prototypen anlegen, Windows-Header laden und Zeiger setzen.
24 CONSTANT ntfile_size
40 CONSTANT section_size
1000 CONSTANT header_size \ Programmkopf-Groesse
\
\ Basis der Strukturen
0 VALUE dos{}
0 VALUE ntfile{}
0 VALUE optional{}
0 VALUE section0{}
\
0 VALUE peheader \ vorhanden ( -1 )
0 VALUE #section \ Anzahl der Sektionen
0 VALUE fid \ Datei-Kennung
CREATE basepage header_size chars allot \ Buffer
\ Fehlermeldungen.
: dumpend1 ( -- ) cr ." Datei nicht vorhanden" dumpmarker abort ;
: dumpend2 ( -- ) cr ." Kein Windows-Header vorhanden" dumpmarker abort ;
\ Kontrolle.
: ?openerror ( n -- ) IF dumpend1 THEN ;
: ?winheader ( n -- ) $5a4d <> IF dumpend2 THEN ;
: ?peheader ( n -- ) $4550 <> IF dumpend2 THEN ;
\ Struktur-Definition aktivieren.
\ alle Strukturen anlegen.
0 to defflag
' rem is doshdr
' rem is pehdr
' rem is sectionhdr
' rem is importhdr
\ Struktur-Prototypen anlegen.
includepath_pe INCLUDED
: windows_header_laden ( -- )
path\name count r/o OPEN-FILE ?openerror to fid
basepage header_size fid READ-FILE 2drop
basepage to dos{}
dos{} e_magic w@ ?winheader \ 'MZ' ?
dos{} e_lfanew @ ( ofs ) \ NTFILE_HEADER-Offset
dup $100 u<
IF
( ofs ) dos{} + to ntfile{} \ NTFILE_HEADER-Basis
ntfile{} Signature @ ?peheader \ 'PE' ?
-1 to peheader
ntfile{} NumberOfSections w@ to #section \ Anzahl der Sektionen
ntfile{} ntfile_size + to optional{} \ OPTIONAL_HEADER-Basis
ntfile{} SizeOfOptionalHeader w@ \ OPTIONAL_HEADER-Laenge
optional{} + to section0{} \ SECTION_HEADER-Basis
ELSE
drop \ DOS-Header
THEN
;
windows_header_laden
\ ------------------------------------------------------------------------------
\ Strukturen mit redefinierten Worten nochmal laden. Sie werden jetzt angezeigt.
\ Index nach Adresse transformieren.
: section{} ( i -- adr ) section_size * section0{} + ;
\ Windows-Header anzeigen.
: .winheader ( -- )
page
-1 to defflag \ Struktur-Redefinition aktivieren
peheader
IF \ pe_header anzeigen
ntfile{} to ofsh
['] rem is pehdr
['] noop is doshdr
['] noop is sectionhdr
['] noop is importhdr
includepath_pe INCLUDED
ELSE \ dos_header anzeigen
dos{} to ofsh
['] rem is doshdr
['] noop is pehdr
['] noop is sectionhdr
['] noop is importhdr
includepath_pe INCLUDED
dumpmarker quit \ Ende
THEN
;
\ Sektionen anzeigen.
: .sections ( -- )
peheader
IF \ section_header anzeigen
['] rem is sectionhdr
['] noop is pehdr
['] noop is doshdr
['] noop is importhdr
#section 0
DO
i section{} to ofsh
includepath_pe INCLUDED
LOOP
THEN
;
.winheader
.sections
\ ------------------------------------------------------------------------------
\ Sektion suchen, wo die Import-Funktionen liegen.
0 VALUE virtual_size \ VirtualSize
0 VALUE virtual_address \ VirtualAddress
0 VALUE raw_size \ SizeOfRawData
0 VALUE raw_pointer \ PointerToRawData
\ Die Adresse ImportDirectoryRva @ (Eintrag vom OPTIONAL_HEADER) muss zwischen
\ VirtualAddress und VirtualAddress+VirtualSize der Sektion liegen.
: search_importsection ( -- )
#section 0
DO
i section{}
dup SizeOfRawData @ to raw_size
dup PointerToRawData @ to raw_pointer
dup VirtualAddress @ to virtual_address
dup VirtualSize @ to virtual_size
drop
optional{} ImportDirectoryRva @
virtual_address dup virtual_size + WITHIN IF leave THEN
LOOP
;
search_importsection \ Virtualaddress (Offset)
\ ------------------------------------------------------------------------------
\ Import-Funktionen anzeigen.
\
\ Die IMPORT_DESCRIPTOREN bilden ein Array von Strukturen.
\ Die letzte ist eine Struktur mit lauter Nullen.
CREATE importsection{} raw_size chars allot \ Array von IMPORT_DESCRIPTOREN
0 VALUE import0{} \ 1. IMPORT_DESCRIPTOR
20 CONSTANT importsize \ Länge
\ Weitere IMPORT_DESCRIPTOREN.
: import{} ( i -- adr ) importsize * import0{} + ;
\ Offset nach absolute Adresse transformieren.
: ofs>mem ( offset -- mem_adr )
virtual_address - importsection{} +
;
\ Importsection laden und Zeiger setzen
: importsektion_laden ( -- )
raw_pointer s>d fid REPOSITION-FILE drop
importsection{} raw_size fid READ-FILE 2drop
fid CLOSE-FILE drop
optional{} ImportDirectoryRva @ ofs>mem to import0{}
;
\ Import-Funktinen anzeigen.
: .import ( -- )
base @ hex
10 0 DO
cr
i import{} DllName @ dup 0<>
IF
( Name der dll-Datei anzeigen )
cr ." IMPORTIERTE FUNKTIONEN AUS " ofs>mem >fstring type
i import{} PointerToThunkData @
BEGIN
dup ofs>mem @ dup 0<>
WHILE
( Nummer und Name der Funktionen anzeigen )
dup ofs>mem w@ cr 4 .r space
2 + ofs>mem >fstring type
4 +
REPEAT
2drop
ELSE
drop leave
THEN
LOOP
base !
cr
;
importsektion_laden
.import
dumpmarker \ alles 'vergessen'
==== DUMPWORD.4TH ====
\ ====================
\ DUMPWORD.4TH
\ Das Ausfuehrungswort
\ ====================
DECIMAL
CREATE path\name 64 chars allot \ Dateiname
: includepath_pe ( -- str len ) s" demos\winheader\pe.inc" ;
: includepath_dump ( -- str len ) s" demos\winheader\dumppeh.4th" ;
: DUMPPEH ( "pfad\name" -- )
nostack \ nur fuer Win32for
bl word count path\name place
includepath_dump INCLUDED
;
\ finis
==== PE.INC ====
\ ===============
\ PE.INC
\ Die Strukturen
\ ===============
DECIMAL
doshdr ((
\? cr .( HEADER VON ) path\name count type
structur IMAGE_DOS_HEADER
2 field e_magic \? .( 'MZ')
2 field e_cblp \? .( Laenge des letzten Sektors Modulo 512)
2 field e_cp \? .( Dateigroesse in 512 Byte-Seiten)
2 field e_crlc \? .( Laenge der Relocation-Tabelle)
2 field e_cparhdr \? .( Headergroesse in Paragraphen [je 16 Byte])
2 field e_minalloc \? .( Anzahl.min der Paragraphen)
2 field e_maxalloc \? .( Anzahl.max der Paragraphen)
2 field e_ss \? .( Stack-Segment-Offset)
2 field e_sp \? .( Inhalt des SP Registers beim Start)
2 field e_csum \? .( Checksumme in Zweierkomplement)
2 field e_ip \? .( Inhalt des IP Registers beim Start)
2 field e_cs \? .( Code-Segment-Offset ab Programmanfang)
2 field e_lfarlc \? .( Relocation-Tabelle-Offset)
2 field e_ovno \? .( Overlaynummer 0 fuer den residenten Teil)
8 field res1 \? .( reserviert)
2 field e_oemid \? .( OEM-Bezeichner)
2 field e_oeminfo \? .( OEM-Info)
20 field e_res2 \? .( reserviert)
4 field e_lfanew \? .( reserviert für Offset zum NTFILE_HEADER)
endstructur
doshdr ))
pehdr ((
\? cr .( HEADER VON ) path\name count type
structur NTFILE_HEADER
4 field Signature \? .( 'PE')
2 field Machine \? .( 014Ch=i386)
2 field NumberOfSections \? .( Anzahl der Sektionen)
4 field TimeDateStamp
4 field PointerToSymbolTable \? .( für debugging)
4 field NumberOfSymbols \? .( für debugging)
2 field SizeOfOptionalHeader \? .( Laenge vom OPTIONAL_HEADER)
2 field Characteristic \? .( Flags)
endstructur
structur OPTIONAL_HEADER
2 field Magic \? .( 10b)
1 field MajorLinkerVersion
1 field MinorLinkerVersion
4 field SizeOfCode \? .( Code)
4 field SizeOfInitializedData \? .( initialisierte Daten
4 field SizOfUninitializedData \? .( nicht initialisierte Daten)
4 field AddressOfEntryPoint \? .( Start relativ zur Ladeadresse)
4 field BaseOfCode \? .( Codebasis relativ zur Ladeadresse)
4 field BaseOfData \? .( Datenbasis relativ zur Ladeadresse)
4 field ImageBase \? .( Ladeadresse)
4 field SectionAlignment \? .( Granularitaet im Speicher)
4 field FileAlignment \? .( Granularitaet in der Datei)
2 field MajorOsVersion
2 field MinorOsVersion
2 field MajorImageVersion
2 field MinorImageVersion
2 field MajorSubsystemVersion
2 field MinorSubsystemVersion
4 field Win32VersionValue
4 field SizeOfImage \? .( Speicherverbrauch)
4 field SizeOfHeaders
4 field CheckSum
2 field Subsystem \? .( 2=Windows, 3=Console)
2 field DllCharacteristics
4 field SizeOfStackReserve
4 field SizeOfStackCommit
4 field SizeOfHeapReserve
4 field SizeOfHeapCommit
4 field LoaderFlags
4 field NumberOfRvaAndSizes
4 field ExportDirectoryRva \? .( Offset zum EXPORT_DESCRIPTOR)
4 field ExportSize
4 field ImportDirectoryRva \? .( Offset zum IMPORT_DESCRIPTOR)
4 field ImportSize
112 field DataDirectory
endstructur
pehdr ))
sectionhdr ((
structur SECTION_HEADER
8 field SectionName
4 field VirtualSize \? .( Anzahl der Bytes im Speicher)
4 field VirtualAddress \? .( Offset in Speicher)
4 field SizeOfRawData \? .( Laenge in der Datei)
4 field PointerToRawData \? .( Offset in der Datei)
4 field PointerToRelocations
4 field PointerToLinenumbers
2 field NumberOfRelocations
2 field NumberOfLinenumbers
4 field Characteristics1 \? attribute
endstructur
sectionhdr ))
importhdr ((
structur IMPORT_DESCRIPTOR
4 field PointerToThunkData \ Adresse der Struktur THUNK_DATA
4 field TimeDateStamp1
4 field ForwarderChain
4 field DllName \ Name der dll-Datei
4 field FirstThunk
endstructur
structur THUNK_DATA
4 field ForwarderString \ Name der Funktion: db fnummer,0,'Text',0
4 field Function
4 field Ordinal
4 field AddressOfData
endstructur
importhdr ))