Generic Artemis Engine (root.pfs.*)

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
velvety
Posts: 3
Joined: Thu Jan 10, 2019 8:38 pm

Generic Artemis Engine (root.pfs.*)

Post by velvety »

Hello,
I rewrote the script for root.pfs archives.
Only tested on a single game though. Can you please add it to the compendium?

artemis-root-pfs.bms

Code: Select all

# Generic Artemis Engine (root.pfs.*) v1.0
# Based on initial work by aluigi for Amnesia: Memories and Norn9
# script for QuickBMS https://aluigi.altervista.org/quickbms.htm or https://aluigi.zenhax.com/

# Credits to @GARbro for figuring out the XOR key calculation
# https://github.com/morkt/GARbro/blob/12bbd3a3/ArcFormats/Artemis/ArcPFS.cs#L101

QuickBMSver 0.7.3

# SHA1 hash length (160 bits)
math KEYSZ = 20

# Example for Noraneko Heart HD (NSW)
#get NAME filename
#if NAME == "root.pfs"
#    set KEY binary "\xB7\x36\x16\xDD\x3F\xE1\x0A\xF1\x22\x06\xAD\x3C\xB6\x67\x80\x72\x46\x25\x7A\x61"
#elif NAME == "root.pfs.000"
#    set KEY binary "\x83\x3D\xCB\x3D\xD8\x7D\x70\xD4\x9C\xCE\x2E\x25\xCC\xAB\x89\x43\xFB\xD0\xE3\x36"
#elif NAME == "root.pfs.001"
#    set KEY binary "\xDB\x1E\x30\x29\x7B\x8C\xC7\x58\xE1\xD7\x33\xD0\xC4\x66\x36\x87\x62\xC6\xE6\xDF"
#elif NAME == "root.pfs.002"
#    set KEY binary "\x8D\x98\xA0\x17\x31\x14\xD1\x04\xE7\x72\xFF\xC1\xA3\x60\x6E\xEC\x59\x64\x37\xC7"
#elif NAME == "root.pfs.003"
#    set KEY binary "\xD7\x98\x0D\x0E\x54\x83\x44\x90\x2C\x4C\x0D\xC9\x11\x0E\x76\x25\x94\x31\xEB\x29"
#endif

idstring "pf"
getdstring VER 1    # '6', '8' and so on
if VER == "8"
    codepage 932
endif

get INFO_SIZE long
SavePos INFO_OFFSET
Log MEMORY_FILE INFO_OFFSET INFO_SIZE
Encryption sha1 MEMORY_FILE
Log MEMORY_FILE 0 0
print "KEY %QUICKBMS_HEXHASH%"
GoTo INFO_OFFSET
get FILES long
for i = 0 < FILES
    get NAMESZ long
    getdstring NAME NAMESZ
    get ZERO long
    get OFFSET long
    get SIZE long

    set EXT extension NAME
    if EXT == "mp4"
    else
        encryption xor QUICKBMS_HASH 0 KEYSZ
    endif
    log NAME OFFSET SIZE
    encryption "" ""
next i
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by aluigi »

:D
velvety
Posts: 3
Joined: Thu Jan 10, 2019 8:38 pm

Version 2 handling pf6 magic

Post by velvety »

root.pfs archives with a pf6 idstring (cleartext, apparently) were not handled properly.

Here's a v2.

Code: Select all

# Generic Artemis Engine (root.pfs.*)
# Based on initial work by aluigi for Amnesia: Memories and Norn9
# v2 handles 'pf6' as cleartext
# script for QuickBMS http://quickbms.aluigi.org

# Credits to @GARbro for figuring out the XOR key calculation
# https://github.com/morkt/GARbro/blob/12bbd3a3/ArcFormats/Artemis/ArcPFS.cs#L101

# SHA1 hash length (160 bits)
math KEYSZ = 20

