FTP | CCD | Buscar | Trucos | Trabajo | Foros |
#1
|
|||
|
|||
Inyeccion DLL[Duda]
Hola
Este es mi primer post en el foro. Estoy estudiando la inyección de DLL en un proceso. Hasta el momento he conseguido hacer un Hook (metodo trampolin) a un MessageBox. La duda que tengo es la siguiente. Yo tengo un programa de este estilo, pero con mucho más código: Código:
program Project2; {$APPTYPE CONSOLE} uses SysUtils,Windows; Var i: Integer; Cuenta: String; begin { TODO -oUser -cConsole Main : Insert code here } Cuenta := ''; For i:=0 To 10 Do Begin Cuenta := Cuenta + IntToStr(i); End; MessageBox(0,PAnsiChar(Cuenta),'Cuenta',64); end. Espero me puedan ayudar. Muchísimas gracias de antemano. Un saludo |
#2
|
||||
|
||||
En el foro tienes ejemplos de como inyectar una dll. De entrada, necesitas tener una dll que inyectar y tu código no lo es.
Saludos. |
#3
|
|||
|
|||
Hola escafandra
Gracias por tu respuesta. La DLL que quiero inyectar es esta: Código:
library Sumar; {$APPTYPE CONSOLE} uses SysUtils,Windows; Var i: Integer; Cuenta: String; begin { TODO -oUser -cConsole Main : Insert code here } Cuenta := ''; For i:=0 To 10 Do Begin Cuenta := Cuenta + IntToStr(i); End; MessageBox(0,PAnsiChar(Cuenta),'Cuenta',64); end. Ahora mismo estoy trabajando con este codigo, que me funciona en Windows XP: Código:
procedure InjectDll(PID: dword; DLL: pChar); var BytesWritten, hProcess, hThread, TID: Cardinal; Parameters: pointer; pThreadStartRoutine: Pointer; begin // Abrimos el proceso hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID); // Creamos espacio en el proceso Parameters := VirtualAllocEx( hProcess, nil, Length(DLL)+1, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); // Escribimos en el proceso la ruta de nuestra DLL WriteProcessMemory(hProcess,Parameters,Pointer(DLL ),Length(DLL)+1,BytesWritten); // Obtenemos la direccion de LoadLibrary con GetProcAddress pThreadStartRoutine := GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'); // Creamos un Thread en el proceso remoto que ejecute nuestra dll hThread := CreateRemoteThread(hProcess, nil, 0, pThreadStartRoutine, Parameters, 0, TID); // Cerramos el hProcess abierto CloseHandle(hProcess); end; procedure TForm1.FormCreate(Sender: TObject); begin InjectDll(Aqui pongo el PID del notepad o de la calculadora,PAnsiChar('C:\Sumar.dll')); end; Tengo unas dudas, ¿porque obtenemos la dirección de LoadLibrary? He leido el algun tutorial, pero no se porque motivo es, que este codigo no funciona en Sistemas Operativos de 64 bits. ¿Por que razon no funciona? Yo no le podido probar en sistemas operativos de 64 bits porque no tengo. Muchisimas gracias de antemano. Saludos |
#4
|
||||
|
||||
Aclarando dudas:
Estudia la API CreateRemoteThread, el 4 parámetro precisa un puntero a una función y el 5 es un puntero que se pasará a la dicha función. LoadLibrary es la API que se usa para cargar una dll en el proceso actual y usa un parámetro que es el nombre de la dll. La inyección se basa en obligar a otro proceso a cargar una dll, CreateRemoteThread hace esa función ejecutando en el proceso anfitrión LoadLibrary con el nombre de la dll que queremos inyectar. Por eso necesitamos conocer un puntero a Loadlíbrary y reservar memoria en el espacio de direcciones del priceso anfitrión para escribir el nombre de la dll que pasaremos a LoadLibrary. El truco se basa en que las direcciones de las APIs del sistema son idénticas para todos los procesos. Cita:
no se puede inyectar código compilado para 32bits en un proceso 64bits. Saludos. |
#5
|
||||
|
||||
Perdón por la errata:
Cita:
Un proceso compilado para 64bits no puede usar una dll compilada para 32bits, por lo tanto no se puede inyectar código compilado para 32bits en un proceso 64bits. Saludos. |
#6
|
|||
|
|||
Hola escafandra
Referente a la API CreateRemoteThread me ha quedado todo muy claro. Ahora si lo que entiendo muy bien. Sinceramente, muchisimas gracias escafandra. El tema de 32 bits y 64 bits también, creo , que me ha quedado claro. Esto es lo que he entendido: - Para utilizar una DLL en 32 bits, se deberá crear esa DLL en una arquitectura 32 bits. Ejemplo: Windows Vista 32 bits,... - Para utilizar una DLL en 64 bits, se deberá crear esa DLL en una arquitectura 64 bits. Ejemplo: Windows 7 64 bits,... Espero haberlo entendido bien. Una vez entendido el tema de la inyección DLL bastante bien, quería aprender el tema de Hook API porque aunque algo hecho todavía no lo entiendo del todo bien. El código con el que he estado trabajando es el siguiente(Autor: Robert Milan ): Aplicación Test: Código:
procedure TForm1.Button1Click(Sender: TObject); begin MessageBoxA(Self.Handle, // Application Handle PAnsiChar(AnsiString(Edit1.Text)), // Message in messagebox PAnsiChar(Self.Caption), // Title of messagebox $00000040); // Information Icon end; Código:
procedure TForm1.Button1Click(Sender: TObject); begin InjectDLL('notepad.exe', Ruta de la DLL); end; function GetProcessIdByName(s : String) : Cardinal; var { Process Vars } hProcessSnap : THandle; PE32 : ProcessEntry32; begin { Init. Result } Result := 0; { Take a snapshot of all the processes in the system } hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap = INVALID_HANDLE_VALUE) then exit; { Size of the ProcessEntry32 Structure } PE32.dwSize := SizeOf(TProcessEntry32); { Unable to retreive information about the first process } if not (Process32First(hProcessSnap, PE32)) then begin PE32.dwSize := 0; CloseHandle(hProcessSnap); exit; end; { Iterate through the process list } while not (Process32Next(hProcessSnap, PE32) = false) do begin if (Lowercase(PE32.szExeFile) = Lowercase(s)) then begin Result := PE32.th32ProcessID; break; end; end; { Cleanup the ProcessEntry32 struct. } with PE32 do begin dwSize := 0; cntUsage := 0; th32ProcessID := 0; th32DefaultHeapID := 0; th32ModuleID := 0; cntThreads := 0; th32ParentProcessID := 0; pcPriClassBase := 0; dwFlags := 0; szExeFile := ''; end; { Freeup allocated memory } CloseHandle(hProcessSnap); end; function InjectDLL(Process: AnsiString; Dll: AnsiString) : Integer; var PID : Cardinal; { Process ID } hProcess : THandle; { Process Object } hThread : THandle; { Remote Thread Handle } dwThreadID : DWORD; { Remote Thread ID } BaseAddr : PChar; { Memory Address } BytesWritten : LongWord; { Total Bytes Written } begin { Search for process id } PID := GetProcessIdByName(Process); { Process wasn't found } if (PID = 0) then begin Result := -1; exit; end; { Something went wrong, we can't find the process } if (PID = 0) then begin Result := -1; exit; end; { Open the process } hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or { For Token, Exit code and more } PROCESS_CREATE_THREAD or { For CreateRemoteThread } PROCESS_VM_OPERATION or { For VirtualAllocEx/VirtualFreeEx } PROCESS_VM_WRITE, { For WriteProcessMemory } false, PID); { Allocate some extra memory in the target process } BaseAddr := PChar(VirtualAllocEx(hProcess, nil, strlen(PChar(DLL)) + 1 * sizeof(Char), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE)); { Inject dll into memory } if not (BaseAddr = nil) then begin WriteProcessMemory(hProcess, BaseAddr, PChar(DLL), Length(DLL), BytesWritten); end else begin { No need to continue, we couldn't write the dll into memory } Result := -1; exit; end; { Create a thread, force the process to load the dll } hThread := CreateRemoteThread(hProcess, nil, 0, GetProcAddress(LoadLibrary('Kernel32.dll'), 'LoadLibraryA'), BaseAddr, 0, dwThreadID); { Wait for the thread to execute } WaitForSingleObject(hThread, INFINITE); { Free allocated memory } VirtualFreeEx(hProcess, BaseAddr, 0, MEM_RELEASE); CloseHandle(hProcess); Result := 0; end; Código:
(************************************************************) (* Win32 API Hooking Library *) (* by Robert Milan (03/23/13) *) (************************************************************) (* This code is provided "as is" without express or *) (* implied warranty of any kind. Use it at your own risk. *) (************************************************************) library prjHook; uses Windows, SysUtils, StrUtils, Classes, Dialogs, Winsock; var { Original API } TMessageBoxA : function (Handle : hWnd; lpText : PAnsiChar; lpCaption : PAnsiChar; uType : Cardinal) : Integer; stdcall; {$R *.res} { Duplicate of the original api } function OMessageBoxA(Handle : hWnd; lpText : PAnsiChar; lpCaption : PAnsiChar; uType : Cardinal) : Integer; stdcall; begin { Here we will edit the api in any way that we want. } { Edit the message for the MessageBox } lpText := PAnsiChar('Message text edited!'); { Change the icon type to exclamation } uType := $00000030; { Call the original api } Result := TMessageBoxA(Handle, lpText, lpCaption, uType); end; { This function will take a api call from a dll and create a unconditional JMP to the functions address in this dll. If the "REAL" function address is "0x00AA0F00" and the address to our replacement is "0x00FFFFFF" then the JMP will replace a JMP right before we reach the "REAL" address to the replacement address. } // Example: InterceptAPI('USER32.dll', 'MessageBoxA', @OMessageBoxA, @TMessageBoxA); function InterceptAPI(lpModuleName : PAnsiChar; lpProcName: PAnsiChar; PCallBack : Pointer; var PTrampoline : Pointer) : Integer; stdcall; var hMod : HMODULE; FuncAddr : Pointer; FuncOrg : Pointer; dwProtect : DWORD; begin { Dynamic Link Library } hMod := GetModuleHandle(lpModuleName); if (hMod = 0) then begin Result := 0; exit; end; { Address to api function } FuncAddr := GetProcAddress(hMod, lpProcName); if (FuncAddr = nil) then begin Result := 0; exit; end; VirtualProtect(FuncAddr, 5, PAGE_WRITECOPY, dwProtect); GetMem(FuncOrg, 10); CopyMemory(FuncOrg, FuncAddr, 5); { Create a unconditional JMP to the address of our replacement api} Byte(Pointer(DWORD(FuncOrg) + 5)^) := $E9; DWORD(Pointer(DWORD(FuncOrg) + 6)^) := (DWORD(FuncAddr) - (DWORD(FuncOrg) + 5)); { Create a trampoline so that we can replace the replacement api back with the original } PTrampoline := FuncOrg; Byte(FuncAddr^) := $E9; DWORD(Pointer(DWORD(FuncAddr) + 1)^) := DWORD(PCallback) - (DWORD(FuncAddr) + 5); VirtualProtect(FuncAddr, 5, dwProtect, dwProtect); FlushInstructionCache(GetCurrentProcess(), Nil, 0); Result := 1; end; procedure DllMain(reason: integer); begin case reason of DLL_PROCESS_ATTACH: // DLL Loaded begin InterceptAPI('USER32.dll', 'MessageBoxA', @OMessageBoxA, @TMessageBoxA); end; DLL_PROCESS_DETACH: // DLL Unloaded begin // Do something while dll is being unloaded. end; end; end; { DllMain } begin { Set the dll entry point and call it } DllProc := @DllMain; DllProc(DLL_PROCESS_ATTACH); end. Mas o menos entiendo que hace el codigo y en que consiste la tecnica del trampolin. Pero tengo unas dudas: - Como se que $E9 hace referencia a JMP. - Y la operación inversa. Como sacar que "codigo hexadecimal" tiene JMP. Mirando google he visto otros codigos que hacen uso de la funcion SetWindowsHookEx, CallNextHookEx y UnhookWindowsHookEx para hacer un Hook. Quería saber la diferencia que hay entre hacer un hook con el metodo trampolin y el hacer el hook utilizando las 3 apis de arriba. Tengo un codigo que hacer un hook del 2º tipo, pero sinceramente no lo entiendo. Estudiando y leyendo, creo que la respuesta es que el metodo trampolin hace un hook INDIVIDUAL a una api de un UNICO proceso, mientras que con SetWindowsHookEx se hace un hook GLOBAL que es procesado por un UNICO proceso, pero sinceramente no estoy seguro de si es correcto lo que he dicho. Muchisimas gracias escafandra por la ayuda!!! Siento lo largo que me ha quedado el post y espero que me haya explicado con claridad. Saludos |
#7
|
||||
|
||||
Cita:
Cita:
Saludos. |
#8
|
|||
|
|||
Ok, Muchísimas gracias Escafandra!!
¿Y donde puedo mirar o como puedo saber que JMP es E9?¿Y saber que E9 es JMP? Un saludo |
#9
|
||||
|
||||
Cita:
El desensamblador de delphi también te serviría. También puedes consultar tablas de opcodes como esta. Saludos. |
#10
|
|||
|
|||
ok, muchísimas gracias escafandra!!
Seguro que me ayuda para entender mejor los opcodes. Saludos |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Inyeccion SQL | RebeccaGL | MySQL | 10 | 30-04-2012 17:15:43 |
ataques de inyección de sql | hogol | SQL | 5 | 17-10-2011 23:00:37 |
Formas de inyección de procesos | aeff | API de Windows | 8 | 27-10-2007 19:25:25 |
Inyeccion de sql | richy08 | PHP | 0 | 19-10-2007 01:08:41 |
evitar inyeccion de html | reevil | PHP | 2 | 21-12-2006 03:26:08 |
|