Related
I am utilising the checkm8 exploit on my old iPad, trying to write my own implementation using the libusb-wrapper library python-libusb.
When I send a control transfer with a request of 4 (DFU_CLRSTATUS), the program just hangs there and never executes the next line of code. I've tried the following control transfers but they all produce the same result.
device._controlTransfer(0x21, 0x4, 0, 0, 0, 0, 0)
device.controlRead(0x21, 0x4, 0, 0, 0, 0)
device.controlWrite(0x21, 0x4, 0, 0, 0, 0)
This is the code leading up to the problematic block - I wonder if it's the asynchronous transfer that causes the issue?
stall(device)
for i in range(config.hole): // config.hole = 6
no_leak(device)
usb_req_leak(device)
no_leak(device)
dfu.release_device(device)
device = dfu.acquire_device()
async_ctrl_transfer(device, 0x21, 1, 0, 0, b'A' * 0x800, 0.0001)
Here is the functions that can be seen in the code:
def ctrl_transfer(
device: usb1.USBDeviceHandle,
bmRequestType: int,
bRequest: int,
wValue: int,
wIndex: int,
data_or_wLength: int = None,
timeout: float = None):
print(f"type of data_or_wLength: {type(data_or_wLength)}")
if type(data_or_wLength) is not int:
print(type(data_or_wLength))
r = device.controlWrite(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout)
else:
r = device.controlRead(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout)
def async_ctrl_transfer(
device: usb1.USBDeviceHandle,
bm_request_type: int,
b_request: int,
w_value: int,
w_index: int,
data: bytes,
timeout: float,
) -> None:
global request, transfer_ptr, never_free_device
request_timeout = int(timeout) if timeout >= 1 else 0
start = time.time()
never_free_device = device
request = array.array(
"B",
struct.pack("<BBHHH", bm_request_type, b_request, w_value, w_index, len(data))
+ data,
)
transfer_ptr = device.getTransfer(len(request))
transfer_ptr.setControl(bm_request_type, b_request, w_value, w_index, data)
transfer_ptr.submit()
while time.time() - start < timeout / 1000.0:
pass
transfer_ptr.cancel()
def stall(device: usb1.USBDeviceHandle): async_ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, b'A' * 0x10, 0.00001)
def leak(device: usb1.USBDeviceHandle): ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, 0xC0, 1)
def no_leak(device: usb1.USBDeviceHandle): ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, 0xC1, 1)
def usb_req_stall(device: usb1.USBDeviceHandle): ctrl_transfer(device, 0x2, 3, 0x0, 0x80, 0x0, 10)
def usb_req_leak(device: usb1.USBDeviceHandle): ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, 0x40, 1)
def usb_req_no_leak(device: usb1.USBDeviceHandle): ctrl_transfer(device, 0x80, 6, 0x304, 0x40A, 0x41, 1)
If there is anyone who has a good knowledge with USB or iDevices, I would be more than grateful if you could offer me some guidance on how to fix this problem. Thanks for any help!
I got my hands on a Lego Dimensions pad which is in fact a triple NFC reader. Found some code on github to start playing with it with a raspberry pi. I've got it so far that it sends a webhook to my Home Assistant to turn on a light when placing a minifigure on the pad. Where I got stuck and my python programming skills fall short is to also send a webhook when the tag is removed. Can anyone point me in the right direction?
Thx!
#!/usr/bin/python
import usb.core
import usb.util
from time import sleep
import requests
TOYPAD_INIT = [0x55, 0x0f, 0xb0, 0x01, 0x28, 0x63, 0x29, 0x20, 0x4c, 0x45, 0x47, 0x4f, 0x20, 0x32, 0x30, 0x31, 0x34, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
# Colors
OFF = [0,0,0]
RED = [255,0,0]
GREEN = [0,255,0]
BLUE = [0,0,255]
YELLOW = [255,255,0]
PURPLE = [128,0,128]
# Pad number
ALL_PADS = 0
CENTER_PAD = 1
LEFT_PAD = 2
RIGHT_PAD = 3
# Actions
TAG_INSERTED = 0
TAG_REMOVED = 1
# UIDs can be retrieved with Android App (most probably in hexadecimal)
uidBatman = [4, 117, 251, 42, 41, 73, 128] # Batman Lego
uidLucy = [4, 66, 84, 114, 82, 66, 129] # Lucy Lego
uidGandalf = [4, 133, 184, 90, 181, 73, 128] # Gandalf
# Webhook var
auth_token='[Token]'
hed = {'Authorization': 'Bearer ' + auth_token}
dataon = {"state": "on"}
dataoff = {"state": "off"}
def init_usb():
global dev
dev = usb.core.find(idVendor=0x0e6f, idProduct=0x0241)
if dev is None:
print("Device not found")
else:
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)
print usb.util.get_string(dev, dev.iProduct)
dev.set_configuration()
dev.write(1,TOYPAD_INIT)
return dev
def send_command(dev,command):
# calculate checksum
checksum = 0
for word in command:
checksum = checksum + word
if checksum >= 256:
checksum -= 256
message = command+[checksum]
# pad message
while(len(message) < 32):
message.append(0x00)
# send message
dev.write(1, message)
return
def switch_pad(pad, colour):
send_command(dev,[0x55, 0x06, 0xc0, 0x02, pad, colour[0], colour[1], colour[2],])
return
def main():
init_usb()
if dev != None :
while True:
try:
in_packet = dev.read(0x81, 32, timeout = 10)
bytelist = list(in_packet)
if not bytelist:
pass
elif bytelist[0] != 0x56: # NFC packets start with 0x56
pass
else:
pad_num = bytelist[2]
uid_bytes = bytelist[6:13]
action = bytelist[5]
if action == TAG_INSERTED :
print uid_bytes
if (uid_bytes == uidBatman) :
switch_pad(pad_num, RED)
url = '[URL]'
response = requests.post(url, json=dataon, headers=hed)
print(response)
print(response.json())
elif (uid_bytes == uidLucy) :
switch_pad(pad_num, PURPLE)
url = '[URL]'
response = requests.post(url, json=data, headers=hed)
print(response)
print(response.json())
elif (uid_bytes == uidGandalf) :
switch_pad(pad_num, YELLOW)
url = '[URL]'
response = requests.post(url, json=data, headers=hed)
print(response)
print(response.json())
else:
# some other tag
switch_pad(pad_num, GREEN)
else:
# some tag removed
switch_pad(pad_num, OFF)
except usb.USBError, err:
pass
switch_pad(ALL_PADS,OFF)
return
if __name__ == '__main__':
main()
Ethernet to RS-485 сonverter is connected to the computer and then I have 3 RS-485 controllers connected. I am writing registers to controllers using pymodbus. How can I do the same with modbus_tk?
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.utilities import computeCRC
Defaults.Timeout = 0.02
client = ModbusClient('192.168.0.191', port=9761)
client.connect()
builder = BinaryPayloadBuilder()
data = [0x00, 0x06, 0x00, 0x01, 0x00, 0xFF]
builder.add_8bit_uint(data[0])
builder.add_8bit_uint(data[1])
builder.add_8bit_uint(data[2])
builder.add_8bit_uint(data[3])
builder.add_8bit_uint(data[4])
builder.add_8bit_uint(data[5])
crc = computeCRC(data)
builder.add_8bit_uint(crc >> 8)
builder.add_8bit_uint(crc & 0x00FF)
payload = builder.build()
address = 0
client.write_registers(address, payload, skip_encode=True, unit=1)
I wrote this and it keeps giving me errors:
import usb.util
from time import sleep
TOYPAD_INIT = [0x55, 0x0f, 0xb0, 0x01, 0x28, 0x63, 0x29, 0x20, 0x4c, 0x45, 0x47, 0x4f, 0x20, 0x32, 0x30, 0x31, 0x34, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
OFF = [0,0,0]
RED = [255,0,0]
GREEN = [0,255,0]
BLUE = [0,0,255]
ALL_PADS = 0
CENTER_PAD = 1
LEFT_PAD = 2
RIGHT_PAD = 3
# Actions
TAG_INSERTED = 0
TAG_REMOVED = 1
# UIDs can be retrieved with Android App (most probably in hexadecimal)
uidDarthVader = (4, 161, 158, 210, 227, 64 , 128) # Darth Vader from Disney Infinity 3.0
def init_usb():
global dev
dev = usb.core.find(idVendor=0x0e6f, idProduct=0x0241)
if dev is None:
print('Device not found')
else:
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)
print(usb.util.get_string(dev, dev.iProduct))
dev.set_configuration()
dev.write(1,TOYPAD_INIT)
return dev
def send_command(dev,command):
# calculate checksum
checksum = 0
for word in command:
checksum = checksum + word
if checksum >= 256:
checksum -= 256
message = command+[checksum]
# pad message
while(len(message) < 32):
message.append(0x00)
# send message
dev.write(1, message)
return
def switch_pad(pad, colour):
send_command(dev,[0x55, 0x06, 0xc0, 0x02, pad, colour[0], colour[1], colour[2],])
return
def uid_compare(uid1, uid2):
match = True
for i in range(0,7):
if (uid1[i] != uid2[i]) :
match = False
return match
def main():
init_usb()
if dev != None :
while True:
try:
in_packet = dev.read(0x81, 32, timeout = 10)
bytelist = list(in_packet)
if not bytelist:
pass
elif bytelist[0] != 0x56: # NFC packets start with 0x56
pass
else:
pad_num = bytelist[2]
uid_bytes = bytelist[6:13]
match = uid_compare(uid_bytes, uidDarthVader)
action = bytelist[5]
if action == TAG_INSERTED :
if match:
# Darth Vader
switch_pad(pad_num, RED)
else:
# some other tag
switch_pad(pad_num, GREEN)
else:
# some tag removed
switch_pad(pad_num, OFF)
except(usb.USBError, err):
pass
switch_pad(ALL_PADS,OFF)
return
if __name__ == '__main__':
main()
and get one of two errors:
NameError: name 'err' is not defined
or
except usb.USBError, err:
^
SyntaxError: invalid syntax
why is that? My goal is to use this for a piece of tech i'm developing. i have tried looking on the web found nothing and tried reformatting the code still didn't work, finally i tried to use the code formatting assistant and it still didn't help.
Your error is a result of the variable err being undefined.
Here I can replicate the error:
In [7]: try:
...: raise SyntaxError
...: except(SyntaxError, err):
...: print("Error message")
...:
---------------------------------------------------------------------------
SyntaxError Traceback (most recent call last)
<ipython-input-7-7c18a68f8815> in <module>
1 try:
----> 2 raise SyntaxError
3 except(SyntaxError, err):
SyntaxError: None
During handling of the above exception, another exception occurred:
NameError Traceback (most recent call last)
<ipython-input-7-7c18a68f8815> in <module>
1 try:
2 raise SyntaxError
----> 3 except(SyntaxError, err):
4 print("Error message")
5
NameError: name 'err' is not defined
Instead, try removing the err, your except line should read
except(SyntaxError):
You should also know that the github repo where you got the code that you copy-pasted is in python 2, so that is likely why you are seeing this error.
Here is a link to the source, I've taken the liberty of fixing the syntax highlighting.
I build up some kind of RFID-Reader with an Raspberry Pi 3 and an RC522 using this code as a start: https://github.com/mxgxw/MFRC522-python.
Unfortunately I'm not able to get a APDU-Response from my card after sending any APDU-Command.
My current workflow is more or less the ISO 14443-4:
Search for cards
receive ATQA
Perform anticollision and select card
Determine whether card is supporting ISO-14443-4 protocol or not
Send RATS and receive ATS
Perform an PPS-Request [Until here everything is fine and I get responses.]
Send an APDU-Command [btw. command works fine with my smartphone and an APP]
#Scan for cards
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
#If a card is found
if status == MIFAREReader.MI_OK:
print "Card detected"
TagType = (TagType >> 6) | 0 #(Länge der UID errechnen
print "Tagtype: %s" % (TagType)
# START ANTI-COLLISION AS OF ISO 14443
if TagType == 0:
print "UID length is single -- starting ANTI-COLLISION CL1"
(status,uid) = MIFAREReader.MFRC522_Anticoll()
if status == MIFAREReader.MI_OK:
print "Card read UID: %s,%s,%s,%s" % (uid[0], uid[1], uid[2], uid[3])
elif TagType == 1: # Ignore this part as there is no functionality by now
print "CARD IS NOT SUPPORTED YET"
(status,uid) = MIFAREReader.MFRC522_Anticoll()
elif TagType == 2:
print "CARD IS NOT SUPPORTED YET"
(status,uid) = MIFAREReader.MFRC522_Anticoll()
elif TagType == 3:
print "CARD IS NOT SUPPORTED YET"
(status,uid) = MIFAREReader.MFRC522_Anticoll()
else:
print "An unexpected error occured: UID length is not covered by ISO-14443."
(size, APDU) = MIFAREReader.MFRC522_SelectTag(uid)
print "Card selected"
print "ISO 14443-4 Compatibility: %s" % (APDU)
if APDU == 1: # Card supports ISO 14443-4 protocol [Problem could be here]
#SEND RATS
print "Sening RATS"
RATS_Sequenz = [0xE0, 0x50]
CRC_RATS = []
CRC_RATS = MIFAREReader.CalulateCRC(RATS_Sequenz)
RATS_Sequenz.append(CRC_RATS[0])
RATS_Sequenz.append(CRC_RATS[1])
(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, RATS_Sequenz)
# Muss: Auswertung des ATS
# PPS
print "Initialisiere PPS-Kommando"
PPSS_Sequenz = [0xD0, 0x11, 0x00]
CRC_PPSS = []
CRC_PPSS = MIFAREReader.CalulateCRC(PPSS_Sequenz)
PPSS_Sequenz.append(CRC_PPSS[0])
PPSS_Sequenz.append(CRC_PPSS[1])
(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, PPSS_Sequenz)
#PCB = [0x02]
#PCB.append(PCB[0])
#PCB.append(PCB[1])
#(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, PCB)
command = [0xFF, 0x41, 0x00, 0x00, 0x00] # NOT THE COMMAND!
Header = [0x00, 0x22, 0xC1, 0xA4, 0x12, 0x80, 0x0A, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x04, 0x02, 0x02, 0x83, 0x01, 0x02, 0x84, 0x01, 0x0D] #Command to be sent
pOut = MIFAREReader.CalulateCRC(Header)
Header.append(pOut[0])
Header.append(pOut[1])
(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, (Header))
time.sleep(1) # Leftover from here / another non working try
Body = [0x80, 0x0A, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x04, 0x02, 0x02, 0x83, 0x01, 0x02, 0x84, 0x01, 0x0D]
#pOut = MIFAREReader.CalulateCRC(Body)
#Body.append(pOut[0])
#Body.append(pOut[1])
#(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, Body)
elif APDU == 0:
#HALT
command = [0x50]
pOut = MIFAREReader.CalulateCRC(command)
command.append(pOut[0])
command.append(pOut[1])
(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, command)
#WOP
This is the send function as found in the 'library':
def MFRC522_ToCard(self,command,sendData):
backData = []
backLen = 0
status = self.MI_ERR
irqEn = 0x00
waitIRq = 0x00
lastBits = None
n = 0
i = 0
if command == self.PCD_AUTHENT:
irqEn = 0x12
waitIRq = 0x10
if command == self.PCD_TRANSCEIVE:
irqEn = 0x77
waitIRq = 0x30
self.Write_MFRC522(self.CommIEnReg, irqEn|0x80)
self.ClearBitMask(self.CommIrqReg, 0x80)
self.SetBitMask(self.FIFOLevelReg, 0x80)
self.Write_MFRC522(self.CommandReg, self.PCD_IDLE);
while(i<len(sendData)):
self.Write_MFRC522(self.FIFODataReg, sendData[i])
i = i+1
self.Write_MFRC522(self.CommandReg, command)
if command == self.PCD_TRANSCEIVE:
self.SetBitMask(self.BitFramingReg, 0x80)
i = 2000
while True:
n = self.Read_MFRC522(self.CommIrqReg)
i = i - 1
if ~((i!=0) and ~(n&0x01) and ~(n&waitIRq)):
break
self.ClearBitMask(self.BitFramingReg, 0x80)
if i != 0:
if (self.Read_MFRC522(self.ErrorReg) & 0x1B)==0x00:
status = self.MI_OK
if n & irqEn & 0x01:
status = self.MI_NOTAGERR
if command == self.PCD_TRANSCEIVE:
n = self.Read_MFRC522(self.FIFOLevelReg)
lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
if lastBits != 0:
backLen = (n-1)*8 + lastBits
else:
backLen = n*8
if n == 0:
n = 1
if n > self.MAX_LEN:
n = self.MAX_LEN
i = 0
while i<n:
backData.append(self.Read_MFRC522(self.FIFODataReg))
i = i + 1;
else:
status = self.MI_ERR
print"Status: %s, Data: %s, Length: %s" % (status, backData, backLen)
return (status,backData,backLen)
The command is send using the 'toCard' function of the code mentioned above with following structure:
APDU-Command + CRC-Bytes.
e.g. 0x00 [CLA], 0x22 [INS], 0xC1 [P1], 0xA4 [P2], 0x12 [Length], 0x80 [DATA, 0x0A, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x04, 0x02, 0x02, 0x83, 0x01, 0x02, 0x84, 0x01, 0x0D, CRC1, CRC2
I also tried sending the Command with an additional PCB or in multiple parts (e.g. Header first then body).
I'm not sure if the structure of the APDU-Command is or if I forgot some part of the activation process as of ISO 14443. I'd be glad if anybody can help me.