mpd中codecs与编码的对应关系
计划写一个转换/解析mpd的脚本,目前完成了一部分。
有一个字段属性是codecs
,比如avc1.4d4029
,如果那这个来做文件名的一部分,不直观也好看。
然后找到了一个比较正式的对应关系,来自于chromium的源码。
计划写一个转换/解析mpd的脚本,目前完成了一部分。
有一个字段属性是codecs
,比如avc1.4d4029
,如果那这个来做文件名的一部分,不直观也好看。
然后找到了一个比较正式的对应关系,来自于chromium的源码。
今天找一个标准文件,结果没找到能下载的,后来折腾半天发现道客巴巴有,质量还行。
扒下来是图片文字分离的,文字坐标倒是有了,不过还在研究怎么合并到pdf上去。
这不是本文重点,重点是怎么合并图片到PDF,谷歌许多,都不太理想,最后看到说用Pillow,一试效果还不错。
几个说明:
搜寻过程中了解到的一些工具/库:img2pdf pgmagick ImageMagick fpdf PyPDF2
要提一下的是ImageMagick也不崩,但量大的时候命令行都显示完成了,任务管理器还是显示在占用内存。。
最后分享代码如下:
from PIL import Image
from pathlib import Path
def png_to_pdf():
fpath = Path(r"path/to/images")
imgs = []
paths = [path for path in fpath.iterdir()]
paths = sorted(paths, key=lambda p: int(p.stem.split("_")[-1]))
for index, path in enumerate(paths):
img: Image.Image = Image.open(str(path.resolve()))
rgb = Image.new('RGB', img.size, (255, 255, 255))
rgb.paste(img, mask=img.split()[3])
if index == 0:
_rgb = rgb
else:
imgs.append(rgb)
pdf_path = str(Path("filename.pdf").resolve())
_rgb.save(pdf_path, "PDF", resolution=200.0, save_all=True, append_images=imgs)
if __name__ == "__main__":
png_to_pdf()
原标题:Chrome下使用可调试版Flash进行swf分析
感觉这标题不行,换个大气一点的:SWF逆向环境搭建教程(免安装Chrome + Adobe Flash Player)
常规安装在此略过
网上免安装版很多,这里自己动手搞一个。
首先下载一个standalone版的离线安装包,下载链接:
https://www.google.com/chrome/?standalone=1&platform=win64
双击安装,这里不是真的要安装,只是为了提取需要的部分,如图可以看到提示(当然得先开好UAC,不然会直接安装?):
这个时候点否,然后进入
C:\Users\用户名\AppData\Local\Temp
或者win+r
输入%TEMP%
回车打开,然后就能找到一个名字类似GUMB973.tmp
的文件,太多不好找就按时间排序一下。
这个时候把名字里有chrome_installer.exe
的这个文件复制出来,用解压软件打开,可以发现是一个chrome.7z
,这就是需要的本体了。
然后记得取消掉chrome的安装
在解压后的文件夹下新建init.bat
脚本文件,具体内容如下,作用是创建User Data文件夹和快捷键方式
@echo off
set SCRIPT="%TEMP%\%RANDOM%-%RANDOM%-%RANDOM%-%RANDOM%.vbs"
set ChromePath=%~dp0chrome.exe
set ChromeInkPath=%~dp0chrome.lnk
set ChromeUserDataDirPath=%~dp0User Data
echo Set oWS = WScript.CreateObject("WScript.Shell") >> %SCRIPT%
echo sLinkFile = "%ChromeInkPath%" >> %SCRIPT%
echo Set oLink = oWS.CreateShortcut(sLinkFile) >> %SCRIPT%
echo oLink.TargetPath = "%ChromePath%" >> %SCRIPT%
echo oLink.Arguments = "--user-data-dir=""%ChromeUserDataDirPath%""" >> %SCRIPT%
echo oLink.Description = "custom standalone version chrome" >> %SCRIPT%
echo oLink.WorkingDirectory = "%~dp0" >> %SCRIPT%
echo oLink.Save >> %SCRIPT%
cscript /nologo %SCRIPT%
del %SCRIPT%
if not exist "%~dp0User Data" mkdir "%~dp0User Data"
pause
再新建一个mm.bat
,内容如下:
@echo off
set mmcfgPath="%~dp0User Data\Default\Pepper Data\Shockwave Flash\System\"
set mmcfg=%mmcfgPath%mm.cfg
if not exist %mmcfgPath% mkdir %mmcfgPath%
echo ErrorReportingEnable=1 >> %mmcfg%
echo TraceOutputFileEnable=1 >> %mmcfg%
pause
双击快捷方式运行Chrome,初始化一些默认设置,然后关闭Chrome,再执行mm.bat
生成mm.cfg。
当然你也可以手动新建一个名为mm.cfg
,内容为
ErrorReportingEnable=1
TraceOutputFileEnable=1
的文件,位于解压路径下的
User Data\Default\Pepper Data\Shockwave Flash\System\
至此,chrome设置部分完成
插件商店地址、项目地址
https://github.com/FirefoxBar/HeaderEditor
https://chrome.google.com/webstore/detail/eningockdidmgiojffjmkdblpjocbhgh
主要是为了避免下载Flash Player被重定向到特供版,另外这个插件也能修改很多东西,可以让你更像是在一个纯英文环境。
新版chrome会自动隐藏已经开启的插件的图标,在这里打开:
然后进入设置(左键点击):
右下角加号添加规则:
设置如图:
然后就可以下载Flash Player了
这是一个补充知识点,其实抓包就能知道怎么下了,简而言之就是:
https://clients2.google.com/service/update2/crx?response=redirect&os=win&arch=x86&os_arch=x86_64&nacl_arch=x86-64&prod=chromiumcrx&prodchannel=stable&prodversion=85.0&lang=zh-CN&acceptformat=crx2,crx3&x=id%3D{插件ID}%26installsource%3Dondemand%26uc
替换这个{插件ID}
部分,这部分就是插件地址最后面的部分,那么Header Editor的crx下载地址就是:
https://clients2.google.com/service/update2/crx?response=redirect&os=win&arch=x86&os_arch=x86_64&nacl_arch=x86-64&prod=chromiumcrx&prodchannel=stable&prodversion=85.0&lang=zh-CN&acceptformat=crx2,crx3&x=id%3Deningockdidmgiojffjmkdblpjocbhgh%26installsource%3Dondemand%26uc
安装本地的crx要先打开chrome,进入chrome://extensions/
,把开发者模式打开,然后把crx拖进来就行了,当然能在线安装更好。
debug版下载地址:
https://www.adobe.com/support/flashplayer/debug_downloads.html
https://fpdownload.macromedia.com/pub/flashplayer/updaters/32/flashplayer_32_ppapi_debug.exe
在安装前,建议卸载已有的Adobe Flash Player,否则后面很可能会出现这个提示:
如果出现这种情况,按照官方方案,需要删除全部的pepflashplayer.dll
,然后重新安装Adobe Flash Player
pepflashplayer.dll
可能出现的路径举例,主要是第三个,第四个是免安装下的路径:
C:\Windows\SysWOW64\Macromed\Flash\pepflashplayer32_32_0_0_433_pepper.dll
C:\Windows\System32\Macromed\Flash\pepflashplayer64_32_0_0_433_pepper.dll
%USERPROFILE%\AppData\Local\Google\Chrome\User Data\PepperFlash\32.0.0.433\pepflashplayer.dll
Chrome文件夹\User Data\PepperFlash\32.0.0.433\pepflashplayer.dll
假设你已经卸载了原有的Flash。
下载后安装,然后把
Chrome文件夹\User Data\PepperFlash\32.0.0.433\pepflashplayer.dll
这个备份(改个名字),然后将
C:\Windows\System32\Macromed\Flash\pepflashplayer64_32_0_0_433_pepper.dll
移动过来并改名为pepflashplayer.dll
,自行对应版本(64/32)。
这个时候运行chrome浏览器,并打开https://helpx.adobe.com/flash-player.html
,点击Check Now
就能看到Flash信息了,显示debug version
说明debug版Flash安装成功了。
由于新版的chrome不能直接设置默认就运行Flash,所以得修改下注册表,这样方便一些。
根据官方文档,建立一个如下内容的reg文件,然后双击添加:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
"DefaultPluginsSetting"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\PluginsAllowedForUrls]
"1"="http://*"
"2"="https://*"
"3"="http://v.qq.com"
"4"="https://v.qq.com"
这里后两个是完整域名地址,这是因为85版本后的chrome不能直接用通配符的方式以达到让全部网站都自动启用Flash了,只能单个域名(完整二级域名)设定,这样添加主要是为了测试腾讯的swf,测试的swf地址不同还请自行修改添加。
原文档说明:
Starting in Chrome 85: For the PluginsAllowedForUrls and PluginsBlockedForUrls policies, you can no longer use wildcards in hostnames, such as https:// and https://[.]solarmora.com.
添加结果如图:
为了保险起见,屏蔽Flash有关的域名,hosts路径
C:\Windows\System32\drivers\etc\hosts
追加内容:
127.0.0.1 geo2.adobe.com
127.0.0.1 flash.2144.com
127.0.0.1 www.2144.cn
127.0.0.1 fpdownload2.macromedia.com
127.0.0.1 fpdownload.macromedia.com
127.0.0.1 macromedia.com
127.0.0.1 flash.cn
找一个需要运行swf的地址就行(一般都会有输出日志),比如腾讯视频的:
http://v.qq.com/iframe/player.html?vid=n0147bokgun
效果如图,可以看到Flash选项是强制默认开启的,这个报错估计是Flash版本问题,没有大碍:
swf产生的日志也有了,在这个路径:
chrome文件夹\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\Logs\flashlog.txt
日志文件路径在新版本是无法修改的,免安装版就是在上面这个路径,安装版应该是在
%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\Logs\flashlog.txt
具体参见:
https://helpx.adobe.com/flash-player/kb/configure-debugger-version-flash-player.html
至此,SWF的调试环境就搭建好了,你可以通过反编译SWF,添加一些trace语句等,然后通过flashlog.txt追踪进行逆向分析。
感觉是个很蠢的方案。
最后将我整理好的完整的环境压缩包奉上,另外85版本(不能对全部网站自动开启Flash)有一点新,找了一个84版本的(84.0.4147.105)。
下载:https://www.lanzoux.com/ityNPgk6ggj 密码:4mky
另外压缩包附带一个日志分析工具Vizzy,需要手动选择一下日志目录,FlashDevelop需要的话请自己下:
成品使用:
init.bat
flash.reg
mm.bat
本文耗时:一天。
设计师里面的“提升为”就是在应用自定义部件,但是一看到这个.h就感觉不太好了,网上一搜都是新建头文件云云。。
我以为得写C++呢!
然后,果然还是在StackOverflow找到了答案。
原来设计师这个只是一个提示,本质上就是替换了一下字符,所以只需要填写类名和你预先写好的py文件的相对路径即可。
注意相对路径的形式,末尾是.h不是.py,斜杠方向不要错了,这样通过pyuic5转换ui文件到py文件时才会生成正确的导入。
path/to/py.h
算是一个练习
之前都是用的BeautifulSoup来提取需要的信息,相对来说操作简单,但是需要这个额外的库有时候感觉还是比较慢。
之前也知道python内置了HTMLParser,可以用来解析html,但是一直没用过,这次用这个来做。
直接上代码了。
from html.parser import HTMLParser
class THTMLParser(HTMLParser):
def __init__(self):
super(THTMLParser, self).__init__()
self.brflag = 0
self.qflag = None
self.imgtag = None
self.xtag = False
self.recording = False
self.record_step = 0 # 抽取进入的深度
self.record_data = []
def handle_starttag(self, tag, attrs):
if tag == "legend":
# 跳过 legend
self.recording = False
if tag == "x":
self.xtag = True
if tag == "div":
if self.recording is True:
self.record_step += 1
for key, value in attrs:
if key == "id" and value == "kdescr":
self.recording = True # 开始记录
self.record_step += 1 # 步进步数
break
if tag == "fieldset":
if self.recording is True:
self.record_step += 1
if self.qflag is None:
self.qflag = "quote_start"
def handle_endtag(self, tag):
if tag == "legend":
self.recording = True
return
if self.recording is True:
self.record_step -= 1
# 回退到起始tag 则说明要抽取的部分遍历结束了
if self.record_step == 0:
self.recording = False
# if self.xtag is True:
# self.xtag = False
if tag == "fieldset" and self.qflag == "find_next":
self.record_data[-1] += "[/quote]"
self.qflag = None
def handle_startendtag(self, tag, attrs):
if self.recording is False:
return
# 处理 <tagname /> 这种形式的tag
if tag == "br":
if self.brflag != 0:
if len(self.record_data) > 0:
if len(self.record_data[-1]) > 0 and self.record_data[-1][-1] != "\n":
self.record_data[-1] += "\n"
self.brflag = 0
self.brflag += 1
if tag == "hr":
if self.qflag is None:
self.qflag = "quote_start"
if self.qflag == "find_next":
self.record_data[-1] += "[/quote]"
self.qflag = None
if tag == "img":
for key, value in attrs:
if key == "src":
text = f"[img]{value}[/img]"
self.record_data.append(text)
def handle_data(self, data: str):
if self.recording is True:
# 这里没有处理 \u3000 即全角空白 因为全角空白可以对齐
text = data.strip("\n\t").replace("\xa0", " ")
if text != "":
if self.brflag == 1:
self.brflag = 0
if self.xtag is True:
self.record_data[-1] += text
self.xtag = False
else:
if self.qflag == "quote_start":
text = "[quote]" + text
self.qflag = "find_next"
self.record_data.append(text)
if self.record_data[-1] in ["Video", "Audio", "Other"]:
self.record_data[-1] = "\n" + self.record_data[-1]
def handle_comment(self, data):
pass
# print('<!--', data, '-->')
def handle_entityref(self, name):
pass
# print('&%s;' % name)
def handle_charref(self, name):
pass
# print('&#%s;' % name)
if __name__ == "__main__":
with open(r"torrent.html", "r", encoding="utf-8") as f:
content = f.read()
parser = THTMLParser()
parser.feed(content)
with open(r"torrent.md", "w", encoding="utf-8") as f:
content = f.write("\n".join(parser.record_data))