为了验证设计可行性,一般我会先快速建模,用delphi实验一下,因为VCL和编译器以及OO的思想使得模型实现起来非常快,尤其自带基础类型String非常好用而且速度极快,但是源码里是看不到的,编译器自动支持,然而在测试大规模hook api的时候,字符串操作会偶尔缺失中间的某个字节,这就是我为何不相信第三方库的原因了,在追影C实现的挂钩模块中,我没有使用任何第三方库(记录模块使用了cuckoo monitor,挂钩模块和记录器是两个东西),甚至连memcpy这些都自己用汇编做了实现,使得挂钩模块中的一切可控,随时知道问题出在哪里。在底层的开发中,任何黑箱对我来说都是一种隐患,当出问题的时候我不得不打开每个黑箱,去审计大量的第三方代码,事实上也不止一次发现第三方代码中存在大量问题。也是带着这种怀疑精神,我逆向了编译器是如何实现其自带的string类型。
结果如下:
struct unicodestring{
dword reference;
dword length;
word content[];
}
跟COM的做法有点类似。每次进入有字符串类型的函数前,编译器自动加上一个增加引用的调用,退出函数前减少引用。我推测在引用为0的时候会释放内存,跟COM的做法一样。而通过反汇编发现,实际上字符串变量内的地址指向的是content的地址,而不是unicodestring的地址,编译器通过content地址的偏移去操作reference和length,由于提前知道了长度,比通过检查\0结尾,把整个串撸一遍的字符串操作要快的多。