Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - lweb20

#1
ASM / Modo de video VGA
20 Octubre 2013, 17:52 PM
Buenas, aquí estoy de nuevo con la programación de mi SO. Por favor quisiera que me ayuden en lo siguiente:

He conseguido estos datos sobre el VGA:
Tamaño total: 256 KiB de VRAM
Cantidad de colores máximo: 256
Máximo de 720 píxeles horizontales
Máximo de 480 líneas
Tasa de refresco de hasta 70 Hz

He conseguido entrar a un modo unchained (modo X) 320x240x256 como máximo. Quisiera saber si puedo obtener una resolución algo más alta como 640x480x256.

Y si alguien me puede explicar sobre la VRAM cómo funciona, es decir, máximo cuántos bytes por página hay en los modos X.

Estaría muy agradecido si me ayudaran. Gracias de antemano.


Si alguno de ustedes desea colaborar con el desarrollo del SO sin fines de lucro también están bienvenidos.
#2
Buenas, aquí estoy continuando con el desarrollo de mi sistema operativo.

Hoy decidí cambiar la convención de llamada de mi sistema de _cdecl a _fastcall porque si no me equivoco _fastcall reduce el tamaño del ejecutable y casi siempre usa registros en lugar de la pila, lo cual lo hace más veloz al SO. (Corríjanme si me equivoco).

Resulta que tuve un pequeño problema con las interrupciones del SO (el manejador del teclado, etc..).

El manejador del teclado dejó de funcionar :o. Entonces empecé a testear y testear, investigar e investigar y nada :(. Aquí les dejo el código a ver si alguien me da una mano:

void __cdecl Teclado::manejador(){
_asm cli // deshabilito interrupcionnes
_asm pushad // guardo registros generales en la pila

// aquí va todo el código para controlar las teclas... etc......

_asm popad // saco los registros guardados de la pila
_asm sti // habilito interrupciones si no me quedo colgado xD
_asm iret // salgo de la interrupción
}


El error que sale es Invalid opcode.

También tengo la duda si el manejador debe ser _cdecl o puede ser _fastcall porque con ninguna funciona :(

Ojalá alguien pueda ayudarme por favor  ;D
#3
Hola, aquí estoy de nuevo.

Estuve un rato en el foro leyendo algunos post y me hizo acordar sobre una época que logré hacer un driver para Windows 7 ( casi todo copy/past ) para hookear el CreateProcess.

Una vez consulté aquí en el foro sobre una duda y me respondió "Eternal Idol" y me dijo que no es buena idea hookear ya que en 64-bit no funciona, y eso me hizo pensar muchas cosas.

1) ¿Cómo hacen los antivirus para analizar cada proceso que se abre y detener la ejecución antes que empiece?

2) ¿Acaso existe otro método que no sea hookear?

3) ¿Qué mas se pueden hacer con los drivers? ( aparte de usarlo con hardware claro )

Agradecería mucho alguna aclaración.

EDIT: Y por de casualidad. ¿Alguien conoce manuales sobre el kernel de Windows en español? ya que estos temas son complicaditos y difíciles de entender sobre todo cuando está en inglés 100 hojas :P
#4
Hola a todos. Continuando con el desarrollo de mi SO.

Tengo una duda:

Si tengo el siguiente código de ejemplo:


KERNEL:


void EjecutarProceso(int id){
  ...
  _asm iret // interrupt return
}

void sys_TerminarProceso(){
  ...
}

void EjecutarPrograma(){
  int id = CrearProceso("programa.exe");
  EjecutarProceso(id);

  continuar:
  ...
}



PROGRAMA:


#include "syscalls.h"

void main(){
  ...
  sys_TerminarProceso();
}


Explico:

El código de ejemplo lo asemejo a un código para entrar al modo usuario desde el kernel, ejecutar un programa y regresar al modo kernel ( todo funciona perfectamente ). Lo que quiero hacer es que cuando termine el proceso "sys_TerminarProceso" continúe al label "continuar".

Para ello he pensado en 2 alternativas:

PRIMERA ALTERNATIVA ( probada y sí funciona ) :

a) Pasarle como parámetro a "EjecutarPrograma" la dirección de "continuar".
b) Guardar esa dirección en la memoria mediante una variable global.
c) Cuando el programa ( usuario ) ejecute sys_TerminarProceso, esta función ejecutará al final ( después de los ... ) dicha dirección del label.
d) Enjoy! :P

