Disassembler
Volume Number: 1
Issue Number: 6
Column Tag: MacNosy
A New Disassembler
By Steve Jasik
A New Disassembler
As a compiler writer specializing in code generation, I decided to build a
Disassembler to better understand the Motorola 68000 and the Macintosh operating
system. Given the poor quality of the documentation and the general lack of source
listings, a powerful disassembler is a useful tool for debugging and getting information
about the system.
MacNosy and its helper programs consist of over 7000 lines of Pascal and about
300 lines of assembly lanaguage code. Internally, MacNosy contains many features
usually associated with a compiler such as a table manager, symbol table enter/lookup
routines, a reference map, global flow analysis, etc.
Features
MacNosy has many features that place it an order of magnitude above other
disassemblers. They include:
• Symbol dictionaries of the Rom names and global symbols (0 - $B00) along with
value to symbol substitution in appropriate places.
• Selective list of procedures in a file by procedure name or substring.
• Ability to place the disassembled output on a file in assembler listing output or
assembler input format (MDS “.list” or “.asm” format).
• References to the symbols are collected and may be selectively viewed.
• Ability to search the program file for references to selected address’s, trap
(rom) calls, resource type references, constant or string references.
• Ability to translate the segment relative address of an instruction to the disk file
relative address for code patching purposes.
• MacNosy records its input on a “.jrnl” file (in text format) for later playback.
This feature is used as an educational tool and as a medium of communication
between developers, hackers, etc.
• Ability to reformat data in its “natural format” via directives. This is in
addition to the automatic recognition of various character string formats.
• A full or selective listing of the resources in a file. Format is similar to that of
the Resource Mover, but you get more information with less work.
• A built-in mini editor to view files without leaving Nosy.
Facts and Specifications
MacNosy runs on a 512K Mac or a 1 Meg Lisa under the Workshop O.S. or the
Macworks environment.
It is capable of disassembling the resource fork of any application file, ROM,
Macsbug, and various resource types in the System file (DRVR, PACK, INIT, CDEF,
WDEF, etc). Note that source listing of the WDEF, CDEF procedures come with the
MacSupplement.
The released disk contains both the Mac and Lisa versions of MacNosy, some
sample “.jrnl’ files to acquaint you with it, source code for the table manager (this
may be useful to other developers) and the SfGetFile routines so you can see how it
selects files to disassemble.
How does MacNosy work?
When disassembling a file, one must know the structure (code or data) of a given
piece of the file. To do this, Nosy uses the fact that every program has a “call graph”.
The nodes of the graph are the procedures and the edges are the calls (A calls B, etc).
As Nosy is primarily interested in the size of the nodes, it ignores some aspects of the
graph (such as recursion) which leads to cycles in the graph. Because of this, the
graph reduces to a Directed Acyclic (without cycles) Graph. We can get sloppy in our
terminology and refer to the DAG as a “tree of procedures”.
Discovering the size and extent of a procedure is a messy problem that entails
disassembling instructions, and looking for the procedure exits. The potential
presence of spaghetti code makes the algorithm more complicated.
At this point a reasonable strategy is to treat the file as a collection of code and
data blocks (contigious set of bytes). We start at the entry points and walk the tree
until all possible procedures have been discovered. The remaining areas are
caterogized as “data” blocks. During the tree walk Nosy builds symbol tables for the
various categories of labels which are:
Procedure (JSR X) X = proc’nnn’ or the 8 character name following the proc if
compiled by Lisa Pascal with the D+ option on.
Global labels ( X(A5) )
X = glob’nnn’
Data labels (LEA X or PEA X)
X = data’nnn’
Common labels (JMP X, Bcc X from another proc) - com_’nnn’
Local labels within a procedure - loc_’nnn’
You can change the names of all but the local labels in Nosy.
Example 1 - A fragment of the resource list of a System file.
Note that for the DITL’s the accompanying text/controls are listed.
26 resource types, data index = 100
Type FRSV att indx length name
ID 1 00 CF12 A 0 0
Type ALRT att indx length name
ID -3997 20 CDBC C 0 0
ID -3996 20 CDCC C 0 0
ID -3995 20 CDDC C 0 0
ID -3994 20 CDEC C 0 0
Type DITL att indx length name
ID -15936 20 BA6C 1E
ID -6047 20 CA18 1A6
Do you want to initialize it?
This disk is unreadable:
This disk is damaged:
This is not a Macintosh disk:
Please name this disk:
Initializing disk . . .
Initialization failed!
Initialize this disk?
ID -4000 20 CC7C A8
h
ID -3999 20 CD28 90 Save as:
Example 2 - code fragment from a little test program I wrote.
The output listing format is:
aaa: hhhh hhhh ‘cccc’ label opcode address $ssaaaaaa
aaa = segment relative address , hhhh and ccccc are the value of the instruction in
hex and ascii. The field ssaaaaaa is the address of any label or symbol reference
in the
address field. ss is the segment number of the reference.
I have suppressed leading zeros in most cases and many of the numeric formats
use decimal conversion. The macros POP and PUSH have the obvious meaning. The
QUAL pseudo implies that all the labels of the form loc_nnn are local to the procedure.
The line right after it tells us who calls it. The line with “_Button” is a trap macro.
The DNAME macro expands to the 8 character name which is used by Lisabug and Nosy.
440: QUAL CHK_USER
; refs - TEST
440:
440: 4E56 0000 ‘NV..’ CHK_USER LINK A6,#0
444: 4267 ‘Bg’ CLR -(A7)
446: A974 ‘.t’ _Button
448: 101F ‘..’ POP.B D0
44A: 6714 ‘g.’ BEQ loc_2
$1000460
44C: 2F0E ‘/.’ PUSH.L A6
44E: 4EBA FFC0 ‘N...’ JSR WAITBUTT
$1000410
452: 4267 ‘Bg’ loc_1 CLR -(A7)
454: A974 ‘.t’ _Button
456: 101F ‘..’ POP.B D0
458: 67F8 ‘g.’ BEQ loc_1
$1000452
45A: 2F0E ‘/.’ PUSH.L A6
45C: 4EBA FFB2 ‘N...’ JSR WAITBUTT
$1000410
460: 4E5E ‘N^’ loc_2 UNLK A6
462: 4E75 ‘Nu’ RTS
464:
464: C348 data21 DNAME CHK_USER,0,2
Example 3 - This next routine was dumped to the hardcopy file in
“.asm” format.
It is suitable for input to the MDS assembler ASM.
QUAL WCR
; refs - TEST

