Files
Pyarmor-Static-Unpack-1shot/pyc_module.cpp

261 lines
5.4 KiB
C++
Raw Normal View History

2011-10-23 17:48:10 -07:00
#include "pyc_module.h"
2009-07-24 08:35:21 +00:00
#include "data.h"
#include <stdexcept>
2009-07-24 08:35:21 +00:00
void PycModule::setVersion(unsigned int magic)
{
// Default for versions that don't support unicode selection
m_unicode = false;
switch (magic) {
case MAGIC_1_0:
m_maj = 1;
m_min = 0;
break;
case MAGIC_1_1:
m_maj = 1;
m_min = 1;
break;
case MAGIC_1_3:
m_maj = 1;
m_min = 3;
break;
case MAGIC_1_4:
m_maj = 1;
m_min = 4;
break;
case MAGIC_1_5:
m_maj = 1;
m_min = 5;
break;
/* Starting with 1.6, Python adds +1 for unicode mode (-U) */
case MAGIC_1_6+1:
m_unicode = true;
/* Fall through */
case MAGIC_1_6:
m_maj = 1;
m_min = 6;
break;
case MAGIC_2_0+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_0:
m_maj = 2;
m_min = 0;
break;
case MAGIC_2_1+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_1:
m_maj = 2;
m_min = 1;
break;
case MAGIC_2_2+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_2:
m_maj = 2;
m_min = 2;
break;
case MAGIC_2_3+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_3:
m_maj = 2;
m_min = 3;
break;
case MAGIC_2_4+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_4:
m_maj = 2;
m_min = 4;
break;
case MAGIC_2_5+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_5:
m_maj = 2;
m_min = 5;
break;
case MAGIC_2_6+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_6:
m_maj = 2;
m_min = 6;
break;
case MAGIC_2_7+1:
m_unicode = true;
/* Fall through */
case MAGIC_2_7:
m_maj = 2;
m_min = 7;
2010-09-02 01:01:05 -07:00
break;
2009-07-24 08:35:21 +00:00
/* 3.0 and above are always unicode */
case MAGIC_3_0+1:
m_maj = 3;
m_min = 0;
m_unicode = true;
break;
case MAGIC_3_1+1:
m_maj = 3;
m_min = 1;
m_unicode = true;
break;
2011-01-06 17:15:48 -08:00
/* 3.2 stops using the unicode increment */
case MAGIC_3_2:
m_maj = 3;
m_min = 2;
m_unicode = true;
break;
2012-05-26 13:50:23 -07:00
case MAGIC_3_3:
m_maj = 3;
m_min = 3;
m_unicode = true;
break;
case MAGIC_3_4:
m_maj = 3;
m_min = 4;
m_unicode = true;
break;
2015-10-01 16:06:09 -07:00
case MAGIC_3_5:
/* fall through */
case MAGIC_3_5_3:
2015-10-01 16:06:09 -07:00
m_maj = 3;
m_min = 5;
m_unicode = true;
break;
case MAGIC_3_6:
m_maj = 3;
m_min = 6;
m_unicode = true;
break;
case MAGIC_3_7:
m_maj = 3;
m_min = 7;
m_unicode = true;
break;
case MAGIC_3_8:
m_maj = 3;
m_min = 8;
m_unicode = true;
break;
case MAGIC_3_9:
m_maj = 3;
m_min = 9;
m_unicode = true;
break;
2021-04-12 11:03:36 -07:00
2021-10-10 00:52:41 +05:30
case MAGIC_3_10:
m_maj = 3;
m_min = 10;
m_unicode = true;
break;
2021-04-12 11:03:36 -07:00
2009-07-24 08:35:21 +00:00
/* Bad Magic detected */
default:
m_maj = -1;
m_min = -1;
}
}
bool PycModule::isSupportedVersion(int major, int minor)
{
switch (major) {
case 1:
return (minor >= 0 && minor <= 6);
case 2:
return (minor >= 0 && minor <= 7);
case 3:
return (minor >= 0 && minor <= 10);
default:
return false;
}
}
2009-07-24 08:35:21 +00:00
void PycModule::loadFromFile(const char* filename)
{
PycFile in(filename);
if (!in.isOpen()) {
fprintf(stderr, "Error opening file %s\n", filename);
return;
}
setVersion(in.get32());
if (!isValid()) {
fputs("Bad MAGIC!\n", stderr);
2009-07-24 08:35:21 +00:00
return;
}
int flags = 0;
if (verCompare(3, 7) >= 0)
flags = in.get32();
if (flags & 0x1) {
// Optional checksum added in Python 3.7
in.get32();
in.get32();
} else {
in.get32(); // Timestamp -- who cares?
if (verCompare(3, 3) >= 0)
in.get32(); // Size parameter added in Python 3.3
}
2012-05-26 13:50:23 -07:00
m_code = LoadObject(&in, this).require_cast<PycCode>();
2009-07-24 08:35:21 +00:00
}
2022-06-16 12:49:04 +01:00
void PycModule::loadFromMarshalledFile(const char* filename, int major, int minor)
{
PycFile in (filename);
if (!in.isOpen()) {
fprintf(stderr, "Error opening file %s\n", filename);
return;
}
if (!isSupportedVersion(major, minor)) {
fprintf(stderr, "Unsupported version %d.%d\n", major, minor);
return;
}
m_maj = major;
m_min = minor;
m_unicode = (major >= 3);
m_code = LoadObject(&in, this).require_cast<PycCode>();
}
PycRef<PycString> PycModule::getIntern(int ref) const
2009-07-24 08:35:21 +00:00
{
if (ref < 0)
throw std::out_of_range("Intern index out of range");
auto it = m_interns.cbegin();
while (ref-- && it != m_interns.cend())
++it;
if (it == m_interns.cend())
throw std::out_of_range("Intern index out of range");
return *it;
}
PycRef<PycObject> PycModule::getRef(int ref) const
{
if (ref < 0)
throw std::out_of_range("Ref index out of range");
auto it = m_refs.cbegin();
while (ref-- && it != m_refs.cend())
++it;
if (it == m_refs.cend())
throw std::out_of_range("Ref index out of range");
2009-07-24 08:35:21 +00:00
return *it;
}