unidade de unidade1; A interface usa janelas, mensagens, sysutils, variantes, classes, gráficos, controles, formulários, diálogos, stdctrls; TIPO TFFORM1 = Classe (TForm) Button1: Tbutton; Memorando1: TMemo; Button2: tbutton; Button3: tbutton; Procedimento Button1Click (remetente: Tobject); Procedimento Button2Click (remetente: Tobject); Procedimento Button3Click (remetente: Tobject); procedimento formDestroy (remetente: tabjas); Procedimento FormCreate (remetente: Tobject); Private {Declarações Privadas} Procedimento ShowMSG (S: String); public {public declarações} final; Var Form1: TForm1; implementação {$ r *.dfm} usa mlde32Unit; const Despath = 'C:/Arquivos de Programas/Borland/Delphi6/Projects/ADV APIHOOK/TEST/VT.EXE'; Func2Hook = 'Freelibrary'; var // deve ser uma variável globa ptrreal: ponteiro; CBSTOLEN: cardeal; Ntdllbase, ntdllLlength: integer; P: ponteiro; H: DWORD; procedimento TFFORM1.SHOWMSG (S: String); BEGIN MEMO1.LINES.ADD (S); fim; procedimento TForm1.Button1Click (remetente: TOBJECT); etiqueta fakecode, rtncode; var // si: startupinfo; // pi: process_information; OriginalBytes: Array [0..4] de Char; Hookjmp: PCHA; Rtn: cardeal; Bytes: Array [0..4] de Char; TMP: cardeal; Peb, LDR, Flink: Ponteiro; BS: DWORD; Comece ptrreal: = nil; NtdllLlength: = 0; Ntdllbase: = getModuleHandle ('ntdll.dll'); ASM MOV EAX, FS: [$ 30] MOV PEB, EAX END; ldr: = ponteiro (dword (ponteiro (dWord (PEB) +12)^)); Flink: = ponteiro (DWORD (ponteiro (DWORD (LDR) +12)^)); P: = Flink; Repita BS: = DWORD (ponteiro (DWORD (P)+$ 18)^); Se BS = ntdllBase, inicie ntdllLlength: = dword (pointer (dword (p)+$ 20)^); quebrar; fim; p: = ponteiro (dword (p^)); até dword (flink) = dword (p^); Se ntdllLlength = 0, então ShowMSG ('não pode obter o tamanho da imagem ntdll.dll!'); {SHOWMSG ('Criando processo suspenso ...'); Zeromemory (@si, sizeof (startupinfo)); si.cb: = sizeof (startupinfo); CreateProcess (despath, nil, nil, nil, false, create_suspended, nil, nil, si, pi); } Showmsg ('preparando gancho' + func2hook + '...'); Ptrreal: = getProcaddress (getModuleHandle ('Kernel32.dll'), func2Hook); Se atribuído (ptrreal), então ShowMSG ('real' + func2Hook + 'addr:' + inttohex (dword (ptrreal), 8)) caso contrário, inicie o showmsg ('addr:' + func2Hook + 'é ilegível! saída!'); // resumethread (pi.hthread); Saída; fim; ReadProcessMemory (getCurrentProcess, ptrreal, @bytes, 5, rtn); // readProcessMemory (pi.hprocess, ptrreal, @bytes, 5, rtn); Se bytes [0] <> chr ($ e9), inicie o copymemory (@originalbytes, @bytes, 5); Showmsg (func2hook + 'não foi viciado!'); END ENCHE BEGIN SHOSTMSG (FUNC2HOOK + 'foi fisgado! Sair!'); // resumethread (pi.hthread); saída; fim; cbstolen: = 0; enquanto cbstolen <5 do cbstolen: = cbstolen + lde32 (ponteiro (dword (ptrreal) + cbstolen)); Showmsg ('let' roube o primeiro ' + inttostr (cbstolen) +' bytes :) '); Showmsg ('mas o crie por gravidade primeiro ...'); Se VirtualProtect (ptrreal, cbstolen, page_execute_readwrite, @tmp) então showmsg ('make' + inttohex (dword (ptrreal), 8) + 'worlabled!'), comece o showmsg ('aros! ), 8) + 'Falhou! // resumethread (pi.hthread); saída; fim; Showmsg ('codos jmp de montagem e gancho' + func2hook + '...'); GetMem (Hookjmp, 5); tente hookjmp [0]: = ch ($ e9); ASM empurre eax lea eax, fakecode mov tmp, eax pop eax end; tmp: = tmp - dword (ptrreal) - 5; Copymemory (@hookjmp [1], @tmp, 4); ASM empurre eax lea eax, rtncode mov tmp, eax pop eax end; VirtualProtect (Pointer (TMP), cbstolen, page_execute_readwrite, @rtn); Copimemoria (ponteiro (tmp), ptrreal, cbstolen); WriteProcessMemory (getCurrentProcess, ptrReal, Hookjmp, 5, RTN); // writeProcessMemory (pi.hprocess, ptrreal, hookjmp, 5, rtn); ShowMSG ('gancho' + func2Hook + 'é bem -sucedido! Reduza thread!'); Finalmente Freemem (Hookjmp); // resumethread (pi.hthread); fim; saída; Fakecode: // Sem strings daqui em ASM Int 3 End; ASM empurre eax lea eax, [esp+4] mov p, eax pop eax end; Se dWord (p^) - ntdllbase <ntdlllllength então asm pop // MessageBox (0, PChar (P), '', 0); Rtncode: ASM NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP MOV EAX, PTRREAL ADICIONAR EAX, CBSTOLEN JMP EAX FIM; fim; var ptr, ppp: ponteiro; procedimento TForm1.Button2Click (remetente: TOBJECT); Comece {ASM Call PPP; fim; saída; } Button3Click (NIL); PTR: = VirtualAlloc (nil, 1024, mem_Commit, page_execute_readwrite); se não for atribuído (ptr), então memor1.lines.add ('Erro fatal: virtualAlloc falhou!') else Memo1.Lines.add ('VirtualAlloc de sucesso! fim; procedimento TFFORM1.FORMDESTROY (remetente: Tobject); BOTEN Button3Click (NIL); UMAPVIELOFFILE (PPP); CloseHandle (H); fim; Procedimento TForm1.Button3Click (remetente: Tobject); Comece se atribuído (PTR) então VirtualFree (ptr, 0, mem_release); fim; procedimento TForm1.FormCreate (remetente: Tobject); BEGIN H: = CreateFilemapping ($ ffffffff, nil, page_readWrite ou Sec_Commit, 0, 1, 'PE'); ppp: = mapViewOffile (h, file_map_all_access, 0,0,0); Legenda: = InttoHex (DWORD (PPP), 8); char (ppp^): = chr ($ c3); fim; fim. ====== Unidade1 里有很多垃圾代码 , 因为这个防 gancho 的程序只是一个副产品。有用代码写成 dll 注入其他进程就可以防 gancho 了 , 已经试过没问题。代码风格比较差 , 不过不知道怎么改的更好 (Fakecode 部分放到单独过程中) 。如果你改好了希望能发给我一份。 mlde32Unit 代码来自 29a 第七期 , 作者忘记了 , 不好意思。 不好意思。 不好意思。 不好意思。 不好意思。