publicidade
publicidade
publicidade
publicidade
publicidade
publicidade
publicidade

Fazendo o seu Code Injection


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
Deixe seu Comentário:
Sem comentários »

0 comentários:

Postar um comentário

ORA VIVA, OLHA TEU COMENTARIO VALE MAIS DO QUE OURO PARA MIM, PRECISO DELE PARA MELHORAR A DISPONIBILIDADE DO BLOG.