
ç¶æ³ãç°¡åã«æãåºããŸãã Mac OS Xçšã®ããã°ã©ã ããããŸããããã¯ãå€ãã®ãµãŒãããŒãã£ã®ãã€ãããã¯ãªã³ã¯ã©ã€ãã©ãªã䜿çšãããã®ã©ã€ãã©ãªã¯äºãã®æ©èœã䜿çšããŸãã
ã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ããããã©ã€ãã©ãªããå¥ã®ã©ã€ãã©ãªãžã®é¢æ°ã®åŒã³åºããã€ã³ã¿ãŒã»ãããããã³ãã©ãŒã§å ã®é¢æ°ãåŒã³åºããŸãã
ãã€ãã®ããã«ããã£ãã¡ãªäººã¯ä»ãããã¹ãŠãããŠã³ããŒãããŠè©Šãããšãã§ããŸã ã
ããããããããããã«ãæ¶ç©ºã®äŸã瀺ããŸããCèšèªã®ãtestããšåŒã°ããããã°ã©ã ïŒãã¡ã€ã«test.cïŒãšãäºåã«ã³ã³ãã€ã«ãããå 容ãå€æŽãããŠããªãå ±æã©ã€ãã©ãªïŒãã¡ã€ã«libtest.cïŒããããŸãã ãã®ã©ã€ãã©ãªã¯ã1ã€ã®é¢æ°libtestïŒïŒãæäŸããŸãã å®è£ ã§ã¯ããããããæšæºã®Cèšèªã©ã€ãã©ãªïŒlibSystem.B.dylibã«å«ãŸããMac OSã«ä»å±ïŒã®putsïŒïŒé¢æ°ã䜿çšããŸãã 説æããç¶æ³ã®æŠç¥å³ãèŠãŠã¿ãŸãããã

ã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ãã
- libtest.dylibã©ã€ãã©ãªã®putsïŒïŒé¢æ°åŒã³åºãããã¡ã€ã³ããã°ã©ã ïŒtest.cãã¡ã€ã«ïŒã«å®è£
ãããhooked_putsïŒïŒé¢æ°åŒã³åºãã«çœ®ãæããå¿
èŠããããŸãããã®é¢æ°åŒã³åºãã¯ãå
ã®putsïŒïŒã䜿çšã§ããŸãã
- è¡ãããå€æŽãç Žæ£ããŸããã€ãŸããlibtestïŒïŒã®ç¹°ãè¿ãåŒã³åºããå
ã®putïŒïŒã®åŒã³åºãã«ã€ãªããããšã確èªããŸãã
Mach-Oã«ã€ããŠç°¡åã«
Mach-Oãç解ããããã®æè¯ã®æ¹æ³ã¯ã以äžã®ç»åãèŠãããšã§ãã

人é¡ã¯ãŸã ãã®æ§é ãããæ確ã«æåã§ããŠããªãããã§ãã æåã®è¿äŒŒã§ã¯ããã¹ãŠã次ã®ããã«ãªããŸãã
- ã¿ã€ãã«-ã¿ãŒã²ããã¢ãŒããã¯ãã£ã«é¢ããæ å ±ãšããã¡ã€ã«ã®å 容ãããã«è§£éããããã®ããŸããŸãªãªãã·ã§ã³ãããã«ä¿åãããŸãã
- ããŠã³ããŒãã³ãã³ã-æåã«ããŒãããããã«ãMach-OããŒããããŠã³ããŒãããæ¹æ³ãšå Žæãã»ã°ã¡ã³ãïŒä»¥äžãåç §ïŒãã·ã³ãã«ããŒãã«ãããã³ãã®ãã¡ã€ã«ãäŸåããã©ã€ãã©ãªã瀺ããŸãã
- ã»ã°ã¡ã³ã-ã»ã¯ã·ã§ã³ã«ã³ãŒããŸãã¯ããŒã¿ãããŒãããã¡ã¢ãªé åãèšè¿°ããŸãã
ããŒãµãŒãŠãŒãã£ãªãã£
2çªç®ã®è¿äŒŒã«ã€ããŠã¯ãããã€ãã®ãŠãŒãã£ãªãã£ã«ç²Ÿéããå¿ èŠããããŸãã
- otool-ã·ã¹ãã ã«ä»å±ããŠããã³ã³ãœãŒã«ããã°ã©ã ã§ãã ãã¡ã€ã«ã®ããŸããŸãªéšåïŒããããŒãããŠã³ããŒãã³ãã³ããã»ã°ã¡ã³ããã»ã¯ã·ã§ã³ãªã©ïŒã®å 容ã衚瀺ã§ããŸãã èµ·åæã«-vïŒåé·ïŒã¹ã€ãããè¿œå ãããšç¹ã«äŸ¿å©ã§ãã
- MachOView -GPLã§é åžãããGUIããããMac OS 10.6以éã§ã®ã¿åäœããŸãã Mach-Oã®å šå 容ã衚瀺ã§ããŸããä»ã®éšåã®ããŒã¿ã«åºã¥ããŠãããã€ãã®ã»ã¯ã·ã§ã³ã®æ å ±ãè£è¶³ããŸããããã¯éåžžã«äŸ¿å©ã§ãã

