Assembly 如何知道应用程序已完成文件处理?

Assembly 如何知道应用程序已完成文件处理?,assembly,binary,reverse-engineering,fuzzing,Assembly,Binary,Reverse Engineering,Fuzzing,我正在尝试自动化我在应用程序中执行的检测,但问题是我正在处理的应用程序在处理后不会自动退出。例如,以任何pdfviewer/reader为例,如果我打开一个文件,就会显示该文件,并且我可以看到应用程序已经处理了该文件 通过应用程序处理文件,我的意思是应用程序已成功显示文件 应用程序可以是用于ex-adobe reader、xpdf、foxitreader的任何GUI pdf查看器,也可以是用于ex-gpicview的任何图像查看器等。文件格式可以是任何类型,而不是任何特定的文件格式 此外,我没有

我正在尝试自动化我在应用程序中执行的检测,但问题是我正在处理的应用程序在处理后不会自动退出。例如,以任何pdfviewer/reader为例,如果我打开一个文件,就会显示该文件,并且我可以看到应用程序已经处理了该文件

通过应用程序处理文件,我的意思是应用程序已成功显示文件

应用程序可以是用于ex-adobe reader、xpdf、foxitreader的任何GUI pdf查看器,也可以是用于ex-gpicview的任何图像查看器等。文件格式可以是任何类型,而不是任何特定的文件格式

此外,我没有应用程序的源代码,我正在处理应用程序的二进制代码

但是,在自动化过程中,我想知道应用程序何时处理了文件。我最初能想到的是,会有一些基本块,表示在执行之后,它已经完成了对文件的处理,并在执行特定基本块时退出我的指令插入


但是这里的问题是如何识别基本块?

对于黑盒可执行文件,您可以自动执行的最简单、最可靠的操作可能是查看它们的CPU使用情况。当他们完成加载时,他们的所有线程都应该(大部分)空闲,如果他们等待具有非无限超时的事件,可能会偶尔醒来。(和其他GUI事件,如鼠标移动)

确保等待足够长的时间来检测磁盘I/O阻塞与等待用户输入阻塞之间的差异。(在类Unix操作系统上,这是磁盘睡眠和睡眠之间的区别,如
D
S
top
的进程列表中所示。)

如果您不想依赖操作系统来检测磁盘睡眠而不是常规睡眠,只需等待比最大磁盘I/O请求服务时间长几倍的时间(约为磁盘延迟的几倍,如果被测进程是唯一执行I/O的进程,则等待时间较低)。如果黑盒进程在该时间间隔内没有使用任何CPU时间,则可以假定它已完成加载并在屏幕上显示文件

当然,正如@Ped7g所指出的,它可能没有解析整个文件。例如,当用户滚动浏览一个大的PDF文件时,它可能会根据需要延迟加载。监视CPU时间应该是一种合理的方法,可以在以编程方式向进程发送page down命令后检测进程何时完成更新

我认为你应该能够从中得到可靠的结果。如果您想可靠地确定一个进程是在无需等待的情况下完成加载的,那么您可能需要考虑多个输入的启发式方法,如系统I/O性能或未完成的磁盘IO请求


正如评论中所讨论的,在文件描述符上寻找达到EOF的进程在这方面是不可靠的(它可能会映射它)。我将把这个放在这里,以防它对任何人都有趣或有用,但为了您的使用,您可能希望完全忽略它。充其量,您可以将其作为启发式的输入,以决定何时完成流程加载

在大多数操作系统上,都有一些用于进程跟踪其他进程的工具。在Linux上,主要的是ptraceAPI。像
strace
这样的命令使用它来跟踪系统调用。我相信Windows也有类似的功能,我想OSX也有

因此,您可以在PDF上查找open()系统调用以找到正确的fd,然后在其上查找mmap、read()和close()系统调用。如果read()返回0,则为EOF。如果它是在没有mmap的情况下关闭的,则进程将使用它完成(除非它再次打开它,或者出于某种原因使用dup()或dup2()

您可以解析strace的文本输出,也可以自己使用ptraceAPI


或者,在Linux上,您可以在
/proc//fdinfo/
中查看文件位置。其他操作系统可能有类似的功能来查看打开的文件描述符/文件句柄的文件位置

例如,我碰巧打开了显示PDF的
evice
open。在`/proc中/

$ ll /proc/4241/fd
...
lr-x------ 1 peter peter 64 Oct 21 06:43 14 -> /f/p/docs/agner_fog.microarchitecture.pdf    # is anyone really surprised this is the PDF I had open?  :P
...
$ ls -lL /proc/4241/fd/14       # follow the symlink to see the file size
-rw-rw-r-- 1 peter peter 2078709 Feb  4  2016 /proc/4241/fd/14

$ m /proc/4241/fdinfo/14        # alias for less
pos:    2078709
flags:  0100000
mnt_id: 49

这证实了我的猜测,当完成读取文件时,evince将在EOF处显示文件位置。您可能需要等待几毫秒,然后再次检查,以防测试中的软件再次在文件上循环。

是否需要关闭或EOF指示应用程序已完成处理,假设我已在缓冲区中读取文件,然后显示我正在使用该缓冲区的数据。通过文件处理,我并不意味着文件已被完全读取。我的意思是它已经成功地显示出来了。@user2823667:是的,这是一个很好的观点。也许这两者的结合和等待它停止使用CPU时间是你最好的选择。只要等到它读取了文件,并且在大约40毫秒或其他时间内没有占用大量CPU时间,这取决于您的磁盘I/O延迟。(在等待I/O时避免误报)。@user2823667:如果您可以跟踪它的任何线程是否耗尽了整个时间片,而不是它们是否刚刚醒来处理GUI事件并立即返回睡眠状态,我认为这将是需要寻找的。如果应用程序映射文件,关闭它,然后再处理它,该怎么办?当文件只是其地址空间的一部分时,您无法(轻松)检查应用程序对该文件的访问。@ShacharShemesh:好的,监视文件描述符通常是不可靠的。等待进程的CPU使用率接近零的时间超过磁盘I/O延迟的几倍,您的磁盘I/O延迟应该始终有效。如果您想编写更多代码,以便在某些情况下更确定地进行检测(因此不必等待很长时间以确保进程现在处于空闲状态),则可以使用strace来检测进程是否已关闭文件,而无需对其进行映射。但是我想看看进程的CPU