WCR LINK A6,#0
PUSH.L glob13(A5)
PEA data19
CLR -(A7)
JSR %W_STR
PUSH.L glob13(A5)
JSR %W_LN
PUSH.L glob12(A5)
PEA glob8(A5)
PUSH #255
JSR %R_STR
PUSH.L glob12(A5)
JSR %R_LN
UNLK A6
RTS

data18 DNAME WCR ,0,2

; refs - WCR+8
data19 STR ‘wait for cr’
Example 4 - Note the Value to Symbol substitution in this ROM fragment
listing
404C12: 50F8 0902 ‘P...’ Launch S_T LaunchFlag
$902
404C16: 31E8 0004 0936 ‘1....6 loc_2 MOVE 4(A0),CurPageOption
$936
404C1C: 2058 ‘ X’ MOVE.L (A0)+,A0
404C1E: 43F8 0910 ‘C...’ LEA CurApName,A1
$910
404C22: 7020 ‘p ‘ MOVEQ #32,D0
404C24: A02E ‘..’ _BlockMove
Example 5 - Sample Reference Map listing fragment of the “System
Globals” from ROM
114 HeapEnd proc203 MaxMem proc253
118 TheZone proc201 proc203 GetZone MaxMem proc212
proc232
InitResources proc852 MoreMasters InitZone
proc204
SetGrowZone
11C uTableBase proc36 proc89 proc96 RDrvrInstall
SystemTask proc942
SystemMenu OpenDeskacc BlockMove com_28
Example 6 - Sample Segment Reference Map listing fragment of Nosy.
Inter seg refs are prefixed with “n/”. This map may be used for procedure
balancing.
seg# procedure fba blen refs (seg#/proc) called by
1] HEAP_OVF 1D6 50 ADD_USED 4/NEW_TBL
1] SET_MAX 208 120 CLR_TBL 4/REL_TBLS 3/RTN_PTR
1] CLR_TBL 280 46 DI_PROC 3/SEARCH_C 4/DI_FILE
3/SEARCH_C
1] MOVEUP 2AE 80 ADD_USED
1] ADD_ENTR 2FE 42 DI_PROC ENTER_LA PUT_REF
NEW_CASE
ADD_ISPR 3/CHK_PROC 4/NI_FILE
4/DI_FILE
PROCESS_
1] SET_USED 328 44 4/NI_FILE
Disassemblling the ROM
I Would like to show a sample listing of a piece or two of ROM but I don’t want to
start any fights with Apple’s Lawyers. So like sex, I leave it for you to do it in the
privacy of your own home.
I found a few interesting things looking around the ROM. One is an interesting
piece of unreachable code at 40AD30 which blasts 32 long words into RAM and then
hangs. Another is the “come from” code in the rom patch area in the system heap. In
many cases bugs were patched by placing a CMPI.L $40xxxx,28(A7) followed by a
suitable jump in unrelated routines. A rather obnoxious example is BlockMove which
contains 3 such checks. I will be forming a MacNosy Users Group (Special Interest
Group) on the Delphi Information Service (800-544-4005) starting in April to
study the ROM and swap “jrnl” files. Admission will be limited to registered owners
of MacNosy.
Ordering Information
If ordered from the author before May 1, 1985 cost is $55, including sales tax
for CA. residents. After that it will be sold in selected stores or direct for $70. Orders
should be addressed to:
Steve Jasik
343 Trenton Way
Menlo Park, Ca. 94025
(415-322-1386)