# Proxmark3 developers community

Research, development and trades concerning the powerful Proxmark3 device.

Remember; sharing is caring. Bring something back to the community.

"Learn the tools of the trade the hard way." +Fravia

You are not logged in.

## #1 2019-06-12 10:32:32

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

Below is my code for the leading 0 write command.

Since there are many forks, this will need to be turned to suite the fork, but should be enough for someone to run with.

feel free to use and change as needed.

What I did was added a z 'leading Zero' option in the client software.  I supplied the opton via the arg flags passed in with the normal write call.

My thought was to use 2 bits in the arg byte, were 00 - normal/default. 01 was leading 0, 10 and 11 reserved for the other two modes.

all this can live in the lfops.c file.

I updated the T55xxWriteBlock function to call the correct writeblockExt.

void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {

if ((arg & 0xC0) == 0x00) T55xxWriteBlockExt    (Data, Block, Pwd, arg); // Standard
if ((arg & 0xC0) == 0x80) T55xxWriteBlockExt_lz (Data, Block, Pwd, arg); // Leading 0

// T55xxWriteBlockExt(Data, Block, Pwd, arg);
cmd_send(CMD_ACK,0,0,0,0,0);
}

then the following addition for leading zero.  This is a cut and paste from the base code, then tuned and adjusted for leading 0 with the timings (based on the data sheet) that I found to work for me.

#define lzSTART_GAP 31*8
#define lzWRITE_GAP 20*8
#define lzWRITE_0   18*8
#define lzWRITE_1   40*8

void T55xxWriteBitlz(int bit) {
if (!bit)
else
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(WRITE_GAP);

}

void T55xxWriteBlockExt_lz (uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {

LED_A_ON();
bool PwdMode = arg & 0x1;
uint8_t Page = (arg & 0x2)>>1;
bool testMode = arg & 0x4;
uint32_t i = 0;

// Set up FPGA, 125kHz
StartTicks();
// make sure tag is fully powered up...
WaitMS(5);
// Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);

WaitUS(START_GAP);

/* MWalker change 15 May 2019
11   : Opcode
00   : Fixed 00 if protected write (i.e. have password)
0 	: Lock Bit
<32 bit data>

*/

/*
Standard Write : 0 1p L <32 data bits> <3 bit addr>
0 10 0 00000000000000000000000000000000 001
Protected Write: 0 1p 00 <32 pwd bits> L <32 data bits> <3 bit addr>
0 10 00 00000000000000000000000000000000 0 00000000000000000000000000000000 001
Wake Up			 0 10 00 <32 pwd bits>
Protected Read   0 1p 00 <32 pwd bits> 0 <3 bit addr>
Reset            0 00

*/

T55xxWriteBitlz(0); //T55xxWriteBit(0);

if (testMode) Dbprintf("TestMODE");
// Std Opcode 10
T55xxWriteBitlz(testMode ? 0 : 1);
T55xxWriteBitlz(testMode ? 1 : Page); //Page 0

if (PwdMode) {
// Leading zero - insert two fixed 00 between opcode and password
T55xxWriteBitlz (0);
T55xxWriteBitlz (0);
// Send Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBitlz(Pwd & i);
}

// Send Lock bit
T55xxWriteBitlz(0);

// Send Data
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBitlz(Data & i);

// Send Block number
for (i = 0x04; i != 0; i >>= 1)
T55xxWriteBitlz(Block & i);

// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
// so wait a little more)
// "there is a clock delay before programming"
//  - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567
//  so we should wait 1 clock + 5.6ms then read response?
//  but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow...
if (testMode) {
//TESTMODE TIMING TESTS:
// <566us does nothing
// 566-568 switches between wiping to 0s and doing nothing
// 5184 wipes and allows 1 block to be programmed.
// indefinite power on wipes and then programs all blocks with bitshifted data sent.

} else {
//could attempt to do a read to confirm write took
// as the tag should repeat back the new block
// until it is reset, but to confirm it we would
// need to know the current block 0 config mode for
// modulation clock an other details to demod the response...
// response should be (for t55x7) a 0 bit then (ST if on)
// block data written in on repeat until reset.

//DoPartialAcquisition(20, true, 12000);
}

// turn field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_A_OFF();

}

Offline

## #2 2019-06-12 12:19:28

marshmellow
Moderator
From: US
Registered: 2013-06-10
Posts: 2,299

Thanks!.  I assume your fork is not based on the pm3 master repo so you couldn't issue a pull request?

Offline

## #3 2019-06-12 12:55:22

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

I am really not up-to-speed with the whole git thing, learning as I go.  It was based on the official PM3 git.
But, as I think I have heard you comment a few times,  the code has morphed a few times with different coders.  So until I get up to speed I thought it would be simpler for someone who knows to add it in to keep things inline.
(e.g. I am a curly bracket on the next line coder, so had to fight the urge on that one)

When I had a look to add the same thing for the read, I noticed there was no "arg" to set some flags, then I thought.. should I try to change that... So thought I would not touch atm.

To add to that, on my rdv4 i am using the rrg (as I want the bluetooth when i get the module) and thats different again.

So until i am up to speed,  I thought I would pass on.

Offline

## #4 2019-06-14 02:13:00

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

Slowly working out the github side.

With this project is there a place to discuss an idea first, or do we make changes and submit the pull request and then the changes get discussed ?

e.g.
In the above code, the write block function passed in the arg, so we could use that to set some flags as i did.
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg)
but the readblock did not seem to have that, which might be a good idea ?

Not knowing the code as well as others, I dont want to head down the wrong path.
I am happy to learn and work though this and try to do things the way to project would like it.
i.e. My idea for the t55xx was to see if i could get it to support the 4 downlink modes for all reads/writes.
So for the write, the call break out is already there, but to get a readblock (say  for leading 0), would then allow you to read data without changing the card data, so I think it will be a good idea.

So, back to the real question.
I am happy to put in the time to learn and make the changes and test, so not asking others to do this for me (no issue if they do).
I have setup a real fork in github to allow the code to flow in that frame work, almost got that bit sorted (and my head around it).
The question now is more about how we decide if a code change is a good or bad idea such that I can head in the direction of success.

thanks

Offline

## #5 2019-06-14 02:31:18

marshmellow
Moderator
From: US
Registered: 2013-06-10
Posts: 2,299

Well, first adding an arg for you're new options would be the right way to go. ( granted I'm far from as good a coder as pwpiwi or several others here so I'll yield to them if they have other ideas)

Second all code changes are reviewed (and changes may be requested) on the master repo before they get merged.  (You issue a pull request to the master repo to include your changes)

That pull request gets reviewed and commented on before being accepted.

Now I will give you a hint that got me in trouble at times with github.

Keep your master branch = to the master repos master branch and do all you're large code testing/ building in a separate branch(s).  This makes it easier to continue working on other projects while you're pull request is being reviewed.  (Any changes to the branch you're pull request was made on will be included in the pull request automatically.)

Last edited by marshmellow (2019-06-14 02:34:21)

Offline

## #6 2019-06-14 07:20:20

piwi
Contributor
Registered: 2013-06-04
Posts: 698

marshmellow is the Subject Matter Expert when it comes to lf commands, so I will rely on him when it comes to a code review

Offline

## #7 2019-06-15 06:22:46

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

Progress

I have added this option for the lf t55 read and write (with the place holder for the other 2 modes).

e <mode>     - OPTIONAL downlink encoding '0' fixed-bit-length (default), '1' Leading Zero, '2' 1 of 4, '3' Long Zero Reference

I selected option 'e' (for encoding), Happy to review.

Below is my initial testing.

For this example, I have the t55 in leading zero 0 downlink mode.

Actual Data for Block 0 and 1

blk | hex data | binary
----+----------+---------------------------------
0 | 00148050 | 00000000000101001000000001010000
1 | FF836002 | 11111111100000110110000000000010

Attempt to password read (in default mode) - Data will not be correct as the downlink mode is wrong but it will respond with the "EM4105 tag id (or part of) as expected.

proxmark3> lf t55 read b 0 p 51243648 o
blk | hex data | binary
----+----------+---------------------------------
0 | 7FC1B001 | 01111111110000011011000000000001

proxmark3> lf t55 read b 1 p 51243648 o
blk | hex data | binary
----+----------+---------------------------------
1 | 7FC1B001 | 01111111110000011011000000000001

proxmark3> lf t55 read b 0 e 1 p 51243648 o
blk | hex data | binary
----+----------+---------------------------------
0 | 00148050 | 00000000000101001000000001010000

proxmark3> lf t55 read b 1 e 1 p 51243648 o
blk | hex data | binary
----+----------+---------------------------------
1 | FF836002 | 11111111100000110110000000000010

As can be seen the correct data is returned.

Remove the Leading 0/Clear Config Block 3 page 1  (via the leading 0 command)

proxmark3> lf t55 write b 3 1 p 51243648 d 00000000 e 1
Writing page 1  block: 03  data: 0x00000000 pwd: 0x51243648

proxmark3> lf t55 read b 0 p 51243648 o
blk | hex data | binary
----+----------+---------------------------------
0 | 00148050 | 00000000000101001000000001010000

proxmark3> lf t55 read b 1 p 51243648 o
blk | hex data | binary
----+----------+---------------------------------
Safety Check Overriden - proceeding despite risk
1 | FF836002 | 11111111100000110110000000000010

And now the data looks correct without leading 0 options.

For the coders (and comment)
The read was not as smooth as the write.
I needed to extend the AquireData function, to allow the downlink_mode option to be passed in.  So for all calls (that has not been extended to downlink_mode/leading 0), I set the last option to 0 (default), which should mean no change to any of those features.

int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password,uint8_t downlink_mode );

