[Dúvida] Hooking/DLL
Estou com algumas dúvidas sobre Hooking..
Eu estou querendo fazer uma aplicação que não seje fechada..
Para isso eu precisaria de usar um hook né? No TerminateProcess ou ExitProcess?
Eu preciso criar um DLL pra fazer isso ou só pelo EXE ja dá? E se eu quiser impedir outras aplicações de serem fechadas? Preciso de ter uma DLL ou só EXE?
Gostaria de saber tb, se por exemplo eu tiver q usar DLL, num teria como eu ´acoplar´ a DLL ao EXE e ao executar o programa, ele extrai-se a DLL para uma pasta que eu quisesse e assim usá-la?
Sei que tem uns mágicos do hooking por ae(nildo, michael, etc..) :roll:
Se qlqer um ae puder ajudar eu agradeço...
Vlw!!
Mrmick
Respostas
Michael
05/02/2006
Respostas:
1) Vc deve ´hookar´ a API [b:932301d7f7]TerminateProcess[/b:932301d7f7], da [b:932301d7f7]kernel32.dll[/b:932301d7f7]. Veja [url=http://help.madshi.net/HowToUseMadCodeHook.htm]neste link[/url] um exemplo usando a [b:932301d7f7]MadCodeHook[/b:932301d7f7]. Note que vc pode usar a lib do [b:932301d7f7]Nildo [/b:932301d7f7]sem problemas: basta trocar os nomes das funções;
2) O código do hook no EXE só tem efeito sobre ele mesmo. Para interceptar as chamadas à API´s em outros processos vc precisa usar uma DLL e injetá-la no sistema;
3) Vc pode incluir a DLL no executável, extraí-la e injetá-la. Mas, pq faria isso? Apenas para não precisar distribuir o arquivo?
[]´s
Nildo
05/02/2006
Falows
Martins
05/02/2006
Boa sorte!!!
Mrmick
05/02/2006
Vo dar uma lida, uma fuçada..
Dúvidas vo postar aqui, ok?
Vlw pessoal!
:wink:
Mrmick
05/02/2006
Bom, no exemplo lá do madshi, tem essa função:
function ThisIsOurProcess(processHandle: dword) : boolean; var pid : dword; arrCh : array [0..MAX_PATH] of char; begin pid := ProcessHandleToId(processHandle); result := (pid <> 0) and ProcessIdToFileName(pid, arrCh) and (PosText(´OurApplication.exe´, arrCh) > 0); end;
Só que na biblioteca BmsApiHook, não tem o [b:b56d4f8760]ProcessHandleToId[/b:b56d4f8760], [b:b56d4f8760]ProcessIdToFileName[/b:b56d4f8760] e nem o [b:b56d4f8760]PosText[/b:b56d4f8760], ae tipw como eu adaptaria para a biblioteca Bms?
Tava olhando no help e vi que tem a função [b:b56d4f8760]BmsGetProcessID[/b:b56d4f8760], ela poderia substituir a [b:b56d4f8760]ProcessHandleToId[/b:b56d4f8760] né?
Ah, otra coisa fora disso ae, se por exemplo tem uma DLL injetada no explorer.exe, teria como eu fazer um aplicativo pra ´desinjetar´ essa DLL sem fechar ou danificar o explorer.exe ?
Bom, é isso.. Malz ae eu estar incomodando, mas é pq qdo tá se aprendendo é assim mesmo. uma confusão na kbeça.. mto foda..
Vlw ae pessoal!
:wink:
Nildo
05/02/2006
Entao vc pode verificar assim:
function ThisIsOurProcess(processID: dword) : boolean; begin Result := GetCurrentProcessID = BmsGetProcessID( ´OurApplication.exe´ ); end;
Tem sim!
BmsRemoteUnloadLibrary( BmsGetProcessID( ´explorer.exe´ ), ´c:\suaDLL.dll´ );
Titanius
05/02/2006
Tem como eu usar Hook, pra proteger uma pasta? tipo, ninguem acessar ela? se alguem tentar acessar, ele pede uma senha, e se tiver certo libera o acesso?
Se sim, teria como funcionar em modo de seguranca? pois senao cara entra em modo de seguranca e acessa a pasta.. :D
[]s
Martins
05/02/2006
BmsRemoteUnloadLibrary( BmsGetProcessID( ´explorer.exe´ ), ´c:\suaDLL.dll´ );
[b:c3f0c20e36]BmsRemoteUnloadLibrary - Reove a sua DLL do processo.[/b:c3f0c20e36]
BmsRemoteUnloadLibrary( BmsGetProcessID( ´explorer.exe´ ), ´c:\suaDLL.dll´ );
Mrmick
05/02/2006
Tipw, MUITO OBRIGADO! Vlw mesmo! É bom d+ qdo as coisas vão ficando mais claras.. vlw!
Tipw, testei aqui e consigo fechar o programa normalmente.. Não dá erro nem nada pra compilar e Hookar.. mas ele não bloqueia o fechamento do processo..
DLL:
library funcoes; uses Windows, BmsAPIHook; var TerminateProcessNext : function (processHandle, exitCode: dword) : bool; stdcall; function ProcessoProtegido(processID: dword) : boolean; begin Result := GetCurrentProcessID = BmsGetProcessID(´notepad.exe´); end; function TerminateProcessCallback(processHandle, exitCode: dword) : bool; stdcall; begin if ProcessoProtegido(processHandle) then begin result := false; SetLastError(ERROR_ACCESS_DENIED); end else result := TerminateProcessNext(processHandle, exitCode); end; begin BmsHookApi(´kernel32.dll´, ´TerminateProcess´, @TerminateProcessCallback, @TerminateProcessNext); end.
MeuProg:
procedure TForm1.BloqueiaClick(Sender: TObject); begin BmsRemoteLoadLibrary(TODOS_PROCESSOS, ´funcoes.dll´); MessageBox(0, ´Bloqueado!´, ´Aviso...´, MB_ICONINFORMATION); end; procedure TForm1.DesbloqueiaClick(Sender: TObject); begin BmsRemoteUnloadLibrary(TODOS_PROCESSOS, ´funcoes.dll´); end;
Tem algo errado?
valewww!!
:D
Martins
05/02/2006
Uma ótima pergunta [b:5cf0e57f10]Titanius[/b:5cf0e57f10], acho até q já perguntei algo parecido para o [b:5cf0e57f10]Nildo[/b:5cf0e57f10].
Nildo
05/02/2006
Já sobre a função
function ProcessoProtegido(processID: dword) : boolean; begin Result := GetCurrentProcessID = BmsGetProcessID(´notepad.exe´); end;
não é usado Handle mas sim ID.. Então passar o Handle como parametro não vai ser a mesma coisa que passar um ID. Creio que você deva usar as funções da MadCodeHook para obter o Handle de um ID de um processo.
Nildo
05/02/2006
Sim, é só você saber as APIs de acesso a pasta, enumeração de arquivos, e não deixar processar a API caso se trate de sua pasta.
Até dá, porém quando você inicia o micro em modo de segurança, nenhum programa que deve inicializar junto com o Windows vai carregar. Então até que o cara não execute seu programa que vai proteger as pastas ele terá acesso.
Sabe o que alguns programas desse tipo fazem? Eles criam um tipo de extensão, exemplo: [b:8789c9a396]*.AAA[/b:8789c9a396]. Então quando você manda proteger uma pasta ele encripta todo o conteúdo da pasta e joga em um unico arquivo com a extensão [b:8789c9a396]*.AAA[/b:8789c9a396], tudo encriptado nesse único arquivo. Esse programa vai e atrela o ícone de uma pasta normal aos arquivos do tipo [b:8789c9a396]*.AAA[/b:8789c9a396]. Dai quando você acessa esse arquivo pelo Windows Explorer, vai executar o programa do cara que pede uma senha e desencripita esse arquivo e cria a pasta com todas as sub-pastas e arquivos que continha nesse arquivo [b:8789c9a396]*.AAA[/b:8789c9a396]. Mas dai fica um problema, você vai ver sua pasta com uma extensão, e isso fica esquisito. Então esse progra
Dai esse arquivo fica totalmente protegido até em modo de segurança, e se o usuário nao tiver o seu programa pra acessar essa pasta, ele nao acessa nunca. Dai se o engraçadinho desinstalar seu programa por pirraça, já era!
Espero que tenha sanado suas dúvidas!
Um abraço!
Nildo
05/02/2006
Mrmick
05/02/2006
Agora sobre o Handle e ID, eu não tinha reparado mto bem nessa função..
Infelizmente tenho que partir por concorrente (Madshi) auhhauhuahu :lol:
Vlw ae, vo ir tentando aki ;)
Nildo
05/02/2006
Hehehehe Sem problemas, sem mágoas :lol:
Titanius
05/02/2006
[]s
Martins
05/02/2006
Nildo
05/02/2006
Estavamos falando em usar o do Madshi por causa das funções de Handle e ID. Mas quanto ao hook, o que uma faz a outra faz
Martins
05/02/2006
Estavamos falando em usar o do Madshi por causa das funções de Handle e ID. Mas quanto ao hook, o que uma faz a outra faz[/quote:ac28dee717]
Perfeito!
Mrmick
05/02/2006
Mas tipw, estou ficando doido aqui já.. Fiz exatamente como no exemplo do madshi, mas agora ele num tá dando mais certo, o arquivo protegido é fechado normalmente..
DLL:
library funcoes; uses Windows, madRemote, madCodeHook, madStrings; var TerminateProcessNext : function (processHandle, exitCode: dword) : bool; stdcall; function ThisIsOurProcess(processHandle: dword) : boolean; var pid : dword; arrCh : array [0..MAX_PATH] of char; begin pid := ProcessHandleToId(processHandle); result := (pid <> 0) and ProcessIdToFileName(pid, arrCh) and (PosText(´notepad.exe´, arrCh) > 0); end; function TerminateProcessCallback(processHandle, exitCode: dword) : bool; stdcall; begin if ThisIsOurProcess(processHandle) then begin result := false; SetLastError(ERROR_ACCESS_DENIED); end else result := TerminateProcessNext(processHandle, exitCode); end; begin HookAPI(´kernel32.dll´, ´TerminateProcess´, @TerminateProcessCallback, @TerminateProcessNext); end.
Programa:
procedure TForm1.Button1Click(Sender: TObject); begin InjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, ´funcoes.dll´); MessageBox(0, ´Pronto!´, ´OK...´, MB_ICONINFORMATION); end; procedure TForm1.Button2Click(Sender: TObject); begin UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, ´funcoes.dll´); end;
Num consegui entender se tem algo de errado! Se alguém perceber algo por favor me fale :cry:
Vlw ae pessoal..
abraços.
Mrmick
05/02/2006
Michael
05/02/2006
Para comprovar isso, atribua a uma variável o valor de retorno da função [b:91a6f8cdb5]BmsRemoteLoadLibrary [/b:91a6f8cdb5]ou [b:91a6f8cdb5]InjectLibrary [/b:91a6f8cdb5]e verifique se ele contém o status de OK. Não me lembro de cabeça qual é esse valor agora. [b:91a6f8cdb5]Nildo[/b:91a6f8cdb5], qual é mesmo?
[]´s
Nildo
05/02/2006
Minha função vai retornar verdadeiro se não ocorrerem erros na thread que carrega a DLL remotamente. Você pode usar o nome da DLL sem o Path caso ela esteja na pasta do System32 ou na pasta do executável que você está injetando a DLL. Se estiver injetando no Photoshop por exemplo, a DLL deveria ficar na pasta do Photoshop. Ou você resolve da maneira que o Michael disse, colocando o path completo!
Um abraço!
Michael
05/02/2006
Vc tinha me dito que o path era importantíssimo. Olha meu artigo na ClubeDelphi! Coloquei isso em negrito! ;-)
[]´s
Nildo
05/02/2006
Mas é bom que o cara tenha costume em usar o Path, senão o usuario nao usa e não sabe porque não funciona entende?^
Martins
05/02/2006
Minha função vai retornar verdadeiro se não ocorrerem erros na thread que carrega a DLL remotamente. Você pode usar o nome da DLL sem o Path caso ela esteja na pasta do System32 ou na pasta do executável que você está injetando a DLL. Se estiver injetando no Photoshop por exemplo, a DLL deveria ficar na pasta do Photoshop. Ou você resolve da maneira que o Michael disse, colocando o path completo!
Um abraço![/quote:5b33088129]
Poderia ficar assim:
InjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, ExtractFilePath(ParamStr(0)) + ´funcoes.dll´); ... UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, ExtractFilePath(ParamStr(0)) + ´funcoes.dll´);
Pode ser assim?
Michael
05/02/2006
Entendo, e vc ainda é um mané... hehehehehe
[b:d1092fdd17]Martins[/b:d1092fdd17], é exatamente assim.
[]´s
Martins
05/02/2006
Entendo, e vc ainda é um mané... hehehehehe
[b:74622b6695]Martins[/b:74622b6695], é exatamente assim.
[]´s[/quote:74622b6695]
Ok!
valew [b:74622b6695]Michael[/b:74622b6695]!!!!
Mrmick
05/02/2006
Coloquei o path completo e continuou dando erro, ae fiz assim:
program TESTE;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
madCodeHook;
begin
if InjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, ExtractFilePath(ParamStr(0)) + ´TPHook.dll´) then
MessageBox(0, ´PRONTO!´, ´OK...´, MB_ICONINFORMATION) else
UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, ExtractFilePath(ParamStr(0)) + ´TPHook.dll´);
WriteLn(´AFF´);
ReadLn;
end.
E apareceu [b:8c675326b0]AFF[/b:8c675326b0]...
O que pode estar errado?
abraços..
Nildo
05/02/2006
Mrmick
05/02/2006
Está sim.. criei essa outra aplicação do 0 pra ver se era algum erro meu.
Mas não é.. está idêntico ao exemplo do Madshi.. E o estranho é que tinha funcionado mas agora não dá mais..
[]s
Mrmick
05/02/2006
Peguei a DLL madCHook.dll que fica em:
C:\Arquivos de programas\madCollection\madCodeHook\Dll
E coloquei no mesmo diretório da minha aplicação e assim funcionou!
Mas pq? Que tosqueira..
abraços
Nildo
05/02/2006
O Windows não pode adivinhar onde estão as DLLs necessárias.
A diferença da minha biblioteca e da dele é que a minha não necessita de DLL adicional como esta da MadCodeHook, só a sua de Hook
Mrmick
05/02/2006
Sim, eu sei, mas é bem estranho não ter mostrado nenhuma mensagem de erro dizendo que faltava X.dll..
Mas vlw ae.. agora já sei ql é o problema vo ver o que faço aqui.
Vlw mesmo, consegui esclarecer várias coisas neste tópico e entender melhor algumas outras..
abraços pessoal!
PS: Qlqer coisa eu volto pra encher o saco tá ok? :lol:
Mrmick
05/02/2006
function ThisIsOurProcess(processHandle: dword) : boolean; var pid : dword; arrCh : array [0..MAX_PATH] of char; begin pid := ProcessHandleToId(processHandle); result := (pid <> 0) and ProcessIdToFileName(pid, arrCh) and (PosText(´notepad.exe´, arrCh) > 0); end; function TerminateProcessCallback(processHandle, exitCode: dword) : bool; stdcall; begin if ThisIsOurProcess(processHandle) then begin result := false; SetLastError(ERROR_ACCESS_DENIED); end else result := TerminateProcessNext(processHandle, exitCode); end;
Usando madCodeHook é traquilo, mas ficar dependendo da DLL dele pra fazer isso é triste.. :cry:
Fui pro concorrente, mas agora queria saber um modo de verificar o processo usando o 100¬ Brasuca BmsApiHook :lol:
Alguma sugestão?
abraços!
Michael
05/02/2006
Coloque a DLL no programa de instalação da sua aplicação.
[]´s
Mrmick
05/02/2006
O problema é que carregar 119kb á mais só por causa de 1 função, é triste :?
Mas vlw responder.
abraços!
Martins
05/02/2006
Se a questão é só aprndizado não vejo pq não usar a biblioteca do Madshi, mesmo q por uma única função, depois com o tempo e aprendizado vc pode escrever algo q possa substituir o uso dessa função.
Boa sorte!!
Nildo
05/02/2006
Mrmick
05/02/2006
Tá ok.. qdo arrumar um $$ irei comprar as edições da revista que fala sobre Hooking, pra poder me situar melhor e depois partirei para os sites gringos, onde o conteúdo é mais extenso. Vlw ae..
[b:ca4c849ff5]nildo[/b:ca4c849ff5]
Hum.. creio que já tenha tentado isso.. não sei.. mas vo ver novamente..
Obrigado por responderem..
abraços.
Martins
05/02/2006
[b:d1ff06088e]MrMick[/b:d1ff06088e], é isso aí, vc quer aprender, vc consegue, não é fácil, mas depois quando vc olhar para trás e ver o q já desenolveu e o quanto evoluiu, será muito gratificante.
Valew
Donny_
05/02/2006
Enigmax_d2
05/02/2006
var
list: tstrings;
i: integer;
th: tthread;
begin
i := 0;
th := nil;
if DirectoryExists(getroot+´\Teste´) then
if not DeleteFolder(getroot+´\Teste´) then begin
if not SetDebugPrivilege then exit;
if KillProcess(getpid(´Teste.exe´)) then if not deletefile(getroot+´\Teste\Teste.exe´) then begin
while i < 1000 do begin if getpid(´Teste.exe´) <> 0 then break else inc(i, 1); sleep(1); end;
if getpid(´Teste.exe´) <> 0 then begin
th := listthreads(getpid(´Teste.exe´));
for I := 0 to high(th) do suspend(th[i].th32ThreadID);
end;
end;