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.* diff --git a/ps3api/ccapi.py b/ps3api/ccapi.py index 8ee17c7..39fdf94 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 StatusLed(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 ''' @@ -133,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); @@ -142,16 +151,16 @@ 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); 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 ''' 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(); @@ -254,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) - def ConnectTarget(self, TargetIndex): - raise Exception("CCAPI Not Implemented!!") + if IP == None: + raise Exception("Failed to find console info") - def AttachProcess(self): - raise Exception("CCAPI Not Implemented!!") + print(IP) + + return self.ConnectTargetWithIP(IP) + + 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) 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_)