小续

   这也是我11年看加密解密整理的一些笔记,因为后面有事,所以这个笔记并不完整,不过也涉及到很多知识了,写给爱好加密解密的朋友



  多字节数据是按怎样的顺序存放的呢?实际情况和CPU有关,微处理中的存放顺序有正序和逆序之分。正序(big-endian) 逆序(little-endian)

   两种编码的区别:

   big-endian:高位字节存入低字节,低位字节存入高地址,一次排列

   little-endian:低位字节存入低地址,高位字节存入高地址。反序排列


   unicode是asc字符编码的一个扩展,只不过在WINDOWS中,用两个字节对其进行编码,也称为宽字符集

   unicode中,所有的字符都是16位,包括所有的7为asc码都被扩充为16位(注意高位扩充的是〇)

   intel处理器在内存中,一个字存入存储器要占有相继的两个字节,这个字存放时就按little-endian方式存入,即低位字节存入低地址,高位字节存入高地址


   API函数,这些函数提供应用程序运行所需要的窗口管理、图形设备接口、内存管理等各项服务功能。这些功能以函数库的形式组织在一起,形成饿了WINDOWS应用程序编程接口(API),简称win api。win api子系统负责将api调用转换成WINDOWS操作系统的系统服务调用,所以,可以认为API函数是构筑整个WINDOWS框架的基石,在他的下面是WINDOWS的操作系统核心,而在他的上面则是WINDOWS应用程序,对于应用程序开发人员而言,所看到的WINDOWS操作系统实际上就是win API,操作系统的其他部分对开发人员来说是完全透明的


   WINDOWS运转的核心是一个称作“动态链接”的概念,WINDOWS提供了应用程序可利用的丰富的函数调用,这些函数采用动态链接即DLL实现

   win32API 是一个基于c语言的接口,但是win32API中的函数可以由用不同语言编写的程序调用,只要在调用时遵循调用的规范即可

   API函数是区分字符集的:A表示ANSI;W表示Widechars,即unicode。前者是通常使用的单字节方式,后者是宽字节方式,以便处理双字节字符。


   句柄是WINDOWS标识,由应用程序建立或使用的对象所使用的一个唯一的整数值(通常是32位)。WINDOWS要使用各种各样的句柄来标识诸如应用程序实例、窗口、图标、菜单、输出设备、文件等对象。程序通过调用WINDOWS函数获取句柄,然后在其他WINDOWS函数中使用这个句柄,以引用他代表的对象。句柄的实际值对程序来说无关紧要,这个值是被WINDOWS模块内部用来引用相应对象的

   当一个进程被初始化时,系统要为他分配一个句柄表,句柄值是放入进程的句柄表中的索引


   unicode影响到计算机工业的每个部分,对操作系统和编程语言的影响最大

   在NT架构下,win32API能接受unicode和ASCI字符串,而其内核则只能使用unicode ,所有这些操作对用户来说都是透明的,但进行这些字符串的转换需要占用系统资源。


   WINDOWS是一个消息驱动式系统,WINDOWS消息提供应用程序与应用程序之间、应用程序与WINDOWS系统之间进行通信的手段。应用程序想要实现的功能由消息来触发,并且靠对消息的响应和处理来完成。

   WINDOWS系统中有两种消息队列:一种是系统消息队列,另一种是应用程序消息队列。计算机的所有输入设备由WINDOWS监控。当一个事件发生时,WINDOWS先将输入的消息放入系统消息队列中,再将输入的消息拷贝到相应的应用程序队列中,应用程序中的消息循环从他的消息队列中检索每个消息并且发送给相应的窗口函数中。一个事件的发生,到达处理他的窗口函数必须经历上述过程。值得注意的是消息的非抢先性,即不论事件的急与缓,总是按到达的先后顺序排队(一些系统消息除外)

   由于WINDOWS本身是由消息驱动的,所以调试程序时跟踪一个消息会得到相当底层的答案。


   一般来说,80X86及其以后的各代CPU可在实模式、保护模式、虚拟86模式下运转

   在保护模式下程序可以利用更多的内存,可以实现多任务系统


   在保护模式下,CPU的寻址方式与实模式不同,实模式下的寻址方式是“段基址+段偏移”,段的默认大小为64kB,所有段都是可读/写的,唯有代码段是可执行的,段的特权级为0.而在保护模式下内存是“线性”的,因为这时段寄存器的意义不同,他里面存放的不再是段基地址,二十存放着段选择子,这呃值是不直接参与寻址的,只是全局描述表(global descriptor table ,GDT)或本地描述表(local descriptor table,LDT)的一个指针,不同段寄存器有不同的属性(读、写、执行、特权级等)


   虚拟内存(virtual memory)不是真正的内存,他通过映射(map)的方法,使可用的虚拟地址达到4GB,每个应用程序可以被分配2GB的虚拟地址,剩下的2GB留给操作系统自己用。WINDOWS是一个分时多任务操作系统,CPU时间被分成一个个的事件片后分配给不同程序,在一个时间片里,和这个程序执行不无关的东西并不映射到线性地址中。因此每个程序都有自己的4GB寻址空间,互补干扰。在物理内存中,操作系统和系统DLl代码需要供每个应用程序调用,所以在所有的时间必须映射;用户exe程序只在自己所属的时间片内被映射,而用户DLL则有选择地被映射。


   简单地说,虚拟内存的实现方法和过程如下:

   1、当一个应用程序被启动时,操作系统就创建一个新进程,并给每个进程分配2GB的虚拟地址(不是内存,只是地址)

   2、虚拟内存管理器将应用程序的代码映射到那个应用程序的虚拟地址中的某个位置,并把当前所需要的代码读取到物理地址中(注意:虚拟地址和应用程序代码在物理内存中的位置是没有关系的)

   3、如果使用动态链接库DLL,DLL也被映射到进程的虚拟地址空间,在需要的时候才被读入物理内存

   4、其他项目(例如数据、堆栈)的空间是从物理内存中分配的,并被映射到虚拟地址空间中

   5、应用程序通过使用他的虚拟地址空间中的地址开始执行,然后虚拟内存管理器把每次的内存访问映射到物理位置


   关于虚拟内存,要明白一下几点:

   1、应用程序是不会直接访问物理地址的

   2、虚拟内存管理器通过虚拟地址的访问请求,控制所有的物理地址访问

   3、每个应用程序都有相互独立的4GB寻址空间,不同应用程序的地址空间是隔离的

   4、DLL程序没有自己的“私有”空间,他们总是被映射到其他应用程序的地址空间中,作为其他应用程序的一部分运行。因为如果他不和其他程序同属一个地址空间,应用程序就无法调用他


   使用虚拟内存的好处是:简化了内存的管理,并可弥补物理内存的不足;可以防止多任务环境下各个应用程序之间的冲突


   在保护模式下,所有的应用程序都有权限级别,这个权限级别按优先次序分为4等

   0等级权限可以执行所有的指令并访问所有数据,操作系统核心层是运行在ring0级的,而win32子系统(如动态链接库)是运行在ring3级的,以提供与应用程序的接口

   保护模式使应用程序没有权限去破坏操作系统,只能规矩地使用win32API接口函数与系统打交道。如果想控制系统,就必须取得0特权级,比如调试工具softICE就是工作在0特权级上的


   WINDOWS的可执行文件(EXE、DLL)是PE格式

   PE文件使用的是一个平面地址空间,所有代码和数据都被合并在一起,组成一个很大的结构。文件的内容被分割为不同的区块(section,又称区段、节等),块中包含代码或数据。每个块都有他自己在内存中的一套属性,比如:这个块是否包含代码、是否只读或可读/写等


   每个块都有不同的名字,这个名字用来表示区块的功能。常见的快的有.text,.rdata,.data,.idata,.rsrc等。各种块的含义如下:

   .text:实在编译或汇编结束时产生的一种块,他的内容全是指令代码;

   .rdata:是运行期只读数据;

   .data:是初始化的数据块;

    .idata:包含其他外来的DLL的函数及数据信息,即输入表;

   .rsrc:包含模块的全部资源,如图标、菜单、位图等。


   PE文件非常好的一个地方就是在磁盘上的数据结构与在内存中的结构是一致的,装载一个可执行文件到内存中,主要就是将一个PE文件的某一部分映射到地址空间中。这样,PE文件的数据结构在磁盘和内存中是一样的

   程序访问存储器所使用的逻辑地址称为虚拟地址,又称为内存偏移地址(memory offset)。与实地址模式下的分段地址类似,虚拟地址也可以写成“段:偏移量”的形式,这个的段是指段选择子。例如“0167:00401000”就是这个表示方法(0167:这个是段选择子,其数据保存在CS段选择器里。同一程序在不同系统环境下,此值可能不同,一般也不需要关心此值)


   基地址:文件执行时将被映射到指定内存地址中,这个初始内存地址称为基地址(p_w_picpathbase)。这个值是由PE文件本身设定的


   动态分析技术中最重要的工具是调试器,分为用户模式和内核模式两种类型。用户模式调试器是指用来调试用户模式应用程序的调试器,他们工作在ring3级。内核模式调试器是指能调试操作系统内核的调试器,他们处于CPU和操作系统之间,工作在ring0级