📄 usbkeyemu.c
字号:
/*++
Copyright (c) 2004 Chingachguk & Denger2k All Rights Reserved
Module Name:
USBKeyEmu.c
Abstract:
This module contains routines for emulation of USB bus and USB HASP key.
Environment:
kernel mode only
Revision History:
--*/
#include <stdarg.h>
#include <ntddk.h>
#include <usb.h>
#include <usbdrivr.h>
#include <stdio.h>
#include ".\Include\driver.h"
#include "vusb.h"
#include "EncDecSim.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, Bus_HandleUSBIoCtl)
#pragma alloc_text (PAGE, EmulateKey)
#pragma alloc_text (PAGE, _Chiper)
#pragma alloc_text (PAGE, Chiper)
#pragma alloc_text (PAGE, GetMemorySize)
#pragma alloc_text (PAGE, Bus_LoadDumpsFromRegistry)
#pragma alloc_text (PAGE, Bus_LoadDumpFromRegistry)
#endif
void _Chiper(VOID *bufPtr, ULONG bufSize, PUSHORT key1Ptr, PUSHORT key2Ptr) {
/*++
Routine Description:
Encode/decode response/request to key
Arguments:
bufPtr - pointer to a encoded/decoded data
bufSize - size of encoded information
key1Ptr, key2Ptr - ptr to chiper keys
Return Value:
none
--*/
if (bufSize) {
__asm {
pusha
mov esi, [key1Ptr]
mov edi, [key2Ptr]
loc_12C6A:
xor dl, dl
mov ebx, 4
loc_12C71:
mov cx, [esi]
add dl, dl
test cl, 1
jz loc_12C96
mov ax, [edi]
or dl, 1
xor ax, cx
mov [esi], ax
shr ax, 1
mov [esi], ax
or ah, 80h
mov [esi], ax
jmp loc_12C9D
loc_12C96:
shr cx, 1
mov [esi], cx
loc_12C9D:
add dl, dl
test byte ptr [esi], 80h
jz loc_12CA7
or dl, 1
loc_12CA7:
dec ebx
jnz loc_12C71
mov eax, [bufPtr]
inc [bufPtr]
xor [eax], dl
dec [bufSize]
jnz loc_12C6A
popa
}
}
}
void Chiper(VOID *buf, ULONG size, PKEYDATA pKeyData) {
/*++
Routine Description:
Encode/decode response/request to key (stub only)
Arguments:
bufPtr - pointer to a encoded/decoded data
bufSize - size of encoded information
pKeyData - ptr to key data
Return Value:
none
--*/
LogMessage ("Chiper inChiperKey1=%08X, inChiperKey2=%08X, length=%X\n",
pKeyData->chiperKey1, pKeyData->chiperKey2, size);
_Chiper(buf, size, &pKeyData->chiperKey1, &pKeyData->chiperKey2);
LogMessage ("Chiper outChiperKey1=%08X, outChiperKey2=%08X\n",
pKeyData->chiperKey1, pKeyData->chiperKey2);
}
// Disable warn 'function changes ebp register'
#pragma warning(disable:4731)
ULONG CheckEncodedStatus(UCHAR AdjustedReqCode, UCHAR SetupKeysResult, UCHAR *BufPtr) {
/*++
Routine Description:
Check encoded status (byte after status) for validity
Arguments:
AdjustedReqCode - pointer to ((requested fn code) & 7E)
SetupKeysResult - data[0] response of key to 0x80 function
BufPtr - ptr to status byte
Return Value:
bool, 1 - encoded status ok, 0 - wrong encoded status
--*/
ULONG loopCnt;
__asm {
push ebx
push edx
push ecx
push esi
cmp [AdjustedReqCode], 0
jz loc_12D33
cmp [SetupKeysResult], 2
jb loc_12D33
mov esi, [BufPtr]
mov cl, [esi]
cmp cl, 1Fh
jbe loc_12D06
xor eax, eax
jmp loc_CheckEncodedStatus_exit
loc_12D06:
mov byte ptr [loopCnt], 0Fh
lea eax, [loopCnt]
push eax
push ecx
call sub_12D50
lea eax, [loopCnt]
mov cl, [esi+1]
push eax
push ecx
call sub_12D50
mov al, byte ptr [loopCnt]
and al, 0Fh
cmp al, 1
sbb eax, eax
neg eax
jmp loc_CheckEncodedStatus_exit
loc_12D33:
mov al, 0Fh
mov esi, [BufPtr]
cmp al, [esi]
sbb eax, eax
inc eax
jmp loc_CheckEncodedStatus_exit
sub_12D50:
push ebp
mov ecx, 7
mov ebp, esp
push ebx
push esi
mov al, [ebp+8]
mov esi, [ebp+0Ch]
loc_12D60:
mov dl, al
mov bl, [esi]
shr dl, cl
and dl, 1
add bl, bl
or dl, bl
test dl, 10h
mov [esi], dl
jz loc_12D79
xor dl, 0Dh
mov [esi], dl
loc_12D79:
and byte ptr [esi], 0Fh
dec ecx
jns loc_12D60
pop esi
pop ebx
pop ebp
retn 8
loc_CheckEncodedStatus_exit:
pop esi
pop ecx
pop edx
pop ebx
}
}
#pragma warning(default:4731)
LONG GetMemorySize(PKEYDATA pKeyData) {
/*++
Routine Description:
Compute memory size of key in bytes
Arguments:
pKeyData - ptr to key data
Return Value:
memory size of key in bytes
--*/
if (pKeyData->memoryType==4)
return 512-16;
return 128-16;
}
void EmulateKey(PKEYDATA pKeyData, PKEY_REQUEST request, PULONG outBufLen, PKEY_RESPONSE outBuf) {
/*++
Routine Description:
Emulation of key main procedure (IOCTL_INTERNAL_USB_SUBMIT_URB handler)
Arguments:
pKeyData - ptr to key data
request - ptr to request buffer
outBufLen - ptr to out buffer size variable
outBuf - ptr to out buffer
Return Value:
none
--*/
UCHAR encodeOutData, status, encodedStatus;
ULONG outDataLen;
KEY_RESPONSE keyResponse;
LARGE_INTEGER time;
//
// Get time data, it used as random number source
//
KeQueryTickCount(&time);
//
// Setup answer
//
LogMessage ("Setup answer\n");
RtlZeroMemory(&keyResponse, sizeof(keyResponse));
keyResponse.status=KEY_OPERATION_STATUS_ERROR;
outDataLen=0; encodeOutData=0;
//
// Analyse fn number
//
LogMessage ("Analyse fn number\n");
switch (request->majorFnCode) {
case KEY_FN_SET_CHIPER_KEYS:
LogMessage ("KEY_FN_SET_CHIPER_KEYS\n");
pKeyData->chiperKey1=request->param1;
pKeyData->chiperKey2=0xA0CB;
// Setup random encoded status begin value
pKeyData->encodedStatus=(UCHAR)pKeyData;
pKeyData->isInitDone=1;
// Make key response
keyResponse.status=KEY_OPERATION_STATUS_OK;
keyResponse.data[0]=0x02;
keyResponse.data[1]=0x0A;
keyResponse.data[2]=0x00;
// Bytes 3, 4 - key sn, set it to low word of ptr to key data
keyResponse.data[3]=(UCHAR)(((USHORT)pKeyData) & 0xFF);
keyResponse.data[4]=(UCHAR)((((USHORT)pKeyData) >> 8) & 0xFF);
outDataLen=5;
encodeOutData=1;
break;
case KEY_FN_CHECK_PASS:
// Decode pass
Chiper(&request->param1, 4, pKeyData);
// Show request
LogMessage ("KEY_FN_CHECK_PASS pass=%08X, pKeyData->password=%08X, pKeyData->isInitDone=%X\n",
*((PULONG)&request->param1), pKeyData->password, pKeyData->isInitDone);
// Compare pass
if (*((PULONG)&request->param1)==pKeyData->password && pKeyData->isInitDone==1) {
keyResponse.status=KEY_OPERATION_STATUS_OK;
// data[0], data[1] - memory size
keyResponse.data[0]=(UCHAR)((GetMemorySize(pKeyData)) & 0xFF);
keyResponse.data[1]=(UCHAR)((GetMemorySize(pKeyData) >> 8) & 0xFF);
keyResponse.data[2]=0x10;
outDataLen=3;
encodeOutData=1;
// FN_OPEN_KEY
pKeyData->isKeyOpened=1;
}
break;
case KEY_FN_READ_NETMEMORY_3WORDS:
LogMessage ("KEY_FN_READ_NETMEMORY\n");
// Decode offset into NetMemory
Chiper(&request->param1, 2, pKeyData);
// Typical data into NetMemory:
// 12 1A 12 0F 03 00 70 00 02 FF 00 00 FF FF FF FF
// 12 1A 12 0F - sn
// 03 00 - key type
// 70 00 - memory size in bytes
// 02 FF - ?
// 00 00 - net user count
// FF FF - ?
// FF - key type (FF - local, FE - net, FD - time)
// FF - ?
// Analyse memory offset
if (pKeyData->isKeyOpened && request->param1>=0 && request->param1<=7) {
keyResponse.status=KEY_OPERATION_STATUS_OK;
RtlCopyMemory(keyResponse.data, &pKeyData->netMemory[request->param1*2], sizeof(USHORT)*3);
outDataLen=sizeof(USHORT)*3;
encodeOutData=1;
}
break;
case KEY_FN_READ_3WORDS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -