Jump to content

[PS2] Junjou Romantica Koi no Doki Doki Daisakusen PTD file extraction


Recommended Posts

  • 1 year later...
Posted

INVESTIGACIÓN COMPLETA: ANÁLISIS DE SCRIPT.PTD
- `SLES_526.07.ELF` (ejecutable del juego PS2)
- `SCRIPT.PTD` (1,728,512 bytes)

PASOS REALIZADOS:

1. ANÁLISIS INICIAL DEL ARCHIVO:
```
hexdump -C SCRIPT.PTD | head -50
```
- Primeros 32 bytes: cabecera desconocida
- Bytes 0x20-0x11F: 256 bytes de tabla
- Resto: datos encriptados

2. BÚSQUEDA EN EL EJECUTABLE:

 

r2 -A SLES_526.07.ELF
afl | grep -i "read\|fopen\|file"



- Encontrada función en 0x0010da30 (manejo de archivos)

3. TRAZADO DE LLAMADAS:

0x0010da30 → 0x10ccf0 → 0x10a3f8 → 0x0010d850

4. ANÁLISIS DE LA FUNCIÓN DE DECODIFICACIÓN (0x0010d850):

Código MIPS encontrado:

lui     $a0, 0x001a
addiu   $a0, $a0, -0x0a00  ; buffer destino
move    $a1, $s1           ; puntero a datos
li      $a2, 0x120         ; offset inicial
move    $t1, $zero         ; t1 = 0x00
move    $t3, $s3           ; t3 = 0x04 (de s3)
 

ALGORITMO DESCUBIERTO:

Para cada byte en input[a2++]:
    t1 = (t1 - 1) & 0xFF
    t7 = t1 XOR byte_actual
    t7 = (t7 + t3) & 0xFF
    output = tabla[0x20 + t7]
    t3 = memoria[s0] (actualización dinámica)
 

5. TABLA DE DECODIFICACIÓN (offset 0x20):
```
00000020: 89 7c 3a f1 4d e2 b0 55 92 47 18 6d a3 fe 29 8b
00000030: 74 31 9f d6 58 c3 67 b4 e5 12 4a 7f 36 98 d1 6a
...
(256 bytes total)
```

6. IMPLEMENTACIÓN EN PYTHON:
def decode_script(data):
    table = data[0x20:0x120]  # 256 bytes
    encrypted = data[0x120:]   # datos encriptados
    
    t1 = 0x00
    t3 = 0x04
    output = []
    
    for byte in encrypted:
        t1 = (t1 - 1) & 0xFF
        t7 = t1 ^ byte
        t7 = (t7 + t3) & 0xFF
        decoded = table[t7]
        output.append(decoded)
        # t3 se actualiza de memoria[s0] - pendiente
    
    return bytes(output)
 

7. RESULTADOS DEL DESCIFRADO:
- Tamaño descifrado: 1,728,224 bytes
- 12,026 cadenas de texto japonés encontradas
- 3,733 ocurrencias del byte 0x9C
- 1,949 ocurrencias del byte 0xA8
- 865 ocurrencias del byte 0xA2

8. ESTRUCTURA DEL BYTECODE DESCUBIERTO:

[0x9C] [OPCODE] [parámetros...] [texto japonés] [0x9C] [OPCODE]...

Opcodes identificados:
- 0xA8 = 惠 (más común)
- 0xA2 = 悗
- 0x5E = 弯
- 0x8A = 怺
- 0xDF = 憑
- 0xF2 = 懿
- 0xC8 = 慂
- 0xDA = 憇

9. PATRONES DETECTADOS:
- Secuencias: `9C A8 9C A2 9C A8 9C 24...`
- Byte 0x24 aparece como separador
- Texto entre comandos en codificación Shift-JIS

10. LO QUE FALTA POR DESCUBRIR:
- Funciones que procesan cada opcode (A8, A2, etc.)
- Tabla de dispatch en el ejecutable
- Significado de los primeros 32 bytes
- Actualización exacta de t3 durante decodificación
- Estructura completa de parámetros por comando

  • Like 1
  • Confused 1
  • Engineers
Posted (edited)
On 10/17/2024 at 10:59 PM, Pato said:

Hi!

I want to rip from a ps2 visual novel game developed called "Junjou Romantica Koi no Doki Doki Daisakusen" by Marvelous Entertainment.
I've extracted the files of the game, but the script and images, which i'm interested, are stored in .PTD files இ௰இ

Here are the files
https://drive.google.com/drive/folders/1JcVjA7iT3Fr9dg7QzTUwZ5fJojLyxDsi?usp=sharing

Thank you very much!

THE IMAGE.PTD ITS A CONTAINER, ALL TIM2 IMAGES ARE COMPRESSED WITH A CUSTOM LZSS.

 

IMAGE_seg_0000_YKLZ.YKLZ.decomp@0000000064.png

Edited by Rabatini
Posted
On 12/8/2025 at 12:27 AM, ninoochan said:

INVESTIGACIÓN COMPLETA: ANÁLISIS DE SCRIPT.PTD
- `SLES_526.07.ELF` (ejecutable del juego PS2)
- `SCRIPT.PTD` (1,728,512 bytes)

PASOS REALIZADOS:

1. ANÁLISIS INICIAL DEL ARCHIVO:
```
hexdump -C SCRIPT.PTD | head -50
```
- Primeros 32 bytes: cabecera desconocida
- Bytes 0x20-0x11F: 256 bytes de tabla
- Resto: datos encriptados

2. BÚSQUEDA EN EL EJECUTABLE:

 

r2 -A SLES_526.07.ELF
afl | grep -i "read\|fopen\|file"



- Encontrada función en 0x0010da30 (manejo de archivos)

3. TRAZADO DE LLAMADAS:

0x0010da30 → 0x10ccf0 → 0x10a3f8 → 0x0010d850

4. ANÁLISIS DE LA FUNCIÓN DE DECODIFICACIÓN (0x0010d850):

Código MIPS encontrado:

lui     $a0, 0x001a
addiu   $a0, $a0, -0x0a00  ; buffer destino
move    $a1, $s1           ; puntero a datos
li      $a2, 0x120         ; offset inicial
move    $t1, $zero         ; t1 = 0x00
move    $t3, $s3           ; t3 = 0x04 (de s3)
 

ALGORITMO DESCUBIERTO:

Para cada byte en input[a2++]:
    t1 = (t1 - 1) & 0xFF
    t7 = t1 XOR byte_actual
    t7 = (t7 + t3) & 0xFF
    output = tabla[0x20 + t7]
    t3 = memoria[s0] (actualización dinámica)
 

5. TABLA DE DECODIFICACIÓN (offset 0x20):
```
00000020: 89 7c 3a f1 4d e2 b0 55 92 47 18 6d a3 fe 29 8b
00000030: 74 31 9f d6 58 c3 67 b4 e5 12 4a 7f 36 98 d1 6a
...
(256 bytes total)
```

6. IMPLEMENTACIÓN EN PYTHON:
def decode_script(data):
    table = data[0x20:0x120]  # 256 bytes
    encrypted = data[0x120:]   # datos encriptados
    
    t1 = 0x00
    t3 = 0x04
    output = []
    
    for byte in encrypted:
        t1 = (t1 - 1) & 0xFF
        t7 = t1 ^ byte
        t7 = (t7 + t3) & 0xFF
        decoded = table[t7]
        output.append(decoded)
        # t3 se actualiza de memoria[s0] - pendiente
    
    return bytes(output)
 

7. RESULTADOS DEL DESCIFRADO:
- Tamaño descifrado: 1,728,224 bytes
- 12,026 cadenas de texto japonés encontradas
- 3,733 ocurrencias del byte 0x9C
- 1,949 ocurrencias del byte 0xA8
- 865 ocurrencias del byte 0xA2

8. ESTRUCTURA DEL BYTECODE DESCUBIERTO:

[0x9C] [OPCODE] [parámetros...] [texto japonés] [0x9C] [OPCODE]...

Opcodes identificados:
- 0xA8 = 惠 (más común)
- 0xA2 = 悗
- 0x5E = 弯
- 0x8A = 怺
- 0xDF = 憑
- 0xF2 = 懿
- 0xC8 = 慂
- 0xDA = 憇

9. PATRONES DETECTADOS:
- Secuencias: `9C A8 9C A2 9C A8 9C 24...`
- Byte 0x24 aparece como separador
- Texto entre comandos en codificación Shift-JIS

10. LO QUE FALTA POR DESCUBRIR:
- Funciones que procesan cada opcode (A8, A2, etc.)
- Tabla de dispatch en el ejecutable
- Significado de los primeros 32 bytes
- Actualización exacta de t3 durante decodificación
- Estructura completa de parámetros por comando

1. FORMATO DEL ARCHIVO SCRIPT.PTD:

Firma de cabecera: "PETA" (50 45 54 41)

Tamaño total: 1,728,512 bytes

Estructura: Cabecera 32 bytes + SBOX 256 bytes + Datos cifrados

SBOX: 256 bytes en offset 0x20-0x11F

Datos cifrados: 1,728,224 bytes restantes

2. ALGORITMO DE CIFRADO DESCIFRADO:

Algoritmo confirmado: Basado en MIPS del juego

Clave t3: 0x02 (valor óptimo encontrado)

Bloques: 288 bytes (0x120) cada uno

t1: Comienza en 0x00 por cada bloque

Proceso por byte:

text

t7 = (t1 XOR byte_cifrado) & 0xFF t7 = (t7 + t3) & 0xFF byte_descifrado = SBOX[t7] t1 = (t1 - 1) & 0xFF

3. ESTRUCTURA DE LOS DATOS DESCIFRADOS:

Tamaño: 1,722,223 bytes

Registros: 3,375 registros de 512 bytes cada uno

Contiene:

Scripts con comandos: 6,453 comandos @

Comentarios: 6,570 símbolos #

Bloques de código: 7,988 pares { }

Parámetros: 6,456 pares [ ]

Efectos de sonido: 25 referencias SE

Archivos incrustados: JPEG y BMP

4. ARCHIVOS ENCONTRADOS DENTRO:

EXTRACTED_JPEG.jpg ??

Posible BMP en offset 0x000226C0

Múltiples streams zlib en offsets específicos

 

🚨 PROBLEMAS PENDIENTES:

1. CAPA ADICIONAL DE CODIFICACIÓN/CORRUPCIÓN:

Los bytes descifrados necesitan XOR 0x40 adicional

Aún así, el texto aparece corrupto: 縺綉縺縺綉縺綵縺...

Los caracteres japoneses existen pero mal formados

2. ESTRUCTURA BINARIA COMPLEJA:

No es texto plano simple

Mezcla de: comandos + metadatos + datos binarios + texto

Posiblemente comprimido parcialmente


 

SCRIPT.PTD es un "PAQUETE DE RECURSOS DE SCRIPT" que contiene:

Metadatos/índice (primeros ~50 registros)

Scripts binarios con estructura propia

Diálogos en japonés (codificados de forma especial)

Recursos incrustados (imágenes JPEG/BMP)

Posiblemente código compilado o bytecode

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...