quinta-feira, 12 de julho de 2012

hex-to-ascii elisp function to fast decode protected donwload urls

Is really common to face download urls being "protected" but some annoying ringtone site. Some of then are so stupid that just encode the url as an hexadecimal string. Here is an example http://www.baixedetudo.net/id/?url=687474703a2f2f756c2e746f2f6f7977366b667732. Is easy to see the url here. I used perl to decode this, simple as in
print pack("H*", "687474703a2f2f756c2e746f2f6f7977366b667732"), "\n";
But as much I become an "emacs guy" more I do to easy my life.
Here is what I use from now to translate urls from hex to ascii The function usage is simple, just select the hex text and run it, you should get the translated text on clipboard.. You should be running emacs in its graphical form.
(defun hex-to-ascii (b e)
  "Translate the region from hex to ascii and copy it to clipboard.
I use that to translate urls in hex and paste it to url bar on my
browser."
  (interactive "r")
  (save-excursion
    (let ((i e)
           (x-select-enable-clipboard t)
           s)
      (while (> i b)
        (setq s (concat (format "%c" (read (concat "#x" (buffer-substring-no-properties (- i 2) i)))) s))
        (setq i (- i 2)))
      (kill-new s t)
      (message (format "%s copied to clip board" s)))))

I just keep this on my init.el.

Also I have done the opposite, a function that takes ascii string and returns its hex representation 
(defun ascii-to-hex (b e)
  "Translate an ascii string to a hex string and copy it to clipboard"
  (interactive "r")
  (save-excursion
    (let ((i b)
          (x-select-enable-clipboard t)
          s)
      (while (< i e)
        (setq s (concat s (format "%x" (get-byte i))))
        (setq i (+ i 1)))
      (kill-new s t)
      (message s))))

Nice and Easy :-)

quarta-feira, 11 de julho de 2012

elisp - get lines of text to a list

Here is an example of how get lines of text on a list.. I think I will use this on future for process text... Also I'm exercising my elisp skills since I want to be able to process text programmatically.
;; This text will be obtained 
;; by the function get-lines
;; It takes two parameters
;; The first being the start line (inclusive)
;; from with the text will be gathered 
;; The second being the end line (exclusive)
;; Nice and easy!! :-)

(defun get-beginning-of-line ()
  "Get the point at the beginning of line"
  (save-excursion
    (beginning-of-line)
    (point)))

(defun get-end-of-line ()
  "Get the point at the end of line"
  (save-excursion
    (end-of-line)
    (point)))

(defun programmatic-goto-line (line)
  "As goto-line but better for programming stuff"
  (goto-char (point-min))
  (forward-line (- line 1)))


(defun get-lines (start-line end-line)
  "Return a list with the lines between START-LINE (inclusive) and END-LINE (exclusive)"
  (save-excursion
    (programmatic-goto-line end-line)
    (let (lines)
      (while (< start-line (line-number-at-pos))
        (forward-line -1)
        (setq lines (cons (buffer-substring-no-properties (get-beginning-of-line) (get-end-of-line)) lines)))
      lines)))
      
               
;; Example
(let (v)
  (dolist (v (get-lines 1 7))
    (princ (format "%s\n" v))))

;; This text will be obtained 
;; by the function get-lines
;; It takes two parameters
;; The first being the start line (inclusive)
;; from with the text will be gathered 
;; The second being the end line (exclusive)
nil


sexta-feira, 6 de julho de 2012

My two "just arrived" new kernel books

Understading the Linux Kernel 

amd Linux Device Drivers

terça-feira, 3 de julho de 2012

Resolving names and IPs

Here is two examples of name resolving in linux.. I use getaddrinfo() and getnameinfo() respectively..


getaddrinfo: given a name retuns all translated IPs, one per line
/*
 * File: getaddrinfo.c
 * Compile: gcc getaddrinfo.c -o getaddrinfo
 * Usage: ./getaddrinfo FQN
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
        int error;

        struct addrinfo saddr, *psaddr, *ptr;

        memset(&saddr, '\0', sizeof(saddr));
        saddr.ai_family = AF_INET;


        saddr.ai_socktype = SOCK_STREAM;

        error = getaddrinfo(argv[1], NULL, &saddr, &psaddr);
        if (error) {
                fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
                exit(EXIT_FAILURE);
        }

        for (ptr = psaddr; ptr; ptr = ptr->ai_next) {
                puts(inet_ntoa(((struct sockaddr_in *)    
                               ptr->ai_addr)->sin_addr));
        }

        return 0;
}

getnameinfo: Given an IP returns the name that first resolves to it. 
/*
 * File: getnameinfo.c
 * Compile: gcc getnameinfo.c -o getnameinfo
 * Usage: ./getnameinfo IP
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

static char hostname[255];

int main(int argc, char **argv)
{
        int error;
        struct sockaddr_in saddr_in;



        memset(&saddr_in, '\0', sizeof(saddr_in));
        saddr_in.sin_family = AF_INET;
        error = inet_aton(argv[1], &saddr_in.sin_addr);
        if (error == 0) {
                perror("inet_aton");
                exit(EXIT_FAILURE);
        }

        error = getnameinfo((struct sockaddr *)&saddr_in, sizeof(saddr_in),
                            hostname, sizeof(hostname),
                            NULL, 0, NI_NAMEREQD);
        if (error) {
                fprintf(stderr, "getnameinfo: %s\n", gai_strerror(error));
                exit(EXIT_FAILURE);
        }

        puts(hostname);
        return 0;
}


Cheers

terça-feira, 17 de abril de 2012

My first shellcode :)

/*
 * File: shello.c
 *
 * Generated from this assembly code:
 *      pushl   %ebp
 *      movl    %esp, %ebp
 *      
 *      subl    $12, %esp
 *      movl    $0x6c6c6548, -12(%ebp)
 *      movl    $0x6f57206f, -8(%ebp)
 *      movl    $0x0a646c72, -4(%ebp)
 *      
 *      movl    $4, %eax        
 *      movl    $1, %ebx
 *      leal    -12(%ebp), %ecx 
 *      movl    $12, %edx 
 *      
 *      int     $0x80
 *      addl     $12, %esp
 *      
 *      leave
 *      ret
 * 
 */

/*
 * Tested on Linux hilstdsk 3.2.7-1-ARCH #1 SMP PREEMPT Tue Feb 21
 * 16:59:04 UTC 2012 i686 AMD Athlon(tm) 64 X2 Dual Core Processor
 * 4400+ AuthenticAMD GNU/Linux
 * Archlinux
 */

/*
 * Compile: gcc -o shello shello.c
 * Run: ./shello
 * Output: Hello World
 */
 
/*
 * Thats pretty cool!
 */
#include 

static char shellcode[] = "\x55"
        "\x89\xe5"
        "\x83\xec\x0c"
        "\xc7\x45\xf4\x48\x65\x6c\x6c"
        "\xc7\x45\xf8\x6f\x20\x57\x6f"
        "\xc7\x45\xfc\x72\x6c\x64\x0a"
        "\xb8\x04\x00\x00\x00"
        "\xbb\x01\x00\x00\x00"
        "\x8d\x4d\xf4"
        "\xba\x0c\x00\x00\x00"
        "\xcd\x80"
        "\x83\xc4\x0c"
        "\xc9"
        "\xc3";

int main(void)
{
        void (*p)(void);
        p = shellcode;
        p();
        return 0;
}

segunda-feira, 19 de março de 2012

My first elisp function

;; This is my first elisp function, it helps me to write functions
;; that surround text by HTML tags.
(defun surround-by-tag (begin end topen tclose)
  "Surround selected text by HTML tags"
  (goto-char begin)
  (insert topen)
  (goto-char (+ end (length topen)))
  (insert tclose))


;; Here is how to use it. I define a function and calls
;; surround-by-tag passing the begin and end of my selection
;; as the open and close tags. 
(defun p (b e)
  "Surround text by <p></p>"
  (interactive "r")
  (surround-by-tag b e "<p>" "</p>"))

(defun pre (b e)
  "Surround text by <pre></pre>"
  (interactive "r")
  (surround-by-tag b e "<pre>" "</pre>"))


;; Then I select my text and use the defined interactive function
;; <p>Hello elisp world</p>

sábado, 10 de março de 2012

regex example

/*
 * File: regex.c
 * 
 * This is a sample regex usage, gets three arguments. It is a grep
 * like tool.  
 * -f <FILE> -> A file to be read if omited or - stdin is read 
 * -p <PATTERN> -> The pattern to be matched agains every line on FILE 
 * -v -> Invert the match, as like grep -v.
 *
 * Compiling: gcc -o preg regex.c 
 */
 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <regex.h>
#include <unistd.h>
#include <getopt.h>



int main(int argc, char **argv)
{
        regex_t reg;
        char pattern[256];
        int status;
        char buf[256];
        FILE *fp = NULL;
        int opt;
        int inverted = 0;
        
        while ((opt = getopt(argc, argv, "vp:f:")) != -1) {
                switch (opt) {
                case 'v':
                        inverted = 1;
                        break;
                case 'p':
                        strncpy(pattern, optarg, 256);
                        break;
                case 'f':
                        if (optarg[0] == '-') {
                                fp = stdin;
                        } else {
                                fp = fopen(optarg, "r");
                                if (!fp) {
                                        perror("fopen");
                                        exit(EXIT_FAILURE);
                                }
                        }
                        break;
                }
                /* printf("%c\n", opt); */
        }

        if (!fp)
                fp = stdin;

        status = regcomp(&reg, pattern, REG_EXTENDED | REG_NOSUB);
        if (status != 0)
        {
                fprintf(stderr, "Compiling the regular expression \"%s\" failed.\n", pattern);
                exit(EXIT_FAILURE);
        }


        while (fgets(buf, 256, fp)) {
                status = regexec(&reg, buf,
                                 /* nmatch = */ 0,
                                 /* pmatch = */ NULL,
                                 /* eflags = */ 0);

                if (inverted ? status : !status) {
                        printf("%s", buf);
                }
        }

        return 0;
}

quarta-feira, 15 de fevereiro de 2012

Capture idle "percentage" in C

This program will read /proc/stat an calculum the amount of time that computer was idle...


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define BUFLEN 256
static char buf[BUFLEN];


int strsplit (char *string, char **fields, size_t size);

int main(void)
{
        FILE *stat;
        char *fields[9];        
        int numfields;

        unsigned int ncores;

        unsigned int idle;
        unsigned int old_idle = 0;

        
        while (1) {
                /*
                 * The cpu sum line SHOULD be the first line
                 * on /proc/stat, or things will get wrong.
                 */
                if ((stat = fopen("/proc/stat", "r")) == NULL) {
                        perror("fopen");
                        exit(EXIT_FAILURE);
                }

                fgets(buf, BUFLEN, stat);

                numfields = strsplit (buf, fields, 9);
                if (numfields < 5) {
                        fprintf(stderr, "To few fields\n");
                        exit(EXIT_FAILURE);
                }
                
                ncores = sysconf(_SC_NPROCESSORS_ONLN); /* number of cores */
                idle = atoi(fields[4]);
                printf("idle %d%%\n", (idle - old_idle) / ncores);
                old_idle = idle;
                
                fclose(stat);
                sleep(1);
        }                        

        return 0;
}

int strsplit (char *string, char **fields, size_t size)
{
        size_t i;
        char *ptr;
        char *saveptr;

        i = 0;
        ptr = string;
        saveptr = NULL;
        while ((fields[i] = strtok_r (ptr, " \t\r\n", &saveptr)) != NULL)
        {
                ptr = NULL;
                i++;

                if (i >= size)
                        break;
        }

        return ((int) i);
}

quarta-feira, 25 de janeiro de 2012

Creating C libraries/extensions/binds to Lua

I'm training the C API of lua.. planning to create extensions to awesome window manager (the one I use) -> http://awesome.naquadah.org/. Here is a "Lua calling C" hello world.


/*
 * File: hellolib.c
 *
 * Compile: 
 * gcc -Wall -fPIC -c hellolib.c && gcc -shared -Wl -o libhellolib.so hellolib.o
 *
 * Calling from lua:
 *
 * > hello_lib = package.loadlib("/home/geckos/programming/lua/libhellolib.so", "lua_open_hellolib")()
 * > 
 * > 
 * > hello_lib.hello_from_c()
 * Hello from C world to lua
 * > 
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>


static int hello_from_c(lua_State *L)
{
 puts("Hello from C world to lua");
 return 0;
}

static const struct luaL_reg hello_lib[] = {
 { "hello_from_c", hello_from_c },
 { NULL, NULL },
};

int lua_open_hellolib(lua_State *L)
{
 luaL_openlib(L, "hello_lib", hello_lib, 0);
 return 1;
}


quinta-feira, 5 de janeiro de 2012

TCP Flooder with pthreads

/**
 * This code creates N threads. Each threads does one GET to an address. The
 * GET, the address and the number of threads are passed as argument. An "\r\n"
 * is appended to the GET string. 
 */
/* headers *//*{{{*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pthread.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netdb.h>/*}}}*/

/* declarations and prototypes */ /*{{{*/
#define pexit(s) ({perror(s); exit(exit_failure);})
static struct cstats { 
        int socket_errors;
        int send_errors;
        int recv_errors;
        int connect_errors;
        int avg_respt; /* average response time */
        pthread_mutex_t mutex;
} cstats;
        

struct sockaddr_in addr;

#define buflen 1024
static char buf[buflen];
static int buf_len;

void *get_get_thread(void *);/*}}}*/

int main(int argc, char **argv)
{
        /* main declarations *//*{{{*/
        int i;
        int fail = 0;
        int ngets;
 int addr_len;
 int error;
 struct hostent *host;
        pthread_t *threadv;
        pthread_attr_t attr;/*}}}*/
  
        /* error checking *//*{{{*/
 if (argc <= 4) { 
  printf("usage: %s address port number_of_gets get_string\n", argv[0]);
  exit(exit_failure);
 }


        ngets = atoi(argv[3]);
        if (ngets <= 0) {
                printf("number_of_gets\n");
                errno = einval;
                exit(exit_failure);
        }
/*}}}*/

        bzero(&cstats, sizeof(struct cstats));

        /* pthread initialization *//*{{{*/
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, pthread_create_joinable);
        pthread_mutex_init(&cstats.mutex, null);
        threadv = malloc(sizeof(pthread_t) * ngets);
        if (!threadv) 
                pexit("malloc");/*}}}*/

        /* address initialization *//*{{{*/
        strncpy(buf, argv[4], buflen);
        strncat(buf, "\r\n", buflen);

 host = gethostbyname(argv[1]);
 if (!host)
  pexit("gethostbyname");

 memcpy(&addr.sin_addr.s_addr, host->h_addr_list[0], sizeof(struct
    sockaddr_in)); 
 addr.sin_family = pf_inet;
 addr.sin_port = htons(atoi(argv[2]));
/*}}}*/

        /* creating threads *//*{{{*/
 for (i = 0; i < ngets; i++) {
                error = pthread_create(&threadv[i], &attr,
                                        get_get_thread, null);
                if (error)
                        fail++; 
 }/*}}}*/


        printf("%d thread created. Running...\n", ngets -  fail);

        /* joing threads *//*{{{*/
        for (i = 0; i < ngets; i++) {
                error = pthread_join(threadv[i], null);
                if (error)
                        perror("pthread_join");
        }/*}}}*/

        /* output *//*{{{*/
        printf("errors:\n"
               "    socket() errors: %d\n"
               "    connect() errors: %d\n"
               "    send() errors: %d\n"
               "    recv() errors: %d\n", cstats.socket_errors,
               cstats.connect_errors, cstats.send_errors, cstats.recv_errors);/*}}}*/

 return 0;
}

void *get_get_thread(void *dummy)/*{{{*/
{
        int error;
        int nbytes;
        int sock;
#define RBUF_LEN 1024
        char rbuf[RBUF_LEN];

 sock = socket(PF_INET, SOCK_STREAM, 0);/*{{{*/
 if (sock < 0) {
                pthread_mutex_lock(&cstats.mutex);
                cstats.socket_errors++;
                pthread_mutex_unlock(&cstats.mutex);
        }/*}}}*/

 error = connect(sock, (struct sockaddr *)&addr, sizeof addr);/*{{{*/
 if (error) {
                pthread_mutex_lock(&cstats.mutex);
                cstats.connect_errors++;
                pthread_mutex_unlock(&cstats.mutex);
        }/*}}}*/

        nbytes = send(sock, buf, strlen(buf) , 0);/*{{{*/
        if (nbytes == -1) /* error */ {
                pthread_mutex_lock(&cstats.mutex);
                cstats.send_errors++;
                pthread_mutex_unlock(&cstats.mutex);
        }/*}}}*/

        nbytes = recv(sock, rbuf, RBUF_LEN, 0);/*{{{*/
        if (nbytes == -1) {
                pthread_mutex_lock(&cstats.mutex);
                cstats.recv_errors++;
                pthread_mutex_unlock(&cstats.mutex);
        }/*}}}*/

 close(sock);
        return (void *)0;
}/*}}}*/

/* vim: set fdm=marker: tw=80 : */

Collectd patch to collect cpu average on linux

I'm using collectd to collectd data at work -> http://www.collectd.org The cpu plugin don't collectd average cpu usage, I have create a patch to work this around. Here it is
diff -Nurp collectd-5.0.1/src/cpu.c collectd-5.0.1-new/src/cpu.c
--- collectd-5.0.1/src/cpu.c 2011-10-14 17:49:49.000000000 -0300
+++ collectd-5.0.1-new/src/cpu.c 2012-01-03 17:48:22.000000000 -0200
@@ -252,7 +252,11 @@ static void submit (int cpu_num, const c
  vl.values_len = 1;
  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
  sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin));
- ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+        if (cpu_num < 0)
+                ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+   "avg");
+        else
+                ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
    "%i", cpu_num);
  sstrncpy (vl.type, "cpu", sizeof (vl.type));
  sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
@@ -359,6 +363,7 @@ static int cpu_read (void)
 
  char *fields[9];
  int numfields;
+        int coren = sysconf(_SC_NPROCESSORS_ONLN); /* number of cores */
 
  if ((fh = fopen ("/proc/stat", "r")) == NULL)
  {
@@ -372,18 +377,24 @@ static int cpu_read (void)
  {
   if (strncmp (buf, "cpu", 3))
    continue;
-  if ((buf[3] < '0') || (buf[3] > '9'))
-   continue;
 
   numfields = strsplit (buf, fields, 9);
   if (numfields < 5)
    continue;
 
-  cpu = atoi (fields[0] + 3);
-  user = atoll (fields[1]);
-  nice = atoll (fields[2]);
-  syst = atoll (fields[3]);
-  idle = atoll (fields[4]);
+                if (!isdigit(fields[0][3])) {
+                        cpu = -1;
+                        user = atoll (fields[1]) / coren;
+                        nice = atoll (fields[2]) / coren;
+                        syst = atoll (fields[3]) / coren;
+                        idle = atoll (fields[4]) / coren;
+                } else { 
+          cpu = atoi (fields[0] + 3);
+                        user = atoll (fields[1]);
+                        nice = atoll (fields[2]);
+                        syst = atoll (fields[3]);
+                        idle = atoll (fields[4]);
+                }
 
   submit (cpu, "user", user);
   submit (cpu, "nice", nice);
@@ -392,9 +403,15 @@ static int cpu_read (void)
 
   if (numfields >= 8)
   {
-   wait = atoll (fields[5]);
-   intr = atoll (fields[6]);
-   sitr = atoll (fields[7]);
+                        if (cpu < 0) {
+                                wait = atoll (fields[5]) / coren;
+                                intr = atoll (fields[6]) / coren;
+                                sitr = atoll (fields[7]) / coren;
+                        } else {
+                                wait = atoll (fields[5]);
+                                intr = atoll (fields[6]);
+                                sitr = atoll (fields[7]);
+                        }
 
    submit (cpu, "wait", wait);
    submit (cpu, "interrupt", intr);