個人資料
歸檔
正文

數據恢複及破壞

(2018-09-12 18:42:48) 下一個

https://bbs.pediy.com/thread-165661.htm  

DiskGenius注冊算法簡析

MistHill 2013-3-13 20:09  97530
 
初次接觸DiskGenius已經成為遙遠的記憶,那個時候還隻有DOS版本。後來到Windows版,用它來處理過幾個找回丟失分區的案例,方便實用。到現在它的功能越來越強大,成為喜好啟動技術和桌麵支持人員的必備工具之一。

回想起好幾年前的一個案例,一個用了很久的老機器突然崩盤,磁盤引導部分物理損壞,無法啟動係統。一般的數據當然可以用DiskGenius等工具來恢複,但重點已經不在這裏了,因為大部分數據我有備份。
讓人焦慮的是我有一個EFS加密的文件和Outlook郵件偏偏就沒有備份。裏麵含有個人和公司全部軟件係統及服務器的帳戶、授權信息。進不了係統,就意味著我要和它們永久地說拜拜了,著實令人不寒而栗。
嚐試了很多數據恢複工具,包括Windows係統和其他係統的"NTFS/EFS Recovery"、"Raw Copy"等等,全都沒用。因為沒有數字證書,這個EFS文件等同於一堆垃圾字節,也沒辦法進入郵件帳戶。
交給專業的數據恢複公司又不放心,當然我沒有冠希同學那樣的秘密,要是他當初EFS一下,就不會招致那麽多的口水和對那麽多人的生活造成影響,嗬嗬。
後來自己終歸解決了這個問題,說穿了很簡單:在另一個係統裏構造一個和宕機的係統完全一樣的帳戶,至少我還記得用戶名和密碼。要點是保證新建帳戶和原帳戶的SID一致,這樣SAM裏的Hash就和原來的相同,係統通過SID將帳戶和文件的所有者對應起來。
在Windows係統中,得到了別人的這個Hash,就可以進入他的係統。曾在Marcus Murray的某個Microsoft TechEd演示"Knowing the Enemy - A lightning demonstration on how hackers attack networks"中看到,使用Hash將網絡中的一台機器作為跳板入侵另一台機器。這方麵還有大家熟知的Mark Russinovich。
得到的教訓是,雞蛋不能放在一個籃子裏:備份、備份還是備份;另外,EFS就真的那麽安全?真要用的話,請遵循“最佳實踐”:備份證書,並將其從係統中移除。

這個故事脫離了本主題,按下不表。事情的起因是前段時間的一個“事故”:小弟的小弟替員工重裝係統,拿錯了映像,造成其他分區數據丟失。這就要命,擱誰也誰也鬱悶,得幫人家恢複。
好久都沒幹這種事了,憑以往的經驗用DiskGenius和R-STUDIO,感覺DiskGenius更有效和準確一些。

DiskGenius分免費版和專業版。免費版是體驗用的,恢複文件時有64KB大小限製,搜索算法也相對簡單,和未注冊的專業版相同。由於有限製,基本上沒法用,要麽購買要麽“破解”。出於對逆向的偏好,加上對傳說中“暗樁”的好奇,決定玩一玩,也學習一下它的方法。
當然首先要找幾個“破解版”在虛擬機上試一下,發現隻有版本3.8那個是“真破解”,其他都是“偽破解”。甚至某“破解補丁”在內存中改程序的Title和About,難免被人批為大日本帝國的軍人——“自慰”隊員。很少有人提到激活文件Options.ini,見過的其中注冊碼也是錯誤的。

本文以目前最新的DiskGenius Pro 4.2.0.100為例,設想是不通過“破解”,而是弄清楚它的注冊算法,實現完美激活。亂套一下“不戰而屈人之兵”,是謂伐謀與攻心,乃最高境界。
先官樣文章地聲明一下,純技術探討,覺得軟件有用請購買。這裏不會暴露具體的細節,故命題為“簡析”,到是整個過程中一些好玩的東西可能更有趣。

一.注冊碼的奧秘
未注冊的專業版用戶界麵窗口標題會有“未注冊”字樣,“關於”對話框多一個“立即注冊”按鈕:
[LEFT]

點進去,出現“注冊DiskGenius”對話框,隨便填些東東,再點“立即激活”,提示“無效的注冊碼,請重新輸入。”。


非常友善,是不是。從這個對話框我們了解到,激活分網絡(在線/離線)和加密鎖兩種方式,另外輸入的注冊碼不符合它的要求,類似網頁提交前客戶端有一個初步的驗證。直截了當,就從此對話框的窗口過程入手,找到它的驗證算法,一探注冊碼的奧秘。
通過代碼分析得知,內部有一個簡單加密的Base36字符集,但不是標準序列、而是自定義的,最後4個字符是'01IO',從解碼算法證實:注冊碼實際上是Base32編碼,棄用了容易誤識的數字和字母,每5個字符一組、5組共25個字符,以'-'分隔。類似Microsoft的CDKEY或Product Key,不過MSFT用的是Base24,還棄用了易被誤認的'5AELNSUZ'。不會涉及橢圓曲線簽名算法吧?讓人望而生畏!有一點可以肯定,Hash(或者說Checksum bits)是有的,用於驗證注冊碼的有效性。

顯然,Base32比Base24表示的大整數要大很多,意味著我們選擇的餘地更大、相對容易一些。有了Base32字符集和校驗算法,我們就可以開始生成自己的注冊碼了。但是我不想抄那些反匯編代碼,換一種玩法:用HTML頁麵+瀏覽器作UI,Javascript作算法實現,隻需一個支持高亮和好用的文本編輯器,比如EmEditor就可以方便地設計界麵和修改程序進行調試了。
因為我有一個現成的來自About.com的"Password Generator"頁麵,稍加修改成為"regcode Generator"隨機生成注冊碼,再用校驗算法得到Hash。About的頁麵簡潔、美觀,Layout全部用DIV+CSS,不象其他大多數人用TABLE,記得以前有過DIV和TABLE的爭論。
Javascript和C++都是麵向Object的,Javascript具有C++沒有的"Regular Expressions",但兩者都沒有匯編指令ROR/ROL這樣簡單的運算符,兩條指令C++實現的例子可在Bruce Eckel的"Thinking in C++", Volume 1中找到。

但是注冊碼生成器中Javascript有兩個問題需要解決,大整數和無符號整數。
在Javascript裏,數字都用符合IEE754規範的64位雙精度浮點數表示。顯然注冊碼輕鬆地超過了64位限製,需要找一個簡單的Javascript庫處理"Big Number",可參考stanford.edu的"RSA and ECC in JavaScript"裏相關內容,但我們這裏不用整這麽複雜。
數據類型方麵,MSFT到"Internet Explorer 10"才在"Windows Runtime Types"中引入UInt8、Int32、Int64[-2^53, 2^53]和Uint64[0, 2^53]等等;Mozilla到是早就在ctypes裏支持Int64和UInt64。同樣不打算弄得這麽繁瑣,隻將必要的運算(左移位、加/帶位加、異或/或等)改寫,保證結果為UINT類型。
另外,數字需要經常在二進製、十進製和十六進製間轉換,Javascript的Number.toPrecision([precision])卻沒法用,精度不夠,得自己想辦法。IE嚴格遵循JScript文檔,precision超過21就報錯,而Firefox中將precision設到40時返回的還是近似數。
FF的Javascript性能表現遠遠超過IE,這在編碼大整數為Base32時能明顯感覺到。意料中的事,MSFT早已不滿足於將IE定位為單純的Browser,IE已然成為一個試圖一統天下的超級客戶端,以滿足服務器端產品的要求,同時和操作係統密不可分,十分地臃腫。

下圖為"regcode Generator for DiskGenius"的頁麵:


這部分很容易,先隨機生成注冊碼的前22位,再將16bits的Hash值編碼為Base32字符得到注冊碼的末3位。

二.激活請求發送了什麽
現在注冊碼是有效的了,試著激活。但這次是服務器回答“Error: 注冊碼無效!”,這裏可理解為:注冊碼仍然有問題、確實無效,或有效、但在它的數據庫中沒有記錄,還可能數據庫存在記錄、但其他字段不匹配。無論那種情況都不可能指望它返回有用的信息,也不好意思老去騷擾人家的服務器。
換個思路,轉而從處理返回結果的代碼著手。為方便和避免錯誤,我需要在本地啟用HTTP服務,將激活服務器的地址指向本地,進行模擬。程序需要什麽數據,就按要求響應它,讓我能一步一步走下去。

