一、C语言运行库:入口函数、初始化、堆管理、基本IO。
1、开始:入口函数;main参数;CRT初始化;结束部分。
2、堆的实现:malloc()、free()。
3、IO与文件操作:fopen()、fread()、fwrite()、fclose()、fseek()。
4、字符串相关操作:itoa、strcmp、strcpy、strlen。
5、格式化字符串:fputc、fputs、vfprintf、printf、fprintf。
二、如何使用Mini CRT:导出Mini CRT的头文件,供开发时include即可。
三、C++运行库实现
1、new 与 delete:操作符函数。
2、C++全局构造与析构:MSVC为.CRT$XCA段和.CRT$XCZ段。GCC为.ctor段。
3、atexit实现。
4、入口函数修改。
5、stream和string。
四、如何使用Mini CRT++:编译、链接。

一、系统调用介绍
1、什么是系统调用:操作系统将可能产生冲突的资源保护起来,比如:文件、网络、IO、各种设备等,只能通过系统调用来操作。
2、Linux系统调用:通过0x80中断指令,用EAX中的值表示具体是哪个系统调用。
3、系统调用的弊端:使用不便;各操作系统不兼容。通过运行时库来解决这个问题。
二、系统调用原理
1、特权级与中断:两种特权级别:用户模式和内核模式,即用户态和内核态。CPU根据中断号去中断向量表中找中断处理程序。
2、基于int的Linux经典系统调用实现:触发中断,切换堆栈,中断处理程序。
3、Linux的新型系统调用机制:sysenter和sysexit。虚拟动态共享库VDSO中有具体实现。

三、Windows API:Windows不公开系统调用,只公开API,通过API来完成系统调用。
1、Windows API概览:大量DLL描述及相关文件、工具提供给开发者,称之为SDK(Software Development Kit)。
2、为什么要使用Windows API:兼容性。
3、API与子系统:为了兼容,出子系统(subsystem)。比如:WoW(Windows On Windows),32位系统运行16位程序,就是WoW机制。64位运行32程序亦然。

昨天跟楼下的大叔搞定了这次的漏水事件,简单总结一下。

第一次漏水事件发生在两年前,持续一年。
当时我发现我家的阳台漏水,只要下的得稍大一些,就会漏,水越大,漏得越厉害。第一反应是楼上有问题。
一般预报有雨的时候,阳台就不敢晾衣服。还怕水会流进卧室,泡了木地板。
找楼上的阿姨沟通了小半年,阿姨说不是她家的问题,最终阿姨告诉我真正的问题,墙外的雨水管出问题了。
我确认一下,也发现是这个问题,找物业反馈,差不多折腾他们半年,才给修好。

第二次漏水事件发生在一年前,又持续一年。
去年,楼下的大叔上来找我,说洗手间漏水,我第一反应是我家的水盆坏了,正在修,怀疑是这个问题。
跟大叔说修好水盆再看看。然后就没音了。
上周大叔又上来找我,说又漏了。我家水盆是好的,就不知道原因了。我停用了一周水盆,陪他做测试,看是不是这个问题。
昨天满一周,大叔上来说,漏得更厉害了。
我们协商好,我先不用水盆和淋浴,再试一周。下午,大叔跑上来找我,说确认是他们家自己水管的问题,跟我家没关系。他家水管锈了,漏水。
一直只看吊顶,大叔拆了吊顶看楼板,才发现楼板是干的,水管生锈了,滴水。
幸好我没上来就重新做防水,否则就白折腾了。
我这次坚持的原则是:先用排除法,确认是我家哪一块的问题,然后再动手。

这两次漏水非常相似,事实证明,主观的第一反应是靠不住的:
第一次,我很自信的去找楼上,说是他们的问题。后来证实是别的原因。
第二次,楼下也很自信是我家的问题,后来也证实是别的原因。

大胆假设,小心求证。

一、入口函数和程序初始化。
1、程序从main开始吗:显然不是,之前已经知道有动态链接器了。从入口函数开始。
2、入口函数如何实现:ebp清零(表示最外层函数)、参数和环境变量入栈。
3、运行库与I/O:I/O指代所有操作系统理解为“文件”的事务。
4、MSVC CRT的入口函数初始化:堆初始化、I/O初始化。
二、C/C++运行库
1、C语言运行库:入口函数及其依赖的函数包括各种标准的库函数。
2、C语言标准库:数学函数、字符/字符串函数、I/O基本操作等。特殊函数:变长参数、非局部跳转。
3、glibc与MSVC CRT

- 阅读剩余部分 -

一、程序的内存和布局
1、栈:用于维护函数调用的上下文。
2、堆:程序在运行时动态分配的区域。
3、可执行文件映像。
4、保留区:比如地址0
二、栈与调用惯例
1、什么是栈:后进先出的队列,包括函数的返回地址和参数、临时变量、寄存器的上下文。
2、调用惯例:函数调用方和被调用方之间的约定,包括:参数传递方式、栈维护方式、名字修饰策略。
3、函数返回值传递:一般是eax,5~8字节用eax和edx,超过8字节用栈上开对象用eax指向其地址的方式。

- 阅读剩余部分 -

一、DLL简介
1、进程和地址空间管理:32位Windows之前,是共享数据空间(包括数据空间),32位Windows开始,各自独立的空间。
2、基地址和RVA:基地址是装载时的起始地址,RVA是相对于起始地址的偏移。
3、DLL共享数据段:DLL可以设置某些数据共享,即同时存在共享数据和私有数据。
4、DLL的简单例子:导出指定的某些符号,使用时导入。有别于ELF中的全导出。
5、创建DLL:cl /LDd **.c,生成四个文件,**.dll,**.obj,**.exp,**.lib
6、使用DLL:把编译后的目标文件与**.lib链接。**.lib中是导出符号。
7、使用模块定义文件:.def文件。
8、DLL显式运行时链接:跟ELF类似。LoadLibrary、GetProcAddress、FreeLibrary。
二、符号导出导入表
1、导出表:PE文件提供出来给别的程序使用的符号表,为省内存使用序号机制,ELF中也有类似用法。
2、Exp文件:链接器在第一遍扫描后生成的导出表临时文件,用于链接器在第二遍时的链接。
3、导出重定向:某dll文件的导出符号表直接指向另一个dll文件。寻址的时候,直接跳过去,所以不是委托。
4、导入表:对所调用的DLL的引用信息。也有神奇的延迟载入。delay load。
5、导入函数的调用:PE的DLL不是地址无关的,它用了rebasing的方法。没有全局符号介入问题。

- 阅读剩余部分 -