c语言二级指针的使用

起因

最近在闲暇的时候, 拾起 Windows PE文件解析.上次写PE已是去年的事情了,上次解析没有使用到指针,这次使用了指针,不过在指针使用上,还是有了一些认识,还有就是学了东西就要去用,不然时间长了容易忘记.要加以练习.

二级指针使用

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>


//加载文件到内存
//由于不知道文件大小
int load_file_to_memory(char* file_name, char** buf)
{
	if (file_name == NULL)
	{
		return -1;
	}
	FILE* fp = fopen(file_name, "rb");
	if (fp == NULL)
	{
		return -1;
	}

	//先将文件指针移动到结尾,通过ftell计算文件大小,再将文件指针移动开始未知,方便下边读取
	fseek(fp, 0, SEEK_END);
	long size = ftell(fp);
	fseek(fp, 0, SEEK_SET);

	//根据获取文件大小,分配并初始化为0
	void* temp_buf = calloc(size, sizeof(char));

	//读取size大小到temp_buf中
	int read_size = fread(temp_buf, sizeof(char), size, fp);

	//buf为二级指针,*buf指向temp_buf指向的内容
	*buf = (char*)temp_buf;

	if (fp != NULL)
	{
		fclose(fp);
	}
	return read_size;
}

//image_buf也是二级指针,因为不解析file_buf中的内容,不知道该为image_buf分配多少空间
int file_to_image(char** file_buf, char** image_buf)
{
	//获取二级指针file_buf指向的内容 
	char* buf = *file_buf;

	//这里对image_buf,不多说明,后期在pe中进行说明
	int write_size = 0;
	return  write_size;
}

int main(int argc, char* argv[])
{
	char* file_name = "h1.exe";
	int file_size;
	int write_size;
	char* buf;
	char* image_buf;

	//由于不知道文件大小,所以只声明一个buf,在函数内部读取文件后,确定文件大小,进行分配
	//并将文件内容读取分配的内存中,然后二级参数buf指向内存分配的指针上
	file_size = load_file_to_memory(file_name, &buf);

	write_size = file_to_image(&buf, &image_buf);

	//buf和image_buf在不使用的时候,要进行手动释放
	if (buf != NULL)
	{
		free(buf);
	}
	if (image_buf != NULL)
	{
		free(image_buf);
	}

	return 0;
}

在指针上移动,要看指针类型

int main(int argc, char* argv[])
{
	char* txt = "hello world,hello c!";
	printf("%c\n", *(txt + 1));  //输出e
	printf("%c\n", *(txt + 2));  //输出l

	printf("==========================\n");

	int size = strlen(txt);
	for (int i=0;i<size;i++)
	{
		printf("%c\n", *(txt + i));  
	}
	//发现txt+1,就移动1个字节,是因为char类型占一个直接

	return 0;
}

指针 偏移是跟指针类型有关系,char类型指针加1,就移动1个直接

在看下面这个

PIMAGE_SECTION_HEADER temp_section_header = section_header;
for (int i = 0; i < file_header->NumberOfSections; i++)
{
	void* des = (void*)((unsigned long)temp_buffer + temp_section_header->VirtualAddress);
	void* src = (void*)((unsigned long)ptemp +(temp_section_header + i)->PointerToRawData);  //temp_section_header + 1,移动多少呢?
	memcpy(des, src, temp_section_header->SizeOfRawData);
}

 是 sizeof(IMAGE_SECTION_HEADER),PIMAGE_SECTION_HEADER是IMAGE_SECTION_HEADER类型的指针.

秋风 2019-07-12