吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 469|回复: 7
收起左侧

[求助] veh hook时如何构造delphi ansistring

[复制链接]
回帖奖励 25 CB吾爱币 回复本帖可获得 5 CB吾爱币奖励! 每人限 1 次
zhuxiangyu1024 发表于 2024-3-23 16:17
本帖最后由 zhuxiangyu1024 于 2024-3-23 16:34 编辑

c写了一段hook,将某个delphi应用的寄存器 eax指向的字符串修改为2,假如这个delphi的eax指向的字符串是个c字符串,程序是可以正常运行的,一旦为delphi string程序无法正常运行。

略过其他hook相关的代码,代码仅仅只有v指向的不同,当程序的eax寄存器指向一个c字符串的时候,可以直接将寄存器指向 v

char* v = "2";

而delphi anstring的结构 为      refcount| size| strbuff   ,我尝试在内存里面直接写入字节数据,虽然eax确实指向了这段数据,但是程序直接崩溃了。                     
char data[] = {0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x32,0x0,0x0,0x0};
char* v = (char*)&data[8];


对于delphi应用的逆向,假如我要写入一个新的key,应该早就有公开的方案了吧,搜了半天没啥相关的内容。


还有个200币的帖子没结,哪位老兄有思路的可以一起结给你。


有回帖奖励每个5币,勿灌水,集思广益。

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

solly 发表于 2024-3-23 17:24

回帖奖励 +5 CB吾爱币

不能超过原有长度吧,可能会溢出导致崩溃。
引用计数要用原来的数值,你改小了可能会内存泄漏,泄漏多了也会有问题。
用delphi string 时,不能用c 的strcpy, strcmp之类的函数,中间有0值会拷贝不全数据。
 楼主| zhuxiangyu1024 发表于 2024-3-23 18:01
solly 发表于 2024-3-23 17:24
不能超过原有长度吧,可能会溢出导致崩溃。
引用计数要用原来的数值,你改小了可能会内存泄漏,泄漏多了也 ...

我现在想实现的效果倒是简单一点,就是想在veh hook的时候把寄存器指向的字符串改成新的字符串,如果是个c字符串直接把指针给寄存器就行了,但是如果是个delphi 应用字符串的结构有点不同,我尝试直接生生在内存里写了这么个结构的字符串,然而似乎漏了哪里,寄存器的地址倒是指向了这里,应用直接崩溃了。 奈何看了点delphi的文档没啥思路,资料也少,我在想是不是写个delphi的dll来生成这么个字符串暴露出来,但是我看大白补丁倒是有这么个把寄存器的内存数据改为delphi string的功能,感觉应该可以实现的。
yes2 发表于 2024-3-23 18:10

回帖奖励 +5 CB吾爱币

你可能需要分析一下delphi的这个字符串类。
比如std::string,字符串内容小于16字节的话就不会分配额外内存,超过16字节就会分配额外内存,这就涉及到类析构的时候的资源释放。
如果是无论字符串长度,类的结构都是统一的refcount| size| strbuff,那么就要确认一下这个类是在栈还是在堆,如果是堆,你需要先用对应的释放方式去释放原始的delphi字符串类,再用对应的分配方式去分配新的空间;如果是栈内容,那么你的data数组最好也是在原有的线程栈上构建
爱飞的猫 发表于 2024-3-23 18:27

回帖奖励 +5 CB吾爱币

char data[] = {0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x32,0x0,0x0,0x0};
char* v = (char*)&data[8];

data 在堆栈上,退出你的 veh 处理函数后这段内容就不能保证了吧。

需要看看 Delphi 是如何申请字符串缓冲内存,用相同的方法把旧的释放然后建立新的,最后把指针覆盖。
DEATHTOUCH 发表于 2024-3-23 18:47

回帖奖励 +5 CB吾爱币

Delphi的RTL里面有基本的堆内存管理函数(其实都在system.pas文件里面),由结构TMemoryManagerEx表示,有GetMem、FreeMem、ReallocMem等常用函数,所有的字符串都是通过这些函数管理内存。

不过回到你提供的代码,我发现一个可能的问题:

char data[] = {0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x32,0x0,0x0,0x0};
在这里,你把引用计数设为了1,那么很有可能Delphi的RTL就会在使用完成之后试图释放这个内存,而要作为常量,引用计数应该为为-1。
lies2014 发表于 2024-3-23 22:55

回帖奖励 +5 CB吾爱币

先用 IDR 之类的工具看看是什么函数调用了这个字符串,再查函数定义找到确切的参数,还要搞清楚 Delphi 的版本号
Delphi 的 String 在 2007 及以前的版本中等价于 AnsiString ,后面的版本变成了 WideString
而从 Delphi 2009 开始的版本中 AnsiString 前面是多了描述代码页的4字节的,真正的字符串是从第 13 字节开始的
有点乱,搞不清楚的话的确很容易出错的
 楼主| zhuxiangyu1024 发表于 2024-3-29 11:03
爱飞的猫 发表于 2024-3-23 18:27
char data[] = {0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x32,0x0,0x0,0x0};
char* v = (char*)&data[8] ...

你这个回答是我遇到的情况,我有个200币的关联这个帖子的悬赏,需要的话可以回一下我结给你。
https://www.52pojie.cn/thread-1904633-1-1.html
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 16:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表