2009-10-11 7 views
2

У меня есть компилятор, который компилирует язык ассемблера на машинный язык (в памяти). Мой проект находится в C# .net. Есть ли способ запустить память в потоке? Как DEP может предотвратить это?как запустить некоторый код в памяти?

byte[] a: 
01010101 10111010 00111010 10101011 ... 

ответ

2

Уверен, что есть поддерживаемый способ. Я не знаю и не исследовал его, но вот некоторые догадки:

Самый простой способ - запустить его как процесс: записать его в *.com file, а затем сообщить O/S, чтобы запустить исполняемый файл ,

В качестве альтернативы передайте память как параметр в CreateThread function (но вам нужно будет скрестить код, имеющий правильные соглашения о вызове, ожидающие указанные параметры, сохраняющие регистры и находящиеся в памяти, которая является исполняемой).

Другая возможность заключается в том, чтобы записать коды операций в память, которая уже известна, которая уже будет выполнена (например, перезаписать существующий код в недавно загруженной DLL).

+1

Файл '.com' ограничен 16-разрядным кодом DOS, и, хотя этого может быть достаточно для некоторых целей, это не общее решение. Это берет на себя стоимость загрузки NTVDM для выполнения 16-битного кода. –

+0

Ответ JulianR выглядит неплохо. – ChrisW

1

Вы можете белый список приложения с панели управления http://ask-leo.com/how_do_i_turn_off_data_execution_prevention_errors.html

Я сомневаюсь, что вы можете его в белый список programattically, но, конечно, не без доступа администратора - это свело бы цель этой функции безопасности.

3

Это можно выполнить байт как код:

Inline x86 ASM in C#

Это требует использования unsafe кода.

Я думал, что это был просто забавный факт, но бесполезен на практике, но, возможно, ваше приложение на самом деле имеет использование для этого :)

+1

Не рекомендуется - не поддерживается в приложениях x64. –

+0

Каким образом нет? Является ли это по своей сути нарушением, или просто, что пример не очень переносимый? – JulianR

+0

Компилятор Microsoft C++ просто не работал над поддержкой 64-разрядной версии. К тому времени, когда 64-битная стала популярной, для людей просто не так важно было программировать в сборке, как было. –

7

Ключ заключается в том, чтобы поместить исполняемый код в блок памяти, выделяемой VirtualAlloc так что буфер помечен как исполняемый.

IntPtr pExecutableBuffer = VirtualAlloc(
    IntPtr.Zero, 
    new IntPtr(byteCount), 
    AllocationType.MEM_COMMIT | AllocationType.MEM_RESERVE, 
    MemoryProtection.PAGE_EXECUTE_READWRITE); 

(тогда используйте VirtualFree для очистки после себя).

Это говорит Windows, что память должна быть помечена как исполняемый код, чтобы она не запускала проверку DEP.

+0

+1 Вероятно, менее хаки, чем мой метод: p – JulianR