int x = sscanf(read, "%02hhx", assembly_code);
Это преобразует только один байт. Я не думаю, что есть стандартная библиотечная функция для преобразования всей строки шестнадцатеричных байтов; вам придется вызывать sscanf
по всем oop, увеличивая указатели внутри входного буфера read
и выходного буфера assembly_code
, в зависимости от ситуации.
При вызове mmap
, если вы не не хотите отображать файл, вы должны использовать флаг MAP_ANONYMOUS
вместо MAP_SHARED
. Вам также следует проверить его возвращаемое значение (при ошибке возвращается MAP_FAILED
) и сообщить о любой ошибке. Кроме того, возвращаемое значение в принципе имеет тип void *
вместо int *
(хотя это не должно иметь значения в обычных Unix системах).
Вызов mmap
(после исправления) будет вернуть указатель на блок памяти, заполненный нулями. Нет смысла в нем содержать ваш assembly_code
, поэтому вам придется скопировать его туда, возможно, с memcpy
. Или вы можете переместить ваш l oop и проанализировать шестнадцатеричные байты непосредственно в область, выделенную с помощью mmap
.
Ваш ((void (*)(void))map)();
для передачи управления на сопоставленный адрес кажется правильным, поэтому, как только вы получите блок правильно сопоставлен и заполнен, он должен выполнять ваш машинный код. Я не пытался разобрать предоставленную вами шестнадцатеричную строку, чтобы посмотреть, действительно ли она будет выполнять то, что вы ожидаете, но, надеюсь, это удастся.
Кроме того, read
не очень хорошее имя для переменной, так как есть также стандартная библиотечная функция с этим именем. Ваш код будет работать, поскольку локальная переменная затеняет глобальный объект, но было бы более понятно выбрать другое имя.
О, а char assembly_code[sizeof argv[1]];
не правильно. Тщательно продумайте, что sizeof
делает и не делает.