[comp.sys.next] Ripping apart NIBS

simsong@daily-bugle.media.mit.edu (Simson L. Garfinkel) (02/20/91)

I've just placed a tar file called NibEditor.tar.Z into pub/next/submissions on cs.orst.edu.  

NibEditor is a collection of two programs that you can use to rip apart NeXT applications, see how they are written, and put them back together.  It works with Interface Builder.

Here is the README file:

Welcome to the magic of Nib Editing...

One of the real problems with the NeXT is that you can't get the
source-code to the application programs.  Unfortunately, this can be a
real barrier to understanding how to write application programs in the
NeXT Step environment.

The NeXT computer uses a special object-file-format called Mach-O.
Basically, a Mach-o file consists of a number of segments and sections
within each segment.  One of these segments is the NIB segment, which
contains all of the NIBs that a program uses at run-time.  These nibs
are in the same format that Interface Builder uses.

By extracting a segment with the "segedit" command, you can see how an
application is built, which makes it a lot easier to build your own.
It partially gets around the problem that NeXT doesn't provide source-code.

The NIB Editor is a collection of two programs for seeing how NeXT
applications are built and modifying them.  The programs are:

extract <application>
        Takes an application, finds all of the NIBs in it, takes them
all out and puts them into *.nib files in the current directory.  Also
builds a file called NIBLIST, which is the list of all of the nibs.

combine <application> <new-application>
        Takes an application and NIBLIST, checks the mtime of each one
to see which ones that you've modified, and inserts each one into
<new-application>.  Repeats for each modified NIB.


Using these two programs, you can also modify an application.  For
example, you an change the text, much as you can with the Macintosh
Resource Editor. Another thing you can do is change menus, default
command-key bindings, or even connections.  If you want to get
advanced, you can add your own windows to an application, add
functionality, and do lots of other nifty things.

Enjoy!

                        2/20/91
                        Simson L. Garfinkel
                        simsong@mit.edu
daily-bugle.media.mit.edu> 

 

trivedi@motcid.UUCP (Kamlesh Trivedi) (02/20/91)

simsong@daily-bugle.media.mit.edu (Simson L. Garfinkel) writes:

>I've just placed a tar file called NibEditor.tar.Z into
pub/next/submissions on cs.orst.edu.
>NibEditor is a collection of two programs that you can use to rip
apart NeXT applications, see how they are written, and put them back together.  It works with Interface Builder.
>                        2/20/91
>                        Simson L. Garfinkel
>                        simsong@mit.edu

Thanks, Simson.  I tried out the extract portion so far and it works great!

Look at the number of .nib's in IB, WOW!

This little program that Simson has written is probably the best thing
that I have gotten from the archives and it's fantastically small, too (< 32K)!

The questions:

(1) Why do Chess and IB always have a connection back to the First Responder
rather than the object they are going to "MakeKeyAndOrderFront"? Because
code is easier to manipulate than connections in IB when changes are required?

(2) What is the NibDebug.nib in IB used for?  I know IB needs an
interactive debugger facility is this the start of one or is it some
panel that I haven't discovered yet?


Before a Lotus screams "rape and pillage" ;), Simson's tool is only good for
looking at .nib's, it doesn't give the code, you can unparse so
that you can create a stub, but it does not give code!

Simson, send me your USmail address and I'll send some money even
though you sent NibEditor out as a freeware --- I'm probably gonna
enjoy "peeping" w/ it too much.

-KamT-
-- 
Kamlesh Trivedi - My opinions not Motorola's - Reply to: uunet!motcid!trivedi

louie@sayshell.umd.edu (Louis A. Mamakos) (02/22/91)

The NIB extrator is really neat!  Not willing to leave well enough
alone, here's a version in Perl which a bit smaller on the disk
assuming, of course, that you already have Perl installed on your
machine as all right-thinking folks do!  It also extracts other
"interesting" parts of the NIB file including .tiff files, .snd files,
etc.  Enjoy!

My thanks to Simson for thinking up this wonderful idea..  My thanks to
Larry Wall for Perl, a wonderful tool for hacking up stuff like this.

louie

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	extract
#	combine
# This archive created: Fri Feb 22 00:37:28 1991
export PATH; PATH=/bin:$PATH
if test -f 'extract'
then
	echo shar: will not over-write existing file "'extract'"
