最近在研究二进制,研究到函数调用部分,将自己理解的原理做个记录。

首先需要了解系统栈的工作原理,栈可以理解成一种先进后出的数据结构,这就不用多说了。
在操作系统中,系统栈也起到用来维护函数调用、参数传递等关系的一个作用。嗯,这是我的理解。
在高级语言编程中,函数调用的底层原理是对用户屏蔽的,所以不用过多的纠结于底层的实现。而对于
汇编研究者来说,了解这个原理就很重要了。
首先可以想象一下,汇编语言在内存中是以指令的形式存在的,这些指令是按照顺序存储和执行的,高级语言中
编写的循环、调用,到了底层都会变成一些最基本的判断和跳转,如何在线性的结构上完成“非线性”的过程调度,
理解了这些,就理解了汇编。

这里先抛出高级语言的一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
/*20160701*/
#include <stdio.h>

int funcA( int arg ){
arg += 1;
return arg;
}

int main(){
int a;
a = funcA(1);
printf("%d", a);
}

在这个程序中,main函数调用了函数funcA,funcA对传入的数据进行+1然后返回。
这个程序在编译之后,main函数变成这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000400516 <+0>: push rbp
0x0000000000400517 <+1>: mov rbp,rsp
0x000000000040051a <+4>: sub rsp,0x10
0x000000000040051e <+8>: mov edi,0x1
0x0000000000400523 <+13>:call 0x400506 <funcA>
0x0000000000400528 <+18>:mov DWORD PTR [rbp-0x4],eax
0x000000000040052b <+21>:mov eax,DWORD PTR [rbp-0x4]
0x000000000040052e <+24>:mov esi,eax
0x0000000000400530 <+26>:mov edi,0x4005d4
0x0000000000400535 <+31>:mov eax,0x0
0x000000000040053a <+36>:call 0x4003e0 <printf@plt>
0x000000000040053f <+41>:leave
0x0000000000400540 <+42>:ret
End of assembler dump.

其中rbp是调用main函数的函数的栈桢的底部,这么说有点绕,简单的来说,main函数调用了funcA,那funcA中首先要做的一件事情就是把调用它的main函数栈桢的底部保存,所以在main函数被操作系统装载执行之后,main要做的首先是把调用它的函数的栈桢的底部保存,不然怎么返回呢?
第二个步骤把rsp的值传递给rbp,这是替换当前栈桢的底部,因为调用了funcA,所以要为funcA创建独立的栈桢,于是抬高栈底,怎么抬高呢,把栈顶传给指向栈桢底部的指针就可以了。
下一步是抬高栈顶,这是为funcA创建栈桢空间。
接着将参数传递给edi,因为这里只有一个参数,所以不涉及到参数顺序的问题,关于这个问题,可以去了解一下函数调用约定
调用了funcA,再来观察一下funcA的内部机制:

1
2
3
4
5
6
7
8
9
10
(gdb) disassemble funcA
Dump of assembler code for function funcA:
0x0000000000400506 <+0>: push rbp
0x0000000000400507 <+1>: mov rbp,rsp
0x000000000040050a <+4>: mov DWORD PTR [rbp-0x4],edi
0x000000000040050d <+7>: add DWORD PTR [rbp-0x4],0x1
0x0000000000400511 <+11>: mov eax,DWORD PTR [rbp-0x4]
0x0000000000400514 <+14>: pop rbp
0x0000000000400515 <+15>: ret
End of assembler dump.

同样的,在funcA中,首先保存上一个函数,即main函数栈桢的栈底,然后将rsp的值赋给rbp,抬高栈桢底部。
接着从edi中取得参数,并放入位于自身栈桢空间中,rbp之后的双字单元内。
然后执行操作,将其自增。
执行完成之后,将返回值保存在eax中,等待返回。
弹出上一个函数的栈桢的底部,重新回到main函数的空间。

PS:
直到目前为止,这个程序反编译出来的结果和书上说的原理还是有一些出入的,还有下面几个问题:
0x01 书上说的是,传递参数,会将参数按照一定顺序压栈,而不是像本程序中这样使用edi
0x02 在main函数调用funcA函数之后,将栈顶指针esp抬高了,但是在funcA函数执行完成需要返回到main函数的时候,只恢复了ebp指针,并没有恢复esp指针,这是为什么?

希望接下来可以搞懂上面的两个问题。
本文中用到的相关代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*20160701*/
#include <stdio.h>

int funcA( int arg ){
arg += 1;
return arg;
}

int main(){
int a;
a = funcA(1);
printf("%d", a);
}

SP Flash Tool v3.1224.0.100
MT6516,MT6573,MT6573,MT6575,MT6575,MT6577,
SP Flash Tool v3.1332.0.187
MT6516,MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6582,MT8135,
SP Flash Tool v3.1344.0.212

MT6516,MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6582,MT8135,MT6592,MT6571,
SP Flash Tool v5.1352.01
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT6592,
SP-Flash-Tool-v5.1436.00
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,
SP-Flash-Tool-v5.1528.00
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,MT8163,MT8590,MT6580,MT6570,
SP-Flash-Tool-v5.1532.00
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,MT8163,MT8590,MT6580,MT6570,MT6755,
SP_Flash_Tool_5.1343
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT6592,
SP_Flash_Tool_5.1504
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,
SP_Flash_Tool_5.1520
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,MT8163,MT8590,MT6580,MT6570,
SP_Flash_Tool_5.1524.00
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,MT8163,MT8590,MT6580,MT6570,
SP_Flash_Tool_v5.1452
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,
SP_Flash_Tool_v5.1512
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,MT8163,MT8590,MT6580,MT6570,
SP_Flash_Tool_v5.1516
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6735M,MT6753,MT8163,MT8590,MT6580,MT6570,
SP_Flash_Tool_v5.1548
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737,MT6735M,MT6753,MT8163,MT8590,MT6580,MT6570,MT6755,MT6797,
SP_Flash_Tool_v5.1552
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT7623,MT6580,MT6570,MT6755,MT6797,
SP_Flash_Tool_v5.1604
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,
SP_Flash_Tool_v5.1612
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,
SP_Flash_Tool_v5.1616_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,ELBRUS,MT6798,MT0507,
SP_Flash_Tool_v5.1620_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,ELBRUS,MT6798,MT0507,MT8160,MT0633,
SP_Flash_Tool_v5.1624_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,ELBRUS,MT6798,MT0507,MT8167,MT0633,
SP_Flash_Tool_v5.1628_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,ELBRUS,MT6799,MT0507,MT8167,MT0633,
SP_Flash_Tool_v5.1632_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT8521,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,ELBRUS,MT6799,MT0507,MT8167,MT6570,MT0690,
SP_Flash_Tool_v5.1636_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT8521,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,ELBRUS,MT6799,MT6798,MT8167,MT6570,MT0690,
SP_Flash_Tool_v5.1640_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT8521,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,MT6757D,ELBRUS,MT6799,MT6798,MT8167,MT6570,MT0690,
SP_Flash_Tool_v5.1644_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT8521,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,MT6757D,ELBRUS,MT6799,MT6798,MT8167,MT6570,MT0690,
SP_Flash_Tool_v5.1648_Win
MT6573,MT6573,MT6575,MT6575,MT6577,MT6589,MT6572,MT6571,MT6582,MT8135,MT8127,MT6592,MT6595,MT6752,MT2601,MT6795,MT8173,MT6735,MT6737T,MT6735M,MT6737M,MT6753,MT8163,MT8590,MT8521,MT7623,MT6580,MT6570,MT6755,MT6750,MT6797,MT6757,MT6757D,ELBRUS,MT6799,MT6759,MT8167,MT8516,MT6570,MT6763,

下载链接:
http://spflashtools.com/windows/sp-flash-tool-v5-1343
http://spflashtools.com/windows/sp-flash-tool-v5-1352
http://spflashtools.com/windows/sp-flash-tool-v5-1436
http://spflashtools.com/windows/sp-flash-tool-v5-1452
http://spflashtools.com/windows/sp-flash-tool-v5-1504
http://spflashtools.com/windows/sp-flash-tool-v5-1512
http://spflashtools.com/windows/sp-flash-tool-v5-1516
http://spflashtools.com/windows/sp-flash-tool-v5-1520
http://spflashtools.com/windows/sp-flash-tool-v5-1524
http://spflashtools.com/windows/sp-flash-tool-v5-1528
http://spflashtools.com/windows/sp-flash-tool-v5-1532
http://spflashtools.com/windows/sp-flash-tool-v5-1548
http://spflashtools.com/windows/sp-flash-tool-v5-1552
http://spflashtools.com/windows/sp-flash-tool-v5-1604
http://spflashtools.com/windows/sp-flash-tool-v5-1612
http://spflashtools.com/windows/sp-flash-tool-v5-1616
http://spflashtools.com/windows/sp-flash-tool-v5-1620
http://spflashtools.com/windows/sp-flash-tool-v5-1624
http://spflashtools.com/windows/sp-flash-tool-v5-1628
http://spflashtools.com/windows/sp-flash-tool-v5-1632
http://spflashtools.com/windows/sp-flash-tool-v5-1636
http://spflashtools.com/windows/sp-flash-tool-v5-1640
http://spflashtools.com/windows/sp-flash-tool-v5-1644
http://spflashtools.com/windows/sp-flash-tool-v5-1648

出于隐私需求,不想暴露自己的真实mac地址。
把下面这个脚本的内容加入/etc/init.d,就可以在每次开机的时候为网卡随机设置一个mac地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
#Chorder
#2016/12/08
#http://chorder.net

mhash=`date +%s|md5sum`

ifconfig eth0 down
ifconfig eth0 hw ether `echo ${mhash:$((RANDOM % 13)):2}:\
${mhash:$((RANDOM % 13)):2}:${mhash:$((RANDOM % 13)):2}:\
${mhash:$((RANDOM % 15)):2}:${mhash:$((RANDOM % 15)):2}:\
${mhash:$((RANDOM % 15)):2} `
ifconfig eth0 up

ifconfig wlan0 down
ifconfig wlan0 hw ether `echo ${mhash:$((RANDOM % 13)):2}:\
${mhash:$((RANDOM % 13)):2}:${mhash:$((RANDOM % 13)):2}:\
${mhash:$((RANDOM % 15)):2}:${mhash:$((RANDOM % 15)):2}:\
${mhash:$((RANDOM % 15)):2} `
ifconfig wlan0 up

终于解决这个问题了。
来记录一下。
~下面的.Xmodmap文件
如果想要鼠标逆序滚动,就将其中的内容改为

1
pointer = 1 2 3 4 5 6 7 8 9 10 11 12

否则,就将内容改为:

1
pointer = 1 2 3 5 4 6 7 8 9 10 11 12

4和5代表的是鼠标滚轮方向的映射。

给有需要的人。

初学溢出,免不了要经历这一关。
闲话不多说,直接说方法。
Windows XP SP3
在Windows XP SP3中,关闭DEP的方法是:
编辑C:\boot.ini,你大概会看到如下内容

1
2
3
4
5
6
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional"
/noexecute=optin /fastdetect

要关闭DEP,将/noexecute=optin 改为/excute,重启系统即可。

Windows 7
Windows7中不是通过boot.ini来保护了,需要在命令行中输入bcdedit,如果观察到输出的最后一项为
nx 1
表示DEP保护是开启的,并且级别为1
只需要运行

1
bcdedit /set nx alwaysoff

就可以了,然后重启系统。

从二十世纪六七十年代美国的”电话飞客“到现如今的各种攻击手段,黑客的发展已经历经了快六十个年头。这期间发展出了很多新颖的攻击技术,也因此催生了信息安全行业快速蓬勃的发展,更涌现了一批又一批的牛人。黑客的圈子从来不缺故事,只是这群让政府头疼,让网民害怕,却也让人又爱又恨的可爱家伙们,他们的思路太快太活跃。他们厌恶世俗,厌倦繁杂的事务,他们更害怕被曝光,怕找麻烦,我想这大概也是黑客圈很少有人著书立传的原因吧。

其实要说起黑客精神,古代的锁匠,乃至近代以后的图灵、香农等等,他们的身上,是最早出现”黑客“这一属性的。锁匠,他们对着一把没有钥匙的锁,去苦苦探索如何巧妙的解开之,直到最后想出百般奇技,用尽千种淫巧去破解锁的过程,就是一种”hack“的行为。也就不难想到,图灵、香农这类奠定密码学、信息论等基础理论的前人了。”hack“这个单词的本意,是有劈、砍、开垦之意,最早的黑客技术,可能其理论并不复杂,甚至是一种很原始的手法,但是却因为拓宽了视野,开辟了思路,为人们所津津乐道,以至于代代相传,前赴后继。

