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.
Time changes and with it the technology
Proxmark3 @ discord
Users of this forum, please be aware that information stored on this site is not private.
I would like to introduce a command that uses 4 parameters.
they are all integers.
could i modify the declaration of UsbCommand (now it uses 3 parameters) as it follows:
(the question is: It is ok, or there is a best way to do it?)
Part of the file "include/usb_cmd.h"
#define USB_CMD_DATA_SIZE 512
typedef struct {
uint64_t cmd;
uint64_t arg[4];
union {
uint8_t asBytes[USB_CMD_DATA_SIZE];
uint32_t asDwords[USB_CMD_DATA_SIZE/4];
} d;
} PACKED UsbCommand;
Last edited by gaucho (2014-04-24 19:41:52)
Offline
You would need to change all commands to cope with the additional parameter. Why don't you use the existing asBytes[USB_CMD_DATA_SIZE] to transfer your additional parameter?
Offline
This week I don't have the pm3 board with me.
so i'm proceeding with the Theoretical way programming.
(i'm just kidding for now)
I'm not sure how to assign my int to the asBytes array.
could i use the asDwords array?
this is the declaration that i found:
#define USB_CMD_DATA_SIZE 512
typedef struct {
uint64_t cmd;
uint64_t arg[3];
union {
uint8_t asBytes[USB_CMD_DATA_SIZE];
uint32_t asDwords[USB_CMD_DATA_SIZE/4];
} d;
} PACKED UsbCommand;
Will it work using then the UsbCommand this way?:
int CmdHFsnoop(const char *Cmd)
{
//do something
//for now i could start printing out a string
PrintAndLog("# Preparing data..");
//get these parameters from Cmd:
//-snoop frequency
//-trigger level
//-samples to skip(delay) from trigger
//-number of trigger to skip
//Note: the used memory is all the memory available, it is not a parameter
int samplingFrequency, triggerLevel, samplesToSkip, triggersToSkip;
char * pEnd;
samplingFrequency =(int)strtol (Cmd,&pEnd,10);
triggerLevel = (int)strtol (pEnd,&pEnd,10);
samplesToSkip = (int)strtol (pEnd,&pEnd,10);
triggersToSkip = (int)strtol (pEnd,NULL,10);
PrintAndLog("# Sampling Frequency: %dHz",samplingFrequency);
PrintAndLog("# Trigger Level: %d",triggerLevel);
PrintAndLog("# Samples to Skip: %d",samplesToSkip);
PrintAndLog("# Triggers to Skip: %d",triggersToSkip);
UsbCommand c={CMD_HF_SNOOP};
c.d.asDwords[0]=samplingFrequency;
c.d.asDwords[1]=triggerLevel;
c.d.asDwords[2]=samplesToSkip ;
c.d.asDwords[3]=triggersToSkip ;SendCommand(&c);
PrintAndLog("# Snoop command sent..");
return 0;
}
What do you think?
infact:
- samplingFrequency goes from 1Hz to 13000000Hz
- triggerLevel goes from -128 to + 128
-samplesToSkip and triggersToSkip can go from 0 to 2000000000
Last edited by gaucho (2014-04-25 16:26:54)
Offline
The usual way is to use memcpy to add data, e.g. in cmdhfmf.c:
UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
memcpy(c.d.asBytes, key, 6);
memcpy(c.d.asBytes + 10, bldata, 16);
SendCommand(&c);
and there are reasons for it. This allows to add arbitrary data with different lengths and pack it to d.asBytes without running into problems with alignment. Be aware that different compilers on different OS might have different ideas on how long a long int would be and how it should be aligned in memory. The ARM on the receiving side has no idea on both length of host types and their alignment. When communicating between host and ARM it is therefore better to
a) not use int, long, long long, etc. but instead use the types uint16_t (always 2 bytes), uint32_t (always 4 Bytes), etc.
b) use memcpy to avoid alignment to 2, 4 or 8 Byte boundaries.
Offline
could you please read again my previous message?
i modified it.
thank you.
Offline
piwi could you please read again my message? could i use that way the asDwords array?
Last edited by gaucho (2014-04-25 16:25:27)
Offline
A side note first: it is not a good idea to completely rephrase a question after it has been answered. It will be hard for others to follow the thread.
Please have a look at other functions how to extract parameters from Cmd.
Otherwise I stick to my recommendation. You can't be sure that an int is 4 bytes.
Offline
yes but asDwords is an array of uint32, so each int (even if a int is not composed by 4 bytes)parameter is casted to a uint32 in my previous post. i didn't found a matching example on other commands. for sure i didn't looked well at the code. just asking if it is writable that way. it seems to me more readable than a specular memcopy on both client and arm.
ps:sorry for post editing. after sent i realized it was a wrong approach.
Last edited by gaucho (2014-04-25 23:54:11)
Offline
..Otherwise I stick to my recommendation. You can't be sure that an int is 4 bytes.
inside cmdlf.c i found the following code. Considering that i already told you that i'm planning to cast int to uint_32(elements of asDwords array), do you think that the following code is wrong since it uses unsigned int for uid? I think that my implementation is correct like the following code. Am I wrong?
int CmdIndalaClone(const char *Cmd)
{
unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7;
UsbCommand c;
uid1=0;
uid2=0;
uid3=0;
uid4=0;
uid5=0;
uid6=0;
uid7=0;
int n = 0, i = 0;
if (strchr(Cmd,'l') != 0) {
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
uid1 = (uid1 << 4) | (uid2 >> 28);
uid2 = (uid2 << 4) | (uid3 >> 28);
uid3 = (uid3 << 4) | (uid4 >> 28);
uid4 = (uid4 << 4) | (uid5 >> 28);
uid5 = (uid5 << 4) | (uid6 >> 28);
uid6 = (uid6 << 4) | (uid7 >> 28);
uid7 = (uid7 << 4) | (n & 0xf);
}
PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7);
c.cmd = CMD_INDALA_CLONE_TAG_L;
c.d.asDwords[0] = uid1;
c.d.asDwords[1] = uid2;
c.d.asDwords[2] = uid3;
c.d.asDwords[3] = uid4;
c.d.asDwords[4] = uid5;
c.d.asDwords[5] = uid6;
c.d.asDwords[6] = uid7;
.......
.....
Offline
It wasn't my intention to start an academic discussion, but here we go:
By C99 defiinition, an unsigned int is guaranteed to be able to store integers from 0 to 65535. It can be more, and on today's machines it usually will be more.
This code assumes that an unsigned int is 4 Bytes wide. This assumption would hold on nearly all CPUs and compilers today.
Does it work? Yes, on most machines.
Is it correct? No.
Offline