@@ -204,21 +204,40 @@ bool UACParser::parseUAC(void* uac, size_t len) {
204204 }
205205 }
206206 CloseHandle (duplicated_handle);
207- write_target = *reinterpret_cast <void **>(buffer + 6 * sizeof (UINT32) + 4 * sizeof (void *));
207+
208+ unsigned char * buf_write_target = buffer + 6 * sizeof (UINT32) + 4 * sizeof (void *);
209+ /*
210+ At this address, the new consent data stores the base64 of a UUID (24 characters) padded to 129 bytes, and then left 7 bytes margin at the tail.
211+ So there should be a long all-zero area if we skip the first 24 bytes.
212+ We can make a guess.
213+ */
214+ bool is_new_type = true ;
215+
216+ for (size_t i=24 ;i<129 ;i++){
217+
218+ if (buf_write_target[i]!=0 ){
219+ is_new_type = false ;
220+ break ;
221+ }
222+ }
223+ int new_type_offset = is_new_type?136 :0 ;
224+
225+ write_target = *reinterpret_cast <void **>(buffer + 6 * sizeof (UINT32) + 4 * sizeof (void *) + new_type_offset);
226+
208227 size_t base_offset = 0 ;
209228 if (uac_type == 0 || uac_type ==2 ) {// Known to be excutable
210229 // uac_type==2 means msi. which is similar to exe except that content meanings have changed.
211- base_offset = 6 * sizeof (DWORD) + 6 * sizeof (void *);
230+ base_offset = 6 * sizeof (DWORD) + 6 * sizeof (void *) + new_type_offset ;
212231 }
213232 else if (uac_type == 1 ) {// dll
214- base_offset = 6 * sizeof (DWORD) + 5 * sizeof (void *);
233+ base_offset = 6 * sizeof (DWORD) + 5 * sizeof (void *) + new_type_offset ;
215234 }
216235 else {
217236 // see if any of these fits.
218237 do
219238 {
220239 {
221- base_offset = 6 * sizeof (DWORD) + 6 * sizeof (void *);
240+ base_offset = 6 * sizeof (DWORD) + 6 * sizeof (void *) + new_type_offset ;
222241 uintptr_t description_offset = *reinterpret_cast <uintptr_t *>(buffer + base_offset);
223242 uintptr_t path_offset = *reinterpret_cast <uintptr_t *>(buffer + base_offset + sizeof (uintptr_t ));
224243 uintptr_t parameters_offset = *reinterpret_cast <uintptr_t *>(buffer + base_offset + 2 * sizeof (uintptr_t ));
@@ -232,7 +251,7 @@ bool UACParser::parseUAC(void* uac, size_t len) {
232251 )break ;
233252 }
234253 {
235- base_offset = 6 * sizeof (DWORD) + 5 * sizeof (void *);
254+ base_offset = 6 * sizeof (DWORD) + 5 * sizeof (void *) + new_type_offset ;
236255 uintptr_t description_offset = *reinterpret_cast <uintptr_t *>(buffer + base_offset);
237256 uintptr_t path_offset = *reinterpret_cast <uintptr_t *>(buffer + base_offset + sizeof (uintptr_t ));
238257 uintptr_t parameters_offset = *reinterpret_cast <uintptr_t *>(buffer + base_offset + 2 * sizeof (uintptr_t ));
0 commit comments