在普罗大众悉心关注,甚至信息安全问题上升到了我们国家战略的今天,黑客精神存在很多误读和沦陷,不过所有“精神”类型的意识形态似乎都免不了如此。近几十年来,信息技术给世界带来了太多的变化,也让人们对未来的生活产生更多的想象。IT技术的更新变化尤其快,每隔一段时间,就会有新的技术被提出和使用,世界上似乎从来不缺优秀的程序员。硬件、内核、驱动、应用程序、虚拟化、Web,每一层都在IT的世界肩负着重要的一环,都需要最高明的工匠持之以恒的去维护,去打磨,安全问题自然也层出不穷。因此黑客这行当,也演变出了各个方向,有硬件黑客或者极客,有挖掘内核漏洞的黑客,有应用层玩的很好的,有精通网络协议的,也有容易入门所以玩家最多的web黑客。种种技术,各个流派,谁能分出个高下?哪里又是真正的巅峰?内核黑客手握0day,千里之外夺人系统,web黑客坐拥亿万数据,分分钟查出你的名姓,找到你的隐私!技术的世界如此奇妙,那么多人在玩这个游戏,那么多工匠在发明和创造。这个变化的世界,甚至没有任何容你喘息的机会。这也是个危险的世界,身不由己的事情太多,高处亦不胜寒。所以最后看到,很多人选择了蛰伏,选择在技术的世界里遨游或是沉沦,在自己的角落里偏安一隅,也是幸事,不亦乐乎?

近些年不管是国内还是国外,各种各样的新技术被提出,被放大。商业的东西,这里不想讨论,但是有些东西扒开来看,大家心里都是明白的。和平年代,坐在格子间里办公的人们,不愁吃喝,却总不能闲着。其实这也不只是在安全行业,任何一个行业都是这样。社会要发展,经济要运转,该花的钱要花,该演的戏要演。也总得有人做实事,有人走过场。只是每每想到这些,我就更加佩服那些让人尊敬的前辈,那些引领技术的牛人。
倒过来看我写的文字,连我自己都会觉得有些中庸。没有批判,没有宣泄,没有叙事,也没有解读。只有轻描淡写的看法,流水帐一样的记录。我深知某些时候,某些事物,我们只有欣赏权,没有发言权。
最后想说,圈子还是那个圈子,人还是那些人,事情也仍是那些事情。黑客的圈子不大,却也算是个江湖。江湖有道义,黑客有精神。

Chorder
2016/09/25

本次的编程环境: CentOS 6.8
Linux centos 2.6.32-573.8.1.el6.x86_64

在内核的源代码中定义了很多进程和进程调度相关的内容。其实Linux内核中所有关于进程的表示全都放在“进程描述符”这个庞大的结构体当中,关于这个结构体的内容和定义,可以在内核的linux/sched.h文件中找到。
现在就来通过编程实现对进程描述符的操作,主要是读取。至于修改等操作,将在后面的内容中提到。
通过对进程描述符的读取,可以获取进程的一切内容,包括进程的ID,进程的地址空间等等。

不多说,上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//20160912
//currentptr.c

#include <linux/tty.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/module.h>

/*Function To Write Msg To TTY*/
void tty_write_message(struct tty_struct *tty,char *msg){
if(tty && tty->ops->write){
tty->ops->write(tty,msg,strlen(msg));
}
return;
}

static int my_init(void){
char *msg="Hello tty!\n";
tty_write_message(current->signal->tty,msg);
printk("Hello -- from the kernel...\n");
printk("Parent pid: %d(%s)\n",current->parent->pid,current->parent->comm);
printk("Current pid: %d(%s)\n",current->pid,current->comm);
printk("Current fs: %d\n",current->fs);
printk("Current mm: %d\n",current->mm);
return 0;
}

static void my_cleanup(void){
printk("Goodbye -- from the kernel...\n");
}

module_init(my_init);
module_exit(my_cleanup);

