分类目录归档:不是技术

标准C库函数

C-1 标准输出输入函数

C -2 字元检查函数

C -3 字串函数

C -4 数学函数

C -5 日期/时间函数

C -6 工具函数

 

C-1 标准输出输入函数

FILE* fopen(const char* filename, const char* mode):使用mode模式开启参数filename的档案,传回档案串流,失败传回NULL.

FILE* freopen(const char* filename, const char* mode, FILE* stream):关闭档案后重新开启档案.

int fflush(FILE* stream):清除缓冲区的内容,成功传回0,失败传回EOF.

int fclose(FILE* stream):关闭档案.

int remove(const char* filename):删除参数的档案,失败传回非零值.

int rename(const char* oldname, const char* newname):将档案名称oldname改为newname,失败传回非零值.

FILE* tmpfile():建立

wb+

模式的暂存档案,当结束程式后就会关闭且删除此档案.

char* tmpname(char s[L_tmpnam]):指定暂存档案的名称为s.

int setvbuf(FILE* stream, char* buf, int mode, size_t size):指定串流暂存区尺寸size,使用mode参数值_IOFBF为完整暂存区,_IOLBF是线性暂存区或_IONBF没有暂存区.

void setbuf(FILE* stream, char* buf):指定串流的暂存区为参数buf.

int fprintf(FILE* stream, const char* format, …):将格式化字串写入档案串流.

int printf(const char* format, …):在标准输出显示格式化字串.

int sprintf(char* s, const char* format, …):将格式化字串输出到字串s.

int fscanf(FILE* stream, const char* format, …):从档案串流读取指定格式的资料.

int scanf(const char* format, …):从标准输入读取指定格式的资料.

int sscanf(char* s, const char* format, …):从字串s读取指定格式的资料.

int fgetc(FILE* stream):从档案串流读取一个字元.

char* fgets(char* s, int n, FILE* stream):从档案串流读取一个字串.

int fputc(int c, FILE* stream):写入一个字元到档案.

char* fputs(const char* s, FILE* stream):写入一个字串到档案.

int getc(FILE* stream):从档案串流读取一个字元.

int getchar(void):从标准输入读取一个字元.

char* gets(char* s):从标准输入读取一个字串.

int putc(int c, FILE* stream):写入一个字元到档案.

int putchar(int c):在标准输出显示一个字元.

int puts(const char* s):在标准输出显示一个字串.

int ungetc(int c, FILE* stream):将一个字元放回档案串流.

size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream):从档案读取指定大小的资料.

size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream):将指定大小的资料写入档案.

int fseek(FILE* stream, long offset, int origin):移动档案指标到offset位移量,其方向是origin参数值SEEK_SET的档案开头,SEEK_CUR是目前位置或SEEK_END档尾.

long ftell(FILE* stream):目前档案指标的位置.

void rewind(FILE* stream):重设档案指标到档头.

int feof(FILE* stream):是否到达档尾.

int ferror(FILE* stream):是否档案串流产生错误.

C-2 字元检查函数

int isalnum(int c):isalpha(c)或isdigit(c)的字元.

int isalpha(int c):isupper(c)或islower(c)的字元.

int iscntrl(int c):是否是ASCII控制字元.

int isdigit(int c):是否是数字.

int isgraph(int c):是否是显示字元,不含空白字元.

int islower(int c):是否是小写字元.

int isprint(int c):是否是显示字元0x20 (‘ ‘)到0x7E (‘~’).

int ispunct(int c):是否是显示字元,不包含空白,字母,数字字元.

int isspace(int c):是否是空白字元.

int isupper(int c):是否是大写字元.

int isxdigit(int c):是否是十六进位字元.

int tolower(int c):转换成小写字元.

int toupper(int c):转换成大写字元.

C-3 字串函数

char* strcpy(char* s, const char* ct):将字串ct复制到字串s.(String Copy)

