ReSource can get its input from a file, disk track, or memory, and output all or in part to any of these. If the input is a load file, ReSource will make use of all the reloc32 and symbol information in the file.
ReSource creates symbols and labels for you, either manually or automatically, to take much of the drudgery out of disassembly.
becomesMOVEA.L (4),A6 LEA (START+$06B6,PC),A1 JSR (-$0198,A6) MOVE.L D0,(START+$2248) BNE.B START+$6AE MOVEA.L D0,A6 MOVE.L #$3EE,D2 LEA (START+$06C2,PC),A0 MOVE.L A0,D1 JSR (-$1E,A6) TST.L D0 BEQ.W START+$1044
Note that this and other examples of ReSource output are all shown using Motorola's new M68000 Family assembly language syntax. The new syntax was developed specifically for the addressing modes available on the 020/030 CPUs, and the output from ReSource in this mode is completely compatible with the Macro68 assembler.MOVEA.L (AbsExecBase),A6 LEA (DosName,PC),A1 JSR (_LVOOldOpenLibrary,A6) MOVE.L D0,(_DosBase) BNE.B NoDos MOVEA.L D0,A6 MOVE.L #MODE_NEWFILE,D2 LEA (ThisCON,PC),A0 MOVE.L A0,D1 JSR (_LVOOpen,A6) TST.L D0 BEQ.W NoFile
Virtually all Amiga© V1.3 and V2.0 symbol bases are included, over 7000 symbols in all. User-defined symbol bases may be used, allowing the disassembly of even non-standard structures to be automated. Your symbol bases may be edited too.
Full key rebinding is supported. You may load or save keytables of your choice to be used at any time.
You may load, define, and save macros. Macros support absolute looping, conditional looping, and variable executing speed.
A number of numeric and text processing functions allow you to automate many of the chores that used to make disassembly so slow! ReSource supports code, longword, word, byte and ASCII data types, as well as binary, decimal, hexadecimal, and ASCII numeric bases.
In Order to allow you to move freely around in code or data, ReSource includes forward and backward referencing, to allow you to quickly examine referenced code/data, and return to your original position (nested references are supported to 127 levels). Very sophisticated and flexible search functions are provided. You can search the buffer, or a disassembly of the buffer. Search strings may contain wildcards, and a binary search mode is supported. You can search forwards, backwards, or bi-directionally. You may restrict your search to just labels, or just symbols.
There is special support for base-relative data referencing. Any address register may be selected to hold the base, which makes ReSource particularly valuable for work with compilers that use unusual base-registers, such as Modula2.
ReSource can simplify your work in a variety of ways. You can patch files on disk or programs in memory, even while running. You can locate image data in memory, convert it to binary, then save to a file and include in your programs: instant gadget images! ReSource has even been used to reconstruct MFM data on corrupted disks. You may also inspect and perhaps alter boot blocks.
Before leaving this section, a brief look at how ReSource achieves its
fast screen output is in order. All text that is displayed on the
ReSource screen, with the exception of menus and requesters which
are rendered by Intuition, uses text rendering routines internal to
ReSource. This make text rendering extremely fast, but also means
that the font can't be easily changed. The text rendering routines
were originally inspired by Warptext II. Fast smooth scrolling is
made possible by direct hardware access of the blitter.
|Size on disk||12K|
|Size loaded as executable||79K|
|With labels created (min. necessary for reassembly)||82K|
|With many symbols created, some custom labels||140K|
In the design of any program, there must be compromises. ReSource was designed such that whenever there was a compromise between anything and memory usage, memory usage always lost. Therefore, ReSource is fast and powerful, but very memory hungry. For several reasons, this was considered not to be a great problem. Memory prices are still dropping, and it is expected that the users who need ReSource the most will have plenty of memory.
Here is what you will find in this section:
Version 1.3 or higher of the Amiga© OS is required.
One megabyte of RAM is required, and you will need 1 1/2 to 2 megabytes of RAM if you want to work with files larger than 30-40K.
Because ReSource uses functions in the "ARP" library, you must have the file "arp.library" in your "LIBS:" directory when you run ReSource. This file is supplied with ReSource, and is also available from most BBS's. The version of "arp.library" must be 34 or higher.
If you will be using ReSource under V1.3 of the Amiga© OS, we suggest that you run FastFonts© or Blitzfonts©. Otherwise, scanning though the menus will be very sluggish due to the large number of sub-items.
WARNING: You will need 2-3 megabytes of disk space on your hard drive for the ReSource program and related utilities and files. For full details on how to install ReSource on a hard disk, please refer to the "Install" doc file, located on the "ReSource1" disk.
Following is a quick guide to a minimum installation:
copy ReSource1:ReSource#? DH0:c copy ReSource1:ShowKeys DH0:c copy ReSource1:ShowMacros DH0:c copy ReSource1:libs DH0:libs ALL CLONE copy ReSource1:s/RS.#? DH0:s CLONE
|Point||To move the mouse so that the mouse pointer is either pointing at or pointing on top of some object.|
|Press||To hold the mouse button down.|
|Click||To press and quickly release either the left or right mouse button.|
|Double click||To click the left mouse button twice quickly.|
|Drag||To press the left mouse button and move the pointer in some direction while still holding the mouse button down.|
|Multiple select||In this manual, multiple selection will always be referring to menus. Access the menu with the right mouse button. Instead of releasing the right button over just one menu item, position the mouse pointer over each desired menu item and press the left mouse button to select that item.|
|Shift||Refers to a particular shift key, which will always be indicated i.e. left-Shift.|
|Ctrl||Refers to the control key. "Ctrl+s" means to hold down the control key, and while holding it down, press the "s" key. Then release the control key.|
|Alt||Refers to either the left or right Alt key. "Alt-z" means to hold down the Alt key, and while holding it down, press the "z" key. Then release the Alt key.|
|kp||Refers to keys on the numeric keypad, as in "kp1".|
If you will be starting ReSource from the Workbench™, you will see several icons, including the "ReSource" program icon. Double click on the "ReSource" program icon.1>run ReSource ;the word "run" is optional.
If you will be starting ReSource from the CLI, at the prompt type:
If you will be starting ReSource from the Workbench™, double click on the "C" drawer. Shortly you will see several icons, including the "ReSource" program icon. Double click on the "ReSource" program icon.1>run ReSource ;the word "run" is optional.
Throughout this manual, a heading ending with a ":" refers to the lowest hierarchical menu item for that function. In some cases, the heading will end with a "/:" to indicate that there are several sub-items with related functions begin discussed, e.g.:
|"DISPLAY/Set Counter:"||Refers to a single item.|
|"DISPLAY/Hiliting/:"||Refers to a group of sub-items.|
The menus in ReSource fully support drag-selecting, and multiple selection.
Before we leave the subject of menus, there is one function that ca save you a lot of time. "SPECIAL FUNCTIONS/Repeat last command" is normally bound to the spacebar. This function repeats the last command that was initiated from a menu. It does not repeat commands that came from keys. What this can do for you, is that if you will be using a particular function quite a bit around the piece of code on which you are currently working, you can call the function from the menu. Now that function may be repeated just by hitting the spacebar, while you can still use keys to call other functions in between. This will remain true until another menu item is selected.
|upArrow||means scroll up one line|
|downArrow||means scroll down one line|
|Shift-upArrow||means page backward|
|Shift-downArrow||means page forward|
|rightArrow||means forward reference|
|leftArrow||means previous location|
|rightAmiga-O||means open a file|
At the slowest rate, the display is shifted one pixel at a time followed by a short delay. The second slowest rate is the same number of pixels with no delays. The third moves 2 pixels at a time, fourth slowest is 4 pixels at a time, and the fastest rate is 8 pixels at a time. It is possible to select any of these rates by using menus or keys. Mouse scrolling also lets you scroll at rates faster than 8 pixels at a time. By moving the mouse vertically further away from the point where the left button was pressed, up to several hundred lines of text will be skipped between display refreshes.
Several functions can be used during mouse scrolling; on example of this automatic label creation. To do this, hold down the left-Amiga key while scrolling. Note that under V2.0 of the OS, the mouse button must be pressed before the left-Amiga key. This gives close control over the disassembly process; you examine the code as it scrolls up and ReSource creates the necessary labels.
If you are unsure which data type, code, ASCII, bytes, words, or longwords, should be used for any part of a file, you can have the display lock on one of these display types temporarily. While holding the left mouse button, even while scrolling, press and hold down the control key. Everything will be shown as code regardless of how it is normally shown. Press the left-Shift key, and everything will be shown as bytes. Similarly, the left-Alt key will give you ASCII, left-Shift and left-Alt together will give you words, and all three, left-Alt, left-Shift, and Ctrl, will display everything as longwords.
If you wish to change the data type permanently, you would normally use one of the "DISPLAY/Set data type/:" functions, but while using the mouse and the above qualifier keys, it is also possible to set the data type by pressing the right mouse button. Be sure that the location where you want the new data type to start is at the top of the screen.
When the left mouse button is held own, as well as the Ctrl key, symbols and comments are temporarily disabled, as well as optimization. This allows you to quickly see the value of any symbols present in code.
While using the mouse to scroll, if the left-Amiga key is held down, labels are created using forward references. If the left mouse button is pressed while the pointer is within 3 pixels of the right screen border, ReSource will assume that you are holding the left-Amiga key down, until you let the left mouse button go. This makes it easy to create labels single-handed. You don't have to keep the pointer on the right while scrolling, only its position when you actually pres the left mouse button is important. If you press the left-Amiga key while in this mode, and then release it, ReSource will again test for the mouse position.
If ReSource's window is selected (activated) when the mouse pointer is on the far left of the screen, a screen update will not be performed. This may be necessary after saving to a ".asm" file, when the source profile information is to be saved to a file.
Any of the above lines could be inserted into an assembly language source file, and yield exactly the same output - two bytes, the first one being 42, and the second one being 64. While it often make no difference to an assembler how the data is displayed, it does make a lot of difference if you wish to make any sense of what you are disassembling. If something was originally assembled as code, it will mean nothing if displayed as ASCII, or a series of bytes, words or longwords. And just as importantly, if something was originally assembled as ASCII:MOVEA.L D0,A5 DC.W $2A40 DC.W 10816 DC.W %0010101001000000 DC.W '*@' DC.B '*@' DC.B '*','@' DC.B $2A,$40 DC.B 42,64 DC.B %00101010,%01000000
...it will mean very little to you if displayed as bytes:doslibrary.MSG DC.B 'dos.library',0
When you tell ReSource that something should be displayed as code, or bytes, or perhaps ASCII, you are "setting the data type". Data types supported by ReSource include:lbB000232 DC.B $64,$6F,$73,$2E,$6C,$69 DC.B $62,$72,$61,$72,$79,$00
"Data type" is only one of many attributes of a position in ReSource's buffer that determine just what will be displayed.
The "current line" is the top line, as you see it on ReSource's screen.
If there is a section statement (e.g. SECTION BSS) to be displayed at the cursor address, this will be shown before any other text, and will force the other text to be shown on the next line down. If this is not the first section statement in the program, there will be an extra blank line, which will be shown before the section statement. After the section statement, and before the rest of the line, one or more "full-line comments" can be attached. Immediately after the cursor line, any "hidden labels" will be shown. A hidden label may also have a full-line comment attached, which will be shown immediately before it, but after the cursor line. Note that in this example:
all of the above text is defined as one line. Whenever you scroll up or down a line, all parts of the "current line" will scroll together. To put it simply, the first "real" line of code or data in the window is the current line.SECTION prog000000,CODE ;Section statement ; This is a full line comment! ; This is a another full line comment! MOVE.L D1-D4/A2-A6,-(SP) ;Line of code
All steps that you should perform, will be indicated by a small pointing arrow "»".
To open the load file:
ReSource 0% 000000 Examples/Tut1orial
It doesn't look too much like code yet, does it? Nothing has been scanned, so ReSource doesn't know what is code or data.SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (START+$30,PC),A1 JSR (-$228,A6) MOVE.L D0,(lbL000054) BNE.B START+$24 MOVE.L #$38007,D7 JSR (-$6C,A6) BRA.B START+$2A JSR (lbC00003C) ADDQ.W #8,SP MOVEQ #0,D0 RTS BCC.B ???? ???? BGE.B ???? BHI.B *+$74 BSR.B *+$74 ???? lbC00003C TST.L (lbL000054) BEQ.B START+$52 MOVEA.L (lbL000054),A1 MOVEA.L (4),A6 JSR (-$19E,A6) RTS lbL000054 DC.L 0 END
If a line of code makes a reference to somewhere within the program that doesn't have a label yet, it will be shown as some offset from the label "START", which is imagined to be attached to the first byte of the program. Also ReSource displays question marks when the data type is code and there is no legal instruction at that location.
One very useful function of ReSource is its ability to scan lines of code, looking for references to other parts of the program being disassembled. When a reference is made, it creates a label at that address, which will be used in all future references to that part of the program. What is more important, ReSource can determine what type of data is being referenced, and be correct (almost) every time. If you intend to reassemble the source, you should still verify it before saving, as mistakes will occasionally occur. Before ReSource makes a decision about what type of data is being referenced it examines many different pieces of information that are available, including the actual instruction that made the reference. There are a few ways of getting ReSource to scan lines of code, The simplest way is by using the built-in disassembly function.
» Select the "PROJECT/Disassemble:" function from the menu now. The screen will now look like this:
What has happened is that ReSource has "scanned" all the code in the program and determined which bytes were code and which were data, and the appropriate data types set. Labels have been assigned to locations that were referenced from within the program. Note that ReSource uses the offset into the file as the last 6 characters of "shop" labels, with the first 3 characters being "lbC" for code, "lbL" for longwords, "lbW" for words, "lbB" for bytes and "lbA" for ASCII. Additionally, if ReSource finds some ASCII data that will make a legal assembly language label, it will use as much of the text as it can, appending with ".MSG".SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (doslibrary.MSG,PC),A1 JSR (-$228,A6) MOVE.L D0,(lbL000054) BNE.B lbC000024 MOVE.L #$38007,D7 JSR (-$6C,A6) BRA.B lbC00002A lbC000024 JSR (lbC00003C) lbC00002A ADDQ.W #8,SP MOVEQ #0,D0 RTS doslibrary.MSG DC.B 'dos.library',0 lbC00003C TST.L (lbL000054) BEQ.B lbC000052 MOVEA.L (lbL000054),A1 MOVEA.L (4),A6 JSR (-$19E,A6) lbC000052 RTS lbL000054 DC.L 0 END
At this point, if you output to a ".asm" file, it will be good enough to reassemble. However, most people will want to examine the file, and make it more readable, especially if the program need to be modified. An excellent place to start is by finding where any libraries are being opened, finding where the library base is being stored, and giving meaningful names to these data storage locations.
» Scroll so that the line that reads "JSR (-$228,A6)" becomes the top line on the screen, and select "SYMBOLS 1/Libraries/Exec:" from the menu. Our block of code will now look like this:
You have just created a symbol, from one of ReSource's internal symbol bases.SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (doslibrary.MSG,PC),A1 JSR (_LVOOpenLibrary,A6) MOVE.L D0,(lbL000054) BNE.B lbC000024 MOVE.L #$38007,D7 JSR (-$6C,A6) BRA.B lbC00002A lbC000024 JSR (lbC00003C) lbC00002A ADDQ.W #8,SP MOVEQ #0,D0 RTS doslibrary.MSG DC.B 'dos.library',0 lbC00003C TST.L (lbL000054) BEQ.B lbC000052 MOVEA.L (lbL000054),A1 MOVEA.L (4),A6 JSR (-$19E,A6) lbC000052 RTS lbL000054 DC.L 0 END
» Scroll so that the line that reads "MOVE.L D0,(lbL000054)" becomes the top line on the screen, and select "CURSOR/Absolute/Forward reference:". This will normally be bound to the right cursor key. The line with the label "lbL000054" will now be at the top of the screen.
» Select "LABELS/Create single/Label" from the menu, and when the requester come up, type in, "_DOSBase". Select "CURSOR/Absolute/Previous location:" (this is normally bound to the left cursor key) and notice how ReSource remembered our previous location. Our block of code will now look like this:
Notice that every place in the program that formerly said "lbL000054" has been changed to "_DOSBase", not just the label you changed. This happens automatically, whenever you replace any label. The process helps itself; starting is hardest, then the rest come fairly easily.SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (doslibrary.MSG,PC),A1 JSR (_LVOOpenLibrary,A6) MOVE.L D0,(_DOSBase) BNE.B lbC000024 MOVE.L #$38007,D7 JSR (-$6C,A6) BRA.B lbC00002A lbC000024 JSR (lbC00003C) lbC00002A ADDQ.W #8,SP MOVEQ #0,D0 RTS doslibrary.MSG DC.B 'dos.library',0 lbC00003C TST.L (_DOSBase) BEQ.B lbC000052 MOVEA.L (_DOSBase),A1 MOVEA.L (4),A6 JSR (-$19E,A6) lbC000052 RTS _DOSBase DC.L 0 END
In general, where a label is used, if you have any idea of what is happening at all, you should replace it with a label that will remind you of what the code is doing. It doesn't matter what name you use, as long as it is a legal label for the assembler that you plan to use; if necessary you can replace it with something better later on. Anything nominally mnemonic will be superior to a "shop" label while you're trying to understand code.
Getting back to our program, we see that if the D0 register did contain a non-zero value, it means that "dos.library" did open successfully and the following conditional branch will be taken. The destination of this branch is labeled "lbC000024". A better name for this might be "OpenedOK".
» Scroll so that the label "lbC000024" is on the top line of the display, and select "LABELS/Create single/Label". When asked, type in "OpenedOK". Now we see that, as before, the change we made has been echoed to other parts of the program:
If the call to "OpenLibrary" was unsuccessful, the branch on the sixth line would NOT be taken. In this case, the D7 register is loaded with the value "$38007", and a call is made ti the subroutine at offset -$6C from where the A6 register is currently pointing. We do know that the A6 register was pointing to the Exec library base before, and we also know that none of the code executed so far has destroyed the value in A6, so we can safely assume that A6 still points to Exec library base.SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (doslibrary.MSG,PC),A1 JSR (_LVOOpenLibrary,A6) MOVE.L D0,(_DOSBase) BNE.B OpenedOK MOVE.L #$38007,D7 JSR (-$6C,A6) BRA.B lbC00002A OpenedOK JSR (lbC00003C) lbC00002A ADDQ.W #8,SP MOVEQ #0,D0 RTS doslibrary.MSG DC.B 'dos.library',0 lbC00003C TST.L (_DOSBase) BEQ.B lbC000052 MOVEA.L (_DOSBase),A1 MOVEA.L (4),A6 JSR (-$19E,A6) lbC000052 RTS _DOSBase DC.L 0 END
» Scroll so that the line "JSR (-$6C,A6)"" is on the top line of the display, and select "SYMBOLS 1/Libraries/Exec" again. Our block will look like this:
After reading the documentation for the Exec call "Alert", we find out that on entry, the D7 register should contain a number representing an alert code.SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (doslibrary.MSG,PC),A1 JSR (_LVOOpenLibrary,A6) MOVE.L D0,(_DOSBase) BNE.B OpenedOK MOVE.L #$38007,D7 JSR (_LVOAlert,A6) BRA.B lbC00002A OpenedOK JSR (lbC00003C) lbC00002A ADDQ.W #8,SP MOVEQ #0,D0 RTS doslibrary.MSG DC.B 'dos.library',0 lbC00003C TST.L (_DOSBase) BEQ.B lbC000052 MOVEA.L (_DOSBase),A1 MOVEA.L (4),A6 JSR (-$19E,A6) lbC000052 RTS _DOSBase DC.L 0 END
» Scroll so the line "MOVE.L #$38007,D7" is on the top line of the display, and select "SYMBOLS 2/A-B/Alert codes". Our block will now look like this:
SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (doslibrary.MSG,PC),A1 JSR (_LVOOpenLibrary,A6) MOVE.L D0,(_DOSBase) BNE.B OpenedOK MOVE.L #(AG_OpenLib!AO_DOSLib),D7 JSR (_LVOAlert,A6) BRA.B lbC00002A OpenedOK JSR (lbC00003C) lbC00002A ADDQ.W #8,SP MOVEQ #0,D0 RTS doslibrary.MSG DC.B 'dos.library',0 lbC00003C TST.L (_DOSBase) BEQ.B lbC000052 MOVEA.L (_DOSBase),A1 MOVEA.L (4),A6 JSR (-$19E,A6) lbC000052 RTS _DOSBase DC.L 0 END
» Place the line that says, "LEA (doslibrary.MSG,PC),A1" on the cursor line, and then select "CURSOR/Absolute/Forward reference:". The line labeled "doslibrary.MSG" will move up to the cursor line. You can now use "LABELS/Create single/Label" to change the name "doslibrary.MSG" into something more meaningful, like "DosName".
» Now use "CURSOR/Absolute/Previous location:", and you will find yourself back where you were, with a new name for the first operand. Normally you will just use the right-Arrow and left-Arrow keys for these two functions rather than using the menus.
Our block will now look like this:
SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (4),A6 LEA (DosName,PC),A1 JSR (_LVOOpenLibrary,A6) MOVE.L D0,(_DOSBase) BNE.B OpenedOK MOVE.L #(AG_OpenLib!AO_DOSLib),D7 JSR (_LVOAlert,A6) BRA.B lbC00002A OpenedOK JSR (lbC00003C) lbC00002A ADDQ.W #8,SP MOVEQ #0,D0 RTS DosName DC.B 'dos.library',0 lbC00003C TST.L (_DOSBase) BEQ.B lbC000052 MOVEA.L (_DOSBase),A1 MOVEA.L (4),A6 JSR (-$19E,A6) lbC000052 RTS _DOSBase DC.L 0 END
This completes the disassembly of "Tutorial1".SECTION Tutorial1000000,CODE ProgStart MOVEM.L D0/A0,-(SP) MOVEA.L (AbsExecBase),A6 LEA (DosName,PC),A1 JSR (_LVOOpenLibrary,A6) MOVE.L D0,(_DOSBase) BNE.B OpenedOK MOVE.L #(AG_OpenLib!AO_DOSLib),D7 JSR (_LVOAlert,A6) BRA.B NoDos OpenedOK JSR (Main) NoDos ADDQ.W #8,SP MOVEQ #0,D0 RTS DosName DC.B 'dos.library',0 Main TST.L (_DOSBase) BEQ.B Done MOVEA.L (_DOSBase),A1 MOVEA.L (AbsExecBase),A6 JSR (_LVOCloseLibrary,A6) Done RTS _DOSBase DC.L 0 END
The online help facility contains documentation on each and every function that can be selected from the menus. There is also a glossary of terms and phrases.
You can get nested help within nested help. There is a limit to just how many positions within the help files ReSource will remember (256 levels), but it is highly unlikely that anyone will ever approach this limit. In fact, it is unlikely that you will nest to a depth of more than three in normal operation.
|Help||Display this table|
|Escape||Exit from the online help facility|
|downArrow/upArrows||Move forward/backward through text|
|leftArrow/rightArrow||Use to hilite a word/phrase|
|Return||If word/phrase hilited, get help on it|
|Alt-downArrow||Move forward to end of text|
|Alt-upArrow||Move to start of text|
|Backspace||Return to previous level|
Using "?" as the first parameter on the command line will display the parameter syntax requirements, then exit immediately.1>ReSource ?
The executable program <ProgName> will be loaded as a load file if it is a load file. Otherwise, it will be loaded as a ".RS" data file if it is a data file. Otherwise, it will be loaded as a binary file. Corrupted load files may have to be loaded as a binary image.1>ReSource <ProgName>
The file <FileName> will be loaded as a binary image.1>ReSource *b <FileName>
Load memory, from location <Sloc> to location <Eloc>.1>ReSource *m <Sloc> <Eloc>
Load from drive DFn: starting at cylinder <Scyl> and continuing to <Ecyl+1>. The default is to read complete track(s). This may be modified by the next two optional parameters: The fourth parameter specifies that ReSource should read [#sec] extra sectors, and the fifth parameter specifies that rather than begin reading from the start of <Scyl>, offset the start sector by [Offsec] sectors.1>ReSource *DFn: <Scyl> <Ecyl+1> [#sec] [Offsec]
As of publication of this manual, the following flags were implemented:
ReSource will accept "-I" or "-i" as the first parameter on the command line. This will force ReSource to use an interlaced screen. Note that if your Workbench™ screen is in interlaced mode, this flag has no effect.
Conversely, to force ReSource to use a non-interlaced screen,
use "-N" or "-n" as the first parameter on the command line.
This will force ReSource to use a non-interlaced screen. Note
that if your Workbench™ screen is not in interlace mode, this
flag has no effect.
The following examples are provided for clarification:
The program "popcli" will be loaded as a load file, from the C: device.1>ReSource c:popcli
Load the file "arp.library", from the LIBS: device, as a load file.1>ReSource libs:arp.library
The file "popcli" will be loaded as a binary image, from the C: device.1>ReSource *b c:popcli
The first 64K of Kickstart™, V1.3 or earlier, will be loaded.1>ReSource *m $FC0000 $FD0000
The boot sectors from DF0: will be loaded, a total of 1024 bytes. Use this to check for or disassemble viruses.1>ReSource *DF0: 0 0 2
The cylinder containing the root directory will be loaded from DF1:, 11K in all.1>ReSource *DF1: 40 41
Load the area of memory between location $400 and location $800. For some Amigas, this will load the Exec library base. Some shells will eat the "$" character on their command line. If this is a problem, ReSource will treat the "C" standard, "0x", as en equivalent prefix.1>ReSource *m $400 $800
Load one byte of memory, at location zero.1>ReSource *m 0 1
ReSource may be "Run" without problem, and multitask beautifully. It will even allow you to change the task priority from inside ReSource.
LACEFLAG - If true, this flag will force ReSource to use an interlaced screen. To set this select the ReSource icon, and then select the "Info" menu item. When the Information window opens, Select "Add tooltypes", and enter:
|LACEFLAG=ON||;If you want to force interlace|
|LACEFLAG=OFF||;If you do not want to force interlace|
NOLACEFLAG - If set true, this flag will force ReSource to use an non-interlaced screen. To set this select the ReSource icon, and then select the "Info" menu item. When the Information window opens, Select "Add tooltypes", and enter:
|NOLACEFLAG=ON||;If you want to force non-interlace|
|NOLACEFLAG=OFF||;If you do not want to force non-interlace|
These two flags are defined as being mutually exclusive. If you set
both flags to ON, ReSource will not be able to figure out what you
really want to do, and will exit immediately with a complaint.
Data from symbol hunks will be shown as labels in their proper places within the program, and even the relocation information is available. For example, if you select "DISPLAY/Hiliting/Reloc32:", any relocated pointers a hilited. When disassembling, this information is quite valuable, as it helps you to tell where code is, where tables of pointers are, etc. ReSource also makes heavy use of this information in many functions, and this is one of the main reasons that it is so accurate in determining data types, especially when distinguishing code from ASCII. The hunk information also tells you whether something was meant to load into chip memory, which immediately lets you know that it is probably graphics or sound data.
When a file with overlays is loaded, only then root node is loaded. When this happens, the user is notified of this, and must select "OKAY" on the requester before ReSource will continue.
The "LABELS/Create multiple/Reloc32:" function is called automatically after every "Open load file", unless there was no reloc32 table in the file, and providing that this is not overridden by "OPTIONS/Allow/Auto labels/OFF:" option. It may be stopped by pressing rightAmiga-A, in any case.
If a program has symbol hunks left in it, it makes the disassembling process much easier. When the file is loaded, for each label found in the symbol hunk, if it is nine characters long, starts with "lb", and is followed by an upper case "A", "B", "C", "L", or "W", at the point that the label is attached, the data type will immediately be set to ASCII bytes, code, longwords or words, respectively. Additionally, local labels, of the "1$" variety, and labels ending in "SUB" are recognized as code, and labels ending in ".MSG" are recognized as ASCII.
Thus if you are disassembling a program that you previously disassembled, then reassembled, many of the data types will be set for you, as the file is loaded. Even if the program did not previously come form ReSource, symbol hunks will give you clues to what's going on in the code by names given to the routines.
There is one other type of file that can be loaded in using "PROJECT/Open load file:", the ReSource data file, or ".RS" file. It is discussed in detail in the section entitled, About Data Files.
If ReSource cannot load the file as an ".RS", or an Amiga© load file it will automatically attempt to load it as a binary file, without looking for hunk, relocation, or symbol hunk information. If it is an Amiga© load file, but has been corrupted, ReSource will refuse to load it. You can still load it, however using the "PROJECT/Load binary file:" function. With this function, you can load any file that will fit into available memory. Keep in mind that ReSource will require memory 6 times the file size, of which memory 4 times the file size must be contiguous. In the case of normal Amiga© load files you may wish to load them as binary files in order to examine the hunk information in them.
The "PROJECT/Restore:" function will attempt to load the same file that you loaded last. This is useful when you make a mess of things, and just want to start again. The restore function is only usable when you load from a file, not when you disassemble memory directly, or read tracks from a floppy disk.
When you are asked to select a file using the file requester, you may click on "CANCEL" and retain the current file. If you click on the "OKAY" gadget, and the file is not successfully loaded, (perhaps because it is too large for available memory), you will have lost the current file. If, at this time, you select "CANCEL", ReSource will give you the chance to quit, in case you cannot or are unwilling to load any file. If you don't quit, ReSource will again offer the file requester, where you may select a file to disassemble.
There are two separate functions for loading binary files into ReSource. Using "PROJECT/Load binary file:" is very similar to loading a normal Amiga© load file except that none of the hunk, relocation, and symbol information is stripped from the file; what you see is an exact image of the file as it exists on disk. Another similarity to loading Amiga© load files is that the current file, if any is replaced.
On the other hand, "PROJECT/O'lay binary image:" does not displace the current file. ReSource will attempt to open the file you request, and read the contents, overlaying the current file starting from the current cursor position. This is not the same as opening a file normally, as all labels, symbols, comments, datatypes, etc., stay as they are. Only the actual contents of the executable itself, as it appears in ReSource's buffer, is overwritten. For example, you may wish to replace the beginning of one file with another, possibly to make a patch. This function will do that easily. Another reason to use this is that you may wish to pass on a ".RS" file to someone, but because the program you have disassembled is copyrighted, you cannot legally distribute the normal ".RS" file, as it contains the executable. By using this function, and inputting a filename of "*" (asterisk), ReSource will completely clear the executable within the current file. You may then save to a ".RS" file, which may then be distributed, devoid of the executable. If another person has previously purchased the program, that you have disassembled, they may load it it into ReSource, and use "SAVE/Save binary image/All:", to save the executable to a file. They then load the special ".RS" file which you created. Next, they use "PROJECT/O'lay binary image:" supplying as a filename the name of the file previously saved with the "SAVE/Save binary image/All:" function. This effectively puts the executable back into the ".RS" file. The other save functions may then be used, to save to a .asm file, for example.
Please make sure the executable section is cleared before you share ".RS" files that are disassemblies of copyrighted material. Failure to do this is illegal, and may also result in litigation from the copyright holders.
It is the content of the file that allows ReSource to recognize a ".RS" file, not the name of the file. However, the file should have an extension of ".RS", so it is immediately recognizable by humans as a ReSource data file.
To save your work, no matter how you loaded it, select "PROJECT/Save .RS/Save:", and select a filename under which it will be saved.
You can share a ".RS" file with a friend, if they have also purchased ReSource. When doing so, always remember that the executable must be cleared before you distribute ".RS" files of any program that is not Public Domain. This may be done by using the "PROJECT/O'lay binary image:" function. Also, you must not use ReSource to remove copy protection, or to aid other people in doing the same thing.
Input may also come directly from disk, although as stated previously, ReSource can read only normal disk blocks, and is not able to read MFM or CGR data directly. After selecting "PROJECT/Read tracks:", you will be asked to supply the parameters for the track read. The first parameter must be either "DF0:", "DF1;", "DF2:", or "DF3:" (lower case is okay). This represents the drive that holds the disk to be read from. The second parameter is the number of the cylinder to start reading from. The third parameter is the number of the last cylinder to be read, plus one. For example, if you wished to read only the very first sector from DF1:, the parameters would be "DF1: 0 0 1". If you wished to read the first sector from the directory track of DF2:, the parameter would be "DF2: 40 40 1". The fifth parameter is also optional, and it represents the sector offset, to start the read. For example, if you wished to read sectors nine and ten on cylinder 79 of the disk in DF3:, the parameters would be "DF3: 79 79 2 9".
Another output function is "SAVE/Save binary image:". This function gives you a way of performing modifications on an existing binary file, which may also be a load file. For example, if you have a program that has some annoying feature, you could load the file using "PROJECT/Open binary file:". Then you could quickly find the offending code with ReSource, and imply overwrite it with "NOP" instructions. You may use "SPECIAL FUNCTIONS/Zap:" to enter "NOP" opcodes as "Nq" or "$4E71". Look up hex values of any other opcodes that you may need. Once this has been done, select "SAVE/Save binary image/All:", and you can use the file immediately, without going through the complete disassemble/reassemble/link process.
To find out how large the output .asm file will be, you can select "SAVE/Calculate asm size/All:". This will tell you the output size, in bytes, K's and as a percentage of a floppy disk, which may be greater than 100%. If you change any of the options, it will most probably have some effect on the size of the output file. To make the output .asm file smaller, most things in the "OPTIONS" menu should be switched OFF, except for "DCB instructions", which if used, can shrink the size of a .asm file considerably, especially if there are large data areas. Selecting "OPTIONS/Show/Multiple constants:" will also help to shrink the output size. Either real tabs, ASCII value 9, or spaces may be used in the output file. Selecting "SAVE/Tabs/Real tabs:" will also make the output file size smaller, as will turning off all of the "DISPLAY/Blank lines/" selections. If the size of the output file is not a problem, then set these options to suit your tastes. Another way to deal with limited space for .asm files, is to save them as two or more partial files using "SAVE/Save .asm/Partial:" repeatedly.
Furthermore, these preferences may be set automatically on startup be selecting the "PROJECT/Save config" function. This will create a new configuration macro for you, and offer to save all macros. The macro created will then be executed each time ReSource is loaded. Not only are settings of checked menus restored, but User-defined symbol bases are loaded as they were when the configuration was saved. Plus, the string contents of various user-definable buffers are saved. These include accumulator, buffers A-M, search strings, etc.
The next that you see on the display will be the text that is searched. For the purpose of searches, tabs are set to real tabs, not spaces. Thus if you wish to search for:
you would type: "\tMOVE.L\t#100,D0". Tabs are entered where you see white space in the above line. Because string requesters under V2.0 of the Amiga© OS will not accept control characters, ReSource accepts the following "C" escape sequence as substitutes:MOVE.L #100,D0
|\t = TAB ($09)|
|\n = LF ($0A)|
|\r = CR ($0D)|
|\e = ESC ($1B)|
When using the pattern search, ReSource uses the extensive set of wildcards provided by the ARP library. This set includes all the AmigaDOS™ set of wildcards, as well as the more standard UNIX style of wildcards. ARP supports the following wildcard characters. Note that these are valid inside or outside quotes:
|(a|b|c)||Will match one of a, b or c. These can be patterns.|
|?||Matches any single character.|
|#<pat>||Pattern repeated 0 or more times, in particular, #? matches anything.|
|[char]||A set of characters, for example, [abc] or [a..c] specify the same set.|
|[^char]||Match everything but this set of characters.|
|*||1 or more occurrences of any character.|
For example, if you want to search for "JSR" or "BSR", you could specify "?SR" as the search pattern, and you would use the pattern search, not the normal search. Here are some more examples:
lb[ABCWL] would find any occurrence of "lbA", "lbB", "lbC", "lbW", or "lbL". "lbM" would not constitute a valid match.
J(MP|SR)\t'(-$????,A6') would get a match on the following lines:
but not on the following lines:JMP (-$00C6,A6) JSR (-$00C6,A6) JSR (-$01FE,A6) JMP (-$FFFF,A6)
Note the ticks (single quote or "'") in front of the opening and closing parentheses in the latter part of the search pattern. The tick tells the search routine that the parentheses are literal characters, and not to consider them part of a search pattern, but are in fact literal characters.JMP ($00C6,A6) JSR (-$00C6,A5) JSR ($01FE,A6) JMP (A6)
Also note that a tab sequence was used above, between "J(MP|SR)" and "'(-$????,A6')". Once entered, if you were to edit this pattern, the "\t" would appear as a small box in the string requester. It need not be entered again. During a search, it is unimportant weather tabs are set to real or spaces.
In this example, the option to show leading zeros is turned on so all the library offsets are 4 characters, and we can search for them with "????". If the leading zero options is turned off, we could also substitute "*" for the "????", but with a decrease in precision.
The size of a macro is limited only by how much memory you have. Macros may be nested within macros, provided that the nesting depth does not exceed approximately 30. You have control over the speed at which macros execute. There is even a "Wait on mouse" speed available. With this selected, you must press and release the left mouse button for each function within the macro to be executed. Combined with the "ShowMacros" utility this is an excellent way of finding bugs in a macro that you have created.
Notice that the directive "Start conditional" was not required in the above example, as conditional sections are not nested.MACROS/Set macro label/#1: CURSOR/Relative/Next line: MACROS/Previous macro label/#1: MACROS/Directives/End conditional: MACROS/Set macro label/#2: CURSOR/Relative/Previous line: MACROS/Previous macro label/#2: MACROS/Directives/End conditional: MACROS/Previous macro label/#1:
On the other hand, if you want to force the user to input a string during the execution of the macro, you should select the "Cancel" gadget in the string requester. Any string that you typed into the requester will still be used while creating the macro, however when the macro is executed, the user is forced to input a new string each time, even though "Interactive" may be set to "OFF".
Buffers A-M are simply 13 separate 240-byte string buffers, in which you can store any strings that you like. A more appropriate name might be "text registers". Buffers L and M are special, in that if you select "STRING/Define string/M:", and buffer L is not empty, the string contained in buffer L will be used as the prompt in the requester. This is handy during macro functions where you want to get a string from a user. The user can then see what the string is required for.
If you set the commentary level to "None" and execute this macro, the cursor will move down one line. If you set the commentary level to "Light", and execute this macro, the cursor will move down two lines. If you set the commentary level to "Full" and execute this macro, the cursor will move down five lines. Using the "SPECIAL FUNCTIONS/Dos command" function you can use the "SAY" command to add speech to macros and give excellent running commentary to tutorial macros.MACROS/Commentary level/Full: CURSOR/Relative/Next line: MACROS/Commentary level/Heavy: CURSOR/Relative/Next line: MACROS/Commentary level/Normal: CURSOR/Relative/Next line: MACROS/Commentary level/Light: CURSOR/Relative/Next line: MACROS/Commentary level/None: CURSOR/Relative/Next line:
ReSource macro files may be disassembled, examined, edited, reassembled, and reused. Guidelines may be found in the Utilities section and also in the separate file, "ShowMacros.doc".
To run any of the demonstration macros, select the "MACROS 1/Load macros" function, supplying the pathname of the "RS.Macros" file as supplied in the S: directory on ReSource distribution disk #1. This done, you may then select one of the functions in the "MACROS 2/Execute/:" menu, which will start the execution of the macro that you have selected. You may wish to select the "MACROS 1/Execution speed/Wait on mouse:" and "DISPLAY/Titlebar info/Function names:" function before starting one of the demo macros in order to see each step as its being performed.
There are 2 basic types of user-defined symbol bases. The most common type will be one in which any particular value can only equate to one symbol. An example of this would be, "wd_SIZE equ $84". In the other type the target number is considered to be one or more groups of bit fields, and each field may or may not equate to a symbol. The resulting symbols are OR'd together, to create the final string. For example, "MEMF_CLEAR|MEMF_CHIP" is composed of two symbols, the first equates to $10000; the second equates to 2. Therefore, the number that created this string must have been $10002.
Several functions are included in ReSource to facilitate loading and using user-defined symbol bases. "SYMBOLS 1/Load user symbols/:" will load a previously defined symbol base into ReSource. Select an empty slot from this menu for your symbol base. When the file requester pops up, type in the pathname of your symbol base.
Note that User-defined symbol bases can be loaded as part of the configuration macro. To take advantage of this, simply load any user-defined symbol bases that you will always want loaded, and select the "PROJECT/Save config:" function.
Once your symbol base files have been loaded, select a symbol base from the "SYMBOLS 1/User-defined symbols/:" menu to create a symbol using this particular base. You can use these in the same manner as ReSource's built-in symbols.
To unload a symbol base, select the symbol base to unload, and then select "CANCEL" on the requester.
For more details about user-defined symbol bases, as well as instructions on how to construct your own symbol bases, see the file, "UserSymbols.doc".
In this section we will explain how ReSource uses the information contained in an Amiga© load file to create symbolic source code that may be reassembled and executed.
These initial labels are either found in a symbol hunk in the load file, or created by the "LABELS/Create multiple/Reloc32" function, which is executed after loading any executable file if "OPTIONS/Allow/Auto labels" is selected.
Then, when the code is scanned, either manually or automatically, ReSource looks for internal references to other parts of the program. When a reference is made, it creates a label at that address, which will be used in all future references to that part of the program. ReSource can usually determine what type of data is being referenced, and will create a label name to reflect this. The offset into the file is used as the last 6 characters of "shop" labels, with the first 3 characters being "lbC" for code, "lbL" for longwords, "lbW" for words, "lbB" for bytes and "lbA" for ASCII. Additionally, if ReSource, finds some ASCII data that will make a legal assembly language label, it will use as much of the text as it can, with ".MSG" appended.
A special case exists where there is a code reference (JMP, BRA etc), to a user-defined label. In this case, ReSource uses the label being referenced, adds an underscore ("_") to the start of that label, makes it unique, and uses the result as the name of the label to create at this position. For example, if asked to create a label for the line:
ReSource would create "_" + "_OpenLibrary", giving:JMP (_OpenLibrary)
Labels may be, and should be, edited by you to reflect their function. In general, if you have any idea of what is happening in a routine, you should replace it with a label that will remind you of what the code is doing. It doesn't matter what name you use, as long as it is a legal label for the assembler that you plan to use; if necessary you can replace it with something better later on. Anything nominally mnemonic will be superior to a "shop" label while you're trying to understand the code. The process helps itself; starting is hardest, the rest come fairly easily.__OpenLibrary JMP (_OpenLibrary)
When a label is either created, or edited, all locations that use that label will reflect the change immediately. This happens automatically, whenever you replace any label.
The benefit derived from local labels is that not all the labels in a program need be unique. As you are disassembling a program, it is possible to treat each routine like a "black box" where only the global labels is accessible to the rest of the program. This technique works fairly well with "C" programs, which tend to treat routines as objects anyway, but be careful with programs originally written in assembly language where routines may have entry points almost anywhere.
To make ReSource do this, you would scroll so that this line became the current line, and then select "Exec library" from the SYMBOLS menu. There are hundreds of other symbol bases that are available, including libraries, devices, structures, parameters, and error code names.JSR (_LVOOpenLibrary,A6)
If you need to define a symbol that ReSource doesn't know about, there are two other options. You can define that symbol immediately by using the "Create symbol" function. If you have an entire symbol base that's undefined say, the base for a custom library, you may define your own symbol base and use it in exactly the same manner as the built-in symbol bases. See the section User-defined symbol bases for more information on this subject.
Please note that both "Create full-line comment" and "Edit full-line comment" will place the newly created or edited comment after any previous full-line comments on the current line. When deleting full-line comments, the first comment on the current line will be the one deleted. A related function lets you rotate a group of full-line comments to get specific comment to the top, where it can be either edited or removed.
One of the most useful hiliting functions is "Reloc32". This is most useful when disassembling executable programs. A "Reloc32" refers to a group of four bytes that contains a pointer to a memory location. The actual memory location being pointed to is calculated by adding an offset to the base address of one of the hunks in the file. Certain assumptions can generally be made about how reloc32s can be displayed. Any line containing a reloc32 pointer must either be code, or longwords, as there is no other sensible alternative.
To allow several differing types of hiliting simultaneously, ReSource uses several different types of hiliting:
For each byte if the file, some of the things that are marked are:
Be aware that by setting the data type at a particular offset in a file, you are not only telling ReSource how that line and lines below it should be displayed, you are also telling it where it should start showing that data type, also.
For example, if something is shown as ASCII, and you change the data type permanently at that place in the file to some other data type, i.e. code, permanently changing the data type back to ASCII does not necessarily make it exactly what it was before. This particularly important when you set the data type to ASCII. Often, many bytes if ASCII are displayed together on one line. By setting the data type, you are forcing ReSource to start a new line at that point, regardless of what data type is displayed above. If you do set a data type somewhere, and decide that it wasn't a good idea, use the "LABELS/Remove single/All:" or "DISPLAY/Set data type/Unknown:" function.
Unlike the first tutorial, we will not show the entire file at every example, but only a small piece, representative of what we are currently working on. Also unlike the previous lesson, we will refer to functions by their keys as well as their menu names. All such usage will be based on the default keytable provided with ReSource. So if you have modified it already, load the original as soon as you start the program. We will also refer to lines by both labels and offsets, so keep your eye on the titlebar.
Note that when asked to create or edit symbols, you can undo mistakes by using the "LABELS/Remove single/Symbol:" function.
» To begin, start the ReSource program. Then open the load file provided with ReSource for this tutorial, "Tutorial2". You should see something like this:
Notice that the first lines of code loads something into register A5. Also notice that whatever A5 is pointing to is immediately being cleared. If you use the right cursor key, you will notice that A5 is pointing at a line that look like:SECTION Tutorial2000000,CODE ProgStart LEA (lbL000320,PC),A5 MOVEA.L A5,A0 MOVEQ #5,D1 MOVEQ #0,D0 MOVE.L D0,(A0)+ DBRA D1,START+$0A
The "DX" stands for "Define eXtra storage". It is s special type of "DS" that takes no disk space, but may have to be cleared by the program, as it is not cleared by the system as BSS sections are.lbL000320 DX.L 8
Using the left cursor key to return to or previous location, you might also notice that several lines of code are referencing things off A5. Taken together, all these clues gives us a very good idea that A5 is being used as a base register. Base registers are used both to make program smaller, and to make the code run faster. Because it is not possible to write to PC relative locations with 680x0 CPUs, we must either use absolute addressing, or use base relative addressing, effectively reducing the size of the program by 6 bytes each time we do. Since A5 is our base register, we need to tell ReSource about it.
» Pull down the "*" (SPECIAL FUNCTIONS) menu and look at the line where it says "SPECIAL FUNCTIONS/Convert (xx,A4) EAs/:". Now select the function "SPECIAL FUNCTIONS/Specify base register/A5:" and notice that the line you looked at before has changed to A5. Now we will inform ReSource of the base location by selecting "SPECIAL FUNCTIONS/Convert (xx,A5) EA's/This operand".
Notice that what was previously:
has been changed toMOVE.L D0,(0,A5)
and ReSource has created a label named "DT" for us. Note that because A5 is pointing at "lbL000320", that (0,A5) and (lbL000320-DT,A5) are equivalent. The principal reason for expressing the relationship in this way is that if you decide to modify this program, and either removed or added lines to the DX area, the simple offset would no longer be valid.MOVE.L D0,(lbL000320-DT,A5)
Now that our relative base is firmly established, we can proceed to disassemble the program.
» Select "PROJECT/Disassemble:".
That was quick, but a whole lot of things were going on. ReSource scanned the code and assigned data types. Notice that we now have labels, and there is even some readable text in the program.
» Scroll down to the line at offset $10. We know that location 4 is AbsExecBase, so let's name it that. Use the "V" key to select "Create Symbol" and type "AbsExecBase" into the requester.
The line at offset $14 is an offset of A6, which is pointing to Exec library, so this offset must be in the Exec library base.
» Use the "E" key to select "SYMBOLS 1/Exec library".
Note that A2 is now pointing to our process base.
» Make the line at offset $18 current. then use the "T" key to select "SYMBOLS 2/Task control struct".
Here the program is testing the pointer to the CLI structure. If it is zero, this task was launched from the Workbench™. Therefore, if we take the branch, we were launched from the CLI.
» Make the line at offset $1C current, Use the right cursor key to take the branch. Then use the "kp9" key and enter "FromCLI" into the requester. Finally, return with the left cursor key.
The next 5 lines are executed if we were launched from Workbench™. They get the Workbench message and save it until we exit the program.
» Use the "T" and "E" keys to create symbols for the 4 lines beginning at offset $1E. If you make a mistake, just hit the proper key. When you get down to offset $2E, use right cursor to go to the destination, and use "kp9" to name this ":WBenchMsg". Use the left cursor to return.
We are now down to the label "FromCLI" at offset $32. you can probably surmise that we are about to open some libraries.
» Make the line at offset $38 current, and use "E" to name this call. Because we just opened Graphics library, go to label "lbL000324", where the pointer will be stored, and rename this to "_GfxBase". Then scroll down to offset $60 and do the same things, except rename the label at "lbL000328" to "_IntuitionBase". Then scroll back to offset $44.
The program is moving _GfxBase into A6, and then making A0 point to something, at which time a call is made to the graphics library. this is the sort of situation that makes disassembling interesting.
» Move to offset $4A, and by using the "g" key to select "SYMBOLS 2/Graphics library", the symbol "_LVOOpenFont" will appear.
What is A0 pointing to? The AutoDocs™ tells us that when calling "OpenFont", A0 should point to a TextAttr structure. They also tell us that if the call is successful, a pointer to a font will be returned in D0. So let's go to lbL000186 and make it look like a TextAttr structure.
» The way to do this is to make the line where the label "lbL000186" is the current line, and then tell ReSource this is a longword with left-Amiga L. Scroll to the next line and make it into a word with left-Amiga W. Finally, make the last 2 lines bytes by using left-Amiga B. We can name it "MyTextAttr". It should look like this when we are done:
» At offset $4E, press the right cursor key to go to offset $32C, and create the label "_FontPtr" (use keypad "9" key again).MyTextAttr DL topazfont.MSG DW 8 DB 0 DB 1
Go back to offset $68, and notice that if the intuition library doesn't open, we take a branch. If you look back over the code we have done so far, you will see that if anything doesn't open, we go to the same location.
» Go to label lbC0000E2 and rename it "Cleanup".
Notice that at offset $6A the program moves _IntuitionBase into A6 and, after pointing A0 to something, makes a call to intuition library. This is the same situation we had before where we needed to find out what A0 was pointing to. The best way to resolve these cases is to gather all the evidence you can, and then make an informed choice.
» Go to offset $70 and use the "I" key to name this call to intuition library.
If the call is to OpenWindow, A0 must be pointing to a NewWindow structure. Let's go to lbL00018E and check it out.
» Go to lbL00018E and rename it "MyNewWindow". Get out the include.i files and look in "intuition/intuition.i" for the NewWindow structure. We are going to clean up MyNewWindow so that it's more readable.
» Make the label MyNewWindow the current line, and use the left-Amiga W key to tell ReSource that these lines are words. Scroll down 4 lines to offset $196 and use left-Amiga B to set the data type to bytes. Scroll down 2 lines to offset $198 and set the data type to longwords. Scroll down 7 lines to offset $1B4 and set the data type to words. Scroll down 4 lines to offset $1BC and again set the data type to words. Why we are setting this line to words again will be clear in a moment.
» While still at offset $1BC, select "SYMBOLS 2/S/Screen flags:". This should create the symbol "WBENCHSCREEN". Scroll up to offset $198 and select "SYMBOLS 2/H-I/IDCMP classes:". Scroll down 1 line to offset $19C and select "SYMBOLS 2/U-Z/Window flags:".
» Type a ShiftCtrl-upArrow (shift + ctrl + cursor up) to select "CURSOR/Relative/Previous label:", which will take us to the label MyNewWindow. Once we're there, we can do some magic. Select "DISPLAY 2/Mult constatns override/Set:" from the menu. Notice that we have all four words on the same line now. Use the Shift-~ (shift + ~) key to set these values to decimal. Scroll down 1 line to offset $196, and hit the spacebar to call the function, "Repeat last command". Notice that even though we used another function from a key, the spacebar is still bound to the last menu function we selected.
» While still at offset $196, type a "V" and enter "-1" for nw_DetailPen. Type Shift-rightArrow (shift + right cursor) to move forward 1 byte, and set nw_BlockPen to -1 also.
» Move down to offset $1AC and hit the spacebar. Do the same at offset $1B4. Notice that this last "Multiple constants" command put 4 words on the same line, but left WBENCHSCREEN alone. This is why we used an extra set data type to word before. "Multiple constants" stops when it reaches either a different data type, or a byte that already has its data type set. Lastly, we can add a blank line before and after the NewWindow structure by using full-line-comments. Remember, if a full-line-comment has a leading semicolon, it will not use the semicolon. So if our comment consists of only a semicolon, we will have a blank line. Go to offset $1BE and type a "kp-", then enter a ";" in the requester. Type a ShiftCtrl-upArrow to get back to MyNewWindow, and put a blank line there as well.
We have just completed our NewWindow structure. Looks pretty good, doesn't it? Lets take this opportunity to save the work we've done so far, and then we'll tackle something else.
» Select "PROJECT/Save .RS/Save:" from the menu. When the requester comes up, if you don't like the default name, type in a path and filename. It's usually a good idea to use the ".rs" suffix so you can tell that this is a ReSource data file.
Now that your work is saved, take another look at the NewWindow structure. Notice that the nw_FirstGadget field is non-zero. This means that this window has at least one gadget attached.
» Go to the nw_FirstGadget field of MyNewWindow (at offset $1A0) and use the right cursor key to go to that location. While we're here, we will rename this from "lbL0001BE" to "First_Gadget". This may not be the final name of this structure, but as we stated previously, it makes the name much easier to remember.
We are now going to construct a macro that will turn disassembled gadgets into code that looks like a gadget. FirstGadget should be on the current line for this exercise.
» Select "MACROS 1/Create:" and the first empty slot in the menu. When the requester asks for a name, enter "Gadget". Select all the functions from the following list. Take your time, and if you make a mistake, end the macro and start over. The text preceded by semicolons is for your benefit, not ReSource's, and shouldn't be entered.
Here is the function list for the "Gadget" macro:
|Function Name||Default Key||Gadget Field|
|DISPLAY/Set data type/Longs||;leftAmiga-L||gg_NextGadget|
|DISPLAY/Set data type/Words||;leftAmiga-W||gg_LeftEdge|
|DISPLAY/Set data type/Words||;leftAmiga-W||gg_Flags|
|SYMBOLS 2/E-G/Gadget flags|
|SYMBOLS 2/E-G/Gadget activation|
|SYMBOLS 2/E-G/Gadget types|
|DISPLAY/Set data type/Longs||;leftAmiga-L||gg_GadgetRender|
|DISPLAY/Set data type/Words||;leftAmiga-W||gg_GadgetID|
|DISPLAY/Set data type/Longs||;leftAmiga-L||gg_UserData|
|LABELS/Edit single/Full-line comment||;kp-||Enter ";"|
|CURSOR/Relative/Previous line||;upArrow||Do this 14 times|
|DISPLAY 2/Mult constants override/Set|
|DISPLAY/Set Numeric base/Decimal||;shift-~|
|CURSOR/Relative/Previous line||;up Arrow||Should be at First_Gadget now|
|CURSOR/Absolute/Forward reference||;rightArrow||This takes us to gg_NextGadget|
Press rightAmiga-A to end the macro.
Now we can use this macro to process any other gadgets (there are 2 more), and you will always have it to use on future gadgets. Note that the last line takes us to the next gadget in the linked list - if there are no more gadgets this field will be zero and the macro will fail at that point.
» Without changing the location which should be lblL0001FE, select "MACROS/Execute/Gadget:" twice to process both gadgets.
We are now positioned at the third and last gadget, but we don't know much about it. One of the best ways to find out about an Amiga© program is by looking at its menus and gadgets. And the best way to find out about a gadget is to look at its text, if it has some. This gadget has a pointer in its gg_GadgetText field, so we know there is an IntuiText structure. We will clean up this structure, and find the text.
» Go to the gadget's gg_GadgetText field at offset $26C and then forward reference to the IntuiText structure at offset $2B6. Using the skills that you have jsut learned, clean up and rename the structure so it looks like this:
Notice that we incorporated the text in the name of the IntuiText structure. It cannot be over emphasized that there is a world of difference between "lbB0002B6" and "False_ITxt". Even though "False" has no significance to us yet, "lbB0002B6" is an anonymous string of characters, and looks much like all other shop labels to our eyes. But "False_Itxt" is distinctive, and we will gradually build a mental model of what this code is doing, Even then, we can change the name if it no longer suits the code.False_ITxt DB 1,0,0,0 ;Was lbB0002B6 DW -4,20 DL MyTextAttr DL False.MSG DL 0
» Go back to lbL000252 and rename the gadget "False_Gadget".
Notice that the gadget has a pointer to something in its gg_GadgetRender field too. Because the GADIMAGE flags isn't present, we know that this must be a Border structure.
» Forward reference to this structure at offset $27E. Referring to your ROM Kernel Manual, clean it up so that it looks like this:
» Left arrow back to the gadget at offset $1FE. Notice that this gadget has no pointer to IntuiText, but does have pointers to both gg_GadgetRender and gg_SelectRender. Also note that both the GADGIMAGE and GADGHIMAGE flags are present. This means that we have Image structures. Follow the gg_GadgetRender and gg_SelectRender pointers, and clean up the Image structures so they look like this:Border1 DW 0,0 DB 2,0,0,3 DL Coords1 DL Border2 Coords1 DW 0,14,0,0,30,0 Border2 DW 0,0 DB 1,0,0,3 DL Coords2 DL 0 Coords2 DW 30,1,30,14,0,14
Remember that image structures point to image data, so we will also rename those, and clean them up too. Before we go, note that width of the image so you will know what data type to use. Remembering that image data must be a multiple of words, 31 bits would fit into either 2 words or 1 longword. It's fully your choice, but longwords will have fewer "%"s to get in your way than words. In this case we, will use longwords.Normal_Image DW 0,0,31,15,1 ;Was lbL00022A DL lbL000340 ;ig_ImageData DB 1,1 DL 0 Select_Image DW 0,0,31,15,1 ;Was lbL00023E DL lbL00037C ;ig_ImageData DB 1,1 DL 0
» Go to the first image data at offset $340. Name this "Normal_Data". Set the data type to longwords. Then, use ShiftCtrl-downArrow to select "CURSOR/Relative/Next label:" to go to the second image data at offset $37C. Insert a blank line here, using kp- and ";", and then name the second image, "Select_Data". Set the data type here to longwords, too. Use ShiftCtrl-upArrow to get back to offset $340.
» We are now going to build another macro, but this one is simpler; only 2 instructions. First, select "MACROS 1/Create:" and the first empty slot in the menu. When the requester asks for a name, enter anything you like. Then select "DISPLAY/Set Numeric base/Binary:", "CURSOR/Relative/Next line:" and "MACROS 1/Previous macro label/#1:". The macro is done, so press rightAmiga-A to end the macro. Execute this macro now.
» Now move the cursor back to the label "Normal_Data". But this time, do it by selecting "CURSOR/Absolute/Specify label:", and entering "Normal_Data".
What happened here is that the macro converted every line to binary. Take a moment and look at the neat image you just made.
» Left arrow back to the gadget at offset $1FE and rename it "Image_Gadget". Then go to the gadget at offset $1BE. Fix up it's IntuiText structure and rename that to "True_ITxt". Then rename the gadget to "True_Gadget". Finally, go back until you hits the reference to MyNewWindow at offset $6C.
We can now forward reference the location after the OpenWindow library call, and rename it "_WindowPtr". Since the line at offset $7A puts a pointer to the window structure into A0, then the number in the line at offset $7C must be an offset into that structure.
» Select "SYMBOLS 2/U-Z/Window:" for that line. The program now puts the pointer to the Window's RastPort into A1, and stores that for future use. Make offset$80 current, forward reference, and rename this "_RastPort". While we're at it, fill in the graphics library call at offset $8C, by using the "G" key.
The next line gets the pointer to the window into A2, so the number in the line at offset $94 must be an offset into that structure.
» Select "Window" again to have ReSource fix this up. The line at offset $98 puts AbsExecBase into A6, so it looks like we're getting ready to call Exec library. Use the "E" key on the line at offset $9C.
» This looks suspiciously like it could be our main GetMsg loop, so go back to the previous label and rename it "GetMessage".
After we call GetMsg, we test D0 to see if we actually got one. If so, we branch to label lbC0000AE. Since we come here if we get a message, let's call this "GotMessage". Moving to offset $A4, we see that if there is no message, we get the pointer to the UserPort from the Window again and then call another Exec library function.
» Use "SYMBOLS 2/U-Z/Window:" for the Window offset and the "E" key for the call.
Having arrived at GotMessage, we move the message pointer into A1 and reference offsets into whatever A1 is pointing at on 2 lines. Since this message came from the UserPort of a Window, it must be an IntuiMsg.
» Select "SYMBOLS 2/H-I/IntuiMessage:" for the lines at offsets $B0 and $B4. Then use the "E" key to fix the call to Exec library on the next line.
The next line compares D2 with some value. If we look back 3 lines we will find that im_Class was moved into D2.
» Select "SYMBOLS/I-H/IDCMP classes:" to change this into a symbol. Notice that we are making the same type of comparisons at offsets $CA and $DA. Move to those lines and just hit the spacebar for each one.
Notice that if the im_Class in D2 is equal to GADGETUP, we do a BSR to some routine at lbC000146. That might give us a clue to what the program is about, so letøs go take a look at it. First, it clears D0, then it gets the address of something into A0. Let's take a look at that. Referencing to "ascii.MSG" we find 4 spaces.
» As "Space4.txt" is much more informative, we'll rename it to that. Use leftArrow to return to lbC000146.
It appears that this subroutine contains 3 calls to graphics library. The best thing to do at this point is to name those, so we can see what is going on.
» Use the "G" key to name the 3 calls to graphics library.
This subroutine is setting the color of the front pen, moving to a particular spot in the RastPort, And writing the 4 spaces. So let's call our subroutines at lbC000146, "Print4Spaces". » Rename lbC000146 to "Print4Spaces".
That looks better, but the trouble is that we still don't know what that label, lbC00014C is for. Let's find out right now. ReSource has a number of different ways of looking for things. We could search for the label, but searches are relative slow. Even though this is a tiny program and it would not make any difference, we will use something else. ReSource has two functions that are frequently used together. The first function finds the absolute first backward reference to a label, i.e. something else that's referenceing that label. The second function finds all the other references, one at a time. These functions are extremely fast.
» Make the label, lbC00014C, the current line and type Alt-s to select "CURSOR/Absolute/Backwards reference:". Note where it landed. Then type Ctrl-s to select "CURSOR/Relative/Next backwards reference:". Type Ctrl-s repeatedly, until you are back at the original label, making note of the references as you go.
As it turns out, there were only two other references, and they were both close by. It looks like lbC00014C is the common code for all 3 routines. They enter with a pen number in D0, and a pointer to some text in A0. So let's call this subroutine, "PrintText".
» Rename lbC00014C to "PrintText". Use leftArrow to return to offset $C4. Note that you will have to use it several times because the previous functions push the target offsets onto the cursor stack, so that you can easily find them later.
Moving down the label lbC0000CA, we see that if the im_Class in D2 is equal to GADGETUP we take something out of what A2 is pointing at and put it into A0. Remembering that at offset $B4, the program put im_IAddress into A2, and this is a GADGETUP class message, A2 must point to a gadget.
» Select "SYMBOLS 2/E-G/Gadget:" for the line at offset $D2.
Because the next line does an indirect JSR off this data, these must be pointers to routines for the gadgets. The only way we can trace these is go back to the gadgets themselves, and see what is in the the gg_UserData fields. Because we used the "Backwards reference" functions previously, let's use a search function this time. Since we created the names of the gadgets, we know that all 3 of them have the string "_Gadget" in common.
» Type F7 to select "CURSOR/Normal search/Set search pattern:", and type "_Gadget" into the requester. If anything else was already there, type rightAmiga-X to clear it. Not type F9 to select "CURSOR/Normal search/Find next occurrence:". The first time you will come to the NewWindow structure, so type F9 again to find the first gadget. The gg_UserData field is at the very end of this gadget. Scroll down there and use the rightArrow to get to its reference.
This routine call PrintText with pen #3, and text that says, "True". Since this function address came from True_Gadget, we could call this, "PrintTrue".
» Rename lbC000136 to "PrintTrue". LeftArrow back, and type F9 to find the next gadget. Scroll down to its gg_UserData and use rightArrow again to get to its reference.
Here is something different. This doesn't look at all like the other gadget's action routines. As usual, the first thing to do is to resolve the symbol offsets so that we can find out what is going on.
» Use "SYMBOLS 2/U-Z/Window:" and the "I" key to resolve these symbols.
It looks as if the False_Gadget beeps the screen when it's poked.
» Rename lbC000174 to "Beep". LeftArrow back to the gadget. Use "PROJECT/Save .RS:" to save your work.
That pretty well wraps up the tutorial. You now know everything you need to know to finish tidying up the program. The original source code is provided so that you can compare it to this disassembly, if you like.
This can easily be accomplished by using the "DISPLAY/Set counter:"
function. Position the base point at the current line and
select this function. From now on, the offsets shown in the titlebar
will be relative to your selected base, rather than from the start of the
file. In order to again show offsets relative to the beginning of the
file select "DISPLAY/Reset counter:".
If you scroll ahead in this file $CA*4, or $328 bytes, ahead in the file, you will come to the following line:DC.L HUNK_CODE ;Hunk size DC.L $CA ;Size of code ;Start of code LEA (START+$034A,PC),A5 MOVEA.L A5,A0 MOVEQ #$1D,D1 MOVEQ #0,D0 ... DC.L HUNK_END ;End of this hunk
There are many different hunk types, and they have different formats. Consult your AmigaDOS™ manual for more information.DC.L HUNK_RELOC32 DC.L 8 ;# of offsets DC.L 1 ;Hunk number DC.L $238 ;Offsets DC.L $234 DC.L $230 ... DC.L HUNK_END
The last two lines of code tell us immediately that we are getting a word offset from the table at "lbW00A8A6", and that the jump location is "lbW00A8A8". In order to turn the word offset into a symbolic offset to the routines that we will call, and at the same time create labels for those routines, we need to do two things.MOVE.L D7,D0 SUBQ.L #1,D0 BLT.W lbC00AB6A CMPI.L #7,D0 BGE.W lbC00AB6A ADD.W D0,D0 MOVE.W (lbW00A8A6,PC,D0.W),D0 JMP (lbW00A8A8,PC,D0.W lbW00A8A6 DC.W $C lbW00A8A8 DC.W $A0 DC.W $C2 DC.W $DC DC.W $154 DC.W $1D4 DC.W $1EE
First tell ReSource where the offset base is by scrolling so that "lbW00A8A8" is the current line and selecting "SPECIAL FUNCTIONS/Convert specific EA's/Set base #1:". Then we can scroll up one line to the start of the table, at "lbW00A8A6" and select "SPECIAL FUNCTIONS/Cvert W/base 1:" to actually do the conversion. The later function must be done for each offset in the table. When we're done, it will look like this:
lbW00A8A6 DC.W lbC00A8B4-lbC00A8A8 lbW00A8A8 DC.W lbC00A948-lbC00A8A8 DC.W lbC00A96A-lbC00A8A8 DC.W lbC00A984-lbC00A8A8 DC.W lbC00A9FC-lbC00A8A8 DC.W lbC00AA7C-lbC00A8A8 DC.W lbC00AA96-lbC00A8A8
This will load the boot sectors, a total of 1024 bytes, from DF0:. Similarly, to load the same data when ReSource is already running, select "PROJECT/Read tracks:" and enter "DF0: 0 0 2" into the requester.1>ReSource *DF0: 0 0 2
Once the boot code is entered, how you disassemble it depends on what the code looks like. A standard boot block might look like:
On the other hand, custom boot code, or a virus might be very complex. Some of the other topics in this section may offer some clues. The best advice is that becoming very good at disassembling code is much like other pursuits; it takes a lot of work, practice, and experience.DC.B 'DOS',0 ;OFS DC.L $C0200F19 ;Checksum DC.L 880 ;# of blocks BootCode LEA (DosName,PC),A1 JSR (_LVOFindResident,A6) TST.L D0 BEQ.B NoDos MOVEA.L D0,A0 MOVEA.L (RT_INIT,A0),A0 MOVEQ #0,D0 Done RTS NoDos MOVEQ #-1,D0 BRA.B Done DosName DC.B 'dos.library',0
After the code is reassembled with symbols, run it through your favorite debugger, and pay careful attention to where the decrypted code is being stored. After you have successfully regenerated the encrypted code, either give ReSource the address of the buffer and use the "Disassemble memory" function, or save the buffer and load it into ReSource as a binary file.
Because ReSource cannot use internal information supplied by the loader to make decisions based on data type, it is best not to use the automatic "Disassemble" function. Doing so would likely create a lot of undesirable labels in the middle of instructions as ReSource runs into data or ASCII, and tries to disassemble it. Proceed slowly and careful, making reasonable sure that an area is code before you attempt to disassemble it and/or create labels.
Much thanks to Doug Sears and Grace Lavin for ideas, proofreading, and general support.
Layout and typesetting done by Jeff Lavin on an Amiga 3000, using Professional Page, and an NEC SilentWriter LC890.
Printing done by Print Worx of Eugene, Oregon.