/// <summary> /// Step #6 /// /// Rebuild and save the unpacked file. /// </summary> /// <returns></returns> private bool Step6() { FileStream fStream = null; try { // Rebuild the file sections.. this.File.RebuildSections(); // Open the unpacked file for writing.. var unpackedPath = this.File.FilePath + ".unpacked.exe"; fStream = new FileStream(unpackedPath, FileMode.Create, FileAccess.ReadWrite); // Write the DOS header to the file.. fStream.WriteBytes(Pe32Helpers.GetStructureBytes(this.File.DosHeader)); // Write the DOS stub to the file.. if (this.File.DosStubSize > 0) { fStream.WriteBytes(this.File.DosStubData); } // Update the entry point of the file.. var ntHeaders = this.File.NtHeaders; ntHeaders.OptionalHeader.AddressOfEntryPoint = (uint)this.StubHeader.OriginalEntryPoint; this.File.NtHeaders = ntHeaders; // Write the NT headers to the file.. fStream.WriteBytes(Pe32Helpers.GetStructureBytes(ntHeaders)); // Write the sections to the file.. for (var x = 0; x < this.File.Sections.Count; x++) { var section = this.File.Sections[x]; var sectionData = this.File.SectionData[x]; // Write the section header to the file.. fStream.WriteBytes(Pe32Helpers.GetStructureBytes(section)); // Set the file pointer to the sections raw data.. var sectionOffset = fStream.Position; fStream.Position = section.PointerToRawData; // Write the sections raw data.. var sectionIndex = this.File.Sections.IndexOf(section); if (sectionIndex == this.CodeSectionIndex) { fStream.WriteBytes(this.CodeSectionData ?? sectionData); } else { fStream.WriteBytes(sectionData); } // Reset the file offset.. fStream.Position = sectionOffset; } // Set the stream to the end of the file.. fStream.Position = fStream.Length; // Write the overlay data if it exists.. if (this.File.OverlayData != null) { fStream.WriteBytes(this.File.OverlayData); } this.Log(" --> Unpacked file saved to disk!", LogMessageType.Success); this.Log($" --> File Saved As: {unpackedPath}", LogMessageType.Success); return(true); } catch { this.Log(" --> Error trying to save unpacked file!", LogMessageType.Error); return(false); } finally { fStream?.Dispose(); } }
/// <summary> /// Step #4 /// /// Rebuild and save the unpacked file. /// </summary> /// <returns></returns> private bool Step4() { FileStream fStream = null; try { // Zero the DosStubData if desired.. if (this.Options.ZeroDosStubData && this.File.DosStubSize > 0) { this.File.DosStubData = Enumerable.Repeat((byte)0, (int)this.File.DosStubSize).ToArray(); } // Open the unpacked file for writing.. var unpackedPath = this.File.FilePath + ".unpacked.exe"; fStream = new FileStream(unpackedPath, FileMode.Create, FileAccess.ReadWrite); // Write the DOS header to the file.. fStream.WriteBytes(Pe32Helpers.GetStructureBytes(this.File.DosHeader)); // Write the DOS stub to the file.. if (this.File.DosStubSize > 0) { fStream.WriteBytes(this.File.DosStubData); } // Update the NT headers.. var ntHeaders = this.File.NtHeaders; var lastSection = this.File.Sections[this.File.Sections.Count - 1]; ntHeaders.OptionalHeader.AddressOfEntryPoint = this.File.GetRvaFromVa(this.StubHeader.OEP); ntHeaders.OptionalHeader.CheckSum = 0; ntHeaders.OptionalHeader.SizeOfImage = this.File.GetAlignment(lastSection.VirtualAddress + lastSection.VirtualSize, this.File.NtHeaders.OptionalHeader.SectionAlignment); this.File.NtHeaders = ntHeaders; // Write the NT headers to the file.. fStream.WriteBytes(Pe32Helpers.GetStructureBytes(ntHeaders)); // Write the sections to the file.. for (var x = 0; x < this.File.Sections.Count; x++) { var section = this.File.Sections[x]; var sectionData = this.File.SectionData[x]; // Write the section header to the file.. fStream.WriteBytes(Pe32Helpers.GetStructureBytes(section)); // Set the file pointer to the sections raw data.. var sectionOffset = fStream.Position; fStream.Position = section.PointerToRawData; // Write the sections raw data.. var sectionIndex = this.File.Sections.IndexOf(section); if (sectionIndex == this.CodeSectionIndex) { fStream.WriteBytes(this.CodeSectionData ?? sectionData); } else { fStream.WriteBytes(sectionData); } // Reset the file offset.. fStream.Position = sectionOffset; } // Set the stream to the end of the file.. fStream.Position = fStream.Length; // Write the overlay data if it exists.. if (this.File.OverlayData != null) { fStream.WriteBytes(this.File.OverlayData); } this.Log(" --> Unpacked file saved to disk!", LogMessageType.Success); this.Log($" --> File Saved As: {unpackedPath}", LogMessageType.Success); return(true); } catch { this.Log(" --> Error trying to save unpacked file!", LogMessageType.Error); return(false); } finally { fStream?.Dispose(); } }