首页
社区
课程
招聘
[原创]2021 KCTF 第九题 平定战乱 设计思路
发表于: 2021-5-9 13:09 6177

[原创]2021 KCTF 第九题 平定战乱 设计思路

Ex_ 活跃值
1
2021-5-9 13:09
6177

给用户的源程序

用于启动docker。

例如

 
$ cd docker
$ docker build -t kctf .
$ docker run -dti -p55555:55555 kctf
$ cd docker
$ docker build -t kctf .
$ docker run -dti -p55555:55555 kctf
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
 
typedef struct chunk{
    size_t pre_size, size;
    struct chunk *fd, *bk;
}chunk;
 
#define POINT(chk) ((chunk*)(((char *)(chk)) + 0x10))
#define UNPOINT(chk) ((chunk*)(((char *)(chk)) - 0x10))
#define CHUNK_SIZE(size) (((size) & 0xf) ? (((size) | 0xf) + 0x11) : ((size) + 0x10))
#define NEXT_CHUNK(chk) ((chunk *)(((char *)chk) + (chk->size & 0xf0)))
#define PRE_CHUNK(chk) ((chunk *)(((char *)chk) - (chk->pre_size & 0xf0)))
#define ASSERT(value, expected, error_info) if((value) != (expected)){ fprintf(stderr, "Error Report: %s\n", (error_info)); exit(1); }
#define SIZE_CHECK(size) ASSERT((!((size) & 0xf0)), 0, "Size check! ")
 
void *top_chunk;
chunk *link_hint[0x10];
 
chunk free_list;
 
void my_free(char *mem)
{
    unsigned int size;
    chunk *victim, *temp, *next_chunk, *pre_chunk;
    victim = (chunk *)(mem - 0x10);
    if(mem == NULL)
    {
        return;
    }
 
    ASSERT((size_t)victim & 0xf, 0, "Wrong ptr!");
    ASSERT(victim->size & 0xe, 0, "Wrong size!");
    next_chunk = NEXT_CHUNK(victim);
 
    // check
    if(next_chunk != top_chunk)
    {
        ASSERT(next_chunk->size & 0xe, 0, "Wrong next_chunk size!");
        SIZE_CHECK(next_chunk->size);
        if((next_chunk->size & 1))
        {
            ASSERT(victim->size & 0xf0, next_chunk->pre_size & 0xf0, "Wrong heap! ");
        }
    }
 
    if(victim->size & 1)
    {
        pre_chunk = PRE_CHUNK(victim);
        ASSERT(victim->size & 0xe, 0, "Wrong pre_chunk size!");
        SIZE_CHECK(pre_chunk->size);
        ASSERT(victim->pre_size & 0xf0, pre_chunk->size & 0xf0, "Wrong heap! ");
    }
 
 
    size = victim->size & 0xf0;
 
    temp = UNPOINT(free_list.bk);
    // insert
 
    if(temp == POINT(&free_list) || (temp->size & 0xf0) >= size)
    {
        ASSERT(temp->size & 0xe, 0, "Wrong size!");
        ASSERT(temp->fd, POINT(&free_list), "Double link list error!");
 
        victim->bk = POINT(temp);
        victim->fd = POINT(&free_list);
        temp->fd = POINT(victim);
        free_list.bk = POINT(victim);
    }
    else
    {
        while(temp->bk != POINT(&free_list))
        {
            temp = UNPOINT(temp->bk);
            if((temp->size & 0xf0) >= size)
            {
                ASSERT(UNPOINT(temp->bk)->fd, POINT(temp), "Duoble link list error!");
                ASSERT(UNPOINT(temp->fd)->bk, POINT(temp), "Double link list error!");
 
                victim->bk = POINT(temp);
                victim->fd = temp->fd;
                UNPOINT(temp->fd)->bk = POINT(victim);
                temp->fd = POINT(victim);
            }
        }
 
        if(temp->bk == POINT(&free_list))
        {
            ASSERT(UNPOINT(temp->bk)->fd, POINT(temp), "Duoble link list error!");
            ASSERT(UNPOINT(temp->fd)->bk, POINT(temp), "Double link list error!");
 
            victim->bk = POINT(&free_list);
            victim->fd = POINT(temp);
            temp->bk = POINT(victim);
            free_list.fd = POINT(victim);
        }
    }
 
    next_chunk->pre_size = victim->size & 0xf0;
    //
    next_chunk->size |= 1;
    link_hint[(victim->size & 0xf0) >> 4] = victim;
}
 
