elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  castiar un thiscall
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] 3 Ir Abajo Respuesta Imprimir
Autor Tema: castiar un thiscall  (Leído 5,734 veces)
dewolo

Desconectado Desconectado

Mensajes: 83


Ver Perfil
Re: castiar un thiscall
« Respuesta #10 en: 1 Octubre 2011, 02:25 am »

http://foro.elhacker.net/net/inyeccion_dll_sin_dll_by_e0n_problema_edicion_de_memoria_convertir_a_c-t267355.0.html

http://www.infomalware.net/t62-inyeccion-de-codigo-sin-dll

si con dll ya esta hecho pero es mucho mas facil, y como encontre el codigo este se me ocurrio hacerlo de esta forma... como es por aprendizaje nada mas ..
supongamos que estan las 3 funciones en la memoria remota (A,B y myHook), Inyectada ya fue copiada, pero el problema es myHook porque las 3 van a transformarse en 3 punteros a funciones:
Código:
struct EstructIny
{
        TipoCT pCT;
        TipoS pSleep;

        //esto no sirve porque no son direcciones remotas sino locales
        /*
        void WINAPI myHook(int i);
        void B();
        static DWORD WINAPI Func(LPVOID lpParameter);*/

        //estos punteros a funciones deben guardar direcciones remotas de las funciones
        TipoMH pmyHook;// =&myHook
        TipoMH Orig_myHook;
        TipoB pB;// =&B
        TipoFunc pFunc;// =&Func
};

///Si estan afuera de la struct
//
void WINAPI myHook(int i)
{
      //El problema es myHook porque necesita llamar algunas funciones de la struct
      //como pSleep o pLoadLibrary, pGetModuleHandle, etc
      //y aparte debe retornar la direccion original de la api en cuestion y dicha direccion
      //es remota tambien

      //y siendo Orig_myHook miembro de la struct y myHook no siendolo se complica
      //porque no puedo modificar la definicion de myHook porque es el reemplazo de una api
     //osea no puedo agregar argumentos , etc entonces myHook deberia estar dentro de la struct
    //pero entonces como va a ser copiada por separado  :huh:

      Orig_myHook(i);
}
void B()
{
}
static DWORD WINAPI Func(LPVOID lpParameter)
{
        EstructIny *ptrThis = (EstructIny*)lpParameter;
        ptrThis->pSleep(2000);    
        return 0;
}


//SI son parte de la struct (punteros a funciones en la struct, pero con direcciones locales)
/*
void WINAPI EstructIny::myHook(int i)
{
      Orig_myHook(i);
}
void EstructIny::B()
{
}
static DWORD WINAPI EstructIny::Func(LPVOID lpParameter)
{
        EstructIny *ptrThis = (EstructIny*)lpParameter;
        ptrThis->pSleep(2000);    
        return 0;
}*/

/////

//La función que inyectaremos (Esta ya esta en el otro proceso)
DWORD Inyectada ( EstructIny *data)
{
      data->pCT(NULL, 0, (LPTHREAD_START_ROUTINE)data->Func, data, 0, NULL);
      return 0;
}
osea lo que no entiendo es como asignarle al myHook remoto el valor de retorno, aparte de que me doy cuenta de lo complicado del metodo sin embargo ya es tarde para dejarlo XD

EDITADO
asi es tal cual el codigo de eon solo que usa messagebox solamente pero calculado localmente
Código:

//Función que nos devuelve un DWORD con la dirección de una api
DWORD GetAddress(char*module, char*function)
{
HMODULE dh = LoadLibrary(module);
DWORD pf = (DWORD)GetProcAddress(dh,function);
FreeLibrary(dh);
return pf;
}


//La función inyectora
void Inyectora()
{
int      pid;                   // Este es el pid del proceso en el que nos queremos inyectar
HANDLE  proc;                   // El handle del proceso en el que inyectaremos
EstructIny    dat;     // El tipo de dato de la estructura
DWORD    TamFun;                // El tamaño de la función a inyectar
void*esp;                   // Lugar de memoria donde copiaremos nuestra función

HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //Obtenemos el pid
PROCESSENTRY32 procinfo = { sizeof(PROCESSENTRY32) };
while(Process32Next(handle, &procinfo))
{
 if(!strcmp(procinfo.szExeFile, "notepad.exe"))
 {
 CloseHandle(handle);
          pid = procinfo.th32ProcessID;
 }
}
CloseHandle(handle);

//Abrimos el proceso en el que nos inyectaremos
proc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);

//---------------------------
//Metemos la dirección de la api en la estructura llamando a la función GetAddress
        //estas son direcciones locales!
// dat.pCreateThread = (CreateThread_t)GetAddress("KERNEL32.DLL", "CreateThread");
// dat.pSleep = (Sleep_t)GetAddress("KERNEL32.DLL", "Sleep");
//--------------------------------------


//Reservamos espacio para nuestra estructura en el proceso a inyectar y la escribimos
EstructIny*dat_ = (EstructIny*)VirtualAllocEx(proc, 0, sizeof(EstructIny), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(proc, dat_, &dat, sizeof(EstructIny), NULL);

//Calculamos el tamaño de la función a inyectar
TamFun = (long unsigned int) Inyectora - (long unsigned int)Inyectada;

//Reservamos espacio para la función, escribimos en él y creamos un hilo
esp = VirtualAllocEx(proc, 0, TamFun, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(proc, esp, (void*)Inyectada, TamFun, NULL);
CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE) esp, dat_, 0, NULL);
}



« Última modificación: 1 Octubre 2011, 02:42 am por dewolo » En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: castiar un thiscall
« Respuesta #11 en: 1 Octubre 2011, 02:44 am »

Es muy tarde (casi 3 AM) para seguir intentado hacerlo asi ... fijate que el ejemplo de esos hilos es MUCHO mas simple de lo que vos estas tratando de hacer.

Si tuvieras una DLL no tendrias este problema:
1) Las funciones de la API estarian en tu tabla de importacion
2) Cualquier informacion que necesitaras compartir seria una variable global

Lo complicado es establecer algo que cualquier funcion hookeada pueda usar para obtener el puntero a la estructura. Normalmente uno podria usar un TLS pero depende de una variable global que no podes tener ...

Sinceramente lo unico que se me ocurre en este momento es que uses un valor hardcodeado para el puntero y sobreescribas la parte de la funcion que lo contiene antes de arrancar el primer hilo ...

Supongamos que:
Código
  1. extern "C" void B()//B solo quiere la direccion de myHook
  2. {
  3.        EstructIny *ptrThis = (EstructIny*)0x89ABCDEF;
  4. ptrThis->Sleep_fn(5000);
  5. }

Entonces la idea seria que reemplazaras ese valor por data ...  poder se puede pero la verdad es una enorme perdida de tiempo.


En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
dewolo

Desconectado Desconectado

Mensajes: 83


Ver Perfil
Re: castiar un thiscall
« Respuesta #12 en: 1 Octubre 2011, 03:00 am »

suponemos que en la struct principal tenemos los punteros a funciones de myHook, B y de Func, y por su puesto tambien de Orig_myHook (porque es el valor de retorno de myHook), suponemos que las 3 funciones fueron escritas en la memoria remota osea (myHook, B y Func), entonces yo lo qye necesito es tener un hilo que se ejecute en el proceso remoto y que me inicialize los 4 punteros antes mecionados, los primeros 3 corresponden a las funciones mapeadas digamos, y el cuarto corresponde a una direccion que se encuentra en el proceso remoto, por decir "loadlibrary", usando getprocaddress como en el ejemplo de eon. la pregunta seria los pasos en el tiempo digamos en qe momento deberia inicializar los 4 punteros, y si debo usar ese mismo hilo. obviamente deben ser inicializados despues de la copia de las 3 funciones claramente.

lo que se deduce de esto es que solo seran miembros de la struct los 4 punteros a funciones, las definiciones de las 3 funciones no son de la struct sino que son separadas y son copiadas a parte.

esto esta bien en teoria?

EDITADO
me faltaba el peqenio detalle de que si myHook no es de la struct no accede al puntero a funcion Orig_myHook para poder retornar a la original, se debe implementar algun truqillo como el que mostraste.. asi no es necesario agregar argumentos ni modificar la declaracion del hook



