├── .gitignore ├── CodeConfusing ├── classmodel.cpp ├── classmodel.h ├── codeconfusing.pro ├── codepiece.json ├── cppparser.cpp ├── cppparser.h ├── database.cpp ├── database.h ├── dict.txt ├── fileviewer.cpp ├── fileviewer.h ├── garbagecode.cpp ├── garbagecode.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── ocparser.cpp ├── ocparser.h ├── reskeys.txt ├── resources.qrc ├── resultdialog.cpp ├── resultdialog.h ├── srcfilemodel.cpp ├── srcfilemodel.h ├── stringutil.cpp └── stringutil.h ├── README.md └── 使用说明.docx /.gitignore: -------------------------------------------------------------------------------- 1 | Debug 2 | Release 3 | .xcodeproj 4 | tmp 5 | -------------------------------------------------------------------------------- /CodeConfusing/classmodel.cpp: -------------------------------------------------------------------------------- 1 | #include "classmodel.h" 2 | 3 | ClassModel::ClassModel() 4 | { 5 | fileName = ""; //不带后缀名的文件名 6 | filePath = ""; //文件路径 7 | className = ""; //类名词 8 | identifyName = ""; 9 | identifyOriginName = ""; 10 | isObjectiveC = false; 11 | isPropertyName = false; 12 | isMethodName = false; 13 | } 14 | -------------------------------------------------------------------------------- /CodeConfusing/classmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | class ClassModel 8 | { 9 | public: 10 | string fileName; //不带后缀名的文件名 11 | string filePath; //文件路径 12 | string className; //类名词 13 | string identifyName; 14 | string identifyOriginName; 15 | 16 | bool isObjectiveC; 17 | bool isPropertyName; 18 | bool isMethodName; 19 | 20 | ClassModel(); 21 | }; 22 | -------------------------------------------------------------------------------- /CodeConfusing/codeconfusing.pro: -------------------------------------------------------------------------------- 1 | 2 | QT += core gui 3 | 4 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 5 | 6 | CONFIG += c++11 link_pkgconfig 7 | 8 | TARGET = codeconfusing 9 | TEMPLATE = app 10 | 11 | SOURCES += main.cpp\ 12 | mainwindow.cpp \ 13 | fileviewer.cpp \ 14 | cppparser.cpp \ 15 | ocparser.cpp \ 16 | srcfilemodel.cpp \ 17 | stringutil.cpp \ 18 | database.cpp \ 19 | classmodel.cpp \ 20 | resultdialog.cpp \ 21 | garbagecode.cpp 22 | 23 | HEADERS += \ 24 | mainwindow.h \ 25 | fileviewer.h \ 26 | cppparser.h \ 27 | ocparser.h \ 28 | srcfilemodel.h \ 29 | stringutil.h \ 30 | database.h \ 31 | classmodel.h \ 32 | resultdialog.h \ 33 | garbagecode.h 34 | 35 | RESOURCES += \ 36 | resources.qrc 37 | -------------------------------------------------------------------------------- /CodeConfusing/codepiece.json: -------------------------------------------------------------------------------- 1 | { 2 | "0":"printf(\"(%s)%s:[%d]\\n\", __FILE__, __FUNCTION__, __LINE__);" 3 | , 4 | "1":"#include " 5 | } 6 | -------------------------------------------------------------------------------- /CodeConfusing/cppparser.cpp: -------------------------------------------------------------------------------- 1 | #include "cppparser.h" 2 | #include "database.h" 3 | #include 4 | 5 | CppParser::CppParser() 6 | { 7 | classname = ""; 8 | } 9 | 10 | int CppParser::parseCppFile(SrcFileModel srcFile) 11 | { 12 | QFile file(srcFile.filePath.c_str()); 13 | if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) 14 | { 15 | return -1; 16 | } 17 | 18 | StringUtil stringUtil; 19 | if(stringUtil.EndWith(srcFile.fileName, ".h") && srcFile.mFileName.length() == 0) 20 | { 21 | ifstream fin(srcFile.filePath.c_str());//文件输入流,p是代码路径 22 | string str; 23 | string temp; 24 | size_t pos = 0; 25 | while(getline(fin,temp,'\n')) 26 | { 27 | str.append(temp+"\r\n\t"); 28 | } 29 | R(str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 30 | //注释里面出现include的话会出事囧 31 | while(findSubStrAtPos(str,"#include",pos)){}//连续读取代码中的include名 32 | while(findSubStrAtPos(str,"class ",pos)){}//连续读取代码中的类 33 | while(findSubStrAtPos(str,"template",pos)){}//连续读取代码中的类 34 | 35 | QFile cppFile(srcFile.cppFilePath.c_str()); 36 | if(cppFile.open(QIODevice::ReadOnly | QIODevice::Text)) 37 | { 38 | fin.close(); 39 | 40 | srcFile.fileName = srcFile.cppFileName; 41 | srcFile.filePath = srcFile.cppFilePath; 42 | ifstream fin_cpp(srcFile.cppFilePath.c_str());//文件输入流,p是代码路径 43 | string str_cpp; 44 | string temp_cpp; 45 | pos = 0; 46 | while(getline(fin_cpp,temp_cpp,'\n')) 47 | { 48 | str_cpp.append(temp_cpp+"\r\n\t"); 49 | } 50 | while(findSubStrAtPos(str_cpp,"#include",pos)){}//连续读取代码中的include名 51 | 52 | R(str_cpp);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 53 | 54 | //has_class_declare为false的时候,表示虽然是cpp文件,但是cpp文件中不包含class类声明 55 | //GlobalClassDeclare这个类是默认用于添加形如"class A;"的类声明语句,不是真实类名 56 | bool has_class_declare = false; 57 | for(vector::iterator b = _classes.begin(); b!=_classes.end(); ++b) 58 | { 59 | if (trim(b->classname).length() > 0 && !stringUtil.EndWith(b->classname, "GlobalClassDeclare")) 60 | { 61 | has_class_declare = true; 62 | while(findFunctionAndVarsOfClass(str_cpp, b->classname,pos, *b)){}//连续读取代码中的类 63 | } 64 | } 65 | if (!has_class_declare) 66 | { 67 | findGlobalVarsAndFunctions(str_cpp); 68 | } 69 | display(srcFile); 70 | fin_cpp.close(); 71 | } 72 | else 73 | { 74 | display(srcFile); 75 | fin.close(); 76 | } 77 | } 78 | else if(stringUtil.EndWith(srcFile.fileName, ".cpp") || stringUtil.EndWith(srcFile.fileName, ".cxx") || stringUtil.EndWith(srcFile.fileName, ".cc") || stringUtil.EndWith(srcFile.fileName, ".mm")) 79 | { 80 | QFile headFile(srcFile.headerFilePath.c_str()); 81 | if(headFile.open(QIODevice::ReadOnly | QIODevice::Text)) 82 | { 83 | ifstream fHeaderIn(srcFile.headerFilePath.c_str());//文件输入流,p是代码路径 84 | string str; 85 | string temp; 86 | size_t pos = 0; 87 | while(getline(fHeaderIn,temp,'\n')) 88 | { 89 | str.append(temp+"\r\n\t"); 90 | } 91 | R(str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 92 | //注释里面出现include的话会出事囧 93 | while(findSubStrAtPos(str,"#include",pos)){}//连续读取代码中的include名 94 | while(findSubStrAtPos(str,"class ",pos)){}//连续读取代码中的类 95 | while(findSubStrAtPos(str,"template",pos)){}//连续读取代码中的类 96 | fHeaderIn.close(); 97 | 98 | ifstream fin_cpp(srcFile.filePath.c_str());//文件输入流,p是代码路径 99 | string str_cpp; 100 | string temp_cpp; 101 | pos = 0; 102 | while(getline(fin_cpp,temp_cpp,'\n')) 103 | { 104 | str_cpp.append(temp_cpp+"\r\n\t"); 105 | } 106 | while(findSubStrAtPos(str_cpp,"#include",pos)){}//连续读取代码中的include名 107 | 108 | R(str_cpp);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 109 | 110 | //has_class_declare为false的时候,表示虽然是cpp文件,但是cpp文件中不包含class类声明 111 | //GlobalClassDeclare这个类是默认用于添加形如"class A;"的类声明语句,不是真实类名 112 | bool has_class_declare = false; 113 | for(vector::iterator b = _classes.begin(); b!=_classes.end(); ++b) 114 | { 115 | if (trim(b->classname).length() > 0 && !stringUtil.EndWith(b->classname, "GlobalClassDeclare")) 116 | { 117 | has_class_declare = true; 118 | while(findFunctionAndVarsOfClass(str_cpp, b->classname,pos, *b)){}//连续读取代码中的类 119 | } 120 | } 121 | if (!has_class_declare) 122 | { 123 | findGlobalVarsAndFunctions(str_cpp); 124 | } 125 | display(srcFile); 126 | fin_cpp.close(); 127 | } 128 | else 129 | { 130 | ifstream fin(srcFile.filePath.c_str());//文件输入流,p是代码路径 131 | string str; 132 | string temp; 133 | size_t pos = 0; 134 | while(getline(fin,temp,'\n')) 135 | { 136 | str.append(temp+"\r\n\t"); 137 | } 138 | R(str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 139 | 140 | //注释里面出现include的话会出事囧 141 | while(findSubStrAtPos(str,"#include",pos)){}//连续读取代码中的include名 142 | while(findSubStrAtPos(str,"class ",pos)){}//连续读取代码中的类 143 | while(findSubStrAtPos(str,"template",pos)){}//连续读取代码中的类 144 | 145 | findGlobalVarsAndFunctions(str); 146 | 147 | display(srcFile); 148 | fin.close(); 149 | } 150 | } 151 | else if(stringUtil.EndWith(srcFile.fileName, ".c")) 152 | { 153 | ifstream fin(srcFile.filePath.c_str());//文件输入流,p是代码路径 154 | string str; 155 | string temp; 156 | size_t pos = 0; 157 | while(getline(fin,temp,'\n')) 158 | { 159 | str.append(temp+"\r\n\t"); 160 | } 161 | R(str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 162 | 163 | //注释里面出现include的话会出事囧 164 | while(findSubStrAtPos(str,"#include",pos)){}//连续读取代码中的include名 165 | while(findSubStrAtPos(str,"class ",pos)){}//连续读取代码中的类 166 | while(findSubStrAtPos(str,"template",pos)){}//连续读取代码中的类 167 | 168 | findGlobalVarsAndFunctions(str); 169 | 170 | display(srcFile); 171 | fin.close(); 172 | } 173 | else 174 | { 175 | //其他文件格式 176 | } 177 | 178 | return 0; 179 | } 180 | 181 | size_t CppParser::judge(string s) 182 | { 183 | if(s=="#include") 184 | { 185 | return INCLUDE; 186 | } 187 | else if(s=="class ") 188 | { 189 | return CLASS; 190 | } 191 | else if(s=="template") 192 | { 193 | return TEMPLATE_CLASS; 194 | } 195 | else if(s=="vaiabler") 196 | { 197 | return VARIABLE; 198 | } 199 | else if(s=="function") 200 | { 201 | return FUNCTION; 202 | } 203 | return UNDEINED; 204 | } 205 | 206 | void CppParser::D(string& str,char c) 207 | { 208 | if(c == '#') //如果字符是 '=' , 则把 = 等号 和 ; 分号之间的信息除去,例如:int a = 5; 把=号、空格和5给擦除 209 | { 210 | size_t index_s = 0; 211 | while(index_s(isspace))); 397 | str.erase(str.begin(), p); 398 | return str; 399 | } 400 | 401 | inline string& CppParser::rtrim(string &str) 402 | { 403 | string::reverse_iterator p = find_if(str.rbegin(), str.rend(), not1(ptr_fun(isspace))); 404 | str.erase(p.base(), str.end()); 405 | return str; 406 | } 407 | 408 | inline string& CppParser::trim(string &str) 409 | { 410 | ltrim(rtrim(str)); 411 | return str; 412 | } 413 | 414 | void CppParser::display(SrcFileModel fileModel) 415 | { 416 | DataBase *database = DataBase::Instance(); 417 | 418 | vector::iterator b; 419 | size_t pos; 420 | for(b = include.begin(); b!=include.end();++b) 421 | { 422 | //include 423 | } 424 | vector::iterator i; 425 | for(i = _classes.begin(); i!=_classes.end() ; ++i) 426 | { 427 | //类名 428 | string classname = i->classname; 429 | 430 | if(i->extends.size() != 0) 431 | { 432 | for(b = i->extends.begin(); b != i->extends.end(); ++b) 433 | { 434 | pos = 0; 435 | trim(*b); 436 | ignorespacetab(*b,pos); 437 | if(pos != b->length()) 438 | { 439 | //继承 440 | } 441 | } 442 | } 443 | for(b = i->var.begin(); b != i->var.end(); ++b) 444 | { 445 | pos = 0; 446 | trim(*b); 447 | ignorespacetab(*b,pos); 448 | if(pos != b->length()) 449 | { 450 | string varName = b->substr(pos,b->length()-pos); 451 | ClassModel model; 452 | model.fileName = fileModel.fileName; 453 | model.className = classname; 454 | model.identifyName = varName; 455 | model.identifyOriginName = varName; 456 | model.filePath = fileModel.filePath; 457 | 458 | if (handleCppIdentify(model)) 459 | { 460 | database->insertRecord(model); 461 | } 462 | } 463 | } 464 | for(b = i->function.begin(); b != i->function.end(); ++b) 465 | { 466 | pos = 0; 467 | trim(*b); 468 | ignorespacetab(*b,pos); 469 | if(pos != b->length()) 470 | { 471 | string functionName = b->substr(pos,b->length()-pos); 472 | ClassModel model; 473 | model.fileName = fileModel.fileName; 474 | model.className = classname; 475 | model.identifyName = functionName; 476 | model.identifyOriginName = functionName; 477 | model.filePath = fileModel.filePath; 478 | 479 | if (handleCppIdentify(model)) 480 | { 481 | database->insertRecord(model); 482 | } 483 | } 484 | } 485 | } 486 | } 487 | 488 | int CppParser::findGlobalClassDeclares(string& str) 489 | { 490 | CppParser tempC; 491 | tempC.classname = "GlobalClassDeclare"; 492 | vector vs = divideByTab(str);//根据制表符分解字符串 493 | size_t sem_index;//分号下标 494 | //根据分号来区分函数和变量 495 | for(vector::iterator it = vs.begin(); it!=vs.end();++it) 496 | { 497 | string it_str = trim(*it); 498 | sem_index = it_str.find_last_of(';'); 499 | if( sem_index != string::npos) 500 | { 501 | string cur_var = it_str.substr(0,sem_index); 502 | cur_var = trim(cur_var); 503 | size_t cls_index = cur_var.find("class "); 504 | 505 | size_t friend_index = cur_var.find("friend "); 506 | if (cls_index != string::npos && friend_index != string::npos) 507 | { 508 | cls_index = friend_index; 509 | } 510 | 511 | if (cur_var.length() > 2 && cls_index != string::npos) 512 | { 513 | string class_declare_str = cur_var + ";"; 514 | size_t index = str.find(class_declare_str); 515 | 516 | tempC.var.push_back(cur_var); 517 | 518 | if (index != string::npos) 519 | { 520 | str.replace(index, sem_index-cls_index+1, ""); 521 | } 522 | } 523 | } 524 | } 525 | 526 | _classes.push_back(tempC); 527 | 528 | if(tempC.var.size() > 0 || tempC.function.size() > 0) 529 | { 530 | return HAVEFOUND; 531 | } 532 | else 533 | { 534 | return NOTFOUND; 535 | } 536 | } 537 | 538 | int CppParser::findGlobalVarsAndFunctions(string& str) 539 | { 540 | CppParser tempC; 541 | tempC.classname = "GlobalVarsAndFunctions"; 542 | size_t lBlock = str.find('{',0) ;// 找{ 543 | size_t cur_index = lBlock; 544 | vector vi = actionscope(str,cur_index);//获取函数和数组变量初始化等 { 和 } 的位置 545 | string temp = ""; 546 | //排除所有作用域内的字符串 547 | for(vector::iterator vit = vi.begin(); vit != vi.end(); vit += 2) 548 | { 549 | size_t start_index = *vit+1; 550 | size_t substr_index = *(vit+1)-*(vit)-1; 551 | 552 | if (start_index > str.length() || start_index+substr_index > str.length()) 553 | { 554 | break; 555 | } 556 | 557 | temp += str.substr(start_index, substr_index); 558 | } 559 | vector vs = divideByTab(temp);//根据制表符分解字符串 560 | size_t sem_index;//分号下标 561 | //根据分号来区分函数和变量 562 | for(vector::iterator b = vs.begin(); b!=vs.end();++b) 563 | { 564 | sem_index = b->find_last_of(';'); 565 | if( sem_index != string::npos) 566 | { 567 | string cur_var = b->substr(0,sem_index); 568 | cur_var = trim(cur_var); 569 | if (cur_var.length() > 2) 570 | { 571 | tempC.var.push_back(cur_var); 572 | } 573 | } 574 | else 575 | { 576 | string cur_function_str = trim(*b); 577 | if (cur_function_str.length() > 2) 578 | { 579 | tempC.function.push_back(cur_function_str); 580 | } 581 | } 582 | } 583 | 584 | _classes.push_back(tempC); 585 | 586 | if(tempC.var.size() > 0 || tempC.function.size() > 0) 587 | { 588 | return HAVEFOUND; 589 | } 590 | else 591 | { 592 | return NOTFOUND; 593 | } 594 | } 595 | 596 | /** 597 | fI , nI - fI 取得是fI 到 nI-1下标的子串 598 | */ 599 | int CppParser::findSubStrAtPos(string& str,string s,size_t& pos) 600 | { 601 | size_t type = judge(s); 602 | size_t fI,nI;//firstIndex,nextIndex 603 | string temp = ""; 604 | switch(type) 605 | { 606 | case INCLUDE: 607 | { 608 | fI = str.find(s,pos);//先找到include的位置 609 | if(fI != string::npos) 610 | { 611 | //判断include是否在class里面的注释里 612 | size_t cI = str.find("class ",pos); 613 | if(cI != string::npos && cI en = findExtendsName(classline,begin);//extendsname 649 | 650 | string classname = cn; 651 | if (trim(classname).length() <= 0) 652 | { 653 | return NOTFOUND; 654 | } 655 | 656 | theclass.classname = cn; 657 | theclass.extends = en; 658 | 659 | size_t cur_index = lBlock;//current_index 660 | vector vi = actionscope(str,cur_index);//获取函数和数组变量初始化等 { 和 } 的位置 661 | string temp = ""; 662 | //排除所有作用域内的字符串 663 | for(vector::iterator vit = vi.begin(); vit != vi.end(); vit += 2) 664 | { 665 | size_t start_index = *vit+1; 666 | size_t substr_index = *(vit+1)-*(vit)-1; 667 | 668 | if (start_index > str.length() || start_index+substr_index > str.length()) 669 | { 670 | break; 671 | } 672 | 673 | temp += str.substr(start_index, substr_index); 674 | } 675 | vector vs = divideByTab(temp);//根据制表符分解字符串 676 | size_t sem_index;//分号下标 677 | //根据分号来区分函数和变量 678 | for(vector::iterator b = vs.begin(); b!=vs.end();++b) 679 | { 680 | sem_index = b->find_last_of(';'); 681 | if( sem_index != string::npos) 682 | { 683 | string cur_var = b->substr(0,sem_index); 684 | cur_var = trim(cur_var); 685 | if (cur_var.length() > 2) 686 | { 687 | theclass.var.push_back(cur_var); 688 | } 689 | } 690 | else 691 | { 692 | string cur_function_str = trim(*b); 693 | if (cur_function_str.length() > 2 ) 694 | { 695 | theclass.function.push_back(cur_function_str); 696 | } 697 | } 698 | } 699 | 700 | _classes.push_back(theclass); 701 | pos = fI + 1;//下一个搜索位置从fI开始,因为可能会出现类里面嵌套类的情况 702 | return HAVEFOUND; 703 | } 704 | } 705 | else 706 | { 707 | return NOTFOUND; 708 | } 709 | } 710 | break; 711 | case TEMPLATE_CLASS: 712 | { 713 | fI = str.find(s,pos);//找到"template" 714 | if(fI != string::npos) 715 | { 716 | fI += strlen("template"); 717 | CppParser theclass;//C类 718 | size_t lBlock = str.find('>',fI) ;// 找template<>的>结束符 719 | if(lBlock != string::npos) 720 | { 721 | ++lBlock; 722 | string classline = str.substr(fI,lBlock-fI);//获得类信息的第一行 723 | size_t begin = 0; 724 | const string cn = findClassName(classline,begin);//classname 725 | vector en = findExtendsName(classline,begin);//extendsname 726 | 727 | theclass.classname = cn; 728 | theclass.extends = en; 729 | 730 | size_t cur_index = lBlock;//current_index 731 | vector vi = actionscope(str,cur_index);//获取函数和数组变量初始化等 { 和 } 的位置 732 | string temp = ""; 733 | //排除所有作用域内的字符串 734 | for(vector::iterator vit = vi.begin(); vit != vi.end(); vit += 2) 735 | { 736 | size_t start_index = *vit+1; 737 | size_t substr_index = *(vit+1)-*(vit)-1; 738 | 739 | if (start_index > str.length() || start_index+substr_index > str.length()) 740 | { 741 | break; 742 | } 743 | 744 | temp += str.substr(start_index, substr_index); 745 | } 746 | vector vs = divideByTab(temp);//根据制表符分解字符串 747 | size_t sem_index;//分号下标 748 | //根据分号来区分函数和变量 749 | for(vector::iterator b = vs.begin(); b!=vs.end();++b) 750 | { 751 | sem_index = b->find_last_of(';'); 752 | if( sem_index != string::npos) 753 | { 754 | string cur_var = b->substr(0,sem_index); 755 | cur_var = trim(cur_var); 756 | if (cur_var.length() > 2) 757 | { 758 | theclass.var.push_back(cur_var); 759 | } 760 | } 761 | else 762 | { 763 | string cur_function_str = trim(*b); 764 | if (cur_function_str.length() > 2) 765 | { 766 | theclass.function.push_back(cur_function_str); 767 | } 768 | } 769 | } 770 | 771 | size_t template_class_begin = cn.find("<", pos); 772 | size_t template_class_end = cn.find(">", pos); 773 | if (template_class_begin!=string::npos || template_class_end!=string::npos) 774 | { 775 | //do nothing 776 | } 777 | else 778 | { 779 | _classes.push_back(theclass); 780 | } 781 | pos = fI + 1;//下一个搜索位置从fI开始,因为可能会出现类里面嵌套类的情况 782 | return HAVEFOUND; 783 | } 784 | } 785 | else 786 | { 787 | return NOTFOUND; 788 | } 789 | } 790 | break; 791 | case VARIABLE: 792 | break; 793 | case FUNCTION: 794 | break; 795 | case UNDEINED: 796 | break; 797 | }; 798 | return NOTFOUND; 799 | } 800 | 801 | bool CppParser::is_str_contain_space(string str) 802 | { 803 | return str.find(' ') != string::npos; 804 | } 805 | 806 | int CppParser::findFunctionAndVarsOfClass(string& str,string s,size_t& pos,CppParser& theclass) 807 | { 808 | size_t fI;//firstIndex 809 | string temp = ""; 810 | 811 | fI = str.find(s+"::",pos);//找到具体类 812 | size_t lBlock = str.find("{",fI) ;// 找{ 813 | if(fI != string::npos) 814 | { 815 | fI += strlen(s.c_str()); 816 | 817 | size_t cur_index = lBlock;//current_index 818 | vector vi = actionscope(str,cur_index);//获取函数和数组变量初始化等 { 和 } 的位置 819 | string temp = ""; 820 | //排除所有作用域内的字符串 821 | for(vector::iterator vit = vi.begin(); vit != vi.end(); vit += 2) 822 | { 823 | size_t start_index = *vit+1; 824 | size_t substr_index = *(vit+1)-*(vit)-1; 825 | 826 | if (start_index > str.length() || start_index+substr_index > str.length()) 827 | { 828 | break; 829 | } 830 | 831 | temp += str.substr(start_index, substr_index); 832 | } 833 | D(temp,'#');//删除 # 号 和 \n 号之间的信息,包括#号,不包括\n号 834 | vector vs = divideByTab(temp);//根据制表符分解字符串 835 | for(vector::iterator b = vs.begin(); b!=vs.end();++b) 836 | { 837 | string cur_function_str = trim(*b); 838 | if (cur_function_str.length() > 2 && cur_function_str.find(s+"::") != string::npos && is_str_contain_space(cur_function_str)) 839 | { 840 | theclass.function.push_back(cur_function_str); 841 | } 842 | } 843 | 844 | sort(theclass.function.begin(),theclass.function.end()); 845 | theclass.function.erase(unique(theclass.function.begin(), theclass.function.end()), theclass.function.end()); 846 | 847 | pos = fI + 1;//下一个搜索位置从fI开始,因为可能会出现类里面嵌套类的情况 848 | return HAVEFOUND; 849 | } 850 | else 851 | { 852 | return NOTFOUND; 853 | } 854 | } 855 | 856 | string CppParser::findClassName(const string& classline,size_t &begin) 857 | { 858 | string classname = classline; 859 | 860 | size_t space_start = classname.find(" ", 0);//找修饰符的位置 861 | while(space_start != string::npos) 862 | { 863 | classname = classname.replace(space_start, 2, ""); 864 | space_start = classname.find(" ", 0);//找修饰符的位置 865 | } 866 | 867 | size_t newline_start = classname.find("\r\n\t", 0);//找修饰符的位置 868 | while(newline_start != string::npos) 869 | { 870 | classname = classname.replace(newline_start, 3, ""); 871 | newline_start = classname.find("\r\n\t", 0);//找修饰符的位置 872 | } 873 | 874 | size_t decorate_start = classname.find("public", 0);//找修饰符的位置 875 | string result = classname; 876 | while (decorate_start != string::npos) 877 | { 878 | size_t nest_class_index = classname.find("public:class"); 879 | size_t block_index = classname.find("{"); 880 | if (nest_class_index != string::npos)//内部类 881 | { 882 | string nest_classname = classname.substr(nest_class_index+strlen("public:class"), block_index-nest_class_index-strlen("public:class")); 883 | nest_classname = trim(nest_classname); 884 | return nest_classname; 885 | } 886 | 887 | result = classname.replace(decorate_start, decorate_start+strlen("public"), ""); 888 | decorate_start = result.find("public", 0); 889 | } 890 | 891 | decorate_start = classname.find("protected", 0);//找修饰符的位置 892 | while (decorate_start != string::npos) 893 | { 894 | size_t nest_class_index = classname.find("protected:class"); 895 | size_t block_index = classname.find("{"); 896 | if (nest_class_index != string::npos)//内部类 897 | { 898 | string nest_classname = classname.substr(nest_class_index+strlen("protected:class"), block_index-nest_class_index-strlen("protected:class")); 899 | nest_classname = trim(nest_classname); 900 | return nest_classname; 901 | } 902 | 903 | result = classname.replace(decorate_start, decorate_start+strlen("protected"), ""); 904 | decorate_start = result.find("protected", 0); 905 | } 906 | 907 | size_t extends_colon_index = result.find(":"); 908 | size_t not_extends_colon_index = result.find("::"); 909 | string curr_classline = result.substr(0, extends_colon_index); 910 | curr_classline = trim(curr_classline); 911 | if (extends_colon_index != string::npos && not_extends_colon_index == string::npos) 912 | { 913 | size_t space_index = curr_classline.find_last_of(' '); 914 | string result_classname = curr_classline; 915 | if (space_index != string::npos) 916 | { 917 | curr_classline = curr_classline.substr(space_index, curr_classline.length()-space_index); 918 | result_classname = trim(curr_classline); 919 | } 920 | else 921 | { 922 | result_classname = curr_classline.substr(0, extends_colon_index); 923 | result_classname = trim(curr_classline); 924 | } 925 | 926 | return result_classname; 927 | } 928 | 929 | size_t space_index = curr_classline.find_last_of(' '); 930 | size_t block_index = curr_classline.find_last_of('{'); 931 | if (space_index != string::npos && block_index != string::npos) 932 | { 933 | string result_classname = curr_classline.substr(space_index, block_index-space_index); 934 | result_classname = trim(result_classname); 935 | return result_classname; 936 | } 937 | 938 | ignorespacetab(curr_classline,begin); 939 | size_t CNS = begin;//classname_start 940 | ignorealnum(curr_classline,begin); 941 | size_t CNE = begin;//classname_end 942 | 943 | curr_classline = curr_classline.substr(CNS,CNE-CNS); 944 | 945 | return curr_classline; 946 | } 947 | 948 | vector CppParser::split(std::string str,std::string pattern) 949 | { 950 | string::size_type pos; 951 | vector result; 952 | str+=pattern;//扩展字符串以方便操作 953 | size_t size=str.length(); 954 | 955 | for(size_t i=0; i CppParser::findExtendsName(const string& str,size_t pos) 969 | { 970 | vector extends_name; 971 | 972 | string curr_str = str; 973 | 974 | size_t extends_start = curr_str.find(":",pos);//extends_start 975 | size_t extends_end = curr_str.find("\r\n\t",pos);//extends_end 976 | if( extends_start != string::npos && extends_end != string::npos) 977 | { 978 | string result = curr_str.substr(extends_start+1, extends_end-extends_start-1); 979 | 980 | vector extends = split(result, ","); 981 | 982 | for (vector::iterator str_iter = extends.begin(); str_iter != extends.end(); str_iter++) 983 | { 984 | string curr_extend_str = *str_iter; 985 | size_t public_start = curr_extend_str.find("public", 0);//找修饰符的位置 986 | size_t protected_start = curr_extend_str.find("protected", 0);//找修饰符的位置 987 | size_t nest_class_index = curr_extend_str.find("class ", 0); 988 | if (public_start != string::npos && nest_class_index == string::npos) 989 | { 990 | curr_extend_str = curr_extend_str.replace(public_start, strlen("public"), ""); 991 | extends_name.push_back(trim(curr_extend_str)); 992 | } 993 | else if (protected_start != string::npos && nest_class_index == string::npos) 994 | { 995 | curr_extend_str = curr_extend_str.replace(protected_start, strlen("protected"), ""); 996 | extends_name.push_back(trim(curr_extend_str)); 997 | } 998 | } 999 | return extends_name; 1000 | } 1001 | return extends_name; 1002 | } 1003 | 1004 | //以下是判断作用域的位置,并返回合适的 { 和 } 位置来将变量名和函数名分割出来。 1005 | void CppParser::actionscope_ignore(const string& str,size_t& fI) 1006 | { 1007 | int lBlock_num = 1; 1008 | while(lBlock_num) 1009 | { 1010 | if(fI >= str.length()) 1011 | { 1012 | break; 1013 | } 1014 | ++fI; 1015 | if(str[fI] == '{') 1016 | { 1017 | ++lBlock_num; 1018 | } 1019 | else if(str[fI] == '}') 1020 | { 1021 | --lBlock_num; 1022 | } 1023 | } 1024 | } 1025 | 1026 | 1027 | vector CppParser::actionscope(const string& str,size_t& fI) 1028 | { 1029 | vector index; 1030 | index.push_back(fI-1); 1031 | int lBlock_num = 1; 1032 | while(lBlock_num) 1033 | { 1034 | if(fI >= str.length()) 1035 | { 1036 | break; 1037 | } 1038 | if(str[fI] == '{') 1039 | { 1040 | index.push_back(fI);//获取'{'的下标 1041 | actionscope_ignore(str,fI); 1042 | index.push_back(fI);//获得匹配上面的'{'的'}'的下标 1043 | } 1044 | else if(str[fI] == '}') 1045 | { 1046 | lBlock_num = 0; 1047 | index.push_back(fI); 1048 | continue; 1049 | } 1050 | ++fI; 1051 | } 1052 | return index; 1053 | } 1054 | 1055 | bool CppParser::handleCppIdentify(ClassModel &classModel) 1056 | { 1057 | StringUtil stringUtil; 1058 | 1059 | string identify_str = classModel.identifyName; 1060 | 1061 | string lowercase_idt_str = identify_str; 1062 | stringUtil.Tolower(lowercase_idt_str); 1063 | //过滤宏定义,复制,还有带分号的语句 1064 | if(lowercase_idt_str.find("#define") != string::npos || 1065 | lowercase_idt_str.find("=") != string::npos || 1066 | lowercase_idt_str.find(";") != string::npos || 1067 | lowercase_idt_str.find("),") != string::npos || 1068 | lowercase_idt_str.find("export ") != string::npos || 1069 | lowercase_idt_str.find("extern ") != string::npos) 1070 | { 1071 | return false; 1072 | } 1073 | 1074 | identify_str = trim(identify_str); 1075 | 1076 | size_t class_colonIndex = identify_str.find("::"); 1077 | 1078 | if (class_colonIndex != string::npos)// Cpp Function 1079 | { 1080 | size_t first_brackets_index = identify_str.find_first_of('('); 1081 | if (first_brackets_index != string::npos) 1082 | { 1083 | identify_str = identify_str.substr(class_colonIndex+2, first_brackets_index-class_colonIndex-2); 1084 | } 1085 | 1086 | stringUtil.deleteSpecialChar(identify_str); 1087 | 1088 | if (stringUtil.is_allow_identify_name_c_cpp(identify_str)) 1089 | { 1090 | string method_str = trim(identify_str); 1091 | if (stringUtil.is_allow_identify_name(classModel.className)) 1092 | { 1093 | classModel.identifyName = method_str; 1094 | 1095 | return true; 1096 | } 1097 | } 1098 | } 1099 | else 1100 | { 1101 | size_t first_brackets_index = identify_str.find_first_of('('); 1102 | if (first_brackets_index != string::npos) 1103 | { 1104 | identify_str = identify_str.substr(0, first_brackets_index); 1105 | } 1106 | 1107 | size_t last_space_index = identify_str.find_last_of(' '); 1108 | if (last_space_index != string::npos) 1109 | { 1110 | identify_str = identify_str.substr(last_space_index+1, identify_str.length()-last_space_index-1); 1111 | } 1112 | 1113 | stringUtil.deleteSpecialChar(identify_str); 1114 | if (stringUtil.is_allow_identify_name_c_cpp(identify_str)) 1115 | { 1116 | string method_str = trim(identify_str); 1117 | if (stringUtil.is_allow_identify_name(classModel.className)) 1118 | { 1119 | classModel.identifyName = method_str; 1120 | 1121 | return true; 1122 | } 1123 | } 1124 | } 1125 | 1126 | return false; 1127 | } 1128 | 1129 | -------------------------------------------------------------------------------- /CodeConfusing/cppparser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "srcfilemodel.h" 12 | #include "stringutil.h" 13 | #include "classmodel.h" 14 | 15 | using namespace std; 16 | 17 | #define INCLUDE 10 18 | #define CLASS 20 19 | #define TEMPLATE_CLASS 30 20 | #define VARIABLE 40 21 | #define FUNCTION 50 22 | #define UNDEINED 65535 23 | #define NOTFOUND 0 24 | #define HAVEFOUND 1 25 | 26 | /** 27 | * 目前出现的问题: 28 | * 1. 不用制表符首行推进,而是用空格。函数没有识别到。 29 | */ 30 | 31 | class CppParser 32 | { 33 | public: 34 | string classname;//类的名字 35 | vector extends;//类的extends 36 | vector var;//类的变量 37 | vector properties;//类的属性 38 | vector function;//类的函数 39 | 40 | vector include;//include集合 41 | vector _classes;//类的结合 42 | 43 | CppParser(); 44 | 45 | int parseCppFile(SrcFileModel srcFile); 46 | 47 | private: 48 | inline string& rtrim(string &str); 49 | inline string& ltrim(string &str); 50 | string& trim(string &s); //去除空格和换行 51 | size_t judge(string s);//判断字符串名字返回不同的值 52 | void D(string& str,char c);//在字符串str中循环删除字符c 53 | void D(string& str,string s);//删除所有指定的字符串 54 | void R(string& str);//以\r为判断删除注释 55 | vector divideByTab(string &str);//以制表符为分隔符分解字符串成vector 56 | void ignorespacetab(const string& str,size_t& fI);//fI停在非空格和制表符处 57 | void ignorealnum(const string&str ,size_t& fI);//fI停在非数字和字母处 58 | void display(SrcFileModel fileModel);//用文件输出流输出 59 | int findSubStrAtPos(string& str,string s,size_t& pos);//在pos处,str找s 60 | string findClassName(const string& str,size_t &begin);//在一个字符串上找类名 61 | vector findExtendsName(const string& str,size_t pos);//在一个字符串上找扩展名 62 | int findFunctionAndVarsOfClass(string& str,string s,size_t& pos,CppParser& theclass); 63 | 64 | int findGlobalClassDeclares(string& str);//寻找全局类声明,和友元类; 65 | 66 | int findGlobalVarsAndFunctions(string& str);//寻找全局变量和全局函数 67 | void actionscope_ignore(const string& str,size_t& fI);//忽略一个大的作用域中的所有作用域 68 | vector actionscope(const string& str,size_t& fI);//获取最大的作用域的位置 69 | vector split(std::string str,std::string pattern); 70 | 71 | bool is_str_contain_space(string str);//是否包含空格 72 | 73 | bool handleCppIdentify(ClassModel &classModel); 74 | }; 75 | -------------------------------------------------------------------------------- /CodeConfusing/database.cpp: -------------------------------------------------------------------------------- 1 | #include "database.h" 2 | #include "stringutil.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | DataBase::DataBase() 10 | { 11 | } 12 | 13 | DataBase::~DataBase() 14 | { 15 | } 16 | 17 | void DataBase::clearIdentifyVec() 18 | { 19 | vector().swap(m_identifyVec); 20 | } 21 | 22 | bool DataBase::insertRecord(ClassModel classModel) 23 | { 24 | StringUtil su; 25 | m_modelVec.push_back(classModel); 26 | m_identifyVec.push_back(classModel.identifyName); 27 | 28 | //类名 29 | if (classModel.isObjectiveC) 30 | { 31 | if (su.is_allow_identify_name(classModel.className)) 32 | { 33 | m_identifyVec.push_back(su.trim(classModel.className)); 34 | } 35 | } 36 | else 37 | { 38 | m_identifyVec.push_back(su.trim(classModel.className)); 39 | } 40 | 41 | return true; 42 | } 43 | 44 | //查询所有信息 45 | vector DataBase::queryAll() 46 | { 47 | sort(m_identifyVec.begin(),m_identifyVec.end()); 48 | m_identifyVec.erase(unique(m_identifyVec.begin(), m_identifyVec.end()), m_identifyVec.end()); 49 | return m_identifyVec; 50 | } 51 | 52 | vector DataBase::queryAllModel() 53 | { 54 | return m_modelVec; 55 | } 56 | 57 | //删除所有记录 58 | bool DataBase::deleteAll() 59 | { 60 | return true; 61 | } 62 | -------------------------------------------------------------------------------- /CodeConfusing/database.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "classmodel.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | #define DECLARE_SINGLETON(Class) \ 17 | Q_DISABLE_COPY(Class) \ 18 | public: \ 19 | static Class* Instance() \ 20 | { \ 21 | static QMutex mutex; \ 22 | static QScopedPointer inst; \ 23 | if (Q_UNLIKELY(!inst)) { \ 24 | mutex.lock(); \ 25 | if (!inst) inst.reset(new Class); \ 26 | mutex.unlock(); \ 27 | } \ 28 | return inst.data(); \ 29 | } 30 | 31 | class DataBase 32 | { 33 | DECLARE_SINGLETON(DataBase) 34 | private: 35 | vector sqlcmds; 36 | vector m_identifyVec; 37 | vector m_modelVec; 38 | public: 39 | DataBase(); 40 | ~DataBase(); 41 | 42 | void clearIdentifyVec(); 43 | 44 | bool insertRecord(ClassModel classModel); //新增数据 45 | vector queryAll(); //查询所有信息 46 | 47 | vector queryAllModel(); 48 | bool deleteAll(); //删除所有信息 49 | }; 50 | -------------------------------------------------------------------------------- /CodeConfusing/fileviewer.cpp: -------------------------------------------------------------------------------- 1 | #include "fileviewer.h" 2 | 3 | #include 4 | 5 | FileViewer::FileViewer(QString dir, QString file_path, 6 | QString dir_path, QWidget *parent) 7 | : QDialog(parent) 8 | { 9 | this->dir = new QDir(dir); 10 | this->file_out = new QFile(file_path); 11 | this->dir_out = new QFile(dir_path); 12 | 13 | this->current_file = new QLabel(""); 14 | this->file_name = new QLabel(""); 15 | 16 | this->file_name->setFont(QFont("Ubuntu", 25)); 17 | 18 | this->add = new QPushButton("Add"); 19 | this->skip = new QPushButton("Skip"); 20 | this->look_inside = new QPushButton("Look inside"); 21 | 22 | connect(add, SIGNAL(clicked(bool)), SLOT(add_clicked())); 23 | connect(skip, SIGNAL(clicked(bool)), SLOT(skip_clicked())); 24 | connect(look_inside, SIGNAL(clicked(bool)), SLOT(look_inside_clicked())); 25 | 26 | add->setEnabled(false); 27 | skip->setEnabled(false); 28 | look_inside->setEnabled(false); 29 | 30 | set_up_layouts(dir); 31 | 32 | file_out->open(QIODevice::WriteOnly | QIODevice::Append); 33 | dir_out->open(QIODevice::WriteOnly | QIODevice::Append); 34 | 35 | setWindowTitle("Chooser"); 36 | setWindowFlags(Qt::Window); 37 | setGeometry(400,400,500,400); 38 | } 39 | 40 | void FileViewer::set_up_layouts(QString dir) 41 | { 42 | QHBoxLayout *a = new QHBoxLayout(); 43 | a->addWidget(new QLabel("Directory:")); 44 | a->addWidget(new QLabel(dir)); 45 | 46 | QHBoxLayout *b = new QHBoxLayout(); 47 | b->addWidget(new QLabel("Current file:")); 48 | b->addWidget(current_file); 49 | 50 | QVBoxLayout *header = new QVBoxLayout(); 51 | header->addLayout(a); 52 | header->addLayout(b); 53 | 54 | QHBoxLayout *buttons = new QHBoxLayout(); 55 | buttons->addWidget(look_inside); 56 | buttons->addWidget(add); 57 | buttons->addWidget(skip); 58 | 59 | QVBoxLayout *all = new QVBoxLayout(); 60 | all->addLayout(header); 61 | all->addStretch(1); 62 | all->addWidget(file_name, 0, Qt::AlignCenter); 63 | all->addStretch(1); 64 | all->addLayout(buttons); 65 | 66 | setLayout(all); 67 | } 68 | 69 | void FileViewer::start() 70 | { 71 | dir->setSorting(QDir::DirsLast); 72 | // dir->setFilter(QDir::NoDotAndDotDot); 73 | this->list = dir->entryInfoList(); 74 | index = -1; // it really matters and needed 75 | 76 | next(); 77 | 78 | this->add->setEnabled(true); 79 | this->skip->setEnabled(true); 80 | this->look_inside->setEnabled(true); 81 | } 82 | 83 | void FileViewer::next() 84 | { 85 | index++; 86 | if( index < list.size() ) 87 | { 88 | current_file->setText( list[index].absoluteFilePath() ); 89 | file_name->setText( list[index].fileName() ); 90 | } 91 | else 92 | { 93 | this->close(); 94 | } 95 | } 96 | 97 | void FileViewer::add_clicked() 98 | { 99 | QByteArray array; 100 | QString string = list[index].fileName() + " #" 101 | + list[index].absoluteFilePath() + "\n"; 102 | array.append(string); 103 | 104 | if( list[index].isFile() ) 105 | { 106 | file_out->write( array ); 107 | } 108 | else if( list[index].isDir() ) 109 | { 110 | dir_out->write(array); 111 | } 112 | 113 | next(); 114 | } 115 | 116 | 117 | void FileViewer::skip_clicked() 118 | { 119 | next(); 120 | } 121 | 122 | void FileViewer::look_inside_clicked() 123 | { 124 | emit new_path( list[index].absoluteFilePath() ); 125 | next(); 126 | } 127 | 128 | FileViewer::~FileViewer() 129 | { 130 | if( file_out->isOpen() ){ 131 | file_out->flush(); 132 | file_out->close(); 133 | } 134 | if( dir_out->isOpen() ){ 135 | dir_out->flush(); 136 | dir_out->close(); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /CodeConfusing/fileviewer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class FileViewer : public QDialog 13 | { 14 | Q_OBJECT 15 | private: 16 | QLabel *file_name; 17 | QLabel *current_file; 18 | 19 | QPushButton *add; 20 | QPushButton *skip; 21 | QPushButton *look_inside; 22 | 23 | QFile *file_out; 24 | QFile *dir_out; 25 | QDir *dir; 26 | 27 | QFileInfoList list; 28 | int index; 29 | 30 | void set_up_layouts(QString dir); 31 | 32 | public: 33 | FileViewer(QString dir = "", QString file_path = "", QString dir_path = "", QWidget *parent = nullptr); 34 | 35 | void start(); 36 | void next(); 37 | 38 | ~FileViewer(); 39 | 40 | signals: 41 | void new_path(QString path); 42 | 43 | private slots: 44 | void add_clicked(); 45 | void skip_clicked(); 46 | void look_inside_clicked(); 47 | 48 | }; 49 | -------------------------------------------------------------------------------- /CodeConfusing/garbagecode.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // garbagecode.cpp 3 | // CodeConfusing 4 | // 5 | // Created by Apple on 2017/12/4. 6 | // 7 | // 8 | 9 | #include "garbagecode.h" 10 | #include "stringutil.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | void GarbageCodeTool::modifyContentInFile(const char *fileName, string content) 19 | { 20 | StringUtil su; 21 | 22 | string line; 23 | string preline = ""; 24 | 25 | ifstream fin(fileName); 26 | 27 | string tempStr = ""; 28 | while(getline(fin,line,'\n')) 29 | { 30 | preline = su.trim(preline); 31 | if(preline.length() > 0 && 32 | line.length() > 0 && 33 | su.EndWith(preline, ")") && 34 | su.StartWith(line, "{")) 35 | { 36 | string subline = line.substr(1,line.length()-1); 37 | tempStr += + "{\n\t" + content+"\n" + subline + "\n"; 38 | } 39 | else 40 | { 41 | tempStr += line+"\n"; 42 | } 43 | 44 | preline = line; 45 | } 46 | fin.close(); 47 | 48 | ofstream fout(fileName, ofstream::out); 49 | fout< 0 && 73 | su.StartWith(line, "#include") && 74 | isHeadInjected == false) 75 | { 76 | string subline = line.substr(0,line.length()); 77 | qDebug() << "subline:" << subline.c_str()<< endl; 78 | tempStr += + "\n" + includeCode+"\n"+subline+"\n"; 79 | 80 | isHeadInjected = true; 81 | } 82 | else 83 | { 84 | tempStr += line+"\n"; 85 | } 86 | } 87 | fin.close(); 88 | 89 | ofstream fout(fileName, ofstream::out); 90 | fout << tempStr; 91 | fout.close(); 92 | } 93 | -------------------------------------------------------------------------------- /CodeConfusing/garbagecode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "srcfilemodel.h" 4 | 5 | class GarbageCodeTool 6 | { 7 | public: 8 | void insertGarbageCode(SrcFileModel srcFile, string garbageCode); 9 | void insertIncludeCode(SrcFileModel srcFile, string includeCode); 10 | void modifyContentInFile(const char *fileName,string content); 11 | }; 12 | -------------------------------------------------------------------------------- /CodeConfusing/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "database.h" 3 | 4 | #include 5 | #include 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | QApplication app(argc, argv); 10 | 11 | QString file_storage_default_name = "cached_files.dat"; 12 | QString dir_storage_default_name = "cached_dirs.dat"; 13 | 14 | if( argc == 3 ) 15 | { 16 | // setting the custom names of storage files 17 | file_storage_default_name = QString( argv[1] ); 18 | dir_storage_default_name = QString( argv[2] ); 19 | } 20 | 21 | MainWindow mainWin(file_storage_default_name,dir_storage_default_name); 22 | mainWin.setMinimumSize(800, 500); 23 | mainWin.show(); 24 | 25 | return app.exec(); 26 | } 27 | -------------------------------------------------------------------------------- /CodeConfusing/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | #include "stringutil.h" 4 | #include "cppparser.h" 5 | #include "ocparser.h" 6 | #include "database.h" 7 | #include "resultdialog.h" 8 | #include "garbagecode.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define random(a,b) (rand()%(b-a+1)+a) 26 | 27 | void MainWindow::readFileList(const char *basePath) 28 | { 29 | QDir dir(basePath); 30 | 31 | if (!dir.exists()) 32 | { 33 | return; 34 | } 35 | 36 | dir.setFilter(QDir::Files | QDir::NoSymLinks); 37 | QFileInfoList list = dir.entryInfoList(); 38 | 39 | int file_count = list.count(); 40 | if(file_count <= 0) 41 | { 42 | return; 43 | } 44 | 45 | QStringList string_list; 46 | 47 | //获取所选文件类型过滤器 48 | QStringList filters; 49 | filters << QString("*.*"); 50 | 51 | //定义迭代器并设置过滤器 52 | QDirIterator dirIter(basePath, 53 | filters, 54 | QDir::Files | QDir::NoSymLinks, 55 | QDirIterator::Subdirectories); 56 | 57 | while(dirIter.hasNext()) 58 | { 59 | dirIter.next(); 60 | QFileInfo fileInfo = dirIter.fileInfo(); 61 | QString absFilePath = fileInfo.absoluteFilePath(); 62 | 63 | SrcFileModel fileModel; 64 | fileModel.fileName = fileInfo.fileName().toStdString(); 65 | fileModel.filePath = absFilePath.toStdString(); 66 | fileModel.isParsed = false; 67 | fileList.push_back(fileModel); 68 | } 69 | } 70 | 71 | MainWindow::MainWindow(QString file_storage, QString dir_storage, QWidget *parent) 72 | : QMainWindow(parent) 73 | { 74 | this->file_storage = file_storage; 75 | this->dir_storage = dir_storage; 76 | 77 | list = new QListWidget(); 78 | 79 | choose = new QPushButton("请选择项目文件夹"); 80 | start = new QPushButton("开始混淆"); 81 | edit_line = new QLineEdit(); 82 | edit_ignore_folders = new QLineEdit(); 83 | lbl_ignore_folders = new QLabel("请输入要忽略的文件夹名字,以空格分割:"); 84 | cb_isconfuse_objc = new QCheckBox("是否混淆Objective C代码", this); 85 | cb_isconfuse_cpp = new QCheckBox("是否混淆C/C++代码", this); 86 | cb_isinject_garbagecode_cpp = new QCheckBox("是否在C/C++函数中注入自定义代码", this); 87 | 88 | //set default flags 89 | is_confuse_objc = true; 90 | is_confuse_cpp = true; 91 | is_inject_garbagecode_cpp = true; 92 | 93 | cb_isconfuse_objc->setCheckState(Qt::Checked); 94 | cb_isconfuse_cpp->setCheckState(Qt::Checked); 95 | cb_isinject_garbagecode_cpp->setCheckState(Qt::Checked); 96 | 97 | list->setSelectionMode(QAbstractItemView::ExtendedSelection); 98 | 99 | lbl_ignore_folders->setAlignment(Qt::AlignLeft); 100 | lbl_ignore_folders->adjustSize(); 101 | 102 | edit_line->setMinimumWidth(300); 103 | choose->setMinimumWidth(140); 104 | 105 | connect(choose, SIGNAL(clicked(bool)), SLOT(choose_path())); 106 | connect(start, SIGNAL(clicked(bool)), SLOT(start_choosing())); 107 | connect(cb_isconfuse_objc, SIGNAL(stateChanged(int)), this, SLOT(onConfuseObjCStateChanged(int))); 108 | connect(cb_isconfuse_cpp, SIGNAL(stateChanged(int)), this, SLOT(onConfuseCppStateChanged(int))); 109 | connect(cb_isinject_garbagecode_cpp, SIGNAL(stateChanged(int)), this, SLOT(onInjectCodeStateChanged(int))); 110 | 111 | QHBoxLayout *inputLayout = new QHBoxLayout(); 112 | inputLayout->addWidget(edit_line); 113 | inputLayout->addWidget(choose); 114 | 115 | QVBoxLayout *checksLayout = new QVBoxLayout(); 116 | 117 | QHBoxLayout *ignoreFolderLayout = new QHBoxLayout(); 118 | ignoreFolderLayout->addWidget(lbl_ignore_folders); 119 | ignoreFolderLayout->addWidget(edit_ignore_folders); 120 | ignoreFolderLayout->setStretchFactor(lbl_ignore_folders, 1); 121 | ignoreFolderLayout->setStretchFactor(edit_ignore_folders, 2); 122 | 123 | checksLayout->addLayout(ignoreFolderLayout); 124 | checksLayout->addWidget(cb_isconfuse_objc); 125 | checksLayout->addWidget(cb_isconfuse_cpp); 126 | checksLayout->addWidget(cb_isinject_garbagecode_cpp); 127 | 128 | QVBoxLayout *mainLayout = new QVBoxLayout(); 129 | mainLayout->addLayout(inputLayout); 130 | mainLayout->addLayout(checksLayout); 131 | mainLayout->addWidget(list); 132 | mainLayout->addWidget(start); 133 | 134 | QWidget *mainWidget = new QWidget; 135 | mainWidget->setLayout(mainLayout); 136 | 137 | setCentralWidget(mainWidget); 138 | 139 | setWindowTitle("项目代码混淆&注入工具"); 140 | setWindowFlags(Qt::Window); 141 | } 142 | 143 | void MainWindow::choose_path() 144 | { 145 | QString path = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), "."); 146 | edit_line->setText(path); 147 | } 148 | 149 | void MainWindow::add_next_path(QString path) 150 | { 151 | list->insertItem(0, path); 152 | } 153 | 154 | bool MainWindow::is_identify_class(string identify_str) 155 | { 156 | DataBase *database = DataBase::Instance(); 157 | 158 | vector modelVec = database->queryAllModel(); 159 | 160 | StringUtil stringUtil; 161 | for (vector::iterator it=modelVec.begin(); it != modelVec.end(); ++it) 162 | { 163 | ClassModel model = *it; 164 | if (stringUtil.StartWith(model.className, identify_str) && model.className.length() == identify_str.length()) 165 | { 166 | return true; 167 | } 168 | } 169 | 170 | return false; 171 | } 172 | 173 | 174 | bool MainWindow::is_identify_property(string identify_str) 175 | { 176 | DataBase *database = DataBase::Instance(); 177 | 178 | vector modelVec = database->queryAllModel(); 179 | 180 | StringUtil stringUtil; 181 | for (vector::iterator it=modelVec.begin(); it != modelVec.end(); ++it) 182 | { 183 | ClassModel model = *it; 184 | if (stringUtil.StartWith(model.identifyName, identify_str) && model.identifyName.length() == identify_str.length() && model.isPropertyName && model.identifyName.find("readonly") == string::npos) 185 | { 186 | return true; 187 | } 188 | } 189 | 190 | return false; 191 | } 192 | 193 | void MainWindow::onConfuseObjCStateChanged(int state) 194 | { 195 | if (state == Qt::Checked) // "选中" 196 | { 197 | is_confuse_objc = true; 198 | } 199 | else if(state == Qt::PartiallyChecked) // "半选" 200 | { 201 | } 202 | else // 未选中 - Qt::Unchecked 203 | { 204 | is_confuse_objc = false; 205 | } 206 | } 207 | 208 | void MainWindow::onConfuseCppStateChanged(int state) 209 | { 210 | if (state == Qt::Checked) // "选中" 211 | { 212 | is_confuse_cpp = true; 213 | } 214 | else if(state == Qt::PartiallyChecked) // "半选" 215 | { 216 | } 217 | else // 未选中 - Qt::Unchecked 218 | { 219 | is_confuse_cpp = false; 220 | } 221 | } 222 | 223 | void MainWindow::onInjectCodeStateChanged(int state) 224 | { 225 | if (state == Qt::Checked) // "选中" 226 | { 227 | is_inject_garbagecode_cpp = true; 228 | } 229 | else if(state == Qt::PartiallyChecked) // "半选" 230 | { 231 | } 232 | else // 未选中 - Qt::Unchecked 233 | { 234 | is_inject_garbagecode_cpp = false; 235 | } 236 | } 237 | 238 | void MainWindow::inject_garbagecode() 239 | { 240 | StringUtil stringUtil; 241 | 242 | QString codePiecePath = QString(":/resources/codepiece.json"); 243 | QFile codePieceJsonFile(codePiecePath); 244 | if(!codePieceJsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) 245 | { 246 | QMessageBox::critical(nullptr, "critical", "读取自定义代码文件出错!", QMessageBox::Yes, QMessageBox::Yes); 247 | } 248 | 249 | QString val = codePieceJsonFile.readAll(); 250 | codePieceJsonFile.close(); 251 | 252 | vector garbageCodeArr; 253 | QJsonDocument doc = QJsonDocument::fromJson(val.toUtf8()); 254 | QJsonObject jsonObj = doc.object(); 255 | 256 | QStringList keyList = jsonObj.keys(); 257 | 258 | for(int i=0; itext(); 265 | QStringList ignore_folders_list = ignore_folders.split(" "); 266 | 267 | QApplication::setOverrideCursor(Qt::WaitCursor); 268 | 269 | StringUtil su; 270 | GarbageCodeTool gct; 271 | for(size_t i=0; i 0) 283 | { 284 | bool bPathContainsIgnoreFolder = false; 285 | for (int k=0; kaddItem(cppFilePathString); 307 | 308 | for(size_t index=0; indexaddItem(parseInfoString); 331 | 332 | for(size_t index=0; indexupdate(); 352 | list->repaint(); 353 | list->scrollToBottom(); 354 | QCoreApplication::processEvents(); 355 | } 356 | 357 | QApplication::restoreOverrideCursor(); 358 | } 359 | 360 | void MainWindow::generate_confuse_code() 361 | { 362 | StringUtil stringUtil; 363 | 364 | QString ignore_folders = edit_ignore_folders->text(); 365 | QStringList ignore_folders_list = ignore_folders.split(" "); 366 | 367 | QApplication::setOverrideCursor(Qt::WaitCursor); 368 | for(size_t i=0; i 0) 380 | { 381 | bool bPathContainsIgnoreFolder = false; 382 | for (int k=0; k 0) 404 | { 405 | QString headFileString = QString("正在分析:"); 406 | headFileString = headFileString.append(file.headerFilePath.c_str()); 407 | list->addItem(headFileString); 408 | 409 | QString cppFilePathString = QString("正在分析:"); 410 | cppFilePathString = cppFilePathString.append(file.cppFilePath.c_str()); 411 | list->addItem(cppFilePathString); 412 | 413 | CppParser cppParser; 414 | cppParser.parseCppFile(file); 415 | } 416 | 417 | if(is_confuse_objc && file.mmFilePath.length() > 0) 418 | { 419 | QString headFileString = QString("正在分析:"); 420 | headFileString = headFileString.append(file.headerFilePath.c_str()); 421 | list->addItem(headFileString); 422 | 423 | QString mFilePathString = QString("正在分析:"); 424 | mFilePathString = mFilePathString.append(file.mmFilePath.c_str()); 425 | list->addItem(mFilePathString); 426 | 427 | OCParser ocParser; 428 | ocParser.parseOCFile(file); 429 | 430 | CppParser cppParser; 431 | cppParser.parseCppFile(file); 432 | 433 | SrcFileModel xibfile; 434 | xibfile.fileName = file.mmFileName; 435 | xibfile.filePath = file.mmFilePath; 436 | 437 | xibAndsb.push_back(xibfile); 438 | } 439 | 440 | if(is_confuse_objc && file.mFilePath.length() > 0) 441 | { 442 | QString headFileString = QString("正在分析:"); 443 | headFileString = headFileString.append(file.headerFilePath.c_str()); 444 | list->addItem(headFileString); 445 | 446 | QString mFilePathString = QString("正在分析:"); 447 | mFilePathString = mFilePathString.append(file.mFilePath.c_str()); 448 | list->addItem(mFilePathString); 449 | 450 | OCParser ocParser; 451 | ocParser.parseOCFile(file); 452 | 453 | SrcFileModel xibfile; 454 | xibfile.fileName = file.mFileName; 455 | xibfile.filePath = file.mFilePath; 456 | 457 | xibAndsb.push_back(xibfile); 458 | } 459 | } 460 | else if(is_confuse_cpp && (stringUtil.EndWith(file.fileName, ".cpp") || stringUtil.EndWith(file.fileName, ".cxx") || stringUtil.EndWith(file.fileName, ".cc"))) 461 | { 462 | file.cppFileName = file.fileName; 463 | file.cppFilePath = file.filePath; 464 | 465 | if(findHeaderFileWithFileModel(file)) 466 | { 467 | QString headerFilePathString = QString("正在分析:"); 468 | headerFilePathString = headerFilePathString.append(file.headerFilePath.c_str()); 469 | list->addItem(headerFilePathString); 470 | } 471 | QString cppFilePathString = QString("正在分析:"); 472 | cppFilePathString = cppFilePathString.append(file.cppFilePath.c_str()); 473 | list->addItem(cppFilePathString); 474 | 475 | CppParser cppParser; 476 | cppParser.parseCppFile(file); 477 | } 478 | else if(is_confuse_cpp && stringUtil.EndWith(file.fileName, ".c")) 479 | { 480 | findHeaderFileWithFileModel(file); 481 | 482 | file.cFileName = file.fileName; 483 | file.cFilePath = file.filePath; 484 | 485 | QString parseInfoString = QString("正在分析:"); 486 | parseInfoString = parseInfoString.append(file.filePath.c_str()); 487 | list->addItem(parseInfoString); 488 | 489 | CppParser cppParser; 490 | cppParser.parseCppFile(file); 491 | } 492 | else if(is_confuse_objc && stringUtil.EndWith(file.fileName, ".m")) 493 | { 494 | file.mFileName = file.fileName; 495 | file.mFilePath = file.filePath; 496 | 497 | if(findHeaderFileWithFileModel(file)) 498 | { 499 | QString headerFilePathString = QString("正在分析:"); 500 | headerFilePathString = headerFilePathString.append(file.headerFilePath.c_str()); 501 | list->addItem(headerFilePathString); 502 | } 503 | 504 | QString parseInfoString = QString("正在分析:"); 505 | parseInfoString = parseInfoString.append(file.filePath.c_str()); 506 | list->addItem(parseInfoString); 507 | 508 | OCParser ocParser; 509 | ocParser.parseOCFile(file); 510 | 511 | 512 | SrcFileModel xibfile; 513 | xibfile.fileName = file.fileName; 514 | xibfile.filePath = file.filePath; 515 | 516 | xibAndsb.push_back(xibfile); 517 | } 518 | else if(is_confuse_objc && stringUtil.EndWith(file.fileName, ".mm")) 519 | { 520 | findHeaderFileWithFileModel(file); 521 | 522 | file.mmFileName = file.fileName; 523 | file.mmFilePath = file.filePath; 524 | 525 | QString parseInfoString = QString("正在分析:"); 526 | parseInfoString = parseInfoString.append(file.filePath.c_str()); 527 | list->addItem(parseInfoString); 528 | 529 | OCParser ocParser; 530 | ocParser.parseOCFile(file); 531 | 532 | CppParser cppParser; 533 | cppParser.parseCppFile(file); 534 | } 535 | else 536 | { 537 | //跳过其他文件 538 | } 539 | 540 | list->update(); 541 | list->repaint(); 542 | list->scrollToBottom(); 543 | QCoreApplication::processEvents(); 544 | } 545 | QApplication::restoreOverrideCursor(); 546 | } 547 | 548 | void MainWindow::start_choosing() 549 | { 550 | start->setEnabled(false); 551 | 552 | list->setMouseTracking(false); 553 | 554 | list->setEditTriggers(QAbstractItemView::NoEditTriggers); 555 | list->setSelectionRectVisible(true); 556 | list->setSelectionBehavior(QAbstractItemView::SelectColumns); 557 | list->setSelectionMode(QAbstractItemView::NoSelection); 558 | list->setDragEnabled(false); 559 | 560 | while(list->count() != 0) 561 | { 562 | QListWidgetItem *item = list->takeItem(0); 563 | list->removeItemWidget(item); 564 | delete item; 565 | } 566 | 567 | DataBase *database = DataBase::Instance(); 568 | database->clearIdentifyVec(); 569 | vector().swap(fileList); 570 | 571 | QString path = edit_line->text(); 572 | 573 | QByteArray ba = path.toUtf8(); 574 | char *pathStr = ba.data(); 575 | readFileList(pathStr); 576 | 577 | if (is_inject_garbagecode_cpp) 578 | { 579 | inject_garbagecode(); 580 | } 581 | 582 | if (is_confuse_cpp || is_confuse_objc) 583 | { 584 | generate_confuse_code(); 585 | } 586 | 587 | 588 | vector identifyVec = database->queryAll(); 589 | 590 | vector keysVec; 591 | putAllKeyWords(keysVec); 592 | 593 | vector intersectVec(20000); 594 | set_intersection(identifyVec.begin(), identifyVec.end(), keysVec.begin(), keysVec.end(), intersectVec.begin());//交集 595 | sort(intersectVec.begin(),intersectVec.end()); 596 | intersectVec.erase(unique(intersectVec.begin(), intersectVec.end()), intersectVec.end()); 597 | 598 | vector resultVec(100000); 599 | set_difference(identifyVec.begin(), identifyVec.end(), intersectVec.begin(), intersectVec.end(), resultVec.begin()); //差集 600 | sort(resultVec.begin(),resultVec.end()); 601 | resultVec.erase(unique(resultVec.begin(), resultVec.end()), resultVec.end()); 602 | 603 | QString resDictPath = QString(":/resources/dict.txt"); 604 | QFile resDictFile(resDictPath); 605 | if(!resDictFile.open(QIODevice::ReadOnly | QIODevice::Text)) 606 | { 607 | QMessageBox::critical(nullptr, "critical", "读取字典文件出错!", QMessageBox::Yes, QMessageBox::Yes); 608 | } 609 | 610 | QApplication::setOverrideCursor(Qt::WaitCursor); 611 | vector wordsVec; 612 | 613 | QTextStream stream(&resDictFile); 614 | QString line; 615 | int n = 1; 616 | while (!stream.atEnd()) 617 | { 618 | line = stream.readLine(); 619 | string keyword = line.toStdString(); 620 | wordsVec.push_back(keyword); 621 | ++n; 622 | 623 | QCoreApplication::processEvents(); 624 | } 625 | QApplication::restoreOverrideCursor(); 626 | 627 | StringUtil stringUtil; 628 | QApplication::setOverrideCursor(Qt::WaitCursor); 629 | srand(static_cast(time(nullptr))); 630 | unordered_set strset; 631 | string ss = ""; 632 | while(strset.size() < resultVec.size()) 633 | { 634 | size_t index = static_cast(random(1, static_cast(wordsVec.size()-1))); 635 | 636 | ss = wordsVec[index]; 637 | string ssFirstCharStr = ss.substr(0,1); 638 | stringUtil.Toupper(ssFirstCharStr); 639 | ss = ss.replace(0, 1, ssFirstCharStr); 640 | strset.insert(ss); 641 | 642 | QCoreApplication::processEvents(); 643 | } 644 | QApplication::restoreOverrideCursor(); 645 | 646 | QApplication::setOverrideCursor(Qt::WaitCursor); 647 | vector disorderIdentifyVec; 648 | for (unordered_set::iterator it=strset.begin(); it!=strset.end(); it++) 649 | { 650 | disorderIdentifyVec.push_back(*it); 651 | QCoreApplication::processEvents(); 652 | } 653 | 654 | QApplication::restoreOverrideCursor(); 655 | 656 | //启用list 657 | list->setEditTriggers(QAbstractItemView::AllEditTriggers); 658 | list->setSelectionBehavior(QAbstractItemView::SelectItems); 659 | list->setSelectionMode(QAbstractItemView::SingleSelection); 660 | list->setDragEnabled(true); 661 | 662 | ResultDialog *pResultDlg = new ResultDialog(this); 663 | pResultDlg->setModal(true); 664 | pResultDlg->setConfuseResult(resultVec, disorderIdentifyVec); 665 | pResultDlg->show(); 666 | 667 | start->setEnabled(true); 668 | } 669 | 670 | bool MainWindow::findCppFileWithFileModel(SrcFileModel &fileModel) 671 | { 672 | QFile srcFile(fileModel.filePath.c_str()); 673 | QFileInfo fileInfo = QFileInfo(srcFile); 674 | 675 | string cppFileName = fileInfo.baseName().append(".cpp").toStdString(); 676 | string ccFileName = fileInfo.baseName().append(".cc").toStdString(); 677 | string cxxFileName = fileInfo.baseName().append(".cxx").toStdString(); 678 | 679 | StringUtil stringUtil; 680 | for(size_t i=0; i &keysVec) 814 | { 815 | QString reskeysFile = QString(":/resources/reskeys.txt"); 816 | QFile resFile(reskeysFile); 817 | if(!resFile.open(QIODevice::ReadOnly | QIODevice::Text)) 818 | { 819 | QMessageBox::critical(nullptr, "critical", "读取关键字文件出错!", QMessageBox::Yes, QMessageBox::Yes); 820 | } 821 | 822 | QApplication::setOverrideCursor(Qt::WaitCursor); 823 | QTextStream stream(&resFile); 824 | QString line; 825 | int n = 1; 826 | while (!stream.atEnd()) 827 | { 828 | line = stream.readLine(); 829 | string keyword = line.toStdString(); 830 | keysVec.push_back(keyword); 831 | ++n; 832 | QCoreApplication::processEvents(); 833 | } 834 | 835 | QApplication::restoreOverrideCursor(); 836 | 837 | sort(keysVec.begin(), keysVec.end()); 838 | 839 | resFile.close(); 840 | } 841 | -------------------------------------------------------------------------------- /CodeConfusing/mainwindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "fileviewer.h" 4 | #include "srcfilemodel.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | class MainWindow : public QMainWindow 27 | { 28 | Q_OBJECT 29 | 30 | public: 31 | MainWindow(QString file_storage, QString dir_storage, QWidget *parent = nullptr); 32 | 33 | ~MainWindow(); 34 | 35 | public slots: 36 | void add_next_path(QString path); 37 | 38 | private slots: 39 | void putAllKeyWords(vector &keysVec); 40 | bool findMFileWithFileModel(SrcFileModel &fileModel); 41 | bool findMMFileWithFileModel(SrcFileModel &fileModel); 42 | bool findCppFileWithFileModel(SrcFileModel &fileModel); 43 | bool findHeaderFileWithFileModel(SrcFileModel &fileModel); 44 | void readFileList(const char *basePath); 45 | void choose_path(); 46 | void start_choosing(); 47 | void onConfuseObjCStateChanged(int state); 48 | void onConfuseCppStateChanged(int state); 49 | void onInjectCodeStateChanged(int state); 50 | 51 | void generate_confuse_code(); 52 | void inject_garbagecode(); 53 | 54 | bool is_identify_property(string identify_str); 55 | bool is_identify_class(string identify_str); 56 | 57 | private: 58 | QListWidget *list = nullptr; 59 | QPushButton *add = nullptr; 60 | QPushButton *start = nullptr; 61 | QPushButton *choose = nullptr; 62 | QLabel *lbl_ignore_folders = nullptr; 63 | QCheckBox *cb_isconfuse_objc = nullptr; 64 | QCheckBox *cb_isconfuse_cpp = nullptr; 65 | QCheckBox *cb_isinject_garbagecode_cpp = nullptr; 66 | QLineEdit *edit_ignore_folders = nullptr; 67 | QLineEdit *edit_line = nullptr; 68 | QPushButton *del = nullptr; 69 | 70 | QString file_storage; 71 | QString dir_storage; 72 | vector fileList; 73 | vector xibAndsb; 74 | 75 | bool is_confuse_objc; 76 | bool is_confuse_cpp; 77 | bool is_inject_garbagecode_cpp; 78 | }; 79 | -------------------------------------------------------------------------------- /CodeConfusing/ocparser.cpp: -------------------------------------------------------------------------------- 1 | #include "ocparser.h" 2 | #include "stringutil.h" 3 | #include "database.h" 4 | 5 | OCParser::OCParser() 6 | { 7 | extends = ""; 8 | classname = ""; 9 | } 10 | 11 | OCParser::OCParser(string extends) 12 | { 13 | classname = ""; 14 | this->extends = extends; 15 | } 16 | 17 | int OCParser::parseOCFile(SrcFileModel srcFile) 18 | { 19 | QFile file(srcFile.filePath.c_str()); 20 | if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) 21 | { 22 | return -1; 23 | } 24 | 25 | StringUtil stringUtil; 26 | if(stringUtil.EndWith(srcFile.fileName, ".h")) 27 | { 28 | ifstream fin(srcFile.filePath.c_str());//文件输入流 29 | string str; 30 | string temp; 31 | size_t pos = 0; 32 | while(getline(fin,temp,'\n')) 33 | { 34 | str.append(temp+"\r\n\t"); 35 | } 36 | R(str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 37 | //注释里面出现include和import的话会出事囧 38 | while(find(str,"#include",pos)){}//连续读取代码中的include名 39 | while(find(str,"#import",pos)){}//连续读取代码中的import名 40 | while(find(str,"@interface",pos)){}//连续读取代码中的类 41 | while(find(str,"@implementation",pos)){}//连续读取代码中的类 42 | 43 | QFile mFile(srcFile.mFilePath.c_str()); 44 | if(mFile.open(QIODevice::ReadOnly | QIODevice::Text)) 45 | { 46 | fin.close(); 47 | 48 | ifstream m_fin(srcFile.mFilePath.c_str());//文件输入流,p是代码路径 49 | string m_str; 50 | string m_temp; 51 | size_t m_pos = 0; 52 | while(getline(m_fin,m_temp,'\n')) 53 | { 54 | m_str.append(m_temp+"\r\n\t"); 55 | } 56 | R(m_str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 57 | srcFile.fileImpleParseString = m_str; 58 | //注释里面出现include和import的话会出事囧 59 | while(find(m_str,"#include",m_pos)){}//连续读取代码中的include名 60 | while(find(m_str,"#import",m_pos)){}//连续读取代码中的import名 61 | while(find(m_str,"@interface",m_pos)){}//连续读取代码中的类 62 | while(find(m_str,"@implementation",m_pos)){}//连续读取代码中的类 63 | 64 | display(srcFile); 65 | m_fin.close(); 66 | } 67 | else 68 | { 69 | display(srcFile); 70 | fin.close(); 71 | } 72 | } 73 | else if(stringUtil.EndWith(srcFile.fileName, ".m") || stringUtil.EndWith(srcFile.fileName, ".mm")) 74 | { 75 | ifstream fin(srcFile.filePath.c_str());//文件输入流,p是代码路径 76 | string str; 77 | string temp; 78 | size_t pos = 0; 79 | while(getline(fin,temp,'\n')) 80 | { 81 | str.append(temp+"\r\n\t"); 82 | } 83 | R(str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 84 | srcFile.fileImpleParseString = str; 85 | //注释里面出现include和import的话会出事囧 86 | while(find(str,"#include",pos)){}//连续读取代码中的include名 87 | while(find(str,"#import",pos)){}//连续读取代码中的import名 88 | while(find(str,"@interface",pos)){}//连续读取代码中的类 89 | while(find(str,"@implementation",pos)){}//连续读取代码中的类 90 | 91 | QFile headFile(srcFile.headerFilePath.c_str()); 92 | if(headFile.open(QIODevice::ReadOnly | QIODevice::Text)) 93 | { 94 | fin.close(); 95 | 96 | ifstream header_fin(srcFile.headerFilePath.c_str());//文件输入流,p是代码路径 97 | string header_str; 98 | string header_temp; 99 | size_t header_pos = 0; 100 | while(getline(header_fin,header_temp,'\n')) 101 | { 102 | header_str.append(header_temp+"\r\n\t"); 103 | } 104 | R(header_str);//删除全部注释,跟D(temp)不一样的是 D(temp)以\t判断,这个以\r判断 105 | //注释里面出现include和import的话会出事囧 106 | while(find(header_str,"#include",header_pos)){}//连续读取代码中的include名 107 | while(find(header_str,"#import",header_pos)){}//连续读取代码中的import名 108 | while(find(header_str,"@interface",header_pos)){}//连续读取代码中的类 109 | while(find(header_str,"@implementation",header_pos)){}//连续读取代码中的类 110 | 111 | display(srcFile); 112 | header_fin.close(); 113 | } 114 | else 115 | { 116 | display(srcFile); 117 | 118 | fin.close(); 119 | } 120 | } 121 | else 122 | { 123 | //其他文件格式 124 | } 125 | 126 | return 0; 127 | } 128 | 129 | int OCParser::judge(string s) 130 | { 131 | if(s=="#include") 132 | { 133 | return OC_INCLUDE; 134 | } 135 | else if(s=="#import") 136 | { 137 | return OC_IMPORT; 138 | } 139 | else if(s=="@interface") 140 | { 141 | return OC_CLASS; 142 | } 143 | else if(s=="@implementation") 144 | { 145 | return OC_IMPLEMENTS; 146 | } 147 | else if(s=="vaiabler") 148 | { 149 | return OC_VARIABLE; 150 | } 151 | else if(s=="function") 152 | { 153 | return OC_IMPORT; 154 | } 155 | return OC_UNDEINED; 156 | } 157 | 158 | void OCParser::D(string& str,char c) 159 | { 160 | if(c == '=') //如果字符是 '=' , 则把 = 等号 和 ; 分号之间的信息除去,例如:int a = 5; 把=号、空格和5给擦除 161 | { 162 | size_t index_s = 0; 163 | size_t index_e = 0; 164 | while(index_s(isspace))); 331 | str.erase(str.begin(), p); 332 | return str; 333 | } 334 | 335 | inline string& OCParser::rtrim(string &str) 336 | { 337 | string::reverse_iterator p = find_if(str.rbegin(), str.rend(), not1(ptr_fun(isspace))); 338 | str.erase(p.base(), str.end()); 339 | return str; 340 | } 341 | 342 | inline string& OCParser::trim(string &str) 343 | { 344 | ltrim(rtrim(str)); 345 | return str; 346 | } 347 | 348 | inline bool OCParser::is_property_name_exist(string functionName, vector propertyList) 349 | { 350 | StringUtil stringUtil; 351 | for(size_t i=0; i::iterator b; 366 | size_t pos; 367 | for(b = oc_include.begin(); b!=oc_include.end();++b) 368 | { 369 | //include 370 | } 371 | for(b = oc_import.begin(); b!=oc_import.end();++b) 372 | { 373 | //import 374 | } 375 | vector::iterator i; 376 | for(i = _oc.begin(); i!=_oc.end() ; ++i) 377 | { 378 | //类名 379 | string oc_class_name = i->classname; 380 | if(i->extends.size() != 0) 381 | { 382 | //继承 383 | } 384 | if(i->delegates.size()!=0) 385 | { 386 | for(b = i->delegates.begin(); b != i->delegates.end(); ++b) 387 | { 388 | //代理 389 | } 390 | } 391 | for(b = i->var.begin(); b != i->var.end(); ++b) 392 | { 393 | pos = 0; 394 | trim(*b); 395 | ignorespacetab(*b,pos); 396 | if(pos != b->length()) 397 | { 398 | string varName = b->substr(pos,b->length()-pos); 399 | //不混淆xib绑定的属性和方法 400 | if (varName.find("IBOutlet") != string::npos || varName.find("IBAction") != string::npos) 401 | { 402 | continue; 403 | } 404 | 405 | ClassModel model; 406 | model.fileName = fileModel.fileName; 407 | model.className = oc_class_name; 408 | model.identifyName = varName; 409 | model.identifyOriginName = varName; 410 | model.filePath = fileModel.filePath; 411 | model.isObjectiveC = true; 412 | 413 | if (handleObjectiveCIdentify(model)) 414 | { 415 | database->insertRecord(model); 416 | } 417 | } 418 | } 419 | for(b = i->properties.begin(); b != i->properties.end(); ++b) 420 | { 421 | pos = 0; 422 | trim(*b); 423 | ignorespacetab(*b,pos); 424 | if (pos != b->length()) 425 | { 426 | string propertyName = b->substr(pos,b->length()-pos); 427 | 428 | //不混淆xib绑定的属性 429 | if (propertyName.find("IBOutlet") != string::npos) 430 | { 431 | continue; 432 | } 433 | 434 | ClassModel model; 435 | model.fileName = fileModel.fileName; 436 | model.className = oc_class_name; 437 | model.identifyName = propertyName; 438 | model.identifyOriginName = propertyName; 439 | model.filePath = fileModel.filePath; 440 | model.isObjectiveC = true; 441 | 442 | if (handleObjectiveCIdentify(model)) 443 | { 444 | database->insertRecord(model); 445 | } 446 | 447 | } 448 | } 449 | for(b = i->function.begin(); b != i->function.end(); ++b) 450 | { 451 | pos = 0; 452 | trim(*b); 453 | ignorespacetab(*b,pos); 454 | 455 | if(pos != b->length()) 456 | { 457 | string functionName = b->substr(pos,b->length()-pos); 458 | 459 | //不混淆xib绑定的方法 460 | if (functionName.find("IBAction") != string::npos) 461 | { 462 | continue; 463 | } 464 | 465 | if(!is_property_name_exist(functionName, i->properties)) 466 | { 467 | ClassModel model; 468 | model.fileName = fileModel.fileName; 469 | model.className = oc_class_name; 470 | model.identifyName = functionName; 471 | model.identifyOriginName = functionName; 472 | model.filePath = fileModel.filePath; 473 | model.isObjectiveC = true; 474 | 475 | if (handleObjectiveCIdentify(model)) 476 | { 477 | database->insertRecord(model); 478 | } 479 | } 480 | } 481 | } 482 | } 483 | } 484 | 485 | /** 486 | fI , nI - fI 取得是fI 到 nI-1下标的子串 487 | */ 488 | int OCParser::find(string& str,string s,size_t& pos){ 489 | int type = judge(s); 490 | size_t fI,nI;//firstIndex,nextIndex 491 | string temp = ""; 492 | switch(type) 493 | { 494 | case OC_INCLUDE: 495 | case OC_IMPORT: 496 | { 497 | fI = str.find(s,pos);//先找到include或import的位置 498 | if(fI != string::npos) 499 | { 500 | //判断include和import是否在@interface里面的注释里 501 | size_t cI = str.find("@interface",pos); 502 | if(cI != string::npos && cI dn = findDelegatesName(classline,begin);//delegatesname 543 | map> map = findPropertiesAndFunctionDeclaresName(classline,begin);//propertiesname 544 | 545 | theclass.classname = cn; 546 | theclass.extends = en; 547 | theclass.delegates = dn; 548 | theclass.properties = map["properties"]; 549 | theclass.function = map["functions"]; 550 | 551 | _oc.push_back(theclass); 552 | pos = fI + 1;//下一个搜索位置从fI开始,因为可能会出现类里面嵌套类的情况 553 | return OC_HAVEFOUND; 554 | } 555 | } 556 | else 557 | { 558 | return OC_NOTFOUND; 559 | } 560 | } 561 | break; 562 | case OC_IMPLEMENTS: 563 | { 564 | fI = str.find(s,pos);//找到"@implementation" 565 | if(fI != string::npos) 566 | { 567 | fI += strlen("@implementation")+1; 568 | OCParser theclass;//C类 569 | size_t lBlock = str.find('\n',fI) ; 570 | if(lBlock != string::npos) 571 | { 572 | ++lBlock; 573 | string classline = str.substr(fI,lBlock-fI);//获得类信息的第一行 574 | size_t begin = 0; 575 | const string cn = findClassName(classline,begin);//classname 576 | theclass.classname = cn; 577 | 578 | size_t cur_index = lBlock;//current_index 579 | vector vi = actionscope(str,cur_index);//获取函数和数组变量初始化等 { 和 } 的位置 580 | string temp = ""; 581 | //排除所有作用域内的字符串 582 | for(vector::iterator vit = vi.begin(); vit != vi.end(); vit += 2) 583 | { 584 | size_t index = *vit+1; 585 | size_t length = *(vit+1)-*(vit)-1; 586 | if (index >= str.length() || index+length >= str.length()) 587 | { 588 | break; 589 | } 590 | temp += str.substr(index, length); 591 | } 592 | vector vs = divideByTab(temp);//根据制表符分解字符串 593 | size_t sem_index;//分号下标 594 | //根据分号来区分函数和变量 595 | for(vector::iterator b = vs.begin(); b!=vs.end();++b) 596 | { 597 | sem_index = b->find_last_of(';'); 598 | if( sem_index != string::npos) 599 | { 600 | theclass.var.push_back(b->substr(0,sem_index)); 601 | } 602 | else 603 | { 604 | string functionStr = trim(*b); 605 | D(functionStr,'#'); 606 | if (functionStr.length() > 2 && functionStr.find("@") == string::npos) 607 | { 608 | theclass.function.push_back(*b); 609 | } 610 | } 611 | } 612 | sort(theclass.var.begin(),theclass.var.end()); 613 | theclass.var.erase(unique(theclass.var.begin(), theclass.var.end()), theclass.var.end()); 614 | sort(theclass.function.begin(),theclass.function.end()); 615 | theclass.function.erase(unique(theclass.function.begin(), theclass.function.end()), theclass.function.end()); 616 | _oc.push_back(theclass); 617 | pos = fI + 1;//下一个搜索位置从fI开始,因为可能会出现类里面嵌套类的情况 618 | return OC_HAVEFOUND; 619 | } 620 | } 621 | else 622 | { 623 | return OC_NOTFOUND; 624 | } 625 | } 626 | break; 627 | case OC_VARIABLE: 628 | break; 629 | case OC_FUNCTION: 630 | break; 631 | case OC_UNDEINED: 632 | break; 633 | }; 634 | return OC_NOTFOUND; 635 | } 636 | 637 | string OCParser::findClassName(const string& classline,size_t &begin) 638 | { 639 | ignorespacetab(classline,begin); 640 | size_t CNS = begin;//classname_start 641 | ignorealnum(classline,begin); 642 | size_t CNE = begin;//classname_end 643 | return classline.substr(CNS,CNE-CNS); 644 | } 645 | 646 | string OCParser::findExtendsName(const string& str,size_t pos) 647 | { 648 | size_t es = str.find(":",pos);//extends_start 649 | if( es != string::npos ) 650 | { 651 | es += 1; 652 | ignorespacetab(str,es); 653 | size_t ens = es;//extendsname_start 654 | ignorealnum(str,es); 655 | size_t ene = es;//extendsname_end; 656 | 657 | return str.substr(ens,ene-ens); 658 | } 659 | return ""; 660 | } 661 | 662 | const vector OCParser::findDelegatesName(const string& str,size_t pos) 663 | { 664 | vector delegates; 665 | size_t ds = str.find("<",pos);//delegates_start 666 | size_t de = str.find(">",pos);//delegates_end 667 | if( ds != string::npos) 668 | { 669 | ds += 1; 670 | ignorespacetab(str,ds); 671 | size_t ins = ds;//delegates_start 672 | size_t ine = de;//delegates_end 673 | 674 | delegates.push_back(str.substr(ins,ine-ins)); 675 | } 676 | return delegates; 677 | } 678 | 679 | const map> OCParser::findPropertiesAndFunctionDeclaresName(const string& str,size_t pos) 680 | { 681 | map> propertiesAndFunctionDeclaresMap; 682 | vector properties; 683 | vector functionDeclares; 684 | size_t ps = str.find("@property",pos);//property_start 685 | size_t pe = str.find(";",pos);//property_end 686 | if( ps != string::npos) 687 | { 688 | ignorespacetab(str,ps); 689 | size_t ins = ps;//property_start 690 | size_t ine = pe;//property_end 691 | 692 | while(ps= str.length()) 745 | { 746 | break; 747 | } 748 | ++fI; 749 | if(str[fI] == '{') 750 | { 751 | ++lBlock_num; 752 | } 753 | else if(str[fI] == '}') 754 | { 755 | --lBlock_num; 756 | } 757 | } 758 | } 759 | 760 | vector OCParser::actionscope(const string& str,size_t& fI) 761 | { 762 | vector index; 763 | index.push_back(fI-1); 764 | int lBlock_num = 1; 765 | while(lBlock_num) 766 | { 767 | if(fI >= str.length()) 768 | { 769 | break; 770 | } 771 | if(str[fI] == '{') 772 | { 773 | index.push_back(fI);//获取'{'的下标 774 | actionscope_ignore(str,fI); 775 | index.push_back(fI);//获得匹配上面的'{'的'}'的下标 776 | } 777 | else if(str[fI] == '}') 778 | { 779 | lBlock_num = 0; 780 | index.push_back(fI); 781 | continue; 782 | } 783 | ++fI; 784 | } 785 | return index; 786 | } 787 | 788 | 789 | bool OCParser::handleObjectiveCIdentify(ClassModel &classModel) 790 | { 791 | StringUtil stringUtil; 792 | 793 | string identify_str = classModel.identifyName; 794 | 795 | size_t NS1 = identify_str.find("NS_AVAILABLE_IOS"); 796 | if (NS1 != string::npos) 797 | { 798 | identify_str = identify_str.substr(0, NS1); 799 | } 800 | 801 | size_t ATTR = identify_str.find("__attribute__"); 802 | if (ATTR != string::npos) 803 | { 804 | identify_str = identify_str.substr(0, ATTR); 805 | } 806 | 807 | size_t UI1 = identify_str.find("UI_APPEARANCE_SELECTOR"); 808 | if (UI1 != string::npos) 809 | { 810 | identify_str = identify_str.substr(0, UI1); 811 | } 812 | 813 | identify_str = trim(identify_str); 814 | 815 | size_t operator_index = identify_str.find(" operator"); 816 | size_t operator_index2 = identify_str.find("::operator"); 817 | size_t method_index = identify_str.find('+'); 818 | size_t method_index2 = identify_str.find('-'); 819 | 820 | size_t property_index = identify_str.find("@property"); 821 | if ( (method_index != string::npos || method_index2 != string::npos) && 822 | (operator_index==string::npos && operator_index2==string::npos) )//Objective C Method 823 | { 824 | if (stringUtil.StartWith(identify_str, "set")) 825 | { 826 | return false; 827 | } 828 | 829 | size_t first_colon_index = identify_str.find_first_of(':'); 830 | if (first_colon_index != string::npos) 831 | { 832 | identify_str = identify_str.substr(0, first_colon_index); 833 | } 834 | 835 | size_t first_brackets_index = identify_str.find_last_of(')'); 836 | if (first_brackets_index != string::npos) 837 | { 838 | identify_str = identify_str.substr(first_brackets_index+1, identify_str.length()-first_brackets_index); 839 | } 840 | 841 | stringUtil.deleteSpecialChar(identify_str); 842 | if (stringUtil.is_allow_identify_name(identify_str)) 843 | { 844 | string method_str = trim(identify_str); 845 | if (stringUtil.is_allow_identify_name(classModel.className)) 846 | { 847 | classModel.identifyName = method_str; 848 | classModel.isMethodName = true; 849 | 850 | return true; 851 | } 852 | } 853 | } 854 | else if(property_index != string::npos)//Objective C Property 855 | { 856 | size_t block_index = identify_str.find_first_of('^'); 857 | if (block_index != string::npos) 858 | { 859 | identify_str = identify_str.substr(block_index+1, identify_str.length()-block_index); 860 | size_t first_brackets_index = identify_str.find_first_of(')'); 861 | if (first_brackets_index != string::npos) 862 | { 863 | identify_str = identify_str.substr(0, first_brackets_index); 864 | } 865 | return false; 866 | } 867 | 868 | size_t last_space_index = identify_str.find_last_of(' '); 869 | if (last_space_index != string::npos) 870 | { 871 | identify_str = identify_str.substr(last_space_index, identify_str.length()-last_space_index); 872 | } 873 | 874 | stringUtil.deleteSpecialChar(identify_str); 875 | if (stringUtil.is_allow_identify_name(identify_str)) 876 | { 877 | string property_str = trim(identify_str); 878 | if (stringUtil.is_allow_identify_name(classModel.className)) 879 | { 880 | classModel.identifyName = property_str; 881 | classModel.isPropertyName = true; 882 | return true; 883 | } 884 | } 885 | } 886 | else 887 | { 888 | size_t first_brackets_index = identify_str.find_first_of('('); 889 | if (first_brackets_index != string::npos) 890 | { 891 | identify_str = identify_str.substr(0, first_brackets_index); 892 | } 893 | 894 | size_t last_space_index = identify_str.find_last_of(' '); 895 | if (last_space_index != string::npos) 896 | { 897 | identify_str = identify_str.substr(last_space_index, identify_str.length()-last_space_index); 898 | } 899 | 900 | stringUtil.deleteSpecialChar(identify_str); 901 | if (stringUtil.is_allow_identify_name(identify_str)) 902 | { 903 | //qDebug() << "other identify:" << classModel.identifyName.c_str() << identify_str.c_str(); 904 | } 905 | } 906 | 907 | return false; 908 | } 909 | -------------------------------------------------------------------------------- /CodeConfusing/ocparser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "srcfilemodel.h" 4 | #include "classmodel.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | 19 | #define OC_INCLUDE 8 20 | #define OC_IMPORT 7 21 | #define OC_CLASS 3 22 | #define OC_IMPLEMENTS 2 23 | #define OC_VARIABLE 4 24 | #define OC_FUNCTION 5 25 | #define OC_UNDEINED -1 26 | #define OC_NOTFOUND 0 27 | #define OC_HAVEFOUND 1 28 | 29 | typedef map > STRING2VECTOR; 30 | 31 | class OCParser 32 | { 33 | public: 34 | string classname;//类的名字 35 | string extends;//类的extends 36 | vector delegates;//类的delegates 37 | vector var;//类的变量 38 | vector properties;//类的属性 39 | vector function;//类的函数 40 | 41 | vector oc_include;//include集合 42 | vector oc_import;//import集合 43 | vector _oc;//类的结合 44 | 45 | OCParser(); 46 | OCParser(string extends); 47 | 48 | int parseOCFile(SrcFileModel srcFile); 49 | 50 | private: 51 | 52 | //如果已经存在属性名称,则忽略同名的函数名称 53 | inline bool is_property_name_exist(string functionName, vector propertyList); 54 | 55 | inline bool is_allow_identify_name(string str); 56 | inline void deleteSpecialChar(string& str); 57 | bool handleObjectiveCIdentify(ClassModel &model); 58 | 59 | inline string& rtrim(string &str); 60 | inline string& ltrim(string &str); 61 | string& trim(string &s); //去除空格和换行 62 | int judge(string s);//判断字符串名字返回不同的值 63 | void D(string& str,char c);//在字符串str中循环删除字符c 64 | void R(string& str);//以\r为判断删除注释 65 | vector divideByTab(string &str);//以制表符为分隔符分解字符串成vector 66 | void ignorespacetab(const string& str,size_t& fI);//fI停在非空格和制表符处 67 | void ignorealnum(const string&str ,size_t& fI);//fI停在非数字和字母处 68 | void display(SrcFileModel fileModel);//用文件输出流输出 69 | int find(string& str,string s,size_t& pos);//在pos处,str找s 70 | string findClassName(const string& str,size_t &begin);//在一个字符串上找类名 71 | string findExtendsName(const string& str,size_t pos);//在一个字符串上找扩展名 72 | const vector findDelegatesName(const string& str,size_t pos);//代理 73 | const map> findPropertiesAndFunctionDeclaresName(const string& str,size_t pos);//属性和方法 74 | void actionscope_ignore(const string& str,size_t& fI);//忽略一个大的作用域中的所有作用域 75 | vector actionscope(const string& str,size_t& fI);//获取最大的作用域的位置 76 | }; 77 | -------------------------------------------------------------------------------- /CodeConfusing/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | dict.txt 4 | reskeys.txt 5 | codepiece.json 6 | 7 | 8 | -------------------------------------------------------------------------------- /CodeConfusing/resultdialog.cpp: -------------------------------------------------------------------------------- 1 | #include "resultdialog.h" 2 | #include "classmodel.h" 3 | #include "database.h" 4 | #include "stringutil.h" 5 | #include 6 | #include 7 | 8 | ResultDialog::ResultDialog(QWidget *parent) 9 | :QDialog(parent) 10 | { 11 | ok_btn = new QPushButton("好的"); 12 | 13 | edit_result = new QTextEdit(); 14 | edit_result->setMinimumWidth(300); 15 | 16 | QHBoxLayout *input = new QHBoxLayout(); 17 | input->addWidget(edit_result); 18 | 19 | QVBoxLayout *all = new QVBoxLayout(); 20 | all->addLayout(input); 21 | all->addWidget(ok_btn); 22 | 23 | connect(ok_btn, SIGNAL(clicked(bool)), SLOT(hideDialog())); 24 | 25 | setLayout(all); 26 | 27 | setWindowTitle("混淆结果"); 28 | setWindowFlags(Qt::Window); 29 | setGeometry(400,400,800,490); 30 | } 31 | 32 | ResultDialog::~ResultDialog() 33 | { 34 | 35 | } 36 | 37 | bool is_identify_property(string identify_str) 38 | { 39 | DataBase *database = DataBase::Instance(); 40 | 41 | vector modelVec = database->queryAllModel(); 42 | 43 | StringUtil stringUtil; 44 | for (vector::iterator it=modelVec.begin(); it != modelVec.end(); ++it) 45 | { 46 | ClassModel model = *it; 47 | if (stringUtil.StartWith(model.identifyName, identify_str) && model.identifyName.length() == identify_str.length() && model.isPropertyName && model.identifyName.find("readonly") == string::npos) 48 | { 49 | return true; 50 | } 51 | } 52 | 53 | return false; 54 | } 55 | 56 | bool is_identify_class(string identify_str) 57 | { 58 | DataBase *database = DataBase::Instance(); 59 | 60 | vector modelVec = database->queryAllModel(); 61 | 62 | StringUtil stringUtil; 63 | for (vector::iterator it=modelVec.begin(); it != modelVec.end(); ++it) 64 | { 65 | ClassModel model = *it; 66 | if (stringUtil.StartWith(model.className, identify_str) && model.className.length() == identify_str.length()) 67 | { 68 | return true; 69 | } 70 | } 71 | 72 | return false; 73 | } 74 | 75 | void ResultDialog::setConfuseResult(vector resultVec, vector disorderIdentifyVec) 76 | { 77 | StringUtil stringUtil; 78 | QString resultStr = ""; 79 | for (size_t i=1; isetText(resultStr); 128 | } 129 | 130 | void ResultDialog::hideDialog() 131 | { 132 | this->hide(); 133 | } 134 | -------------------------------------------------------------------------------- /CodeConfusing/resultdialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "srcfilemodel.h" 11 | 12 | using namespace std; 13 | 14 | class ResultDialog : public QDialog 15 | { 16 | Q_OBJECT 17 | protected: 18 | QPushButton *ok_btn; 19 | QTextEdit *edit_result; 20 | 21 | public: 22 | ResultDialog(QWidget *parent = nullptr); 23 | ~ResultDialog(); 24 | void setConfuseResult(vector resultVec, vector disorderIdentifyVec); 25 | 26 | private slots: 27 | void hideDialog(); 28 | }; 29 | -------------------------------------------------------------------------------- /CodeConfusing/srcfilemodel.cpp: -------------------------------------------------------------------------------- 1 | #include "srcfilemodel.h" 2 | 3 | SrcFileModel::SrcFileModel() 4 | { 5 | fileImpleParseString = ""; 6 | 7 | fileName = ""; 8 | filePath = ""; 9 | 10 | headerFileName = ""; 11 | headerFilePath = ""; 12 | cFileName = ""; 13 | cFilePath = ""; 14 | cppFileName = ""; 15 | cppFilePath = ""; 16 | mFileName = ""; 17 | mFilePath = ""; 18 | mmFileName = ""; 19 | mmFilePath = ""; 20 | } 21 | -------------------------------------------------------------------------------- /CodeConfusing/srcfilemodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | class SrcFileModel 8 | { 9 | public: 10 | string fileImpleParseString; 11 | 12 | string fileName; 13 | string filePath; 14 | string headerFileName; 15 | string headerFilePath; 16 | string cFileName; 17 | string cFilePath; 18 | string cppFileName; 19 | string cppFilePath; 20 | string mFileName; 21 | string mFilePath; 22 | string mmFileName; 23 | string mmFilePath; 24 | 25 | bool isParsed; //是否已进行过语法分析 true-是 false-否 26 | 27 | SrcFileModel(); 28 | }; 29 | -------------------------------------------------------------------------------- /CodeConfusing/stringutil.cpp: -------------------------------------------------------------------------------- 1 | #include "stringutil.h" 2 | 3 | StringUtil::StringUtil() 4 | { 5 | } 6 | 7 | void StringUtil::Toupper(string& str) 8 | { 9 | transform(str.begin(),str.end(),str.begin(),::toupper); 10 | } 11 | 12 | void StringUtil::Tolower(string& str) 13 | { 14 | transform(str.begin(),str.end(),str.begin(),::tolower); 15 | } 16 | 17 | inline string& StringUtil::ltrim(string &str) 18 | { 19 | string::iterator p = find_if(str.begin(), str.end(), not1(ptr_fun(isspace))); 20 | str.erase(str.begin(), p); 21 | return str; 22 | } 23 | 24 | inline string& StringUtil::rtrim(string &str) 25 | { 26 | string::reverse_iterator p = find_if(str.rbegin(), str.rend(), not1(ptr_fun(isspace))); 27 | str.erase(p.base(), str.end()); 28 | return str; 29 | } 30 | 31 | string& StringUtil::trim(string &str) 32 | { 33 | ltrim(rtrim(str)); 34 | return str; 35 | } 36 | 37 | void StringUtil::DeleteChar(string& str,char ch) 38 | { 39 | str.erase(remove_if(str.begin(),str.end(),bind2nd(equal_to(), ch)),str.end()); 40 | } 41 | 42 | bool StringUtil::StartWith(const string& str,const string& strStart) 43 | { 44 | if(str.empty() || strStart.empty()) 45 | { 46 | return false; 47 | } 48 | if (strStart.size() > str.size()) 49 | { 50 | return false; 51 | } 52 | 53 | return str.compare(0,strStart.size(),strStart)==0?true:false; 54 | } 55 | 56 | bool StringUtil::EndWith(const string& str,const string& strEnd) 57 | { 58 | if(str.empty() || strEnd.empty()) 59 | { 60 | return false; 61 | } 62 | 63 | if (strEnd.size() > str.size()) 64 | { 65 | return false; 66 | } 67 | return str.compare(str.size()-strEnd.size(),strEnd.size(),strEnd)==0?true:false; 68 | } 69 | 70 | void StringUtil::deleteSpecialChar(string& str) 71 | { 72 | str = trim(str); 73 | 74 | if(str.find('{') != string::npos) 75 | { 76 | size_t index_s = 0; 77 | while(index_s chars_vec; 143 | chars_vec.push_back("public:"); 144 | chars_vec.push_back("private:"); 145 | chars_vec.push_back("protected:"); 146 | chars_vec.push_back("#"); 147 | chars_vec.push_back("="); 148 | chars_vec.push_back(":"); 149 | chars_vec.push_back("if "); 150 | chars_vec.push_back("if("); 151 | chars_vec.push_back("return "); 152 | chars_vec.push_back("cout<<"); 153 | chars_vec.push_back("cout "); 154 | chars_vec.push_back("."); 155 | chars_vec.push_back("this"); 156 | chars_vec.push_back("->"); 157 | chars_vec.push_back("\\"); 158 | 159 | for(vector::iterator iter = chars_vec.begin(); iter!=chars_vec.end();++iter) 160 | { 161 | if (str.find(*iter) != string::npos) 162 | { 163 | is_contain = true; 164 | break; 165 | } 166 | } 167 | 168 | return is_contain; 169 | } 170 | 171 | bool StringUtil::is_var_or_function(string str) 172 | { 173 | return (str.find(';') == string::npos && is_str_contain_space(str) && !is_str_contain_chars(str)); 174 | } 175 | 176 | bool StringUtil::is_allow_identify_name(string str) 177 | { 178 | if (str.length() == 1) 179 | { 180 | return false; 181 | } 182 | 183 | StringUtil stringUtil; 184 | regex reg("[_[:alpha:]][_[:alnum:]]*"); 185 | 186 | regex upper_underline_reg("[_[:digit:][:upper:]]*"); 187 | 188 | string judge_str = stringUtil.trim(str); 189 | if (regex_match(str, reg) && 190 | !regex_match(str, upper_underline_reg) && 191 | !stringUtil.StartWith(str, "_") && 192 | !stringUtil.StartWith(str, "init") && 193 | !stringUtil.StartWith(str, "dispatch_") && 194 | !stringUtil.StartWith(str, "gl") && 195 | !stringUtil.StartWith(str, "const_") && 196 | !stringUtil.StartWith(str, "objc_") && 197 | !stringUtil.StartWith(str, "CC_") && 198 | !stringUtil.StartWith(str, "CG") && 199 | !stringUtil.StartWith(str, "CM") && 200 | !stringUtil.StartWith(str, "CT") && 201 | !stringUtil.StartWith(str, "CF") && 202 | !stringUtil.StartWith(str, "NS") && 203 | !stringUtil.StartWith(str, "sqlite3_") && 204 | !stringUtil.StartWith(str, "set") && 205 | !stringUtil.StartWith(str, "is") && 206 | !stringUtil.StartWith(str, "NS") && 207 | !stringUtil.StartWith(str, "kCG") && 208 | !stringUtil.StartWith(str, "AV") && 209 | !stringUtil.StartWith(str, "kCF") && 210 | !stringUtil.StartWith(str, "kCT") && 211 | !stringUtil.StartWith(str, "isEqual") && 212 | !stringUtil.StartWith(str, "UI") && 213 | !stringUtil.StartWith(str, "Sec") && 214 | !stringUtil.StartWith(str, "error") && 215 | !stringUtil.EndWith(str, "error") && 216 | !stringUtil.StartWith(str, "unsigned")) 217 | { 218 | return true; 219 | } 220 | else 221 | { 222 | return false; 223 | } 224 | } 225 | 226 | bool StringUtil::is_allow_identify_name_c_cpp(string str) 227 | { 228 | if (str.length() == 1) 229 | { 230 | return false; 231 | } 232 | 233 | StringUtil stringUtil; 234 | regex reg("[_[:alpha:]][_[:alnum:]]*"); 235 | 236 | regex upper_underline_reg("[_[:digit:][:upper:]]*"); 237 | 238 | string judge_str = stringUtil.trim(str); 239 | if (regex_match(str, reg) && 240 | !regex_match(str, upper_underline_reg) && 241 | !stringUtil.StartWith(str, "_") && 242 | !stringUtil.StartWith(str, "gl") && 243 | !stringUtil.StartWith(str, "const_") && 244 | !stringUtil.StartWith(str, "objc_") ) 245 | { 246 | return true; 247 | } 248 | else 249 | { 250 | return false; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /CodeConfusing/stringutil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class StringUtil 11 | { 12 | public: 13 | StringUtil(); 14 | 15 | bool is_allow_identify_name(string str); 16 | bool is_allow_identify_name_c_cpp(string str); 17 | bool is_var_or_function(string str); 18 | inline bool is_str_contain_chars(string str); 19 | inline bool is_str_contain_space(string str); 20 | 21 | void Toupper(string& str); //转大写 22 | void Tolower(string& str); //转小写 23 | 24 | inline string& rtrim(string &str); 25 | inline string& ltrim(string &str); 26 | string& trim(string &s); //去除空格和换行 27 | void deleteSpecialChar(string& str); 28 | void DeleteChar(string& str,char ch); //去掉字符串里某个字符,注意,是都去掉 29 | bool StartWith(const string& str,const string& strStart); //字符串以某段开头 30 | bool EndWith(const string& str,const string& strEnd); //字符串以某段结尾 31 | }; 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeConfuseTool 2 | 3 | C++/Objective C 项目代码混淆工具,主要功能是混淆类名和函数名,使用C++和Qt开发 4 | 5 | * 支持有选择的混淆Objective C代码 6 | * 支持有选择的混淆C/C++代码 7 | * 支持C++代码注入垃圾代码 8 | 9 | 目前仅支持在 Mac OS X 或者Linux下编译运行: 10 | 11 | Mac下可以使用命令:qmake -spec macx-xcode #生成Xcode工程文件 12 | 13 | 需要安装Qt 5.9.1 for Mac http://download.qt.io/archive/qt/5.9/5.9.1/ 14 | -------------------------------------------------------------------------------- /使用说明.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macosunity/CodeConfuseTool/3e4d9b69c5861d0751c1008cc65cbee802ad97c2/使用说明.docx --------------------------------------------------------------------------------