Duda GetProcAddress

Iniciado por naderST, 5 Marzo 2013, 02:41 AM

0 Miembros y 1 Visitante están viendo este tema.

naderST

Buenas a todos, he visto varios códigos donde hacen algo como esto:


GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA");


Entiendo que obtiene la dirección de memoria de la función MessageBoxA, pero lo que no logro entender es cómo es que es la misma dirección para todos los procesos? No se si me explico bien, pero no entiendo como funciona esto.

x64core

Cita de: naderST en  5 Marzo 2013, 02:41 AM
Buenas a todos, he visto varios códigos donde hacen algo como esto:


GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA");


Entiendo que obtiene la dirección de memoria de la función MessageBoxA, pero lo que no logro entender es cómo es que es la misma dirección para todos los procesos? No se si me explico bien, pero no entiendo como funciona esto.

Cada proceso tiene su propio espacio de memoria virtual ( el tamaño depende de la version de Windows que se ha instalado en el sistema: 32, 64 bits ).
El manipulador de memoria sabe cuando desmapear una pagina de memoria cuando ya no es usada y cuando volver a mapearla para su uso.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366912(v=vs.85).aspx
http://en.wikipedia.org/wiki/Virtual_memory

naderST

Mi duda me surge cuando vi este código:


#include <windows.h>
#include <stdio.h>

typedef int (WINAPI *_MessageBoxA)(HWND, LPCTSTR, LPCTSTR, UINT);

struct sTDatos_MessageBoxA
{
    _MessageBoxA direccionMessageBoxA;
    char titulo[255], texto[255];
};

typedef struct sTDatos_MessageBoxA TDatos_MessageBoxA;

void Hilo_MessageBoxA(TDatos_MessageBoxA *datos)
{
    datos->direccionMessageBoxA(0, datos->texto, datos->titulo, 0);
}

void Inyectar_MessageBoxA(DWORD pID, char* titulo, char* texto)
{
    DWORD tamFunc;
    HANDLE tHandle, funcionRemota;
    TDatos_MessageBoxA datos, *direccionDatosRemotos;
    void* direccionFuncionRemota;

    tHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, 0, pID);

    datos.direccionMessageBoxA = (_MessageBoxA)GetProcAddress(GetModuleHandle("USER32.DLL"), "MessageBoxA");
    sprintf(datos.titulo, titulo);
    sprintf(datos.texto, texto);

    direccionDatosRemotos = (TDatos_MessageBoxA*)VirtualAllocEx(tHandle, 0, sizeof(TDatos_MessageBoxA), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(tHandle, direccionDatosRemotos, &datos, sizeof(TDatos_MessageBoxA), NULL);

tamFunc = (DWORD)Inyectar_MessageBoxA - (DWORD)Hilo_MessageBoxA;

direccionFuncionRemota = VirtualAllocEx(tHandle, 0, tamFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(tHandle, direccionFuncionRemota, (void*)Hilo_MessageBoxA, tamFunc, NULL);

funcionRemota = CreateRemoteThread(tHandle, NULL, 0, (LPTHREAD_START_ROUTINE)direccionFuncionRemota, direccionDatosRemotos, 0, NULL);

WaitForSingleObject(funcionRemota,INFINITE);
   CloseHandle(funcionRemota);

   VirtualFreeEx(tHandle,direccionFuncionRemota,0,MEM_RELEASE);
   VirtualFreeEx(tHandle,direccionDatosRemotos,0,MEM_RELEASE);   

   CloseHandle(tHandle);   
}

int main()
{
    DWORD pID;
    HWND hWnd;

    hWnd = FindWindow("SciCalc", NULL);

    if(hWnd!=NULL)
    {
        GetWindowThreadProcessId(hWnd, &pID);
        Inyectar_MessageBoxA(pID, "descifra.me", "Codigo inyectado!");
    }

    return 0;
}


Cómo es que al crear un hilo en otro proceso se puede utilizar esta dirección en el hilo creado en el otro proceso:

datos.direccionMessageBoxA = (_MessageBoxA)GetProcAddress(GetModuleHandle("USER32.DLL"), "MessageBoxA");

Me surge la duda porque la llamada a GetModuleHandle se hace en un proceso distinto.

x64core

Cuando el loader de Windows carga un .exe, carga modulos tales como ntdll, kernel32,etc
Por ser los primeros es que podria no haber conflicto entre espacios de memoria entre modulos por eso cada modulo de cada proceso
podría cargarse en el mismo espacio de memoria de un proceso, aunque yo preferiría obtener la direcciones de funciones desde el proceso 
en el que se ha inyectado el codigo, ese codigo no es la mejor forma de inyección.

naderST

Muchas gracias por la aclaratoria x64Core esa era mi duda