1
0
mirror of https://github.com/mastercodeon314/KsDumper-11.git synced 2024-11-27 16:00:53 +01:00
KsDumper-11/KsDumper11/ProcessDumper.cs
2023-01-21 19:32:57 -06:00

300 lines
10 KiB
C#

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using KsDumper11.Driver;
using KsDumper11.PE;
using KsDumper11.Utility;
namespace KsDumper11
{
// Token: 0x02000003 RID: 3
public class ProcessDumper
{
// Token: 0x0600002E RID: 46 RVA: 0x000038AD File Offset: 0x00001AAD
public ProcessDumper(DriverInterface kernelDriver)
{
this.kernelDriver = kernelDriver;
}
// Token: 0x0600002F RID: 47 RVA: 0x000038C0 File Offset: 0x00001AC0
private static bool IsWin64Emulator(Process process)
{
bool flag = Environment.OSVersion.Version.Major > 5 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1);
bool retVal;
return flag && (ProcessDumper.NativeMethods.IsWow64Process(process.Handle, out retVal) && retVal);
}
// Token: 0x06000030 RID: 48 RVA: 0x0000392C File Offset: 0x00001B2C
public bool DumpProcess(Process processSummary, out PEFile outputFile)
{
IntPtr basePointer = processSummary.MainModule.BaseAddress;
NativePEStructs.IMAGE_DOS_HEADER dosHeader = this.ReadProcessStruct<NativePEStructs.IMAGE_DOS_HEADER>(processSummary.Id, basePointer);
outputFile = null;
Logger.SkipLine();
Logger.Log("Targeting Process: {0} ({1})", new object[] { processSummary.ProcessName, processSummary.Id });
bool isValid = dosHeader.IsValid;
if (isValid)
{
IntPtr peHeaderPointer = basePointer + dosHeader.e_lfanew;
Logger.Log("PE Header Found: 0x{0:x8}", new object[] { peHeaderPointer.ToInt64() });
IntPtr dosStubPointer = basePointer + Marshal.SizeOf<NativePEStructs.IMAGE_DOS_HEADER>();
byte[] dosStub = this.ReadProcessBytes(processSummary.Id, dosStubPointer, dosHeader.e_lfanew - Marshal.SizeOf<NativePEStructs.IMAGE_DOS_HEADER>());
bool flag = !ProcessDumper.IsWin64Emulator(processSummary);
PEFile peFile;
if (flag)
{
peFile = this.Dump64BitPE(processSummary.Id, dosHeader, dosStub, peHeaderPointer);
}
else
{
peFile = this.Dump32BitPE(processSummary.Id, dosHeader, dosStub, peHeaderPointer);
}
bool flag2 = peFile != null;
if (flag2)
{
IntPtr sectionHeaderPointer = peHeaderPointer + peFile.GetFirstSectionHeaderOffset();
Logger.Log("Header is valid ({0}) !", new object[] { peFile.Type });
Logger.Log("Parsing {0} Sections...", new object[] { peFile.Sections.Length });
for (int i = 0; i < peFile.Sections.Length; i++)
{
NativePEStructs.IMAGE_SECTION_HEADER sectionHeader = this.ReadProcessStruct<NativePEStructs.IMAGE_SECTION_HEADER>(processSummary.Id, sectionHeaderPointer);
peFile.Sections[i] = new PESection
{
Header = PESection.PESectionHeader.FromNativeStruct(sectionHeader),
InitialSize = (int)sectionHeader.VirtualSize
};
this.ReadSectionContent(processSummary.Id, new IntPtr(basePointer.ToInt64() + (long)((ulong)sectionHeader.VirtualAddress)), peFile.Sections[i]);
sectionHeaderPointer += Marshal.SizeOf<NativePEStructs.IMAGE_SECTION_HEADER>();
}
Logger.Log("Aligning Sections...", Array.Empty<object>());
peFile.AlignSectionHeaders();
Logger.Log("Fixing PE Header...", Array.Empty<object>());
peFile.FixPEHeader();
Logger.Log("Dump Completed !", Array.Empty<object>());
outputFile = peFile;
return true;
}
Logger.Log("Bad PE Header !", Array.Empty<object>());
}
return false;
}
// Token: 0x06000031 RID: 49 RVA: 0x00003B80 File Offset: 0x00001D80
public bool DumpProcess(ProcessSummary processSummary, out PEFile outputFile)
{
IntPtr basePointer = (IntPtr)((long)processSummary.MainModuleBase);
NativePEStructs.IMAGE_DOS_HEADER dosHeader = this.ReadProcessStruct<NativePEStructs.IMAGE_DOS_HEADER>(processSummary.ProcessId, basePointer);
outputFile = null;
Logger.SkipLine();
Logger.Log("Targeting Process: {0} ({1})", new object[] { processSummary.ProcessName, processSummary.ProcessId });
bool isValid = dosHeader.IsValid;
if (isValid)
{
IntPtr peHeaderPointer = basePointer + dosHeader.e_lfanew;
Logger.Log("PE Header Found: 0x{0:x8}", new object[] { peHeaderPointer.ToInt64() });
IntPtr dosStubPointer = basePointer + Marshal.SizeOf<NativePEStructs.IMAGE_DOS_HEADER>();
byte[] dosStub = this.ReadProcessBytes(processSummary.ProcessId, dosStubPointer, dosHeader.e_lfanew - Marshal.SizeOf<NativePEStructs.IMAGE_DOS_HEADER>());
bool flag = !processSummary.IsWOW64;
PEFile peFile;
if (flag)
{
peFile = this.Dump64BitPE(processSummary.ProcessId, dosHeader, dosStub, peHeaderPointer);
}
else
{
peFile = this.Dump32BitPE(processSummary.ProcessId, dosHeader, dosStub, peHeaderPointer);
}
bool flag2 = peFile != null;
if (flag2)
{
IntPtr sectionHeaderPointer = peHeaderPointer + peFile.GetFirstSectionHeaderOffset();
Logger.Log("Header is valid ({0}) !", new object[] { peFile.Type });
Logger.Log("Parsing {0} Sections...", new object[] { peFile.Sections.Length });
for (int i = 0; i < peFile.Sections.Length; i++)
{
NativePEStructs.IMAGE_SECTION_HEADER sectionHeader = this.ReadProcessStruct<NativePEStructs.IMAGE_SECTION_HEADER>(processSummary.ProcessId, sectionHeaderPointer);
peFile.Sections[i] = new PESection
{
Header = PESection.PESectionHeader.FromNativeStruct(sectionHeader),
InitialSize = (int)sectionHeader.VirtualSize
};
this.ReadSectionContent(processSummary.ProcessId, new IntPtr(basePointer.ToInt64() + (long)((ulong)sectionHeader.VirtualAddress)), peFile.Sections[i]);
sectionHeaderPointer += Marshal.SizeOf<NativePEStructs.IMAGE_SECTION_HEADER>();
}
Logger.Log("Aligning Sections...", Array.Empty<object>());
peFile.AlignSectionHeaders();
Logger.Log("Fixing PE Header...", Array.Empty<object>());
peFile.FixPEHeader();
Logger.Log("Dump Completed !", Array.Empty<object>());
outputFile = peFile;
return true;
}
Logger.Log("Bad PE Header !", Array.Empty<object>());
}
return false;
}
// Token: 0x06000032 RID: 50 RVA: 0x00003DD4 File Offset: 0x00001FD4
private PEFile Dump64BitPE(int processId, NativePEStructs.IMAGE_DOS_HEADER dosHeader, byte[] dosStub, IntPtr peHeaderPointer)
{
NativePEStructs.IMAGE_NT_HEADERS64 peHeader = this.ReadProcessStruct<NativePEStructs.IMAGE_NT_HEADERS64>(processId, peHeaderPointer);
bool isValid = peHeader.IsValid;
PEFile pefile;
if (isValid)
{
pefile = new PE64File(dosHeader, peHeader, dosStub);
}
else
{
pefile = null;
}
return pefile;
}
// Token: 0x06000033 RID: 51 RVA: 0x00003E08 File Offset: 0x00002008
private PEFile Dump32BitPE(int processId, NativePEStructs.IMAGE_DOS_HEADER dosHeader, byte[] dosStub, IntPtr peHeaderPointer)
{
NativePEStructs.IMAGE_NT_HEADERS32 peHeader = this.ReadProcessStruct<NativePEStructs.IMAGE_NT_HEADERS32>(processId, peHeaderPointer);
bool isValid = peHeader.IsValid;
PEFile pefile;
if (isValid)
{
pefile = new PE32File(dosHeader, peHeader, dosStub);
}
else
{
pefile = null;
}
return pefile;
}
// Token: 0x06000034 RID: 52 RVA: 0x00003E3C File Offset: 0x0000203C
private T ReadProcessStruct<T>(int processId, IntPtr address) where T : struct
{
IntPtr buffer = MarshalUtility.AllocEmptyStruct<T>();
bool flag = this.kernelDriver.CopyVirtualMemory(processId, address, buffer, Marshal.SizeOf<T>());
T t;
if (flag)
{
t = MarshalUtility.GetStructFromMemory<T>(buffer, true);
}
else
{
t = default(T);
}
return t;
}
// Token: 0x06000035 RID: 53 RVA: 0x00003E80 File Offset: 0x00002080
private bool ReadSectionContent(int processId, IntPtr sectionPointer, PESection section)
{
int readSize = section.InitialSize;
bool flag = sectionPointer == IntPtr.Zero || readSize == 0;
bool flag2;
if (flag)
{
flag2 = true;
}
else
{
bool flag3 = readSize <= 100;
if (flag3)
{
section.DataSize = readSize;
section.Content = this.ReadProcessBytes(processId, sectionPointer, readSize);
flag2 = true;
}
else
{
this.CalculateRealSectionSize(processId, sectionPointer, section);
bool flag4 = section.DataSize != 0;
if (flag4)
{
section.Content = this.ReadProcessBytes(processId, sectionPointer, section.DataSize);
flag2 = true;
}
else
{
flag2 = false;
}
}
}
return flag2;
}
// Token: 0x06000036 RID: 54 RVA: 0x00003F18 File Offset: 0x00002118
private byte[] ReadProcessBytes(int processId, IntPtr address, int size)
{
IntPtr unmanagedBytePointer = MarshalUtility.AllocZeroFilled(size);
this.kernelDriver.CopyVirtualMemory(processId, address, unmanagedBytePointer, size);
byte[] buffer = new byte[size];
Marshal.Copy(unmanagedBytePointer, buffer, 0, size);
Marshal.FreeHGlobal(unmanagedBytePointer);
return buffer;
}
// Token: 0x06000037 RID: 55 RVA: 0x00003F5C File Offset: 0x0000215C
private void CalculateRealSectionSize(int processId, IntPtr sectionPointer, PESection section)
{
int readSize = section.InitialSize;
int currentReadSize = readSize % 100;
bool flag = currentReadSize == 0;
if (flag)
{
currentReadSize = 100;
}
IntPtr currentOffset = sectionPointer + readSize - currentReadSize;
while (currentOffset.ToInt64() >= sectionPointer.ToInt64())
{
byte[] buffer = this.ReadProcessBytes(processId, currentOffset, currentReadSize);
int codeByteCount = this.GetInstructionByteCount(buffer);
bool flag2 = codeByteCount != 0;
if (flag2)
{
currentOffset += codeByteCount;
bool flag3 = sectionPointer.ToInt64() < currentOffset.ToInt64();
if (flag3)
{
section.DataSize = (int)(currentOffset.ToInt64() - sectionPointer.ToInt64());
section.DataSize += 4;
bool flag4 = section.InitialSize < section.DataSize;
if (flag4)
{
section.DataSize = section.InitialSize;
}
}
break;
}
currentReadSize = 100;
currentOffset -= currentReadSize;
}
}
// Token: 0x06000038 RID: 56 RVA: 0x0000404C File Offset: 0x0000224C
private int GetInstructionByteCount(byte[] dataBlock)
{
for (int i = dataBlock.Length - 1; i >= 0; i--)
{
bool flag = dataBlock[i] > 0;
if (flag)
{
return i + 1;
}
}
return 0;
}
// Token: 0x0400002B RID: 43
private DriverInterface kernelDriver;
// Token: 0x02000023 RID: 35
internal static class NativeMethods
{
// Token: 0x060000EF RID: 239
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool IsWow64Process([In] IntPtr process, out bool wow64Process);
}
}
}