<转>运算符巧妙原理解析

 

最近一直研究一个对个人而言很有价值的一个LIB库的逆向。在今天下班后突然灵感闪现,这个断断续续逆了接近一周的核心管理类。终于在今天给逆完了。在最后一个函数里,碰到了之前基本没有用过的一条指令。(呵呵,高手见笑了!)当然光看单句的汇编指令,是没有办法看出具体的作用的,而且还很可能会认为原作者本来就是用汇编来实现的!呵呵,先不废话,先贴出反汇编代码一睹为快:

  mov        dword ptr ,64h   // int b
  xor         eax,eax
  cmp        dword ptr ,0
  setg        al   
  sub         eax,1
  and         eax,64h
  add         eax,0C8h
  mov         dword ptr [a],eax   // int a

     今天的LIB里面的那段迷惑的代码就跟这段代码一致,唯独a、b变量不一样。当然这个不影响结果。一开始可能会对setg这条指令的用途不了解。二是看下面蓝色的三条指令,什么又是减,又是and,又是add一些莫名奇妙的立即数。还真让人迷惑这段代码翻译成C++将怎么写。难道就一句一句的翻译?这样的话恐怕一条汇编就是一句C++。而且到了setg这条指令时还真不知道怎么单独的将其翻译成C++的什么语句。呵呵!这可能也就是逆向所带来的乐趣之一吧(个人观点)!

     好了。不废话,先分析下。首先b是一个变量,首先被赋值成0x64(100)。然后将b与0进行比较,如果有心的朋友会觉得奇怪,这个cmp的下面一条语句怎么不是跳转语句,一般都是比较后,然后根据比较结果进行跳转。否则cmp有什么意义呢?到这里的话误导我们的就是setg这条指令了。要了解它,首先得知道cmp会影响到标志寄存器的标志位。cmp是执行的减法操作,将前面的操作数减去后面的操作数。与sub的区别就是它不将减后的值放到目的操作数中。所以cmp有可能减溢出等,从而影响到了标志位。由此一来我们就算猜测都能知道setg应该与标志位有关系。然后通过资料或者奔腾X86指令集查找表(我使用的平台是INTEL X86 CPU)。就可以知道setg指令乃是大于零为真,setg al 就是如果cmp比较后大于零,al里的值将是0x01。setg的判断表达式就是(ZF=0 and SF=OF),还有个setle( ZF = 1 or SF <> OF ),等等还有几个,这里就不一一说明。有兴趣的朋友可以去查阅。

     之后蓝色的三条指令,仔细分析会发现,如果eax为0的话,sub eax, 1后eax将是0xffffffff。之后再and eax, 64h结果eax为64h,之后再是加C8h。之后就给a变量了。然后再分析另外一种情况,假如eax为1, sub eax, 1后将是0,再and等于没运算,之后才是加上C8h,后面就一样了。前面的xor eax, eax就不说了,就是把eax清零。这样一分析,可以有个大概的C++语句的锥形。那就是三目运算符:(?:)。

    好了,这句C++语句很短,那就是:

int b = 100;

int a = ( b <= 0 ) ? 300 : 200;

     哈哈,很简单吧!其实逆向就是这样,分析一大段很可能翻译过来的C++代码就一句而已。这篇文章说是巧妙原理解析。这里的巧妙之处就在于编译器很聪明(MS很厉害),这些细节的技巧可以给我们很多的启发。这个三目运算在汇编层面上,首先编译器会把后面冒号两边的数字求差,差将用于and运算。b <= 100后eax要么为1要么为0。因此后面的sub eax, 1后eax要么为0xffffffff,要么为0,为0xffffffff表示b小于等于0。b小于等于0之后的and eax, 64h也就将300 - 200的差100赋值给了eax,之后再add C8h(200),便得到了300。反之,sub eax, 1后。 eax将为0。and运算后等于就没有算上差值,之后加上冒号后面的数。就是小的200了。呵呵!这些细节,MS的程序很细心啊!

     还有就是一点,这里记录的差值是有符号的,而且是固定的冒号前面的数减去后面的数。如果前面的数小于后面的数,那么这里记录的将是一个负值,原理一样。

     再举一个例子吧:

      mov         dword ptr ,1
      xor         eax,eax
      cmp         dword ptr ,0
      setg        al   
      lea         eax,[eax+eax-1]
      mov         dword ptr [a],eax

     这个例子就不用说了,直接贴C++代码:

     int b = 1;
     int a = ( b > 0 )? 1 : -1;

     或者是BOOL类型的。注意看红色指令的巧用,它直接代替了and和add指令。大家慢慢体会!   

     如果后面冒号两边任意一边是变量的话,就不会被编译成这样子了,就会被编译成普通的跳转类似于if语句了。

     好了,这里就是一点小小的心得,当是长个记性。

 

