Created
April 2, 2022 07:02
-
-
Save Wra7h/7b6c2ad5d4970891195c167013373cc4 to your computer and use it in GitHub Desktop.
Scan processes for any Application Recovery Callbacks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Scan for any Application Recovery Callbacks on your system. Each Process ID/Callback address combination should only be displayed once. | |
// Also, it's a continuous loop so it shouldn't die until you're done with it. | |
// Full PoC here: https://github.com/Wra7h/ARCInject | |
// Compile: C:\windows\Microsoft.NET\Framework64\v3.5\csc.exe .\ARC_Scan.cs | |
// Execute: .\ARC_Scan.exe | |
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
namespace ARC_Scan | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
List<KeyValuePair<int, IntPtr>> prevDetected = new List<KeyValuePair<int, IntPtr>>(); | |
Console.WriteLine("\t\t\t+----------------------+"); | |
Console.WriteLine("\t\t\t| ARC SCAN |"); | |
Console.WriteLine("\t\t\t+----------------------+\n"); | |
while (true) | |
{ | |
FindRegisteredCallbacks(ref prevDetected); | |
} | |
} | |
static void FindRegisteredCallbacks(ref List<KeyValuePair<int, IntPtr>> prevDetected) | |
{ | |
Process[] processList = Process.GetProcesses(); | |
IntPtr pRC = IntPtr.Zero; // A pointer to the recovery callback function. | |
IntPtr ppvParam = IntPtr.Zero; // A pointer to the callback parameter. | |
uint pdwPI = 0; // The recovery ping interval, in 100-nanosecond intervals. | |
uint reserved = 0; // Reserved for future use. | |
foreach (Process proc in processList) | |
{ | |
try | |
{ | |
uint ret = GetApplicationRecoveryCallback(proc.Handle, out pRC, out ppvParam, out pdwPI, out reserved); | |
if (ret == 0 && pRC != IntPtr.Zero) | |
{ | |
if (prevDetected.Where(kv => kv.Key == proc.Id).Count() == 0) | |
{ | |
Console.WriteLine("[+] Process Name: {0} | PID: {1} | Address: 0x{2:X}", proc.MainModule.ModuleName, proc.Id, pRC.ToInt64()); | |
prevDetected.Add(new KeyValuePair<int, IntPtr>(proc.Id, pRC)); | |
} | |
else if ((prevDetected.Where(kv => kv.Key == proc.Id).Count() > 0) && (prevDetected.Where(kv => kv.Value == pRC).Count() == 0)) | |
{ | |
Console.WriteLine("[+] Process Name: {0} | PID: {1} | Address: 0x{2:X}", proc.MainModule.ModuleName, proc.Id, pRC.ToInt64()); | |
prevDetected.Add(new KeyValuePair<int, IntPtr>(proc.Id, pRC)); | |
} | |
} | |
} | |
catch | |
{ | |
continue; //Keep looping through the other processes that have been identified | |
} | |
} | |
} | |
// GetApplicationRecoveryCallback: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getapplicationrecoverycallback | |
[DllImport("kernel32.dll")] | |
static extern uint GetApplicationRecoveryCallback(IntPtr hProcess, out IntPtr pRecoveryCallback, out IntPtr ppvParameter, out uint pdwPingInterval, out uint pdwFlags); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment