Apk脱壳

Q 准备工作 Frida frida-15.1.14-py3.8-macosx-10.9-x86_64.egg 放到~目录(pip install frida报错时会出现目录地址) pip install frida pip install frida-tools 网易mumu frida-server-15.1.14-android-x86_64 需要确认底层架构,网易mumu是x86_64 FRIDA-DEXDump 脱壳 adb push ~/Downloads/frida-server-15.1.14-android-x86_64 /data/local adb shell cd /data/local chmod 777 frida-server-15.1.14-android-x86_64 ./frida-server-15.1.14-android-x86_64 通过网易mumu打开APP 通过FRIDA-DEXDump执行 python main.py done !

December 13, 2021 · 1 min · quicksandzn

微信小程序反编译

准备工作 网易mumu模拟器 Root Explorer APK ES文件浏览器 微信 小程序反编译工具 破解 打开微信搜索对应的小程序 最好提前清空微信小程序缓存这样比较好找到对应的小程序 通过Root Explorer找到对应目录 /data/data/com.tencent.mm/MicroMsg/7e0c9d2b7278c1fac318e91eaeae4c0f/appbrand/pkg 通过wxappUnpacker bingo.sh 反编译得到源码

August 19, 2021 · 1 min · quicksandzn

字体加密破解

页面分析 view page source <span class="gzfont" data-v-48736255>&#58928;&#59854;&#58397;&#60492;-&#59854;&#59246;</span> 可以看到以上的字体是有加密的 我们通过gzfont这个class去css中寻找 .gzfont { font-family: gzfont } @font-face { font-family: "gzfont"; src: url(https://example.woff2) format("woff"); font-weight: 400; font-style: normal } src中的url就是字体文件的下载地址 字体文件解析 经过多次刷新发现css里面的字体文件是不会变的,我们只需要把字体文件解析出来匹配好对应关系即可 FontEditor在线浏览字体文件 通过python的TTFont把字体文件解析成XML from fontTools.ttLib import TTFont font = TTFont('/Users/zn/Downloads/font.woff2') font.saveXML('font.xml') 一个GlyphID里面的name对应一个TTGlyph对象,它是用来绘制一个字 <GlyphOrder> <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> <GlyphID id="0" name=".notdef"/> <GlyphID id="1" name=".null"/> <GlyphID id="2" name="nonmarkingreturn"/> <GlyphID id="3" name="x"/> <GlyphID id="4" name="uniE1D0"/> <GlyphID id="5" name="uniE325"/> <GlyphID id="6" name="uniE41D"/> <GlyphID id="7" name="uniE4D9"/> <GlyphID id="8" name="uniE52E"/> <GlyphID id="9" name="uniE630"/> <GlyphID id="10" name="uniE76E"/> <GlyphID id="11" name="uniE891"/> <GlyphID id="12" name="uniE9CE"/> <GlyphID id="13" name="uniEAF2"/> <GlyphID id="14" name="uniEC4C"/> <GlyphID id="15" name="uniF7C2"/> <GlyphID id="16" name="uniF88A"/> </GlyphOrder> <TTGlyph name="uniEAF2" xMin="43" yMin="-40" xMax="523" yMax="716"> <contour> <pt x="133" y="180" on="1"/> <pt x="148" y="103" on="0"/> <pt x="185" y="69" on="1"/> <pt x="221" y="38" on="0"/> <pt x="276" y="35" on="1"/> <pt x="326" y="35" on="0"/> <pt x="384" y="78" on="1"/> <pt x="427" y="123" on="0"/> <pt x="427" y="250" on="0"/> <pt x="387" y="290" on="1"/> <pt x="345" y="331" on="0"/> <pt x="284" y="331" on="1"/> <pt x="257" y="331" on="0"/> <pt x="220" y="321" on="1"/> <pt x="230" y="406" on="1"/> <pt x="236" y="400" on="0"/> <pt x="239" y="399" on="1"/> <pt x="254" y="399" on="0"/> <pt x="245" y="399" on="1"/> <pt x="303" y="411" on="0"/> <pt x="348" y="428" on="1"/> <pt x="394" y="459" on="0"/> <pt x="394" y="524" on="1"/> <pt x="395" y="579" on="0"/> <pt x="361" y="604" on="1"/> <pt x="330" y="635" on="0"/> <pt x="274" y="635" on="1"/> <pt x="222" y="635" on="0"/> <pt x="195" y="604" on="1"/> <pt x="153" y="572" on="0"/> <pt x="142" y="504" on="1"/> <pt x="52" y="520" on="1"/> <pt x="69" y="612" on="0"/> <pt x="127" y="660" on="1"/> <pt x="186" y="699" on="0"/> <pt x="272" y="716" on="1"/> <pt x="326" y="710" on="0"/> <pt x="383" y="683" on="1"/> <pt x="433" y="659" on="0"/> <pt x="487" y="569" on="0"/> <pt x="487" y="470" on="0"/> <pt x="462" y="432" on="1"/> <pt x="445" y="394" on="0"/> <pt x="371" y="371" on="1"/> <pt x="451" y="356" on="0"/> <pt x="487" y="309" on="1"/> <pt x="519" y="247" on="0"/> <pt x="523" y="190" on="1"/> <pt x="523" y="95" on="0"/> <pt x="383" y="-40" on="0"/> <pt x="276" y="-40" on="1"/> <pt x="179" y="-40" on="0"/> <pt x="116" y="18" on="1"/> <pt x="52" y="82" on="0"/> <pt x="43" y="155" on="1"/> <pt x="133" y="174" on="1"/> </contour> <instructions/> </TTGlyph> 读取CMAP code是16进制的数字 对应页面的数字值 name对应字体编码 可以得出 58928==0xe630==uniE630 <cmap_format_4 platformID="0" platEncID="3" language="0"> <map code="0x78" name="x"/><!...

