├── .gitignore ├── arm ├── libcms.so ├── libdu.so ├── libdexvmp.so ├── libsecsdk.so ├── libSecShell.so ├── libcompatible.so ├── libmetasec_ml.so ├── libnative-lib.so ├── libnative-lib.so.config.json ├── libdu.so.config.json ├── libSecShell.so.config.json ├── libsecsdk.so.config.json ├── libcompatible.so.config.json ├── libmetasec_ml.so.config.json └── libcms.so.config.json ├── arm64 ├── libvdog.so ├── cff-arm64-v8a.elf ├── libcompatible.so ├── libnative-lib.so ├── cff-arm64-v8a.elf.config.json ├── libcompatible.so.config.json ├── libvdog.so.config.json └── libnative-lib.so.config.json ├── x86 ├── libdexvmp.so ├── libcompatible_x86.so ├── libshellx-super.2019.so ├── libcompatible_x86.so.config.json └── libshellx-super.2019.so.config.json ├── x86_64 ├── libcompatible_x86.so ├── demo-control-flow-flatten.elf64 └── demo-control-flow-flatten.elf64.config.json ├── tests ├── template.html └── generate.py ├── test_gen_config.py ├── test_gen_case.py ├── README.md └── test_gen_cases_batch.py /.gitignore: -------------------------------------------------------------------------------- 1 | /ida/ 2 | -------------------------------------------------------------------------------- /arm/libcms.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libcms.so -------------------------------------------------------------------------------- /arm/libdu.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libdu.so -------------------------------------------------------------------------------- /arm/libdexvmp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libdexvmp.so -------------------------------------------------------------------------------- /arm/libsecsdk.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libsecsdk.so -------------------------------------------------------------------------------- /arm64/libvdog.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm64/libvdog.so -------------------------------------------------------------------------------- /x86/libdexvmp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/x86/libdexvmp.so -------------------------------------------------------------------------------- /arm/libSecShell.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libSecShell.so -------------------------------------------------------------------------------- /arm/libcompatible.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libcompatible.so -------------------------------------------------------------------------------- /arm/libmetasec_ml.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libmetasec_ml.so -------------------------------------------------------------------------------- /arm/libnative-lib.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm/libnative-lib.so -------------------------------------------------------------------------------- /arm64/cff-arm64-v8a.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm64/cff-arm64-v8a.elf -------------------------------------------------------------------------------- /arm64/libcompatible.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm64/libcompatible.so -------------------------------------------------------------------------------- /arm64/libnative-lib.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/arm64/libnative-lib.so -------------------------------------------------------------------------------- /x86/libcompatible_x86.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/x86/libcompatible_x86.so -------------------------------------------------------------------------------- /x86/libshellx-super.2019.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/x86/libshellx-super.2019.so -------------------------------------------------------------------------------- /x86_64/libcompatible_x86.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/x86_64/libcompatible_x86.so -------------------------------------------------------------------------------- /x86_64/demo-control-flow-flatten.elf64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obpo-project/samples/HEAD/x86_64/demo-control-flow-flatten.elf64 -------------------------------------------------------------------------------- /arm/libnative-lib.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 1872, 4 | "filename": "libnative-lib.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 2064 12 | ] 13 | } 14 | ] -------------------------------------------------------------------------------- /arm64/cff-arm64-v8a.elf.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 1688, 4 | "filename": "cff-arm64-v8a.elf", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 64, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 1896 12 | ] 13 | } 14 | ] -------------------------------------------------------------------------------- /arm64/libcompatible.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 1512580, 4 | "filename": "libcompatible.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 64, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 1513484 12 | ] 13 | } 14 | ] -------------------------------------------------------------------------------- /x86_64/demo-control-flow-flatten.elf64.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 4195536, 4 | "filename": "demo-control-flow-flatten.elf64", 5 | "maturity": 5, 6 | "arch": "metapc", 7 | "bit": 64, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 4195584 12 | ] 13 | } 14 | ] -------------------------------------------------------------------------------- /arm64/libvdog.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 528392, 4 | "filename": "libvdog.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 64, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 532036, 12 | 531556, 13 | 535364, 14 | 531400, 15 | 530504, 16 | 529768, 17 | 528620, 18 | 532556, 19 | 531824, 20 | 533556, 21 | 534680, 22 | 528828 23 | ] 24 | } 25 | ] -------------------------------------------------------------------------------- /tests/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | {BODY} 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /x86/libcompatible_x86.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 1514176, 4 | "filename": "libcompatible_x86.so", 5 | "maturity": 5, 6 | "arch": "metapc", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 1515824, 12 | 1514668 13 | ] 14 | }, 15 | { 16 | "func": 856512, 17 | "filename": "libcompatible_x86.so", 18 | "maturity": 5, 19 | "arch": "metapc", 20 | "bit": 32, 21 | "is_be": false, 22 | "t": [], 23 | "dispatchers": [ 24 | 857936, 25 | 859712 26 | ] 27 | } 28 | ] -------------------------------------------------------------------------------- /arm/libdu.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 138800, 4 | "filename": "libdu.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [ 10 | 138800 11 | ], 12 | "dispatchers": [ 13 | 139250, 14 | 139134 15 | ] 16 | }, 17 | { 18 | "func": 131452, 19 | "filename": "libdu.so", 20 | "maturity": 5, 21 | "arch": "ARM", 22 | "bit": 32, 23 | "is_be": false, 24 | "t": [ 25 | 131452 26 | ], 27 | "dispatchers": [ 28 | 132222 29 | ] 30 | } 31 | ] -------------------------------------------------------------------------------- /test_gen_config.py: -------------------------------------------------------------------------------- 1 | # Author: hluwa 2 | # HomePage: https://github.com/hluwa 3 | # CreateTime: 2022/3/26 4 | import json 5 | 6 | from idaapi import * 7 | from obpoplugin.manager import mark_manager_instance 8 | from obpoplugin.process import generate_microcode, prepare_request, _backup_calls 9 | 10 | ea = get_screen_ea() 11 | file_name = get_root_filename() 12 | func_name = get_func_name(ea) 13 | 14 | func = get_func(ea) 15 | mba = generate_microcode(func) 16 | _backup_calls(mba) 17 | 18 | data = prepare_request(mba, mark_manager_instance().func_marked(ea)) 19 | data = json.loads(data) 20 | 21 | print(json.dumps({ 22 | "func": list(map(int, data["func"].keys()))[0], 23 | "maturity": data["maturity"], 24 | "filename": file_name, 25 | "arch": data["arch"], 26 | "t": data["t"], 27 | "bit": data["bit"], 28 | "is_be": data["is_be"], 29 | "dispatchers": data["dispatchers"] 30 | }, sort_keys=False, indent=4, separators=(', ', ': '))) 31 | -------------------------------------------------------------------------------- /arm/libSecShell.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 129084, 4 | "filename": "libSecShell.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [ 10 | 129084 11 | ], 12 | "dispatchers": [ 13 | 129152 14 | ] 15 | }, 16 | { 17 | "func": 260586, 18 | "filename": "libSecShell.so", 19 | "maturity": 5, 20 | "arch": "ARM", 21 | "bit": 32, 22 | "is_be": false, 23 | "t": [ 24 | 260586 25 | ], 26 | "dispatchers": [ 27 | 260626 28 | ] 29 | }, 30 | { 31 | "func": 57432, 32 | "filename": "libSecShell.so", 33 | "maturity": 5, 34 | "arch": "ARM", 35 | "bit": 32, 36 | "is_be": false, 37 | "t": [ 38 | 57432 39 | ], 40 | "dispatchers": [ 41 | 57458 42 | ] 43 | }, 44 | { 45 | "func": 60064, 46 | "filename": "libSecShell.so", 47 | "maturity": 5, 48 | "arch": "ARM", 49 | "bit": 32, 50 | "is_be": false, 51 | "t": [ 52 | 60064 53 | ], 54 | "dispatchers": [ 55 | 60098 56 | ] 57 | } 58 | ] -------------------------------------------------------------------------------- /test_gen_case.py: -------------------------------------------------------------------------------- 1 | # Author: hluwa 2 | # HomePage: https://github.com/hluwa 3 | # CreateTime: 2022/3/26 4 | import json 5 | 6 | from idaapi import * 7 | from obpo.analysis.dispatcher import DispatchAnalyzer 8 | from obpo.analysis.pathfinder import FlowFinder 9 | from obpoplugin.manager import mark_manager_instance 10 | from obpoplugin.process import generate_microcode, prepare_request, _backup_calls 11 | 12 | 13 | def inst_info_str(i): 14 | return "{}. {}".format(i.blk.serial, i.topins.dstr()) 15 | 16 | 17 | ea = get_screen_ea() 18 | file_name = get_root_filename() 19 | func_name = get_func_name(ea) 20 | 21 | func = get_func(ea) 22 | mba = generate_microcode(func) 23 | _backup_calls(mba) 24 | 25 | data = prepare_request(mba, mark_manager_instance().func_marked(ea)) 26 | data = json.loads(data) 27 | 28 | out_name = "mba-{}-{}{}-{}.json".format(file_name, data["arch"], data["bit"], func_name) 29 | analyzer = DispatchAnalyzer(mba=mba) 30 | for m in mark_manager_instance().func_marked(ea): 31 | analyzer.mark_dispatcher(m) 32 | analyzer.run() 33 | data.update(analyzer.data()) 34 | 35 | finder = FlowFinder(analyzer) 36 | finder.run() 37 | data.update(finder.data()) 38 | 39 | out_path = os.path.join(os.path.dirname(__file__), "tests", "testres", out_name) 40 | with open(out_path, 'w') as out: 41 | out.write(json.dumps(data)) 42 | -------------------------------------------------------------------------------- /arm/libsecsdk.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 109048, 4 | "filename": "libsecsdk.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 109260 12 | ] 13 | }, 14 | { 15 | "func": 131816, 16 | "filename": "libsecsdk.so", 17 | "maturity": 5, 18 | "arch": "ARM", 19 | "bit": 32, 20 | "is_be": false, 21 | "t": [], 22 | "dispatchers": [ 23 | 131956 24 | ] 25 | }, 26 | { 27 | "func": 144392, 28 | "filename": "libsecsdk.so", 29 | "maturity": 5, 30 | "arch": "ARM", 31 | "bit": 32, 32 | "is_be": false, 33 | "t": [], 34 | "dispatchers": [ 35 | 144692 36 | ] 37 | }, 38 | { 39 | "func": 423708, 40 | "filename": "libsecsdk.so", 41 | "maturity": 5, 42 | "arch": "ARM", 43 | "bit": 32, 44 | "is_be": false, 45 | "t": [], 46 | "dispatchers": [ 47 | 423864 48 | ] 49 | }, 50 | { 51 | "func": 437540, 52 | "filename": "libsecsdk.so", 53 | "maturity": 5, 54 | "arch": "ARM", 55 | "bit": 32, 56 | "is_be": false, 57 | "t": [], 58 | "dispatchers": [ 59 | 437728 60 | ] 61 | } 62 | ] -------------------------------------------------------------------------------- /tests/generate.py: -------------------------------------------------------------------------------- 1 | # Author: hluwa 2 | # HomePage: https://github.com/hluwa 3 | # CreateTime: 2022/3/27 4 | import asyncio 5 | import os 6 | 7 | from pyppeteer import launch 8 | 9 | DIRNAME = os.path.dirname(__file__) 10 | TEMPLATE = open(os.path.join(DIRNAME, "template.html")).read() 11 | 12 | 13 | async def generate_png(html, png): 14 | browser = await launch() 15 | page = await browser.newPage() 16 | await page.goto("file://" + html) 17 | await page.screenshot({'path': png, 'fullPage': True}) 18 | await browser.close() 19 | 20 | 21 | if __name__ == "__main__": 22 | for dir in os.listdir(DIRNAME): 23 | dir = os.path.join(DIRNAME, dir) 24 | if not os.path.isdir(dir): continue 25 | 26 | files = [f for f in os.listdir(dir) if f.endswith(".c")] 27 | width = int(100 / len(files)) 28 | body = "" 29 | for f in files: 30 | body += """\ 31 |
32 |

