1 // PELoad.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
2 //
3
4 #include <iostream>
5 #include <windows.h>
6 #include <tchar.h>
7
8 IMAGE_DOS_HEADER DOSheader;
9 IMAGE_NT_HEADERS NTHeader;
10 PVOID ModuleBase;
11
12
13 void FixBaseRelocTable(PVOID ModuleBase)
14 {
15 int OriginalImageBase;
16 int uRelocTableSize;
17 int* uRelocAddress;
18 int uIndex;
19 IMAGE_DATA_DIRECTORY ImageDataDirectory;
20 IMAGE_BASE_RELOCATION* pImageBaseRelocation;
21
22 //定位到可选PE头里拿到ImageBase
23 OriginalImageBase = NTHeader.OptionalHeader.ImageBase;
24 //定位到可选PE头的DataDirArray里的重定位表
25 ImageDataDirectory = NTHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
26 //重定位表的实际地址
27 pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)((ULONG)ModuleBase + ImageDataDirectory.VirtualAddress);
28 if (pImageBaseRelocation == NULL)
29 {
30 return;
31 }
32 while (pImageBaseRelocation->SizeOfBlock)
33 {
34 typedef struct
35 {
36 USHORT offset : 12;
37 USHORT type : 4;
38 }TypeOffset;
39 TypeOffset* pTypeOffset = (TypeOffset*)(pImageBaseRelocation + 1);
40 uRelocTableSize = (pImageBaseRelocation->SizeOfBlock - 8) / 2;
41 for (uIndex = 0; uIndex < uRelocTableSize; uIndex++)
42 {
43
44 if (pTypeOffset[uIndex].type == 3)
45 {
46 uRelocAddress = (int*)(pTypeOffset[uIndex].offset + pImageBaseRelocation->VirtualAddress + (int)ModuleBase);
47 //printf("%x\n", *uRelocAddress);
48 *uRelocAddress = (int)ModuleBase + (*uRelocAddress - OriginalImageBase);
49 }
50 }
51 pImageBaseRelocation = (IMAGE_BASE_RELOCATION*)((ULONG)pImageBaseRelocation + pImageBaseRelocation->SizeOfBlock);
52 }
53
54
55 }
56
57 void FixIAT(PVOID ModuleBase)
58 {
59 IMAGE_DATA_DIRECTORY ImageDataDirectory;
60
61 PIMAGE_IMPORT_DESCRIPTOR ImportTable;
62
63 ImageDataDirectory = NTHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
64
65 ImportTable = PIMAGE_IMPORT_DESCRIPTOR(ImageDataDirectory.VirtualAddress + (int)ModuleBase);
66
67 int i = 0;
68
69 while (ImportTable->Name)
70 {
71 char* dllname = (char*)((int)ModuleBase + ImportTable->Name);
72
73 HMODULE hMoudle = LoadLibraryA((LPCSTR)dllname);
74
75 printf("%s\n", dllname);
76
77 int structaddr =ImportTable->OriginalFirstThunk + (int)ModuleBase;
78
79 IMAGE_IMPORT_BY_NAME* FirtstINT = (IMAGE_IMPORT_BY_NAME*)(*(DWORD*)structaddr+(int)ModuleBase);
80
81 IMAGE_THUNK_DATA* FirtstThunk = (IMAGE_THUNK_DATA*)(ImportTable->FirstThunk + (int)ModuleBase);
82
83 while (FirtstThunk->u1.Ordinal)
84 {
85 if (FirtstThunk->u1.Ordinal& IMAGE_ORDINAL_FLAG32)
86 {
87 FirtstThunk->u1.Ordinal = DWORD (GetProcAddress(hMoudle, (char*)((FirtstThunk->u1.Ordinal << 0x1) >> 0x1)));
88 }
89 else
90 {
91 char* FuncName = (char*)(FirtstINT->Name);
92 printf("%s\n", FuncName);
93 FirtstThunk->u1.Ordinal = DWORD(GetProcAddress(hMoudle, FuncName));
94 }
95 structaddr += 4;
96 FirtstINT = (IMAGE_IMPORT_BY_NAME*)(*(DWORD*)structaddr + (int)ModuleBase);
97 FirtstThunk++;
98 }
99
100 i++;
101
102 *ImportTable = ImportTable[i];
103 }
104
105
106
107 }
108
109 void LoadFileToMemory(LPCWSTR FileName)
110 {
111
112 BOOL Istrue;
113 DWORD Bytes;
114 HANDLE hFile;
115 PVOID SectionBuff;
116 OVERLAPPED overlap;
117 memset(&overlap, 0, sizeof(overlap));
118 // Open the file for overlapped reads
119 hFile = CreateFile(FileName,
120 GENERIC_READ,
121 FILE_SHARE_READ | FILE_SHARE_WRITE,
122 NULL,
123 OPEN_EXISTING,
124 FILE_FLAG_OVERLAPPED,
125 NULL);
126 if (hFile == INVALID_HANDLE_VALUE)
127 {
128 printf("打开文件失败!\n");
129 return;
130 }
131
132 ReadFile(hFile, &DOSheader, sizeof(IMAGE_DOS_HEADER), &Bytes, &overlap);
133
134 overlap.Offset = DOSheader.e_lfanew;
135
136 ReadFile(hFile, &NTHeader, sizeof(IMAGE_NT_HEADERS), &Bytes, &overlap);
137
138 WORD SectionNumber = NTHeader.FileHeader.NumberOfSections;
139
140 IMAGE_SECTION_HEADER* Sections = (IMAGE_SECTION_HEADER*)VirtualAlloc(NULL,sizeof(IMAGE_SECTION_HEADER)*SectionNumber,MEM_COMMIT,PAGE_READWRITE);
141
142 overlap.Offset = DOSheader.e_lfanew+ sizeof(IMAGE_NT_HEADERS);
143
144 ReadFile(hFile, Sections, sizeof(IMAGE_SECTION_HEADER) * SectionNumber, &Bytes, &overlap);
145
146 ModuleBase = VirtualAlloc(NULL, NTHeader.OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
147
148 if (ModuleBase == 0)
149 {
150 printf("申请内存失败!\n");
151 return;
152 }
153
154 memcpy(ModuleBase, &DOSheader, sizeof(DOSheader));
155
156 memcpy((PVOID)((int)ModuleBase+DOSheader.e_lfanew), &NTHeader, sizeof(NTHeader));
157
158 memcpy((PVOID)((int)ModuleBase + DOSheader.e_lfanew+sizeof(IMAGE_NT_HEADERS)), (PVOID)Sections, sizeof(IMAGE_SECTION_HEADER) * SectionNumber);
159
160
161 //依次COPY 各区段数据
162 int SectionSize;
163
164 for (int i = 0; i < SectionNumber; i++)
165 {
166 PVOID SectionVirtualAddress = (PVOID) Sections[i].VirtualAddress;//对应区段相对偏移
167 if (Sections[i].Misc.VirtualSize > Sections[i].SizeOfRawData)
168 SectionSize = Sections[i].Misc.VirtualSize;//取最大的占用空间
169 else
170 SectionSize = Sections[i].SizeOfRawData;
171
172 SectionBuff = VirtualAlloc(NULL, SectionSize, MEM_COMMIT, PAGE_READWRITE);
173
174 overlap.Offset = Sections[i].PointerToRawData;
175
176 ReadFile(hFile, SectionBuff, SectionSize, &Bytes, &overlap);
177
178 memcpy((PVOID)((int)ModuleBase + (int)SectionVirtualAddress), SectionBuff, SectionSize);
179
180 VirtualFree(SectionBuff, SectionSize, MEM_RELEASE);
181
182 }
183
184 VirtualFree(Sections, sizeof(IMAGE_SECTION_HEADER) * SectionNumber, MEM_RELEASE);
185
186 FixBaseRelocTable(ModuleBase);
187
188 FixIAT(ModuleBase);
189
190
191 }
192
193 int main()
194 {
195 const wchar_t* FileName = L"D:\\MyProjects\\test\\Debug\\哈哈哈.exe";
196
197 LoadFileToMemory((LPCWSTR)FileName);
198
199
200 DWORD* OEP = (DWORD*)((DWORD)ModuleBase + NTHeader.OptionalHeader.AddressOfEntryPoint);
201
202
203
204 DWORD OldProtect;
205
206 OldProtect = 0;
207
208 BOOL istrue = VirtualProtect(ModuleBase, NTHeader.OptionalHeader.SizeOfImage, PAGE_EXECUTE_READWRITE, &OldProtect);
209
210 printf("111111111111111");
211
212 _asm
213 {
214
215 pushad
216 pushfd
217
218 call OEP
219
220 popfd
221 popad
222
223 }
224
225 return 0;
226 }