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.
Hi folks,
I've modified the USB driver and the Windows client to support multiple Proxmark3 devices. The client will 1st list all the connected Proxmarks and their associated serial numbers (I added that to the USB driver). The user then can pick a device from the list to connect to.
So, I simply assign a serial number to each of the units, reflash, and that's it. This affects the 20090905 (r216) release.
If you've any suggestions on that, please let me know.
Best.
Offline
Sounds useful! Please post the patch so we can check it out...
Offline
Oh, I thought I'd post it with my previous post, lol! Here goes.
Index: common/usb.c
===================================================================
--- common/usb.c (revision 216)
+++ common/usb.c (working copy)
@@ -90,7 +90,12 @@
0x01,0x00, // Device release number (0001)
0x01, // Manufacturer string descriptor index
0x02, // Product string descriptor index
- 0x00, // Serial Number string descriptor index (None)
+ //0x00, // Serial Number string descriptor index (None)
+ 0x03, // Serial Number string descriptor index
0x01, // Number of possible configurations (1)
};
@@ -196,10 +201,26 @@
't', 0x00,
};
+static const BYTE StringDescriptor3[] = {
+ 14, // Length
+ 0x03, // Type is string
+ 'P', 0x00,
+ 'r', 0x00,
+ 'o', 0x00,
+ 'x', 0x00,
+ '-', 0x00,
+ '5', 0x00,
+};
+
static const BYTE * const StringDescriptors[] = {
StringDescriptor0,
StringDescriptor1,
StringDescriptor2,
+ StringDescriptor3,
};
Index: winsrc/prox.cpp
===================================================================
--- winsrc/prox.cpp (revision 216)
+++ winsrc/prox.cpp (working copy)
@@ -15,8 +15,17 @@
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
int offline = 0;
-HANDLE UsbHandle;
+HANDLE UsbHandle = NULL;
+HMODULE HidHandle = NULL;
+
+typedef struct _UsbUnit {
+ HANDLE UsbHandle;
+ wchar_t SerialNumber[512];
+} UsbUnit;
+
static void ShowError(void)
{
char buf[1024];
@@ -32,16 +41,29 @@
typedef BOOLEAN (__stdcall *GetPreparsedProc)(HANDLE,
PHIDP_PREPARSED_DATA *);
typedef NTSTATUS (__stdcall *GetCapsProc)(PHIDP_PREPARSED_DATA, PHIDP_CAPS);
+ typedef BOOLEAN (__stdcall *GetSerialNumber)(IN HANDLE, OUT PVOID, IN ULONG);
+
GetGuidProc getGuid;
GetAttrProc getAttr;
GetPreparsedProc getPreparsed;
GetCapsProc getCaps;
+ GetSerialNumber getSerialNumber;
- HMODULE h = LoadLibrary("hid.dll");
- getGuid = (GetGuidProc)GetProcAddress(h, "HidD_GetHidGuid");
- getAttr = (GetAttrProc)GetProcAddress(h, "HidD_GetAttributes");
- getPreparsed = (GetPreparsedProc)GetProcAddress(h, "HidD_GetPreparsedData");
- getCaps = (GetCapsProc)GetProcAddress(h, "HidP_GetCaps");
+ //HMODULE h = LoadLibrary("hid.dll");
+ HidHandle = LoadLibrary("hid.dll");
+ getGuid = (GetGuidProc)GetProcAddress(HidHandle, "HidD_GetHidGuid");
+ getAttr = (GetAttrProc)GetProcAddress(HidHandle, "HidD_GetAttributes");
+ getPreparsed = (GetPreparsedProc)GetProcAddress(HidHandle, "HidD_GetPreparsedData");
+ getCaps = (GetCapsProc)GetProcAddress(HidHandle, "HidP_GetCaps");
+ getSerialNumber = (GetSerialNumber)GetProcAddress(HidHandle, "HidD_GetSerialNumberString");
GUID hidGuid;
getGuid(&hidGuid);
@@ -53,6 +75,11 @@
SP_DEVICE_INTERFACE_DATA devInfoData;
devInfoData.cbSize = sizeof(devInfoData);
+ UsbUnit units[50];
+ int nIndex = 0;
+
int i;
for(i = 0;; i++) {
if(!SetupDiEnumDeviceInterfaces(devInfo, 0, &hidGuid, i, &devInfoData))
@@ -62,7 +89,8 @@
}
// printf("done list\n");
SetupDiDestroyDeviceInfoList(devInfo);
- return FALSE;
+ /// return FALSE;
+ break;
}
// printf("item %d:\n", i);
@@ -84,12 +112,18 @@
if(!SetupDiGetDeviceInterfaceDetail(devInfo, &devInfoData,
devInfoDetailData, 87, NULL, NULL))
{
+ free(devInfoDetailData);
// printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
continue;
}
+
+ //char *path = devInfoDetailData->DevicePath;
+ char path[2048];
+ strcpy(path, devInfoDetailData->DevicePath);
+ free(devInfoDetailData);
- char *path = devInfoDetailData->DevicePath;
-
UsbHandle = CreateFile(path, /*GENERIC_READ |*/ GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
@@ -114,36 +148,71 @@
CloseHandle(UsbHandle);
// printf(" nope, not us\n");
continue;
- }
+ } else {
+ // printf ("got it!\n");
+ CloseHandle(UsbHandle);
+
+ UsbHandle = CreateFile(path, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED, NULL);
+
+ if(UsbHandle == INVALID_HANDLE_VALUE) {
+ ShowError();
+ // printf("Error, couldn't open our own handle as desired.\n");
+ ///return FALSE;
+ continue;
+ }
+
+ PHIDP_PREPARSED_DATA pp;
+ getPreparsed(UsbHandle, &pp);
+ HIDP_CAPS caps;
+
+ if(getCaps(pp, &caps) != HIDP_STATUS_SUCCESS) {
+ // printf("getcaps failed\n");
+ ///return FALSE;
+ continue;
+ }
+
+ // printf("input/out report %d/%d\n", caps.InputReportByteLength,
+ // caps.OutputReportByteLength);
+
+ UsbUnit unit = {UsbHandle, {0}};
+ getSerialNumber(UsbHandle, unit.SerialNumber, 1024);
+ units[nIndex++] = unit;
+
+ printf("HNDL: %08x VID: %04x PID: %04x SN: ", unit.UsbHandle, attr.VendorID, attr.ProductID);
+ wprintf(L"%s\n", unit.SerialNumber);
+ }
+
+/// return TRUE;
+ }
-// printf ("got it!\n");
- CloseHandle(UsbHandle);
-
- UsbHandle = CreateFile(path, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED, NULL);
-
- if(UsbHandle == INVALID_HANDLE_VALUE) {
- ShowError();
-// printf("Error, couldn't open our own handle as desired.\n");
- return FALSE;
- }
-
- PHIDP_PREPARSED_DATA pp;
- getPreparsed(UsbHandle, &pp);
- HIDP_CAPS caps;
-
- if(getCaps(pp, &caps) != HIDP_STATUS_SUCCESS) {
-// printf("getcaps failed\n");
- return FALSE;
- }
-
-// printf("input/out report %d/%d\n", caps.InputReportByteLength,
-// caps.OutputReportByteLength);
-
-
- return TRUE;
- }
+ if (nIndex > 0) {
+ printf("Connected Proxmark units:\n");
+ for (i=0; i < nIndex; i++) {
+ wprintf(L"\t%d. SN: %s\n", i+1, units[i].SerialNumber);
+ }
+
+ int selection = 0;
+ while (selection < 1 || selection > nIndex) {
+ printf("Which unit do you want to connect to? ");
+ scanf("%d", &selection);
+ }
+ selection --;
+
+ wprintf(L"\nUnit no. %d (%s) selected.\n", selection+1, units[selection].SerialNumber);
+
+ UsbHandle = units[selection].UsbHandle;
+ for (i=0; i < nIndex; i++) {
+ if (i == selection) continue;
+ CloseHandle(units[i].UsbHandle);
+ }
+
+ return TRUE;
+ }
return FALSE;
}
@@ -497,8 +566,22 @@
return 1;
}
+static void clean_up(void) {
+ if (UsbHandle != NULL)
+ CloseHandle(UsbHandle);
+
+ if (HidHandle != NULL)
+ FreeLibrary(HidHandle);
+}
+
int main(int argc, char **argv)
{
+ atexit(clean_up);
+
int i = 0;
if(argc < 2) {
Offline
Thanks, but that patch is against a version that is about 200 revisions behind where we are now! Most of that code doesn't even exist any more...
I still think it's a great idea, but it needs to be done against current code.
Offline
Okay. I just didn't want to tamper with unstable releases you know. But today, I checked out the latest revision, and OMG. Those are some real NICE changes guys! I really like it! Keep up the good work...
So..follows a new patch for the latest revision :-).
Index: client/proxusb.c
===================================================================
--- client/proxusb.c (revision 441)
+++ client/proxusb.c (working copy)
@@ -113,6 +113,8 @@
{
struct usb_bus *busses, *bus;
usb_dev_handle *handle = NULL;
+ struct prox_unit units[50];
+ int iUnit = 0;
usb_find_busses();
usb_find_devices();
@@ -129,14 +131,42 @@
handle = usb_open(dev);
if (!handle) {
if (verbose)
- fprintf(stderr, "open failed: %s!\n", usb_strerror());
- return NULL;
+ fprintf(stderr, "open fabiled: %s!\n", usb_strerror());
+ //return NULL;
+ continue;
}
*iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
- return handle;
+
+ struct prox_unit unit = {handle, {0}};
+ usb_get_string_simple(handle, desc->iSerialNumber, unit.serial_number, sizeof(unit.serial_number));
+ units[iUnit++] = unit;
+
+ //return handle;
}
+ }
+ }
+ if (iUnit > 0) {
+ int iSelection = 0;
+
+ fprintf(stdout, "\nConnected units:\n");
+
+ for (int i = 0; i < iUnit; i++)
+ fprintf(stdout, "\t%d. SN: %s\n", i+1, units[i].serial_number);
+
+ while (iSelection < 1 || iSelection > iUnit) {
+ fprintf(stdout, "Which unit do you want to connect to? ");
+ fscanf(stdin, "%d", &iSelection);
}
+ iSelection --;
+
+ for (int i = 0; i < iUnit; i++) {
+ if (iSelection == i) continue;
+ usb_close(units[i].handle);
+ units[i].handle = NULL;
+ }
+
+ return units[iSelection].handle;
}
return NULL;
Index: client/proxusb.h
===================================================================
--- client/proxusb.h (revision 441)
+++ client/proxusb.h (working copy)
@@ -26,4 +26,9 @@
struct usb_dev_handle* OpenProxmark(int verbose);
void CloseProxmark(void);
+struct prox_unit {
+ usb_dev_handle *handle;
+ char serial_number[256];
+};
+
#endif
Index: common/usb.c
===================================================================
--- common/usb.c (revision 441)
+++ common/usb.c (working copy)
@@ -95,7 +95,7 @@
0x01,0x00, // Device release number (0001)
0x01, // Manufacturer string descriptor index
0x02, // Product string descriptor index
- 0x00, // Serial Number string descriptor index (None)
+ 0x03, // Serial Number string descriptor index
0x01, // Number of possible configurations (1)
};
@@ -201,10 +201,24 @@
't', 0x00,
};
+// Serial Number
+// TODO: Pick yours! Don't forget to modify the length, if needed.
+static const uint8_t StringDescriptor3[] = {
+ 14, // Length
+ 0x03, // Type is string
+ 'P', 0x00,
+ 'r', 0x00,
+ 'o', 0x00,
+ 'x', 0x00,
+ '-', 0x00,
+ '5', 0x00,
+};
+
static const uint8_t * const StringDescriptors[] = {
StringDescriptor0,
StringDescriptor1,
StringDescriptor2,
+ StringDescriptor3,
};
Best.
Offline
Nice! Thanks!!!
I've committed rev 442 which implements this patch with a minor change that it only applies if there is more than one device (and I've also tweaked to 'Serial No.' to give a hint as to what it's there for!
Offline