[comp.sys.atari.st] Self Modifying code

covertr@force.UUCP (Richard E. Covert) (10/27/89)

I have a friend who has written some shareware programs
(ARCIT, ARCIT Shell, UNARCIT etc ) and he would like to
make his code self-modifying. IN particular he would like
to save the state of various buttons that he uses.

1) Write the data to an external file (*.CFG), but now
you have to maintain a PRG, a RSC and a CFG file. Clumsy.

2) Write to the RSC file, but my friend wants to incorporate
the RSC into the PRG (using RSCTOC or equivalent). So, there
may not be a RSC to write to.

3) Write to the PRG file. Best of all since you need it to
run his program!!




But how do you modify a PRG file on the run?? One idea is
to store some unique string of characters indicating the
start of a buffer region. Then the PRG could do a binary
search of itself to locate the string in the disk file,
and then overwrite the next XX bytes with the new config
data. But you would have to make certain that the search
string is unique.

Another idea is to reserve XX bytes at the end of the
PRG file. If you read in the PRG as a binary file you
could LSEEK to the end of the PRG and then LSEEK back
XX bytes.

Well, does anyone have any C code that could be used??

I am interested in this whole idea.

Rich Covert


How can one go about do this in C??

I have several ideas.

sirkm@ssyx.ucsc.edu (Greg Anderson) (10/27/89)

In article <46768dca.14a1f@force.UUCP> covertr@force.UUCP (Richard E. Covert) writes:
>... he would like to
>make his code self-modifying. IN particular he would like
>to save the state of various buttons that he uses.
>
>1) Write the data to an external file (*.CFG), but now
>you have to maintain a PRG, a RSC and a CFG file. Clumsy.

Far from clumsy, this solution is so elegant and simple it is a wonder
you would even consider anything else.

Some advice:

	1. Keep the CFG info in a human-readable (ASCII) format.
	2. If the CFG file doesn't exist, create it.

  ___\    /___               Greg Anderson              ___\    /___ 
  \   \  /   /         Social Sciences Computing        \   \  /   /
   \  /\/\  /    University of California, Santa Cruz    \  /\/\  /
    \/    \/              sirkm@ssyx.ucsc.edu             \/    \/

klute%trillian.irb@unido.uucp (Rainer Klute) (10/27/89)

In article <46768dca.14a1f@force.UUCP> covertr@force.UUCP (Richard E. Covert) writes:
>I have a friend who has written some shareware programs
>(ARCIT, ARCIT Shell, UNARCIT etc ) and he would like to
>make his code self-modifying. IN particular he would like
>to save the state of various buttons that he uses.
>
>1) Write the data to an external file (*.CFG), but now
>you have to maintain a PRG, a RSC and a CFG file. Clumsy.
>
>2) Write to the RSC file, but my friend wants to incorporate
>the RSC into the PRG (using RSCTOC or equivalent). So, there
>may not be a RSC to write to.
>
>3) Write to the PRG file. Best of all since you need it to
>run his program!!


No, no, no! Never write self-modifying code!

1. Self-modifying code is very bad style. It is difficult to
   write and even more difficult to understand. Programs that
   modify itself tend to be unmaintainable.

2. A lot of machines do not allow you to modify a program file
   for security aspects. Consider everyone on a multiuser
   system would be allowed to modify any file. Sure, this is
   not true for the Atari ST, but one should learn to do it the
   right way. Spend some time to figure out how to do it on e.
   g. a Unix system and you can to it equivalently on the ST.
   (Slight simplification here, but you got the idea, right?)

3. On a related topic: Several systems do not even allow you to
   modify your executing program while it is located in memory.
   You will only be allowed to write to the data portion of the
   program. This is due to the fact that on a multitasking
   system several tasks can execute one single program
   simultaneously. Now, if the program code can not be modified
   by the executing task it is sufficient to load the program
   into core only once, thus gaining a lot of efficiency. (Of
   course each program get it's individual data section.)

4. If you are afraid of virusses don't modify your program
   file. You (the average user) could never tell whether the
   program is modified by a virus or not. There are programs on
   the market (including the PD market) that estimate a certain
   checksum for each program and alarm you if this number
   changes. How could such a program tell if the change is due
   to a virus or not?

5. If you are afraid of virusses write protect your media as
   far as possible. A program that writes to it's program file
   needs to be run from a not write protected disk. This a
   unnessary and an avoidable security hole.

6. In the case you mention it is fully sufficient to maintain a
   .CFG file. Simply write out the following items for each
   button (or other object): index of root object, index of
   object within the root object, current flags of the object.
   Upon start of the program the whole stuff has to be read in
   again and the object flags set accordingly. Simple, isn't it?

If you considered this a flame it may be turned off now :-).

  Dipl.-Inform. Rainer Klute      klute@trillian.irb.informatik.uni-dortmund.de
  Univ. Dortmund, IRB             klute@unido.uucp, klute@unido.bitnet
  Postfach 500500         |)|/    ...uunet!mcvax!unido!klute
D-4600 Dortmund 50        |\|\    Tel.: +49 231 755-4663

R.D.Chafer@sysc.salford.ac.UK (11/16/89)

>Date: 13 Nov 89 01:12:27 GMT
>From: psuvm!sml108@psuvax1.cs.psu.edu
>Subject: Self-Modifying Code
>
>Hi, I am writing an assembly language routine which modifies its own code in
>a tight loop in order to avoid having to do a decision statement at every
>iteration.  Unfortunately, whatever code I am inserting is screwing things up
>royally, and although I have checked it fairly throughly, I cannot figure out
>what is going on.  Question:  Is there something screwy about executable and
>object files that would disallow self modifying.  The block that gets modified
>is this:
>
>         lsr.w   d3
>         bne     cont
>         add.l   #8,a0
>         move.w  #$8000,d3
>  cont:  nop
>
>Since branching is relative, one would think it would work, and a dump of
>the object file indicates this is so.    HELP !!!!
>
>Scott Le Grand
 
I don't know if this has been answered, but could the 68000's instruction
prefetch be causing the problem (The 68010 has a bigger prefetch I believe
which would probably cause problems). Instruction prefetch on a 68000 or
68010 is one good reason NOT to write self modifying code.
 
Robert Chafer
 
 
=========================================================================
From:  Robert Chafer
 
    Computing Centre             Telephone: +44 61 736 5843 x 672 or x7328,
    University of Salford,
    Salford M5 4WT
    UK
 
E-mail:
    JANET:   chafer @ uk.ac.salford.sysc
    ARPANET: chafer%uk.ac.salford.sysc @ nss.cs.ucl.ac.uk
    BITNET:  chafer%uk.ac.salford.sysc @ uk.ac
        or   chafer%uk.ac.salford.sysc%ukacrl.bitnet @ cunyvm.cuny.edu