disassembler-x86-intel
Version:
An Intel x86 disassembler, generates assembly from Opcode
116 lines (115 loc) • 5.58 kB
JavaScript
;
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports._Disassembler = void 0;
var _32bit_adressing_table_modrm_1 = require("32bit-adressing-table-modrm");
var _Disassembler = /** @class */ (function () {
function _Disassembler() {
this._prefixMap = new Map().set('66', 'registerMode').set('67', 'addressMode');
this.modRmSet = new Set(['80', '81', '83']);
this._opCodeMap = new Map();
this.generateOpCodeMap([this.createOpCode('add', ['80/0', 'b', '81/0', 'd', '83/0', 'b'])]);
}
_Disassembler.prototype.byteIterator = function (s) {
var i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i = 0;
_a.label = 1;
case 1:
if (!(i < s.length)) return [3 /*break*/, 4];
return [4 /*yield*/, s[i] + s[i + 1]];
case 2:
_a.sent();
_a.label = 3;
case 3:
i += 2;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
};
_Disassembler.prototype.disassemble = function (opCodes) {
var iterator = this.byteIterator(opCodes);
var currentByte = iterator.next().value;
var prefix = this.fetchPrefix(currentByte);
if (prefix) {
currentByte = iterator.next().value;
}
var modRmByte;
var possibleRegisters = [];
if (this.modRmSet.has(currentByte)) {
var nextByte = iterator.next().value;
var searchResult = _32bit_adressing_table_modrm_1.Table.getReverseValueFromTable(nextByte);
modRmByte = searchResult[1].pop();
possibleRegisters = searchResult[0];
}
var op = this._opCodeMap.get(modRmByte ? currentByte + "/" + modRmByte : currentByte);
var instruction = op === null || op === void 0 ? void 0 : op.instruction;
var operand1 = possibleRegisters.length > 0 ? possibleRegisters[1] : undefined;
var operand2 = this.getValueFromLength(iterator, prefix ? 'w' : op === null || op === void 0 ? void 0 : op.length);
return instruction + ' ' + operand1 + ' ' + operand2;
};
_Disassembler.prototype.getValueFromLength = function (it, length) {
if (length) {
switch (length) {
case 'b':
return it.next().value;
case 'd':
return it.next().value + it.next().value + it.next().value + it.next().value;
case 'w':
return it.next().value + it.next().value;
}
}
return '';
};
_Disassembler.prototype.fetchPrefix = function (pref) {
return this._prefixMap.get(pref);
};
_Disassembler.prototype.generateOpCodeMap = function (codes) {
var _this = this;
codes.forEach(function (c) {
c.codes.forEach(function (c1) {
_this._opCodeMap.set(c1.value, { instruction: c.instruction, length: c1.length });
});
});
};
_Disassembler.prototype.createOpCode = function (ins, codeAndLength) {
var codes = [];
for (var i = 0; i < codeAndLength.length; i += 2) {
var code = codeAndLength[i];
var length_1 = codeAndLength[i + 1];
codes.push({ value: code, length: length_1 !== '' ? length_1 : undefined });
}
return { instruction: ins, codes: codes };
};
return _Disassembler;
}());
exports._Disassembler = _Disassembler;