DOSBox屏幕截图到特定文件

时间:2015-07-17 14:13:21

标签: bash dosbox xdotool

我有一个项目,我正在尝试' stream'一个DOS游戏,在Ubuntu上的DOSBox中工作。我们的想法是截取屏幕截图,然后将其上传到服务器。要从DOSBox中截取屏幕截图,我使用xdotool来触发键组合" Ctrl + F5",这会触发屏幕截图。然后将屏幕截图保存到/ capture文件夹中,我可以从中找到该文件。

问题是屏幕截图名为progName_000.png,progName_001.png,...我希望覆盖单个文件。有可能实现吗?

目前我正在使用下面可怕的bash代码:

WID=`xdotool search --limit 1 --name "DOSBox" 2>/dev/null`
while [ 1 ]; do
    fN=`ls ./DOSBox/capture/ | head -1`
    cp ./DOSBox/capture/$fN ./img.png
    rm ./DOSBox/capture/*

    xdotool key --window $WID Ctrl+F5
    sleep 0.10;
done

每100毫秒,我读取捕获文件,获取我遇到的第一个文件,将其复制到./img.png,然后清除捕获文件夹,并拍摄另一个屏幕截图。什么是更好的选择?

(PS:上面的代码是简化的;通常我将捕获的图像复制到多个图像; img0.png和img1.png,这样当一个被写入时,另一个可以被读取,就像页面翻转一样。无论如何。)

1 个答案:

答案 0 :(得分:0)

我通过直接篡改编译的DOSBox二进制文件找到了解决方案。我本可以编辑源代码并简单地构建项目,但那里的乐趣在哪里?

二进制文件位于/ usr / bin / dosbox中。我以root身份在终端中打开gdb并写了

gdb -write -silent /usr/bin/dosbox

这是我的DOSBox 0.74二进制文件的解决方案,为Ubuntu 14.04编译。

首先,屏幕截图文件名包含一个3位数字,例如'whatevs_000.png'。可能是使用sprintf函数调用将文件名构造为字符串,使用包含%3d%03d的格式字符串。使用objdump -s /usr/bin/dosbox | grep "\%03"的幸运搜索显示字符串"%s%c%s%03d%s"确实存储在0x5fa9c7

使用awatch *0x5fa9c7设置硬件访问观察点后,我run gdb中的程序{可能需要多个continue。一旦DOSBox启动,我使用Ctrl + F5截取屏幕截图并将程序捕获到sprintf函数中的指令。在几个up之后,我进入了主程序流程(地址0x4a9949)。 disass向上,我发现了一个for循环,它有标准的库调用来实现目录列表。我检测到循环的入口点(在循环中使用两个continue语句,我稍后通过检查源代码验证),并用无条件跳转到最后替换for循环终止语句(0x4a9854)循环(0x4a9908)如下:

set write on

set *(unsigned char*)0x4a9854 = 0xeb     Short jump to 0x4a98d4
set *(unsigned char*)0x4a9855 = 0x7e

set *(unsigned char*)0x4a9856 = 0x90     Fill the remaining
set *(unsigned char*)0x4a9857 = 0x90     bytes of the previous
set *(unsigned char*)0x4a9858 = 0x90     instruction with NOPs
set *(unsigned char*)0x4a9859 = 0x90     because why not

set *(unsigned char*)0x4a98d4 = 0xeb     Short jump to 0x4a9908
set *(unsigned char*)0x4a98d5 = 0x32

(我跳了两个短跳,跳过更远的范围,因为这是我唯一能记住的操作码,我对其余的谷歌太困了)

在此之后,DOSBox始终覆盖filename_000.pngfilename是要模拟的二进制文件的名称。