void *my_malloc(unsigned int n)
{
    unsigned int size;
    chunk *temp, *victim,  *next_chunk, *pre_chunk;
 
    size = CHUNK_SIZE(n);
    temp = UNPOINT(free_list.bk);
    while((temp != &free_list) && (temp->size & 0xf0) <= size)
    {
        if((temp->size & 0xf0) == size)
        {
            ASSERT(UNPOINT(temp->bk)->fd, POINT(temp), "Double link list error!");
            ASSERT(UNPOINT(temp->fd)->bk, POINT(temp), "Double link list error!");
            // more checks
            if(link_hint[(size & 0xf0) >> 4] == temp)
            {
                SIZE_CHECK(UNPOINT(temp->bk)->size);
                SIZE_CHECK(UNPOINT(temp->fd)->size);
                ASSERT(UNPOINT(temp->bk)->size & 0xe, 0, "Wrong heap!");
                ASSERT(UNPOINT(temp->fd)->size & 0xe, 0, "Wrong heap!");
 
                victim = UNPOINT(temp->fd);
 
                if(victim != &free_list)
                {
                    next_chunk = NEXT_CHUNK(victim);
 
                    // check
                    if(next_chunk != top_chunk)
                    {
                        ASSERT(next_chunk->size & 0xe, 0, "Wrong next_chunk size!");
                        SIZE_CHECK(next_chunk->size);
                        if((next_chunk->size & 1))
                        {
                            ASSERT(victim->size & 0xf0, next_chunk->pre_size & 0xf0, "Wrong heap! ");
                        }
                    }
 
                    if(victim->size & 1)
                    {
                        pre_chunk = PRE_CHUNK(victim);
                        ASSERT(victim->size & 0xe, 0, "Wrong pre_chunk size!");
                        SIZE_CHECK(pre_chunk->size);
                        ASSERT(victim->pre_size & 0xf0, pre_chunk->size & 0xf0, "Wrong heap! ");
                    }
                }
 
 
 
                victim = UNPOINT(temp->bk);
 
                if(victim != &free_list)
                {
                    next_chunk = NEXT_CHUNK(victim);
 
                    // check
                    if(next_chunk != top_chunk)
                    {
                        ASSERT(next_chunk->size & 0xe, 0, "Wrong next_chunk size!");
                        SIZE_CHECK(next_chunk->size);
                        if((next_chunk->size & 1))
                        {
                            ASSERT(victim->size & 0xf0, next_chunk->pre_size & 0xf0, "Wrong heap! ");
                        }
                    }
 
                    if(victim->size & 1)
                    {
                        pre_chunk = PRE_CHUNK(victim);
                        ASSERT(victim->size & 0xe, 0, "Wrong pre_chunk size!");
                        SIZE_CHECK(pre_chunk->size);
                        ASSERT(victim->pre_size & 0xf0, pre_chunk->size & 0xf0, "Wrong heap! ");
                    }
                }
            }
 
            // unlink
            UNPOINT(temp->bk)->fd = temp->fd;
            UNPOINT(temp->fd)->bk = temp->bk;
 
            next_chunk = NEXT_CHUNK(temp);
            next_chunk->size &= 0xf0;
 
            return POINT(temp);
        }
        else
        {
            temp = UNPOINT(temp->bk);
        }
    }
 
    temp = top_chunk;
    ASSERT(temp->size & 0xf0, 0, "Top chunk error!");
    temp->size |= size;
    top_chunk = (char *)top_chunk + size;
 
    return POINT(temp);
}
 
 
void initial()
{
 
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
 
    alarm(60);
}
 
int read_n(char *buf, int size)
{
    int bytes;
 
    bytes = read(0, buf, size);
    if(bytes <= 0)
    {
        exit(EXIT_FAILURE);
    }
    if(buf[bytes - 1] == '\n')
    {
        buf[bytes - 1] = '\0';
    }
 
    return bytes;
}
 
unsigned int get_int()
{
    char buf[0x100];
    memset(buf, 0, sizeof(buf));
    read_n(buf, sizeof(buf) - 1);
    return atol(buf);
}
 
#define LENGTH 0x10
char *ptr[LENGTH];
unsigned int ptr_size[LENGTH];
 
void add()
{
    unsigned int index, i, size;
 
    for(i = 0; i < LENGTH; i++)
    {
        if(!ptr[i])
        {
            index = i;
            break;
        }
    }
 
    if(index >= LENGTH)
    {
        puts("No space!");
        return;
    }
 
    printf("Size: ");
    size = get_int();
    if(size >= 0xf0)
    {
        puts("Invalid size!");
        return;
    }
 
    ptr[index] = my_malloc(size);
    ptr_size[index] = size;
    printf("Content: ");
    read_n(ptr[index], size);
}
 
void delete()
{
    unsigned int index;
    printf("Index: ");
    index = get_int();
    if(index < LENGTH && ptr[index])
    {
        my_free(ptr[index]);
    }
    else
    {
        puts("Invalid index!");
    }
}
 
void edit()
{
    unsigned int index;
    printf("Index: ");
    index = get_int();
    if(index < LENGTH && ptr[index])
    {
        printf("Content: ");
        read_n(ptr[index], ptr_size[index]);
    }
    else
    {
        puts("Invalid index!");
    }
}
 
int main()
{
    char buf[0x100];
    int option = 0;
    unsigned int length;
    initial();
 
    puts("KCTF\n");
 
    top_chunk = mmap(NULL, 0x40000, 3, 0x22, -1, 0);
    ((size_t*)top_chunk)[1] = 0x20;
    top_chunk = (size_t*)top_chunk + 4;
    free_list.size = 0x20;
    free_list.bk = POINT(&free_list);
    free_list.fd = POINT(&free_list);
 
    do
    {
        printf( "1. add\n"
                "2. delete\n"
                "3. edit\n"
                "4. exit\n"
                "Your choice: ");
 
        option = get_int();
        switch(option)
        {
        case 1:
            add();
            break;
        case 2:
            delete();
            break;
        case 3:
            edit();
            break;
        case 4:
            break;
        default:
            puts("Invalid choice!");
            break;
        }
 
        puts("");
    }while(option != 4);
 
    puts("Goodbye!");
    return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
 
typedef struct chunk{
    size_t pre_size, size;
    struct chunk *fd, *bk;
}chunk;
 
#define POINT(chk) ((chunk*)(((char *)(chk)) + 0x10))
#define UNPOINT(chk) ((chunk*)(((char *)(chk)) - 0x10))
#define CHUNK_SIZE(size) (((size) & 0xf) ? (((size) | 0xf) + 0x11) : ((size) + 0x10))
#define NEXT_CHUNK(chk) ((chunk *)(((char *)chk) + (chk->size & 0xf0)))
#define PRE_CHUNK(chk) ((chunk *)(((char *)chk) - (chk->pre_size & 0xf0)))
#define ASSERT(value, expected, error_info) if((value) != (expected)){ fprintf(stderr, "Error Report: %s\n", (error_info)); exit(1); }
#define SIZE_CHECK(size) ASSERT((!((size) & 0xf0)), 0, "Size check! ")
 
void *top_chunk;
chunk *link_hint[0x10];
 
chunk free_list;
 
void my_free(char *mem)
{
    unsigned int size;
    chunk *victim, *temp, *next_chunk, *pre_chunk;
    victim = (chunk *)(mem - 0x10);
    if(mem == NULL)
    {
        return;
    }
 
    ASSERT((size_t)victim & 0xf, 0, "Wrong ptr!");
    ASSERT(victim->size & 0xe, 0, "Wrong size!");
    next_chunk = NEXT_CHUNK(victim);
 
    // check
    if(next_chunk != top_chunk)
    {
        ASSERT(next_chunk->size & 0xe, 0, "Wrong next_chunk size!");
        SIZE_CHECK(next_chunk->size);
        if((next_chunk->size & 1))
        {
            ASSERT(victim->size & 0xf0, next_chunk->pre_size & 0xf0, "Wrong heap! ");
        }
    }
 
    if(victim->size & 1)
    {
        pre_chunk = PRE_CHUNK(victim);
        ASSERT(victim->size & 0xe, 0, "Wrong pre_chunk size!");
        SIZE_CHECK(pre_chunk->size);
        ASSERT(victim->pre_size & 0xf0, pre_chunk->size & 0xf0, "Wrong heap! ");
    }
 
 
    size = victim->size & 0xf0;
 
    temp = UNPOINT(free_list.bk);
    // insert
 
    if(temp == POINT(&free_list) || (temp->size & 0xf0) >= size)
    {
        ASSERT(temp->size & 0xe, 0, "Wrong size!");
        ASSERT(temp->fd, POINT(&free_list), "Double link list error!");
 
        victim->bk = POINT(temp);
        victim->fd = POINT(&free_list);
        temp->fd = POINT(victim);
        free_list.bk = POINT(victim);
    }
    else
    {
        while(temp->bk != POINT(&free_list))
        {
            temp = UNPOINT(temp->bk);
            if((temp->size & 0xf0) >= size)
            {
                ASSERT(UNPOINT(temp->bk)->fd, POINT(temp), "Duoble link list error!");
                ASSERT(UNPOINT(temp->fd)->bk, POINT(temp), "Double link list error!");
 
                victim->bk = POINT(temp);
                victim->fd = temp->fd;
                UNPOINT(temp->fd)->bk = POINT(victim);
                temp->fd = POINT(victim);
            }
        }
 
        if(temp->bk == POINT(&free_list))
        {
            ASSERT(UNPOINT(temp->bk)->fd, POINT(temp), "Duoble link list error!");
            ASSERT(UNPOINT(temp->fd)->bk, POINT(temp), "Double link list error!");
 
            victim->bk = POINT(&free_list);
            victim->fd = POINT(temp);
            temp->bk = POINT(victim);
            free_list.fd = POINT(victim);
        }
    }
 
    next_chunk->pre_size = victim->size & 0xf0;
    //
    next_chunk->size |= 1;
    link_hint[(victim->size & 0xf0) >> 4] = victim;
}
 
void *my_malloc(unsigned int n)
{
    unsigned int size;
    chunk *temp, *victim,  *next_chunk, *pre_chunk;
 
    size = CHUNK_SIZE(n);
    temp = UNPOINT(free_list.bk);
    while((temp != &free_list) && (temp->size & 0xf0) <= size)
    {
        if((temp->size & 0xf0) == size)
        {
            ASSERT(UNPOINT(temp->bk)->fd, POINT(temp), "Double link list error!");
            ASSERT(UNPOINT(temp->fd)->bk, POINT(temp), "Double link list error!");
            // more checks
            if(link_hint[(size & 0xf0) >> 4] == temp)
            {
                SIZE_CHECK(UNPOINT(temp->bk)->size);
                SIZE_CHECK(UNPOINT(temp->fd)->size);
                ASSERT(UNPOINT(temp->bk)->size & 0xe, 0, "Wrong heap!");
                ASSERT(UNPOINT(temp->fd)->size & 0xe, 0, "Wrong heap!");
 
                victim = UNPOINT(temp->fd);
 
                if(victim != &free_list)
                {
                    next_chunk = NEXT_CHUNK(victim);
 
                    // check
                    if(next_chunk != top_chunk)
                    {
                        ASSERT(next_chunk->size & 0xe, 0, "Wrong next_chunk size!");
                        SIZE_CHECK(next_chunk->size);
                        if((next_chunk->size & 1))
                        {
                            ASSERT(victim->size & 0xf0, next_chunk->pre_size & 0xf0, "Wrong heap! ");
                        }
                    }
 
                    if(victim->size & 1)
                    {
                        pre_chunk = PRE_CHUNK(victim);
                        ASSERT(victim->size & 0xe, 0, "Wrong pre_chunk size!");
                        SIZE_CHECK(pre_chunk->size);
                        ASSERT(victim->pre_size & 0xf0, pre_chunk->size & 0xf0, "Wrong heap! ");
                    }
                }
 
 
 
                victim = UNPOINT(temp->bk);
 
                if(victim != &free_list)
                {
                    next_chunk = NEXT_CHUNK(victim);
 
                    // check
                    if(next_chunk != top_chunk)
                    {
                        ASSERT(next_chunk->size & 0xe, 0, "Wrong next_chunk size!");
                        SIZE_CHECK(next_chunk->size);
                        if((next_chunk->size & 1))
                        {
                            ASSERT(victim->size & 0xf0, next_chunk->pre_size & 0xf0, "Wrong heap! ");
                        }
                    }
 
                    if(victim->size & 1)
                    {
                        pre_chunk = PRE_CHUNK(victim);
                        ASSERT(victim->size & 0xe, 0, "Wrong pre_chunk size!");
                        SIZE_CHECK(pre_chunk->size);

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-5-27 12:13 被kanxue编辑 ,原因:
上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//