char* strncpy(char* s, const char* ct, size_t n):将字串ct前n个字元复制到字串s.

char* strcat(char* s, const char* ct):连结字串ct到字串s之后.(String Catanation)

char* strncat(char* s, const char* ct, size_t n):连结字串ct前n个字元到字串s.

int strcmp(const char* cs, const char* ct):比较字串cs和ct.

int strncmp(const char* cs, const char* ct, size_t n):比较字串cs和ct的前n个字元.

char* strchr(const char* cs, int c):传回字元c第一次出现在字串cs位置的指标.

char* strrchr(const char* cs, int c):传回字元c第后一次出现在字串cs位置的指标.

char* strpbrk(const char* cs, const char* ct):传回字串ct任何字元在字串cs第一次出现的位置指标.

char* strstr(const char* cs, const char* ct):传回字串ct在字串cs第一次出现的位置指标.

size_t strlen(const char* cs):传回字串cs的长度.

char* strerror(int n):传回指定错误代码的说明文字内容.

char* strtok(char* s, const char* t):以字串t的任何字元为分隔字元,找寻字串s中下一个token记号.

void* memcpy(void* s, const void* ct, size_t n):从位置ct复制n个字元到位置s,传回s.

void* memmove(void* s, const void* ct, size_t n):从位置ct搬移n个字元到位置s,传回s.

int memcmp(const void* cs, const void* ct, size_t n):比较位置ct和位置cs的前n个字元.

void* memchr(const void* cs, int c, size_t n):传回cs位置开始前n个字元第一次出现字元c的位置指标.

void* memset(void* s, int c, size_t n):取代cs位置开始前n个字元成为字元c,传回位置指标s.

C-4 数学函数

double exp(double x):自然数的指数e^x.

double log(double x):自然对数logx

double log10(double x):十为底的对数log10x.

double pow(double x, double y):传回参数x为底,参数y的次方值x^y.

double sqrt(double x):参数x的平方根.

double ceil(double x):传回大於或等於参数x的最小double整数.

double floor(double x):传回小於或等於参数x的最大double整数.

double fabs(double x):传回参数x的绝对值.

hypot(double x, double y):传回√(x^2+y^2)公式的值

double ldexp(double x, int n):x乘以2的n次方是x*2^n.

double frexp(double x, int* exp):将参数x的浮点数分解成尾数和指标,x = m*2^exp,传回m值的尾数,将指数存入参数exp.

double modf(double x, double* ip):将浮点数x分解成整数和小数部分,传回小数部分,将整数部分存入参数ip.

double fmod(double x, double y):如果y为非零值,传回浮点数x/y的余数.

double sin(double x):正弦函数.

double cos(double x):余弦函数.

double tan(double x):正切函数.

double asin(double x):反正弦函数.

double acos(double x):反余弦函数.

double atan(double x):反正切函数.

double atan2(double y, double x):参数y/x的反正切函数值.

double sinh(double x):hyperbolic正弦函数,sinh(x)=(e^x-e^(-x))/2.

double cosh(double x):hyperbolic余弦函数,cosh(x)=(e^x+e^(-x))/2.

double tanh(double x):hyperbolic正切函数,tanh(x)=(e^x-e^(-x))/(e^2+e^(-x)).

C-5 日期/时间函数

clock_t clock(void):传回程式开始执行后所使用的CPU时间,以ticks为单位,除以常数CLK_TCK就是秒数.

time_t time(time_t* tp):传回目前的历法时间(Calendar Time),也会指定给参数的tp指标,如为无效时间,传回-1.

double difftime(time_t time2, time_t time1):传回参数time2和time1的时间差,即time2-time1.

time_t mktime(struct tm* tp):将参数*tp的当地时间改为历法时间, 如果不能转换传回-1.

char* asctime(const struct tm* tp):传回参数tm结构指标转换成日期/时间格式的字串,字串最后有新行字元\n.