{}

33 |

34 | {}
35 | 
36 |
""".format(width, f, open(os.path.join(dir, f)).read()) 37 | with open(os.path.join(dir, "compare.html"), 'w') as htmlout: 38 | htmlout.write(TEMPLATE.replace("{BODY}", body)) 39 | asyncio.get_event_loop().run_until_complete( 40 | generate_png(os.path.join(dir, "compare.html"), os.path.join(dir, "compare.png"))) 41 | 42 | with open(os.path.join(dir, "README.md"), 'w') as mdout: 43 | mdout.write("![](compare.png)") 44 | -------------------------------------------------------------------------------- /arm/libcompatible.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 1462816, 4 | "filename": "libcompatible.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 1463208, 12 | 1463564 13 | ] 14 | }, 15 | { 16 | "func": 847484, 17 | "filename": "libcompatible.so", 18 | "maturity": 5, 19 | "arch": "ARM", 20 | "bit": 32, 21 | "is_be": false, 22 | "t": [], 23 | "dispatchers": [ 24 | 848804 25 | ] 26 | }, 27 | { 28 | "func": 850108, 29 | "filename": "libcompatible.so", 30 | "maturity": 5, 31 | "arch": "ARM", 32 | "bit": 32, 33 | "is_be": false, 34 | "t": [], 35 | "dispatchers": [ 36 | 851220 37 | ] 38 | }, 39 | { 40 | "func": 899992, 41 | "filename": "libcompatible.so", 42 | "maturity": 5, 43 | "arch": "ARM", 44 | "bit": 32, 45 | "is_be": false, 46 | "t": [], 47 | "dispatchers": [ 48 | 900916 49 | ] 50 | }, 51 | { 52 | "func": 905864, 53 | "filename": "libcompatible.so", 54 | "maturity": 5, 55 | "arch": "ARM", 56 | "bit": 32, 57 | "is_be": false, 58 | "t": [], 59 | "dispatchers": [ 60 | 906348 61 | ] 62 | } 63 | ] -------------------------------------------------------------------------------- /x86/libshellx-super.2019.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 9680, 4 | "filename": "libshellx-super.2019.so", 5 | "maturity": 5, 6 | "arch": "metapc", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 10112 12 | ] 13 | }, 14 | { 15 | "func": 133616, 16 | "filename": "libshellx-super.2019.so", 17 | "maturity": 5, 18 | "arch": "metapc", 19 | "bit": 32, 20 | "is_be": false, 21 | "t": [], 22 | "dispatchers": [ 23 | 133808 24 | ] 25 | }, 26 | { 27 | "func": 191424, 28 | "filename": "libshellx-super.2019.so", 29 | "maturity": 5, 30 | "arch": "metapc", 31 | "bit": 32, 32 | "is_be": false, 33 | "t": [], 34 | "dispatchers": [ 35 | 193168 36 | ] 37 | }, 38 | { 39 | "func": 208080, 40 | "filename": "libshellx-super.2019.so", 41 | "maturity": 5, 42 | "arch": "metapc", 43 | "bit": 32, 44 | "is_be": false, 45 | "t": [], 46 | "dispatchers": [ 47 | 208192, 48 | 212544 49 | ] 50 | }, 51 | { 52 | "func": 229632, 53 | "filename": "libshellx-super.2019.so", 54 | "maturity": 5, 55 | "arch": "metapc", 56 | "bit": 32, 57 | "is_be": false, 58 | "t": [], 59 | "dispatchers": [ 60 | 229776 61 | ] 62 | } 63 | ] -------------------------------------------------------------------------------- /arm64/libnative-lib.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 73860, 4 | "filename": "libnative-lib.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 64, 8 | "is_be": false, 9 | "t": [], 10 | "dispatchers": [ 11 | 75776, 12 | 75524, 13 | 75156, 14 | 74776, 15 | 75044, 16 | 75436, 17 | 76332, 18 | 74164, 19 | 75956, 20 | 74676, 21 | 75708, 22 | 75208, 23 | 75352, 24 | 76128, 25 | 76260, 26 | 75624, 27 | 76396, 28 | 74992, 29 | 74864, 30 | 75892, 31 | 76020, 32 | 74612 33 | ] 34 | }, 35 | { 36 | "func": 94908, 37 | "filename": "libnative-lib.so", 38 | "maturity": 5, 39 | "arch": "ARM", 40 | "bit": 64, 41 | "is_be": false, 42 | "t": [], 43 | "dispatchers": [ 44 | 97536, 45 | 97928, 46 | 96912, 47 | 96400, 48 | 97296, 49 | 96664, 50 | 97700, 51 | 95780, 52 | 97448, 53 | 96812, 54 | 95920, 55 | 95668, 56 | 97144, 57 | 97080, 58 | 96576, 59 | 95180, 60 | 98124, 61 | 97360, 62 | 96348, 63 | 97244, 64 | 97768, 65 | 95592, 66 | 96492, 67 | 95856, 68 | 97648, 69 | 95732, 70 | 96760, 71 | 97020 72 | ] 73 | } 74 | ] -------------------------------------------------------------------------------- /arm/libmetasec_ml.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 205340, 4 | "filename": "libmetasec_ml.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [ 10 | 205340 11 | ], 12 | "dispatchers": [ 13 | 205994 14 | ] 15 | }, 16 | { 17 | "func": 307568, 18 | "filename": "libmetasec_ml.so", 19 | "maturity": 5, 20 | "arch": "ARM", 21 | "bit": 32, 22 | "is_be": false, 23 | "t": [ 24 | 307568, 25 | 308358, 26 | 308656, 27 | 308708, 28 | 308794, 29 | 308834, 30 | 309058, 31 | 309172, 32 | 309230, 33 | 309614, 34 | 309714, 35 | 309812, 36 | 310188, 37 | 310434 38 | ], 39 | "dispatchers": [ 40 | 307740 41 | ] 42 | }, 43 | { 44 | "func": 371920, 45 | "filename": "libmetasec_ml.so", 46 | "maturity": 5, 47 | "arch": "ARM", 48 | "bit": 32, 49 | "is_be": false, 50 | "t": [ 51 | 371920, 52 | 373288, 53 | 373426, 54 | 373530, 55 | 373672, 56 | 374176, 57 | 374302, 58 | 374566, 59 | 375388 60 | ], 61 | "dispatchers": [ 62 | 376118 63 | ] 64 | }, 65 | { 66 | "func": 378596, 67 | "filename": "libmetasec_ml.so", 68 | "maturity": 5, 69 | "arch": "ARM", 70 | "bit": 32, 71 | "is_be": false, 72 | "t": [ 73 | 378596 74 | ], 75 | "dispatchers": [ 76 | 380778 77 | ] 78 | } 79 | ] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | | ARCH | NAME | SOURCE | DESC | OBPO SUPPORT | 2 | | ---- | ---- | ------ | ---- | ------------ | 3 | | arm | [libcms.so](arm/libcms.so) | [maiyao1988/deobf](https://github.com/maiyao1988/deobf/blob/master/tests/bin/libcms.so) | | YES | 4 | | arm | [libdu.so](arm/libdu.so) | shuzilm | From memory dump | Partial | 5 | | arm | [libsecsdk.so](arm/libsecsdk.so) | msa | | YES | 6 | | arm | [libSecShell.so](arm/libSecShell.so) | [maiyao1988/deobf](https://github.com/maiyao1988/deobf/blob/master/tests/bin/libSecShell.so) | | YES | 7 | | arm | [libcompatible.so](arm/libcompatible.so) | [nProtect AppGuard](https://appguard.nprotect.com/) | | YES | 8 | | arm | [libdexvmp.so](arm/libdexvmp.so) | secneo | | Partial | 9 | | arm | [libnative-lib.so](arm/libnative-lib.so) | * | [GoSSIP-SJTU/Armariris](https://github.com/GoSSIP-SJTU/Armariris) | YES | 10 | | arm | [libmetasec_ml.so](arm/libmetasec_ml.so) | * | | YES | 11 | | arm64 | [libvdog.so](arm64/libvdog.so) | [amimo/ollvm-breaker](https://github.com/amimo/ollvm-breaker/blob/master/tests/libvdog.so) | | YES | 12 | | arm64 | [cff-arm64-v8a.elf](arm64/cff-arm64-v8a.elf) | [amimo/ollvm-breaker](https://github.com/amimo/ollvm-breaker/blob/master/tests/cff-arm64-v8a.elf) | | YES | 13 | | arm64 | [libnative-lib.so](arm64/libnative-lib.so) | [sanfengAndroid/AntiOllvm](https://github.com/sanfengAndroid/AntiOllvm/blob/main/Arm64Test/kanxueOllvm/bin/libnative-lib.so) | | YES | 14 | | arm64 | [libcompatible.so](arm64/libcompatible.so) | [nProtect AppGuard](https://appguard.nprotect.com/) | | YES | 15 | | x86 | [libshellx-super.2019.so](x86/libshellx-super.2019.so) | [PShocker/de-ollvm](https://github.com/PShocker/de-ollvm/blob/main/sample/libshellx-super.2019.so) | | YES | 16 | | x86 | [libcompatible_x86.so](x86/libcompatible_x86.so) | [nProtect AppGuard](https://appguard.nprotect.com/) | | YES | 17 | | x86 | [libdexvmp.so](x86/libdexvmp.so) | secneo | | NO | 18 | | x86_64 | [demo-control-flow-flatten.elf64](x86_64/demo-control-flow-flatten.elf64) | [amimo/goron](https://github.com/amimo/goron/blob/master/examples/demo-control-flow-flatten.elf64) | Interprocedural Flattening | YES, NEED [IDABeautify](https://github.com/P4nda0s/IDABeautify) | 19 | | x86_64 | [libcompatible_x86.so](x86_64/libcompatible_x86.so) | [nProtect AppGuard](https://appguard.nprotect.com/) | | YES | -------------------------------------------------------------------------------- /arm/libcms.so.config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "func": 496684, 4 | "filename": "libcms.so", 5 | "maturity": 5, 6 | "arch": "ARM", 7 | "bit": 32, 8 | "is_be": false, 9 | "t": [ 10 | 496684 11 | ], 12 | "dispatchers": [ 13 | 510582 14 | ] 15 | }, 16 | { 17 | "func": 468528, 18 | "filename": "libcms.so", 19 | "maturity": 5, 20 | "arch": "ARM", 21 | "bit": 32, 22 | "is_be": false, 23 | "t": [ 24 | 468528 25 | ], 26 | "dispatchers": [ 27 | 481024 28 | ] 29 | }, 30 | { 31 | "func": 569396, 32 | "filename": "libcms.so", 33 | "maturity": 5, 34 | "arch": "ARM", 35 | "bit": 32, 36 | "is_be": false, 37 | "t": [ 38 | 569396 39 | ], 40 | "dispatchers": [ 41 | 579236, 42 | 578986, 43 | 579466, 44 | 569548, 45 | 576716, 46 | 575288, 47 | 576028 48 | ] 49 | }, 50 | { 51 | "func": 675640, 52 | "filename": "libcms.so", 53 | "maturity": 5, 54 | "arch": "ARM", 55 | "bit": 32, 56 | "is_be": false, 57 | "t": [ 58 | 675640 59 | ], 60 | "dispatchers": [ 61 | 681636, 62 | 681092, 63 | 685316, 64 | 685764, 65 | 684872, 66 | 686792, 67 | 685900, 68 | 686290, 69 | 682584, 70 | 675804 71 | ] 72 | }, 73 | { 74 | "func": 710044, 75 | "filename": "libcms.so", 76 | "maturity": 5, 77 | "arch": "ARM", 78 | "bit": 32, 79 | "is_be": false, 80 | "t": [ 81 | 710044 82 | ], 83 | "dispatchers": [ 84 | 710196 85 | ] 86 | }, 87 | { 88 | "func": 734564, 89 | "filename": "libcms.so", 90 | "maturity": 5, 91 | "arch": "ARM", 92 | "bit": 32, 93 | "is_be": false, 94 | "t": [ 95 | 734564 96 | ], 97 | "dispatchers": [ 98 | 734752 99 | ] 100 | } 101 | ] -------------------------------------------------------------------------------- /test_gen_cases_batch.py: -------------------------------------------------------------------------------- 1 | # Author: hluwa 2 | # HomePage: https://github.com/hluwa 3 | # CreateTime: 2022/3/26 4 | import os 5 | import json 6 | 7 | 8 | def inst_info_str(i): 9 | return "{}. {}".format(i.blk.serial, i.topins.dstr()) 10 | 11 | 12 | def ida_entry(): 13 | import idaapi 14 | import idc 15 | from ida_segregs import SR_user 16 | from obpo.analysis.dispatcher import DispatchAnalyzer 17 | from obpo.analysis.pathfinder import FlowFinder 18 | from obpoplugin.manager import mark_manager_instance 19 | from obpoplugin.process import generate_microcode, prepare_request, _backup_calls 20 | 21 | idaapi.auto_wait() 22 | 23 | CONFIG_PATH = idaapi.get_input_file_path() + ".config.json" 24 | config = json.loads(open(CONFIG_PATH).read()) 25 | for c in config: 26 | for ea in c["t"]: 27 | ea &= ~1 28 | idc.split_sreg_range(ea, "T", 1, SR_user) 29 | ea = c["func"] 30 | idaapi.auto_make_code(ea) 31 | idaapi.auto_wait() 32 | 33 | file_name = c["filename"] 34 | 35 | _ = list(map(mark_manager_instance().mark, c["dispatchers"])) 36 | 37 | before = idaapi.decompile(ea) 38 | 39 | func = idaapi.get_func(ea) 40 | mba = generate_microcode(func) 41 | mba.final_type = False 42 | 43 | c_map = _backup_calls(mba) 44 | 45 | data = prepare_request(mba, mark_manager_instance().func_marked(ea)) 46 | data = json.loads(data) 47 | 48 | analyzer = DispatchAnalyzer(mba=mba) 49 | for m in mark_manager_instance().func_marked(ea): analyzer.mark_dispatcher(m) 50 | analyzer.run() 51 | data.update(analyzer.data()) 52 | 53 | finder = FlowFinder(analyzer) 54 | finder.run() 55 | data.update(finder.data()) 56 | from obpo.patch.deoptimizer import SplitCommonPatcher 57 | from obpo.patch.link import FlowPatcher 58 | from obpo.idahelper import visit_blocks 59 | from obpoplugin.process import _fixup_calls 60 | from obpoplugin.process import MBAFixup 61 | from obpoplugin.manager import mba_manager_instance 62 | SplitCommonPatcher(finder).run() 63 | mba.build_graph() 64 | patcher = FlowPatcher(analyzer) 65 | for edge, flows in finder.edge4flows().items(): 66 | patcher.run(edge, flows) 67 | 68 | # Clear graph to bypass verify mba 69 | for b in visit_blocks(mba): 70 | if b.type in [idaapi.BLT_STOP, idaapi.BLT_XTRN] or b.serial == 0: continue 71 | b.type = idaapi.BLT_NONE 72 | b.mark_lists_dirty() 73 | 74 | _fixup_calls(mba, c_map) 75 | MBAFixup(mba).run() 76 | 77 | mba_manager_instance().cache(mba) 78 | 79 | after = idaapi.decompile(ea, flags=idaapi.DECOMP_NO_CACHE) 80 | 81 | out_name = "{}-{}{}-{}".format(file_name, data["arch"], data["bit"], hex(ea)) 82 | out_path = idaapi.os.path.join(idaapi.os.path.dirname(__file__), "tests", out_name) 83 | os.makedirs(out_path, exist_ok=True) 84 | with open(os.path.join(out_path, out_name + ".json"), 'w') as out: 85 | out.write(json.dumps(data)) 86 | with open(os.path.join(out_path, "original.c"), 'w') as original: 87 | original.write(str(before)) 88 | with open(os.path.join(out_path, "original_obpo.c"), 'w') as original: 89 | original.write(str(after)) 90 | exit() 91 | 92 | 93 | def python_entry(): 94 | import threadpool 95 | 96 | pool = threadpool.ThreadPool(num_workers=64) 97 | idapath = os.getenv("IDAPATH") 98 | 99 | if not idapath or not os.path.exists(idapath): 100 | idapath = os.path.join(os.path.dirname(__file__), "ida") 101 | if not os.path.exists(idapath): 102 | print("cannot found ida, exiting...") 103 | exit() 104 | 105 | all_arch = ["arm", "arm64", "x86", "x86_64"] 106 | 107 | def runnable(target): 108 | os.system("{} -A -S{} {}".format( 109 | os.path.join(idapath, "ida64" if "64" in arch else "ida"), __file__, target)) 110 | print("{} -A -S{} {}".format( 111 | os.path.join(idapath, "ida64" if "64" in arch else "ida"), __file__, target)) 112 | 113 | def clear(): 114 | for a in all_arch: 115 | d = os.path.join(os.path.dirname(__file__), a) 116 | for f in os.listdir(d): 117 | if f.endswith(".id0") \ 118 | or f.endswith(".id1") \ 119 | or f.endswith(".id2") \ 120 | or f.endswith(".idb") \ 121 | or f.endswith(".nam") \ 122 | or f.endswith(".til") \ 123 | or f.endswith(".i64"): 124 | os.remove(os.path.join(d, f)) 125 | 126 | clear() 127 | for arch in all_arch: 128 | bin_dir = os.path.join(os.path.dirname(__file__), arch) 129 | for file in os.listdir(bin_dir): 130 | if not file.endswith(".config.json"): continue 131 | 132 | bin_file = os.path.join(bin_dir, file.removesuffix(".config.json")) 133 | if not os.path.exists(bin_file): 134 | print("missing binary {}".format(bin_file)) 135 | continue 136 | 137 | pool.putRequest(threadpool.WorkRequest(runnable, [bin_file])) 138 | pool.wait() 139 | clear() 140 | 141 | 142 | def is_idapython(): 143 | try: 144 | import idaapi 145 | return True 146 | except: 147 | return False 148 | 149 | 150 | if is_idapython(): 151 | try: 152 | ida_entry() 153 | except: 154 | exit() 155 | else: 156 | python_entry() 157 | --------------------------------------------------------------------------------