2015-12-19 5 views
0

Я пытаюсь ввести заглушку в 64-битный процесс Windows из моего 32-битного процесса, а затем удаленно запустить поток в процессе x64. Это вызывает некоторые проблемы, потому что winapi's CreateRemoteThread выбрасывает код ошибки 5, который переводит на ERROR_ACCESS_DENIED, независимо от того, какие флаги я использую при вызове OpenProcess. Я читал, что это связано с тем, что Windows не позволит впрыскивать «кросс-платформу», но я не думаю, что это проблема, поскольку код вводит штраф.CreateRemoteThread, ошибка 5

Я использую GetLastError() сразу после вызова CreateRemoteThread() и показывает код ошибки 5.

Я использую этот набор флагов для OpenProcess, без успеха:

PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE 

, а также только PROCESS_ALL_ACCESS.

У кого-нибудь есть идея, что может вызвать эту ошибку?

ответ

3

Звонки на CreateRemoteThread, выполненные из 32-разрядного процесса, где целевой процесс составляет 64 бит, не поддерживаются. Вам нужно будет позвонить CreateRemoteThread из 64-битного процесса.

+0

Просто, чтобы быть уверенным; нет никакого способа обойти это? –

+0

Круглый, чтобы использовать 64-битный процесс! –

+0

Хорошо, спасибо, хотя это не вариант, поскольку мне пришлось бы переписать все приложение –

0

Невозможно сделать. Вы не можете запустить 32-разрядный код в 64-разрядном процессе, и вы не можете запустить 64-разрядный код в 32-битном процессе.

Решение состоит в том, чтобы восстановить код инъекции как 64-разрядный.

Это по дизайну. Процессор просто не работает точно так же в 32- и 64-битном режиме, и вы не можете тривиально переключаться с одного режима на другой и обратно. Несколько вещей сильно отличаются:

  • Инструкции Push и Pop всегда 64-разрядные в 64-разрядном режиме. Таким образом, 32-разрядный код будет вызывать 64-битные значения, и, таким образом, void foo(int x, int y) получит 64-разрядный x, охватывающий как x, так и y. Это затрагивает смещения для переменных в стеке и все остальное внутри функций.
  • Фактическое соглашение о вызове отличается - 32-разрядный режим использует разные регистры для передачи аргументов функциям (если любые аргументы передаются регистром - это необязательно), где 64-разрядный режим всегда использует регистры и больше регистров. Таким образом, вызовы из 32-битного режима будут иметь данные не в том месте для 64-битного режима и т. Д.
  • Кодировка инструкций для некоторых общих инструкций различна - в первую очередь, что 0x40-0x4f являются однобайтовыми инструкциями для PUSH/POP всех регистров , где этот диапазон является префиксом REX (Расширение регистра) в 64-битном режиме. 64-битный режим использует кодирования двухбайтовых [который был введен, чтобы позволить более гибкий набор инструкций PUSH/POP, с нескольких адресацией режимов, описанных во втором байте]

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

+0

Переключение режимов динамического процессора http://rce.co/knockin-on-heavens-gate-dynamic-processor-mode-switching/ – Balu

+0

@Balu Пробовали ли вы это решение? Я вижу, что это связано с ASM. Я задаюсь вопросом, является ли это прочным способом решения проблемы? –

+0

@PeterJensen да, это связано с некоторым сборочным кодированием для изменения регистра сегмента кода. Он будет работать, я использовал его для ввода 64-разрядной библиотеки DLL в 32-разрядный wow64-процесс. – Balu

Смежные вопросы