upload files

This commit is contained in:
Collin
2026-02-17 22:43:40 +01:00
commit 698d6f6121
37 changed files with 3000 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.36422.26
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GTASPRXPS4", "GTASPRXPS4.vcxproj", "{82CE3C65-C144-4D91-8A5B-324A963546C3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ORBIS = Debug|ORBIS
Release|ORBIS = Release|ORBIS
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{82CE3C65-C144-4D91-8A5B-324A963546C3}.Debug|ORBIS.ActiveCfg = Debug|ORBIS
{82CE3C65-C144-4D91-8A5B-324A963546C3}.Debug|ORBIS.Build.0 = Debug|ORBIS
{82CE3C65-C144-4D91-8A5B-324A963546C3}.Release|ORBIS.ActiveCfg = Release|ORBIS
{82CE3C65-C144-4D91-8A5B-324A963546C3}.Release|ORBIS.Build.0 = Release|ORBIS
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2A7492B0-84F4-4E66-8BCA-1CF48EB16BC0}
EndGlobalSection
EndGlobal
+96
View File
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ORBIS">
<Configuration>Debug</Configuration>
<Platform>ORBIS</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ORBIS">
<Configuration>Release</Configuration>
<Platform>ORBIS</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{82ce3c65-c144-4d91-8a5b-324a963546c3}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ORBIS'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ORBIS'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup Condition="'$(DebuggerFlavor)'=='ORBISDebugger'" Label="OverrideDebuggerDefaults">
<!--LocalDebuggerCommand>$(TargetPath)</LocalDebuggerCommand-->
<!--LocalDebuggerCommandArguments></LocalDebuggerCommandArguments-->
<!--LocalDebuggerTarget></LocalDebuggerTarget-->
<!--LocalDebuggerWorkingDirectory>$(ProjectDir)</LocalDebuggerWorkingDirectory-->
<!--LocalRunCommandLine></LocalRunCommandLine-->
</PropertyGroup>
<ImportGroup Label="ExtensionSettings">
<Import Condition="Exists('$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.props')" Project="$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.props" />
<Import Condition="Exists('$(VCTargetsPath)\BuildCustomizations\SCU.props')" Project="$(VCTargetsPath)\BuildCustomizations\SCU.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ORBIS'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ORBIS'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ORBIS'">
<TargetName>GTAServer</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ORBIS'">
<TargetName>GTAServer</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ORBIS'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions);</PreprocessorDefinitions>
<GenerateDebugInformation>true</GenerateDebugInformation>
</ClCompile>
<Link>
<Addressing>NonAslr</Addressing>
<AdditionalDependencies>$(SCE_ORBIS_SDK_DIR)\target\lib\libSceImeDialog_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceSysmodule_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceMsgDialog_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceCommonDialog_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceSystemService_stub.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceSystemService_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libScePosix_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceNet_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceHttp_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libScePad_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceUserService_stub_weak.a;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>cd /d "$(TargetDir)"
call "$(TargetDir)make_sprx.bat"
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ORBIS'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions);</PreprocessorDefinitions>
<OptimizationLevel>Level2</OptimizationLevel>
</ClCompile>
<PostBuildEvent>
<Command>cd /d "$(TargetDir)"
call "$(TargetDir)make_sprx.bat"
</Command>
</PostBuildEvent>
<Link>
<AdditionalDependencies>$(SCE_ORBIS_SDK_DIR)\target\lib\libSceImeDialog_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceSysmodule_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceMsgDialog_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceCommonDialog_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceSystemService_stub.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceSystemService_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libScePosix_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceNet_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceHttp_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libScePad_stub_weak.a;$(SCE_ORBIS_SDK_DIR)\target\lib\libSceUserService_stub_weak.a;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="prx.cpp" />
<ClCompile Include="Syscall.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Syscall.h" />
</ItemGroup>
<Import Condition="'$(ConfigurationType)' == 'Makefile' and Exists('$(VCTargetsPath)\Platforms\$(Platform)\SCE.Makefile.$(Platform).targets')" Project="$(VCTargetsPath)\Platforms\$(Platform)\SCE.Makefile.$(Platform).targets" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Condition="Exists('$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.targets')" Project="$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.targets" />
<Import Condition="Exists('$(VCTargetsPath)\BuildCustomizations\SCU.targets')" Project="$(VCTargetsPath)\BuildCustomizations\SCU.targets" />
</ImportGroup>
</Project>
+30
View File
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;cc;s;asm</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;pssli</Extensions>
</Filter>
<Filter Include="Shader Files">
<UniqueIdentifier>{5FAE8098-8EE5-44A0-ABB6-C797B807CDE6}</UniqueIdentifier>
<Extensions>pssl;scu</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="prx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Syscall.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Syscall.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
+30
View File
@@ -0,0 +1,30 @@
prx.cpp
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(257,12): warning : unused variable 'g_user_logged_in' [-Wunused-variable]
static int g_user_logged_in = 0;
^
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(258,29): warning : unused variable 'g_user_id' [-Wunused-variable]
static SceUserServiceUserId g_user_id = 1;
^
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(259,12): warning : unused variable 'g_login_event_pending' [-Wunused-variable]
static int g_login_event_pending = 1;
^
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(260,12): warning : unused variable 'g_logout_event_pending' [-Wunused-variable]
static int g_logout_event_pending = 0;
^
4 warnings generated.
orbis-ld 4.50.0.4213 (rel,orbis,4.500 @342832 x64) C:\Program Files (x86)\SCE\ORBIS SDKs\4.500\host_tools\bin\orbis-ld.exe
Command line : warning : L0474: The --addressing=<mode> option only applies to main modules and will be ignored
GTASPRXPS4.vcxproj -> C:\Users\DontCry361x\Documents\GTASPRXPS4\ORBIS_Debug\GTAServer.prx
[INFO] Running fself.py ...
loading elf file: GTAServer.prx
saving fake signed elf file: test.sprx
processing segment #00...
processing segment #01...
processing segment #02...
processing segment #07...
processing segment #08...
done
[OK] SPRX created.
[INFO] Uploading to PS4...
Connecting to 192.168.137.241:2121 ...
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(148,5): warning MSB5021: Terminating the task executable "cmd" and its child processes because the build was canceled.
@@ -0,0 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=Clang:EnableManagedIncrementalBuild=:VCToolArchitecture=:WindowsTargetPlatformVersion=
Debug|ORBIS|C:\Users\DontCry361x\Documents\GTASPRXPS4\|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+816
View File
@@ -0,0 +1,816 @@
#!/usr/bin/env python
import sys, os, struct, traceback
import hashlib, hmac
import argparse, re, string
def int_with_base_type(val):
return int(val, 0)
def try_parse_int(x, base=0):
try:
return int(x, base) if isinstance(x, str) else int(x)
except:
return None
def align_up(x, alignment):
return (x + (alignment - 1)) & ~(alignment - 1)
def align_down(x, alignment):
return x & ~(alignment - 1)
def ilog2(x):
if x <= 0:
raise ValueError('math domain error')
return len(bin(x)) - 3
def is_intervals_overlap(p1, p2):
return p1[0] <= p2[1] and p1[1] <= p2[0]
def check_file_magic(f, expected_magic):
old_offset = f.tell()
try:
magic = f.read(len(expected_magic))
except:
return False
finally:
f.seek(old_offset)
return magic == expected_magic
def parse_version(version):
major, minor, patch = (version >> 8) & 0xFF, version & 0xFF, 0 # FIXME
major = 10 * (major >> 4) + (major & 0xF)
minor = 10 * (minor >> 4) + (minor & 0xF)
return '{0:d}.{1:02d}.{2:03d}'.format(major, minor, patch)
def sha256(data):
return hashlib.sha256(data).digest()
def hmac_sha256(key, data):
return hmac.new(key=key, msg=data, digestmod=hashlib.sha256).digest()
class ElfError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return repr(self.msg)
class ElfEHdr(object):
FMT = '<4s5B6xB'
EX_FMT = '<2HI3QI6H'
MAGIC = '\x7FELF'
CLASS64 = 0x2
DATA2LSB = 0x1
EM_X86_64 = 0x3E
EV_CURRENT = 0x1
ET_EXEC = 0x2
ET_SCE_EXEC = 0xFE00
ET_SCE_EXEC_ASLR = 0xFE10
ET_SCE_DYNAMIC = 0xFE18
def __init__(self):
self.magic = None
self.machine_class = None
self.data_encoding = None
self.version = None
self.os_abi = None
self.abi_version = None
self.nident_size = None
self.type = None
self.machine = None
self.version = None
self.entry = None
self.phoff = None
self.shoff = None
self.flags = None
self.ehsize = None
self.phentsize = None
self.phnum = None
self.shentsize = None
self.shnum = None
self.shstridx = None
def load(self, f):
if not check_file_magic(f, ElfEHdr.MAGIC):
raise ElfError('Invalid magic.')
self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size = struct.unpack(ElfEHdr.FMT, f.read(struct.calcsize(ElfEHdr.FMT)))
if self.machine_class != ElfEHdr.CLASS64 or self.data_encoding != ElfEHdr.DATA2LSB:
raise ElfError('Unsupported class or data encoding.')
self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx = struct.unpack(ElfEHdr.EX_FMT, f.read(struct.calcsize(ElfEHdr.EX_FMT)))
if self.machine != ElfEHdr.EM_X86_64 or self.version != ElfEHdr.EV_CURRENT:
raise ElfError('Unsupported machine type or version.')
if self.phentsize != struct.calcsize(ElfPHdr.FMT) or (self.shentsize > 0 and self.shentsize != struct.calcsize(ElfSHdr.FMT)):
raise ElfError('Unsupported header entry size.')
if self.type not in [ElfEHdr.ET_EXEC, ElfEHdr.ET_SCE_EXEC, ElfEHdr.ET_SCE_EXEC_ASLR, ElfEHdr.ET_SCE_DYNAMIC]:
raise ElfError('Unsupported type.')
def save(self, f):
f.write(struct.pack(ElfEHdr.FMT, self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size))
f.write(struct.pack(ElfEHdr.EX_FMT, self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx))
def has_segments(self):
return self.phentsize > 0 and self.phnum > 0
def has_sections(self):
return self.shentsize > 0 and self.shnum > 0
class ElfPHdr(object):
FMT = '<2I6Q'
PT_LOAD = 0x1
PT_DYNAMIC = 0x2
PT_INTERP = 0x3
PT_TLS = 0x7
PT_GNU_EH_FRAME = 0x6474E550
PT_GNU_STACK = 0x6474E551
PT_SCE_RELA = 0x60000000,
PT_SCE_DYNLIBDATA = 0x61000000
PT_SCE_PROCPARAM = 0x61000001
PT_SCE_MODULE_PARAM = 0x61000002
PT_SCE_RELRO = 0x61000010
PT_SCE_COMMENT = 0x6FFFFF00
PT_SCE_VERSION = 0x6FFFFF01
PF_EXEC = 0x1
PF_WRITE = 0x2
PF_READ = 0x4
PF_READ_EXEC = PF_READ | PF_EXEC
PF_READ_WRITE = PF_READ | PF_WRITE
def __init__(self, idx):
self.idx = idx
self.type = None
self.flags = None
self.offset = None
self.vaddr = None
self.paddr = None
self.filesz = None
self.memsz = None
self.align = None
def load(self, f):
self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align = struct.unpack(ElfPHdr.FMT, f.read(struct.calcsize(ElfPHdr.FMT)))
def save(self, f):
f.write(struct.pack(ElfPHdr.FMT, self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align))
def name(self):
if self.type == ElfPHdr.PT_LOAD:
if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC:
return '.text'
elif (self.flags & ElfPHdr.PF_READ_WRITE) == ElfPHdr.PF_READ_WRITE:
return '.data'
else:
return '.load_{0:02}'.format(self.idx)
else:
return {
ElfPHdr.PT_DYNAMIC: '.dynamic',
ElfPHdr.PT_INTERP: '.interp',
ElfPHdr.PT_TLS: '.tls',
ElfPHdr.PT_GNU_EH_FRAME: '.eh_frame_hdr',
ElfPHdr.PT_SCE_DYNLIBDATA: '.sce_dynlib_data',
ElfPHdr.PT_SCE_PROCPARAM: '.sce_process_param',
ElfPHdr.PT_SCE_MODULE_PARAM: '.sce_module_param',
ElfPHdr.PT_SCE_COMMENT: '.sce_comment',
}.get(self.type, None)
def class_name(self):
if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC:
return 'CODE'
else:
return 'DATA'
class ElfSHdr(object):
FMT = '<2I4Q2I2Q'
def __init__(self, idx):
self.idx = idx
self.name = None
self.type = None
self.flags = None
self.addr = None
self.offset = None
self.size = None
self.link = None
self.info = None
self.align = None
self.entsize = None
def load(self, f):
self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize = struct.unpack(ElfSHdr.FMT, f.read(struct.calcsize(ElfSHdr.FMT)))
def save(self, f):
f.write(struct.pack(ElfSHdr.FMT, self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize))
class ElfFile(object):
def __init__(self, **kwargs):
self.ehdr = None
self.phdrs = None
self.shdrs = None
self.file_size = None
self.digest = None
self.segments = None
self.sections = None
self.ignore_shdrs = 'ignore_shdrs' in kwargs and kwargs['ignore_shdrs']
def load(self, f):
start_offset = f.tell()
data = f.read()
self.file_size = len(data)
self.digest = sha256(data)
f.seek(start_offset)
self.ehdr = ElfEHdr()
self.ehdr.load(f)
if self.ignore_shdrs:
self.ehdr.shnum = 0
self.phdrs = []
self.segments = []
if self.ehdr.has_segments():
for i in xrange(self.ehdr.phnum):
f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize)
phdr = ElfPHdr(i)
phdr.load(f)
self.phdrs.append(phdr)
if phdr.filesz > 0:
f.seek(start_offset + phdr.offset)
data = f.read(phdr.filesz)
else:
data = ''
self.segments.append(data)
self.shdrs = []
self.sections = []
if self.ehdr.has_sections():
for i in xrange(self.ehdr.shnum):
f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize)
shdr = ElfSHdr(i)
shdr.load(f)
self.shdrs.append(shdr)
if phdr.filesz > 0:
f.seek(start_offset + shdr.offset)
data = f.read(phdr.filesz)
else:
data = ''
self.sections.append(data)
def save(self, f, no_sections=False):
start_offset = f.tell()
self.ehdr.save(f)
if not no_sections:
if self.ehdr.has_sections():
for i in xrange(self.ehdr.shnum):
f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize)
shdr = self.shdrs[i]
shdr.save(f)
if self.ehdr.has_segments():
for i in xrange(self.ehdr.phnum):
f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize)
phdr = self.phdrs[i]
phdr.save(f)
DIGEST_SIZE = 0x20
SIGNATURE_SIZE = 0x100
BLOCK_SIZE = 0x4000
DEFAULT_BLOCK_SIZE = 0x1000
SELF_CONTROL_BLOCK_TYPE_NPDRM = 0x3
SELF_NPDRM_CONTROL_BLOCK_CONTENT_ID_SIZE = 0x13
SELF_NPDRM_CONTROL_BLOCK_RANDOM_PAD_SIZE = 0xD
EMPTY_DIGEST = '\0' * DIGEST_SIZE
EMPTY_SIGNATURE = '\0' * SIGNATURE_SIZE
class SignedElfEntry(object):
FMT = '<4Q'
PROPS_ORDER_SHIFT = 0
PROPS_ORDER_MASK = 0x1
PROPS_ENCRYPTED_SHIFT = 1
PROPS_ENCRYPTED_MASK = 0x1
PROPS_SIGNED_SHIFT = 2
PROPS_SIGNED_MASK = 0x1
PROPS_COMPRESSED_SHIFT = 3
PROPS_COMPRESSED_MASK = 0x1
PROPS_WINDOW_BITS_SHIFT = 8
PROPS_WINDOW_BITS_MASK = 0x7
PROPS_HAS_BLOCKS_SHIFT = 11
PROPS_HAS_BLOCKS_MASK = 0x1
PROPS_BLOCK_SIZE_SHIFT = 12
PROPS_BLOCK_SIZE_MASK = 0xF
PROPS_HAS_DIGESTS_SHIFT = 16
PROPS_HAS_DIGESTS_MASK = 0x1
PROPS_HAS_EXTENTS_SHIFT = 17
PROPS_HAS_EXTENTS_MASK = 0x1
PROPS_HAS_META_SEGMENT_SHIFT = 20
PROPS_HAS_META_SEGMENT_MASK = 0x1
PROPS_SEGMENT_INDEX_SHIFT = 20
PROPS_SEGMENT_INDEX_MASK = 0xFFFF
PROPS_DEFAULT_BLOCK_SIZE = 0x1000
PROPS_META_SEGMENT_MASK = 0xF0000
def __init__(self, index):
self.index = index
self.props = None
self.offset = None
self.filesz = None
self.memsz = None
self.data = None
def save(self, f):
f.write(struct.pack(SignedElfEntry.FMT, self.props, self.offset, self.filesz, self.memsz))
@property
def order(self):
return (self.props >> SignedElfEntry.PROPS_ORDER_SHIFT) & SignedElfEntry.PROPS_ORDER_MASK
@order.setter
def order(self, value):
self.props &= ~(SignedElfEntry.PROPS_ORDER_MASK << SignedElfEntry.PROPS_ORDER_SHIFT)
self.props |= (value & SignedElfEntry.PROPS_ORDER_MASK) << SignedElfEntry.PROPS_ORDER_SHIFT
@property
def encrypted(self):
return ((self.props >> SignedElfEntry.PROPS_ENCRYPTED_SHIFT) & SignedElfEntry.PROPS_ENCRYPTED_MASK) != 0
@encrypted.setter
def encrypted(self, value):
self.props &= ~(SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT
@property
def signed(self):
return ((self.props >> SignedElfEntry.PROPS_SIGNED_SHIFT) & SignedElfEntry.PROPS_SIGNED_MASK) != 0
@signed.setter
def signed(self, value):
self.props &= ~(SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT
@property
def compressed(self):
return ((self.props >> SignedElfEntry.PROPS_COMPRESSED_SHIFT) & SignedElfEntry.PROPS_COMPRESSED_MASK) != 0
@compressed.setter
def compressed(self, value):
self.props &= ~(SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT
@property
def has_blocks(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT) & SignedElfEntry.PROPS_HAS_BLOCKS_MASK) != 0
@has_blocks.setter
def has_blocks(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT
@property
def has_digests(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT) & SignedElfEntry.PROPS_HAS_DIGESTS_MASK) != 0
@has_digests.setter
def has_digests(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT
@property
def has_extents(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT) & SignedElfEntry.PROPS_HAS_EXTENTS_MASK) != 0
@has_extents.setter
def has_extents(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT
@property
def has_meta_segment(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT) & SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK) != 0
@has_meta_segment.setter
def has_meta_segment(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT
@property
def wbits(self):
return (self.props >> SignedElfEntry.PROPS_WINDOW_BITS_SHIFT) & SignedElfEntry.PROPS_WINDOW_BITS_MASK
@wbits.setter
def wbits(self, value):
self.props &= ~(SignedElfEntry.PROPS_WINDOW_BITS_MASK << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT)
self.props |= (value & SignedElfEntry.PROPS_WINDOW_BITS_MASK) << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT
@property
def block_size(self):
if self.has_blocks:
return 1 << (12 + (self.props >> SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) & SignedElfEntry.PROPS_BLOCK_SIZE_MASK)
else:
return DEFAULT_BLOCK_SIZE
@block_size.setter
def block_size(self, value):
self.props &= ~(SignedElfEntry.PROPS_BLOCK_SIZE_MASK << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT)
if self.has_blocks:
value = ilog2(value) - 12
else:
value = 0 # TODO: check
self.props |= (value & SignedElfEntry.PROPS_BLOCK_SIZE_MASK) << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT
@property
def segment_index(self):
return (self.props >> SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK
@wbits.setter
def segment_index(self, value):
self.props &= ~(SignedElfEntry.PROPS_SEGMENT_INDEX_MASK << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT)
self.props |= (value & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK) << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT
def is_meta_segment(self): # TODO: check
return (self.props & SignedElfEntry.PROPS_META_SEGMENT_MASK) != 0
def __repr__(self):
return 'prs:0x{0:X} ofs:0x{1:X} fsz:0x{2:X} msz:0x{3:X}'.format(self.props, self.offset, self.filesz, self.memsz)
class SignedElfExInfo(object):
FMT = '<4Q32s'
PTYPE_FAKE = 0x1
PTYPE_NPDRM_EXEC = 0x4
PTYPE_NPDRM_DYNLIB = 0x5
PTYPE_SYSTEM_EXEC = 0x8
PTYPE_SYSTEM_DYNLIB = 0x9 # including Mono binaries
PTYPE_HOST_KERNEL = 0xC
PTYPE_SECURE_MODULE = 0xE
PTYPE_SECURE_KERNEL = 0xF
def __init__(self):
self.paid = None
self.ptype = None
self.app_version = None
self.fw_version = None
self.digest = None
def save(self, f):
f.write(struct.pack(SignedElfExInfo.FMT, self.paid, self.ptype, self.app_version, self.fw_version, self.digest))
class SignedElfNpdrmControlBlock(object):
FMT = '<H14x19s13s'
def __init__(self):
self.type = SELF_CONTROL_BLOCK_TYPE_NPDRM
self.content_id = None
self.random_pad = None
def save(self, f):
f.write(struct.pack(SignedElfNpdrmControlBlock.FMT, self.type, self.content_id, self.random_pad))
class SignedElfMetaBlock(object):
FMT = '<80x'
def __init__(self):
pass
def save(self, f):
f.write(struct.pack(SignedElfMetaBlock.FMT))
class SignedElfMetaFooter(object):
FMT = '<48xI28x'
def __init__(self):
self.unk1 = None
def save(self, f):
f.write(struct.pack(SignedElfMetaFooter.FMT, self.unk1))
class SignedElfFile(object):
COMMON_HEADER_FMT = '<4s4B'
EXT_HEADER_FMT = '<I2HQ2H4x'
MAGIC = '\x4F\x15\x3D\x1D'
VERSION = 0x00
MODE = 0x01
ENDIAN = 0x01
ATTRIBS = 0x12
KEY_TYPE = 0x101
FLAGS_SEGMENT_SIGNED_SHIFT = 4
FLAGS_SEGMENT_SIGNED_MASK = 0x7
HAS_NPDRM = 1
def __init__(self, elf, **kwargs):
self.elf = elf
self.magic = None
self.version = None
self.mode = None
self.endian = None
self.attribs = None
self.key_type = None
self.header_size = None
self.meta_size = None
self.file_size = None
self.num_entries = None
self.flags = None
self.entries = None
self.ex_info = None
self.npdrm_control_block = None
self.meta_blocks = None
self.meta_footer = None
self.signature = None
self.version_data = None
self.paid = kwargs['paid'] if 'paid' in kwargs and not kwargs['paid'] is None else 0x3100000000000002
self.ptype = kwargs['ptype'] if 'ptype' in kwargs and not kwargs['ptype'] is None else SignedElfExInfo.PTYPE_FAKE
self.app_version = kwargs['app_version'] if 'app_version' in kwargs and not kwargs['app_version'] is None else 0
self.fw_version = kwargs['fw_version'] if 'fw_version' in kwargs and not kwargs['fw_version'] is None else 0
self.auth_info = kwargs['auth_info'] if 'auth_info' in kwargs and not kwargs['auth_info'] is None else None
def _prepare(self):
self.magic = SignedElfFile.MAGIC
self.version = SignedElfFile.VERSION
self.mode = SignedElfFile.MODE
self.endian = SignedElfFile.ENDIAN
self.attribs = SignedElfFile.ATTRIBS
self.key_type = SignedElfFile.KEY_TYPE
self.flags = 0x2
signed_block_count = 2
self.flags |= (signed_block_count & SignedElfFile.FLAGS_SEGMENT_SIGNED_MASK) << SignedElfFile.FLAGS_SEGMENT_SIGNED_SHIFT
self.entries = []
entry_idx = 0
for i in xrange(self.elf.ehdr.phnum):
phdr = self.elf.phdrs[i]
if phdr.type == ElfPHdr.PT_SCE_VERSION:
self.version_data = self.elf.segments[i]
if not phdr.type in [ElfPHdr.PT_LOAD, ElfPHdr.PT_SCE_RELRO, ElfPHdr.PT_SCE_DYNLIBDATA, ElfPHdr.PT_SCE_COMMENT]:
continue
meta_entry = SignedElfEntry(entry_idx)
meta_entry.props = 0
meta_entry.encrypted = False
meta_entry.signed = True
meta_entry.has_digests = True
meta_entry.segment_index = entry_idx + 1
self.entries.append(meta_entry)
data_entry = SignedElfEntry(entry_idx + 1)
data_entry.props = 0
data_entry.encrypted = False
data_entry.signed = True
data_entry.has_blocks = True
data_entry.block_size = BLOCK_SIZE
data_entry.segment_index = i
self.entries.append(data_entry)
entry_idx += 2
self.num_entries = len(self.entries)
self.ex_info = SignedElfExInfo()
self.ex_info.paid = self.paid
self.ex_info.ptype = self.ptype
self.ex_info.app_version = self.app_version
self.ex_info.fw_version = self.fw_version
self.ex_info.digest = self.elf.digest
if SignedElfFile.HAS_NPDRM:
self.npdrm_control_block = SignedElfNpdrmControlBlock()
self.npdrm_control_block.content_id = '\0' * SELF_NPDRM_CONTROL_BLOCK_CONTENT_ID_SIZE
self.npdrm_control_block.random_pad = '\0' * SELF_NPDRM_CONTROL_BLOCK_RANDOM_PAD_SIZE
self.header_size = struct.calcsize(SignedElfFile.COMMON_HEADER_FMT) + struct.calcsize(SignedElfFile.EXT_HEADER_FMT)
self.header_size += self.num_entries * struct.calcsize(SignedElfEntry.FMT)
self.header_size += max(self.elf.ehdr.ehsize, self.elf.ehdr.phoff + self.elf.ehdr.phentsize * self.elf.ehdr.phnum)
self.header_size = align_up(self.header_size, 16)
self.header_size += struct.calcsize(SignedElfExInfo.FMT)
if SignedElfFile.HAS_NPDRM:
self.header_size += struct.calcsize(SignedElfNpdrmControlBlock.FMT)
self.meta_size = self.num_entries * struct.calcsize(SignedElfMetaBlock.FMT) + struct.calcsize(SignedElfMetaFooter.FMT) + SIGNATURE_SIZE
self.meta_blocks = []
for i in xrange(self.num_entries):
meta_block = SignedElfMetaBlock()
self.meta_blocks.append(meta_block)
self.meta_footer = SignedElfMetaFooter()
self.meta_footer.unk1 = 0x10000
if not self.auth_info is None:
self.signature = (struct.pack('<QQ', len(self.auth_info), self.ex_info.paid) + self.auth_info[8:]).ljust(SIGNATURE_SIZE, '\0')
else:
self.signature = EMPTY_SIGNATURE
entry_idx = 0
offset = self.header_size + self.meta_size
for i in xrange(self.elf.ehdr.phnum):
phdr = self.elf.phdrs[i]
if not phdr.type in [ElfPHdr.PT_LOAD, ElfPHdr.PT_SCE_RELRO, ElfPHdr.PT_SCE_DYNLIBDATA, ElfPHdr.PT_SCE_COMMENT]:
continue
print('processing segment #{0:02}...'.format(i))
meta_entry, data_entry = self.entries[entry_idx], self.entries[entry_idx + 1]
num_blocks = align_up(phdr.filesz, BLOCK_SIZE) // BLOCK_SIZE
meta_entry.data = EMPTY_DIGEST * num_blocks
meta_entry.offset = offset
meta_entry.memsz = meta_entry.filesz = len(meta_entry.data)
offset += meta_entry.filesz
offset = align_up(offset, 16)
data_entry.data = self.elf.segments[i]
data_entry.offset = offset
data_entry.memsz = data_entry.filesz = phdr.filesz
offset += data_entry.filesz
offset = align_up(offset, 16)
entry_idx += 2
self.file_size = offset
def save(self, f):
start_offset = f.tell()
# calculate neccessary fields
self._prepare()
# write common header
f.write(struct.pack(SignedElfFile.COMMON_HEADER_FMT, self.magic, self.version, self.mode, self.endian, self.attribs))
# write extended header
f.write(struct.pack(SignedElfFile.EXT_HEADER_FMT, self.key_type, self.header_size, self.meta_size, self.file_size, self.num_entries, self.flags))
# write entries
for entry in self.entries:
entry.save(f)
# write elf headers
elf_offset = f.tell()
elf_header_size = max(self.elf.ehdr.ehsize, self.elf.ehdr.phoff + self.elf.ehdr.phentsize * self.elf.ehdr.phnum)
elf_header_size = align_up(elf_header_size, 16)
self.elf.save(f, True)
f.seek(elf_offset + elf_header_size)
# write extended info
self.ex_info.save(f)
# write npdrm control block
if SignedElfFile.HAS_NPDRM:
self.npdrm_control_block.save(f)
# write meta blocks
for meta_block in self.meta_blocks:
meta_block.save(f)
# write meta footer
self.meta_footer.save(f)
# write signature
f.write(self.signature)
# write segments
for entry in self.entries:
f.seek(start_offset + entry.offset)
f.write(entry.data)
# write version
if not self.version_data is None:
f.write(self.version_data)
def ensure_hex_string(val, **kwargs):
exact_size = int(kwargs['exact_size']) if 'exact_size' in kwargs else None
min_size = int(kwargs['min_size']) if 'min_size' in kwargs else None
max_size = int(kwargs['max_size']) if 'max_size' in kwargs else None
val = re.sub('\s+', '', val)
val_size = len(val)
if val_size > 0:
if val.startswith('0x') or val.startswith('0X'):
val = val[2:]
if len(val) % 2 != 0 or not all(x in string.hexdigits for x in val):
return None
val = val.decode('hex')
val_size = len(val)
if not exact_size is None and val_size != exact_size:
return None
else:
if not min_size is None and val_size < min_size:
return None
if not max_size is None and val_size > max_size:
return None
return val
def input_file_type(val):
if not os.access(val, os.F_OK | os.R_OK) or not os.path.isfile(val):
raise argparse.ArgumentTypeError('invalid input file: {0}'.format(val))
return val
def output_file_type(val):
if os.access(val, os.F_OK) and (not os.path.isfile(val) or not os.access(val, os.F_OK | os.W_OK)):
raise argparse.ArgumentTypeError('invalid output file: {0}'.format(val))
return val
def auth_info_type(val):
new_val = ensure_hex_string(val, exact_size=0x88)
if new_val is None:
raise argparse.ArgumentTypeError('invalid auth info: {0}'.format(val))
return new_val
class MyParser(argparse.ArgumentParser):
def error(self, message):
self.print_help()
sys.stderr.write('\nerror: {0}\n'.format(message))
sys.exit(2)
parser = MyParser(description='fake signed elf maker')
parser.add_argument('input', type=input_file_type, default=None, help='elf/prx file path')
parser.add_argument('output', type=output_file_type, default=None, help='self/sprx file path')
parser.add_argument('--paid', type=int_with_base_type, default=0x3100000000000002, help='program authentication id')
parser.add_argument('--ptype', default=None, help='program type {fake, npdrm_exec, npdrm_dynlib, system_exec, system_dynlib, host_kernel, secure_module, secure_kernel}')
parser.add_argument('--app-version', type=int_with_base_type, default=0, help='application version')
parser.add_argument('--fw-version', type=int_with_base_type, default=0, help='firmware version')
parser.add_argument('--auth-info', type=auth_info_type, default=None, help='authentication info')
if len(sys.argv) == 1:
parser.print_usage()
sys.exit(1)
args = parser.parse_args()
paid = args.paid
if not (0 <= paid <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid program authentication id: 0x{0:016X}'.format(paid))
ptype = SignedElfExInfo.PTYPE_FAKE
if not args.ptype is None:
ptype = {
'fake': SignedElfExInfo.PTYPE_FAKE,
'npdrm_exec': SignedElfExInfo.PTYPE_NPDRM_EXEC,
'npdrm_dynlib': SignedElfExInfo.PTYPE_NPDRM_DYNLIB,
'system_exec': SignedElfExInfo.PTYPE_SYSTEM_EXEC,
'system_dynlib': SignedElfExInfo.PTYPE_SYSTEM_DYNLIB,
'host_kernel': SignedElfExInfo.PTYPE_HOST_KERNEL,
'secure_module': SignedElfExInfo.PTYPE_SECURE_MODULE,
'secure_kernel': SignedElfExInfo.PTYPE_SECURE_KERNEL,
}.get(args.ptype.strip().lower(), None)
if ptype is None:
ptype = try_parse_int(args.ptype)
if ptype is None:
parser.error('invalid program type: 0x{0:016X}'.format(ptype))
if not (0 <= ptype <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid program type: 0x{0:016X}'.format(ptype))
app_version = args.app_version
if not (0 <= app_version <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid application version: 0x{0:016X}'.format(app_version))
fw_version = args.fw_version
if not (0 <= fw_version <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid firmware version: 0x{0:016X}'.format(fw_version))
auth_info = args.auth_info
elf_file_path = args.input
fself_file_path = args.output
print('loading elf file: {0}'.format(elf_file_path))
try:
with open(elf_file_path, 'rb') as f:
elf_file = ElfFile(ignore_shdrs=True)
elf_file.load(f)
except Exception as err:
traceback.print_exc()
print('')
parser.error('unable to load elf file: {0} ({1})'.format(elf_file_path, err))
print('saving fake signed elf file: {0}'.format(fself_file_path))
try:
with open(fself_file_path, 'wb') as f:
self_file = SignedElfFile(elf_file, paid=paid, ptype=ptype, app_version=app_version, fw_version=fw_version, auth_info=auth_info)
self_file.save(f)
except Exception as err:
traceback.print_exc()
print('')
parser.error('unable to save fself file: {0} ({1})'.format(elf_file_path, err))
print('done')
+46
View File
@@ -0,0 +1,46 @@
@echo off
setlocal
REM ==============================
REM RUN FSELF
REM ==============================
echo [INFO] Running fself.py ...
C:\Python27\python.exe fself.py GTAServer.prx test.sprx
if %errorlevel% neq 0 (
echo [ERROR] fself failed.
exit /b 1
)
echo [OK] SPRX created.
REM ==============================
REM FTP UPLOAD (WinSCP)
REM ==============================
set WINSCP="C:\Program Files (x86)\WinSCP\winscp.com"
set PS4_IP=192.168.137.241
set PS4_PORT=2121
set REMOTE_DIR=/data/GoldHEN/plugins
set FILE=test.sprx
if not exist "%FILE%" (
echo [ERROR] %FILE% not found.
exit /b 1
)
echo [INFO] Uploading to PS4...
%WINSCP% ^
/command ^
"open ftp://anonymous@%PS4_IP%:%PS4_PORT%/" ^
"cd %REMOTE_DIR%" ^
"put %FILE%" ^
"exit"
if %errorlevel% neq 0 (
echo [ERROR] FTP upload failed.
exit /b 1
)
echo [OK] FTP upload successful.
exit /b 0
BIN
View File
Binary file not shown.
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
prx.cpp
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(257,12): warning : unused variable 'g_user_logged_in' [-Wunused-variable]
static int g_user_logged_in = 0;
^
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(258,29): warning : unused variable 'g_user_id' [-Wunused-variable]
static SceUserServiceUserId g_user_id = 1;
^
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(259,12): warning : unused variable 'g_login_event_pending' [-Wunused-variable]
static int g_login_event_pending = 1;
^
C:\Users\DontCry361x\Documents\GTASPRXPS4\prx.cpp(260,12): warning : unused variable 'g_logout_event_pending' [-Wunused-variable]
static int g_logout_event_pending = 0;
^
4 warnings generated.
GTASPRXPS4.vcxproj -> C:\Users\DontCry361x\Documents\GTASPRXPS4\ORBIS_Release\GTAServer.prx
'"C:\Users\DontCry361x\Documents\GTASPRXPS4\ORBIS_Release\make_sprx.bat"' is not recognized as an internal or external command,
operable program or batch file.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(148,5): error MSB3073: The command "cd /d "C:\Users\DontCry361x\Documents\GTASPRXPS4\ORBIS_Release\"
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(148,5): error MSB3073: call "C:\Users\DontCry361x\Documents\GTASPRXPS4\ORBIS_Release\make_sprx.bat"
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(148,5): error MSB3073:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(148,5): error MSB3073: :VCEnd" exited with code 1.
@@ -0,0 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=Clang:EnableManagedIncrementalBuild=:VCToolArchitecture=:WindowsTargetPlatformVersion=
Release|ORBIS|C:\Users\DontCry361x\Documents\GTASPRXPS4\|
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
C:\Users\DontCry361x\source\repos\GTASPRXPS4\ORBIS_Release\GTAServer.prx
Binary file not shown.
Binary file not shown.
Binary file not shown.
+816
View File
@@ -0,0 +1,816 @@
#!/usr/bin/env python
import sys, os, struct, traceback
import hashlib, hmac
import argparse, re, string
def int_with_base_type(val):
return int(val, 0)
def try_parse_int(x, base=0):
try:
return int(x, base) if isinstance(x, str) else int(x)
except:
return None
def align_up(x, alignment):
return (x + (alignment - 1)) & ~(alignment - 1)
def align_down(x, alignment):
return x & ~(alignment - 1)
def ilog2(x):
if x <= 0:
raise ValueError('math domain error')
return len(bin(x)) - 3
def is_intervals_overlap(p1, p2):
return p1[0] <= p2[1] and p1[1] <= p2[0]
def check_file_magic(f, expected_magic):
old_offset = f.tell()
try:
magic = f.read(len(expected_magic))
except:
return False
finally:
f.seek(old_offset)
return magic == expected_magic
def parse_version(version):
major, minor, patch = (version >> 8) & 0xFF, version & 0xFF, 0 # FIXME
major = 10 * (major >> 4) + (major & 0xF)
minor = 10 * (minor >> 4) + (minor & 0xF)
return '{0:d}.{1:02d}.{2:03d}'.format(major, minor, patch)
def sha256(data):
return hashlib.sha256(data).digest()
def hmac_sha256(key, data):
return hmac.new(key=key, msg=data, digestmod=hashlib.sha256).digest()
class ElfError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return repr(self.msg)
class ElfEHdr(object):
FMT = '<4s5B6xB'
EX_FMT = '<2HI3QI6H'
MAGIC = '\x7FELF'
CLASS64 = 0x2
DATA2LSB = 0x1
EM_X86_64 = 0x3E
EV_CURRENT = 0x1
ET_EXEC = 0x2
ET_SCE_EXEC = 0xFE00
ET_SCE_EXEC_ASLR = 0xFE10
ET_SCE_DYNAMIC = 0xFE18
def __init__(self):
self.magic = None
self.machine_class = None
self.data_encoding = None
self.version = None
self.os_abi = None
self.abi_version = None
self.nident_size = None
self.type = None
self.machine = None
self.version = None
self.entry = None
self.phoff = None
self.shoff = None
self.flags = None
self.ehsize = None
self.phentsize = None
self.phnum = None
self.shentsize = None
self.shnum = None
self.shstridx = None
def load(self, f):
if not check_file_magic(f, ElfEHdr.MAGIC):
raise ElfError('Invalid magic.')
self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size = struct.unpack(ElfEHdr.FMT, f.read(struct.calcsize(ElfEHdr.FMT)))
if self.machine_class != ElfEHdr.CLASS64 or self.data_encoding != ElfEHdr.DATA2LSB:
raise ElfError('Unsupported class or data encoding.')
self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx = struct.unpack(ElfEHdr.EX_FMT, f.read(struct.calcsize(ElfEHdr.EX_FMT)))
if self.machine != ElfEHdr.EM_X86_64 or self.version != ElfEHdr.EV_CURRENT:
raise ElfError('Unsupported machine type or version.')
if self.phentsize != struct.calcsize(ElfPHdr.FMT) or (self.shentsize > 0 and self.shentsize != struct.calcsize(ElfSHdr.FMT)):
raise ElfError('Unsupported header entry size.')
if self.type not in [ElfEHdr.ET_EXEC, ElfEHdr.ET_SCE_EXEC, ElfEHdr.ET_SCE_EXEC_ASLR, ElfEHdr.ET_SCE_DYNAMIC]:
raise ElfError('Unsupported type.')
def save(self, f):
f.write(struct.pack(ElfEHdr.FMT, self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size))
f.write(struct.pack(ElfEHdr.EX_FMT, self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx))
def has_segments(self):
return self.phentsize > 0 and self.phnum > 0
def has_sections(self):
return self.shentsize > 0 and self.shnum > 0
class ElfPHdr(object):
FMT = '<2I6Q'
PT_LOAD = 0x1
PT_DYNAMIC = 0x2
PT_INTERP = 0x3
PT_TLS = 0x7
PT_GNU_EH_FRAME = 0x6474E550
PT_GNU_STACK = 0x6474E551
PT_SCE_RELA = 0x60000000,
PT_SCE_DYNLIBDATA = 0x61000000
PT_SCE_PROCPARAM = 0x61000001
PT_SCE_MODULE_PARAM = 0x61000002
PT_SCE_RELRO = 0x61000010
PT_SCE_COMMENT = 0x6FFFFF00
PT_SCE_VERSION = 0x6FFFFF01
PF_EXEC = 0x1
PF_WRITE = 0x2
PF_READ = 0x4
PF_READ_EXEC = PF_READ | PF_EXEC
PF_READ_WRITE = PF_READ | PF_WRITE
def __init__(self, idx):
self.idx = idx
self.type = None
self.flags = None
self.offset = None
self.vaddr = None
self.paddr = None
self.filesz = None
self.memsz = None
self.align = None
def load(self, f):
self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align = struct.unpack(ElfPHdr.FMT, f.read(struct.calcsize(ElfPHdr.FMT)))
def save(self, f):
f.write(struct.pack(ElfPHdr.FMT, self.type, self.flags, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.align))
def name(self):
if self.type == ElfPHdr.PT_LOAD:
if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC:
return '.text'
elif (self.flags & ElfPHdr.PF_READ_WRITE) == ElfPHdr.PF_READ_WRITE:
return '.data'
else:
return '.load_{0:02}'.format(self.idx)
else:
return {
ElfPHdr.PT_DYNAMIC: '.dynamic',
ElfPHdr.PT_INTERP: '.interp',
ElfPHdr.PT_TLS: '.tls',
ElfPHdr.PT_GNU_EH_FRAME: '.eh_frame_hdr',
ElfPHdr.PT_SCE_DYNLIBDATA: '.sce_dynlib_data',
ElfPHdr.PT_SCE_PROCPARAM: '.sce_process_param',
ElfPHdr.PT_SCE_MODULE_PARAM: '.sce_module_param',
ElfPHdr.PT_SCE_COMMENT: '.sce_comment',
}.get(self.type, None)
def class_name(self):
if (self.flags & ElfPHdr.PF_READ_EXEC) == ElfPHdr.PF_READ_EXEC:
return 'CODE'
else:
return 'DATA'
class ElfSHdr(object):
FMT = '<2I4Q2I2Q'
def __init__(self, idx):
self.idx = idx
self.name = None
self.type = None
self.flags = None
self.addr = None
self.offset = None
self.size = None
self.link = None
self.info = None
self.align = None
self.entsize = None
def load(self, f):
self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize = struct.unpack(ElfSHdr.FMT, f.read(struct.calcsize(ElfSHdr.FMT)))
def save(self, f):
f.write(struct.pack(ElfSHdr.FMT, self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize))
class ElfFile(object):
def __init__(self, **kwargs):
self.ehdr = None
self.phdrs = None
self.shdrs = None
self.file_size = None
self.digest = None
self.segments = None
self.sections = None
self.ignore_shdrs = 'ignore_shdrs' in kwargs and kwargs['ignore_shdrs']
def load(self, f):
start_offset = f.tell()
data = f.read()
self.file_size = len(data)
self.digest = sha256(data)
f.seek(start_offset)
self.ehdr = ElfEHdr()
self.ehdr.load(f)
if self.ignore_shdrs:
self.ehdr.shnum = 0
self.phdrs = []
self.segments = []
if self.ehdr.has_segments():
for i in xrange(self.ehdr.phnum):
f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize)
phdr = ElfPHdr(i)
phdr.load(f)
self.phdrs.append(phdr)
if phdr.filesz > 0:
f.seek(start_offset + phdr.offset)
data = f.read(phdr.filesz)
else:
data = ''
self.segments.append(data)
self.shdrs = []
self.sections = []
if self.ehdr.has_sections():
for i in xrange(self.ehdr.shnum):
f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize)
shdr = ElfSHdr(i)
shdr.load(f)
self.shdrs.append(shdr)
if phdr.filesz > 0:
f.seek(start_offset + shdr.offset)
data = f.read(phdr.filesz)
else:
data = ''
self.sections.append(data)
def save(self, f, no_sections=False):
start_offset = f.tell()
self.ehdr.save(f)
if not no_sections:
if self.ehdr.has_sections():
for i in xrange(self.ehdr.shnum):
f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize)
shdr = self.shdrs[i]
shdr.save(f)
if self.ehdr.has_segments():
for i in xrange(self.ehdr.phnum):
f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize)
phdr = self.phdrs[i]
phdr.save(f)
DIGEST_SIZE = 0x20
SIGNATURE_SIZE = 0x100
BLOCK_SIZE = 0x4000
DEFAULT_BLOCK_SIZE = 0x1000
SELF_CONTROL_BLOCK_TYPE_NPDRM = 0x3
SELF_NPDRM_CONTROL_BLOCK_CONTENT_ID_SIZE = 0x13
SELF_NPDRM_CONTROL_BLOCK_RANDOM_PAD_SIZE = 0xD
EMPTY_DIGEST = '\0' * DIGEST_SIZE
EMPTY_SIGNATURE = '\0' * SIGNATURE_SIZE
class SignedElfEntry(object):
FMT = '<4Q'
PROPS_ORDER_SHIFT = 0
PROPS_ORDER_MASK = 0x1
PROPS_ENCRYPTED_SHIFT = 1
PROPS_ENCRYPTED_MASK = 0x1
PROPS_SIGNED_SHIFT = 2
PROPS_SIGNED_MASK = 0x1
PROPS_COMPRESSED_SHIFT = 3
PROPS_COMPRESSED_MASK = 0x1
PROPS_WINDOW_BITS_SHIFT = 8
PROPS_WINDOW_BITS_MASK = 0x7
PROPS_HAS_BLOCKS_SHIFT = 11
PROPS_HAS_BLOCKS_MASK = 0x1
PROPS_BLOCK_SIZE_SHIFT = 12
PROPS_BLOCK_SIZE_MASK = 0xF
PROPS_HAS_DIGESTS_SHIFT = 16
PROPS_HAS_DIGESTS_MASK = 0x1
PROPS_HAS_EXTENTS_SHIFT = 17
PROPS_HAS_EXTENTS_MASK = 0x1
PROPS_HAS_META_SEGMENT_SHIFT = 20
PROPS_HAS_META_SEGMENT_MASK = 0x1
PROPS_SEGMENT_INDEX_SHIFT = 20
PROPS_SEGMENT_INDEX_MASK = 0xFFFF
PROPS_DEFAULT_BLOCK_SIZE = 0x1000
PROPS_META_SEGMENT_MASK = 0xF0000
def __init__(self, index):
self.index = index
self.props = None
self.offset = None
self.filesz = None
self.memsz = None
self.data = None
def save(self, f):
f.write(struct.pack(SignedElfEntry.FMT, self.props, self.offset, self.filesz, self.memsz))
@property
def order(self):
return (self.props >> SignedElfEntry.PROPS_ORDER_SHIFT) & SignedElfEntry.PROPS_ORDER_MASK
@order.setter
def order(self, value):
self.props &= ~(SignedElfEntry.PROPS_ORDER_MASK << SignedElfEntry.PROPS_ORDER_SHIFT)
self.props |= (value & SignedElfEntry.PROPS_ORDER_MASK) << SignedElfEntry.PROPS_ORDER_SHIFT
@property
def encrypted(self):
return ((self.props >> SignedElfEntry.PROPS_ENCRYPTED_SHIFT) & SignedElfEntry.PROPS_ENCRYPTED_MASK) != 0
@encrypted.setter
def encrypted(self, value):
self.props &= ~(SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_ENCRYPTED_MASK << SignedElfEntry.PROPS_ENCRYPTED_SHIFT
@property
def signed(self):
return ((self.props >> SignedElfEntry.PROPS_SIGNED_SHIFT) & SignedElfEntry.PROPS_SIGNED_MASK) != 0
@signed.setter
def signed(self, value):
self.props &= ~(SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_SIGNED_MASK << SignedElfEntry.PROPS_SIGNED_SHIFT
@property
def compressed(self):
return ((self.props >> SignedElfEntry.PROPS_COMPRESSED_SHIFT) & SignedElfEntry.PROPS_COMPRESSED_MASK) != 0
@compressed.setter
def compressed(self, value):
self.props &= ~(SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_COMPRESSED_MASK << SignedElfEntry.PROPS_COMPRESSED_SHIFT
@property
def has_blocks(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT) & SignedElfEntry.PROPS_HAS_BLOCKS_MASK) != 0
@has_blocks.setter
def has_blocks(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_BLOCKS_MASK << SignedElfEntry.PROPS_HAS_BLOCKS_SHIFT
@property
def has_digests(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT) & SignedElfEntry.PROPS_HAS_DIGESTS_MASK) != 0
@has_digests.setter
def has_digests(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_DIGESTS_MASK << SignedElfEntry.PROPS_HAS_DIGESTS_SHIFT
@property
def has_extents(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT) & SignedElfEntry.PROPS_HAS_EXTENTS_MASK) != 0
@has_extents.setter
def has_extents(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_EXTENTS_MASK << SignedElfEntry.PROPS_HAS_EXTENTS_SHIFT
@property
def has_meta_segment(self):
return ((self.props >> SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT) & SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK) != 0
@has_meta_segment.setter
def has_meta_segment(self, value):
self.props &= ~(SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT)
if value:
self.props |= SignedElfEntry.PROPS_HAS_META_SEGMENT_MASK << SignedElfEntry.PROPS_HAS_META_SEGMENT_SHIFT
@property
def wbits(self):
return (self.props >> SignedElfEntry.PROPS_WINDOW_BITS_SHIFT) & SignedElfEntry.PROPS_WINDOW_BITS_MASK
@wbits.setter
def wbits(self, value):
self.props &= ~(SignedElfEntry.PROPS_WINDOW_BITS_MASK << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT)
self.props |= (value & SignedElfEntry.PROPS_WINDOW_BITS_MASK) << SignedElfEntry.PROPS_WINDOW_BITS_SHIFT
@property
def block_size(self):
if self.has_blocks:
return 1 << (12 + (self.props >> SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT) & SignedElfEntry.PROPS_BLOCK_SIZE_MASK)
else:
return DEFAULT_BLOCK_SIZE
@block_size.setter
def block_size(self, value):
self.props &= ~(SignedElfEntry.PROPS_BLOCK_SIZE_MASK << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT)
if self.has_blocks:
value = ilog2(value) - 12
else:
value = 0 # TODO: check
self.props |= (value & SignedElfEntry.PROPS_BLOCK_SIZE_MASK) << SignedElfEntry.PROPS_BLOCK_SIZE_SHIFT
@property
def segment_index(self):
return (self.props >> SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT) & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK
@wbits.setter
def segment_index(self, value):
self.props &= ~(SignedElfEntry.PROPS_SEGMENT_INDEX_MASK << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT)
self.props |= (value & SignedElfEntry.PROPS_SEGMENT_INDEX_MASK) << SignedElfEntry.PROPS_SEGMENT_INDEX_SHIFT
def is_meta_segment(self): # TODO: check
return (self.props & SignedElfEntry.PROPS_META_SEGMENT_MASK) != 0
def __repr__(self):
return 'prs:0x{0:X} ofs:0x{1:X} fsz:0x{2:X} msz:0x{3:X}'.format(self.props, self.offset, self.filesz, self.memsz)
class SignedElfExInfo(object):
FMT = '<4Q32s'
PTYPE_FAKE = 0x1
PTYPE_NPDRM_EXEC = 0x4
PTYPE_NPDRM_DYNLIB = 0x5
PTYPE_SYSTEM_EXEC = 0x8
PTYPE_SYSTEM_DYNLIB = 0x9 # including Mono binaries
PTYPE_HOST_KERNEL = 0xC
PTYPE_SECURE_MODULE = 0xE
PTYPE_SECURE_KERNEL = 0xF
def __init__(self):
self.paid = None
self.ptype = None
self.app_version = None
self.fw_version = None
self.digest = None
def save(self, f):
f.write(struct.pack(SignedElfExInfo.FMT, self.paid, self.ptype, self.app_version, self.fw_version, self.digest))
class SignedElfNpdrmControlBlock(object):
FMT = '<H14x19s13s'
def __init__(self):
self.type = SELF_CONTROL_BLOCK_TYPE_NPDRM
self.content_id = None
self.random_pad = None
def save(self, f):
f.write(struct.pack(SignedElfNpdrmControlBlock.FMT, self.type, self.content_id, self.random_pad))
class SignedElfMetaBlock(object):
FMT = '<80x'
def __init__(self):
pass
def save(self, f):
f.write(struct.pack(SignedElfMetaBlock.FMT))
class SignedElfMetaFooter(object):
FMT = '<48xI28x'
def __init__(self):
self.unk1 = None
def save(self, f):
f.write(struct.pack(SignedElfMetaFooter.FMT, self.unk1))
class SignedElfFile(object):
COMMON_HEADER_FMT = '<4s4B'
EXT_HEADER_FMT = '<I2HQ2H4x'
MAGIC = '\x4F\x15\x3D\x1D'
VERSION = 0x00
MODE = 0x01
ENDIAN = 0x01
ATTRIBS = 0x12
KEY_TYPE = 0x101
FLAGS_SEGMENT_SIGNED_SHIFT = 4
FLAGS_SEGMENT_SIGNED_MASK = 0x7
HAS_NPDRM = 1
def __init__(self, elf, **kwargs):
self.elf = elf
self.magic = None
self.version = None
self.mode = None
self.endian = None
self.attribs = None
self.key_type = None
self.header_size = None
self.meta_size = None
self.file_size = None
self.num_entries = None
self.flags = None
self.entries = None
self.ex_info = None
self.npdrm_control_block = None
self.meta_blocks = None
self.meta_footer = None
self.signature = None
self.version_data = None
self.paid = kwargs['paid'] if 'paid' in kwargs and not kwargs['paid'] is None else 0x3100000000000002
self.ptype = kwargs['ptype'] if 'ptype' in kwargs and not kwargs['ptype'] is None else SignedElfExInfo.PTYPE_FAKE
self.app_version = kwargs['app_version'] if 'app_version' in kwargs and not kwargs['app_version'] is None else 0
self.fw_version = kwargs['fw_version'] if 'fw_version' in kwargs and not kwargs['fw_version'] is None else 0
self.auth_info = kwargs['auth_info'] if 'auth_info' in kwargs and not kwargs['auth_info'] is None else None
def _prepare(self):
self.magic = SignedElfFile.MAGIC
self.version = SignedElfFile.VERSION
self.mode = SignedElfFile.MODE
self.endian = SignedElfFile.ENDIAN
self.attribs = SignedElfFile.ATTRIBS
self.key_type = SignedElfFile.KEY_TYPE
self.flags = 0x2
signed_block_count = 2
self.flags |= (signed_block_count & SignedElfFile.FLAGS_SEGMENT_SIGNED_MASK) << SignedElfFile.FLAGS_SEGMENT_SIGNED_SHIFT
self.entries = []
entry_idx = 0
for i in xrange(self.elf.ehdr.phnum):
phdr = self.elf.phdrs[i]
if phdr.type == ElfPHdr.PT_SCE_VERSION:
self.version_data = self.elf.segments[i]
if not phdr.type in [ElfPHdr.PT_LOAD, ElfPHdr.PT_SCE_RELRO, ElfPHdr.PT_SCE_DYNLIBDATA, ElfPHdr.PT_SCE_COMMENT]:
continue
meta_entry = SignedElfEntry(entry_idx)
meta_entry.props = 0
meta_entry.encrypted = False
meta_entry.signed = True
meta_entry.has_digests = True
meta_entry.segment_index = entry_idx + 1
self.entries.append(meta_entry)
data_entry = SignedElfEntry(entry_idx + 1)
data_entry.props = 0
data_entry.encrypted = False
data_entry.signed = True
data_entry.has_blocks = True
data_entry.block_size = BLOCK_SIZE
data_entry.segment_index = i
self.entries.append(data_entry)
entry_idx += 2
self.num_entries = len(self.entries)
self.ex_info = SignedElfExInfo()
self.ex_info.paid = self.paid
self.ex_info.ptype = self.ptype
self.ex_info.app_version = self.app_version
self.ex_info.fw_version = self.fw_version
self.ex_info.digest = self.elf.digest
if SignedElfFile.HAS_NPDRM:
self.npdrm_control_block = SignedElfNpdrmControlBlock()
self.npdrm_control_block.content_id = '\0' * SELF_NPDRM_CONTROL_BLOCK_CONTENT_ID_SIZE
self.npdrm_control_block.random_pad = '\0' * SELF_NPDRM_CONTROL_BLOCK_RANDOM_PAD_SIZE
self.header_size = struct.calcsize(SignedElfFile.COMMON_HEADER_FMT) + struct.calcsize(SignedElfFile.EXT_HEADER_FMT)
self.header_size += self.num_entries * struct.calcsize(SignedElfEntry.FMT)
self.header_size += max(self.elf.ehdr.ehsize, self.elf.ehdr.phoff + self.elf.ehdr.phentsize * self.elf.ehdr.phnum)
self.header_size = align_up(self.header_size, 16)
self.header_size += struct.calcsize(SignedElfExInfo.FMT)
if SignedElfFile.HAS_NPDRM:
self.header_size += struct.calcsize(SignedElfNpdrmControlBlock.FMT)
self.meta_size = self.num_entries * struct.calcsize(SignedElfMetaBlock.FMT) + struct.calcsize(SignedElfMetaFooter.FMT) + SIGNATURE_SIZE
self.meta_blocks = []
for i in xrange(self.num_entries):
meta_block = SignedElfMetaBlock()
self.meta_blocks.append(meta_block)
self.meta_footer = SignedElfMetaFooter()
self.meta_footer.unk1 = 0x10000
if not self.auth_info is None:
self.signature = (struct.pack('<QQ', len(self.auth_info), self.ex_info.paid) + self.auth_info[8:]).ljust(SIGNATURE_SIZE, '\0')
else:
self.signature = EMPTY_SIGNATURE
entry_idx = 0
offset = self.header_size + self.meta_size
for i in xrange(self.elf.ehdr.phnum):
phdr = self.elf.phdrs[i]
if not phdr.type in [ElfPHdr.PT_LOAD, ElfPHdr.PT_SCE_RELRO, ElfPHdr.PT_SCE_DYNLIBDATA, ElfPHdr.PT_SCE_COMMENT]:
continue
print('processing segment #{0:02}...'.format(i))
meta_entry, data_entry = self.entries[entry_idx], self.entries[entry_idx + 1]
num_blocks = align_up(phdr.filesz, BLOCK_SIZE) // BLOCK_SIZE
meta_entry.data = EMPTY_DIGEST * num_blocks
meta_entry.offset = offset
meta_entry.memsz = meta_entry.filesz = len(meta_entry.data)
offset += meta_entry.filesz
offset = align_up(offset, 16)
data_entry.data = self.elf.segments[i]
data_entry.offset = offset
data_entry.memsz = data_entry.filesz = phdr.filesz
offset += data_entry.filesz
offset = align_up(offset, 16)
entry_idx += 2
self.file_size = offset
def save(self, f):
start_offset = f.tell()
# calculate neccessary fields
self._prepare()
# write common header
f.write(struct.pack(SignedElfFile.COMMON_HEADER_FMT, self.magic, self.version, self.mode, self.endian, self.attribs))
# write extended header
f.write(struct.pack(SignedElfFile.EXT_HEADER_FMT, self.key_type, self.header_size, self.meta_size, self.file_size, self.num_entries, self.flags))
# write entries
for entry in self.entries:
entry.save(f)
# write elf headers
elf_offset = f.tell()
elf_header_size = max(self.elf.ehdr.ehsize, self.elf.ehdr.phoff + self.elf.ehdr.phentsize * self.elf.ehdr.phnum)
elf_header_size = align_up(elf_header_size, 16)
self.elf.save(f, True)
f.seek(elf_offset + elf_header_size)
# write extended info
self.ex_info.save(f)
# write npdrm control block
if SignedElfFile.HAS_NPDRM:
self.npdrm_control_block.save(f)
# write meta blocks
for meta_block in self.meta_blocks:
meta_block.save(f)
# write meta footer
self.meta_footer.save(f)
# write signature
f.write(self.signature)
# write segments
for entry in self.entries:
f.seek(start_offset + entry.offset)
f.write(entry.data)
# write version
if not self.version_data is None:
f.write(self.version_data)
def ensure_hex_string(val, **kwargs):
exact_size = int(kwargs['exact_size']) if 'exact_size' in kwargs else None
min_size = int(kwargs['min_size']) if 'min_size' in kwargs else None
max_size = int(kwargs['max_size']) if 'max_size' in kwargs else None
val = re.sub('\s+', '', val)
val_size = len(val)
if val_size > 0:
if val.startswith('0x') or val.startswith('0X'):
val = val[2:]
if len(val) % 2 != 0 or not all(x in string.hexdigits for x in val):
return None
val = val.decode('hex')
val_size = len(val)
if not exact_size is None and val_size != exact_size:
return None
else:
if not min_size is None and val_size < min_size:
return None
if not max_size is None and val_size > max_size:
return None
return val
def input_file_type(val):
if not os.access(val, os.F_OK | os.R_OK) or not os.path.isfile(val):
raise argparse.ArgumentTypeError('invalid input file: {0}'.format(val))
return val
def output_file_type(val):
if os.access(val, os.F_OK) and (not os.path.isfile(val) or not os.access(val, os.F_OK | os.W_OK)):
raise argparse.ArgumentTypeError('invalid output file: {0}'.format(val))
return val
def auth_info_type(val):
new_val = ensure_hex_string(val, exact_size=0x88)
if new_val is None:
raise argparse.ArgumentTypeError('invalid auth info: {0}'.format(val))
return new_val
class MyParser(argparse.ArgumentParser):
def error(self, message):
self.print_help()
sys.stderr.write('\nerror: {0}\n'.format(message))
sys.exit(2)
parser = MyParser(description='fake signed elf maker')
parser.add_argument('input', type=input_file_type, default=None, help='elf/prx file path')
parser.add_argument('output', type=output_file_type, default=None, help='self/sprx file path')
parser.add_argument('--paid', type=int_with_base_type, default=0x3100000000000002, help='program authentication id')
parser.add_argument('--ptype', default=None, help='program type {fake, npdrm_exec, npdrm_dynlib, system_exec, system_dynlib, host_kernel, secure_module, secure_kernel}')
parser.add_argument('--app-version', type=int_with_base_type, default=0, help='application version')
parser.add_argument('--fw-version', type=int_with_base_type, default=0, help='firmware version')
parser.add_argument('--auth-info', type=auth_info_type, default=None, help='authentication info')
if len(sys.argv) == 1:
parser.print_usage()
sys.exit(1)
args = parser.parse_args()
paid = args.paid
if not (0 <= paid <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid program authentication id: 0x{0:016X}'.format(paid))
ptype = SignedElfExInfo.PTYPE_FAKE
if not args.ptype is None:
ptype = {
'fake': SignedElfExInfo.PTYPE_FAKE,
'npdrm_exec': SignedElfExInfo.PTYPE_NPDRM_EXEC,
'npdrm_dynlib': SignedElfExInfo.PTYPE_NPDRM_DYNLIB,
'system_exec': SignedElfExInfo.PTYPE_SYSTEM_EXEC,
'system_dynlib': SignedElfExInfo.PTYPE_SYSTEM_DYNLIB,
'host_kernel': SignedElfExInfo.PTYPE_HOST_KERNEL,
'secure_module': SignedElfExInfo.PTYPE_SECURE_MODULE,
'secure_kernel': SignedElfExInfo.PTYPE_SECURE_KERNEL,
}.get(args.ptype.strip().lower(), None)
if ptype is None:
ptype = try_parse_int(args.ptype)
if ptype is None:
parser.error('invalid program type: 0x{0:016X}'.format(ptype))
if not (0 <= ptype <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid program type: 0x{0:016X}'.format(ptype))
app_version = args.app_version
if not (0 <= app_version <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid application version: 0x{0:016X}'.format(app_version))
fw_version = args.fw_version
if not (0 <= fw_version <= 0xFFFFFFFFFFFFFFFF):
parser.error('invalid firmware version: 0x{0:016X}'.format(fw_version))
auth_info = args.auth_info
elf_file_path = args.input
fself_file_path = args.output
print('loading elf file: {0}'.format(elf_file_path))
try:
with open(elf_file_path, 'rb') as f:
elf_file = ElfFile(ignore_shdrs=True)
elf_file.load(f)
except Exception as err:
traceback.print_exc()
print('')
parser.error('unable to load elf file: {0} ({1})'.format(elf_file_path, err))
print('saving fake signed elf file: {0}'.format(fself_file_path))
try:
with open(fself_file_path, 'wb') as f:
self_file = SignedElfFile(elf_file, paid=paid, ptype=ptype, app_version=app_version, fw_version=fw_version, auth_info=auth_info)
self_file.save(f)
except Exception as err:
traceback.print_exc()
print('')
parser.error('unable to save fself file: {0} ({1})'.format(elf_file_path, err))
print('done')
Binary file not shown.
+18
View File
@@ -0,0 +1,18 @@
__asm__(
".att_syntax prefix\n"
".globl orbis_syscall\n"
"orbis_syscall:\n"
" movq $0, %rax\n"
" movq %rcx, %r10\n"
" syscall\n"
" jb err\n"
" retq\n"
"err:\n"
" pushq %rax\n"
" callq __error\n"
" popq %rcx\n"
" movl %ecx, 0(%rax)\n"
" movq $0xFFFFFFFFFFFFFFFF, %rax\n"
" movq $0xFFFFFFFFFFFFFFFF, %rdx\n"
" retq\n"
);
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int orbis_syscall(int num, ...);
#ifdef __cplusplus
}
#endif
+1082
View File
File diff suppressed because it is too large Load Diff