home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 564.EVAL.TXT < prev    next >
Text File  |  1989-01-23  |  17KB  |  374 lines

  1.             NET/ROM vs. TheNet, a Software Comparison
  2.  
  3.  
  4. During the late summer of 1988, I obtained the source files of
  5. NET/ROM 1.3 from the author and the source files of TheNet
  6. version 1.0/1.1 from local sources in order to do an independent
  7. comparison in light of claims by Software 2000 of copyright
  8. infringement by the Northern German Packet Group, NORD><LINK.
  9. This document reports my findings.
  10.  
  11. NET/ROM is a firmware replacement which converts a regulation
  12. TNC-2 to a packet radio network node controller.  It was written
  13. by Ronald Raikes, WA8DED.  Although I am a packet enthusiast, I
  14. have no connection with Software 2000 nor any proprietary
  15. interest in NET/ROM.  My interest in doing this evaluation was
  16. purely technical.
  17.  
  18. First Things First:
  19.  
  20. I started this activity by copying all the NET/ROM and TheNet
  21. source files to my hard disk.  After removing all tabs, the files
  22. were printed on a laser printer and separated into two 3-ring
  23. binders.  After considerable time reviewing the 2-inch stack of
  24. listings wondering how to attack the project, I discovered a
  25. curious and consistent similarity.  Some routines in one set
  26. appeared to have a counterpart routine in the other binder; they
  27. were of similar lengths, had the same number of formal calling
  28. parameters, same number of local variables, and virtually
  29. identical form of construction.
  30.  
  31. I decided to create a cross-reference table of routine names and
  32. their associated file names so I could keep track of this manual
  33. progress through the files.  I "visited" every routine in the
  34. NET/ROM binder and copied the procedure name, the file name, and
  35. the number of parameters into a text file.  After sorting on the
  36. column of procedure names, I printed the file to use as a
  37. worksheet.
  38.  
  39. I began to search through the set of TheNet files to find some
  40. correlation with the NET/ROM routines I had already cataloged.
  41. By narrowing each search pass to just those files dealing with a
  42. single protocol layer (starting with layer 7), the table was
  43. filled in rather quickly.  Nevertheless, this effort took over
  44. two weeks of part-time work.  For every NET/ROM routine, there
  45. was a matching NordLink routine, but I had four TheNet routines
  46. left over which had no match in NET/ROM.  The result of this
  47. effort was a four page reference of all routine and file names
  48. and number of parameters.
  49.  
  50. I compared every pair of routines visually, line by line.  When I
  51. ran my index fingers down each page, the same pattern recurred;
  52. an IF followed by an assignment, followed by a procedure call,
  53. followed by a pointer increment, followed by a call, etc., ad
  54. infinitum.  Every called procedure in TheNet could be cross-
  55. referenced to the matching NET/ROM routine I had cataloged.  When
  56. NET/ROM called a C routine, so did TheNet.  When assembly
  57. language was called, so did TheNet.  I  became progressively more
  58. frustrated at the slim prospect of doing this by some automated
  59. means, but I continued with this painstaking process to the
  60. bitter end.
  61.  
  62. Findings:
  63.  
  64. 1  There are 234 NET/ROM routines in version 1.3.  I define
  65.    "routine" as an executable code segment named as public
  66.    (global), which includes all C functions and entry points to
  67.    assembly language code.
  68.  
  69. 2  One routine in NET/ROM, crlf (file LAYER7CN.C), is not
  70.    referenced therein and has no complement in TheNet.  This
  71.    widowed code was probably an oversight from a previous release
  72.    of the firmware.
  73.  
  74. 3  One routine in NET/ROM, staind (file TNC2N.MAC), is not
  75.    referenced.  The matching routine is referenced and used in
  76.    TheNet as STAled (file TNL1.MAC).
  77.  
  78. 4  Of the remaining 232 routines in NET/ROM, all are duplicated
  79.    in TheNet with identical numbers and types of passed
  80.    parameters.  In cases where there are two or more parameters
  81.    in calling arguments, the order has been consistently reversed
  82.    in TheNet.  Reversing the order of the parameters was no doubt
  83.    due to an individual's preference.
  84.  
  85. 5  In every TheNet C function, an identical number and type of
  86.    auto variables are allocated on the stack in the same order as
  87.    they are in the corresponding NET/ROM routine.
  88.  
  89. 6  All structures in NET/ROM having preset data have an identical
  90.    analogue in TheNet including order and type of data
  91.    initialized.  This includes all character strings and
  92.    procedure jump address tables.
  93.  
  94. 7  TheNet routines l2init (in L2E.c), l3init (in TNL3.C), and
  95.    inivar (in TNL7A.C) differ from the corresponding NET/ROM
  96.    routines only in that a single statement has been deleted to
  97.    remove callsign encryption.  l2init of TheNet has one
  98.    additional procedure call related to cold-booting.
  99.  
  100. 8  Full duplex was later added to TheNet routine hstcmd (in
  101.    TNL7C.C).  This added a 20-line case 'F' to an existing switch
  102.    statement and comprised three if statements, six function
  103.    calls, and two assignments.  In assembly language, 16 bytes
  104.    were required to complete this modification, including 3 lines
  105.    in routine kicktx (in TNL1.MAC) and 11 lines of a new module,
  106.    pushtx (in TNL7B.C).  The IDENT command was renamed to INFO
  107.    and the sysop's password was initialized to a different
  108.    string, both minor changes.
  109.  
  110. 9  In NET/ROM layer 2, nine interrupt service routines dealing
  111.    with low level I/O and buffer allocation and de-allocation
  112.    were manually recoded by the author to ensure an adequate
  113.    processing margin at 9600 bps.  These functions were
  114.    originally written in C for the AX.25 Level 2 user firmware
  115.    for the TNC-2.  An assembly language source file, created with
  116.    a Q/C compiler option, was used as a starting point.  It was
  117.    then hand-optimized and assembled.  This optimized set of
  118.    assembly language functions is identical, instruction for
  119.    instruction, in TheNet (file L2D.C, #ifndef PORTABLE).
  120.  
  121. 10 Two trivial routines, ccphig and ccplow, were added in TheNet
  122.    to implement the HIGH and LOW commands.  Each has 15 lines and
  123.    comprises one if, three procedure calls, and a switch with two
  124.    cases.
  125.  
  126. 11 There are minor differences in other assembly language files
  127.    related to NordLink's use of a later version of the C compiler
  128.    (the Q/C compiler supports in-line assembly language).  For
  129.    example, the newer version of the compiler can save one byte
  130.    when clearing a double register.  In some cases, TheNet used a
  131.    variation on the subroutine entry macro.
  132.  
  133. 12 TheNet uses a #define statement in its primary include file,
  134.    ALL.H, to define a preprocessor variable FIRMWARE.  When this
  135.    variable is defined, the source code is conditionally compiled
  136.    into TheNet (the network node controller), and when not
  137.    defined, the code compiles into TheFirmware, a replacement for
  138.    the user firmware for the TNC-2.  The NET/ROM source is
  139.    similarly structured with a preprocessor variable, and
  140.    conditionally compiles the WA8DED AX.25 user firmware for the
  141.    TNC-2.  That firmware is available on many BBS, and is the
  142.    foundation on which NET/ROM was built by the author.
  143.  
  144. 13 TheNet does not contain the code to support the PK-87 TNC.
  145.    NET/ROM's support for the PK-87 is conditionally compiled when
  146.    a preprocessor variable called PK87N is defined.
  147.  
  148. 14 NET/ROM, in my opinion, is concise and easier to follow
  149.    (notwithstanding TheNet's extensive documentation in German).
  150.  
  151. Object File Comparison:
  152.  
  153. I have not personally evaluated the hex files of the original and
  154. the NordLink versions.  Members of NordLink on at least two
  155. occasions have publicly suggested independent comparison of the
  156. binary files.  However, they never recommended comparison at the
  157. source code level.  Many well-meaning people in the U.S. have
  158. performed their own evaluations of the programs' differences
  159. based on the only materials available to them, the hex files.
  160. Their conclusions have ranged from "maybe 20-30 percent
  161. identical" to "definitely a copy."  However, any judgment of the
  162. similarities of NET/ROM and TheNet from the comparison of hex
  163. files is fallacious because of the following:
  164.  
  165. o  A single difference in the relative placement of any global,
  166.    local, or static data item (simple item, table, structure,
  167.    etc) will render slightly different byte or word addresses.
  168.    Since addresses comprise a major portion of the object code,
  169.    the hex address of the item will be different throughout the
  170.    module.
  171.  
  172. o  A minor addition or removal of code (full duplex, HIGH and LOW
  173.    commands, callsign encryption) will show as blocks of
  174.    dissimilar code including addresses of function entry points,
  175.    followed by major discrepancies.
  176.  
  177. o  Even a minor reordering of object modules in the linking step
  178.    will render major differences in the hex file.  Sophisticated
  179.    pattern matching programs may be able to discover this
  180.    reordering, however, jump addresses and procedure entry points
  181.    beyond the reordering point will change significantly.
  182.  
  183. There is no possibility that the source programs for NET/ROM were
  184. obtained by NordLink as they had never left the author's house
  185. until the electronic version was loaned to me for review.  The
  186. only real determination of whether TheNet is an original work can
  187. only be done at the source program level.
  188.  
  189. Evaluation:
  190.  
  191. Based on a line-by-line comparison of the two products and 22
  192. years of software experience, I am convinced that the only way
  193. that TheNet could be identical in the structure, calling
  194. sequences and variable definitions of NET/ROM would be to have
  195. disassembled/de-compiled the object code from NET/ROM.  TheNet is
  196. not an original development but rather a replica of the thoughts,
  197. concepts, and the painstakingly developed design embodied in
  198. NET/ROM.  According to NordLink, "disassembling NET/ROM and then
  199. rewriting it in C would be silly."  However, since the source was
  200. not available, their only alternative was to do exactly that -
  201. disassemble the binary code from a NET/ROM 27C256 EPROM and
  202. construct a source program that would produce identical binary
  203. code.
  204.  
  205. Disassembly and De-compilation Methodology:
  206.  
  207. Without doubt, the starting point of this effort began with the
  208. low memory and Q/C library routines, and the routing table
  209. structure and the layer protocol definitions described in the
  210. NET/ROM documentation.  The hex files of WA8DED's user firmware
  211. available in the public domain no doubt provided a convenient set
  212. of low-level I/O routines.
  213.  
  214. Generating assembly language from object code is relatively
  215. simple; disassemblers for all machine codes have been around a
  216. long time.  Converting assembly language to a higher order
  217. language like "C" requires much more forbearance.
  218.  
  219. The Q/C compiler traces its heritage to Ron Cain's Small-C from
  220. the 8080 CP/M world (Hendrix "A Small-C Compiler").  It is a non-
  221. optimizing compiler and, consequently, the structure of its
  222. generated object code for any C construct is predictable and
  223. consistent.  With suitable automated tools, much manual
  224. intervention and an intimate knowledge of the compiler's code
  225. generator, any section of code suspected of originating from this
  226. C compiler can be reconstructed into a syntactically correct
  227. source program.
  228.  
  229. Any programmer who has delved into compiler-generated object code
  230. will recognize that variable names and function names do not
  231. exist at this stage, merely address references to data and
  232. subprograms.  However, if meaningful names are assigned to those
  233. addresses, and suitable comments placed in the source code, the
  234. original meaning and intent of a function in terms of a network
  235. controller will iteratively become evident.  I say iteratively
  236. because a source program, when compiled, can eventually be
  237. modified to generate a given object program.  When all object
  238. modules are linked in the same order as the thing you're copying,
  239. an identical executable module will result.  Minor changes of
  240. data location, removing callsign encryption, adding full duplex
  241. or other minor features could confuse a (hex file) comparison
  242. program, leading one to erroneously conclude that the executable
  243. modules are very different.
  244.  
  245. Source Code Comparison:
  246.  
  247. My visual examination of each routine showed that source code
  248. from both programs was identical, statement by statement, with
  249. only variable, data, and structure names changing.  However, the
  250. source code does not lend itself well to comparison by automatic
  251. means.  Because the object code was analyzed and equivalent
  252. source code was reconstructed from it, virtually no procedure
  253. names or variable names are the same.  To perform even a cursory
  254. quantitative evaluation, one would have to remove all comments
  255. and white space from both versions, transliterate variable and
  256. procedure names into common, but arbitrary, names and convert
  257. both sources to either upper or lower case before a programmatic
  258. comparison could be attempted.
  259.  
  260. Additional problems thwarting an automatic comparison was
  261. TheNet's:
  262.  
  263. o  use of typedef, for example, 'typedef int VOID' and 'typedef
  264.    unsigned BOOLEAN', which created synonyms for common data
  265.    types
  266.  
  267. o  use of #define to create new language constructs, for example,
  268.    '#define LOOP for(;;)' for an infinite loop
  269.  
  270. o  use of numeric constants in the source whose meaning was not
  271.    necessarily understood.  On the other hand, both programs made
  272.    considerable use of #define to give (different) names to
  273.    important and frequently used constants
  274.  
  275. o  source coding variations when using a different set of data
  276.    structures (note: code generated to access the data was the
  277.    same as NET/ROM's accessing its own data structures!).
  278.  
  279. However, even after the automatic comparison, a manual
  280. examination would still be necessary to resolve differences such
  281. as:
  282.  
  283.         if (a != 0) {...}
  284. and     if (!a) {...}
  285.  
  286. as being equivalent and identical, and to recognize that code
  287. segments such as
  288.  
  289.         a = b;
  290.         for (i=0; i<max; ++i,++a) {...}
  291.  
  292. and     for (a=b,i=0; i<max; ++i,++a) {...}
  293.  
  294. or      for (xyz=foo,w=0; w<limit; ++w,++xyz) {...}
  295.  
  296. are entirely equivalent and would compile to identical object
  297. code.
  298.  
  299. As a better example of this comparison difficulty, consider
  300. NET/ROM's layer 7 routine, validc, and TheNet's routine, fvalca,
  301. which validate a callsign:
  302.  
  303. validc(call,valflg)
  304. char *call;
  305. unsigned int valflg;
  306. {
  307.     return(*call == ' ' ? FALSE :
  308.            (valflg == FALSE ? TRUE : valcsc(call)));
  309. }
  310.  
  311. fvalca(pflag, call)
  312. char    *call;
  313. BOOLEAN pflag;
  314.   {
  315.   if (*call == ' ' ) return(0);
  316.   if (!pflag) return (1);
  317.   return (valcal(call));
  318.   }
  319.  
  320. These equivalent routines return 1 if the callsign is valid; 0 or
  321. -1 if not valid.  Although they look quite different to the
  322. untrained eye, the curious programmer is invited to pass these
  323. examples through his favorite C compiler (I used Borland's Turbo
  324. C) and generate the intermediate assembly language; you don't
  325. necessarily need to target to a Z-80 or to a non-stack machine.
  326. These listings are identical if the formal argument parameters in
  327. fvalca are reversed, TRUE and FALSE are defined as 1 and 0
  328. respectively (as they are in NET/ROM and TheNet with #define
  329. statements), and typedef'ing BOOLEAN as unsigned (as done in
  330. TheNet).  Other less trivial examples I have run through my
  331. compiler show the same consistent comparisons at the assembly
  332. language level.
  333.  
  334. One of the more complicated routines extracted from both versions
  335. was the level 4 receive function l4rx (TheNet file TNL4.C) and
  336. l4rcve (NET/ROM file LAYER4.C).  This particular pair of
  337. procedures was selected because it was representative of an
  338. extensive use of C structures and pointers.  I was careful to
  339. insert (#include) the same files used in the parent source file
  340. and to reverse the arguments in TheNet's function calls before
  341. compiling.  There were five minor differences in the 631-line
  342. assembly language files produced.  The object file length for
  343. NET/ROM was 2599; TheNet's was 2577.
  344.  
  345. This slight difference can be attributed to my use of a compiler
  346. that is targeted to the 8086 family, stack-oriented processors
  347. unlike the Z-80; it merely is the only C compiler I have.  As
  348. mentioned previously, Q/C is not an optimizing compiler and it
  349. produces code that is not stack-oriented.  Optimization is
  350. standard for my compiler and cannot be disabled.  Minor source
  351. coding variations can account for the order and manner in which
  352. addresses are calculated.
  353.  
  354. Conclusion:
  355.  
  356. It is my conclusion, and I believe would be the conclusion of any
  357. rational reviewer, that TheNet is not an original development but
  358. rather a direct copy of NET/ROM.  This exercise has left no
  359. question in my mind about the method that NordLink used to make
  360. their "original" design fully compatible with NET/ROM.  Rather
  361. than start with the description of the layer protocols and the
  362. routing table, and then independently design and build a
  363. compatible product (as the author hoped somebody would), they
  364. disassembled Software 2000's product and reused the design in its
  365. entirety, procedure by procedure, and steadfastly proclaimed
  366. original work.  According to NordLink, "it is truly a new and
  367. innovative program with many new features".  I have seen no
  368. evidence of originality, innovation, significant enhancements or
  369. functional changes.
  370.  
  371. Thomas M. Allen, WA6IGY
  372. CIS [72537,1143]
  373. January 1989
  374.