« Última modificación: 1 Octubre 2011, 03:04 am por dewolo » En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: castiar un thiscall
« Respuesta #13 en: 1 Octubre 2011, 03:18 am »

Todo lo podes escribir desde el inyector, incluso el mismo truco ese, mientras lo hagas antes de crear el hilo es suficiente.
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: castiar un thiscall
« Respuesta #14 en: 1 Octubre 2011, 12:47 pm »

Otro truco que se me ocurrio, en este caso lo probe y funciono  :xD

Sabiendo que podemos obtener estos valores con intrinsics (con lo cual funcionarian en x64 tambien):

http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
http://en.wikipedia.org/wiki/Process_Environment_Block

PostProcessInitRoutine
A pointer to a callback function called after DLL initialization but before the main executable code is invoked


Esto solo se usa (si se usa claro) antes de que el ejecutable arranque asi que podemos secuestrarlo  ;D

Esta hardcodeado pero definiendo correctamente la estructura _PEB podrias hacerlo portable con un par de ifdefs (para definir la estructura y para el intrinsic de acuerdo al tamaño de puntero: q/dword), en Inyectada:

Código
  1. PULONG_PTR pPeb = (PULONG_PTR)__readfsdword(0x30);
  2. pPeb += 0X53; //PostProcessInitRoutine
  3. *pPeb = (ULONG_PTR)data;

Código
  1. extern "C" void B()
  2. {
  3. PULONG_PTR pPeb = (PULONG_PTR)__readfsdword(0x30);
  4. pPeb += 0X53; //PostProcessInitRoutine
  5. EstructIny *ptrThis = (EstructIny*)*pPeb;
  6. ptrThis->Sleep_fn(5000);
  7. }
« Última modificación: 1 Octubre 2011, 12:51 pm por Eternal Idol » En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
dewolo

Desconectado Desconectado

Mensajes: 83


Ver Perfil
Re: castiar un thiscall
« Respuesta #15 en: 1 Octubre 2011, 15:18 pm »

gracias amigo por tu dedicacion, pero algunos de esos trucos es la primera ves que los miro XD
sin dejarlos de lado, me podes decir porque este code no funcionaria, es solo una prueba de concepto y ni compila pero necesitaria entender algunos puntos sobre el, antes de avanzar
el codigo ha cambiado un poco eso si, pero con este ejemplo es mas figurado y si entendes ingles que me parece que si porque me recomendaste textos en ingles, etnonces vas a endender los comentarios :laugh:

lo que quisiera saber sobre este code es especificamente porque no funcionaria o quedaria sin comunicacion entre el proceso local y remoto, osea si en algun momento alguna direccion es invalida a causa de esa desconexion. luego voy a pasar a los trucos :)

