psp

Support for PSP games.

Includes ISO and UMD images, EBOOT decryption and signing, ELF expansion and string repacking, GIM/GMO images and PGF fonts.

hacktools.psp.extractIso(isofile, extractfolder, workfolder='', fixfilename=False)[source]

Extract an ISO with pycdlib.

Parameters:
  • isofile (str) – Path of the ISO file.

  • extractfolder (str) – Path of the folder to extract to.

  • workfolder (str) – Optional path of a work folder the extracted files are copied to.

  • fixfilename (bool) – Whether to strip the “;1” suffix from file names.

Return type:

None

hacktools.psp.repackIso(isofile, isopatch, workfolder, patchfile='', fixfilename=False, udf=False, ignorefiles=[])[source]

Repack an ISO with pycdlib, replacing the files found in a folder.

Files are modified in place, so each one needs to fit in its original sectors.

Parameters:
  • isofile (str) – Path of the original ISO file.

  • isopatch (str) – Path of the output ISO file.

  • workfolder (str) – Path of the folder with the replacement files.

  • patchfile (str) – Path of the xdelta patch to create, or empty to skip patch creation.

  • fixfilename (bool) – Whether to add back the “;1” suffix to file names.

  • udf (bool) – Whether the ISO has UDF entries.

  • ignorefiles (list) – Unused.

Return type:

None

class hacktools.psp.UMDFile[source]

A file in a UMD image, as found by searchUMD().

realname

Path of the file on disk.

filename

Path of the file in the image.

pos

Position of the directory record of the file.

lba

Sector of the directory record.

offset

Offset of the directory record within its sector.

oldsize

Original size of the file.

filelba

Sector of the file data.

hacktools.psp.repackUMD(umdfile, umdpatch, workfolder, patchfile='', sectorpadding=1)[source]

Repack a UMD image, replacing all the files in a folder.

Files are written back at their original sector when possible, and the directory records are updated with the new positions and sizes, so files can grow.

Parameters:
  • umdfile (str) – Path of the original UMD file.

  • umdpatch (str) – Path of the output UMD file.

  • workfolder (str) – Path of the folder with the replacement files.

  • patchfile (str) – Path of the xdelta patch to create, or empty to skip patch creation.

  • sectorpadding (int) – Number of sectors the file data is padded to.

Return type:

None

hacktools.psp.searchUMD(f, filename, path, lba, length)[source]

Search the directory records of a UMD image for a file.

Parameters:
  • f (Stream) – Stream opened on the UMD file.

  • filename (str) – Path of the file to search for.

  • path (str) – Path of the directory being searched, “” for the root.

  • lba (int) – Sector of the directory record.

  • length (int) – Length of the directory record.

Returns:

The position of the directory record of the file, or 0 if not found.

Return type:

int

class hacktools.psp.ELF[source]

Structure of an ELF executable.

sections

List of sections in the executable.

sectionsdict

Lookup dictionary from section name to section.

class hacktools.psp.ELFSection[source]

Structure of a single ELF section header.

name

Name of the section.

nameoff

Offset of the section name in the string table.

type

Type of the section.

flags

Flags of the section.

addr

Virtual address of the section.

offset

Offset of the section data in the file.

size

Size of the section.

Section index link.

info

Extra section information.

addralign

Alignment of the section.

entsize

Size of each entry, for sections that hold a table.

hacktools.psp.readELF(infile)[source]

Read the section headers of an ELF executable.

Parameters:

infile (str) – Path of the ELF file.

Returns:

The parsed ELF structure.

Return type:

ELF

hacktools.psp.expandELF(elfpath, n, fixheap=True)[source]

Insert a code cave of n bytes in a 32-bit ELF.

The cave is added at the end of the RWX PT_LOAD segment, fixing up all the headers so the file stays valid. When fixheap is set, MIPS references to _end used as the heap base are bumped past the cave, so the game’s first malloc/sbrk doesn’t land on top of it.

Parameters:
  • elfpath (str) – Path of the ELF file, modified in place.

  • n (int) – Number of bytes to insert.

  • fixheap (bool) – Whether to bump heap base references past the cave.