char* ctime(const time_t* tp):传回参数time_t指标转换成当地日期/时间的字串,字串最后有新行字元\n.

struct tm* gmtime(const time_t* tp):传回将参数的time_t指标转换成UTC(Coordinated Universal Time)日期/时间的tm结构指标.

struct tm* localtime(const time_t* tp):传回将参数的time_t指标转换成当地日期/时间的tm结构指标.

size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp):将参数tp的日期/时间以格式化字串fmt输出到字串s,s最多储存smax个字元.

C-6 工具函数

int abs(int n),long labs(long n):传回整数n的绝对值.

double atof(const char* s):将参数字串s转换成浮点数,如果字串不能转换传回0.0.

int atoi(const char* s):将参数字串s转换成整数,如果字串不能转换传回0.(Char to integer)

int itoa():将整数转换成参数字串s.(Integer to Char)

long atol(const char* s):将参数字串s转换成长整数,如果字串不能转换传回0.

double strtod(const char* s, char** endp):函数忽略字串s前的空白字元,将数字部分转换成浮点数,如果尚有未转换的部分字串,则设成参数endp指标.

long strtol(const char* s, char** endp, int base):函数忽略字串s前的空白字元,将数字部分转换成长整数,如果尚有未转换的部分字串,则设成参数endp指标.

unsigned long strtoul(const char* s, char** endp, int base):如同strtol函数,其传回值是无符号长整数.

void* calloc(size_t nobj, size_t size):传回一块参数nobj阵列大小的记忆体指标,nobj元素大小为size初值为0,错误传回NULL.

void* malloc(size_t size):传回大小size记忆体指标,没有指定初值,错误传回NULL.

void* realloc(void* p, size_t size):将指标p的记忆体改为size大小,不会更改原记忆体的值,多配置部分初值为0,错误传回NULL.

void free(void* p):释放参数p指标的记忆体空间.

void abort():强迫程式以不正常方式结束,如同呼叫raise(SIGABRT)函数.

void exit(int status):程式以正常方式结束,传回系统环境状态值,0表示正常结束.

int system(const char* s):将字串s的指令传给环境来执行,也就是执行MS-DOS的指令.

char* getenv(const char* name):传回参数name的环境字串,如果没有传回NULL.

void* bsearch(const void* key, const void* base, size_t n, size_t size, int (*cmp)(const void* keyval, const void* datum)):阵列基础的二元搜寻函数,阵列是参数base,键值是参数key,n是阵列大小,size是每个元素的大小,最后的参数是指向函数的指标,这是比较元素大小的函数,找到传回该元素指标,没有找到传回NULL.

void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*)):阵列基础的快速排序法函数,阵列是参数base,n是阵列大小,size是每个元素的大小,最后的参数是指向函数的指标,这是比较元素大小的函数.

int rand(void):传回乱数的整数值,其值的范围是0到RAND_MAX常数,其值为0x7FFF.

void srand(unsigned int seed):指定乱数的种子数,参数是无符号整数,如果没有指定,预设的种子数为1.

jabberd2

Ubuntu下的jabberd2很全,钱果然不是盖的,很丰富的可安装的资源。

我发现居然不用下源代码编译直接就能用,真有点不敢相信,不过代码还是要改的……

估计Ubuntu的也只能装来玩玩

Jabberd

上周在redhat上装的Jabberd2。

因为有半年没有编译过程序了,这两个月来我一直在

pjoke

上写php或者actionscript。突然转回Linux编译项目有点反应不过来了。

不过还算顺利。

Jbd2的数据库和验证用的是默认的MySQL,安装这个好烦,我觉得目前好多的所谓安装过程写得都不理想,没有从根本上让你理解linux上安装的概念。各种功能的文件放置在什么路径下,还有各种参数是什么意思。不过总算搞定了,赫赫。

然后把jbd2 configure了,再make, make install。在windows上跑了个gaim,一切正常。

今天开始VMWare+Ubuntu+Jabberd2,看看容易装不。

临界星座速查表

http://pjoke.com/astro/checkastro.php

1950年到1999年的星座速查,精确到分。

根据一个流行的表做的,我浏览了这个表一下,星座的分界跟太阳历不尽相同,大概是用恒星历?

搞不清楚这个差别,不过我还是忠于这个表格作了。

最俗的名字

在样本总量400K的姓名里统计了一下:

单名最俗的十个字

| 萍   |   980 |

| 芳   |   985 |

| 涛   |  1045 |

| 丽   |  1060 |

| 静   |  1321 |

| 斌   |  1327 |

| 军   |  1430 |

| 勇   |  1583 |

| 伟   |  1650 |

| 敏   |  1764 |

双名最俗的前一个字(10个)

| 海   |  4279 |

| 永   |  4464 |

| 丽   |  4716 |

| 玉   |  5087 |

| 国   |  5367 |

| 志   |  6768 |

| 文   |  7107 |

| 晓   |  7407 |

| 小   |  7553 |

| 建   |  7637 |

双名最俗的后一个字(10个)

| 红   |  3606 |

| 玲   |  3863 |

| 芳   |  3921 |

| 萍   |  4039 |

| 林   |  4366 |

| 军   |  4473 |

| 英   |  5808 |

| 明   |  6380 |

| 平   |  7686 |

| 华   | 10467 |

深圳的维修水平

感觉上深圳的维修水平是很高的。

周日一个朋友的台式机坏掉了,开不了机,连蜂鸣都没有。硕泰克的主板,三四年了,电容掉得7788,以我的经验,还是报废了算,不过主人是个女生,最后还是选择去华强北找个电脑医院。有专用仪器对内存,CPU等检测过了,报下价来,100元只修主板。

周二我去取机之前,顺道把我妈的坏手机拿过去通天地,因为有个朋友在那里开了家手机维修店,于是呆了一会。一个4年修手机经验的师傅带了7、8个小工在那里干活。效率很高,基本上2分钟内就可以知道手机坏在什么地方了,由于华强北本身就是手机零件的集散地,因此换IC,换屏幕或者换其他的东西都很方便。价格一般是60元,搞定再收钱。

在旁边看了一下焊接水平,焊工很好,一拖下来,一气呵成。

之后去取电脑,主板上的电容都换过了,开机试了一下,也很顺利。

华强北的这些摊位租金都不菲,我朋友他们家租了两个摊位,加起来20平米的地方,加上小工的工资食宿,每天要700才能开门。

在采集一些数据

本来打算写个crawler来做的,后来发现没有想象中那么简单,结果很可能是写程序占用的时间比手工采集还要多。

于是采用手工采集。其实效率也不算低,因为对于工具的使用越来越娴熟。

事实上,OA的极大发展,可以相当于智能程序带来的优势。

OA还是很重要的。

前天开始采集数据,前天21K,昨天43K,今天48K,我的目标是1M?

看来还是需要加快速度。

诡异的问题无处不在,对么

上周在本机上写的webapp,在IIS+php跑得很开心,今天想挪到网站空间里面,linux平台的

ImageTTFText

这个牛叉的函数显示不出文字来

查了一下,gd库和freetype都是支持的,字库文件是我自己上传的,还好吧……

不过,用相对路径

./simhei.ttf

,文字怎么也出不来,又用phpinfo确认了一下,gd和freetype都声明是支持的啊……

faint死了,最后还是在phpinfo里把绝对路径找出来再加上字库名,才解决了,大概是个bug么?

内核级Rootkit的加载和调试Zz

【导读】本文向读者介绍加载和调试内核级Rootkit的一些简易方法和工具,其中具体介绍了InstDrv和DebugView这两款小工具的使用。实际上,这些方法只适合于开发期间的简单调试,对于更加复杂的调试工作,我们可以使用SoftIce 或WinDbg之类的调试程序;对于“产品级”的Rootkit的加载,我们需要更加高级的技术,我们将会在后面的文章中详细介绍。

