import * as path from "path"; import * as ffi from "ffi"; import * as fs from "fs"; // IMPORTANT: choose one const RL_LIB = "libreadline"; // NOTE: libreadline is GPL // var RL_LIB = "libedit"; const HISTORY_FILE = path.join(process.env.HOME || ".", ".mal-history"); const rllib = ffi.Library(RL_LIB, { "readline": ["string", ["string"]], "add_history": ["int", ["string"]], }); let rlHistoryLoaded = false; export function readline(prompt?: string): string | null { prompt = prompt || "user> "; if (!rlHistoryLoaded) { rlHistoryLoaded = true; let lines: string[] = []; if (fs.existsSync(HISTORY_FILE)) { lines = fs.readFileSync(HISTORY_FILE).toString().split("\n"); } // Max of 2000 lines lines = lines.slice(Math.max(lines.length - 2000, 0)); for (let i = 0; i < lines.length; i++) { if (lines[i]) { rllib.add_history(lines[i]); } }
export const CBContext = Struct({ 'gkeyCallBack': ffi.Function('void *', [GkeyCode, wchar_string, 'void *'])/*logiGkeyCB*/, // 'pointer', 'gkeyContext': 'void *', }); export const CBContextPtr = ref.refType(CBContext); export const gkeyLib = ffi.Library(libPath('gkey'), { // Enable the Gkey SDK by calling this function 'LogiGkeyInit': ['bool', [CBContextPtr/*logiGkeyCBContext* gkeyCBContext*/]], // Enable the Gkey SDK by calling this function if not using callback. Use this initialization if using Unreal Engine 'LogiGkeyInitWithoutCallback': ['bool', []], // Enable the Gkey SDK be calling this function if not using context. Use this initialization if working with Unity Engine 'LogiGkeyInitWithoutContext': ['bool', ['pointer'/*logiGkeyCB gkeyCallBack*/]], // Check if a mouse button is currently pressed 'LogiGkeyIsMouseButtonPressed': ['bool', ['int'/*const int buttonNumber*/]], // Get friendly name for mouse button 'LogiGkeyGetMouseButtonString': [wchar_string, ['int'/*const int buttonNumber*/]], // Check if a keyboard G-key is currently pressed 'LogiGkeyIsKeyboardGkeyPressed': ['bool', ['int'/*const int gkeyNumber*/, 'int'/*const int modeNumber*/]], // Get friendly name for G-key 'LogiGkeyGetKeyboardGkeyString': [wchar_string, ['int'/*const int gkeyNumber*/, 'int'/*const int modeNumber*/]], // Disable the Gkey SDK, free up all the resources. 'LogiGkeyShutdown': ['void', []], }); export function isButtonNumberValid(buttonNumber: mouseButtonNumber | number): buttonNumber is mouseButtonNumber { return Number.isInteger(buttonNumber) && buttonNumber >= 0 && buttonNumber <= LOGITECH_MAX_MOUSE_BUTTONS; }
// Color LCD functions LogiLcdColorSetBackground: Function; LogiLcdColorSetTitle: Function; LogiLcdColorSetText: Function; } export const lcdLib: LcdLib = ffi.Library(libPath('lcd'), { 'LogiLcdInit': ['bool', [wchar_string /*friendlyName*/, 'int' /*lcdType*/]], 'LogiLcdIsConnected': ['bool', ['int' /*lcdType*/]], 'LogiLcdIsButtonPressed': ['bool', ['int' /*button*/]], 'LogiLcdUpdate': ['void', []], 'LogiLcdShutdown': ['void', []], // Monochrome LCD functions 'LogiLcdMonoSetBackground': ['bool', [byteArray /*monoBitmap[]*/]], 'LogiLcdMonoSetText': ['bool', ['int' /*lineNumber*/, wchar_string /*text*/]], // Color LCD functions 'LogiLcdColorSetBackground': ['bool', [byteArray /*colorBitmap[]*/]], 'LogiLcdColorSetTitle': ['bool', [wchar_string /*text*/, 'int' /*red = 255*/, 'int' /*green = 255*/, 'int' /*blue = 255*/]], 'LogiLcdColorSetText': ['bool', ['int' /*lineNumber*/, wchar_string /*text*/, 'int' /*red = 255*/, 'int' /*green = 255*/, 'int' /*blue = 255*/]], }); export function isButtonValid(button: number) { return isButtonValidForColor(button) || isButtonValidForMono(button); } export function isButtonValidForMono(button: number) {
import * as ffi from 'ffi' import * as ref from 'ref' const _unwindmc = ffi.Library('libunwindmc', { version: ['string', []], init: ['bool', ['pointer']], open_binary_file: ['bool', ['string']], open_db: ['bool', ['string']], save_db: ['void', ['string']], get_functions: ['void', ['string', 'size_t']], get_instructions: ['void', ['uint64', 'string', 'size_t']], get_il: ['bool', ['uint64', 'string', 'size_t']], get_flow_blocks: ['bool', ['uint64', 'string', 'size_t']], decompile_il: ['void', []], analyze_control_flow: ['void', []] }) const _buffer = Buffer.alloc(16 * 1024 * 1024) var _logCallback: Buffer; export interface Function { readonly address: number, readonly status: string, readonly callingConvention: 'Unknown' | 'Stdcall', readonly argumentsSize: number, readonly name: string, } export interface Instruction { readonly address: number, readonly hex: string,