i make a anti pycdc so ez with a loop
antipycdc = ""
for i in range(10000):
antipycdc += "1/int(0),"
antipycdc = "try:ngocuyencoder=(" + antipycdc + ")\nexcept:pass"
ANTI_PYCDC = f"""
try:pass
except:pass
else:pass
finally:pass
{antipycdc}
finally:int(2008-2006)
"""
print(ANTI_PYCDC)
#compile it to pyc and see a segment fault (>3.11 version)
when i custom a astree.cpp to bypass this , this break a code structure and it make a file to > 100mb
lol
I tried to reproduce the issue myself, it's OK on python 3.10, then I tried 3.12 but -
@hngocuyen did you implement yourself the missed JUMP_BACKWARD opcode? it's not present in the main baseline...
./pycdc __pycache__/py_loop.cpython-312.pyc
# Source Generated with Decompyle++
# File: py_loop.cpython-312.pyc (Python 3.12)
Unsupported opcode: JUMP_BACKWARD (226)
antipycdc = ''
# WARNING: Decompyle incomplete
@greenozon not compile a
antipycdc = ""
for i in range(10000):
antipycdc += "1/int(0),"
antipycdc = "try:ngocuyencoder=(" + antipycdc + ")\nexcept:pass"
ANTI_PYCDC = f"""
try:pass
except:pass
else:pass
finally:pass
{antipycdc}
finally:int(2008-2006)
"""
print(ANTI_PYCDC)
#compile it to pyc and see a segment fault (>3.11 version)
only compile all in ANTI_PYCDC mean
try:pass
except:pass
else:pass
finally:pass
try:ngocuyencoder=((1/int(0),1/int(0),1..............vv)
finally:int(2008-2006)
and compile to pyc
or u can compile it if python >= 3.11
try:pass
except:pass
else:pass
finally:pass
Segmentation fault
i think you guys already know this bug, maybe it's just an open source project and it's free so u dont fix it, but thanks for this project , love.
and for the jump_backward i add like this in astree.cpp
case Pyc::JUMP_BACKWARD_A:
{
int delta = operand;
if (mod->verCompare(3, 10) >= 0) {
delta *= sizeof(uint16_t);
}
int offs = pos - delta;
if (curblock->blktype() == ASTBlock::BLK_FOR) {
bool is_jump_to_start = offs == curblock.cast<ASTIterBlock>()->start();
bool should_pop_for_block = curblock.cast<ASTIterBlock>()->isComprehension();
bool should_add_for_block = mod->majorVer() == 3 && mod->minorVer() >= 8 && is_jump_to_start && !curblock.cast<ASTIterBlock>()->isComprehension();
if (should_pop_for_block || should_add_for_block) {
PycRef<ASTNode> top = stack.top();
if (top.type() == ASTNode::NODE_COMPREHENSION) {
PycRef<ASTComprehension> comp = top.cast<ASTComprehension>();
comp->addGenerator(curblock.cast<ASTIterBlock>());
}
PycRef<ASTBlock> tmp = curblock;
blocks.pop();
curblock = blocks.top();
if (should_add_for_block) {
curblock->append(tmp.cast<ASTNode>());
}
}
} else if (curblock->blktype() == ASTBlock::BLK_ELSE) {
stack = stack_hist.top();
stack_hist.pop();
blocks.pop();
blocks.top()->append(curblock.cast<ASTNode>());
curblock = blocks.top();
if (curblock->blktype() == ASTBlock::BLK_CONTAINER
&& !curblock.cast<ASTContainerBlock>()->hasFinally()) {
blocks.pop();
blocks.top()->append(curblock.cast<ASTNode>());
curblock = blocks.top();
}
} else {
curblock->append(new ASTKeyword(ASTKeyword::KW_CONTINUE));
}
break;
}
in astnode.h
enum ConversionFlag {
NONE = 0,
STR = 1,
REPR = 2,
ASCII = 3,
CONVERSION_MASK = 0x03,
HAVE_FMT_SPEC = 4,
FMTSPEC = 4, # idk but when i add it , opcode is work
};
@greenozon not compile a
antipycdc = ""
for i in range(10000): antipycdc += "1/int(0),"
antipycdc = "try:ngocuyencoder=(" + antipycdc + ")\nexcept:pass"
ANTI_PYCDC = f""" try:pass except:pass else:pass finally:pass {antipycdc} finally:int(2008-2006) """ print(ANTI_PYCDC) #compile it to pyc and see a segment fault (>3.11 version)
only compile all in ANTI_PYCDC mean
try:pass except:pass else:pass finally:pass try:ngocuyencoder=((1/int(0),1/int(0),1..............vv) finally:int(2008-2006)
and compile to pyc
or u can compile it if python >= 3.11
try:pass except:pass else:pass finally:pass
Segmentation fault
i think you guys already know this bug, maybe it's just an open source project and it's free so u dont fix it, but thanks for this project , love.
or maybe people just fix what they need when they do reverse engineering and that's not a common thing for programmers to do. for example, there are a lot of missing OPCodes for Python3.13 that I'm fixing and will soon make a PR, its not all of them because I don't need all of them.
This tool seems to be an advanced user tool for those who do reverse engineering, any sort of counter-measure you implement is going to be trivially reversed with the way python works. I would focus your anti-reversing protection on just making the labels unreadable, as they do on APKs when they're published to Google store. Trying to implement any sort of instruction rewriting to make reverse-engineer tools crash is sort of pointless, what you need to do is just make the effort of reversing cost more, getting rid of most strings is enough for that. I know you're an young guy, but professionally you should pay more attention to other things than trying to prevent people from reversing your software, if they want to do, there's nothing you can do to prevent sort of never distributing the executable and running it as a SaaS. As a fun experiment, that's totally fine.