| 164 | } |
| 165 | |
| 166 | void PycCode::pyarmorDecryptCoCode(unsigned long consts_index, PycModule *mod) |
| 167 | { |
| 168 | PycRef<PycString> descriptor = getConst(consts_index).cast<PycString>(); |
| 169 | const std::string &descriptor_str = descriptor->strValue(); |
| 170 | if (descriptor_str.length() < 20) |
| 171 | { |
| 172 | fprintf(stderr, "Pyarmor CO descriptor is too short\n"); |
| 173 | return; |
| 174 | } |
| 175 | |
| 176 | const PyarmorCoDescriptor *desc = (const PyarmorCoDescriptor *)(descriptor_str.data() + 8); |
| 177 | bool copy_prologue = desc->flags & 0x8; |
| 178 | bool xor_aes_nonce = desc->flags & 0x4; |
| 179 | bool short_code = desc->flags & 0x2; |
| 180 | |
| 181 | unsigned int nonce_index = short_code |
| 182 | ? desc->short_nonce_index |
| 183 | : desc->short_nonce_index + desc->decrypt_begin_index + desc->decrypt_length; |
| 184 | unsigned char nonce[16] = {0}; |
| 185 | memcpy(nonce, m_code->value() + nonce_index, 12); |
| 186 | nonce[15] = 2; |
| 187 | if (xor_aes_nonce) |
| 188 | { |
| 189 | if (!mod->pyarmor_co_code_aes_nonce_xor_enabled) |
| 190 | { |
| 191 | fprintf(stderr, "FATAL: Pyarmor CO code AES nonce XOR is not enabled but used\n"); |
| 192 | } |
| 193 | else |
| 194 | { |
| 195 | unsigned char *xor_key = mod->pyarmor_co_code_aes_nonce_xor_key; |
| 196 | for (int i = 0; i < 12; i++) |
| 197 | nonce[i] ^= xor_key[i]; |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | std::string &code_bytes = (std::string &)m_code->strValue(); |
| 202 | |
| 203 | plusaes::crypt_ctr( |
| 204 | (unsigned char *)&code_bytes[desc->decrypt_begin_index], |
| 205 | desc->decrypt_length, |
| 206 | mod->pyarmor_aes_key, |
| 207 | 16, |
| 208 | &nonce); |
| 209 | |
| 210 | if (copy_prologue) |
| 211 | { |
| 212 | memcpy( |
| 213 | &code_bytes[0], |
| 214 | &code_bytes[desc->decrypt_length], |
| 215 | desc->decrypt_begin_index); |
| 216 | // Assume tail of code is not used there |
| 217 | memset( |
| 218 | &code_bytes[desc->decrypt_length], |
| 219 | mod->verCompare(3, 13) == 0 ? 30 : mod->verCompare(3, 14) == 0 ? 27 : 9, // NOP |
| 220 | desc->decrypt_begin_index); |
| 221 | } |
| 222 | |
| 223 | // When running, the first 8 bytes are set to &PyCodeObject |