_____ _______ .~. / __ \ |___ (_) /V\ | / \/ ___ _ __ ___ / / _ _ __ ___ // \\ | | / _ \| '__/ _ \ / / | | '_ \ / _ \ /( )\ | \__/\ (_) | | | __/./ /__| | | | | __/ ^`~'^ \____/\___/|_| \___|\_____/_|_| |_|\___| ------[ Corezine volume 02 - August 1999 Corezine #02 ================== ¹ø¿ª : truefinder , seo@igrus.inha.ac.kr Last update : 2002/02/18 RUNTIME KERNEL KMEM PATCHING - Silvio Cesare - November 1998 INTRODUCTION ÀÌ ¹®¼­´Â Ä¿³Î ¸Þ¸ð¸®¿¡ ´ÙÀÌ·ºÆ®·Î Á¢±ÙÇÏ´Â ¹æ½ÄÀ» ÅëÇÑ runtime kernel patching±â¹ýÀ» ±â¼úÇÑ´Ù. °ø°ÝÀÚ¿¡ÀÇÇØ »ç¿ëµÇ´Â Ä¿³Î ÆÐĪÀÇ ¿¹´Â lsmod¿¡ lkmÀÇ visuality¸¦ Á¦°ÅÇÏ´Â ±â¹ýÀÌ º¸¿©Áø´Ù. ±×¸®°í Âü°í·Î loadable kernel modulesÀÌ native lkmÀ» ¼­Æ÷Æ® ÇÏÁö ¾Ê´Â ½Ã½ºÅÛ¿¡¼­Á¶Â÷ runtimeÀ¸·Î ¼öÇàµÈ´Ù´Â °ÍÀÌ´Ù. ¿ì¸®ÀÇ ³íÀÇ´Â system symbol mapÀ» ÀûÀýÇÏ°Ô À籸¼ºÇÏ´Â °Í±îÁö ´Ù·ç¾îÁø´Ù. ÀÌ ¹®¼­¿¡¼­ ¸ñÀûÇÏ´Â ¹Ù¸¦ À§ÇØ linux kernel programming skillsÀÌ ÇÊ¿äÇÏ´Ù. ELF¸¦ »ç¿ëÇØ¼­ object code¸¦ linkingÇÏ´Â ¼½¼ÇÀ» À§Çؼ­´Â, ... Èï¹ÌÀÖ´Â µ¶ÀÚµéÀº ELFÀÇ specÀ» ã¾Æº¸±â¸¦ °­·ÂÈ÷ ÃßõÇÑ´Ù. ±¸ÇöµÈ °ÍÀ» ¸ðµÎ ÀÌÇØÇß´Ù¸é À̰ÍÀº Ưº°È÷ ´ç½Å¿¡°Ô´Â Áø½ÇÀÌ´Ù. THE KERNEL SYMBOL LIST Linux´Â symbolµéÀÌ export µÇ¾ú´øÁö ±×·¸Áö ¾Ê¾Ò´øÁö °£¿¡ kernel¿¡ ÀÇÇØ ¾²ÀÌ´Â ¸ðµç symbolÀ» À§Ä¡½Ã۱â À§ÇÑ ¼ö´ÜÀ» Á¦°øÇÑ´Ù. À̰ÍÀº System.map¿¡ ÀÇÇØ °¡´ÉÇÏ´Ù. À̰ÍÀº Ä¿³Î ÄÄÆÄÀÏÀ» À§ÇØ ¾²ÀÌ´Â object file¿¡¼­ symbol Á¤º¸¸¦ ÃßÃâÇÔÀ¸·Î½á ÄÄÆÄÀϽÿ¡ ¸¸µé¾î Áö°Ô µÈ´Ù. # cat /System.map 00100000 T _stext 00100000 T stext 00100000 t startup_32 001000bc t isnew 00100118 t is486x 00100183 t n6x86 . . . ±×·¡¼­ ¿ì¸®´Â symbolµéÀ» À̸§À¸·Î identifyÇÑ´Ù´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù. ¿ì¸®°¡ Á÷Á¢ »ç¿ëÇÒ¼ö ÀÖ´Â address´Â /dev/kmemÀ» ÅëÇÑ Ä¿³Î ¸Þ¸ð¸®¸¦ ÂüÁ¶ÇÑ´Ù. exportedµÈ Kernel symbolµéÀº globalÇÏ°Ô visibleÇϸç, Ä¿³Î³»¿¡¼­ À¯ÁöµÈ´Ù. ±×¸®°í À̰ÍÀº ÀÌ¹Ì ¼³¸íÇßµíÀÌ System.mapÀ» ÇÊ¿ä·ÎÇÏÁö ¾Ê´Â /proc/ksysm°ú get-kernel_syms() À» ÅëÇØ user-land¿¡ À¯È¿ÇÏ´Ù. ±×·¯³ª À̰ÍÀº lkm support°¡ Ä¿³Î¿¡ ÄÄÆÄÀϵǾúÀ»¶§¸¸ À¯È¿ÇÏ´Ù. DIRECT KERNEL MEMORY ACCESS IN LINUX ¸®´ª½º»ó¿¡¼­ÀÇ ¸Þ¸ð¸® direct access´Â µÎ°³ÀÇ device file¿¡ ÀÇÇØ¼­ Á¦°øµÈ´Ù. /dev/mem Àº ¼±Çü¸Þ¸ð¸®ÀÇ ¸ÅÇÎÈ­ÀÏÀÌ´Ù. /dev/kmemÀº »ç¿ë°¡´ÉÇÑ ¸ðµç °¡»ó¸Þ¸ð¸®ÀÇ ¸ÅÇÎÈ­ÀÏÀÌ´Ù. À̰ÍÀº ¼±Çü ¸Þ¸ð¸®°¡ swap°ø°£À» ´õÇÑ´Ù´Â °ÍÀÌ´Ù. deviceÈ­ÀϵéÀ» ¸Þ¸ð¸®·Î »ç¿ëÇϱâ À§ÇØ ±×°ÍÀ» ¿­¾î¼­ ±×°ÍÀ» Æò¹üÇÏ°Ô ¾²´Â °ÍÀÌ ¿ä±¸µÈ´Ù. ·£´ý access´Â ±×°ÍÀ» Àаųª ¾²±âÀü¿¡ ÀûÀýÇÑ À§Ä¡¸¦ ã´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù. BUILDING SYMBOL INFORMATION FROM KMEM System.map Àº Linux¸¦ µ¹¸®´Âµ¥ ²À ÇÊ¿äÇÏÁö ¾Ê´Ù. ¸¸¾à lkmÀÌ ¿øÃµÀûÀ¸·Î kernel¿¡¼­ Áö¿ø µÇÁö ¾Ê´Â´Ù¸é /proc/ksymsµµ ¸¶Âú°¡ÁöÀÌ´Ù. ±×·¯³ª, symbol Á¤º¸´Â kmemÀ» »ç¿ëÇØ¼­ kernel À» patchingÇϴµ¥ À¯¿ëÇÏ´Ù. kmemÀ» ÀÌ¿ëÇØ¼­ running kernel·Î ºÎÅÍ symbolÁ¤º¸¸¦ Àç ±¸¼º ÇÏ´Â °Í¿¡ ´ëÇÑ ´Ù¾çÇÑ Á¢±ÙÀÌ À¯È¿ÇÏ´Ù. °¡Àå ½¬¿î ¹æ¹ýÀº symbolÀÇ ÁÖ¼Ò¿¡¼­ ¸î¹ÙÀÌÆ®¸¦ copyÇÏ´Â °ÍÀÌ´Ù. ±×¸®°í À̰ÍÀ» ¹®ÀÚ¿­ °Ë»ö¿¡ ÀÇÇØ kmem¿¡ symbolÀ» À§Ä¡½Ã۱â À§ÇÑ key·Î½á Ȱ¿ëÇÏ´Â °ÍÀÌ´Ù. ÀÌ·¯ÇÑ Á¢±ÙÀº ¿¹¸¦ µé¾î , ÇÔ¼ö°°Àº °ÍÀÌ ³ªÅ¸³ª´Â symbolµéÀ» À§Ä¡½Ã۱â À§ÇØ ¾ÆÁÖ ÀÌ»óÀûÀÌ´Ù. ±â°è¾î ÄÚµå instructionµéÀº key·Î Ȱ¿ëµÉ°ÍÀÌ´Ù. ±×·¯³ª À̰ÍÀº ¾Æ¸¶µµ architectureµé°ú Ä¿³Î ¹öÁ¯µé»çÀ̸¦ º¯È­½Ãų °ÍÀÌ´Ù. ±×·¡¼­ ÇÔ¼öµéÀ» À§ÇÑ key listµéÀº °¢°¢ÀÇ Ä¿³Î¹öÁ¯°ú °¢ ±¸Á¶¿¡ ÀÇÇØ À¯ÁöµÇ¾î¾ß ÇÑ´Ù. ÀÌ¿Í À¯»çÇϰÔ, ¸¸¾à ÇÔ¼öµéÀÌ ÄÄÆÄÀÏ Å¸ÀÓ configuration Äڵ带 »ç¿ëÇÑ´Ù¸é, ¿ì¸®°¡ Ưº°ÇÑ configurationÀ» À§ÇÑ keyÀ» »ç¿ëÇÑ´Ù ÇÒÁö¶óµµ ÀÌ·¯ÇÑ Á¢±ÙÀº ½ÇÆÐÇÒ °ÍÀÌ´Ù. ±×·¯³ª ÀϹÝÀûÀ¸·Î À̰ÍÀº ¾ÆÁÖ ±×³ª¸¶ ¼º°øÀûÀ̶ó°í ÇÒ ¼ö ÀÖ´Ù. ±×¸®°í key listÀÇ ±¸¼º°ú °Ë»öÀº ¸¹Àº ¼öÀÇ symbolµéÀ» ã±â¿¡ ÀÚµ¿È­µÇ±â°¡ ¿ëÀÌÇÏ´Ù. ÀÌ Á¢±Ù¹æ½ÄÀº key list°¡ ±¸¼ºµÈ °÷ÀÇ ¸Ó½Å»ó¿¡¼­ À¯È¿ÇÑ symbol Á¤º¸¸¦ ¿äÇÑ´Ù. ÀÌ Á¤º¸´Â System.mapÀ̳ª /proc/ksyms¸¦ ¾µ¼ö ÀÖ´Ù, º¸Åë ¸¹Àº ½Ã½ºÅÛ¿¡¼­´Â System.mapÀÌ ¾ø°í, Ä¿³ÎÀÇ ÄÄÆÄÀÏÁß copyµÇÁö ¾Ê´Â´Ù. µû¶ó¼­ ÈÄÀÚÀÇ (/proc/ksyms)ÂÊÀÌ ´õ ³ªÀº ¼Ò½º¶ó°í ÇÒ¼ö ÀÖ´Ù. key lists¸¦ ±¸¼ºÇÏ´Â implementationÀº build-ksyms-keys.shÀÌ´Ù. À̰ÍÀº key ±æÀÌ·Î ÃÖÀú 15bytes¸¦ »ç¿ëÇÑ´Ù. ±×·¯³ª ÀÌ ±æÀÌ·Î °¢ symbolµéÀÇ key°¡ ±¸º°µÇÁö ¾ÊÀ» °æ¿ì ÇöÀç Ű ±æÀ̸¦ ´Ã¿©¾ß ÇÑ´Ù. ±×·¯³ª ÀÌ·¯ÇÑ method¿¡´Â ¹®Á¦°¡ ÀÖ´Ù. À̰ÍÀº º¸Åë ¾Ë·ÁÁöÁö ¾ÊÀº ´Ù¸¥ ½Éº¼À» ÂüÁ¶ÇÏ´Â ¼ö¸¹Àº ÇÔ¼öµéÀ» À§ÇѰÍÀÌ´Ù. ÀÌ·¯ÇÑ ¹®Á¦¸¦ Ç®±âÀ§ÇØ ÇÊ¿äÇÑ°Í Àº ¿ì¸®°¡ ¾î´ÀºÎºÐÀÇ key list°¡ randomÇÑÁö¸¦ ¾Ë¾Æ¼­ ¾ÈÀüÇÏ°Ô ¹«½ÃÇÒ ¼öÀÖ¾î¾ß ÇÑ´Ù. ÀÌ·¸°Ô Çϱâ À§ÇØ , ¿ì¸®´Â key list¸¦ ¸¸µé¼ö ÀÖ´Ù. ¾î¶²Å°°¡ ÀüüÀûÀ¸·Î »ç¿ëµÉ °ÍÀΰ¡¸¦ °¡Á¤ÇØ¾ß Çϰí, ±×¶§ ¿ì¸®´Â ¿ì¸®ÀÇ Å° list¸¦ Ä¿³Î¿¡ »õ·ÎÀÌ updateÇØ¾ß ÇÑ´Ù. Ä¿³Î»çÀÌ¿¡ ¾î¶°ÇÑ °ÍÀÌ ¹Ù²î¾ú³ª¸¦ »ìÆìº½´Â °ÍÀº,À̸¦ ÅëÇØ ¿ì¸®°¡ ¹«¾ùÀ» ¹«½Ã»ì°ÍÀΰ¡·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿ª½Ã , À̰ÍÀº ¿ì¸®ÀÇ Å°°¡ ¾ó¸¶³ª À¯¿ëÇѰſ¡ ´ëÇÑ Å¸´çÇÑ ÃßÃøÀ» ÁÖ°í, ¸¸¾à key°¡ ÀüÇô stableÀÌ ¾Æ´Ï¸é discardµÇ¾î¾ß ÇÑ´Ù. ÀڷᱸÁ¶¸¦ ¸Þ¸ð¸®¿¡ ¿Ã¸®´Â °Í ¿ª½Ã ÀÌ·¯ÇÑ serch key ±â¹ýÀ» »ç¿ëÇØ¼­ Á¢±ÙÀÌ °¡´ÉÇÏ´Ù. À̰ÍÀ» À§ÇØ ¿ì¸®´Â °¡´ÉÇÑÇÑ ÀڷᱸÁ¶¿¡¼­ ¸¹Àº Á¤º¸¸¦ ¾Ë¾Æ¾ß ÇÑ´Ù. ±×·¡¼­ ¿ì¸®´Â ±×·¯ÇÑ ÀÏÀ» À§ÇØ ½Å·ÚÇÒ¼ö ÀÖ´Â key¸¦ °¡Á®¾ß ÇÑ´Ù. key°¡ ¹®ÀÚ¿­ÀÏ ÇÊ¿ä´Â ¾ø´Ù. ±×·¯³ª, ¿ì¸®´Â ±×°Í¾È¿¡ °¨ÃçÁø Çʵ带 ¾ÍÀ¸·Î ÀÎÇØ, ±¸Á¶¸¦ Ž»öÇÒ¼ö ÀÖ´Ù. ½ÇÁ¦ ¿¹Á¦´Â ¼Ò½º¿¡ ±¸ÇöµÇ¾î ÀÖ´Ù. From /usr/include/linux/module.h struct module { struct module *next; struct module_ref *ref; /* the list of modules that refer to me */ struct symbol_table *symtab; const char *name; int size; /* size of module in pages */ void* addr; /* address of module */ int state; void (*cleanup)(void); /* cleanup routine */ }; ¿ª) /* 2.2.5-22 ½ÇÁ¦ /usr/include/linux/module.h */ struct module { unsigned long size_of_struct; /* == sizeof(module) */ struct module *next; const char *name; unsigned long size; union { atomic_t usecount; long pad; } uc; /* Needs to keep its size - so says rth */ unsigned long flags; /* AUTOCLEAN et al */ unsigned nsyms; unsigned ndeps; struct module_symbol *syms; struct module_ref *deps; struct module_ref *refs; int (*init)(void); void (*cleanup)(void); const struct exception_table_entry *ex_table_start; const struct exception_table_entry *ex_table_end; #ifdef __alpha__ unsigned long gp; #endif /* Members past this point are extensions to the basic module support and are optional. Use mod_opt_member() to examine them. */ const struct module_persist *persist_start; const struct module_persist *persist_end; int (*can_unload)(void); }; ¸ðµâ¿¡¼­ nameÀº ¹®ÀÚ¿­À» °¡¸£Å°´Â pointerÀÌ´Ù. ÀÌ·¯ÇÑ ¸ðµâ ÀڷᱸÁ¶¸¦ ¸Þ¸ð¸®¿¡ ¿Ã¸®±â À§ÇØ ¿ì¸®´Â µÎ°¡Áö °æ·Î¸¦ °¡Áø´Ù. ù¹øÂ°, ¿ì¸®´Â string°ú matchµÇ´Â °ÍÀ» ¸ðµÎ ã´Â °ÍÀÌ´Ù. ÀÌ stringÀº ¹°·Ð moduleÀÇ À̸§ÀÌ´Ù. ±×¸®°í µÎ¹øÂ° °æ·Î¿¡¼­ , ¿ì¸®´Â ¸ðµâ ÀڷᱸÁ¶¿¡¼­ nameÀÇ °ª·Î¼­ ÀÌ ¹®ÀÚ¿­ÀÇ ÁÖ¼Ò¸¦ »ç¿ëÇÒ¼ö ÀÖ´Ù. ÀÌ Å½»öÀ» ½ÇÁ¦ÀûÀÎ °ÍÀ¸·Î ÇϱâÀ§ÇØ, ¿ì¸®´Â serch key¸¦ ¹þ¾î³­ ºÎºÐÀûÀ¸·Î ¿ÏÀüÇÑ ¸ðµâ ±¸Á¶¿¡ °¡´ÉÇÑÇÑ ¸¹ÀÌ Ã¤¿ö³Ö´Â ½Ãµµ¸¦ ÇØ¾ß ÇÑ´Ù. ¸ðµâÀÇ size´Â moduleÀ» ¸®½ºÆÃÇϴµ¥ »ç¿ëµÈ´Ù. ±×¸®°í ¿ì¸®´Â À̰ÍÀ» ¿ì¸®ÀÇ key¸¦ ´õ¿í À¯¿ëÇÏ°Ô ÇÑ´Ù. # lsmod Module Pages Used by ppp 5 1 (autoclean) slhc 2 [ppp] 1 (autoclean) serial 8 1 ipx 4 0 rarp 1 0 smbfs 7 0 nfs 13 4 # ÆäÀÌÁö ¼ýÀÚµéÀº ÆäÀÌÁö »óÀÇ ¸ðµâ »çÀÌÁ ¸»ÇÑ´Ù. ±×·¡¼­ ¿ì¸®´Â ¸ðµâ ÀڷᱸÁ¶¸¦ »ç¿ëÇÏ´Â µ¥ ¾µ¼ö ÀÖ´Ù. ¸ðµâÀÇ state´Â MOD_RUNNINGÀ¸·Î °¡Á¤µÇ°í, À̰ÍÀº ¸ðµâÀÌ ÇöÀç ÀÛµ¿µÇ°í ÀÖ´Ù´Â °ÍÀÌ´Ù. ( À̰ÍÀº Áö¿öÁö·Á°í Çϴ°Ͱú, ÃʱâÈ­ µÈ°Í°ú´Â ´Ù¸£´Ù.) ref´Â NULL·Î °¡Á¤µÈ´Ù. À̰ÍÀº ¾î¶°ÇÑ moduleµéµµ À̰ÍÀ» ÂüÁ¶ÇÏÁö ¾ÊÀ» °ÍÀ̶ó´Â °ÍÀÌ´Ù. µû¶ó¼­ cleanupÀº NULL·Î °£ÁÖµÇÁö ¾Ê´Â´Ù. symbolÀ» À§Ä¡½Ã۱âÀ§ÇÑ ´Ù¸¥ ¹æ¹ýÀº ¸¸¾à À̰ÍÀÌ ¾Ë·ÁÁø symbol°ú Á¤ÀûÀÎ °Å¸®¸¦ °®´Â´Ù°í ÇÒ¶§, ¾Ë·ÁÁöÁö ¾Ê´Â symbolÀº ¾Ë·ÁÁöÁö ¾Ê´Â symbolÀº ¾Ë·ÁÁø symbolÀÇ ÇÔ¼ö·Î ¹ß°ßµÈ´Ù´Â °ÍÀÌ´Ù. From /usr/src/linux-2.0.35/kernel/sched.c . . . struct task_struct * task[NR_TASKS] = {&init_task, }; struct kernel_stat kstat = { 0 }; . . . task´Â ¿ì¸®°¡ À§Ä¡½Ãų symbolÀÌ´Ù. À̰ÍÀº /proc/ksyms¿¡ ÀÖÁö ¾Ê´Ù. ±×·¯³ª kstat¿¡´Â ÀÖ´Ù. ±×·¡¼­ ¿ì¸®´Â ´ÙÀ½°ú °°Àº ¿­À» º¼¼ö ÀÖ´Ù. ADDR(task) == ADDR(kstat) - NR_TASKS * sizeof(struct task_struct *) À̰ÍÀº °¡´ÉÇÏ´Ù. ±×·¯³ª ¿ì¸®´Â °¢ structure¸¦ ±¸º°Çϴµ¥ »ç¿ëÇÒ ¾î¶°ÇÑ Á¤º¸µµ °¡Áö°í ÀÖÁö ¸øÇÏ´Ù. ±×°ÍÀº structure°¡ ¿ì¸®ÀÇ ÀÓÀÌÀÇ À§Ä¡¿¡¼­ ȤÀº unknown data¿¡¼­ºÎÅÍ ³ª¿À±â ¶§¹®ÀÌ´Ù. ¶ÇÇÑ ¾Ë·ÁÁø ½Éº¼À» ÂüÁ¶ Æ÷ÀÎÆ®·Î½á ¾µ¼öµµ ¾ø´Ù. ¸¸¾à ÀÌ·±ÀÏÀÌ ¹ß»ýÇϸé , ¿ì¸®´Â structure¸¦ °£Á¢ÀûÀ¸·Î ¿ì¸®°¡ ã´Â ÀڷᱸÁ¶¸¦ ÂüÁ¶ÇÏ´Â Äڵ带 ãÀ½À¸·Î½á À§Ä¡½Ãų¼ö ÀÖ´Ù. From /usr/src/linux-2.0.35/arch/i386/kernel/entry.S . . . * Stack layout in 'ret_from_system_call': * ptrace needs to have all regs on the stack. * if the order here is changed, it needs to be * updated in fork.c:copy_process, signal.c:do_signal, * ptrace.c and ptrace.h * * 0(%esp) - %ebx * 4(%esp) - %ecx * 8(%esp) - %edx * C(%esp) - %esi * 10(%esp) - %edi * 14(%esp) - %ebp * 18(%esp) - %eax * 1C(%esp) - %ds * 20(%esp) - %es * 24(%esp) - %fs * 28(%esp) - %gs * 2C(%esp) - orig_eax * 30(%esp) - %eip * 34(%esp) - %cs * 38(%esp) - %eflags * 3C(%esp) - %oldesp * 40(%esp) - %oldss */ . . . ALIGN 1: call SYMBOL_NAME(syscall_trace) movl ORIG_EAX(%esp),%eax call *SYMBOL_NAME(sys_call_table)(,%eax,4) movl %eax,EAX(%esp) # save the return value #ifdef __SMP__ GET_PROCESSOR_OFFSET(%eax) movl SYMBOL_NAME(current_set)(,%eax),%eax ÄÚµå¾È¿¡¼­ sys_call_tableÀÌ ÂüÁ¶µÇ´Â °ÍÀ¸·Î º¸ÀδÙ. ¸¸¾à ¿ì¸®°¡ À̰ÍÀ» ºÎºÐÀûÀ¸·Î À§Ä¡½Ãų¼ö ÀÖ´Ù¸é, ¿ì¸®´Â sys_call_tableÀÇ À§Ä¡¸¦ ²ø¾î³¾¼ö ÀÖ´Ù. ±×¸®°í À̰ÍÀÌ keyÀÇ È¿À²¼ºÀ» Áõ°¡½Ã۱âÀ§ÇØ °¡´ÉÇÑÇÑ ¸¹Àº instructionµéÀ» »ç¿ëÇÒ¼ö ÀÖ°Ô Áغñ ÇÑ´Ù. À̰ÍÀº ÀÛÀº key¸¦ ÀÌ¿ëÇÑ pointless searchingÀÌ´Ù. ±×·¡¼­ À̰͵éÀº ¸¹Àº°¡´ÉÇÑ matchµéÀ» ±¸ºÐÇØ ÁØ´Ù. sys_call_tableÀ» ÂüÁ¶ÇÏ´Â Àû´çÇÑ instructionµéÀ» »ç¿ëÇÔÀ¸·Î½á ¿ì¸®´Â ¿ì¸® Àڽſ¡°Ô ÁÁÀº key¸¦ Á¦°øÇÒ¼ö ÀÖ´Ù. ÀÌ·¯ÇÑ instructionsµéÀº ¾Ë·ÁÁöÁö ¾ÊÀº °ÍµéÀº »ç¿ëÇÏÁö ¾Ê´Â´Ù. µû¶ó¼­ ÀûÀýÈ÷ »ç¿ëµÉ¼ö ÀÖ´Ù. ÀÌ¿Í ºñ½ÁÇÏ°Ô __SMP__ ¿¡ ÀÇÁ¸ÇÑ ÄÚµå´Â »ç¿ëÇÏÁö ¾ÊÀ»°ÍÀÌ´Ù. °á±¹ ¿ì¸®°¡ »ç¿ëÇÒ ÄÚµå´Â ´ÙÀ½°ú °°´Ù. movl ORIG_EAX(%esp),%eax call *SYMBOL_NAME(sys_call_table)(,%eax,4) movl %eax,EAX(%esp) # save the return value ¿ì¸®°¡ ÀÌ Äڵ带 dummy ÇÁ·Î±×·¥¿¡ ÄÄÆÄÀÏÇϰí, À̰ÍÀº objdump·Î ¶°º¸¸é¼­ ¿ì¸®´Â ¿ì¸®ÀÇ search key¸¦ »Ì¾Æ³¾¼ö ÀÖ´Ù. ÀÌ search key´Â ºÎºÐÀûÀ¸·Î´Â ¿ÏÀüÄ¡¾ÊÀº ¹®ÀÚ¿­·Î »ý°¢µÈ´Ù. entry.S ÄÚµå´Â ÀÚÁÖ ¹Ù²îÁö ¾ÊÀ¸¸ç À̰ÍÀº ¶ÇÇÑ ¸¹Àº kernel¿¡¼­ º¸¿©Áø´Ù. ±×·¡¼­ ¿ì¸®´Â °¢ Ä¿³Î¸¶´Ù ´Ù¸¥ search key¸¦ »ç¿ëÇÒ ÇÊ¿ä´Â ¾ø´Ù. Áï À̰ÍÀº ÀÌ·¯ÇÑ Æ¯º°ÇÑ ¾ÆÅ°ÅØÃÄ¿¡ »ç¿ëµÉ¼ö ÀÖÁö¸¸, ±×·¯³ª °°Àº ¹ýÄ¢ÀÌ ´Ù¸¥ °Í¿¡µµ Àû¿ëµÈ´Ù´Â ¸»ÀÌ´Ù. ù¹øÂ° ¿¹´Â kenel structure¸¦ ¾î¶»°Ô ¹Ù²Ù´Â°¡¿¡ ´ëÇÑ °£´ÜÇÑ ¿¹Á¦ applicationÀÌ´Ù. kroot´Â ¼öÆÛÀ¯Àú°¡ µÇ±âÀ§ÇÑ processÀÇ uid¸¦ ¹Ù²Ù´Â ÇÁ·Î±×·¥À¸·Î Á¦°øµÈ´Ù. À̰ÍÀº ½ÇÁ¦ mem device°¡ insecureÇÏÁö ¾ÊÀº ÀÌ»ó Çö½ÇÀûÀÌÁö ¸øÇÏ´Ù. - ¿ø·¡ À̰ÍÀº ¿¹Àü¿¡ kernel bug·Î ¾Ë·ÁÁ® ÀÖ´Ù. ±×·¯³ª À̰ÍÀº ¿ì¸®¿¡°Ô ÁÁÀº exampleÀ» ÁØ´Ù. algorithm Àº ´ÙÀ½°ú °°´Ù. * /dev/kmemÀ» openÇϰí * task symbolÀÇ address¸¦ ã´Â´Ù. * task tableÀ» ¸Þ¸ð¸®¿¡ ÀÒ¾î¿À°í * ¿ì¸®°¡ º¯ÇüÇϰíÀÚ ÇÏ´Â task¸¦ ÀûÀýÈ÷ À§Ä¡½ÃŲ´Ù. * task¸¦ superuser uid¿¡ »óÃæÇÏ°Ô ¼öÁ¤Çϰí * È­ÀϾȿ¡¼­ ƯÁ¤ task¸¦ ã´Â´Ù. * ±×ÈÄ, º¯ÇüµÈ task¸¦ ¾´´Ù. 'task' symbolÀÇ address¸¦ À§Ä¡½Ã۱â À§ÇØ ¿ì¸®´Â À§¿¡¼­ ¸»ÇÑ ¹æ¹ýÀ» ½á¾ß ÇÑ´Ù. ´õ ½ÇÁ¦ÀûÀÎ ¿¡Á¦°¡ ÁÖ¾îÁ® ÀÖ´Ù. ¸ðµâ Ä¿³Î ±¸Á¶¸¦ module listing¿¡¼­ Á¦°ÅÇϱâ À§ÇÑ ÆÐαâ¹ý ÀÌ´Ù. From /usr/src/linux-2.0.35/kernel/module.c . . . /* * Called by the /proc file system to return a current list of modules. */ int get_module_list(char *buf) { . . . q = mp->name; if (*q == '\0' && mp->size == 0 && mp->ref == NULL) continue; /* don't list modules for kernel syms */ . . . À̰ÍÀº À̸§ÀÌ listµÇÁö ¾ÊÀº lkmÀÌ ºñ¾îÀÖ´Â °ÍÀ¸·Î º¸¿©Áø´Ù. size´Â 0À̰í ref¶ÇÇÑ NULLÀÌ´Ù. lkm 'zapper'ÀÇ ±¸ÇöÀº ÀÌ·¯ÇÑ Á¤º¸¸¦ module ±¸Á¶ÀÇ size¿Í ref ¸â¹öµéÀ» ÆÐÄ¡Çϱâ À§ÇØ »ç¿ë µÈ´Ù. ±×¸®°í À̰ÍÀº nameÀ» empty stringÀ¸·Î ÆÐÄ¡ÇÒ °ÍÀÌ´Ù. ÀÌ ¹Ý´ëµµ °¡´ÉÇÏ´Ù. zapping ÇÁ·Î¼¼½º»ó¿¡ siz¿Í ref Æ÷ÀÎÅ͸¦ °¡Áö°í ÀÖ´Ù¸é À̰ÍÀº °¡´ÉÇÏ´Ù. PATCHING THE KERNEL TO RUN INSERTED KERNEL CODE ¸®´ª½º´Â sys_call_tableÀ̶ó°í ³ªÅ¸³ª´Â system call tableÀ» Á¦°øÇÑ´Ù. ÀÌ tableÀº fixed size arrayÀ̰í, °¢ arrayÀÇ ¿ä¼ÒµéÀº °¢ system callÀ» Áö½ÃÇÏ´Â pointerÀÌ´Ù, °¢ ¼ýÀÚµéÀÌ °¡Áö´Â Àǹ̴ ±× arrayÀÇ intexÀÌ´Ù. ¸¸¾à , ¾î¶² system callµµ ±× syscall ¼ýÀÚ¸¦ À§ÇØ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù¸é , ±× element´Â NULL pointerÀÌ´Ù. º¸Åë syscall tableÀÇ ¸¹Àº elementµéÀÌ syscall slot ¿¡¼­ »ç¿ë°¡´ÉÇÑ nullÀ» ³ªÅ¸³»°í ÀÖ´Ù. »õ·Î¿î Ä¿³ÎÄÚµåÀÇ ÁÖ¼Ò¸¦ ¾Ë°íÀÖÀ½À¸·Î ÇØ¼­, ¿ì¸®´Â syscall tableÀ» ÆÐĪÇÒ¼ö ÀÖ°í empty slotÀ» ¿ì¸®ÀÇ ÄÚµå·Î °¡¸£Å°°Ô ÇÒ¼ö ÀÖ´Ù. kernel code¸¦ µ¿ÀÛ½Ã۱âÀ§Çؼ­´Â , ¿ì¸®´Â ¾î¶² callÀ» »õ·Î¿î user-land syscallÀ» ¸®´ª½º°¡ µµÀÔÇÑ int 0x80 ¸ÞÄ¿´ÏÁòÀ» ÅëÇØ ºÎ¸¦¼ö ÀÖ´Ù. ÀÌ·Î½á ¿ì¸®ÀÇ Äڵ尡 µ¿ÀÛÇÏ°Ô µÇ´Â°ÍÀÌ´Ù. PATCHING THE KERNEL TO INSERT NEW CODE /dev/kmemÀº ¿ì¸®¿¡°Ô Á÷Á¢ kernel memory¿¡ Á¢±ÙÇÒ¼ö ÀÖµµ·Ï ÇØÁØ´Ù. ±×·¡¼­ ¿ì¸®°¡ »õ·Î¿î Äڵ带 ½±°Ô »ðÀÔÇÑ´Ù´Â °ÍÀº memoryºÎºÐÀ» overwriteÇÑ´Ù´Â ¸»ÀÌ µÈ´Ù. ÇѰ¡Áö Áß¿äÇѰÍÀº ¿ì¸®°¡ kernel À» stableÇÑ »óÅ·Π³õ¾ÆµÎ±â À§ÇØ ¿ì¸®´Â ÀÌ¹Ì ÇÒ´çµÇ°Å³ª »ç¿ëµÇ°í ÀÖ´Â internal kernel ±¸Á¶¸¦ overwriteÇÒ ¼ö´Â ¾ø´Ù´Â °ÍÀÌ´Ù. Ä¿³Î °ø°£¿¡¼­ kmalloc poolÀ» »ç¿ëÇÏ´Â °ÍÀº °¡´ÉÇÑ ÀÏÀÌ´Ù. ±×·¯³ª ¿ì¸®´Â ±×°ÍÀÌ ÀÌ¹Ì kmalloc¿¡ ÀÇÇØ »ç¿ëµÇ¾îÁö°í ÀÖ´ÂÁö È®½ÅÇÒ¼ö°¡ ¾ø´Ù. ºñ½ÁÇÏ°Ô , ¿ì¸®°¡ ºñ·Ï free memory¸¦ ã±âÀ§ÇØ ÇÒ´çµÈ black headerµéÀ» ã´Â´Ù°í ÇÒÁö¶óµµ, operationµéÀº atomicÀÌ ¾Æ´Ï°í µû¶ó¼­ À̰ÍÀº kernel°úÀÇ race ÇÒ¼ö ÀÖ´Â »óŸ¦ ¸¸µé¼ö ÀÖ´Ù. kernel memoryÀÇ ¼±Çü layoutÀº ´ÙÀ½°ú °°´Ù. [compile time kernel memory reserve] [kmalloc pool] kmalloc poolÀÇ ÇѰè´Â ÀÌ¹Ì memory_start , memory_end¶ó´Â symbol¿¡ ÀÇÇØ Á¤ÀǵǾî ÀÖ´Ù. [compile time kernel memory reserve] memory_start: [kmalloc pool] memory_end: kmalloc poolÀº ±×·¯³ª memory_startÀÇ page border¿¡ Á¤·ÄµÇ¾î ÀÖ°í, ±×·¡¼­ ¾Æ·¡¿Í °°Àº ¸ð¾çÀÌ µÈ´Ù. Key: [..] a complete page K kmalloc pool P padding R reserve (compile time kernel text/data etc) [RRRRRRRRRRRR] ... [RRRRRRRRRRRR] [RRRR memory_start: PPPPPPPP] [KKKKKKKKKKKK] ... [KKKKKKKKKKKK] memory_end: paddingµéÀº ¿ì¸®¿¡°Ô »õ·Î¿î Ä¿³ÎÄڵ忡 ´ëÇÑ ÀÌ»óÀûÀÎ À§Ä¡¸¦ Á¦°øÇØ ÁØ´Ù, as it is totally safe to use as the kernel is not allowed to use this memory. ¿ì¸®°¡ memory_start¸¦ À§Ä¡½Ã۱â À§ÇØ System.mapÀ̳ª ´Ù¸¥ techniqueÀ» »ç¿ëÇÏ´Â °ÍÀº ¾ÆÁÖ ÀÌ»óÀûÀÎ »óȲÀÌ´Ù. It is preferable however if we can not to use a symbol who's address is not known at runtime without location. From /usr/src/linux-2.0.35/arch/i386/mm/init.c . . . /* * BAD_PAGE is the page that is used for page faults when linux * is out-of-memory. Older versions of linux just did a * do_exit(), but using this instead means there is less risk * for a process dying in kernel mode, possibly leaving a inode * unused etc.. * * BAD_PAGETABLE is the accompanying page-table: it is initialized * to point to BAD_PAGE entries. . . . From /usr/src/linux-2.0.35/arc/i386/kernel/head.S . . . .org 0x3000 ENTRY(empty_bad_page) .org 0x4000 ENTRY(empty_bad_page_table) .org 0x5000 ENTRY(empty_zero_page) . . . À̰͵éÀº ¾ÐÃàµÈ kernel image¸¦ À§ÇØ ¸ðµÎ 0x100000 ¿¡¼­ ½ÃÀÛÇϰí ÀÖ´Ù. ±×·¡¼­ empty_bad_page´Â 0x100300À̰í, »çÀÌÁî´Â 4097 bytesÀÌ´Ù. ¸Þ¸ð¸®ÀÇ °í°¥Àº º¸Åë ÀϾÁö ¾Ê´Â´Ù. ±×¸®°í ¿ì¸®´Â empty_bad_page¸¦ ±×·¸°Ô µÎ·Á¿ö ÇÏÁö ¾Ê°íµµ ¿ì¸® ÀÚ½ÅÀÇ ÄÚµå·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. PATCHING NEW CODE INTO THE LINUX KERNEL »õ·Î¿î Äڵ带 Ä¿³Î¿¡ patchingÇÏ´Â µ¥´Â µÎ °¡Áö°¡ ÇÊ¿äÇÏ´Ù. Äڵ尡 kernel space¿¡ ÀÖ¾î¾ß ÇÏ¸ç ±×°ÍÀ» ºÎ¸¦¼ö ÀÕ´Â calling method°¡ ÇÊ¿äÇÏ´Ù. À§ÀÇ text´Â À̰ÍÀ» ÃæÁ·½Ãų¸¸ÇÑ ÃæºÐÇÑ ¾ð±ÞÀ» Çϰí ÀÖ´Ù. algorithmÀº ´ÙÀ½°ú °°´Ù. * »õ·Î¿î Äڵ带 ÀÌ¹Ì ±â¼úÇÑ ¹æ¹ýÀ» »ç¿ëÇÏ¿© memory¿¡ ³Ö´Â´Ù. * sys_call_tableÀ» patchÇÑ´Ù. ±×·¡¼­ syscallÀÌ »õ·Î¿î Äڵ带 °¡¸£Å°°Ô ÇÑ´Ù. * syscallÀÌ ¿ì¸®ÀÇ »õ·Î¿î ÄÚµå·Î °¡¸£Å°°ÔÇÑ´Ù. OBJECT CODE (LKM) INSERTING OF KERNEL CODE object code¸¦ ³Ö´Â °ÍÀº code¸¦ Á÷Á¢ÀûÀ¸·Î ³Ö´Â °°Àº ¿øÄ¢À» µû¸¥´Ù. ±×·¯³ª ÀÌÀü¿¡ ¾ð±ÞÇßµíÀÌ kernel symbol referenceµéÀº kernel symbol tableÀ» º½À¸·Î½á »ç¿ëµÇ´Â Á¤È®ÇÑ ÁÖ¼Ò¸¦ ¿ä±¸ÇÑ´Ù. symbolÀ» ÁÖ¼Ò¿¡ bindingÇϴ°ÍÀº ¿ì¸®°¡ ¸Å´º¾óÀ» µû¶ó¼­ ÇÏ´Â °Í°ú´Â °Å¸®°¡ ¸Õ linkingÀÌ´Ù. non trivial code¸Þ´º¾ó ¸µÅ·Àº ¿ì¸®°¡ º¼¼ö ÀÖ´Â ¼Ö·ç¼ÇÀÌ ¾Æ´Ï´Ù. ±×¸®°í linking Àº ¿ì¸®°¡ »ç¿ëÇÏ´Â ¤¿¾Ë°í¸®µë¿¡ Ãß°¡µÇ¾î¾ß ÇÑ´Ù. OBJECT CODE (LKM) LINKING TO KERNEL ELF´Â Linux»ó¿¡¼­ object code¸¦ Ç¥ÇöÇϴµ¥ ¾ÆÁÖ ÀüÇüÀûÀΠǥÁØÀÌ´Ù. ÀÌ ¹®¼­´Â ELF object¸¦ »ç¿ëÇØ¼­ ¸µÅ·ÇÏ´Â °ÍÀ» ÂüÁ¶ÇÒ °ÍÀÌ´Ù. object code È­ÀÏÀº ELF¸¦ »ç¿ëÇÒ ¶§ Àç¹èÄ¡ °¡´É ÄÚµå·Î ÂüÁ¶µÈ´Ù. ±×°ÍÀÌ ¹«¾ùÀÎÁö¸¦ summarizeÇϱ⠶§¹®ÀÌ´Ù. À̰ÍÀº ¾î´À ¸Þ¸ð¸® À§Ä¡¿¡µµ fixµÇÁö ¾Ê´Â´Ù. Àç¹èġȭÀÏÀ» ½ÇÇØ°¡´ÉÇÑ À̹ÌÁö·Î ¸¸µé¾î ³»´Â °Í°ú ½Éº¼µéÀ» ÁÖ¼Ò·Î ¹ÙÀεùÇϴ°ÍÀº ¸µÅ·ÀÇ Ã¥ÀÓÀÌ´Ù. Äڵ带 ¸µÅ·Çϴ°ÍÀº fixµÈ À§Ä¡¿¡ Äڵ带 Àç¹èÄ¡ÇÏ´Â °Í¿¡ ÀÇÇØ ¼öÇàµÈ´Ù. ´ëºÎºÐ , object code´Â ¸¹ÀÌ ¹Ù²îÁö´Â ¾Ê´Â´Ù. ´ÙÀ½°ú °°Àº C code¸¦ ÂüÁ¶ÇØ º¸ÀÚ. { char s[] = "I wonder where I'm located..."); printk(KERN_INFO "%s\n", s); } ¹®ÀÚ¿­ 's'´Â ÄÄÆÄÀϽà Àý´ëÀûÀÎ À§Ä¡¸¦ °¡Áö°í ÀÖÁö ¾ÊÀº objectÄÚµå¾ÈÀÇ Àç¹èÄ¡ text sectionÀÇ ºÎºÐÀ¸·Î Á¸ÀçÇÑ´Ù. ºñ½ÁÇÏ°Ô printk´Â Àü¿ªÀûÀÎ symbol·Î ¼±¾ðµÇ¾îÀÖ´Ù. ±×¸®°í À̰ÍÀÇ address´Â ¿ª½Ã ÄÄÆÄÀϽÿ¡ ¾ËÁö ¸øÇÑ´Ù. ELF object¾ÈÀÇ Àç¹èÄ¡ sectionµéÀº object¾È¿¡¼­ ¾î¶²°ÍÀÌ ¼öÁ¤µÇ¾î¾ß ÇÏ´ÂÁö ±â¼úÇϰí ÀÖ´Ù. À§ÀÇ °æ¿ì, Àç¹èÄ¡ ¿£Æ®¸®µéÀº printk¿Í stringÀÇ reference¸¦ À§ÇØ ¸¸µé¾î Áø´Ù. ELF Àç¹èÄ¡ objectÀÇ format Àº ´ÙÀ½°ú °°´Ù. ELF header Program header table Section 1 Section n Section header table From /usr/include/elf.h /* The ELF file header. This appears at the start of every ELF file. */ #define EI_NIDENT (16) typedef struct { unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf32_Half e_type; /* Object file type */ Elf32_Half e_machine; /* Architecture */ Elf32_Word e_version; /* Object file version */ Elf32_Addr e_entry; /* Entry point virtual address */ Elf32_Off e_phoff; /* Program header table file offset */ Elf32_Off e_shoff; /* Section header table file offset */ Elf32_Word e_flags; /* Processor-specific flags */ Elf32_Half e_ehsize; /* ELF header size in bytes */ Elf32_Half e_phentsize; /* Program header table entry size */ Elf32_Half e_phnum; /* Program header table entry count */ Elf32_Half e_shentsize; /* Section header table entry size */ Elf32_Half e_shnum; /* Section header table entry count */ Elf32_Half e_shstrndx; /* Section header string table index */ } Elf32_Ehdr; /* Conglomeration of the identification bytes, for easy testing as a word. */ #define ELFMAG "\177ELF" #define SELFMAG 4 /* Legal values for e_machine (architecture). */ #define EM_386 3 /* Intel 80386 */ #define EM_486 6 /* Intel 80486 */ /* Legal values for e_version (version). */ #define EV_NONE 0 /* Invalid ELF version */ #define EV_CURRENT 1 /* Current version */ From the ELF specifications. "String Table String table ¼½¼ÇµéÀº null-terminated ¹®ÀÚ sequence¸¦ °®´Â´Ù. º¸Åë ¹®ÀÚ¿­À̶ó°í ºÒ¸®¿î´Ù. object fileÀº ÀÌ·¯ÇÑ ¹®ÀÚ¿­À» ½Éº¼°ú ¼½¼ÇÀ̸§À» ³ªÅ¸³»´Âµ¥ ¾´´Ù. string table section¾È ¿¡¼­ À妽º·Î½á Âü°í°¡ µÈ´Ù. ù¹øÂ° byte´Â index 0À̰í, À̰ÍÀº null ¹®ÀÚ¸¦ °¡Áö°í ÀÖ°Ô Á¤ÀǵȴÙ. ºñ½ÁÇϰÔ, ¹®ÀÚ tableµéÀÇ ¸¶Áö¸· byte´Â null·Î Á¤ÀǵȴÙ, ¸ðµç ¹®ÀÚµéÀÌ null·Î ³¡³ª°Ô µÈ´Ù. index°¡ 0ÀÎ stringÀº À̸§À» °¡Áö°í ÀÖÁöµµ ¾Ê°Å³ª null À̸§À¸·Î ƯÁ¤Áö¿öÁø´Ù. À̰ÍÀº context¿¡ ÀÇÁ¸ÀûÀÌ´Ù. empty ¹®ÀÚ¿­ Å×À̺í sectionÀº Çã¿ëµÈ´Ù. ±×°ÍÀÇ secton headerÀÇ sh_size¸â¹ö°¡ zero¸¦ °¡¸£Å³ °ÍÀÌ´Ù. Non-zeroÀ妽ºµéÀº empty¹®ÀÚ¿­ Å×ÀÌºí¿¡ ´ëÇØ À¯¿ëÇÏÁö ¾Ê´Ù. . . . Sections object fileÀÇ section header tableÀº ¸ðµç È­ÀÏÀÇ sectionµéÀ» À§Ä¡½ÃŰ°Ô ÇÑ´Ù. section header tableÀº ¾Æ·¡¿¡¼­ ¼³¸íÇÏ´Â °Í°ú °°ÀÌ Elf32_Shdr ±¸Á¶ÀÇ ¹è¿­ÀÌ´Ù. section header table index´Â ÀÌ ¹è¿­ÀÇ subscriptÀÌ´Ù. ELF headerµéÀÇ e_shoff ¸â¹ö´Â fileÀÇ ½ÃÀÛºÎÅÍ section header table±îÁöÀÇ byte offsetÀ» ÁØ´Ù; e_shnumÀº ¾ó¸¶³ª ¸¹Àº entryµéÀ» section header°¡ °¡Áö°í Àִ°¡¸¦ ¸»ÇØÁØ´Ù. ;±×¸®°í e_shentsize´Â °¢ ¿£Æ®¸®ÀÇ size¸¦ ¸»ÇØÁØ´Ù. From /usr/include/elf.h /* Section header. */ typedef struct { Elf32_Word sh_name; /* Section name (string tbl index) */ Elf32_Word sh_type; /* Section type */ Elf32_Word sh_flags; /* Section flags */ Elf32_Addr sh_addr; /* Section virtual addr at execution */ Elf32_Off sh_offset; /* Section file offset */ Elf32_Word sh_size; /* Section size in bytes */ Elf32_Word sh_link; /* Link to another section */ Elf32_Word sh_info; /* Additional section information */ Elf32_Word sh_addralign; /* Section alignment */ Elf32_Word sh_entsize; /* Entry size if section holds table */ } Elf32_Shdr; From the ELF specifications. "Symbol Table object fileÀÇ symbol tableÀº ÇÁ·Î±×·¥À» Á¦¹èÄ¡Çϰí À§Ä¡½Ã۱âÀ§ÇÑ symbolic Á¤Àǵé°ú ÂüÁ¶¸¦ À§ÇÑ Á¤º¸µéÀ» °¡Áö°í ÀÖ´Ù. symbol tableÀ妽º´Â ÀÌ array¿¡ subscript ÀÌ´Ù. index 0´Â ¿ª½Ã Å×À̺í»ó¿¡¼­ ù¹øÂ° entry·Î µðÀÚÀεǾîÀÖ°í Á¤ÀǵÇÁö ¾ÊÀº symbol index·Î Á¦°øµÇ¾î Áø´Ù. ÃʱâÀÇ ³»¿ë¹°Àº ÀÌ ¼½¼Ç»ó¿¡¼­ ³ªÁß¿¡ Á¤ÇØÁø´Ù. /* Symbol table entry. */ typedef struct { Elf32_Word st_name; /* Symbol name (string tbl index) */ Elf32_Addr st_value; /* Symbol value */ Elf32_Word st_size; /* Symbol size */ unsigned char st_info; /* Symbol type and binding */ unsigned char st_other; /* No defined meaning, 0 */ Elf32_Section st_shndx; /* Section index */ } Elf32_Sym; #define SHN_UNDEF 0 /* No section, undefined symbol. */ /* How to extract and insert information held in the st_info field. */ #define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) #define ELF32_ST_TYPE(val) ((val) & 0xf) #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) /* Legal values for ST_BIND subfield of st_info (symbol binding). */ #define STB_LOCAL 0 /* Local symbol */ #define STB_GLOBAL 1 /* Global symbol */ #define STB_WEAK 2 /* Weak symbol */ #define STB_NUM 3 /* Number of defined types. */ #define STB_LOPROC 13 /* Start of processor-specific */ #define STB_HIPROC 15 /* End of processor-specific */ From the ELF specifications. "Àç¹èÄ¡ ¼½¼ÇÀº ´Ù¸¥ µÎ ¼½¼ÇµéÀ» ÂüÁ¶ÇÑ´Ù : ½Éº¼ table°ú ¼öÁ¤Çϱâ À§ÇÑ ¶Ç ´Ù¸¥ sectionÀÌ ±×°ÍÀÌ´Ù. ¿©±â¼­ section headerÀÇ sh_info¿Í sh_linkÇʵåµéÀº, ¾Õ¿¡¼­ ¸»ÇÑ Section¿¡¼­ ÀÌ·¯ÇÑ °ü°è¸¦ ÁöÁ¤ÇØ ÁְԵȴÙ. ¼­·Î ´Ù¸¥ objectÈ­ÀϵéÀ» À§ÇÑ Àç¹èÄ¡ ¿£Æ®¸®µéÀº r_offsetÀ» À§ÇÑ ÇØ¼®¿¡¼­ »ó´çÈ÷ ´Ù¸£´Ù. Àç¹èÄ¡ È­Àϵ鿡¼­, r_offsetÀº section offsetÀ» °¡Áö°í, Àç¹èÄ¡ ¼½¼Ç ÀÚ½ÅÀº ¾î¶»°Ô ´Ù¸¥ ¼½¼ÇÀ» ¤» È­ÀÏ¿¡¼­ °íÃÄ¾ß ÇÏ´ÂÁö¸¦ ±â¼úÇÑ´Ù. Àç¹èÄ¡ offsetÀº µÎ¹øÂ° ¼½¼Ç¾ÈÀÇ ÀúÀå unitÀ» µðÀÚÀÎÇÑ´Ù. From /usr/include/elf.h /* Relocation table entry without addend (in section of type SHT_REL). */ typedef struct { Elf32_Addr r_offset; /* Address */ Elf32_Word r_info; /* Relocation type and symbol index */ } Elf32_Rel; /* How to extract and insert information held in the r_info field. */ #define ELF32_R_SYM(val) ((val) >> 8) #define ELF32_R_TYPE(val) ((val) & 0xff) #define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) ÀÌ·¯ÇÑ ¼±ÅõǾîÁø ELF spec°ú headerÈ­ÀϷκÎÅÍÀÇ ÆÐ·¯±×·¡ÇÁµé°ú ¼½¼ÇµéÀº ¿ì¸®¿¡°Ô »óÀ§ ·¹º§ÀÇ °³³ä Áï, ¾î¶»°Ô Àç¹èÄ¡ ELF È­ÀÏÀÌ ½ÇÇàµÇ±â¿¡ ÃæºÐÇÑ À̹ÌÁö¸¦ ¸¸µé±â À§ÇØ ¸µÅ© µÇ´ÂÁö¿¡ ´ëÇÑ °³³äÀ» ÁØ´Ù. lkmÀ» ¸µÅ·ÇÏ´Â °úÁ¤Àº ´ÙÀ½°ú °°´Ù. * Àç¹èÄ¡ °¡´ÉÇÑ ELFÆ÷¸Ë¿¡¼­ ó·³ È­ÀÏÀ» ±¸ºÐÁþ´Â´Ù. * °¢ relevant sectionµéÀ» ¸Þ¸ð¸®¿¡ ·ÎµåÇÑ´Ù. * °¢ PROGBIT ¼½¼ÇµéÀ» À§ÇØ ¸Þ¸ð¸®¿¡ section ÁÖ¼Ò¸¦ ¼¼ÆÃÇÑ´Ù. * °¢ REL sectionÀ» À§ÇØ relocationÀ» carry outÇÑ´Ù. * ½ÇÇà°¡´ÉÇÑ À̹ÌÁö¸¦ sectionsµéÀ» ¿¹»óµÇ´Â À§Ä¡ÀÇ ¸Þ¸ð¸®¿¡ copyÇØ ³ÖÀ¸¸é¼­ ºÐ¸®ÇÑ´Ù. lkmÀÇ cleanupÄÚµå¿Í ÃʱâÈ­Äڵ尡 ¾îµð¿¡ À§Ä¡ÇÏ´ÂÁö ¾È´Ù¸é, ´Ù¸¥ Ãß°¡ÀÇ stepÀ» ¼öÇàÇØ Áà¾ßÇÑ´Ù. * Àç¹èÄ¡ °¡´ÉÇÑ ELFÆ÷¸Ë¿¡¼­ ó·³ È­ÀÏÀ» ±¸ºÐÁþ´Â´Ù. * °¢ relevant sectionµéÀ» ¸Þ¸ð¸®¿¡ ·ÎµåÇÑ´Ù. * °¢ PROGBIT ¼½¼ÇµéÀ» À§ÇØ ¸Þ¸ð¸®¿¡ section ÁÖ¼Ò¸¦ ¼¼ÆÃÇÑ´Ù. * °¢ REL sectionÀ» À§ÇØ relocationÀ» carry outÇÑ´Ù. * ½ÇÇà°¡´ÉÇÑ À̹ÌÁö¸¦ sectionsµéÀ» ¿¹»óµÇ´Â À§Ä¡ÀÇ ¸Þ¸ð¸®¿¡ copyÇØ ³ÖÀ¸¸é¼­ ºÐ¸®ÇÑ´Ù. * init_moduleÀ̳ª clean_moduleÀÇ ÁÖ¼Ò¸¦ ÇÁ¸°Æ®Çϰí, À§Ä¡½ÃŲ´Ù. Àç¹èÄ¡ ½ºÅÜÀº ´ÙÀ½ÀÇ ¾Ë°í¸®ÁòÀ» È®ÀåÇØ¾ß ÇÒ °ÍÀÌ´Ù. * Àç¹èÄ¡ ¿£Æ®¸®ÀÇ ¸ñÀû ¼½¼ÇÀ» ±¸ÇÑ´Ù. * Àç¹èÄ¡ ¿£Æ®¸®ÀÇ ½Éº¼Å×À̺íÀ» ±¸ÇÑ´Ù. * Àç¹èÄ¡°¡ Àû¿ëµÉ ¼½¼Ç»ó¿¡¼­ÀÇ À§Ä¡¸¦ ±¸ÇÑ´Ù. * Àç¹èÄ¡¿¡ »ç¿ëµÇ´Â ½Éº¼ÀÇ ÁÖ¼Ò¸¦ ±¸ÇÑ´Ù. * Àç¹èÄ¡¸¦ Àû¿ëÇÑ´Ù. ½ÇÁ¦ÀûÀÎ Àç¹èÄ¡´Â ¼Ò½º¿¡ ³ªÅ¸³ªÀÖ´Ù. Àç¹èÄ¡¿¡ ´ëÇÑ ´õ ¸¹Àº Á¤º¸´Â ELF ½ºÆåÀ» ÂüÁ¶Ç϶ó. ±×¸®°í ¿ì¸®´Â global offset table°ú ¿ÂÀüÇÑ Àç¹èÄ¡ ŸÀÔÀ» öÀúÈ÷ ¹«½ÃÇß´Ù´Â °ÍÀ» ¾Ë¾ÆµÖ¶ó. switch (ELF32_R_TYPE(rel->r_info)) { case R_386_NONE: break; case R_386_PLT32: case R_386_PC32: *loc -= dot; /* *loc += addr - dot */ case R_386_32: *loc += addr; break; Àç¹èÄ¡¿¡ »ç¿ëµÇ´Â ½Éº¼ÀÇ ÁÖ¼Ò¸¦ °è»êÇÏ´Â °ÍÀº È®ÀåµÉ¼öµµ ÀÖ´Ù. ¸¸¾à¿¡ ½Éº¼ÀÌ localÀ̶ó¸é ±×°ÍÀº STB_LOCALÀÌ´Ù.µû¶ó¼­ ½Éº¼Àº ÇöÀç object ½Éº¼Å×ÀÌºí¿¡ À§Ä¡ÇØ ÀÖÀ» °ÍÀÌ´Ù. ,±×¸®°í ±×°ÍÀÌ ÇöÀçÀÇ object¿¡¼­¸¸ º¸¿©Áø´Ù´Â°Íµµ À¯ÀÇÇ϶ó. ¸¸¾à symbolÀÌ STB_GLOBALÀ̶ó°í ÇÑ´Ù¸é, ½Éº¼Àº object¿¡´ëÇØ Àü¿ªÀ̰í, ±× ½Éº¼ÀÇ ÁÖ¼Ò´Â ÀÌ ÀνºÅϽº¿¡¼­ Ä¿³Î ½Éº¼ÀÌ µÇ±â À§ÇØ ¾Ë·ÁÁ® ÀÖ´Ù. ±×·¡¼­ ¿ì¸®´Â System.mapÀ» »ç¿ëÇÔÀ¸·Î½á ȤÀº, ½Éº¼ÀÇ ÁÖ¼Ò¸¦ °áÁ¤ÇÏ´Â ±â¼úÀ» ÅëÇØ À̰ÍÀ» »ç¿ëÇÒ¼ö ÀÖ´Ù. ÀÌ °æ¿ì´Â, Á¦°øµÇ´Â ¼Ò½º¸¦ Âü°íÇÏ´Â °ÍÀÌ °¡Àå ÁÁÀº ±æÀÌ´Ù. BOOTSTRAP LOADING OF OBJECT CODE (LKM) »ç½Ç»ó, ½ÇÁ¦ lkmÀº kmalloc pool ÆÐµù¿¡ ¸ÂÁö ¾ÊÀ»°ÍÀÌ´Ù. ºñ½ÁÇÏ°Ô ¿ì¸®°¡ empty_bad_page¸¦ ¾´´Ù¸é, single pageº¸´Ù Ŭ°ÍÀ̸®¶ó. ±×°Í¿¡ ´ëÇÑ ¼Ö·ç¼ÇÀº bootstrapÀÌ lkmÀ» ·ÎµåÇÏ°Ô Çϴ°ÍÀÌ´Ù. kmallocÀÇ ÀϹÝÀûÀÎ Ä¿³Î method¸¦ »ç¿ëÇÏ¿© ÇÒ´çµÈ ¸Þ¸ð¸®ÀÇ padding¾È¿¡ ºÎÆ®½ºÆ®·¦ ·Î´õ¸¦ »ðÀÔÇϹǷνá ÇÒ ¼ö ÀÖ´Ù. ±×¸®°í ±×°ÍÀ» ½ÇÁ¦ÀÇ lkm¿¡ ³Ö°í ¸Þ¸ð¸®À» ÇÒ´çÇÏ¿© ½ÇÇà½ÃŲ´Ù. bootstrap ·Î´õ´Â ÃæºÐÇÏ°Ô ÀÛ¾ÆÁú¼ö ÀÖ°í ¿ì¸®ÀÇ lkmµéÀº ¾î´À »çÀÌÁî·Îµç ¸ÂÃß¾îÁú¼ö ÀÖ´Ù. ½ÇÁ¦·Î, Ä¿³ÎÀÌ bootstrapingÀ» enable½Ã۱âÀ§ÇØ Ä¿³Î¼Ó¿¡ ³Ö¾î¾ßÇÒ ¿ì¸®°¡ ÇÊ¿ä·ÎÇÏ´Â ÄÚµå´Â ¿ì¸®°¡ ·ÎµåÇØ¼­ ½ÇÇà½Ã۰íÀÚÇÏ´Â ½ÇÁ¦ ¸ðµâÀ» ÃæÁ·½Ãų¸¸ÇÑ ¸Þ¸ð¸®ºí·°À» ÇÒ´çÇÑ return ÁÖ¼ÒÀϰÍÀÌ´Ù. THE PROVIDED IMPLEMENTATION ÷ºÎµÈ ¼Ò½º´Â À§¿¡¼­ ¾ð±ÞÇÑ ¸ðµç ¾Ë°í¸®ÁòÀ» Æ÷ÇÔÇÑ´Ù. front end ½© ½ºÅ©¸³Æ®´Â À¯Àú¿¡°Ô ¾Ë·ÁÁöÁö ¾ÊÀº ³»ºÎ ¼¼ºÎ»çÇ׿¡¼­ ¹þ¾î³ª°Ô ÇØÁÖ±â À§ÇØ Á¦°øµÈ´Ù. CONCLUSION ¾Ë°í¸®Áò°ú ±¸Çö¿¡ µû¸¥ Å严Àº Ä¿³ÎÀÇ nativer ¼­Æ÷Æ®¸¦ ÅëÇØ ¸íÈ®È÷ ³ªÅ¸³¯¼ö ÀÖ´Â ¾î¶² °ÍÀ» Á¦°øÇϱâ À§ÇØ ¸Þ¸ð¸®¿¡ Á÷Á¢ÀûÀ¸·Î Á¢±ÙÇÏ´Â °ÍÀÌ °¡´ÉÇÏ´Ù´Â °ÍÀ» µ¥¸ð·Î Á¦°øÇÑ´Ù. ´Ù¸¥ À¯ÀúÀÇ ¹è¿­À» »ç¿ëÇÏ´Â °ø°ÝÀÚ¸¦ À§ÇÑ ½ÇÁ¦ÀûÀÎ ¿¹À» Á¦°øÇÒ ¼ö ÀÖ´Â, ¶ÇÇÑ Ä¿³Î ¸Þ¸ð¸®¿¡ ´ëÇÑ Á¢±ÙÀ» ½ÇÁ¦ º¸¿©ÁÖ´Â Á¦°øµÇ´Â ÇÁ·Î±×·¥µéÀº °øÇãÇÑ »ý°¢¸¸ÀÌ ¾Æ´Ï¶ó ½ÇÁ¦ÀûÀ¸·Î ±¸ÇöµÈ ¸Å¿ì À¯¿ëÇÑ °³³äÀÌ´Ù. --