home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hacker Chronicles 2
/
HACKER2.BIN
/
564.EVAL.TXT
< prev
next >
Wrap
Text File
|
1989-01-23
|
17KB
|
374 lines
NET/ROM vs. TheNet, a Software Comparison
During the late summer of 1988, I obtained the source files of
NET/ROM 1.3 from the author and the source files of TheNet
version 1.0/1.1 from local sources in order to do an independent
comparison in light of claims by Software 2000 of copyright
infringement by the Northern German Packet Group, NORD><LINK.
This document reports my findings.
NET/ROM is a firmware replacement which converts a regulation
TNC-2 to a packet radio network node controller. It was written
by Ronald Raikes, WA8DED. Although I am a packet enthusiast, I
have no connection with Software 2000 nor any proprietary
interest in NET/ROM. My interest in doing this evaluation was
purely technical.
First Things First:
I started this activity by copying all the NET/ROM and TheNet
source files to my hard disk. After removing all tabs, the files
were printed on a laser printer and separated into two 3-ring
binders. After considerable time reviewing the 2-inch stack of
listings wondering how to attack the project, I discovered a
curious and consistent similarity. Some routines in one set
appeared to have a counterpart routine in the other binder; they
were of similar lengths, had the same number of formal calling
parameters, same number of local variables, and virtually
identical form of construction.
I decided to create a cross-reference table of routine names and
their associated file names so I could keep track of this manual
progress through the files. I "visited" every routine in the
NET/ROM binder and copied the procedure name, the file name, and
the number of parameters into a text file. After sorting on the
column of procedure names, I printed the file to use as a
worksheet.
I began to search through the set of TheNet files to find some
correlation with the NET/ROM routines I had already cataloged.
By narrowing each search pass to just those files dealing with a
single protocol layer (starting with layer 7), the table was
filled in rather quickly. Nevertheless, this effort took over
two weeks of part-time work. For every NET/ROM routine, there
was a matching NordLink routine, but I had four TheNet routines
left over which had no match in NET/ROM. The result of this
effort was a four page reference of all routine and file names
and number of parameters.
I compared every pair of routines visually, line by line. When I
ran my index fingers down each page, the same pattern recurred;
an IF followed by an assignment, followed by a procedure call,
followed by a pointer increment, followed by a call, etc., ad
infinitum. Every called procedure in TheNet could be cross-
referenced to the matching NET/ROM routine I had cataloged. When
NET/ROM called a C routine, so did TheNet. When assembly
language was called, so did TheNet. I became progressively more
frustrated at the slim prospect of doing this by some automated
means, but I continued with this painstaking process to the
bitter end.
Findings:
1 There are 234 NET/ROM routines in version 1.3. I define
"routine" as an executable code segment named as public
(global), which includes all C functions and entry points to
assembly language code.
2 One routine in NET/ROM, crlf (file LAYER7CN.C), is not
referenced therein and has no complement in TheNet. This
widowed code was probably an oversight from a previous release
of the firmware.
3 One routine in NET/ROM, staind (file TNC2N.MAC), is not
referenced. The matching routine is referenced and used in
TheNet as STAled (file TNL1.MAC).
4 Of the remaining 232 routines in NET/ROM, all are duplicated
in TheNet with identical numbers and types of passed
parameters. In cases where there are two or more parameters
in calling arguments, the order has been consistently reversed
in TheNet. Reversing the order of the parameters was no doubt
due to an individual's preference.
5 In every TheNet C function, an identical number and type of
auto variables are allocated on the stack in the same order as
they are in the corresponding NET/ROM routine.
6 All structures in NET/ROM having preset data have an identical
analogue in TheNet including order and type of data
initialized. This includes all character strings and
procedure jump address tables.
7 TheNet routines l2init (in L2E.c), l3init (in TNL3.C), and
inivar (in TNL7A.C) differ from the corresponding NET/ROM
routines only in that a single statement has been deleted to
remove callsign encryption. l2init of TheNet has one
additional procedure call related to cold-booting.
8 Full duplex was later added to TheNet routine hstcmd (in
TNL7C.C). This added a 20-line case 'F' to an existing switch
statement and comprised three if statements, six function
calls, and two assignments. In assembly language, 16 bytes
were required to complete this modification, including 3 lines
in routine kicktx (in TNL1.MAC) and 11 lines of a new module,
pushtx (in TNL7B.C). The IDENT command was renamed to INFO
and the sysop's password was initialized to a different
string, both minor changes.
9 In NET/ROM layer 2, nine interrupt service routines dealing
with low level I/O and buffer allocation and de-allocation
were manually recoded by the author to ensure an adequate
processing margin at 9600 bps. These functions were
originally written in C for the AX.25 Level 2 user firmware
for the TNC-2. An assembly language source file, created with
a Q/C compiler option, was used as a starting point. It was
then hand-optimized and assembled. This optimized set of
assembly language functions is identical, instruction for
instruction, in TheNet (file L2D.C, #ifndef PORTABLE).
10 Two trivial routines, ccphig and ccplow, were added in TheNet
to implement the HIGH and LOW commands. Each has 15 lines and
comprises one if, three procedure calls, and a switch with two
cases.
11 There are minor differences in other assembly language files
related to NordLink's use of a later version of the C compiler
(the Q/C compiler supports in-line assembly language). For
example, the newer version of the compiler can save one byte
when clearing a double register. In some cases, TheNet used a
variation on the subroutine entry macro.
12 TheNet uses a #define statement in its primary include file,
ALL.H, to define a preprocessor variable FIRMWARE. When this
variable is defined, the source code is conditionally compiled
into TheNet (the network node controller), and when not
defined, the code compiles into TheFirmware, a replacement for
the user firmware for the TNC-2. The NET/ROM source is
similarly structured with a preprocessor variable, and
conditionally compiles the WA8DED AX.25 user firmware for the
TNC-2. That firmware is available on many BBS, and is the
foundation on which NET/ROM was built by the author.
13 TheNet does not contain the code to support the PK-87 TNC.
NET/ROM's support for the PK-87 is conditionally compiled when
a preprocessor variable called PK87N is defined.
14 NET/ROM, in my opinion, is concise and easier to follow
(notwithstanding TheNet's extensive documentation in German).
Object File Comparison:
I have not personally evaluated the hex files of the original and
the NordLink versions. Members of NordLink on at least two
occasions have publicly suggested independent comparison of the
binary files. However, they never recommended comparison at the
source code level. Many well-meaning people in the U.S. have
performed their own evaluations of the programs' differences
based on the only materials available to them, the hex files.
Their conclusions have ranged from "maybe 20-30 percent
identical" to "definitely a copy." However, any judgment of the
similarities of NET/ROM and TheNet from the comparison of hex
files is fallacious because of the following:
o A single difference in the relative placement of any global,
local, or static data item (simple item, table, structure,
etc) will render slightly different byte or word addresses.
Since addresses comprise a major portion of the object code,
the hex address of the item will be different throughout the
module.
o A minor addition or removal of code (full duplex, HIGH and LOW
commands, callsign encryption) will show as blocks of
dissimilar code including addresses of function entry points,
followed by major discrepancies.
o Even a minor reordering of object modules in the linking step
will render major differences in the hex file. Sophisticated
pattern matching programs may be able to discover this
reordering, however, jump addresses and procedure entry points
beyond the reordering point will change significantly.
There is no possibility that the source programs for NET/ROM were
obtained by NordLink as they had never left the author's house
until the electronic version was loaned to me for review. The
only real determination of whether TheNet is an original work can
only be done at the source program level.
Evaluation:
Based on a line-by-line comparison of the two products and 22
years of software experience, I am convinced that the only way
that TheNet could be identical in the structure, calling
sequences and variable definitions of NET/ROM would be to have
disassembled/de-compiled the object code from NET/ROM. TheNet is
not an original development but rather a replica of the thoughts,
concepts, and the painstakingly developed design embodied in
NET/ROM. According to NordLink, "disassembling NET/ROM and then
rewriting it in C would be silly." However, since the source was
not available, their only alternative was to do exactly that -
disassemble the binary code from a NET/ROM 27C256 EPROM and
construct a source program that would produce identical binary
code.
Disassembly and De-compilation Methodology:
Without doubt, the starting point of this effort began with the
low memory and Q/C library routines, and the routing table
structure and the layer protocol definitions described in the
NET/ROM documentation. The hex files of WA8DED's user firmware
available in the public domain no doubt provided a convenient set
of low-level I/O routines.
Generating assembly language from object code is relatively
simple; disassemblers for all machine codes have been around a
long time. Converting assembly language to a higher order
language like "C" requires much more forbearance.
The Q/C compiler traces its heritage to Ron Cain's Small-C from
the 8080 CP/M world (Hendrix "A Small-C Compiler"). It is a non-
optimizing compiler and, consequently, the structure of its
generated object code for any C construct is predictable and
consistent. With suitable automated tools, much manual
intervention and an intimate knowledge of the compiler's code
generator, any section of code suspected of originating from this
C compiler can be reconstructed into a syntactically correct
source program.
Any programmer who has delved into compiler-generated object code
will recognize that variable names and function names do not
exist at this stage, merely address references to data and
subprograms. However, if meaningful names are assigned to those
addresses, and suitable comments placed in the source code, the
original meaning and intent of a function in terms of a network
controller will iteratively become evident. I say iteratively
because a source program, when compiled, can eventually be
modified to generate a given object program. When all object
modules are linked in the same order as the thing you're copying,
an identical executable module will result. Minor changes of
data location, removing callsign encryption, adding full duplex
or other minor features could confuse a (hex file) comparison
program, leading one to erroneously conclude that the executable
modules are very different.
Source Code Comparison:
My visual examination of each routine showed that source code
from both programs was identical, statement by statement, with
only variable, data, and structure names changing. However, the
source code does not lend itself well to comparison by automatic
means. Because the object code was analyzed and equivalent
source code was reconstructed from it, virtually no procedure
names or variable names are the same. To perform even a cursory
quantitative evaluation, one would have to remove all comments
and white space from both versions, transliterate variable and
procedure names into common, but arbitrary, names and convert
both sources to either upper or lower case before a programmatic
comparison could be attempted.
Additional problems thwarting an automatic comparison was
TheNet's:
o use of typedef, for example, 'typedef int VOID' and 'typedef
unsigned BOOLEAN', which created synonyms for common data
types
o use of #define to create new language constructs, for example,
'#define LOOP for(;;)' for an infinite loop
o use of numeric constants in the source whose meaning was not
necessarily understood. On the other hand, both programs made
considerable use of #define to give (different) names to
important and frequently used constants
o source coding variations when using a different set of data
structures (note: code generated to access the data was the
same as NET/ROM's accessing its own data structures!).
However, even after the automatic comparison, a manual
examination would still be necessary to resolve differences such
as:
if (a != 0) {...}
and if (!a) {...}
as being equivalent and identical, and to recognize that code
segments such as
a = b;
for (i=0; i<max; ++i,++a) {...}
and for (a=b,i=0; i<max; ++i,++a) {...}
or for (xyz=foo,w=0; w<limit; ++w,++xyz) {...}
are entirely equivalent and would compile to identical object
code.
As a better example of this comparison difficulty, consider
NET/ROM's layer 7 routine, validc, and TheNet's routine, fvalca,
which validate a callsign:
validc(call,valflg)
char *call;
unsigned int valflg;
{
return(*call == ' ' ? FALSE :
(valflg == FALSE ? TRUE : valcsc(call)));
}
fvalca(pflag, call)
char *call;
BOOLEAN pflag;
{
if (*call == ' ' ) return(0);
if (!pflag) return (1);
return (valcal(call));
}
These equivalent routines return 1 if the callsign is valid; 0 or
-1 if not valid. Although they look quite different to the
untrained eye, the curious programmer is invited to pass these
examples through his favorite C compiler (I used Borland's Turbo
C) and generate the intermediate assembly language; you don't
necessarily need to target to a Z-80 or to a non-stack machine.
These listings are identical if the formal argument parameters in
fvalca are reversed, TRUE and FALSE are defined as 1 and 0
respectively (as they are in NET/ROM and TheNet with #define
statements), and typedef'ing BOOLEAN as unsigned (as done in
TheNet). Other less trivial examples I have run through my
compiler show the same consistent comparisons at the assembly
language level.
One of the more complicated routines extracted from both versions
was the level 4 receive function l4rx (TheNet file TNL4.C) and
l4rcve (NET/ROM file LAYER4.C). This particular pair of
procedures was selected because it was representative of an
extensive use of C structures and pointers. I was careful to
insert (#include) the same files used in the parent source file
and to reverse the arguments in TheNet's function calls before
compiling. There were five minor differences in the 631-line
assembly language files produced. The object file length for
NET/ROM was 2599; TheNet's was 2577.
This slight difference can be attributed to my use of a compiler
that is targeted to the 8086 family, stack-oriented processors
unlike the Z-80; it merely is the only C compiler I have. As
mentioned previously, Q/C is not an optimizing compiler and it
produces code that is not stack-oriented. Optimization is
standard for my compiler and cannot be disabled. Minor source
coding variations can account for the order and manner in which
addresses are calculated.
Conclusion:
It is my conclusion, and I believe would be the conclusion of any
rational reviewer, that TheNet is not an original development but
rather a direct copy of NET/ROM. This exercise has left no
question in my mind about the method that NordLink used to make
their "original" design fully compatible with NET/ROM. Rather
than start with the description of the layer protocols and the
routing table, and then independently design and build a
compatible product (as the author hoped somebody would), they
disassembled Software 2000's product and reused the design in its
entirety, procedure by procedure, and steadfastly proclaimed
original work. According to NordLink, "it is truly a new and
innovative program with many new features". I have seen no
evidence of originality, innovation, significant enhancements or
functional changes.
Thomas M. Allen, WA6IGY
CIS [72537,1143]
January 1989