Código
  1. /*---------------------------*/
  2. typedef struct _PROCESS_info
  3. {
  4.       DWORD pid;
  5.       char* name;
  6.       HANDLE oHandle;
  7. } PROCESS_info, *PPROCESS_info;
  8.  
  9. /*---------------------------*/
  10.  
  11. //Structure who will be copied
  12. struct lib_struct
  13. {
  14.           /* these are from kernel32.dll that is at a static virtual address */
  15.           tLoadLibrary pLoadLibrary;//---------> pointer to function
  16.           tGetProcAddress pGetProcAddress;//---------> pointer to function
  17.           tGetModuleHandleA pGetModuleHandleA;//---------> pointer to function
  18.           tCreateThread pCreateThread;//---------> pointer to function
  19.           /*------------------------------------*/
  20.  
  21.           /* from msvcrt.dll */
  22.           tSleep pSleep;//---------> pointer to function
  23.           tSrand pSrand;//---------> pointer to function
  24.           tRand; pRand;//---------> pointer to function
  25.  
  26.           /* from opengl32.dll */
  27.           tglBegin pglBegin;//---------> pointer to the hook function
  28.           tglBegin Orig_glBegin;//---------> return address for the hook function
  29.  
  30.  
  31.           char str_glBegin[128];//will hold the name of the function
  32.           char strOpengl32[MAX_PATH];//will hold the name of the DLL
  33. };
  34.  
  35. /*---------------------------*/
  36. //Function who will be copied in the remote process
  37. void APIENTRY New_glBegin(GLenum m)
  38. {
  39.         lib_struct *Plib;
  40.  
  41.         Plib->Orig_glBegin(m);
  42. }
  43.  
  44. /*---------------------------*/
  45. //Function who will be copied in the remote process
  46. static DWORD WINAPI HookFunction(LPVOID libs_struct)
  47. {
  48.            lib_struct *Plib=(lib_struct)libs_struct;
  49.  
  50.            HMODULE load_lib = Plib->pLoadLibrary(plib->strOpengl32);
  51.  
  52.           //Initialize the original address for glBegin hook return
  53.           Plib->Orig_glBegin= (tglBegin)Plib->pGetProcAddress(load_lib, plib->str_glBegin);
  54.  
  55.           /* detour on glBegin at remote process (pseudocode) */
  56.  
  57.           *glBegin=Plib->pglBegin;//pglBegin is the address of the hook function in the remote process
  58.  
  59.           return 0;
  60. }
  61.  
  62. /*---------------------------*/
  63. //Function who will be copied in the remote process
  64. static int WINAPI test_func(LPVOID libs_struct)
  65. {
  66.             lib_struct *Plib=(lib_struct)libs_struct;
  67.  
  68.            //this function will be copied in the remote process; I would like to start a thread here
  69.           //and the hooking thread will hook glBegin.
  70.           //in order to do that I need to copy New_glBegin and init pointer pglBegin to locate it
  71.           //in the remote process
  72.           //I also need to init Orig_glBegin so the hook can return to the original glBegin
  73.           //but the pointer value has to be the glBegin address in the remote process
  74.  
  75.            PLib->pCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Plib->HookFunction, libs_struct, 0, NULL);
  76.  
  77.            return 1;
  78. }
  79.  
  80. /*---------------------------*/
  81.  
  82. static void __declspec(naked) end_proc() {}
  83.  
  84. /*---------------------------*/
  85.  
  86. int main()
  87. {
  88.          lib_struct libs;
  89.  
  90.           //PASO 1
  91.           PROCESS_info process;
  92.           process.pid = GetProcessPid(process.name
  93.           printf("[*] Getting full access...");
  94.  
  95.           //PASO 2
  96.           libs.pLoadLibrary = (pLoadLibrary)GetProcAddress(kernel32, "LoadLibraryA");
  97.           libs.pGetProcAddress = (pGetProcAddress)GetProcAddress(kernel32, "GetProcAddress");
  98.           strcpy(libs.strOpeng32, "opengl32.dll");
  99.           strcpy(libs.str_glBegin, "glBegin");
  100.           printf("[*] Filling up lib_struct...");
  101.  
  102.           //PASO 3
  103.           process.oHandle = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, process.pid);
  104.           printf("[*] Opening process %s...", process.name);
  105.  
  106.           //PASO 4
  107.           DWORD proc_size = (DWORD)end_proc - (DWORD)test_func;
  108.           printf("[*] Function size: %d\n", proc_size);
  109.  
  110.           //PASO 5
  111.           LPVOID [b]glbeginhook_addr[/b] = VirtualAllocEx(process.oHandle, NULL, proc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  112.           LPVOID [b]hookfunction_addr[/b] = VirtualAllocEx(process.oHandle, NULL, proc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  113.           LPVOID [b]testfunc_addr[/b] = VirtualAllocEx(process.oHandle, NULL, proc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  114.  
  115.           printf("[*] Allocating memory space in %s for test_func...", process.name);
  116.  
  117.  
  118.           //PASO 6 (getting the addreses where I alloc'ed memory for New_glBegin)
  119.           [b]libs.Orig_glBegin[/b] = *(tglBegin)glbeginhook_addr;
  120.           printf("[*] Filling up lib_struct again!!!!! ...");
  121.  
  122.           //PASO 7
  123.           LPVOID struct_addr = VirtualAllocEx(process.oHandle, NULL, sizeof(libs), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  124.           printf("[*] Allocating memory space in %s for lib_struct libs...", process.name);
  125.  
  126.           //PASO 8 (writting the 3 functions)
  127.           WriteProcessMemory(process.oHandle, [b]glbeginhook_addr[/b], New_glBegin, proc_size, &written_bytes);
  128.           WriteProcessMemory(process.oHandle, [b]hookfunction_addr[/b], HookFunc, proc_size, &written_bytes);
  129.           WriteProcessMemory(process.oHandle, [b]testfunc_addr[/b], test_func, proc_size, &written_bytes);
  130.  
  131.           printf("[*] Writing \'test_func\' in %s...", process.name);
  132.  
  133.           //PASO 9 (writting the structure)
  134.           WriteProcessMemory(process.oHandle, struct_addr, &libs, sizeof(libs), &written_bytes);
  135.           printf("[*] Writing \'lib_struct libs\' in %s...", process.name);
  136.  
  137.           //PASO 10
  138.           DWORD thread_id;
  139.           HANDLE remote_thread = CreateRemoteThread(process.oHandle, NULL, 0, (LPTHREAD_START_ROUTINE)func_addr, struct_addr, 0, &thread_id);
  140.           printf("[*] Creating remote thread for test_func in %s...", process.name);
  141.  
  142.           //PASO 11
  143.           printf(" done\n[*] Thread id: %d\n", thread_id);
  144. }
  145. [/quote]
  146.  
  147. obviamente el primer problema a primera impresion es en New_glBegin porque no tiene la address de la struct como para retornar Orig_glBegin :(
  148.  
« Última modificación: 1 Octubre 2011, 17:46 pm por madpitbull_99 » En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: castiar un thiscall
« Respuesta #16 en: 1 Octubre 2011, 17:27 pm »

Al no estar ni los typedefs se hace MUY pesado de compilar asi que solo le di una ojeada. El detour no es ni de lejos tan simple como pareceria en el codigo ... para poder acceder desde el hook a la estructura tenes que hacer algun truco.

PD. No necesariamente MSVCRT.dll estara cargada en el proceso remoto.
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
dewolo

Desconectado Desconectado

Mensajes: 83


Ver Perfil
Re: castiar un thiscall
« Respuesta #17 en: 1 Octubre 2011, 18:32 pm »

te lo mande por pm :)

y lo de msvcrt.dll se puede hacer loadlibrary en el proceso remoto y cargarla?
aparte me entro una duda sobre esa libreria porque existen tambien msvcrt6 y msvcrt7, etc

y lo del truco no compila sabes porque no permite ese simbolo el __readfsdword  :-[

EDITADO
claro era para visual studio 2005 en adelante XD
http://msdn.microsoft.com/en-US/library/3887zk1s(v=VS.80).aspx


« Última modificación: 1 Octubre 2011, 18:59 pm por dewolo » En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: castiar un thiscall
« Respuesta #18 en: 1 Octubre 2011, 18:59 pm »

Si, se puede aunque Sleep la tenes en la API y dudo que sean necesarios numeros aleatorios  ;D

Actualiza el compilador y podras usar __readfsdword.
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
dewolo

Desconectado Desconectado

Mensajes: 83


Ver Perfil
Re: castiar un thiscall
« Respuesta #19 en: 1 Octubre 2011, 19:04 pm »

Si, se puede aunque Sleep la tenes en la API y dudo que sean necesarios numeros aleatorios  ;D

Actualiza el compilador y podras usar __readfsdword.

JAJAJAJAJAJAJ es que iba a hacer otra cosa en primer lugar con srand y rand  :rolleyes:

EDITADO
los tamaños de las primeras dos funciones no son correctos alguien sabe como es el calculamiento ?
por ejemplo para TestFunc
Código:
DWORD proc_size1 = (DWORD)end_proc - (DWORD)TestFunc;

pero para HookFunc
Código:
DWORD proc_size2 = (DWORD)end_proc - (DWORD)TestFunc - (DWORD)HookFunc;

seria asi ?
« Última modificación: 1 Octubre 2011, 20:16 pm por dewolo » En línea

Páginas: 1 [2] 3 Ir Arriba Respuesta Imprimir 

Ir a:  
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines