/*
看雪精华文章,http://bbs.pediy.com/showthread.php?t=37586。
概括性介绍了API-HOOK的知识。
*/
标 题: 【原创】API-HOOK and ANTI-API-HOOK For Ring3
作 者: AnskyaDelphi: push 0 push 0 push 0 push 0 call -$000467cd(这里是MessageBox在导入表的偏移)
77D504EA > 8BFF MOV EDI,EDI 77D504EC 55 PUSH EBP 77D504ED 8BEC MOV EBP,ESP 77D504EF 833D BC04D777 0>CMP DWORD PTR DS:[77D704BC],0 77D504F6 74 24 JE SHORT USER32.77D5051C 77D504F8 64:A1 18000000 MOV EAX,DWORD PTR FS:[18] 77D504FE 6A 00 PUSH 0 77D50500 FF70 24 PUSH DWORD PTR DS:[EAX+24] 77D50503 68 240BD777 PUSH USER32.77D70B24 77D50508 FF15 C812D177 CALL DWORD PTR DS:[<&KERNEL32.Interlocke>; kernel32.InterlockedCompareExchange 77D5050E 85C0 TEST EAX,EAX 77D50510 75 0A JNZ SHORT USER32.77D5051C 77D50512 C705 200BD777 0>MOV DWORD PTR DS:[77D70B20],1 77D5051C 6A 00 PUSH 0 77D5051E FF75 14 PUSH DWORD PTR SS:[EBP+14] 77D50521 FF75 10 PUSH DWORD PTR SS:[EBP+10] 77D50524 FF75 0C PUSH DWORD PTR SS:[EBP+C] 77D50527 FF75 08 PUSH DWORD PTR SS:[EBP+8] 77D5052A E8 2D000000 CALL USER32.MessageBoxExA 77D5052F 5D POP EBP 77D50530 C2 1000 RETN 10
typedef int(*TMessageBoxA)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); void __fastcall TForm1::Button1Click(TObject *Sender) { TMessageBoxA MsgBox; MsgBox = (TMessageBoxA)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA"); MsgBox(0, 0, 0, 0); }
77D504EA >- FF25 1E00055F JMP DWORD PTR DS:[5F05001E]--被补丁了. 77D504F0 3D BC04D777 CMP EAX,user32.77D704BC 77D504F5 007424 64 ADD BYTE PTR SS:[ESP+64],DH 77D504F9 A1 18000000 MOV EAX,DWORD PTR DS:[18] 77D504FE 6A 00 PUSH 0 77D50500 FF70 24 PUSH DWORD PTR DS:[EAX+24] 77D50503 68 240BD777 PUSH user32.77D70B24 77D50508 FF15 C812D177 CALL DWORD PTR DS:[<&KERNEL32.Interlocke>; kernel32.InterlockedCompareExchange 77D5050E 85C0 TEST EAX,EAX 77D50510 75 0A JNZ SHORT user32.77D5051C 77D50512 C705 200BD777 0>MOV DWORD PTR DS:[77D70B20],1 77D5051C 6A 00 PUSH 0 77D5051E FF75 14 PUSH DWORD PTR SS:[EBP+14] 77D50521 FF75 10 PUSH DWORD PTR SS:[EBP+10] 77D50524 FF75 0C PUSH DWORD PTR SS:[EBP+C] 77D50527 FF75 08 PUSH DWORD PTR SS:[EBP+8] 77D5052A E8 2D000000 CALL user32.MessageBoxExA 77D5052F 5D POP EBP 77D50530 C2 1000 RETN 10
bool IsHook(char *lpChar) { if(*lpChar == 0xFF) return true; } function IsHook(lpFunc: Pointer): Boolean; begin Result := False; if (Char(lpFunc^)=#$FF) then Result := True; end;
77D504EA > 68 04BF4000 PUSH 40BF04------这里被写成钩子过程地址 77D504EF C3 RETN-------------返回 77D504F0 3D BC04D777 CMP EAX,user32.77D704BC 77D504F5 007424 64 ADD BYTE PTR SS:[ESP+64],DH 77D504F9 A1 18000000 MOV EAX,DWORD PTR DS:[18] 77D504FE 6A 00 PUSH 0 77D50500 FF70 24 PUSH DWORD PTR DS:[EAX+24] 77D50503 68 240BD777 PUSH user32.77D70B24 77D50508 FF15 C812D177 CALL DWORD PTR DS:[<&KERNEL32.Interlocke>; kernel32.InterlockedCompareExchange 77D5050E 85C0 TEST EAX,EAX 77D50510 75 0A JNZ SHORT user32.77D5051C 77D50512 C705 200BD777 0>MOV DWORD PTR DS:[77D70B20],1 77D5051C 6A 00 PUSH 0 77D5051E FF75 14 PUSH DWORD PTR SS:[EBP+14] 77D50521 FF75 10 PUSH DWORD PTR SS:[EBP+10] 77D50524 FF75 0C PUSH DWORD PTR SS:[EBP+C] 77D50527 FF75 08 PUSH DWORD PTR SS:[EBP+8] 77D5052A E8 2D000000 CALL user32.MessageBoxExA 77D5052F 5D POP EBP 77D50530 C2 1000 RETN 10
mov edi, edi push ebp mov ebp, esp or push ebp mov ebp, esp
unsigned long __fastcall SizeOfProc(void *Proc) { ULONG Length; PUCHAR pOpcode; ULONG Result = 0; do { Length = SizeOfCode(Proc, &pOpcode); Result += Length; if ((Length == 1) && (*pOpcode == 0xC3)) break; Proc = (PVOID)((ULONG)Proc + Length); } while (Length); return Result; }
function GetProcAddressEx(Proc: Pointer): Pointer; var lpCallRet: Pointer; iCodeLen: Integer; begin Result := nil; lpCallRet := nil; iCodeLen := SizeOfCode(Proc); // 判断第一行代码是否为push 0xXXXXXXXX if (iCodeLen = 5) and (Byte(Proc^) = $68) then begin // 获取0xXXXXXXXX Proc := Pointer(PDWORD(longword(Proc) + 1)^); while True do begin iCodeLen := SizeOfCode(Proc); // 判断是否为call dword ptf[0xXXXXXXXX] if (iCodeLen = 6) and (Byte(Proc^) = $FF) and (Byte(Pointer (longword(Proc) + 1)^) = $15) then begin // 获取0xXXXXXXXX lpCallRet := Proc; Break; end; // 函数结尾 if (Byte(Proc^) = $C3) then Break; Proc := pointer(longword(Proc) + iCodeLen); end; end; if lpCallRet <> nil then begin Result := Pointer(PDWORD(PDWORD(longword(lpCallRet) + 2)^)^); end; end;