C语言字符串混淆,C/C++知识点之linux 下字符混淆器

本文主要向大家介绍了C/C++知识点之linux 下字符混淆器,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

f10d364ec27d361ff5c1706bdca805d1.png//gcc elfscure.c -o elfscure#include #include #include #include #include #include #include #include #include #include #include #define SHT_VERSYM  0x6fffffff#define SHT_VERNEED 0x6ffffffe//SHF_WRITE#define W 1//SHF_ALLOC#define A 2//SHF_EXECINSTR#define X 4//功能struct options{    //字符串表随机化    char smix;    char verbose;    //保持与字符串名称一致的区段类型    char sh_type;    //保持区段标志与字符串名称一致    char sh_flags;

} opts;struct stat st;//节类型struct section_type {    char name[64];    uint32_t type;    int flags;

};struct section_type section_type[] = {{"".interp"",           SHT_PROGBITS,     A },

{"".hash"",         SHT_HASH,         A },

{"".note.ABI-tag"",  SHT_NOTE,        A },

{"".gnu.hash"",     SHT_GNU_HASH,     A },

{"".dynsym"",       SHT_DYNSYM,       A },

{"".dynstr"",       SHT_STRTAB,       A },

{"".gnu.version"",   SHT_VERSYM,      A },

{"".gnu.version_r"", SHT_VERNEED,     A },

{"".rel.dyn"",          SHT_REL,          A },

{"".rel.plt"",          SHT_REL,          A },

{"".init"",         SHT_PROGBITS,     A|X},

{"".plt"",              SHT_PROGBITS,     A|X},

{"".text"",         SHT_PROGBITS,     A|X},

{"".fini"",         SHT_PROGBITS,     A|X},

{"".rodata"",       SHT_PROGBITS,     A },

{"".eh_frame_hdr"",  SHT_PROGBITS,        A },

{"".eh_frame"",     SHT_PROGBITS,     A },

{"".ctors"",        SHT_PROGBITS,     W|A},

{"".dtors"",        SHT_PROGBITS,     W|A},

{"".jcr"",              SHT_PROGBITS,     W|A},

{"".dynamic"",          SHT_DYNAMIC,      W|A},

{"".got"",              SHT_PROGBITS,     W|A},

{"".got.plt"",          SHT_PROGBITS,     W|A},

{"".data"",         SHT_PROGBITS,     W|A},

{"".bss"",              SHT_NOBITS,       W|A},

{"".shstrtab"",      SHT_STRTAB,      0 },

{"".symtab"",       SHT_SYMTAB,       0 },

{"".strtab"",       SHT_STRTAB,       0 },

{"""",              SHT_NULL            }

};//用于获取节名的新偏移量int STBL_OFFSET(char *p, char *string, int count){    char *offset = p;    while (count-- > 0)

{        while (*offset++ != '.')

;        if (strcmp(string, offset-1) == 0)            return ((offset - 1) - p);        //有的节名有俩种        if (!strncmp(offset-1, "".rel."", 5) || !strncmp(offset-1, "".gnu."", 5)

||  !strncmp(offset-1, "".not."", 5) || !strncmp(offset-1, "".got."", 5))            while (*offset++ != '.');

}    return 0;

}int strused(char *s, char **used_strings, int count){    int i;    for (i = 0; i 

}int main(int argc, char **argv){   //文件头

Elf32_Ehdr *ehdr;    //节表

Elf32_Shdr *shdr, *shp;    //程序头

Elf32_Phdr *phdr;    //字符串表    char *StringTable, *NewStringTable;    char **STBL, **STBL_USED_STRINGS;    char *p, exec[255];    char tmp[64];    //映射基址    uint8_t *mem;    int fd;    int i, j, k, count;    int strcnt, slen;    char c, failed = 0;    struct timeval tv;    struct timezone tz;

opts.smix = 0;

opts.verbose = 0;

opts.sh_type = 0;

opts.sh_flags = 0;    if (argc 

{        printf(""\n- Elf 二进制混淆器\n""        ""用法: %s  [选项]\n""        ""[-s]    字符串表随机化 \n""        ""[-t]   保持与字符串名称一致的区段类型\n""        ""[-f]    保持区段标志与字符串名称一致\n""        ""如: \n""        ""%s evilprog -stf\n"",

argv[0], argv[0]);

exit(0);

}    strcpy(exec, argv[1]);    //获取选项    while ((c = getopt(argc, argv, ""fstv"")) != -1)

{        switch(c)

{            case 's':

opts.smix++;                break;            case 't':

opts.sh_type++;                break;            case 'f':

opts.sh_flags++;                break;            case 'v':

opts.verbose++;                break;

}

}    //打开文件    if ((fd = open(exec, O_RDWR)) == -1)

{

perror(""open"");        exit(-1);

}    //读文件描述符    if (fstat(fd, &st) 

{

perror(""fstat"");        exit(-1);

}    //映射

mem = mmap(0, st.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);    if (mem == MAP_FAILED)

{

perror(""mmap"");        exit(-1);

}    //文件头

ehdr = (Elf32_Ehdr *)mem;    //程序头

phdr = (Elf32_Phdr *)(mem + ehdr->e_phoff);    //节表头

shdr = (Elf32_Shdr *)(mem + ehdr->e_shoff);    //设置字符串表指针

StringTable = &mem[shdr[ehdr->e_shstrndx].sh_offset];    printf(""[+] ELF Section 混淆 ->\n"");    printf(""[+] 开始字符串表随机化 \n"");    if (opts.sh_type)        printf(""[+] sh_type一致性启用\n"");    if (opts.sh_flags)        printf(""[+] sh_flag一致性启用\n"");    if (opts.sh_type || opts.sh_flags)

ehdr->e_shnum = 0;    //分配e_shnum个    if ((STBL = calloc(ehdr->e_shnum, sizeof(char *))) == NULL)

{

perror(""calloc"");        exit(-1);

}    //分配e_shnum个    if ((STBL_USED_STRINGS = calloc(ehdr->e_shnum, sizeof(char *))) == NULL)

{

perror(""calloc"");        exit(-1);

}    //遍历所有节    for (i = 0, shp = shdr; i e_shnum; shp++, i++)        //拷贝所有字符名称

STBL[i] = strdup(&StringTable[shp->sh_name]);

strcnt = i - 1;    //先计算出长度    for (slen = 0, i = 0; i 

{

perror(""malloc"");        exit(-1);

}    //赋值    for (p = NewStringTable, i = 0; i 

{        strcpy(p, STBL[i]);

p += strlen(p) + 1;

*p = 0;

}    if (opts.verbose)

{        for (i = 0; i 

}    for (i = 0; i 

STBL_USED_STRINGS[i] = malloc(64);

j = 0;    for (i = 0, shp = shdr; i e_shnum; i++, shp++)

{        memset(tmp, 0, sizeof(tmp));

gettimeofday(&tv, NULL);

srand(tv.tv_usec);        //将随机段名称复制到TMP中        strcpy(tmp, STBL[rand() % strcnt]);

//字符串是否被使用        if (strused(tmp, STBL_USED_STRINGS, strcnt))

{

--i;

--shp;            continue;

}        //确认没有分配自己的副本        //.symtab .symtab        if (!strcmp(&StringTable[shp->sh_name], tmp))

{

--i; --shp;            continue;

}

if (shp->sh_type == SHT_NULL)            continue;        //动态节就保持在适当的位置        if (!strcmp(&StringTable[shp->sh_name], "".dynamic"") || !strcmp(tmp, "".dynamic""))

{            if ((shp->sh_name = STBL_OFFSET(NewStringTable, "".dynamic"", strcnt)) == 0)

{                  printf(""STBL_OFFSET failed, could not find section name: %s, moving on\n"", tmp);                              goto done;

}            continue;

}        //创建新的偏移量        if ((shp->sh_name = STBL_OFFSET(NewStringTable, tmp, strcnt)) == 0)            printf(""STBL_OFFSET 失败, 找不到节名: %s\n"", tmp);        //代码段修改为0x8048000        if (!strcmp(tmp, "".text""))

shp->sh_addr = 0x8048000;       //更改节类型以匹配其名称symtab、rel和dynsym类型需要特定的条目大小        if (opts.sh_type)            for (count = 0; count 

{

shp->sh_type = section_type[count].type;                    if (shp->sh_type == SHT_SYMTAB)

shp->sh_entsize = 0x10;                    else                    if (shp->sh_type == SHT_DYNSYM)

shp->sh_entsize = 0x10;                    else                    if (shp->sh_type == SHT_REL)

shp->sh_entsize = 0x08;

}        if (opts.sh_flags)            for (count = 0; count 

shp->sh_flags = section_type[count].flags;        strcpy(STBL_USED_STRINGS[j++], tmp);

}    //拷贝字符串表    memcpy(&mem[shdr[ehdr->e_shstrndx].sh_offset], NewStringTable, shdr[ehdr->e_shstrndx].sh_size);    //实现磁盘文件内容与共享内存区中的内容一致    if (msync(mem, st.st_size, MS_SYNC) == -1)

{

perror(""msync"");

failed++;

}

done:    //解除映射

munmap(mem, st.st_size);    for (i = 0; i 

{   free(STBL[i]);        free(STBL_USED_STRINGS[i]);

}

if (!failed)        printf(""段混淆成功!!!\n"");    else        printf(""段没有完全混淆!!!\n"");    exit(0);

}

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值