get NAME filename
# Example for Noraneko Heart HD (NSW)
#if NAME == "root.pfs"
#    set KEY binary "\xB7\x36\x16\xDD\x3F\xE1\x0A\xF1\x22\x06\xAD\x3C\xB6\x67\x80\x72\x46\x25\x7A\x61"
#elif NAME == "root.pfs.000"
#    set KEY binary "\x83\x3D\xCB\x3D\xD8\x7D\x70\xD4\x9C\xCE\x2E\x25\xCC\xAB\x89\x43\xFB\xD0\xE3\x36"
#elif NAME == "root.pfs.001"
#    set KEY binary "\xDB\x1E\x30\x29\x7B\x8C\xC7\x58\xE1\xD7\x33\xD0\xC4\x66\x36\x87\x62\xC6\xE6\xDF"
#elif NAME == "root.pfs.002"
#    set KEY binary "\x8D\x98\xA0\x17\x31\x14\xD1\x04\xE7\x72\xFF\xC1\xA3\x60\x6E\xEC\x59\x64\x37\xC7"
#elif NAME == "root.pfs.003"
#    set KEY binary "\xD7\x98\x0D\x0E\x54\x83\x44\x90\x2C\x4C\x0D\xC9\x11\x0E\x76\x25\x94\x31\xEB\x29"
#endif

idstring "pf"
getdstring VER 1    # '6', '8' and so on
codepage 932
# If you see weird filenames, you may also want to try UTF-8 (e.g. for console or phone games):
# codepage 65001

get INFO_SIZE long
SavePos INFO_OFFSET
if VER == "8"
    Log MEMORY_FILE INFO_OFFSET INFO_SIZE
    Encryption sha1 MEMORY_FILE
    Set KEY binary QUICKBMS_HASH
elif VER == "6"
    set KEY binary "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
endif

# cannot get this dump to work:
#print "KEY %KEY|dump20%"

GoTo INFO_OFFSET
get FILES long
for i = 0 < FILES
    get NAMESZ long
    getdstring NAME NAMESZ
    get ZERO long
    get OFFSET long
    get SIZE long

    set EXT extension NAME
    if EXT == "mp4"
    else
        encryption xor KEY 0 KEYSZ
    endif
    log NAME OFFSET SIZE
    encryption "" ""
next i
Log MEMORY_FILE 0 0
velvety
Posts: 3
Joined: Thu Jan 10, 2019 8:38 pm

Version 3 handling pf2 magic

Post by velvety »

Sorry for spamming. Here is v3 handling pf2 archives and quitting if version is not handled (pf2, pf6 or pf8)

Code: Select all

# Generic Artemis Engine (root.pfs.*)
# Based on initial work by aluigi for Amnesia: Memories and Norn9
# v3 handles 'pf2' as cleartext, quits if magic is not handled
# v2 handles 'pf6' as cleartext
# script for QuickBMS http://quickbms.aluigi.org

# Credits to @GARbro for figuring out the XOR key calculation
# https://github.com/morkt/GARbro/blob/12bbd3a3/ArcFormats/Artemis/ArcPFS.cs#L101

# SHA1 hash length (160 bits)
math KEYSZ = 20

get NAME filename
# Example for Noraneko Heart HD (NSW)
#if NAME == "root.pfs"
#    set KEY binary "\xB7\x36\x16\xDD\x3F\xE1\x0A\xF1\x22\x06\xAD\x3C\xB6\x67\x80\x72\x46\x25\x7A\x61"
#elif NAME == "root.pfs.000"
#    set KEY binary "\x83\x3D\xCB\x3D\xD8\x7D\x70\xD4\x9C\xCE\x2E\x25\xCC\xAB\x89\x43\xFB\xD0\xE3\x36"
#elif NAME == "root.pfs.001"
#    set KEY binary "\xDB\x1E\x30\x29\x7B\x8C\xC7\x58\xE1\xD7\x33\xD0\xC4\x66\x36\x87\x62\xC6\xE6\xDF"
#elif NAME == "root.pfs.002"
#    set KEY binary "\x8D\x98\xA0\x17\x31\x14\xD1\x04\xE7\x72\xFF\xC1\xA3\x60\x6E\xEC\x59\x64\x37\xC7"
#elif NAME == "root.pfs.003"
#    set KEY binary "\xD7\x98\x0D\x0E\x54\x83\x44\x90\x2C\x4C\x0D\xC9\x11\x0E\x76\x25\x94\x31\xEB\x29"
#endif

idstring "pf"
getdstring VER 1    # '6', '8' and so on
codepage 932
# If you see weird filenames, you may also want to try UTF-8 (e.g. for console or phone games):
# codepage 65001

get INFO_SIZE long
SavePos INFO_OFFSET
if VER == "8"
    Log MEMORY_FILE INFO_OFFSET INFO_SIZE
    Encryption sha1 MEMORY_FILE
    Set KEY binary QUICKBMS_HASH
elif VER == "6"
    set KEY binary "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
elif VER == "2"
    print "hello"
    Math INFO_OFFSET + 4
    set KEY binary "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
else
    print "ERROR This version is not supported: %VER%"
   cleanexit
endif

# cannot get this dump to work:
#print "KEY %KEY|dump20%"

GoTo INFO_OFFSET
get FILES long
for i = 0 < FILES
    get NAMESZ long
    getdstring NAME NAMESZ
    if VER == "2"
       get SIZEOFCRAP long
      Math SIZEOFCRAP - 8
      GoTo SIZEOFCRAP 0 SEEK_CUR
    else
        get ZERO long
    endif
    get OFFSET long
    get SIZE long

    set EXT extension NAME
    if EXT == "mp4"
    else
        encryption xor KEY 0 KEYSZ
    endif
    log NAME OFFSET SIZE
    encryption "" ""
next i
Log MEMORY_FILE 0 0
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by aluigi »

Cool, do you know if exist other versions to cover?
fkvldh
Posts: 1
Joined: Tue Feb 26, 2019 8:38 pm

(CLOSE) Aibeya [root.pfs ~ 002][Windows]

Post by fkvldh »

Hello, everyone.
This game is japanese visual novel.
I want Unpack & Repack this files, but I need bms.
I'm noob, I don't know programming well.
If anyone knows how to and could give me some help, it would be greatly appreciated.

Engine is Artemis engine resource archive
xperiagenerator
Posts: 34
Joined: Fri Dec 23, 2016 2:57 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by xperiagenerator »

deleted
Last edited by xperiagenerator on Wed May 01, 2019 2:37 pm, edited 2 times in total.
xperiagenerator
Posts: 34
Joined: Fri Dec 23, 2016 2:57 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by xperiagenerator »

deleted
Nyanpasu
Posts: 8
Joined: Mon Apr 29, 2019 10:46 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by Nyanpasu »

Any news about repack?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by aluigi »

Nyanpasu wrote:Any news about repack?

In theory reimporting should work, have you got any error or the game refuses to run?
Sonotoki
Posts: 4
Joined: Wed Apr 29, 2020 1:54 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by Sonotoki »

aluigi wrote:
Nyanpasu wrote:Any news about repack?

In theory reimporting should work, have you got any error or the game refuses to run?

Hi! Hello everyone! I'm looking for repacking method, too.
Today I played a game created on the Artemis Engine, I can extract packages well, there's no problem, but when it comes to repack, I tried method above, but it doesn't working (both reimporting.bat and reimporting2.bat).
I'm not reverse engineer yet :( but is there someone who already created the repacking code?

Aaah! :shock: I didn't sleep today! Playing this Visual Novel! :) I wanted to translate, that's why I need the repacker )
おやすみ、これ、自分に言っている:)
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by aluigi »

I updated the script to avoid an error with the generation of the key:
http://aluigi.org/bms/artemis_engine.bms
andrewryanchama
Posts: 1
Joined: Sat Apr 16, 2022 11:22 pm

Re: Generic Artemis Engine (root.pfs.*)

Post by andrewryanchama »

Sonotoki wrote:
aluigi wrote:
Nyanpasu wrote:Any news about repack?

In theory reimporting should work, have you got any error or the game refuses to run?

Hi! Hello everyone! I'm looking for repacking method, too.
Today I played a game created on the Artemis Engine, I can extract packages well, there's no problem, but when it comes to repack, I tried method above, but it doesn't working (both reimporting.bat and reimporting2.bat).
I'm not reverse engineer yet :( but is there someone who already created the repacking code?

Aaah! :shock: I didn't sleep today! Playing this Visual Novel! :) I wanted to translate, that's why I need the repacker )
おやすみ、これ、自分に言っている:)


I tried to reimport this and I found it's not working when the filesize of the script is different from before. I put some spaces at the end of the file to make the file the same size and it is working as expected.