我有一个项目,我试图‘流’一个DOS游戏,在DOSBox上的Ubuntu工作。这个想法是把屏幕截图,然后上传到服务器。为了从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,并清除捕获文件夹,并拍摄另一个屏幕截图。还有什么更好的选择呢?
(P.S:上面的代码是简化的;通常我会将捕获的图像复制到多个图像;img0.png和img1.png,这样,当一个正在编写时,另一个就可以读取,就像页面翻转一样)。无论如何。)
发布于 2015-08-20 20:36:43
我通过直接篡改编译的DOSBox二进制文件找到了一个解决方案。我可以编辑源代码并简单地构建这个项目,但是其中的乐趣在哪里呢?
二进制文件位于/usr/bin/dosbox中。我以根用户身份打开终端中的gdb,并编写
gdb -write -silent /usr/bin/dosbox这是我的Ubuntu14.04编译的DOSBox 0.74二进制文件的解决方案。
首先,屏幕截图文件名包含一个3位数的数字,例如'whatevs_000.png‘。文件名很可能是使用sprintf函数调用构造为字符串的,使用包含%3d或%03d的格式字符串。使用objdump -s /usr/bin/dosbox | grep "\%03"进行的幸运搜索显示,字符串"%s%c%s%03d%s"确实存储在0x5fa9c7。
在使用awatch *0x5fa9c7设置了硬件访问监视点之后,我在gdb中对程序进行了run(可能需要几个continue)。一旦DOSBox启动,我就使用Ctrl+F5获取屏幕截图,并在sprintf函数中的指令处捕获程序。经过几个up之后,我进入了主程序流(address 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.png,filename是要模拟的二进制的名称。
https://stackoverflow.com/questions/31477879
复制相似问题