Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Cargar dinamicamente una dll en VB6 (https://www.clubdelphi.com/foros/showthread.php?t=87415)

aguml 31-12-2014 17:58:27

Cargar dinamicamente una dll en VB6
 
Mi duda es que quiero cargar una dll que he creado pero quiero cargarla dinamicamente en un binario que tengo de VB6, o sea, no tengo los fuentes de dicho binario.
Si fuese en C o C++ podriamos usar LoadLibrary, GetModuleHandle, GetProcAddress, y FreeLibrary para cargar la dll, usar sus funciones y por ultimo liberar la dll.
En VB6 por lo visto no puedo hacer eso ni desde un depurador injertando el codigo a mano ya que no aparecen referencias para esas funciones y si pongo los calls a fuego, por ejemplo un "call LoadLibrary", solo funcionaria en mi maquina. ¿De que manera puedo hacer eso en un binario de VB?

aguml 31-12-2014 19:10:13

Se me olvido decir que en la Import Table no hay referencia a Kernel32.dll por lo que no está en la carga inicial y no se tiene acceso a sus funciones.

escafandra 02-01-2015 22:45:57

He estado fuera de casa en estos días y no he podido contestar.

No deberías tener problemas para inyectar una dll en cualquier proceso que corra en windows, siempre que respetes la compilación en 32bits ó 64 bits, según sea el caso. Aquí tienes una forma de hacerlo. Es independiente del lenguaje original, por lo tanto es igual que el binario provenga de BV u otro.

El hecho de que ciertas APIs no figuren en la IAT del proceso a inyectar, no quiere decir que no las puedas usar. Todo proceso carga Kernel32.dll, para más curiosidad revisa esto: Shellcode en C compatible con distintas inyecciones

Saludos.

aguml 03-01-2015 16:53:01

al final lo hice de otra manera. Como la aplicacion corre dentro de un loader debugger, lo que hago es usar VirtualAllocEx y solicito memoria para copiar las funciones de la dll. Luego pongo unos bps donde deseo y desde esas zonas injerto los push necesarios, el call correspondiente y el retn. De todos modos me interesa mucho tu codigo pero tengo una duda. En xp si en un pc llamas a una api, siempre obtendrás el mismo hmodule pero, segun tengo entendido, a partir de Vista ya no es asi y puede cambiar entre ejecuciones y veo que LoadLibrary lo obtienes en tu proceso ¿No daria problemas en Vista/7/8?

escafandra 03-01-2015 18:27:37

Las inyecciones en win32 sea WinXP, Vista, Win7 o Win8 funcionan localizando la API LoadLibrary, o cualquiera desde el proceso inyector. Pero tienes razón en que MS$ puede cambiar la política de la localización de las direcciones de la API. Para solventar el problema, realicé este ejemplo de shellcode que localiza el BaseAddress de kernel32.dll. Seoane lo hizo de esta otra manera. Así conoceremos las direcciones de las API desde el mismo proceso anfitrión, y no desde el inyector.


Saludos.

aguml 03-01-2015 23:30:46

claro,lo que varia es la posicion base donde se carga la dll pero si puedes ejecutar esas funciones desde el anfitrion pues resuelves el problema. Ahora mismo estoy encamado con fiebre pero cuando me encuentre mejor los miro con mas detenimiento ya que en delphi no me entero mucho. Otra cosa amigo, si uso VirtualAllocEx, cuando se cierra la aplicacion a la que le he asignado la memoria ¿Se libera sola la memoria o tengo que hacerlo yo a mano con VirtualFreeEx? Segun veo con Cheat engine, cuando se cierra la aplicacion la memoria se vuelve inaccesible pero no lo tengo claro.

escafandra 04-01-2015 00:28:20

Lo suyo y lo limpio es liberar la memoria cuando ya no la quieres.

Saludos.

aguml 13-01-2015 16:00:35

Bueno, al final lo que estaba haciendo no me iba bien del todo ya que en unas funciones de la dll funcionaba y en otras crasheaba creo que porque como solo copio las funciones pues al ejecutarse supongo que buscaba alguna cosa de la dll y booom.
Lo estoy intentando pasar todo para usarlo con lo que pusiste y de momento para cargar la dll tengo esto:
Código PHP:

void __fastcall TFormMain::OnEntryPoint(DWORD Address)
{
   
// Inyecta la dll
   
AnsiString dll "DLLHack.dll";
   
HANDLE  hThread 0;
   
DWORD   ExitCode 0;
   
LPTHREAD_START_ROUTINE hLib;

   
// Localizo memoria en el espacio de direcciones de la víctima
   
void*  Buffer VirtualAllocEx((HANDLE)Depurador->GetHProcess(), NULLdll.Length()+1MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);

   if(
Buffer){
      if(
Depurador->WriteMemory((unsigned long)Bufferdll.c_str(), dll.Length()+1)){
         
hLib = (LPTHREAD_START_ROUTINE)Depurador->GetAddressAPIByName("Kernel32.dll""LoadLibraryA");
         if(
hLib){
            
hThread =:: CreateRemoteThread(Depurador->GetHProcess(), NULL0hLibBuffer00);
            if(
hThread){
               
WaitForSingleObject(hThreadINFINITE ); // Espero a que se cree el Thread
               
GetExitCodeThread(hThread, &ExitCode);   // Termino el Thread
               
CloseHandle(hThread);                    // Cierro el Handle hThread
            
}
         }
      }
      
// libero la memoria localizada...
      
VirtualFreeEx((HANDLE)Depurador->GetHProcess(), Buffer0MEM_RELEASE); // Libero memoria
   
}


Como corre dentro de un depurador, tengo metodos para obtener la direccion de las apis dentro del proceso y otras cosas mas.
El problema que tengo es que se queda congelado en el WaitForSingleObject aunque si lo miro con el Cheat Engine puedo ver como se ha creado el hilo. ¿que puedo hacer para solucionar eso?

escafandra 13-01-2015 19:22:27

Probablemente es un problema en el depurador, intenta esto:
Código PHP:

.............................
         if(
hLib){
            
CloseHandle(CreateRemoteThread(Depurador->GetHProcess(), NULL0hLibBuffer00));
         }
........................ 


Saludos.

aguml 13-01-2015 21:24:16

lo he solucionando injertando en el oep el push y el call loadlibrary y en la siguiente linea pongo un bp. Arranco y cuando para en el bp ya tengo la dll cargada asi que restauro los bytes originales, quito el bp y posiciono a eip en el oep y ya corre con la dll. De todos modos mañana probaré lo que me indicas a ver que pasa.

aguml 14-01-2015 01:35:50

una cosa, al estar parado en un evento, al ejecutar el codigo anterior creo que no tendria efecto hasta que arranque ¿No? Se supone que el codigo lo ejecuto dentro del evento y mientras tanto el proceso se congela y con el todos sus hilos. Entonces si es asi el nuevo hilo estaria congelado con lo cual no se ejecutaria hasta que salga del evento ¿No? El hilo aparecia como creado con lo que se me ocurre poner un bp en la siguiente linea y en ese evento poner el waitforsingleobject. De todos modos el modo que uso ahora mismo funciona aunque es algo chapuzas pero bueno.

escafandra 14-01-2015 02:04:56

Exacto, por eso quité el WaitForSingleObject.

Saludos.

aguml 14-01-2015 18:50:15

Amigo como me indicas tengo un inconveniente.
Justo despues de cargar la dll tengo que obtener una serie de punteros a las funciones de la dll y si no pongo el WaitForSingleObject no funciona.
Como yo lo hago si funciona porque como se ejecuta el LoadLibrary y luego paro en la siguiente linea pues ya puedo obtener la info de la dll sin problemas.

escafandra 15-01-2015 11:48:33

En ese caso está claro que no puedes eliminar WaitForSingleObject, pero no pongas un bp en esa línea de código ni depures el thread que se crea para cargar la dll.


Saludos.

aguml 18-01-2015 00:43:46

La clase que creamos se usa para depurar un proceso y si paras en un evento se detiene tanto el hilo principal como todos sus hilos. ¿Como hago para que estando en el evento reanudar uno de sus hilos? Con CreateRemoteThread creo que se obtenia el identificador del nuevo thread pero aunque le indiques que se ejecute al crearse se queda congelado y no se me ocurre nada para hacer que el nuevo hilo se ejecute. En OllyDbg hay un plugin que permite añadir o quitar un modulo pero no se como lo hace aunque te puedo decir que como mi ordenador va de pena de lento a veces se ve como cambia de zona y ejecuta un loadlibrary aunque lo hace tan rapido que ni se ve. Y luego vuelve al lugar donde estaba en el codigo.

escafandra 18-01-2015 00:57:48

Para después de la vuelta de WaitForSingleObject.

Saludos.

aguml 18-01-2015 21:43:59

pues no se me ocurre como hacer eso ya que tendria que hacer la carga internamente y en el evento OnLoadDll de mi clase tendria que comprobar si la dll es la que intento cargar y el problema es que el hilo principal mientras tanto correria y no estaria parado.


La franja horaria es GMT +2. Ahora son las 17:01:34.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi