forked from gentilkiwi/mimikatz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkull_m_acr.c
130 lines (120 loc) · 3.8 KB
/
kull_m_acr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* Benjamin DELPY `gentilkiwi`
https://blog.gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kull_m_acr.h"
BOOL kull_m_acr_init(SCARDCONTEXT hContext, LPCWSTR szReaderName, BOOL withoutCard, LPVOID suppdata, BOOL descr, PKULL_M_ACR_COMM comm)
{
BOOL status = FALSE;
DWORD dwActiveProtocol;
LONG scStatus;
comm->hCard = 0;
comm->withoutCard = withoutCard;
comm->suppdata = suppdata;
comm->descr = descr;
scStatus = SCardConnect(hContext, szReaderName, withoutCard ? SCARD_SHARE_DIRECT : SCARD_SHARE_SHARED, withoutCard ? SCARD_PROTOCOL_UNDEFINED : SCARD_PROTOCOL_Tx, &comm->hCard, &dwActiveProtocol);
if(!(status = (scStatus == SCARD_S_SUCCESS)))
PRINT_ERROR(L"SCardConnect: 0x%08x\n", scStatus);
return status;
}
void kull_m_acr_finish(PKULL_M_ACR_COMM comm)
{
LONG scStatus;
if(comm->hCard)
{
scStatus = SCardDisconnect(comm->hCard, SCARD_LEAVE_CARD);
if(scStatus == SCARD_S_SUCCESS)
comm->hCard = 0;
else PRINT_ERROR(L"SCardDisconnect: 0x%08x\n", scStatus);
}
}
BOOL kull_m_arc_sendrecv(PKULL_M_ACR_COMM comm, const BYTE *pbData, const UINT16 cbData, BYTE *pbResult, UINT16 *cbResult)
{
BOOL status = FALSE;
LONG scStatus;
DWORD ret = *cbResult;
if(comm->hCard)
{
if(cbData <= ACR_MAX_LEN)
{
if(comm->descr)
{
kprintf(L"ACR > ");
kull_m_string_wprintf_hex(pbData, cbData, 1);
kprintf(L"\n");
}
scStatus = comm->withoutCard ?
SCardControl(comm->hCard, IOCTL_CCID_ESCAPE, pbData, cbData, pbResult, *cbResult, &ret) :
SCardTransmit(comm->hCard, NULL, pbData, cbData, NULL, pbResult, &ret);
if(scStatus == SCARD_S_SUCCESS)
{
if(comm->descr)
{
kprintf(L"ACR < ");
kull_m_string_wprintf_hex(pbResult, ret, 1);
kprintf(L"\n");
}
if(status = (ret <= *cbResult))
*cbResult = (UINT16) ret;
}
else PRINT_ERROR(L"%s: 0x%08x\n", comm->withoutCard ? L"SCardControl" : L"SCardTransmit", scStatus);
}
else PRINT_ERROR(L"cbData = %hu / cbResult = %hu (max is %hu)\n", cbData, cbResult, ACR_MAX_LEN);
}
else PRINT_ERROR(L"No handle to Card\n");
return status;
}
BOOL kull_m_acr_sendrecv_ins(PKULL_M_ACR_COMM comm, BYTE cla, BYTE ins, BYTE p1, BYTE p2, const BYTE *pbData, const UINT16 cbData, BYTE *pbResult, UINT16 *cbResult, BOOL noLe)
{
BOOL status = FALSE;
BYTE buffer[ACR_MAX_LEN], idx = 4;
//BYTE max = sizeof(buffer) - idx -
// CHECK SIZES !
buffer[0] = cla;
buffer[1] = ins;
buffer[2] = p1;
buffer[3] = p2;
if(cbData)
{
buffer[idx++] = (BYTE) cbData;
RtlCopyMemory(buffer + idx, pbData, cbData);
idx += cbData;
}
if(!noLe && *cbResult)
buffer[idx++] = (BYTE) *cbResult;
return kull_m_arc_sendrecv(comm, buffer, idx, pbResult, cbResult);
}
BOOL CALLBACK kull_m_arcr_SendRecvDirect(const BYTE *pbData, const UINT16 cbData, BYTE *pbResult, UINT16 *cbResult, LPVOID suppdata)
{
BOOL status = FALSE;
BYTE buffer[ACR_MAX_LEN];
UINT16 cbOut = *cbResult + 2;
if(suppdata)
{
if(cbOut <= sizeof(buffer))
{
if(kull_m_acr_sendrecv_ins((PKULL_M_ACR_COMM) suppdata, 0xff, 0x00, 0x00, 0x00, pbData, cbData, buffer, &cbOut, TRUE))
{
if(cbOut >= 2)
{
if(*(PUINT16) (buffer + cbOut - 2) == 0x0090)
{
cbOut -= 2;
if(status = (cbOut <= *cbResult))
{
RtlCopyMemory(pbResult, buffer, cbOut);
*cbResult = cbOut;
}
else PRINT_ERROR(L"cbResult = %hu (data is %u)\n", *cbResult, cbOut);
}
else PRINT_ERROR(L"RET: %02x %02x\n", buffer[cbOut - 2], buffer[cbOut - 1]);
}
else PRINT_ERROR(L"cbRetBuffer = %hu (not long enough)\n", cbOut);
}
}
else PRINT_ERROR(L"cbOut = %hu (max is %hu)\n", cbOut, sizeof(buffer));
}
else PRINT_ERROR(L"No suppdata (ACR_COMM)\n");
return status;
}