So now, in theory, I should be able to extend to the other calls like the password checking and dump.

In my review, the arg/arg0  is as follows (this seems to be ok, but confirmation would be good)
00000010 - Page
00000100 - Write Test Mode
000xx000 - the new downlink options (00 Default, 01 Leading 0, 10 1 or 4 and 11 long zero reference)

Thanks

Offline

## #8 2019-06-15 07:26:33

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

lf t55 detect seems to work (and a hard coded lf t55 brute also looks good)
e.g.
Default cant find anything, but password protected.

proxmark3> lf t55 detect
Could not detect modulation automatically. Try setting it manually with 'lf t55xx config'

Supply the password, still nothing (as expected)

proxmark3> lf t55 detect p 51243648
Could not detect modulation automatically. Try setting it manually with 'lf t55xx config'

proxmark3> lf t55 detect p 51243648 e 1
Chip Type  : T55x7
Bit Rate   : 5 - RF/64
Inverted   : No
Offset     : 32
Seq. Term. : No
Block0     : 0x00148050

Offline

## #9 2019-06-15 08:50:59

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

Looking at the bruteforce function needed some changes.  So rather then change that I cloned that function to support more arguments.
Note the new function name "bruteforcedl"  for DownLink support.  Again happy to take feedback and comments.

In normal mode no password found as the card is in leading 0 mode.

proxmark3> lf t55 bruteforcedl  i d:\pm3\t55_pwd.txt
chk custom pwd[ 0] 51243648
chk custom pwd[ 1] 000D8787
chk custom pwd[ 2] 88661858
.....
chk custom pwd[77] 65857569
Testing 51243648
Testing 000D8787
Testing 88661858
.....
Testing 65857569
Password NOT found.

