|
| 1 | +struct string { |
| 2 | + char *str; |
| 3 | + struct len_pid *info; |
| 4 | +} |
| 5 | + |
| 6 | +struct len_pid { |
| 7 | + int64_t pad; // set always to 0 |
| 8 | + int32_t pid; // the pid of the process that add the following structure |
| 9 | + int32_t len; // the length of str |
| 10 | +} |
| 11 | + |
| 12 | +struct string *storages[16]; // global |
| 13 | +__int64 __fastcall pprofile_ioctl(__int64 a1, __int64 a2) |
| 14 | +{ |
| 15 | + __int64 v2; // rdx |
| 16 | + __int64 result; // rax |
| 17 | + struct string **storages__; // rbx |
| 18 | + struct string *found_string_ptr_; // rbp |
| 19 | + __int64 v6; // rbx |
| 20 | + struct pid_len *found_info; // rax |
| 21 | + unsigned int found_pid; // ebp |
| 22 | + unsigned int found_size_str; // er12 |
| 23 | + int len_copied; // eax |
| 24 | + int len_copied_; // ebx |
| 25 | + __int64 index_storage__; // rax |
| 26 | + __int64 index_storage___; // r12 |
| 27 | + struct string **current_string__; // rbp |
| 28 | + size_t len_str; // rbp |
| 29 | + unsigned int len_str_plus_1; // er13 |
| 30 | + _DWORD *str_ptr; // r15 |
| 31 | + string *string_ptr; // r14 |
| 32 | + struct pid_len *leak_ptr_current_task; // rcx |
| 33 | + unsigned __int64 current_task_; // rdi |
| 34 | + int len_copied__; // eax |
| 35 | + __int64 index_storage____; // rbp |
| 36 | + struct string *current_string; // r12 |
| 37 | + __int64 current_string_ptr_str; // r13 |
| 38 | + unsigned int index_zeroize_; // eax |
| 39 | + __int64 index_zeroize; // rdx |
| 40 | + struct pid_len *leak_ptr_current_task_; // [rsp+0h] [rbp-60h] |
| 41 | + __int64 local_buffer; // [rsp+8h] [rbp-58h] BYREF |
| 42 | + __int64 v29; // [rsp+10h] [rbp-50h] |
| 43 | + char str_copied[8]; // [rsp+1Fh] [rbp-41h] BYREF |
| 44 | + char v31; // [rsp+27h] [rbp-39h] |
| 45 | + unsigned __int64 v32; // [rsp+28h] [rbp-38h] |
| 46 | + |
| 47 | + _fentry__(a1, a2); |
| 48 | + *(_QWORD *)str_copied = 0LL; |
| 49 | + v31 = 0; |
| 50 | + v32 = __readgsqword(0x28u); |
| 51 | + local_buffer = 0LL; |
| 52 | + v29 = 0LL; |
| 53 | + LODWORD(result) = copy_from_user(&local_buffer, v2, 16LL); |
| 54 | + if ( (_DWORD)result ) |
| 55 | + return (int)result; |
| 56 | + if ( (_DWORD)a2 == 32 ) |
| 57 | + { |
| 58 | + len_copied = strncpy_from_user(str_copied, local_buffer, 8LL); |
| 59 | + len_copied_ = len_copied; |
| 60 | + if ( len_copied && len_copied != 9 ) |
| 61 | + { |
| 62 | + if ( len_copied >= 0 ) |
| 63 | + { |
| 64 | + index_storage__ = 0LL; |
| 65 | + while ( 1 ) |
| 66 | + { |
| 67 | + index_storage___ = (int)index_storage__; |
| 68 | + if ( !storages[index_storage__] ) |
| 69 | + break; |
| 70 | + if ( ++index_storage__ == 16 ) |
| 71 | + return -11LL; |
| 72 | + } |
| 73 | + current_string__ = storages; |
| 74 | + while ( !*current_string__ || strcmp((const char *)(*current_string__)->str, str_copied) ) |
| 75 | + { |
| 76 | + if ( &storages[16] == ++current_string__ ) |
| 77 | + { |
| 78 | + len_str = strlen(str_copied); |
| 79 | + if ( len_str - 1 > 7 ) |
| 80 | + return -11LL; |
| 81 | + len_str_plus_1 = len_str + 1; |
| 82 | + str_ptr = (_DWORD *)_kmalloc(len_str + 1, 6291648LL); |
| 83 | + string_ptr = (string *)kmem_cache_alloc_trace(kmalloc_caches[4], 6291648LL, 16LL); |
| 84 | + leak_ptr_current_task = (struct pid_len *)kmem_cache_alloc_trace(kmalloc_caches[4], 6291648LL, 16LL); |
| 85 | + if ( string_ptr == 0LL || str_ptr == 0LL || !leak_ptr_current_task ) |
| 86 | + return -12LL; // |
| 87 | + // Zeroize the str_ptr (kmalloc) in 4 different way xD, at least |
| 88 | + // from my understanding lol eheh |
| 89 | + // ... they don't know about kzalloc or memset X'D |
| 90 | + if ( len_str_plus_1 >= 8 ) |
| 91 | + { |
| 92 | + *(_QWORD *)((char *)str_ptr + len_str_plus_1 - 8) = 0LL; |
| 93 | + if ( (unsigned int)len_str >= 8 ) |
| 94 | + { |
| 95 | + index_zeroize_ = 0; |
| 96 | + do |
| 97 | + { |
| 98 | + index_zeroize = index_zeroize_; |
| 99 | + index_zeroize_ += 8; |
| 100 | + *(_QWORD *)((char *)str_ptr + index_zeroize) = 0LL; |
| 101 | + } |
| 102 | + while ( index_zeroize_ < (len_str & 0xFFFFFFF8) ); |
| 103 | + } |
| 104 | + } |
| 105 | + else if ( (len_str_plus_1 & 4) != 0 ) |
| 106 | + { |
| 107 | + *str_ptr = 0; |
| 108 | + *(_DWORD *)((char *)str_ptr + len_str_plus_1 - 4) = 0; |
| 109 | + } |
| 110 | + else if ( (_DWORD)len_str != -1 ) |
| 111 | + { |
| 112 | + *(_BYTE *)str_ptr = 0; |
| 113 | + if ( (len_str_plus_1 & 2) != 0 ) |
| 114 | + *(_WORD *)((char *)str_ptr + len_str_plus_1 - 2) = 0; |
| 115 | + } |
| 116 | + leak_ptr_current_task->pad = 0LL; |
| 117 | + *(_QWORD *)&leak_ptr_current_task->pid = 0LL; |
| 118 | + string_ptr->str = 0LL; |
| 119 | + string_ptr->info = 0LL; |
| 120 | + leak_ptr_current_task_ = leak_ptr_current_task; |
| 121 | + memcpy(str_ptr, str_copied, len_str); |
| 122 | + string_ptr->str = (__int64)str_ptr; |
| 123 | + current_task_ = __readgsqword((unsigned int)¤t_task); |
| 124 | + string_ptr->info = leak_ptr_current_task_; |
| 125 | + leak_ptr_current_task_->pid = _task_pid_nr_ns(current_task_, 1LL, 0LL); |
| 126 | + *((_DWORD *)string_ptr->info + 3) = len_copied_; |
| 127 | + storages[index_storage___] = string_ptr; |
| 128 | + return len_copied_; |
| 129 | + } |
| 130 | + } |
| 131 | + return -11LL; |
| 132 | + } |
| 133 | + return len_copied_; |
| 134 | + } |
| 135 | + return -34LL; |
| 136 | + } |
| 137 | + if ( (_DWORD)a2 == 64 ) |
| 138 | + { |
| 139 | + len_copied__ = strncpy_from_user(str_copied, local_buffer, 8LL); |
| 140 | + len_copied_ = len_copied__; |
| 141 | + if ( len_copied__ && len_copied__ != 9 ) |
| 142 | + { |
| 143 | + if ( len_copied__ >= 0 ) |
| 144 | + { |
| 145 | + index_storage____ = 0LL; |
| 146 | + while ( 1 ) |
| 147 | + { |
| 148 | + current_string = storages[index_storage____]; |
| 149 | + if ( current_string ) |
| 150 | + { |
| 151 | + current_string_ptr_str = current_string->str; |
| 152 | + if ( !strcmp((const char *)current_string->str, str_copied) ) |
| 153 | + break; |
| 154 | + } |
| 155 | + if ( ++index_storage____ == 16 ) |
| 156 | + return -11LL; |
| 157 | + } // current_string->str |
| 158 | + kfree(current_string_ptr_str); |
| 159 | + kfree(current_string->info); |
| 160 | + current_string->str = 0LL; |
| 161 | + current_string->info = 0LL; |
| 162 | + kfree(current_string); |
| 163 | + storages[(int)index_storage____] = 0LL; |
| 164 | + } |
| 165 | + return len_copied_; |
| 166 | + } |
| 167 | + return -34LL; |
| 168 | + } |
| 169 | + if ( (_DWORD)a2 != 16 ) |
| 170 | + return -11LL; |
| 171 | + LODWORD(result) = strncpy_from_user(str_copied, local_buffer, 8LL); |
| 172 | + if ( !(_DWORD)result || (_DWORD)result == 9 ) |
| 173 | + return -34LL; |
| 174 | + if ( (int)result < 0 ) |
| 175 | + return (int)result; |
| 176 | + storages__ = storages; |
| 177 | + while ( 1 ) |
| 178 | + { |
| 179 | + found_string_ptr_ = *storages__; |
| 180 | + if ( *storages__ ) |
| 181 | + { |
| 182 | + if ( !strcmp((const char *)found_string_ptr_->str, str_copied) ) |
| 183 | + break; |
| 184 | + } |
| 185 | + if ( ++storages__ == &storages[16] ) |
| 186 | + return -11LL; |
| 187 | + } |
| 188 | + v6 = v29; |
| 189 | + found_info = (struct pid_len *)found_string_ptr_->info; |
| 190 | + found_pid = found_info->pid; |
| 191 | + found_size_str = *(_DWORD *)&found_info->size_str; |
| 192 | + LODWORD(result) = ((__int64 (__fastcall *)(__int64, __int64, __int32))put_user_size)(0LL, v29, 4); |
| 193 | + if ( (_DWORD)result ) |
| 194 | + return (int)result; |
| 195 | + LODWORD(result) = put_user_size(found_pid, v6 + 8); |
| 196 | + if ( (_DWORD)result ) |
| 197 | + return (int)result; |
| 198 | + return (int)put_user_size(found_size_str, v6 + 12); |
| 199 | +} |
0 commit comments