Mr.Alright---安卓如何修改3rd App(某兔兔、某大师、CPU-Z)等检测信息

本文详细介绍了一种在Android系统中伪造手机RAM和ROM显示大小的技术方案,包括修改TextView显示和源头数据更改两种方法,涉及Java与C层代码修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这种作假的东西其实我是很反感的,有些无良客户居然提要求把1G的改成2G的,2G的改成4G的,

导致我现在都不相信现在手机显示出来的数据了,但是没办法,为了能混口饭吃,唉...

本文提供2种方法,并已Ram Rom为例

1.在TextView.java(frameworks/base/core/java/android/widget/TextView.java),因为三方软件我们没办法直接修改,但是从显示上来看肯定是textview,因而我们可以直接在SetText()的方法中去修改

private void setText(CharSequence text, BufferType type,
                        boolean notifyBefore, int oldlen) {
    mTextSetFromXmlOrResourceId = false;
    if (text == null) {
        text = "";
    }
    String packageName = getContext().getPackageName();
    if (packageName.equals("com.antutu.ABenchMark")
                || packageName.equals("com.cpuid.cpu_z")
                || packageName.equals("com.ludashi.benchmark")) {
        //这两个是我们在frameworks/base/core/res/res/valuess/configs.xml中写死的值
        String fakeRamSize = getContext().getResources().getString(com.android.internal.R.string.custom_ram_size);
        String fakeRomSize = getContext().getResources().getString(com.android.internal.R.string.custom_rom_size);
        //然后就是用我们自己定义的字符串去替换,三方的字符串
        if (fakeRamSize != null && !fakeRamSize.equals("") && s.startsWith("Total:") && s.endsWith("MB")) {
                String totals = s.substring(s.indexOf(":") + 1, s.indexOf("B") + 1);
                text = s.replace(totals, fakeRamSize);
        }
        if (fakeRomSize != null && !fakeRomSize.equals("") && s.startsWith("Total:") && s.endsWith("GB")) {
                String totals = s.substring(s.indexOf(":") + 1, s.indexOf("B") + 1);
                text = s.replace(totals, fakeRomSize);
        }
        if (fakeRamSize != null && !fakeRamSize.equals("") && s.contains("/") && s.endsWith("MB")) {
                String totals = s.substring(s.lastIndexOf("/") + 1, s.lastIndexOf("B") + 1);
                text = s.replace(totals, fakeRamSize);
        }
        if (fakeRomSize != null && !fakeRomSize.equals("") && s.contains("/") && s.endsWith("GB")) {
                String totals = s.substring(s.lastIndexOf("/") + 1, s.lastIndexOf("B") + 1);
                text = s.replace(totals, fakeRomSize);
        }
    }   
}

通过上面的方法,我们就可以把ram rom,替换成我们想要的大小,并且肯定是整数。

2. 大家都看到了,用TextView改的方法很low,对不对?这上面只是3个应用就写了这么多代码,有这么多判断,那如果市面上又出来其他主流检测工具呢???

另外,从性能上面讲,系统里有多少Textview,每个显示之前都要判断是不是三方应用,如果是三方应用,每个TextView还要判断已什么开头,我的天!如果说这不影响性能,鬼才信啊!因此,我们的第二种方法会解决这些问题。

思路是这样的,先考虑三方应用是如何获取系统的ram rom的,至于如何获取,在这里不再详述,大家可以自行百度,经过调试最后发现,这些主流的App获取Rom、Ram的方式是:

//ROM
String path = Environment.getDataDirectory().getPath();
StatFs statFs = new StatFs(path);
long blockCount = statFs.getBlockCountLong();
long blockSize = statFs.getBlockSizeLong();
long availableBlocks = statFs.getAvailableBlocksLong();
long totalBytes = statFs.getTotalBytes();
long freeBytes = statFs.getFreeBytes();

//RAM
//RAM是保存在proc/meminfo文件里面的,meminfo的大概结构式这样的
/**
        MemTotal: 所有可用RAM大小。
        MemFree: LowFree与HighFree的总和,被系统留着未使用的内存。
        Buffers: 用来给文件做缓冲大小。
        Cached: 被高速缓冲存储器(cache memory)用的内存的大小(等于diskcache minus SwapCache)。
        SwapCached:被高速缓冲存储器(cache memory)用的交换空间的大小。已经被交换出来的内存,仍然被存放在swapfile中,用来在需要的时候很快的被替换而不需要再次打开I/O端口。
        Active: 在活跃使用中的缓冲或高速缓冲存储器页面文件的大小,除非非常必要,否则不会被移作他用。
        Inactive: 在不经常使用中的缓冲或高速缓冲存储器页面文件的大小,可能被用于其他途径。
        SwapTotal: 交换空间的总大小。
        SwapFree: 未被使用交换空间的大小。
        Dirty: 等待被写回到磁盘的内存大小。
        Writeback: 正在被写回到磁盘的内存大小。
        AnonPages:未映射页的内存大小。
        Mapped: 设备和文件等映射的大小。
        Slab: 内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗。
        SReclaimable:可收回Slab的大小。
        SUnreclaim:不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)。
        PageTables:管理内存分页页面的索引表的大小。
        NFS_Unstable:不稳定页表的大小。
        要获取android手机总内存大小,只需读取”/proc/meminfo”文件的第1行,并进行简单的字符串处理即可。*/

 public static String getMemInfoIype(Context context, String type) {
        try {
            FileReader fileReader = new FileReader("/proc/meminfo");
            BufferedReader bufferedReader = new BufferedReader(fileReader, 4 * 1024);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                if (str.contains(type)) {
                    break;
                }
            }
            bufferedReader.close();
            // \\s表示   空格,回车,换行等空白符
            // +号表示一个或多个的意思     
            String[] array = str.split("\\s+");
            // 获得系统总内存,单位是KB,乘以1024转换为Byte
            int length = Integer.valueOf(array[1]).intValue() * 1024;
            return android.text.format.Formatter.formatFileSize(context, length);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

因此我们只需要在源头改变数据的大小就OK,由于我对C不是太熟悉,所以开始时我采用的是修改java代码达到目的。下面是修改Rom

// 刚才已分析,ROM用的是BlockCount和blocksize的乘积,由于blocksize固定,所以我们用一下改法
// 在对应项目的system.prop文件中添加 ro.faker.rom.size = 8L
/*
扩展一下
属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。
属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。
属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。(这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)
属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。每一项服务必须在/init.rc中定义.
*/

public long getBlockCountLong() {
        long fakerRomSize = SystemProperties.getLong("ro.faker.rom.size", 0L);
        return fakerRomSize == 0L
                ? (int) mStat.f_blocks
                : (int) (1024 * 1024 * 1024L * fakerRomSize / getBlockSizeLong());
    }

当然,getBlockCount()这个方法最好也改一下,这是过时的方法,但是仍可以使用

这个方法一般不会有问题,因为大多数都是通过这种方法获取的,但是如果想万无一失,可以通过修改libcore\luni\src\main\native\libcore_io_Linux.cpp文件中的

static jobject makeStructStatVfs(JNIEnv* env, const struct statvfs& sb) {
    static jmethodID ctor = env->GetMethodID(JniConstants::structStatVfsClass, "<init>",
            "(JJJJJJJJJJJ)V");
    if (ctor == NULL) {
        return NULL;
    }
     return env->NewObject(JniConstants::structStatVfsClass, ctor,
                          static_cast<jlong>(sb.f_bsize),
                          static_cast<jlong>(sb.f_frsize),
                          static_cast<jlong>(sb.f_blocks),
                          static_cast<jlong>(sb.f_bfree),
                          static_cast<jlong>(sb.f_bavail),
                          static_cast<jlong>(sb.f_files),
                          static_cast<jlong>(sb.f_ffree),
                          static_cast<jlong>(sb.f_favail),
                          static_cast<jlong>(sb.f_fsid),
                          static_cast<jlong>(sb.f_flag),
                          static_cast<jlong>(sb.f_namemax));
}

这种改法大家有兴趣自己实现吧,尴尬而不是礼貌的微笑

下面是修改RAM的,这个搞得我头皮发麻,因为之前没搞过C和Kernel,提前说明一下,kernel层和framework层是相对独立的,所以在安卓8.1 上之前的在项目的ProjectConfig.mk中定义一个宏,在kernel层通过Makefile编译的方法不能再用了,废话不说,上代码

// 上面分析过meminfo文件了,这里就不多说了,首先你要清楚项目用的内核版本是什么,可以在手机设置里面看到 ,kernel-4.9\fs\proc\meminfo.c,这个文件生成了meminfo
// 这个方法生成的KB
static int meminfo_proc_show(struct seq_file *m, void *v)
{
	struct sysinfo i;
	unsigned long committed;
	long cached;
......
    #if defined(CONFIG_FAKER_RAM_SIZE) && (CONFIG_FAKER_RAM_SIZE> 0)
        show_val_kb(m, "MemTotal:       ", CONFIG_FAKER_RAM_SIZE* 1024 * 256L);
    #else
       show_val_kb(m, "MemTotal:       ", i.totalram);
    #endif
    
	show_val_kb(m, "MemFree:        ", i.freeram);
	show_val_kb(m, "MemAvailable:   ", available);
	show_val_kb(m, "Buffers:        ", i.bufferram);
......
}

/*
通过这个CONFIG_FAKER_RAM_SIZE,我们就可以随意改变RAM的大小了,这个东西的配置有讲究,注意
首先在kernel-4.9\fs\proc\Kconfig中定义,格式如下 不能错,bool string的写法类似
config FAKER_RAM_SIZE    
    int FAKER_RAM_SIZE
    default 0

CONFIG_FAKER_RAM_SIZE这个就是,config FAKER_RAM_SIZE 合起来的,定义在对应的项目中
kernel-4.9\arch\arm64\configs\xoxo_debug_defconfig
kernel-4.9\arch\arm64\configs\xoxo_defconfig
两个文件都添加如下配置,数值就是项目中需要的RAM大小1G 就是1
CONFIG_FAKER_RAM_SIZE = 1   错误写法 不能留空格 不能留空格 不能留空格
CONFIG_FAKER_RAM_SIZE=1     正确写法
*/

到此为止,就已经实现要求了,Android O,Android P 测试OK,希望你像IG一样,永不加班!

对了补充一句,能拒绝造假的,坚决拒绝,太特么恶心了!!!

### 南京邮电大学算法课程相关课后习题与资料 在南京邮电大学的算法课程中,常见的课后习题涉及多个主题,包括但不限于矩阵运算、搜索算法以及编程实践等内容。以下是针对这些主题的具体描述: #### 1. 矩阵连乘问题优化 矩阵连乘问题是计算机科学中的经典动态规划问题之一,在数学和工程领域具有广泛应用。该问题的核心在于利用矩阵乘法的结合律特性来减少不必要的标量乘法次数,从而提升计算效率[^1]。 ```python def matrix_chain_order(p): n = len(p) - 1 m = [[0 for _ in range(n)] for _ in range(n)] s = [[0 for _ in range(n)] for _ in range(n)] for l in range(2, n + 1): for i in range(1, n - l + 2): j = i + l - 1 m[i-1][j-1] = float(&#39;inf&#39;) for k in range(i, j): q = m[i-1][k-1] + m[k][j-1] + p[i-1]*p[k]*p[j] if q < m[i-1][j-1]: m[i-1][j-1] = q s[i-1][j-1] = k return m, s ``` 上述代码实现了动态规划方法解决矩阵链乘问题的过程,能够有效降低时间复杂度至 \(O(n^3)\)--- #### 2. 学生结构体数据处理 对于学生信息管理类题目,通常会涉及到结构化数据的操作。例如,《MATLAB数学实验》第三版提供了关于如何随机生成一组学生的成绩并进行统计分析的例子[^2]。下面是一个类似的 Python 实现版本: ```python import random class Student: def __init__(self, name, id_num, grades): self.name = name self.id = id_num self.grades = grades students = [] m = random.randint(30, 60) for i in range(m): student_name = f&#39;Student {i+1}&#39; student_id = i + 1 student_grades = [random.randint(30, 100) for _ in range(5)] students.append(Student(student_name, student_id, student_grades)) for student in students: total_score = sum(student.grades) avg_score = total_score / len(student.grades) print(f&#39;学生{student.name} 的总分是 {total_score},平均分是 {avg_score:.2f}&#39;) ``` 此脚本展示了如何构建一个简单的学生成绩管理系统,并完成基本的数据汇总功能。 --- #### 3. 三分查找算法及其应用 三分查找是一种改进型的一维搜索技术,适用于单峰函数极值求解等问题。其核心思想是在每次迭代过程中将当前区间划分为三部分,通过两次比较逐步逼近目标位置[^3]。 C++实现如下所示: ```cpp #include <iostream> using namespace std; int ternarySearch(int arr[], int size, int target){ int low=0; int high=size-1; while(low<=high){ int mid1=(low+(high-low)/3); int mid2=(high-(high-low)/3); if(target==arr[mid1]) return mid1; if(target==arr[mid2]) return mid2; if(target<arr[mid1]){ high=mid1-1; } else if(target>arr[mid2]){ low=mid2+1; } else{ low=mid1+1; high=mid2-1; } } return -1; // Not found } ``` 以上代码片段清晰地体现了三分查找的工作机制,同时具备较高的运行效率,适合用于大规模有序数组检索场景。 --- #### 4. MATLAB 数组操作练习 MATLAB 是一门广泛应用于科学研究和技术开发的强大工具软件。在其入门阶段的教学材料里,往往包含了大量有关矩阵变换的基础训练项目[^4]。比如对给定二维数组实施逐元素加减乘除运算,或是调用内置函数完成更复杂的数值映射任务等。 示例命令序列可能像这样: ```matlab % 初始化测试矩阵 A 和 B A = magic(3); B = ones(size(A)) * pi; % 执行一系列算术指令 result_addition = A + 10; result_subtraction_complex = result_addition - complex(0, 2); result_multiplication_elementwise = result_subtraction_complex .* B; result_division_right = result_multiplication_elementwise ./ abs(B - A); result_square_elements = sqrt(result_division_right.^2); result_logarithmic_natural = log(exp(result_square_elements)); column_product_A = prod(A, &#39;all&#39;); min_values_per_column = min(A(:), [], 1); indices_of_minimums = find(min_values_per_column == A); nonzero_linear_indices = find(result_logarithmic_natural ~= 0); [row_nonzeros col_nonzeros] = ind2sub(size(A), nonzero_linear_indices); linspace_vector_example = linspace(3, 4, 5); second_column_extracted = A(:, 2); ``` 每一步都严格遵循特定规则展开,最终达成预期效果。 --- #### 5. 自适应均衡器性能对比研究 最后提到的是通信系统建模方向的一个专题——即采用不同策略调整滤波权重系数以抵消信道干扰现象的研究课题[^5]。具体而言,LMS(Least Mean Square)与 RLS(Recursive Least Squares)作为两类主流递推估计框架被频繁提及。它们各自拥有独特优势但也存在局限之处,需依据实际需求权衡选用。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值