6

I have a C64 program in a .t64 file. If I load it into an emulator, what I see is that it loads into a cracktro, which then proceeds to uncompress (taking several seconds at 100% speed) the original program. The program proper doesn't do any further tape or disk IO, so basically if I dump the RAM from the emulator after uncompression, that 64 Kb image contains everything.

I'd like to reconstruct an uncompressed loader, for the purposes of easy editing. So I'd like a way to start either from the compressed .t64 file or the full RAM dump, and transform it into a format (.prg I guess?) that I can then take apart, change, put back together, etc, and the result should be something I can put on tape or a disk and load it on a C64.

Are there any established uncompressers for C64 images? Is there any way to start with this that is easier than straight-up reverse-engineering the cracktro's uncompression routine?

  • 5
    No need to reverse-engineer it in full -- just find its end (return from the depacker and passing control to the original code) and put a breakpoint there. – lvd Sep 21 '20 at 17:41
  • @lvd OK, I think I have managed to put a breakpoint there. But now what? I can now take the full 64K dump again, and I now know where the starting address is -- but that still doesn't give me something I could reload from disk/tape. – Cactus Sep 22 '20 at 10:48
  • OK I have now found out that Vice's memory dumps can actually directly be put into a .d64 file. So the remaining question is -- how do I find out where the stuff I should save starts and ends? – Cactus Sep 22 '20 at 11:15
3

With Vice, you can wait until the uncompressed, actual, application code has started execution, then activate the built-in ML Monitor. You will thus pause execution at wherever the Program Counter happens to be, most likely waiting for the first user input to the application.

  1. Dump the stack to see the history of any subroutines that have been invoked. Going back up the stack should lead you to a code location very near the actual start of the code.
  2. Examine memory above and below this location, using the disassembler. Look for blocks of continuous discernible assembly code. You need to find the starting address that was jumped to after decompression, and there will most likely be a "gap" in the code before this address. This becomes the likely start address for the actual code.
  3. Examine memory in the opposite direction again using the disassembler. You should see discernible assembly code. There might be small gaps, but any large gap likely signifies the end of the code OR, MAYBE, it's a SID score, or a bunch of graphical tile data, depending on what this app actually IS.
  4. Prepend a two-byte header before the start of the code with your loading address, then save the whole range including header to a PRG file. This should be loadable in the emulator or on a real C64.

If you want to make multiple attempts at this without starting over, use the Vice snapshot feature to store the whole of the memory state. You can thus reload it and try again if you identified the wrong start/end of the code before. It would be highly unlikely, though possible, that there are many chunks of disjointed code and/or pre-initialized data. Such a memory map (if it ever existed) for the program should have been cleaned up before applying the compression, in order to simplify the decompression process.

  • "1" -- if the stack was not moved across the memory. "2-4" -- there is not only 'assembly code' around, there might be also graphics, music, different data structures. Still, stopping during decompression is a more viable option. Additionally, one can dig how many blocks are depacked and where to -- to give clues which memory to store in a snapshot. – lvd Sep 22 '20 at 16:50
  • @lvd You're right, of course. But it's hard to guess about the nature of data included in the binary while knowing nothing about the app that is being investigated. A possible added (generic) step is to run a sophisticated disassembler tool outside Vice that flags recognizable data blocks, right? – Brian H Sep 22 '20 at 18:35
  • Disassembler can of course find many (not all) code blocks, but most probably it will fail to find most arrays of data basing solely on statical analysis. I feel like, just, repeat what depacker does, including filling of memory areas before (or after) depacking but before starting the original program. Just don't pack memory areas the depacker depacks, put them in your snapshot as-is. – lvd Sep 22 '20 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.