[comp.sys.amiga.tech] Patching dos.library

ddave@pnet02.cts.com (David Donley) (03/25/89)

Hi.  Could somebody give me some code on patching a dos.library function? 
(ExNext to be more precise)  I would like to write a patch to make files with
the hidden bit invisible (Gee I thought it was supposed to do that already) 
I've tried SetFunction, and also something that stuffed my address into the
library directly, but neither worked, so I guess I'm not doing it right.
Thanks.

              Don't call my BBS, my harddisk left me for a 2500.
          Disclaimer: If it doesn't work, I guess it's broken ain't it?
     ddave@pnet02.CTS.COM ddave@pnet.gryphon.COM killer!gryphon!pnet02!ddave

aleks@well.UUCP (Brian J. Witt) (03/27/89)

In article <13731@gryphon.COM> you write:
>Hi.  Could somebody give me some code on patching a dos.library function? 
>(ExNext to be more precise)  I would like to write a patch to make files with
>the hidden bit invisible (Gee I thought it was supposed to do that already) 
>I've tried SetFunction, and also something that stuffed my address into the
>library directly, but neither worked, so I guess I'm not doing it right.
>Thanks.
>

The problem:  For each call to Examine()/ExNext() you wish to filter out
 files that have a certain file attribute bit that you have decided to
 call HIDDEN.  How do you patch AmigaDOS?

Possible Solution:  For each call to Examine()/ExNext, after DOS calls
 the device handler, you check if a certain HIDDEN bit is set.  If yes,
 then retry the Examine operation.  If after many attempts at finding a
 non-hidden file, DOS returns IOERR_NO_MORE_ENTRIES_IN_THIS_SEARCH, then
 you finally return to the caller.

The dos.library is not a common library the way Carl would like to see
it.  Each vector entry contains code like:
        moveq  #9,D0               <--- offset into GlobVec table(?)
        bra.s  common_hanlder
I told this to Andy Finkel a few years back, and he nope, you're wrong--
doesn't even happen.  To patch a function I recommond tracing through
it and find where it loads  DosLib->dl_A2.  This is GlobVec.
The code soon indexes through this pointer, I believe,  like:
        jmp   0(A2,D0)
This address is the _real_ function in BCPL.  At this point you are in 
the BCPL environment, and all its register conventions now apply.  Any BCPL
code (like DIR and LIST) call through the Global Vector Table, completely
bypassing dos.library, which is around mostly for "C" programmers.  The
code you jump to here just finds the handler, formats a packet, sends
it off, then waits for the reply.

Inside of BCPL, you can find two parameters in registers, and the rest
are on the stack (A7).  After your routine has checked for the HIDDEN
bit, perform  JMP (A6)  to return to your caller.  Remember the stack
grows toward high addresses.

When patching any library jump vector, you should create a WEDGE of
sorts sothat your loading program may unload itself, and also sothat
the vector may be restored at a later time.  The "true and unadultered
facts about SetFunction()'ing library vectors" is revealed in the 
Washington DC DevCon notes.  For register conventions, check some
Fred Fish disks for BCPL interfacing routines.  Good Luck  :-) :-)

>     ddave@pnet02.CTS.COM ddave@pnet.gryphon.COM killer!gryphon!pnet02!ddave

"Sometimes doctor, when I wake up in the morning, I just don't know who I am..."
               --- confessions of an Abstract Data Type

--- brian witt
--- USNET:  well!aleks@ucbvax.berkeley.edu

andy@cbmvax.UUCP (Andy Finkel) (03/30/89)

In article <11110@well.UUCP> aleks@well.UUCP (Brian J. Witt) writes:
>In article <13731@gryphon.COM> you write:
>>Hi.  Could somebody give me some code on patching a dos.library function? 
>>(ExNext to be more precise)  I would like to write a patch to make files with
>>the hidden bit invisible (Gee I thought it was supposed to do that already) 
>>I've tried SetFunction, and also something that stuffed my address into the
>>library directly, but neither worked, so I guess I'm not doing it right.
>>Thanks.
>>
>
>The problem:  For each call to Examine()/ExNext() you wish to filter out
> files that have a certain file attribute bit that you have decided to
> call HIDDEN.  How do you patch AmigaDOS?
>
>Possible Solution:  For each call to Examine()/ExNext, after DOS calls
> the device handler, you check if a certain HIDDEN bit is set.  If yes,
> then retry the Examine operation.  If after many attempts at finding a
> non-hidden file, DOS returns IOERR_NO_MORE_ENTRIES_IN_THIS_SEARCH, then
> you finally return to the caller.
>
>The dos.library is not a common library the way Carl would like to see
>it.  Each vector entry contains code like:
>        moveq  #9,D0               <--- offset into GlobVec table(?)
>        bra.s  common_hanlder
>I told this to Andy Finkel a few years back, and he nope, you're wrong--
>doesn't even happen.  To patch a function I recommond tracing through

