l3ftoverz
@l3ftoverz
Туды сюды

Как люди узнавали какой ASM код нужно инжектить в другой процесс, чтобы использовать функционал заражаемого процесса?

Есть такой код, этот код написал не я, я его только немного изменил.
Я пытаюсь разобраться с внедрением ASM кода в другой процесс, всё, что я нашёл - материалы разных форумов с очень большой давностью, все авторы статей давно не были в сети и на связь не выходят.

Меня интересует момент с вставкой ASM кода, где его брали? Его же как-то в процессе дебага находили в памяти процесса \ через ollydb или аналоги? Как мне выявить код, который исполняется при каком-то событии? Например я открою клиент игры и сделаю 3 шага вперёд - по идее же должен выполниться код, который где-то в памяти (Если я верно понимаю суть работы программ) - как мне "поймать" этот код, что бы использовать в своих целях?
  • Вопрос задан
  • 210 просмотров
Решения вопроса 2
JRK_DV
@JRK_DV
Рецепты https://codepen.io/jrkdv/full/LKLXdq
всё, что я нашёл - материалы разных форумов с очень большой давностью

Кардинально ничего не поменялось, всё так же используется ассемблер
Изменились, например, инструменты, softice на ollydbg или windbg, какие то техники для доставки кода.

Есть такой код, этот код написал не я, я его только немного изменил. Я пытаюсь разобраться с внедрением ASM кода в другой процесс

В этом коде используется, можно сказать, классическая инъекция, через выделение памяти в чужом процессе и запуска потока на исполнение Асм инструкций в выделенном блоке памяти
Это реализовано в функции "InjectAndExecute"
Несколько комментариев к коду
// 71:
// Ищем окно и идентификатор процесса, который создал данное окно
HWND windowHandle = FindWindowA("ElementClient Window", NULL);
GetWindowThreadProcessId(windowHandle, &pId);
// 82:
// Открываем чужой процесс со всеми правами (На эту операцию требуются права администратора)
hProc = OpenProcess(PROCESS_ALL_ACCESS, false, pId);
// 89-90:
// В открытом чужом процессе выделяем, в памяти, блоки размерами 4096 и 256 байт для чтения и записи
// Тут большинство античитов поднимут тревогу :)
pFunction = VirtualAllocEx(hProc, NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
pParams = VirtualAllocEx(hProc, NULL, 256, MEM_COMMIT, PAGE_READWRITE);
// 91-92:
// В выделенную память записываем Асм инструкции из тела функции по указателю Func
WriteProcessMemory(hProc, pFunction, Func, 4096, NULL);
WriteProcessMemory(hProc, pParams, Params, 256, NULL);
// 94:
// Финальная стадия - запускаем в чужом процессе поток на выполнение Асм инструкций по начальному адресу pFunction
hProcThread = CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)pFunction, pParams, NULL, NULL);


Меня интересует момент с вставкой ASM кода, где его брали?

// 134:
// Скорее всего по этому адресу в клиенте игры находится функция, которая инициирует действие игрока
mov edx, 0x0044FE60

Означает что внутри клиента игры по адресу "0x0044FE60" есть функция, которая начинает логику "Атаковать".
Получается когда мы внедрили наш код, то он запустил оригинальную функцию игры для атаки.
* Атака, - если судить по названию инжектируемой функции Attack_THREAD()

На счёт вопроса где его брали?
Да вы на правильном пути. Используют отладчики. Если упрощённо, то это было так:
В клиенте игры нашли функцию "Атаковать" и определили какие она принимает параметры.
Дальше, в данном случае, написали Асм инструкции, которые запускают оригинальную функцию игрового клиента, при этом никакие оригинальные функции игры не подменяются.
Ответ написан
dollar
@dollar
Сначала нужно изучить код заражаемого процесса. То есть по сути произвести обратный инжиниринг. После этого, когда уже есть представление о структуре кода, хоть и в машинном виде, но всё же можно выделить логически, где что находится и за что отвечает, то начинается создание своего кода, который в эту структуру органично впишется.

Это касается даже не столько ассемблера, сколько инжекта как такового вообще.

Простой пример: есть вызов функции. Вы хотите инжекнуться в это место. То есть вы меняете этот вызов так, что он вызывает не функцию, а ваш собственный код, затем ваш код что-то делает, и уже вызывает конечную функцию. То есть ваш код как бы вклинивается в вызов, получая аргументы функции, а потом передавая эти же аргументы дальше по цепочке. С точки зрения приложения практически ничего не изменилось, т.к. в функцию приходят аргументы, а потом попадают внутрь функции и используются там. Но реально они могут быть просмотрены или даже изменены (подмена) вашим кодом. И здесь сразу есть два важных момента:
1) Вы должны понимать, что это за функция (логически) и что это за аргументы (логически). То есть что это вообще такое и зачем оно вам нужно. Иначе инжект не имеет смысла, потому что это просто какие-то цифры и какая-то передача управления через стек.
2) Вы должны понимать, что можно, а что нельзя (в плане изменений). Скажем, можно ли менять аргументы. И если можно, то в каких пределах, чтобы ничего не сломалось. Можно ли вам использовать конкретные регистры процессора (хотя бы общего назначения) безнаказанно, или же вам надо обязательно восстановить их исходное значение в момент вызова функции.
Вот, чтобы эти два пункта выполнить, нужно изучить заражаемый процесс, как он устроен, что там происходит и т.д. Это поможет не только создать код инжекта, но и найти самое клёвое и удобное место для инжекта, который даст вам максимальный профит.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы