unité unité 1; L'interface utilise des fenêtres, des messages, des systèmes, des variantes, des classes, des graphiques, des contrôles, des formulaires, des boîtes de dialogue, STDCTRLS; type tform1 = classe (tform) Button1: tbutton; Memo1: TMEMO; Button2: TBUTTON; Button3: Tbutton; Procédure Button1Click (expéditeur: tobject); Procédure Button2Click (expéditeur: tobject); Procédure Button3Click (expéditeur: tobject); Procédure FormDestroy (expéditeur: tobject); Procédure FormCreate (expéditeur: tobject); Procédure privée {Private} procédure showmsg (s: string); Public {Public Declarations} end; var forme1: tform1; implémentation {$ r * .dfm} utilise mlde32Unit; const Despath = 'C: / Program Files / Borland / Delphi6 / Projects / adv apihook / test / vt.exe'; Func2hook = 'freelibrary'; var // doit être un ptrreal variable glloble: pointeur; CBSTOLEN: Cardinal; NtdllBase, ntdllLength: entier; P: pointeur; H: DWORD; procédure tform1.showmsg (s: string); begin memo1.lines.add (s); fin; Procédure tform1.button1Click (expéditeur: tobject); étiquette fakecode, rtncode; var // si: startupInfo; // pi: process_information; OriginalBytes: Array [0..4] de Char; HookJMP: PCHA; RTN: Cardinal; Octets: Array [0..4] de char; TMP: Cardinal; PEB, LDR, FLINK: Pointer; BS: DWORD; commencer ptrreal: = nil; NtdllLength: = 0; NtdllBase: = getModuleHandle ('ntdll.dll'); ASM MOV EAX, FS: [30 $] MOV PEB, EAX end; ldr: = pointeur (dword (pointeur (dword (peb) +12) ^)); Flink: = pointeur (dword (pointeur (dword (ldr) +12) ^)); P: = Flink; répéter bs: = dword (pointeur (dword (p) + 18 $) ^); Si bs = ntdllBase, commencez ntdllLength: = dword (pointeur (dword (p) + 20 $) ^); casser; fin; p: = pointeur (dword (p ^)); Jusqu'à ce que DWORD (FLINK) = DWORD (P ^); Si ntdllLength = 0 alors showmsg ('ne peut pas obtenir la taille de l'image ntdll.dll!'); {Showmsg ('Création d'un processus suspendu ...'); Zeromemory (@si, sizeof (startupInfo)); si.cb: = sizeof (startupInfo); CreateProcess (Despath, Nil, Nil, Nil, False, Create_Suspeded, Nil, Nil, Si, PI); } Showmsg ('préparation de crochet' + func2hook + '...'); Ptrreal: = getProcaddress (getModuleHandle ('kernel32.dll'), func2hook); Si vous êtes attribué (ptrreal) alors showmsg ('real' + func2hook + 'addr:' + intohex (dword (ptrreal), 8)) else commence showmsg ('addr:' + func2hook + 'est illisible! // Resumethread (pi.hthread); Sortie; fin; ReadProcessMemory (getCurrentProcess, ptrreal, @bytes, 5, rtn); // readProcessMemory (pi.hprocess, ptrreal, @bytes, 5, rtn); Si les octets [0] <> Chr ($ e9) commencent Copymemory (@originalbytes, @bytes, 5); Showmsg (func2hook + 'havn'''t a été accroché!'); End Else Begin ShowmsG (Func2Hook + 'ont été accrochés! Exit!'); // Resumethread (pi.hthread); sortie; fin; cbstolen: = 0; tandis que cbstolen <5 do cbstolen: = cbstolen + lde32 (pointeur (dword (ptrreal) + cbstolen)); Showmsg ('Let'’s voler le premier' + inttoStr (cbstolen) + 'octets :)'); Showmsg ('mais le rendre écrivable d'abord ...'); Si virtualprotect (ptrreal, cbstolen, page_execute_readwrite, @tmp), puis showmsg ('make' + intohex (dword (ptrreal), 8) + 'writeable succeed!') else commence showmsg ('hoops! make' + intohex (dword (ptrreal ), 8) + 'Échec de la sortie!'); // Resumethread (pi.hthread); sortie; fin; Showmsg ('assembler les codes jmp & hook' + func2hook + '...'); GetMem (hookjmp, 5); essayez hookjmp [0]: = chr ($ e9); asm push eax lea eax, fakecode mov tmp, eax pop eax end; tmp: = tmp - dword (ptrreal) - 5; COPYMEMORY (@HOOKJMP [1], @TMP, 4); asm push eax lea eax, rtncode mov tmp, eax pop eax end; VirtualProtect (Pointer (TMP), CBSTOLEN, Page_Execute_Readwrite, @rtn); Copymémoire (pointeur (TMP), ptrreal, cbstolen); WriteProcessMemory (GetCurrentProcess, ptrreal, hookjmp, 5, rtn); // WriteProcessMemory (pi.hprocess, ptrreal, hookjmp, 5, rtn); Showmsg ('hook' + func2hook + 'succéder! Reprendre le thread!'); Enfin FreeMem (HookJMP); // Resumethread (pi.hthread); fin; sortie; FAKECODE: // Pas de chaînes d'ici sur ASM INT 3 END; asm push eax lea eax, [esp + 4] mov p, eax pop eax end; Si dword (p ^) - ntdllBase <ntdllLength alors asm pop p pop eax pop eax pop eax mov eax, 0 jmp p // push p // ret end; // MessageBox (0, pChar (p), '', 0); Rtncode: ASM NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP EAX, PTRRREAL ADD EAX, CBSTOLEN JMP EAX END; fin; var ptr, ppp: pointeur; Procédure tform1.button2click (expéditeur: tobject); commencer {ASM Call PPP; fin; sortie; } Button3Click (nil); Ptr: = virtualalloc (nil, 1024, mem_commit, page_execute_readwrite); Si ce n'est pas attribué (PTR) alors memo1.lines.add ('Erreur fatale: VirtualAlloc a échoué!') Else memo1.lines.add ('virtualAlloc succède! Ptr =' + intoHex (dword (ptr), 8)); fin; Procédure tform1.formDestroy (expéditeur: tobject); Begin Button3Click (nil); UnmapViewoffile (PPP); Halte à clôture (h); fin; Procédure TForm1.Button3Click (expéditeur: tobject); Commencer si attribué (ptr) puis virtualfree (ptr, 0, mem_release); fin; Procédure TForm1.FormCreate (Sender: Tobject); begin h: = createFileMapping ($ ffffffff, nil, page_readwrite ou sec_commit, 0, 1, 'pe'); Ppp: = mapViewoffile (h, file_map_all_access, 0,0,0); Légende: = intoHex (dword (PPP), 8); char (ppp ^): = chr ($ c3); fin; fin. ====== UNIT1 里有很多垃圾代码 , 因为这个防 Crochet 的程序只是一个副产品。有用代码写成 DLL 注入其他进程就可以防 Crochet 了 , 已经试过没问题。代码风格比较差 , 不过不知道怎么改的更好 (如将 FAKECODE 部分放到单独过程中) 。如果你改好了希望能发给我一份。 MLDE32UNIT 代码来自 29A 第七期 , 作者忘记了 , 不好意思。