Buenas, tras conseguir la manera de obtener el PID sin necesidad de cojer la handle de la window, cree un code para poder modificar otros programas o procesos en ejecucion (que bien lo he pasado jeje), aqui primero el programa de ejemplo:
http://www.mediafire.com/?2mapqpuebn8kym1
Para encontrar el sector de memoria a modificar busquen por el numero que tienen almacenado en un momento determinado en la variable y cambien dicho sector de memoria en el codigo para injectar vuestro propio valor.
Esta basado en el tutorial de Vladek que lei hace tiempo, una variable que va acumulando valores de lo que recive sumandolos y mostrando su resultado.
Ahora nuestro programa, que en primer lugar obtiene el PID de un proceso a traves del nombre (Gracias Littlehorse), y lo modifica con WriteProcess, usando el handle obtenido con el PID:
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <stdio.h>
#include "PsControl.h"
using namespace std;
int main()
{
HANDLE hPsLectura;
DWORD pidPs;
pidPs = getPsId("Proyecto1.exe");
cout << pidPs << endl;
hPsLectura = OpenProcess(PROCESS_ALL_ACCESS,false,pidPs);
long Numero = 71827339;
DWORD Bytes;
/* La direcion de memoria que vamos a cambiar en el proceso con HANDLER hPsLectura es 0x0022FF44 y cambiaremos el valor Numero */
WriteProcessMemory(hPsLectura,(LPVOID)0x0022FF44,&Numero,sizeof(Numero_Nuevo),&Bytes);
system("pause");
return 0;
}
Se que me diran que el system("No es portable"); y tal pero es que pocas funciones aqui usadas lo son :)
Y ahora la libreria con el control de procesos:
#ifndef _PSCONTROL_H_
#define _PSCONTROL_H_
#include <Windows.h>
#include <iostream>
#include <cstdlib>
#include <tlhelp32.h>
#include <tchar.h>
#include <stdio.h>
using namespace std;
int killProcess(DWORD pid)
{
HANDLE proceso;
proceso=OpenProcess(PROCESS_TERMINATE,FALSE,pid);
TerminateProcess(proceso,0);
CloseHandle(proceso);
return 0;
}
DWORD getPsId(const char* PsName)
{
DWORD ProcessID;
HANDLE Handle;
PROCESSENTRY32 ProcI;
Handle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
ProcI.dwSize=sizeof(PROCESSENTRY32);
while(Process32Next(Handle,&ProcI))
if(!strcmp(ProcI.szExeFile,PsName))
ProcessID=ProcI.th32ProcessID;
CloseHandle(Handle);
return ProcessID;
}
#endif
Eso es todo, no es un programa final, pero puede que a muchos les solucione algunas dudas.
Un saludo
Suena a Cheat Engine :P
Muy bueno!
Por cierto lo de system("pause") lo puedes cambiar por un getchar/
Saludos!
Cita de: [D4N93R] en 16 Agosto 2010, 18:25 PM
Suena a Cheat Engine :P
Muy bueno!
Por cierto lo de system("pause") lo puedes cambiar por un getchar/
Saludos!
Mi idea es hacer algo asi, pero estatico, osea para un soft en concreto.
Saludos
Hay que tener en cuenta que no siempre podes escribir en otro proceso, dependiendo de si es accesible la región, si tenes privilegios para hacerlo, etc. Igualmente para empezar esta bien, pero falta pulir todo lo que es el manejo de errores ya que en determinados casos puede colapsar.
En cuanto a system, no se trata solamente de la portabilidad, el rendimiento también influye. Cada llamada a system requiere recursos extra que no siempre son necesarios, por ejemplo reservar la memoria para la consola, llamarla, crear el proceso, etc. Indefectiblemente en algún momento hay que sacarse la mala costumbre, mas si estas usando la API directamente, ya que en ese caso tenes muchas opciones para hacer una pausa.
Saludos
Cita de: Littlehorse en 17 Agosto 2010, 03:02 AM
Hay que tener en cuenta que no siempre podes escribir en otro proceso, dependiendo de si es accesible la región, si tenes privilegios para hacerlo, etc. Igualmente para empezar esta bien, pero falta pulir todo lo que es el manejo de errores ya que en determinados casos puede colapsar.
En cuanto a system, no se trata solamente de la portabilidad, el rendimiento también influye. Cada llamada a system requiere recursos extra que no siempre son necesarios, por ejemplo reservar la memoria para la consola, llamarla, crear el proceso, etc. Indefectiblemente en algún momento hay que sacarse la mala costumbre, mas si estas usando la API directamente, ya que en ese caso tenes muchas opciones para hacer una pausa.
Saludos
El getch() que sugirio el compañero?
Saludos
[D4N93R] no menciono getch, menciono getchar. Y si, getchar podría ser una opción, en el foro hay muchos ejemplos sobre las distintas formas para hacer una pausa.
Saludos
Cita de: Littlehorse en 19 Agosto 2010, 02:29 AM
[D4N93R] no menciono getch, menciono getchar. Y si, getchar podría ser una opción, en el foro hay muchos ejemplos sobre las distintas formas para hacer una pausa.
Saludos
Entiendo gracias por la aclaracion!
Saludos
Cita de: Littlehorse en 17 Agosto 2010, 03:02 AM
Hay que tener en cuenta que no siempre podes escribir en otro proceso, dependiendo de si es accesible la región, si tenes privilegios para hacerlo, etc. Igualmente para empezar esta bien, pero falta pulir todo lo que es el manejo de errores ya que en determinados casos puede colapsar.
Y me pregunto que es lo que hace que en los sistemas operativos modernos (y bueno, también linux) desde otro proceso nos permita el S.O. acceder a la memoria reservada para otro proceso. En Win98, (osea MS-DOS) esto era muy fácil, te hacías un bucle que se pasara al escribir en un array o un malloc en un bucle mal hecho y ya te has podido cargar algún proceso. Yo lo hice, y fue uno del S.O. ^^. Pero si teóricamente el S.O. de ahora no permite a un proceso acceder fuera de la memoria que le ha sido asignada, ¿como puede ver y modificar esas otras áreas ahora?
En este caso, porque el programa esta siendo probado en una cuenta donde el proceso tiene los privilegios necesarios.
Como bien dijiste cada proceso tiene un contexto, un propio espacio de direcciones, ahora eso no implica que nunca puedas acceder a la memoria de otro proceso. En este caso funciona por lo antes mencionado, pero en la mayoría de los casos como mínimo necesitas obtener privilegios de depuración para que OpenProcess con PROCESS_ALL_ACCESS no falle.
Igualmente formas hay muchas, un ejemplo básico por ejemplo seria inyectar código para ejecutarte en el contexto del proceso que necesitas acceder. Lo primordial es tener en claro como funcionan los derechos de acceso y los atributos de seguridad de cada proceso.
Saludos
Cita de: Littlehorse en 20 Agosto 2010, 23:25 PMEn este caso funciona por lo antes mencionado, pero en la mayoría de los casos como mínimo necesitas obtener privilegios de depuración para que OpenProcess con PROCESS_ALL_ACCESS no falle.
solo falla cuando no podes ejecutar tu programa como administrador o hay algún driver vigilando el tema (casos especiales), en general solo basta con tener el mismo nivel de acceso del programa al que querés obtener privilegios...
S2
El "solo falla" queda bastante chico, las situaciones que mencionas son de los mas normales.
Es normal que un usuario no utilice una cuenta con privilegios, mas aun si hablamos de versiones posteriores a Windows XP.
Utilizar PROCESS_ALL_ACCESS sin mas preámbulo te va a garantizar errores en la mayoría de los casos, por varios motivos:
1) El carácter del flag es variable a lo largo de las distintas versiones de Windows.
2) Algunos procesos necesitan si o si el privilegio de depuración para tales acciones.
3) Ciertos modos de acceso pueden estar restringidos.
De hecho en Windows XP, los únicos procesos que no podes depurar con el privilegio de depuración son el inactivo y el de sistema, y solamente porque no tienen representación en el modo usuario. El resto, casi seguro que no tendrías problemas, exceptuando por supuesto los casos de los procesos protegidos por un driver.
Ahora bien, no es tan especial que un driver proteja un proceso, mas bien eso sucede en casi toda aplicacion de protección. Protecciones de juegos, antivirus, firewall, etc. Igualmente en ese caso obtener o no los privilegios es irrelevante, fallara de cualquier manera mientras la protección no sea vulnerada.
Citargeneral solo basta con tener el mismo nivel de acceso del programa al que querés obtener privilegios...
Con niveles de acceso no se a lo que te referís específicamente, ya que el modelo de acceso cambia bastante desde NT 6.0 en adelante, o dicho mas claro, difiere bastante si comparamos Windows XP y Windows Vista, por ejemplo.
De cualquier forma, ya que mencionas los niveles, el IL para la mayoría de los procesos por defecto es No-Write-Up + No-Read-Up. Lo cual implica que no podes leer ni escribir al menos que estés en el mismo nivel de integridad, incluso si el DACL lo autoriza.
Esta claro que, en la mayoría de los casos, no vas a estar en el nivel de integridad deseado por defecto.
En conclusión, utilizar PROCESS_ALL_ACCESS es una mala practica cuando no se esta seguro si se va a obtener dichos privilegios ni se chequea la posibilidad de obtenerlos.
Lo ideal es utilizar los
flags que exclusivamente vas a necesitar, y luego chequear y solicitar los privilegios requeridos en caso de no tenerlos (u escalarlos a la fuerza, dependiendo de lo que estemos hablando). Eso es lo que corresponde para una correcta ejecución.
Saludos
Cita de: Littlehorse en 21 Agosto 2010, 07:50 AMLo ideal es utilizar los flags que exclusivamente vas a necesitar, y luego chequear y solicitar los privilegios requeridos en caso de no tenerlos (u escalarlos a la fuerza, dependiendo de lo que estemos hablando). Eso es lo que corresponde para una correcta ejecución.
si, en realidad lo de PROCESS_ALL_ACCESS lo mencionaste vos, yo más bien me refería a lo de obtener permisos de VM y QUERY que son los que en realidad se usan (pero se aplica la misma regla a la hora de otorgar dichos permisos)
S2
Lo mencione porque es el flag utilizado en el código y fue precisamente la parte que citaste.
Efectivamente, las reglas para obtener permisos son las mismas, y las practicas para obtenerlos también. Lo de ejecutar y rezar "a ver si se puede" es un error.
Saludos