wip: header parsing
This commit is contained in:
@@ -37,7 +37,7 @@ def decrypt_process(runtimes: dict[str, RuntimeInfo], sequences: list[tuple[str,
|
||||
with open(dest_path + '.1shot.seq', 'wb') as f:
|
||||
f.write(b'\xa1' + runtime.runtime_aes_key)
|
||||
f.write(b'\xa2' + runtime.mix_str_aes_nonce())
|
||||
f.write(b'\xf0\xf0')
|
||||
f.write(b'\xf0\xff')
|
||||
f.write(data[:cipher_text_offset])
|
||||
f.write(general_aes_ctr_decrypt(
|
||||
data[cipher_text_offset:cipher_text_offset+cipher_text_length], runtime.runtime_aes_key, nonce))
|
||||
|
@@ -35,6 +35,9 @@ public:
|
||||
CO_FUTURE_GENERATOR_STOP = 0x800000, // 3.5 ->
|
||||
CO_FUTURE_ANNOTATIONS = 0x1000000, // 3.7 ->
|
||||
CO_NO_MONITORING_EVENTS = 0x2000000, // 3.13 ->
|
||||
|
||||
// TODO: Shift things
|
||||
CO_PYARMOR_OBFUSCATED = 0x20000000,
|
||||
};
|
||||
|
||||
PycCode(int type = TYPE_CODE)
|
||||
|
@@ -251,6 +251,75 @@ void PycModule::loadFromMarshalledFile(const char* filename, int major, int mino
|
||||
m_code = LoadObject(&in, this).cast<PycCode>();
|
||||
}
|
||||
|
||||
void PycModule::loadFromOneshotSequenceFile(const char *filename)
|
||||
{
|
||||
PycFile in(filename);
|
||||
if (!in.isOpen())
|
||||
{
|
||||
fprintf(stderr, "Error opening file %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
bool oneshot_seq_header = true;
|
||||
while (oneshot_seq_header)
|
||||
{
|
||||
int indicator = in.getByte();
|
||||
switch (indicator)
|
||||
{
|
||||
case 0xA1:
|
||||
in.getBuffer(16, this->pyarmor_aes_key);
|
||||
break;
|
||||
case 0xA2:
|
||||
in.getBuffer(12, this->pyarmor_mix_str_aes_nonce);
|
||||
break;
|
||||
case 0xF0:
|
||||
break;
|
||||
case 0xFF:
|
||||
oneshot_seq_header = false;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown 1-shot sequence indicator %02X\n", indicator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Write only. Some fields unknown to us or not needed for decryption are discarded.
|
||||
char discard_buffer[64];
|
||||
|
||||
char pyarmor_header[64];
|
||||
in.getBuffer(64, pyarmor_header);
|
||||
this->m_maj = pyarmor_header[9];
|
||||
this->m_min = pyarmor_header[10];
|
||||
this->m_unicode = (m_maj >= 3);
|
||||
|
||||
unsigned int remain_header_length = *(unsigned int *)(pyarmor_header + 28) - 64;
|
||||
while (remain_header_length)
|
||||
{
|
||||
unsigned int discard_length = (remain_header_length > 64) ? 64 : remain_header_length;
|
||||
in.getBuffer(discard_length, discard_buffer);
|
||||
remain_header_length -= discard_length;
|
||||
}
|
||||
|
||||
// For 1-shot sequence, the following part has been decrypted once.
|
||||
unsigned int code_object_offset = in.get32();
|
||||
unsigned int co_code_aes_nonce_xor_key_procedure_length = in.get32();
|
||||
this->pyarmor_co_code_aes_nonce_xor_enabled = (co_code_aes_nonce_xor_key_procedure_length > 0);
|
||||
unsigned int remain_second_part_length = code_object_offset - 8;
|
||||
while (remain_second_part_length)
|
||||
{
|
||||
unsigned int discard_length = (remain_second_part_length > 64) ? 64 : remain_second_part_length;
|
||||
in.getBuffer(discard_length, discard_buffer);
|
||||
remain_second_part_length -= discard_length;
|
||||
}
|
||||
|
||||
if (this->pyarmor_co_code_aes_nonce_xor_enabled)
|
||||
{
|
||||
// TODO: Implement the decryption procedure.
|
||||
}
|
||||
|
||||
m_code = LoadObject(&in, this).cast<PycCode>();
|
||||
}
|
||||
|
||||
PycRef<PycString> PycModule::getIntern(int ref) const
|
||||
{
|
||||
if (ref < 0 || (size_t)ref >= m_interns.size())
|
||||
|
@@ -46,6 +46,7 @@ public:
|
||||
|
||||
void loadFromFile(const char* filename);
|
||||
void loadFromMarshalledFile(const char *filename, int major, int minor);
|
||||
void loadFromOneshotSequenceFile(const char* filename);
|
||||
bool isValid() const { return (m_maj >= 0) && (m_min >= 0); }
|
||||
|
||||
int majorVer() const { return m_maj; }
|
||||
@@ -87,6 +88,11 @@ private:
|
||||
int m_maj, m_min;
|
||||
bool m_unicode;
|
||||
|
||||
char pyarmor_aes_key[16];
|
||||
char pyarmor_mix_str_aes_nonce[12];
|
||||
bool pyarmor_co_code_aes_nonce_xor_enabled;
|
||||
char pyarmor_co_code_aes_nonce_xor_key[12];
|
||||
|
||||
PycRef<PycCode> m_code;
|
||||
std::vector<PycRef<PycString>> m_interns;
|
||||
std::vector<PycRef<PycObject>> m_refs;
|
||||
|
@@ -23,7 +23,7 @@ static const char* flag_names[] = {
|
||||
"CO_FUTURE_PRINT_FUNCTION", "CO_FUTURE_UNICODE_LITERALS", "CO_FUTURE_BARRY_AS_BDFL",
|
||||
"CO_FUTURE_GENERATOR_STOP",
|
||||
"CO_FUTURE_ANNOTATIONS", "CO_NO_MONITORING_EVENTS", "<0x4000000>", "<0x8000000>",
|
||||
"<0x10000000>", "<0x20000000>", "<0x40000000>", "<0x80000000>"
|
||||
"<0x10000000>", "CO_PYARMOR_OBFUSCATED", "<0x40000000>", "<0x80000000>"
|
||||
};
|
||||
|
||||
static void print_coflags(unsigned long flags, std::ostream& pyc_output)
|
||||
|
Reference in New Issue
Block a user