TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2008年12月31日 星期三

Self extract loader

以下說明一個較為粗糙的自解檔寫作方式。完成品分為三個部分,啟動器,分隔識別字,以及被包起來的本體,也就是說是二個檔案硬接在一起,中間用一個字串當分隔。
本體程式為了方便,我用一個簡單的shell script做範例,在真實狀況可以是任何檔案。檔名為start.sh。
#! /bin/sh
echo 'Hello, world!'
分隔識別字我使用字串"__METAMAGIC__",magic number[!]請挑選很難重複的字串。
接下來就是關鍵的啟動器了:
#include <fstream>
#include <string>
#include <list>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <cstdlib>

int main( int argc, char * argv[] ) {
    using namespace std;
    ifstream fin( argv[0], ios::binary );

    if( fin.is_open() ) {
        list< char > self;
        copy( istreambuf_iterator< char >( fin ),
              istreambuf_iterator< char >(),
              back_inserter( self ) );
        fin.close();

        string magic( "!_METAMAGIC__" );
        magic[0] = '_';
        list< char >::iterator result = search( self.begin(), self.end(), magic.begin(), magic.end() );
        if( result == self.end() ) {
            cerr << "Can not find piece!" << endl;
        } else {
            advance( result, magic.length() );
            ofstream fout( "/tmp/injection", ios::binary );
            if( fout.is_open() ) {
                copy( result, self.end(),
                      ostreambuf_iterator< char >( fout ) );
                fout.close();
                list< char >().swap( self );
                system( "chmod a+x /tmp/injection && /tmp/injection && rm -f /tmp/injection" );
            } else {
                cerr << "Can not write `/tmp/injection\'!" << endl;
            }
        }
    } else {
        cerr << "Can not open " << argv[0] << "!" << endl;
    }

    return 0;
}
首先以二進位的方式讀取自己,並存到容器內:
copy( istreambuf_iterater< char >( fin ),
      istreambuf_iterator< char >(),
      back_inserter( self ) );
istreambuf_iterator是讀取輸入緩衝區的迭代器,使用copy演算法把內容一字不漏地複製進容器內。
接著要找分隔字了,這裡就要一點技巧:
string magic( "!_METAMAGIC__" );
magic[0] = '_';
不直接使用"__METAMAGIC__"是因為字面常數會被放到text區段,如此一來會被干擾識別字搜尋。
接著就可以愉快的使用STL找字串了:
list< char >::iterator result = search( self.begin(), self.end(), magic.begin(), magic.end() );
如果找不到就會回傳self.end(),這裡先假設它找得到,就直接寫入:
advance( result, magic.length() );
ofstream fout( "/tmp/injection", ios::binary );
if( fout.is_open() ) {
    copy( result, self.end(),
          ostreambuf_iterator< char >( fout ) );
    fout.close();
因為search回傳的是"__METAMAGIC__"字串的開頭,所以要用advance用來把迭代器往前推,讓它指向第二段檔案開頭。輸出檔放在/tmp下是因為這裡通常是任何人皆可使用。
list< char >().swap( self );
這行只是為了把list裡的空間釋放,對程式本身來說可有可無。如果啟動器本身會執行很久,那麼釋放不必要的部分也許比較好。
最後再執行它,就完成了:
system( "chmod a+x /tmp/injection && /tmp/injection && rm -f /tmp/injection" );
之後編譯它:
g++ -O3 -o sfx sfx.cpp
Do something evil--把二段程式黏起來:
echo -n '__METAMAGIC__' | cat sfx - start.sh > inject
之後執行inject就可以看到:
$ ./inject
Hello, world!
這種方式不免讓人聯想到某些病毒的入侵方式--在看似正常的檔案內插入攻擊代碼,利用自己製作的shell或其他程式[?]的bug,解出攻擊碼並執行。
當然這個啟動器是肥了點,因為完全只用C++內建的標準工具,惡意的啟動器通常都只有幾K而己。

2008年12月24日 星期三

第一張棄選單

KDE 4.2 snapshot packages for Debian

就像這篇所提到的,Debian因為龜毛政策沒辦法在官方套件庫中納入KDE 4.2的Beta套件,於是我們的神--Debian Qt/KDE Maintainers就自己開了一個非官方的套件庫,提供勇者們方便地嚐鮮KDE 4.2,以及bug回報。
這個套件庫事先聲明,期望不要太高,因為它們的品質並沒有符合官方的標準[?],更新週期大約是每週一次,不過這也不保證,反正他們有空就會更新。
用Debian到現在我大概可以理解為什麼有人說Debian對開發者很不客氣....光是看那堆打包者守則就快暈了,想要讓套件進unstable還要測試好一段時間,就連KDE 4.1.0也沒有完全進入unstable,而4.1.3還在experimental,搞不好就會直接被將來的4.2.0蓋掉,進不了unstable。
其實unstable+experimental就己經能夠滿足一般桌上使用的需要了,可想而知Debian對穩定的龜毛程度...

2008年12月18日 星期四

KomiX v0.0.1 released!

簡單的說是拿來看漫畫用的。
簡介:
  • 可開啟檔案或資料夾,支援直接拖放
  • 空白鍵或是滑鼠左鍵可平滑捲動
  • F11鍵或滑鼠中鍵可切換全螢幕
  • Esc鍵或點擊系統工具列圖示可隱藏,再點一次圖示可復原
  • 跳頁預覽
  • 提供「自由縮放」、「符合頁寬」、「符合頁高」、「符合視窗」等四種縮放模式
平台:
  • Linux
  • Windows XP / Windows Vista
編譯需求請參閱源碼內文件。
疑難排解:
Q1:提供的執行檔無法執行。
A1:請至Microsoft下載Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)並安裝。
Q2:為何沒有XX(Windows x64, FreeBSD, MacOS, ...)平台版本?
A2:請自行編譯。
Q3:圖示很醜。
A3:えぇ?それ、自信作だけど…

2008年12月11日 星期四

Uninstall using CMake

CMake基於某些理由並沒有在Makefile裡提供uninstall這個target,但是提出了另一個做法:把所有安裝的檔案路徑記錄到一個叫install_manifest.txt的檔案裡,之後利用xargs rm -vf < install_manifest.txt就可以反安裝了。
不過安裝時更改的設定檔要怎麼辦啊....

2008年12月5日 星期五

終於編好KDE4.2 trunk

昨天終於把KDE 4.2編好了,Oxygen的華麗度又往上翻了一級。Debian package有的bug消失了一些。不知道為什麼沒辦法自動切成scim-bridge。Kopete少了MSN支援。AmaroK還是一樣有點腳殘。K3B現身,雖然我還沒試過。無法使用桌面特效,不過倒是因此速度提昇不少:P。
書唸不完作業沒寫完的我到底在幹麻啊....

2008年12月3日 星期三

焦慮

幹!我好弱!真煩....

KDE 4.2 Beta1 well not appear in Experimental

總之,4.2 Beta1不會出現在Experimental裡,因為一放到裡面就會把4.1.3蓋掉,為了不把原本的穩定版蓋掉就要讓它進Unstable,但是Unstable要等到Testing釋出成為Stable後才會接受4.1.3,而Testing什麼時候變Stable?當它準備好的時候!= =