⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbkeyemu.c

📁 USB HASP key emulator, based on USB bus driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

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 + -