Перейти к содержанию

CreateRemoteThread [C#] Сапер


Рекомендуемые сообщения

Всем привет, заинтересован внедрением своего кода в чужой процесс, научился делать AOB-инъекцию, как например с помощью CE 

В целом, инъекция в CE работает, вот код 

Скрытый текст

[ENABLE]
alloc(mycode,0x1000)
registersymbol(mycode)
createthread(mycode)


mycode:
sub rsp, 0x28
call minesweeper.exe+351E0
add rsp, 0x28
ret

[DISABLE]
unregistersymbol(mycode)
dealloc(mycode)

Что он делает? - Вызывает окно "о программе" в стандартном виндовском приложении сапер (MineSweeper)

Теперь этот кодец я бы хотел для примера внедрить в программу

Написал программу(а точнее взял пример с сайта и корректировал под свой процесс, для изучения этого процесса 

Скрытый текст

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace RemoteThread
{
    class Program
    {

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
        [DllImport("kernel32.dll")]
        public static extern bool CloseHandle(IntPtr hObject);
        [DllImport("kernel32.dll")]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
        [DllImport("kernel32.dll")]
        public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
        [DllImport("kernel32.dll")]
        public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);


        [Flags]
        public enum ProcessAccessFlags : uint
        {
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VMOperation = 0x00000008,
            VMRead = 0x00000010,
            VMWrite = 0x00000020,
            DupHandle = 0x00000040,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            Synchronize = 0x00100000,
            All = 0x001F0FFF
        }

        [Flags]
        public enum AllocationType
        {
            Commit = 0x00001000,
            Reserve = 0x00002000,
            Decommit = 0x00004000,
            Release = 0x00008000,
            Reset = 0x00080000,
            TopDown = 0x00100000,
            WriteWatch = 0x00200000,
            Physical = 0x00400000,
            LargePages = 0x20000000
        }

        [Flags]
        public enum MemoryProtection
        {
            NoAccess = 0x0001,
            ReadOnly = 0x0002,
            ReadWrite = 0x0004,
            WriteCopy = 0x0008,
            Execute = 0x0010,
            ExecuteRead = 0x0020,
            ExecuteReadWrite = 0x0040,
            ExecuteWriteCopy = 0x0080,
            GuardModifierflag = 0x0100,
            NoCacheModifierflag = 0x0200,
            WriteCombineModifierflag = 0x0400
        }
        public delegate int ThreadProc(IntPtr param);


        static void Main(string[] args)
        {
            byte[] asm = new byte[] {
                0x48, 0x83, 0xEC, 0x28,
                0xFF, 0x15, 0x02, 0x00, 0x00, 0x00,
                0xEB, 0x08,
                0xE0, 0x51, 
                0xB4, 0xFF,
                0x00, 0x00,
                0x00, 0x00,
                0x48, 0x83, 0xC4, 0x28,
                0xC3
};
            int iProcessId = 3408;
            IntPtr hHandle = OpenProcess(ProcessAccessFlags.All, false, iProcessId);

            if (hHandle == IntPtr.Zero)
                throw new ApplicationException("Cannot get process handle.");
            IntPtr hAlloc = VirtualAllocEx(hHandle, IntPtr.Zero, (uint)asm.Length, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);

            if (hAlloc == IntPtr.Zero)
                throw new ApplicationException("Cannot allocate memory.");
            UIntPtr bytesWritten = UIntPtr.Zero;

            if (!WriteProcessMemory(hHandle, hAlloc, asm, (uint)asm.Length, out bytesWritten))
                throw new ApplicationException("Cannot write process memory.");

            if (asm.Length != (int)bytesWritten)
                throw new ApplicationException("Invalid written size.");
            uint iThreadId = 0;
            IntPtr hThread = CreateRemoteThread(hHandle, IntPtr.Zero, 0, hAlloc, IntPtr.Zero, 0, out iThreadId);

            if (hThread == IntPtr.Zero)
                throw new ApplicationException("Cannot create and execute remote thread.");
            CloseHandle(hThread);
            CloseHandle(hHandle);


        }
    }
}
 

Таким образом программа компилится и вылетает на 5ом исключении(последнее - "Cannot create and execute remote thread.")

Хотелось бы узнать, в чем проблема, ведь среда не пишет конкретной ошибки в коде, кроме как специально созданной)

Ассемблерный листинг команд записан правильно. Память с кодом действительно выделилась в программе - проверил лично)

Флаги, права доступа указаны, что может быть еще не так?

Тема до жути интересна, на данный момент высвободилось время для изучения, чему я и рад)

 

Кто может протестировать и подсказать, в чем я ошибся ? 

 

Изменено пользователем Trix
Ссылка на комментарий
Поделиться на другие сайты

Не знаю может поможет, я с помощью CreateRemoteThread только подгружал дллку в удаленный процесс пришлось включать SeDebugPrivilege, без неё программа не хотела создавать поток, хотя вроде как должна была.

 

Скрытый текст

char dll[MAX_PATH];
GetFullPathName("idklol.dll", MAX_PATH, dll, NULL);
LPSTR lpName;
TOKEN_PRIVILEGES newPriv, oldPriv;
HANDLE hToken,Process;
LUID luid;

Process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION);

OpenProcessToken(Process, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
newPriv.PrivilegeCount = 1;
newPriv.Privileges[0].Luid = luid;
newPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

LookupPrivilegeName(NULL, &newPriv.Privileges[0].Luid, lpName, &cchName);
lpName = malloc(cchName + 1);
LookupPrivilegeName(NULL, &newPriv.Privileges[0].Luid, lpName, &cchName);
free(lpName);

auto LoadLibrary = reinterpret_cast<LPVOID>(GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"));

auto Memory = reinterpret_cast<LPVOID>(VirtualAllocEx(Process, NULL, strlen(dll) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));

WriteProcessMemory(Process, reinterpret_cast<LPVOID>(Memory), dll, strlen(dll) + 1, NULL);


CreateRemoteThread(Process, NULL, NULL, reinterpret_cast<LPTHREAD_START_ROUTINE>(LoadLibrary), reinterpret_cast<LPVOID>(Memory), NULL, NULL);

CloseHandle(hToken);

VirtualFreeEx(Process, reinterpret_cast<LPVOID>(Memory), 0, MEM_RELEASE);

CloseHandle(Process);

 

1 час назад, Trix сказал:

Теперь этот кодец я бы хотел для примера внедрить в программу

 

Почитай, про Middle Hook Function, может в твоем случае это более подходящий вариант, чем создание удаленного потока.

Изменено пользователем partoftheworlD
Ссылка на комментарий
Поделиться на другие сайты

Как вы все сложно делаете.... Почему вам просто не взять готовую длл для .net? Blackmagic, memory etc...

На всю запись в адресс у тебя уйдет 5-10 строчек кода. Согласись, намного проще будет

Ссылка на комментарий
Поделиться на другие сайты

6 минут назад, roma91212 сказал:

Как вы все сложно делаете.... Почему вам просто не взять готовую длл для .net? Blackmagic, memory etc...

На всю запись в адресс у тебя уйдет 5-10 строчек кода. Согласись, намного проще будет

Самому делать интересней, чем юзать готовое все.:D Это как "зачем взламывать игры, когда можно купить читы или скачать трейнер"

Изменено пользователем partoftheworlD
Ссылка на комментарий
Поделиться на другие сайты

12 минуты назад, partoftheworlD сказал:

Самому делать интересней, чем юзать готовое все.:D Это как "зачем взламывать игры, когда можно купить читы или скачать трейнер"

Взломал игру - сохранил табличку, так и писать ничегг не придется. А если что-то и реализовывать - то такие вещи, которые до тебя еще не делали.

Ссылка на комментарий
Поделиться на другие сайты

8 часов назад, roma91212 сказал:

Как вы все сложно делаете.... Почему вам просто не взять готовую длл для .net? Blackmagic, memory etc...

На всю запись в адресс у тебя уйдет 5-10 строчек кода. Согласись, намного проще будет

Да, я что-то слышал про BlackMagic, правда не разобрался, гляну, спасибо)

Ссылка на комментарий
Поделиться на другие сайты

8 часов назад, roma91212 сказал:

Взломал игру - сохранил табличку, так и писать ничегг не придется. А если что-то и реализовывать - то такие вещи, которые до тебя еще не делали.

Да, интересней самому)

8 часов назад, roma91212 сказал:

Взломал игру - сохранил табличку, так и писать ничегг не придется. А если что-то и реализовывать - то такие вещи, которые до тебя еще не делали.

Нет, тут немного запутанней, есть идея написать ради интереса алгоритм, который заместо игрока будет выполнять одну простую тривиальную функцию из пары шагов(как например рыбалка в WOW, только проще)

Ссылка на комментарий
Поделиться на другие сайты

11 час назад, 2zolo2 сказал:

Это хороший совет, благодарю)

Если я правильно понял, то выполняется на шарпе это вот так(из описания msdn)
 

int error = Marshal.GetLastWin32Error();

И тут непонятное мне явление - если так и оставить, то ошибка будет нуливая, если перед этим заставить консоль что-нибудь вывести - получится ошибка 5

"Доступ запрещен", почитал стековерфлоу, там ссылаются на ошибку компиляции под разные разрядности системы, честно, не очень-то и понял. 

Получается, что сапер другой разрядности или как? Был бы очень благодарен за объяснения, ибо понять что к чему в такой ситуации трудно, 

на всевозможных топиках и статьях все облачно и работает, а у меня что-то не очень) 

Для примера сделал более простую инъекцию в CE-Tutorial, все работает как часы)

Ссылка на комментарий
Поделиться на другие сайты

9 минут назад, Trix сказал:

Получается, что сапер другой разрядности или как?

Скорее всего 64-битная.

10 минуту назад, Trix сказал:

Для примера сделал более простую инъекцию в CE-Tutorial, все работает как часы)

А Туториал ты скорее всего запускал именно 32-битный.

Попробуй на 64-битном туториале сделать, скорее всего тебе нужно будет переписать под 64 свой код.

Ссылка на комментарий
Поделиться на другие сайты

Предлагаю для начала сделать то же самое из СЕ, автоассемблером. А дальше уже смотреть, где косяк - в коде, в правах доступа или где-то еще.

Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, keng сказал:

Предлагаю для начала сделать то же самое из СЕ, автоассемблером. А дальше уже смотреть, где косяк - в коде, в правах доступа или где-то еще.

Кенг, со всем уважением)
Чит в автоассемблере исправно работает, а при инъекции ошибки

Ссылка на комментарий
Поделиться на другие сайты

22 hours ago, Trix said:

Кенг, со всем уважением)
Чит в автоассемблере исправно работает, а при инъекции ошибки

Не, ты не понял. Из автоассемблера вызови CreateRemoteThread, скормив ему нужный код.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.