Archives

很喜欢三月

大概是在西安待久了吧,居然忘了一年之中的三月还有这么好的天气。

西安的天气实在不敢恭维,在西安你几乎感觉不到春天来了就到夏天了。一个同学说“西安过了冬天就是夏天”,我很认同。

现在在家,无论白天还是晚上出去,总能感觉到春风拂面,吹过脸庞的风不冷不热,很舒服,而且恰到好处。白天,阳光温和,照进我的房间,有一种暖暖的感觉。夜晚宁静惬意,站在阳台上望去,有一种温馨的感觉。

今天吃晚饭时又恰好下了点儿小雨,更是增添了一份春的气息。

古人讲“烟花三月下扬州”。看来这三月自古就是招人喜爱啊!虽不能“下扬州”,可我却能慢慢品味这“烟花三月”的味道。

SUID, SGID and sticky bit

stick bit以前表示要把这个可执行文件放到swap分区中来加快执行速度,现在这个显然用不着了,因为Linux/Unix的vm子系统会自动完成这种功能。为了“变废为宝”,这个sticky bit并没有被遗弃,现在它的功能是这样的:对于一个目录,如果它被设置了sticky bit,那么它里面的文件只能被文件所有者,目录所有者,或特权用户删除。最好的一个例子是/tmp目录,在Fedora上它的权限是:

$ ls -ld /tmp/
drwxrwxrwt 50 root root 20480 03-09 21:08 /tmp/
$ test -k /tmp
$ echo $?
0

我们可以看到最后一个x变成了t。而如果目录或者文件不具有x权限,那么t就会变成T,比如:

$ touch foo.txt
$ chmod +t foo.txt
$ ls -l foo.txt
-rw-rw-r-T 1 wangcong wangcong 0 03-09 23:53 foo.txt

suid和sgid类似,它们的符号是s或者S而不是t。suid的含义是让可执行文件执行时具有owner的权限,sgid的含义是让其具有owner所在group的权限。例如:

$ ls -l /bin/ping
-rwsr-xr-x 1 root root 41748 2007-04-06 /bin/ping

如果你用ls -l看,你会发现suid的s是在owner权限一组,sgid的s是在group权限一组。

sgid用到目录上的含义是:里面的新文件或者子目录会继承这个group id。而在Linux上,suid用在目录上是被忽略的。

参考资料:
1. http://www.zzee.com/solutions/linux-permissions.shtml#setuid
2. http://www.unixguide.net/hp/faq/5.1.9.shtml.
3. http://en.wikipedia.org/wiki/Sticky_bit
4. http://en.wikipedia.org/wiki/Setuid

为啥俺没女朋友?

今天和两个同学出去闲聊了一下午,那俩女人没别的,就会八卦,先把以前班里的同学全部八卦一遍,然后又八卦那些明星。最后,还不忘问我一个具有杀伤力的问题,你咋还没女朋友呢?我说:哎,别提了,俺们学校的女生@!#%&**&…(省略N个字)

其实仔细想想,那最多只是个客观原因,深层的原因究竟是啥呢?这是一个重大的问题。辗转反侧,深思良久,我觉得根本原因有这么几点:

1. 美女们喜欢帅哥,而我不是。

2. 美女们多数都学文科,而我不光学理而且学的是美女狠少的计算机专业。

3. 美女们90%以上的都使用QQ和Qzone,而我基本不用。

4. 还有一些美女(也)使用MSN,而我没有。

5. 上学的美女一般还喜欢上校内,而我不上。

6. 美女们99%的都用Windows,而我讨厌。

7. 美女们偶尔也会上上bbs,而我连这个都很少用,因为我喜欢usenet和mailing list。

8. 美女们要么不看书,要么看的书我多看不懂,而我看的书美女们都看不懂!

9. 追美女要经常送礼物,而我是穷书生一个。

10. 美女喜欢让你陪着逛街买东西,而我对此深恶痛绝。

11. 美女上网多是娱乐,偶尔玩玩,而我不光不娱乐,还一天24小时我12个小时都在线。

综上所述,我发现“改过自新”的希望很小,只能等着哪天天上掉下一个傻妞,傻儿叭叽地就愿意做我这么个geek的女朋友。

我抬头仰面45度……

Linux下的反调试技术

作者:西邮 王聪

如何防止自己的程序被调试器跟踪,这是一个很有趣的话题,也是反逆向工程中的一个重要话题。这里简单介绍一下Linux平台上的反调试技术。