proxmark3> lf t55 bruteforcedl e 1 i d:\pm3\t55_pwd.txt
chk custom pwd[ 0] 51243648
chk custom pwd[ 1] 000D8787
chk custom pwd[ 2] 88661858
.....
chk custom pwd[77] 65857569
Testing 51243648
Chip Type  : T55x7
Bit Rate   : 5 - RF/64
Inverted   : No
Offset     : 32
Seq. Term. : No
Block0     : 0x00148050

Found valid password: [51243648]

Offline

## #10 2019-06-16 04:40:34

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

Quick update.
I have got the 1 of 4 downlink protocol roughed in.

Also updated the encoding option (e) index to better match the t5577 tech sheet (so my examples above wont match final result).
i.e. in the options arg/arg0
00000010 - Page
00000100 - Write Test Mode
000xx000 - the new downlink options  : 0 {00} Fixed/Default, 1 {01} long leading reference, 2 {10} leading 0 and  3 {11} 1 of 4.

Last edited by mwalker (2019-06-17 05:41:12)

Offline

## #11 2019-06-16 06:47:45

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

I have updated my fork files.
https://github.com/mwalker33/proxmark3

Changes :
- Update functions to support using different downlink modes.
- Added new function lf t55 bruteforcedl to support downlink modes as well as try each mode

for functions with downlink mode extension.

e <mode>     - OPTIONAL downlink encoding '0' fixed-bit-length (default),
'1' Long Zero Reference,
'3' 1 of 4

Could I get some one to d/l and test to ensure
a) I have updated correctly
b) I have not broken anything and the new features work.

e.g. Below is an example run that would use the new features.

See what sort of card is on the proxmark.

proxmark3> lf search
NOTE: some demods output possible binary
if it finds something that looks like a tag
False Positives ARE possible

Checking for known tags:

EM410x pattern found:

EM TAG ID      : 0D00433C43

Possible de-scramble patterns
Unique TAG ID  : B000C23CC2
HoneyWell IdentKey {
DEZ 8          : 04406339
DEZ 10         : 0004406339
DEZ 5.5        : 00067.15427
DEZ 3.5A       : 013.15427
DEZ 3.5B       : 000.15427
DEZ 3.5C       : 067.15427
DEZ 14/IK2     : 00055838981187
DEZ 15/IK3     : 000755926973634
DEZ 20/ZK      : 11000000120203121202
}
Other          : 15427_067_04406339
Pattern Paxton : 223836739 [0xD577A43]
Pattern 1      : 9065316 [0x8A5364]
Pattern Sebury : 15427 67 4406339  [0x3C43 0x43 0x433C43]

Valid EM410x ID Found!

Now see if its a known t55xx

proxmark3> lf t55 detect
Could not detect modulation automatically. Try setting it manually with 'lf t55xx config'

so Lets use e 4 to try all downlink modes with the password file.

proxmark3> lf t55 bruteforcedl e 4 i d:\pm3\t55_pwd.txt
DL Mode : 0
chk custom pwd[ 0] 51243648
chk custom pwd[ 1] 000D8787
chk custom pwd[ 2] 88661858
chk custom pwd[ 3] 44B44CAE
.....
chk custom pwd[75] 0CB7E7FC
chk custom pwd[77] 65857569
Testing 51243648
Chip Type  : T55x7
Bit Rate   : 5 - RF/64
Inverted   : No
Offset     : 32
Seq. Term. : No
Block0     : 0x00148050

Downlink   : e 2 - Leading Zero Reference

It found the password in leading zero downlink mode, (and also told us to use e 2 - where supported).
Now try again to see if we can detect it.

proxmark3> lf t55 detect e 2
Could not detect modulation automatically. Try setting it manually with 'lf t55xx config'

Did not work as no password supplied, but since we know that, lets try with that

proxmark3> lf t55 detect e 2 p 51243648
Chip Type  : T55x7
Bit Rate   : 5 - RF/64
Inverted   : No
Offset     : 32
Seq. Term. : No
Block0     : 0x00148050

Downlink   : e 2 - Leading Zero Reference

Found it with the detected password and again told us what downlink mode was used.

Offline

## #12 2019-06-16 07:51:59

iceman
Registered: 2013-04-25
Posts: 6,098
Website

Great work!

If you feel the love,  https://www.patreon.com/iceman1001

modhex(hkhehghthbhudcfcdchkigiehgduiehg)

Offline

## #13 2019-06-18 06:33:13

piwi
Contributor
Registered: 2013-06-04
Posts: 698

Looking forward to see your first Pull Request. One question upfront: why do you need a new 'bruteforcedl' command? Wouldn't it be sufficient to add the 'e' option (and the automatic trials) to the existing one?

Offline

## #14 2019-06-18 07:37:58

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

thanks Piwi.

Almost ready, just in cleanup mode.
I had a few back and forth moments with things e.g. bruteforcedl, hence some public discussion prior to submit.

What I tried to do (as a high priority) was not break any existing commands.  So if someone had scripts then they should work 100% as is and only need to change if wanting the new feature.

As such, where an existing command had the nice option extraction, then I could slip in the new option.
But in the case of the bruteforce (and some others), the options don't always use an option id and option value.
The existing code looked at the first byte in the argument
e.g. the Hex of start_pwd, if  'h' show help and exit.  if 'i' take to end of line as the filename else assume its the start_pwd.
so if the start range was exxxxxxx, then an issue.

As such, at this point I had three options.
change my 'e' to not be a hex value : OK should have done that:)
rewrite the call and break something - I don't like breaking things, so not an option
have a new function - easy option.

So, I took the easy way (long weekend).

Now still open to suggestions.
On one hand it would be nice if everything was <command> <opt id> <opt values> <opt id> <opt values>
So if that is the direction we can migrate over time by adding the new, then phasing out the old (giving people a chance to update scripts etc).  this is a project direction statement and may not be an option, so not for me to say, but I can help.

I was also trying to select an option letter that kind of meant something.  d for downlink was good, but taken.

Ok, thought explained... Time for action.

What I will do, is change my 'e' (hex value) to 'r' (for reference i.e. fix length reference, long leading reference, etc)
Then I will update the existing brute force to work as is, plus new feature and remove the new function.

I have a few other ideas, but wanted to get phase 1 completed first.

Any other feed back ?

Offline

## #15 2019-06-18 12:07:51

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

Updated the downlink encoding reference option id from 'e' to 'r' so not to be a valid hex character.
Update the original lf t55 bruteforce to run with or without the reference 'r' otpion (and removed the new function)

example
brute force all passwords from feedbee0 to feedbeff and try ALL 4 downlink encoding options

proxmark3> lf t55 brute r 4 feedbee0 feedbeff
Search password range [FEEDBEE0 -> FEEDBEFF]
................Chip Type  : T55x7
Bit Rate   : 5 - RF/64
Inverted   : No
Offset     : 33
Seq. Term. : No
Block0     : 0x00148050

Downlink   : r 3 - 1 of 4 coding reference

Offline

## #16 2019-06-18 14:00:13

marshmellow
Moderator
From: US
Registered: 2013-06-10
Posts: 2,299

I'm not opposed to redoing the arguments to the newer standard with letter then data.  If there are scripts in the master repo we could update them, if not I wouldn't worry about it.

Offline

## #17 2019-06-20 00:37:19

mwalker
Contributor
Registered: 2019-05-11
Posts: 198

@piwi
Being new to all this, whats the procedure.
I submitted the Pull request, people review (I see your comments), then I respond (and others)
Once we agree on the changes, how do we "re-submit" ?
i.e. I make the changes and test, then upload to my fork.
What do i need to do then ?

thanks

Offline

## #18 2019-06-20 04:41:41

marshmellow
Moderator
From: US
Registered: 2013-06-10
Posts: 2,299