2007年8月17日 星期五

One Day Off

西元 2007 年 8 月 17 日 颱風天

這幾天天氣相當的不穩定,小弟連續磕了幾天的普拿疼後,昨天一整天完全沒有工作情緒,今天終於決定不去上班了。
只想好好的睡一覺。好好的放鬆一下。

睡到了十點,恣意的發呆了一下,頭也比較不痛了。
下午到家附近學生時期常去的水餃店吃了中餐,好久沒去那家店了,沒想到老闆還跑來和我聊了一下天,他們以為我搬家了 :P

吃完中餐,發了點小瘋,突然想回台大看看。也就去了。台大多出了許多建築物,舟山路也變成學校的一部分。

颱風越來越大,一個人在校園裏漫遊。回想起那一段刻骨銘心的感情。埸景依舊,兩人依偎的身影卻只在回憶之中。

到新總圖,四樓左側最後面坐了下來。暑假期間,沒什麼人。這是我大學最喜歡的位子,離我喜歡的書很近。大學時,有數不盡的時光泡在這裏。一個人靜靜的慢慢回味。

我很喜歡坐在這裏,人生中有許多重大的決定,很多新的想法,讀出心得,感受出知識的威力都在這裏發生。

畢業多年,回到這裏,也是在思考人生的走向,我們在這時代,我們背負的責任。我是否對得起多年前坐在這心中充滿理想的小子。

回到系館教室,獨自一人坐在裏頭。這是我大學時代最後一次考試的教室。也是在這間教室之中,我聽到一位老師說: Java 的 try catch 改善了過去 C 語言中例外處理的弱勢,這是一個新發明,是專家們深入研究程式語言後的發明。而未來做這件事的人,就是在座的各位。

是的,也許我要更加的努力。

2007年8月13日 星期一

毀壞 Partition 之 Office 2003 Word 救援

身為一名軟體工程師,常常會被親戚朋友問一堆怪怪的電腦問題。
昨天就收到了兩個壞掉的隨身碟。一個 512 MB 另一個 1G 。
它們的 MBR 和 superblock 都被病毒給毀了

可是裏面的 Doc 檔又特別重要… ~_~

身為一個好人,為了未來的幸福…當然義不容辭一定要把它們救回來嘍


以下是我的救援 steps
1. 把 flash 插入可愛的 Linux 機器中。
"dmesg" check 一下是否硬體壞掉。
硬體 OK 但沒有 partition info
2. 用 "fdisk /dev/sda" check MBR
ok 真的爛了 @_@
3. 用 dd if=/dev/sda of=honey_512M.img 備份下來

4. check 資料是否完全爛掉,還好,data 還在

因為苦主說明 word 檔很重要~~ 所以就專攻 word 檔嘍
苦主用的是 office 2003,因此小弟就找了幾個 office 2003 的 word check 了一下檔頭檔尾

Good Luck!!
發現大多數的 word 檔檔頭是以 D0 CF 11 E0 A1 B1 1A E1 開頭
以 6F 63 75 6D 65 6E 74 2E 38 00 F4 39 B2 71 結尾
因此先用 hexdump + head + tail 剪一個出來驗證
驗證 OK !!

5. 隨手寫一支小小的程式把這個區段的 word 檔給一個個 copy 出來
雖然不是所有資料都救回來了,但最重要的救回來了就好了 ^_^

6. ./recover honey_512M.img

這個方法可以 recover 回文字量少(小檔案),沒有使用 macro 的doc 檔
如果檔案較大,大於 block size 那就比較麻煩了,就要去讀file system 的資料
幸運的是,絕大多數的檔案都是小檔案。
如果檔案中有圖片,就很可能變成圖片壞了,文字還是救得回來。

以下是小程式的 source Code:

Filename: recover.c
Composer: Tick
License: GPL

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const int PREFIX[] = {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1};
const int SURFIX[] = {0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, 0x38, 0x00, 0xF4, 0x39, 0xB2, 0x71};

void showExit (char *arg) {
printf("This program is used to recover MS office files from broken image\n");
printf("Usage: %s <image file>\n",arg);
}

void recordFile(FILE *foo,char *file,int start,int end) {
FILE *fp=NULL;
if (!foo || !file || strlen(file)==0) {
printf("Invalid file to record (%d,%d)\n",start,end);
return;
}
fp = fopen(file,"w");
if (fp == NULL) {
printf("open record file %s failed!!\n",file);
return;
}
fseek(foo,start,SEEK_SET);
while (ftell(foo) < end) {
fputc(fgetc(foo),fp);
}
fclose(fp);
}


void scanFile(FILE * foo) {
int c;
int index=0,index_e=0;
int start=0,end=0;
int fid=1;
char buf[256];
while (!feof(foo)) {
c = fgetc(foo);
// printf("get 0x%02x at %d PREFIX[%d]=0x%02x\n", c, (int)ftell(foo),index,PREFIX[index]);
if (c==PREFIX[index]) {
index++;
}else {
index=0;
}
if(index==(sizeof(PREFIX)/sizeof(PREFIX[0]))) {
printf("Get PREFIX at %d index = %d\n",(int)ftell(foo)-index, index);
start=(int)ftell(foo)-index;
index=0;
}

if (start!=0) {
if (c==SURFIX[index_e]) {
index_e++;
}else {
index_e=0;
}
if (index_e==(sizeof(SURFIX)/sizeof(SURFIX[0]))) {
end=(int)ftell(foo);
printf(" File starts at %d end at %d size %d bytes\n",start,end,end-start);
sprintf(buf,"%04d.doc",fid++);
recordFile(foo,buf,start,end);
start=0;
index_e=0;
}
}
}
}

int main (int args,char **argv) {
FILE *foo;
if(args == 1 ) {
showExit(argv[0]);
return 0;
}
foo = fopen(argv[1],"r");
if (!foo) {
printf("Open File %s failed!!\n",argv[1]);
return 0;
}
printf("Open File OK!!\n");

scanFile(foo);

fclose(foo);
}