中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
Jicama下的signal编程
作者:未知 时间:2005-07-27 23:32 出处:CSDN 责编:chinaitpower
              摘要:Jicama下的signal编程

signal是UNIX下最常用的一种通信机制,程序对不同的信号安装处理处理函数,JICAMA支持32个信号,目前还没有平台专用的信号,基本上可以与传统的UNIX兼容。
这是最简单的一个SIGNAL的编程例子,原先的程序来自MINIX:

/* sleep - suspend a process for x sec  Author: Andy Tanenbaum */
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void sigalrm(int signo)
{
 int *ret;
 *ret=(int *)&ret+2;
 printf("receive alarm, signo=%d, ret 0x%x\n", signo,*ret);
}

int main(argc, argv)
int argc;
char *argv[];
{
  register seconds;
  register char c;

  seconds = 0;

  if (argc != 2) {
 printf("Usage: sleep time\n");
 exit(1);
  }
  while (c = *(argv[1])++) {
 if (c < '0' || c > '9') {
  printf("sleep: bad arg\n");
  exit(1);
 }
 seconds = 10 * seconds + (c - '0');
  }

  /* Now sleep. */
  signal(SIGALRM, sigalrm);
  alarm(seconds);
  pause();
  return(0);
}
这个程序的目的是让程序睡眠seconds秒,然后唤醒,继续运行。在用户接口上,JICAMA和MINIX完全一致,这是为了保障程序的兼容性,下面分析下其中的实现吧,

signal函数原代码:
__sighandler_t signal(int sig, __sighandler_t func)
{
 __sighandler_t res;
 __asm__("int $0x80":"=a" (res):
 "0" (NR_SIGNAL),"b" (sig),"c" ((long)func),"d" ((long)&asm_sig_restore));
 return res;
}
__sighandler_t是一个函数指针,原形被定义如下:
typedef void (*__sighandler_t) (int);
signal的目的是为了注册一个信号处理,返回先前该信号的处理句柄,他只有2个参数,sig是要注册的信号,func是当信号发生的情况下执行的函数。
然后alarm设置一个闹钟,注意如果没有signal(SIGALRM, sigalrm);这行代码的话闹钟将会是程序自动退出。pause()将目前的进程挂起,并调度,其他进程运行。
seconds之后,程序得到恢复,进程被标上SIGALRM信号,这时候查找相应的执行函数,如果SIGALRM已经被注册了,则执行注册的程序,在程序开始执行的时候,堆栈构造如下:
esp=_asm_sig_restore
esp+4=信号(signo)
esp+8=保留(???)
esp+12=mask(sigmask)
esp+16=原先的寄存器内容(regs)
他的参数是保存在esp+4,自然是signo,函数执行过后还需要继续往后面的程序运行这个就是恢复函数,否则极有可能抛出一个异常,终止程序运行,恢复内定是由asm_sig_restore来完成的,这是一段汇编代码,它是用NASM写的:
_asm_sig_restore:
 add esp,8
 mov ebx, [esp+4]
 mov ecx, [esp]
 mov eax, 75
 int 0x80
 ret
首先把signo和???里面的内容丢弃,这时候esp的内容指向mask,把mask的内容保存在ecx,把原先寄存器的内容保存在ebx,用于过后的恢复,然后进入内核,内核把其中的寄存器恢复,这样可以继续往后面运行,呵呵,顺便说一句,黑客们完全可以利用_asm_sig_restore的原理来制造病毒程序。


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有