Invalid read / write error while executing legacy x64 compatible code.

I have the following function MyType::Is_Inst ()that throws an invalid memory access error when returning in 64-bit mode, but not in 32-bit mode:

MyType MyType::Is_Inst () {
    unsigned char Bar=0;    
    MyType Foo={0};    
    return Foo;
    }

Looking at the dismantle + step, the program crashes in a line

mov  dword ptr [rax],ecx

... when the program basically tries to dereference the original value of% rdx (since the function was called), which is now in% rax. However,% rdx is simply inactive from the previous function call.

The last time I had such a problem, it was because I was missing from some compilation flags, etc. Should there be any settings for x64 unmanaged C ++ projects? Are there other reasons why I can see this behavior?

I can post more showdown if you need it.


MyType :

class __declspec(dllexport) MyType {
public:
    union {
        struct {
            unsigned int    Id     : 23;
            unsigned int    Flag   : 1;  
            unsigned int    Type   : 4;  
            unsigned int    Unused : 4;  /* 32 bits total */
            };

        unsigned int    All_Bits;          /* Full 32 bits of MyType */
        };

     /* There are some function definitions here, but no other 
        variables, aside from some statically defined ones. */
     };

UPDATE: , Is_Inst(), . , .

// MyType MyType::Is_Inst () {
// uchar Bar=0;
// MyType Foo={0};
   mov         dword ptr [rdx],0 /* %rdx is 0x17, from a prev fn call. */ 

// return Foo;
   mov         rax,rdx  
// }
   ret 

, Is_Inst():

...
for (Counter=0; Counter<N_Items; Counter++) {
    ...
    myOther32BitType = arrayOfMyOtherTypes [Counter]; /* Debugger shows this is ok. */ 

    if (myOther32BitType.8BitField==UNEQUAL_ENUM_VALUE) {
        /* Some stuff that doesn't happen. */
        }

    /* myOther32BitType.8BitField==0x17, so %rdx gets set to 0x17. */
    else if (strchr((char*)Uchar_Table_Of_Enum_Values, myOther32BitType.8BitField)) continue;

    /* %rdx gets set to 0x17 again. */
    else if (strchr((char*)Other_Uchar_Table_Of_Enum_Values,  myOther32BitType.8BitField)) continue;

    else if ( myOther32BitType.8BitField==EQUAL_ENUM_VALUE) {
        if (myType.Is_Inst ().All_Bits) { /* Is_Inst() called here. */
            return false;
            }
        ...
        }
    ...
    }
+3
3

, Qt VS2010. Microsoft Connect . ​​ 1 (SP1). SP1 , , , ( , ).

0
else if (strchr((char*)Other_Uchar_Table_Of_Enum_Values,  myOther32BitType.8BitField)) continue;

It looks terribly wrong. Instead of resorting to completely unnecessary casting, you should use std::find.

In fact, all of your code looks littered with insecure C-style code. Where are the memory management objects?

-1
source

All Articles