public bool SaveToStream(Stream ModuleStream) { MEMORY_BASIC_INFORMATION64 mbi = new MEMORY_BASIC_INFORMATION64(); mbi = DebugApi.AddressType(BaseAddress); if (mbi.Protect == PAGE.NOACCESS && !DebugApi.IsIDNA) { DebugApi.WriteLine("Unable to read memory at %p", BaseAddress); return(false); } bool bIsImage = DebugApi.IsIDNA || (mbi.Type == MEM.IMAGE || mbi.Type == MEM.PRIVATE); IMAGE_DOS_HEADER dosHeader = DOSHeader; if (!dosHeader.isValid) { return(false); } // NT PE Headers ulong dwAddr = BaseAddress; ulong dwEnd = 0; uint nRead; IMAGE_SECTION_HEADER section = new IMAGE_SECTION_HEADER(); ulong sectionAddr = 0; int nSection = 0; if (FileImageType == ImageType.Pe64bit) { sectionAddr = BaseAddress + (ulong)dosHeader.e_lfanew + (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") + NTHeader.FileHeader.SizeOfOptionalHeader; nSection = NTHeader.FileHeader.NumberOfSections; dwEnd = BaseAddress + NTHeader.OptionalHeader.SizeOfHeaders; } if (FileImageType == ImageType.Pe32bit) { sectionAddr = BaseAddress + (ulong)dosHeader.e_lfanew + (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader") + NTHeader32.FileHeader.SizeOfOptionalHeader; nSection = NTHeader32.FileHeader.NumberOfSections; dwEnd = BaseAddress + NTHeader32.OptionalHeader.SizeOfHeaders; } MemLocation[] memLoc = new MemLocation[nSection]; int indxSec = -1; int slot; for (int n = 0; n < nSection; n++) { if (!DebugApi.ReadMemory <IMAGE_SECTION_HEADER>(sectionAddr, out section)) { DebugApi.WriteLine("[IMAGE_SECTION_HEADER] Fail to read PE section info at %p\n", sectionAddr); return(false); } for (slot = 0; slot <= indxSec; slot++) { if ((ulong)section.PointerToRawData < (ulong)memLoc[slot].FileAddr) { break; } } for (int k = indxSec; k >= slot; k--) { memLoc[k + 1] = memLoc[k]; } memLoc[slot].VAAddr = (IntPtr)section.VirtualAddress; memLoc[slot].VASize = (IntPtr)section.VirtualSize; memLoc[slot].FileAddr = (IntPtr)section.PointerToRawData; memLoc[slot].FileSize = (IntPtr)section.SizeOfRawData; indxSec++; sectionAddr += (ulong)Marshal.SizeOf(section); } uint pageSize; DebugApi.Control.GetPageSize(out pageSize); byte[] buffer = new byte[pageSize]; IDebugDataSpaces3 data = (IDebugDataSpaces3)DebugApi.Client; while (dwAddr < dwEnd) { nRead = pageSize; if (dwEnd - dwAddr < nRead) { nRead = (uint)(dwEnd - dwAddr); } if (data.ReadVirtual(dwAddr, buffer, nRead, out nRead) == (int)HRESULT.S_OK) { ModuleStream.Write(buffer, 0, (int)nRead); } else { DebugApi.WriteLine("Fail to read memory\n"); return(false); } dwAddr += nRead; } for (slot = 0; slot <= indxSec; slot++) { //if (!DebugApi.IsTaget64Bits) //{ if (bIsImage) { dwAddr = BaseAddress + (ulong)memLoc[slot].VAAddr; } else { dwAddr = BaseAddress + (ulong)memLoc[slot].FileAddr; } //} //else // dwAddr = BaseAddress + (ulong)memLoc[slot].FileAddr; dwEnd = (ulong)memLoc[slot].FileSize + dwAddr - 1; while (dwAddr <= dwEnd) { nRead = pageSize; if (dwEnd - dwAddr + 1 < pageSize) { nRead = (uint)(dwEnd - dwAddr + 1); } if (data.ReadVirtual(dwAddr, buffer, nRead, out nRead) == (int)HRESULT.S_OK) { ModuleStream.Write(buffer, 0, (int)nRead); } else { DebugApi.WriteLine("Fail to read memory\n"); return(false); } dwAddr += pageSize; } } return(true); }
public ulong RvaToOffset(ulong Rva) { var sectionId = SectionStart; uint sections = 0; MEMORY_BASIC_INFORMATION64 mbi = new MEMORY_BASIC_INFORMATION64(); mbi = DebugApi.AddressType(BaseAddress); if (!DebugApi.IsIDNA && mbi.Protect == PAGE.NOACCESS) { DebugApi.WriteLine("Unable to read memory at %p", BaseAddress); return(0); } bool bIsImage = (DebugApi.IsIDNA || mbi.Type == MEM.IMAGE || mbi.Type == MEM.PRIVATE); if (FileImageType == ImageType.Pe32bit) { sections = NTHeader32.FileHeader.NumberOfSections; sectionId += (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader") + NTHeader32.FileHeader.SizeOfOptionalHeader; } if (FileImageType == ImageType.Pe64bit) { sections = NTHeader.FileHeader.NumberOfSections; sectionId += (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") + NTHeader.FileHeader.SizeOfOptionalHeader; } for (int i = 0; i < sections; i++) { IMAGE_SECTION_HEADER section = new IMAGE_SECTION_HEADER(); if (!DebugApi.ReadMemory <IMAGE_SECTION_HEADER>(sectionId, out section)) { Debug.WriteLine("[RVA] Unable to read IMAGE_SECTION_HEADER"); return(0); } if ((Rva >= section.VirtualAddress) && (Rva < (section.VirtualAddress + section.SizeOfRawData))) { // RVA is in this section, we can now resolve it. ulong start = 0; if (bIsImage) { start = section.VirtualAddress; } else { start = section.PointerToRawData; } ulong address = BaseAddress + (ulong)Rva - (ulong)section.VirtualAddress + start; // (ulong)section.PointerToRawData; return(address); } // Next section sectionId += (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); } // RVA could not be found return(0); }