osobject.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include <stdlib.h>
  2. #include "kexecute.h"
  3. #include "kmem.h"
  4. #include "patchfinder64.h"
  5. #include "osobject.h"
  6. // offsets in vtable:
  7. static uint32_t off_OSDictionary_SetObjectWithCharP = sizeof(void*) * 0x1F;
  8. static uint32_t off_OSDictionary_GetObjectWithCharP = sizeof(void*) * 0x26;
  9. static uint32_t off_OSDictionary_Merge = sizeof(void*) * 0x23;
  10. static uint32_t off_OSArray_Merge = sizeof(void*) * 0x1E;
  11. static uint32_t off_OSArray_RemoveObject = sizeof(void*) * 0x20;
  12. static uint32_t off_OSArray_GetObject = sizeof(void*) * 0x22;
  13. static uint32_t off_OSObject_Release = sizeof(void*) * 0x05;
  14. static uint32_t off_OSObject_GetRetainCount = sizeof(void*) * 0x03;
  15. static uint32_t off_OSObject_Retain = sizeof(void*) * 0x04;
  16. static uint32_t off_OSString_GetLength = sizeof(void*) * 0x11;
  17. // 1 on success, 0 on error
  18. int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val) {
  19. size_t len = strlen(key) + 1;
  20. uint64_t ks = kalloc(len);
  21. kwrite(ks, key, len);
  22. uint64_t vtab = rk64(dict);
  23. uint64_t f = rk64(vtab + off_OSDictionary_SetObjectWithCharP);
  24. int rv = (int) kexecute(f, dict, ks, val, 0, 0, 0, 0);
  25. kfree(ks, len);
  26. return rv;
  27. }
  28. // XXX it can return 0 in lower 32 bits but still be valid
  29. // fix addr of returned value and check if rk64 gives ptr
  30. // to vtable addr saved before
  31. // address if exists, 0 if not
  32. uint64_t _OSDictionary_GetItem(uint64_t dict, const char *key) {
  33. size_t len = strlen(key) + 1;
  34. uint64_t ks = kalloc(len);
  35. kwrite(ks, key, len);
  36. uint64_t vtab = rk64(dict);
  37. uint64_t f = rk64(vtab + off_OSDictionary_GetObjectWithCharP);
  38. int rv = (int) kexecute(f, dict, ks, 0, 0, 0, 0, 0);
  39. kfree(ks, len);
  40. return rv;
  41. }
  42. uint64_t OSDictionary_GetItem(uint64_t dict, const char *key) {
  43. uint64_t ret = _OSDictionary_GetItem(dict, key);
  44. if (ret != 0) {
  45. // XXX can it be not in zalloc?..
  46. ret = zm_fix_addr(ret);
  47. }
  48. return ret;
  49. }
  50. // 1 on success, 0 on error
  51. int OSDictionary_Merge(uint64_t dict, uint64_t aDict) {
  52. uint64_t vtab = rk64(dict);
  53. uint64_t f = rk64(vtab + off_OSDictionary_Merge);
  54. return (int) kexecute(f, dict, aDict, 0, 0, 0, 0, 0);
  55. }
  56. // 1 on success, 0 on error
  57. int OSArray_Merge(uint64_t array, uint64_t aArray) {
  58. uint64_t vtab = rk64(array);
  59. uint64_t f = rk64(vtab + off_OSArray_Merge);
  60. return (int) kexecute(f, array, aArray, 0, 0, 0, 0, 0);
  61. }
  62. uint64_t _OSArray_GetObject(uint64_t array, unsigned int idx){
  63. uint64_t vtab = rk64(array);
  64. uint64_t f = rk64(vtab + off_OSArray_GetObject);
  65. return kexecute(f, array, idx, 0, 0, 0, 0, 0);
  66. }
  67. uint64_t OSArray_GetObject(uint64_t array, unsigned int idx){
  68. uint64_t ret = _OSArray_GetObject(array, idx);
  69. if (ret != 0){
  70. // XXX can it be not in zalloc?..
  71. ret = zm_fix_addr(ret);
  72. }
  73. return ret;
  74. }
  75. void OSArray_RemoveObject(uint64_t array, unsigned int idx){
  76. uint64_t vtab = rk64(array);
  77. uint64_t f = rk64(vtab + off_OSArray_RemoveObject);
  78. (void)kexecute(f, array, idx, 0, 0, 0, 0, 0);
  79. }
  80. // XXX error handling just for fun? :)
  81. uint64_t _OSUnserializeXML(const char* buffer) {
  82. size_t len = strlen(buffer) + 1;
  83. uint64_t ks = kalloc(len);
  84. kwrite(ks, buffer, len);
  85. uint64_t errorptr = 0;
  86. uint64_t rv = kexecute(find_osunserializexml(), ks, errorptr, 0, 0, 0, 0, 0);
  87. kfree(ks, len);
  88. return rv;
  89. }
  90. uint64_t OSUnserializeXML(const char* buffer) {
  91. uint64_t ret = _OSUnserializeXML(buffer);
  92. if (ret != 0) {
  93. // XXX can it be not in zalloc?..
  94. ret = zm_fix_addr(ret);
  95. }
  96. return ret;
  97. }
  98. void OSObject_Release(uint64_t osobject) {
  99. uint64_t vtab = rk64(osobject);
  100. uint64_t f = rk64(vtab + off_OSObject_Release);
  101. (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0);
  102. }
  103. void OSObject_Retain(uint64_t osobject) {
  104. uint64_t vtab = rk64(osobject);
  105. uint64_t f = rk64(vtab + off_OSObject_Release);
  106. (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0);
  107. }
  108. uint32_t OSObject_GetRetainCount(uint64_t osobject) {
  109. uint64_t vtab = rk64(osobject);
  110. uint64_t f = rk64(vtab + off_OSObject_Release);
  111. return (uint32_t) kexecute(f, osobject, 0, 0, 0, 0, 0, 0);
  112. }
  113. unsigned int OSString_GetLength(uint64_t osstring){
  114. uint64_t vtab = rk64(osstring);
  115. uint64_t f = rk64(vtab + off_OSString_GetLength);
  116. return (unsigned int)kexecute(f, osstring, 0, 0, 0, 0, 0, 0);
  117. }
  118. char *OSString_CopyString(uint64_t osstring){
  119. unsigned int length = OSString_GetLength(osstring);
  120. char *str = (char *)malloc(length + 1);
  121. str[length] = 0;
  122. kread(OSString_CStringPtr(osstring), str, length);
  123. return str;
  124. }