Fazendo o seu Code Injection

28/04/2009 14:27 2 comentários

Compartilhe este artigo

Autor:

Fuctura Tecnologia

Tags:

Visto que é algo muito útil e um pouco complicado estarei postando como fazer passo a passo.
Então vamos começar.

Dica:
Para quem não esta acostumado e sequer sabe sobre manipulação de memória recomendo que de uma boa lida em artigos sobre manipulação de memória para que haja uma facilidade de entendimento ao seguir a leitura do tutorial.

O que é Code Injection?
Code injection nada mais é do que injetar uma DLL e fazer com que o processo remoto execute a tal função.
Para fazer isso precisaremos de uma DLL que a função em seja exportada
Ex:no delphi o fim do código seria

exports
FazerExitProcess;

Outro detalhe importante é que precisaremos de privilégios necessários.Para evitar quaisquer eventuais problemas, definiremos o privilégio como o de debug e tambem depois de executada a rotina, não temos mais porque deixar os parâmetros utilizados na execução da mesma no target, isso só iria ocupar espaço, então nós liberaremos toda a memória escrita no processo remoto.

Preparando um Code Injection

Antes de mais nada precisaremos de uma estrutura para os parâmetros do nosso Code Injection então declare
a seguinte type no seu form.

type
TInjectParams = record
LoadLibrary: function (lpLibFileName: PAnsiChar): Cardinal; stdcall;
LibName: PAnsiChar;
GetProcAddress: function (hModule: Cardinal; lpProcName: PAnsiChar): Pointer; stdcall;
ProcName: PAnsiChar;
end;
PInjectParams = ^TInjectParams;

Com essa estrutura,o usuário no final do code injection só precisará de pegar o Process ID(PID) do processo,Portanto declare na uses da sua unit a biblioteca TlHelp32 e nas funções declare a seguinte função.

function GetProcess(proc: string): Cardinal;
var
Snap: THandle;
pe: TProcessEntry32;
begin
Snap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if Snap = 0 then Exit;
if Process32First(Snap,pe) then
begin
repeat
if proc = pe.szExeFile then
begin
Result:=pe.th32ProcessID;
break;
end;
until not Process32Next(Snap,pe)
end
end;

Como ja foi dito,nós precisaremos escrever na memória do processo remoto,portanto é necessário alocar a memória para a escrita,para facilitar vamos declarar as funções.

function WriteString(Process: Cardinal; s: string): Pointer;
var
bytes: Cardinal;
begin
Result:=VirtualAllocEx(Process, nil, length(s) + 1, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result , pchar(s), length(s) + 1, bytes);
end;
function WriteData(Process, dwSize: Cardinal; RemoteData: pointer): pointer;
var
bytes: Cardinal;
begin
Result:=VirtualAllocEx(Process, nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result, RemoteData, dwSize, bytes);
end;


Com quase tudo pronto nós precisaremos de uma função para executar o código no processo remoto então declare mais essa função também.

procedure RemoteFunction(Parametros: PInjectParams); stdcall;
var
proc: procedure; stdcall;
begin
proc:=Parametros^.GetProcAddress(Parametros^.LoadLibrary(Parametros^.LibName),Parametros^.ProcName);
proc;
end;

Agora precisaremos de um método para saber o tamanho dessa rotina descrita acima, pois na hora de escrevê-la no target é necessário por o tamanho. Para isso faremos outro método logo abaixo desse, e depois é só pegar o endereço dele e subtrair do endereço da rotina “RemoteFunction”.
Então declare o procedimento :

procedure RemoteFunctionEnd; stdcall;
begin;
end;

E como ja foi dito nos precisaremos de privilégios de DEBUG então declare a função.

procedure ChangePrivilege(szPrivilege: PChar; fEnable: Boolean);
var
NewState: TTokenPrivileges;
luid: TLargeInteger;
hToken: THandle;
ReturnLength: DWord;
begin
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken);
LookupPrivilegeValue(nil, szPrivilege, luid);

NewState.PrivilegeCount := 1;
NewState.Privileges[0].Luid := luid;
if (fEnable) then
NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
NewState.Privileges[0].Attributes := 0;

AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, ReturnLength);
CloseHandle(hToken);
end;

Pronto, agora só falta montar a função final, mas depois de tudo isso, para quem realmente entendeu a lógica fica fácil.

pprocedure Inject(process, dll, code: string);
var
PID, hProcess, ThreadId, ThreadHandle: Cardinal;
RemoteData,RemoteFunc,LibFileName,ProcName: pointer;
Parametros: TInjectParams;
begin
//Pega o Handle do processo
PID:=GetProcess(Process);
//Seta o privilégio de debug
ChangePrivilege(‘SeDebugPrivilege’, True);

//Abre o processo
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID);

//Define os parâmetros que serão usados para executar a procedure
LibFileName:=WriteString(hProcess, dll);
ProcName:=WriteString(hProcess, code);
Parametros.LoadLibrary:=GetProcAddress(GetModuleHandle(‘kernel32’), ‘LoadLibraryA’);
Parametros.LibName:=LibFileName;
Parametros.GetProcAddress:=GetProcAddress(GetModuleHandle(‘kernel32’), ‘GetProcAddress’);
Parametros.ProcName:=ProcName;

//Abre um novo espaço de memória para guardar os parâmetros
RemoteData:=WriteData(hProcess, sizeof(Parametros), @Parametros);

//Abre um novo espaço de memória para guardar a procedure
RemoteFunc:=WriteData(hProcess, integer(@RemoteFunctionEnd) – integer(@RemoteFunction), @RemoteFunction);

//Cria a thread que executará a procedure
ThreadHandle:=CreateRemoteThread(hProcess, nil, 0, RemoteFunc, RemoteData, 0, ThreadId);
WaitForSingleObject(ThreadHandle, 3000);

//Libera as alocações de memórias criadas
VirtualFreeEx(hProcess,LibFileName,0,MEM_RELEASE);
VirtualFreeEx(hProcess,ProcName,0,MEM_RELEASE);
VirtualFreeEx(hProcess,RemoteFunc,0,MEM_RELEASE);
VirtualFreeEx(hProcess,RemoteData,0,MEM_RELEASE);
end;

Agora chegou a parte que você ira realizar o code injection.
Como ja foi dito precisaremos de uma DLL com uma função que seja exportada então salve todo o seu projeto e crie um novo projeto de DLL.vou mostrar como ficou a minha dll de testes

library testdll;

uses
Windows,
SysUtils,
Classes;

{$R *.res}

procedure MsgBox;
begin
MessageBox(0,’Funcionou’,’Code Injection bem sucedido’,MB_OK+MB_ICONINFORMATION);
end;
exports
MsgBox;
begin
end.

Então agora é só no seu projeto do Injector você usar a função.

Inject('notepad.exe','C:\Dev\CodeInjection\testdll\testdll.dll','MsgBox');

Agora pra quem não entendeu direito,ou não quer nem ler e quer tudo pronto eu coloquei um link com a source do injector e da testdll
http://www.4shared.com/file/101714263/63913ea/CodeInjection.html

Créditos: R0DR1G0.

VN:F [1.9.8_1114]
Rating: 6.9/10 (13 votes cast)
VN:F [1.9.8_1114]
Rating: -3 (from 5 votes)
Fazendo o seu Code Injection, 6.9 out of 10 based on 13 ratings
  • Vivaldi

    q bosta

    VA:F [1.9.8_1114]
    Rating: 1.0/5 (1 vote cast)
    VA:F [1.9.8_1114]
    Rating: -1 (from 1 vote)
  • Vagalume

    Créditos: R0DR1G0.

    tem certeza que foi vc mesmo q criou isso?
    mais antigo q andar para frente.
    pelo menos credite às fontes de onde tirou isso, é o mínimo esperado, se desejas ter ética.

    VA:F [1.9.8_1114]
    Rating: 1.0/5 (1 vote cast)
    VA:F [1.9.8_1114]
    Rating: -1 (from 1 vote)