本文将向读者介绍如何将编译好的驱动程序运行起来并察看它的调试语句给出的消息。换句话说,我们要做的是最简单的调试工作。

一、驱动程序的加载和执行

当我们开发Rootkit的时候,经常需要改变其功能,这时经常重复加载、运行、测试、停止和卸载这一系列的动作。加载和运行驱动程序的方法很多,我们这里介绍的是最简单的一种——利用工具软件InstDrv。

InstDrv是一款非常小巧的工具,它的.zip压缩包只有189KB。该工具可以动态地加载、运行、停止和卸载内核级驱动程序。该工具可以从网上下载,为了读者方便使用,该工具可以到论坛

下载

下面我们以上篇《

内核级Rootkit技术入门

》文章中编译好的驱动程序为例子,来说明如何利用InstDrv加载和卸载内核级驱动程序。InstDrv有两种使用模式,一种模式称为交互模式,它是图形用户界面;另一种模式是命令行模式,在命令行中使用。下面我们首先介绍交互模式的使用方法。

 

先将InstDrv压缩包抽取到合适的目录,例如C:\。然后在在 C:\ InstDrv目录中会看到一个绿色的InstDrv图标,双击该图标打开此程序,如下图所示:

图1 InstDrv程序的交互模式

在交互模式下,首先在“Full path of the driver”下面的文字框中输入要加载的驱动程序的绝对路径,对于本例而言,该地址是C:\myrootkit\objchk_wxp_x86\i386\mydriver.sys,然后就可以利用文字框下面的“Install”、“Start”、“Stop”和“Remove”按钮分别进行驱动程序的安装、运行、停止和卸载操作了。

图2  运行我们的驱动程序

当我们单击“Install”和“Start”按钮后,利用Win0bj程序(

论坛下载地址

)可以在\Driver目录中看到我们的驱动程序mydriver,如下图所示:

图3 利用Win0bj程序查看驱动程序(注意加红色下划线部分)

现在开始介绍InstDrv的命令行模式下的使用方法。在该模式下,我们同样需要使用驱动程序的绝对路径。此外,还有几个选项可用,这些选项的作用如下所示:

 /i      该选项用于安装驱动程序

 /u      该选项用于卸载驱动程序

 /s      使用该选项后,不会弹出任何消息,即使出错也如此。

 /?      显式帮助信息

下面用一个例子来说明命令模式的用法:

instdrv /i /s C:\myrootkit\objchk_wxp_x86\i386\mydriver.sys

该命令的作用是安静地安装驱动程序,并运行它。上面的命令行中使用了选项/i ,InstDrv将以“自动运行”的方式来安装该驱动程序,这意味着每次系统重启后该驱动程序将自动运行。这一点与交互模式下的安装截然相反,在交互模式下安装的驱动程序,系统重启后它不会自动运行,相反,我们必须手工运行驱动程序。

对于InstDrv而言,如果直接在命令行中输入该程序名的话,它会切换到交互模式。此外,如果InstDrv以命令行模式运行时遇到错误的话,一般也会切换到交互模式。但如果我们使用了/s选项的话,它就不会这样做了。因此,/s选项的作用是用于安静的安装一个驱动程序。

二、查看调试语句的输出

大多数操作系统都提供了可用作调试之用的函数,例如在Linux下,可加载模块能用printk()函数来打印调试信息,以及Windows内核级日志函数,例如DbgPrint()等。我们可以在某行代码后面加上这些调试语句,例如:

DbgPrint(

消息字符串

);

当我们收到这样的消息时,至少说明某行代码已经执行,此外还能给出更多的描述信息。虽然这种调试方法计较简陋,但却很方便。像SoftIce 或WinDbg之类的调试程序的配置和使用是很麻烦的,尽管它们功能很强大。使用调试语句时,返回码能打印出来,对于出错情况也有较为详细的描述。我们可以利用这些函数给出驱动程序执行期间的重要信息,然后使用适当的调试消息捕获工具记录下这些消息,从而进行简单的调试。

我们这里介绍的是一个常见的调试语句捕获工具:Debug View,到51CTO论坛

下载

我们说过,这和一般程序不同,驱动程序消息不会显示在标准输出设备上,也就是说,我们在屏幕上看不到这则消息。下面我们还是以上篇“内核级Rootkit技术入门”文章中编译好的驱动程序为例子,来说明如何利用Debug View来记录调试消息。我们的驱动程序非常简单,它只是在内核运行时,利用调试语句给出一则消息:“I am a driver and I loaded!”,然后卸载时给出消息“MyUnload called”。下面具体介绍如何利用专门的工具Debug View查看这些调试消息。

DebugView是一款本地调试软件,它能捕获驱动程序的调试输出信息。DebugView不仅能够捕获用户模式的应用程序产生的调试输出,而且还能捕获Windows内核本身或/和内核模式设备驱动程序所产生的调试输出信息。对于后者,我们需要选中“Capture”菜单中的“Capture Kernel”选项,或者在工具栏中单击齿轮形状的“Capture Kernel”按钮(如果该按钮上有一个红色的叉,你就需要再按一下;否则说明已经设定为捕捉内核状态了),或者使用热键Ctrl+K。

DebugView也有命令行模式,但限于篇幅,我们在此只介绍在图形用户界面下的使用方法。Debug View程序无需安装,解压后便可直接使用。首先打开该程序,按照上面介绍的捕获系统内核驱动程序的方法设置,然后利用InstDrv安装并启动我们的驱动程序,这时我们就能捕获驱动程序发出的消息了,如下图所示:

图4  DebugView 从内核模式驱动程序捕获的输出信息

下面是工作中经常用到的功能,我们在此加以介绍:

插入注释

通过选择“Edit”菜单的“Append Comment”菜单项,我们就能在当前输出窗口中键入注释并回车,从而向输出中添加注释。

清屏

利用工具栏上的“clear”按钮能够清除当前程序产生的输出消息。

输出窗口内容的保存

我们要想将DebugView窗口中的内容保存成一个扩展名为.log的文件,可以选中 “File”菜单中的“Save”或“Save As”菜单项,或者使用组合键Ctrl+S。此外,我们开可以利用“Edit”中的“Copy”菜单项,或组合键Ctrl+C将选中的内容复制到剪贴板,然后保存在适当的地方。

将消息记录到文件中

为了将DebugView程序捕获的记录输出成为像我们在输出窗口看到的样子的文件,我们要使用“Files”菜单中的“Log to File”或“Log to File As”菜单项,或者工具栏中的“Log to File”按钮,或者使用组合键Ctrl+O也可以。然后设置文件的名称和最大尺寸等。如果选择了“wrap”选项,当文件尺寸达到其最大值时,DebugView将回卷到文件起始处。

如果选择了“Create New Log Every Day”项,DebugView就不再限制日志文件的尺寸,但它会为每天的日志新建一个文件,该文件的名称是你规定的文件名加上当前日期。

当记录活动仍在进行的时候,工具栏“Log to File”按钮中的箭头是绿色的,要停止记录,可以单击该按钮或者选择 “File” 菜单中的“Log to File”菜单项即可。如果记录文件达到最大尺寸,记录活动就会停下来,工具栏“log file”按钮中的箭头变成红色的。

三、小结

本文向读者介绍加载和调试内核级Rootkit的一些简易方法和工具,其中具体介绍了InstDrv和DebugView这两款小工具的使用。实际上,这些方法只适合于开发期间的简单调试,对于更加复杂的调试工作,我们可以使用SoftIce 或WinDbg之类的调试程序;对于“产品级”的Rootkit的加载,我们需要更加高级的技术,我们将在会面的文章中详细介绍。