wip: co_flags

This commit is contained in:
2025-02-28 16:56:15 +08:00
parent 21785687b6
commit dacfd29c02
5 changed files with 16 additions and 10 deletions

View File

@@ -4,7 +4,7 @@
Generally this project aims to statically convert (without executing) armored data - which can be regarded as an encrypted variant of pyc files - back to disassembly and (experimentally) source code. Therefore we forked the awesome [Decompyle++](https://github.com/zrax/pycdc) (aka pycdc).
Currently we are trying to support Pyarmor 8.0 - latest (9.0.8), Python 3.6 - 3.13, platforms covering Windows, Linux, macOS, and Android, with obfuscating options as many as possible. (However, we only have limited tests.)
Currently we are trying to support Pyarmor 8.0 - latest (9.1.0), Python 3.7 - 3.13, platforms covering Windows, Linux, macOS, and Android, with obfuscating options as many as possible. (However, we only have limited tests.)
We cannot wait to make it public. Detailed write-up will be available soon. For those who are curious, temporarily you can check out [the similar work of G DATA Advanced Analytics](https://cyber.wtf/2025/02/12/unpacking-pyarmor-v8-scripts/).

View File

@@ -101,7 +101,7 @@ def main():
)
logger = logging.getLogger('shot')
print('''
print(r'''
____ ____
( __ ) ( __ )
| |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| |
@@ -157,8 +157,12 @@ def main():
except:
pass
with open(file_path, 'rb') as f:
beacon = f.read(16 * 1024 * 1024)
try:
with open(file_path, 'rb') as f:
beacon = f.read(16 * 1024 * 1024)
except:
logger.error(f'Failed to read file: {relative_path}')
continue
# is UTF-8 source?
# TODO: only support natural one line now

View File

@@ -64,11 +64,14 @@ void PycCode::load(PycData* stream, PycModule* mod)
else
m_flags = 0;
bool pyarmor_co_obfuscated_flag = m_flags & 0x20000000;
if (mod->verCompare(3, 8) < 0) {
// Remap flags to new values introduced in 3.8
if (m_flags & 0xF0000000)
throw std::runtime_error("Cannot remap unexpected flags");
m_flags = (m_flags & 0xFFFF) | ((m_flags & 0xFFF0000) << 4);
// Pyarmor CO_OBFUSCATED flag always locates at 0x20000000
if (m_flags & 0xD0000000)
fprintf(stderr, "Remapping flags (%08X) may not be correct\n", m_flags);
m_flags = (m_flags & 0x1FFF) | ((m_flags & 0xFFFE000) << 4) | (m_flags & 0x20000000);
}
m_code = LoadObject(stream, mod).cast<PycString>();

View File

@@ -36,8 +36,7 @@ public:
CO_FUTURE_ANNOTATIONS = 0x1000000, // 3.7 ->
CO_NO_MONITORING_EVENTS = 0x2000000, // 3.13 ->
// TODO: Shift things
CO_PYARMOR_OBFUSCATED = 0x20000000,
CO_PYARMOR_OBFUSCATED = 0x20000000, // Pyarmor all
};
PycCode(int type = TYPE_CODE)

View File

@@ -104,7 +104,7 @@ void output_object(PycRef<PycObject> obj, PycModule* mod, int indent,
unsigned int orig_flags = codeObj->flags();
if (mod->verCompare(3, 8) < 0) {
// Remap flags back to the value stored in the PyCode object
orig_flags = (orig_flags & 0xFFFF) | ((orig_flags & 0xFFF00000) >> 4);
orig_flags = (orig_flags & 0x1FFF) | ((orig_flags & 0xDFFE0000) >> 4) | (orig_flags & 0x20000000);
}
iprintf(pyc_output, indent + 1, "Flags: 0x%08X", orig_flags);
print_coflags(codeObj->flags(), pyc_output);