Short:    Safer Setfunctions Debug Tools
Author:   thor@math.tu-berlin.de (Thomas Richter)
Uploader: thor@math.tu-berlin.de (Thomas Richter)
Version:  2.08
Type:     dev/debug
Requires: An Amiga, every model, every OS will do

_____________________________________________________________________________

                        The THOR-Software Licence


This License applies to the computer programs known as "SaferPatches" and 
"ShowPatch". The "Program", below, refers to such program.


The programs and files in this distribution are freely distributable
under the restrictions stated below, but are also Copyright (c)
Thomas Richter.


Distribution of the Program by a commercial organization without written
permission from the author to any third party is prohibited if any payment
is made in connection with such distribution, whether directly
(as in payment for a copy of the Program) or indirectly (as in payment
for some service related to the Program, or payment for some product
or service that includes a copy of the Program "without charge";
these are only examples, and not an exhaustive enumeration of prohibited
activities). However, the following methods of distribution involving
payment shall not in and of themselves be a violation of this restriction:


(i) Posting the Program on a public access information storage and
retrieval service for which a fee is received for retrieving information
(such as an on-line service), provided that the fee is not
content-dependent (i.e., the fee would be the same for retrieving the same
volume of information consisting of random data).



(ii) Distributing the Program on a CD-ROM, provided that the files
containing the Program are reproduced entirely and verbatim on such
CD-ROM, and provided further that all information on such CD-ROM be
redistributable for non-commercial purposes without charge.



Everything in this distribution must be kept together, in original
and unmodified form.




Limitations.

THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS NO
WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE
RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD
THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
SERVICING, REPAIR OR CORRECTION.



IF YOU DO NOT ACCEPT THIS LICENCE, YOU MUST DELETE ALL FILES CONTAINED IN
THIS ARCHIVE.

_____________________________________________________________________________


Purpose of this program:

	Make the SetFunction (= patch function) of the OS safer, allow 
	installation and removal of patches in any order.
	Record the patches made and the program that made the patch.

This program is mainly intended as a debugging tool, for recording the patches
installed and to capture illegal patches. It is, however, adviced to run with
SaferPatches installed permanently.

SaferPatches will free the additional memory occupied by the patched functions
automatically if a library is flushed later on.


	SYNOPSIS:

SaferPatches	INSTALL	REMOVE REMEMBER WARN


INSTALL		Add the "SaferPatches" patch to the system.
REMOVE		Remove "SaferPatches" from the system. You are, however,
		"recommanded" not to remove it once you've started it.
		
REMEMBER	This option can be given together with INSTALL. If present,
		SaferPatches will store the names of the programs together
		with the patch they added.

WARN		Saferpatches will guru with 0x10000026 if a removed vector
		is still used.


	SYNOPSIS:

ShowPatch	fd_dir

	Shows all patches added to the system, together with the entry point
	and the program that added the patch, if available - see the
	REMEMBER option of the Saferpatches program.

	If the "fd_dir" is given, ShowPatch will read standard ".fd"
	library descriptions from that subdirectory and will present the
	name of the entry point that has been patched as well.


_____________________________________________________________________________

Compatibility:

	"SaferPatches" is NOT compatible to the following illegal patches:
(see below for what is considered to be legal)

	-CEDPatch



The way "SaferPatches" operates conflicts with my debug utility "MemSniff".
If you want to run both, "MemSniff" and "SaferPatches", you should add the
command line option "SNIFF" to SaferPatches. You shouldn't provide that
option in other situations.


VirusZ might report that libraries got patched from time to time. This is
because SaferPatches modifies the Expunge vector of all libraries in order
to free the memory occupied by the patches if the library gets closed. This
warning message is harmless.


IMPORTANT:	!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Saferpatches MUST be run BEHIND SetPatch !!!!!!!!!!!!!!!!!
IMPORTANT:	!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!	


SaferPatches IS compatible to the debug tool PatchWork.

