96SEO 2026-02-19 08:48 7
在代码开发过程中因为各种各样的原因常常会引入随机数、时间戳等信息参与运算。

这些信息随着时间、系统状态等因素不停变化它们导致函数入参不变的情况下计算出的结果不固定。
在模拟执行以及算法还原时我们有控制这些干扰项使得结果固定的需求。
调用目标函数且入参一致时理论上返回结果也一致这意味着我们得到了绝对意义上的完全正确的模拟执行。
对于算法还原而言如果能固定干扰项使得参数不变时结果固定这会对辅助算法还原帮助巨大。
这意味着只要不改变入参程序的控制流和数据流就完全固化。
逆向分析好比闯关卡分析人员有无数条命而关卡总是固定你可以砸时间不停试错熟悉并最终击败每一个陷阱和挑战。
这并非好无副作用存在代码覆盖率和执行路径的问题但和它带来的好处相比是一笔划算买卖。
java/lang/System-currentTimeMillis()J:{return
System.currentTimeMillis();}}return
super.callStaticLongMethodV(vm,
java/lang/System-currentTimeMillis()J:{return
super.callStaticLongMethodV(vm,
gettimeofday);Interceptor.replace(addr_gettimeofday,
Int32Array(ArrayBuffer.wrap(ptr_tz,
是另一个高频函数。
这是一个语义相当丰富的函数可以获取真实时间、进程时间、线程时间等多种类型的时间函数原型如下。
0};clock_gettime(CLOCK_REALTIME,
相关的时钟表示从某个不确定的点开始计时的时间这个不确定的点往往是开机或开机后的某个时间。
}总体上说在库函数的层面有不少函数可以获得时间信息。
在真实环境上我们可以用
样本可以通过内联汇编直接调用系统调用而且绝大多数干扰项所对应的库函数也都基于系统调用因此如果拦截和处理系统调用就可以从根本上处理随机干扰项。
linux_eabi_syscall(__NR_clock_gettime,
j___set_errno_internal(-result);return
gettimeofday来到src/main/java/com/github/unidbg/unix/UnixSyscallHandler.java。
System.currentTimeMillis();long
-(calendar.get(Calendar.ZONE_OFFSET)
calendar.get(Calendar.DST_OFFSET))
TimeZone(tz);timeZone.tz_minuteswest
tz_minuteswest;timeZone.tz_dsttime
}直接将System.currentTimeMillis()改为固定值即可固定
中则在src/main/java/com/github/unidbg/linux/ARM64SyscallHandler.java如果样本采用
位环境则对应于src/main/java/com/github/unidbg/linux/ARM32SyscallHandler.java。
backend.reg_read(ArmConst.UC_ARM_REG_R0).intValue();Pointer
UnidbgPointer.register(emulator,
CLOCK_THREAD_CPUTIME_ID:tp.setInt(0,
UnsupportedOperationException(clk_id
}其中的时间获取是System.currentTimeMillis()和System.nanoTime()可以同理做固定。
的实现位于src/main/java/com/github/unidbg/unix/UnixSyscallHandler.java同理可以将
byte[bufSize];random.nextBytes(bytes);buf.write(0,
{log.debug(Inspector.inspectString(bytes,
Integer.toHexString(flags)));}return
os.urandom(buflen)ql.mem.write(buf,
ExAndroidNativeEmu则在这项工作上展示了很大的灵活性。
在
pathandroidemu/cpu/syscall_hooks.py
OVERRIDE_TIMEOFDAY:uc.mem_write(tv
int(OVERRIDE_TIMEOFDAY_SEC).to_bytes(ptr_sz,
byteorderlittle))uc.mem_write(tv
int(OVERRIDE_TIMEOFDAY_USEC).to_bytes(ptr_sz,
byteorderlittle))else:timestamp
byteorderlittle))uc.mem_write(tv
0:#timezone结构体不64还是32都是两个4字节成员uc.mem_write(tz
中想要修改、固定时间、随机数等系统调用就必须修改源码或者自实现
中其代码逻辑位于src/main/java/com/github/unidbg/linux/file/DriverFileIO.java。
其实现逻辑位于src/main/java/com/github/unidbg/linux/file/RandomFileIO.java。
{ThreadLocalRandom.current().nextBytes(bytes);
OverRide位于androidemu/vfs/file_system.py。
/dev/urandom:logging.debug(File
os.path.exists(parent)):os.makedirs(parent)#with
byteorderlittle)f.write(b)算法分析三大方法论
自上而下是最朴素的方法从目标函数的起始地址往下调试代码分析清楚遇到的每一个函数的功能。
这个方法论最朴素也可以获得对目标函数最完全的理解。
理论上我们总是应该采用这个思路。
在做安全开发和代码保护时开发者默认分析者会自上而下去做分析所以也会格外注重保护头部。
比如我们可以观察到很多样本都会在
JNI_OnLoad、目标函数开头等位置塞大量的垃圾指令阻止反汇编和反编译但很多子函数或者说中间函数不会做这类保护。
换句话说自上而下分析意味着你需要直面样本存在的所有代码保护技术。
从代码逻辑上说很多目标函数可以分成三段环境校验、信息收集、加密与编码。
如果我们只是希望还原算法那么很多时候只需要确认第三段的输入以及第三段的具体处理就行了前两段不需要特别仔细的看。
但自上而下的分析处理里需要花费一些时间在前两段上。
自上而下分析是全面、详尽、耗时的分析办法我们一般可以把它当成保底的办法。
这类分析能力很强的运行环境里由果溯因是我很喜欢的一个分析办法。
这意味着我们直接从函数的结果开始分析往上找它的来源来源找清楚了为止。
甚至更少因为和产生运算结果无关的逻辑都被过滤掉了。
想要快速的由果溯因还需要掌握一些小技巧。
它的优点是分析快速可以避开许多无用逻辑和代码保护缺点是分析不够全面而且对分析工具的要求比较高至少得有内存读写监控。
关键函数分析也是常见的一种分析思路如果说自上而下是顺着逻辑往下分析由果溯因是从逻辑下游往上游追关键函数分析就是在执行流上开了很多个小窗口。
加密函数程序的运算过程主要由标准加密算法构成所以只要找到这些标准加密算法的实现函数分析清楚参数和返回值然后
工具函数几乎没有程序离得开工具函数比如memcpy、memcmp、strstr、strlen这些函数hook
它们就可以一窥程序的数据流和字符串流。
如果样本自实现了这些工具函数而非使用库函数那么我们要找到并
这个分析方法的好处是快速很多时候比由果溯因都更快但它是一种更加不全面的分析方法而且需要分析者对加密算法有较深的理解。
大家在拜读完龙哥的文章以后,相信对干扰项和算法分析的方法论有了一个简单的了解.
AndroidEmulatorBuilder.for64Bit().addBackendFactory(new
DynarmicFactory(true)).build();Memory
emulator.getMemory();//作者支持19和23两个sdkmemory.setLibraryResolver(new
AndroidResolver(23));//创建DalvikVM利用apk本身可以为null//如果用apk文件加载so的话会自动处理签名方面的jni具体可看AbstractJni,这就是利用apk加载的好处vm
File(unidbg-android\\src\\test\\resources\\shopee\\com.shopee.my.apk));
emulator.createDalvikVM(null);vm.setJni(this);vm.setVerbose(true);//
要加这行,否则不生效哦.emulator.getSyscallHandler().addIOResolver(this);//加载so使用armv8-64速度会快很多DalvikModule
File(unidbg-android\\src\\test\\resources\\shopee\\libshpssdk.so),true);//调用jnidm.callJNI_OnLoad(emulator);module
dm.getModule();//Jni调用的类加载socWvvvuwwu
vm.resolveClass(com/shopee/shpssdk/wvvvuwwu);}Overridepublic
open:/system/usr/we-need-root/su
open:/system/lib64/libzygisk.so
open:/data/app/~~oONxdR2wXsaVN2qQTbgsSg/com.shopee.my-jns-B-GoPqIjRs55vzq5WA
com.github.unidbg.linux.file;import
com.github.unidbg.arm.backend.Backend;
com.github.unidbg.file.linux.IOConstants;
java.util.concurrent.ThreadLocalRandom;public
count)];randBytes(buf);System.out.println(toHex(buf));Pointer
将字节转换为两位十六进制表示hexString.append(String.format(%02X
ThreadLocalRandom.current().nextBytes(bytes);}
HEmZ77UhssssssssGjh7SdDI4ECew8Ni0CXZ2bqPHq/YYAXe2HFEaAEhgNmv0Q6S6zthC3obx382kCDQOqPOES3fzYA3i2B2ZBTz8BoUh2bl9K7gFpf13w1SakKXfJ46LXdHao4YU9/KoL403WHZ7PviglsqWLeLtJ2Hhz5kPSLFZ0KHteHQb8QEBxNWgV7yAB1bT0tlCLg/PBMMD3BH3hzigQyFcRnLFWSgiG/bcaocJ8JtEgUipW9YQ5JcPYwQoNV/OfyOwHO/VatOh3Vt6jFkWtUkb71kD9hf4X2AzscdYhGESD3Clb20H3VHc5aLYPKbAdWF5EUJt5u9frToquzheHLPofeJjIqe46BMjvEFjjKNI7xByn96Dr28PAO6ficw7w0tUVJUBNDCrifz6Nms2IqMqOa6EpnH3Ct0k9eyxC7SCycW9juDRUY78teyGOJqd6zVwJ54MsypCGoaznmHHQrmdxrHH0estvcQxngGgxVkBMdgBxe2ASOHww3aylOQlLWznMEAjiuKmqKsvrha8h9iQqzl1hMu0TRr7qX6Di0GyEICOY0SyNULYyki7lend67dDpuYOwBf3W8BD2fD9bpmwIyQ7GGJyQA4SgPV0r9FSmSalb6KnHgUp6iyArkud/jGYM5upLM2t84,
da155c6700000000000000100100000000000000000000000000}{253b8c85:
XSzJCUhssssssssW6QP9uqT4JO88VqJQVBT5K3rJyOCjigavaBzYZCv0UMcV5p8M81CJK5Gio/F1nPuYwb//GT6UsZuUB4lmxU187RxGnRcyhDhjmlbSqwIcZApRR0oNMWLje3EP4C9I5CAFtaelujQO1bUzEhR1PGqAOqt1LhqHhcyYAORH4nlrxmIw75xbim1mfQ/cIQuesumawvaBdvQ0syJBDHJBiEuW83rsYiZXkjW5M1hg3/co29fxryoJ6RHEw/5UMsDobutLzhFuvNLjFqckw1WoDXaeDJYFsyKLD258wzMb6y3XLYxqkgbhIQa2VXsNCW6wCLIZGhb8EKth6sVdPlf2FHPHUwnyEH7Bawueb8ZyJQ2ttPivGeofxlmFjvVxra4567mb8ywlQxkZOXicU20ehCiTeLyYoF5ApqiuawUBjWFEHyOyjEF0FDYENz0tUcKqPiIyCJRWvdWtIJODCwvyIKlssrDAnBExaFBsfg7yabK0jPBMbSi1m600C6lPxSJhJS2IgiWv2nIkCCH1Ks33qfr2erJziIZCm6VGkqzebewQkBcJPIW6cKiY4mslR/gjNtOqtTzC9iV1E4VeaXThlrsoWs74xeIPpRi/QgJYI52dVnBCMzCxqOhEMgYBT4yiToRrsT,
f0155c6700000000000000100100000000000000000000000000}
我们直接跳转到src/main/java/com/github/unidbg/unix/UnixSyscallHandler.java中,
JUzmVgUhssssssssQdlQxFFfZGYqSaSgzUR76C5RLev5MRK2RI7yAuYBKAXrGYJbCOnGdXNPqYDmwAcbi1JwCbWl3oTdP2cdJ/dLIJ4k2iGnKBvxm3sqBXJct9jJ1h8coPVIq9YEYomeQZE9yKcUxfAtuiMHHQ42KMMKA7yXhR0QioVjE20SSJM1G4PaX1AbR1PP33pEjJ4NpqZP/n7n2gLJilpx8cPsgHjIHpk9mQqguWQLQl76CU8FgJwfIGSed22PKNUmdK5axBYGsOrDVOlC63hf01WI9wLVqNHLJ0xO2cJcpvoNSvbkJ8SlIyPHuzmykJCftqsAQliYc12i3chvXSZueWaVsF7nxEp3jmoJgrVitx7QQBfwcYH2hMY1mda5DvScagW2ZoshRrlX3DB1h2Pu8wlCMw39n8fo9tEFJvHTTxgM3Xf5YS0bYs4hmr1iwrAdNNQRy1lSr4epiJQHfSVCXYcXx5yOlgP5avJ8tYoCSt93QyRZNksZBDAbSuOCpWy3bv7nCuE87R0cvSgCv6CNKV6bv4Y5BCUpe9SCaEs7Sn1OmAI6u/FBNRdoq3vR8x/n0PGDVZNjAXXkAVtHBy8Iw2hFduWfHqug6v8wmiSAfzbnpk16GSGUD8HksBUnwuLptUwMlpE,
21185c6700000000000000100100000000000000000000000000}{253b8c85:
JUzmVgUhssssssssQdlQxFFfZGYqSaSgzUR76C5RLev5MRK2RI7yAuYBKAXrGYJbCOnGdXNPqYDmwAcbi1JwCbWl3oTdP2cdJ/dLIJ4k2iGnKBvxm3sqBXJct9jJ1h8coPVIq9YEYomeQZE9yKcUxfAtuiMHHQ42KMMKA7yXhR0QioVjE20SSJM1G4PaX1AbR1PP33pEjJ4NpqZP/n7n2gLJilpx8cPsgHjIHpk9mQqguWQLQl76CU8FgJwfIGSed22PKNUmdK5axBYGsOrDVOlC63hf01WI9wLVqNHLJ0xO2cJcpvoNSvbkJ8SlIyPHuzmykJCftqsAQliYc12i3chvXSZueWaVsF7nxEp3jmoJgrVitx7QQBfwcYH2hMY1mda5DvScagW2ZoshRrlX3DB1h2Pu8wlCMw39n8fo9tEFJvHTTxgM3Xf5YS0bYs4hmr1iwrAdNNQRy1lSr4epiJQHfSVCXYcXx5yOlgP5avJ8tYoCSt93QyRZNksZBDAbSuOCpWy3bv7nCuE87R0cvSgCv6CNKV6bv4Y5BCUpe9SCaEs7Sn1OmAI6u/FBNRdoq3vR8x/n0PGDVZNjAXXkAVtHBy8Iw2hFduWfHqug6v8wmiSAfzbnpk16GSGUD8HksBUnwuLptUwMlpE,
21185c6700000000000000100100000000000000000000000000}
对memcpy、memcmp、strstr、strlen这几个方法进行监听.
emulator.attach().addBreakPoint(module.findSymbolByName(memcpy).getAddress(),
emulator.getContext();UnidbgPointer
registerContext.getPointerArg(1);int
registerContext.getIntArg(2);Inspector.inspect(src.getByteArray(0,
com.github.unidbg.linux.file;import
com.github.unidbg.arm.backend.Backend;
com.github.unidbg.file.linux.IOConstants;
java.util.concurrent.ThreadLocalRandom;public
(0xf0num)};num1;System.out.println(toHex:
将字节转换为两位十六进制表示hexString.append(String.format(%02X
ThreadLocalRandom.current().nextBytes(bytes);}
93d2e9772b93d71f014a3bc22397f7f5add37f6f7316数据长度一共52位前面8位暂时未知后面44位为随机数第15(下标14)位为
emulator.attach().addBreakPoint(module.findSymbolByName(memcpy).getAddress(),
emulator.getContext();UnidbgPointer
registerContext.getPointerArg(1);int
registerContext.getIntArg(2);Inspector.inspect(src.getByteArray(0,
memcpy:src.toString());emulator.getUnwinder().unwind();return
true;}});-----------------------------------------------------------------------------
md567e94e4ff6e091489d33c2cff29067b6,
^-----------------------------------------------------------------------------^
[0x040000000][0x040084a98][libshpssdk.so][0x084a98]
[0x040000000][0x040084228][libshpssdk.so][0x084228]
[0x040000000][0x040083d58][libshpssdk.so][0x083d58]
[0x040000000][0x04009122c][libshpssdk.so][0x09122c]
[0x040000000][0x04009a2a8][libshpssdk.so][0x09a2a8]
emulator.attach().addBreakPoint(module.base
unidbg-android/src/test/java/com/shopee/shpssdk/tracecode.txt;
true);emulator.traceCode(module.base
*[libshpssdk.so*0x091190]*[56fd498b]*0x40091190:*add
fp0xbffff540q00x220000000000000031(2.4E-322,
q10x180(5.3809861030072976E-43)
q30x70000000000000006(3.0E-323,
q40x10000000000000001(4.9E-324,
q50x40000000000000004(2.0E-323,
q60x20000000000000002(1.0E-323,
q70x1310000000000000131(1.507E-321,
q150x0(0.0)q160x51310000000000004131(8.2455E-320,
q180x51310000000000004131(8.2455E-320,
然后我们还没有看到的操作应该就是把x10进行大小端序的转换成小端序的排序即可.
x100x499602d2然后我们就可以把它丢给GPT生成代码了
[random.choice(0123456789abcdef)
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback