Archive for the 'Assembly' Category

例 求机器数 1010 0000分别是原码定点小数,补码定点小数时的真值x。
解 若[x]原码=1010 0000B
当是原码定点小数时 x真值=-0.01B=-0.25D
当是补码定点小数时 [x]真值=-0.11B=-0.75D
-0.25D和-0.75D值的运算过程为:
根据规则,定点小数后第一位乘以1/2+第二位乘以1/4+第三位乘以1/8+…+第N位乘以2的N次方
那么
-0.01的十进制就是:-0×2^0+0x(1/2)+0x(1/4)=-0.25D;
-0.11…………:-0×2^0+1x(1/2)+1x(1/4)=-0.75D;
这种格式通常被用于商业计算(例如在电子表格或COBOL中);因为在这里,丢弃小数位来记录金钱是不能接受的。因此了解二进制如何存贮小数是十分有用的。
首先去我们必须决定要用多少位来存贮小数部分和多少位来存储整数部分。假设我们使用32位来表示这种格式,那么我们用16位表示整数部分,16位来表示小数部分。
小数部分怎么使用呢?这沿用了表示整数的方式:如果8位接下来是4位,是2位,1位,那么当然接下来就是半位,1/4位和1/8位等等了。
例如:
整数位 小数位
0.5 = 1/2 = 00000000 00000000.10000000 00000000
1.25 = 1 1/4 = 00000000 00000001.01000000 00000000
7.375 = 7 3/8 = 00000000 00000111.01100000 00000000
有一点棘手的是,如果您要表达1/5(十进制的0.2),那不能得到精确的数值表达方式。最好的方法只能是:
- 13107/65536 = 00000000 00000000.00110011 00110011 = 0.1999969… 十进制
- 13108/65536 = 00000000 00000000.00110011 00110100 = 0.2000122… 十进制
然而,我们不能总这样做,即使你有更多的数位来表达。问题是,一些小数使用二进制的方式不能精确地表达出来。除非使用一个特殊的办法。这个特殊的办 法是分别使用两个数字来表达小数:一个是分子,一个是分母。然后您可以使用学校学习的加、减、乘、除来得到它们。然而,这些方法不能表达更高级的数字(例 如平方根),或者如果这两个分母的最小公倍数很大的话,那就难以使用。这就是使用定点小数表达小数的优点。
ds和es一个是数据段,一个是附加数据段,这两个数据段一般情况下在使用方面没有多少区别。
在数据移动、搜索、比较这类指令中,DS 对应 SI,ES 对应 DI。这个时候,DS和ES就不同了,前面的表示源,后面的表示目的地。
例:直接存储单元传送,求数组元素之和,结果送SUM单元
D_SEG SEGMENT
ARRAY DW 50 DUP(?)
COUNT DW 50
SUM DW ?
TABLE DW 3 DUP(?)
D_SEG ENDS
…
MOV TABLE,OFFSET ARRAY
MOV TABLE+2,OFFSET COUNT
MOV TABLE+4,OFFSET SUM
CALL PROADD ;主程序
…
;TABLE ARRAY首地址
; Count地址
; SUM地址
PROADD PROC
PUSH AX ;保护现场
…
push DI
MOV SI,[BX] ;数组首地址送SI
MOV BP,[BX+2] ;数组长度单元地址送BP
MOV CX,DS:[BP] ;数组长度送CX,如果不用DS超越前缀,那么BP是在栈中默认SS
MOV DI,[BX+4] ;存储和单元地址送DI
MOV AX,0
ADDT: ADD AX,[SI]
ADD SI,2 ;双子节+2
LOOP ADDT
MOV [DI],AX ;结果直接送SUM
POP DI ;恢复现场
…
RET
PROADD ENDP
例:直接存储单元传送,求数组元素之和,结果送SUM单元
D_SEG SEGMENT
ARRAY DW 50 DUP(?)
COUNT DW 50
SUM DW ?
D_SEG ENDS
…
CALL PROADD ;主程序
…
PROADD PROC
PUSH AX ;保存现场
PUSH CX
push SI
XOR AX,AX
LEA SI,ARRAY ;直接使用存储单元中数据
MOV CX,COUNT
ADDT: ADD AX,[SI]
ADD SI,2 ;双子节+2
LOOP ADDT
MOV SUM,AX ;结果直接送SUM
POP SI ;恢复现场
POP CX
POP AX
RET
PROADD ENDP
例:求数组元素之和,并以16进制显示。
D_SEG SEGMENT
ARRAY DB 10,20,30,5,60
COUNT EQU $-ARRAY
D_SEG ENDS
S_SEG SEGMENT PARA STACK
DW 100 DUP(?)
S_SEG ENDS
C_SEG SEGMENT
ASSUME CS:C_SEG,DS:D_SEG,SS:S_SEG
START:…
LEA SI,ARRAY ;参数准备
MOV CX,COUNT
CALL SUM1 ;求和
CALL DISPLAY ;转化为16进制显示
…
;子程序:SUM1
;入口参数:SI=数组首址,CX=数组长度
;出口参数:AX=数组合
;使用寄存器:AX,CX,SI
SUM1 PROC NEAR
CMP CX,0
JZ EXIT ;为0返回到主程序
XOR AX,AX
AGAIN:ADD AL,[SI] ;求和
ADC AH,0
INC SI
LOOP AGAIN
EXIT: RET
SUM1 ENDP
;子程序:DISPLAY
;入口参数:AX=数组和
DISPLAY PROC NEAR
MOV BX,AX ;AX中的数据是二进制代码
MOV CH,4 ;用4位二进制代码来表示1位16进制代码,4*4=16,共需4位16进制表示循环4次
ROTATE: MOV CL,4
ROL BX,CL ;把BX中内容循环左移4位最高位插入最低4位
MOV AL,BL
AND AL,0FH ;取AL最低4位值就是左移前BX的最高4位
OR AL,30H ;形成ASCII码
CMP AL,3AH ;因是16位数据判断是否是0-9,还是A-F
JL PRINT
ADD AL,07H ;转换为A-F的时候需要加07H
PRINT: MOV DL,AL ;显示DL数据字符到屏幕
MOV AH,02H ;中断指令显示一个字符
INT 21H
DEC CH
JNZ ROTATE
RET
DISPLAY ENDP
例:编程产生FIBONACCI(斐波那契)数列,要求数列中的最大数项小于600,
数列存放在SERIER为首址的缓冲区,数列长度在FIBONA单元。
分析:产生多少个FIBONACCI数项并不知道,但题中要求最大数项小于600,这就是循环控制的“条件”。
定于数据段如下:
D_SEG SEGMENT
SERIER DW 100 DUP(?) ;存放数列
FIBONA DB 0 ;数列长度
MAX DW 600
D_SEG ENDS
程序段如下:
MOV AX,0 ;FIBONACCI数列的首项
MOV BX,1 ;FIBONACCI数列的次项
LEA SI,SERIER
AGAIN:MOV [SI],AX ;存数项
XCHG AX,BX
ADD AX,BX ;产生当前数项
ADD SI,2 ;修改指针
INC FIBONA ;数项计数
CMP AX,MAX ;条件判断
JA NEXT
JMP AGAIN
NEXT:
AX和BX的变化:
AX BX
0 1
1 0 XCHG
1 ADD
0 1 XCHG
1 ADD
1 1 XCHG
2 ADD
1 2 XCHG
3 ADD
2 3 XCHG
5 ADD
[作者]
猪头三
个人网站 :http://www.x86asm.com/
[序言]
很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文为主,这样让很多驱动初学 者很头疼.本人从事驱动开发时间不长也不短,大概也就3~4年时间.大多数人都认为会驱动开发的都是牛人,高手之类的.其实高手,牛人不是这样定义的.我 们在学习驱动开发之前,一定要明白一个道理:术业有专攻,不要盲目跟风.
[贡献者]
1> defddr 看雪学院
2> StudyRush 看雪学院
[本内容适用环境及工具]
1> Windows系统下
2> VC6.0以及VS2003版本以上
3> Windows驱动开发包(DDK(老版本) WDK(新版本))
4> 有能力着可以安装VMWare
[本内容适用群体]
1> 具有C/C++语言基础的人
2> 具有80×86汇编基础的人
3> 具备高中以上文化水平的逻辑思维
[具备Windows系统理论书籍]
1> Windows核心编程
2> Win32多线程程序设计
3> 深入解析Windows操作系统
4> Windows操作系统原理
FAQ1:为什么需要[具备Windows系统理论书籍]这4本书?
答:驱动是Windows系统的一个重要的组成部分,深入Windows系统核心的一个体系,就因为驱动跟系统内核联系得十分紧密,所以涉及了不少系统的 基础理论以及原理.因此在学习驱动开发之前必须先明白Windows系统的基础开发理论,Windows系统的运作原理,Windows系统的架构体系. 那么我提供的上面4本书是目前市面上我认为最经典最全面的书籍了.
[具备Windows驱动开发书籍]
1> Windows驱动开发技术详解
2> Windows设备驱动程序WDF开发
FAQ2:为什么需要[具备Windows驱动开发书籍]这2本书?
答:假设你对Windows系统的基础理论扎实了,也看完了所说的[Windows系统理论书籍]这4本书,而且你还从事开发过Windows程序或者大 程序的经验者.那么你进入Windows驱动开发的时候,需要一本经典的驱动入门开发书籍即可正确入门.现在我提供了[Windows驱动开发书籍]这2 本书完完全全针对Windows驱动开发入门而编写的书籍.当然我首要推荐<Windows驱动开发详解>这本书.本书的内容在目前来说,针 对驱动开发的讲解时非常到位了.包含了驱动开发理论 配置 驱动体系 等等……是一本不可多得的好书.那么第2本,其实有点滥竽充数,但是他里面有少少涉及到WDF这个最新的驱动开发理论的讲解,大家也就凑合着吧.
[具备Windows调试基础理论书籍]
1> 软件调试
2> Windows用户态程序高效排错
FAQ3:为什么需要[具备Windows调试基础理论书籍]这2本书?
答:在开发驱动的情况下,你少不了要调试驱动程序.那么如何调试驱动程序呢? Windows已为你考虑到这个问题了并开发了一套强有力的调试工具:Windbg .如何学习这个工具的调试呢?那么现在市面上只有这2本书针对Windbg讲解得还比较到位,至少针对调试命令的使用,已经用中文讲解了,大家可以通过2 本书先大概了解Windbg的调试命令,然后再进一步进行GOOGLE搜索并深入学习.
[具备汇编基础理论书籍]
1> 汇编语言 作者:王爽
2> 80×86汇编语言程序设计教程[绿皮版 或者 黑皮版]
FAQ4:为什么需要[具备汇编基础理论书籍]这2本书?
答:由于在Windows环境下开发驱动,从而有个弊端,就是Windows的WDK,DDK文档少得可怜,很多说明多是模糊的.因此导致我们开发的驱动 极其不稳定,这时就需要逆向Windows驱动的机制来加深理解.在一个由于驱动的不稳定性,会导致系统蓝屏,有时错误并不会直接定位到你的代码,这时就 需要汇编来分析错误的缘由.就如我前面介绍的[具备Windows调试基础理论书籍]基本是用汇编语言来阐述调试技术.
[驱动开发扩展书籍]
1> 寒江独钓-Windows内核安全编程
2> Windows内核原理与实现
3> Rootkit Windows内核安全防范
4> Windows内核情景分析
FAQ5:为什么需要[驱动开发扩展书籍]这4本书?
答:熟话说:学无止境,驱动开发领域是一个很庞大的体系,这归根于驱动框架多样化而决定的.驱动包含了:文件驱动,磁盘驱动,显卡驱动,网络驱动,等等不 同的种类,每一种类就是一个领域,你决定你的能力需要扩展到多方面,那么你可以考虑先我这里提供的这4本书来学习,通过阅读这3本书,你会发现驱动可以做 很多你意想不到的事情.本人从事开发驱动将近4年,也仅仅涉及 文件驱动,磁盘驱动以及一些小型驱动而已.这些的学习我也仅仅是根据需求来进行选择性学习.每个人都有自己的能力极限,大家要量力而行.
备注:网友可以推荐其他好书
[推荐学习资源站点]
1> http://forum.driverdevelop.com/ 国内唯一个知识点比较全的驱动交流网站
2> http://www.osronline.com/ 国外著名的驱动开发社区
3> http://www.microsoft.com/whdc/default.mspx 微软官方驱动开发技术支持
[推荐正确学习方式]
1> 认真阅读我提供的参考书籍
2> 多使用Google来解决你遇到的问题
3> 多尝试用驱动写你自己喜欢的功能
4> 提升你英文阅读能力,因为大部分有价值的资料来自于国外
5> 不要急于求成,不要浮躁,不要把驱动开发技术当做一种炫耀
[修改补充]
如果你有什么建议和补充的话,请留言跟帖,好让我更加完善这篇文章,以造福更多的初学者。
[作者]
猪头三
个人网站:http://www.x86asm.com/
[序言]
从事Windows系统下的软件研发,已走过差不多9年的时光,在这段时间里认识不少朋友。在每认识一个新的朋友的时候,我都会被问到:如何学习破解,如何逆向,这类相关的问题。那么这篇文章我将会详细的介绍正确的方式。
[本内容适用领域]
1> 基于x86-64Bit Windows系统下的商业软件软件破解
2> 商业注册码破解
3> 商业软件脱壳
4> Windows版本的游戏破解
[内容贡献者]
fly [Unpack.cn社区]
songyi [Unpack.cn社区]
kings0527 [Unpack.cn社区]
[本内容讨论社区]
[Unpack.cn社区]http://www.unpack.cn/thread-47658-1-1.html
[学习破解/逆向之前的前提基本语言和开发工具]
1> 熟悉 x86-64 CPU体系的汇编语言 [参考书籍: 王爽汇编语言程序设计]
2> 熟悉 C/C++ 语言 [参考书籍: C Primer Plus, C++ Primer Plus]
3> 熟悉 VC DELPHI 等 可利用WIN32 API的开发的工具
[学习破解/逆向之前的自身Windows系统理论]
1> Windows核心编程 [参考书籍: Windows核心编程]
2> Windows系统原理和概念 [参考书籍: 深入解析Windows操作系统]
3> Windows套接字网络编程 [参考书籍: Windows网络编程[绝版]]
4> Windows系统的PE文件格式
5> Windows SDK开发入门 [参考书籍: Windows程序设计(第5版)]
[学习破解/逆向之前的必须经验]
1> 至少有编写程序的经验
2> 至少有用过 DELPHI 或 VC 开发软件的实战经验
……等
[进入破解/逆向之后常用工具]
1> PE文件观察软件 [比如: PEid]
2> 动态调试软件 [比如: Windbg,OllyDbg]
3> 静态反编译软件 [比如: IDA]
4> 16进制查看工具 [比如: WinHEX]
5> 自动脱壳工具/脚本
……等
[进入破解/逆向之后建议添加调试理论]
1> Windows环境下的调试理论 [参考书籍: 软件调试,Windows高级调试,Windows 用户态程序高效排错]
[进入破解/逆向之后建议添加驱动理论]
1> Windows环境下驱动开发 [参考书籍: Windows驱动开发技术详解,寒江独钓:Windows内核安全编程]
[网友FAQ]
1> 进入破解领域时需要掌握什么语言?
答: 熟悉x86asm C/C++ 即可应付大部分的商业软件
2> 破解和逆向一个软件时看到的都是汇编源码,是不是只用学习汇编就可以了?
答: 要破解和逆向一个软件,只会汇编,是远远不够的。因为现代软件的编写大多数不是基于汇编来编写了,而是基于 C/C++ C# JAVA DELPHI 等高级语言来编码。作为一个破解/逆向人员来说,必须掌握2~3种高级语言,并有实际的开发经验。你才能明白一个软件的程序执行流程和原理,只要明白这 些,你才能在茫茫的汇编代码中,找到对应的程序逻辑。这样才能方便你去有目的地去破解/逆向一个商业软件的功能。
3> 要进入破解/逆向领域需要多长时间?
答: 这个要看个人资质,有天赋的话,可以在1年时间基本明白破解/逆向 的思路。 资质不高,又不够努力,那么最好放弃这个领域的研究。破解/逆向是一个深奥的领域,需要一个人的 毅力+勤奋 才能找到这个领域的乐趣。
4> 现在要进入游戏外挂开发,是否还需要具备什么其他特殊技术吗?
答: 基于现在游戏的保护强度加大,要能开发一个合格的游戏外挂,我们必须还要会一些 Windows驱动开发 Windows套接字编程。当然游戏外挂开发是一个很庞大的工程,需要多工种配合。目前来说,以1个人完成一个商业游戏外挂,是非常困难的,但是不排除国 内的卧虎藏龙的现象。因为,一个游戏外挂的开发需要涉及几个工种:
1> 游戏程序脱壳
2> 游戏网络通信协议加解密
3> 游戏认证码处理
4> 游戏内存数据搜索修改查询
5> 游戏数据导出封装
6> 游戏程序自我保护机制绕过[NP,HS,XTRAP,TP,APEX等]
……等
所以要认清事实,开一个游戏外挂,必须要面对以上这些繁琐的技术。
[修改补充]
如果你有什么建议和补充的话,请留言跟帖,好让我更加完善这篇文章,以造福更多的初学者。
教材《宏汇编语言程序设计及应用》 东南大学 傅德盛编著
参考书《IBM PC汇编语言程序设计》 清华大学 沈美明编著
这两本书入的门,比学之前想像的轻松的多的多没遇到什么障碍,呵呵
巩固一段时间后再向32位安全模式汇编进攻
1、系统自动填入
被定义为对战的段选择STACK组合类型,当含有该段的目标程序被装入存储器时,系统自动取该段基址送入SS,取段长度送SP
S_SEG SEGMENT PARA STACK ‘STACK’
DW 200 DUP(?)
S_SEG ENDS
2、用指令填入
被定义为堆栈的段在组合类型位置上缺省,在代码段中用3条MOV指令完成这个功能
S_SEG SEGMENT PARA ‘STACK’
DW 200 DUP(?)
TOP LABLE WORD ;TOP指明为WORD类型
S_SEG ENDS
C_SEG SEGMENT PARA ‘CODE’
ASSUME CS:C_SEG,SS:S_SEG
ASSUME DS:NOTHING,ES:NOTHING
START: ;指明程序一开始就执行
MOV AX,S_SEG ;填入段基址
MOV SS,AX
LEA SP,TOP ;填入栈指针TOP=200
C_SEG ENDS
END START