逆向工程一个用“freeze”编译的python mac应用程序

逆向工程 Python
2021-07-11 01:14:44

(注)我已经看过这篇文章:用 Python 编写的逆向工程程序,用“freeze”编译

有谁知道如何使用 PyCommand 但使用 mac 应用程序执行上述链接中的操作?我试图逆向工程的程序是使用完全相同的程序编译的,但二进制文件是一个 mac 应用程序。

不幸的是,Immunity Debugger 只能在 Windows 上运行,所以我不能使用 PyCommand(据我所知)。任何帮助表示赞赏,谢谢。

1个回答

根据链接的帖子,您可以使用任何调试器转储使用冻结编译的冻结模块。但是,由于您使用的是 Mac,PyCommand 和 Immunity Debugger 将无法工作。但是,这并不妨碍您按照自己的方式工作。

在非 Windows 操作系统上,您可以使用frida将代码注入正在运行的可执行文件中。由于 frida在进程中注入了javascript,因此需要将python代码转换js

您只需要转储相关的冻结模块,它会像_frozen所有冻结模块的数组一样自动发生


更新

这是使用fridapython 绑定转储冻结模块的脚本该脚本相当便携,应该适用于所有操作系统。您只需要提供相关进程PID,您可以从操作系统的活动监视器/系统监视器/任务管理器中获取PID

import frida, struct, sys

# Magic value of pyc files, The value provided here is for python 2.7
# You can get it by imp.get_magic()
PYTHONMAGIC = '\x03\xF3\x0D\x0A' + '\x00' * 4

# Provide the pid of your process
PID = 2008

# The size of a pointer is 8 bytes on 64 bit OS and 4 on a 32 bit OS
ptr_size = 8 if sys.maxsize > 2**32 else 4

# Name of python shared library
if sys.platform.startswith('linux'):
    lib_name = 'libpython2.7.so'
elif sys.platform.startswith('darwin'):
    lib_name = 'libpython2.7.dylib'
elif sys.platform.startswith('win32'):
    lib_name = 'python27.dll'
else:
    raise Exception('Unsupported platform')


session = frida.attach(PID)
export_va = 0

# Read a null terminated C string or a char array of a given length
def readString(addr, size = 0):
    if size > 0:
        return struct.unpack('@{}s'.format(size) , session.read_bytes(addr, size))[0]
    elif size == 0:
        s = ''
        while True:
            ch, = struct.unpack('@c', session.read_bytes(addr, 1))
            addr += 1
            if ch == '\x00':
                break
            else:
                s += ch
        return s
    else:
        return ''


modules = session.enumerate_modules()
for module in modules:
    if module.name == lib_name:
        exports = module.enumerate_exports()
        for export in exports:
            if export.name == 'PyImport_FrozenModules':
                export_va = module.base_address + export.relative_address
                break
    if export_va != 0:
        break


if export_va == 0:
    raise Exception("Could not get export address of PyImport_FrozenModules")

structAddr, = struct.unpack_from('@P', session.read_bytes(export_va , ptr_size))

while True:
    ptrToName, ptrToCode, sizeOfCode = struct.unpack_from('@PPi', session.read_bytes(structAddr, ptr_size * 2 + 4))
    structAddr += ptr_size * 2 + 4

    # The array is terminated by a structure whose members are null
    if ptrToName == 0 and ptrToCode == 0 and sizeOfCode == 0:
        break

    moduleName = readString(ptrToName)
    moduleCode = readString(ptrToCode, sizeOfCode)

    # You can change the output path here
    with open(moduleName + '.pyc', 'wb') as f:
        f.write(PYTHONMAGIC + moduleCode)

print '[*] Frozen modules dumped'