注意:扩大节最好在最后节扩展 不然要修改好多东西
一:扩大节
1、拉伸到内存
2、分配一块新的空间:SizeOfImage+Ex
3、将最后一个节的SizeOfRawData 和 VirtualSize改成N
SizeOfRawData = VirtualSize = N
N = (SizeOfRawData或者Virtualsize 内存对齐后的值)+Ex
4、修改sizeofimage大小
Sizeofimage= sizeofimage+Ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
VOID ExpansionSection()
{
PVOID pFileBuffer
=
NULL;
PVOID pImageBuffer
=
NULL;
PVOID pNewBuffer
=
NULL;
PVOID pNewImageBuffer
=
NULL;
PIMAGE_DOS_HEADER pDosHeader
=
NULL;
PIMAGE_FILE_HEADER pPEHeader
=
NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader
=
NULL;
PIMAGE_SECTION_HEADER pSectionHeader
=
NULL;
PIMAGE_SECTION_HEADER pSectionHeaderUP
=
NULL;
PBYTE codeBegin
=
NULL;
BOOL
isOk
=
FALSE;
DWORD size
=
0
;
ReadPEFile(file_path, &pFileBuffer);
if
(!pFileBuffer)
{
printf(
"文件->缓冲区失败"
);
return
;
}
/
*
FileBuffer
-
>ImageBuffer
*
/
CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
if
(!pImageBuffer)
{
printf(
" 复制文件到缓冲区失败"
);
free(pFileBuffer);
return
;
}
pDosHeader
=
(PIMAGE_DOS_HEADER)pImageBuffer;
pPEHeader
=
(PIMAGE_FILE_HEADER)((DWORD)((DWORD)pImageBuffer
+
pDosHeader
-
>e_lfanew)
+
4
);
pOptionHeader
=
(PIMAGE_OPTIONAL_HEADER32)(((DWORD)pImageBuffer
+
pDosHeader
-
>e_lfanew)
+
4
+
IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader
=
(PIMAGE_SECTION_HEADER)(((DWORD)pImageBuffer
+
pDosHeader
-
>e_lfanew)
+
4
+
IMAGE_SIZEOF_FILE_HEADER
+
pPEHeader
-
>SizeOfOptionalHeader);
pOptionHeader
-
>SizeOfImage
+
=
0x1000
;
pSectionHeader[pPEHeader
-
>NumberOfSections
-
1
].Misc.VirtualSize
+
=
0x1000
;
pSectionHeader[pPEHeader
-
>NumberOfSections
-
1
].SizeOfRawData
+
=
0x1000
;
size
=
CopyImageBufferToNewFileBuffer(pImageBuffer, &pNewBuffer);
if
(size
=
=
0
|| !pNewBuffer)
{
printf(
"存盘失败"
);
free(pFileBuffer);
free(pImageBuffer);
free(pNewBuffer);
return
;
}
isOk
=
MemoryToFile(pNewBuffer, size, write_file_path);
printf(
"MemoryToFile"
);
if
(isOk)
{
printf(
"存盘成功"
);
return
;
}
free(pFileBuffer);
free(pImageBuffer);
free(pNewBuffer);
return
;
}
|
合并节是将多个节合并;
例如所有节合并为一个节:
1】只保留一个节表;
2】所有的节当作一个节,将描述信息写在第一个节表中;
合并节后,原来节表的地方空出来了,可以方便插入新节;
有多个节时,拉伸时需要循环遍历各个节表做对齐之类的操作;合并节 表后减少了这些操作;
如果把所有节合并,那么节与节之间就不再考虑内存对齐或者文件对齐了,由于我们是在文件装载到内存后合并的节,如果内存对齐和文件对齐不一样,那么最后将合并后的文件再还原成硬盘上的状态时,所有的节会当成一个整体,不会再文件对齐了,所以就导致了合并后文件可能会变大
1)拉伸到内存
2)将第一个节的内存大小、文件大小改成一样
1
2
3
|
Max
=
SizeOfRawData>VirtualSize?SizeOfRawData:VirtualSize
SizeOfRawData
=
VirtualSize
=
最后一个节的VirtualAddress
+
Max
-
SizeOfHeaders(内存对齐后的大小)
|
3)将第一个节的属性改为包含所有节的属性,即用第一个节的属性与其他的节的属性做或运算
4)修改节的数量为1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
VOID MergeSection()
{
PIMAGE_DOS_HEADER pDos
=
NULL;
PIMAGE_FILE_HEADER pFile
=
NULL;
PIMAGE_NT_HEADERS32 pNt
=
NULL;
PIMAGE_OPTIONAL_HEADER pOpt
=
NULL;
PIMAGE_SECTION_HEADER pSec
=
NULL;
PVOID pFileBuffer
=
NULL;
PVOID pImageBuffer
=
NULL;
PVOID pNewBuffer
=
NULL;
BOOL
isOk
=
FALSE;
DWORD size
=
0
;
ReadPEFile(file_path,&pFileBuffer);
if
(!pFileBuffer)
{
printf(
"读取文件失败"
);
return
;
}
CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
if
(!pImageBuffer)
{
printf(
"复制文件到imagebuffer失败"
);
free(pFileBuffer);
return
;
}
pDos
=
(PIMAGE_DOS_HEADER)pImageBuffer;
pNt
=
(PIMAGE_NT_HEADERS32)((DWORD)pDos
+
pDos
-
>e_lfanew);
pFile
=
(PIMAGE_FILE_HEADER)((DWORD)pNt
+
4
);
pOpt
=
(PIMAGE_OPTIONAL_HEADER)((DWORD)pFile
+
IMAGE_SIZEOF_FILE_HEADER);
pSec
=
(PIMAGE_SECTION_HEADER)((DWORD)pOpt
+
pFile
-
>SizeOfOptionalHeader);
/
/
修改节的属性
DWORD dwMax
=
pSec[pFile
-
>NumberOfSections
-
1
].Misc.VirtualSize > pSec[pFile
-
>NumberOfSections
-
1
].SizeOfRawData ? pSec[pFile
-
>NumberOfSections
-
1
].Misc.VirtualSize : pSec[pFile
-
>NumberOfSections
-
1
].SizeOfRawData;
pSec
-
>Misc.VirtualSize
=
pSec
-
>SizeOfRawData
=
pSec[pFile
-
>NumberOfSections
-
1
].VirtualAddress
+
dwMax
-
pOpt
-
>SizeOfHeaders;
for
(size_t i
=
1
; i < pFile
-
>NumberOfSections; i
+
+
)
{
pSec
-
>Characteristics |
=
pSec[i].Characteristics;
}
memset(pSec
+
1
,
0
, IMAGE_SIZEOF_SECTION_HEADER
*
(pFile
-
>NumberOfSections
-
1
));
pFile
-
>NumberOfSections
=
1
;
/
/
TO NewBuffer
size
=
CopyImageBufferToNewFileBuffer(pImageBuffer, &pNewBuffer);
if
(size
=
=
0
|| !pNewBuffer)
{
printf(
"存盘失败"
);
free(pFileBuffer);
free(pImageBuffer);
free(pNewBuffer);
return
;
}
isOk
=
MemoryToFile(pNewBuffer, size, write_file_path);
if
(isOk)
{
printf(
"存盘成功"
);
return
;
}
free(pFileBuffer);
free(pImageBuffer);
free(pNewBuffer);
return
;
}
|
更多【扩大节-合并节】相关视频教程:www.yxfzedu.com