-
-
[原创]2021 KCTF 第九题 平定战乱 设计思路
-
发表于: 2021-5-9 13:09 6159
-
给用户的源程序
用于启动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);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-5-27 12:13
被kanxue编辑
,原因:
赞赏
谁下载
谁下载
谁下载
谁下载
谁下载
谁下载
看原图
赞赏
雪币:
留言: