For the last three days I have been looking for block and value blocks for Mifare 1K.
For example, I wrote data successfully 1. block with this APDU:
< FF D6 00 01 10 61 79 79 69 6C 64 69 7A 66 61 74 69 68 31 31 31
- Start Block 01
- Number of Bytes to Write: 16
- Data: ayyildizfatih111
> 90 00
- Write Binary Block Success
Then I can read as below APDU:
< FF B0 00 01 10
- Data Read at Start Block 01
- Number of Bytes Read: 16
> 61 79 79 69 6C 64 69 7A 66 61 74 69 68 31 31 31 90 00
- ASCII Mode: ayyildizfatih111
- Read Binary Block Success
But when I tried read value block it's giving this error.
< FF B1 00 01 04
- ACR122U Read Value Block
> 63 00
- Operation failed
So my question is what is the difference? When I am writing data, should I use binary blocks or value blocks. Which one is better?
Reading the value block fails because your block 1 is not a value block. Binary data blocks and value blocks share the same memory, the difference is just how you format the contents of the block and how you set the permissions for the block.
In order to turn block 1 into a value block, you would set the blocks access bits to allow value block operations (decrement, transfer, restore, and (optional) increment). You would then write the block as a value block (with ACR122U V2.02: either using the Value Block Operation command or using a regular Update Binary Block command).
The format of a value block (when using binary data block operations) is:
+----------+----------+----------+----+----+----+----+
Byte | 0..3 | 4..7 | 8..11 | 12 | 13 | 14 | 15 |
+----------+----------+----------+----+----+----+----+
Data | xxxxxxxx | yyyyyyyy | xxxxxxxx | uu | vv | uu | vv |
+----------+----------+----------+----+----+----+----+
Where xxxxxxxx is a 4 byte signed (2's complement) integer (LSB = byte 0), yyyyyyyy is the inverted value of xxxxxxxx, uu is an address byte (can be used when implementing a backup mechanism), vv is the inverted value of uu.
If you should use binary data blocks or should use the value format depends on your application. If you want to store a 4 byte integer value and wat to use value block operations, you may prefer to use the value block format. If you want to store other data, don't need the redundancy of the value block format, only want to use binary read/write operations, you may prefer to use a block as free-form binary data block.
Related
I use dieHarder tool with ASCII format input files and results are OK but now it`s the right time to use binary files instead. When I had converted my random data to a BIN file like described below no BIAS at all tests is seen. The documentation speaks of raw-binary input format when running on my UBUNTU machine but how this should look like ? My file content is as follows:
(UINT32 as bitstream in file)
0001110000111111000011101110111001111001010000000101110111111011111010011111001011111100100001 ...
call program as:
dieharder -g 201 -f <myFile.bin> -a
some sample probes of my input values:
473894638
00011100001111110000111011101110
2034261499
01111001010000000101110111111011
3925015684
11101001111100101111110010000100
...
All p-values will remain at 0.00000 when applying that binary format file.
I am curious whether how you write .bin file. I guess you wrote binary file in ASCII character. But it is not PROPER input_file_raw that Dieharder test needs. You should write file in Bytes(Binary) not ASCII. This post will be helpful to you or Comment please :)
I had tested several files with MT19937 (Mersenne Twister) and find out PROPER input file.
When you are going to write binary file for Dieharder test, you should keep in mind below 2 things.
Remove Header. (6 lines. From ####... to numbit: 32)
Change Integers from ASCII to Little Endian bytes
Dieharder Test example
Below Data is from MT19937 (32-bits, NOT 64-bits) in Go-language, with seed=0, generating 10,000,000 integers.
(Decimal) ASCII example
#==================================================================
# generator MT19937 seed = 0
#==================================================================
type: d
count: 10000000
numbit: 32
2357136044
2546248239
3071714933
3626093760
...
Binary file example
This is screenshots whether I can see with VSCode-HexEditor
AC 0A 7F 8C 2F AA C4 97 75 A6 16 B7 C0 CC 21 D8
43 B3 4E 9A FB 52 A2 DB C3 76 7D 8B 67 7D E5 D8
09 A4 74 6C D3 DE A1 9F 15 51 59 A5 F2 D6 66 62
24 B7 05 70 57 3A 2B 4C 46 3C 4B E4 D8 BD 84 0E
58 9A B2 F6 8C CD CC 45 3A 39 29 62 C1 42 48 7A
E6 7D AE CA 27 4A EA CF 57 A8 65 87 AE C8 DF 7A
58 5E 6B 91 51 8B 8D 64 A5 E6 F3 EC 19 42 09 D6
...
First data 2357136044 = 0x8C7F0AAC You can see First 4 bytes starts with 'AC' '0A' '7F' '8C'. That shows 2 things, there is no Header and it is Little Endian.
Code in Golang
I know below code is not helpful to you. As far as I know, there is no official Pure-MT19937 generator in Go-language. So, I do porting on my own from Pseudo-code in wiki to Go-language (1.17.1).
littleEndianFile, err := os.Create("./MT19937_LittleEndian.bin")
littleEndianFileBuffer := bufio.NewWriter(littleEndianFile)
littleEndianByte := make([]byte, 4)
// Generate MT19937 on my own.
test := NewMT19937(0)
newInt32 := test.NextUint32()
binary.LittleEndian.PutUint32(littleEndianByte, newInt32)
for _, eachByte := range littleEndianByte {
littleEndianFileBuffer.WriteByte(eachByte)
}
littleEndianFileBuffer.Flush()
Result - (Decimal) ASCII example
> dieharder -a -g 202 -f ./generated/MT19937_10000000.dat
#=============================================================================#
# dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
#=============================================================================#
rng_name | filename |rands/second|
file_input|./generated/MT19937_10000000.dat| 7.79e+06 |
#=============================================================================#
test_name |ntup| tsamples |psamples| p-value |Assessment
#=============================================================================#
diehard_birthdays| 0| 100| 100|0.63638992| PASSED
diehard_operm5| 0| 1000000| 100|0.00012670| WEAK
diehard_rank_32x32| 0| 40000| 100|0.93085433| PASSED
diehard_rank_6x8| 0| 100000| 100|0.07088597| PASSED
diehard_bitstream| 0| 2097152| 100|0.10456387| PASSED
Result - Little-Endian example
> dieharder -a -g 201 -f ./generated/MT19937_10000000_LittleEndian.bin
#=============================================================================#
# dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
#=============================================================================#
rng_name | filename |rands/second|
file_input_raw|./generated/MT19937_10000000_LittleEndian.bin| 5.60e+07 |
#=============================================================================#
test_name |ntup| tsamples |psamples| p-value |Assessment
#=============================================================================#
diehard_birthdays| 0| 100| 100|0.63638992| PASSED
diehard_operm5| 0| 1000000| 100|0.00012670| WEAK
diehard_rank_32x32| 0| 40000| 100|0.93085433| PASSED
diehard_rank_6x8| 0| 100000| 100|0.07088597| PASSED
diehard_bitstream| 0| 2097152| 100|0.10456387| PASSED
You can see above 2 tests (Decimal ASCII and Little-Endian) have same results (P-value)
Result - Big-Endian example
> dieharder -a -g 201 -f ./generated/MT19937_10000000_BigEndian.bin
#=============================================================================#
# dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
#=============================================================================#
rng_name | filename |rands/second|
file_input_raw|./generated/MT19937_10000000_BigEndian.bin| 5.65e+07 |
#=============================================================================#
test_name |ntup| tsamples |psamples| p-value |Assessment
#=============================================================================#
diehard_birthdays| 0| 100| 100|0.46325487| PASSED
diehard_operm5| 0| 1000000| 100|0.00000093| FAILED
diehard_rank_32x32| 0| 40000| 100|0.93085433| PASSED
diehard_rank_6x8| 0| 100000| 100|0.27138035| PASSED
diehard_bitstream| 0| 2097152| 100|0.75581067| PASSED
diehard_opso| 0| 2097152| 100|0.25961325| PASSED
diehard_oqso| 0| 2097152| 100|0.00025268| WEAK
However you can see that there is some different P-value between above and Big-Endian File. That proves that Dieharder PROPER example should be written in Little-Endian Binary.
Conclusion and Comments
I am afraid that you wrote binaries in ASCII characters. If you can see data with normal text editor like Windows-notepad, that means you wrote in ASCII character and it is UN-PROPER input_file. So, you have to write in Little-Endian Binary instead. This post and test results proved that Little-Endian is right and input_file_raw don't need header.
I am not sure if there is difference between Little-Endian and Big-Endian in "Analyzing test results". In NIST SP800-22, the statistical randomness test is kind of "Counting the number of 0 or 1" or "Checking if there is pattern of '0101', '001100', etc." I think there is no difference in "TRUTH level", which means this generate random or not.
But, I recommend you that writing binaries in Little-Endian. Because we don't know if test builder has profound reason or not.. We just follow the "PROPER" direction for use. :)
i'm using this open source lib as a ZVT implementation.
I have problems with the reversal of older transactions.
The example shows how to reverse the most recent transaction.
The ZVT Protocol (p.40) says to send the following to the terminal:
image link
tags in this brackets "[ ]" are optional.
I tried sending this:
06 30 06 12 34 5F 87 00 85
06 30 = Reversal
06 = 6 bytes length
12 34 5 = password with F as Filler?
87 = receipt no
00 85 = receipt no. 85
The password is: 12345
I dont know how to fill the empty space (uneven password). 0 and F does not work.
The receipt-no is a 2 byte long.
But the Terminal replies with error code "181" -> reversal not possible
my payment terminal is a iCT220.
Had to send
06 30 06 00 00 00 87 00 85
And watch out that 87 indicates the receipt-no. not the trace-no.
I am working with a Visa CDET contact-less test card. I have successfully selected the Application, which gave me the following result:
<= 6f 29 84 07 a0 00 00 00 03 10 10 a5 1e 50 0b 56 49 53 41 20 43 52 45 44 49 54 5f 2d 02 65 6e 9f 38 09 9f 66 04 9f 02 06 9f 37 04
The result included a PDOL which asked for the following items:
Terminal Transaction Qualifiers
Length: 4 bytes
Authorised Amount
Length: 6 bytes
Unpredictable Number
Length: 4 bytes
When it comes to the GPO command, I do have all the elements needed as shown below:
=> 80 a8 00 00 10 83 0e f3 20 40 00 00 00 00 00 12 00 bc 4b a2 3f 00
But when i run the command, I received a 67 00 error: Wrong Lc length. What could be the issue? Keep in mind the same program works perfectly when working with Visa CDET Contact test cards from the same kit.
EDIT:
About the same problem, I have a test reader that I use to confirm my readings. The reader and its program can get the GPO options and return the result for other cards, but my program is not giving me any results when I try the EXACT same command using the EXACT same card in my custom program. The result is a blank, yet the status words are 90 00 (they are separate from the returned data). Why is that?
Just assume first, that the card is right: If the length of data object 83 is 0x0F (instead of 0x0E) if I counted correctly, then the total length to be supplied in LC has to be 0x11 instead of 0x10 (tag and length to be added). This does not explain, why the contact version works, but possibly it still will work after the adjustment.
I received a 67 00 error: Wrong Lc length.
ok, its because you dont have Lc=0x00 in APDU
just add 0x00 to APDU
I am developing an application which reads NFC card from the reader.
I know the code for reading binary block like this:
FF B0 00 04 10
04 for the block 4 and 10 for 16 bytes data. My card has the data "TEST009996".
I run 5 code for read binary blocks from 4-8 like this:
FF B0 00 04 10
FF B0 00 05 10
FF B0 00 06 10
FF B0 00 07 10
FF B0 00 08 10
I got the following results:
T☻enTEÉ ☺
T☻enTEST00É
T☻enTEST009996É
enTEST009996■ 6É
ST009996■ 6 É
or in hexadecimal:
01 03 A0 10 44 03 11 D1 01 0D 54 02 65 6E 48 43 90 00
44 03 11 D1 01 0D 54 02 65 6E 48 43 49 44 30 30 90 00
01 0D 54 02 65 6E 48 43 49 44 30 30 39 39 39 36 90 00
65 6E 48 43 49 44 30 30 39 39 39 36 FE 00 00 36 90 00
49 44 30 30 39 39 39 36 FE 00 00 36 00 00 00 00 90 00
Should I create an algorithm to cut the result to get the data? Are there any better ways?
Source:
http://downloads.acs.com.hk/drivers/en/API-ACR122U-2.02.pdf
It seems that your tag is an NFC Forum Type 2 Tag (find the NFC Forum Type 2 Tag Operation specification on the NFC Forum website). As you mention MIFARE this could, for instance, be a MIFARE Ultralight, MIFARE Ultralight C or NTAG tag.
A block on a Type 2 Tag consists of 4 bytes. The read command reads 4 blocks at a time. So the read command gives you 4 blocks (4 bytes each) starting at a given block offset plus a status word for the read command (0x9000 for success). In your case you get:
Read(4, 16): 0103A010 440311D1 010D5402 656E4843 9000
Read(5, 16): 440311D1 010D5402 656E4843 49443030 9000
Read(6, 16): 010D5402 656E4843 49443030 39393936 9000
Read(7, 16): 656E4843 49443030 39393936 FE000036 9000
Read(8, 16): 49443030 39393936 FE000036 00000000 9000
Consequently, the memory of your tag looks like this:
0103A010
440311D1
010D5402
656E4843
49443030
39393936
FE000036
00000000
A Type 2 Tag (btw. in order to make sure that this tag actually conforms to the Type 2 Tag Operation Specification you would also need to read the capability container which is located in block 3) contains a series of tag-length-value (TLV) structures:
01 (Tag: Lock Control TLV)
03 (Length: 3 bytes)
A0 10 44 (Value: Information on position and function of lock bytes)
03 (Tag: NDEF Message TLV)
11 (Length: 17 bytes)
D1010D5402656E48434944303039393936 (Value: NDEF message)
FE (Tag: Terminator TLV; has no length field)
So your tag contains the NDEF message
D1010D5402656E48434944303039393936
This translates to
D1 (Header byte of record 1)
- Message begin is set (= first record of an NDEF message)
- Message end is set (= last record of an NDEF message)
- Short record flag is set (= Payload length field consists of 1 byte only)
- Type Name Format = 0x1 (= Type field contains an NFC Forum well-known type)
01 (Type length: 1 byte)
0D (Payload length: 13 bytes)
54 (Type: "T")
02656E48434944303039393936 (Payload field)
The payload field of a NFC Forum Text record decodes like this:
02 (Status byte: Text is UTF-8 encoded, Language code has a length of 2 bytes)
656E (Language code: "en")
48434944303039393936 (Text: "TEST009996")
I am trying to write a command line application which can modify a .so file using hex values at specific addresses.
I'm using IDA Demo and HxD Hex Editor to attain the addresses which need to be updated, however, each time I try to modify the file, no matter which language I use (bash scripting, php, python) every time I edit the file, it updates from the wrong address offsets which I have from IDA and HxD Hex Editor.
I have seen a few posts regarding this, but as of yet, none have been able to give a definitive answer as to how to attain the addresses which HxD and IDA have no issue finding :(
In python I have used the mmap function to attempt this using the below;
import mmap
import contextlib
import os
filesize = os.stat("filetomodify.so").st_size
print int(filesize)
with open("filetomodify.so", 'r+b') as f:
with contextlib.closing(mmap.mmap(f.fileno(), access=mmap.ACCESS_WRITE)) as m:
m[0x173596] = "FF 20"
m[0x18D88E] = "FF 20"
m.close()
This uses the os library to determine the size of the file which is returned as 10025936, however, each time I add the length=filesize argument between f.fileno() and access=mmap.ACCESS_WRITE I always get a mmap.error: [Errno 22] Invalid argument Error Message, but when I omit the argument, I get a m: TypeError: Required argument 'length' (pos 2) not found
The bash script I have used is one which I found here, which modifies the file okay, but updates the wrong addresses;
#!/bin/bash
# param 1: file
# param 2: offset
# param 3: value
# param 4: Size of Bytes
function replaceByte() {
printf "$(printf '\\x%02X' $3)" | dd of="$1" bs=$4 seek=$2 count=1 conv=notrunc &> /dev/null
}
# Usage:
replaceByte 'filetomod.so' "0x173596" "95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01" 15
Calling the function as described above updates the file and writes it ok, but when I do a find for the updated byte string (e.g, 95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01 -- Just a long unique string which you would not expect to find in a file) it has been inserted at the incorrect address, or it tells me that the offset is outside of the file size.
Lastly, the php code I used (which I wasn't expecting much success with anyway) was;
<?php
$fp = fopen('binary_file.bin', 'w+b');
fseek($fp, 173596, );
fwrite($fp, '95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01');
fclose($fp);
?>
However, rather than editing the Hex values of the binary file, this added the string as a string to the binary file at HxD Address 0002A61C with the hex code as 39 35 20 45 35 20 30 41 20 32 46 20 36 36 20 31 45 20 33 32 20 45 45 20 34 43 20 42 38 20 39 41 20 36 45 20 42 44 20 45 43 20 30 31 which had the output of 95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01
Any help with this would be greatly appreciated. My only requirement for the answers would be that it can be run from command line, whether php, bash, python, java etc.
Thank you in advance.
After some trials in a virtual machine running Centos 6.5, I got it
function replaceByte() {
printf "$(printf '\\x%02X' $3)" |
dd of="$1" ibs=1 count=1 obs=1 seek="$2" conv=notrunc &> /dev/null
}
The problem is the unit of the seek parameter: BLOCKS, not BYTES.
When you change the default block size, both input block size and output block size are changed. Therefore the seek parameter refers to blocks whose size is the value of bs parameter.
To solve this, you must set the input block size ibs as youd did but the output block size obs must be set to 1. Otherwise, as output is a disk file, the obs value is set to 512 bytes (the disk block size).
You can try the following test to check the size of the output block is 512, not 1:
Create a text file (file.txt) containing an entire blank line (for example, 30 white spaces)
Check that the size of the file is near 30 bytes.
Run echo -e '\x41' | dd if=file.txt ibs=1 count=1 seek=3 conv=notrunc (0x41 is the ASCII code for A)
Check that the size of file.txt has changed: 1537 bytes (3 blocks of 512 bytes per block plus 1 -- 3*512+1)
As file.txt is "corrupted", repeat the steps 1 and 2.
Run echo -e '\x41' | dd if=file.txt ibs=1 count=1 obs=1 seek=3 conv=notrunc
Check that the size of file.txt has not changed.
Look the contents of the file and check that there is an 'A' replacing the 4th blank.
Best regards.
P.D: this funcion replaceByte() should work fine for just ONE byte. If you need to change several contiguous bytes in a single call, you must replace the printf, perhaps, with a loop... and the ibs=1 with the proper value.