探索黑客技术攻防,实战研究与安全创新

导航菜单

打造完美花指令——浅谈花指令平衡原理

相信很多朋友对花指令都不陌生,随着学习的不断深入,汇编语言功底也在不断的增强,但是更多的朋友仅仅是停留在会用的基础上,而对花指令并没有实际的理解,想成为一名真正的高手,就要从更基础的方面下手。我查阅了汇编语言的相关书籍,又结合自已的经验,配合了相关实例,通过花指令来带领大家近一步的了解汇编语言的相关知识,本文正是由此而写的。

QQ截图20170118170253.png

一、知识准备

什么是堆栈?堆栈是一个特定的RAM存储区,主要用于暂存数据和断点地址。堆栈一端固定,称为栈底,另一端浮动,称为栈顶。先压入的数据后弹出,后压入的数据先弹出,就像盖楼房一样,要从下往上盖(以Intel CPU为例),压人数据的时候,要先进7964H,再进34CDH,出栈的时候要先出l245H,再出AB48H(高字节存高地址,低字节存低地址,压栈出栈都是2的倍数的字节数)。

什么是寄存器?寄存器分通用寄存器(EAX、EBX、ECX、EDX、ESP、EBP、ESI、EDI)、段寄存器(CS代码段、SS堆栈段、DS数据段、ES附加段……)、指令指针寄存器(EIP)、标志寄存器(EFLAGS)。其中,我们经常用到的是通用寄存器以及指令指针寄存器EIP。EIP用来存放当前指令的偏移地址,用于指向下一条指令。标志寄存器主要用于表示运算结果的进位、符号位,奇偶等信息,比如JE、JNE、JO等跳转语句,都是依靠标志寄存器来实现的。

二、花指令原理

“花指令的原理就是堆栈平衡”,相信大家对于这句话也都不陌生,因为许多关于花指令的文章都会这么写,但我认为这句话说的并不够完善,实际上花指令就是程序中一些无用的代码,它的存在与否并不影响程序的正常运行,花指令不仅仅要做到堆栈平衡,还要做到“寄存器平衡”及“标志位平衡”。可能有读者要问了,什么是堆栈平衡?什么是寄存器平衡?什么是标志位平衡呢?下面我将以实例来向大家说明。

三、CALL指令与堆栈平衡

说到堆栈平衡,就不能不说CALL指令(其实,壳与ESP定律,都是利用的堆栈平衡原理),相信大家对这条指令也不陌生吧?是的,就是调用子程序命令,而CALL的工作过程,能更好的帮助我们理解堆栈平衡。

实际上,CALL这条命令在执行后对应两个步骤:1、将CALL的下一条指令地址压人堆栈。2、JMP到CALL后边的地址。

先将00409019这个地址压人堆栈,然后“JMP00409C9”去执行子程序中的内容。当子程序执行完毕后,需要返回到CALL的下一条指令处,这时就需要RETN了。RETN是如何工作的呢?实际上就是JMP跳到当前ESP指向的地址,也就是当初执行CALL指令压人的地址。因此,在子程序中,对堆栈进行操作,一定要保证指令成对出现,比如有“PUSH EAX”,就要有“POP EAX”,这样在最后执行RETN的时候,地址指向才不会出错,这就是著名的堆栈平衡原理!如果没有保持堆栈平衡,那么RETN就会跑飞了,程序自然也就出错了(有过汇编语言编程经验的朋友都应该知道,在进行静态检查的时候,其中有一条重点,就是检查“堆栈平衡”)。

四、寄存器平衡

前文中已经提到,由于花指令是无用代码,并不会改变程序原有值,所以当使用ADD、SUB之类的指令,对EAX、EBX等寄存器进行改变,应在之后将值恢复原样。EAX加5减5后,等于没改变什么,很好理解吧,这就是寄存器平衡。

五、标志位平衡

标志位对于大家来说应该是比较陌生的,但实际上我们在加花指令以及软件破解中所用到的重要的转跳语句,都是根据标志位来判断的(JMP不算,它太霸道了)。常用的几个标志位如下:CF进位标志位、PF奇偶标志位、AF辅助进位标志位、ZF零标志位、SF符号标志位、OF溢出标志位。在OD中的寄存器窗口中我们可以看到标志位的信息,比如C、P、A、Z、S、T、D、O,都是用来表示标志位的。大多数指令在执行的时候,都会影响标志位,如果我们编写的花指令中,有影响标志位的指令(ADD、SUB、INC、DEC等都会影响),花指令之外的转跳语句将不会按照原有的流程执行,那该怎么办呢?这就应该用到PUSHF与POPF指令了。

624196-20151117165544218-658459921.png

PUSHF把所有标志位的内容暂存到堆栈中,POPF功能与PUSHF相反,将堆栈中的数据弹出送到标志位中。关于标志位,涉及到的汇编语言知识就比较多了,有兴趣的朋友可以自己查阅相关书籍进行学习,这里就不再详细介绍了。

六、实例说明

好了,介绍了这么多花指令的平衡原理,大家是不是已经跃跃欲试,要自己编写出完美的花指令呢?下面这个小例子将综合运用前文中所包含的原理知识,来帮助大家更好的理解这些内容。

七、总结

通过本文我们所学到的知识点如下:

1、花指令就是无用指令:原理是堆栈平衡,寄存器平衡,标志位平衡。

2、堆栈平衡原理的概念,CALL指令的详细执行过程。

3、汇编语言中,标志位的作用。

4、自己能编写完美的花指令。 

本文内容所提及均为本地测试或经过目标授权同意,旨在提供教育和研究信息,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,作者不鼓励或支持任何形式的非法破解行为。