July 27, 2021 · 3 min · quicksandzn

Zuul网关跨域问题

跨域概述 跨域就指着协议,域名,端口不一致,出于安全考虑,跨域的资源之间是无法交互的。简单说就是协议不通,域名不通,端口不同都会产生跨域问题 跨源资源共享(CORS) 跨源资源共享 (CORS) (或通俗地译为跨域资源共享)是一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头 遇到的问题 The ‘Access-Control-Allow-Origin’ header contains multiple values ‘, ‘, but .. 单个项目解决跨域问题 @Configuration public class WebMvcConfigurer extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowCredentials(true) .allowedHeaders("*") .allowedOrigins("*") .allowedMethods("*"); } } 因为我们用Zuul做网关,在网关层也配置了CORS跨域问题解决,这样就会导致遇到上述错误 解决方法 在Zuul配置文件添加 sensitiveHeaders: Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Credentials

July 23, 2021 · 1 min · quicksandzn

Redis Rehash

Rehash rehash执行条件 关键说明 负载因子::load_factor = ht[0].used / ht[0].size BGSAVE::fork一个子进程来创建RDB文件,父进程可以继续处理命令请求 BGREWRITEAOF:AOF重写缓冲区,由于redis是单进程的,为了不在进行重写时阻塞服务,redis使用了子进程的方式进行AOF重写 redis中每次开始执行aof文件重写或者开始生成新的RDB文件或者执行aof重写/生成RDB的子进程结束时,都会调用updateDictResizePolicy->dictDisableResize函数,所以从该函数中,也可以看出来,如果当前没有子进程在执行aof文件重写或者生成RDB文件,则运行进行字典扩容;否则禁止字典扩容。 扩容 以下条件中的任意一个被满足时执行扩容 服务器目前没有在执行 BGSAVE 命令或者 BGREWRITEAOF 命令, 并且哈希表的负载因子大于等于 1 服务器目前正在执行 BGSAVE 命令或者 BGREWRITEAOF 命令, 并且哈希表的负载因子大于等于 5 缩容 databasesCron->tryResizeHashTables函数检查用于保存键值对的redis数据库字典是否需要缩容 最小size是4 服务器目前没有在执行 BGSAVE 命令或者 BGREWRITEAOF 命令,并且哈希表的负载因子小于 0.1 时, 程序自动开始对哈希表执行收缩操作 rehash执行过程 为字典的 ht[1] 哈希表分配空间=ht[0].used= ht[0] 当前包含的键值对数量 如果执行的是扩展操作, 那么 ht[1] 的大小为 为第一个大于等于ht[0].used * 2 的 2^n 如果执行的是收缩操作, 那么 ht[1] 的大小为为第一个大于等于 ht[0].used的 2^n 将保存在 ht[0] 中的所有键值对 rehash 到 ht[1] 上面: rehash 指的是重新计算键的哈希值和索引值, 然后将键值对放置到 ht[1] 哈希表的指定位置上。 当 ht[0] 包含的所有键值对都迁移到了 ht[1] 之后 (ht[0] 变为空表), 释放 ht[0] , 将 ht[1] 设置为 ht[0] , 并在 ht[1] 新创建一个空白哈希表, 为下一次 rehash 做准备。 渐进式Rehash rehash执行条件等同于Rehash 在渐进式 rehash 执行期间, 新添加到字典的键值对一律会被保存到 ht[1] 里面, 而 ht[0] 则不再进行任何添加操作: 这一措施保证了 ht[0] 包含的键值对数量会只减不增, 并随着 rehash 操作的执行而最终变成空表。 rehash执行过程 为 ht[1] 分配空间, 让字典同时持有 ht[0] 和 ht[1] 两个哈希表。 在字典中维护一个索引计数器变量rehashidx,并将它设置为0,表示rehash工作正式开始 在rehash进行期间,每次对字段执行添加、删除、查找、更新操作的时候,程序除了执行指定的操作意外,还会顺带将 ht[0] 哈希表在 rehashidx 索引上的所有键值对 rehash 到 ht[1] , 当 rehash 工作完成之后, 程序将 rehashidx 属性的值++ 随着字典操作的不断执行, 最终在某个时间点上, ht[0] 的所有键值对都会被 rehash 至 ht[1] , 这时程序将 rehashidx 属性的值设为 -1 , 表示 rehash 操作已完成。 定时辅助rehash 虽然redis实现了在读写操作时,辅助服务器进行渐进式rehash操作,但是如果服务器比较空闲,redis数据库将很长时间内都一直使用两个哈希表。所以在redis周期函数中,如果发现有字典正在进行渐进式rehash操作,则会花费1毫秒的时间,帮助一起进行渐进式rehash操作。...

July 22, 2021 · 1 min · quicksandzn

Redis 持久化方式

Redis 的两种持久化方式(RDB与AOF) RDB RDB (Redis DataBase) 持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。 RDB触发机制分为手动触发和自动触发 手动触发 SAVE命令:阻塞当前Redis服务器,知道RDB过程完成为止 BGSAVE:Redis 进程执行fork()操作创建出一个子进程,在后台完成RDB持久化的过程 自动触发 配置(redis.conf) == BGSAVE save 900 1 //服务器在900秒之内,对数据库执行了至少1次修改 save 300 10 //服务器在300秒之内,对数据库执行了至少10修改 save 60 1000 //服务器在60秒之内,对数据库执行了至少1000修改 优势 整个 Redis 数据库将只包含一个文件,十分易于备份 性能最大化,对于 Redis 的服务进程而言,在开始持久化时,它唯一需要做的只是 fork 出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大地避免服务进程执行 IO 操作 相对于 AOF,基于 RDB 数据文件来重启和恢复 Redis 会更快 劣势 无法最大限度地避免数据丢失,系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失 由于 RDB 是通过 fork 子进程来协助完成数据持久化工作的,因此,如果当数据较大时,可能会导致整个服务器停止服务数毫秒,甚至数秒 AOF AOF (Append Only File) 持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,只许追加文件但不可以改写文件,可以打开文件看到详细的操作记录 同步策略 appendsync always #每次有数据修改发生时都会写入AOF文件 appendsync everysec #每秒同步一次,该策略为AOF的缺省策略 appendsync no #从不同步。高效但是数据不会被持久化 优势 最大限度地避免数据丢失,默认的 everysec 策略可以记录下每秒的修改操作,但如果一秒内宕机,有数据丢失 AOF 对日志文件的写入操作采用的是 append 模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。 劣势 对于同一份数据来说,AOF 文件通常要大于 RDB 文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。 根据同步策略的不同,AOF 在运行效率上往往会慢于 RDB。但是每秒同步策略的效率还是比较高的。 总结 二者选择的标准,就是愿意牺牲一些性能,换取最少的数据丢失(AOF),还是牺牲一些数据来换取更高的性能(RDB)。实际中应该综合使用 AOF 和 RDB 两种持久化机制,用 AOF 来保证数据不丢失,作为数据恢复的第一选择; 用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复...

July 21, 2021 · 1 min · quicksandzn

Redis 数据类型

数据类型及使用场景 String:缓存、计数器、分布式锁等 List:链表、队列、微博关注人时间轴列表等 Hash: 用户信息、Hash 表等 Set: 去重、赞、踩、共同好友等 Sorted Set: 访问量排行榜、点击量排行榜等 Redis Object typedef struct redisObject { unsigned type:4; // 类型 unsigned encoding:4; // 一个对象可能包含多个encoding unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */ int refcount; // 引用计数 实现内存回收机制 void *ptr; // 存储的值 } robj; /* Object types */ #define OBJ_STRING 0 #define OBJ_LIST 1 #define OBJ_SET 2 #define OBJ_ZSET 3 #define OBJ_HASH 4 /* Objects encoding. Some kind of objects like Strings and Hashes can be * internally represented in multiple ways....

July 21, 2021 · 2 min · quicksandzn

缓存的场景问题及解决方案

缓存雪崩 描述 大量的 key 设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时 DB 请求量大、压力骤增,引起雪崩。 解决方案 分级缓存 给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。 缓存穿透 描述 访问一个不存在的 key 时,缓存不起作用,请求会穿透到 DB ,流量大时 DB 自然就会瘫痪。 解决方案 利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试。 即使查询到的数据为空,仍把该空值缓存,还需要设置过期时间。 布隆过滤器,内部维护一系列合法有效的 key 就可以迅速判断出请求所携带的key是否合法有效。如果不合法,则直接返回。 缓存击穿 描述 一个存在的 key,在缓存过期的一刻,恰好在这个时间点对这个 key 有大量的并发请求过来,这个时候大量的请求可能会瞬间瘫痪掉 DB 。 解决方案 分级缓存 互斥锁 缓存预热 描述 系统上线后,提前将数据刷到缓存。避免用户在访问的时候,先去查询数据库。 解决方案 数据量不大的时候,工程启动的时候进行加载缓存 数据量大的时候,设置一个定时任务脚本,进行缓存的刷新 数据量太大的时候,优先保证热点数据进行提前加载到缓存 缓存降级 缓存降级是指缓存失效或缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或访问服务的内存数据

July 21, 2021 · 1 min · quicksandzn