Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat[junk-code]support remove jump-abs junk #266

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,20 @@
*.kdev4
/.kdev4
__pycache__
/bytes
/CMake*
/Debug
/.vs
ALL_BUILD*
*.vcxproj
*.filter
*.filters
*.recipe
*.log
*.tlog
*.obj
*.exe
*.pdb
*.txt
*.ilk
*.sln
24 changes: 19 additions & 5 deletions ASTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,15 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
}
break;
}

// should check if stack_history has any item,if empty ,that count be a `junkcode-absjump`
if (!stack_hist.size()) {
// reset to next byte of JUMP_ABS
for (int i = 0; i < 4; i++) {
pos++;
source.getByte();
}
break;
}
stack = stack_hist.top();
stack_hist.pop();

Expand Down Expand Up @@ -2808,10 +2816,16 @@ void print_src(PycRef<ASTNode> node, PycModule* mod, std::ostream& pyc_output)
auto map = new ASTMap;
for (const auto& key : keys) {
// Values are pushed onto the stack in reverse order.
PycRef<ASTNode> value = values.back();
values.pop_back();
if (values.size() > 0) {
PycRef<ASTNode> value = values.back();
values.pop_back();
map->add(new ASTObject(key), value);
}
else {
map->add(new ASTObject(key), PycRef<ASTNode>());
}

map->add(new ASTObject(key), value);

}

print_src(map, mod, pyc_output);
Expand Down Expand Up @@ -3341,7 +3355,7 @@ void decompyle(PycRef<PycCode> code, PycModule* mod, std::ostream& pyc_output)
clean->removeFirst();
}
}
if (clean->nodes().back().type() == ASTNode::NODE_RETURN) {
if (clean->nodes().size() && clean->nodes().back().type() == ASTNode::NODE_RETURN) {
PycRef<ASTReturn> ret = clean->nodes().back().cast<ASTReturn>();

if (ret->value() == NULL || ret->value().type() == ASTNode::NODE_LOCALS) {
Expand Down
74 changes: 38 additions & 36 deletions pyc_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,60 @@
#include "pyc_module.h"
#include "data.h"
#include <stdexcept>
#include <wchar.h>

static bool check_ascii(const std::string& data)
{
auto cp = reinterpret_cast<const unsigned char*>(data.c_str());
while (*cp) {
if (*cp & 0x80)
return false;
++cp;
}
return true;
auto cp = reinterpret_cast<const unsigned char*>(data.c_str());
while (*cp) {
if (*cp & 0x80)
return false;
++cp;
}
return true;
}

/* PycString */
void PycString::load(PycData* stream, PycModule* mod)
{
if (type() == TYPE_STRINGREF) {
PycRef<PycString> str = mod->getIntern(stream->get32());
m_type = str->m_type;
m_value = str->m_value;
} else {
int length;
if (type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED)
length = stream->getByte();
else
length = stream->get32();
if (type() == TYPE_STRINGREF) {
PycRef<PycString> str = mod->getIntern(stream->get32());
m_type = str->m_type;
m_value = str->m_value;
}
else {
int length;
if (type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED)
length = stream->getByte();
else
length = stream->get32();

if (length < 0)
throw std::bad_alloc();
if (length < 0)
throw std::bad_alloc();

m_value.resize(length);
if (length) {
stream->getBuffer(length, &m_value.front());
if (type() == TYPE_ASCII || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED) {
if (!check_ascii(m_value))
throw std::runtime_error("Invalid bytes in ASCII string");
}
}
m_value.resize(length);
if (length) {
stream->getBuffer(length, &m_value.front());
if (type() == TYPE_ASCII || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED) {
if (!check_ascii(m_value))
throw std::runtime_error("Invalid bytes in ASCII string");
}
}

if (type() == TYPE_INTERNED || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII_INTERNED)
mod->intern(this);
}
if (type() == TYPE_INTERNED || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII_INTERNED)
mod->intern(this);
}
}

bool PycString::isEqual(PycRef<PycObject> obj) const
{
if (type() != obj.type())
return false;
if (type() != obj.type())
return false;

PycRef<PycString> strObj = obj.cast<PycString>();
return isEqual(strObj->m_value);
PycRef<PycString> strObj = obj.cast<PycString>();
return isEqual(strObj->m_value);
}

void PycString::print(std::ostream &pyc_output, PycModule* mod, bool triple,
Expand Down
2 changes: 1 addition & 1 deletion pycdc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ int main(int argc, char* argv[])
}
const char* dispname = strrchr(infile, PATHSEP);
dispname = (dispname == NULL) ? infile : dispname + 1;
*pyc_output << "# Source Generated with Decompyle++\n";
*pyc_output << "# Source Generated with Decompyle++ , apply in pydumpck\n";
formatted_print(*pyc_output, "# File: %s (Python %d.%d%s)\n\n", dispname,
mod.majorVer(), mod.minorVer(),
(mod.majorVer() < 3 && mod.isUnicode()) ? " Unicode" : "");
Expand Down