æ
å¢
ãã®è°è«ã¯Linuxãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã«ãŒãã«ã«èšåããŠããããã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã çšã®ã«ãŒãã«ã¢ãžã¥ãŒã«ãšãã©ã€ããŒã®éçºè
ã«ãšã£ãŠè峿·±ããã®ã§ãã ä»ã®ãã¹ãŠã®äººã«ãšã£ãŠããããã®ã¡ã¢ã¯ã»ãšãã©é¢å¿ããããŸããã
æãç°¡åãªLinuxã«ãŒãã«ã¢ãžã¥ãŒã«ãäœæãã人ã¯èª°ã§ãç¥ã£ãŠããŸãããŸããLinuxãã©ã€ããŒã®äœææè¡ã«é¢ããæ¢åã®ãã¹ãŠã®æžç±ã«æžãããŠããŸãã ããã¯ãLinuxã«ãŒãã«ãã¡ã€ã³ã®æãè€éãªæŠå¿µã®1ã€ã§ãããã«ãŒãã«ã·ã³ãã«ã®ãšã¯ã¹ããŒãã§ãã ã«ãŒãã«ç©ºéããã®ååãå¥ã®ã¢ãžã¥ãŒã«ã§ãã€ã³ãã§ããããã«ããã«ã¯ããã®ååã«ã€ããŠæ¬¡ã®2ã€ã®æ¡ä»¶ãæºãããŠããå¿
èŠããããŸãã ååã«ã¯ã°ããŒãã«ã¹ã³ãŒããå¿
èŠã§ãïŒã¢ãžã¥ãŒã«å
ã§ã¯ããã®ãããªååã¯éçãšå®£èšããªãã§ãã ããïŒããã³bïŒã ååã¯æç€ºçã«ãšã¯ã¹ããŒããšå®£èšããå¿
èŠãããããã¯ããã©ã¡ãŒã¿EXPORT_SYMBOLïŒãŸãã¯çµæçã«ã¯åãã§ã¯ãªãEXPORT_SYMBOL_GPLïŒã䜿çšããŠæç€ºçã«èšè¿°ããå¿
èŠããããŸãã
ã«ãŒãã«ã§ç¥ãããŠãããã¹ãŠã®ååã¯/ proc / kallsymsç䌌ãã¡ã€ã«ã«åçã«è¡šç€ºããããã®æ°ã¯èšå€§ã§ãïŒ
$ uname -r 3.13.0-37-generic $ cat /proc/kallsyms | wc -l 108960
ã«ãŒãã«ã«ãã£ãŠãšã¯ã¹ããŒããããååïŒã¢ãžã¥ãŒã«ã®ããã°ã©ã ã³ãŒãã§äœ¿çšããããã«æäŸãããïŒã®æ°ã¯å€§å¹
ã«å°ãªããªããŸãã
$ cat /lib/modules/`uname -r`/build/Module.symvers | wc -l 17533
ã芧ã®ãšãããã«ãŒãã«ã«ã¯ïŒã«ãŒãã«ã®ããŒãžã§ã³ã«å¿ããŠïŒæ°åäžã®ååãå®çŸ©ãããŠããŸãã ãã ãããããã®ååã®ã»ãã®äžéšïŒçŽ10ïŒ
ïŒã®ã¿ããšã¯ã¹ããŒããããŠãããšå®£èšãããŠãããã«ãŒãã«ã¢ãžã¥ãŒã«ã³ãŒãã§äœ¿çšïŒãã€ã³ãïŒã§ããŸãã
ã«ãŒãã«APIåŒã³åºãã¯ãååã®çµ¶å¯Ÿäœçœ®ã§è¡ãããããšãæãåºããŠãã ããã ã«ãŒãã«ïŒãŸãã¯ã¢ãžã¥ãŒã«ïŒã«ãã£ãŠãšã¯ã¹ããŒããããåååã«ã¯ã¢ãã¬ã¹ãé¢é£ä»ããããŠããããã®ååã䜿çšããŠã¢ãžã¥ãŒã«ãããŒããããšãã«ãã€ã³ãããããã«äœ¿çšãããŸãã ããã¯ãã¢ãžã¥ãŒã«ãšã«ãŒãã«éã®çžäºäœçšã®äž»ãªã¡ã«ããºã ã§ãã ã·ã¹ãã ãå®è¡ããããšãã¢ãžã¥ãŒã«ã¯åçã«ããŒããããã«ãŒãã«ã³ãŒãã®äžå¯æ¬ ãªéšåã«ãªããŸãã ããã«ãããLinuxã®ã«ãŒãã«ã¢ãžã¥ãŒã«ã¯ç¹å®ã®ã«ãŒãã«ïŒéåžžã¯ã€ã³ã¹ããŒã«å ŽæïŒã§ã®ã¿ã³ã³ãã€ã«ã§ãããã®ãããªãã€ããªã¢ãžã¥ãŒã«ãå¥ã®ã«ãŒãã«ã§ããŒãããããšãããšããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãã¯ã©ãã·ã¥ããŸãã
ãã®çããšã¯ã¹ã«ãŒã·ã§ã³ã®çµæãšããŠãLinuxã«ãŒãã«éçºè
ã¯ãæ¡åŒµæ©èœïŒã«ãŒãã«ã¢ãžã¥ãŒã«ïŒã®éçºè
åãã«ãéåžžã«éãããïŒéåžžã«äžååãªææžåãããïŒAPIã®ã»ãããæäŸãããšè¿°ã¹ãããšãã§ããŸãã ãããããã®æèŠã¯ããã©ã€ããŒã®éçºè
èªèº«ã®æèŠãšäžèŽããªãå ŽåããããŸãããã©ã€ããŒã®éçºè
ã¯ãã«ãŒãã«ã®ãã¹ãŠã®æŠåšãæã«ããããšèããŠããŸãã ãããŠãããã䜿çšããããšã¯ããªãå¯èœã§ããããã«ã€ããŠã¯æ®ãã®ããã¹ãã§èª¬æããŸãã
ååã§äœæãæ€çŽ¢
/ proc / kallsymså
ã®ïŒ108960以éã®ïŒã«ãŒãã«åã®ã¬ã³ãŒãè¡ã®æ§é ãèŠãŠã¿ãŸãããã
$ sudo cat /proc/kallsyms | grep ' T ' | grep sys_close c1176ff0 T sys_close
ããã¯ãã·ã¹ãã ã³ãŒã«ãã³ãã©ïŒPOSIXïŒcloseïŒïŒã®ãšã¯ã¹ããŒãåã§ãã ïŒäžéšã®Linuxãã£ã¹ããªãã¥ãŒã·ã§ã³ã§ã¯ãè¡ã®ã¢ãã¬ã¹ã¯ãèªã¿åããã«ãŒãç¹æš©ã§è¡ãããå Žåã«ã®ã¿å
¥åãããŸããä»ã®ãŠãŒã¶ãŒã®å Žåã¯ãã¢ãã¬ã¹ãã£ãŒã«ãã«ãŒãå€ã衚瀺ãããŸããïŒ
ã¢ãžã¥ãŒã«ã®ã³ãŒãã§sys_closeïŒïŒé¢æ°åŒã³åºãã䜿çšããããšãã§ããŸãã ãã ããsys_openïŒïŒãå®å
šã«å¯Ÿç§°çã«åŒã³åºããŠãããè¡ãããšã¯ã§ããŸããããã®ååã¯ã«ãŒãã«ã«ãã£ãŠãšã¯ã¹ããŒããããªãããã§ãã ãã®ãããªã¢ãžã¥ãŒã«ãçµã¿ç«ãŠããšã次ã®ãããªèŠåã衚瀺ãããŸãã
$ make ... MODPOST 2 modules WARNING: "sys_open" [/home/olej/2011_WORK/LINUX-books/examples.DRAFT/sys_call_table/md_0o.ko] undefined! ...
ãã ãããã®ãããªã¢ãžã¥ãŒã«ãããŒãããããšãããšå€±æããŸãã
$ sudo insmod md_0o.ko insmod: error inserting 'md_0o.ko': -1 Unknown symbol in module $ dmesg md_0o: Unknown symbol sys_open
ãã®ãããªã¢ãžã¥ãŒã«ã¯ãã«ãŒãã«ã®æŽåæ§ã«ãŒã«ã«ççŸãããããããŒãã§ããŸããïŒæªè§£æ±ºã®å€éšã·ã³ãã«ãå«ãŸããŠããŸã-ãã®ã·ã³ãã«ã¯ããã€ã³ãã£ã³ã°ã®ããã«ã«ãŒãã«ã«ãã£ãŠãšã¯ã¹ããŒããããŸããïŒã€ãŸããã³ã³ãã€ã©ã®èгç¹ããã®èŠåã¯ãéçºè
ã®èгç¹ããã¯é倧ãªãšã©ãŒã®ããã«èŠããŸãïŒã
äžèšã¯ããšã¯ã¹ããŒããããã«ãŒãã«ã·ã³ãã«ã®ã¿ãã¢ãžã¥ãŒã«ã®ã³ãŒãã§äœ¿çšã§ããããšãæå³ããŸããïŒ ããããããã¯ãååã«ããïŒååã®çµ¶å¯Ÿã¢ãã¬ã¹ã«ããïŒæšå¥šãã€ã³ãã£ã³ã°æ¹æ³ãããšã¯ã¹ããŒããããååã«ã®ã¿é©çšãããããšãæå³ããŸãã ãšã¯ã¹ããŒãã¯ãã«ãŒãã«ã®æŽåæ§ã確ä¿ããããã®å¥ã®è¿œå ã®å¶åŸ¡ã©ã€ã³ãæäŸããŸã-æå°éã®äžæ£ç¢ºãã¯ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®å®å
šãªã¯ã©ãã·ã¥ã«ã€ãªãããŸãã
ãã¹ãŠã®ã«ãŒãã«ã·ã³ãã«ã¯/ proc / kallsymsç䌌ãã¡ã€ã«ã«è¡šç€ºããããããã¢ãžã¥ãŒã«ã³ãŒãã¯ããããããããååŸã§ããŸãã ããã«ãããã¯ãã«ãŒãã«APIã«ãã¹ãŠã®ååãããŒã«ã©ã€ãºããã¡ãœãããããããããã®ã¡ãœãããåãç®çã§ã³ãŒãã§äœ¿çšã§ããããšãæå³ããŸãã äžéãœãªã¥ãŒã·ã§ã³ã®ãã¹ãçç¥ããŠã2ã€ã®ãªãã·ã§ã³ã2ã€ã®ãšã¯ã¹ããŒããããåŒã³åºãïŒã«ãŒãã«ã®<linux / kallsyms.h>ã®ãã¹ãŠã®å®çŸ©ããŸãã¯
lxr.free-electrons.com/source/include/linux/kallsyms.hãåç
§ïŒã®ã¿ãèæ
®ããŸãã
åŒã³åºãïŒ
unsigned long kallsyms_lookup_name( const char *name );
ããã§nameã¯æ¢ããŠããååã§ããã®çµ¶å¯Ÿã¢ãã¬ã¹ãè¿ãããŸãã ãã®ãªãã·ã§ã³ã®æ¬ ç¹ã¯ãã«ãŒãã«ããŒãžã§ã³2.6.32ãš2.6.35ã®éïŒãŸãã¯ããããã2010幎ã®å€ãš2011å¹Žã®æ¥ã®ããã±ãŒãžé
åžã®éïŒã®ã©ããã«è¡šç€ºãããããšã§ããæ£ç¢ºã«ã¯ã以åã«ååšããŸãããããšã¯ã¹ããŒããããŸããã§ããã çµã¿èŸŒã¿ã·ã¹ãã ããã³å°èŠæš¡ã·ã¹ãã ã®å Žåãããã¯é倧ãªé害ã«ãªãå¯èœæ§ããããŸãã
ããäžè¬çãªé»è©±ïŒ
int kallsyms_on_each_symbol( int (*fn)(void*, const char*, struct module*, unsigned long), void *data );
ãã®èª²é¡ã¯ããè€éã§ãããããã§ç°¡åãªèª¬æãå¿
èŠã§ãã æåã®ãã©ã¡ãŒã¿ãŒïŒfnïŒã¯ãã«ãŒãã«ããŒãã«å
ã®ãã¹ãŠã®æåã«å¯ŸããŠé£ç¶ããŠïŒã«ãŒãã§ïŒåŒã³åºããããŠãŒã¶ãŒå®çŸ©é¢æ°ãžã®ãã€ã³ã¿ãŒãåãåãã2çªç®ïŒããŒã¿ïŒ-ååŒã³åºãã«æž¡ãããä»»æã®ããŒã¿ãããã¯ïŒãã©ã¡ãŒã¿ãŒïŒãžã®ãã€ã³ã¿ãŒãã®é¢æ°fnïŒïŒã®ã
åååã«å¯ŸããŠåšæçã«åŒã³åºããããŠãŒã¶ãŒå®çŸ©é¢æ°fnã®ãããã¿ã€ãïŒ
int func( void *data, const char *symb, struct module *mod, unsigned long addr );
ããã«ïŒ
data-äžèšã§èª¬æããããã«ãåŒã³åºããŠãããã«å
¥åãããåŒã³åºãããkallsyms_on_each_symbolïŒïŒé¢æ°ïŒ2çªç®ã®åŒã³åºããã©ã¡ãŒã¿ãŒïŒã«æž¡ããããã©ã¡ãŒã¿ãŒãããã¯ãããã§ã¯ãæ¢ããŠãããã£ã©ã¯ã¿ãŒã®ååãæž¡ãã®ãããã§ãããã
symb-çŸåšã®funcåŒã³åºãã§åŠçããããã«ãŒãã«åããŒãã«ã®ååã®ã·ã³ããªãã¯ã€ã¡ãŒãžïŒæååïŒã
mod-åŠçãããæåãå±ããã«ãŒãã«ã¢ãžã¥ãŒã«ã
addr-ã«ãŒãã«ã®ã¢ãã¬ã¹ç©ºéå
ã®ã·ã³ãã«ã®ã¢ãã¬ã¹ïŒå®éãããã¯ç§ãã¡ãæ¢ããŠãããã®ã§ãïŒã
ãŠãŒã¶ãŒå®çŸ©é¢æ°funcããŒã以å€ã®å€ãè¿ãå Žåãã«ãŒãã«ããŒãã«ã®ååã®åæã¯çŸåšã®ã¹ãããã§äžæãããç¶è¡ã§ããªããªããŸãïŒå¹çäžã®çç±ãããå¿
èŠãªæåãæ¢ã«åŠçããŠããå ŽåïŒã
kallsyms_on_each_symbolïŒïŒã®åŒã³åºãã䜿çšããã«ã¯ãkallsyms_lookup_nameïŒïŒãšåãæå³ã®ç¬èªã®ã©ãããŒé¢æ°ãæºåããŸãã
static void* find_sym( const char *sym ) { // find address kernel symbol sym static unsigned long faddr = 0; // static !!! // ----------- nested functions are a GCC extension --------- int symb_fn( void* data, const char* sym, struct module* mod, unsigned long addr ) { if( 0 == strcmp( (char*)data, sym ) ) { faddr = addr; return 1; } else return 0; }; // -------------------------------------------------------- kallsyms_on_each_symbol( symb_fn, (void*)sym ); return (void*)faddr; }
ããã§ã¯ãsymb_fnïŒïŒé¢æ°ã®çµã¿èŸŒã¿å®çŸ©ã䜿çšããããªãã¯ã䜿çšããŸãããããã¯ãGCCã³ã³ãã€ã©æ¡åŒµïŒCèšèªæšæºã«é¢é£ïŒã䜿çšããŠå®å
šã«æ£åœã§ãããã«ãŒãã«ã¢ãžã¥ãŒã«ã®ã³ã³ãã€ã«ã«ã¯GCCã®ã¿ã䜿çšããŸãã ãã®ã³ãŒãã¯ãã°ããŒãã«ãªäžé倿°ã®å®£èšãé¿ããåå空éã®è©°ãŸããé²ããã³ãŒãã®ããŒã«ã©ã€ãºã«åœ¹ç«ã¡ãŸãã
䜿çšäŸ
Linuxãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§æãç¥èãªå Žæã®1ã€ã¯ãã·ã¹ãã ã³ãŒã«ãè¡ãããsys_call_tableã»ã¬ã¯ã¿ããŒãã«ã§ããããã«å¿ããŠãã©ã¡ãŒã¿ãæºåãã1çªç®ã®ãã©ã¡ãŒã¿ã§ã·ã¹ãã ã³ãŒã«ã®çªå·ïŒã»ã¬ã¯ã¿ïŒãæžã蟌ããšãã·ã¹ãã ã¯ã³ãã³ããå®è¡ããŠã«ãŒãã«ã«ç§»åããŸãïŒint 80hïŒinæ¬è³ªçã«ã¯åããã®ã§ãïŒã ã·ã¹ãã ã³ãŒã«çªå·ïŒã»ã¬ã¯ã¿ãŒã第1ãã©ã¡ãŒã¿ãŒïŒã¯ãã«ãŒãã«ã·ã¹ãã ã³ãŒã«åŠç颿°ãžã®ãã€ã³ã¿ãŒã®sys_call_tableïŒé
åïŒå
ã®ã€ã³ããã¯ã¹ã§ãã ããšãã°ãi386ã¢ãŒããã¯ãã£ã®å Žåããã¹ãŠã®ã·ã¹ãã ã³ãŒã«ã®æ°ã確èªã§ããŸãã
$ cat /usr/include/i386-linux-gnu/asm/unistd_32.h ...
以äžã¯ãæšæºã©ã€ãã©ãªC libc.soã«ãã£ãŠå®è£
ãããããŠãŒã¶ãŒã®ã¢ãã¬ã¹ç©ºéã§äœ¿çšãããã·ã¹ãã ã³ãŒã«ã®ã€ã³ããã¯ã¹ïŒçªå·ïŒã®è¡šã§ãã ãã®ããŒãã«ã®æ£ç¢ºãªé¡äŒŒç©ã¯ãã«ãŒãã«ã®ã¢ãã¬ã¹ç©ºéã«ããã«ãŒãã«ããããŒãã¡ã€ã«ã«ããããŸãã ãŸããã·ã¹ãã ã³ãŒã«ã€ã³ããã¯ã¹ã®åæ§ã®ããŒãã«ã¯ãLinuxã§ãµããŒãããããã¹ãŠã®ã¢ãŒããã¯ãã£ã«ååšããŸãïŒç°ãªãã¢ãŒããã¯ãã£ã®ããŒãã«ã¯ããµã€ãºãæ§æãããã³åæ§ã®ã³ãŒã«ã®ã€ã³ããã¯ã¹ã®æ°å€ãç°ãªããŸãïŒïŒã
ã«ãŒãã«ã®ããŒãžã§ã³2.6以éãã«ãŒãã«éçºããŒã ãéåžžã«ããçè§£ããŠããã»ãã¥ãªãã£äžã®èæ
®äºé
ã«åºã¥ããŠãsys_call_tableã·ã³ãã«ã¯ãšã¯ã¹ããŒãããé€å€ãããŠããŸãïŒã»ãã¥ãªãã£ã¯ããµãŒãããŒãã£ã®ããã°ã©ããŒããä¿è·ãããã«ãŒãã«éçºè
ã®äžéšãšããæå³ã§ããã§è§£éãããããšã«ãªã£ãŠãããšæšæž¬ã§ããŸãïŒã Linuxãã©ã€ããŒã®äœæã«é¢ãããã¹ãŠã®æžç±ã«ã¯ããã©ã€ããŒã³ãŒãã§sys_call_tableã䜿çšã§ããªãããšãèšèŒãããŠããŸãã ããŠããããŠããã«è°è«ã®æ¬¡ã®éšåã§ãããã¯ããã§ã¯ãªãããšã瀺ããŸãïŒ
ããªãé·ãéïŒ2011幎以éïŒãè°è«äžã®äž»é¡ãæ±ã£ãŠããã®äž»é¡ã«é¢ããå€ãã®åºçç©ãèªã¿ãŸããã sys_cal_tableæ€çŽ¢ã®ããã«çºæããã®ã§ã¯ãªããæãããåèªããã«ãŒã§èªåèªèº«ãæãããããŠã€ã«ã¹ã©ã€ã¿ãŒããã®ä»ã®ãŽã-ã«ãŒãã«ã¡ã¢ãªã®ã»ã¯ã·ã§ã³ãã¹ãã£ã³ããããšã§ãã«ãŒãã«ãå æãããã€ããªã¡ã¢ãªãã©ã°ã¡ã³ãã®ãã³ããåçã«ãã³ãŒãããŸãïŒããšãã°ãsys_closeïŒïŒäœçœ®ã¯ãšã¯ã¹ããŒããããŸãïŒåžžã«ïŒã ãããã瀺ãããããã«ãããã¯ãã¹ãŠã¯ããã«ç°¡åã«è¡ãããŸãã Linuxã®åŸ©å
åã®å¯äžã®ç§å¯ã¯ããã§ã¯ãããŸããã ãã®æ±ãããªãã¯ã¯ããã«äœããèŠã€ããããšãã§ããŸããããã¢ã¯ã»ã¹æš©ã®èŠå¶ã¯ïŒã«ãŒãã®æš©å©ãªãã§ïŒãã®èŠå¶ã®å€ã§åä»ãªããšãããããšãèš±ããŸãã...ãããŠèª°ãæ±ãããªãã¯ã«ã«ãŒãã®æš©å©ãäžããŸããã
ãã ãããšã¯ã¹ããŒãã§ããªãã«ãŒãã«æåã解決ããã¿ã¹ã¯ã«æ»ããŸãã æåã®ãªãã·ã§ã³ïŒmod_kct.cãã¡ã€ã«ïŒã¯ãkallsyms_lookup_nameïŒïŒã®äœ¿ç𿹿³ã瀺ããŠããŸãïŒç°¡åã«ããããã«ãããããŒãã¡ã€ã«ã®ã€ã³ã¯ã«ãŒãã¯è¡šç€ºãããŸãããMODULE_ *ïŒïŒãªã©ã®å¿
èŠãªãã¯ãã¯ãã¢ãŒã«ã€ããã¡ã€ã«ã«ãããŸãïŒã
static int __init ksys_call_tbl_init( void ) { void** sct = (void**)kallsyms_lookup_name( "sys_call_table" ); printk( "+ sys_call_table address = %p\n", sct ); if( sct ) { int i; char table[ 120 ] = "sys_call_table : "; for( i = 0; i < 10; i++ ) sprintf( table + strlen( table ), "%p ", sct[ i ] ); printk( "+ %s ...\n", table ); } return -EPERM; } module_init( ksys_call_tbl_init );
ããã§ã¯ãsys_call_tableããŒãã«ã®ã¢ãã¬ã¹ãååŸãããããã«å«ãŸããæåã®10åã®ã·ã¹ãã ã³ãŒã«ïŒ__NR_restart_syscall ... __NR_linkïŒã®ãã³ãã©ãŒã®ã¢ãã¬ã¹ãæœåºãããŸãã
$ sudo insmod mod_kct.ko insmod: ERROR: could not insert module mod_kct.ko: Operation not permitted $ dmesg | tail -n 2 [39473.496040] + sys_call_table address = c1666140 [39473.496045] + sys_call_table : c1067840 c1059280 c1055eb0 c1179ee0 c1179f70 c1178cb0 c1176ff0 c1059570 c1178d10 c1188860 ...
ïŒãšã©ãŒãæäœã¯èš±å¯ãããŠããŸãããã¯æ··ä¹±ããªãã¯ãã§ã-ãŒã以å€ã®ãªã¿ãŒã³ã³ãŒã-EPERMã§ç€ºãããããã«ãã¢ãžã¥ãŒã«ãããŒãããã€ããã¯ãããŸããã§ãããç¹æš©ã¢ãŒããã¹ãŒããŒãã€ã¶ãŒãããã»ããµä¿è·ãªã³ã°ãŒãã§ã³ãŒããå®è¡ããã ãã§ãïŒã
èŠã€ãã£ãã¢ãã¬ã¹ãsys_call_tableé
åã®å
é ã«ããããšã確èªããŸãã
$ sudo cat /proc/kallsyms | grep c1067840 c1067840 T sys_restart_syscall $ sudo cat /proc/kallsyms | grep c1059280 c1059280 T SyS_exit c1059280 T sys_exit $ sudo cat /proc/kallsyms | grep c1055eb0 c1055eb0 T sys_fork
...ãªã©ïŒåè¿°ã®ã·ã¹ãã ã³ãŒã«çªå·ã®è¡šãšæ¯èŒããŠãã ããïŒã
次ã®ãªãã·ã§ã³ã¯çè§£ãå°ãé£ãããªããŸããkallsyms_on_each_symbolïŒïŒé¢æ°ã䜿çšããŸãããããæ±çšçã§ãïŒmod_koes.cãã¡ã€ã«ïŒïŒ
static int __init ksys_call_tbl_init( void ) { void **sct = find_sym( "sys_call_table" ); // table sys_call_table address printk( "+ sys_call_table address = %p\n", sct ); if( sct != NULL ) { int i; char table[ 120 ] = "sys_call_table : "; for( i = 0; i < 10; i++ ) sprintf( table + strlen( table ), "%p ", sct[ i ] ); printk( "+ %s ...\n", table ); } return -EPERM; } module_init( ksys_call_tbl_init );
ããã¹ãçã«ã¯ãåã®ãã®ãšã»ãŒå®å
šã«ç¹°ãè¿ãããŸããfind_symïŒïŒé¢æ°ã¯ãäžèšã§èª¬æããŸãããããã¹ãŠã®çç£çãªäœæ¥ãè¡ããŸãã å®è¡ã®çµæã¯åžžã«åãã§ãïŒ
$ sudo insmod mod_koes.ko insmod: ERROR: could not insert module mod_koes.ko: Operation not permitted $ dmesg | tail -n2 [42451.186648] + sys_call_table address = c1666140 [42451.186654] + sys_call_table : c1067840 c1059280 c1055eb0 c1179ee0 c1179f70 c1178cb0 c1176ff0 c1059570 c1178d10 c1188860 ...
è°è«
æçè«è
ã¯ç°è°ãå±ãããããããªãïŒãã ããäœïŒã åçã«ããŒããããå®éã®ã«ãŒãã«ã¢ãžã¥ãŒã«ã³ãŒãã§ã«ãŒãã«APIã䜿çšããããã«å¿
èŠãã€ååãªã¡ã«ããºã ã瀺ãããŠãããšããäºå®ã 瀺ãããŠããææ³ã«ãããã«ãŒãã«ã¢ãžã¥ãŒã«ã®äœæè
ã®æ©èœã®ç¯å²ã倧å¹
ã«æ¡å€§ãããŸãã ãããã¯éåžžã«èšå€§ãªèŠéãã§ãããããæ€èšã®ããã«ãã®è°è«ã®åŸç¶ã®éšåãå¿
èŠã«ãªããŸãã
...ããããã¹ããŒãªãŒã®å®æãããã»ã©éå±ã§ã¯ãªãããã«ãã·ã³ãã«ã ãå°è±¡çãªã¢ããªã±ãŒã·ã§ã³ã®1ã€ã玹ä»ããŸããã«ãŒãã«ã¢ãžã¥ãŒã«ã³ãŒããããŠãŒã¶ãŒã©ã€ãã©ãªã®ã·ã¹ãã ã³ãŒã«ã³ãŒãïŒäžè¬çã«ã¯ä»»æïŒãå®è¡ããŸãã
ã«ãŒãã«ã¢ãžã¥ãŒã«ã³ãŒããã·ã¹ãã ãã°ïŒprintkïŒïŒïŒã«åºåãæäŸãã端æ«ïŒprintfïŒïŒïŒã«åºåã§ããªããšèšãããŸãããïŒ ããã¯ããã§ã¯ãªãããšã瀺ããŸã...ããã«ã端æ«ã«åºåãããã®ãããªåçŽãªã«ãŒãã«ã¢ãžã¥ãŒã«ã瀺ããŸãã
static asmlinkage long (*sys_write) ( unsigned int, const char __user *, size_t ); static int __init wr_init( void ) { char buf[ 80 ] = "Hello from kernel!\n"; int len = strlen( buf ), n; sys_write = find_sym( "sys_write" ); printk( "+ sys_write address = %p\n", sys_write ); printk( "+ [%d]: %s", len, buf ); if( sys_write != NULL ) { mm_segment_t fs = get_fs(); set_fs( get_ds() ); n = sys_write( 1, buf, len ); set_fs( fs ); printk( "+ printf() return : %d\n", n ); } return -EPERM; } module_init( wr_init );
ãããŠãããã«ãã®å®è¡ããããŸãïŒç·æ¥çµäºã³ãŒãã§èµ·åãã詊ã¿ïŒïŒ
$ sudo insmod mod_wrc.ko Hello from kernel! insmod: ERROR: could not insert module mod_wrc.ko: Operation not permitted $ dmesg | tail -n3 [23942.974587] + sys_write address = c1179f70 [23942.974591] + [19]: Hello from kernel! [23942.974612] + printf() return : 19
ããã®æåã®è¡ã¯ãwriteïŒïŒã·ã¹ãã ã³ãŒã«ã§ãã åœç¶ãåºåã¯ãŠãŒã¶ãŒããã»ã¹insmodã®å¶åŸ¡ç«¯æ«ã«å¯ŸããŠè¡ãããŸãããããã§éèŠãªããšã¯ãã«ãŒãã«ã¹ããŒã¹ã³ãŒãããwriteïŒïŒã·ã¹ãã ã³ãŒã«ãå®è¡ããããšã§ãã ããã§ãããã€ãã®è©³çްã«ã€ããŠããã«èª¬æãå¿
èŠã«ãªãå ŽåããããŸãã
ã¢ãã¬ã¹å€æ°sys_writeãèšè¿°ããããã®ãããªãããŒãªããããã¿ã€ãã¯ã©ãã§å
¥æããŸãããïŒ ãã¡ãããã«ãŒãã«ã®sys_writeïŒïŒé¢æ°ã®å
ã®å®çŸ©ãã<linux / syscalls.h>ããããŒãã¡ã€ã«ã«ãã³ãŒãã®ã³ã¡ã³ãïŒã¢ãŒã«ã€ãå
šäœã®ã³ãŒãïŒã«ç€ºãããŠããããã«ãæ¥ç¥ããã«æžãçããŸããã
/* <linux/syscalls.h> asmlinkage long sys_write( unsigned int fd, const char __user *buf, size_t count ); */
ãããŠãããã¯ã䜿çšãããŠãããã¹ãŠã®ãšã¯ã¹ããŒããããŠããªãã«ãŒãã«åã«å¯Ÿå¿ããå¯äžã®æ¹æ³ã§ã-察å¿ããããããŒãã¡ã€ã«ãã颿°ãå®è£
ãããããã¿ã€ããæžãèœãšããŸãã ãããã¿ã€ãã®æå°éã®äžäžèŽã¯ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®å³æã¯ã©ãã·ã¥ã«ã€ãªãããŸãïŒ
get_dsïŒïŒãget_fsïŒïŒãset_fsïŒïŒãšãã圢åŒã®ããã€ãã®åæ§ã®åŒã³åºãã¯ã©ãããæå³ã§ããïŒ ããã¯ãã«ãŒãã«å
ã®ããŒã¿ã»ã°ã¡ã³ãã®äžæçãªçœ®æã§æ§æãããå°ããªããªãã¯ã§ãã å®éãsys_writeïŒïŒã·ã¹ãã ã³ãŒã«ãã³ãã©ã®ãããã¿ã€ãã«ã¯__user修食åããããããã¯ãã€ã³ã¿ããŠãŒã¶ãŒç©ºéã®ããŒã¿ãæããŠããããšã瀺ããŠããŸãã ã·ã¹ãã ã³ãŒã«ã³ãŒãã¯ããããå±ãããã©ããïŒã¢ãã¬ã¹ã®æ°å€ã®ç¯å²ã®ã¿ïŒããã§ãã¯ããã¢ãã¬ã¹ãã«ãŒãã«ã¹ããŒã¹ã®é åãæãå ŽåïŒãã®å Žåã®ããã«ïŒãç°åžžçµäºãåŒãèµ·ãããŸãã ãã®ããªãã¯ã䜿çšããŠãã¢ãã¬ã¹ããŠãŒã¶ãŒã®ã¹ããŒã¹ã«å±ãããã®ãšããŠè§£éãããå¿
èŠãããããšãå¶åŸ¡ã³ãŒãã«ç€ºããŸãã ãã®ãããªå Žåããã®ããªãã¯ã¯ããã®æå³ãå®éã«èããã«ãæ©æ¢°çã«äœ¿çšã§ããŸãã
泚é
åæ§ã®ã³ãŒãã䜿çšããå®éšãããã«è©³ãã説æããã±ãŒã¹ïŒããã«è©³ããã¯åŸè¿°ããŸãïŒã§ã¯ãåé¡ãçºçããŸããã³ãŒãã®å°ããªãšã©ãŒã§ãããããã«ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãå§åããŸãã ããã«æªãããšã«ãã·ã¹ãã ã¯äžç¹å®ã®äžå®å®ãªç¶æ
ã§ã¯ã©ãã·ã¥ããåèµ·ååŸãã·ã¹ãã ãå埩ããªãå¯èœæ§ããããŸãïŒããã»ã©é«ããªãïŒã
åæ§ã®ã³ãŒãã䜿çšããå®éšäžãç§ã¯åžžã«çåãæ±ããŠããŸãããä»®æ³ãã·ã³ã§ãã¹ãããŠãã¹ãããããšã¯å¯èœã§ããïŒ ããã¯ãCR0ãªã©ã®é ãããã»ããµããŒããŠã§ã¢ã¬ãžã¹ã¿ãžã®æžã蟌ã¿ãªã©ãéåžžã«ãã·ã³ã«äŸåããããšãå®è¡ããå¿
èŠããããšããäºå®ã«ããããããã§ãã
è°è«ããããã¹ãŠã®ã³ãŒãã¯ãå°ãªããšã2013幎ã®ç¶æ
ããå§ãŸã£ãŠãå°ãªããšãæ¯èŒçææ°ã®ããŒãžã§ã³ã®Oracle VirtualBoxç°å¢ã®ä»®æ³ãã·ã³ã§é©åã«å®è¡ããããšæºè¶³ããŠè¿°ã¹ãããšãã§ããŸãã
ãããã£ãŠãæ·±å»ãªãã©ãã«ãåé¿ããããã«ãä»®æ³ãã·ã³ã§æåã«ãã®ãããªã³ãŒãã䜿çšããããšã匷ããå§ãããŸãã
Oracle VirtualBoxã®èšåã¯ããã®ç¶æ³ãä»ã®ä»®æ³ãã·ã³ãããŒãžã£ãŒã«ä¿åãããªãããšãæå³ãããã®ã§ã¯ãããŸããããããã®ãããŒãžã£ãŒã®ã³ãŒãããã§ãã¯ããŸããã§ããïŒVirtualBoxã¯QEMUããä»®æ³åã³ãŒããååŸãããããã»ãŒç¢ºå®ã«ãã¹ãŠãQEMU / KVMã§å®å
šã«ãªããŸãïŒã
æ¬æã«èšèŒãããŠããå®éšçšã®ãã¡ã€ã«ïŒã³ãŒãïŒã®ã¢ãŒã«ã€ãã¯ã
ãããŸãã¯
ããã§å
¥æã§ã
ãŸã ã