예제 #1
0
    def show_risk_code(self, level):
        result = Color.red('===== Risk Codes =====\n')
        for k, v in RISKS.items():
            if v['lvl'] < level:
                continue
            kflag = True
            for sf in self.smali_dir:
                for mtd in sf.get_methods():
                    mflag = True
                    lines = re.split(r'\n\s*', mtd.get_body())
                    for idx, line in enumerate(lines):
                        for ptn in v['code']:
                            if re.search(ptn, line):
                                if kflag:
                                    result += Color.magenta('---' +
                                                            k + '---\n')
                                    kflag = False
                                if mflag:
                                    result += Color.green(' ' +
                                                          str(mtd)) + '\n'
                                    mflag = False
                                result += ' ' * 3 + str(idx) + line + '\n'
                                break

        return result
예제 #2
0
    def _process_mtd(self, mtd, ptn):
        # if get_value('DEBUG_MODE'):
        print('\n', '+' * 100)
        print('Starting to decode ...')
        print(Color.green(mtd))

        body = mtd.get_body()

        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            arg_pos, cname, mname, rtn_name = item.groups()
            cname = cname[1:].replace('/', '.')
            # 通过参数位置获取参数值
            rex = arg_pos + '\s*.array-data 1([\w\W\s]+?).end array-data'
            ptn_arr = re.compile(rex, re.MULTILINE)
            bjson = []
            for it in ptn_arr.finditer(body):
                arr = it.groups()
                for i in arr[0].split("\n"):
                    i = i.strip()
                    if i == "":
                        continue
                    bjson.append(int(i.replace('t', ''), 16))
            arguments = ['[B:' + str(bjson)]
            print(Color.green(cname) + " " + str(arguments))
            json_item = self.get_json_item(cname, mname, arguments)
            self.append_json_item(json_item, mtd, old_content, rtn_name)
예제 #3
0
def test_keep_tags():
    """Test keep_tags keyword arg."""
    assert_both = partial(assert_both_values, kind="Color color")

    instance = Color("{red}Test{/red}", keep_tags=True)
    assert_both(instance, "{red}Test{/red}", "{red}Test{/red}")
    assert_both(instance.upper(), "{RED}TEST{/RED}", "{RED}TEST{/RED}")
    assert len(instance) == 15

    instance = Color("{red}\033[41mTest\033[49m{/red}", keep_tags=True)
    assert_both(instance, "{red}Test{/red}", "{red}\033[41mTest\033[49m{/red}")
    assert_both(instance.upper(), "{RED}TEST{/RED}", "{RED}\033[41mTEST\033[49m{/RED}")
    assert len(instance) == 15
예제 #4
0
    def _process_mtd(self, mtd, ptn):
        if DEBUG_MODE:
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()

        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            # arg: 解密参数
            # cname:解密类
            # mname:解密方法
            # rtn_name:最后返回的字符串寄存器,new String的寄存器名字
            arg, cname, mname, rtn_name = item.groups()
            # 转化解密参数
            arguments = [self.convert_args('Ljava/lang/String;', arg)]
            import smafile

            cname = smafile.smali2java(cname)

            json_item = self.get_json_item(cname, mname, arguments)

            mid = json_item['id']
            self.append_json_item(json_item, mtd, old_content, rtn_name)

            if mid in self.results:  # 如果同样的ID存在,那么无需解密
                continue
            self.decode(mid)
예제 #5
0
 def process_item(item):
     text = ''
     perm = item.get('@android:permission', '')
     if '_DEVICE' not in perm:
         return text
     if pflag:
         text += Color.red('===== Risk Permissions =====\n')
     text += perm + item.get('@android:name') + '\n'
예제 #6
0
    def show_risk_perm(self):
        result = ''
        if not self.apk.get_manifest():
            return result
        risk_perms = [
            '_SMS',
            '_CALL',
            '_DEVICE_ADMIN',
            '_AUDIO',
            '_CONTACTS'
        ]
        ps = set()
        pflag = True
        for item in self.apk.get_manifest().get('uses-permission', []):
            for perm in risk_perms:
                if perm not in item.get('@android:name'):
                    continue

                if pflag:
                    result += Color.red('===== Risk Permissions =====\n')
                    pflag = False

                name = item.get('@android:name')
                if name in ps:
                    continue
                result += name + '\n'
                ps.add(name)

        app = self.apk.get_manifest().get('application')
        recs = app.get('receiver')

        def process_item(item):
            text = ''
            perm = item.get('@android:permission', '')
            if '_DEVICE' not in perm:
                return text
            if pflag:
                text += Color.red('===== Risk Permissions =====\n')
            text += perm + item.get('@android:name') + '\n'

        if isinstance(recs, dict):
            text = process_item(item)
            if text:
                result += text
                pflag = False
        elif isinstance(recs, list):
            for item in recs:
                text = process_item(item)
                if text:
                    result += text
                    pflag = False
                    break

        if not pflag:
            result += '\n'

        return result