Bueno este es muy seguro y lógico a mi parecer, pero... este "EjecutarPrograma" también lo ejecutará el cliente como un "sys_EjecutarPrograma" y bueno no es muy normal que ejecute algo así: "EjecutarPrograma(etiquetaparacontinuar)".

SEGUNDA ALTERNATIVA ( dudas, problemas ) :

Obtener la dirección de una vez pasada la llamada "EjecutarProceso(id);", es decir, por donde está continuar ( sin el label claro ).


Si alguien tiene alguna idea agradecería mucho su ayuda. Gracias por la atención.
#5
ASM / Modo protegido, dolor de cabeza
4 Marzo 2013, 01:43 AM
Hola que tal jeje. Soy yo de nuevo, me pareció muy creativo el título.

Llevo ya varios meses con el desarrollo de un sistema operativo en 32-bits en modo protegido (obviamente) y quisiera aquí tratar todos los problemas y pequeños detalles (trataré) sobre el modo protegido.

Este post va a ser un poco informativo pero va a haber más preguntas que respuestas. Quiero aclarar que no soy un experto pero no puedo negar que se aprende muchas cosas en el transcurso del camino. No quiero caer mal ni mucho menos quiero ofender a alguien.

¿Por qué elegí 32-bits?
- Porque 16-bits es muy limitado y vulnerable a ataques de aplicaciones al hardware (modo real)
- Porque la mayoría de lenguajes de alto nivel (que son los más fáciles de programar a mi parecer) usan 32-bits. Aclaro que gcc existe una forma de usar 16-bits

Características principales del modo protegido de 32-bits
- No interrupciones de la BIOS (que miedo :S)
- Puedes crear tus propias interrupciones
- Prácticamente 2 niveles de acceso (sistema* y usuario - ring0 y ring3)
- Entre otros que poco a poco voy a ir comentando

Lo interesante del modo protegido
- Crear drivers (controladores)
- Entrar y salir del modo usuario
- Multitarea
- Acceso directo a la memoria (modo sistema*)
- Posibilidad de usar out para enviar comandos a dispositivos (*)
- Manejo avanzado de energía (APM, ACPI)
- Ejecutar aplicaciones de distintas unidades de almacenamiento
- Crear uno mismo sistemas de archivos (hechos y propios)
- Modo virtual

Mis dudas ;D
Aquí si pido ayuda si alguien tiene alguna idea de lo que hablo. Disculpen si son muchas pero llevo tiempo con estas dudas y he tenido más que he ido solucionando poco a poco.

- Entrar al modo virtual y salir (ejecutar alguna interrupción de la BIOS)
- Salir del modo usuario (ya sé entrar :D)
- Ejecutar programas PE (los básicos, buscar el main y ejecutarlo)
- Necesito un manual de hardware del modo protegido. Sobre todo usando el in y el out.


Gracias por leer y disculpen la molestia. Sé que no es su obligación contestar y si podría poner puntos lo haría :)




Nunca edito mis mensajes


* creo
#6
Programación C/C++ / Código basura de GCC?
1 Marzo 2013, 01:12 AM
EI: del Cache de Google:
cache:http://foro.elhacker.net/programacion_cc/codigo_basura_de_gcc-t384404.0.html





Hola a todos. A ver a ver cómo empezar...

Antes que nada, me disculpo de la forma cómo hablo ya que no soy muy bueno escribiendo en foros (sí en blogs, por ejemplo el mío). No quiero ofender a nadie.

Bueno, estoy programando un sistema operativo de 32 bits como hobby (No soy un novato más). Estuve como 5 meses leyendo y leyendo (claro, aparte del tiempo que estuve estudiando por mi cuenta asm de 16 bits - no mucho pero me sirvió para hacer un micro-so :P), haciendo pruebas y encontré un manual de paso a paso cómo iniciar un kernel. Bueno ya tengo mi kernel que inicia el GDT, IDT, el teclado, la disquetera, y algunas otras cosas (no menos importantes).

La cosa es que estuve programando y re-programando (volviendo a programar para corregir errores y mejorarlos) algunos drivers básicos (ya saben) y como tenía tanto código cada compilada se comenzaba a demorar más y más en compilar (y nada en ejecutar :D) y se me ocurrió cargar un archivo en la memoria y luego ejecutarlo (call).

Como siempre estuve haciendo pruebas tras pruebas, investigando como loco y cuando me puse a descansar un rato se me vino la solución a la cabeza y listo! pude ejecutar un archivo ensamblado con nasm en mi kernel usando una interrupción del IDT (int 0x80 - mostrar un texto en la pantalla) y todo funciona ok.

Ahora quise que un programa compilado con un lenguaje de alto nivel (C) se pudiera ejecutar en mi kernel y después de 2 días pude lograrlo.. A medias... Lo que pasa es que me ejecuta el código pero cuando termina la ejecución se genera un page fault (excepción) y estuve revisando el por qué, adjunto el código del archivo de C, el linker script, el batch y las imágenes que tengo:


LINKER SCRIPT (los comentarios que ves los agregué al postear)

ENTRY("_inicio")
SECTIONS
{
   . = 0x10000; // Aquí es donde ubica el kernel al programa
//lo demás no lo entiendo (no voy a mentir) aunque me solucionó un problema anterior (googleando lo encontré)
   .text :
   {
       code = .;
       *(.text)
       text_end = .;
   }
   .rodata :
   {
       rodata = rodata_end;
       *(.rodata)
       rodata_end  = .;    
   }  
   .rdata :
   {
       rdata = rdata_end;
       *(.rodata)
       rdata_end  = .;    
   }
   .data :
   {
       data = data_end;
       *(.data)
       data_end = .;
   }
   .bss :
   {
       bss = bss_end;
       *(.bss)
       bss_end = .;
   }
   end = .;
           /DISCARD/ :{
               *(.note*)
               *(.indent)
               *(.comment)
               *(.stab)
               *(.stabstr)
       }
}


PROGRAMA EN C (GCC)
void inicio(){
char* imprimir = "Hola mundo desde GCC (Intel Syntax, programa.exe) v2!";
asm(
"xor eax, eax\n" // función 0
"mov ebx, %0\n" // cadena
"int 0x80\n" // llama a la interrupción del kernel
:
: "m"(imprimir)
);
return;
}


BATCH

// Yo mismo lo hice xD

:X
cls

gcc -march=i686 -std=gnu99 -ffreestanding -c test.c -masm=intel // aquí hay un problema a mi parecer
ld -o test -Tlink.ld test.o //creo el archivo PE
objcopy -S -O binary test ..\programa.exe //genero un archivo binario en base al archivo PE
pause
goto X


Bueno acá van las imágenes.

1. Aquí veo un código "basura" el cual me parece que mi kernel no lo entiende o no sé que sea :S

CÓDIGO OBJETO OBTENIDO POR GCC. Lo seleccionado es lo que me parece que es el problema.



2. Aquí se repite el código. Extrañamente se fue al final del archivo binario :¬¬




Cuando borro el código seleccionado manualmente en el binario se ejecuta mi programa normalmente.

Por cierto mis primeros lenguajes de programación entre comillas fueron HTML, javascript (tenía 9 años xD), después a los 13 aprendí VB.NET que es el lenguaje que siento que soy muy bueno (llevo años..) y a los 17 (masomenos) aprendí C++ (me adapté al C luego :p) y asm tuve que estudiarlo a la fuerza (obviamente no soy tan bueno pero me defiendo). Todo esto fue por mi cuenta.

No sé si alguien podría ayudarme o darme una pista para poder entender qué cosa es ese código que sobra y cómo podría eliminarlo o no ejecutarlo.

POSDATA: Mi kernel ejecuta desde el indice 0 del archivo (no ejecuta PE ni ELF, sólo binarios)

Gracias por haber leído tal discurso :)
#7
Programación C/C++ / Driver kernel x64
21 Noviembre 2012, 02:29 AM
Hola, aquí estaba retomando la programación de un driver que dejé a la mitad.

Resulta que como ya sabrán muchos no se puede hookear api's (por lo que he entendido en foros y por experiencia propia) en sistemas x64. Lo que quisiera es creo yo cambiar la dirección de memoria (perdonen si no es como digo, es lo que creo) donde está por ejemplo la API NtCreateProcess y así aceptar o denegar el acceso a algún proceso mientras se esté creando.

Bueno, lo que pido es que si alguien conoce, aunque sea cómo se llama, cómo se podría hacer lo que estaba mencionando. Pido aunque sea una idea. Gracias :)
#8
ASM / Bootloader 32-bit y segmentación
2 Septiembre 2012, 04:53 AM
Buenas.

Les cuento que hace un tiempo comencé a aprender asm (assembly) por motivos que me pareció bastante interesante poder decirle a la computadora lo que quería y esta lo hacía sin ningún límite :o, así que como los sistemas de 32-bit como windows (por cierto tengo win8 de 64bits que no me deja hacer mucho...) y linux estaban limitados quise hacer un programa que corriera al inicio de la computadora, que muestre un mensaje y algo más... ;)

Bueno la cosa es que estuve a full averiguando ;-), imprimiendo manuales completos de asm.. y bueno he aprendido varias cosas pero existen algunos temas que no los entiendo por nada >:( como son La Segmentación que se requiere creo yo en el bootloader y en un kernel ( digo kernel porque queria un bootloader y un archivo ejecutable ). Digo esto debido a que por ejemplo quiero mostrar un mensaje y no lo muestra o lo hace incompleto.

He programado con FASM MASM y NASM pero más me gusta el nasm ya que es multisistema (así se llama creo).

Ya estaba trabajando en un minisistema operativo (resaltando "mini") que muestre un mensaje y pida una o mas teclas y todo funciona a la "perfección" a excepción que no puedo trabajar con 32 bits.

Cuando intento entrar al famoso modo protegido lógicamente no me deja usar interrupciones ya que está "protegido". Al tener este problema investigué y encontré algunos temas (en inglés por cierto) que tengo que escribir directamente en la memoria pero tampoco no me funciona...

Bueno esas son todas mis dudas por el momento. :)

Lo que quiero hacer en conclusión es un bootloader de 16 bits que lea un kernel.bin y este kernel pase de 16 bits a 32 bits y muestre un mensaje. NADA MÁS :xD

¿Alguien me podría explicar por favor? y disculpen la molestia ;D
#9
Hola que tal :D soy nuevo aquí :P.

Tengo un driver creado con el DDK y lo que quisiera es obtener la ruta del proceso que se va a ejecutar hookeando a NewZwOpenProcess.

He conseguido obtener el nombre del proceso en C++ pero con el DDK no me funciona ya que dice que tlhelp32.h no existe; además no creo que ese archivo funcione con el DDK ( como es C.... ).

Mi driver tiene el siguiente código:

#include "ntddk.h"

typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function)KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]

int typedef DWORD (ULONG);
PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;

#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig )_Orig = (PVOID) InterlockedExchange( (PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Hook)
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig )InterlockedExchange( (PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Hook)

//Declaramos la API para poder trabajar con ella.
NTSYSAPI NTSTATUS NTAPI ZwOpenProcess (OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
typedef NTSTATUS (*TypZwOpenProc)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
TypZwOpenProc ZwOpenProcessIni;

void ObternerRuta( int pid );

NTSTATUS NewZwOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL)
{
HANDLE PID;
__try //Utilizamos el bloque try para evitar BSOD
{
PID = ClientId->UniqueProcess;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return STATUS_INVALID_PARAMETER;
}

DbgPrint("PID: 0x%x",PID);
//CORREGÍ UN ERROR ACÁ :P
if (ObternerRuta(PID)== "C:\\miprograma.exe") return
STATUS_ACCESS_DENIED; //Retornamos acceso denegado
else
return ZwOpenProcessIni(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId); //Llamamos a la API nativa y retornamos el resultado correcto
}

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("Descargando driver...");

//Unhookeamos
UNHOOK_SYSCALL( ZwOpenProcess, ZwOpenProcessIni, NewZwOpenProcess );

//Eliminamos la MDL
if(g_pmdlSystemCall)
{
MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
IoFreeMdl(g_pmdlSystemCall);
}
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath)
{
DriverObject->DriverUnload = OnUnload;
DbgPrint("Driver cargado");
ZwOpenProcessIni =(TypZwOpenProc)(SYSTEMSERVICE(ZwOpenProcess));

//Creamos la MDL para deshabilitar la protección de memoria
g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
if(!g_pmdlSystemCall)
return STATUS_UNSUCCESSFUL;

MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedSystemCallTable = (PVOID*)MmMapLockedPages(g_pmdlSystemCall, KernelMode);
DbgPrint("Hookeando...");
HOOK_SYSCALL( ZwOpenProcess, NewZwOpenProcess, ZwOpenProcessIni );

return STATUS_SUCCESS;
}

void ObternerRuta( int pid )
{
//AQUÍ ME FALTA CÓDIGO
}



¿ALGUIEN ME PODRÍA AYUDAR POR FAVOR? Gracias