Returns:

The virtual address of the cave (the old segment _end), or 0 if the RWX PT_LOAD segment wasn’t found.

Return type:

int

hacktools.psp.extractBinaryStrings(elf, foundstrings, infile, func, encoding='shift_jis', elfsections=['.rodata'])[source]

Extract strings from sections of an ELF executable.

Parameters:
  • elf (ELF) – ELF structure returned by readELF().

  • foundstrings (list) – List of already known strings, new strings are added to it.

  • infile (str) – Path of the ELF file.

  • func – Function used to detect strings, called with (stream, encoding).

  • encoding (str) – Encoding passed to func.

  • elfsections (list) – Names of the sections to scan.

Returns:

The updated foundstrings list.

Return type:

list

hacktools.psp.repackBinaryStrings(elf, section, infile, outfile, readfunc, writefunc, encoding='shift_jis', elfsections=['.rodata'])[source]

Repack translated strings into sections of an ELF executable.

Translations are written in place, padded with zeros. Strings that don’t fit are logged and skipped.

Parameters:
  • elf (ELF) – ELF structure returned by readELF().

  • section (dict) – Dictionary of translations.

  • infile (str) – Path of the original ELF file.

  • outfile (str) – Path of the output ELF file, already copied from infile.

  • readfunc – Function used to detect strings, called with (stream, encoding).

  • writefunc – Function used to write strings, called with (stream, string, maxlen).

  • encoding (str) – Encoding passed to readfunc.

  • elfsections (list) – Names of the sections to scan.

Return type:

None

hacktools.psp.decryptBIN(ebinout, binout)[source]

Decrypt an EBOOT.BIN with pyeboot.

Parameters:
  • ebinout (str) – Path of the encrypted EBOOT.BIN file.

  • binout (str) – Path of the decrypted output file.

Return type:

None

hacktools.psp.signBIN(binout, ebinout, tag)[source]

Sign a BOOT.BIN into an EBOOT.BIN with pyeboot.

If pyeboot is not available, the file is copied as-is.

Parameters:
  • binout (str) – Path of the BOOT.BIN file.

  • ebinout (str) – Path of the output EBOOT.BIN file.

  • tag (int) – Tag to sign the file with.

Return type:

None

class hacktools.psp.GIM[source]

Structure of a GIM image file.

Format reference: https://www.psdevwiki.com/ps3/Graphic_Image_Map_(GIM)

rootoff

Offset of the root block.

rootsize

Size of the root block.

images

List of images in the file.

class hacktools.psp.GIMImage[source]

Structure of a single image in a GIM file.

picoff

Offset of the picture block.

picsize

Size of the picture block.

imgoff

Offset of the image block.

imgsize

Size of the image block.

imgframeoff

Offset of the image data, relative to the image block.

format

Format of the image data, an index for palette formats or a color format below 0x04.

bpp

Bits per pixel, derived from the format.

width

Width of the image.

height

Height of the image.

tiled

Whether the image data is tiled.

blockedwidth

Width rounded up to a multiple of the tile width.

blockedheight

Height rounded up to a multiple of the tile height.

tilewidth

Width of a single tile.

tileheight

Height of a single tile.

paloff

Offset of the palette block.

palsize

Size of the palette block.

palframeoff

Offset of the palette data, relative to the palette block.

palformat

Color format of the palette.

palette

Palette colors, as a list of RGBA tuples.

colors

Image data, a list of palette indexes or RGBA tuples depending on the format.

class hacktools.psp.TGAImage[source]

Structure of a TGA image, assumed to be 32bit RGBA.

rootoff

Offset of the image in the file.

format

Image type from the TGA header.

width

Width of the image.

height

Height of the image.

imgoff

Offset of the image data.

colors

Image data, as a list of RGBA tuples.

class hacktools.psp.GMO[source]

Structure of a GMO model file, only its textures are parsed.

size

Size of the file data.

names

List of texture names.

offsets

List of texture data offsets.

