Jump to content
IGNORED

Porting the original Atari Jaguar SDK to ELF


boricj

Recommended Posts

Hi all,

 

I'm tinkering with a reverse-engineering technique called unlinking*, which can turn (parts of) programs back into object files. I needed a straightforward, proprietary, text-only, statically-linked, non-PIC/PIE, reasonably-sized program with preferably at least one person who cares about it to use as one of my case studies, at which point I remembered this post on LKML.

 

Long story short, I've unlinked aln from the original Atari Jaguar SDK (taken from here), an a.out i386 static executable for Linux, and turned it into an ELF i386 object file (without its embedded C standard library bits). I've provided a dynamically-linked Linux ELF i386 executable with glibc 2.31 as a proof-of-concept which seems to work, but using a period-correct C standard library or an ABI-compatible drop-in replacement would certainly help with the rather antiquated ABI expectations of aln.

 

Now, while I can run `CC=i686-linux-gnu-gcc make && ./aln.elf -v -z -?` and see that it doesn't crash on my system, I'm not an Atari Jaguar homebrew developer so I can't actually give it a good shakedown. There are many ways this unlinking/relinking process can go wrong so I'd be grateful if anyone here gives it a try, including linking aln.o yourself on your own system. Consider this an alpha-quality preview.

 

On a side-note, this is a side-quest for me because I just wanted to write an article on my blog about one application of this unlinking technique (well, originally I wanted to decompile a Playstation 1 video game and got severely side-tracked in the past 16 months or so...). I do want a working case study for my article so I'll try and fix any issues in that object file that are attributable to this unlinking process, but I have yet to decide if I'll do any other executable from the original Atari Jaguar SDK. For reference, it took me about a day of reverse-engineering work with Ghidra to get this object file with my tooling (the tooling itself took about 16 months and three incarnations to industrialize it).

 

*I'm not sure how it's actually called given how few resources there are online about it, but I'm pretty sure I didn't invent it.

atari-sdk-elf.tgz

Edited by boricj
  • Like 4
Link to comment
Share on other sites

Very cool! I'll test it out on some real input files later, and I'll definitely be reading through your blog!

 

Converting mac (MADMAC) would be a lot more useful in the long run. ALN is a pretty simple program and is largely interchangeable with RLN these days, but MADMAC is still worth using, if only as a comparison tool to help find and characterize bugs and behavior differences between it and RMAC (modern replacement).

  • Like 1
Link to comment
Share on other sites

19 hours ago, cubanismo said:

Converting mac (MADMAC) would be a lot more useful in the long run. ALN is a pretty simple program and is largely interchangeable with RLN these days, but MADMAC is still worth using, if only as a comparison tool to help find and characterize bugs and behavior differences between it and RMAC (modern replacement).

I'll try and look into it this week-end. No promises though.

Link to comment
Share on other sites

On 8/29/2023 at 7:23 PM, boricj said:

I'll try and look into it this week-end. No promises though.

Well, I tried and I've found multiple cases of unrecognized i386 relocation patterns (that's on me) and multiple cases of undetected/misdetected references by Ghidra. Each case led to memory references to the old executable address space, which makes the program segfaults (the relinked executables have a far higher base address). Given what I've seen, I am not convinced that the aln.o object file I've provided is correctly and completely unlinked, it only takes one bad/missing relocation for a bug or a crash to occur in one code path.

 

I've mostly used my tooling on MIPS executables before and never on something of this scale (hundreds of kilobytes being unlinked in one go), so I'm hitting a lot of corner cases I haven't encountered yet. I'll have to beef up my x86 relocation analyzer and significantly improve my integration test suite to deal with this. This is going to take some time before I can take a crack at aln and mac again.

Edited by boricj
  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

Well, it took some time, but there has been some developments.

 

First, I've determined that Slackware 2.3's C static library is a very close match to the aln, mac and AGPU's cc1 executables. This means that most if not all of the original Atari Jaguar SDK Linux binaries were either built on Slackware 2.3 or something very close. I've managed to produce libc.o, an a.out object file that combines every object file from Slackware 2.3's libc.a. It can then be loaded into Ghidra [1], whose Version Tracking tool can then basically match and apply every symbol from libc.o to those old Linux executables.

 

