三环PE文件自行加载,并运行,解析PE结构,修复IAT,修复重定位表

  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 }

 

posted @ 2022-11-11 18:27  骑士198803  阅读(101)  评论(0)    收藏  举报