`context.bits` will not automatically switch when setting `context.arch` twice.
I was using IPython to do some quick poc work that time, first I switched
context.archto'amd64'and assembledcdqeand then I suddenly would like to try what if I assemblecdqein 32-bit mode. So I switchedcontext.archback to'i386'and wanted to assemble, only to find an error:AttributeError: Invalid arch/bits combination: i386/64
Pwntools may can not handle context.arch correctly, it could change context.bits accordingly when first setting it. However, when setting context.arch the second time, context.bits left unchanged. I guess this bug is related to self._tls?
poc:
one more poc:
from pwn import *
print(f"{context.arch}/{context.bits}")
context.arch = 'amd64'
print(f"{context.arch}/{context.bits}")
context.arch = 'i386'
print(f"{context.arch}/{context.bits}")
BTW, the document has a wrong source code reference. When clicking on property arch [source], it jumps to file /pwnlib/context.py, which don't exist. The correct file should be pwnlib/context/__init__.py.
This is actually a feature to keep manual context changes instead of silently overwriting values using those smart attributes like arch. arch changes bits and endian too, so the idea is to keep the old bits value if it was changed before:
>>> context.bits = 24
>>> context.arch = 'amd64'
>>> context.bits
24
We could special case setting bits and endian through arch and not protect them from changes through arch again? Sounds like that's what most users want. We should only retain the old value if it was set explicitly like in the example above.
That's right. Consider adding an "explicit flag", set it only when user explicitly set context.bits by method. When switching context.arch, set property directly, so that the flag won't be modified.