I am fixing a bug in a parser for DWARF debug information (2nd DWARF version). In the process I made the following strange observation:
A bytestream was created by reading a dll file (created with ada files by GNAT). At the position of a "DW_TAG_structure_type" in debug_info inside this bytestream an additional byte with the value 1 has crept into the byte stream. Thereby all values in the FileInputStream are shifted by 1 byte.
This is how the original DIE in .debug_info looks like:
<1><3aa824>: Abbrev Number: 129 (DW_TAG_structure_type)
<3aa826> DW_AT_byte_size : 44
<3aa827> DW_AT_decl_file : 11
<3aa828> DW_AT_decl_line : 380
<3aa82a> DW_AT_artificial : 1
<3aa82b> DW_AT_sibling : <0x3aa888>
This is the corresponding scheme for the DIE in .debug_abbrev:
129 DW_TAG_structure_type [has children]
DW_AT_byte_size DW_FORM_data1
DW_AT_decl_file DW_FORM_data1
DW_AT_decl_line DW_FORM_data2
DW_AT_artificial DW_FORM_flag
DW_AT_sibling DW_FORM_ref4
DW_AT value: 0 DW_FORM value: 0
However, when I display the bytestream at this point, these values are shown:
Abbrev Number >>Strange Byte<< DW_AT_byte_size DW_AT_decl_file
81 01 2C 0B ...
(129) ?? (44) (11)
Does anyone know what this "Strange Byte" is all about?
Not really familiar with DWARF, but the DWARF 2.0 specification reads (section 7.5.3):
Following the tag encoding is a 1-byte value that determines whether a
debugging information entry using this abbreviation has child entries
or not. If the value is DW_CHILDREN_yes, the next physically
succeeding entry of any debugging information entry using this
abbreviation is the first child of the prior entry. If the 1-byte
value following the abbreviation’s tag encoding is DW_CHILDREN_no, the
next physically succeeding entry of any debugging information entry
using this abbreviation is a sibling of the prior entry. [...]
Finally, the child encoding is followed by a series of attribute
specifications. [...]
So, could this "strange byte" represent DW_CHILDREN_yes?
I'm also a little bit puzzled by the value 0x81 (129). The specification states that the tag encoding for DW_TAG_structure_type is 0x13 (which should fit in a byte), and the previous quote suggests that the tag encoding is followed by a byte that is not part of the tag encoding itself (if I understand correctly). So I would expect a stream of 0x13 0x01 (encoded tag + has child entries flag).
I want to read around 336 bytes of data from NVRAM using Read Memory By Address UDS service. The command I am giving is "23 22 1C 22 01 50", where
0x23 - UDS command for Read Memory By Address
0x22 - Address and Length Format Identifier (Memory
address parameter - 2 and Memory size parameter 2)
0x1C 0x22 - Memory Address in 2 bytes
0x01 0x50 - Data length to read in 2 bytes (length is 336 bytes)
When I submit the command, I am getting "0x13 Incorrect Message Length or Invalid Format Error".
Can someone help me fixing this problem.
Thanks in advance.
Reference: https://piembsystech.com/uds-protocol/
What NRC 0x13 means
According to ISO 14229-1:2020:
This means:
SID 0x23 is supported by the server otherwise you would receive NRC 0x11 serviceNotSupported
Your request has inproper format (it is either too long or too short), in other cases you would receive other NRC (e.g. 0x31 requestOutOfRange). I suspect that address value is not 2 bytes long. It might be 4 bytes long (it depends on the memory type and size), but it is just a guess.
How to send the request properly
Well we do not know what is the exact format that the server accepts (it depends on memory of the server), but the ISO 14229-1:2020 define SID 0x23 request format as below:
I would try following request:
0x22 0x44 0x00 0x00 0x1C 0x22 0x00 0x00 0x01 0x50
where:
0x00 0x00 0x1C 0x22 - 4-byte memoryAddress
0x00 0x00 0x01 0x50 - memorySize (it is also 4 byte to make sure that addressAndLengthFormatIdentifier is properly interpreted by the server)
Other options
Server might have defect(s) (especially if you succesfully read memory using 2-byte-long address) and incorrectly display NRC 0x13 or have only support for certain value of addressAndLenghtFormatIdentifier. It is hard to judge with 100% certainty though. You would have provide at least one request with positive response.
Please do so in the comment and I am going to guide you through the problem.
I was modifying a piece of PC software I wrote to read multiple NDEF records from an NFC tag. However, one of the tags I have contains a record with what seems to be a mangled NDEF header. It's the last record of 6, the other 5 coming in as expected. I've listed it below. For simplicity, all values are listed in hexidecimal and the payload has been truncated.
Record #6
Header: 42
Type Length: 03
Random Bytes: 00 00 00
Payload Length: 2C (44)
Rec. Type: 6E 2F 70 (n/p)
Payload: **
As you can see, 3 random zero bytes are shoved between what should be the Type Length and Payload Length. I have double checked the Length Field in the TLV and found that it accounts for these 3 bytes. I'm not getting any data truncated off of the end of the TLV due to these added bytes.
I decided to do a sanity check with NXP's TagInfo app to make sure I wasn't just reading the data incorrectly. Checking the data dump from a full scan, I saw that the data does in fact match. I've listed the memory scan below. Only the relevant data points are listed and the payload is, again, truncated.
Memory Dump
addr data
...
[30] -- -- 42 03 |--B.|
[31] 00 00 00 2C |...,|
[32] 6E 2F 70 ** |n/p*|
[33] ** ** ** ** |****|
...
[3D] ** ** ** FE |***.|
...
We thought that maybe this was an issue with padding given that, in this case, the Terminator TLV appears at the end of page 0x3D. However, due to the nature of previous records, this is not always the case. Sometimes, the Terminator TLV shows up in the middle of a page.
However, the strange thing is that, in the same TagInfo app on the NDEF page, it reports the NDEF message as follows.
NDEF Message
...
[A8] 52 03 2C 6E 2F 70 ** ** |R.,n/p**|
[B0] ** ** ** ** ** ** ** ** |********|
...
[D8] ** ** |** |
...
Somehow, the software has not only removed the 3 extra bytes, but has correctly set the SR bit in the NDEF header. I have double checked this with another NFC app on Android and have confirmed that the other app is able to read the NDEF Message this way as well.
My question is, is there a reason or logic behind how the app is able to correct not only the the added bytes, but also the NDEF Header? I'm not sure if this is Android doing the correction or something else deeper in the NDEF message structure. Either way, I'm looking at the right way to make the correction while not effecting how I read the other 5 records held within this tag.
Those bytes are also part of the payload length
If the record does not have the SR (short record) bit set, then the payload length is 4 bytes long rather than one byte.
https://learn.adafruit.com/adafruit-pn532-rfid-nfc/ndef#payload-length-9-9
The first byte is 0x42, which in binary is 0100 0010. If we separate that out, we can see that the record has the ME (or 'Message End') bit set, as well as a TNF ('Type Name Format') of 0x02 - 'MIME Media Record'. The SR bit is bit 4, which is zero in this case.
That's also why they disappear in the version corrected by the TagInfo app - it has set the SR (which is why the header jumps to 0x52) and removed the unnecessary bytes.
I'm trying to switch a Mifare Plus card into SL1 mode using an Omnikey 5421, however using the "Generic card command" interface as instructed by the documentation does not seem to work (card does not return any kind of output except 0x9000 which seems to be only an ACK that the command was sent succesfully - there should be additionaly bytes in the response before 0x90 0x00 which come from the chip itself).
The sequence is sent using SCardTransmit:
0xFF 0xA0 0x00 0x07 0x03 0x01 0x00 0x01 - enter generic session - returns 0x9000
... additional commands using documentation:
0xFF 0xA0 0x00 0x05 6+n 01 00 F3 00 00 64 + Mifare+ command 00 - returns 0x9000 whatever the command, even if invalid Mifare+ commands
0xFF 0xA0 0x00 0x07 0x03 0x01 0x00 0x02 - exit generic session - returns 0x9000 still
The only commands that seem to work are enter and exit, any other command that I send in between does not seem to have any effect, including RATS, Writeperso or Commitperso. When I add the 00 Le byte at the end the return code is 0x6400 instead of 0x9000, even though the docs say that Le byte should be appended when issuing Mifare+ commands.
All other operations work ok once the cards is personalized in SL1 mode (read, write, authenticate). I can already switch the card to SL1 mode using android NFC, so it does not seem to be a problem with the algorithm or the card.
I've tried to use command from the PC/SC part 3 documentation, but the return code is "not supported", so it seems that only this mechanism of transparent channel is available to issue 14443A commands.
In SL0 and SL3, You may directly call the Plus command via Generic Card Command.
"generic session" should be for SL1 to accept Plus command(as by default it goes to mifare classic mode)
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendorId);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
CFRelease(numberRef);
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &deviceProductId);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
CFRelease(numberRef);
numberRef = NULL;
kr = IOServiceAddMatchingNotification(gNotifyPort,
kIOFirstMatchNotification,
matchingDict,
DeviceAdded,
NULL,
&gAddedIter);
For handle the notification while add the usb device to Mac pc is ok, but can i getting the signal while user press the button on the usb device?
Thanks ALL!
If a user presses a button on a device, this will not create a device notification. Unless this is a device Apple has a driver for (in which case you may receive an input event, e.g. an NSEvent), you will have to get the device interface and talk to that device through its interface. E.g. USB devices have interfaces, each interface has endpoints and the connections to those endpoints are labeled pipelines. There are outgoing and incoming pipelines and you can send data to or read data from those pipelines. Different kind of pipelines exist, bulk, isochronous and interrupt pipelines. Further every device has a control pipe, the only pipeline you can use bidirectionally.
Apple ships a tool named USB Prober with Xcode, have a look at your USB devices with it. E.g. my Apple Cinema Display, also connected via USB, reports the following:
Full Speed device # 3 (0xFD520000): ............................................. Composite device: "Apple Cinema HD Display"
Port Information: 0x0019
Captive
External Device
Connected
Enabled
Device Descriptor
Descriptor Version Number: 0x0110
Device Class: 0 (Composite)
Device Subclass: 0
Device Protocol: 0
Device MaxPacketSize: 8
Device VendorID/ProductID: 0x05AC/0x9223 (Apple Inc.)
Device Version Number: 0x0114
Number of Configurations: 1
Manufacturer String: 1 "Apple Computer, Inc."
Product String: 2 "Apple Cinema HD Display"
Serial Number String: 0 (none)
Configuration Descriptor
Length (and contents): 34
Raw Descriptor (hex) 0000: 09 02 22 00 01 01 00 E0 01 09 04 00 00 01 03 00
Raw Descriptor (hex) 0010: 00 00 09 21 11 01 00 01 22 37 00 07 05 81 03 08
Raw Descriptor (hex) 0020: 00 10
Number of Interfaces: 1
Configuration Value: 1
Attributes: 0xE0 (self-powered, remote wakeup)
MaxPower: 2 ma
Interface #0 - HID
Alternate Setting 0
Number of Endpoints 1
Interface Class: 3 (HID)
Interface Subclass; 0
Interface Protocol: 0
HID Descriptor
Descriptor Version Number: 0x0111
Country Code: 0
Descriptor Count: 1
Descriptor 1
Type: 0x22 (Report Descriptor)
Length (and contents): 55
Raw Descriptor (hex) 0000: 05 80 09 01 A1 01 15 00 26 FF 00 75 08 85 02 96
Raw Descriptor (hex) 0010: 01 01 09 02 B2 02 01 05 82 95 02 85 10 09 10 B1
Raw Descriptor (hex) 0020: 02 25 04 85 D6 09 D6 B1 02 25 07 85 E7 B1 02 26
Raw Descriptor (hex) 0030: FF 00 85 E4 81 02 C0
Parsed Report Descriptor:
Usage Page (Monitor)
Usage 1 (0x1)
Collection (Application)
Logical Minimum......... (0)
Logical Maximum......... (255)
Report Size............. (8)
ReportID................ (2)
Report Count............ (257)
Usage 2 (0x2)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Buffered bytes)
Usage Page (VESA Virtual Controls)
Report Count............ (2)
ReportID................ (16)
Usage 16 (0x10)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Logical Maximum......... (4)
ReportID................ (214)
Usage 214 (0xd6)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Logical Maximum......... (7)
ReportID................ (231)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Logical Maximum......... (255)
ReportID................ (228)
Input................... (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
End Collection
Endpoint 0x81 - Interrupt Input
Address: 0x81 (IN)
Attributes: 0x03 (Interrupt no synchronization data endpoint)
Max Packet Size: 8
Polling Interval: 16 ms
This device has one Interface, Interface #0 and there exist one endpoint on this interface (0x81), which is connected through an interrupt pipeline, that can transfer packets up to 8 bytes in size every 16 ms. If you'd now want to communicate with that pipeline, you'll have to get the USB driver interface of the device and this interface offers functions to communicate with the pipeline in question, synchronously or asynchronously, it's all pretty similar to network code.
If you now ask yourself, what this pipeline is good for at a monitor in the first place, it's how the monitor communicates button presses to the system. Apple's Cinema Displays have 3 buttons, "+" and "-" for brightness and a power button. The functionality of the power button is configurable in the system prefs, e.g. it can send the whole Mac to sleep if I want that. Whenever I hit one of those button, an interrupt event is created and sent via this USB pipe to the system (actually the system has to poll for such an event every 16 ms, but the system does that for you - your code can pretend the event was pushed by the monitor).
Have a look at the IOUSBDeviceInterface197, and please note, that it inherits of IOUSBDeviceInterface187, which inherits of IOUSBDeviceInterface182, which again inherits of IOUSBDeviceInterface. That means if you retrieve a 197 version of the interface, all methods of the interfaces it inherits from are available for this interface as well (they are just not listed again on the page). Apple has to use interface with versions in the name to stay compatible with older code. Apple extended the USB interfaces over the time (e.g. with new OS X releases) and to be sure that old code still runs, they always added a new interfaces, otherwise they'd break existing code.
Here you get a list of all these interfaces. Yes, the documentation is horrible. You have to learn by try and and/or and sample code. Please note there are DeviceInterfaces and InterfaceInterfaces; that's not the same thing. A DeviceInterface is the driver interface to a device itself, every device can have multiple "USB interfaces" (this is a term of the USB standard) and the interface to such an "usb interface" is named an "InterfaceInterface". Simple devices, as the monitor shown above, only have a single interface, though.
You think that this is darn complicated? Well, most developers from other platforms say, that once they figured out how all this stuff works, Mac OS is the easiest of all platforms if you need raw access to USB pipes. However, it gets even worse: Every interface can have multiple configurations and you can set a configuration on the interface which might change the pipelines (e.g. in one configuration a pipe is a bulk pipe and in another one the very same pipe is now an isochronous pipe). You can see all this in the USB Prober application (it shows alternative configuration). And please note, that an USB device can have a completely different set of interfaces, pipelines and configurations for different speeds (e.g. one for USB 1.2, aka low + full speed, and one for USB 2, aka hi-speed).
Apple tries to explain most of the USB basics you should know before you start writing any code on this page. And if you click on "Working With USB Device Interfaces", Apple even has plenty of sample code for you how to get a DeviceInterface, which you can use to get InterfaceInterfaces.
I hope I could get you some pointers and some interesting links for reading. It's not really the answer to your question, but it is a good start. Of course, you could also write a kernel driver (kernel extension) to add support for your device to the system, so that pressing the button generates an event that any software can handle without having to use IOKit at all... but I somehow doubt you want to go there.