├── .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("")
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 |
--------------------------------------------------------------------------------