-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathExtract.cpp
More file actions
94 lines (86 loc) · 2.69 KB
/
Extract.cpp
File metadata and controls
94 lines (86 loc) · 2.69 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <Windows.h>
#include <stdio.h>
BOOL ReadFileData(WCHAR *filename, BYTE **buff, DWORD *size);
const IMAGE_NT_HEADERS * GetNtHeader(const BYTE *image, const DWORD imageSize)
{
const IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER*)image;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
wprintf(L"Invalid DOS header\n");
return NULL;
}
const IMAGE_NT_HEADERS *ntHeader = (IMAGE_NT_HEADERS*)((ULONG_PTR)image + dosHeader->e_lfanew);
if ((BYTE*)ntHeader < image) {
wprintf(L"Invalid NT header\n");
return NULL;
}
if ((BYTE*)ntHeader > (image + imageSize - sizeof(IMAGE_NT_HEADERS))) {
wprintf(L"Invalid NT header\n");
return NULL;
}
if (ntHeader->Signature != IMAGE_NT_SIGNATURE) {
wprintf(L"Invalid NT header\n");
return NULL;
}
return ntHeader;
}
int wmain(int argc, WCHAR *argv[])
{
if (argc < 3) {
wprintf(L"usage: Extract.exe <PEFILE> <SHELLCODE>\n");
return 1;
}
DWORD imageSize = 0;
BYTE *image = NULL;
if (!ReadFileData(argv[1], &image, &imageSize)) {
wprintf(L"Failed to read file: %s\n", argv[1]);
return 1;
}
// get .text section
const IMAGE_NT_HEADERS *ntHeader = GetNtHeader(image, imageSize);
if (ntHeader == NULL)
return 1;
IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(ntHeader);
IMAGE_SECTION_HEADER *codeSection = NULL;
for (size_t i = 0; i < ntHeader->FileHeader.NumberOfSections; i++, section++) {
if ((BYTE*)section > (image + imageSize - sizeof(IMAGE_SECTION_HEADER))) {
wprintf(L"Invalid section header\n");
return 1;
}
if (memcmp(".text\x00", section->Name, 6) == 0) {
codeSection = section;
break;
}
}
if (codeSection == NULL) {
wprintf(L"Failed to find code section\n");
return 1;
}
// write .text section to file
const BYTE *text = image + codeSection->PointerToRawData;
if (text < image) {
wprintf(L"Invalid .text section\n");
return 1;
}
if ((text + codeSection->Misc.VirtualSize < text) || (text + codeSection->Misc.VirtualSize) > (image + imageSize)) {
wprintf(L"Invalid .text section\n");
return 1;
}
HANDLE hFile = CreateFileW(argv[2], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
wprintf(L"Failed to open file: %s\n", argv[2]);
return 1;
}
DWORD numWritten = 0;
DWORD numLeft = codeSection->Misc.VirtualSize;
BYTE *textPtr = (BYTE*)text;
while (numLeft > 0) {
if (!WriteFile(hFile, textPtr, numLeft, &numWritten, NULL)) {
wprintf(L"Failed to write to file: %s\n", argv[2]);
return 1;
}
numLeft -= numWritten;
textPtr += numWritten;
}
wprintf(L"Wrote %lu bytes to %s\n", codeSection->Misc.VirtualSize, argv[2]);
return 0;
}