以上的代码,主要就是通过引入内核头文件,进而引用进程描述符中的指针,并通过这种方式获取当前进程和相关进程的描述信息。
Makefile文件如下:

1
2
#Makefile
obj-m += currentptr.o

编译的指令:

1
make -C /usr/src/linux SUBDIRS=$PWD modules

然后通过insmod把模块装载进内核,首先tty输出了Hello tty!
同时在/var/log/message中,模块打印出了这些内容:

1
2
3
4
5
Sep 12 10:35:36 centos kernel: Hello -- from the kernel...
Sep 12 10:35:36 centos kernel: Parent pid: 2235(bash)
Sep 12 10:35:36 centos kernel: Current pid: 13197(insmod)
Sep 12 10:35:36 centos kernel: Current fs: 927961856
Sep 12 10:35:36 centos kernel: Current mm: 932613056

分别是这个进程的相关信息。
对于进程描述符的定义,在本次实验用来编译的内核源码包(kernel-devel-2.6.32-642.4.2.el6.x86_64)中,
进程描述符具体定义在include/linux/sched.h的1326行往后。

需要参考的进程具体信息都在其中,可随时参考,以备不时之需。

Linux内核编程一直是我很想掌握的一个技能。如果问我为什么,我也说不上来。
也许是希望有一天自己的ID也出现在内核开发组的邮件列表里?或是内核发行文件的CREDITS文件上?
也许是吧。其实更多的,可能是对于底层的崇拜,以及对于内核的求索精神。
想到操作系统的繁杂,想到软件系统之间的衔接,内心觉得精妙的同时,更是深深的迷恋。
所以从这篇文章开始,我要真正的走进Linux内核里了,让代码指引我,去奇妙的世界一探究竟。

在这篇文章中,一起来对内核说Hello World。
本次的编程环境:
CentOS 6.8

Linux centos 2.6.32-573.8.1.el6.x86_64

没有安装内核的,可能需要安装一下内核源码包
kernel-devel-2.6.32-642.4.2.el6.x86_64

1
yum install kernel-devel-2.6.32-642.4.2.el6.x86_64

安装好之后,这个版本内核可以在/usr/src/linux找到。

然后先话不多说,首先看代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//20160904
//kernel_hello_world.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int __init lkp_init(void){
printk("Hello,World! --from the kernel space...\n");
return 0;
}

static void __exit lkp_cleanup(void){
printk("Goodbye,World! --leaving kernel space...");
}

module_init(lkp_init);
module_exit(lkp_cleanup);

以上代码是kernel_hello_world.c内容。
作为内核模块,在编译的时候,Makefile文件这样写:

1
2
#File:Makefile
obj-m += kernel_hello_world.o

然后可以通过这条命令来编译:

1
make -C /usr/src/linux SUBDIRS=$PWD modules

编译好以后,目录下面的文件可能是这样子:

1
2
3
kernel_hello_world.ko.unsigned  kernel_hello_world.o  Module.symvers
kernel_hello_world.c kernel_hello_world.mod.c Makefile
kernel_hello_world.ko kernel_hello_world.mod.o modules.order

有这么多文件被生成,其中kernel_hello_world.ko就是本次编译出来的内核模块文件,在Linux内核中有很多这样的模块,它们可能充当着不同的角色,可能是驱动,也可能是各种设备。
这个模块会在/var/log/message文件中打印一行字,即Hello,World! --from the kernel space...
可以使用insmod kernel_hello_world.ko来将这个模块载入到内核。
使用lsmod来查看是否已经加载。
使用rmmod kernel_hello_world.ko来卸载这个模块。
可以tail /var/log/message来看一下是否成功执行了呢?

Hello,Kernel.

VmWare默认的镜像格式是.vmdk格式的,VirtualBox则默认是.vdi格式的。其实这在VirtualBox新建虚拟机的过程中是可选的。

导入.vmdk格式的镜像到VirtualBox只需要新建一个虚拟机,并且不创建虚拟硬盘。如下图:

无视警告,继续:

创建好之后,在设置里面把.vmdk格式的虚拟硬盘添加进去:

这样就可以了。

如果遇到windows虚拟机起不开的情况,尝试更改下下面这个选项:
启用下I/O APIC试试。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×