时间: 2024-09-26 10:02:57

<转>运算符巧妙原理解析的相关文章

SQL Server 内存数据库原理解析

原文:SQL Server 内存数据库原理解析 前言 关系型数据库发展至今,细节上以做足文章,在寻求自身突破发展的过程中,内存与分布式数据库是当下最流行的主题,这与性能及扩展性在大数据时代的需求交相辉映.SQL Server作为传统的数据库也在最新发布版本SQL Server 2014中提供了新利器 SQL Server In-Memory OLTP(Hekaton),使得其在OLTP系统中的性能有了几十倍甚至上百倍的性能提升,本篇文章为大家探究一二.         大数据时代的数据如何组织应

Skinned Mesh原理解析和一个最简单的实现示例

Skinned Mesh原理解析和一个最简单的实现示例   作者:n5 Email: happyfirecn@yahoo.com.cn Blog: http://blog.csdn.net/n5 2008-10月   Histroy: Version:1.01  Date:2008-11-01        修改了一些不精确的用语 Version:1.00 Date:2008-10-19     讲述骨骼动画的资料很多,但大部分都是针对DX8或DX9的SkinnedMesh进行讲解.我觉得对于骨

[IT]JSONP跨域的原理解析

JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为"Same-Origin Policy"(同源策略).这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript 只能访问与包含它的文档在同一域下的内容. JavaScript这个安全策略在进行多iframe或多窗口编程.以及Ajax编程时显得尤为重要.根据这个策略,在baidu.com下的页面中包含的JavaScript代码

Android中微信抢红包插件原理解析及开发思路_Android

一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导致了.或许是网络的原因,而且这个也是最大的原因.但是其他的不可忽略的因素也是要考虑到进去的,比如在手机充电锁屏的时候,我们并不知道有人已经开始发红包了,那么这时候也是让我们丧失了一大批红包的原因.那么关于网络的问题,我们开发者可能用相关技术无法解决(当然在Google和Facebook看来的话,他们

Android代码入侵原理解析(一)

Android代码入侵原理解析(一)           1.代码入侵原理 代码入侵,或者叫代码注入,指的是让目标应用/进程执行指定的代码.代码入侵,可以在应用进行运行过程中进行动态分析,也是对应用进行攻击的一种常见方式.我把代码入侵分为两种类型:静态和动态.静态代码入侵是直接修改相关代码,在应用启动和运行之前,指定代码就已经和应用代码关联起来.动态代码入侵是应用启动之后,控制应用运行进程,动态加载和运行指定代码. 2.静态代码入侵 静态代码入侵,有直接和间接的手段. 直接手段是修改应用本身代码

秋色园QBlog技术原理解析:性能优化篇:字节、缓存、并发(十二)

文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色园QBlog技术原理解析:UrlRewrite之无后缀URL原理(三) --介绍如何实现无后缀URL 4: 秋色园QBlog技术原理解析:UrlRewrite之URL重定向体系(四) --介绍URL如何定位到处理程序 5: 秋色园QBlog技术原理解析:Module之页面基类设计(五) --介绍创建

秋色园QBlog技术原理解析:性能优化篇:access的并发极限及超级分库分散并发方案(十六)

上节回顾:   上节 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五) 中, 介绍了 秋色园QBlog 在性能优化方面,从技术的优化手段,开始步入数据库设计优化,并从数据的使用情况上进行了分析,从而将文章内容进行分离,得到新的分表,由于内容比较大,进而分了库,达到一种基础减压.   本节内容:   本节将介绍秋色园 QBlog 的Super分库方案,以及何以如此Super分库的原因.   描述说明:   在进行上了上节的分库方案后,虽然感觉一度秋色园QBlog的访

秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)

上节概要:   上节 秋色园QBlog技术原理解析:性能优化篇:access的并发极限及分库分散并发方案(十六) 中, 介绍了 Access的并发上限,及从某种程度上 秋色园QBlog 针对并发上限进行了多个数据的划分,从而最大并发上限从64提升到64*N(个数据库),虽然总和的最大并发值是上升了,但是单个库的最大值并没有变化,或者说单个表的最大并发值没有发生变化,上限仍是64. 于是,对于频繁产生更新操作的访问计数器(用户表及文章表),是该进入优化的方案了.   本节概要:   本节将介绍秋色

秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)

文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色园QBlog技术原理解析:UrlRewrite之无后缀URL原理(三) --介绍如何实现无后缀URL 4: 秋色园QBlog技术原理解析:UrlRewrite之URL重定向体系(四) --介绍URL如何定位到处理程序 5: 秋色园QBlog技术原理解析:Module之页面基类设计(五) --介绍创建