For aln, that's almost half of the executable figured out "for free". I expect that this will be of great help to any reverse-engineering projects on these old executables.

 

Then, I've made tons of improvements to my delinker tooling and tried delinking aln again. This time, aln is relinked whole as an ELF executable as a proof-of-concept. I've beefed up the reference sanity checks so I'm more confident this time it'll work, but Ghidra's analyzers aren't perfect so there could still be some missing or incorrect relocations in there. Anyways, running "./aln.elf -z -v -w -d" doesn't crash on my end, but I'll let actual Atari Jaguar homebrew developers give it a fair shakedown.

 

Overall, I think the delinker [2] should be mature enough now to be usable in practice on the rest of the original Atari Jaguar Linux toolchain. It can be used to relink as ELF executables as shown here, but also to make patches by replacing pieces or even as part of a decompilation projects by splitting an executable into many object files and reimplementing them one at a time...

 

Now, aln made for a decent test case for bootstrapping an x86 relocation synthesizer, but I'm not part of the Atari Jaguar community. That means I'm not going to delink or otherwise mess with the other executables myself, that's a job for someone who has an interest in doing so. I am willing however to answer questions about the delinking process and to fix issues/make improvements on my tooling if anybody wants to take a crack at it.

 

[1] With these modifications: https://github.com/colinbourassa/ghidra/pull/2

[2] v0.2.0 freshly released: https://github.com/boricj/ghidra-delinker-extension/releases/tag/v0.2.0

atari-sdk-elf.tgz libc.o

  • Like 3
Link to comment
Share on other sites

  • 3 months later...
Posted (edited)

It took way too long, but I'm finally done with this stuff:

  • aln.elf: the original Linux a.out aln repackaged whole as a Linux i386 ELF executable and rebased at address 0x08048000 (no need to "sysctl -w vm.mmap_min_addr=4096" anymore) ;
  • aln.static.elf: aln statically linked with glibc 2.xx ;
  • aln.dynamic.elf: aln dynamically linked with glibc 2.xx ;
  • aln.exe: a native Windows port of aln (yes, this is a real i386 PE executable, it's not the MS-DOS version).

This time, I've tested them with the jaghello sample and confirmed that all versions can reproduce byte-for-byte jaghello.cof, so unless I missed something these are all functionally identical to the original Linux a.out version:

 

$ aln.dynamic.elf -e -l -g2 -rd -a 4000 x x -v -o jaghello.cof startup.o jag.o
***********************************
*   ATARI LINKER (Mar 17 1995)    *
*  Adds from Atari version 1.11   *
*     and PC/DOS&Linux ports      *
*  Copyright 1993-95 Brainstorm.  *
** Copyright 1987-95 Atari Corp. **
***********************************
Output file is jaghello.cof

Sizes:   Text   Data    Bss   Syms
(hex)     3C0    410   FA54   1C00

Link complete.

 

Not only that, but I have documented the full process over at my blog, if anyone wants to take a crack at the rest of the original Atari Jaguar SDK programs. The delinking process enables both piecewise decompilation and making software ports, depending on what you want to achieve. I do recommend starting with repackaging from a.out to ELF first, which will weed out most of the potential issues upfront without introducing ABI incompatibilities into the mix.

 

The files in this post are stripped versions of the ones in the case study archive linked in the blog posts, which contains everything required for building them (including the Ghidra project archive for aln, so anyone should be able to reproduce my results with aln at home).

 

That concludes this proof-of-concept on my part as I've done what I set out to do: prove that this approach works and document it. I'm not going to work on the rest of the original Atari Jaguar SDK since I'm not an Atari Jaguar developer, aln just happened to be a convenient case study for my delinking experiments. I am however willing to answer questions and look over the shoulder of anyone who wants to take a stab at it.

aln.elf aln.static.elf aln.dynamic.elf aln.exe

Edited by boricj
fix link
  • Like 6
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...