您的位置:首页 > 其它

VC 编译器将除法优化为乘法的策略

2014-03-26 11:40 337 查看
这是我今天破解一个crackme看到的 

XOR EAX,ESI

  ADD ESP,8

  MOV ECX,EAX

  MOV EAX,55555556

  IMUL ECX

  MOV EAX,EDX

  POP ESI

  SHR EAX,1F

  ADD EDX,EAX

 由于技术欠缺,对汇编不熟悉,转换成如下表达式,发现不会算,遂google之15890084????????h=(x shr 1f +x)=55555556h*(注册码h xor 55564949h)

发现原来是VC 编译器将除法优化为乘法的结果,好不容易搞明白,贴出两个对我帮助很大的帖子http://bbs.pediy.com/archive/index.php?t-68849.html

http://www.cppblog.com/huyutian/articles/124742.html

并作备份如下:

今天调试一个程序时遇到了一段奇怪的汇编代码

        mov     eax, 68DB8BADh

        push    edi

        movsx   ecx, word ptr [esi+0Eh]

        imul    ecx

        sar     edx, 0Ch

        mov     eax, edx

        shr     eax, 1Fh

        add     edx, eax

看了半天也没看明白,主要是这个68DB8BADh出现的很突兀,与前后代码在逻辑上都不相关联。到网上搜了下,还居然找到了答案。原来这是一段编译器将除法优化为乘法运算的典型代码。众所周知,除法是最耗CPU的,能够转化为等效的乘法就要快得多了。但不是每次除法都能这么优化的。对于一些特定数作为被除数时,这种优化还是很有效的。
http://www.thesolver.it/Manuali/Factotum/source/076.htm这里列出了一些典型数的除法转换表。



这个表是32位运算下除法转换为乘法的一些案例。比如68DB8BADh这个魔术数就是用来转换除以625的。要计算x/625 = (x * 68DB8BADh) >>8.所以上面的代码其实就是计算[esi +0Eh] / 10000.

下面这个表是64位运算时除法转换为乘法的一些魔术数,摘录在此,以防备忘



如果想搞清楚相关的运算原理可以看该网站的Chapter 10. Integer Division by Constants ,网址是http://www.thesolver.it/Manuali/Factotum/source/062.htm

大家也可以自己编一段小程序验证一下。

 1 #include <stdio.h>
 2 
 3 int main(int argc, char* argv[])
 4 {
 5     int a = getchar();
 6     int b = a / 10000;
 7     printf("a=%d\nb=a/10000=%d\n", a, b);
 8     return 0;
 9 }
10 

在VC2008下设置项目编译属性Assembler Output,选择输出汇编代码,看看编译出来的代码与上面的完全一致。



———————————————————————————————————————————

#include <stdio.h>

int main()

{

 int a;

 int b;

 b = rand();

 a = b/9;

 printf("b = %d, a= %d", b , a);

 getchar();

}

.text:00401000                   ; int __cdecl main(int argc, const char **argv, const char *envp)

.text:00401000                   _main proc near ; CODE XREF: start+AFp

.text:00401000 E8 0E 02 00 00        call _rand

.text:00401005 8B C8                 mov ecx, eax

.text:00401007 B8 39 8E E3 38        mov eax, 38E38E39h

.text:0040100C F7 E9                 imul ecx

.text:0040100E D1 FA                 sar edx, 1

.text:00401010 8B C2                 mov eax, edx

.text:00401012 C1 E8 1F              shr eax, 1Fh

.text:00401015 03 D0                 add edx, eax

.text:00401017 52                    push edx

.text:00401018 51   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: