From 547fe4b50665fea8b1ce795f588f5980517cef5b Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 Jan 2022 08:38:24 +0000 Subject: [PATCH 1/5] Add some pretty badges. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 8009cc8..a917ea4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ # PS3API PS3 API for TMAPI and CCAPI in python. +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ps3api) +[![Downloads](https://pepy.tech/badge/ps3api)](https://pepy.tech/project/ps3api) +![GitHub commits since latest release (by date)](https://img.shields.io/github/commits-since/imod1998/ps3api/latest/main) +![GitHub](https://img.shields.io/github/license/imod1998/ps3api) + ## **Note** *This only works on 32 bit python as TMAPI and CCAPI are 32 bit DLLs.* From ca7fe04587d76a47d8e4661937024298fc19735a Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 Jan 2022 08:38:46 +0000 Subject: [PATCH 2/5] CCAPI Fix name of enum. --- ps3api/ccapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ps3api/ccapi.py b/ps3api/ccapi.py index 8ee17c7..8b524c9 100644 --- a/ps3api/ccapi.py +++ b/ps3api/ccapi.py @@ -54,7 +54,7 @@ class NotifyIcon(CEnum): NOTIFY_TROPHY3 = (18) NOTIFY_TROPHY4 = (19) -class StatusLed(CEnum): +class ConsoleType(CEnum): UNK = (0) CEX = (1) DEX = (2) From 33f42ba58e39abeb3f90941f20cd361b4f8a0242 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 Jan 2022 12:19:30 +0000 Subject: [PATCH 3/5] Fix CCAPI exports. --- ps3api/ccapi.py | 53 +++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/ps3api/ccapi.py b/ps3api/ccapi.py index 8b524c9..1c02cdd 100644 --- a/ps3api/ccapi.py +++ b/ps3api/ccapi.py @@ -8,31 +8,31 @@ class CCAPIError(CEnum): CCAPI_OK = (0) CCAPI_ERROR = (-1) -class ConsoleIdType(CEnum): +class CCAPIConsoleIdType(CEnum): IDPS = (0) PSID = (1) -class ShutdownMode(CEnum): +class CCAPIShutdownMode(CEnum): SHUTDOWN = (0) SOFT_REBOOT = (1) HARD_REBOOT = (2) -class BuzzerType(CEnum): +class CCAPIBuzzerType(CEnum): CONTINIOUS = (0) SINGLE = (1) DOUBLE = (2) TRIPLE = (3) -class ColorLed(CEnum): +class CCAPIColorLed(CEnum): GREEN = (0) RED = (1) -class StatusLed(CEnum): +class CCAPIStatusLed(CEnum): OFF = (0) ON = (1) BLINK = (2) -class NotifyIcon(CEnum): +class CCAPINotifyIcon(CEnum): NOTIFY_INFO = (0) NOTIFY_CAUTION = (1) NOTIFY_FRIEND = (2) @@ -54,30 +54,39 @@ class NotifyIcon(CEnum): NOTIFY_TROPHY3 = (18) NOTIFY_TROPHY4 = (19) -class ConsoleType(CEnum): +class CCAPIConsoleType(CEnum): UNK = (0) CEX = (1) DEX = (2) TOOL = (3) -class ConsoleId(Structure): +class CCAPIConsoleId(Structure): _fields_ = [ - ("value", c_uint8 * 16 ) + ("value", c_char * 16 ) ] -class ProcessName(Structure): +class CCAPIProcessName(Structure): _fields_ = [ - ("value", c_uint8 * 512 ) + ("value", c_char * 512 ) ] -class ConsoleName(Structure): +class CCAPIConsoleName(Structure): _fields_ = [ - ("value", c_uint8 * 256 ) + ("value", c_char * 256 ) + ] + +class CCAPIConsoleIp(Structure): + _fields_ = [ + ("value", c_char * 256 ) ] class CCAPIExports: def __init__(self): + # + # TODO: might need to bundle in future + # os.add_dll_directory(os.getcwd()) + os.add_dll_directory(os.path.join(os.getenv('APPDATA'), "ControlConsoleAPI")) self.CCAPI_DLL = CDLL("CCAPI.dll") @@ -113,8 +122,8 @@ def __init__(self): Set the console ID that will be used on boot. ''' - self.CCAPISetBootConsoleIds = CCAPI_DLL.CCAPISetBootConsoleIds - self.CCAPISetBootConsoleIds.argtypes = [ c_int32, c_int32, POINTER(ConsoleId) ] + self.CCAPISetBootConsoleIds = self.CCAPI_DLL.CCAPISetBootConsoleIds + self.CCAPISetBootConsoleIds.argtypes = [ c_int32, c_int32, POINTER(CCAPIConsoleId) ] self.CCAPISetBootConsoleIds.restype = CCAPIError ''' @@ -123,7 +132,7 @@ def __init__(self): Set the current console ID. ''' self.CCAPISetConsoleIds = self.CCAPI_DLL.CCAPISetConsoleIds - self.CCAPISetConsoleIds.argtypes = [ c_int32, POINTER(ConsoleId) ] + self.CCAPISetConsoleIds.argtypes = [ CCAPIConsoleIdType, POINTER(CCAPIConsoleId) ] self.CCAPISetConsoleIds.restype = CCAPIError ''' @@ -149,9 +158,9 @@ def __init__(self): Get the list of processes. ''' - self.CCAPIGetProcessList = self.CCAPI_DLL.CCAPIGetMemory + self.CCAPIGetProcessList = self.CCAPI_DLL.CCAPIGetProcessList self.CCAPIGetProcessList.argtypes = [ POINTER(c_uint32), POINTER(c_uint32) ] - self.CCAPIGetProcessList.restype = CCAPIError + self.CCAPIGetProcessList.restype = c_ulong # seems to return something else 0x80001000 ''' int CCAPIGetProcessName(u32 pid, ProcessName* name); @@ -159,7 +168,7 @@ def __init__(self): Get the name of the current attached process. ''' self.CCAPIGetProcessName = self.CCAPI_DLL.CCAPIGetProcessName - self.CCAPIGetProcessName.argtypes = [ c_uint32, POINTER(ProcessName) ] + self.CCAPIGetProcessName.argtypes = [ c_uint32, POINTER(CCAPIProcessName) ] self.CCAPIGetProcessName.restype = CCAPIError ''' @@ -235,13 +244,13 @@ def __init__(self): self.CCAPIGetNumberOfConsoles.restype = c_int32 ''' - int CCAPIGetConsoleInfo(int index, ConsoleName* name, ConsoleIp* ip); + void CCAPIGetConsoleInfo(int index, ConsoleName* name, ConsoleIp* ip); Get console name and ip. ''' self.CCAPIGetConsoleInfo = self.CCAPI_DLL.CCAPIGetConsoleInfo - self.CCAPIGetConsoleInfo.argtypes = [ c_uint32, POINTER(ConsoleName), POINTER(ConsoleIp) ] - self.CCAPIGetConsoleInfo.restype = CCAPIError + self.CCAPIGetConsoleInfo.argtypes = [ c_uint32, POINTER(CCAPIConsoleName), POINTER(CCAPIConsoleIp) ] + self.CCAPIGetConsoleInfo.restype = None ''' int CCAPIGetDllVersion(); From 49f8566616e79f105b6f7ceae8eb0a5d4acbc3a9 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 Jan 2022 17:51:35 +0000 Subject: [PATCH 4/5] Fix error using string arguments with RPC. --- ps3api/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ps3api/rpc.py b/ps3api/rpc.py index 0ca0495..8d119e7 100644 --- a/ps3api/rpc.py +++ b/ps3api/rpc.py @@ -287,7 +287,7 @@ def __call__(self, *Args): WantedType = ArgType._type_.__ctype_be__ Bytes = bytearray(WantedType(ArgValue)) - CallContext.AddGPRegister(Context.AddArgData(Bytes)) + CallContext.AddGPRegister(CallContext.AddArgData(Bytes)) # elif issubclass(ArgType, Array): # WantedType = ARRAY(ArgType._type_.__ctype_be__, ArgType._length_) From be0a5611038f079300dc2ae8663f231db4a01ed0 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 Jan 2022 17:52:05 +0000 Subject: [PATCH 5/5] CCAPI support implemented. --- ps3api/ccapi.py | 113 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 11 deletions(-) diff --git a/ps3api/ccapi.py b/ps3api/ccapi.py index 1c02cdd..39fdf94 100644 --- a/ps3api/ccapi.py +++ b/ps3api/ccapi.py @@ -142,7 +142,7 @@ def __init__(self): ''' self.CCAPISetMemory = self.CCAPI_DLL.CCAPISetMemory self.CCAPISetMemory.argtypes = [ c_uint32, c_uint64, c_uint32, POINTER(c_char) ] - self.CCAPISetMemory.restype = CCAPIError + self.CCAPISetMemory.restype = c_ulong ''' int CCAPIGetMemory(u32 pid, u64 address, u32 size, void* data); @@ -151,7 +151,7 @@ def __init__(self): ''' self.CCAPIGetMemory = self.CCAPI_DLL.CCAPIGetMemory self.CCAPIGetMemory.argtypes = [ c_uint32, c_uint64, c_uint32, POINTER(c_char) ] - self.CCAPIGetMemory.restype = CCAPIError + self.CCAPIGetMemory.restype = c_ulong ''' int CCAPIGetProcessList(u32* npid, u32* pids); @@ -160,7 +160,7 @@ def __init__(self): ''' self.CCAPIGetProcessList = self.CCAPI_DLL.CCAPIGetProcessList self.CCAPIGetProcessList.argtypes = [ POINTER(c_uint32), POINTER(c_uint32) ] - self.CCAPIGetProcessList.restype = c_ulong # seems to return something else 0x80001000 + self.CCAPIGetProcessList.restype = c_ulong ''' int CCAPIGetProcessName(u32 pid, ProcessName* name); @@ -263,19 +263,110 @@ def __init__(self): class CCAPI: def __init__(self): - raise Exception("CCAPI Not Implemented!!") + self.NativeAPI = CCAPIExports() + self.PS3TargetIndex = -1 + self.IsConnected = False + self.ProcessID = 0 + + def GetNumberOfTargets(self): + return self.NativeAPI.CCAPIGetNumberOfConsoles() def GetDefaultTarget(self): - raise Exception("CCAPI Not Implemented!!") + NumConsoles = self.GetNumberOfTargets() + + if NumConsoles == 0: + return None + + return 0 + + def GetConsoleInfo(self, TargetIndex): + NamePtr = pointer(CCAPIConsoleName()) + IPPtr = pointer(CCAPIConsoleIp()) + + self.NativeAPI.CCAPIGetConsoleInfo(TargetIndex, NamePtr, IPPtr) + + Name = NamePtr.contents.value + IP = IPPtr.contents.value + + if Name == b"" or IP == b"": + return (None, None) + + return (Name.decode("ascii"), IP.decode("ascii")) + + def ConnectTargetWithIP(self, TargetIP): + if self.NativeAPI.CCAPIConnectConsole(bytes(TargetIP, "ascii")) == CCAPIError.CCAPI_OK: + return True + + return False + + def ConnectTarget(self, TargetIndex=-1): + NumConsoles = self.GetNumberOfTargets() + + if NumConsoles == 0: + raise Exception("No Consoles Added In CCAPI") + + TargetIndex = self.GetDefaultTarget() if TargetIndex == -1 else TargetIndex + + if TargetIndex == None: + raise Exception("Could not find default console") + + ConsoleName, IP = self.GetConsoleInfo(TargetIndex) + + if IP == None: + raise Exception("Failed to find console info") + + print(IP) - def ConnectTarget(self, TargetIndex): - raise Exception("CCAPI Not Implemented!!") + return self.ConnectTargetWithIP(IP) - def AttachProcess(self): - raise Exception("CCAPI Not Implemented!!") + def GetProcessList(self): + NumProcessPtr = pointer(c_uint32(0)) + + if self.NativeAPI.CCAPIGetProcessList(NumProcessPtr, None) == CCAPIError.CCAPI_ERROR: + raise Exception("CCAPIGetProcessList() Failed") + + print(NumProcessPtr.contents.value) + + ProccessIDList = (c_uint32 * NumProcessPtr.contents.value)() + + if self.NativeAPI.CCAPIGetProcessList(NumProcessPtr, ProccessIDList) == CCAPIError.CCAPI_ERROR: + raise Exception("CCAPIGetProcessList() Failed") + + return list(ProccessIDList) + + def GetProcessName(self, ProcessID): + ProcessNamePtr = pointer(CCAPIProcessName()) + + if self.NativeAPI.CCAPIGetProcessName(ProcessID, ProcessNamePtr) == CCAPIError.CCAPI_OK: + ProcessName = ProcessNamePtr.contents.value + return ProcessName.decode("ascii") + + return None + + def AttachProcess(self, ProcessID=-1): + if ProcessID == -1: + ProcessList = self.GetProcessList() + + for Process in ProcessList: + ProcessName = self.GetProcessName(Process) + + if "dev_flash" not in ProcessName: + ProcessID = Process + break + + if ProcessID == -1: + raise Exception("Failed to find game process ID") + + self.ProcessID = ProcessID def ReadMemory(self, Address, Size): - raise Exception("CCAPI Not Implemented!!") + MemoryBuffer = (c_char * Size)() + + Error = self.NativeAPI.CCAPIGetMemory(self.ProcessID, Address, Size, MemoryBuffer) + + return bytes(MemoryBuffer) def WriteMemory(self, Address, Bytes): - raise Exception("CCAPI Not Implemented!!") \ No newline at end of file + WriteBuffer = (c_char * len(Bytes)).from_buffer(bytearray(Bytes)) + + Error = self.NativeAPI.CCAPISetMemory(self.ProcessID, Address, len(Bytes), WriteBuffer)