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.
101 lines
2.6 KiB
101 lines
2.6 KiB
var ref = require('ref'),
|
|
ffi = require('ffi'),
|
|
consts = require('./consts'),
|
|
extend = require('util')._extend
|
|
|
|
var ks_engine = 'void',
|
|
ks_enginePtr = ref.refType(ks_engine),
|
|
ks_enginePtrPtr = ref.refType(ks_enginePtr),
|
|
ks_arch = 'int',
|
|
ks_err = 'int',
|
|
ks_opt_type = 'int',
|
|
uintPtr = ref.refType('uint'),
|
|
ucharPtr = ref.refType('uchar'),
|
|
ucharPtrPtr = ref.refType(ucharPtr),
|
|
size_tPtr = ref.refType('size_t'),
|
|
stringPtr = ref.refType('string')
|
|
|
|
var Keystone = ffi.Library('libkeystone', {
|
|
'ks_version': [ 'uint', [ uintPtr, uintPtr ] ],
|
|
'ks_arch_supported': [ 'bool', [ ks_arch ] ],
|
|
'ks_open': [ ks_err, [ ks_arch, 'int', ks_enginePtrPtr ] ],
|
|
'ks_close': [ ks_err, [ ks_enginePtr ] ],
|
|
'ks_errno': [ 'int', [ ks_enginePtr ] ],
|
|
'ks_strerror': [ 'string', [ ks_err ] ],
|
|
'ks_option': [ ks_err, [ ks_enginePtr, ks_opt_type, 'size_t' ] ],
|
|
'ks_asm': [ 'int', [ ks_enginePtr, 'string', 'uint64', ucharPtrPtr, size_tPtr, size_tPtr ] ],
|
|
'ks_free': [ 'void', [ 'pointer' ] ]
|
|
})
|
|
|
|
function KsError(message, errno, count) {
|
|
this.message = message
|
|
this.errno = errno
|
|
this.count = count
|
|
}
|
|
|
|
function Ks(arch, mode) {
|
|
var _ks = ref.alloc(ks_enginePtr),
|
|
err = Keystone.ks_open(arch, mode, _ks)
|
|
|
|
if (err !== consts.ERR_OK) {
|
|
this._ks = null
|
|
throw new KsError('Error: failed on ks_open()')
|
|
}
|
|
|
|
this._ks = _ks.deref()
|
|
|
|
|
|
this.__defineGetter__('errno', function() {
|
|
return Keystone.ks_errno(this._ks)
|
|
})
|
|
|
|
this.__defineSetter__('syntax', function(value) {
|
|
this.set_option(consts.OPT_SYNTAX, value)
|
|
})
|
|
}
|
|
|
|
Ks.prototype.asm = function(code, addr) {
|
|
var encoding = ref.alloc('uchar *'),
|
|
size = ref.alloc('size_t'),
|
|
count = ref.alloc('size_t'),
|
|
err, msg
|
|
|
|
if (Keystone.ks_asm(this._ks, code, addr || 0, encoding, size, count) !== consts.ERR_OK) {
|
|
err = this.errno
|
|
msg = Keystone.ks_strerror(err)
|
|
throw new KsError(msg, err, count.deref())
|
|
}
|
|
|
|
return {
|
|
encoding: ref.reinterpret(encoding.deref(), size.deref(), 0),
|
|
count: count.deref()
|
|
}
|
|
}
|
|
|
|
Ks.prototype.close = function() {
|
|
Keystone.ks_close(this._ks)
|
|
this._ks = null
|
|
}
|
|
|
|
Ks.prototype.set_option = function(type, value) {
|
|
var err = Keystone.ks_option(this._ks, type, value)
|
|
if (err != consts.ERR_OK) {
|
|
throw new KsError(Keystone.ks_strerror(err), err)
|
|
}
|
|
}
|
|
|
|
module.exports.Ks = Ks
|
|
|
|
module.exports.is_arch_supported = function(arch) {
|
|
return Keystone.ks_arch_supported(arch)
|
|
}
|
|
|
|
module.exports.__defineGetter__('version', function() {
|
|
var version = Keystone.ks_version(null, null)
|
|
return {
|
|
major: version >> 8,
|
|
minor: version & 255
|
|
}
|
|
})
|
|
extend(module.exports, consts)
|