也談寫OllyScript指令碼之Career和心聲

看雪資料發表於2004-09-25

也談寫OllyScript指令碼之Career(for 0.92)

現在喜歡用Ollydbg的人相信比較多……

    近來,喜歡上寫OllyScript指令碼,又愛又恨。指令碼寫得比較爛和慢,原因是彙編命令沒認識幾個,邏輯思維差,不過認識的還能在OllyScript指令碼找到,OllyScript是那麼讓人和愛可親,卻又是(一般地說)比較難靈活運用,執行還欠些好的透明度。個人認為,指令碼和我們寫程式(我可沒寫過真正的程式)一樣,先是你有了主題(target:目標),然後用你認為可行的方式進行組織“框架”,(用OS的“法規”)填飽草圖,一番瀟灑的“文筆”(寫命令)後,馬上就要進入天堂和地獄的測試考驗。如果你是“算死草”--邏輯思維很強的老手,多數直接奔向天堂;但地獄又經常向我等傻瓜招手,屢屢折磨我們。

以下是我寫指令碼的 Career 和心聲(還很爛):

1.注意變數的宣告,最好寫在一起宣告(在開頭,同在一個指令碼里的都是全域性的了),以便報錯時,能快速查詢(雖然指令碼有報錯行,但我相信你不想去拉捲軸)

2.弄清變數的真正含義(宣告後在賦值後才能確定,有字元、16進位制數值串、32位地址或數值):
for example:
var addr
mov addr,[esp+10]//不支援間接計算,這樣指令碼不會報錯,但你一執行就知利害

var addr
var code
mov addr,401000 //缺少這行賦值,addr是0,會帶來非法操作
mov addr,#9876543210ABCDEF# // 這條本是想存放16進位制串到addr,應該這樣 mov [addr],#9876543210ABCDEF# ,且addr應是個有效地址

3.注意命令作用的變更:
find類命令應該用得比較多吧
for example:
find eip,#ABCDEF# // 0.85版是從eip所在的記憶體塊image地址開始搜尋
      //0.92版是從eip所指地址開始搜尋
findop //此命令,是查詢真正的命令--一眼就能看到的,如你要找的命令附近有花指令的,使用是找不到的。

4.儘量寫成模組功能(精簡為上),以便寫註釋、移植、(用#inc命令)組裝和查詢錯誤(第1個執行的指令碼定義的變數是全域性的,它到第2、3..指令碼有效,全域性變數值改變後可返回到上一指令碼,與全域性變數同名變數重新宣告無效),包含指令碼方面的作用我還在糊塗中。
for example:
//下面的功能簡單:不難看出是交換a、b兩個數
var a
var b
var c

mov a,12
mov b,10
mov c,a
mov a,b
mov b,c
log a //記錄交換後的結果
log b
ret

遺憾的是大家都比較少寫模組功能指令碼,缺乏加強交流測試認證(可能功能細小,大家怕寫了沒人理會),只想寫一氣呵成、一起包辦的專門版本指令碼(開始我都認為該這樣寫)--有的顯得相當長篇,難以理解,方法各有特點,一般只有作者本人可以讀懂,這樣長讓作者寫註釋都要瞄來瞄去,心情欠佳(比如:對付某版本某加殼,作者都希望指令碼簡短,可多數事與願為)就不起勁;模組化(一定的功能)可能還未被人重視的原故吧,我個人覺得應該多向這方面考慮出發寫一下,好比C語言,就是個大家都普遍瞭解的例子,模組化一些功能--貴精求精,使之標準化==Public,容易移植,往後,我們要寫起指令碼來就輕鬆得多,因為功能已經得到測試認可,只需利用在其模組上修改一些變數或引數等,用#inc或貼上在適當位置作連線就可事半功倍....

5.在迴圈設計和判斷方面上,應該多考慮錯誤發生的可能性,除錯或執行時可在其中放入pause和log somthing 或step以便監察執行當中的閃失漏洞。比如:我所遇到過的某變數a是的地址變數,在迴圈中突然變成了0,如果它是參與地址訪問,哈哈,後果...

6.認真檢查變數物件的名稱是否誤寫了,比如:esp寫成了ebp,執行的話,指令碼是無法為你檢出錯誤的,因為這些是不需要宣告的。

7.我不是程式設計師,也不是專家,僅是a boy,所說的都是錯誤中的心聲,希望大家都來分享你自己的指令碼“心聲”,多多少少總會有的,不管它是喜與憂,是不懂還是半懂,只有加強交流和實踐,指令碼編寫方面總會取得一定的成果的。大家很少談寫指令碼的心得,猜測原因大概是寫指令碼的一般都不是真正的程式設計師(程式設計師引以為傲的是自己能寫程式搞頂吧)或者認為提出要談論的就一定是高手,然而你寫出的功能指令碼也有可能是不太實用或實際的,但我認為你願意跟別人交流已經很不錯了--即使那是事實。寫指令碼比較花時間(有時一個指令碼花上好幾天,主要是除錯)--首先你要取得除錯方面的收穫,然後又要花盡腦汁去描繪指令碼,測試,除錯修復,再測試……直到成功,寫完後釋出,又要經歷同樣的測試,不難想象,他們(包括我)害羞、沒空、希望交流又沒人組織和提供交流的固定地點……我可是那一類不想做組織和leader的傢伙,當然自己也沒什麼本事嘛!希望有位中國同志站出來...呵呵,鼓掌中……推舉一下loveboom怎麼樣………

last:
我也有寫指令碼的問題,好些命令也沒機會實踐:
象是 0.92的<EXECute/END>對當前除錯程式,執行在EXEC和ENDE之間的指令。
exec
push 0
call ExitProcess
ret
ende

我沒有執行成功,理解能力差吧,也不知它如何使其能夠執行,call ExitProcess 這個OS能理解翻譯嗎?還有的是call函式一般都要用到控制程式碼引數等,這個命令的執行缺乏透明度,裡面幹了什麼不得而知,有朋友可告知其運用的例項嗎?

呵呵,看完了,我可不是練打字呀,希望能大家發動互相交流。如果指令碼寫得好的話,會有一些驚喜的亮點,很多Ollydbg的其它外掛都可以隱居山林了呀……

順便來一個指令碼(不知如何):

//  抵達aspr首次堆疊出現硬碟指紋

//作用:如題,方便大家在aspr定位,比如填寫註冊資訊或什麼!歡迎大家測試反饋!
var drc
var test
var zero
var count
mov count,0

dbh
eob break

loop:
esto
inc count
mov drc,esp
add drc,28
mov zero,drc
sub zero,4
mov zero,[zero]
mov drc,[drc]
cmp zero,0
jne loop
cmp drc,0
je loop
mov test,drc
and test,FF000000
cmp test,0
jne loop

final:
log eip
log drc
sub drc,4
cmp [drc],0C
jne loop
log "下面count是使用指令碼以來的異常統計:"
log count
cmt eip,"祝賀,你成功抵達首次堆疊出現硬碟指紋的異常!"
ret

break:
msgyn "現在指令碼發現不明的斷點中斷,請選擇是否繼續Pass異常?Y/N"
cmp $RESULT,0
je end
jmp loop

end:
msg "你選擇了結束指令碼,Bye Bye!"
ret

相關文章