Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Гайд [Сурс] Очистка строк чита из памяти (SS Bypass) — C#

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
606
Реакции
16
Проверка на сервере или так называемый Screenshare (SS) в том же FiveM, Rust или Roblox — это всегда лотерея, если ты не умеешь за собой подметать. Современные админы уже давно не смотрят только папку загрузок; они лезут в строки системных процессов типа explorer.exe, lsass.exe и svchost.exe. Именно там оседает мусор в виде путей к файлам, названий ваших инжекторов и прочего палева, которое Process Hacker выплевывает на раз-два.

Суть метода
Идея проста: стучимся в системный процесс, получаем привилегии SeDebugPrivilege, меняем права доступа к региону памяти через VirtualProtectEx и затираем наши «грязные» строки рандомными байтами или нулями. Это позволяет закосить под легита, даже если проверка идет в режиме реального времени.

Техническая часть и грабли
Многие сталкиваются с проблемой при попытке изменить права доступа к памяти в системных процессах. Код ниже — это база для чистки, но имейте в виду: если вы ловите Error 487 (Invalid Address), то либо адрес уже невалиден (динамическая память, привет), либо вы пытаетесь прыгнуть выше головы без обхода PPL (Protected Process Light) в случае с тем же lsass.

Код:
Expand Collapse Copy
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Bypasser
{
    internal class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint dwSize, out int lpNumberOfBytesWritten);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID luid);

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool AdjustTokenPrivileges(IntPtr tokenHandle, bool disableAllPrivileges, ref TOKEN_PRIVILEGES newState, uint bufferLength, IntPtr previousState, IntPtr returnLength);

        private const string SE_DEBUG_NAME = "SeDebugPrivilege";
        private const uint PROCESS_VM_OPERATION = 0x0008;
        private const uint PROCESS_VM_WRITE = 0x0020;
        private const uint PROCESS_VM_READ = 0x0010;
        private const uint PAGE_READWRITE = 0x04;

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct LUID { public uint LowPart; public int HighPart; }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct TOKEN_PRIVILEGES { public int PrivilegeCount; public LUID Luid; public uint Attributes; }

        public static bool EnableDebugPrivilege()
        {
            if (!OpenProcessToken(Process.GetCurrentProcess().Handle, 0x0020 | 0x0008, out IntPtr tokenHandle)) return false;
            if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out LUID luid)) return false;
            TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES { PrivilegeCount = 1, Luid = luid, Attributes = 0x00000002 };
            return AdjustTokenPrivileges(tokenHandle, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
        }

        static void Main(string[] args)
        {
            if (!EnableDebugPrivilege()) return;
            
            int pid = 4420; // PID целевого процесса (например, explorer)
            IntPtr hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, pid);
            if (hProc == IntPtr.Zero) return;

            IntPtr targetAddr = (IntPtr)0x1d9d93bea18; // Адрес строки для затирки
            byte[] junk = new byte[16];
            new Random().NextBytes(junk);

            if (VirtualProtectEx(hProc, targetAddr, (UIntPtr)junk.Length, PAGE_READWRITE, out uint old))
            {
                WriteProcessMemory(hProc, targetAddr, junk, (uint)junk.Length, out _);
                VirtualProtectEx(hProc, targetAddr, (UIntPtr)junk.Length, old, out _);
            }
        }
    }
}

Важные нюансы:
  1. Адреса строк постоянно меняются. Хардкодить адрес, как в примере — гиблое дело. Нужно делать сигнатурный поиск или сканить всю область памяти процесса.
  2. Права доступа. Для затирки в lsass.exe простых дебаг-привилегий может не хватить, винда активно защищает эти процессы от записи.
  3. Антивирусы и проактивка. Юзать WriteProcessMemory в адресное пространство проводника — это прямая дорога к флагу от серьезных античитов, если те мониторят хендлы.

Если решили пилить свой клинер, советую смотреть в сторону более скрытных методов работы с памятью, иначе ваш «байпасс» сам станет отличным триггером для бана. Будет интересно глянуть, как вы реализуете динамический поиск паттернов в чужом адресном пространстве без серьезных просадок по скорости.
 
Назад
Сверху Снизу