Já está nas bancas a revista
Clube Delphi 127 com meu primeiro artigo sobre a madShi Collection. Neste artigo eu explico o básico sobre API Hooking.
Neste post falarei sobre um exemplo que não se encontra no artigo, que é o hooking da API GetUserName.
Os motivos que levam a hookar essa API podem ser variados, e todos eles nada éticos a meu ver. Você pode desde tentar enganar um produto registrado para um usuário acessando-o como outro usuário ou simplesmente para tapear um usuário administrador, que quando olhar quem está logado verá um nome diferente (supondo que isso funcione, não testei).
A idéia é que dá para mudar a resposta que outros programas recebem quando perguntam quem é o usuário logado. Para isso é necessário conhecer quais são as api's que fazem isso e como interceptá-las.
O código dessa postagem mostra como usar a madCodeHook para interceptar a api GetUserName da api do windows.
Primeiro de tudo criei um programa que mostra o nome do usuário corrente:
function NomeUsuario: string;
var
I: DWord;
begin
I := 255;
SetLength(Result, I);
Windows.GetUserName(PChar(Result), I);
Result := string(PChar(Result));
end;
procedure TForm2.btTestarClick(Sender: TObject);
begin
Edit1.Text := NomeUsuario;
end;
Esse programa simplesmente mostra o usuário logado. Depois de injetada a DLL que faz o hook a chamada a GetUserName terá seu resultado mudado.
É preciso salientar que existe outra api chamada GetUserNameEx que não está mapeada na unit windows.pas e que aceita mais parâmetros, e devolve mais resultados.
Interceptar essas duas API's é certeza de que mudará os resultados às suas relativas chamadas. Não é garantia nenhuma de que será possível abrir um arquivo para o qual seu usuário atual não tem autorização, mas não custa nada tentar.
Como pôde ser visto nos artigos que escrevi para a Revista Clube Delphi, eis o código da dll a ser injetada.
Essa dll intercepta apenas a função GetUserName, deixo a cargo do leitor a GetUserNamneEx, que é mais complexa. Num post futuro trataremos da GetUserNameEx. Deixo apenas o esqueleto para quem quiser se aventurar.
Lembre-se de que se estiver usando a versão trial/demo da madCollectionHook deverá manter mchEvaluation rodando para que o hooking funcione.
library hook;
uses
SysUtils,
windows,
Classes,
madcodehook;
{$R *.res}
const
USUORIGINAL = 'vitorrubio'; // vitorrubio --> meu user
USUTROCA = 'Administrador'; // Administrador--> quem quero ser
var
GetUserNameWNext: function (lpBuffer: PWideChar; var nSize: DWORD): BOOL; stdcall;
GetUserNameANext: function (lpBuffer: PAnsiChar; var nSize: DWORD): BOOL; stdcall;
function GetUserNameWCallback (lpBuffer: PWideChar; var nSize: DWORD): BOOL; stdcall;
begin
Result := GetUserNameWNext(lpBuffer, nSize);
if (trim(string(lpBuffer)) = USUORIGINAL) then
begin
StrCopy(lpBuffer, USUTROCA);
nSize := Length(USUTROCA);
end;
end;
function GetUserNameACallback (lpBuffer: PAnsiChar; var nSize: DWORD): BOOL; stdcall;
begin
Result := GetUserNameANext(lpBuffer, nSize);
if (trim(AnsiString(lpBuffer)) = AnsiString(USUORIGINAL)) then
begin
StrCopy(lpBuffer, USUTROCA);
nSize := Length(USUTROCA);
end;
end;
begin
HookAPI('advapi32.dll', 'GetUserNameW', @GetUserNameWCallback, @GetUserNameWNext);
HookAPI('advapi32.dll', 'GetUserNameA', @GetUserNameACallback, @GetUserNameANext);
end.
Agora o código para injetar, desinjetar e testar a dll:
procedure TForm1.btInjetarClick(Sender: TObject);
begin
InjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, 'hook.dll');
end;
procedure TForm1.btTestarClick(Sender: TObject);
begin
Edit1.Text := NomeUsuario;
end;
procedure TForm1.btDesinjetarClick(Sender: TObject);
begin
UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, 'hook.dll');
end;
Crie uma form com 3 botões e um edit e teste. Lembre-se de todas as medidas de segurança necessárias para se trabalhar com API hooking e lembre-se que toda a api do windows se invoca com stdcall.
Coloque a dll e o testador em um mesmo project group para facilitar.
É importante salientar que qualquer processo que use a GetUserNameEx para identificar o usuário não sofrerá nenhum efeito desse hooking. Além disso o windows tem outras formas, de baixo nível, para descobrir o usuário logado.
Have fun :)
Comentários
Postar um comentário