2014-09-02 1 views
1

У меня есть простой «функции», если вы могли бы даже назвать это та, которая является исключительно «NOP» хранится в памяти:Создание функции в памяти и назвав его

byte[] func = new byte[] {0x90}; // NOP 

Я тогда Выделяют часть памяти, которая будет держать его, и установить содержание:

Memory mem = new Memory(func.length); 
mem.write(0, code, 0, code.length); // Write all bytes from code, starting at mem + 0 

Теперь я хочу, чтобы «позвонить» эту маленькую функцию я только что создали. Давайте попробуем:

Function function = Function.getFunction(mem, Function.C_CONVENTION); 
function.invokeVoid(null); // I have tried other types of invokeXX too. 

Но это не работает, но вместо этого бросает исключение:

Exception in thread "main" java.lang.Error: Invalid memory access at com.sun.jna.Native.invokeVoid(Native Method) at com.sun.jna.Function.invoke(Function.java:367) at com.sun.jna.Function.invoke(Function.java:315) at com.sun.jna.Function.invoke(Function.java:268) at com.sun.jna.Function.invokeVoid(Function.java:727) at [my line calling invokeVoid]

Я не ожидал получить эту ошибку, потому что это, безусловно, должно быть. Я понятия не имею, что может пойти не так.

Есть ли что-нибудь, что мне не хватает здесь или (очевидно, но что?), Что делает неправильный?

NB: Я использую JNA 4.1.0.

+2

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

+0

Ну, я тоже не знал, но, согласно примерам [здесь] (https://github.com/kobalicek/asmjit), предлагается быть хорошим для генерации функций «на лету» и называть их. Это то, что я тоже пытался. :) –

+2

Вы уверены, что это не просто выполнение вашего NOP, а затем переход к некоторой неопределенной памяти после этого? Вам может понадобиться код операции возврата вызова. – darron

ответ

1

Я думаю, что использование объекта памяти - не очень хорошая идея. Если вы посмотрите на метод finalize, вы заметите, что он вызывает функцию free free(), а адрес, который не управляется jvm, может вызвать ошибку сегментации. Очевидно, проблема здесь возникает раньше. Попробуйте предоставить объект указателя функции Function.getFunction, но не память. Вы можете просто попробовать это:

Pointer ptr = Pointer.createConstant(0x90); 
Function f = Function.getFunction(ptr, Function.C_CONVENTION); 
1

Оказалось, что, как предложил Петр Lawrey, страница была действительно защищена от исполнения. Решение было довольно простым.

Мне пришлось сопоставить VirtualProtectEx с API Win32 и вызвать это со значением 0x40, чтобы разрешить выполнение. После этого все получилось!

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