This repository was archived by the owner on Oct 11, 2022. It is now read-only.
forked from nickelsworth/swag
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0019.pas
More file actions
157 lines (148 loc) · 6.48 KB
/
Copy path0019.pas
File metadata and controls
157 lines (148 loc) · 6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
===========================================================================
BBS: Canada Remote Systems
Date: 07-03-93 (11:56) Number: 29412
From: KELD R. HANSEN Refer#: NONE
To: JON JASIUNAS Recvd: NO
Subj: Re: Self-modifying .EXEs Conf: (1221) F-PASCAL
---------------------------------------------------------------------------
In a message dated 28 Jun 93, Jon Jasiunas (1:273/216.0) wrote:
> Here's the code I use for my self-modifying .EXEs. I've used it
> successfully in several applications.
It works fine (I have one similar of my own), but it doesn't take care of DPMI
programs and won't work if your "customer" PKLITEs the program.
TYPE
ExeHeaderDOS = RECORD
{ 00 } Signature : ARRAY[1..2] OF CHAR;
{ 02 } LastPageSize : WORD;
{ 04 } Pages : WORD;
{ 06 } RelocItems : WORD;
{ 08 } HeaderSizePara : WORD;
{ 0A } MinMemPara : WORD;
{ 0C } MaxMemPara : WORD;
{ 0E } EntrySS : WORD;
{ 10 } EntrySP : WORD;
{ 12 } CheckSum : WORD;
{ 14 } EntryIP : WORD;
{ 16 } EntryCS : WORD;
{ 18 } FirstRelocItemOfs : WORD;
{ 1A } OverlayNumber : WORD;
Reserved : ARRAY[$1C..$23] OF BYTE;
{ 24 } IdentifierOEM : WORD;
{ 26 } InformationOEM : WORD;
ReservedToo : ARRAY[$28..$3B] OF BYTE;
{ 3C } NewExeHeaderOfs : LONGINT
END;
ExeHeaderOS2 = RECORD
Signature : ARRAY[1..2] OF CHAR;
LinkerMajorVers : BYTE;
LinkerMinorVers : BYTE;
EntryTableOfs : WORD;
EntryTableSize : WORD;
CRC : LONGINT;
ModuleFlags : WORD;
SegmentNoDGROUP : WORD;
HeapSize : WORD;
StackSize : WORD;
EntryIP : WORD;
EntryCS : WORD;
EntrySP : WORD;
EntrySS : WORD;
SegmentTableEntries : WORD;
ModuleRefEntries : WORD;
NonResNameTableSize : WORD;
SegTableOfs : WORD;
ResourceTableOfs : WORD;
ResNamesTableOfs : WORD;
ModuleRefTableOfs : WORD;
ImpNamesTableOfs : WORD;
NonResNamesTableOfs : LONGINT;
MovableEntryPoints : WORD;
AlignmentUnitPower : WORD;
ResourceTableEntries: WORD;
TargetOS : BYTE;
WindowsFlags : BYTE;
FastLoadStart : WORD;
FastLoadSize : WORD;
Reserved : WORD;
WindowsVers : WORD
END;
SegTableRec = RECORD
Start : WORD;
Size : WORD;
Flags : WORD;
MinSize : WORD
END;
FileOffset = LONGINT;
PROCEDURE ReadOnly;
INLINE($C6/$06/FileMode/$A0);
PROCEDURE ReadWrite;
INLINE($C6/$06/FileMode/$02);
{ ExeOfs returns the offset of the item V in the .EXE file of the currently }
{ running program. Use this to get the offset of a configuration record that }
{ is located in the .EXE file (remember that you must declare it as a typed }
{ constant to include it in the .EXE file) }
{$IFDEF DPMI }
FUNCTION ExeOfs(CONST V) : FileOffset;
VAR
HeaderDOS : ExeHeaderDOS;
HeaderOS2 : ExeHeaderOS2;
FIL : FILE;
CodeSeg,Seg : WORD;
SegTab : SegTableRec;
BEGIN
ReadOnly;
ASSIGN(FIL,ParamStr(0)); RESET(FIL,1);
BLOCKREAD(FIL,HeaderDOS,SizeOf(ExeHeaderDOS));
IF HeaderDOS.Signature<>'MZ' THEN
ExeOfs:=-1
ELSE BEGIN
SEEK(FIL,HeaderDOS.NewExeHeaderOfs);
BLOCKREAD(FIL,HeaderOS2,SizeOf(ExeHeaderOS2));
IF HeaderOS2.Signature<>'NE' THEN
ExeOfs:=-1
ELSE BEGIN
ASM
MOV BX,WORD PTR V+2
MOV CX,SS
CMP BX,CX
JE @STACK
XOR AX,AX
VERW BX
JZ @OUT
MOV ES,BX
MOV AX,ES:[0000h]
JMP @OUT
@STACK: MOV AX,HeaderOS2.EntrySS
@OUT: MOV CodeSeg,AX
END;
IF CodeSeg<>0 THEN BEGIN
SEEK(FIL,HeaderDOS.NewExeHeaderOfs+HeaderOS2.SegTableOfs+
PRED(CodeSeg)*SizeOf(SegTableRec));
BLOCKREAD(FIL,SegTab,SizeOf(SegTableRec)) END
ELSE BEGIN
SEEK(FIL,HeaderDOS.NewExeHeaderOfs+HeaderOS2.SegTableOfs);
FOR Seg:=1 TO HeaderOS2.SegmentTableEntries DO BEGIN
BLOCKREAD(FIL,SegTab,SizeOf(SegTableRec));
IF (SegTab.Start>0) AND (SegTab.Flags AND $0001=$0001) THEN BREAK
END
END;
ExeOfs:=SegTab.Start SHL HeaderOS2.AlignmentUnitPower+OFS(V)
END
END;
CLOSE(FIL);
ReadWrite
END;
{$ELSE }
FUNCTION ExeOfs(CONST V) : FileOffset;
VAR
HeaderDOS : ExeHeaderDOS;
FIL : FILE;
BEGIN
ReadOnly;
ASSIGN(FIL,ParamStr(0)); RESET(FIL,1);
BLOCKREAD(FIL,HeaderDOS,SizeOf(ExeHeaderDOS));
CLOSE(FIL);
ExeOfs:=(HeaderDOS.HeaderSizePara+(SEG(V)-(PrefixSeg+$0010)))*16+OFS(V)
END;
{$ENDIF }