首先使用IDA_PRO打开myvm,然后继续打开Sub_CE0函数,按下F5获取C语言伪代码。
FILE *v1; // rax
FILE *v2; // rbx
__int64 v3; // r15
void *v4; // r14
char *v5; // rbx
上述代码定义V1,V2文件变量;V3是64位整型变量;V4是空的动态数组;V5是字符型指针变量。
v1 = fopen(a1, "rb");
v2 = v1;
上述代码含义是打开a1文件,然后操作方式为读取,V2=V1
,这段代码不太明白,猜测是V1来打开文件,V2来进行后续操作,以防止出现某种错误。
if ( !v1 )
return 0LL;
fseek(v1, 0LL, 2);
v3 = ftell(v2);
fseek(v2, 0LL, 0);
v4 = malloc(0x10000uLL);
memset(v4, 0, 0x10000uLL);
fread(v4, 1uLL, v3, v2);
fclose(v2);
上述代码的含义是如果V1不存在或空,则返回0LL;当V1不空时,则进行下述操作:
fseek()函数的作用是把指针放到V1文件末尾偏移量为0LL的位置;
ftell()函数返回的是文件相对于文件首的位置的偏移量;即V3等于V2文件的大小;
把指针放到V2文件首的位置;
malloc()的作用是分配空间,空间的大小为0x10000uLL;
memset(v4,0,0x10000uLL)
把V4动态数组大小为0x10000uLL空间的所有数赋为0,即V4所有内容全为0;
fread(v4, 1uLL, v3, v2)
将V2的1uLL空间的数赋给V4,赋V3次;
close(v2)
将V2文件关闭;
_mm_storeu_si128(
(__m128i *)&unk_202018 + 4096,
_mm_unpacklo_epi64((__m128i)(unsigned __int64)&unk_202018, (__m128i)((unsigned __int64)&unk_202018 + 0x8000)));
memcpy(y, v4, 0x10000uLL);
_mm_storeu_si128((__m128i *)&unk_202018 + 4097, (__m128i)0LL);
*(_QWORD *)((char *)&unk_202018 + 65566) = 0LL;
*((_WORD *)&unk_202018 + 32785) = 32764;
*((_QWORD *)&unk_202018 + 8197) = 0LL;
v5 = (char *)&unk_202018 + 0x10000;
free(v4);
return v5;
上述代码的意思为:
_mm_storeu_si128(__m128i *a,__m128i b)
函数的意思为将b赋值给a;
_mm_unpacklo_epi64(__m128i a,__m128i b)
低64位交错,返回的是一个128位的数据。
则上述
_mm_storeu_si128()
内的内容意思为:&unk_202018
地址的低64位和&unk_202018 + 0x8000
的低64位交错,然后赋值为)&unk_202018
地址向下移动4096位;
` memcpy(&unk_202018, v4, 0x10000uLL)
将V4内所有内容拷贝到原
&unk_202018`地址中去;
_mm_storeu_si128((__m128i *)&unk_202018 + 4097, (__m128i)0LL)
将0LL赋值给&unk_202018
向下移动4097位地址中去;猜想进过上述几轮操作,只剩下&unk_202018
向下移动的第4096位才有数据,其余127位都为0;
_QWORD *
是1bit变量的数据类型;
_WORD *
是1个字变量的数据类型;
*(_QWORD *)((char *)&unk_202018 + 65566) = 0LL
将0LL赋值到&unk_202018
向下移动65566位的地址中;
` *((_WORD *)&unk_202018 + 32785) = 32764
将32764赋值到
&unk_202018`向下移动32785位的地址中中;
*((_QWORD *)&unk_202018 + 8197) = 0LL
将0LL赋值到&unk_202018
向下移动8197位的地址中;
v5 = (char *)&unk_202018 + 0x10000
将&unk_202018
向下移动0x10000地址中的数转化为字符指针类型然后赋值给V5;
free(v4)
释放V4的地址空间;
return v5
返回V5的值;
总结
此函数的意思为,将a1的文件打开进行一系列操作,然后返回某个地址的值,所以要得到指令,需要对这个地址进行分析,使用的工具应为Linux内的gdb。