工作需要逆向微信部分代码,遇到了这个指令集,资料很少,整理如下:
xmm0~xmm7 128位
mm0~mm7 64位
byte 一个字节、8bit
dword 双字,4个字节,32bit
qword 四字,8个字节,64bit
指令含义参照如下英文链接:
https://www.felixcloutier.com/x86/index.html
movdqu
movdqu xmm7,dqword ptr ds:[ebx] 从ebx所指向的地址中取双字存入xmm7
移入两个qword,可以在未对其的内存中操作,movdqa只能在对其内存中操作。
pextrb/pextrd/pextrq
pextrd edx,xmm7,0x3 //从xmm7中偏移3位抽取一个双字存储到edx。同理有pextrq,pextrb 根据最后一位字母决定抽取大小。byte、dword、qword分别代表单字,四字节和八字节。目标项可以是寄存器或内存地址,当是寄存器时,高位置零。
使用IDA F5反编译出的代码如下:
PEXTRB: int _mm_extract_epi8 (__m128i src, const int ndx);
PEXTRD: int _mm_extract_epi32 (__m128i src, const int ndx);
PEXTRQ: __int64 _mm_extract_epi64 (__m128i src, const int ndx);
pinsrb/pinsrd/pinsrq
pinsrd xmm7,ebp,0x3 // 在xmm7的03偏移的位置,插入ebp
同上,b,d,q代表不同的长度。
反编译如下:
PINSRB: __m128i _mm_insert_epi8 (__m128i s1, int s2, const int ndx);
PINSRD: __m128i _mm_insert_epi32 (__m128i s2, int s, const int ndx);
PINSRQ: __m128i _mm_insert_epi64(__m128i s2, __int64 s, const int ndx);
bswap
bswap ebx //将ebx反序
pshufb
pshufb xmm1,xmm2 根据xmm2重写xmm1
xmm2共16个字节,
解释:每个src 寄存器是128bit=16byte, 每个byte的最高位存放是否shuffle, 如果是1,则dest对应byte 置零。
否则,该byte的低4byte对应了相应的移动位置。
for i = 0 to 15 { if (SRC[(i * 8)+7] = 1 ) then DEST[(i*8)+7..(i*8)+0] ← 0; else index[3..0] ← SRC[(i*8)+3 .. (i*8)+0]; DEST[(i*8)+7..(i*8)+0] ← DEST[(index*8+7)..(index*8+0)]; endif } DEST[VLMAX-1:128] ← 0
pshufd
pshufd xmm3, xmm1, 80h
PSHUFD xmm1, xmm2/m128,imm8 | 按照 imm8 中的编码对 xmm2/m128 中的双字执行乱序处理,结果存储到 xmm1。 |
pshufd XMM,XMM/m128,imm8(0~255)
描述:
将源存储器的4个双字由imm8指定选入目的寄存器,内存变量必须对齐内存16字节.
高64位 | 低64位
源寄存器: (11) | b(10) | b(01) | b(00)
目的寄存器排列结果: b(00~11) | b(00~11) | b(00~11) | b(00~11)
例:
当 XMM1 = 0x 11111111 22222222 33333333 44444444,
执行 pshufd XMM0,XMM1,11 01 01 10b
则 XMM0 = 0x 11111111 33333333 33333333 22222222
pshufw
pshufw mm2,mm1,0xC0 在mm1中取 c0 个单元存入mm2
PSHUFW: __m64 _mm_shuffle_pi16(__m64 a, int n)
movups
mov + u + ps 128位的传值。
xorps
xor + ps 128位异或
pxor
同上,没找到区别