9
9
import speakeasy .windows .objman as objman
10
10
11
11
from .. import api
12
+ from Crypto .Cipher import ARC4
12
13
import hashlib
13
14
14
15
SERVICE_STATUS_HANDLE_BASE = 0x1000
@@ -35,6 +36,8 @@ def __init__(self, emu):
35
36
self .curr_handle = 0x2800
36
37
self .service_status_handle = SERVICE_STATUS_HANDLE_BASE
37
38
39
+ self .rc4 = None
40
+
38
41
super (AdvApi32 , self ).__get_hook_attrs__ (self )
39
42
40
43
def get_handle (self ):
@@ -1113,6 +1116,99 @@ def CryptDestroyHash(self, emu, argv, ctx={}):
1113
1116
1114
1117
return 1
1115
1118
1119
+ @apihook ('CryptDeriveKey' , argc = 5 )
1120
+ def CryptDeriveKey (self , emu , argv , ctx = {}):
1121
+ """
1122
+ BOOL CryptDeriveKey(
1123
+ HCRYPTPROV hProv,
1124
+ ALG_ID Algid,
1125
+ HCRYPTHASH hBaseData,
1126
+ DWORD dwFlags,
1127
+ HCRYPTKEY *phKey
1128
+ );
1129
+ """
1130
+
1131
+ hProv , Algid , hBaseData , dwFlags , phKey = argv
1132
+
1133
+ # Only RC4 supported right now
1134
+ if Algid != 0x6801 :
1135
+ return 0
1136
+
1137
+ hnd = self .hash_objects .get (hBaseData , None )
1138
+
1139
+ if hnd is None :
1140
+ emu .set_last_error (windefs .ERROR_INVALID_HANDLE )
1141
+ return 0
1142
+
1143
+ # CryptDeriveKey zeroes out the last 11 bytes of the hash,
1144
+ # so we gotta do the same before it is written to the
1145
+ # phKey structure
1146
+ fixed_digest = hnd .digest ()[:5 ] + b'\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 '
1147
+
1148
+ ptrsz = emu .get_ptr_size ()
1149
+
1150
+ hKey = self .win .HCRYPTKEY (ptrsz )
1151
+ hKey .Algid = Algid
1152
+ hKey .keylen = hnd .digest_size
1153
+ hKey .keyp = self .mem_alloc (hKey .keylen )
1154
+
1155
+ hKeyp = self .mem_alloc (hKey .sizeof ())
1156
+
1157
+ self .mem_write (hKey .keyp , fixed_digest )
1158
+
1159
+ self .mem_write (hKeyp , hKey .get_bytes ())
1160
+ self .mem_write (phKey , hKeyp .to_bytes (ptrsz , "little" ))
1161
+
1162
+ return 1
1163
+
1164
+ @apihook ('CryptDecrypt' , argc = 6 )
1165
+ def CryptDecrypt (self , emu , argv , ctx = {}):
1166
+ """
1167
+ BOOL CryptDecrypt(
1168
+ HCRYPTKEY hKey,
1169
+ HCRYPTHASH hHash,
1170
+ BOOL Final,
1171
+ DWORD dwFlags,
1172
+ BYTE *pbData,
1173
+ DWORD *pdwDataLen
1174
+ );
1175
+ """
1176
+
1177
+ hKey , hHash , Final , dwFlags , pbData , pdwDataLen = argv
1178
+
1179
+ # Hashing not supported
1180
+ if hHash :
1181
+ return 0
1182
+
1183
+ ptrsz = emu .get_ptr_size ()
1184
+
1185
+ hKey = self .mem_cast (self .win .HCRYPTKEY (ptrsz ), hKey )
1186
+
1187
+ # Only RC4 supported right now
1188
+ if hKey .Algid != 0x6801 :
1189
+ return 0
1190
+
1191
+ encdatalen_b = self .mem_read (pdwDataLen , 4 )
1192
+ encdatalen = int .from_bytes (encdatalen_b , "little" )
1193
+
1194
+ encdata = self .mem_read (pbData , encdatalen )
1195
+
1196
+ key = self .mem_read (hKey .keyp , hKey .keylen )
1197
+
1198
+ if self .rc4 is None :
1199
+ self .rc4 = ARC4 .new (key )
1200
+
1201
+ dec = self .rc4 .decrypt (encdata )
1202
+ declen = len (dec )
1203
+
1204
+ self .mem_write (pbData , dec )
1205
+ self .mem_write (pdwDataLen , int .to_bytes (declen , 4 , "little" ))
1206
+
1207
+ if Final == True :
1208
+ self .rc4 = None
1209
+
1210
+ return 1
1211
+
1116
1212
@apihook ('RegGetValue' , argc = 7 , conv = _arch .CALL_CONV_STDCALL )
1117
1213
def RegGetValue (self , emu , argv , ctx = {}):
1118
1214
'''
0 commit comments