TuxeraNTFS-patcher.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #include <stdint.h>
  2. #include <stddef.h>
  3. #include <stdio.h>
  4. #include <memory.h>
  5. #include <openssl/err.h>
  6. #include <openssl/obj_mac.h>
  7. #include <openssl/ec.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <sys/types.h>
  11. #include <sys/errno.h>
  12. #include <sys/stat.h>
  13. #include <sys/mman.h>
  14. #define _countof(x) (sizeof((x))/sizeof((x)[0]))
  15. //--------in helper.c
  16. extern void PrintBytes(const uint8_t* bytes, size_t len);
  17. extern unsigned long PrintKeyInfo(const EC_KEY* lpcECKey, int* lperrno);
  18. //--------end
  19. const uint8_t OfficialPublicKey[] = {
  20. 0x47, 0xcf, 0xb5, 0xf7, 0xe8, 0x93, 0x1e, 0xc9, 0x3d, 0x42, 0xd1, 0x22, 0x1e, 0x7f,
  21. 0x98, 0x5d, 0x74, 0xaf, 0x45, 0x53, 0x70, 0xf3, 0x47, 0x39, 0x8e, 0x1b, 0x1d, 0x3e
  22. };
  23. const char* PatchFileList[] = {
  24. "/Library/PreferencePanes/Tuxera NTFS.prefPane/Contents/MacOS/Tuxera NTFS",
  25. "/Library/PreferencePanes/Tuxera NTFS.prefPane/Contents/Resources/WriteActivationData",
  26. "/Library/PreferencePanes/Tuxera NTFS.prefPane/Contents/Resources/WriteActivationDataTiger",
  27. "/Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.4/ntfsck",
  28. "/Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.4/tuxera_ntfs",
  29. "/Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.5/ntfsck",
  30. "/Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.5/tuxera_ntfs"
  31. };
  32. void DoPatch(uint8_t* lpFileContent,
  33. off_t Offset,
  34. const uint8_t* lpcNewPublicKey,
  35. size_t KeySize) {
  36. memset(lpFileContent + Offset,
  37. 0,
  38. sizeof(OfficialPublicKey));
  39. memcpy(lpFileContent + Offset,
  40. lpcNewPublicKey,
  41. KeySize);
  42. }
  43. off_t SearchOfficialPublicKey(uint8_t* lpFileContent, size_t FileSize, off_t start_offset) {
  44. off_t ret = -1;
  45. for (off_t i = start_offset; i + sizeof(uintptr_t) < FileSize; ++i)
  46. if (*(uintptr_t*)(lpFileContent + i) == *(uintptr_t*)OfficialPublicKey)
  47. if (0 == memcmp(lpFileContent + i, OfficialPublicKey, sizeof(OfficialPublicKey))) {
  48. ret = (off_t)i;
  49. break;
  50. }
  51. return ret;
  52. }
  53. int OpenFile(const char* lpszFilePath) {
  54. int fd = open(lpszFilePath, O_RDWR, S_IRUSR | S_IWUSR);
  55. if (fd == -1)
  56. printf("Failed to open file. CODE: 0x%08x\n", errno);
  57. return fd;
  58. }
  59. size_t GetFileSize(int fd) {
  60. struct stat fd_stat = {};
  61. if (fstat(fd, &fd_stat) != 0) {
  62. printf("Failed to get file size. CODE: 0x%08x\n", errno);
  63. return (size_t)-1;
  64. } else {
  65. return (size_t)fd_stat.st_size;
  66. }
  67. }
  68. void* MapFileContent(int fd, size_t map_size) {
  69. void* lpFileContent = (void*)-1;
  70. lpFileContent = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  71. if (lpFileContent == (void*)-1)
  72. printf("Failed to map file. CODE: 0x%08x\n", errno);
  73. return lpFileContent;
  74. }
  75. int UnmapFileContent(void* lpFileContent, size_t map_size) {
  76. return munmap(lpFileContent, map_size);
  77. }
  78. void StartPatch(const uint8_t* lpcNewPublicKey, size_t KeySize) {
  79. off_t offset = -1;
  80. int fd = -1;
  81. struct stat fd_stat = {};
  82. uint8_t* lpFileContent = NULL;
  83. printf("Patching...\n");
  84. for (size_t i = 0; i < _countof(PatchFileList); ++i) {
  85. int fd = -1;
  86. size_t stFileSize = (size_t)-1;
  87. uint8_t* lpFileContent = NULL;
  88. printf("Target file: %s\n", PatchFileList[i]);
  89. fd = OpenFile(PatchFileList[i]);
  90. if (fd == -1)
  91. return;
  92. printf("Open file successfully!\n");
  93. stFileSize = GetFileSize(fd);
  94. if (stFileSize == (size_t)-1) {
  95. close(fd);
  96. return;
  97. }
  98. printf("File size: %zu byte(s).\n", stFileSize);
  99. lpFileContent = MapFileContent(fd, stFileSize);
  100. if (lpFileContent == (void*)-1) {
  101. close(fd);
  102. return;
  103. }
  104. printf("Map file successfully!\n");
  105. int found = 0;
  106. off_t offset = -1;
  107. while (1) {
  108. offset = SearchOfficialPublicKey(lpFileContent, stFileSize, offset + 1);
  109. if (offset == -1)
  110. break;
  111. found++;
  112. printf("offset = 0x%016llx, writing data.....", offset);
  113. DoPatch(lpFileContent, offset, lpcNewPublicKey, KeySize);
  114. printf("Patch is done.\n");
  115. }
  116. printf("Modified: %d\n\n", found);
  117. UnmapFileContent(lpFileContent, stFileSize);
  118. close(fd);
  119. }
  120. }
  121. char SaveKey(const char* lpcszFileName,
  122. const uint8_t* lpcPrivateKey, size_t PrivateKeySize,
  123. const uint8_t* lpcPublicKey, size_t PublicKeySize) {
  124. int fd = open(lpcszFileName, O_RDWR | O_CREAT, 0666);
  125. if (fd == -1) {
  126. printf("Failed to create %s. CODE: 0x%08x\n", lpcszFileName, errno);
  127. return 0;
  128. }
  129. if (PrivateKeySize != write(fd, lpcPrivateKey, PrivateKeySize)) {
  130. printf("Failed to write private key or write incompletely. CODE: 0x%08x\n", errno);
  131. close(fd);
  132. return 0;
  133. }
  134. if (PublicKeySize != write(fd, lpcPublicKey, PublicKeySize)) {
  135. printf("Failed to write public key or write incompletely. CODE: 0x%08x\n", errno);
  136. close(fd);
  137. return 0;
  138. }
  139. printf("Write private key to %s successfully.\n", lpcszFileName);
  140. close(fd);
  141. return 1;
  142. }
  143. int main(int argc, char* argv[]) {
  144. unsigned long ErrorCode = 0;
  145. EC_KEY* newKey = NULL;
  146. const BIGNUM* PrivateKey = NULL;
  147. const EC_POINT* PublicKey = NULL;
  148. BIGNUM* PublicKeyX = NULL;
  149. BIGNUM* PublicKeyY = NULL;
  150. uint8_t binPrivateKey[14] = { };
  151. uint8_t binPublicKey[2][14] = { };
  152. newKey = EC_KEY_new_by_curve_name(NID_secp112r1);
  153. if (newKey == NULL) {
  154. ErrorCode = ERR_get_error();
  155. goto On_main_Error;
  156. }
  157. if (!EC_KEY_generate_key(newKey)) {
  158. ErrorCode = ERR_get_error();
  159. goto On_main_Error;
  160. }
  161. ErrorCode = PrintKeyInfo(newKey, NULL);
  162. if (ErrorCode) {
  163. goto On_main_Error;
  164. } else if (errno) {
  165. ErrorCode = (unsigned long)errno;
  166. goto On_main_Error;
  167. }
  168. PrivateKey = EC_KEY_get0_private_key(newKey);
  169. if (PrivateKey == NULL) {
  170. ErrorCode = ERR_get_error();
  171. goto On_main_Error;
  172. }
  173. PublicKey = EC_KEY_get0_public_key(newKey);
  174. if (PublicKey == NULL) {
  175. ErrorCode = ERR_get_error();
  176. goto On_main_Error;
  177. }
  178. PublicKeyX = BN_new();
  179. if (PublicKeyX == NULL) {
  180. ErrorCode = ERR_get_error();
  181. goto On_main_Error;
  182. }
  183. PublicKeyY = BN_new();
  184. if (PublicKeyY == NULL) {
  185. ErrorCode = ERR_get_error();
  186. goto On_main_Error;
  187. }
  188. if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(newKey),
  189. PublicKey,
  190. PublicKeyX,
  191. PublicKeyY,
  192. NULL)) {
  193. ErrorCode = ERR_get_error();
  194. goto On_main_Error;
  195. }
  196. if (!BN_bn2bin(PrivateKey, binPrivateKey + sizeof(binPrivateKey) - BN_num_bytes(PrivateKey))) {
  197. ErrorCode = ERR_get_error();
  198. goto On_main_Error;
  199. }
  200. if (!BN_bn2bin(PublicKeyX, binPublicKey[0] + sizeof(binPublicKey[0]) - BN_num_bytes(PublicKeyX))) {
  201. ErrorCode = ERR_get_error();
  202. goto On_main_Error;
  203. }
  204. if (!BN_bn2bin(PublicKeyY, binPublicKey[1] + sizeof(binPublicKey[1]) - BN_num_bytes(PublicKeyY))) {
  205. ErrorCode = ERR_get_error();
  206. goto On_main_Error;
  207. }
  208. if(!SaveKey("tuxera_key.bin",
  209. binPrivateKey, sizeof(binPrivateKey),
  210. (uint8_t*)binPublicKey, sizeof(binPublicKey))) {
  211. goto On_main_Error;
  212. }
  213. printf("\n");
  214. StartPatch((uint8_t*)binPublicKey, sizeof(binPublicKey));
  215. On_main_Error:
  216. if (PublicKeyY)
  217. BN_free(PublicKeyY);
  218. if (PublicKeyX)
  219. BN_free(PublicKeyX);
  220. if (newKey)
  221. EC_KEY_free(newKey);
  222. if (ErrorCode)
  223. printf("%s\n", ERR_error_string(ErrorCode, NULL));
  224. return (int)ErrorCode;
  225. }