æŠããŠãäžè¬ãŠãŒã¶ãŒã«ãšã£ãŠMach-Oãç解ããã«ã¯ãããŸããŸãªäŸã§MachOViewãè©ŠããŠãã ããã ããããããããŒãããŒãã³ãã³ããã»ã°ã¡ã³ããã»ã¯ã·ã§ã³ãã·ã³ãã«ããŒãã«ãããã³ãããã®ãã£ãŒã«ãã®æ£ç¢ºãªèª¬æã®æ£ç¢ºãªæ§é ã¯äžæã§ãããããããã¯Mach-Oããã°ã©ãã³ã°ã«ã¯ååã§ã¯ãããŸããã ããããããã¯ä»æ§ã«é¢ãã倧ããªåé¡ã§ã¯ãããŸããã ãããŠãå ¬åŒã®Apple Webãµã€ãã§ãã€ã§ãå©çšã§ããŸã ã ãŸããéçºããŒã«ãã€ã³ã¹ããŒã«ããŠããå Žåã¯ã/ usr / include / mach-oïŒç¹ã«loader.hïŒããããããŒãã¡ã€ã«ã確èªã§ããŸãã
ããã«ããã¡ã€ã«ã®å 容ã¯ãã£ã¹ã¯äžãšãŸã£ããåãé åºã§ã¡ã¢ãªå ã«ãããŸããããªã³ã«ã¯ã·ã³ãã«ããŒãã«ã®äžéšãè¡ã®ããŒãã«å šäœãåé€ããããŒãæã«ã¡ã¢ãªå ã®å®éã®ãªãã»ããã®å€ã眮ãããšãã§ããŸããå¿ èŠã«å¿ããŠããã¡ã€ã«å ã§ãããã®å€ãéåžžãŒãã«ãããããã£ã¹ã¯äžã®ãªãã»ããã«å¯Ÿå¿ãããããšãã§ããŸãã
ããããŒæ§é ã¯åçŽã§ãïŒ32ãããã¢ãŒããã¯ãã£ã®å Žåã¯åŒçšããŸããã64ãããã¯ããã»ã©å€ãããŸããïŒã
struct mach_header { uint32_t magic; cpu_type_t cputype; cpu_subtype_t cpusubtype; uint32_t filetype; uint32_t ncmds; uint32_t sizeofcmds; uint32_t flags; };
ãã¹ãŠã¯ããžãã¯å€ã§å§ãŸããŸãïŒæ©æ¢°èªã®ãã€ãé åºã«é¢ããåæã«å¿ããŠã0xFEEDFACEãŸãã¯ãã®éïŒã 次ã«ãããã»ããµã¢ãŒããã¯ãã£ã®ã¿ã€ããããŒãã³ãã³ãã®æ°ãšãµã€ãºãããã³ä»ã®æ©èœã説æãããã©ã°ã衚瀺ãããŸãã
äŸïŒ

å¿ é ã®ããŒãã³ãã³ãã¯æ¬¡ã®ãšããã§ãã
- LC_SEGMENT-ç¹å®ã®ã»ã°ã¡ã³ãã«é¢ããããŸããŸãªæ å ±ãå«ã¿ãŸãïŒãµã€ãºãã»ã¯ã·ã§ã³æ°ããã¡ã€ã«å ã®ãªãã»ãããããŒãåŸã®ã¡ã¢ãªå
- LC_SYMTAB-æåãšæååã®ããŒãã«ãããŒãããŸã
- LC_DYSYMTAB-ã€ã³ããŒãããŒãã«ãäœæããŸããæåããŒã¿ã¯æåããŒãã«ããååŸãããŸã
- LC_LOAD_DYLIB-ãµãŒãããŒãã£ã©ã€ãã©ãªãžã®äŸåé¢ä¿ã瀺ããŸã
![]() | ![]() |
æãéèŠãªã»ã°ã¡ã³ãã¯æ¬¡ã®ãšããã§ãã
- __TEXT-å®è¡å¯èœã³ãŒãããã³ãã®ä»ã®èªã¿åãå°çšããŒã¿
- __DATA-æžã蟌ã¿å¯èœãªããŒã¿ã ã€ã³ããŒãããŒãã«ãå«ã
- __OBJC-Objective-Cã©ã³ã¿ã€ã æšæºã©ã€ãã©ãªã®ããŸããŸãªæ å ±
- __IMPORT-32ãããã¢ãŒããã¯ãã£å°çšã®ããŒãã«ãã€ã³ããŒãããŸãïŒMac OS 10.5ã§ã®ã¿çæããŸããïŒ
- __LINKEDIT-ããã§ããã€ãããã¯ããŒããŒã¯ãæ¢ã«ããŒããããŠããã¢ãžã¥ãŒã«ïŒæåãæååãªã©ã®ããŒãã«ïŒã®ããŒã¿ãèŠã€ããŸãã
struct load_command { uint32_t cmd; // uint32_t cmdsize; // };
ãã®åŸãã³ãã³ãã®ã¿ã€ãã«å¿ããŠãããã«å€ãã®ç°ãªããã£ãŒã«ãããããŸãã
äŸïŒ

ãããã®ã»ã°ã¡ã³ãã§æãèå³æ·±ãã»ã¯ã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
- __TEXTã__ text-å®éã®ã³ãŒã
- __TEXTã__ cstring-å®æ°æååïŒäºéåŒçšç¬Šã§å²ã¿ãŸãïŒ
- __TEXTã__ const-ããŸããŸãªå®æ°
- __DATAã__ data-åæåãããå€æ°ïŒæååãšé åïŒ
- __DATAã__ la_symbol_ptr-ã€ã³ããŒããããé¢æ°ãžã®ãã€ã³ã¿ãŒã®ããŒãã«
- __DATAã__ bss-åæåãããŠããªãéçå€æ°
- __IMPORTã__ jump_table-ã€ã³ããŒããããé¢æ°ã®åŒã³åºãã®ã¹ã¿ã
ã»ã°ã¡ã³ãå ã®ã»ã¯ã·ã§ã³ã®æ§é ã¯æ¬¡ã®ãšããã§ãã
struct section { char sectname[16]; char segname[16]; uint32_t addr; uint32_t size; uint32_t offset; uint32_t align; uint32_t reloff; uint32_t nreloc; uint32_t flags; uint32_t reserved1; uint32_t reserved2; };
ã»ã°ã¡ã³ãã®ååãšã»ã¯ã·ã§ã³èªäœããµã€ãºããã¡ã€ã«å ã®ãªãã»ããããã€ãããã¯ããŒããŒãé 眮ããã¡ã¢ãªå ã®ã¢ãã¬ã¹ããããŸãã ããã«ãç¹å®ã®ã»ã¯ã·ã§ã³ã«åºæã®ä»ã®æ å ±ããããŸãã
äŸïŒ

ãã¡ãããã€ããª
ãã¡ãããAppleãã¿ãŒã²ããã¢ãŒããã¯ãã£ïŒMotorola-> IBM-> IntelïŒã®ã¹ã ãŒãºãªç§»è¡ãç¹°ãè¿ããçµæãå®è¡å¯èœãã¡ã€ã«ãšã©ã€ãã©ãªã¯ãè€æ°ã®ããŒãžã§ã³ã®å®è¡å¯èœã³ãŒããäžåºŠã«æ ŒçŽããããã«ãåŠç¿ãããããšã«èšåãã䟡å€ããããŸãã äžè¬ã«ããããã®ãã¡ã€ã«ã¯fat binaryãšåŒã°ããŸãã å®éããããã¯1ã€ã®ãã¡ã€ã«ã«éããããããã€ãã®Mach-Oã§ããããã®ããããŒã¯ç¹å¥ã§ãã ãµããŒããããŠããã¢ãŒããã¯ãã£ã®æ°ãšçš®é¡ãããã³åã¢ãŒããã¯ãã£ãžã®ãªãã»ããã«é¢ããæ å ±ãå«ãŸããŠããŸãã ãã®ãªãã»ããã«ã¯ãäžèšã®æ§é ãæã€éåžžã®Mach-OããããŸãã
Cã§ã¯æ¬¡ã®ããã«ãªããŸãã
struct fat_header { uint32_t magic; uint32_t nfat_arch; };
0xCAFEBABEãéæ³ã®äžã«é ãããŠããå ŽåïŒãŸãã¯ãã®é-ç°ãªãããã»ããµäžã®ãã·ã³èªã®ç°ãªããã€ãé ã«ã€ããŠèŠããŠãããŠãã ããïŒã ãããŠãã®åŸããã®åã®ã¡ããã©nfat_archæ§é ãããã«ç¶ããŸãïŒ
struct fat_arch { cpu_type_t cputype; cpu_subtype_t cpusubtype; uint32_t offset; uint32_t size; uint32_t align; };
å®éã«ã¯ããã£ãŒã«ãåã¯ãããã»ããµã®çš®é¡ãç¹å®ã®Mach-Oã®ãã¡ã€ã«å ã®ãªãã»ããããµã€ãºãããã³é 眮ãè¡šããŠããŸãã
å®éšããã°ã©ã
ã€ã³ããŒããããé¢æ°ãåŒã³åºãæäœã調ã¹ãããã«ãCã§æ¬¡ã®ãã¡ã€ã«ãååŸããŸãã
ãã¡ã€ã«test.c
void libtest(); //from libtest.dylib int main() { libtest(); //calls puts() from libSystem.B.dylib return 0; }
libtest.cãã¡ã€ã«
#include <stdio.h> void libtest() //just a simple library function { puts("libtest: calls the original puts()"); }
åçã¬ã€ã¢ãŠããæ¢çŽ¢ãã
Intelããã»ããµã«éå®ãããŠããŸãã Mac OS 10.5ãå ¥æããŸãããã ãããã®ãã¡ã€ã«ãæ°ããXcodeãããžã§ã¯ãã«è¿œå ããã³ã³ãã€ã«ïŒ32ãããããŒãžã§ã³ïŒããŠãããã°ã¢ãŒãã§å®è¡ããlibtest.dylibã©ã€ãã©ãªã®libtestïŒïŒé¢æ°ã§putsïŒïŒé¢æ°ãåŒã³åºãããè¡ã§åæ¢ããŸãã libtestïŒïŒã®ã¢ã»ã³ãã©ãªã¹ãã次ã«ç€ºããŸãã

ãã1ã€ã®åœä»€ãå®è¡ããŸãããã

ãããŠåœŒå¥³ã®èšæ¶ãèŠãŠãã ããïŒ

ããã¯ãã€ã³ããŒãããŒãã«ã®ã»ã«ïŒãã®å Žåãã»ã«__IMPORTã__ jump_tableïŒã§ãããã¬ã€ããã€ã³ãã£ã³ã°ïŒé 延ãã€ã³ãã£ã³ã°ïŒã䜿çšãããŠããå ŽåããŸãã¯ã¿ãŒã²ããé¢æ°ã«ããã«ãžã£ã³ãããå Žåããã€ãããã¯ããŒããŒïŒé¢æ°__dyld_stub_binding_helper_interfaceïŒãåŒã³åºãããã®ã¹ããªã³ã°ããŒããšããŠæ©èœããŸãã ããã¯ããã®åŸã®putsïŒïŒã®åŒã³åºãã«ãã£ãŠç¢ºèªãããŸãã

ãããŠã¡ã¢ãªå ïŒ

ãã®ããããã€ãããã¯ããŒããŒãCALLéæ¥åŒã³åºãåœä»€ïŒ0xE8ïŒãJMPéæ¥ãžã£ã³ãåœä»€ïŒ0xE9ïŒã«çœ®ãæããããšãããããŸãã ãããã£ãŠã__ jump_tableèŠçŽ ããªãã€ã¬ã¯ãããã«ã¯ãåæã³ã³ãã³ãã®ä»£ããã«ã眮æé¢æ°ã®å é ãžã®éæ¥é·ç§»ã®åœä»€ãèŠå®ããã ãã§ååã§ãã
ããäžã€ã®èå³æ·±ãç¹ã JMPããã€ãããã¯ããŒããŒïŒå¥åãªã³ã«ãŒïŒãžã®åãæ¿ãã«äœ¿çšãããªãã®ã¯ãªãã§ããïŒ ã¯ããã¹ã¿ãã¯ã«æ»ãã¢ãã¬ã¹ãæ ŒçŽããCALLã¯ãã€ã³ããŒãããŒãã«ã®ã©ã®èŠçŽ ãåŒã³åºãå ãåŒã³åºãããããªã³ã«ãå€æããã®ã«åœ¹ç«ã€ããã§ãã ãããã£ãŠãå¿ èŠãªæ©èœã®éæ¥JMPã䜿çšããŠCALLãããèªäœã«å€æŽããããšã«ãããã©ã®ãããªã·ã³ãã«ã§ããããèšç®ããæå¹ã«ããŸãã
次ã«ããããžã§ã¯ããMac OS 10.6ã«è»¢éãã32ãããããã³64ãããã¢ãŒããã¯ãã£çšã®ãã¡ãããã€ããªãã³ã³ãã€ã«ããŸãã 念ã®ãããXcodeã§ã¯æ¬¡ã®ããã«ããŸãã

ã³ã³ãã€ã«ãã64ãããããŒãžã§ã³ãå®è¡ããŠïŒããšãã°ãSnow Leopardã®ã€ã³ããŒãããŒãã«ã¯32ããããšåãã«ãªããŸãïŒãputsïŒïŒåŒã³åºãã§åã³åæ¢ããŸãã

ç¹°ãè¿ããŸãããåçŽãªCALLã§ãã ããã«èª¿æ»ããŸãã

ããã§ãéåžžã®__IMPORTã__ jump_tableãšã®éãã¯ãã§ã«é¡èã§ãã
__TEXTã__ symbol_stub1ãžããããã ãã®è¡šã¯ãã€ã³ããŒããããåé¢æ°ã®JMPåœä»€ã®ã»ããã§ãã ç§ãã¡ã®å Žåãäžèšã®ãããªæ瀺ã¯1ã€ãããããŸããã ãã®ãããªååœä»€ã¯ã__ DATAã__ la_symbol_ptrããŒãã«ã®å¯Ÿå¿ããã»ã«ã§æå®ãããã¢ãã¬ã¹ã«ç§»è¡ããŸãã åŸè ã¯ããã®Mach-Oã®ã€ã³ããŒãããŒãã«ã§ãã
ããããç 究ãç¶ããŸãããã 移è¡ãè¡ãããã¢ãã¬ã¹ãèŠããšïŒ

次ã«ã以äžã衚瀺ãããŸãã

__TEXTã__ stub_helperã»ã¯ã·ã§ã³ã«å ¥ããŸãã ããã¯åºæ¬çã«ãMach-Oã®PLTïŒããã·ãŒãžã£ãªã³ã±ãŒãžããŒãã«ïŒã§ãã æåã®åœä»€ïŒãã®å ŽåãR11ãšçµã¿åãããLEAããŸãã¯åçŽãªPUSHããã£ãå¯èœæ§ããããŸãïŒãåçãªã³ã«ãŒã¯åå²ãåœãŠãå¿ èŠãªã·ã³ãã«ãèšæ¶ãã2çªç®ã®åœä»€ã¯åžžã«åãã¢ãã¬ã¹ã«ã€ãªãããŸã-ãã€ã³ãã£ã³ã°ãåŠçãã__dyld_stub_binding_helperé¢æ°ã®éå§ïŒ

åçãªã³ã«ãŒãputsïŒïŒã®åé 眮ãå®è¡ãããšã__ DATAã__ la_symbol_ptrã®å¯Ÿå¿ããã»ã«ã¯æ¬¡ã®ããã«ãªããŸãã

ãããŠãããã¯libSystem.B.dylibã¢ãžã¥ãŒã«ã®putsïŒïŒé¢æ°ã®ã¢ãã¬ã¹ã§ãã ã€ãŸããã¢ãã¬ã¹ã«çœ®ãæãããšãã³ãŒã«ããªãã€ã¬ã¯ããããšããæãŸããå¹æãåŸãããŸãã
ã ããã ãã®æ®µéã§ãåçãªã³ã¯ã®çºçæ¹æ³ãMach-Oã®ã€ã³ããŒãããŒãã«ã®çš®é¡ãããã³ããããã©ã®èŠçŽ ã§æ§æãããŠããããç¹å®ã®äŸã䜿çšããŠç¢ºèªããŸããã ããã§ã¯ãMach-Oã®è§£æã«åãããããŸãããïŒ
ã€ã³ããŒãããŒãã«ã§ã¢ã€ãã ãæ€çŽ¢ãã
ã€ã³ããŒãããŒãã«ã§ãã·ã³ãã«ã®ååã§å¯Ÿå¿ããã»ã«ãèŠã€ããå¿ èŠããããŸãã ãã®ã¢ã¯ã·ã§ã³ã®ã¢ã«ãŽãªãºã ã¯ããéèŠã§ãã
ãŸãããã£ã©ã¯ã¿ãŒããŒãã«ã§ãã£ã©ã¯ã¿ãŒèªäœãèŠã€ããå¿ èŠããããŸãã åŸè ã¯ã次ã®æ§é ã®é åã§ãã
struct nlist { union { int32_t n_strx; } n_un; uint8_t n_type; uint8_t n_sect; int16_t n_desc; uint32_t n_value; };
n_un.n_strxã¯ããã®æåã®ååã®æååããŒãã«ã®å é ããã®ãã€ãåäœã®ãªãã»ããã§ãã æ®ãã¯ãã·ã³ãã«ã®ã¿ã€ããã·ã³ãã«ãé 眮ãããŠããã»ã¯ã·ã§ã³ãªã©ã«é¢ä¿ããŸãã ã€ãŸããå®éšã©ã€ãã©ãªlibtest.dylibïŒ32ãããããŒãžã§ã³ïŒã®æåŸã®èŠçŽ ã®äžéšã次ã«ç€ºããŸãã

è¡ããŒãã«ã¯ãããããããŒãã§çµããååã®ãã§ãŒã³ã§ãã ãã ããã³ã³ãã€ã©ã¯åååã®å é ã«ã¢ã³ããŒã¹ã³ã¢ã_ããè¿œå ãããããããšãã°ãæååããŒãã«ã§ã¯ãputsããšããååã¯ã_putsãã®ããã«ãªããŸãã
以äžã«äŸã瀺ããŸãã

察å¿ããããŒãã³ãã³ãïŒLC_SYMTABïŒããæåãšæååã®ããŒãã«ã®å ŽæãèŠã€ããããšãã§ããŸãã

ãã ããã·ã³ãã«ããŒãã«ã¯åäžã§ã¯ãããŸããã ããã€ãã®ã»ã¯ã·ã§ã³ããããŸãã ãã®ãã¡ã®1ã€ã¯ç¹ã«èå³æ·±ããã®ã§ãããããã¯æªå®çŸ©ïŒæªå®çŸ©ïŒã®æåãã€ãŸãåçã«ãªã³ã¯ãããŠããæåã§ãã ãšããã§ãMachOViewã¯èæ¯ãéã¿ããã£ããã®ã匷調衚瀺ããŸãã ã·ã³ãã«ããŒãã«ã®ã©ã®éšåãæªå®çŸ©ã®ã·ã³ãã«ã®ãµãã»ãããåæ ããŠããããå€æããã«ã¯ãåçã·ã³ãã«ããŒãã³ãã³ãïŒLC_DYSYMTABïŒã調ã¹ãå¿ èŠããããŸãã

Cã§ã®åœŒå¥³ã®ãã¬ãŒã³ããŒã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
struct dysymtab_command { uint32_t cmd; uint32_t cmdsize; uint32_t ilocalsym; uint32_t nlocalsym; uint32_t iextdefsym; uint32_t nextdefsym; uint32_t iundefsym; uint32_t nundefsym; uint32_t tocoff; uint32_t ntoc; uint32_t modtaboff; uint32_t nmodtab; uint32_t extrefsymoff; uint32_t nextrefsyms; uint32_t indirectsymoff; uint32_t nindirectsyms; uint32_t extreloff; uint32_t nextrel; uint32_t locreloff; uint32_t nlocrel; };
ããã§ãdysymtab_command.iundefsymã¯ãæªå®çŸ©ã®æåã®ãµãã»ããã§å§ãŸãæåããŒãã«ã®ã€ã³ããã¯ã¹ã§ãã dysymtab_command.nundefsym-æªå®çŸ©ã®æåã®æ°ã æ¢ããŠããã®ã¯æå³çã«äžå®ã®ã·ã³ãã«ãªã®ã§ããã®ãµãã»ããã®ã·ã³ãã«ããŒãã«ã§ã®ã¿æ€çŽ¢ããå¿
èŠããããŸãã
ãããŠä»ãéåžžã«éèŠãªç¹ïŒååã§ã·ã³ãã«ãèŠã€ããããšãç§ãã¡ã«ãšã£ãŠæãéèŠãªããšã¯ãã·ã³ãã«ããŒãã«ã®ã€ã³ããã¯ã¹ãæåããèŠããããšã§ãã ãããã®ã€ã³ããã¯ã¹ã®æ°å€ã¯å¥ã®éèŠãªããŒãã«ã§ãããããéæ¥ã·ã³ãã«ã®ããŒãã«ã§ãã dysymtab_command.indirectsymoffã®å€ã§èŠã€ããããšãã§ããã€ã³ããã¯ã¹ã®æ°ã«ãã£ãŠdysymtab_command.nindirectsymsã決ãŸããŸãã
äºçŽ°ãªã±ãŒã¹ã§ã¯ããã®ããŒãã«ã¯1ã€ã®èŠçŽ ã®ã¿ã§æ§æãããŠããŸãïŒå®éã«ã¯ããã«å€ãã®èŠçŽ ããããŸãïŒã

æåŸã«ãæåŸã«èŠã€ããå¿ èŠãããèŠçŽ ã®__IMPORTã__ jump_tableã»ã¯ã·ã§ã³ãèŠãŠã¿ãŸãããã 次ã®ããã«ãªããŸãã

ãã®ã»ã¯ã·ã§ã³ã®section.reserved1ãã£ãŒã«ãã¯éåžžã«éèŠã§ãïŒMachOViewã¯Indirect Sym IndexãšåŒã°ããŸãïŒã ããã¯ã__ jump_tableèŠçŽ ã§1察1ã®å¯Ÿå¿ãå§ãŸãéæ¥ã·ã³ãã«ããŒãã«ã®ã€ã³ããã¯ã¹ãæå³ããŸãã ãŸããéæ¥ã·ã³ãã«ããŒãã«ã®èŠçŽ ã¯ãã·ã³ãã«ããŒãã«ã®ã€ã³ããã¯ã¹ã§ããããšãèŠããŠããŸãã ç§ãåŸãŠãããã®ããã£ããããŸããïŒ
ããããæçµçã«ãã¹ãŠã®ç¥èãåéããåã«ãç»åãå®æãããããã«ã__ DATAã__ la_symbol_ptrãã€ã³ããŒãããŒãã«ã®åœ¹å²ãæããSnow Leopardã®ç¶æ³ãç°¡åã«èŠãŠã¿ãŸãããã å®éãéãã¯ããŸãç®ç«ã¡ãŸããã
以äžã¯ããã£ã©ã¯ã¿ãŒã®èªã¿èŸŒã¿ã³ãã³ãã§ãã

ãããŠãããã«åœŒå¥³ã®æåŸã®èŠçŽ ããããŸãïŒ

ãã€ãããã¯ã·ã³ãã«ããŒãã³ãã³ãïŒLC_DYSYMTABïŒããã®ããŒã¿ã«å¯Ÿå¿ãã2ã€ã®ãããŸããªæåãéã¿ããã£ãèæ¯ã«è¡šç€ºãããŸãã

ãŸããéæ¥ã·ã³ãã«ã®è¡šã«ã¯ããã§ã«1ã€ã®èŠçŽ ã§ã¯ãªãã4ã€ã®èŠçŽ ããããŸãã

ãã ããç§èµã»ã¯ã·ã§ã³__la_symbol_ptrã®reserved1ãã£ãŒã«ããèŠããšãéæ¥ã·ã³ãã«ã®ããŒãã«ã§ã®èŠçŽ ã®1察1ã®åæ ã¯ãæåŸã®èŠçŽ ã®å é ããã§ã¯ãªãã4çªç®ã®èŠçŽ ïŒã€ã³ããã¯ã¹ã¯3ïŒããå§ãŸãããšãããããŸãã

__la_symbol_ptrã»ã¯ã·ã§ã³ã§èª¬æãããŠããã€ã³ããŒãããŒãã«ã®å 容ã¯æ¬¡ã®ãšããã§ãã

ããããã¹ãŠã®Mach-Oã®åŸ®åŠããç¥ã£ãã®ã§ãã€ã³ããŒãããŒãã«ã§ç®çã®ã¢ã€ãã ãèŠã€ããããã®ã¢ã«ãŽãªãºã ãå®åŒåã§ããŸãã
ãªãã€ã¬ã¯ãã¢ã«ãŽãªãºã
ãã¹ãŠã®ã¢ã¯ã·ã§ã³ãèšèã§èª¬æããŸããã³ã¡ã³ããè±å¯ã«ããã«ãããããããã³ãŒãã¯ããã»ã©æ確ã§ã¯ãªãå¯èœæ§ãããããã§ãã
- LC_SYMTAB loadã³ãã³ãããã®ããŒã¿ã«åŸã£ãŠãæåãšè¡ã®ããŒãã«ãèŠã€ããŸãã
- LC_DYSYMTABããŒãã³ãã³ããããæªå®çŸ©ã®ã·ã³ãã«ã®ãµãã»ãããéå§ããã·ã³ãã«ããŒãã«ã®èŠçŽ ïŒiundefsymãã£ãŒã«ãïŒããåŠç¿ããŸãã
- æåããŒãã«å ã®æªå®çŸ©æåã®ãµãã»ããã®äžãããååã§ã¿ãŒã²ããæåãæ¢ããŠããŸãã
- ã·ã³ãã«ããŒãã«ã®å é ããã¿ãŒã²ããã·ã³ãã«ã®ã€ã³ããã¯ã¹ãèŠããŠããŸãã
- LC_DYSYMTABããŒãã³ãã³ãïŒindirectsymoffãã£ãŒã«ãïŒããã®ããŒã¿ã䜿çšããŠãéæ¥ã·ã³ãã«ã®ããŒãã«ãèŠã€ããŸãã
- éæ¥ã·ã³ãã«ããŒãã«ïŒreserved1ãã£ãŒã«ãïŒã§ãã€ã³ããŒãããŒãã«ã®è¡šç€ºãéå§ããã€ã³ããã¯ã¹ïŒ__DATAã__ la_symbol_ptrã»ã¯ã·ã§ã³ã®å 容ïŒãŸãã¯__IMPORTã__ jump_table-1ã€ãããŸãïŒïŒãèŠã€ããŸãã
- ãã®ã€ã³ããã¯ã¹ããå§ããŠãéæ¥ã·ã³ãã«ããŒãã«ãèŠãŠãã·ã³ãã«ããŒãã«å ã®ã¿ãŒã²ããã·ã³ãã«ã®ã€ã³ããã¯ã¹ã«å¯Ÿå¿ããå€ãæ¢ããŸãã
- ã€ã³ããŒãããŒãã«ãéæ¥ã·ã³ãã«ããŒãã«ã«è¡šç€ºããããšãã«ãæåããã¿ãŒã²ããã·ã³ãã«ããã£ãããããæ¹æ³ãèŠããŠããŸãã æ ŒçŽãããŠããå€ã¯ãã€ã³ããŒãããŒãã«å ã®ç®çã®ã¢ã€ãã ã®ã€ã³ããã¯ã¹ã§ãã
- __la_symbol_ptrïŒãŸãã¯__jump_tableïŒã»ã¯ã·ã§ã³ã®ããŒã¿ã«ãããšãã€ã³ããŒãããŒãã«ïŒãªãã»ãããã£ãŒã«ãïŒãèŠã€ãããŸãã
- ã¿ãŒã²ããèŠçŽ ã®ã€ã³ããã¯ã¹ãå«ãŸããŠããã®ã§ãã¢ãã¬ã¹ïŒ__la_symbol_ptrã®å ŽåïŒãå¿ èŠãªå€ã«æžãæããŸãïŒãŸãã¯ãªãã©ã³ãã䜿çšããŠCALL / JMPåœä»€ãJMPã«å€æŽããŸã-å¿ èŠãªé¢æ°ã®ã¢ãã¬ã¹ïŒ__jump_tableã®å ŽåïŒïŒã
ãªãã€ã¬ã¯ãã®å®è£
ããªãã®èããã³ãŒãã«å€ããæã§ãã ãªãã€ã¬ã¯ãããšã«å¿ èŠãªMach-OèŠçŽ ã®æ€çŽ¢ãæé©åããããã«ãæäœå šäœã3ã€ã®æ®µéã«åå²ããŸãã
void *mach_hook_init(char const *library_filename, void const *library_address);
struct mach_hook_handle { void const *library_address; //base address of a library in memory char const *string_table; //buffer to read string_table table from file struct nlist const *symbol_table; //buffer to read symbol table from file uint32_t const *indirect_table; //buffer to read the indirect symbol table in dynamic symbol table from file uint32_t undefined_symbols_count; //number of undefined symbols in the symbol table uint32_t undefined_symbols_index; //position of undefined symbols in the symbol table uint32_t indirect_symbols_count; //number of indirect symbols in the indirect symbol table of DYSYMTAB uint32_t indirect_symbols_index; //index of the first imported symbol in the indirect symbol table of DYSYMTAB uint32_t import_table_offset; //the offset of (__DATA, __la_symbol_ptr) or (__IMPORT, __jump_table) uint32_t jump_table_present; //special flag to show if we work with (__IMPORT, __jump_table) };
mach_substitution mach_hook(void const *handle, char const *function_name, mach_substitution substitution);
void mach_hook_free(void *handle);
ãããã®ãããã¿ã€ããèãããšããã¹ãããã°ã©ã ãæžãçŽãå¿ èŠããããŸãã
#include <stdio.h> #include <dlfcn.h> #include "mach_hook.h" #define LIBTEST_PATH "libtest.dylib" void libtest(); //from libtest.dylib int hooked_puts(char const *s) { puts(s); //calls the original puts() from libSystem.B.dylib, because our main executable module called "test" remains intact return puts("HOOKED!"); } int main() { void *handle = 0; //handle to store hook-related info mach_substitution original; //original data for restoration Dl_info info; if (!dladdr((void const *)libtest, &info)) //gets an address of a library which contains libtest() function { fprintf(stderr, "Failed to get the base address of a library!\n", LIBTEST_PATH); goto end; } handle = mach_hook_init(LIBTEST_PATH, info.dli_fbase); if (!handle) { fprintf(stderr, "Redirection init failed!\n"); goto end; } libtest(); //calls puts() from libSystem.B.dylib puts("-----------------------------"); original = mach_hook(handle, "puts", (mach_substitution)hooked_puts); if (!original) { fprintf(stderr, "Redirection failed!\n"); goto end; } libtest(); //calls hooked_puts() puts("-----------------------------"); original = mach_hook(handle, "puts", original); //restores the original relocation if (!original) { fprintf(stderr, "Restoration failed!\n"); goto end; } libtest(); //again calls puts() from libSystem.B.dylib end: mach_hook_free(handle); handle = 0; //no effect here, but just a good advice to prevent double freeing return 0; }
ãã¹ãã±ãŒã¹ã®å®å šãªå®è£ ã¯ããªãã€ã¬ã¯ãã¢ã«ãŽãªãºã ãšãããžã§ã¯ããã¡ã€ã«ãšå ±ã«ããŠã³ããŒãã§ããŸã ã
è©Šé転
次ã®ãããªãã®ãè©ŠããŠãã ããïŒ
user@mac$ arch -i386 ./test libtest: calls the original puts() ----------------------------- libtest: calls the original puts() HOOKED! ----------------------------- libtest: calls the original puts()
user@mac$ arch -x86_64 ./test libtest: calls the original puts() ----------------------------- libtest: calls the original puts() HOOKED! ----------------------------- libtest: calls the original puts()
ããã°ã©ã ã®çµè«ã¯ãæåã«èšå®ãããã¿ã¹ã¯ãå®å šã«å®è¡ãããããšã瀺ããŠããŸãã
䟿å©ãªãªã³ã¯
- Mac OS X ABI Mach-Oãã¡ã€ã«åœ¢åŒãªãã¡ã¬ã³ã¹
- Mach-oããã°ã©ãã³ã°ã®ãããã¯
- ãã€ãããã¯ãªã³ã¯ïŒELF vs. ããããª
- ãã€ãããã¯ã·ã³ãã«ããŒãã«ã®æ±ºéïŒELF察Mach-Oãã©ãŠã³ã2
- Apple Mac OS Xã®ãã€ãããã¯ããŒããŒãä»ããã©ã³ã¿ã€ã ãã€ããªã®èªã¿èŸŒã¿
- Mach-Oãé£ã°ã-Black Hat
- é«åºŠãªMac OS Xç©çã¡ã¢ãªåæ-Black Hat
- Mac OS Xã®ç Žå£