$$ $$>a< C:\cygwin64\home\Test\tracer.txt init

.catch
{
	.if '${$arg1}' == 'init'
	{
        $$ DONE
        .if (0 == 0) {
        bm CRYPTSP!CryptHashData 			@"$$>a<${$arg0} CryptHashData";
        bm CRYPTSP!CryptGetHashParam        @"$$>a<${$arg0} CryptGetHashParam";
        bm CRYPTSP!CryptDecrypt             @"$$>a<${$arg0} CryptDecrypt";
        bm CRYPTSP!CryptEncrypt             @"$$>a<${$arg0} CryptEncrypt";
        bm CRYPTSP!CryptGenKey              @"$$>a<${$arg0} CryptGenKey";
        bm CRYPTSP!CryptImportKey           @"$$>a<${$arg0} CryptImportKey";
        bm CRYPTSP!CryptExportKey           @"$$>a<${$arg0} CryptExportKey";
        bm CRYPTSP!CryptCreateHash          @"$$>a<${$arg0} CryptCreateHash";
        bm CRYPTSP!CryptGenRandom           @"$$>a<${$arg0} CryptGenRandom";
        bm CRYPTSP!CryptDuplicateHash       @"$$>a<${$arg0} CryptDuplicateHash"
        bm CRYPT32!CryptEncodeObject        @"$$>a<${$arg0} CryptEncodeObject"
        bm WINUSB!WinUsb_ReadPipe           @"$$>a<${$arg0} WinUsb_ReadPipe"; 
        bm WINUSB!WinUsb_WritePipe          @"$$>a<${$arg0} WinUsb_WritePipe";
        bm WINUSB!WinUsb_ControlTransfer    @"$$>a<${$arg0} WinUsb_ControlTransfer";
        bm BCRYPT!BCryptDeriveKey           @"$$>a<${$arg0} BCryptDeriveKey"

        $$ TODO
        bm BCRYPT!BCryptExportKey               @"$$>a<${$arg0} BCryptExportKey"
        bm BCRYPT!BCryptGenerateKeyPair         @"$$>a<${$arg0} BCryptGenerateKeyPair"
        bm BCRYPT!BCryptImportKeyPair           @"$$>a<${$arg0} BCryptImportKeyPair"
        bm BCRYPT!BCryptOpenAlgorithmProvider   @"$$>a<${$arg0} BCryptOpenAlgorithmProvider"
        bm BCRYPT!BCryptSecretAgreement         @"$$>a<${$arg0} BCryptSecretAgreement"
        bm BCRYPT!BCryptSignHash                @"$$>a<${$arg0} BCryptSignHash"
        bm BCRYPT!BCryptVerfySignature          @"$$>a<${$arg0} BCryptVerfySignature"

        $$ TODO 2
        bm CRYPT32!CryptDecodeObject        @"$$>a<${$arg0} CryptDecodeObject"
        bm CRYPTSP!CryptDestroyHash         @"$$>a<${$arg0} CryptDestroyHash";
        bm CRYPTSP!CryptGetUserKey          @"$$>a<${$arg0} CryptGetUserKey";
        bm CRYPTSP!CryptGetKeyParam         @"$$>a<${$arg0} CryptGetKeyParam";
        bm CRYPTSP!CryptDestroyKey          @"$$>a<${$arg0} CryptDestroyKey";
        bm CRYPTSP!CryptSetHashParam        @"$$>a<${$arg0} CryptSetHashParam";
        bm CRYPTSP!CryptSignHashW           @"$$>a<${$arg0} CryptSignHashW";
        bm CRYPTSP!CryptSignHashA           @"$$>a<${$arg0} CryptSignHashA";
        bm CRYPTSP!CryptVerifySignatureW    @"$$>a<${$arg0} CryptVerifySignatureW"; 
        bm CRYPTSP!CryptVerifySignatureA    @"$$>a<${$arg0} CryptVerifySignatureA";
        }

        $$ bm synaWudfBioUsb!00000001800290C0 

        .logopen "log.txt"

        $$ Ignore some debug events (to lessen output pollution)
        sxi ld;

        $$ Display the list of the newly installed breakpoints
        bl;

        .leave;		
	}

	$$ Display API name
    .echotime
	.printf "${$arg1}:\n";
    
    $$.printf "Search:\n";
    $$ s 0 L?100000000000 70 89 6c 99 ad;
    $$.printf "\n";

    $$ BOOL WINAPI CryptHashData(_In_ HCRYPTHASH hHash, _In_ BYTE *pbData,_In_ DWORD dwDataLen, _In_ DWORD dwFlags);
	.if ($sicmp("${$arg1}", "CryptHashData") == 0)
	{
        .printf "Handle: %#x, Data length: %#x(%#d), Flags: %#x\n", @rcx, @r8, @r8, @r9;
        db /c 10 @rdx L@r8;
	}

    $$ BOOL WINAPI CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ BYTE *pbData, _Inout_ DWORD *pdwDataLen, _In_ DWORD dwFlags);
    .if ($sicmp("${$arg1}", "CryptGetHashParam") == 0) {
        .printf "Handle: %#x, Param: %#x, Flags: %#x, Len: ", @rcx, @rdx, poi(@rsp+28);
        .if ((@r9) != 0) {
            .printf "%#x\n", poi(@r9);
        } .else {
            .printf "NULL\n";
        }
        r $t0 = @r8; $$ out data
        r $t1 = @r9; $$ size

        gu;
        .printf "\nRETURN:\n";

        .if (($t1) != 0) {
            .printf "Result len: %#x\n", poi($t1);
            .if (($t0) != 0) {
                db /c 10 $t0 L(poi($t1) & 0xFFFFFFFF);
            }
        } .else {
            .printf "No result\n";
        }

        .printf "\n\n";
        g;
    }


    $$ BOOL __stdcall WinUsb_ReadPipe(_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle, _In_ UCHAR PipeID, _Out_ PUCHAR Buffer,
    $$                                              _In_ ULONG BufferLength, _Out_opt_ PULONG LengthTransferred, _In_opt_ LPOVERLAPPED Overlapped);
    .if ($sicmp("${$arg1}", "WinUsb_ReadPipe") == 0) {
        .printf "Interface handle: %#x, Pipe: #%x, Buffer len: #%x\n", @rcx, @rdx, @r9;
        r $t0 = @r8; $$ out data
        r $t1 = @r9; $$ size

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            db /c 10 $t0 L($t1);
        }

        .printf "\n\n";
        g;
    }


    $$ BOOL __stdcall WinUsb_WritePipe(_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle, _In_ UCHAR PipeID, _In_ PUCHAR Buffer, _In_ ULONG BufferLength,
    $$                                          _Out_opt_ PULONG LengthTransferred, _In_opt_ LPOVERLAPPED Overlapped);
    .if ($sicmp("${$arg1}", "WinUsb_WritePipe") == 0) {
        .printf "Interface handle: %#x, Pipe: #%x, Buffer len: #%x\n", @rcx, @rdx, @r9;
        db /c 10 @r8 L(@r9 & 0xFFFFFFFF);
    }


    $$ BOOL __stdcall WinUsb_ControlTransfer(_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle, _In_ WINUSB_SETUP_PACKET SetupPacket, _Out_ PUCHAR Buffer,
    $$                               _In_ ULONG BufferLength,  _Out_opt_ PULONG LengthTransferred, _In_opt_ LPOVERLAPPED Overlapped);
    .if ($sicmp("${$arg1}", "WinUsb_ControlTransfer") == 0) {
        .printf "Interface handle: %#x\n", @rcx;
    }


    $$ BOOL WINAPI CryptDecrypt(_In_ HCRYPTKEY hKey1, _In_ HCRYPTHASH hHash2, _In_ BOOL Final3, _In_ DWORD dwFlags4, _Inout_ BYTE *pbData5, _Inout_ DWORD *pdwDataLen6);
    .if ($sicmp("${$arg1}", "CryptDecrypt") == 0) {
        .printf "Key handle: %#x, Hash handle: %#x, Final: %#x, Flags: %#x, Len: %#x\n", @rcx, @rdx, @r8, @r9, poi(poi(@rsp+30))
        r $t0 = poi(@rsp+28); $$ out data
        r $t1 = poi(@rsp+30); $$ size

        .if (($t0) != 0) {
            db /c 10 $t0 L(poi($t1) & 0xFFFFFFFF);
        }

        gu;
        .printf "\nRETURN:\n";
    
        .printf "Result len: %#x\n", poi($t1);
        .if (($t0) != 0) {
            db /c 10 $t0 L(poi($t1) & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }


    $$ BOOL WINAPI BOOL WINAPI CryptEncrypt(_In_ HCRYPTKEY hKey1, _In_ HCRYPTHASH hHash2, _In_ BOOL Final3, _In_ DWORD dwFlags4, _Inout_ BYTE *pbData5,
    $$                                                                                                                  _Inout_ DWORD *pdwDataLen6, _In_ DWORD dwBufLen7);
    .if ($sicmp("${$arg1}", "CryptEncrypt") == 0) {
        .printf "Key handle: %#x, Hash handle: %#x, Final: %#x, Flags: %#x, Len: %#x\n", @rcx, @rdx, @r8, @r9, poi(poi(@rsp+30))
        r $t0 = poi(@rsp+28); $$ out data
        r $t1 = poi(@rsp+30); $$ size

        .if (($t0) != 0) {
            db /c 10 $t0 L(poi($t1) & 0xFFFFFFFF);
        }

        gu;
        .printf "\nRETURN:\n";

        .printf "Result len: %#x\n", poi($t1);
        .if (($t0) != 0) {
            db /c 10 $t0 L(poi($t1) & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }

    $$ BOOL WINAPI CryptGenKey(_In_ HCRYPTPROV hProv1, _In_ ALG_ID Algid2, _In_ DWORD dwFlags3, _Out_ HCRYPTKEY *phKey4);
    .if ($sicmp("${$arg1}", "CryptGenKey") == 0) {
        .printf "Prov handle: %#x, Alg id: %#x, Flags: %#x, Key handle: %#x\n", @rcx, @rdx, @r8, @r9);
    }

    $$ BOOL WINAPI CryptImportKey(_In_ HCRYPTPROV hProv1, _In_ BYTE *pbData2, _In_ DWORD dwDataLen3, _In_ HCRYPTKEY hPubKey4, _In_ DWORD dwFlags5, _Out_ HCRYPTKEY *phKey6);
    .if ($sicmp("${$arg1}", "CryptImportKey") == 0) {
        .printf "Prov handle: %#x, Data len: %#x, Pubkey handle: %#x, Flags: %#x\n", @rcx, @r8, @r9, poi(@rsp+28)
        db /c 10 @rdx L(@r8);
    }

    $$ BOOL WINAPI CryptExportKey(_In_ HCRYPTKEY hKey1, _In_ HCRYPTKEY hExpKey2, _In_ DWORD dwBlobType3, _In_ DWORD dwFlags4, _Out_ BYTE *pbData5, _Inout_ DWORD *pdwDataLen6);
    .if ($sicmp("${$arg1}", "CryptExportKey") == 0) {
        .printf "Prov handle: %#x, Data len: %#x, Pubkey handle: %#x, Flags: %#x\n", @rcx, @r8, @r9, poi(@rsp+28)

        r $t0 = poi(@rsp+28); $$ out data
        r $t1 = poi(@rsp+30); $$ size

        gu;
        .printf "\nRETURN:\n";

        .printf "Result len: %#x\n", poi($t1);
        .if (($t0) != 0) {
            db /c 10 $t0 L(poi($t1) & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }


    $$ BOOL WINAPI CryptCreateHash(_In_ HCRYPTPROV hProv1, _In_ ALG_ID Algid2, _In_ HCRYPTKEY hKey3, _In_ DWORD dwFlags4, _Out_ HCRYPTHASH *phHash);
    .if ($sicmp("${$arg1}", "CryptCreateHash") == 0) {
        .printf "Prov handle: %#x, Alg id: %#x, Key handle: %#x, Flags: %#x\n", @rcx, @rdx, @r8, @r9;
    }

    
    $$ BOOL WINAPI CryptGenRandom(_In_ HCRYPTPROV hProv, _In_ DWORD dwLen, _Inout_ BYTE *pbBuffer);
    .if ($sicmp("${$arg1}", "CryptGenRandom") == 0) {
        .printf "Prov handle: %#x, Len: %#x\n", @rcx, @rdx;
        r $t0 = @r8; $$ out data
        r $t1 = @rdx; $$ size

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            db /c 10 $t0 L($t1 & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }


    $$ BOOL WINAPI CryptDuplicateHash(_In_ HCRYPTHASH hHash, _In_ DWORD *pdwReserved, _In_ DWORD dwFlags, _Out_ HCRYPTHASH *phHash);
    .if ($sicmp("${$arg1}", "CryptDuplicateHash") == 0) {
        .printf "Hash handle: %#x, Flags: %#x\n", @rcx, @r8;
        r $t0 = @r9; $$ out data

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            .printf "Hash duplicate handle: %#x\n", poi($t0);
        }

        .printf "\n\n";
        g;
    }

    $$ BOOL WINAPI CryptEncodeObject(_In_ DWORD dwCertEncodingType1, _In_ LPCSTR lpszStructType2, _In_ const void *pvStructInfo3, _Out_ BYTE *pbEncoded4, _Inout_ DWORD *pcbEncoded5);
    .if ($sicmp("${$arg1}", "CryptEncodeObject") == 0) {
        .printf "Enc type: %#x, Struct type: \n", @rcx;
        du @rdx;

        r $t0 = @r9; $$ out data
        r $t1 = poi(@rsp+28); $$ size

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            .printf "Len: %#x\n", poi($t1);
            db /c 10 $t0 L(poi($t1) & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }


    $$ NTSTATUS WINAPI BCryptDeriveKey(_In_ BCRYPT_SECRET_HANDLE hSharedSecret1, _In_ LPCWSTR pwszKDF2, _In_opt_ BCryptBufferDesc *pParameterList3,
    $$                                                                      _Out_opt_ PUCHAR pbDerivedKey4, _In_ ULONG cbDerivedKey5, _Out_ ULONG *pcbResult6, _In_ ULONG dwFlags7);
    .if ($sicmp("${$arg1}", "BCryptDeriveKey") == 0) {
        .printf "Secret handle: %#x, KDF: ", @rcx;
        du @rdx;
        .printf "\n";

        r $t0 = @r9; $$ out data
        r $t1 = poi(@rsp+28); $$ size

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            .printf "Len: %#x\n", $t1;
            db /c 10 $t0 L($t1 & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }

    $$ NTSTATUS WINAPI BCryptImportKeyPair(_In_ BCRYPT_ALG_HANDLE hAlgorithm, _Inout_ BCRYPT_KEY_HANDLE hImportKey, 
    $$    _In_ LPCWSTR pszBlobType, _Out_ BCRYPT_KEY_HANDLE *phKey, _In_ PUCHAR pbInput, _In_ ULONG cbInput, _In_ ULONG dwFlags);
    .if ($sicmp("${$arg1}", "BCryptImportKeyPair") == 0) {
        .printf "Algo handle: %#x, Key handle: %#x, Blob type ", @rcx, @rdx;
        du @r8;
        .printf "\n";

        .printf "Input:\n";

        db /c 10 poi(rsp+28) L(poi(rsp+30) & 0xFFFFFFFF);

        .printf "\n\n";
        g;
    }

    $$ NTSTATUS WINAPI BCryptSignHash(_In_ BCRYPT_KEY_HANDLE hKey1, _In_opt_ VOID *pPaddingInfo2, _In_ PBYTE pbInput3, _In_ DWORD cbInput4,
    $$    _Out_ PBYTE pbOutput5, _In_ DWORD cbOutput, _Out_ DWORD *pcbResult, _In_ ULONG dwFlags);
    .if ($sicmp("${$arg1}", "BCryptSignHash") == 0) {
        .printf "Key handle: %#x, Len in: %#x, Len out: %#x, Flags: %#x\n", @rcx, @r9, poi(@rsp + 30), poi(@rsp + 48);
        .printf "Data to hash:\n";

        db /c 10 @r8 L(@r9);

        r $t0 = poi(@rsp+28); $$ out data
        r $t1 = poi(@rsp+30); $$ size

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            .printf "Len: %#x\n", $t1;
            db /c 10 $t0 L($t1 & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }

    $$ NTSTATUS WINAPI BCryptExportKey(_In_ BCRYPT_KEY_HANDLE hKey1, _In_ BCRYPT_KEY_HANDLE hExportKey2, _In_ LPCWSTR pszBlobType3,
    $$                      _Out_ PUCHAR pbOutput4, _In_ ULONG cbOutput5, _Out_ ULONG *pcbResult6, _In_ ULONG dwFlags7);
    .if ($sicmp("${$arg1}", "BCryptExportKey") == 0) {
        .printf "Key handle: %#x, Exported key handle: %#x, Len out: %#x, Flags: %#x, Type: ", @rcx, @rdx, poi(@rsp + 28), poi(@rsp + 38);
        du @r8;


        r $t0 = @r9; $$ out data
        r $t1 = poi(@rsp+28); $$ size

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            .printf "Len: %#x\n", $t1;
            db /c 10 $t0 L($t1 & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }

    $$ NTSTATUS WINAPI BCryptOpenAlgorithmProvider(_Out_ BCRYPT_ALG_HANDLE *phAlgorithm1, _In_ LPCWSTR pszAlgId2,
    $$                          _In_ LPCWSTR pszImplementation3, _In_ DWORD dwFlags4);
    .if ($sicmp("${$arg1}", "BCryptOpenAlgorithmProvider") == 0) {
        .printf "Flags: %#x, algId: ", @r9;
        du @rdx;

        .if (@r8 != 0) {.printf "implementation: ";du @r8;}

        r $t0 = @rcx; $$ handle

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            .printf "Handle: %#x\n", poi($t0);
        }

        .printf "\n\n";
        g;
    }

    $$ BOOL WINAPI CryptDecodeObject(_In_ DWORD dwCertEncodingType1, _In_ LPCSTR lpszStructType2, _In_ const BYTE *pbEncoded3,
    $$    _In_ DWORD cbEncoded4, _In_ DWORD dwFlags5, _Out_ void *pvStructInfo6, _Inout_ DWORD *pcbStructInfo7);
    .if ($sicmp("${$arg1}", "CryptDecodeObject") == 0) {
        .printf "Type: %#x, len: %#x, flags: %#x, type: ", @rcx, @r9, poi(@rsp+28);
        du @rdx;

        .printf "\nIN:\n";
        db /c 10 @r8 L(@r9 & 0xFFFFFFFF);

        r $t0 = poi(@rsp+30); $$ out struct

        gu;
        .printf "\nRETURN:\n";

        .if (($t0) != 0) {
            db /c 10 $t0 L(60 & 0xFFFFFFFF);
        }

        .printf "\n\n";
        g;
    }

    .printf "\n\n";

	$$ Continue after breakpoint
	g;    
}
