Iniciar en modo grafico (GUI) cualquier app[WIN]
Hola, todos habrán visto que sus programas de C para Windows salen por defecto en modo consola, con esa ventanita negra atras, suponganse que quieren hacerlo invisible al programa… esa ventanita no deberia estar… bueh, hay 2 formas, que en realidad es 1:
indicarle al compilador que lo cree en modo GUI (modo grafico, sin ventanita negra). esto depende de cada compilador pero para en DEV-C++ basta con crear un proyecto nuevo e indicarle que es “Windows aplication”. esto sirve para cuando hacemos botonces y ventanas y esas cosas pero tambien para “ocultarnos”, obiamente no le pueden pedir al usuario que ingrese un dato por teclado y tampoco que lea algo xD.
la segunda es hacer lo que hace el compilador manualmente, pero esto nos sirve (al ser manual) para cualquier programa.
(al final de post, despues del codigo, explico lo que hay que modificar)
que pasa cuando el copilador lo crea en modo GUI?? en el archivo .exe que genera, hay una parte específica que obtiene el valor 2, que es el modo GUI, en cambio si es en modo consola, el valor que obtiene ahi es el 3, asique solo es cuestion de abrir el archivo y cambiar el valor 3 por el 2 para que no aparezca la ventana, pero lo puede hacer un programa no?
explico lo que hace este programa
convierte un exe que le indicamos a modo GUI (si esta en modo consola) o en modo consola (si esta en modo GUI), asique lo abren, les pide el programa asique escriben la ruta y listo.
#include stdio.h /*ponganle los signos de mayor y menor en stdio.h*/ #define GUI 2 #define CUI 3 int main(int argc, char **argv) { FILE *f; char c = 0, name[500]; printf("Ingrese el exe a modificar:\n"); gets(name);/*pide el nombre del programa */ if(!(f = fopen(name, "rb+"))){ printf("FOPEN"); getchar(); return 0; } if(fgetc(f) != 'M'){/*se fija que tenga el numero magico 'MZ', lo que indica que es ejecutable*/ printf("NOT EXE"); goto end; } if(fgetc(f) != 'Z'){ printf("NOT EXE"); goto end; } fseek(f, 0x3C, SEEK_SET);/*asi es como se busca PE*/ fread(&i, 1, 4, f); if(i == 0){ printf("NOT PE"); goto end; } fseek(f, i, SEEK_SET); if(fgetc(f) != 'P'){/*se fija que tenga el numero magico 'PE', lo que indica que es ejecutable*/ printf("NOT PE"); goto end; } if(fgetc(f) != 'E'){ printf("NOT PE"); goto end; } if(feof(f)){ eof: printf("EOF"); goto end; } fseek(f, 0x5A ,SEEK_CUR);/*nos vamos a esa posicion especial*/ if(fgetc(f) == GUI){ fseek(f, -1, SEEK_CUR); fputc(CUI, f);/*y escribimos que sea CUI*/ } else{ fseek(f, -1, SEEK_CUR); fputc(GUI, f);/*y escribimos que sea GUI*/ } printf("listo\n"); end: fclose(f); getchar(); return 0; }
y ahora el programa que le indicamos va a iniciar en modo grafico. sin ventanita negra! 
al principio de un exe, tenemos la cabecera DOS, que no nos sirve, esta empieza con los caracteres ascii MZ
si avanzamos un poco… aparecen los caracteres ascii PE, estos SI interesan 
ahora viene IMAGE_FILE_HEADER, que ocupa 0×14 bytes (hay que aclarar que despues de PE hay 2 bytes en 0 que no son contados), como esta seccionno interesa pasamos a la otra, IMAGE_OPTIONAL_HEADER, esta empieza con el valor 0×010B, pero en el archivo aparece 0B 01, pero no importa, es cuestion de como se ordenan los bytes en la memoria (menor peso menor posicion de memoria, por eso 0b que es el byte de menor peso esta antes), ahora en 0×44 bytes mas adelante (CONTANDO el 0×010B tenemos
The type of subsystem that this executable uses for its user interface. WINNT.H defines the following values:
1 Doesn’t require a subsystem (such as a device driver)
WINDOWS_GUI
2 Runs in the Windows GUI subsystem
WINDOWS_CUI
3 Runs in the Windows character subsystem (a console app)
OS2_CUI
5 Runs in the OS/2 character subsystem (OS/2 1.x apps only)
POSIX_CUI
7 Runs in the Posix character subsystem
asique hay que moverse hasta ahi, yo me muevo 0×5A, pero.. 0×44 mas 0×14 = 0×58, eso es porque yo busco a PE, y no conte todabia los 2 bytes en 0
y bueh, ya estamos, ponemos el valor adecuado y listo:P
salu2!