但再這之前,得搞清楚程序向激活服務器發送了些什麽數據,以幫助我們猜測和理解返回數據的構成。用Wireshark這類的工具記錄一下HTTP的Request和Response內容。
捕獲的數據簡單明了,它使用GET方法發送請求數據,URL中各字段依次為(在跟程序時也可觀察到):
1
2
3
4
5
6
7
ver=4.2.0.100
code=YH23U-R65WC-CKPA2-RN2JB-XENVZ
name=MistHill
email=misthill%40easycompany.com
mid=mOD_CDOcD^OFHLOHLHLL%1A%1A%1A%1A%1A%1CL%1C
appname=DiskGenius
diskinfo1=XCyo|kXg|z{obGJKFo|jJ|gxkQ>%3F>>>>>>>>>>>>>>>>>%3FQ:%3F7:%3D>:>

注意到:首先,傳遞的值一定要編碼為有效的URI(Uniform Resource Identifier)。其次,mid和diskinfo1的內容是加密的,其他字段的含義一目了然。
mid從字麵上理解意為機器碼,為三次CPUID指令的結果變化而成。
diskinfo1顯然代表磁盤信息,我在調試的機器上都隻掛了一塊硬盤,兩塊及以上的情況是不是還會發送diskinfo?,沒仔細查程序代碼,不能確認。
程序為找到的每一個磁盤都創建一個磁盤對象,共支持0x80個磁盤。對每個磁盤對象,調用兩次KERNEL32.DeviceIoControl。第一次取Geometry,第二次取ProductId和SerialNumber。
根據Geometry計算出磁盤的總扇區數,再加上ProductId(型號)和SerialNumber(序列號)得到diskinfo1的內容。

三.實現一個簡單的HTTP服務
前麵講到激活分網絡和加密鎖兩種方式。沒有加密鎖可以寫一個Driver來模擬,為使事情變得簡單,我選擇網絡方式。在本地如果有現成的IIS或Apache[Tomcat],可簡單地寫個頁麵來響應請求。
這裏我決定借用現成的模板寫一個APP來實現簡單的HTTP服務,我就不用在調試虛擬機上搞一大堆東西,也方便以後類似的工作。
可以找到很多類似的東西,但我希望盡可能簡單,並一定要有詳細的文檔。來自IBM的Nigel Griffiths有一篇"nweb: a tiny, safe Web server (static pages only)"就非常不錯,全部C源碼僅200行,支持靜態頁麵.html或.htm、圖像、壓縮文件。遺憾它需要UNIX係統,如Ubuntu、Fedora、OpenSUSE和Debian等。
我需要Windows環境的。MSFT的David Cook一篇"Write a Simple HTTP-based Server Using MFC and Windows Sockets"正是我要找的,文章發表於MSJ(Microsoft Systems Journal - MSDN的前身)February 1996。嗯…,這麽古老的東西?沒錯,就是它。越早越容易被奉為經典。
它的工程名稱為Webster,文章十分詳細,涵蓋HTML、HTTP、Sockets等,可設置Server的基本選項,高度可控;"MIME Data Types"可擴展;支持詳細的調試和日誌記錄;支持"System Tray"圖標;源碼注釋得也很好。
編譯連接後,先用Telnet測試一下:


啊哈,工作完全正常!現在我們可以使用自己的“激活服務器”了。但是激活時Webster服務器Hung在那裏,追查Bug:發現用於接收GET請求URI的Buffer太小,請求的URI字符串太長造成“緩衝區溢出”。
再來,這次沒問題了:


對工程Webster改了大概以下幾處:
a) HTTP/1.1協議支持,96年那時還隻有HTTP/0.9和HTTP/1.0。
b) URI緩衝區大小。
c) 由CScrollView派生的CWebView水平滾動條支持。
d) 由CPropertySheet派生的CWebProps各屬性標簽CPropertyPage裏Controls的字體。

四.完美激活
接下來,根據程序處理激活碼那部分代碼的分析,開始寫注冊機。因為要用到CPUID指令和API調用,用VC++來寫。


