瞎记录
1、博客的一些更新
- 服务器
服务器使用水萌大佬的机器也有三个月了,在刚开始的时候因为他们那边也是在不断调不断加东西,所以经常会爆炸,或者重启路由导致ddns ip改变。不过自从过年那次大爆炸之后一来,已经相当稳定运行了半个月了,可喜可贺,可喜可贺。
原始的vultr本来想着会被废置,不过我留下来当作自己的socks代理了(不是ss,纯socks5)不知道为什么好像比别人用的ss还稳,老见到他们说某某又墙了之类的,可能因为只有我一个人用吧(笑
SSL的话,本来我准备换le的野卡,结果还延期公开了。前两天稍微用 acme.sh 测试了一下可以csr同时生成两个域名的证书,爬丝的dnspod api我之前给他搞ddns ip自动更新的时候要过也可以用,到时候再帮他cron上
- 音乐播放
两周前更改了一下逻辑,之前设置仅在首页播放,因为没有可靠的跨tab通信确保不重复播放的方法。
然后想到了一个方法,用localStorage保存一个值,不存在的时候记录为当前页并自动播放,并设置关闭时删除值;存在且不是当前页的时候不自动播放,不过生成并显示播放器,点击的时候覆盖值并在关闭时删除值
这样就完成了一个简陋的单tab播放的逻辑
- 侧栏
并不满与现在的顶端固定实现,最理想的是先跟随滚动,到底后固定,继续向下返回时跟随向上,到顶后再固定,这种感觉
写了个跟随scroll的之后发现很难看,去爬丝站上看了看实现发现是动态切换position,虽然美观一些但还是有瑕疵。最后采用了youtube式的侧栏,即独立滚动条
那阵子倒腾redive,虽然说cri的key早都有了,但还是手痒搞了一个这玩意儿
在之前给 @CaiMiao 翻腾PlayerPrefs键名解密的时候看到C# string类的格式的时候对这些对象在内存中的分布又有了一些理解
按照Il2CppDumper导出的类结构,String类是:
// Namespace: System public sealed class String : IConvertible, IComparable, IEnumerable, ICloneable, IComparable`1<string>, IEquatable`1<string>, IEnumerable`1<char> // TypeDefIndex: 27 { // Fields private int length; // 0x10 private char start_char; // 0x14 public static readonly string Empty; // 0x0 private static readonly char[] WhiteChars; // 0x8 // Methods public void .ctor(char* value, int startIndex, int length); // 0x101639C88 public void .ctor(char[] value, int startIndex, int length); // 0x101639C8C public void .ctor(char[] value); // 0x101639C90 public void .ctor(char c, int count); // 0x101639C94 private static void .cctor(); // 0x101639C98 private bool System.IConvertible.ToBoolean(IFormatProvider provider); // 0x101639D40 // other methods ... }
然后观察了几个其他的结构体后,大概懂了这些对象的组成:存储一个对象存的肯定是个指针,指针指向的地方0-8是所有函数的地址,C风格函数中参数开头会有一个thisPointer,static调用的时候取0,public/private等等调用就传递对象地址。而比如取string.length的时候就是*((int*) (string+0x10) )
而理解了cs的string类的内存表示之后,我就着手写了一个CSStringReader:
NSString* CSStringReader(char* stringPtr) { int stringLen = *((int*)(*( (long*)stringPtr ) + 0x10)); char* cStringPtr = (char*)(*( (long*)stringPtr ) + 0x14); NSData *data = [[[NSData alloc] initWithBytesNoCopy:cStringPtr length: stringLen * 2 freeWhenDone:NO] autorelease]; NSString * string = [[[NSString alloc] initWithData:data encoding:NSUTF16LittleEndianStringEncoding] autorelease]; return string; }
而写的时候碰到的坑是我hook了CriWareDecryptionConfig的构造函数,但是永远读不到正确的key string地址。我倒腾了能有两个小时也没搞出来,然后突然想到,会不会是延后设置的?(我在ida中查看构造函数的时候认为已经设置过key的值,所以一直理解是生成的时候已经设置好了)在代码中加了个Timer触发之后果然读取到了正确的stringLength,果然够坑。
在最后为了(未来可能有的)使用简便,把代码固定函数偏移转移到了插件plist中,这样搞其他的就不需要重新编译了,美滋滋
(说起来,我好像不应该用long,key的长度是固定int64,应该用long long的……不管了,都8102了谁还用32位的ios啊(小并感))