KELFTOOL -FMCB COMPATIBLE FORK-

PS2 KELFTOOL -FMCB COMPATIBLE FORK- 1.00

alexparrado

Developer
This kelftool release can create KELF files, which are compatible with FMCB 1.9 series installer, Windows and Linux binaries are provided. Generated KELF files can be properly signed by secrman_special through SECRSIF.

In addition, newer version allows creation of MBR KELF files which are bootable from __mbr. To achieve this, source must be a raw binary (headerless) created from an ELF with load address 0x100000.

To encrypt do the following:

(Linux) ./kelftool.elf encrypt fmcb your.elf your.kelf
(Windows) kelftool.exe encrypt fmcb your.elf your.kelf

To create MBR KELF file do the following:

(Linux) ./kelftool.elf encrypt mbr yourbinary yourMBR.kelf
(Windows) kelftool.exe encrypt mbr yourbinary yourMBR.kelf



Fork source code available at: https://github.com/parrado/kelftool
 
Does it means that also output KELFs can be successfully launched from APA "headers" ("__mbr" and "PP")?

I'm asking because this one is for only DESR KELFs:
https://www.psx-place.com/threads/kelftool-gui.31630/

This release uses same headers from FMCB.XLF (fmcb flag) and FHDB.XLF (fhdb flag). Output KELFs using any of two headers are correctly signed by FMCB Installer (SecrDownloadFile from libsecr) and launched as osdsys update from MC of PS2. I've not tested anything beyond that.
 
Last edited:
If PS2 boots those KELFs from "__mbr", it will also from "PP." (they are the same if I'm not wrong).

Thanks. ^^

Nice. Keep in mind that source ELFs must load from 0x100000 address. In my case I use an old SDK along with -nostartfiles linker flag. Then, a raw binary is generated by ee-objcopy and used as source for kelftool.
 
Last edited:
Yeah, I know. So I tested only uLE kHn because he releasing also XLF (kelf) and even tiny partition image to not tinkering with himself of address fixes in hex editor and apa "header" re-checksumming. At least in this case, this file boots from __mbr, APA (internal in system.cnf) and PFS (external in system.cnf). That's why assuming they are the same.

What is strange, readelf shows me two loading addresses. Is that normal? One is 0x10000 and another far above.
 
In my case readelf -h shows 0x100008. Nevertheless, .text section starts from 0x100000. Thus, load address shown by readelf -h can have a value a few words away from 0x100000.
 
Last edited:
That's why assuming they are the same.

What is strange, readelf shows me two loading addresses. Is that normal? One is 0x10000 and another far above.
Yes, they're the same. It's just that the MBR KELF file is zero-padded in between the two segments, as the HDD_Loader module basically loads the entire data to 0x00100000 with no ELF header.
The other KELF (BOOT.XLF) is the same thing but with a ELF header, that allows to load the segment "separately". No padding.
Segment 1 is the unpacker stub, loads at 0x00100000, entrypoint at 0x00100008 (HDD_Loader execs at 0x00100000)
Segment 2 is packed data, loads at 0x00100740
 
Yes, they're the same. It's just that the MBR KELF file is zero-padded in between the two segments, as the HDD_Loader module basically loads the entire data to 0x00100000 with no ELF header.
The other KELF (BOOT.XLF) is the same thing but with a ELF header, that allows to load the segment "separately". No padding.
Segment 1 is the unpacker stub, loads at 0x00100000, entrypoint at 0x00100008 (HDD_Loader execs at 0x00100000)
Segment 2 is packed data, loads at 0x00100740

BTW, is there any chance @sp193 super packer can be shared?
 
  • Like
Reactions: TnA
Would be awesome to have such packer as would allow anyone for very easy XLF creation from any ELF (decompressing packed ELFs and packed by such special packer). So I'm joining to polite request of releasing it. ^^
 
Would You kindly tell us how to determine the header length? Readelf tells me that attached file started from 0x52, so I cut it and sign using "mbr" parram, but HDD OSD doesn't launch it, which means that I wrongly determine it. Tried also with first 48 bytes cut off (as I saw You did the same with OPL-Launcher R3, so I blindly without understanding repeat the steps ;p) and it also doesn't work.

However, file signing using SCEDoormat application works from "PP partition" - it contains wider XLF header and keeps also ELF header. Could You then add to Yours kelftool fork additional parram (pp?) which signing the same way but accept executables with ELF header; or maybe add possibility to automatically detect header length and cut it out automatically? @krHACKen said that "PP XLF" can have ELF header which attached file proofs true (it works, it is OPL-Launcher pre-release version) and only "MBR XLF" cannot (so maybe such additionally parram have sense).

Sorry to bother You.
 

Attachments

  • Like
Reactions: TnA
Would You kindly tell us how to determine the header length? Readelf tells me that attached file started from 0x52, so I cut it and sign using "mbr" parram, but HDD OSD doesn't launch it, which means that I wrongly determine it. Tried also with first 48 bytes cut off (as I saw You did the same with OPL-Launcher R3, so I blindly without understanding repeat the steps ;p) and it also doesn't work
I don't manually cut-off headers from ELF. Instead, I use objcopy command to get the raw binary, that's the approach I use in SoftDev2. And as you pointed out, it's only necessary for MBR. For OPL-Launcher, ELF header has to be kept, cause ELF is loaded in the regular way.

Could You then add to Yours kelftool fork additional parram (pp?) which signing the same way but accept executables with ELF header; or maybe add possibility to automatically detect header length and cut it out automatically?
I don't think that's a required feature, It'll turn kelftool unnecessarily complex, cause kelftool can encrypt any file, it doesn't care about contents, flags only affect user header. In fact, after having a talk with Balika (kelftool and mechapwn author), he claimed those user headers are useless, I need to go deeper on that lol.

In conclusion, you can always get a headerless ELF with objcopy and then encrypt it with kelftool. For all remaining tasks (OSDSYS updates, PP XLFs) use regular ELF files.

Sorry to bother You.
It's ok mate.
 
Last edited:
You have in mind standard Linux binutil? But with which switches?
https://linux.die.net/man/1/objcopy

Is this correct?
Code:
objcopy -O full.elf castrate.elf

For all remaining tasks (OSDSYS updates, PP XLFs) use regular ELF files.
Tried but when I feed kelftool by OPL-Launcher.elf without cutting anything, it crashes. So that's I assumed it checking header.
 
It doesn't (win32 version at least), I don't remember what it prints so when I go back to home, I'll check and add another comment.

So if I understand correctly, it should be sufficient to "PP partition" just encrypting whole "compatible elf" with "mbr" parram and should works?
 
New version up.
Fixed some memory leaks.
Added support for PS2KEYS.dat placed in the working directory instead of HOME.
Fixed macOS build.
The app will print Kelf file configuration in detail. Known bit flags will be explained.
Now you can differ fhdb, fmcb, mbr generated kelf by opening files in hex view.
Encryption now uses 1 RAW block for speeding up kelf processing on real consoles.
More generic encryption (still not fully implemented for byte-perfect encryption).
Code:
build/kelftool decrypt build/FHDB.XLF build/FHDB.ELF
header.UserDefined     = 01 00 00 04 00 02 00 4A 00 08 01 00 00 00 00 1B (FHDB)
header.ContentSize     = 0X1F1B0
header.HeaderSize      = 0X80
header.SystemType      = 0 (SYSTEM_TYPE_PS2)
header.ApplicationType = 1 (xosdmain)
header.Flags           = 0X22C - kelf:HDR_FLAG2|HDR_FLAG3|HDR_FLAG4_3DES|HDR_FLAG9|
header.BitCount        = 0
header.MGZones         = 0XFF |All regions allowed|
header.gap             = 00 00 00
HeaderSignature        = 6E 81 AC 1C B9 11 C7 B7
Kbit                   = BB F3 9C 3B 4F 16 E5 96 D2 32 0E 71 43 E8 82 87
Kc                     = D2 C5 75 FD 86 31 6A 29 2D 08 B9 08 4D 15 B5 08
BitTableSize           = 0X28
bitTable.HeaderSize    = 0X80
bitTable.BlockCount    = 2
bitTable.gap           = 00 00 00
                         Size        Signature           Flags
    bitTable.Blocks[0] = 00000020    517193D4C6B693EA    3 (encrypted and signed)
    bitTable.Blocks[1] = 0001F190    0000000000000000    0 (not encrypted, not signed)
 

Similar threads

Back
Top