using System.Collections.Generic;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
[DllImport("Kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr handle, long address, byte[] bytes, long nsize, ref long op);
[DllImport("Kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hwind, long Address, byte[] bytes, long nsize, out long output);
[DllImport("Kernel32.dll")]
public static extern IntPtr OpenProcess(int Token, bool inheritH, int ProcID);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, long lpAddress,
uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int VirtualQuery(IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
[DllImport("kernel32.dll")]
public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
public struct MEMORY_BASIC_INFORMATION
public long AllocationBase;
public long AllocationProtect;
public struct SYSTEM_INFO
public ushort processorArchitecture;
public IntPtr minimumApplicationAddress;
public IntPtr maximumApplicationAddress;
public IntPtr activeProcessorMask;
public uint numberOfProcessors;
public uint processorType;
public uint allocationGranularity;
public ushort processorLevel;
public ushort processorRevision;
ExecuteReadWrite = 0x0040,
ExecuteWriteCopy = 0x0080,
GuardModifierflag = 0x0100,
NoCacheModifierflag = 0x0200,
WriteCombineModifierflag = 0x0400,
Proc_All_Access = 2035711
private static byte[] OriginalCode = { 0x41, 0x90, 0x01, 0x00, 0x00, 0x00, 0x44, 0x89, 0x90, 0x24, 0x90, 0x41, 0x83, 0x90, 0xFF, 0x4C, 0x90, 0x90, 0x8B, 0x90 };
private static long PatchOffsetLocation = 0x00;
static void Main(string[] args)
Console.Title = "PacketTracer7 - Password Recovery Tool";
Process[] processes = Process.GetProcessesByName("PacketTracer");
if(processes.Count() == 0)
Console.WriteLine("Packet tracer not found!\nPlease open Packet Tracer first and try again.\n\nPress any key to exit...");
Console.WriteLine("Packet tracer found!");
foreach(var p in processes)
Console.WriteLine("Targeting PID 0x" + p.Id.ToString("X"));
Console.WriteLine("Done! Press any key to exit...");
private static void PrintBanner()
Console.WriteLine(@" __________ __ __ ___________ ");
Console.WriteLine(@" \______ \_____ ____ | | __ _____/ |_ \__ ___/___________ ____ ___________ ");
Console.WriteLine(@" | ___/\__ \ _/ ___\| |/ // __ \ __\ | | \_ __ \__ \ _/ ___\/ __ \_ __ \ ");
Console.WriteLine(@" | | / __ \\ \___| <\ ___/| | | | | | \// __ \\ \__\ ___/| | \/ ");
Console.WriteLine(@" |____| (____ /\___ >__|_ \\___ >__| |____| |__| (____ /\___ >___ >__| ");
Console.WriteLine(@" \/ \/ \/ \/ \/ \/ \/ (Recovery tool)");
Console.ForegroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("RHR98Crux3DEZPXzjLBpfmHTHKqJ\n");
private static void InjectAssembly(Process process)
IntPtr wHandle = OpenProcess((int)MemoryProtection.Proc_All_Access, false, process.Id);
byte[] PWoverwrite = new byte[]
0x38, 0x00, 0x30, 0x00, 0x35, 0x00, 0x46, 0x00, 0x34, 0x00, 0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 0x37, 0x00, 0x32, 0x00, 0x37, 0x00, 0x45, 0x00, 0x37, 0x00, 0x46, 0x00, 0x41, 0x00, 0x33, 0x00, 0x46, 0x00, 0x43, 0x00, 0x35, 0x00, 0x44, 0x00, 0x37, 0x00, 0x46, 0x00, 0x46, 0x00, 0x45, 0x00, 0x45, 0x00, 0x32, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x35, 0x00, 0x45, 0x00, 0x43, 0x00,
0x48, 0xB8, 0xDE, 0xAD, 0xC0, 0xDE, 0xDE, 0xC0, 0xAD, 0xDE,
PatchOffsetLocation = AOBScan(wHandle, ref OriginalCode);
for(int i = 15; i < OriginalCode.Length; i++)
if (PatchOffsetLocation > 0x0100)
Console.WriteLine("Placing hook at 0x" + PatchOffsetLocation.ToString("X"));
Console.WriteLine("Failed finding location, already patched?");
long hAlloc = (long)VirtualAllocEx(wHandle, 0, (uint)PWoverwrite.Length + (uint)OriginalCode.Length + 15, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
byte[] HashLocation = BitConverter.GetBytes(hAlloc + 2);
for (int i = 0; i < 8; i++)
PWoverwrite[i + 68] = HashLocation[i];
WriteProcessMemory(wHandle, hAlloc, PWoverwrite, PWoverwrite.Length, out BytesWritten);
Console.WriteLine("Failed patching PacketTracer memory ;_;");
WriteProcessMemory(wHandle, hAlloc + PWoverwrite.Length, OriginalCode, OriginalCode.Length, out BytesWritten);
Console.WriteLine("Failed patching PacketTracer memory ;_;");
byte[] LongJump = { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xC0, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0x90 };
byte[] ReturnAddress = BitConverter.GetBytes(PatchOffsetLocation + 14);
for(int i = 0; i < 8; i++)
LongJump[i + 6] = ReturnAddress[i];
WriteProcessMemory(wHandle, hAlloc + PWoverwrite.Length + OriginalCode.Length, LongJump, LongJump.Length, out BytesWritten);
Console.WriteLine("Failed patching PacketTracer memory ;_;");
byte[] LongJump2 = { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xC0, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0x90 };
byte[] ReturnAddress2 = BitConverter.GetBytes(hAlloc);
for (int i = 0; i < 8; i++)
LongJump[i + 6] = ReturnAddress2[ i];
WriteProcessMemory(wHandle, PatchOffsetLocation, LongJump, LongJump.Length, out BytesWritten);
Console.WriteLine("Failed patching PacketTracer memory ;_;");
Console.WriteLine("Password set to \"Ferib\"");
private static long AOBScan(IntPtr rHandle, ref byte[] AoBpattern)
SYSTEM_INFO sys_info = new SYSTEM_INFO();
GetSystemInfo(out sys_info);
IntPtr proc_min_address = sys_info.minimumApplicationAddress;
IntPtr proc_max_address = sys_info.maximumApplicationAddress;
ulong proc_min_address_l = (ulong)proc_min_address;
ulong proc_max_address_l = (ulong)proc_max_address;
MEMORY_BASIC_INFORMATION mem_basic_info = new MEMORY_BASIC_INFORMATION();
while (proc_min_address_l < proc_max_address_l)
VirtualQueryEx(rHandle, proc_min_address, out mem_basic_info, 56);
Console.Write("0x" + proc_min_address.ToString("X"));
if (mem_basic_info.AllocationProtect <= 0x80 && mem_basic_info.AllocationProtect >= 0x20 && mem_basic_info.RegionSize < int.MaxValue)
Console.Write(" scanning..");
byte[] ScanMemory = new byte[mem_basic_info.RegionSize];
byte[] buffer = new byte[mem_basic_info.RegionSize];
ReadProcessMemory(rHandle, mem_basic_info.BaseAddress, buffer, mem_basic_info.RegionSize, ref bytesRead);
for (long i = 0; i < buffer.Length - AoBpattern.Length - 1; i++)
for (long j = 0; j < AoBpattern.Length; j++)
if (j == AoBpattern.Length - 1)
for (long x = AoBpattern.Length-1; x >= 0; x--)
AoBpattern[x] = buffer[i + j - AoBpattern.Length + 1 + x];
return result = (long)proc_min_address + i;
if(AoBpattern[j] != 0x90)
if (buffer[i + j] != AoBpattern[j])
proc_min_address_l += (ulong)mem_basic_info.RegionSize;
proc_min_address = (IntPtr)proc_min_address_l;