激活碼(Activation Key)實際上是對激活時提交信息進行變換、加密處理後的結果。這是激活服務器後台幹的事,程序解密激活碼後對那些信息逐一進行對比,沒有問題激活就成功了。
激活碼可視為一張證書,分好幾種類型。比如是否限製了特定版本,若無則通用證書適用於其他版本;還有試用證書,可指定過期日期。大概還有一種,決定硬件信息的比對來源,是加密鎖還是API,沒詳細看代碼,無法肯定。
圖中uncheck兩個Encrypted的Checkbox會顯示mid和diskinfo1各自的明文。
激活成功後,程序會寫激活文件Options.ini,用於重啟驗證;同時會複製一份到dos文件夾給DOS版使用。格式基本上是這樣子:
1
2
3
4
5
6
7
[license]
user = "MistHill"
email = "misthill@easycompany.com"
regcode = "YH23U-R65WC-CKPA2-RN2JB-XENVZ"
key = "9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA"
[LicenseInfo]
Show = "N"


這裏注冊碼(regcode)目前看來是“有效的”;激活碼(key)是我手工敲的,顯然無效,不能通過驗證。但已足夠讓程序去掉Title裏的“未注冊”字樣和“關於”對話框的“立即注冊”按鈕:


貌視已注冊成功,此為“暗樁”之一。

五.注冊碼兮,注冊碼
將key的內容改回注冊機(DiskGenius Keygen)裏"Activation Key"的內容,這下能通過重啟驗證,應該是“完美激活”了吧?
No, No, No..., Something wrong! 試圖恢複大於64KB的文件時失敗,錯誤類型表明還是“未注冊”!
看來還有玄機。重新審查激活碼驗證通過後的代碼,發現確實有調用對注冊碼再次進行驗證,當前這個regcode沒有通過!
在仔細研究了那段代碼後,我才恍然大悟,它還真是跟MSFT的CDKEY學來的,注冊碼由三部分組成:序列號(SerialNumber) + 簽名(Signature) + 校驗位(Hash)。簽名由序列號按簽名算法得到,校驗位為根據前兩部分計算出的結果。
同時也搞清楚了哪幾個關鍵標誌DWORDs的值應該是什麽才表明它是真正注冊成功了。
回到第一節的"regcode Generator for DiskGenius"頁麵,"Phase I"解決了Hash的問題,接下來"Phase II"解決簽名的問題。先隨機生成一個RegCode,得到序列號部分,根據它的逆算法得到簽名部分,最後計算校驗位部分。


這樣整個DiskGenius的注冊過程分為兩個步驟:1) 用HTML頁麵產生有效的注冊碼;2) 用注冊機生成激活碼。Webster隻是分析問題時的一個工具,不再需要了。
再試一試恢複大於64KB的文件,這次當然不會再有問題:



最後,感謝DiskGenius的作者,很好的工具,希望它更加強大!我從分析它代碼的過程中得到樂趣。
謝謝您閱讀此文!謬誤之處,請批評指正。

win10如何徹底清理電腦?

http://www.w10zj.com/Win10xy/Win10yh_7025.html  

Linux下Undelete

 

https://www.maketecheasier.com/recover-files-ext3-ext4-linux/ 
For example, I deleted a folder named /home/joe/mytest. 
To restore deleted files, the files partition mush be unmounted, or else as restore recreate files it will overwrite so only partial of them would be restored. If you have only one partition, get ready a Ubuntu live USB and boot from there click Try Ubuntu. 
To install s/w on Ubuntu live, each time you need manuall choose “software & Updates” and check the button of “Community...(universe)” then close. 
$ sudo apt-get undate 
$ sudo apt-get install ext4magic 
$ sudo fdisk –l 
Device     Boot     Start       End   Sectors   Size Id Type 
/dev/sda1  *         2048   1126399   1124352   549M  7 HPFS/NTFS/exFAT 
/dev/sda2         1126400 217266175 216139776 103.1G  7 HPFS/NTFS/exFAT 
/dev/sda3       217268222 468860927 251592706   120G  5 Extended 
/dev/sda5       217268224 466862079 249593856   119G 83 Linux 
/dev/sda6       466864128 468860927   1996800   975M 82 Linux swap / Solaris 
Live USB is now sdb1. /dev/sda3 is a MS Windows partition, so /home/joe is in /dev/sda5 
$ sudo ext4magic /dev/sda5 -a $(date -d "-3hours" +%s) -f /home/amcclab/mytest -l 
Filesystem in use: /dev/sda5 
Using  internal Journal at Inode 8 
Activ Time after  : Thu Dec 20 16:11:47 2018 
Activ Time before : Thu Dec 20 19:11:47 2018 
Inode found "/home/amcclab/mytest"   917869  
  100%     /home/amcclab/mytest/S4/sensor_parsing.sh  
… 
$ sudo ext4magic /dev/sda5 -f /home/amcclab/mytest -r -d recovered 
"recovered"  accept for recoverdir 
Filesystem in use: /dev/sda5 
Using  internal Journal at Inode 8 
Inode found "/home/amcclab/mytest"   917869  
--------    recovered/home/amcclab/mytest/S4/sensor_parsing.sh 
...... 
ext4magic : EXIT_SUCCESS 
ubuntu@ubuntu:~$ sudo chown -R ubuntu:ubuntu recovered 
ubuntu@ubuntu:~$ ls recovered/home/amcclab/mytest/ 
S22  S3  S4 

The limitation is the recovered files are on live disk and after reboot, files and installed ext4magic are disappear. You had better have a separate large enough partition – not same partition of deleted files, or copy the recovered files to original partition if you are sure all are restored correctly. 
If you click install on live USB then something else and choose another USB say sdc, click + to add partition as 472M-ext4-/boot,1022M-swap,rest as ext4-/ and install, you will get a OS on USB. 
** 
Following example has /dev/sda2 that can be used to restore files in /dev/sda1: 
[amcclab@s01 scripts]$ sudo fdisk -l  
Disk /dev/sda: 1000.2 GB, 1000204886016 bytes 
255 heads, 63 sectors/track, 121601 cylinders 
Units = cylinders of 16065 * 512 = 8225280 bytes 
Sector size (logical/physical): 512 bytes / 4096 bytes 
I/O size (minimum/optimal): 4096 bytes / 4096 bytes 
Disk identifier: 0x000bf394 
   Device Boot      Start         End      Blocks   Id  System 
/dev/sda1   *           1        2040    16384000   83  Linux 
/dev/sda2            2040        2550     4096000   83  Linux 
/dev/sda3            2550        2678     1024000   82  Linux swap / Solaris 
/dev/sda4            2678      121602   955257560    5  Extended 
/dev/sda5            2678      121602   955255808   83  Linux 
[amcclab@s01 scripts]$ df 
Filesystem     1K-blocks      Used Available Use% Mounted on 
/dev/sda1       16126920   6932128   8375592  46% / 
tmpfs            1993260         8   1993252   1% /dev/shm 
/dev/sda5      940265216 789078016 103424412  89% /state/partition1 
/dev/sda2        4031680    514172   3312708  14% /var 
tmpfs             973276     60800    912476   7% /var/lib/ganglia/rrds 
[amcclab@s01 board_sampling]$ du -sh 4_08_17-val/ 
1.5G    4_08_17-val/ 
/home/amcclab/test/skylark/soldered_board/board_sampling/4_08_20-val 
sudo ext4magic /dev/sda5 -a $(date -d "-30hours" +%s) -f /home/amcclab/test/skylark/soldered_board/board_sampling/4_08_20-val -l 
Filesystem in use: /dev/sda5 
Using  internal Journal at Inode 8 
Activ Time after  : Wed Dec 19 09:21:58 2018 
Activ Time before : Thu Dec 20 15:21:58 2018 
Inode found "/home/amcclab/test/skylark/soldered_board/board_sampling/4_08_20-val"   19906565  
Inode 19906565 is allocated 
ext4magic : EXIT_SUCCESS 
amcclab@E6400SSD-1:~$ sudo ext4magic /dev/sda5 -f /home/amcclab/test/skylark/soldered_board/board_sampling/4_08_20-val -r -d recovered 
"recovered"  accept for recoverdir 
Filesystem in use: /dev/sda5 
Using  internal Journal at Inode 8 
Inode found "/home/amcclab/test/skylark/soldered_board/board_sampling/4_08_20-val"   19906565  
Inode 19906565 is allocated 
ext4magic : EXIT_SUCCESS 

This time actually failed as restored folder is empty, now time to try sub-folder name.

 

[ 打印 ]
閱讀 ()評論 (0)
評論
目前還沒有任何評論
登錄後才可評論.