(本文主要参考:http://blog.txipinet.com/2006/10/05/37-tecnicas-anti-debugging-sencillas-para-gnu-linux/
做人要厚道,转载请指明出处!

一. int3指令

Intel Software Developer’s Manual Volume 2A中提到:

The INT 3 instruction generates a special one byte opcode (CC) that is intended for
calling the debug exception handler. (This one byte form is valuable because it can be
used to replace the first byte of any instruction with a breakpoint, including other one
byte instructions, without over-writing other code).

int3是一个特殊的中断指令(从名字上也看得出来),专门用来给调试器使用。这时,我们应该很容易想到,要反调试,只要插入int3来迷惑调试器即可。不过,这会不会影响正常的程序?会!因为int3会在用户空间产生SIGTRAP。没关系,我们只要忽略这个信号就可以了。

include

include

void handler(int signo)
{}

int main(void)
{
signal(SIGTRAP, handler);
asm(“nopnt”
“int3nt”);
printf(“Hello from main!n”);
return 0;
}

二. 文件描述符

这是一个很巧妙的办法,不过它只对gdb之类的调试器有效。方法如下:

include

include

include

int main(void)
{
if(close(3) == -1) {
printf(“OKn”);
} else {
printf(“traced!n”);
exit(-1);
}
return 0;
}

gdb要调试这个程序时会打开一个额外的文件描述符来读这个可执行文件,而这个程序正是利用了这个“弱点”。当然,你应该能猜到,这个技巧对strace是无效的。

三. 利用getppid

和上面一个手法类似,不过这个更高明,它利用getppid来进行探测。我们知道,在Linux上要跟踪一个程序,必须是它的父进程才能做到,因此,如果一个程序的父进程不是意料之中的bash等(而是gdb,strace之类的),那就说明它被跟踪了。程序代码如下:

include

include

include

include

include

include

include

int get_name_by_pid(pid_t pid, char* name)
{
int fd;
char buf[1024] = {0};
snprintf(buf, 1024, “/proc/%d/cmdline”, pid);
if ((fd = open(buf, O_RDONLY)) == -1)
return -1;
read(fd, buf, 1024);
strncpy(name, buf, 1023);
return 0;
}

int main(void)
{
char name[1024];
pid_t ppid = getppid();
printf(“getppid: %dn”, ppid);

    if (get_name_by_pid(ppid, name))
    return -1;
if (strcmp(name, "bash") == 0 ||
    strcmp(name, "init") == 0)
        printf("OK!n");
else if (strcmp(name, "gdb") == 0 ||
    strcmp(name, "strace") == 0 ||
    strcmp(name, "ltrace") == 0)
    printf("Traced!n");
else
    printf("Unknown! Maybe traced!n");

return 0;

}

同样的手法,一个更简单的方式是利用session id。我们知道,不论被跟踪与否,session id是不变的,而ppid会变!下面的程序就利用了这一点。

include

include

include

int main(void)
{
printf(“getsid: %dn”, getsid(getpid()));
printf(“getppid: %dn”, getppid());

    if (getsid(getpid()) != getppid()) {
    printf("traced!n");
    exit(EXIT_FAILURE);
}
    printf("OKn");

return 0;

}

四. 利用环境变量

bash有一个环境变量叫$_,它保存的是上一个执行的命令的最后一个参数。如果在被跟踪的状态下,这个变量的值是会发生变化的(为什么?)。下面列出了几种情况:


argv[0] getenv(“_”)
shell ./test ./test
strace ./test /usr/bin/strace
ltrace ./test /usr/bin/ltrace
gdb /home/user/test (NULL)

所以我们也可以据此来判断。

include

include

include

int main( int argc, char *argv[])
{
printf(“getenv(): %sn”, getenv(““));
printf(“argv[0]: %sn”, argv[0]);

if(strcmp(argv[0], (char *)getenv("_"))) {
    printf("traced!n");
    exit(-1);
}

printf("OKn");
    return 0;

}

五. 利用ptrace

很简单,如果被跟踪了还再调用ptrace(PTRACE_TRACEME…)自然会不成功。

include

include

int main(void)
{
if ( ptrace(PTRACE_TRACEME, 0, 1, 0) < 0 ) {
printf("traced!n");
return 1;
}
printf("OKn");
return 0;
}

Happy hacking!

《老无所依》

不错的一部电影。和普通的电影不一样,在这个电影里,恶最终没有恶报,杀人狂最后依旧是逍遥法外,与杀人狂周旋的牛仔最后却死了,不过不是死到他手里。老警长对一切都力不从心,正如电影的名字所示……

还可以这样利用x86的堆栈

原来还能这样“践踏”x86的堆栈,利用push后直接ret,很简单很直接!以前都是利用缓冲区溢出去覆盖~

我写的用户空间的一段示例代码(注:执行时的段错误是意料之中的):

include

void hello(void)
{
printf(“hello world!n”);
}

void pushcall(void *call)
{
asm _volatile
(“pushl %%eaxnt”
“ret”
::”a” (call)
);
}

int main(void)
{
push_call(&hello);
return 0;
}

git使用小结

1. git-config

配置git,一般需要配置的是user.name,user.email,有时sendemail.smtpserver也要配置,比如,我使用msmtp:

git-config —global sendemail.smtpserver /usr/local/bin/msmtp

如果你仅仅是想给这一个项目配置,把—global选项去掉。查看配置的选项是—list。

  1. git-pull

git-pull没必要带后面那长长的url(-_-b 我那么用了好多次,不过我用的是!git-pull)。如果你在给Linux内核这样的项目工作,记得git-pull之前检查是不是在master分支。

3. git-format-patch

如果发送多于一个补丁,最好用[PATCH n/m]的形式,加上-n。加signed-off-by那行是-s。指定为几次commit生成补丁,直接加数字,比如,

$ git-format-patch -3

检查补丁是—check,最好加上这个。

4. git-send-email

如果一次提交补丁比较多,最好用—no-chain-reply-to,因为如果不用的话,在thread嵌套会太深,不利于别人阅读。这个也可以通过选项sendemail.chainreplyto来控制。—signed-off-by-cc,要加上,可以省去手工处理的麻烦。—compose用来编辑[PATCH 0/m],这个一般是对整个patchset的描述。—smtp-server,如果你不想用git-config指定的话,用它也行。—cc和—to就不用说了。

5. git-commit

在git-commit之前最好git-add。git-commit几个常用的选项有:-s 会增加Signed-off-by行,-e编辑commit message,-a表示all,-m是指定commit信息。同样,删除文件是先git-rm。查看commit列表用git-rev-list,查看某个commit用git-show,查看commit的日志用git-log,-p是以补丁的形式查看。

6. 其它

git-diff也可以比较不同版本之间的差异,某个版本的某个文件的差异,如:

$ git-diff v2.6.22
$ git diff v2.6.20 init/main.c
$ git-diff v2.6.23 v2.6.24-rc1 init/main.c

git-whatchanged也差不多:

$ git-whatchanged -p init/main.c

7.错误提交了commit怎么办?

a) git-revert

