main函数
今天对main函数的汇编代码结合伪代码进行分析,使用F5大法生成伪代码。
1 | char *v4; // rbx |
首先对栈进行初始化操作,然后判断a4(edi)==2?
不成立就进行print操作,输出file流文件,然后跳C3D出栈。
成立的话会调用一个signal函数,查询了一下signal(a1,a2),a1为要进行处理的信号,这里为2;a2为处理方式,一般来说处理方式一般有三种:
SIG_IGN 忽略该信号
SIG_DFL 恢复对信号的系统默认处理
sighandler_t 执行handler函数
在此处就需要执行handler函数,使用handler处理信号量2.
令rdi=rbx+8,调用sub_CE0
1 | FILE *v1; // rax |
sub_CE0里先打开a1文件,如果是空就可以直接返回了。不为空,就定位文件头和尾,v3是文件首的偏移字节数,再动态分配一个内存,memset对内存初始化操作。读取文件中的数据到新内存中,关闭文件流。之后一大段SSE指令,把一些内容放到&unk_202018中,又将&unk_202018 + 65536赋值给v5.释放内存空间,返回。
总结
在分析过程中遇到几个函数,进行整理。
(1)signal(a1,a2)这个在之前分析代码时写过。
(2)int fseek(FILE stream, long offset, int fromwhere)把fp的文件读写位置指针移到指定的位置.
SEEK_SET 0 文件开头
SEEK_CUR 1 文件当前位置
SEEK_END 2 文件末尾
(3)long ftell(FILE fp) 得到流式文件的当前读写位置,其返回值是当前读写位置偏离文件头部的字节数
(4)void malloc(size_t size) 用于申请一块连续的指定大小的内存块区域,以void 类型返回分配的内存区域地址
(5)void memset(void s,int c,size_t n) 将已开辟内存空间 s 的首 n 个字节的值设为值 c。
(6)size_t fread( void buffer, size_t size, size_t count, FILE stream )
buffer 是读取的数据存放的内存的指针
size 是每次读取的字节数
count 是读取次数
stream 是要读取的文件的指针
(7) void _mm_storeu_si128( m128i * p, m128i a) 可存储128位数据,将__m128i 变量a的值存储到p所指定的变量中去
(8)_mm_unpacklo_epi64 (m128i a, m128i b) 返回一个m128i的寄存器,它将寄存器a和寄存器b的低64bit数以64bit为单位交织在一块。
(9)void memcpy(void str1, const void * str2, size_t n) 从存储区 str2 复制 n 个字符到存储区 str1
由于代码量比较大,今天只分析一小部分,明天继续分析。