The core library of "chameleon-ultra.js". The instance of this class must use exactly one adapter plugin to communication to ChameleonUltra.

Constructors

Connection Related

Device Related

Slot Related

Reader Related

Emulator Related

Mifare Classic Related

Mifare Ultralight Related

Plugin Related

Internal

Constructors

  • Create a new instance of ChameleonUltra.

    Parameters

    • debug: boolean = false

      Enable debug mode.

    Returns ChameleonUltra

    Example

    Example usage in Browser (place at the end of body):

    <script src="https://cdn.jsdelivr.net/npm/chameleon-ultra.js@0/dist/iife/index.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chameleon-ultra.js@0/dist/iife/plugin/WebbleAdapter.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chameleon-ultra.js@0/dist/iife/plugin/WebserialAdapter.min.js"></script>
    <script>
    const { ChameleonUltra, WebbleAdapter, WebserialAdapter } = ChameleonUltraJS

    const ultraUsb = new ChameleonUltra()
    ultraUsb.use(new WebserialAdapter())

    const ultraBle = new ChameleonUltra()
    ultraBle.use(new WebbleAdapter())
    </script>

    Example usage in CommonJS:

    const { ChameleonUltra } = require('chameleon-ultra.js')
    const WebbleAdapter = require('chameleon-ultra.js/plugin/WebbleAdapter')
    const WebserialAdapter = require('chameleon-ultra.js/plugin/WebserialAdapter')
    const SerialPortAdapter = require('chameleon-ultra.js/plugin/SerialPortAdapter')

    const ultraUsb = new ChameleonUltra()
    ultraUsb.use(new WebserialAdapter())

    const ultraBle = new ChameleonUltra()
    ultraBle.use(new WebbleAdapter())

    const ultraNode = new ChameleonUltra()
    ultraNode.use(new SerialPortAdapter())

    Example usage in ESM:

    import { ChameleonUltra } from 'chameleon-ultra.js'
    import WebbleAdapter from 'chameleon-ultra.js/plugin/WebbleAdapter'
    import WebserialAdapter from 'chameleon-ultra.js/plugin/WebserialAdapter'
    import SerialPortAdapter from 'chameleon-ultra.js/plugin/SerialPortAdapter'

    const ultraUsb = new ChameleonUltra()
    ultraUsb.use(new WebserialAdapter())

    const ultraBle = new ChameleonUltra()
    ultraBle.use(new WebbleAdapter())

    const ultraNode = new ChameleonUltra()
    ultraNode.use(new SerialPortAdapter())

Connection Related

  • Return true if ChameleonUltra is connected.

    Returns boolean

Device Related

VERSION_SUPPORTED: {
    gte: "2.0";
    lt: "3.0";
} = VERSION_SUPPORTED

The supported version of SDK.

