1 前言:
這2天看了Secrets of Reverse Engineering一書,對分析未文檔化的API的技術比較有心得,希望各位看了下面的教程,能拋磚引玉靈活的應用在逆向工程和破解技術上,方法是死的,但是人的思維是活,最重要是靈活應用。
2 實踐:
用OllyDbg對NTDLL.DLL進行反匯編,前提你要加入NTDLL.DLL的符號表,這樣你才能更好的對未文檔化的API進行反匯編,你們到微軟官方網站獲取相應版本Windows系統的系統符號表。
下面是RtlInitializeGenericTable函數的反匯編代碼:
01 MOV EDI, EDI ;
//壓入堆棧,保存EBP的數值
02 PUSH EBP ;
03 MOV EBP, ESP ;
// 獲取[ESP+8]的數值傳入EAX
// 此處指令我們可以翻譯為:
// MOV EAX, DWORD PTR SS:[ESP+8]
// 含義: 把當前堆棧頂向下偏移8h處的值賦給EAX,也就是該函數的第1個參數
// 聲明:我喜歡用ESP指針來想象堆棧。但是CPU處理的話,是用EBP來進行偏移處理
04 MOV EAX, DWORD PTR SS:[EBP+8] ;
05 XOR EDX, EDX ;
// EAX+4的數值當作指針傳入ECX
06 LEA ECX, DWORD PTR DS:[EAX+4] ;
// EDX的數值傳入[EAX],說明EAX的值是某個結構的指針
// 假設pUnknowStruct的地址為 EAX的數值
// 07的匯編指令對應的C語言: pUnknowStruct->member1 = 0 ;
07 MOV DWROD PTR DS:[EAX], EDX ;
// 此處指令我們可以翻譯為:
// MOV DWORD PTR DS:[EAX+8], EAX+4 ;
// 備注: [EAX] 為某結構的第1個變量
// [EAX+4]為某結構的第2個變量
// [EAX+8]為某結構的第3個變量
// 含義:該結構的第3個成員變量被賦于指向該結構的第2個成員變量的指針數值
// 08的匯編指令對應的C語言: pUnknowStruct->member3 = &pUnknowStruct->member2
08 MOV DWORD PTR DS:[ECX+4], ECX ;
// 此處指令我們可以翻譯為:
// MOV DWORD PTR DS:[EAX+4], EAX+4 ;
// 09的匯編指令對應的C語言: pUnknowStruct->member2 = &pUnknowStruct->member2
09 MOV DWORD PTR DS:[ECX], ECX ;
// 此處指令我們可以翻譯為:
// MOV DWORD PTR DS:[EAX+C], EAX+4 ;
// 10的匯編指令對應的C語言: pUnknowStruct->member4 = &pUnknowStruct->member2
10 MOV DWORD PTR DS:[EAX+C], ECX ;
// 此處指令我們可以翻譯為:
// MOV ECX, DWORD PTR SS:[ESP+C]
// 含義: 把當前堆棧頂向下偏移Ch處的值賦給ECX,也就是該函數的第2個參數
11 MOV ECX, DWORD PTR SS:[EBP+C] ;
// 含義: 把第2個參數傳送給某結構的第7個成員變量
// 12的匯編指令對應的C語言為: pUnknowStruct->member7 = Param2
12 MOV DWORD PTR DS:[EAX+18], ECX ;
// 此處指令我們可以翻譯為:
// MOV ECX, DWORD PTR SS:[ESP+10]
// 含義: 把當前堆棧頂向下偏移10h處的值賦給ECX,也就是該函數的第3個參數
13 MOV ECX, DWORD PTR SS:[EBP+10] ;
// 含義:把參數3傳給某結構的第8個成員變量
// 14的匯編指令對應的C語言為: pUnknowStruct->member8 = Param3
14 MOV DWORD PTR DS:[EAX+1C], ECX ;
// 此處指令我們可以翻譯為:
// MOV ECX, DWORD PTR SS:[ESP+14]
// 含義: 把當前堆棧頂向下偏移14h處的值賦給ECX,也就是該函數的第4個參數