3250
一、IP地址:1.根据地址查归属地请求地址:http://search.csource.com.cn/search.php请求方式:POST
请求条件:searchdata=[查询的IP]&searchfs=ip
返回结果:{"status":"1",
"message":"Success",
"Data":{"beginIP":"0.0.0.0",
"endIP":"0.255.255.255",
"dataA":"IANA",
"dataB":"\u4fdd\u7559\u5730\u5740"
}}
2.查询自己的IP请求地址:http://search.csource.com.cn/search.php请求方式:POST
请求条件:software_alive=get&searchdata=local&searchfs=ip
返回结果:{"status":"1",
"message":"Success",
"UserIP":"[你的IP]",
"Data":{"beginIP":"0.0.0.0",
"endIP":"0.255.255.255",
"dataA":"IANA",
"dataB":"\u4fdd\u7559\u5730\u5740"
}}二、MAC地址查询:请求地址:http://search.csource.com.cn/search.phpMAC地址格式:xx-xx-xx-xx-xx-xx
请求方式:POST
请求条件:searchfs=mac&searchdata=[mac地址]
返回结果:{"status":"0",
"message":"Success",
"mac":"[查询的mac地址]",
"mac_q":"[mac地址前缀]",
"regcompy":"[注册公司/所有公司]"三、文件后缀查询(1) 通过后缀名查询请求地址:http://search.csource.com.cn/search.php
请求方式:POST
请求条件:searchdata=[后缀名]&searchfs=hz
返回结果:{"status":"4",
"message":"Success",
"Data":{"filetype":[后缀名], "binarydata":[文件字节头], "Open":[打开方式],
"title":[文件描述],
"searchkeyword":[搜索关键词]
}}(2) 通过后缀名查询请求地址:http://search.csource.com.cn/search.php
请求方式:POST
请求条件:searchdata=[文件字节头]&searchfs=hz_binary
返回结果:{"status":"4",
"message":"Success",
"Data":{"filetype":[后缀名],
"binarydata":[文件字节头],
"Open":[打开方式],
"title":[文件描述],
"searchkeyword":[搜索关键词]
}}四、进程安全查询请求地址:http://search.csource.com.cn/search.php
进程名:[进程名.exe]
请求方式:POST
请求条件:searchfs=process&searchdata=[进程名.exe]
返回结果:{"status":"2","message":"Success",
"p_name":"[进程名.exe]",
"p_path":"[文件路径,如果不是系统文件,则该项为空]",
"regcompy":"[开发商]",
"p_level":"[安全等级0-5]",
"p_other":"[进程描述]"}
3
0 916天前
2857
题外话:
由于站长实在看不惯国内各个站长的作风,遂将不容易弄到的源码公开放出来
注:此源码经站长测试可正常使用,压缩包无解压密码且不收费,压缩包无解压密码且不收费,
压缩包无解压密码且不收费,源码不需要注册我们网站的账号也可下载尊重版权,如果您作为商业使用,建议您购买
购买连接:Customize Your Selection | CodeCanyon汉化包使用:
安装程序汉化包:
将install.zip文件解压出来,然后双击打开解压后的文件夹,可以看到里面只有一个public文件夹,
将这个public文件夹替换网站根目录同名文件夹即可
语言汉化包(需要安装完成后数据库中存在Localizations数据表后才可执行):
第一步 mysql中执行该命令(必须执行)
INSERT INTO `localizations` VALUES (2, 'china', '2023-02-26 03:42:55', '2023-03-03 17:07:24', 'zh');
第二步 下载页面底部的汉化包文件,解压出来会得到一个文件夹,将这整个文件夹复制到网站根目录,
然后在网站后台setting -> localization -> site language 中选择china,点击Update即可
汉化包使用说明:1.关于使用汉化包后部分地方仍然是英文的原因这个并非是我们没进行汉化,而是程序本身显示的问题导致,对于此问题我们经过多次尝试仍然无法解决2.部分内容生涩、机翻感严重要说明的是,因为不是英语专业,所以里面的大部分单词都是基于百度翻译得到的结果,所以这也是为什么机翻感强部分可以直接看得到的单词,已经尽量根据实际情况、使用位置进行了调整,而部分语句由于不清楚使用位置,故未做翻译或做了翻译但也只是简单的机翻
目录|- 一、介绍|- 二、安装要求|- 三、安装方法|- 四、预览|- 五、下载|- 六、更新|- 七、可能会碰到的问题============================================================================一、介绍 BeMusic 是一个优秀的多功能的音乐共享和流媒体平台。它可以用于创建许多不同类型的音乐相关站点,包括类似于soundcloud,mixcloud,spotify等的站点。功能说明易于安装 –使用易于使用的安装程序和文档,只需几分钟即可轻松安装BeMusic,无需编码或服务器知识外观编辑器 –功能强大的外观编辑器可让您轻松更改BeMusic的外观,而无需任何编码知识。Automated – BeMusic可以访问数百万艺术家,歌曲和专辑,所有这些都可以自动获得。用作CMS –您可以轻松禁用所有自动数据提取并手动创建所有内容,将BeMusic转换为功能齐全的音乐CMS。用户库 –除了播放列表之外,用户还可以在BeMusic的库中添加歌曲,专辑和艺术家。播放列表 –用户可以创建,共享和关注播放列表。播放器 –功能齐全的播放器,包括随机播放,重复播放,歌词,队列等。艺术家和专辑页面 –为数百万艺术家和专辑自动生成的页面有完整的唱片,类似的艺术家,高级广播,biograhpy,图像,流派等。单页 – BeMusic是一个单页(基于ajax)的应用程序,这意味着在通过应用程序导航时没有浏览器页面刷新。可翻译 – BeMusic已完全翻译。 您可以从管理区域轻松翻译它,因此无需混淆配置文件或第三方应用程序。响应 – BeMusic完全响应,可以扩展到任何设备的大小。文档 –深入介绍从安装到所有功能的文档。用户系统 –功能齐全的用户系统,具有社交登录(Facebook,Twitter和谷歌),正常登录,注册,密码恢复,配置文件,帐户设置等。禁用注册 –可以从管理面板完全禁用注册,因此只有您从管理面板手动创建的用户才能登录。强制登录 –您可以强制用户登录,然后才能访问任何BeMusic功能。广告 – 6个整合广告位。 您只需将广告代码粘贴到管理区域,BeMusic即可完成剩下的工作。专业设计 –用像素完美的专业设计给用户留下深刻印象。设置 –管理区域加载了允许您根据需要自定义站点的设置。Google Analytics(分析) – Google Analytics(分析)会直接集成到管理区域中,因此您无需打开单独的页面即可查看您网站的运行情况。多个主页 –在多个主页之间进行选择,包括登录页面,登录页面或您自己的自定义html页面。上下文菜单 –完全集成的上下文菜单(右键单击歌曲,艺术家,专辑或播放列表)可用于许多操作。 可以通过单击基于触摸的设备上的省略号按钮来访问此菜单。搜索 –强大的搜索,几乎可以找到任何歌曲,艺术家或专辑。二、安装要求V2.5.2 版本PHP> = 5.6OpenSSL PHP扩展PDO扩展(默认启用)php_fileinfo扩展(默认启用)MySQL数据库服务器。 推荐环境PHP = 8.0OpenSSL PHP扩展PDO扩展(默认启用)php_fileinfo扩展(默认启用)MySQL = 8.0V3.0.6 版本(V3.0版本开始则必须为PHP8.0以上)PHP 最低为 8.0.12OpenSSL PHP扩展PDO扩展(默认启用)php_fileinfo扩展(默认启用)php zip扩展三、安装方法:1、下载BeMusic安装包到本地,解压缩。2、将解压缩后的文件上传到网站根目录3、访问域名,根据安装向导开始安装,直到安装完成。在Windows下或者Linux下均可搭建,哪个顺手就哪个四、预览五、下载V2.5.2文件下载(需下载全部分卷):分卷1 分卷2 分卷3 该版本为2.5.2文件下载(方式二):百度云(访问密码:8888) 城通网盘(访问密码:4496) 蓝奏云V2.5.2(密码:f6qt) 汉化包:简易汉化包(2023-04-12更新) 安装程序汉化包V3.0.6蓝奏云 v3.0.6(密码:cxra)汉化包:V3.0.6 汉化包六、更新:Bemusic 更新方式均为:首先将新版本覆盖旧版本文件,然后在浏览器中访问http://xxxx/update,按提示升级即可七、可能出现的问题:1、安装出现502、503 错误该情况为php异常导致,经过测试在宝塔面板下,PHP版本为7.4.33下,会出现该提示,更换php版本即可解决2.安装出现500错误,显示“<!DOCTYPE html> <html lang="en"> <head> <base href="install_files/"> ”站长通过多次测试后发现,此时数据库的数据表只有30条,而完整应该是56条,因此推测应该是脚本执行超时,既然知道原因,那么解决方法就很简单了,此时不要刷新页面的情况下,继续点击"立即安装"会发现还是可以继续安装的,根据实际情况可能会需要点击多次,直到出现安装完成3、安装完成后上传出现Could no upload 提示,按F12开发工具,查看对应post请求,错误为"Malformed UTF-8 characters,possibly incorrectly encoded"该情况为当前上传的文件存在IDV3标签,且IDV3的标签编码非UTF-8,因此程序无法识别导致,解决方案删除音频文件中的IDV3、IDV2即可(或者也可以重新写入UTF-8编码的IDV3),删除工具可以使用我们另外一个帖子提供的Mp3Tag(传送门)4.安装完成后上传出现Could no upload 提示,按F12开发工具,查看对应post请求,错误为"getPathName() is null"该情况为当前使用的是分片上传,由于部分文件使用分片上传,特别是在Linux平台下特别容易出现该错误,因此在设置中关闭掉分片上传即可5.网站整体迁移到另外文件夹后,访问显示404、500错误该情况需要检查网站根目录下的.env文件(该文件可能为隐藏状态,需要在文件夹选项中启用显示隐藏文件),检查里面的网址、数据库连接方式、连接地址、数据库账号密码是否正确6.保存专辑时出现"SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '0-11' for key 'artist_track_artist_id_track_id_unique'" 错误该错误主要出现在专辑有多个艺人的情况下,如果是上传了歌曲,则只需要将多个艺人删除,也即是当前专辑仅包含一个艺人情况下,首先我们把上传的歌曲保存了,然后再次编辑,并添加艺人,此时会再次报上述错误,我们可以不用管,退出去再进来会发现其实已经保存成功了
0
0 590天前
4282
转自:Windows 10 自带那么多图标,去哪里找呢?_walter lv的博客-CSDN博客_windows图标提取的ICON下载:点击下载大家都知道在文件夹上右键,选择 属性 → 自定义 → 更改图标,这里可以选择很多图标,但用了很多年看腻了,Windows 10 中还自带有那么多,它们又在哪里呢?Windows XP/2003 自带的图标几乎都在 %systemroot\system32\*.dll 中Windows 7/10/11 自带的图标几乎都在 %systemroot\SystemResources\*.mun 中,部分在 %systemroot\system32\*.dll 中Windows 10 风格%systemroot\system32\ddores.dll
%systemroot\system32\dmdskres.dll
%systemroot\system32\imageres.dll
%systemroot\system32\mmres.dll
%systemroot\system32\networkexplorer.dll
%systemroot%\system32\pnidui.dll
%systemroot%\system32\sensorscpl.dll
%systemroot%\system32\setupapi.dll
%systemroot%\system32\shell32.dll
%systemroot%\system32\wmploc.dll
%systemroot%\system32\wpdshext.dllWindows 7 风格%systemroot\system32\accessibilitycpl.dll
%systemroot\system32\dsuiext.dll
%systemroot\system32\gameux.dll
%systemroot\system32\ieframe.dll
%systemroot\system32\mstscax.dll
%systemroot\system32\netcenter.dllWindows 早期风格%systemroot\system32\compstui.dll
%systemroot\system32\mmcndmgr.dll
%systemroot\system32\moricons.dll
%systemroot\system32\pifmgr.dllWindows 10 风格▲ ddores.dll 包含各种硬件图标▲ dmdskres.dll 磁盘管理所用图标▲ imageres.dll 各种各样 Windows 10 风格的图标,涵盖各种用途▲ mmres.dll 音频设备图标▲ networkexplorer.dll 网络和共享中心图标▲ pnidui.dll 不要被这些空白迷惑了,这都是白色的网络指示图标(有线、无线、飞行模式等)▲ sensorscpl.dll 各种传感器图标(如温度、亮度、声音、指纹、地理位置等)▲ setupapi.dll 为各种硬件安装程序提供的图标▲ shell32.dll 这个是点开“更改图标”按钮后查看的默认图标库,也包含各种各样 Windows 10 风格的图标,涵盖各种用途▲ wmploc.dll 各种媒体设备、媒体文件、媒体文件夹▲ wpdshext.dllWindows 7/Vista 风格▲ accessibilitycpl.dll 辅助功能图标▲ dsuiext.dll 服务器或网络服务所用图标▲ ieframe.dll IE 所用的图标(部分图标其实已经更新成 Windows 10 风格,给 Edge 用)▲ mstscax.dll 远程桌面连接所用图标(部分图标其实已经更新成 Windows 10 风格)▲ netcenter.dll Windows 7 风格的网络和共享中心所用图标Windows XP/2000/9X/3.X 风格▲ compstui.dll▲ mmcndmgr.dll 古老的图标▲ moricons.dll 古老的图标▲ netshell.dll 古老的网络连接图标▲ pifmgr.dll Windows 95 时代古老的图标▲ wiashext.dll 各种图片、照片和媒体设备图标一个说明:你会发现有些图标是空白的,这个不是 BUG,是微软的无奈……因为有些古老的不负责任的程序会依赖于这些老旧的被微软淘汰的图标,如果微软删掉了这些图标,那么这些程序会崩溃。哎……
0
0 807天前
1865
转自:Windows PnP设备驱动删除设备的处理流程 - 知乎 (zhihu.com)参考文档:Understanding When Remove IRPs Are Issued - Windows drivers / 让设备实现即插即用--福优学苑@音视频+流媒体 (hellotongtong.com)Windows对于PnP(即插即用)设备,有一个专门的IRP Major Code定义:IRP_MJ_PNP,任何PnP设备驱动以及工作在PnP设备协议栈之上的驱动(如文件系统驱动)和过滤驱动都需要处理IRP_MJ_PNP请求,尤其是删除的过程,如果驱动没有针对这类请求进行处理,可能会导致系统挂起或者删除设备失败。一个常见的用户层面表现就是无法安全弹出U盘。本文主要翻译自前面的链接,不保证内容一定正确(未进行完整验证)。PnP设备有两种删除流程,一种是正常删除,也就是用户层面发起的“安全弹出”请求;另一种是用户直接拔出设备,这种是非正常删除。对于正常安全删除的流程:Windows会先发起一个IRP_MN_QUERY_REMOVE_DEVICE请求,去查询设备是否可以正常删除,如果此时设备忙,则可以通过Irp->IoStatus.Status返回一个STATUS_UNSUCCESSFUL,同时调用IoCompleteRequest,并且不传播Irp给下层驱动。这样在用户层面上,就会提示设备忙,无法删除。如果驱动认为设备时可以删除的,那么收到此请求以后,就应该禁止新的其它请求进入,同时设置Irp->IoStatus.Status为STATUS_SUCCESS,并调用IoSkipCurrentIrpStackLocation和IoCallDriver传播这个Irp到更底层的设备。通常来说,如果这个请求返回成功,那么驱动此时就应该释放一些资源,当然驱动也可以选择不释放,而是仅仅阻止更多的请求进入,具体驱动选择哪种行为,由驱动自己决定,但通常情况下,对设备加锁是必需的,也要阻止任何“创建”类型的请求进入驱动。当IRP_MN_QUERY_REMOVE_DEVICE返回成功,并且整个设备栈上的所有驱动都返回成功时,Windows的PnP管理器会发送IRP_MN_REMOVE_DEVICE请求,完成对设备彻底删除,当收到IRP_MN_REMOVE_DEVICE请求时,驱动需要释放全部资源,关闭设备,停止还在执行中的其它Irp请求。同时,驱动也要传播这个请求到下层驱动。Windows文档中要求:IRP_MN_REMOVE_DEVICE请求是必须成功的,不能失败,否则可能会造成设备状态信息不一致。IRP_MN_REMOVE_DEVICE请求有可能是驱动被卸载前的最后一个请求,所以必须要保证所有资源被正确释放。如果IRP_MN_QUERY_REMOVE_DEVICE返回失败,那么Windows会重新发送一个IRP_MN_CANCEL_REMOVE_DEVICE请求通知驱动以及整个设备栈取消之前的请求。当驱动收到IRP_MN_CANCEL_REMOVE_DEVICE时,需要解开设备锁定的状态,并允许“创建”类型的请求进入驱动。类似地,IRP_MN_CANCEL_REMOVE_DEVICE也要被传播到底层驱动,通知底层设备驱动更新状态。还有一种特例是,虽然IRP_MN_QUERY_REMOVE_DEVICE返回成功,但上层代码改变主意,不希望删除设备,那么也会发送一个IRP_MN_CANCEL_REMOVE_DEVICE请求,对于这个请求的处理跟前面描述的是一致的:更新状态,传播Irp到底层。所以大致的流程图如下IRP_MN_QUERY_REMOVE_DEVICE(查询是否可以删除)
|
+-----(失败)---> IRP_MN_CANCEL_REMOVE_DEVICE
|
+-----(用户层面取消请求)---> IRP_MN_CANCEL_REMOVE_DEVICE
|
(成功)
v
IRP_MN_REMOVE_DEVICE (可能是最后一个IRP)对于非正常拔出设备的删除流程:Windows PnP管理器会发送一个IRP_MN_SURPRISE_REMOVAL请求给驱动,通知驱动这个设备已经被强制删除了。这个时候驱动需要做的事情如下:1. 检查设备是否还存在,如果还存在,需要停止并删除设备(笔者注:这段状态很奇怪,但文档里是这么写的)2. 释放全部资源,阻止新的IO请求。3. 除了IRP_MJ_CLEANUP,IRP_MJ_CLOSE,IRP_MJ_POWER,IRP_MJ_PNP之外,其它IRP都需要被阻止。4. 如果过滤驱动不能处理这个请求,向底层传播。5. 设置Irp->IoStatus.Status为STATUS_SUCCESS,必须成功,不能失败。6. 调用IoSkipCurrentIrpStackLocation和IoCallDriver传播IRP7. 通过IoCallDriver获得返回值并返回IRP dispatch函数8. 不要调用任何Complete函数当IRP_MN_SURPRISE_REMOVAL请求返回以后,Windows会继续发送一个IRP_MN_REMOVE_DEVICE完成设备删除,流程与正常安全移除设备的方式一致。=============================================================================附注:一、即插即用IRP表二、启动与停止代码#pragma PAGEDCODE
NTSTATUS HandleStartDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter HandleStartDevice\n"));
//转发IRP并等待返回
NTSTATUS status = ForwardAndWait(pdx,Irp);
if (!NT_SUCCESS(status))
{
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
//得到当前堆栈
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
//从当前堆栈得到资源信息
PCM_PARTIAL_RESOURCE_LIST raw;
if (stack->Parameters.StartDevice.AllocatedResources)
raw = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
else
raw = NULL;
KdPrint(("Show raw resouces\n"));
ShowResources(raw);
//从当前堆栈得到翻译信息
PCM_PARTIAL_RESOURCE_LIST translated;
if (stack->Parameters.StartDevice.AllocatedResourcesTranslated)
translated = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
else
translated = NULL;
KdPrint(("Show translated resouces\n"));
ShowResources(translated);
//完成IRP
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KdPrint(("Leave HandleStartDevice\n"));
return status;
}
#pragma PAGEDCODE
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter HelloWDMPnp\n"));
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
{
HandleStartDevice,// IRP_MN_START_DEVICE
DefaultPnpHandler,// IRP_MN_QUERY_REMOVE_DEVICE
HandleRemoveDevice,// IRP_MN_REMOVE_DEVICE
DefaultPnpHandler,// IRP_MN_CANCEL_REMOVE_DEVICE
DefaultPnpHandler,// IRP_MN_STOP_DEVICE
DefaultPnpHandler,// IRP_MN_QUERY_STOP_DEVICE
DefaultPnpHandler,// IRP_MN_CANCEL_STOP_DEVICE
DefaultPnpHandler,// IRP_MN_QUERY_DEVICE_RELATIONS
DefaultPnpHandler,// IRP_MN_QUERY_INTERFACE
DefaultPnpHandler,// IRP_MN_QUERY_CAPABILITIES
DefaultPnpHandler,// IRP_MN_QUERY_RESOURCES
DefaultPnpHandler,// IRP_MN_QUERY_RESOURCE_REQUIREMENTS
DefaultPnpHandler,// IRP_MN_QUERY_DEVICE_TEXT
DefaultPnpHandler,// IRP_MN_FILTER_RESOURCE_REQUIREMENTS
DefaultPnpHandler,//
DefaultPnpHandler,// IRP_MN_READ_CONFIG
DefaultPnpHandler,// IRP_MN_WRITE_CONFIG
DefaultPnpHandler,// IRP_MN_EJECT
DefaultPnpHandler,// IRP_MN_SET_LOCK
DefaultPnpHandler,// IRP_MN_QUERY_ID
DefaultPnpHandler,// IRP_MN_QUERY_PNP_DEVICE_STATE
DefaultPnpHandler,// IRP_MN_QUERY_BUS_INFORMATION
DefaultPnpHandler,// IRP_MN_DEVICE_USAGE_NOTIFICATION
DefaultPnpHandler,// IRP_MN_SURPRISE_REMOVAL
};
ULONG fcn = stack->MinorFunction;
if (fcn >= arraysize(fcntab))
{// 未知的子功能代码
status = DefaultPnpHandler(pdx, Irp); // some function we don't know about
return status;
}
#if DBG
static char* fcnname[] =
{
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
};
KdPrint(("PNP Request (%s)\n", fcnname[fcn]));
#endif // DBG
status = (*fcntab[fcn])(pdx, Irp);
KdPrint(("Leave HelloWDMPnp\n"));
return status;
}三、设备资源#pragma PAGEDCODE
VOID ShowResources(IN PCM_PARTIAL_RESOURCE_LIST list)
{
//枚举资源
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = list->PartialDescriptors;
ULONG nres = list->Count;
ULONG i;
for (i = 0; i < nres; ++i, ++resource)
{// for each resource
ULONG type = resource->Type;
static char* name[] = {
"CmResourceTypeNull",
"CmResourceTypePort",
"CmResourceTypeInterrupt",
"CmResourceTypeMemory",
"CmResourceTypeDma",
"CmResourceTypeDeviceSpecific",
"CmResourceTypeBusNumber",
"CmResourceTypeDevicePrivate",
"CmResourceTypeAssignedResource",
"CmResourceTypeSubAllocateFrom",
};
KdPrint((" type %s", type < arraysize(name) ? name[type] : "unknown"));
switch (type)
{// select on resource type
case CmResourceTypePort:
case CmResourceTypeMemory:
KdPrint((" start %8X%8.8lX length %X\n",
resource->u.Port.Start.HighPart, resource->u.Port.Start.LowPart,
resource->u.Port.Length));
break;
case CmResourceTypeInterrupt:
KdPrint((" level %X, vector %X, affinity %X\n",
resource->u.Interrupt.Level, resource->u.Interrupt.Vector,
resource->u.Interrupt.Affinity));
break;
case CmResourceTypeDma:
KdPrint((" channel %d, port %X\n",
resource->u.Dma.Channel, resource->u.Dma.Port));
}// select on resource type
}// for each resource
}// ShowResources
0
0 807天前
4451
作者:jiawen
链接:https://juejin.cn/post/6890344584078721031
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
一.背景
之前扒过飞书的源码,从代码设计架构层面里里外外学习一把,飞书还是挺“大方”的,源码在客户端和网页端都一览无余,不过好像新版本已经看不到了。相关的文章由于在内网技术论坛发过了不便于再发出来(泄露内部资料会被查水表的),因此这次周末抽时间换一个鸟窝来掏一掏。
一不小心发现迅雷的客户端竟然也是基于 Electron 开发的,那代码就好扒拉了。(先吐槽一下这新版本的某lei为什么要抄钉钉的界面,这些年某lei都不知道自己要干什么了,每个版本都招人嫌)二.开撬 2.1 一点背景知识说明 基于前端技术栈 Electron 构建的桌面应用,本质上都是加载本地前端资源文件,而这些文件通常是用
asar 格式(类似 windows iso 镜像)的方式进行打包,然后运行时再通过挂在到内存实现前端资源文件 js/css/html/img 等文件的读取。 这么说 asar 想办法挂载就可以随意阅读源码了吗?不是的。同时 asar 会提供一套通过加密方式防止任意解压,飞书就是这么做的,直接通过 asar extract 的方式无法解包出来。但是由于 node 端和 rust 构建的二进制文件如果打包到 asar 会导致无法链接到这些二进制文件,因此需要从 asar 中独立出来,因而导致有部分 js 文件仍然裸露在外面。不过即便没有任何 js 是暴露的仍然是有办法爆破的。 啊,跑偏了,先不谈飞书,今天的主菜是迅雷。
那迅雷的前端资源文件是怎么管理的呢? 是在下想多了,不好意思,迅雷梅川酷子,都摊着在那呢,根本没用 asar 打包/加密。 2.2.开撬
既然 js 都暴露了,也没什么好绕的,直接植入代码吧。我们都知道 Electron 是有 render 进程和 Node 进程的,接下来这一步需要猜猜看哪个文件是负责 render 主进程的?好吧不用猜,名字都非常人类可读,就 main-renderer(主窗口渲染进程)。打开找到 html 文件(js也可以)插入如下这串 双击启动,调试窗口出来了,可以大致看到整体页面结构了 然后看了一下,迅雷的悬浮小圆圈和主窗口,分别用一个 BrowserWindow 来实现。有趣的是那个小圆圈窗口其实并不小,鼠标悬停出来的那个浮窗也是它的一部分,为了让小圆圈在屏幕的任何位置都可以看到悬浮窗,所以整个小圆圈的 BrowserWindow 是大约 4 倍的悬浮窗口大小 独立窗口的检视界面 - 窗口实际是 4倍 浮窗大小,灰色部分全都是这个“小”浮窗所使用的
BrowserWindow区域 2.3.一点防御措施
从代码来看,nodejs 进程只有一个文件 main.js ,是 webpack 的构建产物,看源码这里的 BrowserWindow 的 webPreference 参数是把 devTools 禁用掉的,导致直接在命令行里敲 openDevTools 是不能检视任意窗口的 当然了,这里即便是混淆过了也没关系,毕竟还是明文,把 1 改成 0,把它打开就好(双叹号/true/1啥都行,开心就好)。不过由于迅雷的窗口实在是太多了,下载弹窗是独立窗口,选择文件夹是独立窗口,各种广告窗口也是,需要改的配置点很多,这里就不列了,总共有 10 个窗口,这个配置点按需打开(批量替换也行,谨慎操作就行)。
三.进程结构
呃……然后要干啥……好像也没什么好看的了,代码是混淆过的,也没有 map 文件。而且前端部分的代码也没什么技术含量可以说的,哪个 web 页面都那样。那看看进程分工吧。
3.1.进程树
在进程树里可以看出来,几乎全部的进程都是 Thunder.exe,可见 Thunder.exe 作为进程派发入口(类似 server 的网关,而并不直接是业务本身),用户启动的时候传参是
--StartType:DesktopIcon,随后它唤起了两组进程,一组是 Electron main 进程,main 进程唤起相关的 renderer;然后是下载的 SDK 服务 DownlaodSDKServer。
那么迅雷的进程关系差不多是清楚了:多个 Electron 窗口,对应一个 DownloadSDK。 3.2.通信方式 那么 Electron 的进程(甭管 main-process 还是 renderer-process,统称 electron进程) 和 DownloadSDK 是如何通信的呢? 进程间通信一般都是依靠 ipc 管道的形式来实现。不过迅雷似乎没按套路来,它的 DownloadSDK 是控制台程序,意味着很有可能是通过 stdio 的方式来进行交互的(后续证明不是)。
通过观察进程打开的句柄,看到很诡异的一个现象:DownloadSDK 并没有打开任何 ipc 管道,反倒是前端进程打开了一个 3.2.1.前端的 ipc
而
Electron 打开的这个 handler 进程名称,查了一下,竟然全是 Electron 进程使用的,而且是所有进程。 那么不妨做出一个大胆的推测:前端多窗口之间是靠自建的 ipc 通道实现的,而 ipc 是 1
server 对 N client 的方式,那么 server
很有可能就是在主窗口上的,也就是前文看到那个及其明显的 main-renderer 进程,通过控制台查看,确实如此,nodejs 的 net 方式创建了一个
server,并且将一个叫做 __xdasIPCServerInstance 的对象暴露在全局环境供前端 js 调用,也即 jsapi。 而小窗口并不存在上述 server 实例,而相对应的有一个 client 实例 3.2.2.和 DownloadSDK 的通讯方式
这样看起来就很奇葩了,前端进程之间是通过自建的 ipc 管道通信的,但是并没有跟 DownloadSDK 有任何通信管道,难道它俩是心有灵犀无言自通?啊这……程序员是唯物主义的!
那怎么查它到底是怎么跟前端进程交互的呢?既然前端暴露了 server sdk instance,那意味着 DownLoadSDK 肯定是以一种 proxy 的方式暴露在这上面作为 jsapi 的。可以拿【创建一个下载任务api】来顺藤摸瓜。看了主窗口的 server instance 一下果然有这个方法:createTask ,应该就是前端用于创建下载任务用的 api。 chrome 浏览器里查代码不方便,转战 vscode 看源码,搜索 createTask 这个函数的声明位置,看到这一段(篇幅控制,此处删减了部分代码)createTask(e, t) {
return n(this, void 0, void 0, function* () {
.....
}
switch (e) {
case h.DownloadKernel.TaskType.P2sp:
...
case h.DownloadKernel.TaskType.Bt:
...
case h.DownloadKernel.TaskType.Emule:
...
case h.DownloadKernel.TaskType.Group:
...
case h.DownloadKernel.TaskType.Magnet:
...
default:
i = !1;
}
return (
...
_.fireTaskEvent(h.DownloadKernel.TaskEventType.TaskCreated, [
);
});
} 没跑了,证实了我前面的猜想,这个 __xdasIPCServerInstance 就是 download sdk 封装到前端的 proxy。 继续查,这个 fireTaskEvent 是怎么处理的,阅读代码过程繁琐按下不提,就看这两段代码(有删减整理)
// 片段一
(e.getDownloadSdkVersion = function () {
let e = a.join(__rootDir, "../bin/SDK/DownloadSDKServer.exe");
return v.getFileVersion(e);
}),
// 片段二
y = l.default(o.join(__rootDir, "../bin/ThunderHelper.node"));
let F = "/ssdkver " + u.DownloadKernelManager.getDownloadSdkVersion();
B.push(F)
y.shellExecute(0, "open", o, B, H, "SW_SHOW"); 很显然,DownloadSDK 是通过一个 ThunderHelper.node 的 nodejs addon 模块来启动、通信的。
我们知道, nodejs 可以通过 ffi 等方式实现内存共享,以达到两个进程不需要通过 pipe/sock 等管道就达到通信的目的。而通过工具观察 Thunder.exe 的唤起关系、句柄关系,两者的关系就更加一目了然了:ELectron 前端进程加载 DownloadSDK 进程,并且通过 \Sessions\5\BaseNamedObjects\xx@22123720|SendShareMemory 这种内存通道来实现的通信,句柄一一对应上了。四.总结 扒拉了半天,扒完了有点空虚是怎么回事
迅雷的代码架构关系是轻
node 而重前端,把所有的 node 加载、进程管理、多窗口通信都放在前端进程的主窗口进程里。关于这个做法,我尊重而不认同。前端进程不应该做太重的底层交互,尤其是 js 这种单线程语言,天然的就运行效率低,而且主窗口使用这么频繁就不怕卡住吗
Electron 天然就有 ipc 通信能力,完全可以在 node 端做一个消息网关,达成每个窗口通信的能力,完全不需要自建一个 ipc server-client 体系。可能这也是一开始就把大量工作放在前端(主窗口)了导致后期的程序设计受限。说不定是个历史包袱
用一个 node
addon 的方式来跟 DownloadSDK 来通信,这点是可以点个赞的,虽然是业界标准(飞书是通过rust,基本原理类似),但是我目前所负责的业务并没有做到这样,所以在惭愧的同时也给它点个赞
迅雷使用的
Electron 版本是 9.2.1,vscode 也是这个版本,好神奇!非常好奇为何业界都用这个版本,事实上 electron 9.x 最新版本已经更新到 9.3.3 了(2020年10月28日)这个 9.2.1 有什么魔力让业界都用它吗
这里说明一下,Electron
从 6.0 开始就不支持 windows7(非sp1) 及以下的版本了。
我在 win7 系统上用迅雷安装器安装迅雷最新版本,发现 electron 用的是 1.8.6 版本
Electron 的主入口是处理过了的,通过 Thunder.exe 程序干了很多除了启动前端以外的事情,这个定制还是挺棒的,因为这样就可以把各种进程模块管理起来,不会出现多个独立进程。就我所看到的不少 Electron 应用其实都没有定制过。
以上是纯粹技术挖掘,没有破坏到迅雷的核心机密,仅做学习交流使用哈
五.关于我们
我们部门有若干桌面端应用,用户基数大,挑战大,招聘有 electron 经验或者前端技术专家。经常会做一些好玩的桌面端实践,也会深入挖掘和学习一些 app 的程序设计。如果有兴趣的话欢迎联系我,简历请狠砸我!私信我获取联系方式哦!都可以聊一下,说不定就成为同事了,没有你想象的那么难!
还记得开头说的扒了飞书的源码的事情吗?想看吗?想就投简历吧哈哈哈哈
5
0 1359天前
5049
解决方案参考:https://blog.csdn.net/jingzz1/article/details/104551555 近日,因为需要使用android studio改个程序,正好看到android studio 更新到3.6,于是在安装完后,打好中文补丁,导入之前的代码,运行,咦?怎么报错了,再一看,怎么都是乱码,这样怎么知道是什么错误呀。。。。 (界面类似上图) 首先怀疑,有没有可能是中文补丁导致,遂移除,可症状依旧,于是考虑下一个,字体问题,更换字体后,问题依旧,没办法只好google(为什么不用百度?因为一开始百度出来的结果,全是过时的旧数据,没一点用),然后看到一位博主也碰到同样问题,在按照他的方法操作后,终于正常。 其实,解决方法很简单 首先关闭android studio,一定要先关闭,然后打开android studio 安装目录下的bin目录: 可以看到两个文件:studio.exe.vmoptions,studio64.exe.vmoptions
分别以文本文档(即txt)的方式打开 在最后一行添加:-Dfile.encoding=UTF-8 ,如图: 保存后重新打开android studio,乱码的问题就解决了
2
0 1647天前
5775
Win7及以上的系统已经不再支持Debug,想体验需要自行搭建模拟环境 在cmd中(Win98为command),输入debug回车,进入debug命令,然后将以下内容复制进去,即可看到e100 33 f6 bf 0 20 b5 10 f3 a5 8c c8 5 0 2 50 68 13 1 cb e 1f be a1 1 bf 0 1
e11b 6 57 b8 11 1 bb 21 13 89 7 4b 4b 48 79 f9 ad 86 e0 8b c8 bd ff ff e8 20
e134 0 3d 0 1 74 1a 7f 3 aa eb f3 2d ff 0 50 e8 f 0 5a f7 d8 8b d8 26 8a 1 aa
e14f 4a 75 f9 eb de cb 57 bb 21 13 8b c1 40 f7 27 f7 f5 8b fb ba 11 1 4f 4f 4a
e168 39 5 7f f9 52 8b c5 f7 25 f7 37 2b c8 95 f7 65 2 f7 37 95 2b e8 fe e fe
e181 10 79 6 c6 6 fe 10 7 46 d0 14 d1 d1 d1 e5 79 ec 5a b8 11 1 ff 7 4b 4b 48
e19b 3b d0 75 f7 5f c3 83 f7 83 a6 5d 59 82 cd b2 8 42 46 9 57 a9 c5 ca aa 1b
e1b4 4f 52 b4 92 3f ab 6e 9e a8 1d c6 3 fc e 6a e7 ae bb 5f 7b 10 b8 b4 f7 8
e1cd e2 bf 36 4e 39 9d 79 29 3f a f9 36 52 16 fb 5 e8 e5 a6 c2 e9 b0 43 d3 a3
e1e6 cf d3 fd fd cb d1 4c 5e e0 63 58 86 bb 3e 9 c1 20 bc cc 91 a3 47 81 70 b3
e1ff d6 1a 9e c2 c9 12 e7 4e ad f4 5f e3 30 e9 9 39 d7 e8 f9 f4 d2 44 e8 d7 22
e218 be e2 ce 88 25 cf 30 4a a8 29 ae 3f 47 c6 2d 85 e9 73 54 13 b e6 e0 34 65
e231 e2 50 8a 89 18 5f ce 70 99 3 5f 42 bf eb 7 ae d0 ca 5 22 8d 22 a5 b7 f0
e24a 90 81 bc 7a bc dc 5 db c0 6a 2 e5 57 38 be 60 cb ac ba a5 3b 9d f1 77 38
e263 a6 84 d1 3c af 49 d8 6a 45 a2 76 60 21 12 c0 c2 44 f2 5e bb e5 37 a9 2b
e27b ec 4a 8c 4c f2 f7 a9 58 71 2b ba 6d d6 6a e5 60 46 e0 da e5 b9 90 e5 a3
e293 f7 7f 31 60 58 f0 c4 88 10 4e 3c a3 ee 4e 11 55 8f a 92 eb db ad 7a 9c f
e2ac db 5a 28 96 da 87 ae 91 91 2d e3 5e ea df 6 95 71 67 71 40 ce d1 2e 31 6d
e2c5 c1 9c d8 6a 76 9b 4a e8 36 44 d6 76 d 30 5 ff d4 1b ac 1f 32 65 31 bf 55
e2de 26 b a4 55 e1 5d 5e 16 ed 97 48 6c 77 fb 81 86 e f9 18 bd d4 f4 8b de 1d
e2f7 ba d 47 75 3 89 4b 3e dc 27 86 1c d0 17 89 48 d1 a6 8d d4 2b 54 4e 8f b0
e310 2 e1 6b 1a 75 78 ea 21 91 13 c0 cf 78 a0 ab f3 35 c6 b4 c8 90 8d d7 45 e7
e329 c 5b a4 ba 52 10 64 f5 4a 50 b7 ec 46 22 15 23 84 30 81 5c df 61 5a 8f 67
e342 c4 63 57 6d f7 26 92 a3 1f e5 3 a5 0 54 41 8 48 7c 26 90 33 82 9c 91 b0
e35b ab 78 5d df 99 e0 b9 fc 5 36 ac d9 49 91 ab 20 a2 63 48 89 ce 5c 60 64 f0
e374 63 d9 a8 38 3b d3 e6 4c 8c 23 34 4e 20 51 93 5e 6d b4 7a 22 9b 4c f2 d3
e38c c4 f8 3 6f 47 40 f4 f8 45 9b 83 f3 83 6 31 d0 0 17 82 83 dc 67 f9 62 77
e3a5 90 3b d9 ec f3 55 96 b8 d9 db 79 55 f1 e5 8c 5e f2 e5 2e b0 b 6e e2 81 25
e3be 93 8e b5 dd 5b 46 f9 af ed 6 12 cf c9 1d f0 f7 3b 16 2d c6 58 73 8d e9 5f
e3d7 fd 5a b6 a1 94 4d 1a 8 ff eb b7 6 80 c7 86 83 b6 b9 fd 1c e0 c c3 2e a0
e3f0 2f b 3e 3 6b 29 e1 27 85 1c ea 6d df b3 a3 ed 65 4a 9a 59 3b 54 e 4b ae
e409 9e 27 f0 4d 3b c 4c 46 b7 e5 57 1b 1f 1f bb 80 86 f5 b7 ef 73 52 bf 2c c7
e422 ed a b7 81 2 f3 90 3e ee cc 6c eb f 38 1 6c 68 b1 d 45 78 b2 f f6 83 b0
e43c c4 33 df b1 d1 91 98 1e 81 a5 e2 59 9f f4 8c b6 72 8 a7 8c f6 e a3 b2 1f
e455 d9 d3 23 f0 7c 5e 5f 68 61 8b 45 da 1d 91 ec 8d 4e ea 1a 38 85 94 aa ac
e46d f2 4 f6 c4 e5 92 8e 9a 4e 83 e1 73 e8 cf 2a 5c 2b 7e f1 30 2 8a e6 28 1a
e486 3b ce bc 96 aa 7f eb 87 cd 8b 96 2d 9 59 7a a0 1a 43 62 9a 9e 4f ff 8e d9
e49f ce d6 a4 70 79 cd 65 fa 2e 92 14 29 f7 6c 74 4b 49 60 80 bb ff 41 bb 2d
e4b7 60 33 3f 98 77 9a 1 ee a6 a3 da bc ba e9 f3 72 f4 7c c3 59 2 a6 44 a4 c8
e4d0 c8 54 93 ce bd 69 bb b9 43 21 2c c4 ea 4a 5c 3f 75 60 f2 b4 91 ca 9 82 e3
e4e9 a e9 a6 20 b9 76 50 ed 47 e9 fe 6d 41 34 13 2f 28 2f 4e f4 da e 3c 78 6c
e502 b1 79 87 45 98 a4 d4 c3 b3 29 c2 4a 8b ed a6 54 e2 1b 31 62 60 ff 2c 1d
e51a 21 0 15 b2 4e 5c c 2 d 83 fa a2 f3 8a 5 12 72 4a c7 44 7c 91 d4 be b a f2
e535 70 52 fb b4 a2 df 89 de ff c4 96 73 c9 c ed d3 c9 8e 5c dc 8e d1 3b de 8c
e54e 53 a2 8b f9 e9 91 dd d6 df 6e 74 d1 dd 34 60 8f 9e 32 7f 3b ec 79 a3 83
e566 45 78 b4 2f 1c 50 7b 7a 97 b0 9d 2d c dd 8a 26 cd 7d 8c 4c 5a 8a 4c f9 a4
e57f 11 f9 2c 6c 92 e9 b5 cb 56 89 8c be f6 64 fa 25 43 fa 6f e2 c8 3a 18 a8
e597 f0 e9 f4 c2 86 e6 2b 44 67 4a b9 34 9 ed 5f 33 42 62 d4 8a 1e 5b 31 67 cd
e5b0 3d 71 6d 83 fd 36 20 69 ea 1 c3 e6 e6 de 99 aa 7 11 5b 59 8a 1f 43 83 52
e5c9 ea 5d 8c 6a 69 c7 3 eb 4e 3b 88 a5 5f b1 6e 27 5f 3 5c 28 c 9b 6c c3 f8
e5e2 e5 b9 d6 11 d6 8b fa 5c 8 c7 1 eb 45 db f3 6c 9f 16 46 61 51 ed df f bb
e5fb c0 c4 1e 64 68 98 4 79 30 94 72 df d4 cd 1f 7f 72 c6 82 2e 79 47 4e 8c 4b
e614 a2 c7 e2 36 df 76 fd a4 b6 4e db 96 40 3b 8b b5 d4 85 64 c6 0 2c ad 9d 27
e62d 14 99 82 4b bc 9 fa 94 b5 db 7c 98 eb b 13 a7 b0 79 1d 7e c5 45 aa 20 49
e646 be ff 9d 64 0 5d c ec 6 5 ad f2 38 6b ed 7a d6 b2 c7 2e 6a a6 12 4b ff 55
e660 20 3b a 77 f b9 0 9d 57 4a ad ce a4 d3 ff 1 4f fb 53 54 88 f 1 ed 4b 56
e67a 15 c8 dc 28 bf f2 72 d4 10 1f 99 42 69 9e 78 e2 47 82 93 31 d0 2d be 9f
e692 93 93 9a 1b 80 c0 10 c 53 78 a0 26 2a 96 4f 74 4b 16 c7 9c 8d ad ac fb 16
e6ab 15 c6 fd c9 a4 14 48 62 47 20 c9 41 ed 61 f8 9b f8 ff ba 39 50 65 87 ee
e6c3 bd ce 95 c0 fb a5 7e d8 cd 27 fd 2c 74 3 c1 1b 89 b9 51 d5 e3 da ef 9e 6
e6dc f0 aa a9 a7 fb 87 4c 5d cd ff 65 36 8c 73 6f 9 c6 78 9a b6 77 db df 81 68
e6f5 3b b8 ae 5d e1 af d4 e6 66 8c d6 a4 83 9f 37 3c 1 dc a2 a6 57 c2 20 1b 90
e70e 75 df cd a5 62 a5 36 79 fb 35 8a 9b b0 a0 a5 c3 37 6f 80 72 bc 52 30 8d
e726 9f 7a 64 d3 7 41 45 d8 68 97 f2 aa 1c a1 6c 7c 9d 32 7d ad 15 b1 53 e3 33
e73f 8a ed e9 49 d4 cf dc 96 22 37 36 11 9d 7f f0 4d e0 62 31 b1 c7 69 c4 79
e757 ac 20 1 e8 3c 6a 8c 32 cb 52 63 36 68 f4 10 2b 9c 21 4f df 5d 60 92 39 91
e770 e2 f9 c9 7d ca 48 3 3f 21 dd 6c f 23 2e 61 3a 9f ba c3 f9 4e 7 ea ed ef
e789 71 4a 72 3a ed 23 3d 77 b5 ed d5 1d f6 a4 99 fa ef 98 dd 2 98 80 b6 7c a3
e7a2 62 96 7b 8e bf 7b 81 9f 9a ce 3f 12 40 2e 25 db 84 16 dd 2e 86 f f4 b2 7e
e7bb 5e b4 14 6a f3 29 b1 a4 57 d5 a8 17 6f 87 a4 74 5b 9b 17 79 f1 ec 33 c8
e7d3 f0 1d b2 7e a8 4d 95 7f 5f 9 d5 1a 5a 45 f4 41 c6 d 3f eb 66 2a c0 e8 5b
e7ec 3c bd 50 ad f1 53 9d 2e 45 9a d8 7d 2c 17 a8 6e 15 48 13 39 53 ed 3d 78
e804 ad f 3a 65 a3 3e 2e fa ca 7 94 4a 1f b4 d8 7e 47 8a 8e de e7 7e 34 c1 69
e81d 7f 6a aa 66 58 18 31 24 72 13 22 34 8a 56 36 87 df c2 d 8e 3f 71 a2 5f 25
e836 8b 8d 4 78 fd c9 45 d1 55 79 c1 9f 13 84 1b c8 5 db 95 d0 7c 64 96 20 51
e84f c4 e0 5e ee 47 8a 11 ac fb 9 e0 bb 40 db 86 84 12 93 b9 c9 f2 9c 63 47 c9
e868 eb ad 1 3e fa 6d 3f a 64 5b 58 56 27 f ca 5d e0 30 bc 3e 10 5d ec 17 28
e881 85 5 51 8e 95 a3 94 3a a8 f1 96 f2 f 29 5c 97 dc 47 db 9d 6c 63 e8 e7 f0
e89a e4 a 70 f8 f1 47 54 d3 2d 32 7c ef bb 9a b4 1b 0 2b d6 dd e7 30 b a2 75
e8b3 c7 f5 d0 31 d7 d2 8a b0 ac 1c 6d 60 3a f7 c2 db 1e 6d 7 f6 8f 35 88 e5 7f
e8cc 3c 26 81 34 a0 32 a3 25 18 6e 73 b2 a0 f1 cb 86 61 e7 65 8b 76 98 19 6f
e8e4 c0 62 9b a3 cc 18 5e 40 12 97 2b d0 15 79 de 19 ea df 7a 59 2f b5 d7 39
e8fc 52 e2 6 f1 3 a0 a5 d9 1b 88 93 4d 30 c8 2d f5 db 55 ea 85 6f a 3f dc bd
e915 57 15 6a a3 a3 3e 8e ad 2d da a0 ca 75 7c 57 8b c5 cb b 1d 2c 8e c6 96 2e
e92e 6d 59 83 7d 64 72 ca 80 2e 6 a4 ff f6 f2 d5 1e 7 4 ba 34 6e 9 86 25 aa 4e
e948 e0 7f f5 32 47 3e 7c 43 d8 28 c4 1c 11 1d bd 33 3 b5 ca 13 43 34 2 b1 a0
e961 57 ed 9d 3c 23 d4 45 b2 6e 81 6e af 3e 67 90 be 59 a5 45 34 53 46 85 d1
e979 25 ee 7d cb a4 db 12 c3 aa 17 61 9a fb 66 40 76 fe 3a 69 96 c0 91 14 a7
e991 5d cc 9f f6 73 59 ee b8 55 97 20 26 ff 99 ec 72 41 b5 27 21 6e ae 8a d0
e9a9 e4 d3 da 6f c4 53 c5 f8 b3 a7 a1 5d 66 93 d8 b1 89 40 23 92 c0 90 fb cb
e9c1 e7 6b 4e 51 0 5d 57 f7 cd 1 e2 88 bf 44 9f ef c4 33 ce fa 46 46 a1 86 b
e9da 7a 84 66 66 b9 2 ec 10 c6 a1 d4 c1 18 33 b1 d1 2 18 ad 2f 53 e4 b9 33 59
e9f3 be 3c af 80 4c 8a d5 76 c 3b a7 e2 97 94 15 75 4d 17 d5 97 cf f9 4a d0 6e
ea0c bb 27 20 fc f1 f5 9 a8 df 4d b6 5d f0 1d 69 3b 76 35 82 a4 f3 56 64 39 5b
ea25 6b b3 7 e7 5 8e 82 11 22 a8 1a db c8 3e 67 4a 3 7e 72 51 d6 3d 1a 1c f6
ea3e b8 da 4b 18 8a 15 9d d0 a4 84 96 3e cd 3 f9 3a 30 f3 fb 8f 6e 2 73 eb 52
ea57 93 95 cf dc 6f 48 fb ab d2 a9 70 b4 e2 23 8d 72 86 a8 fa 78 98 1d c5 fe
ea6f 8a 51 88 2b b7 58 b0 ca ae 40 8a 33 32 75 1 6 c0 d4 b7 da 2a a7 bb ad f7
ea88 48 98 5a bc d3 d1 e6 16 97 c3 80 ab 73 ac 32 11 41 1f d 5d aa 0 dc d9 6e
eaa1 fc 30 6 ef 11 60 27 a2 5f eb 5f b9 35 8 23 4 be 10 c0 85 3e 55 b3 82 fd
eaba f7 c3 24 9f 2d 83 94 32 36 de ff 7c 87 7f 4a 80 7 2 23 cf a4 52 eb 3e 19
ead3 a0 b4 a 94 1a 40 58 d9 16 6d c0 64 c4 69 ed 60 46 65 cb df 58 38 0 51 c3
eaec ad a0 37 e4 cf ab f7 6c 24 7d 9 48 65 4a 9f 91 ad 1c 79 a4 a1 78 55 c e8
eb05 44 5b d ef 51 bd ea 2d a7 42 57 ab 3a 4f 2 b 3 19 6a 4d 72 76 5c 97 0 6c
eb1f c5 5d bc dd e7 81 cf 8d 34 38 50 3c 98 58 cc 41 aa 99 90 af fe 4e 96 77
eb37 ed 54 18 ce 2c d1 5d 34 cb 79 50 ff 28 96 44 e0 51 64 6 a8 b7 6e 8c 62 c4
eb50 66 95 81 4f 8c f6 26 ba ea 5d d2 79 b1 e4 e9 29 fc a fd b3 85 8c e6 52 dd
eb69 33 bd 5d c7 39 ef 6 ef 9e a6 6a 61 9c 9f d5 54 b4 fa a1 d4 10 9b ff 7e 33
eb82 11 52 99 c7 26 6e a1 36 8a ad ee 48 7a 2c 7f d5 b7 27 8a 6b 37 c 71 39 85
eb9b 9c ba a8 a 17 b9 d0 51 56 95 c2 3b 5 a7 31 c5 8b 5c 95 6e 4c 89 6f 17 ef
ebb4 d4 5a a 77 65 e1 49 b2 e8 72 ac 3c f0 6b 71 fa 3 c7 ca fc ad f9 55 22 ec
ebcd 58 2f 1c fa 29 cf 73 b4 ad 51 5c f8 66 70 59 5d 70 3e d1 3f c4 eb ec f1
ebe5 7 78 6a 93 67 9f 44 fc cb 5b 95 ff 74 c0 b7 42 77 26 c9 aa 8c ed 39 a2 db
ebfe 9c b3 eb 3d 4a 1e 9b 89 e4 d8 a8 27 74 ef a3 ed a5 24 5d bb ab d0 fe a1
ec16 29 ab df 75 a a6 23 0 cc f1 14 72 9b 1a 55 7e e5 d1 da 98 dc c4 cf ab 34
ec2f ba 8d de 4a 59 6 13 dd d8 44 3c e bb 56 95 ae 97 e2 3b 49 e5 9a 6b a2 53
ec48 c1 33 35 24 1b 33 17 c3 8a 8c 12 3d 3d 4e 5b 75 22 30 67 4f a0 5d 3a 78
ec60 88 a 11 35 7 b1 77 42 32 a8 c3 bb 20 fb 98 5 d6 ac e7 3a 63 35 90 93 9e
ec79 44 24 2e 1b d7 8c aa 29 53 4d d9 ab eb e6 1 56 c4 fd 54 a3 bd 14 5b b0 8f
ec92 ce be 23 24 93 c4 48 18 a3 e7 4 5 4b 78 cc 79 dd 3 56 a4 ed dd 5f 98 41
ecab 1b 68 4c c1 bb 41 c2 1e 3e 94 8e ef 28 1e b 76 e 4f 36 b1 c 6e e2 18 17
ecc4 20 fc 35 40 1f e4 6d a4 18 bb bc d5 9e ea 85 86 af af 63 d4 13 66 92 c4
ecdc 2b 69 84 ca 23 2b d3 66 81 6b 81 73 26 4 85 36 21 4c 49 44 75 64 39 16 3c
ecf5 ed e0 6d 44 75 45 30 43 68 c0 78 fc d0 17 b eb 81 3e c3 ba 1b f 4d ae c5
ed0e 55 1f c 39 12 5d 8 65 f1 34 59 de dd 98 56 17 43 38 66 49 9a eb db c1 87
ed27 51 38 cc b7 5f 98 fd 43 be 2d bb 74 f3 f8 f2 36 3d a4 34 a5 7e d2 26 cc
ed3f 84 1f ea 56 f0 80 18 69 4d 88 41 fc 56 fd 41 3b 1e e 9 27 4f f6 3b 62 4e
ed58 5a 1b 2a 4e 85 8c b2 4f 79 ef 59 4e e 73 3d bd c4 ca 60 e7 4a 47 90 b5 8
ed71 2a f0 4e dc ba 66 ae 48 2b 31 73 a2 11 c 32 ff 54 14 77 6b d6 58 4b bf ee
ed8a f6 6a bc dd 1 88 d da a9 f 81 24 c5 f8 72 9a db d5 c8 2a 80 a9 16 d7 c6
eda3 b1 91 c0 a9 95 40 b5 b3 a8 2a 28 c6 92 16 ab 54 7d f8 93 5f 3a 17 c8 45
edbb a9 f0 e0 71 23 76 53 38 a5 a1 cc d4 f1 f2 3c 2b 46 43 a1 d5 ba e d7 19 7a
edd4 c2 e1 8f 67 1d d 98 9d a1 79 9d 1b 20 7f 4d e7 bf f9 ff fe aa 28 ab 8f c
eded 4d 50 33 e3 26 fc 3c 3 3a 2b 26 12 f7 1 8f ee 97 4c e6 6 2b d9 1f a1 4a
ee06 77 44 d4 8b b7 3e 5e 2d 18 c3 54 68 99 a8 8d 92 96 9e 9d ab 33 38 ff b8
ee1e ee 78 c6 7b b5 84 95 d3 6 27 ae 5d 27 38 a 38 8e f0 1 a5 96 4b d7 9b 42
ee37 e5 6f 57 75 4c e9 78 2d 5b ec b6 d2 29 e2 a8 92 95 9c 65 2a 3e bf 8d e0
ee4f bf b3 ac c8 e 7e 13 af 88 26 7d 48 5a c7 39 29 36 d2 90 e8 3b 3 d0 61 1a
ee68 d2 e8 a8 f ba 8e a1 9f df 12 ab 54 7 23 98 de 62 af 4c 7e d4 fb 6b 2 6e
ee81 40 40 37 b7 73 f2 d8 81 be 29 d2 99 c0 73 25 1a 3c 92 75 6e bd d7 79 79
ee99 4 14 c0 4e 99 57 66 93 74 ec b0 29 7c df 61 b0 3 3a d1 c3 fa a4 f7 f 9f
eeb2 d3 f 0 b9 2a 5a 3a c5 88 25 b8 b9 cc 82 3 57 3a e1 7b 51 75 70 a6 74 1a
eecb ca cb 3 18 68 ca 77 fe 1b ad cd 68 7f 36 85 fc b7 4f a0 11 da 69 fa 79 87
eee4 d6 b9 21 dd 3e 70 db dc 84 d4 6e d1 20 4 af f6 32 a2 8e d 54 25 fe 7 54
eefd e 7a 74 4b a0 4b f7 f4 e8 74 22 e9 98 70 fb 25 2e f4 64 57 75 28 85 45 53
ef16 3a 2e e2 3c 54 36 e9 29 6 67 59 43 10 7e c1 49 cd 5e f9 97 a 58 5f 8a 11
ef2f 4f 3d 9a e2 2b 22 58 fa be fc 69 91 7a 8c 3f 77 9f c9 3b 54 26 23 93 b3
ef47 85 de ae f5 bd c5 47 4c c4 cd 5e ad bc 8f ba 31 f6 e4 70 fb 6e a7 96 d5
ef5f ad 10 80 39 43 97 4f 10 cc 1b 8f 8d cd 4c 63 4 d8 1e 85 70 41 6c a8 eb df
ef78 7f 36 c5 60 a7 12 9 16 73 fe 75 3a 2d 40 29 7d aa a 5c 2 29 23 0 a6 e5 6b
ef92 24 6d 9b 20 e5 7 cb 40 b0 38 59 9c a7 69 6a 70 d3 38 ef e2 b2 11 3e ea 2a
efab f9 2b 2e 43 1d 65 cf d6 1b ef 83 5a 5f e6 c5 62 16 ca 5e 4c a6 39 e4 53
efc3 2d 23 d2 5e 7e 15 54 8a 8 b7 3d bb 88 59 b9 9e a2 7c 42 1f a2 77 3c 5b 9
efdc 6d fa 8f 21 46 1a 3e ed ce 49 56 1d 29 2d 70 3 a7 6f 75 ac 1 87 ff 27 86
eff5 73 49 28 85 2d 97 7a 84 e 37 3d 86 10 21 4c e2 74 62 6b 51 70 8f 15 72 f3
e100e 81 b2 a9 9d 8a 63 ad 1b d5 aa 8a dc 96 3c e7 47 16 51 fc 87 50 9 b7 60
e1026 29 33 52 fb b0 df 70 c5 65 4a 60 3b c d7 a8 29 47 51 f7 8a 77 f3 99 3f
e103e 38 16 60 de 68 27 b2 24 7 62 a2 fd 40 86 b2 75 c3 3c 2f 3d fa 9 d9 a9 9a
e1057 71 3c ce 46 94 0 f9 bc 46 7f b8 2e 85 7f 7d d3 8d ea b4 63 81 59 10 bb
e106f 57 d0 b6 ab e1 83 74 1e 25 d5 73 78 18 b1 60 62 c f4 76 8d 17 d5 ed 23
e1087 23 e4 f6 32 64 5a 61 9 63 f6 92 57 d5 29 40 d6 3b ba 63 72 18 0 25 1b 7
e10a0 ee 7f 25 4a fa 6 74 19 46 e3 e8 89 7a c6 56 54 a7 43 13 4e bf 97 a5 6f
e10b8 99 2f ac 33 4d fa 58 3a 5a a a4 1a 74 62 c8 4f 3b 78 9 d7 ee 7e ee 2d 69
e10d1 30 40 ea 47 82 3b 85 8e 3 23 8f 74 4e 8 35 ab 74 4 1 57 d5 85 b1 6b 1e
e10ea f4 7d 1e d2 1e b3 fe f3 12 10 32 39 51 48 2d 6f e5 d3 a3 8c 8 8
g
3
0 2042天前
5996
转自看雪论坛:https://bbs.pediy.com/thread-249594.htm通过CPUID原理:通过检查功能号1的CPUID返回的ecx的最高位是否为1,如果为1,则在虚拟环境下运行。真机的最高位不为1。检测处理器是否支持 cpuid 指令(忽略这一条)现在的CPU都支持 cpuid 指令,没必要去检测是否支持,除非在很早的的机器上运行才有必要(那好像也要80486的机器吧)。在 eflags.ID 标志位是 Processor Feature Identification 位,即最高位,通过修改这个标志位的值,以此来检测是否支持 cpuid 指令。要使用CPUID指令,输入eax表示功能号(类似中断的用法)输出eax,ebx,ecx,edx在EDX和ECX中返回的功能标志表明着该CPU都支持那些功能。ECX返回值定义如下(资料来自Intel):bit Name Description
---------------------------------------------------------
00 SSE3 Streaming SIMD Extensions 3
01 Reserved
02 DTES64 64-Bit Debug Store
03 MONITOR MONITOR/MWAIT
04 DS-CPL CPL Qualified Debug Store
05 VMX Virtual Machine Extensions
06 SMX Safer Mode Extensions
07 EST Enhanced Intel SpeedStep® Technology
08 TM2 Thermal Monitor 2
09 SSSE3 Supplemental Streaming SIMD Extensions 3
10 CNXT-ID L1 Context ID
12:11 Reserved
13 CX16 CMPXCHG16B
14 xTPR xTPR Update Control
15 PDCM Perfmon and Debug Capability
17:16 Reserved
18 DCA Direct Cache Access
19 SSE4.1 Streaming SIMD Extensions 4.1
20 SSE4.2 Streaming SIMD Extensions 4.2
21 x2APIC Extended xAPIC Support
22 MOVBE MOVBE Instruction
23 POPCNT POPCNT Instruction
25:24 Reserved
26 XSAVE XSAVE/XSTOR States
27 OSXSAVE
31:28 Reserved
下面是使用CPUID检测的核心汇编代码:
.CODE
getcpuid PROC
xor eax,eax
mov eax,1h
cpuid
mov a,eax
mov b,ebx
mov c_var,ecx
mov d,edx
ret
getcpuid ENDP
END
通过利用IoInitializeTimer配合IoStartTimer的定时器来循环判定。遍历模块我们说到的第一种CPUID的方法可能通过修改VMX的配置等方法绕过。还有一种方式是遍历当前系统中所有的sys。我们要查找的是vmmouse.sys,vmrawdsk.sys,vmusbmouse.sys中的任意一个。核心是利用NtQuerySystemInformation:#include <ntddk.h>
#include <windef.h>
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
{
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef NTSTATUS(*NTQUERYSYSTEMINFORMATION) (
IN ULONG SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG_PTR SystemInformationLength,
OUT PULONG_PTR ReturnLength OPTIONAL
);
VOID getcpuid();
BOOLEAN CheckDriverModule();
UNICODE_STRING symLinkName = { 0 };
PDEVICE_OBJECT pDevice;
PETHREAD pThreadObject = NULL;
BOOLEAN boom = FALSE;
//eax为CPU型号
//若为虚拟机,则ecx最高位为1;如果是物理机,则最高位为0.
//code in cpuid.asm
DWORD a = 0, b = 0, c_var = 0, d = 0;
VOID Unload() {//PDRIVER_OBJECT DriverObject
if (pThreadObject) {
boom = TRUE;
KeWaitForSingleObject(pThreadObject, Executive, KernelMode, FALSE, NULL);
}
if (pDevice) {
IoStopTimer(pDevice);
IoDeleteSymbolicLink(&symLinkName);
IoDeleteDevice(pDevice);
pDevice = NULL;
}
DbgPrint("Unload --------");
}
VOID TimerRoutine(PDEVICE_OBJECT DeviceObject, PVOID context) {
DbgPrint("In TimerRoutine\n");
//Begin normal check
getcpuid();
c_var = c_var >> 31;
if (c_var){
DbgPrint("Running in the virtual machine 2. Find VMWare by CPUID!!!!\n");
}
}
BOOLEAN CheckDriverModule() {
BOOLEAN bRet = FALSE;
NTQUERYSYSTEMINFORMATION m_NtQuerySystemInformation = NULL;
UNICODE_STRING NtQuerySystemInformation_Name = { 0 };
PSYSTEM_MODULE_INFORMATION ModuleEntry = NULL;
ULONG_PTR RetLength = 0, BaseAddr = 0, EndAddr = 0;
ULONG ModuleNums = 0, Index = 0;
NTSTATUS status = STATUS_SUCCESS;
PVOID Buffer = NULL;
RtlInitUnicodeString(&NtQuerySystemInformation_Name, L"NtQuerySystemInformation");
do
{
m_NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&NtQuerySystemInformation_Name);
if (m_NtQuerySystemInformation == NULL) {
bRet = TRUE;
break;
}
status = m_NtQuerySystemInformation(0xb, NULL, 0, &RetLength);
if (status < 0 && status != STATUS_INFO_LENGTH_MISMATCH) {
bRet = TRUE;
break;
}
Buffer = ExAllocatePoolWithTag(PagedPool, RetLength, "ytz");
if (Buffer == NULL) {
bRet = TRUE;
break;
}
RtlZeroMemory(Buffer, RetLength);
status = m_NtQuerySystemInformation(0xb, Buffer, RetLength, &RetLength);
if (status < 0) {
bRet = TRUE;
break;
}
ModuleNums = *(ULONG*)Buffer;
ModuleEntry = (PSYSTEM_MODULE_INFORMATION)((ULONG_PTR)Buffer + 8);
for (Index = 0; Index < ModuleNums; Index++) {
if (strstr(ModuleEntry->ImageName, "vmmouse.sys") ||
strstr(ModuleEntry->ImageName, "vmrawdsk.sys") ||
strstr(ModuleEntry->ImageName, "vmusbmouse.sys")) {
DbgPrint("The Module Name is %s\n", ModuleEntry->ImageName);
bRet = TRUE;
break;
}
ModuleEntry++;
}
break; //Amuse
} while (TRUE);
if (Buffer)
{
ExFreePool(Buffer);
Buffer = NULL;
}
return bRet;
}
VOID CheckVmWare(PVOID context) {
LARGE_INTEGER sleeptime = { 0 };
sleeptime.QuadPart = -20000000;
while (1)
{
if (boom)
break;
if (CheckDriverModule()) {
DbgPrint("Running in the virtual machine 1. Find VMWare!!!!\n");
}
DbgPrint("Thread is working");
KeDelayExecutionThread(KernelMode, 0, &sleeptime);
}
PsTerminateSystemThread(STATUS_SUCCESS);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING RegPath) {
HANDLE hThread = NULL;
NTSTATUS status = NULL;
UNICODE_STRING DeviceName = { 0 };
driverObject->DriverUnload = Unload;
status = PsCreateSystemThread(&hThread, 0, NULL, NULL, NULL, CheckVmWare, NULL);
if (!NT_SUCCESS(status)) {
DbgPrint("Create Thread Failed!\n");
return STATUS_UNSUCCESSFUL;
}
status = ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &pThreadObject, NULL);
if (!NT_SUCCESS(status))
{
DbgPrint("Cannot reference");
ObDereferenceObject(pThreadObject);
}
RtlInitUnicodeString(&DeviceName, L"\\Device\\MyDevices");
status = IoCreateDevice(driverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevice);
if (!NT_SUCCESS(status)) {
DbgPrint("Create Device Failed!");
return STATUS_UNSUCCESSFUL;
}
RtlInitUnicodeString(&symLinkName, "\\?\\SybLinkName");
status = IoCreateSymbolicLink(&symLinkName, &DeviceName);
if (!NT_SUCCESS(status)) {
DbgPrint("Create SymLink Failed!");
//return STATUS_UNSUCCESSFUL;
}
IoInitializeTimer(pDevice, (PIO_TIMER_ROUTINE)TimerRoutine, NULL);
IoStartTimer(pDevice);
ZwClose(hThread);
return STATUS_SUCCESS;
}注:在X64下使用上文的汇编代码时,需要修改下asm的属性。效果: github:https://github.com/pcy190/DriverKit/tree/master/AntiVirtualMachine_driver
2
0 2046天前
5441
jQuery自诞生以来,版本越来越多,而且jQuery官网的新版本还在不断的更新和发布中,现已经达到了2.x甚至更新的版本,但是我们在以前的项目中就已经使用了旧版本的jQuery,比如已经出现的:1.3.X、1.4.X、1.5.X、1.6.2等等。 由于项目的需要,必然也需要不断的使用较新版的jQuery,但对于原来就已经存在并已经采用了的旧jQuery版本,我们如何让多个不同的jQuery版本在同一个页面并存而不冲突呢? 其实,利用jQuery.noConflict()特性,我们不仅可以让jQuery与其他的JS库并存,比如Prototype。也可以与jQuery本身的其他不同版本并存而不冲突。<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>在同一个页面中加载多个不同的jQuery版本</title>
<!-- 加载jQuery最新版本-->
<script type="text/javascript" src="http://api.csource.com.cn/index.php?dir=&file=jquery-3.3.1.min.js"></script>
<script type="text/javascript">var jQuery_New = $.noConflict(true);</script>
<!-- 加载jQuery1.6.2版本-->
<script type="text/javascript" src="http://api.csource.com.cn/index.php?dir=&file=jquery-1.6.2.min.js"></script>
<script type="text/javascript">var jQuery_1_6_2 = $.noConflict(true);</script>
<!-- 加载jQuery1.5.2版本-->
<script type="text/javascript" src="http://api.csource.com.cn/index.php?dir=&file=jquery-1.5.2.min.js"></script>
<script type="text/javascript">var jQuery_1_5_2 = $.noConflict(true);</script>
<!-- 加载jQuery1.4.2版本-->
<script type="text/javascript" src="http://api.csource.com.cn/index.php?dir=&file=jquery-1.4.2.min.js"></script>
<script type="text/javascript">var jQuery_1_4_2 = $.noConflict(true);</script>
<!-- 加载jQuery1.3.2版本-->
<script type="text/javascript" src="http://api.csource.com.cn/index.php?dir=&file=jquery-1.3.2.min.js"></script>
<script type="text/javascript">var jQuery_1_3_2 = $.noConflict(true);</script>
<!-- 测试效果 -->
<script type="text/javascript">
alert(jQuery_New.fn.jquery);
alert(jQuery_1_6_2.fn.jquery);
alert(jQuery_1_5_2.fn.jquery);
alert(jQuery_1_4_2.fn.jquery);
alert(jQuery_1_3_2.fn.jquery);
jQuery_New(function($){$('<p>我是最新的'+$.fn.jquery+'版本添加进来的。</p>').appendTo('body');});
jQuery_1_6_2(function($){$('<p>我是'+$.fn.jquery+'版本添加进来的。</p>').appendTo('body');});
jQuery_1_5_2(function($){$('<p>我是'+$.fn.jquery+'版本添加进来的。</p>').appendTo('body');});
jQuery_1_4_2(function($){$('<p>我是'+$.fn.jquery+'版本添加进来的。</p>').appendTo('body');});
jQuery_1_3_2(function($){$('<p>我是'+$.fn.jquery+'版本添加进来的。</p>').appendTo('body');});
</script>
</head>
<body>
在同一个页面中加载多个不同的jQuery版本
<br>
</body>
</html>文件所用jsquery均可在:http://api.csource.com.cn/ 获取
2
0 2086天前
7205
原文地址:https://bbs.pediy.com/thread-225175.htm今天我们探索一个问题: 64位的ntdll是如何被加载到WoW64下的32位进程?今天的旅程将会带领我们进入到Windows内核逻辑中的未知领域,我们将会发现32位进程的内存地址空间是如何被初始化的。WoW64是什么?来自MSDN:WOW64是允许32位Windows应用程序无缝运行在64位Windows的模拟器。 换句话说,随着64位版本Windows的引进,Microsoft需要拿出一种允许在32位时代的Windows程序与64位Windows新的底层组件无缝交互的解决方案。特别是64位内存寻址和与内核直接交流的组件。两个NT层,一个内核在32位的Windows系统中,要调用Windows API的应用程序需要经过一系列的动态链接库(DLL)。然而,所有的系统调用最终会定向到ntdll.dll,它是在用户模式下将用户模式API传递给内核的最高层。以调用CreateFileW为例,这个API调用源于用户模式下的kernel32.dl,随后它以NtCreateFile传递给ntdll,随后NtCreateFile通过系统调度程序将控制权传递给内核。在32位Windows下这是非常简单的,然而,在WoW64下需要额外的步骤。32位的ntdll不可以直接将控制权交给内核,因为内核是64位的,只接受遵循64位ABI的类型(译者注:ABI,Application Binary Interface,应用二进制接口)。正因为如此,一个翻译层以几个标准的命名为wow64.dll,wow64cpu.dll和wow64win.dll的DLL的形式被添加到64位Windows。这几个DLL负责将32位调用转换成64位调用。那些调用最终被定向到映射到每个32位进程中的64位ntdll。许多关于这种从32位系统调用到64位系统调用(1)的神奇转换的信息是可获得的,所以我们不会从这里进入。我们最关注的是内核何时和怎样将64位版本的ntdll映射到一个32位进程。看起来像这样:我们特别关注倒数第二项。我们能发现ntdll被映射到地址是64位地址范围(7FFFFED40000-7FFFFEF1FFFF),而且它的位置在Windows 64位系统文件所在的System32\路径下。然而,我们知道32位进程不可以访问或者运行在64位内存空间。为了理解上面输出的内容,我们首先讨论VAD(Virtual Address Descriptor,虚拟地址描述符)是什么和它将如何帮助我们理解加载64位dll到32位进程的机制的。什么是虚拟地址描述符?VAD是Windows操作系统跟踪系统中可用物理内存的许多方法之一。VAD专门跟踪每个进程用户模式范围的保留的和提交的地址。任何时候一个进程请求一些内存,一个新的VAD实力被创建用来跟踪内存。VAD被构造成一个自平衡树,每个节点描述了一段内存范围。每个节点至多包含两个子节点,左边是低地址,右边是高地址。每个进程被分配一个VadRoot,之后通过遍历VadRoot来分辨额外用来描述保留或提交的虚拟地址范围的额外节点。我们需要关注WindDBG中的!vad命令的输出,因为这是我们将大量使用来跟踪64位Windows中32位进程的映射的输出。对于这个练习,不是所有的域对我们来说都是特别有趣的。我们考虑测试程序HelloWorld.exe的输出。通过!process ProcessObject 命令的输出来分辨我们进程的VadRoot。 一旦我们确定了VadRoot,我将地址输入到 !vad 命令。(输出为了容易分析已被截断)我们看到五列: "VAD", "Level", "Start", "End", 和"Commit".!vad命令 接受VAD实例的地址;在我们的例子中,我们已经为它提供了在此进程中通过使用!process命令获得的VadRoot。VAD地址是当前VAD结构体或实例的地址:等级(Level)描述了这个VAD实例(节点)在所在树中的级别。Level 0是从上面!process输出中获得的VadRoot。开始(Starting)和结束(Ending)地址值用VPN(Virtual Page Numbers,虚拟页数量)表示。这些地址可以通过乘以页面大小(4kb)或者左移3位转化为虚拟地址。结束VPN会添加一个额外的0xFFF来扩展到页面末尾。如我们上面例子中的D20->D20000,DD20->DD2FFF。提交(Commit)是被此VAD实例描述的范围内提交页面的数量。分配类型(type of allocation)告诉我们改特定范围是否已经被映射或是进程私有的。访问类型(Type of access)描述改范围内的允许访问。最后是被映射到当前区域对应的名称。一个AVD实例可以以多种方式创建。如通过使用映射API(CreateFileMapping/MapViewOfFile)或者内存分配API如VirutalAlloc函数。内存可以是保留或者提交的(或free的),或保留和部分提交的。无论哪一种,一个VAD项被映射到进程的Vad树来让内存管理器知道此进程中当前已提交的内存。我们对VAD 的观察将揭示WoW64下运行的32位进程的初始设置。 映射NT子系统DLL进程初始化的早期,在主可执行文件被映射和初始化之前,Windows为特殊区域确定和保留一些地址范围。其中包含初始进程地址空间,共享系统空间(_KUSER_SHARED_DATA),控制流守护位图区域,和NT本地子系统(ntdll)。由于进程初始化整体的复杂性,我们只关注最后一块,它包含32位ntdll和64位ntdll加载到32位进程地址空间的逻辑。我们关注一系列的API调用和在每个点的内存区域的虚拟地址描述符(VAD)。为了让内核区分怎样映射一个新进程,它需要知道是否这是一个WoW64进程。当进程对象最初被创建,内核通过读取名为_EPROCESS.Wow64Process的未文档化结构体_EPROCESS结构体的值来实现此操作。PspAllocateProcess是我们探索开始的地方,但是更具体的说,我们开始在MmInitializeProcessAddressSpace()。MmInitializeProcessAddressSpace()负责与一个新进程地址空间有关的初始化。它调用MiMapProcessExecutable,该函数创建了定义初始进程可寻址内存空间的VAD项,随后将新创建的进程映射到它的基虚拟地址。一个特别有趣的函数是PspMapSystemDlls。我们关注在调用PspMapSystemDlls之前的进程地址空间的样子。在WinDBG中确保我们当前处于我们测试应用程序的上下文中(.process),并寻找当前VadRoot(!vad output)。 到目前为止我们可以观察到,我们的进程在32问地址空间中被映射和分配了一个基地址(1200),内核共享内存(0x7FFE0000-0x7FFE0FFF) 和64KB保留内存区域(0x7FFE1000-0x7FFEFFFF) 也已经被映射到他们各自的虚拟地址。PspMapSystemDlls 通过一个包含多个平台子系统模块的全局指针迭代。对于x86和x64Windows,这些是分别位于 C:\Windows\SysWow64 和C:\Windows\System 目录中的ntdll.dll。一旦 PspMapSystemDlls 发现要加载的DLL,它调用 PspMapSystemDll 来映射他们(DLLs)到进程的地址空间。该函数非常简短,下面展示了一个片段。为了正确映射本地子系统,需要满足一些条件。 PspMapSystemDll 通过调用 MmMapViewOfSection 实现实际的本地DLL的映射,并保存所占的基地址。在这两个DLL映射完成并且他们的VAD项初始化完成后,我们的32位进程地址空间看起来像这样: 所以现在,我们映射完我们的进程(0xc40000-0xcf2fff),内核共享内存空间(0x7ffe0000-0x7ffe0fff),32位地址空间的有效结束区域(0x7ffe1000-0x7ffeffff),和我们的两个NT子系统DLL。锁定地址空间为了完成32位进程的映射,还有最后一步要做。我们知道一个32位进程最多寻址到2GB的虚拟内存,所以Windows需要屏蔽此进程剩余的地址空间。对于32位进程,屏蔽在 0x7FFF0000 - 0x7FFFFFFF 之后;然而,0x7FFeFFFF 之后什么也不可以映射。基于此事实,紧邻64位NTDLL的内存区域需要保留或者屏蔽。要做到这一点,内核标记剩下的64位地址空间为私有。它通过遍历当前进程的VAD树和定位最后可用的虚拟地址来创建此VAD项,然后附加一个新的VAD项。完成此任务的API是 MiInitializeUserNoAccess。该函数接受当前进程句柄和一个虚拟地址。传递的虚拟地址是 0x7FFF0000,这是32为进程最后可寻址范围的起始。然后,它遍历当前的VAD项并执行一个新范围的插入,该范围覆盖了32位进程剩余的地址空间。在此调用后,我们的进程地址空间看起来像这样: 我们现在可以发现,我们的32位进程已经映射,并且它的合规的内存地址范围已经被内核保留。涵盖 0x7FFF0 - 0x7FFFFED3F 和 0x7FFFFEF20- 0x7FFFFFFEF 范围的VAD实例已经被内核保留为私有。随后任何检索内存的调用仅仅会发生在允许的32为地址空间内。一旦进程完全加载,我们可以看到额外的已提交的内存出现在进程(0xC40000)附近的地址空间。 结束演讲我们观察到64位Windows下的32位进程的初始映射以及64位ntdll如何被映射到64位区域,随后64位地址空间被锁定,防止用户访问,我们学到了什么?1、早期初始化逻辑决定我们是否准备映射一个WoW64进程。2、分配最初的32位地址空间区域;这包括最高可访问的32位地址范围,和进程首选的基虚拟地址。3、NT子系统DLL被加载到他们各自的地址范围,32位ntdll加载到32位空间,64位ntdll加载到64位地址空间。4、MmInitializeUserNoAccess 用来创建与64位ntdll范围相邻的西游范围。这具有从32位进程锁定64位可寻址空间的效果。希望这篇文章提供了一些关于Windows如何允许讲32位进程无缝集成到64位Windows操作系统的透明度。随着WoW64模拟层的添加,对地址空间可用性进行了一些额外的考虑,并且这个过程反映了一些这些考虑和及其实现。
2
0 2398天前
6046
DBA操作规范作者:hcymysql 原文转自:http://blog.51cto.com/hcymysql/20614511、涉及业务上的修改/删除数据,在得到业务方、CTO的邮件批准后方可执行,执行前提前做好备份,必要时可逆。2、所有上线需求必须走工单系统,口头通知视为无效。3、在对大表做表结构变更时,如修改字段属性会造成锁表,并会造成从库延迟,从而影响线上业务,必须在凌晨0:00 后业务低峰期执行,另统一用工具 pt-online-schema-change 避免锁表且降低延迟执行时间。使用范例:#pt-online-schema-change --alter="add index IX_id_no(id_no)" \
--no-check-replication-filters --recursion-method=none --user=dba \
--password=123456 D=test,t=t1 --execute对于MongoDB创建索引要在后台创建,避免锁表。使用范例:db.t1.createIndex({idCardNum:1},{background:1})4、所有线上业务库均必须搭建MHA高可用架构,避免单点问题。5、给业务方开权限时,密码要用MD5加密,至少16位。权限如没有特殊要求,均为select查询权限,并做库表级限制。6、删除默认空密码账号。delete from mysql.user where user='' and password='';
flush privileges;7、汇总库开启Audit审计日志功能,出现问题时方可追溯。行为规范8、禁止一个MySQL实例存放多个业务数据库,会造成业务耦合性过高,一旦出现问题会殃及池鱼,增加了定位故障问题的难度。通常采用多实例解决,一个实例一个业务库,互不干扰。9、禁止在主库上执行后台管理和统计类的功能查询,这种复杂类的SQL会造成CPU的升高,进而会影响业务。10、批量清洗数据,需要开发和DBA共同进行审查,应避开业务高峰期时段执行,并在执行过程中观察服务状态。11、促销活动等应提前与DBA当面沟通,进行流量评估,比如提前一周增加机器内存或扩展架构,防止DB出现性能瓶颈。12、禁止在线上做数据库压力测试。基本规范13、禁止在数据库中存储明文密码。14、使用InnoDB存储引擎。支持事务,行级锁,更好的恢复性,高并发下性能更好。InnoDB表避免使用COUNT(*)操作,因内部没有计数器,需要一行一行累加计算,计数统计实时要求较强可以使用memcache或者Redis。15、表字符集统一使用UTF8。不会产生乱码风险。16、所有表和字段都需要添加中文注释。方便他人、方便自己。17、不在数据库中存储图片、文件等大数据。图片、文件更适合于GFS分布式文件系统,数据库里存放超链接即可。18、避免使用存储过程、视图、触发器、事件。MySQL是OLTP应用,最擅长简单的增、删、改、查操作,但对逻辑计算分析类的应用,并不适合,所以这部分的需求最好通过程序上实现。19、避免使用外键,外键用来保护参照完整性,可在业务端实现。外键会导致父表和子表之间耦合,十分影响SQL性能,出现过多的锁等待,甚至会造成死锁。20、对事务一致性要求不高的业务,如日志表等,优先选择存入MongoDB。其自身支持的sharding分片功能,增强了横向扩展的能力,开发不用过多调整业务代码。库表设计规范21、表必须有主键,例如自增主键。这样可以保证数据行是按照顺序写入,对于SAS传统机械式硬盘写入性能更好,根据主键做关联查询的性能也会更好,并且还方便了数据仓库抽取数据。从性能的角度来说,使用UUID作为主键是个最不好的方法,它会使插入变得随机。22、禁止使用分区表。分区表的好处是对于开发来说,不用修改代码,通过后端DB的设置,比如对于时间字段做拆分,就可以轻松实现表的拆分。但这里面涉及一个问题,查询的字段必须是分区键,否则会遍历所有的分区表,并不会带来性能上的提升。此外,分区表在物理结构上仍旧是一张表,此时我们更改表结构,一样不会带来性能上的提升。所以应采用切表的形式做拆分,如程序上需要对历史数据做查询,可通过union all的方式关联查询。另外随着时间的推移,历史数据表不再需要,只需在从库上dump出来,即便捷地迁移至备份机上。字段设计规范23、用DECIMAL代替FLOAT和DOUBLE存储精确浮点数。浮点数的缺点是会引起精度问题,请看下面一个例子:mysql> CREATE TABLE t3 (c1 float(10,2),c2 decimal(10,2));
Query OK, 0 rows affected (0.05 sec)
>mysql> insert into t3 values (999998.02, 999998.02);
Query OK, 1 row affected (0.01 sec)
>mysql> select * from t3;
+-----------+-----------+
| c1 | c2 |
+-----------+-----------+
| 999998.00 | 999998.02 |
+-----------+-----------+
1 row in set (0.00 sec)可以看到c1列的值由999998.02变成了999998.00,这就是float浮点数类型的不精确性造成的。因此对货币等对精度敏感的数据,应该用定点数表示或存储。24、使用TINYINT来代替ENUM类型。采用enum枚举类型,会存在扩展的问题,例如用户在线状态,如果此时增加了:5表示请勿打扰、6表示开会中、7表示隐身对好友可见,那么增加新的ENUM值要做DDL修改表结构操作了。25、字段长度尽量按实际需要进行分配,不要随意分配一个很大的容量。选择字段的一般原则是保小不保大,能用占用字节少的字段就不用大字段。比如主键,强烈建议用int整型,不用uuid,为什么?省空间啊。空间是什么?空间就是效率!按4个字节和按32个字节定位一条记录,谁快谁慢太明显了。涉及几个表做join时,效果就更明显了。更小的字段类型占用的内存就更少,占用的磁盘空间和磁盘I/O也会更少,而且还会占用更少的带宽。有不少开发人员在设计表字段时,只要是针对数值类型的全部用int,但这不一定合适,就比如用户的年龄,一般来说,年龄大都在1~100岁之间,长度只有3,那么用int就不适合了,可以用tinyint代替。又比如用户在线状态,0表示离线、1表示在线、2表示离开、3表示忙碌、4表示隐身等,其实类似这样的情况,用int都是没有必要的,浪费空间,采用tinyint完全可以满足需要,int占用的是4字节,而tinyint才占用1个字节。int整型有符号(signed)最大值是2147483647,而无符号(unsigned)最大值是4294967295,如果你的需求没有存储负数,那么建议改成有符号(unsigned),可以增加int存储范围。int(10)和int(1)没有什么区别,10和1仅是宽度而已,在设置了zerofill扩展属性的时候有用,例:root@localhost(test)10:39>create table test(id int(10) zerofill,id2 int(1));
Query OK, 0 rows affected (0.13 sec)
root@localhost(test)10:39>insert into test values(1,1);
Query OK, 1 row affected (0.04 sec)
root@localhost(test)10:56>insert into test values(1000000000,1000000000);
Query OK, 1 row affected (0.05 sec)
root@localhost(test)10:56>select * from test;
+------------+------------+
| id | id2 |
+------------+------------+
| 0000000001 | 1 |
| 1000000000 | 1000000000 |
+------------+------------+
2 rows in set (0.01 sec)26、字段定义为NOT NULL要提供默认值。从应用层角度来看,可以减少程序判断代码,比如你要查询一条记录,如果没默认值,你是不是得先判断该字段对应变量是否被设置,如果没有,你得通过java把该变量置为''或者0,如果设了默认值,判断条件可直接略过。NULL值很难进行查询优化,它会使索引统计更加复杂,还需要MySQL内部进行特殊处理。27、尽可能不使用TEXT、BLOB类型。增加存储空间的占用,读取速度慢。索引规范28、索引不是越多越好,按实际需要进行创建。索引是一把双刃剑,它可以提高查询效率但也会降低插入和更新的速度并占用磁盘空间。适当的索引对应用的性能至关重要,而且在MySQL中使用索引它的速度是极快的。遗憾的是,索引也有相关的开销。每次向表中写入时(如INSERT、UPDATEH或DELETE),如果带有一个或多个索引,那么MySQL也要更新各个索引,这样索引就增加了对各个表的写入操作的开销。只有当某列被用于WHERE子句时,才能享受到索引的性能提升的好处。如果不使用索引,它就没有价值,而且会带来维护上的开销。29、查询的字段必须创建索引。如:1、SELECT、UPDATE、DELETE语句的WHERE条件列;2、多表JOIN的字段。30、不在索引列进行数学运算和函数运算。无法使用索引,导致全表扫描。例:SELECT * FROM t WHERE YEAR(d) >= 2016;由于MySQL不像Oracle那样支持函数索引,即使d字段有索引,也会直接全表扫描。应改为----->SELECT * FROM t WHERE d >= '2016-01-01';31、不在低基数列上建立索引,例如‘性别’。有时候,进行全表浏览要比必须读取索引和数据表更快,尤其是当索引包含的是平均分布的数据集是更是如此。对此典型的例子是性别,它有两个均匀分布的值(男和女)。通过性别需要读取大概一半的行。在种情况下进行全表扫描浏览要更快。32、不使用%前导的查询,如like ‘%xxx’。无法使用索引,导致全表扫描。低效查询
SELECT * FROM t WHERE name LIKE '%de%';
----->
高效查询
SELECT * FROM t WHERE name LIKE 'de%';33、不使用反向查询,如 not in / not like。无法使用索引,导致全表扫描。34、避免冗余或重复索引。联合索引IX_a_b_c(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c),那么索引 (a) 、(a,b) 就是多余的。SQL设计规范*35、不使用SELECT ,只获取必要的字段。**消耗CPU和IO、消耗网络带宽;无法使用覆盖索引。36、用IN来替换OR。低效查询
SELECT * FROM t WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30;
----->
高效查询
SELECT * FROM t WHERE LOC_IN IN (10,20,30);37、避免数据类型不一致。SELECT * FROM t WHERE id = '19';
----->
SELECT * FROM t WHERE id = 19;38、减少与数据库的交互次数。INSERT INTO t (id, name) VALUES(1,'Bea');
INSERT INTO t (id, name) VALUES(2,'Belle');
INSERT INTO t (id, name) VALUES(3,'Bernice');
----->
INSERT INTO t (id, name) VALUES(1,'Bea'), (2,'Belle'),(3,'Bernice');
Update … where id in (1,2,3,4);
Alter table tbl_name add column col1, add column col2;39、拒绝大SQL,拆分成小SQL。低效查询
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id = tag.id
JOIN post ON tag_post.post_id = post.id
WHERE tag.tag = 'mysql';
可以分解成下面这些查询来代替
----->
高效查询
SELECT * FROM tag WHERE tag = 'mysql'
SELECT * FROM tag_post WHERE tag_id = 1234
SELECT * FROM post WHERE post_id in (123, 456, 567, 9098, 8904);40、禁止使用order by rand()SELECT * FROM t1 WHERE 1=1 ORDER BY RAND() LIMIT 4;
---->
SELECT * FROM t1 WHERE id >= CEIL(RAND()*1000) LIMIT 4;
2
0 2451天前