hao对《琢石成器》的笔记(30)

hao
hao

读过 琢石成器

琢石成器
  • 书名: 琢石成器
  • 作者: 罗云彬
  • 副标题: Windows环境下32位汇编语言程序设计
  • 页数: 733
  • 出版社: 电子工业出版社
  • 出版年: 2009-6
  • 第20页 背景知识

    这本书也是很早就读了。 = =! 我不用win32 ASM ,就当是《windows核心编程》的汇编版,虽然《windows核心编程》讲得更细,更广,但是这两本书我认为各有各的优点吧。至少我第一次学习逆向有收获的是看这本书。很多小知识也是。 放上来主要是为了让我的读书笔记不空洞,算是记录自己的人生学习经历了。等书丢失了,回来也可以找笔记看关键点(靠近本质的)。 1.80x86处理器的工作模式

    80386处理器有3种工作模式:实模式,保护模式和虚拟86模式。实模式和虚拟86模式是为了和8086处理器兼容而设置的。保护模式是80386处理器的工作模式,在此方式下,处理器可以寻址4GB的地址空间。同时,保护模式也提供了处理器先进的多任务,内存分页管理和优先级保护等机制。
    引自 背景知识

    1.1实模式

    80386处理器被复位或在加电时以实模式启动。各寄存器以实模式初始化,寻址方式和8086一样,由段寄存器的内容乘以16当作基址,加上段内偏移最终形成物理地址。寻址空间为1MB。32位寄存器只使用了低20位 在实模式下,所有的段都是可读写,可执行的。实模式下,不支持优先级,所有指令相当于工作在ring 0。
    引自 背景知识

    1.2保护模式

    80386在保护模式下,发挥最大威力,所有功能都是可用的。所有32根地址线都可供寻址,物理寻址空间高达4GB。 保护模式下,支持多任务,可以依靠仅在一条指令中实现任务切换。任务环境的保护工作由处理器自动完成。 保护模式下,支持优先级机制,不同的程序可以运行在不同的优先级上。优先级分四个级别(ring0~ring3),ring0为最高优先级,应用程序一般运行在ring3.
    引自 背景知识

    1.3虚拟86模式

    虚拟86模式是为了在保护模式下执行8086程序而设置的。虚拟86模式是以任务形式在保护模式下执行的。所以支持任务切换和内存分页。
    引自 背景知识

    2.windows内存管理

    在实模式下,段地址被放在16位的段寄存器中,然后在指令中用16位的偏移地址寻址。换算公式:段地址*16+16位偏移得到物理地址。 当处理器工作在保护模式和虚拟86模式下,32位地址线可以用,访问4G大的内存。段地址+偏移的计算方法显然无法覆盖这么大的范围,但因为8086的限制不存在了,所有通用寄存器为32位,2^32=4G。所以用任何一个通用寄存器间接寻址,不必分段就已经可以访问到所有内存地址。 在保护模式下,段寄存器就更有用了。在定义地址空间的安全属性上派上了用场。 段寄存器是16位的,无法放下保护模式下64位的段描述符。所以就把所有段的段描述符(Segment Descriptor)放在指定位置,组成一个段描述符表(Descriptor Table)。而段寄存器中的16位用来做索引信息,指定这个段的属性用段描述符表中的第几个描述符来表示。 段描述符表的位置:80386中引入两个新的寄存器来管理段描述符表。一个是48bits的全局描述符表寄存器GDTR,一个是16bits的局部描述符表寄存器LDTR。GDTR指向GDT。LDTR指向LDT。 GDT包含系统所有任务都可用的段描述符(OS所使用的代码段,数据段,堆栈段。以及各任务的LDT段。)。GDT只有一个。 每个任务都有一个独立的LDT。它包含每个任务私有的代码段,数据段和堆栈段的描述符,也包含该任务所使用的一些门描述符,如任务门,调用门描述符。 和GDTR直接指向内存地址不同,LDTR和CS,DS等段选择寄存器一样只存放索引值。随着任务的切换,只要改变LDTR的值,系统当前的LDT也随之切换。
    引自 背景知识
    GDTR,LDTR GDT,LDT 和selector的关系

    3.分页机制

    在保护模式下,段选择器+偏移地址转换后形成“线性地址”(虚拟地址),而不是“物理地址”。
    引自 背景知识

    分页机制有我笔记,改天我贴上来。

    页表规定的不仅仅是地址映射,同时还规定了页的访问属性,是否可读,可写。利用这个机制可以在硬件层次上支持虚拟内存的实现。
    引自 背景知识
    内存地址转换表

    4.windows的内存安排

    windows的内存安排

    2013-07-16 14:58:44 回应
  • 第22页 准备编程环境
    Win32 PE文件的开发过程
    2013-07-16 14:58:56 回应
  • 第45页 准备编程环境

    其实直接用RadASM就可以了。书上介绍太麻烦。不要makefile什么的了。

    .rc是资源脚本,可以编辑。
    引自 准备编程环境
    2013-07-16 14:59:05 回应
  • 第88页 使用MASM

    使用MASM,其实就是它的文法,下面我归纳总结一下: Win32汇编,程序的基本构造跟DOS下差不太多。 下面是个Hello World的程序: .386 .model flat, stdcall option casemap:none ;>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;include文件定义 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>> include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;数据段 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .data szCaption db 'A MessageBox !',0 szText db 'Hello ,World ! ',0 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;代码段 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .code start: invoke MessageBox, NULL, offset szText,\ offset szCaption, MB_OK invoke ExitProcess, NULL >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end start .386是伪指令,用来告诉编译器在本程序中使用的指令集。在80386以及以上的处理器中,使用这句是必不可少的。(注意,这不是纯汇编,是MASM汇编,有文法的。) 如果后面带p(例如:.386p)就表示程序可以使用特权指令。如果我们要写VxD等驱动程序,就有可能用到类似指令。 .model用来定义程序的工作模式。但对于win32应用程序来说只有一种模式,就是flat(平坦模式),因为每个进程运行在独立的4GB内存空间中。 如果定义了平坦模式,MASM就自动为各种段寄存器做了如下定义: ASSUME cs:flat, ds:flat, ss:flat, es:flat, fs:error, gs:error 指令格式: .model 内存模式 [, 语言模式] [,其他模式] win32汇编中有各种段, .code, .const, .data .data? 与DOS不同,它没有堆栈段,因为系统会为程序分配一个向低址扩展的段作为堆栈段。这些段绝对不是DOS汇编中那种意义的段,而是内存的“分段”。所有的“分段”合起来,包括系统所使用的地址空间,组成了4GB空间。4GB空间被分页机制管理,每页4KB,每页都有自己的属性,“分段”的概念实际上就是把不同类型的数据或代码归类,再放到不同属性的内存页。必须注意与DOS汇编中“段”的不同含义。 数据段: .data .data?和.const 的数据,分别把数据放在PE文件不同的节区(section)(详细参考PE文件结构)。 .data可读可写。已经初始化,放在PE文件的_DATA节区,类似与C中static变量和全局变量,会增大PE文件大小。(.exe文件)。 .data?可读可写。未定义。存放在_BBS节区。编译出来不会增加PE文件大小。编译器只为它保留大小信息,不会浪费磁盘空间。 代码段: .code 所有指令必须写在代码段中,存放在PE文件的_TEXT节区。.code段不可写。代码段的属性是由PE文件头部中的属性位决定的。可以修改。ring0程序直接有权利修改代码段。 程序的结束和入口: 在C语言中不必显式指定程序由哪里开始执行,编译器已经约定从main函数执行了。在汇编里,程序员可以指定从代码段的任何一个地方开始执行。 end [开始地址] 调用win32 API: DOS下调用(显式)系统功能是中断,而到了win32下则不是了(实际上在内核态下还是调用了int 2e,这个先不考虑),win32系统中的功能模块则是放在dll文件中的,dll文件也是PE文件结构。 kernel32.dll -----系统服务功能。包括内存管理,任务管理和动态链接 GDI32.dll-------图形设备接口。利用VGA与DRV之类的显示设备驱动程序完成显示文本等功能。 USER32.dll------用户接口服务。建立窗口和传送消息。 不同的dll提供不同的系统功能,所有的这些dll组成了win32编程环境。 调用API: 因为MASM为简化开发,用了invoke伪指令,来简化函数调用,实际上完成了push等参数入栈操作和平衡堆栈操作。 API的返回值一般放在eax中。只有dword一种类型。 字符串相关的API有W和A型的,MessageBoxW和MessageBoxA,前者处理Unicode,后者处理ANSI。Unicode占2bytes,ANSI占1bytes。所以为了让程序更有移植性,一般不显式指定W或者A。直接: if UNICODE MessageBox equ <MessageBoxW> else MessageBox equ <MessageBoxA> include [XX.inc] .inc为所有DLL函数生命列表,每个dll对应[dll名.inc]文件。 includelib 在win32汇编中,程序必须知道API在哪,否则必须搜索系统所有dll,并且无法处理不同dll中的同名函数,所以必须有个文件来包括dll库正确的定位信息,这就是lib文件(导入库)。DOS下的C语言函数库也是lib文件(称静态库),因为函数实现都存在lib中了。缺点就是每个可执行文件都包括了相同函数的代码,浪费磁盘空间,在执行的时候也浪费内存。

    lib文件只是告诉链接器在链接的时候到指定库(dll)中去找API函数的位置信息而已。
    引自 使用MASM

    MASM定义全局和局部变量: 全局: 变量名 类型 初始值1,初始值2,... 变量名 类型 重复数量 dup (初始值1,初始值2,...) 局部: local 变量名[[重复数量]]:[类型] local @var:dword, @var2:word,@var3:byte

    在80386处理器中,以dowrd为界对齐时对内存访问最快。(所以不要轻易去数结构体的大小)
    引自 使用MASM

    子程序定义方式: 子程序名 proc [距离] [语言类型] [可视区域] [USES 寄存器列表][,参数:类型]...[VARARG] local 局部变量列表 指令 子程序名 endp 分支语句: .if 条件表达式1 指令 [.else if 条件表达式2] 指令 ..... [.else ] 指令 .endif 循环语句: .while 条件测试表达式 指令 [.break [.if 退出条件]] [.continue] .endw 类似C中的wile(){} .reapt 指令 [.break [.if 退出条件]] [.continue] .until 条件测试表达式 类似C语言中的do{}wile() 代码组织: 1.使用频繁的部分把它们封装成黑匣子,尽量把全局变量设置成局部变量。 2.子程序规模尽量小。不应该太大,行数尽量在几百行以内。 3.尽量从以前的代码中拷贝相似的代码,把子程序封装成黑匣子,随着积累,开发程序是很快的。

    2013-07-16 14:59:23 回应
  • 第97页 第一个窗口程序
    窗口运行的过程机制
    2013-07-16 14:59:37 回应
  • 第99页 第一个窗口程序

    1.模块和句柄

    一个模块代表的是一个运行中的.exe文件或dll文件,用来代表这个文件中所有的代码和资源,磁盘上的文件不是模块,装入内存才叫模块。一个应用程序调用API,用到dll时,dll装入内存,就产生了不同的模块,为了区分地址空间中的不同模块,每个模块都有一个唯一的模块句柄来标识。 在win32中,模块句柄在“数值”上等于程序装入内存的起始地址(基地址),用GetModelHandle获得。 hInstance(实例句柄)概念源于win16.
    引自 第一个窗口程序

    句柄只是一个数值而已,对于程序员无意义,(其实是句柄表的索引,引用内核对象的),用来表示各种资源的编号而已。
    引自 第一个窗口程序

    2013-07-16 14:59:48 回应
  • 第120页 使用资源
    资源文件的”源文件“是以.rc为扩展名的脚本文件,由资源编译器rc.exe编译成res为扩展名的二进制文件,最后链接的时候由link.exe链接进PE文件。
    引自 使用资源
    2013-07-16 15:00:01 回应
  • 第144页 使用资源
    位图(bitmap)是windows储存图像的方式。使用位图的优越之处就是操作速度快。 windowsGDI中广泛支持的是bmp文件,其他格式jpg与tif不能直接用,要使用这些文件必须转换到位图格式才能使用。
    引自 使用资源
    2013-07-16 15:00:09 回应
  • 第146页 使用资源
    大部分工作在主窗口完成,和用户互交一般是对话框(有些功能没有必要全部放在主窗口界面上)。
    引自 使用资源

    普通窗口和对话框的区别:

    普通窗口RegisterClass,CreateWindow,ShowWindow,UpdateWindow,消息循环函数(GetMessage,TransalteMessage,DispatchMessage),窗口过程回调。 非模态对话框CreateDialogParam,然后(非内建)消息循环,然后到内建窗口过程WM_CREATE 到WM_INITDIALOG,WM_CLOSE,WM_DESTROY
    引自 使用资源

    TIPS:内建消息循环就是windows干的事情,就是不是我们干的,

    模态对话框DialogBoxParam,然后内建消息循环,然后到内建窗口过程WM_CREATE 到WM_INITDIALOG,WM_CLOSE,WM_DESTROY
    引自 使用资源
    2013-07-16 15:00:18 回应
  • 第242页 图形操作
    windows为每个窗口维护一个”绘图信息结构“。 GDI接口把程序和硬件分离开来。 程序设置一个周期为100ms的定时器,windows会每隔100ms调用TimeProc子程序。 ”设备环境“只是一个环境,是设备属性的一组定义,程序输出的图形数据透过”设备环境“被定向到具体设备上,”设备环境“本身不存储这些数据。
    引自 图形操作
    2013-07-16 15:00:30 回应
<前页 1 2 3 后页>

hao的其他笔记  · · · · · ·  ( 全部427条 )

P2P网络技术原理与C++开发案例
5
大话移动通信
1
图解网络硬件
1
写给大家看的C++书
1
Orange'S
1
虚拟机
1
大规模C++程序设计
10
Linux Shell脚本攻略
3
HTTP权威指南
3
C++ API设计
8
C++语言的设计和演化
5
构建嵌入式LINUX系统
3
七周七语言
15
链接器和加载器
1
Windows网络与通信程序设计
2
Windows核心编程(第5版)
16
C++GUI Qt4编程
3
图解TCP/IP (第5版)
12
Python学习手册
5
编写可读代码的艺术
14
你一定爱读的极简欧洲史
2
短码之美
1
程序员的自我修养
17
美国纽约摄影学院摄影教材(上)
2
Win32多线程程序设计
8
竹林蹊径
4
鸟哥的Linux私房菜
4
Linux/Unix设计思想
6
程序设计语言的形式语义
1
Windows驱动开发技术详解
9
你必须知道的495个C语言问题
5
Windows内核原理与实现
44
PCI Express 体系结构导读
3
程序员的数学
5
深入浅出 MFC 第二版
2
并发的艺术
4
群和它的图象表示
1
C语言接口与实现
1
致命元素
2
深入解析Windows操作系统
51
Linux C编程一站式学习
13
淘宝技术这十年
1
高效程序的奥秘
1
花田半亩
1
于丹:重温最美古诗词
1
诛仙8(大结局)
1
深入理解计算机系统(原书第2版)
9
C和指针
9
寒江独钓
5
Windows程序设计
9
数据结构与算法分析
11
80X86汇编语言程序设计教程
3
数学分析教程
1
操作系统概念(第六版)
12
算法竞赛入门经典
10
C++反汇编与逆向分析技术揭秘
12