Browse Source

dos2unix py and c files, back slash changed to forward slash in PacExtract.py

master
surkeh 4 years ago
parent
commit
fdea0db450
  1. 104
      PTXRepack.py
  2. 379
      PacExtract.py
  3. 392
      PacInject.c
  4. 320
      PacRepack.py
  5. 150
      ReadMe.txt
  6. 360
      scanPAC.c

104
PTXRepack.py

@ -1,53 +1,53 @@ @@ -1,53 +1,53 @@
#PTX Repack
#coded by james
import sys
from struct import pack
#Another version of getFiles, for PTX usage
def getFilesPTX(index_file):
line = index_file.readline().strip()
files = []
while line != "":
print "\t%s" % line
files.append(line)
line = index_file.readline().strip()
return files
#repacks a PTX archive
def PTX(file):
print "\nRepacking PTX Archive: %s" % file
try:
index_file = open("%s\\%s.index" % (file, file), "r")
except:
print "Error Reading %s.index from PTX folder %s" % (file, file)
return(-1)
files = getFilesPTX(index_file)
num_files = len(files)
header = pack("<I", num_files)
body = ""
outfile = open("%s.ptx" % (file), "wb")
for i in range(num_files):
bin_open = open("%s\\%s" % (file, files[i]), "rb")
bin_str = bin_open.read()
header += pack("<I", len(bin_str)/1024/2)
body += bin_str
header += ("00000000".decode("hex"))*(511-num_files) #cushion
outfile.write(header+body)
return 0
def main():
print "BETA PTX PYTHON REPACKER\nDMC3 Modding"
if len(sys.argv) < 2:
print "Usage: %s [folder]" % sys.argv[0]
return(-1)
else:
PTX(sys.argv[1])
return(0)
#PTX Repack
#coded by james
import sys
from struct import pack
#Another version of getFiles, for PTX usage
def getFilesPTX(index_file):
line = index_file.readline().strip()
files = []
while line != "":
print "\t%s" % line
files.append(line)
line = index_file.readline().strip()
return files
#repacks a PTX archive
def PTX(file):
print "\nRepacking PTX Archive: %s" % file
try:
index_file = open("%s\\%s.index" % (file, file), "r")
except:
print "Error Reading %s.index from PTX folder %s" % (file, file)
return(-1)
files = getFilesPTX(index_file)
num_files = len(files)
header = pack("<I", num_files)
body = ""
outfile = open("%s.ptx" % (file), "wb")
for i in range(num_files):
bin_open = open("%s\\%s" % (file, files[i]), "rb")
bin_str = bin_open.read()
header += pack("<I", len(bin_str)/1024/2)
body += bin_str
header += ("00000000".decode("hex"))*(511-num_files) #cushion
outfile.write(header+body)
return 0
def main():
print "BETA PTX PYTHON REPACKER\nDMC3 Modding"
if len(sys.argv) < 2:
print "Usage: %s [folder]" % sys.argv[0]
return(-1)
else:
PTX(sys.argv[1])
return(0)
main()

379
PacExtract.py

@ -1,189 +1,190 @@ @@ -1,189 +1,190 @@
#PAC Extractor
#coded by James
#! python2
#import
import sys, os
from struct import *
#gets all the offsets from the header
def getFiles(str):
num_files = unpack("<I", str[4:8])[0] #how many files
offset = 8
offsets = []
#for how many files, get each pointer
for i in range(num_files):
file = unpack("<I", str[offset:offset+4])[0]
if file != 0 and file not in offsets:
offsets.append(file)
offset += 4
return offsets
#get the type of file, just add more to this for more file types
#double tested because I was having errors without it
def getType(str):
try:
if str[:4].encode("hex").upper() == "4D4F4420" or str[:3] == "MOD":
suf = "mod"
elif str[:4].encode("hex").upper() == "44445320" or str[:3] == "DDS":
suf = "dds"
elif str[:4].encode("hex").upper() == "53485720" or str[:3] == "SHW":
suf = "shw"
elif str[:3] == "MOT" or str[:4].encode("hex").upper() == "50000000":
suf = "mot"
elif str[:3] == "PAC" or str[:3] == "PNS":
suf = "pac"
elif str[:4].encode("hex").upper() == "4F676753" or str[:3] == "Ogg":
suf = "ogg"
elif str[:4].encode("hex").upper() == "424D3600" or str[:3] == "BM6":
suf = "bm6"
elif str[:4].encode("hex").upper() == "000001BA":
suf = "mpg"
elif str[:4] == "LIG2":
suf = "lig"
elif str[:3] == "SEF":
suf = "sef"
elif str[:3] == "CAM":
suf = "cam"
elif str[:3] == "EVE":
suf = "eve"
elif str[:3] == "POS":
suf = "pos"
elif str[:4].encode("hex").upper() == "EFBBBF23":
suf = "txt"
elif str[:4].encode("hex").upper() == "00000000":
suf = "bd"
elif str[:4].encode("hex").upper() == "00000100":
suf = "ico"
elif str[:4].encode("hex").upper() == "64627354" or str[:4] == "dbsT":
suf = "tsb"
elif str[:2] == "# ":
suf = "txt"
# elif str[:4] == "ff&A":
# suf = "ff"
elif str[:1] == ";":
suf = "txt"
elif str[:2].encode("hex").upper() == "0600" and str[2:4] != "0000":
suf = "so"
#last chance, if the first three values are ASCII, use em.
elif (unpack("B", str[:1]) >= 65 and unpack("B", str[:1]) <= 90 and unpack("B", str[1:2]) >= 65 and unpack("B", str[1:2]) <= 90 and unpack("B", str[2:3]) >= 65 and unpack("B", str[2:3]) <= 90) or (unpack("B", str[:1]) >= 97 and unpack("B", str[:1]) <= 122 and unpack("B", str[1:2]) >= 97 and unpack("B", str[1:2]) <= 122 and unpack("B", str[2:3]) >= 97 and unpack("B", str[2:3]) <= 122):
suf = str[:3]
else: suf = "ukn"
except:
suf = "ukn"
return suf
#PTX extractor
def PTX(str, ptx_name, pac_name):
print "PTX Archive: %s.ptx" % ptx_name
num_files = unpack("<I", str[:4])[0] #number of files
offsets = []
last = 0
trail_str=str[2056:2160]
trail_open = open("%s\\%s.trail" % (pac_name, ptx_name), "wb")
trail_open.write(trail_str)
trail_open.close()
#too lazy to properly write it, just searched
for i in range(num_files):
offsets.append(str.find("DDS", last))
last = str.find("DDS", last)+4
#make another sub directory
try:
os.mkdir("%s\\%s" % (pac_name, ptx_name))
except WindowsError:
""
index_file = open("%s\\%s\\%s.index" % (pac_name, ptx_name, ptx_name), "w")
#for how many files, write each file
for i in range(num_files):
try:
file_str = str[offsets[i]:offsets[i+1]]
except IndexError:
file_str = str[offsets[i]:]
#index files, and writing contents
index_file.write("%s_%.3d.dds\n" % (ptx_name, i))
print "\tWriting: %s_%.3d.dds" % (ptx_name, i)
try:
file_open = open("%s\\%s\\%s_%.3d.dds" % (pac_name, ptx_name, ptx_name, i), "wb")
file_open.write(file_str)
file_open.close()
except:
print "\tError Writing %s_%.3d.dds" % (ptx_name, i)
return 0
def main():
#greetings
print "\n=================================\nDevil May Cry 3 \nPac extractor\nv1.0\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n"
#not enough args, usage
if len(sys.argv) < 2:
print "Usage: %s [file]\nExtracts Contents of a DMC3 PAC" % sys.argv[0]
return -1
else:
pac_file = sys.argv[1] #pac file
pac_name = pac_file[:pac_file.find(".")] #the name of the folder
#if can't open, exit
print "Opening: %s" % pac_file
try:
pac_open = open(pac_file, "rb")
except:
print "Error Opening %s" % pac_file
return -1
#if can't read, exit
print "Reading: %s" % pac_file
try:
pac_str = pac_open.read()
except:
print "Error Reading %s" % pac_file
return -1
pac_open.close()
#if the header is corrupt, exit
try:
offsets = getFiles(pac_str)
print "\nNumber of Files: %d\n" % len(offsets)
except:
print "Error Getting Contents of %s" % pac_file
return -1
#make directory
try:
os.mkdir(pac_name)
except:
""
#write all the files
index_file = open("%s\\%s.index" % (pac_name, pac_name), "w")
for i in range(len(offsets)):
try:
file_str = pac_str[offsets[i]:offsets[i+1]]
except IndexError:
file_str = pac_str[offsets[i]:]
if "DDS" in file_str[4:] and "PAC" not in file_str and "PNST" not in file_str:
print "%X" % offsets[i]
PTX(file_str, "%s_%.3d" % (pac_name, i), pac_name)
index_file.write("%s folder\n" % ("%s_%.3d"% (pac_name, i)))
else:
index_file.write("%s_%.3d.%s\n" % (pac_name, i,getType(file_str)))
print "Writing: %s_%3d.%s" % (pac_name, i,getType(file_str))
try:
file_open = open("%s\\%s_%.3d.%s" % (pac_name,pac_name, i,getType(file_str)), "wb")
file_open.write(file_str)
file_open.close()
except:
print "Error Writing %s" % ("%s_%.3i.%s" % (pac_name, i,getType(file_str)))
index_file.close()
print "\nAll Done!"
return 0
main()
#!/usr/bin/python
#! python2
#PAC Extractor
#coded by James
#import
import sys, os
from struct import *
#gets all the offsets from the header
def getFiles(str):
num_files = unpack("<I", str[4:8])[0] #how many files
offset = 8
offsets = []
#for how many files, get each pointer
for i in range(num_files):
file = unpack("<I", str[offset:offset+4])[0]
if file != 0 and file not in offsets:
offsets.append(file)
offset += 4
return offsets
#get the type of file, just add more to this for more file types
#double tested because I was having errors without it
def getType(str):
try:
if str[:4].encode("hex").upper() == "4D4F4420" or str[:3] == "MOD":
suf = "mod"
elif str[:4].encode("hex").upper() == "44445320" or str[:3] == "DDS":
suf = "dds"
elif str[:4].encode("hex").upper() == "53485720" or str[:3] == "SHW":
suf = "shw"
elif str[:3] == "MOT" or str[:4].encode("hex").upper() == "50000000":
suf = "mot"
elif str[:3] == "PAC" or str[:3] == "PNS":
suf = "pac"
elif str[:4].encode("hex").upper() == "4F676753" or str[:3] == "Ogg":
suf = "ogg"
elif str[:4].encode("hex").upper() == "424D3600" or str[:3] == "BM6":
suf = "bm6"
elif str[:4].encode("hex").upper() == "000001BA":
suf = "mpg"
elif str[:4] == "LIG2":
suf = "lig"
elif str[:3] == "SEF":
suf = "sef"
elif str[:3] == "CAM":
suf = "cam"
elif str[:3] == "EVE":
suf = "eve"
elif str[:3] == "POS":
suf = "pos"
elif str[:4].encode("hex").upper() == "EFBBBF23":
suf = "txt"
elif str[:4].encode("hex").upper() == "00000000":
suf = "bd"
elif str[:4].encode("hex").upper() == "00000100":
suf = "ico"
elif str[:4].encode("hex").upper() == "64627354" or str[:4] == "dbsT":
suf = "tsb"
elif str[:2] == "# ":
suf = "txt"
# elif str[:4] == "ff&A":
# suf = "ff"
elif str[:1] == ";":
suf = "txt"
elif str[:2].encode("hex").upper() == "0600" and str[2:4] != "0000":
suf = "so"
#last chance, if the first three values are ASCII, use em.
elif (unpack("B", str[:1]) >= 65 and unpack("B", str[:1]) <= 90 and unpack("B", str[1:2]) >= 65 and unpack("B", str[1:2]) <= 90 and unpack("B", str[2:3]) >= 65 and unpack("B", str[2:3]) <= 90) or (unpack("B", str[:1]) >= 97 and unpack("B", str[:1]) <= 122 and unpack("B", str[1:2]) >= 97 and unpack("B", str[1:2]) <= 122 and unpack("B", str[2:3]) >= 97 and unpack("B", str[2:3]) <= 122):
suf = str[:3]
else: suf = "ukn"
except:
suf = "ukn"
return suf
#PTX extractor
def PTX(str, ptx_name, pac_name):
print "PTX Archive: %s.ptx" % ptx_name
num_files = unpack("<I", str[:4])[0] #number of files
offsets = []
last = 0
trail_str=str[2056:2160]
trail_open = open("%s/%s.trail" % (pac_name, ptx_name), "wb")
trail_open.write(trail_str)
trail_open.close()
#too lazy to properly write it, just searched
for i in range(num_files):
offsets.append(str.find("DDS", last))
last = str.find("DDS", last)+4
#make another sub directory
try:
os.mkdir("%s/%s" % (pac_name, ptx_name))
except WindowsError:
""
index_file = open("%s/%s/%s.index" % (pac_name, ptx_name, ptx_name), "w")
#for how many files, write each file
for i in range(num_files):
try:
file_str = str[offsets[i]:offsets[i+1]]
except IndexError:
file_str = str[offsets[i]:]
#index files, and writing contents
index_file.write("%s_%.3d.dds\n" % (ptx_name, i))
print "\tWriting: %s_%.3d.dds" % (ptx_name, i)
try:
file_open = open("%s/%s/%s_%.3d.dds" % (pac_name, ptx_name, ptx_name, i), "wb")
file_open.write(file_str)
file_open.close()
except:
print "\tError Writing %s_%.3d.dds" % (ptx_name, i)
return 0
def main():
#greetings
print "\n=================================\nDevil May Cry 3 \nPac extractor\nv1.0\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n"
#not enough args, usage
if len(sys.argv) < 2:
print "Usage: %s [file]\nExtracts Contents of a DMC3 PAC" % sys.argv[0]
return -1
else:
pac_file = sys.argv[1] #pac file
pac_name = pac_file[:pac_file.find(".")] #the name of the folder
#if can't open, exit
print "Opening: %s" % pac_file
try:
pac_open = open(pac_file, "rb")
except:
print "Error Opening %s" % pac_file
return -1
#if can't read, exit
print "Reading: %s" % pac_file
try:
pac_str = pac_open.read()
except:
print "Error Reading %s" % pac_file
return -1
pac_open.close()
#if the header is corrupt, exit
try:
offsets = getFiles(pac_str)
print "\nNumber of Files: %d\n" % len(offsets)
except:
print "Error Getting Contents of %s" % pac_file
return -1
#make directory
try:
os.mkdir(pac_name)
except:
""
#write all the files
index_file = open("%s/%s.index" % (pac_name, pac_name), "w")
for i in range(len(offsets)):
try:
file_str = pac_str[offsets[i]:offsets[i+1]]
except IndexError:
file_str = pac_str[offsets[i]:]
if "DDS" in file_str[4:] and "PAC" not in file_str and "PNST" not in file_str:
print "%X" % offsets[i]
PTX(file_str, "%s_%.3d" % (pac_name, i), pac_name)
index_file.write("%s folder\n" % ("%s_%.3d"% (pac_name, i)))
else:
index_file.write("%s_%.3d.%s\n" % (pac_name, i,getType(file_str)))
print "Writing: %s_%3d.%s" % (pac_name, i,getType(file_str))
try:
file_open = open("%s/%s_%.3d.%s" % (pac_name,pac_name, i,getType(file_str)), "wb")
file_open.write(file_str)
file_open.close()
except:
print "Error Writing %s" % ("%s_%.3i.%s" % (pac_name, i,getType(file_str)))
index_file.close()
print "\nAll Done!"
return 0
main()

