21 enero 2009

CM-Ezine #1

Hola, aca una e-zine de code-makers, la #1!

http://foro.code-makers.es/1_cm_ezine-t3059.0.html

(salio hace un mes xD me re olvide de postearlo aca)

salu2!

Tipo struct y union en C

Hola
vamos a explicar struct y union en C Lengua :D :D

los 2 son un tipo de dato,con struct (llamado RECORD en otros lenguajes) lo que hacemos es meter diferentes variables bajo un solo "paquete", osea, es como si tubiesemos diferentes cajitas desparramadas por todos lados, y para mantener un poco el orden las metemos todas esas cajitas dentro de una mas grande. las caja grande es el "struct" y las cajas chiquitas son las otras variables que contiene el struct. para usar struct hacemos

Código
struct tipo_struct {
tipo_variable nombre;
tipo_variable2 nombre2;
/*etc.*/
} nombre_struct;
dentro de los { } ponemos todas las variables que queramos, estas variables no las podemos iniciar con algun valor,osea, algo asi
Código
struct {
int i = 3;
}ent;
da error
el tipo_struct es optativo, al igual que nombre_struct, pero no tiene gracia dejar sin ningun nombre a la escructura xD
el nombre_struct es para ya tener la struct declarada, lista para usar, y el tipo_struct es para definir la struct.
para poder acceder a los elementos de la struct tenemos que hacer
nombre_struct.nombre
osea, el nombre de la estructura + punto + nombre de la variable
de esta forma trabajamos con esa variable como cualquier otra
veamos unos ejemplos para enteder esto de "tipo_struct" y "Nombre_struct" y como funciona:

Código
struct tipouno {
char texto[20];
short c;
int len;
};

struct {
int i;
char x;
}nombreuno;

struct tipodos {
char *p;
} nombredos;

/*tipouno solo esta definida, pero no declarada, con hacer struct tipo_struct nuevo_nombre
la declaramos para que tenga un espacio de memoria y la podamos usar*/

struct tipouno jose;
/*tipodos ya esta declarada como nombredos pero de todas maneras
dado que le pusimos nombre a tipo_struct podemos hacer mas structs del mismo tipo*/

struct tipodos pepe, manuelita;

/*nombreuno ya esta definida asique la podemos usar normalmente*/
nombreuno.x = 'a';
jose.c = nombreuno.x;
/*ahora fijense que utilizo los punteros como siempre*/
manuelita.p = &(nombreuno.i);
*(manuelita.p) = 4;

tambien podemos tener un puntero a una estructura, por ejemplo:
Código
struct estructura{
int i;
char x;
} *puntero;
/*fijense como el tipo_struct se puede utilizar en sizeof */
puntero=malloc(sizeof(struct estructura));
/*y ahora 2 metodos para utilizar punteros*/
(*puntero).i = 3;
puntero->i = 3;

un dato importante es que con struct tenemos todas las variables una al lado de la otra, osea, por ejemplo si dentr de un struct tenemos un int y 3 char, en memoria aparecen
[int][char][char][char]
uno al lado del otro, consecutivos.

muy bien, eso es struct
union se utiliza igual que struct, igual igual. pero cambia la forma en que pone las variables en la memoria.
la unica diferencia es que con union tenemos todas las variables una "arriba" de la otra, osea, si tenemos
Código
union {
int i;
char c;
short x;
}miunion;
la posicion de memoria de i ( &(miunion.i) ) y de c ( &(miunion.c) ) y de x ( &(miunion.x) ) es LA MISMA,
vean esto y quisa lo entiendan mejor:

Código
union {
short i;
char c;
}miunion;

miunion.i = 0xFFFF;
printf("%X\n", miunion.i); /*aca imprime FFFF*/
miunion.c = 'N';
printf("%c\n", miunion.c); /*aca imprime N*/
/*ojo con esta:*/
printf("%X\n", miunion.i); /*aca imprime FF4E*/
/*eso es porque el 0x4E de c se superpuso a i*/

(no, no deberia ser 4EFF, i y c estan en el mismo lugar, pero por un problema de intel y de la "little-order" el primer byte de menor peso de una variable se coloca en la posicion mas baja de memoria, por eso aparece FF4E, es complicado de explicar...)



bueno, creo que eso es todo

salu2!

20 enero 2009

Crear Drivers para Linux en C

Hola! aca hize una traduccion de un tutorial que me lei, como es largo (y para hacer spam cof cof) les doy el link:
http://foro.code-makers.es/creando_drivers_para_linux_en_c-t3231.0.html;msg16151
como el foro esta re muerto y es mas probable que Jason Becker vuelva a tocar a que Code Makers reviva, pude hacer una copia del foro...:
http://www.badongo.com/file/14910699

pronto lo voy a postear completo en el blog, asi si badongo me llega a eliminar el archivo, sige estando en el blog (y en mi pc)

espero que se entienda y que lo disfruten!

salu2!

06 enero 2009

BrainFuck Compiler MS-DOS

Hola, hice un compilador de BrainFuck
el CODIGO es para cualquier S.O., pero el programa COMPILA a .com, asique solo con MS-DOS (o Windows) lo pueden ejecutar.
si en la entrada de datos del programa .com (osea, el brainfuck compilado) precionas ESC, es como un 0 (cero) para el programa
aca completo,

http://sites.google.com/site/ni0sources/Home/bfc-1.0-w.rar?attredirects=0
http://www.badongo.com/file/16542919


el exe que incluye (osea, el codigo ya compilado) esta para MS-DOS (esta en 16 bits, lo compile con el Turbo C)

/*
BrainFuck Compiler
*/

/*
Ni0 http://ni0.blogspot.com ni0@el-hacker.org
SSW Team http://sswteam.wordpress.com
*/

/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/



#include stdio.h
#include string.h
#include stdlib.h

#define MAXJUMPS 500

/*codigos en asm del brainfuck
si terminan con _ significa que el primer
byte es la cantidad de bytes a copiar,
si no tiene _ uso strlen()*/

/*asm codes of the brainfuck
if they end with an _, it means the first byte
is the size of the array,
if it does not end with an _, i use
strlen()*/


char start_[] =
/*mov si,0xEFFF
b:
cmp si,0xBFFFF
jz a
mov byte [si],0
dec si
jmp b
a:
inc si*/

{
16, 0xBE, 0xFF, 0xEF, 0x81, 0xFE, 0xFF, 0xBF, 0x74, 0x06,
0xC6, 0x04, 0x00, 0x4E, 0xEB, 0xF4, 0x46
};

char starti_[] =
/*mov si, 0x9000*/
{
3, 0xBE, 0x00, 0x90
};

char end[] =
/*xor ah,ah
int 0x21*/

{
0x30,0xE4,0xCD,0x21, 0
};

char buffover_[] =
/*cmp si,0xF000
jnz a
xor ah,ah
int 21
a:*/

{
10, 0x81, 0xFE, 0x00, 0xF0, 0x75, 0x04, 0x30, 0xE4, 0xCD, 0x21
};

char buffunder[] =
/*cmp si, 0xBFFF
ja a
xor ah,ah
int 21
a:*/

{
0x81, 0xFE, 0xFF, 0xBF, 0x77, 0x04, 0x30, 0xE4, 0xCD, 0x21, 0
};

char Ni0[] = " BFC - Ni0 - SSW ";


char add[] =
/*inc byte [si]*/
{
0xFE,0x04,0
};

char add2[] =
/*inc word [si]*/
{
0xFF, 0x04, 0
};

char sub[] =
/*dec byte [si]*/
{
0xFE,0x0C, 0
};

char sub2[] =
/*dec word [si]*/
{
0xFF, 0x0C, 0
};

char next[] =
/*inc si*/
{
0x46,0
};

char prev[] =
/*dec si*/
{
0x4E,0
};

char in[] =
/*mov ah,1
int 0x21
cmp al,0x0D
jnz b
mov al,0x0A
mov dl,al
mov ah,02
int 0x21
b:
cmp al,0x1B
jnz a
xor al,al
a:
mov [si],al*/

{
0xB4, 0x01, 0xCD, 0x21, 0x3C, 0x0D, 0x75, 0x08, 0xB0,
0x0A, 0x88, 0xC2, 0xB4, 0x02, 0xCD, 0x21, 0x3C, 0x1B,
0x75, 0x02, 0x30, 0xC0, 0x88, 0x04, 0
};

char in2_[] =
/*inc si
mov [si],0
dec si*/

{
5, 0x46, 0xC6, 0x04, 0x00, 0x4E
};

char out[] =
/*mov ah,02
mov dl,[si]
int 0x21
cmp byte [si],0x0A
jnz a
mov dl,0x0D
mov ah,02
int 0x21
a:
*/

{
0xB4,0x02,0x8A,0x14,0xCD,0x21, 0x80, 0x3C, 0x0A, 0x75, 0x06, 0xB2,
0x0D, 0xB4, 0x02, 0xCD, 0x21, 0
};

char jz[] =
/*xor al,al
cmp [si],al
jz 0xFFFF*/

{
0x30, 0xC0, 0x38, 0x04, 0x0F, 0x84, 0xFF, 0xFF, 0
};

char jz2[] =
/*xor ax,ax
cmp [si],ax
jz 0xFFFF*/

{
0x31, 0xC0, 0x39, 0x04, 0x0F, 0x84, 0xFF, 0xFF, 0
};

char jmp[] =
/*jmp 0xFFFF*/
{
0xE9, 0xFF, 0xFF, 0
};

/*las verciones en ingles y en castellano*/
/*english and spanish version*/

char *chelp;
char chelpen[] = "\nBrainFuck Compiler by Ni0\nni0@el-hacker.org\nhttp:\\\\ni0.blogspot.com\n\nCompile a BranFuck code to a .com program\n"
"\nUsage: %s file_in [-o file_out][-n][-b][-i][-2][-h][-e]\n"
"\nfile_in\ta BrainFuck code"
"\n[-o]\tset another file (file_out) where the code will be compiled\n\tthe default file is file_in.com"
"\n[-n]\tthe string \" BFC - Ni0 - SSW \" won't be added at the end of the file"
"\n[-b]\ta bufferoverflow check won't be added to the program"
"\n[-i]\tdo not initialize the array to 0"
"\n[-2]\tuse 2 bytes for the array (default 1 byte)"
"\n[-h]\tshow this help\n\n"
"\nto get the binary file as short as this compiler can, use the -n, -b and -i\nexample: %s mycode.bf -n -b -i\n";
char chelpes[] = "\nBrainFuck Compiler by Ni0\nni0@el-hacker.org\nhttp:\\\\ni0.blogspot.com\n\nCompila un codigo en BrainFuck a un programa .com\n"
"\nUso: %s entrada [-o salida][-n][-b][-i][-2][-h][-e]\n"
"\narchivo_entrada\tun codigo en BrainFuck"
"\n[-o]\tespecifica otro archivo (archivo_salida) donde el codigo va a ser compilado\n\tel archivo por defecto es archivo_entrada.com"
"\n[-n]\tla cadena \" BFC - Ni0 - SSW \" no sera colocada al final del archivo"
"\n[-b]\tno se le colocara un chekeo de desbordamiento al programa"
"\n[-i]\tno inicializa el array en 0"
"\n[-2]\tusa 2 bytes para el array (por defecto es 1 byte)"
"\n[-h]\tmuestra esta ayuda"
"\n[-e]\tcompilador en ingles (the compiler in english)\n\n"
"\npara obtener el archivo binario lo mas chico posible, usar los argumentos -n, -b y -i\nejemplo: %s micodigo.bf -n -b -i\n";

char *cusage;
char cusageen[] = "\nUsage: %s file_in [-o file_out][-n][-b][-i][-2][-h][-e]\nType %s -h para ayuda en castellano, or -h -e for english help\n";
char cusagees[] = "\nUso: %s entrada [-o salida][-n][-b][-i][-2][-h][-e]\nponer %s -h para ayuda, o -h -e for english help\n";

char *cfilene;
char cfileneen[] = "\nERROR: File %s does not exist\n";
char cfilenees[] = "\nERROR: El archivo %s no existe\n";

char *cfileno;
char cfilenoen[] = "\nERROR: File %s could not be opened\n";
char cfilenoes[] = "\nERROR: El archivo %s no se pudo abrir\n";

char *cmaxjumps;
char cmaxjumpsen[] = "\nERROR (%s : char %d) : there are %d \'[\' without \']\'\n";
char cmaxjumpses[] = "\nERROR (%s : caracter %d) : hay %d \'[\' sin \']\'\n";

char *cexpectend;
char cexpectenden[] = "\nERROR (%s : char %d) : there is a \']\' without a \'[\'\n";
char cexpectendes[] = "\nERROR (%s : caracter %d) : hay un \']\' sin un \'[\'\n";

char *cbig;
char cbigen[] = "\nERROR (%s) : the code is too large (more than 48kb), there is not free space for the array\n";
char cbiges[] = "\nERROR (%s) : el codigo es muy largo (mas de 48kb), no hay espacio libre para el vector\n";

char *cexpectbegin;
char cexpectbeginen[] = "\nERROR (%s) : expected \']\' before end of file\n";
char cexpectbegines[] = "\nERROR (%s) : se esperaba \']\' antes del fin de archivo\n";

char *ccompiled;
char ccompileden[] = "\nCompiled!\nsource = %s\nout = %s\n8/16 bits (1/2 bytes) = %d\ntotal bytes = %d\n";
char ccompiledes[] = "\nCompilado!\nfuente = %s\nsalida = %s\n8/16 bits (1/2 bytes) = %d\nbytes totales = %d\n";

void setenglish(void)
{
chelp = chelpen;
cusage = cusageen;
cfilene = cfileneen;
cfileno = cfilenoen;
cmaxjumps = cmaxjumpsen;
cexpectend = cexpectenden;
cbig = cbigen;
cexpectbegin = cexpectbeginen;
ccompiled = ccompileden;
}

void setspanish(void)
{
chelp = chelpes;
cusage = cusagees;
cfilene = cfilenees;
cfileno = cfilenoes;
cmaxjumps = cmaxjumpses;
cexpectend = cexpectendes;
cbig = cbiges;
cexpectbegin = cexpectbegines;
ccompiled = ccompiledes;
}

/*cuando hay un error...*/
/*when there is an error...*/

void comperror(int ec, FILE *f1, FILE *f2, char *rem)
{
fclose(f1);
fclose(f2);
remove(rem);
exit(ec);
}

/*checkea que todos los argumentos esten permitidos, s = argumentos permitidos*/
/*make a check of the arguments to see if they are allowed, s = arguments allowed*/

int checkarg(int argc, char **argv, char *s)
{
int i, is, ic;
char ca[50], flag;
if(s == 0){
if(argc != 1)
return 1;
else
return 0;
}
if(!strcmp(s, ""))
return 0;
for(i = 1; i != argc; i++){
is = 0;
/*chekea el argumento actual con los argumentos permitidos*/
/*checks the current argument with the arguments allowed*/
while(s[is] != 0){
ca[0] = 0;
ic = 0;
if(s[is] == ' ')
is++;
while(s[is] != ' ' && s[is] != 0){
ca[ic] = s[is];
ic++;
is++;
}
ca[ic] = 0;
/*con el %s permite cualquier argumento que No empieze con - */
/*with the %s, allows all the arguments wich Not starts with - */
if(!strcmp(ca, "%s")){
if(argv[i][0] != '-')
flag = 0;
else
flag = 1;
}
else
flag = strcmp(ca, argv[i]);
if(flag == 0)
break;

}
if(flag != 0)
return i;
}
return 0;
}

/*devuelve la posision de un argumento especifico (s)*/
/*return an especific argument (s) position*/

int isarg(int argc, char **argv, char *s)
{
int i;
if(s == 0 || !strcmp(s, ""))
return 0;
for(i = 1; i != argc; i++){
if(!strcmp(argv[i], s))
return i;
}
return 0;
}

int main(int argc, char **argv)
{
FILE *i, *o;/*archivo entrada (i), archivo salida (o)*//*file in (i), file out (o)*/
fpos_t fp;
/*nombre del archivo salida (fo), word = 1 => 16 bits, buf = 1 => checkeo de desbordamiento*/
/*file out name (fo), word = 1 => 16 bits, buf = 1 => overflow check*/
char fo[100], c, word = 0, buf = 1;
/*vector con los saltos (jumps), posision en el vector jumps (jpos)*/
/*jumps array (jumps), position in the jumps array (jpos)*/
int jmps[MAXJUMPS], ar, jpos;
unsigned int pos;/*posision en el archivo salida*//*file out position*/
if(isarg(argc, argv, "-e") != 0)
setenglish();
else
setspanish();
if(isarg(argc, argv, "-h") != 0){
printf(chelp, argv[0], argv[0]);
return -1;
}
if(checkarg(argc, argv, "%s -o -n -b -i -h -2 -e") != 0 || argc < 2 || argv[1][0] == '-'){
printf(cusage, argv[0], argv[0]);
return -1;
}
i = fopen(argv[1], "r");
if(!i){
printf(cfilene, argv[1]);
return -1;
}
ar = isarg(argc, argv, "-o");
if(ar != 0){
/*se especifico otro archivo de salida...*/
/*another out file was set...*/
if(ar + 1 < style="color: rgb(102, 204, 102);">[ar+1][0] != '-' && strcmp(argv[ar+1], argv[1]) != 0)
strcpy(fo, argv[ar+1]);
else{
/*se olvido de poner el nombre despues del -o*/
/*he forgot putting the name after -o*/
fclose(i);
printf(cusage, argv[0], argv[0]);
return -1;
}
}
else{
strcpy(fo, argv[1]);
strcpy(strchr(fo, '.') == 0 ? fo + strlen(fo) : strchr(fo, '.'), ".com");
}
o = fopen(fo, "wb+");
if(!o){
fclose(i);
printf(cfileno, fo);
return -1;
}
ar = isarg(argc, argv, "-i");
if(ar != 0){
fwrite(starti_ + 1, 1, starti_[0], o);
pos = starti_[0];
}
else {
fwrite(start_ + 1, 1, start_[0], o);
pos = start_[0];
}
ar = isarg(argc, argv, "-2");
if(ar != 0)
word = 1;
ar = isarg(argc, argv, "-b");
if(ar != 0)
buf = 0;
jpos = 0;
c = fgetc(i);
while(!feof(i)){
switch(c){
case '+':
if(word){
fputs(add2, o);
pos += strlen(add2);
break;
}
fputs(add, o);
pos += strlen(add);
break;
case '-':
if(word){
fputs(sub2, o);
pos += strlen(sub2);
break;
}
fputs(sub, o);
pos += strlen(sub);
break;
case '>':
/*si es de 16 bits, pongo 2 veces el codigo next*/
/*if it is in 16 bits, i put twice the next code*/
if(word){
fputs(next, o);
pos += strlen(next);
}
fputs(next, o);
pos += strlen(next);
if(buf){
fwrite(buffover_ + 1, 1, buffover_[0], o);
pos += buffover_[0];
}
break;
case '<':
if(word){
fputs(prev, o);
pos += strlen(prev);
}
fputs(prev, o);
pos += strlen(prev);
if(buf){
fputs(buffunder, o);
pos += strlen(buffunder);
}
break;
case '.':
fputs(out, o);
pos += strlen(out);
break;
case ',':
fputs(in, o);
pos += strlen(in);
if(word){
fwrite(in2_ + 1, 1, in2_[0], o);
pos += in2_[0];
}
break;
case '[':
if(jpos == MAXJUMPS - 1){
fgetpos(i, &fp);
printf(cmaxjumps, argv[1], fp, MAXJUMPS);
comperror(1, i, o, fo);
}
if(word){
fputs(jz2, o);
pos += strlen(jz2);
jmps[jpos] = pos;
jpos++;
break;
}
fputs(jz, o);
pos += strlen(jz);
jmps[jpos] = pos;
jpos++;
break;
case ']':
if(jpos == 0){
fgetpos(i, &fp);
printf(cexpectend, argv[1],fp);
comperror(1, i, o, fo);
}
jpos--;
/*aca calculo bien el salto*/
/*here I calculate the jump*/
fseek(o, jmps[jpos] - strlen(jz) + 6 , SEEK_SET);
fputc((char)((pos - jmps[jpos] + strlen(jmp)) & 0xFF), o);
fputc((char)((pos - jmps[jpos] + strlen(jmp)) / 0x100), o);
fseek(o, pos, SEEK_SET);
fputs(jmp, o);
pos += strlen(jmp);
fseek(o, -2, SEEK_CUR);
fputc((char)(0xFFFF - (pos - (jmps[jpos] - strlen(jz)))) + 1, o);
fputc((char)(((0xFFFF - (pos - (jmps[jpos] - strlen(jz)))) + 1) / 0x100), o);
break;
}
if(pos >= 0xBF00){
printf(cbig, argv[1]);
comperror(1, i, o, fo);
}
c = fgetc(i);
}
fputs(end, o);
pos += strlen(end);
if(!isarg(argc, argv, "-n")){
fputs(Ni0,o);
pos += strlen(Ni0);
}
if(jpos != 0){
printf(cexpectbegin, argv[1]);
comperror(1, i, o, fo);
}
fclose(i);
fclose(o);
printf(ccompiled, argv[1], fo, word == 1 ? 16 : 8, pos);
return 0;
}

salu2!