本文分为两个部分,第一部分是调用到read()函数的过程,第二部分是解释向上方向键显示命令历史的过程。
yy_readline_get()
readline()
readline_internal()read()
第一步: 在read()下断点,read的地址为 0x39624
第二步:
<bochs:80> x /20wx 0x17:0x3bff5a4
[bochs]:
0x0bbff5a4 <bogus+ 0>: 0x00032afe 0x00000000 0x03bff5b4 0x00000001
返回地址 句柄0 字符c地址&c sizeof(char)
此时的堆栈中得到返回的字符c的地址为0x03bff5b4
第三步:在int0x80后下断点
最后的到字符d的返回值64!
<bochs:84> x /20wx 0x17:0x3bff5b4
[bochs]:
0x0bbff5b4 <bogus+ 0>: 0x00000064
下面是本文的第二部分:
下面看看向上方向键显示命令历史的过程:
向上方向键为ESC [ A
1d 5b 41
第一个是1d会调用:emacs_keymap.c
{ ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
(emacs_meta_keymap强制转换成函数指针)
既:
case ISKMAP:
if (map[key].function != (Function *)NULL)
{
int newkey;
rl_key_sequence_length++;
newkey = rl_read_key ();
rl_dispatch (newkey, (Keymap)map[key].function); /*又强制转换成了Keymap类型)*/
/*(注意这里递归调用的rl_dispatch()函数的第二个参数变成了emacs_meta_keymap[]的地址)*/
}
else
{
rl_abort ();
return;
}
break;
第二个是5b会调用:emacs_keymap.c
{ ISFUNC, rl_arrow_keys }, /* Meta-[ */
rl_arrow_keys()函数:会调用rl_read_key()函数取得下一个字符既41(A)所以会调用rl_get_previous_history()函数
参加readline.c中的下列代码:
rl_arrow_keys (count, c)
int count, c;
{
int ch;
ch = rl_read_key ();
switch (to_upper (ch))
{
case 'A':
rl_get_previous_history (count);
break;
case 'B':
rl_get_next_history (count);
break;
case 'C':
rl_forward (count);
break;
case 'D':
rl_backward (count);
break;
default:
ding ();
}
}
bash-1.05 by gcc-1.40 in minix-386 第二版 (readline.a 是bash-1.08或bash-1.12的)
百度网盘下载地址1:http://pan.baidu.com/share/link?shareid=339630&uk=453348606
csdn下载地址2:bash 1.05 by gcc-1.40 in minix-386 第二版