├── obfusc ├── pre.cpp ├── ToDo.txt ├── CParser.cc ├── CParser.h ├── Tree.cpp ├── FunctionNode.cpp ├── Tree.h ├── FunctionNode.h ├── NotObfusIdTable.h ├── pre.h ├── ONString.h ├── ONConstant.h ├── NumberExpGenerator.h ├── ONIdentifier.h ├── CodeFile.h ├── TokenTypes.h ├── ONDoWhile.h ├── ONWhile.h ├── IdentifierGenerator.h ├── CodeFile.cpp ├── ONFor.h ├── Symbol.cpp ├── ONBlockItemList.h ├── ArgPack.h ├── RecordTable.cpp ├── NotObfusIdTable.cpp ├── RecordTable.h ├── Obfuscator.h ├── SymbolTable.h ├── ONDoWhile.cpp ├── ExtraString.h ├── CAnalys.h ├── ExtraString.cpp ├── Obfuscator.cpp ├── IObfusNode.h ├── ONWhile.cpp ├── NumberExpGenerator.cpp ├── Symbol.h ├── ONString.cpp ├── ONFor.cpp ├── Node.h ├── IdentifierGenerator.cpp ├── ONIdentifier.cpp ├── ONConstant.cpp ├── main.cc ├── SymbolTable.cpp ├── ArgPack.cpp ├── CAnalys.cc ├── getopt.h ├── obfusc.vcxproj.filters ├── ONBlockItemList.cpp ├── CLexer.l ├── Node.cpp ├── obfusc.vcxproj ├── CLexer.h └── CParser.y ├── binary └── obfusc.exe ├── flex_bison ├── bison++.exe ├── flex++.exe ├── bison.h ├── flexskel.h └── bison.cc ├── obfusc.sln ├── readme.md └── .gitignore /obfusc/pre.cpp: -------------------------------------------------------------------------------- 1 | #include "pre.h" 2 | 3 | -------------------------------------------------------------------------------- /obfusc/ToDo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavxin/CSCO/HEAD/obfusc/ToDo.txt -------------------------------------------------------------------------------- /binary/obfusc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavxin/CSCO/HEAD/binary/obfusc.exe -------------------------------------------------------------------------------- /obfusc/CParser.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavxin/CSCO/HEAD/obfusc/CParser.cc -------------------------------------------------------------------------------- /obfusc/CParser.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavxin/CSCO/HEAD/obfusc/CParser.h -------------------------------------------------------------------------------- /flex_bison/bison++.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavxin/CSCO/HEAD/flex_bison/bison++.exe -------------------------------------------------------------------------------- /flex_bison/flex++.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavxin/CSCO/HEAD/flex_bison/flex++.exe -------------------------------------------------------------------------------- /obfusc/Tree.cpp: -------------------------------------------------------------------------------- 1 | #include "Tree.h" 2 | 3 | Tree::Tree(void) 4 | { 5 | //isEnd = false; 6 | } 7 | 8 | Tree::~Tree(void) 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /obfusc/FunctionNode.cpp: -------------------------------------------------------------------------------- 1 | #include "FunctionNode.h" 2 | 3 | 4 | //FunctionNode::FunctionNode(void) 5 | //{ 6 | //} 7 | 8 | 9 | FunctionNode::~FunctionNode(void) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /obfusc/Tree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Node.h" 3 | #include "pre.h" 4 | 5 | class Tree : public Node 6 | { 7 | public: 8 | Tree(void); 9 | ~Tree(void); 10 | 11 | // is End analysis. 12 | //bool isEnd; 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /obfusc/FunctionNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "node.h" 5 | class FunctionNode : 6 | public Node 7 | { 8 | public: 9 | //FunctionNode(void); 10 | ~FunctionNode(void); 11 | 12 | // function name; 13 | string functionName; 14 | // full string with function type, args. 15 | string functionDefineString; 16 | 17 | 18 | }; -------------------------------------------------------------------------------- /obfusc/NotObfusIdTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | using namespace std; 4 | 5 | class NotObfusIdTable 6 | { 7 | public: 8 | NotObfusIdTable(void); 9 | ~NotObfusIdTable(void); 10 | 11 | vector idList; 12 | 13 | void AddId(string name); 14 | bool hasId(string name); 15 | bool InputNotObfusIdFile(string path); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /obfusc/pre.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | //#include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include -------------------------------------------------------------------------------- /obfusc/ONString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "iobfusnode.h" 5 | class ONString : 6 | public IObfusNode 7 | { 8 | private: 9 | // convert string like this 10 | // "\x64\x69\x66\x66\x73\x74\x61\x74\x20\x76\x65\x72\x73\x69\x6f\x6e\x20\x25\x73" 11 | string Convert2HexStyle(string str); 12 | public: 13 | ONString(void); 14 | ~ONString(void); 15 | bool JudgeType(Node *node); 16 | void Action(Node *node); 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /obfusc/ONConstant.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "iobfusnode.h" 5 | 6 | 7 | // this class will obfuscate the CONSTANT node. 8 | 9 | class ONConstant : 10 | public IObfusNode 11 | { 12 | public: 13 | ONConstant(void); 14 | ~ONConstant(void); 15 | bool JudgeType(Node *node); 16 | void Action(Node *node); 17 | bool getConstantValue(string str,double *value); 18 | //static string Contant2String(double constant); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /obfusc/NumberExpGenerator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | using namespace std; 4 | 5 | class NumberExpGenerator; 6 | class NumberExpGenerator 7 | { 8 | private: 9 | static NumberExpGenerator instance; 10 | 11 | string int2hexStr(int value); 12 | string int2octStr(int value); 13 | 14 | public: 15 | NumberExpGenerator(void); 16 | ~NumberExpGenerator(void); 17 | 18 | static NumberExpGenerator& get() 19 | { 20 | return instance; 21 | }; 22 | 23 | string Generate(double num); 24 | 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /obfusc/ONIdentifier.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | #include "IObfusNode.h" 4 | #include "NotObfusIdTable.h" 5 | 6 | class ONIdentifier : 7 | public IObfusNode 8 | { 9 | public: 10 | ONIdentifier(void); 11 | ~ONIdentifier(void); 12 | 13 | static const int ID_LEN=8; 14 | // see the node type if it is the type which this class to obfuscate. 15 | bool JudgeType(Node *node); 16 | // main function. Obufuscator will call this function 17 | void Action(Node *node); 18 | 19 | string GenerateIdentifier(); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /obfusc/CodeFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | #include "Tree.h" 4 | #include "SymbolTable.h" 5 | 6 | class CodeFile 7 | { 8 | public: 9 | //CodeFile(void); 10 | CodeFile(string name, string out, bool isRemoveTypeset); 11 | ~CodeFile(void); 12 | bool isError; 13 | // file name 14 | string filename; 15 | // output file name 16 | string outputfilename; 17 | 18 | // FILE *p 19 | FILE *file; 20 | 21 | Tree *tree; 22 | SymbolTable *symbolTable; 23 | // is remove typeset. 24 | bool isRemoveTypeset; 25 | 26 | string Output(); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /obfusc/TokenTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | #include "ExtraString.h" 4 | 5 | using namespace std; 6 | 7 | typedef struct { 8 | int first_line,last_line,first_column,last_column; 9 | char *text; 10 | // store the TOKEN type; 11 | int tokenId; 12 | // the Text String of the TOKEN 13 | string theText; 14 | // the String before the Text. usually spaces & tab & \n. 15 | string preString; 16 | // advanced preString. 17 | ExtraString *extraString; 18 | } TokenLocation; 19 | 20 | typedef struct { 21 | int first_line,last_line,first_column,last_column; 22 | } SymbolLocation; -------------------------------------------------------------------------------- /obfusc/ONDoWhile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "iobfusnode.h" 3 | 4 | // before Obfuscated 5 | /* 6 | do 7 | instr 8 | while (expr) 9 | */ 10 | // after Obfuscated 11 | /* 12 | l_continue: 13 | instr; 14 | if (expr) 15 | goto l_continue; 16 | l_break: 17 | */ 18 | class ONDoWhile : 19 | public IObfusNode 20 | { 21 | private: 22 | bool isRemoveTypeset; 23 | public: 24 | ONDoWhile(bool); 25 | ~ONDoWhile(void); 26 | 27 | // see the node type if it is the type which this class to obfuscate. 28 | bool JudgeType(Node *node); 29 | // main function. Obufuscator will call this function 30 | void Action(Node *node); 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /obfusc/ONWhile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "iobfusnode.h" 3 | 4 | 5 | // before Obfuscated 6 | /* 7 | WHILE '(' expression ')' 8 | statement 9 | */ 10 | // after Obfuscated 11 | /* 12 | l_continue: 13 | if (!(expr)) 14 | goto l_break; 15 | instr; 16 | goto l_continue; 17 | l_break: 18 | */ 19 | class ONWhile : 20 | public IObfusNode 21 | { 22 | private: 23 | bool isRemoveTypeset; 24 | public: 25 | ONWhile(bool); 26 | ~ONWhile(void); 27 | 28 | // see the node type if it is the type which this class to obfuscate. 29 | bool JudgeType(Node *node); 30 | // main function. Obufuscator will call this function 31 | void Action(Node *node); 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /obfusc/IdentifierGenerator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | using namespace std; 4 | 5 | class IdentifierGenerator; 6 | 7 | class IdentifierGenerator 8 | { 9 | private: 10 | static IdentifierGenerator instance; 11 | static const int ID_MIN_LEN = 8; 12 | public: 13 | IdentifierGenerator(void); 14 | ~IdentifierGenerator(void); 15 | 16 | static IdentifierGenerator& get() 17 | { 18 | return instance; 19 | }; 20 | 21 | // the identifier name length. 22 | int idLength; 23 | // 24 | enum IdLookLike { LL_NORMAL, LL_O0, LL_l1, LL_CUSTOM } idLookLike; 25 | // custom char table. 26 | string custom; 27 | 28 | string Generate(); 29 | 30 | void SetSymbolNum(int num); 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /obfusc/CodeFile.cpp: -------------------------------------------------------------------------------- 1 | #include "CodeFile.h" 2 | 3 | 4 | //CodeFile::CodeFile(void) 5 | //{ 6 | // symbolTable = new SymbolTable(); 7 | //} 8 | 9 | 10 | CodeFile::~CodeFile(void) 11 | { 12 | } 13 | 14 | CodeFile::CodeFile(string name, string out, bool isRemoveTypeset) : 15 | isError(false), 16 | filename(name), 17 | outputfilename(out), 18 | isRemoveTypeset(isRemoveTypeset) 19 | { 20 | // open file. 21 | errno_t err; 22 | if ( (err=fopen_s(&file, name.c_str(), "r") ) != 0 ) { 23 | cout << "can't open file:" << name << endl; 24 | isError = true; 25 | } 26 | 27 | symbolTable = new SymbolTable(); 28 | } 29 | 30 | string CodeFile::Output() 31 | { 32 | return tree->ToSourceCode(isRemoveTypeset) + "\n"; 33 | } -------------------------------------------------------------------------------- /obfusc/ONFor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "iobfusnode.h" 3 | 4 | // before Obfuscated 5 | /* 6 | for (expr1; expr2; expr3) 7 | instr 8 | */ 9 | // after Obfuscated 10 | /* 11 | expr1; 12 | l_loop: 13 | if (!(expr2)) 14 | goto l_break; 15 | goto l_instr; 16 | l_continue: 17 | expr3; 18 | goto l_loop; 19 | l_instr: 20 | instr; 21 | goto l_continue; 22 | l_break:; 23 | */ 24 | 25 | 26 | class ONFor : 27 | public IObfusNode 28 | { 29 | private: 30 | bool isRemoveTypeset; 31 | public: 32 | ONFor(bool); 33 | ~ONFor(void); 34 | 35 | // see the node type if it is the type which this class to obfuscate. 36 | bool JudgeType(Node *node); 37 | // main function. Obufuscator will call this function 38 | void Action(Node *node); 39 | }; 40 | 41 | -------------------------------------------------------------------------------- /obfusc/Symbol.cpp: -------------------------------------------------------------------------------- 1 | #include "Symbol.h" 2 | 3 | 4 | Symbol::Symbol(void) 5 | { 6 | } 7 | 8 | 9 | Symbol::~Symbol(void) 10 | { 11 | } 12 | 13 | Symbol::Symbol(string name) : 14 | name(name),type(Symbol::IDENTIFIER),isDeclared(false),isObfusced(false) 15 | { 16 | 17 | } 18 | 19 | Symbol::Symbol(string name, SymbolType type) : 20 | name(name),type(type),isDeclared(false),isObfusced(false) 21 | { 22 | 23 | } 24 | // addLocation 25 | void Symbol::addLocation(int first_line, int first_column, int last_line, int last_column) 26 | { 27 | SymbolLocation l; 28 | l.first_line = first_line; 29 | l.first_column = first_column; 30 | l.last_column = last_column; 31 | l.last_line = last_line; 32 | appearedLocation.push_back(l); 33 | } 34 | // returrn Appeared time 35 | int Symbol::AppearedTime() 36 | { 37 | return (int)appearedLocation.size(); 38 | } -------------------------------------------------------------------------------- /obfusc/ONBlockItemList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "iobfusnode.h" 3 | class ONBlockItemList : 4 | public IObfusNode 5 | { 6 | private: 7 | string globleVar; 8 | string tmpGlobleVar; 9 | string startLable; 10 | string endLable; 11 | vector sequence; 12 | bool isRemoveTypeset; 13 | bool isObfuscateConstant; 14 | int findIndexOfSequence(int value); 15 | public: 16 | ONBlockItemList(bool isRemoveTypeset,bool); 17 | ~ONBlockItemList(void); 18 | 19 | bool JudgeType(Node *node); 20 | void Action(Node *node); 21 | 22 | // if is a statement 23 | bool isStatement(Node *node); 24 | 25 | void AddGlobleVar(); 26 | 27 | void InitAction(); 28 | void GenerateRandomSequence(vector &sequence, int size); 29 | void GenerateRandomStatementBlocks(vector &sn, int blocksize, int numStatement, vector statements); 30 | 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /obfusc/ArgPack.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "IdentifierGenerator.h" 5 | 6 | using namespace std; 7 | class ArgPack 8 | { 9 | public: 10 | ArgPack(int argc, char *const argv []); 11 | ~ArgPack(void); 12 | bool isError; 13 | 14 | // input file. 15 | string input; 16 | // out file. 17 | string output; 18 | 19 | // before-after obfuscated table file 20 | bool isOutputBAfile; 21 | string baFile; 22 | 23 | // Not obfuscate table. 24 | bool isNotObfuscateFile; 25 | string noFile; 26 | 27 | bool isObfuscateConstant; 28 | bool isObfuscateString; 29 | bool isObfuscateIdentifier; 30 | // custom identifier charactor table. 31 | string custom; 32 | bool isRemoveTypeset; 33 | 34 | bool isObfuscateLoopStatement; 35 | bool isObfuscateControlFlow; 36 | 37 | // TYPE_NAME; 38 | bool isTYPE_NAMEFile; 39 | string typeNameFile; 40 | 41 | void useage(char *proc); 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /obfusc/RecordTable.cpp: -------------------------------------------------------------------------------- 1 | #include "RecordTable.h" 2 | 3 | 4 | RecordTable::RecordTable(void) 5 | { 6 | } 7 | 8 | 9 | RecordTable::~RecordTable(void) 10 | { 11 | } 12 | 13 | void RecordTable::AddRecord(string name, string afterName, 14 | int first_line, int first_column, 15 | int last_line, int last_column) 16 | { 17 | Record r(name,afterName,first_line,first_column,last_line,last_column); 18 | list.push_back(r); 19 | } 20 | 21 | string RecordTable::PrintRecordTable(bool hasLocation) 22 | { 23 | string result; 24 | stringstream ss(""); 25 | vector::iterator it; 26 | for ( it=list.begin() ; it!=list.end() ; it++) { 27 | ss << it->name + "\t"; 28 | ss << it->afterName + "\t"; 29 | if ( hasLocation ) { 30 | ss << "(" << it->first_line << "," << it->first_column << "-" 31 | << it->last_line << "," << it->last_column << ")"; 32 | } 33 | ss << endl; 34 | } 35 | result = ss.str(); 36 | return result; 37 | } -------------------------------------------------------------------------------- /obfusc/NotObfusIdTable.cpp: -------------------------------------------------------------------------------- 1 | #include "NotObfusIdTable.h" 2 | 3 | 4 | NotObfusIdTable::NotObfusIdTable(void) 5 | { 6 | idList = vector(); 7 | 8 | this->AddId("main"); 9 | } 10 | 11 | 12 | NotObfusIdTable::~NotObfusIdTable(void) 13 | { 14 | } 15 | 16 | void NotObfusIdTable::AddId(string name) 17 | { 18 | idList.push_back(name); 19 | } 20 | 21 | bool NotObfusIdTable::hasId(string name) 22 | { 23 | vector::iterator it; 24 | for ( it = idList.begin() ; it != idList.end() ; it++ ) { 25 | if ( (*it) == name ) { 26 | return true; 27 | } 28 | } 29 | return false; 30 | } 31 | 32 | bool NotObfusIdTable::InputNotObfusIdFile(string path) 33 | { 34 | ifstream infile(path); 35 | if ( !infile ) { 36 | cerr << "NotObfusIdTable::InputNotObfusIdFile Can't open file: \"" << path << "\"" << endl; 37 | return false; 38 | } 39 | string word; 40 | while ( infile >> word ) { 41 | AddId(word); 42 | } 43 | return true; 44 | } -------------------------------------------------------------------------------- /obfusc/RecordTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | #include "TokenTypes.h" 4 | using namespace std; 5 | class Record; 6 | class RecordMap; 7 | 8 | class Record 9 | { 10 | public: 11 | string name; 12 | string afterName; 13 | 14 | int first_line,first_column,last_line,last_column; 15 | 16 | // constructor 17 | Record(string name, string afterName, 18 | int first_line, int first_column, 19 | int last_line, int last_column) : name(name), afterName(afterName), 20 | first_line(first_line),first_column(first_column), 21 | last_line(last_line), last_column(last_column) 22 | { 23 | } 24 | }; 25 | 26 | class RecordTable 27 | { 28 | private: 29 | vector list; 30 | public: 31 | RecordTable(void); 32 | ~RecordTable(void); 33 | 34 | void AddRecord(string name, string afterName, 35 | int first_line, int first_column, 36 | int last_line, int last_column); 37 | 38 | string PrintRecordTable(bool hasLocation); 39 | }; 40 | 41 | -------------------------------------------------------------------------------- /obfusc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "obfusc", "obfusc\obfusc.vcxproj", "{4EC6E0E8-1BA0-41EF-95C3-A720FE870A61}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4EC6E0E8-1BA0-41EF-95C3-A720FE870A61}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4EC6E0E8-1BA0-41EF-95C3-A720FE870A61}.Debug|Win32.Build.0 = Debug|Win32 14 | {4EC6E0E8-1BA0-41EF-95C3-A720FE870A61}.Release|Win32.ActiveCfg = Release|Win32 15 | {4EC6E0E8-1BA0-41EF-95C3-A720FE870A61}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | GlobalSection(ExtensibilityGlobals) = postSolution 21 | VisualSVNWorkingCopyRoot = . 22 | EndGlobalSection 23 | EndGlobal 24 | -------------------------------------------------------------------------------- /obfusc/Obfuscator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "IObfusNode.h" 5 | #include "CodeFile.h" 6 | #include "NotObfusIdTable.h" 7 | #include "RecordTable.h" 8 | /** 9 | * Obfuscator will operate the AST tree(Tree). 10 | * It will obfuscate the name. the SymbolTable will be the reference. 11 | **/ 12 | class Obfuscator 13 | { 14 | private: 15 | Tree *currentTree; 16 | SymbolTable *currentSymbolTable; 17 | NotObfusIdTable *currentNotObfusIdTable; 18 | RecordTable recordTable; 19 | 20 | // left traversal 21 | void Traversal(Node *node); 22 | // ObfusNode list; 23 | vector onList; 24 | // do something to node. call the IObfusNode::Action. 25 | void ObfuscateNode(Node *); 26 | public: 27 | ~Obfuscator(void); 28 | 29 | // create Obfuscator instance with CodeFile. 30 | Obfuscator(CodeFile &file, NotObfusIdTable *t); 31 | 32 | // main function. 33 | void Obfuscate(); 34 | 35 | // add ObfuscNode 36 | void Register(IObfusNode *node); 37 | 38 | string PrintObfuscRecordTable(bool needLocation) 39 | { 40 | return recordTable.PrintRecordTable(needLocation); 41 | } 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /obfusc/SymbolTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "Symbol.h" 5 | #include "TokenTypes.h" 6 | #include "CParser.h" 7 | 8 | class SymbolTable 9 | { 10 | private: 11 | vector symbolList; 12 | public: 13 | SymbolTable(void); 14 | ~SymbolTable(void); 15 | // print the symbol table 4debug. 16 | string PrintSymbolTable(); 17 | 18 | // add Symbol; 19 | void AddToTable(Symbol *); 20 | void ScanedIdentifier(int t, TokenLocation l); 21 | 22 | // find Symbol; 23 | Symbol *findSymbol(string name); 24 | bool isExist(string name); 25 | bool isExistObfusc(string name); 26 | 27 | // find TYPE_NAME Symbol 28 | Symbol *SymbolTable::findTYPE_NAMESymbol(string name); 29 | bool isExistType(string name); 30 | 31 | // return num of symbols 32 | int GetSize(); 33 | 34 | bool InputTYPE_NAMEFile(string path); 35 | void AddTYPE_NAME(string word); 36 | 37 | 38 | 39 | /******************************** 40 | * called by Parser 41 | *******************************/ 42 | // Convert Symbol. 43 | void ConvertIdentifier2TYPE_NAME(string name); 44 | 45 | void SetIdentifierDeclared(string name); 46 | 47 | }; 48 | 49 | -------------------------------------------------------------------------------- /obfusc/ONDoWhile.cpp: -------------------------------------------------------------------------------- 1 | #include "ONDoWhile.h" 2 | 3 | 4 | ONDoWhile::ONDoWhile(bool isRemoveTypeset) : 5 | isRemoveTypeset(isRemoveTypeset) 6 | { 7 | } 8 | 9 | 10 | ONDoWhile::~ONDoWhile(void) 11 | { 12 | } 13 | // see the node type if it is the type which this class to obfuscate. 14 | bool ONDoWhile::JudgeType(Node *node) 15 | { 16 | if ( node->nodeType == Node::NODE 17 | && node->nodeTypeName == "iteration_statement" 18 | && node->childNodes.size() == 7 19 | && node->getChild(0)->nodeType == Node::TOKEN 20 | && node->getChild(0)->tokenId == CParser::DO ) 21 | { 22 | return true; 23 | } 24 | return false; 25 | } 26 | 27 | // main function. Obufuscator will call this function 28 | void ONDoWhile::Action(Node *node) 29 | { 30 | if ( !JudgeType(node) ) { 31 | return; 32 | } 33 | 34 | string l_continue = GenerateId(); 35 | string l_break = GenerateId(); 36 | 37 | Node *expression = node->getChild(4); 38 | Node *statement = node->getChild(1); 39 | 40 | stringstream ss; 41 | ss << l_continue << ":"; 42 | ss << statement->ToSourceCode(isRemoveTypeset) ; 43 | ss << "if(" << expression->ToSourceCode(isRemoveTypeset) << ")"; 44 | ss << "goto " << l_continue << ";"; 45 | ss << l_break << ":;"; 46 | 47 | string code = ss.str(); 48 | 49 | node->isObfuscated = true; 50 | node->obfuscatedTokenString = code; 51 | } -------------------------------------------------------------------------------- /obfusc/ExtraString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | using namespace std; 4 | 5 | class ExtraString; 6 | class PreProcessElement; 7 | class CommentElement; 8 | class TypesetElement; 9 | class IExtraStringElement; 10 | 11 | class ExtraString 12 | { 13 | public: 14 | ExtraString(void); 15 | ~ExtraString(void); 16 | 17 | enum ElementType { TYPESET, COMMENT, PREPROCESS } elmentType; 18 | 19 | IExtraStringElement *CreateElement(ElementType type, string t); 20 | void addString(ElementType type, string t); 21 | 22 | vector list; 23 | 24 | string toString(); 25 | string toShortString(); 26 | }; 27 | 28 | class IExtraStringElement 29 | { 30 | public: 31 | IExtraStringElement(){}; 32 | virtual ~IExtraStringElement(){}; 33 | ExtraString::ElementType type; 34 | string content; 35 | }; 36 | 37 | class TypesetElement : public IExtraStringElement 38 | { 39 | public: 40 | TypesetElement(string t) {type = ExtraString::TYPESET; content= t;}; 41 | ~TypesetElement(){}; 42 | }; 43 | 44 | class CommentElement : public IExtraStringElement 45 | { 46 | public: 47 | CommentElement(string t) {type = ExtraString::COMMENT; content= t;}; 48 | ~CommentElement(){}; 49 | }; 50 | 51 | class PreProcessElement : public IExtraStringElement 52 | { 53 | public: 54 | PreProcessElement(string t) {type = ExtraString::PREPROCESS; content= t;}; 55 | ~PreProcessElement(){}; 56 | }; 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /obfusc/CAnalys.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "CLexer.h" 5 | #include "CParser.h" 6 | #include "Tree.h" 7 | #include "Node.h" 8 | #include "CodeFile.h" 9 | #include "Symbol.h" 10 | #include "SymbolTable.h" 11 | 12 | #define TAB_COLUMN 4 13 | // class define 14 | class CAnalys : public CLexer, public CParser 15 | { 16 | private: 17 | Tree** currentTree; 18 | SymbolTable *currentSymbolTable; 19 | protected: 20 | int Scan(); 21 | public: 22 | void SetDebug(int d); 23 | void PrintError(char *s ); 24 | int check_type(TokenValue &theValue); 25 | 26 | void FindTPYEDEFDeclaration(Node *); 27 | void ParsedDeclaration(Node * node); 28 | void ParsedFunctionDefinition(Node *functionNode, Node *declaratorNode); 29 | 30 | Tree * getCurrentTree(void) { return *currentTree; }; 31 | void setCurrentTree(Tree *value) { *currentTree = value; }; 32 | //void setCurrentTree(Tree *value) { currentTree = value; }; 33 | SymbolTable * getCurrentSymbolTable(void) { return currentSymbolTable;}; 34 | //void setCurrentSymbolTable(SymbolTable *value) { currentSymbolTable = value; }; 35 | 36 | void setCurrentCodeFile(CodeFile &file); 37 | 38 | CAnalys(); 39 | ~CAnalys(); 40 | 41 | 42 | void AddToSymbolTable(int t,TokenLocation l); 43 | 44 | // when Only do the Lex, 45 | // no Tree, Only Symbol Table will be created. 46 | // SymbolTable not have detail information of Symbols. 47 | void OnlyLexer(); 48 | }; -------------------------------------------------------------------------------- /obfusc/ExtraString.cpp: -------------------------------------------------------------------------------- 1 | #include "ExtraString.h" 2 | 3 | 4 | ExtraString::ExtraString(void) 5 | { 6 | list = vector(); 7 | } 8 | 9 | 10 | ExtraString::~ExtraString(void) 11 | { 12 | 13 | } 14 | // Create String. 15 | void ExtraString::addString(ElementType type, string t) 16 | { 17 | IExtraStringElement *iese; 18 | iese = CreateElement(type,t); 19 | list.push_back(iese); 20 | } 21 | // Create Element 22 | IExtraStringElement *ExtraString::CreateElement(ElementType type, string t) 23 | { 24 | IExtraStringElement *p; 25 | switch(type) { 26 | case TYPESET: 27 | p = new TypesetElement(t); 28 | break; 29 | case COMMENT: 30 | p = new CommentElement(t); 31 | break; 32 | case PREPROCESS: 33 | p = new PreProcessElement(t); 34 | break; 35 | } 36 | return p; 37 | } 38 | 39 | string ExtraString::toString() 40 | { 41 | string result; 42 | vector::iterator it; 43 | for ( it = list.begin() ; it != list.end() ; it++ ) { 44 | result += (*it)->content; 45 | } 46 | return result; 47 | } 48 | 49 | string ExtraString::toShortString() 50 | { 51 | string result; 52 | vector::iterator it; 53 | for ( it = list.begin() ; it != list.end() ; it++ ) { 54 | if ( (*it)->type == PREPROCESS ) { 55 | if ( result.empty()) { 56 | result += "\n"; 57 | } 58 | result += (*it)->content; 59 | } 60 | } 61 | /*if ( result.empty() ) { 62 | result = " "; 63 | }*/ 64 | return result; 65 | } 66 | -------------------------------------------------------------------------------- /obfusc/Obfuscator.cpp: -------------------------------------------------------------------------------- 1 | #include "Obfuscator.h" 2 | #include "Node.h" 3 | 4 | Obfuscator::~Obfuscator(void) 5 | { 6 | 7 | } 8 | 9 | Obfuscator::Obfuscator(CodeFile &file,NotObfusIdTable *t) 10 | { 11 | currentTree = file.tree; 12 | currentSymbolTable = file.symbolTable; 13 | currentNotObfusIdTable = t; 14 | } 15 | // main function. 16 | void Obfuscator::Obfuscate() 17 | { 18 | Traversal(currentTree); 19 | } 20 | // left traversal 21 | void Obfuscator::Traversal(Node *node) 22 | { 23 | if ( node == NULL ) { 24 | cerr << "Node::Traversal Node NULL" << endl; 25 | return ; 26 | } 27 | 28 | if ( node->nodeType == Node::TOKEN ) { 29 | ObfuscateNode(node); 30 | } else { 31 | list::iterator it; 32 | for ( it = node->childNodes.begin() ; it != node->childNodes.end() ; it++) { 33 | Traversal((*it)); 34 | } 35 | ObfuscateNode(node); 36 | } 37 | return ; 38 | } 39 | // do action to Node 40 | void Obfuscator::ObfuscateNode(Node *node) 41 | { 42 | //cout << node->nodeTypeName << endl; 43 | //node->preString = "123"; 44 | vector::iterator it; 45 | for( it = onList.begin() ; it != onList.end() ; it++) { 46 | (*it)->Action(node); 47 | } 48 | } 49 | // register ObfuscNode classes 50 | void Obfuscator::Register(IObfusNode *on) 51 | { 52 | on->symbolTable = currentSymbolTable; 53 | on->notObfusIdTable = currentNotObfusIdTable; 54 | on->recordTable = &recordTable; 55 | on->root = currentTree; 56 | onList.push_back(on); 57 | on->InitAction(); 58 | } 59 | -------------------------------------------------------------------------------- /obfusc/IObfusNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "Node.h" 5 | #include "SymbolTable.h" 6 | #include "NotObfusIdTable.h" 7 | #include "RecordTable.h" 8 | #include "IdentifierGenerator.h" 9 | 10 | class IObfusNode 11 | { 12 | public: 13 | SymbolTable *symbolTable; 14 | NotObfusIdTable *notObfusIdTable; 15 | RecordTable *recordTable; 16 | Node *root; 17 | 18 | IObfusNode(void) 19 | { 20 | } 21 | 22 | string beforeObfuscate; 23 | string afterObfuscated; 24 | 25 | virtual ~IObfusNode(void) 26 | { 27 | } 28 | // see the node type if it is the type which this class to obfuscate. 29 | virtual bool JudgeType(Node *node) 30 | { 31 | return false; 32 | } 33 | // main function. Obufuscator will call this function 34 | virtual void Action(Node *node) 35 | { 36 | } 37 | 38 | // Init. 39 | virtual void InitAction(){}; 40 | 41 | Node * CreateNodeTOKEN(string str) 42 | { 43 | TokenLocation tmp; 44 | tmp.tokenId = -1; 45 | tmp.theText = str; 46 | tmp.preString = ""; 47 | tmp.extraString = new ExtraString(); 48 | tmp.first_line = -1; 49 | tmp.first_column = -1; 50 | tmp.last_line = -1; 51 | tmp.last_column = -1; 52 | 53 | Node *re = new Node(tmp); 54 | 55 | return re; 56 | } 57 | 58 | string GenerateId() { 59 | string generated = IdentifierGenerator::get().Generate(); 60 | while( symbolTable->isExistObfusc(generated) ) { 61 | generated = IdentifierGenerator::get().Generate(); 62 | } 63 | symbolTable->AddToTable(new Symbol(generated)); 64 | return generated; 65 | } 66 | }; 67 | 68 | -------------------------------------------------------------------------------- /obfusc/ONWhile.cpp: -------------------------------------------------------------------------------- 1 | #include "ONWhile.h" 2 | 3 | 4 | ONWhile::ONWhile(bool isRemoveTypeset) : 5 | isRemoveTypeset(isRemoveTypeset) 6 | { 7 | } 8 | 9 | 10 | ONWhile::~ONWhile(void) 11 | { 12 | } 13 | 14 | 15 | // see the node type if it is the type which this class to obfuscate. 16 | bool ONWhile::JudgeType(Node *node) 17 | { 18 | if ( node->nodeType == Node::NODE 19 | && node->nodeTypeName == "iteration_statement" 20 | && node->childNodes.size() == 5 21 | && node->getChild(0)->nodeType == Node::TOKEN 22 | && node->getChild(0)->tokenId == CParser::WHILE ) 23 | { 24 | return true; 25 | } 26 | return false; 27 | } 28 | // main function. Obufuscator will call this function 29 | void ONWhile::Action(Node *node) 30 | { 31 | if ( !JudgeType(node) ) { 32 | return; 33 | } 34 | // before Obfuscated 35 | /* 36 | WHILE '(' expression ')' 37 | statement 38 | */ 39 | // after Obfuscated 40 | /* 41 | l_continue: 42 | if (!(expression)) 43 | goto l_break; 44 | statement; 45 | goto l_continue; 46 | l_break:; 47 | */ 48 | string l_continue = GenerateId(); 49 | string l_break = GenerateId(); 50 | 51 | Node *expression = node->getChild(2); 52 | Node *statement = node->getChild(4); 53 | 54 | stringstream ss; 55 | ss << l_continue << ":"; 56 | ss << "if(!(" << expression->ToSourceCode(isRemoveTypeset) << "))"; 57 | ss << "goto " << l_break << ";"; 58 | ss << statement->ToSourceCode(isRemoveTypeset) ; 59 | ss << "goto " << l_continue << ";"; 60 | ss << l_break << ":;"; 61 | 62 | string code = ss.str(); 63 | 64 | node->isObfuscated = true; 65 | node->obfuscatedTokenString = code; 66 | } -------------------------------------------------------------------------------- /obfusc/NumberExpGenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "NumberExpGenerator.h" 2 | 3 | NumberExpGenerator NumberExpGenerator::instance; 4 | NumberExpGenerator::NumberExpGenerator(void) 5 | { 6 | } 7 | 8 | 9 | NumberExpGenerator::~NumberExpGenerator(void) 10 | { 11 | } 12 | 13 | string NumberExpGenerator::int2hexStr(int value) 14 | { 15 | string result; 16 | stringstream strm; 17 | strm.setf(stringstream::showbase | stringstream::uppercase); 18 | strm << std::hex << value << endl; 19 | strm >> result; 20 | strm.clear(); 21 | return result; 22 | } 23 | 24 | string NumberExpGenerator::int2octStr(int value) 25 | { 26 | string result; 27 | stringstream strm; 28 | strm.setf(stringstream::showbase | stringstream::uppercase); 29 | strm << std::oct << value << endl; 30 | strm >> result; 31 | strm.clear(); 32 | return result; 33 | } 34 | 35 | 36 | string NumberExpGenerator::Generate(double constant) 37 | { 38 | 39 | stringstream strm; 40 | // generate a random int 41 | int randInt = rand() % 0x7FFF; 42 | string randStr = int2hexStr(randInt); 43 | 44 | // bug 0x1E-13. 45 | if ( randStr[randStr.size()-1] == 'E' ) { 46 | randStr[randStr.size()-1] = 'F'; 47 | randInt++; 48 | } 49 | 50 | // r1*r2 51 | int r1 = rand() % 077; 52 | string r1Str = int2octStr(r1); 53 | int r2 = rand() % 99 + 100; 54 | 55 | 56 | 57 | 58 | // calculate adjust value; 59 | double adjust = constant - randInt - r1*r2; 60 | 61 | // after obfuscated 62 | stringstream strm2; 63 | if ( adjust < 0 ) { 64 | strm2 << "(" << randStr << "+" << r1Str << "*" << r2 << adjust << ")"; 65 | } else { 66 | strm2 << "(" << randStr << "+" << r1Str << "*" << r2 << "+" << adjust << ")"; 67 | } 68 | 69 | return strm2.str(); 70 | } -------------------------------------------------------------------------------- /obfusc/Symbol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pre.h" 3 | 4 | #include "TokenTypes.h" 5 | using namespace std; 6 | /** 7 | * the Symbol Class store the name which we need to obfuscate. 8 | * 9 | * It's include variables, functions 10 | * It also has a Obfuscated name property. 11 | * 12 | * CONST , like number and string, will NOT be added to Symbol. 13 | **/ 14 | class Symbol 15 | { 16 | public: 17 | Symbol(void); 18 | ~Symbol(void); 19 | 20 | 21 | // the name of the Symbol 22 | string name; 23 | // type of Symbol 24 | enum SymbolType { IDENTIFIER, VAR, FUNC, TYPE_NAME } type; 25 | //enum SymbolType { IDENTIFIER, CONST, STRING_LITERAL, TYPE_NAME } type; 26 | 27 | 28 | 29 | Symbol(string name); 30 | Symbol(string name, SymbolType type); 31 | 32 | // appeared location 33 | vector appearedLocation; 34 | void addLocation(int first_line, int first_column, int last_line, int last_column); 35 | int AppearedTime(); 36 | 37 | /***************************** 38 | * IDENTIFIER 39 | ****************************/ 40 | //enum IdentifierType { VAR, FUNC } idType; 41 | /***************************** 42 | * VAR (IDENTIFIER) 43 | ****************************/ 44 | // storage type of Symbol, such as "int []" 45 | string storeType; 46 | // If declared. 47 | bool isDeclared; 48 | 49 | // var scope 50 | enum SymbolScope { GLOBAL, LOCAL } scope; 51 | 52 | // If LOCAL 53 | string funcName; 54 | /***************************** 55 | * FUNCTION (IDENTIFIER) 56 | ****************************/ 57 | // full function define statement. 58 | string defineString; 59 | 60 | /***************************** 61 | * TYPE_NAME 62 | ****************************/ 63 | 64 | /***************************** 65 | * Obfusc 66 | ****************************/ 67 | bool isObfusced; 68 | string nameAfterObfusc; 69 | }; 70 | -------------------------------------------------------------------------------- /obfusc/ONString.cpp: -------------------------------------------------------------------------------- 1 | #include "ONString.h" 2 | 3 | ONString::ONString(void) 4 | { 5 | } 6 | 7 | 8 | ONString::~ONString(void) 9 | { 10 | } 11 | 12 | bool ONString::JudgeType(Node *node) 13 | { 14 | // first of all. must sure that it's a CONSTANT. 15 | if ( !( node->nodeType == Node::TOKEN 16 | && node->tokenId == CParser::STRING_LITERAL ) ) { 17 | return false; 18 | } 19 | return true; 20 | } 21 | // convert string like this 22 | // "\x64\x69\x66\x66\x73\x74\x61\x74\x20\x76\x65\x72\x73\x69\x6f\x6e\x20\x25\x73" 23 | string ONString::Convert2HexStyle(string str) 24 | { 25 | stringstream strm; 26 | string after; 27 | char cur; 28 | for ( int i = 0 ; i < (int)str.length() ; i ++ ) { 29 | if ( i == 0 ) { 30 | after += '\"'; 31 | } else if ( i == str.length() -1 ) { 32 | after += '\"'; 33 | } else { 34 | cur = str[i]; 35 | // if found a type cast \; 36 | if ( cur == '\\' ) { 37 | after += cur; 38 | after += str[i+1]; 39 | i++; 40 | // else will convert to \xFF; 41 | } else { 42 | // get hex 43 | int value = (int)cur; 44 | string strValue; 45 | strm.setf(ios::uppercase); 46 | strm<< std::hex << value; 47 | strm >> strValue; 48 | strm.clear(); 49 | 50 | after += "\\x"; 51 | after += strValue; 52 | } 53 | } 54 | } 55 | 56 | return after; 57 | } 58 | 59 | void ONString::Action(Node *node) 60 | { 61 | if ( !JudgeType(node) ) { 62 | return; 63 | } 64 | 65 | if ( node->tokenString.length() < 2 ) { 66 | cerr << "error token string_literal length smaller than 2" << endl; 67 | return ; 68 | } 69 | 70 | // convert to hex style 71 | beforeObfuscate = node->tokenString; 72 | afterObfuscated = Convert2HexStyle(node->tokenString); 73 | 74 | // set obfuscated 75 | node->isObfuscated = true; 76 | node->obfuscatedTokenString = afterObfuscated; 77 | 78 | //save the changes. 79 | recordTable->AddRecord(beforeObfuscate, afterObfuscated, 80 | node->first_line, node->first_column, 81 | node->last_line, node->last_column); 82 | } 83 | -------------------------------------------------------------------------------- /obfusc/ONFor.cpp: -------------------------------------------------------------------------------- 1 | #include "ONFor.h" 2 | 3 | 4 | ONFor::ONFor(bool isRemoveTypeset) : 5 | isRemoveTypeset(isRemoveTypeset) 6 | { 7 | } 8 | 9 | 10 | ONFor::~ONFor(void) 11 | { 12 | } 13 | 14 | // see the node type if it is the type which this class to obfuscate. 15 | bool ONFor::JudgeType(Node *node) 16 | { 17 | if ( node->nodeType == Node::NODE 18 | && node->nodeTypeName == "iteration_statement" 19 | && node->getChild(0)->nodeType == Node::TOKEN 20 | && node->getChild(0)->tokenId == CParser::FOR ) 21 | { 22 | return true; 23 | } 24 | return false; 25 | } 26 | 27 | // main function. Obufuscator will call this function 28 | void ONFor::Action(Node *node) 29 | { 30 | if ( !JudgeType(node) ) { 31 | return; 32 | } 33 | 34 | string l_loop = GenerateId(); 35 | string l_continue = GenerateId(); 36 | string l_instr = GenerateId(); 37 | string l_break = GenerateId(); 38 | 39 | string expr1,expr2,expr3,instr; 40 | expr1 = node->getChild(2)->ToSourceCode(isRemoveTypeset); 41 | Node *expression_statement = node->getChild(3); 42 | if ( expression_statement->childNodes.size() == 1 ) { 43 | expr2 = "1"; 44 | } else { 45 | expr2 = expression_statement->getChild(0)->ToSourceCode(isRemoveTypeset); 46 | } 47 | 48 | if ( node->childNodes.size() == 6 ) { 49 | expr3 = ""; 50 | instr = node->getChild(5)->ToSourceCode(isRemoveTypeset); 51 | } else { 52 | expr3 = node->getChild(4)->ToSourceCode(isRemoveTypeset); 53 | expr3 += ";"; 54 | instr = node->getChild(6)->ToSourceCode(isRemoveTypeset); 55 | } 56 | 57 | stringstream ss; 58 | ss << expr1; 59 | ss << l_loop << ":"; 60 | ss << "if(!(" << expr2 << "))"; 61 | ss << "goto " << l_break << ";"; 62 | ss << "goto " << l_instr << ";"; 63 | ss << l_continue << ":"; 64 | ss << expr3; 65 | ss << "goto " << l_loop << ";"; 66 | ss << l_instr << ":"; 67 | ss << instr; 68 | ss << "goto " << l_continue << ";"; 69 | ss << l_break << ":;"; 70 | 71 | string code = ss.str(); 72 | 73 | node->isObfuscated = true; 74 | node->obfuscatedTokenString = code; 75 | } -------------------------------------------------------------------------------- /obfusc/Node.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "pre.h" 4 | #include "TokenTypes.h" 5 | #include "ExtraString.h" 6 | using namespace std; 7 | class Node; 8 | class NodeTraversal; 9 | 10 | class Node 11 | { 12 | private: 13 | string ToCodeTreeCall(int level); 14 | // the begin(), end() function use this list. 15 | list traversaledList; 16 | bool isLetter(char c); 17 | public: 18 | Node(void); 19 | ~Node(void); 20 | 21 | Node *parent; 22 | 23 | // NodeType will be a TOKEN or NODE contains TOKENs 24 | enum NodeType { TOKEN, NODE } nodeType; 25 | 26 | // childNodes 27 | list childNodes; 28 | Node *getChild(int index); 29 | 30 | // if Is a TOKEN, tokenId, tokenString. 31 | // we just intrested in IDENTIFIER, CONST, STIRNG... 32 | int tokenId; 33 | string tokenString; 34 | 35 | // if Obfuscated. 36 | bool isObfuscated; 37 | string obfuscatedTokenString; 38 | 39 | // If is a NODE , then set the nodeTypeName; 40 | string nodeTypeName; 41 | 42 | // store the notValue strs before the node; 43 | string preString; 44 | ExtraString *extraString; 45 | 46 | // Location 47 | int first_line,first_column; 48 | int last_line, last_column; 49 | 50 | 51 | 52 | // create Node 53 | Node(TokenLocation l); 54 | Node(string typeName,int num,...); 55 | 56 | // add Child Node 57 | void AddChildNode(Node *); 58 | void AddChildNode(int num, ...); 59 | 60 | // conver the Node to Source code. 61 | string ToCode(); 62 | string ToSourceCode(bool isRemoveTypeset); 63 | // 4debug 64 | string ToCodeTree(); 65 | 66 | // find identifier children. 67 | void findIdentifierChildren(vector &found); 68 | 69 | // find typedef; 70 | bool hasTypedefToken(); 71 | // find extern; 72 | bool hasExternToken(); 73 | // find gotoStatement; 74 | bool hasGotoStatement(); 75 | 76 | // Judge the type. 77 | bool isToken(int tokenId); 78 | bool isNode(string nodeTypeName); 79 | 80 | // left traveral 81 | //void Traversal(void (*func)()); 82 | //void Traversal2(int tokenId, bool (*func)(int)); 83 | 84 | // functions about traversal all node. 85 | typedef list::iterator iterator; 86 | void TraversalAllNode(list &l); 87 | list::iterator begin(); 88 | list::iterator end(); 89 | }; -------------------------------------------------------------------------------- /obfusc/IdentifierGenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "IdentifierGenerator.h" 2 | 3 | IdentifierGenerator IdentifierGenerator::instance; 4 | 5 | IdentifierGenerator::IdentifierGenerator(void) 6 | { 7 | srand((unsigned int)time(0)); 8 | idLength = ID_MIN_LEN; 9 | } 10 | 11 | 12 | IdentifierGenerator::~IdentifierGenerator(void) 13 | { 14 | } 15 | 16 | 17 | // generate a Identifier string. 18 | string IdentifierGenerator::Generate() 19 | { 20 | //char firtable[]="_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 21 | //char digTable[] = "0123456789"; 22 | char table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; 23 | char O0Table[] = "O0"; 24 | char l1Table[] = "l1"; 25 | char *p; 26 | char firstChar = 'x'; 27 | 28 | // Pick a character table. 29 | if ( idLookLike == LL_NORMAL ) { 30 | p = table; 31 | } else if ( idLookLike == LL_l1 ) { 32 | firstChar = 'l'; 33 | p = l1Table; 34 | } else if ( idLookLike == LL_O0 ) { 35 | firstChar = 'O'; 36 | p = O0Table; 37 | } else if ( idLookLike == LL_CUSTOM ) { 38 | char t[100]; 39 | strncpy(t,custom.c_str(),100); 40 | p = t; 41 | } 42 | 43 | string result = ""; 44 | int r; 45 | for (int i = 0 ;i < idLength; i++ ) { 46 | if ( i == 0 ) { 47 | //r = rand() % strlen(firtable); 48 | //result += firtable[r]; 49 | result += firstChar; 50 | } else { 51 | r = rand() % strlen(p); 52 | result += *(p+r); 53 | } 54 | } 55 | 56 | return result; 57 | } 58 | 59 | void IdentifierGenerator::SetSymbolNum(int num) 60 | { 61 | char table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890123456789012345678901234567890"; 62 | char O0Table[] = "O0"; 63 | char l1Table[] = "l1"; 64 | 65 | int len; 66 | // Pick a character table. 67 | if ( idLookLike == LL_NORMAL ) { 68 | len = strlen(table); 69 | } else if ( idLookLike == LL_l1 ) { 70 | len = strlen(l1Table); 71 | } else if ( idLookLike == LL_O0 ) { 72 | len = strlen(O0Table); 73 | } else if ( idLookLike == LL_CUSTOM ) { 74 | len = custom.size(); 75 | } 76 | 77 | assert(len > 1); 78 | 79 | double f = log((double)num * 20)/log((double)len); 80 | int intf = (int)f + 1; 81 | if ( intf < ID_MIN_LEN ) { 82 | idLength = ID_MIN_LEN; 83 | } else { 84 | idLength = intf; 85 | } 86 | } -------------------------------------------------------------------------------- /obfusc/ONIdentifier.cpp: -------------------------------------------------------------------------------- 1 | #include "ONIdentifier.h" 2 | #include "IdentifierGenerator.h" 3 | 4 | ONIdentifier::ONIdentifier(void) 5 | { 6 | srand((unsigned int)time(0)); 7 | } 8 | 9 | 10 | ONIdentifier::~ONIdentifier(void) 11 | { 12 | } 13 | 14 | 15 | // see the node type if it is the type which this class to obfuscate. 16 | bool ONIdentifier::JudgeType(Node *node) 17 | { 18 | if ( node->nodeType == Node::TOKEN 19 | && ( node->tokenId == CParser::IDENTIFIER || node->tokenId == CParser::TYPE_NAME ) ) { 20 | return true; 21 | } 22 | return false; 23 | } 24 | // main function. Obufuscator will call this function 25 | void ONIdentifier::Action(Node *node) 26 | { 27 | if ( !JudgeType(node) ) { 28 | return; 29 | } 30 | 31 | // Do not obfuscate Identifier which in the NotObfusIdTable 32 | if ( notObfusIdTable->hasId(node->tokenString) ) { 33 | return; 34 | } 35 | 36 | Symbol *s = symbolTable->findSymbol(node->tokenString); 37 | //// If Not found the symbol. do not obfuscate the symbol 38 | //if ( s == NULL ) { 39 | 40 | // return; 41 | //} 42 | assert(s != NULL); 43 | // Do not obfuscate NOT defined Symbol. 44 | if ( s->isDeclared == false ) { 45 | return; 46 | } 47 | 48 | // If already obfuscated. 49 | if ( s->isObfusced == true ) { 50 | node->obfuscatedTokenString = s->nameAfterObfusc; 51 | node->isObfuscated = true; 52 | } else { 53 | // First Met the Symbol. 54 | beforeObfuscate = node->tokenString; 55 | // generate name until Not same 56 | string generated = IdentifierGenerator::get().Generate(); 57 | while( symbolTable->isExistObfusc(generated) ) { 58 | generated = IdentifierGenerator::get().Generate(); 59 | } 60 | 61 | afterObfuscated = generated; 62 | // set symbol. 63 | s->nameAfterObfusc = afterObfuscated; 64 | s->isObfusced = true; 65 | // set node 66 | node->obfuscatedTokenString = afterObfuscated; 67 | node->isObfuscated = true; 68 | } 69 | // save the records. 70 | recordTable->AddRecord(beforeObfuscate, afterObfuscated, 71 | node->first_line, node->first_column, 72 | node->last_line, node->last_column); 73 | } 74 | 75 | // generate a Identifier string. 76 | string ONIdentifier::GenerateIdentifier() 77 | { 78 | char firtable[]="_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 79 | char table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890123456789012345678901234567890"; 80 | char digTable[] = "0123456789"; 81 | char Oo0Table[] = "Oo0"; 82 | 83 | string result = ""; 84 | int r; 85 | for (int i = 0 ;i < ID_LEN; i++ ) { 86 | if ( i == 0 ) { 87 | //r = rand() % strlen(firtable); 88 | //result += firtable[r]; 89 | result += "O"; 90 | } else { 91 | r = rand() % strlen(Oo0Table); 92 | result += Oo0Table[r]; 93 | } 94 | } 95 | 96 | return result; 97 | } -------------------------------------------------------------------------------- /obfusc/ONConstant.cpp: -------------------------------------------------------------------------------- 1 | #include "ONConstant.h" 2 | #include "Node.h" 3 | #include "NumberExpGenerator.h" 4 | 5 | ONConstant::ONConstant(void) 6 | { 7 | srand((unsigned int)time(0)); 8 | } 9 | 10 | 11 | ONConstant::~ONConstant(void) 12 | { 13 | } 14 | 15 | bool ONConstant::JudgeType(Node *node) 16 | { 17 | // first of all. must sure that it's a CONSTANT. 18 | if ( !( node->nodeType == Node::TOKEN 19 | && node->tokenId == CParser::CONSTANT ) ) { 20 | return false; 21 | } 22 | return true; 23 | } 24 | 25 | //do action to the node. 26 | void ONConstant::Action(Node *node) 27 | { 28 | if ( !JudgeType(node) ) { 29 | return; 30 | } 31 | 32 | // do not obfuscate constant char 'x' 33 | if ( node->tokenString[0] == '\'' && node->tokenString.length() != 3 ) { 34 | return ; 35 | } 36 | 37 | // get Ture value. If fail do not obfusc. 38 | double trueValue; 39 | if ( !getConstantValue(node->tokenString,&trueValue) ) { 40 | return ; 41 | } 42 | 43 | // do Obfuscate To Node. 44 | beforeObfuscate = node->tokenString; 45 | afterObfuscated = NumberExpGenerator::get().Generate(trueValue); 46 | 47 | // set value to the node. 48 | node->obfuscatedTokenString = afterObfuscated; 49 | node->isObfuscated = true; 50 | 51 | // will save the changes. 52 | recordTable->AddRecord(beforeObfuscate,afterObfuscated, 53 | node->first_line,node->first_column, 54 | node->last_line,node->last_column); 55 | } 56 | /* 57 | string ONConstant::Contant2String(double constant) 58 | { 59 | 60 | stringstream strm; 61 | // generate a random int 62 | int randInt = rand() % 0xFFFF; 63 | string randStr; 64 | strm.setf(stringstream::showbase | stringstream::uppercase); 65 | strm << std::hex << randInt << endl; 66 | strm >> randStr; 67 | strm.clear(); 68 | // bug 0x1E-13. 69 | if ( randStr[randStr.size()-1] == 'E' ) { 70 | randStr[randStr.size()-1] = 'F'; 71 | randInt++; 72 | } 73 | 74 | // calculate adjust value; 75 | double adjust = constant - randInt; 76 | 77 | // after obfuscated 78 | stringstream strm2; 79 | if ( adjust < 0 ) { 80 | strm2 << "(" << randStr << adjust << ")"; 81 | } else { 82 | strm2 << "(" << randStr << "+" << adjust << ")"; 83 | } 84 | 85 | return strm2.str(); 86 | }*/ 87 | 88 | bool ONConstant::getConstantValue(string str,double *value) 89 | { 90 | char *end; // strtod() 91 | double result; 92 | // char 93 | if ( str.length()==3 && str[0] == '\'' ) { 94 | result = str[1]; 95 | // 0xFFF 96 | } else if ( str.length() >= 2 && str[0] == '0' 97 | && (str[1] == 'x'||str[1]=='X') ) { 98 | long l = strtol(str.c_str(),&end,0); 99 | if ( *end ) { 100 | cerr << "Can't find true value in ONConstant::getConstantValue str:" << str << endl; 101 | return false; 102 | } 103 | result = l; 104 | } else if ( str.length() >= 2 && str[0] == '0' ) { 105 | long l = strtol(str.c_str(),&end,8); 106 | if ( *end ) { 107 | cerr << "Can't find true value in ONConstant::getConstantValue str:" << str << endl; 108 | return false; 109 | } 110 | result = l; 111 | } else { 112 | char *end; 113 | result = strtod(str.c_str(),&end); 114 | if ( *end ) { 115 | cerr << "Can't find true value in ONConstant::getConstantValue str:" << str << endl; 116 | return false; 117 | } 118 | } 119 | *value = result; 120 | return true; 121 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # C Source Code Obfuscator(CSCO) 2 | by 4con. v1.0 3 | 4 | 此软件为混淆C语言(C89)源代码级的混淆器,是本人在大学时的小作品。 5 | 此软件输入为一个C语言源代码文件,输出为一个经过混淆后的C语言源代码文件。 6 | 混淆后的C语言源代码文件可以正常编译,程序功能与混淆前一样。 7 | 8 | 支持的功能 9 | 10 | - 名称变换功能,可自定义要混淆的内容:常量数值、常量字符串、标识符。 11 | - 循环语句混淆功能。 12 | - 控制流混淆功能,可以将顺序执行的代码语句位置打乱。 13 | - 自动分辨可混淆标识符,导入的函数与变量不会进行混淆。 14 | - 可自定义混淆时使用的字符。 15 | - 可自定义不想混淆的标识符。 16 | - 可以参考并自行添加新的混淆功能。 17 | 18 | 尚未支持功能(很久以后可能也不支持 XD) 19 | 20 | - C语言预处理相关部分不能混淆,暂时只支持对#define的混淆。 21 | - 不支持同时对多个文件的混淆。 22 | 23 | ## Design & Code 24 | 25 | (有些年头了,可能记不得很多细节。) 26 | 27 | 1. C语言源文件输入会经过flex bison作为词法语法分析器(lex/yacc的C++版)进行词法语法分析。 28 | 词法分析主要用于分辨标识符的类型,通过词法分析功能可以实现名称变换混淆功能。 29 | 语法分析功能支持了更进一步的循环与控制流的混淆,也能够自动分辨可混淆标识符。 30 | 31 | 2. 经过语法分析后,会构建AST抽象语法树与符号表。通过符号表可以对标识符进行混淆。 32 | 通过语法树遍历,并找到特定的语法节点后(如循环或顺序结构),对节点进行混淆替换, 33 | 最后能够得到语法上的混淆效果。 34 | 35 | 简单代码说明: 36 | - CLexer.l/CParser.y为词法/语法文件,可以使用flex++/bison++进行编译生成对应代码文件CLexer.h/CLexer.cc/CParser.h/CParser.cc。 37 | - CAnalys是分析器类,结合了词法分析与语法分析功能。 38 | - Node表示抽象语法树节点。Symbol表示标识符,SymbolTable为符号表。 39 | - 由ON开始的文件名对应某种混淆功能,如ONString.h/ONString.cpp里是对常量字符串的混淆。 40 | 41 | ## Build 42 | 43 | 1. 此工程是使用VS2010 RC版本建立的。 44 | 2. flex_bison目录下是,flex++与bison++,通过CLexer.l与CParser.y生成CLexer.h,CLexer.cc,CParser.h,CParser.cc的工具。 45 | 46 | 命令是: 47 | cd $(ProjectDir) 48 | ..\flex_bison\bison++ -d -o CParser.cc -h CParser.h CParser.y 49 | ..\flex_bison\flex++ -8 -hCLexer.h -oCLexer.cc CLexer.l 50 | 51 | 每次修改CLexer.l与CParser.y后,通过上述命令生成对应的头文件与代码文件。 52 | (如果使用VS2010,此部分已经在工程设定里设定了,每次编译前会执行上面的命令,然后进行编译。) 53 | 54 | ## Usage 55 | 56 | ``` 57 | Useage: obfusc.exe [-o output] [-t table] [-c] [-s] [-i METHOD] [-m] [-l] [-k] [ 58 | -p type] [-n not] file 59 | Options: 60 | -o FILE Set output filename 61 | -t FILE Output before-after obfuscated table file 62 | -c Obfuscate constante number 63 | -s Obfuscate const string 64 | -i METHOD Obfuscate identifier. 65 | METHOD is one of: N, O0, l1, or a custom string 66 | N: normal charactor set. [0-9a-zA-Z] 67 | O0: use charactor [O0] 68 | l1: use charactor in [l1] 69 | [string]: use charactors in [[string]] 70 | -m Remove Typeset charactors. 71 | -l Obfuscate the loop statement. 72 | for, while, do while statement will be replace by if and goto. 73 | 74 | -k Obfuscate the Control Flow. 75 | -p FILE Input TYPE_NAME file. 76 | word in file will be considered as a TYPE_NAME,like int. 77 | -n FILE Input Not Obfuscate Identifier table 78 | FILE should (separate with a space or enter). 79 | 80 | ``` 81 | 82 | ``` 83 | 中文参数说明: 84 | -o FILE 输出文件名称 85 | -t FILE 输出标识符的混淆前后对比表文件名 86 | -c 数值常量混淆 87 | -s 字符串常量混淆 88 | -i METHOD 标识符重命名 89 | -m 去除格式以及注释 90 | -l 循环变换成if与goto的结构 91 | -k 顺序结构变换 92 | -p FILE 输入存储类型名称列表文件 93 | -n FILE 输入不混淆标识符列表文件 94 | ``` 95 | 96 | ## Result example (PART) 97 | 98 | used flag -csmlk -i O0 99 | 100 | before: 101 | ``` 102 | int partition(int low, int high) 103 | { 104 | int tmp,pivotkey; 105 | tmp = array[low]; 106 | pivotkey = array[low]; 107 | while (low < high) 108 | { 109 | while (low < high && array[high] >= pivotkey) 110 | --high; 111 | array[low] = array[high]; 112 | while (low < high && array[low] <= pivotkey) 113 | ++low; 114 | array[high] = array[low]; 115 | } 116 | array[low] = tmp; 117 | return low; 118 | } 119 | ``` 120 | 121 | after: 122 | ``` 123 | int OOO000OO(int OO0OOO00,int O000OO0O){int OO000O0O,OOOOO0O0;OO000O0O=OOOO0000[OO0OOO00];OOOOO0O0=OOOO0000[OO0OOO00];O00O000O:if(!(OO0OOO00=OOOOO0O0))goto O0O0OOO0;--O000OO0O;goto O0O0000O;O0O0OOO0:;OOOO0000[OO0OOO00]=OOOO0000[O000OO0O];O000OOOO:if(!(OO0OOO00InputTYPE_NAMEFile(arg.typeNameFile) ) { 35 | throw "Error!"; 36 | } 37 | } 38 | 39 | analys.setCurrentCodeFile(file); 40 | //analys.SetDebug(1); 41 | analys.Parse(); 42 | 43 | IdentifierGenerator::get().SetSymbolNum(file.symbolTable->GetSize()); 44 | 45 | // Read not obfuscate identifier file 46 | NotObfusIdTable noIdTable; 47 | if ( arg.isNotObfuscateFile ) { 48 | if ( !noIdTable.InputNotObfusIdFile(arg.noFile) ) { 49 | throw "Error!"; 50 | } 51 | } 52 | 53 | // Obfuscator. 54 | Obfuscator obf(file,&noIdTable); 55 | if ( arg.isObfuscateConstant ) { 56 | obf.Register(new ONConstant()); 57 | } 58 | if ( arg.isObfuscateIdentifier ) { 59 | obf.Register(new ONIdentifier()); 60 | } 61 | if ( arg.isObfuscateString ) { 62 | obf.Register(new ONString()); 63 | } 64 | if ( arg.isObfuscateLoopStatement ) { 65 | obf.Register(new ONWhile(arg.isRemoveTypeset)); 66 | obf.Register(new ONDoWhile(arg.isRemoveTypeset)); 67 | obf.Register(new ONFor(arg.isRemoveTypeset)); 68 | } 69 | if ( arg.isObfuscateControlFlow ) { 70 | obf.Register(new ONBlockItemList(arg.isRemoveTypeset,arg.isObfuscateConstant)); 71 | } 72 | 73 | obf.Obfuscate(); 74 | 75 | // out put the output file. 76 | ofstream outfile(file.outputfilename); 77 | if ( !outfile ) { 78 | cerr << "Can't output file: \"" << file.outputfilename << "\"" << endl; 79 | throw "Can't output file"; 80 | } 81 | outfile << file.Output() ; 82 | outfile.close(); 83 | 84 | // output the before-after obfuscated table. 85 | if ( arg.isOutputBAfile ) { 86 | ofstream bafilestream(arg.baFile); 87 | if ( !bafilestream ) { 88 | cerr << "Can't output baFile: \"" << arg.baFile << endl; 89 | throw "baFile"; 90 | } 91 | bafilestream << obf.PrintObfuscRecordTable(true); 92 | bafilestream.close(); 93 | } 94 | 95 | /*cout<< "---------------------------" << endl 96 | << file.Output() << endl 97 | << "---------------------------" << endl;*/ 98 | 99 | //cout<< "---------------------------" << endl 100 | // << analys.getCurrentTree()->ToCodeTree() << endl 101 | // << "---------------------------" << endl; 102 | 103 | /*cout<< "---------------------------" << endl 104 | << analys.getCurrentSymbolTable()->PrintSymbolTable() << endl 105 | << "---------------------------" << endl;*/ 106 | 107 | //cout<< "---------------------------" << endl 108 | // << analys.getCurrentTree()->ToCode() << endl 109 | // << "---------------------------" << endl; 110 | 111 | //cout<< "---------------------------" << endl 112 | // << analys.getCurrentTree()->ToSourceCode(true) << endl 113 | // << "---------------------------" << endl; 114 | // 115 | /*cout<< "---------------------------" << endl 116 | << obf.PrintObfuscRecordTable(true) << endl 117 | << "---------------------------" << endl;*/ 118 | 119 | 120 | 121 | 122 | //string after; 123 | //strstream strm; 124 | //strm.setf(ios::showbase | ios::uppercase); 125 | //strm << std::hex << 1234 << endl; 126 | //strm >> after; 127 | 128 | //string s = "'0f'"; 129 | //double a; 130 | //strm.clear(); 131 | //strm << s; 132 | //strm >> a; 133 | 134 | //printf("-------%d--------",(int)s[1]); 135 | // 136 | 137 | //cout<< "---------------------------" << endl 138 | // << a << endl 139 | // << "---------------------------" << endl; 140 | //int a; 141 | 142 | 143 | //// 4debug 144 | //CAnalys analys2; 145 | //analys2.Parse(); 146 | cout << "Success! Please see the file " << file.outputfilename << endl ; 147 | } catch (string e) { 148 | cout << e << endl; 149 | return; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /obfusc/SymbolTable.cpp: -------------------------------------------------------------------------------- 1 | #include "SymbolTable.h" 2 | #include "CParser.h" 3 | 4 | SymbolTable::SymbolTable(void) 5 | { 6 | } 7 | 8 | 9 | SymbolTable::~SymbolTable(void) 10 | { 11 | } 12 | // find Symbol by name 13 | Symbol *SymbolTable::findSymbol(string name) 14 | { 15 | vector::iterator it; 16 | for ( it = symbolList.begin() ; it != symbolList.end() ; it++ ) { 17 | if ( (*it)->name == name ) { 18 | return (*it); 19 | } 20 | } 21 | return NULL; 22 | } 23 | // find TYPE Symbol by name 24 | Symbol *SymbolTable::findTYPE_NAMESymbol(string name) 25 | { 26 | vector::iterator it; 27 | for ( it = symbolList.begin() ; it != symbolList.end() ; it++ ) { 28 | if ( (*it)->type == Symbol::TYPE_NAME && (*it)->name == name ) { 29 | return (*it); 30 | } 31 | } 32 | return NULL; 33 | } 34 | 35 | bool SymbolTable::isExist(string name) 36 | { 37 | if ( findSymbol(name) != NULL ) { 38 | return true; 39 | } 40 | else 41 | return false; 42 | } 43 | 44 | bool SymbolTable::isExistObfusc(string name) 45 | { 46 | vector::iterator it; 47 | for ( it = symbolList.begin() ; it != symbolList.end() ; it++ ) { 48 | Symbol *s = *it; 49 | if ( s->type == Symbol::IDENTIFIER ) { 50 | if ( s->isObfusced == false && s->name == name ) { 51 | return true; 52 | } 53 | if ( s->isObfusced == true && s->nameAfterObfusc == name) { 54 | return true; 55 | } 56 | } else { 57 | cout << s->name ; 58 | } 59 | } 60 | return false; 61 | } 62 | 63 | bool SymbolTable::isExistType(string name) 64 | { 65 | if ( findTYPE_NAMESymbol(name) != NULL ) { 66 | return true; 67 | } 68 | else 69 | return false; 70 | } 71 | 72 | int SymbolTable::GetSize() 73 | { 74 | return (int)symbolList.size(); 75 | } 76 | 77 | 78 | // Lexer will call this. 79 | // It will store the new Symbol and 80 | // log the location. 81 | void SymbolTable::ScanedIdentifier(int t, TokenLocation l) 82 | { 83 | /*cout << endl 84 | << "-----------" << endl 85 | << l.theText << endl 86 | << "-----------" << endl;*/ 87 | Symbol * s; 88 | 89 | switch (t) { 90 | case CParser::IDENTIFIER: 91 | if ( !isExist(l.theText) ) { 92 | s = new Symbol(l.theText); 93 | AddToTable(s); 94 | } else { 95 | s = findSymbol(l.theText); 96 | // ?? 97 | } 98 | s->addLocation(l.first_line,l.first_column,l.last_line,l.last_column); 99 | break; 100 | case CParser::TYPE_NAME: 101 | assert( isExistType(l.theText) ); 102 | s = findTYPE_NAMESymbol(l.theText); 103 | s->addLocation(l.first_line,l.first_column,l.last_line,l.last_column); 104 | break; 105 | } 106 | } 107 | // add to Symbol Table; 108 | void SymbolTable::AddToTable(Symbol * symbol) 109 | { 110 | symbolList.push_back(symbol); 111 | } 112 | 113 | // Convert to TYPE_NAME 114 | void SymbolTable::ConvertIdentifier2TYPE_NAME(string name) 115 | { 116 | Symbol *symbol = findSymbol(name); 117 | if ( symbol == NULL ) { 118 | cerr << "ConvertIdentifier2TYPE_NAME Symbol Not found" << endl; 119 | return; 120 | } 121 | 122 | symbol->type = Symbol::TYPE_NAME; 123 | } 124 | // set the identifier symbol 125 | void SymbolTable::SetIdentifierDeclared(string name) 126 | { 127 | Symbol *symbol = findSymbol(name); 128 | if ( symbol == NULL ) { 129 | cerr << "SymbolTable::SetIdentifierDeclared Symbol Not found" << endl; 130 | return ; 131 | } 132 | 133 | symbol->isDeclared = true; 134 | } 135 | 136 | // print symbol table; 137 | string SymbolTable::PrintSymbolTable() 138 | { 139 | string result ="name\t\tisDecl\ttype\tObfu\n"; 140 | 141 | vector::iterator it; 142 | for( it = symbolList.begin() ; it != symbolList.end() ; it++ ) { 143 | Symbol *s = *it; 144 | result += s->name + ((s->name.length()<8)?"\t\t":"\t"); 145 | result += ((s->isDeclared)?"true\t":"false\t"); 146 | char *table[] = {"IDENTIFIER", "VAR", "FUNC", "TYPE_NAME"}; 147 | result += table[(int)s->type]; 148 | result += "\t"; 149 | 150 | result += ((s->isObfusced)?s->nameAfterObfusc+"\t":"\t"); 151 | 152 | result += "\n"; 153 | } 154 | return result; 155 | } 156 | 157 | 158 | bool SymbolTable::InputTYPE_NAMEFile(string path) 159 | { 160 | ifstream infile(path); 161 | if ( !infile ) { 162 | cerr << "SymbolTable::InputTYPE_NAMEFile Can't open file: \"" << path << "\"" << endl; 163 | return false; 164 | } 165 | string word; 166 | while ( infile >> word ) { 167 | AddTYPE_NAME(word); 168 | } 169 | return true; 170 | } 171 | 172 | void SymbolTable::AddTYPE_NAME(string word) 173 | { 174 | Symbol *s = new Symbol(word, Symbol::TYPE_NAME); 175 | AddToTable(s); 176 | } -------------------------------------------------------------------------------- /obfusc/ArgPack.cpp: -------------------------------------------------------------------------------- 1 | #include "ArgPack.h" 2 | #include "getopt.h" 3 | 4 | ArgPack::ArgPack(int argc, char *const argv []) : 5 | output(""), 6 | isError(false), 7 | isOutputBAfile(false), 8 | isObfuscateConstant(false), 9 | isObfuscateString(false), 10 | isObfuscateIdentifier(false), 11 | isRemoveTypeset(false), 12 | isNotObfuscateFile(false), 13 | isObfuscateLoopStatement(false), 14 | isObfuscateControlFlow(false), 15 | isTYPE_NAMEFile(false) 16 | { 17 | char c; 18 | int err = 0; 19 | string tmp; 20 | while ( (c = getopt(argc, argv, "o:t:csmlki:n:y:p:")) != EOF) 21 | { 22 | switch (c) 23 | { 24 | case 'o': 25 | output = optarg; 26 | break; 27 | case 't': 28 | isOutputBAfile = true; 29 | baFile = optarg; 30 | break; 31 | case 'c': 32 | isObfuscateConstant = true; 33 | break; 34 | case 's': 35 | isObfuscateString = true; 36 | break; 37 | case 'm': 38 | isRemoveTypeset = true; 39 | break; 40 | case 'i': 41 | isObfuscateIdentifier = true; 42 | tmp = optarg; 43 | if ( tmp == "N" ) { 44 | IdentifierGenerator::get().idLookLike = IdentifierGenerator::LL_NORMAL; 45 | } else if ( tmp == "O0" ) { 46 | IdentifierGenerator::get().idLookLike = IdentifierGenerator::LL_O0; 47 | } else if ( tmp == "l1" ) { 48 | IdentifierGenerator::get().idLookLike = IdentifierGenerator::LL_l1; 49 | } else { 50 | IdentifierGenerator::get().idLookLike = IdentifierGenerator::LL_CUSTOM; 51 | // remove same char 52 | string table; 53 | bool isFind = false; 54 | for ( int i = 0; i < (int)tmp.size() - 1; i++ ) { 55 | char p = tmp[i]; 56 | string t = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; 57 | if ( t.find(p) == -1 ) { 58 | cout << "-i custom charactor table should [0-9a-zA-Z]" << endl; 59 | err++; 60 | break; 61 | } 62 | for ( int j = 0; j < (int)table.size() - 1; j++) { 63 | if ( table[j] == p ) { 64 | isFind = true; 65 | break; 66 | } 67 | } 68 | if ( !isFind ) { 69 | table += p; 70 | } else { 71 | cout << "-i custom charactor table can't has same charactor" << endl; 72 | err++; 73 | break; 74 | } 75 | } 76 | 77 | if ( table.size() < 2 ) { 78 | cout << "-i custom charactor table size can't < 2" << endl; 79 | err++; 80 | } 81 | } 82 | break; 83 | case 'n': 84 | isNotObfuscateFile = true; 85 | noFile = optarg; 86 | break; 87 | case 'l': 88 | isObfuscateLoopStatement = true; 89 | break; 90 | case 'k': 91 | isObfuscateControlFlow = true; 92 | break; 93 | case 'p': 94 | isTYPE_NAMEFile = true; 95 | typeNameFile = optarg; 96 | break; 97 | default: 98 | err++; 99 | break; 100 | } 101 | 102 | } 103 | //for (int index = optind; index < argc; index++) 104 | // printf ("Non-option argument %s\n", argv[index]); 105 | if ( argc != optind + 1 ) { 106 | cout << "wrong count of args" << endl; 107 | err++; 108 | } else { 109 | input = argv[optind]; 110 | } 111 | if ( input.empty() ) { 112 | 113 | err++; 114 | } 115 | if ( output.empty() && err == 0 ) { 116 | output = input + ".ob"; 117 | } 118 | if ( err > 0 ) { 119 | useage(argv[0]); 120 | isError = true; 121 | } 122 | } 123 | 124 | 125 | ArgPack::~ArgPack(void) 126 | { 127 | } 128 | 129 | void ArgPack::useage(char *proc) 130 | { 131 | printf( 132 | "C Source Code Obfuscator(CSCO). By falcon. v1.0\n" 133 | "Useage: %s [-o output] [-t table] [-c] [-s] [-i METHOD] [-m] [-l] [-k] [-p type] [-n not] file\n" 134 | "Options:\n" 135 | " -o FILE Set output filename\n" 136 | " -t FILE Output before-after obfuscated table file\n" 137 | " -c Obfuscate constante number\n" 138 | " -s Obfuscate const string\n" 139 | " -i METHOD Obfuscate identifier.\n" 140 | " METHOD is one of: N, O0, l1, or a custom string\n" 141 | " N: normal charactor set. [0-9a-zA-Z]\n" 142 | " O0: use charactor [O0]\n" 143 | " l1: use charactor in [l1]\n" 144 | " [string]: use charactors in [[string]]\n" 145 | " -m Remove Typeset charactors.\n" 146 | " -l Obfuscate the loop statement.\n" 147 | " for, while, do while statement will be replace by if and goto.\n" 148 | " -k Obfuscate the Control Flow.\n" 149 | " -p FILE Input TYPE_NAME file.\n" 150 | " word in file will be considered as a TYPE_NAME,like int.\n" 151 | " -n FILE Input Not Obfuscate Identifier table\n" 152 | " FILE should (separate with a space or enter).\n" 153 | //" -y FILE Output Symbol table\n" 154 | , proc); 155 | } -------------------------------------------------------------------------------- /obfusc/CAnalys.cc: -------------------------------------------------------------------------------- 1 | #include "CAnalys.h" 2 | using namespace std; 3 | 4 | CAnalys::CAnalys() 5 | { 6 | debugFlag=0; 7 | }; 8 | CAnalys::~CAnalys() 9 | { 10 | }; 11 | 12 | void CAnalys::setCurrentCodeFile(CodeFile &file) 13 | { 14 | currentTree = &file.tree; 15 | currentSymbolTable = file.symbolTable; 16 | yyin = file.file; 17 | } 18 | 19 | 20 | //set the debug mode of parser 21 | void CAnalys::SetDebug(int d) 22 | { 23 | debugFlag=d; 24 | fprintf(stderr,"DEBUG MODE =%d\n",debugFlag); 25 | }; 26 | // Check the token in the Symbol Table, if it is a TYPE_NAME. 27 | int CAnalys::check_type(TokenValue &theValue) 28 | { 29 | string str = (char *)theText; 30 | if ( currentSymbolTable->isExistType(str) ) { 31 | return TYPE_NAME; 32 | } 33 | return IDENTIFIER; 34 | } 35 | 36 | //instead of the true Lex ScanValue 37 | int CAnalys::Scan() 38 | { 39 | theTokenLocation.first_line=theLine; 40 | theTokenLocation.first_column=theColumn; 41 | int t=CLexer::ScanValue(theTokenValue); 42 | theTokenLocation.last_line=theLine; 43 | theTokenLocation.last_column=theColumn; 44 | theTokenLocation.text=(char *)theText; 45 | // custom property 46 | theTokenLocation.tokenId = t; 47 | theTokenLocation.theText = (char *)theText; 48 | //theTokenLocation.preString = notValueText; 49 | //notValueText = "" 50 | prestring2exstr(); 51 | theTokenLocation.extraString = exstr; 52 | exstr = NULL; 53 | 54 | // Add to Symbol Table 55 | AddToSymbolTable(t,theTokenLocation); 56 | 57 | 58 | if(debugFlag) 59 | { 60 | fprintf(stderr,"TOKEN %d (l%d,c%d-l%d,c%d)=(%d)\"%*.*s\"\n",t, 61 | theTokenLocation.first_line, 62 | theTokenLocation.first_column, 63 | theTokenLocation.last_line, 64 | theTokenLocation.last_column, 65 | theTextLength,theTextLength, 66 | theTextLength,theTokenLocation.text); 67 | } 68 | return t; 69 | }; 70 | // parser error... 71 | void CAnalys::PrintError(char *s ) 72 | { 73 | 74 | fprintf(stderr,"%s\n",s); 75 | fprintf(stderr,"Stopped at or near token (line %d ,column %d -line %d ,column %d):\"%s\"\n", 76 | theTokenLocation.first_line, theTokenLocation.first_column, 77 | theTokenLocation.last_line, theTokenLocation.last_column, 78 | theTokenLocation.text); 79 | }; 80 | 81 | // Add to Symbol Table. 82 | void CAnalys::AddToSymbolTable(int t,TokenLocation l) 83 | { 84 | switch (t) { 85 | case CParser::IDENTIFIER: 86 | 87 | //case CParser::CONST: 88 | 89 | //case CParser::STRING_LITERAL: 90 | 91 | //case CParser::TYPE_NAME: 92 | currentSymbolTable->ScanedIdentifier(t,l); 93 | break; 94 | } 95 | } 96 | 97 | void CAnalys::OnlyLexer() 98 | { 99 | int t; 100 | while ( (t = Scan()) != 0 ) { 101 | } 102 | } 103 | // If found a typedef declaration. like: 104 | // typedef int a; 105 | // typedef (*a)(int); 106 | // Will set symbol a as a TYPE_NAME. 107 | void CAnalys::FindTPYEDEFDeclaration(Node *node) 108 | { 109 | if ( !node->hasTypedefToken() ) { 110 | return; 111 | } 112 | 113 | vector founds = vector(); 114 | 115 | Node *typedefName; 116 | // declaration_specifiers ';' 117 | if ( node->childNodes.size() == 2 ) { 118 | typedefName = node->getChild(0); 119 | // declaration_specifiers init_declarator_list ';' 120 | } else if ( node->childNodes.size() == 3 ) { 121 | typedefName = node->getChild(1); 122 | } 123 | typedefName->findIdentifierChildren(founds); 124 | 125 | vector::iterator it; 126 | for( it = founds.begin() ; it != founds.end() ; it++) { 127 | // set the Node. 128 | (*it)->tokenId = CParser::TYPE_NAME; 129 | // tell SymbolTable that is a TYPE_NAME 130 | currentSymbolTable->ConvertIdentifier2TYPE_NAME((*it)->tokenString); 131 | currentSymbolTable->SetIdentifierDeclared((*it)->tokenString); 132 | // do more ?? 133 | } 134 | } 135 | 136 | // Parser found a declaration. 137 | void CAnalys::ParsedDeclaration(Node * node) 138 | { 139 | // find TYPEDEF. 140 | FindTPYEDEFDeclaration(node); 141 | 142 | //cout << "found a declaration!" << endl; 143 | // find all identifier. 144 | vector founds = vector(); 145 | node->findIdentifierChildren(founds); 146 | 147 | //cout << "found :" << founds.size() << endl; 148 | // set every identifier declared. 149 | vector::iterator it; 150 | for( it = founds.begin() ; it != founds.end() ; it++) { 151 | currentSymbolTable->SetIdentifierDeclared((*it)->tokenString); 152 | // do more ?? 153 | } 154 | // 155 | //declaration_specifiers 156 | Node *desp = node->getChild(0); 157 | 158 | if ( desp->hasExternToken() ) { 159 | //cout << "Extern !!" << endl; 160 | } 161 | } 162 | // Parser found a function definition. 163 | void CAnalys::ParsedFunctionDefinition(Node *functionNode, Node *declaratorNode) 164 | { 165 | // find the function name identifier. 166 | vector founds = vector(); 167 | declaratorNode->findIdentifierChildren(founds); 168 | 169 | //cout << "found :" << founds.size() << endl; 170 | 171 | //assert(founds.size() == 1); 172 | if ( founds.size() == 0 ) { 173 | cerr << "Error, not found function name in function Node" << endl; 174 | return; 175 | } 176 | 177 | currentSymbolTable->SetIdentifierDeclared(founds[0] -> tokenString); 178 | for ( int i=1 ;i < (int)founds.size(); i++ ) { 179 | currentSymbolTable->SetIdentifierDeclared(founds[i] -> tokenString); 180 | } 181 | // do more ?? 182 | } -------------------------------------------------------------------------------- /obfusc/getopt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1987, 1993, 1994 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | extern "C" { 34 | #if defined(LIBC_SCCS) && !defined(lint) 35 | static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; 36 | #endif /* LIBC_SCCS and not lint */ 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | int opterr = 1, /* if error message should be printed */ 43 | optind = 1, /* index into parent argv vector */ 44 | optopt, /* character checked for validity */ 45 | optreset; /* reset getopt */ 46 | char *optarg; /* argument associated with option */ 47 | 48 | #define BADCH (int)'?' 49 | #define BADARG (int)':' 50 | #define EMSG "" 51 | 52 | /* 53 | * getopt -- 54 | * Parse argc/argv argument vector. 55 | */ 56 | int 57 | getopt(int nargc, char * const *nargv, const char *ostr) 58 | { 59 | #ifdef WIN32 60 | char *__progname="windump"; 61 | #else 62 | extern char *__progname; 63 | #endif 64 | static char *place = EMSG; /* option letter processing */ 65 | char *oli; /* option letter list index */ 66 | 67 | if (optreset || !*place) { /* update scanning pointer */ 68 | optreset = 0; 69 | if (optind >= nargc || *(place = nargv[optind]) != '-') { 70 | place = EMSG; 71 | return (-1); 72 | } 73 | if (place[1] && *++place == '-') { /* found "--" */ 74 | ++optind; 75 | place = EMSG; 76 | return (-1); 77 | } 78 | } /* option letter okay? */ 79 | if ((optopt = (int)*place++) == (int)':' || 80 | !(oli = (char *)strchr(ostr, optopt))) { 81 | /* 82 | * if the user didn't specify '-' as an option, 83 | * assume it means -1. 84 | */ 85 | if (optopt == (int)'-') 86 | return (-1); 87 | if (!*place) 88 | ++optind; 89 | if (opterr && *ostr != ':') 90 | (void)fprintf(stderr, 91 | "%s: illegal option -- %c\n", __progname, optopt); 92 | return (BADCH); 93 | } 94 | if (*++oli != ':') { /* don't need argument */ 95 | optarg = NULL; 96 | if (!*place) 97 | ++optind; 98 | } 99 | else { /* need an argument */ 100 | if (*place) /* no white space */ 101 | optarg = place; 102 | else if (nargc <= ++optind) { /* no arg */ 103 | place = EMSG; 104 | if (*ostr == ':') 105 | return (BADARG); 106 | if (opterr) 107 | (void)fprintf(stderr, 108 | "%s: option requires an argument -- %c\n", 109 | __progname, optopt); 110 | return (BADCH); 111 | } 112 | else /* white space */ 113 | optarg = nargv[optind]; 114 | place = EMSG; 115 | ++optind; 116 | } 117 | return (optopt); /* dump back option letter */ 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /flex_bison/bison.h: -------------------------------------------------------------------------------- 1 | /* before anything */ 2 | #ifdef c_plusplus 3 | #ifndef __cplusplus 4 | #define __cplusplus 5 | #endif 6 | #endif 7 | #ifdef __cplusplus 8 | #ifndef YY_USE_CLASS 9 | #define YY_USE_CLASS 10 | #endif 11 | #else 12 | #endif 13 | #include 14 | $ /* %{ and %header{ and %union, during decl */ 15 | #ifndef YY_@_COMPATIBILITY 16 | #ifndef YY_USE_CLASS 17 | #define YY_@_COMPATIBILITY 1 18 | #else 19 | #define YY_@_COMPATIBILITY 0 20 | #endif 21 | #endif 22 | 23 | #if YY_@_COMPATIBILITY != 0 24 | /* backward compatibility */ 25 | #ifdef YYLTYPE 26 | #ifndef YY_@_LTYPE 27 | #define YY_@_LTYPE YYLTYPE 28 | /* WARNING obsolete !!! user defined YYLTYPE not reported into generated header */ 29 | /* use %define LTYPE */ 30 | #endif 31 | #endif 32 | #ifdef YYSTYPE 33 | #ifndef YY_@_STYPE 34 | #define YY_@_STYPE YYSTYPE 35 | /* WARNING obsolete !!! user defined YYSTYPE not reported into generated header */ 36 | /* use %define STYPE */ 37 | #endif 38 | #endif 39 | #ifdef YYDEBUG 40 | #ifndef YY_@_DEBUG 41 | #define YY_@_DEBUG YYDEBUG 42 | /* WARNING obsolete !!! user defined YYDEBUG not reported into generated header */ 43 | /* use %define DEBUG */ 44 | #endif 45 | #endif 46 | #ifdef YY_@_STYPE 47 | #ifndef yystype 48 | #define yystype YY_@_STYPE 49 | #endif 50 | #endif 51 | /* use goto to be compatible */ 52 | #ifndef YY_@_USE_GOTO 53 | #define YY_@_USE_GOTO 1 54 | #endif 55 | #endif 56 | 57 | /* use no goto to be clean in C++ */ 58 | #ifndef YY_@_USE_GOTO 59 | #define YY_@_USE_GOTO 0 60 | #endif 61 | 62 | #ifndef YY_@_PURE 63 | $/* YY_@_PURE */ 64 | #endif 65 | $/* prefix */ 66 | #ifndef YY_@_DEBUG 67 | $/* YY_@_DEBUG */ 68 | #endif 69 | #ifndef YY_@_LSP_NEEDED 70 | $ /* YY_@_LSP_NEEDED*/ 71 | #endif 72 | /* DEFAULT LTYPE*/ 73 | #ifdef YY_@_LSP_NEEDED 74 | #ifndef YY_@_LTYPE 75 | typedef 76 | struct yyltype 77 | { 78 | int timestamp; 79 | int first_line; 80 | int first_column; 81 | int last_line; 82 | int last_column; 83 | char *text; 84 | } 85 | yyltype; 86 | 87 | #define YY_@_LTYPE yyltype 88 | #endif 89 | #endif 90 | /* DEFAULT STYPE*/ 91 | #ifndef YY_@_STYPE 92 | #define YY_@_STYPE int 93 | #endif 94 | /* DEFAULT MISCELANEOUS */ 95 | #ifndef YY_@_PARSE 96 | #define YY_@_PARSE yyparse 97 | #endif 98 | #ifndef YY_@_LEX 99 | #define YY_@_LEX yylex 100 | #endif 101 | #ifndef YY_@_LVAL 102 | #define YY_@_LVAL yylval 103 | #endif 104 | #ifndef YY_@_LLOC 105 | #define YY_@_LLOC yylloc 106 | #endif 107 | #ifndef YY_@_CHAR 108 | #define YY_@_CHAR yychar 109 | #endif 110 | #ifndef YY_@_NERRS 111 | #define YY_@_NERRS yynerrs 112 | #endif 113 | #ifndef YY_@_DEBUG_FLAG 114 | #define YY_@_DEBUG_FLAG yydebug 115 | #endif 116 | #ifndef YY_@_ERROR 117 | #define YY_@_ERROR yyerror 118 | #endif 119 | 120 | #ifndef YY_@_PARSE_PARAM 121 | #ifndef __STDC__ 122 | #ifndef __cplusplus 123 | #ifndef YY_USE_CLASS 124 | #define YY_@_PARSE_PARAM 125 | #ifndef YY_@_PARSE_PARAM_DEF 126 | #define YY_@_PARSE_PARAM_DEF 127 | #endif 128 | #endif 129 | #endif 130 | #endif 131 | #ifndef YY_@_PARSE_PARAM 132 | #define YY_@_PARSE_PARAM void 133 | #endif 134 | #endif 135 | 136 | /* TOKEN C */ 137 | #ifndef YY_USE_CLASS 138 | 139 | #ifndef YY_@_PURE 140 | extern YY_@_STYPE YY_@_LVAL; 141 | #endif 142 | 143 | $ /* #defines token */ 144 | /* after #define tokens, before const tokens S5*/ 145 | #else 146 | #ifndef YY_@_CLASS 147 | #define YY_@_CLASS @ 148 | #endif 149 | 150 | #ifndef YY_@_INHERIT 151 | #define YY_@_INHERIT 152 | #endif 153 | #ifndef YY_@_MEMBERS 154 | #define YY_@_MEMBERS 155 | #endif 156 | #ifndef YY_@_LEX_BODY 157 | #define YY_@_LEX_BODY 158 | #endif 159 | #ifndef YY_@_ERROR_BODY 160 | #define YY_@_ERROR_BODY 161 | #endif 162 | #ifndef YY_@_CONSTRUCTOR_PARAM 163 | #define YY_@_CONSTRUCTOR_PARAM 164 | #endif 165 | /* choose between enum and const */ 166 | #ifndef YY_@_USE_CONST_TOKEN 167 | #define YY_@_USE_CONST_TOKEN 0 168 | /* yes enum is more compatible with flex, */ 169 | /* so by default we use it */ 170 | #endif 171 | #if YY_@_USE_CONST_TOKEN != 0 172 | #ifndef YY_@_ENUM_TOKEN 173 | #define YY_@_ENUM_TOKEN yy_@_enum_token 174 | #endif 175 | #endif 176 | 177 | class YY_@_CLASS YY_@_INHERIT 178 | { 179 | public: 180 | #if YY_@_USE_CONST_TOKEN != 0 181 | /* static const int token ... */ 182 | $ /* decl const */ 183 | #else 184 | enum YY_@_ENUM_TOKEN { YY_@_NULL_TOKEN=0 185 | $ /* enum token */ 186 | }; /* end of enum declaration */ 187 | #endif 188 | public: 189 | int YY_@_PARSE(YY_@_PARSE_PARAM); 190 | virtual void YY_@_ERROR(char *msg) YY_@_ERROR_BODY; 191 | #ifdef YY_@_PURE 192 | #ifdef YY_@_LSP_NEEDED 193 | virtual int YY_@_LEX(YY_@_STYPE *YY_@_LVAL,YY_@_LTYPE *YY_@_LLOC) YY_@_LEX_BODY; 194 | #else 195 | virtual int YY_@_LEX(YY_@_STYPE *YY_@_LVAL) YY_@_LEX_BODY; 196 | #endif 197 | #else 198 | virtual int YY_@_LEX() YY_@_LEX_BODY; 199 | YY_@_STYPE YY_@_LVAL; 200 | #ifdef YY_@_LSP_NEEDED 201 | YY_@_LTYPE YY_@_LLOC; 202 | #endif 203 | int YY_@_NERRS; 204 | int YY_@_CHAR; 205 | #endif 206 | #if YY_@_DEBUG != 0 207 | public: 208 | int YY_@_DEBUG_FLAG; /* nonzero means print parse trace */ 209 | #endif 210 | public: 211 | YY_@_CLASS(YY_@_CONSTRUCTOR_PARAM); 212 | public: 213 | YY_@_MEMBERS 214 | }; 215 | /* other declare folow */ 216 | #endif 217 | 218 | 219 | #if YY_@_COMPATIBILITY != 0 220 | /* backward compatibility */ 221 | #ifndef YYSTYPE 222 | #define YYSTYPE YY_@_STYPE 223 | #endif 224 | 225 | #ifndef YYLTYPE 226 | #define YYLTYPE YY_@_LTYPE 227 | #endif 228 | #ifndef YYDEBUG 229 | #ifdef YY_@_DEBUG 230 | #define YYDEBUG YY_@_DEBUG 231 | #endif 232 | #endif 233 | 234 | #endif 235 | /* END */ 236 | $ /* section 3 %header{ */ 237 | /* AFTER END , NEVER READ !!! */ 238 | 239 | 240 | 241 | -------------------------------------------------------------------------------- /obfusc/obfusc.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | Source Files 62 | 63 | 64 | Source Files 65 | 66 | 67 | Source Files 68 | 69 | 70 | Source Files 71 | 72 | 73 | Source Files 74 | 75 | 76 | Source Files 77 | 78 | 79 | Source Files 80 | 81 | 82 | Source Files 83 | 84 | 85 | Source Files 86 | 87 | 88 | Source Files 89 | 90 | 91 | Source Files 92 | 93 | 94 | 95 | 96 | Header Files 97 | 98 | 99 | Header Files 100 | 101 | 102 | Header Files 103 | 104 | 105 | Header Files 106 | 107 | 108 | Header Files 109 | 110 | 111 | Header Files 112 | 113 | 114 | Header Files 115 | 116 | 117 | Header Files 118 | 119 | 120 | Header Files 121 | 122 | 123 | Header Files 124 | 125 | 126 | Header Files 127 | 128 | 129 | Header Files 130 | 131 | 132 | Header Files 133 | 134 | 135 | Header Files 136 | 137 | 138 | Header Files 139 | 140 | 141 | Header Files 142 | 143 | 144 | Header Files 145 | 146 | 147 | Header Files 148 | 149 | 150 | Header Files 151 | 152 | 153 | Header Files 154 | 155 | 156 | Header Files 157 | 158 | 159 | Header Files 160 | 161 | 162 | Header Files 163 | 164 | 165 | Header Files 166 | 167 | 168 | Header Files 169 | 170 | 171 | Header Files 172 | 173 | 174 | Header Files 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /obfusc/ONBlockItemList.cpp: -------------------------------------------------------------------------------- 1 | #include "ONBlockItemList.h" 2 | #include "IdentifierGenerator.h" 3 | #include "ONConstant.h" 4 | #include "NumberExpGenerator.h" 5 | 6 | ONBlockItemList::ONBlockItemList(bool isRemoveTypeset, bool isObfuscateConstant): 7 | isRemoveTypeset(isRemoveTypeset), 8 | isObfuscateConstant(isObfuscateConstant) 9 | { 10 | srand((unsigned int)time(0)); 11 | } 12 | 13 | 14 | ONBlockItemList::~ONBlockItemList(void) 15 | { 16 | } 17 | 18 | 19 | bool ONBlockItemList::JudgeType(Node *node) 20 | { 21 | if ( node->nodeType == Node::NODE 22 | && node->nodeTypeName == "block_item_list" 23 | && !node->hasGotoStatement() ) { 24 | return true; 25 | } 26 | return false; 27 | } 28 | void ONBlockItemList::Action(Node *node) 29 | { 30 | if ( !JudgeType(node) ) { 31 | return; 32 | } 33 | // calculate num of statements. 34 | vector statements; 35 | vector declarations; 36 | int numStatements = 0; 37 | int numBlocks = 0; 38 | bool flag = false; 39 | list::iterator it; 40 | for ( it = node->childNodes.begin() ; it != node->childNodes.end() ; it++ ) { 41 | if ( flag == true ) { 42 | if ( !isStatement((*it)) ) { 43 | return; 44 | } 45 | numStatements++; 46 | statements.push_back(*it); 47 | } else { 48 | if ( isStatement((*it)) ) { 49 | flag = true; 50 | numStatements++; 51 | statements.push_back(*it); 52 | } else { 53 | declarations.push_back(*it); 54 | } 55 | } 56 | } 57 | // if statements > 5 will Obfuscate. 58 | if ( numStatements < 6 ) { 59 | return; 60 | } 61 | 62 | // get the statements. (some is declaration) 63 | // pop the childNodes. 64 | 65 | //for ( int i = 0; i < numStatements; i ++ ) { 66 | // Node *tmp = node->childNodes.back(); 67 | // cout << tmp->ToSourceCode(false) << endl; 68 | // if ( tmp && isStatement(tmp) ) { 69 | // node->childNodes.pop_back(); 70 | // statements.push_back(tmp); 71 | // } else { 72 | // break; 73 | // } 74 | //} 75 | assert((int)statements.size()==numStatements); 76 | 77 | // generate blocks count 78 | int minBlocks = 5; 79 | int maxBlocks = (numStatements>100)?100:numStatements; 80 | numBlocks = rand()%(maxBlocks - minBlocks) + minBlocks; 81 | 82 | // generate a random sequence. 83 | GenerateRandomSequence(this->sequence,numBlocks); 84 | 85 | vector statementBlocks; 86 | GenerateRandomStatementBlocks(statementBlocks,numBlocks,numStatements,statements); 87 | /* 88 | tmp=sw;sw=1; 89 | START: 90 | switch (sw) { 91 | case 1: 92 | A; 93 | sw = 3; 94 | goto START; 95 | case 2: 96 | C; 97 | goto END; 98 | case 3: 99 | B; 100 | sw = 2; 101 | goto START; 102 | } 103 | END:sw=tmp; 104 | */ 105 | // front 106 | stringstream ss; 107 | // generate start lable and end lable 108 | startLable = GenerateId(); 109 | endLable = GenerateId(); 110 | // codeFront & codeEnd; 111 | ss << tmpGlobleVar << "=" << globleVar << ";"; 112 | ss << globleVar << "=" << findIndexOfSequence(0) << ";"; 113 | ss << startLable << ":switch(" << globleVar << "){"; 114 | string codeFront = ss.str(); 115 | string codeEnd = "}" + endLable + ":" + globleVar + "=" + tmpGlobleVar + ";" ; 116 | //case 1: 117 | // A; 118 | // sw = 3; 119 | // goto START; 120 | vector bodys; 121 | string body; 122 | for ( int i = 0; i < numBlocks; i++ ) { 123 | ss.str(""); 124 | if ( isObfuscateConstant ) { 125 | ss << "case" << NumberExpGenerator::get().Generate((double)i) << ":"; 126 | } else { 127 | ss << "case " << i << ":"; 128 | } 129 | //ss << statements[numBlocks-1-sequence[i]]->ToSourceCode(isRemoveTypeset); 130 | ss << statementBlocks[sequence[i]] ; 131 | 132 | if ( sequence[i]+1 != numBlocks ) { 133 | if ( isObfuscateConstant ) { 134 | ss << globleVar << "=" << NumberExpGenerator::get().Generate((double)findIndexOfSequence(sequence[i]+1)) << ";"; 135 | } else { 136 | ss << globleVar << "=" << findIndexOfSequence(sequence[i]+1) << ";"; 137 | } 138 | ss << "goto " << startLable << ";"; 139 | } else { 140 | ss << "goto " << endLable << ";"; 141 | } 142 | //body += ss.str(); 143 | bodys.push_back(ss.str()); 144 | } 145 | // random 146 | vector seq; 147 | GenerateRandomSequence(seq,numBlocks); 148 | for ( int i = 0; i < numBlocks; i++ ) { 149 | body += bodys[seq[i]]; 150 | } 151 | 152 | string code = codeFront + body + codeEnd; 153 | // add All to the Node 154 | //node->childNodes.push_back(CreateNodeTOKEN(code)); 155 | 156 | string declaration; 157 | vector::iterator it2; 158 | for ( it2 = declarations.begin(); it2 != declarations.end(); it2++ ) { 159 | declaration += (*it2)->ToSourceCode(isRemoveTypeset); 160 | } 161 | node->isObfuscated = true; 162 | node->obfuscatedTokenString = declaration + code; 163 | } 164 | 165 | void ONBlockItemList::InitAction() 166 | { 167 | // Add globle var 168 | AddGlobleVar(); 169 | } 170 | 171 | bool ONBlockItemList::isStatement(Node *node) 172 | { 173 | if ( node->nodeType == Node::NODE 174 | && node->nodeTypeName == "statement") 175 | return true; 176 | return false; 177 | } 178 | 179 | void ONBlockItemList::AddGlobleVar() 180 | { 181 | globleVar = GenerateId(); 182 | tmpGlobleVar = GenerateId(); 183 | string str = "int " + globleVar + "," + tmpGlobleVar + ";\n"; 184 | 185 | Node *create = new Node("UseInObfuscate",1,CreateNodeTOKEN(str)); 186 | 187 | root->childNodes.push_front(create); 188 | } 189 | 190 | void ONBlockItemList::GenerateRandomSequence(vector &seq, int size) 191 | { 192 | seq.clear(); 193 | int i; 194 | for ( i = 0; i < size; i++ ) { 195 | seq.push_back(i); 196 | } 197 | 198 | for ( i = 0; i < size ; i++ ) 199 | { 200 | int j = rand()%size; 201 | // swap i, j 202 | int tmp = seq[i]; 203 | seq[i] = seq[j]; 204 | seq[j] = tmp; 205 | } 206 | } 207 | 208 | void ONBlockItemList::GenerateRandomStatementBlocks(vector &statementBlock, int blocksize, int numStatement, vector statements) 209 | { 210 | int i; 211 | statementBlock.clear(); 212 | vector tmp; 213 | for ( i= 0; i < numStatement-1;i++) { 214 | tmp.push_back(false); 215 | } 216 | 217 | for ( i = 0; i < blocksize-1; i++ ) { 218 | while (1) { 219 | int i = rand()%(numStatement-1); 220 | if ( tmp[i] == false ) { 221 | tmp[i] = true; 222 | break; 223 | } 224 | } 225 | } 226 | int lasti = 0; 227 | statementBlock.push_back(""); 228 | for (i = 0; i < numStatement-1; i++) { 229 | statementBlock[statementBlock.size()-1] += statements[i]->ToSourceCode(isRemoveTypeset); 230 | if ( tmp[i] == true ) { 231 | statementBlock.push_back(""); 232 | } 233 | } 234 | statementBlock[statementBlock.size()-1] 235 | += statements[numStatement-1]->ToSourceCode(isRemoveTypeset); 236 | 237 | assert(statementBlock.size() == blocksize); 238 | } 239 | 240 | 241 | int ONBlockItemList::findIndexOfSequence(int value) 242 | { 243 | int size = (int)sequence.size(); 244 | for (int i=0 ; i < size; i++ ) { 245 | if ( value == sequence[i] ) { 246 | return i; 247 | } 248 | } 249 | return -1; 250 | } 251 | 252 | 253 | -------------------------------------------------------------------------------- /obfusc/CLexer.l: -------------------------------------------------------------------------------- 1 | %name CLexer 2 | 3 | %header{ 4 | #include "pre.h" 5 | 6 | #include "CLexer.h" 7 | #include "CParser.h" 8 | 9 | #include "ExtraString.h" 10 | 11 | #define TAB_COLUMN 4 12 | #define YY_USER_ACTION BeginAction(); 13 | %} 14 | 15 | %define INHERIT 16 | %define LEX_RETURN int 17 | %define LEX ScanValue 18 | %define LEX_PARAM TokenValue &theValue 19 | %define MEMBERS \ 20 | protected: \ 21 | int theLine,theColumn; \ 22 | string notValueText; \ 23 | ExtraString *exstr; \ 24 | virtual int check_type(TokenValue &theValue); \ 25 | void comment(); \ 26 | void comment2(); \ 27 | void BeginAction(); \ 28 | void notValue(); \ 29 | void preprocess(); \ 30 | void SetColumnLine4Input(char c); \ 31 | void prestring2exstr(); 32 | %define CONSTRUCTOR_PARAM void 33 | %define CONSTRUCTOR_INIT : theLine(1),theColumn(1) 34 | %define CONSTRUCTOR_CODE {exstr=NULL;}; 35 | 36 | %define TEXT theText 37 | %define LENG theTextLength 38 | 39 | 40 | 41 | D [0-9] 42 | L [a-zA-Z_] 43 | H [a-fA-F0-9] 44 | E [Ee][+-]?{D}+ 45 | P [Pp][+-]?{D}+ 46 | FS (f|F|l|L) 47 | IS ((u|U)|(u|U)?(l|L|ll|LL)|(l|L|ll|LL)(u|U)) 48 | 49 | 50 | 51 | %% 52 | 53 | ^[ \t]*"#"[^\n]* { preprocess(); } 54 | "/*" { comment(); } 55 | "//"[^\n]* { /* consume //-comment */comment2(); } 56 | 57 | 58 | "auto" { return(CParser::AUTO); } 59 | "_Bool" { return(CParser::BOOL); } 60 | "break" { return(CParser::BREAK); } 61 | "case" { return(CParser::CASE); } 62 | "char" { return(CParser::CHAR); } 63 | "_Complex" { return(CParser::COMPLEX); } 64 | "const" { return(CParser::CONST); } 65 | "continue" { return(CParser::CONTINUE); } 66 | "default" { return(CParser::DEFAULT); } 67 | "do" { return(CParser::DO); } 68 | "double" { return(CParser::DOUBLE); } 69 | "else" { return(CParser::ELSE); } 70 | "enum" { return(CParser::ENUM); } 71 | "extern" { return(CParser::EXTERN); } 72 | "float" { return(CParser::FLOAT); } 73 | "for" { return(CParser::FOR); } 74 | "goto" { return(CParser::GOTO); } 75 | "if" { return(CParser::IF); } 76 | "_Imaginary" { return(CParser::IMAGINARY); } 77 | "inline" { return(CParser::INLINE); } 78 | "int" { return(CParser::INT); } 79 | "long" { return(CParser::LONG); } 80 | "register" { return(CParser::REGISTER); } 81 | "restrict" { return(CParser::RESTRICT); } 82 | "return" { return(CParser::RETURN); } 83 | "short" { return(CParser::SHORT); } 84 | "signed" { return(CParser::SIGNED); } 85 | "sizeof" { return(CParser::SIZEOF); } 86 | "static" { return(CParser::STATIC); } 87 | "struct" { return(CParser::STRUCT); } 88 | "switch" { return(CParser::SWITCH); } 89 | "typedef" { return(CParser::TYPEDEF); } 90 | "union" { return(CParser::UNION); } 91 | "unsigned" { return(CParser::UNSIGNED); } 92 | "void" { return(CParser::VOID); } 93 | "volatile" { return(CParser::VOLATILE); } 94 | "while" { return(CParser::WHILE); } 95 | 96 | {L}({L}|{D})* { return(check_type(theValue)); } 97 | 98 | 0[xX]{H}+{IS}? { return(CParser::CONSTANT); } 99 | 0{D}+{IS}? { return(CParser::CONSTANT); } 100 | {D}+{IS}? { return(CParser::CONSTANT); } 101 | L?'(\\.|[^\\'\n])+' { return(CParser::CONSTANT); } 102 | 103 | {D}+{E}{FS}? { return(CParser::CONSTANT); } 104 | {D}*"."{D}+({E})?{FS}? { return(CParser::CONSTANT); } 105 | {D}+"."{D}*({E})?{FS}? { return(CParser::CONSTANT); } 106 | 0[xX]{H}+{P}{FS}? { return(CParser::CONSTANT); } 107 | 0[xX]{H}*"."{H}+({P})?{FS}? { return(CParser::CONSTANT); } 108 | 0[xX]{H}+"."{H}*({P})?{FS}? { return(CParser::CONSTANT); } 109 | 110 | 111 | L?\"(\\.|[^\\"\n])*\" { return(CParser::STRING_LITERAL); } 112 | 113 | "..." { return(CParser::ELLIPSIS); } 114 | ">>=" { return(CParser::RIGHT_ASSIGN); } 115 | "<<=" { return(CParser::LEFT_ASSIGN); } 116 | "+=" { return(CParser::ADD_ASSIGN); } 117 | "-=" { return(CParser::SUB_ASSIGN); } 118 | "*=" { return(CParser::MUL_ASSIGN); } 119 | "/=" { return(CParser::DIV_ASSIGN); } 120 | "%=" { return(CParser::MOD_ASSIGN); } 121 | "&=" { return(CParser::AND_ASSIGN); } 122 | "^=" { return(CParser::XOR_ASSIGN); } 123 | "|=" { return(CParser::OR_ASSIGN); } 124 | ">>" { return(CParser::RIGHT_OP); } 125 | "<<" { return(CParser::LEFT_OP); } 126 | "++" { return(CParser::INC_OP); } 127 | "--" { return(CParser::DEC_OP); } 128 | "->" { return(CParser::PTR_OP); } 129 | "&&" { return(CParser::AND_OP); } 130 | "||" { return(CParser::OR_OP); } 131 | "<=" { return(CParser::LE_OP); } 132 | ">=" { return(CParser::GE_OP); } 133 | "==" { return(CParser::EQ_OP); } 134 | "!=" { return(CParser::NE_OP); } 135 | ";" { return(';'); } 136 | ("{"|"<%") { return('{'); } 137 | ("}"|"%>") { return('}'); } 138 | "," { return(','); } 139 | ":" { return(':'); } 140 | "=" { return('='); } 141 | "(" { return('('); } 142 | ")" { return(')'); } 143 | ("["|"<:") { return('['); } 144 | ("]"|":>") { return(']'); } 145 | "." { return('.'); } 146 | "&" { return('&'); } 147 | "!" { return('!'); } 148 | "~" { return('~'); } 149 | "-" { return('-'); } 150 | "+" { return('+'); } 151 | "*" { return('*'); } 152 | "/" { return('/'); } 153 | "%" { return('%'); } 154 | "<" { return('<'); } 155 | ">" { return('>'); } 156 | "^" { return('^'); } 157 | "|" { return('|'); } 158 | "?" { return('?'); } 159 | 160 | [ \t\v\n\f] { notValue(); } 161 | . { /* Add code to complain about unmatched characters */ } 162 | 163 | %% 164 | 165 | void CLexer::notValue() 166 | { 167 | notValueText += (char *)theText; 168 | } 169 | 170 | void CLexer::comment(void) 171 | { 172 | prestring2exstr(); 173 | 174 | char c, prev = 0; 175 | notValueText += "/*"; 176 | while ((c = yyinput()) != 0) /* (EOF maps to 0) */ 177 | { 178 | SetColumnLine4Input(c); 179 | //printf("%c",c); 180 | 181 | if (c == '/' && prev == '*') { 182 | notValueText += "/"; 183 | break; 184 | } 185 | prev = c; 186 | notValueText += c; 187 | } 188 | /*error("unterminated comment");*/ 189 | // add COMMENT to exstr 190 | exstr->addString(ExtraString::COMMENT, notValueText); 191 | notValueText = ""; 192 | } 193 | void CLexer::comment2() 194 | { 195 | char c; 196 | prestring2exstr(); 197 | // read one more \n 198 | notValueText += (char *)theText; 199 | c = yyinput(); 200 | if ( c != 0 ) { 201 | SetColumnLine4Input(c); 202 | notValueText += c; 203 | } 204 | 205 | // add COMMENT to exstr 206 | exstr->addString(ExtraString::COMMENT, notValueText); 207 | notValueText = ""; 208 | } 209 | 210 | void CLexer::prestring2exstr() 211 | { 212 | // add pre TYPESET to exstr 213 | if ( exstr == NULL ) { 214 | exstr = new ExtraString(); 215 | } 216 | if ( !notValueText.empty() ) { 217 | exstr->addString(ExtraString::TYPESET, notValueText); 218 | } 219 | notValueText = ""; 220 | } 221 | void CLexer::preprocess(void) 222 | { 223 | prestring2exstr(); 224 | 225 | char c; 226 | notValueText += (char *)theText; 227 | 228 | while ((c = yyinput()) != 0) /* (EOF maps to 0) */ 229 | { 230 | SetColumnLine4Input(c); 231 | //printf("%c",c); 232 | 233 | notValueText += c; 234 | if (c == '\n') { 235 | // because of notValueText at least will be "# \".length > 2 236 | if ( notValueText.length() > 2 && 237 | notValueText[notValueText.length()-2] == '\\' ) { 238 | continue; 239 | } else { 240 | break; 241 | } 242 | } 243 | } 244 | 245 | // add PREPROCESS to exstr 246 | exstr->addString(ExtraString::PREPROCESS, notValueText); 247 | notValueText = ""; 248 | } 249 | 250 | 251 | void CLexer::SetColumnLine4Input(char c) 252 | { 253 | if (c == '\n') { 254 | theColumn = 1; 255 | theLine ++; 256 | } 257 | else if (c == '\t') 258 | theColumn += TAB_COLUMN - (theColumn % TAB_COLUMN); 259 | else 260 | theColumn++; 261 | 262 | 263 | } 264 | 265 | int CLexer::check_type(TokenValue &theValue) 266 | { 267 | 268 | return CParser::IDENTIFIER; 269 | } 270 | 271 | // execute before every action in lex 272 | void CLexer::BeginAction(void) 273 | { 274 | // count the column & lineno 275 | int i; 276 | 277 | for (i = 0; theText[i] != '\0'; i++) { 278 | SetColumnLine4Input(theText[i]); 279 | } 280 | 281 | // echo theText 282 | //yy_echo(); 283 | }; 284 | -------------------------------------------------------------------------------- /obfusc/Node.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Node.h" 3 | #include "CParser.h" 4 | 5 | Node::Node(void) 6 | { 7 | } 8 | Node::~Node(void) 9 | { 10 | } 11 | 12 | // create node with location 13 | Node::Node(TokenLocation l) : isObfuscated(false) 14 | { 15 | nodeType = TOKEN; 16 | tokenId = l.tokenId; 17 | tokenString = l.theText; 18 | nodeTypeName = ""; 19 | preString = l.preString; 20 | extraString = l.extraString; 21 | 22 | // set Location 23 | first_line = l.first_line; 24 | first_column = l.first_column; 25 | last_line = l.last_line; 26 | last_column = l.last_column; 27 | } 28 | // create node with typename; 29 | Node::Node(string typeName,int num,...) : isObfuscated(false) 30 | { 31 | // set the NodeType to NODE 32 | nodeType = Node::NODE; 33 | nodeTypeName = typeName; 34 | 35 | // add child nodes; 36 | Node *n; 37 | va_list arg_ptr; 38 | va_start(arg_ptr,num); 39 | for ( int i=0 ; i < num ; i++ ) { 40 | n = va_arg(arg_ptr, Node *); 41 | this->AddChildNode(n); 42 | n->parent = this; 43 | // 4debug 44 | //cout << n->nodeIndex << endl; 45 | } 46 | va_end(arg_ptr); 47 | 48 | } 49 | 50 | // add Child node. will push to childNodesList, and set the location. 51 | void Node::AddChildNode(Node *n) 52 | { 53 | // childNodes push 54 | childNodes.push_back(n); 55 | 56 | // setLocation 57 | if ( (int)childNodes.size() == 1 ) { 58 | first_line = n->first_line; 59 | first_column = n->first_column; 60 | } 61 | 62 | last_line = n->last_line; 63 | last_column = n->last_column; 64 | } 65 | 66 | void Node::AddChildNode(int num, ...) 67 | { 68 | // add child nodes; 69 | Node *n; 70 | va_list arg_ptr; 71 | va_start(arg_ptr,num); 72 | for ( int i=0 ; i < num ; i++ ) { 73 | n = va_arg(arg_ptr, Node *); 74 | this->AddChildNode(n); 75 | // 4debug 76 | //cout << n->nodeIndex << endl; 77 | } 78 | va_end(arg_ptr); 79 | } 80 | 81 | string Node::ToSourceCode(bool isRemoveTypeset) 82 | { 83 | string result = ""; 84 | if ( this == NULL ) { 85 | cerr << "Node::ToCodeCall Node NULL" << endl; 86 | return result; 87 | } 88 | // TOKEN. 89 | if ( this->nodeType == TOKEN ) { 90 | if ( isRemoveTypeset ) { 91 | result += this->extraString->toShortString(); 92 | } else { 93 | result += this->extraString->toString(); 94 | } 95 | if ( this->isObfuscated == true ) { 96 | result += this->obfuscatedTokenString; 97 | } else { 98 | result += this->tokenString; 99 | } 100 | // A Node. 101 | } else { 102 | if ( this->isObfuscated ) { 103 | result += this->obfuscatedTokenString; 104 | } else { 105 | list::iterator it; 106 | for ( it = this->childNodes.begin() ; it != this->childNodes.end() ; it++) { 107 | //result += (*it)->ToSourceCode(isRemoveTypeset); 108 | string str = (*it)->ToSourceCode(isRemoveTypeset); 109 | // determine if should add a space. 110 | if ( isRemoveTypeset && !result.empty() && !str.empty() ) { 111 | char c = result[result.length()-1]; 112 | char d = str[0]; 113 | if ( isLetter(c) && isLetter(d) ) { 114 | result += " "; 115 | } 116 | } 117 | result += str; 118 | } 119 | } 120 | } 121 | return result; 122 | } 123 | bool Node::isLetter(char c) 124 | { 125 | if ( ( c >= 'a' && c<='z' ) 126 | || ( c >= 'A' && c<= 'Z' ) 127 | || ( c == '_' ) 128 | || ( c >= '0' && c<= '9' )) 129 | { 130 | return true; 131 | } 132 | return false; 133 | } 134 | 135 | // To Code 136 | string Node::ToCode() 137 | { 138 | string result = ""; 139 | if ( this == NULL ) { 140 | cerr << "Node::ToCodeCall Node NULL" << endl; 141 | return result; 142 | } 143 | if ( this->nodeType == TOKEN ) { 144 | // 145 | result += this->extraString->toString(); 146 | 147 | if ( this->isObfuscated == true ) { 148 | result += this->obfuscatedTokenString; 149 | } else { 150 | result += this->tokenString; 151 | } 152 | } else { 153 | list::iterator it; 154 | for ( it = this->childNodes.begin() ; it != this->childNodes.end() ; it++) { 155 | result += (*it)->ToCode(); 156 | } 157 | } 158 | return result; 159 | } 160 | 161 | 162 | // print the Tree; 163 | string Node::ToCodeTree() 164 | { 165 | return this->ToCodeTreeCall(0); 166 | } 167 | // print the Tree; 168 | string Node::ToCodeTreeCall(int level) 169 | { 170 | string result = ""; 171 | 172 | if ( this == NULL ) { 173 | cerr << "Node::ToCodeTreeCall Node NULL" << endl; 174 | return result; 175 | } 176 | 177 | for ( int i = 0 ; i < level ; i++ ) { 178 | result += " "; 179 | } 180 | 181 | if ( this->nodeType == TOKEN ) { 182 | char tokenIdChar[5]; 183 | sprintf(tokenIdChar,"%d",this->tokenId); 184 | result += "TOKEN:(" + this->tokenString + ") typeID:"+ tokenIdChar +"\n"; 185 | } else { 186 | result += this->nodeTypeName + "\n"; 187 | list::iterator it; 188 | for ( it = this->childNodes.begin() ; it != this->childNodes.end() ; it++) { 189 | result += (*it)->ToCodeTreeCall(level + 1); 190 | } 191 | } 192 | return result; 193 | } 194 | 195 | 196 | // find all identifier children. called by parser. 197 | void Node::findIdentifierChildren(vector &found) 198 | { 199 | if ( this == NULL ) { 200 | cerr << "Node::findIdentifierChildrenCall Node NULL" << endl; 201 | return ; 202 | } 203 | 204 | if ( this->nodeType == TOKEN ) { 205 | if ( this->tokenId == CParser::IDENTIFIER ) { 206 | found.push_back(this); 207 | } 208 | } else { 209 | list::iterator it; 210 | for ( it = this->childNodes.begin() ; it != this->childNodes.end() ; it++) { 211 | (*it)->findIdentifierChildren(found); 212 | } 213 | } 214 | return ; 215 | } 216 | 217 | Node * Node::getChild(int index) 218 | { 219 | list::iterator it = this->childNodes.begin(); 220 | for ( int i = 0 ; i < index; i ++ ) { 221 | it ++; 222 | } 223 | return (*it); 224 | } 225 | 226 | bool Node::hasTypedefToken() 227 | { 228 | Node::iterator it; 229 | for ( it = this->begin() ; it != this->end() ; it++) 230 | { 231 | if ( (*it)->isToken(CParser::TYPEDEF) ) { 232 | return true; 233 | } 234 | } 235 | return false; 236 | } 237 | // has Extern token 238 | bool Node::hasExternToken() 239 | { 240 | Node::iterator it; 241 | for ( it = this->begin() ; it != this->end() ; it++) 242 | { 243 | if ( (*it)->isToken(CParser::EXTERN) ) { 244 | return true; 245 | } 246 | } 247 | 248 | return false; 249 | } 250 | 251 | // has 252 | bool Node::hasGotoStatement() 253 | { 254 | Node::iterator it; 255 | for ( it = this->begin(); it != this->end(); it++ ) { 256 | if ( (*it)->isToken(CParser::GOTO) ) { 257 | return true; 258 | } 259 | } 260 | return false; 261 | } 262 | 263 | bool Node::isToken(int tokenId) 264 | { 265 | if ( this->nodeType == Node::TOKEN && this->tokenId == tokenId ) { 266 | return true; 267 | } 268 | return false; 269 | } 270 | 271 | bool Node::isNode(string nodeTypeName) 272 | { 273 | if ( this->nodeType == Node::NODE && this->nodeTypeName == nodeTypeName ) { 274 | return true; 275 | } 276 | return false; 277 | } 278 | 279 | //void Node::Traversal(void (*func)()) 280 | //{ 281 | // if ( this == NULL ) { 282 | // cerr << "Node::Traversal Node NULL" << endl; 283 | // return ; 284 | // } 285 | // 286 | // if ( this->nodeType == TOKEN ) { 287 | // func(); 288 | // } else { 289 | // list::iterator it; 290 | // for ( it = this->childNodes.begin() ; it != this->childNodes.end() ; it++) { 291 | // (*it)->Traversal(func); 292 | // } 293 | // func(); 294 | // } 295 | // return ; 296 | //} 297 | 298 | void Node::TraversalAllNode(list &l) 299 | { 300 | if ( this == NULL ) { 301 | cerr << "Node::Traversal Node NULL" << endl; 302 | return ; 303 | } 304 | 305 | if ( this->nodeType == TOKEN ) { 306 | l.push_back(this); 307 | } else { 308 | list::iterator it; 309 | for ( it = this->childNodes.begin() ; it != this->childNodes.end() ; it++) { 310 | (*it)->TraversalAllNode(l); 311 | } 312 | l.push_back(this); 313 | } 314 | return ; 315 | } 316 | 317 | list::iterator Node::begin() 318 | { 319 | traversaledList = list(); 320 | TraversalAllNode(traversaledList); 321 | return traversaledList.begin(); 322 | } 323 | 324 | list::iterator Node::end() 325 | { 326 | return traversaledList.end(); 327 | } -------------------------------------------------------------------------------- /obfusc/obfusc.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | false 72 | CppCode 73 | 74 | 75 | CppCode 76 | 77 | 78 | 79 | 80 | {4EC6E0E8-1BA0-41EF-95C3-A720FE870A61} 81 | Win32Proj 82 | obfusc 83 | 84 | 85 | 86 | Application 87 | true 88 | Unicode 89 | v90 90 | 91 | 92 | Application 93 | false 94 | true 95 | Unicode 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | true 109 | ClCompile 110 | 111 | 112 | false 113 | 114 | 115 | false 116 | ClCompile 117 | false 118 | 119 | 120 | 121 | 122 | 123 | Level3 124 | Disabled 125 | WIN32;MSDOS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 126 | false 127 | pre.h 128 | 129 | 130 | Console 131 | true 132 | false 133 | 134 | 135 | cd $(ProjectDir) 136 | echo 137 | echo bison....... bison++ -d -o CParser.cc -h CParser.h CParser.y 138 | ..\flex_bison\bison++ -d -o CParser.cc -h CParser.h CParser.y 139 | echo 140 | echo flexing...... flex++ -8 -hCLexer.h -oCLexer.cc CLexer.l 141 | ..\flex_bison\flex++ -8 -hCLexer.h -oCLexer.cc CLexer.l 142 | 1 143 | 进入Flex,Bison解析阶段 144 | 145 | 146 | 147 | 148 | Level3 149 | 150 | 151 | MaxSpeed 152 | true 153 | true 154 | WIN32;MSDOS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 155 | false 156 | 157 | 158 | Console 159 | true 160 | true 161 | true 162 | false 163 | 164 | 165 | cd $(ProjectDir) 166 | echo 167 | echo bison....... bison++ -d -o CParser.cc -h CParser.h CParser.y 168 | ..\flex_bison\bison++ -d -o CParser.cc -h CParser.h CParser.y 169 | echo 170 | echo flexing...... flex++ -8 -hCLexer.h -oCLexer.cc CLexer.l 171 | ..\flex_bison\flex++ -8 -hCLexer.h -oCLexer.cc CLexer.l 172 | 进入Flex,Bison解析阶段 173 | 1 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /flex_bison/flexskel.h: -------------------------------------------------------------------------------- 1 | /* A lexical scanner header generated by flex */ 2 | /* MODIFIED FOR C++ CLASS BY Alain Coetmeur: coetmeur(at)icdc.fr */ 3 | /* Note that (at) mean the 'at' symbol that I cannot write */ 4 | /* because it is expanded to the class name */ 5 | /* made at Informatique-CDC, Research&development department */ 6 | /* company from the Caisse Des Depots et Consignations */ 7 | 8 | 9 | /*********************************************/ 10 | /* SYSTEM dependent declaration, includes... */ 11 | /*********************************************/ 12 | /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ 13 | #ifdef c_plusplus 14 | #ifndef __cplusplus 15 | #define __cplusplus 16 | #endif 17 | #endif 18 | #ifdef __cplusplus 19 | #ifndef YY_USE_PROTOS 20 | #define YY_USE_PROTOS 21 | #endif 22 | #ifndef YY_USE_CLASS 23 | #define YY_USE_CLASS 24 | #endif 25 | #else /* ! __cplusplus */ 26 | #ifdef __STDC__ 27 | #ifdef __GNUC__ 28 | #else 29 | #endif /* __GNUC__ */ 30 | #ifndef YY_USE_PROTOS 31 | #define YY_USE_PROTOS 32 | #endif 33 | #endif /* __STDC__ */ 34 | #endif /* ! __cplusplus */ 35 | /*********************************************/ 36 | /* COMPILER DEPENDENT MACROS */ 37 | /*********************************************/ 38 | /* use prototypes in function declarations */ 39 | #ifndef YY_PROTO 40 | #ifdef YY_USE_PROTOS 41 | #define YY_PROTO(proto) proto 42 | #else 43 | #define YY_PROTO(proto) () 44 | #endif 45 | #endif 46 | #include 47 | 48 | 49 | 50 | 51 | %% here is the declaration from section1 %header{ 52 | 53 | #ifdef YY_USE_CLASS 54 | #ifdef YY_@_IOSTREAM 55 | #include 56 | #define YY_@_IFILE istream 57 | #define YY_@_OFILE ostream 58 | #define YY_@_ERRFILE cerr 59 | 60 | #ifndef YY_@_IFILE_DEFAULT 61 | #define YY_@_IFILE_DEFAULT &cin 62 | #endif 63 | 64 | #ifndef YY_@_OFILE_DEFAULT 65 | #define YY_@_OFILE_DEFAULT &cout 66 | #endif 67 | 68 | #endif 69 | #endif 70 | 71 | #ifndef YY_@_IFILE 72 | #define YY_@_IFILE FILE 73 | #endif 74 | 75 | #ifndef YY_@_OFILE 76 | #define YY_@_OFILE FILE 77 | #endif 78 | 79 | #ifndef YY_@_ERRFILE 80 | #define YY_@_ERRFILE stderr 81 | #endif 82 | 83 | #ifndef YY_@_IFILE_DEFAULT 84 | #define YY_@_IFILE_DEFAULT stdin 85 | #endif 86 | 87 | #ifndef YY_@_OFILE_DEFAULT 88 | #define YY_@_OFILE_DEFAULT stdout 89 | #endif 90 | 91 | 92 | 93 | 94 | #ifndef YY_@_TEXT 95 | #define YY_@_TEXT yytext 96 | #endif 97 | #ifndef YY_@_LENG 98 | #define YY_@_LENG yyleng 99 | #endif 100 | #ifndef YY_@_IN 101 | #define YY_@_IN yyin 102 | #endif 103 | #ifndef YY_@_OUT 104 | #define YY_@_OUT yyout 105 | #endif 106 | 107 | #ifndef YY_@_LEX_RETURN 108 | #define YY_@_LEX_RETURN int 109 | #else 110 | #ifndef YY_@_LEX_DEFINED 111 | #define YY_@_LEX_DEFINED 112 | #endif 113 | #endif 114 | 115 | #ifndef YY_@_LEX 116 | #define YY_@_LEX yylex 117 | #else 118 | #ifndef YY_@_LEX_DEFINED 119 | #define YY_@_LEX_DEFINED 120 | #endif 121 | #endif 122 | 123 | #ifndef YY_@_LEX_PARAM 124 | #ifndef YY_USE_PROTOS 125 | #define YY_@_LEX_PARAM 126 | #else 127 | #define YY_@_LEX_PARAM void 128 | #endif 129 | #else 130 | #ifndef YY_@_LEX_DEFINED 131 | #define YY_@_LEX_DEFINED 132 | #endif 133 | #endif 134 | 135 | #ifndef YY_@_LEX_PARAM_DEF 136 | #define YY_@_LEX_PARAM_DEF 137 | #else 138 | #ifndef YY_@_LEX_DEFINED 139 | #define YY_@_LEX_DEFINED 140 | #endif 141 | #endif 142 | 143 | #ifndef YY_@_RESTART 144 | #define YY_@_RESTART yyrestart 145 | #endif 146 | #ifndef YY_@_SWITCH_TO_BUFFER 147 | #define YY_@_SWITCH_TO_BUFFER yy_switch_to_buffer 148 | #endif 149 | #ifndef YY_@_LOAD_BUFFER_STATE 150 | #define YY_@_LOAD_BUFFER_STATE yy_load_buffer_state 151 | #endif 152 | 153 | #ifndef YY_@_CREATE_BUFFER 154 | #define YY_@_CREATE_BUFFER yy_create_buffer 155 | #ifndef YY_USE_CLASS 156 | #ifndef yy_new_buffer 157 | #define yy_new_buffer yy_create_buffer 158 | #endif 159 | #endif 160 | #endif 161 | #ifndef YY_@_DELETE_BUFFER 162 | #define YY_@_DELETE_BUFFER yy_delete_buffer 163 | #endif 164 | #ifndef YY_@_INIT_BUFFER 165 | #define YY_@_INIT_BUFFER yy_init_buffer 166 | #endif 167 | 168 | 169 | 170 | #ifdef YY_@_FLEX_DEBUG 171 | #ifndef YY_@_DEBUG 172 | #define YY_@_DEBUG 1 173 | #endif 174 | #else 175 | #ifndef YY_@_DEBUG 176 | #define YY_@_DEBUG 0 177 | #endif 178 | #endif 179 | 180 | #if YY_@_DEBUG != 0 181 | #ifndef YY_@_DEBUG_FLAG 182 | #define YY_@_DEBUG_FLAG yy_flex_debug 183 | #endif 184 | #ifndef YY_@_DEBUG_INIT 185 | #define YY_@_DEBUG_INIT 1 186 | #endif 187 | #endif 188 | 189 | 190 | 191 | 192 | #ifndef YY_USE_CLASS 193 | #ifndef YY_@_CURRENT_BUFFER 194 | #define YY_@_CURRENT_BUFFER yy_current_buffer 195 | #endif 196 | typedef struct yy_buffer_state *YY_BUFFER_STATE; 197 | 198 | extern void YY_@_RESTART YY_PROTO(( YY_@_IFILE *input_file )); 199 | extern void YY_@_SWITCH_TO_BUFFER YY_PROTO(( YY_BUFFER_STATE new_buffer )); 200 | extern void YY_@_LOAD_BUFFER_STATE YY_PROTO(( void )); 201 | extern YY_BUFFER_STATE YY_@_CREATE_BUFFER YY_PROTO(( YY_@_IFILE *file, int size )); 202 | extern void YY_@_DELETE_BUFFER YY_PROTO(( YY_BUFFER_STATE b )); 203 | extern void YY_@_INIT_BUFFER YY_PROTO(( YY_BUFFER_STATE b, YY_@_IFILE *file )); 204 | 205 | #if YY_@_DEBUG != 0 206 | extern int YY_@_DEBUG_FLAG ; 207 | #endif 208 | extern YY_@_CHAR *YY_@_TEXT; 209 | extern int YY_@_LENG; 210 | extern YY_@_IFILE *YY_@_IN; 211 | extern YY_@_OFILE *YY_@_OUT; 212 | #ifdef YY_@_LEX_DEFINED 213 | extern YY_@_LEX_RETURN YY_@_LEX ( YY_@_LEX_PARAM ) 214 | YY_@_LEX_PARAM_DEF 215 | #else 216 | #ifndef YY_DECL 217 | extern YY_@_LEX_RETURN YY_@_LEX ( YY_@_LEX_PARAM ) 218 | YY_@_LEX_PARAM_DEF 219 | #else 220 | /* no declaration if oldstyle flex */ 221 | #endif 222 | #endif 223 | #else 224 | 225 | #ifndef YY_@_CURRENT_BUFFER 226 | #define YY_@_CURRENT_BUFFER YY_CURRENT_BUFFER 227 | #endif 228 | #ifndef YY_@_CLASS 229 | #define YY_@_CLASS @ 230 | #endif 231 | #ifndef YY_@_ECHO 232 | #define YY_@_ECHO yy_echo 233 | #endif 234 | #ifdef YY_@_ECHO_PURE 235 | #define YY_@_ECHO_NOCODE 236 | #endif 237 | 238 | #ifndef YY_@_ECHO_CODE 239 | #ifndef YY_@_IOSTREAM 240 | #define YY_@_ECHO_CODE fwrite( (char *) YY_@_TEXT, YY_@_LENG, 1, YY_@_OUT ); 241 | #else 242 | #define YY_@_ECHO_CODE (YY_@_OUT->write( (char *) YY_@_TEXT, YY_@_LENG)); 243 | #endif 244 | #endif 245 | 246 | #ifndef YY_@_INPUT 247 | #define YY_@_INPUT yy_input 248 | #endif 249 | #ifdef YY_@_INPUT_PURE 250 | #define YY_@_INPUT_NOCODE 251 | #endif 252 | 253 | #ifndef YY_@_INPUT_CODE 254 | #ifndef YY_@_IOSTREAM 255 | #define YY_@_INPUT_CODE return result= fread( buffer, 1,max_size,YY_@_IN ); 256 | #else 257 | #define YY_@_INPUT_CODE if(YY_@_IN->eof()) result=0;else {YY_@_IN->read(buffer,max_size);result=YY_@_IN->gcount();YY_@_IN->clear(YY_@_IN->rdstate()&(~ios::failbit));if(YY_@_IN->bad()) result= -1;} return result; 258 | #endif 259 | #endif 260 | 261 | #ifdef YY_@_FATAL_ERROR_PURE 262 | #define YY_@_FATAL_ERRO_NOCODE 263 | #endif 264 | #ifndef YY_@_FATAL_ERROR 265 | #define YY_@_FATAL_ERROR yy_fatal_error 266 | #endif 267 | 268 | #ifndef YY_@_FATAL_ERROR_CODE 269 | #ifndef YY_@_IOSTREAM 270 | #define YY_@_FATAL_ERROR_CODE fputs( msg, YY_@_ERRFILE );putc( '\n', YY_@_ERRFILE );exit( 1 ); 271 | #else 272 | #define YY_@_FATAL_ERROR_CODE YY_@_ERRFILE<< msg < 51 | 52 | 53 | 54 | 55 | /* % here is the declaration from section1 %header{ */ 56 | #line 4 "CLexer.l" 57 | #include "pre.h" 58 | 59 | #include "CLexer.h" 60 | #include "CParser.h" 61 | 62 | #include "ExtraString.h" 63 | 64 | #define TAB_COLUMN 4 65 | #define YY_USER_ACTION BeginAction(); 66 | #line 15 "CLexer.l" 67 | #define YY_CLexer_INHERIT 68 | #line 16 "CLexer.l" 69 | #define YY_CLexer_LEX_RETURN int 70 | #line 17 "CLexer.l" 71 | #define YY_CLexer_LEX ScanValue 72 | #line 18 "CLexer.l" 73 | #define YY_CLexer_LEX_PARAM TokenValue &theValue 74 | #line 19 "CLexer.l" 75 | #define YY_CLexer_MEMBERS \ 76 | protected: \ 77 | int theLine,theColumn; \ 78 | string notValueText; \ 79 | ExtraString *exstr; \ 80 | virtual int check_type(TokenValue &theValue); \ 81 | void comment(); \ 82 | void comment2(); \ 83 | void BeginAction(); \ 84 | void notValue(); \ 85 | void preprocess(); \ 86 | void SetColumnLine4Input(char c); \ 87 | void prestring2exstr(); 88 | #line 32 "CLexer.l" 89 | #define YY_CLexer_CONSTRUCTOR_PARAM void 90 | #line 33 "CLexer.l" 91 | #define YY_CLexer_CONSTRUCTOR_INIT : theLine(1),theColumn(1) 92 | #line 34 "CLexer.l" 93 | #define YY_CLexer_CONSTRUCTOR_CODE {exstr=NULL;}; 94 | #line 36 "CLexer.l" 95 | #define YY_CLexer_TEXT theText 96 | #line 37 "CLexer.l" 97 | #define YY_CLexer_LENG theTextLength 98 | #line 51 "CLexer.l" 99 | #line 52 "C:\\Users\\L.Falcon\\Desktop\\\37777777724\37777777664\37777777664\37777777772\37777777702\37777777753\\obfusc\\flex_bison\\flexskel.h" 100 | 101 | #ifdef YY_USE_CLASS 102 | #ifdef YY_CLexer_IOSTREAM 103 | #include 104 | #define YY_CLexer_IFILE istream 105 | #define YY_CLexer_OFILE ostream 106 | #define YY_CLexer_ERRFILE cerr 107 | 108 | #ifndef YY_CLexer_IFILE_DEFAULT 109 | #define YY_CLexer_IFILE_DEFAULT &cin 110 | #endif 111 | 112 | #ifndef YY_CLexer_OFILE_DEFAULT 113 | #define YY_CLexer_OFILE_DEFAULT &cout 114 | #endif 115 | 116 | #endif 117 | #endif 118 | 119 | #ifndef YY_CLexer_IFILE 120 | #define YY_CLexer_IFILE FILE 121 | #endif 122 | 123 | #ifndef YY_CLexer_OFILE 124 | #define YY_CLexer_OFILE FILE 125 | #endif 126 | 127 | #ifndef YY_CLexer_ERRFILE 128 | #define YY_CLexer_ERRFILE stderr 129 | #endif 130 | 131 | #ifndef YY_CLexer_IFILE_DEFAULT 132 | #define YY_CLexer_IFILE_DEFAULT stdin 133 | #endif 134 | 135 | #ifndef YY_CLexer_OFILE_DEFAULT 136 | #define YY_CLexer_OFILE_DEFAULT stdout 137 | #endif 138 | 139 | 140 | 141 | 142 | #ifndef YY_CLexer_TEXT 143 | #define YY_CLexer_TEXT yytext 144 | #endif 145 | #ifndef YY_CLexer_LENG 146 | #define YY_CLexer_LENG yyleng 147 | #endif 148 | #ifndef YY_CLexer_IN 149 | #define YY_CLexer_IN yyin 150 | #endif 151 | #ifndef YY_CLexer_OUT 152 | #define YY_CLexer_OUT yyout 153 | #endif 154 | 155 | #ifndef YY_CLexer_LEX_RETURN 156 | #define YY_CLexer_LEX_RETURN int 157 | #else 158 | #ifndef YY_CLexer_LEX_DEFINED 159 | #define YY_CLexer_LEX_DEFINED 160 | #endif 161 | #endif 162 | 163 | #ifndef YY_CLexer_LEX 164 | #define YY_CLexer_LEX yylex 165 | #else 166 | #ifndef YY_CLexer_LEX_DEFINED 167 | #define YY_CLexer_LEX_DEFINED 168 | #endif 169 | #endif 170 | 171 | #ifndef YY_CLexer_LEX_PARAM 172 | #ifndef YY_USE_PROTOS 173 | #define YY_CLexer_LEX_PARAM 174 | #else 175 | #define YY_CLexer_LEX_PARAM void 176 | #endif 177 | #else 178 | #ifndef YY_CLexer_LEX_DEFINED 179 | #define YY_CLexer_LEX_DEFINED 180 | #endif 181 | #endif 182 | 183 | #ifndef YY_CLexer_LEX_PARAM_DEF 184 | #define YY_CLexer_LEX_PARAM_DEF 185 | #else 186 | #ifndef YY_CLexer_LEX_DEFINED 187 | #define YY_CLexer_LEX_DEFINED 188 | #endif 189 | #endif 190 | 191 | #ifndef YY_CLexer_RESTART 192 | #define YY_CLexer_RESTART yyrestart 193 | #endif 194 | #ifndef YY_CLexer_SWITCH_TO_BUFFER 195 | #define YY_CLexer_SWITCH_TO_BUFFER yy_switch_to_buffer 196 | #endif 197 | #ifndef YY_CLexer_LOAD_BUFFER_STATE 198 | #define YY_CLexer_LOAD_BUFFER_STATE yy_load_buffer_state 199 | #endif 200 | 201 | #ifndef YY_CLexer_CREATE_BUFFER 202 | #define YY_CLexer_CREATE_BUFFER yy_create_buffer 203 | #ifndef YY_USE_CLASS 204 | #ifndef yy_new_buffer 205 | #define yy_new_buffer yy_create_buffer 206 | #endif 207 | #endif 208 | #endif 209 | #ifndef YY_CLexer_DELETE_BUFFER 210 | #define YY_CLexer_DELETE_BUFFER yy_delete_buffer 211 | #endif 212 | #ifndef YY_CLexer_INIT_BUFFER 213 | #define YY_CLexer_INIT_BUFFER yy_init_buffer 214 | #endif 215 | 216 | 217 | 218 | #ifdef YY_CLexer_FLEX_DEBUG 219 | #ifndef YY_CLexer_DEBUG 220 | #define YY_CLexer_DEBUG 1 221 | #endif 222 | #else 223 | #ifndef YY_CLexer_DEBUG 224 | #define YY_CLexer_DEBUG 0 225 | #endif 226 | #endif 227 | 228 | #if YY_CLexer_DEBUG != 0 229 | #ifndef YY_CLexer_DEBUG_FLAG 230 | #define YY_CLexer_DEBUG_FLAG yy_flex_debug 231 | #endif 232 | #ifndef YY_CLexer_DEBUG_INIT 233 | #define YY_CLexer_DEBUG_INIT 1 234 | #endif 235 | #endif 236 | 237 | 238 | 239 | 240 | #ifndef YY_USE_CLASS 241 | #ifndef YY_CLexer_CURRENT_BUFFER 242 | #define YY_CLexer_CURRENT_BUFFER yy_current_buffer 243 | #endif 244 | typedef struct yy_buffer_state *YY_BUFFER_STATE; 245 | 246 | extern void YY_CLexer_RESTART YY_PROTO(( YY_CLexer_IFILE *input_file )); 247 | extern void YY_CLexer_SWITCH_TO_BUFFER YY_PROTO(( YY_BUFFER_STATE new_buffer )); 248 | extern void YY_CLexer_LOAD_BUFFER_STATE YY_PROTO(( void )); 249 | extern YY_BUFFER_STATE YY_CLexer_CREATE_BUFFER YY_PROTO(( YY_CLexer_IFILE *file, int size )); 250 | extern void YY_CLexer_DELETE_BUFFER YY_PROTO(( YY_BUFFER_STATE b )); 251 | extern void YY_CLexer_INIT_BUFFER YY_PROTO(( YY_BUFFER_STATE b, YY_CLexer_IFILE *file )); 252 | 253 | #if YY_CLexer_DEBUG != 0 254 | extern int YY_CLexer_DEBUG_FLAG ; 255 | #endif 256 | extern YY_CLexer_CHAR *YY_CLexer_TEXT; 257 | extern int YY_CLexer_LENG; 258 | extern YY_CLexer_IFILE *YY_CLexer_IN; 259 | extern YY_CLexer_OFILE *YY_CLexer_OUT; 260 | #ifdef YY_CLexer_LEX_DEFINED 261 | extern YY_CLexer_LEX_RETURN YY_CLexer_LEX ( YY_CLexer_LEX_PARAM ) 262 | YY_CLexer_LEX_PARAM_DEF 263 | #else 264 | #ifndef YY_DECL 265 | extern YY_CLexer_LEX_RETURN YY_CLexer_LEX ( YY_CLexer_LEX_PARAM ) 266 | YY_CLexer_LEX_PARAM_DEF 267 | #else 268 | /* no declaration if oldstyle flex */ 269 | #endif 270 | #endif 271 | #else 272 | 273 | #ifndef YY_CLexer_CURRENT_BUFFER 274 | #define YY_CLexer_CURRENT_BUFFER YY_CURRENT_BUFFER 275 | #endif 276 | #ifndef YY_CLexer_CLASS 277 | #define YY_CLexer_CLASS CLexer 278 | #endif 279 | #ifndef YY_CLexer_ECHO 280 | #define YY_CLexer_ECHO yy_echo 281 | #endif 282 | #ifdef YY_CLexer_ECHO_PURE 283 | #define YY_CLexer_ECHO_NOCODE 284 | #endif 285 | 286 | #ifndef YY_CLexer_ECHO_CODE 287 | #ifndef YY_CLexer_IOSTREAM 288 | #define YY_CLexer_ECHO_CODE fwrite( (char *) YY_CLexer_TEXT, YY_CLexer_LENG, 1, YY_CLexer_OUT ); 289 | #else 290 | #define YY_CLexer_ECHO_CODE (YY_CLexer_OUT->write( (char *) YY_CLexer_TEXT, YY_CLexer_LENG)); 291 | #endif 292 | #endif 293 | 294 | #ifndef YY_CLexer_INPUT 295 | #define YY_CLexer_INPUT yy_input 296 | #endif 297 | #ifdef YY_CLexer_INPUT_PURE 298 | #define YY_CLexer_INPUT_NOCODE 299 | #endif 300 | 301 | #ifndef YY_CLexer_INPUT_CODE 302 | #ifndef YY_CLexer_IOSTREAM 303 | #define YY_CLexer_INPUT_CODE return result= fread( buffer, 1,max_size,YY_CLexer_IN ); 304 | #else 305 | #define YY_CLexer_INPUT_CODE if(YY_CLexer_IN->eof()) result=0;else {YY_CLexer_IN->read(buffer,max_size);result=YY_CLexer_IN->gcount();YY_CLexer_IN->clear(YY_CLexer_IN->rdstate()&(~ios::failbit));if(YY_CLexer_IN->bad()) result= -1;} return result; 306 | #endif 307 | #endif 308 | 309 | #ifdef YY_CLexer_FATAL_ERROR_PURE 310 | #define YY_CLexer_FATAL_ERRO_NOCODE 311 | #endif 312 | #ifndef YY_CLexer_FATAL_ERROR 313 | #define YY_CLexer_FATAL_ERROR yy_fatal_error 314 | #endif 315 | 316 | #ifndef YY_CLexer_FATAL_ERROR_CODE 317 | #ifndef YY_CLexer_IOSTREAM 318 | #define YY_CLexer_FATAL_ERROR_CODE fputs( msg, YY_CLexer_ERRFILE );putc( '\n', YY_CLexer_ERRFILE );exit( 1 ); 319 | #else 320 | #define YY_CLexer_FATAL_ERROR_CODE YY_CLexer_ERRFILE<< msg < 35 | 36 | #elif defined (__MSDOS_AND_ALIKE) 37 | #include 38 | #ifndef __TURBOC__ 39 | /* MS C runtime lib */ 40 | #define alloca _alloca 41 | #endif 42 | 43 | #elif defined(_AIX) 44 | #include 45 | #pragma alloca 46 | 47 | #elif defined(__hpux) 48 | #ifdef __cplusplus 49 | extern "C" { 50 | void *alloca (unsigned int); 51 | }; 52 | #else /* not __cplusplus */ 53 | void *alloca (); 54 | #endif /* not __cplusplus */ 55 | 56 | #endif /* not _AIX not MSDOS, or __TURBOC__ or _AIX, not sparc. */ 57 | #endif /* alloca not defined. */ 58 | #ifdef c_plusplus 59 | #ifndef __cplusplus 60 | #define __cplusplus 61 | #endif 62 | #endif 63 | #ifdef __cplusplus 64 | #ifndef YY_USE_CLASS 65 | #define YY_USE_CLASS 66 | #endif 67 | #else 68 | #ifndef __STDC__ 69 | #define const 70 | #endif 71 | #endif 72 | #include 73 | #define YYBISON 1 74 | $/* %{ and %header{ and %union, during decl */ 75 | #define YY_@_BISON 1 76 | #ifndef YY_@_COMPATIBILITY 77 | #ifndef YY_USE_CLASS 78 | #define YY_@_COMPATIBILITY 1 79 | #else 80 | #define YY_@_COMPATIBILITY 0 81 | #endif 82 | #endif 83 | 84 | #if YY_@_COMPATIBILITY != 0 85 | /* backward compatibility */ 86 | #ifdef YYLTYPE 87 | #ifndef YY_@_LTYPE 88 | #define YY_@_LTYPE YYLTYPE 89 | #endif 90 | #endif 91 | #ifdef YYSTYPE 92 | #ifndef YY_@_STYPE 93 | #define YY_@_STYPE YYSTYPE 94 | #endif 95 | #endif 96 | #ifdef YYDEBUG 97 | #ifndef YY_@_DEBUG 98 | #define YY_@_DEBUG YYDEBUG 99 | #endif 100 | #endif 101 | #ifdef YY_@_STYPE 102 | #ifndef yystype 103 | #define yystype YY_@_STYPE 104 | #endif 105 | #endif 106 | /* use goto to be compatible */ 107 | #ifndef YY_@_USE_GOTO 108 | #define YY_@_USE_GOTO 1 109 | #endif 110 | #endif 111 | 112 | /* use no goto to be clean in C++ */ 113 | #ifndef YY_@_USE_GOTO 114 | #define YY_@_USE_GOTO 0 115 | #endif 116 | 117 | #ifndef YY_@_PURE 118 | $/* YY_@_PURE */ 119 | #endif 120 | 121 | /* section apres lecture def, avant lecture grammaire S2 */ 122 | $/* prefix */ 123 | #ifndef YY_@_DEBUG 124 | $/* YY_@_DEBUG */ 125 | #endif 126 | 127 | 128 | #ifndef YY_@_LSP_NEEDED 129 | $ /* YY_@_LSP_NEEDED*/ 130 | #endif 131 | 132 | 133 | 134 | /* DEFAULT LTYPE*/ 135 | #ifdef YY_@_LSP_NEEDED 136 | #ifndef YY_@_LTYPE 137 | typedef 138 | struct yyltype 139 | { 140 | int timestamp; 141 | int first_line; 142 | int first_column; 143 | int last_line; 144 | int last_column; 145 | char *text; 146 | } 147 | yyltype; 148 | 149 | #define YY_@_LTYPE yyltype 150 | #endif 151 | #endif 152 | /* DEFAULT STYPE*/ 153 | /* We used to use `unsigned long' as YY_@_STYPE on MSDOS, 154 | but it seems better to be consistent. 155 | Most programs should declare their own type anyway. */ 156 | 157 | #ifndef YY_@_STYPE 158 | #define YY_@_STYPE int 159 | #endif 160 | /* DEFAULT MISCELANEOUS */ 161 | #ifndef YY_@_PARSE 162 | #define YY_@_PARSE yyparse 163 | #endif 164 | #ifndef YY_@_LEX 165 | #define YY_@_LEX yylex 166 | #endif 167 | #ifndef YY_@_LVAL 168 | #define YY_@_LVAL yylval 169 | #endif 170 | #ifndef YY_@_LLOC 171 | #define YY_@_LLOC yylloc 172 | #endif 173 | #ifndef YY_@_CHAR 174 | #define YY_@_CHAR yychar 175 | #endif 176 | #ifndef YY_@_NERRS 177 | #define YY_@_NERRS yynerrs 178 | #endif 179 | #ifndef YY_@_DEBUG_FLAG 180 | #define YY_@_DEBUG_FLAG yydebug 181 | #endif 182 | #ifndef YY_@_ERROR 183 | #define YY_@_ERROR yyerror 184 | #endif 185 | #ifndef YY_@_PARSE_PARAM 186 | #ifndef __STDC__ 187 | #ifndef __cplusplus 188 | #ifndef YY_USE_CLASS 189 | #define YY_@_PARSE_PARAM 190 | #ifndef YY_@_PARSE_PARAM_DEF 191 | #define YY_@_PARSE_PARAM_DEF 192 | #endif 193 | #endif 194 | #endif 195 | #endif 196 | #ifndef YY_@_PARSE_PARAM 197 | #define YY_@_PARSE_PARAM void 198 | #endif 199 | #endif 200 | #if YY_@_COMPATIBILITY != 0 201 | /* backward compatibility */ 202 | #ifdef YY_@_LTYPE 203 | #ifndef YYLTYPE 204 | #define YYLTYPE YY_@_LTYPE 205 | #else 206 | /* WARNING obsolete !!! user defined YYLTYPE not reported into generated header */ 207 | #endif 208 | #endif 209 | #ifndef YYSTYPE 210 | #define YYSTYPE YY_@_STYPE 211 | #else 212 | /* WARNING obsolete !!! user defined YYSTYPE not reported into generated header */ 213 | #endif 214 | #ifdef YY_@_PURE 215 | #ifndef YYPURE 216 | #define YYPURE YY_@_PURE 217 | #endif 218 | #endif 219 | #ifdef YY_@_DEBUG 220 | #ifndef YYDEBUG 221 | #define YYDEBUG YY_@_DEBUG 222 | #endif 223 | #endif 224 | #ifndef YY_@_ERROR_VERBOSE 225 | #ifdef YYERROR_VERBOSE 226 | #define YY_@_ERROR_VERBOSE YYERROR_VERBOSE 227 | #endif 228 | #endif 229 | #ifndef YY_@_LSP_NEEDED 230 | #ifdef YYLSP_NEEDED 231 | #define YY_@_LSP_NEEDED YYLSP_NEEDED 232 | #endif 233 | #endif 234 | #endif 235 | #ifndef YY_USE_CLASS 236 | /* TOKEN C */ 237 | $ /* #defines tokens */ 238 | #else 239 | /* CLASS */ 240 | #ifndef YY_@_CLASS 241 | #define YY_@_CLASS @ 242 | #endif 243 | #ifndef YY_@_INHERIT 244 | #define YY_@_INHERIT 245 | #endif 246 | #ifndef YY_@_MEMBERS 247 | #define YY_@_MEMBERS 248 | #endif 249 | #ifndef YY_@_LEX_BODY 250 | #define YY_@_LEX_BODY 251 | #endif 252 | #ifndef YY_@_ERROR_BODY 253 | #define YY_@_ERROR_BODY 254 | #endif 255 | #ifndef YY_@_CONSTRUCTOR_PARAM 256 | #define YY_@_CONSTRUCTOR_PARAM 257 | #endif 258 | #ifndef YY_@_CONSTRUCTOR_CODE 259 | #define YY_@_CONSTRUCTOR_CODE 260 | #endif 261 | #ifndef YY_@_CONSTRUCTOR_INIT 262 | #define YY_@_CONSTRUCTOR_INIT 263 | #endif 264 | /* choose between enum and const */ 265 | #ifndef YY_@_USE_CONST_TOKEN 266 | #define YY_@_USE_CONST_TOKEN 0 267 | /* yes enum is more compatible with flex, */ 268 | /* so by default we use it */ 269 | #endif 270 | #if YY_@_USE_CONST_TOKEN != 0 271 | #ifndef YY_@_ENUM_TOKEN 272 | #define YY_@_ENUM_TOKEN yy_@_enum_token 273 | #endif 274 | #endif 275 | 276 | class YY_@_CLASS YY_@_INHERIT 277 | { 278 | public: 279 | #if YY_@_USE_CONST_TOKEN != 0 280 | /* static const int token ... */ 281 | $ /* decl const */ 282 | #else 283 | enum YY_@_ENUM_TOKEN { YY_@_NULL_TOKEN=0 284 | $ /* enum token */ 285 | }; /* end of enum declaration */ 286 | #endif 287 | public: 288 | int YY_@_PARSE (YY_@_PARSE_PARAM); 289 | virtual void YY_@_ERROR(char *msg) YY_@_ERROR_BODY; 290 | #ifdef YY_@_PURE 291 | #ifdef YY_@_LSP_NEEDED 292 | virtual int YY_@_LEX (YY_@_STYPE *YY_@_LVAL,YY_@_LTYPE *YY_@_LLOC) YY_@_LEX_BODY; 293 | #else 294 | virtual int YY_@_LEX (YY_@_STYPE *YY_@_LVAL) YY_@_LEX_BODY; 295 | #endif 296 | #else 297 | virtual int YY_@_LEX() YY_@_LEX_BODY; 298 | YY_@_STYPE YY_@_LVAL; 299 | #ifdef YY_@_LSP_NEEDED 300 | YY_@_LTYPE YY_@_LLOC; 301 | #endif 302 | int YY_@_NERRS; 303 | int YY_@_CHAR; 304 | #endif 305 | #if YY_@_DEBUG != 0 306 | int YY_@_DEBUG_FLAG; /* nonzero means print parse trace */ 307 | #endif 308 | public: 309 | YY_@_CLASS(YY_@_CONSTRUCTOR_PARAM); 310 | public: 311 | YY_@_MEMBERS 312 | }; 313 | /* other declare folow */ 314 | #if YY_@_USE_CONST_TOKEN != 0 315 | $ /* const YY_@_CLASS::token */ 316 | #endif 317 | /*apres const */ 318 | YY_@_CLASS::YY_@_CLASS(YY_@_CONSTRUCTOR_PARAM) YY_@_CONSTRUCTOR_INIT 319 | { 320 | #if YY_@_DEBUG != 0 321 | YY_@_DEBUG_FLAG=0; 322 | #endif 323 | YY_@_CONSTRUCTOR_CODE; 324 | }; 325 | #endif 326 | $ /* fattrs + tables */ 327 | 328 | /* parser code folow */ 329 | 330 | 331 | /* This is the parser code that is written into each bison parser 332 | when the %semantic_parser declaration is not specified in the grammar. 333 | It was written by Richard Stallman by simplifying the hairy parser 334 | used when %semantic_parser is specified. */ 335 | 336 | /* Note: dollar marks section change 337 | the next is replaced by the list of actions, each action 338 | as one case of the switch. */ 339 | 340 | #if YY_@_USE_GOTO != 0 341 | /* 342 | SUPRESSION OF GOTO : on some C++ compiler (sun c++) 343 | the goto is strictly forbidden if any constructor/destructor 344 | is used in the whole function (very stupid isn't it ?) 345 | so goto are to be replaced with a 'while/switch/case construct' 346 | here are the macro to keep some apparent compatibility 347 | */ 348 | #define YYGOTO(lb) {yy_gotostate=lb;continue;} 349 | #define YYBEGINGOTO enum yy_labels yy_gotostate=yygotostart; \ 350 | for(;;) switch(yy_gotostate) { case yygotostart: { 351 | #define YYLABEL(lb) } case lb: { 352 | #define YYENDGOTO } } 353 | #define YYBEGINDECLARELABEL enum yy_labels {yygotostart 354 | #define YYDECLARELABEL(lb) ,lb 355 | #define YYENDDECLARELABEL }; 356 | #else 357 | /* macro to keep goto */ 358 | #define YYGOTO(lb) goto lb 359 | #define YYBEGINGOTO 360 | #define YYLABEL(lb) lb: 361 | #define YYENDGOTO 362 | #define YYBEGINDECLARELABEL 363 | #define YYDECLARELABEL(lb) 364 | #define YYENDDECLARELABEL 365 | #endif 366 | /* LABEL DECLARATION */ 367 | YYBEGINDECLARELABEL 368 | YYDECLARELABEL(yynewstate) 369 | YYDECLARELABEL(yybackup) 370 | /* YYDECLARELABEL(yyresume) */ 371 | YYDECLARELABEL(yydefault) 372 | YYDECLARELABEL(yyreduce) 373 | YYDECLARELABEL(yyerrlab) /* here on detecting error */ 374 | YYDECLARELABEL(yyerrlab1) /* here on error raised explicitly by an action */ 375 | YYDECLARELABEL(yyerrdefault) /* current state does not do anything special for the error token. */ 376 | YYDECLARELABEL(yyerrpop) /* pop the current state because it cannot handle the error token */ 377 | YYDECLARELABEL(yyerrhandle) 378 | YYENDDECLARELABEL 379 | /* ALLOCA SIMULATION */ 380 | /* __HAVE_NO_ALLOCA */ 381 | #ifdef __HAVE_NO_ALLOCA 382 | int __alloca_free_ptr(char *ptr,char *ref) 383 | {if(ptr!=ref) free(ptr); 384 | return 0;} 385 | 386 | #define __ALLOCA_alloca(size) malloc(size) 387 | #define __ALLOCA_free(ptr,ref) __alloca_free_ptr((char *)ptr,(char *)ref) 388 | 389 | #ifdef YY_@_LSP_NEEDED 390 | #define __ALLOCA_return(num) \ 391 | return( __ALLOCA_free(yyss,yyssa)+\ 392 | __ALLOCA_free(yyvs,yyvsa)+\ 393 | __ALLOCA_free(yyls,yylsa)+\ 394 | (num)) 395 | #else 396 | #define __ALLOCA_return(num) \ 397 | return( __ALLOCA_free(yyss,yyssa)+\ 398 | __ALLOCA_free(yyvs,yyvsa)+\ 399 | (num)) 400 | #endif 401 | #else 402 | #define __ALLOCA_return(num) return(num) 403 | #define __ALLOCA_alloca(size) alloca(size) 404 | #define __ALLOCA_free(ptr,ref) 405 | #endif 406 | 407 | /* ENDALLOCA SIMULATION */ 408 | 409 | #define yyerrok (yyerrstatus = 0) 410 | #define yyclearin (YY_@_CHAR = YYEMPTY) 411 | #define YYEMPTY -2 412 | #define YYEOF 0 413 | #define YYACCEPT __ALLOCA_return(0) 414 | #define YYABORT __ALLOCA_return(1) 415 | #define YYERROR YYGOTO(yyerrlab1) 416 | /* Like YYERROR except do call yyerror. 417 | This remains here temporarily to ease the 418 | transition to the new meaning of YYERROR, for GCC. 419 | Once GCC version 2 has supplanted version 1, this can go. */ 420 | #define YYFAIL YYGOTO(yyerrlab) 421 | #define YYRECOVERING() (!!yyerrstatus) 422 | #define YYBACKUP(token, value) \ 423 | do \ 424 | if (YY_@_CHAR == YYEMPTY && yylen == 1) \ 425 | { YY_@_CHAR = (token), YY_@_LVAL = (value); \ 426 | yychar1 = YYTRANSLATE (YY_@_CHAR); \ 427 | YYPOPSTACK; \ 428 | YYGOTO(yybackup); \ 429 | } \ 430 | else \ 431 | { YY_@_ERROR ("syntax error: cannot back up"); YYERROR; } \ 432 | while (0) 433 | 434 | #define YYTERROR 1 435 | #define YYERRCODE 256 436 | 437 | #ifndef YY_@_PURE 438 | /* UNPURE */ 439 | #define YYLEX YY_@_LEX() 440 | #ifndef YY_USE_CLASS 441 | /* If nonreentrant, and not class , generate the variables here */ 442 | int YY_@_CHAR; /* the lookahead symbol */ 443 | YY_@_STYPE YY_@_LVAL; /* the semantic value of the */ 444 | /* lookahead symbol */ 445 | int YY_@_NERRS; /* number of parse errors so far */ 446 | #ifdef YY_@_LSP_NEEDED 447 | YY_@_LTYPE YY_@_LLOC; /* location data for the lookahead */ 448 | /* symbol */ 449 | #endif 450 | #endif 451 | 452 | 453 | #else 454 | /* PURE */ 455 | #ifdef YY_@_LSP_NEEDED 456 | #define YYLEX YY_@_LEX(&YY_@_LVAL, &YY_@_LLOC) 457 | #else 458 | #define YYLEX YY_@_LEX(&YY_@_LVAL) 459 | #endif 460 | #endif 461 | #ifndef YY_USE_CLASS 462 | #if YY_@_DEBUG != 0 463 | int YY_@_DEBUG_FLAG; /* nonzero means print parse trace */ 464 | /* Since this is uninitialized, it does not stop multiple parsers 465 | from coexisting. */ 466 | #endif 467 | #endif 468 | 469 | 470 | 471 | /* YYINITDEPTH indicates the initial size of the parser's stacks */ 472 | 473 | #ifndef YYINITDEPTH 474 | #define YYINITDEPTH 200 475 | #endif 476 | 477 | /* YYMAXDEPTH is the maximum size the stacks can grow to 478 | (effective only if the built-in stack extension method is used). */ 479 | 480 | #if YYMAXDEPTH == 0 481 | #undef YYMAXDEPTH 482 | #endif 483 | 484 | #ifndef YYMAXDEPTH 485 | #define YYMAXDEPTH 10000 486 | #endif 487 | 488 | 489 | #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ 490 | #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) 491 | #else /* not GNU C or C++ */ 492 | 493 | /* This is the most reliable way to avoid incompatibilities 494 | in available built-in functions on various systems. */ 495 | 496 | #ifdef __cplusplus 497 | static void __yy_bcopy (char *from, char *to, int count) 498 | #else 499 | #ifdef __STDC__ 500 | static void __yy_bcopy (char *from, char *to, int count) 501 | #else 502 | static void __yy_bcopy (from, to, count) 503 | char *from; 504 | char *to; 505 | int count; 506 | #endif 507 | #endif 508 | { 509 | register char *f = from; 510 | register char *t = to; 511 | register int i = count; 512 | 513 | while (i-- > 0) 514 | *t++ = *f++; 515 | } 516 | #endif 517 | 518 | int 519 | #ifdef YY_USE_CLASS 520 | YY_@_CLASS:: 521 | #endif 522 | YY_@_PARSE(YY_@_PARSE_PARAM) 523 | #ifndef __STDC__ 524 | #ifndef __cplusplus 525 | #ifndef YY_USE_CLASS 526 | /* parameter definition without protypes */ 527 | YY_@_PARSE_PARAM_DEF 528 | #endif 529 | #endif 530 | #endif 531 | { 532 | register int yystate; 533 | register int yyn; 534 | register short *yyssp; 535 | register YY_@_STYPE *yyvsp; 536 | int yyerrstatus; /* number of tokens to shift before error messages enabled */ 537 | int yychar1=0; /* lookahead token as an internal (translated) token number */ 538 | 539 | short yyssa[YYINITDEPTH]; /* the state stack */ 540 | YY_@_STYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ 541 | 542 | short *yyss = yyssa; /* refer to the stacks thru separate pointers */ 543 | YY_@_STYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ 544 | 545 | #ifdef YY_@_LSP_NEEDED 546 | YY_@_LTYPE yylsa[YYINITDEPTH]; /* the location stack */ 547 | YY_@_LTYPE *yyls = yylsa; 548 | YY_@_LTYPE *yylsp; 549 | 550 | #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) 551 | #else 552 | #define YYPOPSTACK (yyvsp--, yyssp--) 553 | #endif 554 | 555 | int yystacksize = YYINITDEPTH; 556 | 557 | #ifdef YY_@_PURE 558 | int YY_@_CHAR; 559 | YY_@_STYPE YY_@_LVAL; 560 | int YY_@_NERRS; 561 | #ifdef YY_@_LSP_NEEDED 562 | YY_@_LTYPE YY_@_LLOC; 563 | #endif 564 | #endif 565 | 566 | YY_@_STYPE yyval; /* the variable used to return */ 567 | /* semantic values from the action */ 568 | /* routines */ 569 | 570 | int yylen; 571 | /* start loop, in which YYGOTO may be used. */ 572 | YYBEGINGOTO 573 | 574 | #if YY_@_DEBUG != 0 575 | if (YY_@_DEBUG_FLAG) 576 | fprintf(stderr, "Starting parse\n"); 577 | #endif 578 | yystate = 0; 579 | yyerrstatus = 0; 580 | YY_@_NERRS = 0; 581 | YY_@_CHAR = YYEMPTY; /* Cause a token to be read. */ 582 | 583 | /* Initialize stack pointers. 584 | Waste one element of value and location stack 585 | so that they stay on the same level as the state stack. 586 | The wasted elements are never initialized. */ 587 | 588 | yyssp = yyss - 1; 589 | yyvsp = yyvs; 590 | #ifdef YY_@_LSP_NEEDED 591 | yylsp = yyls; 592 | #endif 593 | 594 | /* Push a new state, which is found in yystate . */ 595 | /* In all cases, when you get here, the value and location stacks 596 | have just been pushed. so pushing a state here evens the stacks. */ 597 | YYLABEL(yynewstate) 598 | 599 | *++yyssp = yystate; 600 | 601 | if (yyssp >= yyss + yystacksize - 1) 602 | { 603 | /* Give user a chance to reallocate the stack */ 604 | /* Use copies of these so that the &'s don't force the real ones into memory. */ 605 | YY_@_STYPE *yyvs1 = yyvs; 606 | short *yyss1 = yyss; 607 | #ifdef YY_@_LSP_NEEDED 608 | YY_@_LTYPE *yyls1 = yyls; 609 | #endif 610 | 611 | /* Get the current used size of the three stacks, in elements. */ 612 | int size = yyssp - yyss + 1; 613 | 614 | #ifdef yyoverflow 615 | /* Each stack pointer address is followed by the size of 616 | the data in use in that stack, in bytes. */ 617 | #ifdef YY_@_LSP_NEEDED 618 | /* This used to be a conditional around just the two extra args, 619 | but that might be undefined if yyoverflow is a macro. */ 620 | yyoverflow("parser stack overflow", 621 | &yyss1, size * sizeof (*yyssp), 622 | &yyvs1, size * sizeof (*yyvsp), 623 | &yyls1, size * sizeof (*yylsp), 624 | &yystacksize); 625 | #else 626 | yyoverflow("parser stack overflow", 627 | &yyss1, size * sizeof (*yyssp), 628 | &yyvs1, size * sizeof (*yyvsp), 629 | &yystacksize); 630 | #endif 631 | 632 | yyss = yyss1; yyvs = yyvs1; 633 | #ifdef YY_@_LSP_NEEDED 634 | yyls = yyls1; 635 | #endif 636 | #else /* no yyoverflow */ 637 | /* Extend the stack our own way. */ 638 | if (yystacksize >= YYMAXDEPTH) 639 | { 640 | YY_@_ERROR("parser stack overflow"); 641 | __ALLOCA_return(2); 642 | } 643 | yystacksize *= 2; 644 | if (yystacksize > YYMAXDEPTH) 645 | yystacksize = YYMAXDEPTH; 646 | yyss = (short *) __ALLOCA_alloca (yystacksize * sizeof (*yyssp)); 647 | __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); 648 | __ALLOCA_free(yyss1,yyssa); 649 | yyvs = (YY_@_STYPE *) __ALLOCA_alloca (yystacksize * sizeof (*yyvsp)); 650 | __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); 651 | __ALLOCA_free(yyvs1,yyvsa); 652 | #ifdef YY_@_LSP_NEEDED 653 | yyls = (YY_@_LTYPE *) __ALLOCA_alloca (yystacksize * sizeof (*yylsp)); 654 | __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); 655 | __ALLOCA_free(yyls1,yylsa); 656 | #endif 657 | #endif /* no yyoverflow */ 658 | 659 | yyssp = yyss + size - 1; 660 | yyvsp = yyvs + size - 1; 661 | #ifdef YY_@_LSP_NEEDED 662 | yylsp = yyls + size - 1; 663 | #endif 664 | 665 | #if YY_@_DEBUG != 0 666 | if (YY_@_DEBUG_FLAG) 667 | fprintf(stderr, "Stack size increased to %d\n", yystacksize); 668 | #endif 669 | 670 | if (yyssp >= yyss + yystacksize - 1) 671 | YYABORT; 672 | } 673 | 674 | #if YY_@_DEBUG != 0 675 | if (YY_@_DEBUG_FLAG) 676 | fprintf(stderr, "Entering state %d\n", yystate); 677 | #endif 678 | 679 | YYGOTO(yybackup); 680 | YYLABEL(yybackup) 681 | 682 | /* Do appropriate processing given the current state. */ 683 | /* Read a lookahead token if we need one and don't already have one. */ 684 | /* YYLABEL(yyresume) */ 685 | 686 | /* First try to decide what to do without reference to lookahead token. */ 687 | 688 | yyn = yypact[yystate]; 689 | if (yyn == YYFLAG) 690 | YYGOTO(yydefault); 691 | 692 | /* Not known => get a lookahead token if don't already have one. */ 693 | 694 | /* yychar is either YYEMPTY or YYEOF 695 | or a valid token in external form. */ 696 | 697 | if (YY_@_CHAR == YYEMPTY) 698 | { 699 | #if YY_@_DEBUG != 0 700 | if (YY_@_DEBUG_FLAG) 701 | fprintf(stderr, "Reading a token: "); 702 | #endif 703 | YY_@_CHAR = YYLEX; 704 | } 705 | 706 | /* Convert token to internal form (in yychar1) for indexing tables with */ 707 | 708 | if (YY_@_CHAR <= 0) /* This means end of input. */ 709 | { 710 | yychar1 = 0; 711 | YY_@_CHAR = YYEOF; /* Don't call YYLEX any more */ 712 | 713 | #if YY_@_DEBUG != 0 714 | if (YY_@_DEBUG_FLAG) 715 | fprintf(stderr, "Now at end of input.\n"); 716 | #endif 717 | } 718 | else 719 | { 720 | yychar1 = YYTRANSLATE(YY_@_CHAR); 721 | 722 | #if YY_@_DEBUG != 0 723 | if (YY_@_DEBUG_FLAG) 724 | { 725 | fprintf (stderr, "Next token is %d (%s", YY_@_CHAR, yytname[yychar1]); 726 | /* Give the individual parser a way to print the precise meaning 727 | of a token, for further debugging info. */ 728 | #ifdef YYPRINT 729 | YYPRINT (stderr, YY_@_CHAR, YY_@_LVAL); 730 | #endif 731 | fprintf (stderr, ")\n"); 732 | } 733 | #endif 734 | } 735 | 736 | yyn += yychar1; 737 | if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) 738 | YYGOTO(yydefault); 739 | 740 | yyn = yytable[yyn]; 741 | 742 | /* yyn is what to do for this token type in this state. 743 | Negative => reduce, -yyn is rule number. 744 | Positive => shift, yyn is new state. 745 | New state is final state => don't bother to shift, 746 | just return success. 747 | 0, or most negative number => error. */ 748 | 749 | if (yyn < 0) 750 | { 751 | if (yyn == YYFLAG) 752 | YYGOTO(yyerrlab); 753 | yyn = -yyn; 754 | YYGOTO(yyreduce); 755 | } 756 | else if (yyn == 0) 757 | YYGOTO(yyerrlab); 758 | 759 | if (yyn == YYFINAL) 760 | YYACCEPT; 761 | 762 | /* Shift the lookahead token. */ 763 | 764 | #if YY_@_DEBUG != 0 765 | if (YY_@_DEBUG_FLAG) 766 | fprintf(stderr, "Shifting token %d (%s), ", YY_@_CHAR, yytname[yychar1]); 767 | #endif 768 | 769 | /* Discard the token being shifted unless it is eof. */ 770 | if (YY_@_CHAR != YYEOF) 771 | YY_@_CHAR = YYEMPTY; 772 | 773 | *++yyvsp = YY_@_LVAL; 774 | #ifdef YY_@_LSP_NEEDED 775 | *++yylsp = YY_@_LLOC; 776 | #endif 777 | 778 | /* count tokens shifted since error; after three, turn off error status. */ 779 | if (yyerrstatus) yyerrstatus--; 780 | 781 | yystate = yyn; 782 | YYGOTO(yynewstate); 783 | 784 | /* Do the default action for the current state. */ 785 | YYLABEL(yydefault) 786 | 787 | yyn = yydefact[yystate]; 788 | if (yyn == 0) 789 | YYGOTO(yyerrlab); 790 | 791 | /* Do a reduction. yyn is the number of a rule to reduce with. */ 792 | YYLABEL(yyreduce) 793 | yylen = yyr2[yyn]; 794 | if (yylen > 0) 795 | yyval = yyvsp[1-yylen]; /* implement default value of the action */ 796 | 797 | #if YY_@_DEBUG != 0 798 | if (YY_@_DEBUG_FLAG) 799 | { 800 | int i; 801 | 802 | fprintf (stderr, "Reducing via rule %d (line %d), ", 803 | yyn, yyrline[yyn]); 804 | 805 | /* Print the symbols being reduced, and their result. */ 806 | for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) 807 | fprintf (stderr, "%s ", yytname[yyrhs[i]]); 808 | fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); 809 | } 810 | #endif 811 | 812 | $ /* the action file gets copied in in place of this dollarsign */ 813 | yyvsp -= yylen; 814 | yyssp -= yylen; 815 | #ifdef YY_@_LSP_NEEDED 816 | yylsp -= yylen; 817 | #endif 818 | 819 | #if YY_@_DEBUG != 0 820 | if (YY_@_DEBUG_FLAG) 821 | { 822 | short *ssp1 = yyss - 1; 823 | fprintf (stderr, "state stack now"); 824 | while (ssp1 != yyssp) 825 | fprintf (stderr, " %d", *++ssp1); 826 | fprintf (stderr, "\n"); 827 | } 828 | #endif 829 | 830 | *++yyvsp = yyval; 831 | 832 | #ifdef YY_@_LSP_NEEDED 833 | yylsp++; 834 | if (yylen == 0) 835 | { 836 | yylsp->first_line = YY_@_LLOC.first_line; 837 | yylsp->first_column = YY_@_LLOC.first_column; 838 | yylsp->last_line = (yylsp-1)->last_line; 839 | yylsp->last_column = (yylsp-1)->last_column; 840 | yylsp->text = 0; 841 | } 842 | else 843 | { 844 | yylsp->last_line = (yylsp+yylen-1)->last_line; 845 | yylsp->last_column = (yylsp+yylen-1)->last_column; 846 | } 847 | #endif 848 | 849 | /* Now "shift" the result of the reduction. 850 | Determine what state that goes to, 851 | based on the state we popped back to 852 | and the rule number reduced by. */ 853 | 854 | yyn = yyr1[yyn]; 855 | 856 | yystate = yypgoto[yyn - YYNTBASE] + *yyssp; 857 | if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) 858 | yystate = yytable[yystate]; 859 | else 860 | yystate = yydefgoto[yyn - YYNTBASE]; 861 | 862 | YYGOTO(yynewstate); 863 | 864 | YYLABEL(yyerrlab) /* here on detecting error */ 865 | 866 | if (! yyerrstatus) 867 | /* If not already recovering from an error, report this error. */ 868 | { 869 | ++YY_@_NERRS; 870 | 871 | #ifdef YY_@_ERROR_VERBOSE 872 | yyn = yypact[yystate]; 873 | 874 | if (yyn > YYFLAG && yyn < YYLAST) 875 | { 876 | int size = 0; 877 | char *msg; 878 | int x, count; 879 | 880 | count = 0; 881 | /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ 882 | for (x = (yyn < 0 ? -yyn : 0); 883 | x < (sizeof(yytname) / sizeof(char *)); x++) 884 | if (yycheck[x + yyn] == x) 885 | size += strlen(yytname[x]) + 15, count++; 886 | msg = (char *) malloc(size + 15); 887 | if (msg != 0) 888 | { 889 | strcpy(msg, "parse error"); 890 | 891 | if (count < 5) 892 | { 893 | count = 0; 894 | for (x = (yyn < 0 ? -yyn : 0); 895 | x < (sizeof(yytname) / sizeof(char *)); x++) 896 | if (yycheck[x + yyn] == x) 897 | { 898 | strcat(msg, count == 0 ? ", expecting `" : " or `"); 899 | strcat(msg, yytname[x]); 900 | strcat(msg, "'"); 901 | count++; 902 | } 903 | } 904 | YY_@_ERROR(msg); 905 | free(msg); 906 | } 907 | else 908 | YY_@_ERROR ("parse error; also virtual memory exceeded"); 909 | } 910 | else 911 | #endif /* YY_@_ERROR_VERBOSE */ 912 | YY_@_ERROR("parse error"); 913 | } 914 | 915 | YYGOTO(yyerrlab1); 916 | YYLABEL(yyerrlab1) /* here on error raised explicitly by an action */ 917 | 918 | if (yyerrstatus == 3) 919 | { 920 | /* if just tried and failed to reuse lookahead token after an error, discard it. */ 921 | 922 | /* return failure if at end of input */ 923 | if (YY_@_CHAR == YYEOF) 924 | YYABORT; 925 | 926 | #if YY_@_DEBUG != 0 927 | if (YY_@_DEBUG_FLAG) 928 | fprintf(stderr, "Discarding token %d (%s).\n", YY_@_CHAR, yytname[yychar1]); 929 | #endif 930 | 931 | YY_@_CHAR = YYEMPTY; 932 | } 933 | 934 | /* Else will try to reuse lookahead token 935 | after shifting the error token. */ 936 | 937 | yyerrstatus = 3; /* Each real token shifted decrements this */ 938 | 939 | YYGOTO(yyerrhandle); 940 | 941 | YYLABEL(yyerrdefault) /* current state does not do anything special for the error token. */ 942 | 943 | #if 0 944 | /* This is wrong; only states that explicitly want error tokens 945 | should shift them. */ 946 | yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ 947 | if (yyn) YYGOTO(yydefault); 948 | #endif 949 | 950 | YYLABEL(yyerrpop) /* pop the current state because it cannot handle the error token */ 951 | 952 | if (yyssp == yyss) YYABORT; 953 | yyvsp--; 954 | yystate = *--yyssp; 955 | #ifdef YY_@_LSP_NEEDED 956 | yylsp--; 957 | #endif 958 | 959 | #if YY_@_DEBUG != 0 960 | if (YY_@_DEBUG_FLAG) 961 | { 962 | short *ssp1 = yyss - 1; 963 | fprintf (stderr, "Error: state stack now"); 964 | while (ssp1 != yyssp) 965 | fprintf (stderr, " %d", *++ssp1); 966 | fprintf (stderr, "\n"); 967 | } 968 | #endif 969 | 970 | YYLABEL(yyerrhandle) 971 | 972 | yyn = yypact[yystate]; 973 | if (yyn == YYFLAG) 974 | YYGOTO(yyerrdefault); 975 | 976 | yyn += YYTERROR; 977 | if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) 978 | YYGOTO(yyerrdefault); 979 | 980 | yyn = yytable[yyn]; 981 | if (yyn < 0) 982 | { 983 | if (yyn == YYFLAG) 984 | YYGOTO(yyerrpop); 985 | yyn = -yyn; 986 | YYGOTO(yyreduce); 987 | } 988 | else if (yyn == 0) 989 | YYGOTO(yyerrpop); 990 | 991 | if (yyn == YYFINAL) 992 | YYACCEPT; 993 | 994 | #if YY_@_DEBUG != 0 995 | if (YY_@_DEBUG_FLAG) 996 | fprintf(stderr, "Shifting error token, "); 997 | #endif 998 | 999 | *++yyvsp = YY_@_LVAL; 1000 | #ifdef YY_@_LSP_NEEDED 1001 | *++yylsp = YY_@_LLOC; 1002 | #endif 1003 | 1004 | yystate = yyn; 1005 | YYGOTO(yynewstate); 1006 | /* end loop, in which YYGOTO may be used. */ 1007 | YYENDGOTO 1008 | } 1009 | 1010 | /* END */ 1011 | $ /* section 3 */ 1012 | 1013 | /* AFTER END , NEVER READ !!! */ 1014 | -------------------------------------------------------------------------------- /obfusc/CParser.y: -------------------------------------------------------------------------------- 1 | %name CParser 2 | 3 | 4 | %header{ 5 | #include "pre.h" 6 | 7 | #include "Node.h" 8 | #include "FunctionNode.h" 9 | #include "Tree.h" 10 | #include "SymbolTable.h" 11 | #include "Symbol.h" 12 | 13 | class Node; 14 | class SymbolTable; 15 | class Symbol; 16 | class Tree; 17 | 18 | using namespace std; 19 | %} 20 | 21 | %union { 22 | Node * node; 23 | } 24 | 25 | %header{ 26 | typedef YY_CParser_STYPE TokenValue; 27 | #include "TokenTypes.h" 28 | // 4quick 29 | 30 | #define CN new Node 31 | 32 | %} 33 | 34 | %define LSP_NEEDED 35 | %define LTYPE TokenLocation 36 | %define LLOC theTokenLocation 37 | %define LVAL theTokenValue 38 | 39 | %define DEBUG 1 40 | %define LEX_BODY =0 41 | %define ERROR_BODY =0 42 | %define ERROR PrintError 43 | %define DEBUG_FLAG debugFlag 44 | 45 | %define LEX Scan 46 | %define PARSE Parse 47 | %define PARSE_PARAM 48 | 49 | %define MEMBERS \ 50 | public: \ 51 | virtual Tree * getCurrentTree(void) {return NULL;}; \ 52 | virtual void setCurrentTree(Tree *value){}; \ 53 | virtual SymbolTable * getCurrentSymbolTable(void){return NULL;}; \ 54 | virtual void ParsedDeclaration(Node *){}; \ 55 | virtual void FindTPYEDEFDeclaration(Node *){}; \ 56 | virtual void ParsedFunctionDefinition(Node *functionNode, Node *declaratorNode){}; 57 | %define CONSTRUCTOR_PARAM 58 | %define CONSTRUCTOR_INIT 59 | %define CONSTRUCTOR_CODE \ 60 | ; 61 | %define ENUM_TOKEN EnumToken 62 | 63 | 64 | %token IDENTIFIER 65 | %token CONSTANT STRING_LITERAL SIZEOF 66 | %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP 67 | %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN 68 | %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN 69 | %token XOR_ASSIGN OR_ASSIGN TYPE_NAME 70 | 71 | %token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE RESTRICT 72 | %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID 73 | %token BOOL COMPLEX IMAGINARY 74 | %token STRUCT UNION ENUM ELLIPSIS 75 | 76 | %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN 77 | 78 | %type primary_expression 79 | %type postfix_expression argument_expression_list unary_expression 80 | %type unary_operator cast_expression multiplicative_expression additive_expression 81 | %type shift_expression relational_expression equality_expression and_expression 82 | %type exclusive_or_expression inclusive_or_expression logical_and_expression logical_or_expression 83 | %type conditional_expression assignment_expression assignment_operator expression 84 | %type constant_expression declaration declaration_specifiers init_declarator_list 85 | %type init_declarator storage_class_specifier type_specifier struct_or_union_specifier 86 | %type struct_or_union struct_declaration_list struct_declaration specifier_qualifier_list 87 | %type struct_declarator_list struct_declarator enum_specifier enumerator_list 88 | %type enumerator type_qualifier function_specifier declarator 89 | %type direct_declarator pointer type_qualifier_list parameter_type_list 90 | %type parameter_list parameter_declaration identifier_list type_name 91 | %type abstract_declarator direct_abstract_declarator initializer initializer_list 92 | %type designation designator_list designator statement 93 | %type labeled_statement compound_statement block_item_list block_item 94 | %type expression_statement selection_statement iteration_statement jump_statement 95 | %type translation_unit external_declaration function_definition declaration_list 96 | 97 | %start translation_unit 98 | %% 99 | 100 | primary_expression 101 | : IDENTIFIER 102 | { 103 | $$ = CN("primary_expression",1,CN(@1)); 104 | } 105 | | CONSTANT 106 | { 107 | $$ = CN("primary_expression",1,CN(@1)); 108 | } 109 | | STRING_LITERAL 110 | { 111 | $$ = CN("primary_expression",1,CN(@1)); 112 | } 113 | | '(' expression ')' 114 | { 115 | $$ = CN("primary_expression",3,CN(@1),$2,CN(@3)); 116 | } 117 | ; 118 | 119 | postfix_expression 120 | : primary_expression 121 | { 122 | $$ = CN("postfix_expression",1,$1); 123 | } 124 | | postfix_expression '[' expression ']' 125 | { 126 | $$ = CN("postfix_expression",4,$1,CN(@2),$3,CN(@4)); 127 | } 128 | | postfix_expression '(' ')' 129 | { 130 | $$ = CN("postfix_expression",3,$1,CN(@2),CN(@3)); 131 | } 132 | | postfix_expression '(' argument_expression_list ')' 133 | { 134 | $$ = CN("postfix_expression",4,$1,CN(@2),$3,CN(@4)); 135 | } 136 | | postfix_expression '.' IDENTIFIER 137 | { 138 | $$ = CN("postfix_expression",3,$1,CN(@2),CN(@3)); 139 | } 140 | | postfix_expression PTR_OP IDENTIFIER 141 | { 142 | $$ = CN("postfix_expression",3,$1,CN(@2),CN(@3)); 143 | } 144 | | postfix_expression INC_OP 145 | { 146 | $$ = CN("postfix_expression",2,$1,CN(@2)); 147 | } 148 | | postfix_expression DEC_OP 149 | { 150 | $$ = CN("postfix_expression",2,$1,CN(@2)); 151 | } 152 | | '(' type_name ')' '{' initializer_list '}' 153 | { 154 | $$ = CN("postfix_expression",6,CN(@1),$2,CN(@3),CN(@4),$5,CN(@6)); 155 | } 156 | | '(' type_name ')' '{' initializer_list ',' '}' 157 | { 158 | $$ = CN("postfix_expression",7,CN(@1),$2,CN(@3),CN(@4),$5,CN(@6),CN(@7)); 159 | } 160 | ; 161 | 162 | argument_expression_list 163 | : assignment_expression 164 | { 165 | $$ = CN("argument_expression_list",1,$1); 166 | } 167 | | argument_expression_list ',' assignment_expression 168 | { 169 | $$ = CN("argument_expression_list",3,$1,CN(@2),$3); 170 | } 171 | ; 172 | 173 | unary_expression 174 | : postfix_expression 175 | { 176 | $$ = CN("unary_expression",1,$1); 177 | } 178 | | INC_OP unary_expression 179 | { 180 | $$ = CN("unary_expression",2,CN(@1),$2); 181 | } 182 | | DEC_OP unary_expression 183 | { 184 | $$ = CN("unary_expression",2,CN(@1),$2); 185 | } 186 | | unary_operator cast_expression 187 | { 188 | $$ = CN("unary_expression",2,$1,$2); 189 | } 190 | | SIZEOF unary_expression 191 | { 192 | $$ = CN("unary_expression",2,CN(@1),$2); 193 | } 194 | | SIZEOF '(' type_name ')' 195 | { 196 | $$ = CN("unary_expression",4,CN(@1),CN(@2),$3,CN(@4)); 197 | } 198 | ; 199 | 200 | unary_operator 201 | : '&' 202 | { $$ = CN(@1); } 203 | | '*' 204 | { $$ = CN(@1); } 205 | | '+' 206 | { $$ = CN(@1); } 207 | | '-' 208 | { $$ = CN(@1); } 209 | | '~' 210 | { $$ = CN(@1); } 211 | | '!' 212 | { $$ = CN(@1); } 213 | ; 214 | cast_expression 215 | : unary_expression 216 | { 217 | $$ = CN("cast_expression",1,$1); 218 | } 219 | | '(' type_name ')' cast_expression 220 | { 221 | $$ = CN("cast_expression",4,CN(@1),$2,CN(@3),$4); 222 | } 223 | ; 224 | 225 | multiplicative_expression 226 | : cast_expression 227 | { 228 | $$ = CN("multiplicative_expression",1,$1); 229 | } 230 | | multiplicative_expression '*' cast_expression 231 | { 232 | $$ = CN("multiplicative_expression",3,$1,CN(@2),$3); 233 | } 234 | | multiplicative_expression '/' cast_expression 235 | { 236 | $$ = CN("multiplicative_expression",3,$1,CN(@2),$3); 237 | } 238 | | multiplicative_expression '%' cast_expression 239 | { 240 | $$ = CN("multiplicative_expression",3,$1,CN(@2),$3); 241 | } 242 | ; 243 | 244 | additive_expression 245 | : multiplicative_expression 246 | { 247 | $$ = CN("additive_expression",1,$1); 248 | } 249 | | additive_expression '+' multiplicative_expression 250 | { 251 | $$ = CN("additive_expression",3,$1,CN(@2),$3); 252 | } 253 | | additive_expression '-' multiplicative_expression 254 | { 255 | $$ = CN("additive_expression",3,$1,CN(@2),$3); 256 | } 257 | ; 258 | 259 | shift_expression 260 | : additive_expression 261 | { 262 | $$ = CN("shift_expression",1,$1); 263 | } 264 | | shift_expression LEFT_OP additive_expression 265 | { 266 | $$ = CN("shift_expression",3,$1,CN(@2),$3); 267 | } 268 | | shift_expression RIGHT_OP additive_expression 269 | { 270 | $$ = CN("shift_expression",3,$1,CN(@2),$3); 271 | } 272 | ; 273 | 274 | relational_expression 275 | : shift_expression 276 | { 277 | $$ = CN("relational_expression",1,$1); 278 | } 279 | | relational_expression '<' shift_expression 280 | { 281 | $$ = CN("relational_expression",3,$1,CN(@2),$3); 282 | } 283 | | relational_expression '>' shift_expression 284 | { 285 | $$ = CN("relational_expression",3,$1,CN(@2),$3); 286 | } 287 | | relational_expression LE_OP shift_expression 288 | { 289 | $$ = CN("relational_expression",3,$1,CN(@2),$3); 290 | } 291 | | relational_expression GE_OP shift_expression 292 | { 293 | $$ = CN("relational_expression",3,$1,CN(@2),$3); 294 | } 295 | ; 296 | 297 | equality_expression 298 | : relational_expression 299 | { 300 | $$ = CN("equality_expression",1,$1); 301 | } 302 | | equality_expression EQ_OP relational_expression 303 | { 304 | $$ = CN("equality_expression",3,$1,CN(@2),$3); 305 | } 306 | | equality_expression NE_OP relational_expression 307 | { 308 | $$ = CN("equality_expression",3,$1,CN(@2),$3); 309 | } 310 | ; 311 | 312 | and_expression 313 | : equality_expression 314 | { 315 | $$ = CN("and_expression",1,$1); 316 | } 317 | | and_expression '&' equality_expression 318 | { 319 | $$ = CN("and_expression",3,$1,CN(@2),$3); 320 | } 321 | ; 322 | 323 | exclusive_or_expression 324 | : and_expression 325 | { 326 | $$ = CN("exclusive_or_expression",1,$1); 327 | } 328 | | exclusive_or_expression '^' and_expression 329 | { 330 | $$ = CN("exclusive_or_expression",3,$1,CN(@2),$3); 331 | } 332 | ; 333 | 334 | inclusive_or_expression 335 | : exclusive_or_expression 336 | { 337 | $$ = CN("inclusive_or_expression",1,$1); 338 | } 339 | | inclusive_or_expression '|' exclusive_or_expression 340 | { 341 | $$ = CN("inclusive_or_expression",3,$1,CN(@2),$3); 342 | } 343 | ; 344 | 345 | logical_and_expression 346 | : inclusive_or_expression 347 | { 348 | $$ = CN("logical_and_expression",1,$1); 349 | } 350 | | logical_and_expression AND_OP inclusive_or_expression 351 | { 352 | $$ = CN("logical_and_expression",3,$1,CN(@2),$3); 353 | } 354 | ; 355 | 356 | logical_or_expression 357 | : logical_and_expression 358 | { 359 | $$ = CN("logical_or_expression",1,$1); 360 | } 361 | | logical_or_expression OR_OP logical_and_expression 362 | { 363 | $$ = CN("logical_or_expression",3,$1,CN(@2),$3); 364 | } 365 | ; 366 | 367 | conditional_expression 368 | : logical_or_expression 369 | { 370 | $$ = CN("conditional_expression",1,$1); 371 | } 372 | | logical_or_expression '?' expression ':' conditional_expression 373 | { 374 | $$ = CN("conditional_expression",5,$1,CN(@2),$3,CN(@4),$5); 375 | } 376 | ; 377 | 378 | assignment_expression 379 | : conditional_expression 380 | { 381 | $$ = CN("assignment_expression",1,$1); 382 | } 383 | | unary_expression assignment_operator assignment_expression 384 | { 385 | $$ = CN("assignment_expression",3,$1,$2,$3); 386 | } 387 | ; 388 | 389 | assignment_operator 390 | : '=' 391 | { $$ = CN(@1); } 392 | | MUL_ASSIGN 393 | { $$ = CN(@1); } 394 | | DIV_ASSIGN 395 | { $$ = CN(@1); } 396 | | MOD_ASSIGN 397 | { $$ = CN(@1); } 398 | | ADD_ASSIGN 399 | { $$ = CN(@1); } 400 | | SUB_ASSIGN 401 | { $$ = CN(@1); } 402 | | LEFT_ASSIGN 403 | { $$ = CN(@1); } 404 | | RIGHT_ASSIGN 405 | { $$ = CN(@1); } 406 | | AND_ASSIGN 407 | { $$ = CN(@1); } 408 | | XOR_ASSIGN 409 | { $$ = CN(@1); } 410 | | OR_ASSIGN 411 | { $$ = CN(@1); } 412 | ; 413 | 414 | expression 415 | : assignment_expression 416 | { 417 | $$ = CN("expression",1,$1); 418 | } 419 | | expression ',' assignment_expression 420 | { 421 | $$ = CN("expression",3,$1,CN(@2),$3); 422 | } 423 | ; 424 | 425 | constant_expression 426 | : conditional_expression 427 | { 428 | $$ = CN("constant_expression",1,$1); 429 | } 430 | ; 431 | 432 | declaration 433 | : declaration_specifiers ';' 434 | { 435 | $$ = CN("declaration",2,$1,CN(@2)); 436 | //cout << endl << "declaration" << $$->ToCode() << endl; 437 | // Parser Action 438 | ParsedDeclaration($$); 439 | } 440 | | declaration_specifiers init_declarator_list ';' 441 | { 442 | $$ = CN("declaration",3,$1,$2,CN(@3)); 443 | //cout << endl << "declaration:" << $$->ToCode() << endl; 444 | // find all declarator and convert, if it is typedef. 445 | //FindTPYEDEFDeclaration($$); 446 | //cout << "not implement" << endl; 447 | // Parser Action 448 | ParsedDeclaration($$); 449 | } 450 | ; 451 | 452 | declaration_specifiers 453 | : storage_class_specifier 454 | { $$ = CN("declaration_specifiers",1,$1); } 455 | | storage_class_specifier declaration_specifiers 456 | { $$ = CN("declaration_specifiers",2,$1,$2); } 457 | | type_specifier 458 | { 459 | $$ = CN("declaration_specifiers",1,$1); 460 | } 461 | | type_specifier declaration_specifiers 462 | { 463 | $$ = CN("declaration_specifiers",2,$1,$2); 464 | } 465 | | type_qualifier 466 | { 467 | $$ = CN("declaration_specifiers",1,$1); 468 | } 469 | | type_qualifier declaration_specifiers 470 | { 471 | $$ = CN("declaration_specifiers",2,$1,$2); 472 | } 473 | | function_specifier 474 | { 475 | $$ = CN("declaration_specifiers",1,$1); 476 | } 477 | | function_specifier declaration_specifiers 478 | { 479 | $$ = CN("declaration_specifiers",2,$1,$2); 480 | } 481 | ; 482 | 483 | init_declarator_list 484 | : init_declarator 485 | { 486 | $$ = CN("init_declarator_list",1,$1); 487 | } 488 | | init_declarator_list ',' init_declarator 489 | { 490 | // method 1 491 | $$ = CN("init_declarator_list",3,$1,CN(@2),$3); 492 | // method 2. It will reduce the deepth of the AST. 493 | //$1->AddChildNode(2, CN(@2), $3); 494 | //$$ = $1; 495 | } 496 | ; 497 | 498 | init_declarator 499 | : declarator 500 | { 501 | $$ = CN("init_declarator",1,$1); 502 | } 503 | | declarator '=' initializer 504 | { 505 | $$ = CN("init_declarator",3,$1,CN(@2),$3); 506 | } 507 | ; 508 | 509 | storage_class_specifier 510 | : TYPEDEF 511 | { $$ = CN(@1); } 512 | | EXTERN 513 | { $$ = CN(@1); } 514 | | STATIC 515 | { $$ = CN(@1); } 516 | | AUTO 517 | { $$ = CN(@1); } 518 | | REGISTER 519 | { $$ = CN(@1); } 520 | ; 521 | 522 | type_specifier 523 | : VOID 524 | { $$ = CN(@1); } 525 | | CHAR 526 | { $$ = CN(@1); } 527 | | SHORT 528 | { $$ = CN(@1); } 529 | | INT 530 | { $$ = CN(@1); } 531 | | LONG 532 | { $$ = CN(@1); } 533 | | FLOAT 534 | { $$ = CN(@1); } 535 | | DOUBLE 536 | { $$ = CN(@1); } 537 | | SIGNED 538 | { $$ = CN(@1); } 539 | | UNSIGNED 540 | { $$ = CN(@1); } 541 | | BOOL 542 | { $$ = CN(@1); } 543 | | COMPLEX 544 | { $$ = CN(@1); } 545 | | IMAGINARY 546 | { $$ = CN(@1); } 547 | | struct_or_union_specifier 548 | { $$ = $1; } 549 | | enum_specifier 550 | { $$ = $1; } 551 | | TYPE_NAME 552 | { $$ = CN(@1); } 553 | ; 554 | 555 | struct_or_union_specifier 556 | : struct_or_union IDENTIFIER '{' struct_declaration_list '}' 557 | { 558 | $$ = CN("struct_or_union_specifier",5,$1,CN(@2),CN(@3),$4,CN(@5)); 559 | } 560 | | struct_or_union '{' struct_declaration_list '}' 561 | { 562 | $$ = CN("struct_or_union_specifier",4,$1,CN(@2),$3,CN(@4)); 563 | } 564 | | struct_or_union IDENTIFIER 565 | { 566 | $$ = CN("struct_or_union_specifier",2,$1,CN(@2)); 567 | } 568 | ; 569 | 570 | struct_or_union 571 | : STRUCT 572 | { $$ = CN(@1); } 573 | | UNION 574 | { $$ = CN(@1); } 575 | ; 576 | 577 | struct_declaration_list 578 | : struct_declaration 579 | { 580 | $$ = CN("struct_declaration_list",1,$1); 581 | } 582 | | struct_declaration_list struct_declaration 583 | { 584 | $$ = CN("struct_declaration_list",2,$1,$2); 585 | } 586 | ; 587 | 588 | struct_declaration 589 | : specifier_qualifier_list struct_declarator_list ';' 590 | { 591 | $$ = CN("struct_declaration",3,$1,$2,CN(@3)); 592 | } 593 | ; 594 | 595 | specifier_qualifier_list 596 | : type_specifier specifier_qualifier_list 597 | { 598 | $$ = CN("specifier_qualifier_list",2,$1,$2); 599 | } 600 | | type_specifier 601 | { 602 | $$ = CN("specifier_qualifier_list",1,$1); 603 | } 604 | | type_qualifier specifier_qualifier_list 605 | { 606 | $$ = CN("specifier_qualifier_list",2,$1,$2); 607 | } 608 | | type_qualifier 609 | { 610 | $$ = CN("specifier_qualifier_list",1,$1); 611 | } 612 | ; 613 | 614 | struct_declarator_list 615 | : struct_declarator 616 | { 617 | $$ = CN("struct_declarator_list",1,$1); 618 | } 619 | | struct_declarator_list ',' struct_declarator 620 | { 621 | $$ = CN("struct_declarator_list",3,$1,CN(@2),$3); 622 | } 623 | ; 624 | 625 | struct_declarator 626 | : declarator 627 | { 628 | $$ = CN("struct_declarator",1,$1); 629 | } 630 | | ':' constant_expression 631 | { 632 | $$ = CN("struct_declarator",2,CN(@1),$2); 633 | } 634 | | declarator ':' constant_expression 635 | { 636 | $$ = CN("struct_declarator",3,$1,CN(@2),$3); 637 | } 638 | ; 639 | 640 | enum_specifier 641 | : ENUM '{' enumerator_list '}' 642 | { 643 | $$ = CN("enum_specifier",4,CN(@1),CN(@2),$3,CN(@4)); 644 | } 645 | | ENUM IDENTIFIER '{' enumerator_list '}' 646 | { 647 | $$ = CN("enum_specifier",5,CN(@1),CN(@2),CN(@3),$4,CN(@5)); 648 | } 649 | | ENUM '{' enumerator_list ',' '}' 650 | { 651 | $$ = CN("enum_specifier",5,CN(@1),CN(@2),$3,CN(@4),CN(@5)); 652 | } 653 | | ENUM IDENTIFIER '{' enumerator_list ',' '}' 654 | { 655 | $$ = CN("enum_specifier",6,CN(@1),CN(@2),CN(@3),$4,CN(@5),CN(@6)); 656 | } 657 | | ENUM IDENTIFIER 658 | { 659 | $$ = CN("enum_specifier",2,CN(@1),CN(@2)); 660 | } 661 | ; 662 | 663 | enumerator_list 664 | : enumerator 665 | { 666 | $$ = CN("enumerator_list",1,$1); 667 | } 668 | | enumerator_list ',' enumerator 669 | { 670 | $$ = CN("enumerator_list",3,$1,CN(@2),$3); 671 | } 672 | ; 673 | 674 | enumerator 675 | : IDENTIFIER 676 | { 677 | $$ = CN("enumerator",1,CN(@1)); 678 | } 679 | | IDENTIFIER '=' constant_expression 680 | { 681 | $$ = CN("enumerator",3,CN(@1),CN(@2),$3); 682 | } 683 | ; 684 | 685 | type_qualifier 686 | : CONST 687 | { $$ = CN(@1); } 688 | | RESTRICT 689 | { $$ = CN(@1); } 690 | | VOLATILE 691 | { $$ = CN(@1); } 692 | ; 693 | 694 | function_specifier 695 | : INLINE 696 | { $$ = CN(@1); } 697 | ; 698 | 699 | declarator 700 | : pointer direct_declarator 701 | { 702 | $$ = CN("declarator",2,$1,$2); 703 | } 704 | | direct_declarator 705 | { 706 | //cout << "direct_declarator" << @1.theText << endl; 707 | $$ = CN("declarator",1,$1); 708 | } 709 | ; 710 | 711 | 712 | direct_declarator 713 | : IDENTIFIER 714 | { 715 | $$ = CN("direct_declarator",1,CN(@1)); 716 | } 717 | | '(' declarator ')' 718 | { 719 | $$ = CN("direct_declarator",3,CN(@1),$2,CN(@3)); 720 | } 721 | | direct_declarator '[' type_qualifier_list assignment_expression ']' 722 | { 723 | $$ = CN("direct_declarator",5,$1,CN(@2),$3,$4,CN(@5)); 724 | } 725 | | direct_declarator '[' type_qualifier_list ']' 726 | { 727 | $$ = CN("direct_declarator",4,$1,CN(@2),$3,CN(@4)); 728 | } 729 | | direct_declarator '[' assignment_expression ']' 730 | { 731 | $$ = CN("direct_declarator",4,$1,CN(@2),$3,CN(@4)); 732 | } 733 | | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']' 734 | { 735 | $$ = CN("direct_declarator",6,$1,CN(@2),CN(@3),$4,$5,CN(@6)); 736 | } 737 | | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']' 738 | { 739 | $$ = CN("direct_declarator",6,$1,CN(@2),$3,CN(@4),$5,CN(@6)); 740 | } 741 | | direct_declarator '[' type_qualifier_list '*' ']' 742 | { 743 | $$ = CN("direct_declarator",5,$1,CN(@2),$3,CN(@4),CN(@5)); 744 | } 745 | | direct_declarator '[' '*' ']' 746 | { 747 | $$ = CN("direct_declarator",4,$1,CN(@2),CN(@3),CN(@4)); 748 | } 749 | | direct_declarator '[' ']' 750 | { 751 | $$ = CN("direct_declarator",3,$1,CN(@2),CN(@3)); 752 | } 753 | | direct_declarator '(' parameter_type_list ')' 754 | { 755 | $$ = CN("direct_declarator",4,$1,CN(@2),$3,CN(@4)); 756 | } 757 | | direct_declarator '(' identifier_list ')' 758 | { 759 | $$ = CN("direct_declarator",4,$1,CN(@2),$3,CN(@4)); 760 | } 761 | | direct_declarator '(' ')' 762 | { 763 | $$ = CN("direct_declarator",3,$1,CN(@2),CN(@3)); 764 | } 765 | ; 766 | 767 | pointer 768 | : '*' 769 | { 770 | $$ = CN("pointer",1,CN(@1)); 771 | } 772 | | '*' type_qualifier_list 773 | { 774 | $$ = CN("pointer",2,CN(@1),$2); 775 | } 776 | | '*' pointer 777 | { 778 | $$ = CN("pointer",2,CN(@1),$2); 779 | } 780 | | '*' type_qualifier_list pointer 781 | { 782 | $$ = CN("pointer",3,CN(@1),$2,$3); 783 | } 784 | ; 785 | 786 | type_qualifier_list 787 | : type_qualifier 788 | { 789 | $$ = CN("type_qualifier_list",1,$1); 790 | } 791 | | type_qualifier_list type_qualifier 792 | { 793 | $$ = CN("type_qualifier_list",2,$1,$2); 794 | } 795 | ; 796 | 797 | 798 | parameter_type_list 799 | : parameter_list 800 | { 801 | $$ = CN("parameter_type_list",1,$1); 802 | } 803 | | parameter_list ',' ELLIPSIS 804 | { 805 | $$ = CN("parameter_type_list",3,$1,CN(@2),CN(@3)); 806 | } 807 | ; 808 | 809 | parameter_list 810 | : parameter_declaration 811 | { 812 | $$ = CN("parameter_list",1,$1); 813 | } 814 | | parameter_list ',' parameter_declaration 815 | { 816 | $$ = CN("parameter_list",3,$1,CN(@2),$3); 817 | } 818 | ; 819 | 820 | parameter_declaration 821 | : declaration_specifiers declarator 822 | { 823 | $$ = CN("parameter_declaration",2,$1,$2); 824 | } 825 | | declaration_specifiers abstract_declarator 826 | { 827 | $$ = CN("parameter_declaration",2,$1,$2); 828 | } 829 | | declaration_specifiers 830 | { 831 | $$ = CN("parameter_declaration",1,$1); 832 | } 833 | ; 834 | 835 | identifier_list 836 | : IDENTIFIER 837 | { 838 | $$ = CN("identifier_list",1,CN(@1)); 839 | } 840 | | identifier_list ',' IDENTIFIER 841 | { 842 | $$ = CN("identifier_list",3,$1,CN(@2),CN(@3)); 843 | } 844 | ; 845 | 846 | type_name 847 | : specifier_qualifier_list 848 | { 849 | $$ = CN("type_name",1,$1); 850 | } 851 | | specifier_qualifier_list abstract_declarator 852 | { 853 | $$ = CN("type_name",2,$1,$2); 854 | } 855 | ; 856 | 857 | abstract_declarator 858 | : pointer 859 | { 860 | $$ = CN("abstract_declarator",1,$1); 861 | } 862 | | direct_abstract_declarator 863 | { 864 | $$ = CN("abstract_declarator",1,$1); 865 | } 866 | | pointer direct_abstract_declarator 867 | { 868 | $$ = CN("abstract_declarator",2,$1,$2); 869 | } 870 | ; 871 | 872 | direct_abstract_declarator 873 | : '(' abstract_declarator ')' 874 | { 875 | $$ = CN("direct_abstract_declarator",3,CN(@1),$2,CN(@3)); 876 | } 877 | | '[' ']' 878 | { 879 | $$ = CN("direct_abstract_declarator",2,CN(@1),CN(@2)); 880 | } 881 | | '[' assignment_expression ']' 882 | { 883 | $$ = CN("direct_abstract_declarator",3,CN(@1),$2,CN(@3)); 884 | } 885 | | direct_abstract_declarator '[' ']' 886 | { 887 | $$ = CN("direct_abstract_declarator",3,$1,CN(@2),CN(@3)); 888 | } 889 | | direct_abstract_declarator '[' assignment_expression ']' 890 | { 891 | $$ = CN("direct_abstract_declarator",4,$1,CN(@2),$3,CN(@4)); 892 | } 893 | | '[' '*' ']' 894 | { 895 | $$ = CN("direct_abstract_declarator",3,CN(@1),CN(@2),CN(@3)); 896 | } 897 | | direct_abstract_declarator '[' '*' ']' 898 | { 899 | $$ = CN("direct_abstract_declarator",4,$1,CN(@2),CN(@3),CN(@4)); 900 | } 901 | | '(' ')' 902 | { 903 | $$ = CN("direct_abstract_declarator",2,CN(@1),CN(@2)); 904 | } 905 | | '(' parameter_type_list ')' 906 | { 907 | $$ = CN("direct_abstract_declarator",3,CN(@1),$2,CN(@3)); 908 | } 909 | | direct_abstract_declarator '(' ')' 910 | { 911 | $$ = CN("direct_abstract_declarator",3,$1,CN(@2),CN(@3)); 912 | } 913 | | direct_abstract_declarator '(' parameter_type_list ')' 914 | { 915 | $$ = CN("direct_abstract_declarator",4,$1,CN(@2),$3,CN(@4)); 916 | } 917 | ; 918 | 919 | initializer 920 | : assignment_expression 921 | { 922 | $$ = CN("initializer",1,$1); 923 | } 924 | | '{' initializer_list '}' 925 | { 926 | $$ = CN("initializer",3,CN(@1),$2,CN(@3)); 927 | } 928 | | '{' initializer_list ',' '}' 929 | { 930 | $$ = CN("initializer",4,CN(@1),$2,CN(@3),CN(@4)); 931 | } 932 | ; 933 | 934 | initializer_list 935 | : initializer 936 | { 937 | $$ = CN("initializer_list",1,$1); 938 | } 939 | | designation initializer 940 | { 941 | $$ = CN("initializer_list",2,$1,$2); 942 | } 943 | | initializer_list ',' initializer 944 | { 945 | $$ = CN("initializer_list",3,$1,CN(@2),$3); 946 | } 947 | | initializer_list ',' designation initializer 948 | { 949 | $$ = CN("initializer_list",4,$1,CN(@2),$3,$4); 950 | } 951 | ; 952 | 953 | designation 954 | : designator_list '=' 955 | { 956 | $$ = CN("designation",2,$1,CN(@2)); 957 | } 958 | ; 959 | 960 | designator_list 961 | : designator 962 | { 963 | $$ = CN("designator_list",1,$1); 964 | } 965 | | designator_list designator 966 | { 967 | $$ = CN("designator_list",2,$1,$2); 968 | } 969 | ; 970 | 971 | designator 972 | : '[' constant_expression ']' 973 | { 974 | $$ = CN("designator",3,CN(@1),$2,CN(@3)); 975 | } 976 | | '.' IDENTIFIER 977 | { 978 | $$ = CN("designator",2,CN(@1),CN(@2)); 979 | } 980 | ; 981 | 982 | statement 983 | : labeled_statement 984 | { 985 | $$ = CN("statement",1,$1); 986 | } 987 | | compound_statement 988 | { 989 | $$ = CN("statement",1,$1); 990 | } 991 | | expression_statement 992 | { 993 | $$ = CN("statement",1,$1); 994 | } 995 | | selection_statement 996 | { 997 | $$ = CN("statement",1,$1); 998 | } 999 | | iteration_statement 1000 | { 1001 | $$ = CN("statement",1,$1); 1002 | } 1003 | | jump_statement 1004 | { 1005 | $$ = CN("statement",1,$1); 1006 | } 1007 | ; 1008 | 1009 | labeled_statement 1010 | : IDENTIFIER ':' statement 1011 | { 1012 | $$ = CN("labeled_statement",3,CN(@1),CN(@2),$3); 1013 | } 1014 | | CASE constant_expression ':' statement 1015 | { 1016 | $$ = CN("labeled_statement",4,CN(@1),$2,CN(@3),$4); 1017 | } 1018 | | DEFAULT ':' statement 1019 | { 1020 | $$ = CN("labeled_statement",3,CN(@1),CN(@2),$3); 1021 | } 1022 | ; 1023 | 1024 | compound_statement 1025 | : '{' '}' 1026 | { 1027 | $$ = CN("compound_statement",2,CN(@1),CN(@2)); 1028 | } 1029 | | '{' block_item_list '}' 1030 | { 1031 | $$ = CN("compound_statement",3,CN(@1),$2,CN(@3)); 1032 | } 1033 | ; 1034 | 1035 | block_item_list 1036 | : block_item 1037 | { 1038 | $$ = CN("block_item_list",1,$1); 1039 | } 1040 | | block_item_list block_item 1041 | { 1042 | //$$ = CN("block_item_list",2,$1,$2); 1043 | $$ = $1; 1044 | $1->AddChildNode($2); 1045 | } 1046 | ; 1047 | 1048 | block_item 1049 | : declaration 1050 | { 1051 | //$$ = CN("block_item",1,$1); 1052 | $$ = $1; 1053 | } 1054 | | statement 1055 | { 1056 | //$$ = CN("block_item",1,$1); 1057 | $$ = $1; 1058 | } 1059 | ; 1060 | 1061 | expression_statement 1062 | : ';' 1063 | { 1064 | $$ = CN("expression_statement",1,CN(@1)); 1065 | } 1066 | | expression ';' 1067 | { 1068 | $$ = CN("expression_statement",2,$1,CN(@2)); 1069 | } 1070 | ; 1071 | 1072 | selection_statement 1073 | : IF '(' expression ')' statement 1074 | { 1075 | $$ = CN("selection_statement",5,CN(@1),CN(@2),$3,CN(@4),$5); 1076 | } 1077 | | IF '(' expression ')' statement ELSE statement 1078 | { 1079 | $$ = CN("selection_statement",7,CN(@1),CN(@2),$3,CN(@4),$5,CN(@6),$7); 1080 | } 1081 | | SWITCH '(' expression ')' statement 1082 | { 1083 | $$ = CN("selection_statement",5,CN(@1),CN(@2),$3,CN(@4),$5); 1084 | } 1085 | ; 1086 | 1087 | iteration_statement 1088 | : WHILE '(' expression ')' statement 1089 | { 1090 | $$ = CN("iteration_statement",5,CN(@1),CN(@2),$3,CN(@4),$5); 1091 | } 1092 | | DO statement WHILE '(' expression ')' ';' 1093 | { 1094 | $$ = CN("iteration_statement",7,CN(@1),$2,CN(@3),CN(@4),$5,CN(@6),CN(@7)); 1095 | } 1096 | | FOR '(' expression_statement expression_statement ')' statement 1097 | { 1098 | $$ = CN("iteration_statement",6,CN(@1),CN(@2),$3,$4,CN(@5),$6); 1099 | } 1100 | | FOR '(' expression_statement expression_statement expression ')' statement 1101 | { 1102 | $$ = CN("iteration_statement",7,CN(@1),CN(@2),$3,$4,$5,CN(@6),$7); 1103 | } 1104 | | FOR '(' declaration expression_statement ')' statement 1105 | { 1106 | $$ = CN("iteration_statement",6,CN(@1),CN(@2),$3,$4,CN(@5),$6); 1107 | } 1108 | | FOR '(' declaration expression_statement expression ')' statement 1109 | { 1110 | $$ = CN("iteration_statement",7,CN(@1),CN(@2),$3,$4,$5,CN(@6),$7); 1111 | } 1112 | ; 1113 | 1114 | jump_statement 1115 | : GOTO IDENTIFIER ';' 1116 | { 1117 | $$ = CN("jump_statement",3,CN(@1),CN(@2),CN(@3)); 1118 | } 1119 | | CONTINUE ';' 1120 | { 1121 | $$ = CN("jump_statement",2,CN(@1),CN(@2)); 1122 | } 1123 | | BREAK ';' 1124 | { 1125 | $$ = CN("jump_statement",2,CN(@1),CN(@2)); 1126 | } 1127 | | RETURN ';' 1128 | { 1129 | $$ = CN("jump_statement",2,CN(@1),CN(@2)); 1130 | } 1131 | | RETURN expression ';' 1132 | { 1133 | $$ = CN("jump_statement",3,CN(@1),$2,CN(@3)); 1134 | } 1135 | ; 1136 | 1137 | translation_unit 1138 | : external_declaration 1139 | { 1140 | $$ = CN("translation_unit",1,$1); 1141 | setCurrentTree((Tree *)$$); 1142 | } 1143 | | translation_unit external_declaration 1144 | { 1145 | $$ = CN("translation_unit",2,$1,$2); 1146 | setCurrentTree((Tree *)$$); 1147 | } 1148 | ; 1149 | 1150 | external_declaration 1151 | : function_definition 1152 | { 1153 | $$ = CN("external_declaration",1,$1); 1154 | } 1155 | | declaration 1156 | { 1157 | $$ = CN("external_declaration",1,$1); 1158 | } 1159 | | ';' 1160 | { 1161 | $$ = CN("external_declaration",1,CN(@1)); 1162 | } 1163 | ; 1164 | 1165 | function_definition 1166 | : declaration_specifiers declarator declaration_list compound_statement 1167 | { 1168 | $$ = CN("function_definition",4,$1,$2,$3,$4); 1169 | // Parser Action 1170 | ParsedFunctionDefinition($$, $2); 1171 | } 1172 | | declaration_specifiers declarator compound_statement 1173 | { 1174 | $$ = CN("function_definition",3,$1,$2,$3); 1175 | // Parser Action 1176 | ParsedFunctionDefinition($$, $2); 1177 | } 1178 | ; 1179 | 1180 | declaration_list 1181 | : declaration 1182 | { 1183 | $$ = CN("declaration_list",1,$1); 1184 | } 1185 | | declaration_list declaration 1186 | { 1187 | $$ = CN("declaration_list",2,$1,$2); 1188 | } 1189 | ; 1190 | 1191 | %% 1192 | --------------------------------------------------------------------------------