这个本身就会产生一个commit,如果用得多了会让你的log看起来不那么干净。;-)

b) git-reset

用这个要当心,它会把那个commit之后的commit全部删除。一个好的办法是:先建立一个临时的分支,然后再git-reset,再git-rebase,最后再删除临时的分支。 详细可以看这里

Programming Competitions are Considered Harmful

今天在reddit上看到关于编程竞赛的讨论,有个人的观点很有意思,他(她)认为:

Programming is like music, as soon as you compete with others, you lose everything.
仔细想想这句话其实很对。我心目中供奉的那些大牛们,像Linus TorvaldsRichard StallmanBill JoyDonald KnuthDennis RitchieKen ThompsonRob Pike等等,没一个是因为什么编程比赛而出名,甚至都没听说过有一个曾参加过什么国际编程竞赛。Knuth参加过一个编程比赛,我承认,但那是人家CalTech自家的比赛。

不像我们天朝,为了参加某编程比赛争得头破血流,每年都乐不疲此。一年又一年,天朝拿到的金银铜铁牌已经无数了,可是怏怏大国到现在还没有一个图灵奖得主!噢,别提这个,有人会不满意,比如公子同学。反正我们近几十年内是没希望拿上,提也没用。

那天朝为什么至今仍没有自己的CPU和操作系统呢?喔,我说错了,我们有龙芯!不过这正好印证了我的观点。想一想,我们至今没有自己的操作系统,却有了自己的CPU,这又是为什么呢?那是因为ASIC领域没有类似ACM,*OI这样的比赛!

我不否认参加编程比赛的也有高手,但是如果为了比赛而去编程,那还有什么意思呢?现实中有很多很多问题需要解决,何必放此不管而解决那些人为制造的玩具问题呢?

给emacs安装color-theme

决定给emacs换个主题,因为默认的这个主题比较丑。

简单搜索了一下,需要安装color-theme这个package。从这里下载:

http://download.gna.org/color-theme/

下载解压缩后,需要

1) 把color-theme.el拷贝到某个load-path中,比如我的是~/.emacs.d

2) 把themes目录也要拷贝到上面的路径中

3) 在~/.emacs里添加下面几行:

(require ‘color-theme)
(color-theme-initialize)
(color-theme-oswald)

注意:网上的很多教程并没提到第2行,但是它必须有,否则会出错。
最起码在我这里如此。

第3行是我自己选择的一个主题,你可以换成你自己喜欢的,浏览里面
的主题可以用M-x color-theme-select,然后一个个地试,觉得哪个好
就把第三行替换成那个。

最后,如果你有其它主题,把它下载到themes目录里,然后再修改
~/.emacs:

(load-file “~/.emacs.d/themes/your-own-theme.el”)
(color-theme-your-own)

这样emacs看起来就很漂亮。

BTW,这里有一款为mm准备的粉红主题,很炫。不知道有没有mm使用emacs?

在emacs里写blog

搜了好大一会儿才找到emacs的这个写博客的插件——weblogger,配置很简单。
不过下载要直接从CVS上取,用如下命令:

cd ~/.emacs.d/
cvs -z3 -d:pserver:anonymous@cvs.savannah.nongnu.org:/sources/emacsweblogs
co -d weblogger weblogger/lisp

然后编辑~/.emacs:

(add-to-list ‘load-path “~/.emacs.d/weblogger”)
(require ‘weblogger)

配置博客:

M-x weblogger-setup-weblog

写博客:

M-x weblogger-start-entry

发表博客:

M-x weblogger-save-entry

保存博客:

M-x weblogger-send-entry
更多的其它命令可以查看weblogger的帮助。

这是第一篇在emacs里写的文章,作个实验。;-)

Update:这里有一个更新版本,用wordpress的同学最好使用这个。