public static unsafe int DumpProcess(uint processId, string DirectoryName) { IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, 0, processId); if (hProcess == IntPtr.Zero) { return(0); } try { int CurrentCount = 1; bool isok; byte[] onepage = new byte[pagesize]; uint BytesRead = 0; byte[] infokeep = new byte[8]; MegaDumperHelper.CreateDirectories(DirectoryName); for (uint j = minaddress; j < maxaddress; j += pagesize) { isok = ReadProcessMemory(hProcess, j, onepage, pagesize, ref BytesRead); if (isok) { for (int k = 0; k < onepage.Length - 2; k++) { if (onepage[k] == 0x4D && onepage[k + 1] == 0x5A) { if (ReadProcessMemory(hProcess, (uint)(j + k + 0x03C), infokeep, 4, ref BytesRead)) { int PEOffset = BitConverter.ToInt32(infokeep, 0); if (PEOffset > 0 && (PEOffset + 0x0120) < pagesize) { if (ReadProcessMemory(hProcess, (uint)(j + k + PEOffset), infokeep, 2, ref BytesRead)) { if (infokeep[0] == 0x050 && infokeep[1] == 0x045) { long NetMetadata = 0; if (ReadProcessMemory(hProcess, (uint)(j + k + PEOffset + 0x0E8), infokeep, 8, ref BytesRead)) { NetMetadata = BitConverter.ToInt64(infokeep, 0); } #region Dump Native if (NetMetadata != 0) { byte[] PeHeader = new byte[pagesize]; if (ReadProcessMemory(hProcess, (uint)(j + k), PeHeader, pagesize, ref BytesRead)) { int nrofsection = BitConverter.ToInt16(PeHeader, PEOffset + 0x06); if (nrofsection > 0) { int sectionalignment = BitConverter.ToInt32(PeHeader, PEOffset + 0x038); int filealignment = BitConverter.ToInt32(PeHeader, PEOffset + 0x03C); short sizeofoptionalheader = BitConverter.ToInt16(PeHeader, PEOffset + 0x014); bool IsDll = false; if ((PeHeader[PEOffset + 0x017] & 32) != 0) { IsDll = true; } IntPtr pointer = IntPtr.Zero; IMAGE_SECTION_HEADER[] sections = new IMAGE_SECTION_HEADER[nrofsection]; uint ptr = (uint)(j + k + PEOffset) + (uint)sizeofoptionalheader + 4 + (uint)Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)); for (int i = 0; i < nrofsection; i++) { byte[] datakeeper = new byte[Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))]; ReadProcessMemory(hProcess, ptr, datakeeper, (uint)datakeeper.Length, ref BytesRead); fixed(byte *p = datakeeper) { pointer = (IntPtr)p; } sections[i] = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(pointer, typeof(IMAGE_SECTION_HEADER)); ptr = ptr + (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); } // get total raw size (of all sections): int totalrawsize = 0; int rawsizeoflast = sections[nrofsection - 1].size_of_raw_data; int rawaddressoflast = sections[nrofsection - 1].pointer_to_raw_data; if (rawsizeoflast > 0 && rawaddressoflast > 0) { totalrawsize = rawsizeoflast + rawaddressoflast; } string filename = ""; // calculate right size of image int actualsizeofimage = BitConverter.ToInt32(PeHeader, PEOffset + 0x050); int sizeofimage = actualsizeofimage; int calculatedimagesize = BitConverter.ToInt32(PeHeader, PEOffset + 0x0F8 + 012); int rawsize, rawAddress, virtualsize, virtualAddress = 0; int calcrawsize = 0; for (int i = 0; i < nrofsection; i++) { virtualsize = sections[i].virtual_size; int toadd = (virtualsize % sectionalignment); if (toadd != 0) { toadd = sectionalignment - toadd; } calculatedimagesize = calculatedimagesize + virtualsize + toadd; } if (calculatedimagesize > sizeofimage) { sizeofimage = calculatedimagesize; } try { byte[] crap = new byte[totalrawsize]; } catch { totalrawsize = sizeofimage; } if (totalrawsize != 0) { try { byte[] rawdump = new byte[totalrawsize]; isok = ReadProcessMemory(hProcess, (uint)(j + k), rawdump, (uint)rawdump.Length, ref BytesRead); if (isok) { filename = Path.Combine(DirectoryName, "rawdump_" + (j + k).ToString("X8")); if (File.Exists(filename)) { filename = Path.Combine(DirectoryName, "rawdump" + CurrentCount.ToString() + "_" + (j + k).ToString("X8")); } if (IsDll) { filename = filename + ".dll"; } else { filename = filename + ".exe"; } File.WriteAllBytes(filename, rawdump); CurrentCount++; } } catch { } } byte[] virtualdump = new byte[sizeofimage]; Array.Copy(PeHeader, virtualdump, pagesize); int rightrawsize = 0; for (int l = 0; l < nrofsection; l++) { rawsize = sections[l].size_of_raw_data; rawAddress = sections[l].pointer_to_raw_data; virtualsize = sections[l].virtual_size; virtualAddress = sections[l].virtual_address; // RawSize = Virtual Size rounded on FileAlligment calcrawsize = 0; calcrawsize = virtualsize % filealignment; if (calcrawsize != 0) { calcrawsize = filealignment - calcrawsize; } calcrawsize = virtualsize + calcrawsize; if (calcrawsize != 0 && rawsize != calcrawsize && rawsize != virtualsize || rawAddress < 0) { // if raw size is bad: rawsize = virtualsize; rawAddress = virtualAddress; BinaryWriter writer = new BinaryWriter(new MemoryStream(virtualdump)); writer.BaseStream.Position = PEOffset + 0x0F8 + 0x28 * l + 16; writer.Write(virtualsize); writer.BaseStream.Position = PEOffset + 0x0F8 + 0x28 * l + 20; writer.Write(virtualAddress); writer.Close(); } byte[] csection = new byte[0]; try { csection = new byte[rawsize]; } catch { csection = new byte[virtualsize]; } int rightsize = csection.Length; isok = ReadProcessMemory(hProcess, (uint)(j + k + virtualAddress), csection, (uint)rawsize, ref BytesRead); if (!isok || BytesRead != rawsize) { rightsize = 0; byte[] currentpage = new byte[pagesize]; for (int c = 0; c < rawsize; c = c + (int)pagesize) { // some section have a houge size so : try try { isok = ReadProcessMemory(hProcess, (uint)(j + k + virtualAddress + c), currentpage, pagesize, ref BytesRead); } catch { break; } if (isok) { rightsize = rightsize + (int)pagesize; for (int i = 0; i < pagesize; i++) { if ((c + i) < csection.Length) { csection[c + i] = currentpage[i]; } } } } } try { Array.Copy(csection, 0, virtualdump, rawAddress, rightsize); } catch { } if (l == nrofsection - 1) { rightrawsize = rawAddress + rawsize; } } FixImportandEntryPoint((int)(j + k), virtualdump); filename = Path.Combine(DirectoryName, "vdump_" + (j + k).ToString("X8")); if (File.Exists(filename)) { filename = Path.Combine(DirectoryName, "vdump" + CurrentCount.ToString() + "_" + (j + k).ToString("X8")); } if (IsDll) { filename = filename + ".dll"; } else { filename = filename + ".exe"; } using (var fout = new FileStream(filename, FileMode.Create)) fout.Write(virtualdump, 0, Math.Min(rightrawsize, virtualdump.Length)); CurrentCount++; } } // dumping end here } #endregion } } } } } } } } // rename files: foreach (FileInfo fi in new DirectoryInfo(DirectoryName).GetFiles()) { FileVersionInfo info = FileVersionInfo.GetVersionInfo(fi.FullName); string validOriginalFilename = MegaDumperHelper.EnsureValidFileName(info.OriginalFilename); if (validOriginalFilename != "") { string Newfilename = Path.Combine(DirectoryName, validOriginalFilename); int count = 2; if (File.Exists(Newfilename)) { string extension = Path.GetExtension(Newfilename); if (extension == "") { extension = ".dll"; } do { Newfilename = Path.Combine(DirectoryName, Path.GetFileNameWithoutExtension(validOriginalFilename) + "(" + count.ToString() + ")" + extension); count++; }while (File.Exists(Newfilename)); } File.Move(fi.FullName, Newfilename); } } MegaDumperHelper.Classify(DirectoryName); CurrentCount--; return(CurrentCount); } finally { CloseHandle(hProcess); } }
public static unsafe int DumpProcess(uint processId, string DirectoryName) { IntPtr processHandle; processHandle = OpenProcess(1080u, 0, processId); if (processHandle == IntPtr.Zero) { return(0); } try { MegaDumperHelper.CreateDirectories(DirectoryName); int num2 = 1; MEMORY_BASIC_INFORMATION memory_BASIC_INFORMATION; for (ulong num3 = minAddress; num3 < maxAddress; num3 = memory_BASIC_INFORMATION.BaseAddress + memory_BASIC_INFORMATION.RegionSize) { VirtualQueryEx(processHandle, (IntPtr)num3, out memory_BASIC_INFORMATION, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))); if (memory_BASIC_INFORMATION.State == 4096) { byte[] array = new byte[memory_BASIC_INFORMATION.RegionSize]; uint num4 = 0u; byte[] array2 = new byte[8]; bool flag = ReadProcessMemory(processHandle, (IntPtr)((long)num3), array, (uint)array.Length, ref num4); if (flag) { for (int i = 0; i < array.Length - 2; i++) { if (array[i] == 77 && array[i + 1] == 90) { if (ReadProcessMemory(processHandle, (IntPtr)((long)(num3 + (ulong)i + 60UL)), array2, 4u, ref num4)) { int num5 = BitConverter.ToInt32(array2, 0); if (num5 > 0 && num5 + 288 < array.Length) { if (ReadProcessMemory(processHandle, (IntPtr)((long)(num3 + (ulong)i + (ulong)num5)), array2, 2u, ref num4)) { if (array2[0] == 80 && array2[1] == 69) { long num6 = 0L; try { if (ReadProcessMemory(processHandle, (IntPtr)((long)(num3 + (ulong)i + (ulong)num5 + 248UL)), array2, 8u, ref num4)) { num6 = BitConverter.ToInt64(array2, 0); } } catch { } #region Dump Native byte[] array3 = new byte[PageSize]; if (ReadProcessMemory(processHandle, (IntPtr)((long)(num3 + (ulong)i)), array3, (uint)array3.Length, ref num4)) { int num7 = BitConverter.ToInt16(array3, num5 + 6); if (num7 > 0) { int num8 = BitConverter.ToInt32(array3, num5 + 56); int num9 = BitConverter.ToInt32(array3, num5 + 60); short num10 = BitConverter.ToInt16(array3, num5 + 20); bool isDll = false; if ((array3[num5 + 23] & 32) != 0) { isDll = true; } IntPtr ptr = IntPtr.Zero; IMAGE_SECTION_HEADER[] array4 = new IMAGE_SECTION_HEADER[num7]; ulong num11 = num3 + (ulong)i + (ulong)num5 + (ulong)num10 + 4UL + (ulong)Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)); for (int j = 0; j < num7; j++) { byte[] array5 = new byte[Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER))]; ReadProcessMemory(processHandle, (IntPtr)((long)num11), array5, (uint)array5.Length, ref num4); fixed(byte *ptr2 = array5) { ptr = (IntPtr)((void *)ptr2); } array4[j] = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(ptr, typeof(IMAGE_SECTION_HEADER)); num11 += (ulong)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)); } int num12 = 0; int size_of_raw_data = array4[num7 - 1].size_of_raw_data; int pointer_to_raw_data = array4[num7 - 1].pointer_to_raw_data; if (size_of_raw_data > 0 && pointer_to_raw_data > 0) { num12 = size_of_raw_data + pointer_to_raw_data; } int num13 = BitConverter.ToInt32(array3, num5 + 80); int num14 = num13; int num15 = array4[0].pointer_to_raw_data; int num16 = 0; for (int j = 0; j < num7; j++) { int virtual_size = array4[j].virtual_size; int num17 = virtual_size % num8; if (num17 != 0) { num17 = num8 - num17; } num15 = num15 + virtual_size + num17; } if (num15 > num14) { num14 = num15; } try { byte[] array6 = new byte[num12]; } catch { num12 = num14; } if (num12 != 0) { byte[] array7 = new byte[num12]; try { if (ReadProcessMemory(processHandle, (IntPtr)((long)(num3 + (ulong)i)), array7, (uint)array7.Length, ref num4)) { string filePath1 = Path.Combine(DirectoryName, "rawdump_" + (num3 + (ulong)i).ToString("X16")); if (File.Exists(filePath1)) { filePath1 = Path.Combine(DirectoryName, "rawdump" + num2.ToString() + "_" + (num3 + (ulong)i).ToString("X16")); } if (isDll) { filePath1 += ".dll"; } else { filePath1 += ".exe"; } File.WriteAllBytes(filePath1, array7); num2++; } } catch { } } byte[] array8 = new byte[num14]; Array.Copy(array3, array8, (long)((ulong)PageSize)); int num18 = 0; for (int k = 0; k < num7; k++) { int num19 = array4[k].size_of_raw_data; int num20 = array4[k].pointer_to_raw_data; int virtual_size = array4[k].virtual_size; num16 = array4[k].virtual_address; #region Dump RAW int num21 = virtual_size % num9; if (num21 != 0) { num21 = num9 - num21; } num21 = virtual_size + num21; if ((num21 != 0 && num19 != num21 && num19 != virtual_size) || num20 < 0) { num19 = virtual_size; num20 = num16; BinaryWriter binaryWriter = new BinaryWriter(new MemoryStream(array8)); binaryWriter.BaseStream.Position = num5 + 232 + 40 * k + 20 + 28; binaryWriter.Write(virtual_size); binaryWriter.BaseStream.Position = num5 + 232 + 40 * k + 24 + 28; binaryWriter.Write(num16); binaryWriter.Close(); } #endregion byte[] array9 = new byte[0]; try { array9 = new byte[num19]; } catch { array9 = new byte[virtual_size]; } int num22 = array9.Length; flag = ReadProcessMemory(processHandle, (IntPtr)((long)(num3 + (ulong)i + (ulong)num16)), array9, (uint)num19, ref num4); if (!flag || num4 != (ulong)num19) { num22 = 0; byte[] array10 = new byte[PageSize]; for (int l = 0; l < num19; l += (int)PageSize) { try { flag = ReadProcessMemory(processHandle, (IntPtr)((long)(num3 + (ulong)i + (ulong)num16 + (ulong)l)), array10, PageSize, ref num4); } catch { break; } if (flag) { num22 += (int)PageSize; int j = 0; while (j < (long)((ulong)PageSize)) { if (l + j < array9.Length) { array9[l + j] = array10[j]; } j++; } } } } try { Array.Copy(array9, 0, array8, num20, num22); } catch { } if (k == num7 - 1) { num18 = num20 + num19; } } string filePath2 = Path.Combine(DirectoryName, "vdump_" + (num3 + (ulong)i).ToString("X16")); if (File.Exists(filePath2)) { filePath2 = Path.Combine(DirectoryName, "vdump" + num2.ToString() + "_" + (num3 + (ulong)i).ToString("X16")); } if (isDll) { filePath2 += ".dll"; } else { filePath2 += ".exe"; } using (FileStream fileStream = new FileStream(filePath2, FileMode.Create)) fileStream.Write(array8, 0, Math.Min(num18, array8.Length)); num2++; } } #endregion } } } } } } } } } #region 修复文件名 foreach (FileInfo fileInfo in new DirectoryInfo(DirectoryName).GetFiles()) { FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(fileInfo.FullName); string validOriginalFilename = MegaDumperHelper.EnsureValidFileName(versionInfo.OriginalFilename); if (validOriginalFilename != "") { string filePath3 = Path.Combine(DirectoryName, validOriginalFilename); int repetition = 2; if (File.Exists(filePath3)) { string extension = Path.GetExtension(filePath3); if (extension == "") { extension = ".dll"; } do { filePath3 = Path.Combine(DirectoryName, Path.GetFileNameWithoutExtension(validOriginalFilename) + "(" + repetition.ToString() + ")" + extension); repetition++; }while (File.Exists(filePath3)); } File.Move(fileInfo.FullName, filePath3); } } MegaDumperHelper.Classify(DirectoryName); #endregion num2--; return(num2); } finally { CloseHandle(processHandle); } }