Offset inicio/fin de .data

Iniciado por Destro-, 28 Noviembre 2014, 01:39 AM

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

Destro-

Buenas :)


Necesito reemplazar un string en la memoria de otro modulo cargado en el mismo proceso.
Arme algo así:

MODULEINFO mInfo;
int base, start, end;
GetModuleInformation(GetCurrentProcess(),GetModuleHandle("swds.dll"),&mInfo,sizeof(mInfo));

start = (int)mInfo.lpBaseOfDll;
end = start+mInfo.SizeOfImage;

char find_stats[18] = { 'm', 'o', 't', 'd', '_', 'w', 'r', 'i', 't', 'e', 0, 0, 's', 't', 'a', 't', 's', 0 };
for(int p=0; (start+p) < (end-sizeof(find_stats)); p++)
{
if(memcmp((void*)(start+p), &find_stats, sizeof(find_stats)) == 0)
{
memcpy((void*)(start+p+15), &"l", 1);
//char *p = (char *)(start+p+15);
//*p = 'l';
}
}

Funciona perfecto, pero buscaría en todo el modulo y no donde importa. Hay alguna forma de obtener el start y end addres de la sección .data ?.
Estuve buscando en stackoverflow pero no encontré casi nada (tal vez busque mal xd) y lo que encontré no lo entendí :\.

Y otra duda, la parte que esta comentada, porque me crashea ?, creería yo que tendría que funcionar o.O.

Eternal Idol

http://en.wikipedia.org/wiki/Portable_Executable

En la base del modulo hay una IMAGE_DOS_HEADER, con el offset en el campo e_lfanew llegas a la IMAGE_NT_HEADERS, ahi tenes el campo: NumberOfSections
The number of sections. This indicates the size of the section table, which immediately follows the headers.

Un array de IMAGE_SECTION_HEADERs, ahi estan todas las secciones del PE.

Tenes dos variables p ahi ... y el codigo usa la segunda para sumar que es el puntero indefinido.

warning C4700: uninitialized local variable 'p' used
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

Destro-

tengo que sacar un turno para el oculista ya!, jaja :P

Gracias :D
Me quedo algo así:

void get_data_offset(HMODULE hModule, unsigned int &DataStart, unsigned int &DataEnd)
{
char *dllImageBase = (char*)hModule;

IMAGE_NT_HEADERS *pNtHdr = ImageNtHeader(hModule);

IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *)(pNtHdr+1);

for(int i = 0 ; i < pNtHdr->FileHeader.NumberOfSections; i++)
{
char *name = (char*) pSectionHdr->Name;
if(memcmp(name, ".data", 5) == 0)
{
DataStart = (unsigned int)dllImageBase + pSectionHdr->VirtualAddress;
DataEnd = DataStart + pSectionHdr->Misc.VirtualSize;
break;
}
pSectionHdr++;
}
}

// ======================================================

unsigned int start, end;
get_data_offset(GetModuleHandle("swds.dll"), start, end);


char find_stats[] = { 'm', 'o', 't', 'd', '_', 'w', 'r', 'i', 't', 'e', 0, 0, 's', 't', 'a', 't', 's', 0 };

for(unsigned int p=0; (start+p) < (end-sizeof(find_stats)); p++)
{
if(memcmp((void*)(start+p), &find_stats, sizeof(find_stats)) == 0)
{
//memcpy((void*)(start+p+15), &"l", 1);
char *pChar = (char *)(start+p+15);
*pChar = 'l';

//SERVER_PRINT("Pached: stats\n");
}
}

algo para mejorar ?.
____________________
Una duda, para almacenar punteros/direcciones de memoria es correcto utilizar int/unsigned int  ?. porque por ejemplo dllImageBase es un puntero char, es lo mismo ?.




MCKSys Argentina

Cita de: Destro- en 28 Noviembre 2014, 04:02 AM
Una duda, para almacenar punteros/direcciones de memoria es correcto utilizar int/unsigned int  ?. porque por ejemplo dllImageBase es un puntero char, es lo mismo ?.

Los punteros te conviene guardarlos sin signo. Si estás en 32 bits puedes usar DWORD (unsigned long) y en 64 bits DWORD64 (unsigned long long)

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


Eternal Idol

Cita de: Destro- en 28 Noviembre 2014, 04:02 AMUna duda, para almacenar punteros/direcciones de memoria es correcto utilizar int/unsigned int  ?. porque por ejemplo dllImageBase es un puntero char, es lo mismo ?.

Si queres guardar la direccion en una variable entera mejor usar ULONG_PTR que ocupara los bytes correspondientes a la plataforma (4 bytes en x86 y 8 bytes en x64) y no tendra signo.
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

MCKSys Argentina

Cita de: Eternal Idol en 28 Noviembre 2014, 10:06 AM
Si queres guardar la direccion en una variable entera mejor usar ULONG_PTR que ocupara los bytes correspondientes a la plataforma (4 bytes en x86 y 8 bytes en x64) y no tendra signo.

jejeje, que grande Eternal Idol! También agradezco el dato (recién estoy emezando con VC++)

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


Eternal Idol

Cita de: MCKSys Argentina en 28 Noviembre 2014, 16:41 PM
jejeje, que grande Eternal Idol! También agradezco el dato (recién estoy emezando con VC++)

Saludos!

De nadas  ::)
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

x64core

Cita de: Destro- en 28 Noviembre 2014, 04:02 AM
algo para mejorar ?.
____________________
Una duda, para almacenar punteros/direcciones de memoria es correcto utilizar int/unsigned int  ?. porque por ejemplo dllImageBase es un puntero char, es lo mismo ?.


Sí, para de usar este tipo de hardcoding:
IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *)(pNtHdr+1);
Hace que tu código sea generico además de que no tiene sentido si haces luego una comparación del nombre, en lugar de escribir funciones para recuperar un puntero a una determinada sección (PIMAGE_SECTION_HEADER) que luego podes usar en otros códigos;
Lo mismo aquí:
memcmp(name, ".data", 5) == 0)
Mejor utiliza sizeof para IMAGE_SECTION_HEADER.Name.


Destro-

Cita de: Eternal Idol en 28 Noviembre 2014, 10:06 AM
Si queres guardar la direccion en una variable entera mejor usar ULONG_PTR que ocupara los bytes correspondientes a la plataforma (4 bytes en x86 y 8 bytes en x64) y no tendra signo.
Gracias por la info :P.
Puede ser que muy pocos utilicen ULONG_PTR ?, soy nuevo en C pero soy de leer mucho code y hasta ahora no recuerdo haber visto utilizar ULONG_PTR o.O.


Cita de: x64Core en 28 Noviembre 2014, 17:31 PM
Sí, para de usar este tipo de hardcoding:
IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *)(pNtHdr+1);
Hace que tu código sea generico además de que no tiene sentido si haces luego una comparación del nombre, en lugar de escribir funciones para recuperar un puntero a una determinada sección (PIMAGE_SECTION_HEADER) que luego podes usar en otros códigos;
Lo mismo aquí:
memcmp(name, ".data", 5) == 0)
Mejor utiliza sizeof para IMAGE_SECTION_HEADER.Name.
no entendí cuando decís que devuelva el puntero de IMAGE_SECTION_HEADER

por lo demás te referías a que haga algo así ?:

void get_setion_offset(HMODULE hModule, char *SetionName, ULONG_PTR &SetionStart, ULONG_PTR &SetionEnd)
{
IMAGE_NT_HEADERS *pNtHdr = ImageNtHeader(hModule);
PIMAGE_SECTION_HEADER pSectionHdr = (PIMAGE_SECTION_HEADER)(pNtHdr+1);

for(int i = 0 ; i < pNtHdr->FileHeader.NumberOfSections; i++, pSectionHdr++)
{
if(strcmp((char *)pSectionHdr->Name, SetionName) == 0)
{
SetionStart = (ULONG_PTR)hModule + pSectionHdr->VirtualAddress;
SetionEnd = SetionStart + pSectionHdr->Misc.VirtualSize;
break;
}
}
}



Eternal Idol

Cita de: Destro- en 29 Noviembre 2014, 00:15 AM
Gracias por la info :P.
Puede ser que muy pocos utilicen ULONG_PTR ?, soy nuevo en C pero soy de leer mucho code y hasta ahora no recuerdo haber visto utilizar ULONG_PTR o.O.

Ni idea, esta entre los Migrations Tips de Microsoft para x64: Storing a 64-bit Value.
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