else
sed 's/^X//' << \SHAR_EOF > 'extract'
X#!/usr/local/bin/perl -s
X#
X#  extract.pl	0.1
X#  Louis Mamakos <louie@Sayshell.UMD.EDU>
X#
X#  Quick and dirty hack.  Used to extract various interesting
X#  piece of NeXT .nib files for examination, modification and
X#  possible replacement.  Inspired by the pair of C programs
X#  written by simsong@daily-bugle.media.mit.edu (Simson L. Garfinkel),
X#  usage is pretty much the same.  This version also extracts stuff
X#  from the __TIFF, __ICON and __SND segments as well as the original
X#  doing the __NIB segment.
X#
X#  TODO:
X#  	- Need to be a bit more clever to fix up truncated names.  If part of
X#	  required extension is there, we should complete it rather than just
X#	  append the whole thing.
X#
X
X($prog = $ARGV[0]) || die "No arg specified,";
X
Xopen(OTOOL, "otool -l $prog |");
Xopen(FILES, ">NIBFILES");
X
X@NIBFILES = (); @TIFFFILES = (); @ICONFILES = (); @SNDFILES = ();
X
Xwhile(<OTOOL>) {
X	chop;
X	next unless /^Section$/;
X	$_ = <OTOOL>; chop;
X	next unless /^  sectname (.*)$/;
X	$sectname = $1;
X	$_ = <OTOOL>; chop;
X	/^   segname __NIB$/  && push(@NIBFILES, $sectname);
X	/^   segname __TIFF$/ && push(@TIFFFILES, $sectname);
X	/^   segname __ICON$/ && push(@ICONFILES, $sectname);
X	/^   segname __SND$/  && push(@SNDFILES, $sectname);
X}
Xclose(OTOOL);
X
Xformat FILES =
X@<<<<<<  @<<<<<<<<<<<<<<<<<<<  @<<<<<<<<<<<<<<<<<<<<<<<<<<<  @<<<<<<<<<<<<<<
X$type	   $sect	            $filename		$time
X.
X
X&nibsegment("__NIB",  ".nib",  @NIBFILES);
X&nibsegment("__TIFF", ".tiff", @TIFFFILES);
X&nibsegment("__ICON", ".icon.tiff", @ICONFILES);  # need to use a different extension for __ICON files
X&nibsegment("__SND",  ".snd",  @SNDFILES);
Xclose(FILES);
X
Xsub nibsegment {
X	@files = @_;
X	$type = shift(@files);
X	$ext = shift(@files);
X
X	foreach $sect (@files) {
X		$filename = $sect;
X		$filename .= $ext unless ($filename =~ m/$ext$/);
X			
X		if (-e $filename) {
X			print "$filename already exists; skipping...\n";
X			next;
X		}
X		print "Extracting $sect -> $filename\n";
X		print "segedit -extract $type $sect $filename $prog\n" if $debug;
X		#
X		#  Probably should extract multiple sections at a time...
X		#
X		system "segedit -extract $type $sect $filename $prog";
X		@a = stat($filename);
X		$time = $a[$[ + 9];
X		write FILES;
X	}
X}
X
X
X
SHAR_EOF
fi # end of overwriting check
if test -f 'combine'
then
	echo shar: will not over-write existing file "'combine'"
else
sed 's/^X//' << \SHAR_EOF > 'combine'
X#!/usr/local/bin/perl -s
X#  combine.pl	0.1
X#  Louis Mamakos  <louie@Sayshell.umd.edu>
X#
X#  quick and dirty hack, use with "extract" perl script.
X#  This version, unlike the C version, will replace all of the
X#  modified files in one fell swoop.  The thing to worry about here is
X#  if the command line grows too large; this is unlikely to be a
X#  real problem.  Hey, its just a quick hack..
X#
X($prog = $ARGV[0]) || die "No source program specified.\n";
X($new = $ARGV[1]) || die "No new program specified.\n";
X
Xopen(NIBFILES, "< NIBFILES");
X
X$command = '';
X
Xwhile(<NIBFILES>) {
X	($type, $nib, $file, $mtime) = split;
X
X	next if (! -e $file);
X	@a = stat($file);
X	$time = $a[$[ + 9];
X	if ($time > $mtime) {
X		$command .= " -replace $type $nib $file";
X		print
X          "File $file [sect name $nib seg name $type] has been modified\n";
X		print "New file is ", $time - $mtime,
X					" seconds newer\n" if $debug;
X	}
X}
Xclose(NIBFILES);
Xif ($command ne '') {
X	print "segedit $command $prog -output $new\n" if $debug;
X	system "segedit $command $prog -output $new";
X} else {
X	print "No modified files\n";
X}
X
X
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0