_____________________________________________________________________________

Gurus:

	Because "SaferPatches" is supposed to be a debug utility, it may
create "guru meditations", i.e. software alerts. The following alerts may
be created by SaferPatches:

0x01000020		Patch vector out of range.
		A program tried to patch a vector in a library that isn't
		present.

0x01000021		Entry is not patchable.
		A program tried to install a patch into a vector that can't
		be patched. Some vectors, like the GetCC() vector of
		the exec lib are directly inlined functions that can't be
		changed with SaferPatches. Same goes for the DOS library
		of releases 32 to 35, but this has changed starting with
		releases 36 and up of the OS.

0x01000022		No mem for patch vector.
		SaferPatches failed to allocate memory for the patch.

0x01000023		Patched vector to ROM.
		A program attempted to patch one ROM vector to a second
		vector which is actually in the ROM. Replacing one system
		function by a different one is considered to be illegal.

0x01000024		Found libentry without patches
		SaferPatches found a library in its patch list that isn't
		actually patched. This is an internal failure and shouldn't
		occur.

0x01000025		Unsafe patch
		A program tried to patch one vector that can't be patched in
		a safe way because it is called by the SetFunction procedure
		itself. One example is "SetFunction", or "SumLibrary".

0x01000026		Removed libentry called
		A libvector that has been removed was illegally called again.
		A program restored an older patch, but was still calling the
		obsolete return vector. This can only happen with WARN 
		enabled.

0x01000027		Function pointer is NULL
		Somebody tried to patch a function to NULL.

_____________________________________________________________________________

Legal vs. illegal patching:

Three operations are considered to be "legal" patching operations:

1)	Install a patch
2)	Remove a patch
3)	Verify, if a given patch is installed.

3) is new to this implementation of SaferPatches and not having it messed the
system with the RTPatch program.


A legal way how to install a patch: (with or without SaferPatches)

	-Call Forbid() or even Disable() in critical cases.
	-Load the address of the new function in d0, the offset in a0,
	 the library and a1, and ExecBase in a6.
	-Call SetFunction()
	-Store the return value of SetFunction as pointer to the old function.
	-Call Permit() or Enable().


The following methods of installing patches ARE ILLEGAL:

	-Forgetting to Permit()/Forbid().
	-Reading the vector directly from the library vectors instead of
	 using the return value.
	-Using the return code of SetFunction for anything else except
	 jumping into the old code.
	-Patching one OS function to a different one.
	-Patching functions that can't be patched, like inline functions
	 or functions called by SaferPatches. This includes the functions
	 CacheClearU(), SetFunction() and SumLibrary().
	-Using anything else but the return code of SetFunction for calling
	 the old function.
	-Writing the new function directly into the vector offset.


A legal way to remove a patch: (with SaferPatches)

Even though the procedures presented below remove a patch vector safely from 
the os (ONLY the vector, NOT the code) IT DOES NOT PREVENT, WITH SAFERPATCHES 
INSTALLED OR NOT, THAT SOME TASK IS STILL EXECUTING THE CODE OF YOUR PATCH. 
This is, you may not freely deallocate the memory your patch resides in.
Removing patches is always a problem, it is not recommended to release the
patch memory at all UNLESS YOU CAN REALLY, ABSOLUTELY ENSURE THAT NO TASK IS 
EXECUTING YOUR CODE. There is, however, no general guide line how to do that.

The following algorithm "works" IF YOU KNOW the patch is installed and
SaferPatches is installed. It DOES NOT work around general patch caveats:

	-Load d0 with the return code of SetFunction you got when installing 
	 the patch. Load a1 with the base address of the library. Load a6
	 with execbase.
	-Call SetFunction().


A legal and safe way to remove a patch: (with or without SaferPatches)

The following mechanism is recommended for general patch removal. Please
note THAT THIS MIGHT FAIL and you won't be able to remove your patch at all.
It WON'T fail with SaferPatches, though. It does, too, not work around the
code memory caveats from above.

	-Call Forbid() or Disable().
	-Call SetFunction() with the same arguments AS IF you are installing
	 the patch again, this is:
	 Load the address of the new function in d0,the library base in a1
	 and ExecBase in a6 and offset in a0. Call SetFunction.
	-Check the return code:
		If this is the entry point of your patch, then:
		-Load d0 with the return code of SetFunction when installing 
		 the patch. Load a1 with the base address of the library. 
		 Load a6 with execbase.
		-Call SetFunction().
		These calls will remove your patch.
		
		If this is not the address of your patch, then:
		-Load d0 with THIS return code of SetFunction, i.e. what
		 you got from the call a few lines on top. Load a1 with 
		 the base address of the library. Load a6 with execbase.
		-Call SetFunction().
		This will re-install the last patch. 
		YOUR PATCH CAN'T BE REMOVED SAFELY IN THIS CASE 
		(SaferPatches is not running).
	-Call Permit() or Enable().


The following methods of removing a patch ARE ILLEGAL:

	-Use anything else but the return code of the installing SetFunction
	 for removing the patch again.
	-Removing the new function by writing the old return code directly
	 into the vector offset.
	-Executing the steps above not completely in Forbid() mode, i.e.
	 call Permit() in between or calling any other os function that
	 might break the forbid.


A legal way how to verify whether your patch is still installed: 

This algorithm can be used to check if your patch is still active, using
SaferPatches. It will only tell you if the patch is "frontmost" if Safer-
Patches is not installed.

	-Call Forbid() or Disable()
	-Call SetFunction with the same arguments AS IF you are installing
	 the patch again, this is:
	 Load the address of the new function in d0,the library base in a1
	 and ExecBase in a6 and offset in a0. Call SetFunction.
	-Check the return code. If it is the same pointer you passed in d0
	 to SetFunction, your patch is still active. It has been installed
	 now, by the procedure above and must/can be removed if desired/
	 required with a second call to SaferPatches. It will NOT be
	 installed twice by this algorithm, neither with nor without 
	 SaferPatches.
	-Call Permit() or Enable().

This method is used by the RTPatch program and also considered to be legal.

The following verify methods are considered to be illegal:

	-Failing to call Forbid().
	-Reading the vector entry from the vector base directly.


How to check if SaferPatches is installed:

	-Call FindPort("SetMan"). If the result is non-zero, SaferPatches,
	 SetMan or PatchControl is installed. Do not use this port for
	 anything else.

	-Call FindPort("SaferPatches.rendezvous"). If the result is non-
	 zero, it's specifically SaferPatches. There's usually no need to
	 to check for this port. Don't use this port for anything else!

_____________________________________________________________________________

New in 2.08:

Hopefully fixed a minor compatibility problem with PoolMem and MuGuardian-
Angel.
_____________________________________________________________________________


New in 2.07.1:

Updated the ReadMe a bit.


New in 2.07:

Added another GURU, added the WARN option to turn off the 0x01000026 guru.
Patched the close function for completeness (forgot again about the delayed
expunge function, sigh.). Updates the SHOWPATCH program. Added a SetMan port
of completeness.
_____________________________________________________________________________

New in 2.06:

Added a new GURU and fixed a bug of the Expunge replacement. Thanks to
Magnus for reporting!
_____________________________________________________________________________

Thomas,
	May 1998


============================= Archive contents =============================

Original  Packed Ratio    Date     Time    Name
-------- ------- ----- --------- --------  -------------
    3496    2294 34.3% 30-May-99 00:37:58 +SaferPatches
   13021    4860 62.6% 30-May-99 00:39:12 +SaferPatches.readme
    5004    3347 33.1% 09-Nov-97 23:44:56 +ShowPatch
-------- ------- ----- --------- --------
   21521   10501 51.2% 31-May-99 22:09:08   3 files
