添加节 + 扩大节

增加节

BOOL IncreaseSection(PVOID fileName) {
	BYTE shellcode[] = { 0x6a,0x00,0x6a,0x00,0x6a,0x00,0x6a,0x00,0xe8,0xD9,0x42,0xcd,0x74,0xe9,0x12,0xc9,0xff,0xff };
	//&MessageBox = 750F0D80
	//读取到FileBuffer 并且套入Headers
	PVOID pFileBuffer = FileToFileBuffer(fileName);
	PIMAGE_DOS_HEADER pDosHeader = pFileBuffer;
	PIMAGE_NT_HEADERS pNTHeader = (DWORD)pDosHeader + pDosHeader->e_lfanew;
	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
		printf("File is not PE\n");
		free(pFileBuffer);
		return FALSE;
	}
	PIMAGE_FILE_HEADER pFileHeader = &pNTHeader->FileHeader;
	PIMAGE_OPTIONAL_HEADER pOptHeader = (DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER);
	PIMAGE_SECTION_HEADER pSecHeader = (DWORD)pOptHeader + pFileHeader->SizeOfOptionalHeader;
	//计算最后一个节
	PIMAGE_SECTION_HEADER pLastSection = pSecHeader + pFileHeader->NumberOfSections - 1;
	
	//不准备做判断后面能不能新添一个节表,无脑往前提就完了,不过还是要判断往前腾出来的空间够不够放下80字节的
	DWORD commentAreaSize = pDosHeader->e_lfanew - sizeof(IMAGE_DOS_HEADER);
	if (commentAreaSize < 0x80) {
		printf("e_lfanew is not enough\n");
		free(pFileBuffer);
		return FALSE;
	}
	/*从NtHeader到最后节的结尾中间就是要移动的大小,但是我逻辑能力太差了不理解为什么要加4才是全部的数据(因为测试的时候发现就是
	差那个4字节*/
	DWORD pNtheaderSize = (DWORD)(pLastSection + 1) - (DWORD)pNTHeader + 4;
	memcpy((&pDosHeader->e_lfanew + 1), pNTHeader, pNtheaderSize);
	//往前提后所有headers要重新计算...
	pDosHeader->e_lfanew -= commentAreaSize;
	pNTHeader = (DWORD)pDosHeader + pDosHeader->e_lfanew;
	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
		printf("File is not PE\n");
		free(pFileBuffer);
		return FALSE;
	}
	pFileHeader = &pNTHeader->FileHeader;
	pOptHeader = (DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER);
	pSecHeader = (DWORD)pOptHeader + pFileHeader->SizeOfOptionalHeader;
	pLastSection = pSecHeader + pFileHeader->NumberOfSections - 1;
	memset(((DWORD)(&pDosHeader->e_lfanew) + pNtheaderSize), 0, commentAreaSize);
	
	//增加节表
	PIMAGE_SECTION_HEADER pNewSection = pLastSection + 1;
	pFileHeader->NumberOfSections += 1;
	pOptHeader->SizeOfImage += SIZE_OF_INCREASE_SECTION;
	memcpy(pNewSection, pLastSection, sizeof(IMAGE_SECTION_HEADER));
	strcpy(pNewSection->Name, ".gggg");
	pNewSection->Misc.VirtualSize = SIZE_OF_INCREASE_SECTION;
	pNewSection->VirtualAddress = pLastSection->VirtualAddress +
		Align(MAX(pLastSection->SizeOfRawData, pLastSection->Misc.VirtualSize), pOptHeader->SectionAlignment);
	pNewSection->SizeOfRawData = Align(SIZE_OF_INCREASE_SECTION,pOptHeader->FileAlignment);
	pNewSection->PointerToRawData = pLastSection->PointerToRawData + pLastSection->SizeOfRawData;
	//关闭随机基址
	pOptHeader->DllCharacteristics &= (~IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE);
	//更改权限为可执行无脑改
	pNewSection->Characteristics |= IMAGE_SCN_MEM_EXECUTE;
	//早点构造shellcode和改oep,不然等会儿NewFileBuffer又要重新计算所有headers
	DWORD e8Addr = (DWORD)MessageBox - (pOptHeader->ImageBase + pNewSection->VirtualAddress + 8 + 5);
	DWORD e9Addr = pOptHeader->AddressOfEntryPoint - (pNewSection->VirtualAddress + 8 + 5 + 5);
	*((PDWORD)(shellcode + 9)) = e8Addr;
	*((PDWORD)(shellcode + 9 + 5)) = e9Addr;
	pOptHeader->AddressOfEntryPoint = pNewSection->VirtualAddress;
	//把内存里的FileBuffer写到NewFileBuffer里
	DWORD newFileBufferSize = pNewSection->PointerToRawData + pNewSection->SizeOfRawData;
	DWORD oldBufferSize = pLastSection->PointerToRawData + pLastSection->SizeOfRawData;
	PVOID pNewFileBuffer = malloc(newFileBufferSize);
	if (!pNewFileBuffer) {
		printf("malloc failed\n");
		free(pFileBuffer);
		return FALSE;
	}
	memset(pNewFileBuffer, 0, newFileBufferSize);
	memcpy(pNewFileBuffer, pFileBuffer, oldBufferSize);
	//计算shellcode写入shellcode 改变OEP
	PVOID pWritePosition = (DWORD)pNewFileBuffer + pNewSection->PointerToRawData;
	memcpy(pWritePosition, shellcode, sizeof(shellcode));
	//存盘
	FILE* pFile = fopen("C:\\Users\\12459\\Downloads\\111.exe", "wb");
	if (!pFile) {
		printf("fopen failed\n");
		free(pFileBuffer);
		free(pNewFileBuffer);
		return FALSE;
	}
	fwrite(pNewFileBuffer, newFileBufferSize, 1, pFile);
	free(pFileBuffer);
	free(pNewFileBuffer);
	return TRUE;
}