Correct.  By this I mean, the BCPL programs do not go through the
C interface; instead they go through their own table (called
the global vector).  The move/branch to a common routine stuff
is what Tim implemented to wrap a BCPL environment around
the AmigaDOS calls.  Eventually, a call on the library vector
goes through the global vector.  However, the BCPL programs
go directly to the global vector.

This is why, after you patch dos.library, your patch will only
seem to function sometimes.

BTW, turned out that, according to the Exec manual, any 6 bytes
will do for a function.  Including functions that aren't even
jumps, like:

moveq#0,d0
rts

So Tim's branches are legal, at least according to Carl's design.

>Inside of BCPL, you can find two parameters in registers, and the rest
>are on the stack (A7).  After your routine has checked for the HIDDEN
>bit, perform  JMP (A6)  to return to your caller.  Remember the stack
>grows toward high addresses.

Now for the rest of the bad news :-)  Sure, we'd prefer people don't
patch the global vector, since (I hope) that code will break under 1.4...
but that's not the bad news.  The global vector is regenerated
(from the rom table) every time a new cli process gets created.  So
any GV patch is temporary; until the next newcli.

		andy
-- 
andy finkel		{uunet|rutgers|amiga}!cbmvax!andy
Commodore-Amiga, Inc.

"Give me a Standard large enough, and a Committee to discuss it,
 and I will prevent the Earth from moving."

Any expressed opinions are mine; but feel free to share.
I disclaim all responsibilities, all shapes, all sizes, all colors.

pl@etana.tut.fi (Pertti Lehtinen) (03/30/89)

From article <6439@cbmvax.UUCP>, by andy@cbmvax.UUCP (Andy Finkel):
> In article <11110@well.UUCP> aleks@well.UUCP (Brian J. Witt) writes:
>>
>>The dos.library is not a common library the way Carl would like to see
>>it.  Each vector entry contains code like:
>>        moveq  #9,D0               <--- offset into GlobVec table(?)
>>        bra.s  common_hanlder
>>I told this to Andy Finkel a few years back, and he nope, you're wrong--
>>doesn't even happen.  To patch a function I recommond tracing through
> 
> This is why, after you patch dos.library, your patch will only
> seem to function sometimes.
> 
> BTW, turned out that, according to the Exec manual, any 6 bytes
> will do for a function.  Including functions that aren't even
> jumps, like:
> 
> moveq#0,d0
> rts

	I look exec manual and realized that SetFunction
	does not return anything.

	That seems strange, because I thought that it returns
	address of old function. ( At least i've seen someone
	using t that way)

	I wonder which is true.

					Pertti Lehtinen
					pl@tut.fi

pl@tut.fi				! -------------------------------- !
Pertti Lehtinen				!  Alone at the edge of the world  !
Tampere University of Technology	! -------------------------------- !
Software Systems Laboratory

eric@cbmvax.UUCP (Eric Cotton) (03/31/89)

In article <6587@etana.tut.fi> pl@etana.tut.fi (Pertti Lehtinen) writes:
>	I look exec manual and realized that SetFunction
>	does not return anything.
>
>	That seems strange, because I thought that it returns
>	address of old function. ( At least i've seen someone
>	using t that way)
>
>	I wonder which is true.

SetFunction does indeed return a pointer to the old function.

	oldFunc = SetFunction(library, funcOffset, funcEntry)
-- 
Eric Cotton
Commodore-Amiga                                               (215) 431-9100
1200 Wilson Drive                        {uunet|pyramid|rutgers}!cbmvax!eric
West Chester, PA 19380            "I don't find this stuff amusing anymore."

pl@etana.tut.fi (Pertti Lehtinen) (03/31/89)

From article <6462@cbmvax.UUCP>, by eric@cbmvax.UUCP (Eric Cotton):
> 
> SetFunction does indeed return a pointer to the old function.
> 
> 	oldFunc = SetFunction(library, funcOffset, funcEntry)

	That makes things interesting.

	How does find out the address of original function?

	Does it copy old stub somewhere and return address to that?

	Or does it simply use stub as normal library stub (jmp xxx),
	and return xxx.  In this case it isn't surprising that
	it doesn't work with DOS-library.

	Exec manual don't say anything about return value,
	so does it just happen
	under certain circumstances or is it on purpose?

					Pertti Lehtinen
					pl@tut.fi
pl@tut.fi				! -------------------------------- !
Pertti Lehtinen				!  Alone at the edge of the world  !
Tampere University of Technology	! -------------------------------- !
Software Systems Laboratory

jesup@cbmvax.UUCP (Randell Jesup) (04/04/89)

In article <6614@etana.tut.fi> pl@etana.tut.fi (Pertti Lehtinen) writes:
>From article <6462@cbmvax.UUCP>, by eric@cbmvax.UUCP (Eric Cotton):
>> 
>> 	oldFunc = SetFunction(library, funcOffset, funcEntry)
...
>	Or does it simply use stub as normal library stub (jmp xxx),
>	and return xxx.  In this case it isn't surprising that
>	it doesn't work with DOS-library.

	Yes.  This is why it doesn't work properly with dos.library,
since dos.library isn't a jmp xxxx.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup