only998 发表于 2021-12-31 09:29

通过句柄获取文件名,是否有更好的方法?

本帖最后由 only998 于 2021-12-31 14:14 编辑

一、原由
    用x64dbg调试文件时,有时需要跟踪文件读写来确定算法,我通常都是先在Createfile上下断点,然后再在Readfile上下断点,但是这样在读写的文件比较多比较杂的时候不方便。最近在写自用的x64dbg插件,正好想到这个,就准备加入读取到指定文件时断下这个功能。经过一段时间的摸索和查找资料,目前我已经确定可以在 ReadFile的时候,通过 GetFinalPathNameByHandle 这个函数获取到句柄对应的文件名,但是这个函数只能获取当前进程打开的句柄,无法跨进程。

二、解决方法
    目前我有两个解决方案,但都感觉不够好。首先第一个:编写一个专用的dll,在调试程序时使用x64dbg加载到目标程序的地址空间,然后inline hook ReadFile这个函数,分析出句柄对应的文件名,再调用专门给x64dbg断点准备的呼叫函数。这个方法的缺点就是必须额外编写一个dll,并且载入的过程中可能触发x64dbg的其他断点(比如你设置了dll载入断点),造成麻烦,过程不太顺畅。另一个方法是通过 x64dbg申请一块内存区域,汇编填入调用 GetFinalPathNameByHandle 需要的代码,x64dbg在捕获到 ReadFile的断点时,将句柄参数通过x64dbg创建新的线程调用GetFinalPathNameByHandle 对应的汇编,获取文件名。这个方法要频繁的创建新的线程,开销比较大,而且64位模式下申请合适的内存位置也是个麻烦。
    再补充一个方法,就是每次createfile 或者 openfile的时候记录文件名和成功时返回的句柄,然后ReadFile时候检查文件名,但是这种方法缺陷也很大,一个是 进入CreateFile到返回结果这个过程是需要一点时间的,在多线程程序读写时容易导致记录错误,另一个就是CreateFile似乎可以多次打开?还有记录对应的CloseFile,记录也是个麻烦事,比较难办。

三、讨论
想问下各位大佬是否有更好的思路,或者更好的api可以直接跨进程通过句柄获取到文件名的。
    另外是否有现成的工具有上述功能的?

四、解决
    非常感谢 你与明日 大佬提供的解决方案,现在解决情况如下:
1、使用 OpenProcess(PROCESS_DUP_HANDLE, false, DbgGetProcessId()) 远程打开x64dbg正在调试的程序进程,保存获得的句柄 remoteHandle
2、x64dbg在 ReadFile 上下断点,并且注册断点回调函数,捕获断点时取得将要读取文件的句柄 handle
3、使用 DuplicateHandle(远程进程句柄,远程文件句柄,当前进程句柄,&当前文件句柄, NULL,false,DUPLICATE_SAME_ACCESS)创建一个新的文件句柄
3、使用GetFinalPathNameByHandle(当前文件句柄, 缓冲区,缓冲区长度,VOLUME_NAME_DOS )获取文件名,完美决绝问题。

shallies 发表于 2021-12-31 09:48

顶一把,期待大神跟帖

zxsbk 发表于 2021-12-31 09:51

感觉你就是大神

你与明日 发表于 2021-12-31 09:58

0.OpenProcess(PROCESS_DUP_HANDLE)
1.GetProcessHandleCount
2.DuplicateHandle
3.ZwQueryObject

only998 发表于 2021-12-31 10:00

你与明日 发表于 2021-12-31 09:58
0.OpenProcess(PROCESS_DUP_HANDLE)
1.GetProcessHandleCount
2.DuplicateHandle


感谢大佬,马上试下!

冥界3大法王 发表于 2021-12-31 10:18

本帖最后由 冥界3大法王 于 2021-12-31 10:27 编辑

@only998
https://www.52pojie.cn/thread-1569176-1-1.html
执行形如下面的这种:
DbgScriptCmdExec("d 401000"); 就能直接传值给命令行了
问题来:如何把任意x64dbg的命令行执行结果传递给剪贴板?

冥界3大法王 发表于 2022-1-2 10:28

@@only998
楼主跑哪去了,躲起来怕见人了。{:301_971:}
页: [1]
查看完整版本: 通过句柄获取文件名,是否有更好的方法?