[Back to EXEC SWAG index] [Back to Main SWAG index] [Original]
{
OK. Maybe this isn't exactly what you were asking for, but I've seen quite a
number of variations on this peeka-boo-into-the-exe-file, so I felt I just had
to write a comment to this matter.
Using some kind of a magic constant, which is then searched for in the exe
file, probably is the most common approach to this kind of problem. But there's
really no need to do a search. You can calculate exactly where any const is (or
should be) located.
The trick is to use a couple of simple facts:
1/ The size of the exe header, in paragraphs, is located at byte 8 in the
header (actually it's a word made up by bytes 8 and 9 but I still haven't seen
an exe header of more than 4k, so I make it simple for myself using only the
byte).
2/ After the exe header comes the code segment and then directly the data
segment. Thus the size of the code segment can be calculated by a simple dseg-
cseg. Still talking paragraphs.
3/ Now we've reached the data segment in the exe file. The location in the
data segment can be found with ofs. Here we're talking bytes.
Using these facts, here's a simple sample that let's you change a const
string to whatever paramstr(1) you supply. Hope you'll be able to pick out the
stuff you may find any need for.
Since this code was extracted from a pretty small program I once wrote, it
uses the rather crude method to read the entire exe file into a buffer, and
then creating a new file blockwriting the entire buffer. If your program is
larger than 64k you obviously need to use some other method.
}
program SelfModifier; (* Looks for a const and alters it *)
(* Puts paramstr(1) into Name *)
const
Name : string = 'Fix me up'; {get 256 bytes to play with}
type
Buffer = array[0..$3fff] of byte;
var
ExeFile : file;
P : ^Buffer;
N,I,O : word;
NStr : string;
begin
begin
new(P); {get mem for our buffer}
assign(ExeFile,paramstr(0)); {get myself}
reset(ExeFile,1);
blockread(ExeFile,P^,sizeof(Buffer),N);
close(ExeFile); {got it into Buf, now close it}
O:=(dseg-cseg+word(P^[8])) shl 4; {start of data seg in exe file}
writeln('Name: ',Name);
NStr := paramstr(1); {new string to put in Name}
inc(O,ofs(Name)); {where Name is located}
move(NStr[0],P^[O],length(NStr)+1); {move string incl. length byte}
rewrite(ExeFile,1); {create new version}
blockwrite(ExeFile,P^,N); {write it}
close(ExeFile); {close it...}
dispose(P) {...and release mem}
end
end.
[Back to EXEC SWAG index] [Back to Main SWAG index] [Original]