精华内容
下载资源
问答
  • 【文章标题】: HOOK大法实现不修改程序代码给程序添加功能 【文章作者】: 0x18c0 【软件名称】: Scylla 【使用工具】: OD、Stub_PE、ResHacker 【版权声明】: 本文原创于0x18c0, 转载请注明作者并保持文章的完整...
    【文章标题】: HOOK大法实现不修改程序代码给程序添加功能
    【文章作者】: 0x18c0
    【软件名称】: Scylla
    【使用工具】: OD、Stub_PE、ResHacker
    【版权声明】: 本文原创于0x18c0, 转载请注明作者并保持文章的完整, 谢谢!

    菜鸟第一次发帖,写的不好的地方请各位多多包含

    本来是第三次培训的作业,要给Scylla加上弹窗
    @Kido 老师在上课的时候也演示了,没什么难度,但是按照上课的方法来搞,程序一运行就弹个窗口,太粗暴,强迫症完全不能忍好吧,所以我想在窗口上加个按钮,等点击按钮的时候再弹出窗口,这样就感觉友好多了。
     
    这么做其实也不难,方法就是找到窗口的过程函数,然后改写指令让程序先跳到我们自己写的函数里,最后再跳转回原窗口过程函数
    比如@苏紫方璇 大牛这篇帖子的方法,无源码给程序添加功能-记事本标题添加当前时间
    但是,这么搞太麻烦了,需要自己定位窗口过程,还要各种修改指令实现跳转,完全不适合我这种懒人
    但是,懒人有懒人的方法,俗话说的好,懒是推动科技进步的根本动力——0x18c0
    这里我已经忍不住要高喊一句——HOOK大法好!



    先介绍一下方法,我修改了Scylla的导入表,添加了一个我自己编写的DLL,然后在DLL的DllMain函数里下消息hook,每当按钮被按下时,WM_COMMAND消息就会被hook住,从而弹出窗口。



    基本方法介绍完了,下面介绍一下HOOK和DLL的基本知识
    一、HOOK
            Hook,字面意思就是钩子,是windows系统提供给开发者用来改变windows消息处理流程的编程接口。hook也分好几种,拿下面我要用到的消息hook来举例,每当我们按下一个窗口上的按钮时,系统就会捕获到一个WM_COMMAND消息,消息会被Windows系统传递给软件提前编写好的一个函数,这个函数叫做窗口过程函数,过程函数会根据不同的消息做出不同的处理。但是当我们想在消息被操作系统传递给过程函数处理之前先处理怎么办呢?这个时候就要用到消息hook了,操作系统提供给了开发者改变消息的能力,我们只需要调用相关的API,在相应的消息上设置hook钩子,并且告诉操作系统当消息被钩子钩住的时候因该怎么办,操作系统就会按照我们的意愿来处理消息。
            比如我们hook按钮被按下的消息WM_COMMAND,并且告诉操作系统,当钩子被触发的时候把消息传递给我自己编写的函数HookMSG,于是我们每次按下按钮,钩子都会被触发,并且操作系统会自动
    调用HookMSG函数。
    二、DLL
            DLL,动态链接库,可以导出变量和函数供其他程序调用,也可以包含资源文件,DLL有一个DllMain函数,每当DLL被链接时都会被调用,并且不同的调用原因可以有不同的处理办法。所以我们用Stub_PE将一个DLL添加到Scylla的倒入表里,每次Scylla运行时操作系统都回自动载入我们添加的DLL,并且运行DllMain里的代码,所以我们在DllMain里写上我们的hook代码,那么每次Scylla运行都会被自动hook了,这样就达到了我们的目的。



    方法和基本原理都说了,下面就应该开始实战
    一、添加按钮资源
    首先得给Scylla加一个按钮,用ResHacker打开Scylla,在对话框上要添加按钮的地方右键——>insert control,出现添加控件的窗口
     
    选择控件类型为BUTTON,caption这里填写需要显示在按钮上的字,最后别忘了给按钮添加ID,ID需要和其他控件不同以免冲突,这里我填写1099
    ,点击ok后界面上了出现我们添加的按钮,接下来不要忘了编译和保存
     


    二、编写DLL
    接下来我们编写DLL,我电脑上只有vs2013,所以我就用它了,你们也可以用其他编译器,只要可以编写Windows系统上的DLL就可以。
    1.新建工程
    选择win32项目,填写工程名,点击确定
     
    选择DLL和空项目,点击完成,项目创建完成,然后添加main.cpp到工程
     

    2.编写代码
    首先编写DllMain函数
    [C++] 纯文本查看 复制代码
    ?
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    {
            switch (ul_reason_for_call)
            {
            case DLL_PROCESS_ATTACH:     //dll载入时执行
            {
                    g_hModule = hModule;     //保存句柄到全局变量
                    hhk = StartHook();
                    break;
            }
            case DLL_PROCESS_DETACH:     //dll卸载时执行
            {
                    EndHook();
                    break;
            }
            case DLL_THREAD_ATTACH:
            case DLL_THREAD_DETACH:
                    break;
            }
            return TRUE;
    }

    DllMain函数的ul_reason_for_call指明了函数被调用的原因,DLL_PROCESS_ATTACH指DLL被调用,DLL_PROCESS_DETACH指DLL被卸载,而case DLL_THREAD_ATTACH和case DLL_THREAD_DETACH分别表示线程被创建和销毁。我们在dll加载时调用StartHook函数,dll卸载时调用EndHook函数,下面我们看看这两个函数
    [C++] 纯文本查看 复制代码
    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    HHOOK StartHook()
    {
            return SetWindowsHookEx(WH_CALLWNDPROC, HookProc, g_hModule, GetCurrentThreadId());//设置hook,类型为WH_CALLWNDPROC,过程函数为HookProc,hook当前线程
    }
     
    BOOL EndHook()
    {
            return UnhookWindowsHookEx(hhk);     //结束hook
    }

    这两个函数只是很简单的封装了俩个API,重点在于SetWindowsHookEx的参数设置,由于我们hook的是WM_COMMAND消息,所以我们选择hook类型为WH_CALLWNDPROC,表明当窗口过程函数被调用时触发hook,并且我们是hook当前线程,hook过程函数在dll里,所以第三个参数填dll模块句柄或者NULL都行,第四个参赛则直接利用GetCurrentThreadId()获取当前线程id
    这里有一篇文章介绍hook的类型,写的很不错,有兴趣的可以看看http://blog.csdn.net/whatday/article/details/8006225
    重点还在hook过程函数,我们需要在这里过滤出我们需要的消息,并编写功能代码
    [C++] 纯文本查看 复制代码
    ?
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
            if (nCode >= 0)
            {
                    CWPSTRUCT* cwps = (CWPSTRUCT*)lParam;
     
                    if (WM_COMMAND == cwps->message)
                    {
                            INT wmId = LOWORD(cwps->wParam);
                            if (wmId == 1099)
                                    DialogBoxParam(g_hModule, (LPCTSTR)IDD_DIALOG, NULL, DlgProc, NULL);
                    }
            }
     
            return CallNextHookEx(hhk, nCode, wParam, lParam);
    }

    由于我们只需要添加按钮弹窗功能,所以我们只过滤WM_COMMAND消息,前面我们添加按钮资源的时候id填写的是1099,这里就派上用场了。
    这里我调用了DialogBoxParam函数来弹出对话框,弹出对话框需要添加对话框资源,并且编写过程函数。
    选择vs2013的菜单项->项目->添加资源->Dialog->新建
     
    vs中出现我们新建的对话框资源
     
    我就不编辑资源了,直接开始编写对话框的过程函数,这里我没有添加任何功能代码
    [C++] 纯文本查看 复制代码
    ?
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
    {
            switch (msg)
            {
            case WM_CLOSE:
                    EndDialog(hDlg, NULL);
            }
     
            return FALSE;
    }

    到此为止,代码编写工作就完成了,但是这个dll没有一个导出函数,我们没法把它加到Scylla的导入表里,不过我们可以写一个空的导出函数
    [C++] 纯文本查看 复制代码
    ?
    1
    2
    3
    4
    __declspec(dllexport) void EmptyFunc()
    {
            //Do nothing
    }

    3.编译dll
    接下来我们编译dll,将工具条上的编译选项设为release,点击编译。
     
    如果你用的也是vs2013,这里需要修改两个地方的设置,否则编译出来的dll在xp上不能运行
    VS2013菜单->项目->属性->配置属性->常规->平台工具集->Visual Studio 2013 - Windows XP (v120_xp)
    VS2013菜单->项目->属性->配置属性->c/c++->代码生成->运行库->多线程 (/MT)
    在项目文件夹里找到HookMSG.dll,拷贝到Scylla目录下。

    三、修改Scylla导入表
    Stub_PE载入Scylla,选择“函数”选项卡,右键添加函数,选择HookMSG.dll,选择EmptyFunc函数,确定添加并保存。
     



    运行一下看结果,点击about按钮,对话框成功弹出,大功告成。
     


    写在最后:
    其实整个过程没有什么技术含量,懂Windows编程的人看一眼就懂,但是作为新手弄这些东西还是有点难,整个过程当中我也是遇到各种问题,不过结果总算是好的
    发这篇帖子的目的是希望与大家共勉,同时分享一下成功的喜悦,写的不好的地方希望大家多多包涵
    最后感谢论坛提供这个学习的机会,也感谢各位讲师@Hmily @Kido 的指导
    同时附上HookMSG.dll的完整源代码,链接:http://pan.baidu.com/s/1c0GvFOW  密码: v7um
    ps:其实Scylla是开源软件,想要汉化或者改界面的可以下载源代码自己编译,https://github.com/NtQuery/Scylla
    展开全文
  • 修改代码后,调试程序,当前不会命中断点,源代码与原始版本不同。网上搜索解决方案:1、工具”——>选项”——>调试”——>要求源文件与原始版本完成匹配”去掉勾选。未解决。 2、“编辑”-“高级”-“设置文档...

    1、vs2010修改源代码后,调试程序,当前不会命中断点,源代码与原始版本不同。网上搜索解决方案:1、工具”——>选项”——>调试”——>要求源文件与原始版本完成匹配”去掉勾选。未解决。 2、“编辑”-“高级”-“设置文档格式”。未解决。


    自行分析,新建解决方案,新建测试项目均不会出现此问题。则问题应该出现在出问题的解决方案设置或项目设置上,怀疑调试时候,修改的程序集没有重新编译。查看程序的,将 “生成” 勾选,再试,问题解决。差点儿把vs重装了,我去。

    2、VS调试时,不能修改源代码的解决方案。如下图所示提示:

    解决方案:
    (1)查看结果是和 “工具->选项->调试->编辑并继续->启用编辑并继续”以及“工具->选项->调试->常规->一个进程中断则中断所有进程”按钮有关,但是我的这两个按钮处于选中状态,都是正常状态。当去掉“启用编辑并继续”选项时,不弹出上面的问题提示(提示此源文件已更改,不再与以下版本的文件匹配,该版本的文件用于生成所调试的应用程序),但是代码修改后重新运行系统才可生效,同样影响工作效率。
    (2) 1的方案不起作用则怀疑是图上红框里面原因,即程序集生成时设置的调试信息为none或者pdb-only(一般Debug模式下为full Release模式下为pdb-only) 如果不设置为full,则不会允许修改代码。将生成配置修改成Debug或 在vs的程序集属性-》生成-》高级-》调试信息-》full即可,即保证生成设置为输出调试信息full。

    展开全文
  • 微信小程序代码修改无效

    千次阅读 2019-10-12 08:27:36
    dist编译后的文件不能修改,只能修改代码,重新编译。

    dist编译后的文件不能修改,只能修改源代码,重新编译。

    展开全文
  • 没有灵魂的微信小程序代码转支付宝小程序代码微信小程序与支付宝小程序直面代码的替换内容功能快捷键插入链接与图片如何插入一段漂亮的代码片导出与导入导出导入 微信小程序与支付宝小程序 作为一个微信小程序的半...

    没有灵魂的微信小程序代码转支付宝小程序代码

    微信小程序与支付宝小程序

    作为一个微信小程序的半新手,支付宝小程序的全新手! 在公司安排的这次任务中,需要把已经上线的支付宝小程序更新为和微信小程序一样的版本。就只有打开微信和支付宝的开发者对比两个版本的差异然后改改改了。如果是完全生成一个支付宝小程序项目,可参考:https://jingyan.baidu.com/article/a948d651c3ae330a2ccd2e77.html

    以下仅为个人要修改项目中所遇到的总结,如果没有你想知道的就还是去对比文档吧。这是本人第一次写博客,有错误的或者要添加的请大家多多指点

    微信小程序开发文档地址:https://developers.weixin.qq.com/miniprogram/dev/
    支付宝小程序开发者文档地址:https://docs.alipay.com/mini/developer/getting-started

    直面代码的替换内容

    两个小程序大体都是一样的,要修改的不过于有引用的组件名称,页面渲染的指令,点击事件的名称,调用的API等。如果是版本更新,只修改部分页面。一定要记得检查新增的页面,图片等。是否有的没有添加。

    1. 引用文件的名字 :把页面中的wxml改为axml;wxss改为acss

    2. AXML中的修改:选中所有的wx:替换为a:
      (1)在axml搜索bind;将bindTap替换为onTap,catchtap替换为catchTap。
      (2)一些常用组件的事件名称或属性如:scroll-view的bindscrolltolower替换为onScrollToLower,bindscrolltolower替换为onScrollToUpper。picker的bindchange替换为onChanges。checkbox的bindchange替换为onChange。form表单的bindsubmit,bindreset,form-type改为onSubmit,onReset,formType 。
      (3)常见规律是把bind替换为on,然后是以驼峰式命名。可以搜索bind进行查看。别的组件我没有一一列出来。项目有用到的话可以对照文档进行修改。

    3. js的修改:js中所有的wx.替换为my.
      (1) API名称或属性:showToast弱提示框,内容属性title替换成content。makePhoneCall拨打电话的参数phoneNumber替换成number。微信小程序设置导航栏API分别对应有wx.setNavigationBarTitle,wx.setNavigationBar,wx.setNavigationBarColor等,支付宝是在一个API中my.setNavigationBar通过入参进行修改。
      (2)图片的API:在选择图片chooseImage成功后返回的参数由tempFilePaths替换成apFilePaths。对图片进行压缩compressImage中。
      微信的对应的参数为:在这里插入图片描述
      支付宝对应参数为:在这里插入图片描述
      (3)支付的API:在验证支付是否成功时。
      微信对应返回:在这里插入图片描述 官方文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5
      支付宝对应返回:**加粗样式**
      官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/wx.requestPayment.html
      发起支付的api名称和参数时完全不同的,详情见连接。
      (4)内置地图选择地理位置的chooseLocation:调用这个api肯定是需要用户先授权的。(如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口;如果用户已授权,可以直接调用接口;如果已经拒绝授权的话就需要调用wx.openSetting 引导开启授权)
      对于支付宝来说,我也不知为何是可以直接调用的,不用重新引导授权之类的。它也不像微信,在一次申请用户授权后就需要调用openSetting 重新授权。官方文档中也没找到openSetting 这个API。有一个权限引导的my.showAuthGuide。但是里面对应不同设备权限不同。这个有大神知道的希望指点一二。在这里插入图片描述
      值得注意的是,在手机微信小程序中获取位置时有一个常用位置。选择这条地理位置返回的信息与别的位置返回数据是不同的(可能没有省市区)。需要用经纬度重新获取详细地址。在这里插入图片描述 支付宝小程序的位置选择在开发者工具中返回参数是文档所写那样,但是在手机上参数是如此返回的。在这里插入图片描述
      因此,最好用手机打开调试器,输出看一下。并且尤为重要的是Ios和Androidos常用位置返回参数信息是不同的。

    以上是在个人项目中所遇到的总结,大家可以先替换文件内容,直到页面不报错。在查看页面功能,有问题再对应文档进行比较。只是支付宝的文档着实差一点。等熟悉文档大致内容后和真机一起调试就不会再那么迷惑啦。

    功能快捷键

    选中所有匹配项:Ctrl+shift + L
    选中下一个匹配项:Ctrl + D
    查询:Ctrl + F

    展开全文
  • python批量修改文件程序代码

    千次阅读 2017-08-08 23:14:48
    2:因此到了这里,我们可以写个给批量文件的文件名去掉数字的程序 当我们运行程序时确发现控制台出现了这样的结果。 问题是出在了第九行,用os.getcwd()函数得到当前工作目录。 参考链接: python...
  • 退出程序代码

    千次阅读 2019-07-23 09:59:52
    public class MainActivity extends AppCompatActivity { ... // 利用handler延迟发送更改状态信息 mHandler.sendEmptyMessageDelayed(0, 2000); } else { finish(); System.exit(0); } } }
  • 程序代码示例整理

    千次阅读 2019-04-19 16:30:30
    以下是分享了一部分小程序代码示例,希望能够帮助到你们,抓紧收藏吧 微信小程序知乎日报 https://github.com/myronliu347/wechat-app-zhihudaily 微信小程序购物车案例 ... 微信小程序–聊天室功能 ...
  • 微信小程序代码提交步骤

    千次阅读 2019-04-12 16:12:29
    微信小程序提交代码分为两步: 一.本地提交 二.推送到github 1.点击右上角版本控制按钮,选择需要提交的文件,在下面协商更新日志,点击提交按钮(注意:本次提交仅为本地提交,实际没有上传到服务器) 2.可以...
  • 2.在app.js中修改id(客户登录后台管理系统的id),app.json中修改页面导航栏标题navigationBarTitleText | 3.配置合法域名(工具 -> 项目详情 -> 域名信息) 4.如果域名还没有配置,请前往...
  • 修改keil C程序代码字体: 常规设置:在keil C的菜单栏中,点击Edit,选择最下面的Configuration...,进入之后点击Colors&Fonts标签,然后选中自己想要修改字体的项目,比如C文件的程序代码,那么我们选择8051:...
  • DrawTools绘图程序代码分析

    千次阅读 2017-11-12 20:03:21
    代码从https://github.com/tolbkni/DrawTools中下载的,我看的是其中的Winform版本的实现代码,该程序代码量有两千行左右,主要实现的功能有:绘制线条绘制矩形绘制椭圆绘制自由曲线各种绘图对象的移动操作
  • 关于visual studio 2019修改C#代码程序运行不变的想法 C#窗体应用 把代码全都注释,发现程序依然不变 最后发现代码不是此项目的,是之前打开的项目的代码。 做个备忘 ...
  • 判断矩阵一致性检验的Matlab源程序代码

    千次阅读 多人点赞 2019-08-07 13:53:03
    Matlab源程序代码如下: clc clear disp('请输入判断矩阵A') A=input('A='); [n,n] = size(A) %方法1: 算术平均法 Sum_A = sum(A); SUM_A = repmat(Sum_A,n,1); Stand_A = A ./ SUM_A; Stand_A = A ./ Sum_A; % ...
  • 支付宝小程序代码提交五部曲

    千次阅读 2019-04-03 18:54:21
    3.用开发者工具打开小程序代码包,检查无误,点击上传 配置域名 用开发者工具打开代码包 查看控制台左边显示的模板是否是开发者小程序授权应用的模板,如果不是请检查域名配置,开发小程序appid 确认无误,.....
  • STM32F1_外部NorFlash存储程序代码

    万次阅读 2016-05-24 00:10:02
    推荐 分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!...今天提供的实例工程是存储程序代码到外部NorFlash,并执行外部NorFlash的代码(既然存储了程序代码,那么肯定也会运行...
  • 众所周知,微信小程序的语法和uniapp的语法接近,一个是Vue的近亲,一个完全兼容Vue,所以他们相互之间转换应该也是不难的。 微信小程序的语法,其实是vue.js语法的裁剪定制版,在数据绑定、自定义组件等很多方面都...
  • 6. 插入格式化程序代码 作为一个程序员????,笔记中带一些程序代码是一件很正常的事情。 那么如何在笔记中插入和IDE相同美丽的代码呢? 答案就是 - NoteHighlight2016 插件 作为一款开源的插件,它可以将主流的编程...
  • 仿CSND实现网页中程序代码高亮显示

    千次阅读 2016-07-12 21:28:54
    通过SyntaxHighlighter实现网页中程序代码高亮显示;将SyntaxHighlighter 整合到OneThink中的kindeditor中等
  • 在图灵社区使用 Markdown 写文章时,如果在一段文字的每行开头加上四个空格,或者一个制表符(Tab),这段文字就会被视为程序代码。这样,就会自动识别所用的编程语言,进行代码染色,语法高亮显示。但是,如果这段...
  • 将小程序代码转成uni-app代码

    万次阅读 2019-05-16 09:36:29
    首先你可以先到uni-app的官网简单看一下对它的介绍,本次文章的介绍是针对简单的微信小程序来进行的转化。 在这之前我们来看一下目录对比 下面就来介绍一下转移的步骤 1、首先你要新创建一个uniapp项目,...
  • 如何阅读他人的程序代码(上)——技巧学习篇

    万次阅读 多人点赞 2018-06-27 17:10:04
    一、读懂程序代码,使心法皆为我所用 程序代码是别人写的,只有原作者才真的了解程序代码的用途及涵义。许多程序人心里都有一种不自觉的恐惧感,深怕被迫去碰触其他人所写的程序代码。但是,与其抗拒接收别人的程序...
  • 程序代码包压缩 策略&方案

    千次阅读 2019-06-14 21:21:18
    微信小程序自推出以来,逐渐发展,目前正受到越来越多的青睐。...由于轻量级特性,小程序代码包体积、可用内存空间、可用存储空间等均受限制。如何在有效支持业务逻辑的同时,尽量减少资源占用,在小程序开发...
  • 程序代码中常用英文单词使用总结

    千次阅读 2014-12-22 16:12:43
    在写面向对象程序代码时有时想不起来应该用什么单词给类命名,下面把一些常用单词列出来
  • 微信小程序 代码实现 分享朋友圈

    千次阅读 2018-06-01 22:36:10
    程序 现有接口无法实现像公众号一样分享朋友圈功能,那么如何实现朋友圈分享呢!我们可以借道小程序二维码识别功能,就和以前某些智力测试疯传一样方式,将文章生成一张图片同时带小程序二维码。通过识别二维码...
  • Android 退出整个程序代码

    千次阅读 2013-04-19 10:45:04
    今天在网上看见个博客关于退出整个程序的,感觉不错,拿来分享学习 SysApplication这个类复制到工程里面,然后在每个Acitivity的oncreate方法里面通过SysApplication.getInstance().addActivity(this); 添加当前...
  • 如何阅读他人的程序代码【转载】

    千次阅读 2010-03-12 16:51:00
    近日,在互联网上游荡,偶然发现一篇曾经的文章,是关于如何阅读他人程序代码的,阅后颇为受益,于是乎重新整理了一下格式,将此文转载如下: 如何阅读他人的程序代码文/王建兴 作者简介: 王建兴,清华大学资讯...
  • 如何快速读懂大型C++程序代码

    万次阅读 2014-08-01 15:36:27
    如何快速读懂大型C++程序代码  (2012-06-14 11:25:03) 标签:  c编程 分类: C 学习 六个章节: ( 1 )读懂程序码,使心法皆为我所用。 ( 2 )摸清架构,便可轻松掌握全貌。...
  • 这里只是想把微信的代码统一管理,所以决定放到微信的git上 创建远程项目 在微信开发管理工具上点击代码管理 完成用户名密码设定后,点击创建项目。纯英文路径 点击记入项目后可以看到很多参考命令 把项目推送到...
  • 抖音网红追女生小程序代码

    千次阅读 2018-11-15 11:18:29
    msgbox "做我女朋友好吗",vbQuestion,"在吗" msgbox ("房产写你名字") msgbox ("保大") msgbox ("我妈会游泳") ...新建一个文本,拷贝上面的代码保存,然后修改文本后戳为“.vbs” !注意打开显示文件扩展名

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,497,227
精华内容 998,890
关键字:

修改程序代码