You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
2.9 KiB
114 lines
2.9 KiB
4 years ago
|
/*
|
||
|
|
||
|
Ruby bindings for the Keystone Engine
|
||
|
|
||
|
Copyright(c) 2016 Sascha Schirra
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
version 2 as published by the Free Software Foundation.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
|
||
|
*/
|
||
|
#include "ruby.h"
|
||
|
#include <keystone/keystone.h>
|
||
|
#include "keystone.h"
|
||
|
|
||
|
VALUE KeystoneModule = Qnil;
|
||
|
VALUE KsClass = Qnil;
|
||
|
VALUE KsError = Qnil;
|
||
|
|
||
|
|
||
|
void Init_keystone() {
|
||
|
rb_require("keystone/keystone_const");
|
||
|
KeystoneModule = rb_define_module("Keystone");
|
||
|
KsError = rb_define_class_under(KeystoneModule, "KsError", rb_eStandardError);
|
||
|
|
||
|
KsClass = rb_define_class_under(KeystoneModule, "Ks", rb_cObject);
|
||
|
rb_define_method(KsClass, "initialize", m_ks_initialize, 2);
|
||
|
rb_define_method(KsClass, "asm", m_ks_asm, -1);
|
||
|
rb_define_method(KsClass, "syntax", m_ks_get_syntax, 0);
|
||
|
rb_define_method(KsClass, "syntax=", m_ks_set_syntax, 1);
|
||
|
}
|
||
|
|
||
|
VALUE m_ks_initialize(VALUE self, VALUE arch, VALUE mode) {
|
||
|
ks_engine *_ks;
|
||
|
ks_err err;
|
||
|
err = ks_open(NUM2INT(arch), NUM2INT(mode), &_ks);
|
||
|
if (err != KS_ERR_OK) {
|
||
|
rb_raise(KsError, "%d", err);
|
||
|
}
|
||
|
|
||
|
VALUE ks = Data_Wrap_Struct(KsClass, 0, ks_close, _ks);
|
||
|
rb_iv_set(self, "@ksh", ks);
|
||
|
|
||
|
if(NUM2INT(arch) == KS_ARCH_X86){
|
||
|
rb_iv_set(self, "@syntax", INT2NUM(KS_OPT_SYNTAX_INTEL));
|
||
|
}
|
||
|
else{
|
||
|
rb_iv_set(self, "@syntax", Qnil);
|
||
|
}
|
||
|
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
VALUE m_ks_asm(int argc, VALUE* argv, VALUE self){
|
||
|
VALUE string;
|
||
|
VALUE addr;
|
||
|
|
||
|
size_t count;
|
||
|
unsigned char *encode;
|
||
|
size_t size;
|
||
|
|
||
|
ks_err err;
|
||
|
ks_engine *_ks;
|
||
|
|
||
|
VALUE to_return = rb_ary_new();
|
||
|
|
||
|
Data_Get_Struct(rb_iv_get(self,"@ksh"), ks_engine, _ks);
|
||
|
|
||
|
rb_scan_args(argc, argv, "11", &string, &addr);
|
||
|
if (NIL_P(addr))
|
||
|
addr = INT2NUM(0);
|
||
|
|
||
|
err = ks_asm(_ks, StringValuePtr(string), NUM2INT(addr), &encode, &size, &count);
|
||
|
if (err != KS_ERR_OK) {
|
||
|
rb_raise(KsError, "%d", err);
|
||
|
}
|
||
|
|
||
|
if (count == 0){
|
||
|
rb_ary_store(to_return, 0, Qnil);
|
||
|
rb_ary_store(to_return, 1, INT2NUM(0));
|
||
|
}
|
||
|
else{
|
||
|
rb_ary_store(to_return, 0, rb_str_new(encode, size));
|
||
|
rb_ary_store(to_return, 1, INT2NUM(count));
|
||
|
}
|
||
|
ks_free(encode);
|
||
|
return to_return;
|
||
|
}
|
||
|
|
||
|
VALUE m_ks_get_syntax(VALUE self){
|
||
|
return rb_iv_get(self, "@syntax");
|
||
|
}
|
||
|
|
||
|
VALUE m_ks_set_syntax(VALUE self, VALUE val){
|
||
|
ks_err err;
|
||
|
ks_engine *_ks;
|
||
|
|
||
|
Data_Get_Struct(rb_iv_get(self,"@ksh"), ks_engine, _ks);
|
||
|
|
||
|
ks_option(_ks, KS_OPT_SYNTAX, NUM2INT(val));
|
||
|
rb_iv_set(self, "@syntax", val);
|
||
|
|
||
|
return Qnil;
|
||
|
}
|