Type declaration

  • Readonly gte: "2.0"
  • Readonly lt: "3.0"
  • Delete all ble bindings.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdBleDeleteAllBonds()
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the ble address of device.

    Returns Promise<string>

    The ble address of device.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdBleGetAddress()) // 'E8:B6:3D:04:B6:FE'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get current ble pairing key of device.

    Returns Promise<string>

    The ble pairing key.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdBleGetPairingKey()) // '123456'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the ble pairing mode of device.

    Returns Promise<boolean>

    true if pairing is required to connect to device, otherwise return false.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdBleGetPairingMode()) // false
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the ble pairing key of device.

    Parameters

    • key: string

      The new ble pairing key.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdBleSetPairingKey('123456')
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set if the ble pairing is required when connecting to device.

    Parameters

    • enable: number | boolean

      true to enable pairing mode, false to disable pairing mode.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdBleSetPairingMode(false)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Change device mode to tag reader or tag emulator.

    Parameters

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { DeviceMode } = window.ChameleonUltraJS
    await ultra.cmdChangeDeviceMode(DeviceMode.TAG)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Enter bootloader mode.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdEnterBootloader()
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the animation mode of device while wake-up and sleep.

    Returns Promise<AnimationMode>

    The animation mode of device.

    Example

    async function run (ultra) {
    const { AnimationMode } = window.ChameleonUltraJS
    const mode = await ultra.cmdGetAnimationMode()
    console.log(AnimationMode[mode]) // 'FULL'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get current firmware version of device.

    Returns Promise<`${number}.${number}`>

    Current firmware version of device.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdGetAppVersion()) // '1.0'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the battery info of device.

    Returns Promise<BatteryInfo>

    The battery info of device.

    Example

    async function run (ultra) {
    const battery = await ultra.cmdGetBatteryInfo()
    console.log(JSON.stringify(battery)) // { "voltage": 4192, "level": 99 }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the button long press action of specified button.

    Parameters

    Returns Promise<ButtonAction>

    The button long press action of specified button.

    Example

    async function run (ultra) {
    const { ButtonAction, ButtonType } = window.ChameleonUltraJS
    const btnAction = await ultra.cmdGetButtonLongPressAction(ButtonType.BUTTON_A)
    console.log(ButtonAction[btnAction]) // 'CLONE_IC_UID'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the button press action of specified button.

    Parameters

    Returns Promise<ButtonAction>

    The button press action of specified button.

    Example

    async function run (ultra) {
    const { ButtonAction, ButtonType } = window.ChameleonUltraJS
    const btnAction = await ultra.cmdGetButtonPressAction(ButtonType.BUTTON_A)
    console.log(ButtonAction[btnAction]) // 'CYCLE_SLOT_INC'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get chipset id of device in hex format.

    Returns Promise<string>

    Chipset id of device in hex format.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdGetDeviceChipId()) // 'db1c624228d9634c'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get current mode of device.

    Returns Promise<DeviceMode>

    Current mode of device.

    Example

    async function run (ultra) {
    const { DeviceMode } = window.ChameleonUltraJS
    const deviceMode = await ultra.cmdGetDeviceMode()
    console.log(DeviceMode[deviceMode]) // 'TAG'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the device is ChameleonUltra or ChameleonLite.

    Returns Promise<DeviceModel>

    true if device is ChameleonUltra, false if device is ChameleonLite.

    Example

    async function run (ultra) {
    const { DeviceModel } = window.ChameleonUltraJS
    const model = await ultra.cmdGetDeviceModel()
    console.log(DeviceModel[model]) // 'ULTRA'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the settings of device.

    Returns Promise<DeviceSettings>

    The settings of device.

    Example

    async function run (ultra) {
    const settings = await ultra.cmdGetDeviceSettings()
    console.log(JSON.stringify(settings)
    /**
    * {
    * "version": 5,
    * "animation": 0,
    * "buttonPressAction": [1, 2],
    * "buttonLongPressAction": [3, 3],
    * "blePairingMode": false,
    * "blePairingKey": "123456"
    * }
    */
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the git version of firmware.

    Returns Promise<string>

    The git version of firmware.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdGetGitVersion()) // '98605be'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the cmds supported by device.

    Returns Promise<Set<Cmd>>

    The cmds supported by device.

    Example

    async function run (ultra) {
    const cmds = await ultra.cmdGetSupportedCmds()
    console.log(cmds.size) // 67
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Reset the settings of device to default values.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdResetSettings()
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Save the settings of device to persistent storage.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdSaveSettings()
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the animation mode of device while wake-up and sleep.

    Parameters

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { AnimationMode } = window.ChameleonUltraJS
    await ultra.cmdSetAnimationMode(AnimationMode.SHORT)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the button long press action of specified button.

    Parameters

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { ButtonAction, ButtonType } = window.ChameleonUltraJS
    await ultra.cmdSetButtonLongPressAction(ButtonType.BUTTON_A, ButtonAction.CYCLE_SLOT_INC)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the button press action of specified button.

    Parameters

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { ButtonAction, ButtonType } = window.ChameleonUltraJS
    await ultra.cmdSetButtonPressAction(ButtonType.BUTTON_A, ButtonAction.CYCLE_SLOT_INC)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Permanently wipes Chameleon to factory settings. This will delete all your slot data and custom settings. There's no going back.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdWipeFds()
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • To check if the specified cmd is supported by device.

    Parameters

    Returns Promise<boolean>

    true if the specified cmd is supported by device, otherwise return false.

    Example

    async function run (ultra) {
    console.log(await ultra.isCmdSupported(Cmd.GET_APP_VERSION)) // true
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Check if the firmware version is supported by SDK.

    Returns Promise<boolean>

    true if the firmware version is supported, false otherwise.

    Example

    async function run (ultra) {
    if (await ultra.isSupportedAppVersion()) throw new Error('Firmware version is not supported. Please update the firmware.')
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html

Slot Related

  • Change the emulation tag type of specified slot.

    Parameters

    • slot: Slot

      The slot to be set.

    • tagType: TagType

      The tag type to be set.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Slot, TagType } = window.ChameleonUltraJS
    await ultra.cmdSlotChangeTagType(Slot.SLOT_1, TagType.MIFARE_1024)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Delete the nick name of the slot

    Parameters

    Returns Promise<boolean>

    true if success, false if slot name is empty.

    Example

    async function run (ultra) {
    const { Slot, FreqType } = window.ChameleonUltraJS
    console.log(await ultra.cmdSlotDeleteFreqName(Slot.SLOT_1, FreqType.HF)) // true
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Delete the emulation tag data of specified freq type in specified slot.

    Parameters

    • slot: Slot

      The slot to be deleted.

    • freq: FreqType

      The freq type of slot.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Slot, FreqType } = window.ChameleonUltraJS
    await ultra.cmdSlotDeleteFreqType(Slot.SLOT_1, FreqType.HF)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the active emulation tag slot of device.

    Returns Promise<Slot>

    The active slot of device.

    Example

    async function run (ultra) {
    const { Slot } = window.ChameleonUltraJS
    const slot = await ultra.cmdSlotGetActive()
    console.log(Slot[slot]) // 'SLOT_1'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the nickname of specified freq type in specified slot.

    Parameters

    • slot: Slot

      The slot to be get.

    • freq: FreqType

      The freq type to be get.

    Returns Promise<undefined | string>

    The nickname of specified freq type in specified slot.

    Example

    async function run (ultra) {
    const { Slot, FreqType } = window.ChameleonUltraJS
    const name = await ultra.cmdSlotGetFreqName(Slot.SLOT_1, FreqType.HF)
    console.log(name) // 'My Tag'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the slot info of all slots.

    Returns Promise<SlotInfo[]>

    The slot info of all slots.

    Example

    async function run (ultra) {
    const slots = await ultra.cmdSlotGetInfo()
    console.log(JSON.stringify(slots))
    /**
    * [
    * { "hfTagType": 1001, "lfTagType": 100 },
    * { "hfTagType": 1001, "lfTagType": 0 },
    * { "hfTagType": 0, "lfTagType": 100 },
    * { "hfTagType": 0, "lfTagType": 0 },
    * { "hfTagType": 0, "lfTagType": 0 },
    * { "hfTagType": 0, "lfTagType": 0 },
    * { "hfTagType": 0, "lfTagType": 0 },
    * { "hfTagType": 0, "lfTagType": 0 }
    * ]
    */
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get enabled slots.

    Returns Promise<SlotFreqIsEnable[]>

    Enabled slots.

    Example

    async function run (ultra) {
    const enabledSlots = await ultra.cmdSlotGetIsEnable()
    console.log(JSON.stringify(enabledSlots))
    // [
    // { "hf": true, "lf": true },
    // { "hf": true, "lf": false },
    // { "hf": false, "lf": true },
    // { "hf": false, "lf": false },
    // { "hf": false, "lf": false },
    // { "hf": false, "lf": false },
    // { "hf": false, "lf": false },
    // { "hf": true, "lf": false }
    // ]
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Reset the emulation tag data of specified tag type in specified slot to default values.

    Parameters

    • slot: Slot

      The slot to be reset.

    • tagType: TagType

      The tag type to be reset.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Slot, TagType } = window.ChameleonUltraJS
    await ultra.cmdSlotResetTagType(Slot.SLOT_1, TagType.MIFARE_1024)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • The SlotSettings, hf tag data and lf tag data will be written to persistent storage. But the slot nickname is not affected by this command.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    await ultra.cmdMf1EmuWriteBlock(1, Buffer.alloc(16))
    await ultra.cmdSlotSaveSettings()
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Change the active emulation tag slot of device.

    Parameters

    • slot: Slot

      The slot to be active.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Slot } = window.ChameleonUltraJS
    await ultra.cmdSlotSetActive(Slot.SLOT_1)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Enable or disable the specified slot.

    Parameters

    • slot: Slot

      The slot to be enable/disable.

    • freq: FreqType
    • enable: number | boolean

      true to enable the slot, false to disable the slot.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { FreqType, Slot } = window.ChameleonUltraJS
    await ultra.cmdSlotSetEnable(Slot.SLOT_1, FreqType.HF, true)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the nickname of specified freq type in specified slot.

    Parameters

    • slot: Slot

      The slot to be set.

    • freq: FreqType

      The freq type to be set.

    • name: string

      The name to be set. The byteLength of name should between 1 and 32.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Slot, FreqType } = window.ChameleonUltraJS
    await ultra.cmdSlotSetFreqName(Slot.SLOT_1, FreqType.HF, 'My Tag')
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html

Reader Related

  • Scan em410x tag and print id

    Returns Promise<Buffer>

    The id of em410x tag.

    Example

    async function run (ultra) {
    const id = await ultra.cmdEm410xScan()
    console.log(id.toString('hex')) // 'deadbeef88'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Write id of em410x tag to t55xx tag.

    Parameters

    • id: Buffer

      The id of em410x tag.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    await ultra.cmdEm410xWriteToT55xx(Buffer.from('deadbeef88', 'hex'))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Send raw NfcA data to a tag and receive the response.

    Parameters

    • opts: {
          activateRfField?: boolean;
          appendCrc?: boolean;
          autoSelect?: boolean;
          checkResponseCrc?: boolean;
          data?: Buffer;
          dataBitLength?: number;
          keepRfField?: boolean;
          timeout?: number;
          waitResponse?: boolean;
      }
      • Optional activateRfField?: boolean

        Set true to activate RF field. If data is not empty or autoSelect is true, activateRfField will be set to true.

      • Optional appendCrc?: boolean

        Set true to add CRC before sending data.

      • Optional autoSelect?: boolean

        Set true to automatically select card before sending data.

      • Optional checkResponseCrc?: boolean

        Set true to verify CRC of response and remove. If CRC of response is valid, CRC will be removed from response, otherwise will throw HF_ERR_CRC error.

      • Optional data?: Buffer

        The data to be send. If appendCrc is true, the maximum length of data is 62, otherwise is 64.

      • Optional dataBitLength?: number

        Number of bits to send. Useful for send partial byte. dataBitLength is incompatible with appendCrc.

      • Optional keepRfField?: boolean

        Set true to keep the RF field active after sending.

      • Optional timeout?: number

        Default value is 1000 ms. Maximum timeout for reading tag response in ms while waitResponse is true.

      • Optional waitResponse?: boolean

        Default value is true. Set false to skip reading tag response.

    Returns Promise<Buffer>

    The response from tag.

  • Scan 14a tag, and return basic information. The device mode must be set to READER before using this command.

    Returns Promise<Hf14aAntiColl[]>

    The basic infomation of scanned tag.

    Throws

    This command will throw an error if tag not scanned or any error occured.

    Example

    async function run (ultra) {
    const antiColl = _.first(await ultra.cmdHf14aScan())
    console.log(_.mapValues(antiColl, val => val.toString('hex')))
    // { uid: '040dc4420d2981', atqa: '4400', sak: '00', ats: ''}
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the info composed of cmdHf14aScan() and cmdMf1TestNtLevel().

    Returns Promise<Hf14aTagInfo[]>

    The info about 14a tag and mifare protocol.

    Example

    async function run (ultra) {
    const { Mf1PrngType } = window.ChameleonUltraJS
    const tag = _.first(await ultra.hf14aInfo())
    console.log(tag.nxpTypeBySak) // 'MIFARE Classic 1K | Plus SE 1K | Plug S 2K | Plus X 2K'
    console.log(Mf1PrngType[tag.prngType]) // 'WEAK'
    console.log(_.mapValues(tag.antiColl, val => val.toString('hex')))
    // { uid: 'dbe3d63d', atqa: '0400', sak: '08', ats: '' }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html

Emulator Related

  • Get the em410x id of actived slot.

    Returns Promise<Buffer>

    The em410x id of actived slot.

    Example

    async function run (ultra) {
    const id = await ultra.cmdEm410xGetEmuId()
    console.log(id.toString('hex')) // 'deadbeef88'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the em410x id of actived slot.

    Parameters

    • id: Buffer

      The em410x id of actived slot.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    await ultra.cmdEm410xSetEmuId(Buffer.from('deadbeef88', 'hex'))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get anti-collision data from actived slot.

    Returns Promise<null | Hf14aAntiColl>

    The anti-collision data from actived slot.

    Example

    async function run (ultra) {
    const res = await ultra.cmdHf14aGetAntiCollData()
    console.log(JSON.stringify(res))
    // {
    // "uid": { "type": "Buffer", "data": [222, 173, 190, 239] },
    // "atqa": { "type": "Buffer", "data": [4, 0] },
    // "sak": { "type": "Buffer", "data": [8] },
    // "ats": { "type": "Buffer", "data": [] }
    // }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the mifare anti-collision data of actived slot.

    Parameters

    • opts: {
          atqa: Buffer;
          ats?: Buffer;
          sak: Buffer;
          uid: Buffer;
      }
      • atqa: Buffer

        2 bytes, the new atqa to be set.

      • Optional ats?: Buffer

        The new ats to be set.

      • sak: Buffer

        1 byte, the new sak to be set.

      • uid: Buffer

        The new uid to be set.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    await ultra.cmdHf14aSetAntiCollData({
    atqa: Buffer.from('0400', 'hex'),
    sak: Buffer.from('08', 'hex'),
    uid: Buffer.from('01020304', 'hex')
    })
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html

Mifare Classic Related

  • Acquire the data from mifare darkside attack.

    Parameters

    • block: number

      The target block.

    • keyType: Mf1KeyType

      The target key type.

    • isFirst: number | boolean

      true if this is the first attack.

    • syncMax: number = 30

      The max sync count of darkside attack.

    Returns Promise<Mf1DarksideRes>

    The data from mifare darkside attack.

    Example

    async function run (ultra) {
    const { Mf1KeyType, DarksideStatus } = window.ChameleonUltraJS
    const res1 = await ultra.cmdMf1AcquireDarkside(0, Mf1KeyType.KEY_A, true)
    console.log(res1)
    const res2 = {
    status: `${DarksideStatus[res1.status]} (${res1.status})`,
    ...(res1.status !== DarksideStatus.OK ? {} : {
    ar: res1.ar.toString('hex'),
    ks: res1.ks.toString('hex'),
    nr: res1.nr.toString('hex'),
    nt: res1.nt.toString('hex'),
    par: res1.par.toString('hex'),
    uid: res1.uid.toString('hex'),
    }),
    }
    console.log(res2)
    // {
    // "ar": "00000000",
    // "ks": "0c0508080f04050a",
    // "nr": "00000000",
    // "nt": "b346fc3d",
    // "par": "0000000000000000",
    // "status": "OK (0)",
    // "uid": "d3efed0c"
    // }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html

    If you want to use darkside attack to recover the key, you can use the following example code:

    async function run (ultra) {
    const { Buffer, DarksideStatus, Mf1KeyType } = window.ChameleonUltraJS
    const block = 0
    const keyType = Mf1KeyType.KEY_A
    const key = await Crypto1.darkside(
    async attempt => {
    const accquired = await ultra.cmdMf1AcquireDarkside(block, keyType, attempt === 0)
    console.log(_.mapValues(accquired, buf => Buffer.isBuffer(buf) ? buf.toString('hex') : buf))
    if (acquired.status === DarksideStatus.LUCKY_AUTH_OK) throw new Error('LUCKY_AUTH_OK')
    if (acquired.status !== DarksideStatus.OK) throw new Error('card is not vulnerable to Darkside attack')
    return accquired
    },
    async key => {
    return await ultra.cmdMf1CheckBlockKey({ block, keyType, key })
    },
    )
    console.log(`key founded: ${key.toString('hex')}`)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Use a known key to do the mifare nested attack.

    Parameters

    • known: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The info of known key.

      • block: number

        The block of known key.

      • key: Buffer

        The known key.

      • keyType: Mf1KeyType

        The key type of known key.

    • target: {
          block: number;
          keyType: Mf1KeyType;
      }

      The info of target key to be attack.

      • block: number

        The block of target key.

      • keyType: Mf1KeyType

        The key type of target key.

    Returns Promise<Mf1NestedRes[]>

    The result of mifare nested attack.

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const res1 = await ultra.cmdMf1TestNtDistance({ block: 0, keyType: Mf1KeyType.KEY_A, key })
    const res2 = await ultra.cmdMf1AcquireNested(
    { block: 0, keyType: Mf1KeyType.KEY_A, key },
    { block: 4, keyType: Mf1KeyType.KEY_A },
    )
    const res = {
    uid: res1.uid.toString('hex'),
    dist: res1.dist.toString('hex'),
    atks: _.map(res2, item => ({
    nt1: item.nt1.toString('hex'),
    nt2: item.nt2.toString('hex'),
    par: item.par,
    }))
    }
    console.log(res)
    // {
    // uid: '877209e1',
    // dist: '00000080',
    // atks: [
    // { nt1: '35141fcb', nt2: '40430522', par: 7 },
    // { nt1: 'cff2b3ef', nt2: '825ba8ea', par: 5 },
    // ]
    // }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Use a known key to do the mifare static nested attack.

    Parameters

    • known: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The info of known key.

      • block: number

        The block of known key.

      • key: Buffer

        The known key.

      • keyType: Mf1KeyType

        The key type of known key.

    • target: {
          block: number;
          keyType: Mf1KeyType;
      }

      The info of target key to be attack.

      • block: number

        The block of target key.

      • keyType: Mf1KeyType

        The key type of target key.

    Returns Promise<Mf1AcquireStaticNestedRes>

    The result of mifare static nested attack.

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const res1 = await ultra.cmdMf1AcquireStaticNested({
    block: 0,
    keyType: Mf1KeyType.KEY_A,
    key
    }, {
    block: 4,
    keyType: Mf1KeyType.KEY_A
    })
    const res = {
    uid: res1.uid.toString('hex'),
    atks: _.map(res1.atks, item => ({ nt1: item.nt1.toString('hex'), nt2: item.nt2.toString('hex') })),
    }
    console.log(res)
    // {
    // uid: 'b908a16d',
    // atks: [
    // { nt1: '01200145', nt2: '81901975' },
    // { nt1: '01200145', nt2: 'cdd400f3' },
    // ],
    // }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Check if the key is valid for specified block and key type.

    Parameters

    • opts: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The info of key to be checked.

      • block: number

        The block of key to be checked.

      • key: Buffer

        The key to be checked.

      • keyType: Mf1KeyType

        The type of key to be checked.

    Returns Promise<boolean>

    true if the key is valid for specified block and key type.

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    console.log(await ultra.cmdMf1CheckBlockKey({
    block: 0,
    keyType: Mf1KeyType.KEY_A,
    key,
    })) // true
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Given a list of keys, check which is the correct key A and key B of the sectors. If you want to check more than 83 keys, you can use mf1CheckKeysOfSectors().

    Parameters

    • opts: {
          keys: Buffer[];
          mask: Buffer;
      }
      • keys: Buffer[]

        The keys to be checked. Maximum length is 83.

      • mask: Buffer

        The mask of sectors. 80 bits, 2 bits/sector, the first bit is key A, the second bit is key B, 0b1 represent to skip checking the key.

    Returns Promise<null | {
        found: Buffer;
        sectorKeys: (null | Buffer)[];
    }>

    • found: 80 bits, 2 bits/sector, the first bit is key A, the second bit is key B, 0b1 represent key is found.
    • sectorKeys: 80 keys, 2 keys/sector, the first key is key A, the second key is key B. null represent key is not found.

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    const mask = Buffer.from('00000000FFFFFFFFFFFF', 'hex')
    const keys = Buffer.from('FFFFFFFFFFFF\n000000000000\nA0A1A2A3A4A5\nD3F7D3F7D3F7', 'hex').chunk(6)
    const tsStart = Date.now()
    const result = await ultra.cmdMf1CheckKeysOfSectors({ keys, mask })
    console.log(`Time: ${Date.now() - tsStart}ms`)
    const replacer = function (k, v) { return Buffer.isBuffer(this[k]) ? this[k].toString('hex') : v }
    console.log(JSON.stringify(result, replacer, 2))
    }
    // {
    // "found": "ffffffff000000000000",
    // "sectorKeys": [
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // "ffffffffffff", "ffffffffffff", "ffffffffffff", "ffffffffffff",
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // null, null, null, null,
    // ]
    // }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the mifare block data of actived slot.

    Parameters

    • offset: number = 0

      The start block of actived slot.

    • length: number = 1

      The count of blocks to be get.

    Returns Promise<Buffer>

    The mifare block data of actived slot.

    Example

    async function run (ultra) {
    const data = await ultra.cmdMf1EmuReadBlock(1)
    console.log(data.toString('hex')) // '00000000000000000000000000000000'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the mifare block data of actived slot.

    Parameters

    • offset: number

      The start block of actived slot.

    • data: Buffer

      The data to be set. the length of data should be multiples of 16.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    await ultra.cmdMf1EmuWriteBlock(1, Buffer.alloc(16))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the mode of actived slot that using anti-collision data from block 0 for 4 byte UID tags or not.

    Returns Promise<boolean>

    The mode of actived slot that using anti-collision data from block 0 for 4 byte UID tags or not.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdMf1GetAntiCollMode()) // false
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the count of mifare MFKey32 detections.

    Returns Promise<number>

    The count of mifare MFKey32 detections.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdMf1GetDetectionCount()) // 0
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the feature of mifare MFKey32 detections is enabled or not.

    Returns Promise<boolean>

    true if the feature of mifare MFKey32 detections is enabled, otherwise return false.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdMf1GetDetectionEnable()) // false
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the data of mifare MFKey32 detections.

    Parameters

    • offset: number = 0

      The start log of detections to be get.

    Returns Promise<Mf1DetectionLog[]>

    The mifare MFKey32 detections.

    Example

    async function run (ultra) {
    const logs = await ultra.cmdMf1GetDetectionLogs(0)
    console.log(logs)
    /**
    * {
    * "block": 2,
    * "isKeyB": 1,
    * "isNested": 0,
    * "uid": Buffer.from('65535d33', 'hex'),
    * "nt": Buffer.from('cb7b9ed9', 'hex'),
    * "nr": Buffer.from('5a8ffec6', 'hex'),
    * "ar": Buffer.from('5c7c6f89', 'hex'),
    * }
    */
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the mifare settings of actived slot.

    Returns Promise<Mf1EmuSettings>

    The mifare settings of actived slot.

    Example

    async function run (ultra) {
    const mf1Settings = await ultra.cmdMf1GetEmuSettings()
    console.log(JSON.stringify(mf1Settings))
    /**
    * {
    * "detection": false,
    * "gen1a": false,
    * "gen2": false,
    * "antiColl": false,
    * "write": 0
    * }
    */
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the mifare gen1a mode of actived slot.

    Returns Promise<boolean>

    The mifare gen1a mode of actived slot.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdMf1GetGen1aMode()) // false
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the mifare gen2 mode of actived slot.

    Returns Promise<boolean>

    The mifare gen2 mode of actived slot.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdMf1GetGen2Mode()) // false
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the mifare write mode of actived slot.

    Returns Promise<Mf1EmuWriteMode>

    The mifare write mode of actived slot.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdMf1GetWriteMode()) // 0
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Test whether it is mifare classic tag.

    Returns Promise<boolean>

    true if tag is mifare classic tag, otherwise return false.

    Example

    async function run (ultra) {
    console.log(await ultra.cmdMf1IsSupport()) // true
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Read block data from a mifare tag.

    Parameters

    • opts: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The block to be read and the key info of the block.

      • block: number

        The block to be read.

      • key: Buffer

        The key of the block.

      • keyType: Mf1KeyType

        The key type of the block.

    Returns Promise<Buffer>

    The block data read from a mifare tag.

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const block1 = await ultra.cmdMf1ReadBlock({
    block: 1,
    keyType: Mf1KeyType.KEY_A,
    key,
    })
    console.log(block1.toString('hex')) // '00000000000000000000000000000000'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the mode of actived slot that using anti-collision data from block 0 for 4 byte UID tags or not.

    Parameters

    • enable: number | boolean

      true to enable the mode, false to disable the mode.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdMf1SetAntiCollMode(false)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Enable or disable the mifare MFKey32 detection and clear the data of detections.

    Parameters

    • enable: number | boolean

      true to enable the detection, false to disable the detection.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdMf1SetDetectionEnable(true)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the mifare gen1a mode of actived slot.

    Parameters

    • enable: number | boolean

      true to enable the gen1a mode, false to disable the gen1a mode.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdMf1SetGen1aMode(false)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the mifare gen2 mode of actived slot.

    Parameters

    • enable: number | boolean

      true to enable the gen2 mode, false to disable the gen2 mode.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.cmdMf1SetGen2Mode(false)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set the mifare write mode of actived slot.

    Parameters

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Mf1EmuWriteMode } = window.ChameleonUltraJS
    await ultra.cmdMf1SetWriteMode(Mf1EmuWriteMode.NORMAL)
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Dectect the nt distance of mifare protocol.

    Parameters

    • known: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The info of known key.

      • block: number

        The block of known key.

      • key: Buffer

        The known key.

      • keyType: Mf1KeyType

        The key type of known key.

    Returns Promise<Mf1NtDistanceRes>

    The nt distance of mifare protocol.

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const res1 = await ultra.cmdMf1TestNtDistance({ block: 0, keyType: Mf1KeyType.KEY_A, key })
    const res2 = await ultra.cmdMf1AcquireNested(
    { block: 0, keyType: Mf1KeyType.KEY_A, key },
    { block: 4, keyType: Mf1KeyType.KEY_A },
    )
    const res = {
    uid: res1.uid.toString('hex'),
    dist: res1.dist.toString('hex'),
    atks: _.map(res2, item => ({
    nt1: item.nt1.toString('hex'),
    nt2: item.nt2.toString('hex'),
    par: item.par,
    }))
    }
    console.log(res)
    // {
    // uid: '877209e1',
    // dist: '00000080',
    // atks: [
    // { nt1: '35141fcb', nt2: '40430522', par: 7 },
    // { nt1: 'cff2b3ef', nt2: '825ba8ea', par: 5 },
    // ]
    // }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Check the nt level of mifare protocol.

    Returns Promise<Mf1PrngType>

    The nt level of mifare protocol.

    Example

    async function run (ultra) {
    const { Mf1PrngType } = window.ChameleonUltraJS
    console.log(Mf1PrngType[await ultra.cmdMf1TestPrngType()]) // 'WEAK'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • MIFARE Classic manipulate value block

    • Decrement: decrement value by X (0 ~ 2147483647) from src to dst
    • Increment: increment value by X (0 ~ 2147483647) from src to dst
    • Restore: copy value from src to dst (Restore and Transfer)

    Parameters

    • src: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The key info of src block.

      • block: number

        The block of src block.

      • key: Buffer

        The key of src block.

      • keyType: Mf1KeyType

        The key type of src block.

    • operator: Mf1VblockOperator

      The operator of value block.

    • operand: number

      The operand of value block.

    • dst: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The key info of dst block.

      • block: number

        The block of dst block.

      • key: Buffer

        The key of dst block.

      • keyType: Mf1KeyType

        The key type of dst block.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType, Mf1VblockOperator } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const src = { block: 4, keyType: Mf1KeyType.KEY_A, key }
    await ultra.mf1VblockSetValue(src, { value: 2 })
    console.log(await ultra.mf1VblockGetValue(src))
    await ultra.cmdMf1VblockManipulate(
    { block: 4, keyType: Mf1KeyType.KEY_A, key },
    Mf1VblockOperator.DECREMENT, 1,
    { block: 4, keyType: Mf1KeyType.KEY_A, key },
    )
    console.log(await ultra.mf1VblockGetValue(src))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Write data to a mifare tag.

    Parameters

    • opts: {
          block: number;
          data: Buffer;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The block to be written and the key info of the block.

      • block: number

        The block to be written.

      • data: Buffer

        The block data to be written.

      • key: Buffer

        The key of the block.

      • keyType: Mf1KeyType

        The key type of the block.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const block1 = Buffer.from('00000000000000000000000000000000', 'hex')
    await ultra.cmdMf1WriteBlock({
    block: 1,
    keyType: Mf1KeyType.KEY_A,
    key,
    data: block1,
    })
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Mifare Classic check keys of sectors.

    Parameters

    • opts: {
          chunkSize?: number;
          keys: Buffer[];
          mask?: Buffer;
          maxSectors?: number;
          onChunkKeys?: ((opts) => Promise<unknown>);
      }
      • Optional chunkSize?: number

        keys will be chunked by this size.

      • keys: Buffer[]

        The keys to be checked.

      • Optional mask?: Buffer

        The mask of sectors. 80 bits, 2 bits/sector, the first bit is key A, the second bit is key B, 0b1 represent to skip checking the key.

      • Optional maxSectors?: number

        The max sectors to be check.

      • Optional onChunkKeys?: ((opts) => Promise<unknown>)

        The callback function to be invoked before checking every chunk of keys.

    Returns Promise<Buffer[]>

  • Given a list of keys, check which is the correct key A and key B of the sector.

    Parameters

    • sector: number

      The sector number to be checked.

    • keys: Buffer[]

      The keys dictionary.

    Returns Promise<{
        96?: Buffer;
        97?: Buffer;
    }>

    The Key A and Key B of the sector.

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    const keys = Buffer.from('FFFFFFFFFFFF\n000000000000\nA0A1A2A3A4A5\nD3F7D3F7D3F7', 'hex').chunk(6)
    const sectorKey = await ultra.mf1CheckSectorKeys(0, keys)
    console.log(_.mapValues(sectorKey, key => key.toString('hex')))
    // { "96": "ffffffffffff", "97": "ffffffffffff" }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Read blocks from Mifare Classic Gen1a.

    Parameters

    • offset: number

      The start block of Mifare Classic Gen1a.

    • length: number = 1

      The amount of blocks to read.

    Returns Promise<Buffer>

    The blocks data.

    Example

    async function run (ultra) {
    const card = await ultra.mf1Gen1aReadBlocks(0, 64)
    console.log(_.map(card.chunk(16), chunk => chunk.toString('hex')).join('\n'))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Write blocks to Mifare Classic Gen1a.

    Parameters

    • offset: number

      The start block of Mifare Classic Gen1a.

    • data: Buffer

      The blocks data to write.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    await ultra.mf1Gen1aWriteBlocks(1, new Buffer(16))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Send Mifare Classic HALT command and close RF field.

    Returns Promise<void>

    Example

    async function run (ultra) {
    await ultra.mf1Halt()
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Check acl bytes of ACL, block or sector.

    Parameters

    • data: Buffer

      Data of ACL, block or sector.

    Returns boolean

    true if the acl bytes is valid, false otherwise.

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    console.log(ultra.mf1IsValidAcl(Buffer.from('ff078069', 'hex'))) // true
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Read the sector data of Mifare Classic by given keys.

    Parameters

    • sector: number

      The sector number to be read.

    • keys: Buffer[]

      The keys dictionary.

    Returns Promise<{
        data: Buffer;
        success: boolean[];
    }>

    The sector data and the read status of each block.

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType } = window.ChameleonUltraJS
    const keys = Buffer.from('FFFFFFFFFFFF\n000000000000\nA0A1A2A3A4A5\nD3F7D3F7D3F7', 'hex').chunk(6)
    const { data, success } = await ultra.mf1ReadSectorByKeys(0, keys)
    console.log({ data: data.toString('hex'), success })
    // { "data": "...", "success": [true, true, true, true] }
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get value from opts block (MIFARE Classic value block)

    Parameters

    • opts: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The key info of opts block.

      • block: number

        The block of opts block.

      • key: Buffer

        The key of opts block.

      • keyType: Mf1KeyType

        The key type of opts block.

    Returns Promise<{
        adr: number;
        value: number;
    }>

    The value and address of opts block.

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType, Mf1VblockOperator } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const src = { block: 4, keyType: Mf1KeyType.KEY_A, key }
    await ultra.mf1VblockSetValue(src, { value: 2 })
    console.log(await ultra.mf1VblockGetValue(src))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Set value X (-2147483647 ~ 2147483647) to dst block (MIFARE Classic value block)

    Parameters

    • dst: {
          block: number;
          key: Buffer;
          keyType: Mf1KeyType;
      }

      The key info of dst block.

      • block: number

        The block of dst block.

      • key: Buffer

        The key of dst block.

      • keyType: Mf1KeyType

        The key type of dst block.

    • val: {
          adr?: number;
          value?: number;
      }

      The value and address to be set.

      • Optional adr?: number

        The address to be set. Default is dst.block.

      • Optional value?: number

        The value to be set. Default is 0.

    Returns Promise<void>

    Example

    async function run (ultra) {
    const { Buffer, Mf1KeyType, Mf1VblockOperator } = window.ChameleonUltraJS
    const key = Buffer.from('FFFFFFFFFFFF', 'hex')
    const src = { block: 4, keyType: Mf1KeyType.KEY_A, key }
    await ultra.mf1VblockSetValue(src, { value: 2 })
    console.log(await ultra.mf1VblockGetValue(src))
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Write the sector data of Mifare Classic by given keys.

    Parameters

    • sector: number

      The sector number to be written.

    • keys: Buffer[]

      The key dictionary.

    • data: Buffer

      Sector data

    Returns Promise<{
        success: boolean[];
    }>

    the write status of each block.

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    const keys = Buffer.from('FFFFFFFFFFFF\n000000000000\nA0A1A2A3A4A5\nD3F7D3F7D3F7', 'hex').chunk(6)
    const data = Buffer.concat([
    Buffer.from('00000000000000000000000000000000', 'hex'),
    Buffer.from('00000000000000000000000000000000', 'hex'),
    Buffer.from('00000000000000000000000000000000', 'hex'),
    Buffer.from('ffffffffffffff078069ffffffffffff', 'hex'),
    ])
    const { success } = await ultra.mf1WriteSectorByKeys(1, keys, data)
    console.log(success)
    // [true, true, true, true]
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Get the blockNo of sector trailer.

    Parameters

    • sector: number

      The sector number.

    Returns number

    The blockNo of sector trailer.

    Example

    async function run () {
    const { ChameleonUltra } = window.ChameleonUltraJS
    console.log(ChameleonUltra.mf1TrailerBlockNoOfSector(0))
    // 3
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html

Mifare Ultralight Related

  • Read 4 pages (16 bytes) from Mifare Ultralight

    Parameters

    • opts: {
          pageOffset: number;
      }
      • pageOffset: number

        page number to read

    Returns Promise<Buffer>

    4 pages (16 bytes)

    See

    MF0ICU1 MIFARE Ultralight contactless single-ticket IC

    Example

    async function run (ultra) {
    const data = await ultra.mfuReadPages({ pageOffset: 0 })
    console.log(data.toString('hex')) // '040dc445420d2981e7480000e1100600'
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html
  • Write 1 page (4 bytes) to Mifare Ultralight

    Parameters

    • opts: {
          data: Buffer;
          pageOffset: number;
      }
      • data: Buffer

        4 bytes, the page data to be written.

      • pageOffset: number

        page number to read

    Returns Promise<void>

    See

    MF0ICU1 MIFARE Ultralight contactless single-ticket IC

    Example

    async function run (ultra) {
    const { Buffer } = window.ChameleonUltraJS
    const data = await ultra.mfuWritePage({ pageOffset: 9, data: Buffer.from('00000000', 'hex') })
    }

    await run(vm.ultra) // you can run in DevTools of https://taichunmin.idv.tw/chameleon-ultra.js/test.html

Plugin Related

  • Invoke a hook with context.

    Parameters

    • hook: string

      The hook name.

    • ctx: any = {}

      The context will be passed to every middleware.

    • Optional next: MiddlewareComposeFn

      The next middleware function.

    Returns Promise<unknown>

    The return value depent on the middlewares

Internal

debug: boolean
deviceMode: null | DeviceMode = null
hooks: Record<string, MiddlewareComposeFn[]>
isDisconnecting: boolean = false
logger: Record<string, Logger> = {}
plugins: Map<string, ChameleonPlugin>
supportedCmds: Set<Cmd> = ...
  • Internal

    Send a command to device.

    Parameters

    • opts: {
          cmd: Cmd;
          data?: Buffer;
          status?: RespStatus;
      }
      • cmd: Cmd

        The command to be sent to device.

      • Optional data?: Buffer

        <= 512 bytes, the data to be sent. This payload depends on the exact command being used. See Packet payloads for more infomation.

      • Optional status?: RespStatus

        The status is always 0x0000.

    Returns Promise<void>