/*
    Badchecksum - www.badchecksum.com
*/
/*
    Nombre: findhash
    Descripción:
        Extrae un comando db con cuatro bytes que representan
    el hash de la cadena pasada en little endian. Sirve para despues
    llevar estos db's a una shellcode y utilizar los hashes para buscar
    las funciones en memoria.
    Autor: Simkin
    Fecha: 05/01/2005
    OS: Todos
    Compilador: gcc version 3.4.2 (mingw-special)
*/

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

/*
ejemplo:
db 0x29,0x44,0xe8,0x57
*/
#define DBHASHSIZE 22 

long findhash(char *funcname)
{
    long hash = 0;
    if(!funcname) return 0;
	asm(
    "movl %1, %%esi;\
	xor %%edi, %%edi;\
	xor %%eax, %%eax;\
	compute_hash_again:;\
		lodsb;\
		test %%al, %%al;\
		jz compute_hash_finished;\
		rorl $0xd,%%edi;\
		addl %%eax, %%edi;\
		jmp compute_hash_again;\
	compute_hash_finished:;\
	movl %%edi, %0"
	:"=r"(hash)
    :"r"(funcname));
    return hash;
} 

char *hashtodbstr(unsigned long hash)
{
    if(!hash) return NULL;
    char *buf = (char *)malloc(DBHASHSIZE+1);
    memset(buf,'\0',DBHASHSIZE+1);
    sprintf(buf,"db 0x%02x,0x%02x,0x%02x,0x%02x",
        (hash << 24) >> 24,
        (hash << 16) >> 24,
        (hash << 8) >> 24,
        hash >> 24);
    return buf;
} 

int main(int argc, char *argv[]) {
    unsigned long hash = 0;
    char *strhash = NULL;
    char *buf = (char *)malloc(sizeof(char)*50);
        
    printf("Write \"end\" to exit\n\n");
    while(1) {
        memset(buf,'\0',sizeof(char)*50);
        gets(buf);
        if(!strncmp(buf,"end",3)) break;
        hash = findhash(buf);
        strhash = hashtodbstr(hash);
        printf("%s\n",strhash);
        free(strhash);  
    }
    free(buf);
    system("PAUSE");
    return 0;
}
