getImageNameHook.m 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // TEST_CONFIG
  2. #include "test.h"
  3. #include "testroot.i"
  4. @interface One : TestRoot @end
  5. @implementation One @end
  6. @interface Two : TestRoot @end
  7. @implementation Two @end
  8. @interface Both : TestRoot @end
  9. @implementation Both @end
  10. @interface None : TestRoot @end
  11. @implementation None @end
  12. objc_hook_getImageName OnePreviousHook;
  13. BOOL GetImageNameHookOne(Class cls, const char **outName)
  14. {
  15. if (0 == strcmp(class_getName(cls), "One")) {
  16. *outName = "Image One";
  17. return YES;
  18. } else if (0 == strcmp(class_getName(cls), "Both")) {
  19. *outName = "Image Both via One";
  20. return YES;
  21. } else {
  22. return OnePreviousHook(cls, outName);
  23. }
  24. }
  25. objc_hook_getImageName TwoPreviousHook;
  26. BOOL GetImageNameHookTwo(Class cls, const char **outName)
  27. {
  28. if (0 == strcmp(class_getName(cls), "Two")) {
  29. *outName = "Image Two";
  30. return YES;
  31. } else if (0 == strcmp(class_getName(cls), "Both")) {
  32. *outName = "Image Both via Two";
  33. return YES;
  34. } else {
  35. return TwoPreviousHook(cls, outName);
  36. }
  37. }
  38. int main()
  39. {
  40. // before hooks: main executable is the image name for four classes
  41. testassert(strstr(class_getImageName([One class]), "getImageNameHook"));
  42. testassert(strstr(class_getImageName([Two class]), "getImageNameHook"));
  43. testassert(strstr(class_getImageName([Both class]), "getImageNameHook"));
  44. testassert(strstr(class_getImageName([None class]), "getImageNameHook"));
  45. testassert(strstr(class_getImageName([NSObject class]), "libobjc"));
  46. // install hook One
  47. objc_setHook_getImageName(GetImageNameHookOne, &OnePreviousHook);
  48. // two classes are in Image One with hook One in place
  49. testassert(strstr(class_getImageName([One class]), "Image One"));
  50. testassert(strstr(class_getImageName([Two class]), "getImageNameHook"));
  51. testassert(strstr(class_getImageName([Both class]), "Image Both via One"));
  52. testassert(strstr(class_getImageName([None class]), "getImageNameHook"));
  53. testassert(strstr(class_getImageName([NSObject class]), "libobjc"));
  54. // install hook Two which chains to One
  55. objc_setHook_getImageName(GetImageNameHookTwo, &TwoPreviousHook);
  56. // two classes are in Image Two and one in One with both hooks in place
  57. testassert(strstr(class_getImageName([One class]), "Image One"));
  58. testassert(strstr(class_getImageName([Two class]), "Image Two"));
  59. testassert(strstr(class_getImageName([Both class]), "Image Both via Two"));
  60. testassert(strstr(class_getImageName([None class]), "getImageNameHook"));
  61. testassert(strstr(class_getImageName([NSObject class]), "libobjc"));
  62. succeed(__FILE__);
  63. }