private static void MapSections(JLibrary.PortableExecutable.PortableExecutable image, IntPtr hProcess, IntPtr pModule) { foreach (IMAGE_SECTION_HEADER image_section_header in image.EnumSectionHeaders()) { byte[] buffer = new byte[image_section_header.SizeOfRawData]; if (!image.Read((long)image_section_header.PointerToRawData, SeekOrigin.Begin, buffer)) { throw image.GetLastError(); } if ((image_section_header.Characteristics & 0x2000000) == 0) { uint num; WinAPI.WriteProcessMemory(hProcess, pModule.Add((long)image_section_header.VirtualAddress), buffer, buffer.Length, out num); IntPtr lpAddress = pModule.Add((long)image_section_header.VirtualAddress); WinAPI.VirtualProtectEx(hProcess, lpAddress, image_section_header.SizeOfRawData, image_section_header.Characteristics & 0xffffff, out num); } } }
private static void MapSections(PortableExecutable image, IntPtr hProcess, IntPtr pModule) { //very straightforward really. Just iterate through all the sections and map them to their desired virtual addresses in the remote process. //I'm not 100% sure about how well masking the section header characteristics and passing them off as memory protection constants goes. But //so far I haven't hit any issues. (i.e a section header with characteristics "IMAGE_SCN_TYPE_NO_PAD" will set "PAGE_WRITECOPY" memory protection. byte[] databuffer; uint n; foreach (var pSecHd in image.EnumSectionHeaders()) { databuffer = new byte[pSecHd.SizeOfRawData]; if (image.Read(pSecHd.PointerToRawData, SeekOrigin.Begin, databuffer)) { if ((pSecHd.Characteristics & 0x02000000) == 0) //can actually ignore this section (usually the reloc section) { WinAPI.WriteProcessMemory(hProcess, pModule.Add(pSecHd.VirtualAddress), databuffer, databuffer.Length, out n); WinAPI.VirtualProtectEx(hProcess, pModule.Add(pSecHd.VirtualAddress), pSecHd.SizeOfRawData, pSecHd.Characteristics & 0x00FFFFFF, out n); } } else { throw image.GetLastError(); } } }