gims

List of GIM textures, parsed from the offsets.

hacktools.psp.readGMO(file)[source]

Read the texture names and GIM textures of a GMO model.

Parameters:

file (str) – Path of the GMO file.

Returns:

The parsed GMO structure.

Return type:

GMO

hacktools.psp.readGMOChunk(f, gmo, maxsize, nesting='')[source]

Read a single GMO chunk, recursing into nested ones.

Texture names and data offsets are added to the GMO structure.

Parameters:
  • f (Stream) – Stream opened on the GMO file.

  • gmo (GMO) – GMO structure to update.

  • maxsize (int) – Position the chunks end at.

  • nesting (str) – Prefix used to indent the debug logs.

Return type:

None

hacktools.psp.readGIM(file, start=0)[source]

Read a GIM image, or a TGA image if the MIG magic is not found.

Parameters:
  • file (str) – Path of the image file.

  • start (int) – Offset of the image in the file.

Returns:

The parsed GIM or TGAImage structure, or None if a GIM block has an unexpected id.

hacktools.psp.readGIMBlock(f, gim, image)[source]

Read a single GIM block from the current stream position.

Picture blocks add a new image to the GIM structure, while image and palette blocks fill the current one. Unknown blocks are skipped.

Parameters:
  • f (Stream) – Stream opened on the GIM file.

  • gim (GIM) – GIM structure to update.

  • image (GIMImage) – Image being filled, None before the first picture block.

Returns:

A (nextblock, image) tuple with the offset of the next block and the image being filled.

hacktools.psp.writeGIM(file, gim, infile, backwardspal=False)[source]

Write a png image back into a GIM or TGA file.

The images are read from the png stacked vertically, in the same layout drawn by drawGIM().

Parameters:
  • file (str) – Path of the image file to update.

  • gimGIM or TGAImage structure returned by readGIM().

  • infile (str) – Path of the png file to pack.

  • backwardspal (bool) – Whether to search the palettes backwards when matching colors.

Return type:

None

hacktools.psp.writeGIMPixel(f, image, color, backwards=False)[source]

Write a single pixel of a GIM image.

For palette formats, the index of the closest palette color is written.

Parameters:
  • f (Stream) – Stream to write to.

  • image (GIMImage) – Image the pixel belongs to.

  • color – RGBA tuple, or None to write index 0 or a transparent pixel.

  • backwards (bool) – Whether to search the palette backwards.

Return type:

None

hacktools.psp.readColor(f, format)[source]

Read a color in the given GIM color format.

Parameters:
  • f (Stream) – Stream to read from.

  • format (int) – Color format, 0x00 (RGBA5650), 0x01 (RGBA5551), 0x02 (RGBA4444) or 0x03 (RGBA8888).

Returns:

The color as an RGBA tuple.

Return type:

tuple

hacktools.psp.writeColor(f, format, color)[source]

Write a color in the given GIM color format.

Parameters:
  • f (Stream) – Stream to write to.

  • format (int) – Color format, 0x00 (RGBA5650), 0x01 (RGBA5551), 0x02 (RGBA4444) or 0x03 (RGBA8888).

  • color (tuple) – Color to write, as an RGBA tuple.

Return type:

None

hacktools.psp.drawGIM(outfile, gim)[source]

Draw a GIM or TGA image to a png file.

GIM images are stacked vertically, with their palettes drawn on the right side.

Parameters:
Return type:

None

hacktools.psp.drawGIMPixel(image, pixels, x, y, i)[source]

Draw a single pixel of a GIM image.

Parameters:
  • image (GIMImage) – Image the pixel belongs to.

  • pixels – PIL pixel access object to draw on.

  • x (int) – X position to draw at.

  • y (int) – Y position to draw at.

  • i (int) – Index of the pixel in the image data.

Return type:

None

class hacktools.psp.PGF[source]

Structure of a PGF font.

Format reference: https://github.com/tpunix/pgftool/blob/master/pgf.h

headerlen

Length of the header.

charmaplen

Number of charmap entries.

charptrlen

