有人可以解释的malloc的含义(20 * C | - (20 *(无符号__int64)(无符号整数),C>!> 32 = 0)) [英] Can someone explain the meaning of malloc(20 * c | -(20 * (unsigned __int64)(unsigned int)c >> 32 != 0))

查看:161
本文介绍了有人可以解释的malloc的含义(20 * C | - (20 *(无符号__int64)(无符号整数),C>!> 32 = 0))的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在由IDA反编译生成code我看到前pressions这样的:

 的malloc(20 * C |  - (20 *(无符号__int64)(无符号整数),C>> 32 = 0)!)
的malloc(!6 * N | - (3 *(无符号__int64)(unsigned int类型)(2 * N)GT;> 32 = 0))

有人能解释这些计算的目的是什么?

c和n为INT(有符号整数)值。

更新。

原始C ++ code与MSVC编译为32位平台。

这里的组装code以上反编译的C code二线(的malloc(6 * ..)):

  MOV ECX,[EBP + pThis]
MOV [ECX + 4],EAX
MOV EAX,[EBP + pThis]
MOV EAX,[EAX]
SHL EAX,1
异或ECX,ECX
MOV EDX,3
MUL EDX
濑户CL
NEG ECX
或ECX,EAX
MOV ESI,ESP
推ECX;尺寸
调用DWORD PTR DS:__ imp__malloc


解决方案

我猜原始出处code使用的C ++ 运营商分配的数组并用Visual C ++编译。作为user3528438的回答表示该code是为了prevent溢出。具体地说,它是一个32位无符号饱和乘法。如果该乘法的结果将超过4,294,967,295更大,一个32位无符号数的最大值,其结果是夹紧或饱和来表示最大值。

由于Visual Studio 2005中,微软的C ++编译器有生成code,以防止溢出的。例如,我可以生成汇编code,可以通过编译下面用Visual C ++被反编译到您的例子:

 的#include<&stdlib.h中GT;无效*
运营商新的[](为size_t N){
        返回的malloc(N);
}的struct {
        所以char a [20];
};结构T {
        烧焦一个[​​6];
};空虚
美孚(INT N,S ** S,T **吨){
        * S =新S [N];
        * T =新的T [N * 2];
}

其中,与Visual Studio 2015年的编译器生成下面的汇编code:

MOV ESI,DWORD PTR _n $ [ESP]
    异或ECX,ECX
    MOV EAX,ESI
    MOV EDX,20; 00000014H
    MUL EDX
    濑户CL
    NEG ECX
    或ECX,EAX
    推ECX
    调用_malloc
    MOV ECX,DWORD PTR _s $ [ESP + 4]
;第19行
    MOV EDX,6
    MOV DWORD PTR [ECX],EAX
    异或ECX,ECX
    LEA EAX,DWORD PTR [ESI + ESI]
    MUL EDX
    濑户CL
    NEG ECX
    或ECX,EAX
    推ECX
    调用_malloc

大多数反编译前pression是实际上意味着处理只是一个汇编语句。汇编指令濑户CL CL设置为1,如果previous MUL指令溢出,否则CL设置为0。同样,前pression 20 *(无符号__int64)(无符号整数),C>> 32!= 0 计算为1如果 20 * C 溢出的结果,计算结果为0。

如果这个溢出保护是不是有和结果 20 * C 其实没有那么溢出调用的malloc 可能会成功,但分配较少的内存比预期的计划。然后该程序可能会写过去实际分配的存储器和存储器垃圾其它位的结束。这将相当于缓冲区溢出,一个可能被黑客利用的潜在

In decompiled code generated by IDA I see expressions like:

malloc(20 * c | -(20 * (unsigned __int64)(unsigned int)c >> 32 != 0))
malloc(6  * n | -(3  * (unsigned __int64)(unsigned int)(2 * n) >> 32 != 0))

Can someone explain the purpose of these calculations?
c and n are int (signed integer) values.

Update.
Original C++ code was compiled with MSVC for 32-bit platform.
Here's assembly code for second line of decompiled C-code above (malloc(6 * ..)):

mov     ecx, [ebp+pThis]
mov     [ecx+4], eax
mov     eax, [ebp+pThis]
mov     eax, [eax]
shl     eax, 1
xor     ecx, ecx
mov     edx, 3
mul     edx
seto    cl
neg     ecx
or      ecx, eax
mov     esi, esp
push    ecx             ; Size
call    dword ptr ds:__imp__malloc

解决方案

I'm guessing that original source code used the C++ new operator to allocate an array and was compiled with Visual C++. As user3528438's answer indicates this code is meant to prevent overflows. Specifically it's a 32-bit unsigned saturating multiply. If the result of the multiplication would be greater than 4,294,967,295, the maximum value of a 32-bit unsigned number, the result is clamped or "saturated" to that maximum.

Since Visual Studio 2005, Microsoft's C++ compiler has generated code to protect against overflows. For example, I can generate assembly code that could be decompiled into your examples by compiling the following with Visual C++:

#include <stdlib.h>

void *
operator new[](size_t n) {
        return malloc(n);
}

struct S {
        char a[20];
};

struct T {
        char a[6];
};

void
foo(int n, S **s, T **t) {
        *s = new S[n];
        *t = new T[n * 2];
}

Which, with Visual Studio 2015's compiler generates the following assembly code:

    mov esi, DWORD PTR _n$[esp]
    xor ecx, ecx
    mov eax, esi
    mov edx, 20                 ; 00000014H
    mul edx
    seto    cl
    neg ecx
    or  ecx, eax
    push    ecx
    call    _malloc
    mov ecx, DWORD PTR _s$[esp+4]
; Line 19
    mov edx, 6
    mov DWORD PTR [ecx], eax
    xor ecx, ecx
    lea eax, DWORD PTR [esi+esi]
    mul edx
    seto    cl
    neg ecx
    or  ecx, eax
    push    ecx
    call    _malloc

Most of the decompiled expression is actually meant to handle just one assembly statement. The assembly instruction seto cl sets CL to 1 if the previous MUL instruction overflows, otherwise it sets CL to 0. Similarly the expression 20 * (unsigned __int64)(unsigned int)c >> 32 != 0 evaluates to 1 if the result of 20 * c overflows, and evaluates to 0 otherwise.

If this overflow protection wasn't there and the result of 20 * c did actually overflow then the call to malloc would probably succeed, but allocate much less memory than the program intended. The program would then likely write past the end of the memory actually allocated and trash other bits of memory. This would amount to a buffer overrun, one that could be potentially exploited by hackers.

这篇关于有人可以解释的malloc的含义(20 * C | - (20 *(无符号__int64)(无符号整数),C&GT;!&GT; 32 = 0))的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