Skip to content

Instantly share code, notes, and snippets.

@fffonion
Last active August 1, 2022 06:03
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fffonion/d1a0c9507bda9ee52588 to your computer and use it in GitHub Desktop.
Save fffonion/d1a0c9507bda9ee52588 to your computer and use it in GitHub Desktop.
artemis resource unpack
# coding:utf-8
import struct
import os
import os.path as opth
import sys
__version__ = 1.0
getPATH0 = lambda: sys.path[0].decode(sys.getfilesystemencoding())
# 命令行处理
try:
dfile, outdir = sys.argv[1:3]
except:
print('Artemis Engine Extractor v%.1f\nUsage artemis.py file directory cvas|-cvas|d bufsize\n\t To select resources: c:CG, v:video, a:audio, s:system, d:all; -:except' %
__version__)
os._exit(1)
outdir = opth.abspath(outdir)
if len(sys.argv) < 4:
sel_res = '-ALL-'
else:
sel_res = sys.argv[3]
sel_ext = []
if 'd' in sel_res:
sel_res = '-ALL-'
if 'a' in sel_res:
sel_ext += ['ogg', 'mp3']
if 'v' in sel_res:
sel_ext += ['mp4', 'mov']
if 'c' in sel_res:
sel_ext += ['jpg', 'png']
if 's' in sel_res:
sel_ext += ['iet', 'ini', 'otf', 'ttf']
if '-' in sel_res:
sel_res = '-' # 表排除
if len(sys.argv) >= 5:
bufsize = int(sys.argv[4]) * 1024 * 1024
else:
bufsize = 10 * 1024 * 1024
# not-using
'''def rev(i):#转十六进制小端序
str=hex(i)[2::]
if str.endswith('L'):str=str[:-1]
str=str.zfill(8)#补齐8位
return str.decode('hex')[::-1].encode('hex')
def rev_int(i):
return int(rev(i),16)'''
# a=open('jp.co.ideaf.hakuoki_kaikoroku\\main.3.jp.co.ideaf.hakuoki_kaikoroku.obb','rb').read(65628)
# open('head','wb').write(a)
# 读索引头
dtfile = open(dfile, 'rb')
head = dtfile.read(1024 * 1024)
curpos = 19 # 头部偏移
spltpos = head.find(b'\x10', curpos)
elem = []
elem_distr = ''
print('read resource table...')
# 生成资源表
while spltpos != -1:
dt = head[curpos:spltpos + 24]
name, pos, length, mark = struct.unpack(
'<%ds12x3I' % (spltpos - curpos), dt) # 使用小端序
print('%x %x:%s %x %x %s' %
(curpos, spltpos + 24, name, int(pos), int(length), mark))
elem_distr += ('%s,%d,%d,%s,\r\n' % (name, int(pos), int(length), mark))
elem.append([int(pos), int(length), mark, name])
curpos = spltpos + 24
spltpos = head.find(b'\x10', curpos, elem[0][0])
# if len(elem)>10:break
print('%d resources found' % len(elem))
open('elem.txt', 'w').write(elem_distr)
elem.sort()
buf = ''
bufcnt = 0 # 已用buffer计数
rescnt = 0 # 已读资源计数
dtfile.seek(0)
if not opth.exists(outdir):
os.makedirs(outdir)
# 读取并输出
for i in range(len(elem)):
fname = elem[i][3]
if ((not opth.splitext(fname)[1][1:] in sel_ext) ^ (sel_res == '-')) and sel_res != '-ALL-':
print('Skip %s' % fname)
continue
if opth.split(fname)[0] != '' and not opth.exists(opth.join(outdir, opth.split(fname)[0])):
os.makedirs(opth.join(outdir, opth.split(fname)[0]))
while elem[i][0] + elem[i][1] > (bufcnt * bufsize + len(buf)): # 需要读取文件时
print('Reading %dKB to buffer:0x%x (want 0x%x)' % (
bufsize / 1024, elem[i][0] + elem[i][1], bufcnt * bufsize + len(buf)))
skip = (elem[i][0] - bufcnt * bufsize - len(buf)) / bufsize
if skip > 0:
buf = ''
bufcnt = skip + bufcnt + len(buf) / bufsize
dtfile.seek(bufcnt * bufsize)
'''print elem[i][0],elem[i][1],elem[i][0]+elem[i][1]
print bufcnt*bufsize,len(buf),bufcnt*bufsize+len(buf)
print 'seek',skip,(bufcnt+skip)*bufsize,bufcnt
raw_input()'''
buf += dtfile.read(bufsize)
# print elem[i][0]-bufcnt*bufsize,elem[i][1]+elem[i][0]-bufcnt*bufsize
f = open(opth.join(outdir, fname), 'wb')
f.write(
buf[elem[i][0] - bufcnt * bufsize:elem[i][1] + elem[i][0] - bufcnt * bufsize])
f.close()
print('extract %s' % fname)
while elem[i][0] >= bufcnt * bufsize + bufsize: # 清理缓存
if len(buf) >= bufsize:
buf = buf[bufsize:]
bufcnt += 1
print('Clean up buffer #%d' % bufcnt)
rescnt += 1
# raw_input()
raw_input('done extracting %d resources.' % rescnt)
@tung12343
Copy link

uhh, sorry for being an idiot but how to use this?

@fffonion
Copy link
Author

fffonion commented Feb 21, 2021

@tung12343 you will use
python ./artemis.py <path-to-packed-file> <path-for-extracted-files>
for example on Android the path-to-packed-file could be the .obb file in /sdcard/Android/data//

@tung12343
Copy link

@tung12343 you will use
python ./artemis.py <path-to-packed-file> <path-for-extracted-files>
for example on Android the path-to-packed-file could be the .obb file in /sdcard/Android/data//

thankyou so much, Love you for replying

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment