Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
seiya-git committed Oct 25, 2023
1 parent b7f4324 commit 790e0c6
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 97 deletions.
14 changes: 0 additions & 14 deletions bat/install_dependencies.bat

This file was deleted.

6 changes: 0 additions & 6 deletions bat/nscb-compress.bat

This file was deleted.

6 changes: 0 additions & 6 deletions bat/nscb-decopress.bat

This file was deleted.

8 changes: 0 additions & 8 deletions bat/nscb-verify-folder-lv2.bat

This file was deleted.

8 changes: 0 additions & 8 deletions bat/nscb-verify-folder-lv3.bat

This file was deleted.

6 changes: 0 additions & 6 deletions bat/nscb-verify-lv2.bat

This file was deleted.

6 changes: 0 additions & 6 deletions bat/nscb-verify-lv3.bat

This file was deleted.

6 changes: 0 additions & 6 deletions bat/nscb-verify-test.bat

This file was deleted.

6 changes: 6 additions & 0 deletions bat/verify-folder.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@echo off
set app=%~dp0../py/ns_verify_folder.py

py "%app%" -i "%~1" --save-log

pause
33 changes: 14 additions & 19 deletions py/lib/Verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
import enlighten

def parse_name(file):
res = re.search(r'(?P<title_id>\[0100[A-F0-9]{12}\])\s?(?P<version>\[v\d+\]).*?(?P<type>\[(BASE|UPD(ATE)?|DLC( \d+)?)\])?.*?\.(xci|xcz|nsp|nsz)$', file, re.I)
res_id = re.search(r'(?P<title_id>\[0100[A-F0-9]{12}\])', file)
res_ver = re.search(r'(?P<version>\[v\d+\])', file)

if res is None:
if res_id is None or res_ver is None:
return None

# define main data
title_id = res.group('title_id')[1:-1]
version = int(res.group('version')[2:-1])
title_id = res_id.group('title_id')[1:-1]
version = int(res_ver.group('version')[2:-1])
title_type = None

if title_id[:-4] == '010000000000':
Expand All @@ -43,10 +43,14 @@ def parse_name(file):
elif title_oei % 2 == 1 and int(title_ext, 16) > 0:
title_type = 'DLC'

# can't define title_type
if title_type is None:
return None

if title_type != 'DLC':
title_ext = ''
else:
title_ext = f'{int(title_ext, 16):04}'

