首页
论坛
专栏
课程

分享:

问题1:什么是汇编

汇编语言也如其他编程语言一样,是一门可以进行开发作业的语言。然而与其他“高级”语言不同的是,汇编语言是可以直接工作于硬件之上的。并且不需要像其他高级语言一样,先要翻译成处理器可以执行的指令才能被执行。如果我们足够了解硬件系统,那么我们可以使用汇编做到许多其他语言做不到的事情。

汇编语言因为最初的开发目的就是代替近乎无法识别的机器语言,并且年代久远。所以也许并不如现代的诸多高级语言那么接近于自然语言。汇编语言是以助记符形式存在的,可能在刚开始的学习中并不是那么的友好,但是在深入过后你会发现,汇编语言的威力以及魅力是其他程序语言无法代替的。

汇编语言和其它可以跨平台的编程语言(例如C、C++、python)只需要更改少量代码,甚至不需要修改代码就可以运行在其他平台不同。每个平台的汇编语言都对应着该平台的机器语言指令集,并且助记符并不尽相同,所以并没有办法直接移植到其他平台。

问题2:为什么需要学习汇编

现代汇编主要被应用于底层、硬件操作,驱动开发、嵌入式系统以及用于高度依赖效率程序的关键代码优化。(添加实际例子,说明每种方向都有哪些成名作)

但是我们学习汇编的目的基于另一个目的,就是为我们学习信息安全所服务,在二进制安全的学习中,我们往往得不到源代码,这也就是说,我们需要对程序进行反汇编,来进行代码分析,这个时候我们的汇编知识,系统知识,硬件知识有多扎实,就可以体现出来了,虽然有人会说IDA pro可以直接转换汇编成伪C代码。但是当一个程序加了壳之后,这就是完全做不到的,也许还会有人说脱壳,那么很好,这个时候又需要动态调试了,代码依然是汇编代码。

问题3:学习本套课程需要什么基础

学习本套课程需要具有基本的计算机常识,如果学习过一门编程语言,可以理解编程思想,那么是最棒的。当然,如果没有学过其他编程语言,也是可以直接学习本门课程的。

问题4:什么是Windows SDK、API

SDK(软件工具包)Software Development Kit一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。

API(Application Programming Interface,应用编程接口)其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API而使操作系统去执行应用程序的命令

所以Windows的SDK就是微软提供给我们的软件工具包,我们可以通过API调用其中的命令,执行相关的操作。

问题5:我们使用的平台以及IDE

本套课程在学习x86汇编的时候将会使用Windows系统以及Visual Studio 集成开发环境,16位以及x64汇编等到学习的时候再决定使用什么环境。

简介1:汇编的历史

说到汇编语言的产生,首先要讲一下机器语言。机器语言是机器指令的集合。机器指令展开来讲就是一台机器可以正确执行的命令。电子计算机的机器指令是一列二进制数字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。

上面所说的计算机指的是可以执行机器指令,进行运算的机器。这是早期计算机的概念。在我们常用的PC机中,有一个芯片来完成上面所说的计算机的功能。这个芯片就是我们常说的CPU(Central Processing Unit,中央处理单元)。每一种微处理器,由于硬件设计和内部结构的不同,就需要用不同的电平脉冲来控制,使它工作。所以每一种微处理器都有自己的机器指令集,也就是机器语言。

早期的程序设计均使用机器语言。程序员们将用0, 1数字编成的程序代码打在纸带或卡片上,1打孔,0不打孔,再将程序通过纸带机或卡片机输入计算机,进行运算。这样的机器语言由纯粹的0和1构成,十分复杂,不方便阅读和修改,也容易产生错误。程序员们很快就发现了使用机器语言带来的麻烦,它们难于辨别和记忆,给整个产业的发展带来了障碍,于是汇编语言产生了。

汇编语言的主体是汇编指令。汇编指令和机器指令的差别在于指令的表示方法上。汇编指令是机器指令便于记忆的书写格式。

