📄 usbkeyemu.c
字号:
configInfo.interfaceDesc.bAlternateSetting=0;
configInfo.interfaceDesc.bNumEndpoints=0;
configInfo.interfaceDesc.bInterfaceClass=USB_DEVICE_CLASS_VENDOR_SPECIFIC;
configInfo.interfaceDesc.bInterfaceSubClass=0;
configInfo.interfaceDesc.bInterfaceProtocol=0;
configInfo.interfaceDesc.iInterface=0;
urb->UrbControlVendorClassRequest.TransferBufferLength=
min(urb->UrbControlVendorClassRequest.TransferBufferLength, sizeof(configInfo.configDesc)+sizeof(configInfo.interfaceDesc));
RtlCopyMemory(urb->UrbControlVendorClassRequest.TransferBuffer,
&configInfo,
urb->UrbControlVendorClassRequest.TransferBufferLength
);
status = STATUS_SUCCESS;
URB_STATUS(urb) = USBD_STATUS_SUCCESS;
}
break;
}
break;
//
// Select configurations of USB device
//
case URB_FUNCTION_SELECT_CONFIGURATION: {
typedef struct _URB_SELECT_CONFIGURATION *PURB_SELECT_CONFIGURATION;
PURB_SELECT_CONFIGURATION selectConfig;
selectConfig=(PURB_SELECT_CONFIGURATION)urb;
selectConfig->Interface.InterfaceNumber=0;
selectConfig->Interface.AlternateSetting=0;
selectConfig->Interface.Class=USB_DEVICE_CLASS_VENDOR_SPECIFIC;
selectConfig->Interface.SubClass=0;
selectConfig->Interface.Protocol=0;
status = STATUS_SUCCESS;
URB_STATUS(urb) = USBD_STATUS_SUCCESS;
}
break;
//
// IO request to USB hardware
//
case URB_FUNCTION_VENDOR_DEVICE: {
// Emulate request to key
EmulateKey(
&pdoData->keyData,
(PKEY_REQUEST)&urb->UrbControlVendorClassRequest.Request,
&urb->UrbControlVendorClassRequest.TransferBufferLength,
(PKEY_RESPONSE)urb->UrbControlVendorClassRequest.TransferBuffer
);
// I/o with key is succeful
status = STATUS_SUCCESS;
URB_STATUS(urb) = USBD_STATUS_SUCCESS;
} break;
}
#ifdef DEBUG_FULL
//
// Print request result
//
if (urb->UrbHeader.Function==URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE || urb->UrbHeader.Function==URB_FUNCTION_VENDOR_DEVICE) {
PrintBufferContent(str1,
urb->UrbControlVendorClassRequest.TransferBuffer,
urb->UrbControlVendorClassRequest.TransferBufferLength);
LogMessage ("Bus_HandleUSBIoCtl(): out\n"
"\tTransfer buffer length: %X\n"
"\tTransfer buffer contents: %ws\n"
"\tStatus: %X\n",
urb->UrbControlVendorClassRequest.TransferBufferLength,
str1,
URB_STATUS(urb)
);
} else
LogMessage ("Bus_HandleUSBIoCtl(): out\n"
"\tStatus: %X\n",
URB_STATUS(urb)
);
ExFreePool(str2);
ExFreePool(str1);
#endif
}
break;
default:
break; // default status is STATUS_INVALID_PARAMETER
}
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
static WCHAR DUMP_PATH[] = DUMP_PATH_STR;
NTSTATUS
Bus_LoadDumpsFromRegistry(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine enum dumps of HASP keys in registry and load it
Arguments:
DeviceObject A device object in the stack in which we attach HASP keys
Return Value:
NTSTATUS
--*/
{
//
// Search for HASP key dumps in registry
// and attach it as USB devices
//
NTSTATUS status;
HANDLE hkey;
ULONG keysAttached;
WCHAR path[128];
UNICODE_STRING usPath;
OBJECT_ATTRIBUTES oa;
PFDO_DEVICE_DATA fdoData;
PAGED_CODE();
fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
Bus_IncIoCount (fdoData);
keysAttached=0;
RtlInitUnicodeString(&usPath, DUMP_PATH);
InitializeObjectAttributes(&oa, &usPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
//
// Enum keys in registry and attach it
//
status = ZwOpenKey(&hkey, KEY_READ, &oa);
if (NT_SUCCESS(status)) {
ULONG size, i;
PKEY_FULL_INFORMATION fip;
ZwQueryKey(hkey, KeyFullInformation, NULL, 0, &size);
size = min(size, PAGE_SIZE);
fip = (PKEY_FULL_INFORMATION) ExAllocatePool(PagedPool, size);
ZwQueryKey(hkey, KeyFullInformation, fip, size, &size);
for (i = 0; i < fip->SubKeys; ++i) {
ULONG curChar, password, isPasswordValid;
PKEY_BASIC_INFORMATION bip;
ZwEnumerateKey(hkey, i, KeyBasicInformation, NULL, 0, &size);
size = min(size, PAGE_SIZE);
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, size);
ZwEnumerateKey(hkey, i, KeyBasicInformation, bip, size, &size);
// Convert key name into password
password=0; isPasswordValid=1;
for (curChar=0; curChar<bip->NameLength/2; curChar++) {
if (bip->Name[curChar]>=L'0' && bip->Name[curChar]<=L'9')
password=(password << 4) + (bip->Name[curChar] - L'0');
else
if (bip->Name[curChar]>=L'A' && bip->Name[curChar]<=L'F')
password=(password << 4) + (bip->Name[curChar] - L'A') + 10;
else
if (bip->Name[curChar]>=L'a' && bip->Name[curChar]<=L'f')
password=(password << 4) + (bip->Name[curChar] - L'a') + 10;
else {
isPasswordValid=0;
break;
}
}
if (isPasswordValid && INSERT_ALL_KEYS_ON_STARTUP) {
UCHAR buf[sizeof(VUSB_PLUGIN_HARDWARE)+BUS_HARDWARE_IDS_LENGTH];
PVUSB_PLUGIN_HARDWARE pOneKeyInfo;
NTSTATUS status;
LogMessage("Found key %08X\n", password);
pOneKeyInfo=(PVUSB_PLUGIN_HARDWARE)buf;
pOneKeyInfo->Size=sizeof(VUSB_PLUGIN_HARDWARE);
pOneKeyInfo->SerialNo=++keysAttached;
pOneKeyInfo->Password=password;
RtlCopyMemory(pOneKeyInfo->HardwareIDs, BUS_HARDWARE_IDS, BUS_HARDWARE_IDS_LENGTH);
status=Bus_PlugInDevice(pOneKeyInfo, sizeof(VUSB_PLUGIN_HARDWARE)+BUS_HARDWARE_IDS_LENGTH, fdoData);
if (!NT_SUCCESS (status))
keysAttached--;
} else
LogMessage("Found bad key\n");
ExFreePool(bip);
}
ExFreePool(fip);
ZwClose(hkey);
Bus_DecIoCount (fdoData);
//if (keysAttached>0)
// IoInvalidateDeviceRelations (FdoData->UnderlyingPDO, BusRelations);
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
NTSTATUS
GetRegKeyData(
HANDLE hkey,
PWCHAR subKey,
VOID *data,
ULONG needSize)
/*++
Routine Description:
This routine read data from registry key
Arguments:
hkey Ptr to registry key
subKey Name of subkey
data Ptr to buffer, in which we read information
needSize Size of buffer
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
ULONG size;
UNICODE_STRING valname;
PKEY_VALUE_PARTIAL_INFORMATION vpip;
RtlInitUnicodeString(&valname, subKey);
size=0;
status = ZwQueryValueKey(hkey, &valname, KeyValuePartialInformation, NULL, 0, &size);
if (status == STATUS_OBJECT_NAME_NOT_FOUND && size < needSize && size<=PAGE_SIZE)
return STATUS_INVALID_PARAMETER;
vpip = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(PagedPool, size);
if (!vpip)
return STATUS_INSUFFICIENT_RESOURCES;
status = ZwQueryValueKey(hkey, &valname, KeyValuePartialInformation,
vpip, size, &size);
if (!NT_SUCCESS(status))
return STATUS_INVALID_PARAMETER;
RtlCopyMemory(data, vpip->Data, needSize);
ExFreePool(vpip);
return STATUS_SUCCESS;
}
//
// HASP secret table generator vectors, it used to create ST for old HASP keys
//
static UCHAR HASP_rows[8][8]={
{0,0,0,0,0,0,0,0},
{0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0},
{0,0,1,1,0,0,1,1},
{1,1,0,0,1,1,0,0},
{0,0,0,0,1,1,1,1},
{1,1,1,1,0,0,0,0},
{1,1,1,1,1,1,1,1}
};
NTSTATUS
Bus_LoadDumpFromRegistry(
ULONG password,
PKEYDATA keyData)
/*++
Routine Description:
This routine read dump of one HASP key from registry
Arguments:
password Password of key
keyData Ptr to structure with key data
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
HANDLE hkey;
WCHAR path[128];
UNICODE_STRING usPath;
OBJECT_ATTRIBUTES oa;
RtlZeroMemory(keyData, sizeof(keyData));
//
// Try to read data about key from registry
//
swprintf(path, L"%ws\\%08X", DUMP_PATH, password);
RtlInitUnicodeString(&usPath, path);
InitializeObjectAttributes(&oa, &usPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenKey(&hkey, KEY_READ, &oa);
if (NT_SUCCESS(status)) {
NTSTATUS readStatus, hasOption, hasSecTable; readStatus=STATUS_SUCCESS;
keyData->password=(password >> 16) | (password << 16); // Password stored in shuffled form
readStatus+=GetRegKeyData(hkey, L"Type", &keyData->keyType, sizeof(keyData->keyType));
readStatus+=GetRegKeyData(hkey, L"Memory", &keyData->memoryType, sizeof(keyData->memoryType));
readStatus+=GetRegKeyData(hkey, L"SN", &keyData->netMemory[0], sizeof(ULONG));
readStatus+=GetRegKeyData(hkey, L"Data", keyData->memory, min(GetMemorySize(keyData), sizeof(keyData->memory)));
if (NT_SUCCESS(readStatus)) {
hasOption=GetRegKeyData(hkey, L"Option", keyData->options, sizeof(keyData->options));
hasSecTable=GetRegKeyData(hkey, L"SecTable", keyData->secTable, sizeof(keyData->secTable));
if (!(NT_SUCCESS(hasOption) && NT_SUCCESS(hasSecTable) && keyData->options[0]==1) ||
!(!NT_SUCCESS(hasOption) && NT_SUCCESS(hasSecTable))) {
// Universal ST case
ULONG password=keyData->password, i, j;
UCHAR alBuf[8];
LogMessage("Revert to universal ST\n");
password^=0x09071966;
for (i=0; i<8; i++) {
alBuf[i]= (UCHAR)(password & 7);
password = password >> 3;
}
RtlZeroMemory(keyData->secTable, sizeof(keyData->secTable));
for(i=0; i<8; i++)
for(j=0; j<8; j++)
keyData->secTable[j]|=HASP_rows[alBuf[i]][j] << (7 - i);
}
if (GetRegKeyData(hkey, L"NetMemory", &keyData->netMemory[4], sizeof(keyData->netMemory)-sizeof(ULONG))!=STATUS_SUCCESS) {
RtlFillMemory(&keyData->netMemory[4], sizeof(keyData->netMemory)-sizeof(ULONG), 0xFF);
if (keyData->memoryType==4) {
// Unlimited Net key
keyData->netMemory[6+4]=0xFF;
keyData->netMemory[7+4]=0xFF;
keyData->netMemory[10+4]=0xFE;
} else {
// Local key
keyData->netMemory[6+4]=0;
keyData->netMemory[7+4]=0;
keyData->netMemory[10+4]=0;
}
}
GetRegKeyData(hkey, L"EDStruct", keyData->edStruct, sizeof(keyData->edStruct));
}
ZwClose(hkey);
if (!NT_SUCCESS(readStatus))
return STATUS_INVALID_PARAMETER;
} else
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -