幾行我已經在OllyDbg中發現裝配的這幾行:幫助破譯裝配
MOV ECX,DWORD PTR DS:[xxxxxxxx] ; xxxxxxxx is an address
MOV EDX,DWORD PTR DS:[ECX]
MOV EAX,DWORD PTR DS:[EDX+116]
CALL EAX
可能有人步,告訴我這裏發生了什麼?
幾行我已經在OllyDbg中發現裝配的這幾行:幫助破譯裝配
MOV ECX,DWORD PTR DS:[xxxxxxxx] ; xxxxxxxx is an address
MOV EDX,DWORD PTR DS:[ECX]
MOV EAX,DWORD PTR DS:[EDX+116]
CALL EAX
可能有人步,告訴我這裏發生了什麼?
這是存儲在結構中的函數指針的調用。
該第一行獲取存儲在地址DS:xxxxxxxx
處的指針。方括號表示取消引用的地址,非常類似於C中的*
。內存中的值即將用作指針;它被放入ecx
寄存器。
MOV ECX,DWORD PTR DS:[xxxxxxxx] ; xxxxxxxx is an address
第二行提領上面得到的指針。現在將ecx
中的值用作地址,該地址被解除引用。內存中找到的值是另一個指針。這第二個指針被放入edx
寄存器。
MOV EDX,DWORD PTR DS:[ECX]
第三行再次解除引用內存;這次訪問發生在地址爲的偏移量上面從0x116字節獲得的指針上。這不能被4整除,所以這個函數指針看起來不是來自C++的vtable。從存儲器獲得的值是這次存儲在寄存器eax
中。
MOV EAX,DWORD PTR DS:[EDX+116]
最後,執行eax
指向的功能。這只是通過函數指針調用函數。該函數似乎取零參數,但我有一個關於修改我的答案的問題:在此片段之前是否有PUSH
指令?這些將是函數的參數。問號表明這個函數可能會返回一個值,我們不能從我們的優勢中看出來。
CALL EAX
總體而言,代碼片段看起來像一個擴展功能,從插件庫OllyDbg的調用。 OllyDbg ABI指定了包含一些函數指針的各種struct
。還有一些函數指針的數組,但是到達edx
的指針(也是未對齊的偶數倍的偏移量)的雙重間接使我認爲這是一個struct
而不是一個函數指針數組或者一個C++類的vtable。
換句話說,xxxxxxxx
是指向包含函數指針的struct
的指針。
在OllyDbg源文件中,PlugIn.h是一些候選struct
的定義。這裏有一個例子:
typedef struct t_sorted { // Descriptor of sorted table
char name[MAX_PATH]; // Name of table, as appears in error
int n; // Actual number of entries
int nmax; // Maximal number of entries
int selected; // Index of selected entry or -1
ulong seladdr; // Base address of selected entry
int itemsize; // Size of single entry
ulong version; // Unique version of table
void *data; // Entries, sorted by address
SORTFUNC *sortfunc; // Function which sorts data or NULL
DESTFUNC *destfunc; // Destructor function or NULL
int sort; // Sorting criterium (column)
int sorted; // Whether indexes are sorted
int *index; // Indexes, sorted by criterium
int suppresserr; // Suppress multiple overflow errors
} t_sorted;
這些例子允許爲NULL
,和你的彙編代碼段不檢查的函數指針NULL
指針。因此,它必須是來自t_table
的DRAWFUNC
或t_dump
的SPECFUNC
。
您可以創建一個包含頭文件的小項目,並使用printf()
和offsetof()
來確定其中的任一個是否在0x116的偏移處。
否則,我想像OllyDbg的內部是用同樣的風格寫的。所以在OllyDbg中可能會有私人的struct
定義(未在Plugin.h文件中發佈)用於各種目的。
我想補充一點,我認爲這是一個遺憾,OllyDbg來源不可用。我當時的印象是,它所包含的靜態鏈接反彙編工具正處於某種「GPL許可證」下,但我一直沒有得到OllyDbg的消息。
+1比我的更好的描述。 :-) – Pretzel 2010-08-10 20:39:32
「這可能是一個調用......」會更精確,不是?你不知道它到底是什麼。 – x0n 2010-08-10 20:57:02
@ x0n。不,我認爲我有一個很好的想法是什麼。我有OllyDbg的一些經驗。例如,我絕對沒有寫過「OllyDbg可能是用一種不確定的高級語言寫成的」。它是用MSVC 2005編譯的,我擁有該領域特定的知識。當然,這個代碼片段可能是內聯彙編,但是寫了一個OllyDbg插件或三個OllyDbg插件主機測試工具...我想我知道它是什麼。 XOFF。 – 2010-08-10 21:01:02
它已經一段時間,因爲我做了ASM(1997年),甚至當時我只是在做I386 ASM所以原諒我,如果我的回答是不是所有的有用......
不幸的是,這4行代碼唐對我說的不多。它主要是將東西加載到CPU寄存器並調用函數。
具體來說,它看起來像數據或指針正在從該地址加載到您的CX寄存器。然後將該值從CX複製到DX。所以你有位於DX的CX指針的值。那麼DX中的值加上116的偏移量將被複制到AX寄存器中(您的累加器?)
然後,無論位於複製到AX中的地址處的函數是否正在執行。
把地址爲xxxxxxx的32位數字放到ECX寄存器中,然後用這個數值作爲地址並讀取數值並把它放入EDX寄存器,最後在這個數字上加116,並讀取該數值地址到EAX。然後它開始執行現在在EAX中保存的地址的代碼。當代碼遇到返回操作碼時,執行將在調用指令後繼續。
這是非常基本的程序集。它使我懷疑你正在用調試器做什麼以及你的任務是否到期;-)
我正在通過調試東西來學習程序集,所以毫不奇怪它是基本的。我已經掌握了它做了什麼,但是我沒有在「MOV ECX,DWORD PTR [地址]」,然後是「MOV EDX,DWORD PTR [ECX]」中看到一點,所以我認爲它可能會做一些不明顯的事情。 因此無論如何,這是否意味着xxxxxxxx是指向函數的指針,還是指向函數指針的指針? – Iron 2010-08-10 20:34:23
除了意思之外,它並不意味着什麼。你不能推斷那裏有一個「功能」,或者即使函數作爲一個概念存在於任何高級語言編譯過程中(或者即使涉及更高級的語言,tbh也是如此)。爲了逆向工程這個代碼,你需要對生成它的編譯器有深入的瞭解。 – x0n 2010-08-10 20:36:17
我知道這是MSVC++,可能是2005年。 – Iron 2010-08-10 20:38:34
我99%確定這是一個虛擬的方法調用,考慮到關於編譯器是MSVC的評論。
MOV ECX,DWORD PTR DS:[xxxxxxxx]
指向類實例的指針從全局變量載入ECX。 (注意:默認__thiscall調用約定使用ECX傳遞實例指針,也就是這個指針)。
MOV EDX,DWORD PTR DS:[ECX]
vftable(虛函數表)指針通常是類佈局中的第一項。這裏指針被加載到EDX中。
MOV EAX,DWORD PTR DS:[EDX+116]
將表中偏移量116(0x74)處的方法指針加載到EAX中。由於每個指針都是4個字節,這是該類的第30個虛擬方法(116/4 + 1)。
CALL EAX
該方法被調用。
在原來的C++它會是這個樣子:
g_pObject1->method30();
要知道更多關於MSVC的實現C++類,包括虛擬方法,請參閱我的文章here。
@ x0n - 這是作業標籤? – 2010-08-10 21:14:46
這不是家庭作業,我只是不擅長組裝。 – Iron 2010-08-10 21:22:39
刪除了作業標籤。 – x0n 2010-08-10 21:23:39