1234567 操作:寄存器BX的内容送到AX中1000100111011000              机器指令mov ax,bx                    汇编指令

此后,程序员们就用汇编指令编写源程序。可是,计算机能读懂的只有工作过程

机器指令,那么如何让计算机执行程序员用汇编指令编写的程序呢?这时,就需要有一个能够将汇编指令转换成机器指令的翻译程序,这样的程序我们称其为编译器。程序员用汇编语言写出源程序,再用汇编编译器将其编译为机器码,由计算机最终执行。

第一个简单的示例程序

.386
.MODEL flat, stdcall
option casemap:none
includelib user32.lib
includelib kernel32.lib
ExitProcess PROTO, dwExitCode : DWORD
MessageBoxA PROTO hWnd : DWORD, lpText : BYTE, lpCaption : BYTE, uType : DWORD
.data
Number DWORD 0
text db "shellcode",0
.code
main proc
       push 0
       push offset text
       push offset text
       push 0
       call MessageBoxA
       sub esp,16
       call ExitProcess
main ENDP
END main


讲解2:介绍汇编的基本编写格式套路

1.使用的指令集

     Win32环境工作在80386级以上的处理器中,所以.386这一句必不可少

2..model语句

     .model 内存模式[,语言模式][,其他模式]

     .model flat,stdcall

     flat代表的内存使用方式:Win32程序使用的模式,代码和数据段使用同一个4GB段

     stacall通常用于win32API,该方式由被调用者清理栈

3.option语句

     在Win32汇编程序中,需要定义的只有option casemap:none,这个语句定义了程序中的变量名和子程序是否对大小写敏感,由于Win32 API中的API名称是区分大小写的,所以必须指定这个选项,否则在调用API的时候会有问题

4.段的概念

     .data,.data?和.const都是数据段,.code是代码段,.stack是堆栈段,这些都是分段伪指令,因为在windows汇编中不需要考虑堆栈,系统会为程序分配一个向下扩展的,足够大的段作为堆栈段,所以.stack段定义常常被忽略.

4.1数据段

     .data,.data?和.const定义的是数据段,分别对应不同方式的数据定义,在最后生成的可执行文件中也分别放在不同的节区(Section)中,程序中的数据定义一般可以归为三类.

     4.1.1

     第一类是可读可写的已定义变量,这些数据在源程序中已经被定义了初始值,而且在程序的执行中有可能被改变,如一些标志等,这些数据必须定义在.data中,.data段是已初始化数据段,其中定义的数据是可读可写的,在程序装入完成的时候,这些值就已经在内存中了,.data段一般存放在客户自行文件的_DATA节区里.

     4.1.2

     第二类是可读可写的未定义变量.这些变量一般是当做缓冲区或者在程序执行后才开始使用的,这些数据可以定义在.data段中,也可以定义在.data?段中,.但一般它放到.data?段中.虽然定义这两种段都可以正常使用,单定义在.data?段中不会增大.exe文件的大小.比如,需要一个100KB的缓冲区,可以使用下面的语句来定义:

     szBuffer     db     100 * 1024 dup (?)

     这个语句如果放在.data段中,编译器认为这些数据在程序装入时就必须有效,所以它在生成可执行文件的时候保留了所有的100KB的内容,即使它们是全零!假设程序其他部分的大小是50KB,那么最后程序的总大小就会是150KB大小,如果缓冲区定义为1M,那么.exe文件的大小就会增加到1050KB..data段则不同,其中内容编译器会认为程序在开始执行后才会用到,所以在生成客户自行文件的时候只保留了大小信息,不会为它浪费磁盘空间,在与上面的相同情况下,即使缓冲区的定义为1M,可执行文件的大小也只会有50KB!总之,.data?段是未初始化数据段,其中的数据也是可读可写的,但在可执行文件中不占空间,.data?段在可执行文件中一般存放在_BSS节区中.

     4.1.3

     第三类数据是一些常量.如一些要显示的字符串信息,它们在程序装入的时候也已经有效,但是在整个执行过程中不需要修改,这些数据可以放在.const段中,.const段是常量段,它是可读不可写的.为了方便起见,在小程序中常常把常量一起定义到.data段中,而不另外定义一个.const段,在程序中不小心用了.const段中的数据做写操作的指令,会引起保护错误,windows会弹出错误提示框并且结束程序.

     如果不怕可读性不佳的话,也可以把.const段中定义的内容混到.const段中去也可以正常使用,因为.code段也是可以读的.

4.2代码段

     .code段是代码段,所有指令都必须写在代码段中,在可执行文件中,代码段一般都是放在_TEXT节区中的.Win32环境中的数据段是不可执行的只有代码段有可执行的属性,对于工作在特权3的应用程序来说,.code段是不可写的,在编写DOS汇编程序的时候,一些好事的程序员往往有个习惯,就是靠改动代码段中的代码来做一些反跟踪的事情,如果企图在Win32汇编做同样的事情,那么只会有一个下场,弹出报错框,非法操作.

4.3堆栈段

     在程序不必要定义堆栈段,系统会自动分配空间,唯一值得一提的就是,堆栈段的内存属性是可读可写可执行的.

5.程序结束和程序入口

     在C语言中,程序员不必显式的指定程序由哪里开始执行,编译器已经约定好从main开始执行函数,而在汇编中,并没有main函数.程序员可以在代码段的任意位置开始执行,这个地方由程序的最后一句end语句来指定

     end[开始地址]

     end start

     上述两句程序从start这个标号 开始执行程序

     但是,一个源程序不必非要指定入口标号,这时候可以把开始地址忽略不写,这种情况发生在编写多模块程序的单个模块的时候,当分开写多个程序模块时,每个模块的源代码里都可以包括各种分段,只是其他模块最后的end语句必须不带开始地址,当最后把多个模块链接在一起的时候,只有一个主模块指定入口地址,在多个模块中指定入口地址,或者没有一个模块指定入口地址,链接程序都会报错

上传的附件:

上一篇 :
下一篇 :
讨论 (16)
阿東 2018-3-2
 举报
是我亲爱的榴莲湿敷嘛
yyjoooooooo 2018-3-10
 举报
无声?
雨落花潭 2018-3-22
 举报
偷偷抱走右下角的康娜
点灯人 2018-3-22
 举报
声音有点小,把声音开最大了,旁边有人说话的话就听不到了......
superpolice 2018-4-21
 举报
声音小了点
潜水的猫 2018-4-22
 举报
声音太小了
yekehun 2018-5-18
 举报
声音好小+1。
请问老师,教程本文中,4.2代码段里,这个特权3是什么意思?
【讲师回复】 windows系统的权限管理机制,分为ring3和ring0,也就是特权3和特权0.ring3就是我们常见的用户层。ring0指的是系统层,比如内核,驱动一类的都运行在ring0.现在还有一个概念就是ring-1.也就是虚拟化层。
2018-5-21
南方星空 2018-5-24
 举报
声音真的很小
YeahHa 2018-6-30
 举报
我觉得还ok
安星宇 2018-7-26
 举报
为什么VS2017没有语法高亮?
AliBaby 2018-11-1
 举报
老师声音真的太小了,建议下次“优化”一下。
yonghao 2018-11-2
 举报
看不了
DD 2018-11-21
 举报
@君子谬    小错误
文档  4.1.2中
“..data段则不同”应为“。.data?段则不同”
gao_656996 2019-1-11
 举报
听不见啊。
yns 2019-1-15
 举报
谢谢老师
汗宝 2019-3-3
 举报
为啥我的OllyDbg在win10上运行不起来呀??
沪ICP备16048531号-1
沪公网安备 31011502006611号