Number of charptr entries.

charmapbpe

Bits per entry of the charmap table.

charptrbpe

Bits per entry of the charptr table.

charmapmin

First UCS code in the charmap.

charmapmax

Last UCS code in the charmap.

charptrscale

Scale applied to the charptr values.

dimensionlen

Number of entries in the dimension map.

bearingxlen

Number of entries in the horizontal bearing map.

bearingylen

Number of entries in the vertical bearing map.

advancelen

Number of entries in the advance map.

shadowmaplen

Number of entries in the shadowmap table.

shadowmapbpe

Bits per entry of the shadowmap table.

dimensionmap

List of {“x”, “y”} glyph dimensions.

bearingxmap

List of {“x”, “y”} horizontal bearings.

bearingymap

List of {“x”, “y”} vertical bearings.

advancemap

List of {“x”, “y”} advances.

shadowmap

UCS codes of the glyphs with a shadow.

charmap

Charmap table, mapping UCS codes to glyph pointers.

charptr

Charptr table, holding the offset of each glyph.

mapend

Offset of the end of the maps.

glyphpos

Offset of the glyph data.

ucslist

List of the UCS codes to load.

glyphs

List of glyphs in the font.

reversetable

Lookup dictionary from character to glyph indexes.

ptr2ucs(ptr)[source]

Convert a glyph pointer index to its UCS code.

Parameters:

ptr (int) – Glyph pointer index.

Returns:

The UCS code, or 0xffff if not found.

Return type:

int

class hacktools.psp.PGFGlyph[source]

Structure of a single glyph in a PGF font.

index

Index of the glyph.

ucs

UCS code of the glyph.

char

Character the glyph represents.

size

Size of the glyph data.

oldsize

Original size of the glyph data, before repacking.

width

Width of the bitmap.

height

Height of the bitmap.

left

Left offset of the bitmap.

top

Top offset of the bitmap.

flag

Glyph flags, holding the RLE order and which values use maps.

totlen

Length in bits of the glyph header.

shadow

Whether the glyph has a shadow.

shadowflag

Shadow flags.

shadowid

Index in the shadowmap table.

dimensionid

Index in the dimension map, or -1 for an inline value.

bearingxid

Index in the horizontal bearing map, or -1 for an inline value.

bearingyid

Index in the vertical bearing map, or -1 for an inline value.

advanceid

Index in the advance map, or -1 for an inline value.

dimension

Dimension of the glyph, as a {“x”, “y”} dictionary.

bearingx

Horizontal bearing, as a {“x”, “y”} dictionary.

bearingy

Vertical bearing, as a {“x”, “y”} dictionary.

advance

Advance, as a {“x”, “y”} dictionary.

bitmap

RLE encoded bitmap data, filled when repacking.

hacktools.psp.getBPEValue(bpe, buf, pos, float=False)[source]

Read a bit-packed value from a buffer.

Parameters:
  • bpe (int) – Number of bits to read.

  • buf (bytes) – Buffer to read from.

  • pos (int) – Bit position to read at.

  • float (bool) – Whether the value is a 26.6 fixed point number, converted to float.

Returns:

A (value, position) tuple with the new bit position.

hacktools.psp.readBPETable(f, num, bpe)[source]

Read a table of bit-packed values.

Parameters:
  • f (Stream) – Stream to read from.

  • num (int) – Number of values to read.

  • bpe (int) – Bits per entry.

Returns:

The list of values.

Return type:

list

hacktools.psp.setBPEValue(bpe, buf, pos, data, float=False)[source]

Write a bit-packed value in a buffer.

Parameters:
  • bpe (int) – Number of bits to write.

  • buf (bytearray) – Buffer to write to.

  • pos (int) – Bit position to write at.

  • data – Value to write.

  • float (bool) – Whether the value is a float, converted to 26.6 fixed point.

Returns:

The new bit position.

Return type:

int

hacktools.psp.setBPETable(f, num, bpe, table)[source]

Write a table of bit-packed values.

