Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: [Zero] en 31 Agosto 2010, 17:37 pm



Título: ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija
Publicado por: [Zero] en 31 Agosto 2010, 17:37 pm
Bueno, pues la duda es lo que dice el título, estoy intentando usar VirtualAlloc o VirtualAllocEx, me da igual, para reservar memoria en una dirección de memoria fija, en concreto en 0x0040000 (teniendo el base address de mi ejecutable en 00300000). Levo días buscando la razón del error pero no encuentro nada que me sirva, ejecutando lo siguiente:

Código
  1. #pragma comment(linker,"/NODEFAULTLIB")
  2. #pragma comment(linker,"/ENTRY:main")
  3.  
  4. #include <Windows.h>
  5.  
  6. int main()
  7. {
  8. //CHAR MSG[1024];
  9. //SYSTEM_INFO SystemInfo;
  10. //GetSystemInfo(&SystemInfo);
  11.  
  12. //wsprintfA(MSG,"%s%X%s%X","MinimumApplicationAddress: ",SystemInfo.lpMinimumApplicationAddress,"\nMaximumApplicationAddress: ",SystemInfo.lpMaximumApplicationAddress);
  13. //MessageBoxA(0,MSG,"Info",MB_ICONINFORMATION);
  14.  
  15. if(!VirtualAllocEx(GetCurrentProcess(),(LPVOID)0x00400000,0x1000,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE))
  16. {
  17. MessageBoxA(0,"Error al reservar memoria en 0x00400000",0,MB_ICONERROR);
  18. return 0;
  19. }
  20.  
  21. MessageBoxA(0,"Memoria Reservada correctamente en 0x00400000","Éxito",MB_ICONINFORMATION);
  22.  
  23. return 0;
  24. }
  25.  

Ojo, linkear el ejecutable con una dirección base diferente de 0x00400000 o en su defecto cambiar la dirección fija a reservar.

Éste código, en mi PC Win7 32bits reserva memoria bien sólo a veces, otras veces falla devolviendo last_error ERROR_INVALID_ADDRESS. Viendo con olly me dice que la dirección no está en uso incluso cuando falla, pero el error es como sí la dirección estuviera ya reservada  :-\.

Gracias por adelandato  :P


Título: Re: ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija
Publicado por: >FedeX< en 31 Agosto 2010, 21:09 pm
Con cheat engenie se ve como a veces en 0x00400000 hay memoria en uso...


Título: Re: ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija
Publicado por: Littlehorse en 31 Agosto 2010, 23:41 pm
Es necesario utilizar una dirección fija que posiblemente pueda no estar libre, o solo es por probar?

Utiliza VirtualQuery para chequear el estado de la región, o en su defecto VADUMP.

Saludos


Título: Re: ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija
Publicado por: [Zero] en 1 Septiembre 2010, 00:03 am
Necesito usarlo con una dirección fija, me da igual cual pero es necesario que sea fija. En la documentación de la MSDN dice que es perfectamente posible, y ese parámetro no tendría sentido si no fuera así, pero buscando no encuentro más que gente con el mismo problema e hilos a los que no se llega a una solución. Si esa memoria está reservada, el proceso no la está utilizando aparentemente para nada, intente hacer VirtualFree pero sigue sin funcionar  :-\.

Al ejecutar VirtualQuery VirtualAlloc falla siempre, incluso cuando ésta me devuelve MEM_FREE  :-\.

Saludos



Edito:

Hice ésto para ver si me quedaba algo más claro que pasaba, pero sólo logró confundirme más  :xD:
Código
  1. #pragma comment(linker,"/NODEFAULTLIB")
  2. #pragma comment(linker,"/ENTRY:main")
  3.  
  4. #include <Windows.h>
  5.  
  6. int main()
  7. {
  8. MEMORY_BASIC_INFORMATION Buffer;
  9. VirtualQuery((LPVOID)0x00400000,&Buffer,sizeof(MEMORY_BASIC_INFORMATION));
  10.  
  11. switch(Buffer.State)
  12. {
  13. case MEM_COMMIT:
  14.  
  15. MessageBoxA(0,"MEM_COMMIT","Info",MB_ICONINFORMATION);
  16.  
  17. if(!VirtualFree((LPVOID)0x00400000,0x1000,MEM_DECOMMIT))
  18. {
  19. MessageBoxA(0,"Error al desencomendar memoria",0,MB_ICONERROR);
  20. }
  21. else
  22. {
  23. MessageBoxA(0,"Memoria Desencomendada","Info",MB_ICONINFORMATION);
  24.  
  25. if(!VirtualFree((LPVOID)0x00400000,0,MEM_RELEASE))
  26. {
  27. MessageBoxA(0,"Error liberar memoria",0,MB_ICONERROR);
  28. }
  29. else
  30. {
  31. MessageBoxA(0,"Memoria Reservada Liberada","Info",MB_ICONINFORMATION);
  32. }
  33. }
  34. break;
  35.  
  36. case MEM_RESERVE:
  37.  
  38. MessageBoxA(0,"MEM_RESERVE","Info",MB_ICONINFORMATION);
  39.  
  40. if(!VirtualFree((LPVOID)0x00400000,0,MEM_RELEASE))
  41. {
  42. MessageBoxA(0,"Error liberar memoria",0,MB_ICONERROR);
  43. }
  44. else
  45. {
  46. MessageBoxA(0,"Memoria Reservada Liberada","Info",MB_ICONINFORMATION);
  47. }
  48. break;
  49.  
  50. case MEM_FREE:
  51. MessageBoxA(0,"Memoria Libre","Info",MB_ICONINFORMATION);
  52. break;
  53. }
  54.  
  55.  
  56. if(!VirtualAlloc((LPVOID)0x00400000,0x1000,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE))
  57. {
  58. MessageBoxA(0,"Error al reservar memoria en 0x00400000",0,MB_ICONERROR);
  59. return 0;
  60. }
  61.  
  62. MessageBoxA(0,"Memoria Reservada correctamente en 0x00400000","Éxito",MB_ICONINFORMATION);
  63.  
  64. return 0;
  65. }
  66.  


Título: Re: ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija
Publicado por: Littlehorse en 2 Septiembre 2010, 00:34 am
VirtualAlloc mas direcciones hardcodeadas, no es la mejor combinación. ;D

Cuidado con los 0 de mas y de menos en las direcciones, que a simple vista ya se ven errores:

Código
  1. if(Buffer.State==MEM_COMMIT)
  2. {
  3. if(!VirtualFree((LPVOID)0x0040000,0x1000,MEM_DECOMMIT))

0x0040000!=0x00400000

Código
  1. case MEM_RESERVE|MEM_COMMIT:

Ese case esta de mas.

Código
  1. VirtualFreeEx(GetCurrentProcess(),(LPVOID)0x00400000,0,MEM_DECOMMIT);

Si utilizas decommit en una región de memoria sin utilizar release, esta cambia su estado a reservado , o sea, lista para asignar (Suponiendo que sea posible).
Por ende, la llamada a VirtualAllocEx va a fallar del modo que estas usando, porque estas intentando reservar una dirección que ya esta reservada. Asignarla es lo que debería seguir.

Código
  1. VirtualAllocEx(GetCurrentProcess(),ADR,0x1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  2.  

(http://img20.imageshack.us/img20/7417/sadic.jpg) (http://img20.imageshack.us/i/sadic.jpg/)

Antes de seguir, busca los artículos de Mark Russinovich acerca de todo esto ya que explican todo con lujo de detalle. Y sobre todo atención a los "remarks" de la documentación de cada API, porque es eso lo que te esta trayendo dramas. ;D.

Cabe destacar también, que el proceso real que debería realizarse es mucho mas largo, porque esto vale como ejemplo pero en una aplicacion no podes dejar pasar cosas como las posibles medidas de protección de cada región.

Tengo por acá un código que quizas te pueda servir ya que realiza lo que necesitas, es bastante largo y pesado pero de seguro sacas en limpio lo necesario. En un rato lo busco y si lo encuentro te lo mando por pm.

Saludos


Título: Re: ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija
Publicado por: [Zero] en 2 Septiembre 2010, 15:28 pm
Muchas gracias Littlehorse, seguiré trabajando y leyendo esta tarde siguiendo tus indicaciones  ;D.

Saludos



Edito: Arreglé el código de antes, sigue fallando pero al menos ahora los resultados que devuelve son coherentes. Por cierto, ¿que programa usaste arriba para ver el estado de las páginas de memoria?


Título: Re: ERROR_INVALID_ADDRESS al usar VirtualAllocEx con una dirección fija
Publicado por: Littlehorse en 2 Septiembre 2010, 16:32 pm
De nada ;D. El programa del screen es Cheat Engine que para este caso vale perfectamente, pero para el resto lo ideal es WinDBG.

Con Cheat Engine: Memory view + (ctrl +R)

Con WinDBG: !address -summary
                      !address Addr
  
Saludos!