wip: co_flags
This commit is contained in:
@@ -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).
|
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/).
|
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/).
|
||||||
|
|
||||||
|
@@ -101,7 +101,7 @@ def main():
|
|||||||
)
|
)
|
||||||
logger = logging.getLogger('shot')
|
logger = logging.getLogger('shot')
|
||||||
|
|
||||||
print('''
|
print(r'''
|
||||||
____ ____
|
____ ____
|
||||||
( __ ) ( __ )
|
( __ ) ( __ )
|
||||||
| |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| |
|
| |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| |
|
||||||
@@ -157,8 +157,12 @@ def main():
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with open(file_path, 'rb') as f:
|
try:
|
||||||
beacon = f.read(16 * 1024 * 1024)
|
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?
|
# is UTF-8 source?
|
||||||
# TODO: only support natural one line now
|
# TODO: only support natural one line now
|
||||||
|
@@ -64,11 +64,14 @@ void PycCode::load(PycData* stream, PycModule* mod)
|
|||||||
else
|
else
|
||||||
m_flags = 0;
|
m_flags = 0;
|
||||||
|
|
||||||
|
bool pyarmor_co_obfuscated_flag = m_flags & 0x20000000;
|
||||||
|
|
||||||
if (mod->verCompare(3, 8) < 0) {
|
if (mod->verCompare(3, 8) < 0) {
|
||||||
// Remap flags to new values introduced in 3.8
|
// Remap flags to new values introduced in 3.8
|
||||||
if (m_flags & 0xF0000000)
|
// Pyarmor CO_OBFUSCATED flag always locates at 0x20000000
|
||||||
throw std::runtime_error("Cannot remap unexpected flags");
|
if (m_flags & 0xD0000000)
|
||||||
m_flags = (m_flags & 0xFFFF) | ((m_flags & 0xFFF0000) << 4);
|
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>();
|
m_code = LoadObject(stream, mod).cast<PycString>();
|
||||||
|
@@ -36,8 +36,7 @@ public:
|
|||||||
CO_FUTURE_ANNOTATIONS = 0x1000000, // 3.7 ->
|
CO_FUTURE_ANNOTATIONS = 0x1000000, // 3.7 ->
|
||||||
CO_NO_MONITORING_EVENTS = 0x2000000, // 3.13 ->
|
CO_NO_MONITORING_EVENTS = 0x2000000, // 3.13 ->
|
||||||
|
|
||||||
// TODO: Shift things
|
CO_PYARMOR_OBFUSCATED = 0x20000000, // Pyarmor all
|
||||||
CO_PYARMOR_OBFUSCATED = 0x20000000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PycCode(int type = TYPE_CODE)
|
PycCode(int type = TYPE_CODE)
|
||||||
|
@@ -104,7 +104,7 @@ void output_object(PycRef<PycObject> obj, PycModule* mod, int indent,
|
|||||||
unsigned int orig_flags = codeObj->flags();
|
unsigned int orig_flags = codeObj->flags();
|
||||||
if (mod->verCompare(3, 8) < 0) {
|
if (mod->verCompare(3, 8) < 0) {
|
||||||
// Remap flags back to the value stored in the PyCode object
|
// 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);
|
iprintf(pyc_output, indent + 1, "Flags: 0x%08X", orig_flags);
|
||||||
print_coflags(codeObj->flags(), pyc_output);
|
print_coflags(codeObj->flags(), pyc_output);
|
||||||
|
Reference in New Issue
Block a user