debugserver.pxi 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. cdef extern from "libimobiledevice/debugserver.h":
  2. cdef struct debugserver_client_private:
  3. pass
  4. ctypedef debugserver_client_private *debugserver_client_t
  5. cdef struct debugserver_command_private:
  6. pass
  7. ctypedef debugserver_command_private *debugserver_command_t
  8. ctypedef enum debugserver_error_t:
  9. DEBUGSERVER_E_SUCCESS = 0
  10. DEBUGSERVER_E_INVALID_ARG = -1
  11. DEBUGSERVER_E_MUX_ERROR = -2
  12. DEBUGSERVER_E_SSL_ERROR = -3
  13. DEBUGSERVER_E_RESPONSE_ERROR = -4
  14. DEBUGSERVER_E_UNKNOWN_ERROR = -256
  15. debugserver_error_t debugserver_client_new(idevice_t device, lockdownd_service_descriptor_t service, debugserver_client_t * client)
  16. debugserver_error_t debugserver_client_free(debugserver_client_t client)
  17. debugserver_error_t debugserver_client_send(debugserver_client_t client, const char* data, uint32_t size, uint32_t *sent)
  18. debugserver_error_t debugserver_client_send_command(debugserver_client_t client, debugserver_command_t command, char** response)
  19. debugserver_error_t debugserver_client_receive(debugserver_client_t client, char *data, uint32_t size, uint32_t *received)
  20. debugserver_error_t debugserver_client_receive_with_timeout(debugserver_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout)
  21. debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response)
  22. debugserver_error_t debugserver_client_set_argv(debugserver_client_t client, int argc, char* argv[], char** response)
  23. debugserver_error_t debugserver_client_set_environment_hex_encoded(debugserver_client_t client, const char* env, char** response)
  24. debugserver_error_t debugserver_command_new(const char* name, int argc, const char* argv[], debugserver_command_t* command)
  25. debugserver_error_t debugserver_command_free(debugserver_command_t command)
  26. void debugserver_encode_string(const char* buffer, char** encoded_buffer, uint32_t* encoded_length)
  27. void debugserver_decode_string(const char *encoded_buffer, size_t encoded_length, char** buffer)
  28. cdef class DebugServerError(BaseError):
  29. def __init__(self, *args, **kwargs):
  30. self._lookup_table = {
  31. DEBUGSERVER_E_SUCCESS: "Success",
  32. DEBUGSERVER_E_INVALID_ARG: "Invalid argument",
  33. DEBUGSERVER_E_MUX_ERROR: "MUX error",
  34. DEBUGSERVER_E_SSL_ERROR: "SSL error",
  35. DEBUGSERVER_E_RESPONSE_ERROR: "Response error",
  36. DEBUGSERVER_E_UNKNOWN_ERROR: "Unknown error",
  37. }
  38. BaseError.__init__(self, *args, **kwargs)
  39. # from http://stackoverflow.com/a/17511714
  40. from cpython.string cimport PyString_AsString
  41. cdef char ** to_cstring_array(list_str):
  42. if not list_str:
  43. return NULL
  44. cdef char **ret = <char **>malloc(len(list_str) * sizeof(char *))
  45. for i in xrange(len(list_str)):
  46. ret[i] = PyString_AsString(list_str[i])
  47. return ret
  48. cdef class DebugServerCommand(Base):
  49. cdef debugserver_command_t _c_command
  50. def __init__(self, bytes name, int argc = 0, argv = None, *args, **kwargs):
  51. cdef:
  52. char* c_name = name
  53. char** c_argv = to_cstring_array(argv)
  54. try:
  55. self.handle_error(debugserver_command_new(c_name, argc, c_argv, &self._c_command))
  56. except BaseError, e:
  57. raise
  58. finally:
  59. free(c_argv)
  60. def __enter__(self):
  61. return self
  62. def __exit__(self, type, value, traceback):
  63. self.free()
  64. cdef free(self):
  65. cdef debugserver_error_t err
  66. if self._c_command is not NULL:
  67. err = debugserver_command_free(self._c_command)
  68. self.handle_error(err)
  69. cdef inline BaseError _error(self, int16_t ret):
  70. return DebugServerError(ret)
  71. cdef class DebugServerClient(BaseService):
  72. __service_name__ = "com.apple.debugserver"
  73. cdef debugserver_client_t _c_client
  74. def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs):
  75. if (device is not None and descriptor is not None):
  76. self.handle_error(debugserver_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client)))
  77. def __dealloc__(self):
  78. cdef debugserver_error_t err
  79. if self._c_client is not NULL:
  80. err = debugserver_client_free(self._c_client)
  81. self.handle_error(err)
  82. cdef BaseError _error(self, int16_t ret):
  83. return DebugServerError(ret)
  84. cpdef uint32_t send(self, bytes data):
  85. cdef:
  86. uint32_t bytes_send
  87. char* c_data = data
  88. try:
  89. self.handle_error(debugserver_client_send(self._c_client, c_data, len(data), &bytes_send))
  90. except BaseError, e:
  91. raise
  92. return bytes_send
  93. cpdef bytes send_command(self, DebugServerCommand command):
  94. cdef:
  95. char* c_response = NULL
  96. bytes result
  97. try:
  98. self.handle_error(debugserver_client_send_command(self._c_client, command._c_command, &c_response))
  99. if c_response:
  100. result = c_response
  101. return result
  102. else:
  103. return None
  104. except BaseError, e:
  105. raise
  106. finally:
  107. free(c_response)
  108. cpdef bytes receive(self, uint32_t size):
  109. cdef:
  110. uint32_t bytes_received
  111. char* c_data = <char *>malloc(size)
  112. bytes result
  113. try:
  114. self.handle_error(debugserver_client_receive(self._c_client, c_data, size, &bytes_received))
  115. result = c_data[:bytes_received]
  116. return result
  117. except BaseError, e:
  118. raise
  119. finally:
  120. free(c_data)
  121. cpdef bytes receive_with_timeout(self, uint32_t size, unsigned int timeout):
  122. cdef:
  123. uint32_t bytes_received
  124. char* c_data = <char *>malloc(size)
  125. bytes result
  126. try:
  127. self.handle_error(debugserver_client_receive_with_timeout(self._c_client, c_data, size, &bytes_received, timeout))
  128. result = c_data[:bytes_received]
  129. return result
  130. except BaseError, e:
  131. raise
  132. finally:
  133. free(c_data)
  134. cpdef bytes receive_response(self):
  135. cdef:
  136. char* c_response = NULL
  137. bytes result
  138. try:
  139. self.handle_error(debugserver_client_receive_response(self._c_client, &c_response))
  140. if c_response:
  141. result = c_response
  142. return result
  143. else:
  144. return None
  145. except BaseError, e:
  146. raise
  147. finally:
  148. free(c_response)
  149. cpdef bytes set_argv(self, int argc, argv):
  150. cdef:
  151. char** c_argv = to_cstring_array(argv)
  152. char* c_response = NULL
  153. bytes result
  154. try:
  155. self.handle_error(debugserver_client_set_argv(self._c_client, argc, c_argv, &c_response))
  156. if c_response:
  157. result = c_response
  158. return result
  159. else:
  160. return None
  161. except BaseError, e:
  162. raise
  163. finally:
  164. free(c_argv)
  165. free(c_response)
  166. cpdef bytes set_environment_hex_encoded(self, bytes env):
  167. cdef:
  168. char* c_env = env
  169. char* c_response = NULL
  170. bytes result
  171. try:
  172. self.handle_error(debugserver_client_set_environment_hex_encoded(self._c_client, c_env, &c_response))
  173. if c_response:
  174. result = c_response
  175. return result
  176. else:
  177. return None
  178. except BaseError, e:
  179. raise
  180. finally:
  181. free(c_response)
  182. cpdef bytes encode_string(self, bytes buffer):
  183. cdef:
  184. char *c_buffer = buffer
  185. uint32_t encoded_length = len(c_buffer) * 2 + 0x3 + 1
  186. char* c_encoded_buffer = <char *>malloc(encoded_length)
  187. bytes result
  188. try:
  189. debugserver_encode_string(c_buffer, &c_encoded_buffer, &encoded_length)
  190. result = c_encoded_buffer[:encoded_length]
  191. return result
  192. except BaseError, e:
  193. raise
  194. finally:
  195. free(c_encoded_buffer)
  196. cpdef bytes decode_string(self, bytes encoded_buffer):
  197. cdef:
  198. char* c_encoded_buffer = encoded_buffer
  199. uint32_t encoded_length = len(c_encoded_buffer)
  200. char *c_buffer = <char *>malloc(encoded_length)
  201. bytes result
  202. try:
  203. debugserver_decode_string(c_encoded_buffer, encoded_length, &c_buffer)
  204. result = c_buffer
  205. return result
  206. except BaseError, e:
  207. raise
  208. finally:
  209. free(c_buffer)