Parameters:
  • f (Stream) – Stream to write to.

  • num (int) – Number of values in the table.

  • bpe (int) – Bits per entry.

  • table (list) – List of values to write.

Return type:

None

hacktools.psp.readPGFData(file)[source]

Read the header, maps and glyphs of a PGF font.

Based on https://github.com/tpunix/pgftool/blob/master/libpgf.c

Parameters:

file (str) – Path of the PGF file.

Returns:

The parsed font structure.

Return type:

PGF

hacktools.psp.fontpalette = [(0, 0, 0, 255), (31, 31, 31, 255), (47, 47, 47, 255), (63, 63, 63, 255), (79, 79, 79, 255), (95, 95, 95, 255), (111, 111, 111, 255), (127, 127, 127, 255), (143, 143, 143, 255), (159, 159, 159, 255), (175, 175, 175, 255), (191, 191, 191, 255), (207, 207, 207, 255), (223, 223, 223, 255), (239, 239, 239, 255), (255, 255, 255, 255)]

Grayscale palette used for the 4-bit glyph bitmaps.

hacktools.psp.extractPGFBitmap(buf, glyph, outfile)[source]

Decode the RLE bitmap of a glyph and draw it to a png file.

Parameters:
  • buf (bytes) – Buffer holding the encoded bitmap.

  • glyph (PGFGlyph) – Glyph the bitmap belongs to.

  • outfile (str) – Path of the png file to create.

Return type:

None

hacktools.psp.bitmapRLE(pixels)[source]

Encode glyph pixel indexes with the PGF RLE scheme.

Parameters:

pixels (list) – List of palette indexes to encode.

Returns:

The encoded data.

Return type:

bytearray

hacktools.psp.repackPGFBitmap(glyph, infile)[source]

Encode a png glyph bitmap with the PGF RLE scheme.

The bitmap is encoded both in horizontal and vertical order, keeping the smaller of the two.

Parameters:
  • glyph (PGFGlyph) – Glyph the bitmap belongs to.

  • infile (str) – Path of the png file to encode.

Returns:

A (data, rleflag, width, height) tuple with the encoded data, the flag holding the chosen order, and the bitmap size.

hacktools.psp.extractPGFData(file, outfile, bitmapout='', justadvance=False)[source]

Extract the glyph data of a PGF font to a text file.

Each line has the char=json format, with “=” characters written as <3D>, or char=advance when justadvance is set.

Parameters:
  • file (str) – Path of the PGF file.

  • outfile (str) – Path of the output text file.

  • bitmapout (str) – Folder to extract the glyph bitmaps to as numbered png files, or empty to skip them.

  • justadvance (bool) – Whether to only write the x advance of each glyph, instead of the full json data.

Return type:

None

hacktools.psp.checkPGFDataMap(datamap, newvalue)[source]

Get the index of a value in a PGF map, adding it if missing.

Parameters:
  • datamap (list) – Map to search, a list of {“x”, “y”} dictionaries.

  • newvalue (dict) – Value to search for, as a {“x”, “y”} dictionary.

Returns:

The index of the value, or -1 if it’s missing and the map is full.

Return type:

int

hacktools.psp.repackPGFData(fontin, fontout, configfile, bitmapin='')[source]

Repack glyph data and bitmaps into a PGF font.

The glyph information is read from a config file in the format written by extractPGFData(), and the bitmaps from numbered png files when they exist.

Parameters:
  • fontin (str) – Path of the original PGF file.

  • fontout (str) – Path of the output PGF file.

  • configfile (str) – Path of the config file.

  • bitmapin (str) – Folder with the glyph bitmaps, or empty to keep the original ones.

Return type:

None

hacktools.psp.mpstopmf(infile, outfile, duration)[source]

Convert a MPS video to PMF, prepending the PSMF header.

Based on https://github.com/TeamPBCN/pmftools/blob/main/mps2pmf/mps2pmf.cpp

Parameters:
  • infile (str) – Path of the MPS file.

  • outfile (str) – Path of the output PMF file.

  • duration (int) – Duration of the video.

Return type:

None