硬體加密狗的解密過程[轉帖]
作者:qdcrack
轉載:大老
工具:trw2000,uedit
目標軟體:vt4.0(一種醫藥用影像分析軟體)
加密方式:外加密
用trw2000開啟應用程式,首先進入的是novex32.dll,這個動態連線檔案的用處我們很快就知道了.整段程式碼只呼叫了一個子程式,而跳過它的時候會出現要你插狗的提示框,說明novex32的作用就是對狗進行操作.到目前為止一切良好,似乎勝利在望.那麼我們跳過這個子程式不執行,會有什麼後果?試一試,程式執行到noverx32的最後一條指令ret。一個跳轉,來到一片陌生的區域,於是很快就出錯了,很明顯,不能直接跳過去。什麼原因?經過查閱相關技術資料,發現加密狗的外加密方式不止是檢查狗這麼簡單。(還有內加密方式,就是在原始碼中隨機加入對狗的操作,那樣的話只能透過虛擬並口技術實現解密。)實際上,在加密時,原應用程式已經被完全打亂並且被修改,只有讀取相應狗內資料,經過相應演算法恢復後才能正常執行。有的同行就會恍然大悟,說:“那麼就插狗執行到程式入口,再用pedit把記憶體映像dump出來,就可以了(一定會有人這樣想,我當時就是這樣做的)“但是不行,因為在倒出記憶體的時候,倒出來的是跟初始時完全不同的記憶體資料,而由於novex32要對其中的一些資料作操作,用倒出後的記憶體資料來操作的話,就會引起很多無法預料的錯誤,(而且在novex32中也作了很多應用程式的初始化操作,如顯示載入相關動態連線庫之類,所以不能直接跳到dump出的程式入口)由於無法判斷那些地址的資料是要被用到的,(當然,如果你願意仔細的讀他的程式碼,完全的理解他的執行過程,那麼也可以找出那些地址的資料將被使用,不過那太。。。。。累了)唯一的辦法:跟進該子程式去大致看一下。
進來了,**!我當時大吃一驚!這就是他所謂的反跟蹤迷宮技術:在每2條指令之間。都插入了若干指令有比較溫和的:
jmp #########
或者 jmp ######## ------〉jmp ##########
還有小花招的
push ##########
ret
最過分的是:
push ########
push eax
push ebx
pushf
push
ebp
mov ebp,esp
add dword[ebp+10],####
pop ebp
popf
pop
ebx
pop eax
ret
你說過不過分?這麼大一段就是一條跳轉,剛開始還害我捉摸半天,尤其是那個pushf太嚇人了呵呵
就在跟這些跳轉語句的搏鬥中,我找到了跟狗相關的子程式,仔細研讀後,發現他會從狗讀
出若干資料到一個固定的記憶體區域,這樣的讀寫重複4次,每次資料都不同。不知道trw2000怎麼讀出固定記憶體地址的若干內容儲存到檔案中(debug比較簡單),就在記憶體空白的地址裡面添了幾行程式碼,讀完狗之後就執行這些程式碼,作用是把該記憶體區域的相關資料都存進一個檔案,存4次。再修改這幾條程式碼,每次要讀狗時都不執行原來的函式,而執行我的程式碼,作用是把相應的位置的資料從檔案再映像到該記憶體區域,這樣的話,就可以正常透過這一關了。本來以為結束了,結果繼續執行下去,在原程式被重組並接管控制後,居然還要檢查狗在不在,原來他有兩道關口!跟進去你會發現,這次的關口守的並不緊,只是一個判斷而已,只要直接跳到正確的序列就可以了。通常的辦法是把jz改成jmp
short,但是怎麼改?因為原檔案是被打亂修改過的,74(jz)這個程式碼很有可能變成15或是別的什麼東東無法在檔案中找到並修改,就算找到了,改成什麼好?eb(jmp
short)?不行,因為在重組的時候會再修改一次,這樣就不知道是什麼樣的了。看來只能在記憶體中修改,就是在執行過程中。我嘗試在執行過程中添入程式碼,但是執行時報錯,說我要寫的記憶體地址被保護了,不能修改!媽的,那novex32那個混蛋又是怎麼改的呢?我猛然想到會不會使用了virtualprotect?下一個斷點,果然!那個混蛋用了這一招,我於是在它的被授權程式碼段中插入了跳轉指令(反正他到處都是跳轉,我只要改下地址就可以了)跳到我的修改記憶體的程式碼處,執行完了再跳回去,於是很成功的,正常執行了!
可是快樂並沒有持續很長時間,vt裡除了vt4。0這個可執行檔案外,還有一個關於資料庫的可執行檔案album,本來正常執行時,開啟vt4。0時可以點選他視窗“open
database”按鈕來開啟album,但是在我解開的vt4中那個按鈕居然是disable狀態!只有在開啟album看一下,果然,他也使用了novex32!(賤人!我罵道。)這個時候問題就出來了,先不管vt4呼叫album的問題,看一看如果他單獨執行會怎樣。都是使用novex32,如果不考慮在vt裡調album情況(因為novex32已載入了,所以這時的絕對地址不會變化),在單獨執行album時,由於基地址不同,我新增的程式碼段就不能被正常執行,因為我是對絕對地址進行訪問。於是急忙再回去,想辦法找到一個可以做參照的東西來算相對地址,可是慘就慘在相應的對映要作4次,(還記得嗎?呼叫deviceiocontrol的函式(以後簡稱:XXXX的子程式,因為他實在是很大。)被調了4次,而我新增的程式碼就在他裡面)每一次的所有暫存器值都會變化,只有堆疊指標倒是不變,可是兩個程式的堆疊指標到我所訪問的地址偏移量不一樣,很難找到一個不變的數值來作基準。靈光一現!堆疊裡會不會有好東西?果然,在某一個固定棧偏移儲存有一個很重要的資料(好像就是程式載入的基地址),可以用他定位所有的地址了!這樣用相對地址,應該不會出錯了吧?沒想到還是不能單獨的執行album,我仔細檢查了記憶體,發現原來album讀出的資料跟vt4從狗裡讀出的完全不同,只有為它也存一份映像檔案。因為我不想改變可執行檔案,
我的所有改動都是在novex32裡面,不可避免的情況就是,這兩份不同的映像檔案不得不取同樣的名字,還好兩個可執行檔案不在同一個子目錄下,這樣可以把這兩個同名的檔案分別放在各自的目錄下,這樣兩個檔案都能單獨執行了。雖然解決了問題,但是很不痛快。
單獨執行解決了,是該解決vt4調album了,這個時候我卻發現了一個令人沮喪的事情,好像我解除來的檔案在nt下不能正常執行,原來本來是可以的(插狗)。於是我打算先看一下到底nt下是怎麼回事。很明顯,由於nt嚴格的記憶體保護,幾乎我自己新增的程式碼對記憶體的訪問都被報錯,而我又四處下不到nt下的偵錯程式,於是只好在98下分析。看來我要重新看待這個問題了。儘量的減少對記憶體的操作。但是無論我如何減少對記憶體的操作,nt好像都不領情,還是報錯,我覺得要崩潰了,於是放下這東西,休息了幾天(這個我覺得很重要,千萬不要拼命,我覺得那才沒用。)2天后來重操舊業,仔細檢查記憶體後發現一個極重要的情況,好像插狗與不插狗,執行完4次XXXX的子程式後,整個記憶體區域內容沒有什麼變化,這與我原先想的真是大相徑庭(我本來認為讀狗並經過一系列計算後的結果應該體現在記憶體某區域已備後用)我先檢檢視結果是不是反映在暫存器值裡,發現暫存器值很快就被修改,沒有被使用,可見很有可能是在堆疊中,一看,果然堆疊一個地址有個雙字資料,如果沒狗執行完後是0,有狗就是另一個值,我試著不插狗,只在執行完XXXX的子程式後修改該堆疊資料,果然執行正常(第一關)我欣喜若狂,一面也罵自己笨,早一點找到不就什麼事都沒有了?現在好了,nt再厲害,不能不讓人訪問堆疊吧?我什麼訪存程式碼也不加,只是做push
pop操作,很快的,在新的修改方案下,vt4透過了,可是album卻執行不了了,很正常嘛,album的該地址資料一定跟vt4不同,資料記憶體映像都不一樣嘛!可是現在面臨的問題是:由於我只修改novex32,所以需要判斷現在執行的執行緒到底是屬於album還是vt4,這就不可避免要涉及訪存。我把兩個可執行檔案查詢了一遍,在絕對可讀的記憶體區域裡找到了一個可以用作區別的資料,這樣就簡單了,第一關很快記過了,而album好像沒有設定第二關,所以現在他就可以直接執行了。
現在來看vt4。還剩第二關,因為第二關的解決辦法是直接修改記憶體,所以有兩點壞處。一是:有可能遭遇nt的記憶體保護;二:因為novex32是共用的,所以在這裡還要加入判斷,以免修改了album的不需要修改的資料。怎麼辦呢?我決定搞明白重組的演算法。我讓trw2000顯示要修改的那個記憶體區域,初始化時該區域是不可知的。我執行到重組的子程式,然後逐漸跟進,發現ebx存放了要重組的資料的地址,而eax存放了一個重組是要用到的數。整個重組程式應該就是用原來的那個種子數(堆疊裡我們加進去的那個。)透過一系列計算
算出一個數值,放進eax,然後執行“xor [ebx],eax”(推測,也沒有仔細讀原始碼,不過應該是這樣。)這就是恢復的機制了。我找到原來的“亂碼”是11,對應的al是65,異或之後,正好是74。現在有兩個選擇。一是改原檔案,11改8e(8e異或65為eb(jmp
short))而是改novex32,把al改成 fa。當然選後者,所以插入2小段程式碼。再異或之前,跳到第一段,作用是檢查當ebx為要修改的地址時,則改al的值,然後跳回來執行異或(不是就直接跳回)異或完後,再跳到第二段,檢查ebx,若是則把al改回來,然後跳回繼續,不是則直接跳回。這樣就完全沒有訪存,而且因為兩個可執行檔案地址不同,在album中
ebx不會有上述的那個地址值,所以不存在衝突。
到這裡,才算是功德圓滿。在windows平臺上暢通無阻,而且由於只涉及1次訪存,且使用相對地址,所以兩個可執行程式也不會發生衝突,終於成功了。