Ok, this is a wierd request:
I want to write a program to modify a program i have written. In other
words, i would ship the main program with this modifyer program which could
subsequently be used to modify various settings in the main program. The
main program would then be modified semi-permenantly - it would remember
its settings even if it was moved to another computer, with no other files,
but could be edited again in the future.
If you still don't know what i am talking about, the program "Sub 7" uses
this ability to great effect. It is a trogan (although the program i am
writing is beneficial and legal!) comprising of a server program, a client
program and a server modifying program. Firstly you use the modifyer to set
up the way the server behaves on the victim computer, the server program is
then "saved" and is then permenantly modified, and requires no ini files, or
registry enteries to function, the server is sent off to the victim and even
on a different computer, works with the settings it was given with the
modifyer.
So, 1) is this possible in delphi?
and 2) how?
Thanks very much for any replies.
Jeff
More general changes than this won't happen with simple minded modifier
programs,
because the modifier program must typically know:
a) the complete grammar of the Delphi language,
b) the semantic rules (name scoping, typing rules, computation semantics,
semantics of external procedurs called by the modified
program).
This is a much harder task.
Our DMS Reengineering Toolkit is designed to exactly this harder task,
by using generalized compiler technology.
See http://www.semdesigns.com/Products/DMS/DMSToolkit.html.
--
Ira D. Baxter, Ph.D.,CTO email: idba...@semdesigns.com
Semantic Designs, Inc. web: http://www.semdesigns.com
12636 Research Blvd. C-214 voice: (512) 250-1018 x140
Austin, TX 78759-2200 fax: (512) 250-1191
"Jeff" <je...@profish.fsnet.co.uk> wrote in message
news:976m5k$5c6$1...@news5.svr.pol.co.uk...
Maybe someone could post a reply about resource files in Windows
programs. .DFM files are AIUI just fancy .RES files, and you can hold
resources in .RES files as well - your program's icon, version numbers
and other stuff. And you can have strings in resource files as well,
using ResourceString (under "Resource String" in the help on my
machine - not found under "ResourceString"). My understanding was that
such resources are linked to the exe file but were not part of the
program; they get read into the program at run-time. And you should be
able to change them with a resource editor.
Now, if a resource editor can change these strings, there must be a
well-defined format for such resources in a .EXE file, regardless of
what language the .EXE was written in. Part of the .EXE spec or
something. You could have your program settings in ResourceString
constants. Then your question becomes: how does one write a resource
editor? And I don't know that; but at least, if the above is true, it
must be possible, and maybe someone even has a component for it
somewhere.
FP
updateresource() to change a resource in an exe file
only works in NT not w98, so you have above 98 use that in your patcher
otherwise use something like the test stubs cutnpaste below, with better checks
be aware that it doesn't update the exe checksums, or bother with making itself
pretty for the exe
so will blow up anything that honours checksums or expects its own data at the end of a file
there are a lot better ways of doing what you want
to have an exe save its own data into its own executable is a little harder
// add data to end of target exe
// replace any existing data block and truncate to new length if previous was longer
procedure TForm1.appenddataClick(Sender: TObject);
var F:thandle;
var S:string;
var fpos:integer;
var ca:array[1..100] of char;
var count:integer;
var TS:Tstringlist;
begin
TS:=tstringlist.create;
F:=createfile('target.exe',Generic_READ or GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if F <> INVALID_HANDLE_VALUE then
begin
fpos:=setfilepointer(F,-100,0,FILE_END);
readfile(F,ca,100,cardinal(fpos),0);
for count := 100 downto 1 do
if strlcomp(@(ca[count]),pchar('exedata'),7)=0 then break;
if strlcomp(@(ca[count]),pchar('exedata'),7)=0 then
begin
fpos:=setfilepointer(F,-(100-count+1),0,FILE_END);
TS.settext(@(ca[count]));
memo1.lines.add('was registered to '+ TS.values['reguser']);
end
else
memo1.lines.add('no exedata found');
// data block starts with 'exedata' , ending with #0 and CR/LF seperation makes it easy to parse into a stringlist
S:='exedata'+#13#10+'reguser=nobody'#13#10+'pos1=1'+#13#10+'pos2=45'+#13#10#0;
strpcopy(@ca,S);
writefile(F,ca,length(S),cardinal(fpos),0);
fileclose(F);
end
else
memo1.lines.add('open file failure');
end;
// read the data at end of current exe
procedure TForm1.readmydataClick(Sender: TObject);
var F:thandle;
var fpos:integer;
var ca:array[1..100] of char;
var count:integer;
var TS:Tstringlist;
begin
TS:=tstringlist.create;
F:=createfile(pchar(paramstr(0)),Generic_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
if F <> INVALID_HANDLE_VALUE then
begin
fpos:=setfilepointer(F,-100,0,FILE_END);
readfile(F,ca,100,cardinal(fpos),0);
for count := 100 downto 1 do
if strlcomp(@(ca[count]),pchar('exedata'),7)=0 then break;
if strlcomp(@(ca[count]),pchar('exedata'),7)=0 then
begin
TS.settext(@(ca[count]));
memo1.lines.add('registered to '+ TS.values['reguser']);
end
else
memo1.lines.add('no exedata found');
fileclose(F);
end
else
memo1.lines.add('open file failure');
end;
the code compiles with only a few warnings about 0 converted to nil
D3 doesn't like them at all, and some of the call parameters are typed differently
D3 corrections posted in email
if the ema is wrong give a hint that it is please
the errors flagged by D3 are clearly indicated by the IDE and easily fixed
If possible, can you post here? If not, I will email you.
Thank you.
the code is from the 'how can I do this' projects,
doesn't everyone have hundreds of these? ;-)
so it is just meant to work and illustrate not be transportable
they would require more checks and elaboration for anything but a
very simple small chunk of data,
the differences are just in type checking and function protyping between D3 and higher versions
the IDE puts the cursor at the locations changed below
either that or you have some checking options set that I don't that are causing the errors
> >
> >// add data to end of target exe
> >// replace any existing data block and truncate to new length if previous was longer
> >procedure TForm1.appenddataClick(Sender: TObject);
> >var F:thandle;
> >var S:string;
> >var fpos:integer;
> >var ca:array[1..100] of char;
> >var count:integer;
> >var TS:Tstringlist;
> >begin
> > TS:=tstringlist.create;
> > F:=createfile('target.exe',Generic_READ or GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
F:=createfile('target.exe',Generic_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);
> > if F <> INVALID_HANDLE_VALUE then
> > begin
> > fpos:=setfilepointer(F,-100,0,FILE_END);
fpos:=setfilepointer(F,-100,nil,FILE_END);
> > readfile(F,ca,100,cardinal(fpos),0);
readfile(F,ca,100,fpos,nil);
> > for count := 100 downto 1 do
> > if strlcomp(@(ca[count]),pchar('exedata'),7)=0 then break;
> > if strlcomp(@(ca[count]),pchar('exedata'),7)=0 then
> > begin
> > fpos:=setfilepointer(F,-(100-count+1),0,FILE_END);
fpos:=setfilepointer(F,-(100-count+1),nil,FILE_END); //magics to write new data exactly over old data
> > TS.settext(@(ca[count]));
> > memo1.lines.add('was registered to '+ TS.values['reguser']);
> > end
> > else
> > memo1.lines.add('no exedata found');
> > // data block starts with 'exedata' , ending with #0 and CR/LF seperation makes it easy to parse into a stringlist
> > S:='exedata'+#13#10+'reguser=nobody'#13#10+'pos1=1'+#13#10+'pos2=45'+#13#10#0;
> > strpcopy(@ca,S);
> > writefile(F,ca,length(S),cardinal(fpos),0);
writefile(F,ca,length(S),fpos,nil);