392
PacInject.c

@ -1,196 +1,196 @@ @@ -1,196 +1,196 @@
/*DMC 3 Pac injector
* coded by James
*
* Intent for an unstable repacker
* too many exceptions, so injecting is simpler
* -James
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 512
int filesize(FILE *fil) {
int size;
fseek(fil, 0, SEEK_END);
size = ftell(fil);
fseek(fil, 0, SEEK_SET);
return(size);
}
//get unsigned int,
unsigned int GETINT(unsigned char *ptr) {
return((unsigned int)((ptr[3]<<24)|(ptr[2]<<16)|(ptr[1]<<8)|ptr[0]));
}
//Main
int main(int argc, char *argv[]) {
//Greeting and opening statements
printf("\n=================================\nDevil May Cry 3 \nPAC Injector\nvBETA\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n\n");
char *pac_file, *inj_file, *outfile;
int pos;
//if not enough args, exit with usage
if (argc < 4) {
printf("Usage: %s [Pac File] [Inject File] [Position] {outfile}\nif no outfile given, replaces [Pac File]\n", argv[0]);
return(-1);
} else {
pac_file = argv[1];
inj_file = argv[2];
pos = atoi(argv[3])+1;
//if no output, it replaces input
if (argc < 5) {
outfile = pac_file;
} else {
outfile = argv[4];
}
}
//if can't open, exit
printf("Opening: %s\n", pac_file);
FILE *pac_open;
if (!(pac_open = fopen(pac_file, "rb"))) {
printf("Error Opening %s\n", pac_file);
return(-1);
}
//if can't get size, exit
unsigned int size;
if (!(size = filesize(pac_open))) {
printf("Error Getting File Size\n");
return(-1);
}
//if not enough memory, exit
char *buffer;
if (!(buffer = malloc(size))) {
printf("Not Enough Memory\n");
return(-1);
}
//if can't read, exit
printf("Reading: %s\n", pac_file);
if (!(fread(buffer, 1, size, pac_open))) {
printf("Error Reading %s\n", pac_file);
return(-1);
}
fclose(pac_open); //close
//if can't get number of files, probably invalid file.
//exit
unsigned int num_files;
if (!(num_files = GETINT(buffer+4))) {
printf("Error Getting Filecount\n");
return(-1);
} else { //print the amount of files
printf("\nNumber of Files: %d\n", num_files);
}
//if the position is out of range
if (pos > num_files) {
printf("Indexed out of range: %d\n", pos-1);
return(-1);
}
//old file length, new file length, offset of the file
unsigned int old_len, new_len, offset;
if (!(offset = GETINT(buffer+((pos+1)*4)))) {
printf("Error Getting Offsets\n");
return(-1);
} else if (!(offset)) {
printf("Inavlid Position!\nNull Value @ 0x%X\n", pos);
} else {
printf("File @ 0x%X\n", offset);
}
//it's file after offset minus file offset
old_len = (GETINT(buffer +((pos+2)*4))) - (GETINT(buffer +((pos+1)*4)));
if (!(old_len)) { //if last file, it's size minus file offset
printf("%d", size);
old_len = size - (GETINT(buffer +((pos+1)*4)));
}
//injected file
//if can't open, exit
FILE *inj_open;
printf("\nOpening: %s\n", inj_file);
if (!(inj_open = fopen(inj_file, "rb"))) {
printf("Error Opening %s\n", inj_file);
return(-1);
}
//if can't get size, exit
if (!(new_len = filesize(inj_open))) {
printf("Error Getting File Size\n");
return(-1);
}
//if not enough memory, exit
char *inj;
if (!(inj = malloc(new_len))) {
printf("Not Enough Memory\n");
return(-1);
}
//if can't read, exit
printf("Reading: %s\n", inj_file);
if(!(fread(inj, 1, new_len, inj_open))) {
printf("Error Reading %s", inj_file);
return(-1);
}
fclose(inj_open); //close it
//output file
//Header
//if can't open, exit
FILE *outopen;
printf("\nOpening: %s\n", outfile);
if (!(outopen = fopen(outfile, "wb"))) {
printf("Error Opening %s\n", outfile);
return(-1);
}
//if can't write, exit
printf("\tWriting Header...");
if(!(fwrite(buffer, 1, (pos+2)*4, outopen))) {
printf("\nError Writing %s\n", outfile);
return(-1);
}
//get the end of header
int header_end = (num_files+2)*4;
int i, off;
//correct offsets of following pointers
for (i=pos; i<num_files; i++) {
off = ((GETINT(buffer + ((i+2)*4))) != 0) ? (GETINT(buffer + ((i+2)*4))) + (new_len-old_len) : 0;
fwrite(&off, 1, 4, outopen);
}
printf("Done\n");
//BODY
printf("\tWriting Body...");
//write after header, to offset
fwrite(buffer+header_end, 1, offset-header_end, outopen);
int end = offset+old_len; //end of old file
//write the inject file
fwrite(inj, 1, new_len, outopen);
//write past the old file
fwrite(buffer+end, 1, size-end, outopen);
printf("Done\n");
fclose(outopen); //close
//All Done!
printf("\nAll Done!\n");
return(0);
}
/*DMC 3 Pac injector
* coded by James
*
* Intent for an unstable repacker
* too many exceptions, so injecting is simpler
* -James
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 512
int filesize(FILE *fil) {
int size;
fseek(fil, 0, SEEK_END);
size = ftell(fil);
fseek(fil, 0, SEEK_SET);
return(size);
}
//get unsigned int,
unsigned int GETINT(unsigned char *ptr) {
return((unsigned int)((ptr[3]<<24)|(ptr[2]<<16)|(ptr[1]<<8)|ptr[0]));
}
//Main
int main(int argc, char *argv[]) {
//Greeting and opening statements
printf("\n=================================\nDevil May Cry 3 \nPAC Injector\nvBETA\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n\n");
char *pac_file, *inj_file, *outfile;
int pos;
//if not enough args, exit with usage
if (argc < 4) {
printf("Usage: %s [Pac File] [Inject File] [Position] {outfile}\nif no outfile given, replaces [Pac File]\n", argv[0]);
return(-1);
} else {
pac_file = argv[1];
inj_file = argv[2];
pos = atoi(argv[3])+1;
//if no output, it replaces input
if (argc < 5) {
outfile = pac_file;
} else {
outfile = argv[4];
}
}
//if can't open, exit
printf("Opening: %s\n", pac_file);
FILE *pac_open;
if (!(pac_open = fopen(pac_file, "rb"))) {
printf("Error Opening %s\n", pac_file);
return(-1);
}
//if can't get size, exit
unsigned int size;
if (!(size = filesize(pac_open))) {
printf("Error Getting File Size\n");
return(-1);
}
//if not enough memory, exit
char *buffer;
if (!(buffer = malloc(size))) {
printf("Not Enough Memory\n");
return(-1);
}
//if can't read, exit
printf("Reading: %s\n", pac_file);
if (!(fread(buffer, 1, size, pac_open))) {
printf("Error Reading %s\n", pac_file);
return(-1);
}
fclose(pac_open); //close
//if can't get number of files, probably invalid file.
//exit
unsigned int num_files;
if (!(num_files = GETINT(buffer+4))) {
printf("Error Getting Filecount\n");
return(-1);
} else { //print the amount of files
printf("\nNumber of Files: %d\n", num_files);
}
//if the position is out of range
if (pos > num_files) {
printf("Indexed out of range: %d\n", pos-1);
return(-1);
}
//old file length, new file length, offset of the file
unsigned int old_len, new_len, offset;
if (!(offset = GETINT(buffer+((pos+1)*4)))) {
printf("Error Getting Offsets\n");
return(-1);
} else if (!(offset)) {
printf("Inavlid Position!\nNull Value @ 0x%X\n", pos);
} else {
printf("File @ 0x%X\n", offset);
}
//it's file after offset minus file offset
old_len = (GETINT(buffer +((pos+2)*4))) - (GETINT(buffer +((pos+1)*4)));
if (!(old_len)) { //if last file, it's size minus file offset
printf("%d", size);
old_len = size - (GETINT(buffer +((pos+1)*4)));
}
//injected file
//if can't open, exit
FILE *inj_open;
printf("\nOpening: %s\n", inj_file);
if (!(inj_open = fopen(inj_file, "rb"))) {
printf("Error Opening %s\n", inj_file);
return(-1);
}
//if can't get size, exit
if (!(new_len = filesize(inj_open))) {
printf("Error Getting File Size\n");
return(-1);
}
//if not enough memory, exit
char *inj;
if (!(inj = malloc(new_len))) {
printf("Not Enough Memory\n");
return(-1);
}
//if can't read, exit
printf("Reading: %s\n", inj_file);
if(!(fread(inj, 1, new_len, inj_open))) {
printf("Error Reading %s", inj_file);
return(-1);
}
fclose(inj_open); //close it
//output file
//Header
//if can't open, exit
FILE *outopen;
printf("\nOpening: %s\n", outfile);
if (!(outopen = fopen(outfile, "wb"))) {
printf("Error Opening %s\n", outfile);
return(-1);
}
//if can't write, exit
printf("\tWriting Header...");
if(!(fwrite(buffer, 1, (pos+2)*4, outopen))) {
printf("\nError Writing %s\n", outfile);
return(-1);
}
//get the end of header
int header_end = (num_files+2)*4;
int i, off;
//correct offsets of following pointers
for (i=pos; i<num_files; i++) {
off = ((GETINT(buffer + ((i+2)*4))) != 0) ? (GETINT(buffer + ((i+2)*4))) + (new_len-old_len) : 0;
fwrite(&off, 1, 4, outopen);
}
printf("Done\n");
//BODY
printf("\tWriting Body...");
//write after header, to offset
fwrite(buffer+header_end, 1, offset-header_end, outopen);
int end = offset+old_len; //end of old file
//write the inject file
fwrite(inj, 1, new_len, outopen);
//write past the old file
fwrite(buffer+end, 1, size-end, outopen);
printf("Done\n");
fclose(outopen); //close
//All Done!
printf("\nAll Done!\n");
return(0);
}

320
PacRepack.py

@ -1,161 +1,161 @@ @@ -1,161 +1,161 @@
#Pac Repacker
#Coded by James
#import
import sys
from struct import pack
#get the files from the index
def getFiles(index_file, folder):
line = index_file.readline().strip()
files = []
while line != "":
#if there's a sub PTX archive, repack it first
#then add a ptx file to the files array
if line[-6:] == "folder":
PTX(line[:-7], folder)
files.append("%s.ptx" % line[:-7])
else:
print "%s" % line
files.append(line)
line = index_file.readline().strip()
return files #this value is an array of all the filenames
#Another version of getFiles, for PTX usage
def getFilesPTX(index_file):
line = index_file.readline().strip()
files = []
while line != "":
print "\t%s" % line
files.append(line)
line = index_file.readline().strip()
return files
#repacks a PTX archive
def PTX(file, folder):
print "\nRepacking PTX Archive: %s" % file
try:
index_file = open("%s\\%s\\%s.index" % (folder, file, file), "r")
except:
print "Error Reading %s.index from PTX folder %s" % (file, file)
files = getFilesPTX(index_file)
num_files = len(files)
header = pack("<I", num_files)
body = ""
trailer_open = open("%s\\%s.trail" % (folder, file), "rb")
#trailer_open.seek(2048)
trailer = trailer_open.read(2160)
outfile = open("%s\\%s.ptx" % (folder, file), "wb")
for i in range(num_files):
bin_open = open("%s\\%s\\%s" % (folder, file, files[i]), "rb")
bin_str = bin_open.read()
header += pack("<I", len(bin_str)/1024/2)
body += bin_str
header += ("00000000".decode("hex"))*(513-num_files) + trailer #cushion
outfile.write(header+body)
print ""
return 0
#make the body of the pac file
def MakeBody(files, folder):
header = "PAC" + "00".decode("hex") #default
body = ""
num_files = len(files)
pointers = [0] #starting position
for i in range(num_files):
file_open = open("%s\\%s" % (folder, files[i]), "rb")
body += file_open.read()
pointers.append(len(body))
del pointers[-1] #delete file size marker
header_len = (num_files * 4) + 8
while header_len%16: #if header isn't divisible by 16, make it
header_len += 4
for i in range((header_len-8)/4):
try:
pointers[i] = pointers[i] + header_len #correct the pointers
except IndexError:
pointers.append(0)
#odd rule
if pointers[-1] == 0 and pointers[-2] == 0 and pointers[-3] == 0:
pointers[-3] = pointers[0]
#another odd rule, size can't be 20
if len(pointers) == 42:
pointers.append(0)
pointers.append(0)
pointers.append(pointers[0])
pointers.append(0)
num_files += 2
for i in range(len(pointers)):
pointers[i] = pointers[i] + ((len(pointers)*4)-(header_len-8)) if pointers[i] else 0#correct the pointers
header += pack("<I", num_files)
for point in pointers:
header += pack("<I", point)
return header+body
def main():
#greetings
print "\n=================================\nDevil May Cry 3 \nPac Repacker\nvBETA\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n"
#if not enough args, usage
if len(sys.argv) < 2:
print "Usage: %s [folder] {outfile}\nif no outfile given, outfile is [folder].pac" % sys.argv[0]
return -1
else:
folder = sys.argv[1] #folder
try:
pac_file = sys.argv[2] #name of file if sufficient args
except IndexError:
pac_file = "%s.pac" % folder #else it's [folder].pac
#if can't open, exit
print "Opening: %s.index" % folder
try:
index_file = open("%s\\%s.index" % (folder, folder), "r")
except:
print "Error Opening %s.index" % folder
return -1
#if can't read, exit
print "Reading: %s.index\n" % folder
try:
files = getFiles(index_file, folder)
except:
print "Error Reading %s.index" % folder
return -1
#contents
pac = MakeBody(files, folder)
#if can't open output, exit
print "\nOpening: %s" % pac_file
try:
pac_open = open(pac_file, "wb")
except:
print "Error Opening %s" % pac_file
return -1
#if can't write output, exit
print "Writing: %s" % pac_file
try:
pac_open.write(pac)
except:
print "Error Writing %s" % pac_file
return -1
#all done!
print "\nAll Done!"
return 0
#Pac Repacker
#Coded by James
#import
import sys
from struct import pack
#get the files from the index
def getFiles(index_file, folder):
line = index_file.readline().strip()
files = []
while line != "":
#if there's a sub PTX archive, repack it first
#then add a ptx file to the files array
if line[-6:] == "folder":
PTX(line[:-7], folder)
files.append("%s.ptx" % line[:-7])
else:
print "%s" % line
files.append(line)
line = index_file.readline().strip()
return files #this value is an array of all the filenames
#Another version of getFiles, for PTX usage
def getFilesPTX(index_file):
line = index_file.readline().strip()
files = []
while line != "":
print "\t%s" % line
files.append(line)
line = index_file.readline().strip()
return files
#repacks a PTX archive
def PTX(file, folder):
print "\nRepacking PTX Archive: %s" % file
try:
index_file = open("%s\\%s\\%s.index" % (folder, file, file), "r")
except:
print "Error Reading %s.index from PTX folder %s" % (file, file)
files = getFilesPTX(index_file)
num_files = len(files)
header = pack("<I", num_files)
body = ""
trailer_open = open("%s\\%s.trail" % (folder, file), "rb")
#trailer_open.seek(2048)
trailer = trailer_open.read(2160)
outfile = open("%s\\%s.ptx" % (folder, file), "wb")
for i in range(num_files):
bin_open = open("%s\\%s\\%s" % (folder, file, files[i]), "rb")
bin_str = bin_open.read()
header += pack("<I", len(bin_str)/1024/2)
body += bin_str
header += ("00000000".decode("hex"))*(513-num_files) + trailer #cushion
outfile.write(header+body)
print ""
return 0
#make the body of the pac file
def MakeBody(files, folder):
header = "PAC" + "00".decode("hex") #default
body = ""
num_files = len(files)
pointers = [0] #starting position
for i in range(num_files):
file_open = open("%s\\%s" % (folder, files[i]), "rb")
body += file_open.read()
pointers.append(len(body))
del pointers[-1] #delete file size marker
header_len = (num_files * 4) + 8
while header_len%16: #if header isn't divisible by 16, make it
header_len += 4
for i in range((header_len-8)/4):
try:
pointers[i] = pointers[i] + header_len #correct the pointers
except IndexError:
pointers.append(0)
#odd rule
if pointers[-1] == 0 and pointers[-2] == 0 and pointers[-3] == 0:
pointers[-3] = pointers[0]
#another odd rule, size can't be 20
if len(pointers) == 42:
pointers.append(0)
pointers.append(0)
pointers.append(pointers[0])
pointers.append(0)
num_files += 2
for i in range(len(pointers)):
pointers[i] = pointers[i] + ((len(pointers)*4)-(header_len-8)) if pointers[i] else 0#correct the pointers
header += pack("<I", num_files)
for point in pointers:
header += pack("<I", point)
return header+body
def main():
#greetings
print "\n=================================\nDevil May Cry 3 \nPac Repacker\nvBETA\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n"
#if not enough args, usage
if len(sys.argv) < 2:
print "Usage: %s [folder] {outfile}\nif no outfile given, outfile is [folder].pac" % sys.argv[0]
return -1
else:
folder = sys.argv[1] #folder
try:
pac_file = sys.argv[2] #name of file if sufficient args
except IndexError:
pac_file = "%s.pac" % folder #else it's [folder].pac
#if can't open, exit
print "Opening: %s.index" % folder
try:
index_file = open("%s\\%s.index" % (folder, folder), "r")
except:
print "Error Opening %s.index" % folder
return -1
#if can't read, exit
print "Reading: %s.index\n" % folder
try:
files = getFiles(index_file, folder)
except:
print "Error Reading %s.index" % folder
return -1
#contents
pac = MakeBody(files, folder)
#if can't open output, exit
print "\nOpening: %s" % pac_file
try:
pac_open = open(pac_file, "wb")
except:
print "Error Opening %s" % pac_file
return -1
#if can't write output, exit
print "Writing: %s" % pac_file
try:
pac_open.write(pac)
except:
print "Error Writing %s" % pac_file
return -1
#all done!
print "\nAll Done!"
return 0
main()

150
ReadMe.txt

@ -1,75 +1,75 @@ @@ -1,75 +1,75 @@
=================================
Devil May Cry 3
Pac extractor
vBETA
Coded by James aka Jamesuminator
=================================
---------------------------------
Usage: PacExtract [file]
Extracts Contents of a DMC3 PAC
======================================================================
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Pac Extractor
coded by James
Extracts PAC archives, the following filetypes have made up names
so (named after the the header, which is "60 00")
any other name is taken from the header.
----------------------
=================================
Devil May Cry 3
Pac Repacker
vBETA
Coded by James aka Jamesuminator
=================================
---------------------------------
Usage: PacRepack [folder] {outfile}
if no outfile given, outfile is [folder].pac
====================================================================
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Pac Repacker
coded by James
Will not repack a "PNST" header
May have some errors on some files*
Trouble with some PTX's
*Very odd exceptions.
----------------------
=================================
Devil May Cry 3
PAC Injector
vBETA
Coded by James aka Jamesuminator
=================================
---------------------------------
Usage: PacInject.exe [Pac File] [Inject File] [Position] {outfile}
if no outfile given, replaces [Pac File]
======================================================================
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Pac Injector
coded by James
Works perfectly.
Has no support for TIM2 injection.
Must inject PTX archives.
NOTE: no Dlls needed, total stand alone
More Apps included
All Beta
=================================
Devil May Cry 3
Pac extractor
vBETA
Coded by James aka Jamesuminator
=================================
---------------------------------
Usage: PacExtract [file]
Extracts Contents of a DMC3 PAC
======================================================================
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Pac Extractor
coded by James
Extracts PAC archives, the following filetypes have made up names
so (named after the the header, which is "60 00")
any other name is taken from the header.
----------------------
=================================
Devil May Cry 3
Pac Repacker
vBETA
Coded by James aka Jamesuminator
=================================
---------------------------------
Usage: PacRepack [folder] {outfile}
if no outfile given, outfile is [folder].pac
====================================================================
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Pac Repacker
coded by James
Will not repack a "PNST" header
May have some errors on some files*
Trouble with some PTX's
*Very odd exceptions.
----------------------
=================================
Devil May Cry 3
PAC Injector
vBETA
Coded by James aka Jamesuminator
=================================
---------------------------------
Usage: PacInject.exe [Pac File] [Inject File] [Position] {outfile}
if no outfile given, replaces [Pac File]
======================================================================
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Pac Injector
coded by James
Works perfectly.
Has no support for TIM2 injection.
Must inject PTX archives.
NOTE: no Dlls needed, total stand alone
More Apps included
All Beta

360
scanPAC.c

@ -1,180 +1,180 @@ @@ -1,180 +1,180 @@
#include <stdio.h>
#include <stdlib.h>
#define MAX 512
typedef unsigned int uint;
//get filesize
int filesize(FILE *fil) {
int size;
fseek(fil, 0, SEEK_END);
size = ftell(fil);
fseek(fil, 0, SEEK_SET);
return(size);
}
//get unsigned int,
unsigned int GETINT(unsigned char *ptr) {
return((unsigned int)((ptr[3]<<24)|(ptr[2]<<16)|(ptr[1]<<8)|ptr[0]));
}
//big endian
unsigned int TYPEINT(unsigned char *ptr) {
return((unsigned int)((ptr[0]<<24)|(ptr[1]<<16)|(ptr[2]<<8)|ptr[3]));
}
int getType(char *ptr, char *type) {
//test for PTX
uint ptx_count = GETINT(ptr);
if ( !(GETINT(ptr + (ptx_count*4)+8)) || ptx_count == 511 || ptx_count == 512 ) {
snprintf(type, 512, "%s", "PTX");
return(1);
}
uint test = TYPEINT(ptr);
switch( test ) {
case 0x4D4F4420:
//type = "MOD";
sprintf(type, "%s", "MOD");
break;
case 0x54494D32:
//type = "TIM2";
sprintf(type, "%s", "TIM2");
break;
case 0x53485720:
//type = "SHW";
sprintf(type, "%s", "SHW");
break;
case 0x50000000:
//type = "MOT";
sprintf(type, "%s", "MOT");
break;
case 0x50414300:
//type = "PAC";
sprintf(type, "%s", "PAC");
break;
case 0x504E5354:
//type = "PNST";
sprintf(type, "%s", "PNST");
break;
case 0x4F676753:
//type = "Ogg";
sprintf(type, "%s", "OGG");
break;
case 0x424D3600:
//type = "BM6";
sprintf(type, "%s", "BM6");
break;
case 0x000001BA:
//type = "MPG";
sprintf(type, "%s", "MPG");
break;
case 0x4C494732:
//type = "LIG2";
sprintf(type, "%s", "LIG2");
break;
case 0x53454600:
//type = "SEF";
sprintf(type, "%s", "SEF");
break;
case 0x43414d00:
//type = "CAM";
sprintf(type, "%s", "CAM");
break;
case 0x45564500:
//type = "EVE";
sprintf(type, "%s", "EVE");
break;
case 0x504F5300:
//type = "POS";
sprintf(type, "%s", "POS");
break;
case 0xEFBBBF23:
//type = "TXT";
sprintf(type, "%s", "TXT");
break;
case 0x00000000:
//type = "BD";
sprintf(type, "%s", "BD");
break;
case 0x00000100: