2

I've a binary (openend in IDA v7) that uses GUID variables to manipulate something. Whenever I see any variable with GUID data type there always be a _mm_store_si128() or _mm_storeu_si128() functions. I've seen the definitions in Intel Intrinsics Guide. But the article shows that those functions only stores 128-bits of integer data from a variable into memory. The full subroutine is lengthy so I add a small section. Here is an example:

_mm_store_si128

In pseudocode:

if ( RtlGUIDFromString(&GuidString, Guid) >= 0 )
    {
      _mm_store_si128(&v18, v10);
      v18.m128i_i64[1] -= v11;
      v18.m128i_i64[0] = v10.m128i_i64[0] + 2 * v11;
      _mm_store_si128((__m128i *)&GuidString, v18);
      sub_140010DC0(&v18, (__m128i *)&GuidString);
      v10 = v18;
    }

So my questions are: Does those functions only copy 128bit data? Is it same as memcpy() or memmove()? If yes then why not IDA shows those functions (later ones)? Are there any hidden deep relation between _mm_store_si128 and CPU instructions?

1 Answer 1

2

1) The _mm_store_si128 intrinsic indeed stores 128-bits to memory. 128-bits is 16 bytes which is exactly the size of a GUID.

2) The difference between _mm_store_si128 and memcpy/memmove is that whilst both take a pointer to the destination address in memory, the intrinsic takes a value as the source and memcpy/memmove take a pointer to a source in memory. See the function prototypes -

void _mm_store_si128 (__m128i* mem_addr, __m128i a);
void * memcpy ( void * destination, const void * source, size_t num );

3) It's not really a hidden deep relationship. In most cases the intrinsics have a 1-1 relationship with CPU instructions. These are documented in Volume 2 of the Intel 64 and IA-32 Architectures Software Developer Manuals.

_mm_store_si128  <=> MOVDQA with a memory destination
_mm_storeu_si128 <=> MOVDQU with a memory destination
2
  • But sometimes it doesn't treat variable as whole 128bit or GUID type (4 mem struct). Like following allocation: x=a->m128i_i64[0] and y=a->m128i_i64[1].
    – Biswapriyo
    May 16, 2018 at 19:54
  • A GUID is defined as a structure with a number of fields. The original compiler here was smart enough to understand that the whole structure can be stored using a single _mm_store_si128 instruction. If an access is being made to part of the GUID, the memory access will be sized accordingly. Here separate modifications are being made to the first and second 64-bit parts respectively.. The original compiler is using operations on 64-bit general purpose registers to do this.
    – Ian Cook
    May 16, 2018 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.