return {
'title_id': title_id,
'title_type': title_type,
Expand All @@ -58,6 +62,9 @@ def verify(file):
try:
filename = os.path.abspath(file)

check = True
vmsg = list()

if file.lower().endswith('.xci'):
f = Fs.factory(Path(filename))
f.open(filename, 'rb')
Expand All @@ -66,16 +73,7 @@ def verify(file):
elif file.lower().endswith(('.nsp', '.nsz')):
f = Fs.Nsp.Nsp(filename, 'rb')
else:
return False, {}

res = parse_name(file)
log_info = f"{file.upper()[-3:]} {res['title_id']} v{round(res['version']/65536)} {res['title_type']}"
if res['title_type'] == 'DLC':
log_info += f" {str(int(res['title_ext'], 16)).zfill(4)}"
print(f'[:INFO:] Verifying... {log_info}\n')

vmsg = list()
check = True
return False, vmsg

check_decrypt, vmsg = verify_decrypt(f, vmsg)
if check_decrypt == False:
Expand Down Expand Up @@ -110,9 +108,6 @@ def verify_decrypt(nspx, vmsg = None):

verdict = True

if type(nspx) != Fs.Xci.Xci and type(nspx) != Fs.Nsp.Nsp:
return False, msg

tvmsg = '\n[:INFO:] DECRYPTION TEST'
print(tvmsg)
vmsg.append(tvmsg)
Expand Down
62 changes: 62 additions & 0 deletions py/ns_extract_hashes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os
import sys

from pathlib import Path
from Fs import Pfs0, Nca, Type, factory

# set app path
appPath = Path(sys.argv[0])
while not appPath.is_dir():
appPath = appPath.parents[0]
appPath = os.path.abspath(appPath)
print(f'[:INFO:] App Path: {appPath}')

# set logs path
# logs_dir = os.path.abspath(os.path.join(appPath, '..', 'logs'))
# print(f'[:INFO:] Logs Path: {logs_dir}')

import argparse
parser = argparse.ArgumentParser(formatter_class = argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-i', '--input', help = 'input file')
args = parser.parse_args()

INCP_PATH = args.input

def send_hook(message_content):
try:
print(message_content)
except:
pass

def scan_file():
ipath = os.path.abspath(INCP_PATH)
if not os.path.isfile(ipath):
return
if not ipath.lower().endswith(('.xci', '.xcz', '.nsp', '.nsz')):
return

container = factory(Path(ipath).resolve())
container.open(ipath, 'rb')
if ipath.lower().endswith(('.xci', '.xcz')):
container = container.hfs0['secure']
try:
for nspf in container:
if isinstance(nspf, Nca.Nca) and nspf.header.contentType == Type.Content.META:
for section in nspf:
if isinstance(section, Pfs0.Pfs0):
Cnmt = section.getCnmt()
print(Cnmt.__dict__)
for entry in Cnmt.contentEntries:
print(f'\n:{Cnmt.titleId} - Content.{Type.Content(entry.type)._name_}')
print(f'> FILENAME: {entry.ncaId}')
print(f'> HASH: {entry.hash.hex()}')
finally:
container.close()


if __name__ == "__main__":
if INCP_PATH:
scan_file()
else:
parser.print_help()
print()
46 changes: 28 additions & 18 deletions py/verify_folder.py → py/ns_verify_folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import sys
import json
import requests
import shutil
import re

from pathlib import Path
Expand All @@ -23,15 +22,19 @@
parser = argparse.ArgumentParser(formatter_class = argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-i', '--input', help = 'input folder')
parser.add_argument('-w', '--webhook-url', help = 'discord webhook url', required = False)
parser.add_argument('--save-log', help = 'save verify log', required = False, action='store_true')
args = parser.parse_args()
config = vars(args)

INCP_PATH = config['input']
WHOOK_URL = config['webhook_url']
INCP_PATH = args.input
WHOOK_URL = args.webhook_url
SAVE_VLOG = bool(args.save_log)

def send_hook(message_content):
def send_hook(message_content, PadPrint = False):
try:
print(message_content)
print_msg = message_content
if PadPrint == True:
print_msg = f'\n{message_content}'
print(print_msg)
payload = {
'username': 'Contributions',
'content': message_content.strip()
Expand All @@ -53,12 +56,12 @@ def scan_folder():
if not os.path.exists(logs_dir):
os.makedirs(logs_dir)

if os.path.exists(lpath_badfolder):
os.remove(lpath_badfolder)
if os.path.exists(lpath_badname):
os.remove(lpath_badname)
if os.path.exists(lpath_badfile):
os.remove(lpath_badfile)
# if os.path.exists(lpath_badfolder):
# os.remove(lpath_badfolder)
# if os.path.exists(lpath_badname):
# os.remove(lpath_badname)
# if os.path.exists(lpath_badfile):
# os.remove(lpath_badfile)

if not os.path.exists(ipath):
print(f'[:WARN:] Please put your files in "{ipath}" and run this script again.')
Expand All @@ -78,12 +81,13 @@ def scan_folder():
item_path = os.path.join(ipath, item)

findex += 1
send_hook(f'\n[:INFO:] File found ({findex} of {len(files)}): {item}')
send_hook(f'[:INFO:] Checking syntax...')
send_hook(f'[:INFO:] File found ({findex} of {len(files)}): {item}', True)
send_hook(f'[:INFO:] Checking filename...')

data = Verify.parse_name(item)

if data is None:
send_hook(f'{item_path}: BAD NAME')
with open(lpath_badname, 'a') as f:
f.write(f'{item_path}\n')
continue
Expand Down Expand Up @@ -114,15 +118,21 @@ def scan_folder():
log_name = os.path.join(rootpath, basename)

try:
send_hook(f'[:INFO:] Verifying...')
nspTest, nspLog = Verify.verify(item_path)
if nspTest != True:
send_hook(f'{item_path}: BAD', True)
with open(lpath_badfile, 'a') as f:
f.write(f'{item_path}\n')
with open(f'{log_name}-bad.txt', 'w') as f:
f.write(f'{nspLog}')
else:
with open(f'{log_name}.txt', 'w') as f:
f.write(f'{nspLog}')
send_hook(f'{item_path}: OK', True)
if SAVE_VLOG == True:
if nspTest != True:
with open(f'{log_name}-bad.log', 'w') as f:
f.write(f'{nspLog}')
else:
with open(f'{log_name}-ok.log', 'w') as f:
f.write(f'{nspLog}')
except Exception as e:
send_hook(f'[:WARN:] An error occurred:\n{item}: {str(e)}')

Expand Down

0 comments on commit 790e0c6

Please sign in to comment.