blog.jmp.no

Electronics, coding and hacking. And ADD.

« Exploring the Arcade1UP Work in progress: APECAT »

Patching the live Amiga ROM

2019
27
February

As I'm adressing the previous issue with the APECAT board, I'm trying my best to simultaneously plan ahead and clear the road for future obstacles.

One of the issues I want out of the way is patching the Amiga system ROM, commonly known as the Kickstart.

As implied, the Kickstart is stored in Read-Only Memory. Physically reprogramming it in situ is pretty much impossible, but thankfully the Amiga developers thought ahead and made a shadow copy of the address vector table in RAM. This table can easily be updated using the exec.library's SetFunction(), which is what I'll be attempting today.

In the example below I'll be overloading the dos.library's Open() function. To prove it's doing its job, I'll be flashing the screen every time it's called, followed by jumping to the native, original Open() code afterwards.

For those of you not fluent in 68k assembly, I've included some comments to outline the basics.

; exec.library:
MEMF_PUBLIC=1
_LVOAllocMem=-198
_LVOForbid=-132
_LVOPermit=-138
_LVOOpenLibrary=-408
_LVOCloseLibrary=-414
_LVOSetFunction=-420

; dos.library:
_LVOOpen=-30

start:
	*************************************************
	* Open dos.library
	*************************************************

	move.l 4.w,a6
	lea dosname(pc),a1
	moveq #0,d0
	jsr _LVOOpenLibrary(a6)

	lea dosbase(pc),a0
	move.l d0,(a0)

	*************************************************
	* Store original function address
	*************************************************

	move.l d0,a6
	lea _LVOOpen(a6),a0
	lea jump(pc),a1
	move.l 2(a0),2(a1)

	*************************************************
	* Prohibit multitasking and allocate memory
	*************************************************

	move.l 4.w,a6
	jsr _LVOForbid(a6)

	moveq #new_open_function_length,d0
	moveq #MEMF_PUBLIC,d1
	jsr _LVOAllocMem(a6)
	bne.b .memOK
	moveq #2,d1
	bra.b .closeDos

.memOK:
	*************************************************
	* Copy code to allocated memory
	*************************************************

	move.l d0,a1
	lea new_open_function(pc),a0
	moveq #[new_open_function_length/2]-1,d1
.copy:	move.w (a0)+,(a1)+
	dbra d1,.copy

	*************************************************
	* SetFunction and permit multitasking
	*************************************************

	lea (_LVOOpen).w,a0
	move.l 4.w,a6
	move.l dosbase(pc),a1
	jsr _LVOSetFunction(a6)
	jsr _LVOPermit(a6)

	*************************************************
	* Close lib and exit
	*************************************************

.closeDos:
	move.l dosbase(pc),a1
	jsr _LVOCloseLibrary(a6)
	moveq #0,d0
	rts

	*************************************************
	* My fake custom function
	*************************************************

new_open_function:
	move.l #5000,d0
.s:	move.w d0,$dff180
	dbra d0,.s
jump:	jmp $0
new_open_function_length=*-new_open_function

dosbase:dc.l 0
dosname:dc.b 'dos.library',0

...and that's it. We've successfully patched the ROM, and here it is in action to prove that it works. I'm running the program, and then loading a file, which consequentally triggers the Open() function in dos.library. As you can see, the screen flashes in many colors before loading the file.


This is also an accidental step-by-step tutorial in case you want to write a virus for the Amiga. Just make it survive a reset and let Hell break loose. Or not. Please don't.

But why do I want to patch the Kickstart in the first place? And why would I patch it before anything has been loaded or is running? Make a guess and wait for the next post. Bonus points if you get it right.


Share:

to Patching the live Amiga ROM

Feed for this Entry

0 Comments

    There are currently no comments.

About You

Email address is not published.

All messages must be validated by the admin.

Spam messages or messages containing URLs linking to spam, will never be published.

Add to the Discussion

Add to Google