[comp.sys.mac.programmer] converting tail patches to head patches...

sonenbli@oxy.edu (Andrew D. Sonenblick) (11/27/89)

      Ok, with the recent barage of bonfires (ie, big flaming going on) against
      tail patches, I have been trying to convert some of my tail patches to
      head patches.  However, I have as yet been unseccessful and would
      appreciate it if all you major hackers would look at my code snipets
      and comment on them... (ie, tell me what is wrong!)

      How things were in the Tail Patch:

      myPatch()
      {
      ...
      doMyStuff();
      asm{
	   Lea	   @1,A0   <- @1 contains the address of _SysTask via NGet...
	   Move.L  (A0),A0
	   Jsr	   (A0)
	 }   /* this is a tail patch since I jsr to _SysTask instead of Jmp  */

      ...
      }

      Now, how I changed things for to make it a head patchy-watchy...

      myPatch()
      {
      long  rtsAddr;
      asm{
	   Move.L    (SP)+,rtsAddr	   /* save return address in rtsAddr */
	 }
      doMyStuff();
      asm{
	   Move.L    rtsAddr,-(SP)
	   Lea	     @1,A0
	   Move.L    (A0),A0
	   Jmp	     (A0)
	 }

      }

      Ok, so, what's the ups with this?  (I have tried all sorts of things
      similar to this--most just make my mac hang, some crash, none works.)

      Needless to say, if anyone has insights into this, I--perhaps others
      on the net would too--would appreciate the help.

      Thanks, much.  Ando Sonenblick: sonenbli@oxy.edu

________________________________________________________________________________
Have you ever tried to interpret the sound of your floppy drives:  mine sound
like "whumpa, whumpa, grind, grind," which I interpret to mean "Disregard every
third work by Neitzche..."

chewy@apple.com (Paul Snively) (11/28/89)

First of all, thanks for making the effort to avoid tail-patching! :-)

Now, to work:

In article <63359@tiger.oxy.edu> sonenbli@oxy.edu (Andrew D. Sonenblick) 
writes:
>       Now, how I changed things for to make it a head patchy-watchy...
> 
>       myPatch()
>       {
>       long  rtsAddr;
>       asm{
>            Move.L    (SP)+,rtsAddr         /* save return address in 
rtsAddr */
>          }
>       doMyStuff();
>       asm{
>            Move.L    rtsAddr,-(SP)
>            Lea       @1,A0
>            Move.L    (A0),A0
>            Jmp       (A0)
>          }
> 
>       }
> 
>       Ok, so, what's the ups with this?  (I have tried all sorts of 
things
>       similar to this--most just make my mac hang, some crash, none 
works.)
> 
>       Needless to say, if anyone has insights into this, I--perhaps 
others
>       on the net would too--would appreciate the help.

A couple of comments:

Since the problem with tail-patching is that the ORIGINAL code that you're 
calling may check the return address, your approach of removing the return 
address at the beginning of the patch and replacing it immediately before 
jumping to the original code doesn't help.  In fact, one reason that 
you're probably crashing is because you've done the same thing 
(semantically) as if you had simply changed your original JSR to a JMP!  
Not a good idea.

Now for the good news: if you're trying to patch _SystemTask, you can 
probably get away with it, because I don't believe that _SystemTask is 
called from within the ROM, which means that it won't be patched by us 
with this nasty come-from code that's causing all of the headaches.  As 
Larry Rosenstein pointed out, you have a higher probability of being 
"patch safe" with traps that have a high probability of not being called 
from ROM.

Hope this helps.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

tim@hoptoad.uucp (Tim Maroney) (11/28/89)

In article <63359@tiger.oxy.edu> sonenbli@oxy.edu (Andrew D. Sonenblick) writes:
>      myPatch()
>      {
>      long  rtsAddr;
>      asm{
>	   Move.L    (SP)+,rtsAddr	   /* save return address in rtsAddr */
>	 }
>      doMyStuff();
>      asm{
>	   Move.L    rtsAddr,-(SP)
>	   Lea	     @1,A0
>	   Move.L    (A0),A0
>	   Jmp	     (A0)
>	 }
>      }
>
>      Ok, so, what's the ups with this?  (I have tried all sorts of things
>      similar to this--most just make my mac hang, some crash, none works.)

Almost certainly, it's the fact that you moved the stack pointer at the
wrong time and by the wrong amount.  This is the sort of code you
should always step through with a low-level debugger; it'll show you
what's happening very fast.  So anyway, allocating an automatic
variable causes that storage to be pushed on the stack.  So, you are
saving rtsAddr in rtsAddr and trashing it at the same time, since it's
probably the top of the stack.  There's no reason to save/restore
rtsAddr at all; it's right where you want it to be.  You are not taking
into account the A6 frame pointer, either.  In other words, lotsa
problems.  Here's my stab at it:

      myPatch()
      {
      doMyStuff();
      asm{
          unlk      a6
          Lea       @1,A0	; @1 is a dc.l that has the old trap stashed
          Move.L    (A0),A0
          Jmp       (A0)
        }
      }

This should work (but I haven't tested it and I make no guarantees).
If it's not clear, take a look at Figure 5 of Inside Mac, Chapter 4
(page IM I-97).  And if your have a problem, put a break on the trap
you're patching, using MacsBug, then step into it and watch what
happens....

Hope this works for you.  One more thing -- there are a lot of Mac
programmers outside the United States, many of whom read and post
to this newsgroup.  People shouldn't limit the distribution to usa
unless there's some pressing reason to do so, like distributing the
Mac source to a DES encrypter or something.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Mere opinion without supporting argument is no more than the American
 Bandstand school of literary evaluation."  -- Tom Maddox

chaffee@reed.bitnet (Alex Chaffee,(259),,2369505) (11/29/89)

In article <9099@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>      myPatch()
>      {
>      doMyStuff();
>      asm{
>          unlk      a6
>          Lea       @1,A0	; @1 is a dc.l that has the old trap stashed
>          Move.L    (A0),A0
>          Jmp       (A0)
>        }
>      }

What is the syntax one should use for setting up a dc.l from within Think
C?  With scoping as I understand it, the @1 would have to refer to somewhere
_within_ the function, and you haven't declared it...  So shouldn't it go
something like this:

long OldTrap;	/* global - some initialization routine sets this */

myPatch()
{
	doMyStuff();
	asm {
		br.s 	@2
@1		dc.l
@2		move.L	OldTrap, @1
		unlk	A6
		move.L	@1, A0
		move.L	(A0), A0
		jmp	(A0)
	}
}

I'm sure there are a dozen things wrong with the syntax (and it would be
very educational to be corrected), but how's the idea?  By the way, if this
works, I will use it instead of my old method, which is

	asm {
		move.l	OldTrap, A0	; or A1, for some traps
		unlk	A6
		jmp	(A0)
	}

(if I remember correctly).

                "Nor is it a consequence of my bed's being covered with
                 leaves that I am not hallucinating that it is."
                 - Barry Stroud
____________________
--
Alex Chaffee
chaffee@reed.UUCP
____________________

tecot@Apple.COM (Ed Tecot) (11/30/89)

In article <5437@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>Now for the good news: if you're trying to patch _SystemTask, you can 
>probably get away with it, because I don't believe that _SystemTask is 
>called from within the ROM, which means that it won't be patched by us 
>with this nasty come-from code that's causing all of the headaches.  As 
>Larry Rosenstein pointed out, you have a higher probability of being 
>"patch safe" with traps that have a high probability of not being called 
>from ROM.

Actually, Paul is wrong.  SystemTask is called from ROM, in particular, by
ModalDialog and WaitNextEvent.  It's possible that it is called in other
places as well.  However, it is called in relatively few places (compared
to NewHandle or GetResource), and is therefore safer to tail patch.  Note,
that it is not 100% safe, and in this case, it's relatively easy to convert
the tail patch to a head patch, since SystemTask doesn't return anything.
Use

MySystemTask
	(your patch goes here)
	JMP	OldSystemTask

instead of

MySystemTask
	JSR	OldSystemTask
	(patch code here)
	RTS

and your code is 2 bytes shorter and 24 cycles faster as well.

						_emt

christer@cs.umu.se (Christer Ericson) (12/01/89)

In article <9099@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
> . . . . . . . . . .  People shouldn't limit the distribution to usa
>unless there's some pressing reason to do so, like distributing the
>Mac source to a DES encrypter or something.

And why should someone want to limit the distribution of a DES encryptor? 
If someone wants to know about DES all they have to do is look it up in
just about any serious computer journal. Afraid of commies are we?

>Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

/Christer


| Christer Ericson            Internet: christer@cs.umu.se [130.239.1.101] |
| Department of Computer Science, University of Umea, S-90187 UMEA, Sweden |
| "Track 0 sector 0 must *always* load into page 8!" -Krakowicz' first law |

ge@kunivv1.sci.kun.nl (Ge' Weijers) (12/04/89)

christer@cs.umu.se (Christer Ericson) writes:

>In article <9099@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>> . . . . . . . . . .  People shouldn't limit the distribution to usa
>>unless there's some pressing reason to do so, like distributing the
>>Mac source to a DES encrypter or something.

>And why should someone want to limit the distribution of a DES encryptor? 
>If someone wants to know about DES all they have to do is look it up in
>just about any serious computer journal. Afraid of commies are we?

No, of course not. Only afraid of the NSA. The NSA thinks you need
a US passport to be able to write a DES encriptor. They need not worry.
As far as I know DES is assumed to be insecure overhere. :-)

Maybe US citizens need to be more afraid of their security agencies than 
he Russians of the KGB these days. (no :-) this time, sorry)

>>Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

>/Christer

Ge'

Ge' Weijers                                    Internet/UUCP: ge@cs.kun.nl
Faculty of Mathematics and Computer Science,   (uunet.uu.net!cs.kun.nl!ge)
University of Nijmegen, Toernooiveld 1         
6525 ED Nijmegen, the Netherlands              tel. +3180612483 (UTC-2)
Ge' Weijers                                    Internet/UUCP: ge@cs.kun.nl
Faculty of Mathematics and Computer Science,   (uunet.uu.net!cs.kun.nl!ge)
University of Nijmegen, Toernooiveld 1         
6525 ED Nijmegen, the Netherlands              tel. +3180612483 (UTC-2)

tim@hoptoad.uucp (Tim Maroney) (12/05/89)

In article <9099@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
> . . . . . . . . . .  People shouldn't limit the distribution to usa
>unless there's some pressing reason to do so, like distributing the
>Mac source to a DES encrypter or something.

In article <1989Dec1.140641.13414@cs.umu.se> christer@cs.umu.se (Christer
Ericson) writes:
>And why should someone want to limit the distribution of a DES encryptor? 
>If someone wants to know about DES all they have to do is look it up in
>just about any serious computer journal. Afraid of commies are we?

I *am* a commie, you silly person.  I'm considerably more afraid of
the NSA.  There are export restrictions on decrypting software, and
they are taken pretty seriously.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Starting in a hollowed log of wood -- some thousand miles up a river, with an
 infinitesimal prospect of returning!  I ask myself 'Why?' and the only echo
 is 'damned fool! ... the Devil drives!"
	-- Sir Richard Francis Burton in correspondence to Monckton Miles, 1863