扩大节

BOOL ExpandSection(PVOID fileName) {
	//做好准备工作,套入headers
	BYTE shellcode[] = { 0x6a,0x00,0x6a,0x00,0x6a,0x00,0x6a,0x00,0xe8,0xD9,0x42,0xcd,0x74,0xe9,0x12,0xc9,0xff,0xff };
	PVOID pFileBuffer = FileToFileBuffer(fileName);
	PIMAGE_DOS_HEADER pDosHeader = pFileBuffer;
	PIMAGE_NT_HEADERS pNTHeader = (DWORD)pDosHeader + pDosHeader->e_lfanew;
	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
		printf("File is not PE\n");
		free(pFileBuffer);
		return FALSE;
	}
	PIMAGE_FILE_HEADER pFileHeader = &pNTHeader->FileHeader;
	PIMAGE_OPTIONAL_HEADER pOptHeader = (DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER);
	PIMAGE_SECTION_HEADER pSecHeader = (DWORD)pOptHeader + pFileHeader->SizeOfOptionalHeader;
	PIMAGE_SECTION_HEADER pLastSectionHeader = pSecHeader + pFileHeader->NumberOfSections - 1;
	//修改相关的数据
	pLastSectionHeader->Misc.VirtualSize += sizeof(shellcode);
	pLastSectionHeader->SizeOfRawData = Align(pLastSectionHeader->Misc.VirtualSize,pOptHeader->FileAlignment);
	pOptHeader->SizeOfImage = Align(pLastSectionHeader->VirtualAddress +
		pLastSectionHeader->Misc.VirtualSize, pOptHeader->SectionAlignment);
	pLastSectionHeader->Characteristics |= IMAGE_SCN_MEM_EXECUTE;
	pOptHeader->DllCharacteristics &= (~IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE);
	//构造shellcode
	DWORD e8Addr = (DWORD)MessageBoxA - (pOptHeader->ImageBase + pLastSectionHeader->VirtualAddress +
		pLastSectionHeader->Misc.VirtualSize + 8 + 5);
	DWORD e9Addr = (DWORD)pOptHeader->AddressOfEntryPoint - (pLastSectionHeader->VirtualAddress +
		pLastSectionHeader->Misc.VirtualSize + 8 + 5 + 5);
	*((PDWORD)(shellcode + 9)) = e8Addr;
	*((PDWORD)(shellcode + 9 + 5)) = e9Addr;
	//计算写入位置偏移,改OEP,之后只需要申请newbuffer,写入shellcode就行了
	DWORD pWritePositionOffset = pLastSectionHeader->PointerToRawData + pLastSectionHeader->Misc.VirtualSize;
	pOptHeader->AddressOfEntryPoint = pLastSectionHeader->VirtualAddress + pLastSectionHeader->Misc.VirtualSize;
	//申请NewFileBuffer写入shellcode,保存成文件
	DWORD newFileSize = pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData;
	PVOID pNewFileBuffer = malloc(newFileSize);
	if (!pNewFileBuffer) {
		printf("malloc failed\n");
		free(pFileBuffer);
		return FALSE;
	}
	memset(pNewFileBuffer, 0, newFileSize);
	memcpy(pNewFileBuffer, pFileBuffer, pWritePositionOffset);
	memcpy((DWORD)pNewFileBuffer + pWritePositionOffset, shellcode, sizeof(shellcode));
	FILE* pFile = fopen("C:\\Users\\12459\\Downloads\\111.exe", "wb");
	if (!pFile) {
		printf("fopen failed\n");
		free(pFileBuffer);
		free(pNewFileBuffer);
		return FALSE;
	}
	fwrite(pNewFileBuffer, newFileSize, 1, pFile);
	//这里应该是因为我申请的两个buffer大小一样并且结果也是左手倒右手他就帮我优化了,所以我要加一个判断...
	if (pFileBuffer == pNewFileBuffer) {
		free(pFileBuffer);
		return TRUE;
	}
	free(pNewFileBuffer);
	return TRUE;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值