Probe into malloc metadata capture field pointer of C library

On a stormy day, write play.

The wild pointer is annoying, which is easy to cause inexplicable memory stepping error. So how to judge whether a pointer is a wild pointer?

Generally speaking, the memory used by users is in mmap_ Both sides of threshold (generally 128k) are managed by malloc and mmap respectively:

  • malloc: memory management mechanism of C library, generally used for small memory management.
  • mmap: memory management mechanism provided by the operating system, generally used for large memory management.

We won't talk about mmap here, because the mechanism provided by the operating system is too easy to detect. The difficulty is the mechanism of C library:

  • The memory is outside the management of the operating system, completely autonomous, unable to enjoy the segment error prompt of the operating system

...

We have to use the malloc metadata of the C library to detect. For example, you can man -k malloc to get a lot of information about malloc's memory management. But that's not interesting. Just follow the book and publicize it. It's better to find it by hand.

Give a weak burst code:

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
	char *p1, *p2, *p3, *p4;
	int i, j;
	unsigned char *p;

	p1 = calloc(1, 32);
	memset(p1, 'c', 32); 
	p2 = calloc(1, 32); // If a 128 is alloc here, since the block of the same size is cut off, two pointers prev and next will appear at the same time after free.
	memset(p2, 'c', 32);
	p3 = calloc(1, 32);
	memset(p3, 'c', 32);
	p4 = calloc(1, 32);
	memset(p4, 'c', 32);
	// Observe the rule of memory address and find that the interval is 32 + 16
	printf("%p  %p  %p  %p\n", p1, p2, p3, p4);
	p = p1;
	// Guess there is metadata in base-16
	p -= 16;
	// Print detection
	for (i = 0; i < 48*4; ) {
		for (j = 0; j < 16; j++) {
			printf("%02x ", p[i++]);
		}
		printf("\n");
	}
	printf("\n");
	printf("\n");
	free(p1);
	free(p2);
	free(p3);
	free(p4);
	// View the same memory area after free, and observe the change of metadata
	for (i = 0; i < 48*4;) {
		for (j = 0; j < 16; j++) {
			printf("%02x ", p[i++]);
		}
		printf("\n");
	}
	printf("\n");
	// Do it again
	p1 = calloc(1, 32);
	memset(p1, 'c', 32);
	p2 = calloc(1, 32);
	memset(p2, 'c', 32);
	p3 = calloc(1, 32);
	memset(p3, 'c', 32);
	p4 = calloc(1, 32);
	memset(p4, 'c', 32);
	// Oh, it's a plank allocation, just like the slab in the kernel
	printf("%p  %p  %p  %p\n", p1, p2, p3, p4);
	for (i = 0; i < 48*4; ) {
		for (j = 0; j < 16; j++) {
			printf("%02x ", p[i++]);
		}
		printf("\n");
	}
	free(p1);
	free(p2);
	free(p3);
	free(p4);
	// Assign block s of different sizes
	p1 = calloc(1, 32);
	memset(p1, 'c', 32);
	p2 = calloc(1, 64);
	memset(p2, 'd', 64);
	p3 = calloc(1, 128);
	memset(p3, 'e', 128);
	p = p1;
	p -= 16;
	printf("%p  %p  %p \n", p1, p2, p3);
	for (i = 0; i < p3 + 128 - p1 + 16; ) {
		for (j = 0; j < 16; j++) {
			printf("%02x ", p[i++]);
		}
		printf("\n");
	}
	printf("\n");
	free(p1);
	free(p2);
	free(p3);
	// Once again
	p1 = calloc(1, 32);
	memset(p1, 'c', 32);
	p2 = calloc(1, 64);
	memset(p2, 'd', 64);
	p3 = calloc(1, 128);
	memset(p3, 'e', 128);
	p4 = calloc(1, 128);
	memset(p4, 'e', 128);
	p = p1;
	p -= 16;
	printf("%p  %p  %p %p\n", p1, p2, p3, p4);
	for (i = 0; i < p4 + 128 - p1 + 16; ) {
		for (j = 0; j < 16; j++) {
			printf("%02x ", p[i++]);
		}
		printf("\n");
	}
}

Perform once:

[root@localhost check]# ./a.out
0x1a0a010  0x1a0a040  0x1a0a070  0x1a0a0a0
# 0x31 in the first 16 bytes of metadata should be the size of the block.
# 48 = 32 + 16 = 0x30
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63


00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
# The free memory block occupies at least 1 8 bytes for metadata.
# It looks like the address of the next or last available block: 0x01a0000.
# This address includes metadata.
00 a0 a0 01 00 00 00 00 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
30 a0 a0 01 00 00 00 00 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
60 a0 a0 01 00 00 00 00 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63

0x1a0a0a0  0x1a0a070  0x1a0a040  0x1a0a010
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
0x1a0a010  0x1a0a0d0  0x1a0a120
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
60 a0 a0 01 00 00 00 00 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
90 a0 a0 01 00 00 00 00 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 51 00 00 00 00 00 00 00
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
00 00 00 00 00 00 00 00 91 00 00 00 00 00 00 00
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65

0x1a0a010  0x1a0a040  0x1a0a090 0x1a0a120
00 00 00 00 00 00 00 00 31 00 00 00 00 00 00 00
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 51 00 00 00 00 00 00 00
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
64 64 64 64 64 64 64 64 64 64 64 64 64 64 64 64
00 00 00 00 00 00 00 00 91 00 00 00 00 00 00 00
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
00 00 00 00 00 00 00 00 91 00 00 00 00 00 00 00
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65
65 65 65 65 65 65 65 65 65 65 65 65 65 65 65 65

It's easy to explore once. If you face a block of memory and find that its first 16 bytes contain at least one nearby pointer, and you haven't written an address in the memory block at all, then its very high probability is that it has been written into the free ptr's wild pointer by free!

...

In fact, it's more fun. According to this idea, you can dump all the freelist management methods of malloc without reference to any documents or source code, and constantly detect its behavior.

Of course, I certainly know that there are many methods for memory management, and malloc has many. This is the low est one I've listed in this article. No one uses this one now. The high-end ones look down on this one. The thread is not safe. How can I do it? So, then?

It's not true. It's just for fun.

Wenzhou leather shoes in Zhejiang are wet. They will not be fat if it rains and enters the water!

Tags: P4

Posted on Tue, 16 Jun 2020 01:29:56 -0400 by evolve4