예제 #7
0
    def _process_mtd(self, mtd, ptn):
        if DEBUG_MODE:
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()
        # TODO 优化,根据每列来匹配
        # 执行之前,没有返回值,赋值等操作的语句,执行,其他都不执行。
        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            # print(old_content)
            # args: 解密参数
            # cname:解密类
            # mname:解密方法
            # rtn_name:最后返回的字符串寄存器,new String的寄存器名字
            part, args, cname, mname, rtn_name = item.groups()
            snippet = part.split('\n')
            tmp = []
            for item in snippet:
                if not item:
                    continue
                if ':try_start' in item:
                    # print(old_content)
                    old_content = old_content.split(item)
                    # print(old_content)
                    tmp.clear()
                tmp.append(item.strip())
            # print(old_content)
            # print(tmp)
            # 模拟执行代码片段
            # continue
            self.emu.call(tmp, args=self.global_variables, cv=True, thrown=True)

            # 转化解密参数
            ans = self.argument_names(args)
            v1 = self.emu.vm.variables.get(ans[0], None)
            v2 = self.emu.vm.variables.get(ans[1], None)
            v3 = self.emu.vm.variables.get(ans[2], None)
            if v1 is None or v2 is None or v3 is None:
                continue
            arguments = [self.convert_args('S', v1), self.convert_args('I', v2), self.convert_args('S', v3)]

            import smafile
            cname = smafile.smali2java(cname)
            json_item = self.get_json_item(cname, mname, arguments)

            mid = json_item['id']

            if mid in self.results:  # 如果同样的ID存在,那么无需解密
                continue

            self.append_json_item(json_item, mtd, old_content, rtn_name)
            self.decode(mid)
예제 #8
0
    def proccess(self):
        for sf in self.smalidir:
            for mtd in sf.get_methods():
                if 'Lcom/cmcc/papp/a/a;->b(Context, String)V' not in str(mtd):
                    continue

                if DEBUG:
                    from colorclass.color import Color
                    print()
                    print(Color.red(str(mtd)))
                
                self._process_mtd(mtd)
            self.optimize()
            self.clear()
예제 #9
0
    def _process_mtd(self, mtd, ptn):
        if DEBUG_MODE:
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()
        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            print(old_content)
            # args: 解密参数
            # cname:解密类
            # mname:解密方法
            # rtn_name:最后返回的字符串寄存器,new String的寄存器名字
            part, args, cname, mname, rtn_name = item.groups()
            snippet = part.split('\n\n')

            # TODO 自动初始化,静态变量,静态数组等等。后续用于片段计算,用到。

            # TODO 模拟执行代码片段
            self.emu.call(snippet,
                          args={'Lo/r/g/ন$Ⅱ;->ᖬ:I': 0},
                          cv=True,
                          thrown=True)

            # 转化解密参数
            ans = self.argument_names(args)
            v1 = self.emu.vm.variables.get(ans[0], None)
            v2 = self.emu.vm.variables.get(ans[1], None)
            v3 = self.emu.vm.variables.get(ans[2], None)
            if v1 is None or v2 is None or v3 is None:
                continue
            arguments = [
                self.convert_args('I', v1),
                self.convert_args('I', v2),
                self.convert_args('I', v3)
            ]

            import smafile
            cname = smafile.smali2java(cname)
            json_item = self.get_json_item(cname, mname, arguments)

            mid = json_item['id']
            self.append_json_item(json_item, mtd, old_content, rtn_name)

            if mid in self.results:  # 如果同样的ID存在,那么无需解密
                self.json_list.clear()
                continue

            self.decode(mid)
예제 #10
0
        def process_perm_item(item):
            for perm in risk_perms:
                if perm not in item.get('@android:name'):
                    continue

                if pflag:
                    result += Color.red('===== Risk Permissions =====\n')
                    pflag = False

                name = item.get('@android:name')
                if name in ps:
                    continue
                result += name + '\n'
                ps.add(name)
예제 #11
0
파일: ht1021.py 프로젝트: 5l1v3r1/dexsim
    def _process_mtd(self, mtd, ptn):
        if get_value('DEBUG_MODE'):
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()

        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            arg, cname, mname, rtn_name = item.groups()
            arguments = ['java.lang.String:' + arg]
            json_item = self.get_json_item(cname, mname, arguments)
            self.append_json_item(json_item, mtd, old_content, rtn_name)
예제 #12
0
파일: f79c49.py 프로젝트: CKCat/dexsim
    def _process_mtd(self, mtd, ptn):
        if get_value('DEBUG_MODE'):
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()

        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            # base解密的字符串,base64解密
            # 得到结果再次解密,
            # rtn_name:最后返回的字符串寄存器,new String的寄存器名字
            arg, cname, mname, rtn_name = item.groups()
            # base64解密
            arguments = [self.convert_args('Ljava/lang/String;', arg), 'I:2']
            json_item = self.get_json_item('android.util.Base64', 'decode',
                                           arguments)

            mid = json_item['id']
            self.append_json_item(json_item, mtd, old_content, rtn_name)

            arg0 = None
            if mid not in self.results:  # 如果同样的ID存在,那么无需解密
                self.decode(mid)

            arg0 = self.results[mid]
            old_mid = mid
            # arg1 = 'fmsd1234'  # 这个是一个固定值
            # 解密得到的结果
            # 进行第二次解密
            import smafile
            cname = smafile.smali2java(cname)
            arguments = ['[B:' + arg0, 'java.lang.String:fmsd1234']
            # print(cname, mname, arguments)
            json_item = self.get_json_item(cname, mname, arguments)
            mid = json_item['id']
            self.append_json_item(json_item, mtd, old_content, rtn_name)
            if mid in self.results:
                self.json_list.clear()
                continue
            self.decode(mid)
            x = self.results[mid]
            try:
                result = bytes(eval(x)).decode('utf-8')
                self.results[old_mid] = result
                print(result)
            except Exception as e:
                print(result, e)
예제 #13
0
def print_matches(key_path, match_dict):
    ''' example matches dict
    [{
      'tags': ['foo', 'bar'],
      'matches': True,
      'namespace': 'default',
      'rule': 'my_rule',
      'meta': {},
      'strings': [(81L, '$a', 'abc'), (141L, '$b', 'def')]
    }]
    '''
    print(Color.green("[*] {}".format(key_path)))
    for tags in sorted(match_dict):
        values = ', '.join(sorted(match_dict[tags]))
        print(" |-> {} : {}".format(tags, values))
예제 #14
0
    def __process(self):
        for sf in self.smalidir:
            for mtd in sf.get_methods():
                if DEBUG_MODE:
                    print(mtd)
                # if 'com/android/internal/wrapper/NativeWrapper;->' not in str(mtd):
                #     continue
                # if 'eMPGsXR()Ljava/lang/Class;' not in str(mtd):
                #     continue
                if DEBUG_MODE:
                    print(Color.red(mtd))
                if self.skip_mtd(mtd):
                    continue
                self._process_mtd(mtd)

        # 强制更新
        for sf in self.smalidir:
            sf.update()
예제 #15
0
    def show_risk_children(self, flag=False):
        result = ''
        pflag = True
        self.apk.get_files().sort(key=lambda k: (k.get('type'), k.get('name')))
        for item in self.apk.get_files():
            if flag:
                print(item.get('type'), item.get('name'))
                continue

            if item.get('type') not in ['dex', 'apk', 'elf']:
                continue

            if pflag:
                result = Color.red('\n===== Risk Files =====\n')
                pflag = False

            result += item.get('type') + ' ' + item.get('name') + '\n'

        return result
예제 #16
0
def test_keep_tags():
    """Test keep_tags keyword arg."""
    assert_both = partial(assert_both_values, kind='Color color')

    instance = Color('{red}Test{/red}', keep_tags=True)
    assert_both(instance, '{red}Test{/red}', '{red}Test{/red}')
    assert_both(instance.upper(), '{RED}TEST{/RED}', '{RED}TEST{/RED}')
    assert len(instance) == 15

    instance = Color('{red}\033[41mTest\033[49m{/red}', keep_tags=True)
    assert_both(instance, '{red}Test{/red}', '{red}\033[41mTest\033[49m{/red}')
    assert_both(instance.upper(), '{RED}TEST{/RED}',
                '{RED}\033[41mTEST\033[49m{/RED}')
    assert len(instance) == 15
예제 #17
0
    def _process_mtd(self, mtd):
        if DEBUG:
            from colorclass.color import Color
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        # 如果存在数组
        array_data_content = []
        arr_res = self.arr_data_ptn.search(mtd.get_body())
        if arr_res:
            array_data_content = re.split(r'\n\s', arr_res.group())

        lines = re.split(r'\n\s*', mtd.get_body())

        old_body = lines.copy()  # 存放原始方法体
        new_body = []  # 存放解密后的方法体

        snippet = []  # 存放smali代码,用于模拟执行
        args = {}  # 存放方法参数,用于smaliemu执行

        index = -1  # 用于计数

        for line in lines:
            snippet.append(line)
            new_body.append(line)  # 解密结果,直接放后面即可

            index += 1
            if 'invoke-' not in line and 'iget-' not in line:
                continue

            from smafile import SmaliLine
            # 函数有两种类型:
            # 1. 字符串内置类型 - smaliemu能直接执行
            # 2. 其他类型 - 需要发射调用
            if DEBUG:
                print('LINE:', Color.red(line))

            if 'Ljava/lang/String;->' in line:
                if '<init>' not in line:
                    continue

                if DEBUG:
                    print(Color('{autoyellow}process new string...{/yellow} '))

                # 如果是字符串函数,参数为[B/[C/[I,则考虑
                rtn_name, rnames = SmaliLine.parse_string(line)
                if not rnames:
                    continue

                # 直接执行emu解密
                try:
                    ll = args[rnames[1]]
                    # print(ll)
                except KeyError:
                    continue

                if not isinstance(ll, list):
                    continue

                no_str = False
                for i in ll:
                    if i < 0:
                        no_str = True
                        break
                if no_str:
                    continue

                result = ''.join(chr(x) for x in ll)

                if DEBUG:
                    print(result)

                # 更新寄存器
                args[rtn_name] = result
                # 更新代码
                new_line = 'const-string {}, "{}"'.format(rtn_name, result)
                new_body = new_body[:-1]
                new_body.append(new_line)
                self.make_changes = True
                mtd.set_modified(True)
                continue

            elif 'invoke-static' in line:
                # 获取函数相关信息
                cname, mname, ptypes, rtype, rnames = SmaliLine.parse_invoke_static(
                    line)
                if cname in ['Ljava/lang/reflect/Method;']:
                    print(cname, 'will skip')
                    continue

                # 返回值不能其他引用类型
                if rtype[0] == 'L' and rtype != 'Ljava/lang/String;':
                    continue

                if rtype in ['V', 'Z']:
                    continue

                flagx = False
                for i in [
                        'Landroid/content/Context;', 'Landroid/app/Activity;'
                ]:
                    if i in ptypes:
                        flagx = True
                        break

                if flagx:
                    continue
            elif 'iget-object' in line:
                #  iget-object v3, p0, Lcom/fmsd/a/d;->q:Ljava/lang/String;
                # 这种情况,需要直接通过反射获取
                # clz_name, field_name, rname =
                cname, fname, rtype, rname = SmaliLine.parse_iget_object(line)
                if rtype != 'Ljava/lang/String;':
                    continue

                self.json_list = {'type': 'field', 'data': []}
                json_item = {'className': cname, 'fieldName': [fname]}
                # print(json_item)
                self.json_list['data'].append(json_item)

                result = self.get_field_value()
                if not result:
                    continue
                value = result[fname]
                args[rname] = value
                continue
            else:
                continue
            # print('>', cname)
            # print('>', mname)
            # print('>', ptypes)
            # print('>', rnames)
            # print(">", 'return Type:', rtype)
            # 参数名(寄存器的名),类名,方法名,proto(简称)
            # register_name, class_name, mtd_name, ptypescc
            # ('v1, v2, v3', 'Lcom/game/pay/sdk/y', 'a', 'ISB')
            # 解密参数的寄存器名

            # 初始化所有寄存器
            del snippet[-1]
            snippet.extend(array_data_content)
            try:
                args.update(self.pre_process(snippet))
            except TIMEOUT_EXCEPTION:
                pass

            try:
                # for lx in snippet:
                #     print(lx)
                self.emu.call(snippet, args=args, cv=True, thrown=False)
                registers = self.emu.vm.variables
                # registers = self.get_vm_variables(snippet, args, rnames)
                # print('smali执行后,寄存器内容', registers)
                # args = registers if registers else args
                if registers:
                    for k, v in registers.items():
                        if v is None:
                            continue
                        args[k] = v

                registers = args
            except TIMEOUT_EXCEPTION:
                snippet.clear()

                continue

            # print('更新寄存器内容', args)
            # if not registers:
            #     registers = args

            obj_flag = False
            if len(ptypes) == 1 and ptypes[0][0] == 'L' and ptypes != [
                    'Ljava/lang/String;'
            ]:
                # 单独处理参数为对象的情况
                obj_flag = True

            # 已经执行过的代码,不再执行
            snippet.clear()
            if not registers and not obj_flag:
                continue

            # print('----->>>>>>>>>>')
            # 从寄存器中获取对应的参数
            # 参数获取 "arguments": ["I:198", "I:115", "I:26"]}
            arguments = []
            # args = {}  # the parameter of smali method
            if not obj_flag:
                ridx = -1
                for item in ptypes:
                    ridx += 1
                    rname = rnames[ridx]
                    if rname not in registers:
                        break
                    value = registers[rnames[ridx]]
                    argument = self.convert_args(item, value)
                    if argument is None:
                        break
                    arguments.append(argument)
            else:
                arguments.append('Object:' + self.smali2java(ptypes[0]))

            # print('参数类型', ptypes)
            # print('参数值', arguments)

            if len(arguments) != len(ptypes):

                continue

            json_item = self.get_json_item(cname, mname, arguments)
            # print('生成json item')

            # {id}_{rtn_name} 让这个唯一化,便于替换
            old_content = '# %s' % json_item['id']
            # 如果 move_result_obj 操作存在的话,解密后一起替换
            find = self.move_result_obj_ptn.search(lines[index + 1])

            # 必须要找到返回值操作,用于更新寄存器
            if not find:
                # print('找不到返回寄存器')
                continue

            rtn_name = find.groups()[0]
            # 为了避免 '# abc_v10' 替换成 '# abc_v1'
            old_content = old_content + '_' + rtn_name + 'X'
            self.append_json_item(json_item, mtd, old_content, rtn_name)

            # print(json_item)
            result = self.get_result(rtype)
            # print("解密结果", result)

            self.json_list.clear()

            if result:
                new_body = new_body[:-1]
            else:
                continue

            if not args:
                args = {}
            if rtype == 'Ljava/lang/String;':
                result = list(result.values())[0][0]
                # 更新寄存器
                args[rtn_name] = result
                # 更新代码
                new_line = 'const-string {}, "{}"'.format(rtn_name, result)
                new_body.append(new_line)
                self.make_changes = True
                # print(args)
                mtd.set_modified(True)
            elif rtype.startswith('['):
                # print("返回值为数组,更新寄存器内容")
                # print(result)
                args[rtn_name] = result
                # print(args)
            else:
                print("返回值并非字符串,也不是B/C数组")

            # print('-' * 100)

        mtd.set_body('\n'.join(new_body))
예제 #18
0
def test_windows_stream():
    """Test class."""
    # Test error.
    if windows.IS_WINDOWS:
        stream = windows.WindowsStream(windows.init_kernel32()[0],
                                       windows.INVALID_HANDLE_VALUE,
                                       StringIO())
        assert stream.colors == (windows.WINDOWS_CODES['white'],
                                 windows.WINDOWS_CODES['black'])
        stream.colors = windows.WINDOWS_CODES['red'] | windows.WINDOWS_CODES[
            'bgblue']  # No exception, just ignore.
        assert stream.colors == (windows.WINDOWS_CODES['white'],
                                 windows.WINDOWS_CODES['black'])

    # Test __getattr__() and color resetting.
    original_stream = StringIO()
    stream = windows.WindowsStream(MockKernel32(),
                                   windows.INVALID_HANDLE_VALUE,
                                   original_stream)
    assert stream.writelines == original_stream.writelines  # Test __getattr__().
    assert stream.colors == (windows.WINDOWS_CODES['white'],
                             windows.WINDOWS_CODES['black'])
    stream.colors = windows.WINDOWS_CODES['red'] | windows.WINDOWS_CODES[
        'bgblue']
    assert stream.colors == (windows.WINDOWS_CODES['red'],
                             windows.WINDOWS_CODES['bgblue'])
    stream.colors = None  # Resets colors to original.
    assert stream.colors == (windows.WINDOWS_CODES['white'],
                             windows.WINDOWS_CODES['black'])

    # Test special negative codes.
    stream.colors = windows.WINDOWS_CODES['red'] | windows.WINDOWS_CODES[
        'bgblue']
    stream.colors = windows.WINDOWS_CODES['/fg']
    assert stream.colors == (windows.WINDOWS_CODES['white'],
                             windows.WINDOWS_CODES['bgblue'])
    stream.colors = windows.WINDOWS_CODES['red'] | windows.WINDOWS_CODES[
        'bgblue']
    stream.colors = windows.WINDOWS_CODES['/bg']
    assert stream.colors == (windows.WINDOWS_CODES['red'],
                             windows.WINDOWS_CODES['black'])
    stream.colors = windows.WINDOWS_CODES['red'] | windows.WINDOWS_CODES[
        'bgblue']
    stream.colors = windows.WINDOWS_CODES['bgblack']
    assert stream.colors == (windows.WINDOWS_CODES['red'],
                             windows.WINDOWS_CODES['black'])

    # Test write.
    stream.write(Color('{/all}A{red}B{bgblue}C'))
    original_stream.seek(0)
    assert original_stream.read() == 'ABC'
    assert stream.colors == (windows.WINDOWS_CODES['red'],
                             windows.WINDOWS_CODES['bgblue'])

    # Test ignore invalid code.
    original_stream.seek(0)
    original_stream.truncate()
    stream.write('\x1b[0mA\x1b[31mB\x1b[44;999mC')
    original_stream.seek(0)
    assert original_stream.read() == 'ABC'
    assert stream.colors == (windows.WINDOWS_CODES['red'],
                             windows.WINDOWS_CODES['bgblue'])
예제 #19
0
Example usage:
echo "{red}Red{/red}" |python -m colorclass
"""

from __future__ import print_function

import fileinput
import os

from colorclass.color import Color
from colorclass.toggles import disable_all_colors
from colorclass.toggles import enable_all_colors
from colorclass.toggles import set_dark_background
from colorclass.toggles import set_light_background
from colorclass.windows import Windows

TRUTHY = ('true', '1', 'yes', 'on')

if __name__ == '__main__':
    if os.environ.get('COLOR_ENABLE', '').lower() in TRUTHY:
        enable_all_colors()
    elif os.environ.get('COLOR_DISABLE', '').lower() in TRUTHY:
        disable_all_colors()
    if os.environ.get('COLOR_LIGHT', '').lower() in TRUTHY:
        set_light_background()
    elif os.environ.get('COLOR_DARK', '').lower() in TRUTHY:
        set_dark_background()
    Windows.enable()
    for LINE in fileinput.input():
        print(Color(LINE))
예제 #20
0
def test_colorize_methods():
    """Test colorize convenience methods."""
    assert Color.black('TEST').value_colors == '\033[30mTEST\033[39m'
    assert Color.bgblack('TEST').value_colors == '\033[40mTEST\033[49m'
    assert Color.red('TEST').value_colors == '\033[31mTEST\033[39m'
    assert Color.bgred('TEST').value_colors == '\033[41mTEST\033[49m'
    assert Color.green('TEST').value_colors == '\033[32mTEST\033[39m'
    assert Color.bggreen('TEST').value_colors == '\033[42mTEST\033[49m'
    assert Color.yellow('TEST').value_colors == '\033[33mTEST\033[39m'
    assert Color.bgyellow('TEST').value_colors == '\033[43mTEST\033[49m'
    assert Color.blue('TEST').value_colors == '\033[34mTEST\033[39m'
    assert Color.bgblue('TEST').value_colors == '\033[44mTEST\033[49m'
    assert Color.magenta('TEST').value_colors == '\033[35mTEST\033[39m'
    assert Color.bgmagenta('TEST').value_colors == '\033[45mTEST\033[49m'
    assert Color.cyan('TEST').value_colors == '\033[36mTEST\033[39m'
    assert Color.bgcyan('TEST').value_colors == '\033[46mTEST\033[49m'
    assert Color.white('TEST').value_colors == '\033[37mTEST\033[39m'
    assert Color.bgwhite('TEST').value_colors == '\033[47mTEST\033[49m'

    assert Color.black(
        'this is a test.',
        auto=True) == Color('{autoblack}this is a test.{/autoblack}')
    assert Color.black('this is a test.') == Color(
        '{black}this is a test.{/black}')
    assert Color.bgblack(
        'this is a test.',
        auto=True) == Color('{autobgblack}this is a test.{/autobgblack}')
    assert Color.bgblack('this is a test.') == Color(
        '{bgblack}this is a test.{/bgblack}')
    assert Color.red('this is a test.',
                     auto=True) == Color('{autored}this is a test.{/autored}')
    assert Color.red('this is a test.') == Color('{red}this is a test.{/red}')
    assert Color.bgred(
        'this is a test.',
        auto=True) == Color('{autobgred}this is a test.{/autobgred}')
    assert Color.bgred('this is a test.') == Color(
        '{bgred}this is a test.{/bgred}')
    assert Color.green(
        'this is a test.',
        auto=True) == Color('{autogreen}this is a test.{/autogreen}')
    assert Color.green('this is a test.') == Color(
        '{green}this is a test.{/green}')
    assert Color.bggreen(
        'this is a test.',
        auto=True) == Color('{autobggreen}this is a test.{/autobggreen}')
    assert Color.bggreen('this is a test.') == Color(
        '{bggreen}this is a test.{/bggreen}')
    assert Color.yellow(
        'this is a test.',
        auto=True) == Color('{autoyellow}this is a test.{/autoyellow}')
    assert Color.yellow('this is a test.') == Color(
        '{yellow}this is a test.{/yellow}')
    assert Color.bgyellow(
        'this is a test.',
        auto=True) == Color('{autobgyellow}this is a test.{/autobgyellow}')
    assert Color.bgyellow('this is a test.') == Color(
        '{bgyellow}this is a test.{/bgyellow}')
    assert Color.blue(
        'this is a test.',
        auto=True) == Color('{autoblue}this is a test.{/autoblue}')
    assert Color.blue('this is a test.') == Color(
        '{blue}this is a test.{/blue}')
    assert Color.bgblue(
        'this is a test.',
        auto=True) == Color('{autobgblue}this is a test.{/autobgblue}')
    assert Color.bgblue('this is a test.') == Color(
        '{bgblue}this is a test.{/bgblue}')
    assert Color.magenta(
        'this is a test.',
        auto=True) == Color('{automagenta}this is a test.{/automagenta}')
    assert Color.magenta('this is a test.') == Color(
        '{magenta}this is a test.{/magenta}')
    assert Color.bgmagenta(
        'this is a test.',
        auto=True) == Color('{autobgmagenta}this is a test.{/autobgmagenta}')
    assert Color.bgmagenta('this is a test.') == Color(
        '{bgmagenta}this is a test.{/bgmagenta}')
    assert Color.cyan(
        'this is a test.',
        auto=True) == Color('{autocyan}this is a test.{/autocyan}')
    assert Color.cyan('this is a test.') == Color(
        '{cyan}this is a test.{/cyan}')
    assert Color.bgcyan(
        'this is a test.',
        auto=True) == Color('{autobgcyan}this is a test.{/autobgcyan}')
    assert Color.bgcyan('this is a test.') == Color(
        '{bgcyan}this is a test.{/bgcyan}')
    assert Color.white(
        'this is a test.',
        auto=True) == Color('{autowhite}this is a test.{/autowhite}')
    assert Color.white('this is a test.') == Color(
        '{white}this is a test.{/white}')
    assert Color.bgwhite(
        'this is a test.',
        auto=True) == Color('{autobgwhite}this is a test.{/autobgwhite}')
    assert Color.bgwhite('this is a test.') == Color(
        '{bgwhite}this is a test.{/bgwhite}')
예제 #21
0
def test_colorize_methods():
    """Test colorize convenience methods."""
    assert Color.black("TEST").value_colors == "\033[30mTEST\033[39m"
    assert Color.bgblack("TEST").value_colors == "\033[40mTEST\033[49m"
    assert Color.red("TEST").value_colors == "\033[31mTEST\033[39m"
    assert Color.bgred("TEST").value_colors == "\033[41mTEST\033[49m"
    assert Color.green("TEST").value_colors == "\033[32mTEST\033[39m"
    assert Color.bggreen("TEST").value_colors == "\033[42mTEST\033[49m"
    assert Color.yellow("TEST").value_colors == "\033[33mTEST\033[39m"
    assert Color.bgyellow("TEST").value_colors == "\033[43mTEST\033[49m"
    assert Color.blue("TEST").value_colors == "\033[34mTEST\033[39m"
    assert Color.bgblue("TEST").value_colors == "\033[44mTEST\033[49m"
    assert Color.magenta("TEST").value_colors == "\033[35mTEST\033[39m"
    assert Color.bgmagenta("TEST").value_colors == "\033[45mTEST\033[49m"
    assert Color.cyan("TEST").value_colors == "\033[36mTEST\033[39m"
    assert Color.bgcyan("TEST").value_colors == "\033[46mTEST\033[49m"
    assert Color.white("TEST").value_colors == "\033[37mTEST\033[39m"
    assert Color.bgwhite("TEST").value_colors == "\033[47mTEST\033[49m"

    assert Color.black("this is a test.", auto=True) == Color("{autoblack}this is a test.{/autoblack}")
    assert Color.black("this is a test.") == Color("{black}this is a test.{/black}")
    assert Color.bgblack("this is a test.", auto=True) == Color("{autobgblack}this is a test.{/autobgblack}")
    assert Color.bgblack("this is a test.") == Color("{bgblack}this is a test.{/bgblack}")
    assert Color.red("this is a test.", auto=True) == Color("{autored}this is a test.{/autored}")
    assert Color.red("this is a test.") == Color("{red}this is a test.{/red}")
    assert Color.bgred("this is a test.", auto=True) == Color("{autobgred}this is a test.{/autobgred}")
    assert Color.bgred("this is a test.") == Color("{bgred}this is a test.{/bgred}")
    assert Color.green("this is a test.", auto=True) == Color("{autogreen}this is a test.{/autogreen}")
    assert Color.green("this is a test.") == Color("{green}this is a test.{/green}")
    assert Color.bggreen("this is a test.", auto=True) == Color("{autobggreen}this is a test.{/autobggreen}")
    assert Color.bggreen("this is a test.") == Color("{bggreen}this is a test.{/bggreen}")
    assert Color.yellow("this is a test.", auto=True) == Color("{autoyellow}this is a test.{/autoyellow}")
    assert Color.yellow("this is a test.") == Color("{yellow}this is a test.{/yellow}")
    assert Color.bgyellow("this is a test.", auto=True) == Color("{autobgyellow}this is a test.{/autobgyellow}")
    assert Color.bgyellow("this is a test.") == Color("{bgyellow}this is a test.{/bgyellow}")
    assert Color.blue("this is a test.", auto=True) == Color("{autoblue}this is a test.{/autoblue}")
    assert Color.blue("this is a test.") == Color("{blue}this is a test.{/blue}")
    assert Color.bgblue("this is a test.", auto=True) == Color("{autobgblue}this is a test.{/autobgblue}")
    assert Color.bgblue("this is a test.") == Color("{bgblue}this is a test.{/bgblue}")
    assert Color.magenta("this is a test.", auto=True) == Color("{automagenta}this is a test.{/automagenta}")
    assert Color.magenta("this is a test.") == Color("{magenta}this is a test.{/magenta}")
    assert Color.bgmagenta("this is a test.", auto=True) == Color("{autobgmagenta}this is a test.{/autobgmagenta}")
    assert Color.bgmagenta("this is a test.") == Color("{bgmagenta}this is a test.{/bgmagenta}")
    assert Color.cyan("this is a test.", auto=True) == Color("{autocyan}this is a test.{/autocyan}")
    assert Color.cyan("this is a test.") == Color("{cyan}this is a test.{/cyan}")
    assert Color.bgcyan("this is a test.", auto=True) == Color("{autobgcyan}this is a test.{/autobgcyan}")
    assert Color.bgcyan("this is a test.") == Color("{bgcyan}this is a test.{/bgcyan}")
    assert Color.white("this is a test.", auto=True) == Color("{autowhite}this is a test.{/autowhite}")
    assert Color.white("this is a test.") == Color("{white}this is a test.{/white}")
    assert Color.bgwhite("this is a test.", auto=True) == Color("{autobgwhite}this is a test.{/autobgwhite}")
    assert Color.bgwhite("this is a test.") == Color("{bgwhite}this is a test.{/bgwhite}")
예제 #22
0
    def _process_mtd(self, mtd):
        # if DEBUG_MODE:
        #     print('\n', '+' * 100)
        #     print('Starting to decode ...')
        #     print(Color.green(mtd))

        # 如果存在数组
        array_data_content = []
        arr_res = self.arr_data_ptn.search(mtd.get_body())
        if arr_res:
            array_data_content = re.split(r'\n\s', arr_res.group())

        lines = re.split(r'\n\s*', mtd.get_body())

        old_body = lines.copy()  # 存放原始方法体
        new_body = []  # 存放解密后的方法体

        snippet = []  # 存放smali代码,用于模拟执行
        args = {}  # 存放方法参数,用于smaliemu执行

        index = -1  # 用于计数

        xget_opcodes = {'iget', 'iget-object', 'sget', 'sget-object'}

        block_args = {'first': {}}  # 保存所有分支的执行结果
        last_block_key = 'first'  # 上一个分支-关键字
        this_block_key = 'first'  # 当前分支,默认第一分支
        keys = ['first']  # 默认执行第一分支

        for line in lines:
            index += 1
            if not line:
                continue
            new_body.append(line)  # 解密结果,直接放后面即可

            # if DEBUG_MODE:
            #     print(Color.blue(line))

            parts = line.split()
            opcode = parts[0]

            # smali 代码分块执行
            # 命中下述关键字,则表示当前分支结束
            # 并根据上一个分支的情况,判断之前的分支是否可用
            if 'if-' in opcode:
                # if DEBUG_MODE:
                #     print('>' * 10, opcode)
                #     print('this_block_key', this_block_key)
                #     print('last_block_key', last_block_key)
                #     print('block_args', block_args)

                # 存在两种情况
                # 1. 当前代码片段(if语句之前的代码),还没执行;全部执行一次
                # 2. 当前代码片段,已经执行了一部分,因为解密;从执行后的地方开始执行

                pre_args = {}
                if this_block_key in last_block_key:
                    for key in reversed(keys):
                        if this_block_key not in key:
                            pre_args = block_args[key].copy()
                            break
                else:
                    pre_args = block_args[last_block_key].copy()

                if this_block_key in block_args:
                    pre_args.update(block_args[this_block_key])

                snippet.extend(array_data_content)
                self.emu.call(snippet, args=pre_args, cv=True, thrown=False)
                block_args[this_block_key] = self.emu.vm.variables
                snippet.clear()

                last_block_key = this_block_key
                this_block_key = 'if' + parts[-1]  # 表示接下来跑的代码块是这个语句的
                keys.append(this_block_key)

                # if DEBUG_MODE:
                #     print('block_args - 运行后', block_args)
                continue
            elif 'goto' in opcode:
                # 跳转语句,直接跳过
                continue
            elif opcode.startswith(':cond_')\
                or opcode.startswith(':try_start')\
                    or opcode.startswith('.catch_'):
                # if DEBUG_MODE:
                #     print('>' * 10, opcode)
                #     print('this_block_key', this_block_key)
                #     print('last_block_key', last_block_key)
                #     print('block_args', block_args)
                # 存在两种情况
                # 1. 当前代码片段,还没执行;全部执行一次
                # 2. 当前代码片段,已经执行了一部分,因为解密;从执行后的地方开始执行
                pre_args = block_args[last_block_key].copy()
                if this_block_key in block_args:
                    pre_args.update(block_args[this_block_key])

                snippet.extend(array_data_content)
                self.emu.call(snippet, args=pre_args, cv=True, thrown=False)
                block_args[this_block_key] = self.emu.vm.variables

                snippet.clear()

                last_block_key = this_block_key
                this_block_key = opcode  # 表示接下来跑的代码块是这个语句的
                keys.append(this_block_key)

                # if DEBUG_MODE:
                #     print('block_args - 运行后', block_args)
                continue
            elif opcode.startswith(':try_start'):
                pass
            elif '.catch_' in opcode:
                # 前面代码当成一块处理
                continue

            snippet.append(line)

            is_static = True
            if opcode == 'invoke-static':
                result = self.process_invoke_static_statement(line)
                if result:
                    cname, mname, ptypes, rtype, rnames = result
                else:
                    continue
            # elif opcode == 'invoke-virtual':
            # TODO 实例方法,目前只考虑无参实例化。
            #     result = self.process_invoke_static_statement(line)
            #     if result:
            #         cname, mname, ptypes, rtype, rnames = result
            #         print(result)
            #         # 判断类的构造函数是否为<init>()V
            #         clz = self.smalidir.get_method(
            #             java2smali(cname), '<init>()V')
            #         if not clz:
            #             continue
            #         is_static = False
            #     else:
            #         continue
            elif opcode in xget_opcodes:
                self.process_xget_statement(line)
                continue
            elif 'Ljava/lang/String;-><init>([B)V' in line:
                if 'move-result-object' in snippet[0]:
                    snippet = snippet[1:]
                self.emu.call(snippet, args=args, cv=True, thrown=False)
                if not self.emu.vm.result:
                    continue

                # 如果有结果,则替换
                vx, _ = SmaliLine.parse(line)
                new_line = 'const-string {}, "{}"'.format(
                    vx, self.emu.vm.result)
                del new_body[-1]
                new_body.append(new_line)
                self.make_changes = True
                mtd.set_modified(True)

                snippet.clear()
                continue
            else:
                continue

            # 模拟执行,获取解密参数
            del snippet[-1]
            snippet.extend(array_data_content)
            try:
                snippet = self.process_if_statement(snippet)

                # if DEBUG_MODE:
                #     print(Color.red('开始处理解密参数 {}'.format(line)))
                #     for l in snippet:
                #         print(Color.red(l))

                #     print('args', args)
                #     print(block_args)
                #     print(keys)
                #     print(this_block_key)
                #     print('-' * 80)

                pre_args = block_args[last_block_key].copy()
                args.update(pre_args)
                if this_block_key in block_args:
                    args.update(block_args[this_block_key])
                args.update(self.fields)

                self.emu.call(snippet, args=args, cv=True, thrown=False)
                registers = self.emu.vm.variables
                block_args[this_block_key] = registers

                # if DEBUG_MODE:
                #     print(snippet)
                #     print('args:', args)
                #     print('smali执行后,寄存器内容', registers)

                if registers:
                    for k, v in registers.items():
                        if v is None:
                            continue
                        args[k] = v

                registers = args
            except TIMEOUT_EXCEPTION:
                snippet.clear()
                continue

            print(Color.red('->'))

            obj_flag = False
            if len(ptypes) == 1 and ptypes[0][0] == 'L' and ptypes != [
                    'Ljava/lang/String;'
            ]:
                # 单独处理参数为对象的情况
                obj_flag = True

            snippet.clear()  # 已经执行过的代码,不再执行
            if not registers and not obj_flag:
                continue

            print(Color.red('->>'))

            # 从寄存器中获取对应的参数
            # 参数获取 "arguments": ["I:198", "I:115", "I:26"]}
            arguments = []
            # args = {}  # the parameter of smali method
            if not obj_flag:
                ridx = -1
                for item in ptypes:
                    ridx += 1
                    rname = rnames[ridx]
                    if rname not in registers:
                        break
                    value = registers[rnames[ridx]]
                    argument = self.convert_args(item, value)
                    if argument is None:
                        break
                    arguments.append(argument)
            else:
                arguments.append('Object:' + smali2java(ptypes[0]))

            # if DEBUG_MODE:
            #     print(Color.red('->>'))
            #     print('参数类型', ptypes)
            #     print('参数值', arguments)
            if len(arguments) != len(ptypes):
                print(Color.red('->> 参数对不上'))
                continue

            json_item = self.get_json_item(cname, mname, arguments)
            print(json_item)
            # print('生成json item')

            # {id}_{rtn_name} 让这个唯一化,便于替换
            old_content = '# %s' % json_item['id']
            # 如果 move_result_obj 操作存在的话,解密后一起替换
            find = self.move_result_obj_ptn.search(lines[index + 1])

            print(Color.red('->> not fount'))

            # 必须要找到返回值操作,用于更新寄存器
            if not find:
                print('找不到返回寄存器')
                continue

            print(Color.red('->>>'))

            rtn_name = find.groups()[0]
            # 为了避免 '# abc_v10' 替换成 '# abc_v1'
            old_content = old_content + '_' + rtn_name + 'X'
            self.append_json_item(json_item, mtd, old_content, rtn_name)

            result = self.get_result(rtype)
            # if DEBUG_MODE:
            #     print("解密结果", result)

            self.json_list.clear()

            if result:
                new_body = new_body[:-1]
            else:
                continue

            if not args:
                args = {}
            if rtype == 'Ljava/lang/String;':
                result = list(result.values())[0][0]
                # 更新寄存器
                args[rtn_name] = result
                # 更新代码
                new_line = 'const-string {}, "{}"'.format(rtn_name, result)
                new_body.append(new_line)
                self.make_changes = True
                mtd.set_modified(True)
            elif rtype.startswith('['):
                args[rtn_name] = result
                # 把结果保存到当前分支

            else:
                print("返回值并非字符串,也不是B/C数组")

            if args:
                block_args[this_block_key].update(args)

            # 把结果保存到当前分支
            # if DEBUG_MODE:
            #     print(block_args)
            #     print('*' * 100)
            #     print('last_block_key', last_block_key)
            #     print('this_block_key', this_block_key)
            #
            # pre_args = block_args[last_block_key].copy()
            # if this_block_key in block_args:
            #     pre_args.update(block_args[this_block_key])
            # block_args[this_block_key] =

        mtd.set_body('\n'.join(new_body))